gecko-dev/calendar/lightning/content/calendar-todo-list.xml

276 строки
9.9 KiB
XML

<?xml version="1.0"?>
<bindings id="calendar-todo-bindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="calendar-todo-list" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox"
implements="calIObserver, calICompositeObserver, calIOperationListener">
<implementation>
<field name="mCalendar">null</field>
<field name="mOperationListener"><![CDATA[
({
todoList: this,
mBatchCount: 0,
onStartBatch: function onStartBatch()
{
this.mBatchCount++;
return;
},
onEndBatch: function onEndBatch()
{
this.mBatchCount--;
if (this.mBatchCount == 0) {
this.todoList.rebuildDisplay();
}
return;
},
onLoad: function onLoad()
{
return;
},
onAddItem: function onAddItem(aItem)
{
if (!(aItem instanceof Components.interfaces.calITodo) ||
this.mBatchCount)
return;
this.todoList.addTodo(aItem);
},
onDeleteItem: function onDeleteItem(aItem)
{
if (!(aItem instanceof Components.interfaces.calITodo) ||
this.mBatchCount)
return;
this.todoList.removeTodo(aItem);
},
onModifyItem: function onModifyItem(aNewItem, aOldItem)
{
if (!(aNewItem instanceof Components.interfaces.calITodo) ||
this.mBatchCount)
return;
this.todoList.removeTodo(aOldItem);
this.todoList.addTodo(aNewItem);
},
onError: function onError(aErrNo, aMessage)
{
},
onCalendarAdded: function onCalendarAdded(aCalendar)
{
this.todoList.rebuildDisplay();
},
onCalendarRemoved: function onCalendarRemoved(aCalendar)
{
this.todoList.rebuildDisplay();
},
onDefaultCalendarChanged: function onDefaultCalendarChanged(aCalendar)
{
return;
},
onGetResult: function onGetResult(aCalendar, aStatus, aItemType, aDetail, aCount, aItems)
{
if (!Components.isSuccessCode(aStatus)) {
Components.utils.reportError(
"Failed to fetch todo items: 0x" +
aStatus.toString(16));
return;
}
aItems.forEach(this.todoList.addTodo, this.todoList);
},
onOperationComplete: function onOperationComplete(aCalendar, aStatus, aOperationType, aId,
aDetail)
{
if (!Components.isSuccessCode(aStatus))
Components.utils.reportError("Failed to fetch todo item"
+ "(" + aId + "): 0x" +
aStatus.toString(16));
},
QueryInterface: function QueryInterface(aIID) {
if (!aIID.equals(Components.interfaces.calIObserver) &&
!aIID.equals(Components.interfaces.calICompositeObserver) &&
!aIID.equals(Components.interfaces.calIOperationListener) &&
!aIID.equals(Components.interfaces.nsISupports)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
}
})
]]></field>
<property name="calendar">
<getter><![CDATA[ return this.mCalendar; ]]></getter>
<setter><![CDATA[
if (this.mCalendar)
this.mCalendar.removeObserver(this.mOperationListener);
this.mCalendar = val;
if (this.mCalendar)
this.mCalendar.addObserver(this.mOperationListener);
this.rebuildDisplay();
]]></setter>
</property>
<method name="fireEvent">
<parameter name="aEventType"/>
<body><![CDATA[
var e = document.createEvent("Events");
e.initEvent("todo-" + aEventType, true, true);
this.dispatchEvent(e);
]]></body>
</method>
<method name="addTodo">
<parameter name="aTodo"/>
<body><![CDATA[
void("adding new todo " + aTodo.title + "\n");
var newTodoElt = document.createElement("calendar-todo-item");
newTodoElt.setAttribute("item-calendar", aTodo.calendar.uri.spec);
this.appendChild(newTodoElt);
newTodoElt.todo = aTodo;
]]></body>
</method>
<method name="removeTodo">
<parameter name="aTodo"/>
<body><![CDATA[
// don't use for each, because the 'in' operator will return
// other properties of childNodes as well, which don't have .todo
for (var i=0; i < this.childNodes.length; i++) {
var elem = this.childNodes[i];
if (elem.todo.hasSameIds(aTodo)) {
this.removeChild(elem);
}
}
]]></body>
</method>
<method name="fetchTodos">
<body><![CDATA[
if (!this.mCalendar)
return;
const cIC = Components.interfaces.calICalendar;
var filter = cIC.ITEM_FILTER_TYPE_TODO | cIC.ITEM_FILTER_COMPLETED_ALL;
this.mCalendar.getItems(filter, 0, null, null, this.mOperationListener);
]]></body>
</method>
<method name="rebuildDisplay">
<body><![CDATA[
while (this.firstChild)
this.removeChild(this.firstChild);
this.fetchTodos();
]]></body>
</method>
</implementation>
<handlers>
<handler event="dblclick"><![CDATA[
if (this.selectedItem)
this.fireEvent("item-open");
else
this.fireEvent("empty-dblclick");
]]></handler>
<handler event="keypress"><![CDATA[
const kKE = Components.interfaces.nsIDOMKeyEvent;
if (event.keyCode == kKE.DOM_VK_RETURN ||
event.keyCode == kKE.DOM_VK_ENTER) {
this.fireEvent("item-open");
} else if (event.keyCode == kKE.DOM_VK_BACK_SPACE ||
event.keyCode == kKE.DOM_VK_DELETE) {
this.fireEvent("item-delete");
} else if (event.keyCode == kKE.DOM_VK_SPACE) {
var selected = this.selectedItem;
selected.checkbox.checked = !this.checkbox.checked;
selected.updateTodoFromDisplay();
}
]]></handler>
</handlers>
</binding>
<binding id="calendar-todo-item" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content>
<xul:hbox align="center" flex="1">
<xul:checkbox class="calendar-todo-item-checkbox" anonid="todo-check" xbl:inherits="checked=completed" oncommand="document.getBindingParent(this).updateTodoFromDisplay();"/>
<xul:label class="calendar-todo-item-label" anonid="todo-label" crop="end" xbl:inherits="item-calendar,value=label"/>
</xul:hbox>
</content>
<implementation>
<field name="mTodo">null</field>
<property name="checkbox">
<getter><![CDATA[ return document.getAnonymousElementByAttribute(this, "anonid", "todo-check");]]></getter>
</property>
<property name="manager">
<getter><![CDATA[ return this.mManager; ]]></getter>
<setter><![CDATA[ this.mManager = val; ]]></setter>
</property>
<property name="label">
<getter><![CDATA[ return document.getAnonymousElementByAttribute(this, "anonid", "todo-label");]]></getter>
</property>
<property name="todo" onget="return this.mTodo;"
onset="this.mTodo = val; this.updateDisplayFromTodo();"/>
<method name="setAttribute">
<parameter name="aAttr"/>
<parameter name="aVal"/>
<body><![CDATA[
if (aAttr == "completed")
this.checkbox.setAttribute("checked", aVal);
else if (aAttr == "label")
this.label.setAttribute("value", aVal);
return XULElement.prototype.setAttribute.call(this, aAttr, aVal);
]]></body>
</method>
<method name="updateTodoFromDisplay">
<body><![CDATA[
var dirty = false;
var clone = this.mTodo.clone();
if (this.mTodo.isCompleted != this.checkbox.checked) {
clone.isCompleted = this.checkbox.checked;
dirty = true;
}
if (this.mTodo.title != this.label.value) {
clone.title = this.label.value;
dirty = true;
}
if (dirty) {
this.mTodo.calendar.modifyItem(clone, this.mTodo, null);
// dump(clone.icalComponent.serializeToICS() + "\n");
this.mTodo = clone;
}
]]></body>
</method>
<method name="updateDisplayFromTodo">
<body><![CDATA[
this.setAttribute("completed", this.mTodo.isCompleted);
this.setAttribute("label", this.mTodo.title);
]]></body>
</method>
</implementation>
</binding>
</bindings>