var eventListFilter = 'view_today'; var taskListFilter = 'view_today'; var listOfSelection = null; var selectedCalendarCell = null; var showCompletedTasks; var currentDay = ''; var selectedDayNumber = -1; var selectedDayDate = ''; var cachedDateSelectors = []; var contactSelectorAction = 'calendars-contacts'; var eventsToDelete = []; var calendarsOfEventsToDelete = []; var usersRightsWindowHeight = 215; var usersRightsWindowWidth = 502; var calendarEvents = null; var preventAutoScroll = false; var userStates = [ "needs-action", "accepted", "declined", "tentative", "delegated" ]; var calendarHeaderAdjusted = false; var categoriesStyles = new Hash(); var categoriesStyleSheet = null; var clipboard = null; var eventsToCopy = []; // This should probably go in the generic.js function printView() { var flag = false; var calendarsList = $("calendarList").children; for (var i = 0; i < calendarsList.length; i++) { if (calendarsList[i].down("input").checked) { flag = true; break; } } if (flag) window.open("printView","","width=660,height=470"); else showAlertDialog("Please select at least one calendar"); return false; } function newEvent(type, day, hour, duration) { var folder = null; /* if (currentView == "multicolumndayview") { Need to find where the click register is saved }*/ if (UserDefaults['SOGoDefaultCalendar'] == 'personal') folder = $("calendarList").down("li"); else if (UserDefaults['SOGoDefaultCalendar'] == 'first') { var list = $("calendarList"); var inputs = list.select("input"); for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; if (input.checked) { folder = input.up(); break; } } if (!folder) folder = list.down("li"); } else folder = getSelectedFolder(); var folderID = folder.readAttribute("id"); var urlstr = ApplicationBaseURL + folderID + "/new" + type; var params = []; if (!day) day = currentDay; params.push("day=" + day); if (hour) params.push("hm=" + hour); if (duration) params.push("duration=" + duration); if (params.length > 0) urlstr += "?" + params.join("&"); window.open(urlstr, "", "width=490,height=470,resizable=0"); return false; /* stop following the link */ } function newEventFromWidget(sender, type) { var day = $(sender).readAttribute("day"); var hour = sender.readAttribute("hour"); newEvent.delay(0.1, type, day, hour); } function minutesToHM(minutes) { var hours = Math.floor(minutes / 60); if (hours < 10) hours = "0" + hours; var mins = minutes % 60; if (mins < 10) mins = "0" + mins; return "" + hours + mins; } function newEventFromDragging(controller, day, coordinates) { var startHm; if (controller.eventType == "multiday") startHm = minutesToHM(coordinates.start * 15); else startHm = "allday"; var lengthHm = minutesToHM(coordinates.duration * 15); newEvent("event", day, startHm, lengthHm); } function updateEventFromDragging(controller, eventCells, eventDelta) { if (eventDelta.dayNumber || eventDelta.start || eventDelta.duration) { var params = ("days=" + eventDelta.dayNumber + "&start=" + eventDelta.start * 15 + "&duration=" + eventDelta.duration * 15); // log("eventCells: " + eventCells.length); var eventCell = eventCells[0]; // log(" time: " + eventCell.recurrenceTime); // log(" exception: " + eventCell.isException); if (eventCell.recurrenceTime && !eventCell.isException) _editRecurrenceDialog(eventCell, "confirmAdjustment", params); else { var urlstr = (ApplicationBaseURL + "/" + eventCell.calendar + "/" + eventCell.cname); if (eventCell.recurrenceTime) urlstr += "/occurence" + eventCell.recurrenceTime; urlstr += ("/adjust?" + params); // log(" urlstr: " + urlstr); triggerAjaxRequest(urlstr, updateEventFromDraggingCallback); } } } function performEventAdjustment(folder, event, recurrence, params) { var urlstr = ApplicationBaseURL + "/" + folder + "/" + event; if (recurrence) urlstr += "/" + recurrence; urlstr += "/adjust" + generateQueryString(params); triggerAjaxRequest(urlstr, updateEventFromDraggingCallback); } function updateEventFromDraggingCallback(http) { if (http.readyState == 4) { if (isHttpStatus204(http.status)) { refreshEventsAndDisplay(); } else { var response = http.responseText.evalJSON(true); showAlertDialog(response['message']); } } } function getSelectedFolder() { var folder; var list = $("calendarList"); var nodes = list.getSelectedRows(); if (nodes.length > 0) folder = nodes[0]; else folder = list.down("li"); // personal calendar return folder; } function onMenuNewEventClick(event) { var target = document.menuTarget; if (target) { if (/(minutes\d{2}|dayHeader)/.test(target.className)) target = target.parentNode; newEventFromWidget(target, "event"); } else { newEvent('event'); } } function onMenuNewTaskClick(event) { var target = document.menuTarget; if (target) { if (/(minutes\d{2}|dayHeader)/.test(target.className)) target = target.parentNode; newEventFromWidget(target, "task"); } else { newEvent('task'); } } function _editEventId(id, calendar, recurrence) { var targetname = "SOGo_edit_" + id; var urlstr = ApplicationBaseURL + "/" + calendar + "/" + id; if (recurrence) { urlstr += "/" + recurrence; targetname += recurrence; } urlstr += "/edit"; var win = window.open(urlstr, "_blank", "width=490,height=470,resizable=0"); if (win) win.focus(); } function editEvent() { if (listOfSelection) { var nodes = listOfSelection.getSelectedRows(); if (nodes.length == 0) { showAlertDialog(_("Please select an event or a task.")); return false; } for (var i = 0; i < nodes.length; i++) _editEventId.delay(0.1, nodes[i].cname, nodes[i].calendar); } else if (selectedCalendarCell) { if (selectedCalendarCell[0].recurrenceTime && !selectedCalendarCell[0].isException) _editRecurrenceDialog.delay(0.1, selectedCalendarCell[0], "confirmEditing"); else _editEventId.delay(0.1, selectedCalendarCell[0].cname, selectedCalendarCell[0].calendar); } else { showAlertDialog(_("Please select an event or a task.")); } return false; /* stop following the link */ } function _batchDeleteEvents() { // Delete the events of the next calendar var calendar = calendarsOfEventsToDelete.shift(); var events = eventsToDelete.shift(); var urlstr = (ApplicationBaseURL + "/" + calendar + "/batchDelete?ids=" + events.join(',')); document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr, deleteEventCallback, { calendar: calendar, events: events }); } function deleteEvent() { var label = ""; var events = []; if (listOfSelection) { var nodes = listOfSelection.getSelectedRows(); if (nodes.length > 0) { if (listOfSelection.parentNode == $("tasksList")) label = _("taskDeleteConfirmation"); else label = _("eventDeleteConfirmation"); if (nodes.length == 1 && nodes[0].recurrenceTime) { if (nodes[0].erasable) _editRecurrenceDialog(nodes[0], "confirmDeletion"); else showAlertDialog(_("You don't have the required privileges to perform the operation.")); } else { var canDelete; var sortedNodes = []; var calendars = []; for (var i = 0; i < nodes.length; i++) { canDelete = nodes[i].erasable; if (canDelete) { var calendar = nodes[i].calendar; var cname = nodes[i].cname; if (nodes[i].recurrenceTime) { cname += '/occurence' + nodes[i].recurrenceTime; } if (!sortedNodes[calendar]) { sortedNodes[calendar] = []; calendars.push(calendar); } if (sortedNodes[calendar].indexOf(cname) < 0) { // Build list item element for confirmation dialog var itemElement = new Element('li'); var colorBox = new Element('div', {'class': 'colorBox calendarFolder' + nodes[i].calendar}); var content = ''; if (nodes[i].tagName == 'TR') { var cell = nodes[i].down('td span'); content = cell.allTextContent(); // extract the first column only } else { content = nodes[i].allTextContent(); } itemElement.appendChild(colorBox); itemElement.appendChild(new Element('span').update(content.escapeHTML())); if (nodes[i].startDate) { var startDate = new Date(nodes[i].startDate*1000); var dateElement = new Element('div', {'class': 'muted'}); var date; if (typeof nodes[i].hour == 'undefined') date = startDate.toLocaleDateString(localeCode); else date = startDate.toLocaleString(localeCode); dateElement.update(date); itemElement.appendChild(dateElement); } events.push(itemElement); sortedNodes[calendar].push(cname); } } } // Update global arrays for (i = 0; i < calendars.length; i++) { calendarsOfEventsToDelete.push(calendars[i]); eventsToDelete.push(sortedNodes[calendars[i]]); } if (i == 0) showAlertDialog(_("You don't have the required privileges to perform the operation.")); } } else showAlertDialog(_("Please select an event or a task.")); } else if (selectedCalendarCell) { if (selectedCalendarCell.length == 1 && selectedCalendarCell[0].recurrenceTime) { if (selectedCalendarCell[0].erasable) _editRecurrenceDialog(selectedCalendarCell[0], "confirmDeletion"); else showAlertDialog(_("You don't have the required privileges to perform the operation.")); } else { var canDelete; var sortedNodes = []; var calendars = []; var cname; for (var i = 0; i < selectedCalendarCell.length; i++) { canDelete = selectedCalendarCell[i].erasable; if (canDelete) { var calendar = selectedCalendarCell[i].calendar; var cname = selectedCalendarCell[i].cname; if (selectedCalendarCell[i].recurrenceTime) { cname += '/occurence' + selectedCalendarCell[i].recurrenceTime; } if (!sortedNodes[calendar]) { sortedNodes[calendar] = []; calendars.push(calendar); } if (sortedNodes[calendar].indexOf(cname) < 0) { // Build list item element for confirmation dialog var itemElement = new Element('li'); var colorBox = new Element('div', {'class': 'colorBox calendarFolder' + selectedCalendarCell[i].calendar}); var content = ''; var event = $(selectedCalendarCell[i]).down("DIV.text"); for (var j = 0; j < event.childNodes.length; j++) { var node = event.childNodes[j]; if (node.nodeType == Node.TEXT_NODE) { content += node.nodeValue; } } itemElement.appendChild(colorBox); itemElement.appendChild(new Element('span').update(content.escapeHTML())); if (selectedCalendarCell[i].startDate) { var startDate = new Date(selectedCalendarCell[i].startDate*1000); var dateElement = new Element('div', {'class': 'muted'}); var date; if (selectedCalendarCell[i].readAttribute('hour') == 'allday') date = startDate.toLocaleDateString(localeCode); else date = startDate.toLocaleString(localeCode); dateElement.update(date); itemElement.appendChild(dateElement); } events.push(itemElement); sortedNodes[calendar].push(cname); } } } // Update global arrays for (i = 0; i < calendars.length; i++) { calendarsOfEventsToDelete.push(calendars[i]); eventsToDelete.push(sortedNodes[calendars[i]]); } if (i == 0) showAlertDialog(_("You don't have the required privileges to perform the operation.")); } } else showAlertDialog(_("Please select an event or a task.")); if (events.length > 0) { // Show confirmation dialog var p = new Element('p'); p.appendChild(document.createTextNode(label)); var list = new Element('ul'); for (i = 0; i < events.length; i++) { list.appendChild(events[i]); } p.appendChild(list); p.appendChild(document.createTextNode(_("Would you like to continue?"))); showConfirmDialog(_("Warning"), p, deleteEventFromListConfirm, deleteEventCancel); } return false; } function deleteEventFromListConfirm() { if (document.deleteEventAjaxRequest) { document.deleteEventAjaxRequest.aborted = true; document.deleteEventAjaxRequest.abort(); } _batchDeleteEvents(); refreshTasks(); disposeDialog(); } function deleteEventFromViewConfirm() { if (document.deleteEventAjaxRequest) { document.deleteEventAjaxRequest.aborted = true; document.deleteEventAjaxRequest.abort(); } selectedCalendarCell = null; _batchDeleteEvents(); disposeDialog(); } function deleteEventCancel(event) { calendarsOfEventsToDelete = []; eventsToDelete = []; disposeDialog(); } function copyEventToClipboard() { if (listOfSelection) { clipboard = new Array(); var nodes = listOfSelection.getSelectedRows(); for (var i = 0; i < nodes.length; i++) clipboard.push(nodes[i].calendar + "/" + nodes[i].cname); } else if (selectedCalendarCell) { clipboard = new Array(); for (var i = 0; i < selectedCalendarCell.length; i++) clipboard.push(selectedCalendarCell[i].calendar + "/" + selectedCalendarCell[i].cname); } log ("clipboard : " + clipboard.join(", ")); } function copyEventFromClipboard() { if (clipboard && clipboard.length > 0) { var folder = getSelectedFolder(); var folderID = folder.readAttribute("id").substr(1); eventsToCopy = []; for (var i = 0; i < clipboard.length; i++) eventsToCopy[i] = clipboard[i] + "/copy?destination=" + folderID; copyEvents(); } } function copyEventToPersonalCalendar(event) { var calendar = selectedCalendarCell[0].calendar; var cname = selectedCalendarCell[0].cname; eventsToCopy = [calendar + "/" + cname + "/copy"]; copyEvents(); } function copyEvents() { var path = eventsToCopy.shift(); var urlstr = ApplicationBaseURL + "/" + path; log (urlstr); triggerAjaxRequest(urlstr, copyEventCallback); } function copyEventCallback(http) { if (http.readyState == 4) { if (isHttpStatus204(http.status)) { if (eventsToCopy.length) copyEvents(); else refreshEventsAndDisplay(); } else if (parseInt(http.status) == 403) showAlertDialog(_("You don't have the required privileges to perform the operation.")); else if (parseInt(http.status) == 400) showAlertDialog(_("DestinationCalendarError")); else showAlertDialog(_("EventCopyError")); } } function onMenuRawEvent(event) { if (selectedCalendarCell.length != 1) { return; } var calendar = selectedCalendarCell[0].calendar; var cname = selectedCalendarCell[0].cname; var url = ApplicationBaseURL + "/" + calendar + "/" + cname + "/raw"; openGenericWindow.delay(0.1, url); } function modifyEvent(sender, modification, parameters) { var currentLocation = '' + window.location; var arr = currentLocation.split("/"); arr[arr.length-1] = modification; document.modifyEventAjaxRequest = triggerAjaxRequest(arr.join("/"), modifyEventCallback, modification, parameters, { "Content-type": "application/x-www-form-urlencoded" }); return false; } function closeInvitationWindow() { var closeDiv = document.createElement("div"); document.body.appendChild(closeDiv); closeDiv.addClassName("javascriptPopupBackground"); var closePseudoWin = document.createElement("div"); document.body.appendChild(closePseudoWin); closePseudoWin.addClassName("javascriptMessagePseudoTopWindow"); closePseudoWin.style.top = "0px;"; closePseudoWin.style.left = "0px;"; closePseudoWin.style.right = "0px;"; closePseudoWin.appendChild(document.createTextNode(_("closeThisWindowMessage"))); var calLink = document.createElement("a"); closePseudoWin.appendChild(calLink); calLink.href = ApplicationBaseURL; calLink.appendChild(document.createTextNode(_("Calendar").toLowerCase())); } function modifyEventCallback(http) { if (http.readyState == 4) { if (isHttpStatus204(http.status) || http.status == 200) { var mailInvitation = queryParameters["mail-invitation"]; if (mailInvitation && mailInvitation.toLowerCase() == "yes") closeInvitationWindow(); else { window.opener.setTimeout("refreshEventsAndDisplay();", 100); window.setTimeout("window.close();", 100); } } else if (http.status == 403) { var data = http.responseText; var msg; if (data.indexOf("An error occurred during object publishing") > -1) { msg = data.replace(/^(.*\n)*.*
((.*\n)*.*)<\/p>(.*\n)*.*$/, "$2");
} else {
msg = "delegate is a participant";
}
showAlertDialog(_(msg));
}
else {
showAlertDialog(_("eventPartStatModificationError"));
}
document.modifyEventAjaxRequest = null;
}
}
function _deleteCalendarEventBlocks(calendar, cname, occurenceTime) {
// Delete event (or occurence) from the specified calendar
var ownerIsOrganizer = false;
var events = calendarEvents[calendar];
if (events) {
var occurences = events[cname];
if (occurences) {
for (var i = 0; i < occurences.length; i++) {
var nodes = occurences[i].blocks;
for (var j = 0; j < nodes.length; j++) {
var node = nodes[j];
if (occurenceTime == null
|| occurenceTime == node.recurrenceTime) {
ownerIsOrganizer = node.ownerIsOrganizer;
node.parentNode.removeChild(node);
}
}
}
if (ownerIsOrganizer)
// Search for the same event in other calendars (using the cache)
// only if the delete operation is triggered from the organizer's
// calendar.
for (var otherCalendar in calendarEvents) {
if (calendar != otherCalendar) {
occurences = calendarEvents[otherCalendar][cname];
if (occurences) {
for (var i = 0; i < occurences.length; i++) {
var occurence = occurences[i];
if (occurenceTime == null || occurenceTime == occurence[15]) {
var nodes = occurence.blocks;
for (var j = 0; j < nodes.length; j++) {
var node = nodes[j];
if (node.parentNode)
node.parentNode.removeChild(node);
}
}
}
}
}
}
}
}
resizeCalendarHeaderDIV();
}
function _deleteEventFromTables(calendar, cname, occurenceTime) {
var basename = "-" + cname;
if (occurenceTime) {
basename = basename + "-" + occurenceTime;
}
if (calendarEvents[calendar]) {
var occurences = calendarEvents[calendar][cname];
if (occurences) {
var occurence = occurences.first();
var ownerIsOrganizer = occurence[19];
// Delete event from events list
var table = $("eventsList");
var rows = table.tBodies[0].rows;
for (var j = rows.length; j > 0; j--) {
var row = $(rows[j - 1]);
var id = row.getAttribute("id");
var pos = id.indexOf(basename);
if (pos > 0) {
var otherCalendar = id.substr(0, pos);
occurences = calendarEvents[otherCalendar][cname];
if (occurences) {
for (var k = 0; k < occurences.length; k++) {
var occurence = occurences[k];
if (calendar == otherCalendar || ownerIsOrganizer) {
// This is the specified event or the same event in another
// calendar. In this case, remove it only if the delete
// operation is triggered from the organizer's calendar.
if (occurenceTime == null || occurenceTime == occurence[15]) {
row.parentNode.removeChild(row);
break;
}
}
}
}
}
}
}
}
// Delete task from tasks list
var row = $(calendar + basename);
if (row) {
row.parentNode.removeChild(row);
}
}
function _deleteCalendarEventCache(calendar, cname, occurenceTime) {
var ownerIsOrganizer = false;
if (calendarEvents[calendar]) {
var occurences = calendarEvents[calendar][cname];
if (occurences)
ownerIsOrganizer = occurences[0][19];
}
for (var otherCalendar in calendarEvents) {
if (calendarEvents[otherCalendar]) {
var occurences = calendarEvents[otherCalendar][cname];
if (occurences) {
var newOccurences = [];
for (var i = 0; i < occurences.length; i++) {
var occurence = occurences[i];
if (calendar == otherCalendar || ownerIsOrganizer) {
// This is the specified event or the same event in another
// calendar. In this case, remove it only if the delete
// operation is triggered from the organizer's calendar.
if (occurenceTime == null) {
delete calendarEvents[otherCalendar][cname];
}
else if (occurenceTime != occurence[15]) {
// || occurenceTime == occurence[15]) {
newOccurences.push(occurence);
}
}
}
if (occurenceTime)
calendarEvents[otherCalendar][cname] = newOccurences;
}
}
}
}
/**
* This is the Ajax callback function for _batchDeleteEvents.
*/
function deleteEventCallback(http) {
if (http.readyState == 4) {
if (isHttpStatus204(http.status)) {
var isTask = false;
var calendar = http.callbackData.calendar;
var events = http.callbackData.events;
for (var i = 0; i < events.length; i++) {
var cname = /(.+)\/occurence([0-9]+)/.exec(events[i]) || [null, events[i]];
_deleteCalendarEventBlocks(calendar, cname[1], cname[2]);
_deleteEventFromTables(calendar, cname[1], cname[2]);
_deleteCalendarEventCache(calendar, cname[1], cname[2]);
}
if (eventsToDelete.length)
_batchDeleteEvents();
else
document.deleteEventAjaxRequest = null;
}
else if (parseInt(http.status) == 403)
showAlertDialog(_("You don't have the required privileges to perform the operation."));
else
log ("deleteEventCallback Ajax error (" + http.status + ")");
}
}
function getEventById(cname, owner) {
var event = null;
if (calendarEvents) {
if (!owner)
owner = UserLogin;
var userEvents = calendarEvents[owner];
if (userEvents)
event = userEvents[cname];
}
return event;
}
function _editRecurrenceDialog(eventCell, method, params) {
var targetname = "SOGo_edit_" + eventCell.cname + eventCell.recurrenceTime;
var urlstr = (ApplicationBaseURL + "/" + eventCell.calendar + "/" + eventCell.cname
+ "/occurence" + eventCell.recurrenceTime + "/" + method);
if (params && params.length) {
urlstr += "?" + params;
}
var win = window.open(urlstr, "_blank",
"width=490,height=70,resizable=0");
if (win)
win.focus();
}
function onViewEvent(event) {
if (event.detail == 2) return;
var url = ApplicationBaseURL + "/" + this.calendar + "/" + this.cname;
if (typeof this.recurrenceTime != "undefined")
url += "/occurence" + this.recurrenceTime;
url += "/view";
if (document.viewEventAjaxRequest) {
document.viewEventAjaxRequest.aborted = true;
document.viewEventAjaxRequest.abort();
}
document.viewEventAjaxRequest = triggerAjaxRequest(url, onViewEventCallback, this);
}
function onViewEventCallback(http) {
if (http.readyState == 4 && http.status == 200) {
if (http.responseText.length > 0) {
var data = http.responseText.evalJSON(true);
// $H(data).keys().each(function(key) {
// log (key + " = " + data[key]);
// });
var cell = http.callbackData;
var cellPosition = cell.cumulativeOffset();
var cellDimensions = cell.getDimensions();
var div = $("eventDialog");
var divDimensions = div.getDimensions();
var view;
var left;
var top = cellPosition[1] - 5;
if (currentView != "monthview") {
view = $("daysView");
var viewPosition = view.cumulativeOffset();
if (parseInt(data["isAllDay"]) == 0) {
top -= view.scrollTop;
if (viewPosition[1] > top + 2) {
view.stopObserving("scroll", onBodyClickHandler);
view.scrollTop = cell.offsetTop;
top = viewPosition[1];
Event.observe.delay(0.1, view, "scroll", onBodyClickHandler);
}
}
}
else {
top -= cell.up("DIV.day").scrollTop;
}
left = cellPosition[0] + cellDimensions["width"] + 4;
if (left + divDimensions["width"] > window.width()) {
left = cellPosition[0] - divDimensions["width"];
div.removeClassName("left");
div.addClassName("right");
}
else {
div.removeClassName("right");
div.addClassName("left");
}
// Put the event's data in the DIV
div.down("h1").update(data["summary"].replace(/\r?\n/g, "
"));
var paras = div.getElementsByTagName("p");
var para = $(paras[0]);
if (parseInt(data["isAllDay"]) == 0) {
para.down("SPAN").update(data["startTime"] + " - " + data["endTime"]);
para.show();
} else
para.hide();
para = $(paras[1]);
if (data["calendar"].length) {
para.down("SPAN", 1).update(data["calendar"]);
para.show();
} else
para.hide();
para = $(paras[2]);
if (data["location"].length) {
para.down("SPAN", 1).update(data["location"]);
para.show();
} else
para.hide();
para = $(paras[3]);
if (data["created_by"].length) {
para.down("SPAN", 1).update(data["created_by"]);
para.show();
} else
para.hide();
para = $(paras[4]);
if (data["description"].length) {
para.update(data["description"].replace(/\r?\n/g, "
"));
para.show();
} else
para.hide();
div.setStyle({ left: left + "px", top: top + "px" });
div.show();
configureLinks(div);
}
}
else {
log("onViewEventCallback ajax error (" + http.status + "): " + http.url);
}
}
function editDoubleClickedEvent(event) {
if (this.isException && this.recurrenceTime)
_editEventId(this.cname, this.calendar, "occurence" + this.recurrenceTime);
else if (this.recurrenceTime)
_editRecurrenceDialog(this, "confirmEditing");
else
_editEventId(this.cname, this.calendar);
Event.stop(event);
}
function performEventEdition(folder, event, recurrence) {
_editEventId(event, folder, recurrence);
}
function performEventDeletion(folder, event, recurrence) {
if (calendarEvents) {
if (recurrence) {
// Only one recurrence
var occurenceTime = recurrence.substring(9);
var nodes = _eventBlocksMatching(folder, event, occurenceTime);
var urlstr = ApplicationBaseURL + "/" + folder + "/" + event + "/" + recurrence + "/delete";
if (nodes)
document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
performDeleteEventCallback,
{ nodes: nodes,
occurence: occurenceTime });
}
else {
// All recurrences
if (document.deleteEventAjaxRequest) {
document.deleteEventAjaxRequest.aborted = true;
document.deleteEventAjaxRequest.abort();
}
eventsToDelete.push([event]);
calendarsOfEventsToDelete.push(folder);
_batchDeleteEvents();
}
}
}
function performDeleteEventCallback(http) {
if (http.readyState == 4) {
if (isHttpStatus204(http.status)) {
var occurenceTime = http.callbackData.occurence;
var nodes = http.callbackData.nodes;
var cname = nodes[0].cname;
var calendar = nodes[0].calendar;
_deleteCalendarEventBlocks(calendar, cname, occurenceTime);
_deleteEventFromTables(calendar, cname, occurenceTime);
_deleteCalendarEventCache(calendar, cname, occurenceTime);
}
}
}
/* in dateselector */
function onDaySelect(node) {
var day = node.getAttribute('day');
var needRefresh = (eventListFilter == 'view_selectedday'
&& day != currentDay);
var td = $(node).getParentWithTagName("td");
// var table = $(td).getParentWithTagName("table");
// log ("table.selected: " + table.selected);
if (document.selectedDate)
document.selectedDate.deselect();
td.selectElement();
document.selectedDate = td;
changeCalendarDisplay( { "day": day } );
currentDay = day;
selectedDayDate = day;
if (needRefresh)
refreshEvents();
return false;
}
function onDateSelectorGotoMonth(event) {
var day = this.getAttribute("date");
changeDateSelectorDisplay(day, true);
Event.stop(event);
}
function onCalendarGotoDay(node) {
var day = node.getAttribute("date");
var needRefresh = (eventListFilter == 'view_selectedday' && day != currentDay);
changeDateSelectorDisplay(day);
changeCalendarDisplay( { "day": day } );
if (needRefresh)
refreshEvents();
return false;
}
function gotoToday() {
var todayDate = new Date();
selectedDayDate = todayDate.getDayString();
changeDateSelectorDisplay('');
changeCalendarDisplay();
return false;
}
function setDateSelectorContent(content) {
var div = $("dateSelectorView");
div.update(content);
if (currentDay.length > 0)
restoreCurrentDaySelection(div);
initDateSelectorEvents();
}
function dateSelectorCallback(http) {
if (http.readyState == 4
&& http.status == 200) {
document.dateSelectorAjaxRequest = null;
var content = http.responseText;
setDateSelectorContent(content);
cachedDateSelectors[http.callbackData] = content;
}
else
log ("dateSelectorCallback Ajax error");
}
function eventsListCallback(http) {
if (http.readyState == 4
&& http.status == 200) {
var div = $("eventsListView");
document.eventsListAjaxRequest = null;
var table = $("eventsList");
lastClickedRow = -1; // from generic.js
var rows = table.select("TBODY TR");
rows.each(function(e) {
e.remove();
});
if (http.responseText.length > 0) {
var data = http.responseText.evalJSON(true);
for (var i = 0; i < data.length; i++) {
var row = createElement("tr");
table.tBodies[0].appendChild(row);
row.addClassName("eventRow");
var calendar = escape(data[i][1]);
var rTime = data[i][16];
var id = escape(data[i][1] + "-" + data[i][0]);
if (rTime)
id += "-" + escape(rTime);
row.setAttribute("id", id);
row.cname = escape(data[i][0]);
row.calendar = calendar;
if (rTime)
row.recurrenceTime = escape(rTime);
row.isException = data[i][17];
row.editable = data[i][18] || IsSuperUser;
row.erasable = data[i][19] || IsSuperUser;
row.startDate = data[i][5];
var startDate = new Date(data[i][5]*1000);
row.day = startDate.getDayString();
if (!data[i][8])
row.hour = startDate.getHourString(); // event is not all day
row.observe("mousedown", onRowClick);
row.observe("selectstart", listRowMouseDownHandler);
if (data[i][3] != null)
// Status is defined -- event is readable
row.observe("dblclick", editDoubleClickedEvent);
var td = createElement("td");
row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true);
var colorDiv = createElement("div", false, "colorBox calendarFolder" + calendar);
td.appendChild(colorDiv);
colorDiv.update(' ');
var span = createElement("span");
td.appendChild(span);
span.update(data[i][4]); // title
td = createElement("td");
row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true);
td.update(data[i][21]); // start date
td = createElement("td");
row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true);
td.update(data[i][22]); // end date
td = createElement("td");
row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true);
if (data[i][7])
td.update(data[i][7]); // location
td = createElement("td");
row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true);
if (data[i][10])
td.update(data[i][10]); // category
td = createElement("td");
row.appendChild(td);
td.observe("mousedown", listRowMouseDownHandler, true);
td.update(data[i][2]); // calendar
}
if (sorting["event-header"] && sorting["event-header"].length > 0) {
var sortHeader = $(sorting["event-header"]);
if (sortHeader) {
var sortImages = $(table.tHead).select(".sortImage");
$(sortImages).each(function(item) {
item.remove();
});
var sortImage = createElement("img", "messageSortImage", "sortImage");
sortHeader.insertBefore(sortImage, sortHeader.firstChild);
if (sorting["event-ascending"])
sortImage.src = ResourcesURL + "/arrow-up.png";
else
sortImage.src = ResourcesURL + "/arrow-down.png";
}
}
}
}
else
log ("eventsListCallback Ajax error");
}
function activeTasksCallback(http) {
if (http.readyState == 4 && http.status == 200) {
if (http.responseText.length > 0) {
document.activeTasksAjaxRequest = null;
var data = http.responseText.evalJSON(true);
var list = $("calendarList");
var items = list.childNodesWithTag("li");
for (var i = 0; i < items.length; i++) {
var id = items[i].getAttribute("id").substr(1);
var number = data[id];
var input = items[i].childNodesWithTag("input")[0];
var activeTasks = items[i].childNodesWithTag("span")[0];
if (number == "0") {
activeTasks.innerHTML = "";
}
else {
activeTasks.innerHTML = "(" + number + ")";
}
}
}
}
}
function tasksListCallback(http) {
if (http.readyState == 4
&& http.status == 200) {
var div = $("tasksListView");
document.tasksListAjaxRequest = null;
var table = $("tasksList");
lastClickedRow = -1; // from generic.js
var rows = table.select("TBODY TR");
rows.each(function(e) {
e.remove();
});
if (http.responseText.length > 0) {
var data = http.responseText.evalJSON(true);
// [0] Task ID
// [1] Calendar ID
// [2] Calendar name
// [3] Status (0, 1 = completed, 2)
// [4] Title
// [5] Due date (int)
// [6] Classification (0 = public, 1, = private, 2 = confidential)
// [7] Location
// [8] Category
// [9] Editable?
// [10] Erasable?
// [11] Priority (0, 1 = important, 9 = low)
// [12] Status CSS class (duelater, completed, etc)
// (13) Due date (formatted)
for (var i = 0; i < data.length; i++) {
var row = createElement("tr");
table.tBodies[0].appendChild(row);
row.on("dblclick", editDoubleClickedEvent);
var calendar = escape(data[i][1]);
var cname = escape(data[i][0]);
row.setAttribute("id", calendar + "-" + cname);
//listItem.addClassName(data[i][5]); // Classification
row.addClassName(data[i][12]); // status
row.calendar = calendar;
row.cname = cname;
row.erasable = data[i][10] || IsSuperUser;
if (parseInt(data[i][11]) == 1) {
row.addClassName("important");
}
else if (parseInt(data[i][11]) == 9) {
row.addClassName("low");
}
var cell = createElement("td");
row.appendChild(cell);
var input = createElement("input");
input.setAttribute("type", "checkbox");
cell.appendChild(input);
input.setAttribute("value", "1");
if (parseInt(data[i][9]) == 0) // editable?
input.setAttribute("disabled", true);
input.addClassName("checkBox");
if (parseInt(data[i][3]) == 1) // completed?
input.setAttribute("checked", "checked");
input.observe("click", updateTaskStatus, true);
cell = createElement("td");
row.appendChild(cell);
if (data[i][11] != null) {
cell.update(_("prio_" + data[i][11])); // Priority
}
else {
cell.update(""); // Priority
}
cell = createElement("td");
row.appendChild(cell);
var colorDiv = createElement("div", false, "colorBox calendarFolder" + calendar);
cell.appendChild(colorDiv);
colorDiv.update(' ');
var t = new Element ("span");
cell.appendChild(t);
t.update(data[i][4]); // title
cell = createElement("td");
row.appendChild(cell);
if (data[i][13])
cell.update(data[i][13]); // end date
cell = createElement("td");
row.appendChild(cell);
cell.update(data[i][7]); // location
cell = createElement("td");
row.appendChild(cell);
cell.update(data[i][8]); // category
cell = createElement("td");
row.appendChild(cell);
cell.update(data[i][2]); // calendar name
}
table.scrollTop = table.previousScroll;
if (sorting["task-attribute"] && sorting["task-attribute"].length > 0) {
var sortHeader = $(sorting["task-header"]);
if (sortHeader) {
var sortImages = $(table.tHead).select(".sortImage");
$(sortImages).each(function(item) {
item.remove();
});
var sortImage = createElement("img", "messageSortImage", "sortImage");
sortHeader.insertBefore(sortImage, sortHeader.firstChild);
if (sorting["task-ascending"])
sortImage.src = ResourcesURL + "/arrow-up.png";
else
sortImage.src = ResourcesURL + "/arrow-down.png";
}
}
if (http.callbackData) {
var selectedNodesId = http.callbackData;
for (var i = 0; i < selectedNodesId.length; i++) {
// log(selectedNodesId[i] + " (" + i + ") is selected");
var node = $(selectedNodesId[i]);
if (node) {
node.selectElement();
}
}
}
else
log ("tasksListCallback: no data");
}
}
else
log ("tasksListCallback Ajax error");
}
/* in dateselector */
function restoreCurrentDaySelection(div) {
var elements = $(div).select("TD.activeDay SPAN");
if (elements.size()) {
var day = elements[0].readAttribute('day');
if (day.substr(0, 6) == currentDay.substr(0, 6)) {
for (var i = 0; i < elements.length; i++) {
day = elements[i].readAttribute('day');
if (day && day == currentDay) {
var td = $(elements[i]).getParentWithTagName("td");
if (document.selectedDate)
document.selectedDate.deselect();
$(td).selectElement();
document.selectedDate = td;
}
}
}
}
}
function loadPreviousView(event) {
onCalendarGotoDay($("leftNavigationArrow"));
}
function loadNextView(event) {
onCalendarGotoDay($("rightNavigationArrow"));
}
function changeDateSelectorDisplay(day, keepCurrentDay) {
var url = ApplicationBaseURL + "/dateselector";
if (day) {
if (day.length < 8)
day += "01";
url += "?day=" + day;
}
if (!keepCurrentDay)
currentDay = day;
var month = day.substr(0, 6);
if (cachedDateSelectors[month]) {
// log ("restoring cached selector for month: " + month);
setDateSelectorContent(cachedDateSelectors[month]);
}
else {
// log ("loading selector for month: " + month);
if (document.dateSelectorAjaxRequest) {
document.dateSelectorAjaxRequest.aborted = true;
document.dateSelectorAjaxRequest.abort();
}
document.dateSelectorAjaxRequest
= triggerAjaxRequest(url,
dateSelectorCallback,
month);
}
}
function changeCalendarDisplay(data, newView) {
newView = ((newView) ? newView : currentView);
var url = ApplicationBaseURL + "/" + newView;
var day = null;
var scrollEvent = null;
if (data) {
day = data['day'];
scrollEvent = data['scrollEvent'];
}
if (!day)
day = currentDay;
if (day) {
if (data) {
var dayDiv = $("day"+day);
if (dayDiv) {
// Don't reload the view if the event is present in current view
// Deselect day in date selector
if (document.selectedDate)
document.selectedDate.deselect();
// Select day in date selector
var selectedLink = $$('table#dateSelectorTable span[day='+day+']');
if (selectedLink.length > 0) {
selectedCell = selectedLink[0].getParentWithTagName("td");
$(selectedCell).selectElement();
document.selectedDate = selectedCell;
} else
document.selectedDate = null;
// Scroll to event
if (scrollEvent) {
preventAutoScroll = false;
scrollDayView(scrollEvent);
}
setSelectedDayDate(day);
return false;
}
else if (day.length == 6) {
day += "01";
}
}
url += "?day=" + day;
}
selectedCalendarCell = null;
if (document.dayDisplayAjaxRequest) {
document.dayDisplayAjaxRequest.aborted = true;
document.dayDisplayAjaxRequest.abort();
}
document.dayDisplayAjaxRequest
= triggerAjaxRequest(url, calendarDisplayCallback,
{ "view": newView,
"day": day,
"scrollEvent": scrollEvent });
return false;
}
function _ensureView(view) {
if (currentView != view)
changeCalendarDisplay(null, view);
return false;
}
function onDayOverview() {
return _ensureView("dayview");
}
function onMulticolumnDayOverview() {
return _ensureView("multicolumndayview");
}
function onWeekOverview() {
return _ensureView("weekview");
}
function onMonthOverview() {
return _ensureView("monthview");
}
function refreshEventsAndTasks() {
refreshEvents();
refreshTasks();
}
function onCalendarReload() {
if (!reloadWebCalendars()) {
refreshEventsAndTasks();
changeCalendarDisplay();
}
return false;
}
function reloadWebCalendars() {
var remaining = [];
var refreshOperations = { "remaining": remaining };
if (UserSettings['Calendar']
&& UserSettings['Calendar']['WebCalendars']) {
var webCalendars = UserSettings['Calendar']['WebCalendars'];
var folders = $("calendarList");
var calendarNodes = folders.childNodesWithTag("li");
for (var i = 0; i < calendarNodes.length; i++) {
var current = calendarNodes[i];
var calendarID = current.getAttribute("id");
var owner = current.getAttribute("owner");
var realID = owner + ":Calendar/" + calendarID.substr(1);
if (webCalendars[realID]) { /* is web calendar ? */
remaining.push(realID);
reloadWebCalendar(realID, refreshOperations);
}
}
}
return (remaining.length > 0);
}
var calendarReloadErrors = { "invalid-calendar-content":
_("the returned content was not valid calendar"
+ " data"),
"http-error": _("an unknown http error occurred"
+ " during the load operation"),
"bad-url": _("the url in use is invalid or the"
+ " host is currently unreachable"),
"invalid-url": _("the url being used is invalid"
+ " or not handled") };
function reloadWebCalendar(folderID, refreshOperations) {
var url = URLForFolderID(folderID) + "/reload";
var cbData = { "folderID": folderID };
if (refreshOperations) {
cbData["refreshOperations"] = refreshOperations;
}
triggerAjaxRequest(url, reloadWebCalendarCallback, cbData);
}
function reloadWebCalendarCallback(http) {
var cbData = http.callbackData;
if (http.status == 200) {
var result = http.responseText.evalJSON(true);
var requireAuth = false;
var success = false;
if (result.status) {
if (result.status == 401) {
requireAuth = true;
}
else {
if (result.status == 200) {
success = true;
}
else {
var errorMessage = _("An error occurred while importing calendar.");
if (result["error"]) {
var message = calendarReloadErrors[result["error"]];
errorMessage = (_("An error occurred while loading remote"
+ " calendar: %{0}.").formatted(message));
}
showAlertDialog (errorMessage);
}
}
}
else {
var errorMessage = _("An error occurred while importing calendar.");
if (result["error"]) {
var message = calendarReloadErrors[result["error"]];
errorMessage = (_("An error occurred while loading remote"
+ " calendar: %{0}.").formatted(message));
}
showAlertDialog (errorMessage);
}
if (requireAuth) {
reauthenticateWebCalendar(cbData["folderID"], cbData);
}
else {
var refreshOperations = cbData["refreshOperations"];
if (refreshOperations) {
var remaining = refreshOperations["remaining"];
var calIdx = remaining.indexOf(cbData["folderID"]);
remaining.splice(calIdx, 1);
if (remaining.length == 0) {
refreshEventsAndTasks();
changeCalendarDisplay();
}
}
else {
if (success) {
refreshEventsAndTasks();
changeCalendarDisplay();
}
}
}
}
else {
showAlertDialog(_("An error occurred while importing calendar."));
var refreshOperations = cbData["refreshOperations"];
if (refreshOperations) {
var remaining = refreshOperations["remaining"];
var calIdx = remaining.indexOf(cbData["folderID"]);
remaining.splice(calIdx, 1);
if (remaining.length > 0) {
var newFolderID = remaining[0];
reloadWebCalendar(newFolderID, refreshOperations);
}
}
}
}
function reauthenticateWebCalendar(folderID, refreshCBData) {
var remoteURL = null;
if (UserSettings['Calendar'] && UserSettings['Calendar']['WebCalendars']) {
var webCalendars = UserSettings['Calendar']['WebCalendars'];
remoteURL = webCalendars[folderID];
}
var parts = remoteURL.split("/");
var hostname = parts[2];
function authenticate(username, password) {
disposeDialog();
var url = URLForFolderID(folderID) + "/set-credentials";
var parameters = ("username=" + encodeURIComponent(username)
+ "&password=" + encodeURIComponent(password));
triggerAjaxRequest(url, authenticateWebCalendarCallback, refreshCBData, parameters,
{ "Content-type": "application/x-www-form-urlencoded" });
}
showAuthenticationDialog(_("Please identify yourself to %{0}")
.formatted(hostname),
authenticate);
}
function authenticateWebCalendarCallback(http) {
var cbData = http.callbackData;
var folderID = cbData["folderID"];
var refreshOperations = cbData["refreshOperations"];
if (isHttpStatus204(http.status)) {
reloadWebCalendar(folderID, refreshOperations);
}
else {
if (refreshOperations) {
var remaining = refreshOperations["remaining"];
var calIdx = remaining.indexOf(folderID);
remaining.splice(calIdx, 1);
if (remaining.length > 0) {
var newFolderID = remaining[0];
reloadWebCalendar(newFolderID, refreshOperations);
}
}
}
}
function scrollDayView(scrollEvent) {
if (!preventAutoScroll) {
if (scrollEvent) {
var contentView;
var eventRow = $(scrollEvent);
if (eventRow) {
var eventBlocks = selectCalendarEvent(eventRow.calendar, eventRow.cname, eventRow.recurrenceTime);
if (eventBlocks) {
var firstEvent = eventBlocks.first();
if (currentView == "monthview")
contentView = firstEvent.up("DIV.day");
else
contentView = $("daysView");
// Don't scroll to an all-day event
if (typeof eventRow.hour != "undefined") {
var top = firstEvent.cumulativeOffset()[1] - contentView.scrollTop;
// Don't scroll if the event is visible to the user
if (top < contentView.cumulativeOffset()[1])
contentView.scrollTop = firstEvent.cumulativeOffset()[1] - contentView.cumulativeOffset()[1];
else if (top > contentView.cumulativeOffset()[1] + contentView.getHeight() - firstEvent.getHeight())
contentView.scrollTop = firstEvent.cumulativeOffset()[1] - contentView.cumulativeOffset()[1];
}
}
}
}
else if (currentView != "monthview") {
var contentView = $("daysView");
var hours = (contentView.childNodesWithTag("div")[0]).childNodesWithTag("div");
contentView.scrollTop = hours[dayStartHour].offsetTop;
}
}
}
function onClickableCellsDblClick(event) {
var target = getTarget(event);
// Hack to ignore double-click in the scrollbar
if (target.hasClassName("dayHeader") || (this.scrollHeight - this.clientHeight <= 1)) {
newEventFromWidget(this, 'event');
Event.stop(event);
}
}
function refreshCalendarEvents(scrollEvent) {
var todayDate = new Date();
var sd;
var ed;
if (!currentDay)
currentDay = todayDate.getDayString();
if (currentView == "dayview" || currentView == "multicolumndayview") {
sd = currentDay;
ed = sd;
}
else if (currentView == "weekview") {
var startDate;
startDate = currentDay.asDate();
startDate = startDate.beginOfWeek();
sd = startDate.getDayString();
var endDate = new Date();
endDate.setTime(startDate.getTime());
endDate.addDays(6);
ed = endDate.getDayString();
}
else {
var monthDate;
monthDate = currentDay.asDate();
monthDate.setDate(1);
sd = monthDate.beginOfWeek().getDayString();
var lastMonthDate = new Date();
lastMonthDate.setTime(monthDate.getTime());
lastMonthDate.setMonth(monthDate.getMonth() + 1);
lastMonthDate.addDays(-1);
ed = lastMonthDate.endOfWeek().getDayString();
}
if (document.refreshCalendarEventsAjaxRequest) {
document.refreshCalendarEventsAjaxRequest.aborted = true;
document.refreshCalendarEventsAjaxRequest.abort();
}
var url = (ApplicationBaseURL + "/eventsblocks?sd=" + sd + "&ed=" + ed
+ "&view=" + currentView);
document.refreshCalendarEventsAjaxRequest
= triggerAjaxRequest(url, refreshCalendarEventsCallback,
{"startDate": sd, "endDate": ed,
"scrollEvent": scrollEvent});
}
function _parseEvents(list, calendars) {
var newCalendarEvents = {};
if (currentView == "multicolumndayview") {
var list;
for (var i = 0; i < calendars.length; i++) {
list = calendars[i][0];
for (var j = 0; j < list.length; j++) {
var event = list[j];
var cname = event[0];
var calendar = event[1];
// log("parsed cname: " + cname + "; calendar: " + calendar);
var calendarDict = newCalendarEvents[calendar];
if (!calendarDict) {
calendarDict = {};
newCalendarEvents[calendar] = calendarDict;
}
var occurences = calendarDict[cname];
if (!occurences) {
occurences = [];
calendarDict[cname] = occurences;
}
event.blocks = [];
occurences.push(event);
}
}
}
else {
for (var i = 0; i < list.length; i++) {
var event = list[i];
var cname = event[0];
var calendar = event[1];
// log("parsed cname: " + cname + "; calendar: " + calendar);
var calendarDict = newCalendarEvents[calendar];
if (!calendarDict) {
calendarDict = {};
newCalendarEvents[calendar] = calendarDict;
}
var occurences = calendarDict[cname];
if (!occurences) {
occurences = [];
calendarDict[cname] = occurences;
}
event.blocks = [];
occurences.push(event);
}
}
return newCalendarEvents;
}
function _setupEventsDragAndDrop(events) {
/* We setup the drag controllers for all the events.
Since the same events may be listed more than once per calendar
(repeating events), we must keep account of those that have already
been setup. */
var setupFlags = {};
for (var i = 0; i < events.length; i++) {
var cname = events[i][0];
var calendar = events[i][1];
var setupId = calendar + "_" + cname;
if (!setupFlags[setupId]) {
var occurrences = calendarEvents[calendar][cname];
for (var j = 0; j < occurrences.length; j++) {
var blocks = occurrences[j].blocks;
var dragController = new SOGoEventDragController();
dragController.updateDropCallback = updateEventFromDragging;
dragController.attachToEventCells(blocks);
}
setupFlags[setupId] = true;
}
}
}
function refreshCalendarEventsCallback(http) {
if (http.readyState == 4
&& http.status == 200) {
if (http.responseText.length > 0) {
var eventsBlocks = http.responseText.evalJSON(true);
if (currentView == "multicolumndayview") {
calendarEvents = _parseEvents(null, eventsBlocks);
_drawCalendarAllDayEvents(null, null, eventsBlocks);
_drawCalendarEvents(null, null, eventsBlocks);
for (var i = 0 ; i < eventsBlocks.length; i++) {
_setupEventsDragAndDrop(eventsBlocks[i][0]);
}
}
else {
calendarEvents = _parseEvents(eventsBlocks[0], null);
allDayEventsList = eventsBlocks[1];
eventsList = eventsBlocks[2];
if (currentView == "monthview")
_drawMonthCalendarEvents(eventsList, eventsBlocks[0], null);
else {
_drawCalendarAllDayEvents(allDayEventsList, eventsBlocks[0], null);
_drawCalendarEvents(eventsList, eventsBlocks[0], null);
}
_setupEventsDragAndDrop(eventsBlocks[0]);
}
resetCategoriesStyles();
onWindowResize(null);
}
if (http.callbackData["scrollEvent"])
preventAutoScroll = false;
scrollDayView(http.callbackData["scrollEvent"]);
}
else
log("AJAX error when refreshing calendar events");
}
function resetCategoriesStyles() {
if (categoriesStyleSheet == null) {
categoriesStyleSheet = document.createElement("style");
categoriesStyleSheet.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(categoriesStyleSheet);
}
else {
if (Prototype.Browser.IE)
while (categoriesStyleSheet.styleSheet.rules.length)
categoriesStyleSheet.styleSheet.removeRule();
else
while (categoriesStyleSheet.firstChild)
categoriesStyleSheet.removeChild(categoriesStyleSheet.firstChild);
}
if (UserDefaults['SOGoCalendarCategoriesColors']) {
// Update stylesheet with new categories colors
var selectors = [];
var rules = [];
categoriesStyles.keys().each(function(category) {
var color = UserDefaults['SOGoCalendarCategoriesColors'][category];
if (color) {
rules[rules.length] = '{ border-right: 8px solid ' + color + '; }';
selectors[selectors.length] = 'DIV.' + categoriesStyles.get(category);
}
});
if (selectors.length > 0) {
if (categoriesStyleSheet.styleSheet && categoriesStyleSheet.styleSheet.addRule) {
// IE
for (var i = 0; i < selectors.length; i++)
categoriesStyleSheet.styleSheet.addRule(selectors[i],
rules[i]);
}
else {
// Mozilla + Safari
for (var i = 0; i < selectors.length; i++)
categoriesStyleSheet.appendChild(document.createTextNode(selectors[i] +
' ' + rules[i]));
}
}
}
}
function newBaseEventDIV(eventRep, event, eventText) {
// log ("0 cname = " + event[0]);
// log ("1 calendar = " + event[1]);
// log ("2 calendar name = " + event[2]);
// log ("3 status = " + event[3]);
// log ("4 title = " + event[4]);
// log ("5 start = " + event[5]);
// log ("6 end = " + event[6]);
// log ("7 location = " + event[7]);
// log ("8 isallday = " + event[8]);
// log ("9 classification = " + event[9]); // 0 = public, 1 = private, 2 = confidential
// log ("10 category = " + event[10]);
// log ("11 participants emails = " + event[11]);
// log ("12 participants states = " + event[12]);
// log ("13 owner = " + event[13]);
// log ("14 iscycle = " + event[14]);
// log ("15 nextalarm = " + event[15]);
// log ("16 recurrenceid = " + event[16]);
// log ("17 isexception = " + event[17]);
// log ("18 editable = " + event[18]);
// log ("19 erasable = " + event[19]);
// log ("20 ownerisorganizer = " + event[20]);
var eventCell = createElement("div");
eventCell.cname = event[0];
eventCell.calendar = event[1];
var startDate = new Date(event[5]*1000);
if (startDate) {
eventCell.startDate = event[5];
eventCell.writeAttribute('day', startDate.getDayString());
eventCell.writeAttribute('hour', event[8]? 'allday' : startDate.getHourString());
}
// if (event[8] == 1)
// eventCell.addClassName("private");
// else if (event[8] == 2)
// eventCell.addClassName("confidential");
if (eventRep.recurrenceTime)
eventCell.recurrenceTime = eventRep.recurrenceTime;
//eventCell.owner = event[12];
eventCell.isException = event[17];
eventCell.editable = event[18];
eventCell.erasable = event[19] || IsSuperUser;
eventCell.ownerIsOrganizer = event[20];
eventCell.addClassName("event");
// if (event[14] > 0)
// eventCell.addClassName("alarm");
var innerDiv = createElement("div");
eventCell.appendChild(innerDiv);
innerDiv.addClassName("eventInside");
innerDiv.addClassName("calendarFolder" + event[1]);
if (eventRep.userState >= 0 && userStates[eventRep.userState])
innerDiv.addClassName(userStates[eventRep.userState]);
var gradientDiv = createElement("div");
innerDiv.appendChild(gradientDiv);
gradientDiv.addClassName("gradient");
var gradientImg = createElement("img");
gradientDiv.appendChild(gradientImg);
gradientImg.src = ResourcesURL + "/event-gradient.png";
var textDiv = createElement("div");
innerDiv.appendChild(textDiv);
textDiv.addClassName("text");
var iconSpan = createElement("span", null, "icons");
textDiv.update(eventText.replace(/(\\r)?\\n/g, "
"));
textDiv.appendChild(iconSpan);
// Add alarm and classification icons
if (event[9] == 1)
createElement("img", null, null, {src: ResourcesURL + "/private.png"}, null, iconSpan);
else if (event[9] == 2)
createElement("img", null, null, {src: ResourcesURL + "/confidential.png"}, null, iconSpan);
if (event[15] > 0)
createElement("img", null, null, {src: ResourcesURL + "/alarm.png"}, null, iconSpan);
if (event[10] != null) {
var category = event[10].decodeEntities();
var categoryStyle = categoriesStyles.get(category);
if (!categoryStyle) {
categoryStyle = 'category_' + categoriesStyles.keys().length;
categoriesStyles.set([category], categoryStyle);
}
innerDiv.addClassName(categoryStyle);
}
eventCell.observe("contextmenu", onMenuCurrentView);
if (event[3] == null) {
// Status field is not defined -- user can't read event
eventCell.observe("selectstart", listRowMouseDownHandler);
eventCell.observe("click", onCalendarSelectEvent);
eventCell.observe("dblclick", Event.stop);
}
else {
// Status field is defined -- user can read event
eventCell.observe("mousedown", listRowMouseDownHandler);
eventCell.observe("click", onCalendarSelectEvent);
eventCell.observe("dblclick", editDoubleClickedEvent);
eventCell.observe("click", onViewEvent);
}
event.blocks.push(eventCell);
return eventCell;
}
function _drawCalendarAllDayEvents(events, eventsData, columnsData) {
var headerView = $("calendarHeader");
var subdivs = headerView.childNodesWithTag("div");
if (currentView == "multicolumndayview"){
var days = subdivs[2].childNodesWithTag("div");
for (var i = 0; i < days.length; i++) {
var parentDiv = days[i];
var calendar = columnsData[i];
var calendarAllDayEvents = calendar[1][0];
var calendarAllDayEventsData = calendar[0];
for (var j = 0; j < calendarAllDayEvents.length; j++) {
var eventRep = calendarAllDayEvents[j];
var nbr = eventRep.nbr;
var eventCell = newAllDayEventDIV(eventRep, calendarAllDayEventsData[nbr]);
parentDiv.appendChild(eventCell);
}
}
}
else {
var days = subdivs[1].childNodesWithTag("div");
for (var i = 0; i < days.length; i++) {
var parentDiv = days[i];
for (var j = 0; j < events[i].length; j++) {
var eventRep = events[i][j];
var nbr = eventRep.nbr;
var eventCell = newAllDayEventDIV(eventRep, eventsData[nbr]);
parentDiv.appendChild(eventCell);
}
}
}
resizeCalendarHeaderDIV();
}
/* When the list of all day events overflows, we resize it in order to contain
at least 6 or 7 items. Afterwards we restore the regular scrollbar
mechanism. */
function resizeCalendarHeaderDIV() {
var headerView = $("calendarHeader");
var daysView = $("daysView");
if (headerView && daysView) {
/* consts */
var headerViewBaseHeight = 90;
var daysViewBaseTop = 95;
/* /consts */
var maxEventPerDay = 0;
var subdivs = headerView.childNodesWithTag("div");
if (currentView == "multicolumndayview")
var days = subdivs[2].childNodesWithTag("div");
else
var days = subdivs[1].childNodesWithTag("div");
for (var i = 0; i < days.length; i++) {
var parentDiv = days[i];
var divs = parentDiv.childNodesWithTag("div");
if (divs.length > maxEventPerDay) {
maxEventPerDay = divs.length;
}
}
if (maxEventPerDay > 0 && maxEventPerDay <= 4) {
var moveDaysView = (maxEventPerDay * 19.5);
var expendHeaderHeight = ((maxEventPerDay - 1) * 20);
var deltaMax = 60;
if (expendHeaderHeight > deltaMax){
expendHeaderHeight = deltaMax;
moveDaysView = deltaMax;
}
daysView.style.top = String(daysViewBaseTop + moveDaysView) + "px";
headerView.style.height = String(headerViewBaseHeight + expendHeaderHeight) + "px";
}
else if (maxEventPerDay > 4) {
var deltaMax = 60;
daysView.style.top = String(daysViewBaseTop + deltaMax + 19) + "px";
headerView.style.height = String(headerViewBaseHeight + deltaMax) + "px";
}
else {
var headerDays = document.getElementsByClassName("days")[0];
headerDays.observe("mouseenter", function(event){
headerDays.style.zIndex = "1";
});
headerDays.observe("mouseleave", function(event){
headerDays.style.zIndex = "0";
});
daysView.style.top = null;
headerView.style.height = null;
}
}
}
function newAllDayEventDIV(eventRep, event) {
// cname, calendar, starts, lasts,
// startHour, endHour, title) {
var eventCell = newBaseEventDIV(eventRep, event, event[4]);
return eventCell;
}
function _drawCalendarEvents(events, eventsData, columnsData) {
var daysView = $("daysView");
var subdivs = daysView.childNodesWithTag("div");
for (var i = 0; i < subdivs.length; i++) {
var subdiv = subdivs[i];
if (subdiv.hasClassName("days")) {
var days = subdiv.childNodesWithTag("div");
if (currentView == "multicolumndayview") {
for (var j = 0; j < days.length; j++) {
var parentDiv = days[j].childNodesWithTag("div")[0];
var calendar = columnsData[j];
var calendarEvents = calendar[2][0];
var calendarEventsData = calendar[0];
for (var k = 0; k < calendarEvents.length; k++) {
var eventRep = calendarEvents[k];
var nbr = eventRep.nbr;
var eventCell = newEventDIV(eventRep, calendarEventsData[nbr]);
parentDiv.appendChild(eventCell);
}
}
}
else {
for (var j = 0; j < days.length; j++) {
var parentDiv = days[j].childNodesWithTag("div")[0];
for (var k = 0; k < events[j].length; k++) {
var eventRep = events[j][k];
var nbr = eventRep.nbr;
var eventCell = newEventDIV(eventRep, eventsData[nbr]);
parentDiv.appendChild(eventCell);
}
}
}
}
}
}
function newEventDIV(eventRep, event) {
var eventCell = newBaseEventDIV(eventRep, event, event[4]);
var pc = 100 / eventRep.siblings;
var left = Math.floor(eventRep.position * pc);
eventCell.style.left = left + "%";
var right = Math.floor(100 - (eventRep.position + 1) * pc);
eventCell.style.right = right + "%";
eventCell.addClassName("starts" + eventRep.start);
eventCell.addClassName("lasts" + eventRep.length);
if (event[7]) {
var inside = eventCell.childNodesWithTag("div")[0];
var textDiv = inside.childNodesWithTag("div")[1];
textDiv.appendChild(createElement("br"));
var span = createElement("span", null, "location");
var text = _("Location:") + " " + event[7];
span.update(text);
textDiv.appendChild(span);
}
return eventCell;
}
function _drawMonthCalendarEvents(events, eventsData) {
var daysView = $("monthDaysView");
var days = daysView.childNodesWithTag("div");
for (var i = 0; i < days.length; i++) {
var parentDiv = days[i];
for (var j = 0; j < events[i].length; j++) {
var eventRep = events[i][j];
var nbr = eventRep.nbr;
var eventCell = newMonthEventDIV(eventRep, eventsData[nbr]);
parentDiv.appendChild(eventCell);
}
}
}
function newMonthEventDIV(eventRep, event) {
var eventText;
if (event[8]) // all-day event
eventText = event[4];
else
eventText = eventRep.starthour + " - " + event[4];
var eventCell = newBaseEventDIV(eventRep, event,
eventText);
return eventCell;
}
function attachDragControllers(contentView) {
var dayNodes = contentView.select("DIV.days DIV.day");
for (var j = 0; j < dayNodes.length; j++) {
var dayNode = dayNodes[j];
if (dayNode.hasClassName("day")) {
var dragController = new SOGoEventDragController();
dragController.createDropCallback = newEventFromDragging;
dragController.attachToDayNode(dayNode);
}
}
}
/* On IE, the scroll bar is part of the last element. For other browsers, we
execute this method so that the "right" style attribute of the
"calendarHeader" element can be computed. This is execute only once. */
function adjustCalendarHeaderDIV() {
var dv = $("daysView");
if (dv) {
var ch = $("calendarHeader");
var delta = ch.clientWidth - dv.clientWidth - 1;
var styleElement = document.createElement("style");
styleElement.type = "text/css";
var selectors = ["DIV#calendarHeader DIV.calendarLabels",
"DIV#calendarHeader DIV.dayLabels",
"DIV#calendarHeader DIV.days"];
var rule = ("right: " + delta + "px");
if (styleElement.styleSheet && styleElement.styleSheet.addRule) {
// IE
styleElement.styleSheet.addRule(selectors[0], rule);
styleElement.styleSheet.addRule(selectors[1], rule);
} else {
// Mozilla + Firefox
var styleText = selectors.join(",") + " { " + rule + "; }";
styleElement.appendChild(document.createTextNode(styleText));
}
document.getElementsByTagName("head")[0].appendChild(styleElement);
calendarHeaderAdjusted = true;
}
}
function adjustMultiColumnCalendarHeaderDIV() {
var ch = $("calendarHeader");
var calendarLabels = ch.getElementsByClassName("calendarLabels")[0];
var calendarsToDisplay = calendarLabels.getElementsByClassName("calendarsToDisplay");
var dayLabels = ch.getElementsByClassName("dayLabels")[0].getElementsByClassName("dayColumn")[0];
var days = ch.getElementsByClassName("days")[0].getElementsByClassName("dayColumn");
var daysView = $("daysView").getElementsByClassName("dayColumn");
var nbCalendars = calendarsToDisplay.length;
if (nbCalendars > 0) {
var width = 100/nbCalendars;
var left = 0;
var position = "absolute";
for(var i=0; i < nbCalendars; i++){
calendarsToDisplay[i].setStyle({ width: width + '%', left: left + '%', position: position}).show();
days[i].setStyle({ width: width + '%', left: left + '%'}).show();
daysView[i].setStyle({ width: width + '%', left: left + '%'}).show();
left += width;
}
dayLabels.setStyle({ width: '100%'}).show();
}
else {
$("calendarHeader").remove();
$("daysView").remove();
var htmlText = "