зеркало из https://github.com/mozilla/pjs.git
Bug 351084 - Can't set alarm for new task, existing or default alarm throws error, r=philipp
This commit is contained in:
Родитель
18a3742c4c
Коммит
9d1428d8c6
|
@ -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">
|
||||
|
|
Загрузка…
Ссылка в новой задаче