teichmann@5861: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
teichmann@5861: * Software engineering by Intevation GmbH
teichmann@5861: *
teichmann@5993: * This file is Free Software under the GNU AGPL (>=v3)
teichmann@5861: * and comes with ABSOLUTELY NO WARRANTY! Check out the
teichmann@5993: * documentation coming with Dive4Elements River for details.
teichmann@5861: */
teichmann@5861:
teichmann@5835: package org.dive4elements.river.client.client.ui;
ingo@41:
gernotbelger@9066: import java.util.ArrayList;
gernotbelger@9066: import java.util.List;
christian@4131:
gernotbelger@9066: import org.dive4elements.river.client.client.FLYS;
teichmann@5835: import org.dive4elements.river.client.client.FLYSConstants;
teichmann@5835: import org.dive4elements.river.client.client.event.HasStepBackHandlers;
teichmann@5835: import org.dive4elements.river.client.client.event.HasStepForwardHandlers;
teichmann@5835: import org.dive4elements.river.client.client.event.StepBackEvent;
teichmann@5835: import org.dive4elements.river.client.client.event.StepBackHandler;
teichmann@5835: import org.dive4elements.river.client.client.event.StepForwardEvent;
teichmann@5835: import org.dive4elements.river.client.client.event.StepForwardHandler;
teichmann@5835: import org.dive4elements.river.client.shared.model.Artifact;
teichmann@5835: import org.dive4elements.river.client.shared.model.ArtifactDescription;
teichmann@5835: import org.dive4elements.river.client.shared.model.Collection;
teichmann@5835: import org.dive4elements.river.client.shared.model.Data;
teichmann@5835: import org.dive4elements.river.client.shared.model.DataItem;
teichmann@5835: import org.dive4elements.river.client.shared.model.DataList;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultData;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultDataItem;
felix@1591:
gernotbelger@9066: import com.google.gwt.core.client.GWT;
gernotbelger@9066: import com.smartgwt.client.util.SC;
gernotbelger@9066: import com.smartgwt.client.widgets.Button;
gernotbelger@9066: import com.smartgwt.client.widgets.Canvas;
gernotbelger@9066: import com.smartgwt.client.widgets.Img;
gernotbelger@9066: import com.smartgwt.client.widgets.events.ClickEvent;
gernotbelger@9066: import com.smartgwt.client.widgets.events.ClickHandler;
gernotbelger@9066: import com.smartgwt.client.widgets.layout.VLayout;
felix@1591:
ingo@41: /**
ingo@41: * An abstract UIProvider that provides some basic methods.
ingo@41: *
ingo@41: * @author Ingo Weinzierl
ingo@41: */
gernotbelger@9066: public abstract class AbstractUIProvider implements UIProvider, HasStepForwardHandlers, ClickHandler, HasStepBackHandlers {
christian@4131: private static final long serialVersionUID = -1610874613377494184L;
christian@4131:
felix@5189: /** The message class that provides i18n strings. */
ingo@211: protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
ingo@57:
felix@5189: /** The StepForwardHandlers. */
ingo@41: protected List forwardHandlers;
ingo@41:
felix@5189: /** The StepForwardHandlers. */
ingo@60: protected List backHandlers;
ingo@60:
felix@5189: /** The container that is used to position helper widgets. */
ingo@788: protected VLayout helperContainer;
ingo@83:
felix@5189: /** The artifact that contains status information. */
raimund@233: protected Artifact artifact;
ingo@41:
felix@5189: /** The Collection. */
ingo@909: protected Collection collection;
ingo@909:
felix@5189: /** The ParameterList. */
raimund@915: protected ParameterList parameterList;
raimund@915:
ingo@41: /**
ingo@41: * Creates a new UIProvider instance of this class.
ingo@41: */
ingo@41: public AbstractUIProvider() {
gernotbelger@9066: this.forwardHandlers = new ArrayList();
gernotbelger@9066: this.backHandlers = new ArrayList();
ingo@60: }
ingo@60:
ingo@60: /**
ingo@60: * Appends a StepBackHandler that wants to listen to StepBackEvents.
ingo@60: *
gernotbelger@9066: * @param handler
gernotbelger@9066: * A new StepBackHandler.
ingo@60: */
christian@3384: @Override
gernotbelger@9066: public void addStepBackHandler(final StepBackHandler handler) {
ingo@60: if (handler != null) {
gernotbelger@9066: this.backHandlers.add(handler);
ingo@60: }
ingo@41: }
ingo@41:
ingo@41: /**
ingo@41: * Appends a StepForwardHandler that wants to listen to StepForwardEvents.
ingo@41: *
gernotbelger@9066: * @param handler
gernotbelger@9066: * A new StepForwardHandler.
ingo@41: */
christian@3384: @Override
gernotbelger@9066: public void addStepForwardHandler(final StepForwardHandler handler) {
ingo@41: if (handler != null) {
gernotbelger@9066: this.forwardHandlers.add(handler);
ingo@41: }
ingo@41: }
ingo@41:
ingo@41: /**
ingo@60: * This method is called after the user has clicked one of the buttons to
ingo@60: * step back to a previous state.
ingo@60: *
gernotbelger@9066: * @param e
gernotbelger@9066: * The StepBackEvent.
ingo@60: */
gernotbelger@9066: protected void fireStepBackEvent(final StepBackEvent e) {
gernotbelger@9066: GWT.log("AbstractUIProvider - fireStepBackEvent() handlers: " + this.backHandlers.size());
gernotbelger@9066: for (final StepBackHandler handler : this.backHandlers) {
ingo@60: handler.onStepBack(e);
ingo@60: }
ingo@60: }
ingo@60:
ingo@60: /**
ingo@41: * This method is called after the user has clicked on the 'next' button to
ingo@41: * step to the next state.
ingo@41: *
gernotbelger@9066: * @param e
gernotbelger@9066: * The StepForwardEvent.
ingo@41: */
gernotbelger@9066: protected void fireStepForwardEvent(final StepForwardEvent e) {
gernotbelger@9066: GWT.log("AbstractUIProvider - fireStepForwardEvent() handlers: " + this.forwardHandlers.size());
gernotbelger@9066: for (final StepForwardHandler handler : this.forwardHandlers) {
ingo@41: handler.onStepForward(e);
ingo@41: }
ingo@41: }
ingo@41:
ingo@41: /**
ingo@41: * This method is used to listen to click events on the 'next' button. The
ingo@41: * fireStepForwardEvent() method is called here.
ingo@41: *
gernotbelger@9066: * @param e
gernotbelger@9066: * The click event.
ingo@41: */
christian@3384: @Override
gernotbelger@9066: public void onClick(final ClickEvent e) {
gernotbelger@9066: final List errors = validate();
gernotbelger@9079: if (errors == null || errors.isEmpty()) {
gernotbelger@9079: final Data[] data = getData();
gernotbelger@9079: fireStepForwardEvent(new StepForwardEvent(data));
gernotbelger@9079: } else {
gernotbelger@9079: showErrors(errors);
gernotbelger@9079: }
ingo@909: }
ingo@41:
gernotbelger@9066: protected void showErrors(final List errors) {
gernotbelger@9066: final StringBuilder sb = new StringBuilder();
ingo@562:
gernotbelger@9066: for (final String error : errors) {
ingo@909: sb.append(error);
ingo@909: sb.append("
");
ingo@562: }
ingo@909:
ingo@909: SC.warn(sb.toString());
ingo@41: }
ingo@41:
ingo@58: /**
ingo@58: * Creates the 'next' button to step forward to the next state.
ingo@58: *
ingo@58: * @return the 'next' button.
ingo@58: */
ingo@57: protected Canvas getNextButton() {
gernotbelger@9066: final Button next = new Button(this.MSG.buttonNext());
raimund@81: next.addClickHandler(this);
ingo@57:
raimund@81: return next;
ingo@57: }
ingo@57:
ingo@2500: @Override
gernotbelger@9066: public Canvas createHelpLink(final DataList dataList, final Data data, final FLYS instance) {
gernotbelger@9066: final String iUrl = GWT.getHostPageBaseURL() + this.MSG.getFeatureInfo();
gernotbelger@9066: final String helpUrl = dataList.getHelpText();
ingo@2500:
aheinecke@6232: return new WikiImgLink(iUrl, helpUrl, 30, 30, instance);
ingo@2500: }
ingo@2500:
ingo@41: /**
ingo@58: * Creates the 'back' button to step back to a previous state.
ingo@58: *
gernotbelger@9066: * @param targetState
gernotbelger@9066: * The identifier of the target state.
ingo@58: *
ingo@58: * @return the 'back' button.
ingo@58: */
ingo@58: protected Canvas getBackButton(final String targetState) {
gernotbelger@9066: final String url = GWT.getHostPageBaseURL() + this.MSG.imageBack();
gernotbelger@9066: final Img back = new Img(url, 16, 16);
ingo@58:
ingo@58: back.addClickHandler(new ClickHandler() {
christian@3384: @Override
gernotbelger@9066: public void onClick(final ClickEvent event) {
ingo@60: fireStepBackEvent(new StepBackEvent(targetState));
ingo@58: }
ingo@58: });
ingo@58:
ingo@58: return back;
ingo@58: }
ingo@58:
ingo@58: /**
ingo@83: * This method injects a container that is used to position helper widgets.
ingo@83: *
gernotbelger@9066: * @param helperContainer
gernotbelger@9066: * A container that is used to position helper
gernotbelger@9066: * widgets.
ingo@83: */
christian@3384: @Override
gernotbelger@9066: public void setContainer(final VLayout helperContainer) {
ingo@83: this.helperContainer = helperContainer;
ingo@83: }
ingo@83:
ingo@83: /**
raimund@233: * This method injects an artifact that contains the status information.
raimund@233: *
gernotbelger@9066: * @param art
gernotbelger@9066: * An artifact containing status information.
raimund@233: */
christian@3384: @Override
gernotbelger@9066: public void setArtifact(final Artifact art) {
raimund@233: this.artifact = art;
raimund@233: }
raimund@233:
christian@3384: @Override
gernotbelger@9066: public void setCollection(final Collection collection) {
ingo@909: this.collection = collection;
ingo@909: }
ingo@909:
christian@3384: @Override
gernotbelger@9066: public void setParameterList(final ParameterList list) {
raimund@915: this.parameterList = list;
raimund@915: }
raimund@915:
ingo@909: public Collection getCollection() {
gernotbelger@9066: return this.collection;
ingo@909: }
ingo@909:
raimund@233: /**
ingo@247: * This method greps the Data with name name from the list and
ingo@247: * returns it.
ingo@247: *
gernotbelger@9066: * @param items
gernotbelger@9066: * A list of Data.
gernotbelger@9066: * @param name
gernotbelger@9066: * The name of the Data that we are searching for.
ingo@247: *
ingo@247: * @return the Data with the name name.
ingo@247: */
gernotbelger@9066: protected Data getData(final List data, final String name) {
gernotbelger@9066: for (final Data d : data) {
ingo@247: if (name.equals(d.getLabel())) {
ingo@247: return d;
ingo@247: }
ingo@247: }
ingo@247: return null;
ingo@247: }
ingo@247:
gernotbelger@9066: protected String getDataValue(final String state, final String name) {
gernotbelger@9066: final ArtifactDescription desc = this.artifact.getArtifactDescription();
ingo@873:
gernotbelger@9066: final DataList[] old = desc.getOldData();
ingo@873:
gernotbelger@9066: for (final DataList list : old) {
rrenkert@5308: if (list == null) {
rrenkert@5308: continue;
rrenkert@5308: }
gernotbelger@9066: final Data d = getData(list.getAll(), name);
ingo@873:
ingo@873: if (d != null) {
ingo@873: return d.getItems()[0].getStringValue();
ingo@873: }
ingo@873: }
ingo@873:
ingo@873: return null;
ingo@873: }
ingo@873:
ingo@247: /**
ingo@247: * This method greps the DataItem with name name from the list and
ingo@247: * returns it.
ingo@247: *
gernotbelger@9066: * @param items
gernotbelger@9066: * A list of DataItems.
gernotbelger@9066: * @param name
gernotbelger@9066: * The name of the DataItem that we are searching for.
ingo@247: *
ingo@247: * @return the DataItem with the name name.
ingo@247: */
gernotbelger@9066: protected DataItem getDataItem(final DataItem[] items, final String name) {
gernotbelger@9066: for (final DataItem item : items) {
ingo@247: if (name.equals(item.getLabel())) {
ingo@247: return item;
ingo@247: }
ingo@247: }
ingo@247:
ingo@247: return null;
ingo@247: }
ingo@247:
gernotbelger@8852: /**
gernotbelger@8852: * Validates the selection.
gernotbelger@9074: *
gernotbelger@8852: * @return List of internationalized errror messages (if any).
gernotbelger@8852: */
ingo@562: public List validate() {
christian@5658: return new ArrayList(); // FIXME: What's this?
ingo@562: }
ingo@562:
felix@1591: /** Create simple DefaultData with single DataItem inside. */
gernotbelger@9066: public static DefaultData createDataArray(final String name, final String value) {
gernotbelger@9066: final DataItem item = new DefaultDataItem(name, name, value);
felix@1591:
gernotbelger@9066: return new DefaultData(name, null, null, new DataItem[] { item });
felix@1591: }
felix@1591:
ingo@247: /**
ingo@41: * This method needs to be implemented by concrete subclasses. It should
ingo@41: * create a new Canvas object with a representation of data.
ingo@41: *
gernotbelger@9066: * @param data
gernotbelger@9066: * The data that should be displayed.
ingo@41: *
ingo@41: * @return a Canvas object that displays data.
ingo@41: */
christian@3384: @Override
ingo@51: public abstract Canvas create(DataList data);
ingo@41:
ingo@41: /**
ingo@41: * This method needs to be implemented by concrete subclasses. It should
ingo@41: * return the selected data.
ingo@41: *
ingo@41: * @return the selected data.
ingo@41: */
ingo@41: protected abstract Data[] getData();
gernotbelger@9237:
gernotbelger@9237: protected String getRiverName() {
gernotbelger@9237: final ArtifactDescription adescr = this.artifact.getArtifactDescription();
gernotbelger@9237: return adescr.getRiver();
gernotbelger@9237: }
gernotbelger@9237:
ingo@41: }
ingo@41: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :