improved GUI

This commit is contained in:
Francesco Mangiacrapa 2020-11-20 18:10:43 +01:00
parent dfac6a38f8
commit ca5a5dbb00
14 changed files with 256 additions and 129 deletions

View File

@ -59,11 +59,14 @@ public class OLMapManager {
if(!olMap.mapInstancied()) if(!olMap.mapInstancied())
return; return;
if (olMap.isQueryPointActive()) { // if (olMap.isQueryPointActive()) {
GeoQuery select = toDataPointQuery(coordinate); // GeoQuery select = toDataPointQuery(coordinate);
layerManagerBus.fireEvent(new QueryDataEvent(select, coordinate)); // layerManagerBus.fireEvent(new QueryDataEvent(select, coordinate));
//
} // }
GeoQuery select = toDataPointQuery(coordinate);
layerManagerBus.fireEvent(new QueryDataEvent(select, coordinate));
} }
@ -103,7 +106,6 @@ public class OLMapManager {
@Override @Override
public void mapZoomEndListener(MapEvent event) { public void mapZoomEndListener(MapEvent event) {
//onInit
//onInit //onInit
if(!olMap.mapInstancied()) if(!olMap.mapInstancied())
return; return;
@ -153,11 +155,6 @@ public class OLMapManager {
double y2 = Math.max(lat + geoWidth, lat - geoWidth); double y2 = Math.max(lat + geoWidth, lat - geoWidth);
// GWT.log("("+x1+","+y1+")("+x2+","+y2+")"); // GWT.log("("+x1+","+y1+")("+x2+","+y2+")");
// Point pt = new Point(coordinate);
// ol.Extent extent = pt.getExtent();
// //new ClickDataInfo(x1, y1, x2, y2)
// SelectDataInfo selectDataInfo
// selectBox(new GeoQuery(x1, y1, x2, y2, GeoQuery.TYPE.POINT));
GeoQuery select = new GeoQuery(x1, y1, x2, y2, TYPE.POINT); GeoQuery select = new GeoQuery(x1, y1, x2, y2, TYPE.POINT);
return select; return select;
} }

View File

@ -301,35 +301,6 @@ public abstract class OpenLayerOSM {
} }
// /**
// * Adds the WMS layer.
// *
// * @param mapServerHost the map server host
// * @param layerName the layer name
// */
// public void addWMSLayer(String mapServerHost, String layerName) {
//
// ImageWmsParams imageWMSParams = OLFactory.createOptions();
// imageWMSParams.setLayers(layerName);
//
// ImageWmsOptions imageWMSOptions = OLFactory.createOptions();
// imageWMSOptions.setUrl(mapServerHost);
// imageWMSOptions.setParams(imageWMSParams);
// //imageWMSOptions.setRatio(1.5f);
//
// ImageWms imageWMSSource = new ImageWms(imageWMSOptions);
//
// LayerOptions layerOptions = OLFactory.createOptions();
// layerOptions.setSource(imageWMSSource);
//
// Image wmsLayer = new Image(layerOptions);
//
// //visibleLayerItems
//
// map.addLayer(wmsLayer);
// }
/** /**
* Adds the point vector source. * Adds the point vector source.
* *

View File

@ -8,6 +8,7 @@ import org.gcube.portlets.user.geoportaldataviewer.shared.products.model.RecordD
import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.constants.ButtonType; import com.github.gwtbootstrap.client.ui.constants.ButtonType;
import com.github.gwtbootstrap.client.ui.constants.IconSize;
import com.github.gwtbootstrap.client.ui.constants.IconType; import com.github.gwtbootstrap.client.ui.constants.IconType;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickEvent;
@ -44,7 +45,8 @@ public class DetailsPanel extends Composite {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
closeButton.setType(ButtonType.LINK); closeButton.setType(ButtonType.LINK);
closeButton.setIcon(IconType.REMOVE_SIGN); closeButton.setIcon(IconType.REMOVE);
closeButton.setIconSize(IconSize.LARGE);
closeButton.addClickHandler(new ClickHandler() { closeButton.addClickHandler(new ClickHandler() {

View File

@ -38,9 +38,6 @@ public class GeonaDataViewMainPanel extends Composite {
*/ */
interface GeonaDataViewMainPanelUiBinder extends UiBinder<Widget, GeonaDataViewMainPanel> { interface GeonaDataViewMainPanelUiBinder extends UiBinder<Widget, GeonaDataViewMainPanel> {
} }
// @UiField
// Tab mapTabPanel;
@UiField @UiField
HTMLPanel mainContainerPanel; HTMLPanel mainContainerPanel;
@ -48,7 +45,6 @@ public class GeonaDataViewMainPanel extends Composite {
@UiField @UiField
HTMLPanel mainToolBar; HTMLPanel mainToolBar;
@UiField @UiField
NavLink dataPointSelection; NavLink dataPointSelection;

View File

@ -12,7 +12,7 @@
<g:HTMLPanel ui:field="mainContainerPanel"> <g:HTMLPanel ui:field="mainContainerPanel">
<g:HTMLPanel ui:field="mainToolBar" <g:HTMLPanel ui:field="mainToolBar"
addStyleNames="inner-toolbar"> addStyleNames="inner-toolbar">
<b:DropdownButton type="LINK" text="Query"> <b:DropdownButton type="LINK" text="Query" visible="false">
<!-- <b:ButtonGroup toggle="checkbox" ui:field="buttonGroup"> --> <!-- <b:ButtonGroup toggle="checkbox" ui:field="buttonGroup"> -->
<b:NavLink ui:field="dataPointSelection" <b:NavLink ui:field="dataPointSelection"
addStyleNames="{style.margin-right-10}">Data Point addStyleNames="{style.margin-right-10}">Data Point

View File

@ -0,0 +1,69 @@
package org.gcube.portlets.user.geoportaldataviewer.client.ui;
import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.Modal;
import com.github.gwtbootstrap.client.ui.ModalFooter;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Widget;
/**
* The Class ModalWindow.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Nov 20, 2020
*/
public class ModalWindow {
private Modal modal;
private Object caller;
/**
* Instantiates a new modal window.
*
* @param title the title
* @param toAdd the to add
* @param toReturn the to return
*/
public ModalWindow(String title) {
modal = new Modal(false);
modal.hide(false);
modal.setTitle(title);
modal.setCloseVisible(true);
modal.setWidth(900);
ModalFooter modalFooter = new ModalFooter();
final Button buttClose = new Button("Close");
modalFooter.add(buttClose);
buttClose.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
modal.hide();
}
});
modal.add(modalFooter);
}
public void add(Widget toAdd) {
modal.add(toAdd);
}
public void setCaller(Object caller) {
this.caller = caller;
}
public void show() {
modal.show();
}
public void setWidth(int width) {
modal.setWidth(width);
}
}

