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.stationinfo; bjoern@4956: bjoern@4956: import java.util.ArrayList; bjoern@4956: import java.util.List; bjoern@4956: rrenkert@8303: import org.dive4elements.river.client.client.Config; teichmann@5835: import org.dive4elements.river.client.client.FLYS; rrenkert@8303: import org.dive4elements.river.client.client.services.AdvanceService; rrenkert@8303: import org.dive4elements.river.client.client.services.AdvanceServiceAsync; rrenkert@8303: import org.dive4elements.river.client.client.services.ArtifactService; rrenkert@8303: import org.dive4elements.river.client.client.services.ArtifactServiceAsync; rrenkert@8303: import org.dive4elements.river.client.client.services.CreateCollectionService; rrenkert@8303: import org.dive4elements.river.client.client.services.CreateCollectionServiceAsync; rrenkert@8303: import org.dive4elements.river.client.client.services.StepForwardService; rrenkert@8303: import org.dive4elements.river.client.client.services.StepForwardServiceAsync; rrenkert@8303: import org.dive4elements.river.client.client.ui.CollectionView; rrenkert@8303: import org.dive4elements.river.client.shared.model.Artifact; rrenkert@8303: 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; rrenkert@8303: import org.dive4elements.river.client.shared.model.DefaultData; rrenkert@8303: import org.dive4elements.river.client.shared.model.DefaultDataItem; teichmann@5835: import org.dive4elements.river.client.shared.model.GaugeInfo; teichmann@5835: import org.dive4elements.river.client.shared.model.RiverInfo; bjoern@4956: gernotbelger@9093: import com.google.gwt.core.client.GWT; gernotbelger@9093: import com.google.gwt.user.client.rpc.AsyncCallback; gernotbelger@9093: import com.smartgwt.client.util.SC; gernotbelger@9093: import com.smartgwt.client.widgets.Canvas; gernotbelger@9093: import com.smartgwt.client.widgets.grid.ListGridField; gernotbelger@9093: import com.smartgwt.client.widgets.grid.ListGridRecord; gernotbelger@9093: import com.smartgwt.client.widgets.grid.events.RecordClickEvent; gernotbelger@9093: import com.smartgwt.client.widgets.grid.events.RecordClickHandler; bjoern@4956: bjoern@4956: /** bjoern@4956: * @author Björn Ricks bjoern@4956: */ bjoern@4960: public class GaugeListGrid extends InfoListGrid implements RecordClickHandler { bjoern@4956: gernotbelger@9093: public static enum DisappearType { gernotbelger@9093: remove, collapse, stayVisible gernotbelger@9093: } gernotbelger@9093: bjoern@4961: private static final int ABFLUSSTAFEL_COLUMN = 6; bjoern@4961: rrenkert@8303: /** The ArtifactService used to communicate with the Artifact server. */ gernotbelger@9093: protected ArtifactServiceAsync artifactService = GWT.create(ArtifactService.class); rrenkert@8303: rrenkert@8303: /** The StepForwardService used to put data into an existing artifact. */ gernotbelger@9093: protected StepForwardServiceAsync forwardService = GWT.create(StepForwardService.class); rrenkert@8303: gernotbelger@9093: /** The ArtifactService used to communicate with the Artifact server. */ gernotbelger@9093: protected CreateCollectionServiceAsync createCollectionService = GWT.create(CreateCollectionService.class); gernotbelger@9093: gernotbelger@9093: /** The StepForwardService used to put data into an existing artifact. */ gernotbelger@9093: protected AdvanceServiceAsync advanceService = GWT.create(AdvanceService.class); gernotbelger@9093: gernotbelger@9093: private final List gauges = new ArrayList(); gernotbelger@9093: gernotbelger@9093: public GaugeListGrid(final FLYS flys) { bjoern@4956: super(flys); gernotbelger@9093: // TODO i18n!!! gernotbelger@9093: final ListGridField nfield = new ListGridField("name", "Pegel"); gernotbelger@9093: final ListGridField sfield = new ListGridField("kmstart", "Start [km]", 60); gernotbelger@9093: final ListGridField efield = new ListGridField("kmend", "Ende [km]", 60); gernotbelger@9093: final ListGridField stfield = new ListGridField("station", "Station [km]"); gernotbelger@9093: final ListGridField lfield = new ListGridField("infolink", "Info"); gernotbelger@9093: final ListGridField cfield = new ListGridField("curvelink", this.MSG.gauge_curve_link()); bjoern@4959: cfield.addRecordClickHandler(this); bjoern@4956: rrenkert@6272: this.setShowRecordComponents(true); rrenkert@6272: this.setShowRecordComponentsByCell(true); bjoern@4959: this.setFields(nfield, sfield, efield, stfield, lfield, cfield); bjoern@4956: } bjoern@4956: gernotbelger@9093: @Override gernotbelger@9093: public void setRiverInfo(final RiverInfo riverinfo) { gernotbelger@9093: final List gauges = riverinfo.getGauges(); bjoern@4956: bjoern@4956: if (gauges != null && !gauges.isEmpty()) { bjoern@4956: gernotbelger@9093: final ArrayList emptygauges = new ArrayList(); bjoern@4956: bjoern@4956: if (!riverinfo.isKmUp()) { gernotbelger@9093: for (final GaugeInfo gauge : gauges) { bjoern@4956: addGauge(gauge, emptygauges); bjoern@4956: } gernotbelger@9093: } else { gernotbelger@9093: for (int i = gauges.size() - 1; i >= 0; i--) { gernotbelger@9093: final GaugeInfo gauge = gauges.get(i); bjoern@4956: addGauge(gauge, emptygauges); bjoern@4956: } bjoern@4956: } bjoern@4956: bjoern@4956: // put empty gauges to the end gernotbelger@9093: for (final GaugeInfo gauge : emptygauges) { bjoern@4956: addGauge(gauge); bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: private void addGauge(final GaugeInfo gauge, final List empty) { bjoern@4956: if (gauge.getKmStart() != null && gauge.getKmEnd() != null) { bjoern@4956: addGauge(gauge); gernotbelger@9093: } else { bjoern@4956: empty.add(gauge); bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: private void addGauge(final GaugeInfo gauge) { gernotbelger@9093: gernotbelger@9093: this.gauges.add(gauge); gernotbelger@9093: gernotbelger@9093: // this.addData(new GaugeRecord(gauge)); gernotbelger@9093: bjoern@4956: } bjoern@4956: gernotbelger@9093: @Override bjoern@4956: public void open() { gernotbelger@9093: final ArrayList locations = new ArrayList(); bjoern@4956: gernotbelger@9093: if (this.data != null && this.data.length > 0) { gernotbelger@9093: for (final DataList dl : this.data) { gernotbelger@9093: gernotbelger@9093: final String state = dl.getState(); gernotbelger@9093: DisappearType type = DisappearType.collapse; gernotbelger@9093: if (state.contains("state.bundu.") || state.contains("state.fix.")) { gernotbelger@9093: type = DisappearType.remove; gernotbelger@9093: } gernotbelger@9093: bjoern@4956: GWT.log("GaugeListGrid - open " + state); gernotbelger@9093: if (state.contains(".location_distance")) { bjoern@4956: Double ldfrom = null; bjoern@4956: Double ldto = null; bjoern@4956: gernotbelger@9093: for (int j = dl.size() - 1; j >= 0; --j) { gernotbelger@9093: final Data d = dl.get(j); gernotbelger@9093: final String label = d.getLabel(); gernotbelger@9093: GWT.log("GaugeListGrid - setData - label " + label + " " + d.getStringValue()); bjoern@4956: if (label.equals("ld_from")) { bjoern@4956: ldfrom = getDoubleValue(d); gernotbelger@9093: } else if (label.equals("ld_to")) { bjoern@4956: ldto = getDoubleValue(d); gernotbelger@9093: } else if (label.equals("ld_locations")) { bjoern@4956: getLocationsFromData(locations, d); bjoern@4956: openOnLocations(locations); bjoern@4956: return; bjoern@4956: } bjoern@4956: } bjoern@4956: if (ldfrom != null) { gernotbelger@9093: gernotbelger@9093: openOnDistance(ldfrom, ldto, type); bjoern@4956: return; bjoern@4956: } gernotbelger@9093: } else if (state.contains(".distance_only") || state.contains(".distance") gernotbelger@9093: || state.contains(".location") && !state.contains(".location_distance")) { bjoern@4956: Double ldfrom = null; bjoern@4956: Double ldto = null; bjoern@4956: gernotbelger@9093: for (int j = dl.size() - 1; j >= 0; --j) { gernotbelger@9093: final Data d = dl.get(j); gernotbelger@9093: final String label = d.getLabel(); gernotbelger@9093: GWT.log("GaugeListGrid - setData - label " + label + " " + d.getStringValue()); bjoern@4956: if (label.equals("ld_from")) { bjoern@4956: ldfrom = getDoubleValue(d); gernotbelger@9093: } else if (label.equals("ld_to")) { bjoern@4956: ldto = getDoubleValue(d); bjoern@4956: } bjoern@4956: } bjoern@4956: bjoern@4956: if (ldfrom != null) { gernotbelger@9093: openOnDistance(ldfrom, ldto, type); bjoern@4956: return; bjoern@4956: } gernotbelger@9093: } else if (state.equals("state.winfo.location")) { bjoern@4956: getLocations("ld_locations", locations, dl); bjoern@4956: openOnLocations(locations); bjoern@4956: return; gernotbelger@9093: } else if (state.equals("state.winfo.reference.curve.input.start")) { bjoern@4956: getLocations("reference_startpoint", locations, dl); gernotbelger@9093: } else if (state.equals("state.winfo.reference.curve.input.end")) { bjoern@4956: getLocations("reference_endpoint", locations, dl); gernotbelger@9093: } else if (state.equals("state.winfo.historicalq.reference_gauge")) { gernotbelger@9093: for (int j = dl.size() - 1; j >= 0; --j) { gernotbelger@9093: final Data d = dl.get(j); gernotbelger@9093: final String label = d.getLabel(); bjoern@4956: if (label.equals("reference_gauge")) { gernotbelger@9093: final String tmp = d.getStringValue(); bjoern@4956: if (tmp != null) { gernotbelger@9093: final Long gaugereference = Long.valueOf(tmp); bjoern@4956: if (gaugereference != null) { bjoern@4956: openOnReference(gaugereference); bjoern@4956: return; bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: if (!locations.isEmpty()) { bjoern@4956: openOnLocations(locations); gernotbelger@9093: } else { bjoern@4956: openAll(); bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: @Override gernotbelger@9093: public void openAll() { gernotbelger@9093: gernotbelger@9093: GWT.log("InfoListGrid - openAll"); gernotbelger@9093: gernotbelger@9093: setData(new ListGridRecord[] {}); gernotbelger@9093: for (final GaugeInfo gauge : this.gauges) { gernotbelger@9093: addExpandedRecord(gauge); gernotbelger@9093: } gernotbelger@9093: } gernotbelger@9093: gernotbelger@9093: void getLocations(final String labelname, final List locations, final DataList dl) { gernotbelger@9093: for (int j = dl.size() - 1; j >= 0; --j) { gernotbelger@9093: final Data d = dl.get(j); gernotbelger@9093: final String label = d.getLabel(); bjoern@4956: if (label.equals(labelname)) { bjoern@4956: getLocationsFromData(locations, d); bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: void getLocationsFromData(final List locations, final Data data) { gernotbelger@9093: final DataItem[] items = data.getItems(); gernotbelger@9093: for (final DataItem item : items) { gernotbelger@9093: final String tmp = item.getStringValue(); bjoern@4956: GWT.log("GaugeListGrid - getLocationsFromData " + tmp); bjoern@4956: if (tmp != null) { bjoern@4956: if (tmp.contains(" ")) { bjoern@4956: // string contains several values ... gernotbelger@9093: final String[] values = tmp.split(" "); gernotbelger@9093: for (final String value2 : values) { gernotbelger@9093: final Double value = Double.valueOf(value2); bjoern@4956: if (value != null) { bjoern@4956: locations.add(value); bjoern@4956: } bjoern@4956: } gernotbelger@9093: } else { gernotbelger@9093: final Double value = Double.valueOf(tmp); bjoern@4956: if (value != null) { bjoern@4956: locations.add(value); bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: public void openOnReference(final Long number) { bjoern@4956: GWT.log("GaugeListGrid - openOnReference " + number); gernotbelger@9093: gernotbelger@9093: setData(new ListGridRecord[] {}); gernotbelger@9093: gernotbelger@9093: for (final GaugeInfo gauge : this.gauges) { gernotbelger@9093: gernotbelger@9093: if (gauge.getOfficialNumber().equals(number)) { gernotbelger@9093: this.addExpandedRecord(gauge);// (gauge); gernotbelger@9093: } else { gernotbelger@9093: this.addCollapsedRecord(gauge); bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: public void openOnDistance(final Double start, final Double end, final DisappearType type) { bjoern@4956: GWT.log("GaugeListGrid - openOnDistance " + start + " " + end); bjoern@4956: gernotbelger@9093: setData(new ListGridRecord[] {}); gernotbelger@9093: gernotbelger@9093: for (final GaugeInfo gauge : this.gauges) { gernotbelger@9093: gernotbelger@9093: if (end == null && gauge.getKmStart() != null) { gernotbelger@9093: if (gauge.getKmStart() >= start) { gernotbelger@9093: addExpandedRecord(gauge); gernotbelger@9093: } else { gernotbelger@9093: removeOrCollapse(gauge, type); bjoern@4956: } gernotbelger@9093: } else if (gauge.getKmStart() != null && gauge.getKmEnd() != null) { tom@8856: // as getStart()/getEnd() return Double objects, tom@8856: // they can be null and bjoern@4956: // can cause NPEs when comparing with double... strange... gernotbelger@9093: GWT.log("GaugeListGrid - openOnDistance item " + gauge.getKmStart() + " " + gauge.getKmEnd()); gernotbelger@9093: if ((start >= gauge.getKmStart() && start <= gauge.getKmEnd()) || (end >= gauge.getKmStart() && end <= gauge.getKmEnd()) gernotbelger@9093: || (start <= gauge.getKmStart() && end >= gauge.getKmEnd())) { gernotbelger@9093: addExpandedRecord(gauge); gernotbelger@9093: } else { gernotbelger@9093: removeOrCollapse(gauge, type); bjoern@4956: } gernotbelger@9093: } else { gernotbelger@9093: removeOrCollapse(gauge, type); bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: private void removeOrCollapse(final GaugeInfo gauge, final DisappearType type) { gernotbelger@9093: switch (type) { gernotbelger@9093: case remove: gernotbelger@9093: // Remove: gauge wird der datasource nicht hinzugefügt gernotbelger@9093: break; gernotbelger@9093: case collapse: gernotbelger@9093: addCollapsedRecord(gauge); gernotbelger@9093: break; gernotbelger@9093: case stayVisible: // TODO: check gernotbelger@9093: addExpandedRecord(gauge); gernotbelger@9093: break; gernotbelger@9093: } gernotbelger@9093: gernotbelger@9093: } gernotbelger@9093: bjoern@4956: /** felix@4980: * Open Gauge entry if a location fits to the gauge. bjoern@4956: */ gernotbelger@9093: public void openOnLocations(final List locations) { bjoern@4956: GWT.log("GaugeListGrid - openOnLocations " + locations); bjoern@4956: gernotbelger@9093: setData(new ListGridRecord[] {}); gernotbelger@9093: bjoern@4956: if (locations == null || locations.isEmpty()) { bjoern@4956: return; bjoern@4956: } bjoern@4956: gernotbelger@9093: for (final GaugeInfo gauge : this.gauges) { bjoern@4956: boolean isset = false; gernotbelger@9093: for (final Double location : locations) { bjoern@4956: if (locations == null) { bjoern@4956: continue; bjoern@4956: } bjoern@4956: gernotbelger@9093: final Double start = gauge.getKmStart(); gernotbelger@9093: final Double end = gauge.getKmEnd(); bjoern@4956: if (start == null || end == null) { bjoern@4956: // should not occur but avoid NullPointerException bjoern@4956: continue; bjoern@4956: } bjoern@4956: bjoern@4956: if (location >= start && location <= end) { bjoern@4956: isset = true; bjoern@4956: break; bjoern@4956: } bjoern@4956: } bjoern@4956: if (isset) { gernotbelger@9093: addExpandedRecord(gauge); gernotbelger@9093: } else { gernotbelger@9093: addCollapsedRecord(gauge); bjoern@4956: } bjoern@4956: } bjoern@4956: } bjoern@4956: gernotbelger@9093: private void addExpandedRecord(final GaugeInfo gauge) { gernotbelger@9093: final GaugeRecord record = new GaugeRecord(gauge); gernotbelger@9093: gernotbelger@9093: this.addData(record); gernotbelger@9093: gernotbelger@9093: expandRecord(record); gernotbelger@9093: } gernotbelger@9093: gernotbelger@9093: private void addCollapsedRecord(final GaugeInfo gauge) { gernotbelger@9093: final GaugeRecord record = new GaugeRecord(gauge); gernotbelger@9093: gernotbelger@9093: this.addData(record); gernotbelger@9093: gernotbelger@9093: collapseRecord(record); gernotbelger@9093: } gernotbelger@9093: bjoern@4956: @Override gernotbelger@9093: protected Canvas getExpandPanel(final ListGridRecord record) { gernotbelger@9093: final GaugeRecord item = (GaugeRecord) record; gernotbelger@9093: return new GaugeInfoPanel(item, this.flys); bjoern@4956: } bjoern@4960: felix@6032: /** felix@6032: * When clicked on the gauge discharge link, open new Gauge Discharge felix@6032: * Curve view. felix@6032: */ bjoern@4960: @Override gernotbelger@9093: public void onRecordClick(final RecordClickEvent event) { gernotbelger@9093: final GaugeRecord gauge = (GaugeRecord) event.getRecord(); gernotbelger@9093: final Config config = Config.getInstance(); rrenkert@8303: final String locale = config.getLocale(); gernotbelger@9093: this.createCollectionService.create(locale, this.flys.getCurrentUser().identifier(), new AsyncCallback() { gernotbelger@9093: @Override gernotbelger@9093: public void onFailure(final Throwable caught) { gernotbelger@9093: GWT.log("Could not create the new collection."); gernotbelger@9093: SC.warn(FLYS.getExceptionString(GaugeListGrid.this.MSG, caught)); gernotbelger@9093: } gernotbelger@9093: gernotbelger@9093: @Override gernotbelger@9093: public void onSuccess(final Collection collection) { gernotbelger@9093: GWT.log("Successfully created a new collection."); gernotbelger@9093: createArtifact(collection, locale, gauge); gernotbelger@9093: } gernotbelger@9093: }); gernotbelger@9093: } gernotbelger@9093: gernotbelger@9093: private void createArtifact(final Collection collection, final String locale, final GaugeRecord gauge) { gernotbelger@9093: this.artifactService.create(locale, "gaugedischargecurve", null, new AsyncCallback() { gernotbelger@9093: @Override gernotbelger@9093: public void onFailure(final Throwable caught) { gernotbelger@9093: GWT.log("Could not create the new artifact."); gernotbelger@9093: SC.warn(FLYS.getExceptionString(GaugeListGrid.this.MSG, caught)); gernotbelger@9093: } gernotbelger@9093: gernotbelger@9093: @Override gernotbelger@9093: public void onSuccess(final Artifact artifact) { gernotbelger@9093: GWT.log("Successfully created a new artifact."); gernotbelger@9093: gernotbelger@9093: final DataItem riverItem = new DefaultDataItem("river", "river", gauge.getRiverName()); gernotbelger@9093: final Data river = new DefaultData("river", null, null, new DataItem[] { riverItem }); gernotbelger@9093: gernotbelger@9093: final DataItem refItem = new DefaultDataItem("reference_gauge", "reference_gauge", gauge.getOfficialNumber().toString()); gernotbelger@9093: final Data ref = new DefaultData("reference_gauge", null, null, new DataItem[] { refItem }); gernotbelger@9093: gernotbelger@9093: final DataItem locItem = new DefaultDataItem("ld_locations", "ld_locations", gauge.getStation().toString()); gernotbelger@9093: final Data loc = new DefaultData("ld_locations", null, null, new DataItem[] { locItem }); gernotbelger@9093: gernotbelger@9093: final DataItem nameItem = new DefaultDataItem("gauge_name", "gauge_name", gauge.getName()); gernotbelger@9093: final Data name = new DefaultData("gauge_name", null, null, new DataItem[] { nameItem }); gernotbelger@9093: gernotbelger@9093: final Data[] data = new Data[] { river, ref, loc, name }; gernotbelger@9093: GaugeListGrid.this.forwardService.go(locale, artifact, data, new AsyncCallback() { rrenkert@8303: @Override gernotbelger@9093: public void onFailure(final Throwable caught) { gernotbelger@9093: GWT.log("Could not feed the artifact."); gernotbelger@9093: SC.warn(caught.getMessage()); rrenkert@8303: } rrenkert@8303: rrenkert@8303: @Override gernotbelger@9093: public void onSuccess(final Artifact artifact) { gernotbelger@9093: GWT.log("Successfully feed the artifact."); gernotbelger@9093: final CollectionView view = new CollectionView(GaugeListGrid.this.flys, collection, artifact); gernotbelger@9093: GaugeListGrid.this.flys.getWorkspace().addView(collection.identifier(), view); gernotbelger@9093: view.addArtifactToCollection(artifact); rrenkert@8303: } gernotbelger@9093: }); gernotbelger@9093: } gernotbelger@9093: }); bjoern@4960: } bjoern@4961: bjoern@4961: @Override gernotbelger@9093: public String getCellCSSText(final ListGridRecord record, final int rowNum, final int colNum) { bjoern@4961: if (colNum == ABFLUSSTAFEL_COLUMN) { bjoern@4961: // display the ablfusstafel cell like a link gernotbelger@9093: return "text-decoration: underline; color: #0000EE; " + "cursor: pointer;"; gernotbelger@9093: } else { bjoern@4961: return super.getCellCSSText(record, rowNum, colNum); bjoern@4961: } bjoern@4961: } bjoern@4956: }