diff --git a/ChangeLog b/ChangeLog index 7b55fd479..2160ff38b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-07-23 Cyril Robert + + * UI/Scheduler/UIxComponentEditor.m (repeatLabel), (ownerIsAttendee), + (delegateIsAttendee), (eventIsReadOnly), (startDateString), (endDateString): + Added for Mantis 78. + 2009-07-23 Wolfgang Sourdeau * SoObjects/Appointments/SOGoAppointmentFolder.m diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index 291b597c3..0c0f10d9e 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -50,6 +50,7 @@ #import #import #import +#import #import #import #import @@ -875,6 +876,18 @@ iRANGE(2); return text; } +- (NSString *) repeatLabel +{ + NSString *rc; + + if ([self repeat]) + rc = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", [self repeat]]]; + else + rc = [self labelForKey: @"repeat_NEVER"]; + + return rc; +} + - (NSArray *) reminderList { return reminderItems; @@ -1929,4 +1942,134 @@ RANGE(2); return toolbarFilename; } + +- (BOOL) ownerIsAttendee: (SOGoUser *) ownerUser + andClientObject: (SOGoContentObject + *) clientObject +{ + BOOL isOrganizer, rc = NO; + + isOrganizer = [component userIsOrganizer: ownerUser]; + if (isOrganizer) + isOrganizer = ![ownerUser hasEmail: [[component organizer] sentBy]]; + + if ([[component attendees] count] + && [component userIsParticipant: ownerUser] + && !isOrganizer + && ![[component tag] isEqualToString: @"VTODO"]) + rc = YES; + + return rc; +} + +- (BOOL) delegateIsAttendee: (SOGoUser *) ownerUser + andClientObject: (SOGoContentObject + *) clientObject +{ + SoSecurityManager *sm; + SOGoUser *currentUser; + BOOL rc = NO; + + currentUser = [context activeUser]; + sm = [SoSecurityManager sharedSecurityManager]; + + if (![sm validatePermission: SOGoCalendarPerm_ModifyComponent + onObject: clientObject + inContext: context]) + rc = [self ownerIsAttendee: ownerUser + andClientObject: clientObject]; + else if (![sm validatePermission: SOGoCalendarPerm_RespondToComponent + onObject: clientObject + inContext: context] + && [[component attendees] count] + && [component userIsParticipant: ownerUser] + && ![component userIsOrganizer: ownerUser]) + rc = YES; + else + rc = YES; + + return rc; +} + +- (BOOL) eventIsReadOnly +{ + SOGoContentObject *clientObject; + SOGoUser *ownerUser; + BOOL rc = NO; + + clientObject = [self clientObject]; + ownerUser = [SOGoUser userWithLogin: [clientObject ownerInContext: context] + roles: nil]; + + if ([ownerUser isEqual: [context activeUser]]) + rc = [self ownerIsAttendee: ownerUser + andClientObject: clientObject]; + else + rc = [self delegateIsAttendee: ownerUser + andClientObject: clientObject]; + + + return rc; +} + +- (NSString *) startDateString +{ + NSCalendarDate *startDate; + NSCalendarDate *firstDate; + NSTimeZone *timeZone; + iCalEvent *master; + signed int daylightOffset; + + startDate = [component startDate]; + daylightOffset = 0; + + if ([component isKindOfClass: [SOGoAppointmentOccurence class]]) + { + master = (iCalEvent*)[[component parent] firstChildWithTag: @"vevent"]; + firstDate = [master startDate]; + timeZone = [[context activeUser] timeZone]; + + if ([timeZone isDaylightSavingTimeForDate: startDate] != [timeZone isDaylightSavingTimeForDate: firstDate]) + { + daylightOffset = (signed int)[timeZone secondsFromGMTForDate: firstDate] + - (signed int)[timeZone secondsFromGMTForDate: startDate]; + startDate = [startDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:daylightOffset]; + } + } + [startDate setTimeZone: [[context activeUser] timeZone]]; + + return [startDate description]; +} + +- (NSString *) endDateString +{ + NSCalendarDate *startDate, *endDate; + NSCalendarDate *firstDate; + NSTimeZone *timeZone; + iCalEvent *master; + signed int daylightOffset; + + startDate = [component startDate]; + daylightOffset = 0; + + if ([component isKindOfClass: [SOGoAppointmentOccurence class]]) + { + master = (iCalEvent*)[[component parent] firstChildWithTag: @"vevent"]; + firstDate = [master startDate]; + timeZone = [[context activeUser] timeZone]; + + if ([timeZone isDaylightSavingTimeForDate: startDate] != [timeZone isDaylightSavingTimeForDate: firstDate]) + { + daylightOffset = (signed int)[timeZone secondsFromGMTForDate: firstDate] + - (signed int)[timeZone secondsFromGMTForDate: startDate]; + startDate = [startDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:daylightOffset]; + } + } + + endDate = [[component endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:daylightOffset]; + [endDate setTimeZone: [[context activeUser] timeZone]]; + + return [endDate description]; +} + @end diff --git a/UI/Templates/SchedulerUI/UIxComponentEditor.wox b/UI/Templates/SchedulerUI/UIxComponentEditor.wox index 22a16eb71..8692dd7ef 100644 --- a/UI/Templates/SchedulerUI/UIxComponentEditor.wox +++ b/UI/Templates/SchedulerUI/UIxComponentEditor.wox @@ -19,6 +19,7 @@ var activeComponent = ''; + + + +
+
+ + + + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 238b4c537..7512b1745 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -1224,12 +1224,13 @@ function calendarDisplayCallback(http) { 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) + if (node) { + node.calendar = new skycalendar(node); + node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html"); + var dateFormat = node.getAttribute("dateFormat"); + if (dateFormat) node.calendar.setDateFormat(dateFormat); + } } } diff --git a/UI/WebServerResources/UIxAppointmentEditor.js b/UI/WebServerResources/UIxAppointmentEditor.js index 407f0d30d..d7431327b 100644 --- a/UI/WebServerResources/UIxAppointmentEditor.js +++ b/UI/WebServerResources/UIxAppointmentEditor.js @@ -309,21 +309,27 @@ function onAllDayChanged(event) { function initTimeWidgets(widgets) { this.timeWidgets = widgets; - widgets['start']['date'].observe("change", this.onAdjustTime, false); - widgets['start']['hour'].observe("change", this.onAdjustTime, false); - widgets['start']['minute'].observe("change", this.onAdjustTime, false); + if (widgets['start']['date']) { + widgets['start']['date'].observe("change", this.onAdjustTime, false); + widgets['start']['hour'].observe("change", this.onAdjustTime, false); + widgets['start']['minute'].observe("change", this.onAdjustTime, false); + } - widgets['end']['date'].observe("change", this.onAdjustTime, false); - widgets['end']['hour'].observe("change", this.onAdjustTime, false); - widgets['end']['minute'].observe("change", this.onAdjustTime, false); + if (widgets['end']['date']) { + widgets['end']['date'].observe("change", this.onAdjustTime, false); + widgets['end']['hour'].observe("change", this.onAdjustTime, false); + widgets['end']['minute'].observe("change", this.onAdjustTime, false); + } var allDayLabel = $("allDay"); - var input = $(allDayLabel).childNodesWithTag("input")[0]; - input.observe("change", onAllDayChanged.bindAsEventListener(input)); - if (input.checked) { - for (var type in widgets) { - widgets[type]['hour'].disabled = true; - widgets[type]['minute'].disabled = true; + if (allDayLabel) { + var input = $(allDayLabel).childNodesWithTag("input")[0]; + input.observe("change", onAllDayChanged.bindAsEventListener(input)); + if (input.checked) { + for (var type in widgets) { + widgets[type]['hour'].disabled = true; + widgets[type]['minute'].disabled = true; + } } } } @@ -333,8 +339,11 @@ function refreshAttendees() { var attendeesNames = $("attendeesNames").value; var attendeesEmails = $("attendeesEmails").value.split(","); var attendeesStates = $("attendeesStates").value.split(","); - var attendeesMenu = $("attendeesMenu").down("ul"); var attendeesHref = $("attendeesHref"); + var attendeesMenu = null; + + if ($("attendeesMenu")) + attendeesMenu = $("attendeesMenu").down("ul"); // Remove link of attendees for (var i = 0; i < attendeesHref.childNodes.length; i++) @@ -342,7 +351,7 @@ function refreshAttendees() { // Remove attendees from menu var menuItems = $$("DIV#attendeesMenu LI.attendee"); - if (menuItems) + if (menuItems && attendeesMenu) for (var i = 0; i < menuItems.length; i++) attendeesMenu.removeChild(menuItems[i]); @@ -355,7 +364,8 @@ function refreshAttendees() { attendeesNames = attendeesNames.split(","); for (var i = 0; i < attendeesEmails.length; i++) { var node = document.createElement("li"); - attendeesMenu.appendChild(node); + if (attendeesMenu) + attendeesMenu.appendChild(node); $(node).writeAttribute("email", attendeesEmails[i]); $(node).addClassName("attendee"); $(node).addClassName(attendeesStates[i]); @@ -374,7 +384,8 @@ function initializeAttendeesHref() { var attendeesLabel = $("attendeesLabel"); var attendeesNames = $("attendeesNames"); - attendeesHref.observe("click", onAttendeesHrefClick, false); + if (!attendeesHref.hasClassName ("nomenu")) + attendeesHref.observe("click", onAttendeesHrefClick, false); refreshAttendees(); } @@ -399,7 +410,8 @@ function getMenus() { null); var attendeesMenu = $('attendeesMenu'); - attendeesMenu.prepareVisibility = onAttendeesMenuPrepareVisibility; + if (attendeesMenu) + attendeesMenu.prepareVisibility = onAttendeesMenuPrepareVisibility; return { "attendeesMenu": AppointmentEditor.attendeesMenu }; } diff --git a/UI/WebServerResources/UIxComponentEditor.js b/UI/WebServerResources/UIxComponentEditor.js index 49cf7d143..4c60e8e17 100644 --- a/UI/WebServerResources/UIxComponentEditor.js +++ b/UI/WebServerResources/UIxComponentEditor.js @@ -100,42 +100,53 @@ function initializeDocumentHref() { } var changeUrlButton = $("changeAttachButton"); - changeUrlButton.observe("click", onPopupAttachWindow, false); + if (changeUrlButton) + changeUrlButton.observe("click", onPopupAttachWindow, false); } function initializePrivacyMenu() { - var privacy = $("privacy").value.toUpperCase(); - var privacyMenu = $("privacy-menu").childNodesWithTag("ul")[0]; - var menuEntries = $(privacyMenu).childNodesWithTag("li"); - var chosenNode; - if (privacy == "CONFIDENTIAL") - chosenNode = menuEntries[1]; - else if (privacy == "PRIVATE") - chosenNode = menuEntries[2]; - else - chosenNode = menuEntries[0]; - privacyMenu.chosenNode = chosenNode; - $(chosenNode).addClassName("_chosen"); + if ($("privacy-menu")) { + var privacy = $("privacy").value.toUpperCase(); + var privacyMenu = $("privacy-menu").childNodesWithTag("ul")[0]; + var menuEntries = $(privacyMenu).childNodesWithTag("li"); + var chosenNode; + if (privacy == "CONFIDENTIAL") + chosenNode = menuEntries[1]; + else if (privacy == "PRIVATE") + chosenNode = menuEntries[2]; + else + chosenNode = menuEntries[0]; + privacyMenu.chosenNode = chosenNode; + $(chosenNode).addClassName("_chosen"); + } } function onComponentEditorLoad(event) { initializeDocumentHref(); initializePrivacyMenu(); var list = $("calendarList"); - list.observe("change", onChangeCalendar, false); - list.fire("mousedown"); + if (list) { + list.observe("change", onChangeCalendar, false); + list.fire("mousedown"); + } - var menuItems = $("itemPrivacyList").childNodesWithTag("li"); - for (var i = 0; i < menuItems.length; i++) - menuItems[i].observe("mousedown", - onMenuSetClassification.bindAsEventListener(menuItems[i]), - false); + if ($("itemPrivacyList")) { + var menuItems = $("itemPrivacyList").childNodesWithTag("li"); + for (var i = 0; i < menuItems.length; i++) + menuItems[i].observe("mousedown", + onMenuSetClassification.bindAsEventListener(menuItems[i]), + false); + } $("repeatHref").observe("click", onPopupRecurrenceWindow); - $("repeatList").observe("change", onPopupRecurrenceWindow); - $("reminderHref").observe("click", onPopupReminderWindow); - $("reminderList").observe("change", onPopupReminderWindow); - $("summary").observe("keyup", onSummaryChange); + if ($("repeatList")) + $("repeatList").observe("change", onPopupRecurrenceWindow); + if ($("reminderHref")) + $("reminderHref").observe("click", onPopupReminderWindow); + if ($("reminderList")) + $("reminderList").observe("change", onPopupReminderWindow); + if ($("summary")) + $("summary").observe("keyup", onSummaryChange); Event.observe(window, "resize", onWindowResize); @@ -144,12 +155,15 @@ function onComponentEditorLoad(event) { onSummaryChange (null); var summary = $("summary"); - summary.focus(); - summary.selectText(0, summary.value.length); + if (summary) { + summary.focus(); + summary.selectText(0, summary.value.length); + } } function onSummaryChange (e) { - document.title = $("summary").value; + if ($("summary")) + document.title = $("summary").value; } function onWindowResize(event) { @@ -161,10 +175,15 @@ function onWindowResize(event) { height = window.height() - comment.cumulativeOffset().top - offset; - if (document.visible()) - height -= $("changeAttachButton").getHeight(); + if (document.visible()) { + if ($("changeAttachButton")) + height -= $("changeAttachButton").getHeight(); + else + height -= $("documentHref").getHeight(); + } - area.setStyle({ height: (height - offset*2) + "px" }); + if (area) + area.setStyle({ height: (height - offset*2) + "px" }); comment.setStyle({ height: (height - offset) + "px" }); return true; @@ -176,7 +195,7 @@ function onPopupRecurrenceWindow(event) { var repeatHref = $("repeatHref"); - if ($("repeatList").value == 7) { + if ($("repeatList") && $("repeatList").value == 7) { repeatHref.show(); if (event) window.open(ApplicationBaseURL + "editRecurrence", null, @@ -194,13 +213,13 @@ function onPopupReminderWindow(event) { var reminderHref = $("reminderHref"); - if ($("reminderList").value == 15) { + if ($("reminderList") && $("reminderList").value == 15) { reminderHref.show(); if (event) window.open(ApplicationBaseURL + "editReminder", null, "width=250,height=150"); } - else + else if (reminderHref) reminderHref.hide(); return false;