diff --git a/components/tools/OmeroWeb/omeroweb/webclient/controller/container.py b/components/tools/OmeroWeb/omeroweb/webclient/controller/container.py
index 585e2c0515c..8a53ead99f7 100755
--- a/components/tools/OmeroWeb/omeroweb/webclient/controller/container.py
+++ b/components/tools/OmeroWeb/omeroweb/webclient/controller/container.py
@@ -177,6 +177,29 @@ def getPlateId(self):
elif self.acquisition:
return self.acquisition._obj.plate.id.val
+
+ def listFigureScripts(self, objDict=None):
+ """
+ This configures all the Figure Scripts, setting their enabled status given the
+ currently selected object (self.image etc) or batch objects (uses objDict).
+ """
+ figureScripts = []
+ # id is used in url and is mapped to full script path by views.figure_script()
+ splitView = {'id': 'SplitView', 'name':'Split View Figure', 'enabled': False,
+ 'tooltip': "Create a figure of images, splitting their channels into separate views"}
+ # Split View Figure is enabled if we have at least one image with SizeC > 1
+ if self.image:
+ splitView['enabled'] = (self.image.getSizeC() > 1)
+ elif objDict is not None:
+ if 'image' in objDict:
+ for i in objDict['image']:
+ if i.getSizeC() > 1:
+ splitView['enabled'] = True
+ break
+ figureScripts.append(splitView)
+ return figureScripts
+
+
def openAstexViewerCompatible(self):
"""
Is the image suitable to be viewed with the Volume viewer 'Open Astex Viewer' applet?
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/dusty.css b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/dusty.css
index 74e7619c6fa..d84644a15b6 100755
--- a/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/dusty.css
+++ b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/dusty.css
@@ -136,6 +136,7 @@ button::-moz-focus-inner {
.btn_group {background: url(../../webgateway/img/icon_add_group.png )center center no-repeat;}
.btn_delete {background: url(../../webgateway/img/icon_delete.png )center center no-repeat;}
.btn_edit {background: url(../../webgateway/img/icon_edit.png )center center no-repeat;}
+ .btn_figscripts {background: url(../../webgateway/img/icon_figure_scripts.png) center center no-repeat;}
.btn_fspath {background: url(../../webgateway/img/icon_fs_path.png )center center no-repeat;}
.btn_link {background: url(../../webgateway/img/icon_link.png )center center no-repeat;}
@@ -163,7 +164,7 @@ button::-moz-focus-inner {
display:block;
}
- #general_tab .btn_download span {
+ .toolbar_dropdown .btn span {
width:20px;
height:18px;
display:block;
@@ -173,18 +174,19 @@ button::-moz-focus-inner {
background: url(../../webgateway/img/icon_download2.png) center center no-repeat;
}
- #download_dropdown .dropdown {
- right: 0px;
- left: auto;
- }
- #download_dropdown {
+ .toolbar_dropdown {
float:right;
margin-left: 5px;
+ position: relative;
+ }
+ .toolbar_dropdown .dropdown {
+ right: -35px;
+ left: auto;
}
- #download_dropdown .dropdown:before {
+ .toolbar_dropdown .dropdown:before {
left: 68% !important;
}
- #download_dropdown ul a {
+ .toolbar_dropdown ul a {
background: none;
font-size: 80%;
}
@@ -406,7 +408,7 @@ button::-moz-focus-inner {
}
.btn_text span {
- padding:6px 10px !important;
+ padding:3px 7px !important;
}
@@ -487,7 +489,7 @@ button::-moz-focus-inner {
width:12px;
height:12px;
position:absolute;
- z-index:99;
+ z-index:90;
right:5px;
top:5px;
-webkit-border-radius:20px;
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/layout.css b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/layout.css
index 653fae84879..6d9579e0295 100755
--- a/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/layout.css
+++ b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/css/layout.css
@@ -534,7 +534,7 @@
/* Right Inner Content */
.right_tab_inner {
- padding:15px;
+ padding:10px 15px;
overflow: auto;
top:6px ;bottom:0px; left:0px; right:0px;
position: absolute;
@@ -549,7 +549,7 @@
/* Seperator */
hr {
- margin:15px 0;
+ margin:10px 0;
display:block;
border:none;
border-bottom: solid 1px rgba(255,255,255,.8);
@@ -588,7 +588,7 @@
.data_heading {
- margin-bottom:20px;
+ margin-bottom:15px;
border-bottom:solid 1px hsl(210,10%,90%);
overflow:hidden;
-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5);
@@ -597,7 +597,7 @@
-moz-box-shadow:0 1px 0 rgba(255,255,255,.5); /* FF3.5+ */
box-shadow:0 1px 0 rgba(255,255,255,.5); /* Opera 10.5, IE 9.0 */
- padding:10px 0;
+ padding:10px 0 5px 0;
}
@@ -2284,7 +2284,22 @@ width: 250px;
}
+/* Figure scripts dialog */
+.rowDragHandle {
+ float: left;
+ visibility: hidden;
+ position: relative;
+ left: -5px;
+ width: 11px;
+ height: 30px;
+ border-radius: 4px;
+ cursor: pointer;
+ background:#ddd url(../image/drag_handle_arrows_up-down.png) no-repeat center center;
+}
+tr.figImageData:hover .rowDragHandle {
+ visibility: visible;
+}
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/image/drag_handle_arrows_up-down.png b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/image/drag_handle_arrows_up-down.png
new file mode 100644
index 00000000000..e72d9a1c064
Binary files /dev/null and b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/image/drag_handle_arrows_up-down.png differ
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/javascript/ome.split_view_figure.js b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/javascript/ome.split_view_figure.js
new file mode 100644
index 00000000000..4067854c9e5
--- /dev/null
+++ b/components/tools/OmeroWeb/omeroweb/webclient/static/webclient/javascript/ome.split_view_figure.js
@@ -0,0 +1,313 @@
+//
+// Copyright (C) 2013 University of Dundee & Open Microscopy Environment.
+// All rights reserved.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+$(document).ready(function() {
+ OME.setupAjaxError("{% url fsend %}"); // just in case!
+
+ $('#script_form').ajaxForm({
+ success: function(data) {
+ window.opener.OME.showActivities();
+ self.close();
+ }
+ });
+
+
+ // Basically what we're doing here is supplementing the form fields
+ // generated from the script itself to make a nier UI.
+ // We use these controls to update the paramter fields themselves,
+ // as well as updating the Figure preview.
+
+ $("#enableScalebar").click(function(){
+ var enabled = $(this).is(":checked");
+ if (enabled) {
+ $("input[name=Scalebar]").removeAttr("disabled").focus();
+ } else {
+ $("input[name=Scalebar]").attr("disabled", "disabled");
+ }
+ });
+
+ var $channelNamesMap = $("#channelNamesMap"),
+ $figure_table = $("#figure_table"),
+ $columnNames = $(".split_column .channel_name", $figure_table),
+ $mergedNames = $("div.merged_name", $figure_table),
+ $splitIndexes = $("input[name='Split_Indexes']");
+
+ var updateChannelNames = function() {
+ // Update Channel-Names map index:Name
+ var activeCs = [],
+ cNames = [];
+ $("#split_channels input[type=checkbox]").each(function(i) {
+ var cName = $('input[type=text]', $(this).parent()).val(),
+ idx = parseInt( $(this).attr('name'), 10 );
+ cNames.push(cName);
+ if ($(this).is(":checked")) {
+ activeCs.push(idx);
+ }
+ });
+ $('input[name*=Channel_Names_value]', $channelNamesMap).each(function(c){
+ $(this).val( cNames[c] );
+ });
+ // Update Split Indexes
+ $splitIndexes.val(activeCs.join(","));
+ // Update Figure - channels on/off
+ $figure_table.find('tr').each(function(){
+ $(this).find('td.split_column').each(function(c) {
+ if (activeCs.indexOf(c) > -1) {
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+ });
+ // Update Figure - channel Names
+ $columnNames.each(function(i){ // Column names
+ $(this).text(cNames[i]);
+ });
+ $mergedNames.each(function(i){ // Merged names
+ $(this).text(cNames[i]);
+ });
+
+ };
+ // Add / Remove Channels
+ $("#split_channels input[type=checkbox]").click(updateChannelNames);
+ // Renaming Channels
+ $("#split_channels input[type=text]").keyup(updateChannelNames);
+
+ var $mergecColoursMap = $("#mergedColoursMap");
+ var updateMergedChannels = function() {
+ // Update Merged-Colours map index:colourInt
+ $mergecColoursMap.empty();
+ var mergedCs = [],
+ mergedColurs = [];
+ $("#merged_channels input[type=checkbox]:checked").each(function(i){
+ var colourInt = $(this).attr('value'),
+ idx = parseInt( $(this).attr('name'), 10 ),
+ html = "" +
+ "";
+ mergedCs.push(idx+1); // Use 1-based Channel idx for rendering
+ $(html).appendTo($mergecColoursMap);
+ });
+ // Update url of merged panels in Figure
+ $(".merged_column img").each(function(){
+ // remember original src
+ var $this = $(this);
+ if (typeof $this.data('src') === 'undefined') {
+ $this.data('src', $this.attr('src'));
+ }
+ var newSrc = $this.data('src') + "?c=" + mergedCs.join(",");
+ $this.attr('src', newSrc);
+ });
+ // Merged Channel names
+ $mergedNames.each(function(i) {
+ if (mergedCs.indexOf(i+1) > -1) {
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+
+ };
+ // When merged channels are toggled
+ $("#merged_channels input[type=checkbox]").click(function() {
+ updateMergedChannels();
+ updateGrey();
+ });
+
+ // Used to make sure we don't have white labels (on white background!)
+ var checkNotWhite = function(cssColour) {
+ if (cssColour === "rgb(255, 255, 255)") {
+ cssColour = "rgb(0,0,0)";
+ }
+ return cssColour;
+ };
+ // checkNotWhite for each of the mergedNames
+ $mergedNames.each(function(){
+ var $mn = $(this);
+ $mn.css('color', checkNotWhite($mn.css('color')));
+ });
+
+ var $splitPanelsGrey = $("input[name=Split_Panels_Grey]");
+ var updateGrey = function() {
+ // Split Channels grey if 'splitPanelsGrey' OR channel is not merged
+ var grey = $splitPanelsGrey.is(":checked"),
+ mergedCs = [];
+ $("#merged_channels input[type=checkbox]:checked").each(function(i){
+ mergedCs.push( parseInt( $(this).attr('name'), 10 ));
+ });
+ $columnNames.each(function(i){
+ var $this = $(this);
+ // Note the original color if we haven't done so already
+ if (typeof $this.data('color') === 'undefined') {
+ $this.data('color', checkNotWhite($this.css('color')));
+ }
+ // Apply color or black to column Names
+ if (grey && mergedCs.indexOf(i) > -1) {
+ $this.css('color', $this.data('color'));
+ } else {
+ $this.css('color', 'rgb(0,0,0)');
+ }
+ });
+ // Update url of split panels in Figure
+ $(".split_column img").each(function(){
+ // remember original src
+ var $this = $(this),
+ colIdx = parseInt($this.attr("colIdx"), 10),
+ chGrey = (grey || (mergedCs.indexOf(colIdx) === -1)),
+ flag = chGrey ? "g" : "c";
+ if (typeof $this.data('src') === 'undefined') {
+ $this.data('src', $this.attr('src'));
+ }
+ var newSrc = $this.data('src') + "&m=" + flag;
+ $this.attr('src', newSrc);
+ });
+ };
+ // Update grey on checkbox click
+ $splitPanelsGrey.click(updateGrey);
+
+ // Merged names
+ $("input[name=Merged_Names]").click(function(){
+ if ( $(this).is(":checked") ) {
+ $("#merged_label").hide();
+ $("#merged_names").show();
+ } else {
+ $("#merged_label").show();
+ $("#merged_names").hide();
+ }
+ });
+
+
+ // Z selection.
+ // NB: We disable Z-projection by clearing the zStart and zEnd fields.
+ var $zRangeSlider = $("#zRangeSlider"),
+ $zProjectionControls = $("#zProjectionControls"),
+ $zStart = $("input[name=Z_Start]"),
+ $zEnd = $("input[name=Z_End]"),
+ zMin = parseInt($zStart.val(), 10),
+ zMax = parseInt($zEnd.val(), 10),
+ $algorithm = $("select[name=Algorithm]"),
+ $stepping = $("input[name=Stepping]");
+ $zRangeSlider.slider({
+ range: true,
+ min: zMin,
+ max: zMax,
+ values: [ zMin, zMax ],
+ slide: function( event, ui ) {
+ $zStart.val(ui.values[ 0 ]);
+ $zEnd.val(ui.values[ 1 ]);
+ }
+ }).slider( "disable" ); // enable if user chooses zProjection
+ $("input[name=zProjection]").click(function(){
+ if($(this).attr('value') === "z_projection"){
+ $zRangeSlider.slider( "enable" );
+ $zProjectionControls.show();
+ $zStart.removeAttr("disabled");
+ $zEnd.removeAttr("disabled");
+ $algorithm.removeAttr("disabled");
+ $stepping.removeAttr("disabled");
+ } else {
+ $zProjectionControls.hide();
+ $zRangeSlider.slider( "disable" );
+ $zStart.attr("disabled", "disabled");
+ $zEnd.attr("disabled", "disabled");
+ $algorithm.attr("disabled", "disabled");
+ $stepping.attr("disabled", "disabled");
+ }
+ });
+ // Don't allow users to type values here
+ $zStart.keydown(function(){ return false; });
+ $zEnd.keydown(function(){ return false; });
+
+
+ // Image Labels
+ var $Image_Labels = $("select[name=Image_Labels]"),
+ $rowLabels = $(".rowLabel>div"),
+ $imgName = $("div.imgName"),
+ $imgTags = $("div.imgTags"),
+ $imgDatasets = $("div.imgDatasets");
+ $Image_Labels.change(function(){
+ var labels = $(this).val();
+ $rowLabels.hide(); // hide all then show one...
+ if (labels == "Image Name") {
+ $imgName.show();
+ } else if (labels == "Datasets") {
+ $imgDatasets.show();
+ } else if (labels == "Tags") {
+ $imgTags.show();
+ }
+ updateColWidths();
+ });
+
+
+ // Drag and Drop to re-order rows
+ $('table tbody').sortable({
+ disabled: false,
+ items: 'tr.figImageData',
+ handle: '.rowDragHandle',
+ opacity: 0.7,
+ axis: 'y',
+ forceHelperSize: true,
+ update: function( e, ui ) {
+ var sortedIds = []
+ $(".figImageData").each(function(){
+ sortedIds.push($(this).attr('data-imageId') );
+ });
+ $("input[name=IDs]").val(sortedIds.join(","));
+ }
+ });
+ // set
widths, so that while rows are drag-n-dropped, | widths stay the same
+ var updateColWidths = function() {
+ $(".figImageData>td")
+ .removeAttr('width') // clear any previous setting
+ .each(function(){
+ var $td = $(this);
+ $td.attr('width', $td.width());
+ });
+ }
+
+ // Lets sync everything to start with:
+ updateChannelNames();
+ updateMergedChannels();
+ updateGrey();
+ updateColWidths();
+
+
+ // Bonus feature - Zoom the preview thumbs with slider
+ // Make a list of styles (for quick access on zoom)
+ var img_panel_styles = [];
+ $(".img_panel").each(function(){
+ img_panel_styles.push(this.style);
+ });
+ var setImgSize = function(size) {
+ var i, l = img_panel_styles.length;
+ for (i=0; i.
+//
+
/*global OME:true */
if (typeof OME === "undefined") {
OME = {};
@@ -283,6 +301,36 @@ OME.deleteItem = function(event, domClass, url) {
return false;
};
+// More code that is shared between metadata_general and batch_annotate panels
+// Called when panel loaded. Does exactly what it says on the tin.
+OME.initToolbarDropdowns = function() {
+ // -- Toolbar buttons - show/hide dropdown options --
+ $(".toolbar_dropdown ul").css('visibility', 'hidden');
+ // show on click
+ var $toolbar_dropdownlists = $(".toolbar_dropdown ul");
+ $(".toolbar_dropdown button").click(function(e) {
+ // hide any other lists that might be showing...
+ $toolbar_dropdownlists.css('visibility', 'hidden');
+ // then show this one...
+ $("ul", $(this).parent()).css('visibility', 'visible');
+ e.preventDefault();
+ return false;
+ });
+ // on hover-out, hide drop-down menus
+ $toolbar_dropdownlists.hover(function(){}, function(){
+ $(this).css('visibility', 'hidden');
+ });
+
+ // For Figure scripts, we need a popup:
+ $("#figScriptList li a").click(function(event){
+ if (!$(this).parent().hasClass("disabled")) {
+ OME.openScriptWindow(event, 800, 600);
+ }
+ event.preventDefault();
+ return false;
+ });
+};
+
jQuery.fn.tooltip_init = function() {
$(this).tooltip({
bodyHandler: function() {
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/batch_annotate.html b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/batch_annotate.html
index ead6c1872c1..5c4abe9fadd 100644
--- a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/batch_annotate.html
+++ b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/batch_annotate.html
@@ -242,6 +242,9 @@
var url = $(this).attr('href');
OME.deleteItem(event, "file_ann_wrapper", url);
});
+
+
+ OME.initToolbarDropdowns();
});
@@ -261,7 +264,7 @@
-
+
Annotate
{{ obj_labels|length }} objects:
@@ -278,16 +281,28 @@
{% endfor %}
+
+
+
-
+
+ {% include "webclient/annotations/includes/figure_scripts_menu.html" %}
+
+
+
+
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/includes/figure_scripts_menu.html b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/includes/figure_scripts_menu.html
new file mode 100644
index 00000000000..728670631fa
--- /dev/null
+++ b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/includes/figure_scripts_menu.html
@@ -0,0 +1,36 @@
+{% comment %}
+
+{% endcomment %}
+
+
+
\ No newline at end of file
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/includes/toolbar.html b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/includes/toolbar.html
new file mode 100644
index 00000000000..b60edb888ab
--- /dev/null
+++ b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/includes/toolbar.html
@@ -0,0 +1,70 @@
+{% comment %}
+
+{% endcomment %}
+
+
+
+
+
+
+
+
+
+ {% if manager.image %}
+
+
+
+ {% if manager.image.showOriginalFilePaths %}
+
+
+ {% endif %}
+
+ {% endif %}
+
+
+
+ {% include "webclient/annotations/includes/figure_scripts_menu.html" %}
+
+
+
\ No newline at end of file
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/metadata_general.html b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/metadata_general.html
index 877128ff962..75f1312815f 100644
--- a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/metadata_general.html
+++ b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/annotations/metadata_general.html
@@ -285,18 +285,8 @@
});
- // -- Download options --
- $("#download_dropdown ul").css('visibility', 'hidden');
- // show on click
- $("#show_download_dropdown").click(function(e) {
- $("ul", $(this).parent()).css('visibility', 'visible');
- e.preventDefault();
- return false;
- });
- // on hover-out, hide drop-down menus
- $("#download_dropdown ul").hover(function(){}, function(){
- $(this).css('visibility', 'hidden');
- });
+ // We do this here and in batch_annotate panel
+ OME.initToolbarDropdowns();
// Handle Download actions
$("#create-ometiff").click(function(e){
@@ -448,54 +438,32 @@
{% if manager.image %}
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
{% with obj=manager.image nameText=manager.image.name %}
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
-
-
-
- Image ID: {{ manager.image.id }}
+
+
+
+
+ {{ manager.obj_type }} ID: {{ manager.obj_id }}
-
-
{% if manager.image.showOriginalFilePaths %}
@@ -511,16 +479,10 @@
-
-
- {% trans "Launch full viewer" %}
-
-
-
+
{% if manager.openAstexViewerCompatible %}
-
{% trans "Volume viewer" %}
@@ -530,7 +492,7 @@
-
+
@@ -562,23 +524,19 @@
{% else %}
{% if manager.dataset %}
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
{% with obj=manager.dataset nameText=manager.dataset.name %}
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
-
- Dataset ID: {{ manager.dataset.id }}
-
-
-
-
-
-
+
+
+ {{ manager.obj_type }} ID: {{ manager.obj_id }}
+
+
@@ -599,22 +557,18 @@
{% else %}
{% if manager.project %}
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
{% with obj=manager.project nameText=manager.project.name %}
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
+
- Project ID: {{ manager.project.id }}
-
-
-
-
-
-
+ {{ manager.obj_type }} ID: {{ manager.obj_id }}
+
+
@@ -638,29 +592,29 @@
{% if manager.well %}
-
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
+
{% with obj=manager.well.getWellSample.image nameText=manager.well.getWellSample.image.name %}
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
-
- Image ID: {{ manager.well.getWellSample.image.id }} Well ID: {{ manager.well.id }}
-
-
-
-
-
+
+
+
+ Image ID: {{ manager.well.getWellSample.image.id }}
+ Well ID: {{ manager.well.id }}
-
+
{% trans "Launch full viewer" %}
+
+
@@ -676,11 +630,14 @@
{% else %}
{% if manager.acquisition %}
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
{% with obj=manager.acquisition nameText=manager.acquisition.name %}
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
+
Plate Run ID: {{ manager.acquisition.id }}
@@ -692,7 +649,7 @@
-
+
@@ -713,21 +670,16 @@
{% else %}
{% if manager.plate %}
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
{% with obj=manager.plate nameText=manager.plate.name %}
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
+
- Plate ID: {{ manager.plate.id }}
-
-
-
-
-
+ {{ manager.obj_type }} ID: {{ manager.obj_id }}
@@ -757,21 +709,15 @@
{% else %}
{% if manager.screen %}
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
{% with obj=manager.screen nameText=manager.screen.name %}
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
- Screen ID: {{ manager.screen.id }}
-
-
-
-
-
+ {{ manager.obj_type }} ID: {{ manager.obj_id }}
@@ -1047,6 +993,10 @@ Contained in Datasets
{% if manager.tag %}
+
+
+ {% include "webclient/annotations/includes/toolbar.html" %}
+
@@ -1054,17 +1004,8 @@ Contained in Datasets
{% include "webclient/annotations/includes/name.html" %}
{% endwith %}
-
- Tag ID: {{ manager.tag.id }}
-
-
-
-
-
-
+
+
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/base/includes/script_launch_head.html b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/base/includes/script_launch_head.html
index b8b0fd6a816..68e300a4d97 100644
--- a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/base/includes/script_launch_head.html
+++ b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/base/includes/script_launch_head.html
@@ -20,17 +20,8 @@
{% endblock %}
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/scripts/split_view_figure.html b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/scripts/split_view_figure.html
new file mode 100644
index 00000000000..d9d09f7d372
--- /dev/null
+++ b/components/tools/OmeroWeb/omeroweb/webclient/templates/webclient/scripts/split_view_figure.html
@@ -0,0 +1,401 @@
+{% extends "webgateway/base/base_header.html" %}
+{% load i18n %}
+
+{% comment %}
+
+{% endcomment %}
+
+{% comment %}
+
+{% endcomment %}
+
+{% block title %}
+ Create Split View Figure
+{% endblock %}
+
+
+
+{% block script %}
+ {{ block.super }}
+ {% include "webgateway/base/includes/script_src_jquery.html" %}
+ {% include "webgateway/base/includes/script_src_popup.html" %}
+ {% include "webgateway/base/includes/jquery-ui.html" %}
+
+
+
+
+
+
+
+{% endblock %}
+
+
+{% block middle_header_left %}
+
+{% endblock %}
+
+
+{% block content %}
+
+
+
+{% endblock %}
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/urls.py b/components/tools/OmeroWeb/omeroweb/webclient/urls.py
index ce729f403c1..a3fd59a5812 100755
--- a/components/tools/OmeroWeb/omeroweb/webclient/urls.py
+++ b/components/tools/OmeroWeb/omeroweb/webclient/urls.py
@@ -132,6 +132,8 @@
url( r'^script_ui/(?P [0-9]+)/$', views.script_ui, name='script_ui' ), # shows a form for running a script
url( r'^script_run/(?P[0-9]+)/$', views.script_run, name='script_run' ), # runs the script - parameters in POST
url( r'^get_original_file/(?:(?P[0-9]+)/)?$', views.get_original_file, name="get_original_file"), # for stderr, stdout etc
+ url( r'^figure_script/(?P((?i)SplitView|RoiSplit))/$',
+ views.figure_script, name='figure_script' ), # shows a form for running a script
# ome_tiff_script: generate OME-TIFF and attach to image (use script service). Must be POST
url( r'^ome_tiff_script/(?P[0-9]+)/$', views.ome_tiff_script, name='ome_tiff_script' ),
diff --git a/components/tools/OmeroWeb/omeroweb/webclient/views.py b/components/tools/OmeroWeb/omeroweb/webclient/views.py
index 2108e90343e..691ab645d9c 100755
--- a/components/tools/OmeroWeb/omeroweb/webclient/views.py
+++ b/components/tools/OmeroWeb/omeroweb/webclient/views.py
@@ -818,6 +818,7 @@ def load_metadata_details(request, c_type, c_id, conn=None, share_id=None, **kwa
if share_id is None:
template = "webclient/annotations/metadata_general.html"
manager.annotationList()
+ figScripts = manager.listFigureScripts()
form_comment = CommentAnnotationForm(initial=initial)
else:
template = "webclient/annotations/annotations_share.html"
@@ -825,7 +826,8 @@ def load_metadata_details(request, c_type, c_id, conn=None, share_id=None, **kwa
if c_type in ("tag"):
context = {'manager':manager}
else:
- context = {'manager':manager, 'form_comment':form_comment, 'index':index, 'share_id':share_id}
+ context = {'manager':manager, 'form_comment':form_comment, 'index':index,
+ 'share_id':share_id, 'figScripts':figScripts}
context['template'] = template
context['webclient_path'] = request.build_absolute_uri(reverse('webindex'))
return context
@@ -1090,6 +1092,7 @@ def batch_annotate(request, conn=None, **kwargs):
manager = BaseContainer(conn)
batchAnns = manager.loadBatchAnnotations(objs)
+ figScripts = manager.listFigureScripts(objs)
obj_ids = []
obj_labels = []
@@ -1101,7 +1104,8 @@ def batch_annotate(request, conn=None, **kwargs):
link_string = "|".join(obj_ids).replace("=", "-")
context = {'form_comment':form_comment, 'obj_string':obj_string, 'link_string': link_string,
- 'obj_labels': obj_labels, 'batchAnns': batchAnns, 'batch_ann':True, 'index': index}
+ 'obj_labels': obj_labels, 'batchAnns': batchAnns, 'batch_ann':True, 'index': index,
+ 'figScripts':figScripts}
context['template'] = "webclient/annotations/batch_annotate.html"
context['webclient_path'] = request.build_absolute_uri(reverse('webindex'))
return context
@@ -2400,6 +2404,61 @@ def script_ui(request, scriptId, conn=None, **kwargs):
return {'template':'webclient/scripts/script_ui.html', 'paramData': paramData, 'scriptId': scriptId}
+
+@login_required()
+@render_response()
+def figure_script(request, scriptName, conn=None, **kwargs):
+ """
+ Show a UI for running figure scripts
+ """
+
+ imageIds = request.REQUEST.get('Image', None) # comma - delimited list
+ if imageIds is None:
+ return HttpResponse("Need to specify Images as /?Image=1,2")
+ try:
+ imageIds = [long(i) for i in imageIds.split(",")]
+ except Exception, e:
+ return HttpResponse("Need to specify Images as /?Image=1,2")
+
+ images = list( conn.getObjects("Image", imageIds) )
+ if len(images) == 0:
+ raise Http404("No Images found with IDs %s" % imageIds)
+
+ # 'images' list is not sorted. Only use it for validating imageIds
+ validImages = {}
+ for img in images:
+ validImages[img.getId()] = img
+ imageIds = [iid for iid in imageIds if iid in validImages]
+
+ # Lookup Tags & Datasets (for row labels)
+ imgDict = [] # A list of data about each image.
+ for iId in imageIds:
+ data = {'id':iId}
+ img = validImages[iId]
+ data['name'] = img.getName()
+ tags = [ann.getTextValue() for ann in img.listAnnotations() if ann._obj.__class__ == omero.model.TagAnnotationI]
+ data['tags'] = tags
+ data['datasets'] = [d.getName() for d in img.listParents()]
+ imgDict.append(data)
+
+ # Use the first image as a reference
+ image = validImages[imageIds[0]]
+ channels = image.getChannels()
+
+ scriptService = conn.getScriptService()
+ scriptPath = "/omero/figure_scripts/Split_View_Figure.py"
+ scriptId = scriptService.getScriptID(scriptPath);
+ if (scriptId < 0):
+ raise AttributeError("No script found for path '%s'" % scriptPath)
+
+ idString = ",".join( [str(i) for i in imageIds] )
+
+
+
+ return {"template": "webclient/scripts/split_view_figure.html", "scriptId": scriptId,
+ "image": image, "imgDict": imgDict, "idString":idString, "channels": channels, "tags": tags}
+
+
@login_required()
def chgrp(request, conn=None, **kwargs):
"""
@@ -2464,8 +2523,8 @@ def script_run(request, scriptId, conn=None, **kwargs):
continue
if pclass.__name__ == 'RMapI':
- keyName = "%s_key" % key
- valueName = "%s_value" % key
+ keyName = "%s_key0" % key
+ valueName = "%s_value0" % key
row = 0
paramMap = {}
while keyName in request.POST:
diff --git a/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/css/ome.header.css b/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/css/ome.header.css
index 6555304856c..e8fc03b7541 100644
--- a/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/css/ome.header.css
+++ b/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/css/ome.header.css
@@ -228,7 +228,11 @@
#launch_basket a{
background: url(../img/icon_basket.png) center center no-repeat;
}
-
+
+ #figScriptButton{
+ background: url(../img/icon_figure_scripts.png) center center no-repeat;
+ }
+
#scriptButton{
background: url(../img/icon_script.png) center center no-repeat;
}
@@ -459,12 +463,19 @@
float:none;
position:relative;
}
+
+ .dropdown li.disabled {
+ background: transparent;
+ }
+ .dropdown li.disabled a {
+ color: #999;
+ }
- .dropdown > li > a {
+ /* The menuItem class is added by js to items with children */
+ .dropdown > li > a.menuItem {
background:url(../img/dropdown_right_arrow.png) 90% center no-repeat;
}
-
- .dropdown > li:hover > a {
+ .dropdown > li:hover > a.menuItem {
background:url(../img/dropdown_right_arrow_hover.png) 90% center no-repeat;
}
@@ -484,6 +495,12 @@
filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#6B8FB3', endColorstr='#5C7A99',GradientType=0 ); /* IE6-9 */
background:linear-gradient(top, hsl(210,50%,60%) 0%,hsl(210,50%,50%) 100%); /* W3C */
+ }
+
+ .dropdown li.disabled:hover {
+ background: transparent !important;
+ border-bottom: 1px solid transparent;
+ border-top: 1px solid transparent;
}
.dropdown a, #group_user_chooser li strong{
@@ -510,6 +527,10 @@
color:white ;
text-shadow:none !important;
}
+
+ .dropdown li.disabled:hover a {
+ color: #999;
+ }
.dropdown li ul li a{
color:#333 !important;
diff --git a/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/img/icon_figure_scripts.png b/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/img/icon_figure_scripts.png
new file mode 100644
index 00000000000..f2652d813df
Binary files /dev/null and b/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/img/icon_figure_scripts.png differ
diff --git a/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/js/ome.popup.js b/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/js/ome.popup.js
index ef013ca56c3..55a6aa159b4 100644
--- a/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/js/ome.popup.js
+++ b/components/tools/OmeroWeb/omeroweb/webgateway/static/webgateway/js/ome.popup.js
@@ -34,6 +34,58 @@ jQuery.fn.alternateRowColors = function() {
return this;
};
+
+// Call this on an to only allow numbers.
+// I rejects all non-numeric characters but allows paste (then checks value)
+// By default it only allows positive ints.
+// To allow negative or float values use $(".number").numbersOnly({negative:true, float:true});
+jQuery.fn.numbersOnly = function(options) {
+
+ // First, save the current value (assumed to be valid)
+ this.each(function() {
+ $(this).data('numbersOnly', $(this).val());
+ })
+ .keypress(function(event){
+
+ // we allow copy, paste, left or right
+ var allowedChars = [37, 39, 99, 118];
+ if (options && options.negative) {
+ allowedChars.push(45);
+ }
+ if (options && options.float) {
+ allowedChars.push(46);
+ }
+ // Reject keypress if not a number and NOT one of our allowed Chars
+ var charCode = (event.which) ? event.which : event.keyCode;
+ if (charCode > 31 && (charCode < 48 || charCode > 57) && allowedChars.indexOf(charCode) == -1) {
+ return false;
+ }
+
+ // We've allowed keypress (including paste)...
+ //finally check field value after waiting for keypress to update...
+ var $this = $(this);
+ setTimeout(function(){
+ var n = $this.val();
+ var isNumber = function(n) {
+ if (n.length === 0) {
+ return true; // empty strings are allowed
+ }
+ return !isNaN(parseFloat(n)) && isFinite(n);
+ };
+ // If so, save to 'data', otherwise revert to 'data'
+ if (isNumber(n)) {
+ $this.data('numbersOnly', n); // update
+ } else {
+ $this.val( $this.data('numbersOnly') );
+ }
+ }, 10);
+
+ return true;
+ });
+
+ return this;
+};
+
OME.openPopup = function(url) {
// IE8 doesn't support arbitrary text for 'name' 2nd arg. #6118
var owindow = window.open(url, '', 'height=600,width=850,left=50,top=50,toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,directories=no,status=no');
@@ -44,9 +96,9 @@ OME.openPopup = function(url) {
};
-OME.openCenteredWindow = function(url) {
- var width = 550;
- var height = 600;
+OME.openCenteredWindow = function(url, w, h) {
+ var width = w ? +w : 550;
+ var height = h ? +h : 600;
var left = parseInt((screen.availWidth/2) - (width/2), 10);
var top = 0;
var windowFeatures = "width=" + width + ",height=" + height + ",status=no,resizable=yes,scrollbars=yes,menubar=no,toolbar=no,left=" + left + ",top=" + top + "screenX=" + left + ",screenY=" + top;
@@ -58,6 +110,17 @@ OME.openCenteredWindow = function(url) {
};
+OME.openScriptWindow = function(event, width, height) {
+ // open script url, providing Data_Type and IDs params in request
+ var script_url = $(event.target).attr('href');
+ if (script_url == "#") return false;
+
+ script_url += "?"+ OME.get_tree_selection();
+ OME.openCenteredWindow(script_url, width, height);
+ return false;
+};
+
+
/*
* Returns a string representing the currently selected items in the $.jstree.
* E.g. "Image=23,34,98&Dataset=678"
@@ -115,13 +178,13 @@ OME.get_tree_selection = function() {
OME.confirm_dialog = function(dialog_text, callback, title, button_labels, width, height) {
if ((typeof title == "undefined") || (title === null)) {
- var title = "Confirm";
+ title = "Confirm";
}
if ((typeof width == "undefined") || (width === null)) {
- var width = 350;
+ width = 350;
}
if ((typeof height == "undefined") || (height === null)) {
- var height = 140;
+ height = 140;
}
var $dialog = $("#confirm_dialog");
@@ -637,4 +700,4 @@ if (false) { // set to 'true' to run. NB: Need to uncomment '
}
console.dir(differences); // comment out to keep jsHint happy!
}, 1000);
-}
\ No newline at end of file
+}
|