[PATCH 2 of 2] Navigationtheme panel now shows themes of dWt and WQ charts grayed out, if the current station is outside the valid range of the theme

Wald Commits scm-commit at wald.intevation.org
Thu Aug 16 16:28:10 CEST 2018


# HG changeset patch
# User gernotbelger
# Date 1534429683 -7200
# Node ID 05405292a7ca99504615e74938b355062914943b
# Parent  9744ce3c3853abdcd6b609957dfbd2f9f6c1eb3f
Navigationtheme panel now shows themes of dWt and WQ charts grayed out, if the current station is outside the valid range of the theme.

diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/IThemeRecordHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/IThemeRecordHandler.java	Thu Aug 16 16:28:03 2018 +0200
@@ -0,0 +1,21 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * 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 org.dive4elements.river.client.shared.model.FacetRecord;
+
+/**
+ * Implementors of this interface are allowed to manipulate the records of the theme panel.
+ *
+ * @author Gernot Belger
+ */
+public interface IThemeRecordHandler {
+    void handle(FacetRecord facetRecord);
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/NoopThemeRecordHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/NoopThemeRecordHandler.java	Thu Aug 16 16:28:03 2018 +0200
@@ -0,0 +1,25 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * 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 org.dive4elements.river.client.shared.model.FacetRecord;
+
+/**
+ * Default implementation of {@link IThemeRecordHandler} that does nothing.
+ *
+ * @author Gernot Belger
+ */
+public final class NoopThemeRecordHandler implements IThemeRecordHandler {
+
+    @Override
+    public void handle(final FacetRecord facetRecord) {
+        /* we do nothing */
+    }
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ThemePanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ThemePanel.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/ThemePanel.java	Thu Aug 16 16:28:03 2018 +0200
@@ -8,22 +8,8 @@
 
 package org.dive4elements.river.client.client.ui;
 
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-import com.smartgwt.client.util.BooleanCallback;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.grid.ListGrid;
-import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.grid.events.EditCompleteEvent;
-import com.smartgwt.client.widgets.grid.events.EditCompleteHandler;
-import com.smartgwt.client.widgets.grid.events.RowContextClickEvent;
-import com.smartgwt.client.widgets.grid.events.RowContextClickHandler;
-import com.smartgwt.client.widgets.menu.Menu;
-import com.smartgwt.client.widgets.menu.MenuItem;
-import com.smartgwt.client.widgets.menu.events.ClickHandler;
-import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.dive4elements.river.client.client.Config;
 import org.dive4elements.river.client.client.FLYSConstants;
@@ -47,8 +33,21 @@
 import org.dive4elements.river.client.shared.model.Theme;
 import org.dive4elements.river.client.shared.model.ThemeList;
 
-import java.util.ArrayList;
-import java.util.List;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.util.BooleanCallback;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.EditCompleteEvent;
+import com.smartgwt.client.widgets.grid.events.EditCompleteHandler;
+import com.smartgwt.client.widgets.grid.events.RowContextClickEvent;
+import com.smartgwt.client.widgets.grid.events.RowContextClickHandler;
+import com.smartgwt.client.widgets.menu.Menu;
+import com.smartgwt.client.widgets.menu.MenuItem;
+import com.smartgwt.client.widgets.menu.events.ClickHandler;
+import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
 
 /**
  * ThemePanel on the left in CollectionView.
@@ -57,67 +56,62 @@
  *
  * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
  */
-public abstract class ThemePanel
-extends               Canvas
-implements            OnMoveHandler,
-                      EditCompleteHandler,
-                      HasOutputParameterChangeHandlers,
-                      HasRedrawRequestHandlers
-{
-    protected CollectionAttributeServiceAsync updater =
-        GWT.create(CollectionAttributeService.class);
+public abstract class ThemePanel extends Canvas implements OnMoveHandler, EditCompleteHandler, HasOutputParameterChangeHandlers, HasRedrawRequestHandlers {
+
+    private final CollectionAttributeServiceAsync updater = GWT.create(CollectionAttributeService.class);
 
     /** The service used to get collection item attributes. */
-    protected CollectionItemAttributeServiceAsync itemAttributeService =
-        GWT.create(CollectionItemAttributeService.class);
+    private final CollectionItemAttributeServiceAsync itemAttributeService = GWT.create(CollectionItemAttributeService.class);
 
     /** i18ner. */
-    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+    protected final FLYSConstants MSG = GWT.create(FLYSConstants.class);
 
     /** List of OutParameterChangedHandler. */
-    protected List<OutputParameterChangeHandler> outHandlers;
+    private final List<OutputParameterChangeHandler> outHandlers;
 
     /** List of ChartShallRedrawHandler. */
-    protected List<RedrawRequestHandler> redrawRequestHandlers;
+    protected final List<RedrawRequestHandler> redrawRequestHandlers;
 
-    protected OutputMode mode;
+    protected final OutputMode mode;
 
-    protected ThemeNavigationPanel navigation;
-    protected ListGrid list;
+    protected final ThemeNavigationPanel navigation;
 
-    /** The collection view*/
+    protected final ListGrid list;
+
+    /** The collection view */
     protected CollectionView view;
 
+    private final IThemeRecordHandler recordHandler;
+
     /**
      * Setup Grid, navigation bar.
-     * @param collection Collection for which to show themes.
+     *
+     * @param collection
+     *            Collection for which to show themes.
      */
-    public ThemePanel(
-        OutputMode mode,
-        CollectionView view
-    ) {
-        this.mode       = mode;
-        this.list       = createGrid();
-        this.view       = view;
-        list.addRowContextClickHandler(new RowContextClickHandler() {
+    public ThemePanel(final OutputMode mode, final CollectionView view, final IThemeRecordHandler recordHandler) {
+        this.mode = mode;
+        this.recordHandler = recordHandler;
+        this.list = createGrid();
+        this.view = view;
+
+        this.list.addRowContextClickHandler(new RowContextClickHandler() {
             @Override
-            public void onRowContextClick(RowContextClickEvent event) {
-                ListGridRecord[] records = list.getSelectedRecords();
+            public void onRowContextClick(final RowContextClickEvent event) {
+                final ListGridRecord[] records = ThemePanel.this.list.getSelectedRecords();
 
                 Menu menu = null;
 
                 if (records == null || records.length == 0) {
                     return;
-                }
-                else if (records.length == 1) {
+                } else if (records.length == 1) {
                     menu = getSingleContextMenu(records);
-                }
-                else if (records.length > 1) {
+                } else if (records.length > 1) {
                     menu = getMultiContextMenu(records);
                 }
 
                 if (menu != null) {
-                    list.setContextMenu(menu);
+                    ThemePanel.this.list.setContextMenu(menu);
                     menu.showContextMenu();
 
                     event.cancel();
@@ -127,104 +121,98 @@
 
         this.redrawRequestHandlers = new ArrayList<RedrawRequestHandler>();
         this.outHandlers = new ArrayList<OutputParameterChangeHandler>();
-        this.navigation  = new ThemeNavigationPanel();
+        this.navigation = new ThemeNavigationPanel();
         this.navigation.addOnMoveHandler(this);
 
         this.setShowResizeBar(true);
     }
 
-
     public abstract void activateTheme(Theme theme, boolean active);
 
-
     /**
      * Replace the current collection with a new one. <b>NOTE: this operation
      * triggers updateGrid() which modifies the themes in the grid.</b>
      *
-     * @param collection The new collection object.
+     * @param collection
+     *            The new collection object.
      */
-    protected void setCollection(Collection collection) {
+    protected void setCollection(final Collection collection) {
         // Set collection of view, but do not trigger event shooting.
         this.view.setCollection(collection, true);
 
         updateGrid();
     }
 
-
     /** Get Collection. */
     public Collection getCollection() {
-        return view.getCollection();
+        return this.view.getCollection();
     }
 
-
     /**
      * Returns the ThemeList of the current collection and output mode.
      *
      * @return the current ThemeList.
      */
     public ThemeList getThemeList() {
-        return getCollection().getThemeList(mode.getName());
+        return getCollection().getThemeList(this.mode.getName());
     }
 
     public ListGridRecord[] getSelectedRecords() {
-        return list.getSelectedRecords();
+        return this.list.getSelectedRecords();
     }
 
     /**
      * Registers a new OutputParameterChangeHandler.
      *
-     * @param h The new handler.
+     * @param h
+     *            The new handler.
      */
     @Override
-    public void addOutputParameterChangeHandler(OutputParameterChangeHandler h){
+    public void addOutputParameterChangeHandler(final OutputParameterChangeHandler h) {
         if (h != null) {
-            outHandlers.add(h);
+            this.outHandlers.add(h);
         }
     }
 
-
     /**
      * Registers a RedrawRequestHandler.
      *
-     * @param h The new handler.
+     * @param h
+     *            The new handler.
      */
     @Override
-    public void addRedrawRequestHandler(RedrawRequestHandler h){
+    public void addRedrawRequestHandler(final RedrawRequestHandler h) {
         if (h != null) {
-            redrawRequestHandlers.add(h);
+            this.redrawRequestHandlers.add(h);
         }
     }
 
-
     /**
      * Request a redraw of e.g. a Chart.
      */
     final public void requestRedraw() {
-        for (RedrawRequestHandler handler: redrawRequestHandlers) {
+        for (final RedrawRequestHandler handler : this.redrawRequestHandlers) {
             handler.onRedrawRequest(new RedrawRequestEvent(Type.DEFAULT));
         }
     }
 
-
     /**
      * Called when the attribution of an output changed. It informs the
      * registered handlers about the changes.
      */
     protected void fireOutputParameterChanged() {
-        OutputParameterChangeEvent evt = new OutputParameterChangeEvent();
+        final OutputParameterChangeEvent evt = new OutputParameterChangeEvent();
 
-        for (OutputParameterChangeHandler handler: outHandlers) {
+        for (final OutputParameterChangeHandler handler : this.outHandlers) {
             handler.onOutputParameterChanged(evt);
         }
     }
 
-
     /** Registers the CollectionView associated to this ThemePanel. */
-    public void setCollectionView(CollectionView view) {
+    public void setCollectionView(final CollectionView view) {
         this.view = view;
     }
 
-
     /**
      * This method is used to clear the current theme grid and add new updated
      * data.
@@ -232,21 +220,21 @@
     protected void updateGrid() {
         GWT.log("ThemePanel.updateGrid");
 
-        ListGridRecord[] selected = list.getSelectedRecords();
+        final ListGridRecord[] selected = this.list.getSelectedRecords();
 
         clearGrid();
 
-        ThemeList themeList = getThemeList();
+        final ThemeList themeList = getThemeList();
 
         if (themeList == null) {
             GWT.log("ERROR: No theme list.");
             return;
         }
 
-        int count = themeList.getThemeCount();
+        final int count = themeList.getThemeCount();
 
         for (int i = 1; i <= count; i++) {
-            Theme theme = themeList.getThemeAt(i);
+            final Theme theme = themeList.getThemeAt(i);
 
             if (theme == null) {
                 continue;
@@ -260,41 +248,38 @@
                 continue;
             }
 
-            FacetRecord newRecord = createRecord(theme);
+            final FacetRecord newRecord = createRecord(theme);
             addFacetRecord(newRecord);
 
-            String newArtifact = theme.getArtifact();
-            String newFacet    = theme.getFacet();
-            int    newIndex    = theme.getIndex();
+            final String newArtifact = theme.getArtifact();
+            final String newFacet = theme.getFacet();
+            final int newIndex = theme.getIndex();
 
-            for (ListGridRecord r: selected) {
-                FacetRecord sel = (FacetRecord) r;
-                Theme oldTheme  = sel.getTheme();
+            for (final ListGridRecord r : selected) {
+                final FacetRecord sel = (FacetRecord) r;
+                final Theme oldTheme = sel.getTheme();
 
-                if (oldTheme.getArtifact().equals(newArtifact)
-                    && oldTheme.getFacet().equals(newFacet)
-                    && oldTheme.getIndex() == newIndex) {
-                    list.selectRecord(newRecord);
+                if (oldTheme.getArtifact().equals(newArtifact) && oldTheme.getFacet().equals(newFacet) && oldTheme.getIndex() == newIndex) {
+                    this.list.selectRecord(newRecord);
                 }
             }
         }
 
+        updateThemes();
+
         fireOutputParameterChanged();
     }
 
-
     /** Adds given Record to the list (table). */
-    protected void addFacetRecord(FacetRecord rec) {
-        list.addData(rec);
+    protected void addFacetRecord(final FacetRecord rec) {
+        this.list.addData(rec);
     }
 
-
     /** Create a FacetRecord that wraps given theme. */
-    protected FacetRecord createRecord(Theme theme) {
+    protected final FacetRecord createRecord(final Theme theme) {
         return new FacetRecord(theme);
     }
 
-
     /**
      * This method triggers the CollectionAttributeService. Based on the current
      * collectin settings, the attribute of the collection is modified or not.
@@ -303,25 +288,24 @@
      */
     public void updateCollection() {
         final Config config = Config.getInstance();
-        final String loc    = config.getLocale();
+        final String loc = config.getLocale();
 
         GWT.log("ThemePanel.updateCollection via RPC now");
 
         // Don't forget to enable the panel after the request has finished!
         disable();
 
-        updater.update(getCollection(), loc, new AsyncCallback<Collection>() {
+        this.updater.update(getCollection(), loc, new AsyncCallback<Collection>() {
             @Override
-            public void onFailure(Throwable caught) {
+            public void onFailure(final Throwable caught) {
                 GWT.log("Could not update collection attributes.");
-                SC.warn(MSG.getString(caught.getMessage()));
+                SC.warn(ThemePanel.this.MSG.getString(caught.getMessage()));
 
                 enable();
             }
 
-
             @Override
-            public void onSuccess(Collection collection) {
+            public void onSuccess(final Collection collection) {
                 setCollection(collection);
 
                 enable();
@@ -329,51 +313,43 @@
         });
     }
 
-
     /**
      * Create and configure the Grid to display.
      */
     protected ListGrid createGrid() {
-        ListGrid grid = createNewGrid();
+        final ListGrid grid = new ListGrid();
         grid.setLeaveScrollbarGap(false);
 
         return grid;
     }
 
-
-    protected ListGrid createNewGrid() {
-        return new ListGrid();
-    }
-
-
     /**
      * A method that removes all records from theme grid.
      */
     protected void clearGrid() {
-        ListGridRecord[] records = list.getRecords();
+        final ListGridRecord[] records = this.list.getRecords();
 
         if (records == null || records.length == 0) {
             return;
         }
 
-        for (ListGridRecord record: records) {
-            list.removeData(record);
+        for (final ListGridRecord record : records) {
+            this.list.removeData(record);
         }
     }
 
     /** Return 'separator'- menu-item. */
     protected MenuItem createSeparator() {
-        MenuItem separator = new MenuItem();
+        final MenuItem separator = new MenuItem();
         separator.setIsSeparator(true);
         return separator;
     }
 
-
     /**
      * Get the context menu for a (right mouse button)click on a single item.
      */
     protected Menu getSingleContextMenu(final ListGridRecord[] records) {
-        Menu menu = new Menu();
+        final Menu menu = new Menu();
 
         menu.addItem(createActivateItem(records));
         menu.addItem(createDeactivateItem(records));
@@ -384,9 +360,8 @@
         return menu;
     }
 
-
     protected Menu getMultiContextMenu(final ListGridRecord[] records) {
-        Menu menu = new Menu();
+        final Menu menu = new Menu();
 
         menu.addItem(createActivateItem(records));
         menu.addItem(createDeactivateItem(records));
@@ -395,16 +370,15 @@
         return menu;
     }
 
-
     /** The properties menu item (opens style editor on click). */
     protected MenuItem createPropertiesItem(final ListGridRecord[] records) {
-        MenuItem properties = new MenuItem(MSG.properties());
+        final MenuItem properties = new MenuItem(this.MSG.properties());
 
         properties.addClickHandler(new ClickHandler() {
             @Override
-            public void onClick(MenuItemClickEvent evt) {
+            public void onClick(final MenuItemClickEvent evt) {
                 GWT.log("clicked properties");
-                for (ListGridRecord record: records) {
+                for (final ListGridRecord record : records) {
                     openStyleEditor((FacetRecord) record);
                 }
             }
@@ -413,15 +387,14 @@
         return properties;
     }
 
-
     protected MenuItem createActivateItem(final ListGridRecord[] records) {
-        MenuItem activate = new MenuItem(MSG.activateTheme());
+        final MenuItem activate = new MenuItem(this.MSG.activateTheme());
 
         activate.addClickHandler(new ClickHandler() {
             @Override
-            public void onClick(MenuItemClickEvent evt) {
-                for (ListGridRecord record: records) {
-                    FacetRecord facet = (FacetRecord) record;
+            public void onClick(final MenuItemClickEvent evt) {
+                for (final ListGridRecord record : records) {
+                    final FacetRecord facet = (FacetRecord) record;
                     activateTheme(facet.getTheme(), true);
                 }
 
@@ -432,15 +405,14 @@
         return activate;
     }
 
-
     protected MenuItem createDeactivateItem(final ListGridRecord[] records) {
-        MenuItem deactivate = new MenuItem(MSG.deactivateTheme());
+        final MenuItem deactivate = new MenuItem(this.MSG.deactivateTheme());
 
         deactivate.addClickHandler(new ClickHandler() {
             @Override
-            public void onClick(MenuItemClickEvent evt) {
-                for (ListGridRecord record: records) {
-                    FacetRecord facet = (FacetRecord) record;
+            public void onClick(final MenuItemClickEvent evt) {
+                for (final ListGridRecord record : records) {
+                    final FacetRecord facet = (FacetRecord) record;
                     activateTheme(facet.getTheme(), false);
                 }
 
@@ -451,29 +423,27 @@
         return deactivate;
     }
 
-
     /** Remove given themes (not asking for confirmation). */
     protected void removeThemes(final ListGridRecord[] records) {
-        for (ListGridRecord record: records) {
-            FacetRecord facet = (FacetRecord) record;
-            Theme theme = facet.getTheme();
+        for (final ListGridRecord record : records) {
+            final FacetRecord facet = (FacetRecord) record;
+            final Theme theme = facet.getTheme();
             theme.setVisible(0);
             theme.setActive(0);
             updateCollection();
         }
     }
 
-
     /** Create menu item for removing theme(s). Will ask for confirmation. */
     protected MenuItem createRemoveItem(final ListGridRecord[] records) {
-        MenuItem remove = new MenuItem(MSG.removeTheme());
+        final MenuItem remove = new MenuItem(this.MSG.removeTheme());
 
         remove.addClickHandler(new ClickHandler() {
             @Override
-            public void onClick(MenuItemClickEvent evt) {
-                SC.ask(MSG.askThemeRemove(), new BooleanCallback() {
+            public void onClick(final MenuItemClickEvent evt) {
+                SC.ask(ThemePanel.this.MSG.askThemeRemove(), new BooleanCallback() {
                     @Override
-                    public void execute(Boolean value) {
+                    public void execute(final Boolean value) {
                         if (value) {
                             removeThemes(records);
                         }
@@ -485,20 +455,20 @@
         return remove;
     }
 
-
     /**
      * This method is called after a cell in the theme grid has been modified.
      *
-     * @param event The event that stores information about the modified record.
+     * @param event
+     *            The event that stores information about the modified record.
      */
     @Override
-    public void onEditComplete(EditCompleteEvent event) {
+    public void onEditComplete(final EditCompleteEvent event) {
         GWT.log("Edited record.");
 
-        int         row = event.getRowNum();
-        FacetRecord rec = (FacetRecord) list.getRecord(row);
+        final int row = event.getRowNum();
+        final FacetRecord rec = (FacetRecord) this.list.getRecord(row);
 
-        Theme theme = rec.getTheme();
+        final Theme theme = rec.getTheme();
 
         theme.setDescription(rec.getName());
         activateTheme(theme, rec.getActive());
@@ -506,27 +476,28 @@
         updateCollection();
     }
 
-
     /**
      * This method should be defined in subclasses that wants to listen to this
      * event.
      *
-     * @param theme The theme that is moved.
-     * @param oldIdx The index of the theme before it was moved.
-     * @param newIdx The index of the theme after it was moved.
+     * @param theme
+     *            The theme that is moved.
+     * @param oldIdx
+     *            The index of the theme before it was moved.
+     * @param newIdx
+     *            The index of the theme after it was moved.
      */
-    protected void fireThemeMoved(Theme theme, int oldIdx, int newIdx) {
+    protected void fireThemeMoved(final Theme theme, final int oldIdx, final int newIdx) {
         // Do nothing
     }
 
-
     @Override
-    public void onMove(OnMoveEvent event) {
-        int type = event.getType();
+    public void onMove(final OnMoveEvent event) {
+        final int type = event.getType();
 
         GWT.log("ThemePanel.onMove: " + type);
 
-        ListGridRecord[] records = list.getSelectedRecords();
+        final ListGridRecord[] records = this.list.getSelectedRecords();
 
         if (records == null || records.length == 0) {
             GWT.log("ThemePanel.onMove: No records selected.");
@@ -534,28 +505,36 @@
         }
 
         switch (type) {
-            case 0: moveRecordsTop(records); break;
-            case 1: moveRecordsUp(records); break;
-            case 2: moveRecordsDown(records); break;
-            case 3: moveRecordsBottom(records); break;
+        case 0:
+            moveRecordsTop(records);
+            break;
+        case 1:
+            moveRecordsUp(records);
+            break;
+        case 2:
+            moveRecordsDown(records);
+            break;
+        case 3:
+            moveRecordsBottom(records);
+            break;
         }
 
         updateCollection();
     }
 
-
     /**
      * Moves the selected grid records (themes) to the top of the grid.
      *
-     * @param records The selected themes in the list. Null not permitted.
+     * @param records
+     *            The selected themes in the list. Null not permitted.
      */
-    protected void moveRecordsTop(ListGridRecord[] records) {
-        ThemeList themeList = getThemeList();
+    protected void moveRecordsTop(final ListGridRecord[] records) {
+        final ThemeList themeList = getThemeList();
 
         int idx = 1;
 
-        for (ListGridRecord record: records) {
-            Theme theme = ((FacetRecord) record).getTheme();
+        for (final ListGridRecord record : records) {
+            final Theme theme = ((FacetRecord) record).getTheme();
             fireThemeMoved(theme, theme.getPosition(), idx);
             themeList.setThemePosition(theme, idx++);
         }
@@ -563,24 +542,24 @@
         updateGrid();
     }
 
-
     /**
      * Moves the selected grid records (themes) one step up.
      *
-     * @param records The selected themes in the list. Null not permitted.
+     * @param records
+     *            The selected themes in the list. Null not permitted.
      */
-    protected void moveRecordsUp(ListGridRecord[] records) {
-        ThemeList themeList = getThemeList();
+    protected void moveRecordsUp(final ListGridRecord[] records) {
+        final ThemeList themeList = getThemeList();
 
-        int[] newPos = new int[records.length];
+        final int[] newPos = new int[records.length];
 
-        for (int i = 0; i < records.length ; i++) {
-            Theme theme = ((FacetRecord) records[i]).getTheme();
-            newPos[i]   = theme.getPosition() - 1;
+        for (int i = 0; i < records.length; i++) {
+            final Theme theme = ((FacetRecord) records[i]).getTheme();
+            newPos[i] = theme.getPosition() - 1;
         }
 
-        for (int i = 0; i < records.length ; i++) {
-            Theme theme = ((FacetRecord) records[i]).getTheme();
+        for (int i = 0; i < records.length; i++) {
+            final Theme theme = ((FacetRecord) records[i]).getTheme();
             fireThemeMoved(theme, theme.getPosition(), newPos[i]);
             themeList.setThemePosition(theme, newPos[i]);
         }
@@ -588,24 +567,24 @@
         updateGrid();
     }
 
-
     /**
      * Moves the selected grid records (themes) one step down.
      *
-     * @param records The selected themes in the list. Null not permitted.
+     * @param records
+     *            The selected themes in the list. Null not permitted.
      */
-    protected void moveRecordsDown(ListGridRecord[] records) {
-        ThemeList themeList = getThemeList();
+    protected void moveRecordsDown(final ListGridRecord[] records) {
+        final ThemeList themeList = getThemeList();
 
-        int[] newPos = new int[records.length];
+        final int[] newPos = new int[records.length];
 
-        for (int i = records.length-1; i >= 0; i--) {
-            Theme theme = ((FacetRecord) records[i]).getTheme();
-            newPos[i] = theme.getPosition()+1;
+        for (int i = records.length - 1; i >= 0; i--) {
+            final Theme theme = ((FacetRecord) records[i]).getTheme();
+            newPos[i] = theme.getPosition() + 1;
         }
 
-        for (int i = records.length-1; i >= 0; i--) {
-            Theme theme = ((FacetRecord) records[i]).getTheme();
+        for (int i = records.length - 1; i >= 0; i--) {
+            final Theme theme = ((FacetRecord) records[i]).getTheme();
             fireThemeMoved(theme, theme.getPosition(), newPos[i]);
             themeList.setThemePosition(theme, newPos[i]);
         }
@@ -613,19 +592,19 @@
         updateGrid();
     }
 
-
     /**
      * Moves the selected grid records (themes) to the bottom of the grid.
      *
-     * @param records The selected themes in the list. Null not permitted.
+     * @param records
+     *            The selected themes in the list. Null not permitted.
      */
-    protected void moveRecordsBottom(ListGridRecord[] records) {
-        ThemeList themeList = getThemeList();
+    protected void moveRecordsBottom(final ListGridRecord[] records) {
+        final ThemeList themeList = getThemeList();
 
         int idx = themeList.getThemeCount();
 
-        for (int i = records.length-1; i >= 0; i--) {
-            Theme theme = ((FacetRecord) records[i]).getTheme();
+        for (int i = records.length - 1; i >= 0; i--) {
+            final Theme theme = ((FacetRecord) records[i]).getTheme();
             fireThemeMoved(theme, theme.getPosition(), idx);
             themeList.setThemePosition(theme, idx--);
         }
@@ -633,48 +612,47 @@
         updateGrid();
     }
 
+    protected void openStyleEditor(final FacetRecord record) {
+        final Config config = Config.getInstance();
+        final String locale = config.getLocale();
 
-    protected void openStyleEditor(final FacetRecord record) {
-        Config config = Config.getInstance();
-        String locale = config.getLocale();
+        final String artifact = record.getTheme().getArtifact();
 
-        String artifact = record.getTheme().getArtifact();
+        this.itemAttributeService.getCollectionItemAttribute(this.getCollection(), artifact, locale, new AsyncCallback<CollectionItemAttribute>() {
+            @Override
+            public void onFailure(final Throwable caught) {
+                SC.warn(ThemePanel.this.MSG.getString(caught.getMessage()));
+            }
 
-        itemAttributeService.getCollectionItemAttribute(
-            this.getCollection(),
-            artifact,
-            locale,
-            new AsyncCallback<CollectionItemAttribute>() {
-                @Override
-                public void onFailure (Throwable caught) {
-                    SC.warn(MSG.getString(caught.getMessage()));
-                }
-                @Override
-                public void onSuccess(CollectionItemAttribute cia) {
-                    GWT.log("Successfully loaded collectionitem attributes.");
-                    showStyleEditor(cia, record);
-                }
-            });
+            @Override
+            public void onSuccess(final CollectionItemAttribute cia) {
+                GWT.log("Successfully loaded collectionitem attributes.");
+                showStyleEditor(cia, record);
+            }
+        });
     }
 
-
-    protected void showStyleEditor(
-        CollectionItemAttribute cia,
-        FacetRecord record)
-    {
-        StyleEditorWindow win = new StyleEditorWindow(
-            getCollection(),
-            cia,
-            record);
+    protected void showStyleEditor(final CollectionItemAttribute cia, final FacetRecord record) {
+        final StyleEditorWindow win = new StyleEditorWindow(getCollection(), cia, record);
         win.setThemePanel(this);
         win.centerInPage();
         win.show();
     }
 
-
     /** Get OutputMode of this Panel. */
     public OutputMode getMode() {
         return this.mode;
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+
+    public void updateThemes() {
+
+        final ListGridRecord[] records = this.list.getRecords();
+        for (final ListGridRecord record : records) {
+            final FacetRecord facetRecord = (FacetRecord) record;
+
+            this.recordHandler.handle(facetRecord);
+        }
+
+        this.list.markForRedraw();
+    }
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartOutputTab.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartOutputTab.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartOutputTab.java	Thu Aug 16 16:28:03 2018 +0200
@@ -31,6 +31,8 @@
 import org.dive4elements.river.client.client.services.ChartInfoService;
 import org.dive4elements.river.client.client.services.ChartInfoServiceAsync;
 import org.dive4elements.river.client.client.ui.CollectionView;
+import org.dive4elements.river.client.client.ui.IThemeRecordHandler;
+import org.dive4elements.river.client.client.ui.NoopThemeRecordHandler;
 import org.dive4elements.river.client.client.ui.OutputTab;
 import org.dive4elements.river.client.shared.Transform2D;
 import org.dive4elements.river.client.shared.model.Axis;
@@ -74,9 +76,6 @@
      * coordinates. */
     protected Transform2D[] transformer;
 
-    /** The collection view.*/
-    protected CollectionView view;
-
     /** The ThemePanel to expose control over themes (facettes). */
     protected ChartThemePanel ctp;
 
@@ -107,16 +106,17 @@
      * @param collection The Collection which this chart belongs to.
      * @param mode The OutputMode.
      * @param collectionView The shown collection.
+     * @param recordHandler 
      */
     public ChartOutputTab(
         String         title,
         Collection     collection,
         OutputMode     mode,
-        CollectionView collectionView
+        CollectionView collectionView, 
+        IThemeRecordHandler recordHandler
     ){
         super(title, collection, collectionView, mode);
 
-        view      = collectionView;
         left      = new Canvas();
         right     = new Canvas();
         xrange    = new int[2];
@@ -143,7 +143,7 @@
         hLayout.addMember(left);
         hLayout.addMember(right);
 
-        ctp = createThemePanel(mode, collectionView);
+        ctp = createThemePanel(mode, collectionView, recordHandler);
         if (ctp != null) {
             ctp.addRedrawRequestHandler(this);
             ctp.addOutputParameterChangeHandler(this);
@@ -170,17 +170,13 @@
     }
 
 
-    public ChartThemePanel createThemePanel(
-        OutputMode mode, CollectionView view
-    ) {
+    public ChartThemePanel createThemePanel( OutputMode mode, CollectionView view, IThemeRecordHandler recordHandler ) {
         // Output "cross_section" needs slightly modified ThemePanel
         // (with action buttons).
-        if (mode.getName().equals("cross_section")) {
-            return new CrossSectionChartThemePanel(mode, view);
-        }
-        else {
-            return new ChartThemePanel(mode, view);
-        }
+        if (mode.getName().equals("cross_section"))
+            return new CrossSectionChartThemePanel(mode, view, recordHandler);
+
+        return new ChartThemePanel(mode, view, recordHandler);
     }
 
 
@@ -482,7 +478,7 @@
         String locale = config.getLocale();
 
         info.getChartInfo(
-            view.getCollection(),
+            getCollectionView().getCollection(),
             locale,
             mode.getName(),
             getChartAttributes(),
@@ -506,8 +502,11 @@
 
         chart.setSrc(getImgUrl(w, h));
     }
-
-
+    
+    protected final void updateThemePanel() {
+        ctp.updateThemes();
+    }
+    
     /**
      * Returns the existing chart panel.
      *
@@ -709,13 +708,6 @@
         return zoom;
     }
 
-
-    /** Return the 'parent' CollectionView. */
-    public CollectionView getView() {
-        return this.view;
-    }
-
-
     public static Number subtract(Number left, Number right) {
         if (left instanceof Double) {
             return new Double(left.doubleValue() - right.doubleValue());
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartThemePanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartThemePanel.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartThemePanel.java	Thu Aug 16 16:28:03 2018 +0200
@@ -8,25 +8,12 @@
 
 package org.dive4elements.river.client.client.ui.chart;
 
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-import com.smartgwt.client.types.ListGridFieldType;
-import com.smartgwt.client.util.SC;
-import com.smartgwt.client.widgets.grid.ListGridField;
-import com.smartgwt.client.widgets.grid.ListGridRecord;
-import com.smartgwt.client.widgets.layout.VLayout;
-import com.smartgwt.client.widgets.menu.Menu;
-import com.smartgwt.client.widgets.menu.MenuItem;
-import com.smartgwt.client.widgets.menu.events.ClickHandler;
-import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
-
 import org.dive4elements.river.client.client.Config;
-import org.dive4elements.river.client.client.FLYSConstants;
 import org.dive4elements.river.client.client.services.FeedServiceAsync;
 import org.dive4elements.river.client.client.services.LoadArtifactService;
 import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
 import org.dive4elements.river.client.client.ui.CollectionView;
+import org.dive4elements.river.client.client.ui.IThemeRecordHandler;
 import org.dive4elements.river.client.client.ui.ThemePanel;
 import org.dive4elements.river.client.shared.model.Artifact;
 import org.dive4elements.river.client.shared.model.Data;
@@ -38,6 +25,18 @@
 import org.dive4elements.river.client.shared.model.Theme;
 import org.dive4elements.river.client.shared.model.ThemeList;
 
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.menu.Menu;
+import com.smartgwt.client.widgets.menu.MenuItem;
+import com.smartgwt.client.widgets.menu.events.ClickHandler;
+import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
 
 /**
  * ThemePanel on the left in CollectionView.
@@ -48,348 +47,272 @@
  */
 public class ChartThemePanel extends ThemePanel {
     /** Artifact Clone/Creation service. */
-    protected LoadArtifactServiceAsync loadService =
-                GWT.create(LoadArtifactService.class);
+    private final LoadArtifactServiceAsync loadService = GWT.create(LoadArtifactService.class);
 
-    /** The interface that provides i18n messages. */
-    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
+    protected static final String GRID_FIELD_ACTIVE = "active";
+    protected static final String GRID_FIELD_NAME = "name";
+    protected static final String GRID_FIELD_ACTIONS = "actions";
 
-    public static final String GRID_FIELD_ACTIVE  = "active";
-    public static final String GRID_FIELD_NAME    = "name";
-    public static final String GRID_FIELD_ACTIONS = "actions";
+    protected final FeedServiceAsync feedService = GWT.create(org.dive4elements.river.client.client.services.FeedService.class);
 
-    FeedServiceAsync feedService = GWT.create(
-        org.dive4elements.river.client.client.services.FeedService.class);
+    /** Constructor for a ChartThemePanel.
+     * @param recordHandler */
+    public ChartThemePanel(final OutputMode mode, final CollectionView view, final IThemeRecordHandler recordHandler) {
+        super(mode, view, recordHandler);
 
-
-    /** Constructor for a ChartThemePanel. */
-    public ChartThemePanel(
-        OutputMode mode,
-        CollectionView view
-    ) {
-        super(mode, view);
-
-        initGrid();
+        initGrid(recordHandler);
         initLayout();
 
         updateGrid();
     }
 
-
     /** Creates Layout with theme list and navigation bar inside. */
     protected VLayout createLayout() {
-        VLayout layout = new VLayout();
+        final VLayout layout = new VLayout();
         layout.setWidth100();
         layout.setHeight100();
 
-        layout.addMember(list);
-        layout.addMember(navigation);
+        layout.addMember(this.list);
+        layout.addMember(this.navigation);
 
         return layout;
     }
 
-
     /**
      * Initializes the layout of this panel.
      */
-    protected void initLayout() {
+    private void initLayout() {
         setWidth100();
         setHeight100();
 
         addChild(createLayout());
     }
 
-
     /**
      * Initializes the components (columns) of the theme grid.
+     * @param recordHandler
      */
-    protected void initGrid() {
-        list.setCanEdit(true);
-        list.setCanSort(false);
-        list.setShowRecordComponents(false);
-        list.setShowRecordComponentsByCell(true);
-        list.setShowHeader(true);
-        list.setShowHeaderContextMenu(false);
-        list.setWidth100();
-        list.setHeight100();
+    protected void initGrid( final IThemeRecordHandler recordHandler ) {
+        this.list.setCanEdit(true);
+        this.list.setCanSort(false);
+        this.list.setShowRecordComponents(false);
+        this.list.setShowRecordComponentsByCell(true);
+        this.list.setShowHeader(true);
+        this.list.setShowHeaderContextMenu(false);
+        this.list.setWidth100();
+        this.list.setHeight100();
 
-        list.addEditCompleteHandler(this);
+        this.list.addEditCompleteHandler(this);
 
-        ListGridField active = new ListGridField(GRID_FIELD_ACTIVE, " ", 20);
+        final ListGridField active = new ListGridField(GRID_FIELD_ACTIVE, " ", 20);
         active.setType(ListGridFieldType.BOOLEAN);
 
-        ListGridField name = new ListGridField(
-            GRID_FIELD_NAME, MSG.chart_themepanel_header_themes());
+        final ListGridField name = new ListGridField(GRID_FIELD_NAME, this.MSG.chart_themepanel_header_themes());
         name.setType(ListGridFieldType.TEXT);
 
-        list.setFields(active, name);
+        if( recordHandler instanceof CellFormatter)
+            name.setCellFormatter((CellFormatter) recordHandler);
+
+        this.list.setFields(active, name);
     }
 
-
     /** Set theme active/inactive. */
     @Override
-    public void activateTheme(Theme theme, boolean active) {
+    public void activateTheme(final Theme theme, final boolean active) {
         theme.setActive(active ? 1 : 0);
     }
 
-
     /** Returns name of longitudinal section area facets. */
     protected String getAreaFacetName() {
         return "longitudinal_section.area";
     }
 
-
     /** Create the DataProvider ('Blackboard') key for a theme. */
-    public static String areaKey(Theme theme) {
-        return theme.getArtifact() + ":" + theme.getFacet() + ":"
-            + theme.getIndex();
+    public static String areaKey(final Theme theme) {
+        return theme.getArtifact() + ":" + theme.getFacet() + ":" + theme.getIndex();
     }
 
-
     /**
      * Tell an area artifact where to get the upper and lower curve from.
-     * @param artifact UUID of area-artifact.
+     *
+     * @param artifact
+     *            UUID of area-artifact.
      */
-    public void feedTellArea(
-        final String artifact,
-        Theme under,
-        Theme over,
-        boolean between
-    ) {
+    public void feedTellArea(final String artifact, final Theme under, final Theme over, final boolean between) {
         Data[] feedData;
 
         if (over != null && under != null) {
-            feedData = new Data[] {
-                DefaultData.createSimpleStringData("area.curve_under",
-                    areaKey(under)),
-                DefaultData.createSimpleStringData("area.curve_over",
-                    areaKey(over)),
-                DefaultData.createSimpleStringData("area.name",
-                    over.getDescription() + " / " + under.getDescription()),
-                DefaultData.createSimpleStringData("area.facet",
-                    getAreaFacetName()),
-                DefaultData.createSimpleStringData("area.between",
-                    (between)? "true" : "false")
-            };
+            feedData = new Data[] { DefaultData.createSimpleStringData("area.curve_under", areaKey(under)),
+                    DefaultData.createSimpleStringData("area.curve_over", areaKey(over)),
+                    DefaultData.createSimpleStringData("area.name", over.getDescription() + " / " + under.getDescription()),
+                    DefaultData.createSimpleStringData("area.facet", getAreaFacetName()),
+                    DefaultData.createSimpleStringData("area.between", (between) ? "true" : "false") };
             GWT.log("Have 'over' and 'under' curve");
-        }
-        else if (over == null && under != null) {
-            feedData = new Data[] {
-                DefaultData.createSimpleStringData("area.curve_under",
-                    areaKey(under)),
-                DefaultData.createSimpleStringData("area.name",
-                    under.getDescription() + " / " + MSG.getString("x_axis")),
-                DefaultData.createSimpleStringData("area.facet",
-                    getAreaFacetName()),
-                DefaultData.createSimpleStringData("area.between",
-                    (between)? "true" : "false")
-            };
+        } else if (over == null && under != null) {
+            feedData = new Data[] { DefaultData.createSimpleStringData("area.curve_under", areaKey(under)),
+                    DefaultData.createSimpleStringData("area.name", under.getDescription() + " / " + this.MSG.getString("x_axis")),
+                    DefaultData.createSimpleStringData("area.facet", getAreaFacetName()),
+                    DefaultData.createSimpleStringData("area.between", (between) ? "true" : "false") };
             GWT.log("Have 'under' curve only");
-        }
-        else if (over != null && under == null) {
-            feedData = new Data[] {
-                DefaultData.createSimpleStringData("area.curve_over",
-                    areaKey(over)),
-                DefaultData.createSimpleStringData("area.name",
-                    MSG.getString("x_axis") + " / " + over.getDescription()),
-                DefaultData.createSimpleStringData("area.facet",
-                    getAreaFacetName()),
-                DefaultData.createSimpleStringData("area.between",
-                    (between)? "true" : "false")
-            };
+        } else if (over != null && under == null) {
+            feedData = new Data[] { DefaultData.createSimpleStringData("area.curve_over", areaKey(over)),
+                    DefaultData.createSimpleStringData("area.name", this.MSG.getString("x_axis") + " / " + over.getDescription()),
+                    DefaultData.createSimpleStringData("area.facet", getAreaFacetName()),
+                    DefaultData.createSimpleStringData("area.between", (between) ? "true" : "false") };
             GWT.log("Have 'over' curve only");
-        }
-        else {
+        } else {
             GWT.log("Missing Data for area painting.");
             return;
         }
 
-        feedService.feed(
-            Config.getInstance().getLocale(),
-            new DefaultArtifact(artifact, "TODO:hash"),
-            feedData,
-            new AsyncCallback<Artifact>() {
-                @Override
-                public void onFailure(Throwable caught) {
-                    GWT.log("Could not feed artifact (" + artifact
-                            + ") with area info: " + caught.getMessage());
-                    SC.warn(MSG.getString(caught.getMessage()));
-                    enable();
-                }
-                @Override
-                public void onSuccess(Artifact fartifact) {
-                    GWT.log("Successfully set area params to " + artifact);
-                    requestRedraw();
-                    updateCollection();
-                    updateGrid();
-                    enable();
-                }
-            });
+        this.feedService.feed(Config.getInstance().getLocale(), new DefaultArtifact(artifact, "TODO:hash"), feedData, new AsyncCallback<Artifact>() {
+            @Override
+            public void onFailure(final Throwable caught) {
+                GWT.log("Could not feed artifact (" + artifact + ") with area info: " + caught.getMessage());
+                SC.warn(ChartThemePanel.this.MSG.getString(caught.getMessage()));
+                enable();
+            }
+
+            @Override
+            public void onSuccess(final Artifact fartifact) {
+                GWT.log("Successfully set area params to " + artifact);
+                requestRedraw();
+                updateCollection();
+                updateGrid();
+                enable();
+            }
+        });
     }
 
-
     /**
      * Create and parameterize a new area artifact.
+     *
      * @param under
-     * @param over if null, against axis.
-     * @param between if true, ignore under/over order.
+     * @param over
+     *            if null, against axis.
+     * @param between
+     *            if true, ignore under/over order.
      */
-    public void createAreaArtifact(
-        final Theme   over,
-        final Theme   under,
-        final boolean between
-    ) {
-        Config config = Config.getInstance();
-        String locale = config.getLocale();
+    public void createAreaArtifact(final Theme over, final Theme under, final boolean between) {
+        final Config config = Config.getInstance();
+        final String locale = config.getLocale();
 
-        Recommendation area = new Recommendation(
-            "area",
-            "",
-            "",
-            null);
+        final Recommendation area = new Recommendation("area", "", "", null);
 
         // Set target out dynamically.
         area.setTargetOut(getMode().getName());
 
-        Recommendation[] recommendations = new Recommendation[] {area};
+        final Recommendation[] recommendations = new Recommendation[] { area };
 
-        loadService.loadMany(
-            this.getCollection(),
-            recommendations,
-            null, //use individual factories.
-            locale,
-            new AsyncCallback<Artifact[]>() {
-                @Override
-                public void onFailure(Throwable caught) {
-                    GWT.log("Failed, no area artifact: " + caught.getMessage());
-                    enable();
-                    // TODO i18n
-                    SC.warn("Failed, no area artifact: " + caught.getMessage());
-                }
-                @Override
-                public void onSuccess(Artifact[] artifacts) {
-                    GWT.log("Success, created area artifact: "
-                        + artifacts[0].getUuid());
-                    // Now, feed the artifact with the relevant data.
-                    feedTellArea(artifacts[0].getUuid(), under, over, between);
-                }
-            }
-        );
+        this.loadService.loadMany(this.getCollection(), recommendations, null, // use individual factories.
+                locale, new AsyncCallback<Artifact[]>() {
+                    @Override
+                    public void onFailure(final Throwable caught) {
+                        GWT.log("Failed, no area artifact: " + caught.getMessage());
+                        enable();
+                        // TODO i18n
+                        SC.warn("Failed, no area artifact: " + caught.getMessage());
+                    }
+
+                    @Override
+                    public void onSuccess(final Artifact[] artifacts) {
+                        GWT.log("Success, created area artifact: " + artifacts[0].getUuid());
+                        // Now, feed the artifact with the relevant data.
+                        feedTellArea(artifacts[0].getUuid(), under, over, between);
+                    }
+                });
     }
 
-
     /**
      * Return true if two themes are canditates for an area being
      * rendered between them.
      * TODO join with canArea, generalize to allow easier modification
-     *      in subclasses.
+     * in subclasses.
      */
-    protected boolean areAreaCompatible(Theme a, Theme b) {
+    protected boolean areAreaCompatible(final Theme a, final Theme b) {
         if (a.equals(b)) {
             return false;
         }
-        if (a.getFacet().equals("w_differences") &&
-            b.getFacet().equals("w_differences")) {
+        if (a.getFacet().equals("w_differences") && b.getFacet().equals("w_differences")) {
             return true;
         }
-        if (a.getFacet().equals("longitudinal_section.w") ||
-            a.getFacet().equals("other.wqkms.w") ||
-            a.getFacet().equals("other.wqkms") ||
-            a.getFacet().equals("discharge_longitudinal_section.w") ||
-            a.getFacet().equals("discharge_longitudinal_section.c") ||
-            a.getFacet().equals("other.wkms")) {
-            return b.getFacet().equals("longitudinal_section.w")
-                || b.getFacet().equals("other.wqkms")
-                || b.getFacet().equals("other.wqkms.w")
-                || b.getFacet().equals("discharge_longitudinal_section.w")
-                || b.getFacet().equals("discharge_longitudinal_section.c")
-                || b.getFacet().equals("other.wkms");
-        }
-        else if (a.getFacet().equals("longitudinal_section.q") ||
-                 a.getFacet().equals("discharge_longitudinal_section.q") ||
-                 a.getFacet().equals("other.wqkms.q")) {
-            return b.getFacet().equals("longitudinal_section.q")
-                    || b.getFacet().equals("discharge_longitudinal_section.q")
+        if (a.getFacet().equals("longitudinal_section.w") || a.getFacet().equals("other.wqkms.w") || a.getFacet().equals("other.wqkms")
+                || a.getFacet().equals("discharge_longitudinal_section.w") || a.getFacet().equals("discharge_longitudinal_section.c")
+                || a.getFacet().equals("other.wkms")) {
+            return b.getFacet().equals("longitudinal_section.w") || b.getFacet().equals("other.wqkms") || b.getFacet().equals("other.wqkms.w")
+                    || b.getFacet().equals("discharge_longitudinal_section.w") || b.getFacet().equals("discharge_longitudinal_section.c")
+                    || b.getFacet().equals("other.wkms");
+        } else if (a.getFacet().equals("longitudinal_section.q") || a.getFacet().equals("discharge_longitudinal_section.q")
+                || a.getFacet().equals("other.wqkms.q")) {
+            return b.getFacet().equals("longitudinal_section.q") || b.getFacet().equals("discharge_longitudinal_section.q")
                     || b.getFacet().equals("other.wqkms.q");
         }
         return false;
     }
 
-
     /**
      * True if context menu should contain 'create area' submenu on
      * this theme.
      */
-    protected boolean canArea(Theme a) {
-        return a.getFacet().equals("longitudinal_section.q")
-            || a.getFacet().equals("longitudinal_section.w")
-            || a.getFacet().equals("discharge_longitudinal_section.w")
-            || a.getFacet().equals("discharge_longitudinal_section.q")
-            || a.getFacet().equals("discharge_longitudinal_section.c")
-            || a.getFacet().startsWith("other.wqkms")
-            || a.getFacet().equals("other.wkms")
-            || a.getFacet().equals("w_differences");
+    protected boolean canArea(final Theme a) {
+        return a.getFacet().equals("longitudinal_section.q") || a.getFacet().equals("longitudinal_section.w")
+                || a.getFacet().equals("discharge_longitudinal_section.w") || a.getFacet().equals("discharge_longitudinal_section.q")
+                || a.getFacet().equals("discharge_longitudinal_section.c") || a.getFacet().startsWith("other.wqkms") || a.getFacet().equals("other.wkms")
+                || a.getFacet().equals("w_differences");
     }
 
-
     /** Attach menu/item to open editor for Manual Points. */
-    protected void attachManualPointsMenu(Menu menu) {
+    protected void attachManualPointsMenu(final Menu menu) {
         menu.addItem(createSeparator());
-        MenuItem editManualPoints = new MenuItem(MSG.editpoints());
+        final MenuItem editManualPoints = new MenuItem(this.MSG.editpoints());
 
         editManualPoints.addClickHandler(new ClickHandler() {
-                @Override
-                public void onClick(MenuItemClickEvent evt) {
-                    if(mode.getName().equals("historical_discharge")) {
-                        new ManualDatePointsEditor(view.getCollection(),
-                            redrawRequestHandlers.get(0),
-                            mode.getName()).show();
-                    }
-                    else {
-                        new ManualPointsEditor(view.getCollection(),
-                            redrawRequestHandlers.get(0),
-                            mode.getName()).show();
-                    }
+            @Override
+            public void onClick(final MenuItemClickEvent evt) {
+                if (ChartThemePanel.this.mode.getName().equals("historical_discharge")) {
+                    new ManualDatePointsEditor(ChartThemePanel.this.view.getCollection(), ChartThemePanel.this.redrawRequestHandlers.get(0),
+                            ChartThemePanel.this.mode.getName()).show();
+                } else {
+                    new ManualPointsEditor(ChartThemePanel.this.view.getCollection(), ChartThemePanel.this.redrawRequestHandlers.get(0),
+                            ChartThemePanel.this.mode.getName()).show();
                 }
-            });
+            }
+        });
         menu.addItem(editManualPoints);
     }
 
-
     /**
      * Include area specific menu items and manual point editor, depending
      * on facet.
      */
     @Override
     protected Menu getSingleContextMenu(final ListGridRecord[] records) {
-        Menu menu = super.getSingleContextMenu(records);
+        final Menu menu = super.getSingleContextMenu(records);
 
-        final Theme facetTheme = ((FacetRecord)records[0]).getTheme();
+        final Theme facetTheme = ((FacetRecord) records[0]).getTheme();
 
         if (!canArea(facetTheme)) {
             if (facetTheme.getFacet().endsWith("manualpoints")) {
                 attachManualPointsMenu(menu);
                 return menu;
-            }
-            else {
+            } else {
                 return menu;
             }
         }
 
         menu.addItem(createSeparator());
 
-        MenuItem areaMenuItem = new MenuItem(MSG.chart_themepanel_new_area());
-        Menu areaMenu         = new Menu();
+        final MenuItem areaMenuItem = new MenuItem(this.MSG.chart_themepanel_new_area());
+        final Menu areaMenu = new Menu();
 
-        ThemeList themes = getThemeList();
-        int nThemes      = themes.getThemeCount();
+        final ThemeList themes = getThemeList();
+        final int nThemes = themes.getThemeCount();
 
         // Create the "under..." submenu.
-        MenuItem underMenuItem = new MenuItem(
-            MSG.chart_themepanel_area_under());
-        Menu underMenu = new Menu();
-        for (int i = 0; i < nThemes; i++)  {
-            final Theme theme = themes.getThemeAt(i+1);
+        final MenuItem underMenuItem = new MenuItem(this.MSG.chart_themepanel_area_under());
+        final Menu underMenu = new Menu();
+        for (int i = 0; i < nThemes; i++) {
+            final Theme theme = themes.getThemeAt(i + 1);
 
             if (theme.getVisible() == 0) {
                 continue;
@@ -399,12 +322,12 @@
                 continue;
             }
 
-            MenuItem againster = new MenuItem(theme.getDescription());
+            final MenuItem againster = new MenuItem(theme.getDescription());
             underMenu.addItem(againster);
 
             againster.addClickHandler(new ClickHandler() {
                 @Override
-                public void onClick(MenuItemClickEvent evt) {
+                public void onClick(final MenuItemClickEvent evt) {
                     disable();
                     createAreaArtifact(theme, facetTheme, false);
                 }
@@ -412,32 +335,32 @@
         }
 
         // Create the "over..." submenu.
-        MenuItem overMenuItem = new MenuItem(MSG.chart_themepanel_area_over());
-        Menu overMenu = new Menu();
-        for (int i = 0; i < nThemes; i++)  {
-            final Theme theme = themes.getThemeAt(i+1);
+        final MenuItem overMenuItem = new MenuItem(this.MSG.chart_themepanel_area_over());
+        final Menu overMenu = new Menu();
+        for (int i = 0; i < nThemes; i++) {
+            final Theme theme = themes.getThemeAt(i + 1);
             if (theme.getVisible() == 0) {
                 continue;
             }
             if (!areAreaCompatible(facetTheme, theme)) {
                 continue;
             }
-            MenuItem againster = new MenuItem(theme.getDescription());
+            final MenuItem againster = new MenuItem(theme.getDescription());
             overMenu.addItem(againster);
 
             againster.addClickHandler(new ClickHandler() {
                 @Override
-                public void onClick(MenuItemClickEvent evt) {
+                public void onClick(final MenuItemClickEvent evt) {
                     disable();
                     createAreaArtifact(facetTheme, theme, false);
                 }
             });
         }
         overMenu.addItem(createSeparator());
-        MenuItem againstAxis = new MenuItem(MSG.getString("x_axis"));
+        final MenuItem againstAxis = new MenuItem(this.MSG.getString("x_axis"));
         againstAxis.addClickHandler(new ClickHandler() {
             @Override
-            public void onClick(MenuItemClickEvent evt) {
+            public void onClick(final MenuItemClickEvent evt) {
                 disable();
                 createAreaArtifact(null, facetTheme, false);
             }
@@ -445,23 +368,22 @@
         overMenu.addItem(againstAxis);
 
         // Create the "between..." submenu.
-        MenuItem betweenMenuItem = new MenuItem(
-            MSG.chart_themepanel_area_between());
-        Menu betweenMenu = new Menu();
-        for (int i = 0; i < nThemes; i++)  {
-            final Theme theme = themes.getThemeAt(i+1);
+        final MenuItem betweenMenuItem = new MenuItem(this.MSG.chart_themepanel_area_between());
+        final Menu betweenMenu = new Menu();
+        for (int i = 0; i < nThemes; i++) {
+            final Theme theme = themes.getThemeAt(i + 1);
             if (theme.getVisible() == 0) {
                 continue;
             }
             if (!areAreaCompatible(facetTheme, theme)) {
                 continue;
             }
-            MenuItem againster = new MenuItem(theme.getDescription());
+            final MenuItem againster = new MenuItem(theme.getDescription());
             betweenMenu.addItem(againster);
 
             againster.addClickHandler(new ClickHandler() {
                 @Override
-                public void onClick(MenuItemClickEvent evt) {
+                public void onClick(final MenuItemClickEvent evt) {
                     disable();
                     createAreaArtifact(facetTheme, theme, true);
                 }
@@ -478,11 +400,10 @@
         areaMenu.addItem(overMenuItem);
         areaMenu.addItem(underMenuItem);
         areaMenu.addItem(createSeparator());
-        MenuItem standAloneAgainstAxis = new MenuItem(
-            MSG.getString("against_x_axis"));
+        final MenuItem standAloneAgainstAxis = new MenuItem(this.MSG.getString("against_x_axis"));
         standAloneAgainstAxis.addClickHandler(new ClickHandler() {
             @Override
-            public void onClick(MenuItemClickEvent evt) {
+            public void onClick(final MenuItemClickEvent evt) {
                 disable();
                 createAreaArtifact(null, facetTheme, false);
             }
@@ -494,5 +415,4 @@
 
         return menu;
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartToolbar.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartToolbar.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/ChartToolbar.java	Thu Aug 16 16:28:03 2018 +0200
@@ -83,7 +83,7 @@
                 @Override
                 public void onClick(ClickEvent ce) {
                     new ManualWSPEditor(
-                        finalChartTab.getView().getCollection(),
+                        finalChartTab.getCollectionView().getCollection(),
                         finalChartTab,
                         finalChartTab.getMode().getName()).show();
                     }});
@@ -300,11 +300,11 @@
     protected void openPointWindow() {
         ChartOutputTab chartTab = getChartOutputTab();
         if (chartTab.getMode().getName().equals("historical_discharge")) {
-            new ManualDatePointsEditor(chartTab.getView().getCollection(),
+            new ManualDatePointsEditor(chartTab.getCollectionView().getCollection(),
                 chartTab, chartTab.getMode().getName()).show();
         }
         else {
-            new ManualPointsEditor(chartTab.getView().getCollection(),
+            new ManualPointsEditor(chartTab.getCollectionView().getCollection(),
                 chartTab, chartTab.getMode().getName()).show();
         }
     }
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/CrossSectionChartThemePanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/CrossSectionChartThemePanel.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/CrossSectionChartThemePanel.java	Thu Aug 16 16:28:03 2018 +0200
@@ -32,6 +32,7 @@
 import org.dive4elements.river.client.client.services.LoadArtifactService;
 import org.dive4elements.river.client.client.services.LoadArtifactServiceAsync;
 import org.dive4elements.river.client.client.ui.CollectionView;
+import org.dive4elements.river.client.client.ui.IThemeRecordHandler;
 import org.dive4elements.river.client.client.widgets.KMSpinner;
 import org.dive4elements.river.client.client.widgets.KMSpinnerChangeListener;
 import org.dive4elements.river.client.shared.model.Artifact;
@@ -97,12 +98,11 @@
 
     /**
      * Trivial constructor.
+     * @param noopThemeRecordHandler 
      */
-    public CrossSectionChartThemePanel(
-        OutputMode mode,
-        CollectionView view)
+    public CrossSectionChartThemePanel( OutputMode mode, CollectionView view, IThemeRecordHandler recordHandler)
     {
-        super(mode, view);
+        super(mode, view, recordHandler);
     }
 
 
@@ -550,7 +550,7 @@
      * Initializes the components (columns) of the theme grid.
      */
     @Override
-    protected void initGrid() {
+    protected void initGrid(IThemeRecordHandler recordHandler) {
         list.setCanEdit(true);
         list.setCanSort(false);
         list.setShowRecordComponents(true);
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartOutputTab.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartOutputTab.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartOutputTab.java	Thu Aug 16 16:28:03 2018 +0200
@@ -53,7 +53,7 @@
     private INaviChartStepper stepper;
 
     public NaviChartOutputTab(final String title, final Collection collection, final OutputMode mode, final CollectionView collectionView) {
-        super(title, collection, mode, collectionView);
+        super(title, collection, mode, collectionView, new NaviChartRecordHandler(collectionView));
 
         this.stepper = new NilNaviChartStepper();
 
@@ -230,6 +230,7 @@
         this.currentkm.setValue(this.kmFormat.format(currentKm));
         this.tbarPanel.onZoom(null);
 
+        updateThemePanel();
     }
 
     /**
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartRecordHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartRecordHandler.java	Thu Aug 16 16:28:03 2018 +0200
@@ -0,0 +1,85 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * 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.chart;
+
+import org.dive4elements.river.client.client.ui.CollectionView;
+import org.dive4elements.river.client.client.ui.IThemeRecordHandler;
+import org.dive4elements.river.client.shared.model.AttributedTheme;
+import org.dive4elements.river.client.shared.model.FacetRecord;
+import org.dive4elements.river.client.shared.model.Theme;
+
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ * @author Gernot Belger
+ */
+final class NaviChartRecordHandler implements IThemeRecordHandler, CellFormatter {
+
+    private static final String STYLE_CLASS_NAVI_CHART_GRAYED = "naviChartGrayed";
+    private final CollectionView collectionView;
+
+    public NaviChartRecordHandler(final CollectionView collectionView) {
+        this.collectionView = collectionView;
+    }
+
+    private boolean checkOutsideRange(final FacetRecord facetRecord) {
+
+        final Theme theme = facetRecord.getTheme();
+        if (!(theme instanceof AttributedTheme))
+            return false;
+
+        final double currentKm = this.collectionView.getCurrentKm();
+
+        final AttributedTheme aTheme = (AttributedTheme) theme;
+
+        final Double startKm = aTheme.getAttrAsDouble("startKm");
+        final Double endKm = aTheme.getAttrAsDouble("endKm");
+        if (startKm == null || endKm == null)
+            return false;
+
+        final double fromKm = startKm < endKm ? startKm : endKm;
+        final double toKm = startKm < endKm ? endKm : startKm;
+
+        return currentKm < fromKm || currentKm > toKm;
+    }
+
+    @Override
+    public void handle(final FacetRecord facetRecord) {
+
+        final boolean isOutsideRange = checkOutsideRange(facetRecord);
+        if (isOutsideRange)
+            facetRecord.set_baseStyle(STYLE_CLASS_NAVI_CHART_GRAYED);
+        else
+            facetRecord.set_baseStyle(null);
+    }
+
+    @Override
+    public String format(final Object value, final ListGridRecord record, final int rowNum, final int colNum) {
+
+        if (!(record instanceof FacetRecord))
+            return null;
+
+        final FacetRecord facetRecord = (FacetRecord) record;
+        final String description = facetRecord.getName();
+
+        final boolean isOutsideRange = checkOutsideRange(facetRecord);
+        if (isOutsideRange) {
+            return new StringBuilder(description) //
+                    .append(" (") //
+                    // FIXME: i10n
+                    .append("auß. Gültigkeitsbereich") //
+                    .append(")") //
+                    .toString();
+        }
+
+        return description;
+    }
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/OverviewOutputTab.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/OverviewOutputTab.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/OverviewOutputTab.java	Thu Aug 16 16:28:03 2018 +0200
@@ -13,7 +13,9 @@
 import org.dive4elements.river.client.client.event.OutputParameterChangeHandler;
 import org.dive4elements.river.client.client.event.RedrawRequestHandler;
 import org.dive4elements.river.client.client.ui.CollectionView;
+import org.dive4elements.river.client.client.ui.IThemeRecordHandler;
 import org.dive4elements.river.client.client.ui.ImgLink;
+import org.dive4elements.river.client.client.ui.NoopThemeRecordHandler;
 import org.dive4elements.river.client.shared.model.Collection;
 import org.dive4elements.river.client.shared.model.OutputMode;
 import org.dive4elements.river.client.shared.model.Theme;
@@ -24,7 +26,7 @@
     private class NoChartThemePanel extends ChartThemePanel {
 
         public NoChartThemePanel(OutputMode mode, CollectionView view) {
-            super(mode, view);
+            super(mode, view, new NoopThemeRecordHandler());
         }
 
         @Override
@@ -99,15 +101,13 @@
         OutputMode     mode,
         CollectionView collectionView
         ){
-        super(title, collection, mode, collectionView);
+        super(title, collection, mode, collectionView, new NoopThemeRecordHandler());
         left.setVisible(false);
     }
 
 
     @Override
-    public ChartThemePanel createThemePanel(
-        OutputMode mode, CollectionView view
-        ) {
+    public ChartThemePanel createThemePanel(OutputMode mode, CollectionView view, IThemeRecordHandler recordHandler) {
         return new NoChartThemePanel(mode, view);
     }
 
@@ -115,4 +115,4 @@
     public ChartToolbar createChartToolbar(ChartOutputTab tab) {
         return new MinimumChartToolbar(tab);
     }
-}
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/client/ui/map/MapThemePanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/map/MapThemePanel.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/map/MapThemePanel.java	Thu Aug 16 16:28:03 2018 +0200
@@ -25,6 +25,7 @@
 
 import org.dive4elements.river.client.client.FLYSConstants;
 import org.dive4elements.river.client.client.ui.CollectionView;
+import org.dive4elements.river.client.client.ui.NoopThemeRecordHandler;
 import org.dive4elements.river.client.client.ui.ThemePanel;
 import org.dive4elements.river.client.shared.model.AttributedTheme;
 import org.dive4elements.river.client.shared.model.FacetRecord;
@@ -80,7 +81,7 @@
         ThemeMovedCallback themeMovedCallback,
         LayerZoomCallback  layerZoomCallback
     ) {
-        super(mode, view);
+        super(mode, view, new NoopThemeRecordHandler());
 
         this.mapOut             = mapOut;
         this.activateCallback   = activateCallback;
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/shared/model/AttributedTheme.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/AttributedTheme.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/AttributedTheme.java	Thu Aug 16 16:28:03 2018 +0200
@@ -18,58 +18,77 @@
  */
 public class AttributedTheme implements Theme {
 
-    protected Map<String, String> attributes;
+    private static final long serialVersionUID = 1L;
+
+    private Map<String, String> attributes;
 
     /** CollectionItem associated with this facet/themes artifact. */
-    protected CollectionItem collectionItem;
+    private CollectionItem collectionItem;
 
     public AttributedTheme() {
         this.attributes = new HashMap<String, String>();
     }
 
+    /** Remark: only here so attributes is not final and serialization is happy */
+    public void setAttributes(final Map<String, String> attributes) {
+        this.attributes = attributes;
+    }
 
     public Set<String> getKeys() {
-        return attributes.keySet();
+        return this.attributes.keySet();
     }
 
-
-    public void addAttr(String name, String value) {
+    public void addAttr(final String name, final String value) {
         if (name != null && value != null) {
-            attributes.put(name, value);
+            this.attributes.put(name, value);
         }
     }
 
-
-    public String getAttr(String name) {
-        return attributes.get(name);
+    public String getAttr(final String name) {
+        return this.attributes.get(name);
     }
 
-
-    public Integer getAttrAsInt(String name) {
-        String attr = getAttr(name);
+    public Integer getAttrAsInt(final String name) {
+        final String attr = getAttr(name);
 
         if (attr != null && attr.length() > 0) {
             try {
                 return Integer.parseInt(attr);
             }
-            catch (NumberFormatException nfe) {
+            catch (final NumberFormatException nfe) {
+                nfe.printStackTrace();
             }
         }
 
         return null;
     }
 
+    public Double getAttrAsDouble(final String name) {
 
-    public boolean getAttrAsBoolean(String name) {
-        String attr = getAttr(name);
+        final String attr = getAttr(name);
+        if (attr == null || attr.isEmpty())
+            return null;
+
+        try {
+            return Double.parseDouble(attr);
+        }
+        catch (final NumberFormatException nfe) {
+            nfe.printStackTrace();
+            return null;
+        }
+    }
+
+    public boolean getAttrAsBoolean(final String name) {
+        final String attr = getAttr(name);
 
         if (attr != null) {
             try {
-                int num = Integer.valueOf(attr);
+                final int num = Integer.valueOf(attr);
                 return num > 0;
             }
-            catch (NumberFormatException nfe) {
+            catch (final NumberFormatException nfe) {
                 // do nothing
+                nfe.printStackTrace();
             }
         }
 
@@ -79,21 +98,21 @@
 
     @Override
     public int getPosition() {
-        Integer pos = getAttrAsInt("pos");
+        final Integer pos = getAttrAsInt("pos");
 
         return pos != null ? pos.intValue() : -1;
     }
 
 
     @Override
-    public void setPosition(int pos) {
+    public void setPosition(final int pos) {
         addAttr("pos", String.valueOf(pos));
     }
 
 
     @Override
     public int getIndex() {
-        Integer idx = getAttrAsInt("index");
+        final Integer idx = getAttrAsInt("index");
 
         return idx != null ? idx.intValue() : -1;
     }
@@ -106,7 +125,7 @@
 
 
     @Override
-    public void setActive(int active) {
+    public void setActive(final int active) {
         addAttr("active", String.valueOf(active));
     }
 
@@ -130,7 +149,7 @@
 
 
     @Override
-    public void setDescription(String description) {
+    public void setDescription(final String description) {
         if (description != null && description.length() > 0) {
             addAttr("description", description);
         }
@@ -144,18 +163,18 @@
 
 
     @Override
-    public void setVisible(int visible) {
+    public void setVisible(final int visible) {
         addAttr("visible", String.valueOf(visible));
     }
 
 
     @Override
-    public boolean equals(Object o) {
+    public boolean equals(final Object o) {
         if (!(o instanceof AttributedTheme)) {
             return false;
         }
 
-        AttributedTheme other = (AttributedTheme) o;
+        final AttributedTheme other = (AttributedTheme) o;
 
         if (other.getPosition() != getPosition()) {
             return false;
@@ -188,18 +207,15 @@
         return true;
     }
 
-
     /** Get the CollectionItem representing the facets artifact. */
     @Override
     public CollectionItem getCollectionItem() {
-        return collectionItem;
+        return this.collectionItem;
     }
 
-
     /** Set the CollectionItem representing the facets artifact. */
     @Override
-    public void setCollectionItem(CollectionItem ci) {
+    public void setCollectionItem(final CollectionItem ci) {
         this.collectionItem = ci;
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/shared/model/ChartMode.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/ChartMode.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/ChartMode.java	Thu Aug 16 16:28:03 2018 +0200
@@ -11,49 +11,42 @@
 import java.util.List;
 
 import org.dive4elements.river.client.client.ui.CollectionView;
+import org.dive4elements.river.client.client.ui.NoopThemeRecordHandler;
 import org.dive4elements.river.client.client.ui.OutputTab;
 import org.dive4elements.river.client.client.ui.chart.ChartOutputTab;
 import org.dive4elements.river.client.client.ui.chart.NaviChartOutputTab;
 
-
 /**
  * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
  */
 public class ChartMode extends DefaultOutputMode {
 
+    private static final long serialVersionUID = 1L;
+
     public ChartMode() {
     }
 
+    public ChartMode(final String name, final String descrition, final String mimeType, final List<Facet> facets, final String type) {
+        super(name, descrition, mimeType, facets);
 
-    public ChartMode(String name, String desc, String mimeType) {
-        super(name, desc, mimeType);
-    }
-
-
-    public ChartMode(
-        String name,
-        String descrition,
-        String mimeType,
-        List<Facet> facets,
-        String type)
-    {
-        super(name, descrition, mimeType, facets);
         this.type = type;
     }
 
-
     /** Create output tab. Some outs feel better inside a specialized one. */
     @Override
-    public OutputTab createOutputTab(String t, Collection c, CollectionView p) {
-        if (this.getName().equals("fix_wq_curve") ||
-            this.getName().equals("extreme_wq_curve") ||
-            this.getName().equals("fix_deltawt_curve") ||
-            this.getName().equals("fix_derivate_curve") ||
-            this.getName().equals("fix_vollmer_wq_curve") ||
-            this.getName().equals("sinfo_floodduration_curve")){
+    public OutputTab createOutputTab(final String t, final Collection c, final CollectionView p) {
+        final String modeName = this.getName();
+
+        if (modeName.equals("fix_wq_curve") || //
+                modeName.equals("extreme_wq_curve") || //
+                modeName.equals("fix_deltawt_curve") || //
+                modeName.equals("fix_derivate_curve") || //
+                modeName.equals("fix_vollmer_wq_curve") || //
+                modeName.equals("sinfo_floodduration_curve")) {
+
             return new NaviChartOutputTab(t, c, this, p);
         }
-        return new ChartOutputTab(t, c, this, p);
+
+        return new ChartOutputTab(t, c, this, p, new NoopThemeRecordHandler());
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/java/org/dive4elements/river/client/shared/model/FacetRecord.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/FacetRecord.java	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/FacetRecord.java	Thu Aug 16 16:28:03 2018 +0200
@@ -12,46 +12,38 @@
 
 /**
  * ListGridRecord for Facets.
+ *
  * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
  */
-public class FacetRecord extends ListGridRecord {
+public final class FacetRecord extends ListGridRecord {
 
     /** Underlying theme. */
-    protected Theme theme;
+    private final Theme theme;
 
-
-    public FacetRecord(Theme theme) {
+    public FacetRecord(final Theme theme) {
         this.theme = theme;
 
         setActive(theme.getActive() == 1);
         setName(theme.getDescription());
     }
 
-
     public Theme getTheme() {
-        return theme;
+        return this.theme;
     }
 
-
-    public void setName(String description) {
-        // TODO Add a setter method setName() to Facet
-        // facet.setName(name);
+    public void setName(final String description) {
         setAttribute("name", description);
     }
 
-
     public String getName() {
         return getAttribute("name");
     }
 
-
     public boolean getActive() {
         return getAttributeAsBoolean("active");
     }
 
-
-    public void setActive(boolean active) {
+    public void setActive(final boolean active) {
         setAttribute("active", active);
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r 9744ce3c3853 -r 05405292a7ca gwt-client/src/main/webapp/FLYS.css
--- a/gwt-client/src/main/webapp/FLYS.css	Thu Aug 16 16:27:53 2018 +0200
+++ b/gwt-client/src/main/webapp/FLYS.css	Thu Aug 16 16:28:03 2018 +0200
@@ -244,3 +244,80 @@
 .riverLinkHighlight {
     background: #B7D431;
 }
+
+.naviChartGrayed,
+.naviChartGrayedDark,
+.naviChartGrayedOver,
+.naviChartGrayedOverDark,
+.naviChartGrayedSelected,
+.naviChartGrayedSelectedDark,
+.naviChartGrayedSelectedOver,
+.naviChartGrayedSelectedOverDark,
+.naviChartGrayedDisabled,
+.naviChartGrayedDisabledDark  {
+	
+  border-top: 1px solid #fafafa;
+  border-bottom: 1px solid #f0f0f0;
+  font-family: Arial, Verdana, sans-serif;
+  font-size: 11px;
+  text-overflow: ellipsis;	
+	
+  color: #CCCCCC;
+  font-style: italic;
+}
+
+.naviChartGrayedDark {
+  background-color: #fafafa;
+}
+
+.naviChartGrayedOver,
+.naviChartGrayedOverDark {
+  background-color: #c4ddfd;
+  background-image: url(./images/ListGrid/row_Over.png);
+  background-repeat: repeat-x;
+  background-position: bottom left;
+  background-attachment: scroll;
+  background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2M0ZGRmZCIvPjxzdG9wIG9mZnNldD0iOSUiIHN0b3AtY29sb3I9IiNmMGY4ZmYiLz48c3RvcCBvZmZzZXQ9IjE0JSIgc3RvcC1jb2xvcj0iI2U1ZjNmZiIvPjxzdG9wIG9mZnNldD0iODYlIiBzdG9wLWNvbG9yPSIjY2NlNWZmIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjYzRkZGZkIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g');
+  background-size: 100%;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #c4ddfd), color-stop(9%, #f0f8ff), color-stop(14%, #e5f3ff), color-stop(86%, #cce5ff), color-stop(100%, #c4ddfd));
+  background-image: -webkit-linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+  background-image: -moz-linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+  background-image: -o-linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+  background-image: linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+  border-bottom: 1px solid #c4ddfd;
+  border-top: 1px solid #c4ddfd;
+  -webkit-box-shadow: inset #e5f0ff 0 1px 0, inset #e5f0ff 0 -1px 0;
+  -moz-box-shadow: inset #e5f0ff 0 1px 0, inset #e5f0ff 0 -1px 0;
+  box-shadow: inset #e5f0ff 0 1px 0, inset #e5f0ff 0 -1px 0;
+}
+
+.naviChartGrayedSelected,
+.naviChartGrayedSelectedDark {
+  background: #d6e8ff;
+  border-bottom: 1px dotted #9fb7e9;
+  border-top: 1px dotted #9fb7e9;
+}
+
+.naviChartGrayedSelectedOver,
+.naviChartGrayedSelectedOverDark {
+  border-bottom: 1px solid #ababab;
+  border-top: 1px solid #b8cfef;
+  background-color: #c4ddfd;
+  background-image: url(./images/ListGrid/row_Selected_Over.png);
+  background-repeat: repeat-x;
+  background-attachment: scroll;
+  background-position: bottom left;
+  background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUwJSIgeTE9IjAlIiB4Mj0iNTAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2M0ZGRmZCIvPjxzdG9wIG9mZnNldD0iOSUiIHN0b3AtY29sb3I9IiNmMGY4ZmYiLz48c3RvcCBvZmZzZXQ9IjE0JSIgc3RvcC1jb2xvcj0iI2U1ZjNmZiIvPjxzdG9wIG9mZnNldD0iODYlIiBzdG9wLWNvbG9yPSIjY2NlNWZmIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdG9wLWNvbG9yPSIjYzRkZGZkIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g');
+  background-size: 100%;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #c4ddfd), color-stop(9%, #f0f8ff), color-stop(14%, #e5f3ff), color-stop(86%, #cce5ff), color-stop(100%, #c4ddfd));
+  background-image: -webkit-linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+  background-image: -moz-linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+  background-image: -o-linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+  background-image: linear-gradient(top, #c4ddfd 0%, #f0f8ff 9%, #e5f3ff 14%, #cce5ff 86%, #c4ddfd 100%);
+}
+
+.naviChartGrayedDisabled,
+.naviChartGrayedDisabledDark {
+  background-color: white;
+  color: #ababab;
+}
\ No newline at end of file


More information about the Dive4Elements-commits mailing list