View File

@ -1,6 +1,8 @@
package org.gcube.portlets.user.geoportaldataviewer.client.ui.images; package org.gcube.portlets.user.geoportaldataviewer.client.ui.images;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.ModalWindow;
import org.gcube.portlets.user.geoportaldataviewer.client.util.NewBrowserWindow; import org.gcube.portlets.user.geoportaldataviewer.client.util.NewBrowserWindow;
import org.gcube.portlets.user.geoportaldataviewer.client.util.StringUtil;
import org.gcube.portlets.user.geoportaldataviewer.shared.products.content.WorkspaceContentDV; import org.gcube.portlets.user.geoportaldataviewer.shared.products.content.WorkspaceContentDV;
import org.gcube.portlets.user.geoportaldataviewer.shared.products.model.UploadedImageDV; import org.gcube.portlets.user.geoportaldataviewer.shared.products.model.UploadedImageDV;
@ -39,71 +41,81 @@ public class ImageView extends Composite {
Paragraph paragraph1; Paragraph paragraph1;
@UiField @UiField
Button expandImage; Button openImage;
@UiField
Button viewImage;
private WorkspaceContentDV latest; private WorkspaceContentDV latest;
public ImageView(UploadedImageDV imageDV) { public ImageView(UploadedImageDV imageDV, final boolean showView, final boolean showOpen) {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
imageDV.getDidascalia();
heading.setText(imageDV.getTitolo()); heading.setText(imageDV.getTitolo());
paragraph1.setText(imageDV.getDidascalia()); paragraph1.setText(imageDV.getDidascalia());
if(imageDV.getListWsContent()!=null && imageDV.getListWsContent().size()>0) { if(imageDV.getListWsContent()!=null && imageDV.getListWsContent().size()>0) {
latest = imageDV.getListWsContent().get(imageDV.getListWsContent().size()-1); latest = imageDV.getListWsContent().get(imageDV.getListWsContent().size()-1);
expandImage.setVisible(true); openImage.setVisible(true);
viewImage.setVisible(true);
imageURL.setVisible(true); imageURL.setVisible(true);
imageURL.setUrl(latest.getLink()); imageURL.setUrl(latest.getLink());
} }
expandImage.setType(ButtonType.LINK); openImage.setType(ButtonType.LINK);
expandImage.setIcon(IconType.RESIZE_FULL); openImage.setIcon(IconType.EXTERNAL_LINK);
expandImage.setTitle("Open Image in New Browser Window"); openImage.setTitle("Open Image in New Browser Window");
openImage.setVisible(showOpen);
expandImage.addClickHandler(new ClickHandler() { openImage.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if(latest!=null) {
NewBrowserWindow.open(latest.getLink()+"?content-disposition=inline", "_blank", null);
}
}
});
viewImage.setVisible(false);
viewImage.setType(ButtonType.LINK);
viewImage.setIcon(IconType.EXPAND);
viewImage.setTitle("View Image in New Dialog");
viewImage.setVisible(showView);
viewImage.addClickHandler(new ClickHandler() {
@Override @Override
public void onClick(ClickEvent event) { public void onClick(ClickEvent event) {
if(latest!=null) { if(latest!=null) {
NewBrowserWindow.open(latest.getLink(), "_blank", null); ModalWindow mw = new ModalWindow(StringUtil.ellipsize(imageDV.getTitolo(), 20));
mw.add(new ImageView(imageDV, false, true));
/*String noProtocolLink = latest.getLink().replaceFirst("https:", "").replaceFirst("httP:", ""); mw.setCaller(ImageView.this);
GWT.log("noProtocolLink: "+noProtocolLink); mw.setWidth(900);
mw.show();
final RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.HEAD, noProtocolLink);
requestBuilder.setHeader("Content-Disposition", "inline");
requestBuilder.setCallback(new RequestCallback() {
@Override
public void onResponseReceived(Request request, Response response) {
String responseURL = response.getHeader("Location");
GWT.log("Response Received link: "+responseURL);
String link = responseURL+"?content-disposition=inline";
NewBrowserWindow.open(link, "_blank", null);
}
@Override
public void onError(Request request, Throwable exception) {
}
});
try {
requestBuilder.send();
} catch (RequestException e) {
e.printStackTrace();
}*/
} }
} }
}); });
}
/**
* Sets the heading.
*
* @param title the new heading
*/
protected void setHeading(String title) {
heading.setText(title);
}
protected void setParagraph(String text) {
paragraph1.setText(text);
} }
} }

