Bug 351084 - Can't set alarm for new task, existing or default alarm throws error, r=philipp

This commit is contained in:
michael.buettner%sun.com 2007-08-30 14:04:19 +00:00
Родитель 18a3742c4c
Коммит 9d1428d8c6
3 изменённых файлов: 150 добавлений и 91 удалений

Просмотреть файл

@ -81,6 +81,59 @@ function disableElement(elementId)
setElementValue(elementId, "true", "disabled");
}
/**
* This function unconditionally disables the element for
* which the id has been passed as argument. Furthermore, it
* remembers who was responsible for this action by using
* the given key (lockId). In case the control should be
* enabled again the lock gets removed, but the control only
* gets enabled if *all* possibly held locks have been removed.
*/
function disableElementWithLock(elementId,lockId) {
// unconditionally disable the element.
disableElement(elementId);
// remember that this element has been locked with
// the key passed as argument. we keep a primitive
// form of ref-count in the attribute 'lock'.
var element = document.getElementById(elementId);
if (element) {
if (!element.hasAttribute(lockId)) {
element.setAttribute(lockId, "true");
var n = parseInt(element.getAttribute("lock") || 0);
element.setAttribute("lock", n + 1);
}
}
}
/**
* This function is intended to be used in tandem with the
* above defined function 'disableElementWithLock()'.
* See the respective comment for further details.
*/
function enableElementWithLock(elementId, lockId) {
var element = document.getElementById(elementId);
if (!element) {
dump("unable to find " + elementId + "\n");
return;
}
if (element.hasAttribute(lockId)) {
element.removeAttribute(lockId);
var n = parseInt(element.getAttribute("lock") || 0) - 1;
if (n > 0) {
element.setAttribute("lock", n);
} else {
element.removeAttribute("lock");
}
if (n <= 0) {
enableElement(elementId);
}
}
}
/* use with textfields oninput to only allow integers */
function validateIntegerRange(event, lowerBound, upperBound) {
validateIntegers(event);
@ -764,16 +817,17 @@ function saveReminder(item) {
}
function commonUpdateReminder() {
// find relevant elements in the document
var reminderPopup = document.getElementById("item-alarm");
var reminderDetails = document.getElementById("reminder-details");
// if a custom reminder was selected, we show the appropriate
// if a custom reminder has been selected, we show the appropriate
// dialog in order to allow the user to specify the details.
// the result will be placed in the 'reminder-custom-menuitem' tag.
var reminderPopup = document.getElementById("item-alarm");
if (reminderPopup.value == 'custom') {
// show the dialog.
editReminder();
// don't pop up the dialog if this happens during
// initialization of the dialog.
if (reminderPopup.hasAttribute("last-value")) {
editReminder();
}
// Now check if the resulting custom reminder is valid.
// possibly we receive an invalid reminder if the user cancels the
@ -786,6 +840,70 @@ function commonUpdateReminder() {
// remember the current reminder drop down selection index.
gLastAlarmSelection = reminderPopup.selectedIndex;
reminderPopup.setAttribute("last-value", reminderPopup.value);
// possibly the selected reminder conflicts with the item.
// for example an end-relation combined with a task without duedate
// is an invalid state we need to take care of. we take the same
// approach as with recurring tasks. in case the reminder is related
// to the entry date we check the entry date automatically and disable
// the checkbox. the same goes for end related reminder and the due date.
if (isToDo(window.calendarItem)) {
// custom reminder entries carry their own reminder object
// with them, pre-defined entries specify the necessary information
// as attributes attached to the menuitem elements.
var menuitem = reminderPopup.selectedItem;
if (menuitem.value == 'none') {
enableElementWithLock("todo-has-entrydate", "reminder-lock");
enableElementWithLock("todo-has-duedate", "reminder-lock");
} else {
var reminder = menuitem.reminder;
if (!reminder) {
reminder = {};
reminder.length = menuitem.getAttribute('length');
reminder.unit = menuitem.getAttribute('unit');
reminder.relation = menuitem.getAttribute('relation');
reminder.origin = menuitem.getAttribute('origin');
}
// if this reminder is related to the entry date...
if (Number(reminder.origin) > 0) {
// ...automatically check 'has entrydate'.
if (!getElementValue("todo-has-entrydate", "checked")) {
setElementValue("todo-has-entrydate", "true", "checked");
// make sure gStartTime is properly initialized
updateEntryDate();
}
// disable the checkbox to indicate that we need
// the entry-date. the 'disabled' state will be
// revoked if the user turns off the repeat pattern.
disableElementWithLock("todo-has-entrydate", "reminder-lock");
enableElementWithLock("todo-has-duedate", "reminder-lock");
}
// if this reminder is related to the due date...
if (Number(reminder.origin) < 0) {
// ...automatically check 'has duedate'.
if (!getElementValue("todo-has-duedate", "checked")) {
setElementValue("todo-has-duedate", "true", "checked");
// make sure gStartTime is properly initialized
updateDueDate();
}
// disable the checkbox to indicate that we need
// the entry-date. the 'disabled' state will be
// revoked if the user turns off the repeat pattern.
disableElementWithLock("todo-has-duedate", "reminder-lock");
enableElementWithLock("todo-has-entrydate", "reminder-lock");
}
}
}
updateReminderDetails();
}

Просмотреть файл

@ -429,7 +429,8 @@ function loadDialog(item) {
updateTitle();
updateAttendees();
updateReminderDetails();
updateRepeat();
updateReminder();
// How easy would it be to just call hasProperty(), but unfortunately
// this is currently flawed and doesn't give us the answer we're longing for.
@ -1029,10 +1030,6 @@ function updateAccept() {
enableAccept = false;
}
if (!updateTaskAlarmWarnings()) {
enableAccept = false;
}
var accept = document.getElementById("cmd_accept");
if (enableAccept) {
accept.removeAttribute('disabled');
@ -1043,39 +1040,6 @@ function updateAccept() {
return enableAccept;
}
function updateTaskAlarmWarnings() {
var alarmType = getElementValue("item-alarm");
if (!isToDo(window.calendarItem) ||
alarmType == "none") {
return true;
}
var hasEntryDate =
getElementValue(
"todo-has-entrydate",
"checked");
var hasDueDate =
getElementValue(
"todo-has-duedate",
"checked");
var alarmRelated = document.getElementById("alarm-trigger-relation")
.selectedItem.value;
if ((alarmType != "custom" ||
alarmRelated == "START") &&
!hasEntryDate) {
return false;
}
if (alarmRelated == "END" &&
!hasDueDate) {
return false;
}
return true;
}
// this function sets the enabled/disabled
// state of the following controls:
// - 'event-starttime'
@ -1125,17 +1089,6 @@ function updateAllDay() {
updateAccept();
}
function setAlarmFields(alarmItem) {
var alarmLength = alarmItem.getAttribute("length");
if (alarmLength != "") {
var alarmUnits = alarmItem.getAttribute("unit");
var alarmRelation = alarmItem.getAttribute("relation");
setElementValue("alarm-length-field", alarmLength);
setElementValue("alarm-length-units", alarmUnits);
setElementValue("alarm-trigger-relation", alarmRelation);
}
}
function openNewEvent() {
var item = window.calendarItem;
var args = window.arguments[0];
@ -1515,12 +1468,7 @@ function updateCalendar() {
setElementValue("item-calendar", "true", "disabled");
// don't allow to revoke the entrydate of recurring todo's.
disableElement("todo-has-entrydate");
}
// don't allow to revoke the entrydate of recurring todo's.
if (window.recurrenceInfo) {
disableElement("todo-has-entrydate");
disableElementWithLock("todo-has-entrydate", "permanent-lock");
}
// update datetime pickers
@ -1554,10 +1502,12 @@ function editRepeat() {
args);
}
// This function is called after the 'repeat pattern' selection has been
// changed. As a consequence we need to create/modify recurrence rules or
// bring up the custom 'repeat pattern'-dialog and modify states of several
// elements of the document (i.e. task entrydate, etc.)
/**
* This function is responsilble for propagating UI state to controls
* depending on the repeat setting of an item. This functionality is used
* after the dialog has been loaded as well as if the repeat pattern has
* been changed.
*/
function updateRepeat() {
var repeatMenu = document.getElementById("item-repeat");
var repeatItem = repeatMenu.selectedItem;
@ -1567,7 +1517,7 @@ function updateRepeat() {
window.recurrenceInfo = null;
var item = window.calendarItem;
if (isToDo(item)) {
enableElement("todo-has-entrydate");
enableElementWithLock("todo-has-entrydate", "repeat-lock");
}
} else if (repeatValue == 'custom') {
// the user selected custom repeat pattern. we now need to bring
@ -1590,7 +1540,7 @@ function updateRepeat() {
// disable the checkbox to indicate that we need
// the entry-date. the 'disabled' state will be
// revoked if the user turns off the repeat pattern.
disableElement("todo-has-entrydate");
disableElementWithLock("todo-has-entrydate", "repeat-lock");
}
// retrieve the current recurrence info, we need this
@ -1599,7 +1549,11 @@ function updateRepeat() {
var recurrenceInfo = window.recurrenceInfo;
// now bring up the recurrence dialog.
editRepeat();
// don't pop up the dialog if this happens during
// initialization of the dialog.
if (repeatMenu.hasAttribute("last-value")) {
editRepeat();
}
// we need to address two separate cases here.
// 1) we need to revoke the selection of the repeat
@ -1611,7 +1565,7 @@ function updateRepeat() {
repeatMenu.selectedIndex = gLastRepeatSelection;
if (isToDo(item)) {
if (!window.recurrenceInfo) {
enableElement("todo-has-entrydate");
enableElementWithLock("todo-has-entrydate", "repeat-lock");
}
}
}
@ -1677,13 +1631,16 @@ function updateRepeat() {
if (!getElementValue("todo-has-entrydate", "checked")) {
setElementValue("todo-has-entrydate", "true", "checked");
}
disableElement("todo-has-entrydate");
disableElementWithLock("todo-has-entrydate", "repeat-lock");
}
}
gLastRepeatSelection = repeatMenu.selectedIndex;
repeatMenu.setAttribute("last-value", repeatValue);
updateRepeatDetails();
updateEntryDate();
updateDueDate();
updateAccept();
}
@ -2211,12 +2168,12 @@ function updateAttendees() {
}
function updateRepeatDetails() {
// Don't try to show the details text for anything but a custom recurrence
// rule. Also, we don't currently support tasks.
// Don't try to show the details text for
// anything but a custom recurrence rule.
var item = window.calendarItem;
var recurrenceInfo = window.recurrenceInfo;
var itemRepeat = document.getElementById("item-repeat");
if (itemRepeat.value == "custom" && isEvent(item) && recurrenceInfo) {
if (itemRepeat.value == "custom" && recurrenceInfo) {
var startDate = jsDateToDateTime(getElementValue("event-starttime"));
var endDate = jsDateToDateTime(getElementValue("event-endtime"));
var kDefaultTimezone = calendarDefaultTimezone();

Просмотреть файл

@ -481,22 +481,6 @@
</toolbox>
<label id="read-only-item"
value="&newevent.readonly.item.warning;"
hidden="true"/>
<label id="read-only-cal"
value="&newevent.readonly.cal.warning;"
hidden="true"/>
<label id="end-time-warning"
value="&newevent.endtime.warning;"
hidden="true"/>
<label id="alarm-start-warning"
value="&alarm.start.warning;"
hidden="true"/>
<label id="alarm-end-warning"
value="&alarm.due.warning;"
hidden="true"/>
<grid flex="1"
style="padding: 8px 10px 10px 8px;">
<columns>
@ -714,7 +698,7 @@
<separator class="groove"/>
<!-- Reminder (Alarm) -->
<row align="center" class="event-only">
<row align="center">
<label value="&event.reminder.label;"
disable-on-readonly="true"/>
<hbox align="center">
@ -803,7 +787,7 @@
</hbox>
</row>
<separator class="groove event-only"/>
<separator class="groove"/>
<!-- Description -->
<row id="description-row" flex="1">