details: http://www.bx.psu.edu/hg/galaxy/rev/43249ea9d72a changeset: 3405:43249ea9d72a user: jeremy goecks <jeremy.goecks@emory.edu> date: Wed Feb 17 12:25:17 2010 -0500 description: Update to workflow UI: (1) made options menu; (2) created styles for item metadata; and (3) put item annotations in own metadata form below tool form. diffstat: lib/galaxy/web/controllers/page.py | 3 +- static/june_2007_style/base.css.tmpl | 44 +++++++ static/june_2007_style/blue/base.css | 7 + static/scripts/autocomplete_tagging.js | 2 + static/scripts/galaxy.workflow_editor.canvas.js | 1 - static/scripts/packed/autocomplete_tagging.js | 2 +- static/scripts/packed/galaxy.workflow_editor.canvas.js | 2 +- templates/workflow/editor.mako | 103 ++++++++-------- 8 files changed, 109 insertions(+), 55 deletions(-) diffs (355 lines): diff -r 1e85451c9c86 -r 43249ea9d72a lib/galaxy/web/controllers/page.py --- a/lib/galaxy/web/controllers/page.py Wed Feb 17 11:07:08 2010 -0500 +++ b/lib/galaxy/web/controllers/page.py Wed Feb 17 12:25:17 2010 -0500 @@ -570,7 +570,6 @@ @web.expose def display_by_username_and_slug( self, trans, username, slug ): """ Display page based on a username and slug. """ - session = trans.sa_session # Get page. session = trans.sa_session @@ -588,7 +587,7 @@ # Process page content. processor = _PageContentProcessor( trans, 'utf-8', 'text/html', self._get_embed_html ) processor.feed( page.latest_revision.content ) - # Output is string, so convert to unicode. + # Output is string, so convert to unicode for display. page_content = unicode( processor.output(), 'utf-8' ) return trans.fill_template_mako( "page/display.mako", item=page, item_data=page_content, content_only=True ) diff -r 1e85451c9c86 -r 43249ea9d72a static/june_2007_style/base.css.tmpl --- a/static/june_2007_style/base.css.tmpl Wed Feb 17 11:07:08 2010 -0500 +++ b/static/june_2007_style/base.css.tmpl Wed Feb 17 12:25:17 2010 -0500 @@ -111,6 +111,50 @@ overflow: auto; } +div.metadataForm { + border:solid #aaaaaa 1px; +} + +div.metadataFormTitle { + font-weight:bold; + padding:5px; + padding-left:10px; + padding-right:10px; + background:#cccccc; + background-repeat:repeat-x; + background-position:top; + border-bottom:solid #aaaaaa 1px; +} + +div.metadataFormBody { + background:#FFFFFF; + background-image:url(form_body_bg.png); + background-repeat:repeat-x; + background-position:top; + padding:5px 0; +} + +div.metadataFormBody div.metadataFormTitle { + background:transparent; + border:none; + font-weight:bold; + border-bottom:solid #dcb790 1px; + margin-bottom:5px; +} + +div.metadataFormDisabled div.metadataFormTitle { + background:#eee; + border-color:#999; +} + +div.metadataFormDisabled { + border-color:#999; +} + +div.metadataHelpBody { + width:100%;overflow:auto; +} + div.titleRow { font-weight: bold; border-bottom: dotted gray 1px; diff -r 1e85451c9c86 -r 43249ea9d72a static/june_2007_style/blue/base.css --- a/static/june_2007_style/blue/base.css Wed Feb 17 11:07:08 2010 -0500 +++ b/static/june_2007_style/blue/base.css Wed Feb 17 12:25:17 2010 -0500 @@ -22,6 +22,13 @@ div.toolFormDisabled{border-color:#999;} div.toolHelp{} div.toolHelpBody{width:100%;overflow:auto;} +div.metadataForm{border:solid #aaaaaa 1px;} +div.metadataFormTitle{font-weight:bold;padding:5px;padding-left:10px;padding-right:10px;background:#cccccc;background-repeat:repeat-x;background-position:top;border-bottom:solid #aaaaaa 1px;} +div.metadataFormBody{background:#FFFFFF;background-image:url(form_body_bg.png);background-repeat:repeat-x;background-position:top;padding:5px 0;} +div.metadataFormBody div.metadataFormTitle{background:transparent;border:none;font-weight:bold;border-bottom:solid #dcb790 1px;margin-bottom:5px;} +div.metadataFormDisabled div.metadataFormTitle{background:#eee;border-color:#999;} +div.metadataFormDisabled{border-color:#999;} +div.metadataHelpBody{width:100%;overflow:auto;} div.titleRow{font-weight:bold;border-bottom:dotted gray 1px;margin-bottom:0.5em;padding-bottom:0.25em;} div.form{border:solid #d8b365 1px;} div.form-title{font-weight:bold;padding:5px 10px;background:#ebd9b2;background-image:url(form_title_bg.png);background-repeat:repeat-x;background-position:top;border-bottom:solid #d8b365 1px;} diff -r 1e85451c9c86 -r 43249ea9d72a static/scripts/autocomplete_tagging.js --- a/static/scripts/autocomplete_tagging.js Wed Feb 17 11:07:08 2010 -0500 +++ b/static/scripts/autocomplete_tagging.js Wed Feb 17 12:25:17 2010 -0500 @@ -323,12 +323,14 @@ tag_area.hide(); else { + /* var num_tags = array_length(settings.tags); if (num_tags == 0) { add_tag_button.hide(); tag_input_field.show(); } + */ } // Initialize tag names. diff -r 1e85451c9c86 -r 43249ea9d72a static/scripts/galaxy.workflow_editor.canvas.js --- a/static/scripts/galaxy.workflow_editor.canvas.js Wed Feb 17 11:07:08 2010 -0500 +++ b/static/scripts/galaxy.workflow_editor.canvas.js Wed Feb 17 12:25:17 2010 -0500 @@ -307,7 +307,6 @@ node = this; this.tool_state = data.tool_state; this.form_html = data.form_html; - this.annotation = data.annotation; this.tool_errors = data.tool_errors; if ( this.tool_errors ) { el.addClass( "tool-node-error" ); diff -r 1e85451c9c86 -r 43249ea9d72a static/scripts/packed/autocomplete_tagging.js --- a/static/scripts/packed/autocomplete_tagging.js Wed Feb 17 11:07:08 2010 -0500 +++ b/static/scripts/packed/autocomplete_tagging.js Wed Feb 17 12:25:17 2010 -0500 @@ -1,1 +1,1 @@ -function init_tag_click_function(b,a){$(b).find(".tag-name").each(function(){$(this).click(function(){var d=$(this).text();var c=d.split(":");a(c[0],c[1]);return true})})}jQuery.fn.autocomplete_tagging=function(q){var g={get_toggle_link_text_fn:function(r){var t="";var s=o(r);if(s!=0){t=s+(s!=0?" Tags":" Tag")}else{t="Add tags"}return t},tag_click_fn:function(r,s){},editable:true,input_size:20,in_form:false,tags:{},use_toggle_link:true,item_id:"",add_tag_img:"",add_tag_img_rollover:"",delete_tag_img:"",ajax_autocomplete_tag_url:"",ajax_retag_url:"",ajax_delete_tag_url:"",ajax_add_tag_url:""};var e=jQuery.extend(g,q);var o=function(r){if(r.length){return r.length}var s=0;for(element in r){s++}return s};var h=$(this);var c=h.find(".tag-area");var f=h.find(".toggle-link");var b=h.find(".tag-input");var n=h.find(".add-tag-button");f.click(function(){var r=(c.css("display")=="none");var s;if(r){s=function(){var t=$(this).find(".tag-button").length;if(t==0){c.click()}}}else{s=func tion(){c.blur()}}c.slideToggle("fast",s);return $(this)});if(e.editable){b.hide()}b.keyup(function(w){if(w.keyCode==27){$(this).trigger("blur")}else{if((w.keyCode==13)||(w.keyCode==188)||(w.keyCode==32)){new_value=this.value;if(return_key_pressed_for_autocomplete==true){return_key_pressed_for_autocomplete=false;return false}if(new_value.indexOf(": ",new_value.length-2)!=-1){this.value=new_value.substring(0,new_value.length-1);return false}if((w.keyCode==188)||(w.keyCode==32)){new_value=new_value.substring(0,new_value.length-1)}new_value=new_value.replace(/^\s+|\s+$/g,"");if(new_value.length<2){return false}this.value="";var t=k(new_value);var s=c.children(".tag-button");if(s.length!=0){var x=s.slice(s.length-1);x.after(t)}else{c.prepend(t)}var r=new_value.split(":");e.tags[r[0]]=r[1];var u=e.get_toggle_link_text_fn(e.tags);f.text(u);var v=$(this);$.ajax({url:e.ajax_add_tag_url,data:{new_tag:new_value},error:function(){t.remove();delete e.tags[r[0]];var y=e.get_toggle_link_te xt_fn(e.tags);f.text(y);alert("Add tag failed")},success:function(){v.flushCache()}});return false}}});var j=function(t,s,r,v,u){tag_name_and_value=v.split(":");return(tag_name_and_value.length==1?tag_name_and_value[0]:tag_name_and_value[1])};var i={selectFirst:false,formatItem:j,autoFill:false,highlight:false};b.autocomplete(e.ajax_autocomplete_tag_url,i);h.find(".delete-tag-img").each(function(){d($(this))});init_tag_click_function($(this),e.tag_click_fn);n.click(function(){$(this).hide();c.click();return false});if(e.editable){c.blur(function(r){p=o(e.tags);if(p!=0){n.show();b.hide();c.removeClass("active-tag-area");c.addClass("tooltip")}else{}});c.click(function(t){var s=$(this).hasClass("active-tag-area");if($(t.target).hasClass("delete-tag-img")&&!s){return false}if($(t.target).hasClass("tag-name")&&!s){return false}$(this).removeClass("tooltip");$(this).addClass("active-tag-area");n.hide();b.show();b.focus();var r=function(v){var u=c.attr("id");if(($(v.target).attr("i d")!=u)&&($(v.target).parents().filter(u).length==0)){c.blur();$(document).unbind("click",r);$(this).addClass("tooltip")}};$(window).click(r);return false})}if(e.use_toggle_link){c.hide()}else{var p=o(e.tags);if(p==0){n.hide();b.show()}}function l(s,r){return s+((r!=""&&r)?":"+r:"")}function d(r){$(r).mouseenter(function(){$(this).attr("src",e.delete_tag_img_rollover)});$(r).mouseleave(function(){$(this).attr("src",e.delete_tag_img)});$(r).click(function(){var x=$(this).parent();var w=x.find(".tag-name").eq(0);var v=w.text();var t=m(v);var z=t[0];var s=t[1];var y=x.prev();x.remove();delete e.tags[z];var u=e.get_toggle_link_text_fn(e.tags);f.text(u);$.ajax({url:e.ajax_delete_tag_url,data:{tag_name:z},error:function(){e.tags[z]=s;if(y.hasClass("tag-button")){y.after(x)}else{c.prepend(x)}var A=e.get_toggle_link_text_fn(e.tags);alert("Remove tag failed");f.text(A);r.mouseenter(function(){$(this).attr("src",e.delete_tag_img_rollover)});r.mouseleave(function(){$(this).attr("src",e .delete_tag_img)})},success:function(){}});return true})}function a(r){var s=new Array();for(key in r){s[s.length]=key+"-->"+r[key]}return"{"+s.join(",")+"}"}function m(r){return r.split(":")}function k(r){var s=$("<img src='"+e.delete_tag_img+"'/>").addClass("delete-tag-img");d(s);var t=$("<span>").text(r).addClass("tag-name");t.click(function(){tag_name_and_value=r.split(":");e.tag_click_fn(tag_name_and_value[0],tag_name_and_value[1]);return true});var u=$("<span></span>").addClass("tag-button");u.append(t);if(e.editable){u.append(s)}return u}}; \ No newline at end of file +function init_tag_click_function(b,a){$(b).find(".tag-name").each(function(){$(this).click(function(){var d=$(this).text();var c=d.split(":");a(c[0],c[1]);return true})})}jQuery.fn.autocomplete_tagging=function(p){var g={get_toggle_link_text_fn:function(q){var s="";var r=o(q);if(r!=0){s=r+(r!=0?" Tags":" Tag")}else{s="Add tags"}return s},tag_click_fn:function(q,r){},editable:true,input_size:20,in_form:false,tags:{},use_toggle_link:true,item_id:"",add_tag_img:"",add_tag_img_rollover:"",delete_tag_img:"",ajax_autocomplete_tag_url:"",ajax_retag_url:"",ajax_delete_tag_url:"",ajax_add_tag_url:""};var e=jQuery.extend(g,p);var o=function(q){if(q.length){return q.length}var r=0;for(element in q){r++}return r};var h=$(this);var c=h.find(".tag-area");var f=h.find(".toggle-link");var b=h.find(".tag-input");var n=h.find(".add-tag-button");f.click(function(){var q=(c.css("display")=="none");var r;if(q){r=function(){var s=$(this).find(".tag-button").length;if(s==0){c.click()}}}else{r=func tion(){c.blur()}}c.slideToggle("fast",r);return $(this)});if(e.editable){b.hide()}b.keyup(function(v){if(v.keyCode==27){$(this).trigger("blur")}else{if((v.keyCode==13)||(v.keyCode==188)||(v.keyCode==32)){new_value=this.value;if(return_key_pressed_for_autocomplete==true){return_key_pressed_for_autocomplete=false;return false}if(new_value.indexOf(": ",new_value.length-2)!=-1){this.value=new_value.substring(0,new_value.length-1);return false}if((v.keyCode==188)||(v.keyCode==32)){new_value=new_value.substring(0,new_value.length-1)}new_value=new_value.replace(/^\s+|\s+$/g,"");if(new_value.length<2){return false}this.value="";var s=k(new_value);var r=c.children(".tag-button");if(r.length!=0){var w=r.slice(r.length-1);w.after(s)}else{c.prepend(s)}var q=new_value.split(":");e.tags[q[0]]=q[1];var t=e.get_toggle_link_text_fn(e.tags);f.text(t);var u=$(this);$.ajax({url:e.ajax_add_tag_url,data:{new_tag:new_value},error:function(){s.remove();delete e.tags[q[0]];var x=e.get_toggle_link_te xt_fn(e.tags);f.text(x);alert("Add tag failed")},success:function(){u.flushCache()}});return false}}});var j=function(s,r,q,u,t){tag_name_and_value=u.split(":");return(tag_name_and_value.length==1?tag_name_and_value[0]:tag_name_and_value[1])};var i={selectFirst:false,formatItem:j,autoFill:false,highlight:false};b.autocomplete(e.ajax_autocomplete_tag_url,i);h.find(".delete-tag-img").each(function(){d($(this))});init_tag_click_function($(this),e.tag_click_fn);n.click(function(){$(this).hide();c.click();return false});if(e.editable){c.blur(function(q){num_tags=o(e.tags);if(num_tags!=0){n.show();b.hide();c.removeClass("active-tag-area");c.addClass("tooltip")}else{}});c.click(function(s){var r=$(this).hasClass("active-tag-area");if($(s.target).hasClass("delete-tag-img")&&!r){return false}if($(s.target).hasClass("tag-name")&&!r){return false}$(this).removeClass("tooltip");$(this).addClass("active-tag-area");n.hide();b.show();b.focus();var q=function(u){var t=c.attr("id");if(($(u.t arget).attr("id")!=t)&&($(u.target).parents().filter(t).length==0)){c.blur();$(document).unbind("click",q);$(this).addClass("tooltip")}};$(window).click(q);return false})}if(e.use_toggle_link){c.hide()}else{}function l(r,q){return r+((q!=""&&q)?":"+q:"")}function d(q){$(q).mouseenter(function(){$(this).attr("src",e.delete_tag_img_rollover)});$(q).mouseleave(function(){$(this).attr("src",e.delete_tag_img)});$(q).click(function(){var w=$(this).parent();var v=w.find(".tag-name").eq(0);var u=v.text();var s=m(u);var y=s[0];var r=s[1];var x=w.prev();w.remove();delete e.tags[y];var t=e.get_toggle_link_text_fn(e.tags);f.text(t);$.ajax({url:e.ajax_delete_tag_url,data:{tag_name:y},error:function(){e.tags[y]=r;if(x.hasClass("tag-button")){x.after(w)}else{c.prepend(w)}var z=e.get_toggle_link_text_fn(e.tags);alert("Remove tag failed");f.text(z);q.mouseenter(function(){$(this).attr("src",e.delete_tag_img_rollover)});q.mouseleave(function(){$(this).attr("src",e.delete_tag_img)})},success:f unction(){}});return true})}function a(q){var r=new Array();for(key in q){r[r.length]=key+"-->"+q[key]}return"{"+r.join(",")+"}"}function m(q){return q.split(":")}function k(q){var r=$("<img src='"+e.delete_tag_img+"'/>").addClass("delete-tag-img");d(r);var s=$("<span>").text(q).addClass("tag-name");s.click(function(){tag_name_and_value=q.split(":");e.tag_click_fn(tag_name_and_value[0],tag_name_and_value[1]);return true});var t=$("<span></span>").addClass("tag-button");t.append(s);if(e.editable){t.append(r)}return t}}; \ No newline at end of file diff -r 1e85451c9c86 -r 43249ea9d72a static/scripts/packed/galaxy.workflow_editor.canvas.js --- a/static/scripts/packed/galaxy.workflow_editor.canvas.js Wed Feb 17 11:07:08 2010 -0500 +++ b/static/scripts/packed/galaxy.workflow_editor.canvas.js Wed Feb 17 12:25:17 2010 -0500 @@ -1,1 +1,1 @@ -function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var b in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[b])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a) {this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f; this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)).redraw()}).bind("hov er",function(){if(f.connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");ret urn i}).bind("drag",function(i){var h=function(){var k=$(i.dragProxy).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dragProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b .appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;this.tooltip=g.tooltip?g.tooltip:"";this.annotation=g.annotation;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.ext ension);var f=b.name;if(b.extension!="input"){f=f+" ("+b.extension+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.annotation=f.annotation;this.tool_errors=f.tool_errors;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0].terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))}) ;g.replaceWith(b);g.find("div.input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes, function(b,d){var f={};$.each(d.input_terminals,function(g,h){f[h.name]=null;$.each(h.connectors,function(j,k){f[h.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var c={id:d.id,type:d.type,tool_id:d.tool_id,tool_state:d.tool_state,tool_errors:d.tool_errors,input_connections:f,position:$(d.element).position(),annotation:d.annotation};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$( "#right-content").find("form").submit();this.active_form_has_changes=false}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)} }if(level_parents.length==0){break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent(); var d=fix_delta(a.xmin,100);var h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='../images/l oading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function(){$(this).attr("src","../images/delete_icon.png")}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(thi s).css({left:b,top:p});$(this).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.mi n(o,c.top-B);l.css("top",(c.top-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b .cc.width(),g=b.cc.height(),f=b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b) {k=d/h*m;f=(m-k)/2;g=l/b*m;a=(m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}}); \ No newline at end of file +function Terminal(a){this.element=a;this.connectors=[]}$.extend(Terminal.prototype,{connect:function(a){this.connectors.push(a);if(this.node){this.node.changed()}},disconnect:function(a){this.connectors.splice($.inArray(a,this.connectors),1);if(this.node){this.node.changed()}},redraw:function(){$.each(this.connectors,function(a,b){b.redraw()})},destroy:function(){$.each(this.connectors.slice(),function(a,b){b.destroy()})}});function OutputTerminal(a,b){Terminal.call(this,a);this.datatype=b}OutputTerminal.prototype=new Terminal();function InputTerminal(a,b){Terminal.call(this,a);this.datatypes=b}InputTerminal.prototype=new Terminal();$.extend(InputTerminal.prototype,{can_accept:function(a){if(this.connectors.length<1){for(var b in this.datatypes){if(a.datatype=="input"){return true}if(issubtype(a.datatype,this.datatypes[b])){return true}}}return false}});function Connector(b,a){this.canvas=null;this.dragging=false;this.inner_color="#FFFFFF";this.outer_color="#D8B365";if(b&&a) {this.connect(b,a)}}$.extend(Connector.prototype,{connect:function(b,a){this.handle1=b;this.handle1.connect(this);this.handle2=a;this.handle2.connect(this)},destroy:function(){if(this.handle1){this.handle1.disconnect(this)}if(this.handle2){this.handle2.disconnect(this)}$(this.canvas).remove()},redraw:function(){var d=$("#canvas-container");if(!this.canvas){this.canvas=document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(this.canvas)}d.append($(this.canvas));if(this.dragging){this.canvas.style.zIndex="300"}}var n=function(c){return $(c).offset().left-d.offset().left};var i=function(c){return $(c).offset().top-d.offset().top};var h=n(this.handle1.element)+5;var g=i(this.handle1.element)+5;var p=n(this.handle2.element)+5;var m=i(this.handle2.element)+5;var f=100;var k=Math.min(h,p);var a=Math.max(h,p);var j=Math.min(g,m);var t=Math.max(g,m);var b=Math.min(Math.max(Math.abs(t-j)/2,100),300);var o=k-f;var s=j-f;var q=a-k+2*f;var l=t-j+2*f; this.canvas.style.left=o+"px";this.canvas.style.top=s+"px";this.canvas.setAttribute("width",q);this.canvas.setAttribute("height",l);h-=o;g-=s;p-=o;m-=s;var r=this.canvas.getContext("2d");r.lineCap="round";r.strokeStyle=this.outer_color;r.lineWidth=7;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke();r.strokeStyle=this.inner_color;r.lineWidth=5;r.beginPath();r.moveTo(h,g);r.bezierCurveTo(h+b,g,p-b,m,p,m);r.stroke()}});function Node(a){this.element=a;this.input_terminals={};this.output_terminals={};this.tool_errors={}}$.extend(Node.prototype,{enable_input_terminal:function(d,a,b){var c=this;$(d).each(function(){var f=this.terminal=new InputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dropstart",function(g){g.dragProxy.terminal.connectors[0].inner_color="#BBFFBB"}).bind("dropend",function(g){g.dragProxy.terminal.connectors[0].inner_color="#FFFFFF"}).bind("drop",function(g){(new Connector(g.dragTarget.terminal,g.dropTarget.terminal)).redraw()}).bind("hov er",function(){if(f.connectors.length>0){var g=$("<div class='callout'></div>").css({display:"none"}).appendTo("body").append($("<div class='buttons'></div>").append($("<img src='../images/delete_icon.png' />").click(function(){$.each(f.connectors,function(i,h){h.destroy()});g.remove()}))).bind("mouseleave",function(){$(this).remove()});g.css({top:$(this).offset().top-2,left:$(this).offset().left-g.width(),"padding-right":$(this).width()}).show()}});c.input_terminals[a]=f})},enable_output_terminal:function(d,a,b){var c=this;$(d).each(function(){var g=this;var f=this.terminal=new OutputTerminal(this,b);f.node=c;f.name=a;$(this).bind("dragstart",function(j){var i=$('<div class="drag-terminal" style="position: absolute;"></div>').appendTo("#canvas-container").get(0);i.terminal=new OutputTerminal(i);var k=new Connector();k.dragging=true;k.connect(this.terminal,i.terminal);$.dropManage({filter:function(h){return this.terminal.can_accept(f)}}).addClass("input-terminal-active");ret urn i}).bind("drag",function(i){var h=function(){var k=$(i.dragProxy).offsetParent().offset(),j=i.offsetX-k.left,l=i.offsetY-k.top;$(i.dragProxy).css({left:j,top:l});i.dragProxy.terminal.redraw();canvas_manager.update_viewport_overlay()};h();$("#canvas-container").get(0).scroll_panel.test(i,h)}).bind("dragend",function(h){h.dragProxy.terminal.connectors[0].destroy();$(h.dragProxy).remove();$.dropManage().removeClass("input-terminal-active");$("#canvas-container").get(0).scroll_panel.stop()});c.output_terminals[a]=f})},redraw:function(){$.each(this.input_terminals,function(a,b){b.redraw()});$.each(this.output_terminals,function(a,b){b.redraw()})},destroy:function(){$.each(this.input_terminals,function(a,b){b.destroy()});$.each(this.output_terminals,function(a,b){b.destroy()});workflow.remove_node(this);$(this.element).remove()},make_active:function(){$(this.element).addClass("toolForm-active")},make_inactive:function(){var a=this.element.get(0);(function(b){b.removeChild(a);b .appendChild(a)})(a.parentNode);$(a).removeClass("toolForm-active")},init_field_data:function(g){var d=this.element;if(g.type){this.type=g.type}this.name=g.name;this.form_html=g.form_html;this.tool_state=g.tool_state;this.tool_errors=g.tool_errors;this.tooltip=g.tooltip?g.tooltip:"";this.annotation=g.annotation;if(this.tool_errors){d.addClass("tool-node-error")}else{d.removeClass("tool-node-error")}var c=this;var a=d.find(".toolFormBody");a.find("div").remove();var h=$("<div class='inputs'></div>").appendTo(a);$.each(g.data_inputs,function(j,b){var f=$("<div class='terminal input-terminal'></div>");c.enable_input_terminal(f,b.name,b.extensions);h.append($("<div class='form-row dataRow input-data-row' name='"+b.name+"'>"+b.label+"</div>").prepend(f))});if((g.data_inputs.length>0)&&(g.data_outputs.length>0)){a.append($("<div class='rule'></div>"))}$.each(g.data_outputs,function(k,b){var j=$("<div class='terminal output-terminal'></div>");c.enable_output_terminal(j,b.name,b.ext ension);var f=b.name;if(b.extension!="input"){f=f+" ("+b.extension+")"}a.append($("<div class='form-row dataRow'>"+f+"</div>").append(j))});workflow.node_changed(this)},update_field_data:function(f){var c=$(this.element),d=this;this.tool_state=f.tool_state;this.form_html=f.form_html;this.tool_errors=f.tool_errors;if(this.tool_errors){c.addClass("tool-node-error")}else{c.removeClass("tool-node-error")}var g=c.find("div.inputs");var b=$("<div class='inputs'></div>");var a=g.find("div.input-data-row");$.each(f.data_inputs,function(k,h){var j=$("<div class='terminal input-terminal'></div>");d.enable_input_terminal(j,h.name,h.extensions);g.find("div[name="+h.name+"]").each(function(){$(this).find(".input-terminal").each(function(){var i=this.terminal.connectors[0];if(i){j[0].terminal.connectors[0]=i;i.handle2=j[0].terminal}});$(this).remove()});b.append($("<div class='form-row dataRow input-data-row' name='"+h.name+"'>"+h.label+"</div>").prepend(j))});g.replaceWith(b);g.find("div .input-data-row > .terminal").each(function(){this.terminal.destroy()});this.changed();this.redraw()},error:function(d){var a=$(this.element).find(".toolFormBody");a.find("div").remove();var c="<div style='color: red; text-style: italic;'>"+d+"</div>";this.form_html=c;a.html(c);workflow.node_changed(this)},changed:function(){workflow.node_changed(this)}});function Workflow(a){this.canvas_container=a;this.id_counter=0;this.nodes={};this.name=null;this.has_changes=false;this.active_form_has_changes=false}$.extend(Workflow.prototype,{add_node:function(a){a.id=this.id_counter;a.element.attr("id","wf-node-step-"+a.id);this.id_counter++;this.nodes[a.id]=a;this.has_changes=true;a.workflow=this},remove_node:function(a){if(this.active_node==a){this.clear_active_node()}delete this.nodes[a.id];this.has_changes=true},remove_all:function(){wf=this;$.each(this.nodes,function(b,a){a.destroy();wf.remove_node(a)})},to_simple:function(){var a={};$.each(this.nodes,function(b,d){var f={};$.each (d.input_terminals,function(g,h){f[h.name]=null;$.each(h.connectors,function(j,k){f[h.name]={id:k.handle1.node.id,output_name:k.handle1.name}})});var c={id:d.id,type:d.type,tool_id:d.tool_id,tool_state:d.tool_state,tool_errors:d.tool_errors,input_connections:f,position:$(d.element).position(),annotation:d.annotation};a[d.id]=c});return{steps:a}},from_simple:function(a){wf=this;var b=0;wf.name=a.name;$.each(a.steps,function(f,d){var c=prebuild_node("tool",d.name,d.tool_id);c.init_field_data(d);if(d.position){c.element.css({top:d.position.top,left:d.position.left})}c.id=d.id;wf.nodes[c.id]=c;b=Math.max(b,parseInt(f))});wf.id_counter=b+1;$.each(a.steps,function(f,d){var c=wf.nodes[f];$.each(d.input_connections,function(h,g){if(g){var i=wf.nodes[g.id];var j=new Connector();j.connect(i.output_terminals[g.output_name],c.input_terminals[h]);j.redraw()}})})},check_changes_in_active_form:function(){if(this.active_form_has_changes){this.has_changes=true;$("#right-content").find("form" ).submit();this.active_form_has_changes=false}},clear_active_node:function(){if(this.active_node){this.active_node.make_inactive();this.active_node=null}parent.show_form_for_tool("<div>No node selected</div>")},activate_node:function(a){if(this.active_node!=a){this.check_changes_in_active_form();this.clear_active_node();parent.show_form_for_tool(a.form_html+a.tooltip,a);a.make_active();this.active_node=a}},node_changed:function(a){this.has_changes=true;if(this.active_node==a){parent.show_form_for_tool(a.form_html+a.tooltip,a)}},layout:function(){this.check_changes_in_active_form();var i={};var b={};$.each(this.nodes,function(l,k){if(i[l]===undefined){i[l]=0}if(b[l]===undefined){b[l]=[]}});$.each(this.nodes,function(l,k){$.each(k.input_terminals,function(m,n){$.each(n.connectors,function(p,q){var o=q.handle1.node;i[k.id]+=1;b[o.id].push(k.id)})})});node_ids_by_level=[];while(true){level_parents=[];for(var a in i){if(i[a]==0){level_parents.push(a)}}if(level_parents.length==0){ break}node_ids_by_level.push(level_parents);for(var f in level_parents){var j=level_parents[f];delete i[j];for(var g in b[j]){i[b[j][g]]-=1}}}if(i.length){return}var d=this.nodes;var h=80;v_pad=30;var c=h;$.each(node_ids_by_level,function(k,l){l.sort(function(p,o){return $(d[p].element).position().top-$(d[o].element).position().top});var m=0;var n=v_pad;$.each(l,function(o,r){var q=d[r];var p=$(q.element);$(p).css({top:n,left:c});m=Math.max(m,$(p).width());n+=$(p).height()+v_pad});c+=m+h});$.each(d,function(k,l){l.redraw()})},bounds_for_all_nodes:function(){var d=Infinity,b=-Infinity,c=Infinity,a=-Infinity,f;$.each(this.nodes,function(h,g){e=$(g.element);f=e.position();d=Math.min(d,f.left);b=Math.max(b,f.left+e.width());c=Math.min(c,f.top);a=Math.max(a,f.top+e.width())});return{xmin:d,xmax:b,ymin:c,ymax:a}},fit_canvas_to_nodes:function(){var a=this.bounds_for_all_nodes();var f=this.canvas_container.position();var i=this.canvas_container.parent();var d=fix_delta(a.xmin,100);v ar h=fix_delta(a.ymin,100);d=Math.max(d,f.left);h=Math.max(h,f.top);var c=f.left-d;var g=f.top-h;var b=round_up(a.xmax+100,100)+d;var j=round_up(a.ymax+100,100)+h;b=Math.max(b,-c+i.width());j=Math.max(j,-g+i.height());this.canvas_container.css({left:c,top:g,width:b,height:j});this.canvas_container.children().each(function(){var k=$(this).position();$(this).css("left",k.left+d);$(this).css("top",k.top+h)})}});function fix_delta(a,b){if(a<b||a>3*b){new_pos=(Math.ceil(((a%b))/b)+1)*b;return(-(a-new_pos))}return 0}function round_up(a,b){return Math.ceil(a/b)*b}function prebuild_node(l,j,r){var i=$("<div class='toolForm toolFormInCanvas'></div>");var g=new Node(i);g.type=l;if(l=="tool"){g.tool_id=r}var n=$("<div class='toolFormTitle unselectable'>"+j+"</div>");i.append(n);i.css("left",$(window).scrollLeft()+20);i.css("top",$(window).scrollTop()+20);var m=$("<div class='toolFormBody'></div>");var h="<div><img height='16' align='middle' src='../images/loading_small_white_bg.gif'/> loading tool info...</div>";m.append(h);g.form_html=h;i.append(m);var k=$("<div class='buttons' style='float: right;'></div>");k.append($("<img src='../images/delete_icon.png' />").click(function(b){g.destroy()}).hover(function(){$(this).attr("src","../images/delete_icon_dark.png")},function(){$(this).attr("src","../images/delete_icon.png")}));i.appendTo("#canvas-container");var d=$("#canvas-container").position();var c=$("#canvas-container").parent();var a=i.width();var q=i.height();i.css({left:(-d.left)+(c.width()/2)-(a/2),top:(-d.top)+(c.height()/2)-(q/2)});k.prependTo(n);a+=(k.width()+10);i.css("width",a);$(i).bind("dragstart",function(){workflow.activate_node(g)}).bind("dragend",function(){workflow.node_changed(this);workflow.fit_canvas_to_nodes();canvas_manager.draw_overview()}).bind("dragclickonly",function(){workflow.activate_node(g)}).bind("drag",function(o){var f=$(this).offsetParent().offset(),b=o.offsetX-f.left,p=o.offsetY-f.top;$(this).css({left:b,top:p});$(this ).find(".terminal").each(function(){this.terminal.redraw()})});return g}var ext_to_type=null;var type_to_type=null;function issubtype(b,a){b=ext_to_type[b];a=ext_to_type[a];return(type_to_type[b])&&(a in type_to_type[b])}function populate_datatype_info(a){ext_to_type=a.ext_to_class_name;type_to_type=a.class_to_classes}function ScrollPanel(a){this.panel=a}$.extend(ScrollPanel.prototype,{test:function(v,d){clearTimeout(this.timeout);var k=v.pageX,j=v.pageY,l=$(this.panel),c=l.position(),b=l.width(),i=l.height(),w=l.parent(),s=w.width(),a=w.height(),r=w.offset(),p=r.left,m=r.top,A=p+w.width(),u=m+w.height(),B=-(b-(s/2)),z=-(i-(a/2)),g=(s/2),f=(a/2),h=false,q=5,o=23;if(k-q<p){if(c.left<g){var n=Math.min(o,g-c.left);l.css("left",c.left+n);h=true}}else{if(k+q>A){if(c.left>B){var n=Math.min(o,c.left-B);l.css("left",c.left-n);h=true}}else{if(j-q<m){if(c.top<f){var n=Math.min(o,f-c.top);l.css("top",c.top+n);h=true}}else{if(j+q>u){if(c.top>z){var n=Math.min(o,c.top-B);l.css("top",(c.t op-n)+"px");h=true}}}}}if(h){d();var l=this;this.timeout=setTimeout(function(){l.test(v,d)},50)}},stop:function(b,a){clearTimeout(this.timeout)}});function CanvasManager(b,a){this.cv=b;this.cc=this.cv.find("#canvas-container");this.oc=a.find("#overview-canvas");this.ov=a.find("#overview-viewport");this.init_drag()}$.extend(CanvasManager.prototype,{init_drag:function(){var b=this;var a=function(f,g){f=Math.min(f,b.cv.width()/2);f=Math.max(f,-b.cc.width()+b.cv.width()/2);g=Math.min(g,b.cv.height()/2);g=Math.max(g,-b.cc.height()+b.cv.height()/2);b.cc.css({left:f,top:g});b.update_viewport_overlay()};this.cc.each(function(){this.scroll_panel=new ScrollPanel(this)});var d,c;this.cv.bind("dragstart",function(g){var h=$(this).offset();var f=b.cc.position();c=f.top-h.top;d=f.left-h.left}).bind("drag",function(f){a(f.offsetX+d,f.offsetY+c)}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});this.ov.bind("drag",function(k){var j=b.cc.width(),g=b.cc.height(),f =b.oc.width(),h=b.oc.height(),i=$(this).offsetParent().offset(),m=k.offsetX-i.left,l=k.offsetY-i.top;a(-(m/f*j),-(l/h*g))}).bind("dragend",function(){workflow.fit_canvas_to_nodes();b.draw_overview()});$("#overview-border").bind("drag",function(g){var i=$(this).offsetParent();var h=i.offset();var f=Math.max(i.width()-(g.offsetX-h.left),i.height()-(g.offsetY-h.top));$(this).css({width:f,height:f});b.draw_overview()});$("#overview-border div").bind("drag",function(f){})},update_viewport_overlay:function(){var b=this.cc,f=this.cv,a=this.oc,c=this.ov,d=b.width(),j=b.height(),i=a.width(),g=a.height(),h=b.position();c.css({left:-(h.left/d*i),top:-(h.top/j*g),width:(f.width()/d*i)-2,height:(f.height()/j*g)-2})},draw_overview:function(){var j=$("#overview-canvas"),m=j.parent().parent().width(),i=j.get(0).getContext("2d"),d=$("#canvas-container").width(),l=$("#canvas-container").height();var g,a,k,f;var h=this.cv.width();var b=this.cv.height();if(d<h&&l<b){k=d/h*m;f=(m-k)/2;g=l/b*m;a= (m-g)/2}else{if(d<l){a=0;g=m;k=Math.ceil(g*d/l);f=(m-k)/2}else{k=m;f=0;g=Math.ceil(k*l/d);a=(m-g)/2}}j.parent().css({left:f,top:a,width:k,height:g});j.attr("width",k);j.attr("height",g);i.fillStyle="#D2C099";i.strokeStyle="#D8B365";i.lineWidth=1;$.each(workflow.nodes,function(t,q){var s=$(q.element),n=s.position(),c=n.left/d*k,r=n.top/l*g,o=s.width()/d*k,p=s.height()/l*g;i.fillRect(c,r,o,p);i.strokeRect(c,r,o,p)});this.update_viewport_overlay()}}); \ No newline at end of file diff -r 1e85451c9c86 -r 43249ea9d72a templates/workflow/editor.mako --- a/templates/workflow/editor.mako Wed Feb 17 11:07:08 2010 -0500 +++ b/templates/workflow/editor.mako Wed Feb 17 12:25:17 2010 -0500 @@ -26,7 +26,8 @@ <script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"> </script> <![endif]--> - ${h.js( "jquery", + ${h.js( "jquery", + "jquery.tipsy", "jquery.event.drag", "jquery.event.drop", "jquery.event.hover", @@ -128,27 +129,27 @@ return false; }); - ## make_popupmenu( "#optionsbutton", { - ## "Create <b>new</b> workflow" : create_new_workflow_dialog, - ## "<b>Save</b> current workflow" : save_current_workflow, - ## "<b>Load</b> a stored workflow" : load_workflow - ## }); + make_popupmenu( $("#workflow-options-button"), { + ##"Create New" : create_new_workflow_dialog, + "Edit Attributes" : edit_workflow_attributes, + "Layout": layout_editor, + "Save" : save_current_workflow, + ##"Load a Workflow" : load_workflow, + "Close": close_editor, + }); - $("#save-button").click( function() { save_current_workflow(); } ); - $("#close-button").click( function() { close_editor(); } ); - - $("#layout-button").click( function() { + function layout_editor() { workflow.layout(); workflow.fit_canvas_to_nodes(); scroll_to_nodes(); canvas_manager.draw_overview(); - }); + }; - $('#edit-attributes-button').click( function() { + function edit_workflow_attributes() { workflow.clear_active_node(); $('#edit-attributes').show(); - $('#right-content').hide(); - }); + $('#right-content').hide(); + }; $.jStore.ready(function(engine) { engine.ready(function() { @@ -219,7 +220,7 @@ }); // Rename async. - async_save_text("workflow-rename", "workflow-name", "${h.url_for( action="rename_async", id=trans.security.encode_id(stored.id) )}", "new_name"); + async_save_text("workflow-name", "workflow-name", "${h.url_for( action="rename_async", id=trans.security.encode_id(stored.id) )}", "new_name"); // Tag async. Simply have the workflow edit element generate a click on the tag element to activate tagging. $('#workflow-tag').click( function() @@ -228,7 +229,7 @@ return false; }); // Annotate async. - async_save_text("workflow-annotate", "workflow-annotation", "${h.url_for( action="annotate_async", id=trans.security.encode_id(stored.id) )}", "new_annotation", true, 4); + async_save_text("workflow-annotation", "workflow-annotation", "${h.url_for( action="annotate_async", id=trans.security.encode_id(stored.id) )}", "new_annotation", 25, true, 4); }); // Global state for the whole workflow @@ -306,7 +307,7 @@ function show_form_for_tool( text, node ) { $("#edit-attributes").hide(); - $("#right-content").show().html( text ); + $("#right-content").show().html( text ); $("#right-content").find( "form" ).ajaxForm( { type: 'POST', dataType: 'json', @@ -337,17 +338,7 @@ $(this).remove(); make_popupmenu( b, options ); }); - // Add annotation field to form. - // TODO: need to set the annotation for this tool. - var annotation_div = - $( "<div class='form-row'> \ - <label>Annotation / Notes:</label> \ - <div style='margin-right: 10px;'> \ - <textarea name='annotation' rows='3' style='width: 100%'>" + node.annotation + "</textarea> \ - <div class='toolParamHelp'>Add an annotation or notes to this step; annotations are available when a workflow is viewed.</div> \ - </div> \ - </div>"); - $(this).append( annotation_div ); + // Implements auto-saving based on whether the inputs change. We consider // "changed" to be when a field is accessed and not necessarily modified // because of an issue where "onchange" is not triggered when activating @@ -358,6 +349,30 @@ }); }); }); + + + // Add metadata form to tool. + if ( node ) + { + var metadata_div = + $( "<p><div class='metadataForm'> \ + <div class='metadataFormTitle'>Edit Step Attributes</div> \ + <div class='form-row'> \ + <label>Annotation / Notes:</label> \ + <div style='margin-right: 10px;'> \ + <textarea name='annotation' rows='3' style='width: 100%'>" + node.annotation + "</textarea> \ + <div class='toolParamHelp'>Add an annotation or notes to this step; annotations are available when a workflow is viewed.</div> \ + </div> \ + </div> \ + </div>"); + // When metadata is changed, update node and set workflow changes flag. + var textarea = $(metadata_div).find("textarea"); + textarea.change( function () { + node.annotation = $(this).val(); + workflow.has_changes = true; + }); + $("#right-content").find(".toolForm").after( metadata_div ); + } } var close_editor = function() { @@ -373,7 +388,7 @@ { "Cancel" : hide_modal, "Save Changes" : function() { - save_current_workflow( do_close ); + save_current_workflow( null, do_close ); } }, { "Don't Save": do_close @@ -383,7 +398,7 @@ } } - var save_current_workflow = function ( success_callback ) { + var save_current_workflow = function ( eventObj, success_callback ) { show_modal( "Saving workflow", "progress" ); workflow.check_changes_in_active_form(); if (!workflow.has_changes) { @@ -739,13 +754,10 @@ <div class="unified-panel-header" unselectable="on"> <div class="unified-panel-header-inner" style="float: right"> - <a id="layout-button" class="panel-header-button">Layout</a> - - <a id="save-button" class="panel-header-button">Save</a> - <a id="close-button" class="panel-header-button">Close</a> + <a id="workflow-options-button" class="panel-header-button popup" href="#">Options</a> </div> <div class="unified-panel-header-inner"> - Workflow canvas + Workflow Canvas | ${stored.name | h} </div> </div> @@ -770,22 +782,17 @@ <div class="unified-panel-header" unselectable="on"> <div class="unified-panel-header-inner"> Details - <div style="float: right"> - <a id="edit-attributes-button" class="panel-header-button">Edit Workflow Attributes</a> - </div> </div> </div> <div class="unified-panel-body" style="overflow: auto;"> ## Div for elements to modify workflow attributes. - <div id="edit-attributes" class="toolForm right-content"> - <div class="toolFormTitle">Edit Workflow Attributes</div> - <div class="toolFormBody"> + <div id="edit-attributes" class="metadataForm right-content"> + <div class="metadataFormTitle">Edit Workflow Attributes</div> + <div class="metadataFormBody"> ## Workflow name. <div id="workflow-name-area" class="form-row"> <label>Name:</label> - <div style="float: right"><a id="workflow-rename" title="Rename" class="icon-button edit" target="galaxy_main" href="${h.url_for( controller='workflow', action='rename_sync' )}"></a></div> - <div id="workflow-name">${stored.name | h}</div> - <div style="clear: both"></div> + <span id="workflow-name" class="tooltip editable-text" original-title="Click to rename workflow">${stored.name | h}</span> </div> ## Workflow tags. <%namespace file="/tagging_common.mako" import="render_individual_tagging_element" /> @@ -793,24 +800,20 @@ <label> Tags: </label> - <div style="float: right"><a id="workflow-tag" title="Tag" class="icon-button edit" target="galaxy_main" href="${h.url_for( controller='workflow', action='annotate_async' )}"></a></div> <div style="float: left; width: 225px; margin-right: 10px; border-style: inset; border-width: 1px; margin-left: 2px"> <style> .tag-area { border: none; } </style> - ${render_individual_tagging_element(user=trans.get_user(), tagged_item=stored, elt_context="edit_attributes.mako", use_toggle_link=False, input_size="20", render_add_tag_button=False)} + ${render_individual_tagging_element(user=trans.get_user(), tagged_item=stored, elt_context="edit_attributes.mako", use_toggle_link=False, input_size="20")} </div> - <div style="clear: both"></div> <div class="toolParamHelp">Apply tags to make it easy to search for and find items with the same tag.</div> </div> ## Workflow annotation. <div id="workflow-annotation-area" class="form-row"> <label>Annotation / Notes:</label> - <div style="float: right"><a id="workflow-annotate" title="Annotate" class="icon-button edit" target="galaxy_main" href="${h.url_for( controller='workflow', action='annotate_async' )}"></a></div> - <div id="workflow-annotation">${annotation | h}</div> - <div style="clear: both"></div> + <span id="workflow-annotation" class="tooltip editable-text" original-title="Click to edit annotation">${annotation | h}</span> <div class="toolParamHelp">Add an annotation or notes to a workflow; annotations are available when a workflow is viewed.</div> </div> </div>