diff --git a/calendar/base/content/calendar-task-editing.js b/calendar/base/content/calendar-task-editing.js index 3c859544413..f9222d2db43 100644 --- a/calendar/base/content/calendar-task-editing.js +++ b/calendar/base/content/calendar-task-editing.js @@ -38,8 +38,36 @@ /** * Used by the "quick add" feature for tasks, for example in the task view or * the uniinder-todo. + * + * NOTE: many of the following methods are called without taskEdit being the + * |this| object. */ + var taskEdit = { + mObservedCalendar: null, + get observedCalendar tE_get_observedCalendar() { + return this.mObservedCalendar; + }, + + set observedCalendar tE_set_observedCalendar(v) { + if (this.mObservedCalendar) { + this.mObservedCalendar.removeObserver(this.calendarObserver); + } + + this.mObservedCalendar = v; + + if (this.mObservedCalendar) { + this.mObservedCalendar.addObserver(this.calendarObserver); + } + return this.mObservedCalendar; + }, + + setupTaskField: function tE_setupTaskField(aTarget, aDisable, aValue) { + aTarget.value = aValue; + setElementValue(aTarget, aDisable && "true", "readonly"); + setElementValue(aTarget, aDisable && "true", "aria-disabled"); + }, + onFocus: function tE_onFocus(aEvent) { var edit = aEvent.target; if (edit.localName == "input") { @@ -47,13 +75,18 @@ var taskEdit = { // when debugging with venkman. edit = edit.parentNode.parentNode; } - if (!edit.savedInstructions) { - edit.savedInstructions = edit.getAttribute("instructions"); + + var calendar = getSelectedCalendar(); + + if (calendar.getProperty("capabilities.tasks.supported") === false) { + taskEdit.setupTaskField(edit, true, calGetString("calendar", "taskEditInstructionsCapability")); + } else if (!isCalendarWritable(calendar)) { + taskEdit.setupTaskField(edit, true, calGetString("calendar", "taskEditInstructionsReadonly")); + } else { + taskEdit.setupTaskField(edit, false, edit.savedValue || ""); } - edit.value = edit.savedValue || ""; - edit.removeAttribute("instructions"); }, - + onBlur: function tE_onBlur(aEvent) { var edit = aEvent.target; if (edit.localName == "input") { @@ -62,9 +95,17 @@ var taskEdit = { // the parent chain until we reach the textbox. edit = edit.parentNode.parentNode; } - edit.savedValue = edit.value; - edit.value = edit.savedInstructions; - edit.setAttribute("instructions", edit.savedInstructions); + + var calendar = getSelectedCalendar(); + + if (calendar.getProperty("capabilities.tasks.supported") === false) { + taskEdit.setupTaskField(edit, true, calGetString("calendar", "taskEditInstructionsCapability")); + } else if (!isCalendarWritable(getSelectedCalendar())) { + taskEdit.setupTaskField(edit, true, calGetString("calendar", "taskEditInstructionsReadonly")); + } else { + edit.savedValue = edit.value; + taskEdit.setupTaskField(edit, false, calGetString("calendar", "taskEditInstructions")); + } }, onKeyPress: function tE_onKeyPress(aEvent) { @@ -85,5 +126,81 @@ var taskEdit = { }); } } + }, + + onLoad: function tE_onLoad(aEvent) { + window.removeEventListener("load", taskEdit.onLoad, false); + var taskEditFields = document.getElementsByAttribute("class", "task-edit-field"); + for (var i = 0; i < taskEditFields.length; i++) { + taskEdit.onBlur({ target: taskEditFields[i] }); + } + + getCompositeCalendar().addObserver(taskEdit.compositeObserver); + taskEdit.observedCalendar = getSelectedCalendar(); + }, + + onUnload: function tE_onUnload() { + getCompositeCalendar().removeObserver(taskEdit.compositeObserver); + taskEdit.observedCalendar = null; + }, + + calendarObserver: { + QueryInterface: function tE_QueryInterface(aIID) { + return doQueryInterface(this, calendarListTreeView.__proto__, aIID, + [Components.interfaces.calIObserver]); + }, + + onPropertyChanged: function tE_calObs_onPropertyChanged(aCalendar, + aName, + aValue, + aOldValue) { + if (aCalendar.id != getSelectedCalendar().id) { + // Optimization: if the given calendar isn't the default calendar, + // then we don't need to change any readonly/disabled states. + return; + } + switch (aName) { + case "readOnly": + case "disabled": + var taskEditFields = document.getElementsByAttribute("class", "task-edit-field"); + for (var i = 0; i < taskEditFields.length; i++) { + taskEdit.onBlur({ target: taskEditFields[i] }); + } + } + }, + + onPropertyDeleting: function tE_calObs_onPropertyDeleting(aCalendar, + aName) { + // Since the old value is not used directly in onPropertyChanged, + // but should not be the same as the value, set it to a different + // value. + this.onPropertyChanged(aCalendar, aName, null, null); + }, + + __noSuchMethod__: function tE_calObs___noSuchMethod__(aMethod, aArgs) { + // Swallow other methods that don't need to be implemented + } + }, + + compositeObserver: { + QueryInterface: function tE_QueryInterface(aIID) { + return doQueryInterface(this, calendarListTreeView.__proto__, aIID, + [Components.interfaces.calIObserver, + Components.interfaces.calICompositeObserver]); + }, + + onDefaultCalendarChanged: function tE_compObs_onDefaultCalendarChanged(aNewDefault) { + var taskEditFields = document.getElementsByAttribute("class", "task-edit-field"); + for (var i = 0; i < taskEditFields.length; i++) { + taskEdit.onBlur({ target: taskEditFields[i] }); + } + taskEdit.observedCalendar = aNewDefault; + }, + __noSuchMethod__: function tE_compObs___noSuchMethod__(aMethod, aArgs) { + // Swallow other methods that don't need to be implemented + } } }; + +window.addEventListener("load", taskEdit.onLoad, false); +window.addEventListener("unload", taskEdit.onUnload, false); diff --git a/calendar/base/content/calendar-task-view.xul b/calendar/base/content/calendar-task-view.xul index f4b98920ef7..5e3fdfbb61c 100644 --- a/calendar/base/content/calendar-task-view.xul +++ b/calendar/base/content/calendar-task-view.xul @@ -57,8 +57,6 @@ onselect="taskDetailsView.onSelect(event);"> diff --git a/calendar/base/content/calendar-unifinder-todo.xul b/calendar/base/content/calendar-unifinder-todo.xul index 22b42c21882..b50f3abfa1e 100644 --- a/calendar/base/content/calendar-unifinder-todo.xul +++ b/calendar/base/content/calendar-unifinder-todo.xul @@ -74,8 +74,6 @@ diff --git a/calendar/base/themes/pinstripe/calendar-task-view.css b/calendar/base/themes/pinstripe/calendar-task-view.css index ebaff3d2a03..209fe2cbb6e 100644 --- a/calendar/base/themes/pinstripe/calendar-task-view.css +++ b/calendar/base/themes/pinstripe/calendar-task-view.css @@ -61,8 +61,8 @@ margin: 5px; } -.task-edit-field[instructions] { - color: grey; +.task-edit-field[readonly="true"] { + color: GrayText; } .task-quickadd-box { diff --git a/calendar/base/themes/winstripe/calendar-task-view.css b/calendar/base/themes/winstripe/calendar-task-view.css index 1c44240073c..7daa7fb9f39 100644 --- a/calendar/base/themes/winstripe/calendar-task-view.css +++ b/calendar/base/themes/winstripe/calendar-task-view.css @@ -65,8 +65,8 @@ margin: 5px; } -.task-edit-field[instructions] { - color: grey; +.task-edit-field[readonly="true"] { + color: GrayText; } .task-quickadd-box { diff --git a/calendar/locales/en-US/chrome/calendar/calendar.dtd b/calendar/locales/en-US/chrome/calendar/calendar.dtd index 8b2c265d1d7..812edc2c32b 100644 --- a/calendar/locales/en-US/chrome/calendar/calendar.dtd +++ b/calendar/locales/en-US/chrome/calendar/calendar.dtd @@ -196,7 +196,6 @@ - diff --git a/calendar/locales/en-US/chrome/calendar/calendar.properties b/calendar/locales/en-US/chrome/calendar/calendar.properties index fd00c9c2e20..7d66a8a7876 100644 --- a/calendar/locales/en-US/chrome/calendar/calendar.properties +++ b/calendar/locales/en-US/chrome/calendar/calendar.properties @@ -332,3 +332,7 @@ taskDetailsStatusCancelled=Cancelled gettingCalendarInfoCommon=Checking Calendars\u2026 gettingCalendarInfoDetail=Checking Calendar %1$S of %2$S + +taskEditInstructions=Click Here to Add a New Task +taskEditInstructionsReadonly=Please Select a Writable Calendar +taskEditInstructionsCapability=Please Select a Calendar that Supports Tasks diff --git a/calendar/providers/composite/calCompositeCalendar.js b/calendar/providers/composite/calCompositeCalendar.js index 33484f027f6..721a1b5f4d3 100644 --- a/calendar/providers/composite/calCompositeCalendar.js +++ b/calendar/providers/composite/calCompositeCalendar.js @@ -250,11 +250,8 @@ calCompositeCalendar.prototype = { }, setDefaultCalendar: function (cal, usePref) { - // Don't do anything if the passed calendar is the default calendar, or - // the passed calendar is disabled. - if (cal && - ((this.mDefaultCalendar && this.mDefaultCalendar.id == cal.id) || - cal.getProperty("disabled"))) { + // Don't do anything if the passed calendar is the default calendar + if (cal && this.mDefaultCalendar && this.mDefaultCalendar.id == cal.id) { return; } if (usePref && this.mPrefPrefix) {