Mercurial > dive4elements > river
view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/CollectionView.java @ 9260:b570b6fcc052
VegetationZone color added and disabled
author | gernotbelger |
---|---|
date | Tue, 17 Jul 2018 10:59:27 +0200 |
parents | 23945061daec |
children | abf14917be32 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.client.client.ui; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import org.dive4elements.river.client.client.Config; import org.dive4elements.river.client.client.FLYS; import org.dive4elements.river.client.client.FLYSConstants; import org.dive4elements.river.client.client.event.CollectionChangeEvent; import org.dive4elements.river.client.client.event.CollectionChangeHandler; import org.dive4elements.river.client.client.event.HasCollectionChangeHandlers; import org.dive4elements.river.client.client.event.HasOutputModesChangeHandlers; import org.dive4elements.river.client.client.event.OutputModesChangeEvent; import org.dive4elements.river.client.client.event.OutputModesChangeHandler; import org.dive4elements.river.client.client.event.ParameterChangeEvent; import org.dive4elements.river.client.client.event.ParameterChangeHandler; import org.dive4elements.river.client.client.services.AddArtifactService; import org.dive4elements.river.client.client.services.AddArtifactServiceAsync; import org.dive4elements.river.client.client.services.ArtifactService; import org.dive4elements.river.client.client.services.ArtifactServiceAsync; import org.dive4elements.river.client.client.services.CollectionAttributeService; import org.dive4elements.river.client.client.services.CollectionAttributeServiceAsync; import org.dive4elements.river.client.client.services.CreateCollectionService; import org.dive4elements.river.client.client.services.CreateCollectionServiceAsync; import org.dive4elements.river.client.client.services.DescribeCollectionService; import org.dive4elements.river.client.client.services.DescribeCollectionServiceAsync; import org.dive4elements.river.client.client.services.LoadArtifactService; import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync; import org.dive4elements.river.client.shared.model.Artifact; import org.dive4elements.river.client.shared.model.ArtifactDescription; import org.dive4elements.river.client.shared.model.Collection; import org.dive4elements.river.client.shared.model.ExportMode; import org.dive4elements.river.client.shared.model.OutputMode; import org.dive4elements.river.client.shared.model.Recommendation; import org.dive4elements.river.client.shared.model.ReportMode; import org.dive4elements.river.client.shared.model.User; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.rpc.AsyncCallback; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.Window; import com.smartgwt.client.widgets.events.CloseClickEvent; import com.smartgwt.client.widgets.events.CloseClickHandler; import com.smartgwt.client.widgets.layout.Layout; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.tab.TabSet; import com.smartgwt.client.widgets.tab.events.TabSelectedHandler; /** * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ public class CollectionView extends Window implements CollectionChangeHandler, HasCollectionChangeHandlers, OutputModesChangeHandler, HasOutputModesChangeHandlers, ParameterChangeHandler, CloseClickHandler { /** The ArtifactService used to communicate with the Artifact server. */ protected CreateCollectionServiceAsync createCollectionService = GWT.create(CreateCollectionService.class); /** The ArtifactService used to communicate with the Artifact server. */ protected ArtifactServiceAsync createArtifactService = GWT.create(ArtifactService.class); /** The AddArtifactService used to add an artifact to a collection. */ protected AddArtifactServiceAsync addArtifactService = GWT.create(AddArtifactService.class); /** The DescribeCollectionService used to update the existing collection. */ protected DescribeCollectionServiceAsync describeCollectionService = GWT.create(DescribeCollectionService.class); protected CollectionAttributeServiceAsync updater = GWT.create(CollectionAttributeService.class); /** The LoadArtifactService used to load recommendations */ protected LoadArtifactServiceAsync loadArtifactService = GWT.create(LoadArtifactService.class); /** The message class that provides i18n strings. */ protected FLYSConstants messages = GWT.create(FLYSConstants.class); /** The FLYS instance used to call services. */ protected FLYS flys; /** The ParameterList. */ protected ParameterList parameterList; /** The list of CollectionChangeHandlers. */ protected List<CollectionChangeHandler> handlers; /** The list of OutputModesChangeHandlers. */ protected List<OutputModesChangeHandler> outHandlers; /** The collection to be displayed. */ protected Collection collection; /** The artifact that handles the parameterization. */ protected Artifact artifact; protected TabSet tabs; /** The output tab. */ protected Map<String, OutputTab> outputTabs; /** The layout. */ protected Layout layout; /** Layout to show spinning wheel of joy. */ protected VLayout lockScreen; protected int artifactsQueue; protected int recommendationQueue; protected Stack<Recommendation> newRecommendations; /** Values for fix analysis charts */ protected double currentKm; protected double minKm; protected double maxKm; protected double steps; /** * This constructor creates a new CollectionView that is used to display the * <i>collection</i>. */ public CollectionView(final FLYS flys) { this.flys = flys; this.tabs = new TabSet(); this.outputTabs = new HashMap<String, OutputTab>(); this.handlers = new ArrayList<CollectionChangeHandler>(); this.outHandlers = new ArrayList<OutputModesChangeHandler>(); this.layout = new VLayout(); this.parameterList = new ParameterList(flys, this, this.messages.new_project()); this.artifactsQueue = 0; this.recommendationQueue = 0; this.newRecommendations = new Stack<Recommendation>(); this.currentKm = -1d; this.minKm = -1d; this.maxKm = -1d; this.steps = -1d; addCollectionChangeHandler(this); addCollectionChangeHandler(this.parameterList); addCollectionChangeHandler(flys); addOutputModesChangeHandler(this); addOutputModesChangeHandler(this.parameterList); addCloseClickHandler(this); this.parameterList.addParameterChangeHandler(this); init(); } /** * @param collection * The collection to be displayed. */ public CollectionView(final FLYS flys, final Collection collection, final Artifact artifact) { this.flys = flys; this.artifact = artifact; this.collection = collection; this.tabs = new TabSet(); this.outputTabs = new HashMap<String, OutputTab>(); this.handlers = new ArrayList<CollectionChangeHandler>(); this.outHandlers = new ArrayList<OutputModesChangeHandler>(); this.layout = new VLayout(); this.currentKm = -1d; this.minKm = -1d; this.maxKm = -1d; this.steps = -1d; if (artifact != null) { this.parameterList = new ParameterList(flys, this, // FIXME: literally every information about the artifact is transported from the server side // but... the international name is resolved client-side.... Instead also transport the description of the artifact and // use it! // FIXME: the same holds for a very few other international strings (e.g. names of facets used in Tabs) this.messages.getString(artifact.getName()), artifact); } else { this.parameterList = new ParameterList(flys, this, this.messages.new_project()); } this.artifactsQueue = 0; this.newRecommendations = new Stack<Recommendation>(); addCollectionChangeHandler(this); addCollectionChangeHandler(this.parameterList); addCollectionChangeHandler(flys); addOutputModesChangeHandler(this); addOutputModesChangeHandler(this.parameterList); addCloseClickHandler(this); this.parameterList.addParameterChangeHandler(this); init(); setCollection(collection); if (artifact != null) { setArtifact(artifact); } } /** * This method handles the initial layout stuff. */ protected void init() { setWidth(1010); setHeight(700); setMaximized(true); this.layout.setWidth100(); setCanDragReposition(true); setCanDragResize(true); setShowMaximizeButton(true); setKeepInParentRect(true); setTitle(""); addItem(this.layout); this.layout.addMember(this.tabs); this.tabs.addTab(this.parameterList); } protected FLYS getFlys() { return this.flys; } /** * This method registers a new CollectionChangeHandler. * * @param handler * The new CollectionChangeHandler. */ @Override public void addCollectionChangeHandler(final CollectionChangeHandler handler) { if (handler != null) { this.handlers.add(handler); } } /** * This method registers a new OutputModesChangeHandler. * * @param handler * The new OutputModesChangeHandler. */ @Override public void addOutputModesChangeHandler(final OutputModesChangeHandler handler) { if (handler != null) { this.outHandlers.add(handler); } } /** * This method calls the <code>onValueChange()</code> method of all * registered ValueChangeHanders. */ protected void fireCollectionChangeEvent(final Collection old, final Collection newCol) { for (final CollectionChangeHandler handler : this.handlers) { handler.onCollectionChange(new CollectionChangeEvent(old, newCol)); } } protected void fireOutputModesChangeEvent(final OutputMode[] outputs) { if (this.collection == null) { return; } for (final OutputModesChangeHandler handler : this.outHandlers) { handler.onOutputModesChange(new OutputModesChangeEvent(outputs)); } } /** Disables input, grey out, show spinning wheel of joy. */ public void lockUI() { this.lockScreen = ScreenLock.lockUI(this.layout, this.lockScreen); } /** Enable input, remove grey, remove spinning wheel of joy. */ public void unlockUI() { ScreenLock.unlockUI(this.layout, this.lockScreen); } /** * This method returns true, if the Collection is new and no plugins has * been chosen. * * @return true, if the Collection is new. */ public boolean isNew() { return this.collection.hasItems(); } /** * Returns the artifact that is used for the parameterization. * * @return the artifact that is used for the parameterization. */ public Artifact getArtifact() { return this.artifact; } public User getUser() { return getFlys().getCurrentUser(); } /** * Set the current artifact that is the master of the parameterization. * * @param artifact * The new artifact. */ public void setArtifact(final Artifact artifact) { this.artifact = artifact; onArtifactChanged(artifact); } public void onArtifactChanged(final Artifact artifact) { artifactChanged(); if (artifact.isInBackground()) { final LoadingPanel p = new LoadingPanel(this, artifact); p.addStepBackHandler(this.parameterList); } } /** * Implements the onCollectionChange() method to do update the GUI after the * parameterization has changed. * * @param event * The ParameterChangeEvent. */ @Override public void onParameterChange(final ParameterChangeEvent event) { GWT.log("CollectionView.onParameterChange"); setArtifact(event.getNewValue()); } protected void artifactChanged() { final Collection c = getCollection(); if (c != null) { loadCollection(c); } else { updateView(); } } /** * Loads all information of a collection. * If 'recommendations' present, load these. * * @param c * the Collection */ private void loadCollection(final Collection c) { final ArtifactDescription desc = getArtifact().getArtifactDescription(); final Recommendation[] recom = desc.getRecommendations(); final Config config = Config.getInstance(); final String locale = config.getLocale(); this.describeCollectionService.describe(c.identifier(), locale, new AsyncCallback<Collection>() { @Override public void onFailure(final Throwable caught) { GWT.log("Could not DESCRIBE collection."); SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught)); } @Override public void onSuccess(final Collection newCollection) { GWT.log("Successfully DESCRIBED collection."); boolean loaded = true; for (final Recommendation r : recom) { if (!newCollection.loadedRecommendation(r)) { loaded = false; } } if (!loaded) { loadRecommendedArtifacts(recom); } else { setCollection(newCollection); } } }); } /** * Returns the collection of displayed by this view. * * @return the collection of this view. */ public Collection getCollection() { return this.collection; } protected void setCollection(final Collection collection) { setCollection(collection, false); } /** * Set the current collection. * * @param collection * The new collection. * @param suppress * Whether to fire a collectionchangeevent. */ protected void setCollection(final Collection collection, final boolean suppress) { if (collection != null && this.collection == null) { this.flys.getWorkspace().addView(collection.identifier(), this); } final Collection tmp = this.collection; this.collection = collection; setTitle(collection.getDisplayName()); if (!suppress) { fireCollectionChangeEvent(tmp, this.collection); } } @Override public void onCollectionChange(final CollectionChangeEvent event) { if (this.artifactsQueue > 0) { GWT.log("Do not update UI because we are still loading Artifacts."); return; } final Collection newCol = event.getNewValue(); final Map<String, OutputMode> outs = newCol.getOutputModes(); final Set<String> keys = outs.keySet(); final OutputMode[] prepared = new OutputMode[outs.size()]; int idx = 0; for (final String outname : keys) { prepared[idx++] = outs.get(outname); } fireOutputModesChangeEvent(prepared); updateView(); } @Override public void onOutputModesChange(final OutputModesChangeEvent event) { clearOutputTabs(); final OutputMode[] outs = event.getOutputModes(); if (outs == null) { return; } boolean hasCSV = false; for (final OutputMode out : outs) { addOutputTab(out.getName(), out); if (out instanceof ExportMode) { final ExportMode export = (ExportMode) out; if (export.getFacet("csv") != null) { hasCSV = true; } } } if (!hasCSV) { this.parameterList.removeTable(); } } /** * Adds a new tab for the OutputMode <i>out</i>. * * @param name * The name and title of the output. */ protected void addOutputTab(final String name, final OutputMode out) { if (out instanceof ExportMode) { final ExportMode export = (ExportMode) out; if (export.getFacet("csv") != null && !this.parameterList.hasTable()) { final TableDataPanel p = new TableDataPanel(); p.setUuid(this.collection.identifier()); p.setName(out.getName()); this.parameterList.setTable(p); } return; } if (out instanceof ReportMode) { // we don't want to display report modes at all return; } GWT.log("Add new output tab for '" + name + "'"); final String title = this.messages.getString(name); final OutputTab tab = out.createOutputTab(title, getCollection(), this); if (tab != null) { this.outputTabs.put(name, tab); } } /** * Removes all output mode tabs from tab bar. */ protected void clearOutputTabs() { GWT.log("Clear OutputTabs."); final int num = this.tabs.getNumTabs(); for (int i = num - 1; i >= 1; i--) { this.tabs.removeTab(i); } this.outputTabs.clear(); } /** * Update the view (refresh the list of old and current data). */ protected void updateView() { GWT.log("CollectionView.updateView()"); updateOutputTabs(); } /** * This method is used to update the tabs to show specific output modes. */ protected void updateOutputTabs() { GWT.log("Update output tabs."); if (this.outputTabs != null) { final Set<String> keys = this.outputTabs.keySet(); for (final String key : keys) { this.tabs.addTab(this.outputTabs.get(key)); } } } @Override public void onCloseClick(final CloseClickEvent event) { if (this.collection != null) { if (this.artifact != null) { this.flys.closeProject(this.collection.identifier()); } else { this.flys.getProjectList().deleteCollection(this.collection); } } else { hide(); destroy(); } } public void addArtifactToCollection(final Artifact artifact) { final Config config = Config.getInstance(); final String locale = config.getLocale(); final Collection collection = getCollection(); GWT.log("CollectionView.addArtifactToCollection " + collection); if (collection != null) { this.addArtifactService.add(collection, artifact, locale, new AsyncCallback<Collection>() { @Override public void onFailure(final Throwable caught) { GWT.log("An error occured while adding artifact."); SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught)); } @Override public void onSuccess(final Collection newCollection) { GWT.log("Successfully added artifacts."); setCollection(newCollection); } }); } else { // Create new collection and add artifact. final Artifact art = artifact; this.createCollectionService.create(locale, this.flys.getCurrentUser().identifier(), new AsyncCallback<Collection>() { @Override public void onFailure(final Throwable caught) { GWT.log("Could not create the new collection."); SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught)); } @Override public void onSuccess(final Collection collection) { GWT.log("Successfully created a new collection."); CollectionView.this.addArtifactService.add(collection, art, locale, new AsyncCallback<Collection>() { @Override public void onFailure(final Throwable caught) { GWT.log("An error occured while " + "adding artifact."); SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught)); } @Override public void onSuccess(final Collection newCollection) { GWT.log("Successfully added artifacts."); setCollection(newCollection); } }); } }); } } protected void addRecommendationsToCollection() { final Config config = Config.getInstance(); final String locale = config.getLocale(); final Collection collection = getCollection(); collection.addRecommendations(this.newRecommendations); this.updater.update(collection, locale, new AsyncCallback<Collection>() { @Override public void onFailure(final Throwable caught) { CollectionView.this.newRecommendations.removeAllElements(); setCollection(collection); GWT.log("An error occured while saving recommendations."); SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught)); } @Override public void onSuccess(final Collection newCol) { GWT.log("Successfully saved recommendations."); CollectionView.this.newRecommendations.removeAllElements(); setCollection(newCol); } }); } protected void loadRecommendedArtifacts(final Recommendation[] recommendations) { final Config config = Config.getInstance(); final String locale = config.getLocale(); final Collection collection = getCollection(); final Artifact masterArtifact = getArtifact(); if (recommendations == null) { GWT.log("WARNING: Currently no recommendations."); return; } for (final Recommendation recommendation : recommendations) { if (collection.loadedRecommendation(recommendation)) { continue; } this.newRecommendations.push(recommendation); // XXX: UGLY! If no reference artifact given use uuid of // current artifact as reference. if (recommendation.getMasterArtifact() == null) { recommendation.setMasterArtifact(masterArtifact.getUuid()); } } this.loadArtifactService.loadMany(collection, recommendations, null, locale, new AsyncCallback<Artifact[]>() { @Override public void onFailure(final Throwable caught) { GWT.log("Error loading recommendations: " + caught.getMessage()); SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught)); } @Override public void onSuccess(final Artifact[] artifacts) { GWT.log("Loaded artifacts: " + artifacts.length); addRecommendationsToCollection(); } }); } public void registerTabHandler(final TabSelectedHandler tse) { this.tabs.addTabSelectedHandler(tse); } public void setCurrentKm(final double currentKm) { this.currentKm = currentKm; } public double getCurrentKm() { return this.currentKm; } public void setMinKm(final double km) { this.minKm = km; } public double getMinKm() { return this.minKm; } public void setMaxKm(final double km) { this.maxKm = km; } public double getMaxKm() { return this.maxKm; } public void setSteps(final double step) { this.steps = step; } public double getSteps() { return this.steps; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :