+2007-11-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject
+ -aclsForUser:uid]): copy all the roles from the container. If the
+ object is new, make sure the roles contain "ObjectEditor" if and
+ only if "ObjectCreator" is present.
+
+ * SoObjects/SOGo/SOGoGCSFolder.m ([SOGoGCSFolder
+ -aclsForUser:uid]): no longer take the "ObjectReader" role into
+ account.
+
+ * UI/Common/UIxFolderActions.m ([UIxFolderActions
+ -canAccessContentAction]): always return HTTP status 204. We want
+ this because we are relying on the SOPE access control manager to
+ grant access to this method. This requires a fine-tuned access
+ control in SOGo itself...
+
+ * UI/Contacts/UIxContactsUserRightsEditor.m ([-userCanReadObjects])
+ ([-setUserCanReadObjects:userCanReadObjects]): removed methods.
+
+ * UI/MailerUI/UIxMailUserRightsEditor.m ([UIxMailUserRightsEditor
+ -updateRights]): no longer take the "ObjectReader" role into account.
+ ([-userCanReadMails], [-setUserCanReadMails:userCanReadMails]):
+ removed methods.
+
+ * SoObjects/Appointments/SOGoFreeBusyObject.m ([SOGoFreeBusyObject
+ -fetchFreeBusyInfosFrom:_startDateto:_endDate]): specify context
+ when looking up the Calendar folder.
+
2007-11-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor -todo]): same as below.
+2007-11-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * GCSFolder.m ([GCSFolder -versionOfContentWithName:], [GCSFolder
+ -fetchContentWithName:]): ignore records marked as deleted.
+ ([GCSFolder -deletionOfContentWithName:]): don't.
+
2007-11-04 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* GCSFolder.m ([GCSFolder -writeContent:toName:baseVersion:]): the
recursive:YES];
}
-- (id)_fetchValueOfColumn:(NSString *)_col inContentWithName:(NSString *)_name{
+- (id) _fetchValueOfColumn: (NSString *)_col
+ inContentWithName: (NSString *)_name
+ ignoreDeleted: (BOOL) ignoreDeleted
+{
EOAdaptorChannel *channel;
NSException *error;
NSDictionary *row;
NSArray *attrs;
NSString *result;
- NSString *sql;
+ NSMutableString *sql;
if ((channel = [self acquireStoreChannel]) == nil) {
[self errorWithFormat:@"could not open storage channel!"];
}
/* generate SQL */
-
- sql = @"SELECT ";
- sql = [sql stringByAppendingString:_col];
- sql = [sql stringByAppendingString:@" FROM "];
- sql = [sql stringByAppendingString:[self storeTableName]];
- sql = [sql stringByAppendingString:@" WHERE c_name = '"];
- sql = [sql stringByAppendingString:_name];
- sql = [sql stringByAppendingString:@"'"];
-
+ sql = [NSMutableString stringWithFormat: @"SELECT %@"
+ @" FROM %@"
+ @" WHERE c_name = '%@'",
+ _col, [self storeTableName], _name];
+ if (ignoreDeleted)
+ [sql appendString: @" AND (c_deleted != 1 OR c_deleted IS NULL)"];
+
/* run SQL */
if ((error = [channel evaluateExpressionX:sql]) != nil) {
[self errorWithFormat:@"%s: cannot execute SQL '%@': %@",
- __PRETTY_FUNCTION__, sql, error];
+ __PRETTY_FUNCTION__, sql, error];
[self releaseChannel:channel];
return nil;
}
}
- (NSNumber *)versionOfContentWithName:(NSString *)_name {
- return [self _fetchValueOfColumn:@"c_version" inContentWithName:_name];
+ return [self _fetchValueOfColumn:@"c_version" inContentWithName:_name
+ ignoreDeleted: YES];
}
- (NSNumber *)deletionOfContentWithName:(NSString *)_name {
- return [self _fetchValueOfColumn:@"c_deleted" inContentWithName:_name];
+ return [self _fetchValueOfColumn:@"c_deleted" inContentWithName:_name
+ ignoreDeleted: NO];
}
- (NSString *)fetchContentWithName:(NSString *)_name {
- return [self _fetchValueOfColumn:@"c_content" inContentWithName:_name];
+ return [self _fetchValueOfColumn:@"c_content" inContentWithName:_name
+ ignoreDeleted: YES];
}
- (NSDictionary *)fetchContentsOfAllFiles {
// SoSecurityManager *sm;
NSArray *infos;
- calFolder = [[container lookupName: @"Calendar" inContext: nil acquire: NO]
- lookupName: @"personal" inContext: nil acquire: NO];
+ calFolder = [[container lookupName: @"Calendar" inContext: context acquire: NO]
+ lookupName: @"personal" inContext: context acquire: NO];
// sm = [SoSecurityManager sharedSecurityManager];
// if (![sm validatePermission: SOGoPerm_FreeBusyLookup
// onObject: calFolder
switch ([imapAcls characterAtIndex: count])
{
case 'l':
- [SOGoAcls addObjectUniquely: SOGoRole_ObjectViewer];
- break;
case 'r':
- [SOGoAcls addObjectUniquely: SOGoRole_ObjectReader];
+ [SOGoAcls addObjectUniquely: SOGoRole_ObjectViewer];
break;
case 's':
[SOGoAcls addObjectUniquely: SOGoMailRole_SeenKeeper];
while (currentAcl)
{
if ([currentAcl isEqualToString: SOGoRole_ObjectViewer])
- character = 'l';
- else if ([currentAcl isEqualToString: SOGoRole_ObjectReader])
- character = 'r';
+ {
+ [imapAcls appendFormat: @"lr"];
+ character = 0;
+ }
else if ([currentAcl isEqualToString: SOGoMailRole_SeenKeeper])
character = 's';
else if ([currentAcl isEqualToString: SOGoMailRole_Writer])
superclass = "SOGoMailBaseObject";
defaultRoles = {
"View" = ( "Owner", "ObjectViewer" );
- "Access Contents Information" = ( "Owner", "ObjectReader" );
+ "Access Contents Information" = ( "Owner", "ObjectViewer" );
"Add Documents, Images, and Files" = ( "Owner", "ObjectCreator" );
"Delete Objects" = ( "Owner", "ObjectEraser" );
"WebDAV Access" = ( "Owner", "ObjectViewer" );
containerAcls = [container aclsForUser: uid];
if ([containerAcls count] > 0)
{
- if ([containerAcls containsObject: SOGoRole_ObjectCreator])
+ [acls addObjectsFromArray: containerAcls];
+ if (isNew)
{
- [acls addObject: SOGoRole_ObjectCreator];
- if (isNew)
+ if ([containerAcls containsObject: SOGoRole_ObjectCreator])
[acls addObject: SOGoRole_ObjectEditor];
+ else
+ [acls removeObject: SOGoRole_ObjectEditor];
}
- if ([containerAcls containsObject: SOGoRole_ObjectReader])
- [acls addObject: SOGoRole_ObjectViewer];
- if ([containerAcls containsObject: SOGoRole_ObjectEditor])
- [acls addObject: SOGoRole_ObjectEditor];
}
return acls;
containerAcls = [container aclsForUser: uid];
if ([containerAcls count] > 0)
{
- if ([containerAcls containsObject: SOGoRole_ObjectReader])
- [acls addObject: SOGoRole_ObjectViewer];
#warning this should be checked
if ([containerAcls containsObject: SOGoRole_ObjectEraser])
[acls addObject: SOGoRole_ObjectEraser];
NSString *SOGoRole_ObjectCreator = @"ObjectCreator";
NSString *SOGoRole_ObjectEraser = @"ObjectEraser";
NSString *SOGoRole_ObjectViewer = @"ObjectViewer";
-NSString *SOGoRole_ObjectReader = @"ObjectReader";
NSString *SOGoRole_ObjectEditor = @"ObjectEditor";
NSString *SOGoRole_FolderCreator = @"FolderCreator";
- (WOResponse *) canAccessContentAction
{
-#warning IMPROVEMENTS REQUIRED!
- NSArray *acls;
-// NSEnumerator *userAcls;
-// NSString *currentAcl;
+ /* We want this action to be authorized managed by the SOPE's internal acl
+ handling. */
+ return [self responseWith204];
+// #warning IMPROVEMENTS REQUIRED!
+// NSArray *acls;
+// // NSEnumerator *userAcls;
+// // NSString *currentAcl;
- [self _setupContext];
+// [self _setupContext];
-// NSLog(@"canAccessContentAction %@, owner %@", subscriptionPointer, owner);
-
- if ([login isEqualToString: owner] || [owner isEqualToString: @"nobody"]) {
- return [self responseWith204];
- }
- else {
- acls = [clientObject aclsForUser: login];
-// userAcls = [acls objectEnumerator];
-// currentAcl = [userAcls nextObject];
-// while (currentAcl) {
-// NSLog(@"ACL login %@, owner %@, folder %@: %@",
-// login, owner, baseFolder, currentAcl);
-// currentAcl = [userAcls nextObject];
-// }
- if (([[clientObject folderType] isEqualToString: @"Contact"] && [acls containsObject: SOGoRole_ObjectReader]) ||
- ([[clientObject folderType] isEqualToString: @"Appointment"] && [acls containsObject: SOGoRole_AuthorizedSubscriber])) {
- return [self responseWith204];
- }
- }
+// // NSLog(@"canAccessContentAction %@, owner %@", subscriptionPointer, owner);
+
+// if ([login isEqualToString: owner] || [owner isEqualToString: @"nobody"]) {
+// return [self responseWith204];
+// }
+// else {
+// acls = [clientObject aclsForUser: login];
+// // userAcls = [acls objectEnumerator];
+// // currentAcl = [userAcls nextObject];
+// // while (currentAcl) {
+// // NSLog(@"ACL login %@, owner %@, folder %@: %@",
+// // login, owner, baseFolder, currentAcl);
+// // currentAcl = [userAcls nextObject];
+// // }
+// if (([[clientObject folderType] isEqualToString: @"Contact"]
+// && [acls containsObject: SOGoRole_ObjectViewer]) ||
+// ([[clientObject folderType] isEqualToString: @"Appointment"]
+// && [acls containsObject: SOGoRole_AuthorizedSubscriber])) {
+// return [self responseWith204];
+// }
+// }
- return [self responseWithStatus: 403];
+// return [self responseWithStatus: 403];
}
- (WOResponse *) _realFolderActivation: (BOOL) makeActive
actionName = "unsubscribe";
};
canAccessContent = {
- protectedBy = "<public>";
+ protectedBy = "Access Object";
actionClass = "UIxFolderActions";
actionName = "canAccessContent";
};
[folders autorelease];
subfolders = [[parentFolder subFolders] objectEnumerator];
- currentFolder = [subfolders nextObject];
- while (currentFolder)
+ while ((currentFolder = [subfolders nextObject]))
{
if (![securityManager validatePermission: SOGoPerm_AccessObject
onObject: currentFolder inContext: context])
forKey: @"type"];
[folders addObject: currentDictionary];
}
- currentFolder = [subfolders nextObject];
}
return folders;
return [userRights containsObject: SOGoRole_ObjectViewer];
}
-- (void) setUserCanReadObjects: (BOOL) userCanReadObjects
-{
- if (userCanReadObjects)
- [self appendRight: SOGoRole_ObjectReader];
- else
- [self removeRight: SOGoRole_ObjectReader];
-}
-
-- (BOOL) userCanReadObjects
-{
- return [userRights containsObject: SOGoRole_ObjectReader];
-}
-
- (void) updateRights
{
WORequest *request;
else
[self removeRight: SOGoRole_ObjectViewer];
- if ([[request formValueForKey: @"ObjectReader"] length] > 0)
- [self appendRight: SOGoRole_ObjectReader];
- else
- [self removeRight: SOGoRole_ObjectReader];
-
if ([[request formValueForKey: @"ObjectEraser"] length] > 0)
[self appendRight: SOGoRole_ObjectEraser];
else
return [userRights containsObject: SOGoRole_ObjectViewer];
}
-- (void) setUserCanReadMails: (BOOL) userCanReadMails
-{
- if (userCanReadMails)
- [self appendRight: SOGoRole_ObjectReader];
- else
- [self removeRight: SOGoRole_ObjectReader];
-}
-
-- (BOOL) userCanReadMails
-{
- return [userRights containsObject: SOGoRole_ObjectReader];
-}
-
- (void) setUserCanMarkMailsRead: (BOOL) userCanMarkMailsRead
{
if (userCanMarkMailsRead)
else
[self removeRight: SOGoRole_ObjectViewer];
- if ([[request formValueForKey: SOGoRole_ObjectReader] length] > 0)
- [self appendRight: SOGoRole_ObjectReader];
- else
- [self removeRight: SOGoRole_ObjectReader];
-
if ([[request formValueForKey: SOGoMailRole_SeenKeeper] length] > 0)
[self appendRight: SOGoMailRole_SeenKeeper];
else
NSNumber *status;
NSCalendarDate *currentDate;
- record = [records nextObject];
- while (record)
+ while ((record = [records nextObject]))
{
status = [record objectForKey: @"c_status"];
for (count = startInterval; count < endInterval; count++)
[items replaceObjectAtIndex: count withObject: status];
-
- record = [records nextObject];
}
}
defaultRoles = {
"View" = ( "Owner", "ObjectViewer" );
"Change Images And Files" = ( "Owner", "ObjectEditor" );
- "Access Contents Information" = ( "Owner", "ObjectReader" );
+ "Access Object" = ( "Owner", "ObjectViewer", "ObjectEditor", "ObjectCreator", "ObjectEraser" );
+ "Access Contents Information" = ( "Owner", "ObjectViewer" );
"Add Documents, Images, and Files" = ( "Owner", "ObjectCreator" );
"Add Folders" = ( "Owner", "FolderCreator" );
"ReadAcls" = ( "Owner" );
"SaveAcls" = ( "Owner" );
"Delete Objects" = ( "Owner", "ObjectEraser" );
+ "WebDAV Access" = ( "Owner", "ObjectViewer", "ObjectEditor", "ObjectCreator", "ObjectEraser" );
};
};
SOGoContentObject = {
superclass = "SOGoObject";
+ defaultAccess = "Access Contents Information";
protectedBy = "Access Object";
defaultRoles = {
- "Access Object" = ( "Owner", "ObjectViewer" );
- "Access Contents Information" = ( "Owner", "ObjectViewer" );
- "Change Images And Files" = ( "Owner", "ObjectEditor" );
+ "Access Contents Information" = ( "Owner", "ObjectViewer", "ObjectEditor" );
+ "Change Images And Files" = ( "Owner", "ObjectEditor" );
+ };
+ methods = {
+ DELETE = {
+ protectedBy = "Delete Objects";
+ };
+ GET = {
+ protectedBy = "Access Contents Information";
+ };
+ PUT = {
+ protectedBy = "Change Images And Files";
+ };
};
};
+
SOGoFolder = {
superclass = "SOGoObject";
protectedBy = "Access Object";
defaultRoles = {
"Change Images And Files" = ( "Owner", "ObjectEditor" );
- "WebDAV Access" = ( "Owner", "AuthorizedSubscriber" );
- "Access Object" = ( "Owner", "ObjectViewer" );
- "Access Contents Information" = ( "Owner", "ObjectViewer" );
+ "View" = ( "Owner", "ObjectViewer", "ObjectEditor" );
+ "Access Contents Information" = ( "Owner", "ObjectViewer", "ObjectEditor" );
};
};
SOGoParentFolder = {
validate_notitle = "No title is set, continue?";
validate_invalid_startdate = "Incorrect startdate field!";
validate_invalid_enddate = "Incorrect enddate field!";
-validate_endbeforestart = "Enddate is before startdate!";
+validate_endbeforestart = "The end date that you enteterd occurs before the start date.";
"Tasks" = "Tasks";
"Show completed tasks" = "Show completed tasks";
validate_notitle = "Le titre n'est pas rempli. Continuer quand-même ?";
validate_invalid_startdate = "La date de début est invalide !";
validate_invalid_enddate = "La date de fin est invalide !";
-validate_endbeforestart = "La date de fin est avant la date de début !";
+validate_endbeforestart = "La date de fin est avant la date de début.";
"Tasks" = "Tâches";
"Show completed tasks" = "Afficher les tâches accomplies";
iCalRecurrenceRule *rule;
[self event];
- if (event)
- {
- startDate = [event startDate];
- isAllDay = [event isAllDay];
- if (isAllDay)
- endDate = [[event endDate] dateByAddingYears: 0 months: 0 days: -1];
- else
- endDate = [event endDate];
- }
- else
+ if ([[self clientObject] isNew])
{
startDate = [self newStartDate];
duration = [self queryParameterForKey:@"dur"];
= [startDate dateByAddingYears: 0 months: 0 days: 0
hours: 0 minutes: minutes seconds: 0];
}
+ else
+ {
+ startDate = [event startDate];
+ isAllDay = [event isAllDay];
+ if (isAllDay)
+ endDate = [[event endDate] dateByAddingYears: 0 months: 0 days: -1];
+ else
+ endDate = [event endDate];
+ }
ASSIGN (aptStartDate, startDate);
ASSIGN (aptEndDate, endDate);
var:checked="userCanCreateObjects"/><var:string
label:value="This person can add cards to this addressbook."/></label>
<br/>
- <label><input type="checkbox" class="checkBox"
- const:name="ObjectEditor"
- var:checked="userCanEditObjects"/><var:string
- label:value="This person can edit the cards of this addressbook."/></label>
- <br/>
<label><input type="checkbox" class="checkBox"
const:name="ObjectViewer"
var:checked="userCanViewObjects"/><var:string
- label:value="This person can list the content of this addressbook."/></label>
+ label:value="This person can read the cards of this addressbook."/></label>
<br/>
<label><input type="checkbox" class="checkBox"
- const:name="ObjectReader"
- var:checked="userCanReadObjects"/><var:string
- label:value="This person can read the cards of this addressbook."/></label>
+ const:name="ObjectEditor"
+ var:checked="userCanEditObjects"/><var:string
+ label:value="This person can edit the cards of this addressbook."/></label>
<br/>
<label><input type="checkbox" class="checkBox"
const:name="ObjectEraser"
className="UIxComponentEditor"
var:component="event"
var:saveURL="saveURL">
+
<label><span id="allDay" class="content"><input class="checkBox"
type="checkbox" var:selection="isAllDay"
var:checked="isAllDay"
}
function contactsListCallback(http) {
- if (http.readyState == 4
- && http.status == 200) {
- document.contactsListAjaxRequest = null;
-
- var table = $("contactsList");
- if (table) {
- // Update table
- var data = http.responseText;
- var html = data.replace(/^(.*\n)*.*(<table(.*\n)*)$/, "$2");
- var tbody = table.tBodies[0];
- var tmp = document.createElement('div');
- $(tmp).update(html);
- table.replaceChild(tmp.firstChild.tBodies[0], tbody);
- }
- else {
- // Add table (doesn't happen .. yet)
- var div = $("contactsListContent");
- div.update(http.responseText);
- table = $("contactsList");
- configureSortableTableHeaders(table);
- TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
- }
+ if (http.readyState == 4) {
+ if (http.status == 200) {
+ document.contactsListAjaxRequest = null;
+
+ var table = $("contactsList");
+ if (table) {
+ // Update table
+ var data = http.responseText;
+ var html = data.replace(/^(.*\n)*.*(<table(.*\n)*)$/, "$2");
+ var tbody = table.tBodies[0];
+ var tmp = document.createElement('div');
+ $(tmp).update(html);
+ table.replaceChild(tmp.firstChild.tBodies[0], tbody);
+ }
+ else {
+ // Add table (doesn't happen .. yet)
+ var div = $("contactsListContent");
+ div.update(http.responseText);
+ table = $("contactsList");
+ configureSortableTableHeaders(table);
+ TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
+ }
- if (sorting["attribute"] && sorting["attribute"].length > 0) {
- var sortHeader;
- if (sorting["attribute"] == "displayName")
+ if (sorting["attribute"] && sorting["attribute"].length > 0) {
+ var sortHeader;
+ if (sorting["attribute"] == "displayName")
sortHeader = $("nameHeader");
- else if (sorting["attribute"] == "mail")
+ else if (sorting["attribute"] == "mail")
sortHeader = $("mailHeader");
- else if (sorting["attribute"] == "screenName")
+ else if (sorting["attribute"] == "screenName")
sortHeader = $("screenNameHeader");
- else if (sorting["attribute"] == "org")
+ else if (sorting["attribute"] == "org")
sortHeader = $("orgHeader");
- else if (sorting["attribute"] == "phone")
+ else if (sorting["attribute"] == "phone")
sortHeader = $("phoneHeader");
- else
+ else
sortHeader = null;
- if (sortHeader) {
+ if (sortHeader) {
var sortImages = $(table.tHead).getElementsByClassName("sortImage");
$(sortImages).each(function(item) {
item.remove();
var sortImage = createElement("img", "messageSortImage", "sortImage");
sortHeader.insertBefore(sortImage, sortHeader.firstChild);
if (sorting["ascending"])
- sortImage.src = ResourcesURL + "/title_sortdown_12x12.png";
+ sortImage.src = ResourcesURL + "/title_sortdown_12x12.png";
else
- sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
- }
- }
+ sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
+ }
+ }
- var selected = http.callbackData;
- if (selected) {
- for (var i = 0; i < selected.length; i++) {
+ var selected = http.callbackData;
+ if (selected) {
+ for (var i = 0; i < selected.length; i++) {
var row = $(selected[i]);
if (row)
- row.select();
- }
+ row.select();
+ }
+ }
+ }
+ else {
+ var table = $("contactsList");
+ if (table) {
+ var sortImages = $(table.tHead).getElementsByClassName("sortImage");
+ $(sortImages).each(function(item) {
+ item.remove();
+ });
+ var tBody = $(table.tBodies[0]);
+ var length = tBody.rows.length;
+ for (var i = length - 1; i > -1; i--)
+ tBody.removeChild(tBody.rows[i]);
+ }
}
}
else
setCaretTo: function(element, pos) {
element = $(element);
- if (element.selectionStart) { // For Mozilla and Safari
+ if (element.selectionStart) { // For Mozilla and Safari
element.focus();
element.setSelectionRange(pos, pos);
}
- else if (element.createTextRange) { // For IE
+ else if (element.createTextRange) { // For IE
var range = element.createTextRange();
range.move("character", pos);
range.select();
function onLoginCallback(http) {
if (http.readyState == 4) {
- if (isHttpStatus204(http.status))
- window.location.href = ApplicationBaseURL + $("userName").value;
+ if (isHttpStatus204(http.status)) {
+ var userName = $("userName").value;
+ var address = "" + window.location.href;
+ var baseAddress = ApplicationBaseURL + $("userName").value;
+ var altBaseAddress;
+ if (baseAddress[0] == "/") {
+ var parts = address.split("/");
+ var hostpart = parts[2];
+ var protocol = parts[0];
+ baseAddress = protocol + "//" + hostpart + baseAddress;
+ }
+ var altBaseAddress;
+ var parts = baseAddress.split("/");
+ parts.splice(3, 0);
+ altBaseAddress = parts.join("/");
+
+ var newAddress;
+ if ((address.startsWith(baseAddress)
+ || address.startsWith(altBaseAddress))
+ && !address.endsWith("/logoff"))
+ newAddress = address;
+ else
+ newAddress = baseAddress;
+ window.location.href = newAddress;
+ }
}
}
var usersRightsWindowWidth = 502;
function newEvent(sender, type) {
- var day = sender.day;
+ var day = sender.readAttribute("day");
if (!day)
day = currentDay;
-
- var hour = sender.hour;
- if (!hour)
- hour = sender.getAttribute("hour");
+ var hour = sender.readAttribute("hour");
var folder = getSelectedFolder();
- var folderID = folder.getAttribute("id");
- var roles = folder.getAttribute("roles");
+ var folderID = folder.readAttribute("id");
+ var roles = folder.readAttribute("roles");
if (roles) {
roles = roles.split(",")
if ($(roles).indexOf("PublicModifier") < 0)
params.push("hm=" + hour);
if (params.length > 0)
urlstr += "?" + params.join("&");
-
window.open(urlstr, "", "width=490,height=470,resizable=0");
return false; /* stop following the link */
}
function popupCalendar(node) {
- var nodeId = node.getAttribute("inputId");
+ var nodeId = $(node).readAttribute("inputId");
var input = $(nodeId);
input.calendar.popup();
function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
var uids = $('uixselector-participants-uidList');
- log ("contactId: " + contactId);
+
if (contactId)
{
var re = new RegExp("(^|,)" + contactId + "($|,)");
- log ("uids: " + uids);
if (!re.test(uids.value))
{
- log ("no match... realling adding");
if (uids.value.length > 0)
uids.value += ',' + contactId;
else
+ ResourcesURL + '/abcard.gif" />'
+ contactName + '</li>');
}
- else
- log ("match... ignoring contact");
}
return false;
date.setHours(intValue);
intValue = parseInt(window.timeWidgets[which]['minute'].getAttribute("shadow-value"));
date.setMinutes(intValue);
- // window.alert("shadow: " + date);
return date;
}
}
function setEndDate(newEndDate) {
- // window.alert(newEndDate);
this._setDate('end', newEndDate);
}
-function onAdjustEndTime(event) {
- var dateDelta = (window.getStartDate().valueOf()
- - window.getShadowStartDate().valueOf());
- // window.alert(window.getEndDate().valueOf() + ' ' + dateDelta);
- var newEndDate = new Date(window.getEndDate().valueOf() + dateDelta);
- window.setEndDate(newEndDate);
- window.timeWidgets['start']['date'].updateShadowValue();
- window.timeWidgets['start']['hour'].updateShadowValue();
- window.timeWidgets['start']['minute'].updateShadowValue();
+function onAdjustTime(event) {
+ var endDate = window.getEndDate();
+ var startDate = window.getStartDate();
+
+ if ($(this).readAttribute("id").startsWith("start")) {
+ // Start date was changed
+ var delta = window.getShadowStartDate().valueOf() -
+ startDate.valueOf();
+ var newEndDate = new Date(endDate.valueOf() - delta);
+ window.setEndDate(newEndDate);
+
+ window.timeWidgets['end']['date'].updateShadowValue();
+ window.timeWidgets['end']['hour'].updateShadowValue();
+ window.timeWidgets['end']['minute'].updateShadowValue();
+ window.timeWidgets['start']['date'].updateShadowValue();
+ window.timeWidgets['start']['hour'].updateShadowValue();
+ window.timeWidgets['start']['minute'].updateShadowValue();
+ }
+ else {
+ // End date was changed
+ var delta = endDate.valueOf() - startDate.valueOf();
+ if (delta < 0) {
+ alert(labels.validate_endbeforestart);
+ var oldEndDate = window.getShadowEndDate();
+ window.setEndDate(oldEndDate);
+
+ window.timeWidgets['end']['date'].updateShadowValue();
+ window.timeWidgets['end']['hour'].updateShadowValue();
+ window.timeWidgets['end']['minute'].updateShadowValue();
+ }
+ }
}
function onAllDayChanged(event) {
this.timeWidgets = widgets;
Event.observe(widgets['start']['date'], "change",
- this.onAdjustEndTime, false);
+ this.onAdjustTime, false);
Event.observe(widgets['start']['hour'], "change",
- this.onAdjustEndTime, false);
+ this.onAdjustTime, false);
Event.observe(widgets['start']['minute'], "change",
- this.onAdjustEndTime, false);
+ this.onAdjustTime, false);
+
+ Event.observe(widgets['end']['date'], "change",
+ this.onAdjustTime, false);
+ Event.observe(widgets['end']['hour'], "change",
+ this.onAdjustTime, false);
+ Event.observe(widgets['end']['minute'], "change",
+ this.onAdjustTime, false);
var allDayLabel = $("allDay");
var input = $(allDayLabel).childNodesWithTag("input")[0];
icon += 'calendar-folder-16x16.png';
var folderId = userInfos[0] + ":" + folderInfos[1];
var name = folderInfos[0]; // name has the format "Folername (Firstname Lastname <email>)"
- var pos = name.indexOf(' (')
- if (pos !== -1)
+ var pos = name.lastIndexOf(' (')
+ if (pos != -1)
name = name.substring(0, pos); // strip the part with fullname and email
tree.add(parent + i, parent, name, 0, '#', folderId,
folderInfos[2] + '-folder', '', '', icon, icon);
}
if (signatureLength > 0) {
var length = this.getValue().length - signatureLength - 1;
- this.selectText(length, length);
+ this.setCaretTo(length);
}
Event.stopObserving(this, "focus", onTextFocus);
}
var sigLimit = textContent.lastIndexOf("--");
if (sigLimit > -1)
signatureLength = (textContent.length - sigLimit);
+ textarea.scrollTop = textarea.scrollHeight;
textarea.observe("focus", onTextFocus);
- textarea.scrollTop = textarea.offsetHeight;
onWindowResize(null);
Event.observe(window, "resize", onWindowResize);
? obj_caller.gen_tsmp(dt_datetime)
: obj_caller.gen_date(dt_datetime)
);
- if (document.initEvent) {
- var onChangeEvent = document.createEvent("Events");
- onChangeEvent.initEvent("mousedown", false, true);
- obj_caller.target.dispatchEvent(onChangeEvent);
- }
- else if (document.createEvent) {
- var onChangeEvent = document.createEvent("UIEvents");
- onChangeEvent.initEvent("mousedown", false, true);
- obj_caller.target.dispatchEvent(onChangeEvent);
- }
- else {
- // Francis: add support for IE
- obj_caller.target.fireEvent("onmousedown");
- }
+ var adjustTime = window.opener.onAdjustTime.bind(obj_caller.target);
+ adjustTime();
}
if (b_close) window.close();
else obj_caller.popup(dt_datetime.valueOf());