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 :