View File

@ -4,14 +4,18 @@
xmlns:b="urn:import:com.github.gwtbootstrap.client.ui"> xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
<ui:style> <ui:style>
.max-width-400 { .max-width-400 {
max-width: 400px !important; max-width: 400px;
} }
.float-right{
.float-right {
float: right; float: right;
} }
</ui:style> </ui:style>
<b:Thumbnail size="4" addStyleNames="{style.max-width-400}"> <g:HTMLPanel>
<b:Button ui:field="expandImage" addStyleNames="{style.float-right}" visible="false">Open</b:Button> <!-- <b:Thumbnail size="4" addStyleNames="{style.max-width-400}" ui:field="thumbnailCont"> -->
<b:Button ui:field="viewImage" visible="false">View</b:Button>
<b:Button ui:field="openImage"
addStyleNames="{style.float-right}" visible="false">Open</b:Button>
<b:Image ui:field="imageURL" visible="false" /> <b:Image ui:field="imageURL" visible="false" />
<b:Caption> <b:Caption>
<b:Heading size="4" ui:field="heading"></b:Heading> <b:Heading size="4" ui:field="heading"></b:Heading>
@ -20,5 +24,6 @@
<b:Paragraph ui:field="paragraph2"> <b:Paragraph ui:field="paragraph2">
</b:Paragraph> </b:Paragraph>
</b:Caption> </b:Caption>
</b:Thumbnail> </g:HTMLPanel>
<!-- </b:Thumbnail> -->
</ui:UiBinder> </ui:UiBinder>

