123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- /********************************************************************************************************************************
- * Licensed Materials - Property of IBM *
- * *
- * IBM Cognos Products: AGS *
- * *
- * (C) Copyright IBM Corp. 2005, 2008 *
- * *
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *
- *********************************************************************************************************************************/
- /*
- this file holds the undo redo functionality for text and topics in dropzones
- the undo functions maintain stacks of actions and undoneActions.... these are stacked and unstacked as necessary and can be
- agent items delete / add or text add / delete. if an agent item add is undone it is removed from the tree and added to the undone stack
- from where it can be redone. for text changes (triggered by the blur or delete events)the text versions are stacked up in the agent items listener structure FieldContents
- */
- var redoUndoManager = new RedoUndoManager();
- function getRedoUndoManager(){
- return redoUndoManager;
- }
- function RedoUndoManager(){
- //do we batch reversable actions or not
- //if yes batch them and put them all on the undo stack together
- //otherwise stack them now
- this.editActionBatching;
- // undo/redo variables... the array is used as a stack
- this.actionHistory = new Stack();
- this.undoneHistory = new Stack();
-
- //these have to be separate as they are the only actions that survive the page
- this.taskDeleteHistory = new Stack();
- }
- RedoUndoManager.prototype.startEditActionBatch = function(){
- this.editActionBatching = new Array();
- }
- RedoUndoManager.prototype.isEditActionBatching = function(){
- return this.editActionBatching != undefined;
- }
- RedoUndoManager.prototype.getEditActionBatch = function(){
- return this.editActionBatching;
- }
- RedoUndoManager.prototype.stopEditActionBatch = function (){
-
- this.getActionHistory().push(new EditActionBundle(this.editActionBatching));
-
- this.editActionBatching = undefined;
- }
- /**
- *function to allow external code to put atcionts in the undo / redo stacks
- */
- RedoUndoManager.prototype.getActionHistory = function(){
- return this.actionHistory;
- }
- /**
- *function to allow external code to put atcionts in the undo / redo stacks
- */
- RedoUndoManager.prototype.getUndoneHistory = function(){
- return this.undoneHistory;
- }
- /**
- *a field has changed
- */
- RedoUndoManager.prototype.updateField = function(fieldName, new_value, old_value){
- //ahh a nice tea
- var tea = new TextEditAction(new FormObjectHandler(fieldName), new_value, old_value);
-
- var eab = new EditActionBundle(new Array(tea));
-
- if(this.isEditActionBatching()){
- this.getEditActionBatch().push(eab);
- }else{
- this.getActionHistory().push(eab);
- }
-
- this.getUndoneHistory().clear();
- }
- /*
- * check for a valid undo step
- */
- RedoUndoManager.prototype.canUndoTreeAction = function() {
-
- return getActionHistory().peek() != null;
- }
- /*
- * Reset the tree action state
- */
- RedoUndoManager.prototype.clearAgentItemsTracking = function() {
- agentItemsListener = new AgentItemsListener();
- this.getActionHistory().clear();
- this.getUndoneHistory().clear();
-
- this.taskDeleteHistory.clear();
- }
- /*
- * Reset the tree action state
- */
- RedoUndoManager.prototype.resetTreeAction = function() {
- //alert('calling resetTreeAction');
- this.getActionHistory().clear();
- this.getUndoneHistory().clear();
- }
- /*
- check whether this task has been deleted by interogating the taskDeleteHistory stack
- */
- RedoUndoManager.prototype.isDeletedTask = function(taskId){
- var foundBundle = null;
-
- foundBundle = this.taskDeleteHistory.search(new taskDeleteStackSearcher(taskId));
-
- return foundBundle && foundBundle.length ? foundBundle.length > 0 : false;
- }
- function taskDeleteStackSearcher(taskId){
- this.searchTaskId = taskId;
-
- this.search = function(editActionBundle){
- if(this.searchTaskId == editActionBundle.taskId){
- return true;
- }else{
- return false;
- }
- }
- }
- /*
- * Switch the last tree action as a result of an undo/redo,
- * so that if an item was just added, then we delete it and vice versa
- */
- RedoUndoManager.prototype.redoLastEditAction = function() {
- //alert("redo");
- var success=false;
-
- if (this.undoneHistory.peek() != null) {
-
- var undoneAction = this.undoneHistory.pop();
-
- success = this.doEditAction(undoneAction, false);
-
- if(success){
- this.actionHistory.push(undoneAction);
- }
- }
-
- return success;
- }
- /*
- * take an EditAction and carry it out....
- * undo is a boolean indicating whether we are undo or redo
- */
- RedoUndoManager.prototype.doEditAction = function(editAction, undo) {
- var success=true;
-
- //do the bundles contents recursively
- if(editAction instanceof EditActionBundle){
- if(undo){
- for(var i = editAction.editActions.length - 1; i >= 0 && success; i--){
- success = success && this.doEditAction(editAction.editActions[i], undo);
- }
- }else{
- for(var i = 0; i < editAction.editActions.length && success; i++){
- success = success && this.doEditAction(editAction.editActions[i], undo);
- }
- }
-
- return success;
- }
-
- //perform the action
- if ((editAction instanceof DeleteItemEditAction && undo) || (editAction instanceof AddItemEditAction && !undo)) {
- //alert('adding '+editAction.outerHTML+' to the agent items tree');
- //just get the original object and recreate it
- success = addUnknownItem(editAction.refObject.getValue(), true);
- }else if(editAction instanceof TextEditAction){
- var value;
-
- if(undo){
- value = editAction.originalText;
- }else{
- value = editAction.editedText;
- }
-
- editAction.editorObject.setFormObjectValue(value);
- var domObjectId = editAction.editorObject.form_object_id;
-
- //keep the agent items listener up to date
- getAgentItemsListener().redoUndoTopicsUpdate(domObjectId,value);
- //keep the focus
- if (editAction.editorObject != undefined) {
- editAction.editorObject.getFormObject().focus();
- }
- }else if((editAction instanceof DeleteItemEditAction && !undo) || (editAction instanceof AddItemEditAction && undo)){
- //alert('deleting '+editAction.outerHTML+' from the agent items tree');
- //undefined result for delete is a success... so leave it
- deleteDataItemNode(editAction.refObject,true) ;
- }else{
- success = false;
- }
- return success;
- }
- /*
- * Switch the last tree action as a result of an undo/redo,
- * so that if an item was just added, then we delete it and vice versa
- */
- RedoUndoManager.prototype.reverseLastEditAction = function() {
-
- //alert("undoing");
- var success=false;
-
- if (this.actionHistory.peek() != null) {
-
- var editAction = this.actionHistory.pop();
-
- //do the undo do
- success = this.doEditAction(editAction, true);
-
- if(success){
- this.undoneHistory.push(editAction);
- }
-
- }else if(this.taskDeleteHistory.peek()){
- //we have a task delete to undo... hold your breath
-
- //undo the tree changes
- this.doEditAction(this.taskDeleteHistory.pop(), true);
-
- //on your knees morphlet
- var msgFrame = getMessageIFrame();
- var msgDoc = getFrameDocument(msgFrame);
-
- // only undo task delete
- if(msgDoc.pform.m.value.indexOf("dialogAdapter")!= -1) {
- //set the dialog morphlet
- msgDoc.pform.m.value="/ags/dialogAdapter.xts";
-
- if(msgDoc.pform.m.value){
- msgDoc.pform.agentItemOp.value="undo";
- }else{
- messageForm.appendChild(createHiddenInput(msgDoc, "agentItemOp", "undo"));
- }
- }
- msgDoc.pform.submit();
- }
-
- return success;
- }
- //wraps a group of actions to be rolled back
- // or forward at the same time
- function EditActionBundle(editActions){
- if(editActions && editActions.length && editActions.length > 0){
- this.editActions = editActions;
- }else{
- this.editActions = new Array();
- }
- }
- function TaskEditActionBundle(editActions, taskId){
- var eab = new EditActionBundle(editActions);
-
- eab.taskId = taskId;
-
- return eab;
- }
- EditActionBundle.prototype.addEditAction = function(editAction){
- if(editAction){
- this.editActions.push(editAction);
- }
- }
- function DeleteItemEditAction(refObject){
- this.refObject = refObject;
- }
- function AddItemEditAction(refObject){
- this.refObject = refObject;
- }
- function TextEditAction(editor_object, edited_text, original_text){
- this.editorObject = editor_object;
- this.editedText = edited_text;
- this.originalText = original_text;
- }
- //this wraps the form elements used in the undo redo
- //as their not all the same
- function FormObjectHandler(form_object_id){
- this.form_object_id = form_object_id;
- this.form_object;
- }
- FormObjectHandler.prototype.getFormObject = function(){
- if(!this.form_object){
- this.form_object = agsFormUtils.getElementByIdOrName(this.form_object_id);
- }
- return this.form_object;
- }
-
- FormObjectHandler.prototype.getFormObjectValue = function(){
- var cf = getConfigFrame();
- var v_sFrame = getFrame(cf.dropFrame);
- if(v_sFrame && v_sFrame.droppy ){
- return v_sFrame.droppy.getDropZoneValue(this.form_object_id);
- } else {
- if(this.getFormObject().value != undefined){
- return this.getFormObject().value;
- }else if(this.getFormObject().innerHTML != undefined){
- return this.getFormObject().innerHTML;
- }
- }
- }
-
- FormObjectHandler.prototype.setFormObjectValue = function(new_value){
-
- var cf = getConfigFrame();
- var v_sFrame = getFrame(cf.dropFrame);
- if(v_sFrame && v_sFrame.droppy ){
- v_sFrame.droppy.setElementValue(this.form_object_id, new_value);
- }else{
- if(this.getFormObject().value != undefined){
- this.getFormObject().value = new_value;
- }else if(this.getFormObject().innerHTML != undefined){
- this.getFormObject().innerHTML = new_value;
- }
- }
- //now perform any custom actions if we need to
- if (v_sFrame.postEditAction) {
- v_sFrame.postEditAction();
- }
- }
|