+2007-03-22 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage
+ -defaultAction]): remade module to redirect automatically to the
+ Calendar url.
+
+ * SoObjects/Contacts/NSDictionary+Contact.m: removed module.
+
+2007-03-21 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/Contacts/UIxContactsListView.m ([UIxContactsListView
+ -deleteAction]): new web method to delete personal addressbook
+ folders.
+
+ * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder
+ -delete]): override method to refuse the deletion of the folder if
+ its nameInContainer is "personal".
+
+ * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder -delete]): new method
+ that forwards the deletion request to the folder manager.
+
+2007-03-19 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/Scheduler/UIxAttendeesEditor.m ([UIxAttendeesEditor
+ -zoomList]): new method that returns the list of available zoom factors.
+
+ * UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor
+ -changeStatusAction]): rewrote method.
+
+ * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
+ -_handleAttendeesEdition]): make sure "attendeesNames" has a
+ length > 0 before computing the attendees. Otherwise there will be
+ an invalid empty entry.
+ ([UIxComponentEditor -_handleOrganizer]): new method that adds the
+ organizer when there are attendees and remove it when the
+ attendees are removed.
+
+2007-03-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/Scheduler/UIxAttendeesEditor.m): new component.
+
+ * UI/Scheduler/UIxComponentEditor.m: no longer a superclass for
+ the task and appointment editors. Now a container component
+ handling the common elements of tasks and events.
+
+ * UI/Scheduler/UIxTaskEditor.m: same as below.
+
+ * UI/Scheduler/UIxAppointmentEditor.m: rewrote template. No longer
+ a subclass of UIxComponentEditor but a subcomponent of it.
+
+ * UI/Common/UIxToolbar.m ([UIxToolbar -toolbarConfig]): the
+ toolbar can have the special value "none" to indicate there is
+ none attached to the window.
+
+ * SoObjects/Appointments/SOGoCalendarComponent.m
+ ([SOGoCalendarComponent -isOrganizer:emailorOwner:login]): new
+ method.
+ ([SOGoCalendarComponent -isParticipant:email]): new method.
+ ([SOGoCalendarComponent -calendar:create]): takes one parameter
+ "create" which is a boolean indicating whether we want to create
+ the calendar if it does not exist.
+
2007-03-12 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/Scheduler/UIxCalMonthView.m: changed view to use divs instead
{
NSString *currentString, *resultString, *cmpString;
unsigned int count, max;
- BOOL found;
- found = NO;
+ resultString = nil;
- cmpString = [aString uppercaseString];
max = [self count];
count = 0;
+ cmpString = [aString uppercaseString];
- currentString = nil;
- while (!found && count < max)
+ while (!resultString && count < max)
{
currentString = [self objectAtIndex: count];
if ([[currentString uppercaseString] isEqualToString: cmpString])
- found = YES;
+ resultString = currentString;
else
count++;
}
- if (found)
- resultString = currentString;
- else
- resultString = nil;
-
return resultString;
}
- (void) setTimeStampAsDate: (NSCalendarDate *)_date;
- (NSCalendarDate *) timeStampAsDate;
-- (void)setStartDate:(NSCalendarDate *)_date;
-- (NSCalendarDate *)startDate;
+- (void) setStartDate: (NSCalendarDate *) _date;
+- (NSCalendarDate *) startDate;
- (BOOL) hasStartDate;
-- (void)setLastModified:(NSCalendarDate *)_value;
-- (NSCalendarDate *)lastModified;
+- (void) setLastModified: (NSCalendarDate *) _value;
+- (NSCalendarDate *) lastModified;
-- (void)setCreated:(NSCalendarDate *)_value;
-- (NSCalendarDate *)created;
+- (void) setCreated: (NSCalendarDate *) _value;
+- (NSCalendarDate *) created;
-- (void)setSequence:(NSNumber *)_value; /* this is an int */
-- (NSNumber *)sequence;
-- (void)increaseSequence;
+- (void) setSequence: (NSNumber *) _value; /* this is an int */
+- (NSNumber *) sequence;
+- (void) increaseSequence;
/* url can either be set as NSString or NSURL */
-- (void)setUrl:(id)_value;
-- (NSURL *)url;
+- (void) setUrl: (id) _value;
+- (NSURL *) url;
-- (void)setOrganizer:(iCalPerson *)_organizer;
-- (iCalPerson *)organizer;
+- (void) setOrganizer: (iCalPerson *) _organizer;
+- (iCalPerson *) organizer;
- (BOOL)isOrganizer:(id)_email;
-- (void)setStatus:(NSString *)_value;
-- (NSString *)status;
+- (void) setStatus: (NSString *) _value;
+- (NSString *) status;
-- (void)removeAllAttendees;
-- (void)addToAttendees:(iCalPerson *)_person;
-- (NSArray *)attendees;
+- (void) removeAllAttendees;
+- (void) addToAttendees: (iCalPerson *) _person;
+- (NSArray *) attendees;
- (void) setAttendees: (NSArray *) attendees;
/* categorize attendees into participants and resources */
-- (NSArray *)participants;
-- (NSArray *)resources;
-- (BOOL)isParticipant:(id)_email;
-- (iCalPerson *)findParticipantWithEmail:(id)_email;
+- (NSArray *) participants;
+- (NSArray *) resources;
+- (BOOL) isParticipant: (id) _email;
+- (iCalPerson *) findParticipantWithEmail: (id) _email;
-- (void)removeAllAlarms;
-- (void)addToAlarms:(id)_alarm;
-- (NSArray *)alarms;
-- (BOOL)hasAlarms;
+- (void) removeAllAlarms;
+- (void) addToAlarms: (id) _alarm;
+- (NSArray *) alarms;
+- (BOOL) hasAlarms;
@end
*/
#import <GDLContentStore/GCSFolder.h>
-#import <SaxObjC/SaxObjC.h>
#import <NGCards/NGCards.h>
#import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOMessage.h>
#import <NGExtensions/NGCalendarDateRange.h>
+#import <SaxObjC/SaxObjC.h>
+#import <SaxObjC/XMLNamespaces.h>
// #import <NGObjWeb/SoClassSecurityInfo.h>
#import <SOGo/SOGoCustomGroupFolder.h>
NSString *s;
s = [[self container] nameInContainer];
+#warning HH DEBUG
+ [self logWithFormat:@"CAL UID: %@", s];
return [s isNotNull] ? [NSArray arrayWithObjects:&s count:1] : nil;
}
return @"vevent-collection";
}
+- (NSArray *) davResourceType
+{
+ static NSArray *colType = nil;
+ NSArray *gdCol, *cdCol;
+
+ if (!colType)
+ {
+ cdCol = [NSArray arrayWithObjects: @"calendar", XMLNS_CALDAV, nil];
+ gdCol = [NSArray arrayWithObjects: [self groupDavResourceType],
+ XMLNS_GROUPDAV, nil];
+ colType = [NSArray arrayWithObjects: @"collection", cdCol, gdCol, nil];
+ [colType retain];
+ }
+
+ return colType;
+}
+
/* vevent UID handling */
- (NSString *) resourceNameForEventUID: (NSString *)_u
- send iMIP mail for all folders not found
*/
AgenorUserManager *um;
- iCalCalendar *newCalendar;
iCalEvent *oldApt, *newApt;
iCalEventChanges *changes;
iCalPerson *organizer;
updateForcesReconsider = NO;
- if ([_iCal length] == 0) {
- return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
- reason:@"got no iCalendar content to store!"];
- }
+ if ([_iCal length] == 0)
+ return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
+ reason: @"got no iCalendar content to store!"];
um = [AgenorUserManager sharedUserManager];
oldApt = nil;
}
else
- oldApt = (iCalEvent *) [self component];
+ oldApt = (iCalEvent *) [self component: NO];
/* compare sequence if requested */
// TODO
}
-
/* handle new content */
- newCalendar = [iCalCalendar parseSingleFromSource: _iCal];
- newApt = (iCalEvent *) [newCalendar firstChildWithTag: [self componentTag]];
- if (newApt == nil) {
- return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
- reason:@"could not parse iCalendar content!"];
- }
-
+ newApt = (iCalEvent *) [self component: NO];
+ if (!newApt)
+ return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
+ reason: @"could not parse iCalendar content!"];
+
/* diff */
- changes = [iCalEventChanges 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];
+ changes = [iCalEventChanges 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 */
/* preserve organizer */
organizer = [newApt organizer];
- uid = [um getUIDForICalPerson:organizer];
+ uid = [um getUIDForICalPerson: organizer];
+ if (!uid)
+ uid = [self ownerInContext: nil];
if (uid) {
if (![storeUIDs containsObject:uid])
[storeUIDs addObject:uid];
*/
if (oldApt != nil &&
- ([props containsObject:@"startDate"] ||
- [props containsObject:@"endDate"] ||
- [props containsObject:@"duration"]))
+ ([props containsObject: @"startDate"] ||
+ [props containsObject: @"endDate"] ||
+ [props containsObject: @"duration"]))
{
NSArray *ps;
unsigned i, count;
/* perform storing */
- storeError = [self saveContentString:_iCal inUIDs:storeUIDs];
- delError = [self deleteInUIDs:removedUIDs];
+ storeError = [self saveContentString: _iCal inUIDs: storeUIDs];
+ delError = [self deleteInUIDs: removedUIDs];
// TODO: make compound
if (storeError != nil) return storeError;
/* load existing content */
- apt = (iCalEvent *) [self component];
+ apt = (iCalEvent *) [self component: NO];
/* compare sequence if requested */
ex = nil;
// TODO: do we need to use SOGoAppointment? (prefer iCalEvent?)
- apt = (iCalEvent *) [self component];
+ apt = (iCalEvent *) [self component: NO];
if (apt)
{
{
iCalCalendar *calendar;
NSString *calContent;
+ BOOL isNew;
}
- (NSString *) componentTag;
-- (iCalCalendar *) calendar;
-- (iCalRepeatableEntityObject *) component;
+- (iCalCalendar *) calendar: (BOOL) create;
+- (iCalRepeatableEntityObject *) component: (BOOL) create;
+- (BOOL) isNew;
- (NSException *) primarySaveContentString: (NSString *) _iCalString;
- (NSException *) primaryDelete;
andNewObject: (iCalRepeatableEntityObject *) _newObject
toAttendees: (NSArray *) _attendees;
+- (BOOL) isOrganizer: (NSString *) email
+ orOwner: (NSString *) login;
+- (BOOL) isParticipant: (NSString *) email;
+
@end
#endif /* SOGOCALENDARCOMPONENT_H */
{
calendar = nil;
calContent = nil;
+ isNew = NO;
}
return self;
return result;
}
-- (iCalCalendar *) calendar
+- (iCalCalendar *) calendar: (BOOL) create
{
- NSString *iCalString;
+ NSString *iCalString, *componentTag;
+ CardGroup *newComponent;
if (!calendar)
{
iCalString = [self contentAsString];
- if (iCalString)
+ if ([iCalString length] > 0)
+ calendar = [iCalCalendar parseSingleFromSource: iCalString];
+ else
{
- calendar = [iCalCalendar parseSingleFromSource: iCalString];
- [calendar retain];
+ if (create)
+ {
+ calendar = [iCalCalendar groupWithTag: @"vcalendar"];
+ [calendar setVersion: @"2.0"];
+ [calendar setProdID: @"-//Inverse groupe conseil//SOGo 0.9//EN"];
+ componentTag = [[self componentTag] uppercaseString];
+ newComponent = [[calendar classForTag: componentTag]
+ groupWithTag: componentTag];
+ [calendar addChild: newComponent];
+ isNew = YES;
+ }
}
+ if (calendar)
+ [calendar retain];
}
return calendar;
}
-- (iCalRepeatableEntityObject *) component
+- (iCalRepeatableEntityObject *) component: (BOOL) create
{
return (iCalRepeatableEntityObject *)
- [[self calendar]
+ [[self calendar: create]
firstChildWithTag: [self componentTag]];
}
+- (BOOL) isNew
+{
+ return isNew;
+}
+
/* raw saving */
- (NSException *) primarySaveContentString: (NSString *) _iCalString
um = [AgenorUserManager sharedUserManager];
email = [um getEmailForUID: login];
- component = [self component];
+ component = [self component: NO];
if (component)
{
if ([component isOrganizer: email])
return sogoRoles;
}
+- (BOOL) isOrganizer: (NSString *) email
+ orOwner: (NSString *) login
+{
+ BOOL isOrganizerOrOwner;
+ iCalRepeatableEntityObject *component;
+ NSString *organizerEmail;
+
+ component = [self component: NO];
+ organizerEmail = [[component organizer] rfc822Email];
+ if (component && [organizerEmail length] > 0)
+ isOrganizerOrOwner
+ = ([organizerEmail caseInsensitiveCompare: email] == NSOrderedSame);
+ else
+ isOrganizerOrOwner
+ = [[container ownerInContext: nil] isEqualToString: login];
+
+ return isOrganizerOrOwner;
+}
+
+- (BOOL) isParticipant: (NSString *) email
+{
+ BOOL isParticipant;
+ iCalRepeatableEntityObject *component;
+
+ component = [self component: NO];
+ if (component)
+ isParticipant = [component isParticipant: email];
+ else
+ isParticipant = NO;
+
+ return isParticipant;
+}
+
@end
/* load existing content */
- task = (iCalToDo *) [self component];
+ task = (iCalToDo *) [self component: NO];
/* compare sequence if requested */
NSString *myEMail;
// TODO: do we need to use SOGoTask? (prefer iCalToDo?)
- task = (iCalToDo *) [self component];
+ task = (iCalToDo *) [self component: NO];
if (task == nil) {
return [NSException exceptionWithHTTPStatus:500 /* Server Error */
SOGoContactLDAPEntry.m \
SOGoContactLDAPFolder.m \
\
- NSDictionary+Contact.m \
NGLdapEntry+Contact.m \
Contacts_RESOURCE_FILES += \
+++ /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
return @"vcard-collection";
}
+- (NSException *) delete
+{
+ return (([nameInContainer isEqualToString: @"personal"])
+ ? [NSException exceptionWithHTTPStatus: 403
+ reason: @"the 'personal' folder cannot be deleted"]
+ : [super delete]);
+}
+
// /* GET */
// - (id) GETAction: (id)_ctx
#include <NGCards/NGCards.h>
#include "SOGoLRUCache.h"
+#warning we should rely on the LDAP sources instead...
+#define qualifierFormat @"mailNickname = %@"
+
@interface AgenorUserManager (PrivateAPI)
- (NGLdapConnection *)ldapConnection;
return uid;
}
-- (NSString *)getUIDForEmail:(NSString *)_email {
+- (NSString *) getUIDForEmail: (NSString *)_email
+{
NSString *uid;
-
- if ((uid = [self _cachedUIDForEmail:_email]) != nil)
- return uid;
-
- if (useLDAP) {
- uid = [self primaryGetAgenorUIDForEmail:_email];
- }
- else {
- NSRange r;
- NSString *domain;
-
- if(!_email || [_email length] == 0)
- return nil;
-
- r = [_email rangeOfString:@"@"];
- if (r.length == 0)
- return nil;
+ NSRange r;
+ NSString *domain;
+
+ uid = nil;
+ if ([_email length] > 0)
+ {
+ uid = [self _cachedUIDForEmail:_email];
+ if (!uid)
+ {
+ if (useLDAP)
+ uid = [self primaryGetAgenorUIDForEmail:_email];
+
+ if (!uid)
+ {
+ r = [_email rangeOfString:@"@"];
+ if (r.length == 0)
+ return nil;
- domain = [_email substringFromIndex:NSMaxRange(r)];
- if (![domain isEqualToString:defaultMailDomain])
- uid = _email;
- else
- uid = [_email substringToIndex:r.location];
- }
+ domain = [_email substringFromIndex:NSMaxRange(r)];
+ if (![domain isEqualToString:defaultMailDomain])
+ uid = _email;
+ else
+ uid = [_email substringToIndex:r.location];
+ }
+ if (uid)
+ [self _cacheUID:uid forEmail:_email];
+ }
+ }
- [self _cacheUID:uid forEmail:_email];
return uid;
}
-- (NSString *)getUIDForICalPerson:(iCalPerson *)_person {
- return [self getUIDForEmail:[_person rfc822Email]];
+#warning big ugly hack. LDAP lookup should be fixed
+- (NSString *) getUIDForICalPerson: (iCalPerson *) _person
+{
+ NSString *domainString, *email, *uid;
+
+ domainString = [NSString stringWithFormat: @"@%@", defaultMailDomain];
+ email = [_person rfc822Email];
+ if ([email hasSuffix: domainString])
+ uid = [_person cn];
+ else
+ uid = [self getUIDForEmail: email];
+
+ return uid;
}
/* may insert NSNulls into returned array */
NSString *email;
unsigned count;
- q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid];
+ q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
return email;
}
-- (NSString *)getEmailForUID:(NSString *)_uid {
+- (NSString *)getEmailForUID:(NSString *)_uid
+{
NSString *email;
+ NSRange r;
- if (![_uid isNotNull] || [_uid length] == 0)
- return nil;
- if ((email = [self _cachedEmailForUID:_uid]) != nil)
- return email;
-
- if (useLDAP) {
- email = [self primaryGetEmailForAgenorUID:_uid];
- }
- else {
- NSRange r;
-
- r = [_uid rangeOfString:@"@"];
- email = (r.length > 0)
- ? _uid
- : [[_uid stringByAppendingString:@"@"]
- stringByAppendingString:defaultMailDomain];
- }
-
- [self _cacheEmail:email forUID:_uid];
+ email = nil;
+
+ if ([_uid length] > 0)
+ {
+ email = [self _cachedEmailForUID: _uid];
+ if (!email)
+ {
+ if (useLDAP)
+ email = [self primaryGetEmailForAgenorUID:_uid];
+
+ if (!email)
+ {
+ r = [_uid rangeOfString:@"@"];
+ email = ((r.length > 0)
+ ? _uid
+ : [[_uid stringByAppendingString:@"@"]
+ stringByAppendingString: defaultMailDomain]);
+ }
+
+ if (email)
+ [self _cacheEmail: email forUID: _uid];
+ }
+ }
+
return email;
}
if (cnAttrs == nil)
cnAttrs = [[NSArray alloc] initWithObjects:@"cn", nil];
- q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid];
+ q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
NSEnumerator *resultEnum;
NGLdapEntry *entry;
- q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid];
+ q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
if (attrs == nil)
attrs = [[NSArray alloc] initWithObjects:changeInternetAccessAttrName, nil];
- q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid];
+ q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
if (attrs == nil)
attrs = [[NSArray alloc] initWithObjects:mailAutoresponderAttrName, nil];
- q = [EOQualifier qualifierWithQualifierFormat:@"uid = %@", _uid];
+ q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
- (SOGoUser *) userInContext: (WOContext *)_ctx
{
static SOGoUser *anonymous = nil, *freebusy;
- SoUser *user;
+ SOGoUser *user;
NSArray *traversalPath;
NSString *login;
- (NSString *)outlookFolderClass;
- (BOOL) create;
+- (NSException *) delete;
@end
}
- (GCSFolderManager *)folderManager {
- return [GCSFolderManager defaultFolderManager];
+ static GCSFolderManager *folderManager = nil;
+
+ if (!folderManager)
+ {
+ folderManager = [GCSFolderManager defaultFolderManager];
+ [folderManager setFolderNamePrefix: @"SOGo_"];
+ }
+
+ return folderManager;
}
- (GCSFolder *)ocsFolderForPath:(NSString *)_path {
{
NSException *result;
- [GCSFolderType setFolderNamePrefix: @"SOGo_"];
-
result = [[self folderManager] createFolderOfType: [self folderType]
atPath: ocsPath];
return (result == nil);
}
+- (NSException *) delete
+{
+ return [[self folderManager] deleteFolderAtPath: ocsPath];
+}
+
- (NSArray *)fetchContentObjectNames {
NSArray *fields, *records;
return YES;
}
+/* CalDAV support */
+- (NSArray *) davCalendarHomeSet
+{
+ /*
+ <C:calendar-home-set xmlns:D="DAV:"
+ xmlns:C="urn:ietf:params:xml:ns:caldav">
+ <D:href>http://cal.example.com/home/bernard/calendars/</D:href>
+ </C:calendar-home-set>
+
+ Note: this is the *container* for calendar collections, not the
+ collections itself. So for use its the home folder, the
+ public folder and the groups folder.
+ */
+ WOContext *context;
+ NSArray *tag;
+
+ context = [[WOApplication application] context];
+ tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D",
+ [self baseURLInContext: context], nil];
+
+ return [NSArray arrayWithObject: tag];
+}
+
@end /* SOGoUserFolder */
#ifndef UIXPAGEFRAME_H
#define UIXPAGEFRAME_H
+#import <SOGoUI/UIxComponent.h>
+
@interface WOComponent (PopupExtension)
- (BOOL) isPopup;
02111-1307, USA.
*/
+#import "common.h"
+#import <NGObjWeb/SoComponent.h>
+#import <NGObjWeb/WOComponent.h>
+
#import <SOGoUI/UIxComponent.h>
#import <SOGo/SOGoUser.h>
-#include "common.h"
-#include <NGObjWeb/SoComponent.h>
-#include "UIxPageFrame.h"
+#import "UIxPageFrame.h"
@implementation UIxPageFrame
return self;
}
-- (void)dealloc {
+- (void) dealloc
+{
[item release];
[title release];
if (toolbar)
/* accessors */
-- (void)setTitle:(NSString *)_value {
+- (void) setTitle: (NSString *) _value
+{
ASSIGNCOPY(title, _value);
}
-- (NSString *)title {
+- (NSString *) title
+{
if ([self isUIxDebugEnabled])
return title;
return [self labelForKey: @"SOGo"];
}
-- (void)setItem:(id)_item {
+- (void) setItem: (id) _item
+{
ASSIGN(item, _item);
}
-- (id)item {
+- (id) item
+{
return item;
}
-- (NSString *)ownerInContext {
- return [[self clientObject] ownerInContext:[self context]];
+- (NSString *) ownerInContext
+{
+ return [[self clientObject] ownerInContext: nil];
}
- (NSString *) doctype
/* Help URL/target */
-- (NSString *)helpURL
+- (NSString *) helpURL
{
return [NSString stringWithFormat: @"help/%@.html", title];
}
-- (NSString *)helpWindowTarget
+- (NSString *) helpWindowTarget
{
return [NSString stringWithFormat: @"Help_%@", title];
}
/* notifications */
-- (void)sleep {
+- (void) sleep
+{
[item release];
item = nil;
[super sleep];
return [self relativePathToUserFolderSubPath: @""];
}
-- (NSString *)relativeCalendarPath
+- (NSString *) relativeCalendarPath
{
return [self relativePathToUserFolderSubPath: @"Calendar/"];
}
-- (NSString *)relativeContactsPath
+- (NSString *) relativeContactsPath
{
return [self relativePathToUserFolderSubPath: @"Contacts/"];
}
-- (NSString *)relativeMailPath
+- (NSString *) relativeMailPath
{
return [self relativePathToUserFolderSubPath: @"Mail/"];
}
-- (NSString *)logoffPath
+- (NSString *) logoffPath
{
return [self relativePathToUserFolderSubPath: @"logoff"];
}
{
WOComponent *page;
NSString *pageJSFilename;
-
- page = [[self context] page];
+
+ page = [[self context] page];
pageJSFilename = [NSString stringWithFormat: @"%@.css",
NSStringFromClass([page class])];
return tb;
}
-- (id)toolbarConfig {
+- (id) toolbarConfig
+{
id tb;
if (toolbarConfig != nil)
if (toolbar)
tb = toolbar;
else
- tb = [[self clientObject] lookupName:@"toolbar" inContext:[self context]
+ tb = [[self clientObject] lookupName: @"toolbar" inContext:[self context]
acquire:NO];
if ([tb isKindOfClass:[NSException class]]) {
toolbarConfig = [[NSNull null] retain];
return nil;
}
-
- if ([tb isKindOfClass:[NSString class]])
- tb = [self loadToolbarConfigFromResourceNamed:tb];
+
+ if ([tb isKindOfClass: [NSString class]])
+ {
+ if ([tb isEqualToString: @"none"])
+ tb = [NSNull null];
+ else
+ tb = [self loadToolbarConfigFromResourceNamed:tb];
+ }
toolbarConfig = [tb retain];
+
return toolbarConfig;
}
return (amount > 0);
}
+- (BOOL) hasMenu
+{
+ return [[[self buttonInfo] valueForKey:@"hasMenu"] boolValue];
+}
+
- (void) setToolbar: (NSString *) newToolbar
{
ASSIGN(toolbar, newToolbar);
"invalidemailwarn" = "invalidemailwarn";
"new" = "new";
+"htmlMailFormat_UNKNOWN" = "Unknown";
+"htmlMailFormat_FALSE" = "Plain Text";
+"htmlMailFormat_TRUE" = "HTML";
+
"Name or Email" = "Name or Email";
"Personal Addressbook" = "Personal Addressbook";
"Search in Addressbook" = "Search in Addressbook";
"Company: " = "Company: ";
"Street Address: " = "Street Address: ";
"City: " = "City: ";
-"Province: " = "Province: ";
-"Zip or Postal Code: " = "Zip or Postal Code: ";
+"State_Province:" = "State/Province:";
+"ZIP_Postal Code:" = "ZIP/Postal Code:";
"Country: " = "Country: ";
"Web: " = "Web: ";
"Remove the selected Addressbook" = "Remove the selected Addressbook";
"Name of the Address Book" = "Name of the Address Book";
+"Are you sure you want to delete the selected address book?"
+= "Are you sure you want to delete the selected address book?";
/* this file is in UTF-8 format! */
+"Contact" = "Contact";
+"Address" = "Adresses";
+"Other" = "Informations complémentaires";
+
+"Name" = "Identité";
+"Internet" = "E-mail";
+"Phones" = "Numéros de téléphone";
+"Home" = "Personnelle";
+"Work" = "Professionnelle";
+
"Address Books" = "Carnet d'adresses";
"Addresses" = "Adresses";
"Cancel" = "Annuler";
"Lastname" = "Nom";
"Location" = "Lieux";
"MobilePhone" = "Mobile";
-"Name" = "Nom";
"OfficePhone" = "Bureau";
"Organisation" = "Société";
"Phone" = "Téléphone";
-"Phones" = "Téléphones";
"Postal" = "Professionnelle";
"Save" = "Sauvegarder";
"URL" = "URL";
"invalidemailwarn" = "Champ de l'email invalide, continuer quand même ?";
"new" = "Nouveau";
+"htmlMailFormat_UNKNOWN" = "Inconnu";
+"htmlMailFormat_FALSE" = "Texte simple (sans HTML)";
+"htmlMailFormat_TRUE" = "HTML";
+
"Name or Email" = "Le nom ou l'adresse";
"Personal Addressbook" = "Adresses personnelles";
"Search in Addressbook" = "Carnet d'adresses...";
"Preferred" = "Préféré";
"Card for %@" = "Fiche pour %@";
-"Display Name: " = "Nom à afficher : ";
-"Email Address: " = "Adresse électronique : ";
-"Phone Number: " = "Numéro de téléphone : ";
+"Display:" = "Nom à afficher :";
+"Display Name:" = "Nom à afficher :";
+"Email:" = "Adresse électronique :";
+"Additional Email:" = "Adresse alternative :";
-"Firstname: " = "Prénom : ";
-"Lastname: " = "Nom : ";
-"Nickname: " = "Surnom : ";
+"Phone Number:" = "Numéro de téléphone :";
+"Prefers to receive messages formatted as:"
+= "Préfère recevoir les messages au format :";
+"Screen Name:" = "Pseudo :";
+
+"First:" = "Prénom :";
+"Last:" = "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";
+"Work:" = "Travail :";
+"Home:" = "Domicile :";
+"Fax:" = "Télécopieur :";
+"Mobile:" = "Portable :";
+"Pager:" = "Téléavertisseur :";
+
+"Title:" = "Fonction :";
+"Department:" = "Service :";
+"Organization:" = "Société :";
+"Address:" = "Adresse :";
+"City:" = "Ville/Localité :";
+"State_Province:" = "État/Prov. :";
+"ZIP_Postal Code:" = "Code postal :";
+"Country:" = "Pays :";
+"Web Page:" = "Page Web:";
+
"Other Infos" = "Informations complémentaires";
-"Note: " = "Commentaires : ";
-"Timezone: " = "Fuseau horaire : ";
-"Birthday: " = "D. de naissance : ";
-"Freebusy URL: " = "Adresse du FreeBusy : ";
+"Note:" = "Remarques :";
+"Timezone:" = "Fuseau horaire :";
+"Birthday:" = "D. de naissance :";
+"Freebusy URL:" = "Adresse du FreeBusy :";
"Add as..." = "Ajouter...";
"Recipient" = "Destinataire";
"Remove the selected Addressbook" = "Enlever le carnet d'adresses sélectionné";
"Name of the Address Book" = "Nom du carnet d'adresses";
+"Are you sure you want to delete the selected address book?"
+= "Voulez-vous vraiment supprimer le carnet d'adresses sélectionné ?";
@interface UIxContactEditor : UIxComponent
{
- NSString *errorText;
NSString *preferredEmail;
+ NSString *item;
NGVCard *card;
NSMutableDictionary *snapshot; /* contains the values for editing */
}
- (void) dealloc
{
[snapshot release];
- [errorText release];
+ [preferredEmail release];
[super dealloc];
}
/* accessors */
-- (void) setErrorText: (NSString *) _txt
+- (NSArray *) htmlMailFormatList
{
- ASSIGNCOPY(errorText, _txt);
+ static NSArray *htmlMailFormatItems = nil;
+
+ if (!htmlMailFormatItems)
+ {
+ htmlMailFormatItems = [NSArray arrayWithObjects: @"FALSE", @"TRUE", nil];
+ [htmlMailFormatItems retain];
+ }
+
+ return htmlMailFormatItems;
+}
+
+- (NSString *) itemHtmlMailFormatText
+{
+ return [self labelForKey:
+ [NSString stringWithFormat: @"htmlMailFormat_%@", item]];
}
-- (NSString *) errorText
+- (void) setItem: (NSString *) newItem
{
- return errorText;
+ item = newItem;
}
-- (BOOL) hasErrorText
+- (NSString *) item
{
- return [errorText length] > 0 ? YES : NO;
+ return item;
}
/* load/store content format */
[self _setSnapshotValue: @"workMail" to: workMail];
[self _setSnapshotValue: @"homeMail" to: homeMail];
+
+ [self _setSnapshotValue: @"mozillaUseHtmlMail"
+ to: [[card uniqueChildWithTag: @"x-mozilla-html"] value: 0]];
}
- (void) _setupOrgFields
[self _setupEmailFields];
+ [self _setSnapshotValue: @"screenName"
+ to: [[card uniqueChildWithTag: @"x-aim"] value: 0]];
+
elements = [card childrenWithTag: @"adr"
andAttribute: @"type" havingValue: @"work"];
if (elements && [elements count] > 0)
else
[card setPreferred: homeMail];
}
+
+ [[card uniqueChildWithTag: @"x-mozilla-html"]
+ setValue: 0
+ to: [snapshot objectForKey: @"mozillaUseHtmlMail"]];
}
- (void) _saveSnapshot
[self _savePhoneValues];
[self _saveEmails];
+ [[card uniqueChildWithTag: @"x-aim"]
+ setValue: 0 to: [snapshot objectForKey: @"screenName"]];
}
- (id <WOActionResults>) saveAction
- (WOResponse *) _responseForResults: (NSArray *) results
{
WOResponse *response;
- NSString *email, *responseString;
+ NSString *email, *responseString, *uid;
NSDictionary *result;
response = [context response];
if (!result)
result = [results objectAtIndex: 0];
email = [self _emailForResult: result];
+ uid = [result objectForKey: @"c_uid"];
+ if ([uid length] == 0)
+ uid = @"";
responseString = [NSString stringWithFormat: @"%@:%@",
- [result objectForKey: @"c_uid"],
- email];
+ uid, email];
[response setStatus: 200];
[response setHeader: @"text/plain; charset=iso-8859-1"
forKey: @"Content-Type"];
if (value && [value length] > 0)
{
if (label)
- [cardString appendFormat: @"%@%@<br />\n",
+ [cardString appendFormat: @"%@ %@<br />\n",
[self labelForKey: label], value];
else
[cardString appendFormat: @"%@<br />\n", value];
- (NSString *) displayName
{
- return [self _cardStringWithLabel: @"Display Name: "
+ return [self _cardStringWithLabel: @"Display Name:"
value: [card fn]];
}
- (NSString *) nickName
{
- return [self _cardStringWithLabel: @"Nickname: "
+ return [self _cardStringWithLabel: @"Nickname:"
value: [card nickname]];
}
-- (NSString *) preferredEmail
+- (NSString *) primaryEmail
{
NSString *email, *mailTo;
email = [card preferredEMail];
- if (email && [email length] > 0)
+ if ([email length] > 0)
mailTo = [NSString stringWithFormat: @"<a href=\"mailto:%@\""
@" onclick=\"return onContactMailTo(this);\">"
@"%@</a>", email, email];
else
mailTo = nil;
- return [self _cardStringWithLabel: @"Email Address: "
+ return [self _cardStringWithLabel: @"Email:"
value: mailTo];
}
+- (NSString *) secondaryEmail
+{
+ NSString *email, *mailTo;
+ NSMutableArray *emails;
+
+ emails = [NSMutableArray new];
+ [emails addObjectsFromArray: [card childrenWithTag: @"email"]];
+ [emails removeObjectsInArray: [card childrenWithTag: @"email"
+ andAttribute: @"type"
+ havingValue: @"pref"]];
+
+ if ([emails count] > 1)
+ {
+ email = [[emails objectAtIndex: 0] value: 0];
+ mailTo = [NSString stringWithFormat: @"<a href=\"mailto:%@\""
+ @" onclick=\"return onContactMailTo(this);\">"
+ @"%@</a>", email, email];
+ }
+ else
+ mailTo = nil;
+
+ return [self _cardStringWithLabel: @"Additional Email:"
+ value: mailTo];
+}
+
+- (NSString *) screenName
+{
+ NSString *screenName, *goim;
+
+ screenName = [[card uniqueChildWithTag: @"x-aim"] value: 0];
+ if ([screenName length] > 0)
+ goim = [NSString stringWithFormat: @"<a href=\"aim:goim?screenname=%@\""
+ @">%@</a>", screenName, screenName];
+ else
+ goim = nil;
+
+ return [self _cardStringWithLabel: @"Screen Name:" value: goim];
+}
+
- (NSString *) preferredTel
{
- return [self _cardStringWithLabel: @"Phone Number: "
+ return [self _cardStringWithLabel: @"Phone Number:"
value: [card preferredTel]];
}
- (NSString *) workPhone
{
- return [self _phoneOfType: @"work" withLabel: @"Work: "];
+ return [self _phoneOfType: @"work" withLabel: @"Work:"];
}
- (NSString *) homePhone
{
- return [self _phoneOfType: @"home" withLabel: @"Home: "];
+ return [self _phoneOfType: @"home" withLabel: @"Home:"];
}
- (NSString *) fax
{
- return [self _phoneOfType: @"fax" withLabel: @"Fax: "];
+ return [self _phoneOfType: @"fax" withLabel: @"Fax:"];
}
- (NSString *) mobile
{
- return [self _phoneOfType: @"cell" withLabel: @"Mobile: "];
+ return [self _phoneOfType: @"cell" withLabel: @"Mobile:"];
}
- (NSString *) pager
{
- return [self _phoneOfType: @"pager" withLabel: @"Pager: "];
+ return [self _phoneOfType: @"pager" withLabel: @"Pager:"];
}
- (BOOL) hasHomeInfos
- (NSString *) bday
{
- return [self _cardStringWithLabel: @"Birthday: " value: [card bday]];
+ return [self _cardStringWithLabel: @"Birthday:" value: [card bday]];
}
- (NSString *) tz
{
- return [self _cardStringWithLabel: @"Timezone: " value: [card tz]];
+ return [self _cardStringWithLabel: @"Timezone:" value: [card tz]];
}
- (NSString *) note
withString: @"<br />"];
}
- return [self _cardStringWithLabel: @"Note: " value: note];
+ return [self _cardStringWithLabel: @"Note:" value: note];
}
/* hrefs */
02111-1307, USA.
*/
+#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WOResponse.h>
+
#import <Contacts/SOGoContactObject.h>
#import <Contacts/SOGoContactFolder.h>
#import <Contacts/SOGoContactFolders.h>
return self;
}
+- (id <WOActionResults>) deleteAction
+{
+ id <WOActionResults> result;
+ NSException <WOActionResults> *ex;
+ WOResponse *response;
+
+ ex = [[self clientObject] delete];
+ if (ex)
+ result = ex;
+ else
+ {
+ response = [context response];
+ [response setStatus: 200];
+ result = response;
+ }
+
+ return result;
+}
+
- (NSString *) defaultSortKey
{
return @"fn";
pageName = "UIxContactsListView";
actionName = "addressBooksContacts";
};
+ delete = {
+ protectedBy = "View";
+ pageName = "UIxContactsListView";
+ actionName = "delete";
+ };
};
};
}
- (iCalEvent *)storedEvent {
- return (iCalEvent *) [(SOGoAppointmentObject *)[self storedEventObject] component];
+ return (iCalEvent *) [(SOGoAppointmentObject *)[self storedEventObject] component: NO];
}
/* organizer tracking */
-/*
- 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 <NGObjWeb/WOResponse.h>
-#import <SoObjects/Appointments/SOGoFreeBusyObject.h>
-#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
-#import <NGExtensions/NSCalendarDate+misc.h>
-
+/* SOGoUserHomePage.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 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 <NGObjWeb/WORequest.h>
#import <SOGoUI/UIxComponent.h>
-#import <Scheduler/UIxComponent+Agenor.h>
@interface SOGoUserHomePage : UIxComponent
-{
- id item;
-}
-
-- (NSString *)ownPath;
-- (NSString *)userFolderPath;
-- (NSString *)relativePathToUserFolderSubPath:(NSString *)_sub;
-- (NSString *)relativeCalendarPath;
-- (NSString *)relativeContactsPath;
-- (NSString *)relativeMailPath;
-
@end
-#include <SOGo/AgenorUserManager.h>
-#include <SOGo/WOContext+Agenor.h>
-#include <SOGo/SOGoUser.h>
-#include "common.h"
-
@implementation SOGoUserHomePage
-static NSArray *internetAccessStates = nil;
-
-+ (void)initialize {
- static BOOL didInit = NO;
-
- if (didInit) return;
- didInit = YES;
-
- internetAccessStates = [[NSArray alloc] initWithObjects:@"0", @"1", nil];
-}
-
-- (void)dealloc {
- [self->item release];
- [super dealloc];
-}
-
-/* lookup */
-
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
- // Note: we do no acquisition
- id obj;
-
- /* first check attributes directly bound to the object */
- if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
- return obj;
-
- return nil;
-}
-
-/* accessors */
-
-- (void)setItem:(id)_item {
- ASSIGN(self->item, _item);
-}
-- (id)item {
- return self->item;
-}
-
-- (NSArray *)internetAccessStates {
- return internetAccessStates;
-}
-
-- (NSString *)internetAccessState {
- NSUserDefaults *ud;
- NSNumber *value;
-
- ud = [[[self context] activeUser] userDefaults];
- value = [ud objectForKey:@"allowinternet"];
- return [NSString stringWithFormat:@"%d", [value boolValue]];
-}
-- (void)setInternetAccessState:(NSString *)_internetAccessState {
- NSUserDefaults *ud;
-
- ud = [[[self context] activeUser] userDefaults];
- [ud setObject:_internetAccessState forKey:@"allowinternet"];
- [ud synchronize];
-}
-
-- (NSString *)itemInternetAccessStateText {
- NSString *key;
-
- key = [NSString stringWithFormat:@"internetAccessState_%@", self->item];
- return key;
-}
-
-/* paths */
-
-- (NSString *)ownPath {
- 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];
- return uri;
-}
-
-- (NSString *)userFolderPath {
- WOContext *ctx;
- NSArray *traversalObjects;
- NSString *url;
-
- ctx = [self context];
- traversalObjects = [ctx objectTraversalStack];
- url = [[traversalObjects objectAtIndex:1]
- baseURLInContext:ctx];
- return [[NSURL URLWithString:url] path];
-}
-
-- (NSString *)relativePathToUserFolderSubPath:(NSString *)_sub {
- NSString *dst, *rel;
-
- dst = [[self userFolderPath] stringByAppendingPathComponent:_sub];
- rel = [dst urlPathRelativeToPath:[self ownPath]];
- return rel;
-}
-
-- (NSString *)relativeCalendarPath {
- return [self relativePathToUserFolderSubPath:@"Calendar/"];
-}
-
-- (NSString *)relativeContactsPath {
- return [self relativePathToUserFolderSubPath:@"Contacts/"];
-}
-
-- (NSString *)relativeMailPath {
- return [NSString stringWithFormat: @"%@%@/view",
- [self relativePathToUserFolderSubPath:@"Mail/"],
- [self emailForUser]];
-}
-
-/* objects */
-
-- (id)calendarFolder {
- return [[self clientObject] lookupName:@"Calendar"
- inContext:[self context]
- acquire:NO];
-}
-
-/* checking access */
-
-- (BOOL)canAccess {
- WOContext *ctx;
- NSString *owner;
-
- ctx = [self context];
- owner = [[self clientObject] ownerInContext:ctx];
- return [owner isEqualToString:[[ctx activeUser] login]];
-}
-
-- (BOOL)isNotAllowedToChangeInternetAccess {
- // TODO: should be a SOGoUser method
- AgenorUserManager *um;
- WOContext *ctx;
- NSString *uid;
-
- ctx = [self context];
- /* do not allow changes when access is from Internet */
- if (![ctx isAccessFromIntranet])
- return YES;
- um = [AgenorUserManager sharedUserManager];
- uid = [[ctx activeUser] login];
- return [um isUserAllowedToChangeSOGoInternetAccess:uid] ? NO : YES;
-}
-
-- (BOOL)isVacationMessageEnabledForInternet {
- // TODO: should be a SOGoUser method
- AgenorUserManager *um;
- NSString *uid;
-
- um = [AgenorUserManager sharedUserManager];
- uid = [[[self context] activeUser] login];
- return [um isInternetAutoresponderEnabledForUser:uid];
-}
-
-- (BOOL)isVacationMessageEnabledForIntranet {
- // TODO: should be a SOGoUser method
- AgenorUserManager *um;
- NSString *uid;
-
- um = [AgenorUserManager sharedUserManager];
- uid = [[[self context] activeUser] login];
- return [um isIntranetAutoresponderEnabledForUser:uid];
-}
-
-/* actions */
-
-#if 0
-- (id)defaultAction {
- return [self redirectToLocation:[self relativeCalendarPath]];
-}
-#endif
-
-/* this is triggered by an XMLHTTPRequest */
-- (id)saveInternetAccessStateAction {
- NSString *state;
-
- if ([self isNotAllowedToChangeInternetAccess])
- return [NSException exceptionWithHTTPStatus:403 /* Forbidden */];
-
- state = [[[self context] request] formValueForKey:@"allowinternet"];
- [self setInternetAccessState:state];
- return [NSException exceptionWithHTTPStatus:200 /* OK */];
-}
-
-- (void) _fillFreeBusyItems: (NSMutableArray *) items
- withRecords: (NSEnumerator *) records
- fromStartDate: (NSCalendarDate *) startDate
- toEndDate: (NSCalendarDate *) endDate
+- (id <WOActionResults>) defaultAction
{
- 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);
+ NSString *baseURL, *url;
- value = [[record objectForKey: @"enddate"] intValue];
- currentDate = [NSCalendarDate dateWithTimeIntervalSince1970: value];
- if ([currentDate earlierDate: endDate] == endDate)
- endInterval = [items count] - 1;
- else
- endInterval = ([currentDate timeIntervalSinceDate: startDate] / 900);
+ baseURL = [[context request] uri];
+ url = [baseURL stringByAppendingString:@"/../Calendar"];
- for (count = startInterval; count < endInterval; count++)
- [items replaceObjectAtIndex: count withObject: status];
-
- record = [records nextObject];
- }
+ return [self redirectToLocation: url];
}
-- (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 */
+@end
SOGoUserFolder = {
methods = {
view = {
- protectedBy = "HomePage Access";
- pageName = "SOGoUserHomePage";
- };
- edit = {
- protectedBy = "HomePage Access";
+ protectedBy = "View";
pageName = "SOGoUserHomePage";
- actionName = "saveInternetAccessState";
};
- /*
- GET = { // more or less a hack, see README of dbd
- protectedBy = "HomePage Access";
- pageName = "SOGoUserHomePage";
- };
- */
};
};
SOGoGroupsFolder = {
uri = [uri substringToIndex:r.location];
/* next: strip trailing slash */
-
+
if ([uri hasSuffix: @"/"])
uri = [uri substringToIndex: ([uri length] - 1)];
r = [uri rangeOfString:@"/" options: NSBackwardsSearch];
/* Day */
-"Sunday" = "Sunday";
-"Monday" = "Monday";
-"Tuesday" = "Tuesday";
-"Wednesday" = "Wednesday";
-"Thursday" = "Thursday";
-"Friday" = "Friday";
-"Saturday" = "Saturday";
-
-"a2_Sunday" = "Su";
-"a2_Monday" = "Mo";
-"a2_Tuesday" = "Tu";
-"a2_Wednesday" = "We";
-"a2_Thursday" = "Th";
-"a2_Friday" = "Fr";
-"a2_Saturday" = "Sa";
-
-"dayLabelFormat" = "%Y-%m-%d";
-"today" = "today";
-
+"Sunday" = "Sunday";
+"Monday" = "Monday";
+"Tuesday" = "Tuesday";
+"Wednesday" = "Wednesday";
+"Thursday" = "Thursday";
+"Friday" = "Friday";
+"Saturday" = "Saturday";
+
+"a2_Sunday" = "Su";
+"a2_Monday" = "Mo";
+"a2_Tuesday" = "Tu";
+"a2_Wednesday" = "We";
+"a2_Thursday" = "Th";
+"a2_Friday" = "Fr";
+"a2_Saturday" = "Sa";
+
+"dayLabelFormat" = "%m/%d/%Y";
+"today" = "Today";
/* Week */
-"Week" = "Week";
-"this week" = "this week";
+"Week" = "Week";
+"this week" = "this week";
+"Week %d" = "Week %d";
/* Month */
-"this month" = "this month";
-
-"January" = "January";
-"February" = "February";
-"March" = "March";
-"April" = "April";
-"May" = "May";
-"June" = "June";
-"July" = "July";
-"August" = "August";
-"September" = "September";
-"October" = "October";
-"November" = "November";
-"December" = "December";
-
-"a3_January" = "Jan";
-"a3_February" = "Feb";
-"a3_March" = "Mar";
-"a3_April" = "Apr";
-"a3_May" = "May";
-"a3_June" = "Jun";
-"a3_July" = "Jul";
-"a3_August" = "Aug";
-"a3_September" = "Sep";
-"a3_October" = "Oct";
-"a3_November" = "Nov";
-"a3_December" = "Dec";
-
+"this month" = "this month";
+
+"January" = "January";
+"February" = "February";
+"March" = "March";
+"April" = "April";
+"May" = "May";
+"June" = "June";
+"July" = "July";
+"August" = "August";
+"September" = "September";
+"October" = "October";
+"November" = "November";
+"December" = "December";
+
+"a3_January" = "January";
+"a3_February" = "February";
+"a3_March" = "March";
+"a3_April" = "April";
+"a3_May" = "May";
+"a3_June" = "June";
+"a3_July" = "July";
+"a3_August" = "August";
+"a3_September" = "September";
+"a3_October" = "October";
+"a3_November" = "November";
+"a3_December" = "December";
/* Year */
-"this year" = "this year";
+"this year" = "this year";
/* Menu */
-"Calendars" = "Calendars";
-"Calendar" = "Calendar";
-"Contacts" = "Contacts";
+"Calendars" = "Calendars";
+"Calendar" = "Calendar";
+"Contacts" = "Contacts";
"New Calendar..." = "New Calendar...";
"Delete Calendar" = "Delete Calendar";
/* Misc */
-"OpenGroupware.org" = "OpenGroupware.org";
-"Forbidden" = "Forbidden";
+"OpenGroupware.org" = "OpenGroupware.org";
+"Forbidden" = "Forbidden";
+
+
+/* Button Titles */
-/* Button titles */
+"new" = "New";
+"printview" = "Print View";
+"edit" = "Edit";
+"delete" = "Delete";
+"proposal" = "Proposal";
+"Save and Close" = "Save and Close";
+"Close" = "Close";
+"Invite Attendees" = "Invite Attendees";
+"Documents" = "Documents";
+"Cancel" = "Cancel";
+"show_rejected_apts" = "Show rejected appointments";
+"hide_rejected_apts" = "Hide rejected appointments";
-"new" = "new";
-"printview" = "printview";
-"edit" = "edit";
-"delete" = "delete";
-"proposal" = "proposal";
-"Save" = "Save";
-"Cancel" = "Cancel";
-"show_rejected_apts" = "Show rejected appointments";
-"hide_rejected_apts" = "Hide rejected appointments";
/* Schedule */
-"Schedule" = "Appointment propositions";
-"No appointments found" = "You don't have any appointments in the near future.";
+"Schedule" = "Schedule";
+"No appointments found" = "No appointments found";
"Meetings proposed by you" = "Meetings proposed by you";
"Meetings proposed to you" = "Meetings proposed to you";
-"sched_startDateFormat" = "%d.%m. %H:%M";
-"action" = "Action";
-"accept" = "Accept";
-"decline" = "Decline";
-"more attendees" = "more attendees";
+"sched_startDateFormat" = "%d/%m %H:%M";
+"action" = "Action";
+"accept" = "Accept";
+"decline" = "Decline";
+"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";
/* Appointments */
-"Appointment viewer" = "Appointment Viewer";
-"Appointment editor" = "Appointment Editor";
-"Appointment proposal" = "Appointment Proposal";
-"Appointment on" = "Appointment on";
-"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";
-"browse end date" = "browse end date";
-"Title" = "Title";
-"Name" = "Name";
-"Email" = "Email";
-"Status" = "Status";
-"Location" = "Location";
-"Priority" = "Priority";
-"Privacy" = "Privacy";
-"Cycle" = "Cycle";
-"Cycle End" = "End";
-"Categories" = "Categories";
-"Classification" = "Classification";
-"Duration" = "Duration";
-"Attendees" = "Attendees";
-"Resources" = "Resources";
-"Organizer" = "Organizer";
-"Description" = "Description";
-"Start" = "Start";
-"End" = "End";
-"Category" = "Category";
-
-"attributes" = "Attributes";
-"attendees" = "Attendees";
+"Appointment viewer" = "Appointment Viewer";
+"Appointment editor" = "Appointment Editor";
+"Appointment proposal" = "Appointment Proposal";
+"Appointment on" = "Appointment on";
+"Start:" = "Start:";
+"Due Date:" = "Due Date:";
+"Title:" = "Title:";
+"Calendar:" = "Calendar:";
+"Name" = "Name";
+"Email" = "Email";
+"Status:" = "Status:";
+"% complete" = "% complete";
+"Location:" = "Location:";
+"Priority:" = "Priority:";
+"Privacy" = "Privacy";
+"Cycle" = "Cycle";
+"Cycle End" = "Cycle End";
+"Categories" = "Categories";
+"Classification" = "Classification";
+"Duration" = "Duration";
+"Attendees:" = "Attendees:";
+"Resources" = "Resources";
+"Organizer:" = "Organizer:";
+"Description:" = "Description:";
+"Document:" = "Document:";
+"Start:" = "Start:";
+"End:" = "End:";
+"Category:" = "Category:";
+"Repeat:" = "Repeat:";
+"Reminder:" = "Reminder:";
+
+"Target:" = "Target:";
+
+"attributes" = "attributes";
+"attendees" = "attendees";
/* checkbox title */
-"is private" = "is private";
+"is private" = "is private";
/* classification */
-"Public" = "Public";
-"Private" = "Private";
+"Public" = "Public";
+"Private" = "Private";
/* text used in overviews and tooltips */
-"empty title" = "Empty title";
-"private appointment" = "Private appointment";
+"empty title" = "Empty title";
+"private appointment" = "Private appointment";
-"Show Details" = "Show Details";
-"Hide Details" = "Hide Details";
+"Change..." = "Change...";
/* Appointments (participation state) */
-"partStat_NEEDS-ACTION" = "Not decided, yet";
-"partStat_ACCEPTED" = "Accepted";
-"partStat_DECLINED" = "Declined";
-"partStat_TENTATIVE" = "Tentative";
-"partStat_DELEGATED" = "Delegated";
-"partStat_OTHER" = "???";
+"partStat_NEEDS-ACTION" = "Needs action";
+"partStat_ACCEPTED" = "Accepted";
+"partStat_DECLINED" = "Declined";
+"partStat_TENTATIVE" = "Tentative";
+"partStat_DELEGATED" = "Delegated";
+"partStat_OTHER" = "Other";
/* Appointments (error messages) */
-"Conflicts found!" = "One or more conflicts were found.";
-"Invalid iCal data!" = "Invalid iCalendar data ...";
-"Could not create iCal data!" = "Could not create iCalendar data ...";
-
+"Conflicts found!" = "Conflicts found!";
+"Invalid iCal data!" = "Invalid iCal data!";
+"Could not create iCal data!" = "Could not create iCal data!";
/* 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_all" = "All";
+"view_today" = "Today";
+"view_next7" = "Next 7 days";
+"view_next14" = "Next 14 days";
+"view_next31" = "Next 31 days";
+"view_thismonth" = "This Month";
"view_future" = "All Future Events";
-"view_selectedday" = "Currently Selected Day";
+"view_selectedday" = "Selected Day";
"View:" = "View:";
"Title or Description" = "Title or Description";
-"Search" = "Search";
-"Search attendees" = "Search attendees";
-"Search resources" = "Search resources";
-"Search appointments" = "Search appointments";
-"Search in Anais" = "Search in Anaïs";
+"Search" = "Search";
+"Search attendees" = "Search attendees";
+"Search resources" = "Search resources";
+"Search appointments" = "Search appointments";
+"Search in Anais" = "Search in Anais";
-"All Day" = "All Day";
-"check for conflicts" = "check for conflicts";
+"All day Event" = "All day Event";
+"check for conflicts" = "Check for conflicts";
"Browse URL" = "Browse URL";
/* calendar modes */
-"Overview" = "Overview";
-"Chart" = "Chart";
-"List" = "List";
-"Columns" = "Columns";
-
+"Overview" = "Overview";
+"Chart" = "Chart";
+"List" = "List";
+"Columns" = "Columns";
/* Priorities */
-"prio_0" = "Not specified";
-"prio_1" = "High";
-"prio_2" = "High";
-"prio_3" = "High";
-"prio_4" = "High";
-"prio_5" = "Normal";
-"prio_6" = "Low";
-"prio_7" = "Low";
-"prio_8" = "Low";
-"prio_9" = "Low";
+"prio_0" = "Not specified";
+"prio_1" = "High";
+"prio_2" = "High";
+"prio_3" = "High";
+"prio_4" = "High";
+"prio_5" = "Normal";
+"prio_6" = "Low";
+"prio_7" = "Low";
+"prio_8" = "Low";
+"prio_9" = "Low";
/* access classes (privacy) */
"privacy_PUBLIC" = "Public";
-"privacy_CONFIDENTIAL" = "Time and Date Only";
+"privacy_CONFIDENTIAL" = "Confidential";
"privacy_PRIVATE" = "Private";
/* status type */
"status_" = "Not specified";
+"status_NOT-SPECIFIED" = "Not specified";
"status_TENTATIVE" = "Tentative";
"status_CONFIRMED" = "Confirmed";
"status_CANCELLED" = "Cancelled";
+"status_NEEDS-ACTION" = "Needs Action";
+"status_IN-PROCESS" = "In Process";
+"status_COMPLETED" = "Completed on";
/* Cycles */
-"cycle_once" = "once";
-"cycle_daily" = "daily";
-"cycle_weekly" = "weekly";
-"cycle_2weeks" = "all 2 weeks";
-"cycle_4weeks" = "all 4 weeks";
-"cycle_monthly" = "monthly";
-"cycle_weekday" = "weekday";
-"cycle_yearly" = "yearly";
+"cycle_once" = "cycle_once";
+"cycle_daily" = "cycle_daily";
+"cycle_weekly" = "cycle_weekly";
+"cycle_2weeks" = "cycle_2weeks";
+"cycle_4weeks" = "cycle_4weeks";
+"cycle_monthly" = "cycle_monthly";
+"cycle_weekday" = "cycle_weekday";
+"cycle_yearly" = "cycle_yearly";
-"cycle_end_never" = "never";
-"cycle_end_until" = "on date";
+"cycle_end_never" = "cycle_end_never";
+"cycle_end_until" = "cycle_end_until";
/* Appointment categories */
-"APPOINTMENT" = "Appointment";
-"NOT IN OFFICE" = "Outside";
-"MEETING" = "Meeting";
-"HOLIDAY" = "Holiday";
-"PHONE CALL" = "Phone";
+"category_NONE" = "None";
+"category_ANNIVERSARY" = "Anniversary";
+"category_BIRTHDAY" = "Birthday";
+"category_BUSINESS" = "Business";
+"category_CALLS" = "Calls";
+"category_CLIENTS" = "Clients";
+"category_COMPETITION" = "Competition";
+"category_CUSTOMER" = "Customer";
+"category_FAVORITES" = "Favorites";
+"category_FOLLOW UP" = "Follow up";
+"category_GIFTS" = "Gifts";
+"category_HOLIDAYS" = "Holidays";
+"category_IDEAS" = "Ideas";
+"category_ISSUES" = "Issues";
+"category_MISCELLANEOUS" = "Miscellaneous";
+"category_PERSONAL" = "Personal";
+"category_PROJECTS" = "Projects";
+"category_PUBLIC HOLIDAY" = "Public Holiday";
+"category_STATUS" = "Status";
+"category_SUPPLIERS" = "Suppliers";
+"category_TRAVEL" = "Travel";
+"category_VACATION" = "Vacation";
+
+"repeat_NEVER" = "Does not repeat";
+"repeat_DAILY" = "Daily";
+"repeat_WEEKLY" = "Weekly";
+"repeat_BI-WEEKLY" = "Bi-weekly";
+"repeat_EVERY WEEKDAY" = "Every Weekday";
+"repeat_MONTHLY" = "Monthly";
+"repeat_YEARLY" = "Yearly";
+"repeat_CUSTOM" = "Custom...";
+
+"reminder_NONE" = "No reminder";
+"reminder_5_MINUTES_BEFORE" = "5 minutes before";
+"reminder_10_MINUTES_BEFORE" = "10 minutes before";
+"reminder_15_MINUTES_BEFORE" = "15 minutes before";
+"reminder_30_MINUTES_BEFORE" = "30 minutes before";
+"reminder_45_MINUTES_BEFORE" = "45 minutes before";
+"reminder_1_HOUR_BEFORE" = "1 hour before";
+"reminder_2_HOURS_BEFORE" = "2 hours before";
+"reminder_5_HOURS_BEFORE" = "5 hours before";
+"reminder_15_HOURS_BEFORE" = "15 hours before";
+"reminder_1_DAY_BEFORE" = "1 day before";
+"reminder_2_DAYS_BEFORE" = "2 days before";
+"reminder_1_WEEK_BEFORE" = "1 week before";
+"reminder_CUSTOM" = "Custom...";
+
+"zoom_400" = "400%";
+"zoom_200" = "200%";
+"zoom_100" = "100%";
+"zoom_50" = "50%";
+"zoom_25" = "25%";
/* validation errors */
"Tasks" = "Tasks";
"Hide completed tasks" = "Hide completed tasks";
+/* tabs */
+"Task" = "Task";
+"Event" = "Event";
+"Recurrence" = "Recurrence";
+
/* toolbar */
"New Event" = "New Event";
"New Task" = "New Task";
"Week View" = "Week View";
"Month View" = "Month View";
-"eventPartStatModificationError" = "Your participation status at the event could not be modified.";
+"eventPartStatModificationError" = "Your participation status could not be modified.";
+
+/* menu */
+"New Event..." = "New Event...";
+"New Task..." = "New Task...";
+"Edit Selected Event..." = "Edit Selected Event...";
+"Delete Selected Event" = "Delete Selected Event";
+"Select All" = "Select All";
+"Workweek days only" = "Workweek days only";
+"Tasks in View" = "Tasks in View";
-/* 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?";
+"appointmentDeleteConfirmation" = "Erasing this event will be permanent.\\nWould you like to continue?";
+"taskDeleteConfirmation" = "Erasing this task will be permanent.\\nWould you like to continue?";
/* Legend */
"Required participant" = "Required participant";
/* Day */
-"Sunday" = "Dimanche";
-"Monday" = "Lundi";
-"Tuesday" = "Mardi";
-"Wednesday" = "Mercredi";
-"Thursday" = "Jeudi";
-"Friday" = "Vendredi";
-"Saturday" = "Samedi";
-
-"a2_Sunday" = "Di";
-"a2_Monday" = "Lu";
-"a2_Tuesday" = "Ma";
-"a2_Wednesday" = "Me";
-"a2_Thursday" = "Je";
-"a2_Friday" = "Ve";
-"a2_Saturday" = "Sa";
-
-"dayLabelFormat" = "%d/%m/%Y";
-"today" = "Aujourd'hui";
-
+"Sunday" = "Dimanche";
+"Monday" = "Lundi";
+"Tuesday" = "Mardi";
+"Wednesday" = "Mercredi";
+"Thursday" = "Jeudi";
+"Friday" = "Vendredi";
+"Saturday" = "Samedi";
+
+"a2_Sunday" = "Di";
+"a2_Monday" = "Lu";
+"a2_Tuesday" = "Ma";
+"a2_Wednesday" = "Me";
+"a2_Thursday" = "Je";
+"a2_Friday" = "Ve";
+"a2_Saturday" = "Sa";
+
+"dayLabelFormat" = "%d/%m/%Y";
+"today" = "Aujourd'hui";
/* Week */
-"Week" = "Semaine";
-"this week" = "cette semaine";
+"Week" = "Semaine";
+"this week" = "cette semaine";
"Week %d" = "Semaine nº %d";
/* Month */
-"this month" = "ce mois";
-
-"January" = "Janvier";
-"February" = "Février";
-"March" = "Mars";
-"April" = "Avril";
-"May" = "Mai";
-"June" = "Juin";
-"July" = "Juillet";
-"August" = "Août";
-"September" = "Septembre";
-"October" = "Octobre";
-"November" = "Novembre";
-"December" = "Décembre";
-
-"a3_January" = "Jan";
-"a3_February" = "Fev";
-"a3_March" = "Mar";
-"a3_April" = "Avr";
-"a3_May" = "Mai";
-"a3_June" = "Jun";
-"a3_July" = "Jul";
-"a3_August" = "Aou";
-"a3_September" = "Sep";
-"a3_October" = "Oct";
-"a3_November" = "Nov";
-"a3_December" = "Dec";
-
+"this month" = "ce mois";
+
+"January" = "Janvier";
+"February" = "Février";
+"March" = "Mars";
+"April" = "Avril";
+"May" = "Mai";
+"June" = "Juin";
+"July" = "Juillet";
+"August" = "Août";
+"September" = "Septembre";
+"October" = "Octobre";
+"November" = "Novembre";
+"December" = "Décembre";
+
+"a3_January" = "Jan";
+"a3_February" = "Fev";
+"a3_March" = "Mar";
+"a3_April" = "Avr";
+"a3_May" = "Mai";
+"a3_June" = "Jun";
+"a3_July" = "Jul";
+"a3_August" = "Aou";
+"a3_September" = "Sep";
+"a3_October" = "Oct";
+"a3_November" = "Nov";
+"a3_December" = "Dec";
/* Year */
-"this year" = "Cette année";
+"this year" = "Cette année";
/* Menu */
-"Calendars" = "Agendas";
-"Calendar" = "Agenda";
-"Contacts" = "Contacts";
+"Calendars" = "Agendas";
+"Calendar" = "Agenda";
+"Contacts" = "Contacts";
"New Calendar..." = "Nouvel agenda...";
"Delete Calendar" = "Effacer l'agenda";
/* Misc */
-"OpenGroupware.org" = "OpenGroupware.org";
-"Forbidden" = "Accès non autorisée";
+"OpenGroupware.org" = "OpenGroupware.org";
+"Forbidden" = "Accès non autorisée";
/* Button Titles */
-"new" = "Nouveau";
-"printview" = "Version imprimable";
-"edit" = "Éditer";
-"delete" = "Supprimer";
-"proposal" = "Recherche de plages horaires";
-"Save" = "Enregistrer";
-"Cancel" = "Annuler";
-"show_rejected_apts" = "Afficher les rendez-vous refusés";
-"hide_rejected_apts" = "Cacher les rendez-vous refusés";
+"new" = "Nouveau";
+"printview" = "Version imprimable";
+"edit" = "Éditer";
+"delete" = "Supprimer";
+"proposal" = "Recherche de plages horaires";
+"Save and Close" = "Enregistrer et fermer";
+"Close" = "Fermer";
+"Invite Attendees" = "Participants";
+"Documents" = "Documents";
+"Cancel" = "Annuler";
+"show_rejected_apts" = "Afficher les rendez-vous refusés";
+"hide_rejected_apts" = "Cacher les rendez-vous refusés";
/* Schedule */
-"Schedule" = "Suivi de rendez-vous";
+"Schedule" = "Suivi de rendez-vous";
"No appointments found" = "Aucun rendez-vous";
"Meetings proposed by you" = "Rendez-vous que vous proposez";
"Meetings proposed to you" = "Rendez-vous qui vous sont proposés";
"sched_startDateFormat" = "%d/%m %H:%M";
-"action" = "Action";
-"accept" = "Accepter";
-"decline" = "Refuser";
-"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";
+"action" = "Action";
+"accept" = "Accepter";
+"decline" = "Refuser";
+"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";
/* Appointments */
-"Appointment viewer" = "Visualisation de rendez-vous";
-"Appointment editor" = "Edition de rendez-vous";
-"Appointment proposal" = "Proposition de rendez-vous";
-"Appointment on" = "Rendez-vous le";
-"From" = "Du";
-"To" = "Au";
-"Due Time" = "Écheance";
-"Start date" = "Date de début";
-"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";
-"browse end date" = "Sélection Date de fin";
-"Title" ="Titre";
-"Name" = "Nom";
-"Email" = "Email";
-"Status" = "Statut";
-"Location" = "Lieu";
-"Priority" = "Priorité";
-"Privacy" = "Confidentialité";
-"Cycle" = "Récurrence";
-"Cycle End" = "s'arreter";
-"Categories" = "Categories";
-"Classification" = "Classification";
-"Duration" = "Durée";
-"Attendees" = "Participants";
-"Resources" = "Ressources";
-"Organizer" = "Organisateur";
-"Description" = "Description";
-"Start" = "Début";
-"End" = "Fin";
-"Category" = "Catégorie";
-
-"attributes" = "Attributs";
-"attendees" = "Participants";
+"Appointment viewer" = "Visualisation de rendez-vous";
+"Appointment editor" = "Edition de rendez-vous";
+"Appointment proposal" = "Proposition de rendez-vous";
+"Appointment on" = "Rendez-vous le";
+"Start:" = "Début :";
+"Due Date:" = "Échéance :";
+"Title:" = "Titre :";
+"Calendar:" = "Agenda :";
+"Name" = "Nom";
+"Email" = "Email";
+"Status:" = "Statut :";
+"% complete" = "% complété";
+"Location:" = "Lieu :";
+"Priority:" = "Priorité";
+"Privacy" = "Confidentialité";
+"Cycle" = "Récurrence";
+"Cycle End" = "s'arreter";
+"Categories" = "Categories";
+"Classification" = "Classification";
+"Duration" = "Durée";
+"Attendees:" = "Participants :";
+"Resources" = "Ressources";
+"Organizer:" = "Organisateur :";
+"Description:" = "Description :";
+"Document:" = "Document :";
+"Start:" = "Début :";
+"End:" = "Fin :";
+"Category:" = "Catégorie :";
+"Repeat:" = "Répéter :";
+"Reminder:" = "Rappel :";
+
+"Target:" = "Destination :";
+
+"attributes" = "Attributs";
+"attendees" = "Participants";
/* checkbox title */
-"is private" = "Rendez-vous privé";
+"is private" = "Rendez-vous privé";
/* classification */
-"Public" = "Public";
-"Private" = "Privé";
+"Public" = "Public";
+"Private" = "Privé";
/* text used in overviews and tooltips */
-"empty title" = "Titre vide";
-"private appointment" = "Rendez-vous privé";
+"empty title" = "Titre vide";
+"private appointment" = "Rendez-vous privé";
-"Show Details" = "Afficher les détails";
-"Hide Details" = "Cacher les détails";
+"Change..." = "Modifier...";
/* Appointments (participation state) */
-"partStat_NEEDS-ACTION" = "Décision attendue";
-"partStat_ACCEPTED" = "Accepté";
-"partStat_DECLINED" = "Refusé";
-"partStat_TENTATIVE" = "Tentative";
-"partStat_DELEGATED" = "Delegué";
-"partStat_OTHER" = "???";
+"partStat_NEEDS-ACTION" = "Décision attendue";
+"partStat_ACCEPTED" = "Accepté";
+"partStat_DECLINED" = "Refusé";
+"partStat_TENTATIVE" = "Tentative";
+"partStat_DELEGATED" = "Delegué";
+"partStat_OTHER" = "???";
/* Appointments (error messages) */
-"Conflicts found!" = "Un ou plusieurs conflicts ont été détectés";
-"Invalid iCal data!" = "Données iCal non valides ...";
-"Could not create iCal data!" = "Les données iCal n'ont pu être crées ...";
+"Conflicts found!" = "Un ou plusieurs conflicts ont été détectés";
+"Invalid iCal data!" = "Données iCal non valides ...";
+"Could not create iCal data!" = "Les données iCal n'ont pu être crées ...";
/* Searching */
"View:" = "Voir :";
"Title or Description" = "Le titre ou la description";
-"Search" = "Rechercher";
+"Search" = "Rechercher";
"Search attendees" ="Recherche de participants";
"Search resources" ="Recherche de ressources";
-"Search appointments" = "Recherche de rendez-vous";
-"Search in Anais" = "Recherche par Anaïs";
+"Search appointments" = "Recherche de rendez-vous";
+"Search in Anais" = "Recherche par Anaïs";
-"All Day" = "Toute la journée";
+"All day Event" = "Toute la journée";
"check for conflicts" = "Vérifier les conflits";
"Browse URL" = "Visiter l'URL";
/* calendar modes */
-"Overview" = "Vue synthétique";
-"Chart" = "Vue avec repères horaires";
-"List" = "Vue multi-agenda";
-"Columns" = "Vue avec repères mensuels";
-
+"Overview" = "Vue synthétique";
+"Chart" = "Vue avec repères horaires";
+"List" = "Vue multi-agenda";
+"Columns" = "Vue avec repères mensuels";
/* Priorities */
-"prio_0" = "Non-spécifiée";
-"prio_1" = "Haute";
-"prio_2" = "Haute";
-"prio_3" = "Haute";
-"prio_4" = "Haute";
-"prio_5" = "Normale";
-"prio_6" = "Basse";
-"prio_7" = "Basse";
-"prio_8" = "Basse";
-"prio_9" = "Basse";
+"prio_0" = "Non-spécifiée";
+"prio_1" = "Haute";
+"prio_2" = "Haute";
+"prio_3" = "Haute";
+"prio_4" = "Haute";
+"prio_5" = "Normale";
+"prio_6" = "Basse";
+"prio_7" = "Basse";
+"prio_8" = "Basse";
+"prio_9" = "Basse";
/* access classes (privacy) */
"privacy_PUBLIC" = "Public";
/* status type */
"status_" = "Non-spécifié";
+"status_NOT-SPECIFIED" = "Non spécifié";
"status_TENTATIVE" = "Tentative";
"status_CONFIRMED" = "Confirmé";
"status_CANCELLED" = "Annulé";
+"status_NEEDS-ACTION" = "En attente";
+"status_IN-PROCESS" = "En cours";
+"status_COMPLETED" = "Complété le";
/* Cycles */
-"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" = "À chaque même jour de la semaine";
-"cycle_yearly" = "Chaque année";
+"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" = "À chaque même jour de la semaine";
+"cycle_yearly" = "Chaque année";
-"cycle_end_never" = "Jamais";
-"cycle_end_until" = "À la date :";
+"cycle_end_never" = "Jamais";
+"cycle_end_until" = "À la date :";
/* Appointment categories */
-"APPOINTMENT" = "Rendez-vous";
-"NOT IN OFFICE" = "À l'extérieur";
-"MEETING" = "Réunion";
-"HOLIDAY" = "Vacances";
-"PHONE CALL" = "Rendez-vous téléphonique";
+"category_NONE" = "Aucune";
+"category_ANNIVERSARY" = "Anniversaire";
+"category_BIRTHDAY" = "Anniversaire (de nais.)";
+"category_BUSINESS" = "Business";
+"category_CALLS" = "Appels";
+"category_CLIENTS" = "Clients";
+"category_COMPETITION" = "Compétition";
+"category_CUSTOMER" = "Client";
+"category_FAVORITES" = "Favoris";
+"category_FOLLOW UP" = "Suivi";
+"category_GIFTS" = "Cadeaux";
+"category_HOLIDAYS" = "Vacances";
+"category_IDEAS" = "Idées";
+"category_ISSUES" = "Problèmes";
+"category_MISCELLANEOUS" = "Divers";
+"category_PERSONAL" = "Personnel";
+"category_PROJECTS" = "Projets";
+"category_PUBLIC HOLIDAY" = "Public Holiday";
+"category_STATUS" = "Statut";
+"category_SUPPLIERS" = "Fournisseurs";
+"category_TRAVEL" = "Voyage";
+"category_VACATION" = "Absence";
+
+"repeat_NEVER" = "Ne se répète pas";
+"repeat_DAILY" = "quotidiennement";
+"repeat_WEEKLY" = "hebdomadairement";
+"repeat_BI-WEEKLY" = "bi-hebdomadairement";
+"repeat_EVERY WEEKDAY" = "les jours ouvrables";
+"repeat_MONTHLY" = "mensuellement";
+"repeat_YEARLY" = "annuellement";
+"repeat_CUSTOM" = "Personnaliser...";
+
+"reminder_NONE" = "Pas de rappel";
+"reminder_5_MINUTES_BEFORE" = "5 minutes avant";
+"reminder_10_MINUTES_BEFORE" = "10 minutes avant";
+"reminder_15_MINUTES_BEFORE" = "15 minutes avant";
+"reminder_30_MINUTES_BEFORE" = "30 minutes avant";
+"reminder_45_MINUTES_BEFORE" = "45 minutes avant";
+"reminder_1_HOUR_BEFORE" = "1 heure avant";
+"reminder_2_HOURS_BEFORE" = "2 heures avant";
+"reminder_5_HOURS_BEFORE" = "5 heures avant";
+"reminder_15_HOURS_BEFORE" = "15 heures avant";
+"reminder_1_DAY_BEFORE" = "1 jour avant";
+"reminder_2_DAYS_BEFORE" = "2 jours avant";
+"reminder_1_WEEK_BEFORE" = "1 semaine avant";
+"reminder_CUSTOM" = "Personnaliser...";
+
+"zoom_400" = "400%";
+"zoom_200" = "200%";
+"zoom_100" = "100%";
+"zoom_50" = "50%";
+"zoom_25" = "25%";
/* validation errors */
UIxCalMonthViewOld.m \
UIxAptTableView.m \
\
+ UIxAttendeesEditor.m \
UIxComponentEditor.m \
- UIxFreeBusyUserSelector.m \
- UIxFreeBusyUserSelectorTable.m \
UIxAppointmentView.m \
UIxAppointmentEditor.m \
UIxAppointmentProposal.m \
Toolbars/SOGoAppointmentObject.toolbar \
Toolbars/SOGoAppointmentObjectAccept.toolbar \
Toolbars/SOGoAppointmentObjectDecline.toolbar \
- Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar
+ Toolbars/SOGoAppointmentObjectAcceptOrDecline.toolbar \
+ Toolbars/SOGoTaskObject.toolbar \
+ Toolbars/SOGoComponentClose.toolbar
SchedulerUI_LOCALIZED_RESOURCE_FILES += \
Localizable.strings \
( /* the toolbar groups -*-cperl-*- */
( { link = "#";
- isSafe = NO;
- label = "Save";
- onclick = "return saveEvent(this);";
- image = "tb-compose-save-flat-24x24.png"; } )
+ label = "Save and Close";
+ onclick = "return saveEvent();";
+ image = "tb-compose-save-flat-24x24.png"; },
+ { link = "#";
+ label = "Invite Attendees";
+ onclick = "return onPopupAttendeesWindow();";
+ image = "tb-compose-contacts-flat-24x24.png"; },
+ { link = "#";
+ hasMenu = YES;
+ label = "Privacy";
+ onclick = "return onSelectPrivacy(event);";
+ image = "tb-compose-security-flat-24x24.png"; },
+ { link = "#";
+ label = "Documents";
+ onclick = "return onPopupUrlWindow();";
+ image = "tb-compose-attach-flat-24x24.png"; } )
)
/* UIxAppointmentEditor.h - this file is part of SOGo
*
- * Copyright (C) 2006 Inverse groupe conseil
+ * Copyright (C) 2007 Inverse groupe conseil
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
#ifndef UIXAPPOINTMENTEDITOR_H
#define UIXAPPOINTMENTEDITOR_H
-#import <UIxComponentEditor.h>
+#import <SOGoUI/UIxComponent.h>
+@class iCalEvent;
@class NSString;
-@class iCalPerson;
-@class iCalRecurrenceRule;
-@interface UIxAppointmentEditor : UIxComponentEditor
+@interface UIxAppointmentEditor : UIxComponent
{
- NSCalendarDate *endDate;
+ iCalEvent *event;
+ NSCalendarDate *aptStartDate;
+ NSCalendarDate *aptEndDate;
+ NSString *item;
}
+/* template values */
+- (NSString *) saveURL;
+- (iCalEvent *) event;
+
+/* icalendar values */
+- (BOOL) isAllDay;
+- (void) setIsAllDay: (BOOL) newIsAllDay;
+
- (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
+- (NSString *) repeat;
+- (void) setRepeat: (NSString *) newRepeat;
-- (id) acceptOrDeclineAction: (BOOL) _accept;
+- (NSString *) reminder;
+- (void) setReminder: (NSString *) newReminder;
@end
-/*
- 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.
-*/
+/* UIxAppointmentEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 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 <NGObjWeb/SoObject.h>
+#import <NGObjWeb/WORequest.h>
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
+
+#import <NGCards/iCalEvent.h>
+#import <NGCards/iCalPerson.h>
+
+#import <SoObjects/SOGo/AgenorUserManager.h>
+#import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/SOGo/SOGoContentObject.h>
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
+#import <SoObjects/Appointments/SOGoAppointmentObject.h>
+
+#import "UIxComponentEditor.h"
+#import "UIxAppointmentEditor.h"
-#import <NGCards/NSString+NGCards.h>
-#import <NGCards/NSCalendarDate+NGCards.h>
+@implementation UIxAppointmentEditor
-#import <SOGo/AgenorUserManager.h>
-#import <SOGo/NSCalendarDate+SOGo.h>
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ aptStartDate = nil;
+ aptEndDate = nil;
+ item = nil;
+ event = nil;
+ }
-#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"
+ return self;
+}
-#import "UIxAppointmentEditor.h"
+/* template values */
+- (iCalEvent *) event
+{
+ return event;
+}
-/* TODO: CLEAN UP */
+- (NSString *) saveURL
+{
+ return [NSString stringWithFormat: @"%@/saveAsAppointment",
+ [[self clientObject] baseURL]];
+}
-@implementation UIxAppointmentEditor
+- (NSString *) _toolbarForCalObject
+{
+ SOGoUser *currentUser;
+ SOGoAppointmentObject *clientObject;
+ NSString *filename, *email;
+ iCalPerson *person;
+ iCalPersonPartStat participationStatus;
+
+ clientObject = [self clientObject];
+ currentUser = [[self context] activeUser];
+ email = [currentUser email];
+ if ([clientObject isOrganizer: email
+ orOwner: [currentUser login]])
+ filename = @"SOGoAppointmentObject.toolbar";
+ else
+ {
+ if ([clientObject isParticipant: email])
+ {
+ person = [[clientObject component: NO] findParticipantWithEmail: email];
+ participationStatus = [person participationStatus];
+ if (participationStatus == iCalPersonPartStatAccepted)
+ filename = @"SOGoAppointmentObjectDecline.toolbar";
+ else if (participationStatus == iCalPersonPartStatDeclined)
+ filename = @"SOGoAppointmentObjectAccept.toolbar";
+ else
+ filename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar";
+ }
+ else
+ filename = @"SOGoComponentClose.toolbar";
+ }
-+ (int)version {
- return [super version] + 0 /* v2 */;
+ return filename;
}
-+ (void)initialize {
- NSAssert2([super version] == 2,
- @"invalid superclass (%@) version %i !",
- NSStringFromClass([self superclass]), [super version]);
+- (NSString *) toolbar
+{
+ return ([self _toolbarForCalObject]);
}
-- (void) dealloc
+/* icalendar values */
+- (BOOL) isAllDay
{
- [endDate release];
- [super dealloc];
+ return NO;
}
-/* accessors */
+- (void) setIsAllDay: (BOOL) newIsAllDay
+{
+}
-- (void) setAptStartDate: (NSCalendarDate *)_date
+- (void) setAptStartDate: (NSCalendarDate *) newAptStartDate
{
- [self setStartDate: _date];
+ ASSIGN (aptStartDate, newAptStartDate);
}
- (NSCalendarDate *) aptStartDate
{
- return [self startDate];
+ return aptStartDate;
}
-- (void) setAptEndDate: (NSCalendarDate *) _date
+- (void) setAptEndDate: (NSCalendarDate *) newAptEndDate
{
- ASSIGN(endDate, _date);
+ ASSIGN (aptEndDate, newAptEndDate);
}
- (NSCalendarDate *) aptEndDate
{
- return endDate;
+ return aptEndDate;
}
-/* transparency */
-
-- (NSString *) transparency
+- (NSArray *) repeatList
{
- return @"OPAQUE";
+ static NSArray *repeatItems = nil;
+
+ if (!repeatItems)
+ {
+ repeatItems = [NSArray arrayWithObjects: @"DAILY",
+ @"WEEKLY",
+ @"BI-WEEKLY",
+ @"EVERY WEEKDAY",
+ @"MONTHLY",
+ @"YEARLY",
+ @"-",
+ @"CUSTOM",
+ nil];
+ [repeatItems retain];
+ }
+
+ return repeatItems;
}
-/* 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:VEVENT\r\n"
- @"UID:%@\r\n"
- @"CLASS:PUBLIC\r\n"
- @"STATUS:CONFIRMED\r\n" /* confirmed by default */
- @"DTSTAMP:%@Z\r\n"
- @"DTSTART:%@Z\r\n"
- @"DTEND:%@Z\r\n"
- @"TRANSP:%@\r\n"
- @"SEQUENCE:1\r\n"
- @"PRIORITY:5\r\n"
- @"%@" /* organizer */
- @"%@" /* participants and resources */
- @"END:VEVENT\r\n"
- @"END:VCALENDAR";
-
- NSTimeZone *utc;
- NSCalendarDate *lStartDate, *lEndDate, *stamp;
- NSString *template, *s;
- unsigned minutes;
-
- s = [self queryParameterForKey:@"dur"];
- if ([s length] > 0)
- minutes = [s intValue];
+- (NSString *) itemRepeatText
+{
+ NSString *text;
+
+ if ([item isEqualToString: @"-"])
+ text = item;
else
- minutes = 60;
-
- utc = [NSTimeZone timeZoneWithName: @"GMT"];
- lStartDate = [self newStartDate];
- [lStartDate setTimeZone: utc];
- lEndDate = [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],
- [stamp iCalFormattedDateTimeString],
- [lStartDate iCalFormattedDateTimeString],
- [lEndDate iCalFormattedDateTimeString],
- [self transparency],
- [self iCalOrganizerString],
- s];
- return template;
+ text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
+
+ return text;
}
-/* new */
+- (void) setItem: (NSString *) newItem
+{
+ item = newItem;
+}
+
+- (NSString *) item
+{
+ return item;
+}
-- (id) newAction
+- (NSArray *) reminderList
{
- /*
- 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/%@/editAsAppointment", 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];
+ static NSArray *reminderItems = nil;
+
+ if (!reminderItems)
+ {
+ reminderItems = [NSArray arrayWithObjects: @"5_MINUTES_BEFORE",
+ @"10_MINUTES_BEFORE",
+ @"15_MINUTES_BEFORE",
+ @"30_MINUTES_BEFORE",
+ @"45_MINUTES_BEFORE",
+ @"-",
+ @"1_HOUR_BEFORE",
+ @"2_HOURS_BEFORE",
+ @"5_HOURS_BEFORE",
+ @"15_HOURS_BEFORE",
+ @"-",
+ @"1_DAY_BEFORE",
+ @"2_DAYS_BEFORE",
+ @"1_WEEK_BEFORE",
+ @"-",
+ @"CUSTOM",
+ nil];
+ [reminderItems retain];
}
- ps = [emails componentsJoinedByString:@","];
- [self setQueryParameter:ps forKey:@"ps"];
- }
- uri = [self completeHrefForMethod:method];
- return [self redirectToLocation:uri];
+
+ return reminderItems;
}
-/* save */
+// - (void) setReminder: (NSString *) reminder
+// {
+// ASSIGN(reminder, _reminder);
+// }
-- (void) loadValuesFromAppointment: (iCalEvent *) appointment
-{
- NSTimeZone *uTZ;
+// - (NSString *) reminder
+// {
+// return reminder;
+// }
- [self loadValuesFromComponent: appointment];
+- (NSString *) itemReminderText
+{
+ NSString *text;
- uTZ = [[self clientObject] userTimeZone];
- endDate = [appointment endDate];
- if (!endDate)
- endDate = [[self startDate] dateByAddingYears: 0 months: 0 days: 0
- hours: 1 minutes: 0 seconds: 0];
+ if ([item isEqualToString: @"-"])
+ text = item;
+ else
+ text = [self labelForKey: [NSString stringWithFormat: @"reminder_%@", item]];
- [endDate setTimeZone: uTZ];
- [endDate retain];
+ return text;
}
-- (void) saveValuesIntoAppointment: (iCalEvent *) _appointment
+- (NSString *) repeat
{
- /* merge in form values */
- NSArray *attendees, *lResources;
- iCalRecurrenceRule *rrule;
-
- [_appointment setStartDate:[self aptStartDate]];
- [_appointment setEndDate:[self aptEndDate]];
-
- [_appointment setSummary: [self title]];
- [_appointment setUrl: [self url]];
- [_appointment setLocation: [self location]];
- [_appointment setComment: [self comment]];
- [_appointment setPriority:[self priority]];
- [_appointment setAccessClass: [self privacy]];
- [_appointment setStatus: [self status]];
-
-// [_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: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"];
- [_appointment setAttendees: attendees];
-
- /* cycles */
- [_appointment removeAllRecurrenceRules];
- rrule = [self rrule];
- if (rrule)
- [_appointment addToRecurrenceRules: rrule];
+ return @"";
}
-- (iCalEvent *) appointmentFromString: (NSString *) _iCalString
+- (void) setRepeat: (NSString *) newRepeat
{
- iCalCalendar *calendar;
- iCalEvent *appointment;
-
- calendar = [iCalCalendar parseSingleFromSource: _iCalString];
- appointment = (iCalEvent *) [calendar firstChildWithTag: @"vevent"];
-
- return appointment;
}
-/* conflict management */
+- (NSString *) reminder
+{
+ return @"";
+}
-- (BOOL) containsConflict: (id) _apt
+- (void) setReminder: (NSString *) newReminder
{
- NSArray *attendees, *uids;
- SOGoAppointmentFolder *groupCalendar;
- NSArray *infos;
- NSArray *ranges;
- id folder;
-
- [self logWithFormat:@"search from %@ to %@",
- [_apt startDate], [_apt endDate]];
-
- folder = [[self clientObject] container];
- attendees = [_apt 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:[_apt startDate]
- to:[_apt endDate]];
- [self debugWithFormat:@" process: %d events", [infos count]];
-
- ranges = [infos arrayByCreatingDateRangesFromObjectsWithStartDateKey: @"startDate"
- andEndDateKey: @"endDate"];
- ranges = [ranges arrayByCompactingContainedDateRanges];
- [self debugWithFormat:@" blocked ranges: %@", ranges];
-
- return [ranges count] != 0 ? YES : NO;
}
/* actions */
-
-- (id) testAction
+- (NSCalendarDate *) newStartDate
{
- /* for testing only */
- WORequest *req;
- iCalEvent *apt;
- NSString *content;
-
- req = [[self context] request];
- apt = [self appointmentFromString: [self iCalString]];
- [self saveValuesIntoAppointment:apt];
- content = [[apt parent] versitString];
- [self logWithFormat:@"%s -- iCal:\n%@",
- __PRETTY_FUNCTION__,
- content];
+ NSCalendarDate *newStartDate, *now;
+ int hour;
+
+ newStartDate = [self selectedDate];
+ if ([[self queryParameterForKey: @"hm"] length] == 0)
+ {
+ now = [NSCalendarDate calendarDate];
+ [now setTimeZone: [[self clientObject] userTimeZone]];
+ if ([now isDateOnSameDay: 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;
+ }
+ else
+ newStartDate = [newStartDate hour: 8 minute: 0];
+ }
- return self;
+ return newStartDate;
}
-- (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] contentAsString];
- if ([ical length] == 0) /* a new appointment */
- 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"]];
-// }
+ NSCalendarDate *startDate, *endDate;
+ NSString *duration;
+ unsigned int minutes;
+
+ event = (iCalEvent *) [[self clientObject] component: NO];
+ if (event)
+ {
+ startDate = [event startDate];
+ endDate = [event endDate];
+ }
+ else
+ {
+ startDate = [self newStartDate];
+ duration = [self queryParameterForKey:@"dur"];
+ if ([duration length] > 0)
+ minutes = [duration intValue];
+ else
+ minutes = 60;
+ endDate
+ = [startDate dateByAddingYears: 0 months: 0 days: 0
+ hours: 0 minutes: minutes seconds: 0];
+ }
+
+ ASSIGN (aptStartDate, startDate);
+ ASSIGN (aptEndDate, endDate);
+
+ /* here comes the code for initializing repeat, reminder and isAllDay... */
+
return self;
}
-- (id <WOActionResults>) saveAction
+- (id <WOActionResults>) newAction
{
- iCalEvent *apt;
- iCalPerson *p;
+ NSString *objectId, *method, *uri;
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"];
- }
-
- apt = [self appointmentFromString: [self iCalString]];
- if (apt == nil) {
- NSString *s;
-
- s = [self labelForKey:@"Invalid iCal data!"];
- [self setErrorText:s];
- return self;
- }
-
- [self saveValuesIntoAppointment:apt];
- p = [apt findParticipantWithEmail:[self emailForUser]];
- if (p) {
- [p setParticipationStatus:iCalPersonPartStatAccepted];
- }
-
- if ([self checkForConflicts]) {
- if ([self containsConflict:apt]) {
- NSString *s;
-
- s = [self labelForKey:@"Conflicts found!"];
- [self setErrorText:s];
-
- return self;
+ Class clientKlazz;
+
+ clientKlazz = [[self clientObject] class];
+ objectId = [clientKlazz globallyUniqueObjectId];
+ if ([objectId length] > 0)
+ {
+ method = [NSString stringWithFormat:@"%@/Calendar/%@/editAsAppointment",
+ [self userFolderPath], objectId];
+ uri = [self completeHrefForMethod: method];
+ result = [self redirectToLocation: uri];
}
- }
- content = [[apt parent] versitString];
-// [apt release]; apt = 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: @"refreshAppointmentsAndDisplay()"];
+ result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */
+ reason: @"could not create a unique ID"];
return result;
}
-- (NSString *) saveUrl
+- (id <WOActionResults>) saveAction
{
- return [NSString stringWithFormat: @"%@/saveAsAppointment",
- [[self clientObject] baseURL]];
+ SOGoAppointmentObject *clientObject;
+ NSString *iCalString;
+
+ clientObject = [self clientObject];
+ iCalString = [[clientObject calendar: NO] versitString];
+ [clientObject saveContentString: iCalString];
+
+ return [self jsCloseWithRefreshMethod: @"refreshAppointmentsAndDisplay()"];
}
-- (id) acceptAction
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
+ inContext: (WOContext*) context
{
- return [self acceptOrDeclineAction:YES];
+ return ([[self clientObject] isKindOfClass: [SOGoAppointmentObject class]]
+ && [[request method] isEqualToString: @"POST"]);
}
-- (id) declineAction
+- (void) takeValuesFromRequest: (WORequest *) _rq
+ inContext: (WOContext *) _ctx
{
- return [self acceptOrDeclineAction:NO];
+ SOGoAppointmentObject *clientObject;
+
+ clientObject = [self clientObject];
+ event = (iCalEvent *) [clientObject component: YES];
+
+ [super takeValuesFromRequest: _rq inContext: _ctx];
+
+ [event setStartDate: aptStartDate];
+ [event setEndDate: aptEndDate];
+ if ([clientObject isNew])
+ [event setTransparency: @"OPAQUE"];
}
// 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"]];
+ [[self clientObject] changeParticipationStatus:
+ _accept ? @"ACCEPTED" : @"DECLINED"
+ inContext: [self context]];
+
+ return self;
+}
+
+- (id) acceptAction
+{
+ return [self acceptOrDeclineAction:YES];
+}
+
+- (id) declineAction
+{
+ return [self acceptOrDeclineAction:NO];
}
-@end /* UIxAppointmentEditor */
+@end
if (!appointment)
{
clientObject = [self clientObject];
- appointment = (iCalEvent *) [clientObject component];
+ appointment = (iCalEvent *) [clientObject component: NO];
[appointment retain];
}
@interface UIxComponentEditor : UIxComponent
{
- NSString *iCalString;
- NSString *errorText;
+ iCalRepeatableEntityObject *component;
id item;
+
+ NSString *saveURL;
/* 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;
+ iCalPerson *organizer;
NSString *componentOwner;
- BOOL componentLoaded;
+ NSString *attendeesNames;
+ NSString *attendeesEmails;
}
-- (NSArray *) categoryItems;
+- (void) setComponent: (iCalRepeatableEntityObject *) newComponent;
+
+- (void) setSaveURL: (NSString *) newSaveURL;
+- (NSString *) saveURL;
+
+- (NSArray *) categoryList;
- (void) setCategories: (NSArray *) _categories;
- (NSArray *) categories;
- (NSString *) itemCategoryText;
- (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) setUrl: (NSString *) _url;
- (NSString *) url;
-- (void) setParticipants: (NSArray *) _parts;
-- (NSArray *) participants;
+- (void) setAttendeesNames: (NSString *) newAttendeesNames;
+- (NSString *) attendeesNames;
-- (void) setResources: (NSArray *) _res;
-- (NSArray *) resources;
-
-- (void) setCheckForConflicts: (BOOL) _checkForConflicts;
-- (BOOL) checkForConflicts;
+- (void) setAttendeesEmails: (NSString *) newAttendeesEmails;
+- (NSString *) attendeesEmails;
- (NSArray *) cycles;
- (void) setCycle: (NSDictionary *) _cycle;
- (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
{
if ((self = [super init]))
{
+ component = nil;
[self setPrivacy: @"PUBLIC"];
- [self setCheckForConflicts: NO];
[self setIsCycleEndNever];
componentOwner = @"";
- componentLoaded = NO;
+ organizer = nil;
+ attendeesNames = nil;
+ attendeesEmails = nil;
}
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];
+ [attendeesNames release];
+ [attendeesEmails release];
[super dealloc];
}
+- (void) _loadAttendees
+{
+ NSEnumerator *attendees;
+ iCalPerson *currentAttendee;
+ NSMutableString *names, *emails;
+
+ names = [NSMutableString new];
+ emails = [NSMutableString new];
+
+ attendees = [[component attendees] objectEnumerator];
+ currentAttendee = [attendees nextObject];
+ while (currentAttendee)
+ {
+ NSLog (@"currentCN: %@", [currentAttendee cn]);
+ [names appendFormat: @"%@,", [currentAttendee cn]];
+ [emails appendFormat: @"%@,", [currentAttendee rfc822Email]];
+ currentAttendee = [attendees nextObject];
+ }
+
+ if ([names length] > 0)
+ {
+ ASSIGN (attendeesNames, [names substringToIndex: [names length] - 1]);
+ ASSIGN (attendeesEmails,
+ [emails substringToIndex: [emails length] - 1]);
+ }
+
+ [names release];
+ [emails release];
+}
+
+/* warning: we use this method which will be triggered by the template system
+ when the page is instantiated, but we should find another and cleaner way of
+ doing this... for example, when the clientObject is set */
+- (void) setComponent: (iCalRepeatableEntityObject *) newComponent
+{
+// iCalRecurrenceRule *rrule;
+ SOGoObject *co;
+
+ if (!component)
+ {
+ component = newComponent;
+
+ co = [self clientObject];
+ componentOwner = [co ownerInContext: nil];
+
+ ASSIGN (title, [component summary]);
+ ASSIGN (location, [component location]);
+ ASSIGN (comment, [component comment]);
+ ASSIGN (url, [[component url] absoluteString]);
+ ASSIGN (privacy, [component accessClass]);
+ ASSIGN (priority, [component priority]);
+ ASSIGN (status, [component status]);
+ ASSIGN (categories, [[component categories] commaSeparatedValues]);
+ ASSIGN (organizer, [component organizer]);
+ [self _loadAttendees];
+ }
+// /* cycles */
+// if ([component isRecurrent])
+// {
+// rrule = [[component recurrenceRules] objectAtIndex: 0];
+// [self adjustCycleControlsForRRule: rrule];
+// }
+}
+
+- (void) setSaveURL: (NSString *) newSaveURL
+{
+ saveURL = newSaveURL;
+}
+
+- (NSString *) saveURL
+{
+ return saveURL;
+}
+
/* accessors */
- (void) setItem: (id) _item
{
- ASSIGN(item, _item);
+ ASSIGN (item, _item);
}
- (id) item
return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
}
-- (void) setErrorText: (NSString *) _txt
-{
- ASSIGNCOPY(errorText, _txt);
-}
-
-- (NSString *) errorText
+- (void) setTitle: (NSString *) _value
{
- return errorText;
+ ASSIGN (title, _value);
}
-- (BOOL) hasErrorText
+- (NSString *) title
{
- return [errorText length] > 0 ? YES : NO;
+ return title;
}
-- (void) setStartDate: (NSCalendarDate *) _date
+- (void) setUrl: (NSString *) _url
{
- ASSIGN(startDate, _date);
+ ASSIGN (url, _url);
}
-- (NSCalendarDate *) startDate
+- (NSString *) url
{
- return startDate;
+ return url;
}
-- (void) setTitle: (NSString *) _value
+- (void) setAttendeesNames: (NSString *) newAttendeesNames
{
- ASSIGNCOPY(title, _value);
+ ASSIGN (attendeesNames, newAttendeesNames);
}
-- (NSString *) title
+- (NSString *) attendeesNames
{
- return title;
+ return attendeesNames;
}
-- (void) setUrl: (NSString *) _url
+- (void) setAttendeesEmails: (NSString *) newAttendeesEmails
{
- ASSIGNCOPY(url, _url);
+ ASSIGN (attendeesEmails, newAttendeesEmails);
}
-- (NSString *) url
+- (NSString *) attendeesEmails
{
- return url;
+ return attendeesEmails;
}
- (void) setLocation: (NSString *) _value
{
- ASSIGNCOPY(location, _value);
+ ASSIGN (location, _value);
}
- (NSString *) location
- (void) setComment: (NSString *) _value
{
- ASSIGNCOPY(comment, _value);
+ ASSIGN (comment, _value);
}
- (NSString *) comment
return comment;
}
-- (NSArray *) categoryItems
+- (NSArray *) categoryList
{
- // 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 = [NSArray arrayWithObjects: @"ANNIVERSARY",
+ @"BIRTHDAY",
+ @"BUSINESS",
+ @"CALLS",
+ @"CLIENTS",
+ @"COMPETITION",
+ @"CUSTOMER",
+ @"FAVORITES",
+ @"FOLLOW UP",
+ @"GIFTS",
+ @"HOLIDAYS",
+ @"IDEAS",
+ @"ISSUES",
+ @"MISCELLANEOUS",
+ @"PERSONAL",
+ @"PROJECTS",
+ @"PUBLIC HOLIDAY",
+ @"STATUS",
+ @"SUPPLIERS",
+ @"TRAVEL",
+ @"VACATION",
+ nil];
[categoryItems retain];
}
- (void) setCategories: (NSArray *) _categories
{
- ASSIGN(categories, _categories);
+ ASSIGN (categories, _categories);
}
- (NSArray *) categories
- (NSString *) itemCategoryText
{
- return [[self labelForKey: item] stringByEscapingHTMLString];
+ return [self labelForKey: [NSString stringWithFormat: @"category_%@", item]];
}
/* priorities */
if (!priorities)
{
- priorities = [NSArray arrayWithObjects:@"0", @"5", @"1", nil];
+ priorities = [NSArray arrayWithObjects: @"0", @"5", @"1", nil];
[priorities retain];
}
- (void) setPriority: (NSString *) _priority
{
- ASSIGN(priority, _priority);
+ ASSIGN (priority, _priority);
}
- (NSString *) priority
- (void) setPrivacy: (NSString *) _privacy
{
- ASSIGN(privacy, _privacy);
+ ASSIGN (privacy, _privacy);
}
- (NSString *) privacy
- (void) setStatus: (NSString *) _status
{
- ASSIGN(status, _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;
if (!cycles)
{
bundle = [NSBundle bundleForClass:[self class]];
- path = [bundle pathForResource:@"cycles" ofType:@"plist"];
+ 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!");
- (void) setCycle: (NSDictionary *) _cycle
{
- ASSIGN(cycle, _cycle);
+ ASSIGN (cycle, _cycle);
}
- (NSDictionary *) cycle
{
NSString *key;
- key = [(NSDictionary *)item objectForKey:@"label"];
+ key = [(NSDictionary *)item objectForKey: @"label"];
return [self labelForKey:key];
}
- (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate
{
- NSCalendarDate *until;
+// 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);
+// /* 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
if (![self hasCycle])
return nil;
- ruleRep = [cycle objectForKey:@"rule"];
+ ruleRep = [cycle objectForKey: @"rule"];
rule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:ruleRep];
if (cycleUntilDate && [self isCycleEndUntil])
- (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule
{
- NSDictionary *c;
- NSCalendarDate *until;
+// NSDictionary *c;
+// NSCalendarDate *until;
- c = [self cycleMatchingRRule:_rrule];
- [self setCycle:c];
+// c = [self cycleMatchingRRule:_rrule];
+// [self setCycle:c];
- until = [[[_rrule untilDate] copy] autorelease];
- if (!until)
- until = startDate;
- else
- [self setIsCycleEndUntil];
+// until = [[[_rrule untilDate] copy] autorelease];
+// if (!until)
+// until = startDate;
+// else
+// [self setIsCycleEndUntil];
- [until setTimeZone:[[self clientObject] userTimeZone]];
- [self setCycleUntilDate:until];
+// [until setTimeZone:[[self clientObject] userTimeZone]];
+// [self setCycleUntilDate:until];
}
/*
NSString *cr;
c = [cycles objectAtIndex:i];
- cr = [c objectForKey:@"rule"];
+ cr = [c objectForKey: @"rule"];
if ([cr isEqualToString:cycleRep])
return c;
}
- [self warnWithFormat:@"No default cycle for rrule found! -> %@", _rrule];
+ [self warnWithFormat: @"No default cycle for rrule found! -> %@", _rrule];
return nil;
}
- (void) setCycleEnd: (NSString *) _cycleEnd
{
- ASSIGNCOPY(cycleEnd, _cycleEnd);
+ ASSIGN (cycleEnd, _cycleEnd);
}
- (NSString *) cycleEnd
- (BOOL) isCycleEndUntil
{
- return (cycleEnd &&
- [cycleEnd isEqualToString:@"cycle_end_until"]);
+ return (cycleEnd && [cycleEnd isEqualToString: @"cycle_end_until"]);
}
- (void) setIsCycleEndUntil
{
- [self setCycleEnd:@"cycle_end_until"];
+ [self setCycleEnd: @"cycle_end_until"];
}
- (void) setIsCycleEndNever
{
- [self setCycleEnd:@"cycle_end_never"];
+ [self setCycleEnd: @"cycle_end_never"];
}
/* helpers */
uri = [[[self context] request] uri];
/* first: identify query parameters */
- r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
+ r = [uri rangeOfString: @"?" options:NSBackwardsSearch];
if (r.length > 0)
uri = [uri substringToIndex:r.location];
/* next: append trailing slash */
- if (![uri hasSuffix:@"/"])
- uri = [uri stringByAppendingString:@"/"];
+ if (![uri hasSuffix: @"/"])
+ uri = [uri stringByAppendingString: @"/"];
/* next: append method */
uri = [uri stringByAppendingString:_method];
- (BOOL) isWriteableClientObject
{
return [[self clientObject]
- respondsToSelector:@selector(saveContentString:)];
-}
-
-- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq
- inContext: (WOContext*) _c
-{
- return YES;
+ respondsToSelector: @selector(saveContentString:)];
}
- (BOOL) containsConflict: (id) _component
: @"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 isDateOnSameDay: 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;
- }
- else
- newStartDate = [newStartDate hour: 8 minute: 0];
- }
-
- 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;
NSArray *es;
unsigned i, count;
- es = [s componentsSeparatedByString:@","];
+ es = [s componentsSeparatedByString: @","];
count = [es count];
for(i = 0; i < count; i++) {
NSString *email, *cn;
[self cnForUser], [self emailForUser]];
}
-- (NSString *) saveUrl
-{
- [self subclassResponsibility: _cmd];
-
- return @"";
-}
-
- (NSException *) validateObjectForStatusChange
{
id co;
/* contact editor compatibility */
-- (void) setICalString: (NSString *) _s
-{
- ASSIGNCOPY(iCalString, _s);
-}
-
-- (NSString *) iCalString
-{
- return iCalString;
-}
-
- (NSArray *) availableCalendars
{
NSEnumerator *rawContacts;
return classes;
}
-- (NSString *) _toolbarForCalObject: (iCalEntityObject *) calObject
+- (void) _handleAttendeesEdition
{
- NSString *filename, *myEmail;
- iCalPerson *person;
- NSEnumerator *persons;
- iCalPersonPartStat myParticipationStatus;
- BOOL found;
+ NSArray *names, *emails;
+ NSMutableArray *newAttendees;
+ unsigned int count, max;
+ NSString *currentEmail;
+ iCalPerson *currentAttendee;
- myEmail = [[[self context] activeUser] email];
- if ([[organizer rfc822Email] isEqualToString: myEmail])
- filename = @"SOGoAppointmentObject.toolbar";
- else
+ newAttendees = [NSMutableArray new];
+ if ([attendeesNames length] > 0)
{
- 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];
+ names = [attendeesNames componentsSeparatedByString: @","];
+ emails = [attendeesEmails componentsSeparatedByString: @","];
+ max = [emails count];
+ for (count = 0; count < max; count++)
+ {
+ currentEmail = [emails objectAtIndex: count];
+ currentAttendee = [component findParticipantWithEmail: currentEmail];
+ if (!currentAttendee)
+ {
+ currentAttendee = [iCalPerson elementWithTag: @"attendee"];
+ [currentAttendee setCn: [names objectAtIndex: count]];
+ [currentAttendee setEmail: currentEmail];
+ [currentAttendee setRole: @"REQ-PARTICIPANT"];
+ [currentAttendee
+ setParticipationStatus: iCalPersonPartStatNeedsAction];
+ }
+ [newAttendees addObject: currentAttendee];
+ }
}
- return filename;
+ [component setAttendees: newAttendees];
+ [newAttendees release];
}
-- (NSString *) toolbar
+- (void) _handleOrganizer
{
- NSString *filename;
- iCalEntityObject *calObject;
- SOGoCalendarComponent *co;
+ NSString *organizerEmail;
- if (componentLoaded)
+ organizerEmail = [[component organizer] email];
+ if ([organizerEmail length] == 0)
{
- co = [self clientObject];
- calObject = [co component];
- filename = [self _toolbarForCalObject: calObject];
+ if ([[component attendees] count] > 0)
+ {
+ ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
+ [organizer setCn: [self cnForUser]];
+ [organizer setEmail: [self emailForUser]];
+ [component setOrganizer: organizer];
+ }
}
else
- filename = @"";
+ {
+ if ([[component attendees] count] == 0)
+ {
+ ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
+ [component setOrganizer: organizer];
+ }
+ }
+}
+
+- (void) takeValuesFromRequest: (WORequest *) _rq
+ inContext: (WOContext *) _ctx
+{
+ NSCalendarDate *now;
- return filename;
+ [super takeValuesFromRequest: _rq inContext: _ctx];
+
+ now = [NSCalendarDate calendarDate];
+ [component setSummary: title];
+ [component setLocation: location];
+ [component setComment: comment];
+ [component setUrl: url];
+ [self _handleAttendeesEdition];
+ [self _handleOrganizer];
+ if ([[self clientObject] isNew])
+ {
+ [component setCreated: now];
+ [component setTimeStampAsDate: now];
+ [component setPriority: @"0"];
+ }
+ [component setLastModified: now];
}
@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
/* UIxTaskEditor.h - this file is part of SOGo
*
- * Copyright (C) 2006 Inverse groupe conseil
+ * Copyright (C) 2007 Inverse groupe conseil
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* Boston, MA 02111-1307, USA.
*/
-#ifndef UIXTASKEDITOR_H
-#define UIXTASKEDITOR_H
+#ifndef UIXAPPOINTMENTEDITOR_H
+#define UIXAPPOINTMENTEDITOR_H
-#import "UIxComponentEditor.h"
+#import <SOGoUI/UIxComponent.h>
-@class NSString;
-@class iCalPerson;
-@class iCalRecurrenceRule;
@class iCalToDo;
+@class NSString;
-@interface UIxTaskEditor : UIxComponentEditor
+@interface UIxTaskEditor : UIxComponent
{
- NSCalendarDate *dueDate;
+ iCalToDo *todo;
+ NSCalendarDate *taskStartDate;
+ NSCalendarDate *taskDueDate;
+ NSCalendarDate *statusDate;
+ NSString *status;
+ NSString *statusPercent;
BOOL hasStartDate;
BOOL hasDueDate;
- BOOL newTask;
+ NSString *item;
}
+/* template values */
+- (NSString *) saveURL;
+- (iCalToDo *) todo;
+
+/* icalendar values */
- (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;
+- (NSString *) repeat;
+- (void) setRepeat: (NSString *) newRepeat;
@end
-#endif /* UIXTASKEDITOR_H */
+#endif /* UIXAPPOINTMENTEDITOR_H */
-/*
- Copyright (C) 2004-2005 SKYRIX Software AG
-
- This file is part of OpenGroupware.org.
+/* UIxTaskEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 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 <NGObjWeb/SoObject.h>
+#import <NGObjWeb/WORequest.h>
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
+
+#import <NGCards/iCalToDo.h>
+#import <NGCards/iCalPerson.h>
+
+#import <SoObjects/SOGo/AgenorUserManager.h>
+#import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/SOGo/SOGoContentObject.h>
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
+#import <SoObjects/Appointments/SOGoTaskObject.h>
+
+#import "UIxComponentEditor.h"
+#import "UIxTaskEditor.h"
- 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.
+@implementation UIxTaskEditor
- 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.
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ taskStartDate = nil;
+ taskDueDate = nil;
+ statusDate = nil;
+ hasStartDate = NO;
+ hasDueDate = NO;
+ status = nil;
+ statusPercent = nil;
+ item = nil;
+ todo = nil;
+ }
- 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.
-*/
+ return self;
+}
-#import <SOGo/NSCalendarDate+SOGo.h>
+- (void) dealloc
+{
+ [taskStartDate release];
+ [taskDueDate release];
+ [statusDate release];
+ [status release];
+ [statusPercent release];
+ [super dealloc];
+}
-#import "UIxTaskEditor.h"
+/* template values */
+- (iCalToDo *) todo
+{
+ return todo;
+}
-/* TODO: CLEAN UP */
+- (NSString *) saveURL
+{
+ return [NSString stringWithFormat: @"%@/saveAsTask",
+ [[self clientObject] baseURL]];
+}
-#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"
+- (NSString *) _toolbarForCalObject
+{
+ SOGoUser *currentUser;
+ SOGoTaskObject *clientObject;
+ NSString *filename, *email;
+ iCalPerson *person;
+ iCalPersonPartStat participationStatus;
+
+ clientObject = [self clientObject];
+ currentUser = [[self context] activeUser];
+ email = [currentUser email];
+ if ([clientObject isOrganizer: email
+ orOwner: [currentUser login]])
+ filename = @"SOGoTaskObject.toolbar";
+ else
+ {
+ if ([clientObject isParticipant: email])
+ {
+ person = [[clientObject component: NO] findParticipantWithEmail: email];
+ participationStatus = [person participationStatus];
+ if (participationStatus == iCalPersonPartStatAccepted)
+ filename = @"SOGoTaskObjectDecline.toolbar";
+ else if (participationStatus == iCalPersonPartStatDeclined)
+ filename = @"SOGoTaskObjectAccept.toolbar";
+ else
+ filename = @"SOGoTaskObjectAcceptOrDecline.toolbar";
+ }
+ else
+ filename = @"SOGoComponentClose.toolbar";
+ }
-@implementation UIxTaskEditor
+ return filename;
+}
-- (void) dealloc
+- (NSString *) toolbar
{
- [dueDate release];
- [super dealloc];
+ return ([self _toolbarForCalObject]);
}
-- (void) setTaskStartDate: (NSCalendarDate *) _date
+/* icalendar values */
+- (void) setTaskStartDate: (NSCalendarDate *) newTaskStartDate
{
- [self setStartDate: _date];
+ ASSIGN (taskStartDate, newTaskStartDate);
}
- (NSCalendarDate *) taskStartDate
{
- return [self startDate];
+ return taskStartDate;
+}
+
+- (void) setHasStartDate: (BOOL) newHasStartDate
+{
+ hasStartDate = newHasStartDate;
}
-- (void) setTaskDueDate: (NSCalendarDate *) _date
+- (BOOL) hasStartDate
{
- ASSIGN(dueDate, _date);
+ return hasStartDate;
+}
+
+- (BOOL) startDateDisabled
+{
+ return !hasStartDate;
+}
+
+- (void) setTaskDueDate: (NSCalendarDate *) newTaskDueDate
+{
+ ASSIGN (taskDueDate, newTaskDueDate);
}
- (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];
+ return taskDueDate;
}
-/* save */
+- (void) setHasDueDate: (BOOL) newHasDueDate
+{
+ hasDueDate = newHasDueDate;
+}
+
+- (BOOL) hasDueDate
+{
+ return hasDueDate;
+}
-- (void) loadValuesFromTask: (iCalToDo *) _task
+- (BOOL) dueDateDisabled
{
- NSTimeZone *uTZ;
+ return !hasDueDate;
+}
- [self loadValuesFromComponent: _task];
+- (NSArray *) repeatList
+{
+ static NSArray *repeatItems = nil;
- 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)
+ if (!repeatItems)
{
- [dueDate setTimeZone: uTZ];
- [dueDate retain];
+ repeatItems = [NSArray arrayWithObjects: @"DAILY",
+ @"WEEKLY",
+ @"BI-WEEKLY",
+ @"EVERY WEEKDAY",
+ @"MONTHLY",
+ @"YEARLY",
+ @"-",
+ @"CUSTOM",
+ nil];
+ [repeatItems retain];
}
+
+ return repeatItems;
}
-- (void) saveValuesIntoTask: (iCalToDo *) _task
+- (NSString *) itemRepeatText
{
- /* merge in form values */
- NSArray *attendees, *lResources;
- iCalRecurrenceRule *rrule;
- NSCalendarDate *dateTime;
+ NSString *text;
- if (hasStartDate)
- dateTime = [self taskStartDate];
+ if ([item isEqualToString: @"-"])
+ text = item;
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;
-
- calendar = [iCalCalendar parseSingleFromSource: _iCalString];
- task = (iCalToDo *) [calendar firstChildWithTag: @"vtodo"];
-
- 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;
+ text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
+
+ return text;
}
-- (id <WOActionResults>) defaultAction
+- (NSArray *) statusList
{
- NSString *ical;
+ static NSArray *statusItems = nil;
- /* load iCalendar file */
-
- // TODO: can't we use [clientObject contentAsString]?
-// ical = [[self clientObject] valueForKey:@"iCalString"];
- ical = [[self clientObject] contentAsString];
- if ([ical length] == 0)
+ if (!statusItems)
{
- newTask = YES;
- ical = [self iCalStringTemplate];
+ statusItems = [NSArray arrayWithObjects: @"NEEDS-ACTION",
+ @"IN-PROCESS",
+ @"COMPLETED",
+ @"CANCELLED",
+ nil];
+ [statusItems retain];
}
- 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 statusItems;
+}
- return self;
+- (NSString *) itemStatusText
+{
+ return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
}
-- (id <WOActionResults>) saveAction
+- (void) setItem: (NSString *) newItem
{
- 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()"];
+ item = newItem;
+}
- return result;
+- (NSString *) item
+{
+ return item;
}
-- (id) changeStatusAction
+- (NSString *) repeat
{
- iCalToDo *task;
- SOGoTaskObject *taskObject;
- NSString *content;
- id ex;
- int newStatus;
+ return @"";
+}
- newStatus = [[self queryParameterForKey: @"status"] intValue];
+- (void) setRepeat: (NSString *) newRepeat
+{
+}
- taskObject = [self clientObject];
- task = (iCalToDo *) [taskObject component];
- 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"];
- }
+- (NSString *) status
+{
+ return status;
+}
- content = [[task parent] versitString];
- ex = [[self clientObject] saveContentString: content];
- if (ex != nil) {
- [self setErrorText:[ex reason]];
- return self;
- }
-
- return [self redirectToLocation: [self completeURIForMethod: @".."]];
+- (void) setStatus: (NSString *) newStatus
+{
+ status = newStatus;
}
-- (id)acceptAction {
- return [self acceptOrDeclineAction:YES];
+- (void) setStatusDate: (NSCalendarDate *) newStatusDate
+{
+ ASSIGN (statusDate, newStatusDate);
}
-- (id)declineAction {
- return [self acceptOrDeclineAction:NO];
+- (NSCalendarDate *) statusDate
+{
+ return statusDate;
}
-- (NSString *) saveUrl
+- (BOOL) statusDateDisabled
{
- return [NSString stringWithFormat: @"%@/saveAsTask",
- [[self clientObject] baseURL]];
+ return ![status isEqualToString: @"COMPLETED"];
}
-// TODO: add tentatively
+- (BOOL) statusPercentDisabled
+{
+ NSLog (@"status: '%@'", status);
+ return ([status length] == 0
+ || [status isEqualToString: @"CANCELLED"]);
+}
+
+- (void) setStatusPercent: (NSString *) newStatusPercent
+{
+ ASSIGN (statusPercent, newStatusPercent);
+}
+
+- (NSString *) statusPercent
+{
+ return statusPercent;
+}
+
+/* actions */
+- (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 isDateOnSameDay: 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;
+ }
+ else
+ newStartDate = [newStartDate hour: 8 minute: 0];
+ }
+
+ return newStartDate;
+}
+
+- (id <WOActionResults>) defaultAction
+{
+ NSCalendarDate *startDate, *dueDate;
+ NSString *duration;
+ unsigned int minutes;
+
+ todo = (iCalToDo *) [[self clientObject] component: NO];
+ if (todo)
+ {
+ startDate = [todo startDate];
+ dueDate = [todo due];
+ hasStartDate = (startDate != nil);
+ hasDueDate = (dueDate != nil);
+ ASSIGN (status, [todo status]);
+ if ([status isEqualToString: @"COMPLETED"])
+ ASSIGN (statusDate, [todo completed]);
+ else
+ ASSIGN (statusDate, [self newStartDate]);
+ ASSIGN (statusPercent, [todo percentComplete]);
+ }
+ else
+ {
+ startDate = [self newStartDate];
+ duration = [self queryParameterForKey:@"dur"];
+ if ([duration length] > 0)
+ minutes = [duration intValue];
+ else
+ minutes = 60;
+ dueDate = [startDate dateByAddingYears: 0 months: 0 days: 0
+ hours: 0 minutes: minutes seconds: 0];
+ hasStartDate = NO;
+ hasDueDate = NO;
+ ASSIGN (statusDate, [self newStartDate]);
+ ASSIGN (status, @"");
+ ASSIGN (statusPercent, @"");
+ }
+
+ ASSIGN (taskStartDate, startDate);
+ ASSIGN (taskDueDate, dueDate);
+
+ /* here comes the code for initializing repeat, reminder and isAllDay... */
-- (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
+- (id <WOActionResults>) newAction
{
- hasStartDate = aBool;
+ NSString *objectId, *method, *uri;
+ id <WOActionResults> result;
+ Class clientKlazz;
+
+ clientKlazz = [[self clientObject] class];
+ objectId = [clientKlazz globallyUniqueObjectId];
+ if ([objectId length] > 0)
+ {
+ method = [NSString stringWithFormat:@"%@/Calendar/%@/editAsTask",
+ [self userFolderPath], objectId];
+ uri = [self completeHrefForMethod: method];
+ result = [self redirectToLocation: uri];
+ }
+ else
+ result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */
+ reason: @"could not create a unique ID"];
+
+ return result;
}
-- (BOOL) hasStartDate
+- (id <WOActionResults>) saveAction
{
- return (!newTask && [self taskStartDate] != nil);
+ SOGoTaskObject *clientObject;
+ NSString *iCalString;
+
+ clientObject = [self clientObject];
+ iCalString = [[clientObject calendar: NO] versitString];
+ [clientObject saveContentString: iCalString];
+
+ return [self jsCloseWithRefreshMethod: @"refreshTasks()"];
}
-- (BOOL) startDateDisabled
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
+ inContext: (WOContext*) context
{
- return (![self hasStartDate]);
+ return ([[self clientObject] isKindOfClass: [SOGoTaskObject class]]
+ && [[request method] isEqualToString: @"POST"]);
}
-- (void) setHasDueDate: (BOOL) aBool
+- (void) takeValuesFromRequest: (WORequest *) _rq
+ inContext: (WOContext *) _ctx
{
- hasDueDate = aBool;
+ SOGoTaskObject *clientObject;
+
+ clientObject = [self clientObject];
+ todo = (iCalToDo *) [clientObject component: YES];
+
+ [super takeValuesFromRequest: _rq inContext: _ctx];
+
+ if (hasStartDate)
+ [todo setStartDate: taskStartDate];
+ if (hasDueDate)
+ [todo setDue: taskDueDate];
+ if ([status isEqualToString: @"COMPLETED"])
+ [todo setCompleted: statusDate];
+ else
+ [todo setCompleted: nil];
+ if ([status length] > 0)
+ {
+ [todo setStatus: status];
+ [todo setPercentComplete: statusPercent];
+ }
+ else
+ {
+ [todo setStatus: @""];
+ [todo setPercentComplete: @""];
+ }
}
-- (BOOL) hasDueDate
+// TODO: add tentatively
+
+- (id) acceptOrDeclineAction: (BOOL) _accept
{
- return (!newTask && [self taskDueDate] != nil);
+ [[self clientObject] changeParticipationStatus:
+ _accept ? @"ACCEPTED" : @"DECLINED"
+ inContext: [self context]];
+
+ return self;
}
-- (BOOL) dueDateDisabled
+- (id) acceptAction
{
- return (![self hasDueDate]);
+ return [self acceptOrDeclineAction:YES];
}
-- (void) setDueDateDisabled: (BOOL) aBool
+- (id) declineAction
{
+ return [self acceptOrDeclineAction:NO];
}
-- (void) setStartDateDisabled: (BOOL) aBool
+- (id) changeStatusAction
{
+ SOGoTaskObject *clientObject;
+ NSString *newStatus, *iCalString;
+
+ clientObject = [self clientObject];
+ todo = (iCalToDo *) [clientObject component: NO];
+ if (todo)
+ {
+ newStatus = [self queryParameterForKey: @"status"];
+ if ([newStatus intValue])
+ [todo setCompleted: [NSCalendarDate date]];
+ else
+ {
+ [todo setCompleted: nil];
+ [todo setPercentComplete: 0];
+ [todo setStatus: @"IN-PROCESS"];
+ }
+
+ iCalString = [[clientObject calendar: NO] versitString];
+ [clientObject saveContentString: iCalString];
+ }
+
+ return self;
}
-@end /* UIxTaskEditor */
+@end
if (!task)
{
clientObject = [self clientObject];
- task = (iCalToDo *) [clientObject component];
+ task = (iCalToDo *) [clientObject component: NO];
[task retain];
}
}
- (void)setDate:(NSCalendarDate *)_date {
+ NSLog (@"^^^^^^ %@: setDate: %@", self, _date);
int minuteValue;
if (!_date)
_date = [NSCalendarDate date];
}
- (void)setHour:(id)_hour {
+ NSLog (@"---------------- setHour:");
ASSIGN(hour, _hour);
}
+
- (id)hour {
return hour;
}
- (void) setDayStartHour: (unsigned int) aStartHour
{
+ NSLog (@"******************** setDayStartHour...");
startHour = aStartHour;
}
NSCalendarDate *d;
unsigned _year, _month, _day, _hour, _minute, _second;
+ NSLog (@"******************** %@: take values...", self);
/* call super, so that the form values are applied on the popups */
[super takeValuesFromRequest:_rq inContext:_ctx];
pageName = "UIxCalMainView";
actionName = "checkRights";
};
+ editAttendees = {
+ protectedBy = "View";
+ pageName = "UIxAttendeesEditor";
+ };
freeBusyTable = {
protectedBy = "View";
pageName = "UIxFreeBusyUserSelectorTable";
<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>
+ <li target="addressesInfos"><var:string label:value="Address" /></li>
+ <li target="otherInfos"><var:string label:value="Other" /></li>
</ul>
<div id="baseInfos" class="tab">
+ <span class="caption"><var:string label:value="Name" /></span>
<table>
- <tr>
- <td class="titleCell"><var:string label:value="Common" /></td>
- </tr>
<tr>
<td>
- <label><var:string label:value="Firstname: " const:escapeHTML="NO" />
+ <label><var:string label:value="First:" />
<input type="text" class="textField" name="givenName"
id="givenName"
var:value="snapshot.givenName" />
</tr>
<tr>
<td>
- <label><var:string label:value="Lastname: " const:escapeHTML="NO" />
+ <label><var:string label:value="Last:" />
<input type="text" class="textField" name="sn" id="sn"
var:value="snapshot.sn" />
</label>
</tr>
<tr>
<td>
- <label><var:string label:value="Display Name: " const:escapeHTML="NO" />
+ <label><var:string label:value="Display:" />
<input type="text" class="textField" name="fn" id="fn"
var:value="snapshot.fn" />
</label>
</tr>
<tr>
<td>
- <label><var:string label:value="Nickname: " const:escapeHTML="NO" />
+ <label><var:string label:value="Nickname:" />
<input type="text" class="textField" name="nickname" id="nickname"
var:value="snapshot.nickname" />
</label>
</td>
</tr>
</table>
-
- <br />
+ <span class="caption"><var:string label:value="Internet" /></span>
<table id="emailInfos">
- <tr>
- <td class="titleCell"><var:string label:value="EMail" /></td>
- <td class="preferred">
- <var:string label:value="Preferred" />
- </td>
- </tr>
<tr>
<td>
- <label><var:string label:value="Work: " const:escapeHTML="NO" />
+ <label><var:string label:value="Email:" />
<input type="text" class="textField" name="workMail" id="workMail"
var:value="snapshot.workMail" />
</label>
</td>
- <td class="preferred">
- <input type="radio" name="preferredEmail"
- var:selection="preferredEmail" const:value="work" />
- </td>
</tr>
<tr>
<td>
- <label><var:string label:value="Home: " const:escapeHTML="NO" />
+ <label><var:string label:value="Additional Email:" />
<input type="text" class="textField" name="homeMail"
id="homeMail" var:value="snapshot.homeMail" />
</label>
</td>
- <td class="preferred">
- <input type="radio"
- name="preferredEmail"
- var:selection="preferredEmail"
- const:value="home"
- />
+ </tr>
+ <tr>
+ <td id="htmlMailFormat">
+ <label><var:string
+ label:value="Prefers to receive messages formatted as:" />
+ <var:popup list="htmlMailFormatList" item="item"
+ label:noSelectionString="htmlMailFormat_UNKNOWN"
+ string="itemHtmlMailFormatText"
+ selection="snapshot.mozillaUseHtmlMail"
+ />
+ </label>
</td>
</tr>
- </table>
- <br />
- <table>
<tr>
- <td class="titleCell"><var:string label:value="Phones" /></td>
+ <td>
+ <label><var:string label:value="Screen Name:"
+ />
+ <input type="text" class="textField" name="screenName"
+ id="screenName" var:value="snapshot.screenName" />
+ </label>
+ </td>
</tr>
+ </table>
+ <span class="caption"><var:string label:value="Phones" /></span>
+ <table>
<tr>
<td>
- <label><var:string label:value="Work: " const:escapeHTML="NO" />
+ <label><var:string label:value="Work:" />
<input type="text" class="textField"
name="telephoneNumber"
id="telephoneNumber"
</tr>
<tr>
<td>
- <label><var:string label:value="Home: " const:escapeHTML="NO" />
+ <label><var:string label:value="Home:" />
<input type="text" class="textField"
name="homeTelephoneNumber"
id="homeTelephoneNumber"
</tr>
<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>
- </tr>
- <tr>
- <td>
- <label><var:string label:value="Fax: " const:escapeHTML="NO" />
+ <label><var:string label:value="Fax:" />
<input type="text" class="textField"
name="facsimileTelephoneNumber"
id="facsimileTelephoneNumber"
</tr>
<tr>
<td>
- <label><var:string label:value="Pager: " const:escapeHTML="NO" />
+ <label><var:string label:value="Pager:" />
<input type="text" class="textField"
name="pager"
id="pager"
</label>
</td>
</tr>
+ <tr>
+ <td>
+ <label><var:string label:value="Mobile:" />
+ <input type="text" class="textField" name="mobile" id="mobile"
+ var:value="snapshot.mobile" />
+ </label>
+ </td>
+ </tr>
</table>
</div>
<div id="addressesInfos" class="tab">
+ <span class="caption"><var:string label:value="Home" /></span>
<table>
<tr>
- <td class="titleCell" colspan="2">
- <span class="aptview_title">
- <var:string label:value="Work" />
- </span>
+ <td colspan="2">
+ <label><var:string label:value="Address:" />
+ <input type="text" class="textField" name="homeStreetAddress"
+ id="homeStreetAddress"
+ var:value="snapshot.homeStreetAddress" />
+ </label>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <label><var:string label:value="City:" />
+ <input type="text" class="textField" name="homeCity"
+ id="homeCity"
+ var:value="snapshot.homeCity" />
+ </label>
</td>
</tr>
<tr>
<td class="firstColumn">
+ <label><var:string label:value="State_Province:" />
+ <input type="text" class="textField" name="homeState"
+ id="homeState"
+ var:value="snapshot.homeState" />
+ </label>
+ </td>
+ <td class="secondColumn">
+ <label><var:string
+ label:value="ZIP_Postal Code:"
+ />
+ <input type="text" class="textField" name="homePostalCode"
+ id="homePostalCode"
+ var:value="snapshot.homePostalCode" />
+ </label>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <label><var:string label:value="Country:" />
+ <input type="text" class="textField" name="homeCountry"
+ id="homeCountry"
+ var:value="snapshot.homeCountry" />
+ </label>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
<label>
- <var:string label:value="Title: " const:escapeHTML="NO" />
+ <var:string label:value="Web Page:" />
+ <input type="text" class="textField" name="homeURL"
+ var:value="snapshot.homeURL" />
+ </label>
+ </td>
+ </tr>
+ </table>
+ <span class="caption"><var:string label:value="Work" /></span>
+ <table>
+ <tr>
+ <td colspan="2">
+ <label>
+ <var:string label:value="Title:" />
<input type="text" class="textField" name="title"
id="title"
var:value="snapshot.title" />
</label>
</td>
- <td class="secondColumn">
+ </tr>
+ <tr>
+ <td colspan="2">
<label>
- <var:string label:value="Service: " const:escapeHTML="NO" />
+ <var:string label:value="Department:" />
<input type="text" class="textField" name="workService"
id="workService"
var:value="snapshot.workService" />
</tr>
<tr>
<td colspan="2">
- <label><var:string label:value="Company: " const:escapeHTML="NO" />
+ <label><var:string label:value="Organization:" />
<input type="text" class="textField" name="workCompany"
id="workCompany"
var:value="snapshot.workCompany" />
</tr>
<tr>
<td colspan="2">
- <label><var:string label:value="Street Address: " const:escapeHTML="NO" />
+ <label><var:string label:value="Address:" />
<input type="text" class="textField" name="workStreetAddress"
id="workStreetAddress"
var:value="snapshot.workStreetAddress" />
</tr>
<tr>
<td colspan="2">
- <label><var:string label:value="City: " const:escapeHTML="NO" />
+ <label><var:string label:value="City:" />
<input type="text" class="textField" name="workCity"
id="workCity"
var:value="snapshot.workCity" />
</tr>
<tr>
<td class="firstColumn">
- <label><var:string label:value="State/Province: " const:escapeHTML="NO" />
+ <label><var:string label:value="State_Province:" />
<input type="text" class="textField" name="workState"
id="workState"
var:value="snapshot.workState" />
</td>
<td class="secondColumn">
<label><var:string
- label:value="Zip or Postal Code: "
- const:escapeHTML="NO" />
+ label:value="ZIP_Postal Code:"
+ />
<input type="text" class="textField" name="workPostalCode"
id="workPostalCode"
var:value="snapshot.workPostalCode" />
</tr>
<tr>
<td colspan="2">
- <label><var:string label:value="Country: " const:escapeHTML="NO" />
+ <label><var:string label:value="Country:" />
<input type="text" class="textField" name="workCountry"
id="workCountry"
var:value="snapshot.workCountry" />
</tr>
<tr>
<td colspan="2">
- <label><var:string label:value="Web: " const:escapeHTML="NO" />
+ <label><var:string label:value="Web Page:" />
<input type="text" class="textField" name="workURL"
var:value="snapshot.workURL" />
</label>
</td>
</tr>
</table>
-
- <table>
- <tr>
- <td class="titleCell" colspan="2">
- <span class="aptview_title">
- <var:string label:value="Home" />
- </span>
- </td>
- </tr>
- <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>
- </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>
- <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 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>
- <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>
- </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>
- </table>
</div>
<div id="otherInfos" class="tab">
<table>
<tr>
<td class="firstColumn">
- <label><var:string label:value="Birthday: " const:escapeHTML="NO" />
+ <label><var:string label:value="Birthday:" />
<input type="text" class="textField" name="birthday" id="birthday"
var:value="snapshot.bday" />
</label>
</td>
<td class="secondColumn">
- <label><var:string label:value="Timezone: " const:escapeHTML="NO" />
+ <label><var:string label:value="Timezone:" />
<input type="text" class="textField" name="tz" id="tz"
var:value="snapshot.tz" />
</label>
</tr>
<tr>
<td colspan="2">
- <label><var:string label:value="Freebusy URL: " const:escapeHTML="NO" />
+ <label><var:string label:value="Freebusy URL:" />
<input type="text" class="textField" name="calFBURL" id="calFBURL"
var:value="snapshot.calFBURL" />
</label>
</tr>
<tr>
<td colspan="2">
- <label><var:string label:value="Note: " const:escapeHTML="NO" />
+ <label><var:string label:value="Note:" />
<textarea var:value="snapshot.note" name="note" id="note"></textarea>
</label>
</td>
><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="primaryEmail" escapeHTML="NO"
+ /><var:string value="secondaryEmail" escapeHTML="NO"
+ /><var:string value="screenName" escapeHTML="NO"
/><var:string value="preferredTel" escapeHTML="NO"
/><var:string value="preferredAddress" 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: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>
+<!DOCTYPE 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: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>
+ <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" id="abToolbar">
- <a href="#" class="toolbarButton"
- ><span class="toolbarButton"
- ><img rsrc:src="add-addressbook.png" label:title="New Addressbook..."
- /></span></a
- ><a href="#" class="toolbarButton"
- ><span class="toolbarButton"
- ><img rsrc:src="add-user-addressbook.png" label:title="Subscribe to an Addressbook..."
- /></span></a
- ><a href="#" class="toolbarButton"
- ><span class="toolbarButton"
- ><img rsrc:src="remove-addressbook.png" label:title="Remove the selected Addressbook"
- /></span></a
- ></div><!-- var:if -->
+ <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" id="abToolbar">
+ <a href="#" class="toolbarButton"
+ ><span class="toolbarButton"
+ ><img rsrc:src="add-addressbook.png" label:title="New Addressbook..."
+ /></span></a
+ ><a href="#" class="toolbarButton"
+ ><span class="toolbarButton"
+ ><img rsrc:src="add-user-addressbook.png" label:title="Subscribe to an Addressbook..."
+ /></span></a
+ ><a href="#" class="toolbarButton"
+ ><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>
+ <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>
+ <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 class="dragHandle" id="dragHandle"><!-- space --></div>
+ <!-- var:if -->
- <div id="rightPanel">
- <var:component className="UIxContactsFilterPanel" qualifier="qualifier" />
+ <div id="rightPanel">
+ <var:component className="UIxContactsFilterPanel" qualifier="qualifier" />
- <div id="contactsListContent">
- <var:component-content />
- </div>
+ <div id="contactsListContent">
+ <var:component-content />
+ </div>
- <div class="dragHandle" id="rightDragHandle"><!-- space --></div>
+ <div class="dragHandle" id="rightDragHandle"><!-- space --></div>
- <div id="contactView" onmousedown="return false;"
- ></div>
- </div>
- <!-- /var:if> -->
+ <div id="contactView" onmousedown="return false;"
+ ></div>
+ </div>
+ <!-- /var:if> -->
- <!-- var:if condition="isPopup">
- var:component-content />
- /var:if> -->
- </form>
+ <!-- var:if condition="isPopup">
+ var:component-content />
+ /var:if> -->
+ </form>
- <var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
- </var:if>
+ <var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
+ </var:if>
- <var:if condition="hideFrame">
- <var:component-content />
- </var:if>
+ <var:if condition="hideFrame">
+ <var:component-content />
+ </var:if>
- <script type="text/javascript">
- currentContactFolder = '<var:string value="contactFolderId" />';
- </script>
- </var:component>
+ <script type="text/javascript">
+ currentContactFolder = '<var:string value="contactFolderId" />';
+ </script>
+</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: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>
+<!DOCTYPE container>
+<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="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>
+<!DOCTYPE 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="UIxComponentEditor"
+ var:component="event"
+ var:toolbar="toolbar"
+ var:saveURL="saveURL">
+ <label><span id="allDay" class="content"><input class="checkBox"
+ type="checkbox" var:selection="isAllDay"
+ var:checked="isAllDay"
+ /><var:string label:value="All day Event"
+ /></span></label>
+ <span class="checkBoxList"><var:string label:value="Start:" />
+ <span class="content"><var:component className="UIxTimeDateControl"
+ const:controlID="startTime"
+ date="aptStartDate"
+ const:dayStartHour="0"
+ const:dayEndHour="23"
+ /></span></span>
+ <span class="checkBoxList"><var:string label:value="End:" />
+ <span class="content"><var:component className="UIxTimeDateControl"
+ const:controlID="endTime"
+ date="aptEndDate"
+ const:dayStartHour="0"
+ const:dayEndHour="23"
+ /></span></span>
+ <hr />
+ <label><var:string label:value="Repeat:" />
+ <span class="content"><var:popup list="repeatList" item="item"
+ label:noSelectionString="repeat_NEVER"
+ const:disabledValue="-"
+ string="itemRepeatText" selection="repeat"
+ /></span></label>
+ <hr />
+ <label><var:string label:value="Reminder:" />
+ <span class="content"><var:popup list="reminderList" item="item"
+ const:disabledValue="-"
+ label:noSelectionString="reminder_NONE"
+ string="itemReminderText" selection="reminder"
+ /></span></label>
+</var:component>
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE div>
+<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 class="shadow shadow1"><!-- space --></div
+ ><div class="shadow shadow2"><!-- space --></div
+ ><div class="shadow shadow3"><!-- space --></div
+ ><div class="shadow shadow4"><!-- space --></div
+ ><div var:class="innerDisplayClasses"
+ ><div class="gradient"
+ ><img rsrc:src="event-gradient.png" class="gradient"
+ /></div
+ ><div class="text"
+ ><span class="eventHeader"><var:string value="startHour"
+ const:escapeHTML="NO" />
+ <var:string value="appointment.title" const:escapeHTML="NO"
+ /></span></div>
+ </div>
+</div>
className="UIxPageFrame"
title="title"
>
+ <div class="preload" style="visibility: hidden;">
+ <img rsrc:src="event-gradient.png"/>
+ </div>
<div class="menu" id="monthListMenu">
<ul>
<var:foreach list="monthMenuItems" item="monthMenuItem"
<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE var:component>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
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>
<?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>
<?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>
+<!DOCTYPE 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="UIxComponentEditor"
+ var:component="todo"
+ var:toolbar="toolbar"
+ var:saveURL="saveURL">
+ <span class="checkBoxList"><var:string label:value="Start:" />
+ <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 Date:" />
+ <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>
+ <span class="checkBoxList"><var:string label:value="Status:" />
+ <span class="content"><var:popup list="statusList" item="item"
+ const:id="statusList"
+ label:noSelectionString="status_NOT-SPECIFIED"
+ string="itemStatusText" selection="status"
+ /><var:component className="UIxTimeDateControl"
+ const:displayTimeControl="0"
+ var:disabled="statusDateDisabled"
+ const:controlID="statusTime"
+ date="statusDate"
+ const:dayStartHour="0"
+ const:dayEndHour="23"
+ /><input type="text" name="statusPercent"
+ id="statusPercent"
+ class="textField"
+ var:value="statusPercent"
+ var:disabled="statusPercentDisabled"
+ /><var:string label:value="% complete"
+ /></span></span>
+ <hr />
+ <label><var:string label:value="Repeat:" />
+ <span class="content"><var:popup list="repeatList" item="item"
+ label:noSelectionString="repeat_NEVER"
+ const:disabledValue="-"
+ string="itemRepeatText" selection="repeat"
+ /></span></label>
+</var:component>
/>
<var:if condition="displayTimeControl">
<var:if condition="disabled">
- <select var:shadow-value="hour" var:name="hourSelectId" const:disabled="disabled">
+ <select var:shadow-value="hour"
+ var:id="hourSelectId" var:name="hourSelectId" const:disabled="disabled">
<var:foreach list="selectableHours" item="hourOption"
><var:if condition="isCurrentHour"
><option var:value="hourValue" selected="selected"
/></option></var:if>
</var:foreach
></select>
- <select var:shadow-value="minute" var:name="minuteSelectId" const:disabled="disabled">
+ <select var:shadow-value="minute"
+ var:id="minuteSelectId" var:name="minuteSelectId" const:disabled="disabled">
<var:foreach list="selectableMinutes" item="minuteOption"
><var:if condition="isCurrentMinute"
><option var:value="minuteValue" selected="selected"
</var:if
><var:if condition="disabled" const:negate="YES">
- <select var:shadow-value="hour" var:name="hourSelectId">
+ <select var:shadow-value="hour" var:id="hourSelectId" var:name="hourSelectId">
<var:foreach list="selectableHours" item="hourOption"
><var:if condition="isCurrentHour"
><option var:value="hourValue" selected="selected"
/></option></var:if>
</var:foreach
></select>
- <select var:shadow-value="minute" var:name="minuteSelectId">
+ <select var:shadow-value="minute" var:id="minuteSelectId" var:name="minuteSelectId">
<var:foreach list="selectableMinutes" item="minuteOption"
><var:if condition="isCurrentMinute"
><option var:value="minuteValue" selected="selected"
><div id="logConsole"><!-- space --></div></var:if>
<div id="linkBanner" class="linkbanner">
- <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="Address Book" /></a> |
<a var:href="relativeMailPath"
- ><var:string label:value="Mail" /></a> |
- <a var:href="logoffPath"
- ><var:string label:value="Logoff" /></a>
+ ><var:string label:value="Mail" /></a>
+<!-- | <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
><img class="buttonImage"
var:src="buttonImage"
var:alt="buttonInfo.image"
- /><br
+ /><var:if condition="hasMenu"
+ ><img class="buttonMenuArrow"
+ rsrc:src="arrow-dwn-sharp.gif"
+ var:alt="buttonInfo.image"
+ /></var:if
+ ><br
/><span class="buttonLabel"
><var:string
value="buttonLabel"
/></span
- ></span
- ></a>
- </var:if>
- <var:if condition="isButtonEnabled"
+ ></span
+ ></a
+ ></var:if
+ ><var:if condition="isButtonEnabled"
const:negate="YES"
><span class="disabledToolbarButton"
><img class="buttonImage"
><var:string
value="buttonLabel"
/></span
- ></span>
- </var:if>
- </var:foreach>
+ ></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>
+ /></span
+ ></var:if>
+ </var:foreach>
<img id="progressIndicator" rsrc:src="busy.gif" />
</div>
</var:if>
line-height: 1em;
}
+DIV#contactView A
+{ color: #00f;
+ text-decoration: none; }
+
DIV#contactView H3.contactCardTitle
{ display: block;
margin: .2em 0px;
var contactSelectorAction = 'addressbooks-contacts';
function openContactWindow(sender, url) {
- var msgWin = window.open(url, null, "width=545,height=545,resizable=0");
+ var msgWin = window.open(url, null, "width=450,height=600,resizable=0");
msgWin.focus();
}
return true;
}
-function onContactsFolderTreeItemClick(element)
-{
+function onContactsFolderTreeItemClick(element) {
var topNode = $('d');
var contactsFolder = element.parentNode.getAttribute("dataname");
: ApplicationBaseURL + currentContactFolder);
}
-function openContactsFolder(contactsFolder, params, external)
-{
+function openContactsFolder(contactsFolder, params, external) {
if (contactsFolder != currentContactFolder || params) {
if (contactsFolder == currentContactFolder) {
var contactsList = $("contactsList");
= triggerAjaxRequest(url, contactsListCallback);
}
-function contactsListCallback(http)
-{
+function contactsListCallback(http) {
var div = $("contactsListContent");
if (http.readyState == 4
log ("ajax fuckage 1");
}
-function onContactFoldersContextMenu(event)
-{
+function onContactFoldersContextMenu(event) {
var menu = $("contactFoldersMenu");
menu.addEventListener("hideMenu", onContactFoldersContextMenuHide, false);
onMenuClick(event, "contactFoldersMenu");
this.select();
}
-function onContactContextMenu(event, element)
-{
+function onContactContextMenu(event, element) {
var menu = $("contactMenu");
menu.addEventListener("hideMenu", onContactContextMenuHide, false);
onMenuClick(event, "contactMenu");
element.select();
}
-function onContactContextMenuHide(event)
-{
+function onContactContextMenuHide(event) {
var topNode = $("contactsList");
if (topNode.menuSelectedEntry) {
}
}
-function onContactFoldersContextMenuHide(event)
-{
+function onContactFoldersContextMenuHide(event) {
var topNode = $("contactFolders");
if (topNode.menuSelectedEntry) {
}
}
-function onFolderMenuHide(event)
-{
+function onFolderMenuHide(event) {
var topNode = $('d');
if (topNode.menuSelectedEntry) {
topNode.selectedEntry.select();
}
-function loadContact(idx)
-{
+function loadContact(idx) {
if (document.contactAjaxRequest) {
document.contactAjaxRequest.aborted = true;
document.contactAjaxRequest.abort();
}
}
-function contactLoadCallback(http)
-{
+function contactLoadCallback(http) {
var div = $('contactView');
if (http.readyState == 4
}
/* contact menu entries */
-function onContactRowClick(event, node)
-{
+function onContactRowClick(event, node) {
loadContact(node.getAttribute('id'));
return onRowClick(event);
}
-function onContactRowDblClick(event, node)
-{
+function onContactRowDblClick(event, node) {
var contactId = node.getAttribute('id');
openContactWindow(null,
return false;
}
-function onMenuEditContact(event, node)
-{
+function onMenuEditContact(event, node) {
var node = getParentMenu(node).menuTarget.parentNode;
var contactId = node.getAttribute('id');
return false;
}
-function onMenuWriteToContact(event, node)
-{
+function onMenuWriteToContact(event, node) {
var node = getParentMenu(node).menuTarget.parentNode;
var contactId = node.getAttribute('id');
return false;
}
-function onMenuDeleteContact(event, node)
-{
+function onMenuDeleteContact(event, node) {
uixDeleteSelectedContacts(node);
return false;
}
-function onToolbarEditSelectedContacts(event)
-{
+function onToolbarEditSelectedContacts(event) {
var contactsList = $('contactsList');
var rows = contactsList.getSelectedRowsId();
return false;
}
-function onToolbarWriteToSelectedContacts(event)
-{
+function onToolbarWriteToSelectedContacts(event) {
var contactsList = $('contactsList');
var rows = contactsList.getSelectedRowsId();
return false;
}
-function uixDeleteSelectedContacts(sender)
-{
+function uixDeleteSelectedContacts(sender) {
var failCount = 0;
var contactsList = $('contactsList');
var rows = contactsList.getSelectedRowsId();
return false; /* stop following the link */
}
-function onHeaderClick(event)
-{
+function onHeaderClick(event) {
if (document.contactsListAjaxRequest) {
document.contactsListAjaxRequest.aborted = true;
document.contactsListAjaxRequest.abort();
event.preventDefault();
}
-function registerDraggableMessageNodes()
-{
+function registerDraggableMessageNodes() {
log ("can we drag...");
}
return false; /* stop following the link */
}
-function onFolderSelectionChange()
-{
+function onFolderSelectionChange() {
var folderList = $("contactFolders");
var nodes = folderList.getSelectedNodes();
$("contactView").innerHTML = '';
}
}
-function onSearchFormSubmit()
-{
+function onSearchFormSubmit() {
var searchValue = $("searchValue");
openContactsFolder(currentContactFolder, "search=" + searchValue.value);
return false;
}
-function onConfirmContactSelection(tag)
-{
+function onConfirmContactSelection(tag) {
var folderLi = $(currentContactFolder);
var currentContactFolderName = folderLi.innerHTML;
var selectorList = null;
var newValues = initialValues.replace(re, "");
if (initialValues != newValues)
setAdditionalAddressBooks(newValues);
-
- var personal = $("/personal");
- personal.select();
- onFolderSelectionChange();
}
+ else {
+ nodes[0].deselect();
+ var folderId = nodes[0].getAttribute("id").substr(1);
+ deletePersonalAddressBook(folderId);
+ }
+
+ var personal = $("/personal");
+ personal.select();
+ onFolderSelectionChange();
}
event.preventDefault();
}
+function deletePersonalAddressBook(folderId) {
+ var label
+ = labels["Are you sure you want to delete the selected address book?"];
+ if (window.confirm(label.decodeEntities())) {
+ if (document.deletePersonalABAjaxRequest) {
+ document.deletePersonalABAjaxRequest.aborted = true;
+ document.deletePersonalABAjaxRequest.abort();
+ }
+ var url = ApplicationBaseURL + "/" + folderId + "/delete";
+ document.deletePersonalABAjaxRequest
+ = triggerAjaxRequest(url, deletePersonalAddressBookCallback,
+ folderId);
+ }
+}
+
+function deletePersonalAddressBookCallback(http) {
+ if (http.readyState == 4) {
+ if (http.status == 200) {
+ var ul = $("contactFolders");
+
+ var children = ul.childNodesWithTag("li");
+ var i = 0;
+ var done = false;
+ while (!done && i < children.length) {
+ var currentFolderId = children[i].getAttribute("id").substr(1);
+ if (currentFolderId == http.callbackData) {
+ ul.removeChild(children[i]);
+ done = true;
+ }
+ else
+ i++;
+ }
+ }
+ document.deletePersonalABAjaxRequest = null;
+ }
+ else
+ log ("ajax fuckage");
+}
+
function configureDragHandles() {
var handle = $("dragHandle");
if (handle) {
var initContacts = {
handleEvent: function (event) {
- configureAbToolbar();
+ if (!document.body.hasClassName("popup")) {
+ configureAbToolbar();
+ }
configureContactFolders();
// initDnd();
}
/* mail list reply */
-function openMessageWindowsForSelection(action)
-{
+function openMessageWindowsForSelection(action) {
if (document.body.hasClassName("popup"))
win = openMessageWindow(window.messageId,
window.messageURL + "/" + action /* url */);
var oldMaillistHighlight = null; // to remember deleted/selected style
-function ml_highlight(sender)
-{
+function ml_highlight(sender) {
oldMaillistHighlight = sender.className;
if (oldMaillistHighlight == "tableview_highlight")
oldMaillistHighlight = null;
sender.className = "tableview_highlight";
}
-function ml_lowlight(sender)
-{
+function ml_lowlight(sender) {
if (oldMaillistHighlight) {
sender.className = oldMaillistHighlight;
oldMaillistHighlight = null;
return false;
}
-function openMailbox(mailbox, reload)
-{
+function openMailbox(mailbox, reload) {
if (mailbox != currentMailbox || reload) {
currentMailbox = mailbox;
var url = ApplicationBaseURL + mailbox + "/view?noframe=1&desc=1";
return false;
}
-function messageListCallback(http)
-{
+function messageListCallback(http) {
var div = $('mailboxContent');
if (http.readyState == 4
log ("ajax fuckage");
}
-function onMessageContextMenu(event)
-{
+function onMessageContextMenu(event) {
var menu = $('messageListMenu');
menu.addEventListener("hideMenu", onMessageContextMenuHide, false);
onMenuClick(event, 'messageListMenu');
this.select();
}
-function onMessageContextMenuHide(event)
-{
+function onMessageContextMenuHide(event) {
var topNode = $('messageList');
if (topNode.menuSelectedEntry) {
}
}
-function onFolderMenuClick(event)
-{
+function onFolderMenuClick(event) {
var onhide, menuName;
var menutype = this.parentNode.getAttribute("datatype");
this.select();
}
-function onFolderMenuHide(event)
-{
+function onFolderMenuHide(event) {
var topNode = $('d');
if (topNode.menuSelectedEntry) {
counter++;
}
-function getCachedMessage(idx)
-{
+function getCachedMessage(idx) {
var message = null;
var counter = 0;
return message;
}
-function storeCachedMessage(cachedMessage)
-{
+function storeCachedMessage(cachedMessage) {
var oldest = -1;
var timeOldest = -1;
var counter = 0;
cachedMessages[oldest] = cachedMessage;
}
-function onMessageSelectionChange()
-{
+function onMessageSelectionChange() {
var rows = this.getSelectedRowsId();
if (rows.length == 1) {
var idx = rows[0].substr(4);
}
}
-function loadMessage(idx)
-{
+function loadMessage(idx) {
var cachedMessage = getCachedMessage(idx);
if (document.messageAjaxRequest) {
}
}
-function messageCallback(http)
-{
+function messageCallback(http) {
var div = $('messageContent');
if (http.readyState == 4
log ("ajax fuckage");
}
-function processMailboxMenuAction(mailbox)
-{
+function processMailboxMenuAction(mailbox) {
var currentNode, upperNode;
var mailboxName;
var action;
alert("MoveTo: " + uri);
}
-function deleteSelectedMails()
-{
+function deleteSelectedMails() {
}
/* message menu entries */
-function onMenuOpenMessage(event)
-{
+function onMenuOpenMessage(event) {
var node = getParentMenu(event.target).menuTarget.parentNode;
var msgId = node.getAttribute('id').substr(4);
return openMailTo(sender.parentNode.parentNode.menuTarget.innerHTML);
}
-function expandUpperTree(node)
-{
+function expandUpperTree(node) {
var currentNode = node.parentNode;
while (currentNode.className != "dtree")
}
}
-function initMailboxSelection(mailboxName)
-{
+function initMailboxSelection(mailboxName) {
currentMailbox = mailboxName;
log("initMailboxSelection: " + mailboxName);
var tree = $("d");
}
}
-function onHeaderClick(event)
-{
+function onHeaderClick(event) {
if (document.messageListAjaxRequest) {
document.messageListAjaxRequest.aborted = true;
document.messageListAjaxRequest.abort();
event.preventDefault();
}
-function onSearchFormSubmit()
-{
+function onSearchFormSubmit() {
log ("search not implemented");
return false;
padding: 0px;
margin: 0px; }
+SPAN.colorBox
+{ display: block;
+ float: right;
+ border: 1px solid #333;
+ margin: .12em;
+ width: 1em;
+ height: .75em; }
+
UL#tasksList, UL#uixselector-calendarsList-display
{ cursor: default;
margin: .25px;
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: absolute;
left: .5em;
top: .5em;
- right: .5em;
- bottom: .5em;
+ right: 1em;
+ bottom: 1em;
+ border: 0px;
+ margin: 0px;
padding: 0px;
- width: 98%;
- height: 98%;
- min-width: 60em;
+ min-width: 20em;
min-height: 25em; }
DIV.monthView > DIV,
DIV.monthView > DIV.days > DIV
-{ position: absolute; }
+{ position: absolute;
+ padding: 0px;
+ margin: 0px; }
DIV.monthView > DIV.headerDay
{ text-align: center;
- border-left: 2px solid #397d94;
- border-top: 2px solid #397d94;
+ padding-top: .5em;
+ border-left: 2px solid #397d94 !important;
+ border-top: 2px solid #397d94 !important;
top: 0px;
color: #397d94;
- height: 2em;
+ height: 1.5em;
font-weight: bold;
background: #e7efef; }
DIV.monthView DIV.dayOfToday
-{ border: 1px solid #397d94;
+{ border: 0px solid #397d94;
background-color: #deebf7; }
DIV.monthView DIV.weekEndDay
font-weight: bold; }
DIV.monthView DIV.days
-{ position: absolute;
- top: 2em;
+{ top: 2em;
bottom: 0px;
left: 0px;
right: 0px; }
{ top: 50%; }
DIV.monthView DIV.week3of4
-{ top: 75%; }
+{ top: 75%;
+ border-bottom: 2px solid #397d94 !important; }
DIV.monthView DIV.week1of5
{ top: 20%; }
{ top: 60%; }
DIV.monthView DIV.week4of5
-{ top: 80%; }
+{ top: 80%;
+ border-bottom: 2px solid #397d94 !important; }
DIV.monthView DIV.week1of6
{ top: 16.666667%; }
DIV.monthView DIV.week4of6
{ top: 66.666667%; }
-DIV.monthView DIV.week4of6
-{ top: 83.333333%; }
+DIV.monthView DIV.week5of6
+{ top: 83.333333%;
+ border-bottom: 2px solid #397d94 !important; }
DIV.monthView DIV.week3
{ top: 45%; }
DIV.daysViewFor7Days DIV.day6
{ left: 71.4285%; }
-DIV.monthView DIV.day0,
+DIV.monthView DIV.day0
+{ left: 85.7142%;
+ border-right: 2px solid #397d94; }
+
DIV.daysViewFor7Days DIV.day0
{ left: 85.7142%;
border-right: 1px solid #397d94; }
DIV.appointment > DIV.appointmentInside
{ position: absolute;
overflow: hidden;
- top: 2px;
- bottom: 2px;
+ top: 1px;
+ bottom: 5px;
left: 2px;
right: 2px; }
{ left: 0px;
right: 0px;
top: 2px;
- bottom: 0px;
+ bottom: 3px;
-moz-opacity: 0.1; }
DIV.shadow2
{ left: 1px;
right: 1px;
- top: 3px;
- bottom: -2px;
- -moz-opacity: 0.1;
- -moz-border-radius: 3px; }
+ top: 1px;
+ bottom: 2px;
+ -moz-opacity: 0.1; }
DIV.shadow3
{ left: 2px;
right: 2px;
- top: 4px;
- bottom: 0px;
- -moz-opacity: 0.4; }
+ top: 0px;
+ bottom: 3px;
+ -moz-opacity: 0.1; }
DIV.shadow4
{ left: 3px;
right: 3px;
- top: 5px;
- bottom: 1px;
+ top: 3px;
+ bottom: 4px;
-moz-opacity: 0.4; }
DIV.gradient, DIV.text
width: 100%; }
DIV.monthView DIV.appointment
-{ position: relative !important;
+{ position: relative;
+ cursor: default;
white-space: nowrap;
+ margin: 2px;
padding: 1px;
height: 1.5em; }
+DIV.monthView DIV.appointment DIV.text
+{ font-size: 80%; }
+
DIV.daysView DIV[class~="appointment"].starts0
{ top: 0.000000%; }
if (params.length > 0)
urlstr += "?" + params.join("&");
- window.open(urlstr, "", "width=620,height=600,resizable=0");
+ window.open(urlstr, "", "width=490,height=600,resizable=0");
return false; /* stop following the link */
}
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");
+ "width=490,height=600,resizable=0");
win.focus();
}
events);
}
-function deleteEvent()
-{
+function deleteEvent() {
if (listOfSelection) {
var nodes = listOfSelection.getSelectedRows();
}
}
-function deleteEventCallback(http)
-{
+function deleteEventCallback(http) {
if (http.readyState == 4
&& http.status == 200) {
var nodes = http.callbackData;
log ("ajax fuckage");
}
-function editDoubleClickedEvent(node)
-{
+function editDoubleClickedEvent(node) {
_editEventId(node.getAttribute("id"),
node.getAttribute("owner"));
event.returnValue = false;
}
-function onDaySelect(node)
-{
+function onDaySelect(node) {
var day = node.getAttribute("day");
var needRefresh = (listFilter == 'view_selectedday'
&& day != currentDay);
return false;
}
-function onDateSelectorGotoMonth(node)
-{
+function onDateSelectorGotoMonth(node) {
var day = node.getAttribute("date");
changeDateSelectorDisplay(day, true);
return false;
}
-function onCalendarGotoDay(node)
-{
+function onCalendarGotoDay(node) {
var day = node.getAttribute("date");
changeDateSelectorDisplay(day);
return false;
}
-function gotoToday()
-{
+function gotoToday() {
changeDateSelectorDisplay('');
changeCalendarDisplay();
return false;
}
-function setDateSelectorContent(content)
-{
+function setDateSelectorContent(content) {
var div = $("dateSelectorView");
div.innerHTML = content;
restoreCurrentDaySelection(div);
}
-function dateSelectorCallback(http)
-{
+function dateSelectorCallback(http) {
if (http.readyState == 4
&& http.status == 200) {
document.dateSelectorAjaxRequest = null;
log ("ajax fuckage");
}
-function appointmentsListCallback(http)
-{
+function appointmentsListCallback(http) {
var div = $("appointmentsListView");
if (http.readyState == 4
log ("ajax fuckage");
}
-function tasksListCallback(http)
-{
+function tasksListCallback(http) {
var div = $("tasksListView");
if (http.readyState == 4
log ("ajax fuckage");
}
-function restoreCurrentDaySelection(div)
-{
+function restoreCurrentDaySelection(div) {
var elements = div.getElementsByTagName("a");
var day = null;
var i = 9;
}
}
-function changeDateSelectorDisplay(day, keepCurrentDay)
-{
+function changeDateSelectorDisplay(day, keepCurrentDay) {
var url = ApplicationBaseURL + "dateselector";
if (day)
url += "?day=" + day;
}
}
-function changeCalendarDisplay(time, newView)
-{
+function changeCalendarDisplay(time, newView) {
var url = ApplicationBaseURL + ((newView) ? newView : currentView);
selectedCalendarCell = null;
return false;
}
-function onDayOverview()
-{
+function onDayOverview() {
return _ensureView("dayview");
}
-function onMulticolumnDayOverview()
-{
+function onMulticolumnDayOverview() {
return _ensureView("multicolumndayview");
}
-function onWeekOverview()
-{
+function onWeekOverview() {
return _ensureView("weekview");
}
-function onMonthOverview()
-{
+function onMonthOverview() {
return _ensureView("monthview");
}
-function scrollDayView(hour)
-{
+function scrollDayView(hour) {
var rowNumber;
if (hour) {
if (hour.length == 3)
event.returnValue = false;
}
-function calendarDisplayCallback(http)
-{
+function calendarDisplayCallback(http) {
var div = $("calendarView");
// log ("calendardisplaycallback: " + div);
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 assignCalendar(name) {
+ if (typeof(skycalendar) != "undefined") {
+ 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();
+function popupCalendar(node) {
+ var nodeId = node.getAttribute("inputId");
+ var input = $(nodeId);
+ input.calendar.popup();
- return false;
+ return false;
}
-function onAppointmentContextMenu(event, element)
-{
+function onAppointmentContextMenu(event, element) {
var topNode = $("appointmentsList");
// log(topNode);
element.select();
}
-function onAppointmentContextMenuHide(event)
-{
+function onAppointmentContextMenuHide(event) {
var topNode = $("appointmentsList");
if (topNode.menuSelectedEntry) {
return _loadTasksHref("taskslist?hide-completed=" + hideCompletedTasks);
}
-function refreshAppointmentsAndDisplay()
-{
+function refreshAppointmentsAndDisplay() {
refreshAppointments();
changeCalendarDisplay();
}
return refreshAppointments();
}
-function onAppointmentClick(event)
-{
+function onAppointmentClick(event) {
var node = event.target.getParentWithTagName("tr");
var day = node.getAttribute("day");
var hour = node.getAttribute("hour");
return onRowClick(event);
}
-function selectMonthInMenu(menu, month)
-{
+function selectMonthInMenu(menu, month) {
var entries = menu.childNodes[1].childNodesWithTag("LI");
for (i = 0; i < entries.length; i++) {
var entry = entries[i];
}
}
-function selectYearInMenu(menu, month)
-{
+function selectYearInMenu(menu, month) {
var entries = menu.childNodes[1].childNodes;
for (i = 0; i < entries.length; i++) {
var entry = entries[i];
}
}
-function popupMonthMenu(event, menuId)
-{
+function popupMonthMenu(event, menuId) {
var node = event.target;
if (event.button == 0) {
}
}
-function onMonthMenuItemClick(node)
-{
+function onMonthMenuItemClick(node) {
var month = '' + node.getAttribute("month");
var year = '' + $("yearLabel").innerHTML;
}
}
-function changeMonthCalendarDisplayOfSelectedDay(node)
-{
+function changeMonthCalendarDisplayOfSelectedDay(node) {
var daysContainer = node.parentNode;
if (!daysContainer.selectedCell)
findMonthCalendarSelectedCell(daysContainer);
node.addClassName("selectedDay");
}
-function onHideCompletedTasks(node)
-{
+function onHideCompletedTasks(node) {
hideCompletedTasks = (node.checked ? 1 : 0);
return refreshTasks();
}
-function updateTaskStatus(node)
-{
+function updateTaskStatus(node) {
var taskId = node.parentNode.getAttribute("id");
var taskOwner = node.parentNode.getAttribute("owner");
var newStatus = (node.checked ? 1 : 0);
return false;
}
-function updateCalendarStatus()
-{
+function updateCalendarStatus() {
var list = new Array();
var clist = $("calendarsList");
return false;
}
-function calendarUidsList()
-{
+function calendarUidsList() {
var list = "";
var nodes = $("uixselector-calendarsList-display").childNodesWithTag("li");
// }
// }
-function inhibitMyCalendarEntry()
-{
+function inhibitMyCalendarEntry() {
var clist = $("calendarsList");
var nodes = clist.childNodes[5].childNodes;
var done = false;
}
}
-function updateCalendarsList(method)
-{
+function updateCalendarsList(method) {
ensureSelfIfPresent();
var url = (ApplicationBaseURL + "updateCalendars?ids="
+ calendarUidsList());
}
}
-function addContact(tag, fullContactName, contactId, contactName, contactEmail)
-{
+function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
var uids = $("uixselector-calendarsList-uidList");
// log("addContact");
if (contactId)
text-align: right;
width: 3em; }
-DIV#editorTabs
-{
- position: absolute;
- top: 4.5em;
- left: 0px;
- right: 0px;
- bottom: 0px;
-}
-
-DIV#editorTabs > DIV.tab
+DIV#eventView
{ overflow: hidden;
padding: .5em; }
{ display: inline;
vertical-align: middle; }
+#privacy-menu LI
+{ list-style-position: inside;
+ list-style-image: url("menu-nocheck.gif"); }
+
+#privacy-menu LI._chosen
+{ list-style-image: url("menu-check.gif"); }
+
+#privacy-menu LI._chosen:hover
+{ list-style-image: url("menu-check-hover.gif"); }
+
UL.contactList
-{
- display: block;
+{ display: block;
cursor: default;
list-style-type: none;
list-style-image: none;
border: 1px solid #000;
width: 15em;
height: 5em;
- overflow: auto;
-}
+ overflow: auto; }
UL.contactList LI IMG
{ vertical-align: middle; }
width: 100%; }
LABEL#commentArea
-{ height: 11.5em; }
+{ height: 15em; }
SPAN.checkBoxList#participantsCB
{ height: 7em; }
vertical-align: bottom;
bottom: 1em;
right: 1em;
- padding-bottom: 1em; }
+ padding-bottom: 0em; }
+
+A#changeUrlButton
+{ margin-left: 1em; }
A#detailsButton
{ position: absolute;
{ border: 2px solid #000;
vertical-align: middle;
-moz-border-top-colors: #000 #fff;
- -moz-border-left-colors: #000 #fff;
+ -moz-border-left-colors: #000 #fff;
-moz-border-bottom-colors: #000 #fff;
-moz-border-right-colors: #000 #fff; }
{ margin-left: 0px;
margin-right: 1em; }
+SPAN#allDay > INPUT
+{ position: static; }
+
SPAN.content > INPUT
{ position: absolute;
top: 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; }
+A#attendeesHref
+{ color: #00f;
+ text-decoration: underline; }
}
}
-function addContact(tag, fullContactName, contactId, contactName, contactEmail)
-{
+function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
var uids = $('uixselector-participants-uidList');
log ("contactId: " + contactId);
if (contactId)
var delay = 500;
var requestField;
var awaitingFreeBusyRequests = new Array();
-var freeBusySelectorId;
+var additionalDays = 2;
+
+var dayStartHour = 8;
+var dayEndHour = 18;
+
+var attendeesNames;
+var attendeesEmails;
function onContactKeydown(event) {
if (event.keyCode == 9) {
|| event.keyCode > 47) {
running = true;
requestField = this;
+ requestField.setAttribute("modified", "1");
setTimeout("triggerRequest()", delay);
}
else if (this.confirmedValue) {
}
}
-function resetFreeBusyZone()
-{
- var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+function resetFreeBusyZone() {
+ var table = $("freeBusy");
var row = table.tHead.rows[2];
for (var i = 1; i < row.cells.length; i++) {
var nodes = row.cells[i].childNodesWithTag("span");
}
}
-function redisplayFreeBusyZone()
-{
- var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+function redisplayFreeBusyZone() {
+ var table = $("freeBusy");
var row = table.tHead.rows[2];
- var stDay = this.timeWidgets['start']['date'].valueAsDate();
- var etDay = this.timeWidgets['end']['date'].valueAsDate();
+ var stDay = $("startTime_date").valueAsDate();
+ var etDay = $("endTime_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;
+ var stHour = parseInt($("startTime_time_hour").value);
+ var stMinute = parseInt($("startTime_time_minute").value) / 15;
+ var etHour = parseInt($("endTime_time_hour").value);
+ var etMinute = parseInt($("endTime_time_minute").value) / 15;
if (stHour < 8) {
stHour = 8;
stMinute = 0;
}
}
-function newAttendee(event)
-{
- var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+function newAttendee(event) {
+ var table = $("freeBusy");
var tbody = table.tBodies[0];
var model = tbody.rows[tbody.rows.length - 1];
var newAttendeeRow = tbody.rows[tbody.rows.length - 2]
input.focussed = true;
}
-function checkAttendee()
-{
+function checkAttendee() {
this.focussed = false;
var th = this.parentNode.parentNode;
var tbody = th.parentNode;
resetAttendeesValue();
}
-function displayFreeBusyForNode(node)
-{
+function displayFreeBusyForNode(node) {
var nodes = node.parentNode.parentNode.cells;
if (node.uid) {
for (var i = 1; i < nodes.length; i++) {
document.contactFreeBusyAjaxRequest.aborted = true;
document.contactFreeBusyAjaxRequest.abort();
}
- var sd = startDayAsShortString();
- var ed = endDayAsShortString();
+ var sd = $('startTime_date').valueAsShortDateString();
+ var ed = $('endTime_date').valueAsShortDateString();
var urlstr = ( UserFolderURL + "../" + node.uid + "/freebusy.ifb/ajaxRead?"
- + "sday=" + sd + "&eday=" + ed + "&additional=2" );
+ + "sday=" + sd + "&eday=" + ed + "&additional=" + additionalDays );
document.contactFreeBusyAjaxRequest
= triggerAjaxRequest(urlstr,
updateFreeBusyData,
}
}
-function updateFreeBusyData(http)
-{
+function updateFreeBusyData(http) {
if (http.readyState == 4) {
if (http.status == 200) {
var node = http.callbackData;
}
}
-function resetAttendeesValue()
-{
- var table = $("attendeesView").childNodesWithTag("div")[0].childNodesWithTag("table")[0];
+function resetAttendeesValue() {
+ var table = $("freeBusy");
var inputs = table.getElementsByTagName("input");
var uids = new Array();
for (var i = 0; i < inputs.length - 2; i++) {
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];
+function resetAllFreeBusys() {
+ var table = $("freeBusy");
var inputs = table.getElementsByTagName("input");
for (var i = 0; i < inputs.length - 2; i++) {
displayFreeBusyForNode(awaitingFreeBusyRequests.shift());
}
-if (this.initTimeWidgets)
- this.oldInitTimeWidgets = this.initTimeWidgets;
+function initializeWindowButtons() {
+ var okButton = $("okButton");
+ var cancelButton = $("cancelButton");
+
+ okButton.addEventListener("click", onEditorOkClick, false);
+ cancelButton.addEventListener("click", onEditorCancelClick, false);
+
+ var buttons = $("freeBusyViewButtons").childNodesWithTag("a");
+ for (var i = 0; i < buttons.length; i++)
+ buttons[i].addEventListener("click", listRowMouseDownHandler, false);
+ buttons = $("freeBusyZoomButtons").childNodesWithTag("a");
+ for (var i = 0; i < buttons.length; i++)
+ buttons[i].addEventListener("click", listRowMouseDownHandler, false);
+ buttons = $("freeBusyButtons").childNodesWithTag("a");
+ for (var i = 0; i < buttons.length; i++)
+ buttons[i].addEventListener("click", listRowMouseDownHandler, false);
+}
+
+function onEditorOkClick(event) {
+ event.preventDefault();
+
+ attendeesNames = new Array();
+ attendeesEmails = new Array();
+
+ var table = $("freeBusy");
+ var inputs = table.getElementsByTagName("input");
+ for (var i = 0; i < inputs.length - 2; i++) {
+ var name = inputs[i].uid;
+ if (!(name && name.length > 0)) {
+ name = extractEmailName(inputs[i].value);
+ log ("name: " + name);
+ }
+ var email = extractEmailAddress(inputs[i].value);
+ var pos = attendeesEmails.indexOf(email);
+ if (pos == -1)
+ pos = attendeesEmails.length;
+ attendeesNames[pos] = name;
+ attendeesEmails[pos] = email;
+ }
+
+ parent$("attendeesNames").value = attendeesNames.join(",");
+ parent$("attendeesEmails").value = attendeesEmails.join(",");
+ window.opener.refreshAttendees();
+
+ updateParentDateFields("startTime", "startTime");
+ updateParentDateFields("endTime", "endTime");
+
+ window.close();
+}
+
+function onEditorCancelClick(event) {
+ event.preventDefault();
+ window.close();
+}
+
+function synchronizeWithParent(srcWidgetName, dstWidgetName) {
+ var srcDate = parent$(srcWidgetName + "_date");
+ var dstDate = $(dstWidgetName + "_date");
+ dstDate.value = srcDate.value;
-this.initTimeWidgets = function(widgets) {
- if (this.oldInitTimeWidgets)
- this.oldInitTimeWidgets(widgets);
+ var srcHour = parent$(srcWidgetName + "_time_hour");
+ var dstHour = $(dstWidgetName + "_time_hour");
+ dstHour.value = srcHour.value;
- this.timeWidgets = widgets;
+ var srcMinute = parent$(srcWidgetName + "_time_minute");
+ var dstMinute = $(dstWidgetName + "_time_minute");
+ dstMinute.value = srcMinute.value;
+}
- 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);
+function updateParentDateFields(srcWidgetName, dstWidgetName) {
+ var srcDate = $(srcWidgetName + "_date");
+ var dstDate = parent$(dstWidgetName + "_date");
+ dstDate.value = srcDate.value;
- widgets['start']['date'].assignReplica($("FBStartTimeReplica_date"));
- widgets['end']['date'].assignReplica($("FBEndTimeReplica_date"));
+ var srcHour = $(srcWidgetName + "_time_hour");
+ var dstHour = parent$(dstWidgetName + "_time_hour");
+ dstHour.value = srcHour.value;
- 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"]);
+ var srcMinute = $(srcWidgetName + "_time_minute");
+ var dstMinute = parent$(dstWidgetName + "_time_minute");
+ dstMinute.value = srcMinute.value;
+}
+
+function initializeTimeWidgets() {
+ synchronizeWithParent("startTime", "startTime");
+ synchronizeWithParent("endTime", "endTime");
+
+ $("startTime_date").addEventListener("change", onTimeDateWidgetChange, false);
+ $("startTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
+ $("startTime_time_minute").addEventListener("change", onTimeWidgetChange,
+ false);
+
+ $("endTime_date").addEventListener("change", onTimeDateWidgetChange, false);
+ $("endTime_time_hour").addEventListener("change", onTimeWidgetChange, false);
+ $("endTime_time_minute").addEventListener("change", onTimeWidgetChange, false);
+}
+
+function onTimeWidgetChange() {
+ redisplayFreeBusyZone();
}
function onTimeDateWidgetChange(event) {
- if (document.timeWidgetsFreeBusyAjaxRequest) {
- document.timeWidgetsFreeBusyAjaxRequest.aborted = true;
- document.timeWidgetsFreeBusyAjaxRequest.abort();
+ var table = $("freeBusy");
+
+ var rows = table.tHead.rows;
+ for (var i = 0; i < rows.length; i++) {
+ for (var j = rows[i].cells.length - 1; j > 0; j--) {
+ rows[i].deleteCell(j);
+ }
+ }
+
+ rows = table.tBodies[0].rows;
+ for (var i = 0; i < rows.length; i++) {
+ for (var j = rows[i].cells.length - 1; j > 0; j--) {
+ rows[i].deleteCell(j);
+ }
}
- 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);
+ prepareTableHeaders();
+ prepareTableRows();
+ redisplayFreeBusyZone();
+ resetAttendeesValue();
+ resetAllFreeBusys();
}
-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 prepareTableHeaders() {
+ var startTimeDate = $("startTime_date");
+ var startDate = startTimeDate.valueAsDate();
+
+ var endTimeDate = $("endTime_date");
+ var endDate = endTimeDate.valueAsDate();
+ endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
+
+ var rows = $("freeBusy").tHead.rows;
+ var days = startDate.daysUpTo(endDate);
+ for (var i = 0; i < days.length; i++) {
+ var header1 = document.createElement("th");
+ header1.colSpan = (dayEndHour - dayStartHour) + 1;
+ header1.appendChild(document.createTextNode(days[i].toLocaleDateString()));
+ rows[0].appendChild(header1);
+ for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++) {
+ var header2 = document.createElement("th");
+ var text = hour + ":00";
+ if (hour < 10)
+ text = "0" + text;
+ header2.appendChild(document.createTextNode(text));
+ rows[1].appendChild(header2);
+
+ var header3 = document.createElement("th");
+ for (var span = 0; span < 4; span++) {
+ var spanElement = document.createElement("span");
+ spanElement.addClassName("freeBusyZoneElement");
+ header3.appendChild(spanElement);
+ }
+ rows[2].appendChild(header3);
+ }
+ }
}
-function onTimeWidgetChange()
-{
- setTimeout("redisplayFreeBusyZone();", 1000);
+function prepareTableRows() {
+ var startTimeDate = $("startTime_date");
+ var startDate = startTimeDate.valueAsDate();
+
+ var endTimeDate = $("endTime_date");
+ var endDate = endTimeDate.valueAsDate();
+ endDate.setTime(endDate.getTime() + (additionalDays * 86400000));
+
+ var rows = $("freeBusy").tBodies[0].rows;
+ var days = startDate.daysUpTo(endDate);
+ for (var i = 0; i < days.length; i++) {
+ for (var rowNbr = 0; rowNbr < rows.length; rowNbr++) {
+ for (var hour = dayStartHour; hour < (dayEndHour + 1); hour++) {
+ var cell = document.createElement("td");
+ rows[rowNbr].appendChild(cell);
+ }
+ }
+ }
+}
+
+function prepareAttendees() {
+ var value = parent$("attendeesNames").value;
+ if (value.length > 0) {
+ attendeesNames = parent$("attendeesNames").value.split(",");
+ attendeesEmails = parent$("attendeesEmails").value.split(",");
+
+ var body = $("freeBusy").tBodies[0];
+ for (var i = 0; i < attendeesNames.length; i++) {
+ var tr = body.insertRow(i);
+ var td = document.createElement("td");
+ td.addClassName("attendees");
+ var input = document.createElement("input");
+ var value = "";
+ if (attendeesNames[i].length > 0)
+ value += attendeesNames[i] + " ";
+ value += "<" + attendeesEmails[i] + ">";
+ input.value = value;
+ input.setAttribute("uid", attendeesNames[i]);
+ input.addClassName("textField");
+ input.setAttribute("modified", "0");
+ tr.appendChild(td)
+ td.appendChild(input)
+ }
+ }
+ else {
+ attendeesNames = new Array();
+ attendeesEmails = new Array();
+ }
}
function onFreeBusyLoadHandler() {
- initializeFreeBusyUserSelector();
+ initializeWindowButtons();
+ initializeTimeWidgets();
+ prepareAttendees();
+ prepareTableHeaders();
+ prepareTableRows();
+ redisplayFreeBusyZone();
+ resetAttendeesValue();
+ resetAllFreeBusys();
}
window.addEventListener("load", onFreeBusyLoadHandler, false);
DIV#editorTabs
-{
- position: absolute;
- top: 0px;
- left: 0px;
- right: 0px;
- bottom: 2.5em;;
- margin-bottom: 1em;
-}
+{ position: absolute;
+ top: .5em;
+ left: .5em;
+ right: .5em;
+ bottom: 2.5em;
+ margin-bottom: 1em; }
DIV#editorTabs DIV.tab
{ padding: .5em;
- overflow: auto; }
+ overflow: hidden; }
+
+SELECT
+{ width: 8em; }
+
+DIV.tab TABLE
+{ border: 1px solid #aaa;
+ margin-top: -.5em;
+ margin-left: auto;
+ margin-right: auto;
+ margin-bottom: 1em;
+ padding: 1em;
+ -moz-border-radius: 6px;
+ display: table;
+ text-align: right;
+ width: 100%; }
+
+SPAN.caption
+{ text-align: center;
+ cursor: default;
+ background: #999;
+ width: auto;
+ padding: .25em;
+ margin-left: 7px;
+ 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; }
DIV#buttons
{ visibility: visible;
*/
DIV#contactInfos INPUT.textField
-{ width: 65%; }
+{ width: 60%; }
+
+TD#htmlMailFormat
+{ text-align: left !important; }
TABLE#emailInfos TD
{ width: 90%; }
overflow: visible;
text-align: center; }
-TABLE
-{ display: table;
- text-align: right;
- width: 90%; }
-
DIV.tab TD INPUT.textField
-{ width: 70%; }
+{ width: 60%;
+ margin-left: .5em; }
DIV.tab TD.firstColumn INPUT.textField,
DIV.tab TD.secondColumn INPUT.textField
-{ width: 40%; }
+{ width: 35%; }
#otherInfos TEXTAREA
{ width: 70%; }
var contactSelectorAction = 'mailer-contacts';
-function addContact(tag, fullContactName, contactId, contactName, contactEmail)
-{
+function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
if (!mailIsRecipient(contactEmail)) {
var neededOptionValue = 0;
if (tag == "cc")
text-align: right;
width: 3em; }
-DIV#editorTabs
-{
- width: 100%;
- height: 38em;
-}
-
-DIV#editorTabs > DIV.tab
+DIV#eventView
{ overflow: hidden;
padding: .5em; }
{ 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; }
+#privacy-menu LI
+{ list-style-position: inside;
+ list-style-image: url("menu-nocheck.gif"); }
-UL.contactList LI._selected
-{ background: #4b6983;
- color: #fff; }
+#privacy-menu LI._chosen
+{ list-style-image: url("menu-check.gif"); }
-DIV.contactSelector
-{ margin: 0px; }
+#privacy-menu LI._chosen:hover
+{ list-style-image: url("menu-check-hover.gif"); }
LABEL, SPAN.checkBoxList
{ display: block;
width: 100%; }
LABEL#commentArea
-{ height: 11.5em; }
+{ height: 15em; }
SPAN.checkBoxList#participantsCB
{ height: 7em; }
SPAN.content
{ position: absolute;
top: -.25em;
- left: 8em;
+ left: 6em;
right: 1em; }
TEXTAREA
{ position: absolute;
top: 0px;
- left: 8em;
+ left: 6em;
vertical-align: bottom;
- height: 10em;
+ bottom: 1em;
right: 1em;
- padding-bottom: 1em; }
+ padding-bottom: 0em; }
+
+A#changeUrlButton
+{ margin-left: 1em; }
A#detailsButton
{ position: absolute;
{ border: 2px solid #000;
vertical-align: middle;
-moz-border-top-colors: #000 #fff;
- -moz-border-left-colors: #000 #fff;
+ -moz-border-left-colors: #000 #fff;
-moz-border-bottom-colors: #000 #fff;
-moz-border-right-colors: #000 #fff; }
{ margin-left: 0px;
margin-right: 1em; }
+SPAN#allDay > INPUT
+{ position: static; }
+
SPAN.content > INPUT
{ position: absolute;
top: 0px;
INPUT#startDateCB,
INPUT#dueDateCB,
+INPUT#statusPercent,
LABEL#urlArea INPUT
{ position: static; }
+
+INPUT#statusPercent
+{ width: 2em; }
+
+INPUT#statusTime_date
+{ width: 5em; }
-/*
- 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';
+window.addEventListener("load", onTaskEditorLoad, false);
+
function uixEarlierDate(date1, date2) {
// can this be done in a sane way?
// cuicui = 'year';
}
}
-function addContact(tag, fullContactName, contactId, contactName, contactEmail)
-{
+function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
var uids = $('uixselector-participants-uidList');
log ("contactId: " + contactId);
if (contactId)
widgets['start']['hour'].addEventListener("change", this.onAdjustDueTime, false);
widgets['start']['minute'].addEventListener("change", this.onAdjustDueTime, false);
}
+
+function onStatusListChange(event) {
+ var value = $("statusList").value;
+ var statusTimeDate = $("statusTime_date");
+ var statusPercent = $("statusPercent");
+
+ if (value == "WONoSelectionString") {
+ statusTimeDate.disabled = true;
+ statusPercent.disabled = true;
+ statusPercent.value = "";
+ }
+ else if (value == "0") {
+ statusTimeDate.disabled = true;
+ statusPercent.disabled = false;
+ }
+ else if (value == "1") {
+ statusTimeDate.disabled = true;
+ statusPercent.disabled = false;
+ }
+ else if (value == "2") {
+ statusTimeDate.disabled = false;
+ statusPercent.disabled = false;
+ statusPercent.value = "100";
+ }
+ else if (value == "3") {
+ statusTimeDate.disabled = true;
+ statusPercent.disabled = true;
+ }
+ else {
+ statusTimeDate.disabled = true;
+ }
+}
+
+function initializeStatusLine() {
+ var statusList = $("statusList");
+ statusList.addEventListener("mouseup", onStatusListChange, false);
+}
+
+function onTaskEditorLoad() {
+ initializeStatusLine();
+}
+++ /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;
-}
-
-/* appointments */
-
-.apt_organizer {
- color: #0033cc ! important;
-}
-.apt_organizer a {
- color: #0033cc ! important;
-}
-.apt_other {
- color: #000000 ! important;
-}
-.apt_other a {
- color: #000000 ! important;
-}
-
-.apt_nonparticipant {
- font-style: italic ! important;
-}
-.apt_participant {
-}
-
-.apt_private {
-}
-
-.apt_prio0, .apt_prio5, .apt_prio6, .apt_prio7, .apt_prio8, .apt_prio9 {
- font-weight: normal ! important;
-}
-.apt_prio1, .apt_prio2, .apt_prio3, .apt_prio4 {
- font-weight: bold ! important;
-}
-
-
-.apt_other_print {
- font-style: italic;
-}
-
-.aptprintview_apt_other {
- font-style: italic;
-}
-
-
-/* Anais */
-
-.anais_me {
- color: #0000FF;
-}
-
-.anais_uids {
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
-}
-
-
-/* schedule */
-
-.schedoverview {
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
- font-size: 10pt;
-}
-
-.titlefont {
- font-size: 12pt;
- font-weight: bold;
-}
-
-.titleheader {
- background-color: #d8d8d0;
-}
-
-.buttonheader {
- text-align: right;
-}
-
-th.schedoverview_title {
- font-size: 10pt;
- font-weight: bold;
- text-align: left;
- background-color: #e8e8e0;
- vertical-align: top;
-}
-
-th.schedoverview {
- font-size: 10pt;
- font-weight: bold;
- text-align: left;
- vertical-align: top;
-}
-
-td.schedoverview {
- font-size: 10pt;
- text-align: left;
- vertical-align: top;
-}
-
-.schedoverview a {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
- letter-spacing: 0pt;
- padding: 0px;
- text-decoration: none;
-}
-.schedoverview a:hover {
- text-decoration: underline;
-}
-
-
-/* day overview */
-
-.dayoverview {
- font-size: 8pt;
-}
-
-.dayoverview_content {
- padding: 1px;
- margin: 0px 0px 0px 0px;
- vertical-align: top;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
-}
-
-.dayoverview_content_time {
- background-color: #d2d2cc;
- text-align: center;
- font-size: 9pt;
-}
-
-.dayoverview_content_time_link {
- font-size: 8pt;
-}
-.dayoverview_content_time_link a {
- color: #0033cc;
- text-decoration: none;
-}
-.dayoverview_content_time_link a:hover {
- color: #ff0000;
- text-decoration: underline;
-}
-
-.dayoverview_content_apts {
- color: #0033cc;
- background-color: #e8e8e0;
- text-align: left;
- vertical-align: top;
-}
-
-.dayoverview_cal {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
- letter-spacing: 0pt;
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.dayoverview_cal table {
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.dayoverview_cal td {
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.dayoverview_cal a {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
- letter-spacing: 0pt;
- padding: 0px;
- text-decoration: none;
-}
-.dayoverview_cal a:hover {
- text-decoration: underline;
-}
-
-.dayoverview_cal_title {
- background-color: #d2d2cc;
- text-align: center;
- font-size: 10pt;
- font-weight: bold;
- letter-spacing: 0pt;
-}
-
-.dayoverview_cal_day_header {
- background-color: #d2d2cc;
- text-align: center;
- vertical-align: top;
- font-size: 11pt;
-/* width: 24px;
- padding: 2px 2px 2px 2px;
- margin: 2px 2px 2px 2px;
- */}
-
-.dayoverview_cal_content {
- color: #0033cc;
- background-color: #e8e8e0;
- text-align: center;
- vertical-align: top;
-}
-
-.dayoverview_cal_content_hilite {
- color: #0033cc;
- background-color: #fffff0;
- text-align: center;
- vertical-align: top;
-}
-
-.dayoverview_cal_content_selected {
- color: #ff0000;
-}
-.dayoverview_cal_content_selected a {
- color: #ff0000;
-}
-.dayoverview_cal_content_selected a:hover {
- color: #ff0000;
-}
-
-.dayoverview_cal_content_dimmed {
- color: #0033cc;
- background-color: #d2d2cc;
- text-align: center;
- vertical-align: top;
-}
-.dayoverview_cal_content_dimmed a {
- color: #5a5a5a;
-}
-.dayoverview_cal_content_dimmed a:hover {
- color: #5a5a5a;
-}
-
-
-/* day printview */
-
-.dayprintview {
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
- font-size: 10pt;
-}
-
-td.dayprintview_time {
- font-size: 10pt;
- font-weight: bold;
- text-align: center;
-}
-
-td.dayprintview_content {
- font-size: 10pt;
- text-align: left;
-}
-
-h1.dayprintview, h2.dayprintview {
- font-size: 11pt;
- font-weight: bold;
- margin: 0px;
- padding: 0px;
- text-align: center;
-}
-
-h1.dayprintview {
- font-style: italic;
-}
-
-.dayprintview_apt_other {
- font-style: italic;
-}
-
-
-/* week overview */
-
-.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;
-}
-
-
-/* week columnsview */
-
-.weekcolumnsview {
-}
-
-.weekcolumnsview_title {
- font-size: 10pt;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
- color: #000000;
- background-color: #d2d2cc;
- padding: 4px;
-}
-
-.weekcolumnsview_title a {
- color: #0033cc;
- text-decoration: none;
-}
-
-.weekcolumnsview_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;
- padding: 4px;
-}
-
-.weekcolumnsview_title_hilite a {
- color: #0033cc;
- text-decoration: none;
-}
-
-.weekcolumnsview_title_daylink {
- font-size: 12pt;
- color: #0033cc;
- font-weight: bold;
-}
-
-.weekcolumnsview_title_newlink {
- font-size: 8pt;
-}
-
-.weekcolumnsview_holidayinfo {
- font-size: 8pt;
- font-weight: bold;
-}
-
-.weekcolumnsview_content {
- color: #FFFFFF;
- background-color: #e8e8e0;
-}
-
-.weekcolumnsview_content a {
- color: #0000FF;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
- text-decoration: none;
-}
-
-.weekcolumnsview_content_hilite {
- background-color: #fffff0;
-}
-
-.weekcolumnsview_content_hilite a {
- color: #0000FF;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
- text-decoration: none;
-}
-
-.weekcolumnsview_cal {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
- letter-spacing: 0pt;
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.weekcolumnsview_cal table {
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.weekcolumnsview_cal td {
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.weekcolumnsview_cal a {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
- letter-spacing: 0pt;
- padding: 0px;
- text-decoration: none;
-}
-.weekcolumnsview_cal a:hover {
- text-decoration: underline;
-}
-
-.weekcolumnsview_cal_title {
- background-color: #d2d2cc;
- text-align: center;
- font-size: 10pt;
- font-weight: bold;
- letter-spacing: 0pt;
-}
-
-.weekcolumnsview_cal_day_header {
- background-color: #d2d2cc;
- text-align: center;
- vertical-align: middle;
- font-size: 11pt;
- width: 20px;
- padding: 2px 2px 2px 2px;
- margin: 2px 2px 2px 2px;
-}
-
-.weekcolumnsview_cal_content {
- color: #000000;
- background-color: #e8e8e0;
- text-align: center;
- vertical-align: middle;
- font-size: 10pt;
- letter-spacing: 0pt;
-}
-
-.weekcolumnsview_cal_content_hilite {
- color: #000000;
- background-color: #fffff0;
- text-align: center;
- vertical-align: middle;
- font-size: 10pt;
- letter-spacing: 0pt;
-}
-
-.weekcolumnsview_cal_content_dimmed {
- color: #5a5a5a;
- background-color: #d2d2cc;
- text-align: center;
- vertical-align: middle;
- font-size: 10pt;
- letter-spacing: 0pt;
-}
-
-.weekcolumnsview_cal_week {
- background-color: #d2d2cc;
- width: 16pt;
- text-align: center;
- vertical-align: middle;
-}
-
-
-/* week printview */
-
-td.weekprintview {
- border: 1px solid;
-}
-
-h1.weekprintview, h2.weekprintview {
- font-size: 10pt;
- font-weight: bold;
- margin: 0px;
- padding: 0px;
- text-align: center;
-}
-
-h1.weekprintview {
- font-size: 12pt;
- font-style: italic;
-}
-
-.weekprintview_title {
- font-size: 11pt;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
-}
-
-.weekprintview_title_hilite a {
- color: #0033cc;
- text-decoration: none;
-}
-
-.weekprintview_holidayinfo {
- font-size: 10pt;
- font-weight: bold;
-}
-
-.weekprintview_content, .weekprintview_apt_time {
- font-size: 10pt;
-}
-
-.weekprintview_apt_time {
- font-weight: bold;
- font-style: italic;
-}
-
-.weekprintview_apt_time_other {
- font-style: italic;
-}
-
-.weekprintview_apt_other {
- font-style: italic;
-}
-
-
-/* month overview */
-
-.monthoverview {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 7pt;
- font-style: normal;
- font-weight: normal;
- letter-spacing: 0pt;
- text-decoration: none;
-
- text-align: left;
- vertical-align: top;
-}
-
-.monthoverview a {
- color: #0033cc;
-}
-
-.monthoverview a:hover {
- text-decoration: underline;
-}
-
-.monthoverview_title {
- background-color: #d2d2cc;
- font-size: 10pt;
- 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: 7pt;
- height: 60;
- text-align: left;
- vertical-align: top;
-}
-.monthoverview_content a {
- font-style: italic;
- font-weight: bold;
-}
-
-.monthoverview_content_hilite {
- background-color: #fffff0;
- font-size: 7pt;
- height: 60;
- text-align: left;
- vertical-align: top;
-}
-.monthoverview_content_hilite a {
- font-style: italic;
- font-weight: bold;
-}
-
-.monthoverview_content_dimmed {
- background-color: #d2d2cc;
- font-size: 7pt;
- height: 60;
- text-align: left;
- vertical-align: top;
-}
-.monthoverview_content_dimmed a {
- font-style: normal;
- font-weight: normal;
-}
-
-/* .monthoverview_day {
- text-align: left;
- vertical-align: top;
-}
- */
-.monthoverview_day a {
- color: #000000;
- 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;
-}
-
-
-/* month printview */
-
-.monthprintview {
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- letter-spacing: 0pt;
- font-size: 9pt;
-}
-
-h1.monthprintview_header, h2.monthprintview_header {
- font-size: 10pt;
- font-weight: bold;
- margin: 0px;
- padding: 0px;
- text-align: center;
-}
-
-h1.monthprintview_header {
- font-size: 12pt;
- font-style: italic;
-}
-
-.monthprintview_title {
- text-align: center;
-}
-
-.monthprintview_week {
- width: 16pt;
- text-align: center;
- vertical-align: middle;
-}
-
-.monthprintview_apt, .monthprintview_apt_time {
- font-size: 7pt;
-}
-
-.monthprintview_apt_time {
- font-weight: bold;
- font-style: italic;
-}
-
-.monthprintview_apt_time_other {
- font-style: italic;
-}
-
-.monthprintview_apt_other {
- font-style: italic;
-}
-
-td.monthprintview_content {
- text-align: left;
- vertical-align: top;
- font-style: italic;
- font-weight: bold;
- font-size: 12pt;
- height: 60;
-}
-
-td.monthprintview_content_dimmed {
- text-align: left;
- vertical-align: top;
- font-size: 12pt;
- height: 60;
-}
-
-
-/* year overview */
-
-.yearoverview {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
- letter-spacing: 0pt;
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.yearoverview table {
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.yearoverview td {
- padding: 0px 0px 0px 0px;
- margin: 0px 0px 0px 0px;
-}
-
-.yearoverview a {
- color: #000000;
- font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
- font-size: 10pt;
- letter-spacing: 0pt;
- padding: 0px;
- text-decoration: none;
-}
-.yearoverview a:hover {
- text-decoration: underline;
-}
-
-.yearoverview_title {
- background-color: #d2d2cc;
- text-align: center;
- font-size: 10pt;
- font-weight: bold;
- letter-spacing: 0pt;
-}
-
-.yearoverview_day_header {
- background-color: #d2d2cc;
- text-align: center;
- vertical-align: middle;
- font-size: 10pt;
- width: 18px; /* this delimits all td's! */
-}
-
-.yearoverview_content {
- color: #0033cc;
- background-color: #e8e8e0;
- text-align: center;
- vertical-align: middle;
- font-weight: bold;
- font-style: italic;
-}
-.yearoverview_content a {
- color: #0033cc;
-}
-.yearoverview_content a:hover {
- color: #ff0000;
-}
-
-.yearoverview_content_hilite {
- color: #0033cc;
- background-color: #fffff0;
- text-align: center;
- vertical-align: middle;
- font-weight: bold;
- font-style: italic;
-}
-.yearoverview_content_hilite a {
- color: #0033cc;
-}
-.yearoverview_content_hilite a:hover {
- color: #ff0000;
-}
-
-.yearoverview_content_dimmed {
- color: #0033cc;
- background-color: #d2d2cc;
- text-align: center;
- vertical-align: middle;
-}
-.yearoverview_content_dimmed a {
- color: #0033cc;
-}
-.yearoverview_content_dimmed a:hover {
- color: #ff0000;
-}
-
-.yearoverview_week {
- background-color: #d2d2cc;
- width: 16pt;
- text-align: center;
- vertical-align: middle;
-}
-
-.yearoverview_week_hilite {
- background-color: #fffff0;
- width: 16pt;
- text-align: center;
- vertical-align: middle;
-}
var allDocumentElements = null;
/* a W3C compliant document.all */
-function getAllScopeElements(scope)
-{
+function getAllScopeElements(scope) {
var elements = new Array();
for (var i = 0; i < scope.childNodes.length; i++)
return elements;
}
-function getAllElements(scope)
-{
+function getAllElements(scope) {
var elements;
if (scope == null)
function extractEmailName(mailTo) {
var emailName = "";
- var emailNamere = /(\w[\w\ _-]+)\ (<|<)/;
+ var emailNamere = /(.+)\ </;
if (emailNamere.test(mailTo)) {
emailNamere.exec(mailTo);
emailName = RegExp.$1;
}
+
+ return emailName;
}
function sanitizeMailTo(dirtyMailTo) {
}
}
+/* toolbar buttons */
+function popupToolbarMenu(event, menuId) {
+ var toolbar = $("toolbar");
+ var node = event.target;
+ if (node.tagName != 'A')
+ node = node.getParentWithTagName("a");
+ node = node.childNodesWithTag("span")[0];
+
+ if (event.button == 0) {
+ event.cancelBubble = true;
+ event.returnValue = false;
+
+ if (document.currentPopupMenu)
+ hideMenu(event, document.currentPopupMenu);
+
+ var popup = document.getElementById(menuId);
+ var top = node.offsetTop + node.offsetHeight - 2;
+ popup.style.top = top + "px";
+ popup.style.left = node.cascadeLeftOffset() + "px";
+ popup.style.visibility = "visible";
+
+ bodyOnClick = "" + document.body.getAttribute("onclick");
+ document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');");
+ document.currentPopupMenu = popup;
+ }
+}
+
/* contact selector */
-function onContactAdd(node)
-{
+function onContactAdd(node) {
var selector = null;
var selectorURL = '?popup=YES';
if (node) {
}
/* tabs */
-function initTabs()
-{
+function initTabs() {
var containers = document.getElementsByClassName("tabsContainer");
for (var x = 0; x < containers.length; x++) {
var container = containers[x];
var linkBanner = $("linkBanner");
if (linkBanner) {
var anchors = linkBanner.childNodesWithTag("a");
- for (var i = 0; i < 4; i++) {
+ for (var i = 0; i < 2; i++) {
anchors[i].addEventListener("mousedown", listRowMouseDownHandler,
false);
anchors[i].addEventListener("click", onLinkBannerClick, false);
}
- if (anchors.length > 5)
- anchors[5].addEventListener("click", toggleLogConsole, true);
+ if (anchors.length > 3)
+ anchors[3].addEventListener("click", toggleLogConsole, true);
}
}
function onHeaderClick(event) {
window.alert("generic headerClick");
}
+
+function parent$(element) {
+ return window.opener.document.getElementById(element);
+}