--- /dev/null
+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.
Protocols \
include $(GNUSTEP_MAKEFILES)/aggregate.make
+
-lGDLContentStore \
-lGDLAccess \
-lWEExtensions \
- -lNGiCal \
+ -lNGCards \
-lNGObjWeb \
-lNGMime -lNGLdap \
-lNGStreams -lNGExtensions -lEOControl \
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
+ (void)initialize {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+ SoClassSecurityInfo *sInfo;
+ NSArray *basicRoles;
id tmp;
doCrashOnSessionCreate = [ud boolForKey:@"SOGoCrashOnSessionCreate"];
#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 {
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];
/* authenticator */
- (id)authenticatorInContext:(id)_ctx {
- return [SOGoAuthenticator sharedSOGoAuthenticator];
+ return [$(@"SOGoAuthenticator") sharedSOGoAuthenticator];
}
/* name lookup */
}
- (id)lookupUser:(NSString *)_key inContext:(id)_ctx {
- return [[[NSClassFromString(@"SOGoUserFolder") alloc]
+ return [[[$(@"SOGoUserFolder") alloc]
initWithName:_key inContainer:self] autorelease];
}
return lpath;
if (MainProduct == Nil) {
- if ((MainProduct = NSClassFromString(@"MainUIProduct")) == Nil)
+ if ((MainProduct = $(@"MainUIProduct")) == Nil)
[self errorWithFormat:@"did not find MainUIProduct class!"];
}
registry = [SoProductRegistry sharedProductRegistry];
fm = [NSFileManager defaultManager];
-
+
pathes = [[self productSearchPathes] objectEnumerator];
while ((lpath = [pathes nextObject]) != nil) {
NSEnumerator *productNames;
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];
[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];
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
- 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!
+++ /dev/null
-Copyright (C) 2004 SKYRIX Software AG
-
-
-Contact: info@skyrix.com
+++ /dev/null
-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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-# $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
+++ /dev/null
-# $Id$
-
-
--include GNUmakefile.preamble.local
-
-ifeq ($(findstring darwin, $(GNUSTEP_HOST_OS)),)
-ADDITIONAL_OBJCFLAGS += -DWITHOUT_SOPEX
-endif
+++ /dev/null
-<?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>
+++ /dev/null
-# $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
+++ /dev/null
-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
+++ /dev/null
-# $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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-$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
+++ /dev/null
-# $Id$
-
-PROJECTLEAD=helge.hess@opengroupware.org
+++ /dev/null
-$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
-
-
-
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-# $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
-
+++ /dev/null
-// !$*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;
-}
+++ /dev/null
-//
-// 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
+++ /dev/null
-/*
- 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);
-}
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-<?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>
+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-# $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
+++ /dev/null
-# $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
+++ /dev/null
-# $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
+++ /dev/null
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface UIxAppFrame : SoComponent
-@end
-
-#include "common.h"
-
-@implementation UIxAppFrame
-@end /* UIxAppFrame */
+++ /dev/null
-<?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>
+++ /dev/null
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface UIxAppHeader : SoComponent
-@end
-
-#include "common.h"
-
-@implementation UIxAppHeader
-@end /* UIxAppHeader */
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- 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
+++ /dev/null
-<?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
+++ /dev/null
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface UIxAppNavigation : SoComponent
-@end
-
-#include "common.h"
-
-@implementation UIxAppNavigation
-@end /* UIxAppNavigation */
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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__ */
+++ /dev/null
-/*
- 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:@" "];
- [_response appendContentString:@"</div>"];
- }
- else if (isLeftActive)
- [_response appendContentString:@" "];
-
- 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:@" "];
- }
- 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:@" "];
- }
- [_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 */
+++ /dev/null
-/*
- 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
+++ /dev/null
-<?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>
+++ /dev/null
-# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-SUBMINOR_VERSION:=1
-
-# 1.1.0 requires NGObjWeb 4.2.202
+++ /dev/null
-{
- "__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"; },
- );
- };
-}
+++ /dev/null
-.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;
-}
+++ /dev/null
-/*
- 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
+++ /dev/null
-{
- 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";
- };
- };
- };
- };
-}
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-# $Id$
-
-include $(GNUSTEP_MAKEFILES)/common.make
-
-SUBPROJECTS = \
- Common \
- Scheduler \
-
-include $(GNUSTEP_MAKEFILES)/aggregate.make
+++ /dev/null
- 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!
+++ /dev/null
-Copyright (C) 2004 SKYRIX Software AG
-
-
-Contact: info@skyrix.com
+++ /dev/null
-# $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
+++ /dev/null
-# $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
+++ /dev/null
-# $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
+++ /dev/null
-// $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
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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
+++ /dev/null
-// $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__ */
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- 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
+++ /dev/null
-/*
- 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
+++ /dev/null
-<?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
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-// $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__ */
+++ /dev/null
-// $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 */
+++ /dev/null
-/*
- 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
+++ /dev/null
-<?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>
+++ /dev/null
-// $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__ */
+++ /dev/null
-// $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 */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-<?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>
+++ /dev/null
-// $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__ */
+++ /dev/null
-// $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 */
+++ /dev/null
-# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-SUBMINOR_VERSION:=1
-
-# 1.1.0 requires NGObjWeb 4.2.202
+++ /dev/null
-{
- "__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 = (
- );
- };
-}
+++ /dev/null
-/*
- 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>
+++ /dev/null
-{
- 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";
- };
- };
- };
- };
-}
+++ /dev/null
-#!/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()
+++ /dev/null
-# $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---
+++ /dev/null
-#! /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)
+++ /dev/null
-#! /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)
+++ /dev/null
-# 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)
+++ /dev/null
-# 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
+++ /dev/null
-#!/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'")
+++ /dev/null
-#!/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")
+++ /dev/null
-#!/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)
-
+++ /dev/null
-#!/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)
+++ /dev/null
-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();
+++ /dev/null
-#!/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 )
+++ /dev/null
-#!/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 )
+++ /dev/null
-#!/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 )
+++ /dev/null
-Username
-
-Utilisateur-1
- 1000
+++ /dev/null
-#!/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)
+++ /dev/null
-#!/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 ""
-
+++ /dev/null
-#!/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 ""
+++ /dev/null
--- 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 );
-
-
-
+++ /dev/null
--- 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
-
-
+++ /dev/null
-# $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
+++ /dev/null
-# $Id: GNUmakefile.preamble,v 1.1.1.1 2003/07/09 22:57:26 cvs Exp $
-
-ADDITIONAL_TOOL_LIBS += \
- -lNGExtensions \
- -lEOControl
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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
+++ /dev/null
-{
- hostName = "agenor-db";
- userName = "agenor";
- password = "";
- databaseName = "SOGo1";
- port = 5432;
-}
+++ /dev/null
-{
-/*
- 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;
- }
- );
- }
- );
-}
+++ /dev/null
-/*
- @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;
-}
+++ /dev/null
-/*
- @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;
-}
+++ /dev/null
-/*
- @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;
-}
+++ /dev/null
-/*
- @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;
-}
+++ /dev/null
-// !$*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;
-}
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-/*
- 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__ */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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__ */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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__ */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-// $Id$
-
-#include <NGObjWeb/SoComponent.h>
-
-@interface Frame : SoComponent
-@end
-
-#include "common.h"
-
-@implementation Frame
-@end /* Frame */
+++ /dev/null
-<?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>
+++ /dev/null
-# $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
+++ /dev/null
-// $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 */
+++ /dev/null
-<?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>
+++ /dev/null
-# $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.
+++ /dev/null
-# $Id: Version,v 1.1 2003/11/24 01:24:40 helge Exp $
-
-SUBMINOR_VERSION:=1
+++ /dev/null
-/*
- 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>
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-{
- 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 = {
- };
- };
- };
-}
libOGoContentStore_TYPEMODELS += \
appointment.ocs \
- contact.ocs \
-
+ contact.ocs
test_quick_extract_OBJC_FILES += \
test_quick_extract.m
libOGoContentStore_LIBRARIES_DEPEND_UPON += \
-lGDLContentStore \
-lGDLAccess \
- -lNGiCal \
+ -lNGCards \
-lNGExtensions \
-lEOControl \
-lSaxObjC
-lSaxObjC \
-lDOM \
-lNGExtensions \
- -lNGiCal \
+ -lNGCards \
-lGDLContentStore \
-lGDLAccess \
-lOGoContentStore
@interface OCSContactFieldExtractor : GCSFieldExtractor
@end
-#include <NGiCal/NGVCard.h>
+#include <NGCards/NGVCard.h>
#include "common.h"
@implementation OCSContactFieldExtractor
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 {
#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;
/* 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;
[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"]) {
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 {
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];
{
columnName = startdate;
sqlType = "INT";
- allowsNull = NO;
+ allowsNull = YES;
},
{
columnName = enddate;
sqlType = "INT";
- allowsNull = NO;
+ allowsNull = YES;
},
{
columnName = cylceenddate;
{
columnName = participants;
sqlType = "VARCHAR(1000000)";
- allowsNull = NO;
+ allowsNull = YES;
},
{
columnName = isallday;
{
columnName = isopaque;
sqlType = "INT";
- allowsNull = YES;
+ allowsNull = NO;
},
{
columnName = status;
{
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;
+ },
);
}
#ifndef __OGoContentStore_iCalEntityObject_OCS_H_
#define __OGoContentStore_iCalEntityObject_OCS_H_
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
@interface iCalEntityObject (OCS)
#ifndef __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
#define __OGoContentStore_iCalRepeatableEntityObject_OCS_H_
-#include <NGiCal/NGiCal.h>
+#include <NGCards/NGCards.h>
@interface iCalRepeatableEntityObject (OCS)
iCalRecurrenceRule *rule;
rule = [a objectAtIndex:i];
- [ma addObject:[rule iCalRepresentation]];
+ [ma addObject: [rule versitString]];
}
[cycleInfo setObject:ma forKey:@"rules"];
}
iCalRecurrenceRule *rule;
rule = [a objectAtIndex:i];
- [ma addObject:[rule iCalRepresentation]];
+ [ma addObject: [rule versitString]];
}
[cycleInfo setObject:ma forKey:@"exRules"];
}
--- /dev/null
+#!/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
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
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 ...
);
'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' );
# 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
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',
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',
'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;
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,
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 (
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
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
);
--- /dev/null
+#!/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
-lOGoContentStore \
-lGDLAccess \
-lNGObjWeb \
- -lNGMime -lNGiCal -lNGLdap \
+ -lNGMime -lNGCards -lNGLdap \
-lNGStreams -lNGExtensions -lEOControl \
-lXmlRpc -lDOM -lSaxObjC
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 */
- (id)defaultAction {
NSAutoreleasePool *pool;
WOResponse *response;
- SOGoAppointment *event;
+ iCalEvent *event;
NSEnumerator *e;
NSArray *events;
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"];
#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"
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!");
}
- (NSException *)writeNewVEvents:(NSArray *)_events {
SOGoAppointmentFolder *folder;
- iCalRenderer *renderer;
NSException *error;
unsigned i, count;
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: %@",
-# test $Id$
+# $Id$
SOGo
====
Appointments_OBJC_FILES = \
Product.m \
+ NSArray+Appointments.m \
+ iCalEntityObject+Agenor.m \
\
+ SOGoCalendarComponent.m \
SOGoAppointmentObject.m \
+ SOGoTaskObject.m \
SOGoAppointmentFolder.m \
SOGoGroupAppointmentFolder.m \
SOGoFreeBusyObject.m \
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/wobundle.make
-include GNUmakefile.postamble
-include ../../fhsbundle.make
+include ../../fhswobundle.make
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
#ifndef __Appointments_SOGoAppointmentFolder_H__
#define __Appointments_SOGoAppointmentFolder_H__
-#include <SOGo/SOGoFolder.h>
-
/*
SOGoAppointmentFolder
Parent object: the SOGoUserFolder
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
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;
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;
/* 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;
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"];
return [[records objectAtIndex:0] valueForKey:@"c_name"];
}
-- (NSString *)resourceNameForEventUID:(NSString *)_uid {
+- (NSString *) resourceNameForEventUID: (NSString *) _uid
+{
/* caches UIDs */
GCSFolder *folder;
NSString *rname;
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;
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];
}
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];
}
return md;
}
-- (NSMutableDictionary *)fixupCycleRecord:(NSDictionary *)_record
- cycleRange:(NGCalendarDateRange *)_r
+- (NSMutableDictionary *) fixupCycleRecord: (NSDictionary *) _record
+ cycleRange: (NGCalendarDateRange *) _r
{
NSMutableDictionary *md;
id tmp;
/* 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;
return;
}
- row = [self fixupRecord:_row fetchRange:_r];
+ row = [self fixupRecord:_row fetchRange: _r];
[row removeObjectForKey:@"cycleinfo"];
[row setObject:sharedYes forKey:@"isRecurrentEvent"];
}
}
-- (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;
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;
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) {
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;
__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;
/* 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;
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;
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;
return objs;
}
-- (NSArray *)uidsFromICalPersons:(NSArray *)_persons {
+- (NSArray *) uidsFromICalPersons: (NSArray *) _persons
+{
/* Note: can return NSNull objects in the array! */
NSMutableArray *uids;
AgenorUserManager *um;
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;
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)
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)
/* bulk fetches */
-- (NSArray *)fetchAllSOGoAppointments {
+- (NSArray *) fetchAllSOGoAppointments
+{
/*
Note: very expensive method, do not use unless absolutely required.
returns an array of SOGoAppointment objects.
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";
}
#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 */
- (NSException *)changeParticipationStatus:(NSString *)_status
inContext:(id)_ctx;
+
@end
#endif /* __Appointments_SOGoAppointmentObject_H__ */
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];
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;
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];
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;
}
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.
- 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;
/* 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 */
/* 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!"];
/* diff */
- changes = [iCalEventChanges changesFromEvent:[oldApt event]
- toEvent:[newApt event]];
+ changes = [iCalEventChanges changesFromEvent: oldApt
+ toEvent: newApt];
uids = [um getUIDsForICalPersons:[changes deletedAttendees]
applyStrictMapping:NO];
/* preserve organizer */
- organizer = [[newApt event] organizer];
+ organizer = [newApt organizer];
uid = [um getUIDForICalPerson:organizer];
if (uid) {
if (![storeUIDs containsObject:uid])
/* 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]) {
* ... exception from that rule: the organizer
*/
- if (oldApt != nil &&
+ if (oldApt != nil &&
([props containsObject:@"startDate"] ||
[props containsObject:@"endDate"] ||
[props containsObject:@"duration"]))
if (![p hasSameEmailAddress:organizer])
[p setParticipationStatus:iCalPersonPartStatNeedsAction];
}
- _iCal = [newApt iCalString];
+ _iCal = [[newApt parent] versitString];
updateForcesReconsider = YES;
}
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
}
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;
- 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 */
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];
- (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"];
}
[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 */
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;
}
/* generate iCalString once */
- iCalString = [_newApt iCalString];
+ iCalString = [[_newApt parent] versitString];
/* get sendmail object */
sendmail = [NGSendMail sharedSendMail];
[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];
/* 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];
}
}
-- (void)sendInvitationEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendInvitationEMailForAppointment:(iCalEvent *)_apt
toAttendees:(NSArray *)_attendees
{
if (![_attendees count]) return; // another job neatly done :-)
toAttendees:_attendees];
}
-- (void)sendAppointmentUpdateEMailForOldAppointment:(SOGoAppointment *)_oldApt
- newAppointment:(SOGoAppointment *)_newApt
+- (void)sendAppointmentUpdateEMailForOldAppointment:(iCalEvent *)_oldApt
+ newAppointment:(iCalEvent *)_newApt
toAttendees:(NSArray *)_attendees
{
if (![_attendees count]) return;
toAttendees:_attendees];
}
-- (void)sendAttendeeRemovalEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendAttendeeRemovalEMailForAppointment:(iCalEvent *)_apt
toAttendees:(NSArray *)_attendees
{
if (![_attendees count]) return;
toAttendees:_attendees];
}
-- (void)sendAppointmentDeletionEMailForAppointment:(SOGoAppointment *)_apt
+- (void)sendAppointmentDeletionEMailForAppointment:(iCalEvent *)_apt
toAttendees:(NSArray *)_attendees
{
if (![_attendees count]) return;
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 */
+
+
+
#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;
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;
@implementation SOGoAptMailNotification
static NSCharacterSet *wsSet = nil;
-static NSTimeZone *MET = nil;
+static NSTimeZone *EST = nil;
+ (void)initialize {
static BOOL didInit = NO;
didInit = YES;
wsSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] retain];
- MET = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
+ EST = [[NSTimeZone timeZoneWithAbbreviation:@"EST"] retain];
}
- (void)dealloc {
- (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);
}
- (NSTimeZone *)viewTZ {
if (self->viewTZ) return self->viewTZ;
- return MET;
+ return EST;
}
- (void)setViewTZ:(NSTimeZone *)_viewTZ {
ASSIGN(self->viewTZ, _viewTZ);
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
- (NSString *)contentAsStringFrom:(NSCalendarDate *)_startDate
to:(NSCalendarDate *)_endDate;
-- (NSArray *)fetchFreebusyInfosFrom:(NSCalendarDate *)_startDate
+- (NSArray *)fetchFreeBusyInfosFrom:(NSCalendarDate *)_startDate
to:(NSCalendarDate *)_endDate;
@end
*/
// $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;
}
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];
--- /dev/null
+/*
+ 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__ */
--- /dev/null
+/*
+ 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
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" );
+ };
};
};
}
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 \
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
#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
+++ /dev/null
-/*
- 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ 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 */
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__ */
--- /dev/null
+/*
+ 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
#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
+++ /dev/null
-/*
- 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 */
};
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" );
};
};
};
#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;
/* NGMime representations */
-- (NGMimeBodyPart *)bodyPartForText {
+- (NGMimeBodyPart *)bodyPartForText
+{
/*
This add the text typed by the user (the primary plain/text part).
*/
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];
}
}
return bodyPart;
}
-- (NGMimeMessage *)mimeMessageForContentWithHeaderMap:(NGMutableHashMap *)map {
+- (NGMimeMessage *)mimeMessageForContentWithHeaderMap:(NGMutableHashMap *)map
+{
NSDictionary *lInfo;
NGMimeMessage *message;
WOContext *ctx;
/* 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: %@",
}
}
else if (addSuffix)
- body = [fromInternetSuffix dataUsingEncoding:NSUTF8StringEncoding];
+ body = fromInternetSuffix;
message = [[[NGMimeMessage alloc] initWithHeader:map] autorelease];
[message setBody:body];
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 {
/* add subject */
if ([(s = [lInfo objectForKey:@"subject"]) length] > 0)
- [map setObject:s forKey:@"subject"];
+ [map setObject: [s asQPSubjectString] forKey:@"subject"];
/* add standard headers */
+ (void)initialize {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
+ NSString *cfgDraftsFolderName;
NSAssert2([super version] == 1,
@"invalid superclass (%@) version %i !",
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,
// 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;
}
return [[ctx activeUser] fetchAllMailIdentitiesWithOnlyEmitterAccess:_flag];
}
+
- (NSArray *)fetchAllIdentities {
return [self fetchIdentitiesWithOnlyEmitterAccess:NO];
}
+
- (NSArray *)fetchIdentitiesWithEmitterPermissions {
return [self fetchIdentitiesWithOnlyEmitterAccess:YES];
}
ct = [[ctClass alloc] initWithName:_key inContainer:self];
return [ct autorelease];
}
+
- (id)sharedMailAccountWithName:(NSString *)_key inContext:(id)_ctx {
static Class ctClass = Nil;
id ct;
- (NSArray *)toManyRelationshipKeys {
return [[self imap4Connection] subfoldersForURL:[self imap4URL]];
}
+
- (NSArray *)toOneRelationshipKeys {
NSArray *uids;
unsigned count;
- (BOOL)isDeletionAllowed;
- (NSException *)trashInContext:(id)_ctx;
+- (NSException *) moveToFolderNamed: (NSString *) folderName
+ inContext: (id)_ctx;
@end
/* 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;
}
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
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];
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 = {
- (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;
#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)
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";
static unsigned PoolScanInterval = 5 * 60 /* every five minutes */;
-+ (void)initialize {
++ (void) initialize
+{
static BOOL didInit = NO;
NSUserDefaults *ud;
NSString *tmp;
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];
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)
attributes:[self mailServerDiscoveryAttributes]];
while ((entry = [resultEnum nextObject]) != nil) {
- NSString *server, *shareLogin, *emitterAddress;
- id shareUid;
+ NSString *server, *shareLogin;
+ id shareUid, emitterAddress;
/* calculate server connect string */
/* 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 */
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 {
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 \
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
-lOGoContentStore \
-lGDLAccess \
-lNGObjWeb \
- -lNGiCal \
+ -lNGCards \
-lNGMime \
-lNGStreams -lNGExtensions -lEOControl \
-lXmlRpc -lDOM -lSaxObjC \
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
@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;
}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
+++ /dev/null
-/*
- 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_ */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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 */
+++ /dev/null
-/*
- 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_ */
+++ /dev/null
-/*
- 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 */
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
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 */
#ifndef __SOGo_SOGoContentObject_H__
#define __SOGo_SOGoContentObject_H__
-#include <SOGo/SOGoObject.h>
+#import <SOGo/SOGoObject.h>
@class NSString, NSException;
/* 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;
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
#ifndef __SOGo_SOGoFolder_H__
#define __SOGo_SOGoFolder_H__
-#include <SOGo/SOGoObject.h>
+#import "SOGoObject.h"
@class NSString, NSArray, NSDictionary;
@class GCSFolder;
+@class SOGoAclsFolder;
/*
SOGoFolder
- (GCSFolder *)ocsFolder;
/* lower level fetches */
-
- (NSArray *)fetchContentObjectNames;
- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects;
@end
+@interface SOGoFolder (GroupDAVExtensions)
+
+- (NSString *) groupDavResourceType;
+
+@end
+
#endif /* __SOGo_SOGoFolder_H__ */
02111-1307, USA.
*/
+#import <NGObjWeb/SoObject.h>
+
#include "SOGoFolder.h"
#include "common.h"
#include <GDLContentStore/GCSFolderManager.h>
#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 */
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 */
- (NSException *)delete;
- (id)GETAction:(id)_ctx;
+- (SOGoDAVSet *) davCurrentUserPrivilegeSet;
+
/* etag support */
- (NSException *)matchesRequestConditionInContext:(id)_ctx;
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 */
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]])
/* 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];
- (void)sleep {
if ([self doesRetainContainer])
- [self->container release];
- self->container = nil;
+ [container release];
+ container = nil;
}
/* operations */
// default method)
WORequest *rq;
WOResponse *r;
- NSString *uri;
+ NSString *uri;
r = [(WOContext *)_ctx response];
rq = [(WOContext *)_ctx request];
if ((etag = [self davEntityTag]) != nil)
[r setHeader:etag forKey:@"etag"];
+
return r;
}
}
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;
}
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 {
[ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
[self appendAttributesToDescription:ms];
[ms appendString:@">"];
+
return ms;
}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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";
context.activeUser
*/
-@class NSString, NSArray, NSDictionary, NSUserDefaults;
-
-@class NSString, NSArray, NSURL, NSUserDefaults;
+@class NSString, NSArray, NSDictionary, NSURL, NSUserDefaults;
+@class WOContext;
@interface SOGoUser : SoUser
{
- (id)homeFolderInContext:(id)_ctx;
- (id)schedulingCalendarInContext:(id)_ctx;
+- (NSArray *) rolesForObject: (NSObject *) object
+ inContext: (WOContext *) context;
+
@end
#endif /* __SOGoUser_H__ */
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 */
#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
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;
}
-lGDLContentStore \
-lGDLAccess \
-lNGObjWeb \
- -lNGiCal -lNGMime -lNGLdap \
+ -lNGCards -lNGMime -lNGLdap \
-lNGStreams -lNGExtensions -lEOControl \
-lXmlRpc -lDOM -lSaxObjC
/* 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";
/* 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";
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 \
-lNGObjWeb \
-lNGMime \
-lNGStreams -lNGExtensions -lEOControl \
- -lXmlRpc -lDOM -lSaxObjC
+ -lXmlRpc -lDOM -lSaxObjC -lWOExtensions
--- /dev/null
+( /* the toolbar groups -*-cperl-*- */
+ ( { link = "#";
+ isSafe = NO;
+ label = "Close";
+ onclick = "window.close();";
+ image = "tb-mail-stop-flat-24x24.png"; } )
+)
--- /dev/null
+( /* 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"; } )
+)
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
/*
- 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 */
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 */
#include <NGObjWeb/SoComponent.h>
/*
- UIxMailSortableTableHeader
+ UIxSortableTableHeader
TODO: document.
works!
*/
-@interface UIxMailSortableTableHeader : SoComponent
+@interface UIxSortableTableHeader : SoComponent
{
NSString *label;
NSString *sortKey;
#include "common.h"
-@implementation UIxMailSortableTableHeader
+@implementation UIxSortableTableHeader
- (void)dealloc {
[self->label release];
- (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 */
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 */
--- /dev/null
+/* 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
-{
- 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";
+ };
+ };
+ };
};
}
/* 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";
/* 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 à afficher : ";
+"Email Address: " = "Adresse électronique : ";
+"Phone Number: " = "Numéro de téléphone : ";
+
+"Firstname: " = "Prénom : ";
+"Lastname: " = "Nom : ";
+"Nickname: " = "Surnom : ";
+
+"Telephone" = "Téléphone";
+"Work: " = "Travail : ";
+"Home: " = "Domicile : ";
+"Fax: " = "Télécopieur : ";
+"Mobile: " = "Portable : ";
+"Pager: " = "Télé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é";
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 \
--- /dev/null
+( /* 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"; }
+ )
+)
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__ */
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 */
+++ /dev/null
-/*
- 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/*
+ 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 */
*/
// $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
[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 */
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 */
*/
// $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];
}
/*
- 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 */
/*
- 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 */
/*
- 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 */
--- /dev/null
+/*
+ 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 */
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__ */
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 */
+++ /dev/null
-/*
- 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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
/*
- 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 */
+++ /dev/null
-/*
- 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 */
-{
+{ /* -*-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";
+ };
};
- };
- };
+ };
};
}
+
-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é.";
/*
- 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 */
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;
}
--- /dev/null
+/* 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 */
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 */
"Subject" = "Subject";
"Add address" = "Add address";
+"Attachments:" = "Attachments:";
+
"to" = "To";
"cc" = "Cc";
"bcc" = "Bcc";
"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";
"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)";
"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";
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 \
\
UIxFilterList.m \
UIxSieveEditor.m \
\
- UIxMailFolderACLEditor.m \
+ UIxMailFolderACLEditor.m
MailerUI_RESOURCE_FILES += \
Version \
+++ /dev/null
-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.
-
+++ /dev/null
- 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."
-( /* 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"; },
)
)
+++ /dev/null
-( /* 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
+++ /dev/null
-( /* 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"; },
- )
-*/
-)
-( /* 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
+)
+++ /dev/null
-( /* 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
+++ /dev/null
-/*
- 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 */
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
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 */
return;
}
- [self setFrom:[identity email]];
+ [self setFrom: [identity email]];
}
- (SOGoMailIdentity *)selectedMailIdentity {
return @"width: 67%";
return @"width: 100%";
}
+
- (NSString *)initialRightsideStyle {
if ([self hasAttachments])
return @"display: block";
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 */
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 {
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];
@interface UIxMailFilterPanel : WOComponent
{
NSString *searchText;
- struct {
- int hideFrame:1;
- int reserved:31;
- } mfFlags;
+ NSString *searchCriteria;
}
@end
[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;
return q;
}
-- (NSString *)filterLabel {
+- (NSString *)filterLabel
+{
#if 1
return [[[self context] page] labelForKey:[self valueForKey:@"filter"]];
#else
#endif
}
-- (NSString *)selectedFilter {
+- (NSString *)selectedFilter
+{
return [[[self context] request] formValueForKey:@"filterpopup"];
}
-- (EOQualifier *)filterQualifier {
+- (EOQualifier *)filterQualifier
+{
NSString *selectedFilter;
selectedFilter = [self selectedFilter];
? [filterToQualifier objectForKey:selectedFilter] : nil;
}
-- (EOQualifier *)qualifier {
+- (EOQualifier *) qualifier
+{
EOQualifier *sq, *fq;
NSArray *qa;
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
/* configuration */
- (NSTimeZone *)timeZone;
+- (void) setTimeZone: (NSTimeZone *) newTimeZone;
+
- (BOOL)showOnlyTimeForToday;
- (BOOL)showLabelsForNearDays;
/* 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;
}
[self->now setTimeZone:[self timeZone]];
}
[_date setTimeZone:[self timeZone]];
-
+
if ([self showOnlyTimeForToday] && [_date isDateOnSameDay:self->now])
return [self stringForTime:_date prefix:NULL];
/*
- 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 */
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];
[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;
/* 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"];
/* title */
-- (NSString *)objectTitle {
+- (NSString *) objectTitle
+{
return [[self clientObject] nameInContainer];
}
-- (NSString *)panelTitle {
+
+- (NSString *) panelTitle
+{
NSString *s;
s = [self labelForKey:@"View Mail Folder"];
/* 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;
/* fetching messages */
-- (NSArray *)fetchKeys {
+- (NSArray *) fetchKeys
+{
/* Note: see SOGoMailManager.m for allowed IMAP4 keys */
static NSArray *keys = nil;
if (keys == nil) {
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;
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;
return 1;
}
-- (NSArray *)messages {
+- (NSArray *) messages
+{
NSArray *uids;
NSArray *msgs;
NSRange r;
/* 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;
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
/* active message */
-- (SOGoMailObject *)lookupActiveMessage {
+- (SOGoMailObject *) lookupActiveMessage
+{
NSString *uid;
if ((uid = [[[self context] request] formValueForKey:@"uid"]) == nil)
/* 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];
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)
return [self redirectToLocation:@"view"];
}
-- (id)markMessageReadAction {
+
+- (id) markMessageReadAction
+{
NSException *error;
if ((error = [[self lookupActiveMessage] addFlags:@"seen"]) != nil)
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;
return [self redirectToLocation:@"view"];
}
-- (id)emptyTrashAction {
+- (id) emptyTrashAction
+{
// TODO: we might want to flush the caches?
NSException *error;
id client;
/* folder operations */
-- (id)createFolderAction {
+- (id) createFolderAction
+{
NSException *error;
NSString *folderName;
id client;
return [self redirectToLocation:[folderName stringByAppendingString:@"/"]];
}
-- (id)deleteFolderAction {
+- (id) deleteFolderAction
+{
NSException *error;
NSString *url;
id client;
return [self redirectToLocation:url];
}
-@end /* UIxMailListView */
+@end
+
+/* UIxMailListView */
--- /dev/null
+/* 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 */
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
}
- (void)dealloc {
- [self->item release];
- [self->title release];
[self->rootURL release];
[self->userRootURL release];
[super dealloc];
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;
}
- (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?
- (NSString *)calendarRootURL {
return [[self userRootURL] stringByAppendingString:@"Calendar/"];
}
+
- (NSString *)contactsRootURL {
return [[self userRootURL] stringByAppendingString:@"Contacts/"];
}
@"</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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
/* 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;
}
_cc = [self properlySplitAddresses:_cc];
ASSIGNCOPY(self->cc, _cc);
}
+
- (NSArray *)cc {
return self->cc;
}
--- /dev/null
+/* 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 */
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";
}
[self logWithFormat:@"to-many: %@ %@", _object,
[names componentsJoinedByString:@","]];
}
-
+
count = [names count];
ma = [NSMutableArray arrayWithCapacity:(count + 1)];
for (i = 0; i < count; i++) {
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;
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;
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.
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;
}
UIxMailTreeBlock *md;
NSMutableArray *blocks;
NSArray *folders;
- NSString *title, *icon;
+ NSString *title, *icon, *ft;
unsigned i, count;
if (debugBlocks) {
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];
}
/* 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)
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
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
NSMutableArray *blocks;
NSString *activeName;
NSArray *folders;
- NSString *title, *icon;
+ NSString *title, *icon, *ft;
unsigned i, count;
activeName = [_activeChildBlock valueForKey:@"name"];
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];
}
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 */
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;
}
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 {
NSString *link;
NSArray *blocks;
NSString *iconName;
+ NSString *folderType;
+ int serial;
+ int parent;
struct {
int isPath:1;
int isActive:1;
} 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
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];
/* 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;
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];
[_ms appendFormat:@" children=%@", self->blocks];
}
-- (NSString *)description {
+- (NSString *) description
+{
NSMutableString *ms;
ms = [NSMutableString stringWithCapacity:64];
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 */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
02111-1307, USA.
*/
+#import <Foundation/NSException.h>
+#import <NGExtensions/NSException+misc.h>
+
#include <SOGoUI/UIxComponent.h>
@interface UIxMailView : UIxComponent
}
- (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;
return [self isTrashingAllowed] ? NO : YES;
}
-- (BOOL)showTrashButton {
+- (BOOL) showTrashButton
+{
if (![[self clientObject] isDeletionAllowed])
return NO;
id info;
info = [[self clientObject] bodyStructure];
- return [[[self context] mailRenderingContext] viewerForBodyInfo:info];
+ return [[context mailRenderingContext] viewerForBodyInfo:info];
}
/* actions */
*/
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];
reason:@"message got deleted"];
}
- [[[self context] response] setStatus:304 /* Not Modified */];
- return [[self context] response];
+ [[context response] setStatus:304 /* Not Modified */];
+ return [context response];
}
}
}
- (id)redirectToParentFolder {
id url;
- url = [[[self clientObject] container] baseURLInContext:[self context]];
+ url = [[[self clientObject] container] baseURLInContext:context];
return [self redirectToLocation:url];
}
[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;
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]) {
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 */
#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 {
-{
+{ /* -*-cperl-*- */
requires = ( MAIN, CommonUI, Mailer, Sieve );
publicResources = (
"UIxMailToSelection.js",
"lori_32x32.png",
-
+
"tbtv_account_17x17.gif",
"tbtv_drafts_17x17.gif",
"tbtv_inbox_17x17.gif",
"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";
};
};
"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 ";
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
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;
}
}
- (NSString *)relativeMailPath {
- return [self relativePathToUserFolderSubPath:@"Mail/"];
+ return [NSString stringWithFormat: @"%@%@/view",
+ [self relativePathToUserFolderSubPath:@"Mail/"],
+ [self emailForUser]];
}
/* objects */
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 */
+++ /dev/null
-<?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>
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";
*/
};
};
-
SOGoGroupsFolder = {
- superclass = "SOGoObject";
methods = {
index = {
protectedBy = "View";
};
};
SOGoGroupFolder = {
- superclass = "SOGoObject";
methods = {
index = {
protectedBy = "View";
};
};
};
+ SOGoFreeBusyObject = {
+ methods = {
+ ajaxRead = {
+ protectedBy = "View";
+ pageName = "SOGoUserHomePage";
+ actionName = "readFreeBusy";
+ };
+ };
+ };
SOGoCustomGroupFolder = {
- superclass = "SOGoGroupFolder";
methods = {
};
};
# GNUstep makefile
+include ../common.make
-include ../../config.make
include $(GNUSTEP_MAKEFILES)/common.make
include ../../Version
FHS_HEADER_DIRS = SOGoUI
libSOGoUI_HEADER_FILES += \
+ \
UIxComponent.h \
SOGoDateFormatter.h \
SOGoAptFormatter.h \
WOContext+UIx.h \
libSOGoUI_OBJC_FILES += \
+ \
UIxComponent.m \
SOGoDateFormatter.m \
SOGoAptFormatter.m \
-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
- (void)setFullDetails;
- (void)setTitleOnly;
- (void)setShortTitleOnly;
+- (void)setShortMonthTitleOnly;
- (void)setOmitsEndDate;
- (void)setPrivateTooltip;
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 @"";
}
#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_ */
#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 {
#ifndef __UIxComponent_H_
#define __UIxComponent_H_
-#include <NGObjWeb/SoComponent.h>
+#import <NGObjWeb/SoComponent.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+
+#import <SOGo/SOGoObject.h>
/*
UIxComponent
@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;
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;
@implementation UIxComponent
-static NSTimeZone *MET = nil;
-static NSTimeZone *GMT = nil;
-
static NSMutableArray *dayLabelKeys = nil;
static NSMutableArray *abbrDayLabelKeys = nil;
static NSMutableArray *monthLabelKeys = nil;
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"];
}
}
-- (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];
return self->queryParameters;
}
-- (NSDictionary *)queryParameters {
+- (NSDictionary *) queryParameters
+{
return [self _queryParameters];
}
-- (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date{
+- (NSDictionary *) queryParametersBySettingSelectedDate: (NSCalendarDate *) _date
+{
NSMutableDictionary *qp;
qp = [[self queryParameters] mutableCopy];
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;
/* 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;
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;
/* 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)
/* 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!"];
#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];
}
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 {
/* 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";
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";
+++ /dev/null
-<!--
-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> ':'')+'<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?' <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>
-
"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";
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";
+++ /dev/null
-<!--
-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> ':'')+'<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?' <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>
-
+++ /dev/null
-// 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;
-}
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 \
# 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
ADDITIONAL_INCLUDE_DIRS += \
-I.. -I../.. -I../../..
-
[SoComponent]
UIxAppointmentView
UIxCalView
- UIxCalMonthView
+ UIxCalMonthViewOld
UIxCalMonthOverview
+ UIxCalMonthView
UIxCalWeekView
UIxCalWeekOverview
UIxCalWeekPrintview
+++ /dev/null
-/*
- 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__ */
+++ /dev/null
-/*
- 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) */
+++ /dev/null
-/*
- 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_ */
--- /dev/null
+( /* 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"; } )
+)
--- /dev/null
+( /* the toolbar groups -*-cperl-*- */
+ ( { link = "#";
+ isSafe = NO;
+ label = "Save";
+ onclick = "return saveEvent(this);";
+ image = "tb-compose-save-flat-24x24.png"; } )
+)
--- /dev/null
+( /* the toolbar groups -*-cperl-*- */
+ ( { link = "#";
+ isSafe = NO;
+ label = "accept";
+ onclick = "return modifyEvent(this, 'accept');";
+ image = "tb-ab-properties-flat-24x24.png"; } )
+)
--- /dev/null
+( /* 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"; } )
+)
--- /dev/null
+( /* the toolbar groups -*-cperl-*- */
+ ( { link = "#";
+ isSafe = NO;
+ label = "decline";
+ onclick = "return modifyEvent(this, 'decline');";
+ image = "tb-mail-stop-flat-24x24.png"; } )
+)
--- /dev/null
+/* 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 */
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 */
+++ /dev/null
-/*
- 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 */
#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];
}
}
#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;
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 :-) */
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
@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;
}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
@interface UIxCalDayView : UIxCalView
{
- NSCalendarDate *currentDate;
+ NSCalendarDate *currentDate;
}
- (void)setCurrentDate:(NSCalendarDate *)_date;
*/
// $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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 */
*/
// $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
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 */
// $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
/* binding accessors */
- (void)setSelectedDate:(NSCalendarDate *)_date {
- [_date setTimeZone:[self viewTimeZone]];
+ [_date setTimeZone:[[self clientObject] userTimeZone]];
ASSIGN(self->selectedDate, _date);
}
- (NSCalendarDate *)selectedDate {
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
// $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
- (NSArray *)appointments {
- return [self fetchCoreInfos];
+ return [self fetchCoreAppointmentsInfos];
}
@end /* UIxCalMonthOverview */
+++ /dev/null
-/*
- 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
-// $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 */
-// $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
--- /dev/null
+// $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__ */
--- /dev/null
+// $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 */
@end
-#include <NGiCal/NGiCal.h> /* for iCalPersonPartStat */
+#include <NGCards/NGCards.h> /* for iCalPersonPartStat */
#include "common.h"
@implementation UIxCalParticipationStatusView
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];
}
- (void)setCurrentDate:(NSCalendarDate *)_date {
- [_date setTimeZone:[self viewTimeZone]];
+ [_date setTimeZone:[[self clientObject] userTimeZone]];
ASSIGN(self->currentDate, _date);
}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
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;
- (id)holidayInfo;
-
/* related to current day */
- (void)setCurrentDay:(NSCalendarDate *)_day;
- (NSCalendarDate *)currentDay;
- (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__ */
// $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";
/* 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;
}
/* 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 */
@implementation UIxCalWeekOverview
+- (id) correctURLAction
+{
+ return [self redirectToLocation: @"weekoverview"];
+}
+
- (void)configureFormatters {
[super configureFormatters];
+++ /dev/null
-/*
- 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
-// $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
-// $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 */
- (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;
#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_ */
@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];
}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
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 */
+++ /dev/null
-/*
- 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ 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 */
--- /dev/null
+/*
+ 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 */
--- /dev/null
+// $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__ */
--- /dev/null
+/*
+ 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 */
--- /dev/null
+/*
+ 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 */
*/
// $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 */
+++ /dev/null
-/*
- 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 */
#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>
+++ /dev/null
-/*
- 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__ */
+++ /dev/null
-/*
- 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) */
+++ /dev/null
-/*
- 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) */
{
- 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";
+ };
};
};
};
+++ /dev/null
-// 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;
-}
<?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>
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+ <container />
--- /dev/null
+<?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>
<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
clean ::
distclean :: clean
+
+uninstall ::
<?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>
<?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>
+++ /dev/null
-<?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>
<?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>
<?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>
<?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>
--- /dev/null
+<?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>
<?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>
<?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>
</var:foreach>
<option value="all" disabled="1" >All</option>
-</select>
\ No newline at end of file
+</select>
+++ /dev/null
-<?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>
--- /dev/null
+<?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>
+++ /dev/null
-<?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
--- /dev/null
+<?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>
<?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>
+
+++ /dev/null
-<?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>
<?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>
--- /dev/null
+<?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>
<?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>
xmlns:uix="OGo:uix"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label"
- className="UIxMailMainFrame"
+ className="UIxPageFrame"
title="panelTitle"
const:hideFolderTree="1"
>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
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>
--- /dev/null
+<?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>
<?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>
--- /dev/null
+<?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>
<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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
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">
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>
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">
/>
</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>
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">
/>
</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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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
+++ /dev/null
-<?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
+++ /dev/null
-<?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>
+++ /dev/null
-<?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
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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
+++ /dev/null
-<?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
+++ /dev/null
-<?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
--- /dev/null
+<?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>
--- /dev/null
+<?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>
<?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>
+
--- /dev/null
+<?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>
+++ /dev/null
-<?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>
+++ /dev/null
-<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<span>dong dong</span>
+
--- /dev/null
+/*
+ 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; }
--- /dev/null
+/*
+ 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);
--- /dev/null
+/* 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();
+ }
+}
--- /dev/null
+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);
+}
--- /dev/null
+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();
+}
--- /dev/null
+HTMLUListElement.prototype.getSelectedRows = function() {
+ return this.getSelectedNodes();
+}
+
+HTMLUListElement.prototype.getSelectedRowsId = function() {
+ return this.getSelectedNodesId();
+}
--- /dev/null
+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);
+}
--- /dev/null
+/*
+ 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;
+}
--- /dev/null
+/*
+ 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\ _-]+)\ (<|<)/;
+ 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);
--- /dev/null
+/* 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;
+ }
+}
--- /dev/null
+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;';
+ }
+ }
+ }
+
+};
+
--- /dev/null
+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%; }
--- /dev/null
+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);
--- /dev/null
+/* 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; }
--- /dev/null
+/* 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;
+}
--- /dev/null
+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; }
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
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;
}
}
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);
+}
--- /dev/null
+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; }
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)
// 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;
+}
--- /dev/null
+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);
--- /dev/null
+/* 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; }
--- /dev/null
+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 = "";
+}
+++ /dev/null
-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);
-}
}
function hasAddress(email) {
- var e = document.getElementById(email);
+ var e = $(email);
if(e)
return true;
return false;
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);
if(this.hasAddress(email))
return;
- e = document.getElementById('addr_0');
+ e = $('addr_0');
if(e.value == '') {
e.value = s;
shouldAddRow = false;
}
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) {
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];
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;
var idx, input;
idx = addressIDs[i];
- input = document.getElementById('addr_' + idx);
- if (input.value != '')
+ input = $('addr_' + idx);
+ if (input && input.value != '')
addressCount++;
}
return addressCount;
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 */
+
--- /dev/null
+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; }
--- /dev/null
+/*
+ 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);
+}
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;
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;
--- /dev/null
+/*--------------------------------------------------|
+| 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; }
--- /dev/null
+/*--------------------------------------------------|
+ | 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;
+ }
+};
+
--- /dev/null
+/* 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; }
/* 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;
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, "&");
- s = s.replace(/</g, "<");
- s = s.replace(/>/g, ">");
- s = s.replace(/"/g, """);
- return s;
+function extractEmailName(mailTo) {
+ var emailName = "";
+
+ var emailNamere = /(\w[\w\ _-]+)\ (<|<)/;
+ if (emailNamere.test(mailTo)) {
+ emailNamere.exec(mailTo);
+ emailName = RegExp.$1;
+ }
}
-function unescapeHTML(s) {
- s = s.replace(/</g, "<");
- s = s.replace(/>/g, ">");
- s = s.replace(/"/g, '"');
- s = s.replace(/&/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() {
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) {
if (s.charAt(0) == "?") s = s.substr(1, s.length - 1);
return s.split("&");
}
+
function getQueryParaValue(s, name) {
var t;
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");
+}
+++ /dev/null
-/* 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;
-}
/* 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;
}
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;
}
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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;
-}
--- /dev/null
+/* 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
// 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)
// 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());
? 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());
+++ /dev/null
-/* 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;
-}
-lGDLContentStore \
-lGDLAccess \
-lNGObjWeb \
- -lNGMime -lNGiCal -lNGLdap \
+ -lNGMime -lNGCards -lNGLdap \
-lNGStreams -lNGExtensions -lEOControl \
-lXmlRpc -lDOM -lSaxObjC
--- /dev/null
+# 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