gernotbelger@9079: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@9079: * Software engineering by gernotbelger@9079: * Björnsen Beratende Ingenieure GmbH gernotbelger@9079: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@9079: * gernotbelger@9079: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9079: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9079: * documentation coming with Dive4Elements River for details. gernotbelger@9079: */ gernotbelger@9079: package org.dive4elements.river.client.client.ui; gernotbelger@9079: gernotbelger@9079: import java.util.ArrayList; gernotbelger@9079: import java.util.List; gernotbelger@9079: import java.util.TreeSet; gernotbelger@9079: gernotbelger@9079: import org.dive4elements.river.client.client.ui.FromToTableHelperPanel.IColumnClickHandler; gernotbelger@9079: import org.dive4elements.river.client.shared.model.Data; gernotbelger@9079: import org.dive4elements.river.client.shared.model.DataItem; gernotbelger@9079: import org.dive4elements.river.client.shared.model.DataList; gernotbelger@9079: import org.dive4elements.river.client.shared.model.DefaultData; gernotbelger@9079: import org.dive4elements.river.client.shared.model.DefaultDataItem; gernotbelger@9079: gernotbelger@9079: import com.smartgwt.client.widgets.Canvas; gernotbelger@9079: import com.smartgwt.client.widgets.Label; gernotbelger@9079: import com.smartgwt.client.widgets.form.fields.TextItem; gernotbelger@9079: import com.smartgwt.client.widgets.grid.ListGrid; gernotbelger@9079: import com.smartgwt.client.widgets.grid.ListGridRecord; gernotbelger@9079: import com.smartgwt.client.widgets.layout.HLayout; gernotbelger@9079: import com.smartgwt.client.widgets.layout.VLayout; gernotbelger@9079: gernotbelger@9079: /** gernotbelger@9079: * @author Domenico Nardi Tironi gernotbelger@9079: * gernotbelger@9079: */ gernotbelger@9079: public abstract class AbstractEpochPanel extends AbstractUIProvider { gernotbelger@9079: gernotbelger@9079: private static final long serialVersionUID = 1L; gernotbelger@9079: gernotbelger@9079: protected enum Type { gernotbelger@9079: singleMinMax, multi gernotbelger@9079: // Type singleMinMax: nur eine Epoche kann gesetzt werden; minMax vorbelegt aus Datenquelle gernotbelger@9079: // Type multi: mehrere epochs können eingegeben werden gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: private TextItem start; gernotbelger@9079: gernotbelger@9079: private TextItem end; gernotbelger@9079: gernotbelger@9079: private ListGrid elements; gernotbelger@9079: gernotbelger@9079: private List validInputs = new ArrayList(); gernotbelger@9079: gernotbelger@9079: private final Type type; gernotbelger@9079: gernotbelger@9079: public AbstractEpochPanel(final Type type) { gernotbelger@9079: this.type = type; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: protected abstract String getDatakey(); gernotbelger@9079: gernotbelger@9079: protected abstract Canvas createWidget(final DataList data); gernotbelger@9079: gernotbelger@9079: private final void postCreate() { gernotbelger@9079: switch (this.type) { gernotbelger@9079: case singleMinMax: gernotbelger@9079: final TreeSet minMax = new TreeSet(this.validInputs); gernotbelger@9079: if (minMax.size() > 1) { gernotbelger@9079: this.start.setValue(minMax.first()); gernotbelger@9079: this.end.setValue(minMax.last()); gernotbelger@9079: } else { gernotbelger@9079: // TODO: THIS STATE IS INVALID; RETURN - es gibt keinen Mechanismus, der das verhindert; müsste gernotbelger@9079: // im State davor passieren) gernotbelger@9079: } gernotbelger@9079: break; gernotbelger@9079: case multi: gernotbelger@9079: break; // do nothing gernotbelger@9079: default: gernotbelger@9079: throw new IllegalStateException(); gernotbelger@9079: } gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: protected final TextItem createStartInputItem(final String title) { gernotbelger@9079: this.start = PanelHelper.createItem(title); gernotbelger@9079: return this.start; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: protected final TextItem createEndInputItem(final String title) { gernotbelger@9079: this.end = PanelHelper.createItem(title); gernotbelger@9079: return this.end; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: protected final ListGrid createListGrid() { gernotbelger@9079: this.elements = new ListGrid(); gernotbelger@9079: this.elements.setShowHeaderContextMenu(false); gernotbelger@9079: this.elements.setCanReorderFields(false); gernotbelger@9079: this.elements.setCanSort(false); gernotbelger@9079: this.elements.setCanEdit(false); gernotbelger@9079: return this.elements; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: @Override gernotbelger@9079: public final Canvas createOld(final DataList dataList) { gernotbelger@9079: final HLayout layout = new HLayout(); gernotbelger@9079: layout.setWidth("400px"); gernotbelger@9079: final VLayout vLayout = new VLayout(); gernotbelger@9079: vLayout.setWidth(130); gernotbelger@9079: final Label label = new Label(dataList.getLabel()); gernotbelger@9079: label.setWidth("200px"); gernotbelger@9079: label.setHeight(25); gernotbelger@9079: gernotbelger@9079: final List items = dataList.getAll(); gernotbelger@9079: final Data str = getData(items, getDatakey()); gernotbelger@9079: final DataItem[] strItems = str.getItems(); gernotbelger@9079: gernotbelger@9079: final String[] pairs = strItems[0].getLabel().split(";"); gernotbelger@9079: for (final String pair : pairs) { gernotbelger@9079: final Label dateLabel = new Label(pair.replace(",", " - ")); gernotbelger@9079: dateLabel.setHeight(20); gernotbelger@9079: vLayout.addMember(dateLabel); gernotbelger@9079: } gernotbelger@9079: final Canvas back = getBackButton(dataList.getState()); gernotbelger@9079: layout.addMember(label); gernotbelger@9079: layout.addMember(vLayout); gernotbelger@9079: layout.addMember(back); gernotbelger@9079: gernotbelger@9079: return layout; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: @Override gernotbelger@9079: public final Canvas create(final DataList data) { gernotbelger@9079: final VLayout layout = new VLayout(); gernotbelger@9079: final Canvas submit = getNextButton(); gernotbelger@9079: final Canvas widget = createWidget(data); gernotbelger@9079: gernotbelger@9079: layout.addMember(widget); gernotbelger@9079: layout.addMember(submit); gernotbelger@9079: gernotbelger@9079: final IColumnClickHandler fromHandler = createHandler(this.start); gernotbelger@9079: final IColumnClickHandler toHandler = createHandler(this.end); gernotbelger@9079: gernotbelger@9079: final FromToTableHelperPanel helper = new FromToTableHelperPanel(data, getDatakey(), this.MSG, fromHandler, toHandler); gernotbelger@9079: this.validInputs = helper.getKeycolEntries(); gernotbelger@9079: final Canvas table = helper.getTable(); gernotbelger@9079: gernotbelger@9079: this.helperContainer.addMember(table); gernotbelger@9079: gernotbelger@9079: postCreate(); gernotbelger@9079: return layout; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: private final IColumnClickHandler createHandler(final TextItem field) { gernotbelger@9079: final IColumnClickHandler handler = new IColumnClickHandler() { gernotbelger@9079: gernotbelger@9079: @Override gernotbelger@9079: public void columnClicked(final String value) { gernotbelger@9079: field.setValue(value); gernotbelger@9079: } gernotbelger@9079: }; gernotbelger@9079: return handler; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: /* gernotbelger@9079: * Validate the epoch input. We do this here and not in an overridden gernotbelger@9079: * validate method as we want to validate before an epoch is added gernotbelger@9079: * to the list of epochs. gernotbelger@9079: */ gernotbelger@9079: protected final boolean isValidEpoch(final String y1, final String y2) { gernotbelger@9079: // First check that both are integer gernotbelger@9079: // int iY1; gernotbelger@9079: // int iY2; gernotbelger@9079: final List errors = new ArrayList(); gernotbelger@9079: try { gernotbelger@9079: // iY1 = gernotbelger@9079: Integer.parseInt(y1); gernotbelger@9079: } gernotbelger@9079: catch (final NumberFormatException e) { gernotbelger@9079: errors.add(this.MSG.wrongFormat() + ": " + y1); gernotbelger@9079: } gernotbelger@9079: try { gernotbelger@9079: // iY2 = gernotbelger@9079: Integer.parseInt(y2); gernotbelger@9079: } gernotbelger@9079: catch (final NumberFormatException e) { gernotbelger@9079: errors.add(this.MSG.wrongFormat() + ": " + y2); gernotbelger@9079: } gernotbelger@9079: if (!errors.isEmpty()) { gernotbelger@9079: showErrors(errors); gernotbelger@9079: return false; gernotbelger@9079: } gernotbelger@9079: boolean startIsGood = false; gernotbelger@9079: boolean endIsGood = false; gernotbelger@9079: for (final String validYear : this.validInputs) { gernotbelger@9079: if (startIsGood || y1.equals(validYear)) { gernotbelger@9079: startIsGood = true; gernotbelger@9079: } gernotbelger@9079: if (endIsGood || y2.equals(validYear)) { gernotbelger@9079: endIsGood = true; gernotbelger@9079: } gernotbelger@9079: if (startIsGood && endIsGood) { gernotbelger@9079: break; gernotbelger@9079: } gernotbelger@9079: /* gernotbelger@9079: * alternative check if data lies in between gernotbelger@9079: * int aYear = Integer.parseInt(validYear); gernotbelger@9079: * if (aYear >= iY1 && aYear <= iY2) { gernotbelger@9079: * isGood = true; gernotbelger@9079: * break; gernotbelger@9079: * } gernotbelger@9079: */ gernotbelger@9079: } gernotbelger@9079: if (!startIsGood) { gernotbelger@9079: String tmp = this.MSG.no_data_for_year(); gernotbelger@9079: tmp = tmp.replace("$1", y1); gernotbelger@9079: errors.add(tmp); gernotbelger@9079: } gernotbelger@9079: if (!endIsGood) { gernotbelger@9079: String tmp = this.MSG.no_data_for_year(); gernotbelger@9079: tmp = tmp.replace("$1", y2); gernotbelger@9079: errors.add(tmp); gernotbelger@9079: } gernotbelger@9079: if (!errors.isEmpty()) { gernotbelger@9079: showErrors(errors); gernotbelger@9079: return false; gernotbelger@9079: } gernotbelger@9079: return true; gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: @Override gernotbelger@9079: protected final Data[] getData() { gernotbelger@9079: final List data = new ArrayList(); gernotbelger@9079: switch (this.type) { gernotbelger@9079: gernotbelger@9079: case singleMinMax: gernotbelger@9079: data.add(buildResult(this.start.getValueAsString(), this.end.getValueAsString())); gernotbelger@9079: gernotbelger@9079: break; gernotbelger@9079: case multi: gernotbelger@9079: final ListGridRecord[] lgr = this.elements.getRecords(); gernotbelger@9079: if (lgr.length == 0) { gernotbelger@9079: return new Data[0]; gernotbelger@9079: } gernotbelger@9079: for (final ListGridRecord element : lgr) { gernotbelger@9079: data.add(buildResult(element.getAttribute("from"), element.getAttribute("to"))); gernotbelger@9079: } gernotbelger@9079: break; gernotbelger@9079: default: gernotbelger@9079: throw new IllegalStateException(); gernotbelger@9079: } gernotbelger@9079: return data.toArray(new Data[data.size()]); gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: private final Data buildResult(final String startStr, final String endStr) { gernotbelger@9079: final StringBuilder builder = new StringBuilder(); gernotbelger@9079: builder.append(startStr); gernotbelger@9079: builder.append(","); gernotbelger@9079: builder.append(endStr); gernotbelger@9079: builder.append(";"); gernotbelger@9079: final DataItem item = new DefaultDataItem(getDatakey(), null, builder.toString()); gernotbelger@9079: return new DefaultData(getDatakey(), null, null, new DataItem[] { item }); gernotbelger@9079: } gernotbelger@9079: gernotbelger@9079: }