bug #369262 undo/redo stack needs to be in a component. patch by bugzilla@kewis.ch, r=mickey

This commit is contained in:
michael.buettner%sun.com 2007-03-21 13:36:05 +00:00
Родитель 046d985c2a
Коммит 8f557b6620
6 изменённых файлов: 51 добавлений и 125 удалений

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

@ -21,6 +21,7 @@
* Contributor(s):
* Stuart Parmenter <stuart.parmenter@oracle.com>
* Robin Edrenius <robin.edrenius@gmail.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -286,141 +287,43 @@ function setDefaultAlarmValues(aItem)
}
// Undo/Redo code
var gTransactionMgr = Components.classes["@mozilla.org/transactionmanager;1"]
.createInstance(Components.interfaces.nsITransactionManager);
function getTransactionMgr() {
return Components.classes["@mozilla.org/calendar/transactionmanager;1"]
.getService(Components.interfaces.calITransactionManager);
}
function doTransaction(aAction, aItem, aCalendar, aOldItem, aListener) {
var txn = new calTransaction(aAction, aItem, aCalendar, aOldItem, aListener);
gTransactionMgr.doTransaction(txn);
getTransactionMgr().createAndCommitTxn(aAction,
aItem,
aCalendar,
aOldItem,
aListener);
updateUndoRedoMenu();
}
function undo() {
gTransactionMgr.undoTransaction();
getTransactionMgr().undo();
updateUndoRedoMenu();
}
function redo() {
gTransactionMgr.redoTransaction();
getTransactionMgr().redo();
updateUndoRedoMenu();
}
function startBatchTransaction() {
gTransactionMgr.beginBatch();
getTransactionMgr().beginBatch();
}
function endBatchTransaction() {
gTransactionMgr.endBatch();
getTransactionMgr().endBatch();
updateUndoRedoMenu();
}
function canUndo() {
return (gTransactionMgr.numberOfUndoItems > 0);
return getTransactionMgr().canUndo();
}
function canRedo() {
return (gTransactionMgr.numberOfRedoItems > 0);
}
// Valid values for aAction: 'add', 'modify', 'delete', 'move'
// aOldItem is only needed for aAction == 'modify'
function calTransaction(aAction, aItem, aCalendar, aOldItem, aListener) {
this.mAction = aAction;
this.mItem = aItem;
this.mCalendar = aCalendar;
this.mOldItem = aOldItem;
this.mListener = aListener;
}
calTransaction.prototype = {
mAction: null,
mItem: null,
mCalendar: null,
mOldItem: null,
mOldCalendar: null,
mListener: null,
mIsDoTransaction: false,
QueryInterface: function (aIID) {
if (!aIID.equals(Components.interfaces.nsISupports) &&
!aIID.equals(Components.interfaces.nsITransaction) &&
!aIID.equals(Components.interfaces.calIOperationListener))
{
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
onOperationComplete: function(aCalendar, aStatus, aOperationType, aId, aDetail) {
if (aStatus == Components.results.NS_OK) {
if (aOperationType == Components.interfaces.calIOperationListener.ADD ||
aOperationType ==Components.interfaces.calIOperationListener.MODIFY) {
// Add/Delete return the original item as detail for success
if (this.mIsDoTransaction) {
this.mItem = aDetail;
} else {
this.mOldItem = aDetail;
}
}
} else {
Components.utils.reportError("Severe error in internal transaction code!\n" +
aDetail + '\n'+
"Please report this to the developers.\n");
}
if (this.mListener) {
this.mListener.onOperationComplete(aCalendar, aStatus, aOperationType, aId, aDetail);
}
},
onGetResult: function(aCalendar, aStatus, aItemType, aDetail, aCount, aItems) {
if (this.mListener) {
this.mListener.onGetResult(aCalendar, aStatus, aItemType, aDetail, aCount, aItems);
}
},
doTransaction: function () {
this.mIsDoTransaction = true;
switch (this.mAction) {
case 'add':
this.mCalendar.addItem(this.mItem, this);
break;
case 'modify':
this.mCalendar.modifyItem(this.mItem, this.mOldItem,
this);
break;
case 'delete':
this.mCalendar.deleteItem(this.mItem, this);
break;
case 'move':
this.mOldCalendar = this.mOldItem.calendar;
this.mOldCalendar.deleteItem(this.mOldItem, this);
this.mCalendar.addItem(this.mItem, this);
break;
}
},
undoTransaction: function () {
this.mIsDoTransaction = false;
switch (this.mAction) {
case 'add':
this.mCalendar.deleteItem(this.mItem, this);
break;
case 'modify':
this.mCalendar.modifyItem(this.mOldItem, this.mItem, this);
break;
case 'delete':
this.mCalendar.addItem(this.mItem, this);
break;
case 'move':
this.mCalendar.deleteItem(this.mItem, this);
this.mOldCalendar.addItem(this.mOldItem, this);
break;
}
},
redoTransaction: function () {
this.doTransaction();
},
isTransient: false,
merge: function (aTransaction) {
// No support for merging
return false;
}
return getTransactionMgr().canRedo();
}
/**

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

@ -21,6 +21,7 @@
# Dan Mosedale <dan.mosedale@oracle.com>
# Mike Shaver <shaver@off.net>
# Matthew Willis <lilmatt@mozilla.com>
# Philipp Kewisch <mozilla@kewis.ch>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -77,6 +78,7 @@ XPIDLSRCS = calIAlarmService.idl \
calIDateTimeFormatter.idl \
calIWeekTitleService.idl \
calIPrintFormatter.idl \
calITransactionManager.idl \
$(NULL)
EXPORTS = calBaseCID.h

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

@ -21,6 +21,7 @@
#
# Contributor(s):
# Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
# Philipp Kewisch <mozilla@kewis.ch>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
@ -93,6 +94,7 @@ EXTRA_SCRIPTS = \
calTodo.js \
calUtils.js \
calWeekTitleService.js \
calTransactionManager.js \
$(NULL)
# Use NSINSTALL to make the directory, as there's no mtime to preserve.

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

@ -23,6 +23,7 @@
* Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
* Mike Shaver <shaver@off.net>
* Matthew Willis <lilmatt@mozilla.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -163,7 +164,12 @@ const componentData =
{cid: Components.ID("{207a6682-8ff1-4203-9160-729ec28c8766}"),
contractid: "@mozilla.org/calendar/ics-serializer;1",
script: "calIcsSerializer.js",
constructor: "calIcsSerializer"}
constructor: "calIcsSerializer"},
{cid: Components.ID("{40a1ccf4-5f54-4815-b842-abf06f84dbfd}"),
contractid: "@mozilla.org/calendar/transactionmanager;1",
script: "calTransactionManager.js",
constructor: "calTransactionManager"}
];
var calItemModule = {

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

@ -27,6 +27,7 @@
* Stefan Sitter <ssitter@googlemail.com>
* Thomas Benisch <thomas.benisch@sun.com>
* Michael Buettner <michael.buettner@sun.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -124,12 +125,12 @@ var CalendarController =
break;
case "cmd_undo":
if (this.isCalendarInForeground() && canUndo()) {
gTransactionMgr.undoTransaction();
getTransactionMgr().undo();
}
break;
case "cmd_redo":
if (this.isCalendarInForeground() && canRedo()) {
gTransactionMgr.redoTransaction();
getTransactionMgr().redo();
}
break;
case "cmd_print":

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

@ -29,6 +29,7 @@
* Matthew Willis <lilmatt@mozilla.com>
* Joey Minta <jminta@gmail.com>
* Dan Mosedale <dan.mosedale@oracle.com>
* Philipp Kewisch <mozilla@kewis.ch>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -128,6 +129,9 @@ function calendarInit()
getViewDeck().addEventListener("dayselect", observeViewDaySelect, false);
getViewDeck().addEventListener("itemselect", onSelectionChanged, true);
// Setup undo/redo menu for additional main windows
updateUndoRedoMenu();
// Handle commandline args
for (var i=0; i < window.arguments.length; i++) {
try {
@ -476,15 +480,23 @@ function CalendarToolboxCustomizeDone(aToolboxChanged)
}
function updateUndoRedoMenu() {
if (gTransactionMgr.numberOfUndoItems)
document.getElementById('undo_command').removeAttribute('disabled');
else
document.getElementById('undo_command').setAttribute('disabled', true);
// We need to make sure the menu is updated on all main windows
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var enumerator = wm.getEnumerator('calendarMainWindow');
while (enumerator.hasMoreElements()) {
var doc = enumerator.getNext().document;
if (gTransactionMgr.numberOfRedoItems)
document.getElementById('redo_command').removeAttribute('disabled');
else
document.getElementById('redo_command').setAttribute('disabled', true);
if (getTransactionMgr().canUndo())
doc.getElementById('undo_command').removeAttribute('disabled');
else
doc.getElementById('undo_command').setAttribute('disabled', true);
if (getTransactionMgr().canRedo())
doc.getElementById('redo_command').removeAttribute('disabled');
else
doc.getElementById('redo_command').setAttribute('disabled', true);
}
}
function openLocalCalendar() {