]> err.no Git - scalable-opengroupware.org/commitdiff
initial sync
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 3 Jan 2007 16:07:03 +0000 (16:07 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 3 Jan 2007 16:07:03 +0000 (16:07 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1005 d1b88da0-ebda-0310-925b-ed51d893ca5b

731 files changed:
ChangeLog [new file with mode: 0644]
GNUmakefile
Main/ChangeLog.upstream [moved from Main/ChangeLog with 100% similarity]
Main/GNUmakefile.preamble
Main/SOGo.m
Main/SOGoProductLoader.m
Main/sogod.m
Misc/WebUI/Application.h [deleted file]
Misc/WebUI/Application.m [deleted file]
Misc/WebUI/COPYING [deleted file]
Misc/WebUI/COPYRIGHT [deleted file]
Misc/WebUI/ChangeLog [deleted file]
Misc/WebUI/DirectAction.h [deleted file]
Misc/WebUI/DirectAction.m [deleted file]
Misc/WebUI/English.lproj/InfoPlist.strings [deleted file]
Misc/WebUI/GNUmakefile [deleted file]
Misc/WebUI/GNUmakefile.preamble [deleted file]
Misc/WebUI/Info.plist [deleted file]
Misc/WebUI/Lori.icns [deleted file]
Misc/WebUI/NGExtensions/GNUmakefile [deleted file]
Misc/WebUI/NGExtensions/NGLogging/ChangeLog [deleted file]
Misc/WebUI/NGExtensions/NGLogging/GNUmakefile [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogAppender.h [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogAppender.m [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogConsoleAppender.h [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogConsoleAppender.m [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogEvent.h [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogEvent.m [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogSyslogAppender.h [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogSyslogAppender.m [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogger.h [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogger.m [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NGLogging.h [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NSObject+ExtendedLogging.h [deleted file]
Misc/WebUI/NGExtensions/NGLogging/NSObject+ExtendedLogging.m [deleted file]
Misc/WebUI/NOTES [deleted file]
Misc/WebUI/PROJECTLEAD [deleted file]
Misc/WebUI/README [deleted file]
Misc/WebUI/Session.h [deleted file]
Misc/WebUI/Session.m [deleted file]
Misc/WebUI/TODO [deleted file]
Misc/WebUI/Version [deleted file]
Misc/WebUI/WebServerResources/favicon.ico [deleted file]
Misc/WebUI/WebUI.xcode/project.pbxproj [deleted file]
Misc/WebUI/WebUI_Prefix.pch [deleted file]
Misc/WebUI/WebUI_main.m [deleted file]
Misc/WebUI/common.h [deleted file]
Misc/WebUI/version.plist [deleted file]
Misc/WebUI/wox-cheat-sheet.txt [deleted file]
Misc/ZideStore/UI-X/ChangeLog [deleted file]
Misc/ZideStore/UI-X/Common/CommonUIProduct.m [deleted file]
Misc/ZideStore/UI-X/Common/GNUmakefile [deleted file]
Misc/ZideStore/UI-X/Common/GNUmakefile.postamble [deleted file]
Misc/ZideStore/UI-X/Common/GNUmakefile.preamble [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppFrame.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppFrame.wox [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppHeader.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppHeader.wox [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppNavView.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppNavView.wox [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppNavigation.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxAppNavigation.wox [deleted file]
Misc/ZideStore/UI-X/Common/UIxComponent.h [deleted file]
Misc/ZideStore/UI-X/Common/UIxComponent.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxElemBuilder.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxPageFrame.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxPageFrame.wox [deleted file]
Misc/ZideStore/UI-X/Common/UIxTabItem.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxTabView.h [deleted file]
Misc/ZideStore/UI-X/Common/UIxTabView.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxWinClose.m [deleted file]
Misc/ZideStore/UI-X/Common/UIxWinClose.wox [deleted file]
Misc/ZideStore/UI-X/Common/Version [deleted file]
Misc/ZideStore/UI-X/Common/bundle-info.plist [deleted file]
Misc/ZideStore/UI-X/Common/calendar.css [deleted file]
Misc/ZideStore/UI-X/Common/common.h [deleted file]
Misc/ZideStore/UI-X/Common/images/OGoLogo.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_botleft.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_botright.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_bottom.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_left.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_right.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_top.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_topleft.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/box_topright.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/closewindow.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/corner_right.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/line_left.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/line_right.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/line_stretch.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/menu_logo_top.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/tab_.gif [deleted file]
Misc/ZideStore/UI-X/Common/images/tab_selected.gif [deleted file]
Misc/ZideStore/UI-X/Common/product.plist [deleted file]
Misc/ZideStore/UI-X/Common/zidestoreui.css [deleted file]
Misc/ZideStore/UI-X/GNUmakefile [deleted file]
Misc/ZideStore/UI-X/Scheduler/COPYING [deleted file]
Misc/ZideStore/UI-X/Scheduler/COPYRIGHT [deleted file]
Misc/ZideStore/UI-X/Scheduler/GNUmakefile [deleted file]
Misc/ZideStore/UI-X/Scheduler/GNUmakefile.postamble [deleted file]
Misc/ZideStore/UI-X/Scheduler/GNUmakefile.preamble [deleted file]
Misc/ZideStore/UI-X/Scheduler/NOTES [deleted file]
Misc/ZideStore/UI-X/Scheduler/SchedulerUIProduct.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAppointmentEditor.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAppointmentEditor.wox [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAppointmentFormatter.h [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAppointmentFormatter.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.h [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.wox [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAptTableView.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxAptTableView.wox [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalBackForthNavView.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalDateLabel.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalDateLabel.wox [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalMonthOverview.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalMonthOverview.wox [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalMonthView.h [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalMonthView.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalSelectTab.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalSelectTab.wox [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalView.h [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalView.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalWeekOverview.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalWeekOverview.wox [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalWeekView.h [deleted file]
Misc/ZideStore/UI-X/Scheduler/UIxCalWeekView.m [deleted file]
Misc/ZideStore/UI-X/Scheduler/Version [deleted file]
Misc/ZideStore/UI-X/Scheduler/bundle-info.plist [deleted file]
Misc/ZideStore/UI-X/Scheduler/common.h [deleted file]
Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart.gif [deleted file]
Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart_inactive.gif [deleted file]
Misc/ZideStore/UI-X/Scheduler/images/icon_apt_column_view.gif [deleted file]
Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list.gif [deleted file]
Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list_inactive.gif [deleted file]
Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview.gif [deleted file]
Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview_inactive.gif [deleted file]
Misc/ZideStore/UI-X/Scheduler/product.plist [deleted file]
Misc/db/scripts/create_user_tables.py [deleted file]
Misc/db/tests/helge/NOTES [deleted file]
Misc/db/tests/helge/PyGreSQL-samples/advanced.py [deleted file]
Misc/db/tests/helge/PyGreSQL-samples/basics.py [deleted file]
Misc/db/tests/helge/PyGreSQL-samples/func.py [deleted file]
Misc/db/tests/helge/PyGreSQL-samples/syscat.py [deleted file]
Misc/db/tests/helge/chkfolderinfoperf.py [deleted file]
Misc/db/tests/helge/chkhugeperf.py [deleted file]
Misc/db/tests/helge/fill_hugeperf.py [deleted file]
Misc/db/tests/helge/fillfolderinfo.py [deleted file]
Misc/db/tests/helge/laurent-trigger.psql [deleted file]
Misc/db/tests/helge/makedb.py [deleted file]
Misc/db/tests/helge/maketables.py [deleted file]
Misc/db/tests/helge/makeusers.py [deleted file]
Misc/db/tests/helge/scale/NOTES.txt [deleted file]
Misc/db/tests/helge/scale/createapts.py [deleted file]
Misc/db/tests/helge/scale/createfolders.py [deleted file]
Misc/db/tests/helge/scale/createindexes.py [deleted file]
Misc/db/tests/helge/scale/makeidx1-200.psql [deleted file]
Misc/db/tests/helge/scale/user1.sql [deleted file]
Misc/db/tests/znek/GNUmakefile [deleted file]
Misc/db/tests/znek/GNUmakefile.preamble [deleted file]
Misc/db/tests/znek/NSArray+random.h [deleted file]
Misc/db/tests/znek/NSArray+random.m [deleted file]
Misc/db/tests/znek/connection.plist [deleted file]
Misc/db/tests/znek/inserts.eomodel [deleted file]
Misc/db/tests/znek/inserts.m [deleted file]
Misc/db/tests/znek/lmail.m [deleted file]
Misc/db/tests/znek/lpe.m [deleted file]
Misc/db/tests/znek/pfinserts.m [deleted file]
Misc/db/tests/znek/tests.xcode/project.pbxproj [deleted file]
Misc/dbd/DDatabase.m [deleted file]
Misc/dbd/DDatabase.wox [deleted file]
Misc/dbd/DDatabaseManager.m [deleted file]
Misc/dbd/DDatabaseManager.wox [deleted file]
Misc/dbd/DHostView.m [deleted file]
Misc/dbd/DHostView.wox [deleted file]
Misc/dbd/DSoAuthenticator.h [deleted file]
Misc/dbd/DSoAuthenticator.m [deleted file]
Misc/dbd/DSoDatabase.m [deleted file]
Misc/dbd/DSoDatabaseManager.h [deleted file]
Misc/dbd/DSoDatabaseManager.m [deleted file]
Misc/dbd/DSoField.m [deleted file]
Misc/dbd/DSoHost.m [deleted file]
Misc/dbd/DSoObject.h [deleted file]
Misc/dbd/DSoObject.m [deleted file]
Misc/dbd/DSoTable.m [deleted file]
Misc/dbd/DSoUserManager.m [deleted file]
Misc/dbd/DTable.m [deleted file]
Misc/dbd/DTable.wox [deleted file]
Misc/dbd/Frame.m [deleted file]
Misc/dbd/Frame.wox [deleted file]
Misc/dbd/GNUmakefile [deleted file]
Misc/dbd/MainPage.m [deleted file]
Misc/dbd/MainPage.wox [deleted file]
Misc/dbd/README [deleted file]
Misc/dbd/Version [deleted file]
Misc/dbd/common.h [deleted file]
Misc/dbd/dbd.css [deleted file]
Misc/dbd/dbd.m [deleted file]
Misc/dbd/product.plist [deleted file]
OGoContentStore/ChangeLog.upstream [moved from OGoContentStore/ChangeLog with 100% similarity]
OGoContentStore/GNUmakefile
OGoContentStore/GNUmakefile.preamble
OGoContentStore/OCSContactFieldExtractor.m
OGoContentStore/OCSiCalFieldExtractor.m
OGoContentStore/appointment.ocs
OGoContentStore/iCalEntityObject+OCS.h
OGoContentStore/iCalRepeatableEntityObject+OCS.h
OGoContentStore/iCalRepeatableEntityObject+OCS.m
OGoContentStore/sql/acls.sh [new file with mode: 0755]
OGoContentStore/sql/appointment-create.psql
OGoContentStore/sql/folderinfo-create.psql
OGoContentStore/sql/generate-folderinfo-sql-for-users.sh
OGoContentStore/sql/profile-create.psql
OGoContentStore/sql/sogo-folderinfo.sh [new file with mode: 0755]
Protocols/common.make
Protocols/iCalHTTP/ChangeLog.upstream [moved from Protocols/iCalHTTP/ChangeLog with 100% similarity]
Protocols/iCalHTTP/SOGoICalFileFetch.m
Protocols/iCalHTTP/SOGoICalFilePublish.m
README
SoObjects/Appointments/ChangeLog.upstream [moved from SoObjects/Appointments/ChangeLog with 100% similarity]
SoObjects/Appointments/GNUmakefile
SoObjects/Appointments/NSArray+Appointments.h [new file with mode: 0644]
SoObjects/Appointments/NSArray+Appointments.m [new file with mode: 0644]
SoObjects/Appointments/SOGoAppointmentFolder.h
SoObjects/Appointments/SOGoAppointmentFolder.m
SoObjects/Appointments/SOGoAppointmentObject.h
SoObjects/Appointments/SOGoAppointmentObject.m
SoObjects/Appointments/SOGoAptMailNotification.h
SoObjects/Appointments/SOGoAptMailNotification.m
SoObjects/Appointments/SOGoCalendarComponent.h [new file with mode: 0644]
SoObjects/Appointments/SOGoCalendarComponent.m [new file with mode: 0644]
SoObjects/Appointments/SOGoFreeBusyObject.h
SoObjects/Appointments/SOGoFreeBusyObject.m
SoObjects/Appointments/SOGoGroupAppointmentFolder.m
SoObjects/Appointments/SOGoTaskObject.h [new file with mode: 0644]
SoObjects/Appointments/SOGoTaskObject.m [new file with mode: 0644]
SoObjects/Appointments/iCalEntityObject+Agenor.h [new file with mode: 0644]
SoObjects/Appointments/iCalEntityObject+Agenor.m [new file with mode: 0644]
SoObjects/Appointments/product.plist
SoObjects/ChangeLog.upstream [moved from SoObjects/ChangeLog with 100% similarity]
SoObjects/Contacts/ChangeLog.upstream [moved from SoObjects/Contacts/ChangeLog with 100% similarity]
SoObjects/Contacts/GNUmakefile
SoObjects/Contacts/NGLdapEntry+Contact.h [new file with mode: 0644]
SoObjects/Contacts/NGLdapEntry+Contact.m [new file with mode: 0644]
SoObjects/Contacts/NSDictionary+Contact.h [new file with mode: 0644]
SoObjects/Contacts/NSDictionary+Contact.m [new file with mode: 0644]
SoObjects/Contacts/SOGoContactFolder.h
SoObjects/Contacts/SOGoContactFolder.m [deleted file]
SoObjects/Contacts/SOGoContactFolders.h [new file with mode: 0644]
SoObjects/Contacts/SOGoContactFolders.m [new file with mode: 0644]
SoObjects/Contacts/SOGoContactGCSEntry.h [new file with mode: 0644]
SoObjects/Contacts/SOGoContactGCSEntry.m [new file with mode: 0644]
SoObjects/Contacts/SOGoContactGCSFolder.h [moved from UI/MailerUI/UIxMailAccountsView.m with 72% similarity]
SoObjects/Contacts/SOGoContactGCSFolder.m [new file with mode: 0644]
SoObjects/Contacts/SOGoContactLDAPEntry.h [new file with mode: 0644]
SoObjects/Contacts/SOGoContactLDAPEntry.m [new file with mode: 0644]
SoObjects/Contacts/SOGoContactLDAPFolder.h [new file with mode: 0644]
SoObjects/Contacts/SOGoContactLDAPFolder.m [new file with mode: 0644]
SoObjects/Contacts/SOGoContactObject.h
SoObjects/Contacts/SOGoContactObject.m [deleted file]
SoObjects/Contacts/product.plist
SoObjects/Mailer/ChangeLog.upstream [moved from SoObjects/Mailer/ChangeLog with 100% similarity]
SoObjects/Mailer/SOGoDraftObject.m
SoObjects/Mailer/SOGoMailAccount.m
SoObjects/Mailer/SOGoMailAccounts.m
SoObjects/Mailer/SOGoMailFolder.m
SoObjects/Mailer/SOGoMailObject.h
SoObjects/Mailer/SOGoMailObject.m
SoObjects/Mailer/SOGoUser+Mail.m
SoObjects/Mailer/product.plist
SoObjects/SOGo/AgenorUserManager.h
SoObjects/SOGo/AgenorUserManager.m
SoObjects/SOGo/ChangeLog.upstream [moved from SoObjects/SOGo/ChangeLog with 100% similarity]
SoObjects/SOGo/GNUmakefile
SoObjects/SOGo/GNUmakefile.preamble
SoObjects/SOGo/NSArray+Utilities.h [new file with mode: 0644]
SoObjects/SOGo/NSArray+Utilities.m [new file with mode: 0644]
SoObjects/SOGo/NSCalendarDate+SOGo.h [new file with mode: 0644]
SoObjects/SOGo/NSCalendarDate+SOGo.m [new file with mode: 0644]
SoObjects/SOGo/NSDictionary+URL.h [new file with mode: 0644]
SoObjects/SOGo/NSDictionary+URL.m [new file with mode: 0644]
SoObjects/SOGo/NSObject+AptComparison.m
SoObjects/SOGo/NSString+Utilities.h [new file with mode: 0644]
SoObjects/SOGo/NSString+Utilities.m [new file with mode: 0644]
SoObjects/SOGo/NSString+iCal.h [deleted file]
SoObjects/SOGo/SOGoAclsFolder.h [new file with mode: 0644]
SoObjects/SOGo/SOGoAclsFolder.m [new file with mode: 0644]
SoObjects/SOGo/SOGoAppointment.h [deleted file]
SoObjects/SOGo/SOGoAppointment.m [deleted file]
SoObjects/SOGo/SOGoAppointmentICalRenderer.h [deleted file]
SoObjects/SOGo/SOGoAppointmentICalRenderer.m [deleted file]
SoObjects/SOGo/SOGoAuthenticator.h
SoObjects/SOGo/SOGoAuthenticator.m
SoObjects/SOGo/SOGoContentObject.h
SoObjects/SOGo/SOGoCustomGroupFolder.m
SoObjects/SOGo/SOGoDAVRendererTypes.h [new file with mode: 0644]
SoObjects/SOGo/SOGoDAVRendererTypes.m [new file with mode: 0644]
SoObjects/SOGo/SOGoFolder.h
SoObjects/SOGo/SOGoFolder.m
SoObjects/SOGo/SOGoObject.h
SoObjects/SOGo/SOGoObject.m
SoObjects/SOGo/SOGoPermissions.h [new file with mode: 0644]
SoObjects/SOGo/SOGoPermissions.m [new file with mode: 0644]
SoObjects/SOGo/SOGoUser.h
SoObjects/SOGo/SOGoUser.m
SoObjects/SOGo/SOGoUserFolder.h
SoObjects/SOGo/SOGoUserFolder.m
SoObjects/Sieve/ChangeLog.upstream [moved from SoObjects/Sieve/ChangeLog with 100% similarity]
SoObjects/common.make
UI/ChangeLog.upstream [moved from UI/ChangeLog with 100% similarity]
UI/Common/ChangeLog.upstream [moved from UI/Common/ChangeLog with 100% similarity]
UI/Common/English.lproj/Localizable.strings
UI/Common/French.lproj/Localizable.strings
UI/Common/GNUmakefile
UI/Common/GNUmakefile.preamble
UI/Common/Toolbars/SOGoAclAssistant.toolbar [new file with mode: 0644]
UI/Common/Toolbars/SOGoAclOwner.toolbar [new file with mode: 0644]
UI/Common/UIxAclEditor.h [new file with mode: 0644]
UI/Common/UIxAclEditor.m [new file with mode: 0644]
UI/Common/UIxException.m [new file with mode: 0644]
UI/Common/UIxJSClose.h [new file with mode: 0644]
UI/Common/UIxJSClose.m [new file with mode: 0644]
UI/Common/UIxPageFrame.h [moved from Misc/dbd/DSoTable.h with 51% similarity]
UI/Common/UIxPageFrame.m
UI/Common/UIxSortableTableHeader.m [moved from UI/MailerUI/UIxMailSortableTableHeader.m with 83% similarity]
UI/Common/UIxToolbar.m [moved from UI/MailerUI/UIxMailToolbar.m with 54% similarity]
UI/Common/UIxUserLogoff.m [new file with mode: 0644]
UI/Common/product.plist
UI/Contacts/ChangeLog.upstream [moved from UI/Contacts/ChangeLog with 100% similarity]
UI/Contacts/English.lproj/Localizable.strings
UI/Contacts/French.lproj/Localizable.strings
UI/Contacts/GNUmakefile
UI/Contacts/Toolbars/SOGoContactFolder.toolbar [new file with mode: 0644]
UI/Contacts/UIxContactEditor.h [moved from UI/Contacts/UIxContactEditorBase.h with 79% similarity]
UI/Contacts/UIxContactEditor.m
UI/Contacts/UIxContactEditorBase.m [deleted file]
UI/Contacts/UIxContactFoldersView.h [new file with mode: 0644]
UI/Contacts/UIxContactFoldersView.m [new file with mode: 0644]
UI/Contacts/UIxContactSelector.h [new file with mode: 0644]
UI/Contacts/UIxContactSelector.m
UI/Contacts/UIxContactView.h [moved from Misc/dbd/DSoUserManager.h with 73% similarity]
UI/Contacts/UIxContactView.m
UI/Contacts/UIxContactsAclsSelection.m [moved from Misc/dbd/DSoField.h with 78% similarity]
UI/Contacts/UIxContactsAddressBooksSelection.m [moved from Misc/dbd/DSoUser.m with 76% similarity]
UI/Contacts/UIxContactsCalendarsSelection.m [moved from UI/Common/UIxWinClose.m with 77% similarity]
UI/Contacts/UIxContactsFilterPanel.m [new file with mode: 0644]
UI/Contacts/UIxContactsListView.h [moved from UI/Contacts/UIxContactsListViewBase.h with 71% similarity]
UI/Contacts/UIxContactsListView.m
UI/Contacts/UIxContactsListViewBase.m [deleted file]
UI/Contacts/UIxContactsListViewContainer.h [new file with mode: 0644]
UI/Contacts/UIxContactsListViewContainer.m [new file with mode: 0644]
UI/Contacts/UIxContactsMailerSelection.m [moved from Misc/dbd/DSoUser.h with 77% similarity]
UI/Contacts/UIxContactsSelectionView.m [deleted file]
UI/Contacts/product.plist
UI/MailPartViewers/ChangeLog.upstream [moved from UI/MailPartViewers/ChangeLog with 100% similarity]
UI/MailPartViewers/French.lproj/Localizable.strings
UI/MailPartViewers/UIxMailPartICalViewer.h [moved from Misc/dbd/DSoDatabase.h with 57% similarity]
UI/MailPartViewers/UIxMailPartICalViewer.m
UI/MailPartViewers/UIxMailPartTextViewer.h [new file with mode: 0644]
UI/MailPartViewers/UIxMailPartTextViewer.m
UI/MailerUI/ChangeLog.upstream [moved from UI/MailerUI/ChangeLog with 100% similarity]
UI/MailerUI/English.lproj/Localizable.strings
UI/MailerUI/French.lproj/Localizable.strings
UI/MailerUI/GNUmakefile
UI/MailerUI/Images/COPYING [deleted file]
UI/MailerUI/Images/LICENSE-thunderbird.txt [deleted file]
UI/MailerUI/Toolbars/SOGoDraftObject.toolbar
UI/MailerUI/Toolbars/SOGoMailAccount.toolbar [deleted file]
UI/MailerUI/Toolbars/SOGoMailFolder.toolbar [deleted file]
UI/MailerUI/Toolbars/SOGoMailObject.toolbar
UI/MailerUI/Toolbars/SOGoTrashFolder.toolbar [deleted file]
UI/MailerUI/UIxMailAccountView.m [deleted file]
UI/MailerUI/UIxMailEditor.m
UI/MailerUI/UIxMailEditorAction.m
UI/MailerUI/UIxMailFilterPanel.m
UI/MailerUI/UIxMailFolderMenu.h [new file with mode: 0644]
UI/MailerUI/UIxMailFolderMenu.m [new file with mode: 0644]
UI/MailerUI/UIxMailFormatter.h
UI/MailerUI/UIxMailFormatter.m
UI/MailerUI/UIxMailListView.h [moved from UI/Scheduler/UIxCalDayPrintview.m with 59% similarity]
UI/MailerUI/UIxMailListView.m
UI/MailerUI/UIxMailMainFrame.h [new file with mode: 0644]
UI/MailerUI/UIxMailMainFrame.m
UI/MailerUI/UIxMailPopupView.m [new file with mode: 0644]
UI/MailerUI/UIxMailSplashView.m [new file with mode: 0644]
UI/MailerUI/UIxMailToSelection.m
UI/MailerUI/UIxMailTree.h [new file with mode: 0644]
UI/MailerUI/UIxMailTree.m
UI/MailerUI/UIxMailTreeBlock.h
UI/MailerUI/UIxMailTreeBlock.m
UI/MailerUI/UIxMailTreeBlockJS.h [new file with mode: 0644]
UI/MailerUI/UIxMailTreeBlockJS.m [new file with mode: 0644]
UI/MailerUI/UIxMailView.m
UI/MailerUI/WOContext+UIxMailer.m
UI/MailerUI/product.plist
UI/MainUI/ChangeLog.upstream [moved from UI/MainUI/ChangeLog with 100% similarity]
UI/MainUI/French.lproj/Localizable.strings
UI/MainUI/GNUmakefile
UI/MainUI/SOGoUserHomePage.m
UI/MainUI/SOGoUserHomePage.wox [deleted file]
UI/MainUI/product.plist
UI/SOGoUI/ChangeLog.upstream [moved from UI/SOGoUI/ChangeLog with 100% similarity]
UI/SOGoUI/GNUmakefile
UI/SOGoUI/GNUmakefile.preamble
UI/SOGoUI/SOGoAptFormatter.h
UI/SOGoUI/SOGoAptFormatter.m
UI/SOGoUI/SOGoDateFormatter.h
UI/SOGoUI/SOGoDateFormatter.m
UI/SOGoUI/UIxComponent.h
UI/SOGoUI/UIxComponent.m
UI/Scheduler/ChangeLog.upstream [moved from UI/Scheduler/ChangeLog with 100% similarity]
UI/Scheduler/English.lproj/Localizable.strings
UI/Scheduler/English.lproj/skycalendar.html [deleted file]
UI/Scheduler/French.lproj/Localizable.strings
UI/Scheduler/French.lproj/skycalendar.html [deleted file]
UI/Scheduler/French.lproj/skycalendar.js [deleted file]
UI/Scheduler/GNUmakefile
UI/Scheduler/GNUmakefile.preamble
UI/Scheduler/NOTES
UI/Scheduler/NSCalendarDate+UIx.h [deleted file]
UI/Scheduler/NSCalendarDate+UIx.m [deleted file]
UI/Scheduler/SOGoAppointment+UIx.h [deleted file]
UI/Scheduler/Toolbars/SOGoAppointmentFolder.toolbar [new file with mode: 0644]
UI/Scheduler/Toolbars/SOGoAppointmentObject.toolbar [new file with mode: 0644]
UI/Scheduler/Toolbars/SOGoAppointmentObjectAccept.toolbar [new file with mode: 0644]
UI/Scheduler/Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar [new file with mode: 0644]
UI/Scheduler/Toolbars/SOGoAppointmentObjectDecline.toolbar [new file with mode: 0644]
UI/Scheduler/UIxAppointmentEditor.h [new file with mode: 0644]
UI/Scheduler/UIxAppointmentEditor.m
UI/Scheduler/UIxAppointmentPrintview.m [deleted file]
UI/Scheduler/UIxAppointmentProposal.m
UI/Scheduler/UIxAppointmentView.h
UI/Scheduler/UIxAppointmentView.m
UI/Scheduler/UIxCalAptListView.h [new file with mode: 0644]
UI/Scheduler/UIxCalAptListView.m [new file with mode: 0644]
UI/Scheduler/UIxCalCalendarsListView.h [new file with mode: 0644]
UI/Scheduler/UIxCalCalendarsListView.m [new file with mode: 0644]
UI/Scheduler/UIxCalDateLabel.m
UI/Scheduler/UIxCalDateSelector.h [new file with mode: 0644]
UI/Scheduler/UIxCalDateSelector.m [new file with mode: 0644]
UI/Scheduler/UIxCalDayTable.h [new file with mode: 0644]
UI/Scheduler/UIxCalDayTable.m [new file with mode: 0644]
UI/Scheduler/UIxCalDayView.h
UI/Scheduler/UIxCalDayView.m
UI/Scheduler/UIxCalFilterPanel.h [new file with mode: 0644]
UI/Scheduler/UIxCalFilterPanel.m [new file with mode: 0644]
UI/Scheduler/UIxCalInlineAptView.m
UI/Scheduler/UIxCalInlineMonthOverview.h [moved from Misc/dbd/DSoHost.h with 55% similarity]
UI/Scheduler/UIxCalInlineMonthOverview.m
UI/Scheduler/UIxCalMainView.h [new file with mode: 0644]
UI/Scheduler/UIxCalMainView.m [new file with mode: 0644]
UI/Scheduler/UIxCalMonthOverview.h
UI/Scheduler/UIxCalMonthOverview.m
UI/Scheduler/UIxCalMonthPrintview.m [deleted file]
UI/Scheduler/UIxCalMonthView.h
UI/Scheduler/UIxCalMonthView.m
UI/Scheduler/UIxCalMonthViewOld.h [new file with mode: 0644]
UI/Scheduler/UIxCalMonthViewOld.m [new file with mode: 0644]
UI/Scheduler/UIxCalParticipationStatusView.m
UI/Scheduler/UIxCalScheduleOverview.m
UI/Scheduler/UIxCalSelectTab.m
UI/Scheduler/UIxCalTasksListView.h [new file with mode: 0644]
UI/Scheduler/UIxCalTasksListView.m [new file with mode: 0644]
UI/Scheduler/UIxCalView.h
UI/Scheduler/UIxCalView.m
UI/Scheduler/UIxCalWeekListview.m
UI/Scheduler/UIxCalWeekOverview.m
UI/Scheduler/UIxCalWeekPrintview.m [deleted file]
UI/Scheduler/UIxCalWeekView.h
UI/Scheduler/UIxCalWeekView.m
UI/Scheduler/UIxCalYearOverview.m
UI/Scheduler/UIxComponent+Agenor.h
UI/Scheduler/UIxComponent+Agenor.m
UI/Scheduler/UIxComponentEditor.h [new file with mode: 0644]
UI/Scheduler/UIxComponentEditor.m [new file with mode: 0644]
UI/Scheduler/UIxDatePicker.m
UI/Scheduler/UIxDatePickerScript.m [deleted file]
UI/Scheduler/UIxFreeBusyUserSelector.h [new file with mode: 0644]
UI/Scheduler/UIxFreeBusyUserSelector.m [new file with mode: 0644]
UI/Scheduler/UIxFreeBusyUserSelectorTable.h [new file with mode: 0644]
UI/Scheduler/UIxFreeBusyUserSelectorTable.m [new file with mode: 0644]
UI/Scheduler/UIxTaskEditor.h [new file with mode: 0644]
UI/Scheduler/UIxTaskEditor.m [new file with mode: 0644]
UI/Scheduler/UIxTaskProposal.m [new file with mode: 0644]
UI/Scheduler/UIxTaskView.h [new file with mode: 0644]
UI/Scheduler/UIxTaskView.m [new file with mode: 0644]
UI/Scheduler/UIxTimeDateControl.h [new file with mode: 0644]
UI/Scheduler/UIxTimeDateControl.m
UI/Scheduler/UIxTimeSelector.m [deleted file]
UI/Scheduler/common.h
UI/Scheduler/iCalPerson+UIx.h [deleted file]
UI/Scheduler/iCalPerson+UIx.m [deleted file]
UI/Scheduler/iCalRecurrenceRule+SOGo.m [deleted file]
UI/Scheduler/images/next_week.gif [deleted file]
UI/Scheduler/images/previous_week.gif [deleted file]
UI/Scheduler/product.plist
UI/Scheduler/skycalendar.js [deleted file]
UI/Templates/ChangeLog.upstream [moved from UI/Templates/ChangeLog with 100% similarity]
UI/Templates/ContactsUI/UIxContactEditor.wox
UI/Templates/ContactsUI/UIxContactFoldersView.wox [new file with mode: 0644]
UI/Templates/ContactsUI/UIxContactSelector.wox [new file with mode: 0644]
UI/Templates/ContactsUI/UIxContactView.wox
UI/Templates/ContactsUI/UIxContactsAclsSelection.wox [new file with mode: 0644]
UI/Templates/ContactsUI/UIxContactsAddressBooksSelection.wox [new file with mode: 0644]
UI/Templates/ContactsUI/UIxContactsCalendarsSelection.wox [new file with mode: 0644]
UI/Templates/ContactsUI/UIxContactsFilterPanel.wox [new file with mode: 0644]
UI/Templates/ContactsUI/UIxContactsListView.wox
UI/Templates/ContactsUI/UIxContactsListViewContainer.wox [new file with mode: 0644]
UI/Templates/ContactsUI/UIxContactsMailerSelection.wox [new file with mode: 0644]
UI/Templates/GNUmakefile
UI/Templates/MailPartViewers/UIxMailPartTextViewer.wox
UI/Templates/MailerUI/UIxMailAccountView.wox
UI/Templates/MailerUI/UIxMailAccountsView.wox [deleted file]
UI/Templates/MailerUI/UIxMailEditor.wox
UI/Templates/MailerUI/UIxMailFilterPanel.wox
UI/Templates/MailerUI/UIxMailFolderACLEditor.wox
UI/Templates/MailerUI/UIxMailFolderMenu.wox [new file with mode: 0644]
UI/Templates/MailerUI/UIxMailListView.wox
UI/Templates/MailerUI/UIxMailMainFrame.wox
UI/Templates/MailerUI/UIxMailMoveToPopUp.wox
UI/Templates/MailerUI/UIxMailPanelFrame.wox [deleted file]
UI/Templates/MailerUI/UIxMailPopupView.wox [new file with mode: 0644]
UI/Templates/MailerUI/UIxMailSortableTableHeader.wox [deleted file]
UI/Templates/MailerUI/UIxMailSplashView.wox [new file with mode: 0644]
UI/Templates/MailerUI/UIxMailToSelection.wox
UI/Templates/MailerUI/UIxMailToolbar.wox [deleted file]
UI/Templates/MailerUI/UIxMailTree.wox
UI/Templates/MailerUI/UIxMailTreeBlockJS.wox [new file with mode: 0644]
UI/Templates/MailerUI/UIxMailView.wox
UI/Templates/MailerUI/UIxSieveEditor.wox [moved from UI/Templates/UIxSieveEditor.wox with 96% similarity]
UI/Templates/MainUI/SOGoGroupPage.wox [moved from UI/MainUI/SOGoGroupPage.wox with 100% similarity]
UI/Templates/MainUI/SOGoGroupsPage.wox [moved from UI/MainUI/SOGoGroupsPage.wox with 100% similarity]
UI/Templates/MainUI/SOGoRootPage.wox [moved from UI/MainUI/SOGoRootPage.wox with 100% similarity]
UI/Templates/MainUI/SOGoUserHomePage.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxAppointmentEditor.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxAppointmentProposal.wox [moved from UI/Templates/UIxAppointmentProposal.wox with 92% similarity]
UI/Templates/SchedulerUI/UIxAppointmentView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxAptTableView.wox [moved from UI/Templates/UIxAptTableView.wox with 87% similarity]
UI/Templates/SchedulerUI/UIxCalAptListView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalBackForthNavView.wox [moved from Misc/ZideStore/UI-X/Scheduler/UIxCalBackForthNavView.wox with 96% similarity]
UI/Templates/SchedulerUI/UIxCalCalendarsListView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalDateLabel.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalDateSelector.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalDayChartview.wox [moved from UI/Templates/UIxCalDayChartview.wox with 94% similarity]
UI/Templates/SchedulerUI/UIxCalDayListview.wox [moved from UI/Templates/UIxCalDayListview.wox with 93% similarity]
UI/Templates/SchedulerUI/UIxCalDayOverview.wox [moved from UI/Templates/UIxCalDayOverview.wox with 93% similarity]
UI/Templates/SchedulerUI/UIxCalDayTable.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalDayView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalFilterPanel.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalInlineAptView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalInlineMonthOverview.wox [moved from UI/Templates/UIxCalInlineMonthOverview.wox with 100% similarity]
UI/Templates/SchedulerUI/UIxCalMainView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalMonthOverview.wox [moved from UI/Templates/UIxCalMonthOverview.wox with 91% similarity]
UI/Templates/SchedulerUI/UIxCalMonthView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalParticipationStatusView.wox [moved from UI/Templates/UIxCalParticipationStatusView.wox with 100% similarity]
UI/Templates/SchedulerUI/UIxCalScheduleOverview.wox [moved from UI/Templates/UIxCalScheduleOverview.wox with 100% similarity]
UI/Templates/SchedulerUI/UIxCalSelectTab.wox [moved from UI/Templates/UIxCalSelectTab.wox with 100% similarity]
UI/Templates/SchedulerUI/UIxCalTasksListView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalWeekChartview.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalWeekColumnsview.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalWeekListview.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalWeekOverview.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalWeekView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxCalYearOverview.wox [moved from UI/Templates/UIxCalYearOverview.wox with 85% similarity]
UI/Templates/SchedulerUI/UIxDatePicker.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxFilterList.wox [moved from UI/Templates/UIxFilterList.wox with 100% similarity]
UI/Templates/SchedulerUI/UIxFreeBusyUserSelector.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxFreeBusyUserSelectorTable.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxSortButton.wox [moved from UI/Templates/UIxSortButton.wox with 100% similarity]
UI/Templates/SchedulerUI/UIxTaskEditor.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxTaskProposal.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxTaskView.wox [new file with mode: 0644]
UI/Templates/SchedulerUI/UIxTimeDateControl.wox [new file with mode: 0644]
UI/Templates/UIxAclEditor.wox [new file with mode: 0644]
UI/Templates/UIxAppointmentEditor.wox [deleted file]
UI/Templates/UIxAppointmentPrintview.wox [deleted file]
UI/Templates/UIxAppointmentView.wox [deleted file]
UI/Templates/UIxCalBackForthNavView.wox [deleted file]
UI/Templates/UIxCalDateLabel.wox [deleted file]
UI/Templates/UIxCalDayPrintview.wox [deleted file]
UI/Templates/UIxCalInlineAptView.wox [deleted file]
UI/Templates/UIxCalMonthPrintview.wox [deleted file]
UI/Templates/UIxCalWeekChartview.wox [deleted file]
UI/Templates/UIxCalWeekColumnsview.wox [deleted file]
UI/Templates/UIxCalWeekListview.wox [deleted file]
UI/Templates/UIxCalWeekOverview.wox [deleted file]
UI/Templates/UIxCalWeekPrintview.wox [deleted file]
UI/Templates/UIxContactSelector.wox [deleted file]
UI/Templates/UIxContactsSelectionView.wox [deleted file]
UI/Templates/UIxDatePicker.wox [deleted file]
UI/Templates/UIxDatePickerScript.wox [deleted file]
UI/Templates/UIxException.wox [new file with mode: 0644]
UI/Templates/UIxJSClose.wox [new file with mode: 0644]
UI/Templates/UIxPageFrame.wox
UI/Templates/UIxSortableTableHeader.wox [new file with mode: 0644]
UI/Templates/UIxTimeDateControl.wox [deleted file]
UI/Templates/UIxTimeSelector.wox [deleted file]
UI/Templates/UIxToolbar.wox [new file with mode: 0644]
UI/Templates/UIxUserLogoff.wox [new file with mode: 0644]
UI/WebServerResources/ChangeLog.upstream [moved from UI/WebServerResources/ChangeLog with 100% similarity]
UI/WebServerResources/ContactsUI.css [new file with mode: 0644]
UI/WebServerResources/ContactsUI.js [new file with mode: 0644]
UI/WebServerResources/HTMLElement.js [new file with mode: 0644]
UI/WebServerResources/HTMLInputElement.js [new file with mode: 0644]
UI/WebServerResources/HTMLTableElement.js [new file with mode: 0644]
UI/WebServerResources/HTMLUListElement.js [new file with mode: 0644]
UI/WebServerResources/JavascriptAPIExtensions.js [new file with mode: 0644]
UI/WebServerResources/MailerUI.css [new file with mode: 0644]
UI/WebServerResources/MailerUI.js [new file with mode: 0644]
UI/WebServerResources/SOGoDragAndDrop.js [new file with mode: 0644]
UI/WebServerResources/SOGoDragHandles.js [new file with mode: 0644]
UI/WebServerResources/SOGoUserHomePage.js [moved from UI/MainUI/homepage.js with 100% similarity]
UI/WebServerResources/SchedulerUI.css [new file with mode: 0644]
UI/WebServerResources/SchedulerUI.js [new file with mode: 0644]
UI/WebServerResources/Search-bar.png [new file with mode: 0644]
UI/WebServerResources/UIxAclEditor.css [new file with mode: 0644]
UI/WebServerResources/UIxAclEditor.js [new file with mode: 0644]
UI/WebServerResources/UIxAppointmentEditor.css [new file with mode: 0644]
UI/WebServerResources/UIxAppointmentEditor.js
UI/WebServerResources/UIxContactEditor.css [new file with mode: 0644]
UI/WebServerResources/UIxContactEditor.js
UI/WebServerResources/UIxFreeBusyUserSelector.js [new file with mode: 0644]
UI/WebServerResources/UIxMailEditor.css [new file with mode: 0644]
UI/WebServerResources/UIxMailEditor.js [new file with mode: 0644]
UI/WebServerResources/UIxMailListView.js [deleted file]
UI/WebServerResources/UIxMailToSelection.js
UI/WebServerResources/UIxTaskEditor.css [new file with mode: 0644]
UI/WebServerResources/UIxTaskEditor.js [new file with mode: 0644]
UI/WebServerResources/abcard.gif [new file with mode: 0644]
UI/WebServerResources/accepted.png [new file with mode: 0644]
UI/WebServerResources/account-settings.png [new file with mode: 0644]
UI/WebServerResources/add-addressbook.png [new file with mode: 0644]
UI/WebServerResources/add-contact.gif [new file with mode: 0644]
UI/WebServerResources/apt_icon_private.gif [moved from UI/Scheduler/images/apt_icon_private.gif with 100% similarity]
UI/WebServerResources/arrow-lft-sharp.gif [new file with mode: 0644]
UI/WebServerResources/arrow-rit-sharp.gif [new file with mode: 0644]
UI/WebServerResources/busy.gif [new file with mode: 0644]
UI/WebServerResources/calendar.css
UI/WebServerResources/chair.png [new file with mode: 0644]
UI/WebServerResources/choose-date.png [new file with mode: 0644]
UI/WebServerResources/create-account.png [new file with mode: 0644]
UI/WebServerResources/day-view.png [new file with mode: 0644]
UI/WebServerResources/declined.png [new file with mode: 0644]
UI/WebServerResources/delete.png [new file with mode: 0644]
UI/WebServerResources/downstairs.gif [new file with mode: 0644]
UI/WebServerResources/dtree.css [new file with mode: 0644]
UI/WebServerResources/dtree.js [new file with mode: 0644]
UI/WebServerResources/edit.png [new file with mode: 0644]
UI/WebServerResources/empty.gif [new file with mode: 0644]
UI/WebServerResources/first.gif [moved from UI/Scheduler/images/first.gif with 100% similarity]
UI/WebServerResources/generic.css [new file with mode: 0644]
UI/WebServerResources/generic.js
UI/WebServerResources/goto-today.png [new file with mode: 0644]
UI/WebServerResources/green_corner.gif [moved from UI/Scheduler/images/green_corner.gif with 100% similarity]
UI/WebServerResources/icon_popupcalendar.gif [moved from UI/Scheduler/images/icon_popupcalendar.gif with 100% similarity]
UI/WebServerResources/icon_read.gif
UI/WebServerResources/icon_unread.gif
UI/WebServerResources/icon_view_chart.gif [moved from UI/Scheduler/images/icon_view_chart.gif with 100% similarity]
UI/WebServerResources/icon_view_chart_inactive.gif [moved from UI/Scheduler/images/icon_view_chart_inactive.gif with 100% similarity]
UI/WebServerResources/icon_view_columns.gif [moved from UI/Scheduler/images/icon_view_columns.gif with 100% similarity]
UI/WebServerResources/icon_view_columns_inactive.gif [moved from UI/Scheduler/images/icon_view_columns_inactive.gif with 100% similarity]
UI/WebServerResources/icon_view_list.gif [moved from UI/Scheduler/images/icon_view_list.gif with 100% similarity]
UI/WebServerResources/icon_view_list_inactive.gif [moved from UI/Scheduler/images/icon_view_list_inactive.gif with 100% similarity]
UI/WebServerResources/icon_view_overview.gif [moved from UI/Scheduler/images/icon_view_overview.gif with 100% similarity]
UI/WebServerResources/icon_view_overview_inactive.gif [moved from UI/Scheduler/images/icon_view_overview_inactive.gif with 100% similarity]
UI/WebServerResources/invisible_space_2.gif [moved from UI/Scheduler/images/invisible_space_2.gif with 100% similarity]
UI/WebServerResources/last.gif [moved from UI/Scheduler/images/last.gif with 100% similarity]
UI/WebServerResources/lori_16x16.ico [new file with mode: 0644]
UI/WebServerResources/mailer-compose.css [deleted file]
UI/WebServerResources/mailer-toolbar.css
UI/WebServerResources/mailer.css [deleted file]
UI/WebServerResources/mailer.js [deleted file]
UI/WebServerResources/manage-filters.png [new file with mode: 0644]
UI/WebServerResources/manage-imap.png [new file with mode: 0644]
UI/WebServerResources/manage-newsgroups.png [new file with mode: 0644]
UI/WebServerResources/manage-rss.png [new file with mode: 0644]
UI/WebServerResources/month-view.png [new file with mode: 0644]
UI/WebServerResources/multiweek-view.png [new file with mode: 0644]
UI/WebServerResources/needs-action.png [new file with mode: 0644]
UI/WebServerResources/new-card.png [new file with mode: 0644]
UI/WebServerResources/new-event.png [new file with mode: 0644]
UI/WebServerResources/new-list.png [new file with mode: 0644]
UI/WebServerResources/new-task.png [new file with mode: 0644]
UI/WebServerResources/next.gif [moved from UI/Scheduler/images/next.gif with 100% similarity]
UI/WebServerResources/next_week.gif [moved from Misc/ZideStore/UI-X/Scheduler/images/next_week.gif with 100% similarity]
UI/WebServerResources/offline-settings.png [new file with mode: 0644]
UI/WebServerResources/optional-participant.png [new file with mode: 0644]
UI/WebServerResources/previous.gif [moved from UI/Scheduler/images/previous.gif with 100% similarity]
UI/WebServerResources/previous_week.gif [moved from Misc/ZideStore/UI-X/Scheduler/images/previous_week.gif with 100% similarity]
UI/WebServerResources/properties.png [new file with mode: 0644]
UI/WebServerResources/prototype.js [new file with mode: 0644]
UI/WebServerResources/read-messages.png [new file with mode: 0644]
UI/WebServerResources/remove-addressbook.png [new file with mode: 0644]
UI/WebServerResources/remove-contact.gif [new file with mode: 0644]
UI/WebServerResources/required-participant.png [new file with mode: 0644]
UI/WebServerResources/search-messages.png [new file with mode: 0644]
UI/WebServerResources/skycalendar.html [moved from UI/Scheduler/skycalendar.html with 87% similarity]
UI/WebServerResources/skycalendar.js [moved from UI/Scheduler/English.lproj/skycalendar.js with 100% similarity]
UI/WebServerResources/submenu-active.gif [new file with mode: 0644]
UI/WebServerResources/submenu.gif [new file with mode: 0644]
UI/WebServerResources/tbtv_account_17x17.gif
UI/WebServerResources/tbtv_corner_17x17.gif
UI/WebServerResources/tbtv_corner_minus_17x17.gif
UI/WebServerResources/tbtv_corner_plus_17x17.gif
UI/WebServerResources/tbtv_drafts_17x17.gif
UI/WebServerResources/tbtv_inbox_17x17.gif
UI/WebServerResources/tbtv_junction2_17x17.gif [deleted file]
UI/WebServerResources/tbtv_junction_17x17.gif
UI/WebServerResources/tbtv_leaf_corner_17x17.gif
UI/WebServerResources/tbtv_line_17x17.gif
UI/WebServerResources/tbtv_minus_17x17.gif
UI/WebServerResources/tbtv_plus_17x17.gif
UI/WebServerResources/tbtv_space_17x17.gif [new file with mode: 0644]
UI/WebServerResources/tbtv_trash_17x17.gif
UI/WebServerResources/tentative.png [new file with mode: 0644]
UI/WebServerResources/treeview_corner.gif [moved from UI/MailerUI/Images/treeview_corner.gif with 100% similarity]
UI/WebServerResources/treeview_corner_minus.gif [moved from UI/MailerUI/Images/treeview_corner_minus.gif with 100% similarity]
UI/WebServerResources/treeview_corner_plus.gif [moved from UI/MailerUI/Images/treeview_corner_plus.gif with 100% similarity]
UI/WebServerResources/treeview_junction.gif [moved from UI/MailerUI/Images/treeview_junction.gif with 100% similarity]
UI/WebServerResources/treeview_leaf.gif [moved from UI/MailerUI/Images/treeview_leaf.gif with 100% similarity]
UI/WebServerResources/treeview_leaf_corner.gif [moved from UI/MailerUI/Images/treeview_leaf_corner.gif with 100% similarity]
UI/WebServerResources/treeview_line.gif [moved from UI/MailerUI/Images/treeview_line.gif with 100% similarity]
UI/WebServerResources/treeview_minus.gif [moved from UI/MailerUI/Images/treeview_minus.gif with 100% similarity]
UI/WebServerResources/treeview_plus.gif [moved from UI/MailerUI/Images/treeview_plus.gif with 100% similarity]
UI/WebServerResources/treeview_space.gif [moved from UI/MailerUI/Images/treeview_space.gif with 100% similarity]
UI/WebServerResources/uix.css [deleted file]
UI/WebServerResources/week-view.png [new file with mode: 0644]
UI/WebServerResources/write-message.png [new file with mode: 0644]
UI/WebServerResources/write.png [new file with mode: 0644]
UI/common.make
fhswobundle.make [new file with mode: 0644]

diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..c532738
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1784 @@
+2006-12-22  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/MailerUI/UIxMailMainFrame.m ([UIxMailMainFrame
+       -composeAction]): method imported from removed container modules.
+       ([UIxMailMainFrame -mailFolderName]): method imported from removed
+       container modules.
+
+       * UI/MailerUI/UIxMailPopupView.m: a new special popup component
+       for wrapping UIxMailView with the "popupview" action.
+
+       * UI/MailerUI/UIxMailAccountView.m: renamed to UIxMailSplashView,
+       since its the component that displays the same splash screen than
+       the one in Thunderbird/Icedove.
+
+       * UI/MailerUI/UIxMailAccountViewContainer.[hm],
+       UI/MailerUI/UI/MailerUI/UIxMailAccountsView.m,
+       UI/MailerUI/UIxMailListViewContainer.[hm],
+       UI/MailerUI/UIxMailViewContainer.[hm]: removed
+
+2006-12-20  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/HTMLElement.js: replaced the functional
+       selectNode() and deselectNode() functions with select() and
+       deselect() methods of HTMLElement.
+
+       * UI/WebServerResources/ContactsUI.js: cleanup, most of the
+       events are initialized from here now instead of in the HTML code.
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+       -checkRightsAction]): new method similar to the one with the same
+       name in UIxCalMainView.m.
+
+       * UI/Common/UIxAclEditor.m ([UIxAclEditor -saveAclsAction]): added
+       code to handle the publishing of freebusy information.
+
+2006-12-19  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxCalMainView.m ([UIxCalMainView
+       -checkRightsAction]): new action method that returns a
+       comma-separated list of boolean values matching the right of the
+       current user to "view" (as a permission) each foreign calendar
+       stored in his preferences.
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject -setOwner:newOwner]):
+       new method that sets a customOwner, which can be returned with
+       ownerInContext it set.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -fetchFields:_fieldsfromFolder:_folderfrom:_startDateto:_endDatecomponent:_component]): no longer set the owner of elements here.
+
+2006-12-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/SOGoUserFolder.m: same as for SOGoContactFolders
+       below, but for the Contacts and Calendar collections.
+
+       * SoObjects/SOGo/SOGoAclsFolder.m: convert the class to user the
+       new acl facilities method from sope-gdl/GCSFolder.m.
+
+       * SoObjects/Contacts/SOGoContactFolders.m ([SOGoContactFolders
+       -roleOfUser:uidinContext:context]): new method that returns
+       SOGoRole_Assistant when the user is an assistant or a delegate on
+       the "personal" ab object. This is so that setting roles on the
+       SOGoContactFolders object is not required.
+
+2006-12-14  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * Main/SOGo.m: declare "Freebusy" permissions for the top objects.
+
+       * UI/Contacts/UIxContactsAclsSelection.m: new component specific
+       to the handling of the user selection for the acls.
+
+       * SoObjects/SOGo/SOGoPermissions.[hm]: new module that extends the
+       values from SoPermissions with ones specific to SOGo.
+
+       * SoObjects/SOGo/SOGoAclsFolder.[hm]: new class module that
+       handles the storage for the acls.
+
+       * SoObjects/Appointments/SOGoCalendarComponent.[hm]: new parent
+       class for SOGoAppointmentObject and SOGoTaskObject.
+
+       * UI/Common/UIxAclEditor.[hm]: new component that provides a
+       general editor for folder acls.
+
+       * SoObjects/SOGo/NSString+Utilities.[hm]: old "NSString+URL"
+       renamed.
+       ([NSString -davMethodToObjC]): method that returns the method name 
+       for a DAV property implementation.
+
+       * SoObjects/SOGo/NSArray+Utilities.m: new extension module to
+       NSArray.
+       ([NSArray -stringsWithFormat:format]): new method that returns
+       formatted occurences of the strings stored in the array.
+
+       * SoObjects/SOGo/SOGoDAVRendererTypes.m ([SOGoDAVSet
+       +davSetWithArray:newValuesofValuesTaggedAs:newValueTag]): a new
+       subclass module of SoWebDAVValue that supports collections of
+       properties of the same type.
+
+2006-11-21  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Mailer/SOGoMailAccount.m ([SOGoMailAccount
+       -lookupFolder:ofClassNamed:inContext:]): added the ability to
+       configure the name of the SOGoDraftFolders with the ud var
+       "SOGoDraftsFolderName".
+
+2006-11-17  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject
+       -userTimeZone:username]): new method that returns the timezone for
+       the specified user depending on his preferences and the server
+       defaults
+
+       * SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject
+       -stringForData:partInfo:]): take the encoding into account and
+       translate the text to "normal" before processing the charset data.
+
+2006-11-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/generic.js: the progress indicator is on
+       when loading the page so we turn it off, and we turn it back on
+       whenever we switch to another module...
+
+       * UI/WebServerResources/SchedulerUI.js: make sure the day view
+       synchronization mechanism works everywhere.
+
+       * UI/WebServerResources/generic.js: the log window is not only
+       visible when UIxDebugEnabled is set.
+
+       * UI/WebServerResources/SchedulerUI.js: the month overview's day
+       cells are now initialized with the DOM event interface methods
+       instead of with html attributes.
+
+       * UI/Templates/MailerUI/UIxMailView.wox: don't display useless
+       headers (should be made configurable at some point)...
+
+       * OGoContentStore/sql/generate-folderinfo-sql-for-users.sh: drop
+       "not null" constraint on startdate, enddate, isopaque,
+       participants and partmails.
+
+2006-11-14  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxCalDayTable.m ([UIxCalDayTable
+       -hoursToDisplay]): prevent a crash by retaining the
+       "hoursToDisplay" array after it's created.
+       ([UIxCalDayTable -clickableHourCellClass]): new method for the new
+       clickable hours DIV.
+
+       * UI/WebServerResources/SchedulerUI.js: made the event
+       participation status modification asynchronous, which also fixes a
+       bug where the window would sometimes close before the accept or
+       decline action was completed. Also, adapted the event handling
+       related to the days or weeks view with the new DIV-based layout.
+
+       * UI/Scheduler/UIxCalInlineAptView.m: same as the first below...
+
+       * UI/Scheduler/UIxCalDayTable.m: enhanced to provide the new
+       DIV-based presentation of the days and weeks.
+
+       * SoObjects/Appointments/SOGoTaskObject.m: same as below...
+
+       * SoObjects/Appointments/SOGoAppointmentObject.m: lookupName:...
+       might return an exception so we have to handle it if we don't
+       wanna crash...
+
+2006-11-13  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/SchedulerUI.js: updated the list
+       initialization code to use the new event management scheme, adding
+       what was missing to be able to delete events and tasks again.
+
+       * UI/WebServerResources/MailerUI.js: added code to activate the
+       "Get mails" button. Fixed a bug which prevented messages to be
+       deleted.
+
+       * UI/WebServerResources/UIxFreeBusyUserSelector.js: handle tab
+       navigation and focus handling of INPUTs.
+
+2006-11-10  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/MailerUI.js: added code to handle the
+       possible drag and drop events to manager in the mail module.
+       Moving messages, opening parent folders, ...
+
+       * UI/WebServerResources/SOGoDragAndDrop.js: new file containing
+       the drag and drop manager as well as the interface to HTMLElement
+       to trigger drag and drop events.
+
+       * UI/MailerUI/UIxMailView.m ([UIxMailView -moveAction]): new
+       action to move the current message to the mailbox named after the
+       value of parameter "tofolder".
+
+       * SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject
+       -moveToFolderNamed:folderNameinContext:]): new method base on
+       -trashInContext:.
+
+2006-11-09  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/generic.js: added and activated many
+       "load" handlers to configure generic widgets used across the
+       modules. More events are now handled in a DOM-fashion way instead
+       of by setting the relative attributes in the templates.
+
+       * UI/Templates/UIxSortableTableHeader.wox: all the events are
+       declared from the javascript DOM onload handlers.
+
+       * UI/Templates/UIxPageFrame.wox: load the new SOGoDragHandles.js
+       library.
+
+       * UI/Templates/MailerUI/UIxMailListView.wox: all the events are
+       declared from the javascript DOM onload handlers.
+
+       * UI/MailerUI/UIxMailListView.m: removed all the JS methods since
+       we want everything to be separated from each other, as much as
+       possible.
+
+       * UI/WebServerResources/SOGoDragHandles.js: new module containing
+       the "SOGoDragHandlesInterface", implementing methods that can be
+       attributed to DIV so that they can be used as drag handles.
+
+       * SoObjects/Mailer/SOGoDraftObject.m ([NSString
+       -asQPSubjectString]): initialize the tmp strings with '0' to make
+       sure they don't contain garbage.
+
+2006-11-08  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/MailerUI.js: register the messageList
+       table as a dragging source and the leaf of the navigation tree as
+       dnd destinations to the DNDManager.
+
+       * UI/WebServerResources/generic.js: initialize tabs from the
+       "unload" event listener that is added programmatically instead of
+       from the template... Also, added the new DNDManager object.
+
+       * UI/WebServerResources/HTMLTableElement.js: added code to
+       simulate XUL drag n drop events. This code will possibly be moved
+       to HTMLElement.js instead later...
+
+       * SoObjects/Contacts/SOGoContactLDAPFolder.m
+       ([SOGoContactLDAPFolder -_qualifierForFilter:filter]): same as
+       below.
+
+       * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder
+       -_qualifierForFilter:filter]): only search records which starts
+       with the specified pattern.
+
+2006-11-07  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Mailer/SOGoDraftObject.m ([NSString
+       -asQPSubjectString]): new method that returns the special QP
+       string with its qp declaration for email subjects.
+       ([SOGoDraftObject -bodyPartForText]) 
+       ([SOGoDraftObject -mimeMessageForContentWithHeaderMap:]): don't
+       double-encode data in UTF-8.
+
+       * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
+       -newStartDate]): new method to determine the start date depending
+       on the URL parameters, the current day and the current time.
+       ([UIxComponentEditor -toolbar]): new method to determine the
+       filename of the toolbar that should be drawn depending on the
+       ownership and the list of attendees of the task/event wrt to the
+       current user...
+
+       * UI/Scheduler/UIxTimeDateControl.m ([UIxTimeDateControl
+       -setDayStartHour:aStartHour]): adjust the minutes to the next
+       quarter of hour, if not already set to a quarter.
+
+       * UI/WebServerResources/UIxAppointmentEditor.js,
+       UI/WebServerResources/UIxTaskEditor.js: added code to manage start
+       date change.
+
+2006-11-03  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
+       -loadValuesFromComponent:component]): handles access class
+       (privacy) and status.
+
+       * UI/Contacts/UIxContactsListViewContainer.m
+       ([UIxContactsListViewContainer -additionalFolders]): return nil if
+       [self additionalAddressBooks] returns an empty string.
+
+2006-11-02  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxCalMonthView.m ([UIxCalMonthView
+       rangesOf7Days]): enhanced and debugged algorithm to feed the array
+       with slices where the first day is still in the requested month.
+
+       * UI/Templates/UIxPageFrame.wox: the logConsole is created only on
+       non-popup pages.
+
+       * UI/SOGoUI/SOGoAptFormatter.m: added code to handle the display
+       of events in the day boxes of the calendar's monthly view.
+
+       * SoObjects/Appointments/SOGoTaskObject.m ([SOGoTaskObject
+       -davContentType]): declare "text/calendar".
+
+       * SoObjects/Appointments/SOGoAppointmentObject.m
+       ([SOGoAppointmentObject -davContentType]): declare
+       "text/calendar".
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -lookupName:inContext:acquire:]): certain
+       HTTP methods are handled by SOPE and requires nil to be returned,
+       this method now invokes the new
+       "requestNamedIsHandledLater:inContext:" method to check that.
+       ([SOGoAppointmentFolder
+       -requestNamedIsHandledLater:nameinContext:context]): new methods
+       that returns "YES" only for the "OPTIONS" http method (for now...).
+       ([SOGoAppointmentFolder -davComplianceClassesInContext:]):
+       overloaded method to append the "access-control" and
+       "calendar-access" DAV abilities to the initial declaration.
+
+       * UI/Scheduler/UIxCalMonthView.[hm]: rewritten module entirely to
+       imitate the look of Sunbird/Lightning's monthly view.
+
+       * UI/Scheduler/UIxCalMonthView.[hm]: renamed to
+       UIxCalMonthViewOld.[hm].
+
+2006-11-01  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxFreeBusyUserSelectorTable.m
+       ([UIxFreeBusyUserSelectorTable -currentContactHasStatus]): new
+       method.
+       ([UIxFreeBusyUserSelectorTable -currentContactStatusImage]):
+       returns an image name based on the participation status of the
+       current attendee.
+
+       * UI/WebServerResources/SchedulerUI.js: same strip down as for
+       generic.js below.
+
+       * UI/Contacts/UIxContactsListViewContainer.m ([UIxContactsListViewContainer -additionalAddressBooks]) 
+       ([UIxContactsListViewContainer -additionalFolders]) 
+       ([UIxContactsListViewContainer -setCurrentAdditionalFolder:newCurrentAdditionalFolder]) 
+       ([UIxContactsListViewContainer -currentAdditionalFolder]): new
+       methods to handle the external addressbooks a user has subscribed
+       too, by retriving them from his preferences.
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+       -updateAdditionalAddressBooksAction]): new method that updates the
+       user settings with the list of addressbook he has subscribed to.
+
+       * UI/Contacts/UIxContactsAddressBooksSelection.m: new component
+       module for the address book selector.
+
+       * UI/Templates/ContactsUI/UIxContactsListViewContainer.wox: added
+       a toolbar with two buttons ("add" and "remove") to manage the
+       additional addressbooks a user might subscribe to.
+
+       * UI/WebServerResources/ContactsUI.js: added code to handle
+       "external addressbooks" from the Javascript point-of-view, by
+       extending existing methods and adding code for the "add ab" and
+       "remove ab" buttons.
+
+       * UI/WebServerResources/generic.js: moved extensions methods to
+       DOM elements to separate files for better clarity.
+
+       * UI/Common/UIxPageFrame.m ([UIxPageFrame -pageContentClasses]):
+       new method that returns "pageContent" as class, but also "popup"
+       for the DIV where the page content lies, so that we can manipulate
+       the content of popup's with CSS identifiers.
+
+2006-10-31  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxCalInlineAptView.m ([UIxCalInlineAptView
+       -displayStyle]): new method that returns a string containing the
+       css style relative to the current appointment cell. This code is
+       currently inactive but might be reused later.
+
+       * UI/WebServerResources/SchedulerUI.js: added code to handle the
+       display of the selected day (the day pointed by the mouse, or the
+       current day when changing the view).
+
+       * UI/Scheduler/UIxCalDayTable.m ([UIxCalDayTable
+       -dayCellClasses]): new method that returns a string containing the
+       css classes applicable to the current cell, depending on the
+       position of the day in the week, the day of today and the
+       requested day.
+
+       * UI/Scheduler/UIxCalCalendarsListView.m ([UIxCalCalendarsListView
+       -currentContactAptBorder]): new method that returns the
+       appropriate border color for the specified user.
+
+       * SoObjects/Appointments/SOGoAppointmentObject.m
+       ([SOGoAppointmentObject
+       -saveContentString:contentStringbaseVersion:baseVersion]):
+       overloaded method that parse new events and detects if they have
+       an organizer or not. If they are new and have no organizer set
+       (Sunbird/Lightning...), the owner of the event is set as
+       organizer.
+
+       * SoObjects/Appointments/iCalEntityObject+Agenor.[hm]: new
+       category that provides facility methods and interfaces to the
+       AgenorUserManager.
+
+       * SoObjects/Contacts/product.plist: give full access to ANY
+       authenticated user, not just the owner (to every objects...).
+
+2006-10-30  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/UIxFreeBusyUserSelector.js: make sure
+       every replica widgets are declared as such to their master
+       counterpart. Take the days into account when displaying the time
+       range taken by the appointment.
+
+       * UI/Scheduler/UIxComponent+Agenor.m ([UIxComponent
+       -getICalPersonsFromValue:selectorValue]): method taken from
+       UIxFreeBusyUserSelector, that is shared both by
+       UIxFreeBusyUserSelector and UIxFreeBusyUserSelectorTable.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -fetchFields:_fieldsfromFolder:_folderfrom:_startDateto:_endDatecomponent:_component]): reverted to search algorithm to search for events happening outside 0 or 1 (at most) boundary of the timerange.
+
+       * UI/Scheduler/UIxFreeBusyUserSelectorTable.[hm]: new subcomponent
+       derived and taken as a subset of UIxFreeBusyUserSelector that
+       implements the table part of the FreeBusy view. Most of the
+       methods of UIxFreeBusyUserSelector relative to that table were
+       moved into UIxFreeBusyUserSelectorTable, which can also be used as
+       a standalone view for AJAX operations.
+
+2006-10-27  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+       -vCard]): change reverted.
+
+       * UI/Contacts/UIxContactEditor.m: check whether the client contact
+       folder has selector "globallyUniqueObjectId" before calling that
+       method.
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+       -vCard]): the "setVClass" NGVCard method really is "setClass"
+       instead.
+
+       * SoObjects/Contacts/SOGoContactLDAPFolder.m
+       ([SOGoContactLDAPFolder -_searchAttributes]): fixed typo to
+       request the "streetAddress" instead of the "streetaddress".
+       ([SOGoContactLDAPFolder -_qualifierForFilter:filter]): lookup
+       mails that *contain*, and not just *start with* the search
+       pattern.
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+       -vCard]): mark address returned from LDAP as the work address.
+
+       * UI/Templates/SchedulerUI/UIxCalInlineAptView.wox: made the whole
+       span covered with the anchor, not only the textual information
+       within.
+
+       * UI/Templates/SchedulerUI/UIxCalMainView.wox: specify the type
+       argument (event or task) to newEvent in the appointmentListMenu.
+       Make the appointmentsListView display the appointmentsListMenu.
+
+       * UI/SOGoUI/SOGoAptFormatter.m: enlarge the text size limit from
+       12 to 50 before displaying "...".
+       ([SOGoAptFormatter -fullDetailsForApt::]): display location only
+       if its length > 0, whether location itself is nil or not...
+       ([SOGoAptFormatter -tooltipForApt::_refDate]): display information
+       of which the length > 0.
+
+2006-10-26  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/UIxAppointmentEditor.js: correctly handles
+       french and ISO dates.
+
+       * UI/Scheduler/UIxFreeBusyUserSelector.[hm]: added code an ivars
+       from UIxContactSelector to handle contact lists (current and
+       additional contacts).
+
+       * UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage
+       -_freeBusyAsText]): added handling of an "additional"-named query
+       parameter that describe the number of additional days after
+       enddate that should be returned.
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+       -_responseForResults:results]): give priority to results with
+       "c_uid" fields. If none returned, use the first contact received.
+
+       * OGoContentStore/OCSiCalFieldExtractor.m ([OCSiCalFieldExtractor
+       -extractQuickFieldsFromEvent:_event]): changed "TENTATIVE" code to
+       2 and "CANCELLED" to 0.
+
+2006-10-25  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/UIxAppointmentEditor.js: handle conversion
+       of start and end dates to short string dates.
+
+       * UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage
+       -readFreeBusyAction]): new method that returns an array of numbers
+       corresponding to the state in the freebusy of each "quarter of an
+       hour" between the "sday" and "eday" date parameters passed in the
+       url. This permits to handle the display of the freebusy with Ajax
+       mechanisms.
+       ([SOGoUserHomePage -_freeBusyAsText]): add 2 days to the end date
+       since the free busy displays 2 days ahead.
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+       -contactSearchAction]): new action that returns the uid and the
+       username + email of the user whose name contain the value of the
+       "search" url parameter.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -fetchFreebusyInfosFrom:_startDateto:_endDate]): added fields
+       useful for the computing of the status of the freebusy.
+
+       * UI/Scheduler/UIxFreeBusyUserSelector.m ([UIxFreeBusyUserSelector
+       -init]): new component that incarnates a user selector for events
+       inspired by the new one found in Thunderbird Lightning.
+
+2006-10-23  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/generic.js: added code to enable or
+       disable anchor visually (following our internal algorithm).
+
+       * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor -init]):
+       added new "url" ivar with its classic accessors.
+       ([UIxComponentEditor -urlButtonClasses]): new method that returns
+       the class strings for the url button on the appointment/task
+       editor (depending on the validity of the url).
+
+       * UI/Templates/SchedulerUI/UIxTaskEditor.wox,
+       UI/Templates/SchedulerUI/UIxAppointmentEditor.wox: start rewriting
+       the template to match the Lightning's new task/appointment editor.
+
+       * UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor -saveValuesIntoAppointment:_appointment]): initialize url from the components'url.
+
+       * UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor -saveValuesIntoTask:_task]): initialize url from the components'url.
+
+2006-10-20  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Contacts/SOGoContactLDAPFolder.m
+       ([SOGoContactLDAPFolder
+       -lookupContactsWithFilter:filtersortBy:sortKeyordering:sortOrdering]): perform the searchs on objects which start with instead of contain the lookup key.
+
+       * SoObjects/Appointments/SOGoAptMailNotification.[hm]: work on
+       iCalEntityObject instances instead of just iCalEvent's.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -fetchFields:_fieldsfromFolder:_folderfrom:_startDateto:_endDatecomponent:_component]): set ownership of returned records by adding an "owner" key to the resulting dictionaries.
+
+       * SoObjects/SOGo/NSObject+Owner.[hm]: removed module since it's a
+       bad way of handling ownership that way.
+
+       * SoObjects/Contacts/SOGoContactLDAPFolder.m
+       ([SOGoContactLDAPFolder -_qualifierForFilter:filter]): search also
+       on "cn", just like Mozilla.
+
+2006-10-19  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/MailerUI/UIxMailToSelection.m ([UIxMailToSelection -to]):
+       "to" should be retained, otherwise it will be autoreleased and a
+       crash will occur.
+
+       * UI/Contacts/UIxContactEditor.m ([UIxContactEditor
+       -writeAction]): updated method to fetch the card before initing
+       the snapshot.
+
+       * OGoContentStore/OCSiCalFieldExtractor.m ([OCSiCalFieldExtractor
+       -extractQuickFieldsFromTodo:_task]): fixed to use NSNull instead
+       of NSNotFound.
+
+       * UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor
+       -iCalStringTemplate]): start and due date are now optional.
+
+       * UI/Scheduler/UIxTimeDateControl.m ([UIxTimeDateControl
+       -setDayStartHour:aStartHour]):  added a new "isDisabled" ivar with
+       appropriate accessors to be settable through the templates.
+
+       * UI/Scheduler/UIxDatePicker.m ([UIxDatePicker -init]): added a
+       new "isDisabled" ivar with appropriate accessors to be
+       settable through the templates.
+
+       * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
+       -availableCalendars]): new method that list the calendars to which
+       the user has subscribed.
+       ([UIxComponentEditor -componentOwner]): returns the owner of the
+       editted object.
+
+       * OGoContentStore/OCSiCalFieldExtractor.m ([OCSiCalFieldExtractor
+       -extractQuickFieldsFromTodo:_task]): set the start and enddate of
+       quickentries to null whenever each or all of them are null, by
+       providing an impossible timestamp from with NSNotFound as value.
+
+2006-10-18  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/UIxMailEditor.js: update the algorithm
+       that handles the creation of new fields with the new APIs and the
+       new node structure on the page.
+
+       * UI/Scheduler/UIxAppointmentEditor.m,
+       UI/Scheduler/UIxTaskEditor.m:
+       refactored to user UIxComponentEditor as parent class.
+
+       * UI/Scheduler/UIxComponentEditor.[hm]: new class module
+       containing the methods common to the UIxTaskEditor and the
+       UIxAppointmentEditor.
+
+2006-10-17  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -doCalendarQuery:context]): now supports
+       the handling of time-ranges.
+
+       * UI/WebServerResources/ContactsUI.js: specify a notification type as
+       parameters when onConfirmContactSelection in invoked.
+
+       * UI/WebServerResources/generic.js: specify a notification type as
+       parameters when onContactRemove in invoked.
+
+       * UI/WebServerResources/SchedulerUI.js: when the user deselects
+       all calendars, select his entry.
+
+2006-10-16  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/SchedulerUI.js: edit and delete events
+       with their owner-relative urls. Generate a correct entry in the
+       css color table when a user is added to the calendars list. Put
+       the same color next to the user id.
+
+       * UI/WebServerResources/generic.js: implemented some new helper
+       methods.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -deleteEntriesWithIds:ids]): don't delete
+       entries if their owner is not the current user.
+
+       * UI/Scheduler/UIxCalInlineAptView.m ([UIxCalInlineAptView
+       -displayClasses]): return the correct class for the current event
+       representation depending on its owner.
+
+       * UI/Scheduler/UIxCalCalendarsListView.m: added method to create
+       and associate a color for each user login depending on its
+       position in the list.
+
+       * UI/Scheduler/UIxCalAptListView.m ([UIxCalAptListView
+       -currentRowCSSClass]): return the correct class for the current
+       row depending on the owner of the event.
+
+       * UI/Contacts/UIxContactSelector.m ([UIxContactSelector
+       -setColors:colors]): new method to associate a color table with
+       each user in the list.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -fetchFields:_fieldsfromFolder:_folderfrom:_startDateto:_endDatecomponent:_component]): associate each returned record with the owner of the table they are retrieved from.
+
+       * SoObjects/SOGo/NSObject+Owner.[hm]: new extension module to
+       NSObject to associate an instance with a user.
+
+2006-10-13  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/SchedulerUI.js: added handling of multiple
+       calendars.
+
+       * UI/WebServerResources/ContactsUI.js: added handling of
+       notification of changes to contact selectors.
+
+       * UI/WebServerResources/generic.js: added handling of notification
+       of changes to contact selectors.
+
+       * UI/Scheduler/UIxCalMainView.m ([UIxCalMainView
+       -updateCalendarsAction]): proxy method to update the user
+       preference table with the new selected calendar uids.
+
+       * UI/Contacts/UIxContactsListView.m ([UIxContactsListView
+       -calendarsContactsAction]): new method.
+
+       * UI/Contacts/UIxContactSelector.m ([UIxContactSelector -setCheckedBoxes:boxes]) 
+       ([UIxContactSelector -setHasCheckBoxes:aBool]) 
+       ([UIxContactSelector -isCheckBoxChecked]): new accessors method to
+       permit the drawing of checkboxes instead of card icons.
+
+       * UI/Scheduler/UIxCalCalendarsListView.m: new component class that
+       wrap a selector the the "Calendars" tab.
+
+       * UI/Contacts/UIxContactsCalendarsSelection.m: buttons for the
+       new user calendar selector.
+
+2006-10-12  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Templates/SchedulerUI/UIxAppointmentEditor.wox: time ranges
+       may cover hour 0 to hour 23.
+
+       * UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor
+       -iCalStringFromQueryParameter:format:]): dates explicitly set to
+       utc tz.
+
+       * UI/WebServerResources/SchedulerUI.js: manage both lists of
+       objects wrt to the toolbar actions.
+
+       * UI/WebServerResources/generic.js: added code to the "String"
+       class to decode number-encoded char entities.
+
+       * UI/Scheduler/UIxCalMainView.m ([UIxCalMainView
+       -batchDeleteAction]): new method to delete selected entries in the
+       lists.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -deleteEntriesWithIds:ids]): new method
+       that delete identified entries in batch.
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent
+       -jsCloseWithRefreshMethod:methodName]): new method with explicit purpose.
+
+       * UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor -saveAction]),
+       UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor
+       -saveAction]), UI/MailerUI/UIxMailEditor.m ([UIxMailEditor
+       -sendAction]), UI/Contacts/UIxContactEditor.m ([UIxContactEditor
+       -saveAction]):
+       return a UIxJSClose component if everything went fine.
+
+       * UI/Scheduler/UIxTaskEditor.h: interface extracted from
+       UIxTaskEditor.m.
+
+       * UI/Scheduler/UIxAppointmentEditor.h: interface extracted from
+       UIxAppointmentEditor.m.
+
+       * UI/Common/UIxJSClose.[hm]: new UIxComponent designed to display
+       a very light page with javascript code to close a window, by
+       calling a method on the opener if specified. This component is
+       designed to work as a response to form postings.
+
+2006-10-11  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Appointments/SOGoTaskObject.[hm]: clone of
+       SOGoAppointmentObject adapted for the handling of tasks.
+
+       * SoObjects/Appointments/NSArray+Appointments.[hm]: category
+       extracted from SOGoAppointmentObject.
+
+       * UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor
+       -saveUrl]): returns the url needed to POST the new form to.
+       redirect the user to <aptid>/editAsAppointment instead of /edit,
+       so that SOGoAppointmentFolder can return the correct object type.
+
+       * SoObjects/SOGo/NSObject+AptComparison.m ([NSObject
+       -compareAptsAscending:_other]): accept empty start or end dates.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -fetchFields:_fieldsfromFolder:_folderfrom:_startDateto:_endDatecomponent:_component]): added a "component" parameter to match the query against the specified component types. Made startDate and endDate optional by ignoring them altogether in the query whenever one of them is nil.
+       ([SOGoAppointmentFolder -doCalendarQuery:context]): fetch
+       components of type "vtodo" as well as "vevent".
+       ([SOGoAppointmentFolder -lookupName:inContext:acquire:]): if the
+       url specified ends with AsTask or AsAppointment, returns the
+       an object of the appropriate class, otherwise deduce it from its
+       content if the HTTP method is "PUT", otherwise read its type from
+       the quick table.
+
+       * OGoContentStore/OCSiCalFieldExtractor.m ([OCSiCalFieldExtractor
+       -extractQuickFieldsFromTodo:_task]): extract quick fields from
+       tasks.
+
+       * UI/Scheduler/UIxCalView.m ([UIxCalView
+       -fetchCoreAppointmentsInfos]): replacement methods for
+       fetchCoreInfos but by retrieving object with component "vevent".
+       ([UIxCalView -fetchCoreTasksInfos]): same as above for "vtodo"
+       components.
+
+       * UI/Scheduler/UIxCalTasksListView.[hm]: clone of
+       UIxCalAptListView adapted for the handling of tasks.
+
+       * UI/Scheduler/UIxTaskProposal.[hm],
+       UI/Scheduler/UIxTaskView.[hm], UI/Scheduler/UIxTaskEditor.[hm]:
+       clones of the UIxAppointment* classes for the handling of tasks.
+
+       * UI/WebServerResources/UIxTaskEditor.js: clone of
+       UIxAppointmentEditor adapted for the handling of tasks.
+
+       * UI/WebServerResources/SchedulerUI.js: added support for tasks.
+       Scroll the daily view to the appropriate hour when an appointment
+       is selected in the appointments list.
+
+2006-10-05  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxTimeDateControl.m ([UIxTimeDateControl
+       -setDayStartHour:aStartHour]): specifies the user timezone on the
+       given date.
+
+       * UI/Scheduler/UIxAppointmentEditor.m: indicate DTSTAMP with "GMT"
+       as timezone.
+
+       * SoObjects/SOGo/NSCalendarDate+SOGo.m ([NSCalendarDate -adjustedDate]) 
+       ([NSCalendarDate -driftedDate]): methods made useless by a better
+       comprehension of the NSTimeZone API...
+
+2006-10-04  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent -selectedDate]): call
+       new methods from the NSCalendarDate methods.
+
+       * SoObjects/SOGo/NSCalendarDate+SOGo.m: module replacing and
+       extending UI/Scheduler/NSCalendarDate+Scheduler.m.
+       ([NSCalendarDate
+       +dateFromShortDateString:dateStringandShortTimeString:timeStringinTimeZone:timeZone]): new method that generates a date from two short string formatted as follow: "yyyymmdd" and "hhmm". Thismethod replaces a similar method from UIxComponent (noted below).
+       ([NSCalendarDate -adjustedDate]): this method returns another
+       instance set to the correct hour after the original date was set
+       from a non-GMT timezone. This date can be used for storage.
+       ([NSCalendarDate -driftedDate]): this method does exactly the
+       opposite of -adjutedDate, that is, it enables the method
+       hourOfDay, minuteOfHour etc... to return the values according to
+       the original date's timezone. This date CANNOT be used for storage.
+
+       * UI/Scheduler/NSCalendarDate+Scheduler.m ([NSCalendarDate
+       -shortDateString]): new method that will return a "short date
+       string" (yyyymmdd) from a calendar date object.
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent
+       -_cDateFromShortDateString:dateStringandShortTimeString:timeString]): new method to compute the selected date from the "day" and "hm" query parameters (if found). This method replaces the old algorithm that was found in the "selectedDate" method.
+
+       * Main/sogod.m (main): initialize the NSTimeZone's defaultTimeZone
+       to the value of SOGoServerTimeZone or "Canada/Eastern" if not found.
+
+2006-10-03  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/SchedulerUI.js: added code to scroll the
+       view of the day at the height of hour 8:00.
+
+       * UI/Scheduler/UIxCalView.m ([UIxCalView -dayStartHour]): returns 0.
+       ([UIxCalView -dayEndHour]): returns 24.
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView -defaultAction]) 
+       ([UIxContactFoldersView -newAction]): invoke
+       _selectActionForApplication: on self with the proper attribute too.
+
+       * UI/Contacts/UIxContactsSelectionViewContainer.m: removed since
+       we now use the action mechanism in UIxContactsListView to keep the
+       same view for the contact selectors and the regular contact view.
+
+       * UI/Contacts/UIxContactsListViewContainer.[hm]: replaces
+       UIxContactsListViewContainerBase.[hm]
+
+       * UI/Contacts/UIxContactsListView.[hm]: replaces UIxContactsListViewBase.[hm]
+
+       * UI/WebServerResources/generic.js: generalized emailstring
+       handling functions. Generalized address book access functions.
+
+       * UI/Contacts/UIxContactsListViewBase.m ([UIxContactsListViewBase
+       -isPopup]): return YES if the "popup" query parameter is set.
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+       -defaultAction]): keep the url parameters when redirecting.
+       ([UIxContactFoldersView -selectForSchedulerAction]) 
+       ([UIxContactFoldersView -selectForMailerAction]): new action
+       methods for the /scheduler-contacts and /mailer-contacts invocations.
+
+       * SoObjects/SOGo/SOGoObject.m: compose the action url using the
+       newly available NSString+URL category.
+
+       * SoObjects/SOGo/NSDictionary+URL.m ([NSDictionary
+       -asURLParameters]): handle dictionary entries which could be
+       instances of NSArray rather than NSString.
+
+       * SoObjects/SOGo/NSString+URL.m ([NSString
+       -composeURLWithAction:actionparameters:urlParametersandHash:useHash]): when composing the url, remove the encoded parameters first since they will be added later.
+       ([NSString -urlWithoutParameters]): new method that returns the
+       url without its parameters.
+
+       * SoObjects/SOGo/NSString+iCal.h: deleted obsolete file.
+
+       * SoObjects/SOGo/NSDictionary+URL.[hm],
+       UI/SOGoUI/NSString+URL.[hm]: moved from UI/SOGoUI/.
+
+       * UI/WebServerResources/UIxMailEditor.js: add support for
+       additions of different types (to, cc, bcc) of recipients from the
+       address book.
+
+       * UI/Common/UIxPageFrame.m ([UIxPageFrame -doctype]): added the
+       "<?xml..." header.
+
+       * UI/Contacts/UIxContactsMailerSelection.m,
+       UI/Contacts/UIxContactsSchedulerSelection.m: classes replacing
+       UI/Contacts/UIxContactsSelectionView.m to provide a different set
+       of widgets depending on the application invoking the contact list.
+
+2006-09-29  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/ContactsUI.js: hide the current contact
+       whenever the user changes of contact folder.
+
+       * UI/WebServerResources/UIxContactEditor.js: the contact UID is
+       now provided by the template when loading the page.
+
+       * SoObjects/SOGo/AgenorUserManager.m ([AgenorUserManager
+       -iCalPersonWithUid:uid]): new method taken from removed module
+       'iCalPerson+UIx';
+
+2006-09-28  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxAppointmentView.m ([UIxAppointmentView
+       -categoriesAsString]): same as below.
+
+       * UI/Scheduler/UIxAppointmentEditor.m: adapted by using the new
+       vcalendar API's iCalEvent instead of the removed SOGoAppointment.
+
+       * SoObjects/Appointments/SOGoAppointmentObject.m
+       ([SOGoAppointmentObject -calendarFromContent:cnt]): new helper method.
+       ([SOGoAppointmentObject -firstEventFromCalendar:calendar]): new
+       helper method.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -doCalendarQuery:context]): added a
+       hackish test to detect whether the request concernes VEVENT's or
+       anything else. Return events only in the former case.
+       ([SOGoAppointmentFolder
+       -fetchOverviewInfosFrom:_startDateto:_endDate]): retrieve the
+       c_name quickfield so that the calendar list can identify the
+       appointments with their complete "filename".
+
+       * OGoContentStore/OCSiCalFieldExtractor.m: use CardGroup's
+       groupsOfClass:fromSource: to parse the given vcalendar.
+
+       * UI/Scheduler/iCalRecurrenceRule+SOGo.m: removed obsolete class.
+
+       * UI/Scheduler/SOGoAppointment+UIx.h: removed obsolete class.
+
+       * SoObjects/SOGo/SOGoAppointmentICalRenderer.[hm]: removed
+       obsolete class.
+
+       * SoObjects/SOGo/SOGoAppointment.[hm]: removed obsolete class.
+
+2006-09-26  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -lookupName:inContext:acquire:]): be
+       sensitive to the CalDAV method names.
+       ([SOGoAppointmentFolder -doCalendarQuery:context]): method for the
+       "calendar-query" CalDAV method name.
+
+       * UI/WebServerResources/ContactsUI.js: removed a lot of useless
+       code coming originally from MailerUI.js.
+
+       * UI/WebServerResources/UIxContactEditor.js: imitate the
+       Thunderbird address book by completing the display name with the
+       content of the first and last name fields, until the display name
+       is modified manually.
+
+       * UI/WebServerResources/generic.js: added a "trim" method to the
+       String class.
+
+       * UI/Contacts/UIxContactsListViewBase.m ([UIxContactsListViewBase
+       -displayName]): new method that returns the display name from "cn"
+       or from the "displayName" key if found.
+
+       * UI/Contacts/UIxContactEditor.m ([UIxContactEditor
+       -initSnapshot]): check if "[card n]" returns anything to avoid a
+       crash.
+
+       * UI/Common/UIxPageFrame.m ([UIxPageFrame -doctype]): new method
+       that returns an unparsed doctype definition for the pages.
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+       -vCard]): set the card's fn to attribute "displayName" if found
+       before "cn".
+
+2006-09-20  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+       -vCard]): handle the "streetAddress" and "l" fields.
+
+       * UI/Templates/MailerUI/UIxMailEditor.wox: arranged the message
+       header fields by converting the tables to DIVs and SPANs.
+
+       * UI/WebServerResources/generic.css: attempted unification of font
+       families and size across all the elements. changed the
+       logConsole's "position" from "fixed" to "absolute" to avoid
+       performance issues.
+
+2006-09-19  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/ContactsUI.js (uixDeleteSelectedContacts):
+       empty the contact view when the current contact is being deleted.
+
+       * UI/WebServerResources/MailerUI.js (newContactFromEmail): fully
+       parse the email field and provide the address full name if found
+       as the "contactFN" parameter.
+
+       * UI/WebServerResources/generic.js (openMailTo): do not give a
+       name to the opened window so that serveral ones can be opened at
+       the same time.
+
+       * UI/MailPartViewers/UIxMailPartTextViewer.m
+       ([UIxMailPartTextViewer -flatContentAsString]): override method by
+       replacing carriage returns with "<br />" in the result string from
+       super's implementation.
+
+       * UI/Contacts/UIxContactView.m ([UIxContactView
+       -_urlOfType:aType]): don't manage non-mailto urls through
+       javascript, let the user decide what's best for him.
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+       -newAction]): transfer all the query parameters by using the
+       "asURLParameters"'s result string from [self queryParameters].
+
+       * UI/Contacts/UIxContactEditor.m ([UIxContactEditor
+       -initSnapshot]): retrieve "contactEmail" and "contactFN" from the
+       query parameters and put their values (if any) into the snapshot.
+
+       * UI/Contacts/UIxContactView.m ([UIxContactView -note]): convert
+       carriage-returns to "<br />".
+       ([UIxContactView -workCompany]): explicitly initialize company to
+       nil if org is nil or empty.
+
+       * UI/WebServerResources/UIxContactEditor.js: updated validation
+       code after we added and renamed some fields.
+
+       * UI/WebServerResources/ContactsUI.js: added code to cache contact
+       cards and to handle card updates.
+
+2006-09-18  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Contacts/UIxContactView.m ([UIxContactView -hasOtherInfos]):
+       test the length of the returned string since they will never be
+       nil.
+
+       * UI/Contacts/UIxContactEditor.m ([UIxContactEditor -saveAction]):
+       return self if the process went successful, returns an exception
+       otherwise (and only otherwise...).
+
+       * OGoContentStore/OCSContactFieldExtractor.m
+       ([OCSContactFieldExtractor -extractQuickFieldsFromVCard:_vCard]):
+       adapted method to the new VCard api. Since the cards are stored in
+       vcard format, we no longer deal with a dictionary but with a
+       NGVCard object...
+
+2006-09-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Contacts/UIxContactView.m ([UIxContactView -preferredEmail]):
+       return a string with a "mailto" url.
+       ([UIxContactView -_urlOfType:aType]): generic method to return a
+       url string with a html anchor pointing to it.
+
+       * UI/Contacts/UIxContactEditor.[hm]: UIxContactEditorBase renamed
+       since subclass "UIxContactEditor" did nothing. Implemented code to
+       display and modify the values parsed from the vcards, displayed in
+       a way similar to the Thunderbird addressbook.
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+       -save]): new dummy method.
+
+       * SoObjects/Contacts/SOGoContactGCSEntry.m ([SOGoContactGCSEntry
+       -save]): made method void.
+
+2006-09-13  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Contacts/UIxContactView.m: added many wrapper methods to
+       display blocks of data Ã  la Thunderbird Addressbook. If data is
+       available, those wrappers (around the NGVCard methods) will
+       enclose the results in a proper HTML output with the correct label
+       (if present), otherwise it will return an empty string.
+       ([UIxContactView -vcardAction]): new action to return the contact
+       as text/vcard (for exporting).
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+       +contactEntryWithName:aNamewithLDAPEntry:anEntryinContainer:aContainer]): adapted the mapping of the LDIF data with the new NGVCard API.
+
+       * SoObjects/Contacts/SOGoContactGCSEntry.m ([SOGoContactGCSEntry
+       -vCard]): create a new NGVCard instance when no data is available
+       and retain it.
+       ([SOGoContactGCSEntry -save]): save the vCard using the new
+       "versitString" API method/message.
+
+       * UI/Contacts/UIxContactView.h: separated interface from
+       UIxContactView.m.
+
+       * UI/WebServerResources/ContactsUI.js: add-ed code to download card
+       views and display them beneath the list.
+
+2006-09-08  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject -userTimeZone]): retain
+       the timezone even when it's the server timezone.
+
+       * SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder
+       -privateContacts:inContext:]): no long configure the calendar
+       object with the user's timezone since it's now accessible
+       application-wide throught the SOGoObject methods.
+
+       * UI/SOGoUI/UIxComponent.[hm]: removed the "viewTimeZone" ivar and
+       method. Removed the "backendTimeZone" method.
+
+       * UI/MainUI/SOGoUserHomePage.[hm]: made a subclass of UIxComponent
+       instead of SoComponent.
+
+       * SoObjects/Appointments/SOGoAppointmentObject.m: 
+       ([SOGoAppointmentObject -viewTimeZoneForPerson:_person]): returns
+       [self serverTimeZone] instead of "EST" (which was removed).
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.[hm]: removed the
+       "timeZone" ivar and its accessors.
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject -serverTimeZone]): new
+       centralized method returing the timezone configured in the
+       userdefaults db or "Canada/Eastern" if missing.
+       ([SOGoObject -userTimeZone]): new centralized method returing the
+       timezone of the current user or the server timezone if missing
+       from the user configuration table.
+
+2006-09-07  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/SchedulerUI.js: implemented caching of
+       date selectors.
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent -userFolderPath]):
+       return a path based on the object's context instead of the first
+       level in SOGo's object hierarchy...
+
+2006-09-06  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Templates/SchedulerUI/UIxCalDayTable.wox: day columns can now
+       be clicked.
+
+       * UI/Templates/SchedulerUI/UIxCalDateSelector.wox: pass the user's
+       timezone ([self viewTimeZone]) to the WEMonthOverview component to
+       avoid a confusion with the days.
+
+       * UI/Templates/SchedulerUI/UIxCalInlineAptView.wox: appointments
+       can now be clicked.
+
+       * UI/WebServerResources/SchedulerUI.js: implemented a mechanism to
+       imitate Sunbird's synchronization between the 3 visible views.
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent -selectedDate]): make
+       sure the numbers in dateString are formatted so as to take 4 chars
+       for the year and 2 for the day and the month, otherwise
+       NSCalendarDate will return a nil date.
+       ([UIxComponent -applicationPath]): return a path based on the
+       object's context instead of the second level in SOGo's object
+       hierarchy...
+
+2006-09-05  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent -selectedDate]): add the
+       user's timezone abbreviation to the date string passed as parameter to
+       NSCalendarDate to generate an accurate date instance. Do the same
+       when no date is specified and today is chosen.
+
+       * UI/WebServerResources/UIxAppointmentEditor.js: convert the
+       form's time values to integers before comparing them.
+
+       * UI/Scheduler/UIxCalAptListView.m ([UIxCalAptListView -currentStartTime]) 
+       ([UIxCalAptListView -currentEndTime]): initialize the resulting
+       dates timezone with [self viewTimeZone].
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent -init]): new
+       "viewTimeZone" ivar destined to hold an instance of the user's
+       timezone in memory.
+       ([UIxComponent -viewTimeZone]): take the timezone from the user's
+       prefs.
+
+2006-08-30  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Templates/SchedulerUI/UIxAppointmentEditor.wox: completely
+       rearranged the layout.
+
+       * UI/WebServerResources/UIxAppointmentEditor.js: added code to
+       manage showing and hiding appointment details.
+
+       * SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder
+       -privateContacts:inContext:]): init the SOGoAppointmentFolder's
+       timezone by taking the current user's timezone setting.
+
+       * SoObjects/Appointments/SOGoAptMailNotification.m: same as below.
+
+       * SoObjects/Appointments/SOGoAppointmentObject.m
+       ([SOGoAppointmentObject -changeParticipationStatus:inContext:]):
+       set default timezone to EST, although this code should be
+       rewritten to handle a system and a user default value.
+
+       * UI/Scheduler/UIxTimeDateControl.m ([UIxTimeDateControl
+       -takeValuesFromRequest:_rqinContext:_ctx]): enhanced method to
+       take the values from the hour and minute INPUTs when data is
+       POSTed since we no longer use the UIxTimeSelector component.
+       ([UIxTimeDateControl -selectableHours]) 
+       ([UIxTimeDateControl -selectableMinutes]): new methods used by the
+       template SELECTs to display reasonable and acceptable values
+       instead of all the possibilities.
+
+       * UI/WebServerResources/generic.js: adapted code for the new
+       implementation of the UIxContactSelector component (added a
+       "remove" button, removed the previous INPUT and replaced them with
+       links of class "button").
+
+       * UI/Scheduler/UIxTimeDateControl.h: separated interface from
+       UIxTimeDateControl.m.
+
+       * UI/Scheduler/UIxCalDayTable.m ([UIxCalDayTable -currentAppointmentDay]) 
+       ([UIxCalDayTable -currentAppointmentHour]): new methods that
+       returns correctly formatted values used as attributes for JS code.
+
+       * UI/Contacts/UIxContactSelector.m ([UIxContactSelector
+       -initialContactsAsString]): renamed implementation of
+       initialParticipants.
+       ([UIxContactSelector -currentContactId]) 
+       ([UIxContactSelector -currentContactName]): new methods used when
+       listing the initial contacts in the widget. Currently, both return
+       the person's cn but the latter should ultimately return a user
+       fullname.
+
+       * UI/Contacts/UIxContactSelector.h: separated interface from
+       UIxContactSelector.m.
+
+       * UI/Scheduler/UIxDatePickerScript.[hm]: component removed since
+       all javascript code is now put in Scheduler.js/generic.js.
+
+       * UI/Scheduler/NSCalendarDate+UIx.[hm]: category removed, code
+       moved into NSCalendarDate+Scheduler instead.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -setTimeZone:newTZ]): new method to
+       configure the timezone from SOGoUserFolder when the instance is
+       being created.
+       ([SOGoAppointmentFolder -viewTimeZone]): MET was removed. Returns
+       the value of the new "timezone" ivar.
+
+2006-08-25  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/SchedulerUI.{css,js}: added a tabview with
+       the date selector in the first page and the container of the
+       future calendar selector in the second page.
+
+       * UI/WebServerResources/generic.js: added code for handling tabbed
+       views.
+
+       * UI/Common/UIxPageFrame.m ([UIxPageFrame -productFrameworkName]):
+       returns the bundle name associated to the current running product.
+
+2006-08-24  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/UIxAppointmentEditor.js: fixed the AJAX
+       exception by invoking a timeout on the opener rather than invoking
+       the list refresh method.
+
+       * UI/Scheduler/UIxCalDayView.m ([UIxCalDayView -labelForDay]):
+       removed method.
+
+       * UI/Scheduler/UIxCalWeekView.m ([UIxCalWeekView -weekBeforePrevWeekQueryParameters]) 
+       ([UIxCalWeekView -prevWeekQueryParameters]) 
+       ([UIxCalWeekView -nextWeekQueryParameters]) 
+       ([UIxCalWeekView -weekAfterNextWeekQueryParameters]): new methods
+       that return the dates relatively to the current day.
+       ([UIxCalWeekView -lastWeekName]) 
+       ([UIxCalWeekView -currentWeekName]) 
+       ([UIxCalWeekView -nextWeekName]) 
+       ([UIxCalWeekView -weekAfterNextWeekName]) 
+       ([UIxCalWeekView -_weekNumberWithOffsetFromToday:offset]): new
+       methods that returns the label for the corresponding weeks.
+
+       * UI/Scheduler/UIxCalDayTable.[hm]: new class module/component
+       used by UIxCalDayView and UIxCalWeekView to display the events
+       occuring in one or more days.
+
+2006-08-22  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxCalMainView.m: extended class to populate the
+       entries in the new "monthMenu" and "yearMenu".
+
+       * UI/Scheduler/UIxCalDayView.m ([UIxCalDayView -labelForDay]): new
+       method to return the current day as a string formatted depending
+       on the current locale.
+
+       * UI/Scheduler/UIxCalAptListView.m ([UIxCalAptListView -startDate]) 
+       ([UIxCalAptListView -endDate]): "today" is now the default filter
+       for displayed events.
+       ([UIxCalAptListView -currentSerialDay]): new method returning the
+       date of the current enumerated appointment in serial form
+       (yyyymmdd).
+
+       * UI/WebServerResources/SchedulerUI.js: added code to select the
+       relevant day when an appointment is selected. Added code to popup
+       a month and a year menu whenever the header entries are clicked in
+       the calendar widget.
+
+       * UI/WebServerResources/generic.js: made addClassName and
+       removeClassName methods of HTMLElement.
+
+2006-08-21  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/MailerUI.js: fixed the contact creation
+       from email addresses.
+
+       * UI/WebServerResources/generic.js: centralized the search-related
+       functions here since the same code was used across the 3
+       applications.
+
+       * UI/Scheduler/UIxCalAptListView.m ([UIxCalAptListView -startDate]) 
+       ([UIxCalAptListView -endDate]): return the required dates needed
+       depending on the value given to the "filterpopup" url parameter.
+
+       * UI/Common/UIxToolbar.m ([UIxToolbar -buttonLabel]): reduced the
+       code by invoking UIxComponent's labelForKey:.
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent -labelForKey:]): use
+       [self pageResourceManager] instead of [self resourceManager].
+
+       * UI/Contacts/UIxContactEditorBase.m: invokes
+       globallyUniqueObjectId on the clientobject's class instead of the
+       hardcoded "SOGoFolder".
+
+       * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+       -newAction]): redirect the "new" action to the personal (default)
+       contact folder.
+
+       * SoObjects/SOGo/SOGoObject.m ([SOGoObject
+       +objectWithName:inContainer:]): new constructor.
+
+       * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder
+       -lookupContactWithId:recordId]): always create a contact object,
+       even if it does not exist.
+
+2006-08-18  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxCalMainView.[hm]: new class to serve as a pseudo
+       component that lays out the different components of SOGoCalendar.
+       Only serves as an Objective-C counterpart to its xml template.
+
+       * UI/Scheduler/UIxCalInlineMonthOverview.h: interface extracted
+       from its .m file.
+
+       * UI/Scheduler/UIxCalFilterPanel.[hm]: new class designed to
+       display a widget to handle the information displayed in the
+       appointments list. Not currently used, lacks implementation.
+
+       * UI/Scheduler/UIxCalDateSelector.[hm]: new class designed to
+       display a calendar as a dynamic widget from where one can select
+       the current visible day.
+
+       * UI/Scheduler/NSCalendarDate+Scheduler.[hm]: category code
+       extracted from UIxCalInlineMonthOverview.m.
+
+       * UI/Scheduler/UIxDatePicker.m: removed the jsPopup, jsCode and
+       calendarPageURL methods. The javascript code is handled by .js
+       files as much as possible...
+
+       * UI/WebServerResources/ContactsUI.js,
+       UI/WebServerResources/MailerUI.js: adapted to the code refactoring
+       in generic.js.
+
+       * UI/WebServerResources/SchedulerUI.js: implemented functions to
+       handle the new widgets. XmlHTTPRequest code taken from
+       MailerUI.js.
+
+       * UI/WebServerResources/generic.js: put some functions related to
+       element selections as methods to HTMLElement and HTMLTableElement.
+
+       * UI/Scheduler/UIxCalAptListView.[hm]: new class designed to
+       display the list of appointments (embodies the code-size of
+       UIxCalAptListView; answers to the "aptlist" method).
+
+2006-08-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxCalWeekOverview.m ([UIxCalWeekOverview
+       -correctURLAction]): new short action method replacing the method
+       below by taking far less code.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder -GETAction:]): removed method. Replaced
+       with an action in the view-related code.
+
+       * UI/Scheduler/UIxAppointmentEditor.m: invoke
+       "stringByEscapingHTMLString" on the resulting value to avoid
+       issues with accented characters.
+       ([-jsCode]): removed method since the javascript code was merged
+       into SchedulerUI.js.
+
+2006-08-14  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/iCalPerson+UIx.m ([iCalPerson +personWithUid:]):
+       new class method that returns an iCalPerson based on the UID given
+       as param.
+
+       * UI/Contacts/UIxContactsListViewContainerBase.m: 
+       UIxContactsListViewContainer renamed to serve as a base class for
+       the contact lists in both the contact editor and the contact
+       selectors.
+
+       * SoObjects/Contacts/SOGoContactLDAPFolder.m
+       ([SOGoContactLDAPFolder
+       -LDAPSetHostname:setPort:setBindDN:setBindPW:setContactIdentifier:
+       setUserIdentifier:setRootDN:]): an LDAP field specifying the
+       loginname of the users can now be specified.
+
+       * UI/WebServerResources/generic.js: added code to manage contact
+       lists through the new implementation of the UIxContactSelector.
+
+       * UI/Templates: put the templates related to SchedulerUI in its
+       own directory.
+
+       * SoObjects/Contacts/NGLdapEntry+Contact.m ([NGLdapEntry
+       -asDictionaryWithAttributeNames:withUID:andCName:cName]): add an
+       entry for "uid" with the field name representing the login name of
+       the user in the corresponding LDAP branch.
+
+2006-08-10  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder
+       -lookupName:_keyinContext:_ctxacquire:_flag]): when the HTTP
+       request is a PUT, always create an entry, even if we're not sure
+       it does exist.
+
+2006-08-09  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/ContactsUI.js: implemented live-search.
+
+       * SoObjects/Contacts/SOGoContactFolders.m ([SOGoContactFolders
+       -appendSystemSourcesInContext:context]): populated method with
+       code that creates entries mapped to instances SOGoContactFolder,
+       based on the configuration found in the NSUserDefaults under the
+       key "SOGoLDAPAddressBooks".
+       ([SOGoContactFolders
+       -lookupName:nameinContext:contextacquire:acquire]):
+       "contactsources" do not exist anymore, SOGoContactFolder was split
+       into two classes: SOGoContactGCSFolder and SOGoContactLDAPFolder
+       and one protocol: SOGOContactFolder, instead.
+       ([SOGoContactFolders -contactFolders]): new accessor used by the
+       views of SOGoContactXXXFolder to list the possible sources.
+
+       * SoObjects/Contacts/SOGoContactObject.h: new protocol that
+       defines the methods that UIxContactsView, ..Editor and so on...
+       can expect.
+
+       * SoObjects/Contacts/SOGoContactFolder.h: new protocol that
+       defines the methods that UIxContactsListViewBase expects as well
+       as the data fields returned in the contact lists.
+
+       * SoObjects/Contacts/SOGoContactLDAPFolder.[hm]: new class that
+       returns entries an LDAP server. Conforms to the new
+       SOGOContactFolder protocol.
+
+       * SoObjects/Contacts/SOGoContactLDAPEntry.[hm]: new class that
+       returns a vCard based on contact entries from an LDAP server.
+       Conforms to the new SOGOContactObject protocol.
+
+       * SoObjects/Contacts/NGVCardSimpleValue+Contact.m
+       ([NGVCardSimpleValue -vCardEntryString]): generates the correct
+       entry for the textual representation of the vCard.
+
+       * SoObjects/Contacts/NGVCardSimpleValue+Contact.[hm]: new class
+       extension.
+
+       * SoObjects/Contacts/SOGoContactGCSEntry.[hm]: new module name of
+       "SOGoContactObject".
+
+       * SoObjects/Contacts/NGVCard+Contact.m ([NGVCard -asString]): new
+       method that generates a textual representation of the vcard.
+
+       * SoObjects/Contacts/NGVCard+Contact.[hm]: new class extension.
+
+       * SoObjects/Contacts/SOGoContactGCSFolder.[hm]: new module name of
+       "SOGoContactFolder".
+
+       * SoObjects/Contacts/SOGoContactSource.h,
+       SoObjects/Contacts/SOGoPersonalAB.[hm]: unused classes and
+       protocols.
+
+       * SoObjects/Contacts/NGLdapEntry+Contact.m ([NGLdapEntry
+       -singleAttributeWithName:key]): new method that returns the first
+       object associated with an ldap key (where generally one value is
+       returned by key).
+       ([NGLdapEntry
+       -asDictionaryWithAttributeNames:attributeNamesandCName:cName]):
+       map the entry into an NSDictionary for processing by
+       UIxContactsListViewBase.m with the least possible overhead.
+
+       * SoObjects/Contacts/NGLdapEntry+Contact.[hm]: new class
+       extension.
+
+2006-08-04  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder
+       -privateContacts:inContext:]): now returns an instance of
+       SOGoContactFolders.
+
+       * UI/Contacts/UIxContactsListViewContainer.m
+       ([UIxContactsListViewContainer -contactFolderName]): new method to
+       return the absolute path to the current contact folder, called
+       from within the template.
+
+       * UI/Templates/ContactsUI/UIxContactsListViewContainer.wox: added
+       JS code to initialize the 'currentContactFolder' generic var.
+
+       * SoObjects/Contacts/SOGoContactFolder.m ([SOGoContactFolder
+       +contactFolderWithSource:inContainer:andName:]): new class
+       method meant to return an instance connected to the specified
+       source. Currently useless but won't be anymore in the next few
+       days.
+
+       * SoObjects/SOGo/SOGoUserFolder.h: commented out declaration of
+       the "lookupFreeBusyObject" method since it does not exist.
+
+       * UI/Contacts/UIxContactFoldersView.[hm]: new class module serving
+       as a "view" for the SOGoContactFolders object. Does nothing but
+       redirect the browser to the URL of the personal address book of
+       the user. It does not even have a template.
+
+       * SoObjects/Contacts/SOGoPersonalAB.[hm]: new class module
+       implementing the SOGoContactSource protocol. Does nothing
+       currently but will be used to implement access to the personal
+       address book of the user stored in the SOGo database.
+
+       * SoObjects/Contacts/SOGoContactSource.h: new "SOGoContactSource"
+       protocol defining an API common to all possible types of contact
+       sources.
+
+       * SoObjects/Contacts/SOGoContactFolders.[hm]: new class module
+       serving as the root of the contact folders available to the
+       current user. Correctly lists the contact sources in webdav.
+
+2006-08-03  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/MailerUI/UIxMailAccountsView.m ([UIxMailAccountsView
+       -composeAction]): new action method that permits external object
+       to write a message from the default (primary) account.
+
+       * UI/Contacts/UIxContactEditorBase.m ([UIxContactEditorBase
+       -initSnapshot]): new method with code taken from "defaultAction"
+       but needed for others.
+       ([UIxContactEditorBase -writeAction]): new action designed to
+       compose the correct URL needed to obtain the MailerUI's email
+       editor with the correct "mailto" parameter.
+
+       * UI/Common/UIxSortableTableHeader.m: moved from MailerUI to
+       Common so that other modules can use it.
+
+       * UI/Contacts/UIxContactsListViewContainer.m: container to make it
+       easier to manage both ajax and non-ajax requests.
+
+       * UI/Contacts/UIxContactsFilterPanel.m: clone of
+       UIxMailFilterPanel, but applicable to contact lists.
+
+       * SoObjects/Contacts/NSDictionary+Contact.m ([NSDictionary
+       -vcardContentFromSOGoContactRecord]): use the new standard methods
+       created for each type of entry. If a line is determined to not
+       contain information, it will be skipped.
+
+       * SoObjects/SOGo/AgenorUserManager.m ([AgenorUserManager
+       +initialize]): init defaultMailDomain with the user default
+       "SOGoDefaultMailDomain".
+
+2006-08-02  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Contacts/UIxContactEditorBase.m ([UIxContactEditorBase
+       -saveAction]): reorganized methods to only have ONE return point.
+       Invoke saveRecord: directly on the clientObject instead of
+       saveContentString, which does the same thing anyway.
+
+       * SoObjects/Contacts/NSDictionary+Contact.m
+       ([NSDictionary -vcardContentFromSOGoContactRecord]): extension
+       method to convert the dictionary returned with the user submission
+       to a record in VCARD format to be stored in the database.
+
+2006-08-01  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/MailerUI.js: when opening the context menu
+       of the message list, select the message below the mouse cursor and
+       deselect the other selected messages temporarily. This mimics the
+       behaviour of Thunderbird for that matter and was already
+       implemented for the entries of the folder tree.
+
+       * UI/MailerUI/UIxMailFolderMenu.m ([UIxMailFolderMenu
+       -iconForMenuItem]): new method that returns the fully qualified
+       relative URL to the icon representing the mailbox, or the default
+       mailbox icon if needed.
+
+       * UI/SOGoUI/UIxComponent.m ([UIxComponent
+       -urlForResourceFilename:filename]): automatically return an empty
+       string whenever the filename passed as argument is nil.
+
+       * UI/WebServerResources/MailerUI.js: open the mailboxes with the
+       "desc" parameter set to 1 so that they are sorted in descending
+       order by default. Also, added "onHeaderClick()", triggered by
+       clicking on the message list header elements.
+
+       * UI/MailerUI/UIxMailSortableTableHeader.m
+       ([UIxMailSortableTableHeader -isSortedDescending]): same as below.
+
+       * UI/MailerUI/UIxMailListView.m ([UIxMailListView
+       -isSortedDescending]): defaults to "YES" when the sort order is
+       not specified.
+
+2006-07-31  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/MailerUI.js:
+       - message cache: set the max num of cached messages to 20. Limit
+       the cached message size to 30000 bytes.
+       - ajax: when a message request is called while one is already
+       being performed, the latter will be cancelled. Idem when
+       retrieving the content of a mailbox.
+       - folder tree: when a mailbox is selected because of the URL
+       requested (initMailboxSelection), the dtree is expanded throughout
+       the mailbox entry's parent hierarchy to ensure it is made visible
+       when the page is being displayed. (new function: expandUpperTree).
+       - mailbox loading: when loading a mailbox where a message was
+       previously selected, we invoke its url with the "pageforuid"
+       parameter correctly specified. During callback processing, we scan
+       the table for the related row and reselect it.
+       Also, the message area is set blank before loading any mailbox.
+
+       * UI/MailerUI/UIxMailListView.m ([UIxMailListView
+       -defaultAction]): if the "pageforuid" parameter is passed in the
+       url, take its value and invoke [self firstMessageOfPageFor:]
+       consequently to deduce the first message to display. Otherwise,
+       set it to "idx", otherwise set it to 0.
+       ([UIxMailListView -firstMessageOfPageFor:]): new method
+       that determines the first message of the page where the message
+       passed as parameter is contained.
+
+       * UI/WebServerResources/UIxMailListView.js: removed this module,
+       its code was put in MailerUI.js instead.
+
+2006-07-28  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/MailerUI/UIxMailFolderMenu.m: a descendent of UIxMailTree
+       which returns the nodes for the parent specified in "parentMenu".
+       Used to generate the javascript code for the folder dtree.
+
+       * UI/Templates/MailerUI/UIxMailPanelFrame.wox: the components
+       using that container-template are now using UIxMailMainFrame
+       since UIxMailPanelFrame had no real interest. File removed.
+
+       * UI/WebServerResources/dtree.{css,js}: new files to handle
+       javascript-generated mailbox tree. Modified from original version
+       by integrating the previous code with the one we are using for
+       selections and mailbox handling. Minor visual enhancements too...
+
+2006-07-25  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Mailer/SOGoUser+Mail.m: if only one identity is to be
+       returned, put it in an NSArray before returning it (fixes
+       bug#217).
+
+2006-07-24  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/SOGoUI/NSString+URL.m ([NSString -hostlessURL]): new method
+       that returns a url string stripped from its "http://hostname"
+       prefix.
+
+       * UI/SOGoUI/NSDictionary+URL.[hm]: moved from UI/Common.
+
+       * UI/SOGoUI/NSString+URL.[hm]: moved from UI/Common.
+
+2006-07-17  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/MailerUI/WOContext+UIxMailer.m ([WOContext
+       -mailDateFormatter]): retrieve the timezone from the user settings
+       and pass it to the returned dateFormatter. Also, the dateFormatter
+       is kept in a static variable to avoid useless
+       creations/destructions.
+
+       * UI/MailerUI/UIxMailFormatter.m ([UIxMailDateFormatter
+       -setTimeZone:newTimeZone]): new accessor to specify the timezone.
+
+       * UI/MailerUI/UIxMailFilterPanel.m ([UIxMailFilterPanel -setSearchCriteria:]) 
+       ([UIxMailFilterPanel -searchCriteria]): new methods, similar to
+       s/Criteria/Text/ to handle the "criteria" form parameter.
+
+2006-07-11  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/WebServerResources/uix.css: enhanced the toolbar appearance
+       to integrate better with the firefox look&feel. Added entries for
+       the new "menu" DIV class (popup menus).
+
+       * UI/WebServerResources/generic.js: added "sanitizeMailTo" which
+       takes any chunk of text as param, detects the user email and the
+       optional first and last names and return them in a well-formatted
+       way. Renamed "getSelection" to "getSelectedNodes" to avoid a
+       namespace conflict. Added "onMenuClick(node, event, menuId)" to
+       handle popup menus through "onclick" element attributes (node =
+       this, event = event and menuId = name of the menu DIV id to
+       popup).
+
+       * UI/Contacts/UIxContactEditorBase.m ([UIxContactEditorBase
+       -snapshot]): add an entry for "email" into the snapshot
+       dictionary if a "contactEmail" URL parameter was detected and if
+       the entry for "email" is empty.
+
+       * UI/Contacts/Toolbars/SOGoContactFolder.toolbar: the "new card"
+       button now invokes the newContact() js function in ContactsUI.js
+       instead of opening "new" directly. newContact() pops up a window
+       stripped from its navigation bar.
+
+       * UI/Contacts/ContactsUI.js: new module specific to the ContactsUI
+       bundle (AddressBook).
+
+       * UI/Templates/MailerUI/UIxMailView.wox: added a div of class
+       "menu" and id "addressMenu" have the header email addresses
+       display it with the new menu code in generic.js.
+
+       * UI/Templates/MailerUI/UIxMailPanelFrame.wox: same as below +
+       replaced the body tables with a div of class "pageContent"
+       (standardization across the page templates).
+
+       * UI/Templates/MailerUI/UIxMailMainFrame.wox: include
+       productJavaScriptURL and pageJavaScriptURL (conditionnally) since
+       those are now inherited from UIxPageFrame.
+
+       * UI/MailerUI/UIxMailView.js: new file specific to UIxMailView.
+
+       * UI/MailerUI/UIxMailToSelection.m ([UIxMailToSelection -to]): if
+       a "mailto" URL parameter is detected and the "to" array is empty,
+       initialize "to" with the value of "mailto" before returning it.
+
+       * UI/MailerUI/UIxMailEditorAction.m ([UIxMailEditorAction
+       -composeAction]): rewrote method in a cleaner way and with usage
+       of the URL extensions to NSString and NSDictionary (see below).
+       Also, if a "mailto" url parameter is detected, pass it to the
+       redirected url.
+
+       * UI/MailerUI/UIxMailMainFrame.m: subclassed from UIxPageFrame to
+       reduce code.
+
+       * UI/Common/NSDictionary+URL.m ([NSDictionary -asURLParameters]):
+       returns a parameter string to add to a base URL.
+
+       * UI/Common/NSString+URL.m ([NSString
+       -composeURLWithAction:parameters:andHash:useHash]): new method to
+       compose a complete URL from an object URL with parameters and an
+       optional '#' character.
+
+       * UI/Common/UIxPageFrame.h: separated interface from
+       UIxPageFrame.m.
+
+2006-07-07  Wsourdeau Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Scheduler/UIxAppointmentEditor.m: returns yes to "isPopup";
+
+       * UI/WebServerResources/generic.js: added code to manage
+       selections within HTML containers.
+
+       * UI/Common/UIxPageFrame.m ([UIxPageFrame -productJavaScriptURL]):
+       added method to determine the possible URL for a product-specific
+       javascript filename of the forme <productname>.js.
+       ([UIxPageFrame -hasProductSpecificJavaScript]): new method.
+       ([UIxPageFrame -isPopup]): new method to determine whether the
+       application navigator bar should be displayed (main page) or not
+       (popup page).
+
+       * SoObjects/SOGo/SOGoAuthenticator.m ([SOGoAuthenticator
+       -LDAPCheckLogin:_loginpassword:_pwd]): new method to authenticate
+       the user through LDAP.
+
+2006-07-06  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * The toolbar code from the MailerUI product was taken, renamed as
+       "UIxToolBar" and put into UI/Common. Toolbar plists were created
+       for the Contacts and Scheduler products and put in their respectir
+       Toolbars/ subdirectories. Finally,
+       UI/Templates/{UIxToolbarButton,UIxToolbarSeparator}.wox, and
+       UI/Common/{UIxToolbarButton,UIxToolbarSeparator}.m were removed
+       and an invocation to the UIxToolbar component was put at the top
+       of UI/Templaces/UIxPageFrame.wox.
+
+       * UI/Common/UIxToolbar.m: new "isLastGroup" method to determine
+       within the templates whether a separator should be displayed.
+
+       * UI/Common/UIxToolbar.m ([UIxToolbar -hasButtons]): new method
+       that returns NO if the toolbar is empty.
+
+2006-07-05  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * UI/Templates/UIxPageFrame.wox: replaced central table with a DIV.
+
+       * UI/Common/UIxToolbarSeparator.m, UI/Common/UIxToolbarButton.m:
+       new toolbar objects.
+
+       * UI/Templates/UIxPageFrame.wox: use the exact html code as below.
+
+       * UI/Templates/MailerUI/UIxMailMainFrame.wox: redone the
+       linkbanner as a DIV instead of a TABLE.
+
+       * UI/MailerUI/UIxMailMainFrame.m [UIxMailMainFrame
+       showLinkBanner]:
+       returns 'YES' to request the display of the navigation bar between
+       applets.
+
+2006-06-15      ludovic@inverse.ca
+
+        * It's now possible to set the default
+         domain using for email using the
+         SOGoDefaultMailDomain preference key.
+
+2006-06-15     ludovic@inverse.ca
+       
+       * Initial import of SOGo from trunk.
index 78ec6851dda7b81ce8e6317139465428e390ebcd..def68eaa8c23ba6fb818d29abddb63d56f5a0456 100644 (file)
@@ -11,3 +11,4 @@ SUBPROJECTS = \
        Protocols       \
 
 include $(GNUSTEP_MAKEFILES)/aggregate.make
+
similarity index 100%
rename from Main/ChangeLog
rename to Main/ChangeLog.upstream
index 1132d88bcb3e85e06e6363b1b3e72c3cf1204e06..99bdcff367e5d321db5e9faf7b7db96acca8e85c 100644 (file)
@@ -21,7 +21,7 @@ $(SOGOD)_TOOL_LIBS += \
        -lGDLContentStore       \
        -lGDLAccess             \
        -lWEExtensions          \
-       -lNGiCal                \
+       -lNGCards               \
        -lNGObjWeb              \
        -lNGMime -lNGLdap       \
        -lNGStreams -lNGExtensions -lEOControl \
index 4274d8385567114d39f2f0d73e3203bcfd76ea72..0f10c9846d2d6dc50f7c83eac127d1e4d687b28c 100644 (file)
     NSMutableDictionary *localeLUT;
 }
 
-- (NSDictionary *)currentLocaleConsideringLanguages:(NSArray *)_langs;
-- (NSDictionary *)localeForLanguageNamed:(NSString *)_name;
+- (NSDictionary *) currentLocaleConsideringLanguages:(NSArray *)_langs;
+- (NSDictionary *) localeForLanguageNamed:(NSString *)_name;
 
 @end
 
 #include "SOGoProductLoader.h"
-#include <SOGo/SOGoAuthenticator.h>
 #include <WEExtensions/WEResourceManager.h>
+#include <SOGo/SOGoAuthenticator.h>
 #include <SOGo/SOGoUserFolder.h>
+#include <SOGo/SOGoPermissions.h>
 #include "common.h"
 
 @implementation SOGo
@@ -44,6 +45,8 @@ static BOOL doCrashOnSessionCreate = NO;
 
 + (void)initialize {
   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+  SoClassSecurityInfo *sInfo;
+  NSArray *basicRoles;
   id tmp;
   
   doCrashOnSessionCreate = [ud boolForKey:@"SOGoCrashOnSessionCreate"];
@@ -64,18 +67,19 @@ static BOOL doCrashOnSessionCreate = NO;
 #endif
 
   /* SoClass security declarations */
-  
+  sInfo = [self soClassSecurityInfo];
   /* require View permission to access the root (bound to authenticated ...) */
-  [[self soClassSecurityInfo] declareObjectProtected:SoPerm_View];
-  
+  [sInfo declareObjectProtected: SoPerm_View];
+
   /* to allow public access to all contained objects (subkeys) */
-  [[self soClassSecurityInfo] setDefaultAccess:@"allow"];
-  
+  [sInfo setDefaultAccess: @"allow"];
+
+  basicRoles = [NSArray arrayWithObjects: SoRole_Authenticated,
+                        SOGoRole_FreeBusy, nil];
+
   /* require Authenticated role for View and WebDAV */
-  [[self soClassSecurityInfo] declareRole:SoRole_Authenticated
-                              asDefaultForPermission:SoPerm_View];
-  [[self soClassSecurityInfo] declareRole:SoRole_Authenticated
-                              asDefaultForPermission:SoPerm_WebDAVAccess];
+  [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_View];
+  [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess];
 }
 
 - (id)init {
@@ -83,9 +87,9 @@ static BOOL doCrashOnSessionCreate = NO;
     WOResourceManager *rm;
     
     /* ensure core SoClass'es are setup */
-    [NSClassFromString(@"SOGoObject")        soClass];
-    [NSClassFromString(@"SOGoContentObject") soClass];
-    [NSClassFromString(@"SOGoFolder")        soClass];
+    [$(@"SOGoObject")        soClass];
+    [$(@"SOGoContentObject") soClass];
+    [$(@"SOGoFolder")        soClass];
     
     /* setup locale cache */
     self->localeLUT = [[NSMutableDictionary alloc] initWithCapacity:2];
@@ -108,7 +112,7 @@ static BOOL doCrashOnSessionCreate = NO;
 /* authenticator */
 
 - (id)authenticatorInContext:(id)_ctx {
-  return [SOGoAuthenticator sharedSOGoAuthenticator];
+  return [$(@"SOGoAuthenticator") sharedSOGoAuthenticator];
 }
 
 /* name lookup */
@@ -124,7 +128,7 @@ static BOOL doCrashOnSessionCreate = NO;
 }
 
 - (id)lookupUser:(NSString *)_key inContext:(id)_ctx {
-  return [[[NSClassFromString(@"SOGoUserFolder") alloc] 
+  return [[[$(@"SOGoUserFolder") alloc] 
            initWithName:_key inContainer:self] autorelease];
 }
 
@@ -262,7 +266,7 @@ static BOOL doCrashOnSessionCreate = NO;
     return lpath;
   
   if (MainProduct == Nil) {
-    if ((MainProduct = NSClassFromString(@"MainUIProduct")) == Nil)
+    if ((MainProduct = $(@"MainUIProduct")) == Nil)
       [self errorWithFormat:@"did not find MainUIProduct class!"];
   }
   
index 2d994ea2a4d6467d60018c4c6988d3e6b4e17d43..f53fa07bada85bf9718bbc684d0b0b861a86e904 100644 (file)
   
   registry = [SoProductRegistry sharedProductRegistry];
   fm       = [NSFileManager defaultManager];
-  
   pathes = [[self productSearchPathes] objectEnumerator];
   while ((lpath = [pathes nextObject]) != nil) {
     NSEnumerator *productNames;
index 314a248ce9b8d2c49ade80b8bd69f71c0c471b6e..ab5c895f7df12438e87175fdd3702952bb2c9a44 100644 (file)
   02111-1307, USA.
 */
 
-#include <NGObjWeb/NGObjWeb.h>
-#include "common.h"
+#import <Foundation/NSUserDefaults.h>
+#import <Foundation/NSTimeZone.h>
 
-int main(int argc, char **argv, char **env) {
+#import <NGObjWeb/NGObjWeb.h>
+#import "common.h"
+
+int main(int argc, char **argv, char **env)
+{
+  NSString *tzName;
+  NSUserDefaults *ud;
   NSAutoreleasePool *pool;
 
   pool = [[NSAutoreleasePool alloc] init];
@@ -30,7 +36,13 @@ int main(int argc, char **argv, char **env) {
   [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
 #endif
   [NGBundleManager defaultBundleManager];
-  
+
+  ud = [NSUserDefaults standardUserDefaults];
+  tzName = [ud stringForKey: @"SOGoServerTimeZone"];
+  if (!tzName)
+    tzName = @"Canada/Eastern";
+  [NSTimeZone setDefaultTimeZone: [NSTimeZone timeZoneWithName: tzName]];
+
   WOWatchDogApplicationMain(@"SOGo", argc, (void*)argv);
 
   [pool release];
diff --git a/Misc/WebUI/Application.h b/Misc/WebUI/Application.h
deleted file mode 100644 (file)
index cd026c5..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __Application_H_
-#define        __Application_H_
-
-
-#include <NGObjWeb/SoApplication.h>
-
-
-@interface Application : SoApplication
-{
-
-}
-
-@end
-
-#endif /* __Application_H_ */
diff --git a/Misc/WebUI/Application.m b/Misc/WebUI/Application.m
deleted file mode 100644 (file)
index 9252c41..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#import "Application.h"
-#import "common.h"
-
-
-@implementation Application
-
-- (id)init {
-    self = [super init];
-    if(self) {
-        [self logInfoWithFormat:@"Welcome to '%@'", [self name]];
-    }
-    return self;
-}
-
-@end
diff --git a/Misc/WebUI/COPYING b/Misc/WebUI/COPYING
deleted file mode 100644 (file)
index 161a3d1..0000000
+++ /dev/null
@@ -1,482 +0,0 @@
-                 GNU LIBRARY GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1991 Free Software Foundation, Inc.
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-\f
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-\f
-                 GNU LIBRARY GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License").  Each licensee is
-addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-\f
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
-  6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    c) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    d) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-\f
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                           NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-     Appendix: How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-    MA 02111-1307, USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/Misc/WebUI/COPYRIGHT b/Misc/WebUI/COPYRIGHT
deleted file mode 100644 (file)
index 1053b2a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Copyright (C) 2004 SKYRIX Software AG
-
-
-Contact: info@skyrix.com
diff --git a/Misc/WebUI/ChangeLog b/Misc/WebUI/ChangeLog
deleted file mode 100644 (file)
index b45b24d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-2004-05-27  Marcus Mueller  <mm@skyrix.com>
-
-       * README: updated
-
-2004-05-27  Marcus Mueller  <mm@skyrix.com>
-
-       * README, NOTES: updated
-
-       * NGExtensions/NGLogging/ChangeLog: created
-
-2004-05-26  Marcus Mueller  <mm@skyrix.com>
-
-       * ChangeLog: created
diff --git a/Misc/WebUI/DirectAction.h b/Misc/WebUI/DirectAction.h
deleted file mode 100644 (file)
index e25f29b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __DirectAction_H_
-#define        __DirectAction_H_
-
-
-#include <NGObjWeb/NGObjWeb.h>
-
-
-@interface DirectAction : WODirectAction
-{
-
-}
-
-@end
-
-#endif /* __DirectAction_H_ */
diff --git a/Misc/WebUI/DirectAction.m b/Misc/WebUI/DirectAction.m
deleted file mode 100644 (file)
index 695f82b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include "DirectAction.h"
-
-
-@implementation DirectAction
-
-@end
diff --git a/Misc/WebUI/English.lproj/InfoPlist.strings b/Misc/WebUI/English.lproj/InfoPlist.strings
deleted file mode 100644 (file)
index d22a0a2..0000000
Binary files a/Misc/WebUI/English.lproj/InfoPlist.strings and /dev/null differ
diff --git a/Misc/WebUI/GNUmakefile b/Misc/WebUI/GNUmakefile
deleted file mode 100644 (file)
index d8eaed4..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-# $Id$
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-WOAPP_NAME = WebUI
-
-WebUI_OBJC_FILES = \
-       WebUI_main.m    \
-       Application.m   \
-       Session.m       \
-       DirectAction.m  \
-
-
-ADDITIONAL_INCLUDE_DIRS = -INGExtensions -INGExtensions/NGLogging
-
-WebUI_COMPONENTS = \
-       Main.wo         \
-
-
-WebUI_RESOURCE_FILES = \
-
-
-WebUI_WEBSERVER_RESOURCE_FILES := \
-       $(shell find WebServerResources -type f -print) 
-
-
-WebUI_SUBPROJECTS = \
-       NGExtensions    \
-
-
--include GNUmakefile.preamble
-include $(GNUSTEP_MAKEFILES)/woapp.make
--include GNUmakefile.postamble
diff --git a/Misc/WebUI/GNUmakefile.preamble b/Misc/WebUI/GNUmakefile.preamble
deleted file mode 100644 (file)
index 9c0fa29..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# $Id$
-
-
--include GNUmakefile.preamble.local
-
-ifeq ($(findstring darwin, $(GNUSTEP_HOST_OS)),)
-ADDITIONAL_OBJCFLAGS += -DWITHOUT_SOPEX
-endif
diff --git a/Misc/WebUI/Info.plist b/Misc/WebUI/Info.plist
deleted file mode 100644 (file)
index d0cabb5..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-       <key>CFBundleDevelopmentRegion</key>
-       <string>English</string>
-       <key>CFBundleExecutable</key>
-       <string>WebUI</string>
-       <key>CFBundleIconFile</key>
-       <string>Lori</string>
-       <key>CFBundleIdentifier</key>
-       <string>my.sope.apps.WebUI</string>
-       <key>CFBundleInfoDictionaryVersion</key>
-       <string>6.0</string>
-       <key>CFBundlePackageType</key>
-       <string>APPL</string>
-       <key>CFBundleSignature</key>
-       <string>????</string>
-       <key>CFBundleVersion</key>
-       <string>0.1</string>
-       <key>NSMainNibFile</key>
-       <string></string>
-       <key>NSPrincipalClass</key>
-       <string>SOPEXApplication</string>
-</dict>
-</plist>
diff --git a/Misc/WebUI/Lori.icns b/Misc/WebUI/Lori.icns
deleted file mode 100644 (file)
index 4d10244..0000000
Binary files a/Misc/WebUI/Lori.icns and /dev/null differ
diff --git a/Misc/WebUI/NGExtensions/GNUmakefile b/Misc/WebUI/NGExtensions/GNUmakefile
deleted file mode 100644 (file)
index 40bba8b..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# $Id$
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-
-SUBPROJECT_NAME = NGExtensions
-
-
-ADDITIONAL_INCLUDE_DIRS += -I..
-
-
-NGExtensions_SUBPROJECTS = \
-       NGLogging
-
-
--include GNUmakefile.preamble
-include $(GNUSTEP_MAKEFILES)/subproject.make
--include GNUmakefile.postamble
diff --git a/Misc/WebUI/NGExtensions/NGLogging/ChangeLog b/Misc/WebUI/NGExtensions/NGLogging/ChangeLog
deleted file mode 100644 (file)
index 770975e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-2004-05-27  Marcus Mueller  <mm@skyrix.com>
-
-       * NGLogAppender.[hm]: introduced -formattedEvent:, currently not
-         configurable.
-
-       * NGLogSyslogAppender.m: works as expected now.
-
-       * NGLogger.m: uses new default (see README) to select the default
-         appender. Not optimal, but sufficient.
-
-       * NGLogConsoleAppender.m: changed to use -formattedEvent: now.
-
-2004-05-27  Marcus Mueller  <mm@skyrix.com>
-
-       * NGLogSyslogAppender.[hm]: syslog appender, untested.
-
-       * ChangeLog: created
diff --git a/Misc/WebUI/NGExtensions/NGLogging/GNUmakefile b/Misc/WebUI/NGExtensions/NGLogging/GNUmakefile
deleted file mode 100644 (file)
index e596eaa..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# $Id$
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-
-SUBPROJECT_NAME = NGLogging
-
-
-ADDITIONAL_INCLUDE_DIRS += -I.. -I../..
-
-
-NGLogging_OBJC_FILES = \
-    NSObject+ExtendedLogging.m  \
-    NGLogger.m                  \
-    NGLogEvent.m                \
-    NGLogAppender.m             \
-    NGLogConsoleAppender.m      \
-
-NGLogging_HEADER_FILES = \
-    NGLogging.h                 \
-    NSObject+ExtendedLogging.h  \
-    NGLogger.h                  \
-    NGLogEvent.h                \
-    NGLogAppender.h             \
-    NGLogConsoleAppender.h      \
-
-
--include GNUmakefile.preamble
-include $(GNUSTEP_MAKEFILES)/subproject.make
--include GNUmakefile.postamble
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogAppender.h b/Misc/WebUI/NGExtensions/NGLogging/NGLogAppender.h
deleted file mode 100644 (file)
index fabab54..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NGLogAppender_H_
-#define        __NGLogAppender_H_
-
-/*
-  Abstract superclass for all appenders.
-*/
-
-#import <Foundation/Foundation.h>
-#import "NSObject+ExtendedLogging.h"
-
-
-@class NGLogEvent;
-
-
-@interface NGLogAppender : NSObject
-{
-
-}
-
-/* subclass responsibility */
-- (void)appendLogEvent:(NGLogEvent *)_event;
-- (NSString *)formattedEvent:(NGLogEvent *)_event;
-
-- (NSString *)localizedNameOfLogLevel:(NGLogLevel)_level;
-
-@end
-
-#endif /* __NGLogAppender_H_ */
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogAppender.m b/Misc/WebUI/NGExtensions/NGLogging/NGLogAppender.m
deleted file mode 100644 (file)
index 3743c84..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#import "NGLogAppender.h"
-#import "NGLogEvent.h"
-
-
-@implementation NGLogAppender
-
-- (void)appendLogEvent:(NGLogEvent *)_event {
-    [self subclassResponsibility:_cmd];
-}
-
-- (NSString *)formattedEvent:(NGLogEvent *)_event {
-    return [NSString stringWithFormat:@"[%@] %@",
-        [self localizedNameOfLogLevel:[_event level]],
-        [_event message]];
-}
-
-- (NSString *)localizedNameOfLogLevel:(NGLogLevel)_level {
-    NSString *name;
-
-    switch (_level) {
-        case NGLogLevelDebug:
-            name = @"DEBUG";
-            break;
-        case NGLogLevelInfo:
-            name = @"INFO";
-            break;
-        case NGLogLevelWarn:
-            name = @"WARN";
-            break;
-        case NGLogLevelError:
-            name = @"ERROR";
-            break;
-        case NGLogLevelFatal:
-            name = @"FATAL";
-            break;
-        default:
-            name = @"";
-            break;
-    }
-    return name;
-}
-
-@end
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogConsoleAppender.h b/Misc/WebUI/NGExtensions/NGLogging/NGLogConsoleAppender.h
deleted file mode 100644 (file)
index bc3fd34..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NGLogConsoleAppender_H_
-#define        __NGLogConsoleAppender_H_
-
-
-#import "NGLogAppender.h"
-
-
-@interface NGLogConsoleAppender : NGLogAppender
-{
-
-}
-
-@end
-
-#endif /* __NGLogConsoleAppender_H_ */
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogConsoleAppender.m b/Misc/WebUI/NGExtensions/NGLogging/NGLogConsoleAppender.m
deleted file mode 100644 (file)
index d9a53c4..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#import "NGLogConsoleAppender.h"
-#import "NGLogEvent.h"
-
-
-@implementation NGLogConsoleAppender
-
-- (void)appendLogEvent:(NGLogEvent *)_event {
-    NSLog([self formattedEvent:_event]);
-}
-
-@end
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogEvent.h b/Misc/WebUI/NGExtensions/NGLogging/NGLogEvent.h
deleted file mode 100644 (file)
index 3b1dfa4..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NGLogEvent_H_
-#define        __NGLogEvent_H_
-
-
-#import <Foundation/Foundation.h>
-#import "NSObject+ExtendedLogging.h"
-
-
-@interface NGLogEvent : NSObject
-{
-    NSString *msg;
-    NGLogLevel level;
-    NSTimeInterval date;
-}
-
-- (id)initWithLevel:(NGLogLevel)_level message:(NSString *)_msg;
-
-- (NGLogLevel)level;
-- (NSString *)message;
-- (NSDate *)date;
-
-@end
-
-#endif /* __NGLogEvent_H_ */
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogEvent.m b/Misc/WebUI/NGExtensions/NGLogging/NGLogEvent.m
deleted file mode 100644 (file)
index e9c6173..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#import "NGLogEvent.h"
-#import <NGExtensions/NGExtensions.h>
-
-
-@implementation NGLogEvent
-
-- (id)initWithLevel:(NGLogLevel)_level message:(NSString *)_msg {
-    if((self = [super init])) {
-        self->date = [NSDate timeIntervalSinceReferenceDate];
-        self->level = _level;
-        ASSIGN(self->msg, _msg);
-    }
-    return self;
-}
-
-- (void)dealloc {
-    [self->msg release];
-    [super dealloc];
-}
-
-- (NGLogLevel)level {
-    return self->level;
-}
-
-- (NSString *)message {
-    return self->msg;
-}
-
-- (NSDate *)date {
-    return [NSDate dateWithTimeIntervalSinceReferenceDate:self->date];
-}
-
-@end
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogSyslogAppender.h b/Misc/WebUI/NGExtensions/NGLogging/NGLogSyslogAppender.h
deleted file mode 100644 (file)
index e7253b8..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NGLogSyslogAppender_H_
-#define        __NGLogSyslogAppender_H_
-
-
-#import "NGLogAppender.h"
-
-
-@interface NGLogSyslogAppender : NGLogAppender
-{
-
-}
-
-+ (id)sharedAppender;
-
-/* provide syslog identifier */
-- (id)initWithIdentifier:(NSString *)_ident;
-
-@end
-
-#endif /* __NGLogSyslogAppender_H_ */
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogSyslogAppender.m b/Misc/WebUI/NGExtensions/NGLogging/NGLogSyslogAppender.m
deleted file mode 100644 (file)
index 856b475..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#import "NGLogSyslogAppender.h"
-#import "NGLogEvent.h"
-#include <syslog.h>
-#include <stdarg.h>
-
-
-@interface NGLogSyslogAppender (PrivateAPI)
-- (int)syslogLevelForLogLevel:(NGLogLevel)_level;
-@end
-
-@implementation NGLogSyslogAppender
-
-
-static NSString *defaultSyslogIdentifier = nil;
-
-
-+ (void)initialize {
-  NSUserDefaults *ud;
-  static BOOL isInitialized = NO;
-
-  if(isInitialized)
-    return;
-
-  ud = [NSUserDefaults standardUserDefaults];
-  defaultSyslogIdentifier =
-    [[ud stringForKey:@"NGLogSyslogIdentifier"] retain];
-
-  isInitialized = YES;
-}
-
-+ (id)sharedAppender {
-  static id sharedAppender = nil;
-  if(sharedAppender == nil) {
-    sharedAppender = [[self alloc] init];
-  }
-  return sharedAppender;
-}
-
-- (id)init {
-    return [self initWithIdentifier:defaultSyslogIdentifier];
-}
-
-- (id)initWithIdentifier:(NSString *)_ident {
-  if((self = [super init])) {
-    #warning ** default flags?
-    openlog([_ident cString], LOG_PID | LOG_NDELAY, LOG_USER);
-  }
-  return self;
-}
-
-- (void)dealloc {
-  closelog();
-  [super dealloc];
-}
-
-- (void)appendLogEvent:(NGLogEvent *)_event {
-  NSString *formattedMsg;
-  int level;
-
-  formattedMsg = [self formattedEvent:_event];
-  level = [self syslogLevelForLogLevel:[_event level]];
-  syslog(level, [formattedMsg cString]);
-}
-
-- (int)syslogLevelForLogLevel:(NGLogLevel)_level {
-    int level;
-    
-    switch (_level) {
-        case NGLogLevelDebug:
-            level = LOG_DEBUG;
-            break;
-        case NGLogLevelInfo:
-            level = LOG_INFO;
-            break;
-        case NGLogLevelWarn:
-            level = LOG_WARNING;
-            break;
-        case NGLogLevelError:
-            level = LOG_ERR;
-            break;
-        case NGLogLevelFatal:
-            level = LOG_ALERT; // LOG_EMERG is broadcast to all users...
-            break;
-        default:
-            level = LOG_NOTICE;
-            break;
-    }
-    return level;
-}
-
-@end
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogger.h b/Misc/WebUI/NGExtensions/NGLogging/NGLogger.h
deleted file mode 100644 (file)
index 421abb0..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NGLogger_H_
-#define        __NGLogger_H_
-
-/*
-  The logger, modeled closely after log4j.
- */
-
-
-#import <Foundation/Foundation.h>
-#include "NSObject+ExtendedLogging.h"
-
-
-@interface NGLogger : NSObject
-{
-    NGLogLevel minLogLevel;
-    id _appender; // going away as soon as we have a config
-}
-
-- (id)initWithLogLevel:(NGLogLevel)_level;
-
-- (void)setLogLevel:(NGLogLevel)_level;
-- (NGLogLevel)logLevel;
-
-@end
-
-#endif /* __NGLogger_H_ */
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogger.m b/Misc/WebUI/NGExtensions/NGLogging/NGLogger.m
deleted file mode 100644 (file)
index 52a08de..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include "NGLogger.h"
-#include <NGExtensions/NGExtensions.h>
-#include "common.h"
-#include "NGLogEvent.h"
-#include "NGLogAppender.h"
-
-
-@implementation NGLogger
-
-- (id)init {
-    self = [self initWithLogLevel:NGLogLevelAll];
-    return self;
-}
-
-- (id)initWithLogLevel:(NGLogLevel)_level {
-    if((self = [super init])) {
-        NSUserDefaults *ud;
-        NSString *appenderClassName;
-
-        [self setLogLevel:_level];
-
-#warning ** remove this as soon as we have a config
-        ud = [NSUserDefaults standardUserDefaults];
-        appenderClassName = [ud stringForKey:@"NGLogDefaultAppenderClass"];
-        if(appenderClassName == nil)
-            appenderClassName = @"NGLogConsoleAppender";
-        self->_appender = [[NSClassFromString(appenderClassName) alloc] init];
-    }
-    return self;
-}
-
-- (void)dealloc {
-    [self->_appender release];
-    [super dealloc];
-}
-
-
-- (void)setLogLevel:(NGLogLevel)_level {
-    self->minLogLevel = _level;
-}
-
-- (NGLogLevel)logLevel {
-    return self->minLogLevel;
-}
-
-- (void)logLevel:(NGLogLevel)_level withFormat:(NSString *)_fmt, ... {
-    NSString *msg;
-    NGLogEvent *event;
-    va_list va;
-
-    if(self->minLogLevel > _level)
-        return;
-
-    va_start(va, _fmt);
-    msg = [[NSString alloc] initWithFormat:_fmt arguments:va];
-    va_end(va);
-
-    event = [[NGLogEvent alloc] initWithLevel:_level message:msg];
-
-    // iterate appenders
-    // TODO: as soon as we have more appenders, we need to iterate on them
-    [self->_appender appendLogEvent:event];
-
-    [event release];
-    [msg release];
-}
-
-- (BOOL)isLogDebugEnabled {
-    return self->minLogLevel >= NGLogLevelDebug;
-}
-
-- (BOOL)isLogInfoEnabled {
-    return self->minLogLevel >= NGLogLevelInfo;
-}
-
-- (BOOL)isLogWarnEnabled {
-    return self->minLogLevel >= NGLogLevelWarn;
-}
-
-- (BOOL)isLogErrorEnabled {
-    return self->minLogLevel >= NGLogLevelError;
-}
-
-- (BOOL)isLogFatalEnabled {
-    return self->minLogLevel >= NGLogLevelFatal;
-}
-
-@end
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NGLogging.h b/Misc/WebUI/NGExtensions/NGLogging/NGLogging.h
deleted file mode 100644 (file)
index b774724..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NGLogging_H_
-#define        __NGLogging_H_
-
-/*
-  NGLogging is a somewhat more sophisticated logging framework, modeled
-  apparently similar to log4j - without some of its bloat. The current
-  idea is to replace the default logging used throughout OGo (-logWithFormat:,
-  -debugWithFormat:, NSLog()) with the new logging framework to get rid of
-  stdout only logging.
-*/
-
-
-#import <Foundation/Foundation.h>
-
-#include "NSObject+ExtendedLogging.h"
-#include "NGLogger.h"
-
-
-#endif /* __NGLogging_H_ */
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NSObject+ExtendedLogging.h b/Misc/WebUI/NGExtensions/NGLogging/NSObject+ExtendedLogging.h
deleted file mode 100644 (file)
index 04845d9..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NSObject_ExtendedLogging_H_
-#define        __NSObject_ExtendedLogging_H_
-
-
-#import <Foundation/Foundation.h>
-
-
-typedef enum {
-    NGLogLevelAll = 0,
-    NGLogLevelDebug = 1,
-    NGLogLevelInfo = 2,
-    NGLogLevelWarn = 3,
-    NGLogLevelError = 4,
-    NGLogLevelFatal = 5,
-    NGLogLevelOff = 6
-} NGLogLevel;
-
-
-@interface NSObject (NGExtendedLogging)
-
-- (id)sharedLogger;
-- (id)logger;
-
-- (void)logDebugWithFormat:(NSString *)_fmt, ...;
-- (void)logInfoWithFormat:(NSString *)_fmt, ...;
-- (void)logWarnWithFormat:(NSString *)_fmt, ...;
-- (void)logErrorWithFormat:(NSString *)_fmt, ...;
-- (void)logFatalWithFormat:(NSString *)_fmt, ...;
-
-- (BOOL)isLogDebugEnabled;
-- (BOOL)isLogInfoEnabled;
-- (BOOL)isLogWarnEnabled;
-- (BOOL)isLogErrorEnabled;
-- (BOOL)isLogFatalEnabled;
-
-- (void)logLevel:(NGLogLevel)_level withFormat:(NSString *)_fmt, ...;
-
-@end
-
-#endif /* __NSObject_ExtendedLogging_H_ */
diff --git a/Misc/WebUI/NGExtensions/NGLogging/NSObject+ExtendedLogging.m b/Misc/WebUI/NGExtensions/NGLogging/NSObject+ExtendedLogging.m
deleted file mode 100644 (file)
index 50d3020..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#import "NSObject+ExtendedLogging.h"
-#import "NGLogger.h"
-
-
-@implementation NSObject (NGExtendedLogging)
-
-- (id)sharedLogger {
-    static id sharedLogger = nil;
-    if(sharedLogger == nil) {
-        sharedLogger = [[NGLogger alloc] init];
-    }
-    return sharedLogger;
-}
-
-- (id)logger {
-    return [self sharedLogger];
-}
-
-- (void)logDebugWithFormat:(NSString *)_fmt, ... {
-    NSString *msg;
-    va_list va;
-    
-    va_start(va, _fmt);
-    msg = [[NSString alloc] initWithFormat:_fmt arguments:va];
-    va_end(va);
-    [self logLevel:NGLogLevelDebug withFormat:msg];
-    [msg release];
-}
-
-- (void)logInfoWithFormat:(NSString *)_fmt, ... {
-    NSString *msg;
-    va_list va;
-    
-    va_start(va, _fmt);
-    msg = [[NSString alloc] initWithFormat:_fmt arguments:va];
-    va_end(va);
-    [self logLevel:NGLogLevelInfo withFormat:msg];
-    [msg release];
-}
-
-- (void)logWarnWithFormat:(NSString *)_fmt, ... {
-    NSString *msg;
-    va_list va;
-    
-    va_start(va, _fmt);
-    msg = [[NSString alloc] initWithFormat:_fmt arguments:va];
-    va_end(va);
-    [self logLevel:NGLogLevelWarn withFormat:msg];
-    [msg release];
-}
-
-- (void)logErrorWithFormat:(NSString *)_fmt, ... {
-    NSString *msg;
-    va_list va;
-    
-    va_start(va, _fmt);
-    msg = [[NSString alloc] initWithFormat:_fmt arguments:va];
-    va_end(va);
-    [self logLevel:NGLogLevelError withFormat:msg];
-    [msg release];
-}
-
-- (void)logFatalWithFormat:(NSString *)_fmt, ... {
-    NSString *msg;
-    va_list va;
-    
-    va_start(va, _fmt);
-    msg = [[NSString alloc] initWithFormat:_fmt arguments:va];
-    va_end(va);
-    [self logLevel:NGLogLevelFatal withFormat:msg];
-    [msg release];
-}
-
-- (void)logLevel:(NGLogLevel)_level withFormat:(NSString *)_fmt, ... {
-    NSString *msg;
-    va_list va;
-    
-    va_start(va, _fmt);
-    msg = [[NSString alloc] initWithFormat:_fmt arguments:va];
-    va_end(va);
-    [[self logger] logLevel:_level withFormat:msg];
-    [msg release];
-}
-
-- (BOOL)isLogDebugEnabled {
-    return [[self logger] isLogDebugEnabled];
-}
-
-- (BOOL)isLogInfoEnabled {
-    return [[self logger] isLogInfoEnabled];
-}
-
-- (BOOL)isLogWarnEnabled {
-    return [[self logger] isLogWarnEnabled];
-}
-
-- (BOOL)isLogErrorEnabled {
-    return [[self logger] isLogErrorEnabled];
-}
-
-- (BOOL)isLogFatalEnabled {
-    return [[self logger] isLogFatalEnabled];
-}
-
-@end
diff --git a/Misc/WebUI/NOTES b/Misc/WebUI/NOTES
deleted file mode 100644 (file)
index 16dc5b8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-$Id$
-
-- NGExtensions
-  - Stuff I believe might be useful for later addition to NGExtensions framework
-
-  - NGLogging
-    - Had a look at log4cocoa, appeared to be too bloated (they mimic all of
-      log4j which doesn't really make sense in Objective-C).
-    - NGLogConsoleAppender is the only appender currently available, it's
-      hardcoded in NGLogger as default. This should change as soon as we have
-      a config for that purpose. Logging is low priority, so we don't need to
-      do that too soon.
-    - Syslog appender might be useful for the ministry. Syslog provides its own
-      buffering, so syslog appender should be straight forward. Current
-      implementation makes some fix assumptions (log facility).
\ No newline at end of file
diff --git a/Misc/WebUI/PROJECTLEAD b/Misc/WebUI/PROJECTLEAD
deleted file mode 100644 (file)
index ab0c70a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Id$
-
-PROJECTLEAD=helge.hess@opengroupware.org
diff --git a/Misc/WebUI/README b/Misc/WebUI/README
deleted file mode 100644 (file)
index c5beb54..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-$Id$
-
-
-WebUI
-  Part of SOGo
-  Copyright (C) 2000-2004 SKYRIX Software AG - http://www.skyrix.com/
-
-Subprojects
-===========
-
-- NGExtensions
-  - NGLogging
-
-
-UserDefaults
-============
-
-    Default                  | Type   | Example Value
-    ==============================================================
-    NGLogSyslogIdentifier    | String | WebUI
-    NGLogDefaultAppenderClass| String | NGLogConsoleAppender
-
-
-
diff --git a/Misc/WebUI/Session.h b/Misc/WebUI/Session.h
deleted file mode 100644 (file)
index 9cea907..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __Session_H_
-#define        __Session_H_
-
-
-#include <NGObjWeb/NGObjWeb.h>
-
-
-@interface Session : WOSession
-{
-
-}
-
-@end
-
-#endif /* __Session_H_ */
diff --git a/Misc/WebUI/Session.m b/Misc/WebUI/Session.m
deleted file mode 100644 (file)
index 58c00f5..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include "Session.h"
-#include "common.h"
-
-
-@implementation Session
-
-- (id)init {
-    self = [super init];
-    if(self) {
-        [self logWarnWithFormat:@"session with id '%@' did init - this " \
-                                @"should NOT happen!", [self sessionID]];
-    }
-    return self;
-}
-@end
diff --git a/Misc/WebUI/TODO b/Misc/WebUI/TODO
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Misc/WebUI/Version b/Misc/WebUI/Version
deleted file mode 100644 (file)
index f96f6a3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# $Id$
-#
-# This file is included by library makefiles to set the version information 
-# of the executable.
-#
-# NOTE: This has no effect whatsover if you are using Xcode on Mac OS X.
-# For Xcode please use the appropriate user interface or issue the following
-# command in a shell:
-# /Developer/Tools/agvtool new-version \
-# ${MAJOR_VERSION}.${MINOR_VERSION}.${SUBMINOR_VERSION}
-
-MAJOR_VERSION=1
-MINOR_VERSION=0
-SUBMINOR_VERSION=0
-
diff --git a/Misc/WebUI/WebServerResources/favicon.ico b/Misc/WebUI/WebServerResources/favicon.ico
deleted file mode 100644 (file)
index 829cb22..0000000
Binary files a/Misc/WebUI/WebServerResources/favicon.ico and /dev/null differ
diff --git a/Misc/WebUI/WebUI.xcode/project.pbxproj b/Misc/WebUI/WebUI.xcode/project.pbxproj
deleted file mode 100644 (file)
index 6761850..0000000
+++ /dev/null
@@ -1,952 +0,0 @@
-// !$*UTF8*$!
-{
-       archiveVersion = 1;
-       classes = {
-       };
-       objectVersion = 39;
-       objects = {
-               080E96DDFE201D6D7F000001 = {
-                       children = (
-                               AD95C2640664CE7400FCB211,
-                               AD19ED5205D7FBD1009EBA3A,
-                               AD19ED5305D7FBD1009EBA3A,
-                               AD19ED6305D7FBEA009EBA3A,
-                               AD19ED6405D7FBEA009EBA3A,
-                               ADEE3DD505DD126900F523DB,
-                               ADEE3DD605DD126900F523DB,
-                               32CA4F630368D1EE00C91783,
-                               29B97316FDCFA39411CA2CEA,
-                       );
-                       isa = PBXGroup;
-                       name = "Main Server";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               089C165CFE840E0CC02AAC07 = {
-                       children = (
-                               089C165DFE840E0CC02AAC07,
-                       );
-                       isa = PBXVariantGroup;
-                       name = InfoPlist.strings;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               089C165DFE840E0CC02AAC07 = {
-                       fileEncoding = 10;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist.strings;
-                       name = English;
-                       path = English.lproj/InfoPlist.strings;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//080
-//081
-//082
-//083
-//084
-//100
-//101
-//102
-//103
-//104
-               1058C7A1FEA54F0111CA2CBB = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Foundation.framework;
-                       path = /System/Library/Frameworks/Foundation.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-//100
-//101
-//102
-//103
-//104
-//190
-//191
-//192
-//193
-//194
-               19C28FACFE9D520D11CA2CBB = {
-                       children = (
-                               8D1107320486CEB800E47090,
-                       );
-                       isa = PBXGroup;
-                       name = Products;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//190
-//191
-//192
-//193
-//194
-//290
-//291
-//292
-//293
-//294
-               29B97313FDCFA39411CA2CEA = {
-                       buildSettings = {
-                       };
-                       buildStyles = (
-                               4A9504CCFFE6A4B311CA0CBA,
-                               4A9504CDFFE6A4B311CA0CBA,
-                       );
-                       hasScannedForEncodings = 1;
-                       isa = PBXProject;
-                       mainGroup = 29B97314FDCFA39411CA2CEA;
-                       projectDirPath = "";
-                       targets = (
-                               8D1107260486CEB800E47090,
-                       );
-               };
-               29B97314FDCFA39411CA2CEA = {
-                       children = (
-                               ADA38BE605DD23C400C820AA,
-                               AD95C1890664C1E400FCB211,
-                               AD95C18B0664C1E400FCB211,
-                               AD95C1870664C1E400FCB211,
-                               AD95C1880664C1E400FCB211,
-                               AD95C18A0664C1E400FCB211,
-                               ADC15A300664CF290063754B,
-                               AD95AEBB0664BC7B00FCB211,
-                               AD95AEB90664BC6700FCB211,
-                               AD0ACCDE062732BD0054A820,
-                               080E96DDFE201D6D7F000001,
-                               ADC15A400664D0F50063754B,
-                               29B97317FDCFA39411CA2CEA,
-                               ADEE3DCE05DD11C900F523DB,
-                               29B97323FDCFA39411CA2CEA,
-                               19C28FACFE9D520D11CA2CBB,
-                       );
-                       isa = PBXGroup;
-                       name = WebUI;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97316FDCFA39411CA2CEA = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = WebUI_main.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97317FDCFA39411CA2CEA = {
-                       children = (
-                               8D1107310486CEB800E47090,
-                               089C165CFE840E0CC02AAC07,
-                               ADA38B8105DD238A00C820AA,
-                       );
-                       isa = PBXGroup;
-                       name = Resources;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               29B97323FDCFA39411CA2CEA = {
-                       children = (
-                               1058C7A1FEA54F0111CA2CBB,
-                               ADEE3DEB05DD135A00F523DB,
-                               AD19ED3105D7FAF4009EBA3A,
-                               ADEE3DDB05DD131E00F523DB,
-                       );
-                       isa = PBXGroup;
-                       name = Frameworks;
-                       path = "";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//290
-//291
-//292
-//293
-//294
-//320
-//321
-//322
-//323
-//324
-               32CA4F630368D1EE00C91783 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = WebUI_Prefix.pch;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-//320
-//321
-//322
-//323
-//324
-//4A0
-//4A1
-//4A2
-//4A3
-//4A4
-               4A9504CCFFE6A4B311CA0CBA = {
-                       buildSettings = {
-                               COPY_PHASE_STRIP = NO;
-                               DEBUGGING_SYMBOLS = YES;
-                               GCC_DYNAMIC_NO_PIC = NO;
-                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-                               GCC_OPTIMIZATION_LEVEL = 0;
-                               OPTIMIZATION_CFLAGS = "-O0";
-                               ZERO_LINK = YES;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Development;
-               };
-               4A9504CDFFE6A4B311CA0CBA = {
-                       buildSettings = {
-                               COPY_PHASE_STRIP = YES;
-                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               ZERO_LINK = NO;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Deployment;
-               };
-//4A0
-//4A1
-//4A2
-//4A3
-//4A4
-//8D0
-//8D1
-//8D2
-//8D3
-//8D4
-               8D1107260486CEB800E47090 = {
-                       buildPhases = (
-                               8D1107270486CEB800E47090,
-                               8D1107290486CEB800E47090,
-                               8D11072C0486CEB800E47090,
-                               8D11072E0486CEB800E47090,
-                               ADF026F205D903AE00D2292D,
-                       );
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               FRAMEWORK_SEARCH_PATHS = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-                               GCC_ENABLE_TRIGRAPHS = NO;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
-                               GCC_PRECOMPILE_PREFIX_HEADER = YES;
-                               GCC_PREFIX_HEADER = WebUI_Prefix.pch;
-                               GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
-                               GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO;
-                               GCC_WARN_UNKNOWN_PRAGMAS = NO;
-                               HEADER_SEARCH_PATHS = "-INGExtensions -INGExtensions/NGLogging";
-                               INFOPLIST_FILE = Info.plist;
-                               INSTALL_PATH = "$(HOME)/Applications";
-                               LIBRARY_SEARCH_PATHS = "";
-                               OTHER_CFLAGS = "-DCOCOA_Foundation_LIBRARY=1 -DNeXT_RUNTIME=1 -DAPPLE_RUNTIME=1";
-                               OTHER_LDFLAGS = "";
-                               PRODUCT_NAME = WebUI;
-                               SECTORDER_FLAGS = "";
-                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
-                               WRAPPER_EXTENSION = sopex;
-                       };
-                       dependencies = (
-                       );
-                       isa = PBXNativeTarget;
-                       name = WebUI;
-                       productInstallPath = "$(HOME)/Applications";
-                       productName = WebUI;
-                       productReference = 8D1107320486CEB800E47090;
-                       productType = "com.apple.product-type.application";
-               };
-               8D1107270486CEB800E47090 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               8D1107280486CEB800E47090,
-                               AD19ED5405D7FBD1009EBA3A,
-                               AD19ED6505D7FBEA009EBA3A,
-                               ADEE3DD705DD126900F523DB,
-                               AD95C2660664CE7400FCB211,
-                               ADC15A430664D1D90063754B,
-                               ADC15A470664DA320063754B,
-                               ADC15A4B0664DA980063754B,
-                               ADC15A4F0664E25B0063754B,
-                               ADC15A560664E33A0063754B,
-                               AD1967250665E52400E19038,
-                               AD0618D0066610A200AC467F,
-                       );
-                       isa = PBXHeadersBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               8D1107280486CEB800E47090 = {
-                       fileRef = 32CA4F630368D1EE00C91783;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               8D1107290486CEB800E47090 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               8D11072B0486CEB800E47090,
-                               ADEE3DD005DD11C900F523DB,
-                               ADA38B8205DD238A00C820AA,
-                               AD95AEBA0664BC6700FCB211,
-                               AD95AEBC0664BC7B00FCB211,
-                               AD0618D50666121C00AC467F,
-                       );
-                       isa = PBXResourcesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               8D11072B0486CEB800E47090 = {
-                       fileRef = 089C165CFE840E0CC02AAC07;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               8D11072C0486CEB800E47090 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               8D11072D0486CEB800E47090,
-                               AD19ED5505D7FBD1009EBA3A,
-                               AD19ED6605D7FBEA009EBA3A,
-                               ADEE3DD805DD126900F523DB,
-                               ADC15A440664D1D90063754B,
-                               ADC15A4C0664DA980063754B,
-                               ADC15A500664E25B0063754B,
-                               ADC15A570664E33A0063754B,
-                               AD1967260665E52400E19038,
-                               AD0618D1066610A200AC467F,
-                       );
-                       isa = PBXSourcesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               8D11072D0486CEB800E47090 = {
-                       fileRef = 29B97316FDCFA39411CA2CEA;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                               );
-                       };
-               };
-               8D11072E0486CEB800E47090 = {
-                       buildActionMask = 2147483647;
-                       files = (
-                               ADEE3DEC05DD135A00F523DB,
-                               ADEE3DDC05DD131F00F523DB,
-                       );
-                       isa = PBXFrameworksBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-               8D1107310486CEB800E47090 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist;
-                       path = Info.plist;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               8D1107320486CEB800E47090 = {
-                       explicitFileType = wrapper.application;
-                       includeInIndex = 0;
-                       isa = PBXFileReference;
-                       path = WebUI.sopex;
-                       refType = 3;
-                       sourceTree = BUILT_PRODUCTS_DIR;
-               };
-//8D0
-//8D1
-//8D2
-//8D3
-//8D4
-//AD0
-//AD1
-//AD2
-//AD3
-//AD4
-               AD0618CE066610A200AC467F = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NGLogSyslogAppender.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD0618CF066610A200AC467F = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = NGLogSyslogAppender.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD0618D0066610A200AC467F = {
-                       fileRef = AD0618CE066610A200AC467F;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD0618D1066610A200AC467F = {
-                       fileRef = AD0618CF066610A200AC467F;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD0618D40666121C00AC467F = {
-                       explicitFileType = text;
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       path = ChangeLog;
-                       refType = 4;
-                       sourceTree = "<group>";
-                       tabWidth = 4;
-                       usesTabs = 1;
-               };
-               AD0618D50666121C00AC467F = {
-                       fileRef = AD0618D40666121C00AC467F;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD0ACCDE062732BD0054A820 = {
-                       children = (
-                               AD0ACCDF062733370054A820,
-                               AD0ACCE1062733370054A820,
-                               AD0ACCE0062733370054A820,
-                       );
-                       isa = PBXGroup;
-                       name = Makefiles;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD0ACCDF062733370054A820 = {
-                       explicitFileType = sourcecode.make;
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       path = GNUmakefile;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD0ACCE0062733370054A820 = {
-                       explicitFileType = sourcecode.make;
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       path = GNUmakefile.postamble;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD0ACCE1062733370054A820 = {
-                       explicitFileType = sourcecode.make;
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       path = GNUmakefile.preamble;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD1967230665E52400E19038 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NGLogConsoleAppender.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD1967240665E52400E19038 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = NGLogConsoleAppender.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD1967250665E52400E19038 = {
-                       fileRef = AD1967230665E52400E19038;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                                       Public,
-                               );
-                       };
-               };
-               AD1967260665E52400E19038 = {
-                       fileRef = AD1967240665E52400E19038;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD1967610665FE4800E19038 = {
-                       children = (
-                               AD1967620665FE5B00E19038,
-                       );
-                       isa = PBXGroup;
-                       name = Makefiles;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD1967620665FE5B00E19038 = {
-                       explicitFileType = sourcecode.make;
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       path = GNUmakefile;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD1967660665FE6800E19038 = {
-                       children = (
-                               AD1967670665FE9200E19038,
-                       );
-                       isa = PBXGroup;
-                       name = Makefiles;
-                       path = NGExtensions;
-                       refType = 2;
-                       sourceTree = SOURCE_ROOT;
-               };
-               AD1967670665FE9200E19038 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       name = GNUmakefile;
-                       path = NGLogging/GNUmakefile;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD19ED3105D7FAF4009EBA3A = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = SOPE.framework;
-                       path = /Library/Frameworks/SOPE.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               AD19ED5205D7FBD1009EBA3A = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = Application.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD19ED5305D7FBD1009EBA3A = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = Application.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD19ED5405D7FBD1009EBA3A = {
-                       fileRef = AD19ED5205D7FBD1009EBA3A;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD19ED5505D7FBD1009EBA3A = {
-                       fileRef = AD19ED5305D7FBD1009EBA3A;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD19ED6305D7FBEA009EBA3A = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = Session.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD19ED6405D7FBEA009EBA3A = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = Session.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD19ED6505D7FBEA009EBA3A = {
-                       fileRef = AD19ED6305D7FBEA009EBA3A;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD19ED6605D7FBEA009EBA3A = {
-                       fileRef = AD19ED6405D7FBEA009EBA3A;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD95AEB90664BC6700FCB211 = {
-                       explicitFileType = sourcecode.make;
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       path = Version;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD95AEBA0664BC6700FCB211 = {
-                       fileRef = AD95AEB90664BC6700FCB211;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD95AEBB0664BC7B00FCB211 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = ChangeLog;
-                       refType = 4;
-                       sourceTree = "<group>";
-                       tabWidth = 4;
-                       usesTabs = 1;
-               };
-               AD95AEBC0664BC7B00FCB211 = {
-                       fileRef = AD95AEBB0664BC7B00FCB211;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               AD95C1870664C1E400FCB211 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = COPYING;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD95C1880664C1E400FCB211 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = COPYRIGHT;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD95C1890664C1E400FCB211 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = NOTES;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD95C18A0664C1E400FCB211 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = PROJECTLEAD;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD95C18B0664C1E400FCB211 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = TODO;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD95C2640664CE7400FCB211 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = common.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD95C2660664CE7400FCB211 = {
-                       fileRef = AD95C2640664CE7400FCB211;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADA38B8105DD238A00C820AA = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = image.icns;
-                       path = Lori.icns;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADA38B8205DD238A00C820AA = {
-                       fileRef = ADA38B8105DD238A00C820AA;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADA38BE605DD23C400C820AA = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = README;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A300664CF290063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = "wox-cheat-sheet.txt";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A400664D0F50063754B = {
-                       children = (
-                               AD1967610665FE4800E19038,
-                               ADC15A530664E3280063754B,
-                       );
-                       isa = PBXGroup;
-                       path = NGExtensions;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A410664D1D90063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = "NSObject+ExtendedLogging.h";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A420664D1D90063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = "NSObject+ExtendedLogging.m";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A430664D1D90063754B = {
-                       fileRef = ADC15A410664D1D90063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                                       Public,
-                               );
-                       };
-               };
-               ADC15A440664D1D90063754B = {
-                       fileRef = ADC15A420664D1D90063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADC15A450664DA320063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NGLogging.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A470664DA320063754B = {
-                       fileRef = ADC15A450664DA320063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                                       Public,
-                               );
-                       };
-               };
-               ADC15A490664DA980063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NGLogger.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A4A0664DA980063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = NGLogger.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A4B0664DA980063754B = {
-                       fileRef = ADC15A490664DA980063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                                       Public,
-                               );
-                       };
-               };
-               ADC15A4C0664DA980063754B = {
-                       fileRef = ADC15A4A0664DA980063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADC15A4D0664E25B0063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NGLogAppender.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A4E0664E25B0063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = NGLogAppender.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A4F0664E25B0063754B = {
-                       fileRef = ADC15A4D0664E25B0063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                                       Public,
-                               );
-                       };
-               };
-               ADC15A500664E25B0063754B = {
-                       fileRef = ADC15A4E0664E25B0063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADC15A530664E3280063754B = {
-                       children = (
-                               AD1967660665FE6800E19038,
-                               AD0618D40666121C00AC467F,
-                               ADC15A450664DA320063754B,
-                               ADC15A410664D1D90063754B,
-                               ADC15A420664D1D90063754B,
-                               ADC15A490664DA980063754B,
-                               ADC15A4A0664DA980063754B,
-                               ADC15A540664E33A0063754B,
-                               ADC15A550664E33A0063754B,
-                               ADC15A4D0664E25B0063754B,
-                               ADC15A4E0664E25B0063754B,
-                               AD1967230665E52400E19038,
-                               AD1967240665E52400E19038,
-                               AD0618CE066610A200AC467F,
-                               AD0618CF066610A200AC467F,
-                       );
-                       isa = PBXGroup;
-                       name = Logging;
-                       path = NGLogging;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A540664E33A0063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = NGLogEvent.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A550664E33A0063754B = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = NGLogEvent.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADC15A560664E33A0063754B = {
-                       fileRef = ADC15A540664E33A0063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                               ATTRIBUTES = (
-                                       Public,
-                               );
-                       };
-               };
-               ADC15A570664E33A0063754B = {
-                       fileRef = ADC15A550664E33A0063754B;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADEE3DCE05DD11C900F523DB = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = folder;
-                       path = WebServerResources;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADEE3DD005DD11C900F523DB = {
-                       fileRef = ADEE3DCE05DD11C900F523DB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADEE3DD405DD123C00F523DB = {
-                       fileRef = ADEE3DCE05DD11C900F523DB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADEE3DD505DD126900F523DB = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = DirectAction.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADEE3DD605DD126900F523DB = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = DirectAction.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADEE3DD705DD126900F523DB = {
-                       fileRef = ADEE3DD505DD126900F523DB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADEE3DD805DD126900F523DB = {
-                       fileRef = ADEE3DD605DD126900F523DB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADEE3DDB05DD131E00F523DB = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = SOPEX.framework;
-                       path = /Library/Frameworks/SOPEX.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               ADEE3DDC05DD131F00F523DB = {
-                       fileRef = ADEE3DDB05DD131E00F523DB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADEE3DEB05DD135A00F523DB = {
-                       isa = PBXFileReference;
-                       lastKnownFileType = wrapper.framework;
-                       name = Cocoa.framework;
-                       path = /System/Library/Frameworks/Cocoa.framework;
-                       refType = 0;
-                       sourceTree = "<absolute>";
-               };
-               ADEE3DEC05DD135A00F523DB = {
-                       fileRef = ADEE3DEB05DD135A00F523DB;
-                       isa = PBXBuildFile;
-                       settings = {
-                       };
-               };
-               ADF026F205D903AE00D2292D = {
-                       buildActionMask = 2147483647;
-                       dstPath = "";
-                       dstSubfolderSpec = 1;
-                       files = (
-                               ADEE3DD405DD123C00F523DB,
-                       );
-                       isa = PBXCopyFilesBuildPhase;
-                       runOnlyForDeploymentPostprocessing = 0;
-               };
-       };
-       rootObject = 29B97313FDCFA39411CA2CEA;
-}
diff --git a/Misc/WebUI/WebUI_Prefix.pch b/Misc/WebUI/WebUI_Prefix.pch
deleted file mode 100644 (file)
index c12a93e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-// Prefix header for all source files of the 'WebUI' target in the 'WebUI' project
-//
-
-#ifdef __OBJC__
-    #import <Foundation/Foundation.h>
-    #include <NGObjWeb/NGObjWeb.h>
-    #include <NGExtensions/NGExtensions.h>
-#endif
diff --git a/Misc/WebUI/WebUI_main.m b/Misc/WebUI/WebUI_main.m
deleted file mode 100644 (file)
index dfe7dcd..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifdef WITHOUT_SOPEX
-#import <NGObjWeb/NGObjWeb.h>
-#define SOPEXMain WOApplicationMain
-#else
-#import <SOPEX/SOPEX.h>
-#endif /* WITHOUT_SOPEX */
-
-
-int main(int argc, const char *argv[])
-{
-    return SOPEXMain(@"Application", argc, argv);
-}
diff --git a/Misc/WebUI/common.h b/Misc/WebUI/common.h
deleted file mode 100644 (file)
index 79bf6b8..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __common_H_
-#define        __common_H_
-
-
-#import <Foundation/Foundation.h>
-
-#include "NGLogging.h"
-
-
-#endif /* __common_H_ */
diff --git a/Misc/WebUI/version.plist b/Misc/WebUI/version.plist
deleted file mode 100644 (file)
index 6f3c68c..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-       <key>BuildVersion</key>
-       <string>1</string>
-       <key>CFBundleShortVersionString</key>
-       <string>0.1</string>
-       <key>CFBundleVersion</key>
-       <string>0.1</string>
-       <key>ProjectName</key>
-       <string>NibPBTemplates</string>
-       <key>SourceVersion</key>
-       <string>1160200</string>
-</dict>
-</plist>
diff --git a/Misc/WebUI/wox-cheat-sheet.txt b/Misc/WebUI/wox-cheat-sheet.txt
deleted file mode 100644 (file)
index 4a79b24..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-WOxControlElemBuilder
----------------------
-
-:if         -> WOConditional
-:foreach    -> WORepetition
-:for-each   -> WORepetition
-:with       -> WOSetCursor
-
-WOxMiscElemBuilder
-------------------
-
-:component-content      -> WOComponentContent
-:checkbox-list          -> WOCheckBoxList
-:entity                 -> WOEntity
-:multiselection         -> WOBrowser
-:nbsp /*DEPRECATED*/    -> WOEntity 
-:popup                  -> WOPopUpButton
-:radio-button-matrix    -> WORadioButtonMatrix
-:string                 -> WOString
-:singleselection        -> WOBrowser
-
-
-WOxHTMLElemBuilder
-------------------
-
-:text       -> WOTextField
-:file       -> WOFileUpload
-:a          -> WOHyperlink
-:img        -> WOImage
-:form       -> WOForm
-:textarea   -> WOText
-:embed      -> WOEmbeddedObject
-:frame      -> WOFrame
-:iframe     -> WOIFrame
-:body       -> WOBody
-
-:input [type="submit"]          -> WOSubmitButton
-:input [type="reset"]           -> WOResetButton
-:input [type="image"]           -> WOImageButton
-:input [type="radio"]           -> WORadioButton
-:input [type="checkbox"]        -> WOCheckBox
-:input [type="file"]            -> WOFileUpload
-:input [type="hidden"]          -> WOHiddenField
-:input [type="password"]        -> WOPasswordField
-:input [type="*"]               -> WOTextField
-
-:meta [http-equiv="refresh*"]   -> WOMetaRefresh
-
-:* [hasChildNodes="YES"]        -> WOGenericContainer
-:* [hasChildNodes="NO"]         -> WOGenericElement
diff --git a/Misc/ZideStore/UI-X/ChangeLog b/Misc/ZideStore/UI-X/ChangeLog
deleted file mode 100644 (file)
index f8c8667..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-2004-06-30  Marcus Müller  <znek@mulle-kybernetik.com>
-
-       * Scheduler/UIxAppointmentEditor.m: improved -saveAction. Does
-         everything in a complete manner now - except for saving which isn't
-         done at all.
-
-2004-06-30  Helge Hess  <helge.hess@opengroupware.org>
-
-       * Scheduler/UIxAppointmentEditor.m: made the hack more hackish to work
-         on MacOSX
-
-2004-06-28  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/UIxComponent.[hm]: moved -ownMethodName here.
-
-       * Scheduler/UIxCalView.[hm]: removed -ownMethodName, moved to
-         UIxComponent (reuse).
-
-       * Scheduler/UIxAppointmentView.[hm]: first "draft" of view component.
-         The look of OGo is resembled closely, but most features are still
-         missing.
-
-2004-06-28  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Scheduler/GNUmakefile.preamble: links against libSOGoLogic now.
-
-       * Scheduler/UIxAppointmentView.m, Scheduler/UIxAppointmentView.wox:
-         test of iCal object.
-
-2004-06-23  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * UIxCalMonthOverview.[m,wox]: completed month view. Turned out to
-         be much more difficult to improve with style sheets than expected.
-         Requires version 4.2.45 of WEExtensions.
-
-2004-06-22  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Refactoring: Renamed everything from OGo to UIx in order to avoid
-         nameclashes (happens on OSX related to NGBundleManager)
-
-       * Refactoring 2: Moved methods from UIxWeekOverview to UIxCalView.
-
-       * Highlighting in UIxWeekOverview works now.
-
-2004-06-22  Helge Hess  <helge.hess@skyrix.com>
-
-       * Common/GNUmakefile.preamble: fixed linking for OGo gstep-make
-
-2004-06-21  Helge Hess  <helge.hess@opengroupware.org>
-
-       * Scheduler/OGoCalWeekOverview.m: fixed syntax errors
-
-2004-06-18  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Implemented proper calendar in week overview. Highlighting isn't
-         enabled, yet.
-
-2004-06-18  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/OGoComponent.[hm]: new component which serves as a base
-         component for calendar components now. Knows how to deal with
-         queryParameters and offers url construction method(s).
-
-       * All existing components have been rewritten to use queryParameters
-         instead of hardcoded strings where this is feasible. This provides
-         future extensibility and flexibility.
-
-       * Handling of dates has been fixed to center around the use of a
-         'day' parameter. startDate/endDate are coupled to this, but
-         don't override it as it's the duty of the individual view to set
-         its (feasible) ranges accordingly. The new behaviour is noticable
-         in the calendar selection tabview instantly, as it now replicates
-         what OGo does.
-
-2004-06-16  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/OGoAppNavView.m: construct URL correctly.
-
-       * Common/OGoPageFrame.m: display login correctly.
-
-       * Common/calendar.css: cosmetic changes.
-
-       * Scheduler/OGoCalSelectTab.m: always display mondayOfWeek.
-
-       * Scheduler/OGoCalBackForthNavView.m: created.
-
-2004-06-16  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/zidestoreui.css: new style for button_auto.
-
-       * Scheduler/OGoCalView.[hm]: API for completing hrefs with necessary
-         query parts.
-
-       * Scheduler/OGoCalWeekView.m: bugfix for startDate.
-
-       * Scheduler/product.plist: added still missing views -> point to
-         weekoverview for the time being.
-       
-2004-06-15  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/UIxTabView.m: removed class from <a> tag, removed rendering
-         of headerFooter (what's that good for anyways?)
-
-       * Several resources which resolved to wrong products added statically
-         in templates.
-
-       * Cosmetic changes in templates.
-
-2004-06-14  Helge Hess  <helge.hess@opengroupware.org>
-
-       * Scheduler/OGoCalMonthOverview.wox: added missing rsrc namespace
-
-2004-06-14  Helge Hess  <helge.hess@skyrix.com>
-
-       * Common/common.h: fixed a gcc 3.4 warning
-
-2004-06-14  Helge Hess  <helge.hess@opengroupware.org>
-
-       * added aggregate project for UI-X
-
-2004-06-14  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/calendar.css: new date_label (unused)
-
-       * Scheduler/OGoCalSelectTab.m: finished all labels
-
-       * Scheduler/OGoCalDateLabel.m, Scheduler/OGoCalDateLabel.wox: new
-         component for rendering the correct date label based on startDate,
-         endDate and selection
-
-       * Scheduler/OGoCalMonthView.m: prev/next month corrected
-
-       * Scheduler/OGoCalMonthOverview.wox: uses date label and tabs now
-
-       * Scheduler/OGoCalWeekOverview.wox: completed layout
-
-       * Scheduler/GNUmakefile: new component added
-
-2004-06-14  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/UIxTabView.[hm]: more stylesheet support via headerStyle
-         and bodyStyle bindings.
-       
-       * Common/zidestoreui.css: styles for tabs, resembling OGo look.
-
-       * Scheduler/OGoCalSelectTab.m: implemented dateLabel (for testing).
-
-       * Scheduler/OGoCalSelectTab.wox: corrected selection binding namespace.
-
-2004-06-08  Helge Hess  <helge.hess@opengroupware.org>
-
-       * Scheduler/NOTES: added class hierarchy
-
-       * */common.h, GNUmakefile.preamble.: fixed for OSX compile
-
-2004-06-08  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Common/images: added a bunch of images from OGo
-
-2004-06-07  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Custom/GNUmakefile: changed ZIDESTORE to include installed version
-         (ZideStore12). Removed post install hooks.
-
-       * Custom/GNUmakefile.postamble: new file, post install hooks and
-         xmllint for .wox.
-
-2004-06-07  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Scheduler/GNUmakefile: changed ZIDESTORE to include installed version
-         (ZideStore12). Removed post install hooks.
-
-       * Scheduler/GNUmakefile.postamble: post install hooks updated for
-         GNUSTEP_BUILD_DIR.
-
-2004-06-03  Helge Hess  <helge.hess@opengroupware.org>
-
-       * Scheduler/OGoCalWeekOverview.m: moved navigation URL generation to
-         superclass (now generic because we use the 'ownMethodName'). Could
-         even be moved to OGoCalView?
-       
-       * Scheduler/OGoCalMonthView.m: added next/prev month URL generation
-         methods, calculate startdate from form value
-
-       * Scheduler/OGoCalView.m: added -ownMethodName method to return the
-         last path component of the request URL (the SOPE method), eg
-         'weekoverview' for OGoCalWeekView, added 
-         -dateNavigationURLWithNewStartDate: method to calculate 'startDate'
-         URLs (should be improved to include existing query parameters!)
-
-       * Scheduler/OGoCalWeekOverview.m: minor tweaks ;-)
-
-2004-06-03  Marcus Mueller  <znek@mulle-kybernetik.com>
-
-       * Scheduler/OGoCalWeekView.m: construct startDate from formValue,
-         otherwise use current week's monday as startDate.
-
-       * Scheduler/OGoCalWeekOverview.wox: switch back/forth
-
-       * Scheduler/OGoCalWeekOverview.m: provide URLs for switching back/forth
-         weekoverview.
-
-       * Scheduler/OGoCalView.[hm]: methods for converting dates into strings
-         and vice versa.
-
-       * Scheduler/OGoAppointmentView.m, Scheduler/OGoCalView.m: fixed include
-
-       * ChangeLog: created
diff --git a/Misc/ZideStore/UI-X/Common/CommonUIProduct.m b/Misc/ZideStore/UI-X/Common/CommonUIProduct.m
deleted file mode 100644 (file)
index b5a4da4..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  Copyright (C) 2000-2003 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: CommonUIProduct.m,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-#import <Foundation/NSObject.h>
-
-@interface CommonUIProduct : NSObject
-{
-}
-
-@end
-
-#include "common.h"
-
-@implementation CommonUIProduct
-@end /* CommonUIProduct */
diff --git a/Misc/ZideStore/UI-X/Common/GNUmakefile b/Misc/ZideStore/UI-X/Common/GNUmakefile
deleted file mode 100644 (file)
index 0fda272..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-# $Id: GNUmakefile,v 1.2 2003/12/09 17:38:42 helge Exp $
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-ZIDESTORE=$(GNUSTEP_USER_ROOT)/Headers/ZideStore12
-
-
-BUNDLE_NAME        = CommonUI
-BUNDLE_EXTENSION   = .zsp
-BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/ZideStore12
-
-LIBRARY_NAME = libZideStoreCommonUI
-
-
-libZideStoreCommonUI_HEADER_FILES_DIR         = .
-libZideStoreCommonUI_HEADER_FILES_INSTALL_DIR = $(ZIDESTORE)/Common
-
-libZideStoreCommonUI_HEADER_FILES += \
-       UIxComponent.h \
-
-libZideStoreCommonUI_OBJC_FILES += \
-       UIxComponent.m \
-
-
-CommonUI_PRINCIPAL_CLASS = CommonUIProduct
-
-CommonUI_OBJC_FILES += \
-       CommonUIProduct.m       \
-       UIxPageFrame.m          \
-       UIxAppFrame.m           \
-       UIxAppHeader.m          \
-       UIxAppNavigation.m      \
-       UIxWinClose.m   \
-       UIxAppNavView.m \
-       \
-       UIxElemBuilder.m \
-       UIxTabView.m \
-       UIxTabItem.m \
-
-
-CommonUI_RESOURCE_FILES += \
-       Version                 \
-       product.plist           \
-       UIxPageFrame.wox        \
-       UIxAppFrame.wox         \
-       UIxAppHeader.wox        \
-       UIxAppNavigation.wox    \
-       UIxWinClose.wox \
-       UIxAppNavView.wox \
-       \
-       zidestoreui.css         \
-       calendar.css            \
-       \
-       images/OGoLogo.gif      \
-       images/menu_logo_top.gif        \
-       images/line_left.gif    \
-       images/line_stretch.gif \
-       images/line_right.gif   \
-       images/box_topleft.gif  \
-       images/box_top.gif      \
-       images/box_topright.gif \
-       images/box_left.gif     \
-       images/box_right.gif    \
-       images/box_botleft.gif  \
-       images/box_bottom.gif\
-       images/box_botright.gif\
-       images/tab_selected.gif\
-       images/tab_.gif\
-       images/corner_right.gif\
-       images/closewindow.gif
-
-ADDITIONAL_INCLUDE_DIRS += \
-       -I. \
-       -I$(ZIDESTORE)/Frontend -I$(ZIDESTORE)/Backend -I$(ZIDESTORE)
-
-
-# make
-
--include GNUmakefile.preamble
-include $(GNUSTEP_MAKEFILES)/library.make
-include $(GNUSTEP_MAKEFILES)/bundle.make
--include GNUmakefile.postamble
diff --git a/Misc/ZideStore/UI-X/Common/GNUmakefile.postamble b/Misc/ZideStore/UI-X/Common/GNUmakefile.postamble
deleted file mode 100644 (file)
index 3986bcc..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# $Id: GNUmakefile.postamble,v 1.1 2004/05/12 14:45:56 helge Exp $
-
-validate-wox:
-       xmllint --noout *.wox
-
-before-all :: validate-wox
-
-
-ifneq ($(GNUSTEP_BUILD_DIR),)
-after-all ::
-       @(cp bundle-info.plist \
-         $(GNUSTEP_BUILD_DIR)/$(BUNDLE_NAME)$(BUNDLE_EXTENSION))
-else
-after-all ::
-       @(cd $(BUNDLE_NAME)$(BUNDLE_EXTENSION);\
-         cp ../bundle-info.plist .)
-endif
diff --git a/Misc/ZideStore/UI-X/Common/GNUmakefile.preamble b/Misc/ZideStore/UI-X/Common/GNUmakefile.preamble
deleted file mode 100644 (file)
index e76e480..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# $Id$
-
-ifneq ($(GNUSTEP_BUILD_DIR),)
-       RELBUILD_DIR_libZideStoreCommonUI = $(GNUSTEP_OBJ_DIR)
-else
-       RELBUILD_DIR_libZideStoreCommonUI = $(GNUSTEP_OBJ_DIR)
-endif
-
-libZideStoreCommonUI_LIBRARIES_DEPEND_UPON += -lNGObjWeb
-
-CommonUI_LIB_DIRS += -L$(RELBUILD_DIR_libZideStoreCommonUI)
-
-CommonUI_BUNDLE_LIBS += \
-       -lNGObjWeb -lNGScripting \
-       -lNGMime -lNGStreams -lNGExtensions -lEOControl \
-       -lXmlRpc -lDOM -lSaxObjC -lZideStoreCommonUI
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppFrame.m b/Misc/ZideStore/UI-X/Common/UIxAppFrame.m
deleted file mode 100644 (file)
index 8d9553f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface UIxAppFrame : SoComponent
-@end
-
-#include "common.h"
-
-@implementation UIxAppFrame
-@end /* UIxAppFrame */
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppFrame.wox b/Misc/ZideStore/UI-X/Common/UIxAppFrame.wox
deleted file mode 100644 (file)
index 0437cf3..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
->
-  <head>
-    <title><var:string value="title"/></title>
-    
-    <meta name="description" content="ZideStore Web Interface" />
-    <meta name="author"      content="SKYRIX Software AG" />
-    <meta name="robots"      content="stop" />
-    
-    <link href="mailto:hh@skyrix.com" rev="made" />
-  </head>
-  
-  <frameset rows="48,*" frameborder="0" framespacing="0" border="0">
-    
-    <frame src="appheader"
-           name="head"
-           leftmargin="0" topmargin="0" marginheight="0" marginwidth="0" 
-           scrolling="no" noresize="yes" />
-
-    <frameset cols="150,*">
-
-      <frame src="appnavigation"
-             name="navi"
-             leftmargin="0" topmargin="0" marginheight="0" marginwidth="0" 
-             scrolling="yes" />
-
-      <frame src="view"
-             name="content"
-             leftmargin="0" topmargin="0" marginheight="0" marginwidth="0" 
-             scrolling="yes" />
-
-    </frameset>
-
-  </frameset>
-
-  <noframes>
-    This pages requires frame tags, which your browser does not support,
-    sorry ;->
-  </noframes>
-</html>
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppHeader.m b/Misc/ZideStore/UI-X/Common/UIxAppHeader.m
deleted file mode 100644 (file)
index 5a4db92..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface UIxAppHeader : SoComponent
-@end
-
-#include "common.h"
-
-@implementation UIxAppHeader
-@end /* UIxAppHeader */
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppHeader.wox b/Misc/ZideStore/UI-X/Common/UIxAppHeader.wox
deleted file mode 100644 (file)
index 4f8c0d2..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
->
-  <head>
-    <link type="text/css" rel="stylesheet" rsrc:href="zidestoreui.css" />
-
-    <script language="javascript">
-      function viewInNavi(url) {
-        parent.navi.location=url;
-        return true
-      }
-    </script>
-  </head>
-
-  <body>
-    <div id="header">
-      <img filename="OGoLogo.gif" class="headerlogo" alt="Logo" />
-      <div id="headerhistory">
-        <span id="navtitle">ZideStore UI - Experimental</span>
-      </div>
-    </div>
-    
-    <div style="text-align: right; font-size: 8pt;">
-      <a href="#" onClick="viewInNavi('appnavigation')">reload</a> -
-      resistance is obsolete <entity name="trade"/> ;-)
-    </div>
-  </body>
-</html>
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppNavView.m b/Misc/ZideStore/UI-X/Common/UIxAppNavView.m
deleted file mode 100644 (file)
index 8bf1ff1..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#import <NGObjWeb/NGObjWeb.h>
-#import <NGObjWeb/SoObject+SoDAV.h>
-#import <NGObjWeb/WOContext+SoObjects.h>
-#import <Foundation/Foundation.h>
-
-
-@interface UIxAppNavView : WOComponent
-{
-    id element;
-    id lastElement;
-}
-
-@end
-
-
-@implementation UIxAppNavView
-
-- (void)dealloc {
-    [self->element release];
-    [self->lastElement release];
-    [super dealloc];
-}
-
-- (void)setElement:(id)_element {
-    ASSIGN(self->element, _element);
-}
-
-- (id)element {
-    return self->element;
-}
-
-- (void)setLastElement:(id)_element {
-    ASSIGN(self->lastElement, _element);
-}
-
-- (id)lastElement {
-    return self->lastElement;
-}
-
-- (NSArray *)navPathElements {
-    NSArray *traversalObjects;
-    NSMutableArray *navPathComponents;
-    NSMutableString *navURL;
-    unsigned int i, count;
-
-    traversalObjects = [[self context] objectTraversalStack];
-    count = ([traversalObjects count] - 1); /* remove SoPageInvocation */
-    navPathComponents = [[NSMutableArray alloc] initWithCapacity:count];
-    navURL = [[NSMutableString alloc] initWithString:@"/"];
-
-    for(i = 0; i < count; i++) {
-        NSString *name, *url;
-        id obj;
-        
-        obj = [traversalObjects objectAtIndex:i];
-
-        name = [obj davDisplayName];
-        if(!name)
-            name = NSStringFromClass([obj class]);
-
-        [navURL appendString:name];
-        [navURL appendString:@"/"];
-        
-        if(! [name hasPrefix:@"ZideStore"]) {
-            NSMutableDictionary *c;
-
-            c = [[NSMutableDictionary alloc] initWithCapacity:2];
-            [c setObject:name forKey:@"name"];
-            url = [navURL copy];
-            [c setObject:url forKey:@"url"];
-            [url release];
-            [navPathComponents addObject:c];
-            [c release];
-        }
-    }
-
-    [self setLastElement:[navPathComponents lastObject]];
-    return [navPathComponents autorelease];
-}
-
-@end
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppNavView.wox b/Misc/ZideStore/UI-X/Common/UIxAppNavView.wox
deleted file mode 100644 (file)
index 6e924d4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<font xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      class="defaultfont"
->
-<b>You are here:</b><var:entity const:name="nbsp" /><var:foreach list="navPathElements" item="element"><var:if condition="element" value="lastElement" const:negate="YES"><a var:href="element.url"><var:string value="element.name" /></a><var:entity const:name="nbsp" />/<var:entity const:name="nbsp" /></var:if><var:if condition="element" value="lastElement"><var:string value="element.name" /></var:if></var:foreach>
-</font>
\ No newline at end of file
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppNavigation.m b/Misc/ZideStore/UI-X/Common/UIxAppNavigation.m
deleted file mode 100644 (file)
index 529127d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface UIxAppNavigation : SoComponent
-@end
-
-#include "common.h"
-
-@implementation UIxAppNavigation
-@end /* UIxAppNavigation */
diff --git a/Misc/ZideStore/UI-X/Common/UIxAppNavigation.wox b/Misc/ZideStore/UI-X/Common/UIxAppNavigation.wox
deleted file mode 100644 (file)
index 27eadaf..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
->
-  <head>
-    <link type="text/css" rel="stylesheet" rsrc:href="zidestoreui.css" />
-
-    <style>
-      a:link, a:visited, a:active, a:hover { 
-        text-decoration: none; 
-        font-family:     Arial, Helvetica, Helv, Sans-Serif;
-        font-size:       9pt;
-        color:           #0000FF;
-      }
-      a.reloadlink {
-        color:      black;
-      }
-
-      ul {
-        margin:          0; /*removes indent IE and Opera*/
-        padding:         0; /*removes indent Mozilla and NN7*/
-        /* list-style-type: none; */ /*turns off display of bullet*/
-        font-family:     Arial, Helvetica, sans-serif;
-        font-size:       14pt;
-      }
-
-      ul li {
-        /* padding-left: 4px; */
-        /* list-style: url(http://vesper.in.skyrix.com/SKYRiXgreen/WebServerResources/EN.lproj/nav_folder_open.gif); */
-        list-style: url(http://move:9000/OpenGroupware.woa/WebServerResources/English.lproj/icon_folder.gif);
-      }
-
-      ul li a {
-        display: block;
-        border:           1px solid #FFFFFF;
-        padding:          2px 2px 2px 24px;
-        width:            80%;
-        background-color: #EEEEEE;
-      }
-
-      ul li a:link, ul li a:visited {
-        text-decoration:  none;
-      }
-      ul li a:hover {
-        border:           1px solid #333333;
-        background-color: #CCCCCC;
-      }
-    </style>
-
-    <script language="javascript"><![CDATA[
-      function viewInContent(url) {
-        parent.content.location=url;
-        return true;
-      }
-    ]]></script>
-  </head>
-
-  <body leftmargin="0"  topmargin="0" marginwidth="0" marginheight="0">
-    <br />
-    <ul>
-      <li><a href="#">OGo</a></li>
-      <li><a href="#" onclick="viewInContent('view')"         >View</a></li>
-      <li><a href="#" onclick="viewInContent('weekoverview')" >Week</a></li>
-      <li><a href="#" onclick="viewInContent('monthoverview')">Month</a></li>
-      <li><a href="#">OGo</a></li>
-    </ul>
-    <br />
-    
-    <div style="border-top: 1px solid #000000;">
-      <a href="appnavigation" class="reloadlink" 
-         var:_o="context.contextID"><i>(reload)</i></a>
-    </div>
-
-    <br />
-
-    <div style="border-top: 1px solid #000000; font-size: 8pt">
-      <var:string value="context.contextID" />
-    </div>
-    <a href="http://www.projectseven.com/tutorials/css_menus/list_01/"
-       target="extlink">CSS Menues</a>
-  </body>
-</html>
diff --git a/Misc/ZideStore/UI-X/Common/UIxComponent.h b/Misc/ZideStore/UI-X/Common/UIxComponent.h
deleted file mode 100644 (file)
index d9a0c6f..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __UIxComponent_H_
-#define        __UIxComponent_H_
-
-#include <NGObjWeb/SoComponent.h>
-
-@class NSCalendarDate;
-
-
-@interface UIxComponent : SoComponent
-{
-    NSMutableDictionary *queryParameters;
-}
-
-- (NSString *)queryParameterForKey:(NSString *)_key;
-- (NSDictionary *)queryParameters;
-
-/* use this to set 'sticky' query parameters */
-- (void)setQueryParameter:(NSString *)_param forKey:(NSString *)_key;
-
-/* appends queryParameters to _method if any are set */
-- (NSString *)completeHrefForMethod:(NSString *)_method;
-
-- (NSString *)ownMethodName;
-
-/* date selection */
-- (NSCalendarDate *)selectedDate;
-- (NSString *)dateStringForDate:(NSCalendarDate *)_date;
-- (NSCalendarDate *)dateForDateString:(NSString *)_dateString;
-
-@end
-
-#endif /* __UIxComponent_H_ */
diff --git a/Misc/ZideStore/UI-X/Common/UIxComponent.m b/Misc/ZideStore/UI-X/Common/UIxComponent.m
deleted file mode 100644 (file)
index 280bcd7..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include "UIxComponent.h"
-#include <Foundation/Foundation.h>
-#include <NGObjWeb/NGObjWeb.h>
-#include <NGExtensions/NGExtensions.h>
-
-
-@interface UIxComponent (PrivateAPI)
-- (void)_parseQueryString:(NSString *)_s;
-@end
-
-
-@implementation UIxComponent
-
-- (id)init {
-    if ((self = [super init])) {
-        self->queryParameters = [[NSMutableDictionary alloc] init];
-    }
-    return self;
-}
-
-- (void)dealloc {
-    [self->queryParameters release];
-    [super dealloc];
-}
-
-
-- (void)awake {
-    WORequest *req;
-    NSString *uri;
-    NSRange r;
-
-    [super awake];
-
-    req = [[self context] request];
-    uri = [req uri];
-    r = [uri rangeOfString:@"?"];
-    if(r.length > 0) {
-        NSString *qs;
-        
-        qs = [uri substringFromIndex:(r.location + r.length)];
-        [self->queryParameters removeAllObjects];
-        [self _parseQueryString:qs];
-    }    
-}
-
-- (void)_parseQueryString:(NSString *)_s {
-    NSEnumerator *e;
-    NSString *part;
-    
-    e = [[_s componentsSeparatedByString:@"&"] objectEnumerator];
-    while ((part = [e nextObject])) {
-        NSRange  r;
-        NSString *key, *value;
-        
-        r = [part rangeOfString:@"="];
-        if (r.length == 0) {
-            /* missing value of query parameter */
-            key   = [part stringByUnescapingURL];
-            value = @"1";
-        }
-        else {
-            key   = [[part substringToIndex:r.location] stringByUnescapingURL];
-            value = [[part substringFromIndex:(r.location + r.length)] 
-                stringByUnescapingURL];
-        }
-        [self->queryParameters setObject:value forKey:key];
-    }
-}
-
-- (NSString *)queryParameterForKey:(NSString *)_key {
-    return [self->queryParameters objectForKey:_key];
-}
-
-- (void)setQueryParameter:(NSString *)_param forKey:(NSString *)_key {
-    if(_key == nil)
-        return;
-
-    if(_param != nil)
-        [self->queryParameters setObject:_param forKey:_key];
-    else
-        [self->queryParameters removeObjectForKey:_key];
-}
-
-- (NSDictionary *)queryParameters {
-    return self->queryParameters;
-}
-
-- (NSString *)completeHrefForMethod:(NSString *)_method {
-    NSDictionary *qp;
-    NSString *qs;
-    
-    qp = [self queryParameters];
-    if([qp count] == 0)
-        return _method;
-    
-    qs = [[self context] queryStringFromDictionary:qp];
-    return [_method stringByAppendingFormat:@"?%@", qs];
-}
-
-- (NSString *)ownMethodName {
-    NSString *uri;
-    NSRange  r;
-    
-    uri = [[[self context] request] uri];
-    
-    /* first: cut off query parameters */
-    
-    r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
-    if (r.length > 0)
-        uri = [uri substringToIndex:r.location];
-    
-    /* next: strip trailing slash */
-    
-    if ([uri hasSuffix:@"/"]) uri = [uri substringToIndex:([uri length] - 1)];
-    r = [uri rangeOfString:@"/" options:NSBackwardsSearch];
-    
-    /* then: cut of last path component */
-    
-    if (r.length == 0) // no slash? are we at root?
-        return @"/";
-    
-    return [uri substringFromIndex:(r.location + 1)];
-}
-
-/* date */
-
-- (NSCalendarDate *)selectedDate {
-    NSString *s;
-    
-    s = [self queryParameterForKey:@"day"];
-    if(s) {
-        return [self dateForDateString:s];
-    }
-    return [NSCalendarDate date];
-}
-
-- (NSString *)dateStringForDate:(NSCalendarDate *)_date {
-    return [_date descriptionWithCalendarFormat:@"%Y%m%d"];
-}
-
-- (NSCalendarDate *)dateForDateString:(NSString *)_dateString {
-    return [NSCalendarDate dateWithString:_dateString calendarFormat:@"%Y%m%d"];
-}
-
-@end
diff --git a/Misc/ZideStore/UI-X/Common/UIxElemBuilder.m b/Misc/ZideStore/UI-X/Common/UIxElemBuilder.m
deleted file mode 100644 (file)
index 0057908..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include <NGObjWeb/WOxElemBuilder.h>
-
-/*
-  This builder builds various elements from the UI-X product.
-
-  All tags are mapped into the <uix:> namespace (XMLNS_OD_BIND).
-
-    <var:tabview   .../>    maps to UIxTabView
-    <var:tab       .../>    maps to UIxTabItem
-*/
-
-@interface UIxElemBuilder : WOxTagClassElemBuilder
-{
-}
-
-@end
-
-#include <SaxObjC/XMLNamespaces.h>
-#include "common.h"
-
-#define XMLNS_UIX @"OGo:uix"
-
-
-@implementation UIxElemBuilder
-
-- (Class)classForElement:(id<DOMElement>)_element {
-  NSString *tagName;
-  unsigned tl;
-  unichar c1;
-  
-  if (![[_element namespaceURI] isEqualToString:XMLNS_UIX])
-    return Nil;
-
-  tagName = [_element tagName];
-  if ((tl = [tagName length]) < 2)
-    return Nil;
-
-  c1 = [tagName characterAtIndex:0];
-
-  switch (c1) {
-    case 't': { /* starting with 't' */
-      unichar c2;
-      
-      c2 = [tagName characterAtIndex:1];
-      
-      if (tl == 3 && c2 == 'a') {
-        if ([tagName characterAtIndex:2] == 'b')
-          return NSClassFromString(@"UIxTabItem");
-      }
-
-      if (tl > 5) {
-        if (c2 == 'a') {
-          if ([tagName isEqualToString:@"tabview"])
-            return NSClassFromString(@"UIxTabView");
-        }
-      }
-      break;
-    }
-  }
-  
-  return Nil;
-}
-
-@end /* UIxElemBuilder */
diff --git a/Misc/ZideStore/UI-X/Common/UIxPageFrame.m b/Misc/ZideStore/UI-X/Common/UIxPageFrame.m
deleted file mode 100644 (file)
index ba39e5f..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-#include <NGObjWeb/SoHTTPAuthenticator.h>
-#include <NGObjWeb/SoUser.h>
-
-
-@interface UIxPageFrame : SoComponent
-{
-  NSString *title;
-}
-
-@end
-
-#include "common.h"
-
-@implementation UIxPageFrame
-
-- (void)dealloc {
-  [self->title release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (void)setTitle:(NSString *)_value {
-  ASSIGN(self->title, _value);
-}
-
-- (NSString *)title {
-  return self->title;
-}
-
-- (NSString *)login {
-    WOContext *ctx;
-    SoUser *user;
-    
-    ctx = [self context];
-    user = [[[self clientObject] authenticatorInContext:ctx]
-                                 userInContext:ctx];
-    return [user login];
-}
-
-@end /* UIxPageFrame */
diff --git a/Misc/ZideStore/UI-X/Common/UIxPageFrame.wox b/Misc/ZideStore/UI-X/Common/UIxPageFrame.wox
deleted file mode 100644 (file)
index efc1f4d..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:var="http://www.skyrix.com/od/binding" xmlns:const="http://www.skyrix.com/od/constant" xmlns:rsrc="OGo:url">
-  <head>
-    <title>
-      <var:string value="title"/>
-    </title>
-    <meta name="description" content="ZideStore Web Interface"/>
-    <meta name="author" content="SKYRIX Software AG"/>
-    <meta name="robots" content="stop"/>
-    <link type="text/css" rel="stylesheet" rsrc:href="zidestoreui.css"/>
-    <link type="text/css" rel="stylesheet" rsrc:href="calendar.css"/>
-    <link href="mailto:hh@skyrix.com" rev="made"/>
-  </head>
-  <body>
-<!--
-    <div id="header">
-      <img filename="OGoLogo.gif" class="headerlogo" alt="Logo" />
-      <div id="headerhistory">
-        <span id="navtitle">ZideStore UI - Experimental</span>
-      </div>
-    </div>
-    <br />
--->
-    <table cellpadding="5" cellspacing="0" border="0" width="100%">
-      <tr>
-        <td colspan="2">
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td valign="bottom">
-              <var:component className="UIxAppNavView" />
-              </td>
-              <td align="right">
-                <a href="http://www.opengroupware.org:80/" target="OGo">
-                  <img rsrc:src="menu_logo_top.gif" align="center" border="0" ALT="" Valign="middle"/>
-                </a>
-              </td>
-            </tr>
-          </table>
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td class="linecolor">
-                <img rsrc:src="line_left.gif"/>
-              </td>
-              <td class="linecolor" width="100%">
-                <img rsrc:src="line_stretch.gif"/>
-              </td>
-              <td class="linecolor">
-                <img rsrc:src="line_right.gif"/>
-              </td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-      <tr>
-        <td valign="top">
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-<!-- $Id: SkyDock.html,v 1.13 2004/02/13 14:08:27 helge Exp $ -->
-              <td valign="top">
-                <table border="0" cellspacing="0" cellpadding="0" class="leftmenu">
-                  <tr>
-                    <td>
-                      <img rsrc:src="box_topleft.gif"/>
-                    </td>
-                    <td valign="top" rsrc:background="box_top.gif">
-                      <img rsrc:src="box_top.gif"/>
-                    </td>
-                    <td>
-                      <img rsrc:src="box_topright.gif"/>
-                    </td>
-                  </tr>
-                  <tr valign="top">
-                    <td rsrc:background="box_left.gif">
-                      <img rsrc:src="box_left.gif"/>
-                    </td>
-                    <td width="100%">
-                      <table width="100%" border="0" cellspacing="2" cellpadding="" class="leftmenu">
-                        <tr>
-                          <td>
-                            <font class="skydockfont">
-                              <a href="/ZideStore/" class="skydockfont">SOGo (<var:string value="login" />)</a>
-                            </font>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td colspan="2">
-                            <table cellpadding="0" cellspacing="0" border="0" width="100%">
-                              <tr>
-                                <td class="linecolor">
-                                  <img rsrc:src="line_left.gif"/>
-                                </td>
-                                <td class="linecolor" width="100%">
-                                  <img rsrc:src="line_stretch.gif"/>
-                                </td>
-                                <td class="linecolor">
-                                  <img rsrc:src="line_right.gif"/>
-                                </td>
-                              </tr>
-                            </table>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td height="3"/>
-                        </tr>
-                        <tr>
-                          <td valign="middle">
-                            <font class="skydockfont">
-                              <a href="/OpenGroupware/x/dock" class="skydockfont">News</a>
-                            </font>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td valign="middle">
-                            <font class="skydockfont">
-                              <a href="/OpenGroupware/x/dock" class="skydockfont">Projects</a>
-                            </font>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td valign="middle">
-                            <font class="skydockfont">
-                              <a href="/OpenGroupware/x/dock" class="skydockfont">Contacts</a>
-                            </font>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td valign="middle">
-                            <font class="skydockfont">
-                              <a href="/OpenGroupware/x/dock" class="skydockfont">Companies</a>
-                            </font>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td valign="middle">
-                            <font class="skydockfont">
-                              <a href="/OpenGroupware/x/dock" class="skyDockFont">Calendar</a>
-                            </font>
-                          </td>
-                        </tr>
-                        <tr>
-                          <td valign="middle">
-                            <font class="skydockfont">
-                              <a href="/OpenGroupware/x/dock" class="skydockfont">Tasks</a>
-                            </font>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                    <td rsrc:background="box_right.gif">
-                      <img rsrc:src="box_right.gif"/>
-                    </td>
-                  </tr>
-                  <tr>
-                    <td>
-                      <img rsrc:src="box_botleft.gif"/>
-                    </td>
-                    <td rsrc:background="box_bottom.gif">
-                      <img rsrc:src="box_bottom.gif"/>
-                    </td>
-                    <td>
-                      <img rsrc:src="box_botright.gif"/>
-                    </td>
-                  </tr>
-                </table>
-<!-- $Id: SkyDockedProjects.html,v 1.10 2004/05/07 16:05:03 helge Exp $ -->
-              </td>
-            </tr>
-          </table>
-          <br/>
-<!-- $Id: SkyFavorites.html,v 1.5 2003/10/29 18:06:00 helge Exp $ -->
-<!-- the misc box -->
-          <span>
-            <table cellspacing="0" class="leftmenu" border="0" cellpadding="0">
-              <tr>
-                <td>
-                  <img rsrc:src="box_topleft.gif"/>
-                </td>
-                <td rsrc:background="box_top.gif">
-                  <img rsrc:src="box_top.gif"/>
-                </td>
-                <td>
-                  <img rsrc:src="box_topright.gif"/>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td rsrc:background="box_left.gif">
-                  <img rsrc:src="box_left.gif"/>
-                </td>
-                <td width="100%">
-                  <table width="100%" cellspacing="2" class="leftmenu" border="0" cellpadding="">
-                    <tr>
-                      <td>
-                        <font class="skydockfont">Misc</font>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td colspan="2">
-                        <table width="100%" cellspacing="0" border="0" cellpadding="0">
-                          <tr>
-                            <td class="linecolor">
-                              <img rsrc:src="line_left.gif"/>
-                            </td>
-                            <td width="100%" class="linecolor">
-                              <img rsrc:src="line_stretch.gif"/>
-                            </td>
-                            <td class="linecolor">
-                              <img rsrc:src="line_right.gif"/>
-                            </td>
-                          </tr>
-                        </table>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td height="3"/>
-                    </tr>
-                    <tr>
-                      <td valign="middle">
-                        <a href="/OpenGroupware/x/mail" class="skydockfont">New Email</a>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td valign="middle">
-                        <a href="/OpenGroupware/x/mail" class="skydockfont">Inbox</a>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td valign="middle">
-                        <a href="/OpenGroupware/x/dock" class="skydockfont">Preferences</a>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td valign="middle">
-                        <a href="/OpenGroupware/x/downloadBookmark" target="private_desktop" class="skydockfont">Home</a>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td valign="middle">
-                        <a href="/OpenGroupware/x/downloadBookmark" target="public_desktop" class="skydockfont">Desktop</a>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td valign="middle">
-                        <a href="/OpenGroupware/x/dock" class="skydockfont">Logout</a>
-                      </td>
-                    </tr>
-                  </table>
-                </td>
-                <td rsrc:background="box_right.gif">
-                  <img rsrc:src="box_right.gif"/>
-                </td>
-              </tr>
-              <tr>
-                <td>
-                  <img rsrc:src="box_botleft.gif"/>
-                </td>
-                <td rsrc:background="box_bottom.gif">
-                  <img rsrc:src="box_bottom.gif"/>
-                </td>
-                <td>
-                  <img rsrc:src="box_botright.gif"/>
-                </td>
-              </tr>
-            </table>
-          </span>
-        </td>
-        <td valign="top" width="100%">
-          <var:component-content/>
-        </td>
-      </tr>
-      <tr>
-        <td colspan="2">
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td class="linecolor">
-                <img rsrc:src="line_left.gif"/>
-              </td>
-              <td class="linecolor" width="100%">
-                <img rsrc:src="line_stretch.gif"/>
-              </td>
-              <td class="linecolor">
-                <img rsrc:src="line_right.gif"/>
-              </td>
-            </tr>
-            <tr>
-              <td colspan="3"/>
-            </tr>
-          </table>
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td valign="top" align="left">
-                <font class="defaultfont"><var:entity const:name="copy"/>
-      2000-2004 <a href="http://www.skyrix.com:80/knoppix/skyrix/" target="SKYRIX">SKYRIX Software AG</a>.
-      We welcome your
-      <a href="http://www.opengroupware.org/en/feedback.html" target="feedback">feedback</a>.
-        </font>
-              </td>
-              <td valign="top" align="right">
-                <font class="defaultfont">
-          No sessions required! ;-)
-        </font>
-              </td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-    </table>
-  </body>
-</html>
diff --git a/Misc/ZideStore/UI-X/Common/UIxTabItem.m b/Misc/ZideStore/UI-X/Common/UIxTabItem.m
deleted file mode 100644 (file)
index 21046f9..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "UIxTabView.h"
-#include "common.h"
-
-#if DEBUG
-#  define DEBUG_JS 1
-#endif
-
-/* context keys */
-extern NSString *UIxTabView_HEAD;
-extern NSString *UIxTabView_BODY;
-extern NSString *UIxTabView_KEYS;
-extern NSString *UIxTabView_SCRIPT;
-extern NSString *UIxTabView_ACTIVEKEY;
-extern NSString *UIxTabView_COLLECT;
-
-@implementation UIxTabItem
-
-static Class StrClass = Nil;
-
-+ (int)version {
-  return [super version] + 0;
-}
-+ (void)initialize {
-  StrClass = [NSString class];
-}
-
-static NSString *retStrForInt(int i) {
-  switch(i) {
-  case 0:  return @"0";
-  case 1:  return @"1";
-  case 2:  return @"2";
-  case 3:  return @"3";
-  case 4:  return @"4";
-  case 5:  return @"5";
-  case 6:  return @"6";
-  case 7:  return @"7";
-  case 8:  return @"8";
-  case 9:  return @"9";
-  case 10: return @"10";
-    // TODO: find useful count!
-  default:
-    return [[StrClass alloc] initWithFormat:@"%i", i];
-  }
-}
-
-- (id)initWithName:(NSString *)_name
-  associations:(NSDictionary *)_config
-  template:(WOElement *)_subs
-{
-  if ((self = [super initWithName:_name associations:_config template:_subs])) {
-    self->key      = WOExtGetProperty(_config, @"key");
-    self->label    = WOExtGetProperty(_config, @"label");
-
-    self->isScript = WOExtGetProperty(_config, @"isScript");
-    self->href     = WOExtGetProperty(_config, @"href");
-
-    self->icon     = WOExtGetProperty(_config, @"icon");
-    self->action   = WOExtGetProperty(_config, @"action");
-
-    self->tabStyle         = WOExtGetProperty(_config, @"tabStyle");
-    self->selectedTabStyle = WOExtGetProperty(_config, @"selectedTabStyle");
-
-    self->tabIcon         = WOExtGetProperty(_config, @"tabIcon");
-    self->leftTabIcon     = WOExtGetProperty(_config, @"leftTabIcon");
-    self->selectedTabIcon = WOExtGetProperty(_config, @"selectedTabIcon");
-    
-    self->asBackground    = WOExtGetProperty(_config, @"asBackground");
-    self->width           = WOExtGetProperty(_config, @"width");
-    self->height          = WOExtGetProperty(_config, @"height");
-    self->activeBgColor   = WOExtGetProperty(_config, @"activeBgColor");
-    self->inactiveBgColor = WOExtGetProperty(_config, @"inactiveBgColor");
-    
-    self->template = [_subs retain];
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->key      release];
-  [self->label    release];
-
-  [self->href   release];
-
-  [self->action   release];
-
-  [self->isScript release];
-  [self->template release];
-
-  [self->tabStyle release];
-  [self->selectedTabStyle release];
-
-  [self->icon     release];
-  [self->leftTabIcon     release];
-  [self->selectedTabIcon release];
-  [self->tabIcon         release];
-
-  [self->asBackground release];
-  [self->width        release];
-  [self->height       release];
-
-  [self->activeBgColor   release];
-  [self->inactiveBgColor release];
-  
-  [super dealloc];
-}
-
-/* responder */
-
-- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
-  NSString *activeTabKey;
-  NSString *myTabKey;
-  BOOL     doCheck;
-  
-  if ([_ctx objectForKey:UIxTabView_HEAD]) {
-    /* head clicks */
-    [[_ctx component] debugWithFormat:
-                        @"UIxTabItem: head takes (no) values, eid='%@'",
-                        [_ctx elementID]];
-    return;
-  }
-
-  if ((activeTabKey = [_ctx objectForKey:UIxTabView_BODY]) == nil) {
-    [[_ctx component] debugWithFormat:@"UIxTabItem: invalid state"];
-    [self->template takeValuesFromRequest:_rq inContext:_ctx];
-    return;
-  }
-  
-  myTabKey = [self->key      stringValueInComponent:[_ctx component]];
-  doCheck  = [self->isScript boolValueInComponent:[_ctx component]];
-    
-  if ([activeTabKey isEqualToString:myTabKey] || doCheck) {
-#if ADD_OWN_ELEMENTIDS
-    [_ctx appendElementIDComponent:activeTabKey];
-#endif
-      
-#if DEBUG_TAKEVALUES
-    [[_ctx component] debugWithFormat:
-                          @"UIxTabItem: body takes values, eid='%@'",
-                          [_ctx elementID]];
-#endif
-      
-    [self->template takeValuesFromRequest:_rq inContext:_ctx];
-#if ADD_OWN_ELEMENTIDS
-    [_ctx deleteLastElementIDComponent];
-#endif
-  }
-#if DEBUG_TAKEVALUES
-  else {
-      [[_ctx component] debugWithFormat:
-                          @"UIxTabItem: body takes no values, eid='%@'",
-                          [_ctx elementID]];
-  }
-#endif
-}
-
-- (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
-  id            result;
-  WOAssociation *tmp;
-  NSString      *activeTabKey;
-  
-  if ((tmp = [_ctx objectForKey:UIxTabView_HEAD])) {
-    /* click on tab icon */
-    NSString      *tabkey;
-    
-    tabkey = [_ctx currentElementID];
-    [_ctx consumeElementID];
-    [_ctx appendElementIDComponent:tabkey];
-    
-    if ([tmp isValueSettable])
-      [tmp setValue:tabkey inComponent:[_ctx component]];
-    
-#if 0
-    result = [self->action valueInComponent:[_ctx component]];
-#endif
-
-    [_ctx deleteLastElementIDComponent];
-  }
-  else if ((activeTabKey = [_ctx objectForKey:UIxTabView_BODY])) {
-    /* clicked somewhere in the (active) body */
-    result = [self->template invokeActionForRequest:_req inContext:_ctx];
-  }
-  else {
-    [[_ctx component] logWithFormat:@"UIxTabItem: invalid invoke state"];
-    result = [self->template invokeActionForRequest:_req inContext:_ctx];
-  }
-  
-  return result;
-}
-
-/* info collection */
-
-- (void)_collectInContext:(WOContext *)_ctx key:(NSString *)k {
-  BOOL  isLeft = NO;
-  NSMutableArray *keys;
-  UIxTabItemInfo  *info;
-  WOComponent    *cmp;
-      
-  cmp  = [_ctx component];
-  keys = [_ctx objectForKey:UIxTabView_KEYS];
-  if (keys == nil) {
-    keys = [[[NSMutableArray alloc] init] autorelease];
-    [_ctx setObject:keys forKey:UIxTabView_KEYS];
-    isLeft = YES;
-  }
-      
-  if (k == nil) {
-    /* auto-assign a key */
-    k = retStrForInt([keys count]);
-  }
-  else
-    k = [k retain];
-  [_ctx appendElementIDComponent:k];
-  
-  info = [[UIxTabItemInfo alloc] init];
-  info->key      = [k copy];
-  info->label    = [[self->label stringValueInComponent:cmp] copy];
-  info->icon     = [[self->icon  stringValueInComponent:cmp] copy];
-#if 0
-  info->uri      = [[_ctx componentActionURL] copy];
-#else
-  info->uri      = [[self->href stringValueInComponent:cmp] copy];
-#endif
-  info->isScript = [self->isScript boolValueInComponent:cmp];
-  info->tabIcon  = [[self->tabIcon stringValueInComponent:cmp] copy];
-  info->leftIcon = [[self->leftTabIcon stringValueInComponent:cmp] copy];
-  info->selIcon  = [[self->selectedTabIcon stringValueInComponent:cmp]
-                                           copy];
-  info->tabStyle         = [[self->tabStyle stringValueInComponent:cmp] copy];
-  info->selectedTabStyle = [[self->selectedTabStyle stringValueInComponent:cmp]
-                                                    copy];
-
-  if (self->asBackground == nil)
-    info->asBackground = 0;
-  else {
-    info->asBackground
-      = ([self->asBackground boolValueInComponent:cmp]) ? 1 : -1;
-  }
-  info->width        = [[self->width  stringValueInComponent:cmp] copy];
-  info->height       = [[self->height stringValueInComponent:cmp] copy];
-  info->activeBg     = [[self->activeBgColor stringValueInComponent:cmp]
-                                             copy];
-  info->inactiveBg   = [[self->inactiveBgColor stringValueInComponent:cmp]
-                                               copy];
-      
-  if (info->leftIcon == nil) info->leftIcon = [info->tabIcon copy];
-      
-  [keys addObject:info];
-  [info release];
-  [k release];
-      
-  [_ctx deleteLastElementIDComponent];
-}
-
-/* header generation */
-
-- (void)_appendHeadToResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-  activeKey:(NSString *)activeKey
-  key:(NSString *)k
-{
-  /* head is currently generated in UIxTabView */
-#if 0
-  // note: some associations can be inherited by UIxTabView !
-  BOOL        doImages;
-  WOComponent *comp;
-  BOOL        doBgIcon;
-  NSString    *label;
-  NSString    *w, *h;
-  
-  doImages = ![[[_ctx request] clientCapabilities] isTextModeBrowser];
-  comp     = [_ctx component];
-  
-  doBgIcon = self->asBackground && doImages
-    ? [self->asBackground boolValueInComponent:comp] ? YES : NO
-    : NO;
-  
-  if ((label = [self->label stringValueInComponent:comp]) == nil)
-    label = k;
-
-  if (doImages) {
-    /* lookup image */
-    NSString *imgName = nil;
-    // ...
-    
-    imgUri = WEUriOfResource(imgName, _ctx);
-    if ([imgUri length] < 1)
-      doImages = NO;
-  }
-  
-  // .... _isActive
-#endif
-}
-
-/* body generation */
-
-- (void)_appendBodyToResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-  activeKey:(NSString *)tmp
-  key:(NSString *)k
-{
-  BOOL doScript;
-  BOOL isScript_;
-  BOOL isActive;
-
-  doScript  = [[_ctx objectForKey:UIxTabView_SCRIPT] boolValue];
-  isScript_ = [self->isScript boolValueInComponent:[_ctx component]];
-  isActive  = [tmp isEqualToString:k];
-    
-  if (doScript && (isActive || isScript_)) {
-    [_response appendContentString:@"<div id=\""];
-    [_response appendContentString:k];
-    [_response appendContentString:@"TabLayer\" style=\"display: none;\">\n"];
-  }
-  
-  if (isActive || (doScript && isScript_)) {
-    /* content is active or used as layer*/
-#if ADD_OWN_ELEMENTIDS
-    [_ctx appendElementIDComponent:k];
-#endif
-#if DEBUG && 0
-    NSLog(@"TAB: %@", k);
-#endif
-    
-    [self->template appendToResponse:_response inContext:_ctx];
-    
-#if ADD_OWN_ELEMENTIDS
-    [_ctx deleteLastElementIDComponent];
-#endif
-  }
-    
-  if (doScript && (isActive || isScript_)) {
-    NSString *jsout;
-    [_response appendContentString:@"</div>"];
-
-    jsout = [NSString alloc];
-    jsout = [jsout initWithFormat:
-                   @"<script language=\"JavaScript\">\n<!--\n"
-                   @"%@Tab[\"Div\"] = %@TabLayer;\n",
-                   k, k];
-    
-    [_response appendContentString:jsout];
-    [jsout release];
-    
-#if DEBUG_JS
-    jsout = [NSString alloc];
-    jsout = [jsout initWithFormat:
-                     @"if (%@Tab[\"Div\"].style==null) {"
-                     @"alert('missing style in div for tab %@');}",
-                     k, k];
-    
-    [_response appendContentString:jsout];
-    [jsout release];
-#endif
-    
-    if (isActive) {
-      [_response appendContentString:@"showTab("];
-      [_response appendContentString:k];
-      [_response appendContentString:@"Tab);\n"];
-    }
-    [_response appendContentString:@"//-->\n</script>"];
-  }
-}
-
-/* master generation method */
-
-- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
-  NSString *k;
-  BOOL     doForm;
-  id       tmp;
-  
-  doForm = [_ctx isInForm];
-  k = [self->key stringValueInComponent:[_ctx component]];
-  
-  if ((tmp = [_ctx objectForKey:UIxTabView_HEAD])) {
-    if ([tmp isEqual:UIxTabView_COLLECT]) {
-      [self _collectInContext:_ctx key:k];
-    }
-    else {
-      [self _appendHeadToResponse:_response inContext:_ctx
-            activeKey:tmp key:k];
-    }
-  }
-  else if ((tmp = [_ctx objectForKey:UIxTabView_BODY])) {
-    [self _appendBodyToResponse:_response inContext:_ctx
-          activeKey:tmp key:k];
-  }
-  else {
-    NSLog(@"WARNING(%s): invalid UIxTabItem state !!!", __PRETTY_FUNCTION__);
-    [_response appendContentString:@"[invalid state]"];
-  }
-}
-
-@end /* UIxTabItem */
-
-@implementation UIxTabItemInfo
-
-- (void)dealloc {
-  [self->uri                release];
-  [self->icon               release];
-  [self->label              release];
-  [self->key                release];
-  [self->tabStyle           release];
-  [self->selectedTabStyle   release];
-  [self->tabIcon            release];
-  [self->selIcon            release];
-  [self->leftIcon           release];
-  [self->width              release];
-  [self->height             release];
-  [self->activeBg           release];
-  [self->inactiveBg         release];
-
-  [super dealloc];
-}
-
-/* accessors */
-
-- (NSString *)key {
-  return self->key;
-}
-- (NSString *)label {
-  return self->label;
-}
-- (NSString *)icon {
-  return self->icon;
-}
-- (NSString *)uri {
-  return self->uri;
-}
-- (BOOL)isScript {
-  return self->isScript;
-}
-
-- (int)asBackground {
-  return self->asBackground;
-}
-
-- (NSString *)width {
-  return self->width;
-}
-
-- (NSString *)height {
-  return self->height;
-}
-
-- (NSString *)activeBg {
-  return self->activeBg;
-}
-
-- (NSString *)inactiveBg {
-  return self->inactiveBg;
-}
-
-@end /* UIxTabItemInfo */
diff --git a/Misc/ZideStore/UI-X/Common/UIxTabView.h b/Misc/ZideStore/UI-X/Common/UIxTabView.h
deleted file mode 100644 (file)
index 8224b44..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#ifndef __UIxTabView_H__
-#define __UIxTabView_H__
-
-/*
-  This is a library private header !
-*/
-
-#include <NGObjWeb/WODynamicElement.h>
-
-/*
-  Does not support tab-head-creation from nested components !!!
-
-  hh: Why not ??? -> Because selection is manipulated in sub-elements
-
-  UIxTabView creates element-IDs like
-
-    .h.*.$key.  for the tab-items   (head-mode)
-    .b.$key...  for the tab-content (content-mode) (new, hh)
-
-  !!! UIxTabView JavaScript can't handle duplicate tab-keys !!!
-*/
-
-@interface UIxTabView : WODynamicElement
-{
-  WOAssociation *selection;
-
-  /* config: */
-  WOAssociation *headerStyle;
-  WOAssociation *bodyStyle;
-  WOAssociation *tabStyle;
-  WOAssociation *selectedTabStyle;
-
-  /* old config: */
-  WOAssociation *bgColor;
-  WOAssociation *nonSelectedBgColor;
-  WOAssociation *leftCornerIcon;
-  WOAssociation *rightCornerIcon;
-  
-  WOAssociation *tabIcon;
-  WOAssociation *leftTabIcon;
-  WOAssociation *selectedTabIcon;
-  
-  WOAssociation *asBackground;
-  WOAssociation *width;
-  WOAssociation *height;
-  WOAssociation *activeBgColor;
-  WOAssociation *inactiveBgColor;
-
-  WOAssociation *fontColor;
-  WOAssociation *fontSize;
-  WOAssociation *fontFace;
-
-  id            template;
-}
-
-@end
-
-@interface UIxTabItem : WODynamicElement
-{
-  WOAssociation *key;
-  WOAssociation *label;
-
-  WOAssociation *href;
-  WOAssociation *isScript;
-
-  WOAssociation *action;
-  WOAssociation *icon;
-
-  /* config: */
-  WOAssociation *tabStyle;
-  WOAssociation *selectedTabStyle;
-
-  /* old config */
-  WOAssociation *tabIcon;
-  WOAssociation *leftTabIcon;
-  WOAssociation *selectedTabIcon;
-
-  WOAssociation *asBackground;
-  WOAssociation *width;
-  WOAssociation *height;
-  WOAssociation *activeBgColor;
-  WOAssociation *inactiveBgColor;
-  
-  id            template;
-}
-
-@end
-
-@interface UIxTabItemInfo : NSObject
-{
-@public
-  NSString *label;
-  NSString *icon;
-  NSString *key;
-  NSString *uri;
-  NSString *tabIcon;
-  NSString *leftIcon;
-  NSString *selIcon;
-  NSString *tabStyle;
-  NSString *selectedTabStyle;
-
-  int      asBackground; // 0 -> not set, 1 -> YES, else -> NO
-  NSString *width;
-  NSString *height;
-  NSString *activeBg;
-  NSString *inactiveBg;
-
-  BOOL     isScript;
-}
-@end
-
-#endif /* __UIxTabView_H__ */
diff --git a/Misc/ZideStore/UI-X/Common/UIxTabView.m b/Misc/ZideStore/UI-X/Common/UIxTabView.m
deleted file mode 100644 (file)
index ac635c3..0000000
+++ /dev/null
@@ -1,819 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "UIxTabView.h"
-#include "common.h"
-#import <NGObjWeb/NGObjWeb.h>
-#import <NGExtensions/NGExtensions.h>
-#import <EOControl/EOControl.h>
-#include <WEExtensions/WEClientCapabilities.h>
-
-#if DEBUG
-// #  define DEBUG_TAKEVALUES 1
-#  define DEBUG_JS 1
-#endif
-
-/* context keys */
-NSString *UIxTabView_HEAD      = @"UIxTabView_head";
-NSString *UIxTabView_BODY      = @"UIxTabView_body";
-NSString *UIxTabView_KEYS      = @"UIxTabView_keys";
-NSString *UIxTabView_SCRIPT    = @"UIxTabView_script";
-NSString *UIxTabView_ACTIVEKEY = @"UIxTabView_activekey";
-NSString *UIxTabView_COLLECT   = @"~tv~";
-
-@implementation UIxTabView
-
-static NSNumber *YesNumber;
-
-+ (void)initialize {
-  if (YesNumber == nil)
-    YesNumber = [[NSNumber numberWithBool:YES] retain];
-}
-
-+ (int)version {
-  return [super version] + 0;
-}
-
-- (id)initWithName:(NSString *)_name
-  associations:(NSDictionary *)_config
-  template:(WOElement *)_subs
-{
-  if ((self = [super initWithName:_name associations:_config template:_subs])) {
-    self->selection          = WOExtGetProperty(_config, @"selection");
-    
-    self->headerStyle        = WOExtGetProperty(_config, @"headerStyle");
-    self->bodyStyle          = WOExtGetProperty(_config, @"bodyStyle");
-    self->tabStyle           = WOExtGetProperty(_config, @"tabStyle");
-    self->selectedTabStyle   = WOExtGetProperty(_config, @"selectedTabStyle");
-
-    self->bgColor            = WOExtGetProperty(_config, @"bgColor");
-    self->nonSelectedBgColor = WOExtGetProperty(_config, @"nonSelectedBgColor");
-    self->leftCornerIcon     = WOExtGetProperty(_config, @"leftCornerIcon");
-    self->rightCornerIcon    = WOExtGetProperty(_config, @"rightCornerIcon");
-
-    self->tabIcon            = WOExtGetProperty(_config, @"tabIcon");
-    self->leftTabIcon        = WOExtGetProperty(_config, @"leftTabIcon");
-    self->selectedTabIcon    = WOExtGetProperty(_config, @"selectedTabIcon");
-
-    self->asBackground       = WOExtGetProperty(_config, @"asBackground");
-    self->width              = WOExtGetProperty(_config, @"width");
-    self->height             = WOExtGetProperty(_config, @"height");
-    self->activeBgColor      = WOExtGetProperty(_config, @"activeBgColor");
-    self->inactiveBgColor    = WOExtGetProperty(_config, @"inactiveBgColor");
-
-    self->fontColor          = WOExtGetProperty(_config, @"fontColor");
-    self->fontSize           = WOExtGetProperty(_config, @"fontSize");
-    self->fontFace           = WOExtGetProperty(_config, @"fontFace");
-
-    self->template = RETAIN(_subs);
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->selection release];
-
-  [self->headerStyle release];
-  [self->bodyStyle release];
-  [self->tabStyle release];
-  [self->selectedTabStyle release];
-
-  RELEASE(self->bgColor);
-  RELEASE(self->nonSelectedBgColor);
-  RELEASE(self->leftCornerIcon);
-  RELEASE(self->rightCornerIcon);
-
-  RELEASE(self->leftTabIcon);
-  RELEASE(self->selectedTabIcon);
-  RELEASE(self->tabIcon);
-
-  RELEASE(self->width);
-  RELEASE(self->height);
-
-  RELEASE(self->activeBgColor);
-  RELEASE(self->inactiveBgColor);
-
-  RELEASE(self->fontColor);
-  RELEASE(self->fontSize);
-  RELEASE(self->fontFace);
-  
-  RELEASE(self->template);
-  [super dealloc];
-}
-
-/* nesting */
-
-- (id)saveNestedStateInContext:(WOContext *)_ctx {
-  return nil;
-}
-- (void)restoreNestedState:(id)_state inContext:(WOContext *)_ctx {
-  if (_state == nil) return;
-}
-
-- (NSArray *)collectKeysInContext:(WOContext *)_ctx {
-  /* collect mode, collects all keys */
-  [_ctx setObject:UIxTabView_COLLECT forKey:UIxTabView_HEAD];
-  
-  [self->template appendToResponse:nil inContext:_ctx];
-  
-  [_ctx removeObjectForKey:UIxTabView_HEAD];
-  return [_ctx objectForKey:UIxTabView_KEYS];
-}
-
-/* responder */
-
-- (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
-  id       nestedState;
-  NSString *activeTabKey;
-  
-  activeTabKey = [self->selection stringValueInComponent:[_ctx component]];
-  NSLog(@"%s activeTabKey:%@", __PRETTY_FUNCTION__, activeTabKey);
-  nestedState = [self saveNestedStateInContext:_ctx];
-  [_ctx appendElementIDComponent:@"b"];
-  [_ctx appendElementIDComponent:activeTabKey];
-  
-  [_ctx setObject:activeTabKey forKey:UIxTabView_BODY];
-  
-#if DEBUG_TAKEVALUES
-  [[_ctx component] debugWithFormat:@"UIxTabView: body takes values, eid='%@'",
-                    [_ctx elementID]];
-#endif
-  
-  [self->template takeValuesFromRequest:_req inContext:_ctx];
-  
-  [_ctx removeObjectForKey:UIxTabView_BODY];
-  [_ctx deleteLastElementIDComponent]; // activeKey
-  [_ctx deleteLastElementIDComponent]; /* 'b' */
-  [self restoreNestedState:nestedState inContext:_ctx];
-}
-
-- (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
-  NSString *key;
-  id       result;
-  id       nestedState;
-  
-  if ((key = [_ctx currentElementID]) == nil)
-    return nil;
-  
-  result      = nil;
-  nestedState = [self saveNestedStateInContext:_ctx];
-    
-  if ([key isEqualToString:@"h"]) {
-    /* header action */
-    //NSString *urlKey;
-    
-    [_ctx consumeElementID];
-    [_ctx appendElementIDComponent:@"h"];
-#if 0
-    if ((urlKey = [_ctx currentElementID]) == nil) {
-      [[_ctx application]
-             debugWithFormat:@"missing active head tab key !"];
-    }
-    else {
-      //NSLog(@"clicked: %@", urlKey);
-      [_ctx consumeElementID];
-      [_ctx appendElementIDComponent:urlKey];
-    }
-#endif
-    
-    [_ctx setObject:self->selection forKey:UIxTabView_HEAD];
-    result = [self->template invokeActionForRequest:_req inContext:_ctx];
-    [_ctx removeObjectForKey:UIxTabView_HEAD];
-
-#if 0
-    if (urlKey)
-      [_ctx deleteLastElementIDComponent]; // active key
-#endif
-    [_ctx deleteLastElementIDComponent]; // 'h'
-  }
-  else if ([key isEqualToString:@"b"]) {
-    /* body action */
-    NSString *activeTabKey, *urlKey;
-    
-    [_ctx consumeElementID];
-    [_ctx appendElementIDComponent:@"b"];
-      
-    if ((urlKey = [_ctx currentElementID]) == nil) {
-      [[_ctx application]
-             debugWithFormat:@"missing active body tab key !"];
-    }
-    else {
-      //NSLog(@"clicked: %@", urlKey);
-      [_ctx consumeElementID];
-      [_ctx appendElementIDComponent:urlKey];
-    }
-    
-    activeTabKey = [self->selection stringValueInComponent:[_ctx component]];
-    [_ctx setObject:activeTabKey forKey:UIxTabView_BODY];
-    
-    result = [self->template invokeActionForRequest:_req inContext:_ctx];
-      
-    [_ctx removeObjectForKey:UIxTabView_BODY];
-
-    if (urlKey)
-      [_ctx deleteLastElementIDComponent]; // active key
-    [_ctx deleteLastElementIDComponent]; // 'b'
-  }
-  else {
-    [[_ctx application]
-           debugWithFormat:@"unknown tab container key '%@'", key];
-  }
-    
-  [self restoreNestedState:nestedState inContext:_ctx];
-  return result;
-}
-
-- (NSString *)_tabViewCountInContext:(WOContext *)_ctx {
-  int count;
-  count = [[_ctx valueForKey:@"UIxTabViewScriptDone"] intValue];
-  return [NSString stringWithFormat:@"%d",count];
-}
-
-- (NSString *)scriptHref:(UIxTabItemInfo *)_info
-  inContext:(WOContext *)_ctx
-  isLeft:(BOOL)_isLeft
-  keys:(NSArray *)_keys
-{
-  NSMutableString *result = [NSMutableString string];
-  UIxTabItemInfo *tmp;
-  NSString       *activeKey;
-  int            i, cnt;
-  NSString       *elID;
-  NSString       *tstring;
-  
-  activeKey = [self->selection stringValueInComponent:[_ctx component]];
-  [result appendString:@"JavaScript:showTab("];
-  [result appendString:_info->key];
-  [result appendString:@"Tab);"];
-  
-  [result appendString:@"swapCorners("];
-  tstring = (!_isLeft)
-    ? @"tabCorner%@,tabCornerLeft%@);"
-    : @"tabCornerLeft%@,tabCorner%@);";
-  elID = [self _tabViewCountInContext:_ctx];
-  [result appendString:[NSString stringWithFormat:tstring,elID,elID]];
-  
-  for (i=0, cnt = [_keys count]; i < cnt; i++) {
-    tmp = [_keys objectAtIndex:i];
-
-    if ((tmp->isScript || [tmp->key isEqualToString:activeKey])
-        && ![tmp->key isEqualToString:_info->key]) {
-      [result appendString:@"hideTab("];
-      [result appendString:tmp->key];
-      [result appendString:@"Tab);"];
-    }
-  }
-  return result;
-}
-
-- (void)appendLink:(UIxTabItemInfo *)_info
-  toResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-  isActive:(BOOL)_isActive isLeft:(BOOL)_isLeft
-  doScript:(BOOL)_doScript keys:(NSArray *)_keys
-{
-  NSString    *headUri    = nil;
-  NSString    *label      = nil;
-  NSString    *scriptHref = nil;
-  NSString    *styleName  = nil;
-
-  WEClientCapabilities *ccaps;
-  WOComponent *comp;
-
-  ccaps = [[_ctx request] clientCapabilities];
-
-  comp = [_ctx component];
-  headUri = _info->uri;
-
-  if ((label = _info->label) == nil)
-    label = _info->key;
-  
-  if (_isActive) {
-    styleName = (_info->selectedTabStyle)
-      ? _info->selectedTabStyle
-      : [self->selectedTabStyle stringValueInComponent:comp];
-  }
-  else {
-    styleName = (_info->tabStyle)
-      ? _info->tabStyle
-      : [self->tabStyle stringValueInComponent:comp];
-  }
-  
-  [_response appendContentString:@"<td align='center' valign='middle'"];
-  
-  if (styleName) {
-      [_response appendContentString:@" class='"];
-      [_response appendContentHTMLAttributeValue:styleName];
-      [_response appendContentCharacter:'\''];
-  }
-
-  // click on td background
-  if ([ccaps isInternetExplorer] && [ccaps isJavaScriptBrowser]) {
-      [_response appendContentString:@" onclick=\"window.location.href='"];
-      [_response appendContentHTMLAttributeValue:headUri];
-      [_response appendContentString:@"'\""];
-  }
-  
-  [_response appendContentCharacter:'>'];
-
-  [_response appendContentString:@"<a href=\""];
-  
-  if (_doScript && (_info->isScript || _isActive)) {
-    scriptHref =
-      [self scriptHref:_info inContext:_ctx isLeft:_isLeft keys:_keys];
-    [_response appendContentHTMLAttributeValue:scriptHref];
-  }
-  else {
-    [_response appendContentHTMLAttributeValue:headUri];
-  }
-  
-  [_response appendContentString:@"\" "];
-  [_response appendContentString:
-               [NSString stringWithFormat:@"name='%@TabLink'", _info->key]];
-  [_response appendContentString:@">"];
-  
-  if ([label length] < 1)
-      label = _info->key;
-  [_response appendContentString:@"<nobr>"];
-  [_response appendContentHTMLString:label];
-  [_response appendContentString:@"</nobr>"];
-  
-  [_response appendContentString:@"</a>"];
-
-  [_response appendContentString:@"</td>"];
-
-#if 0
-  if (_doScript && (_info->isScript || _isActive)) {
-    NSString *k; // key 
-    NSString *s; // selected   tab icon
-    NSString *u; // unselected tab icon
-    //NSString *out;
-
-    k = _info->key;
-    s = _info->selIcon; // selectedTabIcon
-    u = (_isLeft) ? _info->leftIcon : _info->tabIcon;
-    
-    s = WEUriOfResource(s, _ctx);
-    u = WEUriOfResource(u, _ctx);
-
-    s = ([s length] < 1) ? imgUri : s;
-    u = ([u length] < 1) ? imgUri : u;
-    
-#if 0
-    out = [NSString alloc];
-    out = [out initWithFormat:
-                    @"<script language=\"JavaScript\">\n"
-                    @"<!--\n"
-                    @"var %@Tab = new Array();\n"
-                    @"%@Tab[\"link\"] = %@TabLink;\n"
-                    @"%@Tab[\"href1\"] = \"%@\";\n"
-                    @"%@Tab[\"href2\"] = \"%@\";\n"
-                    @"%@Tab[\"Img\"] = window.document.%@TabImg;\n"
-                    @"%@Tab[\"Ar\"]  = new Array();\n"
-                    @"%@Tab[\"Ar\"][0] = new Image();\n"
-                    @"%@Tab[\"Ar\"][0].src = \"%@\";\n"
-                    @"%@Tab[\"Ar\"][1] = new Image();\n"
-                    @"%@Tab[\"Ar\"][1].src = \"%@\";\n"
-                    @"//-->\n</script>",
-                    k, k, k, k, scriptHref, k, headUri,
-                    k, k, k, k,
-                    k, u, k, k, s
-                    ];
-    [_response appendContentString:out];
-    RELEASE(out);
-#else
-#  define _appendStr_(_str_) [_response appendContentString:_str_]
-    _appendStr_(@"<script language=\"JavaScript\">\n<!--\nvar ");
-    _appendStr_(k); _appendStr_(@"Tab = new Array();\n");
-
-    _appendStr_(k); _appendStr_(@"Tab[\"link\"] = ");
-    _appendStr_(k); _appendStr_(@"TabLink;\n");   // linkName
-      
-    _appendStr_(k); _appendStr_(@"Tab[\"href1\"] = \"");
-    _appendStr_(scriptHref); _appendStr_(@"\";\n"); // scriptHref
-
-    _appendStr_(k); _appendStr_(@"Tab[\"href2\"] = \"");
-    _appendStr_(_info->uri); _appendStr_(@"\";\n"); // actionHref
-      
-    _appendStr_(k); _appendStr_(@"Tab[\"Img\"] = window.document.");
-    _appendStr_(k); _appendStr_(@"TabImg;\n");
-    _appendStr_(k); _appendStr_(@"Tab[\"Ar\"]  = new Array();\n");
-    _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][0] = new Image();\n");
-    _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][0].src = \"");
-    _appendStr_(u); _appendStr_(@"\";\n");  // unselected img
-    _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][1] = new Image();\n");
-    _appendStr_(k); _appendStr_(@"Tab[\"Ar\"][1].src = \"");
-    _appendStr_(s); _appendStr_(@"\";\n");  // selected img
-    _appendStr_(@"//-->\n</script>");
-#undef _appendStr_
-#endif
-  }
-#endif
-}
-
-- (void)appendSubmitButton:(UIxTabItemInfo *)_info
-  toResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-  isActive:(BOOL)_isActive isLeft:(BOOL)_left
-  doScript:(BOOL)_doScript   keys:(NSArray *)_keys
-{
-  [self appendLink:_info
-        toResponse:_response
-        inContext:_ctx
-        isActive:_isActive isLeft:_left
-        doScript:_doScript   keys:_keys];
-}
-
-- (void)_appendTabViewJSScriptToResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-{
-  [_response appendContentString:
-               @"<script language=\"JavaScript\">\n<!--\n\n"
-               @"function showTab(obj) {\n"
-#if DEBUG_JS
-               @"  if (obj==null) { alert('missing tab obj ..'); return; }\n"
-               @"  if (obj['Div']==null) {"
-               @"    alert('missing div key in ' + obj); return; }\n"
-               @"  if (obj['Div'].style==null) {"
-               @"    alert('missing style key in div ' + obj['Div']);return; }\n"
-#endif
-               @"  obj['Div'].style.display = \"\";\n"
-               @"  obj['Img'].src = obj[\"Ar\"][1].src;\n"
-               @"  obj['link'].href = obj[\"href2\"];\n"
-               @"}\n"
-               @"function hideTab(obj) {\n"
-#if DEBUG_JS
-               @"  if (obj==null) { alert('missing tab obj ..'); return; }\n"
-               @"  if (obj['Div']==null) {"
-               @"    alert('missing div key in ' + obj); return; }\n"
-               @"  if (obj['Div'].style==null) {"
-               @"    alert('missing style key in div ' + obj['Div']);return; }\n"
-#endif
-               @" obj['Div'].style.display = \"none\";\n"
-               @" obj['Img'].src = obj[\"Ar\"][0].src;\n"
-               @" obj['link'].href = obj[\"href1\"];\n"
-               @"}\n"
-               @"function swapCorners(obj1,obj2) {\n"
-               @"   if (obj1==null) { alert('missing corner 1'); return; }\n"
-               @"   if (obj2==null) { alert('missing corner 2'); return; }\n"
-               @"   obj1.style.display = \"none\";\n"
-               @"   obj2.style.display = \"\";\n"
-               @"}\n"
-               @"//-->\n</script>"];
-}
-
-- (void)_appendHeaderRowToResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-  keys:(NSArray *)keys activeKey:(NSString *)activeKey
-  doScript:(BOOL)doScript
-{
-  unsigned  i, count;
-  BOOL      doForm;
-  NSString  *styleName;
-  
-  doForm = NO;  /* generate form controls ? */
-  
-  [_response appendContentString:@"<tr><td colspan='2'>"];
-  
-  styleName = [self->headerStyle stringValueInComponent:[_ctx component]];
-  if(styleName) {
-      [_response appendContentString:
-          @"<table border='0' cellpadding='0' cellspacing='0' class='"];
-      [_response appendContentHTMLAttributeValue:styleName];
-      [_response appendContentString:@"'><tr>"];
-  }
-  else {
-      [_response appendContentString:
-          @"<table border='0' cellpadding='0' cellspacing='0'><tr>"];
-  }
-
-  for (i = 0, count = [keys count]; i < count; i++) {
-    UIxTabItemInfo *info;
-    NSString       *key;
-    BOOL           isActive;
-    
-    info     = [keys objectAtIndex:i];
-    key      = info->key;
-    isActive = [key isEqualToString:activeKey];
-    
-    [_ctx appendElementIDComponent:key];
-    
-    if (doForm) {
-      /* tab is inside of a FORM, so produce submit buttons */
-      [self appendSubmitButton:info
-            toResponse:_response
-            inContext:_ctx
-            isActive:isActive
-            isLeft:(i == 0) ? YES : NO
-            doScript:doScript
-            keys:keys];
-    }
-    else {
-      /* tab is not in a FORM, generate hyperlinks for tab */
-      [self appendLink:info
-            toResponse:_response
-            inContext:_ctx
-            isActive:isActive
-            isLeft:(i == 0) ? YES : NO
-            doScript:doScript
-            keys:keys];
-    }
-    
-    [_ctx deleteLastElementIDComponent];
-  }
-  //  [_response appendContentString:@"<td></td>"];
-  [_response appendContentString:@"</tr></table>"];
-  [_response appendContentString:@"</td></tr>"];
-}
-
-- (void)_appendHeaderFootRowToResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-  bgcolor:(NSString *)bgcolor
-  doScript:(BOOL)doScript
-  isLeftActive:(BOOL)isLeftActive
-{
-  NSString *styleName;
-  [_response appendContentString:@"  <tr"];
-    
-  styleName = [self->bodyStyle stringValueInComponent:[_ctx component]];
-  if(styleName) {
-    [_response appendContentString:@" class='"];
-    [_response appendContentHTMLAttributeValue:styleName];
-    [_response appendContentCharacter:'\''];
-  }
-  if (bgcolor) {
-    [_response appendContentString:@" bgcolor=\""];
-    [_response appendContentHTMLAttributeValue:bgcolor];
-    [_response appendContentString:@"\""];
-  }
-  [_response appendContentString:@">\n"];
-    
-  /* left corner */
-  [_response appendContentString:@"    <td align=\"left\" width=\"10\">"];
-  
-  if (doScript) {
-    [_response appendContentString:@"<div id=\"tabCorner"];
-    [_response appendContentString:[self _tabViewCountInContext:_ctx]];
-    [_response appendContentString:@"\" "];
-    [_response appendContentString:@"style=\"display: "];
-    [_response appendContentString:(isLeftActive) ? @"" : @"none"];
-    [_response appendContentString:@";\">"];
-    [_response appendContentString:@"&nbsp;"];
-    [_response appendContentString:@"</div>"];
-  }
-  else if (isLeftActive)
-    [_response appendContentString:@"&nbsp;"];
-  
-  if (doScript) {
-    [_response appendContentString:@"<div id=\"tabCornerLeft"];
-    [_response appendContentString:[self _tabViewCountInContext:_ctx]];
-    [_response appendContentString:@"\" "];
-    [_response appendContentString:@"style=\"display: "];
-    [_response appendContentString:(!isLeftActive) ? @"visible" : @"none"];
-    [_response appendContentString:@";\">"];
-  }
-  
-  if (!isLeftActive || doScript) {
-    NSString *uri;
-    
-    uri = [self->leftCornerIcon stringValueInComponent:[_ctx component]];
-    if ((uri = WEUriOfResource(uri, _ctx))) {
-      [_response appendContentString:@"<img border=\"0\" alt=\"\" src=\""];
-      [_response appendContentString:uri];
-      [_response appendContentString:@"\">"];
-    }
-    else
-      [_response appendContentString:@"&nbsp;"];
-  }
-  if (doScript)
-    [_response appendContentString:@"</div>"];
-
-  [_response appendContentString:@"</td>\n"];
-
-  /* right corner */
-  [_response appendContentString:@"    <td align=\"right\">"];
-  {
-    NSString *uri;
-      
-    uri = [self->rightCornerIcon stringValueInComponent:[_ctx component]];
-    if ((uri = WEUriOfResource(uri, _ctx))) {
-      [_response appendContentString:@"<img border=\"0\" alt=\"\" src=\""];
-      [_response appendContentString:uri];
-      [_response appendContentString:@"\" />"];
-    }
-    else
-      [_response appendContentString:@"&nbsp;"];
-  }
-  [_response appendContentString:@"</td>\n"];
-    
-  [_response appendContentString:@"  </tr>\n"];
-}
-
-- (void)_appendBodyRowToResponse:(WOResponse *)_response
-  inContext:(WOContext *)_ctx
-  bgcolor:(NSString *)bgcolor
-  activeKey:(NSString *)activeKey
-{
-  WEClientCapabilities *ccaps;
-  BOOL indentContent;
-  NSString *styleName;
-
-  styleName = [self->bodyStyle stringValueInComponent:[_ctx component]];
-  ccaps = [[_ctx request] clientCapabilities];
-
-  /* put additional padding table into content ??? */
-  indentContent = [ccaps isFastTableBrowser] && ![ccaps isTextModeBrowser];
-  
-  [_response appendContentString:@"<tr"];
-  if(styleName) {
-    [_response appendContentString:@" class='"];
-    [_response appendContentHTMLAttributeValue:styleName];
-    [_response appendContentCharacter:'\''];
-  }
-  [_response appendContentString:@"><td colspan='2'"];
-  if (bgcolor) {
-    [_response appendContentString:@" bgcolor=\""];
-    [_response appendContentHTMLAttributeValue:bgcolor];
-    [_response appendContentCharacter:'\"'];
-  }
-  [_response appendContentCharacter:'>'];
-    
-  if (indentContent) {
-    /* start padding table */
-    [_response appendContentString:
-               @"<table border='0' width='100%'"
-               @" cellpadding='10' cellspacing='0'>"];
-    [_response appendContentString:@"<tr><td>"];
-  }
-    
-  [_ctx appendElementIDComponent:@"b"];
-  [_ctx appendElementIDComponent:activeKey];
-  
-  /* generate currently active body */
-  {
-    [_ctx setObject:activeKey forKey:UIxTabView_BODY];
-    [self->template appendToResponse:_response inContext:_ctx];
-    [_ctx removeObjectForKey:UIxTabView_BODY];
-  }
-  
-  [_ctx deleteLastElementIDComponent]; // activeKey
-  [_ctx deleteLastElementIDComponent]; // 'b'
-    
-  if (indentContent)
-    /* close padding table */
-    [_response appendContentString:@"</td></tr></table>"];
-    
-  [_response appendContentString:@"</td></tr>"];
-}
-
-- (BOOL)isLeftActiveInKeys:(NSArray *)keys activeKey:(NSString *)activeKey{
-  unsigned i, count;
-  BOOL isLeftActive;
-  
-  isLeftActive = NO;
-  
-  for (i = 0, count = [keys count]; i < count; i++) {
-    UIxTabItemInfo *info;
-    
-    info = [keys objectAtIndex:i];
-    
-    if ((i == 0) && [info->key isEqualToString:activeKey])
-      isLeftActive = YES;
-  }
-  
-  return isLeftActive;
-}
-
-- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
-  WOComponent  *cmp;
-  NSString     *bgcolor;
-  BOOL         isLeftActive;
-  BOOL         doScript;
-  id           nestedState;
-  NSString     *activeKey;
-  NSArray      *keys;
-  int          tabViewCount; /* used for image id's and writing script once */
-  
-  doScript      = NO;  /* perform tab-clicks on browser (use javascript) */
-  tabViewCount  = [[_ctx valueForKey:@"UIxTabViewScriptDone"] intValue];
-  cmp           = [_ctx component];
-  
-  /* check for browser */
-  {
-    WEClientCapabilities *ccaps;
-    //BOOL isJavaScriptBrowser;
-    
-    ccaps    = [[_ctx request] clientCapabilities];
-    doScript = [ccaps isInternetExplorer] && [ccaps isJavaScriptBrowser]; 
-    doScript = (doScript &&
-                [[[cmp session]
-                       valueForKey:@"isJavaScriptEnabled"] boolValue]);
-  }
-
-  /* disable javascript */
-  doScript = NO;
-  
-  /* save state */
-  
-  nestedState = [self saveNestedStateInContext:_ctx];
-  
-  /* configure */
-  
-  activeKey = [self->selection stringValueInComponent:cmp];
-  
-  bgcolor = [self->bgColor stringValueInComponent:cmp];
-  bgcolor = [bgcolor stringValue];
-  
-  [_ctx appendElementIDComponent:@"h"];
-  
-  /* collect & process keys (= available tabs) */
-  
-  keys = [self collectKeysInContext:_ctx];
-  
-  if (![[keys valueForKey:@"key"] containsObject:activeKey])
-    /* selection is not available in keys */
-    activeKey = nil;
-  
-  if ((activeKey == nil) && ([keys count] > 0)) {
-    /* no or invalid selection, use first key */
-    activeKey = [[keys objectAtIndex:0] key];
-    if ([self->selection isValueSettable])
-      [self->selection setValue:activeKey inComponent:[_ctx component]];
-  }
-
-  if (doScript) {
-    doScript = [[keys valueForKey:@"isScript"] containsObject:YesNumber];
-    [_ctx setObject:[NSNumber numberWithBool:doScript]
-          forKey:UIxTabView_SCRIPT];
-  }
-
-  /* start appending */
-  
-  if ((doScript) && (tabViewCount == 0))
-    [self _appendTabViewJSScriptToResponse:_response inContext:_ctx];
-  
-  /* count up for unique tabCorner/tabCornerLeft images */
-  [_ctx takeValue:[NSNumber numberWithInt:(tabViewCount + 1)]
-        forKey:@"UIxTabViewScriptDone"];
-  
-  [_response appendContentString:
-               @"<table border='0' width='100%'"
-               @" cellpadding='0' cellspacing='0'>"];
-  
-  /* find out whether left is active */
-  
-  isLeftActive = [self isLeftActiveInKeys:keys activeKey:activeKey];
-  
-  /* generate header row */
-  
-  [self _appendHeaderRowToResponse:_response inContext:_ctx
-        keys:keys activeKey:activeKey
-        doScript:doScript];
-  
-  [_ctx deleteLastElementIDComponent]; // 'h' for head
-  [_ctx removeObjectForKey:UIxTabView_HEAD];
-
-#if 0
-  /* header foot row */
-
-  [self _appendHeaderFootRowToResponse:_response inContext:_ctx
-        bgcolor:bgcolor
-        doScript:doScript
-        isLeftActive:isLeftActive];
-#endif
-
-  /* body row */
-  
-  [self _appendBodyRowToResponse:_response inContext:_ctx
-        bgcolor:bgcolor
-        activeKey:activeKey];
-  
-  /* close table */
-  
-  [_response appendContentString:@"</table>"];
-  [_ctx removeObjectForKey:UIxTabView_ACTIVEKEY];
-  [_ctx removeObjectForKey:UIxTabView_KEYS];
-  [self restoreNestedState:nestedState inContext:_ctx];
-}
-
-@end /* UIxTabView */
diff --git a/Misc/ZideStore/UI-X/Common/UIxWinClose.m b/Misc/ZideStore/UI-X/Common/UIxWinClose.m
deleted file mode 100644 (file)
index e8320e6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include <NGObjWeb/NGObjWeb.h>
-
-
-@interface UIxWinClose : WOComponent
-{
-
-}
-
-@end
-
-
-@implementation UIxWinClose
-
-@end
diff --git a/Misc/ZideStore/UI-X/Common/UIxWinClose.wox b/Misc/ZideStore/UI-X/Common/UIxWinClose.wox
deleted file mode 100644 (file)
index 35769e4..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<a xmlns="http://www.w3.org/1999/xhtml"
-   xmlns:var="http://www.skyrix.com/od/binding"
-   xmlns:const="http://www.skyrix.com/od/constant"
-   xmlns:rsrc="OGo:url"
-   href="javascript:history.back()"><img border="0" alt="X" src="/ZideStore/so/ControlPanel/Products/CommonUI/Resources/closewindow.gif"/></a>
diff --git a/Misc/ZideStore/UI-X/Common/Version b/Misc/ZideStore/UI-X/Common/Version
deleted file mode 100644 (file)
index d64ce5a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-SUBMINOR_VERSION:=1
-
-# 1.1.0 requires NGObjWeb 4.2.202
diff --git a/Misc/ZideStore/UI-X/Common/bundle-info.plist b/Misc/ZideStore/UI-X/Common/bundle-info.plist
deleted file mode 100644 (file)
index c7081c1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  "__cvs__" = "$Id: bundle-info.plist,v 1.1 2003/11/24 01:24:40 helge Exp $";
-
-  requires = {
-    bundleManagerVersion = 1;
-    classes = (
-      { name = NSObject;    }
-    );
-  };
-
-  provides = {
-    ZideStoreProducts = ( { name = CommonUIProduct; } );
-    
-    classes = (
-      { name = CommonUIProduct;       },
-      { name = UIxComponent;          },
-      { name = UIxPageFrame;          },
-      { name = UIxWinClose;           },
-      { name = UIxAppNavView;         },
-      { name = "UIxElemBuilder"; },
-      { name = "UIxTabView";          },
-      { name = "UIxTabItem";          },
-    );
-
-    WOComponents = (
-      { name = UIxPageFrame;  },
-      { name = UIxWinClose;   },
-      { name = UIxAppNavView; },
-    );
-    
-    WOxElemBuilder = (
-      { name = "UIxElemBuilder"; },
-    );
-
-    WODynamicElements = (
-      { name = "UIxTabView";          },
-      { name = "UIxTabItem";          },
-    );
-  };
-}
diff --git a/Misc/ZideStore/UI-X/Common/calendar.css b/Misc/ZideStore/UI-X/Common/calendar.css
deleted file mode 100644 (file)
index 34553bb..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-.aptview_title {
-  font-size:        10pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  color:            #000000;
-  font-weight:      bold;
-}
-
-.aptview_text {
-  font-size:        10pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  color:            #000000;
-}
-
-.weekoverview_title {
-  font-size:        10pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  letter-spacing:   0pt;
-  color:            #000000;
-  background-color: #d2d2cc;
-}
-
-.weekoverview_title a {
-  color:            #0033cc;
-  text-decoration: none;
-}
-
-.weekoverview_title_hilite {
-  font-size:        10pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  letter-spacing:   0pt;
-  color:            #000000;
-  background-color: #d2d2cc;
-  font-weight:      bold;
-}
-
-.weekoverview_title_hilite a {
-  color:            #0033cc;
-  text-decoration: none;
-}
-
-.weekoverview_title_daylink {
-  font-size:        12pt;
-  color:            #0033cc;
-  font-weight:      bold;
-}
-
-.weekoverview_title_newlink {
-  font-size:        8pt;
-}
-
-.weekoverview_holidayinfo {
-  font-size:        8pt;
-  font-weight:      bold;
-}
-
-.weekoverview_content {
-  color:            #FFFFFF;
-  background-color: #e8e8e0;
-}
-
-.weekoverview_content a {
-  color:           #0000FF;
-  font-family:     Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  letter-spacing:  0pt;
-  text-decoration: none;
-}
-
-.weekoverview_content_hilite {
-  background-color: #fffff0;
-}
-
-.weekoverview_content_hilite a {
-  color:           #0000FF;
-  font-family:     Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  letter-spacing:  0pt;
-  text-decoration: none;
-}
-
-.monthoverview {
-  color:            #000000;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        10pt;
-  letter-spacing:   0pt;
-  padding:          2px;
-}
-
-.monthoverview a {
-  color:            #0033cc;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        7pt;
-  font-style:       normal;
-  font-weight:      normal;
-  letter-spacing:   0pt;
-  text-decoration:  none;
-}
-
-.monthoverview a:hover {
-  text-decoration:  underline;
-}
-
-.monthoverview_title {
-  background-color: #d2d2cc;
-  text-align:       center;
-}
-
-.monthoverview_week {
-  background-color: #d2d2cc;
-  width:            16pt;
-  text-align:       center;
-  vertical-align:   middle;
-}
-
-.monthoverview_week a {
-  color:            #000000;
-  font-size:        10pt;
-}
-
-.monthoverview_week_hilite {
-  background-color: #fffff0;
-  width:            16pt;
-  text-align:       center;
-  vertical-align:   middle;
-}
-
-.monthoverview_week_hilite a {
-  color:            #000000;
-  font-size:        10pt;
-}
-
-.monthoverview_content {
-  background-color: #e8e8e0;
-  font-size:        9pt;
-  height:           60;
-}
-
-.monthoverview_content a {
-  font-style:       italic;
-  font-weight:      bold;
-}
-
-.monthoverview_content td {
-  text-align:       let;
-  vertical-align:   top;
-}
-
-
-.monthoverview_content_hilite {
-  background-color: #fffff0;
-  font-size:        9pt;
-  height:           60;
-}
-
-.monthoverview_content_hilite a {
-  font-style:       italic;
-  font-weight:      bold;
-}
-
-.monthoverview_content_dimmed {
-  background-color: #d2d2cc;
-  font-size:        9pt;
-  height:           60;
-}
-
-.monthoverview_content_dimmed a {
-  font-style:       normal;
-  font-weight:      normal;
-}
-
-.monthoverview_day a {
-  color:            #000000;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        12pt;
-}
-
-.monthoverview_day_new a {
-  font-style:       normal;
-  font-weight:      normal;
-}
-
-.monthoverview_day_new a:hover {
-  font-style:       normal;
-  font-weight:      normal;
-  color:            #ff0000;
-}
-
-.monthoverview_content_link {
-  font-style:       normal;
-  font-weight:      normal;
-}
diff --git a/Misc/ZideStore/UI-X/Common/common.h b/Misc/ZideStore/UI-X/Common/common.h
deleted file mode 100644 (file)
index ea759a9..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: common.h,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-#import <Foundation/Foundation.h>
-
-#if LIB_FOUNDATION_LIBRARY
-#  include <Foundation/exceptions/GeneralExceptions.h>
-#elif NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
-#  include <NGExtensions/NGObjectMacros.h>
-#  include <NGExtensions/NSString+Ext.h>
-#endif
-
-#include <NGExtensions/NGExtensions.h>
-#include <NGObjWeb/NGObjWeb.h>
-#include <NGObjWeb/SoObjects.h>
-
-@interface WOContext(WOExtensionsPrivate)
-- (void)addActiveFormElement:(WOElement *)_element;
-@end
-
-static inline id WOExtGetProperty(NSDictionary *_set, NSString *_name) {
-    id propValue = [_set objectForKey:_name];
-    
-    if (propValue) {
-        propValue = [propValue retain];
-        [(NSMutableDictionary *)_set removeObjectForKey:_name];
-    }
-    return propValue;
-}
-
-static inline NSString *WEUriOfResource(NSString *_name, WOContext *_ctx) {
-    NSArray           *languages;
-    WOResourceManager *resourceManager;
-    NSString          *uri;
-    
-    if (_name == nil)
-        return nil;
-    
-    languages = [_ctx hasSession]
-        ? [[_ctx session] languages]
-        : [[_ctx request] browserLanguages];
-    
-    resourceManager = [[_ctx application] resourceManager];
-    
-    uri = [resourceManager urlForResourceNamed:_name
-                                   inFramework:nil
-                                     languages:languages
-                                       request:[_ctx request]];
-    if ([uri rangeOfString:@"/missingresource?"].length > 0)
-        uri = nil;
-    
-    return uri;
-}
-
-static inline void WEAppendFont(WOResponse *_resp,
-                                NSString   *_color,
-                                NSString   *_face,
-                                NSString   *_size)
-{
-    [_resp appendContentString:@"<font"];
-    if (_color) {
-        [_resp appendContentString:@" color=\""];
-        [_resp appendContentHTMLAttributeValue:_color];
-        [_resp appendContentCharacter:'"'];
-    }
-    if (_face) {
-        [_resp appendContentString:@" face=\""];
-        [_resp appendContentHTMLAttributeValue:_face];
-        [_resp appendContentCharacter:'"'];
-    }
-    if (_size) {
-        [_resp appendContentString:@" size=\""];
-        [_resp appendContentHTMLAttributeValue:_size];
-        [_resp appendContentCharacter:'"'];
-    }
-    [_resp appendContentCharacter:'>'];
-}
-
-static inline void WEAppendTD(WOResponse *_resp,
-                              NSString   *_align,
-                              NSString   *_valign,
-                              NSString   *_bgColor)
-{
-    [_resp appendContentString:@"<td"];
-    if (_bgColor) {
-        [_resp appendContentString:@" bgcolor=\""];
-        [_resp appendContentHTMLAttributeValue:_bgColor];
-        [_resp appendContentCharacter:'"'];
-    }
-    if (_align) {
-        [_resp appendContentString:@" align=\""];
-        [_resp appendContentHTMLAttributeValue:_align];
-        [_resp appendContentCharacter:'"'];
-    }
-    if (_valign) {
-        [_resp appendContentString:@" valign=\""];
-        [_resp appendContentHTMLAttributeValue:_valign];
-        [_resp appendContentCharacter:'"'];
-    }
-    [_resp appendContentCharacter:'>'];
-}
-
-static inline WOElement *WECreateElement(NSString *_className,
-                                         NSString *_name,
-                                         NSDictionary *_config,
-                                         WOElement *_template)
-{
-    Class               c;
-    WOElement           *result = nil;
-    NSMutableDictionary *config = nil;
-    
-    if ((c = NSClassFromString(_className)) == Nil) {
-        NSLog(@"%s: missing '%@' class", __PRETTY_FUNCTION__, _className);
-        return nil;
-    }
-    config = [NSMutableDictionary dictionaryWithCapacity:4];
-    {
-        NSEnumerator *keyEnum;
-        id           key;
-        
-        keyEnum = [_config keyEnumerator];
-        
-        while ((key = [keyEnum nextObject])) {
-            WOAssociation *a;
-            
-            a = [WOAssociation associationWithValue:[_config objectForKey:key]];
-            [config setObject:a forKey:key];
-        }
-    }
-    result = [[c alloc] initWithName:_name
-                        associations:config
-                            template:_template];
-    return [result autorelease];
-}
-
-#define OWGetProperty WOExtGetProperty
diff --git a/Misc/ZideStore/UI-X/Common/images/OGoLogo.gif b/Misc/ZideStore/UI-X/Common/images/OGoLogo.gif
deleted file mode 100755 (executable)
index ea1b5f5..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/OGoLogo.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_botleft.gif b/Misc/ZideStore/UI-X/Common/images/box_botleft.gif
deleted file mode 100644 (file)
index edaa190..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_botleft.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_botright.gif b/Misc/ZideStore/UI-X/Common/images/box_botright.gif
deleted file mode 100644 (file)
index bb8be1b..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_botright.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_bottom.gif b/Misc/ZideStore/UI-X/Common/images/box_bottom.gif
deleted file mode 100644 (file)
index c63a9cf..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_bottom.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_left.gif b/Misc/ZideStore/UI-X/Common/images/box_left.gif
deleted file mode 100644 (file)
index 260636d..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_left.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_right.gif b/Misc/ZideStore/UI-X/Common/images/box_right.gif
deleted file mode 100644 (file)
index 5315a06..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_right.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_top.gif b/Misc/ZideStore/UI-X/Common/images/box_top.gif
deleted file mode 100644 (file)
index 768bd4f..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_top.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_topleft.gif b/Misc/ZideStore/UI-X/Common/images/box_topleft.gif
deleted file mode 100644 (file)
index 0ede378..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_topleft.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/box_topright.gif b/Misc/ZideStore/UI-X/Common/images/box_topright.gif
deleted file mode 100644 (file)
index 5b3ca17..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/box_topright.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/closewindow.gif b/Misc/ZideStore/UI-X/Common/images/closewindow.gif
deleted file mode 100644 (file)
index f4305d6..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/closewindow.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/corner_right.gif b/Misc/ZideStore/UI-X/Common/images/corner_right.gif
deleted file mode 100644 (file)
index 75b945d..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/corner_right.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/line_left.gif b/Misc/ZideStore/UI-X/Common/images/line_left.gif
deleted file mode 100644 (file)
index 19415f3..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/line_left.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/line_right.gif b/Misc/ZideStore/UI-X/Common/images/line_right.gif
deleted file mode 100644 (file)
index 504b5ce..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/line_right.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/line_stretch.gif b/Misc/ZideStore/UI-X/Common/images/line_stretch.gif
deleted file mode 100644 (file)
index 481e301..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/line_stretch.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/menu_logo_top.gif b/Misc/ZideStore/UI-X/Common/images/menu_logo_top.gif
deleted file mode 100644 (file)
index ea1b5f5..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/menu_logo_top.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/tab_.gif b/Misc/ZideStore/UI-X/Common/images/tab_.gif
deleted file mode 100644 (file)
index ad720a0..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/tab_.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/images/tab_selected.gif b/Misc/ZideStore/UI-X/Common/images/tab_selected.gif
deleted file mode 100644 (file)
index 2cbdea6..0000000
Binary files a/Misc/ZideStore/UI-X/Common/images/tab_selected.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Common/product.plist b/Misc/ZideStore/UI-X/Common/product.plist
deleted file mode 100644 (file)
index 1636c42..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{
-  requires = ( MAIN );
-
-  publicResources = (
-    calendar.css,
-    zidestoreui.css,
-    menu_logo_top.gif,
-    line_left.gif,
-    line_stretch.gif,
-    line_right.gif,
-    box_topleft.gif,
-    box_top.gif,
-    box_topright.gif,
-    box_left.gif,
-    box_right.gif,
-    box_botleft.gif,
-    box_bottom.gif,
-    box_botright.gif,
-    tab_selected.gif,
-    tab_.gif,
-    corner_right.gif,
-    closewindow.gif,
-    OGoLogo.gif
-  );
-  
-  factories = {
-  };
-
-  categories = {
-    SxFolder = {
-      methods = {
-        "app" = { 
-          protectedBy = "View";
-          pageName    = "UIxAppFrame"; 
-        };
-        "appheader" = { 
-          protectedBy = "View";
-          pageName    = "UIxAppHeader"; 
-        };
-        "appnavigation" = { 
-          protectedBy = "View";
-          pageName    = "UIxAppNavigation"; 
-        };
-      };
-    };
-  };
-}
diff --git a/Misc/ZideStore/UI-X/Common/zidestoreui.css b/Misc/ZideStore/UI-X/Common/zidestoreui.css
deleted file mode 100644 (file)
index 5d1e878..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/* ZideStore UI Stylesheet */
-
-/* common stuff */
-
-body {
-  color:            #000000;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        10pt;
-  background-color: #FFFFFF;
-  margin:           0px;
-  margin-top:       0px;
-  margin-bottom:    0px;
-  margin-left:      0px;
-  margin-right:     0px;
-}
-
-a:link {
-  color:       #0033CC;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: none;
-}
-a:visited {
-  color:       #660066;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: none;
-}
-a:hover {
-  color:       #FF0000;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: underline;
-}
-
-.linecolor {
-  background-color: #06348B;
-}
-
-font.defaultfont {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #000000;
-}
-
-.window_label {
-  color:            #06348b;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        12pt;
-  font-weight:      bold;
-}
-
-
-/* tabs */
-
-.tab {
-  color:            #000000;
-  background-color: #e8e8e0;
-  font-size:        10pt;
-  text-decoration:  none;
-  width:            100px; 
-  height:           22px;
-  border-top:       1px solid #06348b;
-  border-right:     1px solid #06348b;
-}
-
-.tab a {
-  color:            #000000;
-  border:           none;
-  text-decoration:  none;
-}
-
-.tab_selected {
-  color:            #000000;
-  background-color: #f5f5e9;
-  font-size:        10pt;
-  text-decoration:  none;
-  font-weight:      bold;
-  width:            100px; 
-  height:           22px;
-  border-top:       1px solid #06348b;
-  border-right:     1px solid #06348b;
-}
-
-.tab_selected a {
-  color:            #000000;
-  border:           none;
-  text-decoration:  none;
-}
-
-.tabview_body {
-  background-color: #f5f5e9;
-}
-
-
-/* buttons */
-
-.button_auto_env {
-  height:           16px;
-  text-align:       center;
-  vertical-align:   middle;
-  padding:          0px 0px 0px 0px;
-  margin:           0px 0px 0px 0px;
-  overflow:         hidden;
-}
-
-.button_auto_env a {
-  text-decoration:  none;
-  color:            #000000;
-}
-
-.button_auto_env a:hover {
-  text-decoration:  underline;
-  color:            #ff0000;
-}
-
-.button_auto {
-  height:           20px;
-  border-style:     outset;
-  border-color:     #DDDDDD;
-  border-width:     2px;
-  color:            #000000;
-  background-color: #e8e8e0;
-  font-size:        8pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  letter-spacing:   0pt;
-  text-decoration:  none;
-  text-color:       #000000;
-  text-align:       center;
-  vertical-align:   middle;
-  padding-left:     5px;
-  padding-right:    5px;
-  padding-top:      1px;
-  padding-bottom:   1px;
-  overflow:         hidden;
-}
-
-
-/* header */
-
-div#header {
-  margin-left:  5px;
-  margin-right: 5px;
-  padding:      0;
-  border-bottom: 1px solid #000000;
-}
-div#header img.headerlogo {
-  float:  right; 
-  width:  182px; 
-  height: 30px;
-}
-
-div#header div#headerhistory {
-  font-size:   11px;
-  color:       #000000;
-  margin:      0px;
-  padding-top: 18px;
-  height:      12px;
-}
-div#header a, div#header span {
-  margin:      0px;
-}
-div#header span#navtitle {
-  font-weight: bold;
-}
-div#header a:hover {
-  text-decoration: none;
-}
-
-/* the dock */
-
-a.skydockfont {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #06348B;
-}
-font.skydockfont {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #06348B;
-}
-font.skydockfont_inactiveMail {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #CCCCCC;
-  font-weight:      bold;
-}
-font.skydockfont_newMail {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #06348B;
-  font-weight:      bold;
-}
-table.skytextdocktable {
-  padding:        0px;
-  table-layout:   auto;
-}
diff --git a/Misc/ZideStore/UI-X/GNUmakefile b/Misc/ZideStore/UI-X/GNUmakefile
deleted file mode 100644 (file)
index 6885564..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# $Id$
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-SUBPROJECTS = \
-       Common          \
-       Scheduler       \
-
-include $(GNUSTEP_MAKEFILES)/aggregate.make
diff --git a/Misc/ZideStore/UI-X/Scheduler/COPYING b/Misc/ZideStore/UI-X/Scheduler/COPYING
deleted file mode 100644 (file)
index 161a3d1..0000000
+++ /dev/null
@@ -1,482 +0,0 @@
-                 GNU LIBRARY GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
-
- Copyright (C) 1991 Free Software Foundation, Inc.
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-                           Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-\f
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-\f
-                 GNU LIBRARY GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License").  Each licensee is
-addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-\f
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
-  6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    c) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    d) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-\f
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-                           NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-                    END OF TERMS AND CONDITIONS
-\f
-     Appendix: How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library 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
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-    MA 02111-1307, USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/Misc/ZideStore/UI-X/Scheduler/COPYRIGHT b/Misc/ZideStore/UI-X/Scheduler/COPYRIGHT
deleted file mode 100644 (file)
index 1053b2a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Copyright (C) 2004 SKYRIX Software AG
-
-
-Contact: info@skyrix.com
diff --git a/Misc/ZideStore/UI-X/Scheduler/GNUmakefile b/Misc/ZideStore/UI-X/Scheduler/GNUmakefile
deleted file mode 100644 (file)
index 40c6391..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-# $Id: GNUmakefile,v 1.4 2004/06/04 16:15:23 znek Exp $
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-BUNDLE_NAME        = SchedulerUI
-BUNDLE_EXTENSION   = .zsp
-BUNDLE_INSTALL_DIR = $(GNUSTEP_USER_ROOT)/Library/ZideStore12
-
-SchedulerUI_PRINCIPAL_CLASS = SchedulerUIProduct
-
-SchedulerUI_OBJC_FILES = \
-       SchedulerUIProduct.m    \
-       UIxAppointmentFormatter.m \
-       UIxCalView.m            \
-       UIxCalWeekView.m        \
-       UIxCalMonthView.m       \
-       UIxAptTableView.m       \
-       \
-       UIxCalWeekOverview.m    \
-       UIxCalMonthOverview.m   \
-       UIxAppointmentView.m    \
-       UIxAppointmentEditor.m  \
-       UIxCalSelectTab.m \
-       UIxCalDateLabel.m \
-       UIxCalBackForthNavView.m \
-
-SchedulerUI_RESOURCE_FILES += \
-       Version                         \
-       product.plist                   \
-       \
-       UIxAptTableView.wox             \
-       UIxCalWeekOverview.wox          \
-       UIxCalMonthOverview.wox         \
-       UIxAppointmentView.wox          \
-       UIxAppointmentEditor.wox                \
-       UIxCalSelectTab.wox \
-       UIxCalDateLabel.wox \
-       UIxCalBackForthNavView.wox \
-       images/next_week.gif            \
-       images/previous_week.gif                                                \
-       images/icon_apt_chart.gif                                               \
-       images/icon_apt_overview.gif                            \
-       images/icon_apt_chart_inactive.gif              \
-       images/icon_apt_overview_inactive.gif \
-       images/icon_apt_column_view.gif                         \
-       images/icon_apt_list.gif                                                        \
-       images/icon_apt_list_inactive.gif                       \
-
-
-ifeq ($(FOUNDATION_LIB),apple)
-ZIDESTORE=$(GNUSTEP_USER_ROOT)/Library/Headers/ZideStore12
-else
-ZIDESTORE=$(GNUSTEP_USER_ROOT)/Headers/ZideStore12
-endif
-
-ADDITIONAL_INCLUDE_DIRS += \
-       -I. \
-       -I.. \
-       -I$(ZIDESTORE)/Frontend -I$(ZIDESTORE)/Backend \
-       -I$(ZIDESTORE) -I$(ZIDESTORE)/Common
-
-# make
-
--include GNUmakefile.preamble
-include $(GNUSTEP_MAKEFILES)/bundle.make
--include GNUmakefile.postamble
diff --git a/Misc/ZideStore/UI-X/Scheduler/GNUmakefile.postamble b/Misc/ZideStore/UI-X/Scheduler/GNUmakefile.postamble
deleted file mode 100644 (file)
index 3986bcc..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# $Id: GNUmakefile.postamble,v 1.1 2004/05/12 14:45:56 helge Exp $
-
-validate-wox:
-       xmllint --noout *.wox
-
-before-all :: validate-wox
-
-
-ifneq ($(GNUSTEP_BUILD_DIR),)
-after-all ::
-       @(cp bundle-info.plist \
-         $(GNUSTEP_BUILD_DIR)/$(BUNDLE_NAME)$(BUNDLE_EXTENSION))
-else
-after-all ::
-       @(cd $(BUNDLE_NAME)$(BUNDLE_EXTENSION);\
-         cp ../bundle-info.plist .)
-endif
diff --git a/Misc/ZideStore/UI-X/Scheduler/GNUmakefile.preamble b/Misc/ZideStore/UI-X/Scheduler/GNUmakefile.preamble
deleted file mode 100644 (file)
index 23c9438..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# $Id$
-
-ifneq ($(GNUSTEP_BUILD_DIR),)
-       RELBUILD_DIR_libZideStoreCommonUI = \
-               $(GNUSTEP_BUILD_DIR)/../Common/$(GNUSTEP_OBJ_DIR_NAME)
-else
-       RELBUILD_DIR_libZideStoreCommonUI = ../Common
-endif
-
-SchedulerUI_LIB_DIRS += -L$(RELBUILD_DIR_libZideStoreCommonUI)
-
-SchedulerUI_BUNDLE_LIBS += \
-       -lNGObjWeb -lNGScripting -lNGJavaScript -ljs \
-       -lNGMime -lNGStreams -lNGExtensions -lEOControl \
-       -lXmlRpc -lDOM -lSaxObjC \
-       -lSOGoLogic -lZideStoreCommonUI \
-       -lNGiCal
diff --git a/Misc/ZideStore/UI-X/Scheduler/NOTES b/Misc/ZideStore/UI-X/Scheduler/NOTES
deleted file mode 100644 (file)
index 35c83b1..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// $Id: NOTES,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-Scheduler
-=========
-
-SOPE based interface for scheduler.
-
-Class Hierarchy
-===============
-
-  [WOComponent]
-    [SoComponent]
-      UIxAppointmentView
-      UIxCalView
-        UIxCalMonthView
-          UIxCalMonthOverview
-        UIxCalWeekView
-          UIxCalWeekOverview
-    UIxAptTableView
-  SchedulerUIProduct
-
-TBD:
-  UIxCalDayView
-    UIxCalDayOverview
-    UIxCalDayChart
-    UIxCalDayHChart
-  [UIxCalWeekView]
-    UIxCalWeekColumnView
-    UIxCalWeekChart
-    UIxCalWeekHChart
-  OGoYearOverview - should use aggressive caching in the long run
-
-  - editor page (which comes up in a new window)
-  - delete page
-  - print views
-
-Notes
-=====
-
-editor pages need to use JavaScript to trigger reloads in the parent window
-=> find out how to do that
-
-URLs
-====
-
-/zidestore/ControlPanel/                       => SoControlPanel
-/zidestore/ControlPanel/Products               => SoProductRegistry
-/zidestore/ControlPanel/Products/ZideStoreUI   => SoProduct
-/zidestore/ControlPanel/Products/ZideStoreUI/Resources/
-=> SoProductResourceManager
-/zidestore/ControlPanel/Products/ZideStoreUI/Resources/calendar.css
-=> resource
diff --git a/Misc/ZideStore/UI-X/Scheduler/SchedulerUIProduct.m b/Misc/ZideStore/UI-X/Scheduler/SchedulerUIProduct.m
deleted file mode 100644 (file)
index 7666ef0..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  Copyright (C) 2000-2003 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: SchedulerUIProduct.m,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-#import <Foundation/NSObject.h>
-
-@interface SchedulerUIProduct : NSObject
-{
-}
-
-@end
-
-#include "common.h"
-
-@implementation SchedulerUIProduct
-@end /* SchedulerUIProduct */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentEditor.m b/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentEditor.m
deleted file mode 100644 (file)
index 5d1ef10..0000000
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include "common.h"
-#include <Common/UIxComponent.h>
-#include <SOGoLogic/SOGoAppointment.h>
-#include <NGiCal/NGiCal.h>
-
-
-/* TODO: CLEAN THIS MESS UP */
-
-
-@interface NSObject (AppointmentHack)
-- (BOOL)isAppointment;
-@end
-
-@implementation NSObject (AppointmentHack)
-- (BOOL)isAppointment {
-  return [self isKindOfClass:NSClassFromString(@"SxAppointment")];
-}
-@end
-
-@interface iCalPerson (Convenience)
-- (NSString *)rfc822Email;
-@end
-
-@implementation iCalPerson (Convenience)
-- (NSString *)rfc822Email {
-    NSString *_email = [self email];
-    NSRange colon = [_email rangeOfString:@":"];
-    if(colon.location != NSNotFound) {
-        return [_email substringFromIndex:colon.location + 1];
-    }
-    return _email;
-}
-@end
-
-@interface UIxAppointmentEditor : UIxComponent
-{
-    id appointment;
-    id participants;
-}
-
-- (SOGoAppointment *)appointment;
-- (NSString *)iCalStringTemplate;
-- (NSString *)iCalString;
-- (BOOL)isNewAppointment;
-
-@end
-
-@implementation UIxAppointmentEditor
-
-- (void)dealloc {
-    [self->appointment release];
-    [self->participants release];
-    [super dealloc];
-}
-
-
-/* accessors */
-
-
-- (NSString *)formattedAptStartTime {
-    NSCalendarDate *date;
-    
-    date = [[self appointment] startDate];
-    /* TODO: convert this into display timeZone! */
-    return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"];
-}
-
-- (BOOL)isNewAppointment {
-    return ! [[self clientObject] isAppointment];
-}
-
-- (NSString *)iCalString {
-    if([self isNewAppointment]) {
-        return [self iCalStringTemplate];
-    }
-    else {
-        return [[self clientObject] valueForKey:@"iCalString"];
-    }
-}
-
-- (NSString *)iCalStringTemplate {
-    static NSString *iCalStringTemplate = \
-    @"BEGIN:VCALENDAR\nMETHOD:REQUEST\nPRODID:OpenGroupware.org ZideStore 1.2\n" \
-    @"VERSION:2.0\nBEGIN:VEVENT\nCLASS:PRIVATE\nSTATUS:CONFIRMED\n" \
-    @"DTSTART:%@\nDTEND:%@\n" \
-    @"TRANSP:OPAQUE\n" \
-    @"END:VEVENT\nEND:VCALENDAR";
-    NSCalendarDate *startDate, *endDate;
-    NSString *template;
-    
-    startDate = [self selectedDate];
-    endDate = [startDate dateByAddingYears:0 months:0 days:0
-                         hours:1 minutes:0 seconds:0];
-    
-    template = [NSString stringWithFormat:iCalStringTemplate,
-                                          [startDate icalString],
-                                          [endDate icalString]];
-    
-    return template;
-}
-
-
-/* backend */
-
-
-- (SOGoAppointment *)appointment {
-    if(self->appointment == nil) {
-        self->appointment = [[SOGoAppointment alloc]
-          initWithICalString:[self iCalString]];
-    }
-    return self->appointment;
-}
-
-- (id)participants {
-    if(self->participants == nil) {
-        NSArray *attendees;
-        NSMutableArray *emailAddresses;
-        unsigned i, count;
-
-        attendees = [self->appointment attendees];
-        count = [attendees count];
-        emailAddresses = [[NSMutableArray alloc] initWithCapacity:count];
-        for(i = 0; i < count; i++) {
-            NSString *email;
-            
-            email = [[attendees objectAtIndex:i] rfc822Email];
-            if(email)
-                [emailAddresses addObject:email];
-        }
-        self->participants = [[emailAddresses componentsJoinedByString:@"\n"]
-            retain];
-        [emailAddresses release];
-    }
-    return self->participants;
-}
-
-
-/* helper */
-
-- (NSString *)uriAsFormat {
-    NSString *uri, *qp;
-    NSRange r;
-
-    uri = [[[self context] request] uri];
-    
-    /* first: identify query parameters */
-    r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
-    if (r.length > 0) {
-        uri = [uri substringToIndex:r.location];
-        qp = [uri substringFromIndex:r.location];
-    }
-    else {
-        qp = nil;
-    }
-    
-    /* next: strip trailing slash */
-    if([uri hasSuffix:@"/"])
-        uri = [uri substringToIndex:([uri length] - 1)];
-    r = [uri rangeOfString:@"/" options:NSBackwardsSearch];
-    
-    /* then: cut of last path component */
-    if(r.location == NSNotFound) { // no slash? are we at root?
-        uri = @"/";
-    }
-    else {
-        uri = [uri substringToIndex:(r.location + 1)];
-    }
-    /* next: append format token */
-    uri = [uri stringByAppendingString:@"%@"];
-    if(qp != nil)
-        uri = [uri stringByAppendingString:qp];
-    return uri;
-}
-
-
-/* save */
-
-
-- (id)saveAction {
-    SOGoAppointment *apt;
-    NSString *iCalString, *summary, *location, *nextMethod, *uri, *uriFormat;
-    NSCalendarDate *sd, *ed;
-    NSArray *ps;
-    unsigned i, count;
-    WOResponse *r;
-    WORequest *req;
-
-    req = [[self context] request];
-
-    /* get iCalString from hidden input */
-    iCalString = [req formValueForKey:@"ical"];
-    apt = [[SOGoAppointment alloc] initWithICalString:iCalString];
-
-    /* merge in form values */
-    sd = [NSCalendarDate dateWithString:[req formValueForKey:@"startDate"]
-                         calendarFormat:@"%Y-%m-%d %H:%M"];
-    [apt setStartDate:sd];
-    ed = [NSCalendarDate dateWithString:[req formValueForKey:@"endDate"]
-                         calendarFormat:@"%Y-%m-%d %H:%M"];
-    [apt setEndDate:ed];
-    summary = [req formValueForKey:@"summary"];
-    [apt setSummary:title];
-    location = [req formValueForKey:@"location"];
-    [apt setLocation:location];
-
-    [apt removeAllAttendees]; /* clean up */
-    ps = [[req formValueForKey:@"participants"]
-        componentsSeparatedByString:@"\n"];
-    count = [ps count];
-    for(i = 0; i < count; i++) {
-        NSString *email;
-        
-        email = [ps objectAtIndex:i];
-        if([email length] > 0) {
-            iCalPerson *p;
-            NSRange cnr;
-
-            p = [[iCalPerson alloc] init];
-            [p setEmail:[NSString stringWithFormat:@"mailto:%@", email]];
-            /* construct a fake CN */
-            cnr = [email rangeOfString:@"@"];
-            if(cnr.location != NSNotFound) {
-                [p setCn:[email substringToIndex:cnr.location]];
-            }
-            [apt addToAttendees:p];
-            [p release];
-        }
-    }
-
-    /* receive current representation for save operation */
-    iCalString = [apt iCalString];
-    [apt release];
-    
-
-    /* determine what's to do and where to go next */
-    if([self isNewAppointment]) {
-        nextMethod = @"duhduh";
-    }
-    else {
-        nextMethod = @"view";
-    }
-
-    NSLog(@"%s new iCalString:\n%@", __PRETTY_FUNCTION__, iCalString);
-
-    uriFormat = [self uriAsFormat];
-    uri = [NSString stringWithFormat:uriFormat, nextMethod];
-
-    r = [WOResponse responseWithRequest:req];
-    [r setStatus:302 /* moved */];
-    [r setHeader:uri forKey:@"location"];
-    return r;
-}
-
-@end
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentEditor.wox b/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentEditor.wox
deleted file mode 100644 (file)
index ce2381a..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name"
->
-
-  <form href="save">
-  <table cellspacing="0" cellpadding="5" width="100%">
-  <tr>
-  <td>
-  <table cellpadding="0" cellspacing="0" width="100%">
-  <tr>
-  <td width="5"/>
-  <td class="window_label">Appointment Editor</td>
-  <td width="36" align="right" valign="center">
-  <var:component className="UIxWinClose" />
-  </td>
-  </tr>
-  </table>
-  </td>
-  </tr>
-
-  <tr>
-    <td>
-        <table border="0" cellpadding="2" width="100%" cellspacing="0" bgcolor="#e8e8e0">
-          <tr>
-            <td align="left" colspan="2">
-              <span class="aptview_title">Appointment on <var:string value="formattedAptStartTime" /></span>
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%">
-                <span class="aptview_text">Start time:</span>
-            </td>
-            <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="startDate" var:value="appointment.startDate" const:dateformat="%Y-%m-%d %H:%M" const:size="40" />
-                </span>
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%">
-                <span class="aptview_text">End time:</span>
-            </td>
-            <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="endDate" var:value="appointment.endDate" const:dateformat="%Y-%m-%d %H:%M" const:size="40" />
-                </span>
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%">
-                <span class="aptview_text">Title:</span>
-            </td>
-            <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="summary" var:value="appointment.summary" const:size="40" />
-                </span>
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%">
-                <span class="aptview_text">Location:</span>
-            </td>
-            <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="location" var:value="appointment.location" const:size="40"/>
-                </span>
-            </td>
-          </tr>
-        </table>
-    </td>
-  </tr>
-
-  <tr>
-    <td>
-        <table border="0" cellpadding="2" width="100%" cellspacing="0" bgcolor="#e8e8e0">
-          <tr>
-            <td align="left" colspan="2">
-              <span class="aptview_title">Search participants</span>
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%">
-                <span class="aptview_text">Participants:</span>
-            </td>
-            <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <textarea name="participants" var:value="participants" cols="40" rows="5" />
-                </span>
-            </td>
-          </tr>
-        </table>
-    </td>
-  </tr>
-
-  <tr>
-    <td>
-        <input type="submit" value="Save" />
-        <input type="hidden" name="ical" var:value="iCalString" />
-    </td>
-  </tr>
-  </table>
-  </form>
-  <!-- -->
-  <hr />
-  clientObject: <var:string value="clientObject" />
-</var:component>
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentFormatter.h b/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentFormatter.h
deleted file mode 100644 (file)
index 4202e77..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#ifndef __UIxAppointmentFormatter_H__
-#define __UIxAppointmentFormatter_H__
-
-#import <Foundation/NSFormatter.h>
-
-/*
-  Formatter to format appointment-dicts to readable strings:
-
-  %[(dateFormat)]S
-             - startDate formatted with the dateFormat string
-             - if no dateFormat is defined, the default formats are used
-             - !!! dont forget the ()brakes !!!
-  %[(dateFormat)]E
-             - endDate formatted with the dateFormat string
-             - if no dateFormat is defined, the default formats are used
-             - !!! dont forget the ()brakes !!!
-
-  %[length]T - title with the specified length
-             - if title has more chars than length overLengthString is appended
-             - if no length is defined, no limit is set
-
-  %[max]P    - participants
-             - if more than max participants at appointment
-               moreParticipantsString is appended
-             - if no max defined no limit is set
-
-  %[length]L - location
-             - if location has more chars than length overLengthString is
-               appended
-             - if no length is defined, no limit is set
-
-  Example:
-  format: @"%S - %E, \n%T";
-
- */
-
-@class NSCalendarDate;
-
-@interface UIxAppointmentFormatter : NSFormatter
-{
-@protected
-  NSString        *formatString;           // default: @"%S - %E, \n%T"
-  
-  NSString        *dateFormat;             // default: @"%H:%M"
-  NSString        *otherDayDateFormat;     // default: @"%H:%M(%m-%d)"
-  NSString        *otherYearDateFormat;    // default: @"%H:%M(%Y-%m-%d)"
-
-  NSString        *toLongString;           // default: @".."
-  NSString        *moreParticipantsString; // default: @"..."
-  NSString        *participantsSeparator;  // default: @", "
-
-  NSCalendarDate  *relationDate;           // if nil, dateFormat used as format
-  // to know whether its the same day, the same year or another year
-
-  BOOL            showFullNames; // try to show full names of participants
-}
-
-//init
-- (id)initWithFormat:(NSString *)_format;
-+ (UIxAppointmentFormatter *)formatterWithFormat:(NSString *)_format;
-+ (UIxAppointmentFormatter *)formatter;
-
-//accessors
-- (void)setFormat:(NSString *)_format;
-- (NSString *)format;
-
-- (void)setDateFormat:(NSString *)_format;
-- (NSString *)dateFormat;
-
-- (void)setOtherDayDateFormat:(NSString *)_format;
-- (NSString *)otherDayDateFormat;
-
-- (void)setOtherYearDateFormat:(NSString *)_format;
-- (NSString *)otherYearDateFormat;
-
-- (void)setToLongString:(NSString *)_toLong;
-- (NSString *)toLongString;
-
-- (void)setMoreParticipantsString:(NSString *)_more;
-- (NSString *)moreParticipantsString;
-
-- (void)setParticipantsSeparator:(NSString *)_sep;
-- (NSString *)participantsSeparator;
-
-- (void)setRelationDate:(NSCalendarDate *)_relation;
-- (NSCalendarDate *)relationDate;
-
-- (void)setShowFullNames:(BOOL)_flag;
-- (BOOL)showFullNames;
-
-// easy switches
-
-// this resets the date format
-- (void)switchToAMPMTimes:(BOOL)_showAMPM;
-
-@end
-
-#endif
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentFormatter.m b/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentFormatter.m
deleted file mode 100644 (file)
index 1380448..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "UIxAppointmentFormatter.h"
-#import <Foundation/Foundation.h>
-#import <NGExtensions/NGExtensions.h>
-#import <EOControl/EOControl.h>
-
-@implementation UIxAppointmentFormatter
-
-- (id)init {
-  if ((self = [super init])) {
-    [self setFormat:@"%S - %E, \n%T"];
-    [self setDateFormat:@"%H:%M"];
-    [self setOtherDayDateFormat:@"%H:%M(%m-%d)"];
-    [self setOtherYearDateFormat:@"%H:%M(%Y-%m-%d)"];
-    [self setToLongString:@".."];
-    [self setMoreParticipantsString:@"..."];
-    [self setParticipantsSeparator:@", "];
-    [self setRelationDate:nil];
-    self->showFullNames = NO;
-  }
-  return self;
-}
-
-- (id)initWithFormat:(NSString *)_format {
-  if ((self = [self init])) {
-    [self setFormat:_format];
-  }
-  return self;
-}
-
-+ (UIxAppointmentFormatter *)formatterWithFormat:(NSString *)_format {
-  return AUTORELEASE([(UIxAppointmentFormatter *)[UIxAppointmentFormatter alloc]
-                                                 initWithFormat:_format]);
-}
-
-+ (UIxAppointmentFormatter *)formatter {
-  return AUTORELEASE([[UIxAppointmentFormatter alloc] init]);
-}
-
-#if !LIB_FOUNDATION_BOEHM_GC
-- (void)dealloc {
-  RELEASE(self->formatString);
-  RELEASE(self->dateFormat);
-  RELEASE(self->otherDayDateFormat);
-  RELEASE(self->otherYearDateFormat);
-  RELEASE(self->toLongString);
-  RELEASE(self->moreParticipantsString);
-  RELEASE(self->participantsSeparator);
-  RELEASE(self->relationDate);
-
-  [super dealloc];
-}
-#endif
-
-// accessors
-
-- (void)setFormat:(NSString *)_format {
-  ASSIGN(self->formatString,_format);
-}
-- (NSString *)format {
-  return self->formatString;
-}
-
-- (void)setDateFormat:(NSString *)_format {
-  ASSIGN(self->dateFormat,_format);
-}
-- (NSString *)dateFormat {
-  return self->dateFormat;
-}
-
-- (void)setOtherDayDateFormat:(NSString *)_format {
-  ASSIGN(self->otherDayDateFormat,_format);
-}
-- (NSString *)otherDayDateFormat {
-  return self->otherDayDateFormat;
-}
-
-- (void)setOtherYearDateFormat:(NSString *)_format {
-  ASSIGN(self->otherYearDateFormat,_format);
-}
-- (NSString *)otherYearDateFormat {
-  return self->otherYearDateFormat;
-}
-
-- (void)setToLongString:(NSString *)_toLong {
-  ASSIGN(self->toLongString,_toLong);
-}
-- (NSString *)toLongString {
-  return self->toLongString;
-}
-
-- (void)setMoreParticipantsString:(NSString *)_more {
-  ASSIGN(self->moreParticipantsString,_more);
-}
-- (NSString *)moreParticipantsString {
-  return self->moreParticipantsString;
-}
-
-- (void)setParticipantsSeparator:(NSString *)_sep {
-  ASSIGN(self->participantsSeparator,_sep);
-}
-- (NSString *)participantsSeparator {
-  return self->participantsSeparator;
-}
-
-- (void)setRelationDate:(NSCalendarDate *)_relation {
-  ASSIGN(self->relationDate,_relation);
-}
-- (NSCalendarDate *)relationDate {
-  return self->relationDate;
-}
-
-- (void)setShowFullNames:(BOOL)_flag {
-  self->showFullNames = _flag;
-}
-- (BOOL)showFullNames {
-  return self->showFullNames;
-}
-
-// easy switching
-- (void)switchToAMPMTimes:(BOOL)_showAMPM {
-  if (_showAMPM) {
-    [self setDateFormat:@"%I:%M %p"];
-    [self setOtherDayDateFormat:@"%I:%M %p(%m-%d)"];
-    [self setOtherYearDateFormat:@"%I:%M %p(%Y-%m-%d)"];
-  }
-  else {
-    [self setDateFormat:@"%H:%M"];
-    [self setOtherDayDateFormat:@"%H:%M(%m-%d)"];
-    [self setOtherYearDateFormat:@"%H:%M(%Y-%m-%d)"];
-  }
-}
-
-// formatting helpers
-
-- (NSString *)formatDate:(NSCalendarDate *)_date
-              withFormat:(NSString *)_format
-{
-  NSString *f;
-  NSCalendarDate *rel;
-
-  rel = self->relationDate;
-  
-  if (_format == nil) {
-    if (rel == nil) {
-      f = self->dateFormat;
-    }
-    else if ([_date isDateOnSameDay:rel]) {
-      f = self->dateFormat;
-    }
-    else if ([_date yearOfCommonEra] == [rel yearOfCommonEra]) {
-      f = self->otherDayDateFormat;
-    }
-    else {
-      f = self->otherYearDateFormat;
-    }
-  }
-  else {
-    f = _format;
-  }
-  return [_date descriptionWithCalendarFormat:f];
-}
-
-- (NSString *)formatStartDateFromApt:(id)_apt
-                          withFormat:(NSString *)_format
-{
-  return [self formatDate:[_apt valueForKey:@"startDate"]
-               withFormat:_format];
-}
-
-- (NSString *)formatEndDateFromApt:(id)_apt
-                        withFormat:(NSString *)_format
-{
-  return [self formatDate:[_apt valueForKey:@"endDate"]
-               withFormat:_format];
-}
-
-- (NSString *)stringForParticipant:(id)_part {
-  id label = nil;
-  
-  if ([[_part valueForKey:@"isTeam"] boolValue]) {
-    if ((label = [_part valueForKey:@"info"]) == nil)
-      label = [_part valueForKey:@"description"];
-  }
-  else if (self->showFullNames) {
-    label = [_part valueForKey:@"firstname"];
-    label = ([label length])
-      ? [label stringByAppendingFormat:@" %@", [_part valueForKey:@"name"]]
-      : [_part valueForKey:@"name"];
-  }
-  else if ([[_part valueForKey:@"isAccount"] boolValue]) {
-    label = [_part valueForKey:@"login"];
-  }
-  else {
-    if ((label = [_part valueForKey:@"name"]) == nil) {
-      if ((label = [_part valueForKey:@"info"]) == nil)
-        label = [_part valueForKey:@"description"];
-    }
-  }
-
-  if (![label isNotNull])
-    label = @"*";
-
-  return label;
-}
-
-- (NSString *)participantsForApt:(id)_apt
-                    withMaxCount:(NSString *)_cnt {
-  NSArray         *p;
-  int             max;
-  int             cnt;
-  NSMutableString *pString;
-
-  pString = [NSMutableString stringWithCapacity:255];
-
-  if (_cnt == nil) {
-    max = -1; // no limit
-  }
-  else {
-    max = [_cnt intValue];
-  }
-
-  p = [_apt valueForKey:@"participants"];
-
-  p = [p sortedArrayUsingKeyOrderArray:
-         [NSArray arrayWithObjects:
-                  [EOSortOrdering sortOrderingWithKey:@"isAccount"
-                                  selector:EOCompareAscending],
-                  [EOSortOrdering sortOrderingWithKey:@"login"
-                                  selector:EOCompareAscending],
-                  nil]];
-
-  max = ((max > [p count]) || (max == -1))
-    ? [p count]
-    : max;
-
-  for (cnt = 0; cnt < max; cnt++) {
-
-    if (cnt != 0)
-      [pString appendString:self->participantsSeparator];
-      
-    [pString appendString:
-             [self stringForParticipant:[p objectAtIndex:cnt]]];
-  }
-
-  if (max < [p count]) {
-    [pString appendString:self->moreParticipantsString];
-  }
-
-  return pString;
-}
-
-- (NSString *)titleForApt:(id)_apt withMaxLength:(NSString *)_length {
-  NSString    *t = nil;
-  int l;
-
-  l = (_length == nil)
-    ? -1
-    : [_length intValue];
-
-  t = [_apt valueForKey:@"title"];
-  if (!t) return @"*";
-
-  if (l > 1) {
-    if ([t length] > l) {
-      t = [t substringToIndex:(l - 2)];
-      t = [t stringByAppendingString:self->toLongString];
-    }
-  }
-  
-  if (l == 0)
-    t = @"*";
-  
-  return t;
-}
-
-- (NSString *)locationForApt:(id)_apt withMaxLength:(NSString *)_length {
-  NSString    *t = nil;
-  int l;
-
-  l = (_length == nil)
-    ? -1
-    : [_length intValue];
-
-  t = [_apt valueForKey:@"location"];
-  if (![t isNotNull] ||
-      [t length] == 0 ||
-      [t isEqualToString:@" "])
-    return @"";
-  
-  if (l > 1) {
-    if ([t length] > l) {
-      t = [t substringToIndex:(l - 2)];
-      t = [t stringByAppendingString:self->toLongString];
-    }
-  }
-  
-  if (l == 0)
-    t = @"";
-  
-  return t;
-}
-
-- (NSString *)resourcesForApt:(id)_apt withMaxLength:(NSString *)_length {
-  NSString    *t = nil;
-  int l;
-
-  l = (_length == nil)
-    ? -1
-    : [_length intValue];
-
-  t = [_apt valueForKey:@"resourceNames"];
-  if (![t isNotNull]  ||
-      [t length] == 0 ||
-      [t isEqualToString:@" "])
-    return @"";
-
-  if (l > 1) {
-    if ([t length] > l) {
-      t = [t substringToIndex:(l - 2)];
-      t = [t stringByAppendingString:self->toLongString];
-    }
-  }
-  
-  if (l == 0)
-    t = @"";
-  
-  return t;
-}
-
-// NSFormatter stuff
-
-- (NSString *)stringForObjectValue:(id)_obj {
-  NSMutableString *newString;
-  int             cnt;
-  int             length;
-  BOOL            replaceMode = NO;
-  NSString        *helper = nil;
-  NSCharacterSet  *digits;
-
-  newString = [NSMutableString stringWithCapacity:255];
-  length    = [self->formatString length];
-  digits    = [NSCharacterSet decimalDigitCharacterSet];
-
-  //  NSLog(@"Formatting with format: %@", self->formatString);
-
-  for (cnt = 0; cnt < length; cnt++) {
-    unichar c;
-    c = [self->formatString characterAtIndex:cnt];
-    //    NSLog(@"Character is: %c mode is: %@", c,
-    //          [NSNumber numberWithBool:replaceMode]);
-    if (replaceMode) {
-      if (c == 'S') {
-        [newString appendString:
-                   [self formatStartDateFromApt:_obj withFormat:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'E') {
-        [newString appendString:
-                   [self formatEndDateFromApt:_obj withFormat:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'P') {
-        [newString appendString:
-                   [self participantsForApt:_obj withMaxCount:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'T') {
-        [newString appendString:
-                   [self titleForApt:_obj withMaxLength:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'L') {
-        NSString *l;
-
-        l = [self locationForApt:_obj withMaxLength:helper];
-
-        if ([l length] > 0)
-          [newString appendString:l];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'R') {
-        NSString *r;
-
-        r = [self resourcesForApt:_obj withMaxLength:helper];
-
-        if ([r length] > 0)
-          [newString appendString:r];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == '(') {
-        int     end;
-        NSRange r = NSMakeRange(cnt,length-cnt);
-        
-        r = [self->formatString rangeOfString:@")"
-                 options:0 range:r];
-        
-        end = r.location - 1;
-        r = NSMakeRange(cnt+1, end-cnt-1);
-        
-        helper = [self->formatString substringWithRange:r];
-        cnt = end + 1;
-      }
-      else if ([digits characterIsMember:c]) {
-        helper = (helper == nil)
-          ? [NSString stringWithFormat:@"%c",c]
-          : [NSString stringWithFormat:@"%@%c", helper, c];
-      }
-      else {
-        NSLog(@"UNKNOWN FORMAT CHARACTER '%c'!!",c);
-        replaceMode = NO;
-        helper = nil;
-      }
-    } else {
-      if (c == '%') {
-        replaceMode = YES;
-      }
-      else {
-        [newString appendFormat:@"%c", c];
-      }
-    }
-  }
-  
-  return newString;
-}
-
-@end
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.h b/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.h
deleted file mode 100644 (file)
index 9038594..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// $Id$
-
-#ifndef __ZideStoreUI_UIxAppointmentView_H__
-#define __ZideStoreUI_UIxAppointmentView_H__
-
-#include <Common/UIxComponent.h>
-
-@interface UIxAppointmentView : UIxComponent
-{
-    NSString *tabSelection;
-    id appointment;
-    id attendee;
-}
-
-- (id)appointment;
-
-- (NSString *)attributesTabLink;
-- (NSString *)participantsTabLink;
-
-- (NSString *)completeHrefForMethod:(NSString *)_method
-              withParameter:(NSString *)_param
-              forKey:(NSString *)_key;
-
-@end
-
-#endif /* __ZideStoreUI_UIxAppointmentView_H__ */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.m b/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.m
deleted file mode 100644 (file)
index b05f908..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// $Id$
-
-#include "UIxAppointmentView.h"
-#include "common.h"
-#include <Backend/SxAptManager.h>
-#include <SOGoLogic/SOGoAppointment.h>
-
-
-@interface NSObject(UsedPrivates)
-- (SxAptManager *)aptManagerInContext:(id)_ctx;
-@end
-
-@implementation UIxAppointmentView
-
-- (void)dealloc {
-  [self->appointment release];
-  [self->attendee release];
-  [super dealloc];
-}
-
-
-/* accessors */
-
-
-- (NSString *)tabSelection {
-    NSString *selection;
-    
-    selection = [self queryParameterForKey:@"tab"];
-    if(! selection)
-        selection = @"attributes";
-    return selection;
-}
-
-- (void)setAttendee:(id)_attendee {
-    ASSIGN(self->attendee, _attendee);
-}
-- (id)attendee {
-    return self->attendee;
-}
-
-
-/* backend */
-
-
-- (SxAptManager *)aptManager {
-  return [[self clientObject] aptManagerInContext:[self context]];
-}
-
-- (SOGoAppointment *)appointment {
-    if(self->appointment == nil) {
-        NSString *iCalString;
-
-        iCalString = [[self clientObject] valueForKey:@"iCalString"];
-        self->appointment = [[SOGoAppointment alloc] initWithICalString:iCalString];
-    }
-    return self->appointment;
-}
-
-- (NSString *)formattedAptStartTime {
-    NSCalendarDate *date;
-    
-    date = [[self appointment] startDate];
-    /* TODO: convert this into display timeZone! */
-    return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"];
-}
-
-- (NSString *)formattedAptEndTime {
-    NSCalendarDate *date;
-    
-    date = [[self appointment] endDate];
-    /* TODO: convert this into display timeZone! */
-    return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"];
-}
-
-
-/* hrefs */
-
-
-- (NSString *)attributesTabLink {
-    return [self completeHrefForMethod:[self ownMethodName]
-                 withParameter:@"attributes"
-                 forKey:@"tab"];
-}
-
-- (NSString *)participantsTabLink {
-    return [self completeHrefForMethod:[self ownMethodName]
-                 withParameter:@"participants"
-                 forKey:@"tab"];
-}
-
-- (NSString *)debugTabLink {
-    return [self completeHrefForMethod:[self ownMethodName]
-                 withParameter:@"debug"
-                 forKey:@"tab"];
-}
-
-- (NSString *)completeHrefForMethod:(NSString *)_method
-              withParameter:(NSString *)_param
-              forKey:(NSString *)_key
-{
-    NSString *href;
-
-    [self setQueryParameter:_param forKey:_key];
-    href = [self completeHrefForMethod:[self ownMethodName]];
-    [self setQueryParameter:nil forKey:_key];
-    return href;
-}
-
-@end /* UIxAppointmentView */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.wox b/Misc/ZideStore/UI-X/Scheduler/UIxAppointmentView.wox
deleted file mode 100644 (file)
index 90dfd7b..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name"
->
-
-  <table cellspacing="0" cellpadding="5" width="100%">
-  <tr>
-  <td>
-  <table cellpadding="0" cellspacing="0" width="100%">
-  <tr>
-  <td width="5"/>
-  <td class="window_label">Appointment Viewer</td>
-  <td width="36" align="right" valign="center">
-  <var:component className="UIxWinClose" />
-  </td>
-  </tr>
-  </table>
-  </td>
-  </tr>
-
-  <tr>
-    <td>
-        <table border="0" cellpadding="2" width="100%" cellspacing="0">
-          <tr bgcolor="#e8e8e0">
-            <td align="left">
-              <span class="aptview_title"><var:string value="formattedAptStartTime" /></span>
-            </td>
-            <td align="right" >
-                <table border='0' cellpadding='0' cellspacing='1'>
-                    <tr>
-                        <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
-                            <a class="button_auto"
-                               href="printview"
-                               var:queryDictionary="queryParameters"
-                               target="SOGoPrintView"
-                            >printview</a>
-                        </td>
-                        <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
-                            <a class="button_auto"
-                               href="edit"
-                               var:queryDictionary="queryParameters"
-                            >edit</a>
-                        </td>
-                        <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
-                            <a class="button_auto"
-                               href="delete"
-                               var:queryDictionary="queryParameters"
-                            >delete</a>
-                        </td>
-                    </tr>
-                </table>
-            </td>
-          </tr>
-        </table>
-    </td>
-  </tr>
-  <tr>
-    <td valign="top" width="100%">
-      <table width="100%" border="0" cellpadding="4" cellspacing="0">
-      <!-- general appointment info -->
-      <tr valign="top">
-        <td align="right" width="15%" bgcolor="#E8E8E0">
-            <span class="aptview_text">Title:</span>
-        </td>
-        <td align="left" bgcolor="#FFFFF0">
-            <span class="aptview_text">
-              <var:string value="appointment.summary" />
-            </span>
-        </td>
-      </tr>
-      <tr valign="top">
-        <td align="right" width="15%" bgcolor="#E8E8E0">
-          <span class="aptview_text">Location:</span>
-        </td>
-        <td align="left" bgcolor="#FFFFF0">
-          <span class="aptview_text">
-            <var:string value="appointment.location" />
-          </span>
-        </td>
-      </tr>
-      </table>
-   </td>
-  </tr>
-  <tr>
-    <td valign="top" width="100%">
-        <uix:tabview var:selection="tabSelection"
-                     const:tabStyle="tab"
-                     const:selectedTabStyle="tab_selected"
-                     const:bodyStyle="tabview_body"
-        >
-          <uix:tab const:key="attributes"
-                   const:label="attributes"
-                   var:href="attributesTabLink">
-              <table width="100%" border="0" cellpadding="4" cellspacing="0">
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                    <span class="aptview_text">Start time:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                    <span class="aptview_text">
-                      <var:string value="formattedAptStartTime" />
-                    </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text">End time:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="formattedAptEndTime" />
-                  </span>
-                </td>
-              </tr>
-              </table>
-          </uix:tab>
-          <uix:tab const:key="participants"
-                   const:label="participants"
-                   var:href="participantsTabLink">
-              <table width="100%" border="0" cellpadding="4" cellspacing="0">
-              <tr valign="top">
-                <td align="left" bgcolor="#E8E8E0">
-                    <span class="aptview_title">Email</span>
-                </td>
-              </tr>
-              <var:foreach list="appointment.attendees" item="attendee">
-              <tr valign="top">
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="attendee.email" />
-                  </span>
-                </td>
-              </tr>
-              </var:foreach>
-              </table>
-          </uix:tab>
-          <uix:tab const:key="debug"
-                   const:label="DEBUG"
-                   var:href="debugTabLink">
-            OGo ZideStore Server - <var:string value="name"/>
-            <br />
-            Client: <var:string value="clientObject"/>
-            <br />
-            Group:      <var:string value="clientObject.group"/><br />
-            Deletable:  <var:string value="clientObject.isDeletionAllowed"/><br />
-            Generation: <var:string value="clientObject.zlGenerationCount"/><br />
-            MsgClass:   <var:string value="clientObject.outlookMessageClass"/><br />
-
-            <hr />
-            As iCal:<br />
-            <pre><var:string value="clientObject.iCalString"/></pre>
-
-            <hr />
-            As Mail:<br />
-            <pre><var:string value="clientObject.iCalMailString"/></pre>
-
-          </uix:tab>
-        </uix:tabview>
-    </td>
-  </tr>
-  </table>
-</var:component>
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAptTableView.m b/Misc/ZideStore/UI-X/Scheduler/UIxAptTableView.m
deleted file mode 100644 (file)
index 420c4df..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-  Copyright (C) 2000-2003 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@class NSArray, NSCalendarDate;
-
-@interface UIxAptTableView : SoComponent
-{
-  NSArray *appointments;
-  id      appointment;
-}
-
-/* accessors */
-
-- (NSArray *)appointments;
-- (id)appointment;
-
-@end
-
-#include "common.h"
-
-@implementation UIxAptTableView
-
-- (void)dealloc {
-  [self->appointment  release];
-  [self->appointments release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (void)setAppointments:(NSArray *)_apts {
-  ASSIGN(self->appointments, _apts);
-}
-- (NSArray *)appointments {
-  return self->appointments;
-}
-
-- (void)setAppointment:(id)_apt {
-  ASSIGN(self->appointment, _apt);
-}
-- (id)appointment {
-  return self->appointment;
-}
-
-- (NSString *)appointmentViewURL {
-  id pkey;
-  
-  if ((pkey = [[self appointment] valueForKey:@"dateId"]) == nil)
-    return nil;
-  
-  return [NSString stringWithFormat:@"%@/view", pkey];
-}
-
-@end /* UIxAptTableView */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxAptTableView.wox b/Misc/ZideStore/UI-X/Scheduler/UIxAptTableView.wox
deleted file mode 100644 (file)
index e270edf..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<table
-  style="font-size: 11px;"
-  border="0" cellspacing="0" cellpadding="2"
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
-  <tr>
-    <th>ID</th>
-    <th>Title</th>
-    <th>Time</th>
-    <th>Version</th>
-    <th>Location</th>
-  </tr>
-  <var:foreach list="appointments" item="appointment">
-    <tr>
-      <td><var:string value="appointment.dateId"/></td>
-      <td>
-        <a var:href="appointmentViewURL"
-          ><var:string value="appointment.title"/></a>
-      </td>
-      <td>
-        <var:string value="appointment.startDate"
-                    const:dateformat="%Y-%m-%d %H:%M" />
-        -
-        <var:string value="appointment.endDate"
-                    const:dateformat="%Y-%m-%d %H:%M" />
-      </td>
-      <td><var:string value="appointment.objectVersion"/></td>
-      <td><var:string value="appointment.location"/></td>
-    </tr>
-  </var:foreach>
-</table>
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalBackForthNavView.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalBackForthNavView.m
deleted file mode 100644 (file)
index 4194246..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include <NGObjWeb/NGObjWeb.h>
-
-/*
-    Associations:
-
-    methodName              -> maps to href
-    prevQueryParameters     -> queryDictionary
-    currentQueryParameters  -> queryDictionary
-    nextQueryParameters     -> queryDictionary
-    label                   -> user presentable name to display for "this"
- */
-
-@interface UIxCalBackForthNavView : WOComponent
-{
-}
-
-@end
-
-
-@implementation UIxCalBackForthNavView
-
-- (BOOL)synchronizesVariablesWithBindings {
-    return NO;
-}
-
-@end
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalDateLabel.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalDateLabel.m
deleted file mode 100644 (file)
index 5e7fa48..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include <NGObjWeb/NGObjWeb.h>
-
-
-@interface UIxCalDateLabel : WOComponent
-{
-    NSString *selection;
-    NSCalendarDate *startDate;
-    NSCalendarDate *endDate;
-}
-
-- (NSString *)dayLabel;
-- (NSString *)weekLabel;
-- (NSString *)monthLabel;
-- (NSString *)yearLabel;
-
-@end
-
-
-@implementation UIxCalDateLabel
-
-- (void)dealloc {
-    [self->selection release];
-    [self->startDate release];
-    [self->endDate release];
-    [super dealloc];
-}
-
-- (void)setSelection:(NSString *)_selection {
-    ASSIGN(self->selection, _selection);
-}
-
-- (NSString *)selection {
-    return self->selection;
-}
-
-- (void)setStartDate:(NSCalendarDate *)_date {
-    ASSIGN(self->startDate, _date);
-}
-
-- (NSCalendarDate *)startDate {
-    return self->startDate;
-}
-
-- (void)setEndDate:(NSCalendarDate *)_date {
-    ASSIGN(self->endDate, _date);
-}
-
-- (NSCalendarDate *)endDate {
-    return self->endDate;
-}
-
-- (NSString *)label {
-    NSString *key = [self selection];
-    if([key isEqualToString:@"day"])
-        return [self dayLabel];
-    else if([key isEqualToString:@"week"])
-        return [self weekLabel];
-    else if([key isEqualToString:@"month"])
-        return [self monthLabel];
-    return [self yearLabel];
-}
-
-- (NSString *)dayLabel {
-    return [self->startDate descriptionWithCalendarFormat:@"%Y-%m-%d"];
-}
-
-- (NSString *)weekLabel {
-    NSString *label;
-    
-    label = [self->startDate descriptionWithCalendarFormat:@"%B %Y"];
-    if([self->startDate monthOfYear] != [self->endDate monthOfYear]) {
-        NSString *ext;
-        
-        ext = [self->endDate descriptionWithCalendarFormat:@"%B %Y"];
-        label = [NSString stringWithFormat:@"<nobr>%@ / %@</nobr>",
-                                            label,
-                                            ext];
-    }
-    return label;
-}
-
-- (NSString *)monthLabel {
-    return [self->startDate descriptionWithCalendarFormat:@"%B %Y"];
-}
-
-- (NSString *)yearLabel {
-    return [self->startDate descriptionWithCalendarFormat:@"%Y"];
-}
-
-@end
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalDateLabel.wox b/Misc/ZideStore/UI-X/Scheduler/UIxCalDateLabel.wox
deleted file mode 100644 (file)
index 4a0c93a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      const:class="window_label"
-><var:string value="label" const:escapeHTML="NO" /></span>
\ No newline at end of file
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthOverview.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthOverview.m
deleted file mode 100644 (file)
index 17526f6..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-// $Id$
-
-#include "UIxCalMonthView.h"
-#include <NGExtensions/NGExtensions.h>
-
-
-@interface UIxCalMonthOverview : UIxCalMonthView
-{
-    int dayIndex;
-    int dayOfWeek;
-    int weekOfYear;
-    NSCalendarDate *currentWeekStart;
-}
-
-@end
-
-#include "common.h"
-
-@implementation UIxCalMonthOverview
-
-- (void)dealloc {
-    [self->currentWeekStart release];
-    [super dealloc];
-}
-
-- (void)setDayIndex:(int)_idx {
-    self->dayIndex = _idx;
-}
-
-- (int)dayIndex {
-    return self->dayIndex;
-}
-
-- (void)setDayOfWeek:(int)_day {
-    self->dayOfWeek = _day;
-}
-
-- (int)dayOfWeek {
-    return self->dayOfWeek;
-}
-
-- (void)setCurrentWeekStartDate:(NSCalendarDate *)_date {
-    ASSIGN(self->currentWeekStart, _date);
-}
-
-- (NSCalendarDate *)currentWeekStartDate {
-    return self->currentWeekStart;
-}
-
-- (void)setWeekOfYear:(int)_week {
-    NSCalendarDate *date;
-    
-    self->weekOfYear = _week;
-    if(_week == 52 || _week == 53)
-        date = [[self startDate] mondayOfWeek];
-    else
-        date = [self startDate];
-    date = [date mondayOfWeek:_week];
-    [self setCurrentWeekStartDate:date];
-}
-
-- (int)weekOfYear {
-    return self->weekOfYear;
-}
-
-- (int)year {
-    return [[self startDate] yearOfCommonEra];
-}
-
-- (int)month {
-    return [[self startDate] monthOfYear];
-}
-
-- (NSString *)localizedNameOfDayOfWeek {
-    // TODO: move this to some locale method
-    static char *dayNames[] = {
-        "Sunday",
-        "Monday",
-        "Tuesday",
-        "Wednesday",
-        "Thursday",
-        "Friday",
-        "Saturday"
-    };
-    return [[[NSString alloc] initWithCString:
-        dayNames[self->dayOfWeek]] autorelease];
-}
-
-- (NSDictionary *)currentWeekQueryParameters {
-    return [self queryParametersBySettingSelectedDate:self->currentWeekStart];
-}
-
-
-/* style sheet */
-
-
-- (NSString *)weekStyle {
-    if([self->currentWeekStart isDateInSameWeek:[NSCalendarDate date]])
-        return @"monthoverview_week_hilite";
-    return @"monthoverview_week";
-}
-
-- (NSString *)contentStyle {
-    if([self->currentDay isToday])
-        return @"monthoverview_content_hilite";
-    else if([self->currentDay monthOfYear] != [[self startDate] monthOfYear])
-        return @"monthoverview_content_dimmed";
-    return @"monthoverview_content";
-}
-
-
-/* appointments */
-
-
-- (NSArray *)appointments {
-  return [self fetchCoreInfos];
-}
-
-@end /* UIxCalMonthOverview */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthOverview.wox b/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthOverview.wox
deleted file mode 100644 (file)
index 402e739..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component className="UIxPageFrame" title="name"
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:rsrc="OGo:url"
->
-
-  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
-  <tr>
-  <td class="wintitle">
-  <table cellpadding="0" cellspacing="0" width="100%">
-  <tr>
-  <td width="5"/>
-  <td class="wintitle"><var:component className="UIxCalDateLabel" startDate="startDate" endDate="endDate" const:selection="month" /></td>
-  <td width="36" align="right" valign="center">
-  <var:component className="UIxWinClose" />
-  </td>
-  </tr>
-  </table>
-  </td>
-  </tr>
-
-  <tr>
-  <td id="skywinbodycell" class="wincontent">
-    <table border="0" cellpadding="0" cellspacing="0" width="100%">
-        <tr bgcolor="#e8e8e0">
-            <td align="left" valign="middle" width="80%">TODO: controls</td><!-- 99% -->
-            <td align="right">
-                <var:component className="UIxCalBackForthNavView"
-                               methodName="ownMethodName"
-                               prevQueryParameters="prevMonthQueryParameters"
-                               currentQueryParameters="todayQueryParameters"
-                               nextQueryParameters="nextMonthQueryParameters"
-                               const:label="this month"
-                />
-            </td>
-        </tr>
-    </table>
-  </td>
-  </tr>
-
-  <tr>
-  <td id="skywinbodycell" class="wincontent">
-  <table border="0" width="100%" cellpadding="0" cellspacing="0">
-  <tr>
-  <td colspan="2">
-  <var:component className="UIxCalSelectTab"
-                 const:selection="month"
-                 currentDate="selectedDate"
-  >
-        <table border="0" cellpadding="4" width="100%" cellspacing="2">
-          <tr>
-            <td align="right" bgcolor="#e8e8e0">
-                <table border='0' cellpadding='0' cellspacing='1'>
-                    <tr>
-                        <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
-                            <a class="button_auto" href="monthprintview" var:queryDictionary="queryParameters" target="SOGoPrintView">printview</a>
-                        </td>
-                        <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
-                            <a class="button_auto" href="proposal" var:queryDictionary="queryParameters">proposal</a>
-                        </td>
-                    </tr>
-                </table>
-            </td>
-          </tr>
-        </table>
-
-    <var:month-overview
-      list="appointments"
-      item="appointment"
-      currentDay="currentDay"
-      index="dayIndex"
-      year="year"
-      month="month"
-      const:startDateKey = "startDate"
-      const:endDateKey   = "endDate"
-
-      const:class="monthoverview"
-      contentStyle="contentStyle"
-      const:width="100%"
-    >
-      <var:month-info>
-        <var:if condition="hasHolidayInfo">
-            <var:string value="holidayInfo" const:class="monthoverview_holidayinfo" />
-        </var:if>
-        <var:foreach list="allDayApts" item="appointment">
-            <a var:href="appointmentViewURL"><var:string value="shortTextForApt" /></a>
-        </var:foreach>
-      </var:month-info>
-    <var:month-label const:orientation="top"
-                     dayOfWeek="dayOfWeek"
-                     const:class="monthoverview_title"
-    >
-        <var:string value="localizedNameOfDayOfWeek" />
-    </var:month-label>
-    <var:month-label const:orientation="left"
-                     weekOfYear="weekOfYear"
-                     class="weekStyle"
-    >
-        <a href="weekoverview"
-           var:queryDictionary="currentWeekQueryParameters"
-        ><var:string value="weekOfYear" /></a>
-    </var:month-label>
-    
-        <var:month-title class="contentStyle">
-            <span class="monthoverview_day">
-                <a href="dayoverview"
-                   var:queryDictionary="currentDayQueryParameters"
-                ><var:string value="currentDay.dayOfMonth" /></a>
-            </span>
-            <br />
-            <span class="monthoverview_day_new">
-                <a href="new"
-                   var:queryDictionary="currentDayQueryParameters"
-                >[new]</a>
-            </span>
-        </var:month-title>
-
-        <var:month>
-            <a var:href="appointmentViewURL"
-               class="monthoverview_content_link"
-               var:title="shortTextForApt"
-               var:queryDictionary="currentDayQueryParameters"
-            ><var:string value="shortTitleForApt" /></a>
-        </var:month>
-    </var:month-overview>
-  </var:component>
-  </td>
-  </tr>
-  <tr bgcolor="#F5F5E9">
-  <td align="left" width="10"><var:entity const:name="nbsp"/></td>
-  <td align="right"><img border="0" alt="" src="/ZideStore/so/ControlPanel/Products/CommonUI/Resources/corner_right.gif"/></td>
-  </tr>
-  <tr>
-  <td colspan="2" bgcolor="#F5F5E9">
-  <table border="0" width="100%" cellpadding="10" cellspacing="0">
-  <tr/>
-  </table>
-  </td>
-  </tr>
-  </table>
-  </td>
-  </tr>
-  </table>
-
-<!--
-    <hr />
-    OGo ZideStore Server - <var:string value="name"/>
-    <br />
-    Client: <var:string value="clientObject"/>
-    <br />
-    Appointments: #<var:string value="appointments.count"/>
-    from <var:string value="startDate" />
-    to   <var:string value="endDate" />
-    <br />
-
-
-    <hr />
-
-    Appointments: 
-    <var:component className="UIxAptTableView" appointments="appointments"/>
-    -->
-    <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
-</var:component>
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthView.h b/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthView.h
deleted file mode 100644 (file)
index 5caf1d4..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-// $Id$
-
-#ifndef __ZideStoreUI_UIxCalMonthView_H__
-#define __ZideStoreUI_UIxCalMonthView_H__
-
-#include "UIxCalView.h"
-
-/*
-  UIxCalMonthView
-  
-  Abstract superclass for views which display months.
-*/
-
-@interface UIxCalMonthView : UIxCalView
-{
-}
-
-- (NSDictionary *)prevMonthQueryParameters;
-- (NSDictionary *)nextMonthQueryParameters;
-
-@end
-
-#endif /* __ZideStoreUI_UIxCalMonthView_H__ */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthView.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalMonthView.m
deleted file mode 100644 (file)
index fa3a216..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// $Id$
-
-#include "UIxCalMonthView.h"
-#include "common.h"
-
-@implementation UIxCalMonthView
-
-- (NSCalendarDate *)startDate {
-  return [[super startDate] firstDayOfMonth];
-}
-
-- (NSCalendarDate *)endDate {
-  NSCalendarDate *startDate = [self startDate];
-  return [startDate dateByAddingYears:0
-                    months:0
-                    days:[startDate numberOfDaysInMonth]
-                    hours:0
-                    minutes:0
-                    seconds:0];
-}
-
-/* URLs */
-
-
-- (NSDictionary *)prevMonthQueryParameters {
-    NSCalendarDate *date;
-
-    date = [[self startDate] dateByAddingYears:0
-                             months:-1
-                             days:0
-                             hours:0
-                             minutes:0
-                             seconds:0];
-    return [self queryParametersBySettingSelectedDate:date];
-}
-
-- (NSDictionary *)nextMonthQueryParameters {
-    NSCalendarDate *date;
-    
-    date = [[self startDate] dateByAddingYears:0
-                             months:1
-                             days:0
-                             hours:0
-                             minutes:0
-                             seconds:0];
-    return [self queryParametersBySettingSelectedDate:date];
-}
-
-@end /* UIxCalMonthView */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalSelectTab.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalSelectTab.m
deleted file mode 100644 (file)
index adacf04..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include <Common/UIxComponent.h>
-#include <NGObjWeb/NGObjWeb.h>
-#include <NGExtensions/NGExtensions.h>
-
-
-@interface UIxCalSelectTab : UIxComponent
-{
-    NSString *selection;
-    NSCalendarDate *currentDate;
-}
-
-@end
-
-
-@implementation UIxCalSelectTab
-
-- (void)dealloc {
-    [self->selection release];
-    [self->currentDate release];
-    [super dealloc];
-}
-
-- (void)setSelection:(NSString *)_selection {
-    ASSIGN(self->selection, _selection);
-}
-
-- (NSString *)selection {
-    return self->selection;
-}
-
-- (void)setCurrentDate:(NSCalendarDate *)_date {
-    ASSIGN(self->currentDate, _date);
-}
-
-- (NSCalendarDate *)currentDate {
-    return self->currentDate;
-}
-
-
-/* labels */
-
-
-- (NSString *)dayLabel {
-    return [self->currentDate descriptionWithCalendarFormat:@"%d"];
-}
-
-- (NSString *)weekLabel {
-    return [NSString stringWithFormat:@"Week %d", [self->currentDate weekOfYear]];
-}
-
-- (NSString *)monthLabel {
-    return [self->currentDate descriptionWithCalendarFormat:@"%B"];
-}
-
-- (NSString *)yearLabel {
-    return [self->currentDate descriptionWithCalendarFormat:@"%Y"];
-}
-
-
-/* hrefs */
-
-
-- (NSString *)daytabLink {
-    return [self completeHrefForMethod:@"dayoverview"];
-}
-
-- (NSString *)weektabLink {
-    return [self completeHrefForMethod:@"weekoverview"];
-}
-
-- (NSString *)monthtabLink {
-    return [self completeHrefForMethod:@"monthoverview"];
-}
-
-- (NSString *)yeartabLink {
-    return [self completeHrefForMethod:@"yearoverview"];
-}
-
-
-@end
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalSelectTab.wox b/Misc/ZideStore/UI-X/Scheduler/UIxCalSelectTab.wox
deleted file mode 100644 (file)
index 98ae502..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<uix:tabview xmlns="http://www.w3.org/1999/xhtml"
-             xmlns:var="http://www.skyrix.com/od/binding"
-             xmlns:const="http://www.skyrix.com/od/constant"
-             xmlns:rsrc="OGo:url"
-             xmlns:uix="OGo:uix"
-             var:selection="selection"
-             const:tabStyle="tab"
-             const:selectedTabStyle="tab_selected"
-             const:bodyStyle="tabview_body"
->
-     <uix:tab const:key="day" var:label="dayLabel" var:href="daytabLink">
-     <var:component-content />
-     </uix:tab>
-     <uix:tab const:key="week" var:label="weekLabel" var:href="weektabLink">
-     <var:component-content />
-     </uix:tab>
-     <uix:tab const:key="month" var:label="monthLabel" var:href="monthtabLink">
-     <var:component-content />
-     </uix:tab>
-     <uix:tab const:key="year" var:label="yearLabel" var:href="yeartabLink">
-     <var:component-content />
-     </uix:tab>
-</uix:tabview>
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalView.h b/Misc/ZideStore/UI-X/Scheduler/UIxCalView.h
deleted file mode 100644 (file)
index c9c10e6..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// $Id$
-
-#ifndef __ZideStoreUI_UIxCalView_H__
-#define __ZideStoreUI_UIxCalView_H__
-
-#include <Common/UIxComponent.h>
-
-@class NSArray, NSCalendarDate;
-@class SxAptManager, SxAptSetIdentifier;
-
-@interface UIxCalView : UIxComponent
-{
-  NSArray *appointments;
-  id      appointment;
-  NSCalendarDate *currentDay;
-}
-
-/* accessors */
-
-- (NSArray *)appointments;
-- (id)appointment;
-
-- (NSDictionary *)aptTypeDict;
-- (NSString *)aptTypeLabel;
-- (NSString *)aptTypeIcon;
-- (NSString *)shortTextForApt;
-- (NSString *)shortTitleForApt;
-
-/* related to current day */
-- (void)setCurrentDay:(NSCalendarDate *)_day;
-- (NSCalendarDate *)currentDay;
-- (NSString *)currentDayName;
-- (NSArray *)allDayApts;
-- (BOOL)hasDayInfo;
-- (BOOL)hasHoldidayInfo;
-
-    
-- (BOOL)showFullNames;
-- (BOOL)showAMPMDates;
-- (NSCalendarDate *)referenceDateForFormatter;
-    
-/* URLs */
-
-- (NSString *)appointmentViewURL;
-
-/* backend */
-
-- (SxAptManager *)aptManager;
-- (SxAptSetIdentifier *)aptSetID;
-
-/* fetching */
-
-- (NSCalendarDate *)startDate;
-- (NSCalendarDate *)endDate;
-- (NSArray *)fetchGIDs;
-- (NSArray *)fetchCoreInfos;
-
-/* date selection */
-- (NSDictionary *)todayQueryParameters;
-- (NSDictionary *)currentDayQueryParameters;
-- (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date;
-- (void)setSelectedDateQueryParameter:(NSCalendarDate *)_newDate
-        inDictionary:(NSMutableDictionary *)_qp;
-
-@end
-
-#endif /* __ZideStoreUI_UIxCalView_H__ */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalView.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalView.m
deleted file mode 100644 (file)
index ebd925f..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-// $Id$
-
-#include "UIxCalView.h"
-#include "common.h"
-#include <Backend/SxAptManager.h>
-#include "UIxAppointmentFormatter.h"
-
-@interface NSObject(UsedPrivates)
-- (SxAptManager *)aptManagerInContext:(id)_ctx;
-@end
-
-@implementation UIxCalView
-
-- (void)dealloc {
-  [self->appointment  release];
-  [self->appointments release];
-  [self->currentDay release];
-  [super dealloc];
-}
-
-/* accessors */
-
-
-- (void)setAppointments:(NSArray *)_apts {
-  ASSIGN(self->appointments, _apts);
-}
-- (NSArray *)appointments {
-  return self->appointments;
-}
-
-- (void)setAppointment:(id)_apt {
-  ASSIGN(self->appointment, _apt);
-}
-- (id)appointment {
-  return self->appointment;
-}
-
-- (NSDictionary *)aptTypeDict {
-    return nil;
-}
-
-- (NSString *)aptTypeLabel {
-    return @"aptLabel";
-}
-
-- (NSString *)aptTypeIcon {
-    return @"";
-}
-
-- (NSString *)shortTextForApt {
-    UIxAppointmentFormatter *f;
-    
-    f = [UIxAppointmentFormatter formatterWithFormat:
-        @"%S - %E;\n%T;\n%L;\n%5P;\n%50R"];
-    [f setRelationDate:[self referenceDateForFormatter]];
-    [f setShowFullNames:[self showFullNames]];
-    if([self showAMPMDates])
-        [f switchToAMPMTimes:YES];
-    
-    return [NSString stringWithFormat:@"%@:\n%@",
-        [self aptTypeLabel],
-        [f stringForObjectValue:self->appointment]];
-}
-
-- (NSString *)shortTitleForApt {
-    NSString *title;
-    
-    title = [self->appointment valueForKey:@"title"];
-    if([title length] > 12) {
-        title = [NSString stringWithFormat:@"%@...",
-            [title substringToIndex:11]];
-    }
-    return title;
-}
-
-- (NSCalendarDate *)referenceDateForFormatter {
-    return [self selectedDate];
-}
-
-/* current day related */
-
-- (void)setCurrentDay:(NSCalendarDate *)_day {
-    ASSIGN(self->currentDay, _day);
-}
-- (NSCalendarDate *)currentDay {
-    return self->currentDay;
-}
-
-- (NSString *)currentDayName {
-    // TODO: this is slow, use locale dictionary to speed this up
-    return [self->currentDay descriptionWithCalendarFormat:@"%A"];
-}
-
-- (BOOL)hasDayInfo {
-    return [self hasHoldidayInfo] || ([[self allDayApts] count] != 0);
-}
-
-- (BOOL)hasHoldidayInfo {
-    return NO;
-}
-
-- (NSArray *)allDayApts {
-    return [NSArray array];
-}
-
-
-/* defaults */
-
-
-- (BOOL)showFullNames {
-    return YES;
-}
-
-- (BOOL)showAMPMDates {
-    return NO;
-}
-
-
-/* URLs */
-
-- (NSString *)appointmentViewURL {
-  id pkey;
-  
-  if ((pkey = [[self appointment] valueForKey:@"dateId"]) == nil)
-    return nil;
-  
-  return [NSString stringWithFormat:@"%@/view", pkey];
-}
-
-
-/* backend */
-
-- (SxAptManager *)aptManager {
-  return [[self clientObject] aptManagerInContext:[self context]];
-}
-- (SxAptSetIdentifier *)aptSetID {
-  return [[self clientObject] aptSetID];
-}
-
-/* resource URLs (TODO?) */
-
-- (NSString *)resourcePath {
-  return @"/ZideStore.woa/WebServerResources/";
-}
-
-- (NSString *)favIconPath {
-  return [[self resourcePath] stringByAppendingPathComponent:@"favicon.ico"];
-}
-- (NSString *)cssPath {
-  NSString *path;
-  
-  // TODO: there should be reusable functionality for that!
-  path = @"ControlPanel/Products/ZideStoreUI/Resources/zidestoreui.css";
-  return [[self context] urlWithRequestHandlerKey:@"so"
-                        path:path
-                        queryString:nil];
-}
-
-- (NSString *)calCSSPath {
-  NSString *path;
-  
-  // TODO: there should be reusable functionality for that!
-  path = @"ControlPanel/Products/ZideStoreUI/Resources/calendar.css";
-  return [[self context] urlWithRequestHandlerKey:@"so"
-                        path:path
-                        queryString:nil];
-}
-
-/* fetching */
-
-- (NSCalendarDate *)startDate {
-  return [self selectedDate];
-}
-- (NSCalendarDate *)endDate {
-  return [[self startDate] tomorrow];
-}
-
-- (NSArray *)fetchGIDs {
-  return [[self aptManager] gidsOfAppointmentSet:[self aptSetID]
-                            from:[self startDate] to:[self endDate]];
-}
-
-- (NSArray *)fetchCoreInfos {
-  NSArray *gids;
-  
-  if (self->appointments)
-    return self->appointments;
-  
-  [self logWithFormat:@"fetching (%@ => %@) ...", 
-         [self startDate], [self endDate]];
-  gids = [self fetchGIDs];
-  [self logWithFormat:@"  %i GIDs ...", [gids count]];
-  
-  self->appointments = 
-    [[[self aptManager] coreInfoOfAppointmentsWithGIDs:gids
-                        inSet:[self aptSetID]] retain];
-  
-  [self logWithFormat:@"fetched %i records.", [self->appointments count]];
-  return self->appointments;
-}
-
-
-/* date selection & conversion */
-
-
-- (NSDictionary *)todayQueryParameters {
-    NSCalendarDate *date;
-    
-    date = [NSCalendarDate date]; /* today */
-    return [self queryParametersBySettingSelectedDate:date];
-}
-
-- (NSDictionary *)currentDayQueryParameters {
-    return [self queryParametersBySettingSelectedDate:self->currentDay];
-}
-
-- (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date {
-    NSMutableDictionary *qp;
-    
-    qp = [[self queryParameters] mutableCopy];
-    [self setSelectedDateQueryParameter:_date inDictionary:qp];
-    return [qp autorelease];
-}
-
-- (void)setSelectedDateQueryParameter:(NSCalendarDate *)_newDate
-        inDictionary:(NSMutableDictionary *)_qp;
-{
-    if(_newDate != nil)
-        [_qp setObject:[self dateStringForDate:_newDate]
-             forKey:@"day"];
-    else
-        [_qp removeObjectForKey:@"day"];
-}
-
-@end /* UIxCalView */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekOverview.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekOverview.m
deleted file mode 100644 (file)
index f2d8caf..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "UIxCalWeekView.h"
-
-@interface UIxCalWeekOverview : UIxCalWeekView
-{
-    int dayIndex;
-}
-
-@end
-
-#include "common.h"
-#include <Backend/SxAptManager.h>
-
-
-@implementation UIxCalWeekOverview
-
-- (NSArray *)appointments {
-  return [self fetchCoreInfos];
-}
-
-- (void)setDayIndex:(char)_idx {
-    NSCalendarDate *d;
-    
-    if ((self->dayIndex == _idx) && (self->currentDay != nil))
-        return;
-    
-    self->dayIndex = _idx;
-    
-    if (_idx > 0) {
-        d = [[self startDate]
-               dateByAddingYears:0 months:0 days:_idx
-                           hours:0 minutes:0 seconds:0];
-    }
-    else
-        d = [self startDate];
-    
-    [self setCurrentDay:d];
-}
-
-- (int)dayIndex {
-    return self->dayIndex;
-}
-
-/* style sheet */
-
-- (NSString *)titleStyle {
-    if([self->currentDay isToday])
-        return @"weekoverview_title_hilite";
-    return @"weekoverview_title";
-}
-
-- (NSString *)contentStyle {
-    if([self->currentDay isToday])
-        return @"weekoverview_content_hilite";
-    return @"weekoverview_content";
-}
-
-@end /* UIxCalWeekOverview */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekOverview.wox b/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekOverview.wox
deleted file mode 100644 (file)
index 7d590c2..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name">
-
-  <!-- $Id: SkyNews.html,v 1.3 2003/12/22 16:53:55 helge Exp $ -->
-  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
-  <tr>
-  <td class="wintitle">
-  <table cellpadding="0" cellspacing="0" width="100%">
-  <tr>
-  <td width="5"/>
-  <td class="wintitle"><var:component className="UIxCalDateLabel" startDate="startDate" endDate="endDate" const:selection="week" /></td>
-  <td width="36" align="right" valign="center">
-  <var:component className="UIxWinClose" />
-  </td>
-  </tr>
-  </table>
-  </td>
-  </tr>
-
-  <tr>
-  <td id="skywinbodycell" class="wincontent">
-    <table border="0" cellpadding="0" cellspacing="0" width="100%">
-    <tr bgcolor="#e8e8e0">
-    <td align="left" valign="middle" width="80%">TODO: controls</td><!-- 99% -->
-    <td align="right">
-    <var:component className="UIxCalBackForthNavView"
-                   methodName="ownMethodName"
-                   prevQueryParameters="prevWeekQueryParameters"
-                   currentQueryParameters="todayQueryParameters"
-                   nextQueryParameters="nextWeekQueryParameters"
-                   const:label="this week"
-    />
-    </td>
-    </tr>
-    </table>
-  </td>
-  </tr>
-
-  <tr>
-  <td id="skywinbodycell" class="wincontent">
-  <table border="0" width="100%" cellpadding="0" cellspacing="0">
-  <tr>
-  <td colspan="2">
-  <var:component className="UIxCalSelectTab" const:selection="week" currentDate="selectedDate">
-
-        <table border="0" cellpadding="4" width="100%" cellspacing="2">
-          <tr>
-            <td width="1%" align="left" valign="middle" bgcolor="#e8e8e0">
-              <table border='0' cellpadding='0' cellspacing='0'>
-               <tr>
-                  <td><img rsrc:src="icon_apt_overview_inactive.gif" title="Overview" alt="Overview" border="0" valign="top" /></td>
-                  <td><a href="weekchartview"><img rsrc:src="icon_apt_chart.gif" title="Chart" alt="Chart" border="0" valign="top" /></a></td>
-                  <td><a href="weeklistview"><img rsrc:src="icon_apt_list.gif" title="List" alt="List" border="0" valign="top" /></a></td>
-                  <td>
-                    <a href="weekcolumnview"><img rsrc:src="icon_apt_column_view.gif" title="Columns" alt="Columns" border="0" valign="top" /></a>
-                  </td>
-               </tr>
-              </table>
-            </td>
-          
-            <td align="right" bgcolor="#e8e8e0">
-                <table border='0' cellpadding='0' cellspacing='1'>
-                    <tr>
-                        <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
-                            <a class="button_auto" href="weekprintview" var:queryDictionary="queryParameters" target="SOGoPrintView">printview</a>
-                        </td>
-                        <td class="button_auto_env" nowrap="true" valign='middle' align='center'>
-                            <a class="button_auto" href="proposal" var:queryDictionary="queryParameters">proposal</a>
-                        </td>
-                    </tr>
-                </table>
-            </td>
-          </tr>
-        </table>
-
-    <var:week-overview list="appointments"
-                       item="appointment"
-                       weekStart="startDate"
-                       dayIndex="dayIndex"
-                       const:startDateKey="startDate"
-                       const:endDateKey="endDate"
-                       const:titleStyle="weekoverview_title"
-                       contentStyle="contentStyle"
-    >
-        <var:week-title>
-            <table cellpadding="0"
-                   width="100%"
-                   border="0"
-                   cellspacing="0"
-                   var:class="titleStyle"
-            >
-                <tr>
-                    <td align="left" valign="top">
-                        <a href="dayoverview"
-                           var:queryDictionary="currentDayQueryParameters"
-                           class="weekoverview_title_daylink"
-                        ><var:string value="currentDay.dayOfMonth" /></a>
-                    </td>
-                    <td align="center" valign="top" width="97%">
-                    <var:string value="currentDayName" /><br />
-                    [<a href="new"
-                        var:queryDictionary="currentDayQueryParameters"
-                        class="weekoverview_title_newlink"
-                     >new</a>]
-                    </td>
-                </tr>
-            </table>
-        </var:week-title>
-        <var:if condition="hasDayInfo">
-            <var:week-info>
-                <var:if condition="hasHolidayInfo">
-                    <var:string value="holidayInfo" const:class="weekoverview_holidayinfo" />
-                </var:if>
-                <var:foreach list="allDayApts" item="appointment">
-                    <a var:href="appointmentViewURL"
-                       var:queryDictionary="currentDayQueryParameters"
-                    ><var:string value="shortTextForApt" /></a>
-                </var:foreach>
-            </var:week-info>
-        </var:if>
-      <var:week>
-          <a var:href="appointmentViewURL"><var:string value="appointment.title"/></a>
-      </var:week>
-  </var:week-overview>
-  </var:component>
-  </td>
-  </tr>
-  <tr bgcolor="#F5F5E9">
-  <td align="left" width="10"><var:entity const:name="nbsp"/></td>
-  <td align="right"><img border="0" alt="" src="/ZideStore/so/ControlPanel/Products/CommonUI/Resources/corner_right.gif"/></td>
-  </tr>
-  <tr>
-  <td colspan="2" bgcolor="#F5F5E9">
-  <table border="0" width="100%" cellpadding="10" cellspacing="0">
-  <tr/>
-  </table>
-  </td>
-  </tr>
-  </table>
-  </td>
-  </tr>
-  </table>
-  <!--
-  <hr />
-  <var:string value="thisWeekQueryParameters" />
-  -->
-  <!--
-  <hr/>
-    
-    Appointments: 
-    <var:component className="UIxAptTableView" appointments="appointments"/>
-  -->
-    <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
-
-</var:component>
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekView.h b/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekView.h
deleted file mode 100644 (file)
index f32b434..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// $Id$
-
-#ifndef __ZideStoreUI_UIxCalWeekView_H__
-#define __ZideStoreUI_UIxCalWeekView_H__
-
-#include "UIxCalView.h"
-
-@interface UIxCalWeekView : UIxCalView
-{
-}
-
-/* Query Parameters */
-
-- (NSDictionary *)prevWeekQueryParameters;
-- (NSDictionary *)nextWeekQueryParameters;
-    
-@end
-
-#endif /* __ZideStoreUI_UIxCalWeekView_H__ */
diff --git a/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekView.m b/Misc/ZideStore/UI-X/Scheduler/UIxCalWeekView.m
deleted file mode 100644 (file)
index 5df1d2d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// $Id$
-
-#include "UIxCalWeekView.h"
-#include "common.h"
-
-@implementation UIxCalWeekView
-
-- (NSCalendarDate *)startDate {
-  return [[super startDate] mondayOfWeek];
-}
-
-- (NSCalendarDate *)endDate {
-  return [[self startDate] dateByAddingYears:0 months:0 days:7
-                          hours:0 minutes:0 seconds:0];
-}
-
-/* URLs */
-
-- (NSDictionary *)prevWeekQueryParameters {
-    NSCalendarDate *date;
-
-    date = [[self startDate] dateByAddingYears:0 months:0 days:-7 
-                             hours:0 minutes:0 seconds:0];
-    return [self queryParametersBySettingSelectedDate:date];
-}
-
-- (NSDictionary *)nextWeekQueryParameters {
-    NSCalendarDate *date;
-    
-    date = [[self startDate] dateByAddingYears:0 months:0 days:7 
-                             hours:0 minutes:0 seconds:0];
-    return [self queryParametersBySettingSelectedDate:date];
-}
-
-@end /* UIxCalWeekView */
diff --git a/Misc/ZideStore/UI-X/Scheduler/Version b/Misc/ZideStore/UI-X/Scheduler/Version
deleted file mode 100644 (file)
index d64ce5a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-SUBMINOR_VERSION:=1
-
-# 1.1.0 requires NGObjWeb 4.2.202
diff --git a/Misc/ZideStore/UI-X/Scheduler/bundle-info.plist b/Misc/ZideStore/UI-X/Scheduler/bundle-info.plist
deleted file mode 100644 (file)
index 44a5c52..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "__cvs__" = "$Id: bundle-info.plist,v 1.1 2003/11/24 01:24:40 helge Exp $";
-
-  requires = {
-    bundleManagerVersion = 1;
-    classes = (
-      { name = NSObject;    }
-    );
-  };
-
-  provides = {
-    ZideStoreProducts = ( { name = SchedulerUIProduct; } );
-    
-    classes = (
-    );
-
-    WOComponents = (
-    );
-  };
-}
diff --git a/Misc/ZideStore/UI-X/Scheduler/common.h b/Misc/ZideStore/UI-X/Scheduler/common.h
deleted file mode 100644 (file)
index 093af0b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: common.h,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-#import <Foundation/Foundation.h>
-
-#if LIB_FOUNDATION_LIBRARY
-#  include <Foundation/exceptions/GeneralExceptions.h>
-#elif NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
-#  include <NGExtensions/NGObjectMacros.h>
-#  include <NGExtensions/NSString+Ext.h>
-#endif
-
-#include <NGExtensions/NGExtensions.h>
-#include <NGObjWeb/NGObjWeb.h>
-#include <NGObjWeb/SoObjects.h>
diff --git a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart.gif b/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart.gif
deleted file mode 100644 (file)
index ba0f740..0000000
Binary files a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart_inactive.gif b/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart_inactive.gif
deleted file mode 100644 (file)
index 240f1e8..0000000
Binary files a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_chart_inactive.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_column_view.gif b/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_column_view.gif
deleted file mode 100644 (file)
index 4af2fa1..0000000
Binary files a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_column_view.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list.gif b/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list.gif
deleted file mode 100644 (file)
index 857db76..0000000
Binary files a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list_inactive.gif b/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list_inactive.gif
deleted file mode 100644 (file)
index 4e8debf..0000000
Binary files a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_list_inactive.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview.gif b/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview.gif
deleted file mode 100644 (file)
index 43ac796..0000000
Binary files a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview_inactive.gif b/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview_inactive.gif
deleted file mode 100644 (file)
index 7736f48..0000000
Binary files a/Misc/ZideStore/UI-X/Scheduler/images/icon_apt_overview_inactive.gif and /dev/null differ
diff --git a/Misc/ZideStore/UI-X/Scheduler/product.plist b/Misc/ZideStore/UI-X/Scheduler/product.plist
deleted file mode 100644 (file)
index 680bd69..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-{
-  requires = ( MAIN, CommonUI );
-
-  publicResources = (
-    previous_week.gif,
-    next_week.gif,
-    icon_apt_chart.gif,
-    icon_apt_overview.gif,
-    icon_apt_chart_inactive.gif,
-    icon_apt_overview_inactive.gif,
-    icon_apt_column_view.gif,
-    icon_apt_list.gif,
-    icon_apt_list_inactive.gif
-  );
-
-  factories = {
-  };
-
-  categories = {
-    SxAppointmentFolder = {
-      methods = {
-        "weekoverview" = { 
-          protectedBy = "View";
-          pageName    = "UIxCalWeekOverview"; 
-        };
-        "weekchartview" = { 
-          protectedBy = "View";
-          pageName    = "UIxCalWeekOverview"; 
-        };
-        "weeklistview" = { 
-          protectedBy = "View";
-          pageName    = "UIxCalWeekOverview"; 
-        };
-        "weekcolumnview" = { 
-          protectedBy = "View";
-          pageName    = "UIxCalWeekOverview"; 
-        };
-        "weekprintview" = { 
-          protectedBy = "View";
-          pageName    = "UIxCalWeekOverview"; 
-        };
-        "monthoverview" = { 
-          protectedBy = "View";
-          pageName    = "UIxCalMonthOverview"; 
-        };
-        "new" = { 
-          protectedBy = "View";
-          pageName    = "UIxAppointmentEditor"; 
-        };
-      };
-    };
-
-    SxAppointment = {
-      methods = {
-        "view" = { 
-          protectedBy = "View";
-          pageName    = "UIxAppointmentView"; 
-        };
-        "edit" = { 
-          protectedBy = "View";
-          pageName    = "UIxAppointmentEditor"; 
-        };
-        "save" = { 
-          protectedBy = "View";
-          pageName    = "UIxAppointmentEditor"; 
-          actionName  = "save";
-        };
-      };
-    };
-  };
-}
diff --git a/Misc/db/scripts/create_user_tables.py b/Misc/db/scripts/create_user_tables.py
deleted file mode 100755 (executable)
index 52911fb..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/usr/bin/env python
-
-"""
-README!!!
-
-Check the table names in
-CREATE_QUICK + CREATE_BLOB -> are the table names correct?
-"""
-
-import pg
-import sys
-import random
-
-
-# the default database. this is where folder_info lives
-DEFAULT_DB="test"
-USER="OGo"
-PASSWORD="OGo"
-HOST="agenor-db"
-PORT="5432"
-
-DEFAULT_CONNECTION = "%s:%s@%s:%s" % (USER, PASSWORD, HOST, PORT)
-
-# insert more names if you want to test with multiple db's!
-dbConnectionMap = { DEFAULT_DB : DEFAULT_CONNECTION }
-
-
-# lookup table for db connections
-connectionPool = {}
-
-
-#
-# TEMPLATES
-#
-
-CREATE_QUICK="""CREATE TABLE SOGo_%(user)s_privcal_quick (
-  c_name       VARCHAR(256)    NOT NULL PRIMARY KEY,
-  uid          VARCHAR(256)    NOT NULL,
-  startdate    INT NOT NULL,
-  enddate      INT NOT NULL,
-  title        VARCHAR(1000)   NOT NULL,
-  participants VARCHAR(100000) NOT NULL
-)"""
-
-CREATE_BLOB="""CREATE TABLE SOGo_%(user)s_privcal (
-  c_name         VARCHAR(256)    NOT NULL PRIMARY KEY,
-  c_content      VARCHAR(100000) NOT NULL,
-  c_creationdate INT             NOT NULL,
-  c_lastmodified INT             NOT NULL,
-  c_version      INT             NOT NULL
-)"""
-
-INSERT_FOLDERINFO_USER="""INSERT INTO SOGo_folder_info 
-  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
-VALUES 
-  ( '/Users/%(user)s', 
-    'Users',
-    '%(user)s',
-    NULL,
-    NULL,
-    '%(user)s', 
-    'http://%(connection)s/%(db)s/SOGo_user_folder', 
-    'http://%(connection)s/%(db)s/SOGo_user_folder_quick', 
-    'Container'
-)"""
-
-INSERT_FOLDERINFO_USER_PRIVCAL="""INSERT INTO SOGo_folder_info 
-  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
-VALUES 
-  ( '/Users/%(user)s/Calendar', 
-    'Users',
-    '%(user)s',
-    'Calendar',
-     NULL,
-    'Calendar', 
-    'http://%(connection)s/%(db)s/SOGo_%(user)s_privcal', 
-    'http://%(connection)s/%(db)s/SOGo_%(user)s_privcal_quick', 
-    'Appointment'
-)"""
-
-
-#
-# HELPERS
-#
-
-def usage():
-  sys.stderr.write("""create_user_tables.py <filename>
-  
-  filename is plain text, platform encoding. Each line has a username. Simple.
-  """)
-  sys.exit(1)
-
-def splitConnectionString(connectionString):
-  res = []
-  for t in connectionString.split("@"):
-    for r in t.split(":"):
-      res.append(r)
-  return res
-  
-#
-# MAIN
-#
-
-def run():
-  global dbConnectionMap, connectionPool
-
-  # check arguments
-  try:
-    filename = sys.argv[1]
-  except IndexError:
-    usage()
-
-  # check filename
-  try:
-    f = open (filename, "r");
-  except IOError:
-    sys.stderr.write("%s\n" % (sys.exc_value))
-    sys.exit(1)
-
-  # setup connection pools
-  dbs = dbConnectionMap.keys()
-  dbsCount = len(dbs)
-  for db in dbs:
-    conString = dbConnectionMap[db]
-    c = splitConnectionString(conString)
-    #pg.DB(dbname, host, port, opt, tty, user, passwd)
-    con = pg.DB(db, c[2], int(c[3]), None, None, c[0], c[1])
-    connectionPool[db] = con
-
-  # get the default connection
-  db = DEFAULT_DB
-  defcon = connectionPool[db]
-  con = defcon
-
-  # read list of users
-  users = f.readlines()
-  for user in users:
-    user = user.strip()
-    
-    # pick a random database if dbsCount > 1
-    if dbsCount > 1:
-      idx = random.randrange(0, dbsCount)
-      db = dbs[idx]
-      con = connectionPool[db]
-  
-    map = { "user"       : user,
-            "db"         : db,
-            "connection" : dbConnectionMap[db],
-          }
-   
-    con.query(CREATE_QUICK % map)
-    con.query(CREATE_BLOB % map)
-    defcon.query(INSERT_FOLDERINFO_USER % map)
-    defcon.query(INSERT_FOLDERINFO_USER_PRIVCAL % map)
-
-
-# let the games begin ...
-if __name__ == "__main__":
-    run()
diff --git a/Misc/db/tests/helge/NOTES b/Misc/db/tests/helge/NOTES
deleted file mode 100644 (file)
index 294ab7e..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-# $Id$
-
-Issues
-- folder generation?
-  - addition der item-generations geht nicht, weil auch records geloescht
-    werden koennen
-- separate tabelle fuer "proposed" appointments?
-  - damit wir die Apts nicht schicken muessen und die erst im scheduler
-    angezeigt werden, wenn sie aktuell sind
-
-Move Databases
-==============
-
-HOST="localhost"
-USER="agenor"
-
-DB="blah2"
-DB="agenor%i" % ( i, )
-
-DB="agenortabledb"
-NEWTABLE="agenor_tab_%i" % ( i, )
-
-DB="agenor_fldinfodb"
-
-DB="agenor_testhugeperf"
-
-
-Schemas
-=======
-
-CREATE TABLE SOGo_folder_info (
-  c_foldername VARCHAR(255) NOT NULL,
-  c_tablename  VARCHAR(255) NOT NULL,
-  c_dbname     VARCHAR(255) NOT NULL
-);
-INSERT INTO SOGo_folder_info (c_foldername,c_tablename,c_dbname) 
-  VALUES ('hh calendar', 'agenor_tab_105', 'agenortabledb');
-
-CREATE UNIQUE INDEX SOGo_folder_info_idx 
-  ON SOGo_folder_info 
-  USING BTREE(c_foldername);
-(ca 5s)
-
----
-  CREATE TABLE SOGo_huge_ical (
-     c_pkey INT PRIMARY KEY,
-     c_data VARCHAR(32000) NOT NULL
-  );
-  CREATE TABLE SOGo_huge_quick (
-    c_pkey       INT PRIMARY KEY,
-    c_sourceid   VARCHAR(255) NOT NULL,
-    c_startdate  INT NOT NULL,
-    c_enddate    INT NOT NULL,
-    c_title      VARCHAR(255) NOT NULL,
-    c_attendees  VARCHAR(4096) NOT NULL,
-    c_isallday   INT NOT NULL,
-    c_sequenceid INT NOT NULL,
-    c_generation INT NOT NULL
-  );
-CREATE INDEX SOGo_huge_quick_idx 
-  ON SOGo_huge_quick
-  USING BTREE(c_startdate);
-(ca 15s on 1.000.000)
----
-
-
-Performance
-===========
-agenor_fldinfodb:
-  10000   Folder Info Entries, kein Index: 71s
-  100000  Folder Info Entries: 12:09m, 729s, 137 inserts/s
-    5992424=>6001088, diff 8664KB data size (von ca 16000 auf 110000)
-    ~94 byte per row (raw: ~12+14+13=39 byte)
-  110001-250000 Folder Info Entries: 15:59m, 959s, 145 inserts/s
-    6001088-6014316, diff 13228KB data size (~96 byte per row)
-
-  ohne Index, via Python:
-    COUNT(*)                   => 360ms
-    c_tablename, c_dbname | *  => 1128ms
-    c_tablename, c_dbname | c_foldername='privcal_99827' => 345ms
-  mit Index, via Python
-    COUNT(*)                   => 350ms
-    c_tablename, c_dbname | *  => 1124ms
-    c_tablename, c_dbname | c_foldername='privcal_99827' => 18,5,5ms
-
-agenor_testhugeperf:
-  1.000.000 entries, kein Index:
-    10000=79.37s, 20000=162s, 30000=245s,340000=2831s,790000=6670s 
-      (~120 rows per sec) = > ca 2h fuer 1.000.000, 20h fuer 10.000.000
-    30000=65MB => ~2KB per Record => ~2GB fuer 1.000.000
-    220000=440MB,810000=1.55GB,1.000.000=
-    ~1.92GB x 20 = 40GB
-    duration:~2:50h
-  ohne Index, via Python:
-    COUNT(*)                     => 20.8s
-    pkey,sourceid,start,end | c_start>x&c_end<x+10s => 13.4s
-    c_sourceid              | *  => 10.5s
-  mit Index, via Python
-    COUNT(*)                     => 9.7s,3s,2.5s
-    pkey,sourceid,start,end | c_start>x&c_end<x+10s => 86ms,59ms,17ms,17ms
-    c_sourceid              | *  => 9.3s,4.8s,4.8s
-  vacuum analyze: 30s?
-  ohne fsync, 2 gleichzeitig
-    - 1108 rows pro sec in einer connection! (1.000.000=ca 15min)
-    53:59m
-    53:52m
-  ~8 gleichzeitig
-    ~20:00:-
-
-http://www.varlena.com/varlena/GeneralBits/Tidbits/perf.html
-http://www.varlena.com/varlena/GeneralBits/Tidbits/annotated_conf_e.html
-http://www.lyris.com/lm_help/7.8/tuning_postgresql.html
-http://www.linuxjournal.com/article.php?sid=4791
-http://www.argudo.org/postgresql/soft-tuning.php#s2
-
-PostgreSQL Index
-================
-http://www.postgresql.org/docs/current/static/sql-createindex.html
-http://postgis.refractions.net/docs/x511.html
-
-"After building an index, it is  important to force PostgreSQL to collect table statistics, which are  used to optimize query plans: VACUUM ANALIZE;"
-
-PostgreSQL provides the index methods B-tree, R-tree, hash, and GiST
-- only the B-tree and GiST index methods support multicolumn indexes
-
----snip---
-An index field can be an expression computed from the values of one or more 
-columns of the table row. This feature can be used to obtain fast access to 
-data based on some transformation of the basic data. For example, an index 
-computed on upper(col) would allow the clause WHERE upper(col) = 'JIM' to use 
-an index.
----snap---
-
----snip---
-Note: Because of the limited utility of hash indexes, a B-tree index  should 
-generally be preferred over a hash index. We do not have  sufficient evidence 
-that hash indexes are actually faster than  B-trees even for = comparisons. 
-Moreover,  hash indexes require coarser locks; see Section 9.7.
----snap--
-
-PostgreSQL Arrays
-=================
----snip---
-It all depends, I have found array operations to be slow. So if you have just 
-a few elements, like less than 10 then arrays are ok, but with more e.g. 30+ 
-elements, as in my case, imho the whole exercise is not really feasable. I am 
-going to re-design the schema to get rid of the arrays as soon as I have a 
-moment. Also the code around that part of PostgreSQL has not been visited for 
-a fair while and needs some polishing up. I'd avoid them.
----snap---
diff --git a/Misc/db/tests/helge/PyGreSQL-samples/advanced.py b/Misc/db/tests/helge/PyGreSQL-samples/advanced.py
deleted file mode 100755 (executable)
index 41a5bc4..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-#! /usr/bin/env python
-# advanced.py - demo of advanced features of PostGres. Some may not be ANSI.
-# inspired from the Postgres tutorial 
-# adapted to Python 1995 by Pascal Andre
-
-print """
-__________________________________________________________________
-MODULE ADVANCED.PY : ADVANCED POSTGRES SQL COMMANDS TUTORIAL
-
-This module is designed for being imported from python prompt
-
-In order to run the samples included here, first create a connection
-using :                        cnx = advanced.DB(...)
-
-The "..." should be replaced with whatever arguments you need to open an
-existing database.  Usually all you need is the name of the database and,
-in fact, if it is the same as your login name, you can leave it empty.
-
-then start the demo with:      advanced.demo(cnx)
-__________________________________________________________________
-"""
-
-from pg import DB
-import sys
-
-# waits for a key
-def wait_key():
-       print "Press <enter>"
-       sys.stdin.read(1)
-
-# inheritance features
-def inherit_demo(pgcnx):
-       print "-----------------------------"
-       print "-- Inheritance:"
-       print "--   a table can inherit from zero or more tables. A query"
-       print "--   can reference either all rows of a table or all rows "
-       print "--   of a table plus all of its descendants."
-       print "-----------------------------"
-       print
-       print "-- For example, the capitals table inherits from cities table."
-       print "-- (It inherits  all data fields from cities.)"
-       print
-       print "CREATE TABLE cities ("
-       print "    name         text,"
-       print "    population   float8,"
-       print "    altitude     int"
-       print ")"
-       print
-       print "CREATE TABLE capitals ("
-       print "    state        varchar(2)"
-       print ") INHERITS (cities)"
-       pgcnx.query("""CREATE TABLE cities (
-        name        text,
-        population  float8,
-        altitude    int)""")
-       pgcnx.query("""CREATE TABLE capitals (
-        state       varchar(2)) INHERITS (cities)""")
-       wait_key()
-       print
-       print "-- now, let's populate the tables"
-       print
-       print "INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)"
-       print "INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)"
-       print "INSERT INTO cities VALUES ('Mariposa', 1200, 1953)"
-       print
-       print "INSERT INTO capitals VALUES ('Sacramento', 3.694E+5, 30, 'CA')"
-       print "INSERT INTO capitals VALUES ('Madison', 1.913E+5, 845, 'WI')"
-       print
-       pgcnx.query("INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)")
-       pgcnx.query("INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)")
-       pgcnx.query("INSERT INTO cities VALUES ('Mariposa', 1200, 1953)")
-       pgcnx.query("INSERT INTO capitals VALUES ('Sacramento',3.694E+5,30,'CA')")
-       pgcnx.query("INSERT INTO capitals VALUES ('Madison', 1.913E+5, 845, 'WI')")
-       print
-       print "SELECT * FROM cities"
-       print pgcnx.query("SELECT * FROM cities")
-       print "SELECT * FROM capitals"
-       print pgcnx.query("SELECT * FROM capitals")
-       print
-       print "-- like before, a regular query references rows of the base"
-       print "-- table only"
-       print
-       print "SELECT name, altitude"
-       print "FROM cities"
-       print "WHERE altitude > 500;"
-       print pgcnx.query("""SELECT name, altitude
-        FROM cities
-        WHERE altitude > 500""")
-       print
-       print "-- on the other hand, you can find all cities, including "
-       print "-- capitals, that are located at an altitude of 500 'ft "
-       print "-- or higher by:"
-       print
-       print "SELECT c.name, c.altitude"
-       print "FROM cities* c"
-       print "WHERE c.altitude > 500"
-       print pgcnx.query("""SELECT c.name, c.altitude
-        FROM cities* c
-        WHERE c.altitude > 500""")
-
-# arrays attributes 
-def array_demo(pgcnx):
-       print "----------------------"
-       print "-- Arrays:"
-       print "--      attributes can be arrays of base types or user-defined "
-       print "--      types"
-       print "----------------------"
-       print
-       print "CREATE TABLE sal_emp ("
-       print "    name            text,"
-       print "    pay_by_quarter  int4[],"
-       print "    pay_by_extra_quarter  int8[],"
-       print "    schedule        text[][]"
-       print ")"
-       pgcnx.query("""CREATE TABLE sal_emp (
-        name              text,
-        pay_by_quarter    int4[],
-        pay_by_extra_quarter    int8[],
-        schedule          text[][])""")
-       wait_key()
-       print
-       print "-- insert instances with array attributes.  "
-       print "   Note the use of braces"
-       print
-       print "INSERT INTO sal_emp VALUES ("
-       print "    'Bill',"
-       print "    '{10000,10000,10000,10000}',"
-       print "    '{9223372036854775800,9223372036854775800,9223372036854775800}',"
-       print "    '{{\"meeting\", \"lunch\"}, {}}')"
-       print
-       print "INSERT INTO sal_emp VALUES ("
-       print "    'Carol',"
-       print "    '{20000,25000,25000,25000}',"
-       print "    '{9223372036854775807,9223372036854775807,9223372036854775807}',"
-       print "    '{{\"talk\", \"consult\"}, {\"meeting\"}}')"
-       print
-       pgcnx.query("""INSERT INTO sal_emp VALUES (
-        'Bill', '{10000,10000,10000,10000}',
-       '{9223372036854775800,9223372036854775800,9223372036854775800}',
-        '{{\"meeting\", \"lunch\"}, {}}')""")
-       pgcnx.query("""INSERT INTO sal_emp VALUES (
-        'Carol', '{20000,25000,25000,25000}',
-       '{9223372036854775807,9223372036854775807,9223372036854775807}',
-        '{{\"talk\", \"consult\"}, {\"meeting\"}}')""")
-       wait_key()
-       print
-       print "----------------------"
-       print "-- queries on array attributes"
-       print "----------------------"
-       print
-       print "SELECT name FROM sal_emp WHERE"
-       print "  sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]"
-       print
-       print pgcnx.query("""SELECT name FROM sal_emp WHERE
-        sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]""")
-       print
-       print pgcnx.query("""SELECT name FROM sal_emp WHERE
-        sal_emp.pay_by_extra_quarter[1] <> sal_emp.pay_by_extra_quarter[2]""")
-       print
-       print "-- retrieve third quarter pay of all employees"
-       print 
-       print "SELECT sal_emp.pay_by_quarter[3] FROM sal_emp"
-       print
-       print pgcnx.query("SELECT sal_emp.pay_by_quarter[3] FROM sal_emp")
-       print
-       print "-- retrieve third quarter extra pay of all employees"
-       print 
-       print "SELECT sal_emp.pay_by_extra_quarter[3] FROM sal_emp"
-       print pgcnx.query("SELECT sal_emp.pay_by_extra_quarter[3] FROM sal_emp")
-       print 
-       print "-- retrieve first two quarters of extra quarter pay of all employees"
-       print 
-       print "SELECT sal_emp.pay_by_extra_quarter[1:2] FROM sal_emp"
-       print
-       print pgcnx.query("SELECT sal_emp.pay_by_extra_quarter[1:2] FROM sal_emp")
-       print
-       print "-- select subarrays"
-       print 
-       print "SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE"
-       print "     sal_emp.name = 'Bill'"
-       print pgcnx.query("SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE " \
-        "sal_emp.name = 'Bill'")
-
-# base cleanup
-def demo_cleanup(pgcnx):
-       print "-- clean up (you must remove the children first)"
-       print "DROP TABLE sal_emp"
-       print "DROP TABLE capitals"
-       print "DROP TABLE cities;"
-       pgcnx.query("DROP TABLE sal_emp")
-       pgcnx.query("DROP TABLE capitals")
-       pgcnx.query("DROP TABLE cities")
-
-# main demo function
-def demo(pgcnx):
-       inherit_demo(pgcnx)
-       array_demo(pgcnx)
-       demo_cleanup(pgcnx)
diff --git a/Misc/db/tests/helge/PyGreSQL-samples/basics.py b/Misc/db/tests/helge/PyGreSQL-samples/basics.py
deleted file mode 100755 (executable)
index 98a7f86..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-#! /usr/bin/env python
-# basics.py - basic SQL commands tutorial
-# inspired from the Postgres95 tutorial 
-# adapted to Python 1995 by Pascal ANDRE
-
-print """
-__________________________________________________________________
-MODULE BASICS.PY : BASIC POSTGRES SQL COMMANDS TUTORIAL
-    
-This module is designed for being imported from python prompt
-    
-In order to run the samples included here, first create a connection
-using :                        cnx = basics.DB(...)
-  
-The "..." should be replaced with whatever arguments you need to open an
-existing database.  Usually all you need is the name of the database and,
-in fact, if it is the same as your login name, you can leave it empty.
-        
-then start the demo with:      basics.demo(cnx)
-__________________________________________________________________
-""" 
-
-from pg import DB
-import sys
-
-# waits for a key
-def wait_key():
-       print "Press <enter>"
-       sys.stdin.read(1)
-
-# table creation commands
-def create_table(pgcnx):
-       print "-----------------------------"
-       print "-- Creating a table:"
-       print "--  a CREATE TABLE is used to create base tables. POSTGRES"
-       print "--  SQL has its own set of built-in types. (Note that"
-       print "--  keywords are case-insensitive but identifiers are "
-       print "--  case-sensitive.)"
-       print "-----------------------------"
-       print
-       print "Sending query :"
-       print "CREATE TABLE weather ("
-        print "    city            varchar(80),"
-        print "    temp_lo         int,"
-        print "    temp_hi         int,"
-        print "    prcp            float8,"
-        print "    date            date"
-        print ")"
-        pgcnx.query("""CREATE TABLE weather (city varchar(80), temp_lo int,
-            temp_hi int, prcp float8, date date)""")
-       print
-       print "Sending query :"
-       print "CREATE TABLE cities ("
-       print "    name        varchar(80),"
-       print "    location    point"
-       print ")"
-       pgcnx.query("""CREATE TABLE cities (
-        name     varchar(80),
-        location point)""")
-
-# data insertion commands
-def insert_data(pgcnx):
-       print "-----------------------------"
-       print "-- Inserting data:"
-       print "--  an INSERT statement is used to insert a new row into"
-       print "--  a table. There are several ways you can specify what"
-       print "--  columns the data should go to."
-       print "-----------------------------"
-       print
-       print "-- 1. the simplest case is when the list of value correspond to"
-       print "--    the order of the columns specified in CREATE TABLE."
-       print
-       print "Sending query :"
-       print "INSERT INTO weather "
-       print "   VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')"
-       pgcnx.query("""INSERT INTO weather
-        VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')""")
-       print
-       print "Sending query :"
-       print "INSERT INTO cities "
-       print "   VALUES ('San Francisco', '(-194.0, 53.0)')"
-       pgcnx.query("""INSERT INTO cities
-        VALUES ('San Francisco', '(-194.0, 53.0)')""")
-       print
-       wait_key()
-       print "-- 2. you can also specify what column the values correspond "
-       print "     to. (The columns can be specified in any order. You may "
-       print "     also omit any number of columns. eg. unknown precipitation"
-       print "     below)"
-       print "Sending query :"
-       print "INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)"
-       print "   VALUES ('San Francisco', 43, 57, 0.0, '11/29/1994')"
-       pgcnx.query("INSERT INTO weather (date, city, temp_hi, temp_lo)" \
-        "VALUES ('11/29/1994', 'Hayward', 54, 37)")
-
-# direct selection commands
-def select_data1(pgcnx):
-       print "-----------------------------"
-       print "-- Retrieving data:"
-       print "--  a SELECT statement is used for retrieving data. The "
-       print "--  basic syntax is:"
-       print "--      SELECT columns FROM tables WHERE predicates"
-       print "-----------------------------"
-       print
-       print "-- a simple one would be the query:"
-       print "SELECT * FROM weather"
-       print 
-       print "The result is :"
-       q = pgcnx.query("SELECT * FROM weather")
-       print q
-       print
-       print "-- you may also specify expressions in the target list (the "
-       print "-- 'AS column' specifies the column name of the result. It is "
-       print "-- optional.)"
-       print "The query :"
-       print "   SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date "
-       print "   FROM weather"
-       print "Gives :"
-       print pgcnx.query("""SELECT city, (temp_hi+temp_lo)/2
-        AS temp_avg, date FROM weather""")
-       print
-       print "-- if you want to retrieve rows that satisfy certain condition"
-       print "-- (ie. a restriction), specify the condition in WHERE. The "
-       print "-- following retrieves the weather of San Francisco on rainy "
-       print "-- days."
-       print "SELECT *"
-       print "FROM weather"
-       print "WHERE city = 'San Francisco' "
-       print "  and prcp > 0.0"
-       print pgcnx.query("""SELECT * FROM weather WHERE city = 'San Francisco'
-        AND prcp > 0.0""")
-       print
-       print "-- here is a more complicated one. Duplicates are removed when "
-       print "-- DISTINCT is specified. ORDER BY specifies the column to sort"
-       print "-- on. (Just to make sure the following won't confuse you, "
-       print "-- DISTINCT and ORDER BY can be used separately.)"
-       print "SELECT DISTINCT city"
-       print "FROM weather"
-       print "ORDER BY city;"
-       print pgcnx.query("SELECT DISTINCT city FROM weather ORDER BY city")
-
-# selection to a temporary table
-def select_data2(pgcnx):
-       print "-----------------------------"
-       print "-- Retrieving data into other classes:"
-       print "--  a SELECT ... INTO statement can be used to retrieve "
-       print "--  data into another class."
-       print "-----------------------------"
-       print 
-       print "The query :"
-       print "SELECT * INTO TABLE temptab "
-       print "FROM weather"
-       print "WHERE city = 'San Francisco' "
-       print "  and prcp > 0.0"
-       pgcnx.query("""SELECT * INTO TABLE temptab FROM weather
-        WHERE city = 'San Francisco' and prcp > 0.0""")
-       print "Fills the table temptab, that can be listed with :"
-       print "SELECT * from temptab"
-       print pgcnx.query("SELECT * from temptab")
-
-# aggregate creation commands
-def create_aggregate(pgcnx):
-       print "-----------------------------"
-       print "-- Aggregates"
-       print "-----------------------------"
-       print
-       print "Let's consider the query :"
-       print "SELECT max(temp_lo)"
-       print "FROM weather;"
-       print pgcnx.query("SELECT max(temp_lo) FROM weather")
-       print 
-       print "-- Aggregate with GROUP BY"
-       print "SELECT city, max(temp_lo)"
-       print "FROM weather "
-       print "GROUP BY city;"
-       print pgcnx.query( """SELECT city, max(temp_lo)
-        FROM weather GROUP BY city""")
-
-# table join commands
-def join_table(pgcnx):
-       print "-----------------------------"
-       print "-- Joining tables:"
-       print "--  queries can access multiple tables at once or access"
-       print "--  the same table in such a way that multiple instances"
-       print "--  of the table are being processed at the same time."
-       print "-----------------------------"
-       print
-       print "-- suppose we want to find all the records that are in the "
-       print "-- temperature range of other records. W1 and W2 are aliases "
-       print "--for weather."
-       print
-       print "SELECT W1.city, W1.temp_lo, W1.temp_hi, "
-       print "    W2.city, W2.temp_lo, W2.temp_hi"
-       print "FROM weather W1, weather W2"
-       print "WHERE W1.temp_lo < W2.temp_lo "
-       print "  and W1.temp_hi > W2.temp_hi"
-       print
-       print pgcnx.query("""SELECT W1.city, W1.temp_lo, W1.temp_hi,
-        W2.city, W2.temp_lo, W2.temp_hi FROM weather W1, weather W2
-        WHERE W1.temp_lo < W2.temp_lo and W1.temp_hi > W2.temp_hi""")
-       print
-       print "-- let's join two tables. The following joins the weather table"
-       print "-- and the cities table."
-       print
-       print "SELECT city, location, prcp, date"
-       print "FROM weather, cities"
-       print "WHERE name = city"
-       print
-       print pgcnx.query("""SELECT city, location, prcp, date FROM weather, cities
-        WHERE name = city""")
-       print
-       print "-- since the column names are all different, we don't have to "
-       print "-- specify the table name. If you want to be clear, you can do "
-       print "-- the following. They give identical results, of course."
-       print
-       print "SELECT w.city, c.location, w.prcp, w.date"
-       print "FROM weather w, cities c"
-       print "WHERE c.name = w.city;"
-       print
-       print pgcnx.query("""SELECT w.city, c.location, w.prcp, w.date
-        FROM weather w, cities c WHERE c.name = w.city""")
-
-# data updating commands
-def update_data(pgcnx):
-       print "-----------------------------"
-       print "-- Updating data:"
-       print "--  an UPDATE statement is used for updating data. "
-       print "-----------------------------"
-       print 
-       print "-- suppose you discover the temperature readings are all off by"
-       print "-- 2 degrees as of Nov 28, you may update the data as follow:"
-       print
-       print "UPDATE weather"
-       print "  SET temp_hi = temp_hi - 2,  temp_lo = temp_lo - 2"
-       print "  WHERE date > '11/28/1994'"
-       print
-       pgcnx.query("""UPDATE weather
-        SET temp_hi = temp_hi - 2,  temp_lo = temp_lo - 2
-        WHERE date > '11/28/1994'""")
-       print
-       print "SELECT * from weather"
-       print pgcnx.query("SELECT * from weather")
-
-# data deletion commands
-def delete_data(pgcnx):
-       print "-----------------------------"
-       print "-- Deleting data:"
-       print "--  a DELETE statement is used for deleting rows from a "
-       print "--  table."
-       print "-----------------------------"
-       print
-       print "-- suppose you are no longer interested in the weather of "
-       print "-- Hayward, you can do the following to delete those rows from"
-       print "-- the table"
-       print
-       print "DELETE FROM weather WHERE city = 'Hayward'"
-       pgcnx.query("DELETE FROM weather WHERE city = 'Hayward'")
-       print
-       print "SELECT * from weather"
-       print
-       print pgcnx.query("SELECT * from weather")
-       print
-       print "-- you can also delete all the rows in a table by doing the "
-       print "-- following. (This is different from DROP TABLE which removes "
-       print "-- the table in addition to the removing the rows.)"
-       print
-       print "DELETE FROM weather"
-       pgcnx.query("DELETE FROM weather")
-       print
-       print "SELECT * from weather"
-       print pgcnx.query("SELECT * from weather")
-
-# table removal commands
-def remove_table(pgcnx):
-       print "-----------------------------"
-       print "-- Removing the tables:"
-       print "--  DROP TABLE is used to remove tables. After you have"
-       print "--  done this, you can no longer use those tables."
-       print "-----------------------------"
-       print
-       print "DROP TABLE weather, cities, temptab"
-       pgcnx.query("DROP TABLE weather, cities, temptab")
-
-# main demo function
-def demo(pgcnx):
-       create_table(pgcnx)
-       wait_key()
-       insert_data(pgcnx)
-       wait_key()
-       select_data1(pgcnx)
-       select_data2(pgcnx)
-       create_aggregate(pgcnx)
-       join_table(pgcnx)
-       update_data(pgcnx)
-       delete_data(pgcnx)
-       remove_table(pgcnx)
diff --git a/Misc/db/tests/helge/PyGreSQL-samples/func.py b/Misc/db/tests/helge/PyGreSQL-samples/func.py
deleted file mode 100755 (executable)
index af2b412..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-# func.py - demonstrate the use of SQL functions
-# inspired from the PostgreSQL tutorial 
-# adapted to Python 1995 by Pascal ANDRE
-
-print """
-__________________________________________________________________
-MODULE FUNC.PY : SQL FUNCTION DEFINITION TUTORIAL
-
-This module is designed for being imported from python prompt
-
-In order to run the samples included here, first create a connection
-using :                        cnx = func.DB(...)
-
-The "..." should be replaced with whatever arguments you need to open an
-existing database.  Usually all you need is the name of the database and,
-in fact, if it is the same as your login name, you can leave it empty.
-
-then start the demo with:      func.demo(cnx)
-__________________________________________________________________
-""" 
-
-from pg import DB
-import sys
-
-# waits for a key
-def wait_key():
-       print "Press <enter>"
-       sys.stdin.read(1)
-
-# basic functions declaration
-def base_func(pgcnx):
-       print "-----------------------------"
-       print "-- Creating SQL Functions on Base Types"
-       print "--  a CREATE FUNCTION statement lets you create a new "
-       print "--  function that can be used in expressions (in SELECT, "
-       print "--  INSERT, etc.). We will start with functions that "
-       print "--  return values of base types."
-       print "-----------------------------"
-       print
-       print "--"
-       print "-- let's create a simple SQL function that takes no arguments"
-       print "-- and returns 1"
-       print
-       print "CREATE FUNCTION one() RETURNS int4"
-       print "   AS 'SELECT 1 as ONE' LANGUAGE 'sql'"
-       pgcnx.query("""CREATE FUNCTION one() RETURNS int4
-        AS 'SELECT 1 as ONE' LANGUAGE 'sql'""")
-       wait_key()
-       print
-       print "--"
-       print "-- functions can be used in any expressions (eg. in the target"
-       print "-- list or qualifications)"
-       print
-       print "SELECT one() AS answer"
-       print pgcnx.query("SELECT one() AS answer")
-       print
-       print "--"
-       print "-- here's how you create a function that takes arguments. The"
-       print "-- following function returns the sum of its two arguments:"
-       print
-       print "CREATE FUNCTION add_em(int4, int4) RETURNS int4"
-       print "   AS 'SELECT $1 + $2' LANGUAGE 'sql'"
-       pgcnx.query("""CREATE FUNCTION add_em(int4, int4) RETURNS int4
-        AS 'SELECT $1 + $2' LANGUAGE 'sql'""")
-       print
-       print "SELECT add_em(1, 2) AS answer"
-       print pgcnx.query("SELECT add_em(1, 2) AS answer")
-
-# functions on composite types
-def comp_func(pgcnx):
-       print "-----------------------------"
-       print "-- Creating SQL Functions on Composite Types"
-       print "--  it is also possible to create functions that return"
-       print "--  values of composite types."
-       print "-----------------------------"
-       print
-       print "-- before we create more sophisticated functions, let's "
-       print "-- populate an EMP table"
-       print
-       print "CREATE TABLE EMP ("
-       print "    name    text,"
-       print "    salary  int4,"
-       print "    age     int4,"
-       print "    dept    varchar(16)"
-       print ")"
-       pgcnx.query("""CREATE TABLE EMP (
-        name        text,
-        salary      int4,
-        age         int4,
-        dept        varchar(16))""")
-       print
-       print "INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')"
-       print "INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')"
-       print "INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')"
-       print "INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')"
-       print "INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')"
-       pgcnx.query("INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')")
-       pgcnx.query("INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')")
-       pgcnx.query("INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')")
-       pgcnx.query("INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')")
-       pgcnx.query("INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')")
-       wait_key()
-       print
-       print "-- the argument of a function can also be a tuple. For "
-       print "-- instance, double_salary takes a tuple of the EMP table"
-       print
-       print "CREATE FUNCTION double_salary(EMP) RETURNS int4"
-       print "   AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'"
-       pgcnx.query("""CREATE FUNCTION double_salary(EMP) RETURNS int4
-        AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'""")
-       print
-       print "SELECT name, double_salary(EMP) AS dream"
-       print "FROM EMP"
-       print "WHERE EMP.dept = 'toy'"
-       print pgcnx.query("""SELECT name, double_salary(EMP) AS dream
-        FROM EMP WHERE EMP.dept = 'toy'""")
-       print
-       print "-- the return value of a function can also be a tuple. However,"
-       print "-- make sure that the expressions in the target list is in the "
-       print "-- same order as the columns of EMP."
-       print
-       print "CREATE FUNCTION new_emp() RETURNS EMP"
-       print "   AS 'SELECT \'None\'::text AS name,"
-       print "              1000 AS salary,"
-       print "              25 AS age,"
-       print "              \'none\'::varchar(16) AS dept'"
-       print "   LANGUAGE 'sql'"
-       pgcnx.query("""CREATE FUNCTION new_emp() RETURNS EMP
-        AS 'SELECT \\\'None\\\'::text AS name,
-            1000 AS salary,
-            25 AS age,
-            \\\'none\\\'::varchar(16) AS dept'
-        LANGUAGE 'sql'""")
-       wait_key()
-       print
-       print "-- you can then project a column out of resulting the tuple by"
-       print "-- using the \"function notation\" for projection columns. "
-       print "-- (ie. bar(foo) is equivalent to foo.bar) Note that we don't"
-       print "-- support new_emp().name at this moment."
-       print
-       print "SELECT name(new_emp()) AS nobody"
-       print pgcnx.query("SELECT name(new_emp()) AS nobody")
-       print
-       print "-- let's try one more function that returns tuples"
-       print "CREATE FUNCTION high_pay() RETURNS setof EMP"
-       print "   AS 'SELECT * FROM EMP where salary > 1500'"
-       print "   LANGUAGE 'sql'"
-       pgcnx.query("""CREATE FUNCTION high_pay() RETURNS setof EMP
-        AS 'SELECT * FROM EMP where salary > 1500'
-        LANGUAGE 'sql'""")
-       print
-       print "SELECT name(high_pay()) AS overpaid"
-       print pgcnx.query("SELECT name(high_pay()) AS overpaid")
-
-# function with multiple SQL commands
-def mult_func(pgcnx):
-       print "-----------------------------"
-       print "-- Creating SQL Functions with multiple SQL statements"
-       print "--  you can also create functions that do more than just a"
-       print "--  SELECT."
-       print "-----------------------------"
-       print
-       print "-- you may have noticed that Andy has a negative salary. We'll"
-       print "-- create a function that removes employees with negative "
-       print "-- salaries."
-       print
-       print "SELECT * FROM EMP"
-       print pgcnx.query("SELECT * FROM EMP")
-       print
-       print "CREATE FUNCTION clean_EMP () RETURNS int4"
-       print "   AS 'DELETE FROM EMP WHERE EMP.salary <= 0"
-       print "       SELECT 1 AS ignore_this'"
-       print "   LANGUAGE 'sql'"
-       pgcnx.query("CREATE FUNCTION clean_EMP () RETURNS int4 AS 'DELETE FROM EMP WHERE EMP.salary <= 0; SELECT 1 AS ignore_this' LANGUAGE 'sql'")
-       print
-       print "SELECT clean_EMP()"
-       print pgcnx.query("SELECT clean_EMP()")
-       print
-       print "SELECT * FROM EMP"
-       print pgcnx.query("SELECT * FROM EMP")
-
-# base cleanup
-def demo_cleanup(pgcnx):
-       print "-- remove functions that were created in this file"
-       print
-       print "DROP FUNCTION clean_EMP()"
-       print "DROP FUNCTION high_pay()"
-       print "DROP FUNCTION new_emp()"
-       print "DROP FUNCTION add_em(int4, int4)"
-       print "DROP FUNCTION one()"
-       print
-       print "DROP TABLE EMP CASCADE"
-       pgcnx.query("DROP FUNCTION clean_EMP()")
-       pgcnx.query("DROP FUNCTION high_pay()")
-       pgcnx.query("DROP FUNCTION new_emp()")
-       pgcnx.query("DROP FUNCTION add_em(int4, int4)")
-       pgcnx.query("DROP FUNCTION one()")
-       pgcnx.query("DROP TABLE EMP CASCADE")
-
-# main demo function
-def demo(pgcnx):
-       base_func(pgcnx)
-       comp_func(pgcnx)
-       mult_func(pgcnx)
-       demo_cleanup(pgcnx)
diff --git a/Misc/db/tests/helge/PyGreSQL-samples/syscat.py b/Misc/db/tests/helge/PyGreSQL-samples/syscat.py
deleted file mode 100755 (executable)
index 1ab1d58..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-# syscat.py - parses some system catalogs
-# inspired from the PostgreSQL tutorial 
-# adapted to Python 1995 by Pascal ANDRE
-
-print """
-__________________________________________________________________
-MODULE SYSCAT.PY : PARSES SOME POSTGRESQL SYSTEM CATALOGS
-
-This module is designed for being imported from python prompt
-
-In order to run the samples included here, first create a connection
-using :                        cnx = syscat.DB(...)
-
-The "..." should be replaced with whatever arguments you need to open an 
-existing database.  Usually all you need is the name of the database and,
-in fact, if it is the same as your login name, you can leave it empty.
-
-then start the demo with:      syscat.demo(cnx)
-
-Some results may be empty, depending on your base status."
-
-__________________________________________________________________
-"""
-
-from pg import DB
-import sys
-
-# waits for a key
-def wait_key():
-       print "Press <enter>"
-       sys.stdin.read(1)
-
-# lists all simple indices
-def list_simple_ind(pgcnx):
-       result = pgcnx.query("""SELECT bc.relname AS class_name,
-                       ic.relname AS index_name, a.attname
-               FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a
-               WHERE i.indrelid = bc.oid AND i.indexrelid = bc.oid
-                               AND i.indkey[0] = a.attnum AND a.attrelid = bc.oid
-                               AND i.indproc = '0'::oid AND a.attisdropped = 'f'
-               ORDER BY class_name, index_name, attname""")
-       return result
-
-# list all user defined attributes and their type in user-defined classes
-def list_all_attr(pgcnx):
-       result = pgcnx.query("""SELECT c.relname, a.attname, t.typname
-               FROM pg_class c, pg_attribute a, pg_type t
-               WHERE c.relkind = 'r' and c.relname !~ '^pg_'
-                       AND c.relname !~ '^Inv' and a.attnum > 0
-                       AND a.attrelid = c.oid and a.atttypid = t.oid
-                        AND a.attisdropped = 'f'
-                       ORDER BY relname, attname""")
-       return result
-
-# list all user defined base type
-def list_user_base_type(pgcnx):
-       result = pgcnx.query("""SELECT u.usename, t.typname
-                       FROM pg_type t, pg_user u
-                       WHERE u.usesysid = int2in(int4out(t.typowner))
-                               AND t.typrelid = '0'::oid and t.typelem = '0'::oid 
-                               AND u.usename <> 'postgres' order by usename, typname""")
-       return result 
-
-# list all right-unary operators
-def list_right_unary_operator(pgcnx):
-       result = pgcnx.query("""SELECT o.oprname AS right_unary,
-                       lt.typname AS operand, result.typname AS return_type
-               FROM pg_operator o, pg_type lt, pg_type result
-               WHERE o.oprkind='r' and o.oprleft = lt.oid
-                       AND o.oprresult = result.oid
-               ORDER BY operand""")
-       return result
-
-# list all left-unary operators
-def list_left_unary_operator(pgcnx):
-       result = pgcnx.query("""SELECT o.oprname AS left_unary,
-                       rt.typname AS operand, result.typname AS return_type
-               FROM pg_operator o, pg_type rt, pg_type result
-               WHERE o.oprkind='l' AND o.oprright = rt.oid
-                       AND o.oprresult = result.oid
-               ORDER BY operand""")
-       return result
-
-# list all binary operators
-def list_binary_operator(pgcnx):
-       result = pgcnx.query("""SELECT o.oprname AS binary_op,
-                       rt.typname AS right_opr, lt.typname AS left_opr,
-                       result.typname AS return_type
-               FROM pg_operator o, pg_type rt, pg_type lt, pg_type result
-               WHERE o.oprkind = 'b' AND o.oprright = rt.oid
-                       AND o.oprleft = lt.oid AND o.oprresult = result.oid""")
-       return result
-
-# returns the name, args and return type from all function of lang l
-def list_lang_func(pgcnx, l):
-       result = pgcnx.query("""SELECT p.proname, p.pronargs, t.typname
-               FROM pg_proc p, pg_language l, pg_type t
-               WHERE p.prolang = l.oid AND p.prorettype = t.oid
-                       AND l.lanname = '%s'
-               ORDER BY proname""" % l)
-       return result
-
-# lists all the aggregate functions and the type to which they can be applied
-def list_agg_func(pgcnx):
-       result = pgcnx.query("""SELECT p.proname, t.typname
-               FROM pg_aggregate a, pg_proc p, pg_type t
-               WHERE a.aggfnoid = p.oid
-                       and p.proargtypes[0] = t.oid
-               ORDER BY proname, typname""")
-       return result
-
-# lists all the operator classes that can be used with each access method as
-# well as the operators that can be used with the respective operator classes
-def list_op_class(pgcnx):
-       result = pgcnx.query("""SELECT am.amname, opc.opcname, opr.oprname
-               FROM pg_am am, pg_amop amop, pg_opclass opc, pg_operator opr
-               WHERE amop.amopid = am.oid and amop.amopclaid = opc.oid
-                       AND amop.amopopr = opr.oid order by amname, opcname, oprname""")
-       return result
-
-# demo function - runs all examples
-def demo(pgcnx):
-       import sys, os
-       save_stdout = sys.stdout
-       sys.stdout = os.popen("more", "w")
-       print "Listing simple indices ..."
-       print list_simple_ind(pgcnx)
-       print "Listing all attributes ..."
-       print list_all_attr(pgcnx)
-       print "Listing all user-defined base types ..."
-       print list_user_base_type(pgcnx)
-       print "Listing all left-unary operators defined ..."
-       print list_left_unary_operator(pgcnx)
-       print "Listing all right-unary operators defined ..."
-       print list_right_unary_operator(pgcnx)
-       print "Listing all binary operators ..."
-       print list_binary_operator(pgcnx)
-       print "Listing C external function linked ..."
-       print list_lang_func(pgcnx, 'C')
-       print "Listing C internal functions ..."
-       print list_lang_func(pgcnx, 'internal')
-       print "Listing SQL functions defined ..."
-       print list_lang_func(pgcnx, 'sql')
-       print "Listing 'aggregate functions' ..."
-       print list_agg_func(pgcnx)
-       print "Listing 'operator classes' ..."
-       print list_op_class(pgcnx)
-       del sys.stdout
-       sys.stdout = save_stdout
diff --git a/Misc/db/tests/helge/chkfolderinfoperf.py b/Misc/db/tests/helge/chkfolderinfoperf.py
deleted file mode 100755 (executable)
index e4700e2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/python
-
-import pg, time
-
-USER="agenor"
-HOST="localhost"
-DB="agenor_fldinfodb"
-TABLE="SOGo_folder_info"
-
-db = pg.DB(DB, HOST, 5432, "", "", USER);
-print "connection:", db
-
-def timeSelect(SELECT, WHERE=None):
-    SQL="SELECT %s FROM %s" % ( SELECT, TABLE )
-    if not WHERE is None: SQL="%s WHERE %s" % ( SQL, WHERE )
-    starttime=time.time()
-    res = db.query(SQL)
-    endtime=time.time()
-    print "perf '%s', %s: %.2fms" % ( SELECT, WHERE, (endtime-starttime)*1000)
-
-timeSelect("COUNT(*)")
-timeSelect("c_tablename, c_dbname")
-timeSelect("c_tablename, c_dbname", "c_foldername='privcal_99827'")
diff --git a/Misc/db/tests/helge/chkhugeperf.py b/Misc/db/tests/helge/chkhugeperf.py
deleted file mode 100755 (executable)
index 36c588c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/python
-
-import pg, time
-
-USER="agenor"
-HOST="localhost"
-DB="agenor_testhugeperf"
-TABLE="SOGo_huge_quick"
-
-db = pg.DB(DB, HOST, 5432, "", "", USER);
-print "connection:", db
-
-def timeSelect(SELECT, WHERE=None):
-    SQL="SELECT %s FROM %s" % ( SELECT, TABLE )
-    if not WHERE is None: SQL="%s WHERE %s" % ( SQL, WHERE )
-    starttime=time.time()
-    res = db.query(SQL)
-    endtime=time.time()
-    print "perf '%s', %s: %.2fms" % ( SELECT, WHERE, (endtime-starttime)*1000)
-
-timeSelect("COUNT(*)")
-timeSelect("c_pkey, c_sourceid, c_startdate, c_enddate",
-           "c_startdate > 1085068363 AND c_startdate < 1085068373")
-timeSelect("c_sourceid")
diff --git a/Misc/db/tests/helge/fill_hugeperf.py b/Misc/db/tests/helge/fill_hugeperf.py
deleted file mode 100755 (executable)
index 26a379e..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/python
-
-import pg, time, sys
-
-USER="agenor"
-HOST="localhost"
-DB="agenor_testhugeperf"
-QUICKTABLE="SOGo_huge_quick"
-BLOBTABLE="SOGo_huge_ical"
-
-db = pg.DB(DB, HOST, 5432, "", "", USER);
-print "connection:", db
-
-# index, index, start, end, index, 
-QUICKTEMPLATE="""INSERT INTO %s (
-  c_pkey, c_sourceid, c_startdate, c_enddate, c_title, c_attendees,
-  c_isallday, c_sequenceid, c_generation
-) VALUES (
-  %i, 'longsource%iid', %i, %i, 'long title %i',
-  'hh@skyrix.com,mm@skyrix,je@skyrix.com,fr@skyrix.com,jm@skyrix.com,hh@skyrix.com,mm@skyrix,je@skyrix.com,fr@skyrix.com,jm@skyrix.com,hh@skyrix.com,mm@skyrix,je@skyrix.com,fr@skyrix.com,jm@skyrix.com',
-  0, 0, 1
-);"""
-
-# index, ical
-ICALTEMPLATE="INSERT INTO %s ( c_pkey, c_data ) VALUES ( %i, '%s' );"
-
-ICALFILE="""BEGIN:VEVENT\r
-DURATION:PT1H\r
-ATTENDEE;CN="Elke Bethke";DIR="addressbook://B156F3F0-9CFD-11D8-8561-000\r
- D93C1A604:ABPerson":mailto:E.Bethke@Sachsen-Anhalt-Lotto.de\r
-ATTENDEE;CN="Erik Doernenburg";DIR="addressbook://B15FCB0F-9CFD-11D8-8561\r
- -000D93C1A604:ABPerson":mailto:erik@x101.net\r
-ATTENDEE;CN="Christian Schnelle";DIR="addressbook://B1418D4E-9CFD-11D8-8\r
- 561-000D93C1A604:ABPerson":mailto:cs@enervation.de\r
-ATTENDEE;CN="Chris Herrenberger";DIR="addressbook://B14A390C-9CFD-11D8-8\r
- 561-000D93C1A604:ABPerson":invalid:nomail\r
-ATTENDEE;CN="Horst Parplies";DIR="addressbook://B19B47E5-9CFD-11D8-8561-\r
- 000D93C1A604:ABPerson":mailto:horst.parplies@freenet.de\r
-ATTENDEE;CN="Imdat Solak";DIR="addressbook://B19EDB62-9CFD-11D8-8561-000\r
- D93C1A604:ABPerson":mailto:imdat@solak.de\r
-ATTENDEE;CN="Jens Enders";DIR="addressbook://B1B6819F-9CFD-11D8-8561-000\r
- D93C1A604:ABPerson":mailto:jens.enders@skyrix.com\r
-ATTENDEE;CN="Jens Muenster";DIR="addressbook://B1BBA42E-9CFD-11D8-8561-00\r
- 0D93C1A604:ABPerson":mailto:jens.muenster@skyrix.com\r
-ATTENDEE;CN="Laurent Pierre";DIR="addressbook://9337C270-A825-11D8-B930-\r
- 000D93C1A604:ABPerson":mailto:laurent.pierre@linagora.com\r
-ATTENDEE;CN="Marcel Weiher";DIR="addressbook://B1F9BB12-9CFD-11D8-8561-0\r
- 00D93C1A604:ABPerson":mailto:marcel@metaobject.co\r
-DTSTAMP:20040520T140002Z\r
-UID:BD91C454-AA65-11D8-84CA-000D93C1A604\r
-SEQUENCE:3\r
-STATUS:CONFIRMED\r
-DTSTART;TZID=Europe/Berlin:20040618T160000\r
-SUMMARY:SIZE EVENT\r
-X-WR-ITIPSTATUSML:UNCLEAN\r
-END:VEVENT\r
-"""
-
-
-# ******************** INSERT ********************
-
-FROM=int(sys.argv[1])
-TO=FROM+1000000
-#FROM=1
-#TO=1000000
-
-timingstart=time.time()
-
-for i in range(FROM, TO):
-    start=time.time()
-    end=start+(60 * 30)
-    
-    QSQL = QUICKTEMPLATE % ( QUICKTABLE, i, i, start, end, i, )
-    BSQL = ICALTEMPLATE  % ( BLOBTABLE, i, ICALFILE )
-    
-    if i % 10000 == 0:
-        print "%i (%.2fs): quick %s" % ( i, time.time()-timingstart, QSQL )
-        #print "%i: blob  %s" % ( i, BSQL )
-    db.query(QSQL + BSQL)
-
diff --git a/Misc/db/tests/helge/fillfolderinfo.py b/Misc/db/tests/helge/fillfolderinfo.py
deleted file mode 100755 (executable)
index 2fc12c4..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/python
-
-import pg
-
-USER="agenor"
-HOST="localhost"
-DB="agenor_fldinfodb"
-TABLE="SOGo_folder_info"
-
-db = pg.DB(DB, HOST, 5432, "", "", USER);
-print "connection:", db
-
-for i in range(110001, 250000):
-    SQL=("INSERT INTO %s ( c_foldername, c_tablename, c_dbname ) " + \
-         "VALUES ( 'privcal_%i', 'agenor_tab_%i', 'agenortabledb' );") % \
-         ( TABLE, i, i, )
-    if i % 1000 == 0:
-        print "%i: %s" % ( i, SQL )
-    db.query(SQL)
diff --git a/Misc/db/tests/helge/laurent-trigger.psql b/Misc/db/tests/helge/laurent-trigger.psql
deleted file mode 100644 (file)
index 05456d3..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-CREATE FUNCTION mise_a_jour_t2() RETURNS trigger AS '
-  BEGIN
-    IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
-      UPDATE table2 SET champ2 = champ2 + 1 WHERE... ;
-      RETURN NEW;
-    ELSE IF TG_OP = 'DELETE'
-      UPDATE table2 SET champ2 = champ2 - 1 WHERE ... ;
-      RETURN OLD ;
-    END IF;
-  END;
-
-' LANGUAGE plpgsql;
-
-CREATE TRIGGER mise_a_jour 
-  AFTER INSERT OR UPDATE OR DELETE 
-  ON table1
-  FOR EACH ROW EXECUTE PROCEDURE mise_a_jour_t2();
diff --git a/Misc/db/tests/helge/makedb.py b/Misc/db/tests/helge/makedb.py
deleted file mode 100755 (executable)
index 5113950..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/python
-
-import os, sys
-
-HOST="localhost"
-USER="agenor"
-DB="blah2"
-
-for i in range(920, 10000):
-    DB="agenor%i" % ( i, )
-    res=os.system("createdb -h %s -U %s %s" % ( HOST, USER, DB ))
-    print "%s res: %i" % ( DB, res )
diff --git a/Misc/db/tests/helge/maketables.py b/Misc/db/tests/helge/maketables.py
deleted file mode 100755 (executable)
index 16c0899..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/python
-
-import os, sys
-
-HOST="localhost"
-USER="agenor"
-DB="agenortabledb"
-
-for i in range(10000, 60000):
-    NEWTABLE="agenor_tab_%i" % ( i, )
-    
-    TABLECREATE="""CREATE TABLE %s
-    ( pkey INT PRIMARY KEY,
-      startdate    INT NOT NULL,
-      endate       INT NOT NULL,
-      title        VARCHAR(1000) NOT NULL,
-      participants VARCHAR(100000) NOT NULL);""" % ( NEWTABLE, )
-    
-    CALL="echo '%s' | psql -h %s %s %s" % ( TABLECREATE, HOST, DB, USER )
-    res=os.system(CALL)
-    #res = 1
-    #print "CALL:", CALL
-    print "%s res: %i" % ( NEWTABLE, res )
diff --git a/Misc/db/tests/helge/makeusers.py b/Misc/db/tests/helge/makeusers.py
deleted file mode 100755 (executable)
index a8ac623..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/python
-
-import os, sys
-
-HOST="localhost"
-USER="agenor"
-DB=""
-
-for i in range(1, 10000):
-    NEWUSER="agenor%i" % ( i, )
-    res=os.system("createuser -A -D -h %s -U %s %s" % ( HOST, USER, NEWUSER ))
-    print "%s res: %i" % ( NEWUSER, res )
diff --git a/Misc/db/tests/helge/scale/NOTES.txt b/Misc/db/tests/helge/scale/NOTES.txt
deleted file mode 100644 (file)
index 79ef9fb..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Username
-
-Utilisateur-1
-            1000
diff --git a/Misc/db/tests/helge/scale/createapts.py b/Misc/db/tests/helge/scale/createapts.py
deleted file mode 100755 (executable)
index 6e25a62..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/python
-
-import os, sys
-from datetime import datetime
-
-HOST="localhost"
-USER="postgres"
-DB="ogo"
-
-today11=1088672400
-LOGINPREFIX="Utilisateur-"
-
-# parameters: useridx, aptid, aptid, startutime, endutime, title, parts
-QUICK_TEMPLATE="""
-INSERT INTO user_%i_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  '%s', '%s', %i, %i, '%s', '%s'
-);
-"""
-
-# parameters: aptid, utcstarttime, title
-#             'BD91C454-AA65-11D8-84CA-000D93C1A604'
-#             '20040618T160000Z'
-ICAL_TEMPLATE="""BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:%s
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:%sZ
-SUMMARY:%s
-END:VEVENT
-"""
-
-# parameters: useridx, aptid, creationutime, lastmodutime, icalcontent
-BLOB_TEMPLATE="""
-INSERT INTO user_%i_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( '%s', %i, %i, 1, '%s' );
-"""
-
-BASEDATE=1072963800
-DAYFACTOR=60*60*24
-
-def createAptsForUser(login, idx):
-    print "-- User", idx, "login", login
-    for dayofyear in range(1, 365):
-        ICALID="%s-apt%i" % ( login, dayofyear )
-        
-        STARTDATE = BASEDATE + DAYFACTOR * dayofyear;
-        start = datetime.utcfromtimestamp(STARTDATE)
-        utcstarttime="%04i%02i%02iT%02i%02i00" % ( start.year, start.month,
-                                               start.day, start.hour,
-                                               start.minute )
-        TITLE="Agenor %i (%s)" % ( dayofyear, login )
-        ical=ICAL_TEMPLATE % ( ICALID, utcstarttime, TITLE )
-        print BLOB_TEMPLATE % ( idx, ICALID, today11, today11,
-                                ical )
-
-        PARTS="Laurent Pierre, Marcus Mueller, Helge Hess"
-        print QUICK_TEMPLATE % ( idx, ICALID, ICALID,
-                                 STARTDATE, STARTDATE + 3600,
-                                 TITLE, PARTS)
-        print "-- end apt"
-    print "-- end user", login
-    print ""
-    print ""
-
-for i in range(2,200):
-    createAptsForUser("%s%i" % (LOGINPREFIX, i), i)
diff --git a/Misc/db/tests/helge/scale/createfolders.py b/Misc/db/tests/helge/scale/createfolders.py
deleted file mode 100755 (executable)
index ae2f6ad..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/python
-
-import os, sys
-
-HOST="localhost"
-USER="postgres"
-DB="ogo"
-
-today11="1088672400"
-LOGINPREFIX="Utilisateur-"
-
-QUICK_TEMPLATE="""
-DROP TABLE user_%i_quick;
-CREATE TABLE user_%i_quick (
-  c_name       VARCHAR(256)    NOT NULL PRIMARY KEY,
-  uid          VARCHAR(256)    NOT NULL,
-  startdate    INT NOT NULL,
-  enddate      INT NOT NULL,
-  title        VARCHAR(1000)   NOT NULL,
-  participants VARCHAR(100000) NOT NULL
-);
-"""
-
-CONTENT_TEMPLATE="""
-DROP TABLE user_%i_blob;
-CREATE TABLE user_%i_blob (
-  c_name         VARCHAR(256)    NOT NULL PRIMARY KEY,
-  c_content      VARCHAR(100000) NOT NULL,
-  c_creationdate INT             NOT NULL,
-  c_lastmodified INT             NOT NULL,
-  c_version      INT             NOT NULL
-);
-"""
-
-# parameters: LOGINPREFIX, i, LOGINPREFIX, i, DB, i, DB, i
-FOLDERINFO_TEMPLATE="""
-DELETE FROM SOGo_folder_info WHERE c_path2='%s%i';
-INSERT INTO SOGo_folder_info 
-  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
-VALUES 
-  ( '/Users/%s%i/Calendar', 
-    'Users',
-    '%s%i',
-    'Calendar',
-     NULL,
-    'Calendar', 
-    'http://postgres:test@localhost:5432/%s/user_%i_blob',
-    'http://postgres:test@localhost:5432/%s/user_%i_quick',
-    'Appointment' );
-"""
-
-for i in range(1,1000):
-    print "-- USER: %i %s%i" %  (i, LOGINPREFIX, i )
-    print QUICK_TEMPLATE      % ( i, i, )
-    print CONTENT_TEMPLATE    % ( i, i, )
-    print FOLDERINFO_TEMPLATE % ( LOGINPREFIX, i,
-                                  LOGINPREFIX, i, LOGINPREFIX, i,
-                                  DB, i, DB, i )
-    print ""
-    print ""
-
diff --git a/Misc/db/tests/helge/scale/createindexes.py b/Misc/db/tests/helge/scale/createindexes.py
deleted file mode 100755 (executable)
index f1f9ae6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/python
-
-import os, sys
-
-HOST="localhost"
-USER="postgres"
-DB="ogo"
-
-today11="1088672400"
-LOGINPREFIX="Utilisateur-"
-
-DATERANGEIDX="""
-CREATE INDEX user_%i_daterange_idx
-  ON user_%i_quick
-  USING BTREE ( startdate, enddate );
-"""
-
-NAMEIDX="""
-CREATE INDEX user_%i_blob_name_idx
-  ON user_%i_blob
-  USING HASH ( c_name );
-"""
-
-for i in range(1,200):
-    print "-- USER: %i %s%i" %  (i, LOGINPREFIX, i )
-    print DATERANGEIDX % ( i, i, )
-    print NAMEIDX      % ( i, i, )
-    print ""
-    print ""
diff --git a/Misc/db/tests/helge/scale/makeidx1-200.psql b/Misc/db/tests/helge/scale/makeidx1-200.psql
deleted file mode 100644 (file)
index bbc6264..0000000
+++ /dev/null
@@ -1,2587 +0,0 @@
--- USER: 1 Utilisateur-1
-
-CREATE INDEX user_1_daterange_idx
-  ON user_1_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_1_blob_name_idx
-  ON user_1_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 2 Utilisateur-2
-
-CREATE INDEX user_2_daterange_idx
-  ON user_2_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_2_blob_name_idx
-  ON user_2_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 3 Utilisateur-3
-
-CREATE INDEX user_3_daterange_idx
-  ON user_3_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_3_blob_name_idx
-  ON user_3_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 4 Utilisateur-4
-
-CREATE INDEX user_4_daterange_idx
-  ON user_4_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_4_blob_name_idx
-  ON user_4_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 5 Utilisateur-5
-
-CREATE INDEX user_5_daterange_idx
-  ON user_5_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_5_blob_name_idx
-  ON user_5_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 6 Utilisateur-6
-
-CREATE INDEX user_6_daterange_idx
-  ON user_6_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_6_blob_name_idx
-  ON user_6_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 7 Utilisateur-7
-
-CREATE INDEX user_7_daterange_idx
-  ON user_7_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_7_blob_name_idx
-  ON user_7_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 8 Utilisateur-8
-
-CREATE INDEX user_8_daterange_idx
-  ON user_8_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_8_blob_name_idx
-  ON user_8_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 9 Utilisateur-9
-
-CREATE INDEX user_9_daterange_idx
-  ON user_9_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_9_blob_name_idx
-  ON user_9_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 10 Utilisateur-10
-
-CREATE INDEX user_10_daterange_idx
-  ON user_10_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_10_blob_name_idx
-  ON user_10_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 11 Utilisateur-11
-
-CREATE INDEX user_11_daterange_idx
-  ON user_11_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_11_blob_name_idx
-  ON user_11_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 12 Utilisateur-12
-
-CREATE INDEX user_12_daterange_idx
-  ON user_12_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_12_blob_name_idx
-  ON user_12_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 13 Utilisateur-13
-
-CREATE INDEX user_13_daterange_idx
-  ON user_13_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_13_blob_name_idx
-  ON user_13_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 14 Utilisateur-14
-
-CREATE INDEX user_14_daterange_idx
-  ON user_14_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_14_blob_name_idx
-  ON user_14_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 15 Utilisateur-15
-
-CREATE INDEX user_15_daterange_idx
-  ON user_15_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_15_blob_name_idx
-  ON user_15_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 16 Utilisateur-16
-
-CREATE INDEX user_16_daterange_idx
-  ON user_16_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_16_blob_name_idx
-  ON user_16_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 17 Utilisateur-17
-
-CREATE INDEX user_17_daterange_idx
-  ON user_17_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_17_blob_name_idx
-  ON user_17_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 18 Utilisateur-18
-
-CREATE INDEX user_18_daterange_idx
-  ON user_18_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_18_blob_name_idx
-  ON user_18_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 19 Utilisateur-19
-
-CREATE INDEX user_19_daterange_idx
-  ON user_19_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_19_blob_name_idx
-  ON user_19_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 20 Utilisateur-20
-
-CREATE INDEX user_20_daterange_idx
-  ON user_20_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_20_blob_name_idx
-  ON user_20_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 21 Utilisateur-21
-
-CREATE INDEX user_21_daterange_idx
-  ON user_21_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_21_blob_name_idx
-  ON user_21_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 22 Utilisateur-22
-
-CREATE INDEX user_22_daterange_idx
-  ON user_22_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_22_blob_name_idx
-  ON user_22_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 23 Utilisateur-23
-
-CREATE INDEX user_23_daterange_idx
-  ON user_23_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_23_blob_name_idx
-  ON user_23_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 24 Utilisateur-24
-
-CREATE INDEX user_24_daterange_idx
-  ON user_24_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_24_blob_name_idx
-  ON user_24_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 25 Utilisateur-25
-
-CREATE INDEX user_25_daterange_idx
-  ON user_25_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_25_blob_name_idx
-  ON user_25_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 26 Utilisateur-26
-
-CREATE INDEX user_26_daterange_idx
-  ON user_26_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_26_blob_name_idx
-  ON user_26_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 27 Utilisateur-27
-
-CREATE INDEX user_27_daterange_idx
-  ON user_27_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_27_blob_name_idx
-  ON user_27_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 28 Utilisateur-28
-
-CREATE INDEX user_28_daterange_idx
-  ON user_28_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_28_blob_name_idx
-  ON user_28_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 29 Utilisateur-29
-
-CREATE INDEX user_29_daterange_idx
-  ON user_29_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_29_blob_name_idx
-  ON user_29_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 30 Utilisateur-30
-
-CREATE INDEX user_30_daterange_idx
-  ON user_30_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_30_blob_name_idx
-  ON user_30_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 31 Utilisateur-31
-
-CREATE INDEX user_31_daterange_idx
-  ON user_31_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_31_blob_name_idx
-  ON user_31_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 32 Utilisateur-32
-
-CREATE INDEX user_32_daterange_idx
-  ON user_32_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_32_blob_name_idx
-  ON user_32_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 33 Utilisateur-33
-
-CREATE INDEX user_33_daterange_idx
-  ON user_33_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_33_blob_name_idx
-  ON user_33_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 34 Utilisateur-34
-
-CREATE INDEX user_34_daterange_idx
-  ON user_34_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_34_blob_name_idx
-  ON user_34_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 35 Utilisateur-35
-
-CREATE INDEX user_35_daterange_idx
-  ON user_35_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_35_blob_name_idx
-  ON user_35_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 36 Utilisateur-36
-
-CREATE INDEX user_36_daterange_idx
-  ON user_36_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_36_blob_name_idx
-  ON user_36_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 37 Utilisateur-37
-
-CREATE INDEX user_37_daterange_idx
-  ON user_37_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_37_blob_name_idx
-  ON user_37_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 38 Utilisateur-38
-
-CREATE INDEX user_38_daterange_idx
-  ON user_38_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_38_blob_name_idx
-  ON user_38_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 39 Utilisateur-39
-
-CREATE INDEX user_39_daterange_idx
-  ON user_39_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_39_blob_name_idx
-  ON user_39_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 40 Utilisateur-40
-
-CREATE INDEX user_40_daterange_idx
-  ON user_40_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_40_blob_name_idx
-  ON user_40_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 41 Utilisateur-41
-
-CREATE INDEX user_41_daterange_idx
-  ON user_41_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_41_blob_name_idx
-  ON user_41_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 42 Utilisateur-42
-
-CREATE INDEX user_42_daterange_idx
-  ON user_42_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_42_blob_name_idx
-  ON user_42_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 43 Utilisateur-43
-
-CREATE INDEX user_43_daterange_idx
-  ON user_43_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_43_blob_name_idx
-  ON user_43_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 44 Utilisateur-44
-
-CREATE INDEX user_44_daterange_idx
-  ON user_44_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_44_blob_name_idx
-  ON user_44_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 45 Utilisateur-45
-
-CREATE INDEX user_45_daterange_idx
-  ON user_45_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_45_blob_name_idx
-  ON user_45_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 46 Utilisateur-46
-
-CREATE INDEX user_46_daterange_idx
-  ON user_46_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_46_blob_name_idx
-  ON user_46_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 47 Utilisateur-47
-
-CREATE INDEX user_47_daterange_idx
-  ON user_47_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_47_blob_name_idx
-  ON user_47_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 48 Utilisateur-48
-
-CREATE INDEX user_48_daterange_idx
-  ON user_48_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_48_blob_name_idx
-  ON user_48_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 49 Utilisateur-49
-
-CREATE INDEX user_49_daterange_idx
-  ON user_49_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_49_blob_name_idx
-  ON user_49_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 50 Utilisateur-50
-
-CREATE INDEX user_50_daterange_idx
-  ON user_50_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_50_blob_name_idx
-  ON user_50_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 51 Utilisateur-51
-
-CREATE INDEX user_51_daterange_idx
-  ON user_51_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_51_blob_name_idx
-  ON user_51_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 52 Utilisateur-52
-
-CREATE INDEX user_52_daterange_idx
-  ON user_52_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_52_blob_name_idx
-  ON user_52_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 53 Utilisateur-53
-
-CREATE INDEX user_53_daterange_idx
-  ON user_53_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_53_blob_name_idx
-  ON user_53_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 54 Utilisateur-54
-
-CREATE INDEX user_54_daterange_idx
-  ON user_54_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_54_blob_name_idx
-  ON user_54_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 55 Utilisateur-55
-
-CREATE INDEX user_55_daterange_idx
-  ON user_55_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_55_blob_name_idx
-  ON user_55_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 56 Utilisateur-56
-
-CREATE INDEX user_56_daterange_idx
-  ON user_56_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_56_blob_name_idx
-  ON user_56_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 57 Utilisateur-57
-
-CREATE INDEX user_57_daterange_idx
-  ON user_57_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_57_blob_name_idx
-  ON user_57_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 58 Utilisateur-58
-
-CREATE INDEX user_58_daterange_idx
-  ON user_58_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_58_blob_name_idx
-  ON user_58_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 59 Utilisateur-59
-
-CREATE INDEX user_59_daterange_idx
-  ON user_59_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_59_blob_name_idx
-  ON user_59_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 60 Utilisateur-60
-
-CREATE INDEX user_60_daterange_idx
-  ON user_60_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_60_blob_name_idx
-  ON user_60_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 61 Utilisateur-61
-
-CREATE INDEX user_61_daterange_idx
-  ON user_61_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_61_blob_name_idx
-  ON user_61_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 62 Utilisateur-62
-
-CREATE INDEX user_62_daterange_idx
-  ON user_62_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_62_blob_name_idx
-  ON user_62_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 63 Utilisateur-63
-
-CREATE INDEX user_63_daterange_idx
-  ON user_63_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_63_blob_name_idx
-  ON user_63_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 64 Utilisateur-64
-
-CREATE INDEX user_64_daterange_idx
-  ON user_64_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_64_blob_name_idx
-  ON user_64_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 65 Utilisateur-65
-
-CREATE INDEX user_65_daterange_idx
-  ON user_65_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_65_blob_name_idx
-  ON user_65_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 66 Utilisateur-66
-
-CREATE INDEX user_66_daterange_idx
-  ON user_66_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_66_blob_name_idx
-  ON user_66_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 67 Utilisateur-67
-
-CREATE INDEX user_67_daterange_idx
-  ON user_67_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_67_blob_name_idx
-  ON user_67_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 68 Utilisateur-68
-
-CREATE INDEX user_68_daterange_idx
-  ON user_68_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_68_blob_name_idx
-  ON user_68_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 69 Utilisateur-69
-
-CREATE INDEX user_69_daterange_idx
-  ON user_69_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_69_blob_name_idx
-  ON user_69_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 70 Utilisateur-70
-
-CREATE INDEX user_70_daterange_idx
-  ON user_70_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_70_blob_name_idx
-  ON user_70_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 71 Utilisateur-71
-
-CREATE INDEX user_71_daterange_idx
-  ON user_71_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_71_blob_name_idx
-  ON user_71_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 72 Utilisateur-72
-
-CREATE INDEX user_72_daterange_idx
-  ON user_72_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_72_blob_name_idx
-  ON user_72_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 73 Utilisateur-73
-
-CREATE INDEX user_73_daterange_idx
-  ON user_73_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_73_blob_name_idx
-  ON user_73_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 74 Utilisateur-74
-
-CREATE INDEX user_74_daterange_idx
-  ON user_74_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_74_blob_name_idx
-  ON user_74_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 75 Utilisateur-75
-
-CREATE INDEX user_75_daterange_idx
-  ON user_75_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_75_blob_name_idx
-  ON user_75_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 76 Utilisateur-76
-
-CREATE INDEX user_76_daterange_idx
-  ON user_76_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_76_blob_name_idx
-  ON user_76_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 77 Utilisateur-77
-
-CREATE INDEX user_77_daterange_idx
-  ON user_77_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_77_blob_name_idx
-  ON user_77_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 78 Utilisateur-78
-
-CREATE INDEX user_78_daterange_idx
-  ON user_78_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_78_blob_name_idx
-  ON user_78_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 79 Utilisateur-79
-
-CREATE INDEX user_79_daterange_idx
-  ON user_79_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_79_blob_name_idx
-  ON user_79_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 80 Utilisateur-80
-
-CREATE INDEX user_80_daterange_idx
-  ON user_80_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_80_blob_name_idx
-  ON user_80_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 81 Utilisateur-81
-
-CREATE INDEX user_81_daterange_idx
-  ON user_81_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_81_blob_name_idx
-  ON user_81_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 82 Utilisateur-82
-
-CREATE INDEX user_82_daterange_idx
-  ON user_82_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_82_blob_name_idx
-  ON user_82_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 83 Utilisateur-83
-
-CREATE INDEX user_83_daterange_idx
-  ON user_83_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_83_blob_name_idx
-  ON user_83_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 84 Utilisateur-84
-
-CREATE INDEX user_84_daterange_idx
-  ON user_84_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_84_blob_name_idx
-  ON user_84_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 85 Utilisateur-85
-
-CREATE INDEX user_85_daterange_idx
-  ON user_85_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_85_blob_name_idx
-  ON user_85_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 86 Utilisateur-86
-
-CREATE INDEX user_86_daterange_idx
-  ON user_86_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_86_blob_name_idx
-  ON user_86_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 87 Utilisateur-87
-
-CREATE INDEX user_87_daterange_idx
-  ON user_87_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_87_blob_name_idx
-  ON user_87_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 88 Utilisateur-88
-
-CREATE INDEX user_88_daterange_idx
-  ON user_88_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_88_blob_name_idx
-  ON user_88_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 89 Utilisateur-89
-
-CREATE INDEX user_89_daterange_idx
-  ON user_89_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_89_blob_name_idx
-  ON user_89_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 90 Utilisateur-90
-
-CREATE INDEX user_90_daterange_idx
-  ON user_90_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_90_blob_name_idx
-  ON user_90_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 91 Utilisateur-91
-
-CREATE INDEX user_91_daterange_idx
-  ON user_91_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_91_blob_name_idx
-  ON user_91_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 92 Utilisateur-92
-
-CREATE INDEX user_92_daterange_idx
-  ON user_92_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_92_blob_name_idx
-  ON user_92_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 93 Utilisateur-93
-
-CREATE INDEX user_93_daterange_idx
-  ON user_93_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_93_blob_name_idx
-  ON user_93_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 94 Utilisateur-94
-
-CREATE INDEX user_94_daterange_idx
-  ON user_94_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_94_blob_name_idx
-  ON user_94_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 95 Utilisateur-95
-
-CREATE INDEX user_95_daterange_idx
-  ON user_95_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_95_blob_name_idx
-  ON user_95_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 96 Utilisateur-96
-
-CREATE INDEX user_96_daterange_idx
-  ON user_96_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_96_blob_name_idx
-  ON user_96_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 97 Utilisateur-97
-
-CREATE INDEX user_97_daterange_idx
-  ON user_97_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_97_blob_name_idx
-  ON user_97_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 98 Utilisateur-98
-
-CREATE INDEX user_98_daterange_idx
-  ON user_98_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_98_blob_name_idx
-  ON user_98_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 99 Utilisateur-99
-
-CREATE INDEX user_99_daterange_idx
-  ON user_99_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_99_blob_name_idx
-  ON user_99_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 100 Utilisateur-100
-
-CREATE INDEX user_100_daterange_idx
-  ON user_100_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_100_blob_name_idx
-  ON user_100_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 101 Utilisateur-101
-
-CREATE INDEX user_101_daterange_idx
-  ON user_101_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_101_blob_name_idx
-  ON user_101_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 102 Utilisateur-102
-
-CREATE INDEX user_102_daterange_idx
-  ON user_102_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_102_blob_name_idx
-  ON user_102_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 103 Utilisateur-103
-
-CREATE INDEX user_103_daterange_idx
-  ON user_103_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_103_blob_name_idx
-  ON user_103_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 104 Utilisateur-104
-
-CREATE INDEX user_104_daterange_idx
-  ON user_104_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_104_blob_name_idx
-  ON user_104_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 105 Utilisateur-105
-
-CREATE INDEX user_105_daterange_idx
-  ON user_105_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_105_blob_name_idx
-  ON user_105_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 106 Utilisateur-106
-
-CREATE INDEX user_106_daterange_idx
-  ON user_106_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_106_blob_name_idx
-  ON user_106_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 107 Utilisateur-107
-
-CREATE INDEX user_107_daterange_idx
-  ON user_107_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_107_blob_name_idx
-  ON user_107_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 108 Utilisateur-108
-
-CREATE INDEX user_108_daterange_idx
-  ON user_108_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_108_blob_name_idx
-  ON user_108_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 109 Utilisateur-109
-
-CREATE INDEX user_109_daterange_idx
-  ON user_109_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_109_blob_name_idx
-  ON user_109_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 110 Utilisateur-110
-
-CREATE INDEX user_110_daterange_idx
-  ON user_110_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_110_blob_name_idx
-  ON user_110_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 111 Utilisateur-111
-
-CREATE INDEX user_111_daterange_idx
-  ON user_111_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_111_blob_name_idx
-  ON user_111_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 112 Utilisateur-112
-
-CREATE INDEX user_112_daterange_idx
-  ON user_112_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_112_blob_name_idx
-  ON user_112_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 113 Utilisateur-113
-
-CREATE INDEX user_113_daterange_idx
-  ON user_113_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_113_blob_name_idx
-  ON user_113_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 114 Utilisateur-114
-
-CREATE INDEX user_114_daterange_idx
-  ON user_114_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_114_blob_name_idx
-  ON user_114_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 115 Utilisateur-115
-
-CREATE INDEX user_115_daterange_idx
-  ON user_115_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_115_blob_name_idx
-  ON user_115_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 116 Utilisateur-116
-
-CREATE INDEX user_116_daterange_idx
-  ON user_116_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_116_blob_name_idx
-  ON user_116_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 117 Utilisateur-117
-
-CREATE INDEX user_117_daterange_idx
-  ON user_117_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_117_blob_name_idx
-  ON user_117_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 118 Utilisateur-118
-
-CREATE INDEX user_118_daterange_idx
-  ON user_118_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_118_blob_name_idx
-  ON user_118_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 119 Utilisateur-119
-
-CREATE INDEX user_119_daterange_idx
-  ON user_119_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_119_blob_name_idx
-  ON user_119_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 120 Utilisateur-120
-
-CREATE INDEX user_120_daterange_idx
-  ON user_120_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_120_blob_name_idx
-  ON user_120_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 121 Utilisateur-121
-
-CREATE INDEX user_121_daterange_idx
-  ON user_121_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_121_blob_name_idx
-  ON user_121_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 122 Utilisateur-122
-
-CREATE INDEX user_122_daterange_idx
-  ON user_122_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_122_blob_name_idx
-  ON user_122_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 123 Utilisateur-123
-
-CREATE INDEX user_123_daterange_idx
-  ON user_123_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_123_blob_name_idx
-  ON user_123_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 124 Utilisateur-124
-
-CREATE INDEX user_124_daterange_idx
-  ON user_124_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_124_blob_name_idx
-  ON user_124_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 125 Utilisateur-125
-
-CREATE INDEX user_125_daterange_idx
-  ON user_125_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_125_blob_name_idx
-  ON user_125_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 126 Utilisateur-126
-
-CREATE INDEX user_126_daterange_idx
-  ON user_126_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_126_blob_name_idx
-  ON user_126_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 127 Utilisateur-127
-
-CREATE INDEX user_127_daterange_idx
-  ON user_127_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_127_blob_name_idx
-  ON user_127_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 128 Utilisateur-128
-
-CREATE INDEX user_128_daterange_idx
-  ON user_128_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_128_blob_name_idx
-  ON user_128_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 129 Utilisateur-129
-
-CREATE INDEX user_129_daterange_idx
-  ON user_129_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_129_blob_name_idx
-  ON user_129_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 130 Utilisateur-130
-
-CREATE INDEX user_130_daterange_idx
-  ON user_130_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_130_blob_name_idx
-  ON user_130_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 131 Utilisateur-131
-
-CREATE INDEX user_131_daterange_idx
-  ON user_131_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_131_blob_name_idx
-  ON user_131_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 132 Utilisateur-132
-
-CREATE INDEX user_132_daterange_idx
-  ON user_132_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_132_blob_name_idx
-  ON user_132_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 133 Utilisateur-133
-
-CREATE INDEX user_133_daterange_idx
-  ON user_133_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_133_blob_name_idx
-  ON user_133_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 134 Utilisateur-134
-
-CREATE INDEX user_134_daterange_idx
-  ON user_134_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_134_blob_name_idx
-  ON user_134_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 135 Utilisateur-135
-
-CREATE INDEX user_135_daterange_idx
-  ON user_135_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_135_blob_name_idx
-  ON user_135_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 136 Utilisateur-136
-
-CREATE INDEX user_136_daterange_idx
-  ON user_136_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_136_blob_name_idx
-  ON user_136_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 137 Utilisateur-137
-
-CREATE INDEX user_137_daterange_idx
-  ON user_137_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_137_blob_name_idx
-  ON user_137_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 138 Utilisateur-138
-
-CREATE INDEX user_138_daterange_idx
-  ON user_138_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_138_blob_name_idx
-  ON user_138_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 139 Utilisateur-139
-
-CREATE INDEX user_139_daterange_idx
-  ON user_139_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_139_blob_name_idx
-  ON user_139_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 140 Utilisateur-140
-
-CREATE INDEX user_140_daterange_idx
-  ON user_140_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_140_blob_name_idx
-  ON user_140_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 141 Utilisateur-141
-
-CREATE INDEX user_141_daterange_idx
-  ON user_141_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_141_blob_name_idx
-  ON user_141_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 142 Utilisateur-142
-
-CREATE INDEX user_142_daterange_idx
-  ON user_142_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_142_blob_name_idx
-  ON user_142_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 143 Utilisateur-143
-
-CREATE INDEX user_143_daterange_idx
-  ON user_143_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_143_blob_name_idx
-  ON user_143_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 144 Utilisateur-144
-
-CREATE INDEX user_144_daterange_idx
-  ON user_144_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_144_blob_name_idx
-  ON user_144_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 145 Utilisateur-145
-
-CREATE INDEX user_145_daterange_idx
-  ON user_145_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_145_blob_name_idx
-  ON user_145_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 146 Utilisateur-146
-
-CREATE INDEX user_146_daterange_idx
-  ON user_146_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_146_blob_name_idx
-  ON user_146_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 147 Utilisateur-147
-
-CREATE INDEX user_147_daterange_idx
-  ON user_147_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_147_blob_name_idx
-  ON user_147_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 148 Utilisateur-148
-
-CREATE INDEX user_148_daterange_idx
-  ON user_148_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_148_blob_name_idx
-  ON user_148_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 149 Utilisateur-149
-
-CREATE INDEX user_149_daterange_idx
-  ON user_149_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_149_blob_name_idx
-  ON user_149_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 150 Utilisateur-150
-
-CREATE INDEX user_150_daterange_idx
-  ON user_150_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_150_blob_name_idx
-  ON user_150_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 151 Utilisateur-151
-
-CREATE INDEX user_151_daterange_idx
-  ON user_151_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_151_blob_name_idx
-  ON user_151_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 152 Utilisateur-152
-
-CREATE INDEX user_152_daterange_idx
-  ON user_152_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_152_blob_name_idx
-  ON user_152_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 153 Utilisateur-153
-
-CREATE INDEX user_153_daterange_idx
-  ON user_153_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_153_blob_name_idx
-  ON user_153_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 154 Utilisateur-154
-
-CREATE INDEX user_154_daterange_idx
-  ON user_154_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_154_blob_name_idx
-  ON user_154_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 155 Utilisateur-155
-
-CREATE INDEX user_155_daterange_idx
-  ON user_155_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_155_blob_name_idx
-  ON user_155_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 156 Utilisateur-156
-
-CREATE INDEX user_156_daterange_idx
-  ON user_156_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_156_blob_name_idx
-  ON user_156_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 157 Utilisateur-157
-
-CREATE INDEX user_157_daterange_idx
-  ON user_157_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_157_blob_name_idx
-  ON user_157_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 158 Utilisateur-158
-
-CREATE INDEX user_158_daterange_idx
-  ON user_158_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_158_blob_name_idx
-  ON user_158_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 159 Utilisateur-159
-
-CREATE INDEX user_159_daterange_idx
-  ON user_159_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_159_blob_name_idx
-  ON user_159_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 160 Utilisateur-160
-
-CREATE INDEX user_160_daterange_idx
-  ON user_160_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_160_blob_name_idx
-  ON user_160_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 161 Utilisateur-161
-
-CREATE INDEX user_161_daterange_idx
-  ON user_161_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_161_blob_name_idx
-  ON user_161_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 162 Utilisateur-162
-
-CREATE INDEX user_162_daterange_idx
-  ON user_162_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_162_blob_name_idx
-  ON user_162_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 163 Utilisateur-163
-
-CREATE INDEX user_163_daterange_idx
-  ON user_163_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_163_blob_name_idx
-  ON user_163_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 164 Utilisateur-164
-
-CREATE INDEX user_164_daterange_idx
-  ON user_164_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_164_blob_name_idx
-  ON user_164_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 165 Utilisateur-165
-
-CREATE INDEX user_165_daterange_idx
-  ON user_165_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_165_blob_name_idx
-  ON user_165_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 166 Utilisateur-166
-
-CREATE INDEX user_166_daterange_idx
-  ON user_166_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_166_blob_name_idx
-  ON user_166_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 167 Utilisateur-167
-
-CREATE INDEX user_167_daterange_idx
-  ON user_167_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_167_blob_name_idx
-  ON user_167_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 168 Utilisateur-168
-
-CREATE INDEX user_168_daterange_idx
-  ON user_168_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_168_blob_name_idx
-  ON user_168_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 169 Utilisateur-169
-
-CREATE INDEX user_169_daterange_idx
-  ON user_169_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_169_blob_name_idx
-  ON user_169_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 170 Utilisateur-170
-
-CREATE INDEX user_170_daterange_idx
-  ON user_170_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_170_blob_name_idx
-  ON user_170_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 171 Utilisateur-171
-
-CREATE INDEX user_171_daterange_idx
-  ON user_171_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_171_blob_name_idx
-  ON user_171_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 172 Utilisateur-172
-
-CREATE INDEX user_172_daterange_idx
-  ON user_172_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_172_blob_name_idx
-  ON user_172_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 173 Utilisateur-173
-
-CREATE INDEX user_173_daterange_idx
-  ON user_173_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_173_blob_name_idx
-  ON user_173_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 174 Utilisateur-174
-
-CREATE INDEX user_174_daterange_idx
-  ON user_174_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_174_blob_name_idx
-  ON user_174_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 175 Utilisateur-175
-
-CREATE INDEX user_175_daterange_idx
-  ON user_175_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_175_blob_name_idx
-  ON user_175_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 176 Utilisateur-176
-
-CREATE INDEX user_176_daterange_idx
-  ON user_176_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_176_blob_name_idx
-  ON user_176_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 177 Utilisateur-177
-
-CREATE INDEX user_177_daterange_idx
-  ON user_177_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_177_blob_name_idx
-  ON user_177_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 178 Utilisateur-178
-
-CREATE INDEX user_178_daterange_idx
-  ON user_178_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_178_blob_name_idx
-  ON user_178_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 179 Utilisateur-179
-
-CREATE INDEX user_179_daterange_idx
-  ON user_179_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_179_blob_name_idx
-  ON user_179_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 180 Utilisateur-180
-
-CREATE INDEX user_180_daterange_idx
-  ON user_180_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_180_blob_name_idx
-  ON user_180_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 181 Utilisateur-181
-
-CREATE INDEX user_181_daterange_idx
-  ON user_181_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_181_blob_name_idx
-  ON user_181_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 182 Utilisateur-182
-
-CREATE INDEX user_182_daterange_idx
-  ON user_182_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_182_blob_name_idx
-  ON user_182_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 183 Utilisateur-183
-
-CREATE INDEX user_183_daterange_idx
-  ON user_183_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_183_blob_name_idx
-  ON user_183_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 184 Utilisateur-184
-
-CREATE INDEX user_184_daterange_idx
-  ON user_184_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_184_blob_name_idx
-  ON user_184_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 185 Utilisateur-185
-
-CREATE INDEX user_185_daterange_idx
-  ON user_185_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_185_blob_name_idx
-  ON user_185_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 186 Utilisateur-186
-
-CREATE INDEX user_186_daterange_idx
-  ON user_186_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_186_blob_name_idx
-  ON user_186_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 187 Utilisateur-187
-
-CREATE INDEX user_187_daterange_idx
-  ON user_187_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_187_blob_name_idx
-  ON user_187_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 188 Utilisateur-188
-
-CREATE INDEX user_188_daterange_idx
-  ON user_188_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_188_blob_name_idx
-  ON user_188_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 189 Utilisateur-189
-
-CREATE INDEX user_189_daterange_idx
-  ON user_189_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_189_blob_name_idx
-  ON user_189_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 190 Utilisateur-190
-
-CREATE INDEX user_190_daterange_idx
-  ON user_190_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_190_blob_name_idx
-  ON user_190_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 191 Utilisateur-191
-
-CREATE INDEX user_191_daterange_idx
-  ON user_191_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_191_blob_name_idx
-  ON user_191_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 192 Utilisateur-192
-
-CREATE INDEX user_192_daterange_idx
-  ON user_192_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_192_blob_name_idx
-  ON user_192_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 193 Utilisateur-193
-
-CREATE INDEX user_193_daterange_idx
-  ON user_193_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_193_blob_name_idx
-  ON user_193_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 194 Utilisateur-194
-
-CREATE INDEX user_194_daterange_idx
-  ON user_194_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_194_blob_name_idx
-  ON user_194_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 195 Utilisateur-195
-
-CREATE INDEX user_195_daterange_idx
-  ON user_195_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_195_blob_name_idx
-  ON user_195_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 196 Utilisateur-196
-
-CREATE INDEX user_196_daterange_idx
-  ON user_196_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_196_blob_name_idx
-  ON user_196_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 197 Utilisateur-197
-
-CREATE INDEX user_197_daterange_idx
-  ON user_197_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_197_blob_name_idx
-  ON user_197_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 198 Utilisateur-198
-
-CREATE INDEX user_198_daterange_idx
-  ON user_198_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_198_blob_name_idx
-  ON user_198_blob
-  USING HASH ( c_name );
-
-
-
--- USER: 199 Utilisateur-199
-
-CREATE INDEX user_199_daterange_idx
-  ON user_199_quick
-  USING BTREE ( startdate, enddate );
-
-
-CREATE INDEX user_199_blob_name_idx
-  ON user_199_blob
-  USING HASH ( c_name );
-
-
-
diff --git a/Misc/db/tests/helge/scale/user1.sql b/Misc/db/tests/helge/scale/user1.sql
deleted file mode 100644 (file)
index 5813d98..0000000
+++ /dev/null
@@ -1,9468 +0,0 @@
--- User 1 login Utilisateur-1
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt1', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt1
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040102T133000Z
-SUMMARY:Agenor 1 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt1', 'Utilisateur-1-apt1', 1073050200, 1073053800, 'Agenor 1 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt2', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt2
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040103T133000Z
-SUMMARY:Agenor 2 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt2', 'Utilisateur-1-apt2', 1073136600, 1073140200, 'Agenor 2 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt3', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt3
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040104T133000Z
-SUMMARY:Agenor 3 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt3', 'Utilisateur-1-apt3', 1073223000, 1073226600, 'Agenor 3 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt4', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt4
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040105T133000Z
-SUMMARY:Agenor 4 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt4', 'Utilisateur-1-apt4', 1073309400, 1073313000, 'Agenor 4 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt5', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt5
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040106T133000Z
-SUMMARY:Agenor 5 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt5', 'Utilisateur-1-apt5', 1073395800, 1073399400, 'Agenor 5 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt6', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt6
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040107T133000Z
-SUMMARY:Agenor 6 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt6', 'Utilisateur-1-apt6', 1073482200, 1073485800, 'Agenor 6 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt7', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt7
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040108T133000Z
-SUMMARY:Agenor 7 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt7', 'Utilisateur-1-apt7', 1073568600, 1073572200, 'Agenor 7 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt8', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt8
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040109T133000Z
-SUMMARY:Agenor 8 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt8', 'Utilisateur-1-apt8', 1073655000, 1073658600, 'Agenor 8 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt9', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt9
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040110T133000Z
-SUMMARY:Agenor 9 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt9', 'Utilisateur-1-apt9', 1073741400, 1073745000, 'Agenor 9 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt10', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt10
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040111T133000Z
-SUMMARY:Agenor 10 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt10', 'Utilisateur-1-apt10', 1073827800, 1073831400, 'Agenor 10 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt11', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt11
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040112T133000Z
-SUMMARY:Agenor 11 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt11', 'Utilisateur-1-apt11', 1073914200, 1073917800, 'Agenor 11 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt12', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt12
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040113T133000Z
-SUMMARY:Agenor 12 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt12', 'Utilisateur-1-apt12', 1074000600, 1074004200, 'Agenor 12 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt13', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt13
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040114T133000Z
-SUMMARY:Agenor 13 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt13', 'Utilisateur-1-apt13', 1074087000, 1074090600, 'Agenor 13 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt14', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt14
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040115T133000Z
-SUMMARY:Agenor 14 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt14', 'Utilisateur-1-apt14', 1074173400, 1074177000, 'Agenor 14 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt15', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt15
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040116T133000Z
-SUMMARY:Agenor 15 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt15', 'Utilisateur-1-apt15', 1074259800, 1074263400, 'Agenor 15 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt16', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt16
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040117T133000Z
-SUMMARY:Agenor 16 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt16', 'Utilisateur-1-apt16', 1074346200, 1074349800, 'Agenor 16 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt17', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt17
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040118T133000Z
-SUMMARY:Agenor 17 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt17', 'Utilisateur-1-apt17', 1074432600, 1074436200, 'Agenor 17 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt18', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt18
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040119T133000Z
-SUMMARY:Agenor 18 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt18', 'Utilisateur-1-apt18', 1074519000, 1074522600, 'Agenor 18 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt19', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt19
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040120T133000Z
-SUMMARY:Agenor 19 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt19', 'Utilisateur-1-apt19', 1074605400, 1074609000, 'Agenor 19 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt20', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt20
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040121T133000Z
-SUMMARY:Agenor 20 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt20', 'Utilisateur-1-apt20', 1074691800, 1074695400, 'Agenor 20 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt21', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt21
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040122T133000Z
-SUMMARY:Agenor 21 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt21', 'Utilisateur-1-apt21', 1074778200, 1074781800, 'Agenor 21 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt22', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt22
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040123T133000Z
-SUMMARY:Agenor 22 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt22', 'Utilisateur-1-apt22', 1074864600, 1074868200, 'Agenor 22 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt23', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt23
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040124T133000Z
-SUMMARY:Agenor 23 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt23', 'Utilisateur-1-apt23', 1074951000, 1074954600, 'Agenor 23 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt24', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt24
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040125T133000Z
-SUMMARY:Agenor 24 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt24', 'Utilisateur-1-apt24', 1075037400, 1075041000, 'Agenor 24 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt25', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt25
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040126T133000Z
-SUMMARY:Agenor 25 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt25', 'Utilisateur-1-apt25', 1075123800, 1075127400, 'Agenor 25 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt26', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt26
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040127T133000Z
-SUMMARY:Agenor 26 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt26', 'Utilisateur-1-apt26', 1075210200, 1075213800, 'Agenor 26 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt27', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt27
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040128T133000Z
-SUMMARY:Agenor 27 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt27', 'Utilisateur-1-apt27', 1075296600, 1075300200, 'Agenor 27 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt28', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt28
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040129T133000Z
-SUMMARY:Agenor 28 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt28', 'Utilisateur-1-apt28', 1075383000, 1075386600, 'Agenor 28 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt29', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt29
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040130T133000Z
-SUMMARY:Agenor 29 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt29', 'Utilisateur-1-apt29', 1075469400, 1075473000, 'Agenor 29 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt30', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt30
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040131T133000Z
-SUMMARY:Agenor 30 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt30', 'Utilisateur-1-apt30', 1075555800, 1075559400, 'Agenor 30 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt31', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt31
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040201T133000Z
-SUMMARY:Agenor 31 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt31', 'Utilisateur-1-apt31', 1075642200, 1075645800, 'Agenor 31 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt32', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt32
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040202T133000Z
-SUMMARY:Agenor 32 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt32', 'Utilisateur-1-apt32', 1075728600, 1075732200, 'Agenor 32 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt33', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt33
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040203T133000Z
-SUMMARY:Agenor 33 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt33', 'Utilisateur-1-apt33', 1075815000, 1075818600, 'Agenor 33 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt34', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt34
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040204T133000Z
-SUMMARY:Agenor 34 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt34', 'Utilisateur-1-apt34', 1075901400, 1075905000, 'Agenor 34 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt35', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt35
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040205T133000Z
-SUMMARY:Agenor 35 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt35', 'Utilisateur-1-apt35', 1075987800, 1075991400, 'Agenor 35 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt36', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt36
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040206T133000Z
-SUMMARY:Agenor 36 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt36', 'Utilisateur-1-apt36', 1076074200, 1076077800, 'Agenor 36 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt37', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt37
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040207T133000Z
-SUMMARY:Agenor 37 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt37', 'Utilisateur-1-apt37', 1076160600, 1076164200, 'Agenor 37 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt38', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt38
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040208T133000Z
-SUMMARY:Agenor 38 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt38', 'Utilisateur-1-apt38', 1076247000, 1076250600, 'Agenor 38 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt39', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt39
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040209T133000Z
-SUMMARY:Agenor 39 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt39', 'Utilisateur-1-apt39', 1076333400, 1076337000, 'Agenor 39 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt40', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt40
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040210T133000Z
-SUMMARY:Agenor 40 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt40', 'Utilisateur-1-apt40', 1076419800, 1076423400, 'Agenor 40 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt41', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt41
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040211T133000Z
-SUMMARY:Agenor 41 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt41', 'Utilisateur-1-apt41', 1076506200, 1076509800, 'Agenor 41 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt42', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt42
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040212T133000Z
-SUMMARY:Agenor 42 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt42', 'Utilisateur-1-apt42', 1076592600, 1076596200, 'Agenor 42 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt43', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt43
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040213T133000Z
-SUMMARY:Agenor 43 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt43', 'Utilisateur-1-apt43', 1076679000, 1076682600, 'Agenor 43 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt44', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt44
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040214T133000Z
-SUMMARY:Agenor 44 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt44', 'Utilisateur-1-apt44', 1076765400, 1076769000, 'Agenor 44 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt45', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt45
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040215T133000Z
-SUMMARY:Agenor 45 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt45', 'Utilisateur-1-apt45', 1076851800, 1076855400, 'Agenor 45 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt46', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt46
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040216T133000Z
-SUMMARY:Agenor 46 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt46', 'Utilisateur-1-apt46', 1076938200, 1076941800, 'Agenor 46 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt47', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt47
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040217T133000Z
-SUMMARY:Agenor 47 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt47', 'Utilisateur-1-apt47', 1077024600, 1077028200, 'Agenor 47 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt48', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt48
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040218T133000Z
-SUMMARY:Agenor 48 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt48', 'Utilisateur-1-apt48', 1077111000, 1077114600, 'Agenor 48 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt49', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt49
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040219T133000Z
-SUMMARY:Agenor 49 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt49', 'Utilisateur-1-apt49', 1077197400, 1077201000, 'Agenor 49 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt50', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt50
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040220T133000Z
-SUMMARY:Agenor 50 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt50', 'Utilisateur-1-apt50', 1077283800, 1077287400, 'Agenor 50 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt51', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt51
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040221T133000Z
-SUMMARY:Agenor 51 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt51', 'Utilisateur-1-apt51', 1077370200, 1077373800, 'Agenor 51 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt52', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt52
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040222T133000Z
-SUMMARY:Agenor 52 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt52', 'Utilisateur-1-apt52', 1077456600, 1077460200, 'Agenor 52 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt53', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt53
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040223T133000Z
-SUMMARY:Agenor 53 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt53', 'Utilisateur-1-apt53', 1077543000, 1077546600, 'Agenor 53 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt54', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt54
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040224T133000Z
-SUMMARY:Agenor 54 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt54', 'Utilisateur-1-apt54', 1077629400, 1077633000, 'Agenor 54 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt55', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt55
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040225T133000Z
-SUMMARY:Agenor 55 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt55', 'Utilisateur-1-apt55', 1077715800, 1077719400, 'Agenor 55 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt56', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt56
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040226T133000Z
-SUMMARY:Agenor 56 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt56', 'Utilisateur-1-apt56', 1077802200, 1077805800, 'Agenor 56 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt57', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt57
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040227T133000Z
-SUMMARY:Agenor 57 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt57', 'Utilisateur-1-apt57', 1077888600, 1077892200, 'Agenor 57 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt58', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt58
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040228T133000Z
-SUMMARY:Agenor 58 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt58', 'Utilisateur-1-apt58', 1077975000, 1077978600, 'Agenor 58 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt59', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt59
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040229T133000Z
-SUMMARY:Agenor 59 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt59', 'Utilisateur-1-apt59', 1078061400, 1078065000, 'Agenor 59 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt60', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt60
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040301T133000Z
-SUMMARY:Agenor 60 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt60', 'Utilisateur-1-apt60', 1078147800, 1078151400, 'Agenor 60 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt61', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt61
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040302T133000Z
-SUMMARY:Agenor 61 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt61', 'Utilisateur-1-apt61', 1078234200, 1078237800, 'Agenor 61 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt62', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt62
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040303T133000Z
-SUMMARY:Agenor 62 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt62', 'Utilisateur-1-apt62', 1078320600, 1078324200, 'Agenor 62 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt63', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt63
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040304T133000Z
-SUMMARY:Agenor 63 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt63', 'Utilisateur-1-apt63', 1078407000, 1078410600, 'Agenor 63 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt64', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt64
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040305T133000Z
-SUMMARY:Agenor 64 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt64', 'Utilisateur-1-apt64', 1078493400, 1078497000, 'Agenor 64 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt65', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt65
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040306T133000Z
-SUMMARY:Agenor 65 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt65', 'Utilisateur-1-apt65', 1078579800, 1078583400, 'Agenor 65 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt66', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt66
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040307T133000Z
-SUMMARY:Agenor 66 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt66', 'Utilisateur-1-apt66', 1078666200, 1078669800, 'Agenor 66 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt67', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt67
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040308T133000Z
-SUMMARY:Agenor 67 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt67', 'Utilisateur-1-apt67', 1078752600, 1078756200, 'Agenor 67 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt68', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt68
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040309T133000Z
-SUMMARY:Agenor 68 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt68', 'Utilisateur-1-apt68', 1078839000, 1078842600, 'Agenor 68 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt69', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt69
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040310T133000Z
-SUMMARY:Agenor 69 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt69', 'Utilisateur-1-apt69', 1078925400, 1078929000, 'Agenor 69 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt70', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt70
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040311T133000Z
-SUMMARY:Agenor 70 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt70', 'Utilisateur-1-apt70', 1079011800, 1079015400, 'Agenor 70 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt71', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt71
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040312T133000Z
-SUMMARY:Agenor 71 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt71', 'Utilisateur-1-apt71', 1079098200, 1079101800, 'Agenor 71 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt72', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt72
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040313T133000Z
-SUMMARY:Agenor 72 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt72', 'Utilisateur-1-apt72', 1079184600, 1079188200, 'Agenor 72 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt73', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt73
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040314T133000Z
-SUMMARY:Agenor 73 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt73', 'Utilisateur-1-apt73', 1079271000, 1079274600, 'Agenor 73 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt74', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt74
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040315T133000Z
-SUMMARY:Agenor 74 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt74', 'Utilisateur-1-apt74', 1079357400, 1079361000, 'Agenor 74 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt75', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt75
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040316T133000Z
-SUMMARY:Agenor 75 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt75', 'Utilisateur-1-apt75', 1079443800, 1079447400, 'Agenor 75 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt76', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt76
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040317T133000Z
-SUMMARY:Agenor 76 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt76', 'Utilisateur-1-apt76', 1079530200, 1079533800, 'Agenor 76 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt77', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt77
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040318T133000Z
-SUMMARY:Agenor 77 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt77', 'Utilisateur-1-apt77', 1079616600, 1079620200, 'Agenor 77 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt78', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt78
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040319T133000Z
-SUMMARY:Agenor 78 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt78', 'Utilisateur-1-apt78', 1079703000, 1079706600, 'Agenor 78 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt79', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt79
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040320T133000Z
-SUMMARY:Agenor 79 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt79', 'Utilisateur-1-apt79', 1079789400, 1079793000, 'Agenor 79 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt80', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt80
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040321T133000Z
-SUMMARY:Agenor 80 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt80', 'Utilisateur-1-apt80', 1079875800, 1079879400, 'Agenor 80 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt81', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt81
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040322T133000Z
-SUMMARY:Agenor 81 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt81', 'Utilisateur-1-apt81', 1079962200, 1079965800, 'Agenor 81 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt82', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt82
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040323T133000Z
-SUMMARY:Agenor 82 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt82', 'Utilisateur-1-apt82', 1080048600, 1080052200, 'Agenor 82 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt83', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt83
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040324T133000Z
-SUMMARY:Agenor 83 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt83', 'Utilisateur-1-apt83', 1080135000, 1080138600, 'Agenor 83 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt84', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt84
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040325T133000Z
-SUMMARY:Agenor 84 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt84', 'Utilisateur-1-apt84', 1080221400, 1080225000, 'Agenor 84 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt85', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt85
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040326T133000Z
-SUMMARY:Agenor 85 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt85', 'Utilisateur-1-apt85', 1080307800, 1080311400, 'Agenor 85 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt86', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt86
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040327T133000Z
-SUMMARY:Agenor 86 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt86', 'Utilisateur-1-apt86', 1080394200, 1080397800, 'Agenor 86 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt87', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt87
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040328T133000Z
-SUMMARY:Agenor 87 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt87', 'Utilisateur-1-apt87', 1080480600, 1080484200, 'Agenor 87 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt88', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt88
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040329T133000Z
-SUMMARY:Agenor 88 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt88', 'Utilisateur-1-apt88', 1080567000, 1080570600, 'Agenor 88 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt89', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt89
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040330T133000Z
-SUMMARY:Agenor 89 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt89', 'Utilisateur-1-apt89', 1080653400, 1080657000, 'Agenor 89 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt90', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt90
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040331T133000Z
-SUMMARY:Agenor 90 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt90', 'Utilisateur-1-apt90', 1080739800, 1080743400, 'Agenor 90 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt91', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt91
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040401T133000Z
-SUMMARY:Agenor 91 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt91', 'Utilisateur-1-apt91', 1080826200, 1080829800, 'Agenor 91 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt92', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt92
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040402T133000Z
-SUMMARY:Agenor 92 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt92', 'Utilisateur-1-apt92', 1080912600, 1080916200, 'Agenor 92 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt93', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt93
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040403T133000Z
-SUMMARY:Agenor 93 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt93', 'Utilisateur-1-apt93', 1080999000, 1081002600, 'Agenor 93 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt94', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt94
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040404T133000Z
-SUMMARY:Agenor 94 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt94', 'Utilisateur-1-apt94', 1081085400, 1081089000, 'Agenor 94 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt95', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt95
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040405T133000Z
-SUMMARY:Agenor 95 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt95', 'Utilisateur-1-apt95', 1081171800, 1081175400, 'Agenor 95 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt96', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt96
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040406T133000Z
-SUMMARY:Agenor 96 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt96', 'Utilisateur-1-apt96', 1081258200, 1081261800, 'Agenor 96 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt97', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt97
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040407T133000Z
-SUMMARY:Agenor 97 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt97', 'Utilisateur-1-apt97', 1081344600, 1081348200, 'Agenor 97 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt98', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt98
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040408T133000Z
-SUMMARY:Agenor 98 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt98', 'Utilisateur-1-apt98', 1081431000, 1081434600, 'Agenor 98 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt99', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt99
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040409T133000Z
-SUMMARY:Agenor 99 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt99', 'Utilisateur-1-apt99', 1081517400, 1081521000, 'Agenor 99 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt100', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt100
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040410T133000Z
-SUMMARY:Agenor 100 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt100', 'Utilisateur-1-apt100', 1081603800, 1081607400, 'Agenor 100 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt101', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt101
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040411T133000Z
-SUMMARY:Agenor 101 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt101', 'Utilisateur-1-apt101', 1081690200, 1081693800, 'Agenor 101 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt102', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt102
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040412T133000Z
-SUMMARY:Agenor 102 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt102', 'Utilisateur-1-apt102', 1081776600, 1081780200, 'Agenor 102 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt103', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt103
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040413T133000Z
-SUMMARY:Agenor 103 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt103', 'Utilisateur-1-apt103', 1081863000, 1081866600, 'Agenor 103 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt104', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt104
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040414T133000Z
-SUMMARY:Agenor 104 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt104', 'Utilisateur-1-apt104', 1081949400, 1081953000, 'Agenor 104 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt105', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt105
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040415T133000Z
-SUMMARY:Agenor 105 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt105', 'Utilisateur-1-apt105', 1082035800, 1082039400, 'Agenor 105 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt106', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt106
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040416T133000Z
-SUMMARY:Agenor 106 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt106', 'Utilisateur-1-apt106', 1082122200, 1082125800, 'Agenor 106 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt107', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt107
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040417T133000Z
-SUMMARY:Agenor 107 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt107', 'Utilisateur-1-apt107', 1082208600, 1082212200, 'Agenor 107 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt108', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt108
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040418T133000Z
-SUMMARY:Agenor 108 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt108', 'Utilisateur-1-apt108', 1082295000, 1082298600, 'Agenor 108 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt109', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt109
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040419T133000Z
-SUMMARY:Agenor 109 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt109', 'Utilisateur-1-apt109', 1082381400, 1082385000, 'Agenor 109 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt110', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt110
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040420T133000Z
-SUMMARY:Agenor 110 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt110', 'Utilisateur-1-apt110', 1082467800, 1082471400, 'Agenor 110 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt111', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt111
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040421T133000Z
-SUMMARY:Agenor 111 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt111', 'Utilisateur-1-apt111', 1082554200, 1082557800, 'Agenor 111 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt112', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt112
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040422T133000Z
-SUMMARY:Agenor 112 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt112', 'Utilisateur-1-apt112', 1082640600, 1082644200, 'Agenor 112 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt113', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt113
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040423T133000Z
-SUMMARY:Agenor 113 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt113', 'Utilisateur-1-apt113', 1082727000, 1082730600, 'Agenor 113 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt114', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt114
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040424T133000Z
-SUMMARY:Agenor 114 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt114', 'Utilisateur-1-apt114', 1082813400, 1082817000, 'Agenor 114 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt115', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt115
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040425T133000Z
-SUMMARY:Agenor 115 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt115', 'Utilisateur-1-apt115', 1082899800, 1082903400, 'Agenor 115 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt116', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt116
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040426T133000Z
-SUMMARY:Agenor 116 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt116', 'Utilisateur-1-apt116', 1082986200, 1082989800, 'Agenor 116 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt117', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt117
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040427T133000Z
-SUMMARY:Agenor 117 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt117', 'Utilisateur-1-apt117', 1083072600, 1083076200, 'Agenor 117 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt118', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt118
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040428T133000Z
-SUMMARY:Agenor 118 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt118', 'Utilisateur-1-apt118', 1083159000, 1083162600, 'Agenor 118 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt119', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt119
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040429T133000Z
-SUMMARY:Agenor 119 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt119', 'Utilisateur-1-apt119', 1083245400, 1083249000, 'Agenor 119 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt120', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt120
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040430T133000Z
-SUMMARY:Agenor 120 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt120', 'Utilisateur-1-apt120', 1083331800, 1083335400, 'Agenor 120 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt121', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt121
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040501T133000Z
-SUMMARY:Agenor 121 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt121', 'Utilisateur-1-apt121', 1083418200, 1083421800, 'Agenor 121 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt122', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt122
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040502T133000Z
-SUMMARY:Agenor 122 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt122', 'Utilisateur-1-apt122', 1083504600, 1083508200, 'Agenor 122 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt123', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt123
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040503T133000Z
-SUMMARY:Agenor 123 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt123', 'Utilisateur-1-apt123', 1083591000, 1083594600, 'Agenor 123 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt124', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt124
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040504T133000Z
-SUMMARY:Agenor 124 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt124', 'Utilisateur-1-apt124', 1083677400, 1083681000, 'Agenor 124 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt125', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt125
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040505T133000Z
-SUMMARY:Agenor 125 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt125', 'Utilisateur-1-apt125', 1083763800, 1083767400, 'Agenor 125 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt126', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt126
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040506T133000Z
-SUMMARY:Agenor 126 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt126', 'Utilisateur-1-apt126', 1083850200, 1083853800, 'Agenor 126 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt127', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt127
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040507T133000Z
-SUMMARY:Agenor 127 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt127', 'Utilisateur-1-apt127', 1083936600, 1083940200, 'Agenor 127 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt128', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt128
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040508T133000Z
-SUMMARY:Agenor 128 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt128', 'Utilisateur-1-apt128', 1084023000, 1084026600, 'Agenor 128 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt129', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt129
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040509T133000Z
-SUMMARY:Agenor 129 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt129', 'Utilisateur-1-apt129', 1084109400, 1084113000, 'Agenor 129 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt130', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt130
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040510T133000Z
-SUMMARY:Agenor 130 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt130', 'Utilisateur-1-apt130', 1084195800, 1084199400, 'Agenor 130 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt131', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt131
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040511T133000Z
-SUMMARY:Agenor 131 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt131', 'Utilisateur-1-apt131', 1084282200, 1084285800, 'Agenor 131 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt132', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt132
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040512T133000Z
-SUMMARY:Agenor 132 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt132', 'Utilisateur-1-apt132', 1084368600, 1084372200, 'Agenor 132 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt133', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt133
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040513T133000Z
-SUMMARY:Agenor 133 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt133', 'Utilisateur-1-apt133', 1084455000, 1084458600, 'Agenor 133 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt134', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt134
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040514T133000Z
-SUMMARY:Agenor 134 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt134', 'Utilisateur-1-apt134', 1084541400, 1084545000, 'Agenor 134 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt135', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt135
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040515T133000Z
-SUMMARY:Agenor 135 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt135', 'Utilisateur-1-apt135', 1084627800, 1084631400, 'Agenor 135 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt136', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt136
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040516T133000Z
-SUMMARY:Agenor 136 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt136', 'Utilisateur-1-apt136', 1084714200, 1084717800, 'Agenor 136 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt137', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt137
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040517T133000Z
-SUMMARY:Agenor 137 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt137', 'Utilisateur-1-apt137', 1084800600, 1084804200, 'Agenor 137 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt138', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt138
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040518T133000Z
-SUMMARY:Agenor 138 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt138', 'Utilisateur-1-apt138', 1084887000, 1084890600, 'Agenor 138 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt139', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt139
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040519T133000Z
-SUMMARY:Agenor 139 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt139', 'Utilisateur-1-apt139', 1084973400, 1084977000, 'Agenor 139 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt140', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt140
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040520T133000Z
-SUMMARY:Agenor 140 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt140', 'Utilisateur-1-apt140', 1085059800, 1085063400, 'Agenor 140 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt141', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt141
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040521T133000Z
-SUMMARY:Agenor 141 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt141', 'Utilisateur-1-apt141', 1085146200, 1085149800, 'Agenor 141 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt142', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt142
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040522T133000Z
-SUMMARY:Agenor 142 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt142', 'Utilisateur-1-apt142', 1085232600, 1085236200, 'Agenor 142 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt143', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt143
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040523T133000Z
-SUMMARY:Agenor 143 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt143', 'Utilisateur-1-apt143', 1085319000, 1085322600, 'Agenor 143 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt144', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt144
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040524T133000Z
-SUMMARY:Agenor 144 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt144', 'Utilisateur-1-apt144', 1085405400, 1085409000, 'Agenor 144 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt145', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt145
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040525T133000Z
-SUMMARY:Agenor 145 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt145', 'Utilisateur-1-apt145', 1085491800, 1085495400, 'Agenor 145 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt146', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt146
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040526T133000Z
-SUMMARY:Agenor 146 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt146', 'Utilisateur-1-apt146', 1085578200, 1085581800, 'Agenor 146 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt147', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt147
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040527T133000Z
-SUMMARY:Agenor 147 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt147', 'Utilisateur-1-apt147', 1085664600, 1085668200, 'Agenor 147 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt148', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt148
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040528T133000Z
-SUMMARY:Agenor 148 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt148', 'Utilisateur-1-apt148', 1085751000, 1085754600, 'Agenor 148 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt149', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt149
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040529T133000Z
-SUMMARY:Agenor 149 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt149', 'Utilisateur-1-apt149', 1085837400, 1085841000, 'Agenor 149 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt150', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt150
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040530T133000Z
-SUMMARY:Agenor 150 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt150', 'Utilisateur-1-apt150', 1085923800, 1085927400, 'Agenor 150 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt151', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt151
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040531T133000Z
-SUMMARY:Agenor 151 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt151', 'Utilisateur-1-apt151', 1086010200, 1086013800, 'Agenor 151 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt152', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt152
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040601T133000Z
-SUMMARY:Agenor 152 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt152', 'Utilisateur-1-apt152', 1086096600, 1086100200, 'Agenor 152 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt153', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt153
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040602T133000Z
-SUMMARY:Agenor 153 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt153', 'Utilisateur-1-apt153', 1086183000, 1086186600, 'Agenor 153 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt154', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt154
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040603T133000Z
-SUMMARY:Agenor 154 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt154', 'Utilisateur-1-apt154', 1086269400, 1086273000, 'Agenor 154 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt155', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt155
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040604T133000Z
-SUMMARY:Agenor 155 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt155', 'Utilisateur-1-apt155', 1086355800, 1086359400, 'Agenor 155 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt156', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt156
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040605T133000Z
-SUMMARY:Agenor 156 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt156', 'Utilisateur-1-apt156', 1086442200, 1086445800, 'Agenor 156 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt157', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt157
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040606T133000Z
-SUMMARY:Agenor 157 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt157', 'Utilisateur-1-apt157', 1086528600, 1086532200, 'Agenor 157 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt158', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt158
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040607T133000Z
-SUMMARY:Agenor 158 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt158', 'Utilisateur-1-apt158', 1086615000, 1086618600, 'Agenor 158 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt159', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt159
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040608T133000Z
-SUMMARY:Agenor 159 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt159', 'Utilisateur-1-apt159', 1086701400, 1086705000, 'Agenor 159 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt160', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt160
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040609T133000Z
-SUMMARY:Agenor 160 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt160', 'Utilisateur-1-apt160', 1086787800, 1086791400, 'Agenor 160 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt161', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt161
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040610T133000Z
-SUMMARY:Agenor 161 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt161', 'Utilisateur-1-apt161', 1086874200, 1086877800, 'Agenor 161 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt162', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt162
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040611T133000Z
-SUMMARY:Agenor 162 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt162', 'Utilisateur-1-apt162', 1086960600, 1086964200, 'Agenor 162 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt163', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt163
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040612T133000Z
-SUMMARY:Agenor 163 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt163', 'Utilisateur-1-apt163', 1087047000, 1087050600, 'Agenor 163 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt164', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt164
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040613T133000Z
-SUMMARY:Agenor 164 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt164', 'Utilisateur-1-apt164', 1087133400, 1087137000, 'Agenor 164 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt165', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt165
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040614T133000Z
-SUMMARY:Agenor 165 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt165', 'Utilisateur-1-apt165', 1087219800, 1087223400, 'Agenor 165 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt166', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt166
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040615T133000Z
-SUMMARY:Agenor 166 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt166', 'Utilisateur-1-apt166', 1087306200, 1087309800, 'Agenor 166 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt167', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt167
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040616T133000Z
-SUMMARY:Agenor 167 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt167', 'Utilisateur-1-apt167', 1087392600, 1087396200, 'Agenor 167 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt168', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt168
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040617T133000Z
-SUMMARY:Agenor 168 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt168', 'Utilisateur-1-apt168', 1087479000, 1087482600, 'Agenor 168 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt169', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt169
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040618T133000Z
-SUMMARY:Agenor 169 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt169', 'Utilisateur-1-apt169', 1087565400, 1087569000, 'Agenor 169 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt170', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt170
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040619T133000Z
-SUMMARY:Agenor 170 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt170', 'Utilisateur-1-apt170', 1087651800, 1087655400, 'Agenor 170 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt171', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt171
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040620T133000Z
-SUMMARY:Agenor 171 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt171', 'Utilisateur-1-apt171', 1087738200, 1087741800, 'Agenor 171 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt172', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt172
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040621T133000Z
-SUMMARY:Agenor 172 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt172', 'Utilisateur-1-apt172', 1087824600, 1087828200, 'Agenor 172 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt173', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt173
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040622T133000Z
-SUMMARY:Agenor 173 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt173', 'Utilisateur-1-apt173', 1087911000, 1087914600, 'Agenor 173 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt174', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt174
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040623T133000Z
-SUMMARY:Agenor 174 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt174', 'Utilisateur-1-apt174', 1087997400, 1088001000, 'Agenor 174 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt175', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt175
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040624T133000Z
-SUMMARY:Agenor 175 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt175', 'Utilisateur-1-apt175', 1088083800, 1088087400, 'Agenor 175 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt176', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt176
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040625T133000Z
-SUMMARY:Agenor 176 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt176', 'Utilisateur-1-apt176', 1088170200, 1088173800, 'Agenor 176 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt177', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt177
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040626T133000Z
-SUMMARY:Agenor 177 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt177', 'Utilisateur-1-apt177', 1088256600, 1088260200, 'Agenor 177 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt178', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt178
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040627T133000Z
-SUMMARY:Agenor 178 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt178', 'Utilisateur-1-apt178', 1088343000, 1088346600, 'Agenor 178 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt179', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt179
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040628T133000Z
-SUMMARY:Agenor 179 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt179', 'Utilisateur-1-apt179', 1088429400, 1088433000, 'Agenor 179 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt180', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt180
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040629T133000Z
-SUMMARY:Agenor 180 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt180', 'Utilisateur-1-apt180', 1088515800, 1088519400, 'Agenor 180 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt181', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt181
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040630T133000Z
-SUMMARY:Agenor 181 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt181', 'Utilisateur-1-apt181', 1088602200, 1088605800, 'Agenor 181 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt182', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt182
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040701T133000Z
-SUMMARY:Agenor 182 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt182', 'Utilisateur-1-apt182', 1088688600, 1088692200, 'Agenor 182 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt183', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt183
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040702T133000Z
-SUMMARY:Agenor 183 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt183', 'Utilisateur-1-apt183', 1088775000, 1088778600, 'Agenor 183 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt184', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt184
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040703T133000Z
-SUMMARY:Agenor 184 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt184', 'Utilisateur-1-apt184', 1088861400, 1088865000, 'Agenor 184 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt185', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt185
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040704T133000Z
-SUMMARY:Agenor 185 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt185', 'Utilisateur-1-apt185', 1088947800, 1088951400, 'Agenor 185 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt186', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt186
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040705T133000Z
-SUMMARY:Agenor 186 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt186', 'Utilisateur-1-apt186', 1089034200, 1089037800, 'Agenor 186 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt187', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt187
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040706T133000Z
-SUMMARY:Agenor 187 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt187', 'Utilisateur-1-apt187', 1089120600, 1089124200, 'Agenor 187 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt188', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt188
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040707T133000Z
-SUMMARY:Agenor 188 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt188', 'Utilisateur-1-apt188', 1089207000, 1089210600, 'Agenor 188 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt189', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt189
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040708T133000Z
-SUMMARY:Agenor 189 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt189', 'Utilisateur-1-apt189', 1089293400, 1089297000, 'Agenor 189 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt190', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt190
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040709T133000Z
-SUMMARY:Agenor 190 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt190', 'Utilisateur-1-apt190', 1089379800, 1089383400, 'Agenor 190 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt191', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt191
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040710T133000Z
-SUMMARY:Agenor 191 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt191', 'Utilisateur-1-apt191', 1089466200, 1089469800, 'Agenor 191 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt192', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt192
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040711T133000Z
-SUMMARY:Agenor 192 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt192', 'Utilisateur-1-apt192', 1089552600, 1089556200, 'Agenor 192 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt193', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt193
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040712T133000Z
-SUMMARY:Agenor 193 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt193', 'Utilisateur-1-apt193', 1089639000, 1089642600, 'Agenor 193 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt194', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt194
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040713T133000Z
-SUMMARY:Agenor 194 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt194', 'Utilisateur-1-apt194', 1089725400, 1089729000, 'Agenor 194 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt195', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt195
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040714T133000Z
-SUMMARY:Agenor 195 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt195', 'Utilisateur-1-apt195', 1089811800, 1089815400, 'Agenor 195 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt196', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt196
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040715T133000Z
-SUMMARY:Agenor 196 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt196', 'Utilisateur-1-apt196', 1089898200, 1089901800, 'Agenor 196 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt197', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt197
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040716T133000Z
-SUMMARY:Agenor 197 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt197', 'Utilisateur-1-apt197', 1089984600, 1089988200, 'Agenor 197 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt198', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt198
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040717T133000Z
-SUMMARY:Agenor 198 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt198', 'Utilisateur-1-apt198', 1090071000, 1090074600, 'Agenor 198 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt199', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt199
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040718T133000Z
-SUMMARY:Agenor 199 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt199', 'Utilisateur-1-apt199', 1090157400, 1090161000, 'Agenor 199 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt200', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt200
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040719T133000Z
-SUMMARY:Agenor 200 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt200', 'Utilisateur-1-apt200', 1090243800, 1090247400, 'Agenor 200 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt201', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt201
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040720T133000Z
-SUMMARY:Agenor 201 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt201', 'Utilisateur-1-apt201', 1090330200, 1090333800, 'Agenor 201 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt202', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt202
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040721T133000Z
-SUMMARY:Agenor 202 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt202', 'Utilisateur-1-apt202', 1090416600, 1090420200, 'Agenor 202 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt203', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt203
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040722T133000Z
-SUMMARY:Agenor 203 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt203', 'Utilisateur-1-apt203', 1090503000, 1090506600, 'Agenor 203 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt204', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt204
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040723T133000Z
-SUMMARY:Agenor 204 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt204', 'Utilisateur-1-apt204', 1090589400, 1090593000, 'Agenor 204 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt205', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt205
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040724T133000Z
-SUMMARY:Agenor 205 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt205', 'Utilisateur-1-apt205', 1090675800, 1090679400, 'Agenor 205 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt206', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt206
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040725T133000Z
-SUMMARY:Agenor 206 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt206', 'Utilisateur-1-apt206', 1090762200, 1090765800, 'Agenor 206 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt207', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt207
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040726T133000Z
-SUMMARY:Agenor 207 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt207', 'Utilisateur-1-apt207', 1090848600, 1090852200, 'Agenor 207 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt208', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt208
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040727T133000Z
-SUMMARY:Agenor 208 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt208', 'Utilisateur-1-apt208', 1090935000, 1090938600, 'Agenor 208 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt209', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt209
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040728T133000Z
-SUMMARY:Agenor 209 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt209', 'Utilisateur-1-apt209', 1091021400, 1091025000, 'Agenor 209 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt210', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt210
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040729T133000Z
-SUMMARY:Agenor 210 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt210', 'Utilisateur-1-apt210', 1091107800, 1091111400, 'Agenor 210 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt211', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt211
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040730T133000Z
-SUMMARY:Agenor 211 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt211', 'Utilisateur-1-apt211', 1091194200, 1091197800, 'Agenor 211 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt212', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt212
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040731T133000Z
-SUMMARY:Agenor 212 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt212', 'Utilisateur-1-apt212', 1091280600, 1091284200, 'Agenor 212 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt213', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt213
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040801T133000Z
-SUMMARY:Agenor 213 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt213', 'Utilisateur-1-apt213', 1091367000, 1091370600, 'Agenor 213 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt214', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt214
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040802T133000Z
-SUMMARY:Agenor 214 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt214', 'Utilisateur-1-apt214', 1091453400, 1091457000, 'Agenor 214 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt215', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt215
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040803T133000Z
-SUMMARY:Agenor 215 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt215', 'Utilisateur-1-apt215', 1091539800, 1091543400, 'Agenor 215 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt216', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt216
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040804T133000Z
-SUMMARY:Agenor 216 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt216', 'Utilisateur-1-apt216', 1091626200, 1091629800, 'Agenor 216 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt217', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt217
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040805T133000Z
-SUMMARY:Agenor 217 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt217', 'Utilisateur-1-apt217', 1091712600, 1091716200, 'Agenor 217 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt218', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt218
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040806T133000Z
-SUMMARY:Agenor 218 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt218', 'Utilisateur-1-apt218', 1091799000, 1091802600, 'Agenor 218 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt219', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt219
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040807T133000Z
-SUMMARY:Agenor 219 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt219', 'Utilisateur-1-apt219', 1091885400, 1091889000, 'Agenor 219 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt220', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt220
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040808T133000Z
-SUMMARY:Agenor 220 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt220', 'Utilisateur-1-apt220', 1091971800, 1091975400, 'Agenor 220 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt221', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt221
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040809T133000Z
-SUMMARY:Agenor 221 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt221', 'Utilisateur-1-apt221', 1092058200, 1092061800, 'Agenor 221 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt222', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt222
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040810T133000Z
-SUMMARY:Agenor 222 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt222', 'Utilisateur-1-apt222', 1092144600, 1092148200, 'Agenor 222 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt223', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt223
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040811T133000Z
-SUMMARY:Agenor 223 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt223', 'Utilisateur-1-apt223', 1092231000, 1092234600, 'Agenor 223 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt224', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt224
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040812T133000Z
-SUMMARY:Agenor 224 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt224', 'Utilisateur-1-apt224', 1092317400, 1092321000, 'Agenor 224 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt225', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt225
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040813T133000Z
-SUMMARY:Agenor 225 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt225', 'Utilisateur-1-apt225', 1092403800, 1092407400, 'Agenor 225 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt226', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt226
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040814T133000Z
-SUMMARY:Agenor 226 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt226', 'Utilisateur-1-apt226', 1092490200, 1092493800, 'Agenor 226 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt227', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt227
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040815T133000Z
-SUMMARY:Agenor 227 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt227', 'Utilisateur-1-apt227', 1092576600, 1092580200, 'Agenor 227 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt228', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt228
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040816T133000Z
-SUMMARY:Agenor 228 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt228', 'Utilisateur-1-apt228', 1092663000, 1092666600, 'Agenor 228 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt229', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt229
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040817T133000Z
-SUMMARY:Agenor 229 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt229', 'Utilisateur-1-apt229', 1092749400, 1092753000, 'Agenor 229 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt230', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt230
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040818T133000Z
-SUMMARY:Agenor 230 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt230', 'Utilisateur-1-apt230', 1092835800, 1092839400, 'Agenor 230 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt231', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt231
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040819T133000Z
-SUMMARY:Agenor 231 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt231', 'Utilisateur-1-apt231', 1092922200, 1092925800, 'Agenor 231 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt232', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt232
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040820T133000Z
-SUMMARY:Agenor 232 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt232', 'Utilisateur-1-apt232', 1093008600, 1093012200, 'Agenor 232 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt233', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt233
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040821T133000Z
-SUMMARY:Agenor 233 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt233', 'Utilisateur-1-apt233', 1093095000, 1093098600, 'Agenor 233 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt234', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt234
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040822T133000Z
-SUMMARY:Agenor 234 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt234', 'Utilisateur-1-apt234', 1093181400, 1093185000, 'Agenor 234 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt235', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt235
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040823T133000Z
-SUMMARY:Agenor 235 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt235', 'Utilisateur-1-apt235', 1093267800, 1093271400, 'Agenor 235 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt236', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt236
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040824T133000Z
-SUMMARY:Agenor 236 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt236', 'Utilisateur-1-apt236', 1093354200, 1093357800, 'Agenor 236 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt237', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt237
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040825T133000Z
-SUMMARY:Agenor 237 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt237', 'Utilisateur-1-apt237', 1093440600, 1093444200, 'Agenor 237 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt238', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt238
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040826T133000Z
-SUMMARY:Agenor 238 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt238', 'Utilisateur-1-apt238', 1093527000, 1093530600, 'Agenor 238 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt239', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt239
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040827T133000Z
-SUMMARY:Agenor 239 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt239', 'Utilisateur-1-apt239', 1093613400, 1093617000, 'Agenor 239 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt240', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt240
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040828T133000Z
-SUMMARY:Agenor 240 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt240', 'Utilisateur-1-apt240', 1093699800, 1093703400, 'Agenor 240 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt241', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt241
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040829T133000Z
-SUMMARY:Agenor 241 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt241', 'Utilisateur-1-apt241', 1093786200, 1093789800, 'Agenor 241 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt242', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt242
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040830T133000Z
-SUMMARY:Agenor 242 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt242', 'Utilisateur-1-apt242', 1093872600, 1093876200, 'Agenor 242 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt243', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt243
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040831T133000Z
-SUMMARY:Agenor 243 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt243', 'Utilisateur-1-apt243', 1093959000, 1093962600, 'Agenor 243 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt244', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt244
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040901T133000Z
-SUMMARY:Agenor 244 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt244', 'Utilisateur-1-apt244', 1094045400, 1094049000, 'Agenor 244 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt245', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt245
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040902T133000Z
-SUMMARY:Agenor 245 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt245', 'Utilisateur-1-apt245', 1094131800, 1094135400, 'Agenor 245 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt246', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt246
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040903T133000Z
-SUMMARY:Agenor 246 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt246', 'Utilisateur-1-apt246', 1094218200, 1094221800, 'Agenor 246 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt247', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt247
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040904T133000Z
-SUMMARY:Agenor 247 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt247', 'Utilisateur-1-apt247', 1094304600, 1094308200, 'Agenor 247 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt248', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt248
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040905T133000Z
-SUMMARY:Agenor 248 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt248', 'Utilisateur-1-apt248', 1094391000, 1094394600, 'Agenor 248 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt249', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt249
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040906T133000Z
-SUMMARY:Agenor 249 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt249', 'Utilisateur-1-apt249', 1094477400, 1094481000, 'Agenor 249 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt250', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt250
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040907T133000Z
-SUMMARY:Agenor 250 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt250', 'Utilisateur-1-apt250', 1094563800, 1094567400, 'Agenor 250 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt251', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt251
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040908T133000Z
-SUMMARY:Agenor 251 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt251', 'Utilisateur-1-apt251', 1094650200, 1094653800, 'Agenor 251 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt252', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt252
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040909T133000Z
-SUMMARY:Agenor 252 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt252', 'Utilisateur-1-apt252', 1094736600, 1094740200, 'Agenor 252 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt253', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt253
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040910T133000Z
-SUMMARY:Agenor 253 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt253', 'Utilisateur-1-apt253', 1094823000, 1094826600, 'Agenor 253 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt254', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt254
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040911T133000Z
-SUMMARY:Agenor 254 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt254', 'Utilisateur-1-apt254', 1094909400, 1094913000, 'Agenor 254 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt255', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt255
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040912T133000Z
-SUMMARY:Agenor 255 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt255', 'Utilisateur-1-apt255', 1094995800, 1094999400, 'Agenor 255 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt256', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt256
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040913T133000Z
-SUMMARY:Agenor 256 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt256', 'Utilisateur-1-apt256', 1095082200, 1095085800, 'Agenor 256 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt257', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt257
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040914T133000Z
-SUMMARY:Agenor 257 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt257', 'Utilisateur-1-apt257', 1095168600, 1095172200, 'Agenor 257 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt258', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt258
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040915T133000Z
-SUMMARY:Agenor 258 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt258', 'Utilisateur-1-apt258', 1095255000, 1095258600, 'Agenor 258 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt259', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt259
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040916T133000Z
-SUMMARY:Agenor 259 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt259', 'Utilisateur-1-apt259', 1095341400, 1095345000, 'Agenor 259 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt260', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt260
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040917T133000Z
-SUMMARY:Agenor 260 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt260', 'Utilisateur-1-apt260', 1095427800, 1095431400, 'Agenor 260 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt261', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt261
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040918T133000Z
-SUMMARY:Agenor 261 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt261', 'Utilisateur-1-apt261', 1095514200, 1095517800, 'Agenor 261 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt262', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt262
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040919T133000Z
-SUMMARY:Agenor 262 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt262', 'Utilisateur-1-apt262', 1095600600, 1095604200, 'Agenor 262 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt263', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt263
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040920T133000Z
-SUMMARY:Agenor 263 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt263', 'Utilisateur-1-apt263', 1095687000, 1095690600, 'Agenor 263 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt264', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt264
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040921T133000Z
-SUMMARY:Agenor 264 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt264', 'Utilisateur-1-apt264', 1095773400, 1095777000, 'Agenor 264 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt265', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt265
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040922T133000Z
-SUMMARY:Agenor 265 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt265', 'Utilisateur-1-apt265', 1095859800, 1095863400, 'Agenor 265 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt266', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt266
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040923T133000Z
-SUMMARY:Agenor 266 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt266', 'Utilisateur-1-apt266', 1095946200, 1095949800, 'Agenor 266 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt267', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt267
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040924T133000Z
-SUMMARY:Agenor 267 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt267', 'Utilisateur-1-apt267', 1096032600, 1096036200, 'Agenor 267 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt268', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt268
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040925T133000Z
-SUMMARY:Agenor 268 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt268', 'Utilisateur-1-apt268', 1096119000, 1096122600, 'Agenor 268 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt269', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt269
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040926T133000Z
-SUMMARY:Agenor 269 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt269', 'Utilisateur-1-apt269', 1096205400, 1096209000, 'Agenor 269 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt270', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt270
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040927T133000Z
-SUMMARY:Agenor 270 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt270', 'Utilisateur-1-apt270', 1096291800, 1096295400, 'Agenor 270 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt271', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt271
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040928T133000Z
-SUMMARY:Agenor 271 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt271', 'Utilisateur-1-apt271', 1096378200, 1096381800, 'Agenor 271 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt272', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt272
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040929T133000Z
-SUMMARY:Agenor 272 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt272', 'Utilisateur-1-apt272', 1096464600, 1096468200, 'Agenor 272 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt273', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt273
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20040930T133000Z
-SUMMARY:Agenor 273 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt273', 'Utilisateur-1-apt273', 1096551000, 1096554600, 'Agenor 273 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt274', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt274
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041001T133000Z
-SUMMARY:Agenor 274 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt274', 'Utilisateur-1-apt274', 1096637400, 1096641000, 'Agenor 274 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt275', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt275
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041002T133000Z
-SUMMARY:Agenor 275 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt275', 'Utilisateur-1-apt275', 1096723800, 1096727400, 'Agenor 275 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt276', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt276
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041003T133000Z
-SUMMARY:Agenor 276 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt276', 'Utilisateur-1-apt276', 1096810200, 1096813800, 'Agenor 276 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt277', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt277
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041004T133000Z
-SUMMARY:Agenor 277 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt277', 'Utilisateur-1-apt277', 1096896600, 1096900200, 'Agenor 277 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt278', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt278
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041005T133000Z
-SUMMARY:Agenor 278 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt278', 'Utilisateur-1-apt278', 1096983000, 1096986600, 'Agenor 278 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt279', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt279
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041006T133000Z
-SUMMARY:Agenor 279 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt279', 'Utilisateur-1-apt279', 1097069400, 1097073000, 'Agenor 279 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt280', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt280
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041007T133000Z
-SUMMARY:Agenor 280 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt280', 'Utilisateur-1-apt280', 1097155800, 1097159400, 'Agenor 280 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt281', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt281
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041008T133000Z
-SUMMARY:Agenor 281 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt281', 'Utilisateur-1-apt281', 1097242200, 1097245800, 'Agenor 281 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt282', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt282
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041009T133000Z
-SUMMARY:Agenor 282 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt282', 'Utilisateur-1-apt282', 1097328600, 1097332200, 'Agenor 282 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt283', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt283
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041010T133000Z
-SUMMARY:Agenor 283 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt283', 'Utilisateur-1-apt283', 1097415000, 1097418600, 'Agenor 283 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt284', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt284
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041011T133000Z
-SUMMARY:Agenor 284 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt284', 'Utilisateur-1-apt284', 1097501400, 1097505000, 'Agenor 284 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt285', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt285
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041012T133000Z
-SUMMARY:Agenor 285 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt285', 'Utilisateur-1-apt285', 1097587800, 1097591400, 'Agenor 285 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt286', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt286
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041013T133000Z
-SUMMARY:Agenor 286 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt286', 'Utilisateur-1-apt286', 1097674200, 1097677800, 'Agenor 286 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt287', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt287
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041014T133000Z
-SUMMARY:Agenor 287 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt287', 'Utilisateur-1-apt287', 1097760600, 1097764200, 'Agenor 287 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt288', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt288
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041015T133000Z
-SUMMARY:Agenor 288 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt288', 'Utilisateur-1-apt288', 1097847000, 1097850600, 'Agenor 288 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt289', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt289
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041016T133000Z
-SUMMARY:Agenor 289 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt289', 'Utilisateur-1-apt289', 1097933400, 1097937000, 'Agenor 289 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt290', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt290
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041017T133000Z
-SUMMARY:Agenor 290 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt290', 'Utilisateur-1-apt290', 1098019800, 1098023400, 'Agenor 290 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt291', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt291
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041018T133000Z
-SUMMARY:Agenor 291 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt291', 'Utilisateur-1-apt291', 1098106200, 1098109800, 'Agenor 291 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt292', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt292
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041019T133000Z
-SUMMARY:Agenor 292 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt292', 'Utilisateur-1-apt292', 1098192600, 1098196200, 'Agenor 292 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt293', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt293
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041020T133000Z
-SUMMARY:Agenor 293 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt293', 'Utilisateur-1-apt293', 1098279000, 1098282600, 'Agenor 293 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt294', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt294
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041021T133000Z
-SUMMARY:Agenor 294 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt294', 'Utilisateur-1-apt294', 1098365400, 1098369000, 'Agenor 294 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt295', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt295
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041022T133000Z
-SUMMARY:Agenor 295 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt295', 'Utilisateur-1-apt295', 1098451800, 1098455400, 'Agenor 295 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt296', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt296
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041023T133000Z
-SUMMARY:Agenor 296 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt296', 'Utilisateur-1-apt296', 1098538200, 1098541800, 'Agenor 296 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt297', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt297
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041024T133000Z
-SUMMARY:Agenor 297 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt297', 'Utilisateur-1-apt297', 1098624600, 1098628200, 'Agenor 297 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt298', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt298
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041025T133000Z
-SUMMARY:Agenor 298 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt298', 'Utilisateur-1-apt298', 1098711000, 1098714600, 'Agenor 298 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt299', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt299
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041026T133000Z
-SUMMARY:Agenor 299 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt299', 'Utilisateur-1-apt299', 1098797400, 1098801000, 'Agenor 299 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt300', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt300
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041027T133000Z
-SUMMARY:Agenor 300 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt300', 'Utilisateur-1-apt300', 1098883800, 1098887400, 'Agenor 300 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt301', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt301
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041028T133000Z
-SUMMARY:Agenor 301 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt301', 'Utilisateur-1-apt301', 1098970200, 1098973800, 'Agenor 301 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt302', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt302
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041029T133000Z
-SUMMARY:Agenor 302 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt302', 'Utilisateur-1-apt302', 1099056600, 1099060200, 'Agenor 302 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt303', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt303
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041030T133000Z
-SUMMARY:Agenor 303 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt303', 'Utilisateur-1-apt303', 1099143000, 1099146600, 'Agenor 303 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt304', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt304
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041031T133000Z
-SUMMARY:Agenor 304 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt304', 'Utilisateur-1-apt304', 1099229400, 1099233000, 'Agenor 304 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt305', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt305
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041101T133000Z
-SUMMARY:Agenor 305 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt305', 'Utilisateur-1-apt305', 1099315800, 1099319400, 'Agenor 305 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt306', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt306
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041102T133000Z
-SUMMARY:Agenor 306 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt306', 'Utilisateur-1-apt306', 1099402200, 1099405800, 'Agenor 306 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt307', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt307
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041103T133000Z
-SUMMARY:Agenor 307 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt307', 'Utilisateur-1-apt307', 1099488600, 1099492200, 'Agenor 307 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt308', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt308
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041104T133000Z
-SUMMARY:Agenor 308 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt308', 'Utilisateur-1-apt308', 1099575000, 1099578600, 'Agenor 308 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt309', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt309
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041105T133000Z
-SUMMARY:Agenor 309 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt309', 'Utilisateur-1-apt309', 1099661400, 1099665000, 'Agenor 309 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt310', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt310
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041106T133000Z
-SUMMARY:Agenor 310 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt310', 'Utilisateur-1-apt310', 1099747800, 1099751400, 'Agenor 310 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt311', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt311
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041107T133000Z
-SUMMARY:Agenor 311 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt311', 'Utilisateur-1-apt311', 1099834200, 1099837800, 'Agenor 311 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt312', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt312
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041108T133000Z
-SUMMARY:Agenor 312 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt312', 'Utilisateur-1-apt312', 1099920600, 1099924200, 'Agenor 312 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt313', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt313
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041109T133000Z
-SUMMARY:Agenor 313 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt313', 'Utilisateur-1-apt313', 1100007000, 1100010600, 'Agenor 313 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt314', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt314
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041110T133000Z
-SUMMARY:Agenor 314 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt314', 'Utilisateur-1-apt314', 1100093400, 1100097000, 'Agenor 314 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt315', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt315
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041111T133000Z
-SUMMARY:Agenor 315 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt315', 'Utilisateur-1-apt315', 1100179800, 1100183400, 'Agenor 315 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt316', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt316
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041112T133000Z
-SUMMARY:Agenor 316 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt316', 'Utilisateur-1-apt316', 1100266200, 1100269800, 'Agenor 316 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt317', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt317
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041113T133000Z
-SUMMARY:Agenor 317 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt317', 'Utilisateur-1-apt317', 1100352600, 1100356200, 'Agenor 317 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt318', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt318
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041114T133000Z
-SUMMARY:Agenor 318 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt318', 'Utilisateur-1-apt318', 1100439000, 1100442600, 'Agenor 318 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt319', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt319
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041115T133000Z
-SUMMARY:Agenor 319 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt319', 'Utilisateur-1-apt319', 1100525400, 1100529000, 'Agenor 319 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt320', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt320
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041116T133000Z
-SUMMARY:Agenor 320 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt320', 'Utilisateur-1-apt320', 1100611800, 1100615400, 'Agenor 320 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt321', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt321
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041117T133000Z
-SUMMARY:Agenor 321 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt321', 'Utilisateur-1-apt321', 1100698200, 1100701800, 'Agenor 321 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt322', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt322
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041118T133000Z
-SUMMARY:Agenor 322 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt322', 'Utilisateur-1-apt322', 1100784600, 1100788200, 'Agenor 322 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt323', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt323
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041119T133000Z
-SUMMARY:Agenor 323 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt323', 'Utilisateur-1-apt323', 1100871000, 1100874600, 'Agenor 323 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt324', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt324
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041120T133000Z
-SUMMARY:Agenor 324 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt324', 'Utilisateur-1-apt324', 1100957400, 1100961000, 'Agenor 324 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt325', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt325
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041121T133000Z
-SUMMARY:Agenor 325 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt325', 'Utilisateur-1-apt325', 1101043800, 1101047400, 'Agenor 325 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt326', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt326
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041122T133000Z
-SUMMARY:Agenor 326 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt326', 'Utilisateur-1-apt326', 1101130200, 1101133800, 'Agenor 326 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt327', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt327
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041123T133000Z
-SUMMARY:Agenor 327 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt327', 'Utilisateur-1-apt327', 1101216600, 1101220200, 'Agenor 327 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt328', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt328
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041124T133000Z
-SUMMARY:Agenor 328 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt328', 'Utilisateur-1-apt328', 1101303000, 1101306600, 'Agenor 328 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt329', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt329
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041125T133000Z
-SUMMARY:Agenor 329 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt329', 'Utilisateur-1-apt329', 1101389400, 1101393000, 'Agenor 329 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt330', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt330
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041126T133000Z
-SUMMARY:Agenor 330 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt330', 'Utilisateur-1-apt330', 1101475800, 1101479400, 'Agenor 330 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt331', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt331
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041127T133000Z
-SUMMARY:Agenor 331 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt331', 'Utilisateur-1-apt331', 1101562200, 1101565800, 'Agenor 331 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt332', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt332
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041128T133000Z
-SUMMARY:Agenor 332 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt332', 'Utilisateur-1-apt332', 1101648600, 1101652200, 'Agenor 332 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt333', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt333
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041129T133000Z
-SUMMARY:Agenor 333 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt333', 'Utilisateur-1-apt333', 1101735000, 1101738600, 'Agenor 333 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt334', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt334
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041130T133000Z
-SUMMARY:Agenor 334 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt334', 'Utilisateur-1-apt334', 1101821400, 1101825000, 'Agenor 334 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt335', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt335
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041201T133000Z
-SUMMARY:Agenor 335 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt335', 'Utilisateur-1-apt335', 1101907800, 1101911400, 'Agenor 335 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt336', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt336
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041202T133000Z
-SUMMARY:Agenor 336 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt336', 'Utilisateur-1-apt336', 1101994200, 1101997800, 'Agenor 336 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt337', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt337
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041203T133000Z
-SUMMARY:Agenor 337 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt337', 'Utilisateur-1-apt337', 1102080600, 1102084200, 'Agenor 337 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt338', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt338
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041204T133000Z
-SUMMARY:Agenor 338 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt338', 'Utilisateur-1-apt338', 1102167000, 1102170600, 'Agenor 338 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt339', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt339
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041205T133000Z
-SUMMARY:Agenor 339 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt339', 'Utilisateur-1-apt339', 1102253400, 1102257000, 'Agenor 339 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt340', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt340
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041206T133000Z
-SUMMARY:Agenor 340 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt340', 'Utilisateur-1-apt340', 1102339800, 1102343400, 'Agenor 340 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt341', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt341
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041207T133000Z
-SUMMARY:Agenor 341 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt341', 'Utilisateur-1-apt341', 1102426200, 1102429800, 'Agenor 341 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt342', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt342
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041208T133000Z
-SUMMARY:Agenor 342 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt342', 'Utilisateur-1-apt342', 1102512600, 1102516200, 'Agenor 342 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt343', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt343
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041209T133000Z
-SUMMARY:Agenor 343 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt343', 'Utilisateur-1-apt343', 1102599000, 1102602600, 'Agenor 343 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt344', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt344
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041210T133000Z
-SUMMARY:Agenor 344 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt344', 'Utilisateur-1-apt344', 1102685400, 1102689000, 'Agenor 344 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt345', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt345
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041211T133000Z
-SUMMARY:Agenor 345 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt345', 'Utilisateur-1-apt345', 1102771800, 1102775400, 'Agenor 345 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt346', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt346
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041212T133000Z
-SUMMARY:Agenor 346 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt346', 'Utilisateur-1-apt346', 1102858200, 1102861800, 'Agenor 346 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt347', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt347
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041213T133000Z
-SUMMARY:Agenor 347 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt347', 'Utilisateur-1-apt347', 1102944600, 1102948200, 'Agenor 347 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt348', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt348
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041214T133000Z
-SUMMARY:Agenor 348 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt348', 'Utilisateur-1-apt348', 1103031000, 1103034600, 'Agenor 348 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt349', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt349
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041215T133000Z
-SUMMARY:Agenor 349 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt349', 'Utilisateur-1-apt349', 1103117400, 1103121000, 'Agenor 349 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt350', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt350
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041216T133000Z
-SUMMARY:Agenor 350 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt350', 'Utilisateur-1-apt350', 1103203800, 1103207400, 'Agenor 350 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt351', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt351
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041217T133000Z
-SUMMARY:Agenor 351 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt351', 'Utilisateur-1-apt351', 1103290200, 1103293800, 'Agenor 351 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt352', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt352
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041218T133000Z
-SUMMARY:Agenor 352 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt352', 'Utilisateur-1-apt352', 1103376600, 1103380200, 'Agenor 352 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt353', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt353
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041219T133000Z
-SUMMARY:Agenor 353 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt353', 'Utilisateur-1-apt353', 1103463000, 1103466600, 'Agenor 353 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt354', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt354
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041220T133000Z
-SUMMARY:Agenor 354 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt354', 'Utilisateur-1-apt354', 1103549400, 1103553000, 'Agenor 354 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt355', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt355
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041221T133000Z
-SUMMARY:Agenor 355 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt355', 'Utilisateur-1-apt355', 1103635800, 1103639400, 'Agenor 355 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt356', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt356
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041222T133000Z
-SUMMARY:Agenor 356 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt356', 'Utilisateur-1-apt356', 1103722200, 1103725800, 'Agenor 356 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt357', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt357
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041223T133000Z
-SUMMARY:Agenor 357 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt357', 'Utilisateur-1-apt357', 1103808600, 1103812200, 'Agenor 357 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt358', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt358
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041224T133000Z
-SUMMARY:Agenor 358 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt358', 'Utilisateur-1-apt358', 1103895000, 1103898600, 'Agenor 358 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt359', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt359
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041225T133000Z
-SUMMARY:Agenor 359 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt359', 'Utilisateur-1-apt359', 1103981400, 1103985000, 'Agenor 359 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt360', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt360
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041226T133000Z
-SUMMARY:Agenor 360 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt360', 'Utilisateur-1-apt360', 1104067800, 1104071400, 'Agenor 360 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt361', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt361
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041227T133000Z
-SUMMARY:Agenor 361 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt361', 'Utilisateur-1-apt361', 1104154200, 1104157800, 'Agenor 361 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt362', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt362
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041228T133000Z
-SUMMARY:Agenor 362 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt362', 'Utilisateur-1-apt362', 1104240600, 1104244200, 'Agenor 362 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt363', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt363
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041229T133000Z
-SUMMARY:Agenor 363 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt363', 'Utilisateur-1-apt363', 1104327000, 1104330600, 'Agenor 363 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
-
-INSERT INTO user_1_blob
-  ( c_name, c_creationdate, c_lastmodified, c_version, c_content )
-VALUES
-  ( 'Utilisateur-1-apt364', 1088672400, 1088672400, 1, 'BEGIN:VEVENT
-DURATION:PT1H
-ATTENDEE;CN="Laurent Pierre":mailto:laurent@linagora.de
-ATTENDEE;CN="Marcus Mueller":mailto:mm@skyrix.com
-ATTENDEE;CN="Helge Hess":mailto:helge.hess@opengroupware.org
-DTSTAMP:20040520T140002Z
-UID:Utilisateur-1-apt364
-SEQUENCE:1
-STATUS:CONFIRMED
-DTSTART:20041230T133000Z
-SUMMARY:Agenor 364 (Utilisateur-1)
-END:VEVENT
-' );
-
-
-INSERT INTO user_1_quick
-  ( c_name, uid, startdate, enddate, title, participants )
-VALUES (
-  'Utilisateur-1-apt364', 'Utilisateur-1-apt364', 1104413400, 1104417000, 'Agenor 364 (Utilisateur-1)', 'Laurent Pierre, Marcus Mueller, Helge Hess'
-);
-
--- end apt
--- end user Utilisateur-1
-
-
diff --git a/Misc/db/tests/znek/GNUmakefile b/Misc/db/tests/znek/GNUmakefile
deleted file mode 100644 (file)
index c3c66bb..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-# $Id: GNUmakefile,v 1.2 2003/10/13 08:37:36 helge Exp $
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-TOOL_NAME = \
-       ldapPersonExporter \
-       findLongestEMailAddress \
-       personalFolderInfoInserts \
-        adaptorChannelInserts
-
-ldapPersonExporter_OBJC_FILES = lpe.m
-ldapPersonExporter_TOOL_LIBS += -lNGLdap
-
-findLongestEMailAddress_OBJC_FILES = lmail.m
-
-personalFolderInfoInserts_OBJC_FILES = pfinserts.m
-
-adaptorChannelInserts_OBJC_FILES = inserts.m NSArray+random.m
-adaptorChannelInserts_TOOL_LIBS += -lGDLAccess
-
-
--include GNUmakefile.preamble
-include $(GNUSTEP_MAKEFILES)/tool.make
--include GNUmakefile.postamble
diff --git a/Misc/db/tests/znek/GNUmakefile.preamble b/Misc/db/tests/znek/GNUmakefile.preamble
deleted file mode 100644 (file)
index b587e50..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# $Id: GNUmakefile.preamble,v 1.1.1.1 2003/07/09 22:57:26 cvs Exp $
-
-ADDITIONAL_TOOL_LIBS += \
-       -lNGExtensions  \
-       -lEOControl
diff --git a/Misc/db/tests/znek/NSArray+random.h b/Misc/db/tests/znek/NSArray+random.h
deleted file mode 100644 (file)
index bd83421..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- Copyright (C) 2004 Marcus Mueller <znek@mulle-kybernetik.com>
-
- This file is part of OGo
-
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING.  If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
- */
-// $Id$
-//  Created by znek on Fri May 21 2004.
-
-#ifndef        __NSArray_random_H_
-#define        __NSArray_random_H_
-
-#import <Foundation/Foundation.h>
-
-
-@interface NSArray (RandomExt)
-- (id)randomObject;
-@end
-
-#endif /* __NSArray_random_H_ */
diff --git a/Misc/db/tests/znek/NSArray+random.m b/Misc/db/tests/znek/NSArray+random.m
deleted file mode 100644 (file)
index 26d6d2e..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Copyright (C) 2004 Marcus Mueller <znek@mulle-kybernetik.com>
-
- This file is part of OGo
-
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING.  If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
- */
-// $Id$
-//  Created by znek on Fri May 21 2004.
-
-
-#import "NSArray+random.h"
-#include <stdlib.h>
-
-
-@implementation NSArray (RandomExt)
-
-- (id)randomObject {
-    unsigned i, count;
-    
-    count = [self count];
-    if(count == 0)
-        return nil;
-    
-    i = (unsigned)random() % count;
-    return [self objectAtIndex:i];
-}
-
-@end
diff --git a/Misc/db/tests/znek/connection.plist b/Misc/db/tests/znek/connection.plist
deleted file mode 100644 (file)
index 0e6cda4..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  hostName     = "agenor-db";
-  userName     = "agenor";
-  password     = "";
-  databaseName = "SOGo1";
-  port         = 5432;
-}
diff --git a/Misc/db/tests/znek/inserts.eomodel b/Misc/db/tests/znek/inserts.eomodel
deleted file mode 100644 (file)
index 163da29..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-{
-/*
-  CREATE TABLE SOGo_test (
-    c_id        INT PRIMARY KEY,
-    c_dir       VARCHAR(300) NOT NULL,
-    c_cn        VARCHAR(80) NOT NULL,
-    c_mailto    VARCHAR(120) NOT NULL,
-  );
-*/
-
-    EOModelVersion   = 1;
-    adaptorClassName = PostgreSQLAdaptor;
-    adaptorName      = PostgreSQL;
-
-    entities = (
-      {
-        name         = Test;
-        externalName = SOGo_test;
-        className    = EOGenericRecord;
-        primaryKeyAttributes = ( pkey );
-        attributesUsedForLocking    = ( pkey,
-                                        DIR,
-                                        CN,
-                                        mailto
-         );
-        classProperties             = ( pkey,
-                                        DIR,
-                                        CN,
-                                        mailto
-         );
-        attributes = (
-                {
-                    columnName      = "c_id";
-                    name            = "pkey";
-                    valueClassName  = "NSNumber";
-                    valueType       = i;
-                    externalType    = INT;
-                },
-                {
-                    columnName      = "c_dir";
-                    name            = "DIR";
-                    valueClassName  = "NSString";
-                    externalType    = "VARCHAR(300)";
-                    allowsNull      = N;
-                    width           = 255;
-                },
-                {
-                    columnName      = "c_cn";
-                    name            = "CN";
-                    valueClassName  = "NSString";
-                    externalType    = "VARCHAR(80)";
-                    allowsNull      = N;
-                    width           = 60;
-                },
-                {
-                    columnName      = "c_mailto";
-                    name            = "mailto";
-                    valueClassName  = "NSString";
-                    externalType    = "VARCHAR(120)";
-                    allowsNull      = N;
-                    width           = 120;
-                }
-        );
-      }
-    );
-}
diff --git a/Misc/db/tests/znek/inserts.m b/Misc/db/tests/znek/inserts.m
deleted file mode 100644 (file)
index 7287d99..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
-  @DISCLAIMER@
-*/
-// $Id$
-
-#import <Foundation/Foundation.h>
-#import <EOAccess/EOAccess.h>
-#import <NGExtensions/NGExtensions.h>
-#import "NSArray+random.h"
-
-
-#define DEBUG 0
-
-
-#define PERSON_RECORDS @"/home/znek/all-BALI.plist"
-
-
-int main(int argc, char **argv, char **env) {
-    NSAutoreleasePool *pool;
-    EOModel             *m = nil;
-    EOAdaptor           *a;
-    EOAdaptorContext    *ctx;
-    EOAdaptorChannel    *ch;
-    NSDictionary        *conDict;
-    NSUserDefaults      *ud;
-
-    pool = [[NSAutoreleasePool alloc] init];
-#if LIB_FOUNDATION_LIBRARY
-    [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
-#endif
-
-    ud = [NSUserDefaults standardUserDefaults];
-
-    conDict = [NSDictionary dictionaryWithContentsOfFile:@"connection.plist"];
-    NSLog(@"condict is %@", conDict);
-    
-    if ((a = [EOAdaptor adaptorWithName:@"PostgreSQL72"]) == nil) {
-        NSLog(@"found no PostgreSQL adaptor ..");
-        exit(1);
-    }
-
-#if DEBUG
-    NSLog(@"got adaptor %@", a);
-#endif
-    [a setConnectionDictionary:conDict];
-#if DEBUG
-    NSLog(@"got adaptor with condict %@", a);
-#endif
-
-    
-    ctx = [a   createAdaptorContext];
-    ch  = [ctx createAdaptorChannel];
-    
-    m = [[EOModel alloc] initWithContentsOfFile:@"inserts.eomodel"];
-    if (m) {
-        [a setModel:m];
-        [a setConnectionDictionary:conDict];
-    }
-    
-    
-    NSLog(@"opening channel ..");
-   
-#if DEBUG
-    [ch setDebugEnabled:YES];
-#endif
-
-    if ([ch openChannel]) {
-        NSLog(@"channel is open");
-
-#if 0
-        if ([ctx beginTransaction]) {
-            NSLog(@"began tx ..");
-#endif            
-            {
-                EOSQLQualifier *q;
-                NSArray *attrs;
-                NSString *expr;
-
-#if 1
-                NS_DURING
-
-                if([ctx beginTransaction]) {
-                    expr = @"DROP TABLE SOGo_test";
-
-                    if([ch evaluateExpression:expr]) {
-                        if([ctx commitTransaction]) {
-                            NSLog(@"DROP'ed table - committed.");
-                        } else {
-                            NSLog(@"couldn't commit DROP TABLE!");
-                        }
-                    }
-                }
-
-                NS_HANDLER
-                    
-                    NSLog(@"DROP table aborted - %@", [localException reason]);
-                    [ctx rollbackTransaction];
-                    
-                NS_ENDHANDLER
-#endif
-                
-                NS_DURING
-
-                if([ctx beginTransaction]) {
-                    expr = @"CREATE TABLE SOGo_test (c_id INT PRIMARY KEY, c_dir       VARCHAR(300) NOT NULL, c_cn VARCHAR(80) NOT NULL, c_mailto VARCHAR(120) NOT NULL);";
-                    if([ch evaluateExpression:expr]) {
-                        if([ctx commitTransaction]) {
-                            NSLog(@"CREATE TABLE - committed");
-                        } else {
-                            NSLog(@"couldn't commit CREATE TABLE!");
-                        }
-                    }
-                }
-                
-                NS_HANDLER
-
-                   fprintf(stderr, "exception: %s\n", [[localException description] cString]);
-                   abort();
-
-                NS_ENDHANDLER;
-
-                // Now for some serious business...
-                if([ctx beginTransaction]) {
-                    NSString    *path;
-                    NSArray     *allPersonRecords;
-                    unsigned    i, count;
-                    EOEntity    *e;
-                    NSArray     *attributes, *attributesNames;
-
-                    path = [ud stringForKey:@"PersonRecords"];
-                    if(path == nil)
-                        path = PERSON_RECORDS;
-                    
-                    allPersonRecords = [NSArray arrayWithContentsOfFile:path];
-                    NSCAssert([allPersonRecords count] != 0, @"allPersonRecords empty?!");
-
-                    e = [m entityNamed:@"Test"];
-                    attributes = [e attributesUsedForInsert];
-                    attributesNames = [e attributesNamesUsedForInsert];
-
-                    for(i = 0; i < 10000; i++) {
-                        NSDictionary *pdata, *values;
-                        NSMutableDictionary *row;
-                        NSAutoreleasePool *lpool = [[NSAutoreleasePool alloc] init];
-                        NSNumber *newPK;
-
-                        pdata = [allPersonRecords randomObject];
-#if DEBUG
-                        NSLog(@"pdata: %@", pdata);
-#endif
-                        newPK = [NSNumber numberWithUnsignedInt:i + 1];
-                        row = [pdata mutableCopy];
-                        [row setObject:newPK forKey:[[e primaryKeyAttributeNames] lastObject]];
-                        values = [e convertValuesToModel:row];
-#if 0
-                        pkey = [e primaryKeyForRow:values];
-                        NSLog(@"pkey: %@", pkey);
-#endif
-                        if (![ch insertRow:values forEntity:e])
-                            NSLog(@"Couldn't insert row!");
-                        [lpool release];
-                    }
-                    if([ctx commitTransaction]) {
-                        NSLog(@"INSERTS - committed");
-                    } else {
-                        NSLog(@"couldn't commit INSERTS!");
-                    }
-                } else {
-                    NSLog(@"Couldn't begin transaction?");
-                }
-            }
-#if 0
-            NSLog(@"committing tx ..");
-            if ([ctx commitTransaction])
-                NSLog(@"  could commit.");
-            else
-                NSLog(@"  commit failed.");
-       }
-#endif
-        
-        NSLog(@"closing channel ..");
-        [ch closeChannel];
-    }
-
-    
-    [m release];
-    [pool release];
-
-    exit(0);
-    return 0;
-}
diff --git a/Misc/db/tests/znek/lmail.m b/Misc/db/tests/znek/lmail.m
deleted file mode 100644 (file)
index dced490..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-  @DISCLAIMER@
-*/
-// $Id$
-
-#import <Foundation/Foundation.h>
-
-#define DEBUG 0
-
-#define ALL_RECORDS @"/home/znek/all-BALI.plist"
-
-#ifndef MAX
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif
-
-
-int main(int argc, char **argv, char **env) {
-    NSAutoreleasePool *pool;
-    NSArray *records;
-    unsigned int i, count, maxMailtoLength, maxDNLength, maxCNLength;
-    NSString *longestMailto, *longestCN, *longestDN;
-
-    pool = [[NSAutoreleasePool alloc] init];
-#if LIB_FOUNDATION_LIBRARY
-    [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
-#endif
-
-    records = [NSArray arrayWithContentsOfFile:ALL_RECORDS];
-    count = [records count];
-    maxMailtoLength = 0;
-    maxDNLength = maxCNLength = 0;
-
-    for(i = 0; i < count; i++) {
-        NSDictionary *d;
-        NSString *value;
-        unsigned length;
-
-       d = [records objectAtIndex:i];
-        value = [d objectForKey:@"mailto"];
-        length = [value length];
-        maxMailtoLength = MAX(maxMailtoLength, length);
-        if(length == maxMailtoLength)
-            longestMailto = value;
-
-        value = [d objectForKey:@"DIR"];
-        length = [value length];
-        maxDNLength = MAX(maxDNLength, length);
-        if(length == maxDNLength)
-            longestDN = value;
-
-        value = [d objectForKey:@"CN"];
-        length = [value length];
-        maxCNLength = MAX(maxCNLength, length);
-        if(length == maxCNLength)
-            longestCN = value;
-    }
-    printf("\nTotal: %d\nMaxMailtoLength: %d\nlongest: %s\nmaxDN: %d\nlongest: %s\nmaxCN: %d\nlongest: %s\n", count, maxMailtoLength, [longestMailto cString], maxDNLength, [longestDN cString], maxCNLength, [longestCN cString]);
-    [pool release];
-    exit(0);
-    return 0;
-}
diff --git a/Misc/db/tests/znek/lpe.m b/Misc/db/tests/znek/lpe.m
deleted file mode 100644 (file)
index 07f87e6..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-  @DISCLAIMER@
-*/
-// $Id$
-
-#include <EOControl/EOControl.h>
-#include <NGLdap/NGLdap.h>
-
-#define DEBUG 0
-
-#define LDAP_HOST @"localhost"
-#if DEBUG
-#define LDAP_BASE_DN @"ou=Informatique,ou=SPAG,ou=DDE 32,ou=DDE,ou=melanie,ou=organisation,dc=equipement,dc=gouv,dc=fr"
-#else
-#define LDAP_BASE_DN @"dc=equipement,dc=gouv,dc=fr"
-#endif
-
-/*
-scope = ldap.SCOPE_SUBTREE
-filter = '(mineqTypeEntree=BALI)'
-attrlist = ["mail", "sn", "givenName"]
-*/
-
-int main(int argc, char **argv, char **env) {
-    NSAutoreleasePool *pool;
-    EOQualifier *q;
-    NSArray *attrs;
-    NGLdapConnection *conn;
-    NSEnumerator *resultEnum;
-    NSMutableArray *allResults;
-    id obj;
-    int totalCount = 0;
-
-    pool = [[NSAutoreleasePool alloc] init];
-#if LIB_FOUNDATION_LIBRARY
-    [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
-#endif
-
-    q = [EOQualifier qualifierWithQualifierFormat:@"mineqTypeEntree = BALI"];
-
-    attrs = [[NSArray alloc] initWithObjects:@"sn", @"givenName", @"mail",
-nil];
-
-    conn = [[NGLdapConnection alloc] initWithHostName:LDAP_HOST];
-    [conn setUseCache:NO];
-    resultEnum = [conn deepSearchAtBaseDN:LDAP_BASE_DN
-                                qualifier:q
-                               attributes:attrs];
-
-    allResults = [[NSMutableArray alloc] initWithCapacity:60000];
-    while((obj = [resultEnum nextObject]) != nil) {
-        NSAutoreleasePool *lpool;
-        NSMutableDictionary *resultDict;
-        NSDictionary *attrDict;
-        NSString *dir, *cn;
-        NGLdapAttribute *mail, *sn, *givenName;
-
-        lpool = [[NSAutoreleasePool alloc] init];
-        attrDict = [obj attributes];
-        resultDict =
-            [[NSMutableDictionary alloc] initWithCapacity:[attrDict count] + 1];
-        dir = [NSString stringWithFormat:@"SOGo://%@", [obj dn]];
-#if DEBUG
-        NSLog(@"obj = %@", obj);
-#endif
-        [resultDict setObject:dir forKey:@"DIR"];
-        mail = [attrDict objectForKey:@"mail"];
-        [resultDict setObject:[mail stringValueAtIndex:0] forKey:@"mailto"];
-        sn = [attrDict objectForKey:@"sn"];
-        givenName = [attrDict objectForKey:@"givenName"];
-        cn = [NSString stringWithFormat:@"%@ %@", 
-                       [givenName stringValueAtIndex:0],
-                       [sn stringValueAtIndex:0]];
-        [resultDict setObject:cn forKey:@"CN"];
-        [allResults addObject:resultDict];
-        [resultDict release];
-        totalCount += 1;
-        if(totalCount % 10 == 0)
-            printf(".");
-        [lpool release];
-    }
-
-    [allResults writeToFile:@"/tmp/all.nsarray" atomically:NO];
-    [allResults release];
-    printf("\ndone.\n");
-    [attrs release];
-    [conn release];
-    [pool release];
-    exit(0);
-    return 0;
-}
diff --git a/Misc/db/tests/znek/pfinserts.m b/Misc/db/tests/znek/pfinserts.m
deleted file mode 100644 (file)
index 00d8a5d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-  @DISCLAIMER@
-*/
-// $Id$
-
-#import <Foundation/Foundation.h>
-
-#define DEBUG 0
-
-#define ALL_RECORDS @"/home/znek/all-BALI.plist"
-
-/*
-  CREATE_TABLE personalfolderinfo (
-                                  c_email     VARCHAR(128) NOT NULL, // index drauf
-                                  c_tablename VARCHAR(128) NOT NULL,
-                                  c_dbname    VARCHAR(128) NOT NULL,
-                                  c_dbport    INT NOT NULL
-                                  // kann man spaeter mit condict erweitern (user/login?)
-                                  );
-  */
-
-#define PREAMBLE @"BEGIN;\n"
-#define INSERT_FORMAT @"INSERT INTO personalfolderinfo VALUES ('%@', 'I%06d', 'SOGo1', 0);\n"
-#define POSTAMBLE @"COMMIT;\n"
-
-
-int main(int argc, char **argv, char **env) {
-    NSAutoreleasePool *pool;
-    NSArray *records;
-    unsigned int i, count, maxLength;
-    NSString *longestMailto;
-    int sequence;
-
-    pool = [[NSAutoreleasePool alloc] init];
-#if LIB_FOUNDATION_LIBRARY
-    [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
-#endif
-
-    records = [NSArray arrayWithContentsOfFile:ALL_RECORDS];
-#if DEBUG
-    count = 5;
-#else
-    count = [records count];
-#endif
-    sequence = 0;
-
-    printf([PREAMBLE cString]);
-    for(i = 0; i < count; i++) {
-        NSString *format, *mailto;
-        NSDictionary *d;
-        d = [records objectAtIndex:i];
-                       
-        mailto = [d objectForKey:@"mailto"];
-        if([mailto rangeOfString:@"'"].location != NSNotFound) {
-            NSArray *exploded;
-                                                               
-            exploded = [mailto componentsSeparatedByString:@"'"];
-            mailto = [exploded componentsJoinedByString:@"\\'"];
-        }
-        format = [[NSString alloc] initWithFormat:INSERT_FORMAT,
-                                                   mailto,
-                                               sequence++];
-                                                                                       printf([format cString]);
-        [format release];
-       }
-    printf([POSTAMBLE cString]);
-    [pool release];
-    exit(0);
-    return 0;
-}
diff --git a/Misc/db/tests/znek/tests.xcode/project.pbxproj b/Misc/db/tests/znek/tests.xcode/project.pbxproj
deleted file mode 100644 (file)
index 857cb6d..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-// !$*UTF8*$!
-{
-       archiveVersion = 1;
-       classes = {
-       };
-       objectVersion = 39;
-       objects = {
-               AD3BDFED065E3F7100D1D0A5 = {
-                       children = (
-                               AD3BDFFE065E3FBB00D1D0A5,
-                               AD3BE001065E3FC100D1D0A5,
-                       );
-                       isa = PBXGroup;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BDFEF065E3F7100D1D0A5 = {
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               COPY_PHASE_STRIP = NO;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Development;
-               };
-               AD3BDFF0065E3F7100D1D0A5 = {
-                       buildRules = (
-                       );
-                       buildSettings = {
-                               COPY_PHASE_STRIP = YES;
-                       };
-                       isa = PBXBuildStyle;
-                       name = Deployment;
-               };
-               AD3BDFF1065E3F7100D1D0A5 = {
-                       buildSettings = {
-                       };
-                       buildStyles = (
-                               AD3BDFEF065E3F7100D1D0A5,
-                               AD3BDFF0065E3F7100D1D0A5,
-                       );
-                       hasScannedForEncodings = 1;
-                       isa = PBXProject;
-                       mainGroup = AD3BDFED065E3F7100D1D0A5;
-                       projectDirPath = "";
-                       targets = (
-                       );
-               };
-               AD3BDFF7065E3FB500D1D0A5 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = GNUmakefile;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BDFF8065E3FB500D1D0A5 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = GNUmakefile.preamble;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BDFF9065E3FB500D1D0A5 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = lmail.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BDFFA065E3FB500D1D0A5 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = lpe.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BDFFB065E3FB500D1D0A5 = {
-                       fileEncoding = 30;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = pfinserts.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BDFFE065E3FBB00D1D0A5 = {
-                       children = (
-                               AD3BDFF7065E3FB500D1D0A5,
-                               AD3BDFF8065E3FB500D1D0A5,
-                       );
-                       isa = PBXGroup;
-                       name = Makefiles;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BE001065E3FC100D1D0A5 = {
-                       children = (
-                               AD3BDFF9065E3FB500D1D0A5,
-                               AD3BDFFA065E3FB500D1D0A5,
-                               AD3BDFFB065E3FB500D1D0A5,
-                               AD3BE020065E413D00D1D0A5,
-                       );
-                       isa = PBXGroup;
-                       name = Source;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BE006065E3FF500D1D0A5 = {
-                       explicitFileType = sourcecode.c.objc;
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       path = inserts.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BE020065E413D00D1D0A5 = {
-                       children = (
-                               ADFFCCE8065E6B24003E487A,
-                               AD3BE022065E41B300D1D0A5,
-                               AD3BE006065E3FF500D1D0A5,
-                               AD3BE021065E416500D1D0A5,
-                       );
-                       isa = PBXGroup;
-                       name = adaptorInserts;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BE021065E416500D1D0A5 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text;
-                       path = inserts.eomodel;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               AD3BE022065E41B300D1D0A5 = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = text.plist;
-                       path = connection.plist;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADFFCCDA065E6B1C003E487A = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = "NSArray+random.h";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADFFCCDB065E6B1C003E487A = {
-                       fileEncoding = 4;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = "NSArray+random.m";
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               ADFFCCE8065E6B24003E487A = {
-                       children = (
-                               ADFFCCDA065E6B1C003E487A,
-                               ADFFCCDB065E6B1C003E487A,
-                       );
-                       isa = PBXGroup;
-                       name = Extensions;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-       };
-       rootObject = AD3BDFF1065E3F7100D1D0A5;
-}
diff --git a/Misc/dbd/DDatabase.m b/Misc/dbd/DDatabase.m
deleted file mode 100644 (file)
index f184b3a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@class EOAdaptorChannel;
-
-@interface DDatabase : SoComponent
-{
-  EOAdaptorChannel *channel;
-  NSArray *tableNames;
-  id item;
-}
-
-@end
-
-#include "DSoDatabase.h"
-#include "common.h"
-
-@implementation DDatabase
-
-- (void)dealloc {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  [self->channel release];
-  
-  [self->tableNames release];
-  [self->item       release];
-  [super dealloc];
-}
-
-/* notifications */
-
-- (void)sleep {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  
-  [super sleep];
-}
-
-/* DB things */
-
-- (EOAdaptor *)adaptor {
-  return [(DSoDatabase *)[self clientObject] adaptorInContext:[self context]];
-}
-
-- (EOAdaptorChannel *)channel {
-  EOAdaptorContext *ctx;
-  
-  if (self->channel)
-    return self->channel;
-
-  ctx = [[self adaptor] createAdaptorContext];
-  self->channel = [[ctx createAdaptorChannel] retain];
-  if (![self->channel openChannel]) {
-    [self->channel release];
-    self->channel = nil;
-  }
-
-  return self->channel;
-}
-
-/* accessors */
-
-- (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
-}
-- (id)item {
-  return self->item;
-}
-
-- (NSArray *)tableNames {
-  if (self->tableNames == nil)
-    self->tableNames = [[[self channel] describeTableNames] copy];
-  return self->tableNames;
-}
-
-- (NSString *)tabLink {
-  // this suxx, a) we need to write code, b) we need to attach the / manually
-  return [[self item] stringByAppendingString:@"/"];
-}
-
-@end /* DDatabase */
diff --git a/Misc/dbd/DDatabase.wox b/Misc/dbd/DDatabase.wox
deleted file mode 100644 (file)
index 9a2a405..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component className="Frame" 
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
-
-Host: <a href=".."><var:string value="clientObject.hostName"/></a><br />
-Port: <var:string value="clientObject.port"/><br />
-DB:   <var:string value="clientObject.databaseName"/><br />
-
-<h4>Tables</h4>
-<var:foreach list="tableNames" item="item">
-  <li><a var:href="tabLink"><var:string value="item" /></a></li>
-</var:foreach>
-
-</var:component>
diff --git a/Misc/dbd/DDatabaseManager.m b/Misc/dbd/DDatabaseManager.m
deleted file mode 100644 (file)
index e995028..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@class EOAdaptorChannel;
-
-@interface DDatabaseManager : SoComponent
-{
-  EOAdaptorChannel *channel;
-  NSArray *databaseNames;
-  id item;
-}
-
-@end
-
-#include "DSoHost.h"
-#include "DSoDatabaseManager.h"
-#include "common.h"
-
-@interface EOAdaptorChannel(ModelFetching)
-- (NSArray *)describeDatabaseNames;
-@end
-
-@implementation DDatabaseManager
-
-- (void)dealloc {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  [self->channel release];
-  
-  [self->databaseNames release];
-  [self->item          release];
-  [super dealloc];
-}
-
-/* notifications */
-
-- (void)sleep {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  
-  [super sleep];
-}
-
-/* DB things */
-
-- (EOAdaptor *)adaptor {
-  return [[(DSoDatabaseManager *)[self clientObject] 
-                                host] adaptorInContext:[self context]];
-}
-
-- (EOAdaptorChannel *)channel {
-  EOAdaptorContext *ctx;
-  
-  if (self->channel)
-    return self->channel;
-
-  ctx = [[self adaptor] createAdaptorContext];
-  self->channel = [[ctx createAdaptorChannel] retain];
-  if (![self->channel openChannel]) {
-    [self->channel release];
-    self->channel = nil;
-  }
-
-  return self->channel;
-}
-
-/* accessors */
-
-- (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
-}
-- (id)item {
-  return self->item;
-}
-
-- (NSArray *)databaseNames {
-  if (self->databaseNames == nil)
-    self->databaseNames = [[[self channel] describeDatabaseNames] copy];
-  return self->databaseNames;
-}
-
-- (NSString *)dbLink {
-  // this suxx, a) we need to write code, b) we need to attach the / manually
-  return [[self item] stringByAppendingString:@"/"];
-}
-
-@end /* DDatabaseManager */
diff --git a/Misc/dbd/DDatabaseManager.wox b/Misc/dbd/DDatabaseManager.wox
deleted file mode 100644 (file)
index 16362b3..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component className="Frame" 
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
-
-Host: <var:string value="clientObject.host.hostName"/><br />
-Port: <var:string value="clientObject.host.port"/><br />
-
-<h4>Databases</h4>
-<var:foreach list="databaseNames" item="item">
-  <li><a var:href="dbLink"><var:string value="item" /></a></li>
-</var:foreach>
-
-<hr />
-<a href="../Users/">Users</a>
-
-</var:component>
diff --git a/Misc/dbd/DHostView.m b/Misc/dbd/DHostView.m
deleted file mode 100644 (file)
index ed6f1d9..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@class EOAdaptorChannel;
-
-@interface DHostView : SoComponent
-{
-  EOAdaptorChannel *channel;
-  NSArray *userNames;
-  NSArray *databaseNames;
-  id item;
-}
-
-@end
-
-#include "DSoHost.h"
-#include "common.h"
-
-@interface EOAdaptorChannel(ModelFetching)
-- (NSArray *)describeUserNames;
-- (NSArray *)describeDatabaseNames;
-@end
-
-@implementation DHostView
-
-- (void)dealloc {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  [self->channel release];
-  
-  [self->userNames     release];
-  [self->databaseNames release];
-  [self->item          release];
-  [super dealloc];
-}
-
-/* notifications */
-
-- (void)sleep {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  
-  [super sleep];
-}
-
-/* DB things */
-
-- (EOAdaptor *)adaptor {
-  return [(DSoHost *)[self clientObject] adaptorInContext:[self context]];
-}
-
-- (EOAdaptorChannel *)channel {
-  EOAdaptorContext *ctx;
-  
-  if (self->channel)
-    return self->channel;
-
-  ctx = [[self adaptor] createAdaptorContext];
-  self->channel = [[ctx createAdaptorChannel] retain];
-  if (![self->channel openChannel]) {
-    [self->channel release];
-    self->channel = nil;
-  }
-
-  return self->channel;
-}
-
-/* accessors */
-
-- (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
-}
-- (id)item {
-  return self->item;
-}
-
-- (NSArray *)userNames {
-  if (self->userNames == nil)
-    self->userNames = [[[self channel] describeUserNames] copy];
-  return self->userNames;
-}
-
-- (NSArray *)databaseNames {
-  if (self->databaseNames == nil)
-    self->databaseNames = [[[self channel] describeDatabaseNames] copy];
-  return self->databaseNames;
-}
-
-/* derived accessors */
-
-// Note: it suxx that we need to write code for that ...
-
-- (NSString *)dbLink {
-  return [[@"Databases/" stringByAppendingString:[self item]]
-                        stringByAppendingString:@"/"];
-}
-- (NSString *)userLink {
-  return [[@"Users/" stringByAppendingString:[self item]]
-                    stringByAppendingString:@"/"];
-}
-
-@end /* DHostView */
diff --git a/Misc/dbd/DHostView.wox b/Misc/dbd/DHostView.wox
deleted file mode 100644 (file)
index 984fef0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component className="Frame" 
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
-
-Host: <var:string value="clientObject.hostName"/><br />
-Port: <var:string value="clientObject.port"/><br />
-
-<h4><a href="Databases/">Databases</a></h4>
-<var:foreach list="databaseNames" item="item">
-  <li><a var:href="dbLink"><var:string value="item" /></a></li>
-</var:foreach>
-
-<h4><a href="Users/">Users</a></h4>
-<var:foreach list="userNames" item="item">
-  <li><a var:href="userLink"><var:string value="item" /></a></li>
-</var:foreach>
-
-</var:component>
diff --git a/Misc/dbd/DSoAuthenticator.h b/Misc/dbd/DSoAuthenticator.h
deleted file mode 100644 (file)
index 263761c..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#ifndef __dbd_DSoAuthenticator_H__
-#define __dbd_DSoAuthenticator_H__
-
-#include <NGObjWeb/SoHTTPAuthenticator.h>
-
-/*
-  DSoAuthenticator
-  
-  Authenticator based on PostgreSQL authentication.
-*/
-
-@interface DSoAuthenticator : SoHTTPAuthenticator
-{
-  NSString *hostname;
-  int      port;
-  NSString *dbname;
-}
-
-+ (id)authenticatorWithHostName:(NSString *)_hostname port:(int)_port;
-+ (id)authenticatorWithHostName:(NSString *)_hostname port:(int)_port
-  databaseName:(NSString *)_dbname;
-
-@end
-
-#endif /* __dbd_DSoAuthenticator_H__ */
diff --git a/Misc/dbd/DSoAuthenticator.m b/Misc/dbd/DSoAuthenticator.m
deleted file mode 100644 (file)
index 1fdc38d..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoAuthenticator.h"
-#include "common.h"
-#include <GDLAccess/GDLAccess.h>
-
-/*
-  Things to note:
-  - authenticators themselves are _not_ bound to a context or a SOPE
-    traversal path
-    - because of that we need to duplicate some stuff
-      => or use a separate layer which handles uniquing
-*/
-
-@implementation DSoAuthenticator
-
-static BOOL debugOn = NO;
-
-// TODO: might want to cache authenticator objects ...
-
-- (id)initWithHostName:(NSString *)_hostname port:(int)_port
-  databaseName:(NSString *)_dbname
-{
-  if ((self = [super init])) {
-    self->hostname = [_hostname copy];
-    self->port     = _port;
-    self->dbname   = [_dbname copy];
-  }
-  return self;
-}
-
-+ (id)authenticatorWithHostName:(NSString *)_hostname port:(int)_port {
-  return [[[self alloc] initWithHostName:_hostname port:_port 
-                       databaseName:nil] autorelease];
-}
-+ (id)authenticatorWithHostName:(NSString *)_hostname port:(int)_port
-  databaseName:(NSString *)_dbname
-{
-  return [[[self alloc] initWithHostName:_hostname port:_port 
-                       databaseName:_dbname] autorelease];
-}
-
-- (void)dealloc {
-  [self->hostname release];
-  [self->dbname   release];
-  [super dealloc];
-}
-
-/* realm */
-
-- (NSString *)authRealm {
-  /* 
-     the HTTP authentication realm, we use the database info (default is the 
-     application name, but in our case we can be more specific)
-  */
-  if (self->dbname == nil)
-    return self->hostname;
-  
-  return [[self->dbname stringByAppendingString:@"@"]
-                       stringByAppendingString:self->hostname];
-}
-
-/* adaptor setup */
-
-- (NSString *)defaultDatabase {
-  /* template1 is supposed to exist always (#postgresql channel ;-) */
-  return @"template1";
-}
-
-- (EOAdaptor *)adaptorForLogin:(NSString *)_login password:(NSString *)_pwd {
-  EOAdaptor    *adaptor;
-  NSDictionary *condict;
-  NSString     *dbn;
-  
-  if ((adaptor = [EOAdaptor adaptorWithName:@"PostgreSQL72"]) == nil)
-    return nil;
-
-  if (![_login isNotNull]) _login = @"";
-  if (![_pwd   isNotNull]) _pwd   = @"";
-
-  dbn = [self->dbname isNotNull] ? self->dbname : [self defaultDatabase];
-  
-  // TODO: ignores port
-  condict = [[NSDictionary alloc] initWithObjectsAndKeys:
-                                   self->hostname, @"hostName",
-                                   _login,         @"userName",
-                                   _pwd,           @"password",
-                                   dbn,            @"databaseName",
-                                 nil];
-  [adaptor setConnectionDictionary:condict];
-  [condict release];
-  return adaptor;
-}
-
-/* check credentials */
-
-- (BOOL)checkLogin:(NSString *)_login password:(NSString *)_pwd {
-  EOAdaptor        *adaptor;
-  EOAdaptorContext *adctx;
-  EOAdaptorChannel *adch;
-  BOOL             ok;
-  
-  [self debugWithFormat:@"check login: %@", _login];
-  
-  /* create all necessary objects */
-  
-  adaptor = [self    adaptorForLogin:_login password:_pwd];
-  adctx   = [adaptor createAdaptorContext];
-  adch    = [adctx   createAdaptorChannel];
-  
-  [self debugWithFormat:@"  channel: %@", adch];
-  
-  /* open channel to check whether credentials are valid */
-  
-  if ((ok = [adch openChannel]))
-    [adch closeChannel];
-  else
-    [self debugWithFormat:@"could not open the channel."];
-  
-  return ok;
-}
-
-/* debugging */
-
-- (BOOL)isDebuggingEnabled {
-  return debugOn;
-}
-
-@end /* DSoAuthenticator */
diff --git a/Misc/dbd/DSoDatabase.m b/Misc/dbd/DSoDatabase.m
deleted file mode 100644 (file)
index b848a1c..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoDatabase.h"
-#include "DSoTable.h"
-#include "DSoAuthenticator.h"
-#include "common.h"
-
-// TODO: PG databases do have an owner!
-// TODO: PG databases have an ACL
-
-@implementation DSoDatabase
-
-- (id)initWithHostName:(NSString *)_hostname port:(int)_port 
-  databaseName:(NSString *)_dbname
-{
-  if ((self = [super init])) {
-    self->hostName     = [_hostname copy];
-    self->databaseName = [_dbname copy];
-    self->port         = _port > 0 ? _port : 5432;
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->databaseName release];
-  [self->hostName     release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (NSString *)hostName {
-  return self->hostName;
-}
-- (int)port {
-  return self->port;
-}
-
-- (NSString *)databaseName {
-  return self->databaseName;
-}
-
-// TODO: add baseURL generation
-
-/* support */
-
-- (EOAdaptor *)adaptorInContext:(WOContext *)_ctx {
-  return [self adaptorForHostName:[self hostName] port:[self port]
-              databaseName:[self databaseName] inContext:_ctx];
-}
-
-/* authentication */
-
-- (id)authenticatorInContext:(id)_ctx {
-  return [DSoAuthenticator authenticatorWithHostName:[self hostName]
-                          port:[self port] databaseName:[self databaseName]];
-}
-
-/* name lookup */
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
-  id obj;
-  
-  /* 
-     Note: acquire:NO - otherwise acquired stuff will override the stuff
-           below!
-  */
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
-    return obj;
-  
-  obj = [[DSoTable alloc] initWithName:_key inContainer:self];
-  return [obj autorelease];
-}
-
-@end /* DSoDatabase */
diff --git a/Misc/dbd/DSoDatabaseManager.h b/Misc/dbd/DSoDatabaseManager.h
deleted file mode 100644 (file)
index 3aadcdd..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#ifndef __dbd_DSoDatabaseManager_H__
-#define __dbd_DSoDatabaseManager_H__
-
-#include "DSoObject.h"
-
-@class DSoHost;
-
-@interface DSoDatabaseManager : DSoObject
-{
-  DSoHost *host;
-}
-
-- (id)initWithContainer:(DSoHost *)_container;
-
-/* accessors */
-
-- (DSoHost *)host;
-
-@end
-
-#endif /* __dbd_DSoDatabaseManager_H__ */
diff --git a/Misc/dbd/DSoDatabaseManager.m b/Misc/dbd/DSoDatabaseManager.m
deleted file mode 100644 (file)
index c99b933..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoDatabaseManager.h"
-#include "DSoDatabase.h"
-#include "DSoHost.h"
-#include "common.h"
-
-@implementation DSoDatabaseManager
-
-- (id)initWithContainer:(DSoHost *)_container {
-  if ((self = [super init])) {
-    self->host = [_container retain];
-  }
-  return self;
-}
-- (id)init {
-  return [self initWithContainer:nil];
-}
-
-- (void)dealloc {
-  [self->host release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (DSoHost *)host {
-  return self->host;
-}
-
-- (id)container {
-  return [self host];
-}
-- (NSString *)nameInContainer {
-  return @"Databases";
-}
-
-/* name lookup */
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
-  id obj;
-  
-  /* 
-     Note: acquire:NO - otherwise acquired stuff will override the stuff
-           below!
-  */
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
-    return obj;
-  
-  obj = [[DSoDatabase alloc] initWithHostName:[self->host hostName]
-                            port:[self->host port]
-                            databaseName:_key];
-  return [obj autorelease];
-}
-
-@end /* DSoDatabaseManager */
diff --git a/Misc/dbd/DSoField.m b/Misc/dbd/DSoField.m
deleted file mode 100644 (file)
index 2d3a57a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoField.h"
-#include "common.h"
-
-@implementation DSoField
-
-- (void)dealloc {
-  [super dealloc];
-}
-
-@end /* DSoField */
diff --git a/Misc/dbd/DSoHost.m b/Misc/dbd/DSoHost.m
deleted file mode 100644 (file)
index b0038db..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoHost.h"
-#include "DSoAuthenticator.h"
-#include "DSoDatabaseManager.h"
-#include "DSoUserManager.h"
-#include "common.h"
-
-@implementation DSoHost
-
-+ (id)dHostWithName:(NSString *)_key port:(int)_port {
-  return [[[self alloc] initWithHostName:_key port:_port] autorelease];
-}
-- (id)initWithHostName:(NSString *)_key port:(int)_port {
-  if ((self = [super init])) {
-    self->hostName = [_key copy];
-    self->port     = _port > 0 ? _port : 5432;
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->hostName release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (NSString *)hostName {
-  return self->hostName;
-}
-- (int)port {
-  return self->port;
-}
-
-/* support */
-
-- (EOAdaptor *)adaptorInContext:(WOContext *)_ctx {
-  return [self adaptorForHostName:[self hostName] port:[self port]
-              databaseName:nil inContext:_ctx];
-}
-
-/* authentication */
-
-- (id)authenticatorInContext:(id)_ctx {
-  return [DSoAuthenticator authenticatorWithHostName:[self hostName]
-                          port:[self port]];
-}
-
-/* names */
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
-  /* We only need to deal with two fix keys here :-) */
-  if ([_key isEqualToString:@"Databases"])
-    return [[[DSoDatabaseManager alloc] initWithContainer:self] autorelease];
-  if ([_key isEqualToString:@"Users"])
-    return [[[DSoUserManager alloc] initWithContainer:self] autorelease];
-  
-  return [super lookupName:_key inContext:_ctx acquire:_flag];
-}
-
-@end /* DSoHost */
diff --git a/Misc/dbd/DSoObject.h b/Misc/dbd/DSoObject.h
deleted file mode 100644 (file)
index 4c8ae95..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#ifndef __dbd_DSoObject_H__
-#define __dbd_DSoObject_H__
-
-#import <Foundation/NSObject.h>
-
-@class NSString;
-@class EOAdaptor;
-@class WOContext;
-
-@interface DSoObject : NSObject
-{
-}
-
-- (EOAdaptor *)adaptorForHostName:(NSString *)_hname port:(int)_port
-  databaseName:(NSString *)_dbname inContext:(WOContext *)_ctx;
-
-@end
-
-#endif /* __dbd_DSoObject_H__ */
diff --git a/Misc/dbd/DSoObject.m b/Misc/dbd/DSoObject.m
deleted file mode 100644 (file)
index e6ea929..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoObject.h"
-#include "common.h"
-#include <NGObjWeb/SoHTTPAuthenticator.h>
-#include <GDLAccess/GDLAccess.h>
-
-@implementation DSoObject
-
-- (void)dealloc {
-  [super dealloc];
-}
-
-/* common methods */
-
-- (NSString *)defaultDatabase {
-  /* template1 is supposed to exist always (#postgresql channel ;-) */
-  return @"template1";
-}
-
-- (EOAdaptor *)adaptorForHostName:(NSString *)_hname port:(int)_port
-  databaseName:(NSString *)_dbname inContext:(WOContext *)_ctx
-{
-  EOAdaptor    *adaptor;
-  NSDictionary *condict;
-  NSString     *login = nil, *pwd = nil, *auth;
-  NSArray      *creds;
-  
-  if ((adaptor = [EOAdaptor adaptorWithName:@"PostgreSQL72"]) == nil) {
-    [self logWithFormat:@"missing PostgreSQL72 adaptor"];
-    return nil;
-  }
-  
-  /* extract login/password */
-
-  if ((auth = [[_ctx request] headerForKey:@"authorization"]) == nil) {
-    [self logWithFormat:@"missing 'authorization' .."];
-    return nil;
-  }
-  creds = [SoHTTPAuthenticator parseCredentials:auth];
-  if ([creds count] < 2) {
-    [self logWithFormat:@"cannot use credentials: %@", creds];
-    return nil;
-  }
-  login = [creds objectAtIndex:0];
-  pwd   = [creds objectAtIndex:1];
-  
-  /* create adaptor */
-  
-  _dbname = [_dbname isNotNull] ? _dbname : [self defaultDatabase];
-  
-  // TODO: ignores port
-  condict = [[NSDictionary alloc] initWithObjectsAndKeys:
-                                   _hname,  @"hostName",
-                                   login,   @"userName",
-                                   pwd,     @"password",
-                                   _dbname, @"databaseName",
-                                 nil];
-  [adaptor setConnectionDictionary:condict];
-  [condict release];
-  return adaptor;
-}
-
-#if 0
-- (id)GETAction:(id)_ctx {
-  /* per default, return nothing ... */
-  WOResponse *r = [(WOContext *)_ctx response];
-  NSString   *defName;
-  
-  if ((defName = [self defaultMethodNameInContext:_ctx])) {
-    [r setStatus:302 /* moved */];
-    [r setHeader:[[self baseURL] stringByAppendingPathComponent:defName]
-       forKey:@"location"];
-    return r;
-  }
-  
-  [r setStatus:200 /* Ok */];
-  [self logWithFormat:@"GET on folder, just saying OK"];
-  return r;
-}
-#endif
-
-/* OSX hack */
-
-- (id)valueForUndefinedKey:(NSString *)_key {
-  [self debugWithFormat:@"queried undefined key: '%@'", _key];
-  return nil;
-}
-
-- (BOOL)isCollection {
-  return YES;
-}
-
-@end /* DSoObject */
diff --git a/Misc/dbd/DSoTable.m b/Misc/dbd/DSoTable.m
deleted file mode 100644 (file)
index 36df6c9..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoTable.h"
-#include "DSoDatabase.h"
-#include "common.h"
-
-@implementation DSoTable
-
-- (id)initWithName:(NSString *)_name inContainer:(id)_container {
-  if ((self = [super init])) {
-    self->tableName = [_name      copy];
-    self->database  = [_container retain];
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->database  release];
-  [self->tableName release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (DSoDatabase *)database {
-  return self->database;
-}
-- (NSString *)tableName {
-  return self->tableName;
-}
-
-- (NSString *)hostName {
-  return [[self database] hostName];
-}
-- (int)port {
-  return [[self database] port];
-}
-- (NSString *)databaseName {
-  return [[self database] databaseName];
-}
-
-- (id)container {
-  return [self database];
-}
-- (NSString *)nameInContainer {
-  return [self tableName];
-}
-
-/* support */
-
-- (EOAdaptor *)adaptorInContext:(WOContext *)_ctx {
-  return [self->database adaptorInContext:_ctx];
-}
-
-/* name lookup */
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
-  id obj;
-  
-  /* 
-     Note: acquire:NO - otherwise acquired stuff will override the stuff
-           below!
-  */
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
-    return obj;
-
-  // here we need to differentiate between entry-ids and field names
-  // TODO
-  return nil;
-}
-
-@end /* DSoTable */
diff --git a/Misc/dbd/DSoUserManager.m b/Misc/dbd/DSoUserManager.m
deleted file mode 100644 (file)
index 00a3466..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include "DSoUserManager.h"
-#include "DSoHost.h"
-#include "common.h"
-
-@implementation DSoUserManager
-
-- (id)initWithContainer:(DSoHost *)_container {
-  if ((self = [super init])) {
-    self->host = [_container retain];
-  }
-  return self;
-}
-- (id)init {
-  return [self initWithContainer:nil];
-}
-
-- (void)dealloc {
-  [self->host release];
-  [super dealloc];
-}
-
-/* name lookup */
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
-  id obj;
-  
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:_flag]))
-    return obj;
-
-  // TODO: create DSoUser object
-  
-  return nil;
-}
-
-@end /* DSoUserManager */
diff --git a/Misc/dbd/DTable.m b/Misc/dbd/DTable.m
deleted file mode 100644 (file)
index bdd78a9..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@class EOAdaptorChannel;
-
-@interface DTable : SoComponent
-{
-  EOAdaptorChannel *channel;
-  NSArray *attributes;
-  NSArray *columnNames;
-  id item;
-}
-
-@end
-
-#include "DSoTable.h"
-#include "common.h"
-
-@implementation DTable
-
-- (void)dealloc {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  [self->channel release];
-  
-  [self->attributes  release];
-  [self->columnNames release];
-  [self->item        release];
-  [super dealloc];
-}
-
-/* notifications */
-
-- (void)sleep {
-  if ([self->channel isOpen])
-    [self->channel closeChannel];
-  
-  [super sleep];
-}
-
-/* DB things */
-
-- (EOAdaptor *)adaptor {
-  return [(DSoTable *)[self clientObject] adaptorInContext:[self context]];
-}
-
-- (EOAdaptorChannel *)channel {
-  EOAdaptorContext *ctx;
-  
-  if (self->channel)
-    return self->channel;
-
-  ctx = [[self adaptor] createAdaptorContext];
-  self->channel = [[ctx createAdaptorChannel] retain];
-  if (![self->channel openChannel]) {
-    [self->channel release];
-    self->channel = nil;
-  }
-
-  return self->channel;
-}
-
-- (EOModel *)_describeModel {
-  NSArray *tableNames;
-  
-  tableNames = [NSArray arrayWithObject:[[self clientObject] tableName]];
-  return [[self channel] describeModelWithTableNames:tableNames];
-}
-
-/* accessors */
-
-- (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
-}
-- (id)item {
-  return self->item;
-}
-
-- (NSArray *)attributes {
-  EOModel *model;
-
-  if (self->attributes)
-    return self->attributes;
-  
-  model            = [self _describeModel];
-  self->attributes = [[[[model entities] lastObject] attributes] retain];
-  return self->attributes;
-}
-- (NSArray *)columnNames {
-  if (self->columnNames)
-    return self->columnNames;
-  
-  self->columnNames = [[[self attributes] valueForKey:@"columnName"] copy];
-  return self->columnNames;
-}
-
-- (NSString *)columnLink {
-  return [[[self item] columnName] stringByAppendingString:@"/"];
-}
-- (NSString *)itemSlashLink {
-  // this suxx, a) we need to write code, b) we need to attach the / manually
-  return [[self item] stringByAppendingString:@"/"];
-}
-
-@end /* DTable */
diff --git a/Misc/dbd/DTable.wox b/Misc/dbd/DTable.wox
deleted file mode 100644 (file)
index a15423f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component className="Frame" 
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
-
-Host:  <a href="../.."><var:string value="clientObject.hostName"/></a><br />
-Port:  <var:string value="clientObject.port"/><br />
-DB:    <a href=".."><var:string value="clientObject.databaseName"/></a><br />
-Table: <var:string value="clientObject.tableName"/><br />
-
-<h4>Columns</h4>
-<table>
-  <var:foreach list="attributes" item="item">
-    <tr>
-      <td><a var:href="columnLink"
-            ><var:string value="item.columnName" /></a></td>
-      <td><var:string value="item.externalType" /></td>
-    </tr>
-  </var:foreach>
-</table>
-
-</var:component>
diff --git a/Misc/dbd/Frame.m b/Misc/dbd/Frame.m
deleted file mode 100644 (file)
index c4757b1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface Frame : SoComponent
-@end
-
-#include "common.h"
-
-@implementation Frame
-@end /* Frame */
diff --git a/Misc/dbd/Frame.wox b/Misc/dbd/Frame.wox
deleted file mode 100644 (file)
index cf8d7bd..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<!-- $Id$ -->
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
->
-  <head>
-    <title>DB Testdaemon (<var:string value="context.page.name"/>)</title>
-    <meta name="description" content="OGo DB Testdaemon Web Interface" />
-    <meta name="author"      content="SKYRIX Software AG" />
-    <meta name="robots"      content="stop" />
-    <link href="mailto:feedback@opengroupware.org" rev="made" />
-    <link type="text/css" rel="stylesheet" rsrc:href="dbd.css" />
-  </head>
-
-  <body>
-    <var:component-content/>
-  </body>
-</html>
diff --git a/Misc/dbd/GNUmakefile b/Misc/dbd/GNUmakefile
deleted file mode 100644 (file)
index 07f17ab..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-# $Id: GNUmakefile,v 1.13 2004/06/08 11:41:13 helge Exp $
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-WOAPP_NAME = dbd
-
-dbd_OBJC_FILES += \
-       dbd.m                   \
-       \
-       Frame.m                 \
-       MainPage.m              \
-       DSoAuthenticator.m      \
-       \
-       DSoObject.m             \
-       DSoHost.m               \
-       DSoTable.m              \
-       DSoDatabase.m           \
-       DSoDatabaseManager.m    \
-       DSoUser.m               \
-       DSoUserManager.m        \
-       DSoField.m              \
-       \
-       DHostView.m             \
-       DDatabaseManager.m      \
-       DDatabase.m             \
-       DTable.m                \
-
-dbd_RESOURCE_FILES += \
-       Version                 \
-       product.plist           \
-       \
-       Frame.wox               \
-       MainPage.wox            \
-       \
-       DHostView.wox           \
-       DDatabaseManager.wox    \
-       DDatabase.wox           \
-       DTable.wox              \
-
-dbd_WEBSERVER_RESOURCE_FILES +=
-
-ADDITIONAL_TOOL_LIBS += -lGDLAccess
-
--include GNUmakefile.preamble
-include $(GNUSTEP_MAKEFILES)/woapp.make
--include GNUmakefile.postamble
diff --git a/Misc/dbd/MainPage.m b/Misc/dbd/MainPage.m
deleted file mode 100644 (file)
index db09860..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface MainPage : SoComponent
-{
-  NSString *hostName;
-  NSString *databaseName;
-}
-
-@end
-
-#include "common.h"
-
-@implementation MainPage
-
-- (id)initWithContext:(id)_ctx {
-  if ((self = [super initWithContext:_ctx])) {
-    self->hostName = @"localhost";
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->hostName     release];
-  [self->databaseName release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (void)setHostName:(NSString *)_value {
-  ASSIGNCOPY(self->hostName, _value);
-}
-- (NSString *)hostName {
-  return self->hostName;
-}
-
-- (void)setDatabaseName:(NSString *)_value {
-  ASSIGNCOPY(self->databaseName, _value);
-}
-- (NSString *)databaseName {
-  return self->databaseName;
-}
-
-/* actions */
-
-- (id)connectAction {
-  NSString *url;
-  
-  [self takeFormValuesForKeys:@"databaseName", @"hostName", nil];
-  
-  if ([[self hostName] length] == 0)
-    return nil;
-  
-  url = [@"/" stringByAppendingString:[[self hostName] stringByEscapingURL]];
-  if ([[self databaseName] length] > 0) {
-    url = [url stringByAppendingString:@"/Databases/"];
-    url = [url stringByAppendingString:
-                [[self databaseName] stringByEscapingURL]];
-  }
-  if (![url hasSuffix:@"/"])
-    url = [url stringByAppendingString:@"/"];
-  
-  url = [[self context] urlWithRequestHandlerKey:@"so" 
-                       path:url queryString:nil];
-  return [self redirectToLocation:url];
-}
-
-/* response generation */
-
-- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
-  NSString *rhk;
-  
-  rhk = [[_ctx request] requestHandlerKey];
-  if ([rhk length]==0 || [[self application] requestHandlerForKey:rhk]==nil) {
-    /* a small hack to redirect to a valid URL */
-    NSString *url;
-    
-    url = [_ctx urlWithRequestHandlerKey:@"so" path:@"/" queryString:nil];
-    [_response setStatus:302 /* moved */];
-    [_response setHeader:url forKey:@"location"];
-    [self logWithFormat:@"URL: %@", url];
-    return;
-  }
-  
-  [super appendToResponse:_response inContext:_ctx];
-}
-
-@end /* MainPage */
diff --git a/Misc/dbd/MainPage.wox b/Misc/dbd/MainPage.wox
deleted file mode 100644 (file)
index 17e7c93..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component className="Frame" 
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
-  
-  ClientObject: <var:string value="context.clientObject" />
-  
-  <form href="connect">
-    <table border="0">
-      <tr>
-        <td>Host:</td>
-        <td><input name="hostName" type="text" var:value="hostName" /></td>
-      </tr>
-      <tr>
-        <td>User:</td>
-        <td><input name="userName" type="text" var:value="userName" /></td>
-      </tr>
-      <tr>
-        <td>Database:</td>
-        <td><input name="databaseName" type="text" 
-                   var:value="databaseName" /></td>
-      </tr>
-      
-      <tr>
-        <td></td>
-        <td><input name="submit" type="submit" value="connect"/></td>
-      </tr>
-    </table>
-  </form>
-
-</var:component>
diff --git a/Misc/dbd/README b/Misc/dbd/README
deleted file mode 100644 (file)
index 6405c13..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-# $Id$
-
-PostgreSQL Browser
-==================
-
-Intention:
-- fix open SOPE issues
-- fix PostgreSQL issues, prepare low-level storage
-- work towards SOGo from a storage point of view (with UI-X coming down from a
-  UI point of view)
-
-SOPE Hierarchy
-- /DBHOST/Databases/MYDB/MYTABLE/MYFIELD
-- /DBHOST/Users/MYUSER
-- /DBHOST/Databases/MYDB/MYTABLE/MYFIELD=MYPKEY
-
-Class Hierarchy
-  DSoObject
-    DSoHost            "DBHOST"
-    DSoTable          "MYTABLE"
-    DSoDatabase        "MYDB"
-    DSoDatabaseManager "Database"
-    DSoUser           "MYUSER"
-    DSoUserManager     "Users"
-    DSoField           "MYFIELD"
-
-Tricks used
-===========
-
-- *always* remember that SOPE objects which are looked up in the traversal
-  process are conceptually *UI* objects, not datamodel objects (though this
-  might be done for simplistic applications)
-  - the idea is: the URL is UI
-
-- small hack in MainPage.m to make a redirect to a "valid" WO URL if the
-  request-handler-key is missing
-  - should be made by SOPE itself?
-
-- own authenticator object
-  - two different authenticators (with dbname available and without)
-
-- a hack in the SoApplication -lookupName: to differentiate between
-  'hostnames' and resources
-
-- in DSoObject we extract login/password from the basic auth
-  - SOPE does all the authentication for SOPE level objects, but if we
-    want to reuse passwords, we need to do that manually
-  - we reuse an HTTP parsing method from SoHTTPAuthenticator
-
-- could -sleep to tear down transient state (not used)
-  - -sleep is called by the SoObjectRequestHandler
-  - Note: also supports -_sleepWithContext:
-
-- note that the EOAdaptor is created by the object, but the channel is created
-  by the method (the component)
-  - the object itself is not really active, the methods should be active
-  - the distinction here is blur, in general I would avoid methods which would
-    require an [[WOApplication application] context]
-
-- we are not really clever with DSoUserManager and DSoDatabaseManager,
-  those two classes are basically identical
-
-- the "GET" method is explicitly mapped in product.plist for the application
-  object because otherwise "GET" will be treated as a hostname (because we
-  perform no check on the hostname!)
-  - need to check whether we can make SOPE smarter on this front, but I guess
-    that issue is inherent to all containers which map to arbitary, external
-    collections
-  - we could create an EOAdaptor and connect it to 'template1', but this would
-    result in one unnecessary DB connection?
-  - Note: this is not a problem for methods which are registered in 
-          products.plist - those are found in the SoClass. But the system
-         checks for some keys during its traversal process (and expects 
-          getting a nil if the key does not exist).
-
-- when redirecting to the DSoHost object, we need to ensure that we add a slash
-  - otherwise the relative URLs will be broken!
-  - in theory SOPE should make a redirect to the default method, not sure why
-    this isn't happening
-  - ZideStore always makes such a redirect?
-  - maybe any folderish object when being at the end of a traversal stack 
-    should check that?
-
-- acquisition
-  - if you override -lookupName:inContext:acquire:, you should probably
-    disable acquire in super calls! - otherwise all name processing code 
-    coming after the [super lookup..] is overridden by objects in the 
-    acquisition mechanism
-  - note that acquisition is also done on the traversal path! if the lookup
-    returns nil on an URL path being traversed, URL acquisition will occure
-    (except on non-acquisition protocols like WebDAV)
-  - if you have a path like '/Databases/MyDatabase/MyTable/MyField' and
-    'MyField' isn't processed by MyTable (eg not yet implemented), then this
-    will return a SoDatabase object! - because acquisition will look for
-    'MyField' in 'MyDatabase' which will create a SoDatabase.
-
-- baseURL
-  - calculation of base URL requires you to either override -baseURLInContext:
-    or implement -container and -nameInContainer
-
-- enabling WebDAV
-  - implemented -isCollection in DSoObject
-  - per default the baseURL is broken - you need to ensure that it returns
-    a proper value, see above
-    - if the baseURL doesn't match the requested WebDAV URL, we run into
-      problems, maybe need to fix something in the SOPE WebDAV layer here
-
-- a trick to stop acquisition is to return a NSException 404 code.
diff --git a/Misc/dbd/Version b/Misc/dbd/Version
deleted file mode 100644 (file)
index 1b77c54..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-SUBMINOR_VERSION:=1
diff --git a/Misc/dbd/common.h b/Misc/dbd/common.h
deleted file mode 100644 (file)
index ea6a4db..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  Copyright (C) 2002-2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#import <Foundation/Foundation.h>
-
-#if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
-#  include <NGExtensions/NGObjectMacros.h>
-#  include <NGExtensions/NSString+Ext.h>
-#endif
-
-#include <NGExtensions/NGExtensions.h>
-#include <NGObjWeb/NGObjWeb.h>
-#include <NGObjWeb/SoObjects.h>
-
-#include <GDLAccess/GDLAccess.h>
diff --git a/Misc/dbd/dbd.css b/Misc/dbd/dbd.css
deleted file mode 100644 (file)
index 0a8b8b6..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* dbd UI Stylesheet */
-
-body {
-  color:            #000000;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        10pt;
-  background-color: #FFFFFF;
-  margin:           0px;
-  margin-top:       0px;
-  margin-bottom:    0px;
-  margin-left:      0px;
-  margin-right:     0px;
-}
-
-a:link {
-  color:       #0033CC;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: none;
-}
-a:visited {
-  color:       #660066;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: none;
-}
-a:hover {
-  color:       #FF0000;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: underline;
-}
diff --git a/Misc/dbd/dbd.m b/Misc/dbd/dbd.m
deleted file mode 100644 (file)
index 55089e5..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include <NGObjWeb/SoApplication.h>
-
-@interface DBDaemon : SoApplication
-{
-}
-
-@end
-
-#include "DSoHost.h"
-#include "common.h"
-
-@implementation DBDaemon
-
-- (id)init {
-  if ((self = [super init])) {
-  }
-  return self;
-}
-
-/* name lookup */
-
-- (BOOL)isHostName:(NSString *)_key inContext:(id)_ctx {
-  NSRange r;
-  
-  r = [_key rangeOfString:@"."]; // TODO: this also catches IPs!
-  if (r.length > 0)
-    return NO;
-  
-  return YES;
-}
-
-- (id)lookupHost:(NSString *)_key inContext:(id)_ctx {
-  NSRange  r;
-  NSString *hostName;
-  int      port;
-  
-  r = [_key rangeOfString:@":"];
-  if (r.length == 0) {
-    hostName = _key;
-    port = 5432;
-  }
-  else {
-    hostName = [_key substringToIndex:r.location];
-    port = [[_key substringFromIndex:(r.location + r.length)] intValue];
-  }
-  return [DSoHost dHostWithName:hostName port:port];
-}
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
-  id obj;
-  
-  /* first check attributes directly bound to the application */
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:_flag]))
-    return obj;
-  
-  /* 
-     The problem is, that at this point we still get request for resources,
-     eg 'favicon.ico'.
-     The hack here is to check for a dot in the key, but we should find a way
-     to catch that in a more sensible way.
-     
-     One way to check for a valid key would be to check whether the key is a
-     valid hostname, but I would like to avoid that for performance reasons.
-     
-     Addition: we also get queries for various other methods, like "GET" if
-               no method was provided in the query path.
-  */
-  if ([self isHostName:_key inContext:_ctx])
-    return [self lookupHost:_key inContext:_ctx];
-  
-  return nil;
-}
-
-/* exception handling */
-
-- (WOResponse *)handleException:(NSException *)_exc
-  inContext:(WOContext *)_ctx
-{
-  printf("EXCEPTION: %s\n", [[_exc description] cString]);
-  abort();
-}
-
-@end /* DBDaemon */
-
-
-int main(int argc, char **argv, char **env) {
-  NSAutoreleasePool *pool;
-
-  pool = [[NSAutoreleasePool alloc] init];
-#if LIB_FOUNDATION_LIBRARY
-  [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
-#endif
-  [NGBundleManager defaultBundleManager];
-  
-  WOWatchDogApplicationMain(@"DBDaemon", argc, (void*)argv);
-
-  [pool release];
-  return 0;
-}
diff --git a/Misc/dbd/product.plist b/Misc/dbd/product.plist
deleted file mode 100644 (file)
index 6d55643..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-{
-  publicResources = (
-    "dbd.css"
-  );
-
-  classes = {
-    DBDaemon = {
-      superclass    = "SoApplication";
-      protectedBy   = "View";
-      defaultAccess = "allow";
-      defaultRoles = {
-        "View"          = "Anonymous";
-        "WebDAV Access" = "Authenticated";
-      };
-      methods = {
-        index = { 
-          protectedBy = "View";
-          pageName    = "MainPage"; 
-        };
-        GET = { // more or less a hack, see README
-          protectedBy = "View";
-          pageName    = "MainPage"; 
-        };
-        connect = { 
-          protectedBy = "View";
-          pageName    = "MainPage"; 
-          actionName  = "connect";
-        };
-      };
-    };
-
-    DSoObject = {
-      protectedBy   = "View";
-      defaultAccess = "allow";
-      defaultRoles = {
-        "View"          = "Authenticated";
-        "WebDAV Access" = "Authenticated";
-      };
-      methods = {
-      };
-    };
-    
-    DSoHost = {
-      superclass    = "DSoObject";
-      methods = {
-        index = { 
-          protectedBy = "View";
-          pageName    = "DHostView";
-        };
-      };
-    };
-    DSoTable = {
-      superclass    = "DSoObject";
-      methods = {
-        index = { 
-          protectedBy = "View";
-          pageName    = "DTable";
-        };
-      };
-    };
-    DSoDatabase = {
-      superclass    = "DSoObject";
-      methods = {
-        index = { 
-          protectedBy = "View";
-          pageName    = "DDatabase"; 
-        };
-      };
-    };
-    DSoDatabaseManager = {
-      superclass    = "DSoObject";
-      methods = {
-        index = { 
-          protectedBy = "View";
-          pageName    = "DDatabaseManager"; 
-        };
-      };
-    };
-    DSoUser = {
-      superclass    = "DSoObject";
-      methods = {
-      };
-    };
-    DSoUserManager = {
-      superclass    = "DSoObject";
-      methods = {
-      };
-    };
-    DSoField = {
-      superclass    = "DSoObject";
-      methods = {
-      };
-    };
-  };
-}
index a6c7ab615d113a9d8631f2273ea5b701c1840fad..1b09057cf6beed51fbeab04a804dd240f23ed265 100644 (file)
@@ -22,8 +22,7 @@ libOGoContentStore_OBJC_FILES +=              \
 
 libOGoContentStore_TYPEMODELS += \
        appointment.ocs \
-       contact.ocs     \
-
+       contact.ocs
 
 test_quick_extract_OBJC_FILES += \
        test_quick_extract.m
index 354dafbed9bb5754f8219606866a84866d65595d..faf4e378bde64ea8a969904ad81f09e75088192d 100644 (file)
@@ -3,7 +3,7 @@
 libOGoContentStore_LIBRARIES_DEPEND_UPON += \
        -lGDLContentStore       \
        -lGDLAccess     \
-       -lNGiCal        \
+       -lNGCards       \
        -lNGExtensions  \
        -lEOControl     \
        -lSaxObjC
@@ -24,7 +24,7 @@ test_quick_extract_TOOL_LIBS += \
        -lSaxObjC               \
        -lDOM                   \
        -lNGExtensions          \
-       -lNGiCal                \
+       -lNGCards               \
        -lGDLContentStore       \
        -lGDLAccess             \
        -lOGoContentStore
index 36e8a7c228bb2ebd9583884fe5c63e53e19a1db0..7b53fd061840140723565e508d21610ff7d31564 100644 (file)
@@ -24,7 +24,7 @@
 @interface OCSContactFieldExtractor : GCSFieldExtractor
 @end
 
-#include <NGiCal/NGVCard.h>
+#include <NGCards/NGVCard.h>
 #include "common.h"
 
 @implementation OCSContactFieldExtractor
@@ -42,44 +42,67 @@ static NSString *fieldNames[] = {
   nil, nil
 };
 
-- (NSMutableDictionary *)extractQuickFieldsFromVCard:(NGVCard *)_vCard {
+- (NSMutableDictionary *) extractQuickFieldsFromVCard: (NGVCard *) _vCard
+{
   NSMutableDictionary *fields;
-  unsigned i;
+  NSArray *values;
+  CardElement *adr;
+  NSString *value;
+  unsigned int max;
 
   if (_vCard == nil)
     return nil;
-  
+
   fields = [NSMutableDictionary dictionaryWithCapacity:16];
 
-  for (i = 0; fieldNames[i] != nil; i += 2) {
-    id value;
+  value = [_vCard fn];
+  if (value)
+    [fields setObject: value forKey: @"cn"];
+  values = [_vCard n];
+  if (values)
+    {
+      max = [values count];
+      if (max > 0)
+        {
+          [fields setObject: [values objectAtIndex: 0] forKey: @"sn"];
+          if (max > 1)
+            [fields setObject: [values objectAtIndex: 1]
+                    forKey: @"givenName"];
+        }
+    }
+  value = [_vCard preferredTel];
+  if (value)
+    [fields setObject: value forKey: @"telephoneNumber"];
+  value = [_vCard preferredEMail];
+  if (value)
+    [fields setObject: value forKey: @"mail"];
+  values = [_vCard org];
+  if (values)
+    {
+      max = [values count];
+      if (max > 0)
+        {
+          [fields setObject: [values objectAtIndex: 0] forKey: @"o"];
+          if (max > 1)
+            [fields setObject: [values objectAtIndex: 1] forKey: @"ou"];
+        }
+    }
+  adr = [_vCard preferredAdr];
+  if (adr)
+    [fields setObject: [adr value: 3] forKey: @"l"];
 
-    value = ([fieldNames[i + 1] length] > 0)
-      ? [_vCard valueForKeyPath:fieldNames[i + 1]]
-      : nil;
-    if (![value isNotNull]) value = [NSNull null];
-    
-    [fields setObject:value forKey:[fieldNames[i] lowercaseString]];
-  }
   return fields;
 }
 
 - (NSMutableDictionary *)extractQuickFieldsFromVCardString:(NSString *)_str {
-  NSArray *vCards;
+  NGVCard *vCard;
   
-  if ((vCards = [NGVCard parseVCardsFromSource:_str]) == nil) {
+  if ((vCard = [NGVCard parseSingleFromSource: _str]) == nil) {
     [self errorWithFormat:@"Could not parse content as a vCard."];
     return nil;
   }
-  if ([vCards count] == 0) {
-    [self errorWithFormat:@"Could not parse content as a vCard."];
-    return nil;
-  }
-  
-  if ([vCards count] > 1)
-    [self warnWithFormat:@"More than one vCard in content, using first."];
   
-  return [self extractQuickFieldsFromVCard:[vCards objectAtIndex:0]];
+  return [self extractQuickFieldsFromVCard: vCard];
 }
 
 - (NSMutableDictionary *)extractQuickFieldsFromContent:(NSString *)_content {
index a35e7576084777a8d251f7b2ab9340dcf116bc71..09cbe20efc10ac0c3b60f932b20677bcd7e1de84 100644 (file)
 
 #include "OCSiCalFieldExtractor.h"
 #include "common.h"
-#include <SaxObjC/SaxObjC.h>
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
 #include "iCalEntityObject+OCS.h"
 #include "iCalRepeatableEntityObject+OCS.h"
 
 @implementation OCSiCalFieldExtractor
 
-static id<NSObject,SaxXMLReader> parser               = nil;
-static SaxObjectDecoder          *sax                 = nil;
 static OCSiCalFieldExtractor     *extractor           = nil;
 static NSCalendarDate            *distantFuture       = nil;
 static NSNumber                  *distantFutureNumber = nil;
 
-+ (void)initialize {
++ (void) initialize
+{
   static BOOL didInit = NO;
   
   if (didInit) return;
   didInit = YES;
 
-  parser = [[[SaxXMLReaderFactory standardXMLReaderFactory] 
-               createXMLReaderForMimeType:@"text/calendar"]
-               retain];
-  if (parser == nil)
-    NSLog(@"ERROR: did not find a parser for text/calendar!");
-  sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
-  if (sax == nil)
-      NSLog(@"ERROR: could not create the iCal SAX handler!");
-  [parser setContentHandler:sax];
-  [parser setErrorHandler:sax];
-
   distantFuture       = [[NSCalendarDate distantFuture] retain];
   /* INT_MAX due to Postgres constraint */
   distantFutureNumber = [[NSNumber numberWithUnsignedInt:INT_MAX] retain];
 }
 
-+ (id)sharedICalFieldExtractor {
-  if (extractor == nil) extractor = [[self alloc] init];
-  return extractor;
-}
++ (id) sharedICalFieldExtractor
+{
+  if (extractor == nil)
+    extractor = [self new];
 
-- (void)dealloc {
-  [super dealloc];
+  return extractor;
 }
 
 /* operations */
 
-- (NSNumber *)numberForDate:(NSCalendarDate *)_date {
+- (NSNumber *) numberForDate: (NSCalendarDate *) _date
+{
   if (_date == distantFuture)
     return distantFutureNumber;
+
   return [NSNumber numberWithUnsignedInt:[_date timeIntervalSince1970]];
 }
 
-- (NSMutableDictionary *)extractQuickFieldsFromEvent:(iCalEvent *)_event {
+- (NSMutableDictionary *) extractQuickFieldsFromEvent: (iCalEvent *) _event
+{
   NSMutableDictionary *row;
   NSCalendarDate      *startDate, *endDate;
   NSArray             *attendees;
@@ -107,30 +96,31 @@ static NSNumber                  *distantFutureNumber = nil;
   /* build row */
 
   row = [NSMutableDictionary dictionaryWithCapacity:8];
+
+  [row setObject: @"vevent" forKey: @"component"];
   
   if ([uid isNotNull]) 
     [row setObject:uid forKey:@"uid"];
   else
     [self logWithFormat:@"WARNING: could not extract a uid from event!"];
 
-  [row setObject:[NSNumber numberWithBool:[_event isAllDay]]
-       forKey:@"isallday"];
-  [row setObject:[NSNumber numberWithBool:[_event isRecurrent]]
-       forKey:@"iscycle"];
-  [row setObject:[NSNumber numberWithBool:[_event isOpaque]]
-       forKey:@"isopaque"];
-  [row setObject:[NSNumber numberWithInt:[_event priorityNumber]]
-       forKey:@"priority"];
+  [row setObject:[NSNumber numberWithBool: [_event isAllDay]]
+       forKey: @"isallday"];
+  [row setObject:[NSNumber numberWithBool: [_event isRecurrent]]
+       forKey: @"iscycle"];
+  [row setObject:[NSNumber numberWithBool: [_event isOpaque]]
+       forKey: @"isopaque"];
+  [row setObject:[NSNumber numberWithInt: [_event priorityNumber]]
+       forKey: @"priority"];
+
+  if ([title isNotNull]) [row setObject: title forKey:@"title"];
+  if ([location isNotNull]) [row setObject: location forKey:@"location"];
+  if ([sequence isNotNull]) [row setObject: sequence forKey:@"sequence"];
 
-  if ([title    isNotNull]) [row setObject:title    forKey:@"title"];
-  if ([location isNotNull]) [row setObject:location forKey:@"location"];
-  if ([sequence isNotNull]) [row setObject:sequence forKey:@"sequence"];
-  
   if ([startDate isNotNull]) 
-    [row setObject:[self numberForDate:startDate] forKey:@"startdate"];
+    [row setObject: [self numberForDate: startDate] forKey:@"startdate"];
   if ([endDate isNotNull]) 
-    [row setObject:[self numberForDate:endDate] forKey:@"enddate"];
-
+    [row setObject: [self numberForDate: endDate] forKey:@"enddate"];
   if ([_event isRecurrent]) {
     NSCalendarDate *date;
     
@@ -143,23 +133,24 @@ static NSNumber                  *distantFutureNumber = nil;
     [row setObject:[self numberForDate:date] forKey:@"cycleenddate"];
     [row setObject:[_event cycleInfo] forKey:@"cycleinfo"];
   }
+
   if ([participants length] > 0)
-    [row setObject:participants forKey:@"participants"];
+    [row setObject: participants forKey:@"participants"];
   if ([partmails length] > 0)
-    [row setObject:partmails forKey:@"partmails"];
+    [row setObject: partmails forKey:@"partmails"];
 
   if ([status isNotNull]) {
     int code = 1;
     
     if ([status isEqualToString:@"TENTATIVE"])
-      code = 0;
-    else if ([status isEqualToString:@"CANCELLED"])
       code = 2;
+    else if ([status isEqualToString:@"CANCELLED"])
+      code = 0;
     [row setObject:[NSNumber numberWithInt:code] forKey:@"status"];
   }
   else {
     /* confirmed by default */
-    [row setObject:[NSNumber numberWithInt:1] forKey:@"status"];
+    [row setObject: [NSNumber numberWithInt:1] forKey: @"status"];
   }
 
   if([accessClass isNotNull] && ![accessClass isEqualToString:@"PUBLIC"]) {
@@ -196,24 +187,147 @@ static NSNumber                  *distantFutureNumber = nil;
   return row;
 }
 
-- (NSMutableDictionary *)extractQuickFieldsFromCalendar:(iCalCalendar *)_cal {
-  NSArray *events;
-  
-  if (_cal == nil)
+- (NSMutableDictionary *) extractQuickFieldsFromTodo: (iCalToDo *) _task
+{
+  NSMutableDictionary *row;
+  NSCalendarDate      *startDate, *dueDate;
+  NSArray             *attendees;
+  NSString            *uid, *title, *location, *status, *accessClass;
+  NSNumber            *sequence;
+  id                  organizer, date;
+  id                  participants, partmails;
+  NSMutableString     *partstates;
+  unsigned            i, count, code;
+
+  if (_task == nil)
     return nil;
+
+  /* extract values */
   
-  events = [_cal events];
-  if ([events count] == 0) {
-    [self logWithFormat:@"ERROR: given calendar contains no events: %@", _cal];
-    return nil;
+  startDate    = [_task startDate];
+  dueDate      = [_task due];
+  uid          = [_task uid];
+  title        = [_task summary];
+  location     = [_task location];
+  sequence     = [_task sequence];
+  accessClass  = [[_task accessClass] uppercaseString];
+  status       = [[_task status] uppercaseString];
+
+  attendees    = [_task attendees];
+  partmails    = [attendees valueForKey:@"rfc822Email"];
+  partmails    = [partmails componentsJoinedByString:@"\n"];
+  participants = [attendees valueForKey:@"cn"];
+  participants = [participants componentsJoinedByString:@"\n"];
+
+  /* build row */
+
+  row = [NSMutableDictionary dictionaryWithCapacity:8];
+
+  [row setObject: @"vtodo" forKey: @"component"];
+
+  if ([uid isNotNull]) 
+    [row setObject:uid forKey:@"uid"];
+  else
+    [self logWithFormat:@"WARNING: could not extract a uid from event!"];
+
+  [row setObject:[NSNumber numberWithBool:[_task isRecurrent]]
+       forKey:@"iscycle"];
+  [row setObject:[NSNumber numberWithInt:[_task priorityNumber]]
+       forKey:@"priority"];
+
+  if ([title isNotNull]) [row setObject: title forKey:@"title"];
+  if ([location isNotNull]) [row setObject: location forKey:@"location"];
+  if ([sequence isNotNull]) [row setObject: sequence forKey:@"sequence"];
+  
+  if ([startDate isNotNull])
+    date = [self numberForDate: startDate];
+  else
+    date = [NSNull null];
+  [row setObject: date forKey: @"startdate"];
+
+  if ([dueDate isNotNull]) 
+    date = [self numberForDate: dueDate];
+  else
+    date = [NSNull null];
+  [row setObject: date forKey: @"enddate"];
+
+  if ([participants length] > 0)
+    [row setObject:participants forKey:@"participants"];
+  if ([partmails length] > 0)
+    [row setObject:partmails forKey:@"partmails"];
+
+  if ([status isNotNull]) {
+    code = 0; /* NEEDS-ACTION */
+    if ([status isEqualToString:@"COMPLETED"])
+      code = 1;
+    else if ([status isEqualToString:@"IN-PROCESS"])
+      code = 2;
+    else if ([status isEqualToString:@"CANCELLED"])
+      code = 3;
+    [row setObject: [NSNumber numberWithInt: code] forKey:@"status"];
+  }
+  else {
+    /* confirmed by default */
+    [row setObject:[NSNumber numberWithInt:1] forKey:@"status"];
+  }
+
+  if([accessClass isNotNull] && ![accessClass isEqualToString:@"PUBLIC"]) {
+    [row setObject:[NSNumber numberWithBool:NO] forKey:@"ispublic"];
+  }
+  else {
+    [row setObject:[NSNumber numberWithBool:YES] forKey:@"ispublic"];
   }
-  if ([events count] > 1) {
-    [self logWithFormat:
-           @"WARNING: given calendar contains more than one event: %@",
-           _cal];
+
+  organizer = [_task organizer];
+  if (organizer) {
+    NSString *email;
+    
+    email = [organizer valueForKey:@"rfc822Email"];
+    if (email)
+      [row setObject:email forKey:@"orgmail"];
   }
   
-  return [self extractQuickFieldsFromEvent:[events objectAtIndex:0]];
+  /* construct partstates */
+  count        = [attendees count];
+  partstates   = [[NSMutableString alloc] initWithCapacity:count * 2];
+  for ( i = 0; i < count; i++) {
+    iCalPerson         *p;
+    iCalPersonPartStat stat;
+    
+    p    = [attendees objectAtIndex:i];
+    stat = [p participationStatus];
+    if(i != 0)
+      [partstates appendString:@"\n"];
+    [partstates appendFormat:@"%d", stat];
+  }
+  [row setObject:partstates forKey:@"partstates"];
+  [partstates release];
+  return row;
+}
+
+- (CardGroup *) firstElementFromCalendar: (iCalCalendar *) ical
+{
+  NSArray *elements;
+  CardGroup *element;
+  unsigned int count;
+  
+  elements = [ical allObjects];
+  count = [elements count];
+  if (count)
+    {
+      if (count > 1)
+        [self logWithFormat:
+                @"WARNING: given calendar contains more than one event: %@",
+              ical];
+      element = [elements objectAtIndex: 0];
+    }
+  else
+    {
+      [self logWithFormat:@"ERROR: given calendar contains no elements: %@", ical];
+      element = nil;
+    }
+
+  return element;
 }
 
 - (NSMutableDictionary *)extractQuickFieldsFromContent:(NSString *)_content {
@@ -221,27 +335,29 @@ static NSNumber                  *distantFutureNumber = nil;
   NSDictionary *fields;
   id cal;
   
-  if (parser == nil || sax == nil)
-    return nil;
   if ([_content length] == 0)
     return nil;
 
   pool = [[NSAutoreleasePool alloc] init];
-  
-  [parser parseFromSource:_content];
-  cal = [sax rootObject];
+  cal = [iCalCalendar parseSingleFromSource: _content];
   
   fields = nil;
-  if ([cal isKindOfClass:[iCalEvent class]])
-    fields = [[self extractQuickFieldsFromEvent:cal] retain];
-  else if ([cal isKindOfClass:[iCalCalendar class]])
-    fields = [[self extractQuickFieldsFromCalendar:cal] retain];
-  else if ([cal isNotNull]) {
-    [self logWithFormat:@"ERROR: unexpected iCalendar parse result: %@",
-           cal];
-  }
-  
-  [sax reset];
+  if (cal)
+    {
+      if ([cal isKindOfClass:[iCalCalendar class]])
+        cal = [self firstElementFromCalendar: cal];
+
+      if ([cal isKindOfClass:[iCalEvent class]])
+        fields = [[self extractQuickFieldsFromEvent:cal] retain];
+      else if ([cal isKindOfClass:[iCalToDo class]])
+        fields = [[self extractQuickFieldsFromTodo:cal] retain];
+      else if ([cal isNotNull]) {
+        [self logWithFormat:@"ERROR: unexpected iCalendar parse result: %@",
+              cal];
+      }
+    }
+  else
+    [self logWithFormat:@"ERROR: parsing source didn't return anything"];
 
   [pool release];
   
index 116c109957570dcd0ab0bf6e2f25217061b9c20f..b1d267e29cf171bc8d745f3cb743f2e0a183a114 100644 (file)
     {
       columnName = startdate;
       sqlType    = "INT";
-      allowsNull = NO;
+      allowsNull = YES;
     },
     {
       columnName = enddate;
       sqlType    = "INT";
-      allowsNull = NO;
+      allowsNull = YES;
     },
     {
       columnName = cylceenddate;
@@ -32,7 +32,7 @@
     {
       columnName = participants;
       sqlType    = "VARCHAR(1000000)";
-      allowsNull = NO;
+      allowsNull = YES;
     },
     {
       columnName = isallday;
@@ -57,7 +57,7 @@
     {
       columnName = isopaque;
       sqlType    = "INT";
-      allowsNull = YES;
+      allowsNull = NO;
     },
     {
       columnName = status;
@@ -67,7 +67,7 @@
     {
       columnName = priority;
       sqlType    = "INT";
-      allowsNull = NO;
+      allowsNull = YES;
     },
     {
       columnName = location;
     {
       columnName = partmails;
       sqlType    = "VARCHAR(100000)";
-      allowsNull = NO;
+      allowsNull = YES;
     },
     {
       columnName = partstates;
       sqlType    = "VARCHAR(256)";
-      allowsNull = NO;
+      allowsNull = YES;
     },
     {
       columnName = sequence;
       sqlType    = "INT";
       allowsNull = YES;
     },
+    {
+      columnName = component;
+      sqlType    = "VARCHAR(10)";
+      allowsNull = NO;
+    },
   );
 }
index 0bb5f58ad6e6b9a854854ca6e395837ff9e79f91..c5eb30da8e856453f4d37bbe28ad2a68b872aaaa 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef        __OGoContentStore_iCalEntityObject_OCS_H_
 #define        __OGoContentStore_iCalEntityObject_OCS_H_
 
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
 
 @interface iCalEntityObject (OCS)
 
index 0fa62e1556ffc89bbde9ac8677a7cab3f1daef18..6e608162e6c18474278cce21135bf6daf5a5dfb7 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef        __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
 #define        __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
 
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
 
 @interface iCalRepeatableEntityObject (OCS)
 
index d36f9cbe3cdfe5309863f9d4e10213d23e464842..fe557b6705e9151a947e291b4e5a407b8e820e68 100644 (file)
@@ -47,7 +47,7 @@
       iCalRecurrenceRule *rule;
       
       rule = [a objectAtIndex:i];
-      [ma addObject:[rule iCalRepresentation]];
+      [ma addObject: [rule versitString]];
     }
     [cycleInfo setObject:ma forKey:@"rules"];
   }
@@ -63,7 +63,7 @@
       iCalRecurrenceRule *rule;
       
       rule = [a objectAtIndex:i];
-      [ma addObject:[rule iCalRepresentation]];
+      [ma addObject: [rule versitString]];
     }
     [cycleInfo setObject:ma forKey:@"exRules"];
   }
diff --git a/OGoContentStore/sql/acls.sh b/OGoContentStore/sql/acls.sh
new file mode 100755 (executable)
index 0000000..b3b4da7
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/bash
+#
+# Usage: generate-folderinfo-sql-for-users user1 [user2] [user3] [...]
+#
+
+DB_USER="sogo"
+DB_PASS="sogo"
+DB_HOST="192.168.0.4"
+DB_PORT="5432"
+DB_NAME="sogo"
+TIMEZONE="Canada/Eastern"
+
+
+while [ "$1" != "" ]; do
+USER_ID=$1
+USER_TABLE=`echo $USER_ID | tr -s [:punct:] _`
+cat << EOF
+--
+-- (C) 2004 SKYRIX Software AG
+--
+-- TODO:
+--   add a unique constraints on path
+
+UPDATE SOGo_folder_info
+  SET c_acl_location = 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_acl'
+  WHERE c_folder_type = 'Container'
+  AND c_path2 = '${USER_ID}';
+UPDATE SOGo_folder_info
+  SET c_acl_location = 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts_acl'
+  WHERE c_folder_type = 'Contact'
+  AND c_path2 = '${USER_ID}';
+UPDATE SOGo_folder_info
+  SET c_acl_location = 'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal_acl'
+  WHERE c_folder_type = 'Appointment'
+  AND c_path2 = '${USER_ID}';
+
+DROP TABLE SOGo_${USER_TABLE}_acls;
+DROP TABLE SOGo_${USER_TABLE}_privcal_acls;
+DROP TABLE SOGo_${USER_TABLE}_contacts_acls;
+
+DROP TABLE SOGo_${USER_TABLE}_acl;
+DROP TABLE SOGo_${USER_TABLE}_privcal_acl;
+DROP TABLE SOGo_${USER_TABLE}_contacts_acl;
+
+CREATE TABLE SOGo_${USER_TABLE}_acl (
+  c_uid          VARCHAR(256)    NOT NULL,
+  c_object       VARCHAR(256)    NOT NULL,
+  c_role         VARCHAR(80)     NOT NULL
+);
+
+CREATE TABLE SOGo_${USER_TABLE}_privcal_acl (
+  c_uid          VARCHAR(256)    NOT NULL,
+  c_object       VARCHAR(256)    NOT NULL,
+  c_role         VARCHAR(80)     NOT NULL
+);
+
+CREATE TABLE SOGo_${USER_TABLE}_contacts_acl (
+  c_uid          VARCHAR(256)    NOT NULL,
+  c_object       VARCHAR(256)    NOT NULL,
+  c_role         VARCHAR(80)     NOT NULL
+);
+
+EOF
+shift
+done
index 45bb70c3304852a89c7ad7e88f4a31e66545d0ac..94c370c6144dedcb00f539f69529c1b7fe5f84e0 100644 (file)
@@ -13,7 +13,7 @@ CREATE TABLE %s_quick (
   iscycle      INT             NULL,     -- client needs to fetch to resolve
   ispublic     INT             NOT NULL,
   status       INT             NOT NULL,
-  isopaque     INT             NULL,
+  isopaque     INT             NOT NULL,
   location     VARCHAR(256)    NULL,
   orgmail      VARCHAR(256)    NULL,
   partmails    VARCHAR(100000) NOT NULL, -- the emails of the participants
index d9df55f65e0da55b8dfff178f896ff8b89de7d73..e4a499eaadae6ef09944f7d28a60fdf2edf99aba 100644 (file)
@@ -21,6 +21,7 @@ CREATE TABLE SOGo_folder_info (
   c_foldername     VARCHAR(255)  NOT NULL, -- last path component
   c_location       VARCHAR(2048) NOT NULL, -- URL to folder
   c_quick_location VARCHAR(2048) NULL,     -- URL to quicktable of folder
+  c_acl_location VARCHAR(2048) NULL,     -- URL to quicktable of folder
   c_folder_type    VARCHAR(255)  NOT NULL  -- the folder type ...
 );
 
@@ -36,32 +37,5 @@ VALUES
     'Users', 
     'http://OGo:OGo@localhost:5432/OGo/SOGo_user_folder', 
     'http://OGo:OGo@localhost:5432/OGo/SOGo_user_folder_quick', 
+    'http://OGo:OGo@localhost:5432/OGo/SOGo_user_folder_acl', 
     'Container' );
-
-INSERT INTO SOGo_folder_info 
-  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
-VALUES 
-  ( '/Users/helge', 
-    'Users',
-    'helge',
-    NULL,
-    NULL,
-    'helge', 
-    'http://OGo:OGo@localhost:5432/OGo/SOGo_user_folder', 
-    'http://OGo:OGo@localhost:5432/OGo/SOGo_user_folder_quick', 
-    'Container' );
-
-INSERT INTO SOGo_folder_info 
-  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
-VALUES 
-  ( '/Users/helge/Calendar', 
-    'Users',
-    'helge',
-    'Calendar',
-     NULL,
-    'Calendar', 
-    'http://OGo:OGo@localhost:5432/OGo/SOGo_helge_privcal', 
-    'http://OGo:OGo@localhost:5432/OGo/SOGo_helge_privcal_quick', 
-    'Appointment' );
index 0a08fdac73696fb5be80b1a4c4859a67b8dc2689..ed2e01833ec83a786c0d903e918e61d5185d1274 100755 (executable)
@@ -3,11 +3,12 @@
 # Usage: generate-folderinfo-sql-for-users user1 [user2] [user3] [...]
 #
 
-DB_USER="postgres"
-DB_PASS=""
-DB_HOST="agenor-db"
+DB_USER="sogo"
+DB_PASS="sogo"
+DB_HOST="192.168.0.4"
 DB_PORT="5432"
-DB_NAME="test"
+DB_NAME="sogo"
+TIMEZONE="Canada/Eastern"
 
 
 while [ "$1" != "" ]; do
@@ -24,7 +25,7 @@ DELETE FROM SOGo_folder_info WHERE c_path2 = '${USER_ID}';
 
 INSERT INTO SOGo_folder_info 
   ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
+    c_location, c_quick_location, c_acl_location, c_folder_type )
 VALUES 
   ( '/Users/${USER_ID}', 
     'Users',
@@ -32,13 +33,14 @@ VALUES
     NULL,
     NULL,
     '${USER_ID}', 
-    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_user_folder', 
-    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_user_folder_quick', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_folder', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_quick', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_acl', 
     'Container' );
 
 INSERT INTO SOGo_folder_info 
   ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
+    c_location, c_quick_location, c_acl_location, c_folder_type ) 
 VALUES 
   ( '/Users/${USER_ID}/Calendar', 
     'Users',
@@ -48,20 +50,22 @@ VALUES
     'Calendar', 
     'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal', 
     'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal_quick', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal_acl', 
     'Appointment' );
 
 INSERT INTO SOGo_folder_info 
   ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
-    c_location, c_quick_location, c_folder_type ) 
+    c_location, c_quick_location, c_acl_location, c_folder_type ) 
 VALUES 
-  ( '/Users/${USER_ID}/Contacts', 
+  ( '/Users/${USER_ID}/Contacts/personal', 
     'Users',
     '${USER_ID}',
     'Contacts',
-     NULL,
+    'personal',
     'Contacts', 
     'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts', 
     'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts_quick', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts_acl', 
     'Contact' );
 
 DROP TABLE SOGo_${USER_TABLE}_privcal_quick;
@@ -70,12 +74,12 @@ DROP TABLE SOGo_${USER_TABLE}_privcal;
 CREATE TABLE SOGo_${USER_TABLE}_privcal_quick (
   c_name       VARCHAR(256)    NOT NULL PRIMARY KEY, -- the filename
   uid          VARCHAR(256)    NOT NULL,
-  startdate    INT             NOT NULL,
-  enddate      INT             NOT NULL,
+  startdate    INT             NULL,
+  enddate      INT             NULL,
   cycleenddate INT             NULL,     -- enddate for cyclic events
   title        VARCHAR(1000)   NOT NULL,
   cycleinfo    VARCHAR(1000)   NULL,     -- property list with cycle infos
-  participants VARCHAR(100000) NOT NULL, -- the CNs of the participants
+  participants VARCHAR(100000) NULL, -- the CNs of the participants
   isallday     INT             NULL,
   iscycle      INT             NULL,     -- client needs to fetch to resolve
   ispublic     INT             NOT NULL,
@@ -84,9 +88,10 @@ CREATE TABLE SOGo_${USER_TABLE}_privcal_quick (
   isopaque     INT             NULL,
   location     VARCHAR(256)    NULL,
   orgmail      VARCHAR(256)    NULL,
-  partmails    VARCHAR(100000) NOT NULL, -- the emails of the participants
+  partmails    VARCHAR(100000) NULL, -- the emails of the participants
   partstates   VARCHAR(256)    NOT NULL, -- the status of each participant
-  sequence     INT             NULL      -- the iCal sequence
+  sequence     INT             NULL,      -- the iCal sequence
+  component    VARCHAR(10)     NOT NULL -- the type of component (vevent/vtodo) in the vcalendar
 );
 
 CREATE TABLE SOGo_${USER_TABLE}_privcal (
@@ -120,6 +125,40 @@ CREATE TABLE SOGo_${USER_TABLE}_contacts (
   c_version      INT             NOT NULL  -- version counter
 );
 
+DROP TABLE SOGo_${USER_TABLE}_acl;
+DROP TABLE SOGo_${USER_TABLE}_privcal_acl;
+DROP TABLE SOGo_${USER_TABLE}_contacts_acl;
+
+CREATE TABLE SOGo_${USER_TABLE}_acl (
+  c_uid          VARCHAR(256)    NOT NULL,
+  c_object       VARCHAR(256)    NOT NULL,
+  c_role         VARCHAR(80)     NOT NULL
+);
+
+CREATE TABLE SOGo_${USER_TABLE}_privcal_acl (
+  c_uid          VARCHAR(256)    NOT NULL,
+  c_object       VARCHAR(256)    NOT NULL,
+  c_role         VARCHAR(80)     NOT NULL
+);
+
+CREATE TABLE SOGo_${USER_TABLE}_contacts_acl (
+  c_uid          VARCHAR(256)    NOT NULL,
+  c_object       VARCHAR(256)    NOT NULL,
+  c_role         VARCHAR(80)     NOT NULL
+);
+
+DELETE FROM SOGo_user_profile WHERE uid = '${USER_ID}';
+
+INSERT INTO SOGo_user_profile ( 
+  uid,
+  allowinternet,
+  timezonename,
+  calendaruids
+)
+VALUES (
+    '${USER_ID}', 1, '${TIMEZONE}', '${USER_ID}'
+);
+
 EOF
 shift
 done
index 3bd9c5e4fdfc34d1b861926fa7bb78de292c5cde..b60cabbff3251caafacf7fc488f9faf626d8ae9e 100644 (file)
@@ -5,5 +5,7 @@
 CREATE TABLE SOGo_user_profile (
   uid           VARCHAR(255) NOT NULL PRIMARY KEY,
   allowinternet SMALLINT     DEFAULT 0,
-  timezonename  VARCHAR(255) DEFAULT 'MET'
+  timezonename  VARCHAR(255) DEFAULT 'MET',
+  calendaruids  TEXT,
+  additionaladdressbooks  TEXT
 );
diff --git a/OGoContentStore/sql/sogo-folderinfo.sh b/OGoContentStore/sql/sogo-folderinfo.sh
new file mode 100755 (executable)
index 0000000..5095eec
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/bash
+#
+# Usage: generate-folderinfo-sql-for-users user1 [user2] [user3] [...]
+#
+
+DB_USER="sogo"
+DB_PASS="sogo"
+DB_HOST="192.168.0.4"
+DB_PORT="5432"
+DB_NAME="sogo"
+TIMEZONE="Canada/Eastern"
+
+
+while [ "$1" != "" ]; do
+USER_ID=$1
+USER_TABLE=`echo $USER_ID | tr -s [:punct:] _`
+cat << EOF
+--
+-- (C) 2004 SKYRIX Software AG
+--
+-- TODO:
+--   add a unique constraints on path
+
+DELETE FROM SOGo_folder_info WHERE c_path2 = '${USER_ID}';
+
+INSERT INTO SOGo_folder_info 
+  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
+    c_location, c_quick_location, c_folder_type ) 
+VALUES 
+  ( '/Users/${USER_ID}', 
+    'Users',
+    '${USER_ID}',
+    NULL,
+    NULL,
+    '${USER_ID}', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_user_folder', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_user_folder_quick', 
+    'Container' );
+
+INSERT INTO SOGo_folder_info 
+  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
+    c_location, c_quick_location, c_folder_type ) 
+VALUES 
+  ( '/Users/${USER_ID}/Calendar', 
+    'Users',
+    '${USER_ID}',
+    'Calendar',
+     NULL,
+    'Calendar', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_privcal_quick', 
+    'Appointment' );
+
+INSERT INTO SOGo_folder_info 
+  ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername, 
+    c_location, c_quick_location, c_folder_type ) 
+VALUES 
+  ( '/Users/${USER_ID}/Contacts/personal', 
+    'Users',
+    '${USER_ID}',
+    'Contacts',
+    'personal',
+    'Contacts', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts', 
+    'http://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}/SOGo_${USER_TABLE}_contacts_quick', 
+    'Contact' );
+
+EOF
+shift
+done
index 59752b3bf179cd49a44479040ccc6979a6a084fb..0cc98888b3fb15db999e654143919e5cbe09f171 100644 (file)
@@ -31,6 +31,6 @@ BUNDLE_LIBS +=                                        \
        -lOGoContentStore                       \
        -lGDLAccess                             \
        -lNGObjWeb                              \
-       -lNGMime -lNGiCal -lNGLdap              \
+       -lNGMime -lNGCards -lNGLdap             \
        -lNGStreams -lNGExtensions -lEOControl  \
        -lXmlRpc -lDOM -lSaxObjC
index 2750764ed6a51121966eafe17b6abfce539e5742..3307e5c13b4533c55229f616e0747e4d4e164aa1 100644 (file)
   02111-1307, USA.
 */
 
-#include <NGObjWeb/WODirectAction.h>
+#import <NGObjWeb/WODirectAction.h>
+#import "SOGoICalHTTPHandler.h"
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
+
+#import <NGCards/iCalEvent.h>
+
+#import "common.h"
 
 @interface SOGoICalFileFetch : WODirectAction
 {
 
 @end
 
-#include "SOGoICalHTTPHandler.h"
-#include <SoObjects/Appointments/SOGoAppointmentFolder.h>
-#include <SOGo/SOGoAppointment.h>
-#include "common.h"
-
 @implementation SOGoICalFileFetch
 
 /* clientObject */
@@ -45,7 +46,7 @@
 - (id)defaultAction {
   NSAutoreleasePool *pool;
   WOResponse      *response;
-  SOGoAppointment *event;
+  iCalEvent *event;
   NSEnumerator    *e;
   NSArray         *events;
 
@@ -65,9 +66,8 @@
   events = [[self clientObject] fetchAllSOGoAppointments];
   [self debugWithFormat:@"generate %d appointments ...", [events count]];
   e = [events objectEnumerator];
-  while ((event = [e nextObject]) != nil) {
-    [response appendContentString:[event vEventString]];
-  }
+  while ((event = [e nextObject]) != nil)
+    [response appendContentString: [event versitString]];
 
   /* vcal postamble */
   [response appendContentString:@"END:VCALENDAR\r\n"];
index 9be217e939da07cfe0c860fafaf937a76ad1c102..894565f56847c3e18a3e063eab6bd9d67035106f 100644 (file)
@@ -30,9 +30,7 @@
 #include "SOGoICalHTTPHandler.h"
 #include <SoObjects/Appointments/SOGoAppointmentFolder.h>
 #include <SoObjects/Appointments/SOGoAppointmentObject.h>
-#include <SOGo/SOGoAppointment.h>
-#include <NGiCal/NGiCal.h>
-#include <NGiCal/iCalRenderer.h>
+#include <NGCards/NGCards.h>
 #include <SaxObjC/SaxObjC.h>
 #include "common.h"
 
@@ -51,7 +49,7 @@ static SaxObjectDecoder          *sax   = nil;
       NSLog(@"ERROR: did not find a parser for text/calendar!");
   }
   if (sax == nil) {
-    sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
+    sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGCards"];
     if (sax == nil)
       NSLog(@"ERROR: could not create the iCal SAX handler!");
   }
@@ -135,7 +133,6 @@ static SaxObjectDecoder          *sax   = nil;
 
 - (NSException *)writeNewVEvents:(NSArray *)_events {
   SOGoAppointmentFolder *folder;
-  iCalRenderer *renderer;
   NSException *error;
   unsigned i, count;
   
@@ -144,15 +141,13 @@ static SaxObjectDecoder          *sax   = nil;
                        reason:@"did not find clientObject?!"];
   }
 
-  renderer = [iCalRenderer sharedICalendarRenderer];
-  
   for (i = 0, count = [_events count]; i < count; i++) {
     SOGoAppointmentObject *object;
     iCalEvent *event;
     NSString  *ical;
     
     event = [_events objectAtIndex:i];
-    ical  = [renderer iCalendarStringForEvent:event];
+    ical  = [event versitString];
 
     if (![ical isNotNull] && ([ical length] == 0)) {
       [self logWithFormat:@"ERROR: got no ical representation of event: %@",
diff --git a/README b/README
index 0a4a83837c9e08a09293d172db193b09f832f10e..0383ac1c6ecbee27e0f9aa60262247067ff18135 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-# test $Id$
+# $Id$
 
 SOGo
 ====
index 93af7f7a816df38ecde9f37f35b04f3c479faec5..57b4cb0f30ed12d1d1145c86b993367618e6ce43 100644 (file)
@@ -10,8 +10,12 @@ Appointments_PRINCIPAL_CLASS = SOGoAppointmentsProduct
 
 Appointments_OBJC_FILES = \
        Product.m                       \
+       NSArray+Appointments.m          \
+       iCalEntityObject+Agenor.m       \
        \
+       SOGoCalendarComponent.m         \
        SOGoAppointmentObject.m         \
+       SOGoTaskObject.m                \
        SOGoAppointmentFolder.m         \
        SOGoGroupAppointmentFolder.m    \
        SOGoFreeBusyObject.m            \
@@ -39,4 +43,4 @@ Appointments_COMPONENTS +=    \
 -include GNUmakefile.preamble
 include $(GNUSTEP_MAKEFILES)/wobundle.make
 -include GNUmakefile.postamble
-include ../../fhsbundle.make
+include ../../fhswobundle.make
diff --git a/SoObjects/Appointments/NSArray+Appointments.h b/SoObjects/Appointments/NSArray+Appointments.h
new file mode 100644 (file)
index 0000000..03fd2c3
--- /dev/null
@@ -0,0 +1,37 @@
+/* NSArray+Appointments.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef NSARRAY_APPOINTMENTS_H
+#define NSARRAY_APPOINTMENTS_H
+
+#import <Foundation/NSArray.h>
+
+@class iCalPerson;
+
+@interface NSMutableArray (iCalPersonConvenience)
+
+- (void) removePerson: (iCalPerson *) _person;
+
+@end
+
+
+#endif /* NSARRAY+APPOINTMENTS_H */
diff --git a/SoObjects/Appointments/NSArray+Appointments.m b/SoObjects/Appointments/NSArray+Appointments.m
new file mode 100644 (file)
index 0000000..7f0f911
--- /dev/null
@@ -0,0 +1,41 @@
+/* NSArray+Appointments.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <NGCards/iCalPerson.h>
+
+#import "NSArray+Appointments.h"
+
+@implementation NSMutableArray (iCalPersonConvenience)
+
+- (void)removePerson: (iCalPerson *)_person {
+  int i;
+  
+  for (i = [self count] - 1; i >= 0; i--) {
+    iCalPerson *p;
+    
+    p = [self objectAtIndex:i];
+    if ([p hasSameEmailAddress:_person])
+      [self removeObjectAtIndex:i];
+  }
+}
+
+@end
index 853ef0dc12584756ff17f680bc7b932dc374c38a..4d609ab2300223c755c679e9878d2c2e283aadba 100644 (file)
@@ -22,8 +22,6 @@
 #ifndef __Appointments_SOGoAppointmentFolder_H__
 #define __Appointments_SOGoAppointmentFolder_H__
 
-#include <SOGo/SOGoFolder.h>
-
 /*
   SOGoAppointmentFolder
     Parent object: the SOGoUserFolder
@@ -38,6 +36,8 @@
   create two different vevent-files with the same uid in the store.
 */
 
+#import "SOGo/SOGoFolder.h"
+
 @class NSString, NSArray, NSCalendarDate, NSException, NSMutableDictionary;
 @class GCSFolder;
 
 
 /* selection */
 
-- (NSArray *)calendarUIDs;
+- (NSArray *) calendarUIDs;
 
 /* vevent UID handling */
 
-- (NSString *)resourceNameForEventUID:(NSString *)_uid;
+- (NSString *) resourceNameForEventUID: (NSString *) _uid;
+- (Class) objectClassForResourceNamed: (NSString *) c_name;
 
 /* fetching */
 
-- (NSArray *)fetchFields:(NSArray *)_fields
-  fromFolder:(GCSFolder *)_folder
-  from:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate;
+- (NSArray *) fetchFields: (NSArray *) _fields
+               fromFolder: (GCSFolder *) _folder
+                     from: (NSCalendarDate *) _startDate
+                       to: (NSCalendarDate *) _endDate
+                component: (id) _component;
 
-- (NSArray *)fetchFields:(NSArray *)_fields
-  from:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate;
+- (NSArray * ) fetchFields: (NSArray *) _fields
+                      from: (NSCalendarDate *) _startDate
+                        to: (NSCalendarDate *) _endDate
+                 component: (id) _component;
 
-- (NSArray *)fetchCoreInfosFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate;
+- (NSArray *) fetchCoreInfosFrom: (NSCalendarDate *) _startDate
+                              to: (NSCalendarDate *) _endDate
+                       component: (id) _component;
 
-- (NSArray *)fetchOverviewInfosFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate;
+- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
+                                  to: (NSCalendarDate *) _endDate;
 
-- (NSArray *)fetchFreebusyInfosFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate;
+- (void) deleteEntriesWithIds: (NSArray *) ids;
 
 /* URL generation */
 
-- (NSString *)baseURLForAptWithUID:(NSString *)_uid inContext:(id)_ctx;
+- (NSString *) baseURLForAptWithUID: (NSString *) _uid
+                          inContext: (id) _ctx;
 
 /* folder management */
 
-- (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx;
+- (id) lookupHomeFolderForUID: (NSString *) _uid
+                    inContext: (id) _ctx;
 
-- (NSArray *)lookupCalendarFoldersForUIDs:(NSArray *)_uids inContext:(id)_ctx;
-- (NSArray *)lookupFreeBusyObjectsForUIDs:(NSArray *)_uids inContext:(id)_ctx;
+- (NSArray *) lookupCalendarFoldersForUIDs: (NSArray *) _uids
+                                 inContext: (id) _ctx;
+- (NSArray *) lookupFreeBusyObjectsForUIDs: (NSArray *) _uids
+                                 inContext: (id) _ctx;
 
-- (NSArray *)uidsFromICalPersons:(NSArray *)_persons;
-- (NSArray *)lookupCalendarFoldersForICalPerson:(NSArray *)_persons
-  inContext:(id)_ctx;
+- (NSArray *) uidsFromICalPersons: (NSArray *) _persons;
+- (NSArray *) lookupCalendarFoldersForICalPerson: (NSArray *) _persons
+                                       inContext: (id) _ctx;
 
-- (id)lookupGroupFolderForUIDs:(NSArray *)_uids         inContext:(id)_ctx;
-- (id)lookupGroupCalendarFolderForUIDs:(NSArray *)_uids inContext:(id)_ctx;
+- (id) lookupGroupFolderForUIDs: (NSArray *) _uids
+                      inContext: (id) _ctx;
+- (id) lookupGroupCalendarFolderForUIDs: (NSArray *) _uids
+                              inContext: (id) _ctx;
 
 /* bulk fetches */
 
-- (NSArray *)fetchAllSOGoAppointments;
+- (NSArray *) fetchAllSOGoAppointments;
 
 @end
 
index 4f442be278277cbb7fa04254b444596ede14aa64..3fe48dbad2b21b5c760f0fa9f3c109d8737babb5 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoAppointmentFolder.h"
-#include <SOGo/SOGoCustomGroupFolder.h>
-#include <SOGo/SOGoAppointment.h>
-#include <SOGo/AgenorUserManager.h>
-#include <GDLContentStore/GCSFolder.h>
-#include <SaxObjC/SaxObjC.h>
-#include <NGiCal/NGiCal.h>
-#include <NGExtensions/NGCalendarDateRange.h>
-#include "common.h"
+#import <GDLContentStore/GCSFolder.h>
+#import <SaxObjC/SaxObjC.h>
+#import <NGCards/NGCards.h>
+#import <NGObjWeb/SoObject+SoDAV.h>
+#import <NGExtensions/NGCalendarDateRange.h>
+
+#import <NGObjWeb/SoClassSecurityInfo.h>
+#import <SOGo/SOGoCustomGroupFolder.h>
+#import <SOGo/AgenorUserManager.h>
+#import <SOGo/SOGoPermissions.h>
+#import <SOGo/NSString+Utilities.h>
+
+#import "common.h"
+
+#import "SOGoAppointmentObject.h"
+#import "SOGoTaskObject.h"
+
+#import "SOGoAppointmentFolder.h"
 
 #if APPLE_Foundation_LIBRARY || NeXT_Foundation_LIBRARY
 @interface NSDate(UsedPrivates)
 @implementation SOGoAppointmentFolder
 
 static NGLogger   *logger    = nil;
-static NSTimeZone *MET       = nil;
 static NSNumber   *sharedYes = nil;
 
-+ (int)version {
++ (int) version
+{
   return [super version] + 1 /* v1 */;
 }
-+ (void)initialize {
+
++ (void) initialize
+{
   NGLoggerManager *lm;
   static BOOL     didInit = NO;
+  SoClassSecurityInfo *securityInfo;
 
   if (didInit) return;
   didInit = YES;
@@ -58,25 +70,36 @@ static NSNumber   *sharedYes = nil;
   lm      = [NGLoggerManager defaultLoggerManager];
   logger  = [lm loggerForDefaultKey:@"SOGoAppointmentFolderDebugEnabled"];
 
-  MET       = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
+  securityInfo = [self soClassSecurityInfo];
+  [securityInfo declareRole: SOGoRole_Delegate
+                asDefaultForPermission: SoPerm_AddDocumentsImagesAndFiles];
+  [securityInfo declareRole: SOGoRole_Delegate
+                asDefaultForPermission: SoPerm_ChangeImagesAndFiles];
+  [securityInfo declareRoles: [NSArray arrayWithObjects:
+                                         SOGoRole_Delegate,
+                                       SOGoRole_Assistant, nil]
+                asDefaultForPermission: SoPerm_View];
+
   sharedYes = [[NSNumber numberWithBool:YES] retain];
 }
 
-- (void)dealloc {
+- (void) dealloc
+{
   [self->uidToFilename release];
   [super dealloc];
 }
 
-
 /* logging */
 
-- (id)debugLogger {
+- (id) debugLogger
+{
   return logger;
 }
 
 /* selection */
 
-- (NSArray *)calendarUIDs {
+- (NSArray *) calendarUIDs 
+{
   /* this is used for group calendars (this folder just returns itself) */
   NSString *s;
   
@@ -86,52 +109,303 @@ static NSNumber   *sharedYes = nil;
 
 /* name lookup */
 
-- (BOOL)isValidAppointmentName:(NSString *)_key {
-  if ([_key length] == 0)
-    return NO;
-  
-  return YES;
+- (BOOL) isValidAppointmentName: (NSString *)_key
+{
+  return ([_key length] != 0);
 }
 
-- (id)appointmentWithName:(NSString *)_key inContext:(id)_ctx {
-  static Class aptClass = Nil;
-  id apt;
-  
-  if (aptClass == Nil)
-    aptClass = NSClassFromString(@"SOGoAppointmentObject");
-  if (aptClass == Nil) {
-    [self errorWithFormat:@"missing SOGoAppointmentObject class!"];
-    return nil;
-  }
-  
-  apt = [[aptClass alloc] initWithName:_key inContainer:self];
-  return [apt autorelease];
+- (id) lookupActionForCalDAVMethod: (NSString *)_key
+{
+  SoSelectorInvocation *invocation;
+  NSString *name;
+
+  name = [NSString stringWithFormat: @"%@:", [_key davMethodToObjC]];
+
+  invocation = [[SoSelectorInvocation alloc]
+                 initWithSelectorNamed: name
+                 addContextParameter: YES];
+  [invocation autorelease];
+
+  return invocation;
+}
+
+- (void) appendObject: (NSDictionary *) object
+          withBaseURL: (NSString *) baseURL
+     toREPORTResponse: (WOResponse *) r
+{
+  SOGoContentObject *ocsObject;
+  NSString *c_name, *etagLine, *dataLine;
+
+  c_name = [object objectForKey: @"c_name"];
+
+  ocsObject = [SOGoContentObject objectWithName: c_name
+                                 inContainer: self];
+
+  [r appendContentString: @"  <D:response>\r\n"];
+  [r appendContentString: @"    <D:href>"];
+  [r appendContentString: baseURL];
+  if (![baseURL hasSuffix: @"/"])
+    [r appendContentString: @"/"];
+  [r appendContentString: c_name];
+  [r appendContentString: @"</D:href>\r\n"];
+
+  [r appendContentString: @"    <D:propstat>\r\n"];
+  [r appendContentString: @"      <D:prop>\r\n"];
+  etagLine = [NSString stringWithFormat: @"        <D:getetag>%@</D:getetag>\r\n",
+                       [ocsObject davEntityTag]];
+  [r appendContentString: etagLine];
+  [r appendContentString: @"      </D:prop>\r\n"];
+  [r appendContentString: @"      <D:status>HTTP/1.1 200 OK</D:status>\r\n"];
+  [r appendContentString: @"    </D:propstat>\r\n"];
+
+  dataLine
+    = [NSString
+        stringWithFormat: @"    <C:calendar-data>%@</C:calendar-data>\r\n",
+        [ocsObject contentAsString]];
+  [r appendContentString: dataLine];
+
+  [r appendContentString: @"  </D:response>\r\n"];
+}
+
+- (void) _appendTimeRange: (id <DOMElement>) timeRangeElement
+                 toFilter: (NSMutableDictionary *) filter
+{
+  NSCalendarDate *parsedDate;
+
+  parsedDate = [[timeRangeElement attribute: @"start"] asCalendarDate];
+  [filter setObject: parsedDate forKey: @"start"];
+  parsedDate = [[timeRangeElement attribute: @"end"] asCalendarDate];
+  [filter setObject: parsedDate forKey: @"end"];
+}
+
+- (NSDictionary *) _parseCalendarFilter: (id <DOMElement>) filterElement
+{
+  NSMutableDictionary *filterData;
+  id <DOMNode> parentNode;
+  id <DOMNodeList> ranges;
+  NSString *componentName;
+
+  parentNode = [filterElement parentNode];
+  if ([[parentNode tagName] isEqualToString: @"comp-filter"]
+      && [[parentNode attribute: @"name"] isEqualToString: @"VCALENDAR"])
+    {
+      componentName = [[filterElement attribute: @"name"] lowercaseString];
+      filterData = [NSMutableDictionary new];
+      [filterData autorelease];
+      [filterData setObject: componentName forKey: @"name"];
+      ranges = [filterElement getElementsByTagName: @"time-range"];
+      if ([ranges count])
+        [self _appendTimeRange: [ranges objectAtIndex: 0]
+              toFilter: filterData];
+    }
+  else
+    filterData = nil;
+
+  return filterData;
+}
+
+- (NSArray *) _parseCalendarFilters: (id <DOMElement>) parentNode
+{
+  NSEnumerator *children;
+  id<DOMElement> node;
+  NSMutableArray *filters;
+  NSDictionary *filter;
+
+  filters = [NSMutableArray new];
+
+  children = [[parentNode getElementsByTagName: @"comp-filter"] objectEnumerator];
+  node = [children nextObject];
+  while (node)
+    {
+      filter = [self _parseCalendarFilter: node];
+      if (filter)
+        [filters addObject: filter];
+      node = [children nextObject];
+    }
+
+  return filters;
+}
+
+- (void) _appendComponentsMatchingFilters: (NSArray *) filters
+                               toResponse: (WOResponse *) response
+                                inContext: (WOContext *) context
+{
+  NSArray *apts;
+  unsigned int count, max;
+  NSDictionary *currentFilter, *appointment;
+  NSEnumerator *appointments;
+  NSString *baseURL;
+
+  baseURL = [self baseURLInContext: context];
+
+  max = [filters count];
+  for (count = 0; count < max; count++)
+    {
+      currentFilter = [filters objectAtIndex: 0];
+      apts = [self fetchCoreInfosFrom: [currentFilter objectForKey: @"start"]
+                   to: [currentFilter objectForKey: @"end"]
+                   component: [currentFilter objectForKey: @"name"]];
+      appointments = [apts objectEnumerator];
+      appointment = [appointments nextObject];
+      while (appointment)
+        {
+          [self appendObject: appointment
+                withBaseURL: baseURL
+                toREPORTResponse: response];
+          appointment = [appointments nextObject];
+        }
+    }
+}
+
+- (id) davCalendarQuery: (id) context
+{
+  WOResponse *r;
+  NSArray *filters;
+  id <DOMDocument> document;
+
+  r = [context response];
+  [r setStatus: 207];
+  [r setContentEncoding: NSUTF8StringEncoding];
+  [r setHeader: @"text/xml; charset=\"utf-8\"" forKey: @"content-type"];
+  [r setHeader: @"no-cache" forKey: @"pragma"];
+  [r setHeader: @"no-cache" forKey: @"cache-control"];
+  [r appendContentString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"];
+  [r appendContentString: @"<D:multistatus xmlns:D=\"DAV:\""
+     @" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">\r\n"];
+
+  document = [[context request] contentAsDOMDocument];
+  filters = [self _parseCalendarFilters: [document documentElement]];
+  [self _appendComponentsMatchingFilters: filters
+        toResponse: r
+        inContext: context];
+  [r appendContentString:@"</D:multistatus>\r\n"];
+
+  return r;
+}
+
+- (Class) objectClassForContent: (NSString *) content
+{
+  iCalCalendar *calendar;
+  NSArray *elements;
+  NSString *firstTag;
+  Class objectClass;
+
+  objectClass = Nil;
+
+  calendar = [iCalCalendar parseSingleFromSource: content];
+  if (calendar)
+    {
+      elements = [calendar allObjects];
+      if ([elements count])
+        {
+          firstTag = [[[elements objectAtIndex: 0] tag] uppercaseString];
+          if ([firstTag isEqualToString: @"VEVENT"])
+            objectClass = [SOGoAppointmentObject class];
+          else if ([firstTag isEqualToString: @"VTODO"])
+            objectClass = [SOGoTaskObject class];
+        }
+    }
+
+  return objectClass;
 }
 
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
+- (id) deduceObjectForName: (NSString *)_key
+                 inContext: (id)_ctx
+{
+  WORequest *request;
+  NSString *method;
+  Class objectClass;
   id obj;
-  
+
+  request = [_ctx request];
+  method = [request method];
+  if ([method isEqualToString: @"PUT"])
+    objectClass = [self objectClassForContent: [request contentAsString]];
+  else
+    objectClass = [self objectClassForResourceNamed: _key];
+
+  if (objectClass)
+    obj = [objectClass objectWithName: _key inContainer: self];
+  else
+    obj = nil;
+
+  return obj;
+}
+
+- (BOOL) requestNamedIsHandledLater: (NSString *) name
+                          inContext: (WOContext *) context
+{
+  return [name isEqualToString: @"OPTIONS"];
+}
+
+- (id) lookupName: (NSString *)_key
+        inContext: (id)_ctx
+          acquire: (BOOL)_flag
+{
+  id obj;
+  NSString *url;
+  BOOL handledLater;
+
   /* first check attributes directly bound to the application */
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
-    return obj;
-  
-  if ([self isValidAppointmentName:_key])
-    return [self appointmentWithName:_key inContext:_ctx];
-  
-  /* return 404 to stop acquisition */
-  return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
+  handledLater = [self requestNamedIsHandledLater: _key inContext: _ctx];
+  if (handledLater)
+    obj = nil;
+  else
+    {
+      obj = [super lookupName:_key inContext:_ctx acquire:NO];
+      if (!obj)
+        {
+          if ([_key hasPrefix: @"{urn:ietf:params:xml:ns:caldav}"])
+            obj
+              = [self lookupActionForCalDAVMethod: [_key substringFromIndex: 31]];
+          else if ([self isValidAppointmentName:_key])
+            {
+              url = [[[_ctx request] uri] urlWithoutParameters];
+              if ([url hasSuffix: @"AsTask"])
+                obj = [SOGoTaskObject objectWithName: _key
+                                      inContainer: self];
+              else if ([url hasSuffix: @"AsAppointment"])
+                obj = [SOGoAppointmentObject objectWithName: _key
+                                             inContainer: self];
+              else
+                obj = [self deduceObjectForName: _key
+                            inContext: _ctx];
+            }
+        }
+      if (!obj)
+        obj = [NSException exceptionWithHTTPStatus:404 /* Not Found */];
+    }
+
+  return obj;
 }
 
-/* timezone */
+- (NSArray *) davComplianceClassesInContext: (id)_ctx
+{
+  NSMutableArray *classes;
+  NSArray *primaryClasses;
+
+  classes = [NSMutableArray new];
+  [classes autorelease];
 
-- (NSTimeZone *)viewTimeZone {
-  // TODO: should use a cookie for configuration? we default to MET
-  return MET;
+  primaryClasses = [super davComplianceClassesInContext: _ctx];
+  if (primaryClasses)
+    [classes addObjectsFromArray: primaryClasses];
+  [classes addObject: @"access-control"];
+  [classes addObject: @"calendar-access"];
+
+  return classes;
+}
+
+- (NSString *) groupDavResourceType
+{
+  return @"vevent-collection";
 }
 
 /* vevent UID handling */
 
-- (NSString *)resourceNameForEventUID:(NSString *)_u inFolder:(GCSFolder *)_f {
+- (NSString *) resourceNameForEventUID: (NSString *)_u
+                              inFolder: (GCSFolder *)_f
+{
   static NSArray *nameFields = nil;
   EOQualifier *qualifier;
   NSArray     *records;
@@ -147,7 +421,7 @@ static NSNumber   *sharedYes = nil;
     nameFields = [[NSArray alloc] initWithObjects:@"c_name", nil];
   
   qualifier = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _u];
-  records   = [_f fetchFields:nameFields matchingQualifier:qualifier];
+  records   = [_f fetchFields: nameFields matchingQualifier: qualifier];
   
   if ([records count] == 1)
     return [[records objectAtIndex:0] valueForKey:@"c_name"];
@@ -159,7 +433,8 @@ static NSNumber   *sharedYes = nil;
   return [[records objectAtIndex:0] valueForKey:@"c_name"];
 }
 
-- (NSString *)resourceNameForEventUID:(NSString *)_uid {
+- (NSString *) resourceNameForEventUID: (NSString *) _uid
+{
   /* caches UIDs */
   GCSFolder *folder;
   NSString  *rname;
@@ -186,10 +461,37 @@ static NSNumber   *sharedYes = nil;
   return rname;
 }
 
+- (Class) objectClassForResourceNamed: (NSString *) c_name
+{
+  EOQualifier *qualifier;
+  NSArray *records;
+  NSString *component;
+  Class objectClass;
+
+  qualifier = [EOQualifier qualifierWithQualifierFormat:@"c_name = %@", c_name];
+  records = [[self ocsFolder] fetchFields: [NSArray arrayWithObject: @"component"]
+                              matchingQualifier: qualifier];
+
+  if ([records count])
+    {
+      component = [[records objectAtIndex:0] valueForKey: @"component"];
+      if ([component isEqualToString: @"vevent"])
+        objectClass = [SOGoAppointmentObject class];
+      else if ([component isEqualToString: @"vtodo"])
+        objectClass = [SOGoTaskObject class];
+      else
+        objectClass = Nil;
+    }
+  else
+    objectClass = Nil;
+  
+  return objectClass;
+}
+
 /* fetching */
 
-- (NSMutableDictionary *)fixupRecord:(NSDictionary *)_record
-  fetchRange:(NGCalendarDateRange *)_r
+- (NSMutableDictionary *) fixupRecord: (NSDictionary *) _record
+                           fetchRange: (NGCalendarDateRange *) _r
 {
   NSMutableDictionary *md;
   id tmp;
@@ -199,7 +501,7 @@ static NSNumber   *sharedYes = nil;
   if ((tmp = [_record objectForKey:@"startdate"])) {
     tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
           (NSTimeInterval)[tmp unsignedIntValue]];
-    [tmp setTimeZone:[self viewTimeZone]];
+    [tmp setTimeZone: [self userTimeZone]];
     if (tmp) [md setObject:tmp forKey:@"startDate"];
     [tmp release];
   }
@@ -209,7 +511,7 @@ static NSNumber   *sharedYes = nil;
   if ((tmp = [_record objectForKey:@"enddate"])) {
     tmp = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
           (NSTimeInterval)[tmp unsignedIntValue]];
-    [tmp setTimeZone:[self viewTimeZone]];
+    [tmp setTimeZone: [self userTimeZone]];
     if (tmp) [md setObject:tmp forKey:@"endDate"];
     [tmp release];
   }
@@ -219,8 +521,8 @@ static NSNumber   *sharedYes = nil;
   return md;
 }
 
-- (NSMutableDictionary *)fixupCycleRecord:(NSDictionary *)_record
-  cycleRange:(NGCalendarDateRange *)_r
+- (NSMutableDictionary *) fixupCycleRecord: (NSDictionary *) _record
+                                cycleRange: (NGCalendarDateRange *) _r
 {
   NSMutableDictionary *md;
   id tmp;
@@ -229,18 +531,18 @@ static NSNumber   *sharedYes = nil;
   
   /* cycle is in _r */
   tmp = [_r startDate];
-  [tmp setTimeZone:[self viewTimeZone]];
+  [tmp setTimeZone:[self userTimeZone]];
   [md setObject:tmp forKey:@"startDate"];
   tmp = [_r endDate];
-  [tmp setTimeZone:[self viewTimeZone]];
+  [tmp setTimeZone:[self userTimeZone]];
   [md setObject:tmp forKey:@"endDate"];
   
   return md;
 }
 
-- (void)_flattenCycleRecord:(NSDictionary *)_row
-  forRange:(NGCalendarDateRange *)_r
-  intoArray:(NSMutableArray *)_ma
+- (void) _flattenCycleRecord: (NSDictionary *) _row
+                    forRange: (NGCalendarDateRange *) _r
+                   intoArray: (NSMutableArray *) _ma
 {
   NSMutableDictionary *row;
   NSDictionary        *cycleinfo;
@@ -255,7 +557,7 @@ static NSNumber   *sharedYes = nil;
     return;
   }
 
-  row = [self fixupRecord:_row fetchRange:_r];
+  row = [self fixupRecord:_row fetchRange: _r];
   [row removeObjectForKey:@"cycleinfo"];
   [row setObject:sharedYes forKey:@"isRecurrentEvent"];
 
@@ -283,8 +585,8 @@ static NSNumber   *sharedYes = nil;
   }
 }
 
-- (NSArray *)fixupRecords:(NSArray *)_records
-  fetchRange:(NGCalendarDateRange *)_r
+- (NSArray *) fixupRecords: (NSArray *) _records
+                fetchRange: (NGCalendarDateRange *) _r
 {
   // TODO: is the result supposed to be sorted by date?
   NSMutableArray *ma;
@@ -305,8 +607,8 @@ static NSNumber   *sharedYes = nil;
   return ma;
 }
 
-- (NSArray *)fixupCyclicRecords:(NSArray *)_records
-  fetchRange:(NGCalendarDateRange *)_r
+- (NSArray *) fixupCyclicRecords: (NSArray *) _records
+                      fetchRange: (NGCalendarDateRange *) _r
 {
   // TODO: is the result supposed to be sorted by date?
   NSMutableArray *ma;
@@ -326,15 +628,51 @@ static NSNumber   *sharedYes = nil;
   return ma;
 }
 
-- (NSArray *)fetchFields:(NSArray *)_fields
-  fromFolder:(GCSFolder *)_folder
-  from:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate 
+- (NSString *) _sqlStringForComponent: (id) _component
+{
+  NSString *sqlString;
+  NSArray *components;
+
+  if (_component)
+    {
+      if ([_component isKindOfClass: [NSArray class]])
+        components = _component;
+      else
+        components = [NSArray arrayWithObject: _component];
+
+      sqlString
+        = [NSString stringWithFormat: @" AND (component = '%@')",
+                    [components componentsJoinedByString: @"' OR component = '"]];
+    }
+  else
+    sqlString = @"";
+
+  return sqlString;
+}
+
+- (NSString *) _sqlStringRangeFrom: (NSCalendarDate *) _startDate
+                                to: (NSCalendarDate *) _endDate
 {
-  EOQualifier         *qualifier;
-  NSMutableArray      *fields, *ma = nil;
-  NSArray             *records;
-  NSString            *sql;
+  unsigned int start, end;
+
+  start = (unsigned int) [_startDate timeIntervalSince1970];
+  end = (unsigned int) [_endDate timeIntervalSince1970];
+
+  return [NSString stringWithFormat:
+                     @" AND (startdate <= %d) AND (enddate >= %d)",
+                   end, start];
+}
+
+- (NSArray *) fetchFields: (NSArray *) _fields
+               fromFolder: (GCSFolder *) _folder
+                     from: (NSCalendarDate *) _startDate
+                       to: (NSCalendarDate *) _endDate 
+                component: (id) _component
+{
+  EOQualifier *qualifier;
+  NSMutableArray *fields, *ma = nil;
+  NSArray *records;
+  NSString *sql, *dateSqlString, *componentSqlString; /* , *owner; */
   NGCalendarDateRange *r;
 
   if (_folder == nil) {
@@ -343,72 +681,95 @@ static NSNumber   *sharedYes = nil;
     return nil;
   }
   
-  r = [NGCalendarDateRange calendarDateRangeWithStartDate:_startDate
-                           endDate:_endDate];
+  if (_startDate && _endDate)
+    {
+      r = [NGCalendarDateRange calendarDateRangeWithStartDate: _startDate
+                               endDate: _endDate];
+      dateSqlString = [self _sqlStringRangeFrom: _startDate to: _endDate];
+    }
+  else
+    {
+      r = nil;
+      dateSqlString = @"";
+    }
+
+  componentSqlString = [self _sqlStringForComponent: _component];
 
   /* prepare mandatory fields */
 
-  fields = [NSMutableArray arrayWithArray:_fields];
-  [fields addObject:@"uid"];
-  [fields addObject:@"startdate"];
-  [fields addObject:@"enddate"];
-  
+  fields = [NSMutableArray arrayWithArray: _fields];
+  [fields addObject: @"uid"];
+  [fields addObject: @"startdate"];
+  [fields addObject: @"enddate"];
+
   if (logger)
     [self debugWithFormat:@"should fetch (%@=>%@) ...", _startDate, _endDate];
-  
-  sql = [NSString stringWithFormat:@"(startdate < %d) AND (enddate > %d)"
-                                   @" AND (iscycle = 0)",
-                 (unsigned int)[_endDate   timeIntervalSince1970],
-                 (unsigned int)[_startDate timeIntervalSince1970]];
+
+  sql = [NSString stringWithFormat: @"(iscycle = 0)%@%@",
+                  dateSqlString, componentSqlString];
 
   /* fetch non-recurrent apts first */
-  qualifier = [EOQualifier qualifierWithQualifierFormat:sql];
-
-  records   = [_folder fetchFields:fields matchingQualifier:qualifier];
-  if (records != nil) {
-    records = [self fixupRecords:records fetchRange:r];
-    if (logger)
-      [self debugWithFormat:@"fetched %i records: %@",[records count],records];
-    ma = [NSMutableArray arrayWithArray:records];
-  }
-  
+  qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
+
+  records = [_folder fetchFields: fields matchingQualifier: qualifier];
+  if (records)
+    {
+      if (r)
+        records = [self fixupRecords: records fetchRange: r];
+      if (logger)
+        [self debugWithFormat: @"fetched %i records: %@",
+              [records count], records];
+      ma = [NSMutableArray arrayWithArray: records];
+    }
+
   /* fetch recurrent apts now */
-  sql = [NSString stringWithFormat:@"(startdate < %d) AND (cycleenddate > %d)"
-                                   @" AND (iscycle = 1)",
-                 (unsigned int)[_endDate   timeIntervalSince1970],
-                 (unsigned int)[_startDate timeIntervalSince1970]];
-  qualifier = [EOQualifier qualifierWithQualifierFormat:sql];
-
-  [fields addObject:@"cycleinfo"];
-
-  records = [_folder fetchFields:fields matchingQualifier:qualifier];
-  if (records != nil) {
-    if (logger)
-      [self debugWithFormat:@"fetched %i cyclic records: %@",
-        [records count], records];
-    records = [self fixupCyclicRecords:records fetchRange:r];
-    if (!ma) ma = [NSMutableArray arrayWithCapacity:[records count]];
-    [ma addObjectsFromArray:records];
-  }
-  else if (ma == nil) {
-    [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
-    return nil;
-  }
+  sql = [NSString stringWithFormat: @"(iscycle = 1)%@%@",
+                  dateSqlString, componentSqlString];
+  qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
+
+  [fields addObject: @"cycleinfo"];
+
+  records = [_folder fetchFields: fields matchingQualifier: qualifier];
+  if (records)
+    {
+      if (logger)
+        [self debugWithFormat: @"fetched %i cyclic records: %@",
+              [records count], records];
+      if (r)
+        records = [self fixupCyclicRecords: records fetchRange: r];
+      if (!ma)
+        ma = [NSMutableArray arrayWithCapacity: [records count]];
+
+//       owner = [self ownerInContext: nil];
+      [ma addObjectsFromArray: records];
+    }
+  else if (!ma)
+    {
+      [self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__];
+      return nil;
+    }
+
   /* NOTE: why do we sort here?
      This probably belongs to UI but cannot be achieved as fast there as
      we can do it here because we're operating on a mutable array -
      having the apts sorted is never a bad idea, though
   */
-  [ma sortUsingSelector:@selector(compareAptsAscending:)];
+  [ma sortUsingSelector: @selector (compareAptsAscending:)];
   if (logger)
     [self debugWithFormat:@"returning %i records", [ma count]];
+
+//   [ma makeObjectsPerform: @selector (setObject:forKey:)
+//       withObject: owner
+//       withObject: @"owner"];
+
   return ma;
 }
 
 /* override this in subclasses */
-- (NSArray *)fetchFields:(NSArray *)_fields
-  from:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate 
+- (NSArray *) fetchFields: (NSArray *) _fields
+                     from: (NSCalendarDate *) _startDate
+                       to: (NSCalendarDate *) _endDate 
+                component: (id) _component
 {
   GCSFolder *folder;
   
@@ -417,59 +778,76 @@ static NSNumber   *sharedYes = nil;
       __PRETTY_FUNCTION__];
     return nil;
   }
-  return [self fetchFields:_fields fromFolder:folder
-               from:_startDate to:_endDate];
+
+  return [self fetchFields: _fields fromFolder: folder
+               from: _startDate to: _endDate
+               component: _component];
 }
 
 
-- (NSArray *)fetchFreebusyInfosFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate
+- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
+                                  to: (NSCalendarDate *) _endDate
 {
   static NSArray *infos = nil; // TODO: move to a plist file
-  if (infos == nil) {
-    infos = [[NSArray alloc] initWithObjects:@"partmails", @"partstates", nil];
-  }
-  return [self fetchFields:infos from:_startDate to:_endDate];
-}
+  
+  if (!infos)
+    infos = [[NSArray alloc] initWithObjects: @"partmails", @"partstates",
+                             @"isopaque", @"status", nil];
 
+  return [self fetchFields: infos from: _startDate to: _endDate
+               component: @"vevent"];
+}
 
-- (NSArray *)fetchOverviewInfosFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate
+- (NSArray *) fetchCoreInfosFrom: (NSCalendarDate *) _startDate
+                              to: (NSCalendarDate *) _endDate
+                       component: (id) _component
 {
   static NSArray *infos = nil; // TODO: move to a plist file
-  if (infos == nil) {
+
+  if (!infos)
     infos = [[NSArray alloc] initWithObjects:
-                               @"title", 
-                               @"location", @"orgmail", @"status", @"ispublic",
-                               @"isallday", @"priority",
-                               @"partmails", @"partstates",
-                               nil];
-  }
-  return [self fetchFields:infos
-               from:_startDate
-               to:_endDate];
+                               @"c_name", @"component",
+                             @"title", @"location", @"orgmail",
+                             @"status", @"ispublic",
+                             @"isallday", @"isopaque",
+                             @"participants", @"partmails",
+                             @"partstates", @"sequence", @"priority", nil];
+
+  return [self fetchFields: infos from: _startDate to: _endDate component: _component];
 }
 
-- (NSArray *)fetchCoreInfosFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate 
+- (void) deleteEntriesWithIds: (NSArray *) ids
 {
-  static NSArray *infos = nil; // TODO: move to a plist file
-  if (infos == nil) {
-    infos = [[NSArray alloc] initWithObjects:
-                               @"title", @"location", @"orgmail",
-                               @"status", @"ispublic",
-                               @"isallday", @"isopaque",
-                               @"participants", @"partmails",
-                               @"partstates", @"sequence", @"priority", nil];
-  }
-  return [self fetchFields:infos
-               from:_startDate
-               to:_endDate];
+  Class objectClass;
+  unsigned int count, max;
+  NSString *currentId, *currentUser;
+  WOContext *context;
+  id deleteObject;
+
+  context = [[WOApplication application] context];
+  currentUser = [[context activeUser] login];
+
+  max = [ids count];
+  for (count = 0; count < max; count++)
+    {
+      currentId = [ids objectAtIndex: count];
+      objectClass
+        = [self objectClassForResourceNamed: currentId];
+      deleteObject = [objectClass objectWithName: currentId
+                                  inContainer: self];
+      if ([currentUser isEqualToString: [deleteObject ownerInContext: nil]])
+        {
+          [deleteObject delete];
+          [deleteObject primaryDelete];
+        }
+    }
 }
 
 /* URL generation */
 
-- (NSString *)baseURLForAptWithUID:(NSString *)_uid inContext:(id)_ctx {
+- (NSString *) baseURLForAptWithUID: (NSString *)_uid
+                          inContext: (id)_ctx
+{
   // TODO: who calls this?
   NSString *url;
   
@@ -486,7 +864,9 @@ static NSNumber   *sharedYes = nil;
 
 /* folder management */
 
-- (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx {
+- (id) lookupHomeFolderForUID: (NSString *) _uid
+                    inContext: (id)_ctx
+{
   // TODO: DUP to SOGoGroupFolder
   NSException *error = nil;
   NSArray     *path;
@@ -523,7 +903,9 @@ static NSNumber   *sharedYes = nil;
   return result;
 }
 
-- (NSArray *)lookupCalendarFoldersForUIDs:(NSArray *)_uids inContext:(id)_ctx {
+- (NSArray *) lookupCalendarFoldersForUIDs: (NSArray *) _uids
+                                 inContext: (id)_ctx
+{
   /* Note: can return NSNull objects in the array! */
   NSMutableArray *folders;
   NSEnumerator *e;
@@ -550,7 +932,9 @@ static NSNumber   *sharedYes = nil;
   return folders;
 }
 
-- (NSArray *)lookupFreeBusyObjectsForUIDs:(NSArray *)_uids inContext:(id)_ctx {
+- (NSArray *) lookupFreeBusyObjectsForUIDs: (NSArray *) _uids
+                                 inContext: (id) _ctx
+{
   /* Note: can return NSNull objects in the array! */
   NSMutableArray *objs;
   NSEnumerator   *e;
@@ -577,7 +961,8 @@ static NSNumber   *sharedYes = nil;
   return objs;
 }
 
-- (NSArray *)uidsFromICalPersons:(NSArray *)_persons {
+- (NSArray *) uidsFromICalPersons: (NSArray *) _persons
+{
   /* Note: can return NSNull objects in the array! */
   NSMutableArray    *uids;
   AgenorUserManager *um;
@@ -608,8 +993,8 @@ static NSNumber   *sharedYes = nil;
   return uids;
 }
 
-- (NSArray *)lookupCalendarFoldersForICalPerson:(NSArray *)_persons
-  inContext:(id)_ctx
+- (NSArray *)lookupCalendarFoldersForICalPerson: (NSArray *) _persons
+                                      inContext: (id) _ctx
 {
   /* Note: can return NSNull objects in the array! */
   NSArray *uids;
@@ -620,7 +1005,9 @@ static NSNumber   *sharedYes = nil;
   return [self lookupCalendarFoldersForUIDs:uids inContext:_ctx];
 }
 
-- (id)lookupGroupFolderForUIDs:(NSArray *)_uids inContext:(id)_ctx {
+- (id) lookupGroupFolderForUIDs: (NSArray *) _uids
+                      inContext: (id)_ctx
+{
   SOGoCustomGroupFolder *folder;
   
   if (_uids == nil)
@@ -629,7 +1016,10 @@ static NSNumber   *sharedYes = nil;
   folder = [[SOGoCustomGroupFolder alloc] initWithUIDs:_uids inContainer:self];
   return [folder autorelease];
 }
-- (id)lookupGroupCalendarFolderForUIDs:(NSArray *)_uids inContext:(id)_ctx {
+
+- (id) lookupGroupCalendarFolderForUIDs: (NSArray *) _uids
+                              inContext: (id) _ctx
+{
   SOGoCustomGroupFolder *folder;
   
   if ((folder = [self lookupGroupFolderForUIDs:_uids inContext:_ctx]) == nil)
@@ -649,7 +1039,8 @@ static NSNumber   *sharedYes = nil;
 
 /* bulk fetches */
 
-- (NSArray *)fetchAllSOGoAppointments {
+- (NSArray *) fetchAllSOGoAppointments
+{
   /* 
      Note: very expensive method, do not use unless absolutely required.
            returns an array of SOGoAppointment objects.
@@ -672,44 +1063,16 @@ static NSNumber   *sharedYes = nil;
   
   events   = [NSMutableArray arrayWithCapacity:[files count]];
   contents = [files objectEnumerator];
-  while ((content = [contents nextObject]) != nil) {
-    SOGoAppointment *event;
-    
-    event = [[SOGoAppointment alloc] initWithICalString:content];
-    if (![event isNotNull]) {
-      [self errorWithFormat:@"(%s): could not parse an iCal file!",
-              __PRETTY_FUNCTION__];
-      continue;
-    }
-
-    [events addObject:event];
-    [event release];
-  }
+  while ((content = [contents nextObject]) != nil)
+    [events addObject: [iCalCalendar parseSingleFromSource: content]];
   
   return events;
 }
 
-/* GET */
-
-- (id)GETAction:(id)_ctx {
-  // TODO: I guess this should really be done by SOPE (redirect to
-  //       default method)
-  WOResponse *r;
-  NSString *uri;
-
-  uri = [[(WOContext *)_ctx request] uri];
-  if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
-  uri = [uri stringByAppendingString:@"weekoverview"];
-
-  r = [_ctx response];
-  [r setStatus:302 /* moved */];
-  [r setHeader:uri forKey:@"location"];
-  return r;
-}
-
 /* folder type */
 
-- (NSString *)outlookFolderClass {
+- (NSString *) outlookFolderClass
+{
   return @"IPF.Appointment";
 }
 
index ef2280c80b76ff7f44ea8891ed30ff8f992db336..ccca7fb7fc23ce31c77e24341d05c41048376111 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef __Appointments_SOGoAppointmentObject_H__
 #define __Appointments_SOGoAppointmentObject_H__
 
-#include <SOGo/SOGoContentObject.h>
+#import <SOGo/SOGoContentObject.h>
 
 /*
   SOGoAppointmentObject
         appointments with an externally generated unique key.
 */
 
-@class NSString, NSArray, NSException, iCalEvent;
+@class NSArray;
+@class NSException;
+@class NSString;
 
-@interface SOGoAppointmentObject : SOGoContentObject
-{
-}
+@class iCalEvent;
+@class iCalCalendar;
+
+#import "SOGoCalendarComponent.h"
+
+@interface SOGoAppointmentObject : SOGoCalendarComponent
 
 /* accessors */
 
-- (NSString *)iCalString;
-- (iCalEvent *)event;
+- (iCalEvent *) event;
+- (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) calendar;
 
 /* folder management */
 
@@ -67,6 +72,7 @@
 - (NSException *)changeParticipationStatus:(NSString *)_status
   inContext:(id)_ctx;
 
+
 @end
 
 #endif /* __Appointments_SOGoAppointmentObject_H__ */
index a563ceed2159c11f50851f98ea4f2499c4d10a19..6f34456ca7cd5d5469a07c18aa8596a72ca92775 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoAppointmentObject.h"
-#include <SOGo/AgenorUserManager.h>
-#include <SOGo/SOGoAppointment.h>
-#include <SaxObjC/SaxObjC.h>
-#include <NGiCal/NGiCal.h>
-#include <NGMime/NGMime.h>
-#include <NGMail/NGMail.h>
-#include <NGMail/NGSendMail.h>
-#include "SOGoAptMailNotification.h"
-#include "common.h"
-
-@interface NSMutableArray (iCalPersonConvenience)
-- (void)removePerson:(iCalPerson *)_person;
-@end
+#import "SOGoAppointmentObject.h"
+
+#import <NGCards/iCalCalendar.h>
+#import <NGCards/iCalEvent.h>
+#import <NGCards/iCalEventChanges.h>
+#import <NGCards/iCalPerson.h>
+#import <NGMime/NGMime.h>
+#import <NGMail/NGMail.h>
+#import <NGMail/NGSendMail.h>
+
+#import <SOGo/AgenorUserManager.h>
+#import <SOGo/SOGoObject.h>
+
+#import "SOGoAptMailNotification.h"
+#import "iCalEntityObject+Agenor.h"
+
+#import "common.h"
+
+#import "NSArray+Appointments.h"
 
 @interface SOGoAppointmentObject (PrivateAPI)
-- (NSString *)homePageURLForPerson:(iCalPerson *)_person;
-- (NSTimeZone *)viewTimeZoneForPerson:(iCalPerson *)_person;
+- (NSString *) homePageURLForPerson: (iCalPerson *) _person;
   
 - (void)sendEMailUsingTemplateNamed:(NSString *)_pageName
-  forOldAppointment:(SOGoAppointment *)_newApt
-  andNewAppointment:(SOGoAppointment *)_oldApt
+  forOldAppointment:(iCalEvent *)_newApt
+  andNewAppointment:(iCalEvent *)_oldApt
   toAttendees:(NSArray *)_attendees;
 
-- (void)sendInvitationEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendInvitationEMailForAppointment:(iCalEvent *)_apt
   toAttendees:(NSArray *)_attendees;
-- (void)sendAppointmentUpdateEMailForOldAppointment:(SOGoAppointment *)_oldApt
-  newAppointment:(SOGoAppointment *)_newApt
+- (void)sendAppointmentUpdateEMailForOldAppointment:(iCalEvent *)_oldApt
+  newAppointment:(iCalEvent *)_newApt
   toAttendees:(NSArray *)_attendees;
-- (void)sendAttendeeRemovalEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendAttendeeRemovalEMailForAppointment:(iCalEvent *)_apt
   toAttendees:(NSArray *)_attendees;
-- (void)sendAppointmentDeletionEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendAppointmentDeletionEMailForAppointment:(iCalEvent *)_apt
   toAttendees:(NSArray *)_attendees;
 @end
 
 @implementation SOGoAppointmentObject
 
-static id<NSObject,SaxXMLReader> parser  = nil;
-static SaxObjectDecoder          *sax    = nil;
-static NGLogger                  *logger = nil;
-static NSTimeZone                *MET    = nil;
 static NSString                  *mailTemplateDefaultLanguage = nil;
 
 + (void)initialize {
   NSUserDefaults      *ud;
-  NGLoggerManager     *lm;
-  SaxXMLReaderFactory *factory;
   static BOOL         didInit = NO;
   
   if (didInit) return;
   didInit = YES;
   
-  lm      = [NGLoggerManager defaultLoggerManager];
-  logger  = [lm loggerForClass:self];
-  
-  factory = [SaxXMLReaderFactory standardXMLReaderFactory];
-  parser  = [[factory createXMLReaderForMimeType:@"text/calendar"]
-    retain];
-  if (parser == nil)
-    [logger fatalWithFormat:@"did not find a parser for text/calendar!"];
-  sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
-  if (sax == nil)
-    [logger fatalWithFormat:@"could not create the iCal SAX handler!"];
-  
-  [parser setContentHandler:sax];
-  [parser setErrorHandler:sax];
-
-  MET = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
-  
   ud = [NSUserDefaults standardUserDefaults];
   mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"]
                                      retain];
@@ -95,37 +76,16 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
     mailTemplateDefaultLanguage = @"French";
 }
 
-- (void)dealloc {
-  [super dealloc];
-}
-
 /* accessors */
 
-- (NSString *)iCalString {
-  // for UI-X appointment viewer
-  return [self contentAsString];
-}
-
-- (iCalEvent *)event {
-  NSString  *iCalString;
-  iCalEvent *event;
-
-  iCalString = [self iCalString];
-  if ([iCalString length] > 0) {
-    iCalCalendar *cal;
-
-    [parser parseFromSource:iCalString];
-    cal   = [sax rootObject];
-    [sax reset];
-    event = [[cal events] lastObject];
-    return event;
-  }
-  return nil;
+- (iCalEvent *) event
+{
+  return [self firstEventFromCalendar: [self calendar]];
 }
 
 /* iCal handling */
 
-- (NSArray *)attendeeUIDsFromAppointment:(SOGoAppointment *)_apt {
+- (NSArray *)attendeeUIDsFromAppointment:(iCalEvent *)_apt {
   AgenorUserManager *um;
   NSMutableArray    *uids;
   NSArray  *attendees;
@@ -212,14 +172,27 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
     
     if (![folder isNotNull]) /* no folder was found for given UID */
       continue;
-    
-    apt = [folder lookupName:[self nameInContainer] inContext:ctx
-                 acquire:NO];
+
+    apt = [folder lookupName: [self nameInContainer] inContext:ctx
+                 acquire: NO];
+    if ([apt isKindOfClass: [NSException class]])
+      {
+        [self logWithFormat:@"Note: an exception occured finding '%@' in folder: %@",
+             [self nameInContainer], folder];
+        [self logWithFormat:@"the exception reason was: %@",
+              [(NSException *) apt reason]];
+        continue;
+      }
+
     if (![apt isNotNull]) {
       [self logWithFormat:@"Note: did not find '%@' in folder: %@",
              [self nameInContainer], folder];
       continue;
     }
+    if ([apt isKindOfClass: [NSException class]]) {
+      [self logWithFormat:@"Exception: %@", [(NSException *) apt reason]];
+      continue;
+    }
     
     if ((error = [apt primarySaveContentString:_iCal]) != nil) {
       [self logWithFormat:@"Note: failed to save iCal in folder: %@", folder];
@@ -245,9 +218,8 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
     
     apt = [folder lookupName:[self nameInContainer] inContext:ctx
                  acquire:NO];
-    if (![apt isNotNull]) {
-      [self logWithFormat:@"Note: did not find '%@' in folder: %@",
-             [self nameInContainer], folder];
+    if ([apt isKindOfClass: [NSException class]]) {
+      [self logWithFormat: @"%@", [(NSException *) apt reason]];
       continue;
     }
     
@@ -260,9 +232,26 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   return allErrors;
 }
 
+- (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) aCalendar
+{
+  iCalEvent *event;
+  NSArray *events;
+
+  events = [aCalendar childrenWithTag: @"vevent"];
+  if ([events count])
+    event = (iCalEvent *) [[events objectAtIndex: 0]
+                            groupWithClass: [iCalEvent class]];
+  else
+    event = nil;
+
+  return event;
+}
+
 /* "iCal multifolder saves" */
 
-- (NSException *)saveContentString:(NSString *)_iCal baseSequence:(int)_v {
+- (NSException *) saveContentString: (NSString *) _iCal
+                       baseSequence: (int) _v
+{
   /* 
      Note: we need to delete in all participants folders and send iMIP messages
            for all external accounts.
@@ -280,7 +269,8 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
      - send iMIP mail for all folders not found
   */
   AgenorUserManager *um;
-  SOGoAppointment   *oldApt, *newApt;
+  iCalCalendar *newCalendar;
+  iCalEvent *oldApt, *newApt;
   iCalEventChanges  *changes;
   iCalPerson        *organizer;
   NSString          *oldContent, *uid;
@@ -301,15 +291,14 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   /* handle old content */
   
   oldContent = [self iCalString]; /* if nil, this is a new appointment */
-  if ([oldContent length] == 0) {
+  if ([oldContent length] == 0)
+    {
     /* new appointment */
-    [self debugWithFormat:@"saving new appointment: %@", _iCal];
-    oldApt = nil;
-  }
-  else {
-    oldApt = 
-      [[[SOGoAppointment alloc] initWithICalString:oldContent] autorelease];
-  }
+      [self debugWithFormat:@"saving new appointment: %@", _iCal];
+      oldApt = nil;
+    }
+  else
+    oldApt = [self firstEventFromCalendar: [self calendar]];
   
   /* compare sequence if requested */
 
@@ -320,7 +309,8 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   
   /* handle new content */
   
-  newApt  = [[[SOGoAppointment alloc] initWithICalString:_iCal] autorelease];
+  newCalendar = [iCalCalendar parseSingleFromSource: _iCal];
+  newApt = [self firstEventFromCalendar: newCalendar];
   if (newApt == nil) {
     return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
                        reason:@"could not parse iCalendar content!"];
@@ -328,8 +318,8 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   
   /* diff */
   
-  changes     = [iCalEventChanges changesFromEvent:[oldApt event]
-                                  toEvent:[newApt event]];
+  changes = [iCalEventChanges changesFromEvent: oldApt
+                              toEvent: newApt];
 
   uids        = [um getUIDsForICalPersons:[changes deletedAttendees]
                     applyStrictMapping:NO];
@@ -346,7 +336,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
 
   /* preserve organizer */
 
-  organizer = [[newApt event] organizer];
+  organizer = [newApt organizer];
   uid       = [um getUIDForICalPerson:organizer];
   if (uid) {
     if (![storeUIDs containsObject:uid])
@@ -356,8 +346,8 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
 
   /* organizer might have changed completely */
 
-  if ((oldApt != nil) && ([props containsObject:@"organizer"])) {
-    uid = [um getUIDForICalPerson:[[oldApt event] organizer]];
+  if (oldApt && ([props containsObject: @"organizer"])) {
+    uid = [um getUIDForICalPerson:[oldApt organizer]];
     if (uid) {
       if (![storeUIDs containsObject:uid]) {
         if (![removedUIDs containsObject:uid]) {
@@ -374,7 +364,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
    * ... exception from that rule: the organizer
    */
 
-  if (oldApt != nil                        &&
+  if (oldApt != nil &&
       ([props containsObject:@"startDate"] ||
        [props containsObject:@"endDate"]   ||
        [props containsObject:@"duration"]))
@@ -391,7 +381,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
       if (![p hasSameEmailAddress:organizer])
         [p setParticipationStatus:iCalPersonPartStatNeedsAction];
     }
-    _iCal = [newApt iCalString];
+    _iCal = [[newApt parent] versitString];
     updateForcesReconsider = YES;
   }
 
@@ -412,7 +402,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
         toAttendees:attendees];
 
   if (updateForcesReconsider) {
-    attendees = [NSMutableArray arrayWithArray:[[newApt event] attendees]];
+    attendees = [NSMutableArray arrayWithArray:[newApt attendees]];
     [attendees removeObjectsInArray:[changes insertedAttendees]];
     [attendees removePerson:organizer];
     [self sendAppointmentUpdateEMailForOldAppointment:oldApt
@@ -421,14 +411,14 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   }
 
   attendees = [NSMutableArray arrayWithArray:[changes deletedAttendees]];
-  [attendees removePerson:organizer];
+  [attendees removePerson: organizer];
   if ([attendees count]) {
-    SOGoAppointment *canceledApt;
+    iCalEvent *canceledApt;
     
     canceledApt = [newApt copy];
-    [canceledApt cancelWithoutIncreasingSequence];
+    [(iCalCalendar *) [canceledApt parent] setMethod: @"cancel"];
     [self sendAttendeeRemovalEMailForAppointment:canceledApt
-          toAttendees:attendees];
+          toAttendees: attendees];
     [canceledApt release];
   }
   return nil;
@@ -449,15 +439,13 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
      - delete in removed folders
      - send iMIP mail for all folders not found
   */
-  SOGoAppointment *apt;
-  NSString        *econtent;
+  iCalEvent *apt;
   NSArray         *removedUIDs;
   NSMutableArray  *attendees;
 
   /* load existing content */
-  
-  econtent = [self iCalString]; /* if nil, this is a new appointment */
-  apt = [[[SOGoAppointment alloc] initWithICalString:econtent] autorelease];
+
+  apt = [self event];  
   
   /* compare sequence if requested */
 
@@ -468,11 +456,13 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   removedUIDs = [self attendeeUIDsFromAppointment:apt];
 
   /* send notification email to attendees excluding organizer */
-  attendees = [NSMutableArray arrayWithArray:[[apt event] attendees]];
+  attendees = [NSMutableArray arrayWithArray:[apt attendees]];
   [attendees removePerson:[apt organizer]];
   
   /* flag appointment as being canceled */
-  [apt cancelAndIncreaseSequence];
+  [(iCalCalendar *) [apt parent] setMethod: @"cancel"];
+  [apt increaseSequence];
+
   /* remove all attendees to signal complete removal */
   [apt removeAllAttendees];
 
@@ -488,22 +478,19 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
 - (NSException *)saveContentString:(NSString *)_iCalString {
   return [self saveContentString:_iCalString baseSequence:0];
 }
-- (NSException *)delete {
-  return [self deleteWithBaseSequence:0];
-}
-
 
 - (NSException *)changeParticipationStatus:(NSString *)_status
   inContext:(id)_ctx
 {
-  SOGoAppointment *apt;
+  iCalEvent *apt;
   iCalPerson      *p;
   NSString        *newContent;
   NSException     *ex;
   NSString        *myEMail;
   
   // TODO: do we need to use SOGoAppointment? (prefer iCalEvent?)
-  apt = [[SOGoAppointment alloc] initWithICalString:[self iCalString]];
+  apt = [self event];
+
   if (apt == nil) {
     return [NSException exceptionWithHTTPStatus:500 /* Server Error */
                         reason:@"unable to parse appointment record"];
@@ -517,11 +504,11 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   }
   
   [p setPartStat:_status];
-  newContent = [[[apt iCalString] copy] autorelease];
+  newContent = [[apt parent] versitString];
   
   // TODO: send iMIP reply mails?
   
-  [apt release]; apt = nil;
+//   [apt release]; apt = nil;
   
   if (newContent == nil) {
     return [NSException exceptionWithHTTPStatus:500 /* Server Error */
@@ -574,18 +561,39 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   return [NSString stringWithFormat:@"%@%@", baseURL, uid];
 }
 
-- (NSTimeZone *)viewTimeZoneForPerson:(iCalPerson *)_person {
-  /* TODO: get this from user config as soon as this is available and only
-   *       fall back to default timeZone if config data is not available
-   */
-  return MET;
-}
+- (NSException *) saveContentString: (NSString *) contentString
+                        baseVersion: (unsigned int) baseVersion
+{
+  NSString *newContentString, *oldContentString;
+  iCalCalendar *eventCalendar;
+  iCalEvent *event;
+  NSArray *organizers;
+
+  oldContentString = [self iCalString];
+  if (oldContentString)
+    newContentString = contentString;
+  else
+    {
+      eventCalendar = [iCalCalendar parseSingleFromSource: contentString];
+      event = [self firstEventFromCalendar: eventCalendar];
+      organizers = [event childrenWithTag: @"organizer"];
+      if ([organizers count])
+        newContentString = contentString;
+      else
+        {
+          [event setOrganizerWithUid: [[self container] ownerInContext: nil]];
+          newContentString = [eventCalendar versitString];
+        }
+    }
 
+  return [super saveContentString: newContentString
+                baseVersion: baseVersion];
+}
 
-- (void)sendEMailUsingTemplateNamed:(NSString *)_pageName
-  forOldAppointment:(SOGoAppointment *)_oldApt
-  andNewAppointment:(SOGoAppointment *)_newApt
-  toAttendees:(NSArray *)_attendees
+- (void)sendEMailUsingTemplateNamed: (NSString *)_pageName
+                  forOldAppointment: (iCalEvent *)_oldApt
+                  andNewAppointment: (iCalEvent *)_newApt
+                        toAttendees: (NSArray *)_attendees
 {
   NSString                *pageName;
   iCalPerson              *organizer;
@@ -610,7 +618,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   }
 
   /* generate iCalString once */
-  iCalString = [_newApt iCalString];
+  iCalString = [[_newApt parent] versitString];
   
   /* get sendmail object */
   sendmail   = [NGSendMail sharedSendMail];
@@ -654,7 +662,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
     [p setNewApt:_newApt];
     [p setOldApt:_oldApt];
     [p setHomePageURL:[self homePageURLForPerson:attendee]];
-    [p setViewTZ:[self viewTimeZoneForPerson:attendee]];
+    [p setViewTZ: [self userTimeZone: cn]];
     subject = [p getSubject];
     text    = [p getBody];
 
@@ -688,7 +696,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
     /* calendar part */
     header     = [NSString stringWithFormat:@"text/calendar; method=%@;"
                                             @" charset=utf-8",
-                                            [_newApt method]];
+                           [(iCalCalendar *) [_newApt parent] method]];
     headerMap  = [NGMutableHashMap hashMapWithCapacity:1];
     [headerMap setObject:header forKey:@"content-type"];
     bodyPart   = [NGMimeBodyPart bodyPartWithHeader:headerMap];
@@ -708,7 +716,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
   }
 }
 
-- (void)sendInvitationEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendInvitationEMailForAppointment:(iCalEvent *)_apt
   toAttendees:(NSArray *)_attendees
 {
   if (![_attendees count]) return; // another job neatly done :-)
@@ -719,8 +727,8 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
         toAttendees:_attendees];
 }
 
-- (void)sendAppointmentUpdateEMailForOldAppointment:(SOGoAppointment *)_oldApt
-  newAppointment:(SOGoAppointment *)_newApt
+- (void)sendAppointmentUpdateEMailForOldAppointment:(iCalEvent *)_oldApt
+  newAppointment:(iCalEvent *)_newApt
   toAttendees:(NSArray *)_attendees
 {
   if (![_attendees count]) return;
@@ -731,7 +739,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
         toAttendees:_attendees];
 }
 
-- (void)sendAttendeeRemovalEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendAttendeeRemovalEMailForAppointment:(iCalEvent *)_apt
   toAttendees:(NSArray *)_attendees
 {
   if (![_attendees count]) return;
@@ -742,7 +750,7 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
         toAttendees:_attendees];
 }
 
-- (void)sendAppointmentDeletionEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendAppointmentDeletionEMailForAppointment:(iCalEvent *)_apt
   toAttendees:(NSArray *)_attendees
 {
   if (![_attendees count]) return;
@@ -753,20 +761,33 @@ static NSString                  *mailTemplateDefaultLanguage = nil;
         toAttendees:_attendees];
 }
 
-@end /* SOGoAppointmentObject */
+- (NSString *) davContentType
+{
+  return @"text/calendar";
+}
 
-@implementation NSMutableArray (iCalPersonConvenience)
+- (NSString *) roleOfUser: (NSString *) login
+                inContext: (WOContext *) context
+{
+  AgenorUserManager *um;
+  iCalEvent *event;
+  NSString *role, *email;
 
-- (void)removePerson:(iCalPerson *)_person {
-  int i;
-  
-  for (i = [self count] - 1; i >= 0; i--) {
-    iCalPerson *p;
-    
-    p = [self objectAtIndex:i];
-    if ([p hasSameEmailAddress:_person])
-      [self removeObjectAtIndex:i];
-  }
+  um = [AgenorUserManager sharedUserManager];
+  email = [um getEmailForUID: login];
+
+  event = [self event];
+  if ([event isOrganizer: email])
+    role = @"Organizer";
+  else if ([event isParticipant: email])
+    role = @"Participant";
+  else
+    role = nil;
+
+  return role;
 }
 
-@end /* NSMutableArray (iCalPersonConvenience) */
+@end /* SOGoAppointmentObject */
+
+
+
index 99330d746cf502c6fd39b64a67a78dd234c78d5b..9345717579e0cefb1cc8ab87d0b9e27352d404c6 100644 (file)
@@ -25,6 +25,7 @@
 #include <NGObjWeb/SoComponent.h>
 
 @class NSString, NSTimeZone, NSCalendarDate;
+@class iCalEntityObject;
 
 /*
  * NOTE: We inherit from SoComponent in order to get the correct
  */
 @interface SOGoAptMailNotification : SoComponent
 {
-  id             oldApt;
-  id             newApt;
-  NSString       *homePageURL;
-  NSTimeZone     *viewTZ;
+  iCalEntityObject* oldApt;
+  iCalEntityObject* newApt;
+  NSString *homePageURL;
+  NSTimeZone *viewTZ;
   NSCalendarDate *oldStartDate;
   NSCalendarDate *newStartDate;
-  BOOL           isSubject;
+  BOOL isSubject;
 }
 
-- (id)oldApt;
-- (void)setOldApt:(id)_oldApt;
+- (id) oldApt;
+- (void) setOldApt: (iCalEntityObject *) _oldApt;
 
-- (id)newApt;
-- (void)setNewApt:(id)_newApt;
+- (id) newApt;
+- (void) setNewApt: (iCalEntityObject *) _newApt;
 
 - (NSString *)homePageURL;
-- (void)setHomePageURL:(NSString *)_homePageURL;
+- (void)setHomePageURL: (NSString *)_homePageURL;
 
 - (NSTimeZone *)viewTZ;
 - (void)setViewTZ:(NSTimeZone *)_viewTZ;
index 0e1ecc8190bf20dec8b05021524294360ce5a515..bba1ef46ce4be13bbf6487e153df49b97f93d11f 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoAptMailNotification.h"
-#include <SOGo/SOGoAppointment.h>
-#include "common.h"
+#import <NGCards/iCalEntityObject.h>
+
+#import "SOGoAptMailNotification.h"
+#import "common.h"
 
 @interface SOGoAptMailNotification (PrivateAPI)
 - (BOOL)isSubject;
@@ -31,7 +32,7 @@
 @implementation SOGoAptMailNotification
 
 static NSCharacterSet *wsSet  = nil;
-static NSTimeZone     *MET = nil;
+static NSTimeZone     *EST = nil;
 
 + (void)initialize {
   static BOOL didInit = NO;
@@ -40,7 +41,7 @@ static NSTimeZone     *MET = nil;
   didInit = YES;
 
   wsSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] retain];
-  MET   = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
+  EST   = [[NSTimeZone timeZoneWithAbbreviation:@"EST"] retain];
 }
 
 - (void)dealloc {
@@ -57,14 +58,16 @@ static NSTimeZone     *MET = nil;
 - (id)oldApt {
   return self->oldApt;
 }
-- (void)setOldApt:(id)_oldApt {
+- (void)setOldApt:(iCalEntityObject *)_oldApt {
   ASSIGN(self->oldApt, _oldApt);
 }
 
 - (id)newApt {
   return self->newApt;
 }
-- (void)setNewApt:(id)_newApt {
+
+- (void)setNewApt:(iCalEntityObject *) _newApt
+{
   ASSIGN(self->newApt, _newApt);
 }
 
@@ -86,7 +89,7 @@ static NSTimeZone     *MET = nil;
 
 - (NSTimeZone *)viewTZ {
   if (self->viewTZ) return self->viewTZ;
-  return MET;
+  return EST;
 }
 - (void)setViewTZ:(NSTimeZone *)_viewTZ {
   ASSIGN(self->viewTZ, _viewTZ);
diff --git a/SoObjects/Appointments/SOGoCalendarComponent.h b/SoObjects/Appointments/SOGoCalendarComponent.h
new file mode 100644 (file)
index 0000000..6d93a4a
--- /dev/null
@@ -0,0 +1,46 @@
+/* SOGoCalendarComponent.h - this file is part of SOGo
+ * 
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOCALENDARCOMPONENT_H
+#define SOGOCALENDARCOMPONENT_H
+
+#import <SOGo/SOGoContentObject.h>
+
+@class NSString;
+
+@class iCalCalendar;
+
+@interface SOGoCalendarComponent : SOGoContentObject
+{
+  iCalCalendar *calendar;
+}
+
+/* accessors */
+
+- (NSString *) iCalString;
+- (iCalCalendar *) calendar;
+
+- (NSException *) delete;
+
+@end
+
+#endif /* SOGOCALENDARCOMPONENT_H */
diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m
new file mode 100644 (file)
index 0000000..dc72413
--- /dev/null
@@ -0,0 +1,74 @@
+/* SOGoCalendarComponent.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <NGCards/iCalCalendar.h>
+
+#import "SOGoCalendarComponent.h"
+
+@implementation SOGoCalendarComponent
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      calendar = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (calendar)
+    [calendar release];
+  [super dealloc];
+}
+
+- (NSString *) iCalString
+{
+  // for UI-X appointment viewer
+  return [self contentAsString];
+}
+
+- (iCalCalendar *) calendar
+{
+  NSString *iCalString;
+
+  if (!calendar)
+    {
+      iCalString = [self iCalString];
+      if (iCalString)
+        {
+          calendar = [iCalCalendar parseSingleFromSource: iCalString];
+          [calendar retain];
+        }
+    }
+
+  return calendar;
+}
+
+- (NSException *) delete
+{
+  return [self deleteWithBaseSequence:0];
+}
+
+@end
index 16994a043acab6144f9a9df3ff640996b46c1f1f..6b5ea717995abbbb77fc1cfa74e0cca2029f243a 100644 (file)
@@ -45,7 +45,7 @@
 - (NSString *)contentAsStringFrom:(NSCalendarDate *)_startDate
   to:(NSCalendarDate *)_endDate;
 
-- (NSArray *)fetchFreebusyInfosFrom:(NSCalendarDate *)_startDate
+- (NSArray *)fetchFreeBusyInfosFrom:(NSCalendarDate *)_startDate
   to:(NSCalendarDate *)_endDate;
 
 @end
index d3021fdfd3a9a66600c364e9239ce3cd0602489e..ff9bc72ee0382bfaa30d419fbc32093596d72904 100644 (file)
 */
 // $Id$
 
-#include "SOGoFreeBusyObject.h"
-#include "common.h"
-#include <SOGo/AgenorUserManager.h>
-#include <NGiCal/NGiCal.h>
-#include <NGiCal/iCalRenderer.h>
-
-@interface NSDate(UsedPrivates)
-- (NSString *)icalString; // declared in NGiCal
-@end
+#import <NGCards/iCalCalendar.h>
+#import <NGCards/iCalFreeBusy.h>
+
+#import "common.h"
+
+#import <SOGo/AgenorUserManager.h>
+#import <SOGo/SOGoPermissions.h>
+
+#import "SOGoFreeBusyObject.h"
 
 @interface SOGoFreeBusyObject (PrivateAPI)
-- (NSString *)iCalStringForFreeBusyInfos:(NSArray *)_infos
-  from:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate;
+- (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos
+                                     from: (NSCalendarDate *) _startDate
+                                       to: (NSCalendarDate *) _endDate;
 @end
 
 @implementation SOGoFreeBusyObject
 
-- (NSString *)iCalString {
+- (NSString *) iCalString
+{
   // for UI-X appointment viewer
   return [self contentAsString];
 }
 
-- (NSString *)contentAsString {
+- (NSString *) contentAsString
+{
   NSCalendarDate *startDate, *endDate;
   
   startDate = [[[NSCalendarDate calendarDate] mondayOfWeek] beginOfDay];
-  endDate   = [startDate dateByAddingYears:0
-                                    months:0
-                                      days:7
-                                     hours:23
-                                   minutes:59
-                                   seconds:59];
-  return [self contentAsStringFrom:startDate to:endDate];
+  endDate   = [startDate dateByAddingYears: 0 months: 0 days: 7
+                                     hours: 23 minutes: 59 seconds: 59];
+  return [self contentAsStringFrom: startDate to: endDate];
 }
 
-- (NSString *)contentAsStringFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate
+- (NSString *) contentAsStringFrom: (NSCalendarDate *) _startDate
+                                to: (NSCalendarDate *) _endDate
 {
   NSArray *infos;
   
-  infos = [self fetchFreebusyInfosFrom:_startDate to:_endDate];
+  infos = [self fetchFreeBusyInfosFrom:_startDate to:_endDate];
   return [self iCalStringForFreeBusyInfos:infos from:_startDate to:_endDate];
 }
 
-- (NSArray *)fetchFreebusyInfosFrom:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate
+- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
+                                  to: (NSCalendarDate *) _endDate
 {
-  id                userFolder, calFolder;
-  NSArray           *infos;
-  AgenorUserManager *um;
-  NSString          *email;
-  NSMutableArray    *filtered;
-  unsigned          i, count;
-
-  userFolder = [self container];
-  calFolder  = [userFolder lookupName:@"Calendar" inContext:nil acquire:NO];
-  infos      = [calFolder fetchFreebusyInfosFrom:_startDate to:_endDate];
-  um         = [AgenorUserManager sharedUserManager];
-  email      = [um getEmailForUID:[userFolder login]];
-  count      = [infos count];
-  filtered   = [[[NSMutableArray alloc] initWithCapacity:count] autorelease];
-
-  for (i = 0; i < count; i++) {
-    NSDictionary *info;
-    NSArray      *partmails;
-    unsigned     p, pCount;
-
-    info      = [infos objectAtIndex:i];
-    partmails = [[info objectForKey:@"partmails"]
-                       componentsSeparatedByString:@"\n"];
-    pCount    = [partmails count];
-    for (p = 0; p < pCount; p++) {
-      NSString *pEmail;
-      
-      pEmail = [partmails objectAtIndex:p];
-      if ([pEmail isEqualToString:email]) {
-        NSArray  *partstates;
-        NSString *state;
-
-        partstates = [[info objectForKey:@"partstates"]
-                            componentsSeparatedByString:@"\n"];
-        state      = [partstates objectAtIndex:p];
-        if ([state intValue] == iCalPersonPartStatAccepted) {
-          // TODO: add tentative apts as well, but put state and email
-          //       into info
-          [filtered addObject:info];
-        }
-        break;
-      }
+  id calFolder;
+  SoSecurityManager *sm;
+  WOApplication *woApp;
+  NSArray *infos;
+
+  woApp = [WOApplication application];
+
+  calFolder = [container lookupName: @"Calendar" inContext: nil acquire: NO];
+  sm = [SoSecurityManager sharedSecurityManager];
+  if (![sm validatePermission: SOGoPerm_FreeBusyLookup
+           onObject: calFolder
+           inContext: [woApp context]])
+    infos = [calFolder fetchFreeBusyInfosFrom: _startDate
+                       to: _endDate];
+  else
+    {
+      infos = [NSArray new];
+      [infos autorelease];
     }
-  }
-  return filtered;
+
+  return infos;
 }
 
 /* Private API */
+- (iCalFreeBusyType) _fbTypeForEventStatus: (NSNumber *) eventStatus
+{
+  unsigned int status;
+  iCalFreeBusyType fbType;
+
+  status = [eventStatus unsignedIntValue];
+  if (status == 0)
+    fbType = iCalFBBusyTentative;
+  else if (status == 1)
+    fbType = iCalFBBusy;
+  else
+    fbType = iCalFBFree;
+
+  return fbType;    
+}
 
-- (NSString *)iCalStringForFreeBusyInfos:(NSArray *)_infos
-  from:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate
+- (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos
+                                     from: (NSCalendarDate *) _startDate
+                                       to: (NSCalendarDate *) _endDate
 {
   AgenorUserManager *um;
-  NSMutableString   *ms;
-  NSString          *uid, *x;
-  unsigned          i, count;
+  NSString *uid;
+  NSEnumerator *events;
+  iCalCalendar *calendar;
+  iCalFreeBusy *freebusy;
+  NSDictionary *info;
+  iCalFreeBusyType type;
 
   um  = [AgenorUserManager sharedUserManager];
   uid = [[self container] login];
-  ms  = [[[NSMutableString alloc] initWithCapacity:128] autorelease];
-
-  /* preamble */
-  [ms appendString:@"BEGIN:VCALENDAR\r\n"];
-  [ms appendString:@"BEGIN:VFREEBUSY\r\n"];
-  /* PRODID */
-  [ms appendString:@"PRODID:SOGo/0.9\r\n"];
-  /* VERSION */
-  [ms appendString:@"VERSION:2.0\r\n"];
-  /* DTSTAMP */
-  [ms appendString:@"DTSTAMP:"];
-  [ms appendString:[[NSCalendarDate calendarDate] icalString]];
-  [ms appendString:@"\r\n"];
-  
+
+  calendar = [iCalCalendar groupWithTag: @"vcalendar"];
+  [calendar setProdID: @"//Inverse groupe conseil/SOGo 0.9"];
+  [calendar setVersion: @"2.0"];
+
+  freebusy = [iCalFreeBusy groupWithTag: @"vfreebusy"];
+  [freebusy addToAttendees: [um iCalPersonWithUid: uid]];
+  [freebusy setTimeStampAsDate: [NSCalendarDate calendarDate]];
+  [freebusy setStartDate: _startDate];
+  [freebusy setEndDate: _endDate];
+
   /* ORGANIZER - strictly required but missing for now */
 
   /* ATTENDEE */
-  [ms appendString:@"ATTENDEE"];
-  if ((x = [um getCNForUID:uid])) {
-    [ms appendString:@";CN=\""];
-    [ms appendString:[x iCalDQUOTESafeString]];
-    [ms appendString:@"\""];
-  }
-  if ((x = [um getEmailForUID:uid])) {
-    [ms appendString:@":"]; /* sic! */
-    [ms appendString:[x iCalSafeString]];
-  }
-  [ms appendString:@"\r\n"];
-
-  /* DTSTART */
-  [ms appendString:@"DTSTART:"];
-  [ms appendString:[_startDate icalString]];
-  [ms appendString:@"\r\n"];
-
-  /* DTEND */
-  [ms appendString:@"DTEND:"];
-  [ms appendString:[_endDate icalString]];
-  [ms appendString:@"\r\n"];
+//   person = [um iCalPersonWithUid: uid];
+//   [person setTag: @"ATTENDEE"];
+//   [ms appendString: [person versitString]];
 
   /* FREEBUSY */
-  count = [_infos count];
-  for (i = 0; i < count; i++) {
-    NSDictionary   *info;
-    NSCalendarDate *startDate, *endDate;
-
-    info      = [_infos objectAtIndex:i];
-    startDate = [info objectForKey:@"startDate"];
-    endDate   = [info objectForKey:@"endDate"];
-
-    /* NOTE: currently we cannot differentiate between all the types defined
-     *       in RFC2445, Section 4.2.9.
-     *       These are: FREE" / "BUSY" / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE"
-     */
-    
-    [ms appendString:@"FREEBUSY;FBTYPE=BUSY:"];
-    [ms appendString:[startDate icalString]];
-    [ms appendString:@"/"];
-    [ms appendString:[endDate icalString]];
-    [ms appendString:@"\r\n"];
-  }
-
-  /* postamble */
-  [ms appendString:@"END:VFREEBUSY\r\n"];
-  [ms appendString:@"END:VCALENDAR\r\n"];
-  return ms;
+  events = [_infos objectEnumerator];
+  info = [events nextObject];
+  while (info)
+    {
+      if ([[info objectForKey: @"isopaque"] boolValue])
+        {
+          type = [self _fbTypeForEventStatus: [info objectForKey: @"status"]];
+          [freebusy addFreeBusyFrom: [info objectForKey: @"startDate"]
+                    to: [info objectForKey: @"endDate"]
+                    type: type];
+        }
+      info = [events nextObject];
+    }
+
+  [calendar setUniqueChild: freebusy];
+
+  return [calendar versitString];
 }
 
 /* deliver content without need for view method */
 
-- (id)GETAction:(id)_ctx {
+- (id) GETAction: (id)_ctx
+{
   WOResponse *r;
   NSData     *contentData;
 
-  contentData = [[self contentAsString] dataUsingEncoding:NSUTF8StringEncoding];
+  contentData = [[self contentAsString] dataUsingEncoding: NSUTF8StringEncoding];
+
+  r = [(WOContext *) _ctx response];
+  [r setHeader: @"text/calendar" forKey: @"content-type"];
+  [r setContent: contentData];
+  [r setStatus: 200];
 
-  r = [(WOContext *)_ctx response];
-  [r setHeader:@"text/calendar" forKey:@"content-type"];
-  [r setContent:contentData];
-  [r setStatus:200];
   return r;
 }
 
index 4c51355340c8bf27c38746f3a84ffd657b0af635..0295de5039b4dcfe6d415c69a3757692310e4c7d 100644 (file)
   if (![aptFolder isNotNull])
     return nil;
   
-  if (![aptFolder respondsToSelector:@selector(fetchCoreInfosFrom:to:)]) {
+  if (![aptFolder respondsToSelector:@selector(fetchCoreInfosFrom:to:component:)]) {
     [self errorWithFormat:@"folder does not implemented required API: %@",
            _folder];
     return nil;
 }
 
 /* overridden */
-- (NSArray *)fetchFields:(NSArray *)_fields
-  from:(NSCalendarDate *)_startDate
-  to:(NSCalendarDate *)_endDate 
+- (NSArray *) fetchFields: (NSArray *) _fields
+                     from: (NSCalendarDate *) _startDate
+                       to: (NSCalendarDate *) _endDate
+                component: (id) _component
 {
   NSArray             *folders;
   NSMutableArray      *result;
   NSMutableDictionary *uidToRecord;
   unsigned            i, count;
+  WOContext *context;
+  SoSecurityManager *securityManager;
 
-  if ((folders = [[self container] valueForKey:@"memberFolders"]) == nil) {
-    [self errorWithFormat:@"calendar container has no 'memberFolders'?!"];
-    return nil;
-  }
-  
+  context = [[WOApplication application] context];
+  securityManager = [SoSecurityManager sharedSecurityManager];
+
+  folders = [[self container] memberFolders];
   [self resetFolderCaches];
   
   if ((count = [folders count]) == 0)
              [folders objectAtIndex:i]];
       continue;
     }
-    
-    results = [aptFolder fetchFields:_fields
-                         from:_startDate
-                         to:_endDate];
+
+    if ([securityManager validatePermission: SoPerm_AccessContentsInformation
+                         onObject: aptFolder
+                         inContext: context]) {
+      [self debugWithFormat:@"no permission to read the content of calendar: %@",
+             [folders objectAtIndex:i]];
+      continue;
+    }
+
+    results = [aptFolder fetchFields: _fields
+                         from: _startDate
+                         to: _endDate
+                         component: _component];
     if (![results isNotNull]) continue;
     
     results = [results objectEnumerator];
diff --git a/SoObjects/Appointments/SOGoTaskObject.h b/SoObjects/Appointments/SOGoTaskObject.h
new file mode 100644 (file)
index 0000000..20ad9f7
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#ifndef __Appointments_SOGoTaskObject_H__
+#define __Appointments_SOGoTaskObject_H__
+
+#import "SOGoCalendarComponent.h"
+
+/*
+  SOGoTaskObject
+  
+  Represents a single task. This SOPE controller object manages all the
+  attendee storages (that is, it might store into multiple folders for meeting
+  tasks!).
+
+  Note: SOGoTaskObject do not need to exist yet. They can also be "new"
+        tasks with an externally generated unique key.
+*/
+
+@class NSArray;
+@class NSException;
+@class NSString;
+
+@class iCalToDo;
+@class iCalCalendar;
+
+@interface SOGoTaskObject : SOGoCalendarComponent
+
+/* accessors */
+
+- (iCalToDo *) task;
+- (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) calendar;
+
+/* folder management */
+
+- (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx;
+- (NSArray *)lookupCalendarFoldersForUIDs:(NSArray *)_uids inContext:(id)_ctx;
+
+/* raw saving */
+
+- (NSException *)primarySaveContentString:(NSString *)_iCalString;
+- (NSException *)primaryDelete;
+
+/* "iCal multifolder saves" */
+
+- (NSException *)saveContentString:(NSString *)_iCal baseSequence:(int)_v;
+- (NSException *)deleteWithBaseSequence:(int)_v;
+
+- (NSException *)saveContentString:(NSString *)_iCalString;
+- (NSException *)delete;
+
+- (NSException *)changeParticipationStatus:(NSString *)_status
+                                 inContext:(id)_ctx;
+
+
+@end
+
+#endif /* __Appointmentss_SOGoTaskObject_H__ */
diff --git a/SoObjects/Appointments/SOGoTaskObject.m b/SoObjects/Appointments/SOGoTaskObject.m
new file mode 100644 (file)
index 0000000..02eb7cd
--- /dev/null
@@ -0,0 +1,741 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#import "SOGoTaskObject.h"
+
+#import <NGCards/iCalCalendar.h>
+#import <NGCards/iCalToDo.h>
+#import <NGCards/iCalEventChanges.h>
+#import <NGCards/iCalPerson.h>
+#import <SOGo/AgenorUserManager.h>
+#import <NGMime/NGMime.h>
+#import <NGMail/NGMail.h>
+#import <NGMail/NGSendMail.h>
+#import "SOGoAptMailNotification.h"
+#import "common.h"
+
+#import "NSArray+Appointments.h"
+
+@interface SOGoTaskObject (PrivateAPI)
+- (NSString *)homePageURLForPerson:(iCalPerson *)_person;
+  
+- (void)sendEMailUsingTemplateNamed:(NSString *)_pageName
+  forOldTask:(iCalToDo *)_newApt
+  andNewTask:(iCalToDo *)_oldApt
+  toAttendees:(NSArray *)_attendees;
+
+- (void)sendInvitationEMailForTask:(iCalToDo *)_task
+  toAttendees:(NSArray *)_attendees;
+- (void)sendTaskUpdateEMailForOldTask:(iCalToDo *)_oldApt
+  newTask:(iCalToDo *)_newApt
+  toAttendees:(NSArray *)_attendees;
+- (void)sendAttendeeRemovalEMailForTask:(iCalToDo *)_task
+  toAttendees:(NSArray *)_attendees;
+- (void)sendTaskDeletionEMailForTask:(iCalToDo *)_task
+  toAttendees:(NSArray *)_attendees;
+@end
+
+@implementation SOGoTaskObject
+
+static NSString                  *mailTemplateDefaultLanguage = nil;
+
++ (void)initialize {
+  NSUserDefaults      *ud;
+  static BOOL         didInit = NO;
+  
+  if (didInit) return;
+  didInit = YES;
+  
+  ud = [NSUserDefaults standardUserDefaults];
+  mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"]
+                                     retain];
+  if (!mailTemplateDefaultLanguage)
+    mailTemplateDefaultLanguage = @"French";
+}
+
+/* accessors */
+
+- (iCalToDo *) task
+{
+  return [self firstTaskFromCalendar: [self calendar]];
+}
+
+/* iCal handling */
+
+- (NSArray *)attendeeUIDsFromTask:(iCalToDo *)_task {
+  AgenorUserManager *um;
+  NSMutableArray    *uids;
+  NSArray  *attendees;
+  unsigned i, count;
+  NSString *email, *uid;
+  
+  if (![_task isNotNull])
+    return nil;
+  
+  if ((attendees = [_task attendees]) == nil)
+    return nil;
+  count = [attendees count];
+  uids = [NSMutableArray arrayWithCapacity:count + 1];
+  
+  um = [AgenorUserManager sharedUserManager];
+  
+  /* add organizer */
+  
+  email = [[_task organizer] rfc822Email];
+  if ([email isNotNull]) {
+    uid = [um getUIDForEmail:email];
+    if ([uid isNotNull]) {
+      [uids addObject:uid];
+    }
+    else
+      [self logWithFormat:@"Note: got no uid for organizer: '%@'", email];
+  }
+
+  /* add attendees */
+  
+  for (i = 0; i < count; i++) {
+    iCalPerson *person;
+    
+    person = [attendees objectAtIndex:i];
+    email  = [person rfc822Email];
+    if (![email isNotNull]) continue;
+    
+    uid = [um getUIDForEmail:email];
+    if (![uid isNotNull]) {
+      [self logWithFormat:@"Note: got no uid for email: '%@'", email];
+      continue;
+    }
+    if (![uids containsObject:uid])
+      [uids addObject:uid];
+  }
+  
+  return uids;
+}
+
+/* raw saving */
+
+- (NSException *)primarySaveContentString:(NSString *)_iCalString {
+  return [super saveContentString:_iCalString];
+}
+- (NSException *)primaryDelete {
+  return [super delete];
+}
+
+/* folder management */
+
+- (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx {
+  // TODO: what does this do? lookup the home of the organizer?
+  return [[self container] lookupHomeFolderForUID:_uid inContext:_ctx];
+}
+- (NSArray *)lookupCalendarFoldersForUIDs:(NSArray *)_uids inContext:(id)_ctx {
+  return [[self container] lookupCalendarFoldersForUIDs:_uids inContext:_ctx];
+}
+
+/* store in all the other folders */
+
+- (NSException *)saveContentString:(NSString *)_iCal inUIDs:(NSArray *)_uids {
+  NSEnumerator *e;
+  id           folder;
+  NSException  *allErrors = nil;
+  id ctx;
+
+  ctx = [[WOApplication application] context];
+  
+  e = [[self lookupCalendarFoldersForUIDs:_uids inContext:ctx]
+            objectEnumerator];
+  while ((folder = [e nextObject]) != nil) {
+    NSException           *error;
+    SOGoTaskObject *task;
+    
+    if (![folder isNotNull]) /* no folder was found for given UID */
+      continue;
+    
+    task = [folder lookupName:[self nameInContainer] inContext:ctx
+                 acquire:NO];
+    if ([task isKindOfClass: [NSException class]])
+      {
+        [self logWithFormat:@"Note: an exception occured finding '%@' in folder: %@",
+             [self nameInContainer], folder];
+        [self logWithFormat:@"the exception reason was: %@",
+              [(NSException *) task reason]];
+        continue;
+      }
+
+    if (![task isNotNull]) {
+      [self logWithFormat:@"Note: did not find '%@' in folder: %@",
+             [self nameInContainer], folder];
+      continue;
+    }
+    
+    if ((error = [task primarySaveContentString:_iCal]) != nil) {
+      [self logWithFormat:@"Note: failed to save iCal in folder: %@", folder];
+      // TODO: make compound
+      allErrors = error;
+    }
+  }
+  return allErrors;
+}
+- (NSException *)deleteInUIDs:(NSArray *)_uids {
+  NSEnumerator *e;
+  id           folder;
+  NSException  *allErrors = nil;
+  id           ctx;
+  
+  ctx = [[WOApplication application] context];
+  
+  e = [[self lookupCalendarFoldersForUIDs:_uids inContext:ctx]
+            objectEnumerator];
+  while ((folder = [e nextObject])) {
+    NSException           *error;
+    SOGoTaskObject *task;
+    
+    task = [folder lookupName:[self nameInContainer] inContext:ctx
+                 acquire:NO];
+    if (![task isNotNull]) {
+      [self logWithFormat:@"Note: did not find '%@' in folder: %@",
+             [self nameInContainer], folder];
+      continue;
+    }
+    if ([task isKindOfClass: [NSException class]]) {
+      [self logWithFormat:@"Exception: %@", [(NSException *) task reason]];
+      continue;
+    }
+    
+    if ((error = [task primaryDelete]) != nil) {
+      [self logWithFormat:@"Note: failed to delete in folder: %@", folder];
+      // TODO: make compound
+      allErrors = error;
+    }
+  }
+  return allErrors;
+}
+
+- (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) aCalendar
+{
+  iCalToDo *task;
+  NSArray *tasks;
+
+  tasks = [aCalendar childrenWithTag: @"vtodo"];
+  if ([tasks count])
+    task = (iCalToDo *) [[tasks objectAtIndex: 0]
+                           groupWithClass: [iCalToDo class]];
+  else
+    task = nil;
+
+  return task;
+}
+
+/* "iCal multifolder saves" */
+
+- (NSException *) saveContentString: (NSString *) _iCal
+                       baseSequence: (int) _v
+{
+  /* 
+     Note: we need to delete in all participants folders and send iMIP messages
+           for all external accounts.
+     
+     Steps:
+     - fetch stored content
+     - parse old content
+     - check if sequence matches (or if 0=ignore)
+     - extract old attendee list + organizer (make unique)
+     - parse new content (ensure that sequence is increased!)
+     - extract new attendee list + organizer (make unique)
+     - make a diff => new, same, removed
+     - write to new, same
+     - delete in removed folders
+     - send iMIP mail for all folders not found
+  */
+//   AgenorUserManager *um;
+//   iCalCalendar *calendar;
+//   iCalToDo *oldApt, *newApt;
+// //   iCalToDoChanges  *changes;
+//   iCalPerson        *organizer;
+//   NSString          *oldContent, *uid;
+//   NSArray           *uids, *props;
+//   NSMutableArray    *attendees, *storeUIDs, *removedUIDs;
+  NSException       *storeError, *delError;
+//   BOOL              updateForcesReconsider;
+  
+//   updateForcesReconsider = NO;
+
+//   if ([_iCal length] == 0) {
+//     return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
+//                     reason:@"got no iCalendar content to store!"];
+//   }
+
+//   um = [AgenorUserManager sharedUserManager];
+
+//   /* handle old content */
+  
+//   oldContent = [self iCalString]; /* if nil, this is a new task */
+//   if ([oldContent length] == 0)
+//     {
+//     /* new task */
+//       [self debugWithFormat:@"saving new task: %@", _iCal];
+//       oldApt = nil;
+//     }
+//   else
+//     {
+//       calendar = [iCalCalendar parseSingleFromSource: oldContent];
+//       oldApt = [self firstTaskFromCalendar: calendar];
+//     }
+  
+//   /* compare sequence if requested */
+
+//   if (_v != 0) {
+//     // TODO
+//   }
+  
+  
+//   /* handle new content */
+  
+//   calendar = [iCalCalendar parseSingleFromSource: _iCal];
+//   newApt = [self firstTaskFromCalendar: calendar];
+//   if (newApt == nil) {
+//     return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
+//                     reason:@"could not parse iCalendar content!"];
+//   }
+  
+//   /* diff */
+  
+//   changes = [iCalToDoChanges changesFromEvent: oldApt
+//                               toEvent: newApt];
+
+//   uids        = [um getUIDsForICalPersons:[changes deletedAttendees]
+//                     applyStrictMapping:NO];
+//   removedUIDs = [NSMutableArray arrayWithArray:uids];
+
+//   uids        = [um getUIDsForICalPersons:[newApt attendees]
+//                     applyStrictMapping:NO];
+//   storeUIDs   = [NSMutableArray arrayWithArray:uids];
+//   props       = [changes updatedProperties];
+
+//   /* detect whether sequence has to be increased */
+//   if ([changes hasChanges])
+//     [newApt increaseSequence];
+
+//   /* preserve organizer */
+
+//   organizer = [newApt organizer];
+//   uid       = [um getUIDForICalPerson:organizer];
+//   if (uid) {
+//     if (![storeUIDs containsObject:uid])
+//       [storeUIDs addObject:uid];
+//     [removedUIDs removeObject:uid];
+//   }
+
+//   /* organizer might have changed completely */
+
+//   if (oldApt && ([props containsObject: @"organizer"])) {
+//     uid = [um getUIDForICalPerson:[oldApt organizer]];
+//     if (uid) {
+//       if (![storeUIDs containsObject:uid]) {
+//         if (![removedUIDs containsObject:uid]) {
+//           [removedUIDs addObject:uid];
+//         }
+//       }
+//     }
+//   }
+
+//   [self debugWithFormat:@"UID ops:\n  store: %@\n  remove: %@",
+//                         storeUIDs, removedUIDs];
+
+//   /* if time did change, all participants have to re-decide ...
+//    * ... exception from that rule: the organizer
+//    */
+
+//   if (oldApt != nil &&
+//       ([props containsObject:@"startDate"] ||
+//        [props containsObject:@"endDate"]   ||
+//        [props containsObject:@"duration"]))
+//   {
+//     NSArray  *ps;
+//     unsigned i, count;
+    
+//     ps    = [newApt attendees];
+//     count = [ps count];
+//     for (i = 0; i < count; i++) {
+//       iCalPerson *p;
+      
+//       p = [ps objectAtIndex:i];
+//       if (![p hasSameEmailAddress:organizer])
+//         [p setParticipationStatus:iCalPersonPartStatNeedsAction];
+//     }
+//     _iCal = [[newApt parent] versitString];
+//     updateForcesReconsider = YES;
+//   }
+
+//   /* perform storing */
+
+  storeError = [self primarySaveContentString: _iCal];
+
+//   storeError = [self saveContentString:_iCal inUIDs:storeUIDs];
+//   delError   = [self deleteInUIDs:removedUIDs];
+
+  // TODO: make compound
+  if (storeError != nil) return storeError;
+//   if (delError   != nil) return delError;
+
+  /* email notifications */
+
+//   attendees = [NSMutableArray arrayWithArray:[changes insertedAttendees]];
+//   [attendees removePerson:organizer];
+//   [self sendInvitationEMailForTask:newApt
+//         toAttendees:attendees];
+
+//   if (updateForcesReconsider) {
+//     attendees = [NSMutableArray arrayWithArray:[newApt attendees]];
+//     [attendees removeObjectsInArray:[changes insertedAttendees]];
+//     [attendees removePerson:organizer];
+//     [self sendTaskUpdateEMailForOldTask:oldApt
+//           newTask:newApt
+//           toAttendees:attendees];
+//   }
+
+//   attendees = [NSMutableArray arrayWithArray:[changes deletedAttendees]];
+//   [attendees removePerson: organizer];
+//   if ([attendees count]) {
+//     iCalToDo *canceledApt;
+    
+//     canceledApt = [newApt copy];
+//     [(iCalCalendar *) [canceledApt parent] setMethod: @"cancel"];
+//     [self sendAttendeeRemovalEMailForTask:canceledApt
+//           toAttendees:attendees];
+//     [canceledApt release];
+//   }
+  return nil;
+}
+
+- (NSException *)deleteWithBaseSequence:(int)_v {
+  /* 
+     Note: We need to delete in all participants folders and send iMIP messages
+           for all external accounts.
+          Delete is basically identical to save with all attendees and the
+          organizer being deleted.
+
+     Steps:
+     - fetch stored content
+     - parse old content
+     - check if sequence matches (or if 0=ignore)
+     - extract old attendee list + organizer (make unique)
+     - delete in removed folders
+     - send iMIP mail for all folders not found
+  */
+  iCalToDo *task;
+  NSArray         *removedUIDs;
+  NSMutableArray  *attendees;
+
+  /* load existing content */
+  
+  task = [self task];
+  
+  /* compare sequence if requested */
+
+  if (_v != 0) {
+    // TODO
+  }
+  
+  removedUIDs = [self attendeeUIDsFromTask:task];
+
+  /* send notification email to attendees excluding organizer */
+  attendees = [NSMutableArray arrayWithArray:[task attendees]];
+  [attendees removePerson:[task organizer]];
+  
+  /* flag task as being canceled */
+  [(iCalCalendar *) [task parent] setMethod: @"cancel"];
+  [task increaseSequence];
+
+  /* remove all attendees to signal complete removal */
+  [task removeAllAttendees];
+
+  /* send notification email */
+  [self sendTaskDeletionEMailForTask:task
+        toAttendees:attendees];
+
+  /* perform */
+  
+  return [self deleteInUIDs:removedUIDs];
+}
+
+- (NSException *)saveContentString:(NSString *)_iCalString {
+  return [self saveContentString:_iCalString baseSequence:0];
+}
+
+- (NSException *)changeParticipationStatus:(NSString *)_status
+  inContext:(id)_ctx
+{
+  iCalToDo *task;
+  iCalPerson      *p;
+  NSString        *newContent;
+  NSException     *ex;
+  NSString        *myEMail;
+  
+  // TODO: do we need to use SOGoTask? (prefer iCalToDo?)
+  task = [self task];
+
+  if (task == nil) {
+    return [NSException exceptionWithHTTPStatus:500 /* Server Error */
+                        reason:@"unable to parse task record"];
+  }
+  
+  myEMail = [[_ctx activeUser] email];
+  if ((p = [task findParticipantWithEmail:myEMail]) == nil) {
+    return [NSException exceptionWithHTTPStatus:404 /* Not Found */
+                        reason:@"user does not participate in this "
+                               @"task"];
+  }
+  
+  [p setPartStat:_status];
+  newContent = [[task parent] versitString];
+  
+  // TODO: send iMIP reply mails?
+  
+//   [task release]; task = nil;
+  
+  if (newContent == nil) {
+    return [NSException exceptionWithHTTPStatus:500 /* Server Error */
+                        reason:@"Could not generate iCalendar data ..."];
+  }
+  
+  if ((ex = [self saveContentString:newContent]) != nil) {
+    // TODO: why is the exception wrapped?
+    return [NSException exceptionWithHTTPStatus:500 /* Server Error */
+                        reason:[ex reason]];
+  }
+  
+  return nil /* means: no error */;
+}
+
+
+/* message type */
+
+- (NSString *)outlookMessageClass {
+  return @"IPM.Task";
+}
+
+/* EMail Notifications */
+
+- (NSString *)homePageURLForPerson:(iCalPerson *)_person {
+  static AgenorUserManager *um      = nil;
+  static NSString          *baseURL = nil;
+  NSString *uid;
+
+  if (!um) {
+    WOContext *ctx;
+    NSArray   *traversalObjects;
+
+    um = [[AgenorUserManager sharedUserManager] retain];
+
+    /* generate URL from traversal stack */
+    ctx = [[WOApplication application] context];
+    traversalObjects = [ctx objectTraversalStack];
+    if ([traversalObjects count] >= 1) {
+      baseURL = [[[traversalObjects objectAtIndex:0] baseURLInContext:ctx]
+                                                     retain];
+    }
+    else {
+      [self warnWithFormat:@"Unable to create baseURL from context!"];
+      baseURL = @"http://localhost/";
+    }
+  }
+  uid = [um getUIDForEmail:[_person rfc822Email]];
+  if (!uid) return nil;
+  return [NSString stringWithFormat:@"%@%@", baseURL, uid];
+}
+
+- (void)sendEMailUsingTemplateNamed:(NSString *)_pageName
+  forOldTask:(iCalToDo *)_oldApt
+  andNewTask:(iCalToDo *)_newApt
+  toAttendees:(NSArray *)_attendees
+{
+  NSString                *pageName;
+  iCalPerson              *organizer;
+  NSString                *cn, *sender, *iCalString;
+  NGSendMail              *sendmail;
+  WOApplication           *app;
+  unsigned                i, count;
+
+  if (![_attendees count]) return; // another job neatly done :-)
+
+  /* sender */
+
+  organizer = [_newApt organizer];
+  cn        = [organizer cnWithoutQuotes];
+  if (cn) {
+    sender = [NSString stringWithFormat:@"%@ <%@>",
+                                        cn,
+                                        [organizer rfc822Email]];
+  }
+  else {
+    sender = [organizer rfc822Email];
+  }
+
+  /* generate iCalString once */
+  iCalString = [[_newApt parent] versitString];
+  
+  /* get sendmail object */
+  sendmail   = [NGSendMail sharedSendMail];
+
+  /* get WOApplication instance */
+  app        = [WOApplication application];
+
+  /* generate dynamic message content */
+
+  count = [_attendees count];
+  for (i = 0; i < count; i++) {
+    iCalPerson              *attendee;
+    NSString                *recipient;
+    SOGoAptMailNotification *p;
+    NSString                *subject, *text, *header;
+    NGMutableHashMap        *headerMap;
+    NGMimeMessage           *msg;
+    NGMimeBodyPart          *bodyPart;
+    NGMimeMultipartBody     *body;
+    
+    attendee  = [_attendees objectAtIndex:i];
+    
+    /* construct recipient */
+    cn        = [attendee cn];
+    if (cn) {
+      recipient = [NSString stringWithFormat:@"%@ <%@>",
+                                             cn,
+                                             [attendee rfc822Email]];
+    }
+    else {
+      recipient = [attendee rfc822Email];
+    }
+
+    /* create page name */
+    // TODO: select user's default language?
+    pageName   = [NSString stringWithFormat:@"SOGoAptMail%@%@",
+                                            mailTemplateDefaultLanguage,
+                                            _pageName];
+    /* construct message content */
+    p = [app pageWithName:pageName inContext:[WOContext context]];
+    [p setNewApt: _newApt];
+    [p setOldApt: _oldApt];
+    [p setHomePageURL:[self homePageURLForPerson:attendee]];
+    [p setViewTZ: [self userTimeZone: cn]];
+    subject = [p getSubject];
+    text    = [p getBody];
+
+    /* construct message */
+    headerMap = [NGMutableHashMap hashMapWithCapacity:5];
+    
+    /* NOTE: multipart/alternative seems like the correct choice but
+     * unfortunately Thunderbird doesn't offer the rich content alternative
+     * at all. Mail.app shows the rich content alternative _only_
+     * so we'll stick with multipart/mixed for the time being.
+     */
+    [headerMap setObject:@"multipart/mixed"    forKey:@"content-type"];
+    [headerMap setObject:sender                forKey:@"From"];
+    [headerMap setObject:recipient             forKey:@"To"];
+    [headerMap setObject:[NSCalendarDate date] forKey:@"date"];
+    [headerMap setObject:subject               forKey:@"Subject"];
+    msg = [NGMimeMessage messageWithHeader:headerMap];
+    
+    /* multipart body */
+    body = [[NGMimeMultipartBody alloc] initWithPart:msg];
+    
+    /* text part */
+    headerMap = [NGMutableHashMap hashMapWithCapacity:1];
+    [headerMap setObject:@"text/plain; charset=utf-8" forKey:@"content-type"];
+    bodyPart = [NGMimeBodyPart bodyPartWithHeader:headerMap];
+    [bodyPart setBody:[text dataUsingEncoding:NSUTF8StringEncoding]];
+
+    /* attach text part to multipart body */
+    [body addBodyPart:bodyPart];
+    
+    /* calendar part */
+    header     = [NSString stringWithFormat:@"text/calendar; method=%@;"
+                                            @" charset=utf-8",
+                           [(iCalCalendar *) [_newApt parent] method]];
+    headerMap  = [NGMutableHashMap hashMapWithCapacity:1];
+    [headerMap setObject:header forKey:@"content-type"];
+    bodyPart   = [NGMimeBodyPart bodyPartWithHeader:headerMap];
+    [bodyPart setBody:[iCalString dataUsingEncoding:NSUTF8StringEncoding]];
+    
+    /* attach calendar part to multipart body */
+    [body addBodyPart:bodyPart];
+    
+    /* attach multipart body to message */
+    [msg setBody:body];
+    [body release];
+
+    /* send the damn thing */
+    [sendmail sendMimePart:msg
+              toRecipients:[NSArray arrayWithObject:[attendee rfc822Email]]
+              sender:[organizer rfc822Email]];
+  }
+}
+
+- (void)sendInvitationEMailForTask:(iCalToDo *)_task
+  toAttendees:(NSArray *)_attendees
+{
+  if (![_attendees count]) return; // another job neatly done :-)
+
+  [self sendEMailUsingTemplateNamed:@"Invitation"
+        forOldTask:nil
+        andNewTask:_task
+        toAttendees:_attendees];
+}
+
+- (void)sendTaskUpdateEMailForOldTask:(iCalToDo *)_oldApt
+  newTask:(iCalToDo *)_newApt
+  toAttendees:(NSArray *)_attendees
+{
+  if (![_attendees count]) return;
+  
+  [self sendEMailUsingTemplateNamed:@"Update"
+        forOldTask:_oldApt
+        andNewTask:_newApt
+        toAttendees:_attendees];
+}
+
+- (void) sendAttendeeRemovalEMailForTask:(iCalToDo *)_task
+                             toAttendees:(NSArray *)_attendees
+{
+  if (![_attendees count]) return;
+
+  [self sendEMailUsingTemplateNamed:@"Removal"
+        forOldTask:nil
+        andNewTask:_task
+        toAttendees:_attendees];
+}
+
+- (void) sendTaskDeletionEMailForTask: (iCalToDo *) _task
+                          toAttendees: (NSArray *) _attendees
+{
+  if (![_attendees count]) return;
+
+  [self sendEMailUsingTemplateNamed:@"Deletion"
+        forOldTask:nil
+        andNewTask:_task
+        toAttendees:_attendees];
+}
+
+- (NSString *) davContentType
+{
+  return @"text/calendar";
+}
+
+@end /* SOGoTaskObject */
diff --git a/SoObjects/Appointments/iCalEntityObject+Agenor.h b/SoObjects/Appointments/iCalEntityObject+Agenor.h
new file mode 100644 (file)
index 0000000..e65debf
--- /dev/null
@@ -0,0 +1,34 @@
+/* iCalEntityObject+Agenor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ICALENTITYOBJECT_AGENOR_H
+#define ICALENTITYOBJECT_AGENOR_H
+
+#import <NGCards/iCalEntityObject.h>
+
+@interface iCalEntityObject (SOGoAgenorUserMgmt)
+
+- (void) setOrganizerWithUid: (NSString *) organizerUid;
+
+@end
+
+#endif /* ICALENTITYOBJECT_AGENOR_H */
diff --git a/SoObjects/Appointments/iCalEntityObject+Agenor.m b/SoObjects/Appointments/iCalEntityObject+Agenor.m
new file mode 100644 (file)
index 0000000..2488917
--- /dev/null
@@ -0,0 +1,39 @@
+/* iCalEntityObject+Agenor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <SoObjects/SOGo/AgenorUserManager.h>
+
+#import "iCalEntityObject+Agenor.h"
+
+@implementation iCalEntityObject (SOGoAgenorUserMgmt)
+
+- (void) setOrganizerWithUid: (NSString *) organizerUid
+{
+  iCalPerson *organizer;
+
+  organizer
+    = [[AgenorUserManager sharedUserManager] iCalPersonWithUid: organizerUid];
+  if (organizer)
+    [self setOrganizer: organizer];
+}
+
+@end
index 8692cfd8d9455c1ca20b3145c1f62a76d8e5972b..423c9888603722bf881c278f9dfac5833a8010c8 100644 (file)
   classes = {
     SOGoAppointmentFolder = {
       superclass    = "SOGoFolder";
+      defaultRoles = {
+        "FreeBusyLookup" = ( "Owner", "Delegate", "Assistant", "FreeBusyLookup" );
+      };
     };
+
     SOGoGroupAppointmentFolder = {
       superclass    = "SOGoAppointmentFolder";
     };
 
     SOGoAppointmentObject = {
       superclass    = "SOGoContentObject";
+      defaultRoles = {
+        "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
+      };
     };
 
+    SOGoTaskObject = {
+      superclass    = "SOGoContentObject";
+      defaultRoles = {
+        "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
+      };
+    };
     SOGoFreeBusyObject = {
       superclass    = "SOGoContentObject";
+      protectedBy = "View";
+      defaultRoles = {
+        "View" = ( "Authenticated", "FreeBusy" );
+        "WebDAV Access" = ( "Authenticated", "FreeBusy" );
+      };
     };
   };
 }
index a88e5c37a86136e3cd7a7afb2d88da67487739f7..99db1eafc42a52b7ade4ef4a7d11d5bd27565e75 100644 (file)
@@ -9,8 +9,14 @@ Contacts_PRINCIPAL_CLASS = SOGoContactsProduct
 Contacts_OBJC_FILES =                  \
        Product.m                       \
                                        \
-       SOGoContactObject.m             \
-       SOGoContactFolder.m             \
+       SOGoContactFolders.m            \
+       SOGoContactGCSEntry.m           \
+       SOGoContactGCSFolder.m          \
+       SOGoContactLDAPEntry.m          \
+       SOGoContactLDAPFolder.m         \
+                                       \
+       NSDictionary+Contact.m          \
+       NGLdapEntry+Contact.m           \
 
 Contacts_RESOURCE_FILES +=             \
        Version                         \
diff --git a/SoObjects/Contacts/NGLdapEntry+Contact.h b/SoObjects/Contacts/NGLdapEntry+Contact.h
new file mode 100644 (file)
index 0000000..0551e61
--- /dev/null
@@ -0,0 +1,41 @@
+/* NGLdapEntry+Contact.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef NGLDAPENTRY_CONTACT_H
+#define NGLDAPENTRY_CONTACT_H
+
+#import <NGLdap/NGLdapEntry.h>
+
+@class NSArray;
+@class NSDictionary;
+@class NSString;
+
+@interface NGLdapEntry (SOGoContactExtension)
+
+- (NSString *) singleAttributeWithName: (NSString *) key;
+- (NSDictionary *) asDictionaryWithAttributeNames: (NSArray *) attributes
+                                          withUID: (NSString *) uid
+                                         andCName: (NSString *) cName;
+
+@end
+
+#endif /* NGLDAPENTRY_CONTACT_H */
diff --git a/SoObjects/Contacts/NGLdapEntry+Contact.m b/SoObjects/Contacts/NGLdapEntry+Contact.m
new file mode 100644 (file)
index 0000000..53e9fe4
--- /dev/null
@@ -0,0 +1,81 @@
+/* NGLdapEntry+Contact.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+
+#import <NGLdap/NGLdapAttribute.h>
+
+#import "NGLdapEntry+Contact.h"
+
+@implementation NGLdapEntry (SOGoContactExtension)
+
+- (NSString *) singleAttributeWithName: (NSString *) key
+{
+  return [[self attributeWithName: key]
+           stringValueAtIndex: 0];
+}
+
+- (NSDictionary *) asDictionaryWithAttributeNames: (NSArray *) attributeNames
+                                          withUID: (NSString *) uid
+                                         andCName: (NSString *) cName
+{
+  NSMutableDictionary *valuesDict;
+  NSEnumerator *attrEnum;
+  NSString *attribute, *value;
+
+  if (!attributeNames)
+    attributeNames = [self attributeNames];
+
+  valuesDict = [NSMutableDictionary dictionaryWithCapacity: [attributeNames count]];
+  attrEnum = [attributeNames objectEnumerator];
+  attribute = [attrEnum nextObject];
+  while (attribute)
+    {
+      [valuesDict setObject: [self singleAttributeWithName: attribute]
+                  forKey: attribute];
+      attribute = [attrEnum nextObject];
+    }
+  if (cName)
+    {
+      value = [self singleAttributeWithName: cName];
+      if (!value)
+        value = @"";
+      NSLog (@"value for '%@' = '%@'", cName, value);
+      [valuesDict setObject: value
+                  forKey: @"c_name"];
+    }
+  if (uid)
+    {
+      value = [self singleAttributeWithName: uid];
+      if (!value)
+        value = @"";
+      NSLog (@"value for '%@' = '%@'", uid, value);
+      [valuesDict setObject: value
+                  forKey: @"c_uid"];
+    }
+
+  return valuesDict;
+}
+
+@end
diff --git a/SoObjects/Contacts/NSDictionary+Contact.h b/SoObjects/Contacts/NSDictionary+Contact.h
new file mode 100644 (file)
index 0000000..3894a44
--- /dev/null
@@ -0,0 +1,36 @@
+/* NSDictionary+Contact.h - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef NSDICTIONARY_CONTACT_H
+#define NSDICTIONARY_CONTACT_H
+
+#import <Foundation/NSDictionary.h>
+
+@class NSString;
+
+@interface NSDictionary (SOGoContact)
+
+- (NSString *) vcardContentFromSOGoContactRecord;
+
+@end
+
+#endif /* NSDICTIONARY_CONTACT_H */
diff --git a/SoObjects/Contacts/NSDictionary+Contact.m b/SoObjects/Contacts/NSDictionary+Contact.m
new file mode 100644 (file)
index 0000000..3d67ff6
--- /dev/null
@@ -0,0 +1,125 @@
+/* NSDictionary+Contact.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+
+#import "NSDictionary+Contact.h"
+
+@implementation NSDictionary (SOGoContact)
+
+- (void) _appendSingleVCardValue: (NSString *) value
+                      withFormat: (NSString *) format
+                         toVCard: (NSMutableString *) vCard
+{
+  NSString *info;
+  
+  info = [self objectForKey: value];
+  if (info && [info length] > 0)
+    [vCard appendFormat: format, info];
+}
+
+- (void) _appendMultilineVCardValue: (NSString *) value
+                         withFormat: (NSString *) format
+                            toVCard: (NSMutableString *) vCard
+{
+  NSString *info;
+
+  info = [[self objectForKey: value]
+           stringByReplacingString: @"\r\n"
+           withString: @";"];
+  if (info && [info length] > 0)
+    [vCard appendFormat: format, info];
+}
+
+- (void) _appendArrayedVCardValues: (NSArray *) keys
+                        withFormat: (NSString *) format
+                           toVCard: (NSMutableString *) vCard
+{
+  NSArray *values;
+  unsigned int count, max;
+
+  values = [self objectsForKeys: keys notFoundMarker: @""];
+
+  max = [values count];
+  while (count < max
+         && [[values objectAtIndex: count] isEqualToString: @""])
+    count++;
+
+  if (count < max)
+    [vCard appendFormat: format, [values componentsJoinedByString: @";"]];
+}
+
+- (NSString *) vcardContentFromSOGoContactRecord
+{
+  NSMutableString *newVCard;
+
+  newVCard = [NSMutableString new];
+  [newVCard autorelease];
+
+  [newVCard appendString: @"BEGIN:VCARD\r\n"
+            "VERSION:3.0\r\n"
+            "PRODID:-//OpenGroupware.org//LSAddress v5.3.85\r\n"
+            "PROFILE:vCard\r\n"];
+
+  [self _appendSingleVCardValue: @"cn"
+        withFormat: @"FN:%@\r\n"
+        toVCard: newVCard];
+  [self _appendArrayedVCardValues:
+          [NSArray arrayWithObjects: @"sn", @"givenName", nil]
+        withFormat: @"N:%@;;;\r\n"
+        toVCard: newVCard];
+  [self _appendSingleVCardValue: @"telephoneNumber"
+        withFormat: @"TEL;TYPE=work,voice,pref:%@\r\n"
+        toVCard: newVCard];
+  [self _appendSingleVCardValue: @"facsimileTelephoneNumber"
+        withFormat: @"TEL;TYPE=work,fax:%@\r\n"
+        toVCard: newVCard];
+  [self _appendSingleVCardValue: @"homeTelephoneNumber"
+        withFormat: @"TEL;TYPE=home,voice:%@\r\n"
+        toVCard: newVCard];
+  [self _appendSingleVCardValue: @"mobile"
+        withFormat: @"TEL;TYPE=cell,voice:%@\r\n"
+        toVCard: newVCard];
+  [self _appendArrayedVCardValues:
+          [NSArray arrayWithObjects: @"l", @"departmentNumber", nil]
+        withFormat: @"ORG:%@\r\n"
+        toVCard: newVCard];
+  [self _appendMultilineVCardValue: @"postalAddress"
+        withFormat: @"ADR:TYPE=work,postal:%@\r\n"
+        toVCard: newVCard];
+  [self _appendMultilineVCardValue: @"homePostalAddress"
+        withFormat: @"ADR:TYPE=home,postal:%@\r\n"
+        toVCard: newVCard];
+  [self _appendSingleVCardValue: @"mail"
+        withFormat: @"EMAIL;TYPE=internet,pref:%@\r\n"
+        toVCard: newVCard];
+  [self _appendSingleVCardValue: @"labelledURI"
+        withFormat: @"URL:%@\r\n"
+        toVCard: newVCard];
+
+  [newVCard appendString: @"END:VCARD\r\n"];
+
+  return newVCard;
+}
+
+@end
index 4e4e3f66cbc387e02001c06dfdf9a3d6f928b5ca..28f180c61f373baa18f6d3b06fdda621b8bf67ac 100644 (file)
 #ifndef __Contacts_SOGoContactFolder_H__
 #define __Contacts_SOGoContactFolder_H__
 
-#include <SOGo/SOGoFolder.h>
-
 /*
   SOGoContactFolder
-    Parent object: the SOGoUserFolder
+    Parent object: the user's SOGoUserFolders
     Child objects: SOGoContactObject
-    
+
   The SOGoContactFolder maps to an GCS folder of type 'contact', that
   is, a content folder containing vcal?? files (and a proper quicktable).
 */
 
-@class NSString, NSArray, NSCalendarDate, NSException;
-@class GCSFolder;
+#import <Foundation/NSObject.h>
+
+@class NSString, NSArray;
+@class SOGoContactObject;
+@class SOGoObject;
+
+@protocol SOGoContactObject;
+
+#import <SoObjects/SOGo/SOGoFolder.h>
+
+@protocol SOGoContactFolder <NSObject>
+
++ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
+                                  andDisplayName: (NSString *) aDisplayName
+                                     inContainer: (SOGoObject *) aContainer;
+
+- (id <SOGoContactFolder>) initWithName: (NSString *) aName
+                         andDisplayName: (NSString *) aDisplayName
+                            inContainer: (SOGoObject *) aContainer;
 
-@interface SOGoContactFolder : SOGoFolder
-{
-}
 
-/* fetching */
+- (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId;
+- (NSArray *) lookupContactsWithFilter: (NSString *) filter
+                                sortBy: (NSString *) sortKey
+                              ordering: (NSComparisonResult) sortOrdering;
 
-- (NSArray *)fetchCoreInfos;
+- (void) setDisplayName: (NSString *) aDisplayName;
+- (NSString *) displayName;
 
 @end
 
diff --git a/SoObjects/Contacts/SOGoContactFolder.m b/SoObjects/Contacts/SOGoContactFolder.m
deleted file mode 100644 (file)
index 5792643..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "SOGoContactFolder.h"
-#include <SOGo/SOGoCustomGroupFolder.h>
-#include <SOGo/AgenorUserManager.h>
-#include <GDLContentStore/GCSFolder.h>
-#include <NGiCal/NGiCal.h>
-#include "common.h"
-#include <unistd.h>
-#include <stdlib.h>
-
-@implementation SOGoContactFolder
-
-/* name lookup */
-
-- (BOOL)isValidContactName:(NSString *)_key {
-  if ([_key length] == 0)
-    return NO;
-  
-  return YES;
-}
-
-- (id)contactWithName:(NSString *)_key inContext:(id)_ctx {
-  static Class ctClass = Nil;
-  id ct;
-  
-  if (ctClass == Nil)
-    ctClass = NSClassFromString(@"SOGoContactObject");
-  if (ctClass == Nil) {
-    [self errorWithFormat:@"missing SOGoContactObject class!"];
-    return nil;
-  }
-  
-  ct = [[ctClass alloc] initWithName:_key inContainer:self];
-  return [ct autorelease];
-}
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
-  id obj;
-  
-  /* first check attributes directly bound to the application */
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
-    return obj;
-  
-  if ([self isValidContactName:_key]) {
-#if 0
-    if ([[self ocsFolder] versionOfContentWithName:_key])
-#endif
-      return [self contactWithName:_key inContext:_ctx];
-  }
-
-  /* return 404 to stop acquisition */
-  return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
-}
-
-/* fetching */
-
-- (NSArray *)fixupRecords:(NSArray *)_records {
-  return _records;
-}
-
-- (NSArray *)fetchCoreInfos {
-  NSArray     *fields, *records;
-
-  fields = [NSArray arrayWithObjects:
-                     @"c_name", @"cn",
-                     @"sn", @"givenname", @"l", 
-                     @"mail", @"telephonenumber",
-                   nil];
-  records = [[self ocsFolder] fetchFields:fields matchingQualifier:nil];
-  if (records == nil) {
-    [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
-    return nil;
-  }
-  records = [self fixupRecords:records];
-  //[self debugWithFormat:@"fetched %i records.", [records count]];
-  return records;
-}
-
-/* GET */
-
-- (id)GETAction:(id)_ctx {
-  // TODO: I guess this should really be done by SOPE (redirect to
-  //       default method)
-  WOResponse *r;
-  NSString *uri;
-
-  uri = [[_ctx request] uri];
-  if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
-  uri = [uri stringByAppendingString:@"view"];
-  
-  r = [_ctx response];
-  [r setStatus:302 /* moved */];
-  [r setHeader:uri forKey:@"location"];
-  return r;
-}
-
-/* folder type */
-
-- (NSString *)outlookFolderClass {
-  return @"IPF.Contact";
-}
-
-@end /* SOGoContactFolder */
diff --git a/SoObjects/Contacts/SOGoContactFolders.h b/SoObjects/Contacts/SOGoContactFolders.h
new file mode 100644 (file)
index 0000000..f75db75
--- /dev/null
@@ -0,0 +1,45 @@
+/* SOGoContactFolders.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOCONTACTFOLDERS_H
+#define SOGOCONTACTFOLDERS_H
+
+#import <SOGo/SOGoObject.h>
+
+@class NSMutableDictionary;
+@class NSString;
+
+@interface SOGoContactFolders : SOGoObject
+{
+  NSMutableDictionary *contactFolders;
+  NSString *OCSPath;
+}
+
+- (NSString *) defaultSourceName;
+
+- (void) setBaseOCSPath: (NSString *) newOCSPath;
+
+- (NSArray *) contactFolders;
+
+@end
+
+#endif /* SOGOCONTACTFOLDERS_H */
diff --git a/SoObjects/Contacts/SOGoContactFolders.m b/SoObjects/Contacts/SOGoContactFolders.m
new file mode 100644 (file)
index 0000000..e47adec
--- /dev/null
@@ -0,0 +1,216 @@
+/* SOGoContactFolders.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* exchange folder types:                   */
+/* MailItems                IPF.Note
+   ContactItems             IPF.Contact
+   AppointmentItems         IPF.Appointment
+   NoteItems                IPF.StickyNote
+   TaskItems                IPF.Task
+   JournalItems             IPF.Journal     */
+
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+
+#import <NGObjWeb/WOApplication.h>
+#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/SoUser.h>
+
+#import <SoObjects/SOGo/SOGoPermissions.h>
+
+#import "common.h"
+
+#import "SOGoContactGCSFolder.h"
+#import "SOGoContactLDAPFolder.h"
+#import "SOGoContactFolders.h"
+
+@implementation SOGoContactFolders
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      contactFolders = nil;
+      OCSPath = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (contactFolders)
+    [contactFolders release];
+  if (OCSPath)
+    [OCSPath release];
+  [super dealloc];
+}
+
+- (void) appendPersonalSourcesInContext: (WOContext *) context;
+{
+  SOGoContactGCSFolder *ab;
+
+  ab = [SOGoContactGCSFolder contactFolderWithName: @"personal"
+                             andDisplayName: @"Personal Addressbook"
+                             inContainer: self];
+  [ab setOCSPath: [NSString stringWithFormat: @"%@/%@",
+                            OCSPath, @"personal"]];
+  [contactFolders setObject: ab forKey: @"personal"];
+}
+
+- (void) appendSystemSourcesInContext: (WOContext *) context;
+{
+  NSUserDefaults *ud;
+  NSEnumerator *ldapABs;
+  NSDictionary *udAB;
+  SOGoContactLDAPFolder *ab;
+
+  ud = [NSUserDefaults standardUserDefaults];
+  ldapABs = [[ud objectForKey: @"SOGoLDAPAddressBooks"] objectEnumerator];
+  udAB = [ldapABs nextObject];
+  while (udAB)
+    {
+      ab = [SOGoContactLDAPFolder contactFolderWithName:
+                                    [udAB objectForKey: @"id"]
+                                  andDisplayName:
+                                    [udAB objectForKey: @"displayName"]
+                                  inContainer: self];
+      [ab LDAPSetHostname: [udAB objectForKey: @"hostname"]
+          setPort: [[udAB objectForKey: @"port"] intValue]
+          setBindDN: [udAB objectForKey: @"bindDN"]
+          setBindPW: [udAB objectForKey: @"bindPW"]
+          setContactIdentifier: [udAB objectForKey: @"idField"]
+          setUserIdentifier: [udAB objectForKey: @"userIdField"]
+          setRootDN: [udAB objectForKey: @"rootDN"]];
+      [contactFolders setObject: ab forKey: [udAB objectForKey: @"id"]];
+      udAB = [ldapABs nextObject];
+    }
+}
+
+- (void) initContactSourcesInContext: (WOContext *) context;
+{
+  if (!contactFolders)
+    {
+      contactFolders = [NSMutableDictionary new];
+      [self appendPersonalSourcesInContext: context];
+      [self appendSystemSourcesInContext: context];
+    }
+}
+
+- (id) lookupName: (NSString *) name
+        inContext: (WOContext *) context
+          acquire: (BOOL) acquire
+{
+  id obj;
+  id folder;
+
+  /* first check attributes directly bound to the application */
+  obj = [super lookupName: name inContext: context acquire: NO];
+  if (!obj)
+    {
+      if (!contactFolders)
+        [self initContactSourcesInContext: context];
+
+      folder = [contactFolders objectForKey: name];
+      obj = ((folder)
+             ? folder
+             : [NSException exceptionWithHTTPStatus: 404]);
+    }
+
+  return obj;
+}
+
+- (NSArray *) toManyRelationshipKeys
+{
+  WOContext *context;
+
+  if (!contactFolders)
+    {
+      context = [[WOApplication application] context];
+      [self initContactSourcesInContext: context];
+    }
+
+  return [contactFolders allKeys];
+}
+
+- (NSArray *) contactFolders
+{
+  WOContext *context;
+
+  if (!contactFolders)
+    {
+      context = [[WOApplication application] context];
+      [self initContactSourcesInContext: context];
+    }
+
+  return [contactFolders allValues];
+}
+
+- (NSString *) roleOfUser: (NSString *) uid
+                inContext: (WOContext *) context
+{
+  NSArray *roles, *traversalPath;
+  NSString *objectName, *role;
+
+  role = nil;
+  traversalPath = [context objectForKey: @"SoRequestTraversalPath"];
+  if ([traversalPath count] > 2)
+    {
+      objectName = [traversalPath objectAtIndex: 2];
+      if ([objectName isEqualToString: @"personal"])
+        {
+          roles = [[context activeUser]
+                    rolesForObject: [self lookupName: objectName
+                                          inContext: context
+                                          acquire: NO]
+                    inContext: context];
+          if ([roles containsObject: SOGoRole_Assistant]
+              || [roles containsObject: SOGoRole_Delegate])
+            role = SOGoRole_Assistant;
+        }
+    }
+
+  return role;
+}
+
+- (BOOL) davIsCollection
+{
+  return YES;
+}
+
+- (void) setBaseOCSPath: (NSString *) newOCSPath
+{
+  if (OCSPath)
+    [OCSPath release];
+  OCSPath = newOCSPath;
+  if (OCSPath)
+    [OCSPath retain];
+}
+
+/* web interface */
+- (NSString *) defaultSourceName
+{
+  return @"personal";
+}
+
+@end
diff --git a/SoObjects/Contacts/SOGoContactGCSEntry.h b/SoObjects/Contacts/SOGoContactGCSEntry.h
new file mode 100644 (file)
index 0000000..4ebfeac
--- /dev/null
@@ -0,0 +1,39 @@
+/* SOGoContactGCSEntry.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOCONTACTGCSENTRY_H
+#define SOGOCONTACTGCSENTRY_H
+
+#import <SOGo/SOGoContentObject.h>
+
+#import "SOGoContactObject.h"
+
+@class NGVCard;
+
+@interface SOGoContactGCSEntry : SOGoContentObject <SOGoContactObject>
+{
+  NGVCard *card;
+}
+
+@end
+
+#endif /* SOGOCONTACTGCSENTRY_H */
diff --git a/SoObjects/Contacts/SOGoContactGCSEntry.m b/SoObjects/Contacts/SOGoContactGCSEntry.m
new file mode 100644 (file)
index 0000000..1dde518
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+
+#import <NGCards/NGVCard.h>
+
+#import "SOGoContactGCSEntry.h"
+
+@implementation SOGoContactGCSEntry
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      card = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (card)
+    [card release];
+  [super dealloc];
+}
+
+/* content */
+
+- (NGVCard *) vCard
+{
+  NSString *contentStr;
+
+  if (!card)
+    {
+      contentStr = [self contentAsString];
+      if ([contentStr hasPrefix:@"BEGIN:VCARD"])
+        card = [NGVCard parseSingleFromSource: contentStr];
+      else
+        card = [NGVCard cardWithUid: [self nameInContainer]];
+      [card retain];
+    }
+
+  return card;
+}
+
+/* DAV */
+
+- (NSString *) davContentType
+{
+  return @"text/x-vcard";
+}
+
+/* specialized actions */
+
+- (void) save
+{
+  NGVCard *vcard;
+
+  vcard = [self vCard];
+
+  [self saveContentString: [vcard versitString]];
+}
+
+/* message type */
+
+- (NSString *) outlookMessageClass
+{
+  return @"IPM.Contact";
+}
+
+@end /* SOGoContactGCSEntry */
similarity index 72%
rename from UI/MailerUI/UIxMailAccountsView.m
rename to SoObjects/Contacts/SOGoContactGCSFolder.h
index cbef1b2b3235366b649dd196d113c97db25ef206..71113a6f803070360d55e701dd3e8252d13586ae 100644 (file)
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
+#ifndef __Contacts_SOGoContactGCSFolder_H__
+#define __Contacts_SOGoContactGCSFolder_H__
 
-@interface UIxMailAccountsView : UIxComponent
+#import <SOGo/SOGoFolder.h>
+#import "SOGoContactFolder.h"
+
+@class NSString, NSArray;
+
+@interface SOGoContactGCSFolder : SOGoFolder <SOGoContactFolder>
 {
+  NSString *displayName;
 }
 
 @end
 
-#include "common.h"
-
-@implementation UIxMailAccountsView
-
-- (NSString *)panelTitle {
-  return [self labelForKey:@"SOGo Mail Accounts"];
-}
-
-@end /* UIxMailAccountsView */
+#endif /* __Contacts_SOGoContactGCSFolder_H__ */
diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m
new file mode 100644 (file)
index 0000000..6dd136b
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#import <GDLContentStore/GCSFolder.h>
+
+#import "common.h"
+
+#import "SOGoContactGCSEntry.h"
+#import "SOGoContactGCSFolder.h"
+
+#define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
+                                     @"sn", @"givenname", @"l",          \
+                                     @"mail", @"telephonenumber",        \
+                                     nil]
+
+@implementation SOGoContactGCSFolder
+
++ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
+                                  andDisplayName: (NSString *) aDisplayName
+                                     inContainer: (SOGoObject *) aContainer
+{
+  SOGoContactGCSFolder *folder;
+
+  folder = [[self alloc] initWithName: aName
+                         andDisplayName: aDisplayName
+                         inContainer: aContainer];
+  [folder autorelease];
+
+  return folder;
+}
+
+- (id <SOGoContactFolder>) initWithName: (NSString *) aName
+                         andDisplayName: (NSString *) aDisplayName
+                            inContainer: (SOGoObject *) aContainer
+{
+  if ((self = [self initWithName: aName
+                    inContainer: aContainer]))
+    [self setDisplayName: aDisplayName];
+
+  return self;
+}
+
+- (void) setDisplayName: (NSString *) aDisplayName
+{
+  if (displayName)
+    [displayName release];
+  displayName = aDisplayName;
+  if (displayName)
+    [displayName retain];
+}
+
+- (NSString *) displayName
+{
+  return displayName;
+}
+
+/* name lookup */
+
+- (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
+{
+  SOGoContactGCSEntry *contact;
+
+  if ([recordId length] > 0)
+    contact = [SOGoContactGCSEntry objectWithName: recordId
+                                   inContainer: self];
+  else
+    contact = nil;
+
+  return contact;
+}
+
+- (id) lookupName: (NSString *) _key
+        inContext: (WOContext *) _ctx
+          acquire: (BOOL) _flag
+{
+  id obj;
+
+  /* first check attributes directly bound to the application */
+  obj = [super lookupName:_key inContext:_ctx acquire:NO];
+  if (!obj)
+    {
+      if ([[[_ctx request] method] isEqualToString: @"PUT"])
+        {
+          obj = [[SOGoContactGCSEntry alloc] initWithName: _key
+                                             inContainer: self];
+          [obj autorelease];
+        }
+      else
+        obj = [self lookupContactWithId: _key];
+    }
+  if (!obj)
+    obj = [NSException exceptionWithHTTPStatus:404 /* Not Found */];
+
+// #if 0
+//     if ([[self ocsFolder] versionOfContentWithName:_key])
+// #endif
+//       return [self contactWithName:_key inContext:_ctx];
+//   }
+
+  /* return 404 to stop acquisition */
+  return obj;
+}
+
+/* fetching */
+- (EOQualifier *) _qualifierForFilter: (NSString *) filter
+{
+  NSString *qs;
+  EOQualifier *qualifier;
+
+  if (filter && [filter length] > 0)
+    {
+      qs = [NSString stringWithFormat:
+                       @"(sn isCaseInsensitiveLike: '%@%%') OR "
+                     @"(givenname isCaseInsensitiveLike: '%@%%') OR "
+                     @"(mail isCaseInsensitiveLike: '%@%%') OR "
+                     @"(telephonenumber isCaseInsensitiveLike: '%%%@%%')",
+                     filter, filter, filter, filter];
+      qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
+    }
+  else
+    qualifier = nil;
+
+  return qualifier;
+}
+
+- (NSArray *) lookupContactsWithFilter: (NSString *) filter
+                                sortBy: (NSString *) sortKey
+                              ordering: (NSComparisonResult) sortOrdering
+{
+  NSArray *fields, *records;
+  EOQualifier *qualifier;
+  EOSortOrdering *ordering;
+
+  NSLog (@"fetching records matching '*%@*', sorted by '%@' in order %d",
+         filter, sortKey, sortOrdering);
+
+  fields = folderListingFields;
+  qualifier = [self _qualifierForFilter: filter];
+  records = [[self ocsFolder] fetchFields: fields
+                              matchingQualifier: qualifier];
+  if (records)
+    {
+      ordering
+        = [EOSortOrdering sortOrderingWithKey: sortKey
+                          selector: ((sortOrdering == NSOrderedDescending)
+                                     ? EOCompareCaseInsensitiveDescending
+                                     : EOCompareCaseInsensitiveAscending)];
+      records
+        = [records sortedArrayUsingKeyOrderArray:
+                     [NSArray arrayWithObject: ordering]];
+    }
+  else
+    [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
+
+  //[self debugWithFormat:@"fetched %i records.", [records count]];
+  return records;
+}
+
+- (NSString *) groupDavResourceType
+{
+  return @"vcard-collection";
+}
+
+// /* GET */
+
+// - (id) GETAction: (id)_ctx
+// {
+//   // TODO: I guess this should really be done by SOPE (redirect to
+//   //       default method)
+//   WOResponse *r;
+//   NSString *uri;
+
+//   uri = [[_ctx request] uri];
+//   if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
+//   uri = [uri stringByAppendingString:@"view"];
+  
+//   r = [_ctx response];
+//   [r setStatus:302 /* moved */];
+//   [r setHeader:uri forKey:@"location"];
+//   return r;
+// }
+
+/* folder type */
+
+- (NSString *)outlookFolderClass {
+  return @"IPF.Contact";
+}
+
+@end /* SOGoContactGCSFolder */
diff --git a/SoObjects/Contacts/SOGoContactLDAPEntry.h b/SoObjects/Contacts/SOGoContactLDAPEntry.h
new file mode 100644 (file)
index 0000000..44e4033
--- /dev/null
@@ -0,0 +1,50 @@
+/* SOGoContactLDAPEntry.h - this file is part of SOGo
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOCONTACTLDAPENTRY_H
+#define SOGOCONTACTLDAPENTRY_H
+
+#import <SOGo/SOGoObject.h>
+
+#import "SOGoContactObject.h"
+
+@class NSString;
+@class SOGoContactLDAPFolder;
+@class NGLdapEntry;
+
+@interface SOGoContactLDAPEntry : SOGoObject <SOGoContactObject>
+{
+  NGLdapEntry *ldapEntry;
+  NGVCard *vcard;
+}
+
++ (SOGoContactLDAPEntry *) contactEntryWithName: (NSString *) aName
+                                  withLDAPEntry: (NGLdapEntry *) anEntry
+                                    inContainer: (id) aContainer;
+- (id) initWithName: (NSString *) aName
+      withLDAPEntry: (NGLdapEntry *) anEntry
+        inContainer: (id) aContainer;
+
+- (void) setLDAPEntry: (NGLdapEntry *) anEntry;
+
+@end
+
+#endif /* SOGOCONTACTLDAPENTRY_H */
diff --git a/SoObjects/Contacts/SOGoContactLDAPEntry.m b/SoObjects/Contacts/SOGoContactLDAPEntry.m
new file mode 100644 (file)
index 0000000..92f38c4
--- /dev/null
@@ -0,0 +1,212 @@
+/* SOGoContactLDAPEntry.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+
+#import <NGCards/NGVCard.h>
+#import <NGCards/CardVersitRenderer.h>
+
+#import <NGLdap/NGLdapEntry.h>
+#import <NGLdap/NGLdapAttribute.h>
+
+#import "NGLdapEntry+Contact.h"
+
+#import "SOGoContactLDAPEntry.h"
+
+@implementation SOGoContactLDAPEntry
+
++ (SOGoContactLDAPEntry *) contactEntryWithName: (NSString *) aName
+                                  withLDAPEntry: (NGLdapEntry *) anEntry
+                                    inContainer: (id) aContainer
+{
+  SOGoContactLDAPEntry *entry;
+
+  entry = [[self alloc] initWithName: aName
+                        withLDAPEntry: anEntry
+                        inContainer: aContainer];
+  [entry autorelease];
+
+  return entry;
+}
+
+- (void) dumpEntry: (NGLdapEntry *) anEntry
+{
+  NSArray *keys;
+  unsigned int count, max;
+
+  keys = [anEntry attributeNames];
+  max = [keys count];
+
+  NSLog (@"dumping entry...");
+  for (count = 0; count < max; count++)
+    NSLog (@"%d: %@ = '%@'", count,
+           [keys objectAtIndex: count],
+           [anEntry singleAttributeWithName: [keys objectAtIndex: count]]);
+  NSLog (@"dumping finished..");
+}
+
+- (id) initWithName: (NSString *) aName
+      withLDAPEntry: (NGLdapEntry *) anEntry
+        inContainer: (id) aContainer
+{
+  if ((self = [super initWithName: aName inContainer: aContainer]))
+    {
+      vcard = nil;
+      [self setLDAPEntry: anEntry];
+    }
+
+  [self dumpEntry: anEntry];
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (vcard)
+    [vcard release];
+  [super dealloc];
+}
+
+- (void) setLDAPEntry: (NGLdapEntry *) anEntry;
+{
+  ldapEntry = anEntry;
+}
+
+- (NSString *) contentAsString
+{
+  return [[self vCard] versitString];
+}
+
+- (void) _setPhonesOfVCard: (NGVCard *) vCard
+{
+  NSString *info;
+
+  info = [ldapEntry singleAttributeWithName: @"telephoneNumber"];
+  if (info)
+    [vCard addTel: info
+           types: [NSArray arrayWithObjects: @"work", @"voice", @"pref", nil]];
+  info = [ldapEntry singleAttributeWithName: @"homePhone"];
+  if (info)
+    [vCard addTel: info
+           types: [NSArray arrayWithObjects: @"home", @"voice", nil]];
+  info = [ldapEntry singleAttributeWithName: @"fax"];
+  if (info)
+    [vCard addTel: info
+           types: [NSArray arrayWithObjects: @"work", @"fax", nil]];
+  info = [ldapEntry singleAttributeWithName: @"pager"];
+  if (info)
+    [vCard addTel: info
+           types: [NSArray arrayWithObjects: @"pager", nil]];
+  info = [ldapEntry singleAttributeWithName: @"mobile"];
+  if (info)
+    [vCard addTel: info
+           types: [NSArray arrayWithObjects: @"cell", @"voice", nil]];
+
+// telephoneNumber: work phone
+// homePhone: home phone
+// fax: fax phone
+// pager: page phone
+// mobile: mobile phone
+  
+}
+
+- (NGVCard *) vCard
+{
+  NSString *info, *surname, *streetAddress, *location;
+  CardElement *element;
+
+  if (!vcard)
+    {
+      vcard = [[NGVCard alloc] initWithUid: [self nameInContainer]];
+      [vcard setVClass: @"PUBLIC"];
+      [vcard setProdID: @"-//OpenGroupware.org//SOGo"];
+      [vcard setProfile: @"vCard"];
+      info = [ldapEntry singleAttributeWithName: @"displayName"];
+      if (!(info && [info length] > 0))
+        info = [ldapEntry singleAttributeWithName: @"cn"];
+      [vcard setFn: info];
+      surname = [ldapEntry singleAttributeWithName: @"sn"];
+      if (!surname)
+        surname = [ldapEntry singleAttributeWithName: @"surname"];
+      [vcard setNWithFamily: surname
+             given: [ldapEntry singleAttributeWithName: @"givenName"]
+             additional: nil
+             prefixes: nil
+             suffixes: nil];
+      info = [ldapEntry singleAttributeWithName: @"title"];
+      if (info)
+        [vcard setTitle: info];
+      info = [ldapEntry singleAttributeWithName: @"mozillaNickname"];
+      if (info)
+        [vcard setNickname: info];
+      info = [ldapEntry singleAttributeWithName: @"xmozillaNickname"];
+      if (info)
+        [vcard setNickname: info];
+      info = [ldapEntry singleAttributeWithName: @"notes"];
+      if (info)
+        [vcard setNote: info];
+      info = [ldapEntry singleAttributeWithName: @"mail"];
+      if (info)
+        [vcard addEmail: info
+               types: [NSArray arrayWithObjects: @"internet", @"pref", nil]];
+      [self _setPhonesOfVCard: vcard];
+      streetAddress = [ldapEntry singleAttributeWithName: @"streetAddress"];
+      location = [ldapEntry singleAttributeWithName: @"l"];
+      element = [CardElement elementWithTag: @"adr"
+                             attributes: nil values: nil];
+      [element setValue: 0 ofAttribute: @"type" to: @"work"];
+      if (streetAddress)
+        [element setValue: 2 to: streetAddress];
+      if (location)
+        [element setValue: 3 to: location];
+      if (streetAddress || location)
+        [vcard addChild: element];
+    }
+
+  return vcard;
+}
+
+- (NSString *) davEntityTag
+{
+  return [[ldapEntry attributeWithName: @"modifyTimeStamp"]
+           stringValueAtIndex: 0];
+}
+
+- (NSString *) davContentType
+{
+  return @"text/x-vcard";
+}
+
+- (void) save
+{
+}
+
+/* message type */
+
+- (NSString *) outlookMessageClass
+{
+  return @"IPM.Contact";
+}
+
+@end
diff --git a/SoObjects/Contacts/SOGoContactLDAPFolder.h b/SoObjects/Contacts/SOGoContactLDAPFolder.h
new file mode 100644 (file)
index 0000000..88a8906
--- /dev/null
@@ -0,0 +1,58 @@
+/* SOGoContactLDAPFolder.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOCONTACTLDAPFOLDER_H
+#define SOGOCONTACTLDAPFOLDER_H
+
+#import <SOGo/SOGoObject.h>
+#import "SOGoContactFolder.h"
+
+@class NSString, NSArray;
+@class NGLdapConnection;
+
+@interface SOGoContactLDAPFolder : SOGoObject <SOGoContactFolder>
+{
+  NGLdapConnection *connection;
+  NSString *contactIdentifier;
+  NSString *userIdentifier;
+  NSString *rootDN;
+  NSString *displayName;
+  NSMutableDictionary *entries;
+}
+
+- (NGLdapConnection *) LDAPconnection;
+
+- (void) setDisplayName: (NSString *) aDisplayName;
+- (NSString *) displayName;
+
+- (void) LDAPSetHostname: (NSString *) aHostname
+                 setPort: (int) aPort
+               setBindDN: (NSString *) aBindDN
+               setBindPW: (NSString *) aBindPW
+    setContactIdentifier: (NSString *) aCI
+       setUserIdentifier: (NSString *) aUI
+               setRootDN: (NSString *) aRootDN;
+
+@end
+
+
+#endif /* SOGOCONTACTLDAPFOLDER_H */
diff --git a/SoObjects/Contacts/SOGoContactLDAPFolder.m b/SoObjects/Contacts/SOGoContactLDAPFolder.m
new file mode 100644 (file)
index 0000000..bc4ae3a
--- /dev/null
@@ -0,0 +1,401 @@
+/* SOGoContactLDAPFolder.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+
+#import <NGObjWeb/WOApplication.h>
+#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/SoUser.h>
+
+#import <NGLdap/NGLdapAttribute.h>
+#import <NGLdap/NGLdapConnection.h>
+#import <NGLdap/NGLdapEntry.h>
+
+#import "common.h"
+
+#import "NGLdapEntry+Contact.h"
+
+#import "SOGoContactLDAPEntry.h"
+#import "SOGoContactLDAPFolder.h"
+
+#define folderListingFields [NSArray arrayWithObjects: @"c_name", @"cn", \
+                                     @"displayName",                     \
+                                     @"streetAddress",                   \
+                                     @"sn", @"givenname", @"l",          \
+                                     @"mail", @"telephonenumber",        \
+                                     @"mailNickname",                    \
+                                     @"sAMAccountName",                  \
+                                     nil]
+
+@class WOContext;
+
+@implementation SOGoContactLDAPFolder
+
++ (id <SOGoContactFolder>) contactFolderWithName: (NSString *) aName
+                                  andDisplayName: (NSString *) aDisplayName
+                                     inContainer: (SOGoObject *) aContainer
+{
+  SOGoContactLDAPFolder *folder;
+
+  folder = [[self alloc] initWithName: aName
+                         andDisplayName: aDisplayName
+                         inContainer: aContainer];
+  [folder autorelease];
+
+  return folder;
+}
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      connection = nil;
+      contactIdentifier = nil;
+      userIdentifier = nil;
+      rootDN = nil;
+      entries = nil;
+    }
+
+  return self;
+}
+
+- (id <SOGoContactFolder>) initWithName: (NSString *) aName
+                         andDisplayName: (NSString *) aDisplayName
+                            inContainer: (SOGoObject *) aContainer
+{
+  if ((self = [self initWithName: aName
+                    inContainer: aContainer]))
+    [self setDisplayName: aDisplayName];
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (connection)
+    {
+      if ([connection isBound])
+        [connection unbind];
+      [connection release];
+    }
+  if (contactIdentifier)
+    [contactIdentifier release];
+  if (userIdentifier)
+    [userIdentifier release];
+  if (rootDN)
+    [rootDN release];
+  if (entries)
+    [entries release];
+  [super dealloc];
+}
+
+- (void) setDisplayName: (NSString *) aDisplayName
+{
+  if (displayName)
+    [displayName release];
+  displayName = aDisplayName;
+  if (displayName)
+    [displayName retain];
+}
+
+- (NSString *) displayName
+{
+  return displayName;
+}
+
+- (void) LDAPSetHostname: (NSString *) aHostname
+                 setPort: (int) aPort
+               setBindDN: (NSString *) aBindDN
+               setBindPW: (NSString *) aBindPW
+    setContactIdentifier: (NSString *) aCI
+       setUserIdentifier: (NSString *) aUI
+               setRootDN: (NSString *) aRootDN;
+{
+  connection = [[NGLdapConnection alloc] initWithHostName: aHostname
+                                         port: aPort];
+  [connection bindWithMethod: nil
+              binddn: aBindDN
+              credentials: aBindPW];
+
+  if (rootDN)
+    [rootDN release];
+  rootDN = [aRootDN copy];
+  if (contactIdentifier)
+    [contactIdentifier release];
+  contactIdentifier = [aCI copy];
+  if (userIdentifier)
+    [userIdentifier release];
+  userIdentifier = [aUI copy];
+}
+
+- (NGLdapConnection *) LDAPconnection
+{
+  return connection;
+}
+
+- (NGLdapAttribute *) _attrWithName: (NSString *) aName
+{
+  return [[[NGLdapAttribute alloc] initWithAttributeName: aName] autorelease];
+}
+
+- (NSArray *) _searchAttributes
+{
+  return [NSArray arrayWithObjects:
+                    contactIdentifier,
+                  userIdentifier,
+                  @"title",
+                  @"company",
+                  @"o",
+                  @"displayName",
+                  @"modifytimestamp",
+                  @"mozillaHomeState",
+                  @"mozillaHomeUrl",
+                  @"homeurl",
+                  @"st",
+                  @"region",
+                  @"mozillaCustom2",
+                  @"custom2",
+                  @"mozillaHomeCountryName",
+                  @"description",
+                  @"notes",
+                  @"department",
+                  @"departmentnumber",
+                  @"ou",
+                  @"orgunit",
+                  @"mobile",
+                  @"cellphone",
+                  @"carphone",
+                  @"mozillaCustom1",
+                  @"custom1",
+                  @"mozillaNickname",
+                  @"xmozillanickname",
+                  @"mozillaWorkUrl",
+                  @"workurl",
+                  @"fax",
+                  @"facsimileTelephoneNumber",
+                  @"telephoneNumber",
+                  @"mozillaHomeStreet",
+                  @"mozillaSecondEmail",
+                  @"xmozillasecondemail",
+                  @"mozillaCustom4",
+                  @"custom4",
+                  @"nsAIMid",
+                  @"nscpaimscreenname",
+                  @"street",
+                  @"streetAddress",
+                  @"postOfficeBox",
+                  @"homePhone",
+                  @"cn",
+                  @"commonname",
+                  @"givenName",
+                  @"mozillaHomePostalCode",
+                  @"mozillaHomeLocalityName",
+                  @"mozillaWorkStreet2",
+                  @"mozillaUseHtmlMail",
+                  @"xmozillausehtmlmail",
+                  @"mozillaHomeStreet2",
+                  @"postalCode",
+                  @"zip",
+                  @"c",
+                  @"countryname",
+                  @"pager",
+                  @"pagerphone",
+                  @"mail",
+                  @"sn",
+                  @"surname",
+                  @"mozillaCustom3",
+                  @"custom3",
+                  @"l",
+                  @"locality",
+                  @"birthyear",
+                  @"serialNumber",
+                  nil];
+}
+
+- (void) _loadEntries: (NSString *) entryId
+{
+  NSEnumerator *contacts;
+  NGLdapEntry *entry;
+  NSString *key;
+
+  if (!entries)
+    entries = [NSMutableDictionary new];
+
+  if (entryId)
+    {
+      if (![entries objectForKey: entryId])
+        {
+          entry
+            = [connection entryAtDN:
+                            [NSString stringWithFormat: @"%@=%@,%@",
+                                      contactIdentifier, entryId, rootDN]
+                          attributes: [self _searchAttributes]];
+          if (entry)
+            [entries setObject: entry forKey: entryId];
+        }
+    }
+  else
+    {
+      contacts = [connection deepSearchAtBaseDN: rootDN
+                             qualifier: nil
+                             attributes: [self _searchAttributes]];
+      if (contacts)
+        {
+          entry = [contacts nextObject];
+          while (entry)
+            {
+              key = [[entry attributeWithName: contactIdentifier]
+                      stringValueAtIndex: 0];
+              if (key && ![entries objectForKey: key])
+                [entries setObject: entry forKey: key];
+              entry = [contacts nextObject];
+            }
+        }
+    }
+}
+
+- (id) lookupName: (NSString *) name
+        inContext: (WOContext *) context
+          acquire: (BOOL) acquire
+{
+  id obj;
+  NGLdapEntry *entry;
+
+//   NSLog (@"looking up name '%@'...", name);
+
+  /* first check attributes directly bound to the application */
+  obj = [super lookupName: name inContext: context acquire: NO];
+  if (!obj)
+    {
+      [self _loadEntries: name];
+      entry = [entries objectForKey: name];
+      obj = ((entry)
+             ? [SOGoContactLDAPEntry contactEntryWithName: name
+                                     withLDAPEntry: entry
+                                     inContainer: self]
+             : [NSException exceptionWithHTTPStatus: 404]);
+    }
+
+  return obj;
+}
+
+- (NSArray *) toOneRelationshipKeys
+{
+  [self _loadEntries: nil];
+
+  return [entries allKeys];
+}
+
+- (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
+{
+  NGLdapEntry *entry;
+
+  [self _loadEntries: recordId];
+
+  entry = [entries objectForKey: recordId];
+  return ((entry)
+          ? [SOGoContactLDAPEntry contactEntryWithName: recordId
+                                  withLDAPEntry: entry
+                                  inContainer: self]
+          : nil);
+}
+
+- (EOQualifier *) _qualifierForFilter: (NSString *) filter
+{
+  NSString *qs;
+  EOQualifier *qualifier;
+
+  if (filter && [filter length] > 0)
+    {
+      qs = [NSString stringWithFormat:
+                       @"(cn='%@*')"
+                     @"OR (sn='%@*')"
+                     @"OR (displayName='%@*')"
+                     @"OR (mail='%@*')"
+                     @"OR (telephoneNumber='*%@*')",
+                     filter, filter, filter, filter, filter];
+      qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
+    }
+  else
+    qualifier = nil;
+
+  return qualifier;
+}
+
+- (NSArray *) lookupContactsWithFilter: (NSString *) filter
+                                sortBy: (NSString *) sortKey
+                              ordering: (NSComparisonResult) sortOrdering
+{
+  NSMutableArray *records;
+  NSArray *result;
+  NGLdapEntry *entry;
+  NSEnumerator *contacts;
+  EOSortOrdering *ordering;
+
+  result = nil;
+
+  if (filter && [filter length] > 0)
+    {
+//       NSLog (@"%@: fetching records matching '*%@*', sorted by '%@'"
+//              @" in order %d",
+//              self, filter, sortKey, sortOrdering);
+
+      records = [NSMutableArray new];
+      [records autorelease];
+
+      contacts = [connection deepSearchAtBaseDN: rootDN
+                             qualifier: [self _qualifierForFilter: filter]
+                             attributes: folderListingFields];
+      entry = [contacts nextObject];
+      while (entry)
+        {
+          [records addObject: [entry asDictionaryWithAttributeNames: nil
+                                     withUID: userIdentifier
+                                     andCName: contactIdentifier]];
+          entry = [contacts nextObject];
+        }
+
+      ordering
+        = [EOSortOrdering sortOrderingWithKey: sortKey
+                          selector: ((sortOrdering == NSOrderedDescending)
+                                     ? EOCompareCaseInsensitiveDescending
+                                     : EOCompareCaseInsensitiveAscending)];
+      result
+        = [records sortedArrayUsingKeyOrderArray:
+                     [NSArray arrayWithObject: ordering]];
+    }
+
+  //[self debugWithFormat:@"fetched %i records.", [records count]];
+  return result;
+}
+
+- (NSString *) groupDavResourceType
+{
+  return @"vcard-collection";
+}
+
+@end
index b2d71c95545e169b099eafb3181258e63683a223..6903642e05052d7d095056690653d867aa3a4a93 100644 (file)
@@ -22,8 +22,6 @@
 #ifndef __Contacts_SOGoContactObject_H__
 #define __Contacts_SOGoContactObject_H__
 
-#include <SOGo/SOGoContentObject.h>
-
 /*
   SOGoContactObject
   
 */
 
 @class NSDictionary;
+@class NSString;
 @class NGVCard;
 
-@interface SOGoContactObject : SOGoContentObject
-{
-  id record; /* either an NSMutableDictionary or a NGVCard */
-}
+@protocol SOGoContactObject
 
-/* accessors */
+- (NSString *) contentAsString;
+- (NGVCard *) vCard;
+- (void) save;
 
-- (id)record;
-- (BOOL)isVCardRecord;
-- (NGVCard *)vCard;
+- (NSString *) davEntityTag;
+- (NSString *) nameInContainer;
 
 @end
 
diff --git a/SoObjects/Contacts/SOGoContactObject.m b/SoObjects/Contacts/SOGoContactObject.m
deleted file mode 100644 (file)
index 05f05fb..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "SOGoContactObject.h"
-#include <NGiCal/NGVCard.h>
-#include "common.h"
-
-@implementation SOGoContactObject
-
-- (void)dealloc {
-  [self->record release];
-  [super dealloc];
-}
-
-/* content */
-
-- (id)record {
-  if (self->record == nil) {
-    NSString *s;
-    
-    s = [self contentAsString];
-    
-    if ([s hasPrefix:@"BEGIN:VCARD"]) {
-      NSArray *v;
-      
-      v = [NGVCard parseVCardsFromSource:s];
-      if ([v count] == 0) {
-       [self errorWithFormat:@"Could not parse vCards from content!"];
-       return nil;
-      }
-      
-      self->record = [[v objectAtIndex:0] retain];
-    }
-    else
-      self->record = [[s propertyList] copy];
-    
-    if (self->record == nil)
-      self->record = [[NSNull null] retain];
-  }
-  return [self->record isNotNull] ? self->record : nil;
-}
-
-- (BOOL)isVCardRecord {
-  return [[self record] isKindOfClass:[NGVCard class]];
-}
-
-- (NGVCard *)vCard {
-  return [[self record] isKindOfClass:[NGVCard class]]
-    ? [self record]
-    : nil;
-}
-
-/* key value coding */
-
-- (id)valueForKey:(NSString *)_key {
-  id value;
-  
-  if ((value = [[self record] valueForKey:_key]) != nil)
-    return value;
-
-  return [super valueForKey:_key];
-}
-
-/* DAV */
-
-- (NSString *)davDisplayName {
-  NSString *n;
-  
-  if ((n = [self valueForKey:@"cn"]))
-    return n;
-  
-  return [self nameInContainer];
-}
-
-/* specialized actions */
-
-- (NSException *)saveRecord:(id)_record {
-  if ([_record isKindOfClass:[NGVCard class]]) {
-    // TODO: implement a vCard generator
-    return [NSException exceptionWithHTTPStatus:501 /* Not Implemented */
-                       reason:@"Saving vCards is not supported yet."];
-  }
-  
-  return [self saveContentString:[_record description]];
-}
-
-- (NSException *)patchField:(NSString *)_fname value:(NSString *)_value
-  inContext:(id)_ctx
-{
-  NSMutableDictionary *md;
-
-  if ([self isVCardRecord]) {
-    return [NSException exceptionWithHTTPStatus:501 /* Not Implemented */
-                       reason:@"Changing vCards is not supported yet."];
-  }
-  
-  if ([_fname length] == 0) {
-    return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                       reason:@"missing form field name"];
-  }
-  
-  if ((md = [[[self record] mutableCopy] autorelease]) == nil) {
-    return [NSException exceptionWithHTTPStatus:404 /* Not Found */
-                       reason:@"did not find contact record"];
-  }
-  
-  [md setObject:[_value isNotNull] ? _value : @"" forKey:_fname];
-  
-  return [self saveRecord:md];
-}
-
-- (id)patchOneFieldAction:(id)_ctx {
-  /* 
-     expects: fieldname\nfieldvalue
-     
-     TODO: should be extended to properly parse XML.
-  */
-  NSArray *fields;
-  NSException *error;
-  
-  fields = [[[(WOContext *)_ctx request] contentAsString] 
-            componentsSeparatedByString:@"\n"];
-
-  if ([fields count] < 2) {
-    return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                       reason:@"missing form fields"];
-  }
-  
-  error = [self patchField:[fields objectAtIndex:0] 
-               value:[fields objectAtIndex:1]
-               inContext:_ctx];
-  if (error != nil)
-    return error;
-  
-  return [(WOContext *)_ctx response];
-}
-
-/* message type */
-
-- (NSString *)outlookMessageClass {
-  return @"IPM.Contact";
-}
-
-@end /* SOGoContactObject */
index 15e534316f3aee1f4e14bbd2e165d4ff3bf14ad6..4ff7a9372c19c616c83c11037768d77ed28c7cb0 100644 (file)
@@ -8,27 +8,37 @@
   };
   
   classes = {
-    SOGoContactFolder = {
-      superclass    = "SOGoFolder";
-
-      protectedBy   = "View";
-      defaultAccess = "allow"; /* I think this affects key lookup */
+    SOGoContactFolders = {
+      superclass    = "SOGoObject";
       defaultRoles = {
-        "View"          = "Owner";
-        "WebDAV Access" = "Owner";
+        "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
+        "View"          = ( "Owner", "Delegate", "Assistant" );
+        "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
+        "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
+        "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+        "SaveAcls" = ( "Owner" );
       };
     };
-    SOGoContactObject = {
-      superclass    = "SOGoContentObject";
 
-      protectedBy   = "View";
-      defaultAccess = "allow"; /* I think this affects key lookup */
+    SOGoContactGCSFolder = {
+      superclass    = "SOGoFolder";
+    };
+
+    SOGoContactGCSEntry = {
+      superclass    = "SOGoContentObject";
       defaultRoles = {
-        "View"          = "Owner";
-        "WebDAV Access" = "Owner";
+        "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
       };
+    };
+
+    SOGoContactLDAPFolder = {
+      superclass    = "SOGoFolder";
+    };
 
-      methods = {
+    SOGoContactLDAPEntry = {
+      superclass    = "SOGoContentObject";
+      defaultRoles = {
+        "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
       };
     };
   };
index e8411e99caccadfb49b1f4f0e6b39be55a25e425..e82cd1ff76a104df91e8dc27fd86c264d1d6720e 100644 (file)
 #include <NGMime/NGMimeFileData.h>
 #include <NGMime/NGMimeMultipartBody.h>
 #include <NGMime/NGMimeType.h>
+#include <NGMime/NGMimeHeaderFieldGenerator.h>
 #include <NGImap4/NGImap4Envelope.h>
 #include <NGImap4/NGImap4EnvelopeAddress.h>
 #include <NGExtensions/NSFileManager+Extensions.h>
 #include "common.h"
 
+@interface NSString (NGMimeHelpers)
+
+- (NSString *) asQPSubjectString;
+
+@end
+
+@implementation NSString (NGMimeHelpers)
+
+- (NSString *) asQPSubjectString
+{
+  NSString *qpString;
+  unsigned char *data, *dest;
+  unsigned int dataLen, destLen;
+
+  dataLen = [self length];
+  data = calloc(dataLen, sizeof (unsigned char*));
+  [self getCString: (char *) data];
+
+  destLen = dataLen * 3;
+  dest = calloc(dataLen * 3, sizeof (unsigned char*));
+  NGEncodeQuotedPrintableMime (data, dataLen, dest, destLen);
+
+  qpString = [NSString stringWithFormat: @"=?utf-8?Q?%s?=", dest];
+
+  free (data);
+  free (dest);
+
+  return qpString;
+}
+
+@end
+
 @implementation SOGoDraftObject
 
 static NGMimeType  *TextPlainType  = nil;
@@ -274,7 +307,8 @@ static NSString    *fromInternetSuffixPattern = nil;
 
 /* NGMime representations */
 
-- (NGMimeBodyPart *)bodyPartForText {
+- (NGMimeBodyPart *)bodyPartForText
+{
   /*
     This add the text typed by the user (the primary plain/text part).
   */
@@ -295,7 +329,7 @@ static NSString    *fromInternetSuffixPattern = nil;
   if ((body = [lInfo objectForKey:@"text"]) != nil) {
     if ([body isKindOfClass:[NSString class]]) {
       [map setObject:@"text/plain; charset=utf-8" forKey:@"content-type"];
-      body = [body dataUsingEncoding:NSUTF8StringEncoding];
+//       body = [body dataUsingEncoding:NSUTF8StringEncoding];
     }
   }
   
@@ -306,7 +340,8 @@ static NSString    *fromInternetSuffixPattern = nil;
   return bodyPart;
 }
 
-- (NGMimeMessage *)mimeMessageForContentWithHeaderMap:(NGMutableHashMap *)map {
+- (NGMimeMessage *)mimeMessageForContentWithHeaderMap:(NGMutableHashMap *)map
+{
   NSDictionary  *lInfo;
   NGMimeMessage *message;  
   WOContext     *ctx;
@@ -336,13 +371,12 @@ static NSString    *fromInternetSuffixPattern = nil;
       
       /* Note: just 'utf8' is displayed wrong in Mail.app */
       [map setObject:@"text/plain; charset=utf-8" forKey:@"content-type"];
-      body = [body dataUsingEncoding:NSUTF8StringEncoding];
+//       body = [body dataUsingEncoding:NSUTF8StringEncoding];
     }
     else if ([body isKindOfClass:[NSData class]] && addSuffix) {
       body = [[body mutableCopy] autorelease];
-      [(NSMutableData *)body appendData:
-                         [fromInternetSuffix dataUsingEncoding:
-                                               NSUTF8StringEncoding]];
+      [(NSMutableData *)body
+                        appendData: [fromInternetSuffix dataUsingEncoding:NSUTF8StringEncoding]];
     }
     else if (addSuffix) {
       [self warnWithFormat:@"Note: cannot add Internet marker to body: %@",
@@ -350,7 +384,7 @@ static NSString    *fromInternetSuffixPattern = nil;
     }
   }
   else if (addSuffix)
-    body = [fromInternetSuffix dataUsingEncoding:NSUTF8StringEncoding];
+    body = fromInternetSuffix;
   
   message = [[[NGMimeMessage alloc] initWithHeader:map] autorelease];
   [message setBody:body];
@@ -374,11 +408,9 @@ static NSString    *fromInternetSuffixPattern = nil;
   NSString *s;
   
   s = [self mimeTypeForExtension:[_name pathExtension]];
-  if ([_name length] > 0) {
-    s = [s stringByAppendingString:@"; name=\""];
-    s = [s stringByAppendingString:_name];
-    s = [s stringByAppendingString:@"\""];
-  }
+  if ([_name length] > 0)
+    s = [s stringByAppendingFormat:@"; name=\"%@\"", _name];
+
   return s;
 }
 - (NSString *)contentDispositionForAttachmentWithName:(NSString *)_name {
@@ -624,7 +656,7 @@ static NSString    *fromInternetSuffixPattern = nil;
   /* add subject */
   
   if ([(s = [lInfo objectForKey:@"subject"]) length] > 0)
-    [map setObject:s forKey:@"subject"];
+    [map setObject: [s asQPSubjectString] forKey:@"subject"];
   
   /* add standard headers */
   
index aee34c2641f0e8cb459d02200b585c6dfb33f7a7..8f70346bd72d7bfb49cc4d6d2153bc76b4592182 100644 (file)
@@ -43,6 +43,7 @@ static BOOL     useAltNamespace       = NO;
 
 + (void)initialize {
   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+  NSString *cfgDraftsFolderName;
 
   NSAssert2([super version] == 1,
             @"invalid superclass (%@) version %i !",
@@ -52,10 +53,15 @@ static BOOL     useAltNamespace       = NO;
   
   sharedFolderName     = [ud stringForKey:@"SOGoSharedFolderName"];
   otherUsersFolderName = [ud stringForKey:@"SOGoOtherUsersFolderName"];
-  
+  cfgDraftsFolderName = [ud stringForKey:@"SOGoDraftsFolderName"];
+  if ([cfgDraftsFolderName length] > 0)
+    {
+      ASSIGN (draftsFolderName, cfgDraftsFolderName);
+      NSLog(@"Note: using drafts folder named:      '%@'", draftsFolderName);
+    }
+
   NSLog(@"Note: using shared-folders name:      '%@'", sharedFolderName);
   NSLog(@"Note: using other-users-folders name: '%@'", otherUsersFolderName);
-  
   if ([ud boolForKey:@"SOGoEnableSieveFolder"]) {
     rootFolderNames = [[NSArray alloc] initWithObjects:
                                        draftsFolderName, 
@@ -249,11 +255,11 @@ static BOOL     useAltNamespace       = NO;
   
   // TODO: those should be product.plist bindings? (can't be class bindings
   //       though because they are 'per-account')
-  if ([_key isEqualToString:draftsFolderName]) {
+  if ([_key isEqualToString: draftsFolderName]) {
     if ((obj = [self lookupDraftsFolder:_key inContext:_ctx]) != nil)
       return obj;
   }
-  if ([_key isEqualToString:sieveFolderName]) {
+  if ([_key isEqualToString: sieveFolderName]) {
     if ((obj = [self lookupFiltersFolder:_key inContext:_ctx]) != nil)
       return obj;
   }
index 002de868d4e8dfbb1096660fc7bde3cff3811ced..d88bb9d5b08e08d29c32d449a0979dcc8be8af8d 100644 (file)
@@ -113,9 +113,11 @@ static NSString *AgenorShareLoginMarker  = @".-.";
   
   return [[ctx activeUser] fetchAllMailIdentitiesWithOnlyEmitterAccess:_flag];
 }
+
 - (NSArray *)fetchAllIdentities {
   return [self fetchIdentitiesWithOnlyEmitterAccess:NO];
 }
+
 - (NSArray *)fetchIdentitiesWithEmitterPermissions {
   return [self fetchIdentitiesWithOnlyEmitterAccess:YES];
 }
@@ -143,6 +145,7 @@ static NSString *AgenorShareLoginMarker  = @".-.";
   ct = [[ctClass alloc] initWithName:_key inContainer:self];
   return [ct autorelease];
 }
+
 - (id)sharedMailAccountWithName:(NSString *)_key inContext:(id)_ctx {
   static Class ctClass = Nil;
   id ct;
index 4222e95110e13a401667510773124dedc7684bec..d6bf24cd30d700cea863092afb89ee228220e0bb 100644 (file)
@@ -63,6 +63,7 @@ static BOOL useAltNamespace = NO;
 - (NSArray *)toManyRelationshipKeys {
   return [[self imap4Connection] subfoldersForURL:[self imap4URL]];
 }
+
 - (NSArray *)toOneRelationshipKeys {
   NSArray  *uids;
   unsigned count;
index 1b5b7591f915debd989b1235f38a25de6f73ad2e..7e46daadd62e182b4ead508eb804eb42d33665d3 100644 (file)
@@ -87,6 +87,8 @@
 
 - (BOOL)isDeletionAllowed;
 - (NSException *)trashInContext:(id)_ctx;
+- (NSException *) moveToFolderNamed: (NSString *) folderName
+                          inContext: (id)_ctx;
 
 @end
 
index 69f1457a0853997d9a071e98a8c3ff2d2308f19a..4b30424b0cd0b2ab732964d93b1b2aa6ef562203 100644 (file)
@@ -569,24 +569,36 @@ static BOOL debugSoParts       = NO;
 
 /* convert parts to strings */
 
-- (NSString *)stringForData:(NSData *)_data partInfo:(NSDictionary *)_info {
-  NSString *charset;
-  NSString *s;
+- (NSString *)stringForData:(NSData *)_data partInfo:(NSDictionary *)_info
+{
+  NSString *charset, *encoding, *s;
+  NSData *mailData;
   
   if (![_data isNotNull])
     return nil;
 
   s = nil;
-  
-  charset = [[_info valueForKey:@"parameterList"] valueForKey:@"charset"];
-  if ([charset isNotNull] && [charset length] > 0)
-    s = [NSString stringWithData:_data usingEncodingNamed:charset];
-  
-  if (s == nil) { /* no charset provided, fall back to UTF-8 */
-    s = [[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding];
-    s = [s autorelease];
-  }
-  
+
+  encoding = [[_info objectForKey:@"encoding"] lowercaseString];
+
+  if ([encoding isEqualToString: @"7bit"]
+      || [encoding isEqualToString: @"8bit"])
+    mailData = _data;
+  else if ([encoding isEqualToString: @"base64"])
+    mailData = [_data dataByDecodingBase64];
+  else if ([encoding isEqualToString: @"quoted-printable"])
+    mailData = [_data dataByDecodingQuotedPrintable];
+  
+  charset = [[_info valueForKey:@"parameterList"] valueForKey: @"charset"];
+  if (![charset length])
+    {
+      s = [[NSString alloc] initWithData:mailData encoding:NSUTF8StringEncoding];
+      [s autorelease];
+    }
+  else
+    s = [NSString stringWithData: mailData
+                  usingEncodingNamed: charset];
+
   return s;
 }
 
@@ -800,6 +812,71 @@ static BOOL debugSoParts       = NO;
   return nil;
 }
 
+- (NSException *) moveToFolderNamed: (NSString *) folderName
+                          inContext: (id)_ctx
+{
+  /*
+    Trashing is three actions:
+    a) copy to trash folder
+    b) mark mail as deleted
+    c) expunge folder
+    
+    In case b) or c) fails, we can't do anything because IMAP4 doesn't tell us
+    the ID used in the trash folder.
+  */
+  SOGoMailFolder *destFolder;
+  NSEnumerator *folders;
+  NSString *currentFolderName, *reason;
+  NSException    *error;
+
+  // TODO: check for safe HTTP method
+
+  destFolder = [self mailAccountsFolder];
+  folders = [[folderName componentsSeparatedByString: @"/"] objectEnumerator];
+  currentFolderName = [folders nextObject];
+  currentFolderName = [folders nextObject];
+
+  while (currentFolderName)
+    {
+      destFolder = [destFolder lookupName: currentFolderName
+                               inContext: _ctx
+                               acquire: NO];
+      if ([destFolder isKindOfClass: [NSException class]])
+        return (NSException *) destFolder;
+      currentFolderName = [folders nextObject];
+    }
+
+  if (!([destFolder isKindOfClass: [SOGoMailFolder class]]
+        && [destFolder isNotNull]))
+    {
+      reason = [NSString stringWithFormat: @"Did not find folder name '%@'!",
+                         folderName];
+      return [NSException exceptionWithHTTPStatus:500 /* Server Error */
+                          reason: reason];
+    }
+  [destFolder flushMailCaches];
+
+  /* a) copy */
+  
+  error = [self davCopyToTargetObject: destFolder
+               newName:@"fakeNewUnusedByIMAP4" /* autoassigned */
+               inContext:_ctx];
+  if (error != nil) return error;
+
+  /* b) mark deleted */
+  
+  error = [[self imap4Connection] markURLDeleted: [self imap4URL]];
+  if (error != nil) return error;
+  
+  /* c) expunge */
+
+  error = [[self imap4Connection] expungeAtURL:[[self container] imap4URL]];
+  if (error != nil) return error; // TODO: unflag as deleted?
+  [self flushMailCaches];
+  
+  return nil;
+}
+
 - (NSException *)delete {
   /* 
      Note: delete is different to DELETEAction: for mails! The 'delete' runs
index db6ce1900fcb2aaf0460706fc8c855be104f6e25..2b3c6834fbab5d7ac018ac5fa4759d47f2d01dbe 100644 (file)
@@ -88,7 +88,7 @@
   identity = [self primaryMailIdentity];
   shares = [self valueForKey:@"additionalIMAP4AccountsAndEMails"];
   if ([shares count] == 0)
-    return identity;
+    return [NSArray arrayWithObject: identity];
   
   identities = [NSMutableArray arrayWithCapacity:[shares count] + 1];
   if (identity != nil) [identities addObject:identity];
index 31eacb15ba928b198d6e34af0d2aa6a0ab71a59f..2ace375aa39be3661e9273498ceb07e16b576c6c 100644 (file)
 
     SOGoMailAccounts = {
       superclass    = "SOGoMailBaseObject";
+      defaultRoles = {
+        "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
+        "View"          = ( "Owner", "Delegate", "Assistant" );
+        "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
+        "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
+        "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+        "SaveAcls" = ( "Owner" );
+      };
     };
 
     SOGoMailAccount = {
       superclass    = "SOGoMailBaseObject";
       defaultRoles = {
-        "Add Folders" = "Owner";
+        "Add Folders" = ( "Owner", "Delegate" );
+        "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
+        "View"          = ( "Owner", "Delegate", "Assistant" );
+        "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
+        "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
+        "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+        "SaveAcls" = ( "Owner" );
       };
     };
     SOGoSharedMailAccount = {
     SOGoMailFolder = {
       superclass    = "SOGoMailBaseObject";
       defaultRoles = {
-        "Add Folders" = "Owner";
+        "Add Folders" = ( "Owner", "Delegate" );
+        "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
+        "View"          = ( "Owner", "Delegate", "Assistant" );
+        "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
+        "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
+        "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+        "SaveAcls" = ( "Owner" );
       };
     };
     SOGoSharedInboxFolder = {
index 957349b00fffe5d7480feddf2935ea6d54979e42..c23fd460aeab153b3cb6623a587fd508d5289a8d 100644 (file)
@@ -53,7 +53,9 @@
 - (NSString *)getUIDForEmail:(NSString *)_email;
 - (NSString *)getEmailForUID:(NSString *)_uid;
 
-- (NSString *)getUIDForICalPerson:(iCalPerson *)_person;
+- (iCalPerson *) iCalPersonWithUid: (NSString *) uid;
+
+- (NSString *) getUIDForICalPerson: (iCalPerson *) _person;
 /* may insert NSNulls into returned array if _mapStrictly -> YES */
 - (NSArray  *)getUIDsForICalPersons:(NSArray *)_persons
   applyStrictMapping:(BOOL)_mapStrictly;
index b4cd12943190b836f8caca044f5be8be35382624..99617edce9a4bd5fd686865100597224b3f99f77 100644 (file)
@@ -23,7 +23,7 @@
 #include "AgenorUserDefaults.h"
 #include <NGExtensions/NGExtensions.h>
 #include <NGLdap/NGLdap.h>
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
 #include "SOGoLRUCache.h"
 
 @interface AgenorUserManager (PrivateAPI)
@@ -57,7 +57,7 @@ static NSString *ldapHost   = nil;
 static NSString *ldapBaseDN = nil;
 static NSNull   *sharedNull = nil;
 static NSString *fallbackIMAP4Server          = nil;
-static NSString *defaultMailDomain            = @"equipement.gouv.fr";
+static NSString *defaultMailDomain            = nil;
 static NSString *shareLDAPClass               = @"mineqMelBoite";
 static NSString *shareLoginSeparator          = @".-.";
 static NSString *mailEmissionAttrName         = @"mineqMelmailEmission";
@@ -69,7 +69,8 @@ static NSArray *fromEMailAttrs = nil;
 
 static unsigned PoolScanInterval = 5 * 60 /* every five minutes */;
 
-+ (void)initialize {
++ (void) initialize 
+{
   static BOOL didInit = NO;
   NSUserDefaults *ud;
   NSString *tmp;
@@ -93,7 +94,21 @@ static unsigned PoolScanInterval = 5 * 60 /* every five minutes */;
   if ([fallbackIMAP4Server length] > 0)
     NSLog(@"Note: using fallback IMAP4 server: '%@'", fallbackIMAP4Server);
   else
-    fallbackIMAP4Server = nil;
+    {
+      if (fallbackIMAP4Server)
+        [fallbackIMAP4Server release];
+      fallbackIMAP4Server = nil;
+    }
+
+  defaultMailDomain = [[ud stringForKey:@"SOGoDefaultMailDomain"] copy];
+  if ([defaultMailDomain length] == 0)
+    {
+      if (defaultMailDomain)
+        [defaultMailDomain release];
+      defaultMailDomain = nil;
+      NSLog(@"WARNING: no default mail domain (please specify"
+            " 'SOGoDefaultMailDomain' in the user default db)");
+    }
 
   fromEMailAttrs = 
     [[NSArray alloc] initWithObjects:mailEmissionAttrName, nil];
@@ -108,6 +123,11 @@ static unsigned PoolScanInterval = 5 * 60 /* every five minutes */;
     NSLog(@"ERROR: could not parse AgenorProfileURL: '%@'", tmp);
   else
     NSLog(@"Note: using profile at: %@", [AgenorProfileURL absoluteString]);
+
+  if ((tmp = [ud stringForKey: @"SOGoDefaultMailDomain"]))
+    {
+      defaultMailDomain = [tmp copy];
+    }
   
   PoolScanInterval = [[ud objectForKey:@"AgenorCacheCheckInterval"] intValue];
   if (PoolScanInterval == 0) 
@@ -910,8 +930,8 @@ static unsigned PoolScanInterval = 5 * 60 /* every five minutes */;
                     attributes:[self mailServerDiscoveryAttributes]];
   
   while ((entry = [resultEnum nextObject]) != nil) {
-    NSString *server, *shareLogin, *emitterAddress;
-    id shareUid;
+    NSString *server, *shareLogin;
+    id shareUid, emitterAddress;
 
     /* calculate server connect string */
     
@@ -939,14 +959,15 @@ static unsigned PoolScanInterval = 5 * 60 /* every five minutes */;
     
     /* calculate emitter address (check for proper access right) */
     
-    emitterAddress = [self hasUser:_uid partageAccess:"GC" inEntry:entry]
-      ? [self emissionEMailFromEntry:entry]
-      : nil;
+    if ([self hasUser:_uid partageAccess:"GC" inEntry:entry])
+      emitterAddress = [self emissionEMailFromEntry:entry];
+    else
+      emitterAddress = [NSNull null];
     
     /* set value */
     
-    [shares setObject:(emitterAddress ? emitterAddress : (id)[NSNull null])
-           forKey:shareLogin];
+    [shares setObject: emitterAddress
+           forKey: shareLogin];
   }
   
   /* cache */
@@ -1130,6 +1151,18 @@ static unsigned PoolScanInterval = 5 * 60 /* every five minutes */;
   return attr;
 }
 
+- (iCalPerson *) iCalPersonWithUid: (NSString *) uid
+{
+  iCalPerson *person;
+
+  person = [iCalPerson new];
+  [person autorelease];
+  [person setCn: [self getCNForUID: uid]];
+  [person setEmail: [self getEmailForUID: uid]];
+
+  return person;
+}
+
 /* debugging */
 
 - (BOOL)isDebuggingEnabled {
index f699f0f1969ba7fd0523683424f5c097a604f892..ffcc0cb0ee1a8e63405857e9e895a335c92a64c5 100644 (file)
@@ -23,17 +23,22 @@ libSOGo_HEADER_FILES = \
        SOGoObject.h                    \
        SOGoFolder.h                    \
        SOGoContentObject.h             \
+       SOGoAclsFolder.h                \
        SOGoUserFolder.h                \
        SOGoGroupsFolder.h              \
        SOGoGroupFolder.h               \
        SOGoCustomGroupFolder.h         \
        \
-       SOGoAppointment.h               \
        AgenorUserManager.h             \
+       SOGoPermissions.h               \
        SOGoLRUCache.h                  \
-       NSString+iCal.h                 \
+       NSArray+Utilities.h             \
        NSObject+AptComparison.h        \
        WOContext+Agenor.h              \
+       SOGoDAVRendererTypes.h          \
+       NSString+Utilities.h                    \
+       NSDictionary+URL.h              \
+       NSCalendarDate+SOGo.h           \
        \
        SOGoAuthenticator.h             \
        SOGoUser.h                      \
@@ -42,33 +47,35 @@ libSOGo_OBJC_FILES = \
        SOGoObject.m                    \
        SOGoFolder.m                    \
        SOGoContentObject.m             \
+       SOGoAclsFolder.m                \
        SOGoUserFolder.m                \
        SOGoGroupsFolder.m              \
        SOGoGroupFolder.m               \
        SOGoCustomGroupFolder.m         \
        \
-       SOGoAppointment.m               \
-       SOGoAppointmentICalRenderer.m   \
+       SOGoPermissions.m               \
        SOGoLRUCache.m                  \
        AgenorUserManager.m             \
        NSObject+AptComparison.m        \
        WOContext+Agenor.m              \
+       SOGoDAVRendererTypes.m          \
        AgenorUserDefaults.m            \
+       NSArray+Utilities.m             \
+       NSDictionary+URL.m              \
+       NSString+Utilities.m            \
+       NSCalendarDate+SOGo.m           \
        \
        SOGoAuthenticator.m             \
        SOGoUser.m                      \
 
 # tools
 
-COMMON_TOOL_FILES = \
-       AgenorUserManager.m     \
-       AgenorUserDefaults.m    \
-       SOGoLRUCache.m          \
+agenor_email2uid_OBJC_FILES  += agenor_email2uid.m
+agenor_shares4uid_OBJC_FILES += agenor_shares4uid.m
+agenor_emails4uid_OBJC_FILES += agenor_emails4uid.m
+agenor_defaults_OBJC_FILES   += agenor_defaults.m
 
-agenor_email2uid_OBJC_FILES  += agenor_email2uid.m  $(COMMON_TOOL_FILES)
-agenor_shares4uid_OBJC_FILES += agenor_shares4uid.m $(COMMON_TOOL_FILES)
-agenor_emails4uid_OBJC_FILES += agenor_emails4uid.m $(COMMON_TOOL_FILES)
-agenor_defaults_OBJC_FILES   += agenor_defaults.m   $(COMMON_TOOL_FILES)
+ADDITIONAL_TOOL_LIBS += -Lobj -lSOGo$(LIBRARY_NAME_SUFFIX)
 
 -include GNUmakefile.preamble
 include $(GNUSTEP_MAKEFILES)/library.make
index a4a27319d2bf603a4d2e32ba1dc770d2cb64e0aa..fd20c995895c2546958562b21abc2ef45d882d83 100644 (file)
@@ -19,7 +19,7 @@ libSOGo_LIBRARIES_DEPEND_UPON += \
        -lOGoContentStore       \
        -lGDLAccess             \
        -lNGObjWeb              \
-       -lNGiCal                \
+       -lNGCards               \
        -lNGMime                \
        -lNGStreams -lNGExtensions -lEOControl \
        -lXmlRpc -lDOM -lSaxObjC \
diff --git a/SoObjects/SOGo/NSArray+Utilities.h b/SoObjects/SOGo/NSArray+Utilities.h
new file mode 100644 (file)
index 0000000..bd026f4
--- /dev/null
@@ -0,0 +1,36 @@
+/* NSArray+Utilities.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef NSARRAY_UTILITIES_H
+#define NSARRAY_UTILITIES_H
+
+#import <Foundation/NSArray.h>
+
+@class NSString;
+
+@interface NSArray (SOGoArrayUtilities)
+
+- (NSArray *) stringsWithFormat: (NSString *) format;
+
+@end
+
+#endif /* NSARRAY_UTILITIES_H */
diff --git a/SoObjects/SOGo/NSArray+Utilities.m b/SoObjects/SOGo/NSArray+Utilities.m
new file mode 100644 (file)
index 0000000..6949db3
--- /dev/null
@@ -0,0 +1,48 @@
+/* NSArray+Utilities.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSString.h>
+
+#import "NSArray+Utilities.h"
+
+@implementation NSArray (SOGoArrayUtilities)
+
+- (NSArray *) stringsWithFormat: (NSString *) format
+{
+  NSMutableArray *formattedStrings;
+  NSEnumerator *objects;
+  id currentObject;
+
+  formattedStrings = [NSMutableArray arrayWithCapacity: [self count]];
+  objects = [self objectEnumerator];
+  currentObject = [objects nextObject];
+  while (currentObject)
+    {
+      [formattedStrings
+        addObject: [NSString stringWithFormat: format, currentObject]];
+      currentObject = [objects nextObject];
+    }
+
+  return formattedStrings;
+}
+
+@end
diff --git a/SoObjects/SOGo/NSCalendarDate+SOGo.h b/SoObjects/SOGo/NSCalendarDate+SOGo.h
new file mode 100644 (file)
index 0000000..84c2c66
--- /dev/null
@@ -0,0 +1,44 @@
+/* NSCalendarDate+SOGo.h - this file is part of SOGo
+   Copyright (C) 2000-2004 SKYRIX Software AG
+
+   This file is part of OGo
+
+   OGo is free software; you can redistribute it and/or modify it under
+   the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with OGo; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+*/
+
+#ifndef NSCALENDARDATE_SCHEDULER_H
+#define NSCALENDARDATE_SCHEDULER_H
+
+#import <Foundation/NSCalendarDate.h>
+
+@class NSString;
+@class NSTimeZone;
+
+@interface NSCalendarDate (SOGoExtensions)
+
++ (id) dateFromShortDateString: (NSString *) dateString
+            andShortTimeString: (NSString *) timeString
+                    inTimeZone: (NSTimeZone *) timeZone;
+
+- (BOOL) isDateInSameMonth: (NSCalendarDate *) _other;
+- (NSCalendarDate *) dayOfWeeK: (unsigned) _day
+              offsetFromSunday: (unsigned) _off;
+- (NSCalendarDate *) sundayOfWeek;
+- (NSString *) shortDateString;
+
+@end
+
+#endif /* NSCALENDARDATE_SCHEDULER_H */
diff --git a/SoObjects/SOGo/NSCalendarDate+SOGo.m b/SoObjects/SOGo/NSCalendarDate+SOGo.m
new file mode 100644 (file)
index 0000000..a6160ca
--- /dev/null
@@ -0,0 +1,113 @@
+/* NSCalendarDate+SOGo.m - this file is part of SOGo
+   Copyright (C) 2000-2004 SKYRIX Software AG
+
+   This file is part of OGo
+
+   OGo is free software; you can redistribute it and/or modify it under
+   the terms of the GNU Lesser General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+   License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with OGo; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+*/
+
+#import <NGExtensions/NSCalendarDate+misc.h>
+
+#import "NSCalendarDate+SOGo.h"
+
+@implementation NSCalendarDate (SOGoExtensions)
+
++ (id) dateFromShortDateString: (NSString *) dateString
+            andShortTimeString: (NSString *) timeString
+                    inTimeZone: (NSTimeZone *) timeZone
+{
+  unsigned int year, month, day, hour, minute, total;
+  NSCalendarDate *cDate, *tmpDate;
+
+  if (timeString && [timeString length] == 4)
+    {
+      total = [timeString intValue];
+      hour = total / 100;
+      minute = total - (hour * 100);
+    }
+  else
+    {
+      hour = 12;
+      minute = 0;
+    }
+
+  if (dateString && [dateString length] == 8)
+    {
+      total = [dateString intValue];
+      year = total / 10000;
+      total -= year * 10000;
+      month = total / 100;
+      day = total - (month * 100);
+      cDate = [self dateWithYear: year month: month day: day
+                    hour: hour minute: minute second: 0
+                    timeZone: timeZone];
+    }
+  else
+    {
+      tmpDate = [NSCalendarDate calendarDate];
+      [tmpDate setTimeZone: timeZone];
+      cDate = [self dateWithYear: [tmpDate yearOfCommonEra]
+                    month: [tmpDate monthOfYear]
+                    day: [tmpDate dayOfMonth]
+                    hour: hour minute: minute second: 0
+                    timeZone: timeZone];
+    }
+
+  return cDate;
+}
+
+- (BOOL) isDateInSameMonth: (NSCalendarDate *) _other
+{
+  return (([_other yearOfCommonEra] == [self yearOfCommonEra]) &&
+          ([_other monthOfYear] == [self monthOfYear]));
+}
+
+- (NSCalendarDate *) dayOfWeeK: (unsigned) _day 
+              offsetFromSunday: (unsigned) _offset
+{
+  unsigned dayOfWeek, distance;
+    
+  /* perform "locale" correction */
+  dayOfWeek = (7 + [self dayOfWeek] - _offset) % 7;
+
+  _day = (_day % 7);
+  if(_day == dayOfWeek)
+    return self;
+
+  distance = _day - dayOfWeek;
+  return [self dateByAddingYears:0 months:0 days:distance];
+}
+
+/* this implies that monday is the start of week! */
+
+- (NSCalendarDate *) sundayOfWeek
+{
+  return [self dayOfWeeK:6 offsetFromSunday:1];
+}
+
+- (NSString *) shortDateString
+{
+  NSString *str;
+
+  str = [NSString stringWithFormat: @"%.4d%.2d%.2d",
+                  [self yearOfCommonEra],
+                  [self monthOfYear],
+                  [self dayOfMonth]];
+
+  return str;
+}
+
+@end
diff --git a/SoObjects/SOGo/NSDictionary+URL.h b/SoObjects/SOGo/NSDictionary+URL.h
new file mode 100644 (file)
index 0000000..1568b04
--- /dev/null
@@ -0,0 +1,36 @@
+/* NSDictionary+URL.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef NSDICTIONARY_URL_H
+#define NSDICTIONARY_URL_H
+
+#import <Foundation/NSDictionary.h>
+
+@class NSString;
+
+@interface NSDictionary (SOGoURLExtension)
+
+- (NSString *) asURLParameters;
+
+@end
+
+#endif /* NSDICTIONARY_URL_H */
diff --git a/SoObjects/SOGo/NSDictionary+URL.m b/SoObjects/SOGo/NSDictionary+URL.m
new file mode 100644 (file)
index 0000000..dee5255
--- /dev/null
@@ -0,0 +1,69 @@
+/* NSDictionary+URL.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSEnumerator.h>
+#import <Foundation/NSString.h>
+
+#import "NSDictionary+URL.h"
+
+@implementation NSDictionary (SOGoURLExtension)
+
+- (NSString *) asURLParameters
+{
+  NSMutableString *urlParameters;
+  NSArray *keys;
+  NSEnumerator *keysEnum;
+  NSString *currentKey, *separator;
+  id currentValue;
+  BOOL isFirst;
+
+  urlParameters = [NSMutableString new];
+  [urlParameters autorelease];
+
+  keys = [self allKeys];
+  if ([keys count] > 0)
+    {
+      isFirst = YES;
+      keysEnum = [keys objectEnumerator];
+      currentKey = [keysEnum nextObject];
+      while (currentKey)
+       {
+          currentValue = [self objectForKey: currentKey];
+          if ([currentValue isKindOfClass: [NSArray class]])
+            {
+              separator = [NSString stringWithFormat: @"&%@=", currentKey];
+              currentValue
+                = [currentValue componentsJoinedByString: separator];
+            }
+          [urlParameters appendFormat: @"%@%@=%@",
+                         ((isFirst) ? @"?" : @"&"),
+                         currentKey, currentValue];
+         isFirst = NO;
+         currentKey = [keysEnum nextObject];
+       }
+    }
+
+  return urlParameters;
+}
+
+@end
index 3c3162723b70d9ad6f27ead6da081bcc8bab8b48..d3b0eb2d207fd65eff58201d426376b88620343c 100644 (file)
 
 @implementation NSObject (SOGoAptComparison)
 
-- (NSComparisonResult)compareAptsAscending:(id)_other {
+- (NSComparisonResult) compareAptsAscending: (id) _other
+{
   NSCalendarDate      *sd, *ed;
   NGCalendarDateRange *r1, *r2;
   NSComparisonResult  result;
   NSTimeInterval      t1, t2;
-  
-  sd = [self valueForKey:@"startDate"];
-  ed = [self valueForKey:@"endDate"];
-  r1 = [NGCalendarDateRange calendarDateRangeWithStartDate:sd
-                            endDate:ed];
-  
-  sd = [_other valueForKey:@"startDate"];
-  ed = [_other valueForKey:@"endDate"];
-  r2 = [NGCalendarDateRange calendarDateRangeWithStartDate:sd
-                            endDate:ed];
-  
-  result = [r1 compare:r2];
-  if (result != NSOrderedSame)
-    return result;
-  
-  t1 = [r1 duration];
-  t2 = [r2 duration];
-  if (t1 == t2)
-    return NSOrderedSame;
-  if (t1 > t2)
-    return NSOrderedDescending;
+
+  sd = [self valueForKey: @"startDate"];
+  ed = [self valueForKey: @"endDate"];
+  if (sd && ed)
+    r1 = [NGCalendarDateRange calendarDateRangeWithStartDate: sd
+                              endDate: ed];
+  else
+    r1 = nil;
+
+  sd = [_other valueForKey: @"startDate"];
+  ed = [_other valueForKey: @"endDate"];
+  if (sd && ed)
+    r2 = [NGCalendarDateRange calendarDateRangeWithStartDate: sd
+                              endDate: ed];
+  else
+    r2 = nil;
+
+  if (r1)
+    if (r2)
+      {
+        result = [r1 compare: r2];
+        if (result != NSOrderedSame)
+          return result;
+        
+        t1 = [r1 duration];
+        t2 = [r2 duration];
+        if (t1 == t2)
+          return NSOrderedSame;
+        if (t1 > t2)
+          return NSOrderedDescending;
+      }
+    else
+      return NSOrderedDescending;
+  else
+    if (!r2)
+      return NSOrderedSame;
+
   return NSOrderedAscending;
 }
 
diff --git a/SoObjects/SOGo/NSString+Utilities.h b/SoObjects/SOGo/NSString+Utilities.h
new file mode 100644 (file)
index 0000000..45d76d7
--- /dev/null
@@ -0,0 +1,43 @@
+/* NSString+URL.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef NSSTRING_URL_H
+#define NSSTRING_URL_H
+
+#import <Foundation/NSString.h>
+
+@class NSDictionary;
+
+@interface NSString (SOGoURLExtension)
+
+- (NSString *) composeURLWithAction: (NSString *) action
+                        parameters: (NSDictionary *) urlParameters
+                           andHash: (BOOL) useHash;
+- (NSString *) hostlessURL;
+
+- (NSString *) urlWithoutParameters;
+
+- (NSString *) davMethodToObjC;
+
+@end
+
+#endif /* NSSTRING_URL_H */
diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m
new file mode 100644 (file)
index 0000000..ae0b79e
--- /dev/null
@@ -0,0 +1,101 @@
+/* NSString+URL.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006  Inverse group conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import "NSString+Utilities.h"
+#import "NSDictionary+URL.h"
+
+@implementation NSString (SOGoURLExtension)
+
+- (NSString *) composeURLWithAction: (NSString *) action
+                        parameters: (NSDictionary *) urlParameters
+                           andHash: (BOOL) useHash
+{
+  NSMutableString *completeURL;
+
+  completeURL = [NSMutableString new];
+  [completeURL autorelease];
+
+  [completeURL appendString: [self urlWithoutParameters]];
+  if (![completeURL hasSuffix: @"/"])
+    [completeURL appendString: @"/"];
+  [completeURL appendString: action];
+  [completeURL appendString: [urlParameters asURLParameters]];
+  if (useHash)
+    [completeURL appendString: @"#"];
+
+  return completeURL;
+}
+
+- (NSString *) hostlessURL
+{
+  NSString *newURL;
+  NSRange hostR, locationR;
+
+  if ([self hasPrefix: @"/"])
+    {
+      newURL = [self copy];
+      [newURL autorelease];
+    }
+  else
+    {
+      hostR = [self rangeOfString: @"://"];
+      locationR = [[self substringFromIndex: (hostR.location + hostR.length)]
+                    rangeOfString: @"/"];
+      newURL = [self substringFromIndex: (hostR.location + hostR.length + locationR.location)];
+    }
+
+  return newURL;
+}
+
+- (NSString *) urlWithoutParameters;
+{
+  NSRange r;
+  NSString *newUrl;
+  
+  r = [self rangeOfString:@"?" options: NSBackwardsSearch];
+  if (r.length > 0)
+    newUrl = [self substringToIndex: NSMaxRange(r) - 1];
+  else
+    newUrl = self;
+
+  return newUrl;
+}
+
+- (NSString *) davMethodToObjC
+{
+  NSMutableString *newName;
+  NSEnumerator *components;
+  NSString *component;
+
+  newName = [NSMutableString stringWithString: @"dav"];
+  components = [[self componentsSeparatedByString: @"-"] objectEnumerator];
+  component = [components nextObject];
+  while (component)
+    {
+      [newName appendString: [component capitalizedString]];
+      component = [components nextObject];
+    }
+
+  return newName;
+}
+
+@end
diff --git a/SoObjects/SOGo/NSString+iCal.h b/SoObjects/SOGo/NSString+iCal.h
deleted file mode 100644 (file)
index f8d29cc..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#ifndef        __NSString_iCal_H_
-#define        __NSString_iCal_H_
-
-// DEPRECATED
-
-#import <Foundation/Foundation.h>
-#include <NGiCal/iCalRenderer.h>
-
-#endif /* __NSString_iCal_H_ */
diff --git a/SoObjects/SOGo/SOGoAclsFolder.h b/SoObjects/SOGo/SOGoAclsFolder.h
new file mode 100644 (file)
index 0000000..108db62
--- /dev/null
@@ -0,0 +1,49 @@
+/* SOGoAclsFolder.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOACLSFOLDER_H
+#define SOGOACLSFOLDER_H
+
+#import <Foundation/NSObject.h>
+
+@class NSString;
+@class GCSFolder;
+@class SOGoObject;
+
+@interface SOGoAclsFolder : NSObject
+{
+  NSString *ocsPath;
+  GCSFolder *ocsFolder;
+}
+
++ (id) aclsFolder;
+
+- (NSArray *) aclsForObject: (SOGoObject *) object;
+- (NSArray *) aclsForObject: (SOGoObject *) object
+                    forUser: (NSString *) uid;
+- (void) setRoleForObject: (SOGoObject *) object
+                 forUsers: (NSArray *) uids
+                       to: (NSString *) role;
+
+@end
+
+#endif /* SOGOACLSOBJECT_H */
diff --git a/SoObjects/SOGo/SOGoAclsFolder.m b/SoObjects/SOGo/SOGoAclsFolder.m
new file mode 100644 (file)
index 0000000..64c9710
--- /dev/null
@@ -0,0 +1,230 @@
+/* SOGoAclsFolder.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSKeyValueCoding.h>
+#import <Foundation/NSString.h>
+
+#import <NGExtensions/NSNull+misc.h>
+#import <NGObjWeb/SoObject.h>
+#import <EOControl/EOQualifier.h>
+#import <GDLAccess/EOAdaptorChannel.h>
+#import <GDLContentStore/GCSFolder.h>
+#import <GDLContentStore/GCSFolderManager.h>
+
+#import "SOGoFolder.h"
+#import "SOGoAclsFolder.h"
+
+@implementation SOGoAclsFolder
+
++ (id) aclsFolder
+{
+  id aclsFolder;
+
+  aclsFolder = [self new];
+  [aclsFolder autorelease];
+
+  return aclsFolder;
+}
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      ocsPath = nil;
+      ocsFolder = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (ocsPath)
+    [ocsPath release];
+  if (ocsFolder)
+    [ocsFolder release];
+  [super dealloc];
+}
+
+- (void) setOCSPath: (NSString *) newOCSPath
+{
+  if (ocsPath)
+    [ocsPath release];
+  ocsPath = newOCSPath;
+  if (ocsPath)
+    [ocsPath retain];
+}
+
+- (GCSFolderManager *)folderManager {
+  return [GCSFolderManager defaultFolderManager];
+}
+
+- (GCSFolder *)ocsFolderForPath:(NSString *)_path {
+  return [[self folderManager] folderAtPath:_path];
+}
+
+- (GCSFolder *) ocsFolder {
+  GCSFolder *folder;
+
+  if (!ocsFolder)
+    ocsFolder = [[self ocsFolderForPath: ocsPath] retain];
+
+  if ([ocsFolder isNotNull])
+    folder = ocsFolder;
+  else
+    folder = nil;
+
+  return folder;
+}
+
+- (NSString *) _ocsPathForObject: (SOGoObject *) object
+{
+  NSString *pathForObject;
+  id currentObject;
+  BOOL done;
+
+  pathForObject = nil;
+  currentObject = object;
+  done = NO;
+  while (currentObject && !done)
+    if ([currentObject isKindOfClass: [SOGoFolder class]])
+      {
+        pathForObject = [(SOGoFolder *) currentObject ocsPath];
+        done = YES;
+//         if (!pathForObject)
+//           currentObject = [currentObject container];
+      }
+    else
+      currentObject = [currentObject container];
+
+  return pathForObject;
+}
+
+- (NSArray *) aclsForObject: (SOGoObject *) object
+{
+  EOQualifier *qualifier;
+  NSString *objectPath;
+
+  [self setOCSPath: [self _ocsPathForObject: object]];
+
+  objectPath
+    = [NSString stringWithFormat: @"/%@",
+                [[object pathArrayToSoObject] componentsJoinedByString: @"/"]];
+  qualifier
+    = [EOQualifier qualifierWithQualifierFormat: @"c_object = %@", objectPath];
+
+  return [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
+}
+
+- (NSArray *) aclsForObject: (SOGoObject *) object
+                    forUser: (NSString *) uid
+{
+  EOQualifier *qualifier;
+  NSString *objectPath;
+  NSArray *records;
+
+  [self setOCSPath: [self _ocsPathForObject: object]];
+
+  objectPath
+    = [NSString stringWithFormat: @"/%@",
+                [[object pathArrayToSoObject] componentsJoinedByString: @"/"]];
+  qualifier = [EOQualifier
+                qualifierWithQualifierFormat: @"(c_object = %@) AND (c_uid = %@)",
+                objectPath, uid];
+
+  records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
+
+  return [records valueForKey: @"c_role"];
+}
+
+- (void) removeUsersWithRole: (NSString *) role
+             forObjectAtPath: (NSString *) objectPath
+                    inFolder: (GCSFolder *) folder
+{
+  NSString *deleteSQL;
+  EOAdaptorChannel *channel;
+
+  channel = [folder acquireAclChannel];
+
+  deleteSQL = [NSString stringWithFormat: @"DELETE FROM %@"
+                        @" WHERE c_object = '%@'"
+                        @" AND c_role = '%@'",
+                        [folder aclTableName], objectPath, role];
+  [channel evaluateExpressionX: deleteSQL];
+}
+
+- (void) setRoleForObjectAtPath: (NSString *) objectPath
+                        forUser: (NSString *) uid
+                             to: (NSString *) role
+                       inFolder: (GCSFolder *) folder
+{
+  NSString *SQL;
+  EOAdaptorChannel *channel;
+
+  channel = [folder acquireAclChannel];
+
+  SQL = [NSString stringWithFormat: @"DELETE FROM %@"
+                  @" WHERE c_object = '%@'"
+                  @" AND c_uid = '%@'",
+                  [folder aclTableName], objectPath, uid];
+  [channel evaluateExpressionX: SQL];
+  SQL = [NSString stringWithFormat: @"INSERT INTO %@"
+                  @" (c_object, c_uid, c_role)"
+                  @" VALUES ('%@', '%@', '%@')", [folder aclTableName],
+                  objectPath, uid, role];
+  [channel evaluateExpressionX: SQL];
+}
+
+/* FIXME: part of this code should be moved to sope-gdl/GCSFolder.m */
+- (void) setRoleForObject: (SOGoObject *) object
+                 forUsers: (NSArray *) uids
+                       to: (NSString *) role
+{
+  GCSFolder *aclsFolder;
+  NSString *objectPath, *currentUID;
+  NSEnumerator *userUIDs;
+
+  [self setOCSPath: [self _ocsPathForObject: object]];
+  aclsFolder = [self ocsFolder];
+
+  objectPath
+    = [NSString stringWithFormat: @"/%@",
+                [[object pathArrayToSoObject] componentsJoinedByString: @"/"]];
+  [self removeUsersWithRole: role
+        forObjectAtPath: objectPath
+        inFolder: aclsFolder];
+
+  userUIDs = [uids objectEnumerator];
+  currentUID = [userUIDs nextObject];
+  while (currentUID)
+    {
+      if ([currentUID length] > 0)
+        [self setRoleForObjectAtPath: objectPath
+              forUser: currentUID
+              to: role
+              inFolder: aclsFolder];
+      currentUID = [userUIDs nextObject];
+    }
+}
+
+@end
diff --git a/SoObjects/SOGo/SOGoAppointment.h b/SoObjects/SOGo/SOGoAppointment.h
deleted file mode 100644 (file)
index e432189..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#ifndef        __SOGoAppointment_H_
-#define        __SOGoAppointment_H_
-
-#import <Foundation/NSObject.h>
-#import <Foundation/NSDate.h>
-
-/*
-  SOGoAppointment
-  
-  Wrapper around the iCalendar content of appointments stored in the 
-  OGoContentStore.
-*/
-
-@class NSString, NSArray, NSCalendarDate, NGCalendarDateRange;
-@class iCalPerson, iCalEvent, iCalRecurrenceRule;
-
-@interface SOGoAppointment : NSObject <NSCopying>
-{
-  id        calendar;
-  iCalEvent *event;
-  id        participants;
-}
-
-- (id)initWithICalString:(NSString *)_iCal;
-
-- (void)setUid:(NSString *)_value;
-- (NSString *)uid;
-
-- (void)setSummary:(NSString *)_value;
-- (NSString *)summary;
-
-- (void)setLocation:(NSString *)_value;
-- (NSString *)location;
-- (BOOL)hasLocation;
-
-- (void)setComment:(NSString *)_value;
-- (NSString *)comment;
-- (BOOL)hasComment;
-
-- (void)setUserComment:(NSString *)_userComment;
-- (NSString *)userComment;
-
-- (void)setPriority:(NSString *)_value;
-- (NSString *)priority;
-- (BOOL)hasPriority;
-
-- (void)setCategories:(NSArray *)_value;
-- (NSArray *)categories;
-- (BOOL)hasCategories;
-
-- (void)setStatus:(NSString *)_value;
-- (NSString *)status;
-    
-- (void)setStartDate:(NSCalendarDate *)_date;
-- (NSCalendarDate *)startDate;
-
-- (void)setEndDate:(NSCalendarDate *)_date;
-- (NSCalendarDate *)endDate;
-- (BOOL)hasEndDate;
-
-- (BOOL)hasDuration;
-- (void)setDuration:(NSTimeInterval)_duration;
-- (NSTimeInterval)duration;
-
-- (void)setOrganizer:(iCalPerson *)_organizer;
-- (iCalPerson *)organizer;
-
-- (void)setAccessClass:(NSString *)_value;
-- (NSString *)accessClass;
-- (BOOL)isPublic;
-
-- (void)setTransparency:(NSString *)_value;
-- (NSString *)transparency;
-- (BOOL)isTransparent;
-
-- (void)setMethod:(NSString *)_method;
-- (NSString *)method;
-
-- (void)removeAllAttendees;
-- (void)addToAttendees:(iCalPerson *)_person;
-- (void)appendAttendees:(NSArray *)_persons;
-- (void)setAttendees:(NSArray *)_persons;
-- (NSArray *)attendees;
-
-/* attendees -> role != NON-PART */
-- (NSArray *)participants;
-/* attendees -> role == NON-PART */
-- (NSArray *)resources;
-
-/* simplified recurrence API */
-- (void)setRecurrenceRule:(iCalRecurrenceRule *)_rrule;
-- (iCalRecurrenceRule *)recurrenceRule;
-- (BOOL)hasRecurrenceRule;
-
-- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r;
-
-/* iCal generation */
-
-- (NSString *)iCalString;
-- (NSString *)vEventString;
-
-/* raw entity objects */
-
-- (id)calendar;
-- (id)event;
-
-/* checking */
-
-- (BOOL)isOrganizer:(id)_email;
-- (BOOL)isParticipant:(id)_email;
-
-/* searching */
-
-- (iCalPerson *)findParticipantWithEmail:(id)_email;
-
-/* actions */
-
-- (void)increaseSequence;
-- (void)cancelWithoutIncreasingSequence;
-- (void)cancelAndIncreaseSequence;
-    
-@end
-
-#endif /* __SOGoAppointment_H_ */
diff --git a/SoObjects/SOGo/SOGoAppointment.m b/SoObjects/SOGo/SOGoAppointment.m
deleted file mode 100644 (file)
index 6371086..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "SOGoAppointment.h"
-#include <SaxObjC/SaxObjC.h>
-#include <NGiCal/NGiCal.h>
-#include <EOControl/EOControl.h>
-#include "SOGoAppointmentICalRenderer.h"
-#include "common.h"
-
-@interface SOGoAppointment (PrivateAPI)
-- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons;
-@end
-
-@implementation SOGoAppointment
-
-static id<NSObject,SaxXMLReader> parser  = nil;
-static SaxObjectDecoder          *sax    = nil;
-static NGLogger                  *logger = nil;
-
-+ (void)initialize {
-  NGLoggerManager     *lm;
-  SaxXMLReaderFactory *factory;
-  static BOOL         didInit = NO;
-
-  if (didInit) return;
-  didInit = YES;
-
-  lm      = [NGLoggerManager defaultLoggerManager];
-  logger  = [lm loggerForClass:self];
-
-  factory = [SaxXMLReaderFactory standardXMLReaderFactory];
-  parser  = [[factory createXMLReaderForMimeType:@"text/calendar"]
-    retain];
-  if (parser == nil)
-    [logger fatalWithFormat:@"did not find a parser for text/calendar!"];
-  sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
-  if (sax == nil)
-    [logger fatalWithFormat:@"could not create the iCal SAX handler!"];
-  
-  [parser setContentHandler:sax];
-  [parser setErrorHandler:sax];
-}
-
-- (id)initWithICalRootObject:(id)_root {
-  if ((self = [super init])) {
-#if 0
-    [self logWithFormat:@"root is: %@", root];
-#endif
-    
-    if ([_root isKindOfClass:[iCalEvent class]]) {
-      self->event = [_root retain];
-    }
-    else if ([_root isKindOfClass:[NSDictionary class]]) {
-      /* multiple vevents in the calendar */
-      [self errorWithFormat:
-              @"(%s): tried to initialize with multiple records: %@",
-              __PRETTY_FUNCTION__, _root];
-      [self release];
-      return nil;
-    }
-    else {
-      self->calendar = [_root retain];
-      self->event    = [[[self->calendar events] lastObject] retain];
-    }
-  }
-  return self;
-}
-- (id)initWithICalString:(NSString *)_iCal {
-  id root;
-  
-  if ([_iCal length] == 0) {
-    [self errorWithFormat:@"tried to init SOGoAppointment without iCal"];
-    [self release];
-    return nil;
-  }
-  if (parser == nil || sax == nil) {
-    [self errorWithFormat:@"iCal parser not properly set up!"];
-    [self release];
-    return nil;
-  }
-
-  if ([_iCal length] > 0) {
-    [parser parseFromSource:_iCal];
-    root = [[sax rootObject] retain]; /* retain to keep it around */
-    [sax reset];
-  }
-  else
-    root = nil;
-
-  self = [self initWithICalRootObject:root];
-  [root release];
-  return self;
-}
-
-- (void)dealloc {
-  [self->calendar     release];
-  [self->event        release];
-  [self->participants release];
-  [super dealloc];
-}
-
-/* NSCopying */
-
-- (id)copyWithZone:(NSZone *)_zone {
-  SOGoAppointment *new;
-  
-  new = [[[self class] allocWithZone:_zone] init];
-  
-  new->calendar      = [self->calendar     copyWithZone:_zone];
-  new->event         = [self->event        copyWithZone:_zone];
-  new->participants  = [self->participants copyWithZone:_zone];
-
-  return new;
-}
-
-/* accessors */
-
-- (id)calendar {
-  return self->calendar;
-}
-
-- (id)event {
-  return self->event;
-}
-
-- (NSString *)iCalString {
-  return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer]
-                                            stringForAppointment:self];
-}
-- (NSString *)vEventString {
-  return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer]
-                                            vEventStringForAppointment:self];
-}
-
-/* forwarded methods */
-
-- (void)setUid:(NSString *)_value {
-  [self->event setUid:_value];
-}
-- (NSString *)uid {
-  return [self->event uid];
-}
-
-- (void)setSummary:(NSString *)_value {
-  [self->event setSummary:_value];
-}
-- (NSString *)summary {
-  return [self->event summary];
-}
-
-- (void)setLocation:(NSString *)_value {
-  [self->event setLocation:_value];
-}
-- (NSString *)location {
-  return [self->event location];
-}
-- (BOOL)hasLocation {
-  if (![[self location] isNotNull])
-    return NO;
-  return  [[self location] length] > 0 ? YES : NO;
-}
-
-- (void)setComment:(NSString *)_value {
-  if([_value length] == 0)
-    _value = nil;
-  [self->event setComment:_value];
-}
-- (NSString *)comment {
-  return [self->event comment];
-}
-- (BOOL)hasComment {
-  NSString *s = [self comment];
-  if(!s || [s length] == 0)
-    return NO;
-  return YES;
-}
-
-- (void)setUserComment:(NSString *)_userComment {
-  [self->event setUserComment:_userComment];
-}
-- (NSString *)userComment {
-  return [self->event userComment];
-}
-
-- (void)setPriority:(NSString *)_value {
-  [self->event setPriority:_value];
-}
-- (NSString *)priority {
-  return [self->event priority];
-}
-- (BOOL)hasPriority {
-  NSString *prio = [self priority];
-  NSRange r;
-  
-  if(!prio)
-    return NO;
-  
-  r = [prio rangeOfString:@";"];
-  if(r.length > 0) {
-    prio = [prio substringToIndex:r.location];
-  }
-  return [prio isEqualToString:@"0"] ? NO : YES;
-}
-
-- (void)setCategories:(NSArray *)_value {
-  NSString *catString;
-
-  if(!_value || [_value count] == 0) {
-    [self->event setCategories:nil];
-    return;
-  }
-  _value = [_value sortedArrayUsingSelector:@selector(compareAscending:)];
-  catString = [_value componentsJoinedByString:@","];
-  [self->event setCategories:catString];
-}
-- (NSArray *)categories {
-  NSString *catString;
-  NSArray *cats;
-  NSRange r;
-  
-  catString = [self->event categories];
-  if (![catString isNotNull])
-    return [NSArray array];
-  
-  r = [[catString stringValue] rangeOfString:@";"];
-  if(r.length > 0) {
-    catString = [catString substringToIndex:r.location];
-  }
-  cats = [catString componentsSeparatedByString:@","];
-  return cats;
-}
-- (BOOL)hasCategories {
-  return [self->event categories] != nil ? YES : NO;
-}
-
-- (void)setStatus:(NSString *)_value {
-  [self->event setStatus:_value];
-}
-- (NSString *)status {
-  return [self->event status];
-}
-
-- (void)setStartDate:(NSCalendarDate *)_date {
-  [self->event setStartDate:_date];
-}
-- (NSCalendarDate *)startDate {
-  return [self->event startDate];
-}
-
-- (void)setEndDate:(NSCalendarDate *)_date {
-  [self->event setEndDate:_date];
-}
-- (NSCalendarDate *)endDate {
-  return [self->event endDate];
-}
-- (BOOL)hasEndDate {
-  return [self->event hasEndDate];
-}
-
-- (void)setDuration:(NSTimeInterval)_duration {
-  // TODO
-  [self warnWithFormat:@"could not apply duration!"];
-}
-- (BOOL)hasDuration {
-  return [self->event hasDuration];
-}
-- (NSTimeInterval)duration {
-  return [self->event durationAsTimeInterval];
-}
-
-- (void)setAccessClass:(NSString *)_value {
-  [self->event setAccessClass:_value];
-}
-- (NSString *)accessClass {
-  NSString *s;
-  
-  s = [self->event accessClass];
-  if(!s)
-    s = @"PUBLIC"; /* default for agenor */
-  return s;
-}
-- (BOOL)isPublic {
-  return [[self accessClass] isEqualToString:@"PUBLIC"];
-}
-
-- (void)setTransparency:(NSString *)_value {
-  [self->event setTransparency:_value];
-}
-- (NSString *)transparency {
-  return [self->event transparency];
-}
-- (BOOL)isTransparent {
-  return [[self transparency] isEqualToString:@"TRANSPARENT"];
-}
-
-- (void)setMethod:(NSString *)_method {
-  [self->calendar setMethod:_method];
-}
-- (NSString *)method {
-  return [self->calendar method];
-}
-
-- (void)setOrganizer:(iCalPerson *)_organizer {
-  [self->event setOrganizer:_organizer];
-}
-- (iCalPerson *)organizer {
-  return [self->event organizer];
-}
-
-- (void)removeAllAttendees {
-  [self setAttendees:nil];
-}
-- (void)addToAttendees:(iCalPerson *)_person {
-  [self->event addToAttendees:_person];
-}
-- (void)appendAttendees:(NSArray *)_persons {
-  unsigned i, count;
-  
-  count = [_persons count];
-  for (i = 0; i < count; i++)
-    [self addToAttendees:[_persons objectAtIndex:i]];
-}
-- (void)setAttendees:(NSArray *)_persons {
-  [self->event removeAllAttendees];
-  if ([_persons count] > 0) 
-    [self appendAttendees:_persons];
-}
-- (NSArray *)attendees {
-  return [self->event attendees];
-}
-
-- (NSArray *)participants {
-  if (self->participants != nil)
-    return self->participants;
-  
-  self->participants = [[self _filteredAttendeesThinkingOfPersons:YES] retain];
-  return self->participants;
-}
-- (BOOL)hasParticipants {
-  return [[self participants] count] != 0;
-}
-
-- (NSArray *)resources {
-  return [self _filteredAttendeesThinkingOfPersons:NO];
-}
-
-- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons {
-  NSArray        *list;
-  NSMutableArray *filtered;
-  unsigned       i, count;
-
-  list     = [self attendees];
-  count    = [list count];
-  filtered = [NSMutableArray arrayWithCapacity:count];
-  for (i = 0; i < count; i++) {
-    iCalPerson *p;
-    NSString   *role;
-    
-    p = [list objectAtIndex:i];
-    role = [p role];
-    if (_persons) {
-      if (role == nil || ![role hasPrefix:@"NON-PART"])
-       [filtered addObject:p];
-    }
-    else {
-      if ([role hasPrefix:@"NON-PART"])
-       [filtered addObject:p];
-    }
-  }
-  return filtered;
-}
-
-- (BOOL)isOrganizer:(id)_email {
-  return [[[self organizer] rfc822Email] isEqualToString:_email];
-}
-
-- (BOOL)isParticipant:(id)_email {
-  NSArray *partEmails;
-  
-  _email     = [_email lowercaseString];
-  partEmails = [[self participants] valueForKey:@"rfc822Email"];
-  partEmails = [partEmails valueForKey:@"lowercaseString"];
-  return [partEmails containsObject:_email];
-}
-
-- (iCalPerson *)findParticipantWithEmail:(id)_email {
-  NSArray  *ps;
-  unsigned i, count;
-  
-  _email = [_email lowercaseString];
-  ps     = [self participants];
-  count  = [ps count];
-  
-  for (i = 0; i < count; i++) {
-    iCalPerson *p;
-    
-    p = [ps objectAtIndex:i];
-    if ([[[p rfc822Email] lowercaseString] isEqualToString:_email])
-      return p;
-  }
-  return nil; /* not found */
-}
-
-
-/*
- NOTE: this is not the same API as used by NGiCal!
- SOGo/OGo cannot deal with the complete NGiCal API properly, although
- SOGo COULD do so in the future
-*/
-- (void)setRecurrenceRule:(iCalRecurrenceRule *)_rrule {
-  [_rrule retain];
-  [self->event removeAllRecurrenceRules];
-  if (_rrule)
-    [self->event addToRecurrenceRules:_rrule];
-  [_rrule release];
-}
-- (iCalRecurrenceRule *)recurrenceRule {
-  if ([self->event hasRecurrenceRules])
-    return [[self->event recurrenceRules] objectAtIndex:0];
-  return nil;
-}
-- (BOOL)hasRecurrenceRule {
-  return [self recurrenceRule] != nil;
-}
-
-- (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r {
-  return [self->event recurrenceRangesWithinCalendarDateRange:_r];
-}
-
-/* actions */
-
-- (void)increaseSequence {
-  [self->event increaseSequence];
-}
-
-- (void)cancelWithoutIncreasingSequence {
-  [self setMethod:@"CANCEL"];
-}
-- (void)cancelAndIncreaseSequence {
-  [self cancelWithoutIncreasingSequence];
-  [self increaseSequence];
-}
-
-/* description */
-
-- (void)appendAttributesToDescription:(NSMutableString *)_ms {
-  [_ms appendFormat:@" uid=%@",  [self uid]];
-  [_ms appendFormat:@" date=%@", [self startDate]];
-}
-
-- (NSString *)description {
-  NSMutableString *ms;
-
-  ms = [NSMutableString stringWithCapacity:64];
-  [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
-  [self appendAttributesToDescription:ms];
-  [ms appendString:@">"];
-  return ms;
-}
-
-/* logging */
-
-- (id)logger {
-  return logger;
-}
-
-@end /* SOGoAppointment */
diff --git a/SoObjects/SOGo/SOGoAppointmentICalRenderer.h b/SoObjects/SOGo/SOGoAppointmentICalRenderer.h
deleted file mode 100644 (file)
index afdd2e6..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: SOGoAppointment.h 207 2004-08-14 15:37:04Z znek $
-
-#ifndef        __SOGoAppointmentICalRenderer_H_
-#define        __SOGoAppointmentICalRenderer_H_
-
-#import <Foundation/NSObject.h>
-
-/*
-  SOGoAppointmentICalRenderer
-
-  Transform an SOGoAppointment into an iCalendar formatted string.
-*/
-
-@class NSString;
-@class SOGoAppointment;
-
-@interface SOGoAppointmentICalRenderer : NSObject
-
-+ (id)sharedAppointmentRenderer;
-
-- (NSString *)vEventStringForAppointment:(SOGoAppointment *)_apt;
-- (NSString *)stringForAppointment:(SOGoAppointment *)_apt;
-
-@end
-
-#endif /* __SOGoAppointmentICalRenderer_H_ */
diff --git a/SoObjects/SOGo/SOGoAppointmentICalRenderer.m b/SoObjects/SOGo/SOGoAppointmentICalRenderer.m
deleted file mode 100644 (file)
index 4c737f5..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "SOGoAppointmentICalRenderer.h"
-#include "SOGoAppointment.h"
-#include <NGiCal/NGiCal.h>
-#include <NGiCal/iCalRenderer.h>
-#include "common.h"
-
-// TODO: the basic renderer should be part of NGiCal
-
-@interface NSDate(UsedPrivates)
-- (NSString *)icalString; // declared in NGiCal
-@end
-
-@implementation SOGoAppointmentICalRenderer
-
-static SOGoAppointmentICalRenderer *renderer = nil;
-
-/* assume length of 1K - reasonable ? */
-static unsigned DefaultICalStringCapacity = 1024;
-
-+ (id)sharedAppointmentRenderer {
-  if (renderer == nil)
-    renderer = [[self alloc] init];
-  return renderer;
-}
-
-/* renderer */
-
-- (void)addPreambleForAppointment:(SOGoAppointment *)_apt
-  toString:(NSMutableString *)s
-{
-  iCalCalendar *calendar;
-  NSString     *x;
-
-  calendar = [_apt calendar];
-  
-  [s appendString:@"BEGIN:VCALENDAR\r\n"];
-  [s appendString:@"METHOD:"];
-  if((x = [calendar method]))
-    [s appendString:[x iCalSafeString]];
-  else
-    [s appendString:@"REQUEST"];
-  [s appendString:@"\r\n"];
-  
-  [s appendString:@"PRODID:"];
-  [s appendString:[calendar isNotNull] ? [calendar prodId] : @"SOGo/0.9"];
-  [s appendString:@"\r\n"];
-  
-  [s appendString:@"VERSION:"];
-  [s appendString:[calendar isNotNull] ? [calendar version] : @"2.0"];
-  [s appendString:@"\r\n"];
-}
-- (void)addPostambleForAppointment:(SOGoAppointment *)_apt
-  toString:(NSMutableString *)s
-{
-  [s appendString:@"END:VCALENDAR\r\n"];
-}
-
-- (void)addOrganizer:(iCalPerson *)p toString:(NSMutableString *)s {
-  NSString *x;
-
-  if (![p isNotNull]) return;
-  
-  [s appendString:@"ORGANIZER;CN=\""];
-  if ((x = [p cn]))
-    [s appendString:[x iCalDQUOTESafeString]];
-  
-  [s appendString:@"\""];
-  if ((x = [p email])) {
-    [s appendString:@":"]; /* sic! */
-    [s appendString:[x iCalSafeString]];
-  }
-  [s appendString:@"\r\n"];
-}
-
-- (void)addAttendees:(NSArray *)persons toString:(NSMutableString *)s {
-  unsigned   i, count;
-  iCalPerson *p;
-
-  count   = [persons count];
-  for (i = 0; i < count; i++) {
-    NSString *x;
-    
-    p = [persons objectAtIndex:i];
-    [s appendString:@"ATTENDEE;"];
-    
-    if ((x = [p role])) {
-      [s appendString:@"ROLE="];
-      [s appendString:[x iCalSafeString]];
-      [s appendString:@";"];
-    }
-    
-    if ((x = [p partStat])) {
-      if ([p participationStatus] != iCalPersonPartStatNeedsAction) {
-        [s appendString:@"PARTSTAT="];
-        [s appendString:[x iCalSafeString]];
-        [s appendString:@";"];
-      }
-    }
-
-    [s appendString:@"CN=\""];
-    if ((x = [p cnWithoutQuotes])) {
-      [s appendString:[x iCalDQUOTESafeString]];
-    }
-    [s appendString:@"\""];
-    if ([(x = [p email]) isNotNull]) {
-      [s appendString:@":"]; /* sic! */
-      [s appendString:[x iCalSafeString]];
-    }
-    [s appendString:@"\r\n"];
-  }
-}
-
-- (void)addVEventForAppointment:(SOGoAppointment *)_apt 
-  toString:(NSMutableString *)s
-{
-  iCalEvent *event;
-
-  event = [_apt event];
-  
-  [s appendString:@"BEGIN:VEVENT\r\n"];
-  
-  [s appendString:@"SUMMARY:"];
-  [s appendString:[[_apt summary] iCalSafeString]];
-  [s appendString:@"\r\n"];
-  if ([_apt hasLocation]) {
-    [s appendString:@"LOCATION:"];
-    [s appendString:[[_apt location] iCalSafeString]];
-    [s appendString:@"\r\n"];
-  }
-  [s appendString:@"UID:"];
-  [s appendString:[_apt uid]];
-  [s appendString:@"\r\n"];
-  
-  [s appendString:@"DTSTART:"];
-  [s appendString:[[_apt startDate] icalString]];
-  [s appendString:@"\r\n"];
-  
-  if ([_apt hasEndDate]) {
-    [s appendString:@"DTEND:"];
-    [s appendString:[[_apt endDate] icalString]];
-    [s appendString:@"\r\n"];
-  }
-  if ([_apt hasDuration]) {
-    [s appendString:@"DURATION:"];
-    [s appendString:[event duration]];
-    [s appendString:@"\r\n"];
-  }
-  if([_apt hasPriority]) {
-    [s appendString:@"PRIORITY:"];
-    [s appendString:[_apt priority]];
-    [s appendString:@"\r\n"];
-  }
-  if([_apt hasCategories]) {
-    NSString *catString;
-
-    catString = [[_apt categories] componentsJoinedByString:@","];
-    [s appendString:@"CATEGORIES:"];
-    [s appendString:catString];
-    [s appendString:@"\r\n"];
-  }
-  if([_apt hasComment]) {
-    [s appendString:@"DESCRIPTION:"]; /* this is what iCal.app does */
-    [s appendString:[[_apt comment] iCalSafeString]];
-    [s appendString:@"\r\n"];
-  }
-
-  [s appendString:@"STATUS:"];
-  [s appendString:[_apt status]];
-  [s appendString:@"\r\n"];
-
-  [s appendString:@"TRANSP:"];
-  [s appendString:[_apt transparency]];
-  [s appendString:@"\r\n"];
-
-  [s appendString:@"CLASS:"];
-  [s appendString:[_apt accessClass]];
-  [s appendString:@"\r\n"];
-  
-  /* recurrence rules */
-  if ([_apt hasRecurrenceRule]) {
-    [s appendString:@"RRULE:"];
-    [s appendString:[[_apt recurrenceRule] iCalRepresentation]];
-    [s appendString:@"\r\n"];
-  }
-
-  [self addOrganizer:[_apt organizer] toString:s];
-  [self addAttendees:[_apt attendees] toString:s];
-  
-  /* postamble */
-  [s appendString:@"END:VEVENT\r\n"];
-}
-
-- (BOOL)isValidAppointment:(SOGoAppointment *)_apt {
-  if (![_apt isNotNull])
-    return NO;
-  
-  if ([[_apt uid] length] == 0) {
-    [self warnWithFormat:@"got apt without uid, rejecting iCal generation: %@", 
-            _apt];
-    return NO;
-  }
-  if ([[[_apt startDate] icalString] length] == 0) {
-    [self warnWithFormat:@"got apt without start date, "
-            @"rejecting iCal generation: %@",
-            _apt];
-    return NO;
-  }
-  
-  return YES;
-}
-
-- (NSString *)vEventStringForAppointment:(SOGoAppointment *)_apt {
-  NSMutableString *s;
-  
-  if (![self isValidAppointment:_apt])
-    return nil;
-  
-  s = [NSMutableString stringWithCapacity:DefaultICalStringCapacity];
-  [self addVEventForAppointment:_apt toString:s];
-  return s;
-}
-
-- (NSString *)stringForAppointment:(SOGoAppointment *)_apt {
-  NSMutableString *s;
-  
-  if (![self isValidAppointment:_apt])
-    return nil;
-  
-  s = [NSMutableString stringWithCapacity:DefaultICalStringCapacity];
-  [self addPreambleForAppointment:_apt  toString:s];
-  [self addVEventForAppointment:_apt    toString:s];
-  [self addPostambleForAppointment:_apt toString:s];
-  return s;
-}
-
-@end /* SOGoAppointmentICalRenderer */
index f49e7c56294c0a7f158f8c62113953cea1197301..1a5549e53fb9f5bcb03071decc9e72b64008d4a4 100644 (file)
   the password is already checked in Apache.
 */
 
+@class NSUserDefaults;
+@class NSString;
+
 @interface SOGoAuthenticator : SoHTTPAuthenticator
 {
+  NSUserDefaults *ud;
+  NSString *authMethod;
+  NSString *LDAPBaseDN;
+  NSString *LDAPHost;
+  int LDAPPort;
 }
 
-+ (id)sharedSOGoAuthenticator;
++ (id) sharedSOGoAuthenticator;
+
+- (BOOL) LDAPCheckLogin: (NSString *) _login password: (NSString *) _pwd;
 
 @end
 
index bb1b7a2a9bbe33f40a588b95e26f69cab7e7e6f4..00205e6fd373242f8f45ea87ded6f94850b41672 100644 (file)
   02111-1307, USA.
 */
 
+#import <NGLdap/NGLdapConnection.h>
+#import "SOGoPermissions.h"
+
 #include "SOGoAuthenticator.h"
 #include "SOGoUser.h"
 #include "common.h"
 
 @implementation SOGoAuthenticator
 
-static SOGoAuthenticator *auth = nil; // THREAD
+static SOGoAuthenticator *auth = nil;
 
-+ (id)sharedSOGoAuthenticator {
++ (id) sharedSOGoAuthenticator
+{
   if (auth == nil)
     auth = [[self alloc] init];
   return auth;
 }
 
-/* check credentials */
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      ud = [NSUserDefaults standardUserDefaults];
 
-- (BOOL)checkLogin:(NSString *)_login password:(NSString *)_pwd {
-  if ([_login length] == 0)
-    return NO;
-  
-  /* we accept any password since it is checked by Apache in front */
-  return YES;
+      LDAPBaseDN = nil;
+      LDAPHost = nil;
+      LDAPPort = -1;
+
+      authMethod = [[ud stringForKey:@"AuthentificationMethod"] retain];
+      if ([authMethod isEqualToString: @"LDAP"])
+       {
+         LDAPBaseDN = [[ud stringForKey:@"LDAPRootDN"] retain];
+         LDAPHost = [[ud stringForKey:@"LDAPHost"] retain];
+         LDAPPort = [ud integerForKey:@"LDAPPort"];
+       }
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (LDAPBaseDN)
+    [LDAPBaseDN release];
+  if (LDAPHost)
+    [LDAPHost release];
+  [authMethod release];
+  [super dealloc];
+}
+
+- (BOOL) checkLogin: (NSString *) _login
+          password: (NSString *) _pwd
+{
+  BOOL result;
+
+//   return YES;
+  if ([authMethod isEqualToString: @"LDAP"])
+    result = [self LDAPCheckLogin: _login password: _pwd];
+  else
+    {
+      if ([_login length] == 0)
+       result = NO;
+      else
+       result = YES;
+    }
+
+  return result;
+}
+
+- (BOOL) LDAPCheckLogin: (NSString *) _login
+              password: (NSString *) _pwd
+{
+  return [NGLdapConnection checkPassword: _pwd
+                          ofLogin: _login
+                          atBaseDN: LDAPBaseDN
+                          onHost: LDAPHost
+                          port: LDAPPort];
 }
 
 /* create SOGoUser */
 
-- (SoUser *)userInContext:(WOContext *)_ctx {
-  static SoUser *anonymous = nil;
+- (SoUser *) userInContext:(WOContext *)_ctx
+{
+  static SoUser *anonymous = nil, *freebusy;
   NSString  *login;
-  NSArray   *uroles;
-  
-  if (anonymous == nil) {
-    NSArray *ar = [NSArray arrayWithObject:SoRole_Anonymous];
-    anonymous = [[SOGoUser alloc] initWithLogin:@"anonymous" roles:ar];
-  }
   
+  if (!anonymous)
+    anonymous
+      = [[SOGoUser alloc] initWithLogin:@"anonymous"
+                         roles: [NSArray arrayWithObject: SoRole_Anonymous]];
+
+  if (!freebusy)
+    freebusy
+      = [[SOGoUser alloc] initWithLogin: @"freebusy"
+                          roles: [NSArray arrayWithObject: SOGoRole_FreeBusy]];
+
   if ((login = [self checkCredentialsInContext:_ctx]) == nil)
     /* some error (otherwise result would have been anonymous */
     return nil;
   
-  if ([login isEqualToString:@"anonymous"])
+  if ([login isEqualToString: @"anonymous"])
     return anonymous;
-  
-  uroles = [self rolesForLogin:login];
-  return [[[SOGoUser alloc] initWithLogin:login roles:uroles] autorelease];
+  else if ([login isEqualToString: @"freebusy"])
+    return freebusy;
+
+//   uroles = [NSMutableArray arrayWithArray: ];
+
+  return [[[SOGoUser alloc] initWithLogin: login
+                            roles: [self rolesForLogin: login]]
+          autorelease];
 }
 
+// - (BOOL) renderException: (NSException *) exception
+//                inContext: (WOContext *) context
+// {
+//   id renderedException;
+//   WOComponent *tmpComponent;
+//   WOResponse *response;
+//   BOOL rc;
+
+//   rc = [super renderException: exception inContext: context];
+//   if (!rc)
+//     {
+//       tmpComponent = [WOComponent new];
+//       renderedException = [tmpComponent pageWithName: @"UIxException"];
+//       if (renderedException)
+//         {
+//           rc = YES;
+//           response = [context response];
+//           [response setHeader: @"text/html" forKey: @"content-type"];
+//           [renderedException setClientObject: exception];
+//           [context setPage: renderedException];
+//           [renderedException appendToResponse: response
+//                              inContext: context];
+//         }
+//       [tmpComponent release];
+//     }
+
+//   return rc;
+// }
+
 @end /* SOGoAuthenticator */
index f4c2efe0ff4e233f2d4e2dcafca7a5adb396677c..5c22cda92f0a973d2969e2588f1493d32af01dc6 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef __SOGo_SOGoContentObject_H__
 #define __SOGo_SOGoContentObject_H__
 
-#include <SOGo/SOGoObject.h>
+#import <SOGo/SOGoObject.h>
 
 @class NSString, NSException;
 
index 2f3b6ad1ca4d5bcc686b3f33a26211bd8323d587..3e39df8d69316e8c5a4eb0dd1351eb58d333f249 100644 (file)
@@ -42,7 +42,7 @@ static NSString *SOGoUIDSeparator = @",";
 /* accessors */
 
 - (NSArray *)unescapeURLComponents:(NSArray *)_parts {
-#warning TODO: implement URL UID unescaping if necessary
+// #warning TODO: implement URL UID unescaping if necessary
   // TODO: who calls this for what?
   // Note: remember URL encoding!
   return _parts;
diff --git a/SoObjects/SOGo/SOGoDAVRendererTypes.h b/SoObjects/SOGo/SOGoDAVRendererTypes.h
new file mode 100644 (file)
index 0000000..8a4b927
--- /dev/null
@@ -0,0 +1,45 @@
+/* SOGoDAVRendererTypes.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGODAVRENDERERTYPES_H
+#define SOGODAVRENDERERTYPES_H
+
+#import <NGObjWeb/SoWebDAVValue.h>
+
+@class NSArray;
+@class NSString;
+
+@interface SOGoDAVSet : SoWebDAVValue
+{
+  NSString *valueTag;
+  NSArray *values;
+}
+
++ (id) davSetWithArray: (NSArray *) newValues
+      ofValuesTaggedAs: (NSString *) newValueTag;
+
+- (void) setValueTag: (NSString *) newValueTag;
+- (void) setValues: (NSArray *) newValues;
+  
+@end
+
+#endif /* SOGODAVRENDERERTYPES_H */
diff --git a/SoObjects/SOGo/SOGoDAVRendererTypes.m b/SoObjects/SOGo/SOGoDAVRendererTypes.m
new file mode 100644 (file)
index 0000000..21a102c
--- /dev/null
@@ -0,0 +1,114 @@
+/* SOGoDAVRendererTypes.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSEnumerator.h>
+#import <Foundation/NSString.h>
+
+#import "SOGoDAVRendererTypes.h"
+
+@implementation SOGoDAVSet
+
++ (id) davSetWithArray: (NSArray *) newValues
+      ofValuesTaggedAs: (NSString *) newValueTag
+{
+  id davSet;
+
+  davSet = [self new];
+  [davSet setValueTag: newValueTag];
+  [davSet setValues: newValues];
+  [davSet autorelease];
+
+  return davSet;
+}
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      valueTag = nil;
+      values = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (valueTag)
+    [valueTag release];
+  if (values)
+    [values release];
+  [super dealloc];
+}
+
+- (void) setValueTag: (NSString *) newValueTag
+{
+  ASSIGN (valueTag, newValueTag);
+}
+
+- (void) setValues: (NSArray *) newValues
+{
+  ASSIGN (values, newValues);
+}
+
+- (NSString *) stringForTag: (NSString *) _key
+                    rawName: (NSString *) setTag
+                  inContext: (id) context
+                   prefixes: (NSDictionary *) prefixes
+{
+  NSMutableString *resultString;
+  id currentValue;
+  NSString *valueString;
+  NSEnumerator *valueEnum;
+
+  resultString = [NSMutableString new];
+  [resultString autorelease];
+
+  [resultString appendFormat: @"<%@>", setTag];
+  valueEnum = [values objectEnumerator];
+  currentValue = [valueEnum nextObject];
+  while (currentValue)
+    {
+      if ([currentValue isKindOfClass: [SoWebDAVValue class]])
+        valueString
+          = [currentValue stringForTag:
+                            [NSString stringWithFormat: @"{DAV:}%@", valueTag]
+                          rawName: [NSString stringWithFormat: @"D:%@", valueTag]
+                          inContext: context
+                          prefixes: prefixes];
+      else
+        valueString = currentValue;
+
+      [resultString appendFormat: @"<%@>%@</%@>",
+                    valueTag, valueString, valueTag];
+      currentValue = [valueEnum nextObject];
+    }
+  [resultString appendFormat: @"</%@>", setTag];
+
+  NSLog(@"dav rendering for key '%@' and tag '%@':\n", _key, setTag,
+        resultString);
+
+  return resultString;
+}
+
+@end
index 3e79b2b668509a573d3c10b7d19dcceedbd893ac..b4a6b92bd9789bb2bd8d886d983371e0244ecdfd 100644 (file)
 #ifndef __SOGo_SOGoFolder_H__
 #define __SOGo_SOGoFolder_H__
 
-#include <SOGo/SOGoObject.h>
+#import "SOGoObject.h"
 
 @class NSString, NSArray, NSDictionary;
 @class GCSFolder;
+@class SOGoAclsFolder;
 
 /*
   SOGoFolder
@@ -54,7 +55,6 @@
 - (GCSFolder *)ocsFolder;
 
 /* lower level fetches */
-
 - (NSArray *)fetchContentObjectNames;
 - (NSDictionary *)fetchContentStringsAndNamesOfAllObjects;
 
 
 @end
 
+@interface SOGoFolder (GroupDAVExtensions)
+
+- (NSString *) groupDavResourceType;
+
+@end
+
 #endif /* __SOGo_SOGoFolder_H__ */
index ee96bf3b8e9e8eaf6778a050308bdfdf9611b53d..d60a898150f3da079f7e1e3f5a44a9a89a48102d 100644 (file)
@@ -19,6 +19,8 @@
   02111-1307, USA.
 */
 
+#import <NGObjWeb/SoObject.h>
+
 #include "SOGoFolder.h"
 #include "common.h"
 #include <GDLContentStore/GCSFolderManager.h>
@@ -26,6 +28,8 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+#import "SOGoAclsFolder.h"
+
 @implementation SOGoFolder
 
 + (int)version {
 - (GCSFolderManager *)folderManager {
   return [GCSFolderManager defaultFolderManager];
 }
+
 - (GCSFolder *)ocsFolderForPath:(NSString *)_path {
   return [[self folderManager] folderAtPath:_path];
 }
-- (GCSFolder *)ocsFolder {
-  if (self->ocsFolder != nil)
-    return [self->ocsFolder isNotNull] ? self->ocsFolder : nil;
-  
-  self->ocsFolder = [[self ocsFolderForPath:[self ocsPath]] retain];
-  return self->ocsFolder;
+
+- (GCSFolder *) ocsFolder {
+  GCSFolder *folder;
+
+  if (!ocsFolder)
+    ocsFolder = [[self ocsFolderForPath:[self ocsPath]] retain];
+
+  if ([ocsFolder isNotNull])
+    folder = ocsFolder;
+  else
+    folder = nil;
+
+  return folder;
 }
 
 - (NSArray *)fetchContentObjectNames {
     return records;
   return [records valueForKey:@"c_name"];
 }
+
 - (NSDictionary *)fetchContentStringsAndNamesOfAllObjects {
   NSDictionary *files;
   
   return nil;
 }
 
-- (NSArray *)toOneRelationshipKeys {
+- (NSArray *) davResourceType
+{
+  NSArray *rType, *groupDavCollection;
+
+  if ([self respondsToSelector: @selector (groupDavResourceType)])
+    {
+      groupDavCollection = [NSArray arrayWithObjects: [self groupDavResourceType],
+                                    @"http://groupdav.org/", @"G", nil];
+      rType = [NSArray arrayWithObjects: @"collection", groupDavCollection, nil];
+    }
+  else
+    rType = [NSArray arrayWithObject: @"collection"];
+
+  return rType;
+}
+
+- (NSArray *) toOneRelationshipKeys {
   /* toOneRelationshipKeys are the 'files' contained in a folder */
   NSMutableArray *ma;
   NSArray  *names;
-  NSString *ext;
+  NSString *name, *ext;
   unsigned i, count;
-
-  if ((names = [self fetchContentObjectNames]) == nil)
-    return names;
-  
-  if ((count = [names count]) == 0)
-    return names;
-  
-  if ((ext = [self defaultFilenameExtension]) == nil)
-    return names;
-  
-  ma = [NSMutableArray arrayWithCapacity:count];
-  for (i = 0; i < count; i++) {
-    NSRange  r;
-    NSString *name;
-    
-    name = [names objectAtIndex:i];
-    r = [name rangeOfString:@"."];
-    if (r.length == 0)
-      name = [[name stringByAppendingString:@"."] stringByAppendingString:ext];
-    
-    [ma addObject:name];
-  }
-  return ma;
+  NSRange  r;
+
+  names = [self fetchContentObjectNames];
+  count = [names count];
+  ext = [self defaultFilenameExtension];
+  if (count && [ext length] > 0)
+    {
+      ma = [NSMutableArray arrayWithCapacity: count];
+      for (i = 0; i < count; i++)
+        {
+          name = [names objectAtIndex: i];
+          r = [name rangeOfString: @"."];
+          if (r.length == 0)
+            name = [[name stringByAppendingString:@"."] stringByAppendingString: ext];
+          [ma addObject:name];
+        }
+
+      names = ma;
+    }
+
+  return names;
 }
 
 /* WebDAV */
index f04ad5732e8c7c8fa25ab6957d41b94d7cac6a4b..892afff94fb13cb6f72ccb3efc6456564ff19913 100644 (file)
   lookup.
 */
 
-@class NSString, NSArray, NSMutableString, NSException;
+@class NSString, NSArray, NSMutableString, NSException, NSTimeZone;
 @class GCSFolderManager, GCSFolder;
 @class SOGoUserFolder, SOGoGroupsFolder;
+@class WOContext;
+@class SOGoDAVSet;
+
+#define $(class) NSClassFromString(class)
 
 @interface SOGoObject : NSObject
 {
   NSString *nameInContainer;
   id       container;
+  NSTimeZone *userTimeZone;
+  NSString *customOwner;
 }
 
++ (id) objectWithName: (NSString *)_name inContainer:(id)_container;
+
 - (id)initWithName:(NSString *)_name inContainer:(id)_container;
 
 /* accessors */
 - (NSString *)nameInContainer;
 - (id)container;
 
+- (NSTimeZone *) serverTimeZone;
+- (NSTimeZone *) userTimeZone;
+- (NSTimeZone *) userTimeZone: (NSString *) username;
+
 /* ownership */
 
+- (void) setOwner: (NSString *) newOwner;
 - (NSString *)ownerInContext:(id)_ctx;
 
 /* looking up shared objects */
@@ -71,6 +84,8 @@
 - (NSException *)delete;
 - (id)GETAction:(id)_ctx;
 
+- (SOGoDAVSet *) davCurrentUserPrivilegeSet;
+
 /* etag support */
 
 - (NSException *)matchesRequestConditionInContext:(id)_ctx;
index 9863d36ff2df5ba3dcfcfc360b6d2d59d0631b4d..ca66dff60de995d7e18f7031636e70d338aec26b 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoObject.h"
-#include "SOGoUserFolder.h"
-#include <NGObjWeb/WEClientCapabilities.h>
-#include <NGObjWeb/SoObject+SoDAV.h>
-#include "common.h"
+#import <NGObjWeb/WEClientCapabilities.h>
+#import <NGObjWeb/SoObject+SoDAV.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/WOApplication.h>
+#import <NGCards/NSDictionary+NGCards.h>
+#import "common.h"
+
+#import "NSArray+Utilities.h"
+#import "NSString+Utilities.h"
+
+#import "SOGoPermissions.h"
+#import "SOGoUser.h"
+#import "SOGoAclsFolder.h"
+#import "SOGoAuthenticator.h"
+#import "SOGoUserFolder.h"
+
+#import "SOGoDAVRendererTypes.h"
+#import "AgenorUserManager.h"
+
+#import "SOGoObject.h"
 
 @interface SOGoObject(Content)
 - (NSString *)contentAsString;
 @end
 
+@interface SoClassSecurityInfo (SOGoAcls)
+
++ (id) defaultWebDAVPermissionsMap;
+
+- (NSArray *) allPermissions;
+- (NSArray *) allDAVPermissions;
+- (NSArray *) DAVPermissionsForRole: (NSString *) role;
+- (NSArray *) DAVPermissionsForRoles: (NSArray *) roles;
+
+@end
+
+@implementation SoClassSecurityInfo (SOGoAcls)
+
++ (id) defaultWebDAVPermissionsMap
+{
+  return [NSDictionary dictionaryWithObjectsAndKeys:
+                         @"read", SoPerm_AccessContentsInformation,
+                       @"read", SoPerm_View, 
+                       @"bind", SoPerm_AddDocumentsImagesAndFiles,
+                       @"unbind", SoPerm_DeleteObjects,
+                       @"write-acl", SoPerm_ChangePermissions,
+                       @"write-content", SoPerm_ChangeImagesAndFiles,
+                       @"read-free-busy", SOGoPerm_FreeBusyLookup,
+                       NULL];
+}
+
+- (NSArray *) allPermissions
+{
+  return [defRoles allKeys];
+}
+
+- (NSArray *) allDAVPermissions
+{
+  NSEnumerator *allPermissions;
+  NSMutableArray *davPermissions;
+  NSDictionary *davPermissionsMap;
+  NSString *sopePermission, *davPermission;
+
+  davPermissions = [NSMutableArray array];
+
+  davPermissionsMap = [[self class] defaultWebDAVPermissionsMap];
+  allPermissions = [[self allPermissions] objectEnumerator];
+  sopePermission = [allPermissions nextObject];
+  while (sopePermission)
+    {
+      davPermission = [davPermissionsMap objectForCaseInsensitiveKey: sopePermission];
+      if (davPermission && ![davPermissions containsObject: davPermission])
+        [davPermissions addObject: davPermission];
+      sopePermission = [allPermissions nextObject];
+    }
+
+  return davPermissions;
+}
+- (NSArray *) DAVPermissionsForRole: (NSString *) role
+{
+  return [self DAVPermissionsForRoles: [NSArray arrayWithObject: role]];
+}
+
+- (NSArray *) DAVPermissionsForRoles: (NSArray *) roles
+{
+  NSEnumerator *allPermissions;
+  NSMutableArray *davPermissions;
+  NSDictionary *davPermissionsMap;
+  NSString *sopePermission, *davPermission;
+
+  davPermissions = [NSMutableArray array];
+
+  davPermissionsMap = [[self class] defaultWebDAVPermissionsMap];
+  allPermissions = [[self allPermissions] objectEnumerator];
+  sopePermission = [allPermissions nextObject];
+  while (sopePermission)
+    {
+      if ([[defRoles objectForCaseInsensitiveKey: sopePermission]
+            firstObjectCommonWithArray: roles])
+        {
+          davPermission
+            = [davPermissionsMap objectForCaseInsensitiveKey: sopePermission];
+          if (davPermission
+              && ![davPermissions containsObject: davPermission])
+            [davPermissions addObject: davPermission];
+        }
+      sopePermission = [allPermissions nextObject];
+    }
+
+  return davPermissions;
+}
+
+@end
+
 @implementation SOGoObject
 
 static BOOL kontactGroupDAV = YES;
+static NSTimeZone *serverTimeZone = nil;
 
 + (int)version {
   return 0;
 }
 
-+ (void)initialize {
++ (void) initialize
+{
+  NSString *tzName;
+
   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
-  
+
   kontactGroupDAV = 
     [ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"] ? NO : YES;
 
   /* SoClass security declarations */
   
   /* require View permission to access the root (bound to authenticated ...) */
-  [[self soClassSecurityInfo] declareObjectProtected:SoPerm_View];
-  
+  [[self soClassSecurityInfo] declareObjectProtected: SoPerm_View];
+
   /* to allow public access to all contained objects (subkeys) */
-  [[self soClassSecurityInfo] setDefaultAccess:@"allow"];
+  [[self soClassSecurityInfo] setDefaultAccess: @"allow"];
   
   /* require Authenticated role for View and WebDAV */
-  [[self soClassSecurityInfo] declareRole:SoRole_Authenticated
-                              asDefaultForPermission:SoPerm_View];
-  [[self soClassSecurityInfo] declareRole:SoRole_Authenticated
-                              asDefaultForPermission:SoPerm_WebDAVAccess];
+  [[self soClassSecurityInfo] declareRole: SoRole_Owner
+                              asDefaultForPermission: SoPerm_View];
+  [[self soClassSecurityInfo] declareRole: SoRole_Owner
+                              asDefaultForPermission: SoPerm_WebDAVAccess];
+
+  if (!serverTimeZone)
+    {
+      tzName = [ud stringForKey: @"SOGoServerTimeZone"];
+      if (!tzName)
+        tzName = @"Canada/Eastern";
+      serverTimeZone = [NSTimeZone timeZoneWithName: tzName];
+      [serverTimeZone retain];
+    }
+}
+
++ (void) _fillDictionary: (NSMutableDictionary *) dictionary
+          withDAVMethods: (NSString *) firstMethod, ...
+{
+  va_list ap;
+  NSString *aclMethodName;
+  NSString *methodName;
+  SEL methodSel;
+
+  va_start (ap, firstMethod);
+  aclMethodName = firstMethod;
+  while (aclMethodName)
+    {
+      methodName = [aclMethodName davMethodToObjC];
+      methodSel = NSSelectorFromString (methodName);
+      if (methodSel && [self instancesRespondToSelector: methodSel])
+        [dictionary setObject: methodName
+                    forKey: [NSString stringWithFormat: @"{DAV:}%@",
+                                      aclMethodName]];
+      else
+        NSLog(@"************ method '%@' is still unimplemented!",
+              methodName);
+      aclMethodName = va_arg (ap, NSString *);
+    }
+
+  va_end (ap);
+}
+
++ (NSDictionary *) defaultWebDAVAttributeMap
+{
+  static NSMutableDictionary *map = nil;
+
+  if (!map)
+    {
+      map = [NSMutableDictionary
+              dictionaryWithDictionary: [super defaultWebDAVAttributeMap]];
+      [map retain];
+      [self _fillDictionary: map
+            withDAVMethods: @"owner", @"group", @"supported-privilege-set",
+            @"current-user-privilege-set", @"acl", @"acl-restrictions",
+            @"inherited-acl-set", @"principal-collection-set", nil];
+    }
+
+  return map;
 }
 
 /* containment */
 
++ (id) objectWithName: (NSString *)_name inContainer:(id)_container
+{
+  SOGoObject *object;
+
+  object = [[self alloc] initWithName: _name inContainer: _container];
+  [object autorelease];
+
+  return object;
+}
+
+/* DAV ACL properties */
+- (NSString *) _principalForUser: (NSString *) user
+{
+  WOContext *context;
+
+  context = [[WOApplication application] context];
+
+  return [NSString stringWithFormat: @"%@users/%@",
+                   [self rootURLInContext: context],
+                   user];
+}
+
+- (NSString *) davOwner
+{
+  return [self _principalForUser: [self ownerInContext: nil]];
+}
+
+- (NSString *) davAclRestrictions
+{
+  NSMutableString *restrictions;
+
+  restrictions = [NSMutableString string];
+  [restrictions appendString: @"<D:grant-only/>"];
+  [restrictions appendString: @"<D:no-invert/>"];
+
+  return restrictions;
+}
+
+- (SOGoDAVSet *) davPrincipalCollectionSet
+{
+  NSString *usersUrl;
+  WOContext *context;
+
+  context = [[WOApplication application] context];
+  usersUrl = [NSString stringWithFormat: @"%@users",
+                       [self rootURLInContext: context]];
+
+  return [SOGoDAVSet davSetWithArray: [NSArray arrayWithObject: usersUrl]
+                     ofValuesTaggedAs: @"D:href"];
+}
+
+- (SOGoDAVSet *) davCurrentUserPrivilegeSet
+{
+  SOGoAuthenticator *sAuth;
+  SoUser *user;
+  NSArray *roles;
+  WOContext *context;
+  SoClassSecurityInfo *sInfo;
+  NSArray *davPermissions;
+
+  sAuth = [SOGoAuthenticator sharedSOGoAuthenticator];
+  context = [[WOApplication application] context];
+  user = [sAuth userInContext: context];
+  roles = [user rolesForObject: self inContext: context];
+  sInfo = [[self class] soClassSecurityInfo];
+
+  davPermissions
+    = [[sInfo DAVPermissionsForRoles: roles] stringsWithFormat: @"<D:%@/>"];
+
+  return [SOGoDAVSet davSetWithArray: davPermissions
+                     ofValuesTaggedAs: @"D:privilege"];
+}
+
+- (SOGoDAVSet *) davSupportedPrivilegeSet
+{
+  SoClassSecurityInfo *sInfo;
+  NSArray *allPermissions;
+
+  sInfo = [[self class] soClassSecurityInfo];
+
+  allPermissions = [[sInfo allDAVPermissions] stringsWithFormat: @"<D:%@/>"];
+
+  return [SOGoDAVSet davSetWithArray: allPermissions
+                     ofValuesTaggedAs: @"D:privilege"];
+}
+
+- (NSArray *) _davAcesFromAclsDictionary: (NSDictionary *) aclsDictionary
+{
+  NSEnumerator *keys;
+  NSArray *privileges;
+  NSMutableString *currentAce;
+  NSMutableArray *davAces;
+  NSString *currentKey;
+  SOGoDAVSet *privilegesDS;
+
+  davAces = [NSMutableArray array];
+  keys = [[aclsDictionary allKeys] objectEnumerator];
+  currentKey = [keys nextObject];
+  while (currentKey)
+    {
+      currentAce = [NSMutableString string];
+      if ([currentKey hasPrefix: @":"])
+        [currentAce
+          appendFormat: @"<D:principal><D:property><D:%@/></D:property></D:principal>",
+          [currentKey substringFromIndex: 1]];
+      else
+        [currentAce
+          appendFormat: @"<D:principal><D:href>%@</D:href></D:principal>",
+          [self _principalForUser: currentKey]];
+      privileges = [[aclsDictionary objectForKey: currentKey]
+                     stringsWithFormat: @"<D:%@/>"];
+      privilegesDS = [SOGoDAVSet davSetWithArray: privileges
+                                 ofValuesTaggedAs: @"privilege"];
+      [currentAce appendString: [privilegesDS stringForTag: @"{DAV:}grant"
+                                              rawName: @"grant"
+                                              inContext: nil prefixes: nil]];
+      [davAces addObject: currentAce];
+      currentKey = [keys nextObject];
+    }
+
+  return davAces;
+}
+
+- (void) _appendRolesForPseudoPrincipals: (NSMutableDictionary *) aclsDictionary
+                   withClassSecurityInfo: (SoClassSecurityInfo *) sInfo
+{
+  NSArray *perms;
+
+  perms = [sInfo DAVPermissionsForRole: SoRole_Owner];
+  if ([perms count])
+    [aclsDictionary setObject: perms forKey: @":owner"];
+  perms = [sInfo DAVPermissionsForRole: SoRole_Authenticated];
+  if ([perms count])
+    [aclsDictionary setObject: perms forKey: @":authenticated"];
+  perms = [sInfo DAVPermissionsForRole: SoRole_Anonymous];
+  if ([perms count])
+    [aclsDictionary setObject: perms forKey: @":unauthenticated"];
+}
+
+- (SOGoDAVSet *) davAcl
+{
+  NSArray *role;
+  NSEnumerator *acls;
+  NSMutableDictionary *aclsDictionary;
+  NSDictionary *currentAcl;
+  SoClassSecurityInfo *sInfo;
+
+  acls = [[[SOGoAclsFolder aclsFolder] aclsForObject: self] objectEnumerator];
+  aclsDictionary = [NSMutableDictionary dictionary];
+  sInfo = [[self class] soClassSecurityInfo];
+
+  currentAcl = [acls nextObject];
+  while (currentAcl)
+    {
+      role = [NSArray arrayWithObject: [currentAcl objectForKey: @"role"]];
+      [aclsDictionary setObject: [sInfo DAVPermissionsForRoles: role]
+                      forKey: [currentAcl objectForKey: @"uid"]];
+      currentAcl = [acls nextObject];
+    }
+  [self _appendRolesForPseudoPrincipals: aclsDictionary
+        withClassSecurityInfo: sInfo];
+
+  return [SOGoDAVSet davSetWithArray:
+                       [self _davAcesFromAclsDictionary: aclsDictionary]
+                     ofValuesTaggedAs: @"D:ace"];
+}
+
+/* end of properties */
+
 - (BOOL)doesRetainContainer {
   return YES;
 }
 
 - (id)initWithName:(NSString *)_name inContainer:(id)_container {
   if ((self = [super init])) {
-    self->nameInContainer = [_name copy];
-    self->container = 
+    nameInContainer = [_name copy];
+    container = 
       [self doesRetainContainer] ? [_container retain] : _container;
+    userTimeZone = nil;
+    customOwner = nil;
   }
   return self;
 }
+
 - (id)init {
   return [self initWithName:nil inContainer:nil];
 }
 
 - (void)dealloc {
+  if (customOwner)
+    [customOwner release];
   if ([self doesRetainContainer])
-    [self->container release];
-  [self->nameInContainer release];
+    [container release];
+  if (userTimeZone)
+    [userTimeZone release];
+  [nameInContainer release];
   [super dealloc];
 }
 
 /* accessors */
 
 - (NSString *)nameInContainer {
-  return self->nameInContainer;
+  return nameInContainer;
 }
 - (id)container {
-  return self->container;
+  return container;
 }
 
 /* ownership */
 
+- (void) setOwner: (NSString *) newOwner
+{
+  ASSIGN (customOwner, newOwner);
+}
+
 - (NSString *)ownerInContext:(id)_ctx {
-  return [[self container] ownerInContext:_ctx];
+  return ((customOwner)
+          ? customOwner
+          : [[self container] ownerInContext:_ctx]);
 }
 
 /* hierarchy */
@@ -112,9 +457,10 @@ static BOOL kontactGroupDAV = YES;
   ma    = [NSMutableArray arrayWithCapacity:count + 1];
   for (i = 0; i < count; i++) {
     id folder;
-    
-    folder = [self lookupName:[names objectAtIndex:i] inContext:nil 
-                  acquire:NO];
+
+    folder = [self lookupName: [names objectAtIndex:i]
+                   inContext: nil 
+                  acquire: NO];
     if (folder == nil)
       continue;
     if ([folder isKindOfClass:[NSException class]])
@@ -128,10 +474,10 @@ static BOOL kontactGroupDAV = YES;
 /* looking up shared objects */
 
 - (SOGoUserFolder *)lookupUserFolder {
-  if (![self->container respondsToSelector:_cmd])
+  if (![container respondsToSelector:_cmd])
     return nil;
   
-  return [self->container lookupUserFolder];
+  return [container lookupUserFolder];
 }
 - (SOGoGroupsFolder *)lookupGroupsFolder {
   return [[self lookupUserFolder] lookupGroupsFolder];
@@ -139,8 +485,8 @@ static BOOL kontactGroupDAV = YES;
 
 - (void)sleep {
   if ([self doesRetainContainer])
-    [self->container release];
-  self->container = nil;
+    [container release];
+  container = nil;
 }
 
 /* operations */
@@ -179,7 +525,7 @@ static BOOL kontactGroupDAV = YES;
   //       default method)
   WORequest  *rq;
   WOResponse *r;
-  NSString   *uri;
+  NSString *uri;
   
   r  = [(WOContext *)_ctx response];
   rq = [(WOContext *)_ctx request];
@@ -196,6 +542,7 @@ static BOOL kontactGroupDAV = YES;
       
       if ((etag = [self davEntityTag]) != nil)
        [r setHeader:etag forKey:@"etag"];
+
       return r;
     }
     
@@ -204,11 +551,12 @@ static BOOL kontactGroupDAV = YES;
   }
   
   uri = [rq uri];
-  if (![uri hasSuffix:@"/"]) uri = [uri stringByAppendingString:@"/"];
-  uri = [uri stringByAppendingString:@"view"];
-  
   [r setStatus:302 /* moved */];
-  [r setHeader:uri forKey:@"location"];
+  [r setHeader: [uri composeURLWithAction: @"view"
+                     parameters: [rq formValues]
+                     andHash: NO]
+     forKey:@"location"];
+
   return r;
 }
 
@@ -357,15 +705,53 @@ static BOOL kontactGroupDAV = YES;
   return nil;
 }
 
+- (NSTimeZone *) serverTimeZone
+{
+  return serverTimeZone;
+}
+
+/* TODO: should be moved into SOGoUser */
+- (NSTimeZone *) userTimeZone
+{
+  NSUserDefaults *userPrefs;
+  WOContext *context;
+
+  if (!userTimeZone)
+    {
+      context = [[WOApplication application] context];
+      userPrefs = [[context activeUser] userDefaults];
+      userTimeZone = [NSTimeZone
+                       timeZoneWithName: [userPrefs stringForKey: @"timezonename"]];
+      if (!userTimeZone)
+        userTimeZone = [self serverTimeZone];
+      [userTimeZone retain];
+    }
+
+  return userTimeZone;
+}
+
+- (NSTimeZone *) userTimeZone: (NSString *) username
+{
+  NSUserDefaults *userPrefs;
+  AgenorUserManager *am;
+
+  am = [AgenorUserManager sharedUserManager];
+  userPrefs = [am getUserDefaultsForUID: username];
+  userTimeZone = [NSTimeZone timeZoneWithName: [userPrefs stringForKey: @"timezonename"]];
+  if (!userTimeZone)
+    userTimeZone = [self serverTimeZone];
+
+  return userTimeZone;
+}
+
 /* description */
 
 - (void)appendAttributesToDescription:(NSMutableString *)_ms {
-  if (self->nameInContainer != nil
-    [_ms appendFormat:@" name=%@", self->nameInContainer];
-  if (self->container != nil) {
+  if (nameInContainer
+    [_ms appendFormat:@" name=%@", nameInContainer];
+  if (container)
     [_ms appendFormat:@" container=0x%08X/%@", 
-          self->container, [self->container valueForKey:@"nameInContainer"]];
-  }
+         container, [container valueForKey:@"nameInContainer"]];
 }
 
 - (NSString *)description {
@@ -375,6 +761,7 @@ static BOOL kontactGroupDAV = YES;
   [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
   [self appendAttributesToDescription:ms];
   [ms appendString:@">"];
+
   return ms;
 }
 
diff --git a/SoObjects/SOGo/SOGoPermissions.h b/SoObjects/SOGo/SOGoPermissions.h
new file mode 100644 (file)
index 0000000..ee19617
--- /dev/null
@@ -0,0 +1,39 @@
+/* SOGoPermissions.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOPERMISSIONS_H
+#define SOGOPERMISSIONS_H
+
+#import <Foundation/NSString.h>
+
+#import <NGObjWeb/SoPermissions.h>
+
+extern NSString *SOGoRole_Assistant;
+extern NSString *SOGoRole_Delegate;
+extern NSString *SOGoRole_FreeBusyLookup;
+extern NSString *SOGoRole_FreeBusy;
+
+extern NSString *SOGoPerm_ReadAcls;
+extern NSString *SOGoPerm_CreateAndModifyAcls;
+extern NSString *SOGoPerm_FreeBusyLookup;
+
+#endif /* SOGOPERMISSIONS_H */
diff --git a/SoObjects/SOGo/SOGoPermissions.m b/SoObjects/SOGo/SOGoPermissions.m
new file mode 100644 (file)
index 0000000..13e7cb9
--- /dev/null
@@ -0,0 +1,42 @@
+/* SOGoPermissions.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import "SOGoPermissions.h"
+
+NSString *SOGoRole_Assistant = @"Assistant";               /* a colleague */
+NSString *SOGoRole_Delegate = @"Delegate"; /* a colleague or person that I
+                                              trust in adding or modifying my
+                                              data */
+NSString *SOGoRole_FreeBusyLookup = @"FreeBusyLookup"; /* for users that have
+                                                          access to the
+                                                          freebusy information
+                                                          from a specific
+                                                          calendar */
+NSString *SOGoRole_FreeBusy = @"FreeBusy"; /* for the "freebusy" special user
+                                            */
+
+#warning ReadAcls still not used...
+NSString *SOGoPerm_ReadAcls = @"ReadAcls"; /* the equivalent of "read-acl" in
+                                              the WebDAV acls spec, which is
+                                              currently missing from SOPE */
+NSString *SOGoPerm_CreateAndModifyAcls = @"CreateAndModifyAcls";
+NSString *SOGoPerm_FreeBusyLookup = @"FreeBusyLookup";
index 851dfb62d1f8473bf8aac331d66cb58236db571f..164af564a84ca6fdc07aa2701439b92cbc6a232f 100644 (file)
@@ -34,9 +34,8 @@
     context.activeUser
 */
 
-@class NSString, NSArray, NSDictionary, NSUserDefaults;
-
-@class NSString, NSArray, NSURL, NSUserDefaults;
+@class NSString, NSArray, NSDictionary, NSURL, NSUserDefaults;
+@class WOContext;
 
 @interface SOGoUser : SoUser
 {
@@ -68,6 +67,9 @@
 - (id)homeFolderInContext:(id)_ctx;
 - (id)schedulingCalendarInContext:(id)_ctx;
 
+- (NSArray *) rolesForObject: (NSObject *) object
+                   inContext: (WOContext *) context;
+
 @end
 
 #endif /* __SOGoUser_H__ */
index 04922e4828745c07a0d42684e6ca4c5fc7e47d54..4292e7b91317490cebcec16976fd758ea1fdb5ef 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoUser.h"
-#include <SOGo/AgenorUserManager.h>
-#include "common.h"
+#import <NGObjWeb/SoObject.h>
+#import "AgenorUserManager.h"
+#import "SOGoAclsFolder.h"
+#import "common.h"
+
+#import "SOGoUser.h"
+
+@interface NSObject (SOGoRoles)
+
+- (NSString *) roleOfUser: (NSString *) uid
+                inContext: (WOContext *) context;
+
+@end
 
 @implementation SOGoUser
 
     return folder;
   
   [(WOContext *)_ctx setObject:folder ? folder : [NSNull null] 
-                    forKey:@"ActiveUserHomeFolder"];
+                forKey: @"ActiveUserHomeFolder"];
   return folder;
 }
 
     return folder;
   
   [(WOContext *)_ctx setObject:folder ? folder : [NSNull null] 
-                    forKey:@"ActiveUserCalendar"];
+                forKey:@"ActiveUserCalendar"];
   return folder;
 }
 
+- (NSArray *) rolesForObject: (NSObject *) object
+                   inContext: (WOContext *) context
+{
+  NSMutableArray *rolesForObject;
+  SOGoAclsFolder *aclsFolder;
+  NSArray *sogoRoles;
+  NSString *role;
+
+  rolesForObject
+    = [NSMutableArray arrayWithArray: [super rolesForObject: object
+                                             inContext: context]];
+  if ([[object ownerInContext: context] isEqualToString: [self login]])
+    [rolesForObject addObject: SoRole_Owner];
+  if ([object isKindOfClass: [SOGoObject class]])
+    {
+      aclsFolder = [SOGoAclsFolder aclsFolder];
+      sogoRoles = [aclsFolder aclsForObject: (SOGoObject *) object
+                              forUser: login];
+      [rolesForObject addObjectsFromArray: sogoRoles];
+    }
+  if ([object respondsToSelector: @selector (roleOfUser:inContext:)])
+    {
+      role = [object roleOfUser: login inContext: context];
+      if (role)
+        [rolesForObject addObject: role];
+    }
+
+  return rolesForObject;
+}
+
 @end /* SOGoUser */
index c071b7c25378b231b6536e5c12e0d7f735bb3284..7f52d41f138f6f08cf43d18aec5c3dfc8fa7b256 100644 (file)
@@ -22,7 +22,7 @@
 #ifndef __SOGo_SOGoUserFolder_H__
 #define __SOGo_SOGoUserFolder_H__
 
-#include <SOGo/SOGoFolder.h>
+#import "SOGoFolder.h"
 
 /*
   SOGoUserFolder
 */
 
 @class NSString;
+@class WOContext;
 
 @interface SOGoUserFolder : SOGoFolder
-{
-}
 
 /* accessors */
 
-- (NSString *)login;
+- (NSString *) login;
 
 /* ownership */
 
-- (NSString *)ownerInContext:(id)_ctx;
+- (NSString *) ownerInContext: (WOContext *) _ctx;
 
 /* pathes */
 
-- (NSString *)ocsUserPath;
-- (NSString *)ocsPrivateCalendarPath;
+- (NSString *) ocsUserPath;
+- (NSString *) ocsPrivateCalendarPath;
 
-- (id)lookupFreeBusyObject;
+/* TODO: not implemented, bad bad */
+// - (id)lookupFreeBusyObject;
 
 @end
 
index 469c862c2cee5bf986ec7036f5f4e187bd24bd82..85b084927353fb63c4839fa114a6cc436fdd83f8 100644 (file)
   02111-1307, USA.
 */
 
-#include "SOGoUserFolder.h"
-#include "WOContext+Agenor.h"
-#include "common.h"
+#import "WOContext+Agenor.h"
+#import "common.h"
+#import "SOGoUser.h"
+
+#import "Appointments/SOGoAppointmentFolder.h"
+#import "Appointments/SOGoFreeBusyObject.h"
+#import "Contacts/SOGoContactFolders.h"
+#import "Mailer/SOGoMailAccounts.h"
+#import "SOGoPermissions.h"
+
+#import "SOGoUserFolder.h"
 
 @implementation SOGoUserFolder
 
 /* accessors */
 
-- (NSString *)login {
-  return [self nameInContainer];
+- (NSString *) login
+{
+  return nameInContainer;
 }
 
 /* hierarchy */
 
-- (NSArray *)toManyRelationshipKeys {
+- (NSArray *) toManyRelationshipKeys
+{
   static NSArray *children = nil;
-  
-  if (children == nil) {
+
+  if (!children)
     children = [[NSArray alloc] initWithObjects:
                                  @"Calendar", @"Contacts", @"Mail", nil];
-  }
+
   return children;
 }
 
 /* ownership */
 
-- (NSString *)ownerInContext:(id)_ctx {
-  return [self login];
+- (NSString *) ownerInContext: (WOContext *) _ctx
+{
+  return nameInContainer;
 }
 
 /* looking up shared objects */
 
-- (SOGoUserFolder *)lookupUserFolder {
+- (SOGoUserFolder *) lookupUserFolder
+{
   return self;
 }
-- (SOGoGroupsFolder *)lookupGroupsFolder {
-  return [self lookupName:@"Groups" inContext:nil acquire:NO];
+
+- (SOGoGroupsFolder *) lookupGroupsFolder
+{
+  return [self lookupName: @"Groups" inContext: nil acquire: NO];
 }
 
 /* pathes */
 
-- (void)setOCSPath:(NSString *)_path {
+- (void) setOCSPath: (NSString *) _path
+{
   [self warnWithFormat:
           @"rejected attempt to reset user-folder path: '%@'", _path];
 }
-- (NSString *)ocsPath {
-  return [@"/Users/" stringByAppendingString:[self login]];
+
+- (NSString *) ocsPath
+{
+  return [@"/Users/" stringByAppendingString: [self login]];
 }
 
-- (NSString *)ocsUserPath {
+- (NSString *) ocsUserPath
+{
   return [self ocsPath];
 }
-- (NSString *)ocsPrivateCalendarPath {
+
+- (NSString *) ocsPrivateCalendarPath
+{
   return [[self ocsUserPath] stringByAppendingString:@"/Calendar"];
 }
-- (NSString *)ocsPrivateContactsPath {
+
+- (NSString *) ocsPrivateContactsPath
+{
   return [[self ocsUserPath] stringByAppendingString:@"/Contacts"];
 }
 
 /* name lookup */
 
-- (id)privateCalendar:(NSString *)_key inContext:(id)_ctx {
-  static Class calClass = Nil;
-  id calendar;
-  
-  if (calClass == Nil)
-    calClass = NSClassFromString(@"SOGoAppointmentFolder");
-  if (calClass == Nil) {
-    [self errorWithFormat:@"missing SOGoAppointmentFolder class!"];
-    return nil;
-  }
+// - (NSString *) permissionForKey: (NSString *) key
+// {
+//   return ([key isEqualToString: @"freebusy.ifb"]
+//           ? SoPerm_WebDAVAccess
+//           : [super permissionForKey: key]);
+// }
+
+- (SOGoAppointmentFolder *) privateCalendar: (NSString *) _key
+                                  inContext: (WOContext *) _ctx
+{
+  SOGoAppointmentFolder *calendar;
   
-  calendar = [[calClass alloc] initWithName:_key inContainer:self];
-  [calendar setOCSPath:[self ocsPrivateCalendarPath]];
-  return [calendar autorelease];
-}
+  calendar = [$(@"SOGoAppointmentFolder") objectWithName: _key inContainer: self];
+  [calendar setOCSPath: [self ocsPrivateCalendarPath]];
 
-- (id)privateContacts:(NSString *)_key inContext:(id)_ctx {
-  static Class calClass = Nil;
-  id calendar;
-  
-  if (calClass == Nil)
-    calClass = NSClassFromString(@"SOGoContactFolder");
-  if (calClass == Nil) {
-    [self errorWithFormat:@"missing SOGoContactFolder class!"];
-    return nil;
-  }
-  
-  calendar = [[calClass alloc] initWithName:_key inContainer:self];
-  [calendar setOCSPath:[self ocsPrivateContactsPath]];
-  return [calendar autorelease];
+  return calendar;
 }
 
-- (id)groupsFolder:(NSString *)_key inContext:(id)_ctx {
-  static Class fldClass = Nil;
-  id folder;
-  
-  if (fldClass == Nil)
-    fldClass = NSClassFromString(@"SOGoGroupsFolder");
-  if (fldClass == Nil) {
-    [self errorWithFormat:@"missing SOGoGroupsFolder class!"];
-    return nil;
-  }
-  
-  folder = [[fldClass alloc] initWithName:_key inContainer:self];
-  return [folder autorelease];
+- (SOGoContactFolders *) privateContacts: (NSString *) _key
+                               inContext: (WOContext *) _ctx
+{
+  SOGoContactFolders *contacts;
+
+  contacts = [$(@"SOGoContactFolders") objectWithName:_key inContainer: self];
+  [contacts setBaseOCSPath: [self ocsPrivateContactsPath]];
+
+  return contacts;
 }
 
-- (id)mailAccountsFolder:(NSString *)_key inContext:(id)_ctx {
-  static Class fldClass = Nil;
-  id folder;
-  
-  if (fldClass == Nil)
-    fldClass = NSClassFromString(@"SOGoMailAccounts");
-  if (fldClass == Nil) {
-    [self errorWithFormat:@"missing SOGoMailAccounts class!"];
-    return nil;
-  }
-  
-  folder = [[fldClass alloc] initWithName:_key inContainer:self];
-  return [folder autorelease];
+- (id) groupsFolder: (NSString *) _key
+          inContext: (WOContext *) _ctx
+{
+  return [$(@"SOGoGroupsFolder") objectWithName: _key inContainer: self];
 }
 
-- (id)freeBusyObject:(NSString *)_key inContext:(id)_ctx {
-  static Class fbClass = Nil;
-  id fb;
+- (id) mailAccountsFolder: (NSString *) _key
+                inContext: (WOContext *) _ctx
+{
+  return [$(@"SOGoMailAccounts") objectWithName: _key inContainer: self];
+}
 
-  if (fbClass == Nil)
-    fbClass = NSClassFromString(@"SOGoFreeBusyObject");
-  if (fbClass == Nil) {
-    [self errorWithFormat:@"missing SOGoFreeBusyObject class!"];
-    return nil;
-  }
-  
-  fb = [[fbClass alloc] initWithName:_key inContainer:self];
-  return [fb autorelease];
+- (id) freeBusyObject: (NSString *) _key
+            inContext: (WOContext *) _ctx
+{
+  return [$(@"SOGoFreeBusyObject") objectWithName: _key inContainer: self];
 }
 
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
+- (id) lookupName: (NSString *) _key
+        inContext: (WOContext *) _ctx
+          acquire: (BOOL) _flag
+{
   id obj;
   
   /* first check attributes directly bound to the application */
-  if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
-    return obj;
-  
-  if ([_key hasPrefix:@"Calendar"]) {
-    id calendar;
-    
-    calendar = [self privateCalendar:@"Calendar" inContext:_ctx];
-    if ([_key isEqualToString:@"Calendar"])
-      return calendar;
-    
-    return [calendar lookupName:[_key pathExtension] 
-                    inContext:_ctx acquire:NO];
-  }
-
-  if ([_key isEqualToString:@"Contacts"])
-    return [self privateContacts:_key inContext:_ctx];
-  
-  if ([_key isEqualToString:@"Groups"]) {
-    /* Agenor requirement, return 403 to stop acquisition */
-    if (![_ctx isAccessFromIntranet]) {
-      return [NSException exceptionWithHTTPStatus:403 /* Forbidden */];
+  obj = [super lookupName: _key inContext: _ctx acquire: NO];
+  if (!obj)
+    {
+      if ([_key hasPrefix: @"Calendar"])
+        {
+          obj = [self privateCalendar: @"Calendar" inContext: _ctx];
+          if (![_key isEqualToString: @"Calendar"])
+            obj = [obj lookupName: [_key pathExtension] 
+                       inContext: _ctx acquire: NO];
+        }
+      else if ([_key isEqualToString: @"Contacts"])
+        obj = [self privateContacts: _key inContext: _ctx];
+      else if ([_key isEqualToString: @"Groups"])
+        obj = [self groupsFolder: _key inContext: _ctx];
+      else if ([_key isEqualToString: @"Mail"])
+        obj = [self mailAccountsFolder: _key inContext: _ctx];
+      else if ([_key isEqualToString: @"freebusy.ifb"])
+        obj = [self freeBusyObject:_key inContext:_ctx];
+      else
+        obj = [NSException exceptionWithHTTPStatus: 404 /* Not Found */];
     }
-    return [self groupsFolder:_key inContext:_ctx];
-  }
 
-  if ([_key isEqualToString:@"Mail"])
-    return [self mailAccountsFolder:_key inContext:_ctx];
-
-  if ([_key isEqualToString:@"freebusy.ifb"])
-    return [self freeBusyObject:_key inContext:_ctx];
+  return obj;
+}
+
+- (NSString *) roleOfUser: (NSString *) uid
+                inContext: (WOContext *) context
+{
+  NSArray *roles, *traversalPath;
+  NSString *objectName, *role;
+
+  role = nil;
+  traversalPath = [context objectForKey: @"SoRequestTraversalPath"];
+  if ([traversalPath count] > 1)
+    {
+      objectName = [traversalPath objectAtIndex: 1];
+      if ([objectName isEqualToString: @"Calendar"]
+          || [objectName isEqualToString: @"Contacts"])
+        {
+          roles = [[context activeUser]
+                    rolesForObject: [self lookupName: objectName
+                                          inContext: context
+                                          acquire: NO]
+                    inContext: context];
+          if ([roles containsObject: SOGoRole_Assistant]
+              || [roles containsObject: SOGoRole_Delegate])
+            role = SOGoRole_Assistant;
+        }
+    }
 
-  /* return 404 to stop acquisition */
-  return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
+  return role;
 }
 
 /* WebDAV */
 
-- (NSArray *)fetchContentObjectNames {
+- (NSArray *) fetchContentObjectNames
+{
   static NSArray *cos = nil;
   
-  if (!cos) {
-    cos = [[NSArray alloc] initWithObjects:@"freebusy.ifb", nil];
-  }
+  if (!cos)
+    cos = [[NSArray alloc] initWithObjects: @"freebusy.ifb", nil];
+
   return cos;
 }
 
-- (BOOL)davIsCollection {
+- (BOOL) davIsCollection
+{
   return YES;
 }
 
index 2c0f2b8124c1415c17b395e0abe2afe043ab7c97..8b1fb43d98ffb0bf2f9ebee77630fd9d7d11d639 100644 (file)
@@ -25,7 +25,7 @@ BUNDLE_LIBS += \
        -lGDLContentStore                       \
        -lGDLAccess                             \
        -lNGObjWeb                              \
-       -lNGiCal -lNGMime -lNGLdap              \
+       -lNGCards -lNGMime -lNGLdap             \
        -lNGStreams -lNGExtensions -lEOControl  \
        -lXmlRpc -lDOM -lSaxObjC
 
similarity index 100%
rename from UI/ChangeLog
rename to UI/ChangeLog.upstream
index b3f4b8c5c543e7bc4e2e91b6a7509a491674eba7..3af994ea9c61b215d7912fb837b662ebd53a025c 100644 (file)
@@ -1,11 +1,22 @@
 /* this file is in UTF-8 format! */
 
-"Home"                 = "Home";
-"Calendar"             = "Calendar";
-"Addressbook"          = "Addressbook";
-"Mail"                 = "Mail";
-"Administration"       = "Right Administration";
+/* toolbars */
+"Save" = "Save";
+"Close" = "Close";
+
+"Home" = "Home";
+"Calendar" = "Calendar";
+"Address Book" = "Address Book";
+"Mail" = "Mail";
+"Logoff" = "Logoff";
+"Right Administration" = "Right Administration";
+"Log Console (dev.)" = "Log Console (dev.)";
 
 "User"                 = "User";
 
 "Help"                 = "Help";
+
+"noJavascriptError" = "SOGo requires Javascript to run. Please make sure this option is available and activated within your browser preferences.";
+"noJavascriptRetry" = "Retry";
+
+"Publish the Free/Busy information" = "Publish the Free/Busy information";
index 322c47723bfc897ec810caba5c04bbeeeec758ae..314ae983abb0de2293b8878342396cc0b98e36eb 100644 (file)
@@ -1,10 +1,25 @@
 /* this file is in UTF-8 format! */
 
-"Home"        = "Accueil";
-"Calendar"       = "Agenda";
-"Addressbook"  = "Carnet d'adresses";
-"Mail"             = "Mail";
+/* toolbars */
+"Save" = "Sauver";
+"Close" = "Fermer";
+
+"Home" = "Accueil";
+"Calendar" = "Agenda";
+"Address Book" = "Carnet d'adresses";
+"Mail" = "Courrier";
+"Logoff" = "Quitter";
+"Right Administration" = "Partage";
+"Log Console (dev.)" = "Journal (dév.)";
 
 "User" = "Utilisateur";
 
 "Help" = "Aide";
+
+"noJavascriptError" = "SOGo requiert l'utilisation de Javascript. Veuillez vous assurer que cette option est disponible et activée dans votre fureteur.";
+"noJavascriptRetry" = "Réessayer";
+
+"Owner:" = "Propriétaire :";
+"Associated Users:" = "Utilisateurs associés :";
+"(Unchecked = assistant, checked = delegate)" = "(Coché = assistant, décoché = délégué)";
+"Publish the Free/Busy information" = "Publier l'occupation du temps";
index 3f508815f026ca2f5c3e87276e839112be87b1db..add62ea9abffe52d8b940f7146c46a6cbab68e14 100644 (file)
@@ -12,18 +12,25 @@ CommonUI_OBJC_FILES +=              \
        CommonUIProduct.m       \
        UIxPageFrame.m          \
        UIxPrintPageFrame.m     \
-       UIxWinClose.m           \
        UIxSortButton.m         \
        UIxAppNavView.m         \
+       UIxJSClose.m            \
        \
+       UIxAclEditor.m  \
        UIxElemBuilder.m        \
        UIxTabView.m            \
        UIxTabItem.m            \
-
+       \
+       UIxSortableTableHeader.m \
+       \
+       UIxToolbar.m
 
 CommonUI_RESOURCE_FILES += \
        Version                 \
        product.plist           \
+       Toolbars/SOGoAclOwner.toolbar \
+       Toolbars/SOGoAclAssistant.toolbar \
+
 
 CommonUI_LOCALIZED_RESOURCE_FILES +=   \
        Localizable.strings             \
index a4d2bb3a90a65475ef3e4a3d6b2d43bd38d81ce3..eaf1c03cc39f1c336701d34c7eba5d8ba5546729 100644 (file)
@@ -18,4 +18,4 @@ CommonUI_BUNDLE_LIBS += \
        -lNGObjWeb      \
        -lNGMime        \
        -lNGStreams -lNGExtensions -lEOControl  \
-       -lXmlRpc -lDOM -lSaxObjC
+       -lXmlRpc -lDOM -lSaxObjC -lWOExtensions
diff --git a/UI/Common/Toolbars/SOGoAclAssistant.toolbar b/UI/Common/Toolbars/SOGoAclAssistant.toolbar
new file mode 100644 (file)
index 0000000..6e08205
--- /dev/null
@@ -0,0 +1,7 @@
+( /* the toolbar groups -*-cperl-*- */
+  ( { link = "#";
+      isSafe = NO;
+      label = "Close";
+      onclick = "window.close();";
+      image = "tb-mail-stop-flat-24x24.png"; } )
+)
diff --git a/UI/Common/Toolbars/SOGoAclOwner.toolbar b/UI/Common/Toolbars/SOGoAclOwner.toolbar
new file mode 100644 (file)
index 0000000..70987ee
--- /dev/null
@@ -0,0 +1,12 @@
+( /* the toolbar groups -*-cperl-*- */
+  ( { link = "#";
+      isSafe = NO;
+      label = "Save";
+      onclick = "return saveAcls(this);";
+      image = "tb-compose-save-flat-24x24.png"; },
+    { link = "#";
+      isSafe = NO;
+      label = "Close";
+      onclick = "window.close();";
+      image = "tb-mail-stop-flat-24x24.png"; } )
+)
diff --git a/UI/Common/UIxAclEditor.h b/UI/Common/UIxAclEditor.h
new file mode 100644 (file)
index 0000000..53f7d29
--- /dev/null
@@ -0,0 +1,43 @@
+/* UIxAclEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXACLEDITOR_H
+#define UIXACLEDITOR_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@interface UIxAclEditor : UIxComponent
+{
+  BOOL prepared;
+  BOOL publishInFreeBusy;
+  NSArray *acls;
+  NSMutableArray *users;
+  NSMutableArray *checkedUsers;
+  NSString *ownerCN;
+}
+
+- (NSArray *) aclsForFolder;
+- (NSString *) ownerCN;
+
+@end
+
+#endif /* UIXACLEDITOR_H */
diff --git a/UI/Common/UIxAclEditor.m b/UI/Common/UIxAclEditor.m
new file mode 100644 (file)
index 0000000..cb8cdb0
--- /dev/null
@@ -0,0 +1,185 @@
+/* UIxAclEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSKeyValueCoding.h>
+#import <NGObjWeb/SoUser.h>
+#import <NGObjWeb/WORequest.h>
+#import <NGCards/iCalPerson.h>
+#import <SoObjects/SOGo/AgenorUserManager.h>
+#import <SoObjects/SOGo/SOGoAclsFolder.h>
+#import <SoObjects/SOGo/SOGoPermissions.h>
+
+#import "UIxAclEditor.h"
+
+@implementation UIxAclEditor
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      acls = nil;
+      prepared = NO;
+      publishInFreeBusy = NO;
+      users = [NSMutableArray new];
+      checkedUsers = [NSMutableArray new];
+      ownerCN = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [users release];
+  [checkedUsers release];
+  if (ownerCN)
+    [ownerCN release];
+  [super dealloc];
+}
+
+- (NSArray *) aclsForFolder
+{
+  SOGoAclsFolder *folder;
+
+  if (!acls)
+    {
+      folder = [SOGoAclsFolder aclsFolder];
+      acls = [folder aclsForObject: [self clientObject]];
+    }
+
+  return acls;
+}
+
+- (NSString *) ownerCN
+{
+  if (!ownerCN)
+    {
+      ownerCN = [[self clientObject] ownerInContext: context];
+      [ownerCN retain];
+    }
+
+  return ownerCN;
+}
+
+- (void) _prepareUsers
+{
+  NSEnumerator *aclsEnum;
+  AgenorUserManager *um;
+  NSDictionary *currentAcl;
+  iCalPerson *currentUser;
+  NSString *currentUID;
+
+  aclsEnum = [[self aclsForFolder] objectEnumerator];
+  um = [AgenorUserManager sharedUserManager];
+  currentAcl = [aclsEnum nextObject];
+  while (currentAcl)
+    {
+      currentUID = [currentAcl objectForKey: @"c_uid"];
+      if ([currentUID isEqualToString: @"freebusy"])
+        publishInFreeBusy = YES;
+      else
+        {
+          currentUser = [um iCalPersonWithUid: currentUID];
+          if (![[currentUser cn] isEqualToString: [self ownerCN]])
+            {
+              if ([[currentAcl objectForKey: @"c_role"]
+                    isEqualToString: SOGoRole_Delegate])
+                [checkedUsers addObject: currentUser];
+              [users addObject: currentUser];
+            }
+        }
+      currentAcl = [aclsEnum nextObject];
+
+      prepared = YES;
+    }
+}
+
+- (NSArray *) usersForFolder
+{
+  if (!prepared)
+    [self _prepareUsers];
+
+  return users;
+}
+
+- (NSArray *) checkedUsers
+{
+  if (!prepared)
+    [self _prepareUsers];
+
+  return checkedUsers;
+}
+
+- (BOOL) publishInFreeBusy
+{
+  if (!prepared)
+    [self _prepareUsers];
+
+  return publishInFreeBusy;
+}
+
+- (NSString *) toolbar
+{
+  return (([[self ownerCN] isEqualToString: [[context activeUser] login]])
+          ? @"SOGoAclOwner.toolbar" : @"SOGoAclAssistant.toolbar");
+}
+
+- (BOOL) clientIsCalendar
+{
+  return [NSStringFromClass ([[self clientObject] class])
+                            isEqualToString: @"SOGoAppointmentFolder"];
+}
+
+- (id) saveAclsAction
+{
+  NSString *uids;
+  NSArray *fbUsers;
+  WORequest *request;
+  SOGoAclsFolder *folder;
+  SOGoObject *clientObject;
+
+  folder = [SOGoAclsFolder aclsFolder];
+  request = [context request];
+  clientObject = [self clientObject];
+  uids = [request formValueForKey: @"delegates"];
+  [folder setRoleForObject: clientObject
+          forUsers: [uids componentsSeparatedByString: @","]
+          to: SOGoRole_Delegate];
+  uids = [request formValueForKey: @"assistants"];
+  [folder setRoleForObject: clientObject
+          forUsers: [uids componentsSeparatedByString: @","]
+          to: SOGoRole_Assistant];
+  if ([self clientIsCalendar]) {
+    if ([[request formValueForKey: @"freebusy"] intValue])
+      fbUsers = [NSArray arrayWithObject: @"freebusy"];
+    else
+      fbUsers = nil;
+    [folder setRoleForObject: clientObject
+            forUsers: fbUsers
+            to: SOGoRole_FreeBusy];
+  }
+
+  return [self jsCloseWithRefreshMethod: nil];
+}
+
+@end
diff --git a/UI/Common/UIxException.m b/UI/Common/UIxException.m
new file mode 100644 (file)
index 0000000..3b8ec39
--- /dev/null
@@ -0,0 +1,55 @@
+/* UIxException.m - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSString.h>
+#import <UI/SOGoUI/UIxComponent.h>
+
+@interface UIxException : UIxComponent
+{
+  NSException *exception;
+}
+
+- (void) setException: (NSException *) newException;
+
+- (NSString *) statusCode;
+- (NSString *) reason;
+
+@end
+
+@implementation UIxException
+
+- (void) setException: (NSException *) newException
+{
+  exception = newException;
+}
+
+- (NSString *) statusCode
+{
+  return [NSString stringWithFormat: @"%d", [exception httpStatus]];
+}
+
+- (NSString *) reason
+{
+  return [exception reason];
+}
+
+@end
diff --git a/UI/Common/UIxJSClose.h b/UI/Common/UIxJSClose.h
new file mode 100644 (file)
index 0000000..dd51b86
--- /dev/null
@@ -0,0 +1,41 @@
+/* UIxJSClose.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXJSCLOSE_H
+#define UIXJSCLOSE_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSString;
+
+@interface UIxJSClose : UIxComponent
+{
+  NSString *refreshMethod;
+}
+
+- (void) setRefreshMethod: (NSString *) method;
+- (NSString *) refreshMethod;
+- (BOOL) hasRefreshMethod;
+
+@end
+
+#endif /* UIXJSCLOSE_H */
diff --git a/UI/Common/UIxJSClose.m b/UI/Common/UIxJSClose.m
new file mode 100644 (file)
index 0000000..96dc670
--- /dev/null
@@ -0,0 +1,71 @@
+/* UIxJSClose.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSString.h>
+
+#import "UIxJSClose.h"
+
+@implementation UIxJSClose
+
+- (id) init
+{
+  if ((self = [super init]))
+    refreshMethod = nil;
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (refreshMethod)
+    [refreshMethod release];
+  [super dealloc];
+}
+
+- (NSString *) doctype
+{
+  return (@"<?xml version=\"1.0\"?>\n"
+          @"<!DOCTYPE html"
+          @" PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
+          @" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
+}
+
+- (void) setRefreshMethod: (NSString *) method
+{
+  if (refreshMethod)
+    [refreshMethod release];
+  refreshMethod = method;
+  if (refreshMethod)
+    [refreshMethod retain];
+}
+
+- (NSString *) refreshMethod
+{
+  return refreshMethod;
+}
+
+- (BOOL) hasRefreshMethod
+{
+  return (refreshMethod != nil);
+}
+
+@end
similarity index 51%
rename from Misc/dbd/DSoTable.h
rename to UI/Common/UIxPageFrame.h
index cdad265ba92b8bdb627186f0285233b53d01544f..7647b169e937fb9313966ea2970176e20e873d7e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2004 SKYRIX Software AG
+  Copyright (C) 2004-2005 SKYRIX Software AG
 
   This file is part of OpenGroupware.org.
 
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
-#ifndef __dbd_DSoTable_H__
-#define __dbd_DSoTable_H__
+#ifndef UIXPAGEFRAME_H
+#define UIXPAGEFRAME_H
 
-#include "DSoObject.h"
+@interface WOComponent (PopupExtension)
 
-@class NSString;
-@class DSoDatabase;
+- (BOOL) isPopup;
 
-@interface DSoTable : DSoObject
+@end
+
+@interface UIxPageFrame : UIxComponent
 {
-  DSoDatabase *database;
-  NSString    *tableName;
+  NSString *title;
+  NSString *toolbar;
+  id item;
+  BOOL isPopup;
 }
 
-- (id)initWithName:(NSString *)_name inContainer:(id)_container;
-
-/* accessors */
+- (NSString *) pageJavaScriptURL;
+- (NSString *) productJavaScriptURL;
+- (BOOL) hasPageSpecificJavaScript;
+- (BOOL) hasProductSpecificJavaScript;
 
-- (DSoDatabase *)database;
-- (NSString *)tableName;
+- (NSString *) pageCSSURL;
+- (NSString *) productCSSURL;
+- (BOOL) hasPageSpecificCSS;
+- (BOOL) hasProductSpecificCSS;
 
-- (NSString *)hostName;
-- (int)port;
-- (NSString *)databaseName;
+- (NSString *) productFrameworkName;
 
-/* support */
+- (void) setPopup: (BOOL) popup;
+- (BOOL) isPopup;
 
-- (EOAdaptor *)adaptorInContext:(WOContext *)_ctx;
+- (void) setToolbar: (NSString *) newToolbar;
+- (NSString *) toolbar;
 
 @end
 
-#endif /* __dbd_DSoTable_H__ */
+#endif /* UIXPAGEFRAME_H */
index 4845e2283a6a0f9334971a5dbf8c9cf341601262..dfb04557f9b1bf86825f63624cb28e01e20ad049 100644 (file)
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
-
-@interface UIxPageFrame : UIxComponent
-{
-  NSString *title;
-  id       item;
-}
-
-@end
+#import <SOGoUI/UIxComponent.h>
+#import <SOGo/SOGoUser.h>
 
 #include "common.h"
 #include <NGObjWeb/SoComponent.h>
+#include "UIxPageFrame.h"
 
 @implementation UIxPageFrame
 
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      toolbar = nil;
+    }
+
+  return self;
+}
+
 - (void)dealloc {
-  [self->item  release];
-  [self->title release];
+  [item release];
+  [title release];
+  if (toolbar)
+    [toolbar release];
   [super dealloc];
 }
 
 /* accessors */
 
 - (void)setTitle:(NSString *)_value {
-  ASSIGNCOPY(self->title, _value);
+  ASSIGNCOPY(title, _value);
 }
+
 - (NSString *)title {
   if ([self isUIxDebugEnabled])
-    return self->title;
+    return title;
 
-  return [self labelForKey:@"OpenGroupware.org"];
+  return [self labelForKey: @"SOGo"];
 }
 
 - (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
+  ASSIGN(item, _item);
 }
+
 - (id)item {
-  return self->item;
+  return item;
 }
 
 - (NSString *)ownerInContext {
   return [[self clientObject] ownerInContext:[self context]];
 }
 
+- (NSString *) doctype
+{
+  return (@"<?xml version=\"1.0\"?>\n"
+          @"<!DOCTYPE html"
+          @" PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\""
+          @" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
+}
+
 /* Help URL/target */
 
-- (NSString *)helpURL {
-  return [NSString stringWithFormat:@"help/%@.html", self->title];
-}
-- (NSString *)helpWindowTarget {
-  return [NSString stringWithFormat:@"Help_%@", self->title];
+- (NSString *)helpURL
+{
+  return [NSString stringWithFormat: @"help/%@.html", title];
 }
 
+- (NSString *)helpWindowTarget
+{
+  return [NSString stringWithFormat: @"Help_%@", title];
+}
 
 /* notifications */
 
 - (void)sleep {
-  [self->item release]; self->item = nil;
+  [item release];
+  item = nil;
   [super sleep];
 }
 
 /* URL generation */
 // TODO: I think all this should be done by the clientObject?!
 
-- (NSString *)relativeHomePath {
-  return [self relativePathToUserFolderSubPath:@""];
+- (NSString *) relativeHomePath
+{
+  return [self relativePathToUserFolderSubPath: @""];
+}
+
+- (NSString *)relativeCalendarPath
+{
+  return [self relativePathToUserFolderSubPath: @"Calendar/"];
 }
 
-- (NSString *)relativeCalendarPath {
-  return [self relativePathToUserFolderSubPath:@"Calendar/"];
+- (NSString *)relativeContactsPath
+{
+  return [self relativePathToUserFolderSubPath: @"Contacts/"];
 }
 
-- (NSString *)relativeContactsPath {
-  return [self relativePathToUserFolderSubPath:@"Contacts/"];
+- (NSString *)relativeMailPath
+{
+  return [self relativePathToUserFolderSubPath: @"Mail/"];
 }
 
-- (NSString *)relativeMailPath {
-  return [self relativePathToUserFolderSubPath:@"Mail/"];
+- (NSString *)logoffPath
+{
+  return [self relativePathToUserFolderSubPath: @"logoff"];
 }
 
-/* page based JavaScript */
+/* popup handling */
+- (void) setPopup: (BOOL) popup
+{
+  isPopup = popup;
+}
 
-- (WOResourceManager *)pageResourceManager {
-  WOResourceManager *rm;
-  
-  if ((rm = [[[self context] page] resourceManager]) == nil)
-    rm = [[WOApplication application] resourceManager];
-  return rm;
+- (BOOL) isPopup
+{
+  return isPopup;
+}
+
+- (NSString *) bodyClasses
+{
+  return (isPopup ? @"popup" : @"main");
 }
 
-- (NSString *)pageJavaScriptURL {
-  static NSMutableDictionary *pageToURL = nil;
-  WOResourceManager *rm;
+/* page based JavaScript */
+
+- (NSString *) pageJavaScriptURL
+{
   WOComponent *page;
-  NSString    *jsname, *pageName;
-  NSString    *url;
+  NSString *pageJSFilename;
   
   page     = [[self context] page];
-  pageName = NSStringFromClass([page class]);
-  // TODO: does not seem to work! (gets reset): pageName = [page name];
-  
-  if ((url = [pageToURL objectForKey:pageName]) != nil)
-    return [url isNotNull] ? url : nil;
-  
-  if (pageToURL == nil)
-    pageToURL = [[NSMutableDictionary alloc] initWithCapacity:32];
+  pageJSFilename = [NSString stringWithFormat: @"%@.js",
+                            NSStringFromClass([page class])];
+
+  return [self urlForResourceFilename: pageJSFilename];
+}
+
+- (NSString *) productJavaScriptURL
+{
+  WOComponent *page;
+  NSString *fwJSFilename;
+
+  page = [[self context] page];
+  fwJSFilename = [NSString stringWithFormat: @"%@.js",
+                          [page frameworkName]];
   
-  rm     = [self pageResourceManager];
-  jsname = [pageName stringByAppendingString:@".js"];
+  return [self urlForResourceFilename: fwJSFilename];
+}
+
+- (NSString *) productFrameworkName
+{
+  WOComponent *page;
+
+  page = [[self context] page];
+
+  return [NSString stringWithFormat: @"%@.SOGo", [page frameworkName]];
+}
+
+- (BOOL) hasPageSpecificJavaScript
+{
+  return ([[self pageJavaScriptURL] length] > 0);
+}
+
+- (BOOL) hasProductSpecificJavaScript
+{
+  return ([[self productJavaScriptURL] length] > 0);
+}
+
+- (NSString *) pageCSSURL
+{
+  WOComponent *page;
+  NSString *pageJSFilename;
   
-  url = [rm urlForResourceNamed:jsname
-           inFramework:
-             [[NSBundle bundleForClass:[page class]] bundlePath]
-           languages:nil
-           request:[[self context] request]];
+  page     = [[self context] page];
+  pageJSFilename = [NSString stringWithFormat: @"%@.css",
+                            NSStringFromClass([page class])];
+
+  return [self urlForResourceFilename: pageJSFilename];
+}
+
+- (NSString *) productCSSURL
+{
+  WOComponent *page;
+  NSString *fwJSFilename;
+
+  page = [[self context] page];
+  fwJSFilename = [NSString stringWithFormat: @"%@.css",
+                          [page frameworkName]];
   
-  /* cache */
-  [pageToURL setObject:(url ? url : (id)[NSNull null]) forKey:pageName];
-  return url;
+  return [self urlForResourceFilename: fwJSFilename];
 }
 
-- (BOOL)hasPageSpecificJavaScript {
-  return [[self pageJavaScriptURL] length] > 0 ? YES : NO;
+- (NSString *) thisPageURL
+{
+  return [[[self context] page] uri];
+}
+
+- (BOOL) hasPageSpecificCSS
+{
+  return ([[self pageCSSURL] length] > 0);
+}
+
+- (BOOL) hasProductSpecificCSS
+{
+  return ([[self productCSSURL] length] > 0);
+}
+
+- (void) setToolbar: (NSString *) newToolbar
+{
+  ASSIGN (toolbar, newToolbar);
+}
+
+- (NSString *) toolbar
+{
+  return toolbar;
 }
 
 @end /* UIxPageFrame */
similarity index 83%
rename from UI/MailerUI/UIxMailSortableTableHeader.m
rename to UI/Common/UIxSortableTableHeader.m
index f7cbc4b9751da21d03f8d7f8176f8c6063824d37..66862523943cd577852f5e94930d1aa2973f03dc 100644 (file)
@@ -22,7 +22,7 @@
 #include <NGObjWeb/SoComponent.h>
 
 /*
-  UIxMailSortableTableHeader
+  UIxSortableTableHeader
 
   TODO: document.
 
@@ -30,7 +30,7 @@
         works!
 */
 
-@interface UIxMailSortableTableHeader : SoComponent
+@interface UIxSortableTableHeader : SoComponent
 {
   NSString     *label;
   NSString     *sortKey;
@@ -43,7 +43,7 @@
 
 #include "common.h"
 
-@implementation UIxMailSortableTableHeader
+@implementation UIxSortableTableHeader
 
 - (void)dealloc {
   [self->label           release];
@@ -65,6 +65,7 @@
 - (void)setSortKey:(NSString *)_sortKey {
   ASSIGNCOPY(self->sortKey, _sortKey);
 }
+
 - (NSString *)sortKey {
   return self->sortKey;
 }
 
 /* derived accessors */
 
-- (BOOL)isSelected {
+- (BOOL) isSelected
+{
   NSString *so;
-  
-  if ((so = [self singleQueryValueForKey:@"sort"]) == nil)
-    return self->isDefault;
-  
-  return [so isEqualToString:self->sortKey];
+  so = [self singleQueryValueForKey:@"sort"];
+
+  return ((so)
+          ? [so isEqualToString:self->sortKey]
+          : isDefault);
 }
 
-- (BOOL)isSortedDescending {
+- (BOOL)isSortedDescending
+{
   NSString *desc;
 
-  if ((desc = [self singleQueryValueForKey:@"desc"]) == nil)
-    return NO;
-  
-  return [desc boolValue];
+  desc = [[[self context] request] formValueForKey:@"desc"];
+
+  return ((desc)
+          ? [desc boolValue]
+          : YES);
 }
 
-@end /* UIxMailSortableTableHeader */
+@end /* UIxSortableTableHeader */
similarity index 54%
rename from UI/MailerUI/UIxMailToolbar.m
rename to UI/Common/UIxToolbar.m
index bc7bd7defb18b1c3368352d77e540a358c8b2d90..c36eaece2964b987aeddcb6f15f2044c6ae5c16b 100644 (file)
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
+#import <Foundation/NSKeyValueCoding.h>
+#import <NGExtensions/NGExtensions.h>
+#import <NGObjWeb/NGObjWeb.h>
+#import <NGObjWeb/SoObjects.h>
+
+#import <SOGoUI/UIxComponent.h>
+
+#import <NGObjWeb/SoComponent.h>
 
 @class NSArray, NSDictionary;
 
-@interface UIxMailToolbar : UIxComponent
+@interface UIxToolbar : UIxComponent
 {
   NSArray      *toolbarConfig;
   NSArray      *toolbarGroup;
+  NSString *toolbar;
   NSDictionary *buttonInfo;
 }
+
+- (void) setToolbar: (NSString *) newToolbar;
+- (NSString *) toolbar;
+
 @end
 
-#include <SoObjects/Mailer/SOGoMailBaseObject.h>
-#include "common.h"
-#include <NGObjWeb/SoComponent.h>
+@implementation UIxToolbar
 
-@implementation UIxMailToolbar
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      toolbar = nil;
+    }
+
+  return self;
+}
 
 - (void)dealloc {
-  [self->toolbarGroup  release];
-  [self->toolbarConfig release];
-  [self->buttonInfo    release];
+  [toolbarGroup  release];
+  [toolbarConfig release];
+  [buttonInfo    release];
+  if (toolbar)
+    [toolbar release];
   [super dealloc];
 }
 
 /* notifications */
 
 - (void)sleep {
-  [self->toolbarGroup  release]; self->toolbarGroup  = nil;
-  [self->toolbarConfig release]; self->toolbarConfig = nil;
-  [self->buttonInfo    release]; self->buttonInfo    = nil;
+  [toolbarGroup  release]; toolbarGroup  = nil;
+  [toolbarConfig release]; toolbarConfig = nil;
+  [buttonInfo    release]; buttonInfo    = nil;
   [super sleep];
 }
 
 /* accessors */
 
 - (void)setToolbarGroup:(id)_group {
-  ASSIGN(self->toolbarGroup, _group);
+  ASSIGN(toolbarGroup, _group);
 }
+
 - (id)toolbarGroup {
-  return self->toolbarGroup;
+  return toolbarGroup;
 }
 
 - (void)setButtonInfo:(id)_info {
-  ASSIGN(self->buttonInfo, _info);
+  ASSIGN(buttonInfo, _info);
 }
+
 - (id)buttonInfo {
-  return self->buttonInfo;
+  return buttonInfo;
 }
 
 /* toolbar */
   return [[self application] resourceManager];
 }
 
+- (id) pathToResourceNamed: (NSString *) name
+{
+  WOResourceManager *rm;
+  NSRange  r;
+  NSString *fw, *rn;
+
+  r = [name rangeOfString: @"/"];
+  if (r.length > 0)
+    {
+      fw = [name substringToIndex: r.location];
+      rn = [name substringFromIndex: (r.location + r.length)];
+    }
+  else
+    {
+      rn = name;
+      fw = nil;
+    }
+  
+  rm = [self pageResourceManager];
+
+  return [rm pathForResourceNamed: rn inFramework: fw 
+            languages: [[self context] resourceLookupLanguages]];
+}
+
 - (id)loadToolbarConfigFromResourceNamed:(NSString *)_name {
   /*
     Note: we cannot cache by name because we don't know how the resource
          cache the parsed content for a given path;
   */
   static NSMutableDictionary *pathToConfig = nil;
-  WOResourceManager *rm;
   NSDictionary *tb;
-  NSRange  r;
-  NSString *fw, *rn, *path;
+  NSString *path;
 
-  r = [_name rangeOfString:@"/"];
-  if (r.length > 0) {
-    fw = [_name substringToIndex:r.location];
-    rn = [_name substringFromIndex:(r.location + r.length)];
-  }
-  else {
-    rn = _name;
-    fw = nil;
-  }
-  
-  rm   = [self pageResourceManager];
-  path = [rm pathForResourceNamed:rn inFramework:fw 
-            languages:[[self context] resourceLookupLanguages]];
+  path = [self pathToResourceNamed: _name];
   if (path == nil) {
     [self errorWithFormat:@"Did not find toolbar resource: %@", _name];
     return nil;
   if (pathToConfig == nil)
     pathToConfig = [[NSMutableDictionary alloc] initWithCapacity:32];
   [pathToConfig setObject:(tb ? tb : (id)[NSNull null]) forKey:path];
-  
+
   return tb;
 }
 
 - (id)toolbarConfig {
   id tb;
   
-  if (self->toolbarConfig != nil)
-    return [self->toolbarConfig isNotNull] ? self->toolbarConfig : nil;
+  if (toolbarConfig != nil)
+    return [toolbarConfig isNotNull] ? toolbarConfig : nil;
   
-  tb = [[self clientObject] lookupName:@"toolbar" inContext:[self context]
-                           acquire:NO];
+  if (toolbar)
+    tb = toolbar;
+  else
+    tb = [[self clientObject] lookupName:@"toolbar" inContext:[self context]
+                              acquire:NO];
+
   if ([tb isKindOfClass:[NSException class]]) {
     [self errorWithFormat:
             @"not toolbar configuration found on SoObject: %@ (%@)",
             [self clientObject], [[self clientObject] soClass]];
-    self->toolbarConfig = [[NSNull null] retain];
+    toolbarConfig = [[NSNull null] retain];
     return nil;
   }
   
   if ([tb isKindOfClass:[NSString class]])
     tb = [self loadToolbarConfigFromResourceNamed:tb];
   
-  self->toolbarConfig = [tb retain];
-  return self->toolbarConfig;
+  toolbarConfig = [tb retain];
+  return toolbarConfig;
 }
 
 /* labels */
 
-- (NSString *)buttonLabel {
-  WOResourceManager *rm;
-  NSString          *key, *label;
-  
-  key = [[self buttonInfo] valueForKey:@"label"];
-  
-  /* lookup resource manager */
-  
-  if ((rm = [self pageResourceManager]) == nil)
-    rm = [[WOApplication application] resourceManager];
-  if (rm == nil)
-    [self warnWithFormat:@"missing resource manager!"];
-  
-  /* lookup string */
+- (NSString *) buttonLabel
+{
+  NSString          *key;
   
-  label = [rm stringForKey:key inTableNamed:nil withDefaultValue:key
-              languages:[[self context] resourceLookupLanguages]];
-  return label;
+  key = [[self buttonInfo] valueForKey: @"label"];
+
+  return [self labelForKey: key];
+}
+
+- (id) buttonImage
+{
+  NSString *image;
+
+  image = [buttonInfo objectForKey: @"image"];
+  if (image && [image length] > 0)
+    image = [self urlForResourceFilename: image];
+
+  return image;
 }
 
 /* enable/disable buttons */
   
   if ((onOffKey = [[self buttonInfo] valueForKey:@"enabled"]) == nil)
     return YES;
-  
+
   return [[[[self context] page] valueForKeyPath:onOffKey] boolValue];
 }
 
-@end /* UIxMailToolbar */
+- (BOOL) isLastGroup {
+  return ([toolbarConfig indexOfObject: toolbarGroup]
+         == ([toolbarConfig count] - 1));
+}
+
+- (BOOL) hasButtons
+{
+  id tbConfig;
+  unsigned int count, max, amount;
+
+  tbConfig = [self toolbarConfig];
+
+  amount = 0;
+  max = [tbConfig count];
+  for (count = 0; count < max; count++)
+    amount += [[tbConfig objectAtIndex: count] count];
+
+  return (amount > 0);
+}
+
+- (void) setToolbar: (NSString *) newToolbar
+{
+  ASSIGN(toolbar, newToolbar);
+}
+
+- (NSString *) toolbar
+{
+  return toolbar;
+}
+
+@end /* UIxToolbar */
diff --git a/UI/Common/UIxUserLogoff.m b/UI/Common/UIxUserLogoff.m
new file mode 100644 (file)
index 0000000..99e407b
--- /dev/null
@@ -0,0 +1,73 @@
+/* UIxUserLogoff.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if LIB_FOUNDATION_LIBRARY
+#  include <Foundation/exceptions/GeneralExceptions.h>
+#elif NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
+#  include <NGExtensions/NGObjectMacros.h>
+#  include <NGExtensions/NSString+Ext.h>
+#endif
+
+#include <NGExtensions/NGExtensions.h>
+#include <NGObjWeb/NGObjWeb.h>
+#include <NGObjWeb/SoObjects.h>
+
+#include <SOGoUI/UIxComponent.h>
+
+@interface UIxUserLogoff : UIxComponent
+{
+}
+
+- (id) logoffUserAction;
+
+@end
+
+@implementation UIxUserLogoff
+
++ (void) initialize
+{
+  [[self soClassSecurityInfo] declareRole: SoRole_Anonymous
+                              asDefaultForPermission: SoPerm_View];
+}
+
+- (id) logoffUserAction
+{
+  WOResponse *r;
+  id auth, context;
+
+//   context = [self context];
+//   auth = [[self clientObject] authenticatorInContext: context];
+
+//   [[self context] setActiveUser: nil];
+
+  r = [[self context] response];
+  [r setStatus: 302];
+  [r setHeader: @"http://www.chnu.ca/"
+     forKey: @"location"];
+  [self reset];
+
+//   return [auth unauthorized: @"Logoff" inContext: context];
+
+  return r;
+}
+
+@end
index bef3edcbb0b44c0a61cc7d2c6e19d5bd03056d33..8061b201d504c8b7e1f57cea4e45cea1505193cd 100644 (file)
@@ -1,38 +1,47 @@
-{
-  requires = ( MAIN );
+{ /* -*-javascript-*- */
+  requires = ( MAIN, Mailer );
 
   publicResources = (
-    calendar.css,
-    uix.css,
-    menu_logo_top.gif,
-    line_left.gif,
-    line_stretch.gif,
-    line_right.gif,
-    box_topleft.gif,
-    box_top.gif,
-    box_topright.gif,
-    box_left.gif,
-    box_right.gif,
-    box_botleft.gif,
-    box_bottom.gif,
-    box_botright.gif,
-    tab_selected.gif,
-    tab_.gif,
-    corner_right.gif,
-    closewindow.gif,
-    OGoLogo.gif,
-    upward_sorted.gif,
-    downward_sorted.gif,
-    non_sorted.gif
-  );
-  
+     calendar.css,
+     uix.css,
+     menu_logo_top.gif,
+     line_left.gif,
+     line_stretch.gif,
+     line_right.gif,
+     box_topleft.gif,
+     box_top.gif,
+     box_topright.gif,
+     box_left.gif,
+     box_right.gif,
+     box_botleft.gif,
+     box_bottom.gif,
+     box_botright.gif,
+     tab_selected.gif,
+     tab_.gif,
+     corner_right.gif,
+     closewindow.gif,
+     OGoLogo.gif,
+     upward_sorted.gif,
+     downward_sorted.gif,
+     non_sorted.gif
+     );
+
   factories = {
   };
 
   categories = {
-    SOGoObject = {
-      methods = {
-      };
-    };
+     SOGoFolder = {
+        methods = {
+           acls = {
+              protectedBy = "ReadAcls";
+              pageName    = "UIxAclEditor";
+           };
+           saveAcls = {
+              protectedBy = "SaveAcls";
+              pageName    = "UIxAclEditor";
+              actionName = "saveAcls";
+           };
+        };
+     };
   };
 }
index bc42a9679ef0cc00abced04364d53ce30c52eaa5..ec1cc675acc81ea65e26169f1f40d26f75dfb9f7 100644 (file)
@@ -1,31 +1,89 @@
 /* this file is in UTF-8 format! */
 
-"Addressbook"       = "Addressbook";
-"Addresses"         = "Addresses";
-"Cancel"            = "Cancel";
-"Common"            = "Common";
-"Contact editor"    = "Contact Editor";
-"Contact viewer"    = "Contact Viewer";
-"Copy from Anais"   = "Copy from Anaïs";
-"EMail"             = "Email";
-"Extended"          = "Extended";
-"Fax"               = "Fax";
-"Firstname"         = "Firstname";
-"Home"              = "Home";
-"HomePhone"         = "Home";
-"Lastname"          = "Lastname";
-"Location"          = "Location";
-"MobilePhone"       = "Mobile";
-"Name"              = "Name";
-"OfficePhone"       = "Office";
-"Organisation"      = "Organisation";
-"Phone"             = "Phone";
-"Phones"            = "Phone numbers";
-"Postal"            = "Postal";
-"Save"              = "Save";
-"URL"               = "URL";
-"Unit"              = "Unit";
-"delete"            = "delete";
-"edit"              = "edit";
-"invalidemailwarn"  = "Invalid email field, continue?";
-"new"               = "new";
+"Addressbook" = "Addressbook";
+"Addresses" = "Addresses";
+"Cancel" = "Cancel";
+"Common" = "Common";
+"Contact editor" = "Contact editor";
+"Contact viewer" = "Contact viewer";
+"Copy from Anais" = "Copy from Anais";
+"EMail" = "EMail";
+"Extended" = "Extended";
+"Fax" = "Fax";
+"Firstname" = "Firstname";
+"Home" = "Home";
+"HomePhone" = "HomePhone";
+"Lastname" = "Lastname";
+"Location" = "Location";
+"MobilePhone" = "MobilePhone";
+"Name" = "Name";
+"OfficePhone" = "OfficePhone";
+"Organisation" = "Organisation";
+"Phone" = "Phone";
+"Phones" = "Phones";
+"Postal" = "Postal";
+"Save" = "Save";
+"URL" = "URL";
+"Unit" = "Unit";
+"delete" = "delete";
+"edit" = "edit";
+"invalidemailwarn" = "invalidemailwarn";
+"new" = "new";
+
+"Name or Address" = "Name or Address";
+"Personal Addressbook" = "Personal Addressbook";
+"Search in Addressbook" = "Search in Addressbook";
+
+"New Card" = "New Card";
+"New List" = "New List";
+"Modify" = "Modify";
+"Access Rights..." = "Access Rights...";
+"Write" = "Write";
+"Delete" = "Delete";
+"Instant Message" = "Instant Message";
+"Add..." = "Add...";
+"Remove" = "Remove";
+
+"Preferred" = "Preferred";
+"Card for %@" = "Card for %@";
+"Display Name: " = "Display Name: ";
+"Email Address: " = "Email Address: "
+
+"Firstname: " = "Firstname: ";
+"Lastname: " = "Lastname: ";
+"Nickname: " = "Nickname: ";
+
+"Telephone" = "Telephone";
+"Work: " = "Work: ";
+"Home: " = "Home: ";
+"Fax: " = "Fax: ";
+"Mobile: " = "Mobile: ";
+"Pager: " = "Pager: ";
+
+"Title: " = "Title: ";
+"Service: " = "Service: ";
+"Company: " = "Company: ";
+"Street Address: " = "Street Address: ";
+"City: " = "City: ";
+"Province: " = "Province: ";
+"Zip or Postal Code: " = "Zip or Postal Code: ";
+"Country: " = "Country: ";
+"Web: " = "Web: ";
+
+"Work" = "Work";
+"Other Infos" = "Other Infos";
+
+"Note: " = "Note: ";
+"Timezone: " = "Timezone: ";
+"Birthday: " = "Birthday: ";
+
+"Add as..." = "Add as...";
+"Recipient" = "Recipient";
+"Carbon Copy" = "Carbon Copy";
+"Blind Carbon Copy" = "Blind Carbon Copy";
+"Add Attendee..." = "Add Attendee...";
+"Add Assistant" = "Add Assistant";
+"Add Delegate" = "Add Delegate";
+
+"Add an Addressbook..." = "Add an Addressbook...";
+"Remove the selected Addressbook" = "Remove the selected Addressbook";
index 00ccd6700b0407d680f2cbf67635eb82ada4d1da..ae004fa63deaa3e141b42c2ba8c6bf441ad3848d 100644 (file)
@@ -1,17 +1,15 @@
 /* this file is in UTF-8 format! */
 
-"Addressbook"       = "Carnet d'adresse";
+"Address Books"      = "Carnet d'adresses";
 "Addresses"         = "Adresses";
 "Cancel"            = "Annuler";
 "Common"            = "Identité";
-"Contact editor"    = "Editer le contact";
+"Contact editor"    = "Éditer le contact";
 "Contact viewer"    = "Visualiser le contact";
-"Copy from Anais"    = "Ajouter depuis Anaïs";
 "EMail"             = "Courriel";
 "Extended"          = "Informations complémentaires";
 "Fax"               = "Fax";
 "Firstname"         = "Prénom";
-"Home"              = "Personnelle";
 "HomePhone"         = "Domicile";
 "Lastname"          = "Nom";
 "Location"          = "Lieux";
 "Name"              = "Nom";
 "OfficePhone"       = "Bureau";
 "Organisation"      = "Société";
-"Phone"             = "Téléphone"  
+"Phone"             = "Téléphone";
 "Phones"            = "Téléphones";
 "Postal"            = "Professionnelle";
 "Save"              = "Sauvegarder";
 "URL"               = "URL";
 "Unit"              = "Département";
 "delete"            = "Effacer";
-"edit"              = "Editer";
+"edit"              = "Éditer";
 "invalidemailwarn"  = "Champ de l'email invalide, continuer quand même ?";
 "new"               = "Nouveau";
+
+"Name or Address" = "Le nom ou l'adresse";
+"Personal Addressbook" = "Adresses personnelles";
+"Search in Addressbook" = "Carnet d'adresses...";
+
+"New Card" = "Nouvelle fiche";
+"New List" = "Nouvelle liste";
+"Modify" = "Modifier";
+"Access Rights..." = "Partage...";
+"Write" = "Écrire";
+"Delete" = "Effacer";
+"Instant Message" = "Message instantané";
+"Add..." = "Ajouter...";
+"Remove" = "Enlever";
+
+"Preferred" = "Préféré";
+"Card for %@" = "Fiche pour %@";
+"Display Name: " = "Nom &agrave; afficher : ";
+"Email Address: " = "Adresse &eacute;lectronique : ";
+"Phone Number: " = "Num&eacute;ro de t&eacute;l&eacute;phone : ";
+
+"Firstname: " = "Pr&eacute;nom : ";
+"Lastname: " = "Nom : ";
+"Nickname: " = "Surnom : ";
+
+"Telephone" = "Téléphone";
+"Work: " = "Travail : ";
+"Home: " = "Domicile : ";
+"Fax: " = "T&eacute;l&eacute;copieur : ";
+"Mobile: " = "Portable : ";
+"Pager: " = "T&eacute;l&eacute;avertisseur : ";
+
+"Title: " = "Titre/fonction : ";
+"Service: " = "Service : ";
+"Company: " = "Entreprise : ";
+"Street Address: " = "Adresse : ";
+"City: " = "Ville : ";
+"Province: " = "Province : ";
+"Zip or Postal Code: " = "Code postal : ";
+"Country: " = "Pays : ";
+"Web: " = "Adresse web : ";
+
+"Home" = "Domicile";
+"Work" = "Travail";
+"Other Infos" = "Informations complémentaires";
+
+"Note: " = "Commentaires : ";
+"Timezone: " = "Fuseau horaire : ";
+"Birthday: " = "D. de naissance : ";
+
+"Add as..." = "Ajouter...";
+"Recipient" = "Destinataire";
+"Carbon Copy" = "Copie carbone";
+"Blind Carbon Copy" = "C. carbone cachée";
+"Add Attendee..." = "Ajouter participant...";
+"Add Calendar..." = "Ajouter agenda...";
+"Add Address Book..." = "Ajouter carnet...";
+"Add Assistant" = "Ajouter comme assistant";
+"Add Delegate" = "Ajouter comme délégué";
+
+"Add an Addressbook..." = "Ajouter un carnet d'adresses...";
+"Remove the selected Addressbook" = "Enlever le carnet d'adresses sélectionné";
index 43c6dcb196a7343c67d174009d3a2e4559ce4e54..2c8b9a36f948fc28f9e2686cc93fe1c35035a92c 100644 (file)
@@ -9,20 +9,27 @@ ContactsUI_PRINCIPAL_CLASS = ContactsUIProduct
 ContactsUI_LANGUAGES = English French
 
 ContactsUI_OBJC_FILES =                        \
-       UIxContactsListViewBase.m       \
-       UIxContactEditorBase.m          \
+       UIxContactsAclsSelection.m \
+       UIxContactsAddressBooksSelection.m \
+       UIxContactsCalendarsSelection.m \
+       UIxContactsMailerSelection.m    \
        \
        ContactsUIProduct.m             \
-       UIxContactsSelectionView.m      \
+       UIxContactsFilterPanel.m        \
        UIxContactView.m                \
-       UIxContactSelector.m            \
        UIxContactEditor.m              \
        UIxContactsListView.m           \
+       UIxContactsListViewContainer.m  \
+       UIxContactSelector.m    \
+       UIxContactFoldersView.m         \
 
 ContactsUI_RESOURCE_FILES +=           \
        Version                         \
        product.plist                   \
 
+ContactsUI_RESOURCE_FILES +=           \
+       Toolbars/SOGoContactFolder.toolbar
+
 ContactsUI_LOCALIZED_RESOURCE_FILES += \
        Localizable.strings             \
 
diff --git a/UI/Contacts/Toolbars/SOGoContactFolder.toolbar b/UI/Contacts/Toolbars/SOGoContactFolder.toolbar
new file mode 100644 (file)
index 0000000..2bcf4b6
--- /dev/null
@@ -0,0 +1,29 @@
+( /* the toolbar groups -*-cperl-*- */
+  (
+   { link = "#";
+     jsLink="js_card";
+     label="New Card";
+     image="new-card.png";
+     onclick = "newContact(this); return false;"; },
+   { link = "new_list";
+     enabled = "NO";
+     label="New List";
+     image="new-list.png"; }
+  ),
+  (
+   { link = "edit";
+     label = "Modify";
+     onclick = "return onToolbarEditSelectedContacts(this);";
+     image = "properties.png"; },
+   { link = "write";
+     label="Write";
+     onclick = "return onToolbarWriteToSelectedContacts(this);";
+     image="write.png"; }
+  ),
+  (
+   { link = "delete";
+     label="Delete";
+     onclick = "return uixDeleteSelectedContacts(this);";
+     image="delete.png"; }
+  )
+)
similarity index 79%
rename from UI/Contacts/UIxContactEditorBase.h
rename to UI/Contacts/UIxContactEditor.h
index af041c69bff7eb83d8d5973cb0480b59f3fa560d..64fc77107d32dda712a3a1876edcb8d26005be6d 100644 (file)
   02111-1307, USA.
 */
 
-#ifndef __UIxContactEditorBase_H__
-#define __UIxContactEditorBase_H__
+#ifndef __UIxContactEditor_H__
+#define __UIxContactEditor_H__
 
 #include <SOGoUI/UIxComponent.h>
 
-@class NSString, NSMutableDictionary;
+@class NSString;
+@class NSMutableDictionary;
 
-@interface UIxContactEditorBase : UIxComponent
+@class NGVCard;
+
+@interface UIxContactEditor : UIxComponent
 {
-  NSString *contentString;
   NSString *errorText;
-  NSString *anaisCN;
+  NSString *preferredEmail;
+  NGVCard *card;
   NSMutableDictionary *snapshot; /* contains the values for editing */
 }
 
 @end
 
-#endif /* __UIxContactEditorBase_H__ */
+#endif /* __UIxContactEditor_H__ */
index 45c576891b30dfd8514ade93f6993d471a05f405..275e68a253ced7564bbf7367019cfdb989a12d0d 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxContactEditorBase.h"
+#import <NGCards/NGVCard.h>
+#import <NGCards/NSArray+NGCards.h>
 
-@interface UIxContactEditor : UIxContactEditorBase
-@end
+#import <NGObjWeb/SoObject.h>
+
+#import <Contacts/SOGoContactObject.h>
+#import <Contacts/SOGoContactFolder.h>
+#import "common.h"
+
+#import "UIxContactEditor.h"
 
 @implementation UIxContactEditor
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      snapshot = [[NSMutableDictionary alloc] initWithCapacity:16];
+      preferredEmail = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [snapshot      release];
+  [errorText     release];
+  [super dealloc];
+}
+
+/* accessors */
+
+- (void) setErrorText: (NSString *) _txt
+{
+  ASSIGNCOPY(errorText, _txt);
+}
+
+- (NSString *) errorText
+{
+  return errorText;
+}
+
+- (BOOL) hasErrorText
+{
+  return [errorText length] > 0 ? YES : NO;
+}
+
+/* load/store content format */
+
+- (void)_fixupSnapshot {
+  // TODO: perform sanity checking, eg build CN on demand
+  NSString *cn, *gn, *sn;
+  
+  cn = [snapshot objectForKey:@"cn"];
+  gn = [snapshot objectForKey:@"givenName"];
+  sn = [snapshot objectForKey:@"sn"];
+  
+  if (![sn isNotNull] || [sn length] == 0)
+    sn = nil;
+  if (![cn isNotNull] || [cn length] == 0)
+    cn = nil;
+  
+  if (sn == nil) {
+    if (cn == nil)
+      sn = @"[noname]";
+    else {
+      // TODO: need a better name parser here
+      NSRange r;
+      
+      r = [cn rangeOfString:@" "];
+      sn = (r.length > 0)
+       ? [cn substringFromIndex:(r.location + r.length)]
+       : cn;
+    }
+    [snapshot setObject:sn forKey:@"sn"];
+  }
+  if (sn == nil && gn == nil)
+    cn = @"[noname]";
+  else if (sn == nil)
+    cn = gn;
+  else if (gn == nil)
+    cn = sn;
+  else
+    cn = [[gn stringByAppendingString:@" "] stringByAppendingString:sn];
+  [snapshot setObject:cn forKey:@"cn"];
+}
+
+/* helper */
+
+- (NSString *)_completeURIForMethod:(NSString *)_method {
+  // TODO: this is a DUP of UIxAppointmentEditor
+  NSString *uri;
+  NSRange r;
+    
+  uri = [[[self context] request] uri];
+    
+  /* first: identify query parameters */
+  r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
+  if (r.length > 0)
+    uri = [uri substringToIndex:r.location];
+    
+  /* next: append trailing slash */
+  if (![uri hasSuffix:@"/"])
+    uri = [uri stringByAppendingString:@"/"];
+  
+  /* next: append method */
+  uri = [uri stringByAppendingString:_method];
+    
+  /* next: append query parameters */
+  return [self completeHrefForMethod:uri];
+}
+
+/* actions */
+
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq
+                           inContext: (WOContext*) _c
+{
+  return YES;
+}
+
+- (void) _setSnapshotValue: (NSString *) key
+                        to: (NSString *) aValue
+{
+  if (!aValue)
+    aValue = @"";
+
+  [snapshot setObject: aValue forKey: key];
+}
+
+- (NSMutableDictionary *) snapshot
+{
+  return snapshot;
+}
+
+- (NSString *) _simpleValueForType: (NSString *) aType
+                           inArray: (NSArray *) anArray
+{
+  NSArray *elements;
+  NSString *value;
+
+  elements = [anArray cardElementsWithAttribute: @"type"
+                      havingValue: aType];
+  if ([elements count] > 0)
+    value = [[elements objectAtIndex: 0] value: 0];
+  else
+    value = nil;
+
+  return value;
+}
+
+- (void) _setupEmailFields
+{
+  NSArray *elements;
+  NSString *workMail, *homeMail, *prefMail, *potential;
+  unsigned int max;
+
+  elements = [card childrenWithTag: @"email"];
+  max = [elements count];
+  workMail = [self _simpleValueForType: @"work"
+                   inArray: elements];
+  homeMail = [self _simpleValueForType: @"home"
+                   inArray: elements];
+  prefMail = [self _simpleValueForType: @"pref"
+                   inArray: elements];
+
+  if (max > 0)
+    {
+      potential = [[elements objectAtIndex: 0] value: 0];
+      if (!workMail)
+        {
+          if (homeMail && homeMail == potential && max > 1)
+            workMail = [[elements objectAtIndex: 1] value: 0];
+          else
+            workMail = potential;
+        }
+      if (!homeMail && max > 1)
+        {
+          if (workMail && workMail == potential)
+            homeMail = [[elements objectAtIndex: 1] value: 0];
+          else
+            homeMail = potential;
+        }
+
+      if (prefMail)
+        {
+          if (prefMail == workMail)
+            preferredEmail = @"work";
+          else if (prefMail == homeMail)
+            preferredEmail = @"home";
+        }
+    }
+
+  [self _setSnapshotValue: @"workMail" to: workMail];
+  [self _setSnapshotValue: @"homeMail" to: homeMail];
+}
+
+- (void) _setupOrgFields
+{
+  NSArray *org, *orgServices;
+  NSRange aRange;
+  unsigned int max;
+
+  org = [card org];
+  max = [org count];
+  if (max > 0)
+    {
+      [self _setSnapshotValue: @"workCompany" to: [org objectAtIndex: 0]];
+      if (max > 1)
+        {
+          aRange = NSMakeRange (1, max - 1);
+          orgServices = [org subarrayWithRange: aRange];
+          [self _setSnapshotValue: @"workService"
+                to: [orgServices componentsJoinedByString: @", "]];
+        }
+    }
+}
+
+- (NSString *) preferredEmail
+{
+  return preferredEmail;
+}
+
+- (void) setPreferredEmail: (NSString *) aString
+{
+  preferredEmail = aString;
+}
+
+- (void) _retrieveQueryParameter: (NSString *) queryKey
+               intoSnapshotValue: (NSString *) snapshotKey
+{
+  NSString *queryValue;
+
+  queryValue = [self queryParameterForKey: queryKey];
+  if (queryValue && [queryValue length] > 0)
+    [self _setSnapshotValue: snapshotKey to: queryValue];
+}
+
+- (void) initSnapshot
+{
+  NSArray *n, *elements;
+  CardElement *element;
+  unsigned int max;
+
+  n = [card n];
+  if (n)
+    {
+      max = [n count];
+      if (max > 0)
+        {
+          [self _setSnapshotValue: @"sn" to: [n objectAtIndex: 0]];
+          if (max > 1)
+            [self _setSnapshotValue: @"givenName" to: [n objectAtIndex: 1]];
+        }
+    }
+  [self _setSnapshotValue: @"fn" to: [card fn]];
+  [self _setSnapshotValue: @"nickname" to: [card nickname]];
+
+  elements = [card childrenWithTag: @"tel"];
+  [self _setSnapshotValue: @"telephoneNumber"
+        to: [self _simpleValueForType: @"work" inArray: elements]];
+  [self _setSnapshotValue: @"homeTelephoneNumber"
+        to: [self _simpleValueForType: @"home" inArray: elements]];
+  [self _setSnapshotValue: @"mobile"
+        to: [self _simpleValueForType: @"cell" inArray: elements]];
+  [self _setSnapshotValue: @"facsimileTelephoneNumber"
+        to: [self _simpleValueForType: @"fax" inArray: elements]];
+  [self _setSnapshotValue: @"pager"
+        to: [self _simpleValueForType: @"pager" inArray: elements]];
+
+  [self _setupEmailFields];
+
+  elements = [card childrenWithTag: @"adr"
+                   andAttribute: @"type" havingValue: @"work"];
+  if (elements && [elements count] > 0)
+    {
+      element = [elements objectAtIndex: 0];
+      [self _setSnapshotValue: @"workStreetAddress"
+            to: [element value: 2]];
+      [self _setSnapshotValue: @"workCity"
+            to: [element value: 3]];
+      [self _setSnapshotValue: @"workState"
+            to: [element value: 4]];
+      [self _setSnapshotValue: @"workPostalCode"
+            to: [element value: 5]];
+      [self _setSnapshotValue: @"workCountry"
+            to: [element value: 6]];
+    }
+
+  elements = [card childrenWithTag: @"adr"
+                   andAttribute: @"type" havingValue: @"home"];
+  if (elements && [elements count] > 0)
+    {
+      element = [elements objectAtIndex: 0];
+      [self _setSnapshotValue: @"homeStreetAddress"
+            to: [element value: 2]];
+      [self _setSnapshotValue: @"homeCity"
+            to: [element value: 3]];
+      [self _setSnapshotValue: @"homeState"
+            to: [element value: 4]];
+      [self _setSnapshotValue: @"homePostalCode"
+            to: [element value: 5]];
+      [self _setSnapshotValue: @"homeCountry"
+            to: [element value: 6]];
+    }
+
+  elements = [card childrenWithTag: @"url"];
+  [self _setSnapshotValue: @"workURL"
+        to: [self _simpleValueForType: @"work" inArray: elements]];
+  [self _setSnapshotValue: @"homeURL"
+        to: [self _simpleValueForType: @"home" inArray: elements]];
+
+  [self _setSnapshotValue: @"title" to: [card title]];
+  [self _setupOrgFields];
+
+  [self _setSnapshotValue: @"bday" to: [card bday]];
+  [self _setSnapshotValue: @"tz" to: [card tz]];
+  [self _setSnapshotValue: @"note" to: [card note]];
+
+  [self  _retrieveQueryParameter: @"contactEmail"
+         intoSnapshotValue: @"workMail"];
+  [self  _retrieveQueryParameter: @"contactFN"
+         intoSnapshotValue: @"fn"];
+}
+
+- (id <WOActionResults>) defaultAction
+{
+  card = [[self clientObject] vCard];
+  if (card)
+    [self initSnapshot];
+  else
+    return [NSException exceptionWithHTTPStatus:404 /* Not Found */
+                        reason:@"could not open contact"];
+
+  return self;
+}
+
+- (NSString *) viewActionName
+{
+  /* this is overridden in the mail based contacts UI to redirect to tb.edit */
+  return @"";
+}
+
+- (NSString *) editActionName
+{
+  /* this is overridden in the mail based contacts UI to redirect to tb.edit */
+  return @"edit";
+}
+
+- (CardElement *) _elementWithTag: (NSString *) tag
+                           ofType: (NSString *) type
+{
+  NSArray *elements;
+  CardElement *element;
+
+  elements = [card childrenWithTag: tag
+                   andAttribute: @"type" havingValue: type];
+  if ([elements count] > 0)
+    element = [elements objectAtIndex: 0];
+  else
+    {
+      element = [CardElement new];
+      [element autorelease];
+      [element setTag: tag];
+      [element addType: type];
+      [card addChild: element];
+    }
+
+  return element;
+}
+
+- (void) _savePhoneValues
+{
+  CardElement *phone;
+
+  phone = [self _elementWithTag: @"tel" ofType: @"work"];
+  [phone setValue: 0 to: [snapshot objectForKey: @"telephoneNumber"]];
+  phone = [self _elementWithTag: @"tel" ofType: @"home"];
+  [phone setValue: 0 to: [snapshot objectForKey: @"homeTelephoneNumber"]];
+  phone = [self _elementWithTag: @"tel" ofType: @"cell"];
+  [phone setValue: 0 to: [snapshot objectForKey: @"mobile"]];
+  phone = [self _elementWithTag: @"tel" ofType: @"fax"];
+  [phone setValue: 0
+         to: [snapshot objectForKey: @"facsimileTelephoneNumber"]];
+  phone = [self _elementWithTag: @"tel" ofType: @"pager"];
+  [phone setValue: 0
+         to: [snapshot objectForKey: @"pager"]];
+}
+
+- (void) _saveEmails
+{
+  CardElement *workMail, *homeMail;
+
+  workMail = [self _elementWithTag: @"email" ofType: @"work"];
+  [workMail setValue: 0 to: [snapshot objectForKey: @"workMail"]];
+  homeMail = [self _elementWithTag: @"email" ofType: @"home"];
+  [homeMail setValue: 0 to: [snapshot objectForKey: @"homeMail"]];
+  if (preferredEmail)
+    {
+      if ([preferredEmail isEqualToString: @"work"])
+        [card setPreferred: workMail];
+      else
+        [card setPreferred: homeMail];
+    }
+}
+
+- (void) _saveSnapshot
+{
+  CardElement *element;
+
+  [card setNWithFamily: [snapshot objectForKey: @"sn"]
+        given: [snapshot objectForKey: @"givenName"]
+        additional: nil
+        prefixes: nil
+        suffixes: nil];
+  [card setNickname: [snapshot objectForKey: @"nickname"]];
+  [card setFn: [snapshot objectForKey: @"fn"]];
+  [card setTitle: [snapshot objectForKey: @"title"]];
+  [card setBday: [snapshot objectForKey: @"bday"]];
+  [card setNote: [snapshot objectForKey: @"note"]];
+  [card setTz: [snapshot objectForKey: @"tz"]];
+
+  element = [self _elementWithTag: @"adr" ofType: @"home"];
+  [element setValue: 2 to: [snapshot objectForKey: @"homeStreetAddress"]];
+  [element setValue: 3 to: [snapshot objectForKey: @"homeCity"]];
+  [element setValue: 4 to: [snapshot objectForKey: @"homeState"]];
+  [element setValue: 5 to: [snapshot objectForKey: @"homePostalCode"]];
+  [element setValue: 6 to: [snapshot objectForKey: @"homeCountry"]];
+
+  element = [self _elementWithTag: @"adr" ofType: @"work"];
+  [element setValue: 2 to: [snapshot objectForKey: @"workStreetAddress"]];
+  [element setValue: 3 to: [snapshot objectForKey: @"workCity"]];
+  [element setValue: 4 to: [snapshot objectForKey: @"workState"]];
+  [element setValue: 5 to: [snapshot objectForKey: @"workPostalCode"]];
+  [element setValue: 6 to: [snapshot objectForKey: @"workCountry"]];
+
+  [self _savePhoneValues];
+  [self _saveEmails];
+}
+
+- (id <WOActionResults>) saveAction
+{
+  id <SOGoContactObject> contact;
+  id result;
+  NSString *jsRefreshMethod;
+
+  contact = [self clientObject];
+  card = [contact vCard];
+  if (card)
+    {
+      [self _saveSnapshot];
+      [contact save];
+
+      if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
+        result = [self redirectToLocation: [self applicationPath]];
+      else
+        {
+          jsRefreshMethod
+            = [NSString stringWithFormat: @"refreshContacts(\"%@\")",
+                        [contact nameInContainer]];
+          result = [self jsCloseWithRefreshMethod: jsRefreshMethod];
+        }
+    }
+  else
+    result = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
+                          reason: @"method cannot be invoked on "
+                          @"the specified object"];
+
+  return result;
+}
+
+- (id) writeAction
+{
+  NSString *email, *url;
+
+  card = [[self clientObject] vCard];
+  [self initSnapshot];
+  if ([preferredEmail isEqualToString: @"home"])
+    email = [snapshot objectForKey: @"homeMail"];
+  else
+    email = [snapshot objectForKey: @"workMail"];
+
+  if (email)
+    url = [NSString stringWithFormat: @"Mail/compose?mailto=%@", email];
+  else
+    url = @"Mail/compose";
+
+  return
+    [self redirectToLocation: [self relativePathToUserFolderSubPath: url]];
+}
+
+- (id)newAction {
+  // TODO: this is almost a DUP of UIxAppointmentEditor
+  /*
+    This method creates a unique ID and redirects to the "edit" method on the
+    new ID.
+    It is actually a folder method and should be defined on the folder.
+    
+    Note: 'clientObject' is the SOGoAppointmentFolder!
+          Update: remember that there are group folders as well.
+  */
+  NSString *uri, *objectId, *nextMethod;
+  id <SOGoContactFolder> co;
+
+  co = [self clientObject];
+  if ([[co class] respondsToSelector: @selector (globallyUniqueObjectId)])
+    objectId = [[[self clientObject] class] globallyUniqueObjectId];
+  else
+    objectId = nil;
+
+  if ([objectId length] == 0)
+    return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
+                        reason:@"could not create a unique ID"];
+
+  nextMethod = [NSString stringWithFormat:@"../%@/%@", 
+                          objectId, [self editActionName]];
+  uri = [self _completeURIForMethod:nextMethod];
+  return [self redirectToLocation:uri];
+}
+
 @end /* UIxContactEditor */
diff --git a/UI/Contacts/UIxContactEditorBase.m b/UI/Contacts/UIxContactEditorBase.m
deleted file mode 100644 (file)
index 80ff009..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "UIxContactEditorBase.h"
-#include <Contacts/SOGoContactObject.h>
-#include <Contacts/SOGoContactFolder.h>
-#include "common.h"
-
-@implementation UIxContactEditorBase
-
-- (id)init {
-  if ((self = [super init])) {
-    self->snapshot = [[NSMutableDictionary alloc] initWithCapacity:16];
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->snapshot      release];
-  [self->anaisCN      release];
-  [self->errorText     release];
-  [self->contentString release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (void)setContentString:(NSString *)_cstr {
-  ASSIGNCOPY(self->contentString, _cstr);
-}
-- (NSString *)contentString {
-  return self->contentString;
-}
-
-- (NSString *)contentStringTemplate {
-  return @"{}"; /* empty property list */
-}
-
-- (NSMutableDictionary *)snapshot {
-  return self->snapshot;
-}
-
-- (void)setErrorText:(NSString *)_txt {
-  ASSIGNCOPY(self->errorText, _txt);
-}
-- (NSString *)errorText {
-  return self->errorText;
-}
-
-- (BOOL)hasErrorText {
-  return [self->errorText length] > 0 ? YES : NO;
-}
-
-
-- (void)setAnaisCN:(NSString *)_txt {
-  ASSIGNCOPY(self->anaisCN, _txt);
-}
-- (NSString *)anaisCN {
-  return self->anaisCN;
-}
-
-
-/* load/store content format */
-
-- (void)loadValuesFromContentString:(NSString *)_s {
-  NSDictionary *plist;
-
-  if ([_s hasPrefix:@"BEGIN:VCARD"]) {
-    // TODO: load vCard values
-    [self errorWithFormat:@"Editing of vCard's is not yet supported!"];
-    return;
-  }
-  
-  if ((plist = [_s propertyList]) == nil) {
-    [self errorWithFormat:@"could not parse content string!"];
-    return;
-  }
-  
-  [self->snapshot removeAllObjects];
-  [self->snapshot addEntriesFromDictionary:plist];
-}
-
-- (void)_fixupSnapshot {
-  // TODO: perform sanity checking, eg build CN on demand
-  NSString *cn, *gn, *sn;
-  
-  cn = [self->snapshot objectForKey:@"cn"];
-  gn = [self->snapshot objectForKey:@"givenName"];
-  sn = [self->snapshot objectForKey:@"sn"];
-  
-  if (![sn isNotNull] || [sn length] == 0)
-    sn = nil;
-  if (![cn isNotNull] || [cn length] == 0)
-    cn = nil;
-  
-  if (sn == nil) {
-    if (cn == nil)
-      sn = @"[noname]";
-    else {
-      // TODO: need a better name parser here
-      NSRange r;
-      
-      r = [cn rangeOfString:@" "];
-      sn = (r.length > 0)
-       ? [cn substringFromIndex:(r.location + r.length)]
-       : cn;
-    }
-    [self->snapshot setObject:sn forKey:@"sn"];
-  }
-  if ([self->anaisCN length] > 0 )
-    cn = self->anaisCN;
-  else if (sn == nil && gn == nil)
-    cn = @"[noname]";
-  else if (sn == nil)
-    cn = gn;
-  else if (gn == nil)
-    cn = sn;
-  else
-    cn = [[gn stringByAppendingString:@" "] stringByAppendingString:sn];
-  [self->snapshot setObject:cn forKey:@"cn"];
-}
-
-- (void)saveValuesIntoRecord:(NSMutableDictionary *)_record {
-  [self _fixupSnapshot];
-  [_record addEntriesFromDictionary:[self snapshot]];
-}
-
-/* helper */
-
-- (NSString *)_completeURIForMethod:(NSString *)_method {
-  // TODO: this is a DUP of UIxAppointmentEditor
-  NSString *uri;
-  NSRange r;
-    
-  uri = [[[self context] request] uri];
-    
-  /* first: identify query parameters */
-  r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
-  if (r.length > 0)
-    uri = [uri substringToIndex:r.location];
-    
-  /* next: append trailing slash */
-  if (![uri hasSuffix:@"/"])
-    uri = [uri stringByAppendingString:@"/"];
-  
-  /* next: append method */
-  uri = [uri stringByAppendingString:_method];
-    
-  /* next: append query parameters */
-  return [self completeHrefForMethod:uri];
-}
-
-/* actions */
-
-- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
-  return YES;
-}
-
-- (id<WOActionResults>)defaultAction {
-  // TODO: very similiar to apt-editor (apt editor would need to use std names
-  NSString *c;
-  
-  /* load iCalendar file */
-  
-  c = [[self clientObject] contentAsString];
-  if ([c length] == 0) /* a new contact */
-    c = [self contentStringTemplate];
-  
-  [self setContentString:c];
-  [self loadValuesFromContentString:c];
-  
-  return self;
-}
-
-- (BOOL)isWriteableClientObject {
-  return [[self clientObject] 
-               respondsToSelector:@selector(saveContentString:)];
-}
-
-- (NSString *)viewActionName {
-  /* this is overridden in the mail based contacts UI to redirect to tb.edit */
-  return @"";
-}
-- (NSString *)editActionName {
-  /* this is overridden in the mail based contacts UI to redirect to tb.edit */
-  return @"edit";
-}
-
-- (id)saveAction {
-  NSException *ex;
-  NSString *recstr, *uri;
-  id record;
-  
-  if (![self isWriteableClientObject]) {
-    return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                        reason:@"method cannot be invoked on "
-                               @"the specified object"];
-  }
-  
-  if ((record = [self contentString]) == nil) {
-    [self setErrorText:@"Missing object content!"]; // localize
-    return self;
-  }
-  record = [[[record propertyList] mutableCopy] autorelease];
-  if (record == nil) {
-    [self setErrorText:@"Invalid property list data ..."]; // localize
-    return self;
-  }
-  
-  [self saveValuesIntoRecord:record];
-  
-  // TODO: directly hacking the content, hm, not so nice or reasonable?
-  recstr = [record description]; // make plist
-  ex = [[self clientObject] saveContentString:recstr];
-  if (ex != nil) {
-    [self setErrorText:[ex reason]];
-    return self;
-  }
-  
-  uri = ([(uri = [self viewActionName]) length] > 0)
-    ? [self viewActionName] : @"..";
-  uri = [self _completeURIForMethod:uri];
-  return [self redirectToLocation:uri];
-}
-
-- (id)testAction {
-  [self logWithFormat:@"test ..."];
-  return self;
-}
-
-- (id)newAction {
-  // TODO: this is almost a DUP of UIxAppointmentEditor
-  /*
-    This method creates a unique ID and redirects to the "edit" method on the
-    new ID.
-    It is actually a folder method and should be defined on the folder.
-    
-    Note: 'clientObject' is the SOGoAppointmentFolder!
-          Update: remember that there are group folders as well.
-  */
-  NSString *uri, *objectId, *nextMethod;
-  
-  objectId = [NSClassFromString(@"SOGoContactFolder") globallyUniqueObjectId];
-  if ([objectId length] == 0) {
-    return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
-                       reason:@"could not create a unique ID"];
-  }
-  
-  nextMethod = [NSString stringWithFormat:@"../%@/%@", 
-                          objectId, [self editActionName]];
-  uri = [self _completeURIForMethod:nextMethod];
-  return [self redirectToLocation:uri];
-}
-
-@end /* UIxContactEditorBase */
diff --git a/UI/Contacts/UIxContactFoldersView.h b/UI/Contacts/UIxContactFoldersView.h
new file mode 100644 (file)
index 0000000..6869821
--- /dev/null
@@ -0,0 +1,32 @@
+/* UIxContactFoldersView.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCONTACTFOLDERSVIEW_H
+#define UIXCONTACTFOLDERSVIEW_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@interface UIxContactFoldersView : UIxComponent
+
+@end
+
+#endif /* UIXCONTACTFOLDERSVIEW_H */
diff --git a/UI/Contacts/UIxContactFoldersView.m b/UI/Contacts/UIxContactFoldersView.m
new file mode 100644 (file)
index 0000000..4219446
--- /dev/null
@@ -0,0 +1,277 @@
+/* UIxContactFoldersView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSString.h>
+
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGObjWeb/SoObject.h>
+#import <NGObjWeb/WOResponse.h>
+
+#import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/SOGo/NSString+Utilities.h>
+#import <SoObjects/Contacts/SOGoContactFolders.h>
+#import <SoObjects/Contacts/SOGoContactFolder.h>
+#import <SoObjects/Contacts/SOGoContactGCSFolder.h>
+
+#import "common.h"
+
+#import "UIxContactFoldersView.h"
+
+@implementation UIxContactFoldersView
+
+- (id) _selectActionForApplication: (NSString *) actionName
+{
+  SOGoContactFolders *folders;
+  NSString *url, *action;
+  WORequest *request;
+
+  folders = [self clientObject];
+  action = [NSString stringWithFormat: @"../%@/%@",
+                     [folders defaultSourceName],
+                     actionName];
+
+  request = [[self context] request];
+
+  url = [[request uri] composeURLWithAction: action
+                       parameters: [self queryParameters]
+                       andHash: NO];
+
+  return [self redirectToLocation: url];
+}
+
+- (id) defaultAction
+{
+  return [self _selectActionForApplication: @"view"];
+}
+
+- (id) newAction
+{
+  return [self _selectActionForApplication: @"new"];
+}
+
+- (id) selectForSchedulerAction
+{
+  return [self _selectActionForApplication: @"scheduler-contacts"];
+}
+
+- (id) selectForMailerAction
+{
+  return [self _selectActionForApplication: @"mailer-contacts"];
+}
+
+- (id) selectForCalendarsAction
+{
+  return [self _selectActionForApplication: @"calendars-contacts"];
+}
+
+- (id) selectForAddressBooksAction
+{
+  return [self _selectActionForApplication: @"addressbooks-contacts"];
+}
+
+- (id) selectForAclsAction
+{
+  return [self _selectActionForApplication: @"acls-contacts"];
+}
+
+- (NSArray *) _searchResults: (NSString *) contact
+{
+  NSMutableArray *results;
+  SOGoContactFolders *topFolder;
+  NSEnumerator *sogoContactFolders;
+  id <SOGoContactFolder> currentFolder;
+
+  results = [NSMutableArray new];
+  [results autorelease];
+
+  topFolder = [self clientObject];
+  sogoContactFolders = [[topFolder contactFolders] objectEnumerator];
+  currentFolder = [sogoContactFolders nextObject];
+  while (currentFolder)
+    {
+      [results addObjectsFromArray: [currentFolder
+                                      lookupContactsWithFilter: contact
+                                      sortBy: @"cn"
+                                      ordering: NSOrderedAscending]];
+      currentFolder = [sogoContactFolders nextObject];
+    }
+  [topFolder release];
+
+  return results;
+}
+
+- (NSString *) _emailForResult: (NSDictionary *) result
+{
+  NSMutableString *email;
+  NSString *name, *mail;
+
+  email = [NSMutableString string];
+  name = [result objectForKey: @"displayName"];
+  if (![name length])
+    name = [result objectForKey: @"cn"];
+  mail = [result objectForKey: @"mail"];
+  if ([name length])
+    [email appendFormat: @"%@ <%@>", name, mail];
+  else
+    [email appendString: mail];
+
+  return email;
+}
+
+- (NSDictionary *) _nextResultWithUid: (NSEnumerator *) results
+{
+  NSDictionary *result, *possibleResult;
+
+  result = nil;
+  possibleResult = [results nextObject];
+  while (possibleResult && !result)
+    if ([[possibleResult objectForKey: @"c_uid"] length])
+      result = possibleResult;
+    else
+      possibleResult = [results nextObject];
+
+  return result;
+}
+
+- (WOResponse *) _responseForResults: (NSArray *) results
+{
+  WOResponse *response;
+  NSString *email, *responseString;
+  NSDictionary *result;
+
+  response = [context response];
+
+  if ([results count])
+    {
+      result = [self _nextResultWithUid: [results objectEnumerator]];
+      if (!result)
+        result = [results objectAtIndex: 0];
+      email = [self _emailForResult: result];
+      responseString = [NSString stringWithFormat: @"%@:%@",
+                                 [result objectForKey: @"c_uid"],
+                                 email];
+      [response setStatus: 200];
+      [response setHeader: @"text/plain; charset=iso-8859-1"
+                forKey: @"Content-Type"];
+      [response appendContentString: responseString];
+    }
+  else
+    [response setStatus: 404];
+
+  return response;
+}
+
+- (id <WOActionResults>) contactSearchAction
+{
+  NSString *contact;
+  id <WOActionResults> result;
+
+  contact = [self queryParameterForKey: @"search"];
+  if ([contact length])
+    result = [self _responseForResults: [self _searchResults: contact]];
+  else
+    result = [NSException exceptionWithHTTPStatus: 400
+                          reason: @"missing 'search' parameter"];
+
+  return result;
+}
+
+- (id <WOActionResults>) updateAdditionalAddressBooksAction
+{
+  WOResponse *response;
+  NSUserDefaults *ud;
+
+  ud = [[context activeUser] userDefaults];
+  [ud setObject: [self queryParameterForKey: @"ids"]
+      forKey: @"additionaladdressbooks"];
+  [ud synchronize];
+  response = [context response];
+  [response setStatus: 200];
+  [response setHeader: @"text/html; charset=\"utf-8\"" forKey: @"content-type"];
+
+  return response;
+}
+
+- (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
+{
+  SOGoFolder *upperContainer;
+  SOGoUserFolder *userFolder;
+  SOGoContactFolders *contactFolders;
+  SOGoContactGCSFolder *contactFolder;
+  SoSecurityManager *securityManager;
+
+  upperContainer = [[[self clientObject] container] container];
+  userFolder = [SOGoUserFolder objectWithName: uid
+                               inContainer: upperContainer];
+  contactFolders = [SOGoContactFolders objectWithName: @"Contacts"
+                                       inContainer: userFolder];
+  contactFolder = [SOGoContactGCSFolder objectWithName: @"personal"
+                                        inContainer: contactFolders];
+  [contactFolder
+    setOCSPath: [NSString stringWithFormat: @"/Users/%@/Contacts/personal", uid]];
+  [contactFolder setOwner: uid];
+
+  securityManager = [SoSecurityManager sharedSecurityManager];
+
+  return (([securityManager validatePermission: SoPerm_AccessContentsInformation
+                            onObject: contactFolder
+                            inContext: context] == nil)
+          ? contactFolder : nil);
+}
+
+- (id <WOActionResults>) checkRightsAction
+{
+  WOResponse *response;
+  NSUserDefaults *ud;
+  NSString *uids;
+  NSMutableString *rights;
+  NSArray *ids;
+  unsigned int count, max;
+  BOOL result;
+
+  ud = [[context activeUser] userDefaults];
+  uids = [ud objectForKey: @"additionaladdressbooks"];
+
+  response = [context response];
+  [response setStatus: 200];
+  [response setHeader: @"text/plain; charset=\"utf-8\""
+            forKey: @"content-type"];
+  rights = [NSMutableString string];
+  if ([uids length] > 0)
+    {
+      ids = [uids componentsSeparatedByString: @","];
+      max = [ids count];
+      for (count = 0; count < max; count++)
+        {
+          result = ([self contactFolderForUID: [ids objectAtIndex: count]] != nil);
+          if (count == 0)
+            [rights appendFormat: @"%d", result];
+          else
+            [rights appendFormat: @",%d", result];
+        }
+    }
+  [response appendContentString: rights];
+
+  return response;
+}
+
+@end
diff --git a/UI/Contacts/UIxContactSelector.h b/UI/Contacts/UIxContactSelector.h
new file mode 100644 (file)
index 0000000..81b2075
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2000-2004 SKYRIX Software AG
+ This file is part of OGo
+ OGo is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+ OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with OGo; see the file COPYING.  If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+ */
+
+#ifndef UIXCONTACTSELECTOR_H
+#define UIXCONTACTSELECTOR_H
+
+@class NSArray;
+@class NSDictionary;
+@class NSString;
+@class iCalPerson;
+
+@interface UIxContactSelector : UIxComponent
+{
+  NSString *title;
+  NSString *windowId;
+  NSString *selectorId;
+  NSString *callback;
+
+  NSArray *contacts;
+  NSArray *checkedBoxes;
+  iCalPerson *currentContact;
+
+  BOOL hasCheckBoxes;
+  NSString *checkBoxOnChange;
+
+  NSDictionary *userColors;
+}
+
+- (void) setHasCheckBoxes: (BOOL) aBool;
+- (BOOL) hasCheckBoxes;
+- (void) setCheckBoxOnChange: (NSString *) aString;
+- (NSString *) checkBoxOnChange;
+
+- (void)setTitle:(NSString *)_title;
+- (NSString *)title;
+- (void)setWindowId:(NSString *)_winId;
+- (NSString *)windowId;
+- (void)setSelectorId:(NSString *)_selId;
+- (NSString *)selectorId;
+- (void)setCallback:(NSString *)_callback;
+- (NSString *)callback;
+
+- (void) setContacts: (NSArray *) _contacts;
+- (NSArray *) contacts;
+
+- (void) setCurrentContact: (iCalPerson *) aContact;
+- (NSString *) currentContactId;
+- (NSString *) currentContactName;
+- (NSString *) initialContactsAsString;
+
+- (NSString *)relativeContactsPath;
+
+- (NSString *)jsFunctionName;
+- (NSString *)jsFunctionHref;
+- (NSString *)jsCode;
+@end
+
+#endif /* UIXCONTACTSELECTOR_H */
index 4cc0a9f748e748c4f77f1700a2b084f05352c41a..a9da6fb9fb5f3db7649fbd6ac3b47976ff1f1e76 100644 (file)
  */
 // $Id$
 
+#import <NGExtensions/NGExtensions.h>
+#import <NGCards/iCalPerson.h>
 
-#include <SOGoUI/UIxComponent.h>
+#import <SOGoUI/UIxComponent.h>
+#import <SOGo/AgenorUserManager.h>
 
-@interface UIxContactSelector : UIxComponent
-{
-  NSString *title;
-  NSString *windowId;
-  NSString *callback;
-}
-
-- (void)setTitle:(NSString *)_title;
-- (NSString *)title;
-- (void)setWindowId:(NSString *)_winId;
-- (NSString *)windowId;
-- (void)setCallback:(NSString *)_callback;
-- (NSString *)callback;
-
-- (NSString *)relativeContactsPath;
+#import "common.h"
 
-- (NSString *)jsFunctionName;
-- (NSString *)jsFunctionHref;
-- (NSString *)jsCode;
-@end
-
-#include "common.h"
-#include <NGExtensions/NGExtensions.h>
+#import "UIxContactSelector.h"
 
 @implementation UIxContactSelector
 
@@ -54,6 +37,8 @@
     [self setTitle:@"UIxContacts"];
     [self setWindowId:@"UIxContacts"];
     [self setCallback:@"undefined"];
+    checkedBoxes = nil;
+    userColors = nil;
   }
   return self;
 }
   return self->windowId;
 }
 
+- (void)setSelectorId:(NSString *)_selId {
+  ASSIGNCOPY(selectorId, _selId);
+}
+
+- (NSString *)selectorId {
+  return selectorId;
+}
+
+- (NSString *)selectorIdList {
+  return [NSString stringWithFormat: @"uixselector-%@-uidList", selectorId];
+}
+
+- (NSString *)selectorIdDisplay {
+  return [NSString stringWithFormat: @"uixselector-%@-display", selectorId];
+}
+
 - (void)setCallback:(NSString *)_callback {
   ASSIGNCOPY(self->callback, _callback);
 }
     [self windowId]];
 }
 
+- (void) setContacts: (NSArray *) _contacts
+{
+  contacts = _contacts;
+}
+
+- (NSArray *) contacts
+{
+  return contacts;
+}
+
+- (NSArray *) getICalPersonsFromValue: (NSString *) selectorValue
+{
+  NSMutableArray *persons;
+  NSEnumerator *uids;
+  NSString *uid;
+  AgenorUserManager *um;
+
+  um = [AgenorUserManager sharedUserManager];
+
+  persons = [NSMutableArray new];
+  [persons autorelease];
+
+  if ([selectorValue length] > 0)
+    {
+      uids = [[selectorValue componentsSeparatedByString: @","]
+               objectEnumerator];
+      uid = [uids nextObject];
+      while (uid)
+        {
+          [persons addObject: [um iCalPersonWithUid: uid]];
+          uid = [uids nextObject];
+        }
+    }
+
+  return persons;
+}
+
+- (void) takeValuesFromRequest: (WORequest *) _rq
+                     inContext: (WOContext *) _ctx
+{
+  contacts = [self getICalPersonsFromValue: [_rq formValueForKey: selectorId]];
+  if ([contacts count] > 0)
+    NSLog (@"got %i attendees: %@", [contacts count], contacts);
+  else
+    NSLog (@"got no attendees!");
+}
+
+- (void) setCurrentContact: (iCalPerson *) aContact
+{
+  currentContact = aContact;
+}
+
+- (NSString *) initialContactsAsString
+{
+  NSEnumerator *persons;
+  iCalPerson *person;
+  NSMutableArray *participants;
+
+  participants = [NSMutableArray arrayWithCapacity: [contacts count]];
+  persons = [contacts objectEnumerator];
+  person = [persons nextObject];
+  while (person)
+    {
+      [participants addObject: [person cn]];
+      person = [persons nextObject];
+    }
+
+  return [participants componentsJoinedByString: @","];
+}
+
+- (NSString *) currentContactId
+{
+  return [currentContact cn];
+}
+
+- (NSString *) currentContactName
+{
+  return [currentContact cn];
+}
+
+- (void) setCheckedBoxes: (NSArray *) boxes
+{
+  checkedBoxes = boxes;
+}
+
+- (void) setHasCheckBoxes: (BOOL) aBool
+{
+  hasCheckBoxes = aBool;
+}
+
+- (BOOL) hasCheckBoxes
+{
+  return hasCheckBoxes;
+}
+
+- (BOOL) isCheckBoxChecked
+{
+  return (checkedBoxes != nil
+          && [checkedBoxes containsObject: currentContact]);
+}
+
+- (void) setCheckBoxOnChange: (NSString *) aString
+{
+  checkBoxOnChange = aString;
+}
+
+- (NSString *) checkBoxOnChange
+{
+  return  checkBoxOnChange;
+}
+
+- (void) setColors: (NSDictionary *) colors
+{
+  userColors = colors;
+}
+
+- (BOOL) hasColors
+{
+  return (userColors != nil);
+}
+
+- (NSString *) currentContactStyle
+{
+  return [NSString stringWithFormat: @"background-color: %@;",
+                   [userColors objectForKey: [currentContact cn]]];
+}
+
 @end /* UIxContactSelector */
similarity index 73%
rename from Misc/dbd/DSoUserManager.h
rename to UI/Contacts/UIxContactView.h
index b8830cf6a17abd629799266aa5722a86b162dae7..3560553e638a1f4fd67b9813a08cb276667b3c09 100644 (file)
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
-#ifndef __dbd_DSoUserManager_H__
-#define __dbd_DSoUserManager_H__
+#ifndef UIXCONTACTVIEW_H
+#define UIXCONTACTVIEW_H
 
-#include "DSoObject.h"
+#import <SOGoUI/UIxComponent.h>
 
-@class DSoHost;
+@class NGVCard;
 
-@interface DSoUserManager : DSoObject
+@interface UIxContactView : UIxComponent
 {
-  DSoHost *host;
+  NGVCard *card;
+  NSArray *phones;
+  CardElement *homeAdr;
+  CardElement *workAdr;
 }
 
-- (id)initWithContainer:(DSoHost *)_container;
+- (BOOL)isDeletableClientObject;
 
 @end
 
-#endif /* __dbd_DSoUserManager_H__ */
+#endif /* UIXCONTACTVIEW_H */
index 2059b001fdf9d626009ccadf9cd8b3f0c4609f61..87d4b62062df20bf102e7478add076e219bf5822 100644 (file)
 */
 // $Id$
 
+#import <Contacts/SOGoContactObject.h>
 
-#include <SOGoUI/UIxComponent.h>
+#import <NGCards/NGVCard.h>
+#import <NGCards/CardElement.h>
+#import <NGCards/NSArray+NGCards.h>
+#import <NGExtensions/NSString+Ext.h>
 
-@interface UIxContactView : UIxComponent
-{
-}
-
-- (BOOL)isDeletableClientObject;
+#import "common.h"
 
-@end
-
-#include <Contacts/SOGoContactObject.h>
-#include "common.h"
+#import "UIxContactView.h"
 
 @implementation UIxContactView
 
   return selection;
 }
 
+- (NSString *) _cardStringWithLabel: (NSString *) label
+                              value: (NSString *) value
+{
+  NSMutableString *cardString;
+
+  cardString = [NSMutableString new];
+  [cardString autorelease];
+
+  if (value && [value length] > 0)
+    {
+      if (label)
+        [cardString appendFormat: @"%@%@<br />\n",
+                    [self labelForKey: label], value];
+      else
+        [cardString appendFormat: @"%@<br />\n", value];
+    }
+
+  return cardString;
+}
+
+- (NSString *) contactCardTitle
+{
+  return [NSString stringWithFormat:
+                     [self labelForKey: @"Card for %@"],
+                   [card fn]];
+}
+
+- (NSString *) displayName
+{
+  return [self _cardStringWithLabel: @"Display Name: "
+               value: [card fn]];
+}
+
+- (NSString *) nickName
+{
+  return [self _cardStringWithLabel: @"Nickname: "
+               value: [card nickname]];
+}
+
+- (NSString *) preferredEmail
+{
+  NSString *email, *mailTo;
+
+  email = [card preferredEMail];
+  if (email && [email length] > 0)
+    mailTo = [NSString stringWithFormat: @"<a href=\"mailto:%@\""
+                       @" onclick=\"return onContactMailTo(this);\">"
+                       @"%@</a>", email, email];
+  else
+    mailTo = nil;
+
+  return [self _cardStringWithLabel: @"Email Address: "
+               value: mailTo];
+}
+
+- (NSString *) preferredTel
+{
+  return [self _cardStringWithLabel: @"Phone Number: "
+               value: [card preferredTel]];
+}
+
+- (NSString *) preferredAddress
+{
+  return @"";
+}
+
+- (BOOL) hasTelephones
+{
+  if (!phones)
+    phones = [card childrenWithTag: @"tel"];
+
+  return ([phones count] > 0);
+}
+
+- (NSString *) _phoneOfType: (NSString *) aType
+                  withLabel: (NSString *) aLabel
+{
+  NSArray *elements;
+  NSString *phone;
+
+  elements = [phones cardElementsWithAttribute: @"type"
+                     havingValue: aType];
+
+  if ([elements count] > 0)
+    phone = [[elements objectAtIndex: 0] value: 0];
+  else
+    phone = nil;
+
+  return [self _cardStringWithLabel: aLabel value: phone];
+}
+
+- (NSString *) workPhone
+{
+  return [self _phoneOfType: @"work" withLabel: @"Work: "];
+}
+
+- (NSString *) homePhone
+{
+  return [self _phoneOfType: @"home" withLabel: @"Home: "];
+}
+
+- (NSString *) fax
+{
+  return [self _phoneOfType: @"fax" withLabel: @"Fax: "];
+}
+
+- (NSString *) mobile
+{
+  return [self _phoneOfType: @"cell" withLabel: @"Mobile: "];
+}
+
+- (NSString *) pager
+{
+  return [self _phoneOfType: @"pager" withLabel: @"Pager: "];
+}
+
+- (BOOL) hasHomeInfos
+{
+  BOOL result;
+  NSArray *elements;
+
+  elements = [card childrenWithTag: @"adr"
+                   andAttribute: @"type"
+                   havingValue: @"home"];
+  if ([elements count] > 0)
+    {
+      result = YES;
+      homeAdr = [elements objectAtIndex: 0];
+    }
+  else
+    result = ([[card childrenWithTag: @"url"
+                     andAttribute: @"type"
+                     havingValue: @"home"] count] > 0);
+
+  return result;
+}
+
+- (NSString *) homePobox
+{
+  return [self _cardStringWithLabel: nil value: [homeAdr value: 0]];
+}
+
+- (NSString *) homeExtendedAddress
+{
+  return [self _cardStringWithLabel: nil value: [homeAdr value: 1]];
+}
+
+- (NSString *) homeStreetAddress
+{
+  return [self _cardStringWithLabel: nil value: [homeAdr value: 2]];
+}
+
+- (NSString *) homeCityAndProv
+{
+  NSString *city, *prov;
+  NSMutableString *data;
+
+  city = [homeAdr value: 3];
+  prov = [homeAdr value: 4];
+
+  data = [NSMutableString new];
+  [data autorelease];
+  [data appendString: city];
+  if ([city length] > 0 && [prov length] > 0)
+    [data appendString: @", "];
+  [data appendString: prov];
+
+  return [self _cardStringWithLabel: nil value: data];
+}
+
+- (NSString *) homePostalCodeAndCountry
+{
+  NSString *postalCode, *country;
+  NSMutableString *data;
+
+  postalCode = [homeAdr value: 5];
+  country = [homeAdr value: 6];
+
+  data = [NSMutableString new];
+  [data autorelease];
+  [data appendString: postalCode];
+  if ([postalCode length] > 0 && [country length] > 0)
+    [data appendFormat: @", ", country];
+  [data appendString: country];
+
+  return [self _cardStringWithLabel: nil value: data];
+}
+
+- (NSString *) _urlOfType: (NSString *) aType
+{
+  NSArray *elements;
+  NSString *data, *url;
+
+  elements = [card childrenWithTag: @"url"
+                   andAttribute: @"type"
+                   havingValue: aType];
+  if ([elements count] > 0)
+    {
+      url = [[elements objectAtIndex: 0] value: 0];
+      data = [NSString stringWithFormat:
+                         @"<a href=\"%@\">%@</a>",
+                       url, url];
+    }
+  else
+    data = nil;
+
+  return [self _cardStringWithLabel: nil value: data];
+}
+
+- (NSString *) homeUrl
+{
+  return [self _urlOfType: @"home"];
+}
+
+- (BOOL) hasWorkInfos
+{
+  BOOL result;
+  NSArray *elements;
+
+  elements = [card childrenWithTag: @"adr"
+                   andAttribute: @"type"
+                   havingValue: @"work"];
+  if ([elements count] > 0)
+    {
+      result = YES;
+      workAdr = [elements objectAtIndex: 0];
+    }
+  else
+    result = (([[card childrenWithTag: @"url"
+                      andAttribute: @"type"
+                     havingValue: @"work"] count] > 0)
+              || [[card childrenWithTag: @"org"] count] > 0);
+
+  return result;
+}
+
+- (NSString *) workTitle
+{
+  return [self _cardStringWithLabel: nil value: [card title]];
+}
+
+- (NSString *) workService
+{
+  NSArray *org, *orgServices;
+  NSRange aRange;
+  NSString *services;
+
+  org = [card org];
+  if (org && [org count] > 1)
+    {
+      aRange = NSMakeRange (1, [org count] - 1);
+      orgServices = [org subarrayWithRange: aRange];
+      services = [orgServices componentsJoinedByString: @", "];
+    }
+  else
+    services = nil;
+
+  return [self _cardStringWithLabel: nil value: services];
+}
+
+- (NSString *) workCompany
+{
+  NSArray *org;
+  NSString *company;
+
+  org = [card org];
+  if (org && [org count] > 0)
+    company = [org objectAtIndex: 0];
+  else
+    company = nil;
+
+  return [self _cardStringWithLabel: nil value: company];
+}
+
+- (NSString *) workPobox
+{
+  return [self _cardStringWithLabel: nil value: [workAdr value: 0]];
+}
+
+- (NSString *) workExtendedAddress
+{
+  return [self _cardStringWithLabel: nil value: [workAdr value: 1]];
+}
+
+- (NSString *) workStreetAddress
+{
+  return [self _cardStringWithLabel: nil value: [workAdr value: 2]];
+}
+
+- (NSString *) workCityAndProv
+{
+  NSString *city, *prov;
+  NSMutableString *data;
+
+  city = [workAdr value: 3];
+  prov = [workAdr value: 4];
+
+  data = [NSMutableString new];
+  [data autorelease];
+  [data appendString: city];
+  if ([city length] > 0 && [prov length] > 0)
+    [data appendString: @", "];
+  [data appendString: prov];
+
+  return [self _cardStringWithLabel: nil value: data];
+}
+
+- (NSString *) workPostalCodeAndCountry
+{
+  NSString *postalCode, *country;
+  NSMutableString *data;
+
+  postalCode = [workAdr value: 5];
+  country = [workAdr value: 6];
+
+  data = [NSMutableString new];
+  [data autorelease];
+  [data appendString: postalCode];
+  if ([postalCode length] > 0 && [country length] > 0)
+    [data appendFormat: @", ", country];
+  [data appendString: country];
+
+  return [self _cardStringWithLabel: nil value: data];
+}
+
+- (NSString *) workUrl
+{
+  return [self _urlOfType: @"home"];
+}
+
+- (BOOL) hasOtherInfos
+{
+  return ([[card note] length] > 0
+          || [[card bday] length] > 0
+          || [[card tz] length] > 0);
+}
+
+- (NSString *) bday
+{
+  return [self _cardStringWithLabel: @"Birthday: " value: [card bday]];
+}
+
+- (NSString *) tz
+{
+  return [self _cardStringWithLabel: @"Timezone: " value: [card tz]];
+}
+
+- (NSString *) note
+{
+  NSString *note;
+
+  note = [card note];
+  if (note)
+    {
+      note = [note stringByReplacingString: @"\r\n"
+                   withString: @"<br />"];
+      note = [note stringByReplacingString: @"\n"
+                   withString: @"<br />"];
+    }
+
+  return [self _cardStringWithLabel: @"Note: " value: note];
+}
+
 /* hrefs */
 
-- (NSString *)completeHrefForMethod:(NSString *)_method
-  withParameter:(NSString *)_param
-  forKey:(NSString *)_key
+- (NSString *) completeHrefForMethod: (NSString *) _method
+                       withParameter: (NSString *) _param
+                              forKey: (NSString *) _key
 {
   NSString *href;
 
   [self setQueryParameter:_param forKey:_key];
   href = [self completeHrefForMethod:[self ownMethodName]];
   [self setQueryParameter:nil forKey:_key];
+
   return href;
 }
 
 
 /* action */
 
-- (id<WOActionResults>)defaultAction {
-  if ([[self clientObject] record] == nil) {
-    return [NSException exceptionWithHTTPStatus:404 /* Not Found */
-                       reason:@"could not locate contact"];
-  }
+- (id <WOActionResults>) vcardAction
+{
+  WOResponse *response;
+
+  card = [[self clientObject] vCard];
+  if (card)
+    {
+      response = [WOResponse new];
+      [response autorelease];
+      [response setHeader: @"text/vcard" forKey: @"Content-type"];
+      [response appendContentString: [card versitString]];
+    }
+  else
+    return [NSException exceptionWithHTTPStatus: 404 /* Not Found */
+                        reason:@"could not locate contact"];
+
+  return response;
+}
+
+- (id <WOActionResults>) defaultAction
+{
+  card = [[self clientObject] vCard];
+  if (card)
+    {
+      phones = nil;
+      homeAdr = nil;
+      workAdr = nil;
+    }
+  else
+    return [NSException exceptionWithHTTPStatus: 404 /* Not Found */
+                        reason: @"could not locate contact"];
+
   return self;
 }
 
-- (BOOL)isDeletableClientObject {
-  return [[self clientObject] respondsToSelector:@selector(delete)];
+- (BOOL) isDeletableClientObject
+{
+  return [[self clientObject] respondsToSelector: @selector(delete)];
 }
 
-- (id)deleteAction {
+- (id) deleteAction
+{
   NSException *ex;
   id url;
 
-  if (![self isDeletableClientObject]) {
+  if (![self isDeletableClientObject])
     /* return 400 == Bad Request */
     return [NSException exceptionWithHTTPStatus:400
                         reason:@"method cannot be invoked on "
-                               @"the specified object"];
-  }
+                        @"the specified object"];
 
-  if ((ex = [[self clientObject] delete]) != nil) {
+  ex = [[self clientObject] delete];
+  if (ex)
+    {
     // TODO: improve error handling
-    [self debugWithFormat:@"failed to delete: %@", ex];
-    return ex;
-  }
+      [self debugWithFormat:@"failed to delete: %@", ex];
+
+      return ex;
+    }
 
   url = [[[self clientObject] container] baseURLInContext:[self context]];
+
   return [self redirectToLocation:url];
 }
 
similarity index 78%
rename from Misc/dbd/DSoField.h
rename to UI/Contacts/UIxContactsAclsSelection.m
index b0283fd4ce37d2827017f0b74d9e6186dfb2fe52..eed1fa33499e6d8be471493cee73b7fe280211b4 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2004 SKYRIX Software AG
+  Copyright (C) 2004-2005 SKYRIX Software AG
 
   This file is part of OpenGroupware.org.
 
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
-#ifndef __dbd_DSoField_H__
-#define __dbd_DSoField_H__
-
-#include "DSoObject.h"
-
-@interface DSoField : DSoObject
-{
-}
+#import <SOGoUI/UIxComponent.h>
 
+@interface UIxContactsAclsSelection : UIxComponent
+  
 @end
 
-#endif /* __dbd_DSoField_H__ */
+@implementation UIxContactsAclsSelection
+
+@end /* UIxContactsAclsSelection */
similarity index 76%
rename from Misc/dbd/DSoUser.m
rename to UI/Contacts/UIxContactsAddressBooksSelection.m
index 634b201ac6fedb8a91764ca5f86c6c138f4223b5..53232a1bddb81ad430eeb423697f9fd70e6de75f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2004 SKYRIX Software AG
+  Copyright (C) 2004-2005 SKYRIX Software AG
 
   This file is part of OpenGroupware.org.
 
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
-#include "DSoUser.h"
-#include "common.h"
+#import <SOGoUI/UIxComponent.h>
 
-@implementation DSoUser
+@interface UIxContactsAddressBooksSelection : UIxComponent
+  
+@end
 
-- (void)dealloc {
-  [super dealloc];
-}
+@implementation UIxContactsAddressBooksSelection
 
-@end /* DSoUser */
+@end /* UIxContactsAddressBooksSelection */
similarity index 77%
rename from UI/Common/UIxWinClose.m
rename to UI/Contacts/UIxContactsCalendarsSelection.m
index b93f91f61fc3149c71818f48ca6c7ce0a95f0cc2..7dc4d7293bb80695519c675ab9565f0381f1d139 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2000-2005 SKYRIX Software AG
+  Copyright (C) 2004-2005 SKYRIX Software AG
 
   This file is part of OpenGroupware.org.
 
   02111-1307, USA.
 */
 
-#include <NGObjWeb/WOComponent.h>
+#import <SOGoUI/UIxComponent.h>
 
-@interface UIxWinClose : WOComponent
+@interface UIxContactsCalendarsSelection : UIxComponent
+  
 @end
 
-@implementation UIxWinClose
-@end /* UIxWinClose */
+@implementation UIxContactsCalendarsSelection
+
+@end /* UIxContactsCalendarsSelection */
diff --git a/UI/Contacts/UIxContactsFilterPanel.m b/UI/Contacts/UIxContactsFilterPanel.m
new file mode 100644 (file)
index 0000000..f08c6ab
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ Copyright (C) 2000-2005 SKYRIX Software AG
+ This file is part of OpenGroupware.org.
+ OGo is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+ OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+ License for more details.
+ You should have received a copy of the GNU Lesser General Public
+ License along with OGo; see the file COPYING.  If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+ */
+
+#include <SOGoUI/UIxComponent.h>
+
+@interface UIxContactsFilterPanel : UIxComponent
+{
+  NSString *searchText;
+  NSString *searchCriteria;
+}
+
+@end
+
+#include <SOGoUI/UIxComponent.h>
+#include "common.h"
+
+@implementation UIxContactsFilterPanel
+
+static NSArray      *filters           = nil;
+
++ (void) initialize
+{
+  NSMutableDictionary *md;
+  NSMutableArray *ma;
+  
+  md = [[NSMutableDictionary alloc] initWithCapacity:8];
+  ma = [[NSMutableArray alloc] initWithCapacity:4];
+
+  filters           = [ma copy];
+  [md release]; md = nil;
+  [ma release]; ma = nil;
+}
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      searchText = nil;
+      searchCriteria = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [self->searchCriteria release];
+  [self->searchText release];
+  [super dealloc];
+}
+
+/* accessors */
+
+- (void) setSearchText: (NSString *)_txt
+{
+  ASSIGNCOPY(self->searchText, _txt);
+}
+
+- (void) setSearchCriteria: (NSString *)_txt
+{
+  ASSIGNCOPY(self->searchText, _txt);
+}
+
+- (NSString *) searchText
+{
+  if (!searchText)
+    searchText = [[self queryParameterForKey: @"search"] copy];
+
+  return searchText;
+}
+
+- (NSString *) searchCriteria
+{
+  if (!searchCriteria)
+    searchCriteria = [[self queryParameterForKey: @"criteria"] copy];
+
+  return searchCriteria;
+}
+
+/* filters */
+
+- (NSArray *) filters
+{
+  return filters;
+}
+
+/* qualifiers */
+
+- (NSString *) filterLabel
+{
+#if 1
+  return [[[self context] page] labelForKey: [self valueForKey:@"filter"]];
+#else
+  return [self valueForKey: @"filter"];
+#endif
+}
+
+- (NSString *) selectedFilter
+{
+  return [self queryParameterForKey: @"filterpopup"];
+}
+
+@end /* UIxContactsFilterPanel */
similarity index 71%
rename from UI/Contacts/UIxContactsListViewBase.h
rename to UI/Contacts/UIxContactsListView.h
index 8205f9bef4a772b80d2f9e3637d6065998f93c73..92b4a72e4a90178fecc734119ca6920cd93f6870 100644 (file)
  02111-1307, USA.
 */
 
-#ifndef __UIxContactsListViewBase_H__
-#define __UIxContactsListViewBase_H__
+#ifndef __UIxContactsListView_H__
+#define __UIxContactsListView_H__
 
-#include <SOGoUI/UIxComponent.h>
+#import <SOGoUI/UIxComponent.h>
 
-@class NSString, NSArray;
+@class NSDictionary;
+@class NSString;
 
-@interface UIxContactsListViewBase : UIxComponent
+@protocol SOGoContactObject;
+
+@interface UIxContactsListView : UIxComponent
 {
-  NSArray  *allRecords;
-  NSArray  *filteredRecords;
   NSString *searchText;
-  id       contact;
+  NSDictionary *currentContact;
+  NSString *selectorComponentClass;
 }
 
 @end
 
-#endif /* __UIxContactsListViewBase_H__ */
+#endif /* __UIxContactsListView_H__ */
index a3aa898d76dad7184192ccb6a8a0463cc6782eb5..7a3cdd99d3769c4b7633ddfb2ee1acdfd25a811f 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxContactsListViewBase.h"
+#import <Contacts/SOGoContactObject.h>
+#import <Contacts/SOGoContactFolder.h>
+#import <Contacts/SOGoContactFolders.h>
 
-@interface UIxContactsListView : UIxContactsListViewBase
-@end
+#import "common.h"
+
+#import "UIxContactsListView.h"
 
 @implementation UIxContactsListView
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      selectorComponentClass = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (searchText)
+    [searchText release];
+  [super dealloc];
+}
+
+/* accessors */
+
+- (void) setCurrentContact: (NSDictionary *) _contact
+{
+  currentContact = _contact;
+}
+
+- (NSDictionary *) currentContact
+{
+  return currentContact;
+}
+
+- (void) setSearchText: (NSString *) _txt
+{
+  ASSIGNCOPY (searchText, _txt);
+}
+
+- (id) searchText
+{
+  if (!searchText)
+    [self setSearchText: [self queryParameterForKey:@"search"]];
+
+  return searchText;
+}
+
+- (NSString *) selectorComponentClass
+{
+  return selectorComponentClass;
+}
+
+- (id) mailerContactsAction
+{
+  selectorComponentClass = @"UIxContactsMailerSelection";
+
+  return self;
+}
+
+- (id) calendarsContactsAction
+{
+  selectorComponentClass = @"UIxContactsCalendarsSelection";
+
+  return self;
+}
+
+- (id) addressBooksContactsAction
+{
+  selectorComponentClass = @"UIxContactsAddressBooksSelection";
+
+  return self;
+}
+
+- (id) aclsContactsAction
+{
+  selectorComponentClass = @"UIxContactsAclsSelection";
+
+  return self;
+}
+
+- (NSString *) defaultSortKey
+{
+  return @"fn";
+}
+
+- (NSString *) displayName
+{
+  NSString *displayName;
+
+  displayName = [currentContact objectForKey: @"displayName"];
+  if (!(displayName && [displayName length] > 0))
+    displayName = [currentContact objectForKey: @"cn"];
+
+  return displayName;
+}
+
+- (NSString *) sortKey
+{
+  NSString *s;
+  
+  s = [self queryParameterForKey: @"sort"];
+  if ([s length] == 0)
+    s = [self defaultSortKey];
+
+  return s;
+}
+
+- (NSComparisonResult) sortOrdering
+{
+  return ([[self queryParameterForKey:@"desc"] boolValue]
+          ? NSOrderedDescending
+          : NSOrderedAscending);
+}
+
+- (NSArray *) contactInfos
+{
+  id <SOGoContactFolder> folder;
+
+  folder = [self clientObject];
+
+  return [folder lookupContactsWithFilter: [self searchText]
+                 sortBy: [self sortKey]
+                 ordering: [self sortOrdering]];
+}
+
+/* notifications */
+
+- (void) sleep
+{
+  if (searchText)
+    {
+      [searchText release];
+      searchText = nil;
+    }
+  currentContact = nil;
+//   [allRecords release];
+//   allRecords = nil;
+//   [filteredRecords release];
+//   filteredRecords = nil;
+  [super sleep];
+}
+
+/* actions */
+
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq
+                           inContext: (WOContext*) _c
+{
+  return YES;
+}
+
 @end /* UIxContactsListView */
diff --git a/UI/Contacts/UIxContactsListViewBase.m b/UI/Contacts/UIxContactsListViewBase.m
deleted file mode 100644 (file)
index ddb2b42..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "UIxContactsListViewBase.h"
-#include <Contacts/SOGoContactFolder.h>
-#include "common.h"
-
-@implementation UIxContactsListViewBase
-
-- (void)dealloc {
-  [self->allRecords      release];
-  [self->filteredRecords release];
-  [self->searchText release];
-  [self->contact    release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (void)setContact:(id)_contact {
-  ASSIGN(self->contact, _contact);
-}
-- (id)contact {
-  return self->contact;
-}
-
-- (void)setSearchText:(NSString *)_txt {
-  ASSIGNCOPY(self->searchText, _txt);
-}
-- (id)searchText {
-  if (self->searchText == nil)
-    [self setSearchText:[[[self context] request] formValueForKey:@"search"]];
-  return self->searchText;
-}
-
-- (EOQualifier *)qualifier {
-  NSString *qs, *s;
-  
-  s = [self searchText];
-  if ([s length] == 0)
-    return nil;
-  
-  // TODO: just use qualifier vars
-  qs = [NSString stringWithFormat:
-                  @"(sn isCaseInsensitiveLike: '%@*') OR "
-                  @"(givenname isCaseInsensitiveLike: '%@*') OR "
-                  @"(mail isCaseInsensitiveLike: '*%@*') OR "
-                  @"(telephonenumber isCaseInsensitiveLike: '*%@*')",
-                  s, s, s, s];
-  return [EOQualifier qualifierWithQualifierFormat:qs];
-}
-
-- (NSString *)defaultSortKey {
-  return @"sn";
-}
-- (NSString *)sortKey {
-  NSString *s;
-  
-  s = [[[self context] request] formValueForKey:@"sort"];
-  return [s length] > 0 ? s : [self defaultSortKey];
-}
-- (EOSortOrdering *)sortOrdering {
-  SEL sel;
-
-  sel = [[[[self context] request] formValueForKey:@"desc"] boolValue]
-    ? EOCompareCaseInsensitiveDescending
-    : EOCompareCaseInsensitiveAscending;
-  
-  return [EOSortOrdering sortOrderingWithKey:[self sortKey] selector:sel];
-}
-- (NSArray *)sortOrderings {
-  return [NSArray arrayWithObjects:[self sortOrdering], nil];
-}
-
-- (NSArray *)contactInfos {
-  // TODO: should be done in the backend, but for Agenor AB its OK here
-  NSArray     *records;
-  EOQualifier *q;
-  
-  if (self->filteredRecords != nil)
-    return self->filteredRecords;
-  
-  records = [[self clientObject] fetchCoreInfos];
-  self->allRecords = 
-    [[records sortedArrayUsingKeyOrderArray:[self sortOrderings]] retain];
-  
-  if ((q = [self qualifier]) != nil) {
-  [self debugWithFormat:@"qs: %@", q];
-    self->filteredRecords = 
-      [[self->allRecords filteredArrayUsingQualifier:q] retain];
-  }
-  else
-    self->filteredRecords = [self->allRecords retain];
-  
-  return self->filteredRecords;
-}
-
-/* notifications */
-
-- (void)sleep {
-  [self->contact         release]; self->contact         = nil;
-  [self->allRecords      release]; self->allRecords      = nil;
-  [self->filteredRecords release]; self->filteredRecords = nil;
-  [super sleep];
-}
-
-/* actions */
-
-- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
-  return YES;
-}
-
-@end /* UIxContactsListViewBase */
diff --git a/UI/Contacts/UIxContactsListViewContainer.h b/UI/Contacts/UIxContactsListViewContainer.h
new file mode 100644 (file)
index 0000000..7bed4f8
--- /dev/null
@@ -0,0 +1,58 @@
+/* UIxContactsListViewContainer.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCONTACTSLISTVIEWCONTAINERBASE_H
+#define UIXCONTACTSLISTVIEWCONTAINERBASE_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSArray;
+@class NSString;
+@class SOGoContactFolder;
+
+@interface UIxContactsListViewContainer : UIxComponent
+{
+  NSString *foldersPrefix;
+  NSString *selectorComponentClass;
+  NSString *currentAdditionalFolder;
+  id currentFolder;
+}
+
+- (void) setCurrentFolder: (id) folder;
+
+- (NSString *) foldersPrefix;
+
+- (NSArray *) contactFolders;
+
+- (NSString *) contactFolderId;
+- (NSString *) currentContactFolderId;
+- (NSString *) currentContactFolderName;
+
+- (NSString *) additionalAddressBooks;
+- (NSArray *) additionalFolders;
+
+- (void) setCurrentAdditionalFolder: (NSString *) newCurrentAdditionalFolder;
+- (NSString *) currentAdditionalFolder;
+
+@end
+
+#endif /* UIXCONTACTSLISTVIEWCONTAINERBASE_H */
diff --git a/UI/Contacts/UIxContactsListViewContainer.m b/UI/Contacts/UIxContactsListViewContainer.m
new file mode 100644 (file)
index 0000000..b6e218f
--- /dev/null
@@ -0,0 +1,180 @@
+/* UIxContactsListViewContainer.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+
+#import <NGObjWeb/SoObjects.h>
+#import <NGExtensions/NSObject+Values.h>
+
+#import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/Contacts/SOGoContactFolder.h>
+
+#import "UIxContactsListViewContainer.h"
+
+@class SOGoContactFolders;
+
+@implementation UIxContactsListViewContainer
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      foldersPrefix = nil;
+      selectorComponentClass = nil;
+    }
+
+  return self;
+}
+
+- (void) setSelectorComponentClass: (NSString *) aComponentClass
+{
+  selectorComponentClass = aComponentClass;
+}
+
+- (NSString *) selectorComponentName
+{
+  return selectorComponentClass;
+}
+
+- (WOElement *) selectorComponent
+{
+  WOElement *newComponent;
+//   Class componentClass;
+
+//   componentClass = NSClassFromString(selectorComponentClass);
+//   if (componentClass)
+//     {
+  newComponent = [self pageWithName: selectorComponentClass];
+//     }
+//   else
+//     newComponent = nil;
+
+  return newComponent;
+}
+
+- (void) setCurrentFolder: (id) folder
+{
+  currentFolder = folder;
+}
+
+- (NSString *) foldersPrefix
+{
+  NSMutableArray *folders;
+  SOGoObject *currentObject;
+
+  if (!foldersPrefix)
+    {
+      folders = [NSMutableArray new];
+      [folders autorelease];
+
+      currentObject = [[self clientObject] container];
+      while (![currentObject isKindOfClass: [SOGoContactFolders class]])
+        {
+          [folders insertObject: [currentObject nameInContainer] atIndex: 0];
+          currentObject = [currentObject container];
+        }
+
+      foldersPrefix = [folders componentsJoinedByString: @"/"];
+      [foldersPrefix retain];
+    }
+
+  return foldersPrefix;
+}
+
+- (NSString *) contactFolderId
+{
+  return [NSString stringWithFormat: @"%@/%@",
+                   [self foldersPrefix],
+                   [[self clientObject] nameInContainer]];
+}
+
+- (NSArray *) contactFolders
+{
+  SOGoContactFolders *folderContainer;
+
+  folderContainer = [[self clientObject] container];
+
+  return [folderContainer contactFolders];
+}
+
+- (NSString *) currentContactFolderId
+{
+  return [NSString stringWithFormat: @"%@/%@",
+                   [self foldersPrefix],
+                   [currentFolder nameInContainer]];
+}
+
+- (NSString *) currentContactFolderName
+{
+  return [self labelForKey: [currentFolder displayName]];
+}
+
+- (BOOL) isFolderCurrent
+{
+  return [[self currentContactFolderId] isEqualToString: [self contactFolderId]];
+}
+
+- (NSString *) additionalAddressBooks
+{
+  NSUserDefaults *ud;
+
+  ud = [[context activeUser] userDefaults];
+
+  return [ud objectForKey: @"additionaladdressbooks"];
+}
+
+- (NSArray *) additionalFolders
+{
+  NSString *folders;
+  NSArray *folderNames;
+
+  folders = [self additionalAddressBooks];
+  if ([folders length] > 0)
+    folderNames = [folders componentsSeparatedByString: @","];
+  else
+    folderNames = nil;
+
+  return folderNames;
+}
+
+- (void) setCurrentAdditionalFolder: (NSString *) newCurrentAdditionalFolder
+{
+  currentAdditionalFolder = newCurrentAdditionalFolder;
+}
+
+- (NSString *) currentAdditionalFolder
+{
+  return currentAdditionalFolder;
+}
+
+- (BOOL) hasContactSelectionButtons
+{
+  return (selectorComponentClass != nil);
+}
+
+- (BOOL) isPopup
+{
+  return [[self queryParameterForKey: @"popup"] boolValue];
+}
+
+@end
similarity index 77%
rename from Misc/dbd/DSoUser.h
rename to UI/Contacts/UIxContactsMailerSelection.m
index cab69c34df96f9d3a6a50685ae689fb5ea7b6701..830dd573e5d1eab9228436eaef0dd3aad5733b5b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2004 SKYRIX Software AG
+  Copyright (C) 2004-2005 SKYRIX Software AG
 
   This file is part of OpenGroupware.org.
 
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
-#ifndef __dbd_DSoUser_H__
-#define __dbd_DSoUser_H__
-
-#include "DSoObject.h"
-
-@interface DSoUser : DSoObject
-{
-}
+#import <SOGoUI/UIxComponent.h>
 
+@interface UIxContactsMailerSelection : UIxComponent
+  
 @end
 
-#endif /* __dbd_DSoUser_H__ */
+@implementation UIxContactsMailerSelection
+
+@end /* UIxContactsMailerSelection */
diff --git a/UI/Contacts/UIxContactsSelectionView.m b/UI/Contacts/UIxContactsSelectionView.m
deleted file mode 100644 (file)
index 2e960de..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "UIxContactsListViewBase.h"
-#include <SOGoUI/SOGoJSStringFormatter.h>
-
-@interface UIxContactsSelectionView : UIxContactsListViewBase
-{
-  NSString *callback;
-}
-
-- (NSString *)_getCN;
-- (NSString *)getCN;
-- (NSString *)getSN;
-- (NSString *)getMail;
-- (NSString *)getUID;
-  
-@end
-
-#include "common.h"
-#include <SOGo/AgenorUserManager.h>
-
-@implementation UIxContactsSelectionView
-
-static SOGoJSStringFormatter *jsFormatter = nil;
-
-+ (void)initialize {
-  static BOOL didInit = NO;
-
-  if(didInit)
-    return;
-
-  didInit = YES;
-  jsFormatter = [SOGoJSStringFormatter sharedFormatter];
-}
-
-- (void)dealloc {
-  [self->callback release];
-  [super dealloc];
-}
-
-- (NSString *)callback {
-  if(!self->callback) {
-    WORequest *r = [[self context] request];
-    self->callback = [[r formValueForKey:@"callback"] retain];
-  }
-  return self->callback;
-}
-
-- (NSString *)_getCN {
-  return [self->contact valueForKey:@"cn"];
-}
-
-- (NSString *)getCN {
-  return [jsFormatter stringByEscapingQuotesInString:[self _getCN]];
-}
-
-- (NSString *)getSN {
-  NSString *sn = [self->contact valueForKey:@"sn"];
-  return [jsFormatter stringByEscapingQuotesInString:sn];
-}
-
-- (NSString *)getMail {
-  return [self->contact valueForKey:@"mail"];
-}
-
-- (NSString *)getUID {
-  return [[AgenorUserManager sharedUserManager] getUIDForEmail:[self getMail]];
-}
-
-- (NSString *)jsOnClickCode {
-  /* callback parameters: (type, cn, dn, email, uid, sn) */
-
-
-
-  /* changed to :  type, email, uid, sn, cn, dn */
-  static NSString *jsCode = \
-    @"javascript:opener.window.%@('', '%@', '%@', '%@', '%@', '');";
-
-  return [NSString stringWithFormat:jsCode,
-                  [self callback],
-                  [self getMail],
-                  [self getUID],
-                  [self getSN],
-                  [self getCN]];
-
-
-
-  //  return [NSString stringWithFormat:jsCode,
-  //    [self callback],
-  //    [self getCN],
-  //    [self getMail],
-  //    [self getUID],
-  //    [self getSN]];
-}
-
-@end /* UIxContactsInlineListView */
index 6da687a4e75ce1347bf96401742ea4b4d6cd513d..7dce9f599b0994d20c842d978113f00c329c8344 100644 (file)
-{
+{ /* -*-javascript-*- */
   requires = ( MAIN, CommonUI, Contacts );
 
-  publicResources = (
-  );
+  publicResources = ();
 
-  factories = {
-  };
+  factories = {};
 
   categories = {
-    SOGoContactFolder = {
-      methods = {
-        view = {
-          protectedBy = "View";
-          pageName    = "UIxContactsListView"; 
-        };
-        new = { 
-          protectedBy = "View";
-          pageName    = "UIxContactEditor"; 
-          actionName  = "new";
+     SOGoContactFolders = {
+        methods = {
+           view = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+           };
+           new = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName  = "new";
+           };
+           scheduler-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName  = "selectForScheduler";
+           };
+           mailer-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName  = "selectForMailer";
+           };
+           calendars-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName  = "selectForCalendars";
+           };
+           addressbooks-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName  = "selectForAddressBooks";
+           };
+           acls-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName  = "selectForAcls";
+           };
+           contactSearch = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName  = "contactSearch";
+           };
+           updateAdditionalAddressBooks = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView";
+              actionName = "updateAdditionalAddressBooks";
+           };
+           acls = {
+              protectedBy = "ReadAcls";
+              pageName    = "UIxAclEditor";
+           };
+           saveAcls = {
+              protectedBy = "SaveAcls";
+              pageName    = "UIxAclEditor";
+              actionName = "saveAcls";
+           };
+           checkRights = {
+              protectedBy = "View";
+              pageName    = "UIxContactFoldersView"; 
+              actionName  = "checkRights";
+           };
         };
-        select = {
-          protectedBy = "View";
-          pageName    = "UIxContactsSelectionView"; 
+     };
+
+     SOGoContactGCSFolder = {
+        slots = {
+           toolbar = {
+              protectedBy = "View";
+              value = "SOGoContactFolder.toolbar";
+           };
         };
-      };
-    };
-
-    SOGoContactObject = {
-      methods = {
-        view = { 
-          protectedBy = "View";
-          pageName    = "UIxContactView"; 
+        methods = {
+           view = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+           };
+           new = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+              actionName  = "new";
+           };
+           mailer-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName = "mailerContacts";
+           };
+           calendars-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName = "calendarsContacts";
+           };
+           acls-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName  = "aclsContacts";
+           };
+           addressbooks-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName = "addressBooksContacts";
+           };
         };
-        delete = { 
-          protectedBy = "View";
-          pageName    = "UIxContactView"; 
-          actionName  = "delete";
+     };
+
+     SOGoContactLDAPFolder = {
+        slots = {
+           toolbar = {
+              protectedBy = "View";
+              value = "SOGoContactFolder.toolbar";
+           };
         };
-        edit = { 
-          protectedBy = "View";
-          pageName    = "UIxContactEditor"; 
+        methods = {
+           view = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+           };
+           new = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+              actionName  = "new";
+           };
+           scheduler-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName = "schedulerContacts";
+           };
+           mailer-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName = "mailerContacts";
+           };
+           calendars-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName = "calendarsContacts";
+           };
+           acls-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName  = "aclsContacts";
+           };
+           addressbooks-contacts = {
+              protectedBy = "View";
+              pageName    = "UIxContactsListView";
+              actionName = "addressBooksContacts";
+           };
         };
-        save = { 
-          protectedBy = "View";
-          pageName    = "UIxContactEditor"; 
-          actionName  = "save";
+     };
+
+     SOGoContactGCSEntry = {
+        methods = {
+           view = {
+              protectedBy = "View";
+              pageName    = "UIxContactView";
+           };
+           delete = {
+              protectedBy = "View";
+              pageName    = "UIxContactView";
+              actionName  = "delete";
+           };
+           edit = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+           };
+           save = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+              actionName  = "save";
+           };
+           write = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+              actionName  = "write";
+           };
+           vcard = {
+              protectedBy = "View";
+              pageName    = "UIxContactView";
+              actionName  = "vcard";
+           };
         };
-        test = { 
-          protectedBy = "View";
-          pageName    = "UIxContactEditor"; 
-          actionName  = "test";
+     };
+
+     SOGoContactLDAPEntry = {
+        methods = {
+           view = {
+              protectedBy = "View";
+              pageName    = "UIxContactView";
+           };
+           delete = {
+              protectedBy = "View";
+              pageName    = "UIxContactView";
+              actionName  = "delete";
+           };
+           edit = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+           };
+           save = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+              actionName  = "save";
+           };
+           write = {
+              protectedBy = "View";
+              pageName    = "UIxContactEditor";
+              actionName  = "write";
+           };
+           vcard = {
+              protectedBy = "View";
+              pageName    = "UIxContactView";
+              actionName  = "vcard";
+           };
         };
-      };
-    };
+     };
   };
 }
+
index 7b34d5daf1141b71f35042a03f210e6bded11af1..c9475001de6748cfad478cbf30afd83ea1a919d8 100644 (file)
@@ -1,7 +1,27 @@
-ACCEPTED     = "Accépté"
+ACCEPTED     = "Accepté"
 COMPLETED    = "Terminé"
 DECLINED     = "Refusé"
 DELEGATED    = "Délégué"
 IN-PROCESS   = "En cours de traitement"
 NEEDS-ACTION = "Prise de décision nécessaire"
 TENTATIVE    = "Proposition"
+organized_by_you    = "vous Ãªtes l'organisateur";
+you_are_an_attendee = "vous Ãªtes invité";
+add_info_text       = "iMIP 'ADD' requests are not yet supported by SOGo.";
+publish_info_text   = "L'expéditeur vous informe de l'événement attaché.";
+cancel_info_text    = "Votre invitation ou l'événement au complet a Ã©té annulé.";
+request_info_no_attendee = "propose une réunion entre les invités. Ce message tint seulement lieu d'avis, vous n'êtes pas indiqué comme invité.";
+Appointment         = "Événement";
+
+Organizer           = "Organisateur";
+Time                = "Date";
+Attendees           = "Invités";
+request_info        = "vous invite Ã  une réunion.";
+do_add_to_cal       = "ajouter Ã  l'agenda";
+do_del_from_cal     = "effacer de l'agenda";
+do_accept           = "accepter";
+do_decline          = "decliner";
+do_tentative        = "tentative";
+do_update_status    = "mettre l'agenda Ã  jour";
+reply_info_no_attendee = "Vous avez reçu une réponse Ã  un Ã©vénement mais l'expéditeur n'est pas un invité.";
+reply_info          = "Ceci est une réponse Ã  un Ã©vénement que vous avez organisé.";
similarity index 57%
rename from Misc/dbd/DSoDatabase.h
rename to UI/MailPartViewers/UIxMailPartICalViewer.h
index 60324b5e5b33d04d2a6f8c0ec65c993c1d7f83e1..08ed095dd08debf504a2c3817ee8a39fc9b80a1b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2004 SKYRIX Software AG
+  Copyright (C) 2004-2005 SKYRIX Software AG
 
   This file is part of OpenGroupware.org.
 
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
-#ifndef __dbd_DSoDatabase_H__
-#define __dbd_DSoDatabase_H__
+#ifndef UIXMAILPARTICALVIEWER_H
+#define UIXMAILPARTICALVIEWER_H
 
-#include "DSoObject.h"
+#import "UIxMailPartViewer.h"
 
-@interface DSoDatabase : DSoObject
+@class SOGoDateFormatter;
+@class iCalEvent;
+@class iCalCalendar;
+
+@interface UIxMailPartICalViewer : UIxMailPartViewer
 {
-  NSString *hostName;
-  int      port;
-  NSString *databaseName;
+  iCalCalendar      *inCalendar;
+  iCalEvent         *inEvent;
+  id                attendee;
+  SOGoDateFormatter *dateFormatter;
+  id                item;
+  id                storedEventObject;
+  iCalEvent         *storedEvent;
 }
 
-- (id)initWithHostName:(NSString *)_hostname port:(int)_port 
-  databaseName:(NSString *)_dbname;
-
-/* accessors */
-
-- (NSString *)hostName;
-- (int)port;
-- (NSString *)databaseName;
-
-/* support */
-
-- (EOAdaptor *)adaptorInContext:(WOContext *)_ctx;
+- (iCalEvent *) authorativeEvent;
 
 @end
 
-#endif /* __dbd_DSoDatabase_H__ */
+#endif /* UIXMAILPARTICALVIEWER_H */
index 9b42256bcf9e76810058a414bdda92ad2d45fee7..a91b831135780538370afebba8b9a4bf7023068b 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxMailPartViewer.h"
-
 /*
   UIxMailPartICalViewer
   
   Show plain/calendar mail parts.
 */
 
-@class SOGoDateFormatter;
-@class iCalEvent, iCalCalendar;
-
-@interface UIxMailPartICalViewer : UIxMailPartViewer
-{
-  iCalCalendar      *inCalendar;
-  iCalEvent         *inEvent;
-  id                attendee;
-  SOGoDateFormatter *dateFormatter;
-  id                item;
-  id                storedEventObject;
-  iCalEvent         *storedEvent;
-}
-
-- (iCalEvent *)authorativeEvent;
+#import <SOGoUI/SOGoDateFormatter.h>
+#import <SOGo/SOGoUser.h>
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
+#import <SoObjects/Appointments/SOGoAppointmentObject.h>
+#import <SoObjects/Mailer/SOGoMailObject.h>
+#import <NGCards/NGCards.h>
+#import <NGImap4/NGImap4EnvelopeAddress.h>
+#import "common.h"
 
-@end
-
-#include <SOGoUI/SOGoDateFormatter.h>
-#include <SOGo/SOGoAppointment.h>
-#include <SOGo/SOGoUser.h>
-#include <SoObjects/Appointments/SOGoAppointmentFolder.h>
-#include <SoObjects/Appointments/SOGoAppointmentObject.h>
-#include <SoObjects/Mailer/SOGoMailObject.h>
-#include <NGiCal/NGiCal.h>
-#include <NGImap4/NGImap4EnvelopeAddress.h>
-#include "common.h"
+#import "UIxMailPartICalViewer.h"
 
 @implementation UIxMailPartICalViewer
 
 
 /* accessors */
 
-- (iCalCalendar *)inCalendar {
-  NSString *iCalString;
-  
-  if (self->inCalendar != nil)
-    return [self->inCalendar isNotNull] ? self->inCalendar : nil;
-  
-  if ((iCalString = [self flatContentAsString]) == nil) {
-    [self errorWithFormat:@"Could not retrieve content string for part!"];
-    self->inCalendar = [[NSNull null] retain];
-    return nil;
-  }
-  
-  self->inCalendar = 
-    [[iCalCalendar parseCalendarFromSource:iCalString] retain];
-  if (self->inCalendar == nil) {
-    [self warnWithFormat:@"Could not parse a vcalendar string."];
-    self->inCalendar = [[NSNull null] retain];
-    return nil;
-  }
-  else
-    return self->inCalendar;
+- (iCalCalendar *) inCalendar
+{
+  if (!inCalendar)
+    {
+      inCalendar
+        = [iCalCalendar parseSingleFromSource: [self flatContentAsString]];
+      [inCalendar retain];
+    }
+
+  return inCalendar;
 }
+
 - (BOOL)couldParseCalendar {
   return [[self inCalendar] isNotNull];
 }
   NSCalendarDate *date;
   
   date = [[self authorativeEvent] startDate];
-  [date setTimeZone:[self viewTimeZone]];
+  [date setTimeZone:[[self clientObject] userTimeZone]];
   return date;
 }
 
   NSCalendarDate *date;
   
   date = [[self authorativeEvent] endDate];
-  [date setTimeZone:[self viewTimeZone]];
+  [date setTimeZone:[[self clientObject] userTimeZone]];
   return date;
 }
 
diff --git a/UI/MailPartViewers/UIxMailPartTextViewer.h b/UI/MailPartViewers/UIxMailPartTextViewer.h
new file mode 100644 (file)
index 0000000..f41e494
--- /dev/null
@@ -0,0 +1,36 @@
+/* UIxMailPartTextViewer.h - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXMAILPARTTEXTVIEWER_H
+#define UIXMAILPARTTEXTVIEWER_H
+
+#import "UIxMailPartViewer.h"
+
+@class NSString;
+
+@interface UIxMailPartTextViewer : UIxMailPartViewer
+
+- (NSString *) flatContentAsString;
+
+@end
+
+#endif /* UIXMAILPARTTEXTVIEWER_H */
index 40370e4913d99a34afea3595d062f19fd32cfb41..f37364b5701fa08be3501d21e242c96e875db0bb 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxMailPartViewer.h"
-
 /*
   UIxMailPartTextViewer
 
-  Show plain/text mail parts in a <pre> section.
-  
+  Show plaintext mail parts correctly formatted.
+
   TODO: add server side wrapping.
   TODO: add contained link detection.
 */
 
-@interface UIxMailPartTextViewer : UIxMailPartViewer
-{
-}
-
-@end
+#import "common.h"
 
-#include "common.h"
+#import "UIxMailPartTextViewer.h"
 
 @implementation UIxMailPartTextViewer
 
+- (NSString *) flatContentAsString
+{
+  NSString *content;
+
+  content = [[super flatContentAsString] stringByEscapingHTMLString];
+  content = [content stringByReplacingString: @"\r\n"
+                     withString: @"<br />"];
+
+  return [content stringByReplacingString: @"\n"
+                  withString: @"<br />"];
+}
+
 @end /* UIxMailPartTextViewer */
index a24317930b0c324b46723d534edf43fef6bb310c..49ea90505839f6bd4e5fe226157b1aea614ddf92 100644 (file)
@@ -41,6 +41,8 @@
 "Subject"       = "Subject";
 "Add address"   = "Add address";
 
+"Attachments:" = "Attachments:";
+
 "to"            = "To";
 "cc"            = "Cc";
 "bcc"           = "Bcc";
index 4f5876518dcc0e4ff9a3ae39c968a87d18c898b3..6ba4a8d3e139c286d0233ee0b69e707b192de445 100644 (file)
@@ -6,11 +6,10 @@
 "Empty Trash" = "Vider la corbeille";
 "Delete"      = "Supprimer";
 "Expunge"     = "Purger";
-"Forward"     = "Transférer";
 "Get Mail"    = "Relever";
 "Junk"        = "Indésirable";
 "Reply"       = "Répondre";
-"Reply All"   = "Répo. Ã  tous";
+"Reply All"   = "Rép. Ã  tous";
 "Print"       = "Imprimer";
 "Stop"        = "Stop";
 "Write"       = "Écrire";
@@ -19,7 +18,7 @@
 
 "Home"                 = "Accueil"; 
 "Calendar"             = "Agenda";
-"Addressbook"          = "Carnet d'adresses";
+"Addressbook"          = "Adresses";
 "Mail"                 = "Mail";
 "Right Administration" = "Administration";
 "Help" = "Aide";
 "Subject"       = "Sujet";
 "Add address"   = "Ajouter Adresse";
 
+"Attachments:" = "Pièces jointes :";
+
+"To"            = "À";
+"Cc"            = "Cc";
+"Bcc"           = "Cci";
+
 "to"            = "À";
 "cc"            = "Cc";
 "bcc"           = "Cci";
 
-"Anais"         = "Anaïs";
-
 "This mail is being sent from an unsecure network!" = "Ce mail est envoyé depuis un réseau non sécurisé !";
 
 /* Popup "show" */
 "all"     = "Tous";
 "read"    = "Lus";
 "unread"  = "Non Lus";
-"deleted" = "Éffacés";
+"deleted" = "Effacés";
 "flagged" = "Drapeau";
 
 /* MailListView */
 
+"View:"         = "Voir :";
+
 "Subject or Sender contains" = "Sujet ou Expéditeur contient ";
 "Date"          = "Date";
-"View"          = "Voir";
 "All"           = "Tous";
 "Unread"        = "Non lus";
 "messages"      = "message(s)";
@@ -70,8 +74,8 @@
 "previous"      = "précédent";
 "next"          = "suivant";
 
-"Mark Unread" = "Marqué comme non lu"; 
-"Mark Read"   = "Marqué comme lu";
+"Mark Unread" = "Marquer comme non lu"; 
+"Mark Read"   = "Marquer comme lu";
 
 "msgnumber_to"  = "à";
 "msgnumber_of"  = "de";
 
 "SentFolderName"   = "Éléments envoyés";
 "TrashFolderName"  = "Corbeille";
-"InboxFolderName"  = "Boite de Réception";
+"InboxFolderName"  = "Boite de réception";
 "DraftsFolderName" = "Brouillons";
 "SieveFolderName"  = "Filtres";
-"Folders"          = "Répertoires"; 
+"Folders"          = "Dossiers"; 
 
 /* MailMoveToPopUp */
 
 "MoveTo"        = "Déplacer vers";
+
+/* Address Popup menu */
+"Add to Address Book..." = "Ajouter au carnet d'adresses";
+"Compose Mail To" = "Écrire Ã ";
+"Create Filter From Message..." = "Créer un filtre Ã  partir du message...";
+
+/* Mailbox popup menus */
+"Open in New Mail Window" = "Ouvrir dans une nouvelle fenétre";
+"Copy Folder Location" = "Copier l'adresse du dossier";
+"Subscribe..." = "S'abonner...";
+"Mark Folder Read..." = "Marquer le dossier comme lu";
+"New Folder..." = "Nouveau dossier...";
+"Compact This Folder" = "Compacter ce dossier";
+"Search Messages..." = "Rechercher dans les messages...";
+"Properties..." = "Propriétés";
+"New Subfolder..." = "Nouveau sous-dossier...";
+"Rename Folder..." = "Renommer le dossier...";
+"Delete Folder" = "Supprimer le dossier...";
+"Get Messages for Account" = "Relever les messages de ce compte";
+
+/* Message list popup menu */
+"Open Message In New Window" = "Ouvrir dans une nouvelle fenétre";
+"Reply to Sender Only" = "Répondre Ã  l'expéditeur";
+"Reply to All" = "Répondre Ã  tout le monde";
+"Forward" = "Transférer";
+"Edit As New..." = "Modifier comme un nouveau message";
+"Move To" = "Déplacer vers";
+"Copy To" = "Copier vers";
+"Label" = "Étiquette";
+"Mark" = "Marquer";
+"Save As..." = "Enregistrer comme...";
+"Print Preview" = "Aperçu avant impression";
+"Print..." = "Imprimer...";
+"Delete Message" = "Supprimer le message";
+
+/* Label popup menu */
+"None" = "Aucune";
+"Important" = "Important";
+"Work" = "Travail";
+"Personal" = "Personnel";
+"To Do" = "À faire";
+"Later" = "Peut attendre";
+
+/* Mark popup menu */
+"As Read" = "Comme lu";
+"Thread As Read" = "La discussion comme lue";
+"As Read By Date..." = "Comme lus par date...";
+"All Read" = "Tous les messages comme lus";
+"Flag" = "Avec un drapeau";
+"As Junk" = "Comme indésirable";
+"As Not Junk" = "Comme acceptable";
+"Run Junk Mail Controls" = "Lancer le contrôle des indésirables";
index 174b2737b2709f634b8abae1a1ba4e299ae6555a..3055d8fa7499fd56c929c8dbb89b101da826e136 100644 (file)
@@ -19,13 +19,13 @@ MailerUI_OBJC_FILES += \
        UIxMailMainFrame.m              \
        UIxMailTree.m                   \
        UIxMailTreeBlock.m              \
-       UIxMailToolbar.m                \
+       UIxMailTreeBlockJS.m            \
+       UIxMailFolderMenu.m             \
+       UIxMailSplashView.m             \
        \
-       UIxMailAccountsView.m           \
-       UIxMailAccountView.m            \
        UIxMailListView.m               \
        UIxMailView.m                   \
-       UIxMailSortableTableHeader.m    \
+       UIxMailPopupView.m              \
        UIxMailMoveToPopUp.m            \
        UIxMailFilterPanel.m            \
        \
@@ -41,7 +41,7 @@ MailerUI_OBJC_FILES += \
        UIxFilterList.m                 \
        UIxSieveEditor.m                \
        \
-       UIxMailFolderACLEditor.m        \
+       UIxMailFolderACLEditor.m
 
 MailerUI_RESOURCE_FILES += \
        Version         \
diff --git a/UI/MailerUI/Images/COPYING b/UI/MailerUI/Images/COPYING
deleted file mode 100644 (file)
index 74925c7..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-The default theme icons are derived from the icons provided as
-part of the Mozilla Thunderbird application.
-The licensing terms of Mozilla Thunderbird are available in the
-LICENSE-thunderbird.txt file.
-
diff --git a/UI/MailerUI/Images/LICENSE-thunderbird.txt b/UI/MailerUI/Images/LICENSE-thunderbird.txt
deleted file mode 100644 (file)
index 18f8109..0000000
+++ /dev/null
@@ -1,567 +0,0 @@
-                          MOZILLA PUBLIC LICENSE
-                                Version 1.1
-
-                              ---------------
-
-1. Definitions.
-
-     1.0.1. "Commercial Use" means distribution or otherwise making the
-     Covered Code available to a third party.
-
-     1.1. "Contributor" means each entity that creates or contributes to
-     the creation of Modifications.
-
-     1.2. "Contributor Version" means the combination of the Original
-     Code, prior Modifications used by a Contributor, and the Modifications
-     made by that particular Contributor.
-
-     1.3. "Covered Code" means the Original Code or Modifications or the
-     combination of the Original Code and Modifications, in each case
-     including portions thereof.
-
-     1.4. "Electronic Distribution Mechanism" means a mechanism generally
-     accepted in the software development community for the electronic
-     transfer of data.
-
-     1.5. "Executable" means Covered Code in any form other than Source
-     Code.
-
-     1.6. "Initial Developer" means the individual or entity identified
-     as the Initial Developer in the Source Code notice required by Exhibit
-     A.
-
-     1.7. "Larger Work" means a work which combines Covered Code or
-     portions thereof with code not governed by the terms of this License.
-
-     1.8. "License" means this document.
-
-     1.8.1. "Licensable" means having the right to grant, to the maximum
-     extent possible, whether at the time of the initial grant or
-     subsequently acquired, any and all of the rights conveyed herein.
-
-     1.9. "Modifications" means any addition to or deletion from the
-     substance or structure of either the Original Code or any previous
-     Modifications. When Covered Code is released as a series of files, a
-     Modification is:
-          A. Any addition to or deletion from the contents of a file
-          containing Original Code or previous Modifications.
-
-          B. Any new file that contains any part of the Original Code or
-          previous Modifications.
-
-     1.10. "Original Code" means Source Code of computer software code
-     which is described in the Source Code notice required by Exhibit A as
-     Original Code, and which, at the time of its release under this
-     License is not already Covered Code governed by this License.
-
-     1.10.1. "Patent Claims" means any patent claim(s), now owned or
-     hereafter acquired, including without limitation,  method, process,
-     and apparatus claims, in any patent Licensable by grantor.
-
-     1.11. "Source Code" means the preferred form of the Covered Code for
-     making modifications to it, including all modules it contains, plus
-     any associated interface definition files, scripts used to control
-     compilation and installation of an Executable, or source code
-     differential comparisons against either the Original Code or another
-     well known, available Covered Code of the Contributor's choice. The
-     Source Code can be in a compressed or archival form, provided the
-     appropriate decompression or de-archiving software is widely available
-     for no charge.
-
-     1.12. "You" (or "Your")  means an individual or a legal entity
-     exercising rights under, and complying with all of the terms of, this
-     License or a future version of this License issued under Section 6.1.
-     For legal entities, "You" includes any entity which controls, is
-     controlled by, or is under common control with You. For purposes of
-     this definition, "control" means (a) the power, direct or indirect,
-     to cause the direction or management of such entity, whether by
-     contract or otherwise, or (b) ownership of more than fifty percent
-     (50%) of the outstanding shares or beneficial ownership of such
-     entity.
-
-2. Source Code License.
-
-     2.1. The Initial Developer Grant.
-     The Initial Developer hereby grants You a world-wide, royalty-free,
-     non-exclusive license, subject to third party intellectual property
-     claims:
-          (a)  under intellectual property rights (other than patent or
-          trademark) Licensable by Initial Developer to use, reproduce,
-          modify, display, perform, sublicense and distribute the Original
-          Code (or portions thereof) with or without Modifications, and/or
-          as part of a Larger Work; and
-
-          (b) under Patents Claims infringed by the making, using or
-          selling of Original Code, to make, have made, use, practice,
-          sell, and offer for sale, and/or otherwise dispose of the
-          Original Code (or portions thereof).
-
-          (c) the licenses granted in this Section 2.1(a) and (b) are
-          effective on the date Initial Developer first distributes
-          Original Code under the terms of this License.
-
-          (d) Notwithstanding Section 2.1(b) above, no patent license is
-          granted: 1) for code that You delete from the Original Code; 2)
-          separate from the Original Code;  or 3) for infringements caused
-          by: i) the modification of the Original Code or ii) the
-          combination of the Original Code with other software or devices.
-
-     2.2. Contributor Grant.
-     Subject to third party intellectual property claims, each Contributor
-     hereby grants You a world-wide, royalty-free, non-exclusive license
-
-          (a)  under intellectual property rights (other than patent or
-          trademark) Licensable by Contributor, to use, reproduce, modify,
-          display, perform, sublicense and distribute the Modifications
-          created by such Contributor (or portions thereof) either on an
-          unmodified basis, with other Modifications, as Covered Code
-          and/or as part of a Larger Work; and
-
-          (b) under Patent Claims infringed by the making, using, or
-          selling of  Modifications made by that Contributor either alone
-          and/or in combination with its Contributor Version (or portions
-          of such combination), to make, use, sell, offer for sale, have
-          made, and/or otherwise dispose of: 1) Modifications made by that
-          Contributor (or portions thereof); and 2) the combination of
-          Modifications made by that Contributor with its Contributor
-          Version (or portions of such combination).
-
-          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
-          effective on the date Contributor first makes Commercial Use of
-          the Covered Code.
-
-          (d)    Notwithstanding Section 2.2(b) above, no patent license is
-          granted: 1) for any code that Contributor has deleted from the
-          Contributor Version; 2)  separate from the Contributor Version;
-          3)  for infringements caused by: i) third party modifications of
-          Contributor Version or ii)  the combination of Modifications made
-          by that Contributor with other software  (except as part of the
-          Contributor Version) or other devices; or 4) under Patent Claims
-          infringed by Covered Code in the absence of Modifications made by
-          that Contributor.
-
-3. Distribution Obligations.
-
-     3.1. Application of License.
-     The Modifications which You create or to which You contribute are
-     governed by the terms of this License, including without limitation
-     Section 2.2. The Source Code version of Covered Code may be
-     distributed only under the terms of this License or a future version
-     of this License released under Section 6.1, and You must include a
-     copy of this License with every copy of the Source Code You
-     distribute. You may not offer or impose any terms on any Source Code
-     version that alters or restricts the applicable version of this
-     License or the recipients' rights hereunder. However, You may include
-     an additional document offering the additional rights described in
-     Section 3.5.
-
-     3.2. Availability of Source Code.
-     Any Modification which You create or to which You contribute must be
-     made available in Source Code form under the terms of this License
-     either on the same media as an Executable version or via an accepted
-     Electronic Distribution Mechanism to anyone to whom you made an
-     Executable version available; and if made available via Electronic
-     Distribution Mechanism, must remain available for at least twelve (12)
-     months after the date it initially became available, or at least six
-     (6) months after a subsequent version of that particular Modification
-     has been made available to such recipients. You are responsible for
-     ensuring that the Source Code version remains available even if the
-     Electronic Distribution Mechanism is maintained by a third party.
-
-     3.3. Description of Modifications.
-     You must cause all Covered Code to which You contribute to contain a
-     file documenting the changes You made to create that Covered Code and
-     the date of any change. You must include a prominent statement that
-     the Modification is derived, directly or indirectly, from Original
-     Code provided by the Initial Developer and including the name of the
-     Initial Developer in (a) the Source Code, and (b) in any notice in an
-     Executable version or related documentation in which You describe the
-     origin or ownership of the Covered Code.
-
-     3.4. Intellectual Property Matters
-          (a) Third Party Claims.
-          If Contributor has knowledge that a license under a third party's
-          intellectual property rights is required to exercise the rights
-          granted by such Contributor under Sections 2.1 or 2.2,
-          Contributor must include a text file with the Source Code
-          distribution titled "LEGAL" which describes the claim and the
-          party making the claim in sufficient detail that a recipient will
-          know whom to contact. If Contributor obtains such knowledge after
-          the Modification is made available as described in Section 3.2,
-          Contributor shall promptly modify the LEGAL file in all copies
-          Contributor makes available thereafter and shall take other steps
-          (such as notifying appropriate mailing lists or newsgroups)
-          reasonably calculated to inform those who received the Covered
-          Code that new knowledge has been obtained.
-
-          (b) Contributor APIs.
-          If Contributor's Modifications include an application programming
-          interface and Contributor has knowledge of patent licenses which
-          are reasonably necessary to implement that API, Contributor must
-          also include this information in the LEGAL file.
-
-               (c)    Representations.
-          Contributor represents that, except as disclosed pursuant to
-          Section 3.4(a) above, Contributor believes that Contributor's
-          Modifications are Contributor's original creation(s) and/or
-          Contributor has sufficient rights to grant the rights conveyed by
-          this License.
-
-     3.5. Required Notices.
-     You must duplicate the notice in Exhibit A in each file of the Source
-     Code.  If it is not possible to put such notice in a particular Source
-     Code file due to its structure, then You must include such notice in a
-     location (such as a relevant directory) where a user would be likely
-     to look for such a notice.  If You created one or more Modification(s)
-     You may add your name as a Contributor to the notice described in
-     Exhibit A.  You must also duplicate this License in any documentation
-     for the Source Code where You describe recipients' rights or ownership
-     rights relating to Covered Code.  You may choose to offer, and to
-     charge a fee for, warranty, support, indemnity or liability
-     obligations to one or more recipients of Covered Code. However, You
-     may do so only on Your own behalf, and not on behalf of the Initial
-     Developer or any Contributor. You must make it absolutely clear than
-     any such warranty, support, indemnity or liability obligation is
-     offered by You alone, and You hereby agree to indemnify the Initial
-     Developer and every Contributor for any liability incurred by the
-     Initial Developer or such Contributor as a result of warranty,
-     support, indemnity or liability terms You offer.
-
-     3.6. Distribution of Executable Versions.
-     You may distribute Covered Code in Executable form only if the
-     requirements of Section 3.1-3.5 have been met for that Covered Code,
-     and if You include a notice stating that the Source Code version of
-     the Covered Code is available under the terms of this License,
-     including a description of how and where You have fulfilled the
-     obligations of Section 3.2. The notice must be conspicuously included
-     in any notice in an Executable version, related documentation or
-     collateral in which You describe recipients' rights relating to the
-     Covered Code. You may distribute the Executable version of Covered
-     Code or ownership rights under a license of Your choice, which may
-     contain terms different from this License, provided that You are in
-     compliance with the terms of this License and that the license for the
-     Executable version does not attempt to limit or alter the recipient's
-     rights in the Source Code version from the rights set forth in this
-     License. If You distribute the Executable version under a different
-     license You must make it absolutely clear that any terms which differ
-     from this License are offered by You alone, not by the Initial
-     Developer or any Contributor. You hereby agree to indemnify the
-     Initial Developer and every Contributor for any liability incurred by
-     the Initial Developer or such Contributor as a result of any such
-     terms You offer.
-
-     3.7. Larger Works.
-     You may create a Larger Work by combining Covered Code with other code
-     not governed by the terms of this License and distribute the Larger
-     Work as a single product. In such a case, You must make sure the
-     requirements of this License are fulfilled for the Covered Code.
-
-4. Inability to Comply Due to Statute or Regulation.
-
-     If it is impossible for You to comply with any of the terms of this
-     License with respect to some or all of the Covered Code due to
-     statute, judicial order, or regulation then You must: (a) comply with
-     the terms of this License to the maximum extent possible; and (b)
-     describe the limitations and the code they affect. Such description
-     must be included in the LEGAL file described in Section 3.4 and must
-     be included with all distributions of the Source Code. Except to the
-     extent prohibited by statute or regulation, such description must be
-     sufficiently detailed for a recipient of ordinary skill to be able to
-     understand it.
-
-5. Application of this License.
-
-     This License applies to code to which the Initial Developer has
-     attached the notice in Exhibit A and to related Covered Code.
-
-6. Versions of the License.
-
-     6.1. New Versions.
-     Netscape Communications Corporation ("Netscape") may publish revised
-     and/or new versions of the License from time to time. Each version
-     will be given a distinguishing version number.
-
-     6.2. Effect of New Versions.
-     Once Covered Code has been published under a particular version of the
-     License, You may always continue to use it under the terms of that
-     version. You may also choose to use such Covered Code under the terms
-     of any subsequent version of the License published by Netscape. No one
-     other than Netscape has the right to modify the terms applicable to
-     Covered Code created under this License.
-
-     6.3. Derivative Works.
-     If You create or use a modified version of this License (which you may
-     only do in order to apply it to code which is not already Covered Code
-     governed by this License), You must (a) rename Your license so that
-     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
-     "MPL", "NPL" or any confusingly similar phrase do not appear in your
-     license (except to note that your license differs from this License)
-     and (b) otherwise make it clear that Your version of the license
-     contains terms which differ from the Mozilla Public License and
-     Netscape Public License. (Filling in the name of the Initial
-     Developer, Original Code or Contributor in the notice described in
-     Exhibit A shall not of themselves be deemed to be modifications of
-     this License.)
-
-7. DISCLAIMER OF WARRANTY.
-
-     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
-     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
-     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
-     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
-     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
-     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
-     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
-     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
-     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
-
-8. TERMINATION.
-
-     8.1.  This License and the rights granted hereunder will terminate
-     automatically if You fail to comply with terms herein and fail to cure
-     such breach within 30 days of becoming aware of the breach. All
-     sublicenses to the Covered Code which are properly granted shall
-     survive any termination of this License. Provisions which, by their
-     nature, must remain in effect beyond the termination of this License
-     shall survive.
-
-     8.2.  If You initiate litigation by asserting a patent infringement
-     claim (excluding declatory judgment actions) against Initial Developer
-     or a Contributor (the Initial Developer or Contributor against whom
-     You file such action is referred to as "Participant")  alleging that:
-
-     (a)  such Participant's Contributor Version directly or indirectly
-     infringes any patent, then any and all rights granted by such
-     Participant to You under Sections 2.1 and/or 2.2 of this License
-     shall, upon 60 days notice from Participant terminate prospectively,
-     unless if within 60 days after receipt of notice You either: (i)
-     agree in writing to pay Participant a mutually agreeable reasonable
-     royalty for Your past and future use of Modifications made by such
-     Participant, or (ii) withdraw Your litigation claim with respect to
-     the Contributor Version against such Participant.  If within 60 days
-     of notice, a reasonable royalty and payment arrangement are not
-     mutually agreed upon in writing by the parties or the litigation claim
-     is not withdrawn, the rights granted by Participant to You under
-     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
-     the 60 day notice period specified above.
-
-     (b)  any software, hardware, or device, other than such Participant's
-     Contributor Version, directly or indirectly infringes any patent, then
-     any rights granted to You by such Participant under Sections 2.1(b)
-     and 2.2(b) are revoked effective as of the date You first made, used,
-     sold, distributed, or had made, Modifications made by that
-     Participant.
-
-     8.3.  If You assert a patent infringement claim against Participant
-     alleging that such Participant's Contributor Version directly or
-     indirectly infringes any patent where such claim is resolved (such as
-     by license or settlement) prior to the initiation of patent
-     infringement litigation, then the reasonable value of the licenses
-     granted by such Participant under Sections 2.1 or 2.2 shall be taken
-     into account in determining the amount or value of any payment or
-     license.
-
-     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
-     all end user license agreements (excluding distributors and resellers)
-     which have been validly granted by You or any distributor hereunder
-     prior to termination shall survive termination.
-
-9. LIMITATION OF LIABILITY.
-
-     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
-     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
-     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
-     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
-     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
-     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
-     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
-     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
-     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
-     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
-     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
-     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
-     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
-     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
-
-10. U.S. GOVERNMENT END USERS.
-
-     The Covered Code is a "commercial item," as that term is defined in
-     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
-     software" and "commercial computer software documentation," as such
-     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
-     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
-     all U.S. Government End Users acquire Covered Code with only those
-     rights set forth herein.
-
-11. MISCELLANEOUS.
-
-     This License represents the complete agreement concerning subject
-     matter hereof. If any provision of this License is held to be
-     unenforceable, such provision shall be reformed only to the extent
-     necessary to make it enforceable. This License shall be governed by
-     California law provisions (except to the extent applicable law, if
-     any, provides otherwise), excluding its conflict-of-law provisions.
-     With respect to disputes in which at least one party is a citizen of,
-     or an entity chartered or registered to do business in the United
-     States of America, any litigation relating to this License shall be
-     subject to the jurisdiction of the Federal Courts of the Northern
-     District of California, with venue lying in Santa Clara County,
-     California, with the losing party responsible for costs, including
-     without limitation, court costs and reasonable attorneys' fees and
-     expenses. The application of the United Nations Convention on
-     Contracts for the International Sale of Goods is expressly excluded.
-     Any law or regulation which provides that the language of a contract
-     shall be construed against the drafter shall not apply to this
-     License.
-
-12. RESPONSIBILITY FOR CLAIMS.
-
-     As between Initial Developer and the Contributors, each party is
-     responsible for claims and damages arising, directly or indirectly,
-     out of its utilization of rights under this License and You agree to
-     work with Initial Developer and Contributors to distribute such
-     responsibility on an equitable basis. Nothing herein is intended or
-     shall be deemed to constitute any admission of liability.
-
-13. MULTIPLE-LICENSED CODE.
-
-     Initial Developer may designate portions of the Covered Code as
-     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
-     Developer permits you to utilize portions of the Covered Code under
-     Your choice of the NPL or the alternative licenses, if any, specified
-     by the Initial Developer in the file described in Exhibit A.
-
-EXHIBIT A -Mozilla Public License.
-
-     ``The contents of this file are subject to the Mozilla Public License
-     Version 1.1 (the "License"); you may not use this file except in
-     compliance with the License. You may obtain a copy of the License at
-     http://www.mozilla.org/MPL/
-
-     Software distributed under the License is distributed on an "AS IS"
-     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-     License for the specific language governing rights and limitations
-     under the License.
-
-     The Original Code is ______________________________________.
-
-     The Initial Developer of the Original Code is ________________________.
-     Portions created by ______________________ are Copyright (C) ______
-     _______________________. All Rights Reserved.
-
-     Contributor(s): ______________________________________.
-
-     Alternatively, the contents of this file may be used under the terms
-     of the _____ license (the  "[___] License"), in which case the
-     provisions of [______] License are applicable instead of those
-     above.  If you wish to allow use of your version of this file only
-     under the terms of the [____] License and not to allow others to use
-     your version of this file under the MPL, indicate your decision by
-     deleting  the provisions above and replace  them with the notice and
-     other provisions required by the [___] License.  If you do not delete
-     the provisions above, a recipient may use your version of this file
-     under either the MPL or the [___] License."
-
-     [NOTE: The text of this Exhibit A may differ slightly from the text of
-     the notices in the Source Code files of the Original Code. You should
-     use the text of this Exhibit A rather than the text found in the
-     Original Code Source Code for Your Modifications.]
-
-     ----------------------------------------------------------------------
-
-     AMENDMENTS
-
-     The Netscape Public License Version 1.1 ("NPL") consists of the
-     Mozilla Public License Version 1.1 with the following Amendments,
-     including Exhibit A-Netscape Public License.  Files identified with
-     "Exhibit A-Netscape Public License" are governed by the Netscape
-     Public License Version 1.1.
-
-     Additional Terms applicable to the Netscape Public License.
-          I. Effect.
-          These additional terms described in this Netscape Public
-          License -- Amendments shall apply to the Mozilla Communicator
-          client code and to all Covered Code under this License.
-
-          II. "Netscape's Branded Code" means Covered Code that Netscape
-          distributes and/or permits others to distribute under one or more
-          trademark(s) which are controlled by Netscape but which are not
-          licensed for use under this License.
-
-          III. Netscape and logo.
-          This License does not grant any rights to use the trademarks
-          "Netscape", the "Netscape N and horizon" logo or the "Netscape
-          lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript",
-          "Smart Browsing" even if such marks are included in the Original
-          Code or Modifications.
-
-          IV. Inability to Comply Due to Contractual Obligation.
-          Prior to licensing the Original Code under this License, Netscape
-          has licensed third party code for use in Netscape's Branded Code.
-          To the extent that Netscape is limited contractually from making
-          such third party code available under this License, Netscape may
-          choose to reintegrate such code into Covered Code without being
-          required to distribute such code in Source Code form, even if
-          such code would otherwise be considered "Modifications" under
-          this License.
-
-          V. Use of Modifications and Covered Code by Initial Developer.
-               V.1. In General.
-               The obligations of Section 3 apply to Netscape, except to
-               the extent specified in this Amendment, Section V.2 and V.3.
-
-               V.2. Other Products.
-               Netscape may include Covered Code in products other than the
-               Netscape's Branded Code which are released by Netscape
-               during the two (2) years following the release date of the
-               Original Code, without such additional products becoming
-               subject to the terms of this License, and may license such
-               additional products on different terms from those contained
-               in this License.
-
-               V.3. Alternative Licensing.
-               Netscape may license the Source Code of Netscape's Branded
-               Code, including Modifications incorporated therein, without
-               such Netscape Branded Code becoming subject to the terms of
-               this License, and may license such Netscape Branded Code on
-               different terms from those contained in this License.
-
-          VI. Litigation.
-          Notwithstanding the limitations of Section 11 above, the
-          provisions regarding litigation in Section 11(a), (b) and (c) of
-          the License shall apply to all disputes relating to this License.
-
-     EXHIBIT A-Netscape Public License.
-
-          "The contents of this file are subject to the Netscape Public
-          License Version 1.1 (the "License"); you may not use this file
-          except in compliance with the License. You may obtain a copy of
-          the License at http://www.mozilla.org/NPL/
-
-          Software distributed under the License is distributed on an "AS
-          IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-          implied. See the License for the specific language governing
-          rights and limitations under the License.
-
-          The Original Code is Mozilla Communicator client code, released
-          March 31, 1998.
-
-          The Initial Developer of the Original Code is Netscape
-          Communications Corporation. Portions created by Netscape are
-          Copyright (C) 1998-1999 Netscape Communications Corporation. All
-          Rights Reserved.
-
-          Contributor(s): ______________________________________.
-
-          Alternatively, the contents of this file may be used under the
-          terms of the _____ license (the "[___] License"), in which case
-          the provisions of [______] License are applicable  instead of
-          those above.  If you wish to allow use of your version of this
-          file only under the terms of the [____] License and not to allow
-          others to use your version of this file under the NPL, indicate
-          your decision by deleting  the provisions above and replace  them
-          with the notice and other provisions required by the [___]
-          License.  If you do not delete the provisions above, a recipient
-          may use your version of this file under either the NPL or the
-          [___] License."
index d13346cae174fecdf206f79257ea6ce24b756637..d8bba1f0ac8bdf5de70c027a2ebf64dfa3945c51 100644 (file)
@@ -1,21 +1,27 @@
-( /* the toolbar groups */
+( /* the toolbar groups -*-cperl-*- */
   ( /* first group */
-              { link  = "#"; isSafe = NO;
-                onclick  = "clickedEditorSend(this);return false;";
-                cssClass = "tbicon_send"; label = "Send"; },
-              { link  = "#"; target = "addressbook";
-                onclick  = "openAddressbook(this);return false;";
-                cssClass = "tbicon_addressbook"; label = "Addressbook"; },
-              { link  = "#"; target = "anais";
-                onclick  = "openAnais(this);return false;";
-                cssClass = "tbicon_anais"; label = "Anais"; },
-              { link  = "#"; isSafe = NO;
-                onclick  = "clickedEditorAttach(this)";
-                cssClass = "tbicon_attach"; label = "Attach"; },
-              { link  = "#";  isSafe = NO;
-                onclick  = "clickedEditorSave(this);return false;";
-                cssClass = "tbicon_save"; label = "Save"; },
-              { link = "delete"; isSafe = NO;
-                cssClass = "tbicon_delete"; label = "Delete"; },
+    { link  = "#";
+      isSafe = NO;
+      onclick  = "clickedEditorSend(this);return false;";
+      image = "tb-compose-send-flat-24x24.png";
+      cssClass = "tbicon_send";
+      label = "Send"; },
+    { link  = "#";
+      onclick  = "return onContactAdd(null);";
+      image = "tb-compose-contacts-flat-24x24.png";
+      cssClass = "tbicon_addressbook";
+      label = "Contacts"; },
+    { link  = "#";
+      isSafe = NO;
+      onclick  = "clickedEditorAttach(this)";
+      image = "tb-compose-attach-flat-24x24.png";
+      cssClass = "tbicon_attach";
+      label = "Attach"; },
+    { link  = "#";
+      isSafe = NO;
+      onclick  = "clickedEditorSave(this);return false;";
+      image = "tb-mail-file-flat-24x24.png";
+      cssClass = "tbicon_save";
+      label = "Save"; },
   )
 )
diff --git a/UI/MailerUI/Toolbars/SOGoMailAccount.toolbar b/UI/MailerUI/Toolbars/SOGoMailAccount.toolbar
deleted file mode 100644 (file)
index fb3cfd3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-( /* the toolbar groups */
-            ( /* first group */
-              { link  = "getMail";
-                cssClass = "tbicon_getmail"; label = "Get Mail"; },
-              {
-                link     = "#"; // "compose"; // target = "_blank";
-                isSafe   = NO;
-                onclick  = "clickedCompose(this);return false;";
-                cssClass = "tbicon_compose"; label = "Write";
-              },
-            ),
-            ( // fourth group (folders)
-              { link = "#"; onclick="return ctxFolderAdd(this)";
-                enabled  = "showFolderCreateButton";
-                isSafe = NO;
-                cssClass = "tbicon_folderadd"; label = "Create"; }
-            )
-)
\ No newline at end of file
diff --git a/UI/MailerUI/Toolbars/SOGoMailFolder.toolbar b/UI/MailerUI/Toolbars/SOGoMailFolder.toolbar
deleted file mode 100644 (file)
index c119b46..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-( /* the toolbar groups */
-  ( /* first group */
-    { link  = "getMail";
-      cssClass = "tbicon_getmail"; label = "Get Mail"; },
-
-    { link     = "#"; // "compose"; // target = "_blank";
-      isSafe   = NO;
-      onclick  = "clickedCompose(this);return false;";
-      cssClass = "tbicon_compose"; label = "Write"; },
-  ),
-
-
-  ( // second group
-    { link = "#";  isSafe = NO;
-      onclick="openMessageWindowsForSelection(this, 'reply'); return false;";
-      cssClass = "tbicon_reply";    label = "Reply";     },
-
-    { link = "#";  isSafe = NO;
-      onclick="openMessageWindowsForSelection(this, 'replyall'); return false;";
-      cssClass = "tbicon_replyall"; label = "Reply All"; },
-
-    { link = "#";  isSafe = NO;
-      onclick="openMessageWindowsForSelection(this, 'forward'); return false;";
-      cssClass = "tbicon_forward";  label = "Forward";   },
-  ),
-
-
-  ( // third group
-    /* TODO: maybe this should be a default or get enabled with no trash writes
-      { link = "expunge"; isSafe = NO;
-        enabled  = clientObject.isDeleteAndExpungeAllowed;
-        cssClass = "tbicon_delete"; label = "Expunge"; },
-    */
-    
-    // TODO: rename to uixTrashSelectedMessages, be more consistent with
-    //       SOGoMailObject.toolbar (trash AND delete button)
-    { link = "#"; isSafe = NO;
-      onclick = "uixDeleteSelectedMessages(this); return false;";
-      enabled  = clientObject.isDeleteAndExpungeAllowed;
-      cssClass = "tbicon_delete"; label = "Delete"; },
-
-    /* TODO: enable when implemented
-    // TODO: enable when we know how to mark junk (#971)
-      { link = "#"; isSafe = NO;
-        cssClass = "tbicon_junk";   label = "Junk";   },
-    */
-  ),
-
-
-  ( // fourth group (folders)
-    { link = "#"; onclick="return ctxFolderAdd(this)";
-      enabled  = "clientObject.isCreateAllowed";
-      isSafe = NO;
-      cssClass = "tbicon_folderadd"; label = "Create"; },
-    { link = "#"; onclick="return ctxFolderDelete(this)";
-      enabled  = "clientObject.isCreateAllowed"; // TODO: correct?
-      isSafe = NO;
-      cssClass = "tbicon_folderdel"; label = "Delete"; },
-  ),
-
-/*
-  ( // fourth group
-    //TODO: enable when we can print (#1207)
-    //   { link = "#"; cssClass = "tbicon_print"; label = "Print"; },
-    
-    { link = "#"; cssClass = "tbicon_stop";  label = "Stop";  },
-  )
-*/
-)
index df7816b8c1048e955e2020b5f77ae394facaf739..a54ae3a0d483852e6135598c7b174a8f0b09be15 100644 (file)
@@ -1,50 +1,64 @@
-( /* the toolbar groups */
+( /* the toolbar groups -*-cperl-*- */
 
   ( /* first group */
-    { link  = "getMail";
-      cssClass = "tbicon_getmail"; label = "Get Mail"; },
-
-    { link     = "#"; // "compose"; // target = "_blank";
+    { link  = "#";
+      image = "tb-mail-getmail-flat-24x24.png";
+      cssClass = "tbicon_getmail";
+      label = "Get Mail";
+      onclick = "return refreshMailbox(this);";
+    },
+    { link     = "#";
       isSafe   = NO;
-      onclick  = "clickedCompose(this);return false;";
+      image = "tb-mail-write-flat-24x24.png";
+      onclick  = "return openMessageWindow(null, 'compose');";
       cssClass = "tbicon_compose"; label = "Write";    },
+    { link  = "#"; target = "addressbook";
+      onclick  = "openAddressbook(this);return false;";
+      image = "tb-mail-addressbook-flat-24x24.png";
+      cssClass = "tbicon_addressbook"; label = "Addressbook"; },
   ),
 
   ( // second group
-    { link = "reply"; 
+    { link = "reply";
+      onclick = "return openMessageWindowsForSelection('reply');";
       isSafe   = NO;
+      image = "tb-mail-reply-flat-24x24.png";
       cssClass = "tbicon_reply";    label = "Reply";     },
 
-    { link = "replyall"; 
+    { link = "replyall";
+      onclick = "return openMessageWindowsForSelection('replyall');";
       isSafe   = NO;
+      image = "tb-mail-replyall-flat-24x24.png";
       cssClass = "tbicon_replyall"; label = "Reply All"; },
 
-    { link = "forward"; 
+    { link = "forward";
+      onclick = "return openMessageWindowsForSelection('forward');";
       isSafe   = NO;
+      image = "tb-mail-forward-flat-24x24.png";
       cssClass = "tbicon_forward";  label = "Forward";   },
   ),
 
   ( // third group
-    { link     = "delete"; isSafe = NO;
-      enabled  = showMarkDeletedButton;
-      cssClass = "tbicon_delete"; label = "Delete"; },
-
-    { link     = "trash"; isSafe = NO;
-      enabled  = showTrashButton;
+    { link = "#";
+      isSafe = NO;
+      onclick = "onMenuDeleteMessage(event);";
+//       enabled  = showMarkDeletedButton;
+      image = "tb-mail-delete-flat-24x24.png";
       cssClass = "tbicon_delete"; label = "Delete"; },
-
-    /* TODO: enable when we know how to mark junk (#971)
-       => we could move the mail to the Junk folder?!
-              { link = "#"; 
-                isSafe   = NO;
-                cssClass = "tbicon_junk";   label = "Junk";   },
-     */
+    { link = "#";
+      isSafe = NO;
+      image = "tb-mail-junk-flat-24x24.png";
+      cssClass = "tbicon_junk";   label = "Junk";
+    },
   ),
-/*
-  ( // fourth group
-    // TODO: enable when we can print (#1207)
-    //  { link = "#"; cssClass = "tbicon_print"; label = "Print"; },
-    { link = "#"; cssClass = "tbicon_stop";  label = "Stop";  },
+  (
+   { link = "#";
+     cssClass = "tbicon_print";
+     image = "tb-mail-print-flat-24x24.png";
+     label = "Print"; },
+   { link = "#";
+     image = "tb-mail-stop-flat-24x24.png";
+     cssClass = "tbicon_stop";
+     label = "Stop";  },
   ),
-*/
-)
\ No newline at end of file
+)
diff --git a/UI/MailerUI/Toolbars/SOGoTrashFolder.toolbar b/UI/MailerUI/Toolbars/SOGoTrashFolder.toolbar
deleted file mode 100644 (file)
index 7797307..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-( /* the toolbar groups */
-            ( /* first group */
-              {
-                link  = "getMail";
-                cssClass = "tbicon_getmail"; label = "Get Mail";
-              },
-              {
-                link     = "#"; // "compose"; // target = "_blank";
-                isSafe   = NO;
-                onclick  = "clickedCompose(this);return false;";
-                cssClass = "tbicon_compose"; label = "Write";
-              },
-            ),
-            ( // third group
-              { link = "emptyTrash"; isSafe = NO;
-                enabled  = clientObject.isDeleteAndExpungeAllowed;
-                cssClass = "tbicon_trash"; label = "Empty Trash"; },
-/* TODO: enable when implemented
-// TODO: enable when delete works (#1212)
-              { link = "#"; isSafe = NO;
-                cssClass = "tbicon_delete"; label = "Delete"; },
-// TODO: enable when we know how to mark junk (#971)
-              { link = "#"; isSafe = NO;
-                cssClass = "tbicon_junk";   label = "Junk";   },
-*/
-            ),
-
-/*
-  ( // fourth group
-    { link = "#"; cssClass = "tbicon_stop";  label = "Stop";  },
-  )
-*/
-)
\ No newline at end of file
diff --git a/UI/MailerUI/UIxMailAccountView.m b/UI/MailerUI/UIxMailAccountView.m
deleted file mode 100644 (file)
index 9df7fbe..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include <SOGoUI/UIxComponent.h>
-
-@interface UIxMailAccountView : UIxComponent
-{
-  id inbox;
-}
-
-@end
-
-#include <NGObjWeb/SoObject+SoDAV.h>
-#include <SoObjects/Mailer/SOGoMailFolder.h>
-#include "common.h"
-
-@interface NSString(DotCutting)
-
-- (NSString *)titleForSOGoIMAP4String;
-
-@end
-
-@interface SOGoMailFolder(UsedPrivates)
-- (BOOL)isCreateAllowedInACL;
-@end
-
-@implementation UIxMailAccountView
-
-static BOOL useAltNamespace = NO;
-
-+ (void)initialize {
-  NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
-  
-  useAltNamespace = [ud boolForKey:@"SOGoSpecialFoldersInRoot"];
-}
-
-- (void)dealloc {
-  [self->inbox release];
-  [super dealloc];
-}
-
-/* notifications */
-
-- (void)sleep {
-  [super sleep];
-  [self->inbox release]; self->inbox = nil;
-}
-
-/* title */
-
-- (NSString *)objectTitle {
-  return [[[self clientObject] nameInContainer] titleForSOGoIMAP4String];
-}
-
-- (NSString *)panelTitle {
-  NSString *s;
-  
-  s = [self labelForKey:@"Mail Account"];
-  s = [s stringByAppendingString:@": "];
-  s = [s stringByAppendingString:[self objectTitle]];
-  return s;
-}
-
-- (BOOL)showFolderCreateButton {
-  if (!useAltNamespace) {
-    /* in a regular configuration everything must be created below INBOX */
-    return NO;
-  }
-  
-  /* 
-     A hack to manually check whether we have permission to create folders at
-     the root level. We do this by checking the permissions on the INBOX
-     folder (which is technically the root in Cyrus).
-     
-     See OGo bug #1472 for details.
-  */
-  
-  if (self->inbox == nil) {
-    id tmp;
-    
-    tmp = [[self clientObject] lookupName:@"INBOX" 
-                              inContext:[self context]
-                              acquire:NO];
-    if ([tmp isKindOfClass:[NSException class]] || tmp == nil)
-      tmp = [NSNull null];
-    
-    self->inbox = [tmp retain];
-  }
-  
-  if (![self->inbox isNotNull]) {
-    [self warnWithFormat:@"Found no INBOX folder!"];
-    return NO;
-  }
-  
-  return [self->inbox isCreateAllowedInACL];
-}
-
-/* error redirects */
-
-- (id)redirectToViewWithError:(id)_error {
-  // TODO: DUP to UIxMailListView
-  // TODO: improve, localize
-  // TODO: there is a bug in the treeview which preserves the current URL for
-  //       the active object (displaying the error again)
-  id url;
-  
-  if (![_error isNotNull])
-    return [self redirectToLocation:@"view"];
-  
-  if ([_error isKindOfClass:[NSException class]])
-    _error = [_error reason];
-  else if ([_error isKindOfClass:[NSString class]])
-    _error = [_error stringValue];
-  
-  url = [_error stringByEscapingURL];
-  url = [@"view?error=" stringByAppendingString:url];
-  return [self redirectToLocation:url];
-}
-
-/* actions */
-
-- (id)createFolderAction {
-  NSException *error;
-  NSString    *folderName;
-  id client;
-  
-  folderName = [[[self context] request] formValueForKey:@"name"];
-  if ([folderName length] == 0) {
-    error = [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                        reason:@"missing 'name' query parameter!"];
-    return [self redirectToViewWithError:error];
-  }
-  
-  if ((client = [self clientObject]) == nil) {
-    error = [NSException exceptionWithHTTPStatus:404 /* Not Found */
-                        reason:@"did not find mail folder"];
-    return [self redirectToViewWithError:error];
-  }
-  
-  if ((error = [[self clientObject] davCreateCollection:folderName
-                                   inContext:[self context]]) != nil) {
-    return [self redirectToViewWithError:error];
-  }
-  
-  return [self redirectToLocation:[folderName stringByAppendingString:@"/"]];
-}
-
-@end /* UIxMailAccountView */
index 49f7a552529a47eb5a1e3c67995469a49a682c32..64ea6cfd8a64b94f87113f4f44843a93271fd97f 100644 (file)
@@ -19,7 +19,7 @@
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
+#import <SOGoUI/UIxComponent.h>
 
 /*
   UIxMailEditor
 
 @end
 
-#include <SoObjects/Mailer/SOGoDraftObject.h>
-#include <SoObjects/Mailer/SOGoMailFolder.h>
-#include <SoObjects/Mailer/SOGoMailAccount.h>
-#include <SoObjects/Mailer/SOGoMailAccounts.h>
-#include <SoObjects/Mailer/SOGoMailIdentity.h>
-#include <SoObjects/SOGo/WOContext+Agenor.h>
-#include <SoObjects/SOGo/SOGoUser.h>
-#include <NGMail/NGMimeMessage.h>
-#include <NGMail/NGMimeMessageGenerator.h>
-#include <NGObjWeb/SoSubContext.h>
-#include "common.h"
+#import <SoObjects/Mailer/SOGoDraftObject.h>
+#import <SoObjects/Mailer/SOGoMailFolder.h>
+#import <SoObjects/Mailer/SOGoMailAccount.h>
+#import <SoObjects/Mailer/SOGoMailAccounts.h>
+#import <SoObjects/Mailer/SOGoMailIdentity.h>
+#import <SoObjects/SOGo/WOContext+Agenor.h>
+#import <NGMail/NGMimeMessage.h>
+#import <NGMail/NGMimeMessageGenerator.h>
+#import <NGObjWeb/SoSubContext.h>
+#import "common.h"
 
 @implementation UIxMailEditor
 
@@ -281,17 +280,17 @@ static NSArray      *infoKeys            = nil;
   SOGoMailAccounts *accounts;
   SOGoMailAccount  *account;
   SOGoMailIdentity *identity;
-  
+
   if (useLocationBasedSentFolder) /* from will be based on location */
     return;
-  
+
   if ([self->from isNotEmpty]) /* a from is already set */
     return;
-  
+
   accountID = [[[self context] request] formValueForKey:@"account"];
   if (![accountID isNotEmpty])
     return;
-  
+
   accounts = [[self clientObject] mailAccountsFolder];
   if ([accounts isExceptionOrNull])
     return; /* we don't treat this as an error but are tolerant */
@@ -307,7 +306,7 @@ static NSArray      *infoKeys            = nil;
     return;
   }
   
-  [self setFrom:[identity email]];
+  [self setFrom: [identity email]];
 }
 
 - (SOGoMailIdentity *)selectedMailIdentity {
@@ -451,6 +450,7 @@ static NSArray      *infoKeys            = nil;
     return @"width: 67%";
   return @"width: 100%";
 }
+
 - (NSString *)initialRightsideStyle {
   if ([self hasAttachments])
     return @"display: block";
@@ -491,11 +491,13 @@ static NSArray      *infoKeys            = nil;
   return nil;
 }
 
-- (id)sendAction {
+- (id <WOActionResults>) sendAction
+{
   NSException  *error;
   NSString     *mailPath;
   NSDictionary *h;
-  
+  id <WOActionResults> result;
+
   // TODO: need to validate whether we have a To etc
   
   /* first, save form data */
@@ -553,8 +555,12 @@ static NSArray      *infoKeys            = nil;
   if ((error = [[self clientObject] delete]) != nil)
     return error;
 
-  // if everything is ok, close the window (send a JS closing the Window)
-  return [self pageWithName:@"UIxMailWindowCloser"];
+  if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
+    result = [self redirectToLocation: [self applicationPath]];
+  else
+    result = [self jsCloseWithRefreshMethod: nil];
+
+  return result;
 }
 
 - (id)deleteAction {
index eabab2598c8f1ab554d3a5e58648e7ed5e83e6b6..676fddfbc2c04c0b4f64da8b71029044169827b5 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxMailEditorAction.h"
+#import "UIxMailEditorAction.h"
 
-#include <SoObjects/Mailer/SOGoDraftsFolder.h>
-#include <SoObjects/Mailer/SOGoDraftObject.h>
-#include <SoObjects/Mailer/SOGoMailAccount.h>
-#include <SoObjects/Mailer/SOGoMailObject.h>
-#include "common.h"
+#import <SoObjects/Mailer/SOGoDraftsFolder.h>
+#import <SoObjects/Mailer/SOGoDraftObject.h>
+#import <SoObjects/Mailer/SOGoMailAccount.h>
+#import <SoObjects/Mailer/SOGoMailObject.h>
+#import "common.h"
+
+#import <SOGo/NSString+URL.h>
 
 @implementation UIxMailEditorAction
 
-- (void)dealloc {
+- (void)dealloc
+{
   [self->newDraft release];
   [super dealloc];
 }
      Note: we cannot use acquisition to find the nearest drafts folder, because
            the IMAP4 server might contains an own Drafts folder.
   */
-  SOGoDraftsFolder *drafts;
-  id client;
+//   SOGoDraftsFolder *drafts;
+  SOGoMailAccount *accountFolder;
   
-  client = [self clientObject];
-  drafts = [[client mailAccountFolder]
-                   lookupName:@"Drafts" inContext:[self context] acquire:NO];
-  return drafts;
+  accountFolder = [[self clientObject] mailAccountFolder];
+
+  return [accountFolder
+           lookupName: [accountFolder draftsFolderNameInContext: context]
+           inContext: context acquire: NO];
 }
 
 /* errors */
 
 /* compose */
 
-- (id)composeAction {
+- (id) composeAction
+{
   SOGoDraftsFolder *drafts;
   WOResponse *r;
-  NSString   *url;
-  id accountFolder;
-  
+  NSString *urlBase, *url;
+  NSMutableDictionary *urlParams;
+  id parameter;
+  id returnValue;
+
   drafts = [self draftsFolder];
-  if (![drafts isNotNull])
-    return [self didNotFindDraftsError];
-  if ([drafts isKindOfClass:[NSException class]])
-    return drafts;
-  
-  url = [drafts newObjectBaseURLInContext:[self context]];
-  if (![url isNotNull])
-    return [self couldNotCreateDraftError:drafts];
-  
-  if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"];
-  url = [url stringByAppendingString:@"edit"];
-  
-  /* attach mail-account info */
-  
-  accountFolder = [[self clientObject] valueForKey:@"mailAccountFolder"];
-  if (![accountFolder isExceptionOrNull]) {
-    url = [url stringByAppendingString:@"?account="];
-    url = [url stringByAppendingString:[accountFolder nameInContainer]];
-  }
-  
-  /* perform redirect */
-  
-  [self debugWithFormat:@"compose on %@: %@", drafts, url];
-  
-  r = [[self context] response];
-  [r setStatus:302 /* moved */];
-  [r setHeader:url forKey:@"location"];
-  [self reset];
-  return r;
+  if ([drafts isNotNull])
+    {
+      if ([drafts isKindOfClass: [NSException class]])
+       returnValue = drafts;
+      else
+       {
+         urlBase = [drafts newObjectBaseURLInContext: context];
+         if ([urlBase isNotNull])
+           {
+             urlParams = [NSMutableDictionary new];
+             [urlParams autorelease];
+
+             /* attach mail-account info */
+             parameter
+               = [[self clientObject] valueForKey: @"mailAccountFolder"];
+             if (parameter && ![parameter isExceptionOrNull])
+               [urlParams setObject: [parameter nameInContainer]
+                          forKey: @"account"];
+
+             parameter = [[self request] formValueForKey: @"mailto"];
+             if (parameter)
+               [urlParams setObject: parameter
+                          forKey: @"mailto"];
+
+             url = [urlBase composeURLWithAction: @"edit"
+                            parameters: urlParams
+                            andHash: NO];
+             /* perform redirect */
+             
+             [self debugWithFormat:@"compose on %@: %@", drafts, url];
+  
+             r = [context response];
+             [r setStatus: 302 /* move d */];
+             [r setHeader: url forKey: @"location"];
+             [self reset];
+
+             returnValue = r;
+           }
+         else
+           returnValue = [self couldNotCreateDraftError: drafts];
+       }
+    }
+  else
+    returnValue = [self didNotFindDraftsError];
+
+  return returnValue;
 }
 
 /* creating new draft object */
   if ([drafts isKindOfClass:[NSException class]])
     return drafts;
 
-  return [drafts newObjectInContext:[self context]];
+  return [drafts newObjectInContext:context];
 }
 
 - (NSException *)_setupNewDraft {
     return nil;
   }
   
-  url = [self->newDraft baseURLInContext:[self context]];
+  url = [self->newDraft baseURLInContext:context];
   if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"];
   url = [url stringByAppendingString:@"edit"];
   
   // TODO: debug log
   [self logWithFormat:@"compose on %@", url];
   
-  r = [[self context] response];
+  r = [context response];
   [r setStatus:302 /* moved */];
   [r setHeader:url forKey:@"location"];
   [self reset];
index f0a76e6469b841f3c3a7da3007314d6d67ff09de..bb81e965a54739a4dbd4f58396eed5979c04a45e 100644 (file)
 @interface UIxMailFilterPanel : WOComponent
 {
   NSString *searchText;
-  struct {
-    int hideFrame:1;
-    int reserved:31;
-  } mfFlags;
+  NSString *searchCriteria;
 }
 
 @end
@@ -72,41 +69,66 @@ static NSDictionary *filterToQualifier = nil;
   [ma release]; ma = nil;
 }
 
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      searchText = nil;
+      searchCriteria = nil;
+    }
+
+  return self;
+}
+
 - (void)dealloc {
+  [self->searchCriteria release];
   [self->searchText release];
   [super dealloc];
 }
 
 /* accessors */
 
-- (void)setHideFrame:(BOOL)_flag {
-   self->mfFlags.hideFrame = _flag ? 1 : 0;
-}
-- (BOOL)hideFrame {
-  return self->mfFlags.hideFrame ? YES : NO;
+- (void)setSearchText: (NSString *)_txt
+{
+  ASSIGNCOPY(self->searchText, _txt);
 }
 
-- (void)setSearchText:(NSString *)_txt {
+- (void)setSearchCriteria: (NSString *)_txt
+{
   ASSIGNCOPY(self->searchText, _txt);
 }
-- (NSString *)searchText {
-  if (self->searchText == nil) {
-    // TODO: kinda hack
-    self->searchText = 
-      [[[[self context] request] formValueForKey:@"search"] copy];
-  }
+
+- (NSString *)searchText
+{
+  if (self->searchText == nil)
+    {
+      self->searchText = 
+       [[[[self context] request] formValueForKey:@"search"] copy];
+    }
   return self->searchText;
 }
 
+- (NSString *)searchCriteria
+{
+  if (self->searchCriteria == nil)
+    {
+      self->searchCriteria = 
+       [[[[self context] request] formValueForKey:@"criteria"] copy];
+    }
+  return self->searchCriteria;
+}
+
 /* filters */
 
-- (NSArray *)filters {
+- (NSArray *)filters
+{
   return filters;
 }
 
 /* qualifiers */
 
-- (EOQualifier *)searchTextQualifier {
+- (EOQualifier *) searchTextQualifier
+{
   EOQualifier *q;
   NSString *s;
   
@@ -121,7 +143,8 @@ static NSDictionary *filterToQualifier = nil;
   return q;
 }
 
-- (NSString *)filterLabel {
+- (NSString *)filterLabel
+{
 #if 1
   return [[[self context] page] labelForKey:[self valueForKey:@"filter"]];
 #else
@@ -129,11 +152,13 @@ static NSDictionary *filterToQualifier = nil;
 #endif
 }
 
-- (NSString *)selectedFilter {
+- (NSString *)selectedFilter
+{
   return  [[[self context] request] formValueForKey:@"filterpopup"];
 }
 
-- (EOQualifier *)filterQualifier {
+- (EOQualifier *)filterQualifier
+{
   NSString *selectedFilter;
   
   selectedFilter = [self selectedFilter];
@@ -142,7 +167,8 @@ static NSDictionary *filterToQualifier = nil;
     ? [filterToQualifier objectForKey:selectedFilter] : nil;
 }
 
-- (EOQualifier *)qualifier {
+- (EOQualifier *) qualifier
+{
   EOQualifier *sq, *fq;
   NSArray *qa;
   
diff --git a/UI/MailerUI/UIxMailFolderMenu.h b/UI/MailerUI/UIxMailFolderMenu.h
new file mode 100644 (file)
index 0000000..4a07856
--- /dev/null
@@ -0,0 +1,46 @@
+/* UIxMailFolderMenu.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXMAILFOLDERMENU_H
+#define UIXMAILFOLDERMENU_H
+
+#import "UIxMailTree.h"
+
+@class NSArray;
+
+@interface UIxMailFolderMenu : UIxMailTree
+{
+  NSString *menuId;
+  NSString *parentMenu;
+}
+
+- (void) setMenuId: (NSString *) newMenuId;
+- (NSString *) menuId;
+
+- (void) setParentMenu: (NSString *) newParentMenu;
+- (NSString *) parentMenu;
+
+- (NSArray *) levelledNodes;
+
+@end
+
+#endif /* UIXMAILFOLDERMENU_H */
diff --git a/UI/MailerUI/UIxMailFolderMenu.m b/UI/MailerUI/UIxMailFolderMenu.m
new file mode 100644 (file)
index 0000000..e90d9f4
--- /dev/null
@@ -0,0 +1,84 @@
+/* UIxMailFolderMenu.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+
+#import "UIxMailTreeBlock.h"
+#import "UIxMailFolderMenu.h"
+
+@implementation UIxMailFolderMenu
+
+- (void) setMenuId: (NSString *) newMenuId
+{
+  menuId = newMenuId;
+}
+
+- (NSString *) menuId
+{
+  return menuId;
+}
+
+- (void) setParentMenu: (NSString *) newParentMenu
+{
+  parentMenu = newParentMenu;
+}
+
+- (NSString *) parentMenu
+{
+  return parentMenu;
+}
+
+- (NSArray *) levelledNodes
+{
+  NSEnumerator *nodes;
+  NSMutableArray *levelledNodes;
+  UIxMailTreeBlock *block;
+
+  levelledNodes = [NSMutableArray new];
+  [levelledNodes autorelease];
+
+  nodes = [[self flattenedNodes] objectEnumerator];
+  block = [nodes nextObject];
+
+  while (block)
+    {
+      if ([block parent] == [parentMenu intValue])
+        [levelledNodes addObject: block];
+      block = [nodes nextObject];
+    }
+
+  return levelledNodes;
+}
+
+- (NSString *) iconForMenuItem
+{
+  NSString *iconName;
+
+  iconName = [item iconName];
+  if (!iconName)
+    iconName = [self defaultIconName];
+
+  return [self urlForResourceFilename: iconName];
+}
+
+@end
index 49dded896bf893911f4eefc09a1fe229ca26aa16..2270e2870c47201c6160742fadf2c702a2b53dfc 100644 (file)
@@ -56,6 +56,8 @@
 /* configuration */
 
 - (NSTimeZone *)timeZone;
+- (void) setTimeZone: (NSTimeZone *) newTimeZone;
+
 - (BOOL)showOnlyTimeForToday;
 - (BOOL)showLabelsForNearDays;
 
index e15f27b214504594ea54592e80e3b590bcd2c6d7..0479e953990ef53891d4cd3d2fa542537cebfb02 100644 (file)
@@ -71,10 +71,22 @@ static BOOL debugOn = YES;
 
 /* configuration */
 
-- (NSTimeZone *)timeZone {
+- (NSTimeZone *)timeZone
+{
   return self->timeZone;
 }
 
+- (void) setTimeZone: (NSTimeZone *) newTimeZone
+{
+  if (timeZone)
+    [timeZone release];
+
+  timeZone = newTimeZone;
+
+  if (timeZone)
+    [timeZone retain];
+}
+
 - (BOOL)showOnlyTimeForToday {
   return self->dfFlags.showOnlyTimeForToday ? YES : NO;
 }
@@ -101,7 +113,7 @@ static BOOL debugOn = YES;
     [self->now setTimeZone:[self timeZone]];
   }
   [_date setTimeZone:[self timeZone]];
-  
+
   if ([self showOnlyTimeForToday] && [_date isDateOnSameDay:self->now])
     return [self stringForTime:_date prefix:NULL];
   
similarity index 59%
rename from UI/Scheduler/UIxCalDayPrintview.m
rename to UI/MailerUI/UIxMailListView.h
index b5586f6dd612983c49b86ddc9511acec1114c09c..c98cb4ba59f2898124e74f68a1c9b9ae5cbcba42 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2004 SKYRIX Software AG
+  Copyright (C) 2004-2005 SKYRIX Software AG
 
   This file is part of OpenGroupware.org.
 
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
-
+  
+#ifndef UIXMAILLISTVIEW_H
+#define UIXMAILLISTVIEW_H
 
-#include "UIxCalDayOverview.h"
+#include <SOGoUI/UIxComponent.h>
 
+@class EOQualifier;
 
-@interface UIxCalDayPrintview : UIxCalDayOverview
+@interface UIxMailListView : UIxComponent
 {
+  NSArray     *sortedUIDs; /* we always need to retrieve all anyway! */
+  NSArray     *messages;
+  unsigned    firstMessageNumber;
+  id          message;
+  EOQualifier *qualifier;
 }
 
-@end
-
-#include "common.h"
+- (NSString *)defaultSortKey;
+- (NSString *)imap4SortKey;
+- (NSString *)imap4SortOrdering;
 
-@implementation UIxCalDayPrintview
-
-- (NSString *)title {
-  NSString *fmt;
-  
-  fmt = [self labelForKey:@"dayLabelFormat"];
-  return [[self startDate] descriptionWithCalendarFormat:fmt];
-}
-
-/* style sheet */
-
-- (NSString *)aptStyle {
-  if (![self isMyApt])
-    return @"dayprintview_apt_other";
-  return nil;
-}
+- (BOOL)isSortedDescending;
 
 @end
+
+#endif /* UIXMAILLISTVIEW_H */
index b1008343ae9ce6e3801e5ceeb70c9ac356612619..77e8d59114369a3dd0ccae61d398c8c316de514b 100644 (file)
@@ -19,8 +19,6 @@
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
-
 /*
   UIxMailListView
   
   object.
 */
 
-@class EOQualifier;
-
-@interface UIxMailListView : UIxComponent
-{
-  NSArray     *sortedUIDs; /* we always need to retrieve all anyway! */
-  NSArray     *messages;
-  unsigned    firstMessageNumber;
-  id          message;
-  EOQualifier *qualifier;
-}
-
-- (NSString *)defaultSortKey;
-- (NSString *)imap4SortKey;
-- (NSString *)imap4SortOrdering;
-
-- (BOOL)isSortedDescending;
-
-@end
+#define messagesPerPage 50
 
 #include "common.h"
 #include <SoObjects/Mailer/SOGoMailFolder.h>
 #include <SoObjects/Mailer/SOGoMailObject.h>
 #include <NGObjWeb/SoObject+SoDAV.h>
 
-@implementation UIxMailListView
+#import "UIxMailListView.h"
 
 static int attachmentFlagSize = 8096;
 
-- (void)dealloc {
+@implementation UIxMailListView
+
+- (void) dealloc 
+{
   [self->qualifier  release];
   [self->sortedUIDs release];
   [self->messages   release];
@@ -64,15 +48,10 @@ static int attachmentFlagSize = 8096;
   [super dealloc];
 }
 
-/* frame */
-
-- (BOOL)hideFrame {
-  return [[[[self context] request] formValueForKey:@"noframe"] boolValue];
-}
-
 /* notifications */
 
-- (void)sleep {
+- (void) sleep 
+{
   [self->qualifier  release]; self->qualifier  = nil;
   [self->sortedUIDs release]; self->sortedUIDs = nil;
   [self->messages   release]; self->messages   = nil;
@@ -82,21 +61,28 @@ static int attachmentFlagSize = 8096;
 
 /* accessors */
 
-- (void)setMessage:(id)_msg {
+- (void)setMessage:(id)_msg
+{
   ASSIGN(self->message, _msg);
 }
-- (id)message {
+
+- (id) message 
+{
   return self->message;
 }
 
-- (void)setQualifier:(EOQualifier *)_msg {
+- (void) setQualifier: (EOQualifier *) _msg 
+{
   ASSIGN(self->qualifier, _msg);
 }
-- (EOQualifier *)qualifier {
+
+- (EOQualifier *) qualifier 
+{
   return self->qualifier;
 }
 
-- (BOOL)showToAddress {
+- (BOOL) showToAddress 
+{
   NSString *ftype;
   
   ftype = [[self clientObject] valueForKey:@"outlookFolderClass"];
@@ -105,10 +91,13 @@ static int attachmentFlagSize = 8096;
 
 /* title */
 
-- (NSString *)objectTitle {
+- (NSString *) objectTitle 
+{
   return [[self clientObject] nameInContainer];
 }
-- (NSString *)panelTitle {
+
+- (NSString *) panelTitle 
+{
   NSString *s;
   
   s = [self labelForKey:@"View Mail Folder"];
@@ -119,35 +108,44 @@ static int attachmentFlagSize = 8096;
 
 /* derived accessors */
 
-- (BOOL)isMessageDeleted {
+- (BOOL) isMessageDeleted 
+{
   NSArray *flags;
   
   flags = [[self message] valueForKey:@"flags"];
   return [flags containsObject:@"deleted"];
 }
 
-- (BOOL)isMessageRead {
+- (BOOL) isMessageRead 
+{
   NSArray *flags;
   
   flags = [[self message] valueForKey:@"flags"];
   return [flags containsObject:@"seen"];
 }
-- (NSString *)messageUidString {
+- (NSString *) messageUidString 
+{
   return [[[self message] valueForKey:@"uid"] stringValue];
 }
 
-- (NSString *)messageSubjectStyleClass {
-  return [self isMessageRead]
-    ? @"mailer_readmailsubject"
-    : @"mailer_unreadmailsubject";
-}
-- (NSString *)messageCellStyleClass {
+- (NSString *) messageCellStyleClass 
+{
   return [self isMessageDeleted]
     ? @"mailer_listcell_deleted"
     : @"mailer_listcell_regular";
 }
 
-- (BOOL)hasMessageAttachment {
+- (NSString *) messageSubjectCellStyleClass 
+{
+  return [NSString stringWithFormat: @"%@ %@",
+                  [self messageCellStyleClass],
+                  ([self isMessageRead]
+                   ? @"mailer_readmailsubject"
+                   : @"mailer_unreadmailsubject")];
+}
+
+- (BOOL) hasMessageAttachment 
+{
   /* we detect attachments by size ... */
   unsigned size;
   
@@ -157,7 +155,8 @@ static int attachmentFlagSize = 8096;
 
 /* fetching messages */
 
-- (NSArray *)fetchKeys {
+- (NSArray *) fetchKeys 
+{
   /* Note: see SOGoMailManager.m for allowed IMAP4 keys */
   static NSArray *keys = nil;
   if (keys == nil) {
@@ -167,60 +166,78 @@ static int attachmentFlagSize = 8096;
   return keys;
 }
 
-- (NSString *)defaultSortKey {
+- (NSString *) defaultSortKey 
+{
   return @"DATE";
 }
-- (NSString *)imap4SortKey {
+
+- (NSString *) imap4SortKey 
+{
   NSString *sort;
   
   sort = [[[self context] request] formValueForKey:@"sort"];
-  
+
   if ([sort length] == 0)
     sort = [self defaultSortKey];
+
   return [sort uppercaseString];
 }
 
-- (BOOL)isSortedDescending {
+- (BOOL) isSortedDescending
+{
   NSString *desc;
-  
+
   desc = [[[self context] request] formValueForKey:@"desc"];
-  if(!desc)
-    return NO;
-  return [desc boolValue] ? YES : NO;
+
+  return ((desc)
+          ? [desc boolValue]
+          : YES);
 }
 
-- (NSString *)imap4SortOrdering {
+- (NSString *) imap4SortOrdering 
+{
   NSString *sort;
-  
+
   sort = [self imap4SortKey];
-  if(![self isSortedDescending])
-    return sort;
-  return [@"REVERSE " stringByAppendingString:sort];
+
+  if ([self isSortedDescending])
+    sort = [@"REVERSE " stringByAppendingString: sort];
+
+  return sort;
 }
 
-- (NSRange)fetchRange {
+- (NSRange) fetchRange 
+{
   if (self->firstMessageNumber == 0)
-    return NSMakeRange(0, 50);
-  return NSMakeRange(self->firstMessageNumber - 1, 50);
+    return NSMakeRange(0, messagesPerPage);
+  return NSMakeRange(self->firstMessageNumber - 1, messagesPerPage);
 }
 
-- (NSArray *)sortedUIDs {
-  if (self->sortedUIDs != nil)
-    return self->sortedUIDs;
-  
-  self->sortedUIDs 
-    = [[[self clientObject] fetchUIDsMatchingQualifier:[self qualifier]
-                           sortOrdering:[self imap4SortOrdering]] retain];
+- (NSArray *) sortedUIDs 
+{
+  if (!sortedUIDs)
+    {
+      sortedUIDs 
+        = [[self clientObject] fetchUIDsMatchingQualifier: [self qualifier]
+                               sortOrdering: [self imap4SortOrdering]];
+      [sortedUIDs retain];
+    }
+
   return self->sortedUIDs;
 }
-- (unsigned int)totalMessageCount {
+
+- (unsigned int) totalMessageCount 
+{
   return [self->sortedUIDs count];
 }
-- (BOOL)showsAllMessages {
+
+- (BOOL) showsAllMessages 
+{
   return ([[self sortedUIDs] count] <= [self fetchRange].length) ? YES : NO;
 }
 
-- (NSRange)fetchBlock {
+- (NSRange) fetchBlock 
+{
   NSRange  r;
   unsigned len;
   NSArray  *uids;
@@ -246,27 +263,38 @@ static int attachmentFlagSize = 8096;
     r.length = len - r.location;
   return r;
 }
-- (unsigned int)firstMessageNumber {
+
+- (unsigned int) firstMessageNumber 
+{
   return [self fetchBlock].location + 1;
 }
-- (unsigned int)lastMessageNumber {
+
+- (unsigned int) lastMessageNumber 
+{
   NSRange r;
   
   r = [self fetchBlock];
   return r.location + r.length;
 }
-- (BOOL)hasPrevious {
+
+- (BOOL) hasPrevious 
+{
   return [self fetchBlock].location == 0 ? NO : YES;
 }
-- (BOOL)hasNext {
+
+- (BOOL) hasNext 
+{
   NSRange r = [self fetchBlock];
   return r.location + r.length >= [[self sortedUIDs] count] ? NO : YES;
 }
 
-- (unsigned int)nextFirstMessageNumber {
+- (unsigned int) nextFirstMessageNumber 
+{
   return [self firstMessageNumber] + [self fetchRange].length;
 }
-- (unsigned int)prevFirstMessageNumber {
+
+- (unsigned int) prevFirstMessageNumber 
+{
   NSRange  r;
   unsigned idx;
   
@@ -277,7 +305,8 @@ static int attachmentFlagSize = 8096;
   return 1;
 }
 
-- (NSArray *)messages {
+- (NSArray *) messages 
+{
   NSArray  *uids;
   NSArray  *msgs;
   NSRange  r;
@@ -299,10 +328,14 @@ static int attachmentFlagSize = 8096;
 
 /* URL processing */
 
-- (NSString *)messageViewTarget {
-  return [@"SOGo_msg_" stringByAppendingString:[self messageUidString]];
+- (NSString *) messageViewTarget
+{
+  return [NSString stringWithFormat: @"SOGo_msg_%@",
+                   [self messageUidString]];
 }
-- (NSString *)messageViewURL {
+
+- (NSString *) messageViewURL 
+{
   // TODO: noframe only when view-target is empty
   // TODO: markread only if the message is unread
   NSString *s;
@@ -311,75 +344,43 @@ static int attachmentFlagSize = 8096;
   if (![self isMessageRead]) s = [s stringByAppendingString:@"&markread=1"];
   return s;
 }
-- (NSString *)markReadURL {
+- (NSString *) markReadURL 
+{
   return [@"markMessageRead?uid=" stringByAppendingString:
             [self messageUidString]];
 }
-- (NSString *)markUnreadURL {
+- (NSString *) markUnreadURL 
+{
   return [@"markMessageUnread?uid=" stringByAppendingString:
             [self messageUidString]];
 }
 
 /* JavaScript */
 
-- (NSString *)msgRowID {
+- (NSString *)msgRowID
+{
   return [@"row_" stringByAppendingString:[self messageUidString]];
 }
-- (NSString *)msgDivID {
+
+- (NSString *)msgDivID
+{
   return [@"div_" stringByAppendingString:[self messageUidString]];
 }
 
-- (NSString *)msgIconReadDivID {
+- (NSString *)msgIconReadImgID
+{
   return [@"readdiv_" stringByAppendingString:[self messageUidString]];
 }
-- (NSString *)msgIconUnreadDivID {
-  return [@"unreaddiv_" stringByAppendingString:[self messageUidString]];
-}
-- (NSString *)msgIconReadVisibility {
-  return [self isMessageRead] ? nil : @"display: none;";
-}
-- (NSString *)msgIconUnreadVisibility {
-  return [self isMessageRead] ? @"display: none;" : nil;
-}
 
-- (NSString *)clickedMsgJS {
-  /* return 'false' aborts processing */
-  return [NSString stringWithFormat:@"clickedUid(this, '%@'); return false", 
-                    [self messageUidString]];
-}
-
-// the following are unused?
-- (NSString *)dblClickedMsgJS {
-  return [NSString stringWithFormat:@"doubleClickedUid(this, '%@')", 
-                    [self messageUidString]];
-}
-
-// the following are unused?
-- (NSString *)highlightRowJS {
-  return [NSString stringWithFormat:@"highlightUid(this, '%@')", 
-                    [self messageUidString]];
-}
-- (NSString *)lowlightRowJS {
-  return [NSString stringWithFormat:@"lowlightUid(this, '%@')", 
-                    [self messageUidString]];
-}
-
-- (NSString *)markUnreadJS {
-  return [NSString stringWithFormat:
-                    @"mailListMarkMessage(this, 'markMessageUnread', "
-                    @"'%@', false)", 
-                    [self messageUidString]];
-}
-- (NSString *)markReadJS {
-  return [NSString stringWithFormat:
-                    @"mailListMarkMessage(this, 'markMessageRead', "
-                    @"'%@', true)", 
-                    [self messageUidString]];
+- (NSString *)msgIconUnreadImgID
+{
+  return [@"unreaddiv_" stringByAppendingString:[self messageUidString]];
 }
 
 /* error redirects */
 
-- (id)redirectToViewWithError:(id)_error {
+- (id) redirectToViewWithError: (id) _error 
+{
   // TODO: DUP in UIxMailAccountView
   // TODO: improve, localize
   // TODO: there is a bug in the treeview which preserves the current URL for
@@ -401,7 +402,8 @@ static int attachmentFlagSize = 8096;
 
 /* active message */
 
-- (SOGoMailObject *)lookupActiveMessage {
+- (SOGoMailObject *) lookupActiveMessage 
+{
   NSString *uid;
   
   if ((uid = [[[self context] request] formValueForKey:@"uid"]) == nil)
@@ -413,16 +415,13 @@ static int attachmentFlagSize = 8096;
 
 /* actions */
 
-- (id)defaultAction {
-  self->firstMessageNumber = 
-    [[[[self context] request] formValueForKey:@"idx"] intValue];
-  return self;
-}
-
-- (BOOL)isJavaScriptRequest {
+- (BOOL) isJavaScriptRequest 
+{
   return [[[[self context] request] formValueForKey:@"jsonly"] boolValue];
 }
-- (id)javaScriptOK {
+
+- (id) javaScriptOK 
+{
   WOResponse *r;
 
   r = [[self context] response];
@@ -430,7 +429,46 @@ static int attachmentFlagSize = 8096;
   return r;
 }
 
-- (id)markMessageUnreadAction {
+- (int) firstMessageOfPageFor: (int) messageNbr
+{
+  NSArray *messageNbrs;
+  int nbrInArray;
+  int firstMessage;
+
+  messageNbrs = [self sortedUIDs];
+  nbrInArray
+    = [messageNbrs indexOfObject: [NSNumber numberWithInt: messageNbr]];
+  if (nbrInArray > -1)
+    firstMessage = ((int) (nbrInArray / messagesPerPage)
+                    * messagesPerPage) + 1;
+  else
+    firstMessage = 1;
+
+  return firstMessage;
+}
+
+- (id) defaultAction 
+{
+  WORequest *request;
+  NSString *specificMessage;
+
+  request = [[self context] request];
+  specificMessage = [request formValueForKey: @"pageforuid"];
+  self->firstMessageNumber
+    = ((specificMessage)
+       ? [self firstMessageOfPageFor: [specificMessage intValue]]
+       : [[request formValueForKey:@"idx"] intValue]);
+
+  return self;
+}
+
+- (id) viewAction 
+{
+  return [self defaultAction];
+}
+
+- (id) markMessageUnreadAction 
+{
   NSException *error;
   
   if ((error = [[self lookupActiveMessage] removeFlags:@"seen"]) != nil)
@@ -442,7 +480,9 @@ static int attachmentFlagSize = 8096;
   
   return [self redirectToLocation:@"view"];
 }
-- (id)markMessageReadAction {
+
+- (id) markMessageReadAction 
+{
   NSException *error;
   
   if ((error = [[self lookupActiveMessage] addFlags:@"seen"]) != nil)
@@ -455,26 +495,30 @@ static int attachmentFlagSize = 8096;
   return [self redirectToLocation:@"view"];
 }
 
-- (id)getMailAction {
+- (id) getMailAction 
+{
   // TODO: we might want to flush the caches?
   id client;
-  
+
   if ((client = [self clientObject]) == nil) {
     return [NSException exceptionWithHTTPStatus:404 /* Not Found */
                        reason:@"did not find mail folder"];
   }
-  
-  if (![client respondsToSelector:@selector(flushMailCaches)]) {
-    return [NSException exceptionWithHTTPStatus:500 /* Server Error */
-                       reason:
-                         @"invalid client object (does not support flush)"];
-  }
-  
+
+  if (![client respondsToSelector:@selector(flushMailCaches) ]) 
+    {
+      return [NSException exceptionWithHTTPStatus: 500 /* Server Error */
+                          reason:
+                            @"invalid client object (does not support flush)"];
+    }
+
   [client flushMailCaches];
+
   return [self redirectToLocation:@"view"];
 }
 
-- (id)expungeAction {
+- (id) expungeAction 
+{
   // TODO: we might want to flush the caches?
   NSException *error;
   id client;
@@ -492,7 +536,8 @@ static int attachmentFlagSize = 8096;
   return [self redirectToLocation:@"view"];
 }
 
-- (id)emptyTrashAction {
+- (id) emptyTrashAction 
+{
   // TODO: we might want to flush the caches?
   NSException *error;
   id client;
@@ -533,7 +578,8 @@ static int attachmentFlagSize = 8096;
 
 /* folder operations */
 
-- (id)createFolderAction {
+- (id) createFolderAction 
+{
   NSException *error;
   NSString    *folderName;
   id client;
@@ -559,7 +605,8 @@ static int attachmentFlagSize = 8096;
   return [self redirectToLocation:[folderName stringByAppendingString:@"/"]];
 }
 
-- (id)deleteFolderAction {
+- (id) deleteFolderAction 
+{
   NSException *error;
   NSString *url;
   id client;
@@ -580,4 +627,6 @@ static int attachmentFlagSize = 8096;
   return [self redirectToLocation:url];
 }
 
-@end /* UIxMailListView */
+@end
+
+/* UIxMailListView */
diff --git a/UI/MailerUI/UIxMailMainFrame.h b/UI/MailerUI/UIxMailMainFrame.h
new file mode 100644 (file)
index 0000000..2de7560
--- /dev/null
@@ -0,0 +1,44 @@
+/* UIxMailMainFrame.h - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXMAILMAINFRAME_H
+#define UIXMAILMAINFRAME_H
+
+#import "../Common/UIxPageFrame.h"
+
+@interface UIxMailMainFrame : UIxPageFrame
+{
+  NSString *rootURL;
+  NSString *userRootURL;
+  struct {
+    int hideFolderTree:1;
+    int reserved:31;
+  } mmfFlags;
+}
+
+- (NSString *)rootURL;
+- (NSString *)userRootURL;
+- (NSString *)calendarRootURL;
+
+@end
+
+#endif /* UIXMAILMAINFRAME_H */
index 9a6915e457f04719f081d59f63230bd91888dc25..c9063d6e814263974a194b3fc7c5f9532ba501b0 100644 (file)
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
+#import <SoObjects/Mailer/SOGoMailObject.h>
+#import <SOGoUI/UIxComponent.h>
+#import "UIxMailMainFrame.h"
 
-@interface UIxMailMainFrame : UIxComponent
-{
-  NSString *title;
-  NSString *rootURL;
-  NSString *userRootURL;
-  id       item;
-  struct {
-    int hideFolderTree:1;
-    int hideFrame:1; /* completely disables all the frame around the comp. */
-    int reserved:30;
-  } mmfFlags;
-}
-
-- (NSString *)rootURL;
-- (NSString *)userRootURL;
-- (NSString *)calendarRootURL;
-
-@end
-
-@interface UIxMailPanelFrame : UIxMailMainFrame
-@end
-
-#include "common.h"
-#include <NGObjWeb/SoComponent.h>
+#import "common.h"
+#import <NGObjWeb/SoComponent.h>
 
 @implementation UIxMailMainFrame
 
@@ -61,8 +41,6 @@ static NSString *treeRootClassName = nil;
 }
 
 - (void)dealloc {
-  [self->item        release];
-  [self->title       release];
   [self->rootURL     release];
   [self->userRootURL release];
   [super dealloc];
@@ -81,31 +59,7 @@ static NSString *treeRootClassName = nil;
   return self->mmfFlags.hideFolderTree ? YES : NO;
 }
 
-- (void)setHideFrame:(BOOL)_flag {
-   self->mmfFlags.hideFrame = _flag ? 1 : 0;
-}
-- (BOOL)hideFrame {
-  return self->mmfFlags.hideFrame ? YES : NO;
-}
-
-- (void)setTitle:(NSString *)_value {
-  ASSIGNCOPY(self->title, _value);
-}
-- (NSString *)title {
-  if ([self->title length] == 0)
-    return @"OpenGroupware.org";
-  
-  return self->title;
-}
-
-- (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
-}
-- (id)item {
-  return self->item;
-}
-
-- (NSString *)pageFormURL {
+- (NSString *) pageFormURL {
   NSString *u;
   NSRange  r;
   
@@ -150,22 +104,17 @@ static NSString *treeRootClassName = nil;
 }
 
 - (BOOL)showLinkBanner {
-  return NO;
+  return YES;
 }
+
 - (NSString *)bannerToolbarStyle {
   return nil;
 }
+
 - (NSString *)bannerConsumeStyle {
   return nil;
 }
 
-/* notifications */
-
-- (void)sleep {
-  [self->item release]; self->item = nil;
-  [super sleep];
-}
-
 /* URL generation */
 // TODO: I think all this should be done by the clientObject?!
 // TODO: is the stuff below necessary at all in the mailer frame?
@@ -204,6 +153,7 @@ static NSString *treeRootClassName = nil;
 - (NSString *)calendarRootURL {
   return [[self userRootURL] stringByAppendingString:@"Calendar/"];
 }
+
 - (NSString *)contactsRootURL {
   return [[self userRootURL] stringByAppendingString:@"Contacts/"];
 }
@@ -234,33 +184,55 @@ static NSString *treeRootClassName = nil;
                     @"</script>", errorText];
 }
 
-/* URLs */
-
-- (NSString *)relativeHomePath {
-  return [self relativePathToUserFolderSubPath:@""];
-}
+/* FIXME: migrated methods which might not work yet... */
+#warning check this
+- (NSString *) mailFolderName
+{
+  NSMutableArray *mailboxes;
+  SOGoMailObject *currentObject;
 
-- (NSString *)relativeCalendarPath {
-  return [self relativePathToUserFolderSubPath:@"Calendar/"];
-}
+  mailboxes = [NSMutableArray new];
+  [mailboxes autorelease];
 
-- (NSString *)relativeContactsPath {
-  return [self relativePathToUserFolderSubPath:@"Contacts/"];
-}
+  currentObject = [self clientObject];
+  while (![currentObject isKindOfClass: [SOGoMailAccounts class]])
+    {
+      [mailboxes insertObject: [currentObject nameInContainer] atIndex: 0];
+      currentObject = [currentObject container];
+    }
 
-- (NSString *)relativeMailPath {
-  return [self relativePathToUserFolderSubPath:@"Mail/"];
+  return [NSString stringWithFormat: @"/%@",
+                   [mailboxes componentsJoinedByString: @"/"]];
 }
 
-@end /* UIxMailMainFrame */
-
-@implementation UIxMailPanelFrame
+- (id) composeAction
+{
+  NSArray *c;
+  NSString *inbox, *url, *parameter;
+  NSMutableDictionary *urlParams;
+  id actionResult;
+
+  c = [[self clientObject] toManyRelationshipKeys];
+  if ([c count] > 0)
+    {
+      urlParams = [NSMutableDictionary new];
+      [urlParams autorelease];
+
+      parameter = [self queryParameterForKey: @"mailto"];
+      if (parameter)
+        [urlParams setObject: parameter
+                   forKey: @"mailto"];
+      inbox = [NSString stringWithFormat: @"%@/INBOX",
+                        [c objectAtIndex: 0]];
+      url = [inbox composeURLWithAction: @"compose"
+                   parameters: urlParams
+                   andHash: NO];
+      actionResult = [self redirectToLocation: url];
+    }
+  else
+    actionResult = self;
 
-- (BOOL)hideFolderTree {
-  return YES;
-}
-- (BOOL)showLinkBanner {
-  return NO;
+  return actionResult;
 }
 
-@end /* UIxMailPanelFrame */
+@end /* UIxMailMainFrame */
diff --git a/UI/MailerUI/UIxMailPopupView.m b/UI/MailerUI/UIxMailPopupView.m
new file mode 100644 (file)
index 0000000..2021861
--- /dev/null
@@ -0,0 +1,31 @@
+/* UIxMailPopupView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <SOGoUI/UIxComponent.h>
+
+@interface UIxMailPopupView : UIxComponent
+
+@end
+
+@implementation UIxMailPopupView
+
+@end
diff --git a/UI/MailerUI/UIxMailSplashView.m b/UI/MailerUI/UIxMailSplashView.m
new file mode 100644 (file)
index 0000000..6280118
--- /dev/null
@@ -0,0 +1,29 @@
+/* UIxMailSplashView - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <SOGoUI/UIxComponent.h>
+
+@interface UIxMailSplashView : UIxComponent
+@end
+
+@implementation UIxMailSplashView
+@end /* UIxMailSplashView */
index bd80244320894ba6409ef4c8bdda07a4ab5a3f71..d8c17cbbb65c130acfe11c8de5827034454bca25 100644 (file)
@@ -102,11 +102,23 @@ static NSArray *headers = nil;
 
 /* accessors */
 
-- (void)setTo:(NSArray *)_to {
+- (void)setTo:(NSArray *)_to
+{
   _to = [self properlySplitAddresses:_to];
   ASSIGNCOPY(self->to, _to);
 }
-- (NSArray *)to {
+
+- (NSArray *) to
+{
+  NSString *mailto;
+  mailto = [self queryParameterForKey:@"mailto"];
+  if ([mailto length] > 0 && ![to count])
+    {
+      to = [NSArray arrayWithObject: mailto];
+      [to retain];
+    }
+
   return self->to;
 }
 
@@ -114,6 +126,7 @@ static NSArray *headers = nil;
   _cc = [self properlySplitAddresses:_cc];
   ASSIGNCOPY(self->cc, _cc);
 }
+
 - (NSArray *)cc {
   return self->cc;
 }
diff --git a/UI/MailerUI/UIxMailTree.h b/UI/MailerUI/UIxMailTree.h
new file mode 100644 (file)
index 0000000..dcea0a4
--- /dev/null
@@ -0,0 +1,44 @@
+/* UIxMailTree.h - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006  Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXMAILTREE_H
+#define UIXMAILTREE_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSString;
+
+@interface UIxMailTree : UIxComponent
+{
+  NSString *rootClassName;
+  NSString *treeFolderAction;
+  NSMutableDictionary *flattenedNodes;
+  id rootNodes;
+  id item;
+}
+
+- (NSArray *) flattenedNodes;
+- (NSString *) defaultIconName;
+
+@end
+
+#endif /* UIXMAILTREE_H */
index e6482767453558e5f8be6d16c9c54f8f27651f53..7a81e5d5048328106f0da72ae94a43bfa52196e6 100644 (file)
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
+#import "common.h"
 
-@interface UIxMailTree : UIxComponent
-{
-  NSString *rootClassName;
-  NSString *treeFolderAction;
-  id rootNodes;
-  id item;
-}
-@end
+#import <SoObjects/Mailer/SOGoMailBaseObject.h>
+#import <SoObjects/Mailer/SOGoMailAccount.h>
+#import <SoObjects/Mailer/SOGoMailFolder.h>
+#import <NGObjWeb/SoComponent.h>
+#import <NGObjWeb/SoObject+SoDAV.h>
 
-#include "UIxMailTreeBlock.h"
-#include <SoObjects/Mailer/SOGoMailBaseObject.h>
-#include <SoObjects/Mailer/SOGoMailAccount.h>
-#include "common.h"
-#include <NGObjWeb/SoComponent.h>
-#include <NGObjWeb/SoObject+SoDAV.h>
+#import "UIxMailTree.h"
+#import "UIxMailTreeBlock.h"
 
 /*
   Support special icons:
 
 static BOOL debugBlocks = NO;
 
-+ (void)initialize {
++ (void)initialize
+{
   [UIxMailTreeBlock class]; // ensure that globals are initialized
 }
 
-- (void)dealloc {
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      flattenedNodes = [NSMutableDictionary new];
+    }
+  return self;
+}
+
+- (void) dealloc
+{
   [self->treeFolderAction release];
   [self->rootClassName    release];
   [self->rootNodes release];
   [self->item      release];
+  [flattenedNodes release];
   [super dealloc];
 }
 
 /* icons */
 
-- (NSString *)defaultIconName {
+- (NSString *) defaultIconName
+{
   return @"tbtv_leaf_corner_17x17.gif";
 }
 
@@ -133,7 +139,7 @@ static BOOL debugBlocks = NO;
     [self logWithFormat:@"to-many: %@ %@", _object,
          [names componentsJoinedByString:@","]];
   }
-  
+
   count = [names count];
   ma    = [NSMutableArray arrayWithCapacity:(count + 1)];
   for (i = 0; i < count; i++) {
@@ -180,40 +186,48 @@ static BOOL debugBlocks = NO;
   return [_object isKindOfClass:NSClassFromString([self rootClassName])];
 }
 
-- (NSString *)treeNavigationLinkForObject:(id)_object atDepth:(int)_depth {
-  NSString *link;
-  unsigned i;
-  
-  link = [[_object nameInContainer] stringByAppendingString:@"/"];
-  link = [link stringByAppendingString:[self treeFolderAction]];
-  
-  switch (_depth) {
-  case 0: return link;
-  case 1: return [@"../"       stringByAppendingString:link];
-  case 2: return [@"../../"    stringByAppendingString:link];
-  case 3: return [@"../../../" stringByAppendingString:link];
-  }
+- (NSString *)treeNavigationLinkForObject:(id)_object
+                                 atDepth:(int)_depth
+{
+  NSMutableString *link;
+  int i;
   
+  link = [NSMutableString new];
+  [link autorelease];
+
   for (i = 0; i < _depth; i++)
-    link = [@"../" stringByAppendingString:link];
+    [link appendString: @"../"];
+
+  [link appendFormat: @"%@/%@",
+       [_object nameInContainer],
+       [self treeFolderAction]];
+  
   return link;
 }
 
-- (void)getTitle:(NSString **)_t andIcon:(NSString **)_icon
-  forObject:(id)_object
+- (void) getTitle: (NSString **)_t
+       folderType: (NSString **)_ft
+         andIcon: (NSString **)_icon
+       forObject: (id)_object
 {
   // TODO: need to refactor for reuse!
   NSString *ftype;
   unsigned len;
+
+//   if ([_object respondsToSelector: @selector (outlookFolderClass)])
+//     ftype = [_object outlookFolderClass];
+//   else
+    ftype = [_object valueForKey:@"outlookFolderClass"];
+  len = [ftype length];
   
-  ftype = [_object valueForKey:@"outlookFolderClass"];
-  len   = [ftype length];
-  
+  *_ft = nil;
+
   switch (len) {
   case 8:
     if ([ftype isEqualToString:@"IPF.Sent"]) {
       *_t = [self labelForKey:@"SentFolderName"];
       *_icon = @"tbtv_sent_17x17.gif";
+      *_ft = @"sent";
       return;
     }
     break;
@@ -221,11 +235,13 @@ static BOOL debugBlocks = NO;
     if ([ftype isEqualToString:@"IPF.Inbox"]) {
       *_t = [self labelForKey:@"InboxFolderName"];
       *_icon = @"tbtv_inbox_17x17.gif";
+      *_ft = @"inbox";
       return;
     }
     if ([ftype isEqualToString:@"IPF.Trash"]) {
       *_t = [self labelForKey:@"TrashFolderName"];
       *_icon = @"tbtv_trash_17x17.gif";
+      *_ft = @"trash";
       return;
     }
     break;
@@ -233,44 +249,48 @@ static BOOL debugBlocks = NO;
     if ([ftype isEqualToString:@"IPF.Drafts"]) {
       *_t = [self labelForKey:@"DraftsFolderName"];
       *_icon = @"tbtv_drafts_17x17.gif";
+      *_ft = @"drafts";
       return;
     }
     if ([ftype isEqualToString:@"IPF.Filter"]) {
       *_t = [self labelForKey:@"SieveFolderName"];
       *_icon = nil;
+      *_ft = @"sieve";
       return;
     }
     break;
   }
-  
+
   *_t    = [_object davDisplayName];
   *_icon = nil;
   
   if ([_object isKindOfClass:NSClassFromString(@"SOGoMailFolder")])
     *_icon = nil;
   else if ([_object isKindOfClass:NSClassFromString(@"SOGoMailAccount")]) {
-    *_icon = @"tbtv_inbox_17x17.gif";
+    *_icon = @"tbtv_account_17x17.gif";
+
+    *_ft = @"account";
     
     /* title processing is somehow Agenor specific and should be done in UI */
     *_t = [[_object nameInContainer] titleForSOGoIMAP4String];
   }
   else if ([_object isKindOfClass:NSClassFromString(@"SOGoMailAccounts")])
-    *_icon = @"tbtv_inbox_17x17.gif";
+    *_icon = @"tbtv_account_17x17.gif";
   else if ([_object isKindOfClass:NSClassFromString(@"SOGoUserFolder")])
     *_icon = @"tbtv_inbox_17x17.gif";
   else {
     // TODO: use drafts icon for other SOGo folders
     *_icon = @"tbtv_drafts_17x17.gif";
   }
-  
-  return;
 }
 
-- (UIxMailTreeBlock *)treeNavigationBlockForLeafNode:(id)_o atDepth:(int)_d {
+- (UIxMailTreeBlock *) treeNavigationBlockForLeafNode: (id) _o
+                                             atDepth: (int) _d
+{
   UIxMailTreeBlock *md;
-  NSString *n, *i;
+  NSString *n, *i, *ft;
   id blocks;
-  
+
   /* 
      Trigger plus in treeview if it has subfolders. It is an optimization that
      we do not generate blocks for folders which are not displayed anyway.
@@ -278,14 +298,16 @@ static BOOL debugBlocks = NO;
   blocks = [[_o toManyRelationshipKeys] count] > 0
     ? UIxMailTreeHasChildrenMarker
     : nil;
-  
-  [self getTitle:&n andIcon:&i forObject:_o];
-  
-  md = [UIxMailTreeBlock blockWithName:nil
-                        title:n iconName:i
-                        link:[self treeNavigationLinkForObject:_o atDepth:_d]
-                        isPathNode:NO isActiveNode:NO
-                        childBlocks:blocks];
+
+  [self getTitle: &n folderType: &ft andIcon: &i forObject:_o];
+
+  md = [UIxMailTreeBlock blockWithName: nil
+                        title: n
+                        iconName: i
+                        link: [self treeNavigationLinkForObject:_o atDepth:_d]
+                        isPathNode:NO
+                        isActiveNode:NO
+                        childBlocks: blocks];
   return md;
 }
 
@@ -297,7 +319,7 @@ static BOOL debugBlocks = NO;
   UIxMailTreeBlock *md;
   NSMutableArray   *blocks;
   NSArray          *folders;
-  NSString         *title, *icon;
+  NSString         *title, *icon, *ft;
   unsigned         i, count;
 
   if (debugBlocks) {
@@ -313,7 +335,7 @@ static BOOL debugBlocks = NO;
   for (i = 0; i < count; i++) {
     id block;
     
-    block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
+    block = [self treeNavigationBlockForLeafNode: [folders objectAtIndex:i]
                  atDepth:0];
     if ([block isNotNull]) [blocks addObject:block];
   }
@@ -322,17 +344,63 @@ static BOOL debugBlocks = NO;
   
   /* build block */
   
-  [self getTitle:&title andIcon:&icon forObject:_object];
-  md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
-                        title:title iconName:icon
-                        link:[@"../" stringByAppendingString:
-                                 [_object nameInContainer]]
-                        isPathNode:YES isActiveNode:YES
-                        childBlocks:blocks];
+  [self getTitle:&title folderType: &ft andIcon:&icon forObject:_object];
+
+  md = [UIxMailTreeBlock blockWithName: [_object nameInContainer]
+                        title: title
+                        iconName: icon
+                        link: [@"../" stringByAppendingString:
+                                  [_object nameInContainer]]
+                        isPathNode: YES
+                        isActiveNode: YES
+                        childBlocks: blocks];
   return md;
 }
 
-- (UIxMailTreeBlock *)treeNavigationBlockForActiveNode:(id)_object {
+- (UIxMailTreeBlock *) fullTreeNavigationBlockForNode: (id)_object
+{
+  UIxMailTreeBlock *md;
+  NSMutableArray   *blocks;
+  NSArray          *folders;
+  NSString         *title, *icon, *ft;
+  unsigned         i, count;
+
+  if (debugBlocks)
+    [self logWithFormat:@"block for root node 0x%08X<%@>", 
+           _object, NSStringFromClass([_object class])];
+  
+  folders = [self fetchSubfoldersOfObject: _object];
+  count   = [folders count];
+  blocks  = [NSMutableArray arrayWithCapacity: count];
+  for (i = 0; i < count; i++)
+    {
+      id block;
+    
+      block = [self fullTreeNavigationBlockForNode: [folders objectAtIndex:i]];
+      if ([block isNotNull]) [blocks addObject:block];
+    }
+
+  if (![blocks count])
+    blocks = nil;
+  
+  [self getTitle: &title folderType: &ft andIcon: &icon forObject: _object];
+//   NSLog (@"*********** title = '%@'/icon = '%@'", title, icon);
+
+  md = [UIxMailTreeBlock blockWithName: [_object nameInContainer]
+                        title: title
+                        iconName: icon
+                        link: [@"../" stringByAppendingString:
+                                  [_object nameInContainer]]
+                        isPathNode: YES
+                        isActiveNode: YES
+                        childBlocks: blocks];
+  [md setFolderType: ft];
+
+  return md;
+}
+
+- (UIxMailTreeBlock *) treeNavigationBlockForActiveNode: (id) _object
+{
   /* 
      This generates the block for the clientObject (the object which has the 
      focus)
@@ -340,7 +408,7 @@ static BOOL debugBlocks = NO;
   UIxMailTreeBlock *md;
   NSMutableArray   *blocks;
   NSArray  *folders;
-  NSString *title, *icon;
+  NSString *title, *icon, *ft;
   unsigned i, count;
 
   // TODO: maybe we can join the two implementations, this might not be
@@ -362,26 +430,29 @@ static BOOL debugBlocks = NO;
   for (i = 0; i < count; i++) {
     UIxMailTreeBlock *block;
     
-    block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
-                 atDepth:0];
+    block = [self treeNavigationBlockForLeafNode: [folders objectAtIndex:i]
+                 atDepth: 0];
     if ([block isNotNull]) [blocks addObject:block];
   }
   if ([blocks count] == 0) blocks = nil;
-  
+
   /* build block */
   
-  [self getTitle:&title andIcon:&icon forObject:_object];
-  md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
-                        title:title iconName:icon
-                        link:@"."
-                        isPathNode:YES isActiveNode:YES
-                        childBlocks:blocks];
+  [self getTitle:&title folderType: &ft andIcon:&icon forObject:_object];
+  md = [UIxMailTreeBlock blockWithName: [_object nameInContainer]
+                        title: title
+                        iconName: icon
+                        link: @"."
+                        isPathNode: YES
+                        isActiveNode: YES
+                        childBlocks: blocks];
   return md;
 }
 
-- (UIxMailTreeBlock *)treeNavigationBlockForObject:(id)_object
-  withActiveChildBlock:(UIxMailTreeBlock *)_activeChildBlock 
-  depth:(int)_depth
+- (UIxMailTreeBlock *)
+  treeNavigationBlockForObject: (id) _object
+         withActiveChildBlock: (UIxMailTreeBlock *) _activeChildBlock 
+                        depth: (int) _depth
 {
   /*
     Note: 'activeChildBlock' here doesn't mean that the block is the selected
@@ -392,7 +463,7 @@ static BOOL debugBlocks = NO;
   NSMutableArray   *blocks;
   NSString         *activeName;
   NSArray          *folders;
-  NSString         *title, *icon;
+  NSString         *title, *icon, *ft;
   unsigned         i, count;
   
   activeName = [_activeChildBlock valueForKey:@"name"];
@@ -409,7 +480,8 @@ static BOOL debugBlocks = NO;
     folder = [folders objectAtIndex:i];
     block = [activeName isEqualToString:[folder nameInContainer]]
       ? _activeChildBlock
-      : [self treeNavigationBlockForLeafNode:folder atDepth:_depth];
+      : [self treeNavigationBlockForLeafNode: folder
+             atDepth:_depth];
     
     if ([block isNotNull]) [blocks addObject:block];
   }
@@ -419,17 +491,19 @@ static BOOL debugBlocks = NO;
     else
       blocks = nil;
   }
-  
+
   /* build block */
   
-  [self getTitle:&title andIcon:&icon forObject:_object];
-  resultBlock = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
-                                 title:title iconName:icon
-                                 link:
-                                   [self treeNavigationLinkForObject:_object 
-                                         atDepth:(_depth + 1)] 
-                                 isPathNode:YES isActiveNode:NO
-                                 childBlocks:blocks];
+  [self getTitle:&title folderType: &ft andIcon:&icon forObject:_object];
+  resultBlock
+    = [UIxMailTreeBlock blockWithName: [_object nameInContainer]
+                       title: title
+                       iconName: icon
+                       link:
+                         [self treeNavigationLinkForObject: _object 
+                               atDepth: (_depth + 1)]
+                       isPathNode:YES isActiveNode:NO
+                       childBlocks:blocks];
   
   /* recurse up unless we are at the root */
 
@@ -472,7 +546,7 @@ static BOOL debugBlocks = NO;
   if (debugBlocks) [self logWithFormat:@"ACTIVE parent block ..."];
   block = [self treeNavigationBlockForObject:[_object container] 
                withActiveChildBlock:block
-               depth:1];
+               depth: 1];
   if (debugBlocks) [self logWithFormat:@"done: %@", block];
   return block;
 }
@@ -495,6 +569,77 @@ static BOOL debugBlocks = NO;
   return self->rootNodes;
 }
 
+- (int) addNodes: (NSArray *) nodes
+        atSerial: (int) startSerial
+       forParent: (int) parent
+    withRootName: (NSString *) rootName
+         toArray: (NSMutableArray *) array
+{
+  unsigned int count, max, currentSerial;
+  UIxMailTreeBlock *curNode;
+  NSString *fullName;
+
+  max = [nodes count];
+  currentSerial = startSerial;
+  for (count = 0; count < max; count++)
+    {
+      curNode = [nodes objectAtIndex: count];
+      fullName = [rootName stringByAppendingFormat: @"/%@", [curNode name]];
+      [curNode setName: fullName];
+      [curNode setSerial: currentSerial];
+      [curNode setParent: parent];
+      [array addObject: curNode];
+      if ([curNode hasChildren])
+        currentSerial = [self addNodes: [curNode children]
+                              atSerial: currentSerial + 1
+                              forParent: currentSerial
+                              withRootName: fullName
+                              toArray: array];
+      else
+        currentSerial++;
+    }
+
+  return currentSerial;
+}
+
+- (NSArray *) flattenedNodes
+{
+  NSMutableArray *flattenedBlocks = nil;
+  NSString *userKey;
+  UIxMailTreeBlock *rootNode; // , *curNode;
+  id mailAccounts;
+//   unsigned int count, max;
+
+  userKey = [[self user] login];
+  flattenedBlocks = [flattenedNodes objectForKey: userKey];
+  if (!flattenedBlocks)
+    {
+      flattenedBlocks = [NSMutableArray new];
+
+      if (![[self clientObject] isKindOfClass: NSClassFromString(@"SOGoMailAccounts")])
+       mailAccounts = [[self clientObject] mailAccountsFolder];
+      else
+       mailAccounts = [self clientObject];
+
+      rootNode = [self fullTreeNavigationBlockForNode: mailAccounts];
+      [self addNodes: [rootNode children]
+           atSerial: 1
+           forParent: 0
+           withRootName: @""
+           toArray: flattenedBlocks];
+
+      [flattenedNodes setObject: flattenedBlocks forKey: userKey];
+//       max = [flattenedBlocks count];
+//       for (count = 0; count < max; count++)
+//     {
+//       curNode = [flattenedBlocks objectAtIndex: count];
+//       NSLog (@"%d: %@/%@", count, [curNode title], [curNode iconName]);
+//     }
+    }
+
+  return flattenedBlocks;
+}
+
 /* notifications */
 
 - (void)sleep {
index cc3b316982b540f140e262a5789019bb353410f2..241914ef702ea0aa897987b61a91e1fec77a7984 100644 (file)
@@ -41,6 +41,9 @@ extern id UIxMailTreeHasChildrenMarker;
   NSString *link;
   NSArray  *blocks;
   NSString *iconName;
+  NSString *folderType;
+  int serial;
+  int parent;
   struct {
     int isPath:1;
     int isActive:1;
@@ -48,19 +51,48 @@ extern id UIxMailTreeHasChildrenMarker;
   } flags;
 }
 
-+ (id)blockWithName:(NSString *)_n title:(NSString *)_t iconName:(NSString *)_i
-  link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
-  childBlocks:(NSArray *)_blocks;
-
-- (id)initWithName:(NSString *)_n title:(NSString *)_t iconName:(NSString *)_i
-  link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
-  childBlocks:(NSArray *)_blocks;
++ (id) blockWithName: (NSString *)_n
+              title: (NSString *)_t
+           iconName: (NSString *)_i
+               link: (NSString *)_link
+         isPathNode: (BOOL)_isPath
+       isActiveNode: (BOOL)_isActive
+        childBlocks: (NSArray *)_blocks;
+
+- (id)initWithName: (NSString *)_n
+            title: (NSString *)_t
+         iconName: (NSString *)_i
+             link: (NSString *)_link
+       isPathNode: (BOOL)_isPath
+      isActiveNode: (BOOL)_isActive
+       childBlocks: (NSArray *)_blocks;
 
 /* accessors */
 
-- (BOOL)hasChildren;
-- (BOOL)areChildrenLoaded;
-- (NSArray *)children;
+- (BOOL) hasChildren;
+- (BOOL) areChildrenLoaded;
+- (NSArray *) children;
+
+- (void) setName: (NSString *) newName;
+- (NSString *) name;
+
+- (void) setSerial: (int) newSerial;
+- (int) serial;
+
+- (void) setParent: (int) newParent;
+- (int) parent;
+
+- (void) setFolderType: (NSString *) newFolderType;
+- (NSString *) folderType;
+
+- (NSString *) serialAsString;
+- (NSString *) parentAsString;
+
+- (NSString *) title;
+- (NSString *) link;
+- (NSString *) iconName;
+
+- (NSString *) folderMenuId;
 
 @end
 
index 257631e4d9c3415cd48f632b47a66372b30b73bd..1aabe3d100e141abd8a9c205eec13db90a4bd569 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxMailTreeBlock.h"
-#include "common.h"
+#import "UIxMailTreeBlock.h"
+#import "common.h"
 
 @implementation UIxMailTreeBlock
 
 id UIxMailTreeHasChildrenMarker = nil;
 
-+ (void)initialize {
++ (void) initialize
+{
   // TODO: needs to be an array because the WETreeView requires a
   //       children array
   UIxMailTreeHasChildrenMarker = 
     [[NSArray alloc] initWithObjects:@"FAKE", nil];
 }
 
-+ (id)blockWithName:(NSString *)_name title:(NSString *)_title
-  iconName:(NSString *)_icon
-  link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
-  childBlocks:(NSArray *)_blocks
++ (id) blockWithName: (NSString *) _name
+              title: (NSString *) _title
+           iconName: (NSString *) _icon
+               link: (NSString *) _link
+         isPathNode: (BOOL) _isPath
+       isActiveNode: (BOOL) _isActive
+        childBlocks: (NSArray *) _blocks
 {
   UIxMailTreeBlock *block;
 
-  block = [[self alloc] initWithName:_name title:_title iconName:_icon
+  block = [[self alloc] initWithName:_name
+                       title:_title
+                       iconName:_icon
                        link:_link
-                       isPathNode:_isPath isActiveNode:_isActive
+                       isPathNode:_isPath
+                       isActiveNode:_isActive
                        childBlocks:_blocks];
   return [block autorelease];
 }
 
-- (id)initWithName:(NSString *)_name title:(NSString *)_title
-  iconName:(NSString *)_icon
-  link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
-  childBlocks:(NSArray *)_blocks
+- (id) initWithName: (NSString *) _name
+             title: (NSString *) _title
+          iconName: (NSString *) _icon
+              link: (NSString *) _link
+        isPathNode: (BOOL) _isPath
+       isActiveNode: (BOOL) _isActive
+       childBlocks: (NSArray *) _blocks
 {
-  if ((self = [self init])) {
-    self->name     = [_name   copy];
-    self->title    = [_title  copy];
-    self->iconName = [_icon copy];
-    self->link     = [_link   copy];
-    self->blocks   = [_blocks retain];
+  if ((self = [self init]))
+    {
+      self->name     = [_name   copy];
+      self->title    = [_title  copy];
+      self->iconName = [_icon copy];
+      self->link     = [_link   copy];
+      self->blocks   = [_blocks retain];
     
-    self->flags.isPath   = _isPath   ? 1 : 0;
-    self->flags.isActive = _isActive ? 1 : 0;
-  }
+      self->flags.isPath   = _isPath   ? 1 : 0;
+      self->flags.isActive = _isActive ? 1 : 0;
+    }
   return self;
 }
 
-- (void)dealloc {
+- (void) dealloc
+{
   [self->iconName release];
   [self->blocks   release];
   [self->name     release];
@@ -76,30 +88,49 @@ id UIxMailTreeHasChildrenMarker = nil;
 
 /* accessors */
 
-- (NSString *)name {
+- (NSString *) name
+{
   return self->name;
 }
-- (NSString *)title {
+
+- (void) setName: (NSString *) newName
+{
+  if (name)
+    [name release];
+  name = [newName copy];
+  if (name)
+    [name retain];
+}
+
+- (NSString *) title
+{
   return self->title;
 }
-- (NSString *)link {
+
+- (NSString *) link
+{
   return self->link;
 }
-- (NSString *)iconName {
+
+- (NSString *) iconName
+{
   return self->iconName;
 }
 
-- (BOOL)hasChildren {
+- (BOOL) hasChildren
+{
   if (self->blocks == UIxMailTreeHasChildrenMarker)
     return YES;
   return [self->blocks count] > 0 ? YES : NO;
 }
 
-- (BOOL)areChildrenLoaded {
+- (BOOL) areChildrenLoaded
+{
   return self->blocks != UIxMailTreeHasChildrenMarker ? YES : NO;
 }
 
-- (NSArray *)children {
+- (NSArray *) children
+{
   if (self->blocks == UIxMailTreeHasChildrenMarker)
     // TODO: print a warning
     return self->blocks;
@@ -107,16 +138,20 @@ id UIxMailTreeHasChildrenMarker = nil;
   return self->blocks;
 }
 
-- (BOOL)isPathNode {
+- (BOOL) isPathNode
+{
   return self->flags.isPath ? YES : NO;
 }
-- (BOOL)isActiveNode {
+
+- (BOOL) isActiveNode
+{
   return self->flags.isActive ? YES : NO;
 }
 
 /* description */
 
-- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+- (void) appendAttributesToDescription: (NSMutableString *) _ms
+{
   if (self->name  != nil) [_ms appendFormat:@" name='%@'", self->name];
   if (self->title != nil) [_ms appendFormat:@" title='%@'", self->title];
   
@@ -129,7 +164,8 @@ id UIxMailTreeHasChildrenMarker = nil;
     [_ms appendFormat:@" children=%@", self->blocks];
 }
 
-- (NSString *)description {
+- (NSString *) description
+{
   NSMutableString *ms;
 
   ms = [NSMutableString stringWithCapacity:64];
@@ -139,4 +175,49 @@ id UIxMailTreeHasChildrenMarker = nil;
   return ms;
 }
 
+- (void) setSerial: (int) newSerial
+{
+  serial = newSerial;
+}
+
+- (int) serial
+{
+  return serial;
+}
+
+- (NSString *) serialAsString
+{
+  return [NSString stringWithFormat: @"%d", serial];
+}
+
+- (void) setParent: (int) newParent
+{
+  parent = newParent;
+}
+
+- (int) parent
+{
+  return parent;
+}
+
+- (void) setFolderType: (NSString *) newFolderType
+{
+  folderType = newFolderType;
+}
+
+- (NSString *) folderType
+{
+  return folderType;
+}
+
+- (NSString *) parentAsString
+{
+  return [NSString stringWithFormat: @"%d", parent];
+}
+
+- (NSString *) folderMenuId
+{
+  return [NSString stringWithFormat: @"__wox_submenu_%d-%d", parent, serial];
+}
+
 @end /* UIxMailTreeBlock */
diff --git a/UI/MailerUI/UIxMailTreeBlockJS.h b/UI/MailerUI/UIxMailTreeBlockJS.h
new file mode 100644 (file)
index 0000000..e27d747
--- /dev/null
@@ -0,0 +1,53 @@
+/* UIxMailTreeBlockJS.h - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXMAILTREEBLOCKJS_H
+#define UIXMAILTREEBLOCKJS_H
+
+#import <SOGoUI/UIxComponent.h>
+
+#import "common.h"
+
+@class NSString;
+@class UIxMailTreeBlock;
+
+@interface UIxMailTreeBlockJS : UIxComponent
+{
+  UIxMailTreeBlock *item;
+  NSString *treeObjectName;
+}
+
+- (void) setItem: (UIxMailTreeBlock *) newItem;
+- (UIxMailTreeBlock *) item;
+
+- (NSString *) iconName;
+
+- (void) setTreeObjectName: (NSString *) newName;
+- (NSString *) treeObjectName;
+
+- (BOOL) isAccount;
+- (BOOL) isInbox;
+- (BOOL) isTrash;
+
+@end
+
+#endif /* UIXMAILTREEBLOCKJS_H */
diff --git a/UI/MailerUI/UIxMailTreeBlockJS.m b/UI/MailerUI/UIxMailTreeBlockJS.m
new file mode 100644 (file)
index 0000000..1e03abe
--- /dev/null
@@ -0,0 +1,113 @@
+/* UIxMailTreeBlockJS.m - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import "UIxMailTreeBlockJS.h"
+
+#import "Common/UIxPageFrame.h"
+
+@implementation UIxMailTreeBlockJS
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      item = nil;
+    }
+
+  return self;
+}
+
+- (void) setItem: (UIxMailTreeBlock *) newItem
+{
+  item = newItem;
+}
+
+- (UIxMailTreeBlock *) item
+{
+  return item;
+}
+
+- (WOResourceManager *) resourceManager
+{
+  WOResourceManager *resourceManager;
+  id c;
+
+  resourceManager = nil;
+
+  c = self;
+  while (!resourceManager
+        && c)
+    if ([c respondsToSelector: @selector(pageResourceManager)])
+      resourceManager = [c pageResourceManager];
+    else
+      c = [c parent];
+
+  return resourceManager;
+}
+
+- (NSString *) iconName
+{
+  WOResourceManager *resourceManager;
+  NSString *iconName, *rsrcIconName;
+
+  iconName = [item iconName];
+  if ([iconName length] > 0)
+    {
+      resourceManager = [self resourceManager];
+      rsrcIconName = [resourceManager urlForResourceNamed: iconName
+                                     inFramework: nil
+                                     languages: nil
+                                     request: [[self context] request]];
+    }
+  else
+    rsrcIconName = nil;
+
+  return rsrcIconName;
+}
+
+- (void) setTreeObjectName: (NSString *) newName
+{
+  treeObjectName = newName;
+}
+
+- (NSString *) treeObjectName
+{
+  return treeObjectName;
+}
+
+- (BOOL) isAccount
+{
+  return ([item parent] == 0);
+}
+
+- (BOOL) isInbox
+{
+  return ([[item name] isEqualToString: @"INBOX"]);
+}
+
+- (BOOL) isTrash
+{
+  return NO;
+}
+
+
+@end
index 9e5731ab880f281a5aad4228b93c6d59f10d9e21..7a9027ab2f507a12ec462ac53c05c7e36e1180bf 100644 (file)
@@ -19,6 +19,9 @@
   02111-1307, USA.
 */
 
+#import <Foundation/NSException.h>
+#import <NGExtensions/NSException+misc.h>
+
 #include <SOGoUI/UIxComponent.h>
 
 @interface UIxMailView : UIxComponent
@@ -67,52 +70,49 @@ static NSString *mailETag = nil;
 }
 
 - (void)dealloc {
-  [self->currentAddress release];
   [super dealloc];
 }
 
-/* notifications */
-
-- (void)sleep {
-  [self->currentAddress release]; self->currentAddress = nil;
-  [super sleep];
-}
-
 /* accessors */
 
-- (void)setCurrentAddress:(id)_addr {
-  ASSIGN(self->currentAddress, _addr);
+- (void) setCurrentAddress: (id) _addr
+{
+  currentAddress = _addr;
 }
-- (id)currentAddress {
-  return self->currentAddress;
+
+- (id) currentAddress
+{
+  return currentAddress;
 }
 
-- (NSString *)objectTitle {
+- (NSString *) objectTitle
+{
   return [[self clientObject] subject];
 }
-- (NSString *)panelTitle {
-  NSString *s;
-  
-  s = [self labelForKey:@"View Mail"];
-  s = [s stringByAppendingString:@": "];
-  s = [s stringByAppendingString:[self objectTitle]];
-  return s;
+
+- (NSString *) panelTitle
+{
+  return [NSString stringWithFormat: @"%@: %@",
+                   [self labelForKey: @"View Mail"],
+                   [self objectTitle]];
 }
 
 /* expunge / delete setup and permissions */
 
-- (BOOL)isTrashingAllowed {
+- (BOOL) isTrashingAllowed
+{
   id trash;
   
   trash = [[[self clientObject] mailAccountFolder] 
-                 trashFolderInContext:[self context]];
+            trashFolderInContext:context];
   if ([trash isKindOfClass:[NSException class]])
     return NO;
-  
+
   return [trash isWriteAllowed];
 }
 
-- (BOOL)showMarkDeletedButton {
+- (BOOL) showMarkDeletedButton
+{
   // TODO: we might also want to add a default to always show delete
   if (![[self clientObject] isDeletionAllowed])
     return NO;
@@ -120,7 +120,8 @@ static NSString *mailETag = nil;
   return [self isTrashingAllowed] ? NO : YES;
 }
 
-- (BOOL)showTrashButton {
+- (BOOL) showTrashButton
+{
   if (![[self clientObject] isDeletionAllowed])
     return NO;
   
@@ -156,7 +157,7 @@ static NSString *mailETag = nil;
   id info;
   
   info = [[self clientObject] bodyStructure];
-  return [[[self context] mailRenderingContext] viewerForBodyInfo:info];
+  return [[context mailRenderingContext] viewerForBodyInfo:info];
 }
 
 /* actions */
@@ -172,7 +173,7 @@ static NSString *mailETag = nil;
     */
     NSString *s;
     
-    if ((s = [[[self context] request] headerForKey:@"if-none-match"])) {
+    if ((s = [[context request] headerForKey:@"if-none-match"])) {
       if ([s rangeOfString:mailETag].length > 0) { /* not perfectly correct */
        /* client already has the proper entity */
        // [self logWithFormat:@"MATCH: %@ (tag %@)", s, mailETag];
@@ -182,8 +183,8 @@ static NSString *mailETag = nil;
                              reason:@"message got deleted"];
        }
        
-       [[[self context] response] setStatus:304 /* Not Modified */];
-       return [[self context] response];
+       [[context response] setStatus:304 /* Not Modified */];
+       return [context response];
       }
     }
   }
@@ -207,7 +208,7 @@ static NSString *mailETag = nil;
 - (id)redirectToParentFolder {
   id url;
   
-  url = [[[self clientObject] container] baseURLInContext:[self context]];
+  url = [[[self clientObject] container] baseURLInContext:context];
   return [self redirectToLocation:url];
 }
 
@@ -254,10 +255,10 @@ static NSString *mailETag = nil;
     [self logWithFormat:@"WARNING: method is invoked using safe HTTP method!"];
   }
   
-  if ((ex = [[self clientObject] trashInContext:[self context]]) != nil) {
+  if ((ex = [[self clientObject] trashInContext:context]) != nil) {
     id url;
     
-    if ([[[[self context] request] formValueForKey:@"jsonly"] boolValue])
+    if ([[[context request] formValueForKey:@"jsonly"] boolValue])
       /* called using XMLHttpRequest */
       return ex;
     
@@ -266,10 +267,10 @@ static NSString *mailETag = nil;
     return [self redirectToLocation:url];
   }
 
-  if ([[[[self context] request] formValueForKey:@"jsonly"] boolValue]) {
+  if ([[[context request] formValueForKey:@"jsonly"] boolValue]) {
     /* called using XMLHttpRequest */
-    [[[self context] response] setStatus:200 /* OK */];
-    return [[self context] response];
+    [[context response] setStatus:200 /* OK */];
+    return [context response];
   }
   
   if (![self isInlineViewer]) {
@@ -284,9 +285,42 @@ static NSString *mailETag = nil;
   return [self redirectToParentFolder];
 }
 
-- (id)getMailAction {
-  // TODO: we might want to flush the caches?
-  return [self redirectToLocation:@"view"];
+- (id <WOActionResults>) moveAction
+{
+  id <WOActionResults> result;
+  NSString *destinationFolder;
+  id url;
+
+  if ([self isInvokedBySafeMethod]) {
+    // TODO: fix UI to use POST for unsafe actions
+    [self logWithFormat:@"WARNING: method is invoked using safe HTTP method!"];
+  }
+
+  destinationFolder = [self queryParameterForKey: @"tofolder"];
+  if ([destinationFolder length] > 0)
+    {
+      result = [[self clientObject] moveToFolderNamed: destinationFolder
+                                    inContext: context];
+      if (result)
+        {
+          if (![[[context request] formValueForKey:@"jsonly"] boolValue])
+            {
+              url = [NSString stringWithFormat: @"view?error=%@",
+                              [[result reason] stringByEscapingURL]];
+              result = [self redirectToLocation: url];
+            }
+        }
+      else
+        {
+          result = [context response];
+          [result setStatus: 200];
+        }
+    }
+  else
+    result = [NSException exceptionWithHTTPStatus:500 /* Server Error */
+                          reason: @"No destination folder given"];
+
+  return result;
 }
 
 /* generating response */
index 9489b7d0298c31913a8aaaab94b750f32da17f67..fb4b4432c6b17e84687c27204fb4f09dff8b1b77 100644 (file)
@@ -23,6 +23,8 @@
 #include "UIxMailFormatter.h"
 #include "common.h"
 
+#include <SoObjects/SOGo/SOGoUser.h>
+
 @implementation WOContext(UIxMailer)
 
 // TODO: make configurable
   return [[[UIxSubjectFormatter alloc] init] autorelease];
 }
 
-- (NSFormatter *)mailDateFormatter {
-  return [[[UIxMailDateFormatter alloc] init] autorelease];
+- (NSFormatter *)mailDateFormatter
+{
+  NSTimeZone *userTZ;
+  NSString *userTZString;
+  id userPrefs;
+  static id dateFormatter = nil;
+
+  if (!dateFormatter)
+    {
+      dateFormatter = [UIxMailDateFormatter new];
+      userPrefs = [[self activeUser] userDefaults];
+      userTZString = [userPrefs stringForKey: @"timezonename"];
+      if ([userTZString length] > 0)
+       {
+         userTZ = [NSTimeZone timeZoneWithName: userTZString];
+         [dateFormatter setTimeZone: userTZ];
+       }
+    }
+
+  return dateFormatter;
 }
 
 - (NSFormatter *)mailEnvelopeAddressFormatter {
index 35f10cb2e322a9da6118a609b6921d62a92d2411..cd3b540bc80285142e846024bcacc8acb84e566c 100644 (file)
@@ -1,4 +1,4 @@
-{
+{ /* -*-cperl-*- */
   requires = ( MAIN, CommonUI, Mailer, Sieve );
 
   publicResources = (
@@ -12,7 +12,7 @@
     "UIxMailToSelection.js",
 
     "lori_32x32.png",
-    
+
     "tbtv_account_17x17.gif",
     "tbtv_drafts_17x17.gif",
     "tbtv_inbox_17x17.gif",
@@ -27,7 +27,7 @@
     "tbtv_corner_plus_17x17.gif",
     "tbtv_sent_17x17.gif",
     "tbtv_trash_17x17.gif",
-    
+
     "tbtb_addressbook.png",
     "tbtb_compose.png",
     "tbtb_delete.png",
       slots = {
         toolbar = {
           protectedBy = "View";
-          value = "SOGoMailFolder.toolbar";
+          value = "SOGoMailObject.toolbar";
         };
       };
       methods = {
         view = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
+        };
+        ajax = {
+          protectedBy = "View";
+          pageName    = "UIxMailAjaxRequest";
         };
         index = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
         };
         GET = { /* hack to make it work as the default method */
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
         };
-        
         markMessageUnread = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
           actionName  = "markMessageUnread";
         };
         markMessageRead = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
           actionName  = "markMessageRead";
         };
         getMail = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
           actionName  = "getMail";
         };
         expunge = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
           actionName  = "expunge";
         };
-        
+
         createFolder = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
           actionName  = "createFolder";
         };
         deleteFolder = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
           actionName  = "deleteFolder";
         };
-       
         editACL = {
           protectedBy = "View";
           pageName    = "UIxMailFolderACLEditor";
         };
-        
         compose = {
           protectedBy = "View";
-          actionClass = "UIxMailEditorAction"; 
+          actionClass = "UIxMailEditorAction";
           actionName  = "compose";
         };
       };
       slots = {
         toolbar = {
           protectedBy = "View";
-          value = "SOGoTrashFolder.toolbar";
+          value = "SOGoMailObject.toolbar";
         };
       };
       methods = {
         emptyTrash = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
           actionName  = "emptyTrash";
         };
       };
         };
       };
       methods = {
-        view = { 
+        view = {
           protectedBy = "View";
-          pageName    = "UIxMailView"; 
+          pageName    = "UIxMailView";
         };
-
-        getMail = {
+        popupview = {
           protectedBy = "View";
-          pageName    = "UIxMailView"; 
-          actionName  = "getMail";
+          pageName    = "UIxMailPopupView";
         };
-
-        delete = { 
+        move = {
           protectedBy = "View";
-          pageName    = "UIxMailView"; 
+          pageName    = "UIxMailView";
+          actionName  = "move";
+        };
+        delete = {
+          protectedBy = "View";
+          pageName    = "UIxMailView";
           actionName  = "delete";
         };
-        trash = { 
+        trash = {
           protectedBy = "View";
-          pageName    = "UIxMailView"; 
+          pageName    = "UIxMailView";
           actionName  = "trash";
         };
-        junk = { 
+        junk = {
           protectedBy = "View";
-          pageName    = "UIxMailView"; 
+          pageName    = "UIxMailView";
           actionName  = "junk";
         };
-        edit = { 
+        edit = {
           protectedBy = "View";
-          pageName    = "UIxMailEditor"; 
+          pageName    = "UIxMailEditor";
         };
         compose = {
           protectedBy = "View";
-          actionClass = "UIxMailEditorAction"; 
+          actionClass = "UIxMailEditorAction";
           actionName  = "compose";
         };
         reply = {
           protectedBy = "View";
-          actionClass = "UIxMailReplyAction"; 
+          actionClass = "UIxMailReplyAction";
           actionName  = "reply";
         };
         replyall = {
           protectedBy = "View";
-          actionClass = "UIxMailReplyAction"; 
+          actionClass = "UIxMailReplyAction";
           actionName  = "replyall";
         };
         forward = {
           protectedBy = "View";
-          actionClass = "UIxMailForwardAction"; 
+          actionClass = "UIxMailForwardAction";
           actionName  = "forward";
         };
       };
     };
-    
+
     SOGoMailAccounts = {
       slots = {
         toolbar = {
           protectedBy = "View";
-          value = ( /* the toolbar groups */
-            ( /* first group */
-              { link  = "getMail";
-                cssClass = "tbicon_getmail"; label = "Get Mail"; },
-            )
-          );
+          value = "SOGoMailObject.toolbar";
         };
       };
       methods = {
         view = {
           protectedBy = "View";
-          pageName    = "UIxMailAccountsView"; 
+          pageName    = "UIxMailMainFrame";
+        };
+        compose = {
+          protectedBy = "View";
+          pageName    = "UIxMailMainFrame";
+          actionName  = "compose";
         };
         getMail = {
           protectedBy = "View";
-          pageName    = "UIxMailAccountsView"; 
+          pageName    = "UIxMailAccountsView";
         };
       };
     };
-    
+
     SOGoMailAccount = {
       slots = {
         toolbar = {
           protectedBy = "View";
-          value = "SOGoMailAccount.toolbar";
+          value = "SOGoMailObject.toolbar";
         };
       };
       methods = {
         view = {
           protectedBy = "View";
-          pageName    = "UIxMailAccountView"; 
+          pageName    = "UIxMailAccountView";
         };
         getMail = {
           protectedBy = "View";
-          pageName    = "UIxMailAccountView"; 
+          pageName    = "UIxMailAccountView";
         };
         addressbook = {
           protectedBy = "View";
-          pageName    = "UIxMailAddressbook"; 
+          pageName    = "UIxMailAddressbook";
         };
         anais = {
           protectedBy = "View";
         };
         compose = {
           protectedBy = "View";
-          actionClass = "UIxMailEditorAction"; 
+          actionClass = "UIxMailEditorAction";
           actionName  = "compose";
         };
         createFolder = {
           protectedBy = "View";
-          pageName    = "UIxMailAccountView"; 
+          pageName    = "UIxMailAccountView";
           actionName  = "createFolder";
         };
       };
           value = ( /* the toolbar groups */
             ( /* first group */
               { link  = "getMail";
+               image = "tb-mail-getmail-flat-24x24.png";
                 cssClass = "tbicon_getmail"; label = "Get Mail"; },
               {
-                link     = "#"; // "compose"; // target = "_blank";
-                isSafe = NO;
-                onclick  = "clickedCompose(this);return false;";
-                cssClass = "tbicon_compose"; label = "Write"; },
+              link     = "#"; // "compose"; // target = "_blank";
+              isSafe = NO;
+               onclick  = "return openMessageWindow(null, 'compose');";
+              image = "tb-mail-write-flat-24x24.png";
+              cssClass = "tbicon_compose"; label = "Write"; },
             )
           );
         };
       methods = {
         view = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
         };
         getMail = {
           protectedBy = "View";
-          pageName    = "UIxMailListView"; 
+          pageName    = "UIxMailListView";
         };
         compose = {
           protectedBy = "View";
-          actionClass = "UIxMailEditorAction"; 
+          actionClass = "UIxMailEditorAction";
           actionName  = "compose";
         };
       };
       methods = {
         view = { /* somewhat hackish */
           protectedBy = "View";
-          pageName    = "UIxMailEditor"; 
+          pageName    = "UIxMailEditor";
         };
         edit = {
           protectedBy = "View";
-          pageName    = "UIxMailEditor"; 
+          pageName    = "UIxMailEditor";
           actionName  = "edit";
         };
         save = {
           protectedBy = "View";
-          pageName    = "UIxMailEditor"; 
+          pageName    = "UIxMailEditor";
           actionName  = "save";
         };
         delete = {
           protectedBy = "View";
-          pageName    = "UIxMailEditor"; 
+          pageName    = "UIxMailEditor";
           actionName  = "delete";
         };
 
         viewAttachments = {
           protectedBy = "View";
-          pageName    = "UIxMailEditorAttach"; 
+          pageName    = "UIxMailEditorAttach";
           actionName  = "viewAttachments";
         };
         attach = {
           protectedBy = "View";
-          pageName    = "UIxMailEditorAttach"; 
+          pageName    = "UIxMailEditorAttach";
           actionName  = "attach";
         };
         deleteAttachment = {
           protectedBy = "View";
-          pageName    = "UIxMailEditorAttach"; 
+          pageName    = "UIxMailEditorAttach";
           actionName  = "deleteAttachment";
         };
 
         send = {
           protectedBy = "View";
-          pageName    = "UIxMailEditor"; 
+          pageName    = "UIxMailEditor";
           actionName  = "send";
         };
         addressbook = {
     };
 
     /* Sieve */
-    
+
     SOGoSieveScriptsFolder = {
       slots = {
         toolbar = {
           value = ( /* the toolbar groups */
             ( /* first group */
               {
-                link  = "getMail";
-                cssClass = "tbicon_getmail"; label = "Get Mail";
+              link  = "getMail";
+              image = "tb-mail-getmail-flat-24x24.png";
+              cssClass = "tbicon_getmail"; label = "Get Mail";
               },
               {
-                link     = "#"; // "compose"; // target = "_blank";
-                onclick  = "clickedNewFilter(this); return false";
-                cssClass = "tbicon_compose"; label = "New Filter";
+              link     = "#"; // "compose"; // target = "_blank";
+              onclick  = "clickedNewFilter(this); return false";
+              image = "tb-mail-write-flat-24x24.png";
+              cssClass = "tbicon_compose"; label = "New Filter";
               },
             ),
             ( /* second group
-              { link = "#"; 
+              { link = "#";
                 cssClass = "tbicon_delete"; label = "Delete"; },*/
             ),
           );
       methods = {
         view = {
           protectedBy = "View";
-          pageName    = "UIxFilterList"; 
+          pageName    = "UIxFilterList";
         };
         create = {
           protectedBy = "View";
-          pageName    = "UIxFilterList"; 
+          pageName    = "UIxFilterList";
           actionName  = "create";
         };
       };
           protectedBy = "View";
           value = ( /* the toolbar groups */
             ( /* first group */
-              { link  = "#"; 
+              { link  = "#";
                 onclick  = "clickedEditorSave(this);return false;";
-                cssClass = "tbicon_save"; label = "Save"; },
-              { link = "#"; 
+               image = "tb-mail-file-flat-24x24.png";
+               cssClass = "tbicon_save"; label = "Save"; },
+              { link = "#";
                 onclick  = "clickedEditorDelete(this);return false;";
+               image = "tb-mail-delete-flat-24x24.png";
                 cssClass = "tbicon_delete"; label = "Delete"; },
             )
           );
       methods = {
         edit = {
           protectedBy = "View";
-          pageName    = "UIxSieveEditor"; 
+          pageName    = "UIxSieveEditor";
           actionName  = "edit";
         };
         save = {
           protectedBy = "View";
-          pageName    = "UIxSieveEditor"; 
+          pageName    = "UIxSieveEditor";
           actionName  = "save";
         };
         delete = {
           protectedBy = "View";
-          pageName    = "UIxSieveEditor"; 
+          pageName    = "UIxSieveEditor";
           actionName  = "delete";
         };
       };
index 880d737ec81807a7a40b898e238e1c8775fbfaed..90f6e89c342155655dfd35d4987f02ca8c9ceef3 100644 (file)
@@ -4,7 +4,7 @@
 
 "Internet access authorized and" = "L'accès depuis internet est autorisé et ";
 "Internet access unauthorized and" = "L'accès depuis internet est interdit et "; 
-"internetAccessState_0" = "FERMÉ"
+"internetAccessState_0" = "FERMÉ";
 "internetAccessState_1" = "OUVERT";
 
 "Automatic vacation messages activation" = "Activation du message de réponse automatique ";
index 9b48c556fb761ea9dd456fc1f89273720d241e08..0432e77faa928b3556c15e30e186788c77acee2b 100644 (file)
@@ -17,14 +17,7 @@ MainUI_OBJC_FILES += \
 
 MainUI_RESOURCE_FILES +=       \
        Version                 \
-       product.plist           \
-       \
-       SOGoRootPage.wox        \
-       SOGoUserHomePage.wox    \
-       SOGoGroupPage.wox       \
-       SOGoGroupsPage.wox      \
-       \
-       homepage.js             \
+       product.plist
 
 MainUI_LOCALIZED_RESOURCE_FILES += \
        Locale Localizable.strings
index 564fe0d2aa39511b50b0893d435e9c3d8f672beb..01aa6af4e53c877d4b98bcf1af19a2400bddcbe9 100644 (file)
   02111-1307, USA.
 */
 
-#include <NGObjWeb/SoComponent.h>
+#import <NGObjWeb/WOResponse.h>
+#import <SoObjects/Appointments/SOGoFreeBusyObject.h>
+#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
 
-@interface SOGoUserHomePage : SoComponent
+#import <SOGoUI/UIxComponent.h>
+#import <Scheduler/UIxComponent+Agenor.h>
+
+@interface SOGoUserHomePage : UIxComponent
 {
   id item;
 }
@@ -153,7 +159,9 @@ static NSArray *internetAccessStates = nil;
 }
 
 - (NSString *)relativeMailPath {
-  return [self relativePathToUserFolderSubPath:@"Mail/"];
+  return [NSString stringWithFormat: @"%@%@/view",
+                  [self relativePathToUserFolderSubPath:@"Mail/"],
+                  [self emailForUser]];
 }
 
 /* objects */
@@ -230,4 +238,116 @@ static NSArray *internetAccessStates = nil;
   return [NSException exceptionWithHTTPStatus:200 /* OK */];
 }
 
+- (void) _fillFreeBusyItems: (NSMutableArray *) items
+                withRecords: (NSEnumerator *) records
+              fromStartDate: (NSCalendarDate *) startDate
+                  toEndDate: (NSCalendarDate *) endDate
+{
+  NSDictionary *record;
+  int count, startInterval, endInterval, value;
+  NSNumber *status;
+  NSCalendarDate *currentDate;
+
+  record = [records nextObject];
+  while (record)
+    {
+      status = [record objectForKey: @"status"];
+
+      value = [[record objectForKey: @"startdate"] intValue];
+      currentDate = [NSCalendarDate dateWithTimeIntervalSince1970: value];
+      if ([currentDate earlierDate: startDate] == currentDate)
+        startInterval = 0;
+      else
+        startInterval
+          = ([currentDate timeIntervalSinceDate: startDate] / 900);
+
+      value = [[record objectForKey: @"enddate"] intValue];
+      currentDate = [NSCalendarDate dateWithTimeIntervalSince1970: value];
+      if ([currentDate earlierDate: endDate] == endDate)
+        endInterval = [items count] - 1;
+      else
+        endInterval = ([currentDate timeIntervalSinceDate: startDate] / 900);
+
+      for (count = startInterval; count < endInterval; count++)
+        [items replaceObjectAtIndex: count withObject: status];
+
+      record = [records nextObject];
+    }
+}
+
+- (NSString *) _freeBusyAsTextFromStartDate: (NSCalendarDate *) startDate
+                                  toEndDate: (NSCalendarDate *) endDate
+                                forFreeBusy: (SOGoFreeBusyObject *) fb
+{
+  NSEnumerator *records;
+  NSMutableArray *freeBusyItems;
+  NSTimeInterval interval;
+  int count, intervals;
+
+  interval = [endDate timeIntervalSinceDate: startDate] + 60;
+  intervals = interval / 900; /* slices of 15 minutes */
+  freeBusyItems = [NSMutableArray arrayWithCapacity: intervals];
+  for (count = 1; count < intervals; count++)
+    [freeBusyItems addObject: @"0"];
+
+  records = [[fb fetchFreeBusyInfosFrom: startDate to: endDate] objectEnumerator];
+  [self _fillFreeBusyItems: freeBusyItems withRecords: records
+        fromStartDate: startDate toEndDate: endDate];
+
+  return [freeBusyItems componentsJoinedByString: @","];
+}
+
+- (NSString *) _freeBusyAsText
+{
+  SOGoFreeBusyObject *co;
+  NSCalendarDate *startDate, *endDate;
+  NSString *queryDay, *additionalDays;
+  NSTimeZone *uTZ;
+
+  co = [self clientObject];
+  uTZ = [co userTimeZone];
+
+  queryDay = [self queryParameterForKey: @"sday"];
+  if ([queryDay length])
+    startDate = [NSCalendarDate dateFromShortDateString: queryDay
+                                andShortTimeString: @"0000"
+                                inTimeZone: uTZ];
+  else
+    {
+      startDate = [NSCalendarDate calendarDate];
+      [startDate setTimeZone: uTZ];
+      startDate = [startDate hour: 0 minute: 0];
+    }
+
+  queryDay = [self queryParameterForKey: @"eday"];
+  if ([queryDay length])
+    endDate = [NSCalendarDate dateFromShortDateString: queryDay
+                              andShortTimeString: @"2359"
+                              inTimeZone: uTZ];
+  else
+    endDate = [startDate hour: 23 minute: 59];
+
+  additionalDays = [self queryParameterForKey: @"additional"];
+  if ([additionalDays length] > 0)
+    endDate = [endDate dateByAddingYears: 0 months: 0
+                       days: [additionalDays intValue]
+                       hours: 0 minutes: 0 seconds: 0];
+
+  return [self _freeBusyAsTextFromStartDate: startDate toEndDate: endDate
+               forFreeBusy: co];
+}
+
+- (id <WOActionResults>) readFreeBusyAction
+{
+  WOResponse *response;
+
+  response = [context response];
+  [response setStatus: 200];
+  [response setHeader: @"text/plain; charset=iso-8859-1"
+            forKey: @"Content-Type"];
+  [response appendContentString: [self _freeBusyAsText]];
+
+  return response;
+}
+
 @end /* SOGoUserHomePage */
diff --git a/UI/MainUI/SOGoUserHomePage.wox b/UI/MainUI/SOGoUserHomePage.wox
deleted file mode 100644 (file)
index d09439a..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name"
->
-  <var:if condition="canAccess" const:negate="YES">
-    <var:string label:value="Forbidden" const:style="window_label" />
-  </var:if>
-  <var:if condition="canAccess">
-      <script rsrc:src="generic.js"  > <!-- space required --></script>
-      <script rsrc:src="homepage.js" > <!-- space required --></script>
-    <table id="skywintable"
-           class="wintable"
-           cellspacing="0"
-           cellpadding="5"
-           width="100%"
-    >
-      <tr>
-        <td class="wintitle">
-          <table cellpadding="0" cellspacing="0" width="100%">
-            <tr>
-              <td width="5"/>
-              <td class="wintitle">
-                <span class="window_label">
-                <var:string label:value="Homepage"/>
-                </span>
-              </td>
-              <td width="36" align="right" valign="center">
-                <var:component className="UIxWinClose"/>
-              </td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-      <tr>
-        <td class="wincontent">
-          <p class="homepagefont">
-            <var:if condition="isNotAllowedToChangeInternetAccess">
-              <var:string label:value="Internet access unauthorized and"
-              /> <var:popup const:name="allowinternet"
-                            list="internetAccessStates"
-                            item="item"
-                            label:string="$itemInternetAccessStateText"
-                            label:selection="internetAccessState_0"
-                            const:disabled="YES"
-                 />
-            </var:if>
-            <var:if condition="isNotAllowedToChangeInternetAccess"
-                    const:negate="YES"
-            >
-              <var:string label:value="Internet access authorized and"
-              /> <var:popup const:name="allowinternet"
-                            list="internetAccessStates"
-                            item="item"
-                            label:string="$itemInternetAccessStateText"
-                            selection="internetAccessState"
-                            const:onchange="toggleInternetAccessState(this)"
-                 />
-            </var:if>
-            <br />
-            <var:string label:value="Automatic vacation messages activation" />:
-            <input type="checkbox"
-                   var:selection="isVacationMessageEnabledForInternet"
-                   var:checked="isVacationMessageEnabledForInternet"
-                   disabled="YES"
-            /> <var:string label:value="Internet" />
-            <input type="checkbox"
-                   var:selection="isVacationMessageEnabledForIntranet"
-                   var:checked="isVacationMessageEnabledForIntranet"
-                   disabled="YES"
-            /> <var:string label:value="Intranet" />
-              <input type="submit"
-                     value="SaveInternetAccessState"
-                     name="saveInternetAccessState:method"
-                     style="display: none;"
-              />
-          </p>
-          <p>
-            <var:component className="UIxCalScheduleOverview"
-                           clientObject="calendarFolder"
-            />
-          </p>
-        </td>
-      </tr>
-      <tr>
-        <td class="wincontent">
-          <table border="0" width="100%" cellpadding="0" cellspacing="0">
-            <tr>
-              <td colspan="2">
-              </td>
-            </tr>
-            <tr bgcolor="#F5F5E9">
-              <td align="left" width="10">
-                <var:entity const:name="nbsp"/>
-              </td>
-              <td align="right">
-                <img border="0"
-                     alt=""
-                     rsrc:src="corner_right.gif"
-                />
-              </td>
-            </tr>
-            <tr>
-              <td colspan="2" bgcolor="#F5F5E9">
-                <table border="0" width="100%" cellpadding="10" cellspacing="0">
-                  <tr/>
-                </table>
-              </td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-    </table>
-  </var:if>
-</var:component>
index 19da3a97bb0e04b8e9911ad97b0e0a5f3811917d..ec730eb813bb607d9cd3da56127db3a2b3c96252 100644 (file)
@@ -4,6 +4,53 @@
   publicResources = (
   );
 
+  factories = {
+  };
+  
+  classes = {
+    SOGoRootPage = {
+      superclass  = "SoComponent";
+      protectedBy = "View";
+      defaultRoles = {
+        "View" = ( "Authenticated", "FreeBusy" );
+      };
+    };
+    SOGoUserFolder = {
+      superclass  = "SOGoFolder";
+      protectedBy = "HomePage Access";
+      defaultRoles = {
+        "Homepage Access" = ( "Owner", "Assistant", "Delegate", "FreeBusy" );
+        "WebDAV Access" = ( "Owner", "Assistant", "Delegate", "FreeBusy" );
+        "Access Contents Information" = ( "Owner", "Assistant", "Delegate",
+                                          "FreeBusy" );
+      };
+    };
+    SOGoFolder = {
+      superclass    = "SOGoObject";
+      protectedBy = "Access Contents Information";
+      defaultRoles = {
+        "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
+        "View"          = ( "Owner", "Delegate", "Assistant" );
+        "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
+        "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
+        "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+        "SaveAcls" = ( "Owner" );
+      };
+    };
+    SOGoGroupsFolder = {
+      superclass    = "SOGoObject";
+      protectedBy = "View";
+    };
+    SOGoGroupFolder = {
+      superclass    = "SOGoObject";
+      protectedBy = "View";
+    };
+    SOGoCustomGroupFolder = {
+      superclass = "SOGoGroupFolder";
+      protectedBy = "View";
+    };
+  };
+
   categories = {
     SOGo = { // TODO: move decls to class
       methods = {
           protectedBy = "View";
           pageName    = "SOGoRootPage"; 
         };
-        connect = { 
-          protectedBy = "View";
-          pageName    = "SOGoRootPage"; 
-          actionName  = "connect";
-        };
       };
     };
-  };
-
-  classes = {
     SOGoRootPage = {
-      superclass    = "SoComponent";
-      protectedBy   = "View";
-      defaultRoles = {
-        "View" = "Authenticated";
-      };
     };
-
     SOGoUserFolder = {
-      superclass    = "SOGoFolder";
-
-      defaultRoles = {
-        "HomePage Access" = "Owner";
-      };
-
       methods = {
         view = { 
           protectedBy = "HomePage Access";
@@ -58,9 +85,7 @@
         */
       };
     };
-    
     SOGoGroupsFolder = {
-      superclass    = "SOGoObject";
       methods = {
         index = { 
           protectedBy = "View";
@@ -69,7 +94,6 @@
       };
     };
     SOGoGroupFolder = {
-      superclass    = "SOGoObject";
       methods = {
         index = { 
           protectedBy = "View";
         };
       };
     };
+    SOGoFreeBusyObject = {
+      methods = {
+        ajaxRead = { 
+          protectedBy = "View";
+          pageName = "SOGoUserHomePage"; 
+          actionName = "readFreeBusy";
+        };
+      };
+    };
     SOGoCustomGroupFolder = {
-      superclass = "SOGoGroupFolder";
       methods = {
       };
     };
index f8c064626af4602d0eca1a6bc4a1b9b40b6c9a04..d0c92e469d9c1addad80fe4f4a7edf94660071a1 100644 (file)
@@ -1,5 +1,6 @@
 # GNUstep makefile
 
+include ../common.make
 -include ../../config.make
 include $(GNUSTEP_MAKEFILES)/common.make
 include ../../Version
@@ -12,6 +13,7 @@ libSOGoUI_HEADER_FILES_INSTALL_DIR = /SOGoUI
 FHS_HEADER_DIRS = SOGoUI
 
 libSOGoUI_HEADER_FILES +=      \
+       \
        UIxComponent.h          \
        SOGoDateFormatter.h     \
        SOGoAptFormatter.h      \
@@ -19,6 +21,7 @@ libSOGoUI_HEADER_FILES +=     \
        WOContext+UIx.h         \
 
 libSOGoUI_OBJC_FILES +=                \
+       \
        UIxComponent.m          \
        SOGoDateFormatter.m     \
        SOGoAptFormatter.m      \
index c265788582ab4d588decf5dee4f46d2c832f55b5..d54766e7c5bd8d3efde068a3a46d16c75ca2c84c 100644 (file)
@@ -10,6 +10,7 @@ libSOGoUI_LIBRARIES_DEPEND_UPON += \
        -lNGObjWeb      \
        -lNGMime        \
        -lNGStreams -lNGExtensions -lEOControl \
-       -lXmlRpc -lDOM -lSaxObjC
+       -lXmlRpc -lDOM -lSaxObjC -lWOExtensions
 
 SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
+ADDITIONAL_INCLUDE_DIRS += -I../../SoObjects
index 70834d1e871d653046b371b61f3a46db0fd09a2f..251ba501228f0bfc0441600dce74927a019117c8 100644 (file)
@@ -44,6 +44,7 @@
 - (void)setFullDetails;
 - (void)setTitleOnly;
 - (void)setShortTitleOnly;
+- (void)setShortMonthTitleOnly;
 - (void)setOmitsEndDate;
 
 - (void)setPrivateTooltip;
index 6f0d91d1ff86d19fcc90a3f9db4fb683b3a47279..0568cc2e8864109df84f3fc8f228195fcecf3d79 100644 (file)
   self->formatAction = @selector(shortTitleForApt::);
 }
 
+- (void)setShortMonthTitleOnly {
+  self->formatAction = @selector(shortMonthTitleForApt::);
+}
+
 - (void)setPrivateSuppressAll {
   self->formatAction = @selector(suppressApt::);
 }
   NSString *title;
   
   title = [self titleForApt:_apt :_refDate];
-  if ([title length] > 12)
-    title = [[title substringToIndex:11] stringByAppendingString:@"..."];
+  if ([title length] > 50)
+    title = [[title substringToIndex: 49] stringByAppendingString:@"..."];
+  
+  return title;
+}
+
+- (NSString *)shortMonthTitleForApt:(id)_apt :(NSCalendarDate *)_refDate {
+  NSMutableString *title;
+  NSCalendarDate *startDate;
+  NSTimeZone *dtz;
+
+  title = [NSMutableString new];
+  [title autorelease];
+
+  dtz        = [self displayTZ];
+  startDate  = [_apt valueForKey: @"startDate"];
+  [startDate setTimeZone:dtz];
+  [self appendTimeInfoForDate: startDate usingReferenceDate: nil
+        toBuffer: title];
+  [title appendFormat: @" %@", [self titleForApt:_apt :_refDate]];
   
   return title;
 }
   return aptDescr;
 }
 
-- (NSString *)fullDetailsForApt:(id)_apt :(NSCalendarDate *)_refDate {
+- (NSString *) fullDetailsForApt: (id)_apt
+                                : (NSCalendarDate *)_refDate
+{
   NSMutableString *aptDescr;
-  NSString        *s;
-    
-  aptDescr = [NSMutableString stringWithCapacity:60];
-  [self appendTimeInfoFromApt:_apt
-        usingReferenceDate:_refDate
-        toBuffer:aptDescr];
-  if ((s = [_apt valueForKey:@"location"]) != nil) {
-    if([s length] > 12)
-      s = [[s substringToIndex:11] stringByAppendingString:@"..."];
-    [aptDescr appendFormat:@" (%@)", s];
-  }
-  if ((s = [self shortTitleForApt:_apt :_refDate]) != nil)
+  NSString *s;
+
+  aptDescr = [NSMutableString stringWithCapacity: 60];
+  [self appendTimeInfoFromApt: _apt
+        usingReferenceDate: _refDate
+        toBuffer: aptDescr];
+  s = [_apt valueForKey: @"location"];
+  if ([s length] > 0)
+    {
+      if ([s length] > 50)
+        s = [[s substringToIndex: 49] stringByAppendingString: @"..."];
+      [aptDescr appendFormat:@" (%@)", s];
+    }
+  s = [self shortTitleForApt: _apt : _refDate];
+  if ([s length] > 0)
     [aptDescr appendFormat:@"<br />%@", s];
   
   return aptDescr;
 }
 
-- (NSString *)detailsForPrivateApt:(id)_apt :(NSCalendarDate *)_refDate {
+- (NSString *) detailsForPrivateApt: (id) _apt
+                                   : (NSCalendarDate *) _refDate
+{
   NSMutableString *aptDescr;
   NSString        *s;
 
   return aptDescr;
 }
 
-- (NSString *)titleOnlyForPrivateApt:(id)_apt :(NSCalendarDate *)_refDate {
+- (NSString *) titleOnlyForPrivateApt: (id)_apt
+                                     : (NSCalendarDate *) _refDate
+{
   NSString *s;
   
   s = [self privateTitle];
-  if(!s)
-    return @"";
+  if (!s)
+    s = @"";
+
   return s;
 }
 
-- (NSString *)tooltipForApt:(id)_apt :(NSCalendarDate *)_refDate {
+- (NSString *) tooltipForApt: (id)_apt
+                            : (NSCalendarDate *) _refDate
+{
   NSMutableString *aptDescr;
-  NSString        *s;
+  NSString *s;
 
-  aptDescr = [NSMutableString stringWithCapacity:60];
-  [self appendTimeInfoFromApt:_apt
-        usingReferenceDate:_refDate
-        toBuffer:aptDescr];  
-  if ((s = [self titleForApt:_apt :_refDate]) != nil)
-    [aptDescr appendFormat:@"\n%@", s];
-  if ((s = [_apt valueForKey:@"location"]) != nil)
+  aptDescr = [NSMutableString stringWithCapacity: 60];
+  [aptDescr appendString: @"Date: "];
+  [self appendTimeInfoFromApt: _apt
+        usingReferenceDate: _refDate
+        toBuffer: aptDescr];
+  s = [self titleForApt: _apt : _refDate];
+  if ([s length] > 0)
+    [aptDescr appendFormat: @"\nTitle: %@", s];
+  s = [_apt valueForKey: @"location"];
+  if ([s length] > 0)
+    [aptDescr appendFormat: @"\nLocation: %@", s];
+  s = [_apt valueForKey: @"description"];
+  if ([s length] > 0)
     [aptDescr appendFormat:@"\n%@", s];
-    
+
   return aptDescr;
 }
 
-- (NSString *)tooltipForPrivateApt:(id)_apt :(NSCalendarDate *)_refDate {
+- (NSString *) tooltipForPrivateApt: (id) _apt
+                                   : (NSCalendarDate *) _refDate
+{
   NSMutableString *aptDescr;
-  NSString        *s;
+  NSString *s;
   
-  aptDescr = [NSMutableString stringWithCapacity:25];
-  [self appendTimeInfoFromApt:_apt
-        usingReferenceDate:_refDate
-        toBuffer:aptDescr];  
+  aptDescr = [NSMutableString stringWithCapacity: 25];
+  [self appendTimeInfoFromApt: _apt
+        usingReferenceDate: _refDate
+        toBuffer: aptDescr];  
   if ((s = [self privateTitle]) != nil)
     [aptDescr appendFormat:@"\n%@", s];
 
   return aptDescr;
 }
 
-- (NSString *)suppressApt:(id)_apt :(NSCalendarDate *)_refDate {
+- (NSString *) suppressApt: (id) _apt
+                          : (NSCalendarDate *) _refDate
+{
   return @"";
 }
 
index 15836d69e0660219a9f74edcdadbf8ee0353e0b9..4d460294d04013d6e1e088504f549a47eb1bb584 100644 (file)
@@ -24,7 +24,7 @@
 
 #import <Foundation/NSFormatter.h>
 
-@class NSString, NSDictionary;
+@class NSString, NSCalendarDate, NSDictionary;
 
 @interface SOGoDateFormatter : NSFormatter
 {
 
 - (NSString *)stringForObjectValue:(id)_obj;
 
+- (NSString *)shortDayOfWeek:(int)_day;
+- (NSString *)fullDayOfWeek:(int)_day;
+- (NSString *)shortMonthOfYear:(int)_month;
+- (NSString *)fullMonthOfYear:(int)_month;
+
+- (NSString *)isoDateFormatForDate:(NSCalendarDate *)_date;
+- (NSString *)fullWeekdayNameAndDetailsForDate:(NSCalendarDate *)_date;
+
 @end
 
 #endif /* __SOGoDateFormatter_H_ */
index 331243426956350cd3ed5de4155cf24e2df02abb..c64aca8209bd8d7be5a74f3b6fad20e2fa995b5e 100644 (file)
 #include "SOGoDateFormatter.h"
 #include "common.h"
 
-@interface SOGoDateFormatter (PrivateAPI)
-- (NSString *)shortDayOfWeek:(int)_day;
-- (NSString *)fullDayOfWeek:(int)_day;
-- (NSString *)shortMonthOfYear:(int)_month;
-- (NSString *)fullMonthOfYear:(int)_month;
-
-- (NSString *)isoDateFormatForDate:(NSCalendarDate *)_date;
-- (NSString *)fullWeekdayNameAndDetailsForDate:(NSCalendarDate *)_date;
-@end
-
 @implementation SOGoDateFormatter
 
 - (id)initWithLocale:(NSDictionary *)_locale {
index 683c5486d1b8da3f96a833822ad89d9f84b4cd0e..ff59968427a7e5f3da0bc478c85f6a6766196244 100644 (file)
 #ifndef        __UIxComponent_H_
 #define        __UIxComponent_H_
 
-#include <NGObjWeb/SoComponent.h>
+#import <NGObjWeb/SoComponent.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+
+#import <SOGo/SOGoObject.h>
 
 /*
   UIxComponent
@@ -37,6 +40,7 @@
 @interface UIxComponent : SoComponent
 {
   NSMutableDictionary *queryParameters;
+  NSCalendarDate *_selectedDate;
 }
 
 - (NSString *)queryParameterForKey:(NSString *)_key;
 - (NSString *)ownMethodName;
 
 - (NSString *)userFolderPath;
+- (NSString *) applicationPath;
+
 - (NSString *)ownPath;
 - (NSString *)relativePathToUserFolderSubPath:(NSString *)_sub;
 
 /* date selection */
-- (NSTimeZone *)viewTimeZone;
-- (NSTimeZone *)backendTimeZone;
-- (NSCalendarDate *)selectedDate;
+- (NSCalendarDate *) selectedDate;
+
 - (NSString *)dateStringForDate:(NSCalendarDate *)_date;
-- (NSCalendarDate *)dateForDateString:(NSString *)_dateString;
+
+- (BOOL) hideFrame;
+
+- (UIxComponent *) jsCloseWithRefreshMethod: (NSString *) methodName;
 
 /* SoUser */
 - (SoUser *)user;
 /* locale */
 - (NSDictionary *)locale;
 
+/* cached resource filenames */
+- (WOResourceManager *) pageResourceManager;
+- (NSString *) urlForResourceFilename: (NSString *) filename;
+
 /* Debugging */
 - (BOOL)isUIxDebugEnabled;
 
index 1e4f65f69a8b02e99a425af96ae1173f8bade4a2..5a353f21360b53e9288ce68e8e9b5da8b890dcdd 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxComponent.h"
-#include "SOGoJSStringFormatter.h"
-#include "common.h"
-#include <NGObjWeb/SoHTTPAuthenticator.h>
+#import "SOGoJSStringFormatter.h"
+#import "common.h"
+
+#import <NGObjWeb/SoHTTPAuthenticator.h>
+#import <NGObjWeb/WOResourceManager.h>
+
+#import <SOGo/NSString+URL.h>
+
+#import <SOGo/SOGoUser.h>
+#import <SOGo/SOGoObject.h>
+#import <SOGo/SOGoCustomGroupFolder.h>
+#import <SOGo/NSCalendarDate+SOGo.h>
+
+#import "../Common/UIxJSClose.h"
+
+#import "UIxComponent.h"
 
 @interface UIxComponent (PrivateAPI)
 - (void)_parseQueryString:(NSString *)_s;
@@ -31,9 +43,6 @@
 
 @implementation UIxComponent
 
-static NSTimeZone *MET = nil;
-static NSTimeZone *GMT = nil;
-
 static NSMutableArray *dayLabelKeys       = nil;
 static NSMutableArray *abbrDayLabelKeys   = nil;
 static NSMutableArray *monthLabelKeys     = nil;
@@ -54,10 +63,6 @@ static BOOL uixDebugEnabled = NO;
   
   uixDebugEnabled = [ud boolForKey:@"SOGoUIxDebugEnabled"];
 
-  if (MET == nil) {
-    MET = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
-    GMT = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
-  }
   if (dayLabelKeys == nil) {
     dayLabelKeys = [[NSMutableArray alloc] initWithCapacity:7];
     [dayLabelKeys addObject:@"Sunday"];
@@ -107,73 +112,97 @@ static BOOL uixDebugEnabled = NO;
   }
 }
 
-- (void)dealloc {
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      _selectedDate = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
   [self->queryParameters release];
+  if (_selectedDate)
+    [_selectedDate release];
   [super dealloc];
 }
 
 /* query parameters */
 
-- (void)_parseQueryString:(NSString *)_s {
+- (void) _parseQueryString: (NSString *) _s
+{
   NSEnumerator *e;
   NSString *part;
-    
+  NSRange  r;
+  NSString *key, *value;
+
   e = [[_s componentsSeparatedByString:@"&"] objectEnumerator];
-  while ((part = [e nextObject]) != nil) {
-    NSRange  r;
-    NSString *key, *value;
-        
-    r = [part rangeOfString:@"="];
-    if (r.length == 0) {
+  part = [e nextObject];
+  while (part)
+    {
+      r = [part rangeOfString:@"="];
+      if (r.length == 0)
+        {
       /* missing value of query parameter */
-      key   = [part stringByUnescapingURL];
-      value = @"1";
-    }
-    else {
-      key   = [[part substringToIndex:r.location] stringByUnescapingURL];
-      value = [[part substringFromIndex:(r.location + r.length)] 
-                stringByUnescapingURL];
+          key   = [part stringByUnescapingURL];
+          value = @"1";
+        }
+      else
+        {
+          key   = [[part substringToIndex:r.location] stringByUnescapingURL];
+          value = [[part substringFromIndex:(r.location + r.length)] 
+                    stringByUnescapingURL];
+        }
+      [self->queryParameters setObject:value forKey:key];
+      part = [e nextObject];
     }
-    [self->queryParameters setObject:value forKey:key];
-  }
 }
-- (void)addKeepAliveFormValuesToQueryParameters {
+
+- (void) addKeepAliveFormValuesToQueryParameters
+{
 }
 
-- (NSString *)queryParameterForKey:(NSString *)_key {
+- (NSString *) queryParameterForKey: (NSString *) _key
+{
   return [[self _queryParameters] objectForKey:_key];
 }
 
-- (void)setQueryParameter:(NSString *)_param forKey:(NSString *)_key {
-  if(_key == nil)
-    return;
-
-  if(_param != nil)
-    [[self _queryParameters] setObject:_param forKey:_key];
-  else
-    [[self _queryParameters] removeObjectForKey:_key];
+- (void) setQueryParameter: (NSString *) _param
+                    forKey: (NSString *) _key
+{
+  if (_key)
+    {
+      if (_param)
+        [[self _queryParameters] setObject: _param forKey: _key];
+      else
+        [[self _queryParameters] removeObjectForKey: _key];
+    }
 }
 
-- (NSMutableDictionary *)_queryParameters {
+- (NSMutableDictionary *) _queryParameters
+{
   // TODO: this code is weird, should use WORequest methods for parsing
   WORequest *req;
   NSString  *uri;
   NSRange   r;
+  NSString *qs;
   
   if (self->queryParameters)
     return self->queryParameters;
 
   self->queryParameters = [[NSMutableDictionary alloc] initWithCapacity:8];
-    
+
   req = [[self context] request];
   uri = [req uri];
   r   = [uri rangeOfString:@"?" options:NSBackwardsSearch];
-  if (r.length > 0) {
-    NSString *qs;
-    
-    qs = [uri substringFromIndex:NSMaxRange(r)];
-    [self _parseQueryString:qs];
-  }
+  if (r.length > 0)
+    {
+      qs = [uri substringFromIndex:NSMaxRange(r)];
+      [self _parseQueryString:qs];
+    }
   
   /* add form values */
   [self addKeepAliveFormValuesToQueryParameters];
@@ -181,11 +210,13 @@ static BOOL uixDebugEnabled = NO;
   return self->queryParameters;
 }
 
-- (NSDictionary *)queryParameters {
+- (NSDictionary *) queryParameters
+{
   return [self _queryParameters];
 }
 
-- (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date{
+- (NSDictionary *) queryParametersBySettingSelectedDate: (NSCalendarDate *) _date
+{
   NSMutableDictionary *qp;
     
   qp = [[self queryParameters] mutableCopy];
@@ -193,33 +224,39 @@ static BOOL uixDebugEnabled = NO;
   return [qp autorelease];
 }
 
-- (void)setSelectedDateQueryParameter:(NSCalendarDate *)_newDate
-  inDictionary:(NSMutableDictionary *)_qp;
+- (void) setSelectedDateQueryParameter: (NSCalendarDate *) _newDate
+                          inDictionary: (NSMutableDictionary *) _qp
 {
-  if(_newDate != nil)
-    [_qp setObject:[self dateStringForDate:_newDate] forKey:@"day"];
+  if (_newDate)
+    [_qp setObject: [self dateStringForDate: _newDate] forKey: @"day"];
   else
     [_qp removeObjectForKey:@"day"];
 }
 
-- (NSString *)completeHrefForMethod:(NSString *)_method {
-  WOContext    *ctx;
+- (NSString *) completeHrefForMethod: (NSString *) _method
+{
+  WOContext *ctx;
   NSDictionary *qp;
-  NSString     *qs, *qps;
+  NSString *qs, *qps, *href;
 
   qp = [self queryParameters];
-  if([qp count] == 0)
-    return _method;
+  if ([qp count] > 0)
+    {
+      ctx = [self context];
+      qps = [ctx queryPathSeparator];
+      [ctx setQueryPathSeparator: @"&"];
+      qs = [ctx queryStringFromDictionary: qp];
+      [ctx setQueryPathSeparator: qps];
+      href = [_method stringByAppendingFormat:@"?%@", qs];
+    }
+  else
+    href = _method;
 
-  ctx = [self context];
-  qps = [ctx queryPathSeparator];
-  [ctx setQueryPathSeparator:@"&"];
-  qs = [ctx queryStringFromDictionary:qp];
-  [ctx setQueryPathSeparator:qps];
-  return [_method stringByAppendingFormat:@"?%@", qs];
+  return href;
 }
 
-- (NSString *)ownMethodName {
+- (NSString *) ownMethodName
+{
   NSString *uri;
   NSRange  r;
     
@@ -233,33 +270,86 @@ static BOOL uixDebugEnabled = NO;
     
   /* next: strip trailing slash */
     
-  if ([uri hasSuffix:@"/"]) uri = [uri substringToIndex:([uri length] - 1)];
-  r = [uri rangeOfString:@"/" options:NSBackwardsSearch];
+  if ([uri hasSuffix: @"/"])
+    uri = [uri substringToIndex: ([uri length] - 1)];
+  r = [uri rangeOfString:@"/" options: NSBackwardsSearch];
     
   /* then: cut of last path component */
     
   if (r.length == 0) // no slash? are we at root?
     return @"/";
     
-  return [uri substringFromIndex:(r.location + 1)];
+  return [uri substringFromIndex: (r.location + 1)];
 }
 
-- (NSString *)userFolderPath {
+- (NSString *) userFolderPath
+{
   WOContext *ctx;
-  NSArray   *traversalObjects;
-  NSString  *url;
-  NSString  *path;
+  NSString  *url, *path;
+  NSEnumerator *objects;
+  SOGoObject *currentObject;
+  BOOL found;
 
   ctx = [self context];
-  traversalObjects = [ctx objectTraversalStack];
-  url = [[traversalObjects objectAtIndex:0]
-                           baseURLInContext:ctx];
+  objects = [[ctx objectTraversalStack] objectEnumerator];
+  currentObject = [objects nextObject];
+  found = NO;
+  while (currentObject
+         && !found)
+    if ([currentObject isKindOfClass: [SOGoUserFolder class]])
+      found = YES;
+    else
+      currentObject = [objects nextObject];
+
+  url = [currentObject baseURLInContext:ctx];
   path = [[NSURL URLWithString:url] path];
-  path = [path stringByAppendingPathComponent:[[ctx activeUser] login]];
+
   return path;
 }
 
-- (NSString *)ownPath {
+- (NSString *) applicationPath
+{
+  SOGoObject *currentClient, *parent;
+  NSString *url;
+  BOOL found;
+  Class objectClass, groupFolderClass, userFolderClass;
+  WOContext *ctx;
+
+  groupFolderClass = [SOGoCustomGroupFolder class];
+  userFolderClass = [SOGoUserFolder class];
+
+  currentClient = [self clientObject];
+  objectClass = [currentClient class];
+  found = (objectClass == groupFolderClass || objectClass == userFolderClass);
+  while (!found && currentClient)
+    {
+      parent = [currentClient container];
+      objectClass = [parent class];
+      if (objectClass == groupFolderClass
+          || objectClass == userFolderClass)
+        found = YES;
+      else
+        currentClient = parent;
+    }
+
+  ctx = [self context];
+  url = [currentClient baseURLInContext: ctx];
+
+  return [[NSURL URLWithString: url] path];
+}
+
+- (NSString *) resourcesPath
+{
+  WOResourceManager *rm;
+
+  if ((rm = [self resourceManager]) == nil)
+    rm = [[WOApplication application] resourceManager];
+
+  return [rm webServerResourcesPath];
+}
+
+- (NSString *) ownPath
+{
   NSString *uri;
   NSRange  r;
   
@@ -270,72 +360,71 @@ static BOOL uixDebugEnabled = NO;
   r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
   if (r.length > 0)
     uri = [uri substringToIndex:r.location];
+
   return uri;
 }
 
-- (NSString *)relativePathToUserFolderSubPath:(NSString *)_sub {
+- (NSString *) relativePathToUserFolderSubPath: (NSString *) _sub
+{
   NSString *dst, *rel;
 
   dst = [[self userFolderPath] stringByAppendingPathComponent:_sub];
   rel = [dst urlPathRelativeToPath:[self ownPath]];
+
   return rel;
 }
-  
-/* date */
 
-- (NSTimeZone *)viewTimeZone {
-  // Note: also in the folder, should be based on a cookie?
-  return MET;
-}
+- (NSCalendarDate *) selectedDate
+{
+  if (!_selectedDate)
+    {
+      _selectedDate
+        = [NSCalendarDate
+            dateFromShortDateString: [self queryParameterForKey: @"day"]
+            andShortTimeString: [self queryParameterForKey: @"hm"]
+            inTimeZone: [[self clientObject] userTimeZone]];
+      [_selectedDate retain];
+    }
 
-- (NSTimeZone *)backendTimeZone {
-  return GMT;
+  return _selectedDate;
 }
 
-- (NSCalendarDate *)selectedDate {
-  NSString       *s;
-  NSCalendarDate *cdate;
-
-  s = [self queryParameterForKey:@"day"];
-  cdate = ([s length] > 0)
-    ? [self dateForDateString:s]
-    : [NSCalendarDate date];
-  [cdate setTimeZone:[self viewTimeZone]];
-  s = [self queryParameterForKey:@"hm"];
-  if([s length] == 4) {
-    unsigned hour, minute;
-      
-    hour = [[s substringToIndex:2] unsignedIntValue];
-    minute = [[s substringFromIndex:2] unsignedIntValue];
-    cdate = [cdate hour:hour minute:minute];
-  }
-  else {
-    cdate = [cdate hour:12 minute:0];
-  }
-  return cdate;
-}
+- (NSString *) dateStringForDate: (NSCalendarDate *) _date
+{
+  [_date setTimeZone: [[self clientObject] userTimeZone]];
 
-- (NSString *)dateStringForDate:(NSCalendarDate *)_date {
-  [_date setTimeZone:[self viewTimeZone]];
   return [_date descriptionWithCalendarFormat:@"%Y%m%d"];
 }
 
-- (NSCalendarDate *)dateForDateString:(NSString *)_dateString {
-  return [NSCalendarDate dateWithString:_dateString 
-                        calendarFormat:@"%Y%m%d"];
+- (BOOL) hideFrame
+{
+  return ([[self queryParameterForKey: @"noframe"] boolValue]);
 }
 
+- (UIxComponent *) jsCloseWithRefreshMethod: (NSString *) methodName
+{
+  UIxJSClose *jsClose;
+
+  jsClose = [UIxJSClose new];
+  [jsClose autorelease];
+  [jsClose setRefreshMethod: methodName];
+
+  return jsClose;
+}
 
 /* SoUser */
 
-- (SoUser *)user {
+- (SoUser *) user
+{
   WOContext *ctx;
   
   ctx = [self context];
-  return [[[self clientObject] authenticatorInContext:ctx] userInContext:ctx];
+
+  return [[[self clientObject] authenticatorInContext: ctx] userInContext: ctx];
 }
 
-- (NSString *)shortUserNameForDisplay {
+- (NSString *) shortUserNameForDisplay
+{
   // TODO: better use a SoUser formatter?
   // TODO: who calls that?
   NSString *s;
@@ -358,11 +447,11 @@ static BOOL uixDebugEnabled = NO;
 
 /* labels */
 
-- (NSString *)labelForKey:(NSString *)_str {
+- (NSString *) labelForKey: (NSString *) _str
+{
   WOResourceManager *rm;
-  NSArray           *languages;
-  NSString          *label;
-  NSString          *lKey, *lTable, *lVal;
+  NSArray *languages;
+  NSString *lKey, *lTable, *lVal;
   NSRange r;
 
   if ([_str length] == 0)
@@ -374,7 +463,7 @@ static BOOL uixDebugEnabled = NO;
     
   /* find resource manager */
     
-  if ((rm = [self resourceManager]) == nil)
+  if ((rm = [self pageResourceManager]) == nil)
     rm = [[WOApplication application] resourceManager];
   if (rm == nil)
     [self warnWithFormat:@"missing resource manager!"];
@@ -405,13 +494,13 @@ static BOOL uixDebugEnabled = NO;
 #endif
   
   /* lookup string */
-  
-  label = [rm stringForKey:lKey inTableNamed:lTable withDefaultValue:lVal
-             languages:languages];
-  return label;
+  return [rm stringForKey: lKey
+             inTableNamed: lTable
+             withDefaultValue: lVal
+             languages: languages];
 }
 
-- (NSString *)localizedNameForDayOfWeek:(unsigned)_dayOfWeek {
+- (NSString *) localizedNameForDayOfWeek:(unsigned)_dayOfWeek {
   NSString *key =  [dayLabelKeys objectAtIndex:_dayOfWeek % 7];
   return [self labelForKey:key];
 }
@@ -450,6 +539,55 @@ static BOOL uixDebugEnabled = NO;
   return [[self context] valueForKey:@"locale"];
 }
 
+- (WOResourceManager *) pageResourceManager
+{
+  WOResourceManager *rm;
+  
+  if ((rm = [[[self context] page] resourceManager]) == nil)
+    rm = [[WOApplication application] resourceManager];
+
+  return rm;
+}
+
+- (NSString *) urlForResourceFilename: (NSString *) filename
+{
+  static NSMutableDictionary *pageToURL = nil;
+  NSString *url;
+  WOComponent *page;
+  WOResourceManager *rm;
+  NSBundle *pageBundle;
+
+  if (filename)
+    {
+      if (!pageToURL)
+        pageToURL = [[NSMutableDictionary alloc] initWithCapacity: 32];
+
+      url = [pageToURL objectForKey: filename];
+      if (!url)
+        {
+          rm = [self pageResourceManager];
+          page = [[self context] page];
+          pageBundle = [NSBundle bundleForClass: [page class]];
+          url = [rm urlForResourceNamed: filename
+                    inFramework: [pageBundle bundlePath]
+                    languages: nil
+                    request: [[self context] request]];
+          if (!url)
+            url = @"";
+          else
+            if ([url hasPrefix: @"http"])
+              url = [url hostlessURL];
+          [pageToURL setObject: url forKey: filename];
+        }
+
+//   NSLog (@"url for '%@': '%@'", filename, url);
+    }
+  else
+    url = @"";
+
+  return url;
+}
+
 /* debugging */
 
 - (BOOL)isUIxDebugEnabled {
index cf3ff155235e2c2c95dd44d9bc39b6840b585885..73a973c3f5f4819c269405b55c53585ee359c75c 100644 (file)
 
 /* Menu */
 
+"Calendars"            = "Agendas";
 "Calendar"             = "Calendar";
 "Contacts"             = "Contacts";
 
+"New Calendar..." = "New Calendar...";
+"Delete Calendar" = "Delete Calendar";
+"Access Rights..." = "Access Rights...";
+"Export Calendar..." = "Export Calendar...";
+"Publish Calendar..." = "Publish Calendar...";
+"Reload Remote Calendars" = "Reload Remote Calendars";
+"Properties" = "Properties";
 
 /* Misc */
 
 "action"               = "Action";
 "accept"               = "Accept";
 "decline"              = "Decline";
-"more participants"     = "more participants";
+"more attendees"     = "more attendees";
 "Hide already accepted and rejected appointments" = "Hide already accepted and rejected appointments";
 "Show already accepted and rejected appointments" = "Show already accepted and rejected appointments";
 
 "Appointment editor"   = "Appointment Editor";
 "Appointment proposal" = "Appointment Proposal";
 "Appointment on"       = "Appointment on";
-"Start time"           = "Start time";
-"End time"             = "End time";
+"From"                 = "From";
+"To"                   = "To";
+"Due time"             = "Due time";
 "Start date"           = "Start date";
 "End date"             = "End date";
+"Due date"             = "Due date";
 "Earliest start time"  = "Earliest start time";
 "Latest end time"      = "Latest end time";
 "browse start date"    = "browse start date";
 "Status"               = "Status";
 "Location"             = "Location";
 "Priority"             = "Priority";
+"Privacy"              = "Privacy";
 "Cycle"                        = "Cycle";
 "Cycle End"            = "End";
 "Categories"           = "Categories";
 "Classification"       = "Classification";
 "Duration"             = "Duration";
-"Participants"         = "Participants";
+"Attendees"            = "Attendees";
 "Resources"            = "Resources";
 "Organizer"            = "Organizer";
-"Comment"              = "Comment";
+"Description"          = "Description";
+"Start"                 = "Start";
+"End"                   = "End";
+"Category"              = "Category";
 
 "attributes"           = "Attributes";
-"participants"         = "Participants";
+"attendees"            = "Attendees";
 /* checkbox title */
 "is private"            = "is private";
 /* classification */
 "empty title"          = "Empty title";
 "private appointment"  = "Private appointment";
 
+"Show Details" = "Show Details";
+"Hide Details" = "Hide Details";
+
 /* Appointments (participation state) */
 
 "partStat_NEEDS-ACTION"        = "Not decided, yet";
 
 /* Searching */
 
+"view_all" = "All Events";
+"view_today" = "Today's Events";
+"view_next7" = "Events in the Next 7 Days";
+"view_next14" = "Events in the Next 14 Days";
+"view_next31" = "Events in the Next 31 Days";
+"view_thismonth" = "Events in this Calendar Month";
+"view_future" = "All Future Events";
+"view_selectedday" = "Currently Selected Day";
+
+"View:" = "View:";
+"Title or Description" = "Title or Description";
+
 "Search"               = "Search";
-"Search participants"  = "Search participants";
+"Search attendees"     = "Search attendees";
 "Search resources"     = "Search resources";
 "Search appointments"  = "Search appointments";
 "Search in Anais"      = "Search in Anaïs";
 
+"All Day" = "All Day";
 "check for conflicts" = "check for conflicts";
 
+"Browse URL" = "Browse URL";
+
 /* calendar modes */
 
 "Overview"             = "Overview";
 
 /* Priorities */
 
-"prio_0"               = "Undefined";
+"prio_0"               = "Not specified";
 "prio_1"               = "High";
 "prio_2"               = "High";
 "prio_3"               = "High";
 "prio_8"               = "Low";
 "prio_9"               = "Low";
 
+/* access classes (privacy) */
+"privacy_PUBLIC" = "Public";
+"privacy_CONFIDENTIAL" = "Time and Date Only";
+"privacy_PRIVATE" = "Private";
+
+/* status type */
+"status_" = "Not specified";
+"status_TENTATIVE" = "Tentative";
+"status_CONFIRMED" = "Confirmed";
+"status_CANCELLED" = "Cancelled";
+
 /* Cycles */
 
 "cycle_once"           = "once";
@@ -219,3 +262,42 @@ validate_invalid_startdate = "Incorrect startdate field!";
 validate_invalid_enddate   = "Incorrect enddate field!";
 validate_endbeforestart    = "Enddate is before startdate!";
 
+"Tasks" = "Tasks";
+"Hide completed tasks" = "Hide completed tasks";
+
+/* toolbar */
+"New Event" = "New Event";
+"New Task" = "New Task";
+"Edit" = "Edit";
+"Delete" = "Delete";
+"Go to Today" = "Go to Today";
+"Day View" = "Day View";
+"Week View" = "Week View";
+"Month View" = "Month View";
+
+"eventPartStatModificationError" = "Your participation status at the event could not be modified.";
+
+/* confirmations */
+"appointmentDeleteConfirmation" = "Erasing this event will not be reversible.\\nDo you want to confirm anyway?";
+"taskDeleteConfirmation" = "Erasing this task will be nonreversible.\\nDo you want to confirm anyway?";
+
+/* Legend */
+"Required participant" = "Required participant";
+"Optional participant" = "Optional participant";
+"Chair" = "Chair";
+
+"Needs action" = "Needs action";
+"Accepted" = "Accepted";
+"Declined" = "Declined";
+"Tentative" = "Tentative";
+
+"Free" = "Free";
+"Busy" = "Busy";
+"Maybe busy" = "Maybe busy";
+"No free-busy information" = "No free-busy information";
+
+/* FreeBusy panel buttons */
+"Previous slot" = "Previous slot";
+"Next slot" = "Next slot";
+"Previous hour" = "Previous hour";
+"Next hour" = "Next hour";
diff --git a/UI/Scheduler/English.lproj/skycalendar.html b/UI/Scheduler/English.lproj/skycalendar.html
deleted file mode 100644 (file)
index f6767f4..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-<!--
-Title: Tigra Calendar
-Description: See the demo at url
-URL: http://www.softcomplex.com/products/tigra_calendar/
-Version: 3.1
-Date: 08-08-2002 (mm-dd-yyyy)
-Feedback: feedback@softcomplex.com (specify product title in the subject)
-Note: Permission given to use this script in ANY kind of applications if
-   header lines are left unchanged.
-Note: Script consists of two files: calendar?.js and calendar.html
-About us: Our company provides offshore IT consulting services.
-    Contact us at sales@softcomplex.com if you have any programming task you
-    want to be handled by professionals. Our typical hourly rate is $20.
-    
-modified by Martin Hoerning, mh@skyrix.com, 2002-12-05
--->
-<html>
-<head>
-<title>Select Date, Please.</title>
-<style>
-       td {font-family: Tahoma, Verdana, sans-serif; font-size: 12px;}
-</style>
-<script language="JavaScript">
-
-// months as they appear in the calendar's title
-var ARR_MONTHS = ["January", "February", "March", "April", "May", "June",
-               "July", "August", "September", "October", "November", "December"];
-// week day titles as they appear on the calendar
-var ARR_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
-// day week starts from (normally 0-Mo or 1-Su)
-var NUM_WEEKSTART = 1;
-// path to the directory where calendar images are stored. trailing slash req.
-var STR_ICONPATH = '';
-
-var re_url = new RegExp('datetime=(\\-?\\d+)');
-var dt_current = (re_url.exec(String(window.location))
-       ? new Date(new Number(RegExp.$1)) : new Date());
-var re_id = new RegExp('id=(\\d+)');
-var num_id = (re_id.exec(String(window.location))
-       ? new Number(RegExp.$1) : 0);
-var obj_caller = (window.opener ? window.opener.calendars[num_id] : null);
-
-if (obj_caller && obj_caller.year_scroll) {
-       // get same date in the previous year
-       var dt_prev_year = new Date(dt_current);
-       dt_prev_year.setFullYear(dt_prev_year.getFullYear() - 1);
-       if (dt_prev_year.getDate() != dt_current.getDate())
-               dt_prev_year.setDate(0);
-       
-       // get same date in the next year
-       var dt_next_year = new Date(dt_current);
-       dt_next_year.setFullYear(dt_next_year.getFullYear() + 1);
-       if (dt_next_year.getDate() != dt_current.getDate())
-               dt_next_year.setDate(0);
-}
-
-// get same date in the previous month
-var dt_prev_month = new Date(dt_current);
-dt_prev_month.setMonth(dt_prev_month.getMonth() - 1);
-if (dt_prev_month.getDate() != dt_current.getDate())
-       dt_prev_month.setDate(0);
-
-// get same date in the next month
-var dt_next_month = new Date(dt_current);
-dt_next_month.setMonth(dt_next_month.getMonth() + 1);
-if (dt_next_month.getDate() != dt_current.getDate())
-       dt_next_month.setDate(0);
-
-// get first day to display in the grid for current month
-var dt_firstday = new Date(dt_current);
-dt_firstday.setDate(1);
-dt_firstday.setDate(1 - (7 + dt_firstday.getDay() - NUM_WEEKSTART) % 7);
-
-// function passing selected date to calling window
-function set_datetime(n_datetime, b_close) {
-       if (!obj_caller) return;
-
-       var dt_datetime = new Date(n_datetime);
-
-       if (!dt_datetime) {
-          alert('failed to generate date string');
-          return;
-        }
-        if (b_close) { // only set value when closing window
-          obj_caller.target.value = (document.cal
-            ? obj_caller.gen_tsmp(dt_datetime)
-            : obj_caller.gen_date(dt_datetime)
-          );
-        }
-       if (b_close) window.close();
-       else obj_caller.popup(dt_datetime.valueOf());
-}
-
-</script>
-</head>
-<body bgcolor="#FFFFFF" marginheight="5" marginwidth="5" topmargin="5" leftmargin="5" rightmargin="5">
-<table class="clsOTable" cellspacing="0" border="0" width="100%">
-<tr><td bgcolor="#E8E8E0">
-<table cellspacing="1" cellpadding="3" border="0" width="100%">
-<tr><td colspan="7" bgcolor="#D0D0D0"><table cellspacing="0" cellpadding="0" border="0" width="100%">
-<tr>
-<script language="JavaScript">
-document.write(
-'<td>'+(obj_caller&&obj_caller.year_scroll?'<a href="javascript:set_datetime('+dt_prev_year.valueOf()+')"><img src="'+STR_ICONPATH+'first.gif" width="15" height="15" border="0" alt="previous year" title="previous year"></a>&nbsp;':'')+'<a href="javascript:set_datetime('+dt_prev_month.valueOf()+')"><img src="'+STR_ICONPATH+'previous.gif" width="15" height="15" border="0" alt="previous month" title="previous month"></a></td>'+
-'<td align="center" width="100%"><font color="#000000">'+ARR_MONTHS[dt_current.getMonth()]+' '+dt_current.getFullYear() + '</font></td>'+
-'<td><a href="javascript:set_datetime('+dt_next_month.valueOf()+')"><img src="'+STR_ICONPATH+'next.gif" width="15" height="15" border="0" alt="next month" title="next month"></a>'+(obj_caller && obj_caller.year_scroll?'&nbsp;<a href="javascript:set_datetime('+dt_next_year.valueOf()+')"><img src="'+STR_ICONPATH+'last.gif" width="15" height="15" border="0" alt="next year" title="next year"></a>':'')+'</td>'
-);
-</script>
-</tr>
-</table></td></tr>
-<tr>
-<script language="JavaScript">
-
-// print weekdays titles
-for (var n=0; n<7; n++)
-       document.write('<td bgcolor="#D0D0D0" align="center"><font color="#000000">'+ARR_WEEKDAYS[(NUM_WEEKSTART+n)%7]+'</font></td>');
-document.write('</tr>');
-
-// print calendar table
-var dt_current_day = new Date(dt_firstday);
-while (dt_current_day.getMonth() == dt_current.getMonth() ||
-       dt_current_day.getMonth() == dt_firstday.getMonth()) {
-       // print row heder
-       document.write('<tr>');
-       for (var n_current_wday=0; n_current_wday<7; n_current_wday++) {
-               if (dt_current_day.getDate() == dt_current.getDate() &&
-                       dt_current_day.getMonth() == dt_current.getMonth())
-                       // print current date
-                       document.write('<td bgcolor="#F18D39" align="center" width="14%">');
-               //else if (dt_current_day.getDay() == 0 || dt_current_day.getDay() == 6)
-               else if (dt_current_day.getMonth() != dt_current.getMonth())
-                       // old: weekend days // new: other month
-                       document.write('<td bgcolor="#D0D0D0" align="center" width="14%">');
-               else
-                       // print working days of current month
-                       document.write('<td bgcolor="#E0E0E0" align="center" width="14%">');
-
-               document.write('<a href="javascript:set_datetime('+dt_current_day.valueOf() +', true);">');
-
-               if (dt_current_day.getMonth() == this.dt_current.getMonth())
-                       // print days of current month
-                       document.write('<font color="#000000">');
-               else 
-                       // print days of other months
-                       document.write('<font color="#555555">');
-                       
-               document.write(dt_current_day.getDate()+'</font></a></td>');
-               dt_current_day.setDate(dt_current_day.getDate()+1);
-       }
-       // print row footer
-       document.write('</tr>');
-}
-//if (obj_caller && obj_caller.time_comp)
-//     document.write('<form onsubmit="javascript:set_datetime('+dt_current.valueOf()+', true)" name="cal"><tr><td colspan="7" bgcolor="#87CEFA"><font color="White" face="tahoma, verdana" size="2">Time: <input type="text" name="time" value="'+obj_caller.gen_time(this.dt_current)+'" size="8" maxlength="8"></font></td></tr></form>');
-</script>
-</table></tr></td>
-</table>
-</body>
-</html>
-
index f66401805464dd26f5aea21a9eeff86c50312cb9..a3da6c649ab42bd2f6f85b0cc1cc9bb5bb6d1f85 100644 (file)
@@ -27,6 +27,7 @@
 "Week"          = "Semaine";
 "this week"     = "cette semaine";
 
+"Week %d" = "Semaine nº %d";
 
 /* Month */
 
 
 /* Menu */
 
+"Calendars"            = "Agendas";
 "Calendar"             = "Agenda";
 "Contacts"             = "Contacts";
 
+"New Calendar..." = "Nouvel agenda...";
+"Delete Calendar" = "Effacer l'agenda";
+"Access Rights..." = "Partage";
+"Export Calendar..." = "Exporter l'agenda...";
+"Publish Calendar..." = "Publier l'agenda...";
+"Reload Remote Calendars" = "Recharger les agendas distants";
+"Properties" = "Propriétés";
 
 /* Misc */
 
 
 "new"           = "Nouveau";
 "printview"     = "Version imprimable";
-"edit"                 = "Editer";
+"edit"                 = "Éditer";
 "delete"               = "Supprimer";
 "proposal"      = "Recherche de plages horaires";
-"Save"                 = "Sauvegarder";
+"Save"                 = "Enregistrer";
 "Cancel"               = "Annuler";
 "show_rejected_apts"    = "Afficher les rendez-vous refusés";
 "hide_rejected_apts"    = "Cacher les rendez-vous refusés";
 "action"               = "Action";
 "accept"               = "Accepter";
 "decline"              = "Refuser";
-"more participants"     = "Autres participants";
+"more attendees"     = "Autres participants";
 "Hide already accepted and rejected appointments"    = "Cacher les invitations refusées";
 "Show already accepted and rejected appointments"    = "Montrer aussi les invitations refusées";
 
 "Appointment editor"   = "Edition de rendez-vous";
 "Appointment proposal" = "Proposition de rendez-vous";
 "Appointment on"       = "Rendez-vous le";
-"Start time"           = "Heure de début";
-"End time"             ="Heure de fin";
+"From"                 = "Du";
+"To"                   = "Au";
+"Due Time"             = "Écheance";
 "Start date"           = "Date de début";
-"End date"             = "Date de fin";
+"End Date"             = "Date de fin";
+"Due Date"             = "Écheance";
 "Earliest start time"  = "Au plus tôt";
 "Latest end time"      = "Au plus tard";
 "browse start date"    = "Sélection Date de début";
 "Title"                        ="Titre";
 "Name"                 = "Nom";
 "Email"                        = "Email";
-"Status"               = "Status";
-"Location"             ="Lieu";
+"Status"               = "Statut";
+"Location"             = "Lieu";
 "Priority"             = "Priorité";
-"Cycle"                        = "Récurence";
+"Privacy"              = "Confidentialité";
+"Cycle"                        = "Récurrence";
 "Cycle End"            = "s'arreter";
 "Categories"           = "Categories";
 "Classification"       = "Classification";
 "Duration"             = "Durée";
-"Participants"         = "Participants";
+"Attendees"            = "Participants";
 "Resources"            = "Ressources";
 "Organizer"            = "Organisateur";
-"Comment"              ="Notes";
+"Description"          = "Description";
+"Start"                 = "Début";
+"End"                   = "Fin";
+"Category"              = "Catégorie";
 
 "attributes"           = "Attributs";
-"participants"         = "Participants";
+"attendees"            = "Participants";
 /* checkbox title */
 "is private"            = "Rendez-vous privé";
 /* classification */
 "empty title"          = "Titre vide";
 "private appointment"  = "Rendez-vous privé";
 
+"Show Details" = "Afficher les détails";
+"Hide Details" = "Cacher les détails";
+
 /* Appointments (participation state) */
 
 "partStat_NEEDS-ACTION"        = "Décision attendue";
 
 /* Searching */
 
+"view_all" = "Tous";
+"view_today" = "Aujourd'hui";
+"view_next7" = "Les 7 prochains jours";
+"view_next14" = "Les 14 prochains jours";
+"view_next31" = "Les 31 prochains jours";
+"view_thismonth" = "Ce mois-ci";
+"view_future" = "Tous Ã  venir";
+"view_selectedday" = "Le jour sélectionné";
+
+"View:" = "Voir :";
+"Title or Description" = "Le titre ou la description";
+
 "Search"               = "Rechercher";
-"Search participants"  ="Recherche de participants";
+"Search attendees"     ="Recherche de participants";
 "Search resources"     ="Recherche de ressources";
 "Search appointments"  = "Recherche de rendez-vous";
 "Search in Anais"      = "Recherche par Anaïs";
 
+"All Day" = "Toute la journée";
 "check for conflicts" = "Vérifier les conflits";
 
+"Browse URL" = "Visiter l'URL";
+
 /* calendar modes */
 
 "Overview"      = "Vue synthétique";
 
 /* Priorities */
 
-"prio_0"               = "Non précisée";
+"prio_0"               = "Non-spécifiée";
 "prio_1"               = "Haute";
 "prio_2"               = "Haute";
 "prio_3"               = "Haute";
 "prio_8"               = "Basse";
 "prio_9"               = "Basse";
 
+/* access classes (privacy) */
+"privacy_PUBLIC" = "Public";
+"privacy_CONFIDENTIAL" = "Date et heure seulement";
+"privacy_PRIVATE" = "Privé";
+
+/* status type */
+"status_" = "Non-spécifié";
+"status_TENTATIVE" = "Tentative";
+"status_CONFIRMED" = "Confirmé";
+"status_CANCELLED" = "Annulé";
+
 /* Cycles */
 
-"cycle_once"           = "Sans récurence";
+"cycle_once"           = "Sans récurrence";
 "cycle_daily"          = "Chaque jour";
 "cycle_weekly"         = "Chaque semaine";
 "cycle_2weeks"         = "Toutes les deux semaines";
 "cycle_4weeks"         = "Toutes les quatre semaines ";
 "cycle_monthly"                = "Tous les mois";
-"cycle_weekday"                = "A chaque même jour de la semaine";
+"cycle_weekday"                = "À chaque même jour de la semaine";
 "cycle_yearly"         = "Chaque année";
 
 "cycle_end_never"      = "Jamais";
-"cycle_end_until"      = "A la date :";
+"cycle_end_until"      = "À la date :";
 
 /* Appointment categories */
 
 "APPOINTMENT"          = "Rendez-vous";
-"NOT IN OFFICE"                = "A l'exterieur";
+"NOT IN OFFICE"                = "À l'extérieur";
 "MEETING"              = "Réunion";
 "HOLIDAY"              = "Vacances";
 "PHONE CALL"           = "Rendez-vous téléphonique";
@@ -220,3 +264,56 @@ validate_notitle           = "Le titre n'est pas rempli. Continuer quand-même ?
 validate_invalid_startdate = "La date de début est invalide !";
 validate_invalid_enddate   = "La date de fin est invalide !";
 validate_endbeforestart    = "La date de fin est avant la date de début !";
+
+"Tasks" = "Tâches";
+"Hide completed tasks" = "Masquer les tâches accomplies";
+
+/* tabs */
+"Task" = "Tâche";
+"Event" = "Événement";
+"Recurrence" = "Répétition";
+
+/* toolbar */
+"New Event" = "Nouvel Ã©vénement";
+"New Task" = "Nouvelle tâche";
+"Edit" = "Éditer";
+"Delete" = "Effacer";
+"Go to Today" = "Aujourd'hui";
+"Day View" = "Par jour";
+"Week View" = "Par semaine";
+"Month View" = "Par mois";
+
+"eventPartStatModificationError" = "Votre Ã©tat de participation Ã  l'événement n'a pas pu Ãªtre modifié.";
+
+/* menu */
+"New Event..." = "Nouvel Ã©vénement...";
+"New Task..." = "Nouvelle tâche...";
+"Edit Selected Event..." = "Modifier l'événement sélectionné...";
+"Delete Selected Event" = "Supprimer l'événement sélectionné";
+"Select All" = "Tout sélectionner";
+"Workweek days only" = "Semaine de travail seulement";
+"Tasks in View" = "Afficher les tâches";
+
+"appointmentDeleteConfirmation" = "L'effacement de cet Ã©vénement sera permanent.\\nVoulez-vous continuer?";
+"taskDeleteConfirmation" = "L'effacement de cette tâche sera permanent.\\nVoulez-vous continuer?";
+
+/* Legend */
+"Required participant" = "Participant obligatoire";
+"Optional participant" = "Participant facultatif";
+"Chair" = "Chaise";
+
+"Needs action" = "En attente";
+"Accepted" = "Accepté";
+"Declined" = "Décliné";
+"Tentative" = "Tentative";
+
+"Free" = "Libre";
+"Busy" = "Occupé";
+"Maybe busy" = "Peut-être occupé";
+"No free-busy information" = "Pas d'information";
+
+/* FreeBusy panel buttons */
+"Previous slot" = "Période précédente";
+"Next slot" = "Période suivante";
+"Previous hour" = "Heure précédente";
+"Next hour" = "Heure suivante";
diff --git a/UI/Scheduler/French.lproj/skycalendar.html b/UI/Scheduler/French.lproj/skycalendar.html
deleted file mode 100644 (file)
index f6767f4..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-<!--
-Title: Tigra Calendar
-Description: See the demo at url
-URL: http://www.softcomplex.com/products/tigra_calendar/
-Version: 3.1
-Date: 08-08-2002 (mm-dd-yyyy)
-Feedback: feedback@softcomplex.com (specify product title in the subject)
-Note: Permission given to use this script in ANY kind of applications if
-   header lines are left unchanged.
-Note: Script consists of two files: calendar?.js and calendar.html
-About us: Our company provides offshore IT consulting services.
-    Contact us at sales@softcomplex.com if you have any programming task you
-    want to be handled by professionals. Our typical hourly rate is $20.
-    
-modified by Martin Hoerning, mh@skyrix.com, 2002-12-05
--->
-<html>
-<head>
-<title>Select Date, Please.</title>
-<style>
-       td {font-family: Tahoma, Verdana, sans-serif; font-size: 12px;}
-</style>
-<script language="JavaScript">
-
-// months as they appear in the calendar's title
-var ARR_MONTHS = ["January", "February", "March", "April", "May", "June",
-               "July", "August", "September", "October", "November", "December"];
-// week day titles as they appear on the calendar
-var ARR_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
-// day week starts from (normally 0-Mo or 1-Su)
-var NUM_WEEKSTART = 1;
-// path to the directory where calendar images are stored. trailing slash req.
-var STR_ICONPATH = '';
-
-var re_url = new RegExp('datetime=(\\-?\\d+)');
-var dt_current = (re_url.exec(String(window.location))
-       ? new Date(new Number(RegExp.$1)) : new Date());
-var re_id = new RegExp('id=(\\d+)');
-var num_id = (re_id.exec(String(window.location))
-       ? new Number(RegExp.$1) : 0);
-var obj_caller = (window.opener ? window.opener.calendars[num_id] : null);
-
-if (obj_caller && obj_caller.year_scroll) {
-       // get same date in the previous year
-       var dt_prev_year = new Date(dt_current);
-       dt_prev_year.setFullYear(dt_prev_year.getFullYear() - 1);
-       if (dt_prev_year.getDate() != dt_current.getDate())
-               dt_prev_year.setDate(0);
-       
-       // get same date in the next year
-       var dt_next_year = new Date(dt_current);
-       dt_next_year.setFullYear(dt_next_year.getFullYear() + 1);
-       if (dt_next_year.getDate() != dt_current.getDate())
-               dt_next_year.setDate(0);
-}
-
-// get same date in the previous month
-var dt_prev_month = new Date(dt_current);
-dt_prev_month.setMonth(dt_prev_month.getMonth() - 1);
-if (dt_prev_month.getDate() != dt_current.getDate())
-       dt_prev_month.setDate(0);
-
-// get same date in the next month
-var dt_next_month = new Date(dt_current);
-dt_next_month.setMonth(dt_next_month.getMonth() + 1);
-if (dt_next_month.getDate() != dt_current.getDate())
-       dt_next_month.setDate(0);
-
-// get first day to display in the grid for current month
-var dt_firstday = new Date(dt_current);
-dt_firstday.setDate(1);
-dt_firstday.setDate(1 - (7 + dt_firstday.getDay() - NUM_WEEKSTART) % 7);
-
-// function passing selected date to calling window
-function set_datetime(n_datetime, b_close) {
-       if (!obj_caller) return;
-
-       var dt_datetime = new Date(n_datetime);
-
-       if (!dt_datetime) {
-          alert('failed to generate date string');
-          return;
-        }
-        if (b_close) { // only set value when closing window
-          obj_caller.target.value = (document.cal
-            ? obj_caller.gen_tsmp(dt_datetime)
-            : obj_caller.gen_date(dt_datetime)
-          );
-        }
-       if (b_close) window.close();
-       else obj_caller.popup(dt_datetime.valueOf());
-}
-
-</script>
-</head>
-<body bgcolor="#FFFFFF" marginheight="5" marginwidth="5" topmargin="5" leftmargin="5" rightmargin="5">
-<table class="clsOTable" cellspacing="0" border="0" width="100%">
-<tr><td bgcolor="#E8E8E0">
-<table cellspacing="1" cellpadding="3" border="0" width="100%">
-<tr><td colspan="7" bgcolor="#D0D0D0"><table cellspacing="0" cellpadding="0" border="0" width="100%">
-<tr>
-<script language="JavaScript">
-document.write(
-'<td>'+(obj_caller&&obj_caller.year_scroll?'<a href="javascript:set_datetime('+dt_prev_year.valueOf()+')"><img src="'+STR_ICONPATH+'first.gif" width="15" height="15" border="0" alt="previous year" title="previous year"></a>&nbsp;':'')+'<a href="javascript:set_datetime('+dt_prev_month.valueOf()+')"><img src="'+STR_ICONPATH+'previous.gif" width="15" height="15" border="0" alt="previous month" title="previous month"></a></td>'+
-'<td align="center" width="100%"><font color="#000000">'+ARR_MONTHS[dt_current.getMonth()]+' '+dt_current.getFullYear() + '</font></td>'+
-'<td><a href="javascript:set_datetime('+dt_next_month.valueOf()+')"><img src="'+STR_ICONPATH+'next.gif" width="15" height="15" border="0" alt="next month" title="next month"></a>'+(obj_caller && obj_caller.year_scroll?'&nbsp;<a href="javascript:set_datetime('+dt_next_year.valueOf()+')"><img src="'+STR_ICONPATH+'last.gif" width="15" height="15" border="0" alt="next year" title="next year"></a>':'')+'</td>'
-);
-</script>
-</tr>
-</table></td></tr>
-<tr>
-<script language="JavaScript">
-
-// print weekdays titles
-for (var n=0; n<7; n++)
-       document.write('<td bgcolor="#D0D0D0" align="center"><font color="#000000">'+ARR_WEEKDAYS[(NUM_WEEKSTART+n)%7]+'</font></td>');
-document.write('</tr>');
-
-// print calendar table
-var dt_current_day = new Date(dt_firstday);
-while (dt_current_day.getMonth() == dt_current.getMonth() ||
-       dt_current_day.getMonth() == dt_firstday.getMonth()) {
-       // print row heder
-       document.write('<tr>');
-       for (var n_current_wday=0; n_current_wday<7; n_current_wday++) {
-               if (dt_current_day.getDate() == dt_current.getDate() &&
-                       dt_current_day.getMonth() == dt_current.getMonth())
-                       // print current date
-                       document.write('<td bgcolor="#F18D39" align="center" width="14%">');
-               //else if (dt_current_day.getDay() == 0 || dt_current_day.getDay() == 6)
-               else if (dt_current_day.getMonth() != dt_current.getMonth())
-                       // old: weekend days // new: other month
-                       document.write('<td bgcolor="#D0D0D0" align="center" width="14%">');
-               else
-                       // print working days of current month
-                       document.write('<td bgcolor="#E0E0E0" align="center" width="14%">');
-
-               document.write('<a href="javascript:set_datetime('+dt_current_day.valueOf() +', true);">');
-
-               if (dt_current_day.getMonth() == this.dt_current.getMonth())
-                       // print days of current month
-                       document.write('<font color="#000000">');
-               else 
-                       // print days of other months
-                       document.write('<font color="#555555">');
-                       
-               document.write(dt_current_day.getDate()+'</font></a></td>');
-               dt_current_day.setDate(dt_current_day.getDate()+1);
-       }
-       // print row footer
-       document.write('</tr>');
-}
-//if (obj_caller && obj_caller.time_comp)
-//     document.write('<form onsubmit="javascript:set_datetime('+dt_current.valueOf()+', true)" name="cal"><tr><td colspan="7" bgcolor="#87CEFA"><font color="White" face="tahoma, verdana" size="2">Time: <input type="text" name="time" value="'+obj_caller.gen_time(this.dt_current)+'" size="8" maxlength="8"></font></td></tr></form>');
-</script>
-</table></tr></td>
-</table>
-</body>
-</html>
-
diff --git a/UI/Scheduler/French.lproj/skycalendar.js b/UI/Scheduler/French.lproj/skycalendar.js
deleted file mode 100644 (file)
index 897aa23..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-// Title: Tigra Calendar
-// Description: See the demo at url
-// URL: http://www.softcomplex.com/products/tigra_calendar/
-// Version: 3.1 (European date format)
-// Date: 08-08-2002 (mm-dd-yyyy)
-// Feedback: feedback@softcomplex.com (specify product title in the subject)
-// Note: Permission given to use this script in ANY kind of applications if
-//    header lines are left unchanged.
-// Note: Script consists of two files: calendar?.js and calendar.html
-// About us: Our company provides offshore IT consulting services.
-//    Contact us at sales@softcomplex.com if you have any programming task you
-//    want to be handled by professionals. Our typical hourly rate is $20.
-
-// modified by Martin Hoerning, mh@skyrix.com, 2002-12-05
-// 2003-01-23 added date format support (Martin Hoerning)
-
-// if two digit year input dates after this year considered 20 century.
-var NUM_CENTYEAR = 30;
-// are year scrolling buttons required by default
-var BUL_YEARSCROLL = true;
-var DEF_CALPAGE = 'skycalendar.html';
-
-var calendars = [];
-var RE_NUM = /^\-?\d+$/;
-var dateFormat = "yyyy-mm-dd";
-
-function skycalendar(obj_target) {
-  // assing methods
-  this.gen_date = cal_gen_date1;
-  this.gen_tsmp = cal_gen_tsmp1;
-  this.prs_date = cal_prs_date1;
-  this.prs_tsmp = cal_prs_tsmp1;
-  this.popup    = cal_popup1;
-  this.setCalendarPage = cal_setcalpage1;
-  this.setDateFormat   = cal_setdateformat1;
-
-  // validate input parameters
-  if (!obj_target)
-    return cal_error("Error calling the calendar: no target control specified");
-  if (obj_target.value == null)
-    return cal_error("Error calling the calendar: parameter specified is not valid tardet control");
-  this.target = obj_target;
-  this.year_scroll = BUL_YEARSCROLL;
-  this.calpage     = DEF_CALPAGE;
-       
-  // register in global collections
-  this.id = calendars.length;
-  calendars[this.id] = this;
-}
-
-function cal_setcalpage1(str_page) {
-  this.calpage = str_page;
-}
-
-function cal_setdateformat1(str_dateformat) {
-  this.dateFormat = str_dateformat;
-}
-
-function cal_popup1(str_datetime) {
-  this.dt_current = this.prs_tsmp(str_datetime ? str_datetime : this.target.value);
-  if (!this.dt_current) return;
-
-  var obj_calwindow = window.open(
-    this.calpage+'?datetime=' + this.dt_current.valueOf()+ '&id=' + this.id,
-      'Calendar', 'width=200,height=190'+
-      ',status=no,resizable=no,top=200,left=200,dependent=yes,alwaysRaised=yes'
-    );
-  obj_calwindow.opener = window;
-  obj_calwindow.focus();
-}
-
-// timestamp generating function
-function cal_gen_tsmp1(dt_datetime) {
-  return this.gen_date(dt_datetime);
-}
-
-// date generating function
-function cal_gen_date1(dt_datetime) {
-  var out = this.dateFormat;
-  var idx;
-  if (out.indexOf("yyyy") != 1) {
-    t = out.split("yyyy");
-    out = t.join(dt_datetime.getFullYear());
-  }
-  else {
-    return cal_error("Missing year-part 'yyyy' in format: '"+this.dateFormat);
-  }
-  if (out.indexOf("mm") != 1) {
-    t = out.split("mm");
-    out = t.join((dt_datetime.getMonth() < 9 ? '0' : '')+
-                 (dt_datetime.getMonth()+1));
-  }
-  else {
-    return cal_error("Missing month-part 'mm' in format: '"+this.dateFormat);
-  }
-  if (out.indexOf("dd") != 1) {
-    t = out.split("dd");
-    out = t.join((dt_datetime.getDate() < 10 ? '0' : '')+
-                 dt_datetime.getDate());
-  }
-  else {
-    return cal_error("Missing day-part 'dd' in format: '"+this.dateFormat);
-  }
-
-  return out;
-}
-
-// timestamp parsing function
-function cal_prs_tsmp1(str_datetime) {
-  // if no parameter specified return current timestamp
-  if (!str_datetime)
-    return (new Date());
-
-  // if positive integer treat as milliseconds from epoch
-  if (RE_NUM.exec(str_datetime))
-    return new Date(str_datetime);
-               
-  return this.prs_date(str_datetime);
-}
-
-// date parsing function
-function cal_prs_date1(str_date) {
-  var idx;
-  var year  = null;
-  var month = null;
-  var day   = null;
-
-  if (str_date.length != this.dateFormat.length) {
-    return cal_error ("Invalid date format: '"+str_date+
-                      "'.\nFormat accepted is '"+this.dateFormat+"'.");
-  }
-
-  if ((idx = this.dateFormat.indexOf("yyyy")) != 1) {
-    year = str_date.substring(idx, idx+4);
-  }
-  else {
-    return cal_error("Missing year-part 'yyyy' in format: '"+this.dateFormat);
-  }
-  if ((idx = this.dateFormat.indexOf("mm")) != 1) {
-    month = str_date.substring(idx, idx+2);
-  }
-  else {
-    return cal_error("Missing month-part 'mm' in format: '"+this.dateFormat);
-  }
-  if ((idx = this.dateFormat.indexOf("dd")) != 1) {
-    day = str_date.substring(idx, idx+2);
-  }
-  else {
-    return cal_error("Missing day-part 'dd' in format: '"+this.dateFormat);
-  }
-
-  if (!day) return cal_error("Invalid date format: '"+str_date+
-                             "'.\nNo day of month value can be found.");
-  if (!RE_NUM.exec(day))
-    return cal_error("Invalid day of month value: '"+day+
-                     "'.\nAllowed values are unsigned integers.");
-
-  if (!month) return cal_error("Invalid date format: '"+str_date+
-                             "'.\nNo month of year value can be found.");
-  if (!RE_NUM.exec(month))
-    return cal_error("Invalid month of year value: '"+month+
-                     "'.\nAllowed values are unsigned integers.");
-  
-  if (!year) return cal_error("Invalid date format: '"+str_date+
-                             "'.\nNo year value can be found.");
-  if (!RE_NUM.exec(year))
-    return cal_error("Invalid year value: '"+year+
-                     "'.\nAllowed values are unsigned integers.");
-
-  
-  var dt_date = new Date();
-  dt_date.setDate(1);
-  if (month < 1 || month > 12)
-    return cal_error("Invalid month value: '"+month+
-                     "'.\nAllowed range is 01-12.");
-  dt_date.setMonth(month-1);
-  if (year < 100) year = Number(year)+(year < NUM_CENTYEAR ? 2000 : 1900);
-  dt_date.setFullYear(year);
-  var dt_numdays = new Date(year, month, 0);
-  dt_date.setDate(day);
-  if (dt_date.getMonth() != (month-1))
-    return cal_error("Invalid day of month value: '"+day+
-                     "'.\nAllowed range is 01-"+dt_numdays.getDate()+".");
-  return (dt_date);
-}
-
-function cal_error(str_message) {
-  alert (str_message);
-  return null;
-}
index a4f3fd3ed7de9e30bf4ac5a49c8c518b9b557020..36018de1d91fd1ffd834a6ef548ba7a01ec516fb 100644 (file)
@@ -10,70 +10,63 @@ SchedulerUI_LANGUAGES = English French German
 
 SchedulerUI_OBJC_FILES =               \
        SchedulerUIProduct.m            \
-       iCalPerson+UIx.m                \
-       NSCalendarDate+UIx.m            \
-       SOGoAppointment+UIx.m           \
+                                       \
+       UIxCalMainView.m                \
+                                       \
+       UIxCalFilterPanel.m             \
+       UIxCalDayTable.m                \
+                                       \
+       UIxCalDateSelector.m            \
+                                       \
        UIxComponent+Agenor.m           \
-       \
        UIxCalView.m                    \
+       UIxCalCalendarsListView.m       \
+       UIxCalAptListView.m             \
+       UIxCalTasksListView.m           \
        UIxCalDayView.m                 \
        UIxCalWeekView.m                \
        UIxCalMonthView.m               \
+       UIxCalMonthViewOld.m            \
        UIxAptTableView.m               \
                                        \
        UIxCalDayOverview.m             \
        UIxCalDayChartview.m            \
        UIxCalDayListview.m             \
-       UIxCalDayPrintview.m            \
        UIxCalWeekOverview.m            \
        UIxCalWeekChartview.m           \
        UIxCalWeekListview.m            \
        UIxCalWeekColumnsview.m         \
-       UIxCalWeekPrintview.m           \
        UIxCalMonthOverview.m           \
-       UIxCalMonthPrintview.m          \
        UIxCalYearOverview.m            \
        UIxCalInlineMonthOverview.m     \
+       UIxComponentEditor.m            \
+       UIxFreeBusyUserSelector.m       \
+       UIxFreeBusyUserSelectorTable.m  \
        UIxAppointmentView.m            \
-       UIxAppointmentPrintview.m       \
        UIxAppointmentEditor.m          \
+       UIxAppointmentProposal.m        \
+       UIxTaskView.m           \
+       UIxTaskEditor.m         \
+       UIxTaskProposal.m       \
        UIxCalSelectTab.m               \
        UIxCalDateLabel.m               \
        UIxCalBackForthNavView.m        \
-       UIxAppointmentProposal.m        \
        UIxDatePicker.m                 \
-       UIxDatePickerScript.m           \
-       UIxTimeSelector.m               \
        UIxTimeDateControl.m            \
        UIxCalInlineAptView.m           \
        UIxCalScheduleOverview.m        \
        UIxCalParticipationStatusView.m \
-       \
-       iCalRecurrenceRule+SOGo.m       \
 
 SchedulerUI_RESOURCE_FILES += \
        Version         \
-       product.plist
+       product.plist   
 
 SchedulerUI_RESOURCE_FILES += \
-       images/next_week.gif                    \
-       images/previous_week.gif                \
-       images/icon_view_overview.gif           \
-       images/icon_view_overview_inactive.gif  \
-       images/icon_view_chart.gif              \
-       images/icon_view_chart_inactive.gif     \
-       images/icon_view_list.gif               \
-       images/icon_view_list_inactive.gif      \
-       images/icon_view_columns.gif            \
-       images/icon_view_columns_inactive.gif   \
-       images/icon_popupcalendar.gif           \
-       images/first.gif                        \
-       images/previous.gif                     \
-       images/next.gif                         \
-       images/last.gif                         \
-       images/green_corner.gif                 \
-       images/invisible_space_2.gif            \
-       images/apt_icon_private.gif             \
+       Toolbars/SOGoAppointmentFolder.toolbar \
+       Toolbars/SOGoAppointmentObject.toolbar \
+       Toolbars/SOGoAppointmentObjectAccept.toolbar \
+       Toolbars/SOGoAppointmentObjectDecline.toolbar \
+       Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar
 
 SchedulerUI_LOCALIZED_RESOURCE_FILES += \
        Localizable.strings             \
@@ -81,8 +74,6 @@ SchedulerUI_LOCALIZED_RESOURCE_FILES += \
 # if SoProduct is fixed to enable localized resources, add this to
 # SchedulerUI_LOCALIZED_RESOURCE_FILES instead
 SchedulerUI_RESOURCE_FILES +=          \
-       skycalendar.html                \
-       skycalendar.js                  \
        cycles.plist                    \
 
 # make
index 73c977c3266773edb2c508153e0bcbcbbd95f6c6..efc9130d98e8a3f21498bb3396b15a107496a02f 100644 (file)
@@ -2,4 +2,3 @@
 
 ADDITIONAL_INCLUDE_DIRS += \
        -I.. -I../.. -I../../..
-
index 5e1230b0e95f1e5eb160273897acc16f5af8c132..d943cdb17cc6aac9f1418989ed5d332ef1c6bf34 100644 (file)
@@ -12,8 +12,9 @@ Class Hierarchy
     [SoComponent]
       UIxAppointmentView
       UIxCalView
-        UIxCalMonthView
+        UIxCalMonthViewOld
           UIxCalMonthOverview
+        UIxCalMonthView
         UIxCalWeekView
           UIxCalWeekOverview
             UIxCalWeekPrintview
diff --git a/UI/Scheduler/NSCalendarDate+UIx.h b/UI/Scheduler/NSCalendarDate+UIx.h
deleted file mode 100644 (file)
index 83e228e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: UIxAppointmentEditor.m 181 2004-08-11 15:13:25Z helge $
-
-#ifndef __NSCalendarDate_UIx_H__
-#define __NSCalendarDate_UIx_H__
-
-#import <Foundation/NSCalendarDate.h>
-
-@interface NSCalendarDate(UIx)
-
-- (NSCalendarDate *)dayOfWeeK:(unsigned)_day offsetFromSunday:(unsigned)_off;
-- (NSCalendarDate *)sundayOfWeek;
-
-@end
-
-#endif /* __NSCalendarDate_UIx_H__ */
diff --git a/UI/Scheduler/NSCalendarDate+UIx.m b/UI/Scheduler/NSCalendarDate+UIx.m
deleted file mode 100644 (file)
index 079de1d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: UIxAppointmentEditor.m 181 2004-08-11 15:13:25Z helge $
-
-#include "NSCalendarDate+UIx.h"
-#include "common.h"
-
-@implementation NSCalendarDate(UIx)
-
-- (NSCalendarDate *)dayOfWeeK:(unsigned)_day 
-  offsetFromSunday:(unsigned)_offset
-{
-  unsigned dayOfWeek, distance;
-    
-  /* perform "locale" correction */
-  dayOfWeek = (7 + [self dayOfWeek] - _offset) % 7;
-
-  _day = (_day % 7);
-  if(_day == dayOfWeek)
-    return self;
-
-  distance = _day - dayOfWeek;
-  return [self dateByAddingYears:0 months:0 days:distance];
-}
-
-/* this implies that monday is the start of week! */
-
-- (NSCalendarDate *)sundayOfWeek {
-  return [self dayOfWeeK:6 offsetFromSunday:1];
-}
-
-@end /* NSCalendarDate(UIx) */
diff --git a/UI/Scheduler/SOGoAppointment+UIx.h b/UI/Scheduler/SOGoAppointment+UIx.h
deleted file mode 100644 (file)
index dbbcaec..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-  Copyright (C) 2000-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#ifndef        __SOGoAppointment_UIx_H_
-#define        __SOGoAppointment_UIx_H_
-
-#include <SOGo/SOGoAppointment.h>
-
-@interface SOGoAppointment (UIx)
-- (NSString *)priorityLabelKey;
-@end
-
-#endif /* __SOGoAppointment_UIx_H_ */
diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentFolder.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentFolder.toolbar
new file mode 100644 (file)
index 0000000..ceca26f
--- /dev/null
@@ -0,0 +1,36 @@
+( /* the toolbar groups -*-cperl-*- */
+  ( { link = "#";
+      isSafe = NO;
+      label = "New Event";
+      onclick = "return newEvent(this, 'event');";
+      image = "new-event.png"; },
+    { link  = "new_task";
+      label="New Task";
+      image = "new-task.png";
+      onclick = "return newEvent(this, 'task');";
+      image = "new-task.png"; },
+    { link  = "edit";
+      label="Edit";
+      onclick = "return editEvent(this);";
+      image = "edit.png"; },
+    { link  = "delete";
+      label="Delete";
+      onclick = "return deleteEvent(this);";
+      image = "delete.png"; } ),
+  ( { link  = "today";
+      label="Go to Today";
+      onclick = "return gotoToday();";
+      image = "goto-today.png" } ),
+  ( { link  = "dayoverview";
+      label="Day View";
+      onclick = "return onDayOverview();";
+      image = "day-view.png"; },
+    { link  = "weekoverview";
+      label="Week View";
+      onclick = "return onWeekOverview();";
+      image = "week-view.png"; },
+    { link  = "monthoverview";
+      label="Month View";
+      onclick = "return onMonthOverview();";
+      image = "month-view.png"; } )
+)
diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentObject.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentObject.toolbar
new file mode 100644 (file)
index 0000000..17e78b7
--- /dev/null
@@ -0,0 +1,7 @@
+( /* the toolbar groups -*-cperl-*- */
+  ( { link = "#";
+      isSafe = NO;
+      label = "Save";
+      onclick = "return saveEvent(this);";
+      image = "tb-compose-save-flat-24x24.png"; } )
+)
diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentObjectAccept.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentObjectAccept.toolbar
new file mode 100644 (file)
index 0000000..e3913af
--- /dev/null
@@ -0,0 +1,7 @@
+( /* the toolbar groups -*-cperl-*- */
+  ( { link = "#";
+      isSafe = NO;
+      label = "accept";
+      onclick = "return modifyEvent(this, 'accept');";
+      image = "tb-ab-properties-flat-24x24.png"; } )
+)
diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar
new file mode 100644 (file)
index 0000000..bb967d8
--- /dev/null
@@ -0,0 +1,12 @@
+( /* the toolbar groups -*-cperl-*- */
+  ( { link = "#";
+      isSafe = NO;
+      label = "accept";
+      onclick = "return modifyEvent(this, 'accept');";
+      image = "tb-ab-properties-flat-24x24.png"; },
+    { link = "#";
+      isSafe = NO;
+      label = "decline";
+      onclick = "return modifyEvent(this, 'decline');";
+      image = "tb-mail-stop-flat-24x24.png"; } )
+)
diff --git a/UI/Scheduler/Toolbars/SOGoAppointmentObjectDecline.toolbar b/UI/Scheduler/Toolbars/SOGoAppointmentObjectDecline.toolbar
new file mode 100644 (file)
index 0000000..347b8f8
--- /dev/null
@@ -0,0 +1,7 @@
+( /* the toolbar groups -*-cperl-*- */
+  ( { link = "#";
+      isSafe = NO;
+      label = "decline";
+      onclick = "return modifyEvent(this, 'decline');";
+      image = "tb-mail-stop-flat-24x24.png"; } )
+)
diff --git a/UI/Scheduler/UIxAppointmentEditor.h b/UI/Scheduler/UIxAppointmentEditor.h
new file mode 100644 (file)
index 0000000..612de9e
--- /dev/null
@@ -0,0 +1,73 @@
+/* UIxAppointmentEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXAPPOINTMENTEDITOR_H
+#define UIXAPPOINTMENTEDITOR_H
+
+#import <UIxComponentEditor.h>
+
+@class NSString;
+@class iCalPerson;
+@class iCalRecurrenceRule;
+
+@interface UIxAppointmentEditor : UIxComponentEditor
+{
+  NSCalendarDate *endDate;
+}
+
+- (void) setAptStartDate: (NSCalendarDate *) _date;
+- (NSCalendarDate *) aptStartDate;
+
+- (void) setAptEndDate: (NSCalendarDate *) _date;
+- (NSCalendarDate *) aptEndDate;
+
+/* iCal */
+
+- (NSString *) iCalStringTemplate;
+
+/* new */
+
+- (id) newAction;
+
+/* save */
+
+- (void) loadValuesFromAppointment: (iCalEvent *) _apt;
+- (void) saveValuesIntoAppointment: (iCalEvent *) _apt;
+- (iCalEvent *) appointmentFromString: (NSString *) _iCalString;
+
+/* conflict management */
+
+- (BOOL) containsConflict: (id) _apt;
+- (id <WOActionResults>) defaultAction;
+- (id <WOActionResults>) saveAction;
+- (id) acceptAction;
+- (id) declineAction;
+
+- (NSString *) saveUrl;
+
+// TODO: add tentatively
+
+- (id) acceptOrDeclineAction: (BOOL) _accept;
+
+@end
+
+#endif /* UIXAPPOINTMENTEDITOR_H */
index 676a125d007b61e167758809238752e51c7b6a15..f8b1947392e72dbf896a6e279284531d0fa8c0f7 100644 (file)
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
+#import <NGCards/NSString+NGCards.h>
+#import <NGCards/NSCalendarDate+NGCards.h>
 
-/* TODO: CLEAN UP */
-
-@class NSString;
-@class iCalPerson;
-@class iCalRecurrenceRule;
-@class SOGoAppointment;
-
-@interface UIxAppointmentEditor : UIxComponent
-{
-  NSString *iCalString;
-  NSString *errorText;
-  id item;
-  
-  /* individual values */
-  NSCalendarDate *startDate;
-  NSCalendarDate *endDate;
-  NSCalendarDate *cycleUntilDate;
-  NSString       *title;
-  NSString       *location;
-  NSString       *comment;
-  iCalPerson     *organizer;
-  NSArray        *participants;     /* array of iCalPerson's */
-  NSArray        *resources;        /* array of iCalPerson's */
-  NSString       *priority;
-  NSArray        *categories;
-  NSString       *accessClass;
-  BOOL           isPrivate;         /* default: NO */
-  BOOL           checkForConflicts; /* default: NO */
-  NSDictionary   *cycle;
-  NSString       *cycleEnd;
-}
-
-- (NSString *)iCalStringTemplate;
-- (NSString *)iCalString;
-
-- (void)setIsPrivate:(BOOL)_yn;
-- (void)setAccessClass:(NSString *)_class;
-
-- (void)setCheckForConflicts:(BOOL)_checkForConflicts;
-- (BOOL)checkForConflicts;
-
-- (BOOL)hasCycle;
-- (iCalRecurrenceRule *)rrule;
-- (void)adjustCycleControlsForRRule:(iCalRecurrenceRule *)_rrule;
-- (NSDictionary *)cycleMatchingRRule:(iCalRecurrenceRule *)_rrule;
-
-- (BOOL)isCycleEndUntil;
-- (void)setIsCycleEndUntil;
-- (void)setIsCycleEndNever;
-
-- (NSString *)_completeURIForMethod:(NSString *)_method;
-
-- (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values
-  treatAsResource:(BOOL)_isResource;
-
-- (NSString *)iCalParticipantsAndResourcesStringFromQueryParameters;
-- (NSString *)iCalParticipantsStringFromQueryParameters;
-- (NSString *)iCalResourcesStringFromQueryParameters;
-- (NSString *)iCalStringFromQueryParameter:(NSString *)_qp
-              format:(NSString *)_format;
-- (NSString *)iCalOrganizerString;
-
-- (id)acceptOrDeclineAction:(BOOL)_accept;
-
-@end
+#import <SOGo/AgenorUserManager.h>
+#import <SOGo/NSCalendarDate+SOGo.h>
 
-#include "common.h"
-#include <NGiCal/NGiCal.h>
-#include <NGExtensions/NGCalendarDateRange.h>
-#include <SOGoUI/SOGoDateFormatter.h>
-#include <SOGo/SOGoAppointment.h>
-#include <SOGo/AgenorUserManager.h>
-#include <Appointments/SOGoAppointmentFolder.h>
-#include <Appointments/SOGoAppointmentObject.h>
-#include "iCalPerson+UIx.h"
-#include "UIxComponent+Agenor.h"
+#import "common.h"
+#import <NGCards/NGCards.h>
+#import <NGExtensions/NGCalendarDateRange.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+#import <Appointments/SOGoAppointmentFolder.h>
+#import <Appointments/SOGoAppointmentObject.h>
+#import "UIxComponent+Agenor.h"
 
-@interface iCalRecurrenceRule (SOGoExtensions)
-- (NSString *)cycleRepresentationForSOGo;
-@end
+#import "UIxAppointmentEditor.h"
 
-@interface NSDate(UsedPrivates)
-- (NSString *)icalString; // TODO: this is in NGiCal
-@end
+/* TODO: CLEAN UP */
 
 @implementation UIxAppointmentEditor
 
             NSStringFromClass([self superclass]), [super version]);
 }
 
-- (id)init {
-  self = [super init];
-  if(self) {
-    [self setIsPrivate:NO];
-    [self setCheckForConflicts:NO];
-    [self setIsCycleEndNever];
-  }
-  return self;
-}
-
-- (void)dealloc {
-  [self->iCalString     release];
-  [self->errorText      release];
-  [self->item           release];
-
-  [self->startDate      release];
-  [self->endDate        release];
-  [self->cycleUntilDate release];
-  [self->title          release];
-  [self->location       release];
-  [self->organizer      release];
-  [self->comment        release];
-  [self->participants   release];
-  [self->resources      release];
-  [self->priority       release];
-  [self->categories     release];
-  [self->accessClass    release];
-  [self->cycle          release];
-  [self->cycleEnd      release];
+- (void) dealloc
+{
+  [endDate release];
   [super dealloc];
 }
 
 /* accessors */
 
-- (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
-}
-- (id)item {
-  return self->item;
-}
-
-- (void)setErrorText:(NSString *)_txt {
-  ASSIGNCOPY(self->errorText, _txt);
-}
-- (NSString *)errorText {
-  return self->errorText;
-}
-- (BOOL)hasErrorText {
-  return [self->errorText length] > 0 ? YES : NO;
-}
-
-- (NSFormatter *)titleDateFormatter {
-  SOGoDateFormatter *fmt;
-  
-  fmt = [[[SOGoDateFormatter alloc] initWithLocale:[self locale]] autorelease];
-  [fmt setFullWeekdayNameAndDetails];
-  return fmt;
-}
-
-- (void)setAptStartDate:(NSCalendarDate *)_date {
-  ASSIGN(self->startDate, _date);
-}
-- (NSCalendarDate *)aptStartDate {
-  return self->startDate;
-}
-- (void)setAptEndDate:(NSCalendarDate *)_date {
-  ASSIGN(self->endDate, _date);
-}
-- (NSCalendarDate *)aptEndDate {
-  return self->endDate;
-}
-
-- (void)setTitle:(NSString *)_value {
-  ASSIGNCOPY(self->title, _value);
-}
-- (NSString *)title {
-  return self->title;
-}
-- (void)setLocation:(NSString *)_value {
-  ASSIGNCOPY(self->location, _value);
-}
-- (NSString *)location {
-  return self->location;
-}
-- (void)setComment:(NSString *)_value {
-  ASSIGNCOPY(self->comment, _value);
-}
-- (NSString *)comment {
-  return self->comment;
-}
-
-- (void)setParticipants:(NSArray *)_parts {
-  ASSIGN(self->participants, _parts);
-}
-- (NSArray *)participants {
-  return self->participants;
-}
-- (void)setResources:(NSArray *)_res {
-  ASSIGN(self->resources, _res);
-}
-- (NSArray *)resources {
-  return self->resources;
-}
-
-/* priorities */
-
-- (NSArray *)priorities {
-  /* 0 == undefined
-     5 == normal
-     1 == high
-  */
-  static NSArray *priorities = nil;
-
-  if (!priorities)
-    priorities = [[NSArray arrayWithObjects:@"0", @"5", @"1", nil] retain];
-  return priorities;
-}
-
-- (NSString *)itemPriorityText {
-  NSString *key;
-  
-  key = [NSString stringWithFormat:@"prio_%@", self->item];
-  return [self labelForKey:key];
-}
-
-- (void)setPriority:(NSString *)_priority {
-  ASSIGN(self->priority, _priority);
-}
-- (NSString *)priority {
-  return self->priority;
-}
-
-
-/* categories */
-
-- (NSArray *)categoryItems {
-  // TODO: make this configurable?
-  /*
-   Tasks categories will be modified as follow :
-   â€“ by default (a simple logo or no logo at all),
-   â€“ appointment,
-   â€“ outside,
-   â€“ meeting,
-   â€“ holidays,
-   â€“ phone.
-  */
-  static NSArray *categoryItems = nil;
-  
-  if (!categoryItems) {
-    categoryItems = [[NSArray arrayWithObjects:@"APPOINTMENT",
-                                               @"NOT IN OFFICE",
-                                               @"MEETING",
-                                               @"HOLIDAY",
-                                               @"PHONE CALL",
-                                               nil] retain];
-  }
-  return categoryItems;
-}
-
-- (NSString *)itemCategoryText {
-  return [self labelForKey:self->item];
-}
-
-- (void)setCategories:(NSArray *)_categories {
-  ASSIGN(self->categories, _categories);
-}
-- (NSArray *)categories {
-  return self->categories;
-}
-
-/* class */
-
-#if 0
-- (NSArray *)accessClassItems {
-  static NSArray classItems = nil;
-  
-  if (!classItems) {
-    return [[NSArray arrayWithObjects:@"PUBLIC", @"PRIVATE", nil] retain];
-  }
-  return classItems;
-}
-#endif
-
-- (void)setAccessClass:(NSString *)_class {
-  ASSIGN(self->accessClass, _class);
-}
-- (NSString *)accessClass {
-  return self->accessClass;
-}
-
-- (void)setIsPrivate:(BOOL)_yn {
-  if (_yn)
-    [self setAccessClass:@"PRIVATE"];
-  else
-    [self setAccessClass:@"PUBLIC"];
-  self->isPrivate = _yn;
-}
-- (BOOL)isPrivate {
-  return self->isPrivate;
-}
-
-- (void)setCheckForConflicts:(BOOL)_checkForConflicts {
-  self->checkForConflicts = _checkForConflicts;
-}
-- (BOOL)checkForConflicts {
-  return self->checkForConflicts;
-}
-
-- (NSArray *)cycles {
-  static NSArray *cycles = nil;
-  
-  if (!cycles) {
-    NSBundle *bundle;
-    NSString *path;
-
-    bundle = [NSBundle bundleForClass:[self class]];
-    path   = [bundle pathForResource:@"cycles" ofType:@"plist"];
-    NSAssert(path != nil, @"Cannot find cycles.plist!");
-    cycles = [[NSArray arrayWithContentsOfFile:path] retain];
-    NSAssert(cycles != nil, @"Cannot instantiate cycles from cycles.plist!");
-  }
-  return cycles;
-}
-
-- (void)setCycle:(NSDictionary *)_cycle {
-  ASSIGN(self->cycle, _cycle);
-}
-- (NSDictionary *)cycle {
-  return self->cycle;
-}
-- (BOOL)hasCycle {
-  [self debugWithFormat:@"cycle: %@", self->cycle];
-  if (![self->cycle objectForKey:@"rule"])
-    return NO;
-  return YES;
-}
-- (NSString *)cycleLabel {
-  NSString *key;
-  
-  key = [(NSDictionary *)self->item objectForKey:@"label"];
-  return [self labelForKey:key];
-}
-
-
-- (void)setCycleUntilDate:(NSCalendarDate *)_cycleUntilDate {
-  NSCalendarDate *until;
-
-  /* copy hour/minute/second from startDate */
-  until = [_cycleUntilDate hour:[self->startDate hourOfDay]
-                           minute:[self->startDate minuteOfHour]
-                           second:[self->startDate secondOfMinute]];
-  [until setTimeZone:[self->startDate timeZone]];
-  ASSIGN(self->cycleUntilDate, until);
-}
-- (NSCalendarDate *)cycleUntilDate {
-  return self->cycleUntilDate;
-}
-
-- (iCalRecurrenceRule *)rrule {
-  NSString           *ruleRep;
-  iCalRecurrenceRule *rule;
-
-  if (![self hasCycle])
-    return nil;
-  ruleRep = [self->cycle objectForKey:@"rule"];
-  rule    = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:ruleRep];
-
-  if (self->cycleUntilDate && [self isCycleEndUntil])
-    [rule setUntilDate:self->cycleUntilDate];
-  return rule;
-}
-
-- (void)adjustCycleControlsForRRule:(iCalRecurrenceRule *)_rrule {
-  NSDictionary   *c;
-  NSCalendarDate *until;
-  
-  c = [self cycleMatchingRRule:_rrule];
-  [self setCycle:c];
-
-  until = [[[_rrule untilDate] copy] autorelease];
-  if (!until)
-    until = self->startDate;
-  else
-    [self setIsCycleEndUntil];
-
-  [until setTimeZone:[self viewTimeZone]];
-  [self setCycleUntilDate:until];
+- (void) setAptStartDate: (NSCalendarDate *)_date
+{
+  [self setStartDate: _date];
 }
 
-/*
- This method is necessary, because we have a fixed sets of cycles in the UI.
- The model is able to represent arbitrary rules, however.
- There SHOULD be a different UI, similar to iCal.app, to allow modelling
- of more complex rules.
- This method obviously cannot map all existing rules back to the fixed list
- in cycles.plist. This should be fixed in a future version when interop
- becomes more important.
- */
-- (NSDictionary *)cycleMatchingRRule:(iCalRecurrenceRule *)_rrule {
-  NSString *cycleRep;
-  NSArray  *cycles;
-  unsigned i, count;
-
-  if (!_rrule)
-    return [[self cycles] objectAtIndex:0];
-
-  cycleRep = [_rrule cycleRepresentationForSOGo];
-  cycles   = [self cycles];
-  count    = [cycles count];
-  for (i = 1; i < count; i++) {
-    NSDictionary *c;
-    NSString     *cr;
-
-    c  = [cycles objectAtIndex:i];
-    cr = [c objectForKey:@"rule"];
-    if ([cr isEqualToString:cycleRep])
-      return c;
-  }
-  [self warnWithFormat:@"No default cycle for rrule found! -> %@", _rrule];
-  return nil;
+- (NSCalendarDate *) aptStartDate
+{
+  return [self startDate];
 }
 
-/* cycle "ends" - supposed to be 'never', 'COUNT' or 'UNTIL' */
-- (NSArray *)cycleEnds {
-  static NSArray *ends = nil;
-  
-  if (!ends) {
-    ends = [[NSArray alloc] initWithObjects:@"cycle_end_never",
-                                            @"cycle_end_until",
-                                            nil];
-  }
-  return ends;
+- (void) setAptEndDate: (NSCalendarDate *) _date
+{
+  ASSIGN(endDate, _date);
 }
 
-- (void)setCycleEnd:(NSString *)_cycleEnd {
-  ASSIGNCOPY(self->cycleEnd, _cycleEnd);
-}
-- (NSString *)cycleEnd {
-  return self->cycleEnd;
-}
-- (BOOL)isCycleEndUntil {
-  return (self->cycleEnd &&
-          [self->cycleEnd isEqualToString:@"cycle_end_until"]);
-}
-- (void)setIsCycleEndUntil {
-  [self setCycleEnd:@"cycle_end_until"];
-}
-- (void)setIsCycleEndNever {
-  [self setCycleEnd:@"cycle_end_never"];
+- (NSCalendarDate *) aptEndDate
+{
+  return endDate;
 }
 
 /* transparency */
 
-- (NSString *)transparency {
-  return @"TRANSPARENT";
+- (NSString *) transparency
+{
+  return @"OPAQUE";
 }
 
-
 /* iCal */
 
-- (void)setICalString:(NSString *)_s {
-  ASSIGNCOPY(self->iCalString, _s);
-}
-- (NSString *)iCalString {
-  return self->iCalString;
-}
-
 - (NSString *)iCalStringTemplate {
   static NSString *iCalStringTemplate = \
     @"BEGIN:VCALENDAR\r\n"
     @"METHOD:REQUEST\r\n"
-    @"PRODID:OpenGroupware.org SOGo 0.9\r\n"
+    @"PRODID://Inverse groupe conseil/SOGo 0.9\r\n"
     @"VERSION:2.0\r\n"
     @"BEGIN:VEVENT\r\n"
     @"UID:%@\r\n"
     @"CLASS:PUBLIC\r\n"
     @"STATUS:CONFIRMED\r\n" /* confirmed by default */
-    @"DTSTAMP:%@\r\n"
-    @"DTSTART:%@\r\n"
-    @"DTEND:%@\r\n"
+    @"DTSTAMP:%@Z\r\n"
+    @"DTSTART:%@Z\r\n"
+    @"DTEND:%@Z\r\n"
     @"TRANSP:%@\r\n"
     @"SEQUENCE:1\r\n"
     @"PRIORITY:5\r\n"
     @"END:VEVENT\r\n"
     @"END:VCALENDAR";
 
-  NSCalendarDate *lStartDate, *lEndDate;
-  NSString       *template, *s;
-  unsigned       minutes;
+  NSTimeZone *utc;
+  NSCalendarDate *lStartDate, *lEndDate, *stamp;
+  NSString *template, *s;
+  unsigned minutes;
 
   s = [self queryParameterForKey:@"dur"];
-  if(s && [s length] > 0) {
+  if ([s length] > 0)
     minutes = [s intValue];
-  }
-  else {
+  else
     minutes = 60;
-  }
-  lStartDate = [self selectedDate];
-  lEndDate   = [lStartDate dateByAddingYears:0 months:0 days:0
-                           hours:0 minutes:minutes seconds:0];
-  
-  s          = [self iCalParticipantsAndResourcesStringFromQueryParameters];
-  template   = [NSString stringWithFormat:iCalStringTemplate,
-                                                     [[self clientObject] nameInContainer],
-                                                     [[NSCalendarDate date] icalString],
-                                          [lStartDate icalString],
-                                          [lEndDate icalString],
-                                          [self transparency],
-                                          [self iCalOrganizerString],
-                                          s];
-  return template;
-}
-
-- (NSString *)iCalParticipantsAndResourcesStringFromQueryParameters {
-  NSString *s;
-  
-  s = [self iCalParticipantsStringFromQueryParameters];
-  return [s stringByAppendingString:
-            [self iCalResourcesStringFromQueryParameters]];
-}
-
-- (NSString *)iCalParticipantsStringFromQueryParameters {
-  static NSString *iCalParticipantString = \
-    @"ATTENDEE;ROLE=REQ-PARTICIPANT;CN=\"%@\":mailto:%@\r\n";
-  
-  return [self iCalStringFromQueryParameter:@"ps"
-               format:iCalParticipantString];
-}
-
-- (NSString *)iCalResourcesStringFromQueryParameters {
-  static NSString *iCalResourceString = \
-    @"ATTENDEE;ROLE=NON-PARTICIPANT;CN=\"%@\":mailto:%@\r\n";
-
-  return [self iCalStringFromQueryParameter:@"rs"
-               format:iCalResourceString];
-}
-
-- (NSString *)iCalStringFromQueryParameter:(NSString *)_qp
-              format:(NSString *)_format
-{
-  AgenorUserManager *um;
-  NSMutableString *iCalRep;
-  NSString *s;
-
-  um = [AgenorUserManager sharedUserManager];
-  iCalRep = (NSMutableString *)[NSMutableString string];
-  s = [self queryParameterForKey:_qp];
-  if(s && [s length] > 0) {
-    NSArray *es;
-    unsigned i, count;
-    
-    es = [s componentsSeparatedByString:@","];
-    count = [es count];
-    for(i = 0; i < count; i++) {
-      NSString *email, *cn;
-      
-      email = [es objectAtIndex:i];
-      cn = [um getCNForUID:[um getUIDForEmail:email]];
-      [iCalRep appendFormat:_format, cn, email];
-    }
-  }
-  return iCalRep;
-}
-
-- (NSString *)iCalOrganizerString {
-  static NSString *fmt = @"ORGANIZER;CN=\"%@\":mailto:%@\r\n";
-  return [NSString stringWithFormat:fmt,
-                                      [self cnForUser],
-                                      [self emailForUser]];
-}
-
-#if 0
-- (iCalPerson *)getOrganizer {
-  iCalPerson *p;
-  NSString   *emailProp;
-  
-  emailProp = [@"mailto:" stringByAppendingString:[self emailForUser]];
-  p = [[[iCalPerson alloc] init] autorelease];
-  [p setEmail:emailProp];
-  [p setCn:[self cnForUser]];
-  return p;
-}
-#endif
 
+  utc = [NSTimeZone timeZoneWithName: @"GMT"];
+  lStartDate = [self newStartDate];
+  [lStartDate setTimeZone: utc];
+  lEndDate = [lStartDate dateByAddingYears: 0 months: 0 days: 0
+                         hours: 0 minutes: minutes seconds: 0];
 
-/* helper */
+  stamp = [NSCalendarDate calendarDate];
+  [stamp setTimeZone: utc];
 
-- (NSString *)_completeURIForMethod:(NSString *)_method {
-  NSString *uri;
-  NSRange r;
-    
-  uri = [[[self context] request] uri];
-    
-  /* first: identify query parameters */
-  r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
-  if (r.length > 0)
-    uri = [uri substringToIndex:r.location];
-    
-  /* next: append trailing slash */
-  if (![uri hasSuffix:@"/"])
-    uri = [uri stringByAppendingString:@"/"];
-  
-  /* next: append method */
-  uri = [uri stringByAppendingString:_method];
-    
-  /* next: append query parameters */
-  return [self completeHrefForMethod:uri];
+  s          = [self iCalParticipantsAndResourcesStringFromQueryParameters];
+  template   = [NSString stringWithFormat:iCalStringTemplate,
+                         [[self clientObject] nameInContainer],
+                         [stamp iCalFormattedDateTimeString],
+                         [lStartDate iCalFormattedDateTimeString],
+                         [lEndDate iCalFormattedDateTimeString],
+                         [self transparency],
+                         [self iCalOrganizerString],
+                         s];
+  return template;
 }
 
 /* new */
 
-- (id)newAction {
+- (id) newAction
+{
   /*
     This method creates a unique ID and redirects to the "edit" method on the
     new ID.
                        reason:@"could not create a unique ID"];
   }
 
-  method = [NSString stringWithFormat:@"Calendar/%@/edit", objectId];
+  method = [NSString stringWithFormat:@"Calendar/%@/editAsAppointment", objectId];
   method = [[self userFolderPath] stringByAppendingPathComponent:method];
 
   /* check if participants have already been provided */
-  ps     = [[[self context] request] formValueForKey:@"ps"];
-  if (ps) {
-    [self setQueryParameter:ps forKey:@"ps"];
-  }
-  else if ([[self clientObject] respondsToSelector:@selector(calendarUIDs)]) {
+  ps     = [self queryParameterForKey:@"ps"];
+//   if (ps) {
+//     [self setQueryParameter:ps forKey:@"ps"];
+//   }
+ if (!ps
+     && [[self clientObject] respondsToSelector:@selector(calendarUIDs)]) {
     AgenorUserManager *um;
-    NSArray           *uids;
-    NSMutableArray    *emails;
-    unsigned          i, count;
+    NSArray *uids;
+    NSMutableArray *emails;
+    unsigned i, count;
 
     /* add all current calendarUIDs as default participants */
 
 
 /* save */
 
-/* returned dates are in GMT */
-- (NSCalendarDate *)_dateFromString:(NSString *)_str {
-  NSCalendarDate *date;
-  
-  date = [NSCalendarDate dateWithString:_str 
-                        calendarFormat:@"%Y-%m-%d %H:%M %Z"];
-  [date setTimeZone:[self backendTimeZone]];
-  return date;
-}
-
-- (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values
-  treatAsResource:(BOOL)_isResource
+- (void) loadValuesFromAppointment: (iCalEvent *) appointment
 {
-  unsigned i, count;
-  NSMutableArray *result;
-
-  count = [_values count];
-  result = [[NSMutableArray alloc] initWithCapacity:count];
-  for (i = 0; i < count; i++) {
-    NSString   *pString, *email, *cn;
-    NSRange    r;
-    iCalPerson *p;
-    
-    pString = [_values objectAtIndex:i];
-    if ([pString length] == 0)
-      continue;
-    
-    /* delimiter between email and cn */
-    r = [pString rangeOfString:@";"];
-    if (r.length > 0) {
-      email = [pString substringToIndex:r.location];
-      cn = (r.location + 1 < [pString length])
-       ? [pString substringFromIndex:r.location + 1]
-       : nil;
-    }
-    else {
-      email = pString;
-      cn    = nil;
-    }
-    if (cn == nil) {
-      /* fallback */
-      AgenorUserManager *um = [AgenorUserManager sharedUserManager];
-      cn = [um getCNForUID:[um getUIDForEmail:email]];
-    }
-    
-    p = [[iCalPerson alloc] init];
-    [p setEmail:[@"mailto:" stringByAppendingString:email]];
-    if ([cn isNotNull]) [p setCn:cn];
-    
-    /* see RFC2445, sect. 4.2.16 for details */
-    [p setRole:_isResource ? @"NON-PARTICIPANT" : @"REQ-PARTICIPANT"];
-    [result addObject:p];
-    [p release];
-  }
-  return [result autorelease];
-}
+  NSTimeZone *uTZ;
 
-- (BOOL)isWriteableClientObject {
-  return [[self clientObject] 
-               respondsToSelector:@selector(saveContentString:)];
-}
+  [self loadValuesFromComponent: appointment];
 
-- (NSException *)validateObjectForStatusChange {
-  BOOL ok;
-  id co;
+  uTZ = [[self clientObject] userTimeZone];
+  endDate = [appointment endDate];
+  if (!endDate)
+    endDate = [[self startDate] dateByAddingYears: 0 months: 0 days: 0
+                                hours: 1 minutes: 0 seconds: 0];
 
-  co = [self clientObject];
-  ok = [co respondsToSelector:@selector(changeParticipationStatus:inContext:)];
-  if (!ok) {
-    return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                        reason:
-                          @"method cannot be invoked on the specified object"];
-  }
-  return nil;
+  [endDate setTimeZone: uTZ];
+  [endDate retain];
 }
 
-- (void)loadValuesFromAppointment:(SOGoAppointment *)_appointment {
-  NSString           *s;
-  iCalRecurrenceRule *rrule;
-
-  if ((self->startDate = [[_appointment startDate] copy]) == nil)
-    self->startDate = [[[NSCalendarDate date] hour:11 minute:0] copy];
-  if ((self->endDate = [[_appointment endDate] copy]) == nil) {
-    self->endDate =
-      [[self->startDate hour:[self->startDate hourOfDay] + 1 minute:0] copy];
-  }
-  [self->startDate setTimeZone:[self viewTimeZone]];
-  [self->endDate   setTimeZone:[self viewTimeZone]];
-  
-  self->title        = [[_appointment summary]  copy];
-  self->location     = [[_appointment location] copy];
-  self->comment      = [[_appointment comment]  copy];
-  self->priority     = [[_appointment priority] copy];
-  self->categories   = [[_appointment categories]   retain];
-  self->organizer    = [[_appointment organizer]    retain];
-  self->participants = [[_appointment participants] retain];
-  self->resources    = [[_appointment resources]    retain];
-
-  s                  = [_appointment accessClass];
-  if(!s || [s isEqualToString:@"PUBLIC"])
-    [self setIsPrivate:NO];
-  else
-    [self setIsPrivate:YES]; /* we're possibly loosing information here */
-
-  /* cycles */
-  rrule = [_appointment recurrenceRule];
-  [self adjustCycleControlsForRRule:rrule];
-}
-
-- (void)saveValuesIntoAppointment:(SOGoAppointment *)_appointment {
+- (void) saveValuesIntoAppointment: (iCalEvent *) _appointment
+{
   /* merge in form values */
   NSArray *attendees, *lResources;
+  iCalRecurrenceRule *rrule;
   
   [_appointment setStartDate:[self aptStartDate]];
   [_appointment setEndDate:[self aptEndDate]];
-  
-  [_appointment setSummary:[self title]];
-  [_appointment setLocation:[self location]];
-  [_appointment setComment:[self comment]];
+
+  [_appointment setSummary: [self title]];
+  [_appointment setUrl: [self url]];
+  [_appointment setLocation: [self location]];
+  [_appointment setComment: [self comment]];
   [_appointment setPriority:[self priority]];
-  [_appointment setCategories:[self categories]];
+  [_appointment setAccessClass: [self privacy]];
+  [_appointment setStatus: [self status]];
 
-  [_appointment setAccessClass:[self accessClass]];
-  [_appointment setTransparency:[self transparency]];
+//   [_appointment setCategories: [[self categories] componentsJoinedByString: @","]];
+
+  [_appointment setTransparency: [self transparency]];
 
 #if 0
   /*
     Note: bad, bad, bad!
     Organizer is no form value, thus we MUST NOT change it
   */
-  [_appointment setOrganizer:self->organizer];
+  [_appointment setOrganizer:organizer];
 #endif
   attendees  = [self participants];
   lResources = [self resources];
   if ([lResources count] > 0) {
     attendees = ([attendees count] > 0)
-      ? [attendees arrayByAddingObjectsFromArray:lResources]
+      ? [attendees arrayByAddingObjectsFromArray: lResources]
       : lResources;
   }
-  [_appointment setAttendees:attendees];
+  [attendees makeObjectsPerformSelector: @selector (setTag:)
+             withObject: @"attendee"];
+  [_appointment setAttendees: attendees];
 
   /* cycles */
-  [_appointment setRecurrenceRule:[self rrule]];
-}
-
-- (void)loadValuesFromICalString:(NSString *)_ical {
-  SOGoAppointment *apt;
-
-  apt = [[SOGoAppointment alloc] initWithICalString:_ical];
-  [self loadValuesFromAppointment:apt];
-  [apt release];
+  [_appointment removeAllRecurrenceRules];
+  rrule = [self rrule];
+  if (rrule)
+    [_appointment addToRecurrenceRules: rrule];
 }
 
-/* contact editor compatibility */
-
-- (void)setContentString:(NSString *)_s {
-  [self setICalString:_s];
-}
-- (NSString *)contentStringTemplate {
-  return [self iCalStringTemplate];
-}
-
-- (void)loadValuesFromContentString:(NSString *)_s {
-  [self loadValuesFromICalString:_s];
-}
-
-
-/* access */
-
-- (BOOL)isMyApt {
-  if (self->organizer == nil)
-    return YES; // assume this is safe to do, right?
-  
-  // TODO: this should check a set of emails against the SoUser
-  return [[self->organizer rfc822Email] isEqualToString:[self emailForUser]];
-}
+- (iCalEvent *) appointmentFromString: (NSString *) _iCalString
+{
+  iCalCalendar *calendar;
+  iCalEvent *appointment;
+  SOGoAppointmentObject *clientObject;
 
-- (BOOL)canAccessApt {
-  return [self isMyApt];
-}
+  clientObject = [self clientObject];
+  calendar = [iCalCalendar parseSingleFromSource: _iCalString];
+  appointment = [clientObject firstEventFromCalendar: calendar];
 
-- (BOOL)canEditApt {
-  return [self isMyApt];
+  return appointment;
 }
 
-
 /* conflict management */
 
-- (BOOL)containsConflict:(SOGoAppointment *)_apt {
-  NSArray               *attendees, *uids;
+- (BOOL) containsConflict: (id) _apt
+{
+  NSArray *attendees, *uids;
   SOGoAppointmentFolder *groupCalendar;
-  NSArray               *infos;
-  NSArray               *ranges;
-  id                    folder;
+  NSArray *infos;
+  NSArray *ranges;
+  id folder;
 
   [self logWithFormat:@"search from %@ to %@", 
          [_apt startDate], [_apt endDate]];
                           inContext:[self context]];
   [self debugWithFormat:@"group calendar: %@", groupCalendar];
   
-  if (![groupCalendar respondsToSelector:@selector(fetchFreebusyInfosFrom:to:)]) {
+  if (![groupCalendar respondsToSelector:@selector(fetchFreeBusyInfosFrom:to:)]) {
     [self errorWithFormat:@"invalid folder to run freebusy query on!"];
     return NO;
   }
 
-  infos = [groupCalendar fetchFreebusyInfosFrom:[_apt startDate]
+  infos = [groupCalendar fetchFreeBusyInfosFrom:[_apt startDate]
                          to:[_apt endDate]];
   [self debugWithFormat:@"  process: %d events", [infos count]];
 
-  ranges = [infos arrayByCreatingDateRangesFromObjectsWithStartDateKey:@"startDate"
-                  andEndDateKey:@"endDate"];
+  ranges = [infos arrayByCreatingDateRangesFromObjectsWithStartDateKey: @"startDate"
+                  andEndDateKey: @"endDate"];
   ranges = [ranges arrayByCompactingContainedDateRanges];
   [self debugWithFormat:@"  blocked ranges: %@", ranges];
 
   return [ranges count] != 0 ? YES : NO;
 }
 
-/* response generation */
-
-- (NSString *)jsCode {
-  static NSString *script = \
-  @"function showElement(e, show) {\n"
-  @"   e.style.visibility = show ? 'visible' : 'hidden';\n"
-  @"}\n"
-  @"\n"
-  @"function selectHasCycle(sender) {\n"
-  @"  var value = sender.selectedIndex;\n"
-  @"  var show  = (value != 0);\n"
-  @"  var sel   = document.getElementById('cycle_end_mode_selection');"
-  @"  this.showElement(document.getElementById('cycle_end_label'), show);\n"
-  @"  this.showElement(document.getElementById('cycle_end_mode'),  show);\n"
-  @"  this.selectCycleEnd(sel);\n"
-  @"}\n"
-  @"function selectCycleEnd(sender) {\n"
-  @"  var cycleEndUntil = document.getElementById('cycle_end_until');\n"
-  @"  var value = sender.options[sender.selectedIndex].value;\n"
-  @"  var show  = (value == 'cycle_end_until');\n"
-  @"  this.showElement(cycleEndUntil, show);\n"
-  @"}\n"
-  @"\n";
-
-  return script;
-}
-
-- (NSString *)initialCycleVisibility {
-  if (![self hasCycle])
-    return @"visibility: hidden;";
-  return @"visibility: visible;";
-}
-
-- (NSString *)initialCycleEndUntilVisibility {
-  if ([self isCycleEndUntil])
-    return @"visibility: visible;";
-  return @"visibility: hidden;";
-}
-
-
 /* actions */
 
-- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
-  return YES;
-}
-
-- (id)testAction {
+- (id) testAction
+{
   /* for testing only */
-  WORequest       *req;
-  SOGoAppointment *apt;
-  NSString        *content;
+  WORequest *req;
+  iCalEvent *apt;
+  NSString *content;
 
   req = [[self context] request];
-  apt = [[SOGoAppointment alloc] initWithICalString:[self iCalString]];
+  apt = [self appointmentFromString: [self iCalString]];
   [self saveValuesIntoAppointment:apt];
-  content = [apt iCalString];
+  content = [[apt parent] versitString];
   [self logWithFormat:@"%s -- iCal:\n%@",
     __PRETTY_FUNCTION__,
     content];
-  [apt release];
+
   return self;
 }
 
-- (id<WOActionResults>)defaultAction {
+- (id<WOActionResults>) defaultAction
+{
   NSString *ical;
   
   /* load iCalendar file */
   
   // TODO: can't we use [clientObject contentAsString]?
-  ical = [[self clientObject] valueForKey:@"iCalString"];
+//   ical = [[self clientObject] valueForKey:@"iCalString"];
+  ical = [[self clientObject] contentAsString];
   if ([ical length] == 0) /* a new appointment */
-    ical = [self contentStringTemplate];
-  
-  [self setContentString:ical];
-  [self loadValuesFromContentString:ical];
-  
-  if (![self canEditApt]) {
-    /* TODO: we need proper ACLs */
-    return [self redirectToLocation:[self _completeURIForMethod:@"../view"]];
-  }
+    ical = [self iCalStringTemplate];
+
+  [self setICalString:ical];
+  [self loadValuesFromAppointment: [self appointmentFromString: ical]];
+
+//   if (![self canEditComponent]) {
+//     /* TODO: we need proper ACLs */
+//     return [self redirectToLocation: [self completeURIForMethod: @"../view"]];
+//   }
   return self;
 }
 
-- (id)saveAction {
-  SOGoAppointment *apt;
-  iCalPerson      *p;
-  NSString        *content;
-  NSException     *ex;
-  
+- (id <WOActionResults>) saveAction
+{
+  iCalEvent *apt;
+  iCalPerson *p;
+  id <WOActionResults> result;
+  NSString *content;
+  NSException *ex;
+
   if (![self isWriteableClientObject]) {
     /* return 400 == Bad Request */
     return [NSException exceptionWithHTTPStatus:400
                                @"the specified object"];
   }
   
-  apt = [[SOGoAppointment alloc] initWithICalString:[self iCalString]];
+  apt = [self appointmentFromString: [self iCalString]];
   if (apt == nil) {
     NSString *s;
     
       
       s = [self labelForKey:@"Conflicts found!"];
       [self setErrorText:s];
-      [apt release];
+
       return self;
     }
   }
-  content = [apt iCalString];
-  [apt release]; apt = nil;
+  content = [[apt parent] versitString];
+//   [apt release]; apt = nil;
   
   if (content == nil) {
     NSString *s;
     return self;
   }
   
-  return [self redirectToLocation:[self _completeURIForMethod:@".."]];
+  if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
+    result = [self redirectToLocation: [self applicationPath]];
+  else
+    result = [self jsCloseWithRefreshMethod: @"refreshAppointmentsAndDisplay()"];
+
+  return result;
 }
 
-- (id)acceptAction {
+- (NSString *) saveUrl
+{
+  return [NSString stringWithFormat: @"%@/saveAsAppointment",
+                   [[self clientObject] baseURL]];
+}
+
+- (id) acceptAction
+{
   return [self acceptOrDeclineAction:YES];
 }
 
-- (id)declineAction {
+- (id) declineAction
+{
   return [self acceptOrDeclineAction:NO];
 }
 
 // TODO: add tentatively
 
-- (id)acceptOrDeclineAction:(BOOL)_accept {
+- (id) acceptOrDeclineAction: (BOOL) _accept
+{
   // TODO: this should live in the SoObjects
   NSException *ex;
 
                               _accept ? @"ACCEPTED" : @"DECLINED"
                             inContext:[self context]];
   if (ex != nil) return ex;
-  
-  return [self redirectToLocation:[self _completeURIForMethod:@"../view"]];
+
+  return self;  
+//   return [self redirectToLocation: [self completeURIForMethod: @"../view"]];
 }
 
 @end /* UIxAppointmentEditor */
diff --git a/UI/Scheduler/UIxAppointmentPrintview.m b/UI/Scheduler/UIxAppointmentPrintview.m
deleted file mode 100644 (file)
index 88ebcad..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include "UIxAppointmentView.h"
-
-@interface UIxAppointmentPrintview : UIxAppointmentView
-{
-}
-
-- (BOOL)isMyApt;
-
-@end
-
-#include "common.h"
-#include <SOGoUI/SOGoDateFormatter.h>
-#include <SOGo/SOGoAppointment.h>
-#include "UIxComponent+Agenor.h"
-
-@implementation UIxAppointmentPrintview
-
-- (NSString *)title {
-  return [[self dateFormatter] stringForObjectValue:[self startTime]];
-}
-
-- (BOOL)isMyApt {
-  id       apt;
-  NSString *myEmail;
-
-  apt     = [self appointment];
-  myEmail = [self emailForUser];
-#if 0 /* ZNeK 20041208 - Maxime says this isn't relevant to agenor */
-  if ([apt isOrganizer:myEmail])
-    return YES;
-#endif
-  return [apt isParticipant:myEmail];
-}
-
-- (NSString *)aptStyle {
-  if (![self isMyApt])
-    return @"aptprintview_apt_other";
-  return nil;
-}
-
-@end /* UIxAppointmentPrintview */
index d540e2ff5bae8a2b9d5fe00729d571ac11cff996..978a031462a4a76ebd24660a2df94596fd8b637a 100644 (file)
@@ -57,7 +57,7 @@
 #include <SoObjects/Appointments/SOGoAppointmentFolder.h>
 #include <SoObjects/Appointments/SOGoFreeBusyObject.h>
 #include <NGExtensions/NGCalendarDateRange.h>
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
 #include "common.h"
 
 @implementation UIxAppointmentProposal
                         hour:[[self startDateHour] intValue]
                         minute:[[self startDateMinute] intValue]
                         second:0
-                        timeZone:[self viewTimeZone]];
+                        timeZone:[[self clientObject] userTimeZone]];
 }
 - (void)setEndDate:(NSCalendarDate *)_date {
   [self setEndDateHour:[NSNumber numberWithInt:[_date hourOfDay]]];
                         hour:[[self endDateHour] intValue]
                         minute:[[self endDateMinute] intValue]
                         second:59
-                        timeZone:[self viewTimeZone]];
+                        timeZone:[[self clientObject] userTimeZone]];
 }
 
 - (void)setDuration:(id)_duration {
                         month:[[self startDateMonth] intValue]
                         day:[[self startDateDay] intValue]
                         hour:12 minute:0 second:0
-                        timeZone:[self viewTimeZone]];
+                        timeZone:[[self clientObject] userTimeZone]];
   stop = [NSCalendarDate dateWithYear:[[self endDateYear] intValue]
                         month:[[self endDateMonth] intValue]
                         day:[[self endDateDay] intValue]
                         hour:12 minute:0 second:0
-                        timeZone:[self viewTimeZone]];
+                        timeZone:[[self clientObject] userTimeZone]];
   
   ma = [NSMutableArray arrayWithCapacity:16];
   
   current = base;
   while ([current compare:stop] != NSOrderedDescending) {
-    [current setTimeZone:[self viewTimeZone]];
+    [current setTimeZone:[[self clientObject] userTimeZone]];
     [ma addObject:current];
     
     /* Note: remember the timezone behaviour of the method below! */
   aptEndDate   = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
                                           [aptStartDate timeIntervalSince1970]
                                         + [self durationAsTimeInterval]];
-  [aptStartDate setTimeZone:[self viewTimeZone]];
-  [aptEndDate   setTimeZone:[self viewTimeZone]];
+  [aptStartDate setTimeZone:[[self clientObject] userTimeZone]];
+  [aptEndDate   setTimeZone:[[self clientObject] userTimeZone]];
   aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate:aptStartDate
                                  endDate:aptEndDate];
   [aptEndDate release]; aptEndDate = nil;
     
     fb    = [fbos objectAtIndex:i];
     if (fb != (SOGoFreeBusyObject *)[NSNull null]) {
-      infos = [fb fetchFreebusyInfosFrom:[self startDate] to:[self endDate]];
+      infos = [fb fetchFreeBusyInfosFrom:[self startDate] to:[self endDate]];
       [allInfos addObjectsFromArray:infos];
     }
   }
index 712a8c948c7a757a5e37560c6da9a10c357cc034..306e0640653cca5a9c97b6f55f33a7b541cf685b 100644 (file)
@@ -6,18 +6,19 @@
 #include <SOGoUI/UIxComponent.h>
 
 @class NSCalendarDate;
-@class SOGoAppointment;
+@class iCalEvent;
+@class iCalPerson;
 @class SOGoDateFormatter;
 
 @interface UIxAppointmentView : UIxComponent
 {
-  id appointment;
-  id attendee;
+  iCalEvent* appointment;
+  iCalPerson* attendee;
   SOGoDateFormatter *dateFormatter;
   id item;
 }
 
-- (SOGoAppointment *)appointment;
+- (iCalEvent *)appointment;
 
 /* permissions */
 - (BOOL)canAccessApt;
index b8c5730f55c25c68410ea9b31f489fb292482c26..cb4562abc09d27bee4896162ad8d2278f72883ca 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxAppointmentView.h"
-#include <NGiCal/NGiCal.h>
-#include <SOGo/SOGoAppointment.h>
-#include <SOGo/WOContext+Agenor.h>
-#include <Appointments/SOGoAppointmentObject.h>
-#include <SOGoUI/SOGoDateFormatter.h>
-#include "UIxComponent+Agenor.h"
-#include "common.h"
+#import "UIxAppointmentView.h"
+#import <NGCards/NGCards.h>
+#import <SOGo/WOContext+Agenor.h>
+#import <Appointments/SOGoAppointmentObject.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+#import "UIxComponent+Agenor.h"
+#import "common.h"
 
 @interface UIxAppointmentView (PrivateAPI)
 - (BOOL)isAttendeeActiveUser;
 @implementation UIxAppointmentView
 
 - (void)dealloc {
-  [self->appointment   release];
-  [self->attendee      release];
-  [self->dateFormatter release];
-  [self->item          release];
+  [appointment   release];
+  [attendee      release];
+  [dateFormatter release];
+  [item          release];
   [super dealloc];
 }
 
 }
 
 - (void)setAttendee:(id)_attendee {
-  ASSIGN(self->attendee, _attendee);
+  ASSIGN(attendee, _attendee);
 }
 - (id)attendee {
-  return self->attendee;
+  return attendee;
 }
 
 - (BOOL)isAttendeeActiveUser {
   NSString *email, *attEmail;
-  
+
   email    = [[[self context] activeUser] email];
-  attEmail = [[self attendee] rfc822Email];
-  return [email isEqualToString:attEmail];
+  attendee = [self attendee];
+  attEmail = [attendee rfc822Email];
+
+  return [email isEqualToString: attEmail];
 }
+
 - (BOOL)showAcceptButton {
   return [[self attendee] participationStatus] != iCalPersonPartStatAccepted;
 }
 }
 
 - (void)setItem:(id)_item {
-  ASSIGN(self->item, _item);
+  ASSIGN(item, _item);
 }
 - (id)item {
-  return self->item;
+  return item;
 }
 
 - (SOGoDateFormatter *)dateFormatter {
-  if (self->dateFormatter == nil) {
-    self->dateFormatter =
+  if (dateFormatter == nil) {
+    dateFormatter =
       [[SOGoDateFormatter alloc] initWithLocale:[self locale]];
-    [self->dateFormatter setFullWeekdayNameAndDetails];
+    [dateFormatter setFullWeekdayNameAndDetails];
   }
-  return self->dateFormatter;
+  return dateFormatter;
 }
 
 - (NSCalendarDate *)startTime {
   NSCalendarDate *date;
     
   date = [[self appointment] startDate];
-  [date setTimeZone:[self viewTimeZone]];
+  [date setTimeZone:[[self clientObject] userTimeZone]];
   return date;
 }
 
   NSCalendarDate *date;
   
   date = [[self appointment] endDate];
-  [date setTimeZone:[self viewTimeZone]];
+  [date setTimeZone:[[self clientObject] userTimeZone]];
   return date;
 }
 
   return [cns componentsJoinedByString:@"<br />"];
 }
 
-- (NSString *)categoriesAsString {
-  unsigned i, count;
-  NSArray *cats;
-  NSMutableString *s;
-  
-  s = [NSMutableString stringWithCapacity:32];
-  cats = [((SOGoAppointment *)self->appointment) categories];
-  count = [cats count];
-  for(i = 0; i < count; i++) {
-    NSString *cat, *label;
-
-    cat = [cats objectAtIndex:i];
-    label = [self labelForKey:cat];
-    [s appendString:label];
-    if(i != (count - 1))
-      [s appendString:@", "];
-  }
-  return s;
+- (NSString *) categoriesAsString
+{
+  NSEnumerator *categories;
+  NSArray *rawCategories;
+  NSMutableArray *l10nCategories;
+  NSString *currentCategory, *l10nCategory;
+
+  rawCategories
+    = [[appointment categories] componentsSeparatedByString: @","];
+  l10nCategories = [NSMutableArray arrayWithCapacity: [rawCategories count]];
+  categories = [rawCategories objectEnumerator];
+  currentCategory = [categories nextObject];
+  while (currentCategory)
+    {
+      l10nCategory
+        = [self labelForKey: [currentCategory stringByTrimmingSpaces]];
+      if (l10nCategory)
+        [l10nCategories addObject: l10nCategory];
+      currentCategory = [categories nextObject];
+    }
+
+  return [l10nCategories componentsJoinedByString: @", "];
+}
+
+// appointment.organizer.cnForDisplay
+- (NSString *) eventOrganizer
+{
+  CardElement *organizer;
+
+  organizer = [[self appointment] uniqueChildWithTag: @"organizer"];
+
+  return [organizer value: 0 ofAttribute: @"cn"];
+}
+
+- (NSString *) priorityLabelKey
+{
+  return [NSString stringWithFormat: @"prio_%@", [appointment priority]];
 }
 
 /* backend */
 
-- (SOGoAppointment *)appointment {
+- (iCalEvent *) appointment
+{
   NSString *iCalString;
+  iCalCalendar *calendar;
+  SOGoAppointmentObject *clientObject;
     
-  if (self->appointment != nil)
-    return self->appointment;
-    
+  if (appointment != nil)
+    return appointment;
+
+  clientObject = [self clientObject];
+
   iCalString = [[self clientObject] valueForKey:@"iCalString"];
   if (![iCalString isNotNull] || [iCalString length] == 0) {
     [self errorWithFormat:@"(%s): missing iCal string!", 
             __PRETTY_FUNCTION__];
     return nil;
   }
-    
-  self->appointment = [[SOGoAppointment alloc] initWithICalString:iCalString];
-  return self->appointment;
-}
 
+  calendar = [iCalCalendar parseSingleFromSource: iCalString];
+  appointment = [clientObject firstEventFromCalendar: calendar];
+  [appointment retain];
+
+  return appointment;
+}
 
 /* hrefs */
 
     return YES;
   
   /* not my apt - can access if it's public */
-  if ([[self appointment] isPublic])
+  if ([[[self appointment] accessClass] isEqualToString: @"PUBLIC"])
     return YES;
 
   /* can access it if I'm invited :-) */
diff --git a/UI/Scheduler/UIxCalAptListView.h b/UI/Scheduler/UIxCalAptListView.h
new file mode 100644 (file)
index 0000000..b220523
--- /dev/null
@@ -0,0 +1,43 @@
+/* UIxCalAptListView.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCALAPTLISTVIEW_H
+#define UIXCALAPTLISTVIEW_H
+
+#import "UIxCalView.h"
+
+@class NSDictionary;
+
+@interface UIxCalAptListView : UIxCalView
+{
+  NSCalendarDate *startDate;
+  NSCalendarDate *endDate;
+
+  NSDictionary *currentAppointment;
+}
+
+- (void) setCurrentAppointment: (NSDictionary *) apt;
+- (NSDictionary *) currentAppointment;
+
+@end
+
+#endif /* UIXCALAPTLIST_H */
diff --git a/UI/Scheduler/UIxCalAptListView.m b/UI/Scheduler/UIxCalAptListView.m
new file mode 100644 (file)
index 0000000..5da22d5
--- /dev/null
@@ -0,0 +1,183 @@
+/* UIxCalAptListView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSDate.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+
+#import <NGExtensions/NSCalendarDate+misc.h>
+#import <Appointments/SOGoAppointmentFolder.h>
+
+#import <SOGoUI/SOGoDateFormatter.h>
+
+#import "UIxCalAptListView.h"
+
+@implementation UIxCalAptListView
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      startDate = nil;
+      endDate = nil;
+    }
+
+  return self;
+}
+
+- (void) setCurrentAppointment: (NSDictionary *) apt
+{
+  currentAppointment = apt;
+}
+
+- (NSDictionary *) currentAppointment
+{
+  return currentAppointment;
+}
+
+- (NSCalendarDate *) startDate
+{
+  NSCalendarDate *today;
+  NSString *filterPopup;
+
+  if (!startDate)
+    {
+      filterPopup = [self queryParameterForKey: @"filterpopup"];
+      today = [[NSCalendarDate date] beginOfDay];
+      if (!filterPopup || ![filterPopup length])
+        startDate = today;
+      else if ([filterPopup isEqualToString: @"view_selectedday"])
+        startDate = [[self selectedDate] beginOfDay];
+      else if ([filterPopup isEqualToString: @"view_thismonth"])
+        startDate = [today firstDayOfMonth];
+      else if ([filterPopup isEqualToString: @"view_all"])
+        startDate = [NSCalendarDate dateWithTimeIntervalSince1970: 0];
+      else
+        startDate = today;
+    }
+
+  return startDate;
+}
+
+- (NSCalendarDate *) endDate
+{
+  NSCalendarDate *today;
+  NSString *filterPopup;
+
+  if (!endDate)
+    {
+      filterPopup = [self queryParameterForKey: @"filterpopup"];
+
+      today = [[NSCalendarDate date] endOfDay];
+      if (!filterPopup || ![filterPopup length]
+          || [filterPopup isEqualToString: @"view_today"])
+        endDate = today;
+      else if ([filterPopup isEqualToString: @"view_all"]
+               || [filterPopup isEqualToString: @"view_future"])
+        endDate = [NSCalendarDate dateWithTimeIntervalSince1970: 0x7fffffff];
+      else if ([filterPopup isEqualToString: @"view_thismonth"])
+        endDate = [today lastDayOfMonth];
+      else if ([filterPopup isEqualToString: @"view_selectedday"])
+        endDate = [[self selectedDate] endOfDay];
+      else if ([filterPopup isEqualToString: @"view_next7"])
+        endDate = [today dateByAddingYears: 0 months: 0 days: 7];
+      else if ([filterPopup isEqualToString: @"view_next14"])
+        endDate = [today dateByAddingYears: 0 months: 0 days: 14];
+      else if ([filterPopup isEqualToString: @"view_next31"])
+        endDate = [today dateByAddingYears: 0 months: 1 days: 0];
+      else
+        endDate = today;
+    }
+
+  return endDate;
+}
+
+- (SOGoDateFormatter *) itemDateFormatter
+{
+  SOGoDateFormatter *fmt;
+  
+  fmt = [[SOGoDateFormatter alloc] initWithLocale: [self locale]];
+  [fmt autorelease];
+  [fmt setFullWeekdayNameAndDetails];
+
+  return fmt;
+}
+
+- (NSString *) currentStartTime
+{
+  NSCalendarDate *date;
+
+  date = [NSCalendarDate dateWithTimeIntervalSince1970:
+                           [[currentAppointment objectForKey: @"startdate"]
+                             intValue]];
+  [date setTimeZone: [[self clientObject] userTimeZone]];
+
+  return [[self itemDateFormatter] stringForObjectValue: date];
+}
+
+- (NSString *) currentEndTime
+{
+  NSCalendarDate *date;
+
+  date = [NSCalendarDate dateWithTimeIntervalSince1970:
+                           [[currentAppointment objectForKey: @"enddate"]
+                             intValue]];
+  [date setTimeZone: [[self clientObject] userTimeZone]];
+
+  return [[self itemDateFormatter] stringForObjectValue: date];
+}
+
+- (NSString *) currentLocation
+{
+  return [currentAppointment objectForKey: @"location"];
+}
+
+- (NSString *) currentSerialDay
+{
+  NSCalendarDate *date;
+  int intDate;
+
+  intDate = [[currentAppointment objectForKey: @"startdate"] intValue];
+  date = [NSCalendarDate dateWithTimeIntervalSince1970: intDate];
+  [date setTimeZone: [[self clientObject] userTimeZone]];
+
+  return [NSString stringWithFormat: @"%d%.2d%.2d",
+                   [date yearOfCommonEra],
+                   [date monthOfYear],
+                   [date dayOfMonth]];
+}
+
+- (NSString *) currentSerialHour
+{
+  NSCalendarDate *date;
+  int intDate;
+
+  intDate = [[currentAppointment objectForKey: @"startdate"] intValue];
+  date = [NSCalendarDate dateWithTimeIntervalSince1970: intDate];
+  [date setTimeZone: [[self clientObject] userTimeZone]];
+
+  return [NSString stringWithFormat: @"%.2d%.2d",
+                   [date hourOfDay],
+                   [date minuteOfHour]];
+}
+
+@end
diff --git a/UI/Scheduler/UIxCalCalendarsListView.h b/UI/Scheduler/UIxCalCalendarsListView.h
new file mode 100644 (file)
index 0000000..e3ed293
--- /dev/null
@@ -0,0 +1,42 @@
+/* UIxCalCalendarsListView.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCALCALENDARSLISTVIEW_H
+#define UIXCALCALENDARSLISTVIEW_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSMutableArray;
+@class NSMutableDictionary;
+@class iCalPerson;
+
+@interface UIxCalCalendarsListView : UIxComponent
+{
+  NSMutableArray *checkedContacts;
+  NSMutableArray *contacts;
+  NSMutableDictionary *colors;
+  iCalPerson *currentContactPerson;
+}
+
+@end
+
+#endif /* UIXCALCALENDARSLISTVIEW_H */
diff --git a/UI/Scheduler/UIxCalCalendarsListView.m b/UI/Scheduler/UIxCalCalendarsListView.m
new file mode 100644 (file)
index 0000000..c84369b
--- /dev/null
@@ -0,0 +1,217 @@
+/* UIxCalCalendarsListView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSUserDefaults.h>
+
+#import <SOGo/AgenorUserManager.h>
+#import <SOGo/SOGoUser.h>
+
+#import "UIxCalCalendarsListView.h"
+
+static inline char
+darkenedColor (const char value)
+{
+  char newValue;
+
+  if (value >= '0' && value <= '9')
+    newValue = ((value - '0') / 2) + '0';
+  else if (value >= 'a' && value <= 'f')
+    newValue = ((value + 10 - 'a') / 2) + '0';
+  else if (value >= 'A' && value <= 'F')
+    newValue = ((value + 10 - 'A') / 2) + '0';
+  else
+    newValue = value;
+
+  return newValue;
+}
+
+@implementation UIxCalCalendarsListView
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      contacts = nil;
+      checkedContacts = nil;
+      currentContactPerson = nil;
+      colors = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (currentContactPerson)
+    [currentContactPerson release];
+  if (contacts)
+    [contacts release];
+  if (checkedContacts)
+    [checkedContacts release];
+  if (colors)
+    [colors release];
+  [super dealloc];
+}
+
+- (NSString *) _colorForNumber: (unsigned int) number
+{
+  unsigned int index, currentValue;
+  unsigned char colorTable[] = { 1, 1, 1 };
+  NSString *color;
+
+  if (number == 0)
+    color = @"#ccf";
+  else if (number == NSNotFound)
+    color = @"#f00";
+  else
+    {
+      currentValue = number;
+      index = 0;
+      while (currentValue)
+        {
+          if (currentValue & 1)
+            colorTable[index]++;
+          if (index == 3)
+            index = 0;
+          currentValue >>= 1;
+          index++;
+        }
+      color = [NSString stringWithFormat: @"#%2x%2x%2x",
+                        (255 / colorTable[2]) - 1,
+                        (255 / colorTable[1]) - 1,
+                        (255 / colorTable[0]) - 1];
+    }
+
+  NSLog(@"color = '%@'", color);
+
+  return color;
+}
+
+- (void) _addContactId: (NSString *) contactId
+                withUm: (AgenorUserManager *) um
+             andNumber: (unsigned int) count
+{
+  NSString *contactRealId;
+  iCalPerson *currentContact;
+
+  if ([contactId hasPrefix: @"-"])
+    contactRealId = [contactId substringFromIndex: 1];
+  else
+    contactRealId = contactId;
+
+  currentContact = [um iCalPersonWithUid: contactRealId];
+  [contacts addObject: currentContact];
+  if (contactId == contactRealId)
+    [checkedContacts addObject: currentContact];
+  [colors setObject: [self _colorForNumber: count]
+          forKey: contactRealId];
+}
+
+- (void) _setupContacts
+{
+  SOGoUser *user;
+  NSString *list, *currentId;
+  NSEnumerator *rawContacts;
+  AgenorUserManager *um;
+  unsigned int count;
+
+  contacts = [NSMutableArray new];
+  checkedContacts = [NSMutableArray new];
+  colors = [NSMutableDictionary new];
+
+  um = [AgenorUserManager sharedUserManager];
+  user = [context activeUser];
+  list = [[user userDefaults] stringForKey: @"calendaruids"];
+  if ([list length] == 0)
+    list = [self shortUserNameForDisplay];
+
+  rawContacts
+    = [[list componentsSeparatedByString: @","] objectEnumerator];
+  currentId = [rawContacts nextObject];
+  count = 0;
+  while (currentId)
+    {
+      [self _addContactId: currentId withUm: um andNumber: count];
+      currentId = [rawContacts nextObject];
+      count++;
+    }
+}
+
+- (NSArray *) contacts
+{
+  if (!contacts)
+    [self _setupContacts];
+
+  return contacts;
+}
+
+- (NSArray *) checkedContacts
+{
+  if (!checkedContacts)
+    [self _setupContacts];
+
+  return checkedContacts;
+}
+
+- (void) setCurrentContactPerson: (iCalPerson *) contact
+{
+  if (currentContactPerson)
+    [currentContactPerson release];
+  currentContactPerson = contact;
+  if (currentContactPerson)
+    [currentContactPerson retain];
+}
+
+- (NSString *) currentContactLogin
+{
+  return [currentContactPerson cn];
+}
+
+- (NSString *) currentContactSpanBG
+{
+  return [colors objectForKey: [currentContactPerson cn]];
+}
+
+- (NSString *) currentContactAptBorder
+{
+  NSString *spanBG;
+  char cColor[8];
+  unsigned int count;
+
+  spanBG = [colors objectForKey: [currentContactPerson cn]];
+  [spanBG getCString: cColor];
+  cColor[7] = 0;
+  for (count = 1; count < 7; count++)
+    cColor[count] = darkenedColor(cColor[count]);
+
+  return [NSString stringWithCString: cColor];
+}
+
+- (NSDictionary *) colors
+{
+  return colors;
+}
+
+@end
index 234d62d47efb001b15c9dacaa59e8a13727ffb40..3160607baa6ae2693146f08e48b01c465c6f0bd2 100644 (file)
@@ -37,7 +37,7 @@
 @end
 
 #include "common.h"
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
 
 @implementation UIxCalDateLabel
 
 }
 
 - (NSString *)weekLabel {
-  NSString *label;
+  NSString *label, *le;
   
-  label = [self localizedNameForMonthOfYear:[self->startDate monthOfYear]];
-  label = [NSString stringWithFormat:@"%@ %d",
-                   label,
-                   [self->startDate yearOfCommonEra]];
-  if ([self->startDate monthOfYear] != [self->endDate monthOfYear]) {
-    NSString *le;
-    
-    le = [self localizedNameForMonthOfYear:[self->endDate monthOfYear]];
-    label = [NSString stringWithFormat:@"<nobr>%@ / %@ %d</nobr>",
-                     label, le,
-                     [self->endDate yearOfCommonEra]];
-  }
+  if ([self->startDate monthOfYear] == [self->endDate monthOfYear])
+    label = [NSString stringWithFormat:@"%@ %d",
+                      [self localizedNameForMonthOfYear: [self->startDate monthOfYear]],
+                      [self->startDate yearOfCommonEra]];
+  else
+    {
+      le = [self localizedNameForMonthOfYear:[self->endDate monthOfYear]];
+      label = [NSString stringWithFormat:@"<nobr>%@ / %@ %d</nobr>",
+                        label, le,
+                        [self->endDate yearOfCommonEra]];
+    }
+
   return label;
 }
 
diff --git a/UI/Scheduler/UIxCalDateSelector.h b/UI/Scheduler/UIxCalDateSelector.h
new file mode 100644 (file)
index 0000000..113d267
--- /dev/null
@@ -0,0 +1,47 @@
+/* UIxCalDateSelector.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCALDATESELECTOR_H
+#define UIXCALDATESELECTOR_H
+
+#include "UIxCalMonthOverview.h"
+
+@interface UIxCalDateSelector : UIxCalMonthOverview
+{
+  NSCalendarDate *selectedDate;
+  NSString *style;
+  NSString *headerStyle;
+  NSString *weekStyle;
+  NSString *todayWeekStyle;
+  NSString *dayHeaderStyle;
+  NSString *dayBodyStyle;
+  NSString *todayBodyStyle;
+  NSString *inactiveDayBodyStyle;
+  NSString *selectedDayExtraStyle;
+  NSString *daySelectionHref;
+  NSString *weekSelectionHref;
+  NSString *monthSelectionHref;
+}
+
+@end
+
+#endif /* UIXCALDATESELECTOR_H */
diff --git a/UI/Scheduler/UIxCalDateSelector.m b/UI/Scheduler/UIxCalDateSelector.m
new file mode 100644 (file)
index 0000000..6ab548c
--- /dev/null
@@ -0,0 +1,173 @@
+/* UIxCalDateSelector.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <NGExtensions/NSCalendarDate+misc.h>
+
+#import <SOGo/NSCalendarDate+SOGo.h>
+
+#import "UIxCalDateSelector.h"
+
+@implementation UIxCalDateSelector
+
+/* binding accessors */
+
+- (void) setSelectedDate: (NSCalendarDate *) _date
+{
+  ASSIGN (selectedDate, _date);
+  [selectedDate setTimeZone: [[self clientObject] userTimeZone]];
+}
+
+- (NSCalendarDate *) selectedDate
+{
+  if (!selectedDate)
+    selectedDate = [super selectedDate];
+
+  return selectedDate;
+}
+
+- (NSString *) style
+{
+  return style;
+}
+
+- (NSString *) headerStyle
+{
+  return headerStyle;
+}
+
+- (NSString *) weekStyle
+{
+  return weekStyle;
+}
+
+- (void) setTodayWeekStyle: (NSString *) _style
+{
+  ASSIGN (todayWeekStyle, _style);
+}
+
+- (NSString *) todayWeekStyle
+{
+  return ((todayWeekStyle)
+          ? todayWeekStyle
+          : [self weekStyle]);
+}
+
+- (NSString *) dayHeaderStyle
+{
+  return dayHeaderStyle;
+}
+
+- (void) setSelectedDayExtraStyle: (NSString *) _style
+{
+  ASSIGN(selectedDayExtraStyle, _style);
+}
+
+- (NSString *) selectedDayExtraStyle
+{
+  return selectedDayExtraStyle;
+}
+
+/* date ranges */
+
+- (NSCalendarDate *) startDate
+{
+  return [[self selectedDate] firstDayOfMonth];
+}
+
+/* labels */
+
+- (NSString *) headerMonthValue
+{
+  NSCalendarDate *date;
+
+  date = [self startDate];
+
+  return [NSString stringWithFormat: @"%.2d", [date monthOfYear]];
+}
+
+- (NSString *) headerMonthString
+{
+  NSCalendarDate *date;
+
+  date = [self startDate];
+
+  return [NSString stringWithFormat:@"%@",
+                   [self localizedNameForMonthOfYear: [date monthOfYear]]];
+}
+
+- (NSString *) headerYearString
+{
+  NSCalendarDate *date;
+
+  date = [self startDate];
+
+  return [NSString stringWithFormat: @"%d", [date yearOfCommonEra]];
+}
+
+- (NSString *) localizedDayOfWeekName
+{
+  return [self localizedAbbreviatedNameForDayOfWeek: [self dayOfWeek]];
+}
+
+
+/* stylesheets */
+
+- (NSString *) currentWeekStyle
+{
+  return (([currentWeekStart isDateInSameWeek:[NSCalendarDate date]] &&
+           [currentWeekStart isDateInSameMonth:[self selectedDate]])
+          ? [self todayWeekStyle]
+          : [self weekStyle]);
+}
+
+- (NSString *) contentStyle
+{
+  return (([currentDay isToday]
+           && [currentDay isDateInSameMonth:[self selectedDate]])
+          ? @"dayOfToday"
+          : (([currentDay monthOfYear] != [[self startDate] monthOfYear])
+             ? @"inactiveDay"
+             :  @"activeDay"));
+}
+
+- (NSString *) extraStyle
+{
+  return (([[self selectedDate] isDateOnSameDay: currentDay])
+          ? [self selectedDayExtraStyle]
+          : nil);
+}
+
+/* URLs */
+
+- (NSDictionary *) currentMonthQueryParameters
+{
+  return [self queryParametersBySettingSelectedDate: [self startDate]];
+}
+
+/* overriding */
+
+- (NSArray *) fetchCoreInfos
+{
+  return nil;
+}
+
+@end
diff --git a/UI/Scheduler/UIxCalDayTable.h b/UI/Scheduler/UIxCalDayTable.h
new file mode 100644 (file)
index 0000000..1cd2d3a
--- /dev/null
@@ -0,0 +1,73 @@
+/* UIxCalDayTable.h - this file is part of $PROJECT_NAME_HERE$
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCALDAYTABLE_H
+#define UIXCALDAYTABLE_H
+
+#import "UIxCalView.h"
+
+@class NSArray;
+@class NSCalendarDay;
+@class NSDictionary;
+@class NSString;
+@class SOGoDateFormatter;
+
+@interface UIxCalDayTable : UIxCalView
+{
+  SOGoDateFormatter *dateFormatter;
+  int numberOfDays;
+  NSCalendarDate *startDate;
+  NSCalendarDate *currentTableDay;
+  NSString *currentTableHour;
+  NSMutableArray *daysToDisplay;
+  NSMutableArray *hoursToDisplay;
+  NSArray *allAppointments;
+
+  NSDictionary *currentAppointment;
+
+  NSString *cssClass;
+  NSString *cssId;
+}
+
+- (void) setCSSClass: (NSString *) aCssClass;
+- (NSString *) cssClass;
+
+- (void) setCSSId: (NSString *) aCssId;
+- (NSString *) cssId;
+
+- (void) setNumberOfDays: (NSString *) aNumber;
+- (NSString *) numberOfDays;
+
+- (void) setStartDate: (NSCalendarDate *) aStartDate;
+- (NSCalendarDate *) startDate;
+- (NSCalendarDate *) endDate;
+
+- (NSArray *) daysToDisplay;
+- (void) setCurrentTableDay: (NSCalendarDate *) aTableDay;
+- (NSCalendarDate *) currentTableDay;
+
+- (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment;
+- (NSDictionary *) currentAppointment;
+
+@end
+
+#endif /* UIXCALDAYTABLE_H */
diff --git a/UI/Scheduler/UIxCalDayTable.m b/UI/Scheduler/UIxCalDayTable.m
new file mode 100644 (file)
index 0000000..59fea71
--- /dev/null
@@ -0,0 +1,324 @@
+/* UIxCalDayTable.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSKeyValueCoding.h>
+#import <Foundation/NSString.h>
+
+#import <EOControl/EOQualifier.h>
+
+#import <NGExtensions/NSCalendarDate+misc.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+
+#import "UIxCalDayTable.h"
+
+@class SOGoAppointment;
+
+@implementation UIxCalDayTable
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      allAppointments = nil;
+      daysToDisplay = nil;
+      hoursToDisplay = nil;
+      numberOfDays = 1;
+      startDate = nil;
+      currentTableDay = nil;
+      currentTableHour = nil;
+      dateFormatter = [[SOGoDateFormatter alloc]
+                        initWithLocale: [self locale]];
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  if (allAppointments)
+    [allAppointments release];
+  if (daysToDisplay)
+    [daysToDisplay release];
+  if (hoursToDisplay)
+    [hoursToDisplay release];
+  [dateFormatter release];
+  [super dealloc];
+}
+
+- (void) setCSSClass: (NSString *) aCssClass
+{
+  cssClass = aCssClass;
+}
+
+- (NSString *) cssClass
+{
+  return cssClass;
+}
+
+- (void) setCSSId: (NSString *) aCssId
+{
+  cssId = aCssId;
+}
+
+- (NSString *) cssId
+{
+  return cssId;
+}
+
+- (void) setNumberOfDays: (NSString *) aNumber
+{
+  numberOfDays = [aNumber intValue];
+  if (daysToDisplay)
+    {
+      [daysToDisplay release];
+      daysToDisplay = nil;
+    }
+}
+
+- (NSString *) numberOfDays
+{
+  return [NSString stringWithFormat: @"%d", numberOfDays];
+}
+
+- (void) setStartDate: (NSCalendarDate *) aStartDate
+{
+  startDate = aStartDate;
+  if (daysToDisplay)
+    {
+      [daysToDisplay release];
+      daysToDisplay = nil;
+    }
+}
+
+- (NSCalendarDate *) startDate
+{
+  if (!startDate)
+    startDate = [super startDate];
+
+  return [startDate beginOfDay];
+}
+
+- (NSCalendarDate *) endDate
+{
+  NSCalendarDate *endDate;
+
+  endDate = [[self startDate] dateByAddingYears: 0
+                              months: 0
+                              days: numberOfDays - 1];
+
+  return [endDate endOfDay];
+}
+
+- (NSArray *) hoursToDisplay
+{
+  unsigned int currentHour, lastHour;
+
+  if (!hoursToDisplay)
+    {
+      currentHour = [self dayStartHour];
+      lastHour = [self dayEndHour];
+      hoursToDisplay = [NSMutableArray new];
+
+      while (currentHour < lastHour)
+        {
+          [hoursToDisplay
+            addObject: [NSString stringWithFormat: @"%d", currentHour]];
+          currentHour++;
+        }
+    }
+
+  return hoursToDisplay;
+}
+
+- (NSArray *) daysToDisplay
+{
+  NSCalendarDate *currentDate;
+  int count;
+
+  if (!daysToDisplay)
+    {
+      daysToDisplay = [NSMutableArray new];
+      currentDate = [[self startDate] hour: [self dayStartHour]
+                                      minute: 0];
+      [daysToDisplay addObject: currentDate];
+      for (count = 1; count < numberOfDays; count++)
+        [daysToDisplay addObject: [currentDate dateByAddingYears: 0
+                                               months: 0
+                                               days: count]];
+    }
+
+  return daysToDisplay;
+}
+
+- (void) setCurrentTableDay: (NSCalendarDate *) aTableDay
+{
+  currentTableDay = aTableDay;
+}
+
+- (NSCalendarDate *) currentTableDay
+{
+  return currentTableDay;
+}
+
+- (void) setCurrentTableHour: (NSString *) aTableHour
+{
+  currentTableHour = aTableHour;
+}
+
+- (NSString *) currentTableHour
+{
+  return currentTableHour;
+}
+
+- (NSString *) currentAppointmentHour
+{
+  return [NSString stringWithFormat: @"%.2d00", [currentTableHour intValue]];
+}
+
+- (NSString *) labelForDay
+{
+  return [NSString stringWithFormat: @"%@ %@",
+                   [dateFormatter shortDayOfWeek: [currentTableDay dayOfWeek]],
+                   [dateFormatter stringForObjectValue: currentTableDay]];
+}
+
+- (NSDictionary *) _adjustedAppointment: (NSDictionary *) anAppointment
+                               forStart: (NSCalendarDate *) start
+                                 andEnd: (NSCalendarDate *) end
+{
+  NSMutableDictionary *newMutableAppointment;
+  NSDictionary *newAppointment;
+  BOOL startIsEarlier, endIsLater;
+
+  startIsEarlier
+    = ([[anAppointment objectForKey: @"startDate"] laterDate: start] == start);
+  endIsLater
+    = ([[anAppointment objectForKey: @"endDate"] earlierDate: end] == end);
+
+  if (startIsEarlier || endIsLater)
+    {
+      newMutableAppointment
+        = [NSMutableDictionary dictionaryWithDictionary: anAppointment];
+      
+      if (startIsEarlier)
+        [newMutableAppointment setObject: start
+                               forKey: @"startDate"];
+      if (endIsLater)
+        [newMutableAppointment setObject: end
+                               forKey: @"endDate"];
+
+      newAppointment = newMutableAppointment;
+    }
+  else
+    newAppointment = anAppointment;
+
+  return newAppointment;
+}
+
+- (NSArray *) appointmentsForCurrentDay
+{
+  NSMutableArray *filteredAppointments;
+  NSEnumerator *aptsEnumerator;
+  NSDictionary *currentDayAppointment;
+  NSCalendarDate *start, *end;
+
+  if (!allAppointments)
+    {
+      allAppointments = [self fetchCoreAppointmentsInfos];
+      [allAppointments retain];
+    }
+
+  filteredAppointments = [NSMutableArray new];
+  [filteredAppointments autorelease];
+
+  start = [currentTableDay hour: [self dayStartHour] minute: 0];
+  end = [currentTableDay hour: [self dayEndHour] minute: 0];
+
+  aptsEnumerator = [allAppointments objectEnumerator];
+  currentDayAppointment = [aptsEnumerator nextObject];
+  while (currentDayAppointment)
+    {
+      if (([end laterDate: [currentDayAppointment
+                             valueForKey: @"startDate"]] == end)
+          && ([start earlierDate: [currentDayAppointment
+                                    valueForKey: @"endDate"]] == start))
+        [filteredAppointments
+          addObject: [self _adjustedAppointment: currentDayAppointment
+                           forStart: start andEnd: end]];
+      currentDayAppointment = [aptsEnumerator nextObject];
+    }
+
+  return filteredAppointments;
+}
+
+- (void) setCurrentAppointment: (NSDictionary *) newCurrentAppointment
+{
+  currentAppointment = newCurrentAppointment;
+}
+
+- (NSDictionary *) currentAppointment
+{
+  return currentAppointment;
+}
+
+- (NSArray *) appointmentsClasses
+{
+  return [NSString stringWithFormat: @"appointments appointmentsFor%dDays",
+                   numberOfDays];
+}
+
+- (NSString *) daysViewClasses
+{
+  return [NSString stringWithFormat: @"daysView daysViewFor%dDays", numberOfDays];
+}
+
+- (NSString *) dayClasses
+{
+  NSMutableString *classes;
+  int dayOfWeek;
+
+  classes = [NSMutableString new];
+  [classes autorelease];
+  [classes appendFormat: @"day day%d", [currentTableDay dayOfWeek]];
+  if (numberOfDays > 1)
+    {
+      dayOfWeek = [currentTableDay dayOfWeek];
+      if (dayOfWeek == 0 || dayOfWeek == 6)
+        [classes appendString: @" weekEndDay"];
+      if ([currentTableDay isToday])
+        [classes appendString: @" dayOfToday"];
+      if ([[self selectedDate] isDateOnSameDay: currentTableDay])
+        [classes appendString: @" selectedDay"];
+    }
+
+  return classes;
+}
+
+- (NSString *) clickableHourCellClass
+{
+  return [NSString stringWithFormat: @"clickableHourCell clickableHourCell%@", currentTableHour];
+}
+
+@end
index 938f2d5cd82417dd8c99025e36f68ffd7f39a693..ae74b19e8251c79fc36f549425027f42c6a12ec7 100644 (file)
@@ -29,7 +29,7 @@
 
 @interface UIxCalDayView : UIxCalView
 {
-    NSCalendarDate *currentDate;
+  NSCalendarDate *currentDate;
 }
 
 - (void)setCurrentDate:(NSCalendarDate *)_date;
index 8ad071d5e6235a5551ac8ffbf6b8faaf04c0b1e5..ddd0729ce33b37efbe1f0f94903053bda25f655e 100644 (file)
 */
 // $Id$
 
+#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSKeyValueCoding.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSValue.h>
 
-#import "UIxCalDayView.h"
-#include "common.h"
-#include <EOControl/EOControl.h>
-#include <NGExtensions/NGCalendarDateRange.h>
+#import <EOControl/EOQualifier.h>
+
+#import <NGExtensions/NSCalendarDate+misc.h>
+#import <NGExtensions/NGCalendarDateRange.h>
 
+#import <SOGoUI/SOGoDateFormatter.h>
+
+#import "UIxCalDayView.h"
 
 @interface UIxCalDayView (PrivateAPI)
 - (BOOL)isCurrentDateInApt:(id)_apt;
 
 @implementation UIxCalDayView
 
-- (void)dealloc {
-    [self->currentDate release];
-    [super dealloc];
+- (void) dealloc
+{
+  [self->currentDate release];
+  [super dealloc];
 }
 
-- (void)setCurrentDate:(NSCalendarDate *)_date {
-    ASSIGN(self->currentDate, _date);
+- (void) setCurrentDate: (NSCalendarDate *) _date
+{
+  ASSIGN(self->currentDate, _date);
 }
-- (NSCalendarDate *)currentDate {
-    return self->currentDate;
+
+- (NSCalendarDate *) currentDate
+{
+  return self->currentDate;
 }
 
-- (BOOL)isCurrentDateInApt {
-    return [self isCurrentDateInApt:[self appointment]];
+- (BOOL) isCurrentDateInApt
+{
+  return [self isCurrentDateInApt: [self appointment]];
 }
 
-- (BOOL)isCurrentDateInApt:(id)_apt {
-    NSCalendarDate *dateStart, *dateEnd, *aptStart, *aptEnd;
-    NGCalendarDateRange *dateRange, *aptRange;
+- (BOOL) isCurrentDateInApt: (id) _apt
+{
+  NSCalendarDate *dateStart, *dateEnd, *aptStart, *aptEnd;
+  NGCalendarDateRange *dateRange, *aptRange;
     
-    dateStart = self->currentDate;
-    dateEnd   = [dateStart dateByAddingYears:0 months:0 days:0
-                                       hours:1 minutes:0 seconds:0];
-    dateRange = [NGCalendarDateRange calendarDateRangeWithStartDate:dateStart
-                                                            endDate:dateEnd];
-    aptStart = [self->appointment valueForKey:@"startDate"];
-    aptEnd   = [self->appointment valueForKey:@"endDate"];
-    aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate:aptStart
-                                                           endDate:aptEnd];
-    return [dateRange doesIntersectWithDateRange:aptRange];
-}
-
-- (NSArray *)dateRange {
-    /* default range is from dayStartHour to dayEndHour. Any values before
-       or after are also fine */
-
-    NSCalendarDate *min, *max;
-    NSArray        *aptDateRanges;
-
-    min = [[self startDate] hour:[self dayStartHour] minute:0];
-    max = [[self startDate] hour:[self dayEndHour]   minute:0];
-
-    aptDateRanges = [[self appointments] valueForKey:@"startDate"];
-    if([aptDateRanges count] != 0) {
-        NSCalendarDate *d;
-        
-        aptDateRanges = [aptDateRanges sortedArrayUsingSelector:@selector(compareAscending:)];
-        d   = [aptDateRanges objectAtIndex:0];
-        if ([d isDateOnSameDay:min])
-          min = (NSCalendarDate *)[d earlierDate:min];
-        d   = [aptDateRanges objectAtIndex:[aptDateRanges count] - 1];
-        if ([d isDateOnSameDay:max])
-          max = (NSCalendarDate *)[d laterDate:max];
-    }
+  dateStart = self->currentDate;
+  dateEnd   = [dateStart dateByAddingYears:0 months:0 days:0
+                         hours:1 minutes:0 seconds:0];
+  dateRange = [NGCalendarDateRange calendarDateRangeWithStartDate:dateStart
+                                   endDate:dateEnd];
+  aptStart = [self->appointment valueForKey:@"startDate"];
+  aptEnd   = [self->appointment valueForKey:@"endDate"];
+  aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate:aptStart
+                                  endDate:aptEnd];
+
+  return [dateRange doesIntersectWithDateRange:aptRange];
+}
 
-    return [self _getDatesFrom:min to:max];
+- (NSArray *) dateRange
+{
+  /* default range is from dayStartHour to dayEndHour. Any values before
+     or after are also fine */
+
+  NSCalendarDate *min, *max;
+  NSArray        *aptDateRanges;
+
+  min = [[self startDate] hour:[self dayStartHour] minute:0];
+  max = [[self startDate] hour:[self dayEndHour]   minute:0];
+
+  aptDateRanges = [[self appointments] valueForKey: @"startDate"];
+  if([aptDateRanges count] != 0) {
+    NSCalendarDate *d;
+
+    aptDateRanges
+      = [aptDateRanges sortedArrayUsingSelector: @selector(compareAscending:)];
+    d   = [aptDateRanges objectAtIndex:0];
+    if ([d isDateOnSameDay:min])
+      min = (NSCalendarDate *)[d earlierDate:min];
+    d   = [aptDateRanges objectAtIndex:[aptDateRanges count] - 1];
+    if ([d isDateOnSameDay:max])
+      max = (NSCalendarDate *)[d laterDate:max];
+  }
+  
+  return [self _getDatesFrom:min to:max];
 }
 
-- (NSArray *)_getDatesFrom:(NSCalendarDate *)_from to:(NSCalendarDate *)_to {
-    NSMutableArray *dates;
-    unsigned       i, count, offset;
+- (NSArray *) _getDatesFrom: (NSCalendarDate *) _from
+                         to: (NSCalendarDate *) _to
+{
+  NSMutableArray *dates;
+  unsigned       i, count, offset;
 
-    offset = [_from hourOfDay];
-    count  = ([_to hourOfDay] + 1) - offset;
-    dates  = [[NSMutableArray alloc] initWithCapacity:count];
-    for(i = 0; i < count; i++) {
-        NSCalendarDate *date;
+  offset = [_from hourOfDay];
+  count  = ([_to hourOfDay] + 1) - offset;
+  dates  = [[NSMutableArray alloc] initWithCapacity:count];
+  for(i = 0; i < count; i++) {
+    NSCalendarDate *date;
         
-        date = [_from hour:offset + i minute:0];
-        [dates addObject:date];
-    }
-    return [dates autorelease];
+    date = [_from hour:offset + i minute:0];
+    [dates addObject:date];
+  }
+  return [dates autorelease];
 }
 
-
 /* URLs */
 
-- (NSDictionary *)prevDayQueryParameters {
-    NSCalendarDate *date;
-    
-    date = [[self startDate] dateByAddingYears:0 months:0 days:-1 
-                                         hours:0 minutes:0 seconds:0];
-    return [self queryParametersBySettingSelectedDate:date];
+- (NSDictionary *) dayBeforePrevDayQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: -2];
 }
 
-- (NSDictionary *)nextDayQueryParameters {
-    NSCalendarDate *date;
-    
-    date = [[self startDate] dateByAddingYears:0 months:0 days:1 
-                                         hours:0 minutes:0 seconds:0];
-    return [self queryParametersBySettingSelectedDate:date];
+- (NSDictionary *) prevDayQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: -1];
 }
 
-- (NSDictionary *)currentDateQueryParameters {
-    NSMutableDictionary *qp;
-    NSString *hmString;
-    NSCalendarDate *date;
-    
-    date = [self currentDate];
-    hmString = [NSString stringWithFormat:@"%02d%02d",
-        [date hourOfDay], [date minuteOfHour]];
-    qp = [[self queryParameters] mutableCopy];
-    [self setSelectedDateQueryParameter:date inDictionary:qp];
-    [qp setObject:hmString forKey:@"hm"];
-    return [qp autorelease];
+- (NSDictionary *) nextDayQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: 1];
+}
+
+- (NSDictionary *) dayAfterNextDayQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: 2];
 }
 
+- (NSDictionary *) currentDateQueryParameters
+{
+  NSMutableDictionary *qp;
+  NSString *hmString;
+  NSCalendarDate *date;
+    
+  date = [self currentDate];
+  hmString = [NSString stringWithFormat:@"%.2d%.2d",
+                       [date hourOfDay], [date minuteOfHour]];
+  qp = [[self queryParameters] mutableCopy];
+  [self setSelectedDateQueryParameter:date inDictionary:qp];
+  [qp setObject:hmString forKey:@"hm"];
+  return [qp autorelease];
+}
 
 /* fetching */
 
-- (NSCalendarDate *)startDate {
-    return [[self selectedDate] beginOfDay];
-}
-- (NSCalendarDate *)endDate {
-    return [[self startDate] endOfDay];
+- (NSCalendarDate *) startDate
+{
+  return [[self selectedDate] beginOfDay];
 }
 
+- (NSCalendarDate *) endDate
+{
+  return [[self selectedDate] endOfDay];
+}
 
 /* appointments */
 
-- (NSArray *)appointments {
-    return [self fetchCoreInfos];
+- (NSArray *) appointments
+{
+  return [self fetchCoreAppointmentsInfos];
 }
 
 - (NSArray *)aptsForCurrentDate {
   apts     = [self appointments];
   filtered = [[NSMutableArray alloc] initWithCapacity:1];
   count    = [apts count];
-  for(i = 0; i < count; i++) {
+  for (i = 0; i < count; i++) {
     id apt;
     NSCalendarDate *aptStartDate;
     
-    /* NOTE: appointments are totally opaque objects, we don't know much
-      about them. The reason for this is that they are backend-dependent
-      and we'd like to use UIx for SOGo *and* ZideStore also.
-      We have to accept the fact that we know just a little bit
-      of their API which is completely KVC driven.
-      */
-    
     apt = [apts objectAtIndex:i];
     aptStartDate = [apt valueForKey:@"startDate"];
     if([aptStartDate isGreaterThanOrEqualTo:start] &&
     {
       [filtered addObject:apt];
     }
+  }
+  
+  return [filtered autorelease];
+}
+
+- (NSArray *)allDayApts {
+  NSCalendarDate *start;
+  NSArray        *apts;
+  NSMutableArray *filtered;
+  unsigned       i, count;
+  
+  if (self->allDayApts)
+    return self->allDayApts;
+
+  start    = [self startDate];
+  apts     = [self appointments];
+  filtered = [[NSMutableArray alloc] initWithCapacity:1];
+  count    = [apts count];
+  for (i = 0; i < count; i++) {
+    id       apt;
+    NSNumber *bv;
+    
+    apt = [apts objectAtIndex:i];
+    bv  = [apt valueForKey:@"isallday"];
+    if ([bv boolValue]) {
+      [filtered addObject:apt];
+    }
     else {
-      /* multiple day range? */
-      NSCalendarDate *aptEndDate;
-      
-      if ((aptEndDate = [apt valueForKey:@"endDate"])) {
-        if ([aptEndDate isLessThanOrEqualTo:end] ||
-            ([aptStartDate isLessThan:start] &&
-             [aptEndDate   isGreaterThan:end]))
-        {
-          [filtered addObject:apt];
-        }
+      NSCalendarDate *aptStartDate;
+
+      aptStartDate = [apt valueForKey:@"startDate"];
+      if([aptStartDate isLessThan:start]) {
+        [filtered addObject:apt];
       }
     }
   }
-
-  return [filtered autorelease];
+  
+  ASSIGN(self->allDayApts, filtered);
+  [filtered release];
+  return self->allDayApts;
 }
 
-- (BOOL)hasAptsForCurrentDate {
+- (BOOL) hasAptsForCurrentDate
+{
   return [[self aptsForCurrentDate] count] != 0;
 }
 
+- (NSString *) _dayNameWithOffsetFromToday: (int) offset
+{
+  NSCalendarDate *date;
+
+  date = [[self selectedDate] dateByAddingYears: 0
+                              months: 0
+                              days: offset];
+
+  return [self localizedNameForDayOfWeek: [date dayOfWeek]];
+}
+
+- (NSString *) dayBeforeYesterdayName
+{
+  return [self _dayNameWithOffsetFromToday: -2];
+}
+
+- (NSString *) yesterdayName
+{
+  return [self _dayNameWithOffsetFromToday: -1];
+}
+
+- (NSString *) currentDayName
+{
+  return [self _dayNameWithOffsetFromToday: 0];
+}
+
+- (NSString *) tomorrowName
+{
+  return [self _dayNameWithOffsetFromToday: 1];
+}
+
+- (NSString *) dayAfterTomorrowName
+{
+  return [self _dayNameWithOffsetFromToday: 2];
+}
+
 @end
diff --git a/UI/Scheduler/UIxCalFilterPanel.h b/UI/Scheduler/UIxCalFilterPanel.h
new file mode 100644 (file)
index 0000000..41106f9
--- /dev/null
@@ -0,0 +1,38 @@
+/* UIxContactsFilterPanel.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCONTACTSFILTERPANEL_H
+#define UIXCONTACTSFILTERPANEL_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSString;
+
+@interface UIxCalFilterPanel : UIxComponent
+{
+  NSString *searchText;
+  NSString *searchCriteria;
+}
+
+@end
+
+#endif /* UIXCONTACTSFILTERPANEL_H */
diff --git a/UI/Scheduler/UIxCalFilterPanel.m b/UI/Scheduler/UIxCalFilterPanel.m
new file mode 100644 (file)
index 0000000..4343733
--- /dev/null
@@ -0,0 +1,119 @@
+/* UIxContactsFilterPanel.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSKeyValueCoding.h>
+
+#import <NGObjWeb/WOContext.h>
+
+#import "UIxCalFilterPanel.h"
+
+static NSArray *filters = nil;
+
+@implementation UIxCalFilterPanel
+
++ (void) initialize
+{
+  static NSString *quals[]
+    = {@"view_today", @"view_all", @"view_next7", @"view_next14",
+       @"view_next31", @"view_thismonth", @"view_future",
+       @"view_selectedday" };
+
+  if (!filters)
+    {
+      filters = [NSArray arrayWithObjects: quals count: 8];
+      [filters retain];
+    }
+}
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      searchText = nil;
+      searchCriteria = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [self->searchCriteria release];
+  [self->searchText release];
+  [super dealloc];
+}
+
+/* accessors */
+
+- (void) setSearchText: (NSString *)_txt
+{
+  ASSIGNCOPY(self->searchText, _txt);
+}
+
+- (void) setSearchCriteria: (NSString *)_txt
+{
+  ASSIGNCOPY(self->searchText, _txt);
+}
+
+- (NSString *) searchText
+{
+  if (!searchText)
+    searchText = [[self queryParameterForKey: @"search"] copy];
+
+  return searchText;
+}
+
+- (NSString *) searchCriteria
+{
+  if (!searchCriteria)
+    searchCriteria = [[self queryParameterForKey: @"criteria"] copy];
+
+  return searchCriteria;
+}
+
+/* filters */
+
+- (NSArray *) filters
+{
+  return filters;
+}
+
+/* qualifiers */
+
+- (NSString *) filterLabel
+{
+#if 1
+  return [[[self context] page] labelForKey: [self valueForKey:@"filter"]];
+#else
+  return [self valueForKey: @"filter"];
+#endif
+}
+
+- (NSString *) selectedFilter
+{
+  return [self queryParameterForKey: @"filterpopup"];
+}
+
+@end /* UIxCalFilterPanel */
index eabc1bd90fb86eb5be5222950cebc8ba2c4d7d68..f6d2ae33617c2647355b9c69320556f496430f4b 100644 (file)
  */
 // $Id$
 
-#include <NGObjWeb/NGObjWeb.h>
+#import <Foundation/NSDictionary.h>
+
+#import <NGObjWeb/NGObjWeb.h>
 
 @interface UIxCalInlineAptView : WOComponent
 {
-  id   appointment;
-  id   formatter;
-  id   tooltipFormatter;
-  id   url;
-  id   style;
-  id   queryDictionary;
-  id   referenceDate;
+  NSDictionary *appointment;
+  id formatter;
+  id tooltipFormatter;
+  id url;
+  id style;
+  id queryDictionary;
+  id referenceDate;
+  int dayStartHour;
+  int dayEndHour;
   BOOL canAccess;
 }
 
 
 @implementation UIxCalInlineAptView
 
-- (void)dealloc {
-  [self->appointment      release];
-  [self->formatter        release];
-  [self->tooltipFormatter release];
-  [self->url              release];
-  [self->style            release];
-  [self->queryDictionary  release];
-  [self->referenceDate    release];
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      dayStartHour = 0;
+      dayEndHour = 24;
+      appointment = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [appointment release];
+  [formatter release];
+  [tooltipFormatter release];
+  [url release];
+  [style release];
+  [queryDictionary release];
+  [referenceDate release];
   [super dealloc];
 }
 
-- (void)setAppointment:(id)_appointment {
-  ASSIGN(self->appointment, _appointment);
+- (void) setAppointment: (NSDictionary *) _appointment
+{
+  ASSIGN(appointment, _appointment);
 }
-- (id)appointment {
-  return self->appointment;
+
+- (NSDictionary *) appointment
+{
+  return appointment;
 }
 
-- (void)setFormatter:(id)_formatter {
-  ASSIGN(self->formatter, _formatter);
+- (void) setDayStartHour: (unsigned int) anHour
+{
+  dayStartHour = anHour;
 }
-- (id)formatter {
-  return self->formatter;
+
+- (void) setDayEndHour: (unsigned int) anHour
+{
+  dayEndHour = anHour;
 }
 
-- (void)setTooltipFormatter:(id)_tooltipFormatter {
-  ASSIGN(self->tooltipFormatter, _tooltipFormatter);
+- (void) setFormatter: (id) _formatter
+{
+  ASSIGN(formatter, _formatter);
 }
-- (id)tooltipFormatter {
-  return self->tooltipFormatter;
+
+- (id) formatter
+{
+  return formatter;
+}
+
+- (void) setTooltipFormatter: (id) _tooltipFormatter
+{
+  ASSIGN(tooltipFormatter, _tooltipFormatter);
+}
+
+- (id) tooltipFormatter
+{
+  return tooltipFormatter;
 }
 
-- (void)setUrl:(id)_url {
-  ASSIGN(self->url, _url);
+- (void) setUrl: (id) _url
+{
+  ASSIGN(url, _url);
 }
-- (id)url {
-  return self->url;
+
+- (id) url
+{
+  return url;
 }
 
-- (void)setStyle:(id)_style {
+- (void) setStyle: (id) _style 
+{
   NSMutableString *ms;
-  NSNumber        *prio;
-  NSString        *s;
-  NSString        *email;
+  NSNumber *prio;
+  NSString *s;
+  NSString *email;
 
-  if (_style) {
-    ms = [NSMutableString stringWithString:_style];
-  }
-  else {
+  if (_style)
+    ms = [NSMutableString stringWithString: _style];
+  else
     ms = (NSMutableString *)[NSMutableString string];
-  }
-  if ((prio = [self->appointment valueForKey:@"priority"])) {
+
+  if ((prio = [appointment valueForKey:@"priority"])) {
     [ms appendFormat:@" apt_prio%@", prio];
   }
   email = [[[self context] activeUser] email];
-  if ((s = [self->appointment valueForKey:@"orgmail"])) {
+  if ((s = [appointment valueForKey:@"orgmail"])) {
     if ([s rangeOfString:email].length > 0) {
       [ms appendString:@" apt_organizer"];
     }
       [ms appendString:@" apt_other"];
     }
   }
-  if ((s = [self->appointment valueForKey:@"partmails"])) {
+  if ((s = [appointment valueForKey:@"partmails"])) {
     if ([s rangeOfString:email].length > 0) {
       [ms appendString:@" apt_participant"];
     }
       [ms appendString:@" apt_nonparticipant"];
     }
   }
-  ASSIGNCOPY(self->style, ms);
+  ASSIGNCOPY(style, ms);
 }
+
 - (id)style {
-  return self->style;
+  return style;
+}
+
+- (void) setQueryDictionary: (id) _queryDictionary
+{
+  ASSIGN(queryDictionary, _queryDictionary);
+}
+
+- (id) queryDictionary
+{
+  return queryDictionary;
 }
 
-- (void)setQueryDictionary:(id)_queryDictionary {
-  ASSIGN(self->queryDictionary, _queryDictionary);
+- (void) setReferenceDate: (id) _referenceDate
+{
+  ASSIGN(referenceDate, _referenceDate);
 }
-- (id)queryDictionary {
-  return self->queryDictionary;
+
+- (id) referenceDate
+{
+  return referenceDate;
 }
 
-- (void)setReferenceDate:(id)_referenceDate {
-  ASSIGN(self->referenceDate, _referenceDate);
+- (void) setCanAccess: (BOOL) _canAccess
+{
+  canAccess = _canAccess;
+}
+
+- (BOOL) canAccess
+{
+  return canAccess;
 }
-- (id)referenceDate {
-  return self->referenceDate;
+
+- (NSString *) displayClasses
+{
+  NSTimeInterval secondsStart, secondsEnd, delta;
+  NSCalendarDate *startDate;
+  int deltaStart, deltaLength;
+
+  startDate = [appointment objectForKey: @"startDate"];
+  secondsStart = [startDate timeIntervalSince1970];
+  secondsEnd = [[appointment objectForKey: @"endDate"] timeIntervalSince1970];
+  delta = (secondsEnd - [startDate timeIntervalSince1970]) / 60;
+  deltaLength = delta / 15;
+  if (((int) delta % 15) > 0)
+    deltaLength += 1;
+
+  deltaStart = (([startDate hourOfDay] * 60 + [startDate minuteOfHour]
+                 - dayStartHour * 60) / 15);
+
+  return [NSString stringWithFormat: @"appointment ownerIs%@ starts%d lasts%d",
+                   [appointment objectForKey: @"owner"],
+                   deltaStart, deltaLength, [startDate dayOfWeek]];
 }
 
-- (void)setCanAccess:(BOOL)_canAccess {
-  self->canAccess = _canAccess;
+- (NSString *) innerDisplayClasses
+{
+  return [NSString stringWithFormat: @"appointmentInside ownerIs%@",
+                   [appointment objectForKey: @"owner"]];
 }
-- (BOOL)canAccess {
-  return self->canAccess;
+
+- (NSString *) displayStyle
+{
+  NSCalendarDate *startDate, *endDate, *dayStart, *dayEnd;
+  int sSeconds, eSeconds, deltaMinutes;
+  unsigned int height;
+  NSTimeZone *uTZ;
+
+  uTZ = [referenceDate timeZone];
+  dayStart = [referenceDate beginOfDay];
+  dayEnd = [referenceDate endOfDay];
+
+  sSeconds = [[appointment objectForKey: @"startdate"] intValue];
+  eSeconds = [[appointment objectForKey: @"enddate"] intValue];
+  startDate = [NSCalendarDate dateWithTimeIntervalSince1970: sSeconds];
+  [startDate setTimeZone: uTZ];
+  if ([startDate earlierDate: dayStart] == startDate)
+    startDate = dayStart;
+  endDate = [NSCalendarDate dateWithTimeIntervalSince1970: eSeconds];
+  [endDate setTimeZone: uTZ];
+  if ([endDate earlierDate: dayEnd] == dayEnd)
+    endDate = dayEnd;
+
+  deltaMinutes = (([endDate hourOfDay] - [startDate hourOfDay]) * 60
+                  + [endDate minuteOfHour] - [startDate minuteOfHour]);
+  height = ceil(deltaMinutes / 15) * 25;
+
+  return [NSString stringWithFormat: @"height: %d%%;", height];
 }
 
 /* helpers */
 
-- (NSString *)title {
-  return [self->formatter stringForObjectValue:self->appointment
-                          referenceDate:[self referenceDate]];
+- (NSString *) title
+{
+  return [formatter stringForObjectValue: appointment
+                    referenceDate: [self referenceDate]];
 }
 
-- (NSString *)tooltip {
-  return [self->tooltipFormatter stringForObjectValue:self->appointment
-                                 referenceDate:[self referenceDate]];
+- (NSString *) tooltip
+{
+  return [tooltipFormatter stringForObjectValue: appointment
+                           referenceDate: [self referenceDate]];
 }
 
 @end
similarity index 55%
rename from Misc/dbd/DSoHost.h
rename to UI/Scheduler/UIxCalInlineMonthOverview.h
index cd0bbd102bf2d84d37d7bdfff89e32c4c9c32d84..0948f06fbe9ea8eda02424cedbd7bc1947023615 100644 (file)
   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.
 */
-// $Id$
 
-#ifndef __dbd_DSoHost_H__
-#define __dbd_DSoHost_H__
+#ifndef UIXCALINLINEMONTHOVERVIEW_H
+#define UIXCALINLINEMONTHOVERVIEW_H
 
-#include "DSoObject.h"
+#import "UIxCalMonthOverview.h"
 
+@class NSCalendarDate;
 @class NSString;
 
-@interface DSoHost : DSoObject
+@interface UIxCalInlineMonthOverview : UIxCalMonthOverview
 {
-  NSString *hostName;
-  int      port;
+    NSCalendarDate *selectedDate;
+    NSString *style;
+    NSString *headerStyle;
+    NSString *weekStyle;
+    NSString *todayWeekStyle;
+    NSString *dayHeaderStyle;
+    NSString *dayBodyStyle;
+    NSString *todayBodyStyle;
+    NSString *inactiveDayBodyStyle;
+    NSString *selectedDayExtraStyle;
+    NSString *daySelectionHref;
+    NSString *weekSelectionHref;
+    NSString *monthSelectionHref;
+    BOOL showWeekColumn;
+    BOOL showYear;
 }
 
-+ (id)dHostWithName:(NSString *)_key port:(int)_port;
-- (id)initWithHostName:(NSString *)_key port:(int)_port;
-
-/* accessors */
-
-- (NSString *)hostName;
-- (int)port;
-
-/* support */
-
-- (EOAdaptor *)adaptorInContext:(WOContext *)_ctx;
-
 @end
 
-#endif /* __dbd_DSoHost_H__ */
+#endif /* UIXCALINLINEMONTHOVERVIEW_H */
index 2b61484b56bc0b864dfd13123d10a7ee4e81e277..baaeca1a87f753e8e2ebd074a44973e3b314a28f 100644 (file)
 // $Id$
 
 
-#include "UIxCalMonthOverview.h"
-#include <NGExtensions/NGExtensions.h>
-
-
-@interface UIxCalInlineMonthOverview : UIxCalMonthOverview
-{
-    NSCalendarDate *selectedDate;
-    NSString *style;
-    NSString *headerStyle;
-    NSString *weekStyle;
-    NSString *todayWeekStyle;
-    NSString *dayHeaderStyle;
-    NSString *dayBodyStyle;
-    NSString *todayBodyStyle;
-    NSString *inactiveDayBodyStyle;
-    NSString *selectedDayExtraStyle;
-    NSString *daySelectionHref;
-    NSString *weekSelectionHref;
-    NSString *monthSelectionHref;
-    BOOL showWeekColumn;
-    BOOL showYear;
-}
-
-@end
-
-
-@interface NSCalendarDate (UIxCalMonthOverviewExtensions)
-- (BOOL)isDateInSameMonth:(NSCalendarDate *)_other;
-@end
-
+#import <NGExtensions/NSCalendarDate+misc.h>
 
-@implementation NSCalendarDate (UIxCalMonthOverviewExtensions)
-- (BOOL)isDateInSameMonth:(NSCalendarDate *)_other {
-    if(_other == nil)
-        return NO;
-    if(([_other yearOfCommonEra] == [self yearOfCommonEra]) &&
-       ([_other monthOfYear] == [self monthOfYear])) {
-        return YES;
-    }
-    return NO;
-}
-@end
+#import <SOGo/NSCalendarDate+SOGo.h>
 
+#import "UIxCalInlineMonthOverview.h"
 
 @implementation UIxCalInlineMonthOverview
 
@@ -90,7 +52,7 @@
 /* binding accessors */
 
 - (void)setSelectedDate:(NSCalendarDate *)_date {
-    [_date setTimeZone:[self viewTimeZone]];
+    [_date setTimeZone:[[self clientObject] userTimeZone]];
     ASSIGN(self->selectedDate, _date);
 }
 - (NSCalendarDate *)selectedDate {
diff --git a/UI/Scheduler/UIxCalMainView.h b/UI/Scheduler/UIxCalMainView.h
new file mode 100644 (file)
index 0000000..b1e13a0
--- /dev/null
@@ -0,0 +1,50 @@
+/* UIxCalMainView.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCALMAINVIEW_H
+#define UIXCALMAINVIEW_H
+
+@class NSArray;
+@class NSNumber;
+@class NSString;
+
+#import "UIxCalView.h"
+
+@interface UIxCalMainView : UIxCalView
+{
+  NSString *monthMenuItem;
+  NSNumber *yearMenuItem;
+}
+
+- (NSArray *) monthMenuItems;
+- (NSArray *) yearMenuItems;
+
+- (void) setMonthMenuItem: (NSString *) aMonthMenuItem;
+- (NSString *) monthMenuItem;
+- (NSString *) monthMenuItemLabel;
+
+- (void) setYearMenuItem: (NSNumber *) aYearMenuItem;
+- (NSNumber *) yearMenuItem;
+
+@end
+
+#endif /* UIXCALMAINVIEW_H */
diff --git a/UI/Scheduler/UIxCalMainView.m b/UI/Scheduler/UIxCalMainView.m
new file mode 100644 (file)
index 0000000..35eef41
--- /dev/null
@@ -0,0 +1,170 @@
+/* UIxCalMainView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSUserDefaults.h>
+#import <Foundation/NSValue.h>
+
+#import <NGObjWeb/WOResponse.h>
+
+#import <SOGo/SOGoUser.h>
+
+#import "UIxCalMainView.h"
+
+#import <Appointments/SOGoAppointmentFolder.h>
+
+static NSMutableArray *monthMenuItems = nil;
+static NSMutableArray *yearMenuItems = nil;
+
+@implementation UIxCalMainView
+
+- (NSArray *) monthMenuItems
+{
+  unsigned int count;
+  if (!monthMenuItems)
+    {
+      monthMenuItems = [NSMutableArray arrayWithCapacity: 12];
+      
+      for (count = 1; count < 13; count++)
+        [monthMenuItems addObject:
+                          [NSString stringWithFormat: @"%.2d", count]];
+      [monthMenuItems retain];
+    }
+
+  return monthMenuItems;
+}
+
+- (void) setMonthMenuItem: (NSString *) aMonthMenuItem
+{
+  monthMenuItem = aMonthMenuItem;
+}
+
+- (NSString *) monthMenuItem
+{
+  return monthMenuItem;
+}
+
+- (NSString *) monthMenuItemLabel
+{
+  return [self localizedNameForMonthOfYear: [monthMenuItem intValue]];
+}
+
+- (NSArray *) yearMenuItems
+{
+  int count, year;
+  if (!yearMenuItems)
+    {
+      year = [[NSCalendarDate date] yearOfCommonEra];
+      yearMenuItems = [NSMutableArray arrayWithCapacity: 11];
+      for (count = -5; count < 6; count++)
+        [yearMenuItems addObject: [NSNumber numberWithInt: year + count]];
+      [yearMenuItems retain];
+    }
+
+  return yearMenuItems;
+}
+
+- (void) setYearMenuItem: (NSNumber *) aYearMenuItem
+{
+  yearMenuItem = aYearMenuItem;
+}
+
+- (NSNumber *) yearMenuItem
+{
+  return yearMenuItem;
+}
+
+- (id) batchDeleteAction
+{
+  NSArray *ids;
+  SOGoAppointmentFolder *clientObject;
+
+  ids = [[self queryParameterForKey: @"ids"] componentsSeparatedByString: @"/"];
+  if (ids)
+    {
+      clientObject = [self clientObject];
+      [clientObject deleteEntriesWithIds: ids];
+    }
+
+  return self;
+}
+
+- (id <WOActionResults>) updateCalendarsAction
+{
+  WOResponse *response;
+  NSUserDefaults *ud;
+
+  ud = [[context activeUser] userDefaults];
+  [ud setObject: [self queryParameterForKey: @"ids"]
+                       forKey: @"calendaruids"];
+  [ud synchronize];
+  response = [context response];
+  [response setStatus: 200];
+  [response setHeader: @"text/html; charset=\"utf-8\"" forKey: @"content-type"];
+
+  return response;
+}
+
+- (id <WOActionResults>) checkRightsAction
+{
+  WOResponse *response;
+  NSUserDefaults *ud;
+  NSString *uids, *uid;
+  NSMutableString *rights;
+  NSArray *ids;
+  unsigned int count, max;
+  BOOL result;
+
+  ud = [[context activeUser] userDefaults];
+  uids = [ud stringForKey: @"calendaruids"];
+
+  response = [context response];
+  [response setStatus: 200];
+  [response setHeader: @"text/plain; charset=\"utf-8\""
+            forKey: @"content-type"];
+  rights = [NSMutableString string];
+  if ([uids length] > 0)
+    {
+      ids = [uids componentsSeparatedByString: @","];
+      max = [ids count];
+      for (count = 0; count < max; count++)
+        {
+          uid = [ids objectAtIndex: count];
+          if ([uid hasPrefix: @"-"])
+            uid = [uid substringFromIndex: 1];
+          result = ([self calendarFolderForUID: uid] != nil);
+          if (count == 0)
+            [rights appendFormat: @"%d", result];
+          else
+            [rights appendFormat: @",%d", result];
+        }
+    }
+  [response appendContentString: rights];
+
+  return response;
+}
+
+@end
index 3a91da5d60aa148a59c0794d95eed5a48fcedf8d..52c9b1ab5fa5da4f64c75e92b56488977ec2cd3f 100644 (file)
 // $Id$
 
 
-#include "UIxCalMonthView.h"
-
+#import "UIxCalMonthViewOld.h"
 
 @class NSCalendarDate, NSString, NSDictionary, NSArray;
 
-
-@interface UIxCalMonthOverview : UIxCalMonthView
+@interface UIxCalMonthOverview : UIxCalMonthViewOld
 {
     int dayIndex;
     int dayOfWeek;
 - (NSString *)localizedDayOfWeekName;
 - (NSDictionary *)currentWeekQueryParameters;
 
-
 /* style sheet */
 
-
 - (NSString *)weekStyle;
-
 - (NSString *)contentStyle;
 
-
 /* appointments */
 
-
 - (NSArray *)appointments;
     
 @end
index 728c61444492b55faa06f94d363ac320312dbd1b..f00893c72632bd67a41cfe04b8d5891b202d330c 100644 (file)
@@ -97,7 +97,7 @@
 
 
 - (NSArray *)appointments {
-  return [self fetchCoreInfos];
+  return [self fetchCoreAppointmentsInfos];
 }
 
 @end /* UIxCalMonthOverview */
diff --git a/UI/Scheduler/UIxCalMonthPrintview.m b/UI/Scheduler/UIxCalMonthPrintview.m
deleted file mode 100644 (file)
index ba2cb4c..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- Copyright (C) 2004 SKYRIX Software AG
- This file is part of OpenGroupware.org.
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING.  If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
- */
-// $Id$
-
-
-#include "UIxCalMonthOverview.h"
-
-@interface UIxCalMonthPrintview : UIxCalMonthOverview
-{
-}
-
-@end
-
-#include "common.h"
-
-@implementation UIxCalMonthPrintview
-
-- (NSString *)shortTextForApt {
-  NSCalendarDate  *startDate, *endDate;
-  NSMutableString *aptDescr;
-  NSString        *s;
-  BOOL            isMyApt;
-  BOOL            canAccessApt;
-  BOOL            spansRange;
-  id              apt;
-  
-  apt          = [self appointment];
-  isMyApt      = [self isMyApt];
-  canAccessApt = [self canAccessApt];
-  spansRange   = NO;
-  startDate    = [apt valueForKey:@"startDate"];
-  [startDate setTimeZone:[self viewTimeZone]];
-  endDate      = [apt valueForKey:@"endDate"];
-  if(endDate != nil) {
-    [endDate setTimeZone:[self viewTimeZone]];
-    spansRange = ![endDate isEqualToDate:startDate];
-  }
-
-  aptDescr = [[NSMutableString alloc] init];
-  [aptDescr appendFormat:@"<span class=\"%@\">%02i:%02i",
-                           isMyApt ? @"monthprintview_apt_time" :
-                                     @"monthprintview_apt_time_other",
-                           [startDate hourOfDay],
-                           [startDate minuteOfHour]];
-  if(spansRange) {
-    [aptDescr appendFormat:@" - %02i:%02i",
-                             [endDate hourOfDay],
-                             [endDate minuteOfHour]];
-  }
-  [aptDescr appendFormat:@"</span>,"];
-  if (!isMyApt)
-    [aptDescr appendFormat:@"<span class=\"%@\">", [self aptStyle]];
-  if (canAccessApt) {
-    s = [apt valueForKey:@"title"];
-    if(s) {
-      [aptDescr appendFormat:@"<br />%@", s];
-    }
-    s = [apt valueForKey:@"location"];
-    if(s) {
-      [aptDescr appendFormat:@"<br />%@", s];
-    }
-  }
-  else {
-    [aptDescr appendFormat:@"<br />%@",
-      [self labelForKey:@"private appointment"]];
-  }
-  if(!isMyApt)
-    [aptDescr appendString:@"</span>"];
-  return [aptDescr autorelease];
-}
-
-- (NSString *)title {
-  NSCalendarDate *date;
-  
-  date = [self startOfMonth];
-  return [NSString stringWithFormat:@"%@ %d",
-    [self localizedNameForMonthOfYear:[date monthOfYear]],
-    [date yearOfCommonEra]];
-}
-
-
-/* style sheet */
-
-
-- (NSString *)contentStyle {
-  if([self->currentDay monthOfYear] != [[self startOfMonth] monthOfYear])
-    return @"monthprintview_content_dimmed";
-  return @"monthprintview_content";
-}
-
-- (NSString *)aptStyle {
-  if (![self isMyApt])
-    return @"monthprintview_apt_other";
-  return nil;
-}
-
-@end
index 6fe2c99c82b70b42a8ebc6535f372aedad64836e..94bc806bd9455e1d1ddede4707d7d2bff777ca7b 100644 (file)
@@ -1,25 +1,78 @@
-// $Id$
+/* UIxCalMonthView.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
-#ifndef __SOGo_UIxCalMonthView_H__
-#define __SOGo_UIxCalMonthView_H__
+#ifndef UIXCALMONTHVIEW_H
+#define UIXCALMONTHVIEW_H
 
-#include "UIxCalView.h"
+#import "UIxCalView.h"
 
-/*
-  UIxCalMonthView
-  
-  Abstract superclass for views which display months.
-*/
+@class NSArray;
+@class NSCalendarDate;
+@class NSDictionary;
+@class NSMutableDictionary;
+
+@class SOGoAptFormatter;
+@class SOGoDateFormatter;
+
+@protocol WOActionResults;
 
 @interface UIxCalMonthView : UIxCalView
 {
+  SOGoAptFormatter *monthAptFormatter;
+  SOGoDateFormatter *dateFormatter;
+
+  NSMutableDictionary *sortedAppointments;
+  NSCalendarDate *currentTableDay;
+//   NSArray *rangesOf7Days;
+  NSArray *currentRangeOf7Days;
 }
 
-- (NSCalendarDate *)startOfMonth;
+- (id <WOActionResults>) defaultAction;
+
+- (NSDictionary *) monthBeforePrevMonthQueryParameters;
+- (NSDictionary *) prevMonthQueryParameters;
+- (NSDictionary *) nextMonthQueryParameters;
+- (NSDictionary *) monthAfterNextMonthQueryParameters;
+
+- (NSString *) monthNameOfTwoMonthAgo;
+- (NSString *) monthNameOfOneMonthAgo;
+- (NSString *) monthNameOfThisMonth;
+- (NSString *) monthNameOfNextMonth;
+- (NSString *) monthNameOfTheMonthAfterNextMonth;
+
+- (NSArray *) daysToDisplay;
+
+- (NSString *) labelForCurrentDayToDisplay;
+- (NSString *) dayCellClasses;
+
+- (void) setCurrentTableDay: (NSCalendarDate *) newCurrentTableDay;
+- (NSCalendarDate *) currentTableDay;
+- (NSString *) labelForCurrentDayCell;
+
+- (NSArray *) rangesOf7Days;
 
-- (NSDictionary *)prevMonthQueryParameters;
-- (NSDictionary *)nextMonthQueryParameters;
+- (void) setCurrentRangeOf7Days: (NSArray *) newCurrentRangeOf7Days;
+- (NSArray *) currentRangeOf7Days;
 
 @end
 
-#endif /* __SOGo_UIxCalMonthView_H__ */
+#endif /* UIXCALMONTHVIEW_H */
index ef2ea81cfcaea1d0847d56747b8ae9aeb056c26b..196637353798041d403d891e239c23a91df4d0ed 100644 (file)
-// $Id$
+/* UIxCalMonthView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
-#include "UIxCalMonthView.h"
-#include "NSCalendarDate+UIx.h"
-#include "common.h"
+#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSString.h>
+
+#import <NGExtensions/NSCalendarDate+misc.h>
+#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
+
+#import <SOGoUI/SOGoAptFormatter.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+
+#import "UIxCalMonthView.h"
 
 @implementation UIxCalMonthView
 
-- (NSCalendarDate *)startOfMonth {
-  return [[[super startDate] firstDayOfMonth] beginOfDay];
+- (id) init
+{
+  NSTimeZone *tz;
+
+  if ((self = [super init]))
+    {
+      tz = [[self clientObject] userTimeZone];
+      monthAptFormatter
+        = [[SOGoAptFormatter alloc] initWithDisplayTimeZone: tz];
+      [monthAptFormatter setShortMonthTitleOnly];
+      dateFormatter = [[SOGoDateFormatter alloc]
+                        initWithLocale: [self locale]];
+      sortedAppointments = [NSMutableDictionary new];
+    }
+
+  return self;
 }
 
-- (NSCalendarDate *)startDate {
-  return [[self startOfMonth] mondayOfWeek];
+- (SOGoAptFormatter *) monthAptFormatter
+{
+  return monthAptFormatter;
+}
+
+- (void) dealloc
+{
+  [monthAptFormatter release];
+  [dateFormatter release];
+  [sortedAppointments release];
+  [super dealloc];
+}
+
+- (void) _addEventToSortedEvents: (NSDictionary *) newEvent
+{
+  NSMutableArray *eventArray;
+  NSString *dayId;
+
+  dayId = [[newEvent objectForKey: @"startDate"] shortDateString];
+  eventArray = [sortedAppointments objectForKey: dayId];
+  if (!eventArray)
+    {
+      eventArray = [NSMutableArray new];
+      [eventArray autorelease];
+      [sortedAppointments setObject: eventArray forKey: dayId];
+    }
+  [eventArray addObject: newEvent];
 }
 
-- (NSCalendarDate *)endDate {
+- (id <WOActionResults>) defaultAction
+{
+  NSEnumerator *events;
+  NSDictionary *currentEvent;
+
+  events = [[self fetchCoreAppointmentsInfos] objectEnumerator];
+  currentEvent = [events nextObject];
+  while (currentEvent)
+    {
+      [self _addEventToSortedEvents: currentEvent];
+      currentEvent = [events nextObject];
+//       NSLog (@"event:\n'%@'", currentEvent);
+    }
+
+  return self;
+}
+
+- (NSArray *) daysToDisplay
+{
+  NSMutableArray *daysToDisplay;
+  NSCalendarDate *currentDayToDisplay;
+  unsigned int day;
+
+  daysToDisplay = [NSMutableArray arrayWithCapacity: 7];
+  currentDayToDisplay = [[NSCalendarDate calendarDate] mondayOfWeek];
+  for (day = 0; day < 7; day++)
+    {
+      [daysToDisplay addObject: currentDayToDisplay];
+      currentDayToDisplay
+        = [currentDayToDisplay dateByAddingYears: 0 months: 0 days: 1];
+    }
+
+  return daysToDisplay;
+}
+
+- (NSString *) labelForCurrentDayToDisplay
+{
+  return [dateFormatter fullDayOfWeek: [currentTableDay dayOfWeek]];
+}
+
+- (NSDictionary *) _dateQueryParametersWithOffset: (int) monthsOffset
+{
   NSCalendarDate *date;
   
-  date = [self startOfMonth];
-  date = [date dateByAddingYears:0 months:0 days:[date numberOfDaysInMonth]
-               hours:0 minutes:0 seconds:0];
-  date = [[date sundayOfWeek] endOfDay];
-  return date;
+  date = [[self selectedDate] dateByAddingYears: 0 months: monthsOffset
+                              days: 0 hours: 0 minutes: 0 seconds: 0];
+
+  return [self queryParametersBySettingSelectedDate: date];
 }
 
-/* URLs */
+- (NSDictionary *) monthBeforePrevMonthQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: -2];
+}
 
-- (NSDictionary *)prevMonthQueryParameters {
-  NSCalendarDate *date;
+- (NSDictionary *) prevMonthQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: -1];
+}
 
-  date = [[self startOfMonth] dateByAddingYears:0 months:-1 days:0
-                             hours:0 minutes:0 seconds:0];
-  return [self queryParametersBySettingSelectedDate:date];
+- (NSDictionary *) nextMonthQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: 1];
 }
 
-- (NSDictionary *)nextMonthQueryParameters {
+- (NSDictionary *) monthAfterNextMonthQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: 2];
+}
+
+- (NSString *) _monthNameWithOffsetFromThisMonth: (int) offset
+{
   NSCalendarDate *date;
-    
-  date = [[self startOfMonth] dateByAddingYears:0 months:1 days:0
-                             hours:0 minutes:0 seconds:0];
-  return [self queryParametersBySettingSelectedDate:date];
+
+  date = [[self selectedDate] dateByAddingYears: 0 months: offset days: 0];
+
+  return [self localizedNameForMonthOfYear: [date monthOfYear]];
+}
+
+- (NSString *) monthNameOfTwoMonthAgo
+{
+  return [self _monthNameWithOffsetFromThisMonth: -2];
+}
+
+- (NSString *) monthNameOfOneMonthAgo
+{
+  return [self _monthNameWithOffsetFromThisMonth: -1];
+}
+
+- (NSString *) monthNameOfThisMonth
+{
+  return [self _monthNameWithOffsetFromThisMonth: 0];
+}
+
+- (NSString *) monthNameOfNextMonth
+{
+  return [self _monthNameWithOffsetFromThisMonth: 1];
+}
+
+- (NSString *) monthNameOfTheMonthAfterNextMonth
+{
+  return [self _monthNameWithOffsetFromThisMonth: 2];
+}
+
+/* template accessors */
+- (void) setCurrentTableDay: (NSCalendarDate *) newCurrentTableDay
+{
+  currentTableDay = newCurrentTableDay;
+}
+
+- (NSCalendarDate *) currentTableDay
+{
+  return currentTableDay;
+}
+
+- (void) setCurrentRangeOf7Days: (NSArray *) newCurrentRangeOf7Days
+{
+  currentRangeOf7Days = newCurrentRangeOf7Days;
+}
+
+- (NSArray *) currentRangeOf7Days
+{
+  return currentRangeOf7Days;
+}
+
+- (NSString *) labelForCurrentDayCell
+{
+  NSCalendarDate *lastDayOfMonth;
+  NSString *label, *monthOfYear;
+  int dayOfMonth;
+
+  dayOfMonth = [currentTableDay dayOfMonth];
+  lastDayOfMonth = [currentTableDay lastDayOfMonth];
+  if (dayOfMonth == 1
+      || [currentTableDay isDateOnSameDay: lastDayOfMonth])
+    {
+      monthOfYear
+        = [dateFormatter shortMonthOfYear: [currentTableDay monthOfYear]];
+      label = [NSString stringWithFormat: @"%d %@", dayOfMonth, monthOfYear];
+    }
+  else
+    label = [NSString stringWithFormat: @"%d", dayOfMonth];
+
+  return label;
+}
+
+- (NSString *) dayCellClasses
+{
+  NSMutableString *classes;
+  NSCalendarDate *selectedDate;
+  int dayOfWeek;
+
+  classes = [NSMutableString new];
+  [classes autorelease];
+  [classes appendString: @"day"];
+  dayOfWeek = [currentTableDay dayOfWeek];
+  if (dayOfWeek == 0 || dayOfWeek == 6)
+    [classes appendString: @" weekEndDay"];
+  selectedDate = [self selectedDate];
+  if (![[currentTableDay firstDayOfMonth]
+         isDateOnSameDay: [selectedDate firstDayOfMonth]])
+    [classes appendString: @" dayOfAnotherMonth"];
+  if ([currentTableDay isToday])
+    [classes appendString: @" dayOfToday"];
+  if ([selectedDate isDateOnSameDay: currentTableDay])
+    [classes appendString: @" selectedDay"];
+
+  return classes;
+}
+
+- (NSArray *) _rangeOf7DaysForWeekStartingOn: (NSCalendarDate *) weekStart
+{
+  unsigned int count;
+  NSMutableArray *range;
+  NSCalendarDate *currentDate;
+
+  range = [NSMutableArray arrayWithCapacity: 7];
+  currentDate = weekStart;
+  for (count = 0; count < 7; count++)
+    {
+      [range addObject: currentDate];
+      currentDate = [currentDate dateByAddingYears: 0 months: 0 days: 1];
+    }
+
+  return range;
+}
+
+- (NSCalendarDate *) startDate
+{
+  NSCalendarDate *firstDayOfMonth;
+
+  firstDayOfMonth = [[self selectedDate] firstDayOfMonth];
+
+  return [firstDayOfMonth mondayOfWeek];
+}
+
+- (NSCalendarDate *) endDate
+{
+  NSCalendarDate *lastDayOfMonth;
+
+  lastDayOfMonth = [[self selectedDate] lastDayOfMonth];
+
+  return [[lastDayOfMonth mondayOfWeek] dateByAddingYears: 0 months: 0 days: 6];
+}
+
+- (NSArray *) rangesOf7Days
+{
+  NSCalendarDate *currentDate, *firstDayOfMonth, *lastDayOfMonth;
+  NSMutableArray *rangesOf7Days;
+  NSArray *currentRange;
+  int monthOfYear;
+
+  rangesOf7Days = [NSMutableArray new];
+  [rangesOf7Days autorelease];
+
+  firstDayOfMonth = [[self selectedDate] firstDayOfMonth];
+  lastDayOfMonth = [firstDayOfMonth lastDayOfMonth];
+  currentDate = [firstDayOfMonth mondayOfWeek];
+  currentRange = [self _rangeOf7DaysForWeekStartingOn: currentDate];
+  [rangesOf7Days addObject: currentRange];
+
+  currentDate = [[currentRange objectAtIndex: 6] dateByAddingYears: 0
+                                                 months: 0 days: 1];
+  monthOfYear = [currentDate monthOfYear];
+  while ([currentDate monthOfYear] == monthOfYear)
+    {
+      currentRange = [self _rangeOf7DaysForWeekStartingOn: currentDate];
+      [rangesOf7Days addObject: currentRange];
+      currentDate = [[currentRange objectAtIndex: 6] dateByAddingYears: 0
+                                                     months: 0 days: 1];
+    }
+
+  return rangesOf7Days;
+}
+
+- (NSArray *) aptsForCurrentDate
+{
+  return [sortedAppointments objectForKey: [currentTableDay shortDateString]];
 }
 
-@end /* UIxCalMonthView */
+@end
diff --git a/UI/Scheduler/UIxCalMonthViewOld.h b/UI/Scheduler/UIxCalMonthViewOld.h
new file mode 100644 (file)
index 0000000..85db06d
--- /dev/null
@@ -0,0 +1,23 @@
+// $Id: UIxCalMonthView.h 163 2004-08-02 12:59:28Z znek $
+
+#ifndef __SOGo_UIxCalMonthViewOld_H__
+#define __SOGo_UIxCalMonthViewOld_H__
+
+#include "UIxCalView.h"
+
+/*
+  UIxCalMonthView
+  
+  Abstract superclass for views which display months.
+*/
+
+@interface UIxCalMonthViewOld : UIxCalView
+
+- (NSCalendarDate *) startOfMonth;
+
+- (NSDictionary *) prevMonthQueryParameters;
+- (NSDictionary *) nextMonthQueryParameters;
+
+@end
+
+#endif /* __SOGo_UIxCalMonthViewOld_H__ */
diff --git a/UI/Scheduler/UIxCalMonthViewOld.m b/UI/Scheduler/UIxCalMonthViewOld.m
new file mode 100644 (file)
index 0000000..e681b63
--- /dev/null
@@ -0,0 +1,45 @@
+// $Id: UIxCalMonthView.m 191 2004-08-12 16:28:32Z helge $
+
+#include <SOGo/NSCalendarDate+SOGo.h>
+#include "UIxCalMonthViewOld.h"
+#include "common.h"
+
+@implementation UIxCalMonthViewOld
+
+- (NSCalendarDate *)startOfMonth {
+  return [[[super startDate] firstDayOfMonth] beginOfDay];
+}
+
+- (NSCalendarDate *)startDate {
+  return [[self startOfMonth] mondayOfWeek];
+}
+
+- (NSCalendarDate *)endDate {
+  NSCalendarDate *date;
+  
+  date = [self startOfMonth];
+  date = [date dateByAddingYears:0 months:0 days:[date numberOfDaysInMonth]
+               hours:0 minutes:0 seconds:0];
+  date = [[date sundayOfWeek] endOfDay];
+  return date;
+}
+
+/* URLs */
+
+- (NSDictionary *)prevMonthQueryParameters {
+  NSCalendarDate *date;
+
+  date = [[self startOfMonth] dateByAddingYears:0 months:-1 days:0
+                             hours:0 minutes:0 seconds:0];
+  return [self queryParametersBySettingSelectedDate:date];
+}
+
+- (NSDictionary *)nextMonthQueryParameters {
+  NSCalendarDate *date;
+    
+  date = [[self startOfMonth] dateByAddingYears:0 months:1 days:0
+                             hours:0 minutes:0 seconds:0];
+  return [self queryParametersBySettingSelectedDate:date];
+}
+
+@end /* UIxCalMonthView */
index 2796b2c05ca737907c79db082b63b3f50f1c9577..361edf6fe05c3a0f887f6ff0bf5eefaafe617696 100644 (file)
@@ -31,7 +31,7 @@
 
 @end
 
-#include <NGiCal/NGiCal.h> /* for iCalPersonPartStat */
+#include <NGCards/NGCards.h> /* for iCalPersonPartStat */
 #include "common.h"
 
 @implementation UIxCalParticipationStatusView
index 3b230aed3a82cc9bccd5d4b6021dac8868e5bcc0..5fe7a0f38112aaaf945a3e1944be7bd51c84fe54 100644 (file)
   return self->foreignApts;
 }
 
-- (void)fetchInfos {
+- (void) fetchInfos {
   static NSArray *orders = nil;
   id       aptFolder;
   NSArray  *apts;
   }
 
   aptFolder = [self clientObject];
-  apts      = [aptFolder fetchCoreInfosFrom:[self startDate]
-                         to:[self endDate]];
+  apts      = [aptFolder fetchCoreInfosFrom: [self startDate]
+                         to: [self endDate]
+                         component: @"vevent"];
   userEmail = [self emailForUser];
   count     = [apts count];
 
index ea97c4a57c7293a657f952f3b030b6122ffaf6fe..f77e7b3f43a3a800d2d6dfcff3f1e424ccc681f6 100644 (file)
@@ -52,7 +52,7 @@
 }
 
 - (void)setCurrentDate:(NSCalendarDate *)_date {
-    [_date setTimeZone:[self viewTimeZone]];
+    [_date setTimeZone:[[self clientObject] userTimeZone]];
     ASSIGN(self->currentDate, _date);
 }
 
diff --git a/UI/Scheduler/UIxCalTasksListView.h b/UI/Scheduler/UIxCalTasksListView.h
new file mode 100644 (file)
index 0000000..dd1ab3f
--- /dev/null
@@ -0,0 +1,46 @@
+/* UIxCalTasksListView.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCALTASKSLISTVIEW_H
+#define UIXCALTASKSLISTVIEW_H
+
+#import "UIxCalView.h"
+
+@class NSDictionary;
+
+@interface UIxCalTasksListView : UIxCalView
+{
+  NSCalendarDate *startDate;
+  NSCalendarDate *endDate;
+
+  BOOL knowsToHide;
+  BOOL hideCompleted;
+
+  NSDictionary *currentTask;
+}
+
+- (void) setCurrentTask: (NSDictionary *) task;
+- (NSDictionary *) currentTask;
+
+@end
+
+#endif /* UIXCALTASKSLIST_H */
diff --git a/UI/Scheduler/UIxCalTasksListView.m b/UI/Scheduler/UIxCalTasksListView.m
new file mode 100644 (file)
index 0000000..a939a76
--- /dev/null
@@ -0,0 +1,136 @@
+/* UIxCalTasksListView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSDate.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSValue.h>
+
+#import <NGExtensions/NSCalendarDate+misc.h>
+#import <Appointments/SOGoAppointmentFolder.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+
+#import "UIxCalTasksListView.h"
+
+@implementation UIxCalTasksListView
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      startDate = nil;
+      endDate = nil;
+      knowsToHide = NO;
+      hideCompleted = NO;
+    }
+
+  return self;
+}
+
+- (void) setCurrentTask: (NSDictionary *) task
+{
+  currentTask = task;
+}
+
+- (NSDictionary *) currentTask
+{
+  return currentTask;
+}
+
+- (NSCalendarDate *) startDate
+{
+  return nil;
+}
+
+- (NSCalendarDate *) endDate
+{
+  return nil;
+}
+
+- (NSString *) currentStatusClass
+{
+  NSCalendarDate *taskDate, *now;
+  NSString *statusClass, *allClasses;
+  NSNumber *taskDueStamp;
+
+  if ([[currentTask objectForKey: @"status"] intValue] == 1)
+    statusClass = @"completed";
+  else
+    {
+      taskDueStamp = [currentTask objectForKey: @"enddate"];
+      if ([taskDueStamp intValue])
+        {
+          now = [NSCalendarDate calendarDate];
+          taskDate = [NSCalendarDate dateWithTimeIntervalSince1970:
+                                       [taskDueStamp intValue]];
+          if ([taskDate earlierDate: now] == taskDate)
+            statusClass = @"overdue";
+          else
+            {
+              if ([taskDate isToday])
+                statusClass = @"duetoday";
+              else
+                statusClass = @"duelater";
+            }
+        }
+      else
+        statusClass = @"duelater";
+    }
+
+  allClasses = [NSString stringWithFormat: @"%@ ownerIs%@",
+                         statusClass,
+                         [currentTask objectForKey: @"owner"]];
+
+  return allClasses;
+}
+
+- (BOOL) shouldDisplayCurrentTask
+{
+  if (!knowsToHide)
+    {
+      hideCompleted
+        = [[self queryParameterForKey: @"hide-completed"] intValue];
+      knowsToHide = YES;
+    }
+
+  return !(hideCompleted
+           && [[currentTask objectForKey: @"status"] intValue] == 1);
+}
+
+- (BOOL) shouldHideCompletedTasks
+{
+  if (!knowsToHide)
+    {
+      hideCompleted
+        = [[self queryParameterForKey: @"hide-completed"] intValue];
+      knowsToHide = YES;
+    }
+
+  return hideCompleted;
+}
+
+- (BOOL) isCurrentTaskCompleted
+{
+  return ([[currentTask objectForKey: @"status"] intValue] == 1);
+}
+
+@end
index f0b1a316b270bddd6c0b7237ef854fdaee494992..4195bb2b8c6de4a3dd190ae9ce9d068ee5fbe0fe 100644 (file)
   a SOPE clientObject (which usually is an SOGoAppointmentFolder).
 */
 
-@class NSString, NSArray, NSDictionary, NSCalendarDate, SOGoAptFormatter;
+@class NSString, NSArray, NSDictionary, NSMutableDictionary, NSCalendarDate, SOGoAptFormatter;
+@class SOGoAppointmentFolder;
 
 @interface UIxCalView : UIxComponent
 {
   NSArray          *appointments;
+  NSMutableDictionary *componentsData;
+  NSArray          *tasks;
   NSArray          *allDayApts;
   id               appointment;
   NSCalendarDate   *currentDay;
 
 /* accessors */
 
-- (NSArray *)appointments;
-- (void)setAppointments:(NSArray *)_apts;
+- (NSArray *) appointments;
+- (void) setAppointments: (NSArray *) _apts;
+
+- (void) setTasks: (NSArray *) _tasks;
+- (NSArray *) tasks;
 
 - (NSArray *)allDayApts;
 - (id)appointment;
@@ -63,7 +69,6 @@
 
 - (id)holidayInfo;
 
-
 /* related to current day */
 - (void)setCurrentDay:(NSCalendarDate *)_day;
 - (NSCalendarDate *)currentDay;
@@ -86,7 +91,8 @@
 
 - (NSCalendarDate *)startDate;
 - (NSCalendarDate *)endDate;
-- (NSArray *)fetchCoreInfos;
+- (NSArray *) fetchCoreAppointmentsInfos;
+- (NSArray *) fetchCoreTasksInfos;
 
 /* date selection */
 
 /* calendarUIDs */
 
 - (NSString *)formattedCalendarUIDs;
+- (SOGoAppointmentFolder *) calendarFolderForUID: (NSString *) uid;
 
 /* CSS related */
 
 - (NSString *)aptStyle;
 
+/* protected methods */
+- (NSDictionary *) _dateQueryParametersWithOffset: (int) daysOffset;
+
 @end
 
 #endif /* __SOGo_UIxCalView_H__ */
index 9f99b6bd6f111be7cb960de2f947c4d7760cc715..9a0c74d4ec5ff9c466cdbd2f89a1204445ef4c92 100644 (file)
 // $Id$
 
-#include "UIxCalView.h"
-#include "common.h"
-//#include <OGoContentStore/OCSFolder.h>
-#include "SoObjects/Appointments/SOGoAppointmentFolder.h"
-#include <NGObjWeb/SoUser.h>
-#include <SOGoUI/SOGoAptFormatter.h>
-#include <NGExtensions/NGCalendarDateRange.h>
-#include <NGiCal/NGiCal.h>
-#include "UIxComponent+Agenor.h"
+#import "common.h"
+//#import <OGoContentStore/OCSFolder.h>
+
+#import <NGObjWeb/SoSecurityManager.h>
+#import <NGObjWeb/SoUser.h>
+#import <NGExtensions/NGCalendarDateRange.h>
+#import <NGCards/NGCards.h>
+
+#import <SOGoUI/SOGoAptFormatter.h>
+#import "UIxComponent+Agenor.h"
+
+#import "SoObjects/Appointments/SOGoAppointmentFolder.h"
+#import <SOGo/SOGoUser.h>
+#import <SOGo/SOGoObject.h>
+
+#import "UIxCalView.h"
 
 @interface UIxCalView (PrivateAPI)
-- (NSString *)_userFolderURI;
+- (NSString *) _userFolderURI;
 @end
 
 @implementation UIxCalView
 
 static BOOL shouldDisplayWeekend = NO;
 
-+ (void)initialize {
-  static BOOL    didInit = NO;
++ (void) initialize
+{
+  static BOOL didInit = NO;
   NSUserDefaults *ud;
 
   if (didInit) return;
 
-  ud                   = [NSUserDefaults standardUserDefaults];
-  shouldDisplayWeekend = [ud boolForKey:@"SOGoShouldDisplayWeekend"];
+  ud = [NSUserDefaults standardUserDefaults];
+  shouldDisplayWeekend = [ud boolForKey: @"SOGoShouldDisplayWeekend"];
+  didInit = YES;
 }
 
-- (id)init {
+- (id) init
+{
   self = [super init];
-  if(self) {
-    NSTimeZone *tz;
-
-    tz = [self viewTimeZone];
-    self->aptFormatter =
-      [[SOGoAptFormatter alloc] initWithDisplayTimeZone:tz];
-    self->aptTooltipFormatter =
-      [[SOGoAptFormatter alloc] initWithDisplayTimeZone:tz];
-    self->privateAptFormatter =
-      [[SOGoAptFormatter alloc] initWithDisplayTimeZone:tz];
-    self->privateAptTooltipFormatter =
-      [[SOGoAptFormatter alloc] initWithDisplayTimeZone:tz];
-    [self configureFormatters];
-  }
+  if (self)
+    {
+      NSTimeZone *tz;
+
+      tz = [[self clientObject] userTimeZone];
+      aptFormatter
+        = [[SOGoAptFormatter alloc] initWithDisplayTimeZone: tz];
+      aptTooltipFormatter
+        = [[SOGoAptFormatter alloc] initWithDisplayTimeZone: tz];
+      privateAptFormatter
+        = [[SOGoAptFormatter alloc] initWithDisplayTimeZone: tz];
+      privateAptTooltipFormatter
+        = [[SOGoAptFormatter alloc] initWithDisplayTimeZone: tz];
+      [self configureFormatters];
+      componentsData = [NSMutableDictionary new];
+    }
   return self;
 }
 
-- (void)dealloc {
-  [self->appointments               release];
-  [self->allDayApts                 release];
-  [self->appointment                release];
-  [self->currentDay                 release];
-  [self->aptFormatter               release];
-  [self->aptTooltipFormatter        release];
-  [self->privateAptFormatter        release];
-  [self->privateAptTooltipFormatter release];
+- (void) dealloc
+{
+  [componentsData release];
+  [appointments               release];
+  [allDayApts                 release];
+  [appointment                release];
+  [currentDay                 release];
+  [aptFormatter               release];
+  [aptTooltipFormatter        release];
+  [privateAptFormatter        release];
+  [privateAptTooltipFormatter release];
   [super dealloc];
 }
 
 /* subclasses should override this */
-- (void)configureFormatters {
+- (void) configureFormatters
+{
   NSString *title;
 
-  [self->aptFormatter setFullDetails];
-  [self->aptTooltipFormatter setTooltip];
-  [self->privateAptFormatter setPrivateDetails];
-  [self->privateAptTooltipFormatter setPrivateTooltip];
+  [aptFormatter setFullDetails];
+  [aptTooltipFormatter setTooltip];
+  [privateAptFormatter setPrivateDetails];
+  [privateAptTooltipFormatter setPrivateTooltip];
 
-  title = [self labelForKey:@"empty title"];
-  [self->aptFormatter setTitlePlaceholder:title];
-  [self->aptTooltipFormatter setTitlePlaceholder:title];
+  title = [self labelForKey: @"empty title"];
+  [aptFormatter setTitlePlaceholder: title];
+  [aptTooltipFormatter setTitlePlaceholder: title];
 
-  title = [self labelForKey:@"private appointment"];
-  [self->privateAptFormatter setPrivateTitle:title];
-  [self->privateAptTooltipFormatter setPrivateTitle:title];
+  title = [self labelForKey: @"private appointment"];
+  [privateAptFormatter setPrivateTitle: title];
+  [privateAptTooltipFormatter setPrivateTitle: title];
 }
 
-- (NSArray *)filterAppointments:(NSArray *)_apts {
+- (NSArray *) filterAppointments:(NSArray *) _apts
+{
   NSMutableArray *filtered;
   unsigned       i, count;
   NSString       *email;
 
-  count    = [_apts count];
+  count = [_apts count];
   if (!count) return _apts;
   if ([self shouldDisplayRejectedAppointments]) return _apts;
 
-  filtered = [[[NSMutableArray alloc] initWithCapacity:count] autorelease];
-  email    = [self emailForUser];
+  filtered = [[[NSMutableArray alloc] initWithCapacity: count] autorelease];
+  email = [self emailForUser];
 
-  for (i = 0; i < count; i++) {
-    NSDictionary *info;
-    NSArray      *partmails;
-    unsigned     p, pCount;
-    BOOL         shouldAdd;
+  for (i = 0; i < count; i++)
+    {
+      NSDictionary *info;
+      NSArray      *partmails;
+      unsigned     p, pCount;
+      BOOL         shouldAdd;
     
-    shouldAdd = YES;
-    info      = [_apts objectAtIndex:i];
-    partmails = [[info objectForKey:@"partmails"]
-                       componentsSeparatedByString:@"\n"];
-    pCount     = [partmails count];
-    for (p = 0; p < pCount; p++) {
-      NSString *pEmail;
-
-      pEmail = [partmails objectAtIndex:p];
-      if ([pEmail isEqualToString:email]) {
-        NSArray  *partstates;
-        NSString *state;
-
-        partstates = [[info objectForKey:@"partstates"]
-                            componentsSeparatedByString:@"\n"];
-        state      = [partstates objectAtIndex:p];
-        if ([state intValue] == iCalPersonPartStatDeclined)
-          shouldAdd = NO;
-        break;
-      }
+      shouldAdd = YES;
+      info = [_apts objectAtIndex: i];
+      partmails = [[info objectForKey: @"partmails"]
+                    componentsSeparatedByString: @"\n"];
+      pCount = [partmails count];
+      for (p = 0; p < pCount; p++)
+        {
+          NSString *pEmail;
+
+          pEmail = [partmails objectAtIndex: p];
+          if ([pEmail isEqualToString: email])
+            {
+              NSArray  *partstates;
+              NSString *state;
+
+              partstates = [[info objectForKey: @"partstates"]
+                             componentsSeparatedByString: @"\n"];
+              state = [partstates objectAtIndex: p];
+              if ([state intValue] == iCalPersonPartStatDeclined)
+                shouldAdd = NO;
+              break;
+            }
+        }
+      if (shouldAdd)
+        [filtered addObject: info];
     }
-    if (shouldAdd)
-      [filtered addObject:info];
-  }
   return filtered;
 }
 
 /* accessors */
 
-- (void)setAppointments:(NSArray *)_apts {
-  _apts = [self filterAppointments:_apts];
-  ASSIGN(self->appointments, _apts);
+- (void) setAppointments:(NSArray *) _apts
+{
+  _apts = [self filterAppointments: _apts];
+  ASSIGN(appointments, _apts);
 }
-- (NSArray *)appointments {
-  return self->appointments;
+
+- (NSArray *) appointments
+{
+  return appointments;
 }
 
-- (void)setAppointment:(id)_apt {
+- (void) setAppointment:(id) _apt
+{
   NSString *mailtoChunk;
   NSString *myEmail;
 
-  ASSIGN(self->appointment, _apt);
+  ASSIGN(appointment, _apt);
 
   /* cache some info about apt for faster access */
   
-  mailtoChunk = [_apt valueForKey:@"orgmail"];
-  myEmail     = [self emailForUser];
-  if ([mailtoChunk rangeOfString:myEmail].length > 0) {
-    self->aptFlags.isMyApt      = YES;
-    self->aptFlags.canAccessApt = YES;
-  }
-  else {
-    NSString *partmails;
+  mailtoChunk = [_apt valueForKey: @"orgmail"];
+  myEmail = [self emailForUser];
+  if ([mailtoChunk rangeOfString: myEmail].length > 0)
+    {
+      aptFlags.isMyApt = YES;
+      aptFlags.canAccessApt = YES;
+    }
+  else
+    {
+      NSString *partmails;
+
+      aptFlags.isMyApt = NO;
+
+      partmails = [_apt valueForKey: @"partmails"];
+      if ([partmails rangeOfString: myEmail].length)
+        aptFlags.canAccessApt = YES;
+      else
+        aptFlags.canAccessApt = [[_apt valueForKey: @"ispublic"] boolValue];
+    }
+}
 
-    self->aptFlags.isMyApt = NO;
+- (void) setTasks: (NSArray *) _tasks
+{
+  ASSIGN(tasks, _tasks);
+}
 
-    partmails = [_apt valueForKey:@"partmails"];
-    if ([partmails rangeOfString:myEmail].length)
-      self->aptFlags.canAccessApt = YES;
-    else
-      self->aptFlags.canAccessApt = [[_apt valueForKey:@"ispublic"] boolValue];
-  }
+- (NSArray *) tasks
+{
+  return tasks;
 }
-- (id)appointment {
-  return self->appointment;
+
+- (id) appointment
+{
+  return appointment;
 }
 
-- (BOOL)isMyApt {
-  return self->aptFlags.isMyApt ? YES : NO;
+- (BOOL) isMyApt
+{
+  return aptFlags.isMyApt ? YES : NO;
 }
 
-- (BOOL)canAccessApt {
-  return self->aptFlags.canAccessApt ? YES : NO;
+- (BOOL) canAccessApt
+{
+  return aptFlags.canAccessApt ? YES : NO;
 }
 
-- (BOOL)canNotAccessApt {
-  return self->aptFlags.canAccessApt ? NO : YES;
+- (BOOL) canNotAccessApt
+{
+  return aptFlags.canAccessApt ? NO : YES;
 }
 
-- (NSDictionary *)aptTypeDict {
+- (NSDictionary *) aptTypeDict
+{
   return nil;
 }
-- (NSString *)aptTypeLabel {
+- (NSString *) aptTypeLabel
+{
   return @"aptLabel";
 }
-- (NSString *)aptTypeIcon {
+- (NSString *) aptTypeIcon
+{
   return @"";
 }
 
-- (SOGoAptFormatter *)aptFormatter {
-  if(self->aptFlags.canAccessApt)
-    return self->aptFormatter;
-  return self->privateAptFormatter;
+- (SOGoAptFormatter *) aptFormatter
+{
+  if (aptFlags.canAccessApt)
+    return aptFormatter;
+  return privateAptFormatter;
 }
 
-- (SOGoAptFormatter *)aptTooltipFormatter {
-  if(self->aptFlags.canAccessApt)
-    return self->aptTooltipFormatter;
-  return self->privateAptTooltipFormatter;
+- (SOGoAptFormatter *) aptTooltipFormatter
+{
+  if (aptFlags.canAccessApt)
+    return aptTooltipFormatter;
+  return privateAptTooltipFormatter;
 }
 
 /* TODO: remove this */
-- (NSString *)shortTextForApt {
-  [self warnWithFormat:@"%s IS DEPRECATED!", __PRETTY_FUNCTION__];
+- (NSString *) shortTextForApt
+{
+  [self warnWithFormat: @"%s IS DEPRECATED!", __PRETTY_FUNCTION__];
   if (![self canAccessApt])
     return @"";
-  return [[self aptFormatter] stringForObjectValue:self->appointment];
+  return [[self aptFormatter] stringForObjectValue: appointment];
 }
 
-- (NSString *)shortTitleForApt {
+- (NSString *) shortTitleForApt
+{
   NSString *title;
 
-  [self warnWithFormat:@"%s IS DEPRECATED!", __PRETTY_FUNCTION__];
+  [self warnWithFormat: @"%s IS DEPRECATED!", __PRETTY_FUNCTION__];
 
   if (![self canAccessApt])
     return @"";
-  title = [self->appointment valueForKey:@"title"];
+  title = [appointment valueForKey: @"title"];
   if ([title length] > 12)
-    title = [[title substringToIndex:11] stringByAppendingString:@"..."];
+    title = [[title substringToIndex: 11] stringByAppendingString: @"..."];
   
   return title;
 }
 
-- (NSString *)tooltipForApt {
-  [self warnWithFormat:@"%s IS DEPRECATED!", __PRETTY_FUNCTION__];
-  return [[self aptTooltipFormatter] stringForObjectValue:self->appointment
-                                     referenceDate:[self currentDay]];
+- (NSString *) tooltipForApt
+{
+  [self warnWithFormat: @"%s IS DEPRECATED!", __PRETTY_FUNCTION__];
+  return [[self aptTooltipFormatter] stringForObjectValue: appointment
+                                     referenceDate: [self currentDay]];
 }
 
-- (NSString *)aptStyle {
+- (NSString *) aptStyle
+{
   return nil;
 }
 
-- (NSCalendarDate *)referenceDateForFormatter {
+- (NSCalendarDate *) referenceDateForFormatter
+{
   return [self selectedDate];
 }
 
-- (NSCalendarDate *)thisMonth {
+- (NSCalendarDate *) thisMonth
+{
   return [self selectedDate];
 }
 
-- (NSCalendarDate *)nextMonth {
+- (NSCalendarDate *) nextMonth
+{
+  NSCalendarDate *date = [self thisMonth];
+  return [date dateByAddingYears: 0 months: 1 days: 0
+               hours: 0 minutes: 0 seconds: 0];
+}
+
+- (NSCalendarDate *) prevMonth
+{
   NSCalendarDate *date = [self thisMonth];
-  return [date dateByAddingYears:0 months:1 days:0
-              hours:0 minutes:0 seconds:0];
+  return [date dateByAddingYears: 0 months:-1 days: 0
+               hours: 0 minutes: 0 seconds: 0];
 }
 
+- (NSString *) prevMonthAsString
+{
+  return [self dateStringForDate: [self prevMonth]];
+}
+
+- (NSString *) nextMonthAsString
+{
+  return [self dateStringForDate: [self nextMonth]];
+}
 
 /* current day related */
 
-- (void)setCurrentDay:(NSCalendarDate *)_day {
-  [_day setTimeZone:[self viewTimeZone]];
-  ASSIGN(self->currentDay, _day);
+- (void) setCurrentDay:(NSCalendarDate *) _day
+{
+  [_day setTimeZone: [[self clientObject] userTimeZone]];
+  ASSIGN(currentDay, _day);
 }
-- (NSCalendarDate *)currentDay {
-  return self->currentDay;
+
+- (NSCalendarDate *) currentDay
+{
+  return currentDay;
 }
 
-- (NSString *)currentDayName {
-  return [self localizedNameForDayOfWeek:[self->currentDay dayOfWeek]];
+- (NSString *) currentDayName
+{
+  return [self localizedNameForDayOfWeek: [currentDay dayOfWeek]];
 }
 
-- (id)holidayInfo {
+- (id) holidayInfo
+{
   return nil;
 }
 
-- (NSArray *)allDayApts {
+- (NSArray *) allDayApts
+{
   NSArray        *apts;
   NSMutableArray *filtered;
   unsigned       i, count;
 
-  if (self->allDayApts)
-    return self->allDayApts;
-
-  apts     = [self appointments];
-  count    = [apts count];
-  filtered = [[NSMutableArray alloc] initWithCapacity:3];
-  for (i = 0; i < count; i++) {
-    id       apt;
-    NSNumber *bv;
-
-    apt = [apts objectAtIndex:i];
-    bv  = [apt valueForKey:@"isallday"];
-    if ([bv boolValue])
-      [filtered addObject:apt];
-  }
+  if (allDayApts)
+    return allDayApts;
+
+  apts = [self appointments];
+  count = [apts count];
+  filtered = [[NSMutableArray alloc] initWithCapacity: 3];
+  for (i = 0; i < count; i++)
+    {
+      id       apt;
+      NSNumber *bv;
+
+      apt = [apts objectAtIndex: i];
+      bv = [apt valueForKey: @"isallday"];
+      if ([bv boolValue])
+        [filtered addObject: apt];
+    }
     
-  ASSIGN(self->allDayApts, filtered);
+  ASSIGN(allDayApts, filtered);
   [filtered release];
-  return self->allDayApts;
+  return allDayApts;
 }
 
 
 /* special appointments */
 
-- (BOOL)hasDayInfo {
+- (BOOL) hasDayInfo
+{
   return [self hasHoldidayInfo] || [self hasAllDayApts];
 }
 
-- (BOOL)hasHoldidayInfo {
+- (BOOL) hasHoldidayInfo
+{
   return [self holidayInfo] != nil;
 }
 
-- (BOOL)hasAllDayApts {
+- (BOOL) hasAllDayApts
+{
   return [[self allDayApts] count] != 0;
 }
 
 
 /* defaults */
 
-- (BOOL)showFullNames {
+- (BOOL) showFullNames
+{
   return YES;
 }
 
-- (BOOL)showAMPMDates {
+- (BOOL) showAMPMDates
+{
   return NO;
 }
 
-- (unsigned)dayStartHour {
-  return 8;
+- (unsigned) dayStartHour
+{
+  return 0;
 }
 
-- (unsigned)dayEndHour {
-  return 18;
+- (unsigned) dayEndHour
+{
+  return 24;
 }
 
-- (BOOL)shouldDisplayWeekend {
+- (BOOL) shouldDisplayWeekend
+{
   return shouldDisplayWeekend;
 }
 
-- (BOOL)shouldHideWeekend {
+- (BOOL) shouldHideWeekend
+{
   return ![self shouldDisplayWeekend];
 }
 
 
 /* URLs */
 
-- (NSString *)appointmentViewURL {
+- (NSString *) appointmentViewURL
+{
   id pkey;
   
-  if (![(pkey = [[self appointment] valueForKey:@"uid"]) isNotNull])
+  if (![(pkey = [[self appointment] valueForKey: @"uid"]) isNotNull])
     return nil;
   
-  return [[[self clientObject] baseURLForAptWithUID:[pkey stringValue]
-                              inContext:[self context]]
-                              stringByAppendingString:@"/view"];
+  return [[[self clientObject] baseURLForAptWithUID: [pkey stringValue]
+                               inContext: [self context]]
+           stringByAppendingString: @"/view"];
 }
 
 /* fetching */
 
-- (NSCalendarDate *)startDate {
+- (NSCalendarDate *) startDate
+{
   return [self selectedDate];
 }
-- (NSCalendarDate *)endDate {
+
+- (NSCalendarDate *) endDate
+{
   return [[self startDate] tomorrow];
 }
 
-- (NSArray *)fetchCoreInfos {
-  if (!self->appointments) {
-    id             folder;
-    NSCalendarDate *sd, *ed;
+- (SOGoAppointmentFolder *) calendarFolderForUID: (NSString *) uid
+{
+  SOGoFolder *upperContainer;
+  SOGoUserFolder *userFolder;
+  SOGoAppointmentFolder *calendarFolder;
+  SoSecurityManager *securityManager;
 
-    folder             = [self clientObject];
-    sd                 = [self startDate];
-    ed                 = [self endDate];
-    [self setAppointments:[folder fetchOverviewInfosFrom:sd to:ed]];
-  }
-  return self->appointments;
+  upperContainer = [[[self clientObject] container] container];
+  userFolder = [SOGoUserFolder objectWithName: uid
+                               inContainer: upperContainer];
+  calendarFolder = [SOGoAppointmentFolder objectWithName: @"Calendar"
+                                         inContainer: userFolder];
+  [calendarFolder
+    setOCSPath: [NSString stringWithFormat: @"/Users/%@/Calendar", uid]];
+  [calendarFolder setOwner: uid];
+
+  securityManager = [SoSecurityManager sharedSecurityManager];
+
+  return (([securityManager validatePermission: SoPerm_AccessContentsInformation
+                            onObject: calendarFolder
+                            inContext: context] == nil)
+          ? calendarFolder : nil);
+}
+
+- (NSArray *) activeCalendarFolders
+{
+  NSUserDefaults *ud;
+  NSEnumerator *calendarUIDs;
+  SOGoAppointmentFolder *currentFolder;
+  NSMutableArray *folders;
+  NSString *currentUID;
+
+  folders = [NSMutableArray array];
+  ud = [[context activeUser] userDefaults];
+  calendarUIDs = [[[ud stringForKey: @"calendaruids"]
+                    componentsSeparatedByString: @","] objectEnumerator];
+  currentUID = [calendarUIDs nextObject];
+  while (currentUID)
+    {
+      if (![currentUID hasPrefix: @"-"])
+        {
+          currentFolder = [self calendarFolderForUID: currentUID];
+          if (currentFolder)
+            [folders addObject: currentFolder];
+        }
+      currentUID = [calendarUIDs nextObject];
+    }
+
+  return folders;
+}
+
+- (NSArray *) _fetchCoreInfosForComponent: (NSString *) component
+{
+  NSArray *currentInfos;
+  NSMutableArray *infos;
+  NSEnumerator *folders;
+  SOGoAppointmentFolder *currentFolder;
+
+  infos = [componentsData objectForKey: component];
+  if (!infos)
+    {
+      infos = [NSMutableArray array];
+      folders = [[self activeCalendarFolders] objectEnumerator];
+      currentFolder = [folders nextObject];
+      while (currentFolder)
+        {
+          currentInfos = [currentFolder fetchCoreInfosFrom: [[self startDate] beginOfDay]
+                                        to: [[self endDate] endOfDay]
+                                        component: component];
+          [currentInfos makeObjectsPerform: @selector (setObject:forKey:)
+                        withObject: [currentFolder ownerInContext: nil]
+                        withObject: @"owner"];
+          [infos addObjectsFromArray: currentInfos];
+          currentFolder = [folders nextObject];
+        }
+      [componentsData setObject: infos forKey: component];
+    }
+
+  return infos;
+}
+
+- (NSArray *) fetchCoreAppointmentsInfos
+{
+  if (!appointments)
+    [self setAppointments: [self _fetchCoreInfosForComponent: @"vevent"]];
+  
+  return appointments;
+}
+
+- (NSArray *) fetchCoreTasksInfos
+{
+  if (!tasks)
+    [self setTasks: [self _fetchCoreInfosForComponent: @"vtodo"]];
+  
+  return tasks;
 }
 
 /* query parameters */
 
-- (BOOL)shouldDisplayRejectedAppointments {
+- (BOOL) shouldDisplayRejectedAppointments
+{
   NSString *bv;
   
-  bv = [[[self context] request] formValueForKey:@"dr"];
+  bv = [self queryParameterForKey: @"dr"];
   if (!bv) return NO;
   return [bv boolValue];
 }
 
-- (NSDictionary *)toggleShowRejectedAptsQueryParameters {
+- (NSDictionary *) toggleShowRejectedAptsQueryParameters
+{
   NSMutableDictionary *qp;
   BOOL                shouldDisplay;
   
   shouldDisplay = ![self shouldDisplayRejectedAppointments];
   qp = [[[self queryParameters] mutableCopy] autorelease];
-  [qp setObject:shouldDisplay ? @"1" : @"0" forKey:@"dr"];
+  [qp setObject: shouldDisplay ? @"1" : @"0" forKey: @"dr"];
   return qp;
 }
 
-- (NSString *)toggleShowRejectedAptsLabel {
+- (NSString *) toggleShowRejectedAptsLabel
+{
   if (![self shouldDisplayRejectedAppointments])
     return @"show_rejected_apts";
   return @"hide_rejected_apts";
@@ -393,99 +568,114 @@ static BOOL shouldDisplayWeekend = NO;
 
 /* date selection & conversion */
 
-- (NSDictionary *)todayQueryParameters {
+- (NSDictionary *) _dateQueryParametersWithOffset: (int) daysOffset
+{
   NSCalendarDate *date;
-    
-  date = [NSCalendarDate date]; /* today */
-  return [self queryParametersBySettingSelectedDate:date];
+  
+  date = [[self startDate] dateByAddingYears: 0 months: 0
+                           days: daysOffset
+                           hours: 0 minutes: 0 seconds: 0];
+  return [self queryParametersBySettingSelectedDate: date];
+}
+
+- (NSDictionary *) todayQueryParameters
+{
+  return [self queryParametersBySettingSelectedDate: [NSCalendarDate date]];
 }
 
-- (NSDictionary *)currentDayQueryParameters {
-  return [self queryParametersBySettingSelectedDate:self->currentDay];
+- (NSDictionary *) currentDayQueryParameters
+{
+  return [self queryParametersBySettingSelectedDate: currentDay];
 }
 
 /* calendarUIDs */
 
-- (NSString *)formattedCalendarUIDs {
-    return [[[self clientObject] calendarUIDs]
-                                 componentsJoinedByString:@", "];
+- (NSString *) formattedCalendarUIDs
+{
+  return [[[self clientObject] calendarUIDs]
+           componentsJoinedByString: @", "];
 }
 
 /* Actions */
 
-- (NSString *)_userFolderURI {
+- (NSString *) _userFolderURI
+{
   WOContext *ctx;
   id        obj;
   NSURL     *url;
 
   ctx = [self context];
-  obj = [[ctx objectTraversalStack] objectAtIndex:1];
-  url = [NSURL URLWithString:[obj baseURLInContext:ctx]];
+  obj = [[ctx objectTraversalStack] objectAtIndex: 1];
+  url = [NSURL URLWithString: [obj baseURLInContext: ctx]];
   return [[url path] stringByUnescapingURL];
 }
 
-- (id)redirectForUIDsAction {
+- (id) redirectForUIDsAction
+{
   NSMutableString *uri;
-  NSString   *uidsString, *loc, *prevMethod, *userFolderID;
-  WORequest  *req;
+  NSString *uidsString, *loc, *prevMethod, *userFolderID;
   id <WOActionResults> r;
   BOOL useGroups;
   unsigned index;
 
-  req = [[self context] request];
-
-  uidsString = [req formValueForKey:@"userUIDString"];
+  uidsString = [self queryParameterForKey: @"userUIDString"];
   uidsString = [uidsString stringByTrimmingWhiteSpaces];
+  [self setQueryParameter: nil forKey: @"userUIDString"];
 
-  prevMethod = [req formValueForKey:@"previousMethod"];
-  if(prevMethod == nil)
+  prevMethod = [self queryParameterForKey: @"previousMethod"];
+  if (prevMethod == nil)
     prevMethod = @"";
 
-  uri = [[NSMutableString alloc] initWithString:[self _userFolderURI]];
+  uri = [[NSMutableString alloc] initWithString: [self _userFolderURI]];
   /* if we have more than one entry, use groups - otherwise don't */
-  useGroups = [uidsString rangeOfString:@","].length > 0;
+  useGroups = [uidsString rangeOfString: @","].length > 0;
   userFolderID = [uri lastPathComponent];
-  if(useGroups) {
-    NSArray *uids;
-
-    uids = [uidsString componentsSeparatedByString:@","];
-    /* guarantee that our id is the first */
-    if(((index = [uids indexOfObject:userFolderID]) != NSNotFound) &&
-       (index != 0)) {
-        uids = [[uids mutableCopy] autorelease];
-        [(NSMutableArray *)uids removeObjectAtIndex:index];
-        [(NSMutableArray *)uids insertObject:userFolderID atIndex:0];
-        uidsString = [uids componentsJoinedByString:@","];
+  if (useGroups)
+    {
+      NSArray *uids;
+
+      uids = [uidsString componentsSeparatedByString: @","];
+      /* guarantee that our id is the first */
+      if (((index = [uids indexOfObject: userFolderID]) != NSNotFound)
+          && (index != 0))
+        {
+          uids = [[uids mutableCopy] autorelease];
+          [(NSMutableArray *) uids removeObjectAtIndex: index];
+          [(NSMutableArray *) uids insertObject: userFolderID atIndex: 0];
+          uidsString = [uids componentsJoinedByString: @","];
+        }
+      [uri appendString: @"Groups/_custom_"];
+      [uri appendString: uidsString];
+      [uri appendString: @"/"];
+      NSLog (@"Group URI = '%@'", uri);
     }
-    [uri appendString:@"Groups/_custom_"];
-    [uri appendString:uidsString];
-    [uri appendString:@"/"];
-  }
-  else {
+  else
+    {
       /* check if lastPathComponent is the base that we want to have */
-      if((([uidsString length] != 0) &&
-          (![userFolderID isEqualToString:uidsString]))) {
+      if ((([uidsString length] != 0)
+           && (![userFolderID isEqualToString: uidsString])))
+        {
           NSRange r;
           
           /* uri ends with an '/', so we have to adjust the range a little */
           r = NSMakeRange(0, [uri length] - 1);
-          r = [uri rangeOfString:@"/"
-                         options:NSBackwardsSearch
-                           range:r];
+          r = [uri rangeOfString: @"/"
+                   options: NSBackwardsSearch
+                   range: r];
           r = NSMakeRange(r.location + 1, [uri length] - r.location - 2);
-          [uri replaceCharactersInRange:r withString:uidsString];
-      }
-  }
-  [uri appendString:@"Calendar/"];
-  [uri appendString:prevMethod];
+          [uri replaceCharactersInRange: r withString: uidsString];
+        }
+    }
+  [uri appendString: @"Calendar/"];
+  [uri appendString: prevMethod];
 
 #if 0
   NSLog(@"%s redirect uri:%@",
-          __PRETTY_FUNCTION__,
-          uri);
+        __PRETTY_FUNCTION__,
+        uri);
 #endif
-  loc = [self completeHrefForMethod:uri]; /* this might return uri! */
-  r = [self redirectToLocation:loc];
+  loc = [self completeHrefForMethod: uri]; /* this might return uri! */
+  r = [self redirectToLocation: loc];
   [uri release];
   return r;
 }
index e5931b8d134b5fa4b551c4b14c092910739718f7..384e0ea659c9f03a27a9e4b75ab4c1e0cf775372 100644 (file)
 /* NOTE: this fetches coreInfos instead of overviewInfos
  * as is done in the superclass!
  */
-- (NSArray *)fetchCoreInfos {
-  if (!self->appointments) {
-    id             folder;
-    NSCalendarDate *sd, *ed;
+// - (NSArray *)fetchCoreInfos {
+//   if (!self->appointments) {
+//     id             folder;
+//     NSCalendarDate *sd, *ed;
     
-    folder             = [self clientObject];
-    sd                 = [self startDate];
-    ed                 = [self endDate];
-    [self setAppointments:[folder fetchCoreInfosFrom:sd to:ed]];
-  }
-  return self->appointments;
-}
+//     folder             = [self clientObject];
+//     sd                 = [self startDate];
+//     ed                 = [self endDate];
+//     [self setAppointments: [folder fetchCoreAppointmentsInfos]];
+//   }
+//   return self->appointments;
+// }
 
 /* accessors */
 
index d8f16795934cc70f28c65c43cf0978837f326750..0dbeced3cd363a5b7ba507b625b97e23086e9ec2 100644 (file)
 
 @implementation UIxCalWeekOverview
 
+- (id) correctURLAction
+{
+  return [self redirectToLocation: @"weekoverview"];
+}
+
 - (void)configureFormatters {
   [super configureFormatters];
   
diff --git a/UI/Scheduler/UIxCalWeekPrintview.m b/UI/Scheduler/UIxCalWeekPrintview.m
deleted file mode 100644 (file)
index 17d920c..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- Copyright (C) 2004 SKYRIX Software AG
- This file is part of OpenGroupware.org.
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING.  If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
- */
-// $Id$
-
-#include "UIxCalWeekOverview.h"
-
-@interface UIxCalWeekPrintview : UIxCalWeekOverview
-{
-}
-
-@end
-
-#include "common.h"
-
-@implementation UIxCalWeekPrintview
-
-- (NSString *)shortTextForApt {
-  NSCalendarDate  *startDate, *endDate;
-  NSMutableString *aptDescr;
-  NSString        *s;
-  BOOL            isMyApt;
-  BOOL            canAccessApt;
-  BOOL            spansRange;
-  id              apt;
-  
-  apt          = [self appointment];
-  isMyApt      = [self isMyApt];
-  canAccessApt = [self canAccessApt];
-  spansRange   = NO;
-  startDate    = [apt valueForKey:@"startDate"];
-  [startDate setTimeZone:[self viewTimeZone]];
-  endDate      = [apt valueForKey:@"endDate"];
-  if(endDate != nil) {
-    [endDate setTimeZone:[self viewTimeZone]];
-    spansRange = ![endDate isEqualToDate:startDate];
-  }
-  aptDescr = [[NSMutableString alloc] init];
-  [aptDescr appendFormat:@"<span class=\"%@\">%02i:%02i",
-                           isMyApt ? @"weekprintview_apt_time" :
-                                     @"weekprintview_apt_time_other",
-                           [startDate hourOfDay],
-                           [startDate minuteOfHour]];
-  if(spansRange) {
-    [aptDescr appendFormat:@" - %02i:%02i",
-                             [endDate hourOfDay],
-                             [endDate minuteOfHour]];
-  }
-  [aptDescr appendFormat:@"</span>,"];
-  if(!isMyApt)
-    [aptDescr appendFormat:@"<span class=\"%@\">", [self aptStyle]];
-  if (canAccessApt) {
-    s = [apt valueForKey:@"title"];
-    if(s) {
-      [aptDescr appendFormat:@"<br />%@", s];
-    }
-    s = [apt valueForKey:@"location"];
-    if(s) {
-      [aptDescr appendFormat:@"<br />%@", s];
-    }
-  }
-  else {
-    [aptDescr appendFormat:@"<br />%@",
-                             [self labelForKey:@"private appointment"]];
-  }
-
-  if(!isMyApt)
-    [aptDescr appendString:@"</span>"];
-  return [aptDescr autorelease];
-}
-
-- (NSString *)title {
-  NSMutableString *title;
-  NSCalendarDate *date;
-  
-  date  = [self startDate];
-  title = [[NSMutableString alloc] init];
-  [title appendFormat:@"%@ %d",
-    [self localizedNameForMonthOfYear:[date monthOfYear]],
-    [date yearOfCommonEra]];
-  if([date monthOfYear] != [[self endDate] monthOfYear]) {        
-    [title appendFormat:@" / %@ %d",
-      [self localizedNameForMonthOfYear:[[self endDate] monthOfYear]],
-      [[self endDate] yearOfCommonEra]];
-  }
-  [title appendFormat:@", %@ %d",
-    [self labelForKey:@"Week"],
-    [date weekOfYear]];
-  return [title autorelease];
-}
-
-/* style sheet */
-
-- (NSString *)titleStyle {
-  if([self->currentDay isToday])
-    return @"weekoverview_title_hilite";
-  return @"weekoverview_title";
-}
-
-- (NSString *)contentStyle {
-  if([self->currentDay isToday])
-    return @"weekoverview_content_hilite";
-  return @"weekoverview_content";
-}
-
-- (NSString *)aptStyle {
-  if (![self isMyApt])
-    return @"weekprintview_apt_other";
-  return nil;
-}
-
-@end
index df8a196d9a257955f0c2901f47bb0e28b9a86347..83ab8d5a953a44ff92c6eafd419f67658171294a 100644 (file)
@@ -1,4 +1,24 @@
-// $Id$
+/* UIxCalWeekView.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
 #ifndef __SOGo_UIxCalWeekView_H__
 #define __SOGo_UIxCalWeekView_H__
 @class NSDictionary;
 
 @interface UIxCalWeekView : UIxCalView
-{
-}
 
-/* Query Parameters */
+- (NSDictionary *) weekBeforePrevWeekQueryParameters;
+- (NSDictionary *) prevWeekQueryParameters;
+- (NSDictionary *) nextWeekQueryParameters;
+- (NSDictionary *) weekAfterNextWeekQueryParameters;
 
-- (NSDictionary *)prevWeekQueryParameters;
-- (NSDictionary *)nextWeekQueryParameters;
+- (NSString *) weekBeforeLastWeekName;
+- (NSString *) lastWeekName;
+- (NSString *) currentWeekName;
+- (NSString *) nextWeekName;
+- (NSString *) weekAfterNextWeekName;
     
 @end
 
index be5b8897c3821576eccb1af335f41f1a9e91a4c3..ab520323a3b4fd3719e765e446c4e863fa733161 100644 (file)
-// $Id$
+/* UIxCalWeekView.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSKeyValueCoding.h>
+#import <Foundation/NSString.h>
+
+#import <EOControl/EOQualifier.h>
+
+#import <NGExtensions/NSCalendarDate+misc.h>
 
 #include "UIxCalWeekView.h"
-#include "common.h"
 
 @implementation UIxCalWeekView
 
-- (NSCalendarDate *)startDate {
-    return [[[super startDate] mondayOfWeek] beginOfDay];
+- (NSCalendarDate *) startDate
+{
+  return [[[super startDate] mondayOfWeek] beginOfDay];
 }
 
-- (NSCalendarDate *)endDate {
-    unsigned offset;
+- (NSCalendarDate *) endDate
+{
+  unsigned offset;
     
-    if([self shouldDisplayWeekend])
-        offset = 7;
-    else
-        offset = 5;
+  if([self shouldDisplayWeekend])
+    offset = 7;
+  else
+    offset = 5;
+
   return [[[self startDate] dateByAddingYears:0 months:0 days:offset
                             hours:0 minutes:0 seconds:0]
                             endOfDay];
 }
 
-- (NSArray *)appointments {
-  return [self fetchCoreInfos];
+- (NSArray *) appointments
+{
+  return [self fetchCoreAppointmentsInfos];
 }
 
 /* URLs */
 
-- (NSDictionary *)prevWeekQueryParameters {
-  NSCalendarDate *date;
+- (NSDictionary *) weekBeforePrevWeekQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: -14];
+}
 
-  date = [[self startDate] dateByAddingYears:0 months:0 days:-7 
-                          hours:0 minutes:0 seconds:0];
-  return [self queryParametersBySettingSelectedDate:date];
+- (NSDictionary *) prevWeekQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: -7];
 }
 
-- (NSDictionary *)nextWeekQueryParameters {
+- (NSDictionary *) nextWeekQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: 7];
+}
+
+- (NSDictionary *) weekAfterNextWeekQueryParameters
+{
+  return [self _dateQueryParametersWithOffset: 14];
+}
+
+- (NSString *) _weekNumberWithOffsetFromToday: (int) offset
+{
   NSCalendarDate *date;
-    
-  date = [[self startDate] dateByAddingYears:0 months:0 days:7 
-                          hours:0 minutes:0 seconds:0];
-  return [self queryParametersBySettingSelectedDate:date];
+  NSString *format;
+
+  date = [[self startDate] dateByAddingYears: 0 months: 0 days: (offset * 7)
+                           hours:0 minutes: 0 seconds: 0];
+  format = [self labelForKey: @"Week %d"];
+
+  return [NSString stringWithFormat: format, [date weekOfYear]];
+}
+
+- (NSString *) weekBeforeLastWeekName
+{
+  return [self _weekNumberWithOffsetFromToday: -2];
+}
+
+- (NSString *) lastWeekName
+{
+  return [self _weekNumberWithOffsetFromToday: -1];
+}
+
+- (NSString *) currentWeekName
+{
+  return [self _weekNumberWithOffsetFromToday: 0];
+}
+
+- (NSString *) nextWeekName
+{
+  return [self _weekNumberWithOffsetFromToday: 1];
+}
+
+- (NSString *) weekAfterNextWeekName
+{
+  return [self _weekNumberWithOffsetFromToday: 2];
 }
 
 @end /* UIxCalWeekView */
index 207a151e7cbc6936bce9aad0e18c99c94288d594..4ef7f94b34923bf2a8814663d7a4cdfc60e748ee 100644 (file)
@@ -98,7 +98,7 @@
 - (NSCalendarDate *)startDate {
   return [[[NSCalendarDate alloc] initWithYear:[self year] month:1 day:1
                                   hour:0 minute:0 second:0
-                                  timeZone:[self viewTimeZone]] autorelease];
+                                  timeZone:[[self clientObject] userTimeZone]] autorelease];
 }
 - (NSCalendarDate *)endDate {
   return nil;
index 1a0232a878cfe891e6142569bffb8893366dfefb..89544edeb7edcb07ae2271188eb4b56ec8dc31d7 100644 (file)
 #include <SOGoUI/UIxComponent.h>
 
 @interface UIxComponent (Agenor)
+
+- (NSArray *) getICalPersonsFromValue: (NSString *) selectorValue;
+
 /* email, cn */
 - (NSString *)emailForUser;
 - (NSString *)cnForUser;
 
 /* restrictions */
 - (BOOL)isAccessRestricted;
+
 @end
 
 #endif /* __UIxComponent_Agenor_H_ */
index 216dbc02119d4a8336ac54a304d21df24ba96ebf..08320032e55406be039f48a30f8bec89f1292bcf 100644 (file)
 
 @implementation UIxComponent(Agenor)
 
+- (NSArray *) getICalPersonsFromValue: (NSString *) selectorValue
+{
+  NSMutableArray *persons;
+  NSEnumerator *uids;
+  NSString *uid;
+  AgenorUserManager *um;
+
+  um = [AgenorUserManager sharedUserManager];
+
+  persons = [NSMutableArray new];
+  [persons autorelease];
+
+  if ([selectorValue length] > 0)
+    {
+      uids = [[selectorValue componentsSeparatedByString: @","]
+               objectEnumerator];
+      uid = [uids nextObject];
+      while (uid)
+        {
+          [persons addObject: [um iCalPersonWithUid: uid]];
+          uid = [uids nextObject];
+        }
+    }
+
+  return persons;
+}
+
 - (NSString *)emailForUser {
   return [[[self context] activeUser] email];
 }
diff --git a/UI/Scheduler/UIxComponentEditor.h b/UI/Scheduler/UIxComponentEditor.h
new file mode 100644 (file)
index 0000000..b240e9e
--- /dev/null
@@ -0,0 +1,167 @@
+/* UIxComponentEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXCOMPONENTEDITOR_H
+#define UIXCOMPONENTEDITOR_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSArray;
+@class NSCalendarDate;
+@class NSDictionary;
+@class NSFormatter;
+@class NSString;
+
+@class iCalPerson;
+@class iCalRecurrenceRule;
+@class iCalRepeatableEntityObject;
+
+@interface UIxComponentEditor : UIxComponent
+{
+  NSString *iCalString;
+  NSString *errorText;
+  id item;
+  
+  /* individual values */
+  NSCalendarDate *startDate;
+  NSCalendarDate *cycleUntilDate;
+  NSString *title;
+  NSString *location;
+  NSString *comment;
+  NSString *url;
+  iCalPerson *organizer;
+  NSArray *participants;     /* array of iCalPerson's */
+  NSArray *resources;        /* array of iCalPerson's */
+  NSString *priority;
+  NSString *privacy;
+  NSString *status;
+  NSArray *categories;
+  BOOL checkForConflicts; /* default: NO */
+  NSDictionary *cycle;
+  NSString *cycleEnd;
+  NSString *componentOwner;
+
+  BOOL componentLoaded;
+}
+
+- (NSArray *) categoryItems;
+- (void) setCategories: (NSArray *) _categories;
+- (NSArray *) categories;
+- (NSString *) itemCategoryText;
+
+- (NSArray *) priorities;
+- (void) setPriority: (NSString *) _priority;
+- (NSString *) priority;
+- (NSString *) itemPriorityText;
+
+- (NSArray *) privacyClasses;
+- (void) setPrivacy: (NSString *) _privacy;
+- (NSString *) privacy;
+- (NSString *) itemPrivacyText;
+
+- (NSArray *) statusTypes;
+- (void) setStatus: (NSString *) _status;
+- (NSString *) status;
+- (NSString *) itemStatusText;
+
+- (void) setItem: (id) _item;
+- (id) item;
+- (NSString *) itemPriorityText;
+
+- (void) setErrorText: (NSString *) _txt;
+- (NSString *) errorText;
+- (BOOL) hasErrorText;
+
+- (void) setICalString: (NSString *) _s;
+- (NSString *) iCalString;
+
+- (NSCalendarDate *) newStartDate;
+
+- (void) setStartDate: (NSCalendarDate *) _date;
+- (NSCalendarDate *) startDate;
+
+- (void) setTitle: (NSString *) _value;
+- (NSString *) title;
+
+- (void) setLocation: (NSString *) _value;
+- (NSString *) location;
+
+- (void) setComment: (NSString *) _value;
+- (NSString *) comment;
+
+- (void) setUrl: (NSString *) _url;
+- (NSString *) url;
+
+- (void) setParticipants: (NSArray *) _parts;
+- (NSArray *) participants;
+
+- (void) setResources: (NSArray *) _res;
+- (NSArray *) resources;
+
+- (void) setCheckForConflicts: (BOOL) _checkForConflicts;
+- (BOOL) checkForConflicts;
+
+- (NSArray *) cycles;
+- (void) setCycle: (NSDictionary *) _cycle;
+- (NSDictionary *) cycle;
+- (BOOL) hasCycle;
+- (NSString *) cycleLabel;
+- (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate;
+- (NSCalendarDate *) cycleUntilDate;
+- (iCalRecurrenceRule *) rrule;
+- (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule;
+- (NSDictionary *) cycleMatchingRRule: (iCalRecurrenceRule *) _rrule;
+- (NSArray *) cycleEnds;
+- (void) setCycleEnd: (NSString *) _cycleEnd;
+- (NSString *) cycleEnd;
+- (BOOL) isCycleEndUntil;
+- (void) setIsCycleEndUntil;
+- (void) setIsCycleEndNever;
+
+- (NSString *) componentOwner;
+- (NSArray *) availableCalendars;
+
+/* access */
+- (BOOL) isMyComponent;
+- (BOOL) canEditComponent;
+
+/* helpers */
+- (NSFormatter *) titleDateFormatter;
+- (NSString *) completeURIForMethod: (NSString *) _method;
+- (BOOL) isWriteableClientObject;
+- (NSException *) validateObjectForStatusChange;
+
+/* subclasses */
+- (void) loadValuesFromComponent: (iCalRepeatableEntityObject *) component;
+
+- (NSString *) iCalStringTemplate;
+- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters;
+- (NSString *) iCalParticipantsStringFromQueryParameters;
+- (NSString *) iCalResourcesStringFromQueryParameters;
+- (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
+                                     format: (NSString *) _format;
+- (NSString *) iCalOrganizerString;
+- (NSString *) toolbar;
+
+@end
+
+#endif /* UIXCOMPONENTEDITOR_H */
diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m
new file mode 100644 (file)
index 0000000..689053f
--- /dev/null
@@ -0,0 +1,873 @@
+/* UIxComponentEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSBundle.h>
+#import <Foundation/NSException.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSUserDefaults.h>
+#import <Foundation/NSURL.h>
+
+#import <NGCards/iCalPerson.h>
+#import <NGCards/iCalRepeatableEntityObject.h>
+#import <NGCards/iCalRecurrenceRule.h>
+#import <NGCards/NSString+NGCards.h>
+#import <NGCards/NSCalendarDate+NGCards.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
+#import <NGExtensions/NSObject+Logs.h>
+#import <NGExtensions/NSString+misc.h>
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGObjWeb/WORequest.h>
+
+#import <SOGo/AgenorUserManager.h>
+#import <SOGo/SOGoUser.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+#import <SoObjects/Appointments/SOGoAppointmentObject.h>
+#import <SoObjects/Appointments/SOGoTaskObject.h>
+
+#import "UIxComponent+Agenor.h"
+
+#import "UIxComponentEditor.h"
+
+@implementation UIxComponentEditor
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      [self setPrivacy: @"PUBLIC"];
+      [self setCheckForConflicts: NO];
+      [self setIsCycleEndNever];
+      componentOwner = @"";
+      componentLoaded = NO;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [iCalString release];
+  [errorText release];
+  [item release];
+  [startDate release];
+  [cycleUntilDate release];
+  [title release];
+  [location release];
+  [organizer release];
+  [comment release];
+  [participants release];
+  [resources release];
+  [priority release];
+  [categories release];
+  [cycle release];
+  [cycleEnd release];
+  [url release];
+
+  [super dealloc];
+}
+
+/* accessors */
+
+- (void) setItem: (id) _item
+{
+  ASSIGN(item, _item);
+}
+
+- (id) item
+{
+  return item;
+}
+
+- (NSString *) itemPriorityText
+{
+  return [self labelForKey: [NSString stringWithFormat: @"prio_%@", item]];
+}
+
+- (NSString *) itemPrivacyText
+{
+  return [self labelForKey: [NSString stringWithFormat: @"privacy_%@", item]];
+}
+
+- (NSString *) itemStatusText
+{
+  return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
+}
+
+- (void) setErrorText: (NSString *) _txt
+{
+  ASSIGNCOPY(errorText, _txt);
+}
+
+- (NSString *) errorText
+{
+  return errorText;
+}
+
+- (BOOL) hasErrorText
+{
+  return [errorText length] > 0 ? YES : NO;
+}
+
+- (void) setStartDate: (NSCalendarDate *) _date
+{
+  ASSIGN(startDate, _date);
+}
+
+- (NSCalendarDate *) startDate
+{
+  return startDate;
+}
+
+- (void) setTitle: (NSString *) _value
+{
+  ASSIGNCOPY(title, _value);
+}
+
+- (NSString *) title
+{
+  return title;
+}
+
+- (void) setUrl: (NSString *) _url
+{
+  ASSIGNCOPY(url, _url);
+}
+
+- (NSString *) url
+{
+  return url;
+}
+
+- (void) setLocation: (NSString *) _value
+{
+  ASSIGNCOPY(location, _value);
+}
+
+- (NSString *) location
+{
+  return location;
+}
+
+- (void) setComment: (NSString *) _value
+{
+  ASSIGNCOPY(comment, _value);
+}
+
+- (NSString *) comment
+{
+  return comment;
+}
+
+- (NSArray *) categoryItems
+{
+  // TODO: make this configurable?
+  /*
+   Tasks categories will be modified as follow :
+   â€“ by default (a simple logo or no logo at all),
+   â€“ task,
+   â€“ outside,
+   â€“ meeting,
+   â€“ holidays,
+   â€“ phone.
+  */
+  static NSArray *categoryItems = nil;
+  
+  if (!categoryItems)
+    {
+      categoryItems = [NSArray arrayWithObjects: @"APPOINTMENT",
+                               @"NOT IN OFFICE",
+                               @"MEETING",
+                               @"HOLIDAY",
+                               @"PHONE CALL",
+                               nil];
+      [categoryItems retain];
+    }
+
+  return categoryItems;
+}
+
+- (void) setCategories: (NSArray *) _categories
+{
+  ASSIGN(categories, _categories);
+}
+
+- (NSArray *) categories
+{
+  return categories;
+}
+
+- (NSString *) itemCategoryText
+{
+  return [[self labelForKey: item] stringByEscapingHTMLString];
+}
+
+/* priorities */
+
+- (NSArray *) priorities
+{
+  /* 0 == undefined
+     5 == normal
+     1 == high
+  */
+  static NSArray *priorities = nil;
+
+  if (!priorities)
+    {
+      priorities = [NSArray arrayWithObjects:@"0", @"5", @"1", nil];
+      [priorities retain];
+    }
+
+  return priorities;
+}
+
+- (void) setPriority: (NSString *) _priority
+{
+  ASSIGN(priority, _priority);
+}
+
+- (NSString *) priority
+{
+  return priority;
+}
+
+- (NSArray *) privacyClasses
+{
+  static NSArray *priorities = nil;
+
+  if (!priorities)
+    {
+      priorities = [NSArray arrayWithObjects: @"PUBLIC",
+                            @"CONFIDENTIAL", @"PRIVATE", nil];
+      [priorities retain];
+    }
+
+  return priorities;
+}
+
+- (void) setPrivacy: (NSString *) _privacy
+{
+  ASSIGN(privacy, _privacy);
+}
+
+- (NSString *) privacy
+{
+  return privacy;
+}
+
+- (NSArray *) statusTypes
+{
+  static NSArray *priorities = nil;
+
+  if (!priorities)
+    {
+      priorities = [NSArray arrayWithObjects: @"", @"TENTATIVE", @"CONFIRMED", @"CANCELLED", nil];
+      [priorities retain];
+    }
+
+  return priorities;
+}
+
+- (void) setStatus: (NSString *) _status
+{
+  ASSIGN(status, _status);
+}
+
+- (NSString *) status
+{
+  return status;
+}
+
+- (void) setParticipants: (NSArray *) _parts
+{
+  ASSIGN(participants, _parts);
+}
+
+- (NSArray *) participants
+{
+  return participants;
+}
+
+- (void) setResources: (NSArray *) _res
+{
+  ASSIGN(resources, _res);
+}
+
+- (NSArray *) resources
+{
+  return resources;
+}
+
+- (void) setCheckForConflicts: (BOOL) _checkForConflicts
+{
+  checkForConflicts = _checkForConflicts;
+}
+
+- (BOOL) checkForConflicts
+{
+  return checkForConflicts;
+}
+
+- (NSArray *) cycles
+{
+  NSBundle *bundle;
+  NSString *path;
+  static NSArray *cycles = nil;
+  
+  if (!cycles)
+    {
+      bundle = [NSBundle bundleForClass:[self class]];
+      path   = [bundle pathForResource:@"cycles" ofType:@"plist"];
+      NSAssert(path != nil, @"Cannot find cycles.plist!");
+      cycles = [[NSArray arrayWithContentsOfFile:path] retain];
+      NSAssert(cycles != nil, @"Cannot instantiate cycles from cycles.plist!");
+    }
+
+  return cycles;
+}
+
+- (void) setCycle: (NSDictionary *) _cycle
+{
+  ASSIGN(cycle, _cycle);
+}
+
+- (NSDictionary *) cycle
+{
+  return cycle;
+}
+
+- (BOOL) hasCycle
+{
+  return ([cycle objectForKey: @"rule"] != nil);
+}
+
+- (NSString *) cycleLabel
+{
+  NSString *key;
+  
+  key = [(NSDictionary *)item objectForKey:@"label"];
+
+  return [self labelForKey:key];
+}
+
+- (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate
+{
+  NSCalendarDate *until;
+
+  /* copy hour/minute/second from startDate */
+  until = [_cycleUntilDate hour: [startDate hourOfDay]
+                           minute: [startDate minuteOfHour]
+                           second: [startDate secondOfMinute]];
+  [until setTimeZone: [startDate timeZone]];
+  ASSIGN(cycleUntilDate, until);
+}
+
+- (NSCalendarDate *) cycleUntilDate
+{
+  return cycleUntilDate;
+}
+
+- (iCalRecurrenceRule *) rrule
+{
+  NSString *ruleRep;
+  iCalRecurrenceRule *rule;
+
+  if (![self hasCycle])
+    return nil;
+  ruleRep = [cycle objectForKey:@"rule"];
+  rule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:ruleRep];
+
+  if (cycleUntilDate && [self isCycleEndUntil])
+    [rule setUntilDate:cycleUntilDate];
+
+  return rule;
+}
+
+- (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule
+{
+  NSDictionary *c;
+  NSCalendarDate *until;
+  
+  c = [self cycleMatchingRRule:_rrule];
+  [self setCycle:c];
+
+  until = [[[_rrule untilDate] copy] autorelease];
+  if (!until)
+    until = startDate;
+  else
+    [self setIsCycleEndUntil];
+
+  [until setTimeZone:[[self clientObject] userTimeZone]];
+  [self setCycleUntilDate:until];
+}
+
+/*
+ This method is necessary, because we have a fixed sets of cycles in the UI.
+ The model is able to represent arbitrary rules, however.
+ There SHOULD be a different UI, similar to iCal.app, to allow modelling
+ of more complex rules.
+ This method obviously cannot map all existing rules back to the fixed list
+ in cycles.plist. This should be fixed in a future version when interop
+ becomes more important.
+ */
+- (NSDictionary *) cycleMatchingRRule: (iCalRecurrenceRule *) _rrule
+{
+  NSString *cycleRep;
+  NSArray *cycles;
+  unsigned i, count;
+
+  if (!_rrule)
+    return [[self cycles] objectAtIndex:0];
+
+  cycleRep = [_rrule versitString];
+  cycles   = [self cycles];
+  count    = [cycles count];
+  for (i = 1; i < count; i++) {
+    NSDictionary *c;
+    NSString *cr;
+
+    c  = [cycles objectAtIndex:i];
+    cr = [c objectForKey:@"rule"];
+    if ([cr isEqualToString:cycleRep])
+      return c;
+  }
+  [self warnWithFormat:@"No default cycle for rrule found! -> %@", _rrule];
+  return nil;
+}
+
+/* cycle "ends" - supposed to be 'never', 'COUNT' or 'UNTIL' */
+- (NSArray *) cycleEnds
+{
+  static NSArray *ends = nil;
+  
+  if (!ends)
+    {
+      ends = [NSArray arrayWithObjects: @"cycle_end_never",
+                      @"cycle_end_until", nil];
+      [ends retain];
+    }
+
+  return ends;
+}
+
+- (void) setCycleEnd: (NSString *) _cycleEnd
+{
+  ASSIGNCOPY(cycleEnd, _cycleEnd);
+}
+
+- (NSString *) cycleEnd
+{
+  return cycleEnd;
+}
+
+- (BOOL) isCycleEndUntil
+{
+  return (cycleEnd &&
+          [cycleEnd isEqualToString:@"cycle_end_until"]);
+}
+
+- (void) setIsCycleEndUntil
+{
+  [self setCycleEnd:@"cycle_end_until"];
+}
+
+- (void) setIsCycleEndNever
+{
+  [self setCycleEnd:@"cycle_end_never"];
+}
+
+/* helpers */
+- (NSFormatter *) titleDateFormatter
+{
+  SOGoDateFormatter *fmt;
+  
+  fmt = [[SOGoDateFormatter alloc] initWithLocale: [self locale]];
+  [fmt autorelease];
+  [fmt setFullWeekdayNameAndDetails];
+
+  return fmt;
+}
+
+- (NSString *) completeURIForMethod: (NSString *) _method
+{
+  NSString *uri;
+  NSRange r;
+    
+  uri = [[[self context] request] uri];
+    
+  /* first: identify query parameters */
+  r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
+  if (r.length > 0)
+    uri = [uri substringToIndex:r.location];
+    
+  /* next: append trailing slash */
+  if (![uri hasSuffix:@"/"])
+    uri = [uri stringByAppendingString:@"/"];
+  
+  /* next: append method */
+  uri = [uri stringByAppendingString:_method];
+    
+  /* next: append query parameters */
+  return [self completeHrefForMethod:uri];
+}
+
+- (BOOL) isWriteableClientObject
+{
+  return [[self clientObject] 
+               respondsToSelector:@selector(saveContentString:)];
+}
+
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq
+                           inContext: (WOContext*) _c
+{
+  return YES;
+}
+
+- (BOOL) containsConflict: (id) _component
+{
+  [self subclassResponsibility: _cmd];
+
+  return NO;
+}
+
+/* access */
+
+#if 0
+- (iCalPerson *) getOrganizer
+{
+  iCalPerson *p;
+  NSString *emailProp;
+  
+  emailProp = [@"MAILTO:" stringByAppendingString:[self emailForUser]];
+  p = [[[iCalPerson alloc] init] autorelease];
+  [p setEmail:emailProp];
+  [p setCn:[self cnForUser]];
+  return p;
+}
+#endif
+
+- (BOOL) isMyComponent
+{
+  // TODO: this should check a set of emails against the SoUser
+  return ([[organizer rfc822Email] isEqualToString: [self emailForUser]]);
+}
+
+- (BOOL) canEditComponent
+{
+  return [self isMyComponent];
+}
+
+/* response generation */
+
+- (NSString *) initialCycleVisibility
+{
+  return ([self hasCycle]
+          ? @"visibility: visible;"
+          : @"visibility: hidden;");
+}
+
+- (NSString *) initialCycleEndUntilVisibility {
+  return ([self isCycleEndUntil]
+          ? @"visibility: visible;"
+          : @"visibility: hidden;");
+}
+
+/* subclasses */
+- (NSCalendarDate *) newStartDate
+{
+  NSCalendarDate *newStartDate, *now;
+  int hour;
+
+  newStartDate = [self selectedDate];
+  if ([[self queryParameterForKey: @"hm"] length] == 0)
+    {
+      now = [NSCalendarDate calendarDate];
+      [now setTimeZone: [[self clientObject] userTimeZone]];
+      if (!([[now hour: 8 minute: 0] earlierDate: newStartDate] == newStartDate))
+        {
+          hour = [now hourOfDay];
+          if (hour < 8)
+            newStartDate = [now hour: 8 minute: 0];
+          else if (hour > 18)
+            newStartDate = [[now tomorrow] hour: 8 minute: 0];
+          else
+            newStartDate = now;
+        }
+    }
+
+  return newStartDate;
+}
+
+- (void) loadValuesFromComponent: (iCalRepeatableEntityObject *) component
+{
+  iCalRecurrenceRule *rrule;
+  NSTimeZone *uTZ;
+  SOGoObject *co;
+
+  co = [self clientObject];
+  componentOwner = [co ownerInContext: nil];
+  componentLoaded = YES;
+
+  startDate = [component startDate];
+//   if ((startDate = [component startDate]) == nil)
+//     startDate = [[NSCalendarDate date] hour:11 minute:0];
+  uTZ = [co userTimeZone];
+  if (startDate)
+    {
+      [startDate setTimeZone: uTZ];
+      [startDate retain];
+    }
+
+  title        = [[component summary] copy];
+  location     = [[component location] copy];
+  comment      = [[component comment] copy];
+  url          = [[[component url] absoluteString] copy];
+  privacy      = [[component accessClass] copy];
+  priority     = [[component priority] copy];
+  status       = [[component status] copy];
+  categories   = [[[component categories] commaSeparatedValues] retain];
+  organizer    = [[component organizer] retain];
+  participants = [[component participants] retain];
+  resources    = [[component resources] retain];
+
+  /* cycles */
+  if ([component isRecurrent])
+    {
+      rrule = [[component recurrenceRules] objectAtIndex: 0];
+      [self adjustCycleControlsForRRule: rrule];
+    }
+}
+
+- (NSString *) iCalStringTemplate
+{
+  [self subclassResponsibility: _cmd];
+
+  return @"";
+}
+
+- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters
+{
+  NSString *s;
+  
+  s = [self iCalParticipantsStringFromQueryParameters];
+  return [s stringByAppendingString:
+              [self iCalResourcesStringFromQueryParameters]];
+}
+
+- (NSString *) iCalParticipantsStringFromQueryParameters
+{
+  static NSString *iCalParticipantString = \
+    @"ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=\"%@\":MAILTO:%@\r\n";
+  
+  return [self iCalStringFromQueryParameter: @"ps"
+               format: iCalParticipantString];
+}
+
+- (NSString *) iCalResourcesStringFromQueryParameters
+{
+  static NSString *iCalResourceString = \
+    @"ATTENDEE;ROLE=NON-PARTICIPANT;CN=\"%@\":MAILTO:%@\r\n";
+
+  return [self iCalStringFromQueryParameter: @"rs"
+               format: iCalResourceString];
+}
+
+- (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
+                                     format: (NSString *) _format
+{
+  AgenorUserManager *um;
+  NSMutableString *iCalRep;
+  NSString *s;
+
+  um = [AgenorUserManager sharedUserManager];
+  iCalRep = (NSMutableString *)[NSMutableString string];
+  s = [self queryParameterForKey:_qp];
+  if(s && [s length] > 0) {
+    NSArray *es;
+    unsigned i, count;
+    
+    es = [s componentsSeparatedByString:@","];
+    count = [es count];
+    for(i = 0; i < count; i++) {
+      NSString *email, *cn;
+      
+      email = [es objectAtIndex:i];
+      cn = [um getCNForUID:[um getUIDForEmail:email]];
+      [iCalRep appendFormat:_format, cn, email];
+    }
+  }
+  return iCalRep;
+}
+
+- (NSString *) iCalOrganizerString
+{
+  return [NSString stringWithFormat: @"ORGANIZER;CN=\"%@\":MAILTO:%@\r\n",
+                   [self cnForUser], [self emailForUser]];
+}
+
+- (NSString *) saveUrl
+{
+  [self subclassResponsibility: _cmd];
+
+  return @"";
+}
+
+- (NSException *) validateObjectForStatusChange
+{
+  id co;
+
+  co = [self clientObject];
+  if (![co
+         respondsToSelector: @selector(changeParticipationStatus:inContext:)])
+    return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
+                        reason:
+                          @"method cannot be invoked on the specified object"];
+
+  return nil;
+}
+
+/* contact editor compatibility */
+
+- (void) setICalString: (NSString *) _s
+{
+  ASSIGNCOPY(iCalString, _s);
+}
+
+- (NSString *) iCalString
+{
+  return iCalString;
+}
+
+
+- (NSArray *) availableCalendars
+{
+  NSEnumerator *rawContacts;
+  NSString *list, *currentId;
+  NSMutableArray *calendars;
+  SOGoUser *user;
+
+  calendars = [NSMutableArray array];
+
+  user = [context activeUser];
+  list = [[user userDefaults] stringForKey: @"calendaruids"];
+  if ([list length] == 0)
+    list = [self shortUserNameForDisplay];
+
+  rawContacts
+    = [[list componentsSeparatedByString: @","] objectEnumerator];
+  currentId = [rawContacts nextObject];
+  while (currentId)
+    {
+      if ([currentId hasPrefix: @"-"])
+        [calendars addObject: [currentId substringFromIndex: 1]];
+      else
+        [calendars addObject: currentId];
+      currentId = [rawContacts nextObject];
+    }
+
+  return calendars;
+}
+
+- (NSString *) componentOwner
+{
+  return componentOwner;
+}
+
+- (NSString *) urlButtonClasses
+{
+  NSString *classes;
+
+  if ([url length])
+    classes = @"button";
+  else
+    classes = @"button _disabled";
+
+  return classes;
+}
+
+- (NSString *) _toolbarForCalObject: (iCalEntityObject *) calObject
+{
+  NSString *filename, *myEmail;
+  iCalPerson *person;
+  NSEnumerator *persons;
+  iCalPersonPartStat myParticipationStatus;
+  BOOL found;
+
+  myEmail = [[[self context] activeUser] email];
+  if ([[organizer rfc822Email] isEqualToString: myEmail])
+    filename = @"SOGoAppointmentObject.toolbar";
+  else
+    {
+      filename = @"";
+      found = NO;
+      persons = [participants objectEnumerator];
+      person = [persons nextObject];
+      while (person && !found)
+        if ([[person rfc822Email] isEqualToString: myEmail])
+          {
+            found = YES;
+            myParticipationStatus = [person participationStatus];
+            if (myParticipationStatus == iCalPersonPartStatAccepted)
+              filename = @"SOGoAppointmentObjectDecline.toolbar";
+            else if (myParticipationStatus == iCalPersonPartStatDeclined)
+              filename = @"SOGoAppointmentObjectAccept.toolbar";
+            else
+              filename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar";
+          }
+        else
+          person = [persons nextObject];
+    }
+
+  return filename;
+}
+
+- (NSString *) toolbar
+{
+  NSString *filename;
+  iCalEntityObject *calObject;
+  id co;
+
+  if (componentLoaded)
+    {
+      co = [self clientObject];
+      if ([co isKindOfClass: [SOGoAppointmentObject class]])
+        {
+          calObject = (iCalEntityObject *) [co event];
+          filename = [self _toolbarForCalObject: calObject];
+        }
+      else if ([co isKindOfClass: [SOGoTaskObject class]])
+        {
+          calObject = (iCalEntityObject *) [co task];
+          filename = [self _toolbarForCalObject: calObject];
+        }
+      else
+        filename = @"";
+    }
+  else
+    filename = @"";
+
+  return filename;
+}
+
+@end
index 3ce082741230d4f7e9d166c7ecd06905d897e094..dbcc15a8f0fd01e3d4e86dd64ebdfd9a6b2acd80 100644 (file)
@@ -30,6 +30,7 @@
   id       month;
   id       year;
   NSString *label;
+  BOOL isDisabled;
 }
 
 - (NSString *)dateID;
 
 @implementation UIxDatePicker
 
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      isDisabled = NO;
+    }
+
+  return self;
+}
+
 - (void)dealloc {
   [self->dateID release];
   [self->day    release];
  }
   return [useISOFormats boolValue];
 }
-- (NSString *)formattedDateString {
+
+- (NSString *) formattedDateString
+{
   char buf[22];
 
   if ([self useISOFormats]) {
   return [NSString stringWithCString:buf];
 }
 
-- (NSString *)dateFormat {
+- (NSString *) dateFormat
+{
   return [self useISOFormats] ? @"%Y-%m-%d" : @"%d/%m/%Y";
 }
 
-- (NSString *)jsDateFormat {
+- (NSString *) jsDateFormat
+{
   return [self useISOFormats] ? @"yyyy-mm-dd" : @"dd/mm/yyyy";
 }
 
-
-/* URLs */
-
-- (NSString *)calendarPageURL {
-  WOResourceManager *rm;
-  WOContext *ctx;
-  NSArray   *languages;
-
-  if ((rm = [self resourceManager]) == nil)
-    rm = [[WOApplication application] resourceManager];
-  if (rm == nil)
-    [self warnWithFormat:@"missing resource manager!"];
-
-  ctx       = [self context];
-#if 0
-  languages = [ctx resourceLookupLanguages];
-#else
-#warning !! FIX SoProduct to enable localizable resource, then disable this!
-  languages = nil;
-#endif
-    
-  return [rm urlForResourceNamed:@"skycalendar.html" inFramework:nil
-             languages:languages request:[ctx request]];
-}
-
-/* JavaScript */
-
-- (NSString *)jsPopup {
-  return [NSString stringWithFormat:@"javascript:calendar_%@.popup()",
-        [self dateID]];
-}
-
-- (NSString *)jsCode {
-  static NSString *code = \
-    @"var calendar_%@ = new skycalendar(document.getElementById('%@'));\n"
-    @"calendar_%@.setCalendarPage('%@');\n"
-    @"calendar_%@.setDateFormat('%@');\n";
-  
-  return [NSString stringWithFormat:code,
-                  self->dateID,
-                  self->dateID,
-                  self->dateID,
-                  [self calendarPageURL],
-                  self->dateID,
-                  [self jsDateFormat]];
-}
-
 /* action */
 
-- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
+- (void) takeValuesFromRequest: (WORequest *) _rq
+                     inContext: (WOContext *)_ctx
+{
   NSString       *dateString;
   NSCalendarDate *d;
 
     [self warnWithFormat:@"Could not parse dateString: '%@'", 
             dateString];
   }
+
   [self setDay:  [NSNumber numberWithInt:[d dayOfMonth]]];
   [self setMonth:[NSNumber numberWithInt:[d monthOfYear]]];
   [self setYear: [NSNumber numberWithInt:[d yearOfCommonEra]]];
   [super takeValuesFromRequest:_rq inContext:_ctx];
 }
 
+- (void) setDisabled: (BOOL) disabled
+{
+  isDisabled = disabled;
+}
+
+- (BOOL) disabled
+{
+  return isDisabled;
+}
+
 @end /* UIxDatePicker */
diff --git a/UI/Scheduler/UIxDatePickerScript.m b/UI/Scheduler/UIxDatePickerScript.m
deleted file mode 100644 (file)
index 8ea4d12..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-  Copyright (C) 2000-2004 SKYRIX Software AG
-
-  This file is part of OGo
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-
-#include <NGObjWeb/NGObjWeb.h>
-
-
-@interface UIxDatePickerScript : WOComponent
-{
-
-}
-
-@end
-
-
-@implementation UIxDatePickerScript
-
-@end
diff --git a/UI/Scheduler/UIxFreeBusyUserSelector.h b/UI/Scheduler/UIxFreeBusyUserSelector.h
new file mode 100644 (file)
index 0000000..44ff82e
--- /dev/null
@@ -0,0 +1,62 @@
+/* UIxFreeBusyUserSelector.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXFREEBUSYUSERSELECTOR_H
+#define UIXFREEBUSYUSERSELECTOR_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSArray;
+@class NSMutableArray;
+@class NSCalendarDate;
+@class NSNumber;
+@class iCalPerson;
+
+@interface UIxFreeBusyUserSelector : UIxComponent
+{
+  NSCalendarDate *startDate;
+  NSCalendarDate *endDate;
+  NSNumber *dayStartHour;
+  NSNumber *dayEndHour;
+
+  NSArray *contacts;
+
+  NSString *selectorId;
+}
+
+- (void) setStartDate: (NSCalendarDate *) newStartDate;
+- (void) setEndDate: (NSCalendarDate *) newEndDate;
+
+- (void) setDayStartHour: (NSNumber *) newDayStartHour;
+- (NSNumber *) dayStartHour;
+- (void) setDayEndHour: (NSNumber *) newDayEndHour;
+- (NSNumber *) dayEndHour;
+
+- (void) setContacts: (NSArray *) contacts;
+- (NSArray *) contacts;
+
+- (void) setSelectorId: (NSString *) newSelectorId;
+- (NSString *) selectorId;
+
+@end
+
+#endif /* UIXFREEBUSYUSERSELECTOR_H */
diff --git a/UI/Scheduler/UIxFreeBusyUserSelector.m b/UI/Scheduler/UIxFreeBusyUserSelector.m
new file mode 100644 (file)
index 0000000..13f4c3a
--- /dev/null
@@ -0,0 +1,163 @@
+/* UIxFreeBusyUserSelector.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSValue.h>
+
+#import <NGCards/iCalPerson.h>
+#import <NGObjWeb/WORequest.h>
+
+#import <SoObjects/SOGo/AgenorUserManager.h>
+
+#import "UIxComponent+Agenor.h"
+#import "UIxFreeBusyUserSelector.h"
+
+@implementation UIxFreeBusyUserSelector
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      startDate = nil;
+      endDate = nil;
+      dayStartHour = [NSNumber numberWithInt: 8];
+      [dayStartHour retain];
+      dayEndHour = [NSNumber numberWithInt: 18];
+      [dayEndHour retain];
+      contacts = nil;
+      selectorId = nil;
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [dayStartHour release];
+  [dayEndHour release];
+  if (contacts)
+    [contacts release];
+  if (selectorId)
+    [selectorId release];
+  [super dealloc];
+}
+
+- (void) setStartDate: (NSCalendarDate *) newStartDate
+{
+  startDate = newStartDate;
+}
+
+- (NSCalendarDate *) startDate
+{
+  return startDate;
+}
+
+- (void) setEndDate: (NSCalendarDate *) newEndDate
+{
+  endDate = newEndDate;
+}
+
+- (NSCalendarDate *) endDate
+{
+  return endDate;
+}
+
+- (void) setDayStartHour: (NSNumber *) newDayStartHour
+{
+  ASSIGN (dayStartHour, newDayStartHour);
+}
+
+- (NSNumber *) dayStartHour
+{
+  return dayStartHour;
+}
+
+- (void) setDayEndHour: (NSNumber *) newDayEndHour
+{
+  ASSIGN (dayEndHour, newDayEndHour);
+}
+
+- (NSNumber *) dayEndHour
+{
+  return dayEndHour;
+}
+
+- (void) setSelectorId: (NSString *) newSelectorId
+{
+  ASSIGN (selectorId, newSelectorId);
+}
+
+- (NSString *) selectorId
+{
+  return selectorId;
+}
+
+- (void) setContacts: (NSArray *) newContacts
+{
+  ASSIGN (contacts, newContacts);
+}
+
+- (NSArray *) contacts
+{
+  return contacts;
+}
+
+/* callbacks */
+- (void) takeValuesFromRequest: (WORequest *) request
+                     inContext: (WOContext *) context
+{
+  NSArray *newContacts;
+
+  newContacts
+    = [self getICalPersonsFromValue: [request formValueForKey: selectorId]];
+  ASSIGN (contacts, newContacts);
+  if ([contacts count] > 0)
+    NSLog (@"got %i attendees: %@", [contacts count], contacts);
+  else
+    NSLog (@"got no attendees!");
+}
+
+/* in-template operations */
+- (NSString *) initialContactsAsString
+{
+  NSEnumerator *persons;
+  iCalPerson *person;
+  NSMutableArray *participants;
+
+  participants = [NSMutableArray arrayWithCapacity: [contacts count]];
+  persons = [contacts objectEnumerator];
+  person = [persons nextObject];
+  while (person)
+    {
+      [participants addObject: [person cn]];
+      person = [persons nextObject];
+    }
+
+  return [participants componentsJoinedByString: @","];
+}
+
+- (NSString *) freeBusyViewId
+{
+  return [NSString stringWithFormat: @"parentOf%@", [selectorId capitalizedString]];
+}
+@end
diff --git a/UI/Scheduler/UIxFreeBusyUserSelectorTable.h b/UI/Scheduler/UIxFreeBusyUserSelectorTable.h
new file mode 100644 (file)
index 0000000..969695f
--- /dev/null
@@ -0,0 +1,82 @@
+/* UIxFreeBusyUserSelectorTable.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXFREEBUSYUSERSELECTORTABLE_H
+#define UIXFREEBUSYUSERSELECTORTABLE_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSArray;
+@class NSCalendarDate;
+@class NSNumber;
+
+@class iCalPerson;
+@class SOGoDateFormatter;
+
+@interface UIxFreeBusyUserSelectorTable : UIxComponent
+{
+  BOOL standAlone;
+  NSMutableArray *daysToDisplay;
+  NSMutableArray *hoursToDisplay;
+  SOGoDateFormatter *dateFormatter;
+
+  NSArray *contacts;
+  NSNumber *dayStartHour;
+  NSNumber *dayEndHour;
+  NSCalendarDate *startDate;
+  NSCalendarDate *endDate;
+
+  iCalPerson *currentContact;
+  NSNumber *currentHourToDisplay;
+  NSCalendarDate *currentDayToDisplay;
+}
+
+- (void) setContacts: (NSArray *) newContacts;
+- (NSArray *) contacts;
+
+- (void) setStartDate: (NSCalendarDate *) newStartDate;
+- (void) setEndDate: (NSCalendarDate *) newEndDate;
+
+- (void) setDayStartHour: (NSNumber *) newDayStartHour;
+- (NSNumber *) dayStartHour;
+- (void) setDayEndHour: (NSNumber *) newDayEndHour;
+- (NSNumber *) dayEndHour;
+
+- (void) setCurrentContact: (iCalPerson *) newCurrentContact;
+- (iCalPerson *) currentContact;
+- (NSString *) currentContactId;
+- (NSString *) currentContactName;
+
+- (void) setCurrentDayToDisplay: (NSCalendarDate *) newCurrentDayToDisplay;
+- (NSCalendarDate *) currentDayToDisplay;
+
+- (void) setCurrentHourToDisplay: (NSNumber *) newCurrentHourToDisplay;
+- (NSNumber *) currentHourToDisplay;
+
+- (NSString *) currentFormattedDay;
+
+- (NSArray *) daysToDisplay;
+- (NSArray *) hoursToDisplay;
+
+@end
+
+#endif /* UIXFREEBUSYUSERSELECTORTABLE_H */
diff --git a/UI/Scheduler/UIxFreeBusyUserSelectorTable.m b/UI/Scheduler/UIxFreeBusyUserSelectorTable.m
new file mode 100644 (file)
index 0000000..4e3df85
--- /dev/null
@@ -0,0 +1,292 @@
+/* UIxFreeBusyUserSelectorTable.m - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSValue.h>
+#import <Foundation/NSString.h>
+
+#import <NGCards/iCalPerson.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
+
+#import <SoObjects/Appointments/SOGoFreeBusyObject.h>
+#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+
+#import "UIxComponent+Agenor.h"
+#import "UIxFreeBusyUserSelectorTable.h"
+
+@implementation UIxFreeBusyUserSelectorTable
+
+- (id) init
+{
+  if ((self = [super init]))
+    {
+      standAlone = NO;
+      startDate = nil;
+      endDate = nil;
+      contacts = nil;
+      hoursToDisplay = nil;
+      daysToDisplay = nil;
+      dateFormatter
+        = [[SOGoDateFormatter alloc] initWithLocale: [self locale]];
+    }
+
+  return self;
+}
+
+- (void) dealloc
+{
+  [dateFormatter release];
+  if (hoursToDisplay)
+    [hoursToDisplay release];
+  if (daysToDisplay)
+    [daysToDisplay release];
+  if (standAlone)
+    {
+      if (startDate)
+        [startDate release];
+      if (endDate)
+        [endDate release];
+      if (contacts)
+        [contacts release];
+    }
+  [super dealloc];
+}
+
+- (void) setContacts: (NSArray *) newContacts
+{
+  contacts = newContacts;
+}
+
+- (NSArray *) contacts
+{
+  return contacts;
+}
+
+- (void) setStartDate: (NSCalendarDate *) newStartDate
+{
+  startDate = newStartDate;
+  if (daysToDisplay)
+    {
+      [daysToDisplay release];
+      daysToDisplay = nil;
+    }
+}
+
+- (NSCalendarDate *) startDate
+{
+  return startDate;
+}
+
+- (void) setEndDate: (NSCalendarDate *) newEndDate
+{
+  endDate = newEndDate;
+  if (daysToDisplay)
+    {
+      [daysToDisplay release];
+      daysToDisplay = nil;
+    }
+}
+
+- (NSCalendarDate *) endDate
+{
+  return endDate;
+}
+
+- (void) setDayStartHour: (NSNumber *) newDayStartHour
+{
+  dayStartHour = newDayStartHour;
+  if (hoursToDisplay)
+    {
+      [hoursToDisplay release];
+      hoursToDisplay = nil;
+    }
+}
+
+- (NSNumber *) dayStartHour
+{
+  return dayStartHour;
+}
+
+- (void) setDayEndHour: (NSNumber *) newDayEndHour
+{
+  dayEndHour = newDayEndHour;
+  if (hoursToDisplay)
+    {
+      [hoursToDisplay release];
+      hoursToDisplay = nil;
+    }
+}
+
+- (NSNumber *) dayEndHour
+{
+  return dayEndHour;
+}
+
+/* template operations */
+- (NSArray *) daysToDisplay
+{
+  NSCalendarDate *currentDay, *finalDay;
+
+  if (!daysToDisplay)
+    {
+      daysToDisplay = [NSMutableArray new];
+      finalDay = [endDate dateByAddingYears: 0 months: 0 days: 2];
+      currentDay = startDate;
+      [daysToDisplay addObject: currentDay];
+      while (![currentDay isDateOnSameDay: finalDay])
+        {
+          currentDay = [currentDay dateByAddingYears: 0
+                                   months: 0
+                                   days: 1];
+          [daysToDisplay addObject: currentDay];
+        }
+    }
+
+  return daysToDisplay;
+}
+
+- (NSArray *) hoursToDisplay
+{
+  NSNumber *currentHour;
+
+  if (!hoursToDisplay)
+    {
+      hoursToDisplay = [NSMutableArray new];
+      currentHour = dayStartHour;
+      [hoursToDisplay addObject: currentHour];
+      while (![currentHour isEqual: dayEndHour])
+        {
+          currentHour = [NSNumber numberWithInt: [currentHour intValue] + 1];
+          [hoursToDisplay addObject: currentHour];
+        }
+    }
+
+  return hoursToDisplay;
+}
+
+- (void) setCurrentContact: (iCalPerson *) newCurrentContact
+{
+  currentContact = newCurrentContact;
+}
+
+- (iCalPerson *) currentContact
+{
+  return currentContact;
+}
+
+- (BOOL) currentContactHasStatus
+{
+  return ([currentContact participationStatus] != 0);
+}
+
+- (NSString *) currentContactStatusImage
+{
+  NSString *basename;
+
+  basename = [[currentContact partStatWithDefault] lowercaseString];
+                       
+  return [self urlForResourceFilename: [NSString stringWithFormat: @"%@.png", basename]];;
+}
+
+- (NSString *) currentContactId
+{
+  return [currentContact cn];
+}
+
+- (NSString *) currentContactName
+{
+  return [currentContact cn];
+}
+
+- (void) setCurrentDayToDisplay: (NSCalendarDate *) newCurrentDayToDisplay
+{
+  currentDayToDisplay = newCurrentDayToDisplay;
+}
+
+- (void) setCurrentHourToDisplay: (NSNumber *) newCurrentHourToDisplay
+{
+  currentHourToDisplay = newCurrentHourToDisplay;
+}
+
+- (NSCalendarDate *) currentDayToDisplay
+{
+  return currentDayToDisplay;
+}
+
+- (NSNumber *) currentHourToDisplay
+{
+  return currentHourToDisplay;
+}
+
+- (NSString *) currentFormattedDay
+{
+  return [NSString stringWithFormat: @"%@, %.4d-%.2d-%.2d",
+                   [dateFormatter shortDayOfWeek: [currentDayToDisplay dayOfWeek]],
+                   [currentDayToDisplay yearOfCommonEra],
+                   [currentDayToDisplay monthOfYear],
+                   [currentDayToDisplay dayOfMonth]];
+}
+
+/* as stand-alone component... */
+
+- (id <WOActionResults>) defaultAction
+{
+  SOGoFreeBusyObject *co;
+  NSString *queryParam;
+  NSTimeZone *uTZ;
+
+  co = [self clientObject];
+  uTZ = [co userTimeZone];
+
+  queryParam = [self queryParameterForKey: @"sday"];
+  if ([queryParam length] > 0)
+    {
+      [self setStartDate: [NSCalendarDate dateFromShortDateString: queryParam
+                                          andShortTimeString: @"0000"
+                                          inTimeZone: uTZ]];
+      [startDate retain];
+    }
+  queryParam = [self queryParameterForKey: @"eday"];
+  if ([queryParam length] > 0)
+    {
+      [self setEndDate: [NSCalendarDate dateFromShortDateString: queryParam
+                                        andShortTimeString: @"0000"
+                                        inTimeZone: uTZ]];
+      [endDate retain];
+    }
+  queryParam = [self queryParameterForKey: @"attendees"];
+  if ([queryParam length] > 0)
+    {
+      [self setContacts: [self getICalPersonsFromValue: queryParam]];
+      [contacts retain];
+    }
+  dayStartHour = [NSNumber numberWithInt: 8];
+  dayEndHour = [NSNumber numberWithInt: 18];
+
+  standAlone = YES;
+
+  return self;
+}
+
+@end
diff --git a/UI/Scheduler/UIxTaskEditor.h b/UI/Scheduler/UIxTaskEditor.h
new file mode 100644 (file)
index 0000000..df43674
--- /dev/null
@@ -0,0 +1,78 @@
+/* UIxTaskEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2006 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef UIXTASKEDITOR_H
+#define UIXTASKEDITOR_H
+
+#import "UIxComponentEditor.h"
+
+@class NSString;
+@class iCalPerson;
+@class iCalRecurrenceRule;
+@class iCalToDo;
+
+@interface UIxTaskEditor : UIxComponentEditor
+{
+  NSCalendarDate *dueDate;
+  BOOL hasStartDate;
+  BOOL hasDueDate;
+  BOOL newTask;
+}
+
+- (void) setTaskStartDate: (NSCalendarDate *) _date;
+- (NSCalendarDate *) taskStartDate;
+
+- (void) setTaskDueDate: (NSCalendarDate *) _date;
+- (NSCalendarDate *) taskDueDate;
+
+/* iCal */
+
+- (NSString *) iCalStringTemplate;
+
+/* new */
+
+- (id) newAction;
+
+/* save */
+
+- (void) loadValuesFromTask: (iCalToDo *) _task;
+- (void) saveValuesIntoTask: (iCalToDo *) _task;
+- (iCalToDo *) taskFromString: (NSString *) _iCalString;
+
+/* conflict management */
+
+- (BOOL) containsConflict: (id) _task;
+- (id <WOActionResults>) defaultAction;
+- (id <WOActionResults>) saveAction;
+- (id) changeStatusAction;
+- (id) acceptAction;
+- (id) declineAction;
+
+- (NSString *) saveUrl;
+
+// TODO: add tentatively
+
+- (id) acceptOrDeclineAction: (BOOL) _accept;
+
+@end
+
+#endif /* UIXTASKEDITOR_H */
diff --git a/UI/Scheduler/UIxTaskEditor.m b/UI/Scheduler/UIxTaskEditor.m
new file mode 100644 (file)
index 0000000..9335c23
--- /dev/null
@@ -0,0 +1,505 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#import <SOGo/NSCalendarDate+SOGo.h>
+
+#import "UIxTaskEditor.h"
+
+/* TODO: CLEAN UP */
+
+#import "common.h"
+#import <NGCards/NGCards.h>
+#import <NGExtensions/NGCalendarDateRange.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+#import <SOGo/AgenorUserManager.h>
+#import <Appointments/SOGoAppointmentFolder.h>
+#import <Appointments/SOGoTaskObject.h>
+#import "UIxComponent+Agenor.h"
+
+@implementation UIxTaskEditor
+
+- (void) dealloc
+{
+  [dueDate release];
+  [super dealloc];
+}
+
+- (void) setTaskStartDate: (NSCalendarDate *) _date
+{
+  [self setStartDate: _date];
+}
+
+- (NSCalendarDate *) taskStartDate
+{
+  return [self startDate];
+}
+
+- (void) setTaskDueDate: (NSCalendarDate *) _date
+{
+  ASSIGN(dueDate, _date);
+}
+
+- (NSCalendarDate *) taskDueDate
+{
+  return dueDate;
+}
+
+/* iCal */
+
+- (NSString *) iCalStringTemplate
+{
+  static NSString *iCalStringTemplate = \
+    @"BEGIN:VCALENDAR\r\n"
+    @"METHOD:REQUEST\r\n"
+    @"PRODID://Inverse groupe conseil/SOGo 0.9\r\n"
+    @"VERSION:2.0\r\n"
+    @"BEGIN:VTODO\r\n"
+    @"UID:%@\r\n"
+    @"CLASS:PUBLIC\r\n"
+    @"STATUS:NEEDS-ACTION\r\n" /* confirmed by default */
+    @"PERCENT-COMPLETE:0\r\n"
+    @"DTSTART:%@Z\r\n"
+    @"DUE:%@Z\r\n"
+    @"DTSTAMP:%@Z\r\n"
+    @"SEQUENCE:1\r\n"
+    @"PRIORITY:5\r\n"
+    @"%@"                   /* organizer */
+    @"%@"                   /* participants and resources */
+    @"END:VTODO\r\n"
+    @"END:VCALENDAR";
+
+  NSCalendarDate *stamp, *lStartDate, *lDueDate;
+  NSString *template, *s;
+  NSTimeZone *utc;
+  unsigned minutes;
+
+  s = [self queryParameterForKey:@"dur"];
+  if ([s length] > 0)
+    minutes = [s intValue];
+  else
+    minutes = 60;
+
+  utc = [NSTimeZone timeZoneWithName: @"GMT"];
+  lStartDate = [self newStartDate];
+  [lStartDate setTimeZone: utc];
+  lDueDate = [lStartDate dateByAddingYears: 0 months: 0 days: 0
+                         hours: 0 minutes: minutes seconds: 0];
+  stamp = [NSCalendarDate calendarDate];
+  [stamp setTimeZone: utc];
+  
+  s = [self iCalParticipantsAndResourcesStringFromQueryParameters];
+  template   = [NSString stringWithFormat:iCalStringTemplate,
+                         [[self clientObject] nameInContainer],
+                         [lStartDate iCalFormattedDateTimeString],
+                         [lDueDate iCalFormattedDateTimeString],
+                         [stamp iCalFormattedDateTimeString],
+                         [self iCalOrganizerString],
+                         s];
+  return template;
+}
+
+/* new */
+
+- (id) newAction
+{
+  /*
+    This method creates a unique ID and redirects to the "edit" method on the
+    new ID.
+    It is actually a folder method and should be defined on the folder.
+    
+    Note: 'clientObject' is the SOGoAppointmentFolder!
+          Update: remember that there are group folders as well.
+  */
+  NSString *uri, *objectId, *method, *ps;
+
+  objectId = [NSClassFromString(@"SOGoAppointmentFolder")
+                              globallyUniqueObjectId];
+  if ([objectId length] == 0) {
+    return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
+                       reason:@"could not create a unique ID"];
+  }
+
+  method = [NSString stringWithFormat:@"Calendar/%@/editAsTask", objectId];
+  method = [[self userFolderPath] stringByAppendingPathComponent:method];
+
+  /* check if participants have already been provided */
+  ps     = [self queryParameterForKey:@"ps"];
+//   if (ps) {
+//     [self setQueryParameter:ps forKey:@"ps"];
+//   }
+ if (!ps
+     && [[self clientObject] respondsToSelector:@selector(calendarUIDs)]) {
+    AgenorUserManager *um;
+    NSArray *uids;
+    NSMutableArray *emails;
+    unsigned i, count;
+
+    /* add all current calendarUIDs as default participants */
+
+    um     = [AgenorUserManager sharedUserManager];
+    uids   = [[self clientObject] calendarUIDs];
+    count  = [uids count];
+    emails = [NSMutableArray arrayWithCapacity:count];
+    
+    for (i = 0; i < count; i++) {
+      NSString *email;
+      
+      email = [um getEmailForUID:[uids objectAtIndex:i]];
+      if (email)
+        [emails addObject:email];
+    }
+    ps = [emails componentsJoinedByString:@","];
+    [self setQueryParameter:ps forKey:@"ps"];
+  }
+  uri = [self completeHrefForMethod:method];
+  return [self redirectToLocation:uri];
+}
+
+/* save */
+
+- (void) loadValuesFromTask: (iCalToDo *) _task
+{
+  NSTimeZone *uTZ;
+
+  [self loadValuesFromComponent: _task];
+
+  uTZ = [[self clientObject] userTimeZone];
+  dueDate = [_task due];
+//   if (!dueDate)
+//     dueDate = [[self startDate] dateByAddingYears: 0 months: 0 days: 0
+//                                 hours: 1 minutes: 0 seconds: 0];
+  if (dueDate)
+    {
+      [dueDate setTimeZone: uTZ];
+      [dueDate retain];
+    }
+}
+
+- (void) saveValuesIntoTask: (iCalToDo *) _task
+{
+  /* merge in form values */
+  NSArray *attendees, *lResources;
+  iCalRecurrenceRule *rrule;
+  NSCalendarDate *dateTime;
+
+  if (hasStartDate)
+    dateTime = [self taskStartDate];
+  else
+    dateTime = nil;
+  [_task setStartDate: dateTime];
+  if (hasDueDate)
+    dateTime = [self taskDueDate];
+  else
+    dateTime = nil;
+  [_task setDue: dateTime];
+
+  [_task setSummary: [self title]];
+  [_task setUrl: [self url]];
+  [_task setLocation: [self location]];
+  [_task setComment: [self comment]];
+  [_task setPriority:[self priority]];
+  [_task setAccessClass: [self privacy]];
+  [_task setStatus: [self status]];
+
+//   [_task setCategories: [[self categories] componentsJoinedByString: @","]];
+  
+#if 0
+  /*
+    Note: bad, bad, bad!
+    Organizer is no form value, thus we MUST NOT change it
+  */
+  [_task setOrganizer:organizer];
+#endif
+  attendees  = [self participants];
+  lResources = [self resources];
+  if ([lResources count] > 0) {
+    attendees = ([attendees count] > 0)
+      ? [attendees arrayByAddingObjectsFromArray:lResources]
+      : lResources;
+  }
+  [attendees makeObjectsPerformSelector: @selector (setTag:)
+             withObject: @"attendee"];
+  [_task setAttendees:attendees];
+
+  /* cycles */
+  [_task removeAllRecurrenceRules];
+  rrule = [self rrule];
+  if (rrule)
+    [_task addToRecurrenceRules: rrule];
+}
+
+- (iCalToDo *) taskFromString: (NSString *) _iCalString
+{
+  iCalCalendar *calendar;
+  iCalToDo *task;
+  SOGoTaskObject *clientObject;
+
+  clientObject = [self clientObject];
+  calendar = [iCalCalendar parseSingleFromSource: _iCalString];
+  task = [clientObject firstTaskFromCalendar: calendar];
+
+  return task;
+}
+
+/* conflict management */
+
+- (BOOL) containsConflict: (id) _task
+{
+  NSArray *attendees, *uids;
+  SOGoAppointmentFolder *groupCalendar;
+  NSArray *infos;
+  NSArray *ranges;
+  id folder;
+
+  [self logWithFormat:@"search from %@ to %@", 
+         [_task startDate], [_task due]];
+
+  folder    = [[self clientObject] container];
+  attendees = [_task attendees];
+  uids      = [folder uidsFromICalPersons:attendees];
+  if ([uids count] == 0) {
+    [self logWithFormat:@"Note: no UIDs selected."];
+    return NO;
+  }
+
+  groupCalendar = [folder lookupGroupCalendarFolderForUIDs:uids
+                          inContext:[self context]];
+  [self debugWithFormat:@"group calendar: %@", groupCalendar];
+  
+  if (![groupCalendar respondsToSelector:@selector(fetchFreeBusyInfosFrom:to:)]) {
+    [self errorWithFormat:@"invalid folder to run freebusy query on!"];
+    return NO;
+  }
+
+  infos = [groupCalendar fetchFreeBusyInfosFrom:[_task startDate]
+                         to:[_task due]];
+  [self debugWithFormat:@"  process: %d tasks", [infos count]];
+
+  ranges = [infos arrayByCreatingDateRangesFromObjectsWithStartDateKey:@"startDate"
+                  andEndDateKey:@"dueDate"];
+  ranges = [ranges arrayByCompactingContainedDateRanges];
+  [self debugWithFormat:@"  blocked ranges: %@", ranges];
+
+  return [ranges count] != 0 ? YES : NO;
+}
+
+- (id <WOActionResults>) defaultAction
+{
+  NSString *ical;
+
+  /* load iCalendar file */
+  
+  // TODO: can't we use [clientObject contentAsString]?
+//   ical = [[self clientObject] valueForKey:@"iCalString"];
+  ical = [[self clientObject] contentAsString];
+  if ([ical length] == 0)
+    {
+      newTask = YES;
+      ical = [self iCalStringTemplate];
+    }
+  else
+    newTask = NO;
+
+  [self setICalString:ical];
+  [self loadValuesFromTask: [self taskFromString: ical]];
+  
+//   if (![self canEditComponent]) {
+//     /* TODO: we need proper ACLs */
+//     return [self redirectToLocation: [self completeURIForMethod: @"../view"]];
+//   }
+
+  return self;
+}
+
+- (id <WOActionResults>) saveAction
+{
+  iCalToDo *task;
+  iCalPerson *p;
+  id <WOActionResults> result;
+  NSString *content;
+  NSException *ex;
+
+  if (![self isWriteableClientObject]) {
+    /* return 400 == Bad Request */
+    return [NSException exceptionWithHTTPStatus:400
+                        reason: @"method cannot be invoked on "
+                                @"the specified object"];
+  }
+
+  task = [self taskFromString: [self iCalString]];
+  if (task == nil) {
+    NSString *s;
+    
+    s = [self labelForKey: @"Invalid iCal data!"];
+    [self setErrorText: s];
+
+    return self;
+  }
+
+  [self saveValuesIntoTask:task];
+  p = [task findParticipantWithEmail:[self emailForUser]];
+  if (p) {
+    [p setParticipationStatus:iCalPersonPartStatAccepted];
+  }
+
+  if ([self checkForConflicts]) {
+    if ([self containsConflict:task]) {
+      NSString *s;
+      
+      s = [self labelForKey:@"Conflicts found!"];
+      [self setErrorText:s];
+
+      return self;
+    }
+  }
+  content = [[task parent] versitString];
+//   [task release]; task = nil;
+  
+  if (content == nil) {
+    NSString *s;
+    
+    s = [self labelForKey: @"Could not create iCal data!"];
+    [self setErrorText: s];
+    return self;
+  }
+  
+  ex = [[self clientObject] saveContentString:content];
+  if (ex != nil) {
+    [self setErrorText:[ex reason]];
+    return self;
+  }
+
+  if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
+    result = [self redirectToLocation: [self applicationPath]];
+  else
+    result = [self jsCloseWithRefreshMethod: @"refreshTasks()"];
+
+  return result;
+}
+
+- (id) changeStatusAction
+{
+  iCalToDo *task;
+  SOGoTaskObject *taskObject;
+  NSString *content;
+  id ex;
+  int newStatus;
+
+  newStatus = [[self queryParameterForKey: @"status"] intValue];
+
+  taskObject = [self clientObject];
+  task = [taskObject task];
+  switch (newStatus)
+    {
+    case 1:
+      [task setCompleted: [NSCalendarDate calendarDate]];
+      break;
+    case 2:
+      [task setStatus: @"IN-PROCESS"];
+      break;
+    case 3:
+      [task setStatus: @"CANCELLED"];
+      break;
+    default:
+      [task setStatus: @"NEEDS-ACTION"];
+    }
+
+  content = [[task parent] versitString];
+  ex = [[self clientObject] saveContentString: content];
+  if (ex != nil) {
+    [self setErrorText:[ex reason]];
+    return self;
+  }
+  
+  return [self redirectToLocation: [self completeURIForMethod: @".."]];
+}
+
+- (id)acceptAction {
+  return [self acceptOrDeclineAction:YES];
+}
+
+- (id)declineAction {
+  return [self acceptOrDeclineAction:NO];
+}
+
+- (NSString *) saveUrl
+{
+  return [NSString stringWithFormat: @"%@/saveAsTask",
+                   [[self clientObject] baseURL]];
+}
+
+// TODO: add tentatively
+
+- (id)acceptOrDeclineAction:(BOOL)_accept {
+  // TODO: this should live in the SoObjects
+  NSException *ex;
+
+  if ((ex = [self validateObjectForStatusChange]) != nil)
+    return ex;
+  
+  ex = [[self clientObject] changeParticipationStatus:
+                              _accept ? @"ACCEPTED" : @"DECLINED"
+                            inContext:[self context]];
+  if (ex != nil) return ex;
+  
+  return self;
+//   return [self redirectToLocation: [self completeURIForMethod:@"../view"]];
+}
+
+- (void) setHasStartDate: (BOOL) aBool
+{
+  hasStartDate = aBool;
+}
+
+- (BOOL) hasStartDate
+{
+  return (!newTask && [self taskStartDate] != nil);
+}
+
+- (BOOL) startDateDisabled
+{
+  return (![self hasStartDate]);
+}
+
+- (void) setHasDueDate: (BOOL) aBool
+{
+  hasDueDate = aBool;
+}
+
+- (BOOL) hasDueDate
+{
+  return (!newTask && [self taskDueDate] != nil);
+}
+
+- (BOOL) dueDateDisabled
+{
+  return (![self hasDueDate]);
+}
+
+- (void) setDueDateDisabled: (BOOL) aBool
+{
+}
+
+- (void) setStartDateDisabled: (BOOL) aBool
+{
+}
+
+@end /* UIxTaskEditor */
diff --git a/UI/Scheduler/UIxTaskProposal.m b/UI/Scheduler/UIxTaskProposal.m
new file mode 100644 (file)
index 0000000..c558ccd
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+  Copyright (C) 2004 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+// $Id: UIxTaskEditor.m 181 2004-08-11 15:13:25Z helge $
+
+#include <SOGoUI/UIxComponent.h>
+
+@interface UIxTaskProposal : UIxComponent
+{
+  id item;
+  id currentDay;
+
+  /* individual values */
+  id startDateHour;
+  id startDateMinute;
+  id endDateHour;
+  id endDateMinute;
+
+  id startDateDay;
+  id startDateMonth;
+  id startDateYear;
+  id endDateDay;
+  id endDateMonth;
+  id endDateYear;
+  
+  NSArray        *participants; /* array of iCalPerson's */
+  NSArray        *resources;    /* array of iCalPerson's */
+  id             duration;
+  
+  NSArray *blockedRanges;
+  NSMutableDictionary *currentQueryParameters;
+}
+
+- (NSMutableDictionary *)currentQueryParameters;
+- (NSDictionary *)currentHourQueryParametersForFirstHalf:(BOOL)_first;
+
+- (void)setICalPersons:(NSArray *)_ps asQueryParameter:(NSString *)_qp;
+@end
+
+#include <SoObjects/Appointments/SOGoAppointmentFolder.h>
+#include <SoObjects/Appointments/SOGoFreeBusyObject.h>
+#include <NGExtensions/NGCalendarDateRange.h>
+#include <NGCards/NGCards.h>
+#include "common.h"
+
+@implementation UIxTaskProposal
+
+- (void)dealloc {
+  [self->blockedRanges   release];
+
+  [self->startDateHour   release];
+  [self->startDateMinute release];
+  [self->startDateDay    release];
+  [self->startDateMonth  release];
+  [self->startDateYear   release];
+
+  [self->endDateHour     release];
+  [self->endDateMinute   release];
+  [self->endDateDay      release];
+  [self->endDateMonth    release];
+  [self->endDateYear     release];
+  [self->duration        release];
+    
+  [self->participants    release];
+  [self->resources       release];
+  
+  [self->currentQueryParameters release];
+  [super dealloc];
+}
+
+/* notifications */
+
+- (void)sleep {
+  [self->currentDay release]; self->currentDay = nil;
+  [self->item       release]; self->item       = nil;
+  [super sleep];
+}
+
+/* accessors */
+
+- (void)setItem:(id)_item {
+  ASSIGN(self->item, _item);
+}
+- (id)item {
+  return self->item;
+}
+
+- (void)setStartDateHour:(id)_startDateHour {
+  ASSIGN(self->startDateHour, _startDateHour);
+}
+- (id)startDateHour {
+  return self->startDateHour;
+}
+- (void)setStartDateMinute:(id)_startDateMinute {
+  ASSIGN(self->startDateMinute, _startDateMinute);
+}
+- (id)startDateMinute {
+  return self->startDateMinute;
+}
+- (void)setStartDateDay:(id)_startDateDay {
+  ASSIGN(self->startDateDay, _startDateDay);
+}
+- (id)startDateDay {
+  return self->startDateDay;
+}
+- (void)setStartDateMonth:(id)_startDateMonth {
+  ASSIGN(self->startDateMonth, _startDateMonth);
+}
+- (id)startDateMonth {
+  return self->startDateMonth;
+}
+- (void)setStartDateYear:(id)_startDateYear {
+  ASSIGN(self->startDateYear, _startDateYear);
+}
+- (id)startDateYear {
+  return self->startDateYear;
+}
+- (void)setEndDateHour:(id)_endDateHour {
+  ASSIGN(self->endDateHour, _endDateHour);
+}
+- (id)endDateHour {
+  return self->endDateHour;
+}
+- (void)setEndDateMinute:(id)_endDateMinute {
+  ASSIGN(self->endDateMinute, _endDateMinute);
+}
+- (id)endDateMinute {
+  return self->endDateMinute;
+}
+- (void)setEndDateDay:(id)_endDateDay {
+  ASSIGN(self->endDateDay, _endDateDay);
+}
+- (id)endDateDay {
+  return self->endDateDay;
+}
+- (void)setEndDateMonth:(id)_endDateMonth {
+  ASSIGN(self->endDateMonth, _endDateMonth);
+}
+- (id)endDateMonth {
+  return self->endDateMonth;
+}
+- (void)setEndDateYear:(id)_endDateYear {
+  ASSIGN(self->endDateYear, _endDateYear);
+}
+- (id)endDateYear {
+  return self->endDateYear;
+}
+
+- (void)setStartDate:(NSCalendarDate *)_date {
+  [self setStartDateHour:[NSNumber numberWithInt:[_date hourOfDay]]];
+  [self setStartDateMinute:[NSNumber numberWithInt:[_date minuteOfHour]]];
+  [self setStartDateDay:[NSNumber numberWithInt:[_date dayOfMonth]]];
+  [self setStartDateMonth:[NSNumber numberWithInt:[_date monthOfYear]]];
+  [self setStartDateYear:[NSNumber numberWithInt:[_date yearOfCommonEra]]];
+}
+- (NSCalendarDate *)startDate {
+  return [NSCalendarDate dateWithYear:[[self startDateYear] intValue]
+                        month:[[self startDateMonth] intValue]
+                        day:[[self startDateDay] intValue]
+                        hour:[[self startDateHour] intValue]
+                        minute:[[self startDateMinute] intValue]
+                        second:0
+                        timeZone:[[self clientObject] userTimeZone]];
+}
+- (void)setEndDate:(NSCalendarDate *)_date {
+  [self setEndDateHour:[NSNumber numberWithInt:[_date hourOfDay]]];
+  [self setEndDateMinute:[NSNumber numberWithInt:[_date minuteOfHour]]];
+  [self setEndDateDay:[NSNumber numberWithInt:[_date dayOfMonth]]];
+  [self setEndDateMonth:[NSNumber numberWithInt:[_date monthOfYear]]];
+  [self setEndDateYear:[NSNumber numberWithInt:[_date yearOfCommonEra]]];
+}
+- (NSCalendarDate *)endDate {
+  return [NSCalendarDate dateWithYear:[[self endDateYear] intValue]
+                        month:[[self endDateMonth] intValue]
+                        day:[[self endDateDay] intValue]
+                        hour:[[self endDateHour] intValue]
+                        minute:[[self endDateMinute] intValue]
+                        second:59
+                        timeZone:[[self clientObject] userTimeZone]];
+}
+
+- (void)setDuration:(id)_duration {
+  ASSIGN(self->duration, _duration);
+}
+- (id)duration {
+  return self->duration;
+}
+- (int)durationInMinutes {
+  return [[self duration] intValue];
+}
+- (NSTimeInterval)durationAsTimeInterval {
+  return [self durationInMinutes] * 60;
+}
+
+- (NSString *)itemDurationText {
+  // TODO: use a formatter
+  // TODO: localize
+  switch ([[self item] intValue]) {
+  case  30: return @"30 minutes";
+  case  60: return @"1 hour";
+  case 120: return @"2 hours";
+  case 240: return @"4 hours";
+  case 480: return @"8 hours";
+  default:
+    return [NSString stringWithFormat:@"%@ minutes", [self item]];
+  }
+}
+
+- (void)setParticipants:(NSArray *)_parts {
+  ASSIGN(self->participants, _parts);
+}
+- (NSArray *)participants {
+  return self->participants;
+}
+- (void)setResources:(NSArray *)_res {
+  ASSIGN(self->resources, _res);
+}
+- (NSArray *)resources {
+  return self->resources;
+}
+
+- (NSArray *)attendees {
+  NSArray *a, *b;
+  
+  a = [self participants];
+  b = [self resources];
+  if ([b count] == 0) return a;
+  if ([a count] == 0) return b;
+  return [a arrayByAddingObjectsFromArray:b];
+}
+
+- (void)setCurrentDay:(id)_day {
+  ASSIGN(self->currentDay, _day);
+}
+- (id)currentDay {
+  return self->currentDay;
+}
+
+- (NSArray *)hours {
+  // TODO: from 'earliest start' to 'latest endtime'
+  unsigned lStartHour = 9, lEndHour = 17, i;
+  NSMutableArray *ma;
+  
+  lStartHour = [[self startDateHour] intValue];
+  lEndHour   = [[self endDateHour]   intValue];
+  if (lStartHour < 1) lStartHour = 1;
+  if (lEndHour < lStartHour) lEndHour = lStartHour + 1;
+  
+  ma = [NSMutableArray arrayWithCapacity:lEndHour - lStartHour + 2];
+  for (i = lStartHour; i <= lEndHour; i++)
+    [ma addObject:[NSNumber numberWithInt:i]];
+  return ma;
+}
+
+- (NSArray *)days {
+  // TODO: from startdate to enddate
+  NSMutableArray *ma;
+  NSCalendarDate *base, *stop, *current;
+  
+  base = [NSCalendarDate dateWithYear:[[self startDateYear] intValue]
+                        month:[[self startDateMonth] intValue]
+                        day:[[self startDateDay] intValue]
+                        hour:12 minute:0 second:0
+                        timeZone:[[self clientObject] userTimeZone]];
+  stop = [NSCalendarDate dateWithYear:[[self endDateYear] intValue]
+                        month:[[self endDateMonth] intValue]
+                        day:[[self endDateDay] intValue]
+                        hour:12 minute:0 second:0
+                        timeZone:[[self clientObject] userTimeZone]];
+  
+  ma = [NSMutableArray arrayWithCapacity:16];
+  
+  current = base;
+  while ([current compare:stop] != NSOrderedDescending) {
+    [current setTimeZone:[[self clientObject] userTimeZone]];
+    [ma addObject:current];
+    
+    /* Note: remember the timezone behaviour of the method below! */
+    current = [current dateByAddingYears:0 months:0 days:1];
+  }
+  return ma;
+}
+
+- (NSArray *)durationSteps {
+  // TODO: make configurable
+  return [NSArray arrayWithObjects:
+                   @"30", @"60", @"120", @"240", @"480", nil];
+}
+
+/* slots */
+
+- (BOOL)isRangeGreen:(NGCalendarDateRange *)_range {
+  unsigned idx;
+  
+  idx = [self->blockedRanges indexOfFirstIntersectingDateRange:_range];
+  if (idx != NSNotFound) {
+    [self debugWithFormat:@"blocked range:\n  range: %@\n  block: %@\nintersection:%@", 
+           _range,
+           [self->blockedRanges objectAtIndex:idx],
+      [_range intersectionDateRange:[self->blockedRanges objectAtIndex:idx]]];
+  }
+  
+  return idx == NSNotFound ? YES : NO;
+}
+
+- (BOOL)isSlotRangeGreen:(NGCalendarDateRange *)_slotRange {
+  NGCalendarDateRange *aptRange;
+  NSCalendarDate *aptStartDate, *aptEndDate;
+
+  if (_slotRange == nil)
+    return NO;
+  
+  /* calculate the interval requested by the user (can be larger) */
+
+  aptStartDate = [_slotRange startDate];
+  // TODO: gives warning on MacOSX
+  aptEndDate   = [[NSCalendarDate alloc] initWithTimeIntervalSince1970:
+                                          [aptStartDate timeIntervalSince1970]
+                                        + [self durationAsTimeInterval]];
+  [aptStartDate setTimeZone:[[self clientObject] userTimeZone]];
+  [aptEndDate   setTimeZone:[[self clientObject] userTimeZone]];
+  aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate:aptStartDate
+                                 endDate:aptEndDate];
+  [aptEndDate release]; aptEndDate = nil;
+  
+  return [self isRangeGreen:aptRange];
+}
+
+- (BOOL)isFirstHalfGreen {
+  /* currentday is the date, self->item the hour */
+  NSCalendarDate *from, *to;
+  NGCalendarDateRange *range;
+
+  from  = [self->currentDay hour:[[self item] intValue] minute:0];
+  to    = [self->currentDay hour:[[self item] intValue] minute:30];
+  range = [NGCalendarDateRange calendarDateRangeWithStartDate:from endDate:to];
+  return [self isSlotRangeGreen:range];
+}
+- (BOOL)isSecondHalfGreen {
+  /* currentday is the date, self->item the hour */
+  NSCalendarDate *from, *to;
+  NGCalendarDateRange *range;
+
+  from  = [self->currentDay hour:[[self item] intValue]     minute:30];
+  to    = [self->currentDay hour:[[self item] intValue] + 1 minute:0];
+  range = [NGCalendarDateRange calendarDateRangeWithStartDate:from endDate:to];
+  return [self isSlotRangeGreen:range];
+}
+
+- (BOOL)isFirstHalfBlocked {
+  return [self isFirstHalfGreen] ? NO : YES;
+}
+- (BOOL)isSecondHalfBlocked {
+  return [self isSecondHalfGreen] ? NO : YES;
+}
+
+/* actions */
+
+- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
+  return YES;
+}
+
+- (id<WOActionResults>)defaultAction {
+  NSCalendarDate *now;
+  
+  now = [NSCalendarDate date];
+
+  [self setDuration:@"120"]; /* 1 hour as default */
+  [self setStartDate:[now hour:9 minute:0]];
+  [self setEndDate:[now hour:18 minute:0]];
+  
+  return self;
+}
+
+- (id)proposalSearchAction {
+  NSArray        *attendees, *uids, *fbos, *ranges;
+  unsigned       i, count;
+  NSMutableArray *allInfos;
+
+  [self logWithFormat:@"search from %@ to %@", 
+         [self startDate], [self endDate]];
+  
+  attendees = [self attendees];
+  uids      = [[self clientObject] uidsFromICalPersons:attendees];
+  if ([uids count] == 0) {
+    [self logWithFormat:@"Note: no UIDs selected."];
+    return self;
+  }
+
+  fbos     = [[self clientObject] lookupFreeBusyObjectsForUIDs:uids
+                                  inContext:[self context]];
+  count    = [fbos count];
+  // wild guess at capacity
+  allInfos = [[[NSMutableArray alloc] initWithCapacity:count * 10] autorelease];
+
+  for (i = 0; i < count; i++) {
+    SOGoFreeBusyObject *fb;
+    NSArray            *infos;
+    
+    fb    = [fbos objectAtIndex:i];
+    if (fb != (SOGoFreeBusyObject *)[NSNull null]) {
+      infos = [fb fetchFreeBusyInfosFrom:[self startDate] to:[self endDate]];
+      [allInfos addObjectsFromArray:infos];
+    }
+  }
+  [self debugWithFormat:@"  processing: %d infos", [allInfos count]];
+  ranges = [allInfos arrayByCreatingDateRangesFromObjectsWithStartDateKey:
+                       @"startDate"
+                     andEndDateKey:@"endDate"];
+  ranges = [ranges arrayByCompactingContainedDateRanges];
+  [self debugWithFormat:@"  ranges: %@", ranges];
+  
+  ASSIGNCOPY(self->blockedRanges, ranges);
+  
+  return self;
+}
+
+/* URLs */
+
+- (NSMutableDictionary *)currentQueryParameters {
+  if(!self->currentQueryParameters) {
+    self->currentQueryParameters = [[self queryParameters] mutableCopy];
+    [self->currentQueryParameters setObject:[self duration] forKey:@"dur"];
+    [self setICalPersons:[self resources] asQueryParameter:@"rs"];
+    [self setICalPersons:[self participants] asQueryParameter:@"ps"];
+  }
+  return self->currentQueryParameters;
+}
+
+- (void)setICalPersons:(NSArray *)_ps asQueryParameter:(NSString *)_qp {
+  NSMutableString *s;
+  unsigned i, count;
+  
+  s = [[NSMutableString alloc] init];
+  count = [_ps count];
+  for(i = 0; i < count; i++) {
+    iCalPerson *p = [_ps objectAtIndex:i];
+    [s appendString:[p rfc822Email]];
+    if(i != (count - 1))
+      [s appendString:@","];
+  }
+  [[self currentQueryParameters] setObject:s forKey:_qp];
+  [s release];
+}
+
+- (NSDictionary *)currentHourQueryParametersForFirstHalf:(BOOL)_first {
+  NSMutableDictionary *qp;
+  NSString *hmString;
+  NSCalendarDate *date;
+  unsigned minute;
+
+  minute = _first ? 0 : 30;
+  qp = [self currentQueryParameters];
+
+  date = [self currentDay];
+  hmString = [NSString stringWithFormat:@"%02d%02d",
+    [item intValue], minute];
+  [self setSelectedDateQueryParameter:date inDictionary:qp];
+  [qp setObject:hmString forKey:@"hm"];
+  return qp;
+}
+
+- (NSDictionary *)currentFirstHalfQueryParameters {
+  return [self currentHourQueryParametersForFirstHalf:YES];
+}
+
+- (NSDictionary *)currentSecondHalfQueryParameters {
+  return [self currentHourQueryParametersForFirstHalf:NO];
+}
+
+@end /* UIxTaskProposal */
diff --git a/UI/Scheduler/UIxTaskView.h b/UI/Scheduler/UIxTaskView.h
new file mode 100644 (file)
index 0000000..51678d7
--- /dev/null
@@ -0,0 +1,40 @@
+// $Id: UIxTaskView.h 768 2005-07-15 00:13:01Z helge $
+
+#ifndef __SOGo_UIxTaskView_H__
+#define __SOGo_UIxTaskView_H__
+
+#include <SOGoUI/UIxComponent.h>
+
+@class NSCalendarDate;
+@class iCalToDo;
+@class iCalPerson;
+@class SOGoDateFormatter;
+
+@interface UIxTaskView : UIxComponent
+{
+  iCalToDo* task;
+  iCalPerson* attendee;
+  SOGoDateFormatter *dateFormatter;
+  id item;
+}
+
+- (iCalToDo *) task;
+
+/* permissions */
+- (BOOL)canAccessApt;
+- (BOOL)canEditApt;
+  
+- (SOGoDateFormatter *)dateFormatter;
+- (NSCalendarDate *)startTime;
+- (NSCalendarDate *)endTime;
+  
+- (NSString *)attributesTabLink;
+- (NSString *)participantsTabLink;
+
+- (NSString *)completeHrefForMethod:(NSString *)_method
+  withParameter:(NSString *)_param
+  forKey:(NSString *)_key;
+
+@end
+
+#endif /* __SOGo_UIxTaskView_H__ */
diff --git a/UI/Scheduler/UIxTaskView.m b/UI/Scheduler/UIxTaskView.m
new file mode 100644 (file)
index 0000000..71bf79c
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+  Copyright (C) 2004-2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#import "UIxTaskView.h"
+#import <NGCards/NGCards.h>
+#import <SOGo/WOContext+Agenor.h>
+#import <Appointments/SOGoTaskObject.h>
+#import <SOGoUI/SOGoDateFormatter.h>
+#import "UIxComponent+Agenor.h"
+#import "common.h"
+
+@interface UIxTaskView (PrivateAPI)
+- (BOOL)isAttendeeActiveUser;
+@end
+
+@implementation UIxTaskView
+
+- (void)dealloc {
+  [task   release];
+  [attendee      release];
+  [dateFormatter release];
+  [item          release];
+  [super dealloc];
+}
+
+/* accessors */
+
+- (NSString *)tabSelection {
+  NSString *selection;
+    
+  selection = [self queryParameterForKey:@"tab"];
+  if (selection == nil)
+    selection = @"attributes";
+  return selection;
+}
+
+- (void)setAttendee:(id)_attendee {
+  ASSIGN(attendee, _attendee);
+}
+- (id)attendee {
+  return attendee;
+}
+
+- (BOOL)isAttendeeActiveUser {
+  NSString *email, *attEmail;
+
+  email    = [[[self context] activeUser] email];
+  attendee = [self attendee];
+  attEmail = [attendee rfc822Email];
+
+  return [email isEqualToString: attEmail];
+}
+
+- (BOOL)showAcceptButton {
+  return [[self attendee] participationStatus] != iCalPersonPartStatAccepted;
+}
+- (BOOL)showRejectButton {
+  return [[self attendee] participationStatus] != iCalPersonPartStatDeclined;
+}
+- (NSString *)attendeeStatusColspan {
+  return [self isAttendeeActiveUser] ? @"1" : @"2";
+}
+
+- (void)setItem:(id)_item {
+  ASSIGN(item, _item);
+}
+- (id)item {
+  return item;
+}
+
+- (SOGoDateFormatter *)dateFormatter {
+  if (dateFormatter == nil) {
+    dateFormatter =
+      [[SOGoDateFormatter alloc] initWithLocale:[self locale]];
+    [dateFormatter setFullWeekdayNameAndDetails];
+  }
+  return dateFormatter;
+}
+
+- (NSCalendarDate *)startTime {
+  NSCalendarDate *date;
+    
+  date = [[self task] startDate];
+  [date setTimeZone:[[self clientObject] userTimeZone]];
+  return date;
+}
+
+- (NSCalendarDate *)endTime {
+  NSCalendarDate *date;
+  
+  date = [[self task] due];
+  [date setTimeZone:[[self clientObject] userTimeZone]];
+  return date;
+}
+
+- (NSString *)resourcesAsString {
+  NSArray *resources, *cns;
+
+  resources = [[self task] resources];
+  cns = [resources valueForKey:@"cnForDisplay"];
+  return [cns componentsJoinedByString:@"<br />"];
+}
+
+- (NSString *) categoriesAsString
+{
+  NSEnumerator *categories;
+  NSArray *rawCategories;
+  NSMutableArray *l10nCategories;
+  NSString *currentCategory, *l10nCategory;
+
+  rawCategories
+    = [[task categories] componentsSeparatedByString: @","];
+  l10nCategories = [NSMutableArray arrayWithCapacity: [rawCategories count]];
+  categories = [rawCategories objectEnumerator];
+  currentCategory = [categories nextObject];
+  while (currentCategory)
+    {
+      l10nCategory
+        = [self labelForKey: [currentCategory stringByTrimmingSpaces]];
+      if (l10nCategory)
+        [l10nCategories addObject: l10nCategory];
+      currentCategory = [categories nextObject];
+    }
+
+  return [l10nCategories componentsJoinedByString: @", "];
+}
+
+// task.organizer.cnForDisplay
+- (NSString *) eventOrganizer
+{
+  CardElement *organizer;
+
+  organizer = [[self task] uniqueChildWithTag: @"organizer"];
+
+  return [organizer value: 0 ofAttribute: @"cn"];
+}
+
+- (NSString *) priorityLabelKey
+{
+  return [NSString stringWithFormat: @"prio_%@", [task priority]];
+}
+
+/* backend */
+
+- (iCalToDo *) task
+{
+  NSString *iCalString;
+  iCalCalendar *calendar;
+  SOGoTaskObject *clientObject;
+    
+  if (task != nil)
+    return task;
+
+  clientObject = [self clientObject];
+
+  iCalString = [[self clientObject] valueForKey:@"iCalString"];
+  if (![iCalString isNotNull] || [iCalString length] == 0) {
+    [self errorWithFormat:@"(%s): missing iCal string!", 
+            __PRETTY_FUNCTION__];
+    return nil;
+  }
+
+  calendar = [iCalCalendar parseSingleFromSource: iCalString];
+  task = [clientObject firstTaskFromCalendar: calendar];
+  [task retain];
+
+  return task;
+}
+
+/* hrefs */
+
+- (NSString *)attributesTabLink {
+  return [self completeHrefForMethod:[self ownMethodName]
+              withParameter:@"attributes"
+              forKey:@"tab"];
+}
+
+- (NSString *)participantsTabLink {
+    return [self completeHrefForMethod:[self ownMethodName]
+                 withParameter:@"participants"
+                 forKey:@"tab"];
+}
+
+- (NSString *)debugTabLink {
+  return [self completeHrefForMethod:[self ownMethodName]
+              withParameter:@"debug"
+              forKey:@"tab"];
+}
+
+- (NSString *)completeHrefForMethod:(NSString *)_method
+  withParameter:(NSString *)_param
+  forKey:(NSString *)_key
+{
+  NSString *href;
+
+  [self setQueryParameter:_param forKey:_key];
+  href = [self completeHrefForMethod:[self ownMethodName]];
+  [self setQueryParameter:nil forKey:_key];
+  return href;
+}
+
+
+/* access */
+
+- (BOOL)isMyApt {
+  NSString   *email;
+  iCalPerson *organizer;
+
+  email     = [[[self context] activeUser] email];
+  organizer = [[self task] organizer];
+  if (!organizer) return YES; // assume this is correct to do, right?
+  return [[organizer rfc822Email] isEqualToString:email];
+}
+
+- (BOOL)canAccessApt {
+  NSString *email;
+  NSArray  *partMails;
+
+  if ([self isMyApt])
+    return YES;
+  
+  /* not my apt - can access if it's public */
+  if ([[[self task] accessClass] isEqualToString: @"PUBLIC"])
+    return YES;
+
+  /* can access it if I'm invited :-) */
+  email     = [[[self context] activeUser] email];
+  partMails = [[[self task] participants] valueForKey:@"rfc822Email"];
+  return [partMails containsObject:email];
+}
+
+- (BOOL)canEditApt {
+  return [self isMyApt];
+}
+
+
+/* action */
+
+- (id<WOActionResults>)defaultAction {
+  if ([self task] == nil) {
+    return [NSException exceptionWithHTTPStatus:404 /* Not Found */
+                       reason:@"could not locate task"];
+  }
+  
+  return self;
+}
+
+- (BOOL)isDeletableClientObject {
+  return [[self clientObject] respondsToSelector:@selector(delete)];
+}
+
+- (id)deleteAction {
+  NSException *ex;
+  id url;
+
+  if ([self task] == nil) {
+    return [NSException exceptionWithHTTPStatus:404 /* Not Found */
+                       reason:@"could not locate task"];
+  }
+
+  if (![self isDeletableClientObject]) {
+    /* return 400 == Bad Request */
+    return [NSException exceptionWithHTTPStatus:400
+                        reason:@"method cannot be invoked on "
+                               @"the specified object"];
+  }
+  
+  if ((ex = [[self clientObject] delete]) != nil) {
+    // TODO: improve error handling
+    [self debugWithFormat:@"failed to delete: %@", ex];
+    return ex;
+  }
+  
+  url = [[[self clientObject] container] baseURLInContext:[self context]];
+  return [self redirectToLocation:url];
+}
+
+@end /* UIxTaskView */
diff --git a/UI/Scheduler/UIxTimeDateControl.h b/UI/Scheduler/UIxTimeDateControl.h
new file mode 100644 (file)
index 0000000..bfe490d
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+  Copyright (C) 2004 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#ifndef UIXTIMEDATECONTROL_H
+#define UIXTIMEDATECONTROL_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSString;
+@class NSCalendarDate;
+@class NSNumber;
+
+@interface UIxTimeDateControl : UIxComponent
+{
+  NSString *controlID;
+  NSString *label;
+  NSCalendarDate *date;
+  id       hour;
+  id       minute;
+  id       second;
+  id       day;
+  id       month;
+  id       year;
+  BOOL     displayTimeControl;
+  unsigned int startHour;
+  unsigned int endHour;
+  NSNumber *currentHour;
+  NSNumber *currentMinute;
+  BOOL isDisabled;
+}
+
+- (void) setDayStartHour: (unsigned int) hour;
+- (void) setDayEndHour: (unsigned int) hour;
+
+- (void)setControlID:(NSString *)_controlID;
+- (NSString *)controlID;
+- (void)setLabel:(NSString *)_label;
+- (NSString *)label;
+- (void)setDate:(NSCalendarDate *)_date;
+- (NSCalendarDate *)date;
+
+- (void)setHour:(id)_hour;
+- (id)hour;
+- (void)setMinute:(id)_minute;
+- (id)minute;
+- (void)setSecond:(id)_second;
+- (id)second;
+- (void)setDay:(id)_day;
+- (id)day;
+- (void)setMonth:(id)_month;
+- (id)month;
+- (void)setYear:(id)_year;
+- (id)year;
+
+- (NSString *)timeID;
+- (NSString *)dateID;
+
+- (void)_setDate:(NSCalendarDate *)_date;
+
+@end
+
+#endif /* UIXTIMEDATECONTROL_H */
index 6ec5b49a0428b85933d6701827c875cb2ba7db45..88ee2f69ac3648e6e4946da61e74442bdb3bc851 100644 (file)
 */
 // $Id$
 
-#include <SOGoUI/UIxComponent.h>
-
-@interface UIxTimeDateControl : UIxComponent
-{
-  NSString *controlID;
-  NSString *label;
-  NSCalendarDate *date;
-  id       hour;
-  id       minute;
-  id       second;
-  id       day;
-  id       month;
-  id       year;
-  BOOL     displayTimeControl;
-}
-
-- (void)setControlID:(NSString *)_controlID;
-- (NSString *)controlID;
-- (void)setLabel:(NSString *)_label;
-- (NSString *)label;
-- (void)setDate:(NSCalendarDate *)_date;
-- (NSCalendarDate *)date;
-
-- (void)setHour:(id)_hour;
-- (id)hour;
-- (void)setMinute:(id)_minute;
-- (id)minute;
-- (void)setSecond:(id)_second;
-- (id)second;
-- (void)setDay:(id)_day;
-- (id)day;
-- (void)setMonth:(id)_month;
-- (id)month;
-- (void)setYear:(id)_year;
-- (id)year;
-
-- (NSString *)timeID;
-- (NSString *)dateID;
-
-- (void)_setDate:(NSCalendarDate *)_date;
-
-@end
-
-#include "common.h"
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSValue.h>
+
+#import <NGObjWeb/SoObjects.h>
+
+#import <SOGo/NSCalendarDate+SOGo.h>
+
+#import "UIxTimeDateControl.h"
 
 @implementation UIxTimeDateControl
 
 - (id)init {
   self = [super init];
   if (self) {
-    self->displayTimeControl = YES;
+    displayTimeControl = YES;
+    isDisabled = NO;
   }
   return self;
 }
 
 - (void)dealloc {
-  [self->controlID release];
-  [self->label     release];
-  [self->date      release];
-  [self->hour      release];
-  [self->minute    release];
-  [self->second    release];
-  [self->day       release];
-  [self->month     release];
-  [self->year      release];
+  [controlID release];
+  [label     release];
+  [date      release];
+  [hour      release];
+  [minute    release];
+  [second    release];
+  [day       release];
+  [month     release];
+  [year      release];
   [super dealloc];
 }
 
 /* accessors */
 
 - (void)setControlID:(NSString *)_controlID {
-  ASSIGNCOPY(self->controlID, _controlID);
+  ASSIGNCOPY(controlID, _controlID);
 }
 - (NSString *)controlID {
-  return self->controlID;
+  return controlID;
 }
 - (void)setLabel:(NSString *)_label {
-  ASSIGNCOPY(self->label, _label);
+  ASSIGNCOPY(label, _label);
 }
 - (NSString *)label {
-  return self->label;
+  return label;
 }
+
 - (void)setDate:(NSCalendarDate *)_date {
+  int minuteValue;
   if (!_date)
     _date = [NSCalendarDate date];
-  [self _setDate:_date];
-  [self setHour:[NSNumber numberWithInt:[_date hourOfDay]]];
-  [self setMinute:[NSNumber numberWithInt:[_date minuteOfHour]]];
-  [self setYear:[NSNumber numberWithInt:[_date yearOfCommonEra]]];
-  [self setMonth:[NSNumber numberWithInt:[_date monthOfYear]]];
-  [self setDay:[NSNumber numberWithInt:[_date dayOfMonth]]];
+  [_date setTimeZone: [[self clientObject] userTimeZone]];
+  [self _setDate: _date];
+
+  minuteValue = [_date minuteOfHour];
+  if (minuteValue % 15)
+    minuteValue += 15 - (minuteValue % 15);
+  [self setHour: [NSNumber numberWithInt: [_date hourOfDay]]];
+  [self setMinute: [NSNumber numberWithInt: minuteValue]];
+  [self setYear: [NSNumber numberWithInt: [_date yearOfCommonEra]]];
+  [self setMonth: [NSNumber numberWithInt: [_date monthOfYear]]];
+  [self setDay: [NSNumber numberWithInt: [_date dayOfMonth]]];
 }
+
 - (void)_setDate:(NSCalendarDate *)_date {
-  ASSIGN(self->date, _date);
+  ASSIGN(date, _date);
 }
+
 - (NSCalendarDate *)date {
-  return self->date;
+  return date;
 }
 
 - (void)setHour:(id)_hour {
-  ASSIGN(self->hour, _hour);
+  ASSIGN(hour, _hour);
 }
 - (id)hour {
-  return self->hour;
+  return hour;
 }
 - (void)setMinute:(id)_minute {
-  ASSIGN(self->minute, _minute);
+  ASSIGN(minute, _minute);
 }
 - (id)minute {
-  return self->minute;
+  return minute;
 }
 - (void)setSecond:(id)_second {
-  ASSIGN(self->second, _second);
+  ASSIGN(second, _second);
 }
 - (id)second {
-  return self->second;
+  return second;
 }
 
 - (void)setDay:(id)_day {
-  ASSIGN(self->day, _day);
+  ASSIGN(day, _day);
 }
 - (id)day {
-  return self->day;
+  return day;
 }
 - (void)setMonth:(id)_month {
-  ASSIGN(self->month, _month);
+  ASSIGN(month, _month);
 }
 - (id)month {
-  return self->month;
+  return month;
 }
 - (void)setYear:(id)_year {
-  ASSIGN(self->year, _year);
+  ASSIGN(year, _year);
 }
 - (id)year {
-  return self->year;
+  return year;
+}
+
+- (void) setDayStartHour: (unsigned int) aStartHour
+{
+  startHour = aStartHour;
 }
 
-- (NSString *)timeID {
+- (void) setDayEndHour: (unsigned int) anEndHour
+{
+  endHour = anEndHour;
+}
+
+- (void) setHourOption: (NSNumber *) option
+{
+  currentHour = option;
+}
+
+- (BOOL) isCurrentHour
+{
+  return [currentHour isEqual: hour];
+}
+
+- (BOOL) isCurrentMinute
+{
+  return [currentMinute isEqual: minute];
+}
+
+- (int) hourValue
+{
+  return [currentHour intValue];
+}
+
+- (NSString *) hourLabel
+{
+  return [NSString stringWithFormat: @"%.2d", [currentHour intValue]];
+}
+
+- (NSArray *) selectableHours
+{
+  NSMutableArray *hours;
+  unsigned int h;
+
+  hours = [NSMutableArray new];
+  [hours autorelease];
+
+  for (h = startHour; h < (endHour + 1); h++)
+    [hours addObject: [NSNumber numberWithInt: h]];
+
+  return hours;
+}
+
+- (NSString *) hourSelectId
+{
+  return [[self controlID] stringByAppendingString:@"_time_hour"];
+}
+
+- (void) setMinuteOption: (NSNumber *) option
+{
+  currentMinute = option;
+}
+
+- (int) minuteValue
+{
+  return [currentMinute intValue];
+}
+
+- (NSString *) minuteLabel
+{
+  return [NSString stringWithFormat: @"%.2d", [currentMinute intValue]];
+}
+
+- (NSArray *) selectableMinutes
+{
+  NSMutableArray *minutes;
+  unsigned int m;
+
+  minutes = [NSMutableArray new];
+  [minutes autorelease];
+
+  for (m = 0; m < 60; m += 15)
+    [minutes addObject: [NSNumber numberWithInt: m]];
+
+  return minutes;
+}
+
+- (NSString *) minuteSelectId
+{
+  return [[self controlID] stringByAppendingString:@"_time_minute"];
+}
+
+- (NSString *) timeID
+{
   return [[self controlID] stringByAppendingString:@"_time"];
 }
-- (NSString *)dateID {
+
+- (NSString *) dateID
+{
   return [[self controlID] stringByAppendingString:@"_date"];
 }
 
-- (void)setDisplayTimeControl:(BOOL)_displayTimeControl {
-  self->displayTimeControl = _displayTimeControl;
-}
-- (BOOL)displayTimeControl {
-  return self->displayTimeControl;
+- (void) setDisplayTimeControl: (BOOL) _displayTimeControl
+{
+  displayTimeControl = _displayTimeControl;
 }
 
-#if 0
-- (NSString *)timeControlStyle {
-  if (self->displayTimeControl)
-    return @"visibility : visible;";
-  return @"visibility : hidden;";
+- (BOOL) displayTimeControl
+{
+  return displayTimeControl;
 }
-#endif
 
 /* processing request */
 
-- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
+- (void) takeValuesFromRequest: (WORequest *) _rq
+                     inContext: (WOContext *) _ctx
+{
   NSCalendarDate *d;
   unsigned _year, _month, _day, _hour, _minute, _second;
 
   [super takeValuesFromRequest:_rq inContext:_ctx];
 
   _year  = [[self year] intValue];
-  if(_year == 0)
-      return;
-
-  _month  = [[self month]  intValue];
-  _day    = [[self day]    intValue];
-  _hour   = [[self hour]   intValue];
-  _minute = [[self minute] intValue];
-  _second = [[self second] intValue];
-  d       = [NSCalendarDate dateWithYear:_year
-                            month:_month
-                            day:_day
-                            hour:_hour
-                            minute:_minute
-                            second:_second
-                            timeZone:[self viewTimeZone]];
-  [self _setDate:d];
+  if (_year > 0)
+    {
+      [self setHour: [_rq formValueForKey: [self hourSelectId]]];
+      [self setMinute: [_rq formValueForKey: [self minuteSelectId]]];
+
+      _month  = [[self month] intValue];
+      _day    = [[self day] intValue];
+      _hour   = [[self hour] intValue];
+      _minute = [[self minute] intValue];
+      _second = [[self second] intValue];
+      
+      d = [NSCalendarDate dateWithYear: _year month:_month day:_day
+                          hour:_hour minute:_minute second:_second
+                          timeZone: [[self clientObject] userTimeZone]];
+      [self _setDate: d];
+    }
+}
+
+- (void) setDisabled: (BOOL) disabled
+{
+  isDisabled = disabled;
+}
+
+- (BOOL) disabled
+{
+  return isDisabled;
 }
 
 @end /* UIxTimeDateControl */
diff --git a/UI/Scheduler/UIxTimeSelector.m b/UI/Scheduler/UIxTimeSelector.m
deleted file mode 100644 (file)
index fcc2a1d..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id$
-
-#include <NGObjWeb/WOComponent.h>
-
-@class NSString, NSCalendarDate, NSArray;
-
-@interface UIxTimeSelector : WOComponent
-{
-  NSString *timeID;
-  id       hour;
-  id       minute;
-  NSString *minuteInterval;
-}
-
-- (void)setTimeID:(NSString *)_timeID;
-- (NSString *)timeID;
-- (void)setHour:(id)_hour;
-- (id)hour;
-- (void)setMinute:(id)_minute;
-- (id)minute;
-- (void)setMinuteInterval:(NSString *)_minuteInterval;
-- (NSString *)minuteInterval;
-
-@end
-
-#include "common.h"
-
-@implementation UIxTimeSelector
-
-- (void)dealloc {
-  [self->timeID         release];
-  [self->hour           release];
-  [self->minute         release];
-  [self->minuteInterval release];
-  [super dealloc];
-}
-
-/* accessors */
-
-- (void)setTimeID:(NSString *)_timeID {
-  ASSIGNCOPY(self->timeID, _timeID);
-}
-- (NSString *)timeID {
-  return self->timeID;
-}
-
-- (void)setHour:(id)_hour {
-    ASSIGN(self->hour, _hour);
-}
-- (id)hour {
-    return self->hour;
-}
-- (void)setMinute:(id)_minute {
-    ASSIGN(self->minute, _minute);
-}
-- (id)minute {
-    return self->minute;
-}
-
-- (void)setMinuteInterval:(NSString *)_minuteInterval {
-  ASSIGNCOPY(self->minuteInterval, _minuteInterval);
-}
-- (NSString *)minuteInterval {
-  if(self->minuteInterval == nil)
-    return @"1";
-  return self->minuteInterval;
-}
-
-- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { 
-    /* call super, so that the form values are applied on the popups */
-    [super takeValuesFromRequest:_rq inContext:_ctx];
-}
-
-@end /* UIxTimeSelector */
index bb109a4ae13c646364379b7db806f61ab8563cba..5f7079c03136a8a08c3dbf999626e24366656d6b 100644 (file)
 #import <Foundation/Foundation.h>
 
 #if LIB_FOUNDATION_LIBRARY
-#  include <Foundation/exceptions/GeneralExceptions.h>
+#  import <Foundation/exceptions/GeneralExceptions.h>
 #elif NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY
-#  include <NGExtensions/NGObjectMacros.h>
-#  include <NGExtensions/NSString+Ext.h>
+#  import <NGExtensions/NGObjectMacros.h>
+#  import <NGExtensions/NSString+Ext.h>
 #endif
 
-#include <NGExtensions/NGExtensions.h>
-#include <NGObjWeb/NGObjWeb.h>
-#include <NGObjWeb/SoObjects.h>
+#import <NGExtensions/NGExtensions.h>
+#import <NGObjWeb/NGObjWeb.h>
+#import <NGObjWeb/SoObjects.h>
diff --git a/UI/Scheduler/iCalPerson+UIx.h b/UI/Scheduler/iCalPerson+UIx.h
deleted file mode 100644 (file)
index 02658aa..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: UIxAppointmentEditor.m 181 2004-08-11 15:13:25Z helge $
-
-#ifndef __iCalPerson_UIx_H__
-#define __iCalPerson_UIx_H__
-
-#include <NGiCal/NGiCal.h>
-
-@class NSString;
-
-@interface iCalPerson(Convenience)
-- (NSString *)cnForDisplay;
-@end
-
-#endif /* __iCalPerson_UIx_H__ */
diff --git a/UI/Scheduler/iCalPerson+UIx.m b/UI/Scheduler/iCalPerson+UIx.m
deleted file mode 100644 (file)
index b923475..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-  Copyright (C) 2004 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-// $Id: UIxAppointmentEditor.m 181 2004-08-11 15:13:25Z helge $
-
-#include "iCalPerson+UIx.h"
-#include "common.h"
-
-@implementation iCalPerson(Convenience)
-
-- (NSString *)cnForDisplay {
-  return [self cnWithoutQuotes];
-}
-
-@end /* iCalPerson(Convenience) */
diff --git a/UI/Scheduler/iCalRecurrenceRule+SOGo.m b/UI/Scheduler/iCalRecurrenceRule+SOGo.m
deleted file mode 100644 (file)
index 6d42ca8..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-  Copyright (C) 2004-2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-
-#include <NGiCal/NGiCal.h>
-#include "common.h"
-
-/* HACK ALERT
-   This is a pretty ugly (unfortunately necessary) hack to map our limited
-   set of recurrence rules back to the popup list
-*/
-@interface iCalRecurrenceRule (UsedPrivates)
-- (NSString *)freq;
-- (NSString *)byDayList;
-@end /* iCalRecurrenceRule (UsedPrivates) */
-
-@implementation iCalRecurrenceRule (SOGoExtensions)
-
-- (NSString *)cycleRepresentationForSOGo {
-  NSMutableString *s;
-  
-  s = [NSMutableString stringWithCapacity:20];
-  [s appendString:@"FREQ="];
-  [s appendString:[self freq]];
-  if ([self repeatInterval] != 1) {
-    [s appendFormat:@";INTERVAL=%d", [self repeatInterval]];
-  }
-  if (self->byDay.mask != 0) {
-    [s appendString:@";BYDAY="];
-    [s appendString:[self byDayList]];
-  }
-  return s;
-}
-
-@end /* iCalRecurrenceRule (SOGoExtensions) */
diff --git a/UI/Scheduler/images/next_week.gif b/UI/Scheduler/images/next_week.gif
deleted file mode 100644 (file)
index bacfdb0..0000000
Binary files a/UI/Scheduler/images/next_week.gif and /dev/null differ
diff --git a/UI/Scheduler/images/previous_week.gif b/UI/Scheduler/images/previous_week.gif
deleted file mode 100644 (file)
index 5f1a0da..0000000
Binary files a/UI/Scheduler/images/previous_week.gif and /dev/null differ
index 1a57d357a54386a3a35cfb309e67df0b851ccff2..c0fdd8b3889174709a4817369162c06d48ad432b 100644 (file)
@@ -1,5 +1,5 @@
 {
-  requires = ( MAIN, CommonUI, Appointments );
+  requires = ( MAIN, CommonUI, Appointments, Contacts, ContactsUI );
 
   publicResources = (
     previous_week.gif,
 
   categories = {
     SOGoAppointmentFolder = {
+      slots = {
+        toolbar = {
+          protectedBy = "View";
+          value = "SOGoAppointmentFolder.toolbar";
+        };
+      };
       methods = {
+        view = {
+          protectedBy = "View";
+          pageName    = "UIxCalMainView";
+        };
+        dateselector = {
+          protectedBy = "View";
+          pageName    = "UIxCalDateSelector"; 
+        };
+        aptlist = {
+          protectedBy = "View";
+          pageName    = "UIxCalAptListView"; 
+        };
+        taskslist = {
+          protectedBy = "View";
+          pageName    = "UIxCalTasksListView"; 
+        };
+        dayview = {
+          protectedBy = "View";
+          pageName    = "UIxCalDayView"; 
+        };
+        weekview = {
+          protectedBy = "View";
+          pageName    = "UIxCalWeekView"; 
+        };
+        monthview = {
+          protectedBy = "View";
+          pageName    = "UIxCalMonthView"; 
+        };
+        newevent = {
+          protectedBy = "Add Documents, Images, and Files";
+          pageName    = "UIxAppointmentEditor"; 
+          actionName  = "new";
+        };
+        newtask = { 
+          protectedBy = "Add Documents, Images, and Files";
+          pageName    = "UIxTaskEditor"; 
+          actionName  = "new";
+        };
+        show = { 
+          protectedBy = "View";
+          pageName    = "UIxCalView"; 
+          actionName  = "redirectForUIDs";
+        };
+        proposal = { 
+          protectedBy = "View";
+          pageName    = "UIxAppointmentProposal"; 
+        };
+        proposalSearch = { 
+          protectedBy = "View";
+          pageName    = "UIxAppointmentProposal"; 
+          actionName  = "proposalSearch";
+        };
+        batchDelete = {
+          protectedBy = "Delete Objects";
+          pageName    = "UIxCalMainView";
+          actionName  = "batchDelete";
+        };
+        updateCalendars = {
+          protectedBy = "View";
+          pageName    = "UIxCalMainView";
+          actionName  = "updateCalendars";
+        };
+        checkRights = {
+          protectedBy = "View";
+          pageName    = "UIxCalMainView";
+          actionName  = "checkRights";
+        };
+        freeBusyTable = {
+          protectedBy = "View";
+          pageName    = "UIxFreeBusyUserSelectorTable";
+        };
+
+/* TODO: delete the following components */
         dayoverview = {
           protectedBy = "View";
           pageName    = "UIxCalDayOverview"; 
           protectedBy = "View";
           pageName    = "UIxCalDayListview"; 
         };
-        dayprintview = { 
-          protectedBy = "View";
-          pageName    = "UIxCalDayPrintview"; 
-        };
         weekoverview = { 
           protectedBy = "View";
           pageName    = "UIxCalWeekOverview"; 
           protectedBy = "View";
           pageName    = "UIxCalWeekColumnsview"; 
         };
-        weekprintview = { 
-          protectedBy = "View";
-          pageName    = "UIxCalWeekPrintview"; 
-        };
         monthoverview = { 
           protectedBy = "View";
           pageName    = "UIxCalMonthOverview"; 
         };
-        monthprintview = { 
-          protectedBy = "View";
-          pageName    = "UIxCalMonthPrintview"; 
-        };
         yearoverview = { 
           protectedBy = "View";
           pageName    = "UIxCalYearOverview"; 
         };
-        new = { 
-          protectedBy = "View";
-          pageName    = "UIxAppointmentEditor"; 
-          actionName  = "new";
-        };
-        show = { 
-          protectedBy = "View";
-          pageName    = "UIxCalView"; 
-          actionName  = "redirectForUIDs";
-        };
-        proposal = { 
-          protectedBy = "View";
-          pageName    = "UIxAppointmentProposal"; 
-        };
-        proposalSearch = { 
-          protectedBy = "View";
-          pageName    = "UIxAppointmentProposal"; 
-          actionName  = "proposalSearch";
-        };
       };
     };
 
     SOGoAppointmentObject = {
-      methods = {
-        printview = { 
+      slots = {
+        toolbar = {
           protectedBy = "View";
-          pageName    = "UIxAppointmentPrintview"; 
+          value = "SOGoAppointmentObject.toolbar";
         };
+      };
+      methods = {
         view = { 
           protectedBy = "View";
           pageName    = "UIxAppointmentView"; 
           pageName    = "UIxAppointmentView"; 
           actionName  = "delete";
         };
-        edit = { 
+        edit = {
+          protectedBy = "View";
+          pageName    = "UIxAppointmentEditor"; 
+        };
+        editAsAppointment = { 
           protectedBy = "View";
           pageName    = "UIxAppointmentEditor"; 
         };
           pageName    = "UIxAppointmentEditor"; 
           actionName  = "save";
         };
+        saveAsAppointment = {
+          protectedBy = "View";
+          pageName    = "UIxAppointmentEditor"; 
+          actionName  = "save";
+        };
         accept = { 
           protectedBy = "View";
           pageName    = "UIxAppointmentEditor"; 
           pageName    = "UIxAppointmentEditor"; 
           actionName  = "test";
         };
+        contactSearch = {
+          protectedBy = "View";
+          pageName    = "UIxFreeBusyUserSelector";
+          actionName  = "contactSearch";
+        };
+      };
+    };
+
+    SOGoTaskObject = {
+      slots = {
+        toolbar = {
+          protectedBy = "View";
+          value = "SOGoAppointmentObject.toolbar";
+        };
+      };
+      methods = {
+        view = { 
+          protectedBy = "View";
+          pageName    = "UIxTaskView"; 
+        };
+        delete = { 
+          protectedBy = "View";
+          pageName    = "UIxTaskView"; 
+          actionName  = "delete";
+        };
+        edit = { 
+          protectedBy = "Change Images and Files";
+          pageName    = "UIxTaskEditor"; 
+        };
+        editAsTask = { 
+          protectedBy = "Change Images and Files";
+          pageName    = "UIxTaskEditor"; 
+        };
+        save = { 
+          protectedBy = "Change Images and Files";
+          pageName    = "UIxTaskEditor"; 
+          actionName  = "save";
+        };
+        saveAsTask = { 
+          protectedBy = "Change Images and Files";
+          pageName    = "UIxTaskEditor"; 
+          actionName  = "save";
+        };
+        changeStatus = {
+          protectedBy = "Change Images and Files";
+          pageName    = "UIxTaskEditor"; 
+          actionName  = "changeStatus";
+        };
+        accept = { 
+          protectedBy = "Change Images and Files";
+          pageName    = "UIxTaskEditor"; 
+          actionName  = "accept";
+        };
+        decline = { 
+          protectedBy = "Change Images and Files";
+          pageName    = "UIxTaskEditor"; 
+          actionName  = "decline";
+        };
+        test = { 
+          protectedBy = "View";
+          pageName    = "UIxTaskEditor"; 
+          actionName  = "test";
+        };
       };
     };
   };
diff --git a/UI/Scheduler/skycalendar.js b/UI/Scheduler/skycalendar.js
deleted file mode 100644 (file)
index 897aa23..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-// Title: Tigra Calendar
-// Description: See the demo at url
-// URL: http://www.softcomplex.com/products/tigra_calendar/
-// Version: 3.1 (European date format)
-// Date: 08-08-2002 (mm-dd-yyyy)
-// Feedback: feedback@softcomplex.com (specify product title in the subject)
-// Note: Permission given to use this script in ANY kind of applications if
-//    header lines are left unchanged.
-// Note: Script consists of two files: calendar?.js and calendar.html
-// About us: Our company provides offshore IT consulting services.
-//    Contact us at sales@softcomplex.com if you have any programming task you
-//    want to be handled by professionals. Our typical hourly rate is $20.
-
-// modified by Martin Hoerning, mh@skyrix.com, 2002-12-05
-// 2003-01-23 added date format support (Martin Hoerning)
-
-// if two digit year input dates after this year considered 20 century.
-var NUM_CENTYEAR = 30;
-// are year scrolling buttons required by default
-var BUL_YEARSCROLL = true;
-var DEF_CALPAGE = 'skycalendar.html';
-
-var calendars = [];
-var RE_NUM = /^\-?\d+$/;
-var dateFormat = "yyyy-mm-dd";
-
-function skycalendar(obj_target) {
-  // assing methods
-  this.gen_date = cal_gen_date1;
-  this.gen_tsmp = cal_gen_tsmp1;
-  this.prs_date = cal_prs_date1;
-  this.prs_tsmp = cal_prs_tsmp1;
-  this.popup    = cal_popup1;
-  this.setCalendarPage = cal_setcalpage1;
-  this.setDateFormat   = cal_setdateformat1;
-
-  // validate input parameters
-  if (!obj_target)
-    return cal_error("Error calling the calendar: no target control specified");
-  if (obj_target.value == null)
-    return cal_error("Error calling the calendar: parameter specified is not valid tardet control");
-  this.target = obj_target;
-  this.year_scroll = BUL_YEARSCROLL;
-  this.calpage     = DEF_CALPAGE;
-       
-  // register in global collections
-  this.id = calendars.length;
-  calendars[this.id] = this;
-}
-
-function cal_setcalpage1(str_page) {
-  this.calpage = str_page;
-}
-
-function cal_setdateformat1(str_dateformat) {
-  this.dateFormat = str_dateformat;
-}
-
-function cal_popup1(str_datetime) {
-  this.dt_current = this.prs_tsmp(str_datetime ? str_datetime : this.target.value);
-  if (!this.dt_current) return;
-
-  var obj_calwindow = window.open(
-    this.calpage+'?datetime=' + this.dt_current.valueOf()+ '&id=' + this.id,
-      'Calendar', 'width=200,height=190'+
-      ',status=no,resizable=no,top=200,left=200,dependent=yes,alwaysRaised=yes'
-    );
-  obj_calwindow.opener = window;
-  obj_calwindow.focus();
-}
-
-// timestamp generating function
-function cal_gen_tsmp1(dt_datetime) {
-  return this.gen_date(dt_datetime);
-}
-
-// date generating function
-function cal_gen_date1(dt_datetime) {
-  var out = this.dateFormat;
-  var idx;
-  if (out.indexOf("yyyy") != 1) {
-    t = out.split("yyyy");
-    out = t.join(dt_datetime.getFullYear());
-  }
-  else {
-    return cal_error("Missing year-part 'yyyy' in format: '"+this.dateFormat);
-  }
-  if (out.indexOf("mm") != 1) {
-    t = out.split("mm");
-    out = t.join((dt_datetime.getMonth() < 9 ? '0' : '')+
-                 (dt_datetime.getMonth()+1));
-  }
-  else {
-    return cal_error("Missing month-part 'mm' in format: '"+this.dateFormat);
-  }
-  if (out.indexOf("dd") != 1) {
-    t = out.split("dd");
-    out = t.join((dt_datetime.getDate() < 10 ? '0' : '')+
-                 dt_datetime.getDate());
-  }
-  else {
-    return cal_error("Missing day-part 'dd' in format: '"+this.dateFormat);
-  }
-
-  return out;
-}
-
-// timestamp parsing function
-function cal_prs_tsmp1(str_datetime) {
-  // if no parameter specified return current timestamp
-  if (!str_datetime)
-    return (new Date());
-
-  // if positive integer treat as milliseconds from epoch
-  if (RE_NUM.exec(str_datetime))
-    return new Date(str_datetime);
-               
-  return this.prs_date(str_datetime);
-}
-
-// date parsing function
-function cal_prs_date1(str_date) {
-  var idx;
-  var year  = null;
-  var month = null;
-  var day   = null;
-
-  if (str_date.length != this.dateFormat.length) {
-    return cal_error ("Invalid date format: '"+str_date+
-                      "'.\nFormat accepted is '"+this.dateFormat+"'.");
-  }
-
-  if ((idx = this.dateFormat.indexOf("yyyy")) != 1) {
-    year = str_date.substring(idx, idx+4);
-  }
-  else {
-    return cal_error("Missing year-part 'yyyy' in format: '"+this.dateFormat);
-  }
-  if ((idx = this.dateFormat.indexOf("mm")) != 1) {
-    month = str_date.substring(idx, idx+2);
-  }
-  else {
-    return cal_error("Missing month-part 'mm' in format: '"+this.dateFormat);
-  }
-  if ((idx = this.dateFormat.indexOf("dd")) != 1) {
-    day = str_date.substring(idx, idx+2);
-  }
-  else {
-    return cal_error("Missing day-part 'dd' in format: '"+this.dateFormat);
-  }
-
-  if (!day) return cal_error("Invalid date format: '"+str_date+
-                             "'.\nNo day of month value can be found.");
-  if (!RE_NUM.exec(day))
-    return cal_error("Invalid day of month value: '"+day+
-                     "'.\nAllowed values are unsigned integers.");
-
-  if (!month) return cal_error("Invalid date format: '"+str_date+
-                             "'.\nNo month of year value can be found.");
-  if (!RE_NUM.exec(month))
-    return cal_error("Invalid month of year value: '"+month+
-                     "'.\nAllowed values are unsigned integers.");
-  
-  if (!year) return cal_error("Invalid date format: '"+str_date+
-                             "'.\nNo year value can be found.");
-  if (!RE_NUM.exec(year))
-    return cal_error("Invalid year value: '"+year+
-                     "'.\nAllowed values are unsigned integers.");
-
-  
-  var dt_date = new Date();
-  dt_date.setDate(1);
-  if (month < 1 || month > 12)
-    return cal_error("Invalid month value: '"+month+
-                     "'.\nAllowed range is 01-12.");
-  dt_date.setMonth(month-1);
-  if (year < 100) year = Number(year)+(year < NUM_CENTYEAR ? 2000 : 1900);
-  dt_date.setFullYear(year);
-  var dt_numdays = new Date(year, month, 0);
-  dt_date.setDate(day);
-  if (dt_date.getMonth() != (month-1))
-    return cal_error("Invalid day of month value: '"+day+
-                     "'.\nAllowed range is 01-"+dt_numdays.getDate()+".");
-  return (dt_date);
-}
-
-function cal_error(str_message) {
-  alert (str_message);
-  return null;
-}
index 5a3fbc72ac8178bdb239b3035bb438fda16bab6b..9309fa4a0a90e36d5673a2b720b9dae902c79a1c 100644 (file)
 <?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:label="OGo:label"
-  className="UIxPageFrame"
-  title="name"
->
-  <var:js-stringtable const:framework="ContactsUI.SOGo"
-                      const:identifier="labels" />
-  
-  <style>
-    table.editsec {
-      background-color: #e8e8e0;
-      width:            100%;
-    }
-  </style>
-  
-  <form var:href="clientObject.baseURL" name="editform"
-        onsubmit="return validateContactEditor()">
-    <table cellspacing="0" cellpadding="5" width="100%">
-      <tr>
-        <td>
-          <table cellpadding="0" cellspacing="0" width="100%">
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="name"
+    const:popup="YES"
+    >
+    <form var:href="clientObject.baseURL" name="editform"
+      onsubmit="return validateContactEditor()">
+
+      <div class="tabsContainer" id="editorTabs">
+        <ul>
+          <li target="baseInfos"><var:string label:value="Contact" /></li>
+          <li target="addressesInfos"><var:string label:value="Addresses" /></li>
+          <li target="otherInfos"><var:string label:value="Other Infos" /></li>
+        </ul>
+
+        <div id="baseInfos" class="tab">
+          <table>
             <tr>
-              <td width="5"/>
-              <td class="window_label">
-                <var:string label:value="Contact editor" /></td>
-              <td width="36" align="right" valign="center">
-                <var:component className="UIxWinClose" />
-              </td>
+              <td class="titleCell"><var:string label:value="Common" /></td>
             </tr>
-          </table>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <var:if condition="hasErrorText">
-            <div style="background-color: #AA0000;">
-             <var:string value="errorText" />
-            </div>
-            <hr />
-          </var:if>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <var:if condition="clientObject.isVCardRecord">
-            <h4>Editing of vCards is not yet supported!</h4>
-          </var:if>
-
-  <var:if condition="clientObject.isVCardRecord" const:negate="1">
-          <table border="0" cellpadding="2" cellspacing="0" class="editsec">
             <tr>
-              <td align="right" colspan="2">
-<!-- superflous without Anais
-                <var:component className="AnaisSelector"
-                               const:windowId="UIxContactTemplates"
-                               label:title="Copy from Anais"
-                               const:callback="copyContact"
-                               const:extraAttributes="cn, givenName,telephoneNumber,facsimileTelephoneNumber,mobile,postalAddress,homePostalAddress,departmentNumber,l"
-                />
--->
+              <td>
+                <label><var:string label:value="Firstname: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="givenName"
+                    id="givenName"
+                    var:value="snapshot.givenName" />
+                </label>
               </td>
             </tr>
             <tr>
-              <td align="left" colspan="2">
-                <span class="aptview_title">
-                  <var:string label:value="Common" />
-                </span>
+              <td>
+                <label><var:string label:value="Lastname: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="sn" id="sn"
+                    var:value="snapshot.sn" />
+                </label>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="Lastname" />:
-                </span>
-              </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="sn" id="sn"
-                         var:value="snapshot.sn" size="60" />
-                </span>
+            <tr>
+              <td>
+                <label><var:string label:value="Display Name: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="fn" id="fn"
+                    var:value="snapshot.fn" />
+                </label>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="Firstname" />:
-                </span>
-              </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="hidden" name="cn" id="cn" var:value="anaisCN"/>
-                  <input type="text" name="givenName" id="givenName"
-                         var:value="snapshot.givenName" size="60" />
-                </span>
+            <tr>
+              <td>
+                <label><var:string label:value="Nickname: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="nickname" id="nickname"
+                    var:value="snapshot.nickname" />
+                </label>
               </td>
             </tr>
           </table>
-          <br />
 
-          <table border="0" cellpadding="2" cellspacing="0" class="editsec">
+          <br />
+          <table id="emailInfos">
             <tr>
-              <td align="left" colspan="2">
-                <span class="aptview_title">
-                  <var:string label:value="Phones" />
-                </span>
+              <td class="titleCell"><var:string label:value="EMail" /></td>
+              <td class="preferred">
+                <var:string label:value="Preferred" />
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="OfficePhone" />:
-                </span>
+            <tr>
+              <td>
+                <label><var:string label:value="Work: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workMail" id="workMail"
+                    var:value="snapshot.workMail" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text"
-                         name="telephoneNumber"
-                         id="telephoneNumber"
-                         var:value="snapshot.telephoneNumber"
-                         size="60"
-                  />
-                </span>
+              <td class="preferred">
+                <input type="radio" name="preferredEmail"
+                  var:selection="preferredEmail" const:value="work" />
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="HomePhone" />:
-                </span>
+            <tr>
+              <td>
+                <label><var:string label:value="Home: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="homeMail"
+                    id="homeMail" var:value="snapshot.homeMail" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text"
-                         name="homeTelephoneNumber"
-                         id="homeTelephoneNumber"
-                         var:value="snapshot.homeTelephoneNumber"
-                         size="60"
+              <td class="preferred">
+                <input type="radio"
+                  name="preferredEmail"
+                  var:selection="preferredEmail"
+                  const:value="home"
                   />
-                </span>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="MobilePhone" />:
-                </span>
+          </table>
+          <br />
+          <table>
+            <tr>
+              <td class="titleCell"><var:string label:value="Phones" /></td>
+            </tr>
+            <tr>
+              <td>
+                <label><var:string label:value="Work: " const:escapeHTML="NO" />
+                  <input type="text" class="textField"
+                    name="telephoneNumber"
+                    id="telephoneNumber"
+                    var:value="snapshot.telephoneNumber"
+                    /></label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <!-- pamela.schema defines this as 'mobile',
-                       NOT 'mobileTelephoneNumber'
-                  -->
-                  <input type="text" name="mobile" id="mobile"
-                         var:value="snapshot.mobile" size="60" />
-                </span>
+            </tr>
+            <tr>
+              <td>
+                <label><var:string label:value="Home: " const:escapeHTML="NO" />
+                  <input type="text" class="textField"
+                    name="homeTelephoneNumber"
+                    id="homeTelephoneNumber"
+                    var:value="snapshot.homeTelephoneNumber"
+                    
+                    />
+                </label>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="Fax" />:
-                </span>
+            <tr>
+              <td>
+                <label><var:string label:value="Mobile: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="mobile" id="mobile"
+                    var:value="snapshot.mobile" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text"
-                         name="facsimileTelephoneNumber"
-                         id="facsimileTelephoneNumber"
-                         var:value="snapshot.facsimileTelephoneNumber"
-                         size="60"
-                  />
-                </span>
+            </tr>
+            <tr>
+              <td>
+                <label><var:string label:value="Fax: " const:escapeHTML="NO" />
+                  <input type="text" class="textField"
+                    name="facsimileTelephoneNumber"
+                    id="facsimileTelephoneNumber"
+                    var:value="snapshot.facsimileTelephoneNumber"
+                    
+                    />
+                </label>
+              </td>
+            </tr>
+            <tr>
+              <td>
+                <label><var:string label:value="Pager: " const:escapeHTML="NO" />
+                  <input type="text" class="textField"
+                    name="pager"
+                    id="pager"
+                    var:value="snapshot.pager"
+                    
+                    />
+                </label>
               </td>
             </tr>
           </table>
-          <br />
+        </div>
 
-          <table border="0" cellpadding="2" cellspacing="0" class="editsec">
+        <div id="addressesInfos" class="tab">
+          <table>
             <tr>
-              <td align="left" colspan="2">
+              <td class="titleCell" colspan="2">
                 <span class="aptview_title">
-                  <var:string label:value="Addresses" />
+                  <var:string label:value="Work" />
                 </span>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="Postal" />:
-                </span>
+            <tr>
+              <td class="firstColumn">
+                <label>
+                  <var:string label:value="Title: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="title"
+                    id="title"
+                    var:value="snapshot.title" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <textarea name="postalAddress"
-                            id="postalAddress"
-                            rows="3"
-                            cols="60"
-                            wrap="physical"
-                            var:value="snapshot.postalAddress"
-                  />
-                </span>
+              <td class="secondColumn">
+                <label>
+                  <var:string label:value="Service: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workService"
+                    id="workService"
+                    var:value="snapshot.workService" />
+                </label>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="Home" />:
-                </span>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="Company: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workCompany"
+                    id="workCompany"
+                    var:value="snapshot.workCompany" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <textarea name="homePostalAddress"
-                            rows="3"
-                            cols="60"
-                            wrap="physical"
-                            var:value="snapshot.homePostalAddress"
-                  />
-                </span>
+            </tr>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="Street Address: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workStreetAddress"
+                    id="workStreetAddress"
+                    var:value="snapshot.workStreetAddress" />
+                </label>
+              </td>
+            </tr>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="City: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workCity"
+                    id="workCity"
+                    var:value="snapshot.workCity" />
+                </label>
+              </td>
+            </tr>
+            <tr>
+              <td class="firstColumn">
+                <label><var:string label:value="State/Province: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workState"
+                    id="workState"
+                    var:value="snapshot.workState" />
+                </label>
+              </td>
+              <td class="secondColumn">
+                <label><var:string
+                    label:value="Zip or Postal Code: "
+                    const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workPostalCode"
+                    id="workPostalCode"
+                    var:value="snapshot.workPostalCode" />
+                </label>
+              </td>
+            </tr>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="Country: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workCountry"
+                    id="workCountry"
+                    var:value="snapshot.workCountry" />
+                </label>
+              </td>
+            </tr>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="Web: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="workURL"
+                    var:value="snapshot.workURL" />
+                </label>
               </td>
             </tr>
           </table>
-          <br />
-          <table border="0" cellpadding="2" cellspacing="0" class="editsec">
+
+          <table>
             <tr>
-              <td align="left" colspan="2">
+              <td class="titleCell" colspan="2">
                 <span class="aptview_title">
-                  <var:string label:value="Extended" />
+                  <var:string label:value="Home" />
                 </span>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="EMail" />:
-                </span>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="Street Address: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="homeStreetAddress"
+                    id="homeStreetAddress"
+                    var:value="snapshot.homeStreetAddress" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="mail" id="email"
-                         var:value="snapshot.mail" size="60" />
-                </span>
+            </tr>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="City: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="homeCity"
+                    id="homeCity"
+                    var:value="snapshot.homeCity" />
+                </label>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="Unit" />:
-                </span>
+            <tr>
+              <td class="firstColumn">
+                <label><var:string label:value="State/Province: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="homeState"
+                    id="homeState"
+                    var:value="snapshot.homeState" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="departmentNumber"
-                         id="departmentNumber"
-                         var:value="snapshot.departmentNumber" size="60" />
-                </span>
+              <td class="secondColumn">
+                <label><var:string
+                    label:value="Zip or Postal Code: "
+                    const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="homePostalCode"
+                    id="homePostalCode"
+                    var:value="snapshot.homePostalCode" />
+                </label>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="Location" />:
-                </span>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="Country: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="homeCountry"
+                    id="homeCountry"
+                    var:value="snapshot.homeCountry" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="l" id="l" var:value="snapshot.l"
-                         size="60" />
-                </span>
+            </tr>
+            <tr>
+              <td colspan="2">
+                <label>
+                  <var:string label:value="Web: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="homeURL"
+                    var:value="snapshot.homeURL" />
+                </label>
               </td>
             </tr>
-            <tr valign="top">
-              <td align="right" width="15%">
-                <span class="aptview_text">
-                  <var:string label:value="URL" />:
-                </span>
+          </table>
+        </div>
+
+        <div id="otherInfos" class="tab">
+          <table>
+            <tr>
+              <td class="firstColumn">
+                <label><var:string label:value="Birthday: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="birthday" id="birthday"
+                    var:value="snapshot.bday" />
+                </label>
               </td>
-              <td align="left" bgcolor="#FFFFF0">
-                <span class="aptview_text">
-                  <input type="text" name="labeledURI" 
-                        var:value="snapshot.labeledURI" size="60" />
-                </span>
+              <td class="secondColumn">
+                <label><var:string label:value="Timezone: " const:escapeHTML="NO" />
+                  <input type="text" class="textField" name="tz" id="tz"
+                    var:value="snapshot.tz" />
+                </label>
+              </td>
+            </tr>
+            <tr>
+              <td colspan="2">
+                <label><var:string label:value="Note: " const:escapeHTML="NO" />
+                  <textarea var:value="snapshot.note" name="note" id="note"></textarea>
+                </label>
               </td>
             </tr>
           </table>
-  </var:if>
-        </td>
-      </tr>
-  <var:if condition="clientObject.isVCardRecord" const:negate="1">
-      <tr>
-        <td>
-            <input type="submit" label:value="Save" name="save:method" />
-            <span class="button_auto_env"
-            ><a href="../view"
-                var:queryDictionary="queryParameters"
-                class="button_auto"
-             ><var:string label:value="Cancel" /></a></span>
-            <var:if condition="isUIxDebugEnabled">
-              <input type="submit" value="Test" name="test:method" />
-            </var:if>
-        </td>
-      </tr>
-  </var:if>
-    </table>
-    
-    <input type="hidden" name="content" var:value="contentString" />
-  </form>
+        </div>
+      </div>
+      <div id="buttons">
+        <input
+          type="submit"
+          class="button"
+          label:value="Save"
+          name="save:method" />
+        <input
+          type="submit"
+          class="button"
+          label:value="Cancel"
+          name="cancel"
+          onclick="window.close(); return false;" />
+      </div>
+    </form>
 
-  <var:if condition="isUIxDebugEnabled">
-    <small>
-      <hr />
-      clientObject: <var:string value="clientObject" />
-    </small>
-  </var:if>
-</var:component>
+    <script type="text/javascript">
+      initEditorForm();
+    </script>
+  </var:component>
diff --git a/UI/Templates/ContactsUI/UIxContactFoldersView.wox b/UI/Templates/ContactsUI/UIxContactFoldersView.wox
new file mode 100644 (file)
index 0000000..c42113e
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version='1.0' standalone='yes'?>
+  <container />
diff --git a/UI/Templates/ContactsUI/UIxContactSelector.wox b/UI/Templates/ContactsUI/UIxContactSelector.wox
new file mode 100644 (file)
index 0000000..dcc7590
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version='1.0' standalone='yes'?>
+  <container 
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    xmlns:rsrc="OGo:url"
+    >
+    <div class="contactSelector" var:id="selectorId">
+      <span class="contactSelectorButtons">
+        <a href="#" class="button"
+          onclick="return onContactAdd(this);"
+          ><img rsrc:src="add-contact.gif"
+            label:title="Add..."
+            /></a>
+        <a href="#" class="button"
+          onclick="return onContactRemove(this);"
+          ><img rsrc:src="remove-contact.gif"
+            label:title="Remove"
+            /></a>
+      </span>
+      <input type="hidden"
+        var:id="selectorIdList"
+        var:name="selectorId"
+        var:value="initialContactsAsString" />
+      <ul var:id="selectorIdDisplay"
+        multiselect="yes"
+        class="contactList">
+        <var:foreach list="contacts" item="currentContact"
+          ><li var:uid="currentContactId"
+            onmousedown="return false;"
+            onclick="onRowClick(event);"
+            >
+            <var:if condition="hasColors"
+              ><span class="colorBox" var:style="currentContactStyle"><!-- spacer --></span>
+            </var:if><var:if condition="hasCheckBoxes">
+              <input type="checkbox" class="checkBox"
+                var:checked="isCheckBoxChecked"
+                var:onchange="checkBoxOnChange" />
+            </var:if>
+            <var:if condition="hasCheckBoxes"
+              const:negate="YES">
+              <img rsrc:src="abcard.gif" />
+            </var:if>
+            <var:string value="currentContactName" /></li>
+        </var:foreach>
+      </ul><br />
+    </div>
+  </container>
index d00fac1ef7c1c196e3f6ef57554b1c78b91e86a3..934ca7b5a4248b257731132d64aa71fd99c77c48 100644 (file)
 <?xml version='1.0' standalone='yes'?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:uix="OGo:uix"
-               xmlns:label="OGo:label"
-               className="UIxPageFrame"
-               title="name"
->
-  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5"
-         width="100%"
-  >
-    <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle">
-              <!-- localize me -->
-              <span class="window_label"
-              ><var:string label:value="Contact viewer" /></span>
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose"/>
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    xmlns:uix="OGo:uix"
+    className="UIxPageFrame"
+    title="name"
+    const:popup="YES"
+    >
+    
+    <h3 class="contactCardTitle"><var:string value="contactCardTitle" /></h3>
 
-  <tr>
-    <td>
-        <table border="0" cellpadding="2" width="100%" cellspacing="0">
-          <tr bgcolor="#e8e8e0">
-            <td align="left">
-              <span class="aptview_title">
-               <var:if condition="clientObject.isVCardRecord" const:negate="1">
-                 <var:string value="clientObject.cn"/>
-               </var:if>
-               <var:if condition="clientObject.isVCardRecord">
-                 <var:string label:value="vCard" />:
-                 <var:string value="clientObject.vCard.fn"/>
-               </var:if>
-              </span>
-            </td>
-            <td align="right" >
-              <table border='0' cellpadding='0' cellspacing='1'>
-                <tr>
-                  <td class="button_auto_env" nowrap="true"
-                      valign='middle' align='center'>
-                    <a class="button_auto"
-                       href="edit"
-                       var:queryDictionary="queryParameters"
-                    ><var:string label:value="edit" /></a>
-                  </td>
-                  <td class="button_auto_env" nowrap="true"
-                      valign='middle' align='center'>
-                    <a class="button_auto"
-                       href="delete"
-                       var:queryDictionary="queryParameters"
-                    ><var:string label:value="delete" /></a>
-                  </td>
-                </tr>
-              </table>
-            </td>
-          </tr>
-        </table>
-    </td>
-  </tr>
-  <tr>
-    <td valign="top" width="100%">
-      <table width="100%" border="0" cellpadding="4" cellspacing="0">
-       <var:if condition="clientObject.isVCardRecord" const:negate="1">
-        <!-- general contact info -->
-        <tr valign="top">
-          <td align="right" width="15%" bgcolor="#E8E8E0">
-              <span class="aptview_text"
-              ><var:string label:value="Name" />:</span>
-          </td>
-          <td align="left" bgcolor="#FFFFF0">
-              <span class="aptview_text">
-                <var:string value="clientObject.cn" />
-              </span>
-          </td>
-        </tr>
-        <tr valign="top">
-          <td align="right" width="15%" bgcolor="#E8E8E0">
-            <span class="aptview_text"
-            ><var:string label:value="Unit" />:</span>
-          </td>
-          <td align="left" bgcolor="#FFFFF0">
-            <span class="aptview_text">
-              <var:string value="clientObject.departmentNumber"/></span>
-          </td>
-        </tr>
-        <tr valign="top">
-          <td align="right" width="15%" bgcolor="#E8E8E0">
-            <span class="aptview_text"
-            ><var:string label:value="Location" />:</span>
-          </td>
-          <td align="left" bgcolor="#FFFFF0">
-            <span class="aptview_text">
-              <var:string value="clientObject.l" />
-            </span>
-          </td>
-        </tr>
-       </var:if>
-      </table>
-      </td>
-    </tr>
-    <tr>
-      <td valign="top" width="100%">
-        <uix:tabview var:selection="tabSelection"
-                     const:tabStyle="tab"
-                     const:selectedTabStyle="tab_selected"
-                     const:bodyStyle="tabview_body"
-        >
-          <!-- ******************** Tab for PLists ******************* -->
-       
-          <var:if condition="clientObject.isVCardRecord" const:negate="1">
-           <uix:tab const:key="attributes"
-                   const:label="attributes"
-                   var:href="attributesTabLink"
-           >
-            <table width="100%" border="0" cellpadding="4" cellspacing="0">
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="EMail" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.mail"/></span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="OfficePhone" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.telephoneNumber"/></span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="HomePhone" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.homeTelephoneNumber"/></span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="MobilePhone" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.mobile"/></span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Fax" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.facsimileTelephoneNumber"
-                    /></span>
-                </td>
-              </tr>
-              <!--
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Organisation" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.o"/></span>
-                </td>
-              </tr>
-              -->
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Postal" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.postalAddress"
-                                const:insertBR="YES"
-                    />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Home" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.homePostalAddress"
-                                const:insertBR="YES"
-                    />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="URL" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.labeledURI"/>
-                  </span>
-                </td>
-              </tr>
-            </table>
-           </uix:tab>
-          </var:if>
+    <div id="leftContactColumn" class="contactColumn">
+      <div id="primaryInfos">
+        <h4><var:string label:value="Contact" /></h4>
+        <var:string value="displayName" escapeHTML="NO" />
+        <var:string value="nickName" escapeHTML="NO" />
+        <var:string value="preferredEmail" escapeHTML="NO" />
+        <var:string value="preferredTel" escapeHTML="NO" />
+        <var:string value="preferredAddress" escapeHTML="NO" />
+      </div>
 
-          <!-- ******************** Tab for vCards ******************* -->
+      <var:if condition="hasHomeInfos">
+        <div id="homeInfos">
+          <h4><var:string label:value="Home" /></h4>
+          <var:string value="homePobox" escapeHTML="NO" />
+          <var:string value="homeExtendedAddress" escapeHTML="NO" />
+          <var:string value="homeStreetAddress" escapeHTML="NO" />
+          <var:string value="homeCityAndProv" escapeHTML="NO" />
+          <var:string value="homePostalCodeAndCountry" escapeHTML="NO" />
+          <var:string value="homeUrl" escapeHTML="NO" />
+        </div>
+      </var:if>
 
-          <var:if condition="clientObject.isVCardRecord">
-           <uix:tab const:key="attributes"
-                   const:label="attributes"
-                   var:href="attributesTabLink"
-           >
-            <table width="100%" border="0" cellpadding="4" cellspacing="0">
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="EMail" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string
-                       value="clientObject.vCard.preferredEMail.stringValue"/>
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Phone" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string
-                      value="clientObject.vCard.preferredTel.stringValue"/>
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Address" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string
-                      value="clientObject.vCard.preferredAdr.street"/><br />
-                    <var:string
-                      value="clientObject.vCard.preferredAdr.locality"/><br />
-                    <var:string
-                      value="clientObject.vCard.preferredAdr.country"/><br />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Role" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.vCard.role"/></span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Title" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.vCard.title"/></span>
-                </td>
-              </tr>
+      <var:if condition="hasOtherInfos">
+        <div id="otherInfos">
+          <h4><var:string label:value="Other Infos" /></h4>
+          <var:string value="bday" escapeHTML="NO" />
+          <var:string value="tz" escapeHTML="NO" />
+          <var:string value="note" escapeHTML="NO" />
+        </div>
+      </var:if>
+    </div>
 
-              <tr valign="top">
-                <td align="right" width="15%" bgcolor="#E8E8E0">
-                  <span class="aptview_text"
-                  ><var:string label:value="Note" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:string value="clientObject.vCard.note"/></span>
-                </td>
-              </tr>
-            </table>
-           </uix:tab>
-          </var:if>
+    <div id="rightContactColumn" class="contactColumn">
+      <var:if condition="hasTelephones">
+        <div id="phoneInfos">
+          <h4><var:string label:value="Telephone" /></h4>
+          <var:string value="workPhone" escapeHTML="NO" />
+          <var:string value="homePhone" escapeHTML="NO" />
+          <var:string value="fax" escapeHTML="NO" />
+          <var:string value="mobile" escapeHTML="NO" />
+          <var:string value="pager" escapeHTML="NO" />
+        </div>
+      </var:if>
 
-          <!-- ******************** Debugging Tab ******************** -->
-
-          <var:if condition="isUIxDebugEnabled">
-            <uix:tab const:key="debug"
-                     const:label="DEBUG"
-                     var:href="debugTabLink">
-             <small>
-              SOGo Server - <var:string value="name"/>
-              <br />
-              Client: <var:string value="clientObject"/>
-              <hr />
-              Raw :<br />
-              <pre><var:string value="clientObject.contentAsString"/></pre>
-             </small>
-            </uix:tab>
-          </var:if>
-        </uix:tabview>
-      </td>
-    </tr>
-  </table>
-  <var:if condition="isUIxDebugEnabled">
-    <small>
-      <hr />
-      clientObject: <var:string value="clientObject" />
-    </small>
-  </var:if>
-</var:component>
\ No newline at end of file
+      <var:if condition="hasWorkInfos">
+        <div id="workInfos">
+          <h4><var:string label:value="Work" /></h4>
+          <var:string value="workTitle" escapeHTML="NO" />
+          <var:string value="workService" escapeHTML="NO" />
+          <var:string value="workCompany" escapeHTML="NO" />
+          <var:string value="workPobox" escapeHTML="NO" />
+          <var:string value="workExtendedAddress" escapeHTML="NO" />
+          <var:string value="workStreetAddress" escapeHTML="NO" />
+          <var:string value="workCityAndProv" escapeHTML="NO" />
+          <var:string value="workPostalCodeAndCountry" escapeHTML="NO" />
+          <var:string value="workUrl" escapeHTML="NO" />
+        </div>
+      </var:if>
+    </div>
+  </var:component>
diff --git a/UI/Templates/ContactsUI/UIxContactsAclsSelection.wox b/UI/Templates/ContactsUI/UIxContactsAclsSelection.wox
new file mode 100644 (file)
index 0000000..7a106ac
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version='1.0' standalone='yes'?>
+  <div
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    xmlns:rsrc="OGo:url"
+    class="calendar"
+    >
+    <input type="submit"
+      class="button"
+      label:value="Add Assistant"
+      name="validate"
+      onclick="return onConfirmContactSelection('assistant');" /><br />
+    <input type="submit"
+      class="button"
+      label:value="Add Delegate"
+      name="validate"
+      onclick="return onConfirmContactSelection('delegate');" />
+  </div>
diff --git a/UI/Templates/ContactsUI/UIxContactsAddressBooksSelection.wox b/UI/Templates/ContactsUI/UIxContactsAddressBooksSelection.wox
new file mode 100644 (file)
index 0000000..daf472d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version='1.0' standalone='yes'?>
+  <div
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    xmlns:rsrc="OGo:url"
+    class="calendar"
+    >
+    <input type="submit"
+      class="button"
+      label:value="Add Address Book..."
+      name="validate"
+      onclick="return onConfirmAddressBookSelection();" />
+  </div>
diff --git a/UI/Templates/ContactsUI/UIxContactsCalendarsSelection.wox b/UI/Templates/ContactsUI/UIxContactsCalendarsSelection.wox
new file mode 100644 (file)
index 0000000..06888b3
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version='1.0' standalone='yes'?>
+  <div
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    xmlns:rsrc="OGo:url"
+    class="calendar"
+    >
+    <input type="submit"
+      class="button"
+      label:value="Add Calendar..."
+      name="validate"
+      onclick="return onConfirmContactSelection(null);" />
+  </div>
diff --git a/UI/Templates/ContactsUI/UIxContactsFilterPanel.wox b/UI/Templates/ContactsUI/UIxContactsFilterPanel.wox
new file mode 100644 (file)
index 0000000..ae49850
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version='1.0' standalone='yes'?>
+  <container 
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:label="OGo:label"
+    >
+    <div class="menu" id="searchMenu">
+      <ul id="searchOptions">
+        <li id="name_or_address"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="Name or Address"/></li>
+      </ul>
+    </div>
+
+    <div id="filterPanel">
+      <span class="searchBox" style="float: right">
+        <input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" />
+        <input id="searchValue" class="textField" autocomplete="off" name="search" type="text" var:value="searchText" onmousedown="onSearchMouseDown(event, this);" onclick="popupSearchMenu(event, 'searchMenu');" onblur="onSearchBlur(this);" onfocus="onSearchFocus(this);" onkeydown="onSearchKeyDown(this);" />
+      </span>
+    </div>
+  </container>
index fc62ebd0b76a85800323e735cf7d2a71d13c15e2..ed78ceba238f5e1dab5ee0971da7e677c1460613 100644 (file)
 <?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:label="OGo:label"
-  xmlns:rsrc="OGo:url"
-  className="UIxPageFrame"
-  title="name"
->
-  <style>
-    table.contacttableview {
-      text-decoration:  none;
-      font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-      font-size:        9pt;
-      color:            #000000;
-    }
-    table.contacttableview th {
-      text-align: left;
-    }
-    input.searchfield {
-      font-size:        8pt;
-    }
-  </style>
-
-  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5"
-         width="100%">
-    <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle">
-              <!-- localize me -->
-              <span class="window_label"
-              ><var:string label:value="Addressbook"/></span>
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose"/>
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td id="skywinbodycell" class="wincontent">
-       <form name="searchform" var:href="view" var:_sort="sortKey"
-             method="GET">
-        <table border="0" width="100%" cellpadding="0" cellspacing="0">
-          <tr>
-            <td colspan="2">
-                <table border="0" cellpadding="4" width="100%" cellspacing="0">
-                  <tr bgcolor="#e8e8e0">
-                    <td align="left">
-                      <input type="text" name="search" class="searchfield" 
-                             var:value="searchText" />
-                    </td>
-                    <td align="right">
-                      <table border="0" cellpadding="0" cellspacing="1">
-                        <tr>
-                          <td class="button_auto_env"
-                              nowrap="true" valign="middle" align="center">
-                            <a class="button_auto"
-                               href="new"
-                               var:queryDictionary="queryParameters"
-                            ><var:string label:value="new"/></a>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                  </tr>
-                </table>
-
-                <!-- the content -->
-                <table border="0" width="100%" class="contacttableview">
-                  <tr>
-                    <!-- localize -->
-                    <th>
-                      <var:if condition="sortKey" const:value="sn"
-                              const:negate="YES">
-                        <a href="view"
-                           _sort="sn"
-                           var:_search="searchText"
-                        ><var:string label:value="Lastname" /></a>
-                      </var:if>
-                      <var:if condition="sortKey" const:value="sn">
-                        <i><var:string label:value="Lastname" /></i>
-                      </var:if>
-                    </th>
-                    <th>
-                      <var:if condition="sortKey" const:value="givenname"
-                              const:negate="YES">
-                        <a href="view"
-                           _sort="givenname"
-                           var:_search="searchText"
-                        ><var:string label:value="Firstname" /></a>
-                      </var:if>
-                      <var:if condition="sortKey" const:value="givenname">
-                        <i><var:string label:value="Firstname" /></i>
-                      </var:if>
-                    </th>
-                    <th>
-                      <var:if condition="sortKey" const:value="mail"
-                              const:negate="YES">
-                        <a href="view"
-                           _sort="mail"
-                           var:_search="searchText"
-                        ><var:string label:value="EMail" /></a>
-                      </var:if>
-                      <var:if condition="sortKey" const:value="mail">
-                        <i><var:string label:value="EMail" /></i>
-                      </var:if>
-                    </th>
-                    <th>
-                           <var:string label:value="Phone" />
-                    </th>
-                    <th>
-                           <var:string label:value="Location" />
-                    </th>
-                  </tr>
-                  <var:foreach list="contactInfos" item="contact">
-                    <tr>
-                      <td>
-                        <a var:href="contact.c_name"
-                           ><var:string value="contact.sn" /></a>
-                      </td>
-                      <td><var:string value="contact.givenname"       /></td>
-                      <td><var:string value="contact.mail"            /></td>
-                      <td><var:string value="contact.telephonenumber" /></td>
-                      <td><var:string value="contact.l"               /></td>
-                    </tr>
-                  </var:foreach>
-                </table>
-            </td>
-          </tr>
-
-          <tr bgcolor="#F5F5E9">
-            <td align="left" width="10">
-              <var:entity const:name="nbsp"/>
-            </td>
-            <td align="right">
-              <img border="0" alt=""
-                   rsrc:src="CommonUI.SOGo/corner_right.gif"
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    xmlns:rsrc="OGo:url"
+    className="UIxContactsListViewContainer"
+    selectorComponentClass="selectorComponentClass"
+    title="name">
+    <table id="contactsList" multiselect="yes">
+      <tbody>
+        <tr class="tableview">
+          <!-- localize -->
+          <td class="tbtv_headercell">
+            <var:component className="UIxSortableTableHeader"
+              label:label="Lastname"
+              const:sortKey="cn"
+              const:href="view"
+              var:queryDictionary="context.request.formValues"
               />
-            </td>
-          </tr>
-          <tr>
-            <td colspan="2" bgcolor="#F5F5E9">
-              <table border="0" width="100%" cellpadding="10" cellspacing="0">
-                <tr/>
-              </table>
-            </td>
-          </tr>
-        </table>
-       </form>
-      </td>
-    </tr>
-  </table>
-  
-<!-- todo: need onload for this to work ...
-  <script language="JavaScript">
-    document.searchform.search.select();
-    document.searchform.search.focus();
-  </script>
--->
+          </td>
+          <td class="tbtv_headercell">
+            <var:component className="UIxSortableTableHeader"
+              label:label="EMail"
+              const:sortKey="mail"
+              const:href="view"
+              var:queryDictionary="context.request.formValues"
+              />
+          </td>
+          <td class="tbtv_headercell">
+            <var:string label:value="Phone" />
+          </td>
+          <td class="tbtv_headercell">
+            <var:string label:value="Location" />
+          </td>
+        </tr>
 
-  <var:if condition="isUIxDebugEnabled">
-    <hr />
-    <small>clientObject: <var:string value="clientObject" /></small>
-  </var:if>
-</var:component>
\ No newline at end of file
+        <var:foreach list="contactInfos" item="currentContact">
+          <tr class="tableview"
+            var:id="currentContact.c_name"
+            var:contactname="displayName"
+            var:contactid="currentContact.c_uid"
+            onclick="return onContactRowClick(event, this);"
+            ondblclick="return onContactRowDblClick(event, this);"
+            oncontextmenu="return onContactContextMenu(event, this);">
+            <td onmousedown="return false;"><img rsrc:src="abcard.gif" /><var:string value="displayName" const:escapeHTML="YES" /></td>
+            <td onmousedown="return false;"><var:string value="currentContact.mail"            /></td>
+            <td onmousedown="return false;"><var:string value="currentContact.telephonenumber" /></td>
+            <td onmousedown="return false;"><var:string value="currentContact.l"               /></td>
+          </tr>
+        </var:foreach>
+      </tbody>
+    </table>
+  </var:component>
diff --git a/UI/Templates/ContactsUI/UIxContactsListViewContainer.wox b/UI/Templates/ContactsUI/UIxContactsListViewContainer.wox
new file mode 100644 (file)
index 0000000..f0a71c1
--- /dev/null
@@ -0,0 +1,115 @@
+<?xml version='1.0' standalone='yes'?>
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    xmlns:rsrc="OGo:url"
+    className="UIxPageFrame"
+    title="name"
+    var:popup="isPopup">
+    <var:if condition="hideFrame" const:negate="YES">
+      <div class="menu" id="contactFoldersMenu">
+        <ul>
+          <li><var:string label:value="Modify" /></li>
+          <li id="accessRightsMenuEntry"><var:string label:value="Access Rights..." /></li>
+          <li class="separator"></li>
+          <li><var:string label:value="New Card" /></li>
+          <li><var:string label:value="New List" /></li>
+          <li class="separator"></li>
+          <li><var:string label:value="Delete" /></li>
+        </ul>
+      </div>
+
+      <div class="menu" id="contactMenu">
+        <ul>
+          <li id="modifyContactMenuEntry" onmouseup="return onMenuEditContact(event, this);"><var:string label:value="Modify" /></li>
+          <li class="separator"></li>
+          <li id="writeToContactMenuEntry" onmouseup="return onMenuWriteToContact(event, this);"><var:string label:value="Write" /></li>
+          <li id="imContactMenuEntry"><var:string label:value="Instant Message" /></li>
+          <li class="separator"></li>
+          <li id="deleteContactMenuEntry" onmouseup="return onMenuDeleteContact(event, this);"><var:string label:value="Delete" /></li>
+        </ul>
+      </div>
+
+      <form name="searchform" var:href="view" var:_sort="sortKey"
+        onsubmit="return onSearchFormSubmit();" method="GET">
+<!--   var:if condition="isPopup" const:negate="YES"> -->
+          <var:if condition="hideFolderTree" const:negate="YES">
+            <div class="contactFoldersList" id="contactFoldersList">
+              <div class="titlediv"
+              ><var:string label:value="Address Books"
+                /></div>
+            <var:if var:condition="isPopup" const:negate="YES"
+              ><div class="toolbar">
+                <a href="#" class="toolbarButton" onclick="return onAddressBookAdd(this);"
+                  ><span class="toolbarButton"
+                    ><img rsrc:src="add-addressbook.png" label:title="Add an Addressbook..."
+                      /></span></a
+                  ><a href="#" class="toolbarButton" onclick="return onAddressBookRemove(this);"
+                  ><span class="toolbarButton"
+                    ><img rsrc:src="remove-addressbook.png" label:title="Remove the selected Addressbook"
+                      /></span></a
+                  ></div></var:if>
+
+            <ul id="contactFolders"
+              var:additional-addressbooks="additionalAddressBooks">
+              <var:foreach list="contactFolders" item="currentFolder"
+                ><var:if condition="isFolderCurrent"
+                  ><li var:id="currentContactFolderId" class="_selected"
+                    ><var:string value="currentContactFolderName" /></li
+                    ></var:if
+                  ><var:if condition="isFolderCurrent" const:negate="YES"
+                  ><li var:id="currentContactFolderId"
+                    ><var:string value="currentContactFolderName" /></li
+                    ></var:if>
+              </var:foreach
+                ><var:foreach list="additionalFolders"
+                item="currentAdditionalFolder"
+                ><li var:id="currentAdditionalFolder"
+                  var:external-addressbook="currentAdditionalFolder"
+                  ><var:string value="currentAdditionalFolder" /></li
+                  ></var:foreach>
+            </ul>
+
+            <var:if condition="hasContactSelectionButtons">
+              <div class="contactSelection">
+                <var:component value="selectorComponent" />
+              </div>
+            </var:if>
+          </div>
+
+          <div class="dragHandle" id="dragHandle"><!-- space --></div>
+        </var:if>
+
+        <div id="rightPanel">
+          <var:component className="UIxContactsFilterPanel" qualifier="qualifier" />
+
+          <div id="contactsListContent">
+            <var:component-content />
+          </div>
+
+          <div class="dragHandle" id="rightDragHandle"><!-- space --></div>
+
+          <div id="contactView" onmousedown="return false;"
+            ></div>
+        </div>
+        <!--          /var:if> -->
+
+        <!--   var:if condition="isPopup">
+        var:component-content />
+        /var:if> -->
+      </form>
+
+      <var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
+    </var:if>
+
+    <var:if condition="hideFrame">
+      <var:component-content />
+    </var:if>
+
+    <script type="text/javascript">
+      currentContactFolder = '<var:string value="contactFolderId" />';
+    </script>
+  </var:component>
diff --git a/UI/Templates/ContactsUI/UIxContactsMailerSelection.wox b/UI/Templates/ContactsUI/UIxContactsMailerSelection.wox
new file mode 100644 (file)
index 0000000..a6e1c1b
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version='1.0' standalone='yes'?>
+  <span
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    xmlns:rsrc="OGo:url"
+    >
+    <span id="selectionLabel"><var:string label:value="Add as..." /></span><br />
+    <input type="submit"
+      class="button"
+      label:value="Recipient"
+      name="to"
+      onclick="return onConfirmContactSelection('to');" /><br />
+    <input type="submit"
+      class="button"
+      label:value="Carbon Copy"
+      name="cc"
+      onclick="return onConfirmContactSelection('cc');" /><br />
+    <input type="submit"
+      class="button"
+      label:value="Blind Carbon Copy"
+      name="bcc"
+      onclick="return onConfirmContactSelection('bcc');" />
+  </span>
index eacb1caca0a3260de476548465822da5363cce48..8b9813f662ae08eef1bbc8d6362fe9500dc98094 100644 (file)
@@ -10,3 +10,5 @@ install :: all
 clean ::
 
 distclean :: clean
+
+uninstall ::
index 7e8d5f4cce791019d991012c296a33cc600945ad..b90c69b17adefb4fc8a9abf432dfc9c008f213f9 100644 (file)
@@ -1,9 +1,9 @@
 <?xml version="1.0" standalone="yes"?>
-<pre
+<div
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:var="http://www.skyrix.com/od/binding"
   xmlns:const="http://www.skyrix.com/od/constant"
   xmlns:rsrc="OGo:url"
   xmlns:label="OGo:label"
   class="mailer_plaincontent"
-><var:string value="flatContentAsString" /></pre>
+><var:string value="flatContentAsString" const:escapeHTML="NO" /></div>
index f3f3943c716ebef87deb2b1c387ec58518a91ab0..26cef689edbfc4f9daa254e42ca0603e7115ac29 100644 (file)
@@ -1,71 +1,43 @@
 <?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:rsrc="OGo:url"
-  xmlns:label="OGo:label"
-  className="UIxMailMainFrame"
-  title="panelTitle"
->
-  <div class="titlediv">
-    <var:if condition="clientObject.isSharedAccount">
-      <var:string label:value="Share: " />
-    </var:if>
-    <var:if condition="clientObject.isSharedAccount" const:negate="1">
-      <var:string label:value="Account: " />
-    </var:if>
-    <var:string value="objectTitle"/>
-  </div>
-
-  <div class="embedwhite_out">
-    <div class="embedwhite_in">
-     <div style="padding: 8px;">
-      <div style="font-weight: bold; font-size: 16px;">
-        SOGo Mail - 
-
-        <var:if condition="clientObject.isSharedAccount">
-          <var:string label:value="Shared Account: " />
-        </var:if>
-
-        <var:string value="objectTitle"/>
-      </div>
-      <br />
+  <div style="padding: 1em;"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <h2>
+      SOGo Mail - <var:string value="objectTitle" />
+      
       <var:if condition="clientObject.isSharedAccount">
-        <div>
-          <var:string label:value="Share: " />
-          <var:string value="clientObject.sharedAccountName" />
-        </div>
+        <var:string label:value="Shared Account: " />
       </var:if>
-      <br />
-
-      <div class="whitesec_title">Email</div><br />
-      <li><a href="INBOX/"><var:string label:value="Read messages" /></a></li>
-      <li><a href="#" onclick="clickedCompose(this);"
-             ><var:string label:value="Write a new message" /></a></li>
-      <br />
-      <br />
-
-<!--
-      <div class="whitesec_title">Accounts</div><br />
-      <li><a href="">View settings for this account</a></li>
-      <li><a href="">Create a new account</a> [TBD: not in Agenor]</li>
-      <br />
-      <br />
-
-      <div class="whitesec_title">Advanced Features</div><br />
-      <li><a href="">Search messages</a></li>
-      <li><a href="">Manage message filters</a></li>
-      <li><a href="">Manage folder subscriptions</a></li>
-      <li><a href="">Offline settings</a> [TBD: not in Agenor]</li>
-      <br />
-      <br />
+      
+    </h2>
+    <var:if condition="clientObject.isSharedAccount">
+      <div>
+        <var:string label:value="Share: " />
+        <var:string value="clientObject.sharedAccountName" />
+      </div>
+    </var:if>
+    
+    <h3>Email</h3>
+    <p>
+      <a href="INBOX/" onclick="initMailboxSelection(currentMailbox + '/INBOX'); openMailbox(currentMailbox + '/INBOX'); return false;"><img rsrc:src="read-messages.png" /><var:string label:value="Read messages" /></a><br />
+      <a href="#" onclick="clickedCompose(this);"><img rsrc:src="write-message.png" /><var:string label:value="Write a new message" /></a><br />
+    </p>
 
-      <div class="whitesec_title">Screenshot</div><br />
-      <a rsrc:href="tbird_073_accountview.png">screenshot</a>
--->
-     </div>
-    </div>
+    <h3>Accounts</h3>
+    <p>
+      <a href=""><img rsrc:src="account-settings.png" />View settings for this account</a><br />
+      <a href=""><img rsrc:src="create-account.png" />Create a new account</a> [TBD: not in Agenor]<br />
+    </p>
+    
+    <h3>Advanced Features</h3>
+    <p>
+      <a href=""><img rsrc:src="search-messages.png" />Search messages</a><br />
+      <a href=""><img rsrc:src="manage-filters.png" />Manage message filters</a><br />
+      <a href=""><img rsrc:src="manage-imap.png" />Manage folder subscriptions</a><br />
+      <a href=""><img rsrc:src="offline-settings.png" />Offline settings</a> [TBD: not in Agenor]<br />
+    </p>
   </div>
-</var:component>
diff --git a/UI/Templates/MailerUI/UIxMailAccountsView.wox b/UI/Templates/MailerUI/UIxMailAccountsView.wox
deleted file mode 100644 (file)
index 88eeaa3..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:label="OGo:label"
-  xmlns:rsrc="OGo:url"
-  className="UIxMailMainFrame"
-  title="panelTitle"
->
-  <div class="titlediv">
-    <var:string value="clientObject.davDisplayName" />
-  </div>
-  
-  <div class="embedwhite_out">
-    <div class="embedwhite_in" style="height: 300px">
-     <div style="padding: 8px;">
-      <var:string label:value="Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" />
-     </div>
-<!--
-      <h3>SOGo Mail - Available Accounts</h3>
-
-      <a rsrc:href="tbird_073_accountview.png">screenshot</a>
--->
-    </div>
-  </div>
-</var:component>
index 2a3d3a335c54a03b032ee440007d40766c272e15..97c87337f0a87aed124a8c9eaf72d1a3d7f141e2 100644 (file)
@@ -1,88 +1,46 @@
 <?xml version='1.0' standalone='yes'?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:uix="OGo:uix"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               className="UIxMailPanelFrame"
-               title="panelTitle"
->
-  <script rsrc:src="layout2or3_xlib.js" > <!-- space required --></script>
-  <div id="compose_panel">
-    <var:if condition="showInternetMarker">
-      <div id="compose_internetmarker">
-        <var:string
-            label:value="This mail is being sent from an unsecure network!" />
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="panelTitle"
+    const:popup="YES"
+    >
+    <div id="headerArea">
+      <div id="attachmentsArea">
+        <var:string label:value="Attachments:" />
+        <div id="compose_attachments_list"
+          onclick="clickedEditorAttach(this);"
+          ><var:foreach list="attachmentNames" item="attachmentName">
+            <var:string value="attachmentName" /><br />
+          </var:foreach>
+        </div>
       </div>
-    </var:if>
-    <table border="0" width="100%" id="compose_table">
-      <tr>
-        <td id="compose_leftside" var:style="initialLeftsideStyle">
-          <div id="compose_toselection">
-            <var:component className="UIxMailToSelection"
-                           to="to"
-                           cc="cc"
-                           bcc="bcc"
-            />
-          </div>
-          <!-- moved below to selection to make it look better -->
-          <div id="compose_fromline">
-            <table border="0" width="100%">
-              <tr>
-                <td class="compose_label" width="20%">
-                  <var:string label:value="From" />:
-                </td>
-                <td width="80%">
-                  <var:popup const:name="from" list="fromEMails" item="item"
-                             selection="from"
-                             const:style="width: 100%; font-size: 8pt;"
-                    />
-                </td>
-              </tr>
-            </table>
-          </div>
-    
-          <div id="compose_subject">
-            <table border="0" width="100%">
-              <tr>
-                <td class="compose_label" width="20%">
-                  <var:string label:value="Subject" />:
-                </td>
-                <td width="80%"><input name="subject"
-                                       id="compose_subject_input"
-                                       type="text"
-                                       var:value="subject"
-                                /></td>
-              </tr>
-            </table>
-          </div>
-        </td>
-        <td id="compose_rightside" var:style="initialRightsideStyle">
-          <div id="compose_attachments">
-            <div id="compose_attachments_header">  
-              <span class="compose_label"
-              ><var:string label:value="Attachments" />:</span>
-               <!--<a href="#"
-                  onclick="hideInlineAttachmentList(this);"
-               ><var:string label:value="close" /></a>-->
-            </div>
-            <div id="compose_attachments_list"
-                 onclick="clickedEditorAttach(this);"
-            >
-              <var:foreach list="attachmentNames" item="attachmentName">
-                <var:string value="attachmentName" /><br />
-              </var:foreach>
-            </div>
-          </div>
-        </td>
-      </tr>
-    </table>
-    <!-- separator line -->
-    <div id="compose_text">
-      <textarea name="content" var:value="text" />
+      <span class="headerField"><var:string label:value="From" />:</span>
+      <var:popup const:name="from"
+        list="fromEMails"
+        item="item"
+        selection="from"
+        /><br />
+      <div>
+        <var:component className="UIxMailToSelection"
+          to="to" cc="cc" bcc="bcc" />
+      </div>
+      <div class="addressListElement" id="subjectRow"
+        ><span class="headerField"><var:string label:value="Subject"
+            />:</span
+          ><span class="headerInput"
+          ><input name="subject"
+            type="text"
+            class="textField"
+            var:value="subject"
+            /></span></div>
     </div>
-
+    <!-- separator line -->
+    <textarea name="content" var:value="text" />
     <!-- img rsrc:src="tbird_073_compose.png" alt="screenshot" / -->
-  </div>
-</var:component>
+  </var:component>
index dd0745281305ad93a7d59dc8db1789a1a29b9439..0e3805a46495044a85a7f56d128c6bca881576e1 100644 (file)
@@ -1,45 +1,53 @@
 <?xml version='1.0' standalone='yes'?>
-<container 
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
-  <var:if condition="hideFrame" const:negate="YES">
-<table
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:rsrc="OGo:url"
-  xmlns:label="OGo:label"
-  class="titletable"
-  cellspacing="0" cellpadding="0"
->
-  <tr>
-    <td class="titlecell">
-      <var:string label:value="View" />:
-    </td>
-    <td class="titlecell">
-      <var:popup list="filters" 
-              item="filter" string="filterLabel" value="filter"
-              selection="selectedFilter"
-              const:name="filterpopup" 
-              const:onchange="document.pageform.submit()" />
-    </td>
-    <td class="titlecell" style="padding-left: 4px;">
-      <var:string label:value="Subject or Sender contains" />:
-    </td>
-    <td class="titlecell" style="width: 80%; padding-right: 1px;">
-      <input name="search" type="text" var:value="searchText" 
-             style="width: 100%;" />
-      <!--
-             autocomplete="off"
-             onkeypress="ml_searchFieldKeyPressed(this)"
-             onfocus="ml_activateSearchField(this, 500)" 
-             onblur="ml_deactivateSearchField(this)" />
-        -->
-    </td>
-  </tr>
-</table>
-</var:if>
-</container>
+  <container 
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    >
+    <div class="menu" id="searchMenu">
+      <ul id="searchOptions">
+        <li id="subject"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="Subject"/></li>
+        <li id="sender"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="Sender"/></li>
+        <li id="subject_or_sender"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="Subject or Sender"/></li>
+        <li id="to_or_cc"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="To or Cc"/></li>
+        <li id="entire_message"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="Entire Message"/></li>
+        <li id="find_in_message"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="Find In Message"/></li>
+      </ul>
+    </div>
+    
+    <div id="filterPanel">
+      <var:if condition="hideFrame" const:negate="YES"
+        ><span class="searchBox" style="float: right">
+          <input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" />
+          <input id="searchValue"
+            class="textField"
+            autocomplete="off" name="search" type="text" var:value="searchText"
+            onmousedown="onSearchMouseDown(event, this);"
+            onclick="popupSearchMenu(event, 'searchMenu');"
+            onchange="onSearchChange();"
+            onblur="onSearchBlur(this);"
+            onfocus="onSearchFocus(this);"
+            onkeydown="onSearchKeyDown(this);" />
+        </span>
+
+        <var:string label:value="View:" />
+        <var:popup list="filters" 
+          item="filter" string="filterLabel" value="filter"
+          selection="selectedFilter"
+          const:name="filterpopup" 
+          const:onchange="document.pageform.submit()" />
+      </var:if>
+    </div>
+  </container>
index 3f01eabe672c947abed840e89aee95c8946f88e4..421c98cad9ef80c2fca434cfcadcb89aea9221b4 100644 (file)
@@ -1,14 +1,13 @@
 <?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:rsrc="OGo:url"
-  xmlns:label="OGo:label"
-  className="UIxMailMainFrame"
-  title="panelTitle"
-  const:hideFolderTree="1"
->
-  TODO: IMAP4 ACL editor
-</var:component>
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="panelTitle"
+    const:popup="YES">
+    TODO: IMAP4 ACL editor
+  </var:component>
diff --git a/UI/Templates/MailerUI/UIxMailFolderMenu.wox b/UI/Templates/MailerUI/UIxMailFolderMenu.wox
new file mode 100644 (file)
index 0000000..9a8721a
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version='1.0' standalone='yes'?>
+  <container xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    className="UIxMailFolderMenu"
+    title="panelTitle"
+    >
+
+    <div class="menu" var:id="menuId">
+      <ul id="">
+        <var:foreach list="levelledNodes" item="item"
+          ><var:if condition="item.hasChildren" const:negate="YES"
+            ><li onmouseup="processMailboxMenuAction(this);" var:mailboxname="item.name"><img var:src="iconForMenuItem" /><var:string value="item.title" /></li>
+          </var:if
+          ><var:if condition="item.hasChildren"
+            ><li
+              class="submenu"
+              var:submenu="item.folderMenuId"
+              onmouseover="dropDownSubmenu(event);"
+              onmousedown="return false;"><img var:src="iconForMenuItem" /><var:string value="item.title" /></li>
+          </var:if
+        ></var:foreach
+      ></ul>
+
+      <var:foreach list="levelledNodes" item="item"
+        ><var:if condition="item.hasChildren"
+          ><var:component
+            className="UIxMailFolderMenu"
+            var:menuId="item.folderMenuId"
+            var:parentMenu="item.serialAsString"
+            rootClassName="treeRootClassName" 
+            const:treeFolderAction="view" 
+            /></var:if
+      ></var:foreach>
+    </div>
+  </container>
index 5adc8b3b0db50031c42a9733805fc37c17adbe03..a66e0d832e71e5a1be8a11566a18a0bf436c9ccf 100644 (file)
 <?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:rsrc="OGo:url"
-  xmlns:label="OGo:label"
-  className="UIxMailMainFrame"
-  title="panelTitle"
-  hideFrame="hideFrame"
->
-  <script language="JavaScript" rsrc:src="UIxMailListView.js">
-    <!-- space required -->
-  </script>
-
-  <var:component className="UIxMailFilterPanel" qualifier="qualifier" 
-                 hideFrame="hideFrame" />
-
- <div id="cl_tableview_reloadroot">
-  <div class="embedwhite_out">
-    <div class="embedwhite_in">
-      <table border="0" width="100%" cellspacing="0" cellpadding="1">
-        <tr class="tableview">
-          <td class="tbtv_headercell" width="17">
-            <var:entity const:name="nbsp" />
-          </td>
-          <td class="tbtv_headercell" width="50%">
-            <var:component className="UIxMailSortableTableHeader"
-                           label:label="Subject"
-                           const:sortKey="subject"
-                           const:href="view"
-                           var:queryDictionary="context.request.formValues"
-            />
-          </td>
-          <td class="tbtv_headercell">
-            <var:if condition="showToAddress" const:negate="YES">
-              <var:component className="UIxMailSortableTableHeader"
-                             label:label="From"
-                             const:sortKey="from"
-                             const:href="view"
-                             var:queryDictionary="context.request.formValues"
-              />
-            </var:if>
-            <var:if condition="showToAddress">
-              <var:component className="UIxMailSortableTableHeader"
-                             label:label="To"
-                             const:sortKey="to"
-                             const:href="view"
-                             var:queryDictionary="context.request.formValues"
-              />
-            </var:if>
-          </td>
-          <td class="tbtv_headercell" width="17">
-            <img rsrc:src="title_read_14x14.png" width="14" height="14" />
-          </td>
-          <td class="tbtv_headercell" width="17">
-            <img rsrc:src="title_attachment_14x14.png" width="14" height="14" />
-          </td>
-          <td class="tbtv_headercell">
-            <var:component className="UIxMailSortableTableHeader"
-                           label:label="Date"
-                           const:sortKey="date"
-                           const:href="view"
-                           var:queryDictionary="context.request.formValues"
-                           const:isDefault="YES"
-            />
-          </td>
-        </tr>
-        <tr class="tableview">
-          <td colspan="6" class="tbtv_navcell" align="right">
-            <var:if condition="showsAllMessages">
-              <var:string value="sortedUIDs.count" />
-              <var:string label:value="messages" />
-            </var:if>
-            
-            <var:if condition="showsAllMessages" const:negate="YES">
-              <var:if condition="hasPrevious">
-                <a href="view"
-                   _idx="1"
-                   var:queryDictionary="queryParameters"
-                ><var:string label:value="first"/></a> |
-                <a href="view"
-                   var:_idx="prevFirstMessageNumber"
-                   var:queryDictionary="queryParameters"
+  <table multiselect="yes" id="messageList"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <tbody>
+      <tr class="tableview"
+        ><td class="tbtv_headercell messageFlagColumn"
+          ><var:entity const:name="nbsp" /></td
+          ><td class="tbtv_headercell messageFlagColumn">
+          <img rsrc:src="title_attachment_14x14.png" width="14"
+            height="14"
+            /></td
+          ><td class="tbtv_headercell tbtv_subject_headercell"
+          ><var:component className="UIxSortableTableHeader"
+            label:label="Subject"
+            const:sortKey="subject"
+            const:href="view"
+            var:queryDictionary="context.request.formValues"
+            /></td
+          ><td class="tbtv_headercell"
+          ><var:if condition="showToAddress" const:negate="YES"
+            ><var:component className="UIxSortableTableHeader"
+              label:label="From"
+              const:sortKey="from"
+              const:href="view"
+              var:queryDictionary="context.request.formValues"
+              /></var:if
+            ><var:if condition="showToAddress"
+            ><var:component className="UIxSortableTableHeader"
+              label:label="To"
+              const:sortKey="to"
+              const:href="view"
+              var:queryDictionary="context.request.formValues"
+              /></var:if
+            ></td
+          ><td class="tbtv_headercell messageFlagColumn"
+          ><img rsrc:src="title_read_14x14.png" width="14" height="14"
+            /></td
+          ><td class="tbtv_headercell"
+          ><var:component className="UIxSortableTableHeader"
+            label:label="Date"
+            const:sortKey="date"
+            const:href="view"
+            var:queryDictionary="context.request.formValues"
+            const:isDefault="YES"
+            /></td
+          ></tr>
+      <var:if condition="showsAllMessages" const:negate="YES"
+        ><tr class="tableview"
+          ><td colspan="6" class="tbtv_navcell"
+            ><var:if condition="hasPrevious">
+              <a href="#"
+                onclick="openMailboxAtIndex(this);"
+                idx="1"><var:string label:value="first"/></a> |
+              <a href="#"
+                onclick="openMailboxAtIndex(this);"
+                var:idx="prevFirstMessageNumber"
                 ><var:string label:value="previous"/></a> |
-              </var:if>
-  
-              <var:string value="firstMessageNumber"/>
-              <var:string label:value="msgnumber_to" />
-              <var:string value="lastMessageNumber"/>
-              <var:string label:value="msgnumber_of" />
-              <var:string value="sortedUIDs.count" />
-  
-              <var:if condition="hasNext">
-                | <a href="view"
-                     var:_idx="nextFirstMessageNumber"
-                     var:queryDictionary="queryParameters"
-                  ><var:string label:value="next" /></a>
-              </var:if>
             </var:if>
-          </td>
-        </tr>
-        
-        <var:foreach list="messages" item="message">
-          <tr class="tableview" var:id="msgRowID"
-              onmouseover="ml_highlight(this)"
-              onmouseout="ml_lowlight(this)"
-              style="cursor: pointer;"
-          >
-            <td>
-              <!-- this seems to break on Safari, it treats name==id? -->
-              <input type="checkbox" var:name="msgRowID" value="0" 
-                     onchange="toggleMailSelect(this)" />
-            </td>
-            <!-- the td:onlick doesn't work on Safari -->
-            <td var:class="messageCellStyleClass" var:onclick="clickedMsgJS">
-              <div var:class="messageSubjectStyleClass" var:id="msgDivID">
-                <!-- removed anker (resulted in two clicks on Moz -->
-                <!-- a href="#" var:onclick="clickedMsgJS" -->
-                  <!-- Note: var:href="messageViewURL" (done by JS),
-                             var:target="messageViewTarget" -->
-                  <var:string value="message.envelope.subject"
-                              formatter="context.mailSubjectFormatter"/>
-                <!-- /a -->
-              </div>
-            </td>
-            <td var:class="messageCellStyleClass" var:onclick="clickedMsgJS">
-              <!-- TODO: show compose links -->
-              <!-- TODO: different color for internal vs external addrs -->
-              <var:if condition="showToAddress" const:negate="YES">
-                <var:string value="message.envelope.from"
-                            formatter="context.mailEnvelopeAddressFormatter" />
-              </var:if>
-              <var:if condition="showToAddress">
-                <var:string value="message.envelope.to"
-                            formatter="context.mailEnvelopeAddressFormatter" />
-              </var:if>
-            </td>
+            <var:string value="firstMessageNumber" />
+            <var:string label:value="msgnumber_to" />
+            <var:string value="lastMessageNumber" />
+            <var:string label:value="msgnumber_of" />
+            <var:string value="sortedUIDs.count" />
+            <var:if condition="hasNext"
+              >| <a href="#"
+                onclick="openMailboxAtIndex(this);"
+                var:idx="nextFirstMessageNumber"
+                ><var:string label:value="next" /></a>
+            </var:if
+              ></td
+            ></tr
+          ></var:if>
+      <var:foreach list="messages" item="message"
+        ><tr class="tableview" var:id="msgRowID"
+          ><td></td
+            ><td><var:if condition="hasMessageAttachment"
+              ><img rsrc:src="title_attachment_14x14.png"
+                /></var:if
+              ></td
             
-            <td>
-              <div class="mailer_readicon"
-                   var:style="msgIconReadVisibility"
-                   var:id="msgIconReadDivID">
-                <a href="#" var:onclick="markUnreadJS"
-                   label:title="Mark Unread"> </a>
-              </div>
-              <div class="mailer_unreadicon"  
-                   var:style="msgIconUnreadVisibility"
-                   var:id="msgIconUnreadDivID">
-                <a href="#" var:onclick="markReadJS"
-                   label:title="Mark Read"> </a>
-              </div>
-            </td>
-            <td>
-              <var:if condition="hasMessageAttachment">
-                <img rsrc:src="title_attachment_14x14.png" 
-                     width="14" height="14" />
-              </var:if>
-              <entity name="nbsp" />
-            </td>
-           
-            <td var:class="messageCellStyleClass" var:onclick="clickedMsgJS">
-              <span class="mailer_datefield">
-                <var:string value="message.envelope.date" 
-                            formatter="context.mailDateFormatter"/>
-              </span>
-              <entity name="nbsp" />
-            </td>
-          </tr>
-        </var:foreach>
-
-        <tr class="tableview">
-          <td colspan="6" class="tbtv_actcell">
-<!-- TODO: fix used tree, treeNavigationNodes is the _wrong_ choice
-            <var:component className="UIxMailMoveToPopUp"
-                           const:identifier="moveto"
-                           const:callback="moveTo"
-                           rootNodes="clientObject.treeNavigationNodes"
-            />
--->
-<!-- enable once we have buttons and functionality to actually move sth #1211
-            <var:popup const:name="moveto" const:id="moveto"
-                       list="clientObject.mailAccountFolder.allFolderPathes"
-                      item="item" value="item" displayString="item" />
--->
-          </td>
-        </tr>
-      </table>
-      
-      <span id="selected_uids" style="visibility: hidden;">
-      </span>
-    </div>
-  </div>
- </div>
+            ><td
+            var:class="messageSubjectCellStyleClass"
+            var:id="msgDivID"
+            ><var:string value="message.envelope.subject"
+              formatter="context.mailSubjectFormatter"
+              /></td
 
-  <var:if condition="hideFrame" const:negate="YES">
-    <script language="JavaScript">
-      document.pageform.search.focus();
-    </script>
-  </var:if>
-</var:component>
+            ><td
+            var:class="messageCellStyleClass"
+            ><var:if condition="showToAddress" const:negate="YES"
+              ><var:string value="message.envelope.from"
+                formatter="context.mailEnvelopeAddressFormatter"
+                /></var:if
+              ><var:if condition="showToAddress"
+              ><var:string value="message.envelope.to"
+                formatter="context.mailEnvelopeAddressFormatter"
+                /></var:if
+              ></td
+            
+            ><td var:class="messageCellStyleClass"
+            ><var:if condition="isMessageRead"
+              ><img rsrc:src="icon_read.gif"
+                class="mailerReadIcon"
+                label:title="Mark Unread"
+                label:title-markread="Mark Read"
+                label:title-markunread="Mark Unread"
+                var:id="msgIconReadImgID"
+                /></var:if
+              ><var:if condition="isMessageRead" const:negate="YES"
+              ><img rsrc:src="icon_unread.gif"
+                class="mailerUnreadIcon"
+                label:title="Mark Read"
+                label:title-markread="Mark Read"
+                label:title-markunread="Mark Unread"
+                var:id="msgIconUnreadImgID"
+                /></var:if
+              ></td
+            
+            ><td var:class="messageCellStyleClass"
+            ><span class="mailer_datefield"
+              ><var:string value="message.envelope.date" 
+                formatter="context.mailDateFormatter"
+                /></span
+              ><entity name="nbsp"
+              /></td
+            ></tr>
+      </var:foreach>
+    </tbody>
+  </table>
index 4c0f6c329650de3cef912329b865f51b9f65cb5a..4c1afc879e90d3cd5cfcddc28dccdf1a6782c8be 100644 (file)
 <?xml version="1.0" standalone="yes"?>
-<container xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
->
-  <var:if condition="hideFrame" const:negate="YES">
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
->
-  <head>
-    <title>
-      <var:string value="title"/>
-    </title>
-    
-    <meta name="description" content="SOGo Web Interface"/>
-    <meta name="author" content="SKYRIX Software AG"/>
-    <meta name="robots" content="stop"/>
-    
-    <script rsrc:src="generic.js"> <!-- space required --></script>
-    <script rsrc:src="mailer.js" > <!-- space required --></script>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="title"
+    popup="isPopup"
+    >
+    <div class="menu" id="accountIconMenu">
+      <ul id="sourceList">
+        <li><var:string label:value="Subscribe..." /></li>
+        <li><var:string label:value="Get Messages for Account" /></li>
+        <li><var:string label:value="New Folder..." /></li>
+        <li class="separator"></li>
+        <li><var:string label:value="Search Messages..." /></li>
+        <li><var:string label:value="Properties..." /></li>
+      </ul>
+    </div>
+
+    <div class="menu" id="inboxIconMenu">
+      <ul id="sourceList">
+        <li><var:string label:value="Open in New Mail Window" /></li>
+        <li><var:string label:value="Copy Folder Location" /></li>
+        <li><var:string label:value="Subscribe..." /></li>
+        <li class="separator"></li>
+        <li><var:string label:value="Mark Folder Read..." /></li>
+        <li><var:string label:value="New Folder..." /></li>
+        <li><var:string label:value="Compact This Folder" /></li>
+        <li class="separator"></li>
+        <li><var:string label:value="Search Messages..." /></li>
+        <li><var:string label:value="Properties..." /></li>
+      </ul>
+    </div>
+      
+    <div class="menu" id="trashIconMenu">
+      <ul id="sourceList">
+        <li><var:string label:value="Open in New Mail Window" /></li>
+        <li><var:string label:value="Copy Folder Location" /></li>
+        <li><var:string label:value="Subscribe..." /></li>
+        <li class="separator"></li>
+        <li><var:string label:value="Mark Folder Read..." /></li>
+        <li><var:string label:value="New Subfolder..." /></li>
+        <li><var:string label:value="Compact This Folder" /></li>
+        <li><var:string label:value="Empty Trash" /></li>
+        <li class="separator"></li>
+        <li><var:string label:value="Search Messages..." /></li>
+        <li><var:string label:value="Properties..." /></li>
+      </ul>
+    </div>
+
+    <div class="menu" id="mailboxIconMenu">
+      <ul id="sourceList">
+        <li><var:string label:value="Open in New Mail Window" /></li>
+        <li><var:string label:value="Copy Folder Location" /></li>
+        <li><var:string label:value="Subscribe..." /></li>
+        <li class="separator"></li>
+        <li><var:string label:value="Mark Folder Read..." /></li>
+        <li><var:string label:value="New Subfolder..." /></li>
+        <li><var:string label:value="Rename Folder..." /></li>
+        <li><var:string label:value="Compact This Folder" /></li>
+        <li><var:string label:value="Delete Folder" /></li>
+        <li class="separator"></li>
+        <li><var:string label:value="Search Messages..." /></li>
+        <li><var:string label:value="Properties..." /></li>
+      </ul>
+    </div>
     
-    <link type="text/css" rel="stylesheet" rsrc:href="uix.css"/>
-    <link type="text/css" rel="stylesheet" rsrc:href="mailer.css"/>
-    <link type="text/css" rel="stylesheet" rsrc:href="mailer-toolbar.css"/>
+    <div class="menu" id="addressMenu">
+      <ul id="sourceList">
+        <li id="add_to_addressbook"
+          onmouseup="newContactFromEmail(this);"><var:string label:value="Add to Address Book..."/></li>
+        <li id="compose_mailto"
+          onmouseup="newEmailTo(this);"><var:string label:value="Compose Mail To"/></li>
+        <li id="create_filter"
+          onmouseup="onMenuEntryClick(this, event);"><var:string label:value="Create Filter From Message..."/></li>
+      </ul>
+    </div>
 
-    <link href="mailto:info@skyrix.com" rev="made"/>
-  </head>
+    <div class="menu" id="messageListMenu">
+      <ul id="sourceList">
+        <li
+          onmouseup="onMenuOpenMessage(event);"><var:string label:value="Open Message In New Window"/></li>
+        <li class="separator"></li>
+        <li
+          onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li>
+        <li
+          onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li>
+        <li
+          onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li>
+        <li
+          onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li>
+        <li class="separator"></li>
+        <li
+          class="submenu"
+          mailboxaction="move"
+          submenu="mailboxes-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Move To"/></li>
+        <li
+          class="submenu"
+          mailboxaction="copy"
+          submenu="mailboxes-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Copy To"/></li>
+        <li
+          class="submenu"
+          submenu="label-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Label"/></li>
+        <li
+          class="submenu"
+          submenu="mark-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Mark"/></li>
+        <li class="separator"></li>
+        <li
+          onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li>
+        <li
+          onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li>
+        <li
+          onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li>
+        <li
+          onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li>
+      </ul>
+    </div>
 
-  <body style="background-color: #D4D0C8;">
-   <!-- 
-     Note: the 'href' is required, otherwise an element-id will get created
-     -->
-   <form name="pageform" var:href="pageFormURL" _wosid="0">
+    <div class="menu" id="messageContentMenu">
+      <ul>
+        <li
+          onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li>
+        <li
+          onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li>
+        <li
+          onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li>
+        <li
+          onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li>
+        <li
+          class="submenu"
+          mailboxaction="move"
+          submenu="mailboxes-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Move To"/></li>
+        <li
+          class="submenu"
+          mailboxaction="copy"
+          submenu="mailboxes-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Copy To"/></li>
+        <li class="separator"></li>
+        <li
+          class="submenu"
+          submenu="label-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Label"/></li>
+        <li
+          class="submenu"
+          submenu="mark-menu"
+          onmouseover="dropDownSubmenu(event);"><var:string label:value="Mark"/></li>
+        <li class="separator"></li>
+        <li
+          onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li>
+        <li
+          onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li>
+        <li
+          onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li>
+        <li
+          onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li>
+      </ul>
+    </div>
 
-     <var:if condition="showLinkBanner">
-       <table cellpadding="5" cellspacing="0" border="0" class="linkbanner">
-         <tr>
-          <td colspan="2">
-            <table cellpadding="0" cellspacing="0" border="0" width="100%">
-              <tr>
-                <td class="linkbannerlinks">
-                  <a var:href="relativeHomePath"
-                  ><var:string label:value="Home" /></a> |
-                  <a var:href="relativeCalendarPath"
-                  ><var:string label:value="Calendar" /></a> |
-                  <a var:href="relativeContactsPath"
-                  ><var:string label:value="Addressbook" /></a> |
-                  <a var:href="relativeMailPath"
-                  ><var:string label:value="Mail" /></a> |
-                  <a href="http://to.be.done/"
-                  ><var:string label:value="Right Administration" /></a>
-                </td>
-                <td class="linkbannerimage">
-                  <a href="http://www.opengroupware.org:80/" target="OGo">
-                    <img rsrc:src="CommonUI.SOGo/menu_logo_top.gif"
-                         align="center" border="0" alt="OGo Logo" 
-                         valign="middle"
-                    />
-                  </a>
-                </td>
-              </tr>
-            </table>
-           
-            <!-- TODO: replace the line with a CSS straight line -->
-            <table cellpadding="0" cellspacing="0" border="0" width="100%">
-              <tr>
-                <td class="linecolor"><img 
-                    rsrc:src="CommonUI.SOGo/line_left.gif"/></td>
-                <td class="linecolor" width="98%">
-                  <img rsrc:src="CommonUI.SOGo/line_stretch.gif"/>
-                </td>
-                <td class="linecolor"><img 
-                    rsrc:src="CommonUI.SOGo/line_right.gif"/></td>
-              </tr>
-              <tr>
-                <td valign="top" colspan="2">
-                  <var:component className="UIxAppNavView" />
-                </td>
-                <td valign="top" align="right" class="button_submit_env">
-                  <a var:href="helpURL"
-                     class="button_submit"
-                     label:string="Help"
-                     var:target="helpWindowTarget"
-                  />
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-      </table>
-    </var:if>
+    <div class="menu" id="label-menu">
+      <ul id="">
+        <li onmouseup="onMenuLabelMessage(event, 'none');"><var:string label:value="None" /></li>
+        <li class="separator"></li>
+        <li onmouseup="onMenuLabelMessage(event, 'important);"><var:string label:value="Important" /></li>
+        <li onmouseup="onMenuLabelMessage(event, 'work');"><var:string label:value="Work" /></li>
+        <li onmouseup="onMenuLabelMessage(event, 'personal');"><var:string label:value="Personal" /></li>
+        <li onmouseup="onMenuLabelMessage(event, 'todo');"><var:string label:value="To Do" /></li>
+        <li onmouseup="onMenuLab-elMessage(event, 'later');"><var:string label:value="Later" /></li>
+      </ul>
+    </div>
 
-    <table border="0" class="tb_maintable" cellspacing="0" cellpadding="2"
-           var:style="bannerToolbarStyle">
-      <!-- this table is required for right alignment -->
-      <tr>
-        <td valign="top" class="vertframerow">
-          <var:component className="UIxMailToolbar" />
-        </td>
-        <td align="right" width="80" class="vertframerow">
-          <table border="0"> <!-- TODO: what is this table for? -->
-            <tr>
-              <td class="tb_logocell tb_icon"
-                  ><div class="tbicon_logo"> </div></td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-    </table>
-    
-    <!-- consume toolbar -->
-    <div class="tb_consumer" var:style="bannerConsumeStyle"> </div>
-    
-    <table border="0" width="100%" cellspacing="0" cellpadding="2">
-      <tr class="vertframerow">
-        <td width="100%" valign="top" class="vertframerow" colspan="2">
-          <var:if condition="hideFolderTree">
-            <var:component-content/>
-          </var:if>
-          
-          <var:if condition="hideFolderTree" const:negate="YES">
-            <table width="100%">
-              <tr>
-                <td width="25%" valign="top" class="foldercell">
-                  <div class="titlediv"
-                       ><var:string label:value="Folders" /></div>
-                  <div style="height: 95%">
-                    <div class="embedwhite_out">
-                      <div class="embedwhite_in">
-                        <var:component className="UIxMailTree" 
-                           rootClassName="treeRootClassName" 
-                           const:treeFolderAction="view" 
-                           />
-                      </div>
-                    </div>
-                  </div>
-                </td>
-                <td style="width: 6px;"> </td>
-                <td valign="top" class="contentcell">
-                  <var:component-content/>
-                </td>
-              </tr>
-            </table>
-          </var:if>
-        </td>
-      </tr>
-    </table>
-   </form>
+    <var:component
+      className="UIxMailFolderMenu"
+      const:menuId="mailboxes-menu"
+      const:parentMenu="0"
+      rootClassName="treeRootClassName" 
+      const:treeFolderAction="view" />
+
+    <div class="menu" id="mark-menu">
+      <ul id="">
+        <li onmouseup="onMenuMarkMessage(event, 'read');"><var:string label:value="As Read" /></li>
+        <li onmouseup="onMenuMarkMessage(event, 'threadread');"><var:string label:value="Thread As Read" /></li>
+        <li onmouseup="onMenuMarkMessage(event, 'readbydate);"><var:string label:value="As Read By Date..." /></li>
+        <li onmouseup="onMenuMarkMessage(event, 'allread);"><var:string label:value="All Read" /></li>
+        <li class="separator"></li>
+        <li onmouseup="onMenuMarkMessage(event, 'flag);"><var:string label:value="Flag" /></li>
+        <li class="separator"></li>
+        <li onmouseup="onMenuMarkMessage(event, 'junk);"><var:string label:value="As Junk" /></li>
+        <li onmouseup="onMenuMarkMessage(event, 'notjunk);"><var:string label:value="As Not Junk" /></li>
+        <li onmouseup="onMenuMarkMessage(event, 'runjunkmailcontrols);"><var:string label:value="Run Junk Mail Controls" /></li>
+      </ul>
+    </div>
+
+    <div id="leftPanel">
+      <div class="titlediv"><var:string label:value="Folders" /></div>
+      <var:component className="UIxMailTree" 
+        rootClassName="treeRootClassName" 
+        const:treeFolderAction="view" 
+        />
+    </div>
+      
+    <div class="dragHandle" id="verticalDragHandle"><!-- space --></div>
 
-   <var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
-  </body>
-</html>
-   </var:if>
+    <div id="rightPanel">
+      <var:component className="UIxMailFilterPanel" qualifier="qualifier" />
+      
+        <div id="mailboxContent"><!-- space --></div>
+        <div class="dragHandle" id="rightDragHandle"><!-- space --></div>
+        <div id="messageContent"><!-- space --></div>
+        <script type="text/javascript">
+          initMailboxSelection('<var:string value="mailFolderName" />');
+        </script>
+      </div>
+    </form>
 
-  <var:if condition="hideFrame">
-    <var:component-content/>
-  </var:if>
-</container>
+    <var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
+  </var:component>
index ec331caa6a50157092d9581d6af96294d71dbc6f..12e14d63b39e3ccab298ecff46447278d9d4a85d 100644 (file)
@@ -23,4 +23,4 @@
   </var:foreach>
 
   <option value="all" disabled="1" >All</option>
-</select>
\ No newline at end of file
+</select>
diff --git a/UI/Templates/MailerUI/UIxMailPanelFrame.wox b/UI/Templates/MailerUI/UIxMailPanelFrame.wox
deleted file mode 100644 (file)
index 80c42e8..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<container xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
->
-  <var:if condition="hideFrame" const:negate="YES">
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
->
-  <head>
-    <title>
-      <var:string value="title"/>
-    </title>
-    
-    <meta name="description" content="SOGo Web Interface"/>
-    <meta name="author" content="SKYRIX Software AG"/>
-    <meta name="robots" content="stop"/>
-    
-    <var:js-stringtable const:framework="MailerUI.SOGo"
-                        const:identifier="labels"
-                        const:inplace="NO"
-    />
-    <script rsrc:src="generic.js"> <!-- space required --></script>
-    <script rsrc:src="mailer.js" > <!-- space required --></script>
-    
-    <link type="text/css" rel="stylesheet" rsrc:href="uix.css"    />
-    <link type="text/css" rel="stylesheet" rsrc:href="mailer.css" />
-    <link type="text/css" rel="stylesheet" rsrc:href="mailer-toolbar.css" />
-    <link type="text/css" rel="stylesheet" rsrc:href="mailer-compose.css" />
-
-    <link href="mailto:info@skyrix.com" rev="made"/>
-  </head>
-
-  <body style="background-color: #D4D0C8;">
-   <!-- 
-     Note: the 'href' is required, otherwise an element-id will get created
-     -->
-   <form name="pageform" var:href="pageFormURL" _wosid="0">
-
-     <var:if condition="showLinkBanner">
-       <table cellpadding="5" cellspacing="0" border="0" class="linkbanner">
-         <tr>
-          <td colspan="2">
-            <table cellpadding="0" cellspacing="0" border="0" width="100%">
-              <tr>
-                <td class="linkbannerlinks">
-                  <a var:href="relativeHomePath"
-                  ><var:string label:value="Home" /></a> |
-                  <a var:href="relativeCalendarPath"
-                  ><var:string label:value="Calendar" /></a> |
-                  <a var:href="relativeContactsPath"
-                  ><var:string label:value="Addressbook" /></a> |
-                  <a var:href="relativeMailPath"
-                  ><var:string label:value="Mail" /></a> |
-                  <a href="http://to.be.done/"
-                  ><var:string label:value="Right Administration" /></a>
-                </td>
-                <td class="linkbannerimage">
-                  <a href="http://www.opengroupware.org:80/" target="OGo">
-                    <img rsrc:src="CommonUI.SOGo/menu_logo_top.gif"
-                         align="center" border="0" alt="OGo Logo" 
-                         valign="middle"
-                    />
-                  </a>
-                </td>
-              </tr>
-            </table>
-           
-            <!-- TODO: replace the line with a CSS straight line -->
-            <table cellpadding="0" cellspacing="0" border="0" width="100%">
-              <tr>
-                <td class="linecolor"><img 
-                    rsrc:src="CommonUI.SOGo/line_left.gif"/></td>
-                <td class="linecolor" width="98%">
-                  <img rsrc:src="CommonUI.SOGo/line_stretch.gif"/>
-                </td>
-                <td class="linecolor"><img 
-                    rsrc:src="CommonUI.SOGo/line_right.gif"/></td>
-              </tr>
-              <tr>
-                <td valign="top" colspan="2">
-                  <var:component className="UIxAppNavView" />
-                </td>
-                <td valign="top" align="right" class="button_submit_env">
-                  <a var:href="helpURL"
-                     class="button_submit"
-                     label:string="Help"
-                     var:target="helpWindowTarget"
-                  />
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-      </table>
-    </var:if>
-
-    <table border="0" class="tb_maintable" cellspacing="0" cellpadding="2"
-           var:style="bannerToolbarStyle">
-      <!-- this table is required for right alignment -->
-      <tr>
-        <td valign="top" class="vertframerow">
-          <var:component className="UIxMailToolbar" />
-        </td>
-        <td align="right" width="80" class="vertframerow">
-          <table border="0"> <!-- TODO: what is this table for? -->
-            <tr>
-              <td class="tb_logocell tb_icon"
-                  ><div class="tbicon_logo"> </div></td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-    </table>
-    
-    <!-- consume toolbar -->
-    <div class="tb_consumer" var:style="bannerConsumeStyle"> </div>
-    
-    <table border="0" width="100%" cellspacing="0" cellpadding="2">
-      <tr class="vertframerow">
-        <td width="100%" valign="top" class="vertframerow" colspan="2">
-          <var:component-content/>
-        </td>
-      </tr>
-    </table>
-   </form>
-
-   <var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
-  </body>
-</html>
-   </var:if>
-
-  <var:if condition="hideFrame">
-    <var:component-content/>
-  </var:if>
-</container>
diff --git a/UI/Templates/MailerUI/UIxMailPopupView.wox b/UI/Templates/MailerUI/UIxMailPopupView.wox
new file mode 100644 (file)
index 0000000..6b892b5
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="title"
+    const:popup="YES">
+    <var:component className="UIxMailView" />
+  </var:component>
diff --git a/UI/Templates/MailerUI/UIxMailSortableTableHeader.wox b/UI/Templates/MailerUI/UIxMailSortableTableHeader.wox
deleted file mode 100644 (file)
index c983234..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
->
-  <var:if condition="isSelected" const:negate="YES">
-    <a var:href="href"
-       var:_sort="sortKey"
-       _desc="0"
-       var:queryDictionary="queryDictionary"
-    ><var:string var:value="label"
-     /></a>
-  </var:if>
-  <var:if condition="isSelected">
-    <var:if condition="isSortedDescending" >
-      <a var:href="href"
-         var:_sort="sortKey"
-         _desc="0"
-         var:queryDictionary="queryDictionary"
-      ><var:string var:value="label"
-       /><var:entity const:name="nbsp"
-         /><img rsrc:src="title_sortup_12x12.png"
-                class="tbtv_sortcell"
-           /></a>
-    </var:if>
-    <var:if condition="isSortedDescending" const:negate="YES" >
-      <a var:href="href"
-         var:_sort="sortKey"
-         _desc="1"
-         var:queryDictionary="queryDictionary"
-      ><var:string var:value="label"
-       /><var:entity const:name="nbsp"
-         /><img rsrc:src="title_sortdown_12x12.png"
-                class="tbtv_sortcell"
-           /></a>
-    </var:if>
-  </var:if>
-</span>
\ No newline at end of file
diff --git a/UI/Templates/MailerUI/UIxMailSplashView.wox b/UI/Templates/MailerUI/UIxMailSplashView.wox
new file mode 100644 (file)
index 0000000..26cef68
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version='1.0' standalone='yes'?>
+  <div style="padding: 1em;"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <h2>
+      SOGo Mail - <var:string value="objectTitle" />
+      
+      <var:if condition="clientObject.isSharedAccount">
+        <var:string label:value="Shared Account: " />
+      </var:if>
+      
+    </h2>
+    <var:if condition="clientObject.isSharedAccount">
+      <div>
+        <var:string label:value="Share: " />
+        <var:string value="clientObject.sharedAccountName" />
+      </div>
+    </var:if>
+    
+    <h3>Email</h3>
+    <p>
+      <a href="INBOX/" onclick="initMailboxSelection(currentMailbox + '/INBOX'); openMailbox(currentMailbox + '/INBOX'); return false;"><img rsrc:src="read-messages.png" /><var:string label:value="Read messages" /></a><br />
+      <a href="#" onclick="clickedCompose(this);"><img rsrc:src="write-message.png" /><var:string label:value="Write a new message" /></a><br />
+    </p>
+
+    <h3>Accounts</h3>
+    <p>
+      <a href=""><img rsrc:src="account-settings.png" />View settings for this account</a><br />
+      <a href=""><img rsrc:src="create-account.png" />Create a new account</a> [TBD: not in Agenor]<br />
+    </p>
+    
+    <h3>Advanced Features</h3>
+    <p>
+      <a href=""><img rsrc:src="search-messages.png" />Search messages</a><br />
+      <a href=""><img rsrc:src="manage-filters.png" />Manage message filters</a><br />
+      <a href=""><img rsrc:src="manage-imap.png" />Manage folder subscriptions</a><br />
+      <a href=""><img rsrc:src="offline-settings.png" />Offline settings</a> [TBD: not in Agenor]<br />
+    </p>
+  </div>
index fc9754825524a8974ade13fe86e51bb090c1c842..4a1ecbdcd11ab1532e7e7ba67bd410c7296cfe85 100644 (file)
@@ -1,61 +1,59 @@
 <?xml version='1.0' standalone='yes'?>
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
-      border="0"
-      width="100%"
->
-  <script language="JavaScript">
-    var currentIndex = <var:string value="currentIndex" />;
-  </script>
-  <script language="JavaScript" rsrc:src="UIxMailToSelection.js"> <!-- Space! --></script>
-
-  <table id="addr_table" style="width: 100%;">
-    <var:foreach list="addressLists" item="addressList">
-      <var:foreach list="addressList" item="address">
-        <tr var:id="currentRowId">
-          <td width="20%">
+  <container xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    >
+    <script type="text/javascript">
+      var currentIndex = <var:string value="currentIndex" />;
+    </script>
+    <script type="text/javascript" rsrc:src="UIxMailToSelection.js"> <!-- Space! --></script>
+    <script type="text/javascript" rsrc:src="layout2or3_xlib.js"> <!-- Space! --></script>
+    
+    <div id="addressList"
+      ><var:foreach list="addressLists" item="addressList"
+        ><var:foreach list="addressList" item="address">
+          <div class="addressListElement" var:id="currentRowId">
+            <span class="headerField">
             <var:popup name="currentPopUpId"
-                       list="headers"
-                       item="item"
-                       label:string="$item"
-                       selection="currentHeader"
-                       const:style="width: 100%;"
-            />
-          </td>
-          <td width="80%">
+              list="headers"
+              item="item"
+              label:string="$item"
+              selection="currentHeader"
+              />
+            </span>
+            <span class="headerInput">
             <input var:id="currentAddressId"
-                   var:name="currentAddressId"
-                   type="text"
-                   var:value="address"
-                   onfocus="addressFieldGotFocus(this);"
-                   onblur="addressFieldLostFocus(this);"
-                   style="width: 100%;"
-            />
-          </td>
-        </tr>
-        <var:string value="nextId" />
+              var:name="currentAddressId"
+              class="textField"
+              type="text"
+              var:value="address"
+              onfocus="addressFieldGotFocus(this);"
+              onblur="addressFieldLostFocus(this);"
+              />
+            </span>
+          </div>
+        </var:foreach>
       </var:foreach>
-    </var:foreach>
-    <tr id="row_last">
-      <td width="20%">
-        <!-- todo: use stylesheet? -->
-        <select style="width: 100%;" disabled="1">
-          <option value="to" ><var:string label:value="to" />:</option>
-        </select>
-      </td>
-      <td width="80%">
-        <!-- todo: use stylesheet? -->
-        <input onfocus="fancyAddRow(true,'');" type="text" 
-               style="width: 100%;" />
-      </td>
-    </tr>
-  </table>
-  <!--<var:if condition="isUIxDebugEnabled">
+      <div class="addressListElement" id="lastRow">
+        <span class="headerField">
+          <select disabled="1">
+            <option value="to"><var:string label:value="to" />:</option>
+          </select>
+        </span>
+        <span class="headerInput">
+          <input onfocus="fancyAddRow(true,'');"
+            readonly="1"
+            type="text"
+            class="textField" />
+        </span>
+      </div>
+    <!--<var:if condition="isUIxDebugEnabled">
     <a href="#" onclick="checkAddresses();">check addresses</a>
   </var:if>-->
-  <span id="addr_addresses" style="visibility: hidden;"><var:foreach list="addressLists" item="addressList"><var:foreach list="addressList" item="address"><span var:id="address" /></var:foreach></var:foreach>
-  </span>
-</span>
\ No newline at end of file
+    </div>
+    <span id="addr_addresses" style="display: none; visibility: hidden;"><var:foreach list="addressLists" item="addressList"><var:foreach list="addressList" item="address"><span var:id="address" /></var:foreach></var:foreach>
+    </span>
+  </container>
+
diff --git a/UI/Templates/MailerUI/UIxMailToolbar.wox b/UI/Templates/MailerUI/UIxMailToolbar.wox
deleted file mode 100644 (file)
index 8514870..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<table
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:rsrc="OGo:url"
-  xmlns:label="OGo:label"
-  xmlns:so="http://www.skyrix.com/od/so-lookup"
->
-  <!-- image row -->
-  <tr>
-    <var:foreach list="toolbarConfig" item="toolbarGroup">
-      <var:foreach list="toolbarGroup" item="buttonInfo">
-        <var:if condition="isButtonEnabled">
-          <td class="tb_icon"
-            ><a var:href="buttonInfo.link" var:target="buttonInfo.target"
-               var:class="buttonInfo.cssClass"
-                var:onclick="buttonInfo.onclick"></a></td>
-        </var:if>
-      </var:foreach>
-      <td class="tb_spacer"> </td>
-    </var:foreach>
-  </tr>
-  <!-- label row -->
-  <tr>
-    <var:foreach list="toolbarConfig" item="toolbarGroup">
-      <var:foreach list="toolbarGroup" item="buttonInfo">
-        <var:if condition="isButtonEnabled">
-          <td class="tb_label"><var:string value="buttonLabel" /></td>
-        </var:if>
-      </var:foreach>
-      <td class="tb_spacer"> </td>
-    </var:foreach>
-  </tr>
-</table>
index 5f940b32fc604e26aa9701d62ae7296ccd28c94b..97cb46b1d9c5d97122584a91357f16e96097685d 100644 (file)
@@ -1,39 +1,39 @@
 <?xml version="1.0" standalone="yes"?>
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
->
-  <!-- TODO: extend treeview to use CSS -->
-  <var:treeview
-    list="rootNodes" item="item" sublist="item.children"
-    zoom="item.isPathNode"
-    const:iconWidth       = "17"
-    const:plusIcon        = "tbtv_plus_17x17.gif"
-    const:minusIcon       = "tbtv_minus_17x17.gif"
-    const:lineIcon        = "tbtv_line_17x17.gif"
-    const:cornerIcon      = "tbtv_corner_17x17.gif"
-    const:junctionIcon    = "tbtv_junction_17x17.gif"
-    const:leafIcon        = "tbtv_leaf_corner_17x17.gif"
-    const:leafCornerIcon  = "tbtv_leaf_corner_17x17.gif"
-    const:cornerPlusIcon  = "tbtv_corner_plus_17x17.gif"
-    const:cornerMinusIcon = "tbtv_corner_minus_17x17.gif"
-    const:spaceIcon       = "tbtv_space_17x17.gif"
-  >
-    <var:tree-data const:isTreeElement="YES" const:treeLink=""
-                   var:icon="item.iconName" 
-                   var:cornerIcon="item.iconName">
-      <a var:href="item.link">
-        <span class="treecell">
-          <var:if condition="item.isActiveNode">
-            <b><var:string value="item.title" /></b>
-          </var:if>
-          <var:if condition="item.isActiveNode" const:negate="YES">
-            <var:string value="item.title" />
-          </var:if>
-        </span>
-      </a>
-    </var:tree-data>
-  </var:treeview>
-</span>
+  <div id="folderTreeContent"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <!-- TODO: extend treeview to use CSS -->
+
+    <script type="text/javascript" rsrc:src="dtree.js"><!-- space --></script>
+    <script type="text/javascript">
+      d = new dTree('d');
+      d.config.folderLlinks = true;
+      d.config.hideRoot = true;
+
+      d.icon.root = '<var:string rsrc:value="tbtv_account_17x17.gif" />';
+      d.icon.folder = '<var:string rsrc:value="tbtv_leaf_corner_17x17.gif" />';
+      d.icon.folderOpen        = '<var:string rsrc:value="tbtv_leaf_corner_17x17.gif" />';
+      d.icon.node = '<var:string rsrc:value="tbtv_leaf_corner_17x17.gif" />';
+      d.icon.line = '<var:string rsrc:value="tbtv_line_17x17.gif" />';
+      d.icon.join = '<var:string rsrc:value="tbtv_junction_17x17.gif" />';
+      d.icon.joinBottom        = '<var:string rsrc:value="tbtv_corner_17x17.gif" />';
+      d.icon.plus = '<var:string rsrc:value="tbtv_plus_17x17.gif" />';
+      d.icon.plusBottom        = '<var:string rsrc:value="tbtv_corner_plus_17x17.gif" />';
+      d.icon.minus = '<var:string rsrc:value="tbtv_minus_17x17.gif" />';
+      d.icon.minusBottom = '<var:string rsrc:value="tbtv_corner_minus_17x17.gif" />';
+      d.icon.nlPlus = '<var:string rsrc:value="tbtv_corner_plus_17x17.gif" />';
+      d.icon.nlMinus = '<var:string rsrc:value="tbtv_corner_minus_17x17.gif" />';
+      d.icon.empty = '<var:string rsrc:value="empty.gif" />';
+
+      d.add(0, -1, '');
+      <var:foreach list="flattenedNodes" item="item"
+       ><var:component className="UIxMailTreeBlockJS"
+         const:treeObjectName="d"
+         var:item="item"
+          /></var:foreach>
+      document.write(d);
+    </script>
+  </div>
diff --git a/UI/Templates/MailerUI/UIxMailTreeBlockJS.wox b/UI/Templates/MailerUI/UIxMailTreeBlockJS.wox
new file mode 100644 (file)
index 0000000..d63a075
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" standalone="yes"?>
+  <container 
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    ><var:string value="treeObjectName" />.add(<var:string value="item.serial" />, <var:string value="item.parent" />, '<var:string value="item.title" />', <var:string value="item.hasChildren" />, '#', '<var:string value="item.name" />', '<var:string value="item.folderType" />', '', '', '<var:string value="iconName" />', '<var:string value="iconName" />');
+  </container>
index 2821a62566042cb2db29aec000e80dd7f2593808..07966734ca9ab3e42df8ecf99e8c2246f342d76a 100644 (file)
 <?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:rsrc="OGo:url"
-  xmlns:label="OGo:label"
-  className="UIxMailPanelFrame"
-  title="panelTitle"
->
-  <!-- TODO: refactor address rendering into an own component(/element) -->
-
-  <!-- TODO: can we create own clientObject's for Kolab entities? Probably
-             not (since we would always need to fetch the header during 
-             lookup). It would work for 'annotated' folders though.
-       TODO: for Kolab we need a completely different viewer with a different
-             toolbar etc. And for Kolab we would need a different list viewer
-             as well ...
-    -->
- <var:if condition="clientObject.isKolabObject" const:negate="1">
-  <!-- 
-    Note: We cannot make this section static (like the toolbar) because the CC
-          list has a dynamic height (would require some tricky JavaScript).
-    -->
-  <table class="mailer_fieldtable">
-    <tr class="mailer_fieldrow">
-      <td class="mailer_fieldname" ><var:string label:value="Subject"/>:</td>
-      <td class="mailer_subjectfieldvalue">
-        <var:string value="clientObject.subject"
-                    formatter="context.mailSubjectFormatter"/>
-      </td>
-    </tr>
-    <tr class="mailer_fieldrow">
-      <td class="mailer_fieldname" ><var:string label:value="From"/>:</td>
-      <td class="mailer_fieldvalue">
-        <var:foreach list="clientObject.fromEnvelopeAddresses"
-                     item="currentAddress">
-          <a var:href="currentAddressLink">
-            <var:string value="currentAddress"
-                 formatter="context.mailEnvelopeFullAddressFormatter" /></a>
-        </var:foreach>
-      </td>
-    </tr>
-    <tr class="mailer_fieldrow">
-      <td class="mailer_fieldname" ><var:string label:value="Date"/>:</td>
-      <td class="mailer_fieldvalue">
-        <var:string value="clientObject.date" 
-                    formatter="context.mailDateFormatter"/>
-
-        <!-- TODO:
-        (<a rsrc:href="tbird_073_viewer.png">screenshot</a>)
-         -->
-      </td>
-    </tr>
-
-    <tr class="mailer_fieldrow">
-      <td class="mailer_fieldname" ><var:string label:value="To"/>:</td>
-      <td class="mailer_fieldvalue">
-        <var:foreach list="clientObject.toEnvelopeAddresses"
-                     item="currentAddress">
-          <a var:href="currentAddressLink">
-            <var:string value="currentAddress"
-                 formatter="context.mailEnvelopeFullAddressFormatter" /></a>
-        </var:foreach>
-      </td>
-    </tr>
-    <var:if condition="hasCC">
+  <container xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <table class="mailer_fieldtable">
+      <tr class="mailer_fieldrow">
+        <td class="mailer_fieldname" ><var:string label:value="Subject"/>:</td>
+        <td class="mailer_subjectfieldvalue">
+          <var:string value="clientObject.subject"
+            formatter="context.mailSubjectFormatter"/>
+        </td>
+      </tr>
       <tr class="mailer_fieldrow">
-        <td class="mailer_fieldname" ><var:string label:value="CC"/>:</td>
+        <td class="mailer_fieldname" ><var:string label:value="From"/>:</td>
         <td class="mailer_fieldvalue">
-          <var:foreach list="clientObject.ccEnvelopeAddresses" 
-                       item="currentAddress">
-            <a var:href="currentAddressLink">
+          <var:foreach list="clientObject.fromEnvelopeAddresses"
+            item="currentAddress">
+            <a var:href="currentAddressLink" onclick="return onMenuClick(event, 'addressMenu');" oncontextmenu="onMenuClick(event, 'addressMenu');">
               <var:string value="currentAddress"
-                   formatter="context.mailEnvelopeFullAddressFormatter" /></a>
-            <br /> <!-- TODO: better to use li+CSS -->
+                formatter="context.mailEnvelopeFullAddressFormatter" /></a>
           </var:foreach>
         </td>
       </tr>
-    </var:if>
-
-
-    <!-- header fields if available -->
-    <var:if condition="clientObject.hasMailHeaderInCoreInfos">
+      <tr class="mailer_fieldrow">
+        <td class="mailer_fieldname" ><var:string label:value="Date"/>:</td>
+        <td class="mailer_fieldvalue">
+          <var:string value="clientObject.date" 
+            formatter="context.mailDateFormatter"/>
 
-      <var:if condition="clientObject.mailHeaders.organization.isNotEmpty">
-        <tr class="mailer_fieldrow">
-          <td class="mailer_fieldname" 
-              ><var:string label:value="Organization"/>:</td>
-          <td class="mailer_fieldvalue">
-            <var:if-qualifier
-               const:condition="organization hasPrefix: 'http://'" 
-               object="clientObject.mailHeaders">
-              <a var:href="clientObject.mailHeaders.organization"
-                 var:string="clientObject.mailHeaders.organization" />
-            </var:if-qualifier>
-            <var:if-qualifier
-               const:condition="organization hasPrefix: 'http://'" 
-               object="clientObject.mailHeaders"
-               const:negate="1">
-              <var:string value="clientObject.mailHeaders.organization" />
-            </var:if-qualifier>
-          </td>
-        </tr>
-      </var:if>
-      
-      <var:if condition="clientObject.mailHeaders.list-id.isNotEmpty">
-        <tr class="mailer_fieldrow">
-          <td class="mailer_fieldname" 
-              ><var:string label:value="Mailinglist"/>:</td>
-          <td class="mailer_fieldvalue">
-            <a var:href="clientObject.mailingListArchiveURL"
-               target="_blank"
-               var:string="clientObject.mailHeaders.list-id" />
-            |
-            <a var:href="clientObject.mailingListSubscribeURL"
-               target="_blank"><var:string label:value="subscribe"/></a>
-            |
-            <a var:href="clientObject.mailingListUnsubscribeURL"
-               target="_blank"><var:string label:value="unsubscribe"/></a>
-          </td>
-        </tr>
-      </var:if>
-      
-      <var:if condition="clientObject.mailHeaders.x-virus-status.isNotEmpty">
-        <tr class="mailer_fieldrow">
-          <td class="mailer_fieldname" 
-              ><var:string label:value="Virusstatus"/>:</td>
-          <td class="mailer_fieldvalue">
-            <var:string value="clientObject.mailHeaders.x-virus-status" />
-          </td>
-        </tr>
-      </var:if>
+          <!-- TODO:
+          (<a rsrc:href="tbird_073_viewer.png">screenshot</a>)
+          -->
+        </td>
+      </tr>
 
-      <var:if condition="clientObject.mailHeaders.x-spam-level.isNotEmpty">
+      <tr class="mailer_fieldrow">
+        <td class="mailer_fieldname"><var:string label:value="To"/>:</td>
+        <td class="mailer_fieldvalue">
+          <var:foreach list="clientObject.toEnvelopeAddresses"
+            item="currentAddress"
+            ><a var:href="currentAddressLink"
+              onmousedown="return false;"
+              onclick="return onMenuClick(event, 'addressMenu');"
+              oncontextmenu="onMenuClick(event, 'addressMenu');">
+              <var:string value="currentAddress"
+                formatter="context.mailEnvelopeFullAddressFormatter"
+                /></a>
+          </var:foreach>
+        </td>
+      </tr>
+      <var:if condition="hasCC">
         <tr class="mailer_fieldrow">
-          <td class="mailer_fieldname" 
-              ><var:string label:value="Spamlevel"/>:</td>
+          <td class="mailer_fieldname"><var:string label:value="CC"/>:</td>
           <td class="mailer_fieldvalue">
-            <var:string value="clientObject.mailHeaders.x-spam-level" />
-            <var:if condition="clientObject.mailHeaders.x-spam-flag"
-                    const:value="YES">
-              / <var:string label:value="marked as spam by mailserver" />
-            </var:if>
+            <var:foreach list="clientObject.ccEnvelopeAddresses" 
+              item="currentAddress">
+              <a var:href="currentAddressLink"
+                onclick="return onMenuClick(event, 'addressMenu');"
+                oncontextmenu="onMenuClick(event, 'addressMenu');"
+                onmousedown="return false;"
+                ><var:string value="currentAddress"
+                  formatter="context.mailEnvelopeFullAddressFormatter"
+                  /></a>
+              <!-- TODO: better to use li+CSS -->
+            </var:foreach>
           </td>
         </tr>
       </var:if>
-      
-      <!-- all headers
-      <tr class="mailer_fieldrow">
-        <td class="mailer_fieldname" ><var:string label:value="Header"/>:</td>
-        <td class="mailer_fieldvalue">
-           <pre><var:string value="clientObject.mailHeaders" /></pre>
-        </td>
-      </tr>
-      -->
-    </var:if>
-  </table>
- </var:if><!-- !Kolab -->
-
-  <div class="mailer_mailcontent">
-    <var:component value="contentViewerComponent"
-                   bodyInfo="clientObject.bodyStructure" />
-  </div>
+    </table>
 
-  <script language="JavaScript">
-    if (window.opener) {
-      markMailReadInWindow(window.opener, 
-        '<var:string value="clientObject.nameInContainer"/>');
-    }
-  </script>
-</var:component>
+    <div class="mailer_mailcontent"
+      oncontextmenu="onMenuClick(event, 'messageContentMenu');">
+      <var:component value="contentViewerComponent"
+        bodyInfo="clientObject.bodyStructure" />
+    </div>
+  </container>
similarity index 96%
rename from UI/Templates/UIxSieveEditor.wox
rename to UI/Templates/MailerUI/UIxSieveEditor.wox
index 56f4f5028ca622b06a974a414585400578d5c61b..138ddad1af7a7005b028e4195b16298ee940bb45 100644 (file)
@@ -6,7 +6,7 @@
   xmlns:uix="OGo:uix"
   xmlns:rsrc="OGo:url"
   xmlns:label="OGo:label"
-  className="UIxMailMainFrame"
+  className="UIxPageFrame"
   title="panelTitle"
   const:hideFolderTree="1"
 >
diff --git a/UI/Templates/MainUI/SOGoUserHomePage.wox b/UI/Templates/MainUI/SOGoUserHomePage.wox
new file mode 100644 (file)
index 0000000..a38fe69
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version='1.0' standalone='yes'?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    xmlns:uix="OGo:uix"
+    className="UIxPageFrame"
+    title="name"
+    >
+    <var:if condition="canAccess" const:negate="YES">
+      <var:string label:value="Forbidden" const:style="window_label" />
+    </var:if>
+    <var:if condition="canAccess">
+      <table id="skywintable"
+        class="wintable"
+        cellspacing="0"
+        cellpadding="5"
+        width="100%"
+        >
+        <tr>
+          <td class="window_label"><var:string label:value="Homepage"/></td>
+        </tr>
+        <tr>
+          <td class="wincontent">
+            <p class="homepagefont">
+              <var:component className="UIxCalScheduleOverview"
+                clientObject="calendarFolder"
+                />
+            </p>
+          </td>
+        </tr>
+        <tr>
+          <td class="wincontent">
+            <table border="0" width="100%" cellpadding="0" cellspacing="0">
+              <tr>
+                <td colspan="2">
+                </td>
+              </tr>
+              <tr bgcolor="#F5F5E9">
+                <td align="left" width="10">
+                  <var:entity const:name="nbsp"/>
+                </td>
+                <td align="right">
+                  <img border="0"
+                    alt=""
+                    rsrc:src="corner_right.gif"
+                    />
+                </td>
+              </tr>
+              <tr>
+                <td colspan="2" bgcolor="#F5F5E9">
+                  <table border="0" width="100%" cellpadding="10" cellspacing="0">
+                    <tr/>
+                  </table>
+                </td>
+              </tr>
+            </table>
+          </td>
+        </tr>
+      </table>
+    </var:if>
+  </var:component>
diff --git a/UI/Templates/SchedulerUI/UIxAppointmentEditor.wox b/UI/Templates/SchedulerUI/UIxAppointmentEditor.wox
new file mode 100644 (file)
index 0000000..663ae47
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version='1.0' standalone='yes'?>
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    const:popup="YES"
+    title="name"
+    var:toolbar="toolbar">
+    <script type="text/javascript" rsrc:src="skycalendar.js">
+    </script>
+
+    <form var:href="saveUrl" name="editform" onsubmit="return validateAptEditor();">
+      <var:if condition="hasErrorText">
+        <p style="background-color: #AA0000;"><var:string value="errorText"
+            /></p>
+        <hr />
+      </var:if>
+
+      <div id="editorTabs" class="tabsContainer">
+        <ul>
+          <li target="eventView"><var:string label:value="Event" /></li>
+          <li target="recurrenceView"><var:string label:value="Recurrence" /></li>
+          <li target="attendeesView"><var:string label:value="Attendees" /></li>
+        </ul>
+
+        <div id="eventView" class="tab">
+          <label><var:string label:value="Title" /><span class="content"
+              ><input type="text" name="summary" id="summary"
+                class="textField"
+                var:value="title"
+                /></span></label>
+          <label><var:string label:value="Location" /><span class="content"
+              ><input type="text" name="location" id="location"
+                class="textField"
+                var:value="location"
+                /></span></label>
+          <hr />
+          <span class="checkBoxList"><var:string label:value="From" />
+            <span class="content"><var:component className="UIxTimeDateControl"
+                const:controlID="startTime"
+                date="aptStartDate"
+                const:dayStartHour="0"
+                const:dayEndHour="23"
+                /><label><input class="checkBox"
+                  type="checkbox" var:selection="isAllDay"
+                  var:checked="isAllDay"
+                  /><var:string label:value="All Day"
+                  /></label></span></span>
+          <span class="checkBoxList"><var:string label:value="To" />
+            <span class="content"><var:component className="UIxTimeDateControl"
+                const:controlID="endTime"
+                date="aptEndDate"
+                const:dayStartHour="0"
+                const:dayEndHour="23"
+                /></span></span>
+          <hr />
+          <!-- label id="isPrivate"><input class="checkBox"
+          type="checkbox" var:selection="isPrivate"
+          var:checked="isPrivate"
+          /><var:string label:value="is private" /></label -->
+          <label><var:string label:value="Calendar" />
+            <span class="content"><var:popup list="availableCalendars" item="item"
+                const:onChange="onChangeCalendar(this);"
+                string="item" selection="componentOwner" /></span></label>
+          <label><var:string label:value="Privacy" />
+            <span class="content"><var:popup list="privacyClasses" item="item"
+                string="itemPrivacyText" selection="privacy"
+                /></span></label>
+          <label><var:string label:value="Priority" />
+            <span class="content"><var:popup list="priorities" item="item"
+                string="itemPriorityText" selection="priority"
+                /></span></label>
+          <label><var:string label:value="Status" />
+            <span class="content"><var:popup list="statusTypes" item="item"
+                string="itemStatusText" selection="status"
+                /></span></label>
+<!--          <span id="categoriesCB" class="checkBoxList"
+            ><var:string label:value="Categories"
+              /><span class="content categoriesContent"><var:checkbox-list
+                list="categoryItems"
+                item="item"
+                suffix="itemCategoryText"
+                selections="categories"
+                /></span></span> -->
+          <hr />
+          <label id="commentArea"><var:string label:value="Description"
+              /><textarea name="comment" var:value="comment" /></label> 
+          <label id="urlArea"><var:string label:value="URL" />
+            <span class="content"><input type="text" name="url" id="url"
+                size="40"
+                onkeyup="validateBrowseURL(this);"
+                class="textField"
+                var:value="url"
+                /><a id="browseUrlBtn" var:class="urlButtonClasses" var:href="#" onclick="return browseUrl(this, event);"><var:string value="Browse URL" /><var:string label:value="Browse URL" /></a
+                ></span></label>
+        </div>
+
+        <div id="recurrenceView" class="tab">
+          <label><var:string label:value="Cycle"
+              />
+            <span class="content"
+              ><var:popup list="cycles" item="item"
+                label:string="$cycleLabel"
+                selection="cycle"
+                const:onChange="toggleCycleVisibility(this, 'cycleSelectionFirstLevel', 0);"
+                /><span id="cycleSelectionFirstLevel"
+                ><var:popup list="cycleEnds" item="item"
+                  label:string="$item" value="item"
+                  selection="cycleEnd"
+                  const:onChange="toggleCycleVisibility(this, 'cycleSelectionSecondLevel', 'cycle_end_never');"
+                  const:id="cycle_end_mode_selection"
+                  /><span id="cycleSelectionSecondLevel"
+                  ><var:component className="UIxTimeDateControl"
+                    date="cycleUntilDate"
+                    label="foo"
+                    const:controlID="cycleUntilDate"
+                    const:displayTimeControl="NO"
+                    /></span
+                  ></span
+                ></span
+              ></label>
+        </div>
+
+        <div id="attendeesView" class="tab"
+          ><var:component className="UIxFreeBusyUserSelector"
+            const:selectorId="participants"
+            contacts="participants"
+            var:startDate="aptStartDate" var:endDate="aptEndDate" /></div>
+      </div>
+
+      <script type="text/javascript">
+        initTimeWidgets( { 'start': { 'hour': document.forms['editform']['startTime_time_hour'],
+                                      'minute': document.forms['editform']['startTime_time_minute'],
+                                      'date': document.forms['editform']['startTime_date'] },
+                           'end': { 'hour': document.forms['editform']['endTime_time_hour'],
+                                    'minute': document.forms['editform']['endTime_time_minute'],
+                                    'date': document.forms['editform']['endTime_date'] } } );
+        redisplayFreeBusyZone();
+      </script>
+      <!-- div id="buttons">
+      <input
+      type="submit"
+      class="button"
+      label:value="Save"
+      name="submitmeeting" />
+      <input
+      type="submit"
+      class="button"
+      label:value="Cancel"
+      name="cancel"
+      onclick="window.close(); return false;" />
+      <var:if condition="isUIxDebugEnabled">
+      <input type="submit"
+      class="button"
+      value="Test" name="test:method" />
+    </var:if>
+    </div -->
+      <input type="hidden" name="ical" var:value="iCalString" />
+      <!-- input type="hidden" id="jsaction" -->
+    </form>
+    <!--
+    <var:if condition="canEditComponent" const:negate="YES">
+    Forbidden ... <var:redirect const:setURL="view" />
+  </var:if>
+    -->
+  </var:component>
similarity index 92%
rename from UI/Templates/UIxAppointmentProposal.wox
rename to UI/Templates/SchedulerUI/UIxAppointmentProposal.wox
index 5e45c70eb2e9ecbe696b23958dd57cb0a0c0a928..8c7f0eceff8fa84dc27401c8adc7d74f5ef812b0 100644 (file)
          width="100%"
   >
     <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="window_label">
-              <var:string label:value="Search appointments" />
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose" />
-            </td>
-          </tr>
-        </table>
-      </td>
+        <td class="window_label">
+          <var:string label:value="Search appointments" />
+        </td>
     </tr>
     <tr>
       <td id="skywinbodycell" class="wincontent">
             </tr>
             <tr><td colspan="2"> </td></tr>
             <tr valign="top">
-              <td align="right" width="15%" bgcolor="#E8E8E0">
-                <span class="aptview_text">
-                  <var:string label:value="Search in Anais" />:
-                </span>
+              <td colspan="2">
+                  <var:component className="UIxContactSelector"
+                    const:selectorId="resources" />
               </td>
+<!--
               <td align="left" bgcolor="#FFFFF0">
                 <span class="aptview_text">
-<!--
                   <var:component className="AnaisAttendeeSelector"
                                  const:selectorID="resource"
                                  const:role="NON-PARTICIPANT"
                                  const:division="CC"
                                  const:withAddressBook="1"
                   />
--->
                     TODO: need attendee selector (AB)
                 </span>
               </td>
+-->
             </tr>
             <tr><td colspan="2"> </td></tr>
             <tr bgcolor="#e8e8e0">
             </tr>
             <tr><td colspan="2"> </td></tr>
             <tr valign="top">
-              <td align="right" width="15%" bgcolor="#E8E8E0">
+<!--              <td align="right" width="15%" bgcolor="#E8E8E0">
                 <span class="aptview_text">
                   <var:string label:value="Search in Anais" />:
                 </span>
+              </td> -->
+              <td colspan="2">
+                  <var:component className="UIxContactSelector"
+                    const:selectorId="participants" />
               </td>
-              <td align="left" bgcolor="#FFFFF0">
+<!--              <td align="left" bgcolor="#FFFFF0">
                 <span class="aptview_text">
                   <!-- use '1' instead of 'YES', otherwise breaks on OSX -->
-<!--
-                  <var:component className="AnaisAttendeeSelector"
+<!--                  <var:component className="AnaisAttendeeSelector"
                                  const:selectorID="participant"
                                  const:division="CC"
                                  const:withCN="1"
                                  var:cnForUser="cnForUser"
                                  const:withAddressBook="1"
                   />
--->
                     TODO: need attendee selector (AB)
                 </span>
               </td>
+-->
             </tr>
             <tr><td colspan="2"> </td></tr>
             <tr>
diff --git a/UI/Templates/SchedulerUI/UIxAppointmentView.wox b/UI/Templates/SchedulerUI/UIxAppointmentView.wox
new file mode 100644 (file)
index 0000000..3944c33
--- /dev/null
@@ -0,0 +1,299 @@
+<?xml version='1.0' standalone='yes'?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="name"
+    const:popup="YES"
+    >
+    <table cellspacing="0" cellpadding="5" width="100%">
+      <tr>
+        <td class="window_label"
+          ><var:string label:value="Appointment viewer" /></td>
+      </tr>
+
+      <tr>
+        <td>
+          <table border="0" cellpadding="2" width="100%" cellspacing="0">
+            <tr bgcolor="#e8e8e0">
+              <td align="left">
+                <span class="aptview_title"
+                  ><var:string value="startTime"
+                    formatter="dateFormatter"
+                    /></span>
+              </td>
+              <td align="right" >
+                <table border='0' cellpadding='0' cellspacing='1'>
+                  <tr>
+                    <td class="button_auto_env" nowrap="true"
+                      valign='middle' align='center'>
+                      <!--<a class="button_auto"
+                      href="printview"
+                      var:queryDictionary="queryParameters"
+                      target="SOGoPrintView"
+                      ><var:string label:value="printview" /></a>-->
+                    </td>
+                    <var:if condition="canEditApt">
+                      <td class="button_auto_env" nowrap="true"
+                        valign='middle' align='center'>
+                        <a class="button_auto"
+                          href="edit"
+                          var:queryDictionary="queryParameters"
+                          ><var:string label:value="edit" /></a>
+                      </td>
+                      <td class="button_auto_env" nowrap="true"
+                        valign='middle' align='center'>
+                        <a class="button_auto"
+                          href="delete"
+                          var:queryDictionary="queryParameters"
+                          ><var:string label:value="delete" /></a>
+                      </td>
+                    </var:if>
+                  </tr>
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td valign="top" width="100%">
+          <table width="100%" border="0" cellpadding="4" cellspacing="0">  
+            <!-- general appointment info -->
+            <var:if condition="canAccessApt">  
+              <tr valign="top">
+                <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                  <var:string label:value="Title" />:
+                </td>
+                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string value="appointment.summary" const:escapeHTML="NO" />
+                </td>
+              </tr>
+              <tr valign="top">
+                <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                  <var:string label:value="Location" />:
+                </td>
+                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string value="appointment.location" const:escapeHTML="NO" />
+                </td>
+              </tr>
+              <tr valign="top">
+                <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                  <var:string label:value="Priority" />:
+                </td>
+                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string label:value="$priorityLabelKey" />
+                </td>
+              </tr>
+            </var:if>
+            <tr valign="top">
+              <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                <var:string label:value="Classification" />:
+              </td>
+              <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                <var:if condition="appointment.isPublic">Public</var:if>
+                <var:if condition="appointment.isPublic"
+                  const:negate="YES"
+                  >Private</var:if>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td valign="top" width="100%">
+          <uix:tabview var:selection="tabSelection"
+            const:tabStyle="tab"
+            const:selectedTabStyle="tab_selected"
+            const:bodyStyle="tabview_body"
+            >
+            <uix:tab const:key="attributes"
+              label:label="attributes"
+              var:href="attributesTabLink"
+              >
+              <table width="100%" border="0" cellpadding="4" cellspacing="0">
+                <tr valign="top">
+                  <td align="right"
+                    width="15%"
+                    bgcolor="#E8E8E0"
+                    class="aptview_text"
+                    >
+                    <var:string label:value="Start time" />:
+                  </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                    <var:string value="startTime"
+                      formatter="dateFormatter"
+                      />
+                  </td>
+                </tr>
+                <tr valign="top">
+                  <td align="right"
+                    width="15%"
+                    bgcolor="#E8E8E0"
+                    class="aptview_text"
+                    >
+                    <var:string label:value="End time" />:
+                  </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                    <var:string value="endTime"
+                      formatter="dateFormatter"
+                      />
+                  </td>
+                </tr>
+                <var:if condition="canAccessApt">  
+                  <tr valign="top">
+                    <td align="right"
+                      width="15%"
+                      bgcolor="#E8E8E0"
+                      class="aptview_text"
+                      >
+                      <var:string label:value="Categories" />:
+                    </td>
+                    <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                      <var:string value="categoriesAsString"  const:escapeHTML="NO" />
+                    </td>
+                  </tr>
+                  <!-- Resources removed for v0.8
+                  <tr valign="top">
+                  <td align="right"
+                  width="15%"
+                  bgcolor="#E8E8E0"
+                  class="aptview_text"
+                  >
+                  <var:string label:value="Resources" />:
+                </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string value="resourcesAsString"
+                  const:escapeHTML="NO"
+                  />
+                </td>
+                </tr>
+                  -->
+                  <tr valign="top">
+                    <td align="right"
+                      width="15%"
+                      bgcolor="#E8E8E0"
+                      class="aptview_text"
+                      >
+                      <var:string label:value="Organizer" />:
+                    </td>
+                    <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                      <var:string value="eventOrganizer" />
+                    </td>
+                  </tr>
+                  <tr valign="top">
+                    <td align="right"
+                      width="15%"
+                      bgcolor="#E8E8E0"
+                      class="aptview_text"
+                      >
+                      <var:string label:value="Comment" />:
+                    </td>
+                    <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                      <var:string value="appointment.comment" const:insertBR="1"
+                        const:escapeHTML="NO" />
+                    </td>
+                  </tr>
+                </var:if>
+              </table>
+            </uix:tab>
+            <var:if condition="canAccessApt">    
+              
+              <uix:tab const:key="participants"
+                label:label="participants"
+                var:href="participantsTabLink"
+                >
+                <table width="100%" border="0" cellpadding="4" cellspacing="0">
+                  <tr valign="top">
+                    <td align="left" bgcolor="#E8E8E0" class="aptview_title">
+                      <var:string label:value="Name" />
+                    </td>
+                    <td align="left" bgcolor="#E8E8E0" class="aptview_title">
+                      <var:string label:value="Email" />
+                    </td>
+                    <td align="left"
+                      bgcolor="#E8E8E0"
+                      class="aptview_title"
+                      colspan="2"
+                      >
+                      <var:string label:value="Status" />
+                    </td>
+                  </tr>
+                  <var:foreach list="appointment.participants"
+                    item="attendee"
+                    >
+                    <tr valign="top">
+                      <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                        <var:string value="attendee.cnForDisplay" />
+                      </td>
+                      <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                        <a var:href="attendee.email"
+                          ><var:string value="attendee.rfc822Email" /></a>
+                      </td>
+                      <td align="left"
+                        bgcolor="#FFFFF0"
+                        class="aptview_text"
+                        var:colspan="attendeeStatusColspan"
+                        >
+                        <var:component className="UIxCalParticipationStatusView"
+                          partStat="attendee.participationStatus"
+                          />
+                      </td>
+                      <var:if condition="isAttendeeActiveUser">
+                        <td align="left"
+                          bgcolor="#FFFFF0"
+                          class="button_auto_env"
+                          >
+                          <var:if condition="showAcceptButton">  
+                            <a href="accept"
+                              class="button_auto"
+                              _tab="participants"
+                              ><var:string label:value="accept" /></a>
+                          </var:if>
+                          <var:if condition="showRejectButton">
+                            <a href="decline"
+                              class="button_auto"
+                              _tab="participants"
+                              ><var:string label:value="decline" /></a>
+                          </var:if>
+                        </td>
+                      </var:if>
+                    </tr>
+                  </var:foreach>
+                </table>
+              </uix:tab>
+            </var:if>
+            <var:if condition="isUIxDebugEnabled">
+              <uix:tab const:key="debug"
+                const:label="DEBUG"
+                var:href="debugTabLink">
+                SOGo Server - <var:string value="name"/>
+                <br />
+                Client: <var:string value="clientObject"/>
+                <br />
+                Group:      <var:string value="clientObject.group"
+                  /><br />
+                Deletable:  <var:string value="clientObject.isDeletionAllowed"
+                  /><br />
+                Generation: <var:string value="clientObject.zlGenerationCount"
+                  /><br />
+                MsgClass:   <var:string value="clientObject.outlookMessageClass"
+                  /><br />
+                
+                <hr />
+                As iCal:<br />
+                <pre><var:string value="clientObject.iCalString"/></pre>
+                
+                <hr />
+                As Mail:<br />
+                <pre><var:string value="clientObject.iCalMailString"/></pre>
+                
+              </uix:tab>
+            </var:if>
+          </uix:tabview>
+        </td>
+      </tr>
+    </table>
+  </var:component>
similarity index 87%
rename from UI/Templates/UIxAptTableView.wox
rename to UI/Templates/SchedulerUI/UIxAptTableView.wox
index e270edfc83eb9a6715e390906ba1a92548b2edbf..ca5b29dade33f1462bd9f19b988a873635beefef 100644 (file)
@@ -1,11 +1,8 @@
 <?xml version='1.0' standalone='yes'?>
 <table
-  style="font-size: 11px;"
-  border="0" cellspacing="0" cellpadding="2"
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
->
+  xmlns:const="http://www.skyrix.com/od/constant">
   <tr>
     <th>ID</th>
     <th>Title</th>
diff --git a/UI/Templates/SchedulerUI/UIxCalAptListView.wox b/UI/Templates/SchedulerUI/UIxCalAptListView.wox
new file mode 100644 (file)
index 0000000..1a73d0d
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" standalone="yes"?>
+  <table id="appointmentsList" multiselect="yes"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <tr class="tableview"
+      ><td class="tbtv_headercell tbtv_subject_headercell"
+        ><var:component className="UIxSortableTableHeader"
+          label:label="Title"
+          const:sortKey="Title"
+          const:href="aptlist"
+          var:queryDictionary="context.request.formValues"
+          /></td
+        ><td class="tbtv_headercell headerDateTime"
+        ><var:component className="UIxSortableTableHeader"
+          label:label="Start"
+          const:sortKey="Start"
+          const:href="aptlist"
+          var:queryDictionary="context.request.formValues"
+          /></td
+        ><td class="tbtv_headercell headerDateTime"
+        ><var:component className="UIxSortableTableHeader"
+          label:label="End"
+          const:sortKey="End"
+          const:href="aptlist"
+          var:queryDictionary="context.request.formValues"
+          /></td
+        ><td class="tbtv_headercell headerLocation"
+        ><var:component className="UIxSortableTableHeader"
+          label:label="Location"
+          const:sortKey="Location"
+          const:href="aptlist"
+          var:queryDictionary="context.request.formValues"
+          /></td
+        ></tr>
+
+    <var:foreach list="fetchCoreAppointmentsInfos" item="currentAppointment"
+      ><tr class="tableview appointmentRow"
+        var:id="currentAppointment.c_name"
+        var:owner="currentAppointment.owner"
+        onclick="return onAppointmentClick(event);"
+        ondblclick="return editDoubleClickedEvent(this);"
+        oncontextmenu="return onAppointmentContextMenu(event, this);"
+        var:day="currentSerialDay"
+        var:hour="currentSerialHour"
+        ><td onmousedown="return false;"
+          class="subjectCell"
+          ><var:string value="currentAppointment.title"
+            const:escapeHTML="NO"
+            /></td
+          ><td onmousedown="return false;"
+          ><var:string value="currentStartTime"/></td
+          ><td onmousedown="return false;"
+          ><var:string value="currentEndTime"/></td
+          ><td onmousedown="return false;"
+          ><var:string value="currentLocation" /></td
+          ></tr
+        ></var:foreach>
+  </table>
similarity index 96%
rename from Misc/ZideStore/UI-X/Scheduler/UIxCalBackForthNavView.wox
rename to UI/Templates/SchedulerUI/UIxCalBackForthNavView.wox
index 7c86e8c26cd3401f2757c8a097b3cde64ee32f81..d8bc6558f1a7cf512ed86e65198517767aceed4d 100644 (file)
             <a var:href="^methodName" var:queryDictionary="^prevQueryParameters"><img rsrc:src="previous_week.gif" alt="previous" border="0"/></a>
         </td>
         <td align="right" valign="middle" class="button_auto_env">
-            <a var:href="^methodName" var:queryDictionary="^currentQueryParameters" class="button_auto"><var:string value="^label" escapeHTML="NO" /></a>
+            <a var:href="^methodName" var:queryDictionary="^currentQueryParameters" class="button_auto"><var:string value="^label" /></a>
         </td>
         <td align="right" valign="middle">
             <a var:href="^methodName" var:queryDictionary="^nextQueryParameters"><img rsrc:src="next_week.gif" alt="next" border="0"/></a>
         </td>
     </tr>
-</table>
\ No newline at end of file
+</table>
diff --git a/UI/Templates/SchedulerUI/UIxCalCalendarsListView.wox b/UI/Templates/SchedulerUI/UIxCalCalendarsListView.wox
new file mode 100644 (file)
index 0000000..52f01c7
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" standalone="yes"?>
+  <container
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <style type="text/css">
+      <var:foreach list="contacts" item="currentContactPerson">
+      .ownerIs<var:string value="currentContactLogin" />
+      {
+        background-color: <var:string value="currentContactSpanBG" /> !important;
+      }
+      DIV[class~='appointment'].ownerIs<var:string value="currentContactLogin" />
+      {
+        background-color: <var:string value="currentContactAptBorder" /> !important;
+      }
+      </var:foreach>
+    </style>
+    <var:component className="UIxContactSelector"
+      const:selectorId="calendarsList"
+      const:hasCheckBoxes="YES"
+      colors="colors"
+      contacts="contacts"
+      checkedBoxes="checkedContacts"
+      />
+  </container>
diff --git a/UI/Templates/SchedulerUI/UIxCalDateLabel.wox b/UI/Templates/SchedulerUI/UIxCalDateLabel.wox
new file mode 100644 (file)
index 0000000..565f093
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version='1.0' standalone='yes'?>
+  <span xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:lbl="OGo:label"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    const:class="window_label"
+    ><var:string value="label" /></span>
diff --git a/UI/Templates/SchedulerUI/UIxCalDateSelector.wox b/UI/Templates/SchedulerUI/UIxCalDateSelector.wox
new file mode 100644 (file)
index 0000000..cff93ce
--- /dev/null
@@ -0,0 +1,58 @@
+<?xml version='1.0' standalone='yes'?>
+  <div xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    id="dateSelector">
+    <div class="header">
+      <a href="#"
+        id="rightArrow"
+        var:date="nextMonthAsString"
+        onclick="return onDateSelectorGotoMonth(this);"
+        ><img id="next" rsrc:src="arrow-rit-sharp.gif"
+          /></a>
+      <a href="#"
+        id="leftArrow"
+        var:date="prevMonthAsString"
+        onclick="return onDateSelectorGotoMonth(this);"
+        ><img id="previous" rsrc:src="arrow-lft-sharp.gif" />
+      </a><span id="monthLabel"
+        onmousedown="return false;"
+        var:month="headerMonthValue"
+        onclick="popupMonthMenu(event, 'monthListMenu');"
+        ><var:string value="headerMonthString"
+          /></span><span id="yearLabel"
+        onmousedown="return false;"
+        onclick="popupMonthMenu(event, 'yearListMenu');"
+        ><var:string value="headerYearString"
+          /></span>
+    </div>
+
+    <var:month-overview
+      const:id="dateSelectorTable"
+      currentDay="currentDay"
+      index="dayIndex"
+      year="year"
+      month="month"
+      var:timeZone="viewTimeZone"
+      const:startDateKey="startDate"
+      const:endDateKey="endDate"
+      ><var:month-label
+        const:orientation="top"
+        dayOfWeek="dayOfWeek"
+        class="dayHeaderStyle"
+        ><span class="dayOfWeek"
+          ><var:string value="localizedDayOfWeekName"
+            /></span
+          ></var:month-label>
+      <var:month-title class="contentStyle"
+        ><span var:class="extraStyle"
+          ><a href="#"
+            onclick="return onDaySelect(this);"
+            var:day="currentDay.shortDateString"
+            ><var:string value="currentDay.dayOfMonth"/></a
+            ></span
+          ></var:month-title
+        ></var:month-overview>
+  </div>
similarity index 94%
rename from UI/Templates/UIxCalDayChartview.wox
rename to UI/Templates/SchedulerUI/UIxCalDayChartview.wox
index a6f0a21b2fa23c48a1bfafa3ad75f4acca3efa10..adc8e5f32e459dcf4a584900a2f123947b645e16 100644 (file)
@@ -7,6 +7,7 @@
                className="UIxPageFrame"
                title="name"
 >
+
   <table id="skywintable"
          class="wintable"
          cellspacing="0"
          width="100%"
   >
     <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle">
-              <var:component className="UIxCalDateLabel"
-                             startDate="startDate"
-                             endDate="endDate"
-                             const:selection="day"
-              />
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose"/>
-            </td>
-          </tr>
-        </table>
-      </td>
+        <td class="window_label">
+          <var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="day"
+            />
+        </td>
     </tr>
     <tr>
       <td id="skywinbodycell" class="wincontent">
@@ -45,8 +36,9 @@
                              label:label="today"
               />
             </td>
-            <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector" />
+              <td align="right" valign="middle" width="80%">
+                <var:component className="UIxContactSelector"
+                  const:selectorId="uids" />
             </td>
           </tr>
         </table>
                                             const:dateformat="%H:%M"
                                 />
                                 [<a href="new"
+                                    onclick="return newEvent(this);"
+                                    var:day="currentDayQueryParameters.day"
                                     var:queryDictionary="currentDateQueryParameters"
                                  ><var:string label:value="new" /></a>]
                               </span>
similarity index 93%
rename from UI/Templates/UIxCalDayListview.wox
rename to UI/Templates/SchedulerUI/UIxCalDayListview.wox
index 1111be3ed963b2dc6435b307054882bcf6852a1c..0b2a4106420a33c0ffdf2f20c2805c6a320ff17d 100644 (file)
@@ -7,6 +7,7 @@
                className="UIxPageFrame"
                title="name"
 >
+
   <table id="skywintable"
          class="wintable"
          cellspacing="0"
          width="100%"
   >
     <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle">
-              <var:component className="UIxCalDateLabel"
-                             startDate="startDate"
-                             endDate="endDate"
-                             const:selection="day"
-              />
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose"/>
-            </td>
-          </tr>
-        </table>
-      </td>
+        <td class="window_label">
+          <var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="day"
+            />
+        </td>
     </tr>
     <tr>
       <td id="skywinbodycell" class="wincontent">
@@ -46,7 +37,8 @@
               />
             </td>
             <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector" />
+                <var:component className="UIxContactSelector"
+                  const:selectorId="uids" />
             </td>
           </tr>
         </table>
                                             const:dateformat="%H:%M"
                                 /><br />
                                 [<a href="new"
+                                    onclick="return newEvent(this);"
+                                    var:day="currentDayQueryParameters.day"
                                     var:queryDictionary="currentDateQueryParameters"
                                  ><var:string label:value="new" /></a>]
                               </span>
similarity index 93%
rename from UI/Templates/UIxCalDayOverview.wox
rename to UI/Templates/SchedulerUI/UIxCalDayOverview.wox
index 1ab5ea6255be0007d4dba1be5a857a832d9133c4..f528c559aad419b1c1338272f7160a6a15aab13f 100644 (file)
@@ -7,25 +7,16 @@
                className="UIxPageFrame"
                title="name"
 >
+
   <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
     <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle">
-              <var:component className="UIxCalDateLabel"
-                             startDate="startDate"
-                             endDate="endDate"
-                             const:selection="day"
-              />
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose"/>
-            </td>
-          </tr>
-        </table>
-      </td>
+        <td class="window_label">
+          <var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="day"
+            />
+        </td>
     </tr>
     <tr>
       <td id="skywinbodycell" class="wincontent">
@@ -41,7 +32,8 @@
               />
             </td>
             <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector" />
+                <var:component className="UIxContactSelector"
+                  const:selectorId="uids" />
             </td>
           </tr>
         </table>
         <table border="0" width="100%" cellpadding="0" cellspacing="0">
           <tr>
             <td colspan="2">
-              <var:component className="UIxCalSelectTab"
-                             const:selection="day"
-                             currentDate="selectedDate"
-              >
+    <var:component className="UIxCalSelectTab"
+      const:selection="day"
+      currentDate="selectedDate"
+      >
+
                 <table border="0" cellpadding="4" width="100%" cellspacing="2">
                   <tr>
                     <td width="1%" align="left" valign="middle" bgcolor="#e8e8e0">
                               <br />
                               <span class="dayoverview_content_time_link">
                                 [<a href="new"
+                                    onclick="return newEvent(this);"
+                                    var:day="currentDayQueryParameters.day"
                                     var:queryDictionary="currentDateQueryParameters"
                                  ><var:string label:value="new" /></a>]
                               </span>
diff --git a/UI/Templates/SchedulerUI/UIxCalDayTable.wox b/UI/Templates/SchedulerUI/UIxCalDayTable.wox
new file mode 100644 (file)
index 0000000..42022b7
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" standalone="yes"?>
+  <container
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <div id="daysView" var:class="daysViewClasses">
+      <div class="hours">
+        <var:foreach list="hoursToDisplay" item="currentTableHour"
+          ><div class="hour"><var:string value="currentTableHour" />:00</div
+            ></var:foreach>
+      </div>
+
+      <div class="hourLines">
+        <div class="hourLine hourLine0"><!-- space --></div
+          ><div class="hourLine hourLine1"><!-- space --></div
+          ><div class="hourLine hourLine2"><!-- space --></div
+          ><div class="hourLine hourLine3"><!-- space --></div
+          ><div class="hourLine hourLine4"><!-- space --></div
+          ><div class="hourLine hourLine5"><!-- space --></div
+          ><div class="hourLine hourLine6"><!-- space --></div
+          ><div class="hourLine hourLine7"><!-- space --></div
+          ><div class="hourLine hourLine8"><!-- space --></div
+          ><div class="hourLine hourLine9"><!-- space --></div
+          ><div class="hourLine hourLine10"><!-- space --></div
+          ><div class="hourLine hourLine11"><!-- space --></div
+          ><div class="hourLine hourLine12"><!-- space --></div
+          ><div class="hourLine hourLine13"><!-- space --></div
+          ><div class="hourLine hourLine14"><!-- space --></div
+          ><div class="hourLine hourLine15"><!-- space --></div
+          ><div class="hourLine hourLine16"><!-- space --></div
+          ><div class="hourLine hourLine17"><!-- space --></div
+          ><div class="hourLine hourLine18"><!-- space --></div
+          ><div class="hourLine hourLine19"><!-- space --></div
+          ><div class="hourLine hourLine20"><!-- space --></div
+          ><div class="hourLine hourLine21"><!-- space --></div
+          ><div class="hourLine hourLine22"><!-- space --></div
+          ><div class="hourLine hourLine23"><!-- space --></div>
+      </div>
+
+      <div class="days">
+        <var:foreach list="daysToDisplay" item="currentTableDay"
+          ><div var:class="dayClasses"
+            var:day="currentTableDay.shortDateString"
+            ><div class="header"><var:string value="labelForDay" /></div>
+            <div class="appointments">
+            <var:foreach list="hoursToDisplay" item="currentTableHour"
+              ><div var:class="clickableHourCellClass"
+                var:day="currentTableDay.shortDateString"
+                var:hour="currentAppointmentHour">
+              </div></var:foreach>
+            <var:foreach list="appointmentsForCurrentDay" item="currentAppointment"
+              ><var:component className="UIxCalInlineAptView"
+                dayStartHour="dayStartHour"
+                dayEndHour="dayEndHour"
+                appointment="currentAppointment"
+                formatter="aptFormatter"
+                tooltipFormatter="aptTooltipFormatter"
+                url="appointmentViewURL"
+                const:style="dayoverview"
+                queryDictionary="currentDateQueryParameters"
+                referenceDate="selectedDate"
+                canAccess="canAccessApt"
+                /></var:foreach
+              >
+            </div>
+          </div>
+        </var:foreach>
+      </div>
+    </div>
+  </container>
diff --git a/UI/Templates/SchedulerUI/UIxCalDayView.wox b/UI/Templates/SchedulerUI/UIxCalDayView.wox
new file mode 100644 (file)
index 0000000..821d803
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" standalone="yes"?>
+  <container
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <a href="#"
+      class="leftNavigationArrow"
+      var:date="prevDayQueryParameters.day"
+      onclick="return onCalendarGotoDay(this);"
+      ><img rsrc:src="arrow-lft-sharp.gif"/></a>
+    <span class="daysHeader">
+      <span class="day2"><a href="#"
+          var:date="dayBeforePrevDayQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="dayBeforeYesterdayName"
+            /></a></span
+        ><span class="day1"><a href="#"
+          var:date="prevDayQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="yesterdayName"
+            /></a></span
+        ><span class="day0"><var:string value="currentDayName" /></span
+        ><span class="day1"><a href="#"
+          var:date="nextDayQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="tomorrowName"
+            /></a></span
+        ><span class="day2"><a href="#"
+          var:date="dayAfterNextDayQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="dayAfterTomorrowName"
+            /></a></span
+        ></span>
+    <a href="#"
+      class="rightNavigationArrow"
+      var:date="nextDayQueryParameters.day"
+      onclick="return onCalendarGotoDay(this);"
+      ><img rsrc:src="arrow-rit-sharp.gif"/></a>
+
+    <div id="calendarContent">
+      <var:component
+        className="UIxCalDayTable"
+        startDate="startDate"
+        const:CSSClass="dayOverview"
+        const:numberOfDays="1" />
+    </div>
+  </container>
diff --git a/UI/Templates/SchedulerUI/UIxCalFilterPanel.wox b/UI/Templates/SchedulerUI/UIxCalFilterPanel.wox
new file mode 100644 (file)
index 0000000..b1bd4da
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version='1.0' standalone='yes'?>
+  <container 
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:label="OGo:label"
+    >
+    <div class="menu" id="searchMenu">
+      <ul id="searchOptions">
+        <li id="name_or_address"
+          onmousedown="return false;"
+          onmouseup="setSearchCriteria(event);"><var:string label:value="Title or Description"/></li>
+      </ul>
+    </div>
+
+    <div id="filterPanel">
+      <span class="searchBox" style="float: right">
+        <input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" />
+        <input id="searchValue"
+          class="textField"
+          autocomplete="off" name="search" type="text" var:value="searchText"
+          onmousedown="onSearchMouseDown(event, this);"
+          onclick="popupSearchMenu(event, 'searchMenu');"
+          onchange="onSearchChange();"
+          onblur="onSearchBlur(this);"
+          onfocus="onSearchFocus(this);"
+          onkeydown="onSearchKeyDown(this);" />
+      </span>
+
+      <var:string label:value="View:" />
+      <var:popup list="filters"
+        const:id="filterpopup"
+        item="filter" string="filterLabel" value="filter"
+        selection="selectedFilter"
+        const:name="filterpopup" 
+        const:onchange="return onListFilterChange();" />
+    </div>
+  </container>
diff --git a/UI/Templates/SchedulerUI/UIxCalInlineAptView.wox b/UI/Templates/SchedulerUI/UIxCalInlineAptView.wox
new file mode 100644 (file)
index 0000000..cfe188f
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version='1.0' standalone='yes'?>
+  <div
+    var:class="displayClasses"
+    var:aptCName="appointment.c_name"
+    var:owner="appointment.owner"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url">
+    <div var:class="innerDisplayClasses">
+      <var:string value="appointment.title" const:escapeHTML="NO" />
+    </div>
+  </div>
diff --git a/UI/Templates/SchedulerUI/UIxCalMainView.wox b/UI/Templates/SchedulerUI/UIxCalMainView.wox
new file mode 100644 (file)
index 0000000..9a904ec
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="title"
+    popup="isPopup"
+    >
+    <div class="menu" id="monthListMenu">
+      <ul>
+        <var:foreach list="monthMenuItems" item="monthMenuItem"
+          ><li
+            onmousedown="return false;"
+            onclick="return onMonthMenuItemClick(this);"
+            var:month="monthMenuItem"
+            ><var:string value="monthMenuItemLabel" /></li>
+        </var:foreach
+          ></ul>
+    </div>
+    
+    <div class="menu" id="yearListMenu">
+      <ul>
+        <var:foreach list="yearMenuItems" item="yearMenuItem"
+          ><li
+            onmousedown="return false;"
+            onclick="return onYearMenuItemClick(this);"
+            ><var:string value="yearMenuItem" /></li>
+        </var:foreach
+        ></ul>
+    </div>
+
+    <div class="menu" id="appointmentsListMenu">
+      <ul>
+        <li onmouseup="newEvent(this, 'event');"><var:string label:value="New Event..."/></li>
+        <li class="separator"></li>
+        <li onmouseup="newEvent(this, 'task');"><var:string label:value="New Task..."/></li>
+        <li onmouseup="editEvent();"><var:string label:value="Edit Selected Event..."/></li>
+        <li onmouseup="deleteEvent();"><var:string label:value="Delete Selected Event"/></li>
+        <li class="separator"></li>
+        <li onmouseup="onSelectAll();"><var:string label:value="Select All"/></li>
+        <li class="separator"></li>
+        <li onmouseup="onToggleWorkweekDaysOnly();"><var:string label:value="Workweek days only" /></li>
+        <li onmouseup="onToggleTasksInView();"><var:string label:value="Tasks in View"/></li>
+      </ul>
+    </div>
+
+    <div class="menu" id="calendarsMenu">
+      <ul>
+        <li id="newCalendarMenuEntry"><var:string label:value="New Calendar..."/></li>
+        <li id="deleteCalendarMenuEntry"><var:string label:value="Delete Calendar"/></li>
+        <li id="accessRightsMenuEntry"><var:string label:value="Access Rights..." /></li>
+        <li class="separator"></li>
+        <li id="exportCalendarMenuEntry"><var:string label:value="Export Calendar..."/></li>
+        <li id="publishCalendarMenuEntry"><var:string label:value="Publish Calendar..."/></li>
+        <li class="separator"></li>
+        <li id="publishCalendarMenuEntry"><var:string label:value="Reload Remote Calendars"/></li>
+        <li class="separator"></li>
+        <li id="calendarPropertiesMenuEntry"><var:string label:value="Properties"/></li>
+      </ul>
+    </div>
+
+    <div id="leftPanel">
+      <div class="tabsContainer" id="schedulerTabs">
+        <ul>
+          <li target="dateSelectorView"><var:string label:value="Date" /></li>
+          <li target="calendarSelectorView"><var:string label:value="Calendars" /></li>
+        </ul>
+
+        <div id="dateSelectorView"
+          class="tab"
+          ><var:component className="UIxCalDateSelector"
+            selectedDate="thisMonth"
+            /></div>
+        <div id="calendarSelectorView"
+          class="tab"
+          ><var:component className="UIxCalCalendarsListView"
+            /></div>
+      </div>
+
+      <div id="tasksListView"
+        ><var:component className="UIxCalTasksListView"
+          /></div>
+    </div>
+
+    <div id="verticalDragHandle" class="dragHandle"><!-- space --></div>
+
+    <div id="rightPanel">
+      <var:component className="UIxCalFilterPanel" />
+      <div id="appointmentsListView"
+        oncontextmenu="return onAppointmentContextMenu(event, this);"
+        ><var:component className="UIxCalAptListView"
+          /></div>
+      <div id="rightDragHandle" class="dragHandle"><!-- space --></div>
+      <div id="calendarView"><!-- space --></div>
+    </div>
+  </var:component>
similarity index 91%
rename from UI/Templates/UIxCalMonthOverview.wox
rename to UI/Templates/SchedulerUI/UIxCalMonthOverview.wox
index d591e09d50d4268caabae8af7bb2d52ac52aceeb..795e5f79dbfc24e590aca4892c7fbcddd5ca3ae8 100644 (file)
@@ -7,30 +7,21 @@
                className="UIxPageFrame"
                title="name"
 >
-  <table id="skywintable"
-         class="wintable"
-         cellspacing="0"
-         cellpadding="5"
-         width="100%"
-  >
-    <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle">
-              <var:component className="UIxCalDateLabel"
-                             startDate="startDate"
-                             endDate="endDate"
-                             const:selection="month"
-              />
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose"/>
-            </td>
-          </tr>
-        </table>
-      </td>
+
+    <table id="skywintable"
+      class="wintable"
+      cellspacing="0"
+      cellpadding="5"
+      width="100%"
+      >
+      <tr>
+        <td class="window_label">
+          <var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="month"
+            />
+        </td>
     </tr>
     <tr>
       <td id="skywinbodycell" class="wincontent">
               />
             </td>
             <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector"
+                <var:component className="UIxContactSelector"
+                  const:selectorId="uids" />
+<!--              <var:component className="AnaisUidSelector"
                              calendarUIDs="clientObject.calendarUIDs"
-              />
+              /> -->
             </td>
           </tr>
         </table>
diff --git a/UI/Templates/SchedulerUI/UIxCalMonthView.wox b/UI/Templates/SchedulerUI/UIxCalMonthView.wox
new file mode 100644 (file)
index 0000000..4d6578b
--- /dev/null
@@ -0,0 +1,107 @@
+<?xml version="1.0" standalone="yes"?>
+  <container
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <a href="#"
+      class="leftNavigationArrow"
+      var:date="prevMonthQueryParameters.day"
+      onclick="return onCalendarGotoDay(this);"
+      ><img rsrc:src="arrow-lft-sharp.gif"/></a>
+    <span class="monthsHeader">
+      <span class="month2"><a href="#"
+          var:date="monthBeforePrevMonthQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="monthNameOfTwoMonthAgo"
+            /></a></span
+        ><span class="month1"><a href="#"
+          var:date="prevMonthQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="monthNameOfOneMonthAgo"
+            /></a></span
+        ><span class="month0"><var:string value="monthNameOfThisMonth" /></span
+        ><span class="month1"><a href="#"
+          var:date="nextMonthQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="monthNameOfNextMonth"
+            /></a></span
+        ><span class="month2"><a href="#"
+          var:date="monthAfterNextMonthQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="monthNameOfTheMonthAfterNextMonth"
+            /></a></span
+        ></span>
+    <a href="#"
+      class="rightNavigationArrow"
+      var:date="nextMonthQueryParameters.day"
+      onclick="return onCalendarGotoDay(this);"
+      ><img rsrc:src="arrow-rit-sharp.gif"/></a>
+
+    <div id="calendarContent">
+      <table class="monthOverview">
+        <tr>
+          <var:foreach list="daysToDisplay" item="currentTableDay"
+            ><td class="header"><var:string value="labelForCurrentDayToDisplay"
+                /></td></var:foreach>
+        </tr>
+
+        <var:if condition="hasHolidayInfo">
+          <tr>
+            <td class="hourOfDay" colspan="2">
+              <b><var:string value="holidayInfo.title" /></b>
+            </td>
+          </tr>
+        </var:if>
+
+<!--        <var:foreach list="allDayApts" item="appointment">
+          <tr>
+            <td class="hourOfDay">
+              <var:entity name="nbsp" />
+            </td>
+            <td class="day" width="90%">
+              <var:foreach list="allDayApts" item="appointment">
+                <var:component className="UIxCalInlineAptView"
+                  appointment="appointment"
+                  formatter="aptFormatter"
+                  tooltipFormatter="aptTooltipFormatter"
+                  url="appointmentViewURL"
+                  const:style="dayoverview"
+                  queryDictionary="currentDateQueryParameters"
+                  referenceDate="selectedDate"
+                  canAccess="canAccessApt"
+                  />
+              </var:foreach>
+            </td>
+          </tr>
+        </var:foreach> -->
+
+        <var:foreach list="rangesOf7Days" item="currentRangeOf7Days">
+          <tr>
+            <var:foreach list="currentRangeOf7Days" item="currentTableDay"
+              ><td var:class="dayCellClasses"
+                var:day="currentTableDay.shortDateString"
+                const:hour="0800"
+                ><div class="dayContent"><span class="dayCellLabel"
+                  ><var:string value="labelForCurrentDayCell" /></span
+                  ><br /><var:foreach
+                  list="aptsForCurrentDate"
+                  item="appointment"
+                  ><var:component className="UIxCalInlineAptView"
+                    appointment="appointment"
+                    formatter="monthAptFormatter"
+                    tooltipFormatter="aptTooltipFormatter"
+                    url="appointmentViewURL"
+                    const:style="dayoverview"
+                    queryDictionary="currentDayQueryParameters"
+                    referenceDate="currentTableDay"
+                    canAccess="canAccessApt"
+                    />
+                </var:foreach></div></td>
+            </var:foreach>
+          </tr>
+        </var:foreach>
+      </table>
+    </div>
+  </container>
diff --git a/UI/Templates/SchedulerUI/UIxCalTasksListView.wox b/UI/Templates/SchedulerUI/UIxCalTasksListView.wox
new file mode 100644 (file)
index 0000000..37853c9
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" standalone="yes"?>
+  <container
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <h2><var:string label:value="Tasks" /></h2>
+    <label><input class="checkBox"
+        var:checked="shouldHideCompletedTasks"
+        type="checkbox"
+        onclick="return onHideCompletedTasks(this);"
+        /><var:string label:value="Hide completed tasks"
+        /></label>
+    <ul id="tasksList" multiselect="yes">
+      <var:foreach list="fetchCoreTasksInfos" item="currentTask"
+        ><var:if condition="shouldDisplayCurrentTask"
+          ><li var:id="currentTask.c_name"
+            var:owner="currentTask.owner"
+            var:class="currentStatusClass"
+            onmousedown="return false;"
+            onclick="return onRowClick(event);"
+            ondblclick="return editDoubleClickedEvent(this);"
+            ><input class="checkBox"
+              var:checked="isCurrentTaskCompleted"
+              type="checkbox"
+              onchange="return updateTaskStatus(this);"
+              /><var:string value="currentTask.title" const:escapeHTML="NO"
+                /></li></var:if>
+      </var:foreach>
+    </ul>
+  </container>
diff --git a/UI/Templates/SchedulerUI/UIxCalWeekChartview.wox b/UI/Templates/SchedulerUI/UIxCalWeekChartview.wox
new file mode 100644 (file)
index 0000000..0004f14
--- /dev/null
@@ -0,0 +1,232 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    xmlns:uix="OGo:uix"
+    className="UIxPageFrame"
+    title="name">
+
+    <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
+      <tr>
+        <td class="window_label"><var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="week"
+            /></td>
+      </tr>
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" cellpadding="0" cellspacing="0" width="100%">
+            <tr bgcolor="#e8e8e0">
+              <td align="left">
+                <var:component className="UIxCalBackForthNavView"
+                  methodName="ownMethodName"
+                  prevQueryParameters="prevWeekQueryParameters"
+                  currentQueryParameters="todayQueryParameters"
+                  nextQueryParameters="nextWeekQueryParameters"
+                  label:label="this week"
+                  />
+              </td>
+              <td align="right" valign="middle" width="80%">
+                <var:component className="UIxContactSelector"
+                  const:selectorId="uids" />
+                <!--              <var:component className="AnaisUidSelector"
+                calendarUIDs="clientObject.calendarUIDs"
+                /> -->
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" width="100%" cellpadding="0" cellspacing="0">
+            <tr>
+              <td colspan="2">
+                <var:component className="UIxCalSelectTab"
+                  const:selection="week"
+                  currentDate="selectedDate"
+                  >
+                  <table border="0" cellpadding="4" width="100%" cellspacing="2">
+                    <tr>
+                      <td width="1%" align="left" valign="middle" bgcolor="#e8e8e0">
+                        <table border='0' cellpadding='0' cellspacing='0'>
+                          <tr>
+                            <td><a href="weekoverview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_overview.gif"
+                                  label:title="Overview"
+                                  label:alt="Overview"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                            <td><img rsrc:src="icon_view_chart_inactive.gif"
+                                label:title="Chart"
+                                label:alt="Chart"
+                                border="0"
+                                valign="top"
+                                /></td>
+                            <td><a href="weeklistview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_list.gif"
+                                  label:title="List"
+                                  label:alt="List"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                            <td>
+                              <a href="weekcolumnsview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_columns.gif"
+                                  label:title="Columns"
+                                  label:alt="Columns"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                          </tr>
+                        </table>
+                      </td>
+                      <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
+                        <a var:href="ownMethodName"
+                          class="button_auto"
+                          var:queryDictionary="toggleShowRejectedAptsQueryParameters"
+                          label:string="$toggleShowRejectedAptsLabel"
+                          />
+                      </td>
+                      <td align="right" bgcolor="#e8e8e0">
+                        <table border='0' cellpadding='0' cellspacing='1'>
+                          <tr>
+                            <td class="button_auto_env"
+                              nowrap="true"
+                              valign='middle'
+                              align='center'
+                              >
+                              <!--<a class="button_auto"
+                              href="weekprintview"
+                              var:queryDictionary="queryParameters"
+                              target="SOGoPrintView"
+                              ><var:string label:value="printview" /></a>-->
+                            </td>
+                            <td class="button_auto_env"
+                              nowrap="true"
+                              valign='middle'
+                              align='center'
+                              >
+                              <a class="button_auto"
+                                href="proposal"
+                                var:queryDictionary="queryParameters"
+                                ><var:string label:value="proposal" /></a>
+                            </td>
+                          </tr>
+                        </table>
+                      </td>
+                    </tr>
+                  </table>
+                  <var:vspan-matrix list="appointments"
+                    item="appointment"
+                    rows="hours"
+                    row="hour"
+                    columns="columns"
+                    column="day"
+                    itemActive="isItemActive"
+                    isRowActive="isRowActive"
+                    const:rowHeight="8"
+                    const:width="100%"
+                    const:border="0"
+                    const:cellpadding="0"
+                    const:cellspacing="2"
+                    >
+                    <var:matrix-label const:elementName="td"
+                      const:position="top"
+                      const:align="center"
+                      >
+                      <table cellpadding="5"
+                        cellspacing="0"
+                        width="100%"
+                        border="0"
+                        var:class="titleStyle"
+                        >
+                        <tr>
+                          <td align="left" valign="top">
+                            <a href="daychartview"
+                              var:queryDictionary="currentDayQueryParameters"
+                              class="weekoverview_title_daylink"
+                              ><var:string value="currentDay.dayOfMonth"
+                                const:numberformat="02"
+                                /></a>
+                          </td>
+                          <td align="center" valign="top" width="97%">
+                            <var:string value="currentDayName" /><br />
+                            [<a href="new"
+                              onclick="return newEvent(this);"
+                              var:day="currentDayQueryParameters.day"
+                              var:queryDictionary="currentDayQueryParameters"
+                              class="weekoverview_title_newlink"
+                              ><var:string label:value="new" /></a>]
+                          </td>
+                        </tr>
+                      </table>
+                    </var:matrix-label>
+                    
+                    <var:matrix-label const:elementName="td"
+                      const:position="left"
+                      const:width="2"
+                      const:height="20"
+                      const:bgcolor="#d6d6ce"
+                      >
+                      <span class="dayoverview_content_time_link">
+                        <var:string value="currentDate"
+                          const:dateformat="%H:%M"
+                          />
+                      </span>
+                    </var:matrix-label>
+                    <!-- TODO: use css instead! -->
+                    <var:matrix-empty const:elementName="td"
+                      const:bgcolor="#efefe7"
+                      ><var:entity const:name="nbsp"
+                        />
+                    </var:matrix-empty>
+                    <!-- TODO: use css instead! -->
+                    <var:matrix-cell const:elementName="td"
+                      const:bgcolor="#d6d6ce"
+                      const:align="top"
+                      >
+                      <span class="dayoverview_content_time_link">
+                        <var:component className="UIxCalInlineAptView"
+                          appointment="appointment"
+                          formatter="aptFormatter"
+                          tooltipFormatter="aptTooltipFormatter"
+                          url="appointmentViewURL"
+                          style="aptStyle"
+                          queryDictionary="currentDayQueryParameters"
+                          referenceDate="currentDay"
+                          canAccess="canAccessApt"
+                          />
+                      </span>
+                    </var:matrix-cell>
+                  </var:vspan-matrix>
+                </var:component>
+              </td>
+            </tr>
+            <tr bgcolor="#F5F5E9">
+              <td align="left" width="10"><var:entity const:name="nbsp"/></td>
+              <td align="right"
+                ><img border="0"
+                  alt=""
+                  rsrc:src="corner_right.gif"
+                  /></td>
+            </tr>
+            <tr>
+              <td colspan="2" bgcolor="#F5F5E9">
+                <table border="0" width="100%" cellpadding="10" cellspacing="0">
+                  <tr />
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+    </table>
+  </var:component>
diff --git a/UI/Templates/SchedulerUI/UIxCalWeekColumnsview.wox b/UI/Templates/SchedulerUI/UIxCalWeekColumnsview.wox
new file mode 100644 (file)
index 0000000..fd168ef
--- /dev/null
@@ -0,0 +1,279 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    xmlns:uix="OGo:uix"
+    className="UIxPageFrame"
+    title="name">
+
+    <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
+      <tr>
+        <td class="window_label"><var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="week"
+            /></td>
+      </tr>
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" cellpadding="0" cellspacing="0" width="100%">
+            <tr bgcolor="#e8e8e0">
+              <td align="left">
+                <var:component className="UIxCalBackForthNavView"
+                  methodName="ownMethodName"
+                  prevQueryParameters="prevWeekQueryParameters"
+                  currentQueryParameters="todayQueryParameters"
+                  nextQueryParameters="nextWeekQueryParameters"
+                  label:label="this week"
+                  />
+              </td>
+              <td align="right" valign="middle" width="80%">
+                <var:component className="UIxContactSelector"
+                  const:selectorId="uids" />
+                <!--              <var:component className="AnaisUidSelector"
+                calendarUIDs="clientObject.calendarUIDs"
+                /> -->
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" width="100%" cellpadding="0" cellspacing="0">
+            <tr>
+              <td colspan="2">
+                <var:component className="UIxCalSelectTab"
+                  const:selection="week"
+                  currentDate="selectedDate"
+                  >
+                  <table border="0" cellpadding="4" width="100%" cellspacing="2">
+                    <tr>
+                      <td width="1%"
+                        align="left"
+                        valign="middle"
+                        bgcolor="#e8e8e0"
+                        >
+                        <table border='0' cellpadding='0' cellspacing='0'>
+                          <tr>
+                            <td><a href="weekoverview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_overview.gif"
+                                  label:title="Overview"
+                                  label:alt="Overview"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                            <td><a href="weekchartview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_chart.gif"
+                                  label:title="Chart"
+                                  label:alt="Chart"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                            <td><a href="weeklistview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_list.gif"
+                                  label:title="List"
+                                  label:alt="List"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                            <td><img rsrc:src="icon_view_columns_inactive.gif"
+                                label:title="Columns"
+                                label:alt="Columns"
+                                border="0"
+                                valign="top"
+                                /> </td>
+                          </tr>
+                        </table>
+                      </td>
+                      <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
+                        <a var:href="ownMethodName"
+                          class="button_auto"
+                          var:queryDictionary="toggleShowRejectedAptsQueryParameters"
+                          label:string="$toggleShowRejectedAptsLabel"
+                          />
+                      </td>
+                      <td align="right" bgcolor="#e8e8e0">
+                        <table border='0' cellpadding='0' cellspacing='1'>
+                          <tr>
+                            <td class="button_auto_env"
+                              nowrap="true"
+                              valign='middle'
+                              align='center'
+                              >
+                              <!--<a class="button_auto"
+                              href="weekprintview"
+                              var:queryDictionary="queryParameters"
+                              target="SOGoPrintView"
+                              ><var:string label:value="printview" /></a>-->
+                            </td>
+                            <td class="button_auto_env"
+                              nowrap="true"
+                              valign="middle"
+                              align="center"
+                              >
+                              <a class="button_auto"
+                                href="proposal"
+                                var:queryDictionary="queryParameters"
+                                ><var:string label:value="proposal" /></a>
+                            </td>
+                          </tr>
+                        </table>
+                      </td>
+                    </tr>
+                  </table>
+                  <table width="100%">
+                    <tr valign="top">
+                      <td>
+                        <table>
+                          <tr>
+                            <td>
+                              <var:component className="UIxCalInlineMonthOverview"
+                                selectedDate="thisMonth"
+                                const:showYear="YES"
+                                const:showWeekColumn="YES"
+                                const:weekSelectionHref="weekcolumnsview"
+                                const:style="weekcolumnsview_cal"
+                                const:headerStyle="weekcolumnsview_cal_title"
+                                const:weekStyle="weekcolumnsview_cal_week"
+                                const:dayHeaderStyle="weekcolumnsview_cal_day_header"
+                                const:dayBodyStyle="weekcolumnsview_cal_content"
+                                const:todayBodyStyle="weekcolumnsview_cal_content_hilite"
+                                const:inactiveDayBodyStyle="weekcolumnsview_cal_content_dimmed"
+                                />
+                            </td>
+                          </tr>
+                          <tr>
+                            <td>
+                              <var:component className="UIxCalInlineMonthOverview"
+                                selectedDate="nextMonth"
+                                const:showYear="YES"
+                                const:showWeekColumn="YES"
+                                const:weekSelectionHref="weekcolumnsview"
+                                const:style="weekcolumnsview_cal"
+                                const:headerStyle="weekcolumnsview_cal_title"
+                                const:weekStyle="weekcolumnsview_cal_week"
+                                const:dayHeaderStyle="weekcolumnsview_cal_day_header"
+                                const:dayBodyStyle="weekcolumnsview_cal_content"
+                                const:todayBodyStyle="weekcolumnsview_cal_content_hilite"
+                                const:inactiveDayBodyStyle="weekcolumnsview_cal_content_dimmed"
+                                />
+                            </td>
+                          </tr>
+                        </table>
+                      </td>
+                      <td width="100%">
+                        <var:weekcol-view list="appointments"
+                          item="appointment"
+                          weekStart="startDate"
+                          dayIndex="dayIndex"
+                          const:startDateKey="startDate"
+                          const:endDateKey="endDate"
+                          const:titleStyle="weekcolumnsview_title"
+                          contentStyle="contentStyle"
+                          const:class="weekcolumnsview"
+                          const:width="100%"
+                          const:contentColor="#e8e8e0"
+                          const:cellpadding="0"
+                          const:cellspacing="2"
+                          const:hideWeekend="shouldHideWeekend"
+                          >
+                          <var:weekcol-title>
+                            <table cellpadding="0" width="100%" border="0" cellspacing="0"
+                              var:class="titleStyle">
+                              <tr>
+                                <td align="left" valign="top">
+                                  <a href="dayoverview"
+                                    var:queryDictionary="currentDayQueryParameters"
+                                    class="weekcolumnsview_title_daylink"
+                                    ><var:string value="currentDay.dayOfMonth" /></a>
+                                </td>
+                                <td align="center" valign="top" width="97%">
+                                  <var:string value="currentDayName" /><br />
+                                  [<a href="new"
+                                    onclick="return newEvent(this);"
+                                    var:day="currentDayQueryParameters.day"
+                                    var:queryDictionary="currentDayQueryParameters"
+                                    class="weekcolumnsview_title_newlink"
+                                    ><var:string label:value="new" /></a>]
+                                </td>
+                              </tr>
+                            </table>
+                          </var:weekcol-title>
+                          <var:if condition="hasDayInfo">
+                            <var:weekcol-info>
+                              <var:if condition="hasHolidayInfo">
+                                <var:string value="holidayInfo" 
+                                  const:class="weekcolumnsview_holidayinfo" />
+                              </var:if>
+                              <var:foreach list="allDayApts" item="appointment">
+                                <var:component className="UIxCalInlineAptView"
+                                  appointment="appointment"
+                                  formatter="aptFormatter"
+                                  tooltipFormatter="aptTooltipFormatter"
+                                  url="appointmentViewURL"
+                                  style="aptStyle"
+                                  queryDictionary="currentDayQueryParameters"
+                                  referenceDate="currentDay"
+                                  canAccess="canAccessApt"
+                                  />
+                                <br />
+                              </var:foreach>
+                            </var:weekcol-info>
+                          </var:if>
+                          <var:weekcol>
+                            <var:component className="UIxCalInlineAptView"
+                              appointment="appointment"
+                              formatter="aptFormatter"
+                              tooltipFormatter="aptTooltipFormatter"
+                              url="appointmentViewURL"
+                              style="aptStyle"
+                              queryDictionary="currentDayQueryParameters"
+                              referenceDate="currentDay"
+                              canAccess="canAccessApt"
+                              />
+                            <br />
+                          </var:weekcol>
+                        </var:weekcol-view>
+                      </td>
+                    </tr>
+                  </table>
+                </var:component>
+              </td>
+            </tr>
+            <tr bgcolor="#F5F5E9">
+              <td align="left" width="10"><var:entity const:name="nbsp"/></td>
+              <td align="right"><img border="0"
+                  alt=""
+                  rsrc:src="corner_right.gif"
+                  /></td>
+            </tr>
+            <tr>
+              <td colspan="2" bgcolor="#F5F5E9">
+                <table border="0" width="100%" cellpadding="10" cellspacing="0">
+                  <tr />
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+    </table>
+    <!--
+    <hr />
+    <var:string value="thisWeekQueryParameters" />
+    -->
+    <!--
+    <hr/>
+    
+    Appointments: 
+    <var:component className="UIxAptTableView" appointments="appointments"/>
+    -->
+    <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
+
+  </var:component>
diff --git a/UI/Templates/SchedulerUI/UIxCalWeekListview.wox b/UI/Templates/SchedulerUI/UIxCalWeekListview.wox
new file mode 100644 (file)
index 0000000..8eec362
--- /dev/null
@@ -0,0 +1,243 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    xmlns:uix="OGo:uix"
+    className="UIxPageFrame"
+    title="name"
+    >
+
+    <table id="skywintable"
+      class="wintable"
+      cellspacing="0"
+      cellpadding="5"
+      width="100%"
+      >
+      <tr>
+        <td class="window_label"><var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="week"
+            /></td>
+      </tr>
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" cellpadding="0" cellspacing="0" width="100%">
+            <tr bgcolor="#e8e8e0">
+              <td align="left">
+                <var:component className="UIxCalBackForthNavView"
+                  methodName="ownMethodName"
+                  prevQueryParameters="prevWeekQueryParameters"
+                  currentQueryParameters="todayQueryParameters"
+                  nextQueryParameters="nextWeekQueryParameters"
+                  label:label="this week"
+                  />              
+              </td>
+              <td align="right" valign="middle" width="80%">
+                <var:component className="UIxContactSelector"
+                  const:selectorId="uids" />
+                <!--              <var:component className="AnaisUidSelector"
+                calendarUIDs="clientObject.calendarUIDs"
+                /> -->
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" width="100%" cellpadding="0" cellspacing="0">
+            <tr>
+              <td colspan="2">
+                <var:component className="UIxCalSelectTab"
+                  const:selection="week"
+                  currentDate="selectedDate"
+                  >
+                  <table border="0"
+                    cellpadding="4"
+                    width="100%"
+                    cellspacing="2"
+                    >
+                    <tr>
+                      <td width="1%"
+                        align="left"
+                        valign="middle"
+                        bgcolor="#e8e8e0"
+                        >
+                        <table border='0' cellpadding='0' cellspacing='0'>
+                          <tr>
+                            <td><a href="weekoverview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_overview.gif"
+                                  label:title="Overview"
+                                  label:alt="Overview"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                            <td><a href="weekchartview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_chart.gif"
+                                  label:title="Chart"
+                                  label:alt="Chart"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                            <td><img rsrc:src="icon_view_list_inactive.gif"
+                                label:title="List"
+                                label:alt="List"
+                                border="0"
+                                valign="top"
+                                /></td>
+                            <td>
+                              <a href="weekcolumnsview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_columns.gif"
+                                  label:title="Columns"
+                                  label:alt="Columns"
+                                  border="0"
+                                  valign="top"
+                                  /></a></td>
+                          </tr>
+                        </table>
+                      </td>
+                      <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
+                        <a var:href="ownMethodName"
+                          class="button_auto"
+                          var:queryDictionary="toggleShowRejectedAptsQueryParameters"
+                          label:string="$toggleShowRejectedAptsLabel"
+                          />
+                      </td>
+                      <td align="right" bgcolor="#e8e8e0">
+                        <table border='0' cellpadding='0' cellspacing='1'>
+                          <tr>
+                            <td class="button_auto_env" nowrap="true" valign='middle' 
+                              align='center'>
+                              <!--<a class="button_auto"
+                              href="weekprintview"
+                              var:queryDictionary="queryParameters"
+                              target="SOGoPrintView"
+                              ><var:string label:value="printview" /></a>-->
+                            </td>
+                            <td class="button_auto_env" nowrap="true" valign='middle' 
+                              align='center'>
+                              <a class="button_auto"
+                                href="proposal"
+                                var:queryDictionary="queryParameters"
+                                ><var:string label:value="proposal" /></a>
+                            </td>
+                          </tr>
+                        </table>
+                      </td>
+                    </tr>
+                  </table>
+                  
+                  <var:hspan-matrix list="appointments"
+                    item="appointment"
+                    rows="uids"
+                    row="currentUid"
+                    columns="columns"
+                    column="column"
+                    itemActive="isItemActive"
+                    isRowActive="isRowActive"
+                    const:rowHeight="8"
+                    const:width="100%"
+                    const:border="0"
+                    const:cellpadding="0"
+                    const:cellspacing="2"
+                    >
+                    <var:matrix-label const:elementName="td"
+                      const:position="top"
+                      const:align="center"
+                      span="columnsPerDay"
+                      >
+                      <table cellpadding="2"
+                        cellspacing="0"
+                        width="100%"
+                        border="0"
+                        var:class="titleStyle"
+                        >
+                        <tr>
+                          <td align="left" valign="top">
+                            <a href="daylistview"
+                              var:queryDictionary="currentDayQueryParameters"
+                              class="weekoverview_title_daylink"
+                              ><var:string value="currentDay.dayOfMonth"
+                                const:numberformat="02"
+                                /></a>
+                          </td>
+                          <td align="center" valign="top" width="97%">
+                            <var:string value="currentDayName" /><br />
+                            [<a href="new"
+                              onclick="return newEvent(this);"
+                              var:day="currentDayQueryParameters.day"
+                              var:queryDictionary="currentDayQueryParameters"
+                              class="weekoverview_title_newlink"
+                              ><var:string label:value="new" /></a>]
+                          </td>
+                        </tr>
+                      </table>
+                    </var:matrix-label>
+                    
+                    <var:matrix-label const:elementName="td"
+                      const:position="left"
+                      const:bgcolor="#d6d6ce"
+                      const:width="100"
+                      >
+                      <var:string value="cnForCurrentUid"
+                        const:style="dayoverview_content_time_link"
+                        />
+                    </var:matrix-label>
+                    <!-- TODO: use css instead! -->
+                    <var:matrix-empty const:elementName="td"
+                      const:bgcolor="#efefe7"
+                      ><var:entity const:name="nbsp"
+                        />
+                    </var:matrix-empty>
+                    <var:matrix-label const:elementName="td"
+                      const:position="bottom"
+                      >
+                      <img rsrc:src="invisible_space_2.gif" />
+                    </var:matrix-label>
+                    <!-- TODO: use css instead! -->
+                    <var:matrix-cell const:elementName="td"
+                      const:bgcolor="#d6d6ce"
+                      const:align="top"
+                      >
+                      <span class="dayoverview_content_time_link">
+                        <var:component className="UIxCalInlineAptView"
+                          appointment="appointment"
+                          formatter="aptFormatter"
+                          tooltipFormatter="aptTooltipFormatter"
+                          url="appointmentViewURL"
+                          style="aptStyle"
+                          queryDictionary="currentDayQueryParameters"
+                          canAccess="canAccessApt"
+                          />
+                      </span>
+                    </var:matrix-cell>
+                  </var:hspan-matrix>
+                </var:component>
+              </td>
+            </tr>
+            <tr bgcolor="#F5F5E9">
+              <td align="left" width="10"><var:entity const:name="nbsp"/></td>
+              <td align="right"
+                ><img border="0"
+                  alt=""
+                  rsrc:src="corner_right.gif"
+                  /></td>
+            </tr>
+            <tr>
+              <td colspan="2" bgcolor="#F5F5E9">
+                <table border="0" width="100%" cellpadding="10" cellspacing="0">
+                  <tr />
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+    </table>
+  </var:component>
diff --git a/UI/Templates/SchedulerUI/UIxCalWeekOverview.wox b/UI/Templates/SchedulerUI/UIxCalWeekOverview.wox
new file mode 100644 (file)
index 0000000..e503e8d
--- /dev/null
@@ -0,0 +1,216 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    xmlns:uix="OGo:uix"
+    className="UIxPageFrame"
+    title="name"
+    >
+    <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" 
+      width="100%">
+      <tr>
+        <td class="window_label">[<var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="week"
+            />]</td>
+      </tr>
+
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" cellpadding="0" cellspacing="0" width="100%">
+            <tr bgcolor="#e8e8e0">
+              <td align="left">
+                <var:component className="UIxCalBackForthNavView"
+                  methodName="ownMethodName"
+                  prevQueryParameters="prevWeekQueryParameters"
+                  currentQueryParameters="todayQueryParameters"
+                  nextQueryParameters="nextWeekQueryParameters"
+                  label:label="this week"
+                  />
+              </td><!-- 99% -->
+              <td align="right" valign="middle" width="80%">
+                <var:component
+                  className="UIxContactSelector"
+                  const:selectorId="uids" />
+                <!--                <var:component className="AnaisUidSelector"
+                calendarUIDs="clientObject.calendarUIDs"
+                /> -->
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+
+      <tr>
+        <td id="skywinbodycell" class="wincontent">
+          <table border="0" width="100%" cellpadding="0" cellspacing="0">
+            <tr>
+              <td colspan="2">
+                <var:component className="UIxCalSelectTab"
+                  const:selection="week"
+                  currentDate="selectedDate"
+                  >
+                  <table border="0" cellpadding="4" width="100%" cellspacing="2">
+                    <tr>
+                      <td width="1%" align="left" valign="middle" bgcolor="#e8e8e0">
+                        <table border='0' cellpadding='0' cellspacing='0'>
+                          <tr>
+                            <td><img rsrc:src="icon_view_overview_inactive.gif"
+                                label:title="Overview" label:alt="Overview"
+                                border="0" valign="top" /></td>
+                            <td><a href="weekchartview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_chart.gif"
+                                  label:title="Chart" label:alt="Chart"
+                                  border="0" valign="top" /></a></td>
+                            <td><a href="weeklistview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_list.gif"
+                                  label:title="List" label:alt="List"
+                                  border="0" valign="top" /></a></td>
+                            <td>
+                              <a href="weekcolumnsview"
+                                var:queryDictionary="queryParameters"
+                                ><img rsrc:src="icon_view_columns.gif"
+                                  label:title="Columns" label:alt="Columns"
+                                  border="0" valign="top" /></a>
+                            </td>
+                          </tr>
+                        </table>
+                      </td>
+                      <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
+                        <a var:href="ownMethodName"
+                          class="button_auto"
+                          var:queryDictionary="toggleShowRejectedAptsQueryParameters"
+                          label:string="$toggleShowRejectedAptsLabel"
+                          />
+                      </td>
+                      <td align="right" bgcolor="#e8e8e0">
+                        <table border='0' cellpadding='0' cellspacing='1'>
+                          <tr>
+                            <td class="button_auto_env" nowrap="true" valign='middle' 
+                              align='center'>
+                              <!--<a class="button_auto"
+                              href="weekprintview"
+                              var:queryDictionary="queryParameters"
+                              target="SOGoPrintView"
+                              ><var:string label:value="printview" /></a>-->
+                            </td>
+                            <td class="button_auto_env" nowrap="true" valign='middle' 
+                              align='center'>
+                              <a class="button_auto"
+                                href="proposal"
+                                var:queryDictionary="queryParameters"
+                                ><var:string label:value="proposal" /></a>
+                            </td>
+                          </tr>
+                        </table>
+                      </td>
+                    </tr>
+                  </table>
+
+                  <var:week-overview list="appointments"
+                    item="appointment"
+                    weekStart="startDate"
+                    dayIndex="dayIndex"
+                    const:startDateKey="startDate"
+                    const:endDateKey="endDate"
+                    const:titleStyle="weekoverview_title"
+                    hideWeekend="shouldHideWeekend"
+                    contentStyle="contentStyle"
+                    >
+                    <var:week-title>
+                      <table cellpadding="0" width="100%" border="0" cellspacing="0"
+                        var:class="titleStyle">
+                        <tr>
+                          <td align="left" valign="top">
+                            <a href="dayoverview"
+                              var:queryDictionary="currentDayQueryParameters"
+                              class="weekoverview_title_daylink"
+                              ><var:string value="currentDay.dayOfMonth"
+                                const:numberformat="02"
+                                /></a>
+                          </td>
+                          <td align="center" valign="top" width="97%">
+                            <var:string value="currentDayName" /><br />
+                            [<a href="new"
+                              onclick="return newEvent(this);"
+                              var:day="currentDayQueryParameters.day"
+                              var:queryDictionary="currentDayQueryParameters"
+                              class="weekoverview_title_newlink"
+                              ><var:string label:value="new" /></a>]
+                          </td>
+                        </tr>
+                      </table>
+                    </var:week-title>
+                    <var:if condition="hasDayInfo">
+                      <var:week-info>
+                        <var:if condition="hasHolidayInfo">
+                          <var:string value="holidayInfo" 
+                            const:class="weekoverview_holidayinfo" />
+                        </var:if>
+                        <var:foreach list="allDayApts" item="appointment">
+                          <var:component className="UIxCalInlineAptView"
+                            appointment="appointment"
+                            formatter="aptFormatter"
+                            tooltipFormatter="aptTooltipFormatter"
+                            url="appointmentViewURL"
+                            style="aptStyle"
+                            referenceDate="currentDay"
+                            queryDictionary="currentDayQueryParameters"
+                            canAccess="canAccessApt"
+                            />
+                          <br />
+                        </var:foreach>
+                      </var:week-info>
+                    </var:if>
+                    <var:week>
+                      <var:component className="UIxCalInlineAptView"
+                        appointment="appointment"
+                        formatter="aptFormatter"
+                        tooltipFormatter="aptTooltipFormatter"
+                        url="appointmentViewURL"
+                        style="aptStyle"
+                        referenceDate="currentDay"
+                        canAccess="canAccessApt"
+                        />
+                      <br />
+                    </var:week>
+                  </var:week-overview>
+                </var:component>
+              </td>
+            </tr>
+            <tr bgcolor="#F5F5E9"> <!-- use CSS -->
+              <td align="left" width="10"><var:entity const:name="nbsp"/></td>
+              <td align="right"
+                ><img border="0"
+                  alt=""
+                  rsrc:src="corner_right.gif"
+                  /></td>
+            </tr>
+            <tr>
+              <td colspan="2" bgcolor="#F5F5E9"> <!-- use CSS -->
+                <table border="0" width="100%" cellpadding="10" cellspacing="0">
+                  <tr />
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+    </table>
+    <!--
+    <hr />
+    <var:string value="thisWeekQueryParameters" />
+    -->
+    <!--
+    <hr/>
+    
+    Appointments: 
+    <var:component className="UIxAptTableView" appointments="appointments"/>
+    -->
+    <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
+  </var:component>
diff --git a/UI/Templates/SchedulerUI/UIxCalWeekView.wox b/UI/Templates/SchedulerUI/UIxCalWeekView.wox
new file mode 100644 (file)
index 0000000..be95448
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" standalone="yes"?>
+  <container
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+
+    <a href="#"
+      class="leftNavigationArrow"
+      var:date="prevWeekQueryParameters.day"
+      onclick="return onCalendarGotoDay(this);"
+      ><img rsrc:src="arrow-lft-sharp.gif"/></a>
+    <span class="weeksHeader">
+      <span class="week2"><a href="#"
+          var:date="weekBeforePrevWeekQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="weekBeforeLastWeekName"
+            /></a></span
+        ><span class="week1"><a href="#"
+          var:date="prevWeekQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="lastWeekName"
+            /></a></span
+        ><span class="week0"><var:string value="currentWeekName" /></span
+        ><span class="week1"><a href="#"
+          var:date="nextWeekQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="nextWeekName"
+            /></a></span
+        ><span class="week2"><a href="#"
+          var:date="weekAfterNextWeekQueryParameters.day"
+          onclick="return onCalendarGotoDay(this);"
+          ><var:string value="weekAfterNextWeekName"
+            /></a></span
+        ></span>
+    <a href="#"
+      class="rightNavigationArrow"
+      var:date="nextWeekQueryParameters.day"
+      onclick="return onCalendarGotoDay(this);"
+      ><img rsrc:src="arrow-rit-sharp.gif"/></a>
+
+    <div id="calendarContent">
+      <var:component
+        className="UIxCalDayTable"
+        startDate="startDate"
+        const:CSSClass="weekOverview"
+        const:numberOfDays="7" />
+    </div>
+  </container>
similarity index 85%
rename from UI/Templates/UIxCalYearOverview.wox
rename to UI/Templates/SchedulerUI/UIxCalYearOverview.wox
index 117047b9e83bc9b9dbe284878c1afabf83f6ba01..958f522fee9d5c3385350f2e66dda8f4352618c1 100644 (file)
@@ -7,26 +7,16 @@
                className="UIxPageFrame"
                title="name"
 >
+
   <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" 
          width="100%">
     <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle">
-              <var:component className="UIxCalDateLabel"
-                             startDate="startDate"
-                             endDate="endDate"
-                             const:selection="year"
-              />
-            </td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose"/>
-            </td>
-          </tr>
-        </table>
-      </td>
+        <td class="window_label">
+          <var:component className="UIxCalDateLabel"
+            startDate="startDate"
+            endDate="endDate"
+            const:selection="year"
+            /></td>
     </tr>
     <tr>
       <td id="skywinbodycell" class="wincontent">
               />
             </td>
             <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector"
+                <var:component
+                  className="UIxContactSelector"
+                  const:selectorId="uids" />
+<!--              <var:component className="AnaisUidSelector"
                              calendarUIDs="clientObject.calendarUIDs"
-              />
+              /> -->
             </td>
           </tr>
         </table>
diff --git a/UI/Templates/SchedulerUI/UIxDatePicker.wox b/UI/Templates/SchedulerUI/UIxDatePicker.wox
new file mode 100644 (file)
index 0000000..2086001
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version='1.0' standalone='yes'?>
+  <span xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    class="datePicker"
+    ><input type="text"
+      var:disabled="disabled"
+      class="textField"
+      var:name="dateID"
+      var:id="dateID"
+      var:dateFormat="jsDateFormat"
+      var:shadow-value="formattedDateString"
+      var:value="formattedDateString"
+      size="12"
+      /><a href="#"
+      class="button"
+      var:inputId="dateID"
+      onclick="return popupCalendar(this);"
+      ><img rsrc:src="choose-date.png"
+        var:title="label"
+        var:alt="label"
+        /></a
+      >
+    <script type="text/javascript">
+      assignCalendar('<var:string value="dateID" />');
+    </script>
+  </span>
diff --git a/UI/Templates/SchedulerUI/UIxFreeBusyUserSelector.wox b/UI/Templates/SchedulerUI/UIxFreeBusyUserSelector.wox
new file mode 100644 (file)
index 0000000..ad7589c
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version='1.0' standalone='yes'?>
+  <container
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <script type="text/javascript" rsrc:src="UIxFreeBusyUserSelector.js"><!-- space --></script>
+    <script type="text/javascript">
+      freeBusySelectorId = '<var:string value="selectorId" />';
+    </script>
+    <input type="hidden"
+      var:id="selectorId"
+      var:name="selectorId"
+      var:value="initialContactsAsString" />
+    <div class="freeBusyView" var:id="freeBusyViewId">
+      <var:component className="UIxFreeBusyUserSelectorTable"
+        contacts="contacts"
+        dayStartHour="dayStartHour"
+        dayEndHour="dayEndHour"
+        startDate="startDate"
+        endDate="endDate" />
+    </div>
+    <div class="legend" onmousedown="return false;">
+      <hr />
+      <ul>
+        <li><img rsrc:src="required-participant.png"
+            /><var:string label:value="Required participant" /></li>
+        <li><img rsrc:src="optional-participant.png"
+            /><var:string label:value="Optional participant" /></li>
+        <li><img rsrc:src="chair.png"
+            /><var:string label:value="Chair" /></li>
+      </ul>
+      <ul>
+        <li><img rsrc:src="needs-action.png"
+            /><var:string label:value="Needs action" /></li>
+        <li><img rsrc:src="accepted.png"
+            /><var:string label:value="Accepted" /></li>
+        <li><img rsrc:src="declined.png"
+            /><var:string label:value="Declined" /></li>
+        <li><img rsrc:src="tentative.png"
+            /><var:string label:value="Tentative" /></li>
+      </ul>
+      <ul>
+        <li><span class="colorBox free"><!-- spacer --></span><var:string label:value="Free" /></li>
+        <li><span class="colorBox busy"><!-- spacer --></span><var:string label:value="Busy" /></li>
+        <li><span class="colorBox maybe-busy"><!-- spacer --></span><var:string label:value="Maybe busy" /></li>
+        <li><span class="colorBox noFreeBusy"><!-- spacer --></span><var:string label:value="No free-busy information" /></li>
+      </ul>
+    </div>
+    <div id="freeBusyFooter">
+      <hr />
+      <div id="freeBusyButtons">
+        <a href="#" class="button _disabled"><var:string label:value="Previous slot" /></a>
+        <a href="#" class="button _disabled"><var:string label:value="Next slot" /></a><br />
+        <a href="#" class="button _disabled"><var:string label:value="Previous hour" /></a>
+        <a href="#" class="button _disabled"><var:string label:value="Next hour" /></a>
+      </div>
+      <div id="freeBusyReplicas">
+        <label><var:string label:value="From"
+            /><var:component className="UIxTimeDateControl"
+            const:disabled="yes"
+            const:controlID="FBStartTimeReplica"
+            date="startDate"
+            const:dayStartHour="0"
+            const:dayEndHour="23"
+            /></label>
+        <label><var:string label:value="To"
+            /><var:component className="UIxTimeDateControl"
+            const:disabled="yes"
+            const:controlID="FBEndTimeReplica"
+            date="endDate"
+            const:dayStartHour="0"
+            const:dayEndHour="23"
+            /></label>
+      </div>
+    </div>
+  </container>
diff --git a/UI/Templates/SchedulerUI/UIxFreeBusyUserSelectorTable.wox b/UI/Templates/SchedulerUI/UIxFreeBusyUserSelectorTable.wox
new file mode 100644 (file)
index 0000000..f1e60c0
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version='1.0' standalone='yes'?>
+  <table class="freeBusy"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label">
+    <thead>
+      <tr class="freeBusyHeader1"
+        ><th class="attendees"></th
+          ><var:foreach list="daysToDisplay" item="currentDayToDisplay"
+          ><th colspan="11"><var:string value="currentFormattedDay" /></th
+            ></var:foreach
+          ></tr>
+      <tr class="freeBusyHeader2"
+        ><th class="attendees"></th
+          ><var:foreach list="daysToDisplay" item="currentDayToDisplay"
+          ><var:foreach list="hoursToDisplay" item="currentHourToDisplay"
+            ><th><var:string value="currentHourToDisplay" const:numberformat="00:"/>00</th
+              ></var:foreach
+            ></var:foreach
+          ></tr>
+      <tr class="freeBusyHeader3"
+        ><th class="attendees"></th
+          ><var:foreach list="daysToDisplay" item="currentDayToDisplay"
+          ><var:foreach list="hoursToDisplay" item="currentHourToDisplay"
+            ><th><span class="freeBusyZoneElement"><!-- space --></span><span class="freeBusyZoneElement"><!-- space --></span><span class="freeBusyZoneElement"><!-- space --></span><span class="freeBusyZoneElement"><!-- space --></span></th
+              ></var:foreach
+            ></var:foreach
+          ></tr>
+    </thead>
+    <tbody>
+      <var:foreach list="contacts" item="currentContact"
+        ><tr><td class="attendees"
+            ><var:if condition="currentContactHasStatus"
+              ><img var:src="currentContactStatusImage"
+                /></var:if
+            ><input type="text"
+              var:value="currentContactName"
+              var:uid="currentContactId"
+              class="textField" /></td
+            ><var:foreach list="daysToDisplay" item="currentDayToDisplay"
+            ><var:foreach list="hoursToDisplay" item="currentHourToDisplay"
+              ><td></td
+                ></var:foreach
+              ></var:foreach>
+        </tr></var:foreach>
+      <tr class="futureAttendee"
+        ><td class="attendees"><input type="text" class="textField"
+            readonly="readonly" /></td
+          ><var:foreach list="daysToDisplay" item="currentDayToDisplay"
+          ><var:foreach list="hoursToDisplay" item="currentHourToDisplay"
+            ><td></td
+              ></var:foreach
+            ></var:foreach
+          ></tr>
+      <tr class="attendeeModel"
+        ><td class="attendees"><input type="text" class="textField" /></td
+          ><var:foreach list="daysToDisplay" item="currentDayToDisplay"
+          ><var:foreach list="hoursToDisplay" item="currentHourToDisplay"
+            ><td></td
+              ></var:foreach
+            ></var:foreach
+          ></tr>
+    </tbody>
+  </table>
diff --git a/UI/Templates/SchedulerUI/UIxTaskEditor.wox b/UI/Templates/SchedulerUI/UIxTaskEditor.wox
new file mode 100644 (file)
index 0000000..b9196e0
--- /dev/null
@@ -0,0 +1,178 @@
+<?xml version='1.0' standalone='yes'?>
+  <var:component
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    const:popup="YES"
+    title="name"
+    var:toolbar="toolbar">
+    <script type="text/javascript" rsrc:src="skycalendar.js">
+    </script>
+
+    <form var:href="saveUrl" name="editform" onsubmit="return validateTaskEditor();">
+      <var:if condition="hasErrorText">
+        <p style="background-color: #AA0000;"><var:string value="errorText"
+            /></p>
+        <hr />
+      </var:if>
+
+      <div id="editorTabs" class="tabsContainer">
+        <ul>
+          <li target="taskView"><var:string label:value="Task" /></li>
+          <li target="recurrenceView"><var:string label:value="Recurrence" /></li>
+          <li target="attendeesView"><var:string label:value="Attendees" /></li>
+        </ul>
+
+        <div id="taskView" class="tab">
+          <label><var:string label:value="Title" /><span class="content"
+              ><input type="text" name="summary" id="summary"
+                class="textField"
+                var:value="title"
+                /></span></label>
+          <label><var:string label:value="Location" /><span class="content"
+              ><input type="text" name="location" id="location"
+                class="textField"
+                var:value="location"
+                /></span></label>
+          <hr />
+          <span class="checkBoxList"><var:string label:value="Date" />
+            <span class="content"><input var:checked="hasStartDate"
+                id="startDateCB"
+                type="checkbox" class="checkBox"
+                onchange="onTimeControlCheck(this);"
+                /><var:component className="UIxTimeDateControl"
+                var:disabled="startDateDisabled"
+                const:controlID="startTime"
+                date="taskStartDate"
+                const:dayStartHour="0"
+                const:dayEndHour="23"
+                /></span></span>
+          <span class="checkBoxList"><var:string label:value="Due Time" />
+            <span class="content"><input var:checked="hasDueDate"
+                id="dueDateCB"
+                type="checkbox" class="checkBox"
+                onchange="onTimeControlCheck(this);"
+                /><var:component className="UIxTimeDateControl"
+                var:disabled="dueDateDisabled"
+                const:controlID="dueTime"
+                date="taskDueDate"
+                const:dayStartHour="0"
+                const:dayEndHour="23"
+                /></span></span>
+          <hr />
+          <!-- label id="isPrivate"><input class="checkBox"
+          type="checkbox" var:selection="isPrivate"
+          var:checked="isPrivate"
+          /><var:string label:value="is private" /></label -->
+          <label><var:string label:value="Calendar" />
+            <span class="content"><var:popup list="availableCalendars" item="item"
+                const:onChange="onChangeCalendar(this);"
+                string="item" selection="componentOwner" /></span></label>
+          <label><var:string label:value="Privacy" />
+            <span class="content"><var:popup list="privacyClasses" item="item"
+                string="itemPrivacyText" selection="privacy"
+                /></span></label>
+          <label><var:string label:value="Priority" />
+            <span class="content"><var:popup list="priorities" item="item"
+                string="itemPriorityText" selection="priority"
+                /></span></label>
+          <label><var:string label:value="Status" />
+            <span class="content"><var:popup list="statusTypes" item="item"
+                string="itemStatusText" selection="status"
+                /></span></label>
+<!--          <span id="categoriesCB" class="checkBoxList"
+            ><var:string label:value="Categories"
+              /><span class="content categoriesContent"><var:checkbox-list
+                list="categoryItems"
+                item="item"
+                suffix="itemCategoryText"
+                selections="categories"
+                /></span></span> -->
+          <hr />
+          <label id="commentArea"><var:string label:value="Description"
+              /><textarea name="comment" var:value="comment" /></label> 
+          <label id="urlArea"><var:string label:value="URL" />
+            <span class="content"><input type="text" name="url" id="url"
+                size="40"
+                onkeyup="validateBrowseURL(this);"
+                class="textField"
+                var:value="url"
+                /><a id="browseUrlBtn" var:class="urlButtonClasses" var:href="#" onclick="return browseUrl(this, event);"><var:string value="Browse URL" /><var:string label:value="Browse URL" /></a
+                ></span></label>
+        </div>
+
+        <div id="recurrenceView" class="tab">
+          <label><var:string label:value="Cycle"
+              />
+            <span class="content"
+              ><var:popup list="cycles" item="item"
+                label:string="$cycleLabel"
+                selection="cycle"
+                const:onChange="toggleCycleVisibility(this, 'cycleSelectionFirstLevel', 0);"
+                /><span id="cycleSelectionFirstLevel"
+                ><var:popup list="cycleEnds" item="item"
+                  label:string="$item" value="item"
+                  selection="cycleEnd"
+                  const:onChange="toggleCycleVisibility(this, 'cycleSelectionSecondLevel', 'cycle_end_never');"
+                  const:id="cycle_end_mode_selection"
+                  /><span id="cycleSelectionSecondLevel"
+                  ><var:component className="UIxTimeDateControl"
+                    date="cycleUntilDate"
+                    label="foo"
+                    const:controlID="cycleUntilDate"
+                    const:displayTimeControl="NO"
+                    /></span
+                  ></span
+                ></span
+              ></label>
+        </div>
+
+        <div id="attendeesView" class="tab">
+          <span class="checkBoxList" id="participantsCB"><var:string label:value="Attendees" />
+            <span class="content"><var:component className="UIxContactSelector"
+                const:selectorId="participants"
+                contacts="participants"
+                /></span></span>
+        </div>
+      </div>
+
+      <script type="text/javascript">
+        initTimeWidgets( { 'start': { 'hour': document.forms['editform']['startTime_time_hour'],
+                                      'minute': document.forms['editform']['startTime_time_minute'],
+                                      'date': document.forms['editform']['startTime_date'] },
+                           'due': { 'hour': document.forms['editform']['dueTime_time_hour'],
+                                    'minute': document.forms['editform']['dueTime_time_minute'],
+                                    'date': document.forms['editform']['dueTime_date'] } } );
+      </script>
+
+      <!-- div id="buttons">
+      <input
+      type="submit"
+      class="button"
+      label:value="Save"
+      name="submitmeeting" />
+      <input
+      type="submit"
+      class="button"
+      label:value="Cancel"
+      name="cancel"
+      onclick="window.close(); return false;" />
+      <var:if condition="isUIxDebugEnabled">
+      <input type="submit"
+      class="button"
+      value="Test" name="test:method" />
+    </var:if>
+    </div -->
+      <input type="hidden" name="ical" var:value="iCalString" />
+      <!-- input type="hidden" id="jsaction" -->
+    </form>
+    <!--
+    <var:if condition="canEditComponent" const:negate="YES">
+    Forbidden ... <var:redirect const:setURL="view" />
+  </var:if>
+    -->
+  </var:component>
diff --git a/UI/Templates/SchedulerUI/UIxTaskProposal.wox b/UI/Templates/SchedulerUI/UIxTaskProposal.wox
new file mode 100644 (file)
index 0000000..8c7f0ec
--- /dev/null
@@ -0,0 +1,251 @@
+<?xml version='1.0' standalone='yes'?>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+               xmlns:var="http://www.skyrix.com/od/binding"
+               xmlns:const="http://www.skyrix.com/od/constant"
+               xmlns:rsrc="OGo:url"
+               xmlns:uix="OGo:uix"
+               xmlns:label="OGo:label"
+               className="UIxPageFrame"
+               title="name"
+>
+  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5"
+         width="100%"
+  >
+    <tr>
+        <td class="window_label">
+          <var:string label:value="Search appointments" />
+        </td>
+    </tr>
+    <tr>
+      <td id="skywinbodycell" class="wincontent">
+        <form var:href="clientObject.baseURL">
+          <table border="0" width="100%" cellspacing="0" cellpadding="4">
+            <tr bgcolor="#e8e8e0">
+              <td align="left" colspan="2">
+                <span class="aptview_title">
+                  <var:string label:value="Search appointments"/>
+                </span>
+              </td>
+            </tr>
+            <tr><td colspan="2"> </td></tr>
+            <tr valign="top">
+              <td align="right" width="15%" bgcolor="#E8E8E0">
+                <span class="aptview_text">
+                  <var:string label:value="Start date" />:
+                </span>
+              </td>
+              <td align="left" bgcolor="#FFFFF0">
+                <span class="aptview_text">
+                  <var:component className="UIxDatePickerScript" />
+                  <var:component className="UIxDatePicker"
+                                 const:dateID="startDate"
+                                 day="startDateDay"
+                                 month="startDateMonth"
+                                 year="startDateYear"
+                                 label:label="browse start date"
+                  />
+                </span>
+              </td>
+            </tr>
+            <tr valign="top">
+              <td align="right" width="15%" bgcolor="#E8E8E0" 
+    class="aptview_text" >
+                <var:string label:value="End date" />:
+              </td>
+              <td align="left" bgcolor="#FFFFF0" class="aptview_text" >
+                <var:component className="UIxDatePicker"
+                               const:dateID="endDate"
+                               day="endDateDay"
+                               month="endDateMonth"
+                               year="endDateYear"
+                               label:label="browse end date"
+                />
+              </td>
+            </tr>
+            <tr valign="top">
+              <td align="right" width="15%" bgcolor="#E8E8E0"
+                  class="aptview_text"
+              >
+                <var:string label:value="Earliest start time" />:
+              </td>
+              <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                <var:component className="UIxTimeSelector"
+                               const:timeID="earliestStartTime"
+                               hour="startDateHour"
+                               minute="startDateMinute"
+                />
+              </td>
+            </tr>
+            <tr valign="top">
+              <td align="right" width="15%" bgcolor="#E8E8E0" 
+    class="aptview_text" >
+                <var:string label:value="Latest end time" />:
+              </td>
+              <td align="left" bgcolor="#FFFFF0" class="aptview_text" >
+                <var:component className="UIxTimeSelector"
+                               const:timeID="latestEndTime"
+                               hour="endDateHour"
+                               minute="endDateMinute"
+                />
+              </td>
+            </tr>
+            <tr valign="top">
+              <td align="right" width="15%" bgcolor="#E8E8E0" 
+    class="aptview_text" >
+                <var:string label:value="Duration" />:
+              </td>
+              <td align="left" bgcolor="#FFFFF0" class="aptview_text" >
+                <var:popup list="durationSteps" item="item"
+                           string="itemDurationText"
+                           selection="duration" />
+              </td>
+            </tr>
+            <tr><td colspan="2"> </td></tr>
+            <tr bgcolor="#e8e8e0">
+              <td align="left" colspan="2">
+                <span class="aptview_title">
+                  <var:string label:value="Search resources" />
+                </span>
+              </td>
+            </tr>
+            <tr><td colspan="2"> </td></tr>
+            <tr valign="top">
+              <td colspan="2">
+                  <var:component className="UIxContactSelector"
+                    const:selectorId="resources" />
+              </td>
+<!--
+              <td align="left" bgcolor="#FFFFF0">
+                <span class="aptview_text">
+                  <var:component className="AnaisAttendeeSelector"
+                                 const:selectorID="resource"
+                                 const:role="NON-PARTICIPANT"
+                                 attendees="resources"
+                                 const:division="CC"
+                                 const:withAddressBook="1"
+                  />
+                    TODO: need attendee selector (AB)
+                </span>
+              </td>
+-->
+            </tr>
+            <tr><td colspan="2"> </td></tr>
+            <tr bgcolor="#e8e8e0">
+              <td align="left" colspan="2">
+                <span class="aptview_title">
+                  <var:string label:value="Search participants" />
+                </span>
+              </td>
+            </tr>
+            <tr><td colspan="2"> </td></tr>
+            <tr valign="top">
+<!--              <td align="right" width="15%" bgcolor="#E8E8E0">
+                <span class="aptview_text">
+                  <var:string label:value="Search in Anais" />:
+                </span>
+              </td> -->
+              <td colspan="2">
+                  <var:component className="UIxContactSelector"
+                    const:selectorId="participants" />
+              </td>
+<!--              <td align="left" bgcolor="#FFFFF0">
+                <span class="aptview_text">
+                  <!-- use '1' instead of 'YES', otherwise breaks on OSX -->
+<!--                  <var:component className="AnaisAttendeeSelector"
+                                 const:selectorID="participant"
+                                 const:division="CC"
+                                 const:withCN="1"
+                                 const:role="REQ-PARTICIPANT"
+                                 attendees="participants"
+                                 var:emailForUser="emailForUser"
+                                 var:cnForUser="cnForUser"
+                                 const:withAddressBook="1"
+                  />
+                    TODO: need attendee selector (AB)
+                </span>
+              </td>
+-->
+            </tr>
+            <tr><td colspan="2"> </td></tr>
+            <tr>
+              <td></td>
+              <td>
+                <input type="submit"
+                       label:value="Search"
+                       name="proposalSearch:method"
+                />
+                <span class="button_auto_env"
+                  ><a href="weekoverview"
+                      var:queryDictionary="queryParameters"
+                      class="button_auto"
+                  ><var:string label:value="Cancel" /></a></span>
+              </td>
+            </tr>
+          </table>
+        </form>
+        <hr size="1" noshade="noshade" />
+        <table border="0" cellpadding="0" width="100%" cellspacing="1">
+          <tr>
+            <td align="middle" bgcolor="#FFDAAA" 
+                colspan="1" rowspan="2"> </td>
+            <var:foreach list="hours" item="item">
+              <td colspan="2" align="middle" bgcolor="#FFDAAA">
+                <font color="black" size="2" 
+                      face="Arial,Helvetica,Verdana,Geneva,Tahoma"
+                ><var:string value="item"/></font>
+              </td>
+            </var:foreach>
+          </tr>
+          <tr>
+            <var:foreach list="hours" item="item">
+              <td colspan="1" align="middle" bgcolor="#FFDAAA">
+                <font color="black" size="2" 
+                   face="Arial,Helvetica,Verdana,Geneva,Tahoma">00</font>
+              </td>
+              <td colspan="1" align="middle" bgcolor="#FFDAAA">
+                <font color="black" size="2" 
+                    face="Arial,Helvetica,Verdana,Geneva,Tahoma">30</font>
+              </td>
+            </var:foreach>
+          </tr>
+          <var:foreach list="days" item="currentDay">
+            <tr>
+              <td width="15%" align="middle" bgcolor="#FFDAAA" colspan="1">
+                <font color="black" size="2" 
+                      face="Arial,Helvetica,Verdana,Geneva,Tahoma"
+                      ><var:string value="currentDay" 
+                                   label:dateformat="dayLabelFormat" /></font>
+              </td>
+              <var:foreach list="hours" item="item">
+                <var:if condition="isFirstHalfGreen">
+                  <td align="left" bgcolor="#FAE8B8" valign="top">
+                    <a href="new"
+                       var:queryDictionary="currentFirstHalfQueryParameters"
+                    ><img rsrc:src="green_corner.gif" alt="new" 
+                                     border="0" /></a>
+                  </td>
+                </var:if>
+                <var:if condition="isFirstHalfBlocked">
+                  <td align="middle" bgcolor="#FFAAAA" valign="middle">
+                  </td>
+                </var:if>
+                <var:if condition="isSecondHalfGreen">
+                  <td align="left" bgcolor="#FAE8B8" valign="top">
+                    <a href="new"
+                       var:queryDictionary="currentSecondHalfQueryParameters"
+                    ><img rsrc:src="green_corner.gif" alt="new" 
+                                     border="0" /></a>
+                  </td>
+                </var:if>
+                <var:if condition="isSecondHalfBlocked">
+                  <td align="middle" bgcolor="#FFAAAA" valign="middle">
+                  </td>
+                </var:if>
+              </var:foreach>
+            </tr>
+          </var:foreach>
+        </table>
+      </td>
+    </tr>
+  </table>
+</var:component>
diff --git a/UI/Templates/SchedulerUI/UIxTaskView.wox b/UI/Templates/SchedulerUI/UIxTaskView.wox
new file mode 100644 (file)
index 0000000..3944c33
--- /dev/null
@@ -0,0 +1,299 @@
+<?xml version='1.0' standalone='yes'?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="name"
+    const:popup="YES"
+    >
+    <table cellspacing="0" cellpadding="5" width="100%">
+      <tr>
+        <td class="window_label"
+          ><var:string label:value="Appointment viewer" /></td>
+      </tr>
+
+      <tr>
+        <td>
+          <table border="0" cellpadding="2" width="100%" cellspacing="0">
+            <tr bgcolor="#e8e8e0">
+              <td align="left">
+                <span class="aptview_title"
+                  ><var:string value="startTime"
+                    formatter="dateFormatter"
+                    /></span>
+              </td>
+              <td align="right" >
+                <table border='0' cellpadding='0' cellspacing='1'>
+                  <tr>
+                    <td class="button_auto_env" nowrap="true"
+                      valign='middle' align='center'>
+                      <!--<a class="button_auto"
+                      href="printview"
+                      var:queryDictionary="queryParameters"
+                      target="SOGoPrintView"
+                      ><var:string label:value="printview" /></a>-->
+                    </td>
+                    <var:if condition="canEditApt">
+                      <td class="button_auto_env" nowrap="true"
+                        valign='middle' align='center'>
+                        <a class="button_auto"
+                          href="edit"
+                          var:queryDictionary="queryParameters"
+                          ><var:string label:value="edit" /></a>
+                      </td>
+                      <td class="button_auto_env" nowrap="true"
+                        valign='middle' align='center'>
+                        <a class="button_auto"
+                          href="delete"
+                          var:queryDictionary="queryParameters"
+                          ><var:string label:value="delete" /></a>
+                      </td>
+                    </var:if>
+                  </tr>
+                </table>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td valign="top" width="100%">
+          <table width="100%" border="0" cellpadding="4" cellspacing="0">  
+            <!-- general appointment info -->
+            <var:if condition="canAccessApt">  
+              <tr valign="top">
+                <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                  <var:string label:value="Title" />:
+                </td>
+                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string value="appointment.summary" const:escapeHTML="NO" />
+                </td>
+              </tr>
+              <tr valign="top">
+                <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                  <var:string label:value="Location" />:
+                </td>
+                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string value="appointment.location" const:escapeHTML="NO" />
+                </td>
+              </tr>
+              <tr valign="top">
+                <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                  <var:string label:value="Priority" />:
+                </td>
+                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string label:value="$priorityLabelKey" />
+                </td>
+              </tr>
+            </var:if>
+            <tr valign="top">
+              <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
+                <var:string label:value="Classification" />:
+              </td>
+              <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                <var:if condition="appointment.isPublic">Public</var:if>
+                <var:if condition="appointment.isPublic"
+                  const:negate="YES"
+                  >Private</var:if>
+              </td>
+            </tr>
+          </table>
+        </td>
+      </tr>
+      <tr>
+        <td valign="top" width="100%">
+          <uix:tabview var:selection="tabSelection"
+            const:tabStyle="tab"
+            const:selectedTabStyle="tab_selected"
+            const:bodyStyle="tabview_body"
+            >
+            <uix:tab const:key="attributes"
+              label:label="attributes"
+              var:href="attributesTabLink"
+              >
+              <table width="100%" border="0" cellpadding="4" cellspacing="0">
+                <tr valign="top">
+                  <td align="right"
+                    width="15%"
+                    bgcolor="#E8E8E0"
+                    class="aptview_text"
+                    >
+                    <var:string label:value="Start time" />:
+                  </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                    <var:string value="startTime"
+                      formatter="dateFormatter"
+                      />
+                  </td>
+                </tr>
+                <tr valign="top">
+                  <td align="right"
+                    width="15%"
+                    bgcolor="#E8E8E0"
+                    class="aptview_text"
+                    >
+                    <var:string label:value="End time" />:
+                  </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                    <var:string value="endTime"
+                      formatter="dateFormatter"
+                      />
+                  </td>
+                </tr>
+                <var:if condition="canAccessApt">  
+                  <tr valign="top">
+                    <td align="right"
+                      width="15%"
+                      bgcolor="#E8E8E0"
+                      class="aptview_text"
+                      >
+                      <var:string label:value="Categories" />:
+                    </td>
+                    <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                      <var:string value="categoriesAsString"  const:escapeHTML="NO" />
+                    </td>
+                  </tr>
+                  <!-- Resources removed for v0.8
+                  <tr valign="top">
+                  <td align="right"
+                  width="15%"
+                  bgcolor="#E8E8E0"
+                  class="aptview_text"
+                  >
+                  <var:string label:value="Resources" />:
+                </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  <var:string value="resourcesAsString"
+                  const:escapeHTML="NO"
+                  />
+                </td>
+                </tr>
+                  -->
+                  <tr valign="top">
+                    <td align="right"
+                      width="15%"
+                      bgcolor="#E8E8E0"
+                      class="aptview_text"
+                      >
+                      <var:string label:value="Organizer" />:
+                    </td>
+                    <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                      <var:string value="eventOrganizer" />
+                    </td>
+                  </tr>
+                  <tr valign="top">
+                    <td align="right"
+                      width="15%"
+                      bgcolor="#E8E8E0"
+                      class="aptview_text"
+                      >
+                      <var:string label:value="Comment" />:
+                    </td>
+                    <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                      <var:string value="appointment.comment" const:insertBR="1"
+                        const:escapeHTML="NO" />
+                    </td>
+                  </tr>
+                </var:if>
+              </table>
+            </uix:tab>
+            <var:if condition="canAccessApt">    
+              
+              <uix:tab const:key="participants"
+                label:label="participants"
+                var:href="participantsTabLink"
+                >
+                <table width="100%" border="0" cellpadding="4" cellspacing="0">
+                  <tr valign="top">
+                    <td align="left" bgcolor="#E8E8E0" class="aptview_title">
+                      <var:string label:value="Name" />
+                    </td>
+                    <td align="left" bgcolor="#E8E8E0" class="aptview_title">
+                      <var:string label:value="Email" />
+                    </td>
+                    <td align="left"
+                      bgcolor="#E8E8E0"
+                      class="aptview_title"
+                      colspan="2"
+                      >
+                      <var:string label:value="Status" />
+                    </td>
+                  </tr>
+                  <var:foreach list="appointment.participants"
+                    item="attendee"
+                    >
+                    <tr valign="top">
+                      <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                        <var:string value="attendee.cnForDisplay" />
+                      </td>
+                      <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                        <a var:href="attendee.email"
+                          ><var:string value="attendee.rfc822Email" /></a>
+                      </td>
+                      <td align="left"
+                        bgcolor="#FFFFF0"
+                        class="aptview_text"
+                        var:colspan="attendeeStatusColspan"
+                        >
+                        <var:component className="UIxCalParticipationStatusView"
+                          partStat="attendee.participationStatus"
+                          />
+                      </td>
+                      <var:if condition="isAttendeeActiveUser">
+                        <td align="left"
+                          bgcolor="#FFFFF0"
+                          class="button_auto_env"
+                          >
+                          <var:if condition="showAcceptButton">  
+                            <a href="accept"
+                              class="button_auto"
+                              _tab="participants"
+                              ><var:string label:value="accept" /></a>
+                          </var:if>
+                          <var:if condition="showRejectButton">
+                            <a href="decline"
+                              class="button_auto"
+                              _tab="participants"
+                              ><var:string label:value="decline" /></a>
+                          </var:if>
+                        </td>
+                      </var:if>
+                    </tr>
+                  </var:foreach>
+                </table>
+              </uix:tab>
+            </var:if>
+            <var:if condition="isUIxDebugEnabled">
+              <uix:tab const:key="debug"
+                const:label="DEBUG"
+                var:href="debugTabLink">
+                SOGo Server - <var:string value="name"/>
+                <br />
+                Client: <var:string value="clientObject"/>
+                <br />
+                Group:      <var:string value="clientObject.group"
+                  /><br />
+                Deletable:  <var:string value="clientObject.isDeletionAllowed"
+                  /><br />
+                Generation: <var:string value="clientObject.zlGenerationCount"
+                  /><br />
+                MsgClass:   <var:string value="clientObject.outlookMessageClass"
+                  /><br />
+                
+                <hr />
+                As iCal:<br />
+                <pre><var:string value="clientObject.iCalString"/></pre>
+                
+                <hr />
+                As Mail:<br />
+                <pre><var:string value="clientObject.iCalMailString"/></pre>
+                
+              </uix:tab>
+            </var:if>
+          </uix:tabview>
+        </td>
+      </tr>
+    </table>
+  </var:component>
diff --git a/UI/Templates/SchedulerUI/UIxTimeDateControl.wox b/UI/Templates/SchedulerUI/UIxTimeDateControl.wox
new file mode 100644 (file)
index 0000000..ec42722
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version='1.0' standalone='yes'?>
+<!-- $Id$ -->
+  <span
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    class="timeDateControl"
+    >
+    <var:component className="UIxDatePicker"
+      dateID="dateID"
+      year="year"
+      month="month"
+      day="day"
+      label="label"
+      var:disabled="disabled"
+      />
+    <var:if condition="displayTimeControl">
+      <var:if condition="disabled">
+        <select var:shadow-value="hour" var:name="hourSelectId" const:disabled="disabled">
+          <var:foreach list="selectableHours" item="hourOption"
+            ><var:if condition="isCurrentHour"
+              ><option var:value="hourValue" selected="selected"
+                ><var:string value="hourLabel"
+                  /></option></var:if
+              ><var:if condition="isCurrentHour" const:negate="YES"
+              ><option var:value="hourValue"><var:string value="hourLabel"
+                  /></option></var:if>
+          </var:foreach
+            ></select>
+        <select var:shadow-value="minute" var:name="minuteSelectId" const:disabled="disabled">
+          <var:foreach list="selectableMinutes" item="minuteOption"
+            ><var:if condition="isCurrentMinute"
+              ><option var:value="minuteValue" selected="selected"
+                ><var:string value="minuteLabel"
+                  /></option></var:if
+              ><var:if condition="isCurrentMinute" const:negate="YES"
+              ><option var:value="minuteValue"
+                ><var:string value="minuteLabel"
+                  /></option></var:if>
+          </var:foreach
+            ></select>
+      </var:if
+
+        ><var:if condition="disabled" const:negate="YES">
+        <select var:shadow-value="hour" var:name="hourSelectId">
+          <var:foreach list="selectableHours" item="hourOption"
+            ><var:if condition="isCurrentHour"
+              ><option var:value="hourValue" selected="selected"
+                ><var:string value="hourLabel"
+                  /></option></var:if
+              ><var:if condition="isCurrentHour" const:negate="YES"
+              ><option var:value="hourValue"><var:string value="hourLabel"
+                  /></option></var:if>
+          </var:foreach
+            ></select>
+        <select var:shadow-value="minute" var:name="minuteSelectId">
+          <var:foreach list="selectableMinutes" item="minuteOption"
+            ><var:if condition="isCurrentMinute"
+              ><option var:value="minuteValue" selected="selected"
+                ><var:string value="minuteLabel"
+                  /></option></var:if
+              ><var:if condition="isCurrentMinute" const:negate="YES"
+              ><option var:value="minuteValue"
+                ><var:string value="minuteLabel"
+                  /></option></var:if>
+          </var:foreach
+            ></select>
+      </var:if>
+    </var:if>
+  </span>
diff --git a/UI/Templates/UIxAclEditor.wox b/UI/Templates/UIxAclEditor.wox
new file mode 100644 (file)
index 0000000..f750aed
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:uix="OGo:uix"
+    xmlns:label="OGo:label"
+    className="UIxPageFrame"
+    title="title"
+    var:toolbar="toolbar"
+    const:popup="YES">
+
+    <form id="aclForm" const:href="saveAcls">
+      <div class="acls">
+        <input type="hidden" name="action" value="saveAcls" />
+        <input type="hidden" name="delegates" id="delegates" />
+        <input type="hidden" name="assistants" id="assistants" />
+        <label><var:string label:value="Owner:" />
+          <span class="value"><strong><var:string value="ownerCN" /></strong></span></label><br />
+        <var:component className="UIxContactSelector"
+          const:selectorId="userRoles"
+          const:hasCheckBoxes="YES"
+          const:checkBoxOnChange="return updateAclStatus(this);"
+          contacts="usersForFolder"
+          checkedBoxes="checkedUsers"
+          />
+        <span class="legend"><var:string label:value="(Unchecked = assistant, checked = delegate)" /></span><br />
+        <var:if condition="clientIsCalendar"
+          ><label id="freeBusyLabel"><input type="checkbox"
+              var:checked="publishInFreeBusy"
+              class="checkBox" name="freebusy" id="freebusy"
+              /><var:string label:value="Localizable/Publish the Free/Busy information"
+              /></label></var:if>
+      </div>
+    </form>
+  </var:component>
diff --git a/UI/Templates/UIxAppointmentEditor.wox b/UI/Templates/UIxAppointmentEditor.wox
deleted file mode 100644 (file)
index 831a21e..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component
-  xmlns="http://www.w3.org/1999/xhtml"
-  xmlns:var="http://www.skyrix.com/od/binding"
-  xmlns:const="http://www.skyrix.com/od/constant"
-  xmlns:uix="OGo:uix"
-  xmlns:label="OGo:label"
-  className="UIxPageFrame"
-  title="name"
->
-  <var:js-stringtable const:framework="SchedulerUI.SOGo"
-                      const:identifier="labels" />
-  
-  <form var:href="clientObject.baseURL" name="editform"
-        onsubmit="return validateAptEditor()">
-
-      <script language="JavaScript"> <!-- TODO: use a resource -->
-        <var:string value="jsCode" const:escapeHTML="NO" />
-      </script>
-
-      <table cellspacing="0" cellpadding="5" width="100%">
-        <tr>
-          <td>
-            <table cellpadding="0" cellspacing="0" width="100%">
-              <tr>
-                <td width="5"/>
-                <td class="window_label">
-                  <var:string label:value="Appointment editor" /></td>
-                <td width="36" align="right" valign="center">
-                  <var:component className="UIxWinClose" />
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <var:if condition="hasErrorText">
-             <div style="background-color: #AA0000;">
-               <var:string value="errorText" />
-              </div>
-              <hr />
-            </var:if>
-
-            <table border="0" cellpadding="2" cellspacing="0" width="100%"
-                   bgcolor="#e8e8e0"
-            >
-              <tr>
-                <td align="left" colspan="2">
-                  <span class="aptview_title">
-                    <var:string label:value="Appointment on" /> 
-                    <var:string formatter="titleDateFormatter" 
-                                value="aptStartDate" /></span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Start time" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:component className="UIxDatePickerScript" />
-                    <var:component className="UIxTimeDateControl"
-                                   const:controlID="startTime"
-                                   date="aptStartDate"
-                    />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="End time" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:component className="UIxTimeDateControl"
-                                   const:controlID="endTime"
-                                   date="aptEndDate"
-                    />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Title" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <input type="text" name="summary" id="summary"
-                           const:size="40" var:value="title" />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Location" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <input type="text" name="location" const:size="40"
-                           var:value="location" />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Priority" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:popup list="priorities" item="item"
-                               string="itemPriorityText" selection="priority"/>
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Cycle" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <table>
-                      <tr>
-                        <td>
-                          <var:popup list="cycles" item="item"
-                                     label:string="$cycleLabel"
-                                     selection="cycle"
-                                     const:onChange="selectHasCycle(this);"
-                          />
-                        </td>
-                        <td id="cycle_end_label"
-                            var:style="initialCycleVisibility"
-                        ><var:string label:value="Cycle End"
-                                        const:style="aptview_text"
-                            />:</td>
-                        <td id="cycle_end_mode"
-                            var:style="initialCycleVisibility"
-                        >
-                          <var:popup list="cycleEnds" item="item"
-                                     label:string="$item" value="item"
-                                     selection="cycleEnd"
-                                     const:onChange="selectCycleEnd(this);"
-                                     const:id="cycle_end_mode_selection"
-                          />
-                        </td>
-                        <td id="cycle_end_until"
-                            var:style="initialCycleEndUntilVisibility"
-                        >
-                          <var:component className="UIxTimeDateControl"
-                                         date="cycleUntilDate"
-                                         label="foo"
-                                         const:controlID="cycleUntilDate"
-                                         const:displayTimeControl="NO"
-                          />
-                        </td>
-                      </tr>
-                    </table>
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Categories" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <var:checkbox-list list="categoryItems" item="item"
-                                       suffix="itemCategoryText"
-                                       selections="categories"
-                    />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Classification" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <input type="checkbox" var:selection="isPrivate"
-                           var:checked="isPrivate" />
-                    <var:string label:value="is private" />
-                  </span>
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <table border="0" cellpadding="2" cellspacing="0"
-                   width="100%" bgcolor="#e8e8e0"
-            >
-              <tr>
-                <td align="left" colspan="2">
-                  <span class="aptview_title">
-                    <var:string label:value="Search participants" /> 
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Participants" />:</span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <!-- use '1' instead of 'YES', otherwise breaks on OSX -->
-<!--
-                    <var:component className="AnaisAttendeeSelector"
-                                   const:selectorID="participant"
-                                   const:role="REQ-PARTICIPANT"
-                                   attendees="participants"
-                                   var:emailForUser="emailForUser"
-                                   var:cnForUser="cnForUser"
-                                   const:withCN="1"
-                                   const:withAddressBook="1"
-                    />
--->
-                    TODO: need attendee selector (AB)
-                  </span>
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <table border="0" cellpadding="2" cellspacing="0" width="100%"
-                   bgcolor="#e8e8e0"
-            >
-              <tr>
-                <td align="left" colspan="2">
-                  <span class="aptview_title">
-                    <var:string label:value="Search resources" />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Resources" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-<!--
-                    <var:component className="AnaisAttendeeSelector"
-                                   const:selectorID="resource"
-                                   const:role="NON-PARTICIPANT"
-                                   attendees="resources"
-                                   const:withCN="YES"
-                                   const:withAddressBook="YES"
-                    />
--->
-                    TODO: need attendee selector (AB)
-                  </span>
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-        <tr>
-          <td>
-            <table border="0" cellpadding="2" cellspacing="0" width="100%"
-                   bgcolor="#e8e8e0"
-            >
-              <tr>
-                <td align="left" colspan="2">
-                  <span class="aptview_title">
-                    <var:string label:value="Comment" />
-                  </span>
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right" width="15%">
-                  <span class="aptview_text">
-                    <var:string label:value="Comment" />:
-                  </span>
-                </td>
-                <td align="left" bgcolor="#FFFFF0">
-                  <span class="aptview_text">
-                    <textarea name="comment" rows="8" cols="80" wrap="physical"
-                              var:value="comment" />
-                  </span>
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-        <tr valign="top">
-          <td>
-            <span class="aptview_text">
-              <input type="checkbox"
-                     var:selection="checkForConflicts"
-                     var:checked="checkForConflicts"
-              /> <var:string label:value="check for conflicts" />
-            </span>
-          </td>
-        </tr>
-        <tr>
-          <td>
-              <input type="submit" label:value="Save" name="save:method" />
-              <span class="button_auto_env"
-              ><a href="../weekoverview"
-                  var:queryDictionary="queryParameters"
-                  class="button_auto"
-               ><var:string label:value="Cancel" /></a></span>
-              <var:if condition="isUIxDebugEnabled">
-                <input type="submit" value="Test" name="test:method" />
-              </var:if>
-          </td>
-        </tr>
-      </table>
-    <input type="hidden" name="ical" var:value="iCalString" />
-  </form>
-  <!--
-  <var:if condition="canEditApt" const:negate="YES">
-    Forbidden ... <var:redirect const:setURL="view" />
-  </var:if>
-  -->
-</var:component>
diff --git a/UI/Templates/UIxAppointmentPrintview.wox b/UI/Templates/UIxAppointmentPrintview.wox
deleted file mode 100644 (file)
index 416b542..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:uix="OGo:uix"
-               xmlns:label="OGo:label"
-               className="UIxPrintPageFrame"
-               title="title"
->
-  <table border="1" cellspacing="0" cellpadding="5" width="100%">
-    <tr>
-      <td colspan="2" align="center">
-        <h1 class="dayprintview"><var:string value="title" /></h1>
-      </td>
-    </tr>
-    <tr>
-      <td valign="top" width="100%">
-        <table width="100%" border="0" cellpadding="4" cellspacing="0">
-          <!-- general appointment info -->
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Title" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="appointment.summary"
-                          var:style="aptStyle"
-              />
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Location" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="appointment.location"
-                          var:style="aptStyle"
-              />
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Priority" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string label:value="$appointment.priorityLabelKey" />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td valign="top" width="100%">
-        <table width="100%" border="1" cellpadding="4" cellspacing="0">
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Start time" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="startTime"
-                          formatter="dateFormatter"
-                          var:style="aptStyle"
-              />
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="End time" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="endTime"
-                          formatter="dateFormatter"
-                          var:style="aptStyle"
-              />
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Categories" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="categoriesAsString" />
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Resources" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="resourcesAsString"
-                          const:escapeHTML="NO"
-              />
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Organizer" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="appointment.organizer.cnForDisplay" />
-            </td>
-          </tr>
-          <tr valign="top">
-            <td align="right" width="15%" class="aptview_text">
-              <var:string label:value="Comment" />:
-            </td>
-            <td align="left" class="aptview_text">
-              <var:string value="appointment.comment" const:insertBR="1" />
-            </td>
-          </tr>
-        </table>
-        <table width="100%" border="1" cellpadding="4" cellspacing="0">
-          <tr valign="top">
-            <td align="left" class="aptview_title">
-                <var:string label:value="Name" />
-            </td>
-            <td align="left" class="aptview_title">
-                <var:string label:value="Email" />
-            </td>
-          </tr>
-          <var:foreach list="appointment.participants"
-                       item="attendee"
-          >
-            <tr valign="top">
-              <td align="left" class="aptview_text">
-                  <var:string value="attendee.cnForDisplay" />
-              </td>
-              <td align="left" class="aptview_text">
-                  <a var:href="attendee.email"
-                  ><var:string value="attendee.rfc822Email" /></a>
-              </td>
-            </tr>
-          </var:foreach>
-        </table>
-      </td>
-    </tr>
-    <var:if condition="isUIxDebugEnabled">
-      <tr>
-        <td colspan="2">
-          appointment: <var:string value="appointment" />
-          <br />
-          isMyApt: <var:string value="isMyApt" />
-          <br />
-          aptStyle: <var:string value="aptStyle" />
-          <br />
-          activeUser: <var:string value="context.activeUser"/>
-          <br />
-          email for user: <var:string value="emailForUser" />
-          <br />
-        </td>
-      </tr>
-    </var:if>
-  </table>
-</var:component>
diff --git a/UI/Templates/UIxAppointmentView.wox b/UI/Templates/UIxAppointmentView.wox
deleted file mode 100644 (file)
index cf7be5a..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:uix="OGo:uix"
-               xmlns:label="OGo:label"
-               className="UIxPageFrame"
-               title="name"
->
-  <table cellspacing="0" cellpadding="5" width="100%">
-    <tr>
-      <td>
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="window_label"
-            ><var:string label:value="Appointment viewer" /></td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose" />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-
-    <tr>
-      <td>
-        <table border="0" cellpadding="2" width="100%" cellspacing="0">
-          <tr bgcolor="#e8e8e0">
-            <td align="left">
-              <span class="aptview_title"
-              ><var:string value="startTime"
-                           formatter="dateFormatter"
-               /></span>
-            </td>
-            <td align="right" >
-              <table border='0' cellpadding='0' cellspacing='1'>
-                <tr>
-                  <td class="button_auto_env" nowrap="true"
-                      valign='middle' align='center'>
-                    <!--<a class="button_auto"
-                       href="printview"
-                       var:queryDictionary="queryParameters"
-                       target="SOGoPrintView"
-                    ><var:string label:value="printview" /></a>-->
-                  </td>
-                  <var:if condition="canEditApt">
-                    <td class="button_auto_env" nowrap="true"
-                        valign='middle' align='center'>
-                      <a class="button_auto"
-                         href="edit"
-                         var:queryDictionary="queryParameters"
-                      ><var:string label:value="edit" /></a>
-                    </td>
-                    <td class="button_auto_env" nowrap="true"
-                        valign='middle' align='center'>
-                      <a class="button_auto"
-                         href="delete"
-                         var:queryDictionary="queryParameters"
-                      ><var:string label:value="delete" /></a>
-                    </td>
-                  </var:if>
-                </tr>
-              </table>
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td valign="top" width="100%">
-        <table width="100%" border="0" cellpadding="4" cellspacing="0">  
-          <!-- general appointment info -->
-          <var:if condition="canAccessApt">  
-            <tr valign="top">
-              <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
-                <var:string label:value="Title" />:
-              </td>
-              <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                <var:string value="appointment.summary" />
-              </td>
-            </tr>
-            <tr valign="top">
-              <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
-                <var:string label:value="Location" />:
-              </td>
-              <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                <var:string value="appointment.location" />
-              </td>
-            </tr>
-            <tr valign="top">
-              <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
-                <var:string label:value="Priority" />:
-              </td>
-              <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                <var:string label:value="$appointment.priorityLabelKey" />
-              </td>
-            </tr>
-          </var:if>
-          <tr valign="top">
-              <td align="right" width="15%" bgcolor="#E8E8E0" class="aptview_text">
-                <var:string label:value="Classification" />:
-              </td>
-              <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                <var:if condition="appointment.isPublic">Public</var:if>
-                <var:if condition="appointment.isPublic"
-                        const:negate="YES"
-                >Private</var:if>
-              </td>
-            </tr>
-        </table>
-     </td>
-    </tr>
-    <tr>
-      <td valign="top" width="100%">
-        <uix:tabview var:selection="tabSelection"
-                     const:tabStyle="tab"
-                     const:selectedTabStyle="tab_selected"
-                     const:bodyStyle="tabview_body"
-        >
-          <uix:tab const:key="attributes"
-                   label:label="attributes"
-                   var:href="attributesTabLink"
-          >
-            <table width="100%" border="0" cellpadding="4" cellspacing="0">
-              <tr valign="top">
-                <td align="right"
-                    width="15%"
-                    bgcolor="#E8E8E0"
-                    class="aptview_text"
-                >
-                  <var:string label:value="Start time" />:
-                </td>
-                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                  <var:string value="startTime"
-                              formatter="dateFormatter"
-                  />
-                </td>
-              </tr>
-              <tr valign="top">
-                <td align="right"
-                    width="15%"
-                    bgcolor="#E8E8E0"
-                    class="aptview_text"
-                >
-                  <var:string label:value="End time" />:
-                </td>
-                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                  <var:string value="endTime"
-                              formatter="dateFormatter"
-                  />
-                </td>
-              </tr>
-              <var:if condition="canAccessApt">  
-                <tr valign="top">
-                  <td align="right"
-                      width="15%"
-                      bgcolor="#E8E8E0"
-                      class="aptview_text"
-                  >
-                    <var:string label:value="Categories" />:
-                  </td>
-                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                    <var:string value="categoriesAsString" />
-                  </td>
-                </tr>
-                <!-- Resources removed for v0.8
-                <tr valign="top">
-                  <td align="right"
-                      width="15%"
-                      bgcolor="#E8E8E0"
-                      class="aptview_text"
-                  >
-                    <var:string label:value="Resources" />:
-                  </td>
-                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                    <var:string value="resourcesAsString"
-                                const:escapeHTML="NO"
-                    />
-                  </td>
-                </tr>
-                -->
-                <tr valign="top">
-                  <td align="right"
-                      width="15%"
-                      bgcolor="#E8E8E0"
-                      class="aptview_text"
-                  >
-                    <var:string label:value="Organizer" />:
-                  </td>
-                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                    <var:string value="appointment.organizer.cnForDisplay" />
-                  </td>
-                </tr>
-                <tr valign="top">
-                  <td align="right"
-                      width="15%"
-                      bgcolor="#E8E8E0"
-                      class="aptview_text"
-                  >
-                    <var:string label:value="Comment" />:
-                  </td>
-                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                    <var:string value="appointment.comment" const:insertBR="1" />
-                  </td>
-                </tr>
-              </var:if>
-            </table>
-          </uix:tab>
-          <var:if condition="canAccessApt">    
-  
-            <uix:tab const:key="participants"
-                     label:label="participants"
-                     var:href="participantsTabLink"
-            >
-              <table width="100%" border="0" cellpadding="4" cellspacing="0">
-              <tr valign="top">
-                <td align="left" bgcolor="#E8E8E0" class="aptview_title">
-                  <var:string label:value="Name" />
-                </td>
-                <td align="left" bgcolor="#E8E8E0" class="aptview_title">
-                  <var:string label:value="Email" />
-                </td>
-                <td align="left"
-                    bgcolor="#E8E8E0"
-                    class="aptview_title"
-                    colspan="2"
-                >
-                  <var:string label:value="Status" />
-                </td>
-              </tr>
-              <var:foreach list="appointment.participants"
-                           item="attendee"
-              >
-                <tr valign="top">
-                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                    <var:string value="attendee.cnForDisplay" />
-                  </td>
-                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
-                    <a var:href="attendee.email"
-                    ><var:string value="attendee.rfc822Email" /></a>
-                  </td>
-                  <td align="left"
-                      bgcolor="#FFFFF0"
-                      class="aptview_text"
-                      var:colspan="attendeeStatusColspan"
-                  >
-                    <var:component className="UIxCalParticipationStatusView"
-                                   partStat="attendee.participationStatus"
-                    />
-                  </td>
-                  <var:if condition="isAttendeeActiveUser">
-                    <td align="left"
-                        bgcolor="#FFFFF0"
-                        class="button_auto_env"
-                    >
-                      <var:if condition="showAcceptButton">  
-                        <a href="accept"
-                           class="button_auto"
-                           _tab="participants"
-                        ><var:string label:value="accept" /></a>
-                      </var:if>
-                      <var:if condition="showRejectButton">
-                        <a href="decline"
-                           class="button_auto"
-                           _tab="participants"
-                        ><var:string label:value="decline" /></a>
-                      </var:if>
-                    </td>
-                  </var:if>
-                </tr>
-              </var:foreach>
-              </table>
-            </uix:tab>
-          </var:if>
-          <var:if condition="isUIxDebugEnabled">
-            <uix:tab const:key="debug"
-                     const:label="DEBUG"
-                     var:href="debugTabLink">
-              SOGo Server - <var:string value="name"/>
-              <br />
-              Client: <var:string value="clientObject"/>
-              <br />
-              Group:      <var:string value="clientObject.group"
-                          /><br />
-              Deletable:  <var:string value="clientObject.isDeletionAllowed"
-                          /><br />
-              Generation: <var:string value="clientObject.zlGenerationCount"
-                          /><br />
-              MsgClass:   <var:string value="clientObject.outlookMessageClass"
-                          /><br />
-    
-              <hr />
-              As iCal:<br />
-              <pre><var:string value="clientObject.iCalString"/></pre>
-    
-              <hr />
-              As Mail:<br />
-              <pre><var:string value="clientObject.iCalMailString"/></pre>
-    
-            </uix:tab>
-          </var:if>
-        </uix:tabview>
-      </td>
-    </tr>
-  </table>
-</var:component>
diff --git a/UI/Templates/UIxCalBackForthNavView.wox b/UI/Templates/UIxCalBackForthNavView.wox
deleted file mode 100644 (file)
index 7c86e8c..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<table xmlns="http://www.w3.org/1999/xhtml"
-       xmlns:var="http://www.skyrix.com/od/binding"
-       xmlns:const="http://www.skyrix.com/od/constant"
-       xmlns:rsrc="OGo:url"
-       border="0"
- >
-    <tr>
-        <td align="right" valign="middle">
-            <a var:href="^methodName" var:queryDictionary="^prevQueryParameters"><img rsrc:src="previous_week.gif" alt="previous" border="0"/></a>
-        </td>
-        <td align="right" valign="middle" class="button_auto_env">
-            <a var:href="^methodName" var:queryDictionary="^currentQueryParameters" class="button_auto"><var:string value="^label" escapeHTML="NO" /></a>
-        </td>
-        <td align="right" valign="middle">
-            <a var:href="^methodName" var:queryDictionary="^nextQueryParameters"><img rsrc:src="next_week.gif" alt="next" border="0"/></a>
-        </td>
-    </tr>
-</table>
\ No newline at end of file
diff --git a/UI/Templates/UIxCalDateLabel.wox b/UI/Templates/UIxCalDateLabel.wox
deleted file mode 100644 (file)
index 4a0c93a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      const:class="window_label"
-><var:string value="label" const:escapeHTML="NO" /></span>
\ No newline at end of file
diff --git a/UI/Templates/UIxCalDayPrintview.wox b/UI/Templates/UIxCalDayPrintview.wox
deleted file mode 100644 (file)
index 371e2e1..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               className="UIxPrintPageFrame"
-               title="title"
->
-  <table border="1" cellpadding="5" cellspacing="0" width="100%">
-    <tr>
-      <td colspan="2" align="center">
-        <h1 class="dayprintview"><var:string value="title" /></h1>
-        <h2 class="dayprintview"
-        ><var:string value="formattedCalendarUIDs"/></h2>
-      </td>
-    </tr>
-    <tr valign="top">
-      <var:if condition="hasHolidayInfo">
-        <tr>
-          <td colspan="2" align="left">
-            <b><var:string value="holidayInfo.title" /></b>
-          </td>
-        </tr>
-      </var:if>
-      <var:foreach list="allDayApts" item="appointment">
-        <tr>
-          <td width="10%">
-            <var:entity name="nbsp" />
-          </td>
-          <td class="dayprintview_content">
-            <var:foreach list="allDayApts" item="appointment">
-              <var:string value="appointment"
-                          formatter="aptFormatter"
-                          const:escapeHTML="NO"
-              />
-              <br />
-            </var:foreach>
-          </td>
-        </tr>
-      </var:foreach>
-      <var:foreach list="dateRange" item="currentDate">
-        <tr>
-          <td width="10%" rowspan="minRequiredRowSpan" class="dayprintview_time">
-            <var:string value="currentDate"
-                        const:dateformat="%H:%M"
-            />
-          </td>
-          <var:foreach list="aptsForCurrentDate" item="appointment">
-            <td class="dayprintview_content">
-              <var:string value="appointment"
-                          formatter="aptFormatter"
-                          const:escapeHTML="NO"
-                          style="aptStyle"
-              />
-            </td>
-            <var:if condition="minRequiredRowSpan"
-                    const:value="1"
-                    const:negate="YES"
-            >
-            </var:if>
-          </var:foreach>
-          <var:if condition="hasNoAptsForCurrentDate">
-            <td><var:entity const:name="nbsp" /></td>
-          </var:if>
-        </tr>
-      </var:foreach>
-    </tr>
-  </table>
-</var:component>
diff --git a/UI/Templates/UIxCalInlineAptView.wox b/UI/Templates/UIxCalInlineAptView.wox
deleted file mode 100644 (file)
index 8833223..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
->
-  <var:if condition="appointment.isRecurrentEvent">
-    <!-- TODO: maxime needs to provide an image instead! -->
-    <var:string const:value="[R]" style="style" />
-  </var:if>
-  <var:if condition="canAccess">
-    <var:if condition="appointment.ispublic" const:negate="YES">
-      <img rsrc:src="apt_icon_private.gif" />
-    </var:if>
-    <a var:href="url"
-       var:title="tooltip"
-       var:queryDictionary="queryDictionary"
-    ><small><var:string value="title"
-                        const:escapeHTML="NO"
-                        style="style"
-            /></small></a>
-  </var:if>
-  <var:if condition="canAccess" const:negate="YES">
-    <img rsrc:src="apt_icon_private.gif" />
-    <small><var:string value="title"
-                       const:escapeHTML="NO"
-                       style="style"
-           /></small>
-  </var:if>
-</span>
\ No newline at end of file
diff --git a/UI/Templates/UIxCalMonthPrintview.wox b/UI/Templates/UIxCalMonthPrintview.wox
deleted file mode 100644 (file)
index 64da798..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               className="UIxPrintPageFrame"
-               title="title"
->
-  <var:month-overview list="appointments"
-                      item="appointment"
-                      currentDay="currentDay"
-                      index="dayIndex"
-                      year="year"
-                      month="month"
-                      const:startDateKey="startDate"
-                      const:endDateKey="endDate"
-                      const:class="monthprintview"
-                      contentStyle="contentStyle"
-                      const:cellpadding="5"
-                      const:cellspacing="0"
-                      const:border="1"
-                      const:width="100%"
-  >
-    <var:month-label const:orientation="header"
-                     const:class="monthprintview_header"
-    >
-      <h1 class="monthprintview_header"><var:string value="title" /></h1>
-      <h2 class="monthprintview_header"
-      ><var:string value="formattedCalendarUIDs" /></h2>
-    </var:month-label>
-    <var:month-info>
-      <var:if condition="hasHolidayInfo">
-        <var:string value="holidayInfo"
-                    const:class="monthprintview_holidayinfo"
-        />
-      </var:if>
-      <var:foreach list="allDayApts" item="appointment">
-        <var:string value="shortTextForApt"
-                    const:escapeHTML="NO"
-        />
-        <br />
-      </var:foreach>
-    </var:month-info>
-    <var:month-label const:orientation="top"
-                     dayOfWeek="dayOfWeek"
-                     const:class="monthprintview_title"
-    >
-      <var:string value="localizedDayOfWeekName"/>
-    </var:month-label>
-    <var:month-label const:orientation="left"
-                     weekOfYear="weekOfYear"
-                     const:class="monthprintview_week"
-    >
-      <var:string value="weekOfYear"/>
-    </var:month-label>
-    <var:month-title class="contentStyle">
-      <var:string value="currentDay.dayOfMonth"/>
-    </var:month-title>
-    <var:month>
-      <span const:class="monthprintview_apt">
-        <var:string value="shortTextForApt"
-                    const:escapeHTML="NO"
-        />
-        <br />
-      </span>
-    </var:month>
-  </var:month-overview>
-</var:component>
diff --git a/UI/Templates/UIxCalWeekChartview.wox b/UI/Templates/UIxCalWeekChartview.wox
deleted file mode 100644 (file)
index 2a58230..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name">
-
-  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
-    <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle"><var:component className="UIxCalDateLabel"
-                                                startDate="startDate"
-                                                endDate="endDate"
-                                                const:selection="week"
-                                 /></td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose" />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td id="skywinbodycell" class="wincontent">
-        <table border="0" cellpadding="0" cellspacing="0" width="100%">
-          <tr bgcolor="#e8e8e0">
-            <td align="left">
-              <var:component className="UIxCalBackForthNavView"
-                             methodName="ownMethodName"
-                             prevQueryParameters="prevWeekQueryParameters"
-                             currentQueryParameters="todayQueryParameters"
-                             nextQueryParameters="nextWeekQueryParameters"
-                             label:label="this week"
-              />
-            </td>
-            <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector"
-                             calendarUIDs="clientObject.calendarUIDs"
-              />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td id="skywinbodycell" class="wincontent">
-        <table border="0" width="100%" cellpadding="0" cellspacing="0">
-          <tr>
-            <td colspan="2">
-              <var:component className="UIxCalSelectTab"
-                             const:selection="week"
-                             currentDate="selectedDate"
-              >
-                <table border="0" cellpadding="4" width="100%" cellspacing="2">
-                  <tr>
-                    <td width="1%" align="left" valign="middle" bgcolor="#e8e8e0">
-                      <table border='0' cellpadding='0' cellspacing='0'>
-                        <tr>
-                          <td><a href="weekoverview"
-                               var:queryDictionary="queryParameters"
-                            ><img rsrc:src="icon_view_overview.gif"
-                                                        label:title="Overview"
-                                                        label:alt="Overview"
-                                                        border="0"
-                                                        valign="top"
-                                                   /></a></td>
-                          <td><img rsrc:src="icon_view_chart_inactive.gif"
-                                   label:title="Chart"
-                                   label:alt="Chart"
-                                   border="0"
-                                   valign="top"
-                              /></td>
-                          <td><a href="weeklistview"
-                                 var:queryDictionary="queryParameters"
-                              ><img rsrc:src="icon_view_list.gif"
-                                                          label:title="List"
-                                                          label:alt="List"
-                                                          border="0"
-                                                          valign="top"
-                                                     /></a></td>
-                          <td>
-                            <a href="weekcolumnsview"
-                               var:queryDictionary="queryParameters"
-                            ><img rsrc:src="icon_view_columns.gif"
-                                                           label:title="Columns"
-                                                           label:alt="Columns"
-                                                           border="0"
-                                                           valign="top"
-                                                      /></a></td>
-                        </tr>
-                      </table>
-                    </td>
-                    <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
-                      <a var:href="ownMethodName"
-                         class="button_auto"
-                         var:queryDictionary="toggleShowRejectedAptsQueryParameters"
-                         label:string="$toggleShowRejectedAptsLabel"
-                      />
-                    </td>
-                    <td align="right" bgcolor="#e8e8e0">
-                      <table border='0' cellpadding='0' cellspacing='1'>
-                        <tr>
-                          <td class="button_auto_env"
-                              nowrap="true"
-                              valign='middle'
-                              align='center'
-                          >
-                            <!--<a class="button_auto"
-                               href="weekprintview"
-                               var:queryDictionary="queryParameters"
-                               target="SOGoPrintView"
-                            ><var:string label:value="printview" /></a>-->
-                          </td>
-                          <td class="button_auto_env"
-                              nowrap="true"
-                              valign='middle'
-                              align='center'
-                          >
-                            <a class="button_auto"
-                               href="proposal"
-                               var:queryDictionary="queryParameters"
-                            ><var:string label:value="proposal" /></a>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                  </tr>
-                </table>
-                <var:vspan-matrix list="appointments"
-                                  item="appointment"
-                                  rows="hours"
-                                  row="hour"
-                                  columns="columns"
-                                  column="day"
-                                  itemActive="isItemActive"
-                                  isRowActive="isRowActive"
-                                  const:rowHeight="8"
-                                  const:width="100%"
-                                  const:border="0"
-                                  const:cellpadding="0"
-                                  const:cellspacing="2"
-                >
-                  <var:matrix-label const:elementName="td"
-                                    const:position="top"
-                                    const:align="center"
-                  >
-                    <table cellpadding="5"
-                           cellspacing="0"
-                           width="100%"
-                           border="0"
-                           var:class="titleStyle"
-                    >
-                      <tr>
-                        <td align="left" valign="top">
-                          <a href="daychartview"
-                             var:queryDictionary="currentDayQueryParameters"
-                             class="weekoverview_title_daylink"
-                             ><var:string value="currentDay.dayOfMonth"
-                                          const:numberformat="02"
-                              /></a>
-                        </td>
-                        <td align="center" valign="top" width="97%">
-                          <var:string value="currentDayName" /><br />
-                            [<a href="new"
-                                var:queryDictionary="currentDayQueryParameters"
-                                class="weekoverview_title_newlink"
-                             ><var:string label:value="new" /></a>]
-                        </td>
-                      </tr>
-                    </table>
-                  </var:matrix-label>
-                                        
-                  <var:matrix-label const:elementName="td"
-                                    const:position="left"
-                                    const:width="2"
-                                    const:height="20"
-                                    const:bgcolor="#d6d6ce"
-                  >
-                    <span class="dayoverview_content_time_link">
-                      <var:string value="currentDate"
-                                  const:dateformat="%H:%M"
-                      />
-                    </span>
-                  </var:matrix-label>
-                  <!-- TODO: use css instead! -->
-                  <var:matrix-empty const:elementName="td"
-                                    const:bgcolor="#efefe7"
-                  ><var:entity const:name="nbsp"
-                   />
-                  </var:matrix-empty>
-                  <!-- TODO: use css instead! -->
-                  <var:matrix-cell const:elementName="td"
-                                   const:bgcolor="#d6d6ce"
-                                   const:align="top"
-                  >
-                    <span class="dayoverview_content_time_link">
-                      <var:component className="UIxCalInlineAptView"
-                                     appointment="appointment"
-                                     formatter="aptFormatter"
-                                     tooltipFormatter="aptTooltipFormatter"
-                                     url="appointmentViewURL"
-                                     style="aptStyle"
-                                     queryDictionary="currentDayQueryParameters"
-                                     referenceDate="currentDay"
-                                     canAccess="canAccessApt"
-                      />
-                    </span>
-                  </var:matrix-cell>
-                </var:vspan-matrix>
-              </var:component>
-            </td>
-          </tr>
-          <tr bgcolor="#F5F5E9">
-            <td align="left" width="10"><var:entity const:name="nbsp"/></td>
-            <td align="right"
-            ><img border="0"
-                  alt=""
-                  rsrc:src="corner_right.gif"
-             /></td>
-          </tr>
-          <tr>
-            <td colspan="2" bgcolor="#F5F5E9">
-              <table border="0" width="100%" cellpadding="10" cellspacing="0">
-                <tr />
-              </table>
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-  </table>
-</var:component>
diff --git a/UI/Templates/UIxCalWeekColumnsview.wox b/UI/Templates/UIxCalWeekColumnsview.wox
deleted file mode 100644 (file)
index 1a97f86..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name">
-
-  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" width="100%">
-    <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle"><var:component className="UIxCalDateLabel"
-                                                startDate="startDate"
-                                                endDate="endDate"
-                                                const:selection="week"
-                                 /></td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose" />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td id="skywinbodycell" class="wincontent">
-        <table border="0" cellpadding="0" cellspacing="0" width="100%">
-          <tr bgcolor="#e8e8e0">
-            <td align="left">
-              <var:component className="UIxCalBackForthNavView"
-                             methodName="ownMethodName"
-                             prevQueryParameters="prevWeekQueryParameters"
-                             currentQueryParameters="todayQueryParameters"
-                             nextQueryParameters="nextWeekQueryParameters"
-                             label:label="this week"
-              />
-            </td>
-            <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector"
-                             calendarUIDs="clientObject.calendarUIDs"
-              />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td id="skywinbodycell" class="wincontent">
-        <table border="0" width="100%" cellpadding="0" cellspacing="0">
-          <tr>
-            <td colspan="2">
-              <var:component className="UIxCalSelectTab"
-                             const:selection="week"
-                             currentDate="selectedDate"
-              >
-                <table border="0" cellpadding="4" width="100%" cellspacing="2">
-                  <tr>
-                    <td width="1%"
-                        align="left"
-                        valign="middle"
-                        bgcolor="#e8e8e0"
-                    >
-                      <table border='0' cellpadding='0' cellspacing='0'>
-                       <tr>
-                          <td><a href="weekoverview"
-                                 var:queryDictionary="queryParameters"
-                              ><img rsrc:src="icon_view_overview.gif"
-                                                          label:title="Overview"
-                                                          label:alt="Overview"
-                                                          border="0"
-                                                          valign="top"
-                                                     /></a></td>
-                          <td><a href="weekchartview"
-                                 var:queryDictionary="queryParameters"
-                              ><img rsrc:src="icon_view_chart.gif"
-                                                           label:title="Chart"
-                                                           label:alt="Chart"
-                                                           border="0"
-                                                           valign="top"
-                                                      /></a></td>
-                          <td><a href="weeklistview"
-                                 var:queryDictionary="queryParameters"
-                              ><img rsrc:src="icon_view_list.gif"
-                                                          label:title="List"
-                                                          label:alt="List"
-                                                          border="0"
-                                                          valign="top"
-                                                     /></a></td>
-                          <td><img rsrc:src="icon_view_columns_inactive.gif"
-                                   label:title="Columns"
-                                   label:alt="Columns"
-                                   border="0"
-                                   valign="top"
-                              /> </td>
-                       </tr>
-                      </table>
-                    </td>
-                    <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
-                      <a var:href="ownMethodName"
-                         class="button_auto"
-                         var:queryDictionary="toggleShowRejectedAptsQueryParameters"
-                         label:string="$toggleShowRejectedAptsLabel"
-                      />
-                    </td>
-                    <td align="right" bgcolor="#e8e8e0">
-                      <table border='0' cellpadding='0' cellspacing='1'>
-                        <tr>
-                          <td class="button_auto_env"
-                              nowrap="true"
-                              valign='middle'
-                              align='center'
-                          >
-                            <!--<a class="button_auto"
-                               href="weekprintview"
-                               var:queryDictionary="queryParameters"
-                               target="SOGoPrintView"
-                            ><var:string label:value="printview" /></a>-->
-                          </td>
-                          <td class="button_auto_env"
-                              nowrap="true"
-                              valign="middle"
-                              align="center"
-                          >
-                            <a class="button_auto"
-                               href="proposal"
-                               var:queryDictionary="queryParameters"
-                            ><var:string label:value="proposal" /></a>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                  </tr>
-                </table>
-                <table width="100%">
-                  <tr valign="top">
-                    <td>
-                      <table>
-                        <tr>
-                          <td>
-                             <var:component className="UIxCalInlineMonthOverview"
-                                            selectedDate="thisMonth"
-                                            const:showYear="YES"
-                                            const:showWeekColumn="YES"
-                                            const:weekSelectionHref="weekcolumnsview"
-                                            const:style="weekcolumnsview_cal"
-                                            const:headerStyle="weekcolumnsview_cal_title"
-                                            const:weekStyle="weekcolumnsview_cal_week"
-                                            const:dayHeaderStyle="weekcolumnsview_cal_day_header"
-                                            const:dayBodyStyle="weekcolumnsview_cal_content"
-                                            const:todayBodyStyle="weekcolumnsview_cal_content_hilite"
-                                            const:inactiveDayBodyStyle="weekcolumnsview_cal_content_dimmed"
-                             />
-                          </td>
-                        </tr>
-                        <tr>
-                          <td>
-                             <var:component className="UIxCalInlineMonthOverview"
-                                            selectedDate="nextMonth"
-                                            const:showYear="YES"
-                                            const:showWeekColumn="YES"
-                                            const:weekSelectionHref="weekcolumnsview"
-                                            const:style="weekcolumnsview_cal"
-                                            const:headerStyle="weekcolumnsview_cal_title"
-                                            const:weekStyle="weekcolumnsview_cal_week"
-                                            const:dayHeaderStyle="weekcolumnsview_cal_day_header"
-                                            const:dayBodyStyle="weekcolumnsview_cal_content"
-                                            const:todayBodyStyle="weekcolumnsview_cal_content_hilite"
-                                            const:inactiveDayBodyStyle="weekcolumnsview_cal_content_dimmed"
-                             />
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                    <td width="100%">
-                      <var:weekcol-view list="appointments"
-                                        item="appointment"
-                                        weekStart="startDate"
-                                        dayIndex="dayIndex"
-                                        const:startDateKey="startDate"
-                                        const:endDateKey="endDate"
-                                        const:titleStyle="weekcolumnsview_title"
-                                        contentStyle="contentStyle"
-                                        const:class="weekcolumnsview"
-                                        const:width="100%"
-                                        const:contentColor="#e8e8e0"
-                                        const:cellpadding="0"
-                                        const:cellspacing="2"
-                                        const:hideWeekend="shouldHideWeekend"
-                      >
-                        <var:weekcol-title>
-                          <table cellpadding="0" width="100%" border="0" cellspacing="0"
-                                 var:class="titleStyle">
-                            <tr>
-                              <td align="left" valign="top">
-                                <a href="dayoverview"
-                                   var:queryDictionary="currentDayQueryParameters"
-                                   class="weekcolumnsview_title_daylink"
-                                   ><var:string value="currentDay.dayOfMonth" /></a>
-                              </td>
-                              <td align="center" valign="top" width="97%">
-                                <var:string value="currentDayName" /><br />
-                                  [<a href="new"
-                                      var:queryDictionary="currentDayQueryParameters"
-                                      class="weekcolumnsview_title_newlink"
-                                   ><var:string label:value="new" /></a>]
-                              </td>
-                            </tr>
-                          </table>
-                        </var:weekcol-title>
-                        <var:if condition="hasDayInfo">
-                          <var:weekcol-info>
-                            <var:if condition="hasHolidayInfo">
-                              <var:string value="holidayInfo" 
-                                        const:class="weekcolumnsview_holidayinfo" />
-                            </var:if>
-                            <var:foreach list="allDayApts" item="appointment">
-                              <var:component className="UIxCalInlineAptView"
-                                             appointment="appointment"
-                                             formatter="aptFormatter"
-                                             tooltipFormatter="aptTooltipFormatter"
-                                             url="appointmentViewURL"
-                                             style="aptStyle"
-                                             queryDictionary="currentDayQueryParameters"
-                                             referenceDate="currentDay"
-                                             canAccess="canAccessApt"
-                              />
-                              <br />
-                            </var:foreach>
-                          </var:weekcol-info>
-                        </var:if>
-                        <var:weekcol>
-                          <var:component className="UIxCalInlineAptView"
-                                         appointment="appointment"
-                                         formatter="aptFormatter"
-                                         tooltipFormatter="aptTooltipFormatter"
-                                         url="appointmentViewURL"
-                                         style="aptStyle"
-                                         queryDictionary="currentDayQueryParameters"
-                                         referenceDate="currentDay"
-                                         canAccess="canAccessApt"
-                          />
-                          <br />
-                        </var:weekcol>
-                      </var:weekcol-view>
-                    </td>
-                  </tr>
-                </table>
-              </var:component>
-            </td>
-          </tr>
-          <tr bgcolor="#F5F5E9">
-            <td align="left" width="10"><var:entity const:name="nbsp"/></td>
-            <td align="right"><img border="0"
-                                   alt=""
-                                   rsrc:src="corner_right.gif"
-                              /></td>
-          </tr>
-          <tr>
-            <td colspan="2" bgcolor="#F5F5E9">
-              <table border="0" width="100%" cellpadding="10" cellspacing="0">
-                <tr />
-              </table>
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-  </table>
-  <!--
-  <hr />
-  <var:string value="thisWeekQueryParameters" />
-  -->
-  <!--
-  <hr/>
-    
-    Appointments: 
-    <var:component className="UIxAptTableView" appointments="appointments"/>
-  -->
-    <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
-
-</var:component>
diff --git a/UI/Templates/UIxCalWeekListview.wox b/UI/Templates/UIxCalWeekListview.wox
deleted file mode 100644 (file)
index ec9aea4..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name"
->
-  <table id="skywintable"
-         class="wintable"
-         cellspacing="0"
-         cellpadding="5"
-         width="100%"
-  >
-    <tr>
-      <td class="wintitle">
-        <table cellpadding="0" cellspacing="0" width="100%">
-          <tr>
-            <td width="5"/>
-            <td class="wintitle"><var:component className="UIxCalDateLabel"
-                                                startDate="startDate"
-                                                endDate="endDate"
-                                                const:selection="week"
-                                 /></td>
-            <td width="36" align="right" valign="center">
-              <var:component className="UIxWinClose" />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td id="skywinbodycell" class="wincontent">
-        <table border="0" cellpadding="0" cellspacing="0" width="100%">
-          <tr bgcolor="#e8e8e0">
-            <td align="left">
-              <var:component className="UIxCalBackForthNavView"
-                             methodName="ownMethodName"
-                             prevQueryParameters="prevWeekQueryParameters"
-                             currentQueryParameters="todayQueryParameters"
-                             nextQueryParameters="nextWeekQueryParameters"
-                             label:label="this week"
-              />              
-            </td>
-            <td align="right" valign="middle" width="80%">
-              <var:component className="AnaisUidSelector"
-                             calendarUIDs="clientObject.calendarUIDs"
-              />
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-    <tr>
-      <td id="skywinbodycell" class="wincontent">
-        <table border="0" width="100%" cellpadding="0" cellspacing="0">
-          <tr>
-            <td colspan="2">
-              <var:component className="UIxCalSelectTab"
-                             const:selection="week"
-                             currentDate="selectedDate"
-              >
-                <table border="0"
-                       cellpadding="4"
-                       width="100%"
-                       cellspacing="2"
-                >
-                  <tr>
-                    <td width="1%"
-                        align="left"
-                        valign="middle"
-                        bgcolor="#e8e8e0"
-                    >
-                      <table border='0' cellpadding='0' cellspacing='0'>
-                       <tr>
-                          <td><a href="weekoverview"
-                                 var:queryDictionary="queryParameters"
-                              ><img rsrc:src="icon_view_overview.gif"
-                                                          label:title="Overview"
-                                                          label:alt="Overview"
-                                                          border="0"
-                                                          valign="top"
-                                                     /></a></td>
-                          <td><a href="weekchartview"
-                                 var:queryDictionary="queryParameters"
-                              ><img rsrc:src="icon_view_chart.gif"
-                                                           label:title="Chart"
-                                                           label:alt="Chart"
-                                                           border="0"
-                                                           valign="top"
-                                                      /></a></td>
-                          <td><img rsrc:src="icon_view_list_inactive.gif"
-                                   label:title="List"
-                                   label:alt="List"
-                                   border="0"
-                                   valign="top"
-                              /></td>
-                          <td>
-                            <a href="weekcolumnsview"
-                               var:queryDictionary="queryParameters"
-                            ><img rsrc:src="icon_view_columns.gif"
-                                                           label:title="Columns"
-                                                           label:alt="Columns"
-                                                           border="0"
-                                                           valign="top"
-                                                      /></a></td>
-                       </tr>
-                      </table>
-                    </td>
-                    <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
-                      <a var:href="ownMethodName"
-                         class="button_auto"
-                         var:queryDictionary="toggleShowRejectedAptsQueryParameters"
-                         label:string="$toggleShowRejectedAptsLabel"
-                      />
-                    </td>
-                    <td align="right" bgcolor="#e8e8e0">
-                      <table border='0' cellpadding='0' cellspacing='1'>
-                        <tr>
-                          <td class="button_auto_env" nowrap="true" valign='middle' 
-                              align='center'>
-                            <!--<a class="button_auto"
-                               href="weekprintview"
-                               var:queryDictionary="queryParameters"
-                               target="SOGoPrintView"
-                            ><var:string label:value="printview" /></a>-->
-                          </td>
-                          <td class="button_auto_env" nowrap="true" valign='middle' 
-                              align='center'>
-                            <a class="button_auto"
-                               href="proposal"
-                               var:queryDictionary="queryParameters"
-                            ><var:string label:value="proposal" /></a>
-                          </td>
-                        </tr>
-                      </table>
-                    </td>
-                  </tr>
-                </table>
-          
-                <var:hspan-matrix list="appointments"
-                                  item="appointment"
-                                  rows="uids"
-                                  row="currentUid"
-                                  columns="columns"
-                                  column="column"
-                                  itemActive="isItemActive"
-                                  isRowActive="isRowActive"
-                                  const:rowHeight="8"
-                                  const:width="100%"
-                                  const:border="0"
-                                  const:cellpadding="0"
-                                  const:cellspacing="2"
-                >
-                  <var:matrix-label const:elementName="td"
-                                    const:position="top"
-                                    const:align="center"
-                                    span="columnsPerDay"
-                  >
-                    <table cellpadding="2"
-                           cellspacing="0"
-                           width="100%"
-                           border="0"
-                           var:class="titleStyle"
-                    >
-                      <tr>
-                        <td align="left" valign="top">
-                          <a href="daylistview"
-                             var:queryDictionary="currentDayQueryParameters"
-                             class="weekoverview_title_daylink"
-                             ><var:string value="currentDay.dayOfMonth"
-                                          const:numberformat="02"
-                              /></a>
-                        </td>
-                        <td align="center" valign="top" width="97%">
-                          <var:string value="currentDayName" /><br />
-                            [<a href="new"
-                                var:queryDictionary="currentDayQueryParameters"
-                                class="weekoverview_title_newlink"
-                             ><var:string label:value="new" /></a>]
-                        </td>
-                      </tr>
-                    </table>
-                  </var:matrix-label>
-                                        
-                  <var:matrix-label const:elementName="td"
-                                    const:position="left"
-                                    const:bgcolor="#d6d6ce"
-                                    const:width="100"
-                  >
-                    <var:string value="cnForCurrentUid"
-                                const:style="dayoverview_content_time_link"
-                    />
-                  </var:matrix-label>
-                  <!-- TODO: use css instead! -->
-                  <var:matrix-empty const:elementName="td"
-                                    const:bgcolor="#efefe7"
-                  ><var:entity const:name="nbsp"
-                   />
-                  </var:matrix-empty>
-                  <var:matrix-label const:elementName="td"
-                                    const:position="bottom"
-                  >
-                    <img rsrc:src="invisible_space_2.gif" />
-                  </var:matrix-label>
-                  <!-- TODO: use css instead! -->
-                  <var:matrix-cell const:elementName="td"
-                                   const:bgcolor="#d6d6ce"
-                                   const:align="top"
-                  >
-                    <span class="dayoverview_content_time_link">
-                      <var:component className="UIxCalInlineAptView"
-                                     appointment="appointment"
-                                     formatter="aptFormatter"
-                                     tooltipFormatter="aptTooltipFormatter"
-                                     url="appointmentViewURL"
-                                     style="aptStyle"
-                                     queryDictionary="currentDayQueryParameters"
-                                     canAccess="canAccessApt"
-                      />
-                    </span>
-                  </var:matrix-cell>
-                </var:hspan-matrix>
-              </var:component>
-            </td>
-          </tr>
-          <tr bgcolor="#F5F5E9">
-            <td align="left" width="10"><var:entity const:name="nbsp"/></td>
-            <td align="right"
-            ><img border="0"
-                  alt=""
-                  rsrc:src="corner_right.gif"
-             /></td>
-          </tr>
-          <tr>
-            <td colspan="2" bgcolor="#F5F5E9">
-              <table border="0" width="100%" cellpadding="10" cellspacing="0">
-                <tr />
-              </table>
-            </td>
-          </tr>
-        </table>
-      </td>
-    </tr>
-  </table>
-</var:component>
diff --git a/UI/Templates/UIxCalWeekOverview.wox b/UI/Templates/UIxCalWeekOverview.wox
deleted file mode 100644 (file)
index 7a60f10..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               xmlns:uix="OGo:uix"
-               className="UIxPageFrame"
-               title="name"
->
-  <table id="skywintable" class="wintable" cellspacing="0" cellpadding="5" 
-         width="100%">
-  <tr>
-    <td class="wintitle">
-      <table cellpadding="0" cellspacing="0" width="100%">
-        <tr>
-          <td width="5"/>
-          <td class="wintitle"><var:component className="UIxCalDateLabel"
-                                              startDate="startDate"
-                                              endDate="endDate"
-                                              const:selection="week"
-                               /></td>
-          <td width="36" align="right" valign="center">
-            <var:component className="UIxWinClose" />
-          </td>
-        </tr>
-      </table>
-    </td>
-  </tr>
-
-  <tr>
-  <td id="skywinbodycell" class="wincontent">
-    <table border="0" cellpadding="0" cellspacing="0" width="100%">
-    <tr bgcolor="#e8e8e0">
-    <td align="left">
-      <var:component className="UIxCalBackForthNavView"
-                     methodName="ownMethodName"
-                     prevQueryParameters="prevWeekQueryParameters"
-                     currentQueryParameters="todayQueryParameters"
-                     nextQueryParameters="nextWeekQueryParameters"
-                     label:label="this week"
-      />
-    </td><!-- 99% -->
-    <td align="right" valign="middle" width="80%">
-      <var:component className="AnaisUidSelector"
-                     calendarUIDs="clientObject.calendarUIDs"
-      />
-    </td>
-    </tr>
-    </table>
-  </td>
-  </tr>
-
-  <tr>
-  <td id="skywinbodycell" class="wincontent">
-  <table border="0" width="100%" cellpadding="0" cellspacing="0">
-  <tr>
-  <td colspan="2">
-    <var:component className="UIxCalSelectTab"
-                   const:selection="week"
-                   currentDate="selectedDate"
-    >
-        <table border="0" cellpadding="4" width="100%" cellspacing="2">
-          <tr>
-            <td width="1%" align="left" valign="middle" bgcolor="#e8e8e0">
-              <table border='0' cellpadding='0' cellspacing='0'>
-               <tr>
-                  <td><img rsrc:src="icon_view_overview_inactive.gif"
-                           label:title="Overview" label:alt="Overview"
-                           border="0" valign="top" /></td>
-                  <td><a href="weekchartview"
-                         var:queryDictionary="queryParameters"
-                      ><img rsrc:src="icon_view_chart.gif"
-                            label:title="Chart" label:alt="Chart"
-                            border="0" valign="top" /></a></td>
-                  <td><a href="weeklistview"
-                         var:queryDictionary="queryParameters"
-                      ><img rsrc:src="icon_view_list.gif"
-                            label:title="List" label:alt="List"
-                            border="0" valign="top" /></a></td>
-                  <td>
-                    <a href="weekcolumnsview"
-                       var:queryDictionary="queryParameters"
-                    ><img rsrc:src="icon_view_columns.gif"
-                          label:title="Columns" label:alt="Columns"
-                          border="0" valign="top" /></a>
-                  </td>
-               </tr>
-              </table>
-            </td>
-            <td align="left" bgcolor="#e8e8e0" class="button_auto_env">
-              <a var:href="ownMethodName"
-                 class="button_auto"
-                 var:queryDictionary="toggleShowRejectedAptsQueryParameters"
-                 label:string="$toggleShowRejectedAptsLabel"
-              />
-            </td>
-            <td align="right" bgcolor="#e8e8e0">
-              <table border='0' cellpadding='0' cellspacing='1'>
-                <tr>
-                  <td class="button_auto_env" nowrap="true" valign='middle' 
-                      align='center'>
-                    <!--<a class="button_auto"
-                       href="weekprintview"
-                       var:queryDictionary="queryParameters"
-                       target="SOGoPrintView"
-                    ><var:string label:value="printview" /></a>-->
-                  </td>
-                  <td class="button_auto_env" nowrap="true" valign='middle' 
-                      align='center'>
-                    <a class="button_auto"
-                       href="proposal"
-                       var:queryDictionary="queryParameters"
-                    ><var:string label:value="proposal" /></a>
-                  </td>
-                </tr>
-              </table>
-            </td>
-          </tr>
-        </table>
-
-    <var:week-overview list="appointments"
-                       item="appointment"
-                       weekStart="startDate"
-                       dayIndex="dayIndex"
-                       const:startDateKey="startDate"
-                       const:endDateKey="endDate"
-                       const:titleStyle="weekoverview_title"
-                       hideWeekend="shouldHideWeekend"
-                       contentStyle="contentStyle"
-    >
-      <var:week-title>
-        <table cellpadding="0" width="100%" border="0" cellspacing="0"
-               var:class="titleStyle">
-          <tr>
-            <td align="left" valign="top">
-              <a href="dayoverview"
-                 var:queryDictionary="currentDayQueryParameters"
-                 class="weekoverview_title_daylink"
-                 ><var:string value="currentDay.dayOfMonth"
-                              const:numberformat="02"
-                  /></a>
-            </td>
-            <td align="center" valign="top" width="97%">
-              <var:string value="currentDayName" /><br />
-                [<a href="new"
-                    var:queryDictionary="currentDayQueryParameters"
-                    class="weekoverview_title_newlink"
-                 ><var:string label:value="new" /></a>]
-            </td>
-          </tr>
-        </table>
-      </var:week-title>
-      <var:if condition="hasDayInfo">
-        <var:week-info>
-          <var:if condition="hasHolidayInfo">
-            <var:string value="holidayInfo" 
-                       const:class="weekoverview_holidayinfo" />
-          </var:if>
-          <var:foreach list="allDayApts" item="appointment">
-            <var:component className="UIxCalInlineAptView"
-                           appointment="appointment"
-                           formatter="aptFormatter"
-                           tooltipFormatter="aptTooltipFormatter"
-                           url="appointmentViewURL"
-                           style="aptStyle"
-                           referenceDate="currentDay"
-                           queryDictionary="currentDayQueryParameters"
-                           canAccess="canAccessApt"
-            />
-            <br />
-          </var:foreach>
-        </var:week-info>
-      </var:if>
-      <var:week>
-        <var:component className="UIxCalInlineAptView"
-                       appointment="appointment"
-                       formatter="aptFormatter"
-                       tooltipFormatter="aptTooltipFormatter"
-                       url="appointmentViewURL"
-                       style="aptStyle"
-                       referenceDate="currentDay"
-                       canAccess="canAccessApt"
-        />
-        <br />
-      </var:week>
-    </var:week-overview>
-  </var:component>
-  </td>
-  </tr>
-  <tr bgcolor="#F5F5E9"> <!-- use CSS -->
-  <td align="left" width="10"><var:entity const:name="nbsp"/></td>
-  <td align="right"
-  ><img border="0"
-        alt=""
-        rsrc:src="corner_right.gif"
-   /></td>
-  </tr>
-  <tr>
-  <td colspan="2" bgcolor="#F5F5E9"> <!-- use CSS -->
-  <table border="0" width="100%" cellpadding="10" cellspacing="0">
-  <tr />
-  </table>
-  </td>
-  </tr>
-  </table>
-  </td>
-  </tr>
-  </table>
-  <!--
-  <hr />
-  <var:string value="thisWeekQueryParameters" />
-  -->
-  <!--
-  <hr/>
-    
-    Appointments: 
-    <var:component className="UIxAptTableView" appointments="appointments"/>
-  -->
-    <!-- pre><var:string value="appointments" const:insertBR="YES"/></pre -->
-</var:component>
diff --git a/UI/Templates/UIxCalWeekPrintview.wox b/UI/Templates/UIxCalWeekPrintview.wox
deleted file mode 100644 (file)
index 78e1b41..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" standalone="yes"?>
-<var:component xmlns="http://www.w3.org/1999/xhtml"
-               xmlns:var="http://www.skyrix.com/od/binding"
-               xmlns:const="http://www.skyrix.com/od/constant"
-               xmlns:rsrc="OGo:url"
-               xmlns:label="OGo:label"
-               xmlns:uix="OGo:uix"
-               className="UIxPrintPageFrame"
-               title="title">
-
-  <table border="0" cellpadding="0" cellspacing="0" width="100%">
-    <tr>
-      <td class="weekprintview">
-        <h1 class="weekprintview"><var:string value="title" /></h1>
-        <h2 class="weekprintview"><var:string value="formattedCalendarUIDs" /></h2>
-      </td>
-    </tr>
-    <tr>
-      <td>
-        <var:week-overview list="appointments"
-                           item="appointment"
-                           weekStart="startDate"
-                           dayIndex="dayIndex"
-                           const:startDateKey="startDate"
-                           const:endDateKey="endDate"
-                           const:titleStyle="weekprintview_title"
-                           const:contentStyle="weekprintview_content"
-                           const:cellpadding="5"
-                           const:cellspacing="0"
-                           const:border="1"
-                           const:width="100%"
-        >
-          <var:week-title>
-            <table cellpadding="5"
-                   width="100%"
-                   border="0"
-                   cellspacing="0"
-                   class="weekprintview_title"
-            >
-              <tr>
-                <td align="left" valign="top">
-                  <var:string value="currentDay.dayOfMonth"
-                              const:numberformat="02"
-                  />
-                </td>
-                <td align="center" valign="top" width="97%">
-                  <var:string value="currentDayName" />
-                </td>
-              </tr>
-            </table>
-          </var:week-title>
-          <var:if condition="hasDayInfo">
-            <var:week-info>
-              <var:if condition="hasHolidayInfo">
-                <var:string value="holidayInfo"
-                            const:class="weekprintview_holidayinfo"
-                />
-              </var:if>
-              <var:foreach list="allDayApts" item="appointment">
-                <var:string value="shortTextForApt"
-                            const:escapeHTML="NO"
-                />
-              </var:foreach>
-            </var:week-info>
-          </var:if>
-          <var:week>
-            <var:string value="shortTextForApt"
-                        const:escapeHTML="NO"
-            /> <br />
-          </var:week>
-        </var:week-overview>
-        </td>
-      </tr>
-  </table>
-</var:component>
diff --git a/UI/Templates/UIxContactSelector.wox b/UI/Templates/UIxContactSelector.wox
deleted file mode 100644 (file)
index eff319a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      class="button_submit_env"
->
-  <script language="JavaScript">
-    <var:string value="jsCode" const:escapeHTML="NO" />
-  </script>
-  <a var:href="jsFunctionHref"
-     class="button_submit"
-  ><var:string value="title" /></a>
-</span>
diff --git a/UI/Templates/UIxContactsSelectionView.wox b/UI/Templates/UIxContactsSelectionView.wox
deleted file mode 100644 (file)
index 6e733f0..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
->
-  <head>
-    <title>
-      <var:string label:value="Addressbook"/>
-    </title>
-    <meta name="description" content="SOGo Web Interface"/>
-    <meta name="author" content="SKYRIX Software AG"/>
-    <meta name="robots" content="stop"/>
-    <link type="text/css" rel="stylesheet" rsrc:href="uix.css"/>
-    <link type="text/css" rel="stylesheet" rsrc:href="calendar.css"/>
-    <link href="mailto:hh@skyrix.com" rev="made"/>
-    <style>
-      table.contacttableview {
-        text-decoration:  none;
-        font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-        font-size:        9pt;
-        color:            #000000;
-      }
-      table.contacttableview th {
-        text-align: left;
-      }
-      input.searchfield {
-        font-size:        8pt;
-      }
-    </style>
-  </head>
-  <body>
-    <table id="skywintable"
-           class="wintable"
-           cellspacing="0"
-           cellpadding="5"
-           width="100%"
-    >
-      <tr>
-        <td class="wintitle">
-          <table cellpadding="0" cellspacing="0" width="100%">
-            <tr>
-              <td width="5"/>
-              <td class="wintitle">
-                <!-- localize me -->
-                <span class="window_label"
-                ><var:string label:value="Addressbook"/></span>
-              </td>
-              <td width="36" align="right" valign="center">
-                <var:component className="UIxWinClose"/>
-              </td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-      <tr>
-        <td id="skywinbodycell" class="wincontent">
-         <form name="searchform"
-               var:href="ownMethodName"
-               var:_sort="sortKey"
-               method="GET"
-               var:queryDictionary="context.request.formValues"
-         >
-          <table border="0" width="100%" cellpadding="0" cellspacing="0">
-            <tr>
-              <td colspan="2">
-                  <table border="0" cellpadding="4" width="100%" cellspacing="0">
-                    <tr bgcolor="#e8e8e0">
-                      <td align="left">
-                        <input type="text" name="search" class="searchfield" 
-                               var:value="searchText" />
-                      </td>
-                    </tr>
-                  </table>
-  
-                  <!-- the content -->
-                  <table border="0" width="100%" class="contacttableview">
-                    <tr>
-                      <!-- localize -->
-                      <th>
-                        <var:if condition="sortKey" const:value="sn"
-                                const:negate="YES">
-                          <a var:href="ownMethodName"
-                             _sort="sn"
-                             var:_search="searchText"
-                             var:queryDictionary="context.request.formValues"
-                          ><var:string label:value="Lastname" /></a>
-                        </var:if>
-                        <var:if condition="sortKey" const:value="sn">
-                          <i><var:string label:value="Lastname" /></i>
-                        </var:if>
-                      </th>
-                      <th>
-                        <var:if condition="sortKey" const:value="givenname"
-                                const:negate="YES">
-                          <a var:href="ownMethodName"
-                             _sort="givenname"
-                             var:_search="searchText"
-                             var:queryDictionary="context.request.formValues"
-                          ><var:string label:value="Firstname" /></a>
-                        </var:if>
-                        <var:if condition="sortKey" const:value="givenname">
-                          <i><var:string label:value="Firstname" /></i>
-                        </var:if>
-                      </th>
-                      <th>
-                        <var:if condition="sortKey" const:value="mail"
-                                const:negate="YES">
-                          <a var:href="ownMethodName"
-                             _sort="mail"
-                             var:_search="searchText"
-                             var:queryDictionary="context.request.formValues"
-                          ><var:string label:value="EMail" /></a>
-                        </var:if>
-                        <var:if condition="sortKey" const:value="mail">
-                          <i><var:string label:value="EMail" /></i>
-                        </var:if>
-                      </th>
-                      <th>
-                           <var:string label:value="Phone" />
-                      </th>
-                      <th>
-                           <var:string label:value="Location" />
-                      </th>
-                    </tr>
-                    <var:foreach list="contactInfos" item="contact">
-                      <tr>
-                        <td>
-                          <a var:href="jsOnClickCode"
-                             ><var:string value="contact.sn" /></a>
-                        </td>
-                        <td><var:string value="contact.givenname"       /></td>
-                        <td><var:string value="contact.mail"            /></td>
-                        <td><var:string value="contact.telephonenumber" /></td>
-                        <td><var:string value="contact.l"               /></td>
-                      </tr>
-                    </var:foreach>
-                  </table>
-              </td>
-            </tr>
-  
-            <tr bgcolor="#F5F5E9">
-              <td align="left" width="10">
-                <var:entity const:name="nbsp"/>
-              </td>
-              <td align="right">
-                <img border="0"
-                     alt=""
-                     rsrc:src="corner_right.gif"
-                />
-              </td>
-            </tr>
-            <tr>
-              <td colspan="2" bgcolor="#F5F5E9">
-                <table border="0" width="100%" cellpadding="10" cellspacing="0">
-                  <tr/>
-                </table>
-              </td>
-            </tr>
-          </table>
-         </form>
-        </td>
-      </tr>
-    </table>
-    <var:if condition="isUIxDebugEnabled">
-      <hr />
-      <small>clientObject: <var:string value="clientObject" /></small>
-    </var:if>
-  </body>
-</html>
\ No newline at end of file
diff --git a/UI/Templates/UIxDatePicker.wox b/UI/Templates/UIxDatePicker.wox
deleted file mode 100644 (file)
index 0fdad86..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
->
-  <input type="text"
-         var:name="dateID"
-         var:id="dateID"
-         var:value="formattedDateString"
-         size="12"
-  /><a var:href="jsPopup"
-    ><img rsrc:src="icon_popupcalendar.gif"
-          var:title="label"
-          var:alt="label"
-          border="0"
-     /></a>
-  <script language="JavaScript">
-    <var:string value="jsCode" />\r  </script>
-</span>
\ No newline at end of file
diff --git a/UI/Templates/UIxDatePickerScript.wox b/UI/Templates/UIxDatePickerScript.wox
deleted file mode 100644 (file)
index afcd672..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<script xmlns="http://www.w3.org/1999/xhtml"
-        xmlns:var="http://www.skyrix.com/od/binding"
-        xmlns:const="http://www.skyrix.com/od/constant"
-        xmlns:rsrc="OGo:url"
-        language="JavaScript"
-        rsrc:src="skycalendar.js"
->
-</script>
\ No newline at end of file
diff --git a/UI/Templates/UIxException.wox b/UI/Templates/UIxException.wox
new file mode 100644 (file)
index 0000000..4b7ef15
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:component
+    className="UIxPageFrame"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    const:title="Exception"
+    >
+    reason: <var:string value="reason" />
+  </var:component>
diff --git a/UI/Templates/UIxJSClose.wox b/UI/Templates/UIxJSClose.wox
new file mode 100644 (file)
index 0000000..0627583
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version='1.0' standalone='yes'?>
+<container xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    ><var:string var:value="doctype" const:escapeHTML="NO" />
+<html><head></head><body style="background-color: #dbdad5;"
+        ><script type="text/javascript"
+          ><var:if condition="hasRefreshMethod"
+            >window.opener.setTimeout('<var:string value="refreshMethod"
+              const:escapeHTML="NO" />;', 200);</var:if
+            >window.close();</script
+></body></html
+></container>
index be1852629390f5339a955e400fae5aae62083236..ed9460fe57d6ec6f74a1c4a4633968fcbe1e6c38 100644 (file)
 <?xml version="1.0" standalone="yes"?>
-<html xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      xmlns:label="OGo:label"
->
-  <head>
-    <title>
-      <var:string value="title"/>
-    </title>
-    <meta name="description" content="SOGo Web Interface"/>
-    <meta name="author" content="SKYRIX Software AG"/>
-    <meta name="robots" content="stop"/>
+  <container 
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    ><var:string var:value="doctype" const:escapeHTML="NO" />
+    <var:if condition="hideFrame" const:negate="YES"
+      ><html>
+        <head>
+          <title>
+            <var:string value="title"/>
+          </title>
+          <meta name="hideFrame" var:content="hideFrame" />
+          <meta name="description" content="SOGo Web Interface" />
+          <meta name="author" content="SKYRIX Software AG/Inverse groupe conseil" />
+          <meta name="robots" content="stop" />
+          <link href="mailto:supper@inverse.ca" rev="made" />
+          <link rel="shortcut icon" rsrc:href="lori_16x16.ico" type="image/x-icon" />
+          <link type="text/css" rel="stylesheet" rsrc:href="generic.css" />
+          <link type="text/css" rel="stylesheet" rsrc:href="dtree.css" />
+          <var:if condition="hasProductSpecificCSS"
+            ><link type="text/css" rel="stylesheet" var:href="productCSSURL"
+              /></var:if>
+          <var:if condition="hasPageSpecificCSS"
+            ><link type="text/css" rel="stylesheet" var:href="pageCSSURL"
+              /></var:if>
+        </head>
 
-    <link type="text/css" rel="stylesheet" rsrc:href="uix.css"/>
-    <link type="text/css" rel="stylesheet" rsrc:href="calendar.css"/>
-    <link href="mailto:hh@skyrix.com" rev="made"/>
+        <body oncontextmenu="return false;" var:class="bodyClasses">
+          <script type="text/javascript">
+            var UserFolderURL = '<var:string value="userFolderPath" />';
+            var ApplicationBaseURL = '<var:string value="applicationPath" />';
+            var ResourcesURL = '/SOGo.woa/WebServerResources';
+            var UserLogin = '<var:string value="shortUserNameForDisplay" />';
+          </script>
 
-    <script rsrc:src="generic.js"> <!-- space required --></script>
-    
-    <var:if condition="hasPageSpecificJavaScript">
-      <script var:src="pageJavaScriptURL"> <!-- space required --></script>
-    </var:if>
-  </head>
+          <script type="text/javascript" rsrc:src="prototype.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="JavascriptAPIExtensions.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="HTMLElement.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="HTMLInputElement.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="HTMLTableElement.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="HTMLUListElement.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="generic.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="SOGoDragAndDrop.js"><!-- space required --></script>
+          <script type="text/javascript" rsrc:src="SOGoDragHandles.js"><!-- space required --></script>
+          <var:if condition="hasProductSpecificJavaScript"
+            ><script type="text/javascript" var:src="productJavaScriptURL"><!-- space required --></script
+              ></var:if>
+          <var:if condition="hasPageSpecificJavaScript"
+            ><script type="text/javascript" var:src="pageJavaScriptURL"> <!-- space required --></script
+              ></var:if>
+          <var:js-stringtable
+            var:framework="productFrameworkName"
+            const:identifier="labels" />
+
+          <var:if condition="isPopup" const:negate="YES"
+            ><var:if condition="context.isUIxDebugEnabled"
+              ><div id="logConsole"><!-- space --></div></var:if>
 
-  <body>
-    <table cellpadding="5" cellspacing="0" border="0" width="100%">
-      <tr>
-        <td colspan="2">
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td valign="bottom" style="font-size: 10pt;">
-                <a var:href="relativeHomePath"
+            <div id="linkBanner" class="linkbanner">
+              <a var:href="relativeHomePath"
                 ><var:string label:value="Home" /></a> |
-                <a var:href="relativeCalendarPath"
+              <a var:href="relativeCalendarPath"
                 ><var:string label:value="Calendar" /></a> |
-                <a var:href="relativeContactsPath"
-                ><var:string label:value="Addressbook" /></a> |
-                <a var:href="relativeMailPath"
+              <a var:href="relativeContactsPath"
+                ><var:string label:value="Address Book" /></a> |
+              <a var:href="relativeMailPath"
                 ><var:string label:value="Mail" /></a> |
-                <a href="http://to.be.done/"
-                ><var:string label:value="Administration" /></a>
-              </td>
-              <td align="right">
-                <a href="http://www.opengroupware.org:80/" target="OGo">
-                  <img rsrc:src="menu_logo_top.gif"
-                       align="center" border="0" alt="" valign="middle" />
-                </a>
-              </td>
-            </tr>
-          </table>
-          <!-- TODO: replace the line with a CSS straight line -->
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td class="linecolor"><img rsrc:src="line_left.gif"/></td>
-              <td class="linecolor" width="98%">
-                <img rsrc:src="line_stretch.gif"/>
-              </td>
-              <td class="linecolor"><img rsrc:src="line_right.gif"/></td>
-            </tr>
-            <tr>
-              <td valign="top" colspan="2">
-                <var:component className="UIxAppNavView" />
-              </td>
-              <td valign="top" align="right" class="button_submit_env">
-                <a var:href="helpURL"
-                   class="button_submit"
-                   label:string="Help"
-                   var:target="helpWindowTarget"
-                />
-              </td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-      <tr>
-        <td valign="top" width="100%">
-          <var:component-content/>
-        </td>
-      </tr>
-      <var:if condition="isUIxDebugEnabled">
-        <tr>
-          <td colspan="2">
-            <hr />
-            <table border="0" style="font-size: 9pt;">
-              <tr>
-                <td valign="top">clientObject:</td>
-                <td valign="top"><var:string value="clientObject" /></td>
-              </tr>
-              <tr>
-                <td valign="top">ownerInContext:</td>
-                <td valign="top"><var:string value="ownerInContext" /></td>
-              </tr>
-              <tr>
-                <td valign="top">traversal stack:</td>
-                <td valign="top">
-                  <var:foreach list="context.objectTraversalStack" item="item">
-                    <var:string value="item" /><br />
-                  </var:foreach>
-                </td>
-              </tr>
-              <tr>
-                <td valign="top">traversal path:</td>
-                <td valign="top">
-                  <var:foreach list="context.soRequestTraversalPath"
-                               item="item" const:separator=" => ">
-                    <var:string value="item" />
-                  </var:foreach>
-                </td>
-              </tr>
-              <tr>
-                <td valign="top">request type:</td>
-                <td valign="top"><var:string value="context.soRequestType"/>
-                </td>
-              </tr>
-              <tr>
-                <td valign="top">path info:</td>
-                <td valign="top"><var:string value="context.pathInfo"/></td>
-              </tr>
-              <tr>
-                <td valign="top">rootURL:</td>
-                <td valign="top"><var:string value="context.rootURL"/></td>
-              </tr>
-              <tr>
-                <td valign="top">active user:</td>
-                <td valign="top"><var:string value="context.activeUser"/></td>
-              </tr>
-              <tr>
-                <td valign="top">CN / email:</td>
-                <td valign="top">
-                  <var:string value="cnForUser"/>
-                  <var:entity const:name="lt"
-                  /><var:string value="emailForUser"
-                    /><var:entity const:name="gt"
-                  /></td>
-              </tr>
-              <tr>
-                <td valign="top">Access Restricted:</td>
-                <td valign="top">
-                  <var:if condition="isAccessRestricted">YES</var:if>
-                  <var:if condition="isAccessRestricted"
-                          const:negate="YES"
-                  >NO</var:if>  
-                </td>
-              </tr>
-              <tr>
-                <td valign="top">Headers:</td>
-                <td valign="top">
-                  <span style="white-space: pre;">
-                  <var:string value="context.request.headers"
-                              const:escapeHTML="YES"
-                  />
-                  </span>
-                </td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-      </var:if>
-      <tr>
-        <td colspan="2">
-          <!-- TODO: replace the line with a CSS straight line -->
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td class="linecolor">
-                <img rsrc:src="line_left.gif"/>
-              </td>
-              <td class="linecolor" width="100%">
-                <img rsrc:src="line_stretch.gif"/>
-              </td>
-              <td class="linecolor">
-                <img rsrc:src="line_right.gif"/>
-              </td>
-            </tr>
-            <tr>
-              <td colspan="3"/>
-            </tr>
-          </table>
-          <table cellpadding="0" cellspacing="0" border="0" width="100%">
-            <tr>
-              <td valign="top" align="left">
-                <font class="defaultfont"><var:entity const:name="copy"/>
-                  2004-2005 <a href="http://www.skyrix.com:80/knoppix/skyrix/"
-                               target="SKYRIX"
-                            >SKYRIX Software AG</a>.
-                  We welcome your
-                  <a href="http://www.opengroupware.org/en/feedback.html"
-                     target="feedback"
-                  >feedback</a>.
-                </font>
-              </td>
-              <td valign="top" align="right">
-                <font class="defaultfont">
-                  No sessions required! ;-)
-                </font>
-              </td>
-            </tr>
-          </table>
-        </td>
-      </tr>
-    </table>
-  </body>
-</html>
+              <a var:href="logoffPath"
+                ><var:string label:value="Logoff" /></a>
+              <var:if condition="context.isUIxDebugEnabled"
+                >| <a href="#"><var:string
+                    label:value="Log Console (dev.)" /></a
+                  ></var:if>
+            </div>
+          </var:if
+            
+            ><var:component className="UIxToolbar" var:toolbar="toolbar"
+            />
+
+          <div class="pageContent"
+            ><var:component-content
+              /></div>
+          <noscript>
+            <div id="noJavascriptError">
+            </div>
+            <div class="noJavascriptErrorMessage">
+              <var:string label:value="noJavascriptError"
+                /><br /><br
+                /><a class="button" var:href="page.context.uri"
+                ><var:string label:value="noJavascriptRetry"
+                  /></a>
+            </div>
+          </noscript>
+        </body>
+      </html>
+    </var:if>
+
+    <var:if condition="hideFrame">
+      <var:component-content />
+    </var:if>
+  </container>
+  
diff --git a/UI/Templates/UIxSortableTableHeader.wox b/UI/Templates/UIxSortableTableHeader.wox
new file mode 100644 (file)
index 0000000..787a213
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version='1.0' standalone='yes'?>
+  <span xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    class="sortableTableHeader"
+    ><var:if condition="isSelected"
+      ><var:if condition="isSortedDescending"
+        ><a var:href="href"
+          var:_sort="sortKey"
+          _desc="0"
+          var:queryDictionary="queryDictionary"
+          ><img rsrc:src="title_sortup_12x12.png"
+            class="tbtv_sortcell"
+            /><var:string var:value="label"
+            /></a
+      ></var:if
+        ><var:if condition="isSortedDescending" const:negate="YES"
+        ><a var:href="href"
+          var:_sort="sortKey"
+          _desc="1"
+          var:queryDictionary="queryDictionary"
+          ><img rsrc:src="title_sortdown_12x12.png"
+            class="tbtv_sortcell"
+            /><var:string var:value="label"
+            /></a
+          ></var:if
+        ></var:if
+      ><var:if condition="isSelected" const:negate="YES"
+      ><a var:href="href"
+        var:_sort="sortKey"
+        _desc="0"
+        var:queryDictionary="queryDictionary"
+        ><var:string var:value="label"
+          /></a
+        ></var:if
+      ></span>
diff --git a/UI/Templates/UIxTimeDateControl.wox b/UI/Templates/UIxTimeDateControl.wox
deleted file mode 100644 (file)
index 9f9323f..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-<!-- $Id$ -->
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
->
-  <table cellpadding="0" cellspacing="2">
-    <tr>
-      <var:if condition="displayTimeControl">
-        <td>
-          <var:component className="UIxTimeSelector"
-                         timeID="timeID"
-                         hour="hour"
-                         minute="minute"
-          />
-        </td>
-      </var:if>
-      <td>
-        <var:component className="UIxDatePicker"
-                       dateID="dateID"
-                       year="year"
-                       month="month"
-                       day="day"
-                       label="label"
-        />
-      </td>
-    </tr>
-  </table>
-</span>
diff --git a/UI/Templates/UIxTimeSelector.wox b/UI/Templates/UIxTimeSelector.wox
deleted file mode 100644 (file)
index a5c3a7b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version='1.0' standalone='yes'?>
-
-<span xmlns="http://www.w3.org/1999/xhtml"
-      xmlns:var="http://www.skyrix.com/od/binding"
-      xmlns:const="http://www.skyrix.com/od/constant"
-      xmlns:rsrc="OGo:url"
-      var:id="timeID"
->
-  <var:time-field hour="hour"
-                  minute="minute"
-                  minuteInterval="minuteInterval"
-                  name="timeID"
-  />
-</span>
diff --git a/UI/Templates/UIxToolbar.wox b/UI/Templates/UIxToolbar.wox
new file mode 100644 (file)
index 0000000..9b9f783
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" standalone="yes"?>
+  <var:if condition="hasButtons"
+    xmlns="http://www.w3.org/1999/xhtml"
+    xmlns:var="http://www.skyrix.com/od/binding"
+    xmlns:const="http://www.skyrix.com/od/constant"
+    xmlns:rsrc="OGo:url"
+    xmlns:label="OGo:label"
+    xmlns:so="http://www.skyrix.com/od/so-lookup">
+    <div id="toolbar" class="toolbar">
+      <var:foreach list="toolbarConfig" item="toolbarGroup"
+        ><var:foreach list="toolbarGroup" item="buttonInfo"
+          ><var:if condition="isButtonEnabled"
+            ><a class="toolbarButton"
+              var:href="buttonInfo.link"
+              var:target="buttonInfo.target"
+              var:onclick="buttonInfo.onclick"
+              var:title="buttonInfo.tooltip"
+              ><span class="toolbarButton"
+                ><img class="buttonImage"
+                  var:src="buttonImage"
+                  var:alt="buttonInfo.image"
+                  /><br
+                  /><span class="buttonLabel"
+                  ><var:string
+                    value="buttonLabel"
+                    /></span
+              ></span
+                ></a>
+          </var:if>
+          <var:if condition="isButtonEnabled"
+            const:negate="YES"
+            ><span class="disabledToolbarButton"
+              ><img class="buttonImage"
+                var:src="buttonImage"
+                var:alt="buttonInfo.image"
+                /><br
+                /><span class="buttonLabel"
+                ><var:string
+                  value="buttonLabel"
+                  /></span
+                ></span>
+          </var:if>
+        </var:foreach>
+        <var:if condition="isLastGroup" const:negate="YES"
+          ><span class="toolbarSeparator"
+            ><var:entity const:name="nbsp"
+           /></span
+        ></var:if>
+      </var:foreach>
+      <img id="progressIndicator" rsrc:src="busy.gif" />
+    </div>
+  </var:if>
diff --git a/UI/Templates/UIxUserLogoff.wox b/UI/Templates/UIxUserLogoff.wox
new file mode 100644 (file)
index 0000000..1a98b79
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version='1.0' standalone='yes'?>
+<span>dong dong</span>
+
diff --git a/UI/WebServerResources/ContactsUI.css b/UI/WebServerResources/ContactsUI.css
new file mode 100644 (file)
index 0000000..77e4003
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+  Copyright (C) 2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+DIV#rightPanel
+{
+  position: absolute;
+  top: 6em;
+  left: 15em;
+  margin-left: 5px;
+  right: 0px;
+  bottom: 0px;
+  overflow: hidden;
+}
+
+DIV#contactsListContent
+{ 
+  position: absolute;
+  background: #fff;
+  width: 100%;
+  height: 16em;
+  top: 2em;
+  overflow: auto;
+  left: 0px;
+}
+
+.aptview_text
+{
+  color: #000000;
+}
+
+.apt_other
+{
+  color: #000000;
+}
+
+.apt_other_print
+{
+  font-style: italic;
+}
+
+.foldercell
+{
+  width: 25%;
+}
+
+.contentcell
+{
+}
+
+.titlediv
+{
+  line-height: 2em;
+  vertical-align: bottom;
+  padding-left: 1em;
+}
+
+table.titletable
+{
+  height: 24px;
+  vertical-align: middle;
+  padding-top: 6px;
+  padding-left: 6px;
+}
+
+td.titlecell
+{
+  height: 22px;
+  vertical-align: middle;
+  padding-bottom: 2px;
+  white-space: nowrap;
+}
+
+table.titletable td.titlecell SELECT
+{ 
+  display: -moz-popup;
+  border-top: 1px solid #fff;
+  border-left: 1px solid #fff;
+  border-right: 2px solid #222;
+  border-bottom: 2px solid #222;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  background: #DCDAD5;
+}
+
+.whitesec_title
+{
+  background-color: #DCDAD5;
+  padding: 4px;
+}
+
+DIV#contactFoldersList
+{
+  position: absolute;
+  top: 6em;
+  left: 0px;
+  width: 15em;
+  bottom: 0px;
+  margin: 0px;
+  padding: 0px;
+  overflow: hidden;
+}
+
+DIV#contactFoldersList > DIV.toolbar
+{ width: 100%;
+  background: #f00;
+  padding: 0px;
+  margin: 0px;
+  border-top: 1px solid #aaa;
+  border-left: 1px solid #aaa; }
+
+UL#contactFolders
+{ visibility: hidden;
+  list-style-type: none;
+  list-style-image: none;
+  clear: both;
+  cursor: default;
+  color: #000;  
+  background: #fff;
+  width: 100%;
+  height: 100%;
+  margin: 0px;
+  padding: 0px;
+  border: 0px;
+  overflow: auto; }
+
+UL#contactFolders LI.denied
+{ background: #fefefe;
+  font-style: italic;
+  color: #f33; }
+
+DIV#contactFoldersList LI
+{
+  padding: .2em 1em;
+  margin: 0px;
+  width: auto;
+  white-space: nowrap;
+}
+
+DIV#contactFoldersList LI._selected
+{ 
+  background: #4b6983;
+  color: #fff;
+}
+
+.treecell
+{
+  color: black;
+  vertical-align: bottom;
+  padding-left: 4px; /* move away from the icon */
+  padding-right: 2px; /* move away from the right border */
+  white-space: nowrap;
+}
+
+DIV#folderTreeContent TABLE TD
+{ height: 2em;
+  border-top: 1px solid #fff;
+  margin: 0px;
+  padding: 0px; }
+
+TABLE#contactsList
+{ 
+  display: block;
+  position: relative;
+  color: #000;  
+  background: #fff;
+  width: 100%;
+  height: 100%;
+}
+
+TABLE#contactsList TD
+{ white-space: nowrap; }
+
+TABLE#contactsList TD IMG
+{
+  vertical-align: middle;
+  margin-left: 1em;
+  margin-right: .2em;
+}
+
+TABLE#contactsList TR._selected TD
+{ 
+  background: #4b6983;
+  color: #fff;
+}
+
+TABLE#contactsList TR._deleted TD
+{ 
+  text-decoration: line-through;
+}
+
+DIV#contactView
+{ 
+  position: absolute;
+  background: #fff;
+  padding: .5em;
+  top: 18em;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  overflow: auto;
+  margin-top: 5px;
+  border-top: 1px solid #aaa;
+  border-left: 1px solid #aaa;
+  line-height: 1em;
+}
+
+DIV#contactView H3.contactCardTitle
+{ display: block;
+  margin: .2em 0px;
+  font-size: large;
+  font-weight: bold;
+  width: 100%;
+  text-decoration: underline; }
+
+DIV.contactColumn
+{ 
+  width: 45%;
+  margin-left: 1em;
+  padding: .5em;
+  float: left;
+}
+
+DIV.contactColumn DIV
+{ margin-bottom: 1em; }
+
+DIV.contactColumn H4
+{
+  margin: .2em 0px;
+  margin-left: -1em;
+  font-weight: bold;
+  color: #fff;
+  background: #4b6983;
+  width: 100%;
+  padding: .1em .2em;
+}
+
+INPUT#searchValue:focus
+{ color: #000; }
+
+/* drag handles */
+DIV#dragHandle
+{ 
+  cursor: e-resize;
+  top: 8em;
+  left: 15em;
+  width: 5px;
+  bottom: 0px;
+}
+
+DIV#rightDragHandle
+{
+  cursor: n-resize;
+  top: 18em;
+  left: 0px;
+  right: 0px;
+  height: 5px;
+}
+
+DIV.contactSelector
+{
+  position: absolute;
+  top: 0px;
+  bottom: 0px;
+  right: 0px;
+  left: 0px;
+}
+
+BODY.popup DIV#rightPanel
+{ top: 4em; }
+
+BODY.popup DIV#dragHandle
+{ top: 6em; }
+
+BODY.popup DIV#contactsListContent
+{ height: 8em; }
+
+BODY.popup DIV#contactFoldersList
+{ top: 4em; }
+
+BODY.popup DIV#rightDragHandle
+{ top: 10em; }
+
+BODY.popup DIV#contactView
+{ top: 10em; }
+
+DIV.contactSelection
+{
+  z-index: 10;
+  background: inherit;
+  position: absolute;
+  bottom: 0em;
+  padding: 1em;
+  left: 0px;
+  right: 0px;
+  text-align: right;
+  background: #dbdad5;
+  border-top: 1px solid #fffffb;
+  border-left: 0px;
+  border-right: 0px;
+  border-bottom: 0px;
+  -moz-border-top-colors: -moz-buttonhoverface;
+}
+
+DIV.contactSelection > DIV.calendar
+{ text-align: center; }
+
+DIV.contactSelection INPUT.button
+{ margin-top: .25em; }
+
+DIV.contactSelection SPAN#selectionLabel
+{ float: left; }
diff --git a/UI/WebServerResources/ContactsUI.js b/UI/WebServerResources/ContactsUI.js
new file mode 100644 (file)
index 0000000..58fd986
--- /dev/null
@@ -0,0 +1,734 @@
+/*
+  Copyright (C) 2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+/* JavaScript for SOGo Mailer */
+
+/*
+  DOM ids available in mail list view:
+    row_$msgid
+    div_$msgid
+    readdiv_$msgid
+    unreaddiv_$msgid
+
+  Window Properties:
+    width, height
+    bool: resizable, scrollbars, toolbar, location, directories, status,
+          menubar, copyhistory
+*/
+
+var cachedContacts = new Array();
+var currentContactFolder = '';
+var currentFolderIsExternal = false;
+var contactSelectorAction = 'addressbooks-contacts';
+
+function openContactWindow(sender, url) {
+  var msgWin = window.open(url, null, "width=545,height=545,resizable=0");
+  msgWin.focus();
+}
+
+function clickedUid(sender, contactuid) {
+  resetSelection(window);
+  openContactWindow(sender, contactuid,
+                    CurrentContactFolderURL()
+                    + "/" + contactuid + "/edit");
+  return true;
+}
+
+function doubleClickedUid(sender, contactuid) {
+  alert("DOUBLE Clicked " + contactuid);
+
+  return false;
+}
+
+function toggleMailSelect(sender) {
+  var row;
+  row = $(sender.name);
+  row.className = sender.checked ? "tableview_selected" : "tableview";
+}
+
+/* mail editor */
+
+function validateEditorInput(sender) {
+  var errortext = "";
+  var field;
+  
+  field = document.pageform.subject;
+  if (field.value == "")
+    errortext = errortext + labels.error_missingsubject + "\n";
+
+  if (!UIxRecipientSelectorHasRecipients())
+    errortext = errortext + labels.error_missingrecipients + "\n";
+  
+  if (errortext.length > 0) {
+    alert(labels.error_validationfailed.decodeEntities() + ":\n"
+          + errortext.decodeEntities());
+    return false;
+  }
+  return true;
+}
+
+function onContactsFolderTreeItemClick(element)
+{
+  var topNode = $('d');
+  var contactsFolder = element.parentNode.getAttribute("dataname");
+
+  if (topNode.selectedEntry)
+    topNode.selectedEntry.deselect();
+  element.select();
+  topNode.selectedEntry = element;
+
+  openContactsFolder(contactsFolder);
+}
+
+function CurrentContactFolderURL() {
+  return ((currentFolderIsExternal)
+          ? UserFolderURL + "../" + currentContactFolder + "/Contacts/personal"
+          : ApplicationBaseURL + currentContactFolder);
+}
+
+function openContactsFolder(contactsFolder, params, external)
+{
+  if (contactsFolder != currentContactFolder || params) {
+    if (contactsFolder == currentContactFolder)
+      selection = $("contactsList").getSelectedRowsId();
+    else
+      selection = null;
+
+    currentContactFolder = contactsFolder;
+    if (external)
+      currentFolderIsExternal = true;
+    else
+      currentFolderIsExternal = false;
+    var url = CurrentContactFolderURL() + "/view?noframe=1&sort=cn&desc=0";
+    if (params)
+      url += '&' + params;
+
+    var selection;
+    if (document.contactsListAjaxRequest) {
+      document.contactsListAjaxRequest.aborted = true;
+      document.contactsListAjaxRequest.abort();
+    }
+    document.contactsListAjaxRequest
+      = triggerAjaxRequest(url, contactsListCallback, selection);
+  }
+}
+
+function openContactsFolderAtIndex(element) {
+  var idx = element.getAttribute("idx");
+  var url = CurrentContactFolderURL() + "/view?noframe=1&idx=" + idx;
+
+  if (document.contactsListAjaxRequest) {
+    document.contactsListAjaxRequest.aborted = true;
+    document.contactsListAjaxRequest.abort();
+  }
+  document.contactsListAjaxRequest
+    = triggerAjaxRequest(url, contactsListCallback);
+}
+
+function contactsListCallback(http)
+{
+  var div = $("contactsListContent");
+
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.contactsListAjaxRequest = null;
+    div.innerHTML = http.responseText;
+    var selected = http.callbackData;
+    if (selected) {
+        for (var i = 0; i < selected.length; i++)
+          $(selected[i]).select();
+    }
+    configureSortableTableHeaders();
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function onContactFoldersContextMenu(event)
+{
+  var menu = $("contactFoldersMenu");
+  menu.addEventListener("hideMenu", onContactFoldersContextMenuHide, false);
+  onMenuClick(event, "contactFoldersMenu");
+
+  var topNode = $("contactFolders");
+  var selectedNodes = topNode.getSelectedRows();
+  topNode.menuSelectedRows = selectedNodes;
+  for (var i = 0; i < selectedNodes.length; i++)
+    selectedNodes[i].deselect();
+  topNode.menuSelectedEntry = this;
+  this.select();
+}
+
+function onContactContextMenu(event, element)
+{
+  var menu = $("contactMenu");
+  menu.addEventListener("hideMenu", onContactContextMenuHide, false);
+  onMenuClick(event, "contactMenu");
+
+  var topNode = $("contactsList");
+  var selectedNodes = topNode.getSelectedRows();
+  topNode.menuSelectedRows = selectedNodes;
+  for (var i = 0; i < selectedNodes.length; i++)
+    selectedNodes[i].deselect();
+  topNode.menuSelectedEntry = element;
+  element.select();
+}
+
+function onContactContextMenuHide(event)
+{
+  var topNode = $("contactsList");
+
+  if (topNode.menuSelectedEntry) {
+    topNode.menuSelectedEntry.deselect();
+    topNode.menuSelectedEntry = null;
+  }
+  if (topNode.menuSelectedRows) {
+    var nodes = topNode.menuSelectedRows;
+    for (var i = 0; i < nodes.length; i++)
+      nodes[i].select();
+    topNode.menuSelectedRows = null;
+  }
+}
+
+function onContactFoldersContextMenuHide(event)
+{
+  var topNode = $("contactFolders");
+
+  if (topNode.menuSelectedEntry) {
+    topNode.menuSelectedEntry.deselect();
+    topNode.menuSelectedEntry = null;
+  }
+  if (topNode.menuSelectedRows) {
+    var nodes = topNode.menuSelectedRows;
+    for (var i = 0; i < nodes.length; i++)
+      nodes[i].select();
+    topNode.menuSelectedRows = null;
+  }
+}
+
+function onFolderMenuHide(event)
+{
+  var topNode = $('d');
+
+  if (topNode.menuSelectedEntry) {
+    topNode.menuSelectedEntry.deselect();
+    topNode.menuSelectedEntry = null;
+  }
+  if (topNode.selectedEntry)
+    topNode.selectedEntry.select();
+}
+
+function loadContact(idx)
+{
+  if (document.contactAjaxRequest) {
+    document.contactAjaxRequest.aborted = true;
+    document.contactAjaxRequest.abort();
+  }
+
+  if (cachedContacts[currentContactFolder + "/" + idx]) {
+    var div = $('contactView');
+    div.innerHTML = cachedContacts[currentContactFolder + "/" + idx];
+  }
+  else {
+    var url = (CurrentContactFolderURL() + "/"
+               + idx + "/view?noframe=1");
+    document.contactAjaxRequest
+      = triggerAjaxRequest(url, contactLoadCallback, idx);
+  }
+}
+
+function contactLoadCallback(http)
+{
+  var div = $('contactView');
+
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.contactAjaxRequest = null;
+    var content = http.responseText;
+    cachedContacts[currentContactFolder + "/" + http.callbackData] = content;
+    div.innerHTML = content;
+  }
+  else
+    log ("ajax fuckage");
+}
+
+var rowSelectionCount = 0;
+
+validateControls();
+
+function showElement(e, shouldShow) {
+  e.style.display = shouldShow ? "" : "none";
+}
+
+function enableElement(e, shouldEnable) {
+  if(!e)
+    return;
+  if(shouldEnable) {
+    if(e.hasAttribute("disabled"))
+      e.removeAttribute("disabled");
+  }
+  else {
+    e.setAttribute("disabled", "1");
+  }
+}
+
+function validateControls() {
+  var e = $("moveto");
+  this.enableElement(e, rowSelectionCount > 0);
+}
+
+function moveTo(uri) {
+  alert("MoveTo: " + uri);
+}
+
+/* contact menu entries */
+function onContactRowClick(event, node)
+{
+  loadContact(node.getAttribute('id'));
+
+  return onRowClick(event);
+}
+
+function onContactRowDblClick(event, node)
+{
+  var contactId = node.getAttribute('id');
+
+  openContactWindow(null,
+                    CurrentContactFolderURL()
+                    + "/" + contactId + "/edit");
+
+  return false;
+}
+
+function onMenuEditContact(event, node)
+{
+  var node = getParentMenu(node).menuTarget.parentNode;
+  var contactId = node.getAttribute('id');
+
+  openContactWindow(null,
+                    CurrentContactFolderURL()
+                    + "/" + contactId + "/edit");
+
+  return false;
+}
+
+function onMenuWriteToContact(event, node)
+{
+  var node = getParentMenu(node).menuTarget.parentNode;
+  var contactId = node.getAttribute('id');
+
+  openMailComposeWindow(CurrentContactFolderURL()
+                        + "/" + contactId + "/write");
+
+  return false;
+}
+
+function onMenuDeleteContact(event, node)
+{
+  uixDeleteSelectedContacts(node);
+
+  return false;
+}
+
+function onToolbarEditSelectedContacts(event)
+{
+  var contactsList = $('contactsList');
+  var rows = contactsList.getSelectedRowsId();
+
+  for (var i = 0; i < rows.length; i++) {
+    openContactWindow(null,
+                      CurrentContactFolderURL()
+                      + "/" + rows[i] + "/edit");
+  }
+
+  return false;
+}
+
+function onToolbarWriteToSelectedContacts(event)
+{
+  var contactsList = $('contactsList');
+  var rows = contactsList.getSelectedRowsId();
+
+  for (var i = 0; i < rows.length; i++)
+    openMailComposeWindow(CurrentContactFolderURL()
+                          + "/" + rows[i] + "/write");
+
+  return false;
+}
+
+function uixDeleteSelectedContacts(sender)
+{
+  var failCount = 0;
+  var contactsList = $('contactsList');
+  var rows = contactsList.getSelectedRowsId();
+
+  var contactView = $('contactView');
+  contactView.innerHTML = '';
+
+  for (var i = 0; i < rows.length; i++) {
+    var url, http, rowElem;
+    
+    /* send AJAX request (synchronously) */
+    
+    url = (CurrentContactFolderURL() + "/"
+           + rows[i] + "/delete");
+    http = createHTTPClient();
+    http.open("POST", url, false /* not async */);
+    http.send("");
+    if (http.status != 200) { /* request failed */
+      failCount++;
+      http = null;
+      continue;
+    }
+    http = null;
+
+    /* remove from page */
+
+    /* line-through would be nicer, but hiding is OK too */
+    rowElem = $(rows[i]);
+    rowElem.parentNode.removeChild(rowElem);
+  }
+
+  if (failCount > 0)
+    alert("Could not delete " + failCount + " messages!");
+  
+  return false;
+}
+
+function newEmailTo(sender) {
+  var mailto = sanitizeMailTo(sender.parentNode.parentNode.menuTarget.innerHTML);
+
+  if (mailto.length > 0)
+    {
+      w = window.open("compose?mailto=" + mailto,
+                     "SOGo_compose",
+                     "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," +
+                     "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+      w.focus();
+    }
+
+  return false; /* stop following the link */
+}
+
+function onHeaderClick(event)
+{
+  if (document.contactsListAjaxRequest) {
+    document.contactsListAjaxRequest.aborted = true;
+    document.contactsListAjaxRequest.abort();
+  }
+  url = CurrentContactFolderURL() + "/" + this.link;
+  if (!this.link.match(/noframe=/))
+    url += "&noframe=1";
+  document.contactsListAjaxRequest
+    = triggerAjaxRequest(url, contactsListCallback);
+
+  event.preventDefault();
+}
+
+function registerDraggableMessageNodes()
+{
+  log ("can we drag...");
+}
+
+function newContact(sender) {
+  openContactWindow(sender,
+                    CurrentContactFolderURL() + "/new");
+
+  return false; /* stop following the link */
+}
+
+function onFolderSelectionChange()
+{
+  var folderList = $("contactFolders");
+  var nodes = folderList.getSelectedNodes();
+  $("contactView").innerHTML = '';
+
+  if (nodes[0].hasClassName("denied")) {
+    var div = $("contactsListContent");
+    div.innerHTML = "";
+  }
+  else {
+    var newFolder;
+    var externalFolder = nodes[0].getAttribute("external-addressbook");
+    if (externalFolder)
+      newFolder = externalFolder;
+    else
+      newFolder = nodes[0].getAttribute("id");
+
+    openContactsFolder(newFolder, null, externalFolder);
+  }
+}
+
+function onSearchFormSubmit()
+{
+  var searchValue = $("searchValue");
+
+  openContactsFolder(currentContactFolder, "search=" + searchValue.value);
+
+  return false;
+}
+
+function onConfirmContactSelection(tag)
+{
+  var folderLi = $(currentContactFolder);
+  var currentContactFolderName = folderLi.innerHTML;
+  var selectorList = null;
+  var initialValues = null;
+
+  if (selector)
+    {
+      var selectorId = selector.getAttribute("id");
+      selectorList = opener.window.document.getElementById('uixselector-'
+                                                           + selectorId
+                                                           + '-uidList');
+      initialValues = selectorList.value;
+    }
+
+  var contactsList = $("contactsList");
+  var rows = contactsList.getSelectedRows();
+  for (i = 0; i < rows.length; i++) {
+    var cid = rows[i].getAttribute("contactid");
+    var cname = '' + rows[i].getAttribute("contactname");
+    var email = '' + rows[i].cells[1].innerHTML;
+    opener.window.addContact(tag, currentContactFolderName + '/' + cname,
+                             cid, cname, email);
+  }
+
+  if (selector && selector.changeNotification
+      && selectorList.value != initialValues)
+    selector.changeNotification("addition");
+
+  return false;
+}
+
+function onConfirmAddressBookSelection() {
+  var folderLi = $(currentContactFolder);
+  var currentContactFolderName = folderLi.innerHTML;
+
+  var selector = window.opener.document.getElementById("contactFolders");
+  var initialValues = selector.getAttribute("additional-addressbooks");
+  if (!initialValues)
+    initialValues = "";
+  var newValues = initialValues;
+
+  var contactsList = $("contactsList");
+  var rows = contactsList.getSelectedRows();
+  for (i = 0; i < rows.length; i++) {
+    var cid = rows[i].getAttribute("contactid");
+    var cname = '' + rows[i].getAttribute("contactname");
+    var email = '' + rows[i].cells[1].innerHTML;
+    var re = new RegExp("(^|,)" + cid + "($|,)");
+    if (!re.test(newValues)) {
+      if (newValues.length)
+        newValues += "," + cid;
+      else
+        newValues = cid;
+    }
+  }
+
+  if (newValues != initialValues)
+    window.opener.setTimeout("setAdditionalAddressBooks(\""
+                             + newValues + "\");", 100);
+
+  return false;
+}
+
+function setAdditionalAddressBooks(additionalAddressBooks) {
+  var urlstr = (ApplicationBaseURL + "/updateAdditionalAddressBooks?ids="
+                + additionalAddressBooks);
+  if (document.addressBooksAjaxRequest) {
+    document.addressBooksAjaxRequest.aborted = true;
+    document.addressBooksAjaxRequest.abort();
+  }
+  document.addressBooksAjaxRequest
+    = triggerAjaxRequest(urlstr,
+                         addressBooksCallback, additionalAddressBooks);
+}
+
+function addressBooksCallback(http) {
+  if (http.readyState == 4) {
+    if (http.status == 200) {
+      var ul = $("contactFolders");
+
+      var children = ul.childNodesWithTag("li");
+      for (var i = 0; i < children.length; i++)
+        if (children[i].getAttribute("external-addressbook"))
+          ul.removeChild(children[i]);
+
+      ul.setAttribute("additional-addressbooks", http.callbackData);
+      if (http.callbackData.length > 0) {
+        var list = http.callbackData.split(",");
+        var newCode = "";
+        for (var i = 0; i < list.length; i++) {
+          var username = list[i];
+          newCode += ( "<li external-addressbook=\"" + username + "\""
+                       + " onmousedown=\"return false;\""
+                       + " onclick=\"return onRowClick(event);\""
+                       + " oncontextmenu=\"return onContactFolderContextMenu(event);\">" );
+          newCode += ( username + "</li>" );
+        }
+        ul.innerHTML += newCode;
+      }
+    }
+    document.addressBooksAjaxRequest = null;
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function onContactMailTo(node) {
+  return openMailTo(node.innerHTML);
+}
+
+function refreshContacts(contactId) {
+  openContactsFolder(currentContactFolder, "reload=true", currentFolderIsExternal);
+  cachedContacts[currentContactFolder + "/" + contactId] = null;
+  loadContact(contactId);
+
+  return false;
+}
+
+function onAddressBookAdd(node) {
+  var selector = $("contactFolders");
+  var selectorURL = '?popup=YES&selectorId=contactFolders';
+
+  urlstr = ApplicationBaseURL;
+  if (urlstr[urlstr.length-1] != '/')
+    urlstr += '/';
+  urlstr += ("../../" + UserLogin + "/Contacts/"
+             + contactSelectorAction + selectorURL);
+//   log (urlstr);
+  var w = window.open(urlstr, "Addressbook",
+                      "width=640,height=400,resizable=1,scrollbars=0");
+  w.selector = selector;
+  w.opener = this;
+  w.focus();
+
+  return false;
+}
+
+function onAddressBookRemove(node) {
+  var selector = $("contactFolders");
+  var nodes = selector.getSelectedNodes();
+  if (nodes.length > 0) {
+    var cid = nodes[0].getAttribute("external-addressbook");
+    if (cid) {
+      var initialValues = selector.getAttribute("additional-addressbooks");
+      var re = new RegExp("(^|,)" + cid + "($|,)");
+      var newValues = initialValues.replace(re, "");
+      if (initialValues != newValues)
+        setAdditionalAddressBooks(newValues);
+      
+      var personal = $("/personal");
+      personal.select();
+      onFolderSelectionChange();
+    }
+  }
+
+  return false;
+}
+
+function configureDragHandles() {
+  var handle = $("dragHandle");
+  if (handle) {
+    handle.addInterface(SOGoDragHandlesInterface);
+    handle.leftBlock=$("contactFoldersList");
+    handle.rightBlock=$("rightPanel");
+  }
+
+  handle = $("rightDragHandle");
+  if (handle) {
+    handle.addInterface(SOGoDragHandlesInterface);
+    handle.upperBlock=$("contactsListContent");
+    handle.lowerBlock=$("contactView");
+  }
+}
+
+function lookupDeniedFolders() {
+  var rights;
+  var http = createHTTPClient();
+  if (http) {
+    http.url = ApplicationBaseURL + "/checkRights";
+    http.open("GET", http.url, false /* not async */);
+    http.send("");
+    if (http.status == 200
+        && http.responseText.length > 0) {
+      rights = http.responseText.split(",");
+    }
+  }
+
+  return rights;
+}
+
+function configureContactFolders() {
+  var contactFolders = $("contactFolders");
+  if (contactFolders) {
+    contactFolders.addEventListener("selectionchange",
+                                    onFolderSelectionChange, false);
+    var lis = contactFolders.childNodesWithTag("li");
+    for (var i = 0; i < lis.length; i++) {
+      lis[i].addEventListener("mousedown", listRowMouseDownHandler, false);
+      lis[i].addEventListener("click", onRowClick, false);
+      lis[i].addEventListener("contextmenu", onContactFoldersContextMenu, false);
+    }
+
+    var denieds = lookupDeniedFolders();
+    if (denieds) {
+      var start = (lis.length - denieds.length);
+      for (var i = start; i < lis.length; i++) {
+        if (denieds[i-start] == "1")
+          lis[i].removeClassName("denied");
+        else
+          lis[i].addClassName("denied");
+      }
+    }
+    contactFolders.style.visibility = "visible;";
+  }
+}
+
+function onAccessRightsMenuEntryMouseUp(event) {
+  var folders = $("contactFolders");
+  var selected = folders.getSelectedNodes()[0];
+  var external = selected.getAttribute("external-addressbook");
+  var title = this.innerHTML;
+  if (external)
+    url = UserFolderURL + "../" + external + "/Contacts/personal/acls";
+  else
+    url = ApplicationBaseURL + selected.getAttribute("id") + "/acls";
+
+  openAclWindow(url, title);
+}
+
+function initializeMenus() {
+  var menus = new Array("contactFoldersMenu", "contactMenu", "searchMenu");
+  initMenusNamed(menus);
+
+  var menuEntry = $("accessRightsMenuEntry");
+  menuEntry.addEventListener("mouseup", onAccessRightsMenuEntryMouseUp, false);
+}
+
+var initContacts = {
+  handleEvent: function (event) {
+    configureContactFolders();
+//     initDnd();
+  }
+}
+
+window.addEventListener("load", initContacts, false);
diff --git a/UI/WebServerResources/HTMLElement.js b/UI/WebServerResources/HTMLElement.js
new file mode 100644 (file)
index 0000000..9b18e92
--- /dev/null
@@ -0,0 +1,195 @@
+/* custom extensions to the DOM api */
+HTMLElement.prototype.addInterface = function(objectInterface) {
+  Object.extend(this, objectInterface);
+  if (this.bind)
+    this.bind();
+}
+
+HTMLElement.prototype.childNodesWithTag = function(tagName) {
+  var matchingNodes = new Array();
+  var tagName = tagName.toUpperCase();
+
+  for (var i = 0; i < this.childNodes.length; i++) {
+//     log("(" + tagName + ") childNodes " + i + " = " + this.childNodes[i]);
+    if (typeof(this.childNodes[i]) == "object"
+        && this.childNodes[i].tagName
+        && this.childNodes[i].tagName.toUpperCase() == tagName)
+      matchingNodes.push(this.childNodes[i]);
+  }
+
+//   log ("matching: " + matchingNodes.length);
+
+  return matchingNodes;
+}
+
+HTMLElement.prototype.addClassName = function(className) {
+  var classStr = '' + this.getAttribute("class");
+
+  position = classStr.indexOf(className, 0);
+  if (position < 0) {
+    classStr = classStr + ' ' + className;
+    this.setAttribute('class', classStr);
+  }
+}
+
+HTMLElement.prototype.removeClassName = function(className) {
+  var classStr = '' + this.getAttribute('class');
+
+  position = classStr.indexOf(className, 0);
+  while (position > -1) {
+    classStr1 = classStr.substring(0, position); 
+    classStr2 = classStr.substring(position + 10, classStr.length);
+    classStr = classStr1 + classStr2;
+    position = classStr.indexOf(className, 0);
+  }
+
+  this.setAttribute('class', classStr);
+}
+
+HTMLElement.prototype.hasClassName = function(className) {
+  var classStr = '' + this.getAttribute('class');
+  position = classStr.indexOf(className, 0);
+  return (position > -1);
+}
+
+HTMLElement.prototype.getParentWithTagName = function(tagName) {
+  var currentElement = this;
+  tagName = tagName.toUpperCase();
+
+  currentElement = currentElement.parentNode;
+  while (currentElement
+         && currentElement.tagName != tagName) {
+    currentElement = currentElement.parentNode;
+  }
+
+  return currentElement;
+}
+
+HTMLElement.prototype.cascadeLeftOffset = function() {
+  var currentElement = this;
+
+  var offset = 0;
+  while (currentElement) {
+    offset += currentElement.offsetLeft;
+    currentElement = currentElement.getParentWithTagName("div");
+  }
+
+  return offset;
+}
+
+HTMLElement.prototype.cascadeTopOffset = function() {
+  var currentElement = this;
+  var offset = 0;
+
+  var i = 0;
+
+  while (currentElement
+         && currentElement instanceof HTMLElement) {
+    offset += currentElement.offsetTop;
+    currentElement = currentElement.parentNode;
+    i++;
+  }
+
+  return offset;
+}
+
+HTMLElement.prototype.dump = function(additionalInfo, additionalKeys) {
+  var id = this.getAttribute("id");
+  var nclass = this.getAttribute("class");
+  
+  var str = this.tagName;
+  if (id)
+    str += "; id = " + id;
+  if (nclass)
+    str += "; class = " + nclass;
+
+  if (additionalInfo)
+    str += "; " + additionalInfo;
+
+  if (additionalKeys)
+    for (var i = 0; i < additionalKeys.length; i++) {
+      var value = this.getAttribute(additionalKeys[i]);
+      if (value)
+        str += "; " + additionalKeys[i] + " = " + value;
+    }
+
+  log (str);
+}
+
+HTMLElement.prototype.getSelectedNodes = function() {
+  var selArray = new Array();
+
+  for (var i = 0; i < this.childNodes.length; i++) {
+    node = this.childNodes.item(i);
+    if (node.nodeType == 1
+       && isNodeSelected(node))
+      selArray.push(node);
+  }
+
+  return selArray;
+}
+
+HTMLElement.prototype.getSelectedNodesId = function() {
+  var selArray = new Array();
+
+  for (var i = 0; i < this.childNodes.length; i++) {
+    node = this.childNodes.item(i);
+    if (node.nodeType == 1
+       && isNodeSelected(node))
+      selArray.push(node.getAttribute("id"));
+  }
+
+  return selArray;
+}
+
+HTMLElement.prototype.onContextMenu = function(event) {
+  var popup = this.sogoContextMenu;
+
+  if (document.currentPopupMenu)
+    hideMenu(event, document.currentPopupMenu);
+
+  var menuTop = event.pageY;
+  var menuLeft = event.pageX;
+  var heightDiff = (window.innerHeight
+                   - (menuTop + popup.offsetHeight));
+  if (heightDiff < 0)
+    menuTop += heightDiff;
+
+  var leftDiff = (window.innerWidth
+                 - (menuLeft + popup.offsetWidth));
+  if (leftDiff < 0)
+    menuLeft -= popup.offsetWidth;
+
+  popup.style.top = menuTop + "px;";
+  popup.style.left = menuLeft + "px;";
+  popup.style.visibility = "visible;";
+//   setupMenuTarget(popup, event.target);
+
+  bodyOnClick = "" + document.body.getAttribute("onclick");
+  document.body.setAttribute("onclick", "onBodyClick(event);");
+  document.currentPopupMenu = popup;
+
+//   event.cancelBubble = true;
+//   event.returnValue = false;
+}
+
+HTMLElement.prototype.attachMenu = function(menuName) {
+  this.sogoContextMenu = $(menuName);
+  this.addEventListener("contextmenu", this.onContextMenu, true);
+}
+
+HTMLElement.prototype.select = function() {
+  this.addClassName('_selected');
+}
+
+HTMLElement.prototype.deselect = function() {
+  this.removeClassName('_selected');
+}
+
+HTMLElement.prototype.deselectAll = function () {
+  for (var i = 0; i < this.childNodes.length; i++) {
+    var node = this.childNodes.item(i);
+    if (node.nodeType == 1)
+      node.deselect();
+  }
+}
diff --git a/UI/WebServerResources/HTMLInputElement.js b/UI/WebServerResources/HTMLInputElement.js
new file mode 100644 (file)
index 0000000..b5e48e2
--- /dev/null
@@ -0,0 +1,75 @@
+HTMLInputElement.prototype._replicate = function() {
+  if (this.replica) {
+    this.replica.value = this.value;
+    var onReplicaChangeEvent = document.createEvent("Event");
+    onReplicaChangeEvent.initEvent("change", true, true);
+    this.replica.dispatchEvent(onReplicaChangeEvent);
+  }
+}
+
+HTMLInputElement.prototype.assignReplica = function(otherInput) {
+  if (!this._onChangeBound) {
+    this.addEventListener("change", this._replicate, false);
+    this._onChangeBound = true;
+  }
+  this.replica = otherInput;
+}
+
+HTMLInputElement.prototype.valueAsDate = function () {
+  return this.value.asDate();
+}
+
+HTMLInputElement.prototype.setValueAsDate = function(dateValue) {
+  if (!this.dateSeparator)
+    this._detectDateSeparator();
+  this.value = dateValue.stringWithSeparator(this.dateSeparator);
+}
+
+HTMLInputElement.prototype.updateShadowValue = function () {
+  this.setAttribute("shadow-value", this.value);
+}
+
+HTMLInputElement.prototype._detectDateSeparator = function() {
+  var date = this.value.split("/");
+  if (date.length == 3)
+    this.dateSeparator = "/";
+  else
+    this.dateSeparator = "-";
+}
+
+HTMLInputElement.prototype.valueAsShortDateString = function() {
+  var dateStr = '';
+
+  if (!this.dateSeparator)
+    this._detectDateSeparator();
+
+  var date = this.value.split(this.dateSeparator);
+  if (this.dateSeparator == '/')
+    dateStr += date[2] + date[1] + date[0];
+  else
+    dateStr += date[0] + date[1] + date[2];
+
+  return dateStr;
+}
+
+/* "select" is part of the inputs so it's included here */
+HTMLSelectElement.prototype._replicate = function() {
+  if (this.replica) {
+    this.replica.value = this.value;
+    var onReplicaChangeEvent = document.createEvent("Event");
+    onReplicaChangeEvent.initEvent("change", true, true);
+    this.replica.dispatchEvent(onReplicaChangeEvent);
+  }
+}
+
+HTMLSelectElement.prototype.assignReplica = function(otherSelect) {
+  if (!this._onChangeBound) {
+    this.addEventListener("change", this._replicate, false);
+    this._onChangeBound = true;
+  }
+  this.replica = otherSelect;
+}
+
+HTMLSelectElement.prototype.updateShadowValue = function () {
+  this.setAttribute("shadow-value", this.value);
+}
diff --git a/UI/WebServerResources/HTMLTableElement.js b/UI/WebServerResources/HTMLTableElement.js
new file mode 100644 (file)
index 0000000..0390497
--- /dev/null
@@ -0,0 +1,28 @@
+HTMLTableElement.prototype.getSelectedRows = function() {
+  var tbody = (this.getElementsByTagName('tbody'))[0];
+
+  return tbody.getSelectedNodes();
+}
+
+HTMLTableElement.prototype.getSelectedRowsId = function() {
+  var tbody = (this.getElementsByTagName('tbody'))[0];
+
+  return tbody.getSelectedNodesId();
+}
+
+HTMLTableElement.prototype.selectRowsMatchingClass = function(className) {
+  var tbody = (this.getElementsByTagName('tbody'))[0];
+  var nodes = tbody.childNodes;
+  for (var i = 0; i < nodes.length; i++) {
+    var node = nodes.item(i);
+    if (node instanceof HTMLElement
+        && node.hasClassName(className))
+      node.select();
+  }
+}
+
+HTMLTableElement.prototype.deselectAll = function() {
+  var nodes = this.getSelectedRows();
+  for (var i = 0; i < nodes.length; i++)
+    nodes[i].deselect();
+}
diff --git a/UI/WebServerResources/HTMLUListElement.js b/UI/WebServerResources/HTMLUListElement.js
new file mode 100644 (file)
index 0000000..8b622fb
--- /dev/null
@@ -0,0 +1,7 @@
+HTMLUListElement.prototype.getSelectedRows = function() {
+  return this.getSelectedNodes();
+}
+
+HTMLUListElement.prototype.getSelectedRowsId = function() {
+  return this.getSelectedNodesId();
+}
diff --git a/UI/WebServerResources/JavascriptAPIExtensions.js b/UI/WebServerResources/JavascriptAPIExtensions.js
new file mode 100644 (file)
index 0000000..fc7649a
--- /dev/null
@@ -0,0 +1,89 @@
+String.prototype.trim = function() {
+  return this.replace(/(^\s+|\s+$)/g, '');
+}
+
+String.prototype.capitalize = function() {
+  return this.replace(/\w+/g,
+                      function(a) {
+                        return ( a.charAt(0).toUpperCase()
+                                 + a.substr(1).toLowerCase() );
+                      });
+}
+
+String.prototype.decodeEntities = function() {
+  return this.replace(/&#(\d+);/g,
+                      function(wholematch, parenmatch1) {
+                        return String.fromCharCode(+parenmatch1);
+                      });
+}
+
+String.prototype.asDate = function () {
+  var newDate;
+  var date = this.split("/");
+  if (date.length == 3)
+    newDate = new Date(date[2], date[1] - 1, date[0]);
+  else {
+    date = this.split("-");
+    newDate = new Date(date[0], date[1] - 1, date[2]);
+  }
+
+  return newDate;  
+}
+
+Date.prototype.sogoDayName = function() {
+  var dayName = "";
+
+  var day = this.getDay();
+  if (day == 0) {
+    dayName = labels['a2_Sunday'];
+  } else if (day == 1) {
+    dayName = labels['a2_Monday'];
+  } else if (day == 2) {
+    dayName = labels['a2_Tuesday'];
+  } else if (day == 3) {
+    dayName = labels['a2_Wednesday'];
+  } else if (day == 4) {
+    dayName = labels['a2_Thursday'];
+  } else if (day == 5) {
+    dayName = labels['a2_Friday'];
+  } else if (day == 6) {
+    dayName = labels['a2_Saturday'];
+  }
+
+  return dayName;
+}
+
+Date.prototype.daysUpTo = function(otherDate) {
+  var days = new Array();
+  var day1 = this.getTime();
+  var day2 = otherDate.getTime();
+
+  var nbrDays = Math.floor((day2 - day1) / 86400000) + 1;
+  for (var i = 0; i < nbrDays; i++) {
+    var newDate = new Date();
+    newDate.setTime(day1 + (i * 86400000));
+    days.push(newDate);
+  }
+
+  return days;
+}
+
+Date.prototype.stringWithSeparator = function(separator) {
+  var month = '' + (this.getMonth() + 1);
+  var day = '' + this.getDate();
+  if (month.length == 1)
+    month = '0' + month;
+  if (day.length == 1)
+    day = '0' + day;
+
+  if (separator == '-')
+    str = (this.getYear() + 1900) + '-' + month + '-' + day;
+  else
+    str = day + '/' + month + '/' + (this.getYear() + 1900);
+
+  return str;
+}
+
+Date.prototype.sogoFreeBusyStringWithSeparator = function(separator) {
+  return this.sogoDayName() + ", " + this.stringWithSeparator(separator);
+}
diff --git a/UI/WebServerResources/MailerUI.css b/UI/WebServerResources/MailerUI.css
new file mode 100644 (file)
index 0000000..1997ee8
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+  Copyright (C) 2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+/* TODO: is the section below used in the mailer? */
+
+DIV#leftPanel
+{
+  position: absolute;
+  top: 5.5em;
+  left: 0px;
+  width: 15em;
+  bottom: 0px;
+  margin: 0px;
+  padding: 0px;
+  overflow: hidden;
+}
+
+DIV#rightPanel
+{ 
+  position: absolute;
+  top: 5.5em;
+  left: 15em;
+  right: 0px;
+  bottom: 0px;
+  margin: 0px;
+  margin-left: 5px;
+  padding: 0px;
+  overflow: hidden;
+}
+
+DIV#mailboxContent
+{
+  position: absolute;
+  width: 100%;
+  height: 18em;
+  left: 0px;
+  top: 0px;
+  right: 0px;
+}
+
+DIV#messageContent
+{
+  position: absolute;
+  overflow: hidden;
+  top: 18em;
+  bottom: 0px;
+  left: 0px;
+  right: 0px;
+  margin: 0px;
+  margin-top: 5px;
+  padding: 0px;
+  border: 0px;
+  border-top: 1px solid #aaa;
+  border-left: 1px solid #aaa;
+  background: #fff;
+}
+
+DIV#folderTreeContent
+{
+  position: absolute;
+  color: #000;
+  background: #fff;
+  width: 100%;
+  top: 2em;
+  bottom: 0px;
+  overflow: auto;
+  border: 1px solid #fff;
+}
+
+DIV#messageContent P
+{
+  line-height: 3em;
+}
+
+DIV#messageContent P IMG
+{
+  border: 0px;
+  vertical-align: middle;
+  margin-right: 1em;
+}
+
+.aptview_title
+{
+  color: #000000;
+  font-weight: bold;
+}
+
+.aptview_text
+{
+  color: #000000;
+}
+
+.apt_other
+{
+  color: #000000;
+}
+
+.apt_other_print
+{
+  font-style: italic;
+}
+
+.anais_me
+{
+  color: #0000FF;
+}
+
+.anais_uids
+{
+}
+
+
+/* new stuff for Thunderbird like mailer */
+
+.vertframerow
+{
+  border-top-color: white;
+  border-top-width: 1px;
+  border-top-style: solid;
+  border-bottom-color: #808080;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+  background-color: #dcdad5;
+}
+
+.foldercell
+{
+  width: 25%;
+}
+
+.contentcell
+{
+}
+
+.embedwhite_out
+{
+  border-width: 1px;
+  border-style: solid;
+  border-top-color: #808080;
+  border-left-color: #808080;
+  border-bottom-color: white;
+  border-right-color: white;
+}
+
+.embedwhite_in
+{
+  border-width: 1px;
+  border-style: solid;
+  border-top-color: #808080; /* TODO */
+  border-left-color: #808080; /* TODO */
+  border-bottom-color: #808080;
+  border-right-color: #808080;
+
+  background-color: white;
+  /* height: 300px; */
+  /* height: 100%; */
+}
+
+.titlediv
+{
+  height: 24px;
+  vertical-align: middle;
+  padding-top: 6px;
+  padding-left: 6px;
+}
+
+table.titletable
+{
+  height: 24px;
+  vertical-align: middle;
+  padding-top: 6px;
+  padding-left: 6px;
+}
+
+table.titletable td.titlecell SELECT
+{ 
+  display: -moz-popup;
+  border-top: 1px solid #fff;
+  border-left: 1px solid #fff;
+  border-right: 2px solid #222;
+  border-bottom: 2px solid #222;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  background: #dcdad5;
+}
+
+.whitesec_title
+{
+  background-color: #dcdad5;
+  padding: 4px;
+}
+
+.treecell
+{
+  color: black;
+  vertical-align: bottom;
+  padding-left: 4px; /* move away from the icon */
+  padding-right: 2px; /* move away from the right border */
+  white-space: nowrap;
+}
+
+DIV#folderTreeContent TABLE TD
+{ height: 18px;
+  border-top: 1px solid #fff;
+  margin: 0px;
+  padding: 0px; }
+
+/* mail tableview */
+
+span.mailer_datefield
+{
+  white-space: nowrap;
+}
+
+td.mailer_readmailsubject
+{
+  background-image: url(message-mail-read.png) !important;
+  background-repeat: no-repeat !important;
+  background-position: 0px 0px !important;
+  padding-left: 20px !important;
+}
+
+td.mailer_unreadmailsubject
+{
+  background-image: url(message-mail.png) !important;
+  background-repeat: no-repeat !important;
+  background-position: 0px 0px !important;
+  padding-left: 20px !important;
+  font-weight: bold !important;
+}
+
+td.mailer_readmailsubject a
+{
+  color: black;
+  text-decoration: none;
+}
+
+td.mailer_unreadmailsubject a
+{
+  color: black;
+  text-decoration: none;
+}
+
+td.mailer_listcell_deleted
+{
+  text-decoration: line-through;
+}
+
+td.mailer_listcell_regular a
+{
+  color: black;
+  text-decoration: none;
+}
+
+IMG.mailerReadIcon
+{ 
+/*   TODO
+ */
+}
+
+div.mailer_readicon
+{
+  /* TODO: use Thunderbird icon */
+  background-image: url(icon_read.gif);
+  background-repeat: no-repeat;
+  background-position: 0px 4px;
+}
+
+div.mailer_readicon a
+{
+  width: 17px;
+  height: 17px;
+  margin: 0px auto;
+  display: block;
+}
+
+div.mailerUnreadIcon
+{
+  /* TODO: use Thunderbird icon */
+  background-image: url(icon_unread.gif);
+  background-repeat: no-repeat;
+  background-position: 0px 4px;
+}
+
+div.mailer_unreadicon a
+{
+  width: 17px;
+  height: 17px;
+  margin: 0px auto;
+  display: block;
+}
+
+/* fields (key/value UI), eg used in mail viewer */
+
+table.mailer_fieldtable
+{
+  top: 0px;
+  left: 0px;
+  padding-top: .5em;
+  overflow-y: auto;
+  overflow-x: hidden;
+  height: 6.5em;
+  border-bottom: 1px solid #808080;
+  background: #dbdad5;
+}
+
+div.mailer_mailcontent
+{
+  background-color: #fff;
+  position: absolute;
+  padding: .5em;
+  margin-top: .5em;
+  top: 10em;
+  overflow: auto;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+}
+
+DIV#messageContent div.mailer_mailcontent
+{
+  top: 6em;
+}
+
+td.mailer_fieldname
+{
+  white-space: nowrap;
+  padding-left: 1em;
+  text-align: right;
+  font-weight: bold;
+  vertical-align: top;
+}
+
+td.mailer_fieldvalue
+{
+  width: 95%;
+}
+
+td.mailer_subjectfieldvalue
+{
+  font-weight: bold;
+}
+
+td.mailer_fieldvalue a
+{
+  text-decoration: underline;
+  vertical-align: top;
+}
+
+img.mailer_imagecontent
+{
+  border: 0px;
+}
+
+DIV.mailer_plaincontent
+{ 
+  font-family: monospace, fixed;
+  white-space: normal;
+  font-size: inherit;
+  margin: 0px;
+  padding: 0px;
+}
+
+/* attachment editor */
+
+form#attachment_form
+{
+  background-color: #dcdad5;
+  padding: 1px;
+}
+
+div#attachment_list
+{
+  border-top-color: white;
+  border-top-width: 1px;
+  border-top-style: solid;
+}
+
+div#attachment_upload
+{
+  border-bottom-color: #808080;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+  padding: 4px;
+}
+
+td.attachment_uplabel
+{
+  width: 15%;
+  text-align: left;
+}
+
+/* attachment link viewer */
+
+div.linked_attachment_frame
+{
+  background-color: #dcdad5;
+  padding: 4px;
+}
+
+div.linked_attachment_body
+{
+  padding: 4px;
+  border-width: 1px;
+  border-style: solid;
+  border-top-color: white;
+  border-left-color: white;
+  border-bottom-color: #808080;
+  border-right-color: #808080;
+}
+
+div.linked_attachment_meta
+{
+  color: #444444;
+  font-style: italic;
+  border-width: 0;
+  padding: 2px;
+}
+
+table.linked_attachment_meta
+{
+  color: #444444;
+  font-style: italic;
+}
+
+/* folder tree (js) )*/
+DIV.dTreeNode A SPAN.nodeName
+{
+  margin: 0px .2em;
+  padding-left: .2em;
+  padding-right: .2em;
+}
+
+DIV.dTreeNode A._selected SPAN.nodeName
+{
+  background: #4b6983;
+  color: #fff;
+}
+
+DIV.dTreeNode SPAN._dragOver
+{ 
+  background: #4b6983;
+  color: #fff;
+}
+
+/* drag-n-drop */
+IMG.dragMessage
+{
+  position: absolute;
+  visibility: hidden;
+  border: 0px;
+  -moz-opacity: 0.7;
+}
+
+TABLE#addr_table
+{ 
+  margin-left: 30%;
+  width: 100%;
+}
+
+TABLE#messageList
+{ 
+  display: block;
+  position: absolute;
+  background: #fff;
+  color: #000;  
+  width: 100%;
+  left: 0px;
+  right: 0px;
+  top: 2em;
+  bottom: 0px;
+  overflow: auto;
+}
+
+TABLE#messageList TBODY
+{
+  right: 0px;
+  left: 0px;
+  bottom: 3em;
+  width: 100%;
+  background: #fff;
+  color: #000;
+}
+
+TABLE#messageList TD
+{ 
+  height: 1.2em;
+}
+
+TABLE#messageList TR._selected TD
+{ 
+  background: #4b6983;
+  color: #fff;
+}
+
+TABLE#messageList TR._deleted TD
+{ 
+  text-decoration: line-through;
+}
+
+/* drag handles */
+DIV#verticalDragHandle
+{
+  cursor: e-resize;
+  top: 7.5em;
+  left: 15em;
+  width: 5px;
+  bottom: 0px;
+}
+
+DIV#rightDragHandle
+{ 
+  cursor: n-resize;
+  top: 18em;
+  left: 0px;
+  right: 0px;
+  height: 5px;
+}
+
+TD.messageFlagColumn
+{
+  width: 1em !important;
+}
diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js
new file mode 100644 (file)
index 0000000..3c150cf
--- /dev/null
@@ -0,0 +1,1068 @@
+/*
+  Copyright (C) 2005 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+/* JavaScript for SOGo Mailer */
+
+/*
+  DOM ids available in mail list view:
+    row_$msgid
+    div_$msgid
+    readdiv_$msgid
+    unreaddiv_$msgid
+
+  Window Properties:
+    width, height
+    bool: resizable, scrollbars, toolbar, location, directories, status,
+          menubar, copyhistory
+*/
+
+var currentMessages = new Array();
+var maxCachedMessages = 20;
+var cachedMessages = new Array();
+var currentMailbox = '';
+/* mail list */
+
+function openMessageWindow(msguid, url) {
+  var wId = '';
+  if (msguid) {
+    wId += "SOGo_msg_" + msguid;
+    markMailReadInWindow(window, msguid);
+  }
+  var msgWin = window.open(url, wId,
+                          "width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
+                           + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+  if (msguid) {
+    msgWin.messageId = msguid;
+    msgWin.messageURL = ApplicationBaseURL + currentMailbox + "/" + msguid;
+  }
+  msgWin.focus();
+
+  return false;
+}
+
+function onMessageDoubleClick(event) {
+  resetSelection(window);
+  var msguid = this.parentNode.id.substr(4);
+  
+  return openMessageWindow(msguid,
+                           ApplicationBaseURL + currentMailbox + "/"
+                           + msguid + "/popupview");
+}
+
+function toggleMailSelect(sender) {
+  var row;
+  row = $(sender.name);
+  row.className = sender.checked ? "tableview_selected" : "tableview";
+}
+
+function clearSearch(sender) {
+  var searchField = window.$("search");
+  if (searchField) searchField.value="";
+  return true;
+}
+
+/* mail editor */
+
+function validateEditorInput(sender) {
+  var errortext = "";
+  var field;
+  
+  field = document.pageform.subject;
+  if (field.value == "")
+    errortext = errortext + labels.error_missingsubject + "\n";
+
+  if (!UIxRecipientSelectorHasRecipients())
+    errortext = errortext + labels.error_missingrecipients + "\n";
+  
+  if (errortext.length > 0) {
+    alert(labels.error_validationfailed.decodeEntities() + ":\n"
+          + errortext.decodeEntities());
+    return false;
+  }
+  return true;
+}
+
+function clickedEditorSend(sender) {
+  if (!validateEditorInput(sender))
+    return false;
+
+  document.pageform.action="send";
+  document.pageform.submit();
+  // if everything is ok, close the window
+  return true;
+}
+
+function clickedEditorAttach(sender) {
+  var urlstr;
+  
+  urlstr = "viewAttachments";
+  window.open(urlstr, "SOGo_attach",
+             "width=320,height=320,resizable=1,scrollbars=1,toolbar=0," +
+             "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+  return false; /* stop following the link */
+}
+
+function clickedEditorSave(sender) {
+  document.pageform.action="save";
+  document.pageform.submit();
+  refreshOpener();
+  return true;
+}
+
+function clickedEditorDelete(sender) {
+  document.pageform.action="delete";
+  document.pageform.submit();
+  refreshOpener();
+  window.close();
+  return true;
+}
+
+function openAddressbook(sender) {
+  var urlstr;
+  
+  urlstr = ApplicationBaseURL + "/../Contacts/?popup=YES";
+  var w = window.open(urlstr, "Addressbook",
+                      "width=640,height=400,resizable=1,scrollbars=1,toolbar=0,"
+                      + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+  w.focus();
+
+  return false;
+}
+
+/* mail list DOM changes */
+
+function markMailInWindow(win, msguid, markread) {
+  var msgDiv;
+
+  msgDiv = win.$("div_" + msguid);
+  if (msgDiv) {
+    if (markread) {
+      msgDiv.removeClassName("mailer_unreadmailsubject");
+      msgDiv.addClassName("mailer_readmailsubject");
+      msgDiv = win.$("unreaddiv_" + msguid);
+      if (msgDiv)
+        {
+          msgDiv.setAttribute("class", "mailerUnreadIcon");
+          msgDiv.setAttribute("id", "readdiv_" + msguid);
+          msgDiv.setAttribute("src", ResourcesURL + "/icon_read.gif");
+          msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
+                              + " 'markMessageUnread', " + msguid
+                              + ", false);"
+                              +" return false;");
+          var title = msgDiv.getAttribute("title-markunread");
+          if (title)
+            msgDiv.setAttribute("title", title);
+        }
+    }
+    else {
+      msgDiv.removeClassName('mailer_readmailsubject');
+      msgDiv.addClassName('mailer_unreadmailsubject');
+      msgDiv = win.$("readdiv_" + msguid);
+      if (msgDiv)
+        {
+          msgDiv.setAttribute("class", "mailerReadIcon");
+          msgDiv.setAttribute("id", "unreaddiv_" + msguid);
+          msgDiv.setAttribute("src", ResourcesURL + "/icon_unread.gif");
+          msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
+                              + " 'markMessageRead', " + msguid
+                              + ", true);"
+                              +" return false;");
+          var title = msgDiv.getAttribute("title-markread");
+          if (title)
+            msgDiv.setAttribute("title", title);
+        }
+    }
+    return true;
+  }
+  else
+    return false;
+}
+
+function markMailReadInWindow(win, msguid) {
+  /* this is called by UIxMailView with window.opener */
+  return markMailInWindow(win, msguid, true);
+}
+
+/* main window */
+
+function reopenToRemoveLocationBar() {
+  // we cannot really use this, see below at the close comment
+  if (window.locationbar && window.locationbar.visible) {
+    newwin = window.open(window.location.href, "SOGo",
+                        "width=800,height=600,resizable=1,scrollbars=1," +
+                        "toolbar=0,location=0,directories=0,status=0," + 
+                        "menubar=0,copyhistory=0");
+    if (newwin) {
+      window.close(); // this does only work for windows opened by scripts!
+      newwin.focus();
+      return true;
+    }
+    return false;
+  }
+  return true;
+}
+
+/* mail list reply */
+
+function openMessageWindowsForSelection(action)
+{
+  if (document.body.hasClassName("popup"))
+    win = openMessageWindow(window.messageId,
+                            window.messageURL + "/" + action /* url */);
+  else {
+  var messageList = $("messageList");
+  var rows  = messageList.getSelectedRowsId();
+  var idset = "";
+  for (var i = 0; i < rows.length; i++)
+    win = openMessageWindow(rows[i].substr(4)        /* msguid */,
+                           ApplicationBaseURL + currentMailbox
+                            + "/" + rows[i].substr(4)
+                            + "/" + action /* url */);
+  }
+
+  return false;
+}
+
+function mailListMarkMessage(event) {
+  var http = createHTTPClient();
+  var url = ApplicationBaseURL + currentMailbox + "/" + action + "?uid=" + msguid;
+
+  if (http) {
+    // TODO: add parameter to signal that we are only interested in OK
+    http.open("POST", url + "&jsonly=1", false /* not async */);
+    http.send("");
+    if (http.status != 200) {
+      // TODO: refresh page?
+      alert("Message Mark Failed: " + http.statusText);
+      window.location.reload();
+    }
+    else {
+      markMailInWindow(window, msguid, markread);
+    }
+  }
+  else {
+    window.location.href = url;
+  }
+}
+
+/* maillist row highlight */
+
+var oldMaillistHighlight = null; // to remember deleted/selected style
+
+function ml_highlight(sender)
+{
+  oldMaillistHighlight = sender.className;
+  if (oldMaillistHighlight == "tableview_highlight")
+    oldMaillistHighlight = null;
+  sender.className = "tableview_highlight";
+}
+
+function ml_lowlight(sender)
+{
+  if (oldMaillistHighlight) {
+    sender.className = oldMaillistHighlight;
+    oldMaillistHighlight = null;
+  }
+  else
+    sender.className = "tableview";
+}
+
+
+/* folder operations */
+
+function ctxFolderAdd(sender) {
+  var folderName;
+  
+  folderName = prompt("Foldername: ");
+  if (folderName == undefined)
+    return false;
+  if (folderName == "")
+    return false;
+  
+  // TODO: should use a form-POST or AJAX
+  window.location.href = "createFolder?name=" + escape(folderName);
+  return false;
+}
+
+function ctxFolderDelete(sender) {
+  if (!confirm("Delete current folder?").decodeEntities())
+    return false;
+  
+  // TODO: should use a form-POST or AJAX
+  window.location.href = "deleteFolder";
+  return false;
+}
+
+/* bulk delete of messages */
+
+function uixDeleteSelectedMessages(sender) {
+  var failCount = 0;
+  
+  var messageList = $("messageList");
+  var rowIds = messageList.getSelectedRowsId();
+
+  for (var i = 0; i < rowIds.length; i++) {
+    var url, http;
+    var rowId = rowIds[i].substr(4);
+    /* send AJAX request (synchronously) */
+
+    var messageId = currentMailbox + "/" + rowId;
+    url = ApplicationBaseURL + messageId + "/trash?jsonly=1";
+    http = createHTTPClient();
+    http.open("GET", url, false /* not async */);
+    http.send("");
+    if (http.status != 200) { /* request failed */
+      failCount++;
+      http = null;
+      continue;
+    } else {
+      deleteCachedMessage(messageId);
+      if (currentMessages[currentMailbox] == rowId) {
+        var div = $('messageContent');
+        div.innerHTML = "";
+        currentMessages[currentMailbox] = null;
+      }
+    }
+    http = null;
+
+    /* remove from page */
+
+    /* line-through would be nicer, but hiding is OK too */
+    var row = $(rowIds[i]);
+    row.parentNode.removeChild(row);
+  }
+
+  if (failCount > 0)
+    alert("Could not delete " + failCount + " messages!");
+  
+  return false;
+}
+
+function moveMessages(rowIds, folder) {
+  var failCount = 0;
+
+  for (var i = 0; i < rowIds.length; i++) {
+    var url, http;
+
+    /* send AJAX request (synchronously) */
+    
+    var messageId = currentMailbox + "/" + rowIds[i];
+    url = ApplicationBaseURL + messageId + "/move?jsonly=1&tofolder=" + folder;
+    http = createHTTPClient();
+    http.open("GET", url, false /* not async */);
+    http.send("");
+    if (http.status == 200) {
+      var row = $("row_" + rowIds[i]);
+      row.parentNode.removeChild(row);
+      deleteCachedMessage(messageId);
+      if (currentMessages[currentMailbox] == rowIds[i]) {
+        var div = $('messageContent');
+        div.innerHTML = "";
+        currentMessages[currentMailbox] = null;
+      }
+    }
+    else /* request failed */
+      failCount++;
+
+    /* remove from page */
+
+    /* line-through would be nicer, but hiding is OK too */
+  }
+
+  if (failCount > 0)
+    alert("Could not move " + failCount + " messages!");
+  
+  return failCount;
+}
+
+function onMenuDeleteMessage(event) {
+  uixDeleteSelectedMessages();
+  event.preventDefault();
+}
+
+function onMailboxTreeItemClick(event) {
+  var topNode = $('d');
+  var mailbox = this.parentNode.getAttribute("dataname");
+
+  if (topNode.selectedEntry)
+    topNode.selectedEntry.deselect();
+  this.select();
+  topNode.selectedEntry = this;
+
+  openMailbox(mailbox);
+  event.preventDefault();
+}
+
+function refreshMailbox() {
+  openMailbox(currentMailbox, true);
+
+  return false;
+}
+
+function openMailbox(mailbox, reload)
+{
+  if (mailbox != currentMailbox || reload) {
+    currentMailbox = mailbox;
+    var url = ApplicationBaseURL + mailbox + "/view?noframe=1&desc=1";
+    var mailboxContent = $("mailboxContent");
+    var rightDragHandle = $("rightDragHandle");
+    var messageContent = $("messageContent");
+    messageContent.innerHTML = '';
+    if (mailbox.lastIndexOf("/") == 0) {
+      var url = (ApplicationBaseURL + currentMailbox + "/"
+                 + "/view?noframe=1");
+      if (document.messageAjaxRequest) {
+        document.messageAjaxRequest.aborted = true;
+        document.messageAjaxRequest.abort();
+      }
+      document.messageAjaxRequest
+        = triggerAjaxRequest(url, messageCallback);
+      mailboxContent.innerHTML = '';
+      mailboxContent.style.visibility = "hidden;";
+      rightDragHandle.style.visibility = "hidden;";
+      messageContent.style.top = "0px;";
+    } else {
+      if (document.messageListAjaxRequest) {
+        document.messageListAjaxRequest.aborted = true;
+        document.messageListAjaxRequest.abort();
+      }
+      if (currentMessages[mailbox]) {
+        loadMessage(currentMessages[mailbox]);
+        url += '&pageforuid=' + currentMessages[mailbox];
+      }
+      document.messageListAjaxRequest
+        = triggerAjaxRequest(url, messageListCallback,
+                             currentMessages[mailbox]);
+      if (mailboxContent.style.visibility == "hidden") {
+        mailboxContent.style.visibility = "visible;";
+        rightDragHandle.style.visibility = "visible;";
+        messageContent.style.top = (rightDragHandle.offsetTop
+                                    + rightDragHandle.offsetHeight
+                                    + 'px;');
+      }
+    }
+  }
+//   triggerAjaxRequest(mailbox, 'toolbar', toolbarCallback);
+}
+
+function openMailboxAtIndex(element) {
+  var idx = element.getAttribute("idx");
+  var url = ApplicationBaseURL + currentMailbox + "/view?noframe=1&idx=" + idx;
+
+  if (document.messageListAjaxRequest) {
+    document.messageListAjaxRequest.aborted = true;
+    document.messageListAjaxRequest.abort();
+  }
+  document.messageListAjaxRequest
+    = triggerAjaxRequest(url, messageListCallback);
+
+  return false;
+}
+
+function messageListCallback(http)
+{
+  var div = $('mailboxContent');
+
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.messageListAjaxRequest = null;
+    div.innerHTML = http.responseText;
+    var selected = http.callbackData;
+    if (selected) {
+      var row = $('row_' + selected);
+      row.select();
+    }
+    configureMessageListEvents();
+    configureSortableTableHeaders();
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function onMessageContextMenu(event)
+{
+  var menu = $('messageListMenu');
+  menu.addEventListener("hideMenu", onMessageContextMenuHide, false);
+  onMenuClick(event, 'messageListMenu');
+
+  var topNode = $('messageList');
+  var selectedNodes = topNode.getSelectedRows();
+  for (var i = 0; i < selectedNodes.length; i++)
+    selectedNodes[i].deselect();
+  topNode.menuSelectedRows = selectedNodes;
+  topNode.menuSelectedEntry = this;
+  this.select();
+}
+
+function onMessageContextMenuHide(event)
+{
+  var topNode = $('messageList');
+
+  if (topNode.menuSelectedEntry) {
+    topNode.menuSelectedEntry.deselect();
+    topNode.menuSelectedEntry = null;
+  }
+  if (topNode.menuSelectedRows) {
+    var nodes = topNode.menuSelectedRows;
+    for (var i = 0; i < nodes.length; i++)
+      nodes[i].select();
+    topNode.menuSelectedRows = null;
+  }
+}
+
+function onFolderMenuClick(event)
+{
+  var onhide, menuName;
+  
+  var menutype = this.parentNode.getAttribute("datatype");
+  log("parentNode: " + this.parentNode.tagName);
+  log("menutype: " + menutype);
+  if (menutype) {
+    if (menutype == "inbox") {
+      menuName = "inboxIconMenu";
+    } else if (menutype == "account") {
+      menuName = "accountIconMenu";
+    } else if (menutype == "trash") {
+      menuName = "trashIconMenu";
+    } else {
+      menuName = "mailboxIconMenu";
+    }
+  } else {
+    menuName = "mailboxIconMenu";
+  }
+
+  var menu = $(menuName);
+  menu.addEventListener("hideMenu", onFolderMenuHide, false);
+  onMenuClick(event, menuName);
+
+  var topNode = $('d');
+  if (topNode.selectedEntry)
+    topNode.selectedEntry.deselect();
+  if (topNode.menuSelectedEntry)
+    topNode.menuSelectedEntry.deselect();
+  topNode.menuSelectedEntry = this;
+  this.select();
+}
+
+function onFolderMenuHide(event)
+{
+  var topNode = $('d');
+
+  if (topNode.menuSelectedEntry) {
+    topNode.menuSelectedEntry.deselect();
+    topNode.menuSelectedEntry = null;
+  }
+  if (topNode.selectedEntry)
+    topNode.selectedEntry.select();
+}
+
+function deleteCachedMessage(messageId) {
+  var done = false;
+  var counter = 0;
+
+  while (counter < cachedMessages.length
+         && !done)
+    if (cachedMessages[counter]
+        && cachedMessages[counter]['idx'] == messageId) {
+      cachedMessages.splice(counter, 1);
+      done = true;
+    }
+    else
+      counter++;
+}
+
+function getCachedMessage(idx)
+{
+  var message = null;
+  var counter = 0;
+
+  while (counter < cachedMessages.length
+         && message == null)
+    if (cachedMessages[counter]
+        && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
+      message = cachedMessages[counter];
+    else
+      counter++;
+
+  return message;
+}
+
+function storeCachedMessage(cachedMessage)
+{
+  var oldest = -1;
+  var timeOldest = -1;
+  var counter = 0;
+
+  if (cachedMessages.length < maxCachedMessages)
+    oldest = cachedMessages.length;
+  else {
+    while (cachedMessages[counter]) {
+      if (oldest == -1
+          || cachedMessages[counter]['time'] < timeOldest) {
+        oldest = counter;
+        timeOldest = cachedMessages[counter]['time'];
+      }
+      counter++;
+    }
+
+    if (oldest == -1)
+      oldest = 0;
+  }
+
+  cachedMessages[oldest] = cachedMessage;
+}
+
+function onMessageSelectionChange()
+{
+  var rows = this.getSelectedRowsId();
+  if (rows.length == 1) {
+    var idx = rows[0].substr(4);
+
+    if (currentMessages[currentMailbox] != idx) {
+      currentMessages[currentMailbox] = idx;
+      loadMessage(idx);
+    }
+  }
+}
+
+function loadMessage(idx)
+{
+  var cachedMessage = getCachedMessage(idx);
+
+  if (document.messageAjaxRequest) {
+    document.messageAjaxRequest.aborted = true;
+    document.messageAjaxRequest.abort();
+  }
+
+  if (cachedMessage == null) {
+    var url = (ApplicationBaseURL + currentMailbox + "/"
+               + idx + "/view?noframe=1");
+    document.messageAjaxRequest
+      = triggerAjaxRequest(url, messageCallback, idx);
+    markMailInWindow(window, idx, true);
+  } else {
+    var div = $('messageContent');
+    div.innerHTML = cachedMessage['text'];
+    cachedMessage['time'] = (new Date()).getTime();
+    document.messageAjaxRequest = null;
+  }
+}
+
+function messageCallback(http)
+{
+  var div = $('messageContent');
+
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.messageAjaxRequest = null;
+    div.innerHTML = http.responseText;
+    
+    if (http.callbackData) {
+      var cachedMessage = new Array();
+      cachedMessage['idx'] = currentMailbox + '/' + http.callbackData;
+      cachedMessage['time'] = (new Date()).getTime();
+      cachedMessage['text'] = http.responseText;
+      if (cachedMessage['text'].length < 30000)
+        storeCachedMessage(cachedMessage);
+    }
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function processMailboxMenuAction(mailbox)
+{
+  var currentNode, upperNode;
+  var mailboxName;
+  var action;
+
+  mailboxName = mailbox.getAttribute('mailboxname');
+  currentNode = mailbox;
+  upperNode = null;
+
+  while (currentNode
+         && !currentNode.hasAttribute('mailboxaction'))
+    currentNode = currentNode.parentNode.parentNode.parentMenuItem;
+
+  if (currentNode)
+    {
+      action = currentNode.getAttribute('mailboxaction');
+//       var rows  = collectSelectedRows();
+//       var rString = rows.join(', ');
+//       alert("performing '" + action + "' on " + rString
+//             + " to " + mailboxName);
+    }
+}
+
+var rowSelectionCount = 0;
+
+validateControls();
+
+function showElement(e, shouldShow) {
+  e.style.display = shouldShow ? "" : "none";
+}
+
+function enableElement(e, shouldEnable) {
+  if(!e)
+    return;
+  if(shouldEnable) {
+    if(e.hasAttribute("disabled"))
+      e.removeAttribute("disabled");
+  }
+  else {
+    e.setAttribute("disabled", "1");
+  }
+}
+
+function validateControls() {
+  var e = $("moveto");
+  this.enableElement(e, rowSelectionCount > 0);
+}
+
+function moveTo(uri) {
+  alert("MoveTo: " + uri);
+}
+
+function deleteSelectedMails()
+{
+}
+
+/* message menu entries */
+function onMenuOpenMessage(event)
+{
+  var node = getParentMenu(event.target).menuTarget.parentNode;
+  var msgId = node.getAttribute('id').substr(4);
+
+  return openMessageWindow(msgId,
+                           ApplicationBaseURL + currentMailbox
+                           + "/" + msgId + "/view");
+}
+
+/* contacts */
+function newContactFromEmail(sender) {
+  var mailto = sender.parentNode.parentNode.menuTarget.innerHTML;
+
+  var emailre
+    = /([a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z])/g;
+  emailre.exec(mailto);
+  email = RegExp.$1;
+
+  var namere = /(\w[\w\ _-]+)\ (&lt;|<)/;
+  var c_name = '';
+  if (namere.test(mailto)) {
+    namere.exec(mailto);
+    c_name += RegExp.$1;
+  }
+
+  if (email.length > 0)
+    {
+      emailre.exec("");
+      var url = UserFolderURL + "Contacts/new?contactEmail=" + email;
+      if (c_name)
+        url += "&contactFN=" + c_name;
+      w = window.open(url, null,
+                      "width=546,height=490,resizable=1,scrollbars=1,toolbar=0,"
+                      + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+      w.focus();
+    }
+
+  return false; /* stop following the link */
+}
+
+function newEmailTo(sender) {
+  return openMailTo(sender.parentNode.parentNode.menuTarget.innerHTML);
+}
+
+function expandUpperTree(node)
+{
+  var currentNode = node.parentNode;
+
+  while (currentNode.className != "dtree")
+    {
+      if (currentNode.className == 'clip')
+        {
+          var id = currentNode.getAttribute("id");
+          var number = parseInt(id.substr(2));
+          if (number > 0)
+            {
+              var cn = d.aNodes[number];
+              d.nodeStatus(1, number, cn._ls);
+            }
+        }
+      currentNode = currentNode.parentNode;
+    }
+}
+
+function initMailboxSelection(mailboxName)
+{
+  currentMailbox = mailboxName;
+
+  var tree = $("d");
+  var treeNodes = document.getElementsByClassName("dTreeNode", tree);
+  var i = 0;
+  while (i < treeNodes.length
+         && treeNodes[i].getAttribute("dataname") != currentMailbox)
+    i++;
+  if (i < treeNodes.length) {
+    var links = document.getElementsByClassName("node", treeNodes[i]);
+    if (tree.selectedEntry)
+      tree.selectedEntry.deselect();
+    links[0].select();
+    tree.selectedEntry = links[0];
+    expandUpperTree(links[0]);
+  }
+}
+
+function onHeaderClick(event)
+{
+  if (document.messageListAjaxRequest) {
+    document.messageListAjaxRequest.aborted = true;
+    document.messageListAjaxRequest.abort();
+  }
+  url = ApplicationBaseURL + currentMailbox + "/" + this.link;
+  if (!this.link.match(/noframe=/))
+    url += "&noframe=1";
+  document.messageListAjaxRequest
+    = triggerAjaxRequest(url, messageListCallback);
+
+  event.preventDefault();
+}
+
+function onSearchFormSubmit()
+{
+  log ("search not implemented");
+
+  return false;
+}
+
+function pouetpouet(event) {
+  window.alert("pouet pouet");
+}
+
+var mailboxSpanAcceptType = function(type) {
+  return (type == "mailRow");
+}
+
+var mailboxSpanEnter = function() {
+  this.addClassName("_dragOver");
+}
+
+var mailboxSpanExit = function() {
+  this.removeClassName("_dragOver");
+}
+
+var mailboxSpanDrop = function(data) {
+  var success = false;
+
+  if (data) {
+    var folder = this.parentNode.parentNode.getAttribute("dataname");
+    if (folder != currentMailbox)
+      success = (moveMessages(data, folder) == 0);
+  }
+  else
+    success = false;
+
+  return success;
+}
+
+var plusSignEnter = function() {
+  var nodeNr = parseInt(this.id.substr(2));
+  if (!d.aNodes[nodeNr]._io)
+    this.plusSignTimer = setTimeout("openPlusSign('" + nodeNr + "');", 1000);
+}
+
+var plusSignExit = function() {
+  if (this.plusSignTimer) {
+    clearTimeout(this.plusSignTimer);
+    this.plusSignTimer = null;
+  }
+}
+
+function openPlusSign(nodeNr) {
+  d.nodeStatus(1, nodeNr, d.aNodes[nodeNr]._ls);
+  d.aNodes[nodeNr]._io = 1;
+  this.plusSignTimer = null;
+}
+
+var messageListGhost = function () {
+  var newDiv = document.createElement("div");
+//   newDiv.style.width = "25px;";
+//   newDiv.style.height = "25px;";
+  newDiv.style.backgroundColor = "#aae;";
+  newDiv.style.border = "2px solid #a3a;";
+  newDiv.style.padding = "5px;";
+  newDiv.ghostOffsetX = 10;
+  newDiv.ghostOffsetY = 5;
+
+  var imgCode = '<img src="' + ResourcesURL + '/message-mail.png" />';
+
+  var current = this;
+  while (!current.getSelectedRows)
+    current = current.parentNode;
+  var count = current.getSelectedRows().length;
+  var text = imgCode + '<br />' + count + ' messages...';
+  newDiv.innerHTML = text;
+
+  return newDiv;
+}
+
+var messageListData = function(type) {
+  var rows = this.getSelectedRowsId();
+  var msgIds = new Array();
+  for (var i = 0; i < rows.length; i++)
+    msgIds.push(rows[i].substr(4));
+
+  return msgIds;
+}
+
+function configureMessageListEvents() {
+  var messageList = $("messageList");
+  if (messageList) {
+    messageList.addEventListener("selectionchange",
+                                 onMessageSelectionChange, false);
+    var rows = messageList.tBodies[0].rows;
+    var start = 0;
+    if (rows.length > 1) {
+      while (rows[start].cells[0].hasClassName("tbtv_headercell")
+             || rows[start].cells[0].hasClassName("tbtv_navcell"))
+        start++;
+      for (var i = start; i < rows.length; i++) {
+        rows[i].addEventListener("mousedown", onRowClick, false);
+        rows[i].addEventListener("contextmenu", onMessageContextMenu, false);
+        
+        rows[i].dndTypes = function() { return new Array("mailRow"); };
+        rows[i].dndGhost = messageListGhost;
+        rows[i].dndDataForType = messageListData;
+        document.DNDManager.registerSource(rows[i]);
+        
+        for (var j = 0; j < rows[i].cells.length; j++) {
+          var cell = rows[i].cells[j];
+          cell.addEventListener("mousedown", listRowMouseDownHandler, false);
+          if (j == 2 || j == 3 || j == 5)
+            cell.addEventListener("dblclick", onMessageDoubleClick, false);
+          else if (j == 4) {
+            var img = cell.childNodesWithTag("img")[0];
+            img.addEventListener("click", mailListMarkMessage, false);
+          }
+        }
+      }
+    }
+  }
+}
+
+function configureDragHandles() {
+  var handle = $("verticalDragHandle");
+  if (handle) {
+    handle.addInterface(SOGoDragHandlesInterface);
+    handle.leftBlock=$("leftPanel");
+    handle.rightBlock=$("rightPanel");
+  }
+
+  handle = $("rightDragHandle");
+  if (handle) {
+    handle.addInterface(SOGoDragHandlesInterface);
+    handle.upperBlock=$("mailboxContent");
+    handle.lowerBlock=$("messageContent");
+  }
+}
+
+/* dnd */
+function initDnd() {
+  log ("MailerUI initDnd");
+
+  var tree = $("d");
+  if (tree) {
+    var images = tree.getElementsByTagName("img");
+    for (var i = 0; i < images.length; i++) {
+      if (images[i].id[0] == 'j') {
+        images[i].dndAcceptType = mailboxSpanAcceptType;
+        images[i].dndEnter = plusSignEnter;
+        images[i].dndExit = plusSignExit;
+        document.DNDManager.registerDestination(images[i]);
+      }
+    }
+    var nodes = document.getElementsByClassName("leaf", tree);
+    for (var i = 0; i < nodes.length; i++) {
+      nodes[i].dndAcceptType = mailboxSpanAcceptType;
+      nodes[i].dndEnter = mailboxSpanEnter;
+      nodes[i].dndExit = mailboxSpanExit;
+      nodes[i].dndDrop = mailboxSpanDrop;
+      document.DNDManager.registerDestination(nodes[i]);
+    }
+  }
+}
+
+/* stub */
+
+function refreshContacts() {
+}
+
+function openInbox(node) {
+  var done = false;
+  openMailbox(node.parentNode.getAttribute("dataname"));
+  node.select();
+  var currentNode = node.parentNode.parentNode;
+  while (!done) {
+    var number = currentNode.getAttribute("id").substr(2);
+    d.o(number);
+    if (number == "1")
+      done = true;
+    else
+      currentNode = currentNode.parentNode;
+  }
+}
+
+var initMailer = {
+  handleEvent: function (event) {
+    if (!document.body.hasClassName("popup")) {
+      var inboxFound = false;
+      configureMessageListEvents();
+      initDnd();
+      var tree = $("d");
+      var nodes = document.getElementsByClassName("node", tree);
+      for (i = 0; i < nodes.length; i++) {
+        nodes[i].addEventListener("click", onMailboxTreeItemClick, false);
+        nodes[i].addEventListener("contextmenu", onFolderMenuClick, false);
+        if (!inboxFound
+            && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
+          openInbox(nodes[i]);
+          inboxFound = true;
+        }
+      }
+    }
+
+    /*
+, 'onMailboxTreeItemClick(this);'
+<!--      if (typeof(node.datatype) != "undefined") str += ' oncontextmenu="onFolderMenuClick(event, this);"';
+
+    */
+
+  }
+}
+
+function initializeMenus() {
+  var menus = new Array("accountIconMenu", "inboxIconMenu", "trashIconMenu",
+                        "mailboxIconMenu", "addressMenu", "messageListMenu",
+                        "messageContentMenu", "label-menu", "mailboxes-menu",
+                        "mark-menu", "searchMenu");
+  initMenusNamed(menus);
+}
+
+window.addEventListener("load", initMailer, false);
diff --git a/UI/WebServerResources/SOGoDragAndDrop.js b/UI/WebServerResources/SOGoDragAndDrop.js
new file mode 100644 (file)
index 0000000..e0773d1
--- /dev/null
@@ -0,0 +1,274 @@
+/* drag and drop */
+
+/* HTMLElement interface */
+var SOGODragAndDropSourceInterface = {
+  _removeGestureHandlers: function () {
+    window.removeEventListener("mousemove", this.dragGestureMouseMoveHandler, false);
+    window.removeEventListener("mouseup", this.dragGestureMouseUpHandler, false);
+    document._dragGestureStartPoint = null;
+    document._currentMouseGestureObject = null;
+  },
+  bind: function() {
+    this.addEventListener("mousedown", this.dragGestureMouseDownHandler, false);
+  },
+  dragGestureMouseDownHandler: function (event) {
+    if (event.button == 0) {
+      document._dragGestureStartPoint = new Array(event.clientX,
+                                                  event.clientY);
+      document._currentMouseGestureObject = this;
+      window.addEventListener("mousemove", this.dragGestureMouseMoveHandler,
+                              false);
+      window.addEventListener("mouseup", this.dragGestureMouseUpHandler,
+                              false);
+    }
+  },
+  dragGestureMouseUpHandler: function (event) {
+    log("mouseup");
+    document._currentMouseGestureObject._removeGestureHandlers();
+  },
+  dragGestureMouseMoveHandler: function (event) {
+//     log("source mouse move (target: " + event.target + ")");
+    var deltaX = event.clientX - document._dragGestureStartPoint[0];
+    var deltaY = event.clientY - document._dragGestureStartPoint[1];
+    if (Math.sqrt((deltaX * deltaX) + (deltaY * deltaY)) > 10) {
+//       log("event: " + event);
+//       event.stopPropagation();
+//       event.preventDefault();
+      event.returnValue = true;
+      event.cancelBubble = true;
+      var object = document._currentMouseGestureObject;
+      var point = document._dragGestureStartPoint;
+      document.DNDManager.startDragging(object, point);
+      document._currentMouseGestureObject._removeGestureHandlers();
+//       var mouseup = document.createEvent("MouseEvent");
+//       mouseup.initEvent("mouseup", true, true);
+//       event.target.dispatchEvent(mouseup);
+//       var dragStart = document.createEvent("MouseEvents");
+//       dragStart.initMouseEvent("draggesture-hack", true, true, window,
+//                                event.detail, event.screenX, event.screenY,
+//                                event.clientX, event.clientY, event.ctrlKey,
+//                                event.altKey, event.shiftKey, event.metaKey,
+//                                event.button, null);
+//       this.dispatchEvent(dragStart);
+    }
+  }
+}
+
+/* DNDManager */
+document.DNDManager = {
+  lastSource: 0,
+  lastDestination: 0,
+  sources: new Array(),
+  destinations: new Array(),
+  registerSource: function (source) {
+    var id = source.getAttribute("id");
+    if (!id) {
+      id = "_dndSource" + (this.lastSource + 1);
+      source.setAttribute("id", id);
+    }
+    this.sources[id] = source;
+    this.lastSource++;
+    source.addInterface(SOGODragAndDropSourceInterface);
+  },
+  registerDestination: function (destination) {
+    var id = destination.getAttribute("id");
+    if (!id) {
+      id = "_dndDestination" + (this.lastDestination + 1);
+      destination.setAttribute("id", id);
+    }
+    this.destinations[id] = destination;
+    this.lastDestination++;
+  },
+  _lookupSource: function (target) {
+    var source = null;
+    var id = target.getAttribute("id");
+    if (id)
+      source = document.DNDManager.sources[id];
+    return source;
+  },
+  _lookupDestination: function (target) {
+    var destination = null;
+    var id = target.getAttribute("id");
+    if (id)
+      destination = document.DNDManager.destinations[id];
+    return destination;
+  },
+  startDragging: function (object, point) {
+//     log("source gesture intercepted (source: " + object + ")");
+    var source = document.DNDManager._lookupSource (object);
+    if (source) {
+//       log("source known");
+      document.DNDManager.currentDndOperation = new document.DNDOperation(source, point);
+      window.addEventListener("mouseup",
+                              document.DNDManager.destinationDrop, false);
+      window.addEventListener("mouseover",
+                              document.DNDManager.destinationEnter, false);
+      window.addEventListener("mousemove",
+                              document.DNDManager.destinationOver, false);
+      window.addEventListener("mouseout",
+                              document.DNDManager.destinationExit, false);
+    }
+  },
+  destinationEnter: function (event) {
+    var operation = document.DNDManager.currentDndOperation;
+    var destination = document.DNDManager._lookupDestination (event.target);
+    if (operation && destination && destination.dndAcceptType) {
+//       log("enter: " + event.target);
+      operation.type = null;
+      var i = 0;
+      while (operation.type == null
+             && i < operation.types.length) {
+        if (destination.dndAcceptType(operation.types[i])) {
+          operation.type = operation.types[i];
+          operation.setDestination(destination);
+          if (destination.dndEnter)
+            destination.dndEnter(event, operation.source, operation.type);
+        }
+        else
+          i++;
+      }
+    }
+  },
+  destinationExit: function (event) {
+    var operation = document.DNDManager.currentDndOperation;
+    if (operation
+        && operation.destination == event.target) {
+//       log("exit: " + event.target);
+      if (operation.destination.dndExit)
+        event.target.dndExit();
+      operation.setDestination(null);
+    }
+  },
+  destinationOver: function (event) {
+//     log("over: " + event.target);
+//     var operation = document.DNDManager.currentDndOperation;
+//     if (operation
+//         && operation.destination == event.target)
+//       log("over: " + event.target);
+  },
+  destinationDrop: function (event) {
+//     log ("drop...");
+    var operation = document.DNDManager.currentDndOperation;
+    if (operation) {
+      window.removeEventListener("mouseup",
+                                 document.DNDManager.destinationDrop, false);
+      window.removeEventListener("mouseover",
+                                 document.DNDManager.destinationEnter, false);
+      window.removeEventListener("mousemove",
+                                 document.DNDManager.destinationOver, false);
+      window.removeEventListener("mouseout",
+                                 document.DNDManager.destinationExit, false);
+      if (operation.destination == event.target) {
+//         log("drag / drop: " + operation.source + " to " + operation.destination);
+        if (operation.destination.dndExit)
+          event.target.dndExit();
+        if (operation.destination.dndDrop) {
+          var data = null;
+          if (operation.source.dndDataForType)
+            data = operation.source.dndDataForType(operation.type);
+          var result = event.target.dndDrop(data);
+          if (operation.ghost) {
+            if (result)
+              operation.bustGhost();
+            else
+              operation.chaseGhost();
+          }
+        }
+        else
+          if (operation.ghost)
+            operation.chaseGhost();
+      } else {
+        if (operation.ghost)
+          operation.chaseGhost();
+      }
+      document.DNDManager.currentDndOperation = null;
+    }
+  },
+  currentDndOperation: null,
+}
+
+/* DNDOperation */
+document.DNDOperation = function (source, point) {
+  this.startPoint = point;
+  this.source = source;
+  if (source.dndTypes) {
+    this.types = source.dndTypes();
+  }
+  this.type = null;
+  this.destination = null;
+  if (source.dndGhost) {
+    var ghost = source.dndGhost();
+    ghost.style.position = "absolute;";
+    ghost.style.zIndex = 10000;
+    ghost.style.MozOpacity = 0.8;
+    document.body.appendChild(ghost);
+    this.ghost = ghost;
+
+    document.addEventListener("mousemove", this.moveGhost, false);
+  }
+
+  return this;
+};
+
+document.DNDOperation.prototype.setDestination = function(destination) {
+  this.destination = destination;
+}
+
+document.DNDOperation.prototype.moveGhost = function(event) {
+  var offsetX = event.clientX;
+  var offsetY = event.clientY;
+  if (document.DNDManager.currentDndOperation.ghost.ghostOffsetX)
+    offsetX += document.DNDManager.currentDndOperation.ghost.ghostOffsetX;
+  if (document.DNDManager.currentDndOperation.ghost.ghostOffsetY)
+    offsetY += document.DNDManager.currentDndOperation.ghost.ghostOffsetY;
+
+  document.DNDManager.currentDndOperation.ghost.style.left = offsetX + "px;";
+  document.DNDManager.currentDndOperation.ghost.style.top = offsetY + "px;";
+}
+
+document.DNDOperation.prototype.bustGhost = function() {
+  document._dyingOperation = this;
+  document.removeEventListener("mousemove", this.moveGhost, false);
+  this.ghost.bustStep = 10;
+  setTimeout("document._dyingOperation._fadeGhost();", 50);
+}
+
+document.DNDOperation.prototype.chaseGhost = function() {
+  document._dyingOperation = this;
+  document.removeEventListener("mousemove", this.moveGhost, false);
+  this.ghost.bustStep = 25;
+  this.ghost.chaseStep = 25;
+  this.ghost.chaseDeltaX = ((this.ghost.cascadeLeftOffset() - this.startPoint[0])
+                           / this.ghost.chaseStep);
+  this.ghost.chaseDeltaY = ((this.ghost.cascadeTopOffset() - this.startPoint[1])
+                           / this.ghost.chaseStep);
+  setTimeout("document._dyingOperation._chaseGhost();", 20);
+}
+
+document.DNDOperation.prototype._chaseGhost = function() {
+  if (this.ghost.chaseStep) {
+    var newLeft = this.ghost.cascadeLeftOffset() - this.ghost.chaseDeltaX; 
+    var newTop = this.ghost.cascadeTopOffset() - this.ghost.chaseDeltaY;
+    this.ghost.style.MozOpacity = (0.04 * this.ghost.chaseStep);
+    this.ghost.style.left = newLeft + "px;";
+    this.ghost.style.top = newTop + "px;";
+    this.ghost.chaseStep--;
+    setTimeout("document._dyingOperation._chaseGhost();", 20);
+  }
+  else {
+    document.body.removeChild(this.ghost);
+    this.ghost = null;
+  }
+}
+
+document.DNDOperation.prototype._fadeGhost = function() {
+  if (this.ghost.bustStep) {
+    this.ghost.style.MozOpacity = (0.1 * this.ghost.bustStep);
+    this.ghost.bustStep--;
+    setTimeout("document._dyingOperation._fadeGhost();", 50);
+  }
+  else {
+    document.body.removeChild(this.ghost);
+    this.ghost = null;
+  }
+}
diff --git a/UI/WebServerResources/SOGoDragHandles.js b/UI/WebServerResources/SOGoDragHandles.js
new file mode 100644 (file)
index 0000000..aee9509
--- /dev/null
@@ -0,0 +1,134 @@
+var SOGoDragHandlesInterface = {
+  dhType: null,
+  origX: -1,
+  origLeft: -1,
+  origRight: -1,
+  origY: -1, 
+  origUpper: -1,
+  origLower: -1,
+  delta: -1,
+  leftBlock: null,
+  rightBlock: null,
+  upperBlock: null,
+  lowerBlock: null,
+  bind: function () {
+    this.addEventListener("mousedown", this.startHandleDragging, false);
+  },
+  _determineType: function () {
+    if (this.leftBlock && this.rightBlock)
+      this.dhType = 'horizontal';
+    else if (this.upperBlock && this.lowerBlock)
+      this.dhType = 'vertical';
+  },
+  startHandleDragging: function (event) {
+    if (!this.dhType)
+      this._determineType();
+    if (event.button == 0) {
+      if (this.dhType == 'horizontal') {
+        this.origX = this.offsetLeft;
+        this.origLeft = this.leftBlock.offsetWidth;
+        delta = 0;
+        this.origRight = this.rightBlock.offsetLeft - 5;
+        document.body.style.cursor = "e-resize";
+      } else if (this.dhType == 'vertical') {
+        this.origY = this.offsetTop;
+        this.origUpper = this.upperBlock.offsetHeight;
+        delta = event.clientY - this.offsetTop - 5;
+        this.origLower = this.lowerBlock.offsetTop - 5;
+        document.body.style.cursor = "n-resize";
+      }
+      document._currentDragHandle = this;
+      document.addEventListener("mouseup", this.documentStopHandleDragging, true);
+      document.addEventListener("mousemove", this.documentMove, true);
+      this.move(event);
+      event.cancelBubble = true;
+    }
+
+    return false;
+  },
+  documentStopHandleDragging: function (event) {
+    var handle = document._currentDragHandle;
+    return handle.stopHandleDragging(event);
+  },
+  documentMove: function (event) {
+    var handle = document._currentDragHandle;
+    return handle.move(event);
+  },
+  stopHandleDragging: function (event) {
+    if (!this.dhType)
+      this._determineType();
+    if (this.dhType == 'horizontal') {
+      var deltaX
+        = Math.floor(event.clientX - this.origX - (this.offsetWidth / 2));
+      this.rightBlock.style.left = (this.origRight + deltaX) + 'px;';
+      this.leftBlock.style.width = (this.origLeft + deltaX) + 'px;';
+    } else if (this.dhType == 'vertical') {
+      var deltaY
+        = Math.floor(event.clientY - this.origY - (this.offsetHeight / 2));
+      this.lowerBlock.style.top = (this.origLower + deltaY - delta) + 'px;';
+      this.upperBlock.style.height = (this.origUpper + deltaY - delta) + 'px;';
+    }
+    document.removeEventListener("mouseup", this.documentStopHandleDragging, true);
+    document.removeEventListener("mousemove", this.documentMove, true);
+    document.body.setAttribute('style', '');
+
+    this.move(event);
+    document._currentDragHandle = null;
+    event.cancelBubble = true;
+
+    return false;
+  },
+  move: function (event) {
+    if (!this.dhType)
+      this._determineType();
+    if (this.dhType == 'horizontal') {
+      var width = this.offsetWidth;
+      var hX = event.clientX;
+      if (hX > -1) {
+        var newLeft = Math.floor(hX - (width / 2));
+        this.style.left = newLeft + 'px;';
+        event.cancelBubble = true;
+      
+        return false;
+      }
+    } else if (this.dhType == 'vertical') {
+      var height = this.offsetHeight;
+      var hY = event.clientY;
+      if (hY > -1) {
+        var newTop = Math.floor(hY - (height / 2))  - delta;
+        this.style.top = newTop + 'px;';
+        event.cancelBubble = true;
+
+        return false;
+      }
+    }
+  },
+  doubleClick: function (event) {
+    if (!this.dhType)
+      this._determineType();
+    if (this.dhType == 'horizontal') {
+      var lLeft = this.leftBlock.offsetLeft;
+    
+      if (this.offsetLeft > lLeft) {
+        var leftdelta = this.rightBlock.offsetLeft - this.offsetLeft;
+
+        this.style.left = lLeft + 'px;';
+        this.leftBlock.style.width = '0px';
+        this.rightBlock.style.left = (lLeft + leftdelta) + 'px;';
+      }
+    } else if (this.dhType == 'vertical') {
+      var uTop = this.upperBlock.offsetTop;
+
+      if (this.offsetTop > uTop) {
+        var topdelta = this.lowerBlock.offsetTop - this.offsetTop;
+      
+        this.style.top = uTop + 'px;';
+        this.upperBlock.style.width = '0px';
+        this.lowerBlock.style.top = (uTop + topdelta) + 'px;';
+      }
+    }
+  }
+
+};
+
diff --git a/UI/WebServerResources/SchedulerUI.css b/UI/WebServerResources/SchedulerUI.css
new file mode 100644 (file)
index 0000000..908bf71
--- /dev/null
@@ -0,0 +1,1425 @@
+DIV#leftPanel
+{ 
+  position: absolute;
+  top: 5.5em;
+  left: 0px;
+  width: 17em;
+  bottom: 0px;
+  overflow: hidden;
+}
+
+DIV#schedulerTabs
+{
+  position: absolute;
+  top: 0.5em;
+  left: .2em;
+  right: .2em;
+  height: 15em;
+}
+
+DIV#tasksListView
+{
+  position: absolute;
+  top: 18em;
+  bottom: 0px;
+  left: .2em;
+  right: .7em;
+  padding: 0px;
+}
+
+DIV#tasksListView H2
+{ font-size: 12pt;
+  margin: 0px;
+  margin-left: .25em;
+  padding: 0px; }
+
+DIV#tasksListView LABEL
+{ margin: .25em; }
+
+DIV#calendarsList
+{ height: 100%;
+  padding: 0px;
+  margin: 0px; }
+
+UL#tasksList, UL#uixselector-calendarsList-display
+{ cursor: default;
+  margin: .25px;
+  padding: 0px;
+  overflow: auto;
+  border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  background: #fff;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  list-style-type: none;
+  list-style-image: none; }
+
+UL#uixselector-calendarsList-display
+{ height: 10.5em;
+  margin: 0px; }
+
+UL#uixselector-calendarsList-display LI.denied
+{ background: #fefefe;
+  font-style: italic;
+  color: #f33; }
+
+UL#tasksList
+{ position: absolute;
+  width: 100%;
+  top: 3em;
+  left: .25em;
+  right: .25em;
+  bottom: .25em; }
+
+UL#tasksList LI
+{ white-space: nowrap; }
+
+UL#tasksList LI.overdue
+{ color: #f00; }
+
+UL#tasksList LI.duetoday
+{ color: #00f; }
+
+UL#tasksList LI.completed
+{ text-decoration: line-through;
+  color: #000; }
+
+UL#tasksList LI.duelater
+{ color: #999; }
+
+UL#tasksList LI[class~="_selected"].overdue
+{ 
+  color: #fff !important;
+  background-color: #f00 !important;
+}
+
+UL#tasksList LI[class~="_selected"].duetoday
+{ 
+  color: #fff !important;
+  background-color: #00f !important;
+}
+
+UL#tasksList LI[class~="_selected"].duelater
+{ 
+  color: #fff !important;
+  background-color: #999 !important;
+}
+
+DIV#rightPanel
+{
+  position: absolute;
+  top: 5.5em;
+  left: 17em;
+  right: 0px;
+  bottom: 0px;
+  margin: 0px;
+  margin-left: 5px;
+  padding: 0px;
+  overflow: hidden;
+}
+
+DIV#appointmentsListView
+{ 
+  position: absolute;
+  background: #fff;
+  height: 16em;
+  top: 2em;
+  left: 0px;
+  width: 100%;
+  overflow: auto;
+}
+
+DIV#calendarView
+{ 
+  position: absolute;
+  background: #fff;
+  top: 18em;
+  margin-top: 5px;
+  bottom: 0px;
+  width: 100%;
+  overflow: hidden;
+  border-top: 1px solid #aaa;
+  border-left: 1px solid #aaa;
+}
+
+DIV#calendarView A
+{ 
+  text-decoration: none;
+  font: inherit;
+  color: inherit;
+}
+
+#verticalDragHandle
+{
+  cursor: e-resize;
+  top: 7.5em;
+  left: 17em;
+  width: 5px;
+  bottom: 0px;
+}
+
+#rightDragHandle
+{
+  cursor: n-resize;
+  top: 18em;
+  left: 0px;
+  right: 0px;
+  height: 5px;
+}
+
+#filterPanel
+{
+  padding-right: .5em;
+}
+
+#dateSelector
+{
+  margin: 0px auto;
+  background: #fff;
+  border-top: 1px solid #fff; 
+  border-left: 1px solid #fff;
+  border-right: 1px solid #aaa;
+  border-bottom: 1px solid #aaa;
+}
+
+#dateSelector > .header
+{ background: #efefef;
+  width: 100%;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  padding: .2em 0px;
+  margin: 0px;
+  border: 0px; }
+
+#dateSelector > .header A
+{
+  width: 1em;
+  padding: .4em .2em;
+}
+
+#dateSelector > .header #leftArrow
+{
+  float: left;
+}
+
+#dateSelector > .header #rightArrow
+{
+  float: right;
+}
+
+#dateSelector > .header SPAN
+{ cursor: default;
+  font-size: medium;
+  vertical-align: middle;
+  font-weight: bold;
+  border: 1px solid transparent;
+  margin: .5em .2em; }
+
+#dateSelector > .header SPAN:hover
+{ border-left: 1px solid #fff;
+  border-top: 1px solid #fff;
+  border-right: 1px solid #ccc;
+  border-bottom: 1px solid #ccc; }
+
+#dateSelector .dayOfWeek
+{ color: #00f; }
+
+#dateSelector TABLE#dateSelectorTable TD
+{ width: 14%; }
+
+#dateSelector TABLE#dateSelectorTable TD TABLE TD
+{ width: 100% }
+
+#dateSelector TABLE,
+#dateSelector TABLE TABLE
+{ border-collapse: collapse;
+  margin: 0px auto;
+  width: 100%; }
+
+#dateSelector TABLE TABLE TD
+{ 
+  cursor: pointer;
+  margin: 0px;
+  padding: 0px;
+  width: 100%;
+  border: 1px solid #fff;
+}
+
+#dateSelector TABLE TABLE TD:hover
+{ color: #f00;
+  border: 1px solid #deebf7; }
+
+#dateSelector .inactiveDay
+{ color: #dedfde; }
+
+#dateSelector .dayOfToday
+{ background: #deebf7;
+  border: 1px solid #deebf7; }
+
+#dateSelector TD SPAN
+{ width: 1.5em;
+  height: 1.5em;
+  text-align: center;
+  display: block; }
+
+#dateSelector TD SPAN A
+{ color: inherit;
+  background: inherit;
+  text-decoration: none; }
+
+#dateSelector TD:active
+{ background: #ddd;
+  border: 1px solid #deebf7; }
+
+TABLE#appointmentsList
+{ width: 100%; }
+
+#dateSelector TD._selected,
+UL > LI._selected,
+TABLE#appointmentsList TR._selected TD
+{ 
+  background: #4b6983 !important;
+  color: #fff !important;
+}
+
+._unfocused#dateSelector TD._selected,
+UL._unfocused > LI._selected,
+TABLE._unfocused#appointmentsList TR._selected TD
+{ 
+  background: #dbdad5 !important;;
+  color: #fff !important;;
+}
+
+TABLE.monthOverview
+{ position: absolute;
+  display: table;
+  margin: 0 auto;
+  padding: 1em;
+  border-collapse: collapse;
+  display: table;
+  margin: 0px auto;
+  padding: 0px;
+  width: 98%;
+  height: 98%;
+  min-width: 60em;
+  min-height: 25em; }
+
+TABLE.monthOverview TD
+{ border: 2px solid #397d94;
+  padding: 0px;
+  margin: 0px; }
+
+TABLE.monthOverview TD.day
+{ vertical-align: top;
+  margin: 0px;
+  padding: 0px;
+  height: 15%;
+  min-height: 15%;
+  max-height: 15%; }
+
+TABLE.monthOverview TD.day > DIV.dayContent
+{ display: block;
+  width: 100%;
+  height: 100%;
+  overflow: auto; }
+
+TABLE.monthOverview TD.header
+{ text-align: center;
+  color: #397d94;
+  width: 14%;
+  height: 2em;
+  font-weight: bold;
+  background: #e7efef; }
+
+TABLE.monthOverview TD.dayOfToday
+{ border: 3px solid #397d94;
+  background-color: #deebf7; }
+
+TABLE.monthOverview TD.weekEndDay
+{ background-color: #fffbe7; }
+
+TABLE.monthOverview TD.dayOfAnotherMonth
+{ background-color: #e7efef; }
+
+TABLE.monthOverview TD.selectedDay
+{ background-color: #ffe79c; }
+
+SPAN.dayCellLabel
+{ color: #77a;
+  font-weight: bold; }
+
+SPAN.daysHeader,
+SPAN.weeksHeader,
+SPAN.monthsHeader
+{ display: block;
+  white-space: nowrap;
+  background: #dbdad5;
+  overflow: hidden;
+  width: 100%;
+  margin: 0px;
+  height: 2.75em;
+  padding: .1em 1.5em;
+  border: 0px;
+  border-bottom: 1px solid #ccc; }
+
+SPAN.daysHeader SPAN,
+SPAN.weeksHeader SPAN,
+SPAN.monthsHeader SPAN
+{ display: block;
+  margin: .1em;
+  float: left;
+  width: 18%;
+  padding: 0px;
+  text-align: center;
+  border: 1px solid transparent;
+  vertical-align: top; }
+
+SPAN.daysHeader A,
+SPAN.weeksHeader A,
+SPAN.monthsHeader A
+{ padding: 0px .5em; }
+
+A.leftNavigationArrow,
+A.rightNavigationArrow
+{ border: 1px solid transparent;
+  padding: .5em;
+  text-align: center;
+  vertical-align: bottom; }
+
+A.leftNavigationArrow:hover,
+A.rightNavigationArrow:hover,
+SPAN.daysHeader A:hover,
+SPAN.weeksHeader A:hover,
+SPAN.monthsHeader A:hover
+{ border-left: 1px solid #fff;
+  border-top: 1px solid #fff;
+  border-right: 1px solid #ccc;
+  border-bottom: 1px solid #ccc; }
+
+A.leftNavigationArrow:active,
+A.rightNavigationArrow:active,
+SPAN.daysHeader A:active,
+SPAN.weeksHeader A:active,
+SPAN.monthsHeader A:active
+{ border-left: 1px solid #ccc;
+  border-top: 1px solid #ccc;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff; }
+
+SPAN.week2, SPAN.month2
+{
+  font-size: small;
+}
+
+SPAN.day2, SPAN.week1, SPAN.month1
+{
+  font-size: medium;
+}
+
+SPAN.day1, SPAN.week0, SPAN.month0
+{
+  font-size: large;
+}
+
+SPAN.day0
+{
+  font-size: x-large;
+}
+
+SPAN.day0, SPAN.week0, SPAN.month0
+{ border-top: 1px solid #aaa !important;
+  border-left: 1px solid #aaa !important;
+  border-bottom: 1px solid #fff !important;
+  border-right: 1px solid #fff !important;
+  background: #ccc;
+  color: #222; }
+
+A.leftNavigationArrow
+{
+  position: absolute;
+  display: block;
+  top: .5em;
+  left: .5em;
+}
+
+A.rightNavigationArrow
+{
+  position: absolute;
+  display: block;
+  top: .5em;
+  right: .5em;
+}
+
+DIV#calendarContent
+{
+  position: absolute;
+  top: 3em;
+  padding: 0px;
+  margin: 0px;
+  bottom: 0px;
+  left: 0px;
+  right: 0px;
+  overflow: auto;
+/*   background-position: top center;
+  background-repeat: no-repeat;
+  background-image: url("/SOGo.woa/WebServerResources/background.jpg");
+ */}
+
+.menu LI.currentMonth,
+.menu LI.currentYear
+{
+  border-top: 1px solid #aaa;
+  border-left: 1px solid #aaa;
+  border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  background: #ccc;
+  color: #222;
+}
+
+DIV.appointmentView
+{ display: block;
+  overflow: hidden;
+  white-space: nowrap;
+  border: 1px solid #000; }
+
+SPAN.colorBox
+{ display: block;
+  float: right;
+  border: 1px solid #333;
+  margin: .12em;
+  width: 1em;
+  height: .75em; }
+
+DIV.freeBusyView
+{ margin-left: 12em;
+  overflow: auto;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  border-right: 1px solid #fff;
+  border-bottom: 1px solid #fff;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow; }
+
+TABLE.freeBusy TD,
+TABLE.freeBusy TH
+{ padding: 0px;
+  margin: 0px;
+  border: 0px; }
+
+TABLE.freeBusy TH.attendees,
+TABLE.freeBusy TD.attendees
+{ position: absolute;
+  padding: 0px .5em;
+  margin: 0px;
+  width: 11em;
+  border: 0px !important;
+  background: #dbdad5 !important;
+  overflow: hidden;
+  left: 0px; }
+
+TABLE.freeBusy TD.attendees IMG
+{ position: absolute;
+  left: 0em;
+  top: .5em; }
+
+TABLE.freeBusy TD.attendees INPUT
+{ width: 10em;
+  margin: 0px;
+  margin-left: 10px; }
+
+TABLE.freeBusy TR.freeBusyHeader2 TH
+{ font-weight: normal; }
+
+TABLE.freeBusy TR.freeBusyHeader1 TH,
+TABLE.freeBusy TR.freeBusyHeader2 TH,
+TABLE.freeBusy TR.freeBusyHeader3 TH
+{ text-align: left;
+  color: #777;
+  background: #fff;
+  border-collapse: collapse; }
+
+TABLE.freeBusy TR.freeBusyHeader2 TH
+{ width: 6em; }
+
+TABLE.freeBusy TR.freeBusyHeader3 TH
+{ border-bottom: 1px solid #cecbff; }
+
+TABLE.freeBusy TR.attendeeModel
+{ display: none; }
+
+TABLE.freeBusy TR.futureAttendee TD
+{ border-right: none; }
+
+TABLE.freeBusy TD
+{ border-bottom: 1px solid #cecbff;
+  border-right: 1px solid #cecbff;
+  height: 2em;
+  background-color: #fff; }
+
+TABLE.freeBusy TD.noFreeBusy
+{ background-color: #559;
+  border-right: 0px; }
+
+SPAN.freeBusyZoneElement
+{ display: block;
+  float: left;
+  width: 25%;
+  margin: 0px;
+  padding: 0px;
+  border: 0px; }
+
+TABLE.freeBusy TR.freeBusyHeader3 SPAN.freeBusyZoneElement
+{ height: .25em; }
+
+TABLE.freeBusy TD SPAN.freeBusyZoneElement
+{ height: 100%; }
+
+SPAN[class~="colorBox"].free,
+TABLE.freeBusy TD SPAN.freeBusyZoneElement
+{ background-color: #8ca6bd; }
+
+TABLE.freeBusy TH SPAN[class~="freeBusyZoneElement"].busy
+{ background-color: #c55 !important; }
+
+SPAN[class~="colorBox"].busy,
+SPAN[class~="freeBusyZoneElement"].busy
+{ background-color: #5a6b79 !important; }
+
+SPAN[class~="colorBox"].maybe-busy,
+SPAN[class~="freeBusyZoneElement"].maybe-busy
+{ background-color: #adc0d0 !important; }
+
+SPAN[class~="colorBox"].noFreeBusy
+{ background-color: #559; }
+
+
+/* new draggable presentation */
+
+DIV.daysView
+{ position: relative;
+  margin: 1em;
+  height: 100em;
+  border-bottom: 1px solid #397d94; }
+
+DIV.daysView DIV.days
+{ position: absolute;
+  top: 0px;
+  bottom: 0px;
+  left: 5em;
+  right: 0px; }
+
+DIV.daysView DIV.day
+{ position: absolute;
+  left: 0px;
+  border-left: 1px solid #397d94;
+  top: 0px;
+  bottom: 0px; }
+
+DIV.daysView > DIV.days > DIV.day > DIV.header
+{ height: 3.5em;
+  padding-top: .5em;
+  border: 0px;
+  border-top: 1px solid #397d94;
+  font-weight: bold;
+  text-align: center;
+  background: #e7efef;
+  color: #397d94; }
+
+DIV.daysView > DIV.days > DIV.dayOfToday
+{ background-color: #deebf7; }
+
+DIV.daysView > DIV.days > DIV.weekEndDay
+{ background-color: #fffbe7; }
+
+DIV.daysView > DIV.days > DIV.selectedDay
+{ background-color: #ffe79c; }
+
+DIV.daysViewFor1Days DIV.day
+{ width: 100%;
+  border-right: 1px solid #397d94;
+  left: 0px; }
+
+DIV.daysViewFor7Days DIV.day
+{ width: 14.2857%; }
+
+DIV.daysViewFor7Days DIV.day1
+{ left: 0px; }
+
+DIV.daysViewFor7Days DIV.day2
+{ left: 14.2857%; }
+
+DIV.daysViewFor7Days DIV.day3
+{ left: 28.5714%; }
+
+DIV.daysViewFor7Days DIV.day4
+{ left: 42.8571%; }
+
+DIV.daysViewFor7Days DIV.day5
+{ left: 57.1428%; }
+
+DIV.daysViewFor7Days DIV.day6
+{ left: 71.4285%; }
+
+DIV.daysViewFor7Days DIV.day0
+{ left: 85.7142%;
+  border-right: 1px solid #397d94; }
+
+TABLE.monthOverview DIV.appointment
+{ margin: 0px;
+  margin-top: 1px;
+  padding: 1px;
+  border: 0px;
+  height: auto;
+  width: auto;
+  position: static;
+  overflow: hidden;
+  background-color: #fff; }
+
+TABLE.monthOverview DIV.appointmentInside
+{ cursor: default;
+  margin: 0px;
+  padding: 1px;
+  border: 0px;
+  height: auto;
+  width: auto;
+  position: static; }
+
+
+DIV.daysView > DIV.hours
+{ position: absolute;
+  border: 0px;
+  left: 0px;
+  top: 4em;
+  width: 4.5em;
+  height: 95.5em;
+  font-weight: bold;
+  color: #77a;
+  margin: 0px;
+  padding-top: .5em;
+  padding-right: .5em;
+  border-left: 1px solid #397d94;
+  background: #e7efef;
+  text-align: right; }
+
+DIV.daysView > DIV.hours > DIV.hour
+{ height: 4em; }
+
+DIV.daysView > DIV.hourLines > DIV.hourLine
+{ position: absolute;
+  z-index: 1;
+  height: 1px;
+  left: 0px;
+  right: 0px;
+  border-top: 1px solid #397d94; }
+
+DIV.clickableHourCell
+{ width: 100%;
+  height: 4em; }
+
+DIV.clickableHourCell0
+{ top: 0px; }
+
+DIV.clickableHourCell1,
+DIV.daysView > DIV.hourLines > DIV.hourLine0
+{ top: 4em; }
+
+DIV.clickableHourCell2,
+DIV.daysView > DIV.hourLines > DIV.hourLine1
+{ top: 8em; }
+
+DIV.clickableHourCell3,
+DIV.daysView > DIV.hourLines > DIV.hourLine2
+{ top: 12em; }
+
+DIV.clickableHourCell3,
+DIV.daysView > DIV.hourLines > DIV.hourLine3
+{ top: 16em; }
+
+DIV.clickableHourCell5,
+DIV.daysView > DIV.hourLines > DIV.hourLine4
+{ top: 20em; }
+
+DIV.clickableHourCell4,
+DIV.daysView > DIV.hourLines > DIV.hourLine5
+{ top: 24em; }
+
+DIV.clickableHourCell5,
+DIV.daysView > DIV.hourLines > DIV.hourLine6
+{ top: 28em; }
+
+DIV.clickableHourCell6,
+DIV.daysView > DIV.hourLines > DIV.hourLine7
+{ top: 32em; }
+
+DIV.clickableHourCell7,
+DIV.daysView > DIV.hourLines > DIV.hourLine8
+{ top: 36em; }
+
+DIV.clickableHourCell8,
+DIV.daysView > DIV.hourLines > DIV.hourLine9
+{ top: 40em; }
+
+DIV.clickableHourCell9,
+DIV.daysView > DIV.hourLines > DIV.hourLine10
+{ top: 44em; }
+
+DIV.clickableHourCell10,
+DIV.daysView > DIV.hourLines > DIV.hourLine11
+{ top: 48em; }
+
+DIV.clickableHourCell11,
+DIV.daysView > DIV.hourLines > DIV.hourLine12
+{ top: 52em; }
+
+DIV.clickableHourCell12,
+DIV.daysView > DIV.hourLines > DIV.hourLine13
+{ top: 56em; }
+
+DIV.clickableHourCell13,
+DIV.daysView > DIV.hourLines > DIV.hourLine14
+{ top: 60em; }
+
+DIV.clickableHourCell14,
+DIV.daysView > DIV.hourLines > DIV.hourLine15
+{ top: 64em; }
+
+DIV.clickableHourCell15,
+DIV.daysView > DIV.hourLines > DIV.hourLine16
+{ top: 68em; }
+
+DIV.clickableHourCell16,
+DIV.daysView > DIV.hourLines > DIV.hourLine17
+{ top: 72em; }
+
+DIV.clickableHourCell17,
+DIV.daysView > DIV.hourLines > DIV.hourLine18
+{ top: 76em; }
+
+DIV.clickableHourCell18,
+DIV.daysView > DIV.hourLines > DIV.hourLine19
+{ top: 80em; }
+
+DIV.clickableHourCell19,
+DIV.daysView > DIV.hourLines > DIV.hourLine20
+{ top: 84em; }
+
+DIV.clickableHourCell20,
+DIV.daysView > DIV.hourLines > DIV.hourLine21
+{ top: 88em; }
+
+DIV.clickableHourCell21,
+DIV.daysView > DIV.hourLines > DIV.hourLine22
+{ top: 92em; }
+
+DIV.clickableHourCell22,
+DIV.daysView > DIV.hourLines > DIV.hourLine23
+{ top: 96em; }
+
+DIV.daysView DIV.appointments
+{ position: absolute;
+  z-index: 2;
+  border-top: 1px solid #397d94;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  top: 4em; }
+
+DIV.appointments > DIV.appointment
+{ cursor: default;
+  position: absolute;
+  left: 0px;
+  right: 0px;
+  padding: 0px; }
+
+DIV.appointment > DIV
+{ position: absolute;
+  overflow: hidden;
+  top: 2px;
+  bottom: 2px;
+  left: 2px;
+  right: 2px; }
+
+DIV[class~="appointment"].starts0
+{ top: 0.000000%; }
+
+DIV[class~="appointment"].starts1
+{ top: 1.041667%; }
+
+DIV[class~="appointment"].starts2
+{ top: 2.083333%; }
+
+DIV[class~="appointment"].starts3
+{ top: 3.125000%; }
+
+DIV[class~="appointment"].starts4
+{ top: 4.166667%; }
+
+DIV[class~="appointment"].starts5
+{ top: 5.208333%; }
+
+DIV[class~="appointment"].starts6
+{ top: 6.250000%; }
+
+DIV[class~="appointment"].starts7
+{ top: 7.291667%; }
+
+DIV[class~="appointment"].starts8
+{ top: 8.333333%; }
+
+DIV[class~="appointment"].starts9
+{ top: 9.375000%; }
+
+DIV[class~="appointment"].starts10
+{ top: 10.416667%; }
+
+DIV[class~="appointment"].starts11
+{ top: 11.458333%; }
+
+DIV[class~="appointment"].starts12
+{ top: 12.500000%; }
+
+DIV[class~="appointment"].starts13
+{ top: 13.541667%; }
+
+DIV[class~="appointment"].starts14
+{ top: 14.583333%; }
+
+DIV[class~="appointment"].starts15
+{ top: 15.625000%; }
+
+DIV[class~="appointment"].starts16
+{ top: 16.666667%; }
+
+DIV[class~="appointment"].starts17
+{ top: 17.708333%; }
+
+DIV[class~="appointment"].starts18
+{ top: 18.750000%; }
+
+DIV[class~="appointment"].starts19
+{ top: 19.791667%; }
+
+DIV[class~="appointment"].starts20
+{ top: 20.833333%; }
+
+DIV[class~="appointment"].starts21
+{ top: 21.875000%; }
+
+DIV[class~="appointment"].starts22
+{ top: 22.916667%; }
+
+DIV[class~="appointment"].starts23
+{ top: 23.958333%; }
+
+DIV[class~="appointment"].starts24
+{ top: 25.000000%; }
+
+DIV[class~="appointment"].starts25
+{ top: 26.041667%; }
+
+DIV[class~="appointment"].starts26
+{ top: 27.083333%; }
+
+DIV[class~="appointment"].starts27
+{ top: 28.125000%; }
+
+DIV[class~="appointment"].starts28
+{ top: 29.166667%; }
+
+DIV[class~="appointment"].starts29
+{ top: 30.208333%; }
+
+DIV[class~="appointment"].starts30
+{ top: 31.250000%; }
+
+DIV[class~="appointment"].starts31
+{ top: 32.291667%; }
+
+DIV[class~="appointment"].starts32
+{ top: 33.333333%; }
+
+DIV[class~="appointment"].starts33
+{ top: 34.375000%; }
+
+DIV[class~="appointment"].starts34
+{ top: 35.416667%; }
+
+DIV[class~="appointment"].starts35
+{ top: 36.458333%; }
+
+DIV[class~="appointment"].starts36
+{ top: 37.500000%; }
+
+DIV[class~="appointment"].starts37
+{ top: 38.541667%; }
+
+DIV[class~="appointment"].starts38
+{ top: 39.583333%; }
+
+DIV[class~="appointment"].starts39
+{ top: 40.625000%; }
+
+DIV[class~="appointment"].starts40
+{ top: 41.666667%; }
+
+DIV[class~="appointment"].starts41
+{ top: 42.708333%; }
+
+DIV[class~="appointment"].starts42
+{ top: 43.750000%; }
+
+DIV[class~="appointment"].starts43
+{ top: 44.791667%; }
+
+DIV[class~="appointment"].starts44
+{ top: 45.833333%; }
+
+DIV[class~="appointment"].starts45
+{ top: 46.875000%; }
+
+DIV[class~="appointment"].starts46
+{ top: 47.916667%; }
+
+DIV[class~="appointment"].starts47
+{ top: 48.958333%; }
+
+DIV[class~="appointment"].starts48
+{ top: 50.000000%; }
+
+DIV[class~="appointment"].starts49
+{ top: 51.041667%; }
+
+DIV[class~="appointment"].starts50
+{ top: 52.083333%; }
+
+DIV[class~="appointment"].starts51
+{ top: 53.125000%; }
+
+DIV[class~="appointment"].starts52
+{ top: 54.166667%; }
+
+DIV[class~="appointment"].starts53
+{ top: 55.208333%; }
+
+DIV[class~="appointment"].starts54
+{ top: 56.250000%; }
+
+DIV[class~="appointment"].starts55
+{ top: 57.291667%; }
+
+DIV[class~="appointment"].starts56
+{ top: 58.333333%; }
+
+DIV[class~="appointment"].starts57
+{ top: 59.375000%; }
+
+DIV[class~="appointment"].starts58
+{ top: 60.416667%; }
+
+DIV[class~="appointment"].starts59
+{ top: 61.458333%; }
+
+DIV[class~="appointment"].starts60
+{ top: 62.500000%; }
+
+DIV[class~="appointment"].starts61
+{ top: 63.541667%; }
+
+DIV[class~="appointment"].starts62
+{ top: 64.583333%; }
+
+DIV[class~="appointment"].starts63
+{ top: 65.625000%; }
+
+DIV[class~="appointment"].starts64
+{ top: 66.666667%; }
+
+DIV[class~="appointment"].starts65
+{ top: 67.708333%; }
+
+DIV[class~="appointment"].starts66
+{ top: 68.750000%; }
+
+DIV[class~="appointment"].starts67
+{ top: 69.791667%; }
+
+DIV[class~="appointment"].starts68
+{ top: 70.833333%; }
+
+DIV[class~="appointment"].starts69
+{ top: 71.875000%; }
+
+DIV[class~="appointment"].starts70
+{ top: 72.916667%; }
+
+DIV[class~="appointment"].starts71
+{ top: 73.958333%; }
+
+DIV[class~="appointment"].starts72
+{ top: 75.000000%; }
+
+DIV[class~="appointment"].starts73
+{ top: 76.041667%; }
+
+DIV[class~="appointment"].starts74
+{ top: 77.083333%; }
+
+DIV[class~="appointment"].starts75
+{ top: 78.125000%; }
+
+DIV[class~="appointment"].starts76
+{ top: 79.166667%; }
+
+DIV[class~="appointment"].starts77
+{ top: 80.208333%; }
+
+DIV[class~="appointment"].starts78
+{ top: 81.250000%; }
+
+DIV[class~="appointment"].starts79
+{ top: 82.291667%; }
+
+DIV[class~="appointment"].starts80
+{ top: 83.333333%; }
+
+DIV[class~="appointment"].starts81
+{ top: 84.375000%; }
+
+DIV[class~="appointment"].starts82
+{ top: 85.416667%; }
+
+DIV[class~="appointment"].starts83
+{ top: 86.458333%; }
+
+DIV[class~="appointment"].starts84
+{ top: 87.500000%; }
+
+DIV[class~="appointment"].starts85
+{ top: 88.541667%; }
+
+DIV[class~="appointment"].starts86
+{ top: 89.583333%; }
+
+DIV[class~="appointment"].starts87
+{ top: 90.625000%; }
+
+DIV[class~="appointment"].starts88
+{ top: 91.666667%; }
+
+DIV[class~="appointment"].starts89
+{ top: 92.708333%; }
+
+DIV[class~="appointment"].starts90
+{ top: 93.750000%; }
+
+DIV[class~="appointment"].starts91
+{ top: 94.791667%; }
+
+DIV[class~="appointment"].starts92
+{ top: 95.833333%; }
+
+DIV[class~="appointment"].starts93
+{ top: 96.875000%; }
+
+DIV[class~="appointment"].starts94
+{ top: 97.916667%; }
+
+DIV[class~="appointment"].starts95
+{ top: 98.958333%; }
+
+DIV[class~="appointment"].starts96
+{ top: 100.000000%; }
+
+DIV[class~="appointment"].lasts0
+{ height: 0px; }
+
+DIV[class~="appointment"].lasts1
+{ height: 1.041667%; }
+
+DIV[class~="appointment"].lasts2
+{ height: 2.083333%; }
+
+DIV[class~="appointment"].lasts3
+{ height: 3.125000%; }
+
+DIV[class~="appointment"].lasts4
+{ height: 4.166667%; }
+
+DIV[class~="appointment"].lasts5
+{ height: 5.208333%; }
+
+DIV[class~="appointment"].lasts6
+{ height: 6.250000%; }
+
+DIV[class~="appointment"].lasts7
+{ height: 7.291667%; }
+
+DIV[class~="appointment"].lasts8
+{ height: 8.333333%; }
+
+DIV[class~="appointment"].lasts9
+{ height: 9.375000%; }
+
+DIV[class~="appointment"].lasts10
+{ height: 10.416667%; }
+
+DIV[class~="appointment"].lasts11
+{ height: 11.458333%; }
+
+DIV[class~="appointment"].lasts12
+{ height: 12.500000%; }
+
+DIV[class~="appointment"].lasts13
+{ height: 13.541667%; }
+
+DIV[class~="appointment"].lasts14
+{ height: 14.583333%; }
+
+DIV[class~="appointment"].lasts15
+{ height: 15.625000%; }
+
+DIV[class~="appointment"].lasts16
+{ height: 16.666667%; }
+
+DIV[class~="appointment"].lasts17
+{ height: 17.708333%; }
+
+DIV[class~="appointment"].lasts18
+{ height: 18.750000%; }
+
+DIV[class~="appointment"].lasts19
+{ height: 19.791667%; }
+
+DIV[class~="appointment"].lasts20
+{ height: 20.833333%; }
+
+DIV[class~="appointment"].lasts21
+{ height: 21.875000%; }
+
+DIV[class~="appointment"].lasts22
+{ height: 22.916667%; }
+
+DIV[class~="appointment"].lasts23
+{ height: 23.958333%; }
+
+DIV[class~="appointment"].lasts24
+{ height: 25.000000%; }
+
+DIV[class~="appointment"].lasts25
+{ height: 26.041667%; }
+
+DIV[class~="appointment"].lasts26
+{ height: 27.083333%; }
+
+DIV[class~="appointment"].lasts27
+{ height: 28.125000%; }
+
+DIV[class~="appointment"].lasts28
+{ height: 29.166667%; }
+
+DIV[class~="appointment"].lasts29
+{ height: 30.208333%; }
+
+DIV[class~="appointment"].lasts30
+{ height: 31.250000%; }
+
+DIV[class~="appointment"].lasts31
+{ height: 32.291667%; }
+
+DIV[class~="appointment"].lasts32
+{ height: 33.333333%; }
+
+DIV[class~="appointment"].lasts33
+{ height: 34.375000%; }
+
+DIV[class~="appointment"].lasts34
+{ height: 35.416667%; }
+
+DIV[class~="appointment"].lasts35
+{ height: 36.458333%; }
+
+DIV[class~="appointment"].lasts36
+{ height: 37.500000%; }
+
+DIV[class~="appointment"].lasts37
+{ height: 38.541667%; }
+
+DIV[class~="appointment"].lasts38
+{ height: 39.583333%; }
+
+DIV[class~="appointment"].lasts39
+{ height: 40.625000%; }
+
+DIV[class~="appointment"].lasts40
+{ height: 41.666667%; }
+
+DIV[class~="appointment"].lasts41
+{ height: 42.708333%; }
+
+DIV[class~="appointment"].lasts42
+{ height: 43.750000%; }
+
+DIV[class~="appointment"].lasts43
+{ height: 44.791667%; }
+
+DIV[class~="appointment"].lasts44
+{ height: 45.833333%; }
+
+DIV[class~="appointment"].lasts45
+{ height: 46.875000%; }
+
+DIV[class~="appointment"].lasts46
+{ height: 47.916667%; }
+
+DIV[class~="appointment"].lasts47
+{ height: 48.958333%; }
+
+DIV[class~="appointment"].lasts48
+{ height: 50.000000%; }
+
+DIV[class~="appointment"].lasts49
+{ height: 51.041667%; }
+
+DIV[class~="appointment"].lasts50
+{ height: 52.083333%; }
+
+DIV[class~="appointment"].lasts51
+{ height: 53.125000%; }
+
+DIV[class~="appointment"].lasts52
+{ height: 54.166667%; }
+
+DIV[class~="appointment"].lasts53
+{ height: 55.208333%; }
+
+DIV[class~="appointment"].lasts54
+{ height: 56.250000%; }
+
+DIV[class~="appointment"].lasts55
+{ height: 57.291667%; }
+
+DIV[class~="appointment"].lasts56
+{ height: 58.333333%; }
+
+DIV[class~="appointment"].lasts57
+{ height: 59.375000%; }
+
+DIV[class~="appointment"].lasts58
+{ height: 60.416667%; }
+
+DIV[class~="appointment"].lasts59
+{ height: 61.458333%; }
+
+DIV[class~="appointment"].lasts60
+{ height: 62.500000%; }
+
+DIV[class~="appointment"].lasts61
+{ height: 63.541667%; }
+
+DIV[class~="appointment"].lasts62
+{ height: 64.583333%; }
+
+DIV[class~="appointment"].lasts63
+{ height: 65.625000%; }
+
+DIV[class~="appointment"].lasts64
+{ height: 66.666667%; }
+
+DIV[class~="appointment"].lasts65
+{ height: 67.708333%; }
+
+DIV[class~="appointment"].lasts66
+{ height: 68.750000%; }
+
+DIV[class~="appointment"].lasts67
+{ height: 69.791667%; }
+
+DIV[class~="appointment"].lasts68
+{ height: 70.833333%; }
+
+DIV[class~="appointment"].lasts69
+{ height: 71.875000%; }
+
+DIV[class~="appointment"].lasts70
+{ height: 72.916667%; }
+
+DIV[class~="appointment"].lasts71
+{ height: 73.958333%; }
+
+DIV[class~="appointment"].lasts72
+{ height: 75.000000%; }
+
+DIV[class~="appointment"].lasts73
+{ height: 76.041667%; }
+
+DIV[class~="appointment"].lasts74
+{ height: 77.083333%; }
+
+DIV[class~="appointment"].lasts75
+{ height: 78.125000%; }
+
+DIV[class~="appointment"].lasts76
+{ height: 79.166667%; }
+
+DIV[class~="appointment"].lasts77
+{ height: 80.208333%; }
+
+DIV[class~="appointment"].lasts78
+{ height: 81.250000%; }
+
+DIV[class~="appointment"].lasts79
+{ height: 82.291667%; }
+
+DIV[class~="appointment"].lasts80
+{ height: 83.333333%; }
+
+DIV[class~="appointment"].lasts81
+{ height: 84.375000%; }
+
+DIV[class~="appointment"].lasts82
+{ height: 85.416667%; }
+
+DIV[class~="appointment"].lasts83
+{ height: 86.458333%; }
+
+DIV[class~="appointment"].lasts84
+{ height: 87.500000%; }
+
+DIV[class~="appointment"].lasts85
+{ height: 88.541667%; }
+
+DIV[class~="appointment"].lasts86
+{ height: 89.583333%; }
+
+DIV[class~="appointment"].lasts87
+{ height: 90.625000%; }
+
+DIV[class~="appointment"].lasts88
+{ height: 91.666667%; }
+
+DIV[class~="appointment"].lasts89
+{ height: 92.708333%; }
+
+DIV[class~="appointment"].lasts90
+{ height: 93.750000%; }
+
+DIV[class~="appointment"].lasts91
+{ height: 94.791667%; }
+
+DIV[class~="appointment"].lasts92
+{ height: 95.833333%; }
+
+DIV[class~="appointment"].lasts93
+{ height: 96.875000%; }
+
+DIV[class~="appointment"].lasts94
+{ height: 97.916667%; }
+
+DIV[class~="appointment"].lasts95
+{ height: 98.958333%; }
+
+DIV[class~="appointment"].lasts96
+{ height: 100.000000%; }
diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js
new file mode 100644 (file)
index 0000000..7b0da89
--- /dev/null
@@ -0,0 +1,1105 @@
+var sortOrder = '';
+var sortKey = '';
+var listFilter = 'view_today';
+
+var listOfSelection = null;
+
+var hideCompletedTasks = 0;
+
+var currentDay = '';
+var currentView = "dayview";
+
+var cachedDateSelectors = new Array();
+
+var contactSelectorAction = 'calendars-contacts';
+
+var eventsToDelete = new Array();
+var ownersOfEventsToDelete = new Array();
+
+function newEvent(sender, type) {
+  var day = sender.getAttribute("day");
+  if (!day)
+    day = currentDay;
+
+  var hour = sender.getAttribute("hour");
+  var urlstr = ApplicationBaseURL + "new" + type;
+  var params = new Array();
+  if (day)
+    params.push("day=" + day);
+  if (hour)
+    params.push("hm=" + hour);
+  if (params.length > 0)
+    urlstr += "?" + params.join("&");
+
+  window.open(urlstr, "", "width=620,height=600,resizable=0");
+
+  return false; /* stop following the link */
+}
+
+function _editEventId(id, owner) {
+  var urlBase;
+  if (owner)
+    urlBase = UserFolderURL + "../" + owner + "/";
+  urlBase += "Calendar/"
+
+  var urlstr = urlBase + id + "/edit";
+
+  var win = window.open(urlstr, "SOGo_edit_" + id,
+                        "width=620,height=600,resizable=0,scrollbars=0,toolbar=0," +
+                        "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+  win.focus();
+}
+
+function editEvent() {
+  if (listOfSelection) {
+    var nodes = listOfSelection.getSelectedRows();
+
+    for (var i = 0; i < nodes.length; i++)
+      _editEventId(nodes[i].getAttribute("id"),
+                   nodes[i].getAttribute("owner"));
+  }
+
+  return false; /* stop following the link */
+}
+
+function _batchDeleteEvents() {
+  var events = eventsToDelete.shift();
+  var owner = ownersOfEventsToDelete.shift();
+  var urlstr = (UserFolderURL + "../" + owner + "/Calendar/batchDelete?ids="
+                + events.join('/'));
+  document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
+                                                       deleteEventCallback,
+                                                       events);
+}
+
+function deleteEvent()
+{
+  if (listOfSelection) {
+    var nodes = listOfSelection.getSelectedRows();
+
+    if (nodes.length > 0) {
+      var label = "";
+      if (listOfSelection == $("tasksList"))
+        label = labels["taskDeleteConfirmation"].decodeEntities();
+      else
+        label = labels["appointmentDeleteConfirmation"].decodeEntities();
+      
+      if (confirm(label)) {
+        if (document.deleteEventAjaxRequest) {
+          document.deleteEventAjaxRequest.aborted = true;
+          document.deleteEventAjaxRequest.abort();
+        }
+        var sortedNodes = new Array();
+        var owners = new Array();
+
+        for (var i = 0; i < nodes.length; i++) {
+          var owner = nodes[i].getAttribute("owner");
+          if (!sortedNodes[owner]) {
+              sortedNodes[owner] = new Array();
+              owners.push(owner);
+          }
+          sortedNodes[owner].push(nodes[i].getAttribute("id"));
+        }
+        for (var i = 0; i < owners.length; i++) {
+          ownersOfEventsToDelete.push(owners[i]);
+          eventsToDelete.push(sortedNodes[owners[i]]);
+        }
+        _batchDeleteEvents();
+      }
+    }
+  }
+  else
+    window.alert("no selection");
+
+  return false;
+}
+
+function modifyEvent(sender, modification) {
+  var currentLocation = '' + window.location;
+  var arr = currentLocation.split("/");
+  arr[arr.length-1] = modification;
+
+  document.modifyEventAjaxRequest = triggerAjaxRequest(arr.join("/"),
+                                                       modifyEventCallback,
+                                                       modification);
+
+  return false;
+}
+
+function modifyEventCallback(http) {
+  if (http.readyState == 4) {
+    if (http.status == 200) {
+      log("closing window...?");
+      window.close();
+    }
+    else {
+      log("showing alert...");
+      window.alert(labels["eventPartStatModificationError"]);
+    }
+    document.modifyEventAjaxRequest = null;
+  }
+}
+
+function deleteEventCallback(http)
+{
+  if (http.readyState == 4
+      && http.status == 200) {
+    var nodes = $(http.callbackData);
+    for (var i = 0; i < nodes.length; i++) {
+      var node = $(nodes[i]);
+      node.parentNode.removeChild(node);
+    }
+    if (eventsToDelete.length)
+      _batchDeleteEvents();
+    else {
+      document.deleteEventAjaxRequest = null;
+      refreshAppointments();
+      refreshTasks();
+      changeCalendarDisplay();
+    }
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function editDoubleClickedEvent(node)
+{
+  _editEventId(node.getAttribute("id"),
+               node.getAttribute("owner"));
+  
+  return false;
+}
+
+function onSelectAll() {
+  var list = $("appointmentsList");
+  list.selectRowsMatchingClass("appointmentRow");
+
+  return false;
+}
+
+function displayAppointment(event) {
+  _editEventId(this.getAttribute("aptCName"),
+               this.getAttribute("owner"));
+
+  event.preventDefault();
+  event.stopPropagation();
+  event.cancelBubble = true;
+  event.returnValue = false;
+}
+
+function onDaySelect(node)
+{
+  var day = node.getAttribute("day");
+  var needRefresh = (listFilter == 'view_selectedday'
+                     && day != currentDay);
+
+  var td = node.getParentWithTagName("td");
+  var table = td.getParentWithTagName("table");
+
+//   log ("table.selected: " + table.selected);
+
+  if (document.selectedDate)
+    document.selectedDate.deselect();
+
+  td.select();
+  document.selectedDate = td;
+
+  changeCalendarDisplay( { "day": day } );
+  if (needRefresh)
+    refreshAppointments();
+
+  return false;
+}
+
+function onDateSelectorGotoMonth(node)
+{
+  var day = node.getAttribute("date");
+
+  changeDateSelectorDisplay(day, true);
+
+  return false;
+}
+
+function onCalendarGotoDay(node)
+{
+  var day = node.getAttribute("date");
+
+  changeDateSelectorDisplay(day);
+  changeCalendarDisplay( { "day": day } );
+
+  return false;
+}
+
+function gotoToday()
+{
+  changeDateSelectorDisplay('');
+  changeCalendarDisplay();
+
+  return false;
+}
+
+function setDateSelectorContent(content)
+{
+  var div = $("dateSelectorView");
+
+  div.innerHTML = content;
+  if (currentDay.length > 0)
+    restoreCurrentDaySelection(div);
+}
+
+function dateSelectorCallback(http)
+{
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.dateSelectorAjaxRequest = null;
+    var content = http.responseText;
+    setDateSelectorContent(content);
+    cachedDateSelectors[http.callbackData] = content;
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function appointmentsListCallback(http)
+{
+  var div = $("appointmentsListView");
+
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.appointmentsListAjaxRequest = null;
+    div.innerHTML = http.responseText;
+    var params = parseQueryParameters(http.callbackData);
+    sortKey = params["sort"];
+    sortOrder = params["desc"];
+    var list = $("appointmentsList");
+    list.addEventListener("selectionchange",
+                          onAppointmentsSelectionChange, true);
+    configureSortableTableHeaders();
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function tasksListCallback(http)
+{
+  var div = $("tasksListView");
+
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.tasksListAjaxRequest = null;
+    var list = $("tasksList");
+    var scroll = list.scrollTop;
+    div.innerHTML = http.responseText;
+    list = $("tasksList");
+    list.addEventListener("selectionchange",
+                          onTasksSelectionChange, true);
+    list.scrollTop = scroll;
+    if (http.callbackData) {
+      var selectedNodesId = http.callbackData;
+      for (var i = 0; i < selectedNodesId.length; i++)
+        $(selectedNodesId[i]).select();
+    }
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function restoreCurrentDaySelection(div)
+{
+  var elements = div.getElementsByTagName("a");
+  var day = null;
+  var i = 9;
+  while (!day && i < elements.length)
+    {
+      day = elements[i].getAttribute("day");
+      i++;
+    }
+
+  if (day
+      && day.substr(0, 6) == currentDay.substr(0, 6)) {
+      for (i = 0; i < elements.length; i++) {
+        day = elements[i].getAttribute("day");
+        if (day && day == currentDay) {
+          var td = elements[i].getParentWithTagName("td");
+          if (document.selectedDate)
+            document.selectedDate.deselect();
+          td.select();
+          document.selectedDate = td;
+        }
+      }
+    }
+}
+
+function changeDateSelectorDisplay(day, keepCurrentDay)
+{
+  var url = ApplicationBaseURL + "dateselector";
+  if (day)
+    url += "?day=" + day;
+
+  if (day != currentDay) {
+    if (!keepCurrentDay)
+      currentDay = day;
+
+    var month = day.substr(0, 6);
+    if (cachedDateSelectors[month]) {
+//       log ("restoring cached selector for month: " + month);
+      setDateSelectorContent(cachedDateSelectors[month]);
+    }
+    else {
+//       log ("loading selector for month: " + month);
+      if (document.dateSelectorAjaxRequest) {
+        document.dateSelectorAjaxRequest.aborted = true;
+        document.dateSelectorAjaxRequest.abort();
+      }
+      document.dateSelectorAjaxRequest
+        = triggerAjaxRequest(url,
+                             dateSelectorCallback,
+                             month);
+    }
+  }
+}
+
+function changeCalendarDisplay(time, newView)
+{
+  var url = ApplicationBaseURL + ((newView) ? newView : currentView);
+
+  var day = null;
+  var hour = null;
+  if (time) {
+    day = time['day'];
+    hour = time['hour'];
+  }
+
+  if (!day)
+    day = currentDay;
+  if (day)
+    url += "?day=" + day;
+
+//   if (newView)
+//     log ("switching to view: " + newView);
+//   log ("changeCalendarDisplay: " + url);
+
+  if (document.dayDisplayAjaxRequest) {
+//     log ("aborting day ajaxrq");
+    document.dayDisplayAjaxRequest.aborted = true;
+    document.dayDisplayAjaxRequest.abort();
+  }
+  document.dayDisplayAjaxRequest = triggerAjaxRequest(url,
+                                                      calendarDisplayCallback,
+                                                      { "view": newView,
+                                                        "day": day,
+                                                        "hour": hour });
+
+  return false;
+}
+
+function _ensureView(view) {
+  if (currentView != view)
+    changeCalendarDisplay(null, view);
+
+  return false;
+}
+
+function onDayOverview()
+{
+  return _ensureView("dayview");
+}
+
+function onWeekOverview()
+{
+  return _ensureView("weekview");
+}
+
+function onMonthOverview()
+{
+  return _ensureView("monthview");
+}
+
+function scrollDayView(hour)
+{
+  log("stest1");
+  var rowNumber;
+  if (hour) {
+    if (hour.length == 3)
+      rowNumber = parseInt(hour.substr(0, 1));
+    else {
+      if (hour.substr(0, 1) == "0")
+        rowNumber = parseInt(hour.substr(1, 1));
+      else
+        rowNumber = parseInt(hour.substr(0, 2));
+    }
+  } else
+    rowNumber = 8;
+
+  var daysView = $("daysView");
+  var hours = daysView.childNodesWithTag("div")[0].childNodesWithTag("div");
+  if (hours.length > 0)
+    daysView.parentNode.scrollTop = hours[rowNumber + 1].offsetTop;
+
+  log("stest2");
+}
+
+function onClickableCellsDblClick(event) {
+  newEvent(this, 'event');
+
+  event.cancelBubble = true;
+  event.returnValue = false;
+}
+
+function calendarDisplayCallback(http)
+{
+  var div = $("calendarView");
+
+//   log ("calendardisplaycallback: " + div);
+  if (http.readyState == 4
+      && http.status == 200) {
+    document.dateSelectorAjaxRequest = null;
+    div.innerHTML = http.responseText;
+    if (http.callbackData["view"])
+      currentView = http.callbackData["view"];
+    if (http.callbackData["day"])
+      currentDay = http.callbackData["day"];
+    var hour = null;
+    if (http.callbackData["hour"])
+      hour = http.callbackData["hour"];
+    var contentView;
+    if (currentView == "monthview")
+      contentView = $("calendarContent");
+    else {
+      scrollDayView(hour);
+//       log("cbtest1");
+      contentView = $("daysView");
+    }
+    var appointments = document.getElementsByClassName("appointment", contentView);
+    for (var i = 0; i < appointments.length; i++) {
+      appointments[i].addEventListener("mousedown", listRowMouseDownHandler, true);
+      appointments[i].addEventListener("click", onCalendarSelectAppointment, false);
+      appointments[i].addEventListener("dblclick", displayAppointment, true);
+    }
+    var days = document.getElementsByClassName("day", contentView);
+    if (currentView == "monthview")
+      for (var i = 0; i < days.length; i++) {
+        days[i].addEventListener("click", onCalendarSelectDay, true);
+        days[i].addEventListener("dblclick", onClickableCellsDblClick, false);
+      }
+    else
+      for (var i = 0; i < days.length; i++) {
+        days[i].addEventListener("click", onCalendarSelectDay, false);
+        var clickableCells = document.getElementsByClassName("clickableHourCell",
+                                                             days[i]);
+        for (var j = 0; j < clickableCells.length; j++)
+          clickableCells[j].addEventListener("dblclick",
+                                             onClickableCellsDblClick, false);
+      }
+//     log("cbtest1");
+  }
+  else
+    log ("ajax fuckage");
+}
+
+function assignCalendar(name)
+{
+  var node = $(name);
+
+  node.calendar = new skycalendar(node);
+  node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
+  var dateFormat = node.getAttribute("dateFormat");
+  if (dateFormat)
+    node.calendar.setDateFormat(dateFormat);
+}
+
+function popupCalendar(node)
+{
+  var nodeId = node.getAttribute("inputId");
+  var input = $(nodeId);
+  input.calendar.popup();
+
+  return false;
+}
+
+function onAppointmentContextMenu(event, element)
+{
+  var topNode = $("appointmentsList");
+//   log(topNode);
+
+  var menu = $("appointmentsListMenu");
+
+  menu.addEventListener("hideMenu", onAppointmentContextMenuHide, false);
+  onMenuClick(event, "appointmentsListMenu");
+
+  var topNode = $("appointmentsList");
+  var selectedNodes = topNode.getSelectedRows();
+  topNode.menuSelectedRows = selectedNodes;
+  for (var i = 0; i < selectedNodes.length; i++)
+    selectedNodes[i].deselect();
+
+  topNode.menuSelectedEntry = element;
+  element.select();
+}
+
+function onAppointmentContextMenuHide(event)
+{
+  var topNode = $("appointmentsList");
+
+  if (topNode.menuSelectedEntry) {
+    topNode.menuSelectedEntry.deselect();
+    topNode.menuSelectedEntry = null;
+  }
+  if (topNode.menuSelectedRows) {
+    var nodeIds = topNode.menuSelectedRows;
+    for (var i = 0; i < nodeIds.length; i++) {
+      var node = $(nodeIds[i]);
+      node.select();
+    }
+    topNode.menuSelectedRows = null;
+  }
+}
+
+function onAppointmentsSelectionChange() {
+  listOfSelection = this;
+  this.removeClassName("_unfocused");
+  $("tasksList").addClassName("_unfocused");
+}
+
+function onTasksSelectionChange() {
+  listOfSelection = this;
+  this.removeClassName("_unfocused");
+  $("appointmentsList").addClassName("_unfocused");
+}
+
+function _loadAppointmentHref(href) {
+  if (document.appointmentsListAjaxRequest) {
+    document.appointmentsListAjaxRequest.aborted = true;
+    document.appointmentsListAjaxRequest.abort();
+  }
+  var url = ApplicationBaseURL + href;
+  document.appointmentsListAjaxRequest
+    = triggerAjaxRequest(url, appointmentsListCallback, href);
+
+  return false;
+}
+
+function _loadTasksHref(href) {
+  if (document.tasksListAjaxRequest) {
+    document.tasksListAjaxRequest.aborted = true;
+    document.tasksListAjaxRequest.abort();
+  }
+  url = ApplicationBaseURL + href;
+
+  var selectedIds = $("tasksList").getSelectedNodesId();
+  document.tasksListAjaxRequest
+    = triggerAjaxRequest(url, tasksListCallback, selectedIds);
+
+  return false;
+}
+
+function onHeaderClick(event) {
+//   log("onHeaderClick: " + this.link);
+  _loadAppointmentHref(this.link);
+
+  event.preventDefault();
+}
+
+function refreshAppointments() {
+  return _loadAppointmentHref("aptlist?desc=" + sortOrder
+                              + "&sort=" + sortKey
+                              + "&day=" + currentDay
+                              + "&filterpopup=" + listFilter);
+}
+
+function refreshTasks() {
+  return _loadTasksHref("taskslist?hide-completed=" + hideCompletedTasks);
+}
+
+function refreshAppointmentsAndDisplay()
+{
+  refreshAppointments();
+  changeCalendarDisplay();
+}
+
+function onListFilterChange() {
+  var node = $("filterpopup");
+
+  listFilter = node.value;
+//   log ("listFilter = " + listFilter);
+
+  return refreshAppointments();
+}
+
+function onAppointmentClick(event)
+{
+  var node = event.target.getParentWithTagName("tr");
+  var day = node.getAttribute("day");
+  var hour = node.getAttribute("hour");
+
+  changeCalendarDisplay( { "day": day, "hour": hour} );
+  changeDateSelectorDisplay(day);
+
+  return onRowClick(event);
+}
+
+function selectMonthInMenu(menu, month)
+{
+  var entries = menu.childNodes[1].childNodesWithTag("LI");
+  for (i = 0; i < entries.length; i++) {
+    var entry = entries[i];
+    var entryMonth = entry.getAttribute("month");
+    if (entryMonth == month)
+      entry.addClassName("currentMonth");
+    else
+      entry.removeClassName("currentMonth");
+  }
+}
+
+function selectYearInMenu(menu, month)
+{
+  var entries = menu.childNodes[1].childNodes;
+  for (i = 0; i < entries.length; i++) {
+    var entry = entries[i];
+    if (entry instanceof HTMLLIElement) {
+      var entryMonth = entry.innerHTML;
+      if (entryMonth == month)
+        entry.addClassName("currentMonth");
+      else
+        entry.removeClassName("currentMonth");
+    }
+  }
+}
+
+function popupMonthMenu(event, menuId)
+{
+  var node = event.target;
+
+  if (event.button == 0) {
+    event.cancelBubble = true;
+    event.returnValue = false;
+
+    if (document.currentPopupMenu)
+      hideMenu(event, document.currentPopupMenu);
+
+    var popup = $(menuId);
+    var id = node.getAttribute("id");
+    if (id == "monthLabel")
+      selectMonthInMenu(popup, node.getAttribute("month"));
+    else
+      selectYearInMenu(popup, node.innerHTML);
+
+    var diff = (popup.offsetWidth - node.offsetWidth) /2;
+
+    popup.style.top = (node.offsetTop + 95) + "px";
+    popup.style.left = (node.offsetLeft - diff) + "px";
+    popup.style.visibility = "visible";
+
+    bodyOnClick = "" + document.body.getAttribute("onclick");
+    document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');");
+    document.currentPopupMenu = popup;
+  }
+}
+
+function onMonthMenuItemClick(node)
+{
+  var month = '' + node.getAttribute("month");
+  var year = '' + $("yearLabel").innerHTML;
+  
+  changeDateSelectorDisplay(year+month+"01", true);
+
+  return false;
+}
+
+function onYearMenuItemClick(node) {
+  var month = '' + $("monthLabel").getAttribute("month");;
+  var year = '' + node.innerHTML;
+
+  changeDateSelectorDisplay(year+month+"01", true);
+
+  return false;
+}
+
+function onSearchFormSubmit() {
+  log ("search not implemented");
+
+  return false;
+}
+
+function onCalendarSelectAppointment() {
+  var list = $("appointmentsList");
+  list.deselectAll();
+
+  var aptCName = this.getAttribute("aptCName");
+  var row = $(aptCName);
+  if (row) {
+    var div = row.parentNode.parentNode.parentNode;
+    div.scrollTop = row.offsetTop - (div.offsetHeight / 2);
+    row.select();
+  }
+}
+
+function onCalendarSelectDay(event) {
+  var day = this.getAttribute("day");
+  var needRefresh = (listFilter == 'view_selectedday'
+                     && day != currentDay);
+
+  if (currentView == 'weekview')
+    changeWeekCalendarDisplayOfSelectedDay(this);
+  else if (currentView == 'monthview')
+    changeMonthCalendarDisplayOfSelectedDay(this);
+  changeDateSelectorDisplay(day);
+
+  if (needRefresh)
+    refreshAppointments();
+}
+
+function changeWeekCalendarDisplayOfSelectedDay(node) {
+  var days = document.getElementsByClassName("day", node.parentNode);
+
+  for (var i = 0; i < days.length; i++)
+    if (days[i] != node)
+      days[i].removeClassName("selectedDay");
+
+  node.addClassName("selectedDay");
+}
+
+function findMonthCalendarSelectedCell(table) {
+  var tbody = table.tBodies[0];
+  var rows = tbody.rows;
+
+  var i = 1;
+  while (i < rows.length && !table.selectedCell) {
+    var cells = rows[i].cells;
+    var j = 0;
+    while (j < cells.length && !table.selectedCell) {
+      if (cells[j].hasClassName("selectedDay"))
+        table.selectedCell = cells[j];
+      else
+        j++;
+    }
+    i++;
+  }
+}
+
+function changeMonthCalendarDisplayOfSelectedDay(node)
+{
+  var tr = node.parentNode;
+  var table = tr.parentNode.parentNode;
+
+  if (!table.selectedCell)
+    findMonthCalendarSelectedCell(table);
+
+  if (table.selectedCell)
+    table.selectedCell.removeClassName("selectedDay");
+  table.selectedCell = node;
+  node.addClassName("selectedDay");
+}
+
+function onHideCompletedTasks(node)
+{
+  hideCompletedTasks = (node.checked ? 1 : 0);
+
+  return refreshTasks();
+}
+
+function updateTaskStatus(node)
+{
+  var taskId = node.parentNode.getAttribute("id");
+  var taskOwner = node.parentNode.getAttribute("owner");
+  var newStatus = (node.checked ? 1 : 0);
+//   log ("update task status: " + taskId);
+
+  var http = createHTTPClient();
+
+  url = (UserFolderURL + "../" + taskOwner + "/Calendar/"
+         + taskId + "/changeStatus?status=" + newStatus);
+
+  if (http) {
+//     log ("url: " + url);
+    // TODO: add parameter to signal that we are only interested in OK
+    http.url = url;
+    http.open("GET", url, false /* not async */);
+    http.send("");
+    if (http.status == 200)
+      refreshTasks();
+  } else
+    log ("no http client?");
+
+  return false;
+}
+
+function updateCalendarStatus()
+{
+  var list = new Array();
+
+  var clist = $("calendarsList");
+  var nodes = clist.childNodesWithTag("ul")[0].childNodesWithTag("li");
+  for (var i = 0; i < nodes.length; i++) {
+    var input = nodes[i].childNodesWithTag("input")[0];
+    if (input.checked)
+      list.push(nodes[i].getAttribute("uid"));
+  }
+
+  if (!list.length) {
+    list.push(nodes[0].getAttribute("uid"));
+    nodes[0].childNodesWithTag("input")[0].checked = true;
+  }
+//   ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
+//                      + list.join(",") + "/Calendar/");
+
+  updateCalendarsList();
+  refreshAppointments();
+  refreshTasks();
+  changeCalendarDisplay();
+
+  return false;
+}
+
+function calendarUidsList()
+{
+  var list = "";
+
+  var nodes = $("uixselector-calendarsList-display").childNodesWithTag("li");
+  for (var i = 0; i < nodes.length; i++) {
+    var currentNode = nodes[i];
+    var input = currentNode.childNodesWithTag("input")[0];
+    if (!input.checked)
+      list += "-";
+    list += currentNode.getAttribute("uid") + ",";
+  }
+
+  return list.substr(0, list.length - 1);
+}
+
+// function updateCalendarContacts(contacts)
+// {
+//   var list = contacts.split(",");
+
+//   var clist = $("calendarsList");
+//   var nodes = clist.childNodes[5].childNodes;
+//   for (var i = 0; i < nodes.length; i++) {
+//     var currentNode = nodes[i];
+//     if (currentNode instanceof HTMLLIElement) {
+//       var input = currentNode.childNodes[3];
+//       if (!input.checked)
+//         list += "-";
+//       list += currentNode.getAttribute("uid") + ",";
+//     }
+//   }
+// }
+
+function inhibitMyCalendarEntry()
+{
+  var clist = $("calendarsList");
+  var nodes = clist.childNodes[5].childNodes;
+  var done = false;
+
+  var i = 0;
+  while (!done && i < nodes.length) {
+    var currentNode = nodes[i];
+    if (currentNode instanceof HTMLLIElement) {
+      var input = currentNode.childNodes[3];
+      if (currentNode.getAttribute("uid") == UserLogin) {
+        done = true;
+//         currentNode.style.color = "#999;";
+        currentNode.style.fontWeight = "bold;";
+//         currentNode.setAttribute("onclick", "");
+      }
+    }
+    i++;
+  }
+}
+
+function userCalendarEntry(user, color) {
+  var li = document.createElement("li");
+  li.setAttribute("uid", user);
+  li.addEventListener("mousedown", listRowMouseDownHandler, false);
+  li.addEventListener("click", onRowClick, false);
+  var colorBox = document.createElement("span");
+  colorBox.addClassName("colorBox");
+  if (color) {
+    log("color:  " + color);
+    colorBox.style.backgroundColor = color + ";";
+  }
+  li.appendChild(colorBox);
+  var checkBox = document.createElement("input");
+  checkBox.addClassName("checkBox");
+  checkBox.type = "checkbox";
+  checkBox.addEventListener("change", updateCalendarStatus, false);
+  li.appendChild(checkBox);
+  var text = document.createTextNode(" " + user);
+  li.appendChild(text);
+
+  return li;
+}
+
+function ensureSelfIfPresent() {
+  var ul = $("uixselector-calendarsList-display");
+  var list = ul.childNodesWithTag("li");
+  var selfEntry = userCalendarEntry(UserLogin, indexColor(0));
+  selfEntry.style.fontWeight = "bold;";
+  if (list.length < 1) {
+    ul.appendChild(selfEntry);
+  } else if (list[0].getAttribute("uid") != UserLogin) {
+    ul.insertBefore(selfEntry, list[0]);
+  }
+}
+
+function updateCalendarsList(method)
+{
+  ensureSelfIfPresent();
+  var url = (ApplicationBaseURL + "updateCalendars?ids="
+             + calendarUidsList());
+  if (document.calendarsListAjaxRequest) {
+    document.calendarsListAjaxRequest.aborted = true;
+    document.calendarsListAjaxRequest.abort();
+  }
+  var http = createHTTPClient();
+  if (http) {
+    http.url = url;
+    http.open("GET", url, false);
+    http.send("");
+
+    if (method == "removal")
+      updateCalendarStatus();
+
+    http = createHTTPClient();
+    http.url = ApplicationBaseURL + "checkRights";
+    http.open("GET", http.url, false /* not async */);
+    http.send("");
+    if (http.status == 200
+        && http.responseText.length > 0) {
+      rights = http.responseText.split(",");
+      var list = $("uixselector-calendarsList-display").childNodesWithTag("li");
+      for (var i = 0; i < list.length; i++) {
+        var input = list[i].childNodesWithTag("input")[0];
+        if (rights[i] == "1") {
+          list[i].removeClassName("denied");
+          input.disabled = false;
+        }
+        else {
+          input.checked = false;
+          input.disabled = true;
+          list[i].addClassName("denied");
+        }
+      }
+    }
+  }
+}
+
+function addContact(tag, fullContactName, contactId, contactName, contactEmail)
+{
+  var uids = $("uixselector-calendarsList-uidList");
+//   log("addContact");
+  if (contactId)
+    {
+      var re = new RegExp("(^|,)" + contactId + "($|,)");
+
+      if (!re.test(uids.value))
+        {
+          if (uids.value.length > 0)
+            uids.value += ',' + contactId;
+          else
+            uids.value = contactId;
+          var names = $("uixselector-calendarsList-display");
+          var listElems = names.childNodesWithTag("li");
+          var colorDef = indexColor(listElems.length);
+          names.appendChild(userCalendarEntry(contactId, colorDef));
+
+          var styles = document.getElementsByTagName("style");
+          styles[0].innerHTML += ('.ownerIs' + contactId + ' {'
+                                  + ' background-color: '
+                                  + colorDef
+                                  + ' !important; }');
+        }
+    }
+
+  return false;
+}
+
+function onChangeCalendar(list) {
+   var form = document.forms.editform;
+   var urlElems = form.getAttribute("action").split("/");
+   urlElems[urlElems.length-4]
+      = list.childNodesWithTag("option")[list.value].innerHTML;
+   form.setAttribute("action", urlElems.join("/"));
+}
+
+function validateBrowseURL(input) {
+  var button = $("browseURLBtn");
+
+  if (input.value.length) {
+    if (!button.enabled)
+      enableAnchor(button);
+  } else if (!button.disabled)
+    disableAnchor(button);
+}
+
+function browseURL(anchor, event) {
+  if (event.button == 0) {
+    var input = $("url");
+    var url = input.value;
+    if (url.length)
+      window.open(url, '_blank');
+  }
+
+  return false;
+}
+
+function initializeMenus() {
+  var menus = new Array("monthListMenu", "yearListMenu",
+                        "appointmentsListMenu", "calendarsMenu", "searchMenu");
+  initMenusNamed(menus);
+
+  $("calendarsList").attachMenu("calendarsMenu");
+
+  var accessRightsMenuEntry = $("accessRightsMenuEntry");
+  accessRightsMenuEntry.addEventListener("mouseup",
+                                         onAccessRightsMenuEntryMouseUp,
+                                         false);
+}
+
+function onAccessRightsMenuEntryMouseUp(event) {
+  var folders = $("uixselector-calendarsList-display");
+  var selected = folders.getSelectedNodes()[0];
+  var uid = selected.getAttribute("uid");
+  log("application base url: " + ApplicationBaseURL);
+  if (uid == UserLogin)
+    url = ApplicationBaseURL + "acls";
+  else
+    url = UserFolderURL + "../" + uid + "/Calendar/acls";
+
+  openAclWindow(url, uid);
+}
+
+function configureDragHandles() {
+  var handle = $("verticalDragHandle");
+  if (handle) {
+    handle.addInterface(SOGoDragHandlesInterface);
+    handle.leftBlock=$("leftPanel");
+    handle.rightBlock=$("rightPanel");
+  }
+
+  handle = $("rightDragHandle");
+  if (handle) {
+    handle.addInterface(SOGoDragHandlesInterface);
+    handle.upperBlock=$("appointmentsListView");
+    handle.lowerBlock=$("calendarView");
+  }
+}
+
+function initCalendarContactsSelector() {
+  var selector = $("calendarsList");
+  inhibitMyCalendarEntry();
+  updateCalendarStatus();
+  selector.changeNotification = updateCalendarsList;
+
+  var list = $("uixselector-calendarsList-display").childNodesWithTag("li");
+  for (var i = 0; i < list.length; i++) {
+    var input = list[i].childNodesWithTag("input")[0];
+    input.addEventListener("change", updateCalendarStatus, false);
+  }
+}
+
+function initCalendars() {
+  if (!document.body.hasClassName("popup"))
+    initCalendarContactsSelector();
+}
+
+window.addEventListener("load", initCalendars, false);
diff --git a/UI/WebServerResources/Search-bar.png b/UI/WebServerResources/Search-bar.png
new file mode 100644 (file)
index 0000000..4bae71c
Binary files /dev/null and b/UI/WebServerResources/Search-bar.png differ
diff --git a/UI/WebServerResources/UIxAclEditor.css b/UI/WebServerResources/UIxAclEditor.css
new file mode 100644 (file)
index 0000000..bbce7a5
--- /dev/null
@@ -0,0 +1,47 @@
+/* test */
+
+DIV.acls
+{ padding: 1em; }
+
+DIV.acls LABEL
+{ position: relative;
+  white-space: normal;
+  width: 100%; }
+
+DIV.acls LABEL > SPAN.value
+{ position: absolute;
+  top: 0px;
+  left: 11em; }
+
+DIV.acls UL
+{ height: 100%;
+  width: 100%; }
+
+DIV#userRoles
+{ height: 7em;
+  padding-bottom: 2em; }
+
+UL#uixselector-userRoles-display
+{ cursor: default;
+  margin: .25px;
+  padding: 0px;
+  overflow: auto;
+  border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  background: #fff;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  list-style-type: none;
+  list-style-image: none; }
+
+UL#uixselector-userRoles-display > LI._selected
+{ 
+  background: #4b6983 !important;
+  color: #fff !important;
+}
+
+SPAN.legend
+{ margin-left: 1em;
+  font-size: smaller; }
diff --git a/UI/WebServerResources/UIxAclEditor.js b/UI/WebServerResources/UIxAclEditor.js
new file mode 100644 (file)
index 0000000..0c7c2a0
--- /dev/null
@@ -0,0 +1,75 @@
+/* test */
+
+var contactSelectorAction = 'acls-contacts';
+
+function addContact(tag, fullContactName, contactId, contactName,
+                    contactEmail) {
+   if (tag == "assistant")
+      addUser(contactName, contactId, false);
+   else if (tag == "delegate")
+      addUser(contactName, contactId, true);
+}
+
+function addUser(userName, userId, checked) {
+   var uidList = $("uixselector-userRoles-uidList");
+   var uids;
+
+   if (uidList.value.length > 0) {
+      uids = uidList.value.split(",");
+   } else {
+      uids = new Array();
+   }
+
+   if (uids.indexOf(userId) < 0) {
+      uids.push(userId);
+      var ul = $("uixselector-userRoles-display");
+      ul.appendChild(nodeForUser(userName, userId, checked));
+      uidList.value = uids.join(",");
+   }
+
+   log("addUser: " + uidList.value);
+}
+
+function nodeForUser(userName, userId, checked) {
+   var node = document.createElement("li");
+   node.setAttribute("uid", userId);
+   node.setAttribute("class", "");
+   node.addEventListener("mousedown", listRowMouseDownHandler, true);
+   node.addEventListener("click", onRowClick, true);
+
+   var checkbox = document.createElement("input");
+   checkbox.setAttribute("type", "checkbox");
+   checkbox.setAttribute("class", "checkBox");
+   checkbox.checked = checked;
+   checkbox.addEventListener("change", updateAclStatus, true);
+
+   node.appendChild(checkbox);
+   node.appendChild(document.createTextNode(userName));
+
+   return node;
+}
+
+function updateAclStatus() {
+}
+
+function saveAcls() {
+   var form = $("aclForm");
+   var lis = $("uixselector-userRoles-display").childNodesWithTag("li");
+
+   var assistants = new Array();
+   var delegates = new Array();
+   for (var i = 0; i < lis.length; i++) {
+      var uName = lis[i].getAttribute("uid");
+      var cb = lis[i].childNodesWithTag("input")[0];
+      if (cb.checked)
+         delegates.push(uName);
+      else
+         assistants.push(uName);
+   }
+   $("assistants").value = assistants.join(",");
+   $("delegates").value = delegates.join(",");
+
+   form.submit();
+
+   return false;
+}
diff --git a/UI/WebServerResources/UIxAppointmentEditor.css b/UI/WebServerResources/UIxAppointmentEditor.css
new file mode 100644 (file)
index 0000000..ffb011c
--- /dev/null
@@ -0,0 +1,173 @@
+DIV.appointmentLabel
+{ display: block;
+  position: relative;
+  line-height: 1.8em;
+  text-align: right;
+  width: 3em; }
+
+DIV#editorTabs
+{
+  left: 0px;
+  right: 0px;
+  height: 38em;
+}
+
+DIV#editorTabs > DIV.tab
+{ overflow: hidden;
+  padding: .5em; }
+
+DIV.appointmentRightLabel
+{ display: inline;
+  vertical-align: middle; }
+
+UL.contactList
+{ 
+  display: block;
+  cursor: default;
+  list-style-type: none;
+  list-style-image: none;
+  margin: 0px;
+  padding: 0px;
+  background: #fff;
+  border: 1px solid #000;
+  width: 15em;
+  height: 5em;
+  overflow: auto;
+}
+
+UL.contactList LI IMG
+{ vertical-align: middle; }
+
+UL.contactList LI
+{ width: 100%;
+  white-space: nowrap;
+  vertical-align: middle; }
+
+UL.contactList LI._selected
+{ background: #4b6983;
+  color: #fff; }
+
+DIV.contactSelector
+{ margin: 0px; }
+
+LABEL, SPAN.checkBoxList
+{ display: block;
+  position: relative;
+  height: 1.5em;
+  margin-left: .5em;
+  margin-bottom: .5em;
+  width: 100%; }
+
+LABEL#commentArea
+{ height: 11.5em; }
+
+SPAN.checkBoxList#participantsCB
+{ height: 7em; }
+
+SPAN.checkBoxList#categoriesCB
+{ height: 3em; }
+
+DIV#participants UL.contactList
+{ height: 4.5em; }
+
+SPAN.checkBoxList SPAN.content LABEL
+{ display: inline; }
+
+SPAN.content
+{ position: absolute;
+  top: -.25em;
+  left: 8em;
+  right: 1em; }
+
+TEXTAREA
+{ position: absolute;
+  top: 0px;
+  left: 8em;
+  vertical-align: bottom;
+  height: 10em;
+  right: 1em;
+  padding-bottom: 1em; }
+
+A#detailsButton
+{ position: absolute;
+  right: 1em;
+  z-index: 1; }
+
+SPAN.contactSelectorButtons
+{ vertical-align: top;
+  line-height: 2em; }
+
+SPAN#cycleSelectionFirstLevel,
+SPAN#cycleSelectionSecondLevel
+{ visibility: hidden;
+  margin-left: 1em; }
+
+SPAN#cycleSelectionSecondLevel SPAN.timeDateControl
+{ position: static;
+  margin: 0px; }
+
+SPAN#categoriesCB INPUT
+{ border: 2px solid #000;
+  vertical-align: middle;
+  -moz-border-top-colors: #000 #fff;
+  -moz-border-left-colors: #000 #fff; 
+  -moz-border-bottom-colors: #000 #fff;
+  -moz-border-right-colors: #000 #fff; }
+
+SPAN#categoriesCB LABEL
+{ margin-left: 0px;
+  margin-right: 1em; }
+
+SPAN.content > INPUT
+{ position: absolute;
+  top: 0px;
+  left: 0px;
+  right: 0px; }
+
+LABEL#urlArea INPUT
+{ position: static; }
+
+DIV.freeBusyView
+{ height: 22em;
+  overflow: auto; }
+
+DIV#freeBusyFooter
+{ position: absolute;
+  left: .5em;
+  right: .5em;
+  height: 6em;
+  line-height: 2em;
+  text-align: right;
+  bottom: 0px; }
+
+DIV#freeBusyButtons
+{ float: left;
+  text-align: center; }
+
+DIV#freeBusyButtons A.button
+{ width: 5em; }
+
+DIV#freeBusyReplicas LABEL
+{ line-height: 1.5em; }
+
+DIV.legend UL
+{ cursor: default;
+  float: left;
+  width: 30%;
+  margin: 0px;
+  padding: 0px;
+  line-height: 1.5em;
+  list-style-type: none;
+  list-style-image: none; }
+
+DIV.legend UL LI
+{ white-space: nowrap;
+  margin: 0px;
+  padding: 0px; }
+
+DIV.legend UL IMG
+{ margin-right: .5em; }
+
+DIV.legend UL LI SPAN.colorBox
+{ float: left;
+  margin-right: .5em; }
index 1de34b0cea7e8667f7150d1cd2a78a7892962aa4..69adac6609c2c0277ee6e03fe6f2aee7ed4bf6b8 100644 (file)
  02111-1307, USA.
 */
 
+var contactSelectorAction = 'calendars-contacts';
+
 function uixEarlierDate(date1, date2) {
   // can this be done in a sane way?
+//   cuicui = 'year';
   if (date1.getYear()  < date2.getYear()) return date1;
   if (date1.getYear()  > date2.getYear()) return date2;
   // same year
+//   cuicui += '/month';
   if (date1.getMonth() < date2.getMonth()) return date1;
   if (date1.getMonth() > date2.getMonth()) return date2;
-  // same month
+//   // same month
+//   cuicui += '/date';
   if (date1.getDate() < date2.getDate()) return date1;
   if (date1.getDate() > date2.getDate()) return date2;
   // same day
@@ -35,55 +40,57 @@ function uixEarlierDate(date1, date2) {
 
 function validateAptEditor() {
   var e, startdate, enddate, tmpdate;
-      
-  e = document.getElementById('summary');
+
+  e = $('summary');
   if (e.value.length == 0) {
-    if (!confirm(labels.validate_notitle))
+    if (!confirm(labels.validate_notitle.decodeEntities()))
       return false;
   }
 
-  e = document.getElementById('startTime_date');
+  e = $('startTime_date');
   if (e.value.length != 10) {
-    alert(labels.validate_invalid_startdate);
+    alert(labels.validate_invalid_startdate.decodeEntities());
     return false;
   }
-  startdate = calendar_startTime_date.prs_date(e.value);
+  startdate = e.calendar.prs_date(e.value);
   if (startdate == null) {
-    alert(labels.validate_invalid_startdate);
+    alert(labels.validate_invalid_startdate.decodeEntities());
     return false;
   }
       
-  e = document.getElementById('endTime_date');
+  e = $('endTime_date');
   if (e.value.length != 10) {
-    alert(labels.validate_invalid_enddate);
+    alert(labels.validate_invalid_enddate.decodeEntities());
     return false;
   }
-  enddate = calendar_endTime_date.prs_date(e.value);
+  enddate = e.calendar.prs_date(e.value);
   if (enddate == null) {
-    alert(labels.validate_invalid_enddate);
+    alert(labels.validate_invalid_enddate.decodeEntities());
     return false;
   }
-  
+//   cuicui = '';
   tmpdate = uixEarlierDate(startdate, enddate);
   if (tmpdate == enddate) {
-    alert(labels.validate_endbeforestart);
+//     window.alert(cuicui);
+    alert(labels.validate_endbeforestart.decodeEntities());
     return false;
   }
   else if (tmpdate == null /* means: same date */) {
     // TODO: check time
     var start, end;
     
-    start = document.forms[0]['startTime_time_hour'].value;
-    end   = document.forms[0]['endTime_time_hour'].value;
+    start = parseInt(document.forms[0]['startTime_time_hour'].value);
+    end = parseInt(document.forms[0]['endTime_time_hour'].value);
+
     if (start > end) {
-      alert(labels.validate_endbeforestart);
+      alert(labels.validate_endbeforestart.decodeEntities());
       return false;
     }
     else if (start == end) {
-      start = document.forms[0]['startTime_time_minute'].value;
-      end   = document.forms[0]['endTime_time_minute'].value;
+      start = parseInt(document.forms[0]['startTime_time_minute'].value);
+      end = parseInt(document.forms[0]['endTime_time_minute'].value);
       if (start > end) {
-       alert(labels.validate_endbeforestart);
+       alert(labels.validate_endbeforestart.decodeEntities());
        return false;
       }
     }
@@ -91,3 +98,158 @@ function validateAptEditor() {
 
   return true;
 }
+
+function toggleDetails() {
+  var div = $("details");
+  var buttons = $("buttons");
+  var buttonsHeight = buttons.clientHeight * 3;
+
+  if (div.style.visibility) {
+    div.style.visibility = null;
+    window.resizeBy(0, -(div.clientHeight + buttonsHeight));
+    $("detailsButton").innerHTML = labels["Show Details"];
+  } else {
+    div.style.visibility = 'visible;';
+    window.resizeBy(0, (div.clientHeight + buttonsHeight));
+    $("detailsButton").innerHTML = labels["Hide Details"];
+  }
+
+  return false;
+}
+
+function toggleCycleVisibility(node, nodeName, hiddenValue) {
+  var spanNode = $(nodeName);
+  var newVisibility = ((node.value == hiddenValue) ? null : 'visible;');
+  spanNode.style.visibility = newVisibility;
+
+  if (nodeName == 'cycleSelectionFirstLevel') {
+    var otherSpanNode = $('cycleSelectionSecondLevel');
+    if (!newVisibility)
+      {
+        otherSpanNode.superVisibility = otherSpanNode.style.visibility;
+        otherSpanNode.style.visibility = null;
+      }
+    else
+      {
+        otherSpanNode.style.visibility = otherSpanNode.superVisibility;
+        otherSpanNode.superVisibility = null;
+      }
+  }
+}
+
+function addContact(tag, fullContactName, contactId, contactName, contactEmail)
+{
+  var uids = $('uixselector-participants-uidList');
+  log ("contactId: " + contactId);
+  if (contactId)
+    {
+      var re = new RegExp("(^|,)" + contactId + "($|,)");
+
+      log ("uids: " + uids);
+      if (!re.test(uids.value))
+        {
+          log ("no match... realling adding");
+          if (uids.value.length > 0)
+            uids.value += ',' + contactId;
+          else
+            uids.value = contactId;
+
+          var names = $('uixselector-participants-display');
+          names.innerHTML += ('<li onmousedown="return false;"'
+                              + ' onclick="onRowClick(event);"><img src="'
+                              + ResourcesURL + '/abcard.gif" />'
+                              + contactName + '</li>');
+        }
+      else
+        log ("match... ignoring contact");
+    }
+
+  return false;
+}
+
+function saveEvent(sender) {
+  if (validateAptEditor())
+    document.forms['editform'].submit();
+
+  return false;
+}
+
+function startDayAsShortString() {
+  return $('startTime_date').valueAsShortDateString();
+}
+
+function endDayAsShortString() {
+  return $('endTime_date').valueAsShortDateString();
+}
+
+this._getDate = function(which) {
+  var date = window.timeWidgets[which]['date'].valueAsDate();
+  date.setHours( window.timeWidgets[which]['hour'].value );
+  date.setMinutes( window.timeWidgets[which]['minute'].value );
+
+  return date;
+}
+
+this._getShadowDate = function(which) {
+  var date = window.timeWidgets[which]['date'].getAttribute("shadow-value").asDate();
+  var intValue = parseInt(window.timeWidgets[which]['hour'].getAttribute("shadow-value"));
+  date.setHours(intValue);
+  intValue = parseInt(window.timeWidgets[which]['minute'].getAttribute("shadow-value"));
+  date.setMinutes(intValue);
+//   window.alert("shadow: " + date);
+
+  return date;
+}
+
+this.getStartDate = function() {
+  return this._getDate('start');
+}
+
+this.getEndDate = function() {
+  return this._getDate('end');
+}
+
+this.getShadowStartDate = function() {
+  return this._getShadowDate('start');
+}
+
+this.getShadowEndDate = function() {
+  return this._getShadowDate('end');
+}
+
+this._setDate = function(which, newDate) {
+  window.timeWidgets[which]['date'].setValueAsDate(newDate);
+  window.timeWidgets[which]['hour'].value = newDate.getHours();
+  var minutes = newDate.getMinutes();
+  if (minutes % 15)
+    minutes += (15 - minutes % 15);
+  window.timeWidgets[which]['minute'].value = minutes;
+}
+
+this.setStartDate = function(newStartDate) {
+  this._setDate('start', newStartDate);
+}
+
+this.setEndDate = function(newEndDate) {
+//   window.alert(newEndDate);
+  this._setDate('end', newEndDate);
+}
+
+this.onAdjustEndTime = function(event) {
+  var dateDelta = (window.getStartDate().valueOf()
+                   - window.getShadowStartDate().valueOf());
+//   window.alert(window.getEndDate().valueOf() + '  ' + dateDelta);
+  var newEndDate = new Date(window.getEndDate().valueOf() + dateDelta);
+  window.setEndDate(newEndDate);
+  window.timeWidgets['start']['date'].updateShadowValue();
+  window.timeWidgets['start']['hour'].updateShadowValue();
+  window.timeWidgets['start']['minute'].updateShadowValue();
+}
+
+this.initTimeWidgets = function (widgets) {
+  this.timeWidgets = widgets;
+
+  widgets['start']['date'].addEventListener("change", this.onAdjustEndTime, false);
+  widgets['start']['hour'].addEventListener("change", this.onAdjustEndTime, false);
+  widgets['start']['minute'].addEventListener("change", this.onAdjustEndTime, false);
+}
diff --git a/UI/WebServerResources/UIxContactEditor.css b/UI/WebServerResources/UIxContactEditor.css
new file mode 100644 (file)
index 0000000..944ad84
--- /dev/null
@@ -0,0 +1,59 @@
+DIV#editorTabs
+{
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  bottom: 2.5em;;
+  margin-bottom: 1em;
+}
+
+DIV#editorTabs DIV.tab
+{ padding: .5em;
+  overflow: auto; }
+
+DIV#buttons
+{ visibility: visible;
+  position: absolute;
+  right: 1em;
+  bottom: 1em; }
+
+TR
+{ width: 100% !important;
+  border: 2px solid #0ff; }
+
+DIV#editorTabs DIV.tab TD.titleCell
+{ text-align: left;
+  font-weight: bold; }
+
+/* DIV#contactInfos INPUT.textField,
+DIV#contactInfos TABLE
+{ width: 100%; }
+ */
+
+DIV#contactInfos INPUT.textField
+{ width: 65%; }
+
+TABLE#emailInfos TD
+{ width: 90%; }
+
+TABLE#emailInfos TD.preferred
+{ width: 10% !important;
+  overflow: visible;
+  text-align: center; }
+
+TABLE
+{ display: table;
+  text-align: right;
+  width: 90%; }
+
+DIV.tab TD INPUT.textField
+{ width: 70%; }
+
+DIV.tab TD.firstColumn INPUT.textField,
+DIV.tab TD.secondColumn INPUT.textField
+{ width: 40%; }
+
+#otherInfos TEXTAREA
+{ width: 70%;
+  height: 10em; }
index abf74d9bbdb9593747d2b2694308ef4e45368fd9..32670f0bf666ef52e1112d882f1af88e4fe6afbb 100644 (file)
  02111-1307, USA.
 */
 
+var uixEmailUsr = 
+  "([a-zA-Z0-9][a-zA-Z0-9_.-]*|\"([^\\\\\x80-\xff\015\012\"]|\\\\[^\x80-\xff])+\")";
+var uixEmailDomain = 
+  "([a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*[a-zA-Z0-9][a-zA-Z0-9._-]*\\.[a-zA-Z]{2,5}";
+var uixEmailRegex = new RegExp("^"+uixEmailUsr+"\@"+uixEmailDomain+"$");
+
+var displayNameChanged = false;
 
 function unescapeCallbackParameter(s) {
   if(!s || s.length == 0)
@@ -46,38 +53,83 @@ function copyContact(type, email, uid, sn,
     //  var departmentNumber = arguments[10]; 
     //  var l = arguments[11]; 
   var e;
-  e = document.getElementById('cn');
+  e = $('cn');
   e.setAttribute('value', unescapeCallbackParameter(cn));
-  e = document.getElementById('email');
+  e = $('email');
   e.setAttribute('value', email);
-  e = document.getElementById('sn');
+  e = $('sn');
   e.setAttribute('value', unescapeCallbackParameter(sn));
-  e = document.getElementById('givenName');
+  e = $('givenName');
   e.setAttribute('value', unescapeCallbackParameter(givenName));
-  e = document.getElementById('telephoneNumber');
+  e = $('telephoneNumber');
   e.setAttribute('value', telephoneNumber);
-  e = document.getElementById('facsimileTelephoneNumber');
+  e = $('facsimileTelephoneNumber');
   e.setAttribute('value', facsimileTelephoneNumber);
-  e = document.getElementById('mobile');
+  e = $('mobile');
   e.setAttribute('value', mobile);
-  e = document.getElementById('postalAddress');
+  e = $('postalAddress');
   e.setAttribute('value', unescapeCallbackParameter(postalAddress));
-  e = document.getElementById('homePostalAddress');
+  e = $('homePostalAddress');
   e.setAttribute('value', unescapeCallbackParameter(homePostalAddress));
-  e = document.getElementById('departmentNumber');
+  e = $('departmentNumber');
   e.setAttribute('value', unescapeCallbackParameter(departmentNumber));
-  e = document.getElementById('l');
+  e = $('l');
   e.setAttribute('value', unescapeCallbackParameter(l));
 };
 
 function validateContactEditor() {
   var e;
   
-  e = document.getElementById('email');
+  e = $('workMail');
+  if (e.value.length == 0)
+    return true;
+  if (uixEmailRegex.test(e.value) != true)
+    return confirm(labels.invalidemailwarn.decodeEntities());
+
+  e = $('homeMail');
   if (e.value.length == 0)
     return true;
   if (uixEmailRegex.test(e.value) != true)
-    return confirm(labels.invalidemailwarn);
+    return confirm(labels.invalidemailwarn.decodeEntities());
 
   return true;
 }
+
+function showCoords(node) {
+  node = $("givenName");
+  window.alert("x: " + node.cascadeLeftOffset()
+               + ";y: " + node.cascadeTopOffset()
+               + ";width: " + window.innerWidth
+               + ";height: " + window.innerHeight);
+}
+
+function onFnKeyDown() {
+  var fn = $("fn");
+  fn.onkeydown = null;
+  displayNameChanged = true;
+
+  return true;
+}
+
+function onFnNewValue(event) {
+  if (!displayNameChanged) {
+    var sn = $("sn").value.trim();
+    var givenName = $("givenName").value.trim();
+
+    var fullName = givenName;
+    if (fullName && sn)
+      fullName += ' ';
+    fullName += sn;
+
+    $("fn").value = fullName;
+  }
+
+  return true;
+}
+
+function initEditorForm() {
+  displayNameChanged = ($("fn").value.length > 0);
+  $("fn").onkeydown = onFnKeyDown;
+  $("sn").onkeyup = onFnNewValue;
+  $("givenName").onkeyup = onFnNewValue;
+}
diff --git a/UI/WebServerResources/UIxFreeBusyUserSelector.js b/UI/WebServerResources/UIxFreeBusyUserSelector.js
new file mode 100644 (file)
index 0000000..e8c8d44
--- /dev/null
@@ -0,0 +1,373 @@
+var resultsDiv;
+var searchField;
+var running = false;
+var address;
+var delay = 500;
+var requestField;
+var awaitingFreeBusyRequests = new Array();
+var freeBusySelectorId;
+
+function onContactKeydown(event) {
+  if (event.keyCode == 9) {
+    event.preventDefault();
+    if (this.confirmedValue)
+      this.value = this.confirmedValue;
+    var row = this.parentNode.parentNode.nextSibling;
+    while (!(row instanceof HTMLTableRowElement))
+      row = row.nextSibling;
+    this.blur();
+    var input = row.cells[0].childNodesWithTag("input")[0];
+    if (input.readOnly)
+      newAttendee(null);
+    else {
+      input.focus();
+      input.select();
+      input.focussed = true;
+    }
+  }
+  else if (!running) {
+    if (event.keyCode == 8
+        || event.keyCode == 32
+        || event.keyCode > 47) {
+      running = true;
+      requestField = this;
+      setTimeout("triggerRequest()", delay);
+    }
+    else if (this.confirmedValue) {
+      if (event.keyCode == 13) {
+        this.setSelectionRange(this.value.length, this.value.length);
+      }
+    }
+  }
+}
+
+function triggerRequest() {
+  if (document.contactLookupAjaxRequest) {
+    document.contactLookupAjaxRequest.aborted = yes;
+    document.contactLookupAjaxRequest.abort();
+  }
+  var urlstr = ( UserFolderURL + "Contacts/contactSearch?search="
+                 + requestField.value );
+  document.contactLookupAjaxRequest = triggerAjaxRequest(urlstr,
+                                                         updateResults,
+                                                         requestField);
+}
+
+function updateResults(http) {
+  if (http.readyState == 4) {
+    if (http.status == 200) {
+      var searchField = http.callbackData;
+      var start = searchField.value.length;
+      var text = http.responseText.split(":");
+      if (text[0].length > 0)
+        searchField.uid = text[0];
+      else
+        searchField.uid = null;
+      searchField.hasfreebusy = false;
+      if (text[1].substring(0, searchField.value.length).toUpperCase()
+          == searchField.value.toUpperCase())
+        searchField.value = text[1];
+      else {
+        searchField.value += ' >> ' + text[1];
+      }
+      searchField.confirmedValue = text[1];
+      if (searchField.focussed) {
+        var end = searchField.value.length;
+        searchField.setSelectionRange(start, end);
+      }
+      else
+        searchField.value = text[1];
+    }
+    running = false;
+    document.contactLookupAjaxRequest = null;
+  }
+}
+
+function resetFreeBusyZone()
+{
+  var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+  var row = table.tHead.rows[2];
+  for (var i = 1; i < row.cells.length; i++) {
+    var nodes = row.cells[i].childNodesWithTag("span");
+    for (var j = 0; j < nodes.length; j++)
+      nodes[j].removeClassName("busy");
+  }
+}
+
+function redisplayFreeBusyZone()
+{
+  var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+  var row = table.tHead.rows[2];
+  var stDay = this.timeWidgets['start']['date'].valueAsDate();
+  var etDay = this.timeWidgets['end']['date'].valueAsDate();
+  var days = stDay.daysUpTo(etDay);
+  var addDays = days.length - 1;
+  var stHour = parseInt(this.timeWidgets['start']['hour'].value);
+  var stMinute = parseInt(this.timeWidgets['start']['minute'].value) / 15;
+  var etHour = parseInt(this.timeWidgets['end']['hour'].value);
+  var etMinute = parseInt(this.timeWidgets['end']['minute'].value) / 15;
+  if (stHour < 8) {
+    stHour = 8;
+    stMinute = 0;
+  }
+  if (stHour > 19) {
+    stHour = 19
+    stMinute = 0;
+  }
+  if (etHour < 8) {
+    etHour = 8;
+    etMinute = 0;
+  }
+  if (etHour > 19) {
+    etHour = 19;
+    etMinute = 0;
+  }
+  if (stHour > etHour) {
+    var swap = etHour;
+    etHour = stHour;
+    stHour = swap;
+    swap = etMinute;
+    etMinute = stMinute;
+    stMinute = etMinute;
+  } else {
+    if (stMinute > etMinute) {
+      var swap = etMinute;
+      etMinute = stMinute;
+      stMinute = swap;
+    }
+  }
+
+  var deltaCells = (etHour - stHour) + (11 * addDays);
+  var deltaSpans = (deltaCells * 4 ) + (etMinute - stMinute);
+  var currentCellNbr = stHour - 7;
+  var currentCell = row.cells[currentCellNbr];
+  var currentSpanNbr = stMinute;
+  var spans = currentCell.childNodesWithTag("span");
+  resetFreeBusyZone();
+  while (deltaSpans > 0) {
+    var currentSpan = spans[currentSpanNbr];
+    currentSpan.addClassName("busy");
+    currentSpanNbr++;
+    if (currentSpanNbr > 3) {
+      currentSpanNbr = 0;
+      currentCellNbr++;
+      currentCell = row.cells[currentCellNbr];
+      spans = currentCell.childNodesWithTag("span");
+    }
+    deltaSpans--;
+  }
+}
+
+function newAttendee(event)
+{
+  var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+  var tbody = table.tBodies[0];
+  var model = tbody.rows[tbody.rows.length - 1];
+  var newAttendeeRow = tbody.rows[tbody.rows.length - 2]
+  var newRow = model.cloneNode(true);
+  var input = newRow.cells[0].childNodesWithTag("input")[0];
+  input.setAttribute("autocomplete", "off");
+  newRow.setAttribute("class", "");
+  tbody.insertBefore(newRow, newAttendeeRow);
+  input.serial = "pouet";
+  input.addEventListener("blur", checkAttendee, false);
+  input.addEventListener("keydown", onContactKeydown, false);
+  input.focus();
+  input.focussed = true;
+}
+
+function checkAttendee()
+{
+  this.focussed = false;
+  var th = this.parentNode.parentNode;
+  var tbody = th.parentNode;
+  if (this.value.trim().length == 0)
+    tbody.removeChild(th);
+  else if (!this.hasfreebusy) {
+    if (this.confirmedValue)
+      this.value = this.confirmedValue;
+    displayFreeBusyForNode(this);
+    this.hasfreebusy = true;
+  }
+  resetAttendeesValue();
+}
+
+function displayFreeBusyForNode(node)
+{
+  var nodes = node.parentNode.parentNode.cells;
+  if (node.uid) {
+    for (var i = 1; i < nodes.length; i++) {
+      nodes[i].removeClassName("noFreeBusy");
+      nodes[i].innerHTML = ('<span class="freeBusyZoneElement"></span>'
+                            + '<span class="freeBusyZoneElement"></span>'
+                            + '<span class="freeBusyZoneElement"></span>'
+                            + '<span class="freeBusyZoneElement"></span>');
+    }
+    if (document.contactFreeBusyAjaxRequest) {
+      document.contactFreeBusyAjaxRequest.aborted = true;
+      document.contactFreeBusyAjaxRequest.abort();
+    }
+    var sd = startDayAsShortString();
+    var ed = endDayAsShortString();
+    var urlstr = ( UserFolderURL + "../" + node.uid + "/freebusy.ifb/ajaxRead?"
+                   + "sday=" + sd + "&eday=" + ed + "&additional=2" );
+    document.contactFreeBusyAjaxRequest
+      = triggerAjaxRequest(urlstr,
+                           updateFreeBusyData,
+                           node);
+  } else {
+    for (var i = 1; i < nodes.length; i++) {
+      nodes[i].addClassName("noFreeBusy");
+      nodes[i].innerHTML = '';
+    }
+  }
+}
+
+function setSlot(tds, nbr, status) {
+  var tdnbr = Math.floor(nbr / 4);
+  var spannbr = nbr - (tdnbr * 4);
+  var days = 0;
+  if (tdnbr > 24) {
+    days = Math.floor(tdnbr / 24);
+    tdnbr -= (days * 24);
+  }
+  if (tdnbr > 7 && tdnbr < 19) {
+    var i = (days * 11 + tdnbr - 7);
+    var td = tds[i];
+    var spans = td.childNodesWithTag("span");
+    if (status == '2')
+      spans[spannbr].addClassName("maybe-busy");
+    else
+      spans[spannbr].addClassName("busy");
+  }
+}
+
+function updateFreeBusyData(http)
+{
+  if (http.readyState == 4) {
+    if (http.status == 200) {
+      var node = http.callbackData;
+      var slots = http.responseText.split(",");
+      var tds = node.parentNode.parentNode.cells;
+      for (var i = 0; i < slots.length; i++) {
+        if (slots[i] != '0')
+          setSlot(tds, i, slots[i]);
+      }
+    }
+    document.contactFreeBusyAjaxRequest = null;
+    if (awaitingFreeBusyRequests.length > 0)
+      displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
+  }
+}
+
+function resetAttendeesValue()
+{
+  var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+  var inputs = table.getElementsByTagName("input");
+  var uids = new Array();
+  for (var i = 0; i < inputs.length - 2; i++) {
+    var currentInput = inputs[i];
+    var uid = currentInput.getAttribute("uid");
+    if (uid) {
+      currentInput.uid = uid;
+      currentInput.setAttribute("uid", null);
+    }
+    uids.push(currentInput.uid);
+    currentInput.setAttribute("autocomplete", "off");
+    currentInput.addEventListener("keydown", onContactKeydown, false);
+    currentInput.addEventListener("blur", checkAttendee, false);
+  }
+  var input = $(freeBusySelectorId);
+  input.value = uids.join(",");
+  inputs[inputs.length - 2].setAttribute("autocomplete", "off");
+  inputs[inputs.length - 2].addEventListener("click", newAttendee, false);
+}
+
+function initializeFreeBusyUserSelector()
+{
+  resetAttendeesValue();
+  resetAllFreeBusys();
+  disableAnchor($('FBStartTimeReplica_date').parentNode.childNodesWithTag('a')[0]);
+  disableAnchor($('FBEndTimeReplica_date').parentNode.childNodesWithTag('a')[0]);
+}
+
+function resetAllFreeBusys()
+{
+  var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+  var inputs = table.getElementsByTagName("input");
+
+  for (var i = 0; i < inputs.length - 2; i++) {
+    var currentInput = inputs[i];
+    currentInput.hasfreebusy = false;
+//     log ("input: " + currentInput.uid);
+    awaitingFreeBusyRequests.push(currentInput);
+  }
+  if (awaitingFreeBusyRequests.length > 0)
+    displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
+}
+
+if (this.initTimeWidgets)
+  this.oldInitTimeWidgets = this.initTimeWidgets;
+
+this.initTimeWidgets = function(widgets) {
+  if (this.oldInitTimeWidgets)
+    this.oldInitTimeWidgets(widgets);
+
+  this.timeWidgets = widgets;
+
+  widgets['start']['hour'].addEventListener("change", onTimeWidgetChange, false);
+  widgets['start']['minute'].addEventListener("change", onTimeWidgetChange, false);
+  widgets['end']['hour'].addEventListener("change", onTimeWidgetChange, false);
+  widgets['end']['minute'].addEventListener("change", onTimeWidgetChange, false);
+  widgets['start']['date'].addEventListener("change", onTimeDateWidgetChange, false);
+  widgets['end']['date'].addEventListener("change", onTimeDateWidgetChange, false);
+
+  widgets['start']['date'].assignReplica($("FBStartTimeReplica_date"));
+  widgets['end']['date'].assignReplica($("FBEndTimeReplica_date"));
+
+  var form = $("FBStartTimeReplica_date").form;
+  widgets['end']['hour'].assignReplica(form["FBEndTimeReplica_time_hour"]);
+  widgets['end']['minute'].assignReplica(form["FBEndTimeReplica_time_minute"]);
+  widgets['start']['hour'].assignReplica(form["FBStartTimeReplica_time_hour"]);
+  widgets['start']['minute'].assignReplica(form["FBStartTimeReplica_time_minute"]);
+}
+
+function onTimeDateWidgetChange(event) {
+  if (document.timeWidgetsFreeBusyAjaxRequest) {
+    document.timeWidgetsFreeBusyAjaxRequest.aborted = true;
+    document.timeWidgetsFreeBusyAjaxRequest.abort();
+  }
+
+  var date1 = window.timeWidgets['start']['date'].valueAsShortDateString();
+  var date2 = window.timeWidgets['end']['date'].valueAsShortDateString();
+  var attendees = $(freeBusySelectorId).value;
+  var urlstr = ( "../freeBusyTable?sday=" + date1 + "&eday=" + date2
+                 + "&attendees=" + attendees );
+  document.timeWidgetsFreeBusyAjaxRequest
+    = triggerAjaxRequest(urlstr, timeWidgetsFreeBusyCallback);
+}
+
+function timeWidgetsFreeBusyCallback(http)
+{
+  if (http.readyState == 4) {
+    if (http.status == 200) {
+      var div = $("parentOf" + freeBusySelectorId.capitalize());
+      div.innerHTML = http.responseText;
+      resetAttendeesValue();
+      resetAllFreeBusys();
+      redisplayFreeBusyZone();
+    }
+    document.timeWidgetsFreeBusyAjaxRequest = null;
+  }
+}
+
+function onTimeWidgetChange()
+{
+  setTimeout("redisplayFreeBusyZone();", 1000);
+}
+
+function onFreeBusyLoadHandler() {
+  initializeFreeBusyUserSelector();
+}
+
+window.addEventListener("load", onFreeBusyLoadHandler, false);
diff --git a/UI/WebServerResources/UIxMailEditor.css b/UI/WebServerResources/UIxMailEditor.css
new file mode 100644 (file)
index 0000000..7f088b8
--- /dev/null
@@ -0,0 +1,97 @@
+/* CSS for compose panel */
+
+div#compose_panel div table {
+  padding: 2px;
+}
+
+TABLE#compose_table, TABLE#compose_table DIV
+{ 
+  width: 100%;
+}
+
+TABLE#compose_label
+{
+  text-align: right;
+}
+
+DIV#addressList
+{
+  height: 8em;
+  margin-bottom: .25em;
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+DIV.addressListElement
+{ margin: 0px;
+  margin-right: 8em;
+  padding: 0px; }
+
+SPAN.headerField
+{ display: block;
+  float: left;
+  line-height: 1.8em;
+  width: 5em;
+  text-align: right; }
+
+SPAN.headerInput > INPUT
+{ width: 100%;
+  padding-left: 24px;
+  background-image: url('/SOGo.woa/WebServerResources/abcard.gif');
+  background-repeat: no-repeat;
+  background-position: 2px center;
+  margin-right: -9em; }
+
+DIV#subjectRow INPUT
+{ background-image: none;
+  width: 38em;
+  padding-left: .5em; }
+
+div#compose_internetmarker { 
+  padding:          8px;
+  text-align:       center;
+  background-color: white;
+  border-color:     red;
+  border-width:     2px;
+  border-style:     solid;
+}
+
+div#headerArea
+{ border-top: 1px solid #fffffb;
+  border-left: 1px solid #fffffb;
+  border-right: 2px solid #888;
+  border-bottom: 2px solid #888;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent; }
+
+div#attachmentsArea
+{ display: none;
+  float: right;
+  width: 12em;
+  height: 100%;
+  margin: 0px;
+  padding-right: 1em;
+  padding-left: 5px;
+  border-left: 1px solid #888; }
+
+div#compose_attachments_list
+{
+  width: 100%;
+  height: 10em;
+  background-color: #ffffff;
+  margin-left: 0px;
+  padding: 2px;
+  border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent;
+}
+
+TEXTAREA
+{ position: absolute;
+  left: 0em;
+  right: 0em;
+  bottom: 0em;
+  top: 17em; }
diff --git a/UI/WebServerResources/UIxMailEditor.js b/UI/WebServerResources/UIxMailEditor.js
new file mode 100644 (file)
index 0000000..afb9c46
--- /dev/null
@@ -0,0 +1,104 @@
+var contactSelectorAction = 'mailer-contacts';
+
+function addContact(tag, fullContactName, contactId, contactName, contactEmail)
+{
+  if (!mailIsRecipient(contactEmail)) {
+    var neededOptionValue = 0;
+    if (tag == "cc")
+      neededOptionValue = 1;
+    else if (tag == "bcc")
+      neededOptionValue = 2;
+
+    var stop = false;
+    var counter = 0;
+    var currentRow = $('row_' + counter);
+    while (currentRow
+           && !stop) {
+      var currentValue = currentRow.childNodesWithTag("span")[1].childNodesWithTag("input")[0].value;
+      if (currentValue == neededOptionValue) {
+        stop = true;
+        insertContact($("addr_" + counter), contactName, contactEmail);
+      }
+      counter++;
+      currentRow = $('row_' + counter);
+    }
+
+    if (!stop) {
+      fancyAddRow(false, "");
+      $("row_" + counter).childNodesWithTag("span")[0].childNodesWithTag("select")[0].value
+        = neededOptionValue;
+      insertContact($("addr_" + counter), contactName, contactEmail);
+    }
+  }
+}
+
+function mailIsRecipient(mailto) {
+  var isRecipient = false;
+
+  var counter = 0;
+  var currentRow = $('row_' + counter);
+
+  var email = extractEmailAddress(mailto).toUpperCase();
+
+  while (currentRow && !isRecipient) {
+    var currentValue = $("addr_"+counter).value.toUpperCase();
+    if (currentValue.indexOf(email) > -1)
+      isRecipient = true;
+    else
+      {
+        counter++;
+        currentRow = $('row_' + counter);
+      }
+  }
+
+  return isRecipient;
+}
+
+function insertContact(inputNode, contactName, contactEmail) {
+  var value = '' + inputNode.value;
+
+  var newContact = contactName;
+  if (newContact.length > 0)
+    newContact += ' <' + contactEmail + '>';
+  else
+    newContact = contactEmail;
+
+  if (value.length > 0)
+    value += ", ";
+  value += newContact;
+
+  inputNode.value = value;
+}
+
+function toggleAttachments() {
+  var div = $("attachmentsArea");
+  if (div.style.display)
+    div.style.display = "";
+  else
+    div.style.display = "block;";
+
+  return false;
+}
+
+function updateInlineAttachmentList(sender, attachments) {
+  var count = 0;
+
+  var div = $("attachmentsArea");
+  if (attachments)
+    count = attachments.length;
+  if (count)
+    {
+      var text  = "";
+      for (var i = 0; i < count; i++) {
+        text = text + attachments[i];
+        text = text + '<br />';
+      }
+
+      var e = $('compose_attachments_list');
+      e.innerHTML = text;
+      if (!div.style.display)
+        div.style.display = "block;";
+    }
+  else
+    div.style.display = "";
+}
diff --git a/UI/WebServerResources/UIxMailListView.js b/UI/WebServerResources/UIxMailListView.js
deleted file mode 100644 (file)
index 39414f2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-var rowSelectionCount = 0;
-
-validateControls();
-
-function showElement(e, shouldShow) {
-       e.style.display = shouldShow ? "" : "none";
-}
-
-function enableElement(e, shouldEnable) {
-  if(!e)
-    return;
-  if(shouldEnable) {
-    if(e.hasAttribute("disabled"))
-      e.removeAttribute("disabled");
-  }
-  else {
-    e.setAttribute("disabled", "1");
-  }
-}
-
-function toggleRowSelectionStatus(sender) {
-  rowID = sender.value;
-  tr = document.getElementById(rowID);
-  if(sender.checked) {
-    tr.className = "tableview_selected";
-    rowSelectionCount += 1;
-  }
-  else {
-    tr.className = "tableview";
-    rowSelectionCount -= 1;
-  }
-  this.validateControls();
-}
-
-function validateControls() {
-  var e = document.getElementById("moveto");
-  this.enableElement(e, rowSelectionCount > 0);
-}
-
-function moveTo(uri) {
-  alert("MoveTo: " + uri);
-}
index 1966931bac547fb0830d0d37ad5a65a808293770..e5e01a70bff21db15d5a3cb5e935bcd05af70833 100644 (file)
@@ -38,7 +38,7 @@ function sanitizedCn(cn) {
 }
 
 function hasAddress(email) {
-  var e = document.getElementById(email);
+  var e = $(email);
   if(e)
     return true;
   return false;
@@ -47,7 +47,7 @@ function hasAddress(email) {
 function rememberAddress(email) {
   var list, span, idx;
   
-  list    = document.getElementById('addr_addresses');
+  list    = $('addr_addresses');
   span    = document.createElement('span');
   span.id = email;
   idx     = document.createTextNode(currentIndex);
@@ -71,7 +71,7 @@ function addAddress(type, email, uid, sn, cn, dn) {
   if(this.hasAddress(email))
     return;
   
-  e = document.getElementById('addr_0');
+  e = $('addr_0');
   if(e.value == '') {
     e.value = s;
     shouldAddRow = false;
@@ -83,42 +83,45 @@ function addAddress(type, email, uid, sn, cn, dn) {
 }
 
 function fancyAddRow(shouldEdit, text) {
-  var addr, table, lastChild, proto, row, select, input;
+  var addr, addressList, lastChild, proto, row, select, input;
   
-  addr = document.getElementById('addr_' + lastIndex);
+  addr = $('addr_' + lastIndex);
   if (addr && addr.value == '') {
-    input = document.getElementById('compose_subject_input');
+    input = $('subjectField');
     if (input && input.value != '') {
       input.focus();
       input.select();
       return;
     }
   }
-  table = this.getTable();
-  lastChild = document.getElementById('row_last');
+  addressList = $("addressList");
+  lastChild = $("lastRow");
   
   currentIndex++;
-  
-  proto = document.getElementById('row_' + lastIndex);
+
+  proto = $('row_' + lastIndex);
   row = proto.cloneNode(true);
   row.id = 'row_' + currentIndex;
-  
+
   // select popup
-  select = row.childNodes[1].childNodes[1];
+  var rowNodes = row.childNodesWithTag("span");
+  select = rowNodes[0].childNodesWithTag("select")[0];
   select.name = 'popup_' + currentIndex;
-  select.value = proto.childNodes[1].childNodes[1].value;
-  input = row.childNodes[3].childNodes[1];
+//   select.value = row.childNodesWithTag("span")[0].childNodesWithTag("select")[0].value;
+  input = rowNodes[1].childNodesWithTag("input")[0];
   input.name  = 'addr_' + currentIndex;
-  input.id    = 'addr_' + currentIndex;
+  input.id = 'addr_' + currentIndex;
   input.value = text;
-  
-  table.insertBefore(row, lastChild);
 
-  if(shouldEdit) {
+  addressList.insertBefore(row, lastChild);
+
+  if (shouldEdit) {
+    input.setAttribute('autocomplete', 'off');
     input.focus();
     input.select();
+    input.setAttribute('autocomplete', 'on');
   }
-  this.adjustInlineAttachmentListHeight(this);
+//   this.adjustInlineAttachmentListHeight(this);
 }
 
 function addressFieldGotFocus(sender) {
@@ -127,33 +130,38 @@ function addressFieldGotFocus(sender) {
   idx = this.getIndexFromIdentifier(sender.id);
   if ((lastIndex == idx) || (idx == 0)) return;
   this.removeLastEditedRowIfEmpty();
+
+  return false;
 }
+
 function addressFieldLostFocus(sender) {
   lastIndex = this.getIndexFromIdentifier(sender.id);
+
+  return false;
 }
 
 function removeLastEditedRowIfEmpty() {
-  var idx, addr, table, senderRow;
+  var idx, addr, addressList, senderRow;
   
   idx = lastIndex;
   if (idx == 0) return;
-  addr = document.getElementById('addr_' + idx);
+  addr = $('addr_' + idx);
   if (!addr) return;
   if (addr.value != '') return;
   addr = this.findAddressWithIndex(idx);
   if(addr) {
-    var addresses = document.getElementById('addr_addresses');
+    var addresses = $('addr_addresses');
     addresses.removeChild(addr);
   }
-  table = this.getTable();
-  senderRow = this.findRowWithIndex(idx);
-  table.removeChild(senderRow);
+  addressList = $("addressList");
+  senderRow = $("row_" + idx);
+  addressList.removeChild(senderRow);
   this.adjustInlineAttachmentListHeight(this);
 }
 
 function findAddressWithIndex(idx) {
   var list, i, count, addr, idx
-  list = document.getElementById('addr_addresses').childNodes;
+  list = $('addr_addresses').childNodes;
   count = list.length;
   for(i = 0; i < count; i++) {
     addr = list[i];
@@ -163,32 +171,23 @@ function findAddressWithIndex(idx) {
   return null;
 }
 
-function findRowWithIndex(idx) {
-  var id = 'row_' + idx;
-  return document.getElementById(id);
-}
-
 function getIndexFromIdentifier(id) {
   return id.split('_')[1];
 }
 
-function getTable() {
-  return document.getElementById('addr_table').childNodes[1];
-};
-
 function getAddressIDs() {
-  var table, rows, i, count, addressIDs;
+  var addressList, rows, i, count, addressIDs;
 
   addressIDs = new Array();
 
-  table = this.getTable();
-  rows  = table.childNodes;
+  addressList = $("addressList");
+  rows  = addressList.childNodes;
   count = rows.length;
-  
+
   for (i = 0; i < count; i++) {
     var row, rowId;
     
-    row   = table.childNodes[i];
+    row = addressList.childNodes[i];
     rowId = row.id;
     if (rowId && rowId != 'row_last') {
       var idx;
@@ -210,8 +209,8 @@ function getAddressCount() {
     var idx, input;
 
     idx   = addressIDs[i];
-    input = document.getElementById('addr_' + idx);
-    if (input.value != '')
+    input = $('addr_' + idx);
+    if (input && input.value != '')
       addressCount++;
   }
   return addressCount;
@@ -225,3 +224,22 @@ function UIxRecipientSelectorHasRecipients() {
     return true;
   return false;
 }
+
+function adjustInlineAttachmentListHeight(sender) {
+  var e;
+  
+  e = $('attachmentsArea');
+  if (e.style.display != 'none') {
+    /* need to lower left size first, because left auto-adjusts to right! */
+    xHeight('compose_attachments_list', 10);
+
+    var leftHeight, rightHeaderHeight;
+    leftHeight        = xHeight('compose_leftside');
+    rightHeaderHeight = xHeight('compose_attachments_header');
+    xHeight('compose_attachments_list',
+            (leftHeight - rightHeaderHeight) - 16);
+  }
+}
+
+/* addressbook helpers */
+
diff --git a/UI/WebServerResources/UIxTaskEditor.css b/UI/WebServerResources/UIxTaskEditor.css
new file mode 100644 (file)
index 0000000..5771ec3
--- /dev/null
@@ -0,0 +1,129 @@
+DIV.appointmentLabel
+{ display: block;
+  position: relative;
+  line-height: 1.8em;
+  text-align: right;
+  width: 3em; }
+
+DIV#editorTabs
+{
+  width: 100%;
+  height: 38em;
+}
+
+DIV#editorTabs > DIV.tab
+{ overflow: hidden;
+  padding: .5em; }
+
+DIV.appointmentRightLabel
+{ display: inline;
+  vertical-align: middle; }
+
+UL.contactList
+{ 
+  display: block;
+  cursor: default;
+  list-style-type: none;
+  list-style-image: none;
+  margin: 0px;
+  padding: 0px;
+  background: #fff;
+  border: 1px solid #000;
+  width: 15em;
+  height: 5em;
+  overflow: auto;
+}
+
+UL.contactList LI IMG
+{ vertical-align: middle; }
+
+UL.contactList LI
+{ width: 100%;
+  white-space: nowrap;
+  vertical-align: middle; }
+
+UL.contactList LI._selected
+{ background: #4b6983;
+  color: #fff; }
+
+DIV.contactSelector
+{ margin: 0px; }
+
+LABEL, SPAN.checkBoxList
+{ display: block;
+  position: relative;
+  height: 1.5em;
+  margin-left: .5em;
+  margin-bottom: .5em;
+  width: 100%; }
+
+LABEL#commentArea
+{ height: 11.5em; }
+
+SPAN.checkBoxList#participantsCB
+{ height: 7em; }
+
+SPAN.checkBoxList#categoriesCB
+{ height: 3em; }
+
+DIV#participants UL.contactList
+{ height: 4.5em; }
+
+SPAN.checkBoxList SPAN.content LABEL
+{ display: inline; }
+
+SPAN.content
+{ position: absolute;
+  top: -.25em;
+  left: 8em;
+  right: 1em; }
+
+TEXTAREA
+{ position: absolute;
+  top: 0px;
+  left: 8em;
+  vertical-align: bottom;
+  height: 10em;
+  right: 1em;
+  padding-bottom: 1em; }
+
+A#detailsButton
+{ position: absolute;
+  right: 1em;
+  z-index: 1; }
+
+SPAN.contactSelectorButtons
+{ vertical-align: top;
+  line-height: 2em; }
+
+SPAN#cycleSelectionFirstLevel,
+SPAN#cycleSelectionSecondLevel
+{ visibility: hidden;
+  margin-left: 1em; }
+
+SPAN#cycleSelectionSecondLevel SPAN.timeDateControl
+{ position: static;
+  margin: 0px; }
+
+SPAN#categoriesCB INPUT
+{ border: 2px solid #000;
+  vertical-align: middle;
+  -moz-border-top-colors: #000 #fff;
+  -moz-border-left-colors: #000 #fff; 
+  -moz-border-bottom-colors: #000 #fff;
+  -moz-border-right-colors: #000 #fff; }
+
+SPAN#categoriesCB LABEL
+{ margin-left: 0px;
+  margin-right: 1em; }
+
+SPAN.content > INPUT
+{ position: absolute;
+  top: 0px;
+  left: 0px;
+  right: 0px; }
+
+INPUT#startDateCB,
+INPUT#dueDateCB,
+LABEL#urlArea INPUT
+{ position: static; }
diff --git a/UI/WebServerResources/UIxTaskEditor.js b/UI/WebServerResources/UIxTaskEditor.js
new file mode 100644 (file)
index 0000000..ff5846d
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+  Copyright (C) 2005 SKYRIX Software AG
+  This file is part of SOGo.
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+var contactSelectorAction = 'calendars-contacts';
+
+function uixEarlierDate(date1, date2) {
+  // can this be done in a sane way?
+  //   cuicui = 'year';
+  if (date1 && date2) {
+    if (date1.getYear()  < date2.getYear()) return date1;
+    if (date1.getYear()  > date2.getYear()) return date2;
+  // same year
+  //   cuicui += '/month';
+    if (date1.getMonth() < date2.getMonth()) return date1;
+    if (date1.getMonth() > date2.getMonth()) return date2;
+  //   // same month
+  //   cuicui += '/date';
+    if (date1.getDate() < date2.getDate()) return date1;
+    if (date1.getDate() > date2.getDate()) return date2;
+  }
+  // same day
+  return null;
+}
+
+function validateDate(date, label) {
+  var result, dateValue;
+
+  dateValue = date.calendar.prs_date(date.value);
+  if (date.value.length != 10 || !dateValue) {
+    alert(label.decodeEntities());
+    result = false;
+  } else
+    result = dateValue;
+
+  return result;
+}
+
+function validateTaskEditor() {
+  var e, startdate, enddate, tmpdate;
+
+  e = document.getElementById('summary');
+  if (e.value.length == 0
+      && !confirm(labels.validate_notitle.decodeEntities()))
+    return false;
+
+  e = document.getElementById('startTime_date');
+  if (!e.disabled) {
+    startdate = validateDate(e, labels.validate_invalid_startdate);
+    if (!startdate)
+      return false;
+  }
+
+  e = document.getElementById('dueTime_date');
+  if (!e.disabled) {
+    enddate = validateDate(e, labels.validate_invalid_enddate);
+    if (!enddate)
+      return false;
+  }
+
+  if (startdate && enddate) {
+    tmpdate = uixEarlierDate(startdate, enddate);
+    if (tmpdate == enddate) {
+      //     window.alert(cuicui);
+      alert(labels.validate_endbeforestart.decodeEntities());
+      return false;
+    }
+    else if (tmpdate == null /* means: same date */) {
+      // TODO: check time
+      var start, end;
+      
+      start = parseInt(document.forms[0]['startTime_time_hour'].value);
+      end = parseInt(document.forms[0]['dueTime_time_hour'].value);
+      
+      if (start > end) {
+        alert(labels.validate_endbeforestart.decodeEntities());
+        return false;
+      }
+      else if (start == end) {
+        start = parseInt(document.forms[0]['startTime_time_minute'].value);
+        end = parseInt(document.forms[0]['dueTime_time_minute'].value);
+        if (start > end) {
+          alert(labels.validate_endbeforestart.decodeEntities());
+          return false;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+function toggleDetails() {
+  var div = $("details");
+  var buttons = $("buttons");
+  var buttonsHeight = buttons.clientHeight * 3;
+
+  if (div.style.visibility) {
+    div.style.visibility = null;
+    window.resizeBy(0, -(div.clientHeight + buttonsHeight));
+    $("detailsButton").innerHTML = labels["Show Details"];
+  } else {
+    div.style.visibility = 'visible;';
+    window.resizeBy(0, (div.clientHeight + buttonsHeight));
+    $("detailsButton").innerHTML = labels["Hide Details"];
+  }
+
+  return false;
+}
+
+function toggleCycleVisibility(node, nodeName, hiddenValue) {
+  var spanNode = $(nodeName);
+  var newVisibility = ((node.value == hiddenValue) ? null : 'visible;');
+  spanNode.style.visibility = newVisibility;
+
+  if (nodeName == 'cycleSelectionFirstLevel') {
+    var otherSpanNode = $('cycleSelectionSecondLevel');
+    if (!newVisibility)
+      {
+        otherSpanNode.superVisibility = otherSpanNode.style.visibility;
+        otherSpanNode.style.visibility = null;
+      }
+    else
+      {
+        otherSpanNode.style.visibility = otherSpanNode.superVisibility;
+        otherSpanNode.superVisibility = null;
+      }
+  }
+}
+
+function addContact(tag, fullContactName, contactId, contactName, contactEmail)
+{
+  var uids = $('uixselector-participants-uidList');
+  log ("contactId: " + contactId);
+  if (contactId)
+    {
+      var re = new RegExp("(^|,)" + contactId + "($|,)");
+
+      log ("uids: " + uids);
+      if (!re.test(uids.value))
+        {
+          log ("no match... realling adding");
+          if (uids.value.length > 0)
+            uids.value += ',' + contactId;
+          else
+            uids.value = contactId;
+
+          var names = $('uixselector-participants-display');
+          names.innerHTML += ('<li onmousedown="return false;"'
+                              + ' onclick="onRowClick(event);"><img src="'
+                              + ResourcesURL + '/abcard.gif" />'
+                              + contactName + '</li>');
+        }
+      else
+        log ("match... ignoring contact");
+    }
+
+  return false;
+}
+
+function onTimeControlCheck(checkBox) {
+  var inputs = checkBox.parentNode.getElementsByTagName("input");
+  var selects = checkBox.parentNode.getElementsByTagName("select");
+  for (var i = 0; i < inputs.length; i++)
+    if (inputs[i] != checkBox)
+      inputs[i].disabled = !checkBox.checked;
+  for (var i = 0; i < selects.length; i++)
+    if (selects[i] != checkBox)
+      selects[i].disabled = !checkBox.checked;
+}
+
+function saveEvent(sender) {
+  if (validateTaskEditor())
+    document.forms['editform'].submit();
+
+  return false;
+}
+
+function startDayAsShortString() {
+  return dayAsShortDateString($('startTime_date'));
+}
+
+function dueDayAsShortString() {
+  return dayAsShortDateString($('dueTime_date'));
+}
+
+this._getDate = function(which) {
+  var date = window.timeWidgets[which]['date'].valueAsDate();
+  date.setHours( window.timeWidgets[which]['hour'].value );
+  date.setMinutes( window.timeWidgets[which]['minute'].value );
+
+  return date;
+}
+
+this._getShadowDate = function(which) {
+  var date = window.timeWidgets[which]['date'].getAttribute("shadow-value").asDate();
+  var intValue = parseInt(window.timeWidgets[which]['hour'].getAttribute("shadow-value"));
+  date.setHours(intValue);
+  intValue = parseInt(window.timeWidgets[which]['minute'].getAttribute("shadow-value"));
+  date.setMinutes(intValue);
+//   window.alert("shadow: " + date);
+
+  return date;
+}
+
+this.getStartDate = function() {
+  return this._getDate('start');
+}
+
+this.getDueDate = function() {
+  return this._getDate('due');
+}
+
+this.getShadowStartDate = function() {
+  return this._getShadowDate('start');
+}
+
+this.getShadowDueDate = function() {
+  return this._getShadowDate('due');
+}
+
+this._setDate = function(which, newDate) {
+  window.timeWidgets[which]['date'].setValueAsDate(newDate);
+  window.timeWidgets[which]['hour'].value = newDate.getHours();
+  var minutes = newDate.getMinutes();
+  if (minutes % 15)
+    minutes += (15 - minutes % 15);
+  window.timeWidgets[which]['minute'].value = minutes;
+}
+
+this.setStartDate = function(newStartDate) {
+  this._setDate('start', newStartDate);
+}
+
+this.setDueDate = function(newDueDate) {
+//   window.alert(newDueDate);
+  this._setDate('due', newDueDate);
+}
+
+this.onAdjustDueTime = function(event) {
+  if (!window.timeWidgets['due']['date'].disabled) {
+    var dateDelta = (window.getStartDate().valueOf()
+                     - window.getShadowStartDate().valueOf());
+    var newDueDate = new Date(window.getDueDate().valueOf() + dateDelta);
+    window.setDueDate(newDueDate);
+  }
+  window.timeWidgets['start']['date'].updateShadowValue();
+  window.timeWidgets['start']['hour'].updateShadowValue();
+  window.timeWidgets['start']['minute'].updateShadowValue();
+}
+
+this.initTimeWidgets = function (widgets) {
+  this.timeWidgets = widgets;
+
+  widgets['start']['date'].addEventListener("change", this.onAdjustDueTime, false);
+  widgets['start']['hour'].addEventListener("change", this.onAdjustDueTime, false);
+  widgets['start']['minute'].addEventListener("change", this.onAdjustDueTime, false);
+}
diff --git a/UI/WebServerResources/abcard.gif b/UI/WebServerResources/abcard.gif
new file mode 100644 (file)
index 0000000..8bd089d
Binary files /dev/null and b/UI/WebServerResources/abcard.gif differ
diff --git a/UI/WebServerResources/accepted.png b/UI/WebServerResources/accepted.png
new file mode 100644 (file)
index 0000000..6b80bd5
Binary files /dev/null and b/UI/WebServerResources/accepted.png differ
diff --git a/UI/WebServerResources/account-settings.png b/UI/WebServerResources/account-settings.png
new file mode 100644 (file)
index 0000000..46b7e71
Binary files /dev/null and b/UI/WebServerResources/account-settings.png differ
diff --git a/UI/WebServerResources/add-addressbook.png b/UI/WebServerResources/add-addressbook.png
new file mode 100644 (file)
index 0000000..f387c7b
Binary files /dev/null and b/UI/WebServerResources/add-addressbook.png differ
diff --git a/UI/WebServerResources/add-contact.gif b/UI/WebServerResources/add-contact.gif
new file mode 100644 (file)
index 0000000..94a8cec
Binary files /dev/null and b/UI/WebServerResources/add-contact.gif differ
diff --git a/UI/WebServerResources/arrow-lft-sharp.gif b/UI/WebServerResources/arrow-lft-sharp.gif
new file mode 100644 (file)
index 0000000..ae9b1dd
Binary files /dev/null and b/UI/WebServerResources/arrow-lft-sharp.gif differ
diff --git a/UI/WebServerResources/arrow-rit-sharp.gif b/UI/WebServerResources/arrow-rit-sharp.gif
new file mode 100644 (file)
index 0000000..ca628ba
Binary files /dev/null and b/UI/WebServerResources/arrow-rit-sharp.gif differ
diff --git a/UI/WebServerResources/busy.gif b/UI/WebServerResources/busy.gif
new file mode 100644 (file)
index 0000000..cce32f2
Binary files /dev/null and b/UI/WebServerResources/busy.gif differ
index 73fb38beb47c1ac5b5b718c01fc46f96794a04c6..384964917cae4896b5a5995fffe4a412a4a0a84d 100644 (file)
@@ -202,10 +202,10 @@ td.schedoverview {
   text-align:       center;
   vertical-align:   top;
   font-size:        11pt;
-//  width:            24px;
-//  padding:          2px 2px 2px 2px;
-//  margin:           2px 2px 2px 2px;
-}
+/  width:            24px;
+  padding:          2px 2px 2px 2px;
+  margin:           2px 2px 2px 2px;
+ */}
 
 .dayoverview_cal_content {
   color:            #0033cc;
@@ -646,11 +646,12 @@ h1.weekprintview {
   font-style:       normal;
   font-weight:      normal;
 }
-.monthoverview_day {
-//  text-align:       left;
-//  vertical-align:   top;
-}
 
+/* .monthoverview_day {
+  text-align:       left;
+  vertical-align:   top;
+}
+ */
 .monthoverview_day a {
   color:            #000000;
   font-size:        12pt;
diff --git a/UI/WebServerResources/chair.png b/UI/WebServerResources/chair.png
new file mode 100644 (file)
index 0000000..f4a21db
Binary files /dev/null and b/UI/WebServerResources/chair.png differ
diff --git a/UI/WebServerResources/choose-date.png b/UI/WebServerResources/choose-date.png
new file mode 100644 (file)
index 0000000..b81fb3c
Binary files /dev/null and b/UI/WebServerResources/choose-date.png differ
diff --git a/UI/WebServerResources/create-account.png b/UI/WebServerResources/create-account.png
new file mode 100644 (file)
index 0000000..6f9450c
Binary files /dev/null and b/UI/WebServerResources/create-account.png differ
diff --git a/UI/WebServerResources/day-view.png b/UI/WebServerResources/day-view.png
new file mode 100644 (file)
index 0000000..074c260
Binary files /dev/null and b/UI/WebServerResources/day-view.png differ
diff --git a/UI/WebServerResources/declined.png b/UI/WebServerResources/declined.png
new file mode 100644 (file)
index 0000000..e769a15
Binary files /dev/null and b/UI/WebServerResources/declined.png differ
diff --git a/UI/WebServerResources/delete.png b/UI/WebServerResources/delete.png
new file mode 100644 (file)
index 0000000..e951de0
Binary files /dev/null and b/UI/WebServerResources/delete.png differ
diff --git a/UI/WebServerResources/downstairs.gif b/UI/WebServerResources/downstairs.gif
new file mode 100644 (file)
index 0000000..898418d
Binary files /dev/null and b/UI/WebServerResources/downstairs.gif differ
diff --git a/UI/WebServerResources/dtree.css b/UI/WebServerResources/dtree.css
new file mode 100644 (file)
index 0000000..0d95403
--- /dev/null
@@ -0,0 +1,45 @@
+/*--------------------------------------------------|
+| dTree 2.05 | www.destroydrop.com/javascript/tree/ |
+|---------------------------------------------------|
+| Copyright (c) 2002-2003 Geir Landrö               |
+|--------------------------------------------------*/
+
+.dtree
+{
+  color: #000;
+  white-space: nowrap;
+}
+
+.dtree img
+{
+  vertical-align: middle;
+  border: 0px;
+  padding: 0px;
+  margin: 0px;
+}
+
+.dtree a
+{
+  cursor: default;
+  color: #000;
+  text-decoration: none;
+}
+
+.dtree a.node
+{
+  white-space: nowrap;
+  padding: 1px 2px;
+}
+
+.dtree a.node:hover
+{
+  text-decoration: none;
+}
+
+.dtree .clip
+{
+  overflow: hidden;
+}
+
+DIV.dTreeNode
+{ height: 18px; }
diff --git a/UI/WebServerResources/dtree.js b/UI/WebServerResources/dtree.js
new file mode 100644 (file)
index 0000000..169e990
--- /dev/null
@@ -0,0 +1,374 @@
+/*--------------------------------------------------|
+  | dTree 2.05 | www.destroydrop.com/javascript/tree/ |
+  |---------------------------------------------------|
+  | Copyright (c) 2002-2003 Geir Landrö               |
+  |                                                   |
+  | This script can be used freely as long as all     |
+  | copyright messages are intact.                    |
+  |                                                   |
+  | Updated: 17.04.2003                               |
+  |--------------------------------------------------*/
+
+// Node object
+function Node(id, pid, name, isParent, url, dataname, datatype, title, target,
+              icon, iconOpen, open) {
+  this.isParent = isParent;
+  this.id = id;
+  this.pid = pid;
+  this.name = name;
+  this.url = url; 
+  this.title = title;
+  this.target = target;
+  this.icon = icon;
+  this.iconOpen = iconOpen;
+  this.dataname = dataname;
+  this.datatype = datatype;
+  this._io = open || false;
+  this._is = false;
+  this._ls = false;
+  this._hc = false;
+  this._ai = 0;
+  this._p;
+};
+
+// Tree object
+function dTree(objName) {
+  this.config = {
+    target : null,
+    hideRoot : false,
+    folderLinks : true,
+    useSelection : true,
+    useCookies : false,
+    useLines : true,
+    useIcons : true,
+    useStatusText : false,
+    closeSameLevel : false,
+    inOrder : false
+  }
+  this.icon = {
+    root : 'img/base.gif',
+    folder : 'img/folder.gif',
+    folderOpen : 'img/folderopen.gif',
+    node : 'img/page.gif',
+    empty : 'img/empty.gif',
+    line : 'img/line.gif',
+    join : 'img/join.gif',
+    joinBottom : 'img/joinbottom.gif',
+    plus : 'img/plus.gif',
+    plusBottom : 'img/plusbottom.gif',
+    minus : 'img/minus.gif',
+    minusBottom : 'img/minusbottom.gif',
+    nlPlus : 'img/nolines_plus.gif',
+    nlMinus : 'img/nolines_minus.gif'
+  };
+  this.obj = objName;
+  this.aNodes = [];
+  this.aIndent = [];
+  this.root = new Node(-1);
+  this.selectedNode = null;
+  this.selectedFound = false;
+  this.completed = false;
+};
+
+// Adds a new node to the node array
+dTree.prototype.add = function(id, pid, name, isParent, url, datatype,
+                               title, target, icon, iconOpen, open) {
+  this.aNodes[this.aNodes.length] = new Node(id, pid, name, isParent, url,
+                                             datatype, title, target, icon,
+                                             iconOpen, open);
+};
+
+// Open/close all nodes
+dTree.prototype.openAll = function() {
+  this.oAll(true);
+};
+dTree.prototype.closeAll = function() {
+  this.oAll(false);
+};
+
+// Outputs the tree to the page
+dTree.prototype.toString = function() {
+  var str = '<div class="dtree" id="' + this.obj + '">\n';
+  if (document.getElementById) {
+    if (this.config.useCookies)
+      this.selectedNode = this.getSelected();
+    str += this.addNode(this.root);
+  } else str += 'Browser not supported.';
+  str += '</div>';
+  if (!this.selectedFound) this.selectedNode = null;
+  this.completed = true;
+  return str;
+};
+
+// Creates the tree structure
+dTree.prototype.addNode = function(pNode) {
+  var str = '';
+  var n=0;
+  if (this.config.inOrder) n = pNode._ai;
+  for (n; n<this.aNodes.length; n++) {
+    if (this.aNodes[n].pid == pNode.id) {
+      var cn = this.aNodes[n];
+      cn._p = pNode;
+      cn._ai = n;
+      this.setCS(cn);
+      if (!cn.target && this.config.target) cn.target = this.config.target;
+      if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id);
+      if (!this.config.folderLinks && cn._hc) cn.url = null;
+      if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) {
+ cn._is = true;
+ this.selectedNode = n;
+ this.selectedFound = true;
+      }
+      str += this.node(cn, n);
+      if (cn._ls) break;
+    }
+  }
+  return str;
+};
+
+// Creates the node icon, url and text
+dTree.prototype.node = function(node, nodeId) {
+  var str = '';
+
+  if (this.root.id != node.pid || !this.config.hideRoot) {
+    str += '<div class="dTreeNode"';
+    if (node.datatype) str += ' datatype="' + node.datatype + '"';
+    if (node.dataname) str += ' dataname="' + node.dataname + '"';
+    str += '>' + this.indent(node, nodeId);
+    if (node.url) {
+      str += '<a id="s' + this.obj + nodeId + '" class="node" href="' + node.url + '"';
+      if (node.title) str += ' title="' + node.title + '"';
+      if (node.target) str += ' target="' + node.target + '"';
+      if (this.config.useStatusText) str += ' onmouseover="window.status=\'' + node.name + '\';return true;" onmouseout="window.status=\'\';return true;" ';
+      if (this.config.useSelection && ((node._hc && this.config.folderLinks) || !node._hc))
+       str += ' onclick="' + this.obj + '.s(' + nodeId + ');"';
+      str += '>';
+    }
+    else if ((!this.config.folderLinks || !node.url) && node._hc && node.pid != this.root.id)
+      str += '<a href="#" onclick="' + this.obj + '.o(' + nodeId + ');" class="node">';
+    if (this.config.useIcons) {
+      if (!node.icon) node.icon = (this.root.id == node.pid) ? this.icon.root : ((node._hc) ? this.icon.folder : this.icon.node);
+      if (!node.iconOpen) node.iconOpen = (node._hc) ? this.icon.folderOpen : this.icon.node;
+      if (this.root.id == node.pid) {
+       node.icon = this.icon.root;
+       node.iconOpen = this.icon.root;
+      }
+      str += '<img id="i' + this.obj + nodeId + '" src="' + ((node._io) ? node.iconOpen : node.icon) + '" alt="" />';
+    }
+    str += '<span class="nodeName';
+    if (!node.isParent)
+      str += ' leaf';
+    str += '">' + node.name + '</span>';
+    if (node.url || ((!this.config.folderLinks || !node.url) && node._hc)) str += '</a>';
+    str += '</div>';
+  }
+  if (node._hc) {
+    str += '<div id="d' + this.obj + nodeId + '" class="clip" style="display:' + ((this.root.id == node.pid || node._io) ? 'block' : 'none') + ';">';
+    str += this.addNode(node);
+    str += '</div>';
+  }
+  this.aIndent.pop();
+  return str;
+};
+
+// Adds the empty and line icons
+dTree.prototype.indent = function(node, nodeId) {
+  var str = '';
+  if (this.root.id != node.pid)
+  {
+    for (var n=0; n<this.aIndent.length; n++)
+      str += '<img src="' + ( (this.aIndent[n] == 1 && this.config.useLines) ? this.icon.line : this.icon.empty ) + '" alt="" />';
+    (node._ls) ? this.aIndent.push(0) : this.aIndent.push(1);
+    if (node._hc)
+      {
+       str += '<a href="#" onclick="return ' + this.obj + '.o(' + nodeId + ');"><img id="j' + this.obj + nodeId + '" src="';
+       if (!this.config.useLines) str += (node._io) ? this.icon.nlMinus : this.icon.nlPlus;
+       else str += ( (node._io) ? ((node._ls && this.config.useLines) ? this.icon.minusBottom : this.icon.minus) : ((node._ls && this.config.useLines) ? this.icon.plusBottom : this.icon.plus ) );
+       str += '" alt="" /></a>';
+      }
+    else
+      str += '<img src="' + ( (this.config.useLines) ? ((node._ls) ? this.icon.joinBottom : this.icon.join ) : this.icon.empty) + '" alt="" />';
+  }
+  return str;
+};
+
+// Checks if a node has any children and if it is the last sibling
+dTree.prototype.setCS = function(node) {
+  var lastId;
+  for (var n=0; n<this.aNodes.length; n++) {
+    if (this.aNodes[n].pid == node.id) node._hc = true;
+    if (this.aNodes[n].pid == node.pid) lastId = this.aNodes[n].id;
+  }
+  if (lastId==node.id) node._ls = true;
+};
+
+// Returns the selected node
+dTree.prototype.getSelected = function() {
+  var sn = this.getCookie('cs' + this.obj);
+  return (sn) ? sn : null;
+};
+
+// Highlights the selected node
+dTree.prototype.s = function(id) {
+  if (!this.config.useSelection) return;
+  var cn = this.aNodes[id];
+  if (cn._hc && !this.config.folderLinks) return;
+  if (this.selectedNode != id) {
+    if (this.selectedNode || this.selectedNode==0) {
+      eOld = document.getElementById("s" + this.obj + this.selectedNode);
+      eOld.deselect();
+    }
+    eNew = document.getElementById("s" + this.obj + id);
+    eNew.select();
+    this.selectedNode = id;
+    if (this.config.useCookies) this.setCookie('cs' + this.obj, cn.id);
+  }
+};
+
+// Toggle Open or close
+dTree.prototype.o = function(id) {
+  var cn = this.aNodes[id];
+  this.nodeStatus(!cn._io, id, cn._ls);
+  cn._io = !cn._io;
+  if (this.config.closeSameLevel) this.closeLevel(cn);
+  if (this.config.useCookies) this.updateCookie();
+
+  return false;
+};
+
+// Open or close all nodes
+dTree.prototype.oAll = function(status) {
+  for (var n=0; n<this.aNodes.length; n++) {
+    if (this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) {
+      this.nodeStatus(status, n, this.aNodes[n]._ls)
+      this.aNodes[n]._io = status;
+    }
+  }
+  if (this.config.useCookies) this.updateCookie();
+};
+
+// Opens the tree to a specific node
+dTree.prototype.openTo = function(nId, bSelect, bFirst) {
+  if (!bFirst) {
+    for (var n=0; n<this.aNodes.length; n++) {
+      if (this.aNodes[n].id == nId) {
+       nId=n;
+       break;
+      }
+    }
+  }
+  var cn=this.aNodes[nId];
+  if (cn.pid==this.root.id || !cn._p) return;
+  cn._io = true;
+  cn._is = bSelect;
+  if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls);
+  if (this.completed && bSelect) this.s(cn._ai);
+  else if (bSelect) this._sn=cn._ai;
+  this.openTo(cn._p._ai, false, true);
+};
+
+// Closes all nodes on the same level as certain node
+dTree.prototype.closeLevel = function(node) {
+  for (var n=0; n<this.aNodes.length; n++) {
+    if (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) {
+      this.nodeStatus(false, n, this.aNodes[n]._ls);
+      this.aNodes[n]._io = false;
+      this.closeAllChildren(this.aNodes[n]);
+    }
+  }
+}
+
+// Closes all children of a node
+dTree.prototype.closeAllChildren = function(node) {
+  for (var n=0; n<this.aNodes.length; n++) {
+    if (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) {
+      if (this.aNodes[n]._io) this.nodeStatus(false, n, this.aNodes[n]._ls);
+      this.aNodes[n]._io = false;
+      this.closeAllChildren(this.aNodes[n]); 
+    }
+  }
+}
+
+// Change the status of a node(open or closed)
+dTree.prototype.nodeStatus = function(status, id, bottom) {
+  eDiv = document.getElementById('d' + this.obj + id);
+  eJoin = document.getElementById('j' + this.obj + id);
+  if (this.config.useIcons) {
+    eIcon = document.getElementById('i' + this.obj + id);
+    eIcon.src = (status) ? this.aNodes[id].iconOpen : this.aNodes[id].icon;
+  }
+  eJoin.src = (this.config.useLines)?
+  ((status)?((bottom)?this.icon.minusBottom:this.icon.minus):((bottom)?this.icon.plusBottom:this.icon.plus)):
+  ((status)?this.icon.nlMinus:this.icon.nlPlus);
+  eDiv.style.display = (status) ? 'block': 'none';
+};
+
+
+// [Cookie] Clears a cookie
+dTree.prototype.clearCookie = function() {
+  var now = new Date();
+  var yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);
+  this.setCookie('co'+this.obj, 'cookieValue', yesterday);
+  this.setCookie('cs'+this.obj, 'cookieValue', yesterday);
+};
+
+// [Cookie] Sets value in a cookie
+dTree.prototype.setCookie = function(cookieName, cookieValue, expires, path, domain, secure) {
+  document.cookie =
+  escape(cookieName) + '=' + escape(cookieValue)
+  + (expires ? '; expires=' + expires.toGMTString() : '')
+  + (path ? '; path=' + path : '')
+  + (domain ? '; domain=' + domain : '')
+  + (secure ? '; secure' : '');
+};
+
+// [Cookie] Gets a value from a cookie
+dTree.prototype.getCookie = function(cookieName) {
+  var cookieValue = '';
+  var posName = document.cookie.indexOf(escape(cookieName) + '=');
+  if (posName != -1) {
+    var posValue = posName + (escape(cookieName) + '=').length;
+    var endPos = document.cookie.indexOf(';', posValue);
+    if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos));
+    else cookieValue = unescape(document.cookie.substring(posValue));
+  }
+  return (cookieValue);
+};
+
+// [Cookie] Returns ids of open nodes as a string
+dTree.prototype.updateCookie = function() {
+  var str = '';
+  for (var n=0; n<this.aNodes.length; n++) {
+    if (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id) {
+      if (str) str += '.';
+      str += this.aNodes[n].id;
+    }
+  }
+  this.setCookie('co' + this.obj, str);
+};
+
+// [Cookie] Checks if a node id is in a cookie
+dTree.prototype.isOpen = function(id) {
+  var aOpen = this.getCookie('co' + this.obj).split('.');
+  for (var n=0; n<aOpen.length; n++)
+  if (aOpen[n] == id) return true;
+  return false;
+};
+
+// If Push and pop is not implemented by the browser
+if (!Array.prototype.push) {
+  Array.prototype.push = function array_push() {
+    for(var i=0;i<arguments.length;i++)
+    this[this.length]=arguments[i];
+    return this.length;
+  }
+};
+
+if (!Array.prototype.pop) {
+  Array.prototype.pop = function array_pop() {
+    lastElement = this[this.length-1];
+    this.length = Math.max(this.length-1,0);
+    return lastElement;
+  }
+};
+
diff --git a/UI/WebServerResources/edit.png b/UI/WebServerResources/edit.png
new file mode 100644 (file)
index 0000000..45f7544
Binary files /dev/null and b/UI/WebServerResources/edit.png differ
diff --git a/UI/WebServerResources/empty.gif b/UI/WebServerResources/empty.gif
new file mode 100644 (file)
index 0000000..b5cf523
Binary files /dev/null and b/UI/WebServerResources/empty.gif differ
diff --git a/UI/WebServerResources/generic.css b/UI/WebServerResources/generic.css
new file mode 100644 (file)
index 0000000..1e8bb44
--- /dev/null
@@ -0,0 +1,792 @@
+/* SOGo UI Stylesheet */
+
+/* common stuff */
+
+/* Bitstream VeraSans, , Tahoma, FreeSans, Helvetica, sans-serif */
+BODY
+{ position: absolute;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  color: #000000;
+  font-family: Bitstream VeraSans, Tahoma;
+  font-size: 10pt;
+  background-color: #dbdad5;
+  border: 0px;
+  margin: 0px;
+  padding: 0px;
+  overflow: hidden; }
+
+HR
+{ height: 0px; }
+
+TABLE, DIV, IMG
+{ font-family: inherit;
+  font-size: inherit;
+  border: 0px;
+  margin: 0px;
+  padding: 0px; }
+
+IMG#progressIndicator
+{ float: right;
+  margin-top: 1.5em;
+  margin-right: 1em; }
+
+DIV.pageContent
+{ /* position: absolute;
+  background: #ffa;
+  top: 3em;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  margin: 0px;
+  padding: 0px;
+  border: 0px;
+   */clear: both; }
+
+A
+{ text-decoration: none;
+  -moz-outline: 0px; }
+
+LABEL
+{ white-space: nowrap;
+  margin-left: .5em; }
+
+TABLE
+{ display: block;
+  table-layout: fixed;
+  border-spacing: 0px;
+  padding: 0px;
+  margin: 0px;
+  border: 0px; }
+
+a:link
+{ color: #0033CC; }
+
+a:visited
+{ color: #660066; }
+
+a:hover
+{ color: #FF0000;
+  text-decoration: underline; }
+
+.linecolor
+{ background-color: #06348B; }
+
+.defaultfont
+{ text-decoration: none;
+  color: #000000; }
+
+.window_label
+{ color: #06348b;
+  font-weight: bold; }
+
+.homepagefont
+{ text-decoration: none;
+  color: #000000; }
+
+
+/* tabs */
+
+.oldtab
+{ color: #000000;
+  background-color: #e8e8e0;
+  text-decoration: none;
+  width: 100px; 
+  height: 22px;
+  border-top: 1px solid #06348b;
+  border-right: 1px solid #06348b; }
+
+.oldtab a
+{ color: #000000;
+  border: none;
+  text-decoration: none; }
+
+.oldtab_selected
+{ color: #000000;
+  background-color: #f5f5e9;
+  text-decoration: none;
+  font-weight: bold;
+  width: 100px; 
+  height: 22px;
+  border-top: 1px solid #06348b;
+  border-right: 1px solid #06348b; }
+
+.oldtab_selected a
+{ color: #000000;
+  border: none;
+  text-decoration: none; }
+
+.oldtabview_body
+{ background-color: #f5f5e9; }
+
+
+/* buttons */
+
+.button_auto_env
+{ height: 16px;
+  text-align: center;
+  vertical-align: middle;
+  padding: 0px 0px 0px 0px;
+  margin: 0px 0px 0px 0px;
+  overflow: hidden; }
+
+.button_auto_env a
+{ text-decoration: none;
+  color: #000000; }
+
+.button_auto_env a:hover
+{ text-decoration: underline;
+  color: #ff0000; }
+
+.button_auto
+{ height: 20px;
+  border-style: outset;
+  border-color: #DDDDDD;
+  border-width: 2px;
+  color: #000000;
+  background-color: #e8e8e0;
+  letter-spacing: 0pt;
+  text-decoration: none;
+  color: #000000;
+  text-align: center;
+  vertical-align: middle;
+  padding-left: 5px;
+  padding-right: 5px;
+  padding-top: 1px;
+  padding-bottom: 1px;
+  overflow: hidden; }
+
+.button_submit_env
+{ height: 24px;
+  text-align: center;
+  vertical-align: middle;
+  padding: 0px 0px 0px 0px;
+  margin: 0px 0px 0px 0px;
+  overflow: hidden; }
+
+.button_submit_env a
+{ text-decoration: none;
+  color: #000000; }
+
+.button_submit_env a:hover
+{ text-decoration: underline;
+  color: #ff0000; }
+
+.button_submit
+{ height: 30px;
+  border-style: outset;
+  border-color: #DDDDDD;
+  border-width: 2px;
+  color: #000000;
+  background-color: #e8e8e0;
+  letter-spacing: 0pt;
+  text-decoration: none;
+  color: #000000;
+  text-align: center;
+  vertical-align: middle;
+  padding-left: 5px;
+  padding-right: 5px;
+  padding-top: 2px;
+  padding-bottom: 3px;
+  overflow: hidden; }
+
+/* header */
+
+div#header
+{ margin-left: 5px;
+  margin-right: 5px;
+  padding: 0;
+  border-bottom: 1px solid #000000; }
+
+div#header img.headerlogo
+{ float: right; 
+  width: 182px; 
+  height: 30px; }
+
+div#header div#headerhistory
+{ color: #000000;
+  margin: 0px;
+  padding-top: 18px;
+  height: 12px; }
+
+div#header a, div#header span
+{ margin: 0px; }
+
+div#header span#navtitle
+{ font-weight: bold; }
+
+div#header a:hover
+{ text-decoration: none; }
+
+/* the dock */
+
+a.skydockfont
+{ text-decoration: none;
+  color: #06348B; }
+font.skydockfont
+{ text-decoration: none;
+  color: #06348B; }
+font.skydockfont_inactiveMail
+{ text-decoration: none;
+  color: #CCCCCC;
+  font-weight: bold; }
+font.skydockfont_newMail
+{ text-decoration: none;
+  color: #06348B;
+  font-weight: bold; }
+
+table.skytextdocktable
+{ padding: 0px;
+  table-layout: auto; }
+
+
+DIV.linkbanner
+{ 
+  background: #222;
+  width: 100%;
+  top: 0px;
+  left: 0px;
+  z-index: 100;
+  color: #aaa; }
+
+DIV.linkbanner A
+{ 
+  top: 0px;
+  left: 0px;
+  color: #ddd;
+  text-decoration: none;
+  padding: .2em .5em; }
+
+DIV.linkbanner A:hover
+{ color: #dd5; }
+
+
+.linkbannerlinks
+{ vertical-align: bottom;
+  text-align: left; }
+
+.linkbannerimage { 
+  text-align: right; }
+
+DIV.contactSelector
+{ margin: .5em; }
+
+DIV.contactSelector UL.contactList IMG
+{ margin: 0px .5em; }
+
+SELECT
+{ border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  vertical-align: middle;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  margin: 2px;
+  padding-right: 1px; }
+
+DIV.contactSelector DIV.contactList
+{ font-size: smaller;
+  white-space: nowrap;
+  width: 40em;
+  height: 3em;
+  overflow: auto;
+  border: 1px solid #444;
+  background: #eee;
+  text-align: left; }
+
+TEXTAREA
+{ vertical-align: top; }
+
+DIV, TEXTAREA, INPUT
+{ font-family: inherit;
+  font-size: inherit; }
+
+TEXTAREA, INPUT.textField
+{ padding: .2em;
+  margin: .15em;
+  border-bottom: 1px solid #fff;
+  border-right: 1px solid #fff;
+  border-top: 2px solid #222;
+  border-left: 2px solid #222;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent; }
+
+INPUT.textField
+{ line-height: 2em;
+  vertical-align: middle; }
+
+INPUT.button
+{ margin: 0px;
+  padding: 0px .5em;
+  border-top: 2px solid #fffffb;
+  border-left: 2px solid #fffffb;
+  border-bottom: 2px solid #888;
+  border-right: 2px solid #888;
+  background-color: #dbdad5;
+  -moz-border-top-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-left-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent; }
+
+INPUT.button:hover
+{ color: inherit;
+  background: -moz-buttonhoverface; }
+
+INPUT.button:active
+{ -moz-outline: none;
+  margin: 0px;
+  padding: 0px .5em;
+  color: -moz-buttonhovertext;
+  -moz-border-bottom-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-right-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow; }
+
+DIV#toolbar
+{ left: 0px;
+  border-top: 1px solid #fffffb;
+  border-left: 1px solid #fffffb;
+  border-bottom: 2px solid #888;
+  border-right: 2px solid #888;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  margin: 0px;
+  padding: 0px;
+/*   background: #f00;
+ */  height: 4em;
+  background-color: #dbdad5;
+  white-space: nowrap;
+  overflow: auto; }
+
+SPAN.toolbarSeparator
+{ display: block;
+  float: left;
+  height: 90%;
+  vertical-align: middle;
+  border-right : 1px solid ThreeDHighlight;
+  border-left : 1px solid ThreeDShadow;
+  margin: 0px .25em;
+  margin-top: 0.125em;
+  width: 0px;
+  padding: 0px; }
+
+A.toolbarButton
+{ color: #000;
+  text-decoration: none; }
+
+SPAN.toolbarButton, SPAN.disabledToolbarButton
+{ cursor: default;
+  display: block;
+  float: left;
+  height: 80%;
+  text-align: center;
+  -moz-box-align: center;
+  -moz-box-pack: center;
+  margin: 0px;
+  margin-top: 0.125em;
+  border-left: 2px solid transparent;
+  border-top: 2px solid transparent;
+  border-right: 2px solid transparent;
+  border-bottom: 2px solid transparent;
+  padding: 1px 2px;
+  background-color: transparent;
+  color: -moz-DialogText; }
+
+SPAN.disabledToolbarButton
+{ -moz-opacity: 0.4; }
+
+SPAN.toolbarButton:hover
+{ color: -moz-buttonhovertext;
+  background-color: -moz-buttonhoverface;
+  -moz-border-left-colors: ThreeDHighlight -moz-buttonhoverface;
+  -moz-border-top-colors: ThreeDHighlight -moz-buttonhoverface;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow; }
+
+SPAN.toolbarButton:active
+{ color: -moz-buttonhovertext;
+  background-color: #c4c2bd;
+  -moz-border-bottom-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-right-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow; }
+
+.toolbarButton IMG.buttonImage
+{ border: 0px;
+  width: 24px;
+  height: 24px;
+  margin: auto; }
+
+.toolbarButton .buttonLabel
+{ width: 100%;
+  margin: auto; }
+
+/* popups */
+.menu
+{ visibility: hidden;
+  position: absolute;
+  z-index: 1000;
+  background-color: #dcdad5;
+  color: #000;
+  margin: 0px;
+  padding: 0px;
+  border: 1px solid #000; }
+
+.menu UL
+{ 
+  cursor: default;
+  list-style-type: none;
+  list-style-image: none;
+  margin: 0px;
+  padding: 0px;
+  border-top: 1px solid #fff;
+  border-left: 1px solid #fff;
+  border-right: 1px solid #9e9a92;
+  border-bottom: 1px solid #9e9a92; }
+
+.menu LI
+{ padding-left: 1em;
+  padding-right: 1em;
+  padding-top: .2em;
+  padding-bottom: .2em;
+  margin: 0px;
+  width: auto;
+  white-space: nowrap; }
+
+.menu LI IMG
+{ margin-left: -.8em;
+  padding-right: .2em;
+  vertical-align: middle; }
+
+.menu LI:hover, .menu LI.submenu-selected
+{ background: #4b6983;
+  color: #fff; }
+
+.menu LI.separator, .menu LI.separator:hover
+{ padding: 0px;
+  margin: 2px 0px;
+  height: 0px;
+  border-top: 1px solid #aaa;
+  border-bottom: 1px solid #fff; }
+
+.menu LI.submenu, .menu LI.submenu-selected
+{ padding-right: 2em;
+  background-position: 98% 50%;
+  background-repeat: no-repeat; }
+
+.menu LI.submenu
+{ background-image: url('submenu.gif'); }
+
+.menu LI.submenu:hover, .menu LI.submenu-selected
+{ background-image: url('submenu-active.gif') !important; }
+
+DIV#logConsole
+{ position: absolute;
+  overflow: auto;
+  display: none;
+  z-index: 1000;
+  -moz-opacity: 0.7;
+  border-top: 2px solid #fffffb;
+  border-left: 2px solid #fffffb;
+  border-right: 2px solid #999;
+  border-bottom: 2px solid #999;
+  -moz-border-top-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-left-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  font-family: monospace;
+  font-weight: bold;
+  background: #000;
+  color: #ddd;
+  top: 1em;
+  left: 0px;
+  right: 0px;
+  height: 15em; }
+
+/* content lists */
+td.tbtv_actcell
+{ border-width: 1px;
+  border-style: solid;
+  border-top-color: #808080;
+  border-left-color: #808080;
+  border-bottom-color: #808080;
+  border-right-color: #808080;
+  padding-top: 4px;
+  padding-bottom: 3px;
+  padding-left: 4px;
+  padding-right: 4px;
+  
+  background-color: #DCDAD5; }
+
+td.tbtv_headercell SPAN
+{ float: left;
+  width: 100%; }
+
+td.tbtv_headercell a
+{ cursor: default;
+  margin: 0px auto;
+  display: block;
+  color: black;
+  width: 100%; }
+
+td.tbtv_headercell a:hover
+{ margin: 0px auto;
+  display: block;
+  color: black;
+  text-decoration: none;
+  /* background-color: #C4C0B8; */
+}
+
+td.tbtv_headercell img.tbtv_sortcell
+{ float: right;
+  text-align: right;
+  border: 0px;
+  width: 12px;
+  height: 12px; }
+
+.tableview
+{ cursor: default;
+  vertical-align: top; }
+
+TR.tableview TD
+{ white-space: nowrap;
+  padding-left: .3em;
+  padding-right: .3em; }
+
+TR.tableview TD.headerDateTime
+{ width: 14em; }
+
+TR.tableview TD.headerLocation
+{ width: 10em; }
+
+td.tbtv_actcell
+{ border-width: 1px;
+  border-style: solid;
+  border-top-color: #808080;
+  border-left-color: #808080;
+  border-bottom-color: #808080;
+  border-right-color: #808080;
+  padding-top: 4px;
+  padding-bottom: 3px;
+  padding-left: 4px;
+  padding-right: 4px;
+  background-color: #DCDAD5; }
+
+TD.tbtv_headercell,
+TD.tbtv_navcell
+{ background-color: #DCDAD5;
+  border-top: 1px solid #fff;
+  border-left: 1px solid #fff;
+  border-right: 2px solid #222;
+  border-bottom: 2px solid #222;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent; }
+
+TD.tbtv_headercell:active
+{ background-color: #DCDAD5;
+  border: 1px solid #9c9a94;
+  -moz-border-bottom-colors: #9c9a94;
+  -moz-border-right-colors: #9c9a94; }
+
+td.tbtv_headercell SPAN
+{ float: left;
+  width: 100%; }
+
+td.tbtv_headercell a
+{ cursor: default;
+  margin: 0px auto;
+  color: black;
+  width: 100%; }
+
+td.tbtv_headercell a:hover
+{ margin: 0px auto;
+  display: block;
+  color: black;
+  text-decoration: none;
+  /* background-color: #C4C0B8; */
+}
+
+td img.tbtv_sortcell
+{ float: right;
+  text-align: right;
+  margin-top: .2em;
+  border: 0px;
+  width: 12px;
+  height: 12px; }
+
+TD.subjectCell,
+td.tbtv_subject_headercell
+{ overflow: hidden;
+  width: auto; }
+
+/* drag handles */
+DIV.dragHandle
+{ position: absolute;
+  z-index: 1;
+  background: #dbdad5; }
+
+DIV.dragHandle:active
+{ background: #99a; }
+
+/* search fields */
+DIV#filterPanel
+{
+  height: 2em;
+  vertical-align: middle;
+  width: 100%;
+}
+
+INPUT#searchValue
+{ margin-right: 1em;
+  width: 20em;
+  padding-left: 24px;
+  background-image: url('/SOGo.woa/WebServerResources/Search-bar.png');
+  background-repeat: no-repeat;
+  background-position: 2px 2px;
+  color: #aaa; }
+
+DIV#noJavascriptError
+{ position: absolute;
+  background: #999;
+  -moz-opacity: 0.6; 
+  z-index: 2;
+  top: 0px;
+  left: 0px;
+  right: 0px;
+  bottom: 0px;
+  text-align: center; }
+
+DIV.noJavascriptErrorMessage
+{ position: absolute;
+  z-index: 2;
+  border-top: 2px solid #fffffb;
+  border-left: 2px solid #fffffb;
+  border-bottom: 2px solid #888;
+  border-right: 2px solid #888;
+  -moz-border-top-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-left-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  padding: 1em;
+  top: 10em;
+  left: 17em;
+  width: 24em;
+  margin: 0px auto;
+  background: #fff;
+  -moz-opacity: 1.0;
+  color: #000;
+  background: #dedede; }
+
+DIV.noJavascriptErrorMessage A
+{ float: right;
+  margin: 0px auto; }
+
+A.button:hover
+{ color: inherit;
+  background: -moz-buttonhoverface; }
+
+A.button:active
+{ color: -moz-buttonhovertext;
+  background-color: #c4c2bd;
+  -moz-border-bottom-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-right-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+  -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow; }
+
+A.button,
+A[class~="_disabled"].button:hover,
+A[class~="_disabled"].button:active
+{ cursor: default;
+  padding: 1px .5em;
+  border-top: 2px solid #fffffb;
+  border-left: 2px solid #fffffb;
+  border-bottom: 2px solid #888;
+  border-right: 2px solid #888;
+  -moz-border-top-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-left-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  text-decoration: none;
+  color: inherit; }
+
+A.button IMG
+{ vertical-align: middle; }
+
+A[class~="_disabled"].button,
+A[class~="_disabled"].button:hover,
+A[class~="_disabled"].button:active
+{ color: #999;
+  background: inherit; }
+
+/* tabs */
+DIV.tabsContainer
+{ 
+  position: relative;
+  color: #000;
+  background: #dbdad5;
+  margin-top: 1.5em;
+  border-top: 2px solid #fffffb;
+  border-left: 2px solid #fffffb;
+  border-right: 2px solid #888;
+  border-bottom: 2px solid #888;
+  -moz-border-top-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-left-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow transparent; }
+
+DIV.tabsContainer > UL
+{ cursor: default;
+  list-style-type: none;
+  list-style-image: none;
+  margin: 0px;
+  margin-top: -1.5em;
+  padding: 0px; }
+
+DIV.tabsContainer > UL LI
+{ z-index: 3;
+  float: left;
+  padding: 0px .5em;
+  padding-top: 2px;
+  border-top: 2px solid #fffffb;
+  border-bottom: 0px solid #fffffb;
+  border-right: 2px solid #888;
+  -moz-border-top-colors: -moz-buttonhoverface ThreeDHighlight;
+  -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow transparent;
+  -moz-border-bottom-colors: -moz-buttonhoverface ThreeDHighlight;
+  color: #000;
+  background: #fff;
+  background: #c4c2bd; }
+
+DIV.tabsContainer > UL LI.first,
+DIV.tabsContainer > UL LI.active
+{ border-left: 2px solid #fffffb;
+  margin-left: -2px;
+  -moz-border-left-colors: -moz-buttonhoverface ThreeDHighlight; }
+
+DIV.tabsContainer > UL LI.active
+{ z-index: 5;
+  background: #dbdad5;
+  padding-top: 2px;
+  padding-bottom: 2px;
+  margin-top: -2px; }
+
+DIV.tabsContainer > DIV.tab
+{ position: absolute;
+  overflow: auto;
+  top: .5em;
+  left: .5em;
+  right: .5em;
+  bottom: .5em;
+  display: none; }
+
+DIV.tabsContainer > DIV[class~="active"].tab
+{ display: block !important; }
+
+INPUT.checkBox
+{ border: 2px solid #000;
+  vertical-align: middle;
+  -moz-border-top-colors: #000 #fff;
+  -moz-border-left-colors: #000 #fff; 
+  -moz-border-bottom-colors: #000 #fff;
+  -moz-border-right-colors: #000 #fff; }
index 2c2b0a0ed84e1c1df6788276ec9abab0e368ec46..25e8a488179c23b7eab9f26cddd91b1743169ee4 100644 (file)
 
 /* generic stuff */
 
+var logConsole;
+var logWindow = null;
+
+var queryParameters;
+
+var activeAjaxRequests = 0;
+
+// logArea = null;
+var allDocumentElements = null;
+
+/* a W3C compliant document.all */
+function getAllScopeElements(scope)
+{
+  var elements = new Array();
+
+  for (var i = 0; i < scope.childNodes.length; i++)
+    if (typeof(scope.childNodes[i]) == "object"
+       && scope.childNodes[i].tagName
+       && scope.childNodes[i].tagName != '')
+      {
+       elements.push(scope.childNodes[i]);
+       var childElements = getAllElements(scope.childNodes[i]);
+       if (childElements.length > 0)
+         elements.push(childElements);
+      }
+
+  return elements;
+}
+
+function getAllElements(scope)
+{
+  var elements;
+
+  if (scope == null)
+    scope = document;
+
+  if (scope == document
+      && allDocumentElements != null)
+    elements = allDocumentElements;
+  else
+    {
+      elements = getAllScopeElements(scope);
+      if (scope == document)
+       allDocumentElements = elements;
+    }
+
+  return elements;
+}
+
+/* from
+   http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ */
+function getElementsByClassName2(_tag, _class, _scope) {
+  var regexp, classes, elements, element, returnElements;
+
+  _scope = _scope || document;
+
+  elements = (!_tag || _tag == "*"
+             ? getAllElements(null)
+             : _scope.getElementsByTagName(_tag));
+  returnElements = [];
+
+  classes = _class.split(/\s+/);
+  regexp = new RegExp("(^|\s+)("+ classes.join("|") +")(\s+|$)","i");
+
+  if (_class) {
+    for(var i = 0; element = elements[i]; i++) {
+      if (regexp.test(element.className)) {
+       returnElements.push(element);
+      }
+    }
+    return returnElements;
+  } else {
+    return elements;
+  }
+}
+
 function ml_stripActionInURL(url) {
   if (url[url.length - 1] != '/') {
     var i;
@@ -36,29 +112,60 @@ function ml_stripActionInURL(url) {
   return url;
 }
 
-/* emails */
+function extractEmailAddress(mailTo) {
+  var email = "";
 
-var uixEmailUsr = 
-  "([a-zA-Z0-9][a-zA-Z0-9_.-]*|\"([^\\\\\x80-\xff\015\012\"]|\\\\[^\x80-\xff])+\")";
-var uixEmailDomain = 
-  "([a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*[a-zA-Z0-9][a-zA-Z0-9._-]*\\.[a-zA-Z]{2,5}";
-var uixEmailRegex = new RegExp("^"+uixEmailUsr+"\@"+uixEmailDomain+"$");
+  var emailre
+    = /([a-zA-Z0-9]+[a-zA-Z0-9\._-]+[a-zA-Z0-9]+@[a-zA-Z0-9]+[a-zA-Z0-9\._-]+[a-zA-Z0-9]+)/g;
+  if (emailre.test(mailTo)) {
+    emailre.exec(mailTo);
+    email = RegExp.$1;
+  }
 
-/* escaping */
+  return email;
+}
 
-function escapeHTML(s) {
-        s = s.replace(/&/g, "&amp;");
-        s = s.replace(/</g, "&lt;");
-        s = s.replace(/>/g, "&gt;");
-        s = s.replace(/"/g, "&quot;");
-        return s;
+function extractEmailName(mailTo) {
+  var emailName = "";
+
+  var emailNamere = /(\w[\w\ _-]+)\ (&lt;|<)/;
+  if (emailNamere.test(mailTo)) {
+    emailNamere.exec(mailTo);
+    emailName = RegExp.$1;
+  }
 }
-function unescapeHTML(s) {
-        s = s.replace(/&lt;/g, "<");
-        s = s.replace(/&gt;/g, ">");
-        s = s.replace(/&quot;/g, '"');
-        s = s.replace(/&amp;/g, "&");
-        return s;
+
+function sanitizeMailTo(dirtyMailTo) {
+  var emailName = extractEmailName(dirtyMailTo);
+  var email = "" + extractEmailAddress(dirtyMailTo);
+
+  var mailto = "";
+  if (emailName && emailName.length > 0)
+    mailto = emailName + ' <' + email + '>';
+  else
+    mailto = email;
+
+  return mailto;
+}
+
+function openMailComposeWindow(url) {
+  var w = window.open(url, null,
+                      "width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
+                      + "location=0,directories=0,status=0,menubar=0"
+                      + ",copyhistory=0");
+  w.focus();
+
+  return w;
+}
+
+function openMailTo(senderMailto) {
+  var mailto = sanitizeMailTo(senderMailto);
+
+  if (mailto.length > 0)
+    openMailComposeWindow(ApplicationBaseURL
+                          + "/../Mail/compose?mailto=" + mailto);
+
+  return false; /* stop following the link */
 }
 
 function createHTTPClient() {
@@ -70,9 +177,67 @@ function createHTTPClient() {
   catch (e) { }
   try { return new ActiveXObject("Microsoft.XMLHTTP"); } 
   catch (e) { }
+
   return null;
 }
 
+function triggerAjaxRequest(url, callback, userdata) {
+  var http = createHTTPClient();
+
+  activeAjaxRequests += 1;
+  document.animTimer = setTimeout("checkAjaxRequestsState();", 200);
+
+  if (http) {
+    http.onreadystatechange
+      = function() {
+//         log ("state changed (" + http.readyState + "): " + url);
+        try {
+          if (http.readyState == 4
+              && activeAjaxRequests > 0) {
+                if (!http.aborted) {
+                  http.callbackData = userdata;
+                  callback(http);
+                }
+                activeAjaxRequests -= 1;
+                checkAjaxRequestsState();
+              }
+        }
+        catch( e ) {
+          activeAjaxRequests -= 1;
+          checkAjaxRequestsState();
+          log("AJAX Request, Caught Exception: " + e.name);
+          log(e.message);
+        }
+      };
+    http.url = url;
+    http.open("GET", url, true);
+    http.send("");
+  }
+
+  return http;
+}
+
+function checkAjaxRequestsState() {
+  var toolbar = document.getElementById("toolbar");
+  if (toolbar) {
+    if (activeAjaxRequests > 0
+        && !document.busyAnim) {
+      var anim = document.createElement("img");
+      document.busyAnim = anim;
+      anim.id = "progressIndicator";
+      anim.src = ResourcesURL + "/busy.gif";
+      anim.style.visibility = "hidden;";
+      toolbar.appendChild(anim);
+      anim.style.visibility = "visible;";
+    }
+    else if (activeAjaxRequests == 0
+            && document.busyAnim) {
+      document.busyAnim.parentNode.removeChild(document.busyAnim);
+      document.busyAnim = null;
+    }
+  }
+}
+
 function resetSelection(win) {
   var t = "";
   if (win && win.getSelection) {
@@ -134,6 +299,7 @@ function getQueryParaArray(s) {
   if (s.charAt(0) == "?") s = s.substr(1, s.length - 1);
   return s.split("&");
 }
+
 function getQueryParaValue(s, name) {
   var t;
   
@@ -166,3 +332,691 @@ function triggerOpenerCallback() {
     window.opener.location.href = cburl;
   }
 }
+
+/* selection mechanism */
+
+function deselectAll(parent) {
+  for (var i = 0; i < parent.childNodes.length; i++) {
+    var node = parent.childNodes.item(i);
+    if (node.nodeType == 1)
+      node.deselect();
+  }
+}
+
+function isNodeSelected(node) {
+  var classStr = '' + node.getAttribute('class');
+  var position = classStr.indexOf('_selected', 0);
+
+  return (position > -1);
+}
+
+function acceptMultiSelect(node) {
+  var accept = ('' + node.getAttribute('multiselect')).toLowerCase();
+
+  return (accept == 'yes');
+}
+
+function onRowClick(event) {
+  var node = event.target;
+
+  if (node.tagName == 'TD')
+    node = node.parentNode;
+
+  var startSelection = node.parentNode.getSelectedNodes();
+  if (event.shiftKey == 1
+      && (acceptMultiSelect(node.parentNode)
+         || acceptMultiSelect(node.parentNode.parentNode))) {
+    if (isNodeSelected(node) == true) {
+      node.deselect();
+    } else {
+      node.select();
+    }
+  } else {
+    deselectAll(node.parentNode);
+    node.select();
+  }
+
+  if (startSelection != node.parentNode.getSelectedNodes()) {
+    var parentNode = node.parentNode;
+    if (parentNode instanceof HTMLTableSectionElement)
+      parentNode = parentNode.parentNode;
+    var onSelectionChangeEvent = document.createEvent("Event");
+    onSelectionChangeEvent.initEvent("selectionchange", true, true);
+    parentNode.dispatchEvent(onSelectionChangeEvent);
+  }
+}
+
+/* popup menus */
+
+var bodyOnClick = "";
+// var acceptClick = false;
+
+function onMenuClick(event, menuId)
+{
+  var node = event.target;
+
+  if (document.currentPopupMenu)
+    hideMenu(event, document.currentPopupMenu);
+
+  var popup = document.getElementById(menuId);
+
+  var menuTop = event.pageY;
+  var menuLeft = event.pageX;
+  var heightDiff = (window.innerHeight
+                   - (menuTop + popup.offsetHeight));
+  if (heightDiff < 0)
+    menuTop += heightDiff;
+
+  var leftDiff = (window.innerWidth
+                 - (menuLeft + popup.offsetWidth));
+  if (leftDiff < 0)
+    menuLeft -= popup.offsetWidth;
+
+  popup.style.top = menuTop + "px;";
+  popup.style.left = menuLeft + "px;";
+  popup.style.visibility = "visible;";
+  setupMenuTarget(popup, node);
+
+  bodyOnClick = "" + document.body.getAttribute("onclick");
+  document.body.setAttribute("onclick", "onBodyClick(event);");
+  document.currentPopupMenu = popup;
+
+  event.cancelBubble = true;
+  event.returnValue = false;
+
+  return false;
+}
+
+function setupMenuTarget(menu, target)
+{
+  menu.menuTarget = target;
+  var menus = document.getElementsByClassName("menu", menu);
+  for (var i = 0; i < menus.length; i++) {
+    menus[i].menuTarget = target;
+  }
+}
+
+function getParentMenu(node)
+{
+  var currentNode, menuNode;
+
+  menuNode = null;
+  currentNode = node;
+  var menure = new RegExp("(^|\s+)menu(\s+|$)", "i");
+
+  while (menuNode == null
+        && currentNode)
+    if (menure.test(currentNode.className))
+      menuNode = currentNode;
+    else
+      currentNode = currentNode.parentNode;
+
+  return menuNode;
+}
+
+function onBodyClick(event)
+{
+  document.currentPopupMenu.menuTarget = null;
+  hideMenu(event, document.currentPopupMenu);
+  document.body.setAttribute("onclick", bodyOnClick);
+
+  return false;
+}
+
+function hideMenu(event, menuNode)
+{
+  var onHide;
+
+//   log('hiding menu "' + menuNode.getAttribute('id') + '"');
+  if (menuNode.submenu)
+    {
+      hideMenu(event, menuNode.submenu);
+      menuNode.submenu = null;
+    }
+
+  menuNode.style.visibility = "hidden";
+  if (menuNode.parentMenuItem)
+    {
+      menuNode.parentMenuItem.setAttribute('class', 'submenu');
+      menuNode.parentMenuItem = null;
+      menuNode.parentMenu.setAttribute('onmousemove', null);
+      menuNode.parentMenu.submenuItem = null;
+      menuNode.parentMenu.submenu = null;
+      menuNode.parentMenu = null;
+    }
+
+  var onhideEvent = document.createEvent("Event");
+  onhideEvent.initEvent("hideMenu", false, true);
+  menuNode.dispatchEvent(onhideEvent);
+}
+
+function onMenuEntryClick(event, menuId)
+{
+  var node = event.target;
+
+  id = getParentMenu(node).menuTarget;
+//   log("clicked " + id + "/" + id.tagName);
+
+  return false;
+}
+
+function parseQueryParameters(url) {
+  var parameters = new Array();
+
+  var params = url.split("?")[1];
+  if (params) {
+    var pairs = params.split("&");
+    for (var i = 0; i < pairs.length; i++) {
+      var pair = pairs[i].split("=");
+      parameters[pair[0]] = pair[1];
+    }
+  }
+
+  return parameters;
+}
+
+function initLogConsole() {
+  var logConsole = $("logConsole");
+  if (logConsole) {
+    logConsole.addEventListener("dblclick", onLogDblClick, false);
+    logConsole.innerHTML = "";
+    node = document.getElementsByTagName('body')[0];
+    node.addEventListener("keydown", onBodyKeyDown, true);
+  }
+}
+
+function onBodyKeyDown(event)
+{
+  if (event.keyCode == 27) {
+    toggleLogConsole();
+    event.cancelBubble = true;
+    event.returnValue = false;
+  }
+}
+
+function onLogDblClick(event)
+{
+  var logConsole = $("logConsole");
+  logConsole.innerHTML = "";
+}
+
+function toggleLogConsole(event) {
+  var logConsole = $("logConsole");
+  var display = '' + logConsole.style.display;
+  if (display.length == 0) {
+    logConsole.style.display = 'block;';
+  } else {
+    logConsole.style.display = '';
+  }
+  event.cancelBubble = true;
+  event.returnValue = false;
+  event.preventDefault();
+}
+
+function log(message) {
+  if (!logWindow) {
+    logWindow = window;
+    while (logWindow.opener)
+      logWindow = logWindow.opener;
+  }
+  var logConsole = logWindow.document.getElementById('logConsole');
+  if (logConsole)
+    logConsole.innerHTML += message + '<br />' + "\n";
+}
+
+function dropDownSubmenu(event)
+{
+  var node = event.target;
+  var submenu = node.getAttribute("submenu");
+  if (submenu && submenu != "")
+    {
+      var submenuNode = document.getElementById(submenu);
+      var parentNode = getParentMenu(node);
+      if (parentNode.submenu)
+       hideMenu(event, parentNode.submenu);
+      submenuNode.parentMenuItem = node;
+      submenuNode.parentMenu = parentNode;
+      parentNode.submenuItem = node;
+      parentNode.submenu = submenuNode;
+
+      var menuTop = (node.offsetTop - 2);
+      
+      var heightDiff = (window.innerHeight
+                       - (menuTop + submenuNode.offsetHeight));
+      if (heightDiff < 0)
+       menuTop += heightDiff;
+
+      var menuLeft = parentNode.offsetWidth - 3;
+      if (window.innerWidth
+          < (menuLeft + submenuNode.offsetWidth
+             + parentNode.cascadeLeftOffset()))
+       menuLeft = -submenuNode.offsetWidth + 3;
+
+      parentNode.setAttribute('onmousemove', 'checkDropDown(event);');
+      node.setAttribute('class', 'submenu-selected');
+      submenuNode.style.top = menuTop + "px;";
+      submenuNode.style.left = menuLeft + "px;";
+      submenuNode.style.visibility = "visible;";
+    }
+}
+
+function checkDropDown(event)
+{
+  var parentMenu = getParentMenu(event.target);
+  var submenuItem = parentMenu.submenuItem;
+  if (submenuItem)
+    {
+      var menuX = event.clientX - parentMenu.cascadeLeftOffset();
+      var menuY = event.clientY - parentMenu.cascadeTopOffset();
+      var itemX = submenuItem.offsetLeft;
+      var itemY = submenuItem.offsetTop - 75;
+
+      if (menuX >= itemX
+          && menuX < itemX + submenuItem.offsetWidth
+          && (menuY < itemY
+              || menuY > (itemY + submenuItem.offsetHeight)))
+       {
+         hideMenu(event, parentMenu.submenu);
+         parentMenu.submenu = null;
+         parentMenu.submenuItem = null;
+         parentMenu.setAttribute('onmousemove', null);
+       }
+    }
+}
+
+/* search field */
+function popupSearchMenu(event, menuId)
+{
+  var node = event.target;
+  relX = event.pageX - node.cascadeLeftOffset();
+  relY = event.pageY - node.cascadeTopOffset();
+
+  if (event.button == 0
+      && relX < 24) {
+    event.cancelBubble = true;
+    event.returnValue = false;
+
+    if (document.currentPopupMenu)
+      hideMenu(event, document.currentPopupMenu);
+
+    var popup = document.getElementById(menuId);
+    popup.style.top = node.offsetHeight + "px";
+    popup.style.left = (node.offsetLeft + 3) + "px";
+    popup.style.visibility = "visible";
+  
+    bodyOnClick = "" + document.body.getAttribute("onclick");
+    document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');");
+    document.currentPopupMenu = popup;
+  }
+}
+
+function setSearchCriteria(event)
+{
+  searchValue = document.getElementById('searchValue');
+  searchCriteria = document.getElementById('searchCriteria');
+  
+  var node = event.target;
+  searchValue.setAttribute("ghost-phrase", node.innerHTML);
+  searchCriteria = node.getAttribute('id');
+}
+
+function checkSearchValue(event)
+{
+  var form = event.target;
+  var searchValue = document.getElementById('searchValue');
+  var ghostPhrase = searchValue.getAttribute('ghost-phrase');
+
+  if (searchValue.value == ghostPhrase)
+    searchValue.value = "";
+}
+
+function onSearchChange()
+{
+  log ("onSearchChange()...");
+}
+
+function onSearchMouseDown(event, searchValue)
+{
+  superNode = searchValue.parentNode.parentNode.parentNode;
+  relX = (event.pageX - superNode.offsetLeft - searchValue.offsetLeft);
+  relY = (event.pageY - superNode.offsetTop - searchValue.offsetTop);
+
+  if (relY < 24) {
+    event.cancelBubble = true;
+    event.returnValue = false;
+  }
+}
+
+function onSearchFocus(searchValue)
+{
+  ghostPhrase = searchValue.getAttribute("ghost-phrase");
+  if (searchValue.value == ghostPhrase) {
+    searchValue.value = "";
+    searchValue.setAttribute("modified", "");
+  } else {
+    searchValue.select();
+  }
+
+  searchValue.style.color = "#000";
+}
+
+function onSearchBlur(searchValue)
+{
+  var ghostPhrase = searchValue.getAttribute("ghost-phrase");
+//   log ("search blur: '" + searchValue.value + "'");
+  if (!searchValue.value) {
+    searchValue.setAttribute("modified", "");
+    searchValue.style.color = "#aaa";
+    searchValue.value = ghostPhrase;
+  } else if (searchValue.value == ghostPhrase) {
+    searchValue.setAttribute("modified", "");
+    searchValue.style.color = "#aaa";
+  } else {
+    searchValue.setAttribute("modified", "yes");
+    searchValue.style.color = "#000";
+  }
+}
+
+function onSearchKeyDown(searchValue)
+{
+  if (searchValue.timer)
+    clearTimeout(searchValue.timer);
+
+  searchValue.timer = setTimeout("onSearchFormSubmit()", 1000);
+}
+
+function initCriteria()
+{
+  var searchCriteria = document.getElementById('searchCriteria');
+  var searchValue = document.getElementById('searchValue');
+  var firstOption;
+  firstOption = document.getElementById('searchOptions').childNodes[1];
+  searchCriteria.value = firstOption.getAttribute('id');
+  searchValue.setAttribute('ghost-phrase', firstOption.innerHTML);
+  if (searchValue.value == '') {
+    searchValue.value = firstOption.innerHTML;
+    searchValue.setAttribute("modified", "");
+    searchValue.style.color = "#aaa";
+  }
+}
+/* contact selector */
+
+function onContactAdd(node)
+{
+  var selector = null;
+  var selectorURL = '?popup=YES';
+  if (node) {
+    selector = node.parentNode.parentNode;
+    selectorURL += ("&selectorId=" + selector.getAttribute("id"));
+  }
+
+  urlstr = ApplicationBaseURL;
+  if (urlstr[urlstr.length-1] != '/')
+    urlstr += '/';
+  urlstr += ("../../" + UserLogin + "/Contacts/"
+             + contactSelectorAction + selectorURL);
+//   log (urlstr);
+  var w = window.open(urlstr, "Addressbook",
+                      "width=640,height=400,resizable=1,scrollbars=0");
+  w.selector = selector;
+  w.opener = this;
+  w.focus();
+
+  return false;
+}
+
+function onContactRemove(node) {
+  var selector = node.parentNode.parentNode;
+  var selectorId = selector.getAttribute("id");
+  var hasChanged = false;
+
+  var names = $('uixselector-' + selectorId + '-display');
+  var nodes = names.getSelectedNodes();
+  hasChanged = (nodes.length > 0);
+  for (var i = 0; i < nodes.length; i++) {
+    var currentNode = nodes[i];
+    currentNode.parentNode.removeChild(currentNode);
+  }
+
+  var uids = $('uixselector-' + selectorId + '-uidList');
+  nodes = node.parentNode.childNodes;
+  var ids = new Array();
+  for (var i = 0; i < nodes.length; i++)
+    if (nodes[i] instanceof HTMLLIElement)
+      ids.push(nodes[i].getAttribute("uid"));
+  uids.value = ids.join(",");
+
+  if (selector.changeNotification && hasChanged)
+    selector.changeNotification("removal");
+
+  return false;
+}
+
+function listRowMouseDownHandler(event) {
+  event.preventDefault();
+}
+
+/* tabs */
+function initTabs()
+{
+  var containers = document.getElementsByClassName("tabsContainer");
+  for (var x = 0; x < containers.length; x++) {
+    var container = containers[x];
+    var nodes = container.childNodes[1].childNodes;
+
+    var firstTab;
+    for (var i = 0; i < nodes.length; i++) {
+      if (nodes[i] instanceof HTMLLIElement) {
+        if (!firstTab) {
+          firstTab = nodes[i];
+        }
+        nodes[i].addEventListener("mousedown", onTabMouseDown, true);
+        nodes[i].addEventListener("click", onTabClick, true);
+      }
+    }
+
+    firstTab.addClassName("first");
+    firstTab.addClassName("active");
+    container.activeTab = firstTab;
+
+    var target = $(firstTab.getAttribute("target"));
+    target.addClassName("active");
+  }
+}
+
+function initMenusNamed(menuDivNames) {
+  for (var i = 0; i < menuDivNames.length; i++) {
+    var menuDIV = $(menuDivNames[i]);
+    if (menuDIV)
+      initMenu(menuDIV);
+    else
+      log("menu named '" + menuDivNames[i] + "' not found");
+  }
+}
+
+function initMenu(menuDIV) {
+  var lis = menuDIV.childNodesWithTag("ul")[0].childNodesWithTag("li");
+  for (var j = 0; j < lis.length; j++)
+    lis[j].addEventListener("mousedown", listRowMouseDownHandler, false);
+  var subMenus = menuDIV.childNodesWithTag("div");
+  for (var i = 0; i < subMenus.length; i++)
+    initMenu(subMenus[i]);
+}
+
+function onTabMouseDown(event) {
+  event.cancelBubble = true;
+  event.preventDefault();
+}
+
+function openExternalLink(anchor) {
+  return false;
+}
+
+function openAclWindow(url, objectTitle) {
+  var w = window.open(url, "aclWindow",
+                      "width=300,height=300,resizable=1,scrollbars=1,toolbar=0,"
+                      + "location=0,directories=0,status=0,menubar=0"
+                      + ",copyhistory=0");
+  w.focus();
+  w.title = "Poil: " + objectTitle;
+
+  return w;
+}
+
+function onTabClick(event) {
+  var node = event.target;
+
+  var target = node.getAttribute("target");
+
+  var container = node.parentNode.parentNode;
+  var oldTarget = container.activeTab.getAttribute("target");
+  var content = $(target);
+  var oldContent = $(oldTarget);
+
+  oldContent.removeClassName("active");
+  container.activeTab.removeClassName("active");
+  container.activeTab = node;
+  container.activeTab.addClassName("active");
+  content.addClassName("active");
+
+  return false;
+}
+
+function enableAnchor(anchor) {
+  var classStr = '' + anchor.getAttribute("class");
+  var position = classStr.indexOf("_disabled", 0);
+  if (position > -1) {
+    var disabledHref = anchor.getAttribute("disabled-href");
+    if (disabledHref)
+      anchor.setAttribute("href", disabledHref);
+    var disabledOnclick = anchor.getAttribute("disabled-onclick");
+    if (disabledOnclick)
+      anchor.setAttribute("onclick", disabledOnclick);
+    anchor.removeClassName("_disabled");
+    anchor.setAttribute("disabled-href", null);
+    anchor.setAttribute("disabled-onclick", null);
+    anchor.disabled = 0;
+    anchor.enabled = 1;
+  }
+}
+
+function disableAnchor(anchor) {
+  var classStr = '' + anchor.getAttribute("class");
+  var position = classStr.indexOf("_disabled", 0);
+  if (position < 0) {
+    var href = anchor.getAttribute("href");
+    if (href)
+      anchor.setAttribute("disabled-href", href);
+    var onclick = anchor.getAttribute("onclick");
+    if (onclick)
+      anchor.setAttribute("disabled-onclick", onclick);
+    anchor.addClassName("_disabled");
+    anchor.setAttribute("href", "#");
+    anchor.setAttribute("onclick", "return false;");
+    anchor.disabled = 1;
+    anchor.enabled = 0;
+  }
+}
+
+function d2h(d) {
+  var hD = "0123456789abcdef";
+  var h = hD.substr(d&15,1);
+  while (d>15) {
+    d>>=4;
+    h=hD.substr(d&15,1)+h;
+  }
+  return h;
+}
+
+function indexColor(number) {
+  var color;
+
+  if (number == 0)
+    color = "#ccf";
+  else {
+    var colorTable = new Array(1, 1, 1);
+    
+    var currentValue = number;
+    var index = 0;
+    while (currentValue)
+      {
+        if (currentValue & 1)
+          colorTable[index]++;
+      if (index == 3)
+        index = 0;
+      currentValue >>= 1;
+      index++;
+      }
+    
+    color = ("#"
+             + d2h((256 / colorTable[2]) - 1)
+             + d2h((256 / colorTable[1]) - 1)
+             + d2h((256 / colorTable[0]) - 1));
+  }
+
+  return color;
+}
+
+var onLoadHandler = {
+  handleEvent: function (event) {
+    queryParameters = parseQueryParameters('' + window.location);
+    if (!document.body.hasClassName("popup")) {
+      initLogConsole();
+      initializeMenus();
+      initCriteria();
+    }
+    initTabs();
+    configureDragHandles();
+    configureSortableTableHeaders();
+    configureLinkBanner();
+    var progressImage = $("progressIndicator");
+    if (progressImage)
+      progressImage.parentNode.removeChild(progressImage);
+  }
+}
+
+function configureSortableTableHeaders() {
+  var headers = document.getElementsByClassName("sortableTableHeader");
+  for (var i = 0; i < headers.length; i++) {
+    var anchor = headers[i].childNodesWithTag("a")[0];
+    if (!anchor.link) {
+      anchor.link = anchor.getAttribute("href");
+      anchor.href = "#";
+      anchor.addEventListener("click", onHeaderClick, true);
+    }
+  }
+}
+
+function onLinkBannerClick() {
+  activeAjaxRequests++;
+  checkAjaxRequestsState();
+}
+
+function configureLinkBanner() {
+  var linkBanner = $("linkBanner");
+  if (linkBanner) {
+    var anchors = linkBanner.childNodesWithTag("a");
+    for (var i = 0; i < 4; i++) {
+      anchors[i].addEventListener("mousedown", listRowMouseDownHandler,
+                                  false);
+      anchors[i].addEventListener("click", onLinkBannerClick, false);
+    }
+    if (anchors.length > 5)
+      anchors[5].addEventListener("click", toggleLogConsole, true);
+  }
+}
+
+window.addEventListener("load", onLoadHandler, false);
+
+/* stubs */
+function configureDragHandles() {
+}
+
+function initializeMenus() {
+}
+
+function onHeaderClick(event) {
+  window.alert("generic headerClick");
+}
diff --git a/UI/WebServerResources/goto-today.png b/UI/WebServerResources/goto-today.png
new file mode 100644 (file)
index 0000000..2da10b5
Binary files /dev/null and b/UI/WebServerResources/goto-today.png differ
index 364468629928d11f4c3bce6f669eda73b11a3d48..6c7c104e3b0ffb41799f22614a1e00317e6db1b9 100644 (file)
Binary files a/UI/WebServerResources/icon_read.gif and b/UI/WebServerResources/icon_read.gif differ
index f7009d5c0fc3bd2a8414533f64e9cc1207181aa6..441a45fa28426b54c6af360178ef9362fe01b951 100644 (file)
Binary files a/UI/WebServerResources/icon_unread.gif and b/UI/WebServerResources/icon_unread.gif differ
diff --git a/UI/WebServerResources/lori_16x16.ico b/UI/WebServerResources/lori_16x16.ico
new file mode 100644 (file)
index 0000000..195f4a6
Binary files /dev/null and b/UI/WebServerResources/lori_16x16.ico differ
diff --git a/UI/WebServerResources/mailer-compose.css b/UI/WebServerResources/mailer-compose.css
deleted file mode 100644 (file)
index 8163d9e..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* CSS for compose panel */
-
-div#compose_panel div table {
-  padding: 2px;
-}
-table#compose_table {
-  border-bottom-color: #808080;
-  border-bottom-width: 1;
-  border-bottom-style: solid;
-}
-
-td#compose_leftside {
-  vertical-align:   top;
-}
-
-td#compose_rightside {
-  vertical-align: top;
-}
-
-div#compose_fromline {
-}
-div#compose_toselection { 
-}
-div#compose_internetmarker { 
-  padding:          8px;
-  text-align:       center;
-  background-color: white;
-  border-color:     red;
-  border-width:     2px;
-  border-style:     solid;
-}
-div#compose_attachments {
-    padding-top: 4px;
-  padding-right: 10px;
-}
-div#compose_attachments_list  {
-  width:            100%;
-  height:           100px;
-  background-color: #FFFFFF;
-  font-size:        10px;
-  margin-left:      0px;
-  padding:          2px;
-  border-color:     #c3c3c3;
-  border-width:     1px;
-  border-style:     solid;
-}
-
-div#compose_subject { 
-//  border-bottom-color: #808080;
-//  border-bottom-width: 1;
-//  border-bottom-style: solid;
-}
-div#compose_text { 
-  border-top-color:    white;
-  border-top-width:    1;
-  border-top-style:    solid;
-}
-
-div#compose_toselection select { 
-  font-size: 10px;
-}
-div#compose_toselection input { 
-  font-size: 10px;
-}
-
-input#compose_subject_input {
-  font-size: 10px;
-  width:     100%;
-}
-
-.compose_label { 
-  font-size:  11px;
-  text-align: left;
-}
-
-div#compose_text textarea { 
-  width:  100%;
-  height: 280px;
-}
index eb775daf044c14c6fc8028adbf6e7d821ecd2bfb..005a21a47d0b1dc24f6fdf74611d67eb1a9a9a06 100644 (file)
@@ -1,26 +1,25 @@
 /* toolbar for mailer application */
 
 table.tb_maintable { 
-  width:    100%;
-  position: fixed;
-  top:      0px;  /* this is patched when the linkbar is on */
-  height:   40px; /* 48px;  */
-  z-index:  100;
+  width: 100%;
+  top: 0px;  /* this is patched when the linkbar is on */
+  height: 40px; /* 48px;  */
+  z-index: 100;
 }
 td.tb_logocell { 
-  width:         24px; /* 36px; */
+  width: 24px; /* 36px; */
   padding-right: 8px;
 }
 div.tb_consumer { /* consumes the spaces taken by the toolbar */
   height: 52px; /* 58px; */ /* this is patched when the linkbar is on */
-  clear:  both;
+  clear: both;
 }
 
 .tb_toolbar {
-  height:        22px; /* was 30 */
+  height: 22px; /* was 30 */
 }
 .tb_toolbar_group { /* not used currently? */
-  height:        22px; /* was 30 */
+  height: 22px; /* was 30 */
   padding-right: 16px;
 }
 
@@ -28,25 +27,31 @@ div.tb_consumer { /* consumes the spaces taken by the toolbar */
   text-align: center;
 }
 .tb_label {
-  font-size:   11px;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  color:       #000000;
-  text-align:  center;
+  color: #000000;
+  text-align: center;
+  padding-left: .5em;
+  padding-right: .5em;
 }
+
+.tb_label a:link, .tb_label a:hover { 
+  color: #000000;
+  text-align: center;
+}
+
 .tb_spacer { 
   width: 16px;
 }
 
 .tb_icon a {
-  width:   24px;
-  height:  24px;
-  margin:  0px auto;
+  width: 24px;
+  height: 24px;
+  margin: 0px auto;
   display: block;
 }
 
 .tbicon_logo {
   background-image: url(lori_32x32.png);
-  width:  32px;
+  width: 32px;
   height: 32px;
 }
 
diff --git a/UI/WebServerResources/mailer.css b/UI/WebServerResources/mailer.css
deleted file mode 100644 (file)
index ae3b4e7..0000000
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
-  Copyright (C) 2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-/* TODO: is the section below used in the mailer? */
-
-.aptview_title {
-  font-size:        10pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  color:            #000000;
-  font-weight:      bold;
-}
-
-.aptview_text {
-  font-size:        10pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  color:            #000000;
-}
-
-.apt_other {
-  color:            #000000;
-}
-
-.apt_other_print {
-  font-style:       italic;
-}
-
-.anais_me {
-  color:            #0000FF;
-}
-
-.anais_uids {
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        10pt;
-}
-
-
-/* new stuff for Thunderbird like mailer */
-
-.vertframerow {
-  border-top-color:    white;
-  border-top-width:    1;
-  border-top-style:    solid;
-  border-bottom-color: #808080;
-  border-bottom-width: 1;
-  border-bottom-style: solid;
-
-  background-color:    #D4D0C8;
-
-  font-family:  Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:    10pt;
-}
-.foldercell {
-  font-family:  Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:    10pt;
-  width:        25%;
-}
-.contentcell {
-  font-family:  Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:    10pt;
-}
-.embedwhite_out {
-  border-width:        1;
-  border-style:        solid;
-  border-top-color:    #808080;
-  border-left-color:   #808080;
-  border-bottom-color: white;
-  border-right-color:  white;
-}
-.embedwhite_in {
-  border-width:        1;
-  border-style:        solid;
-  border-top-color:    #808080; /* TODO */
-  border-left-color:   #808080; /* TODO */
-  border-bottom-color: #808080;
-  border-right-color:  #808080;
-
-  background-color:    white;
-  /* height:              300px; */
-  /* height: 100%; */
-}
-.titlediv {
-  height:         24px;
-  vertical-align: middle;
-  padding-top:    6px;
-  padding-left:   6px;
-}
-table.titletable {
-  height:         24px;
-  vertical-align: middle;
-  padding-top:    6px;
-  padding-left:   6px;
-}
-td.titlecell {
-  height:         22px;
-  vertical-align: middle;
-  padding-bottom: 2px;
-  white-space:    nowrap;
-  font-family:    Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:      10pt;
-}
-
-.whitesec_title {
-  background-color: #D4D0C8;
-  padding:          4px;
-}
-
-.treecell {
-  font-family:    Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:      10pt;
-  color:          black;
-  vertical-align: bottom;
-  padding-left:   4px; /* move away from the icon */
-  padding-right:  2px; /* move away from the right border */
-  white-space:    nowrap;
-}
-
-/* mail tableview */
-
-.tableview { 
-  font-size:      9pt;
-  font-family:    Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  vertical-align: top;
-}
-.tableview td {
-  border-top-width:    1px;
-  border-top-color:    white;
-  border-bottom-width: 1px;
-  border-bottom-color: white;
-}
-
-.tableview_selected { 
-  font-size:        9pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  vertical-align:   top;
-  background-color: #ffffcc;
-}
-
-.tableview_highlight { 
-  font-size:        9pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  vertical-align:   top;
-  background-color: #D4D0C8;
-}
-.tableview_highlight td {
-  border-top-width:    1px;
-  border-bottom-width: 1px;
-  border-top-style:    solid;
-  border-bottom-style: solid;
-  border-top-color:    #808080;
-  border-bottom-color: #808080;
-}
-
-td.tbtv_navcell { 
-  border-width:        1;
-  border-style:        solid;
-  border-top-color:    white;
-  border-left-color:   white;
-  border-bottom-color: #808080;
-  border-right-color:  #808080;
-  padding-top:         4px;
-  padding-bottom:      3px;
-  padding-left:        4px;
-  padding-right:       4px;
-  
-  background-color:    #D4D0C8;
-}
-
-td.tbtv_headercell { 
-  border-width:        1;
-  border-style:        solid;
-  border-top-color:    white;
-  border-left-color:   white;
-  border-bottom-color: #808080;
-  border-right-color:  #808080;
-  padding-top:         4px;
-  padding-bottom:      3px;
-  padding-left:        4px;
-  padding-right:       4px;
-  
-  background-color:    #D4D0C8;
-}
-
-td.tbtv_actcell { 
-  border-width:        1;
-  border-style:        solid;
-  border-top-color:    #808080;
-  border-left-color:   #808080;
-  border-bottom-color: #808080;
-  border-right-color:  #808080;
-  padding-top:         4px;
-  padding-bottom:      3px;
-  padding-left:        4px;
-  padding-right:       4px;
-  
-  background-color:    #D4D0C8;
-}
-
-td.tbtv_headercell a {
-  margin:  0px auto;
-  display: block;
-  color:   black;
-}
-td.tbtv_headercell a:hover {
-  margin:  0px auto;
-  display: block;
-  color:   black;
-  text-decoration: none;
-  /* background-color: #C4C0B8; */
-}
-
-td.tbtv_headercell img.tbtv_sortcell { 
-  text-align: right;
-  border:     0px;
-  width:      12px;
-  height:     12px;
-}
-
-span.mailer_datefield { 
-  white-space: nowrap;
-}
-
-div.mailer_readmailsubject { 
-  background-image:    url(message-mail-read.png);
-  background-repeat:   no-repeat;
-  background-position: 0px 0px;
-  padding-top:         1px;
-  padding-left:        20px;
-}
-div.mailer_unreadmailsubject { 
-  background-image:    url(message-mail.png);
-  background-repeat:   no-repeat;
-  background-position: 0px 0px;
-  padding-left:        20px;
-  padding-top:         1px;
-  font-weight:         bold;
-}
-div.mailer_readmailsubject a { 
-  color:           black;
-  text-decoration: none;
-}
-div.mailer_unreadmailsubject a { 
-  color:           black;
-  text-decoration: none;
-}
-
-td.mailer_listcell_deleted {
-  text-decoration: line-through;
-}
-td.mailer_listcell_regular {
-}
-td.mailer_listcell_regular a { 
-  color:           black;
-  text-decoration: none;
-}
-
-div.mailer_readicon { 
-  /* TODO: use Thunderbird icon */
-  background-image:    url(icon_read.gif);
-  background-repeat:   no-repeat;
-  background-position: 0px 4px;
-}
-div.mailer_readicon a {
-  width:   17px;
-  height:  17px;
-  margin:  0px auto;
-  display: block;
-}
-div.mailer_unreadicon { 
-  /* TODO: use Thunderbird icon */
-  background-image:    url(icon_unread.gif);
-  background-repeat:   no-repeat;
-  background-position: 0px 4px;
-}
-div.mailer_unreadicon a {
-  width:   17px;
-  height:  17px;
-  margin:  0px auto;
-  display: block;
-}
-
-/* fields (key/value UI), eg used in mail viewer */
-
-table.mailer_fieldtable { 
-  width: 100%;
-
-  border-bottom-color: #808080;
-  border-bottom-width: 1;
-  border-bottom-style: solid;
-}
-tr.mailer_fieldrow { 
-  font-size:   9pt;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-}
-td.mailer_fieldname {
-  padding-left:   24px;
-  text-align:     right;
-  font-weight:    bold;
-  vertical-align: top;
-}
-td.mailer_fieldvalue {
-  width: 95%;
-}
-td.mailer_subjectfieldvalue {
-  font-weight: bold;
-}
-td.mailer_fieldvalue a {
-  text-decoration: underline;
-  vertical-align:  top;
-}
-
-div.mailer_mailcontent { 
-  border-top-color: white;
-  border-top-width: 1;
-  border-top-style: solid;
-  background-color: white;
-  padding:          8px;
-}
-
-img.mailer_imagecontent {
-  border: 0px;
-}
-pre.mailer_plaincontent { 
-}
-
-/* attachment editor */
-
-form#attachment_form { 
-  background-color: #D4D0C8;
-  padding: 1px;
-}
-
-div#attachment_list { 
-  border-top-color:    white;
-  border-top-width:    1;
-  border-top-style:    solid;
-}
-
-form#attachment_form input {
-  font-size: 10px;
-}
-
-div#attachment_upload { 
-  border-bottom-color: #808080;
-  border-bottom-width: 1;
-  border-bottom-style: solid;
-  padding: 4px;
-}
-
-td.attachment_uplabel { 
-  width:      15%;
-  font-size:  11px;
-  text-align: left;
-}
-
-/* attachment link viewer */
-
-div.linked_attachment_frame {
-  background-color: #D4D0C8;
-  padding:          4px;
-}
-
-div.linked_attachment_body {
-  font-family:         Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:           10pt;
-  padding:             4px;
-
-  border-width:        1;
-  border-style:        solid;
-  border-top-color:    white;
-  border-left-color:   white;
-  border-bottom-color: #808080;
-  border-right-color:  #808080;
-}
-
-div.linked_attachment_meta {
-  color:        #444444;
-  font-style:   italic;
-  border-width: 0;
-  padding:      2px;
-}
-table.linked_attachment_meta {
-  font-family:  Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:    10pt;
-  color:        #444444;
-  font-style:   italic;
-}
-
-
-/* OGo link banner on top of mail frame */
-
-table.linkbanner { 
-  width:            100%;
-  background-color: white;
-  position:         fixed;
-  height:           48px;
-  z-index:          100;
-}
-
-.linkbannerlinks {
-  font-size:      10pt;
-  vertical-align: bottom;
-  text-align:     left;
-}
-.linkbannerimage { 
-  text-align:     right;
-}
diff --git a/UI/WebServerResources/mailer.js b/UI/WebServerResources/mailer.js
deleted file mode 100644 (file)
index 2af615a..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
-  Copyright (C) 2005 SKYRIX Software AG
-
-  This file is part of OpenGroupware.org.
-
-  OGo is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the
-  Free Software Foundation; either version 2, or (at your option) any
-  later version.
-
-  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
-  WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-  License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with OGo; see the file COPYING.  If not, write to the
-  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-  02111-1307, USA.
-*/
-/* JavaScript for SOGo Mailer */
-
-/*
-  DOM ids available in mail list view:
-    row_$msgid
-    div_$msgid
-    readdiv_$msgid
-    unreaddiv_$msgid
-
-  Window Properties:
-    width, height
-    bool: resizable, scrollbars, toolbar, location, directories, status,
-          menubar, copyhistory
-*/
-
-/* mail list */
-
-function openMessageWindow(sender, msguid, url) {
-  return window.open(url, "SOGo_msg_" + msguid,
-          "width=640,height=480,resizable=1,scrollbars=1,toolbar=0," +
-          "location=0,directories=0,status=0,menubar=0,copyhistory=0")
-}
-
-function clickedUid(sender, msguid) {
-  resetSelection(window);
-  openMessageWindow(sender, msguid, msguid + "/view");
-  return true;
-}
-function doubleClickedUid(sender, msguid) {
-  alert("DOUBLE Clicked " + msguid);
-
-  return false;
-}
-
-function toggleMailSelect(sender) {
-  var row;
-  row = document.getElementById(sender.name);
-  row.className = sender.checked ? "tableview_selected" : "tableview";
-}
-function collectSelectedRows() {
-  var pageform = document.forms['pageform'];
-  var rows = new Array();
-
-  for (key in pageform) {
-    if (key.indexOf("row_") != 0)
-      continue;
-
-    if (!pageform[key].checked)
-      continue;
-    
-    rows[rows.length] = key.substring(4, key.length);
-  }
-  return rows;
-}
-
-function clearSearch(sender) {
-  var searchField = window.document.getElementById("search");
-  if (searchField) searchField.value="";
-  return true;
-}
-
-/* compose support */
-
-function clickedCompose(sender) {
-  var urlstr;
-  
-  urlstr = "compose";
-  window.open(urlstr, "SOGo_compose",
-             "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," +
-             "location=0,directories=0,status=0,menubar=0,copyhistory=0");
-  return false; /* stop following the link */
-}
-
-/* mail editor */
-
-function validateEditorInput(sender) {
-  var errortext = "";
-  var field;
-  
-  field = document.pageform.subject;
-  if (field.value == "")
-    errortext = errortext + labels.error_missingsubject + "\n";
-
-  if (!UIxRecipientSelectorHasRecipients())
-    errortext = errortext + labels.error_missingrecipients + "\n";
-  
-  if (errortext.length > 0) {
-    alert(labels.error_validationfailed + ":\n" + errortext);
-    return false;
-  }
-  return true;
-}
-
-function clickedEditorSend(sender) {
-  if (!validateEditorInput(sender))
-    return false;
-
-  document.pageform.action="send";
-  document.pageform.submit();
-  // if everything is ok, close the window
-  return true;
-}
-
-function clickedEditorAttach(sender) {
-  var urlstr;
-  
-  urlstr = "viewAttachments";
-  window.open(urlstr, "SOGo_attach",
-             "width=320,height=320,resizable=1,scrollbars=1,toolbar=0," +
-             "location=0,directories=0,status=0,menubar=0,copyhistory=0");
-  return false; /* stop following the link */
-}
-
-function clickedEditorSave(sender) {
-  document.pageform.action="save";
-  document.pageform.submit();
-  refreshOpener();
-  return true;
-}
-
-function clickedEditorDelete(sender) {
-  document.pageform.action="delete";
-  document.pageform.submit();
-  refreshOpener();
-  window.close();
-  return true;
-}
-
-function showInlineAttachmentList(sender) {
-  var r, l;
-  
-  r = document.getElementById('compose_rightside');
-  r.style.display = 'block';
-  l = document.getElementById('compose_leftside');
-  l.style.width = "67%";
-  this.adjustInlineAttachmentListHeight(sender);
-}
-
-function updateInlineAttachmentList(sender, attachments) {
-  if (!attachments || (attachments.length == 0)) {
-    this.hideInlineAttachmentList(sender);
-    return;
-  }
-  var e, i, count, text;
-  
-  count = attachments.length;
-  text  = "";
-  for (i = 0; i < count; i++) {
-    text = text + attachments[i];
-    text = text + '<br />';
-  }
-
-  e = document.getElementById('compose_attachments_list');
-  e.innerHTML = text;
-  this.showInlineAttachmentList(sender);
-}
-
-function adjustInlineAttachmentListHeight(sender) {
-  var e;
-  
-  e = document.getElementById('compose_rightside');
-  if (e.style.display == 'none') return;
-
-  /* need to lower left size first, because left auto-adjusts to right! */
-  xHeight('compose_attachments_list', 10);
-
-  var leftHeight, rightHeaderHeight;
-  leftHeight        = xHeight('compose_leftside');
-  rightHeaderHeight = xHeight('compose_attachments_header');
-  xHeight('compose_attachments_list', (leftHeight - rightHeaderHeight) - 16);
-}
-
-function hideInlineAttachmentList(sender) {
-  var e;
-  
-//  xVisibility('compose_rightside', false);
-  e = document.getElementById('compose_rightside');
-  e.style.display = 'none';
-  e = document.getElementById('compose_leftside');
-  e.style.width = "100%";
-}
-
-/* addressbook helpers */
-
-function openAnais(sender) {
-  var urlstr;
-
-  urlstr = "anais";
-  var w = window.open(urlstr, "Anais",
-                      "width=350,height=600,left=10,top=10,toolbar=no," +
-                      "dependent=yes,menubar=no,location=no,resizable=yes," +
-                      "scrollbars=yes,directories=no,status=no");
-  w.focus();
-}
-
-function openAddressbook(sender) {
-  var urlstr;
-  
-  urlstr = "addressbook";
-  var w = window.open(urlstr, "Addressbook",
-                      "width=600,height=400,left=10,top=10,toolbar=no," +
-                      "dependent=yes,menubar=no,location=no,resizable=yes," +
-                      "scrollbars=yes,directories=no,status=no");
-  w.focus();
-}
-
-/* filters */
-
-function clickedFilter(sender, scriptname) {
-  var urlstr;
-  
-  urlstr = scriptname + "/edit";
-  window.open(urlstr, "SOGo_filter_" + scriptname,
-             "width=640,height=480,resizable=1,scrollbars=1,toolbar=0," +
-             "location=0,directories=0,status=0,menubar=0,copyhistory=0")
-  return true;
-}
-
-function clickedNewFilter(sender) {
-  var urlstr;
-  
-  urlstr = "create";
-  window.open(urlstr, "SOGo_filter",
-             "width=680,height=480,resizable=1,scrollbars=1,toolbar=0," +
-             "location=0,directories=0,status=0,menubar=0,copyhistory=0");
-  return false; /* stop following the link */
-}
-
-/* mail list DOM changes */
-
-function markMailInWindow(win, msguid, markread) {
-  var msgDiv;
-
-  msgDiv = win.document.getElementById("div_" + msguid);
-  if (msgDiv) {
-    if (markread) {
-      msgDiv.className = "mailer_readmailsubject";
-    
-      msgDiv = win.document.getElementById("unreaddiv_" + msguid);
-      if (msgDiv) msgDiv.style.display = "none";
-      msgDiv = win.document.getElementById("readdiv_" + msguid);
-      if (msgDiv) msgDiv.style.display = "block";
-    }
-    else {
-      msgDiv.className = "mailer_unreadmailsubject";
-    
-      msgDiv = win.document.getElementById("readdiv_" + msguid);
-      if (msgDiv) msgDiv.style.display = "none";
-      msgDiv = win.document.getElementById("unreaddiv_" + msguid);
-      if (msgDiv) msgDiv.style.display = "block";
-    }
-    return true;
-  }
-  else
-    return false;
-}
-function markMailReadInWindow(win, msguid) {
-  /* this is called by UIxMailView with window.opener */
-  return markMailInWindow(win, msguid, true);
-}
-
-/* main window */
-
-function reopenToRemoveLocationBar() {
-  // we cannot really use this, see below at the close comment
-  if (window.locationbar && window.locationbar.visible) {
-    newwin = window.open(window.location.href, "SOGo",
-                        "width=800,height=600,resizable=1,scrollbars=1," +
-                        "toolbar=0,location=0,directories=0,status=0," + 
-                        "menubar=0,copyhistory=0");
-    if (newwin) {
-      window.close(); // this does only work for windows opened by scripts!
-      newwin.focus();
-      return true;
-    }
-    return false;
-  }
-  return true;
-}
-
-/* mail list reply */
-
-function openMessageWindowsForSelection(sender, action) {
-  var rows  = collectSelectedRows();
-  var idset = "";
-  
-  for (var i = 0; i < rows.length; i++) {
-    win = openMessageWindow(sender, 
-                           rows[i]                /* msguid */,
-                           rows[i] + "/" + action /* url */);
-  }
-}
-
-function mailListMarkMessage(sender, action, msguid, markread) {
-  var url;
-  var http = createHTTPClient();
-
-  url = action + "?uid=" + msguid;
-
-  if (http) {
-    // TODO: add parameter to signal that we are only interested in OK
-    http.open("POST", url + "&jsonly=1", false /* not async */);
-    http.send("");
-    if (http.status != 200) {
-      // TODO: refresh page?
-      alert("Message Mark Failed: " + http.statusText);
-      window.location.reload();
-    }
-    else {
-      markMailInWindow(window, msguid, markread);
-    }
-  }
-  else {
-    window.location.href = url;
-  }
-}
-
-/* maillist row highlight */
-
-var oldMaillistHighlight = null; // to remember deleted/selected style
-
-function ml_highlight(sender) {
-  oldMaillistHighlight = sender.className;
-  if (oldMaillistHighlight == "tableview_highlight")
-    oldMaillistHighlight = null;
-  sender.className = "tableview_highlight";
-}
-function ml_lowlight(sender) {
-  if (oldMaillistHighlight) {
-    sender.className = oldMaillistHighlight;
-    oldMaillistHighlight = null;
-  }
-  else
-    sender.className = "tableview";
-}
-
-
-/* folder operations */
-
-function ctxFolderAdd(sender) {
-  var folderName;
-  
-  folderName = prompt("Foldername: ");
-  if (folderName == undefined)
-    return false;
-  if (folderName == "")
-    return false;
-  
-  // TODO: should use a form-POST or AJAX
-  window.location.href = "createFolder?name=" + escape(folderName);
-  return false;
-}
-
-function ctxFolderDelete(sender) {
-  if (!confirm("Delete current folder?"))
-    return false;
-  
-  // TODO: should use a form-POST or AJAX
-  window.location.href = "deleteFolder";
-  return false;
-}
-
-/* bulk delete of messages */
-
-function uixDeleteSelectedMessages(sender) {
-  var rows;
-  var failCount = 0;
-  
-  rows = collectSelectedRows();
-  for (var i = 0; i < rows.length; i++) {
-    var url, http, rowElem;
-    
-    /* send AJAX request (synchronously) */
-    
-    url = "" + rows[i] + "/trash?jsonly=1";
-    
-    http = createHTTPClient();
-    http.open("POST", url, false /* not async */);
-    http.send("");
-    if (http.status != 200) { /* request failed */
-      failCount++;
-      http = null;
-      continue;
-    }
-    http = null;
-
-    /* remove from page */
-
-    /* line-through would be nicer, but hiding is OK too */
-    rowElem = document.getElementById("row_" + rows[i]);
-    rowElem.style.display = "none";
-  }
-  
-  if (failCount > 0)
-    alert("Could not delete " + failCount + " messages!");
-  
-  window.location.reload();
-  return false;
-}
diff --git a/UI/WebServerResources/manage-filters.png b/UI/WebServerResources/manage-filters.png
new file mode 100644 (file)
index 0000000..fe22224
Binary files /dev/null and b/UI/WebServerResources/manage-filters.png differ
diff --git a/UI/WebServerResources/manage-imap.png b/UI/WebServerResources/manage-imap.png
new file mode 100644 (file)
index 0000000..7b38e8c
Binary files /dev/null and b/UI/WebServerResources/manage-imap.png differ
diff --git a/UI/WebServerResources/manage-newsgroups.png b/UI/WebServerResources/manage-newsgroups.png
new file mode 100644 (file)
index 0000000..655dd6c
Binary files /dev/null and b/UI/WebServerResources/manage-newsgroups.png differ
diff --git a/UI/WebServerResources/manage-rss.png b/UI/WebServerResources/manage-rss.png
new file mode 100644 (file)
index 0000000..afca0a7
Binary files /dev/null and b/UI/WebServerResources/manage-rss.png differ
diff --git a/UI/WebServerResources/month-view.png b/UI/WebServerResources/month-view.png
new file mode 100644 (file)
index 0000000..113e21c
Binary files /dev/null and b/UI/WebServerResources/month-view.png differ
diff --git a/UI/WebServerResources/multiweek-view.png b/UI/WebServerResources/multiweek-view.png
new file mode 100644 (file)
index 0000000..dbf9b9d
Binary files /dev/null and b/UI/WebServerResources/multiweek-view.png differ
diff --git a/UI/WebServerResources/needs-action.png b/UI/WebServerResources/needs-action.png
new file mode 100644 (file)
index 0000000..eb43489
Binary files /dev/null and b/UI/WebServerResources/needs-action.png differ
diff --git a/UI/WebServerResources/new-card.png b/UI/WebServerResources/new-card.png
new file mode 100644 (file)
index 0000000..ca7dae3
Binary files /dev/null and b/UI/WebServerResources/new-card.png differ
diff --git a/UI/WebServerResources/new-event.png b/UI/WebServerResources/new-event.png
new file mode 100644 (file)
index 0000000..d6ac20c
Binary files /dev/null and b/UI/WebServerResources/new-event.png differ
diff --git a/UI/WebServerResources/new-list.png b/UI/WebServerResources/new-list.png
new file mode 100644 (file)
index 0000000..55ac33d
Binary files /dev/null and b/UI/WebServerResources/new-list.png differ
diff --git a/UI/WebServerResources/new-task.png b/UI/WebServerResources/new-task.png
new file mode 100644 (file)
index 0000000..66355af
Binary files /dev/null and b/UI/WebServerResources/new-task.png differ
diff --git a/UI/WebServerResources/offline-settings.png b/UI/WebServerResources/offline-settings.png
new file mode 100644 (file)
index 0000000..e4396f1
Binary files /dev/null and b/UI/WebServerResources/offline-settings.png differ
diff --git a/UI/WebServerResources/optional-participant.png b/UI/WebServerResources/optional-participant.png
new file mode 100644 (file)
index 0000000..a50d675
Binary files /dev/null and b/UI/WebServerResources/optional-participant.png differ
diff --git a/UI/WebServerResources/properties.png b/UI/WebServerResources/properties.png
new file mode 100644 (file)
index 0000000..0b08798
Binary files /dev/null and b/UI/WebServerResources/properties.png differ
diff --git a/UI/WebServerResources/prototype.js b/UI/WebServerResources/prototype.js
new file mode 100644 (file)
index 0000000..0e85338
--- /dev/null
@@ -0,0 +1,1781 @@
+/*  Prototype JavaScript framework, version 1.4.0
+ *  (c) 2005 Sam Stephenson <sam@conio.net>
+ *
+ *  Prototype is freely distributable under the terms of an MIT-style license.
+ *  For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+  Version: '1.4.0',
+  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+
+  emptyFunction: function() {},
+  K: function(x) {return x}
+}
+
+var Class = {
+  create: function() {
+    return function() {
+      this.initialize.apply(this, arguments);
+    }
+  }
+}
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+  for (property in source) {
+    destination[property] = source[property];
+  }
+  return destination;
+}
+
+Object.inspect = function(object) {
+  try {
+    if (object == undefined) return 'undefined';
+    if (object == null) return 'null';
+    return object.inspect ? object.inspect() : object.toString();
+  } catch (e) {
+    if (e instanceof RangeError) return '...';
+    throw e;
+  }
+}
+
+Function.prototype.bind = function() {
+  var __method = this, args = $A(arguments), object = args.shift();
+  return function() {
+    return __method.apply(object, args.concat($A(arguments)));
+  }
+}
+
+Function.prototype.bindAsEventListener = function(object) {
+  var __method = this;
+  return function(event) {
+    return __method.call(object, event || window.event);
+  }
+}
+
+Object.extend(Number.prototype, {
+  toColorPart: function() {
+    var digits = this.toString(16);
+    if (this < 16) return '0' + digits;
+    return digits;
+  },
+
+  succ: function() {
+    return this + 1;
+  },
+
+  times: function(iterator) {
+    $R(0, this, true).each(iterator);
+    return this;
+  }
+});
+
+var Try = {
+  these: function() {
+    var returnValue;
+
+    for (var i = 0; i < arguments.length; i++) {
+      var lambda = arguments[i];
+      try {
+        returnValue = lambda();
+        break;
+      } catch (e) {}
+    }
+
+    return returnValue;
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+  initialize: function(callback, frequency) {
+    this.callback = callback;
+    this.frequency = frequency;
+    this.currentlyExecuting = false;
+
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    if (!this.currentlyExecuting) {
+      try {
+        this.currentlyExecuting = true;
+        this.callback();
+      } finally {
+        this.currentlyExecuting = false;
+      }
+    }
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+function $() {
+  var elements = new Array();
+
+  for (var i = 0; i < arguments.length; i++) {
+    var element = arguments[i];
+    if (typeof element == 'string')
+      element = document.getElementById(element);
+
+    if (arguments.length == 1)
+      return element;
+
+    elements.push(element);
+  }
+
+  return elements;
+}
+Object.extend(String.prototype, {
+  stripTags: function() {
+    return this.replace(/<\/?[^>]+>/gi, '');
+  },
+
+  stripScripts: function() {
+    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+  },
+
+  extractScripts: function() {
+    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+    return (this.match(matchAll) || []).map(function(scriptTag) {
+      return (scriptTag.match(matchOne) || ['', ''])[1];
+    });
+  },
+
+  evalScripts: function() {
+    return this.extractScripts().map(eval);
+  },
+
+  escapeHTML: function() {
+    var div = document.createElement('div');
+    var text = document.createTextNode(this);
+    div.appendChild(text);
+    return div.innerHTML;
+  },
+
+  unescapeHTML: function() {
+    var div = document.createElement('div');
+    div.innerHTML = this.stripTags();
+    return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+  },
+
+  toQueryParams: function() {
+    var pairs = this.match(/^\??(.*)$/)[1].split('&');
+    return pairs.inject({}, function(params, pairString) {
+      var pair = pairString.split('=');
+      params[pair[0]] = pair[1];
+      return params;
+    });
+  },
+
+  toArray: function() {
+    return this.split('');
+  },
+
+  camelize: function() {
+    var oStringList = this.split('-');
+    if (oStringList.length == 1) return oStringList[0];
+
+    var camelizedString = this.indexOf('-') == 0
+      ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
+      : oStringList[0];
+
+    for (var i = 1, len = oStringList.length; i < len; i++) {
+      var s = oStringList[i];
+      camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
+    }
+
+    return camelizedString;
+  },
+
+  inspect: function() {
+    return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
+  }
+});
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var $break    = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+  each: function(iterator) {
+    var index = 0;
+    try {
+      this._each(function(value) {
+        try {
+          iterator(value, index++);
+        } catch (e) {
+          if (e != $continue) throw e;
+        }
+      });
+    } catch (e) {
+      if (e != $break) throw e;
+    }
+  },
+
+  all: function(iterator) {
+    var result = true;
+    this.each(function(value, index) {
+      result = result && !!(iterator || Prototype.K)(value, index);
+      if (!result) throw $break;
+    });
+    return result;
+  },
+
+  any: function(iterator) {
+    var result = true;
+    this.each(function(value, index) {
+      if (result = !!(iterator || Prototype.K)(value, index))
+        throw $break;
+    });
+    return result;
+  },
+
+  collect: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push(iterator(value, index));
+    });
+    return results;
+  },
+
+  detect: function (iterator) {
+    var result;
+    this.each(function(value, index) {
+      if (iterator(value, index)) {
+        result = value;
+        throw $break;
+      }
+    });
+    return result;
+  },
+
+  findAll: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  grep: function(pattern, iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      var stringValue = value.toString();
+      if (stringValue.match(pattern))
+        results.push((iterator || Prototype.K)(value, index));
+    })
+    return results;
+  },
+
+  include: function(object) {
+    var found = false;
+    this.each(function(value) {
+      if (value == object) {
+        found = true;
+        throw $break;
+      }
+    });
+    return found;
+  },
+
+  inject: function(memo, iterator) {
+    this.each(function(value, index) {
+      memo = iterator(memo, value, index);
+    });
+    return memo;
+  },
+
+  invoke: function(method) {
+    var args = $A(arguments).slice(1);
+    return this.collect(function(value) {
+      return value[method].apply(value, args);
+    });
+  },
+
+  max: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (value >= (result || value))
+        result = value;
+    });
+    return result;
+  },
+
+  min: function(iterator) {
+    var result;
+    this.each(function(value, index) {
+      value = (iterator || Prototype.K)(value, index);
+      if (value <= (result || value))
+        result = value;
+    });
+    return result;
+  },
+
+  partition: function(iterator) {
+    var trues = [], falses = [];
+    this.each(function(value, index) {
+      ((iterator || Prototype.K)(value, index) ?
+        trues : falses).push(value);
+    });
+    return [trues, falses];
+  },
+
+  pluck: function(property) {
+    var results = [];
+    this.each(function(value, index) {
+      results.push(value[property]);
+    });
+    return results;
+  },
+
+  reject: function(iterator) {
+    var results = [];
+    this.each(function(value, index) {
+      if (!iterator(value, index))
+        results.push(value);
+    });
+    return results;
+  },
+
+  sortBy: function(iterator) {
+    return this.collect(function(value, index) {
+      return {value: value, criteria: iterator(value, index)};
+    }).sort(function(left, right) {
+      var a = left.criteria, b = right.criteria;
+      return a < b ? -1 : a > b ? 1 : 0;
+    }).pluck('value');
+  },
+
+  toArray: function() {
+    return this.collect(Prototype.K);
+  },
+
+  zip: function() {
+    var iterator = Prototype.K, args = $A(arguments);
+    if (typeof args.last() == 'function')
+      iterator = args.pop();
+
+    var collections = [this].concat(args).map($A);
+    return this.map(function(value, index) {
+      iterator(value = collections.pluck(index));
+      return value;
+    });
+  },
+
+  inspect: function() {
+    return '#<Enumerable:' + this.toArray().inspect() + '>';
+  }
+}
+
+Object.extend(Enumerable, {
+  map:     Enumerable.collect,
+  find:    Enumerable.detect,
+  select:  Enumerable.findAll,
+  member:  Enumerable.include,
+  entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+  if (!iterable) return [];
+  if (iterable.toArray) {
+    return iterable.toArray();
+  } else {
+    var results = [];
+    for (var i = 0; i < iterable.length; i++)
+      results.push(iterable[i]);
+    return results;
+  }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+  _each: function(iterator) {
+    for (var i = 0; i < this.length; i++)
+      iterator(this[i]);
+  },
+
+  clear: function() {
+    this.length = 0;
+    return this;
+  },
+
+  first: function() {
+    return this[0];
+  },
+
+  last: function() {
+    return this[this.length - 1];
+  },
+
+  compact: function() {
+    return this.select(function(value) {
+      return value != undefined || value != null;
+    });
+  },
+
+  flatten: function() {
+    return this.inject([], function(array, value) {
+      return array.concat(value.constructor == Array ?
+        value.flatten() : [value]);
+    });
+  },
+
+  without: function() {
+    var values = $A(arguments);
+    return this.select(function(value) {
+      return !values.include(value);
+    });
+  },
+
+  indexOf: function(object) {
+    for (var i = 0; i < this.length; i++)
+      if (this[i] == object) return i;
+    return -1;
+  },
+
+  reverse: function(inline) {
+    return (inline !== false ? this : this.toArray())._reverse();
+  },
+
+  shift: function() {
+    var result = this[0];
+    for (var i = 0; i < this.length - 1; i++)
+      this[i] = this[i + 1];
+    this.length--;
+    return result;
+  },
+
+  inspect: function() {
+    return '[' + this.map(Object.inspect).join(', ') + ']';
+  }
+});
+var Hash = {
+  _each: function(iterator) {
+    for (key in this) {
+      var value = this[key];
+      if (typeof value == 'function') continue;
+
+      var pair = [key, value];
+      pair.key = key;
+      pair.value = value;
+      iterator(pair);
+    }
+  },
+
+  keys: function() {
+    return this.pluck('key');
+  },
+
+  values: function() {
+    return this.pluck('value');
+  },
+
+  merge: function(hash) {
+    return $H(hash).inject($H(this), function(mergedHash, pair) {
+      mergedHash[pair.key] = pair.value;
+      return mergedHash;
+    });
+  },
+
+  toQueryString: function() {
+    return this.map(function(pair) {
+      return pair.map(encodeURIComponent).join('=');
+    }).join('&');
+  },
+
+  inspect: function() {
+    return '#<Hash:{' + this.map(function(pair) {
+      return pair.map(Object.inspect).join(': ');
+    }).join(', ') + '}>';
+  }
+}
+
+function $H(object) {
+  var hash = Object.extend({}, object || {});
+  Object.extend(hash, Enumerable);
+  Object.extend(hash, Hash);
+  return hash;
+}
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+  initialize: function(start, end, exclusive) {
+    this.start = start;
+    this.end = end;
+    this.exclusive = exclusive;
+  },
+
+  _each: function(iterator) {
+    var value = this.start;
+    do {
+      iterator(value);
+      value = value.succ();
+    } while (this.include(value));
+  },
+
+  include: function(value) {
+    if (value < this.start)
+      return false;
+    if (this.exclusive)
+      return value < this.end;
+    return value <= this.end;
+  }
+});
+
+var $R = function(start, end, exclusive) {
+  return new ObjectRange(start, end, exclusive);
+}
+
+var Ajax = {
+  getTransport: function() {
+    return Try.these(
+      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
+      function() {return new XMLHttpRequest()}
+    ) || false;
+  },
+
+  activeRequestCount: 0
+}
+
+Ajax.Responders = {
+  responders: [],
+
+  _each: function(iterator) {
+    this.responders._each(iterator);
+  },
+
+  register: function(responderToAdd) {
+    if (!this.include(responderToAdd))
+      this.responders.push(responderToAdd);
+  },
+
+  unregister: function(responderToRemove) {
+    this.responders = this.responders.without(responderToRemove);
+  },
+
+  dispatch: function(callback, request, transport, json) {
+    this.each(function(responder) {
+      if (responder[callback] && typeof responder[callback] == 'function') {
+        try {
+          responder[callback].apply(responder, [request, transport, json]);
+        } catch (e) {}
+      }
+    });
+  }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+  onCreate: function() {
+    Ajax.activeRequestCount++;
+  },
+
+  onComplete: function() {
+    Ajax.activeRequestCount--;
+  }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+  setOptions: function(options) {
+    this.options = {
+      method:       'post',
+      asynchronous: true,
+      parameters:   ''
+    }
+    Object.extend(this.options, options || {});
+  },
+
+  responseIsSuccess: function() {
+    return this.transport.status == undefined
+        || this.transport.status == 0
+        || (this.transport.status >= 200 && this.transport.status < 300);
+  },
+
+  responseIsFailure: function() {
+    return !this.responseIsSuccess();
+  }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+  initialize: function(url, options) {
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+    this.request(url);
+  },
+
+  request: function(url) {
+    var parameters = this.options.parameters || '';
+    if (parameters.length > 0) parameters += '&_=';
+
+    try {
+      this.url = url;
+      if (this.options.method == 'get' && parameters.length > 0)
+        this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
+
+      Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+      this.transport.open(this.options.method, this.url,
+        this.options.asynchronous);
+
+      if (this.options.asynchronous) {
+        this.transport.onreadystatechange = this.onStateChange.bind(this);
+        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
+      }
+
+      this.setRequestHeaders();
+
+      var body = this.options.postBody ? this.options.postBody : parameters;
+      this.transport.send(this.options.method == 'post' ? body : null);
+
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  setRequestHeaders: function() {
+    var requestHeaders =
+      ['X-Requested-With', 'XMLHttpRequest',
+       'X-Prototype-Version', Prototype.Version];
+
+    if (this.options.method == 'post') {
+      requestHeaders.push('Content-type',
+        'application/x-www-form-urlencoded');
+
+      /* Force "Connection: close" for Mozilla browsers to work around
+       * a bug where XMLHttpReqeuest sends an incorrect Content-length
+       * header. See Mozilla Bugzilla #246651.
+       */
+      if (this.transport.overrideMimeType)
+        requestHeaders.push('Connection', 'close');
+    }
+
+    if (this.options.requestHeaders)
+      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
+
+    for (var i = 0; i < requestHeaders.length; i += 2)
+      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
+  },
+
+  onStateChange: function() {
+    var readyState = this.transport.readyState;
+    if (readyState != 1)
+      this.respondToReadyState(this.transport.readyState);
+  },
+
+  header: function(name) {
+    try {
+      return this.transport.getResponseHeader(name);
+    } catch (e) {}
+  },
+
+  evalJSON: function() {
+    try {
+      return eval(this.header('X-JSON'));
+    } catch (e) {}
+  },
+
+  evalResponse: function() {
+    try {
+      return eval(this.transport.responseText);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+  },
+
+  respondToReadyState: function(readyState) {
+    var event = Ajax.Request.Events[readyState];
+    var transport = this.transport, json = this.evalJSON();
+
+    if (event == 'Complete') {
+      try {
+        (this.options['on' + this.transport.status]
+         || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+         || Prototype.emptyFunction)(transport, json);
+      } catch (e) {
+        this.dispatchException(e);
+      }
+
+      if ((this.header('Content-type') || '').match(/^text\/javascript/i))
+        this.evalResponse();
+    }
+
+    try {
+      (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
+      Ajax.Responders.dispatch('on' + event, this, transport, json);
+    } catch (e) {
+      this.dispatchException(e);
+    }
+
+    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
+    if (event == 'Complete')
+      this.transport.onreadystatechange = Prototype.emptyFunction;
+  },
+
+  dispatchException: function(exception) {
+    (this.options.onException || Prototype.emptyFunction)(this, exception);
+    Ajax.Responders.dispatch('onException', this, exception);
+  }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+  initialize: function(container, url, options) {
+    this.containers = {
+      success: container.success ? $(container.success) : $(container),
+      failure: container.failure ? $(container.failure) :
+        (container.success ? null : $(container))
+    }
+
+    this.transport = Ajax.getTransport();
+    this.setOptions(options);
+
+    var onComplete = this.options.onComplete || Prototype.emptyFunction;
+    this.options.onComplete = (function(transport, object) {
+      this.updateContent();
+      onComplete(transport, object);
+    }).bind(this);
+
+    this.request(url);
+  },
+
+  updateContent: function() {
+    var receiver = this.responseIsSuccess() ?
+      this.containers.success : this.containers.failure;
+    var response = this.transport.responseText;
+
+    if (!this.options.evalScripts)
+      response = response.stripScripts();
+
+    if (receiver) {
+      if (this.options.insertion) {
+        new this.options.insertion(receiver, response);
+      } else {
+        Element.update(receiver, response);
+      }
+    }
+
+    if (this.responseIsSuccess()) {
+      if (this.onComplete)
+        setTimeout(this.onComplete.bind(this), 10);
+    }
+  }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+  initialize: function(container, url, options) {
+    this.setOptions(options);
+    this.onComplete = this.options.onComplete;
+
+    this.frequency = (this.options.frequency || 2);
+    this.decay = (this.options.decay || 1);
+
+    this.updater = {};
+    this.container = container;
+    this.url = url;
+
+    this.start();
+  },
+
+  start: function() {
+    this.options.onComplete = this.updateComplete.bind(this);
+    this.onTimerEvent();
+  },
+
+  stop: function() {
+    this.updater.onComplete = undefined;
+    clearTimeout(this.timer);
+    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+  },
+
+  updateComplete: function(request) {
+    if (this.options.decay) {
+      this.decay = (request.responseText == this.lastText ?
+        this.decay * this.options.decay : 1);
+
+      this.lastText = request.responseText;
+    }
+    this.timer = setTimeout(this.onTimerEvent.bind(this),
+      this.decay * this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    this.updater = new Ajax.Updater(this.container, this.url, this.options);
+  }
+});
+document.getElementsByClassName = function(className, parentElement) {
+  var children = ($(parentElement) || document.body).getElementsByTagName('*');
+  return $A(children).inject([], function(elements, child) {
+    if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+      elements.push(child);
+    return elements;
+  });
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element) {
+  var Element = new Object();
+}
+
+Object.extend(Element, {
+  visible: function(element) {
+    return $(element).style.display != 'none';
+  },
+
+  toggle: function() {
+    for (var i = 0; i < arguments.length; i++) {
+      var element = $(arguments[i]);
+      Element[Element.visible(element) ? 'hide' : 'show'](element);
+    }
+  },
+
+  hide: function() {
+    for (var i = 0; i < arguments.length; i++) {
+      var element = $(arguments[i]);
+      element.style.display = 'none';
+    }
+  },
+
+  show: function() {
+    for (var i = 0; i < arguments.length; i++) {
+      var element = $(arguments[i]);
+      element.style.display = '';
+    }
+  },
+
+  remove: function(element) {
+    element = $(element);
+    element.parentNode.removeChild(element);
+  },
+
+  update: function(element, html) {
+    $(element).innerHTML = html.stripScripts();
+    setTimeout(function() {html.evalScripts()}, 10);
+  },
+
+  getHeight: function(element) {
+    element = $(element);
+    return element.offsetHeight;
+  },
+
+  classNames: function(element) {
+    return new Element.ClassNames(element);
+  },
+
+  hasClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    return Element.classNames(element).include(className);
+  },
+
+  addClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    return Element.classNames(element).add(className);
+  },
+
+  removeClassName: function(element, className) {
+    if (!(element = $(element))) return;
+    return Element.classNames(element).remove(className);
+  },
+
+  // removes whitespace-only text node children
+  cleanWhitespace: function(element) {
+    element = $(element);
+    for (var i = 0; i < element.childNodes.length; i++) {
+      var node = element.childNodes[i];
+      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+        Element.remove(node);
+    }
+  },
+
+  empty: function(element) {
+    return $(element).innerHTML.match(/^\s*$/);
+  },
+
+  scrollTo: function(element) {
+    element = $(element);
+    var x = element.x ? element.x : element.offsetLeft,
+        y = element.y ? element.y : element.offsetTop;
+    window.scrollTo(x, y);
+  },
+
+  getStyle: function(element, style) {
+    element = $(element);
+    var value = element.style[style.camelize()];
+    if (!value) {
+      if (document.defaultView && document.defaultView.getComputedStyle) {
+        var css = document.defaultView.getComputedStyle(element, null);
+        value = css ? css.getPropertyValue(style) : null;
+      } else if (element.currentStyle) {
+        value = element.currentStyle[style.camelize()];
+      }
+    }
+
+    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+
+    return value == 'auto' ? null : value;
+  },
+
+  setStyle: function(element, style) {
+    element = $(element);
+    for (name in style)
+      element.style[name.camelize()] = style[name];
+  },
+
+  getDimensions: function(element) {
+    element = $(element);
+    if (Element.getStyle(element, 'display') != 'none')
+      return {width: element.offsetWidth, height: element.offsetHeight};
+
+    // All *Width and *Height properties give 0 on elements with display none,
+    // so enable the element temporarily
+    var els = element.style;
+    var originalVisibility = els.visibility;
+    var originalPosition = els.position;
+    els.visibility = 'hidden';
+    els.position = 'absolute';
+    els.display = '';
+    var originalWidth = element.clientWidth;
+    var originalHeight = element.clientHeight;
+    els.display = 'none';
+    els.position = originalPosition;
+    els.visibility = originalVisibility;
+    return {width: originalWidth, height: originalHeight};
+  },
+
+  makePositioned: function(element) {
+    element = $(element);
+    var pos = Element.getStyle(element, 'position');
+    if (pos == 'static' || !pos) {
+      element._madePositioned = true;
+      element.style.position = 'relative';
+      // Opera returns the offset relative to the positioning context, when an
+      // element is position relative but top and left have not been defined
+      if (window.opera) {
+        element.style.top = 0;
+        element.style.left = 0;
+      }
+    }
+  },
+
+  undoPositioned: function(element) {
+    element = $(element);
+    if (element._madePositioned) {
+      element._madePositioned = undefined;
+      element.style.position =
+        element.style.top =
+        element.style.left =
+        element.style.bottom =
+        element.style.right = '';
+    }
+  },
+
+  makeClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return;
+    element._overflow = element.style.overflow;
+    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+      element.style.overflow = 'hidden';
+  },
+
+  undoClipping: function(element) {
+    element = $(element);
+    if (element._overflow) return;
+    element.style.overflow = element._overflow;
+    element._overflow = undefined;
+  }
+});
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+  this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+  initialize: function(element, content) {
+    this.element = $(element);
+    this.content = content.stripScripts();
+
+    if (this.adjacency && this.element.insertAdjacentHTML) {
+      try {
+        this.element.insertAdjacentHTML(this.adjacency, this.content);
+      } catch (e) {
+        if (this.element.tagName.toLowerCase() == 'tbody') {
+          this.insertContent(this.contentFromAnonymousTable());
+        } else {
+          throw e;
+        }
+      }
+    } else {
+      this.range = this.element.ownerDocument.createRange();
+      if (this.initializeRange) this.initializeRange();
+      this.insertContent([this.range.createContextualFragment(this.content)]);
+    }
+
+    setTimeout(function() {content.evalScripts()}, 10);
+  },
+
+  contentFromAnonymousTable: function() {
+    var div = document.createElement('div');
+    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+    return $A(div.childNodes[0].childNodes[0].childNodes);
+  }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+  initializeRange: function() {
+    this.range.setStartBefore(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment, this.element);
+    }).bind(this));
+  }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(true);
+  },
+
+  insertContent: function(fragments) {
+    fragments.reverse(false).each((function(fragment) {
+      this.element.insertBefore(fragment, this.element.firstChild);
+    }).bind(this));
+  }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+  initializeRange: function() {
+    this.range.selectNodeContents(this.element);
+    this.range.collapse(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.appendChild(fragment);
+    }).bind(this));
+  }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+  initializeRange: function() {
+    this.range.setStartAfter(this.element);
+  },
+
+  insertContent: function(fragments) {
+    fragments.each((function(fragment) {
+      this.element.parentNode.insertBefore(fragment,
+        this.element.nextSibling);
+    }).bind(this));
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+  initialize: function(element) {
+    this.element = $(element);
+  },
+
+  _each: function(iterator) {
+    this.element.className.split(/\s+/).select(function(name) {
+      return name.length > 0;
+    })._each(iterator);
+  },
+
+  set: function(className) {
+    this.element.className = className;
+  },
+
+  add: function(classNameToAdd) {
+    if (this.include(classNameToAdd)) return;
+    this.set(this.toArray().concat(classNameToAdd).join(' '));
+  },
+
+  remove: function(classNameToRemove) {
+    if (!this.include(classNameToRemove)) return;
+    this.set(this.select(function(className) {
+      return className != classNameToRemove;
+    }).join(' '));
+  },
+
+  toString: function() {
+    return this.toArray().join(' ');
+  }
+}
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Field = {
+  clear: function() {
+    for (var i = 0; i < arguments.length; i++)
+      $(arguments[i]).value = '';
+  },
+
+  focus: function(element) {
+    $(element).focus();
+  },
+
+  present: function() {
+    for (var i = 0; i < arguments.length; i++)
+      if ($(arguments[i]).value == '') return false;
+    return true;
+  },
+
+  select: function(element) {
+    $(element).select();
+  },
+
+  activate: function(element) {
+    element = $(element);
+    element.focus();
+    if (element.select)
+      element.select();
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Form = {
+  serialize: function(form) {
+    var elements = Form.getElements($(form));
+    var queryComponents = new Array();
+
+    for (var i = 0; i < elements.length; i++) {
+      var queryComponent = Form.Element.serialize(elements[i]);
+      if (queryComponent)
+        queryComponents.push(queryComponent);
+    }
+
+    return queryComponents.join('&');
+  },
+
+  getElements: function(form) {
+    form = $(form);
+    var elements = new Array();
+
+    for (tagName in Form.Element.Serializers) {
+      var tagElements = form.getElementsByTagName(tagName);
+      for (var j = 0; j < tagElements.length; j++)
+        elements.push(tagElements[j]);
+    }
+    return elements;
+  },
+
+  getInputs: function(form, typeName, name) {
+    form = $(form);
+    var inputs = form.getElementsByTagName('input');
+
+    if (!typeName && !name)
+      return inputs;
+
+    var matchingInputs = new Array();
+    for (var i = 0; i < inputs.length; i++) {
+      var input = inputs[i];
+      if ((typeName && input.type != typeName) ||
+          (name && input.name != name))
+        continue;
+      matchingInputs.push(input);
+    }
+
+    return matchingInputs;
+  },
+
+  disable: function(form) {
+    var elements = Form.getElements(form);
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      element.blur();
+      element.disabled = 'true';
+    }
+  },
+
+  enable: function(form) {
+    var elements = Form.getElements(form);
+    for (var i = 0; i < elements.length; i++) {
+      var element = elements[i];
+      element.disabled = '';
+    }
+  },
+
+  findFirstElement: function(form) {
+    return Form.getElements(form).find(function(element) {
+      return element.type != 'hidden' && !element.disabled &&
+        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+    });
+  },
+
+  focusFirstElement: function(form) {
+    Field.activate(Form.findFirstElement(form));
+  },
+
+  reset: function(form) {
+    $(form).reset();
+  }
+}
+
+Form.Element = {
+  serialize: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    var parameter = Form.Element.Serializers[method](element);
+
+    if (parameter) {
+      var key = encodeURIComponent(parameter[0]);
+      if (key.length == 0) return;
+
+      if (parameter[1].constructor != Array)
+        parameter[1] = [parameter[1]];
+
+      return parameter[1].map(function(value) {
+        return key + '=' + encodeURIComponent(value);
+      }).join('&');
+    }
+  },
+
+  getValue: function(element) {
+    element = $(element);
+    var method = element.tagName.toLowerCase();
+    var parameter = Form.Element.Serializers[method](element);
+
+    if (parameter)
+      return parameter[1];
+  }
+}
+
+Form.Element.Serializers = {
+  input: function(element) {
+    switch (element.type.toLowerCase()) {
+      case 'submit':
+      case 'hidden':
+      case 'password':
+      case 'text':
+        return Form.Element.Serializers.textarea(element);
+      case 'checkbox':
+      case 'radio':
+        return Form.Element.Serializers.inputSelector(element);
+    }
+    return false;
+  },
+
+  inputSelector: function(element) {
+    if (element.checked)
+      return [element.name, element.value];
+  },
+
+  textarea: function(element) {
+    return [element.name, element.value];
+  },
+
+  select: function(element) {
+    return Form.Element.Serializers[element.type == 'select-one' ?
+      'selectOne' : 'selectMany'](element);
+  },
+
+  selectOne: function(element) {
+    var value = '', opt, index = element.selectedIndex;
+    if (index >= 0) {
+      opt = element.options[index];
+      value = opt.value;
+      if (!value && !('value' in opt))
+        value = opt.text;
+    }
+    return [element.name, value];
+  },
+
+  selectMany: function(element) {
+    var value = new Array();
+    for (var i = 0; i < element.length; i++) {
+      var opt = element.options[i];
+      if (opt.selected) {
+        var optValue = opt.value;
+        if (!optValue && !('value' in opt))
+          optValue = opt.text;
+        value.push(optValue);
+      }
+    }
+    return [element.name, value];
+  }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {}
+Abstract.TimedObserver.prototype = {
+  initialize: function(element, frequency, callback) {
+    this.frequency = frequency;
+    this.element   = $(element);
+    this.callback  = callback;
+
+    this.lastValue = this.getValue();
+    this.registerCallback();
+  },
+
+  registerCallback: function() {
+    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+  },
+
+  onTimerEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {}
+Abstract.EventObserver.prototype = {
+  initialize: function(element, callback) {
+    this.element  = $(element);
+    this.callback = callback;
+
+    this.lastValue = this.getValue();
+    if (this.element.tagName.toLowerCase() == 'form')
+      this.registerFormCallbacks();
+    else
+      this.registerCallback(this.element);
+  },
+
+  onElementEvent: function() {
+    var value = this.getValue();
+    if (this.lastValue != value) {
+      this.callback(this.element, value);
+      this.lastValue = value;
+    }
+  },
+
+  registerFormCallbacks: function() {
+    var elements = Form.getElements(this.element);
+    for (var i = 0; i < elements.length; i++)
+      this.registerCallback(elements[i]);
+  },
+
+  registerCallback: function(element) {
+    if (element.type) {
+      switch (element.type.toLowerCase()) {
+        case 'checkbox':
+        case 'radio':
+          Event.observe(element, 'click', this.onElementEvent.bind(this));
+          break;
+        case 'password':
+        case 'text':
+        case 'textarea':
+        case 'select-one':
+        case 'select-multiple':
+          Event.observe(element, 'change', this.onElementEvent.bind(this));
+          break;
+      }
+    }
+  }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.Element.getValue(this.element);
+  }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+  getValue: function() {
+    return Form.serialize(this.element);
+  }
+});
+if (!window.Event) {
+  var Event = new Object();
+}
+
+Object.extend(Event, {
+  KEY_BACKSPACE: 8,
+  KEY_TAB:       9,
+  KEY_RETURN:   13,
+  KEY_ESC:      27,
+  KEY_LEFT:     37,
+  KEY_UP:       38,
+  KEY_RIGHT:    39,
+  KEY_DOWN:     40,
+  KEY_DELETE:   46,
+
+  element: function(event) {
+    return event.target || event.srcElement;
+  },
+
+  isLeftClick: function(event) {
+    return (((event.which) && (event.which == 1)) ||
+            ((event.button) && (event.button == 1)));
+  },
+
+  pointerX: function(event) {
+    return event.pageX || (event.clientX +
+      (document.documentElement.scrollLeft || document.body.scrollLeft));
+  },
+
+  pointerY: function(event) {
+    return event.pageY || (event.clientY +
+      (document.documentElement.scrollTop || document.body.scrollTop));
+  },
+
+  stop: function(event) {
+    if (event.preventDefault) {
+      event.preventDefault();
+      event.stopPropagation();
+    } else {
+      event.returnValue = false;
+      event.cancelBubble = true;
+    }
+  },
+
+  // find the first node with the given tagName, starting from the
+  // node the event was triggered on; traverses the DOM upwards
+  findElement: function(event, tagName) {
+    var element = Event.element(event);
+    while (element.parentNode && (!element.tagName ||
+        (element.tagName.toUpperCase() != tagName.toUpperCase())))
+      element = element.parentNode;
+    return element;
+  },
+
+  observers: false,
+
+  _observeAndCache: function(element, name, observer, useCapture) {
+    if (!this.observers) this.observers = [];
+    if (element.addEventListener) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.addEventListener(name, observer, useCapture);
+    } else if (element.attachEvent) {
+      this.observers.push([element, name, observer, useCapture]);
+      element.attachEvent('on' + name, observer);
+    }
+  },
+
+  unloadCache: function() {
+    if (!Event.observers) return;
+    for (var i = 0; i < Event.observers.length; i++) {
+      Event.stopObserving.apply(this, Event.observers[i]);
+      Event.observers[i][0] = null;
+    }
+    Event.observers = false;
+  },
+
+  observe: function(element, name, observer, useCapture) {
+    var element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.attachEvent))
+      name = 'keydown';
+
+    this._observeAndCache(element, name, observer, useCapture);
+  },
+
+  stopObserving: function(element, name, observer, useCapture) {
+    var element = $(element);
+    useCapture = useCapture || false;
+
+    if (name == 'keypress' &&
+        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+        || element.detachEvent))
+      name = 'keydown';
+
+    if (element.removeEventListener) {
+      element.removeEventListener(name, observer, useCapture);
+    } else if (element.detachEvent) {
+      element.detachEvent('on' + name, observer);
+    }
+  }
+});
+
+/* prevent memory leaks in IE */
+Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+  // set to true if needed, warning: firefox performance problems
+  // NOT neeeded for page scrolling, only if draggable contained in
+  // scrollable elements
+  includeScrollOffsets: false,
+
+  // must be called before calling withinIncludingScrolloffset, every time the
+  // page is scrolled
+  prepare: function() {
+    this.deltaX =  window.pageXOffset
+                || document.documentElement.scrollLeft
+                || document.body.scrollLeft
+                || 0;
+    this.deltaY =  window.pageYOffset
+                || document.documentElement.scrollTop
+                || document.body.scrollTop
+                || 0;
+  },
+
+  realOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.scrollTop  || 0;
+      valueL += element.scrollLeft || 0;
+      element = element.parentNode;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  cumulativeOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  positionedOffset: function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      element = element.offsetParent;
+      if (element) {
+        p = Element.getStyle(element, 'position');
+        if (p == 'relative' || p == 'absolute') break;
+      }
+    } while (element);
+    return [valueL, valueT];
+  },
+
+  offsetParent: function(element) {
+    if (element.offsetParent) return element.offsetParent;
+    if (element == document.body) return element;
+
+    while ((element = element.parentNode) && element != document.body)
+      if (Element.getStyle(element, 'position') != 'static')
+        return element;
+
+    return document.body;
+  },
+
+  // caches x/y coordinate pair to use with overlap
+  within: function(element, x, y) {
+    if (this.includeScrollOffsets)
+      return this.withinIncludingScrolloffsets(element, x, y);
+    this.xcomp = x;
+    this.ycomp = y;
+    this.offset = this.cumulativeOffset(element);
+
+    return (y >= this.offset[1] &&
+            y <  this.offset[1] + element.offsetHeight &&
+            x >= this.offset[0] &&
+            x <  this.offset[0] + element.offsetWidth);
+  },
+
+  withinIncludingScrolloffsets: function(element, x, y) {
+    var offsetcache = this.realOffset(element);
+
+    this.xcomp = x + offsetcache[0] - this.deltaX;
+    this.ycomp = y + offsetcache[1] - this.deltaY;
+    this.offset = this.cumulativeOffset(element);
+
+    return (this.ycomp >= this.offset[1] &&
+            this.ycomp <  this.offset[1] + element.offsetHeight &&
+            this.xcomp >= this.offset[0] &&
+            this.xcomp <  this.offset[0] + element.offsetWidth);
+  },
+
+  // within must be called directly before
+  overlap: function(mode, element) {
+    if (!mode) return 0;
+    if (mode == 'vertical')
+      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+        element.offsetHeight;
+    if (mode == 'horizontal')
+      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+        element.offsetWidth;
+  },
+
+  clone: function(source, target) {
+    source = $(source);
+    target = $(target);
+    target.style.position = 'absolute';
+    var offsets = this.cumulativeOffset(source);
+    target.style.top    = offsets[1] + 'px';
+    target.style.left   = offsets[0] + 'px';
+    target.style.width  = source.offsetWidth + 'px';
+    target.style.height = source.offsetHeight + 'px';
+  },
+
+  page: function(forElement) {
+    var valueT = 0, valueL = 0;
+
+    var element = forElement;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+
+      // Safari fix
+      if (element.offsetParent==document.body)
+        if (Element.getStyle(element,'position')=='absolute') break;
+
+    } while (element = element.offsetParent);
+
+    element = forElement;
+    do {
+      valueT -= element.scrollTop  || 0;
+      valueL -= element.scrollLeft || 0;
+    } while (element = element.parentNode);
+
+    return [valueL, valueT];
+  },
+
+  clone: function(source, target) {
+    var options = Object.extend({
+      setLeft:    true,
+      setTop:     true,
+      setWidth:   true,
+      setHeight:  true,
+      offsetTop:  0,
+      offsetLeft: 0
+    }, arguments[2] || {})
+
+    // find page position of source
+    source = $(source);
+    var p = Position.page(source);
+
+    // find coordinate system to use
+    target = $(target);
+    var delta = [0, 0];
+    var parent = null;
+    // delta [0,0] will do fine with position: fixed elements,
+    // position:absolute needs offsetParent deltas
+    if (Element.getStyle(target,'position') == 'absolute') {
+      parent = Position.offsetParent(target);
+      delta = Position.page(parent);
+    }
+
+    // correct by body offsets (fixes Safari)
+    if (parent == document.body) {
+      delta[0] -= document.body.offsetLeft;
+      delta[1] -= document.body.offsetTop;
+    }
+
+    // set position
+    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
+    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
+    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
+    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+  },
+
+  absolutize: function(element) {
+    element = $(element);
+    if (element.style.position == 'absolute') return;
+    Position.prepare();
+
+    var offsets = Position.positionedOffset(element);
+    var top     = offsets[1];
+    var left    = offsets[0];
+    var width   = element.clientWidth;
+    var height  = element.clientHeight;
+
+    element._originalLeft   = left - parseFloat(element.style.left  || 0);
+    element._originalTop    = top  - parseFloat(element.style.top || 0);
+    element._originalWidth  = element.style.width;
+    element._originalHeight = element.style.height;
+
+    element.style.position = 'absolute';
+    element.style.top    = top + 'px';;
+    element.style.left   = left + 'px';;
+    element.style.width  = width + 'px';;
+    element.style.height = height + 'px';;
+  },
+
+  relativize: function(element) {
+    element = $(element);
+    if (element.style.position == 'relative') return;
+    Position.prepare();
+
+    element.style.position = 'relative';
+    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
+    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+    element.style.top    = top + 'px';
+    element.style.left   = left + 'px';
+    element.style.height = element._originalHeight;
+    element.style.width  = element._originalWidth;
+  }
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned.  For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+  Position.cumulativeOffset = function(element) {
+    var valueT = 0, valueL = 0;
+    do {
+      valueT += element.offsetTop  || 0;
+      valueL += element.offsetLeft || 0;
+      if (element.offsetParent == document.body)
+        if (Element.getStyle(element, 'position') == 'absolute') break;
+
+      element = element.offsetParent;
+    } while (element);
+
+    return [valueL, valueT];
+  }
+}
\ No newline at end of file
diff --git a/UI/WebServerResources/read-messages.png b/UI/WebServerResources/read-messages.png
new file mode 100644 (file)
index 0000000..35ecce1
Binary files /dev/null and b/UI/WebServerResources/read-messages.png differ
diff --git a/UI/WebServerResources/remove-addressbook.png b/UI/WebServerResources/remove-addressbook.png
new file mode 100644 (file)
index 0000000..53bad29
Binary files /dev/null and b/UI/WebServerResources/remove-addressbook.png differ
diff --git a/UI/WebServerResources/remove-contact.gif b/UI/WebServerResources/remove-contact.gif
new file mode 100644 (file)
index 0000000..c275471
Binary files /dev/null and b/UI/WebServerResources/remove-contact.gif differ
diff --git a/UI/WebServerResources/required-participant.png b/UI/WebServerResources/required-participant.png
new file mode 100644 (file)
index 0000000..003df13
Binary files /dev/null and b/UI/WebServerResources/required-participant.png differ
diff --git a/UI/WebServerResources/search-messages.png b/UI/WebServerResources/search-messages.png
new file mode 100644 (file)
index 0000000..a85b013
Binary files /dev/null and b/UI/WebServerResources/search-messages.png differ
similarity index 87%
rename from UI/Scheduler/skycalendar.html
rename to UI/WebServerResources/skycalendar.html
index f6767f4e9e42144590ac265b09234c59c8ee2fdb..97e7dd313f314475a600fcd470ffe508edc541e9 100644 (file)
@@ -24,7 +24,7 @@ modified by Martin Hoerning, mh@skyrix.com, 2002-12-05
 
 // months as they appear in the calendar's title
 var ARR_MONTHS = ["January", "February", "March", "April", "May", "June",
-               "July", "August", "September", "October", "November", "December"];
+                 "July", "August", "September", "October", "November", "December"];
 // week day titles as they appear on the calendar
 var ARR_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
 // day week starts from (normally 0-Mo or 1-Su)
@@ -32,6 +32,30 @@ var NUM_WEEKSTART = 1;
 // path to the directory where calendar images are stored. trailing slash req.
 var STR_ICONPATH = '';
 
+var labels = window.opener.labels;
+if (labels) {
+  for (var i = 0; i < ARR_MONTHS.length; i++) {
+    var string = ARR_MONTHS[i];
+    if (labels[string])
+      ARR_MONTHS[i] = labels[string];
+  }
+
+ if (labels['a2_Sunday'])
+   ARR_WEEKDAYS[0] = labels['a2_Sunday'];
+ if (labels['a2_Monday'])
+   ARR_WEEKDAYS[1] = labels['a2_Monday'];
+ if (labels['a2_Tuesday'])
+   ARR_WEEKDAYS[2] = labels['a2_Tuesday'];
+ if (labels['a2_Wednesday'])
+   ARR_WEEKDAYS[3] = labels['a2_Wednesday'];
+ if (labels['a2_Thursday'])
+   ARR_WEEKDAYS[4] = labels['a2_Thursday'];
+ if (labels['a2_Friday'])
+   ARR_WEEKDAYS[5] = labels['a2_Friday'];
+ if (labels['a2_Saturday'])
+   ARR_WEEKDAYS[6] = labels['a2_Saturday'];
+}
+
 var re_url = new RegExp('datetime=(\\-?\\d+)');
 var dt_current = (re_url.exec(String(window.location))
        ? new Date(new Number(RegExp.$1)) : new Date());
@@ -86,6 +110,9 @@ function set_datetime(n_datetime, b_close) {
             ? obj_caller.gen_tsmp(dt_datetime)
             : obj_caller.gen_date(dt_datetime)
           );
+          var onChangeEvent = document.createEvent("Event");
+          onChangeEvent.initEvent("change", false, true);
+          obj_caller.target.dispatchEvent(onChangeEvent );
         }
        if (b_close) window.close();
        else obj_caller.popup(dt_datetime.valueOf());
diff --git a/UI/WebServerResources/submenu-active.gif b/UI/WebServerResources/submenu-active.gif
new file mode 100644 (file)
index 0000000..123c9f8
Binary files /dev/null and b/UI/WebServerResources/submenu-active.gif differ
diff --git a/UI/WebServerResources/submenu.gif b/UI/WebServerResources/submenu.gif
new file mode 100644 (file)
index 0000000..c5f8fca
Binary files /dev/null and b/UI/WebServerResources/submenu.gif differ
index fbbdd1e24b0257062a08d36173f9cc445e7798ef..2db45e6160e54463319181215c439ae93c790a73 100644 (file)
Binary files a/UI/WebServerResources/tbtv_account_17x17.gif and b/UI/WebServerResources/tbtv_account_17x17.gif differ
index d57bbbfc647542dccaad1c8dd6e3983ca0bfbc66..c60f47619db5946ee7a77a25df494a3f9d7beb83 100644 (file)
Binary files a/UI/WebServerResources/tbtv_corner_17x17.gif and b/UI/WebServerResources/tbtv_corner_17x17.gif differ
index 81c616b56adb1c66ab1370be08b7999eb7051494..203472b6d440532aa3eabe3bf9b078dd9e78298b 100644 (file)
Binary files a/UI/WebServerResources/tbtv_corner_minus_17x17.gif and b/UI/WebServerResources/tbtv_corner_minus_17x17.gif differ
index 2ba4bf460acaf628a318d8b297758fda68b0f16d..b27016f3dd1e15a3d0a95dea26b5a37196f85477 100644 (file)
Binary files a/UI/WebServerResources/tbtv_corner_plus_17x17.gif and b/UI/WebServerResources/tbtv_corner_plus_17x17.gif differ
index c6a82e6c66723c0c464b9dd80476f31f8168b9df..a76d9831ea9854dd966abe5770be9d0d566499a6 100644 (file)
Binary files a/UI/WebServerResources/tbtv_drafts_17x17.gif and b/UI/WebServerResources/tbtv_drafts_17x17.gif differ
index 745709d309f8df7b2d6cf7ec18d6e7cd7133e252..c40b8f0319714581065dd2ff5469235bf0200c13 100644 (file)
Binary files a/UI/WebServerResources/tbtv_inbox_17x17.gif and b/UI/WebServerResources/tbtv_inbox_17x17.gif differ
diff --git a/UI/WebServerResources/tbtv_junction2_17x17.gif b/UI/WebServerResources/tbtv_junction2_17x17.gif
deleted file mode 100644 (file)
index f3c2270..0000000
Binary files a/UI/WebServerResources/tbtv_junction2_17x17.gif and /dev/null differ
index 3c5555295afd25f8b32cdd368a94c2b6d2b27d6b..f3c22703871340588c478726ab5bf90f15b2a7c0 100644 (file)
Binary files a/UI/WebServerResources/tbtv_junction_17x17.gif and b/UI/WebServerResources/tbtv_junction_17x17.gif differ
index 5c73acab2b9b2f0a62828fc54baab80a7ee60739..e5cab997310d951c248d6fd1f7ec001a002aa360 100644 (file)
Binary files a/UI/WebServerResources/tbtv_leaf_corner_17x17.gif and b/UI/WebServerResources/tbtv_leaf_corner_17x17.gif differ
index 962791fedd3189ed7681338dce3265e7bfc29594..a3e12b1787f9629b5f9bb2feef88b6e581737695 100644 (file)
Binary files a/UI/WebServerResources/tbtv_line_17x17.gif and b/UI/WebServerResources/tbtv_line_17x17.gif differ
index ca17de65f053d25dc9991306880766fd617ac0a3..9b51904358aaf74dd70eb706be1dbefa3d7ee661 100644 (file)
Binary files a/UI/WebServerResources/tbtv_minus_17x17.gif and b/UI/WebServerResources/tbtv_minus_17x17.gif differ
index 21eb597d4ec1220cf79701de9c80bdc8bf4fb8da..4722da582b862fa5cbad2e4690c738cc0000cc92 100644 (file)
Binary files a/UI/WebServerResources/tbtv_plus_17x17.gif and b/UI/WebServerResources/tbtv_plus_17x17.gif differ
diff --git a/UI/WebServerResources/tbtv_space_17x17.gif b/UI/WebServerResources/tbtv_space_17x17.gif
new file mode 100644 (file)
index 0000000..13bd3b0
Binary files /dev/null and b/UI/WebServerResources/tbtv_space_17x17.gif differ
index da3c01a774d8cd1ab39c58e142b82c70912974c3..06543b0ab197026fadc8948f5cdada0fe474f33a 100644 (file)
Binary files a/UI/WebServerResources/tbtv_trash_17x17.gif and b/UI/WebServerResources/tbtv_trash_17x17.gif differ
diff --git a/UI/WebServerResources/tentative.png b/UI/WebServerResources/tentative.png
new file mode 100644 (file)
index 0000000..7179364
Binary files /dev/null and b/UI/WebServerResources/tentative.png differ
diff --git a/UI/WebServerResources/uix.css b/UI/WebServerResources/uix.css
deleted file mode 100644 (file)
index 3df8746..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/* SOGo UI Stylesheet */
-
-/* common stuff */
-
-body {
-  color:            #000000;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        10pt;
-  background-color: #FFFFFF;
-  margin:           0px;
-  margin-top:       0px;
-  margin-bottom:    0px;
-  margin-left:      0px;
-  margin-right:     0px;
-}
-
-a:link {
-  color:       #0033CC;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: none;
-}
-a:visited {
-  color:       #660066;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: none;
-}
-a:hover {
-  color:       #FF0000;
-  font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  text-decoration: underline;
-}
-
-.linecolor {
-  background-color: #06348B;
-}
-
-.defaultfont {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #000000;
-}
-
-.window_label {
-  color:            #06348b;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        12pt;
-  font-weight:      bold;
-}
-
-.homepagefont {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        10pt;
-  color:            #000000;
-}
-
-
-/* tabs */
-
-.tab {
-  color:            #000000;
-  background-color: #e8e8e0;
-  font-size:        10pt;
-  text-decoration:  none;
-  width:            100px; 
-  height:           22px;
-  border-top:       1px solid #06348b;
-  border-right:     1px solid #06348b;
-}
-
-.tab a {
-  color:            #000000;
-  border:           none;
-  text-decoration:  none;
-}
-
-.tab_selected {
-  color:            #000000;
-  background-color: #f5f5e9;
-  font-size:        10pt;
-  text-decoration:  none;
-  font-weight:      bold;
-  width:            100px; 
-  height:           22px;
-  border-top:       1px solid #06348b;
-  border-right:     1px solid #06348b;
-}
-
-.tab_selected a {
-  color:            #000000;
-  border:           none;
-  text-decoration:  none;
-}
-
-.tabview_body {
-  background-color: #f5f5e9;
-}
-
-
-/* buttons */
-
-.button_auto_env {
-  height:           16px;
-  text-align:       center;
-  vertical-align:   middle;
-  padding:          0px 0px 0px 0px;
-  margin:           0px 0px 0px 0px;
-  overflow:         hidden;
-}
-
-.button_auto_env a {
-  text-decoration:  none;
-  color:            #000000;
-}
-
-.button_auto_env a:hover {
-  text-decoration:  underline;
-  color:            #ff0000;
-}
-
-.button_auto {
-  height:           20px;
-  border-style:     outset;
-  border-color:     #DDDDDD;
-  border-width:     2px;
-  color:            #000000;
-  background-color: #e8e8e0;
-  font-size:        8pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  letter-spacing:   0pt;
-  text-decoration:  none;
-  color:            #000000;
-  text-align:       center;
-  vertical-align:   middle;
-  padding-left:     5px;
-  padding-right:    5px;
-  padding-top:      1px;
-  padding-bottom:   1px;
-  overflow:         hidden;
-}
-
-.button_submit_env {
-  height:           24px;
-  text-align:       center;
-  vertical-align:   middle;
-  padding:          0px 0px 0px 0px;
-  margin:           0px 0px 0px 0px;
-  overflow:         hidden;
-}
-
-.button_submit_env a {
-  text-decoration:  none;
-  color:            #000000;
-}
-
-.button_submit_env a:hover {
-  text-decoration:  underline;
-  color:            #ff0000;
-}
-
-.button_submit {
-  height:           30px;
-  border-style:     outset;
-  border-color:     #DDDDDD;
-  border-width:     2px;
-  color:            #000000;
-  background-color: #e8e8e0;
-  font-size:        8pt;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  letter-spacing:   0pt;
-  text-decoration:  none;
-  color:            #000000;
-  text-align:       center;
-  vertical-align:   middle;
-  padding-left:     5px;
-  padding-right:    5px;
-  padding-top:      2px;
-  padding-bottom:   3px;
-  overflow:         hidden;
-}
-
-/* header */
-
-div#header {
-  margin-left:  5px;
-  margin-right: 5px;
-  padding:      0;
-  border-bottom: 1px solid #000000;
-}
-div#header img.headerlogo {
-  float:  right; 
-  width:  182px; 
-  height: 30px;
-}
-
-div#header div#headerhistory {
-  font-size:   11px;
-  color:       #000000;
-  margin:      0px;
-  padding-top: 18px;
-  height:      12px;
-}
-div#header a, div#header span {
-  margin:      0px;
-}
-div#header span#navtitle {
-  font-weight: bold;
-}
-div#header a:hover {
-  text-decoration: none;
-}
-
-/* the dock */
-
-a.skydockfont {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #06348B;
-}
-font.skydockfont {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #06348B;
-}
-font.skydockfont_inactiveMail {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #CCCCCC;
-  font-weight:      bold;
-}
-font.skydockfont_newMail {
-  text-decoration:  none;
-  font-family:      Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
-  font-size:        8pt;
-  color:            #06348B;
-  font-weight:      bold;
-}
-table.skytextdocktable {
-  padding:        0px;
-  table-layout:   auto;
-}
diff --git a/UI/WebServerResources/week-view.png b/UI/WebServerResources/week-view.png
new file mode 100644 (file)
index 0000000..eb4703c
Binary files /dev/null and b/UI/WebServerResources/week-view.png differ
diff --git a/UI/WebServerResources/write-message.png b/UI/WebServerResources/write-message.png
new file mode 100644 (file)
index 0000000..461add7
Binary files /dev/null and b/UI/WebServerResources/write-message.png differ
diff --git a/UI/WebServerResources/write.png b/UI/WebServerResources/write.png
new file mode 100644 (file)
index 0000000..152b65e
Binary files /dev/null and b/UI/WebServerResources/write.png differ
index ecb62dbf76d2828846c03bfb88ca9d57363a686b..f1c5fdb8f866ade9ef91d920dd573908286a47a0 100644 (file)
@@ -43,6 +43,6 @@ BUNDLE_LIBS += \
        -lGDLContentStore                       \
        -lGDLAccess                             \
        -lNGObjWeb                              \
-       -lNGMime -lNGiCal -lNGLdap              \
+       -lNGMime -lNGCards -lNGLdap             \
        -lNGStreams -lNGExtensions -lEOControl  \
        -lXmlRpc -lDOM -lSaxObjC
diff --git a/fhswobundle.make b/fhswobundle.make
new file mode 100644 (file)
index 0000000..4afdeef
--- /dev/null
@@ -0,0 +1,35 @@
+# FHS support (this is a hack and is going to be done by gstep-make!)
+
+ifneq ($(FHS_INSTALL_ROOT),)
+
+FHS_INCLUDE_DIR=$(FHS_INSTALL_ROOT)/include/
+FHS_LIB_DIR=$(FHS_INSTALL_ROOT)/lib/
+FHS_SOGOD_DIR=$(FHS_LIB_DIR)sogod-$(MAJOR_VERSION).$(MINOR_VERSION)/
+
+#NONFHS_LIBDIR="$(GNUSTEP_LIBRARIES)/$(GNUSTEP_TARGET_LDIR)/"
+#NONFHS_LIBNAME="$(LIBRARY_NAME)$(LIBRARY_NAME_SUFFIX)$(SHARED_LIBEXT)"
+NONFHS_BINDIR="$(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR)"
+
+
+fhs-sogod-dirs ::
+       $(MKDIRS) $(FHS_SOGOD_DIR)
+
+move-wobundles-to-fhs :: fhs-sogod-dirs
+       @echo "moving wobundles $(WOBUNDLE_INSTALL_DIR) to $(FHS_SOGOD_DIR) .."
+       for i in $(WOBUNDLE_NAME); do \
+          j="$(FHS_SOGOD_DIR)/$${i}$(WOBUNDLE_EXTENSION)"; \
+         if test -d $$j; then rm -r $$j; fi; \
+         (cd $(WOBUNDLE_INSTALL_DIR); \
+           $(TAR) chf - --exclude=CVS --exclude=.svn --to-stdout \
+            "$${i}$(WOBUNDLE_EXTENSION)") | \
+          (cd $(FHS_SOGOD_DIR); $(TAR) xf -); \
+         rm -rf "$(WOBUNDLE_INSTALL_DIR)/$${i}$(WOBUNDLE_EXTENSION)";\
+       done
+
+#        mv "$(WOBUNDLE_INSTALL_DIR)/$${i}$(WOBUNDLE_EXTENSION)" $$j; \
+
+move-to-fhs :: move-wobundles-to-fhs
+
+after-install :: move-to-fhs
+
+endif