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) {