
| Current Path : /var/www/web-klick.de/dsh/90_akt/DEV1303/AutoQX/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/web-klick.de/dsh/90_akt/DEV1303/AutoQX/TestTreeControl.js |
/* ************************************************************************
Copyright:
License:
Authors:
************************************************************************ */
/* ************************************************************************
#asset(autotest/*)
************************************************************************ */
/**
* This class defines the logic needed for the TestTree
*/
qx.Class.define("autotest.TestTreeControl", {
extend : qx.application.Standalone,
/**
* The constructor handles the initializations for every testtree screen
*
* @param testtree_screen - a qooxdoo container for the testtree etc
* @param rpc_url - a string containing the rpc url
* @param rpc_service - a string containing the rpc service (method to call)
*/
construct : function(testtree_screen, rpc_url, rpc_service, tabView, parent) { // Call super class
this.base(arguments);
qx.Class.include(qx.ui.treevirtual.TreeVirtual,qx.ui.treevirtual.MNode);
this.tabView = tabView;
this.testtree_screen = testtree_screen;
this.rpc_url = rpc_url;
this.rpc_service = rpc_service;
this.rpc = new qx.io.remote.Rpc().set({url:rpc_url,serviceName:rpc_service});
this.parent=parent;
this.rpcMutex=false;
this.run_mutex=false;
},
members : {
colorMap : {
1 : "background-color: #66FF66;",
5 : "background-color: #CCFF99;",
10 : "background-color: #00CC00;",
15 : "background-color: #66FF00;",
20 : "background-color: #CCFF66;",
25 : "background-color: #FFFF66;",
30 : "background-color: #FFFF00;",
35 : "background-color: #FFCC33;",
40 : "background-color: #FF9933;",
1000 : "background-color: red;",
9902 : "background-color: #3399FF;"
},
// Label formats:
f_big : {font: qx.bom.Font.fromString("18px sans-serif")},
f_normal : {font: qx.bom.Font.fromString("13px sans-serif")},
/**
* initialization method for the testtree screen
* clears the screen, sets layouts and runs a rpc call for the testtree
* @param testtree_path
* @param testproject_name
*/
init : function (testtree_path,testproject_name, user) {
this.info("init(): called with params ",testtree_path,testproject_name,user);
this.user=user;
this.testtree_screen.removeAll();
this.testtree_screen.setLayout (new qx.ui.layout.VBox(20));
this.akt_testtree_path = testtree_path;
this.testTree = new qx.ui.treevirtual.TreeVirtual(["Item","Result", "Remark"]);
this.testTree.set({minWidth: 300, rowHeight:20, width:Math.floor(qx.bom.Viewport.getWidth()*0.3), maxWidth:500});
this.testTree.setSelectionMode(qx.ui.treevirtual.TreeVirtual.SelectionMode.MULTIPLE_INTERVAL);
for (var i in this.testTree._getPaneScrollerArr()){
this.testTree._getPaneScrollerArr()[i].setLiveResize(true);
}
// set column width
this.testTree.getTableColumnModel().getBehavior().setMinWidth(0, 150);
this.testTree.getTableColumnModel().getBehavior().setMinWidth(1, 30);
this.testTree.getTableColumnModel().getBehavior().setMinWidth(2, 60);
this.testtree_pane = new qx.ui.splitpane.Pane("horizontal");
this.setMultiItemView();
this.setSingleItemView();
this.testtree_pane.add(this.testTree,0);
this.testtree_pane.add(this.singleItemView,1);
this.singleItemView.setEnabled(false);
this.testtree_screen.add(this.testtree_pane);
this.testTree.addListener("treeOpenWithContent",this.createChildren, this);
this.testTree.addListener("cellClick", this.cellClicked, this);
this.dataModel = this.testTree.getDataModel(); // tree data model
this.itemParent = null;
this.testItem = null;
this.nodeDictionary = {};
this.parentDictionary = {};
this.rpc_call([qx.lang.Function.bind(this.appendChildren,this),
"report",this.akt_testtree_path,"","-1"]);
},
/**
* setup for multi item view
*/
setMultiItemView : function () {
var selectedItems = new qx.ui.basic.Label("").set({allowGrowY: true, rich: true});
var runButton = new qx.ui.form.Button("run selected Items");
runButton.addListener("execute",this.run_selected_testitems, this);
this.multiItemView = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
this.multiItemView.add(selectedItems, {left:'2%',right:'2%' ,top:10});
this.multiItemView.add(runButton, {left:'30%' ,top:20});
this.multiItemView["selectedItems"]=selectedItems;
},
/**
* setup for single item view
*/
setSingleItemView : function() {
this.itemPath = "";
// Create container
this.singleItemViewContainer = new qx.ui.container.Composite(new qx.ui.layout.Canvas());
var scroller = new qx.ui.container.Scroll(this.singleItemViewContainer).set({height:this.testtree_pane.getHeight()});
//this.description
this.descr = new qx.ui.basic.Label("<b>Item Name:</b><br><br><li>Result:<br><li>Remark:<br>").set({rich:true});
//run and continue buttons
var runBtn = new qx.ui.form.Button("run");
runBtn.addListener("execute",function(e) {
this.run_testitem(this.testTree.getSelectedNodes()[0].columnData[10],"r");
}, this);
var contBtn = new qx.ui.form.Button("continue");
contBtn.addListener("execute",function(e) {
this.run_testitem(this.testTree.getSelectedNodes()[0].columnData[10],"c");
}, this);
//Program Code Area
var detachButton = new qx.ui.form.Button("detach code area");
detachButton.addListener("execute",this.detachCodeArea, this);
var prog = new qx.ui.basic.Label("<b>Program-Code:</b>").set({rich:true});
this.codeArea = new qx.ui.form.TextArea().set({height:343});
this.codeArea.setPadding(5,5,5,5);
this.codeArea.addListenerOnce("appear", function(){
this.editor = CodeMirror.fromTextArea(this.codeArea.getContainerElement().getDomElement(), {
textWrapping : false, continuousScanning : false, autoMatchParens : true,
lineNumbers : true, matchBrackets : true
});
this.editor.getWrapperElement().style.top="200px";
this.editor.getWrapperElement().style.left="20px";
this.editor.getWrapperElement().style.right="20px";
}, this);
var saveButton = new qx.ui.form.Button("save");
saveButton.addListener("execute", this.storeItemText, this);
this.statusLabel = new qx.ui.basic.Label("").set({textColor: "red"});
//Add all the Elements to the main container
this.singleItemViewContainer.add(this.descr , {left:'2%',right:'2%' ,top:10});
this.singleItemViewContainer.add(runBtn , {right:100 ,top:10});
this.singleItemViewContainer.add(contBtn , {right:10 ,top:10});
this.singleItemViewContainer.add(prog , {left:'2%',right:'2%' ,top:155});
this.singleItemViewContainer.add(detachButton , { right:'2%' ,top:150});
this.singleItemViewContainer.add(this.codeArea , {left:'2%',right:'2%' ,top:200});
this.singleItemViewContainer.add(saveButton , {left:'2%' ,top:520});
this.singleItemViewContainer.add(this.statusLabel, {left:100 ,right:'2%' ,top:525});
// this.singleItemViewContainer.add(requ , {left:'2%',right:'2%' ,top:555});
// this.singleItemViewContainer.add(this.requList , {left:'2%',right:'2%' ,top:575});
this.singleItemViewContainer["detachButton"] = detachButton;
this.singleItemViewContainer["codeArea"] = this.codeArea;
this.singleItemViewContainer["testItem"] = this.itemPath;
this.singleItemViewContainer["runBtn"] =runBtn;
this.singleItemView = scroller;
},
/**
* detaches the code area from single item view to an overlay window. closing the overlay
* window reattaches it to the single item view without loss of changes
*/
detachCodeArea: function(){
var progWin = new qx.ui.window.Window().set({allowMinimize:false, layout:new qx.ui.layout.Canvas() });
//remove the codeArea from singleItemView (view on the right when only one item is selected)
//this.singleItemView.remove(this.singleItemView["codeArea"]);
var saveButton = new qx.ui.form.Button("save");
saveButton.addListener("execute",function(e) {this.editor.setValue(this.editor2.getValue()),this.storeItemText();progWin.close();}, this);
//configure progWin - size and width in proportion to the browser width and height
// - add the codeArea and the saveButton
var codeAreaDetached = new qx.ui.form.TextArea().set({minWidth:500, height:500});
codeAreaDetached.setValue(this.editor.getValue());
progWin.add(codeAreaDetached, {left:'3%', top:'3%', right:'3%', bottom:'10%'});
progWin.add(saveButton,{left: '3%',bottom:'0%'});
this.parent.getRoot().add(progWin,{left:'3%', top:'5%',right:50, bottom:50});
progWin.show();
codeAreaDetached.addListenerOnce("appear", function(){
this.editor2 = CodeMirror.fromTextArea(codeAreaDetached.getContainerElement().getDomElement(), {
lineNumbers: true,
matchBrackets: true
});
this.editor2.setValue(codeAreaDetached.getValue());
this.editor2.getWrapperElement().style.top="10px";
this.editor2.getWrapperElement().style.bottom="50px";
this.editor2.getWrapperElement().style.position="absolute";
this.editor2.getWrapperElement().style.width="100%";
this.editor2.getWrapperElement().style.height="100%";
this.editor2.getWrapperElement().childNodes[2].style.height="90%";
this.editor2.getWrapperElement().childNodes[2].style.bottom="50px";
this.editor2.getWrapperElement().childNodes[2].style.top="10px";
this.editor2.getWrapperElement().childNodes[1].style.height="90%";
this.editor2.getWrapperElement().childNodes[1].style.top="10px";
this.editor2.getWrapperElement().childNodes[1].style.bottom="50px";
}, this);
// configure the "close" event function - reattach the codeArea and enable the testTree and ItemView
progWin.addListener("close",function(e) {
this.editor.setValue(this.editor2.getValue());
this.tabView.setEnabled(true);
this.singleItemView.setEnabled(true);
this.testTree.setEnabled(true);
}, this);
//testTree and the view on the right need to be disabled when the code Area is detached
this.tabView.setEnabled(false);
this.singleItemView.setEnabled(false);
this.testTree.setEnabled(false);
},
/**
* is called when the save button from the code area was clicked and runs an rpc call
* to save the item code
*/
storeItemText : function() {
var code = this.editor.getValue();
// check the objects needed for this function and start the rpc call
if (this.itemPath && code && this.statusLabel) {
this.rpc_call([qx.lang.Function.bind(this.storeItemText_1,this),
"store_item_text",this.akt_testtree_path,this.itemPath,code]);
}
},
/**
* called after the rpc call for store item text is returned
* and sets a result message in a status label
* @param result
* @param exc
*/
storeItemText_1 : function(result,exc) {
this.rpc_return(result,exc);
if (result) {
if (result == "___DATABASE_OBJECT___"){
alert("changes saved successfully");
}
/* this part would only partially reload the tree
but does not work if the user renames the testitem
if that should be made possible, we can reenable this part*/
var item = this.testTree.getSelectedNodes()[0];
this.itemParent=null;
if (item){
this.itemParent=this.parentDictionary[item.nodeId];
}
//trigger tree update by closing and opening the parent
if (this.itemParent){
this.testTree.nodeSetOpened(this.itemParent, false);
this.testTree.nodeSetOpened(this.itemParent, true);
this.itemPath = item.columnData[10];
this.singleItemViewContainer["runBtn"].setEnabled(false);
this.rpc_call([qx.lang.Function.bind(this.setProgramCode,this),
"get_item_text",this.akt_testtree_path,this.itemPath,"-1"]);
this.testTree.nodeSetSelected(this.itemParent);
this.cellClicked();
}else{
this.dataModel.clearData();
this.rpc_call([qx.lang.Function.bind(this.appendChildren,this),
"report",this.akt_testtree_path,"","-1"]);
this.codeArea.setValue("");
this.editor.setValue("")
this.descr.setValue("<b>Item Name:</b><br><br><li>Result:<br><li>Remark:<br>");
this.singleItemViewContainer["runBtn"].setEnabled(false);
this.testTree.nodeSetSelected(0);
this.cellClicked();
}
}
},
/**
* called when a cell in the testtree was clicked
* @param e - contains the event data (column information)
*/
cellClicked : function (e) {
var data = this.testTree.getSelectedNodes();
// if more than one item were selected, swap singleItemView for multiItemView
if (data.length > 1) {
if (this.testtree_pane.getChildren()[1] == this.singleItemView) {
this.testtree_pane.remove(this.singleItemView);
this.testtree_pane.add(this.multiItemView,1);
}
this.multiItemView["selectedItems"].setValue("Selected Items: <br>"+"<BLOCKQUOTE>"+data[0].columnData[10]);
for (var i=1; i<data. length; i++) {
this.multiItemView["selectedItems"].setValue(this.multiItemView.selectedItems.getValue()+"<br> "+data[i].columnData[10]);
}
}
else if (data.length > 0){
// if only one item was selected, swap multiItemView for singleItemView
if (this.testtree_pane.getChildren()[1]==this.multiItemView) {
this.testtree_pane.remove(this.multiItemView);
this.testtree_pane.add(this.singleItemView,1);
}
var itemPath = data[0].columnData[10];
// if the column 4 was clicked, the program code will be detached and opened in a seperate window
this.descr.setValue("<b>Item Name: "+ data[0].columnData[10].split("::").pop()+"</b><br><br>"
+"<li>Result: "+data[0].columnData[1]+"<br><li>Remark: "+data[0].columnData[2]);
this.itemPath = data[0].columnData[10];
this.rpc_call([qx.lang.Function.bind(this.setProgramCode,this),
"get_item_text",this.akt_testtree_path,itemPath,"-1"]);
}
},
/**
* runs all the currently selected testitems.
*/
run_selected_testitems : function(){
this.info("run_selected_testitems: running multiple testitems");
var data = this.testTree.getSelectedNodes();
for (var i=0; i<data. length; i++) {
var testitem=data[i].columnData[10];
this.info("run_selected_testitems: sending "+testitem);
this.run_testitem(testitem,"r");
}
},
/**
* starts rpc call for running test items
* @param testitem
*/
run_testitem: function(testitem,mode) {
if (this.run_mutex==true){
this.info("run_testitem: testitem: "+testitem+", this.run_mutex is reserved, trying again in ~250ms");
setTimeout(qx.lang.Function.bind(function(){this.run_testitem(testitem,mode);},this), (200+Math.random()*100));
return;
}
var arch=this.parent.loginInfo.archSelection.getSelection()[0].getLabel();
this.run_mutex=true;
this.info("run_testitem: running " + testitem);
this.updateItem=testitem;
this.rpc_call([qx.lang.Function.bind(this.run_testitem_1,this),
"run_item",this.akt_testtree_path,testitem,mode,arch,this.user]); // testitem);
},
/**
* return function for rpc call sent in method above
* @param result
* @param exc
* @returns {Number}
*/
run_testitem_1 : function(result,exc) {
this.rpc_return(result,exc);
this.itemParent=this.nodeDictionary[this.updateItem];
this.testItem=this.updateItem;
this.info("run_testitem_1: calling async rpc for appendChildren with item " +this.updateItem);
this.rpc_call([qx.lang.Function.bind(this.appendChildren,this),"report",this.akt_testtree_path,this.updateItem,"-1"]);
},
/**
* sets the program code in singleItemView
* @param result
* @param exc
*/
setProgramCode: function(result, exc) {
this.rpc_return(result,exc);
if (exc != null) {
this.error("Error in setProgramCode: ", exc );return;
}
this.codeArea.setValue(result);
this.editor.setValue(result);
this.editor.getWrapperElement().style.width="100%";
this.singleItemViewContainer["runBtn"].setEnabled(true);
},
/**
* is called when a testItem in the tree is expanded
* e.getData() contains the node (testItem) that was expanded
*/
createChildren : function(e) {
if (this.rpc_mutex==true || this.run_mutex==true) return;
var node = e.getData();
this.itemParent = node.nodeId;
this.testItem = node.label;
this.info("createChildren: rpc call async for ", this.testItem);
this.rpc_call([qx.lang.Function.bind(this.appendChildren,this),"report",this.akt_testtree_path,node.columnData[10],"-1"]);
},
/**
* helper function for the rpc call from createChildren()
* gets the children from the rpc call and appends them to the parent in the tree
* @param result
* @param exc
*/
appendChildren : function(result, exc){
this.rpc_return(result,exc);
if(!result || !result[0])return;
if(result[0]=="E") {
this.info("appendChildren: error reported by backend: "+result)
this.testTree.nodeSetOpened(this.itemParent, false);
this.dataModel.setData();
this.testTree.setEnabled(true);
return;
}
if (this.itemParent != null) {
this.dataModel.prune(this.itemParent, false);
}
this.info("appendChildren: got result "+result[0]);
//iterate through the children and append them to the parent (using dataModel.addBranch(...))
for (var i = 1; i < result.length; i++) {
var itemName = result[i][2].split("::").pop();
var childId = this.dataModel.addBranch(this.itemParent, itemName);
this.parentDictionary[childId]=this.itemParent;
this.nodeDictionary[result[i][2]]=childId;
this._appendChildren_setNodeDetail(childId,result[i]);
}
if (this.itemParent!=null){
this.testTree.nodeSetOpened(this.itemParent, true);
this.testTree.nodeSetSelected(this.itemParent, true);
}
//add the "loading..." branch if no children were returned and close the parent
// that way the user can refresh the branch in order to look for children again later
if (result.length == 1 || result.length == 0) {
//if no parent was given, the result are appended to the root of the tree
if (this.itemParent == null){
var childId = this.dataModel.addBranch(null, result[0][2]);
this.nodeDictionary[result[0][2]]=childId;
this._appendChildren_setNodeDetail(childId,result[0]);
this.itemParent = childId;
}
this.dataModel.addBranch(this.itemParent, "loading...");
this.testTree.nodeSetOpened(this.itemParent, false);
}
this.dataModel.setData();
this.testTree.setEnabled(true);
setTimeout(qx.lang.Function.bind(function(){this.run_mutex=false;},this), 50);
},
/**
* helper function for appendchildren, which sets the node detail such as the color and column data
* @param nodeId
* @param options
*/
_appendChildren_setNodeDetail : function(nodeId, item_data){
var itemPath = item_data[2];
this.dataModel.setColumnData(nodeId, 1, item_data[3]);
this.dataModel.setColumnData(nodeId, 2, item_data[5]);
this.dataModel.setColumnData(nodeId, 3, "run");
this.dataModel.setColumnData(nodeId, 4, "continue");
this.dataModel.setColumnData(nodeId, 10, itemPath);
this.dataModel.addBranch(nodeId, "loading...");
var result = item_data[3];
if (typeof result == "string"){
var colorString;
if (result>40 && result <1000){
colorString=this.colorMap[40];
}else if (result==9902){
colorString=this.colorMap[result];
}else if (result>=1000){
colorString=this.colorMap[1000];
}else if (this.colorMap[result]){
colorString=this.colorMap[result];
}
this.testTree.nodeSetLabelStyle(nodeId, colorString);
}
},
/**
* handles all rpc calls
* @param params - contains all necessary parameters for the rpc call:
* <li> the return function for the rpc result
* <li> the name of the function to call
* <li> a maximum of 4 parameters for the target function
*/
rpc_call : function(params){
if (this.rpcMutex==true){
this.info("this.rpcMutex is reserved, trying again in ~250ms");
setTimeout(qx.lang.Function.bind(function(){this.rpc_call(params);},this), (200+Math.random()*100));
return;
}
if (params.length>7)this.error("rpc_call(): rpc params has a length > 7!");
try {
this.rpcMutex=true;
this.info("rpc_call(): sending rpc call with params:", params);
this.tabView.setEnabled(false);
this.testTree.setEnabled(false);
this.singleItemView.setEnabled(false);
switch(params.length){
case 1:
this.rpc.callAsync(params[0]);
break;
case 2:
this.rpc.callAsync(params[0],params[1]);
break;
case 3:
this.rpc.callAsync(params[0],params[1],params[2]);
break;
case 4:
this.rpc.callAsync(params[0],params[1],params[2],params[3])
break;
case 5:
this.rpc.callAsync(params[0],params[1],params[2],params[3],params[4])
break;
case 6:
this.rpc.callAsync(params[0],params[1],params[2],params[3],params[4],params[6])
break;
case 7:
this.rpc.callAsync(params[0],params[1],params[2],params[3],params[4],params[6],params[7])
break;
}
} catch(exc) {
this.error("Exception during RPC call", exc);
this.tabView.setEnabled(true);
this.testTree.setEnabled(true);
this.singleItemView.setEnabled(true);
this.rpcMutex=false;
}
},
/**
* handles all rpc returns where no special action is needed
* @param result
* @param exc
*/
rpc_return : function(result, exc) {
this.tabView.setEnabled(true);
this.testTree.setEnabled(true);
this.singleItemView.setEnabled(true);
this.rpcMutex = false;
},
//***********************************************************************************************
endofclass : null } });