123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543 |
- /********************************************************************************************************************************
- * 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 agent items listener the agent listener
- the items listener, watches for topic changes in the text and adjusts the
- agent items tree when text corresponding to topics is deleted.... this also checks all other references
- to topics within all tasks in the agent... and the state is restored onload
- the text listener, keeps stacks of the versions of text in each dropzone visible.... the state of these stacks are not
- maintained from page to page or on save or load as they are only used by the undo / redo functionality.
- /**
- when a page is created, the dropzone fields are registered here and the contents cached. we recieve onBlur events
- with the updated contents and do a diff to see the changes in model item references. we also track whole groups of dz fields
- whose names are dynamically generated and liable tom change from visit to visit (to the relevant page)there is a unique group id that is used when the group is created or added....
- the id is currently just the unique task id, so were making the rather bold assumption that there is only one group of dynamic form fields per task
- @author mannn
- */
- function AgentItemsListener(){
- //quick count of how many refs per topic
- this.referenceTracker = new AgentItemsReferenceTracker();
- //hold on to the field-contents in groups by id
- this.all_field_sets = new Object();
- //hold on to the dynamic field-contents in groups by id
- this.dynamic_field_group = new Object();
- //this is the working set.... of currently visible fields - organised by holding frames
- this.frameIds = new FrameIdentification();
- //report task list
- this.reportTasks = new Object()
- }
- /*
- a little light debuggage....
- */
- AgentItemsListener.prototype.displayState = function(){
- var message = " ******* agent items tracking ******* \n";
-
- for(var field_set_id in this.all_field_sets){
-
- message += field_set_id + "\n";
-
- var field_set = this.all_field_sets[field_set_id];
-
- for(var field_name in field_set){
-
- var topics = field_set[field_name].getTopics();
-
- message += " " + field_name;
-
- var topics_section = " (";
- for(var i = 0; i < topics.length; i++){
- topics_section += i == 0 ? "" : ", ";
- topics_section += topics[i];
- }
- message += topics_section + ")\n";
- }
-
- var dynamic_group = this.dynamic_field_group[field_set_id];
-
- if(dynamic_group){
- message += " field group ";
- var group_section = " (";
- for(var i = 0; i < dynamic_group.fieldContents.length; i++){
- group_section += i == 0 ? "" : ", ";
- group_section += dynamic_group.fieldContents[i].fieldName;
- }
- message += group_section + ")\n";
- }
-
- if(getRedoUndoManager().taskDeleteHistory.peek()){
- message += " tracking " + getRedoUndoManager().taskDeleteHistory.members.length + "deleted tasks\n";
- }
- }
-
- //ref counts
- message += this.referenceTracker.toString();
-
- for(var id in this.reportTasks){
- message += "\n" + this.reportTasks[id].toString();
- }
- alert(message);
- }
- /*
- sort of singleton method to retutrn the one instance*
- */
- function getAgentItemsListener(){
- if(!agentItemsListener){
- agentItemsListener = new AgentItemsListener()
- }
-
- return agentItemsListener;
- }
- //a frame has been hidden... the drop zones registered against it
- //are no longer showing
- AgentItemsListener.prototype.frameHidden = function(frameName){
- this.frameIds.clearFrame(frameName);
- }
- //some groups of dropzones can change their ids... i.e. calculations
- //can be renamed and their name is used to track the references
- AgentItemsListener.prototype.updateId = function(new_id, old_id, frameName){
- var field_set = this.all_field_sets[old_id];
-
- delete this.all_field_sets[old_id];
- this.all_field_sets[new_id] = field_set;
-
- for(var aName in field_set){
- field_set[aName].id = new_id;
- }
-
- //now let the frameIds holder know
- this.frameIds.addFrameId(new_id, frameName);
- }
- //called from the report and agent pages
- //holds data about report tasks and the paths
- AgentItemsListener.prototype.setReportTask = function(id, name, reportPath){
- var reportTask = new ReportTaskAssignments(id, name, reportPath);
-
- this.reportTasks[id] = reportTask;
- }
- AgentItemsListener.prototype.getReportTaskAssignments = function(){
-
- var reportTasksPa = new Array();
-
- for(var field_set_id in this.reportTasks){
- var reportTask = this.reportTasks[field_set_id];
-
- //dont do nuffink for duds
- if(!reportTask)continue;
-
- //update the pas
- reportTask.parameterAssignments = new Array();
-
- var field_set = this.all_field_sets[field_set_id];
-
- for(var field_name in field_set){
-
- var topics = field_set[field_name].getTopics();
-
- for(var i = 0; topics && i < topics.length; i++){
-
- reportTask.parameterAssignments.push(new ParameterAssignment(field_name, topics[i]));
- }
- }
-
- reportTasksPa.push(reportTask);
- }
-
- return reportTasksPa;
- }
- //this can be called when deleting a task...
- // we remove all references to any topics held against that task id
- //and add them to the special task action stack
- AgentItemsListener.prototype.removeAllReferencesById = function(id){
-
- var field_set = this.getFieldSet(id);
-
- if(getRedoUndoManager().isDeletedTask(id)){
- //weve seen this one before;
- return;
- }
-
- var task_deletes = new Array();
-
- for(var field in field_set){
- //this removes references
- task_deletes = task_deletes.concat(this.removeField(field, id));
- }
-
- var eab = new TaskEditActionBundle(null, id);
-
- for(var i = 0; i < task_deletes.length; i++){
- eab.addEditAction(new DeleteItemEditAction(task_deletes[i]));
- }
-
- //save the deletes in case we change our mind
- getRedoUndoManager().taskDeleteHistory.push(eab);
-
- delete this.all_field_sets[id];
-
- delete this.dynamic_field_group[id];
- if(this.reportTasks[id]){
- delete this.reportTasks[id];
- }
- }
- //here we check that we have the id....and field if not create it and / or add the field and any value...
- //question is.. do we add the agent item here in this case?? I think we just hang on to the ref
- //if we have the id and field, then just flag the id as the current one
- //use a frame name to distinguish dialogd open in diffent frames on the page
- AgentItemsListener.prototype.registerField = function(fieldName, id, initialValue, frameName){
- if(!id){
- //bin out
- return;
- }
-
- //track which tabs are showing
- this.frameIds.addFrameId(id, frameName);
-
- var field = this.getFieldSet(id)[fieldName];
-
- if(!field){
- field = new FieldContent(fieldName, id, initialValue)
- //probably a new field from a new task
- this.addField(field, id);
- }
-
- //check that the field contents havent changed
- this.updateField(fieldName, initialValue);
- }
- /*
- topic has been dropped into this field
- */
- AgentItemsListener.prototype.addItemToField = function(fieldName, item) {
- //DataItems we created (calculations) should not be deleted when
- //They are removed from drop zones.
- if (item && item != "undefined") {
- this.addTopicToField(fieldName, item.getDropValue());
- }
- }
- /*
- topic has been dropped into this field
- */
- AgentItemsListener.prototype.addTopicToField = function(fieldName, topic_value){
-
- //alert("add topic");
- var current_field_set = this.getCurrentFieldSet();
-
- //Check if we can add the topic
- var canAdd = (topic_value && topic_value.length && topic_value.length > 2 && topic_value.charAt(0) == "[" && topic_value.charAt(topic_value.length - 1) == "]");
- if(!current_field_set[fieldName] || !canAdd){
- //alert("delete listener trying to update unregistered field");
- return;
- }
- //add the reference to the field
- current_field_set[fieldName].addTopic(topic_value);
- //hang on to the count
- this.referenceTracker.addReference(topic_value);
- }
- /*
- topics have been dropped into this field (by an undo)
- so we dont add topics if we already know about them
- */
- AgentItemsListener.prototype.redoUndoTopicsUpdate = function(fieldName, new_value){
-
- //alert("redoUndoTopicsUpdate");
-
- var current_field_set = this.getCurrentFieldSet();
-
- if(!current_field_set[fieldName]){
- //alert("delete listener trying to update unregistered field");
- return;
- }
-
- if(!new_value){
- new_value = "";
- }
-
- var topic_objects = findTopicsInContent(new_value);
-
- for(var i = 0; i < current_field_set[fieldName].getTopics().length; i++){
-
- for(var j = 0; j < topic_objects.length; j++) {
- if(topic_objects[j] == current_field_set[fieldName].getTopics()[i]){
- topic_objects.splice(j, 1);
- break;
- }
- }
- }
-
- for(var i = 0; i < topic_objects.length; i++){
-
- //add the reference to the field
- current_field_set[fieldName].addTopic(topic_objects[i]);
-
- //hang on to the count
- this.referenceTracker.addReference(topic_objects[i]);
- }
-
- current_field_set[fieldName].setContent(new_value);
- var removed_topics = current_field_set[fieldName].checkForRemovedTopics();
-
- //remove the topics
- var deleted_ref_objects = this.referenceTracker.removeReferences(removed_topics);
-
- }
- /*
- topic has been dropped into this field
- */
- AgentItemsListener.prototype.removeTopicFromField = function(fieldName, topic_value){
-
- //alert("remove topic");
-
- var current_field_set = this.getCurrentFieldSet();
-
- if(!current_field_set[fieldName]){
- //alert("delete listener trying to update unregistered field");
- return;
- }
-
- //add the reference to the field
- current_field_set[fieldName].removeTopic(topic_value);
-
- //hang on to the count
- this.referenceTracker.removeReference(topic_value);
- }
- /*
- we have a possible chane to the contents fo a field, so look for the topics we think
- are in the field. If we cant find them... assume they have been blattered and
- remove the referenece
- */
- AgentItemsListener.prototype.updateField = function(fieldName, new_value){
-
- var current_field_set = this.getCurrentFieldSet();
-
- var field = current_field_set[fieldName];
-
- if(!field || field.getContent() == new_value){
- return
- }
-
- getRedoUndoManager().updateField(fieldName, new_value, field.getContent());
-
- field.setContent(new_value);
-
- var removed_topics = field.checkForRemovedTopics();
-
- //remove the topic refs
- this.referenceTracker.removeReferences(removed_topics);
- }
- AgentItemsListener.prototype.isValidField = function(fieldName, id){
- return this.getFieldSet(id)[fieldName];
- }
- //return the set of fields by id
- AgentItemsListener.prototype.getFieldSet = function(id){
-
- var field_set = this.all_field_sets[id];
-
- if(!field_set){
- field_set = new Object();
- this.all_field_sets[id] = field_set;
- }
-
- return field_set;
- }
- //this returns an amalgam of field sets
- //containing the field contents of all visible frames
- AgentItemsListener.prototype.getCurrentFieldSet = function(){
-
- var currentFieldSet = new Object();
-
- var ids = this.frameIds.getCurrentIds();
-
- for(var i = 0; i < ids.length; i++){
- var field_set = this.all_field_sets[ids[i]];
-
- if(!field_set){
- field_set = new Object();
- this.all_field_sets[id] = field_set;
- }else{
- for(var field in field_set){
- //copy the field set reference to the return object
- currentFieldSet[field] = field_set[field];
- }
- }
- }
-
- return currentFieldSet;
- }
- //return the set of fields by id
- AgentItemsListener.prototype.getFieldContent = function(fieldName, id){
-
- return this.getFieldSet(id)[fieldName];
- }
- //we are interested in tracking the changes that happened dynamically to this group of
- //dynamic fields.... the changes to individual fields will
- //take place through the other update method.. and should already be registered
- //so this is only interested in removal of a whole field
- //NB this kind of thing is forced externally, and so is not undoable
- AgentItemsListener.prototype.registerDynamicGroup = function(updatedFieldContents, id, frameName){
-
- //track which tabs are showing
- this.frameIds.addFrameId(id, frameName);
-
- if(!id || id == ""){
- //shhh
- //alert("delete listener trying to use an undefined id");
- }
-
- var dfg = this.dynamic_field_group[id];
- if(!dfg){
- //this is a new task
- dfg = this.makeFieldGroup(updatedFieldContents, id);
- this.dynamic_field_group[id] = dfg;
- }else{
- //do the diffs
- new_dfg = this.makeFieldGroup(updatedFieldContents, id);
- new_dfg.update();
-
- this.dynamic_field_group[id] = new_dfg;
- }
- }
- /////////////////////
- // initialisation and update methods for use on load, and when the agent changes to remove fields from the
- ////////////////////
- /**
- fieldName - an env param name to hold on to as valid
- **/
- AgentItemsListener.prototype.addField = function(fieldContents){
- var current_field_set = this.getFieldSet(fieldContents.id);
-
- if(current_field_set){
- var existingFieldContents = current_field_set[fieldContents.fieldName];
-
- if(!existingFieldContents){
- //ask the wise old tree
- var topics = findTopicsInContent(fieldContents.fieldContent);
-
- fieldContents.topics = topics;
- current_field_set[fieldContents.fieldName] = fieldContents;
-
- //tot up the topics
- this.referenceTracker.addReferences(topics);
- }
- }
- }
- /*
- get rid of a field that has been registered and take its references with it
- we hang on to the agent item changes but not the text changes here.... as its task delete
- or a field removed from a field group
- */
- AgentItemsListener.prototype.removeField = function(fieldName, task_id){
- var current_field_set = this.getFieldSet(task_id);
- var deleted_items;
-
- if(current_field_set){
- var fieldContents = current_field_set[fieldName];
- if (fieldContents != undefined){
- deleted_items = this.referenceTracker.removeReferences(fieldContents.getTopics());
-
- }
- delete current_field_set[fieldName];
- }
-
- return deleted_items;
- }
- AgentItemsListener.prototype.addDynamicGroup = function(fieldContentArray, id){
-
- this.dynamic_field_group[id] = this.makeFieldGroup(fieldContentArray, id);
- }
- AgentItemsListener.prototype.makeFieldGroup = function(fieldContentArray, id){
- var dfg;
- //this is a new dynamic group
- dfg = new DynamicFieldGroup(fieldContentArray, id);
-
- return dfg;
- }
- /*
- this holds one id per frame
- for as many frames as you care to have
- */
- function FrameIdentification(){
- this.frameSet = new Object();
-
- }
- //return all current ids
- FrameIdentification.prototype.getCurrentIds = function(){
- var allFrames = new Array();
-
- for(var aFrame in this.frameSet){
- if(this.frameSet[aFrame]){
- allFrames.push(this.frameSet[aFrame]);
- }
- }
-
- return allFrames;
- }
- //clear the id assoc with a frame and return the deleted id
- FrameIdentification.prototype.clearFrame = function(frameName){
- var current_id = this.frameSet[frameName];
- delete this.frameSet[frameName];
- return current_id;
- }
- //set a new registration and return any old ones
- FrameIdentification.prototype.addFrameId = function(id, frameName){
- var current_id = this.frameSet[frameName];
- var old_id;
-
- if(current_id && current_id != id){
- old_id = current_id;
- }
-
- //this is a new registration
- this.frameSet[frameName] = id;
-
- return old_id;
- }
- var agentItemsListener;;
-
|