View File

@ -0,0 +1,61 @@
package org.gcube.portlets.user.geoportaldataviewer.client.ui.images;
import org.gcube.portlets.user.geoportaldataviewer.client.util.StringUtil;
import org.gcube.portlets.user.geoportaldataviewer.shared.products.model.UploadedImageDV;
import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* The Class ThumbnailImageView.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Nov 20, 2020
*/
public class ThumbnailImageView extends Composite {
private static ThumbnailImageViewUiBinder uiBinder = GWT.create(ThumbnailImageViewUiBinder.class);
@UiField
HTMLPanel thumbnailContainer;
/**
* The Interface ThumbnailImageViewUiBinder.
*
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
*
* Nov 20, 2020
*/
interface ThumbnailImageViewUiBinder extends UiBinder<Widget, ThumbnailImageView> {
}
/**
* Instantiates a new thumbnail image view.
*
* @param imageDV the image DV
* @param showView the show view
* @param showOpen the show open
*/
public ThumbnailImageView(UploadedImageDV imageDV, final boolean showView, final boolean showOpen) {
initWidget(uiBinder.createAndBindUi(this));
ImageView imageView = new ImageView(imageDV, showView, showOpen);
String title = StringUtil.ellipsize(imageDV.getTitolo(), 20);
imageView.setHeading(title);
String didascalia = StringUtil.ellipsize(imageDV.getDidascalia(), 50);
imageView.setParagraph(didascalia);
// imageView.setViewImageVisible(true);
thumbnailContainer.add(imageView);
}
}

View File

@ -0,0 +1,15 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:b="urn:import:com.github.gwtbootstrap.client.ui"
xmlns:citem="urn:import:org.gcube.portlets.user.geoportaldataviewer.client.ui.images">
<ui:style>
.max-width-400 {
max-width: 400px;
}
</ui:style>
<b:Thumbnail size="4" addStyleNames="{style.max-width-400}"
ui:field="thumbnailView">
<g:HTMLPanel ui:field="thumbnailContainer"></g:HTMLPanel>
</b:Thumbnail>
</ui:UiBinder>

View File

