diff --git a/ChangeLog b/ChangeLog index 51e4634ad..627c9024a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-07-09 Francis Lachapelle + + * UI/WebServerResources/UIxAttendeesEditor.js (onContactKeydown): + reset left scroll uppon autocompletion (fix for IE). + (onAttendeeResultClick): idem. + (prepareAttendees): add the organizer at the top of the attendees list. + + * UI/Scheduler/UIxComponentEditor.m (-jsonOrganizer): new method + that returns a JSON representation of a dictionary describing the + organizer of the event. + 2010-07-07 Francis Lachapelle * UI/WebServerResources/HTMLInputElement.js: renamed valueAsDate diff --git a/UI/Scheduler/UIxAttendeesEditor.m b/UI/Scheduler/UIxAttendeesEditor.m index 8e679f967..51be1437e 100644 --- a/UI/Scheduler/UIxAttendeesEditor.m +++ b/UI/Scheduler/UIxAttendeesEditor.m @@ -25,6 +25,8 @@ #import #import +#import + #import #import "UIxAttendeesEditor.h" diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index 25348ead5..3057feb67 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -1,6 +1,6 @@ /* UIxComponentEditor.m - this file is part of SOGo * - * Copyright (C) 2006-2009 Inverse inc. + * Copyright (C) 2006-2010 Inverse inc. * * Author: Wolfgang Sourdeau * @@ -812,6 +812,65 @@ iRANGE(2); return [jsonAttendees jsonRepresentation]; } +- (NSString *) jsonOrganizer +{ + NSMutableDictionary *jsonOrganizer; + NSDictionary *ownerIdentity; + NSString *uid, *name, *email, *partstat, *role; + SOGoUserManager *um; + SOGoCalendarComponent *co; + SOGoUser *ownerUser; + + jsonOrganizer = [NSMutableDictionary dictionary]; + email = [organizer rfc822Email]; + role = nil; + partstat = nil; + + if ([email length]) + { + um = [SOGoUserManager sharedUserManager]; + + name = [organizer cn]; + uid = [um getUIDForEmail: email]; + + partstat = [[organizer partStat] lowercaseString]; + role = [[organizer role] lowercaseString]; + } + else + { + // No organizer defined in vEvent + co = [self clientObject]; + uid = [[co container] ownerInContext: context]; + ownerUser = [SOGoUser userWithLogin: uid roles: nil]; + ownerIdentity = [ownerUser defaultIdentity]; + + name = [ownerIdentity objectForKey: @"fullName"]; + email = [ownerIdentity objectForKey: @"email"]; + } + + if (uid != nil) + [jsonOrganizer setObject: uid + forKey: @"uid"]; + + [jsonOrganizer setObject: name + forKey: @"name"]; + + [jsonOrganizer setObject: email + forKey: @"email"]; + + if (partstat == nil || ![partstat length]) + partstat = @"accepted"; + [jsonOrganizer setObject: partstat + forKey: @"partstat"]; + + if (role == nil || ![role length]) + role = @"chair"; + [jsonOrganizer setObject: role + forKey: @"role"]; + + return [jsonOrganizer jsonRepresentation]; +} + - (void) setLocation: (NSString *) _value { ASSIGN (location, _value); diff --git a/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox b/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox index cfbc59fa4..253a581bb 100644 --- a/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox +++ b/UI/Templates/SchedulerUI/UIxAttendeesEditor.wox @@ -12,7 +12,7 @@ const:popup="YES" const:jsFiles="skycalendar.js">
-
    +
    diff --git a/UI/WebServerResources/UIxAppointmentEditor.js b/UI/WebServerResources/UIxAppointmentEditor.js index f8f979b28..b1700d83b 100644 --- a/UI/WebServerResources/UIxAppointmentEditor.js +++ b/UI/WebServerResources/UIxAppointmentEditor.js @@ -164,7 +164,7 @@ function addContact(tag, fullContactName, contactId, contactName, contactEmail) function saveEvent(sender) { if (validateAptEditor()) { - document.forms['editform'].attendees.value = $(attendees).toJSON(); + document.forms['editform'].attendees.value = Object.toJSON($(attendees)); document.forms['editform'].submit(); } @@ -324,7 +324,7 @@ function refreshAttendees(newAttendees) { if (!attendeesHref) return refreshAttendeesRO(); - + if (attendeesMenu) attendeesMenu = $("attendeesMenu").down("ul"); @@ -337,12 +337,12 @@ function refreshAttendees(newAttendees) { if (menuItems && attendeesMenu) for (var i = 0; i < menuItems.length; i++) attendeesMenu.removeChild(menuItems[i]); - - if (newAttendees) { + + if (newAttendees) + // Update global variable attendees = $H(newAttendees.evalJSON()); - } - if (attendees.keys().length > 0) { + if (attendees.keys().length > 0) { // Update attendees link and show label var names = new Array(); attendees.values().each(function(attendee) { diff --git a/UI/WebServerResources/UIxAttendeesEditor.css b/UI/WebServerResources/UIxAttendeesEditor.css index 46871e08f..1aa954e80 100644 --- a/UI/WebServerResources/UIxAttendeesEditor.css +++ b/UI/WebServerResources/UIxAttendeesEditor.css @@ -243,13 +243,15 @@ TABLE#freeBusyData TD.noFreeBusy { margin: 0px; text-align: left; } +SPAN#freeBusyViewOptions +{ float: left; } + +#freeBusyViewButtons SELECT +{ width: 50px; } + SPAN.hidden { display: none; } -#freeBusyViewButtons > DIV.buttons -{ margin: 0px; - margin-top: 4px; } - DIV#freeBusyReplicas { position: absolute; top: 2px; diff --git a/UI/WebServerResources/UIxAttendeesEditor.js b/UI/WebServerResources/UIxAttendeesEditor.js index da14f2334..7138339ba 100644 --- a/UI/WebServerResources/UIxAttendeesEditor.js +++ b/UI/WebServerResources/UIxAttendeesEditor.js @@ -106,8 +106,10 @@ function onContactKeydown(event) { this.focussed = true; return; } - if (event.keyCode == 9 || event.keyCode == 13) { // Tab + if (event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN) { preventDefault(event); + this.scrollLeft = 0; + $(this).up('DIV').scrollLeft = 0; if (this.confirmedValue) this.value = this.confirmedValue; this.hasfreebusy = false; @@ -128,7 +130,7 @@ function onContactKeydown(event) { } } else if (event.keyCode == 0 - || event.keyCode == 8 // Backspace + || event.keyCode == Event.KEY_BACKSPACE || event.keyCode == 32 // Space || event.keyCode > 47) { this.modified = true; @@ -349,6 +351,8 @@ function onAttendeeResultClick(event) { input.confirmedValue = input.value = this.address; initializeAttendeeRole(input); checkAttendee(input); + this.scrollLeft = 0; + $(this).up('DIV').scrollLeft = 0; this.parentNode.input = null; } @@ -440,7 +444,7 @@ function rotateAttendeeStatus(row) { idx++; } row.setAttribute(attributeName, values[idx]); - if (Prototype.Browser.IE) { + if (!Prototype.Browser.Gecko) { /* This hack enables a refresh of the row element right after the click. Otherwise, this occurs only when leaving the element with them mouse cursor. */ @@ -1289,7 +1293,7 @@ function onEditorOkClick(event) { var inputs = $("freeBusy").getElementsByTagName("input"); for (var i = 0; i < inputs.length - 1; i++) { var input = inputs[i]; - if (input.uid) { + if (!input.disabled && input.uid) { uids.push(input.uid); } } @@ -1321,6 +1325,8 @@ function _confirmEditorOkClick() { var newAttendees = new Hash(); var inputs = $("freeBusy").getElementsByTagName("input"); for (var i = 0; i < inputs.length - 1; i++) { + if (inputs[i].disabled) + continue; var row = $(inputs[i]).up("tr"); var name = extractEmailName(inputs[i].value); var email = extractEmailAddress(inputs[i].value); @@ -1348,7 +1354,7 @@ function _confirmEditorOkClick() { attendee["role"] = role; newAttendees.set(email, attendee); } - window.opener.refreshAttendees(newAttendees.toJSON()); + window.opener.refreshAttendees(Object.toJSON(newAttendees)); updateParentDateFields("startTime", "startTime"); updateParentDateFields("endTime", "endTime"); @@ -1481,16 +1487,48 @@ function prepareTableRows() { function prepareAttendees() { var tableAttendees = $("freeBusyAttendees"); var tableData = $("freeBusyData"); + var organizer = window.opener.organizer; var attendees = window.opener.attendees; var attendeesKeys = (attendees ? attendees.keys() : null); - if (attendeesKeys && attendeesKeys.length > 0) { - var tbodyAttendees = tableAttendees.tBodies[0]; - var modelAttendee = tbodyAttendees.rows[tbodyAttendees.rows.length - 1]; - var newAttendeeRow = tbodyAttendees.rows[tbodyAttendees.rows.length - 2]; - var tbodyData = tableData.tBodies[0]; - var modelData = tbodyData.rows[tbodyData.rows.length - 1]; - var newDataRow = tbodyData.rows[tbodyData.rows.length - 2]; + var tbodyAttendees = tableAttendees.tBodies[0]; + var modelAttendee = tbodyAttendees.rows[tbodyAttendees.rows.length - 1]; + var newAttendeeRow = tbodyAttendees.rows[tbodyAttendees.rows.length - 2]; + + var tbodyData = tableData.tBodies[0]; + var modelData = tbodyData.rows[tbodyData.rows.length - 1]; + var newDataRow = tbodyData.rows[tbodyData.rows.length - 2]; + + // Unconditionaly add the organizer + var row = $(modelAttendee.cloneNode(true)); + tbodyAttendees.insertBefore(row, newAttendeeRow); + row.removeClassName("attendeeModel"); + row.setAttribute("partstat", organizer["partstat"]); + row.setAttribute("role", organizer["role"]); + var uid = organizer["uid"]; + row.addClassName("organizer-row"); + row.removeClassName("attendee-row"); + row.isOrganizer = true; + var input = row.down("input"); + var value = organizer["name"]; + if (value) + value += " "; + else + value = ""; + value += "<" + organizer["email"] + ">"; + input.value = value; + input.uid = uid; + //input.cname = organizer["cname"]; + input.setAttribute("name", ""); + input.modified = false; + input.disable(); + + row = $(modelData.cloneNode(true)); + tbodyData.insertBefore(row, newDataRow); + row.removeClassName("dataModel"); + displayFreeBusyForNode(input); + + if (attendeesKeys && attendeesKeys.length > 0) { attendeesKeys.each(function(atKey) { var attendee = attendees.get(atKey); @@ -1524,7 +1562,7 @@ function prepareAttendees() { value = ""; value += "<" + attendee["email"] + ">"; input.value = value; - input.uid = attendee["uid"]; + input.uid = uid; input.cname = attendee["cname"]; input.setAttribute("name", ""); input.modified = false; @@ -1535,7 +1573,7 @@ function prepareAttendees() { row = $(modelData.cloneNode(true)); tbodyData.insertBefore(row, newDataRow); row.removeClassName("dataModel"); - displayFreeBusyForNode(input); + displayFreeBusyForNode(input); }); } else { diff --git a/UI/WebServerResources/UIxMailEditor.js b/UI/WebServerResources/UIxMailEditor.js index b2a160638..790758f75 100644 --- a/UI/WebServerResources/UIxMailEditor.js +++ b/UI/WebServerResources/UIxMailEditor.js @@ -352,7 +352,6 @@ function initMailEditor() { var subjectField = $$("div#subjectRow input").first(); initTabIndex($("addressList"), subjectField, textarea); - //onWindowResize.defer(); var focusField = (mailIsReply ? textarea : $("addr_0")); focusField.focus(); @@ -517,18 +516,18 @@ function onWindowResize(event) { var attachmentsarea = $("attachmentsArea"); var attachmentswidth = 0; + var subjectfield = headerarea.down("div#subjectRow span.headerField"); + var subjectinput = headerarea.down("div#subjectRow input.textField"); if (attachmentsarea.style.display) { // Resize attachments list attachmentswidth = attachmentsarea.getWidth(); fromfield = $(document).getElementsByClassName('headerField', headerarea)[0]; - var height = headerarea.getHeight() - fromfield.getHeight() - 10; + var height = headerarea.getHeight() - fromfield.getHeight() - subjectfield.getHeight() - 10; if (Prototype.Browser.IE) $("attachments").setStyle({ height: (height - 13) + 'px' }); else $("attachments").setStyle({ height: height + 'px' }); } - var subjectfield = headerarea.down("div#subjectRow span.headerField"); - var subjectinput = headerarea.down("div#subjectRow input.textField"); // Resize subject field subjectinput.setStyle({ width: (window.width()