@ -5,8 +5,9 @@ import java.util.List;
import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerConstants;
import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync; import org.gcube.portlets.user.geoportaldataviewer.client.GeoportalDataViewerServiceAsync;
import org.gcube.portlets.user.geoportaldataviewer.client.gis.MapUtils; import org.gcube.portlets.user.geoportaldataviewer.client.gis.MapUtils;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.ModalWindow;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.dialogs.DialogShareableLink; import org.gcube.portlets.user.geoportaldataviewer.client.ui.dialogs.DialogShareableLink;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.images.ImageView; import org.gcube.portlets.user.geoportaldataviewer.client.ui.images.ThumbnailImageView;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.map.MapView; import org.gcube.portlets.user.geoportaldataviewer.client.ui.map.MapView;
import org.gcube.portlets.user.geoportaldataviewer.client.ui.util.CustomFlexTable; import org.gcube.portlets.user.geoportaldataviewer.client.ui.util.CustomFlexTable;
import org.gcube.portlets.user.geoportaldataviewer.shared.GeoNaItemRef; import org.gcube.portlets.user.geoportaldataviewer.shared.GeoNaItemRef;
@ -16,8 +17,6 @@ import org.gcube.portlets.user.geoportaldataviewer.shared.products.model.Relazio
import org.gcube.portlets.user.geoportaldataviewer.shared.products.model.UploadedImageDV; import org.gcube.portlets.user.geoportaldataviewer.shared.products.model.UploadedImageDV;
import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Button;
import com.github.gwtbootstrap.client.ui.Modal;
import com.github.gwtbootstrap.client.ui.ModalFooter;
import com.github.gwtbootstrap.client.ui.PageHeader; import com.github.gwtbootstrap.client.ui.PageHeader;
import com.github.gwtbootstrap.client.ui.Paragraph; import com.github.gwtbootstrap.client.ui.Paragraph;
import com.github.gwtbootstrap.client.ui.Thumbnails; import com.github.gwtbootstrap.client.ui.Thumbnails;
@ -78,7 +77,7 @@ public class ConcessioneView extends Composite {
Button shareButton; Button shareButton;
@UiField @UiField
Button openButton; Button viewButton;
private ConcessioneDV concessioneDV; private ConcessioneDV concessioneDV;
@ -90,15 +89,25 @@ public class ConcessioneView extends Composite {
private String myLogin; private String myLogin;
private boolean viewImageButtonVisible = true;
private boolean openImageButtonVisible = true;
private ConcessioneView() { private ConcessioneView() {
initWidget(uiBinder.createAndBindUi(this)); initWidget(uiBinder.createAndBindUi(this));
pageViewDetails.getElement().setId("page-view-details"); pageViewDetails.getElement().setId("page-view-details");
} }
public ConcessioneView(GeoNaItemRef item, ConcessioneDV concDV) { public ConcessioneView(GeoNaItemRef item, ConcessioneDV concDV) {
this(item, concDV, true, true);
}
public ConcessioneView(GeoNaItemRef item, ConcessioneDV concDV, boolean viewImageButtonVisible, boolean openImageButtonVisible) {
this(); this();
this.concessioneDV = concDV; this.concessioneDV = concDV;
this.geonaItemRef = item; this.geonaItemRef = item;
this.viewImageButtonVisible = viewImageButtonVisible;
this.openImageButtonVisible = openImageButtonVisible;
titolo.setText(concessioneDV.getNome()); titolo.setText(concessioneDV.getNome());
introduzione.setText(concessioneDV.getIntroduzione()); introduzione.setText(concessioneDV.getIntroduzione());
@ -180,33 +189,22 @@ public class ConcessioneView extends Composite {
} }
}); });
openButton.setType(ButtonType.LINK); viewButton.setType(ButtonType.LINK);
openButton.setIcon(IconType.EXPAND); viewButton.setIcon(IconType.EXPAND);
openButton.setTitle("Open Details in New Dialog"); viewButton.setTitle("View Details in New Dialog");
openButton.addClickHandler(new ClickHandler() { viewButton.addClickHandler(new ClickHandler() {
@Override @Override
public void onClick(ClickEvent event) { public void onClick(ClickEvent event) {
Modal modal = new Modal(false);
modal.hide(false); ConcessioneView cv = new ConcessioneView(geonaItemRef, concessioneDV, false, openImageButtonVisible);
modal.setCloseVisible(true); cv.setViewDetailsButtonVisible(false);
modal.setWidth(900); ModalWindow mw = new ModalWindow(concessioneDV.getNome());
modal.setTitle(concessioneDV.getNome()); mw.add(cv);
modal.add(new ConcessioneView(geonaItemRef, concessioneDV)); mw.setCaller(ConcessioneView.this);
ModalFooter modalFooter = new ModalFooter(); mw.setWidth(900);
final Button buttClose = new Button("Close"); mw.show();
modalFooter.add(buttClose);
buttClose.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
modal.hide();
}
});
modal.add(modalFooter);
modal.show();
} }
}); });
@ -316,7 +314,7 @@ public class ConcessioneView extends Composite {
if (i == 0) if (i == 0)
imagesPanel.add(thumbNails); imagesPanel.add(thumbNails);
thumbNails.add(new ImageView(uploadedImageDV)); thumbNails.add(new ThumbnailImageView(uploadedImageDV, viewImageButtonVisible, openImageButtonVisible));
} }
} }
@ -325,5 +323,9 @@ public class ConcessioneView extends Composite {
public ConcessioneDV getConcessioneDV() { public ConcessioneDV getConcessioneDV() {
return concessioneDV; return concessioneDV;
} }
protected void setViewDetailsButtonVisible(boolean bool) {
viewButton.setVisible(bool);
}
} }

View File

@ -29,7 +29,7 @@
<g:HorizontalPanel <g:HorizontalPanel
addStyleNames="{style.margin-bottom-10}"> addStyleNames="{style.margin-bottom-10}">
<b:Button ui:field="shareButton">Share</b:Button> <b:Button ui:field="shareButton">Share</b:Button>
<b:Button ui:field="openButton">Open</b:Button> <b:Button ui:field="viewButton">View</b:Button>
</g:HorizontalPanel> </g:HorizontalPanel>
<b:Paragraph ui:field="introduzione"></b:Paragraph> <b:Paragraph ui:field="introduzione"></b:Paragraph>
<g:HorizontalPanel> <g:HorizontalPanel>

View File

@ -16,15 +16,12 @@ public class StringUtil {
/** /**
* Ellipsize. * Ellipsize.
* *
* @param input the input string that may be subjected to shortening * @param input the input string that may be subjected to shortening
* @param maxCharacters the maximum characters that must be returned for the input string. Must be at least 3 (that is the ellipses size) * @param maxCharacters the maximum characters that must be returned for the input string
* @return the string * @return the string
* @throws Exception the exception * @throws Exception the exception
*/ */
public static String ellipsize(String input, int maxCharacters) throws Exception{ public static String ellipsize(String input, int maxCharacters) {
if(maxCharacters < 3) {
throw new IllegalArgumentException("maxCharacters must be at least 3 because the ellipsis already take up 3 characters");
}
if (input == null || input.length() < maxCharacters) { if (input == null || input.length() < maxCharacters) {
return input; return input;

View File

@ -86,7 +86,7 @@ public class TestModel {
img.setResponsabili(concessione.getAuthors()); img.setResponsabili(concessione.getAuthors());
List<PersistedContent> actualContentList = new ArrayList<PersistedContent>(1); List<PersistedContent> actualContentList = new ArrayList<PersistedContent>(1);
WorkspaceContent ws = new WorkspaceContent(); WorkspaceContent ws = new WorkspaceContent();
ws.setLink("https://data-dev.d4science.net/ie8Y"); ws.setLink("https://data.dev.d4science.org/shub/E_azRkaVhqTFExMzZvTG9pY0hwSFJNV2tVTHBEMGEycFVsQitvWjZvb29WZjkwRU84b1hXQnp0QjRuSGhrODJqQg==");
actualContentList.add(ws); actualContentList.add(ws);
img.setActualContent(actualContentList); img.setActualContent(actualContentList);
imgs.add(img); imgs.add(img);