]> gerrit.simantics Code Review - simantics/district.git/commitdiff
Make background map preference changes apply immediately 18/3918/1
authorjsimomaa <jani.simomaa@gmail.com>
Thu, 5 Mar 2020 06:56:23 +0000 (08:56 +0200)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 5 Mar 2020 10:47:49 +0000 (10:47 +0000)
gitlab #81

Change-Id: I51786e38b865ac9eb1a3abb7e47b3d4186b44098
(cherry picked from commit 465566b944898a570ce56840e6df9a10ca6cf793)

19 files changed:
org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/CSVImportWizardPage.java
org.simantics.district.maps/src/org/simantics/maps/WebService.java
org.simantics.district.maps/src/org/simantics/maps/eclipse/TileJobQueue.java
org.simantics.district.maps/src/org/simantics/maps/osm/OSMTileProvider.java
org.simantics.district.maps/src/org/simantics/maps/pojo/TileJob.java
org.simantics.district.maps/src/org/simantics/maps/pojo/TileJobQueue.java
org.simantics.district.maps/src/org/simantics/maps/prefs/MapsClientPreferenceInitializer.java
org.simantics.district.maps/src/org/simantics/maps/prefs/MapsClientPreferences.java
org.simantics.district.maps/src/org/simantics/maps/sg/MapNode.java
org.simantics.district.maps/src/org/simantics/maps/tile/ITileJobQueue.java
org.simantics.district.maps/src/org/simantics/maps/tile/TileCache.java
org.simantics.district.network.ui/src/org/simantics/district/network/ui/DynamicComboFieldEditor.java [moved from org.simantics.district.imports.ui/src/org/simantics/district/imports/ui/controls/DynamicComboFieldEditor.java with 99% similarity]
org.simantics.maps.elevation.server/src/org/simantics/maps/elevation/server/TiffTileInterface.java
org.simantics.maps.server.ui/META-INF/MANIFEST.MF
org.simantics.maps.server.ui/src/org/simantics/maps/server/ui/Activator.java
org.simantics.maps.server.ui/src/org/simantics/maps/server/ui/TileserverMapnikStartJob.java
org.simantics.maps.server.ui/src/org/simantics/maps/server/ui/prefs/MapsServerPreferencePage.java
org.simantics.maps.server/src/org/simantics/district/maps/server/TileserverMapnikInstance.java
org.simantics.maps.server/src/org/simantics/district/maps/server/prefs/MapsServerPreferences.java

index 910ae428da266f2a5dde41a3d9f5171bf177852d..beb56be19a2ab31f25246ad16d8438fdda8cbc36 100644 (file)
@@ -34,7 +34,7 @@ import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.swt.widgets.Text;
 import org.geotools.referencing.CRS;
 import org.simantics.district.imports.CSVImportModel;
-import org.simantics.district.imports.ui.controls.DynamicComboFieldEditor;
+import org.simantics.district.network.ui.DynamicComboFieldEditor;
 
 public class CSVImportWizardPage extends WizardPage {
 
index f515d4709dcd0093dc2a1ea3395155ab3557be1c..3bfab58cef2bf947b654f378cc25e56d002512f1 100644 (file)
@@ -32,8 +32,6 @@ public class WebService {
     protected URI uri;
     protected URL service;
 
-    protected HttpURLConnection connection;
-
     public WebService(String address) throws URISyntaxException, MalformedURLException {
         this.uri = new URI(address);
         this.service = uri.toURL();
index 3676b8d9a99ec9c0de51f497c94e44977a8dd0be..7147451cdfd6800b1f16762680335727701ff8c3 100644 (file)
@@ -93,4 +93,12 @@ public class TileJobQueue implements ITileJobQueue {
         }
     }
 
+    @Override
+    public void clear() {
+        for (TileJob job : queries.values()) {
+            job.cancel();
+        }
+        queries.clear();
+    }
+
 }
index a428a2df5162f373c27112bb40ec8fa1565f34bf..eebd749f4a4685d136d0ff29255b5d2c2ce6d6b8 100644 (file)
@@ -161,4 +161,8 @@ public class OSMTileProvider implements ITileProvider {
         }
     }
 
+    public void setWebService(WebService webService) {
+        this.service = webService;
+    }
+
 }
index 6ed930d42419be86c004aeb12517272f84a8c0f2..1d7ad914e93b4a1ae6b6ef48253cea0487d177c3 100644 (file)
@@ -13,14 +13,19 @@ package org.simantics.maps.pojo;
 
 import java.awt.Image;
 import java.util.LinkedList;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.simantics.maps.ProvisionException;
 import org.simantics.maps.query.Query;
 import org.simantics.maps.tile.IFilter;
 import org.simantics.maps.tile.ITileProvider;
 import org.simantics.maps.tile.TileKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * @author Tuukka Lehtonen
@@ -28,9 +33,16 @@ import org.simantics.maps.tile.TileKey;
  */
 public class TileJob implements Runnable {
 
-    LinkedList<Query<TileKey, Image>> queue = new LinkedList<Query<TileKey, Image>>();
-    Executor executor = new ScheduledThreadPoolExecutor(1);
-    ITileProvider provider;
+    private static final Logger LOGGER = LoggerFactory.getLogger(TileJob.class);
+    private static final AtomicInteger counter = new AtomicInteger();
+
+    private LinkedList<Query<TileKey, Image>> queue = new LinkedList<>();
+    private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, runnable -> {
+        Thread thread = new Thread(runnable, getClass().getSimpleName() + "-" + counter.getAndIncrement());
+        thread.setDaemon(true);
+        return thread;
+    });
+    private ITileProvider provider;
 
     public TileJob() {
     }
@@ -51,6 +63,7 @@ public class TileJob implements Runnable {
                     Image result = doQuery(job.source);
                     job.listener.queryComplete(job, result);
                 } catch (Exception e) {
+                    LOGGER.error("Querying failed for job {}", job, e);
                     job.listener.queryFailed(job, e);
                 }
             }
@@ -112,4 +125,16 @@ public class TileJob implements Runnable {
         this.queue = result;
     }
 
+    public void dispose() {
+        executor.shutdown();
+        try {
+            if (!executor.awaitTermination(100, TimeUnit.MILLISECONDS)) {
+                // this should shutdown for good
+                List<Runnable> unfinished = executor.shutdownNow();
+                LOGGER.warn("TileJob did not terminate in time - left jobs {}", unfinished);
+            }
+        } catch (InterruptedException e) {
+        }
+    }
+
 }
index f6ab637c5513541bb6143516590e6bb2b31c84de..343b2ad4e9618d12906a92be279f65b6eaaa6c4c 100644 (file)
@@ -73,4 +73,10 @@ public class TileJobQueue implements ITileJobQueue {
         getJob().removeJob(job);
     }
 
+    @Override
+    public void clear() {
+        getJob().clear();
+        getJob().dispose();
+    }
+
 }
index 2f0e61c93b4b9b6a9967da98b2339ea262222b88..fd946d9f20fd6247e00ff070dc5868443e788c3e 100644 (file)
@@ -6,16 +6,20 @@ import java.util.List;
 import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
 import org.osgi.service.prefs.BackingStoreException;
 import org.osgi.service.prefs.Preferences;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class MapsClientPreferenceInitializer extends AbstractPreferenceInitializer {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(MapsClientPreferenceInitializer.class);
+
     public MapsClientPreferenceInitializer() {
     }
 
     @Override
     public void initializeDefaultPreferences() {
         Preferences node = MapsClientPreferences.getPreferences();
-        
+
         try {
             String[] keys = node.keys();
             List<String> keyss = Arrays.asList(keys);
@@ -26,7 +30,7 @@ public class MapsClientPreferenceInitializer extends AbstractPreferenceInitializ
                 node.put(MapsClientPreferences.P_TILESERVER_URL, possibleBuiltin);
             }
         } catch (BackingStoreException e) {
-            e.printStackTrace();
+            LOGGER.error("Could not get keys for node {}", node, e);
         }
     }
 }
index fbc8b9e06659b9c914db7f2863483b295688f5da..a54185c1c84c22ee8351e250e1a33a9e87936a82 100644 (file)
@@ -3,8 +3,9 @@ package org.simantics.maps.prefs;
 import java.net.MalformedURLException;
 import java.net.URL;
 
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.osgi.service.prefs.Preferences;
 
 public class MapsClientPreferences {
 
@@ -15,13 +16,15 @@ public class MapsClientPreferences {
     
     // TODO: fix this, currently copied from MapsServerPreferences
     public static final String P_DEFAULT_PORT = "org.simantics.maps.server.defaultPort";
+    public static final String P_CURRENT_MBTILES = "org.simantics.maps.server.currentMbTiles";
     public static final String P_CURRENT_TM2STYLE = "org.simantics.maps.server.currentTM2Style";
     public static final String P_SERVER_NODE = "org.simantics.maps.server";
-    public static Preferences getServerPreferences() {
+    
+    public static IEclipsePreferences getServerPreferences() {
         return InstanceScope.INSTANCE.getNode(P_SERVER_NODE);
     }
     
-    public static Preferences getPreferences() {
+    public static IEclipsePreferences getPreferences() {
         return InstanceScope.INSTANCE.getNode(P_NODE);
     }
     
@@ -46,4 +49,12 @@ public class MapsClientPreferences {
         return null;
     }
 
+    public static void addPreferenceChangeListenerMapsServer(IPreferenceChangeListener listener) {
+        getServerPreferences().addPreferenceChangeListener(listener);
+    }
+
+    public static void removePreferenceChangeListenerMapsServer(IPreferenceChangeListener listener) {
+        getServerPreferences().removePreferenceChangeListener(listener);
+    }
+
 }
index ae418de477f61d55daedf9f9af1bdcef755c7452..fe83bd10999c07a24d54b4b0b0678772799f2eac 100644 (file)
@@ -25,6 +25,8 @@ import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.ImageObserver;
 import java.awt.image.VolatileImage;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -36,6 +38,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
 import org.simantics.maps.MapScalingTransform;
 import org.simantics.maps.WebService;
 import org.simantics.maps.osm.OSMTileProvider;
@@ -170,18 +173,26 @@ public class MapNode extends G2DNode implements ITileListener  {
         }
     };
 
+    private IPreferenceChangeListener listener;
+
     public void init() {
-        // Construct WebService from client properties
-        String url;
-        if (MapsClientPreferences.useBuiltinServer())
-            url = MapsClientPreferences.possibleBuiltinServerURL();
-        else 
-            url = MapsClientPreferences.tileserverURL();
-        if (!url.endsWith("/"))
-            url = url + "/";
-        
         try {
-            ITileProvider provider = new OSMTileProvider(new WebService(url), TILE_PIXEL_SIZE);
+            OSMTileProvider provider = new OSMTileProvider(new WebService(computeUrl()), TILE_PIXEL_SIZE);
+
+            listener = event -> {
+                // if tiles or style change we want to flush the tile cache
+                if (MapsClientPreferences.P_CURRENT_MBTILES.equals(event.getKey()) || MapsClientPreferences.P_CURRENT_TM2STYLE.equals(event.getKey())) {
+                    if (tileCache != null) {
+                        tileCache.clear();
+                    }
+                    try {
+                        provider.setWebService(new WebService(computeUrl()));
+                    } catch (MalformedURLException | URISyntaxException e) {
+                        LOGGER.error("Unable to update WebService with new url", e);
+                    }
+                }
+            };
+            MapsClientPreferences.addPreferenceChangeListenerMapsServer(listener);
 
             // Try to load eclipse specific implementation of TileJobQueue, if it doesn't exist, fall back to pojo implementation 
             try {
@@ -219,6 +230,25 @@ public class MapNode extends G2DNode implements ITileListener  {
         }
     }
 
+    private static String computeUrl() {
+     // Construct WebService from client properties
+        String url;
+        if (MapsClientPreferences.useBuiltinServer())
+            url = MapsClientPreferences.possibleBuiltinServerURL();
+        else 
+            url = MapsClientPreferences.tileserverURL();
+        if (!url.endsWith("/"))
+            url = url + "/";
+        return url;
+    }
+
+    @Override
+    public void cleanup() {
+        MapsClientPreferences.removePreferenceChangeListenerMapsServer(listener);
+        tileCache.clear();
+        job.clear();
+    }
+
     @SyncField("enabled")
     public void setEnabled(Boolean enabled) {
         this.enabled = enabled;
index 7a0a3753d8213baf6feb364c7da9f83e6d287a29..a69fe3a330c72302abe8bd69c578788875f9b3c0 100644 (file)
@@ -46,4 +46,6 @@ public interface ITileJobQueue {
      */
     public void setTileProvider(ITileProvider provider);
 
+    public void clear();
+
 }
\ No newline at end of file
index 9f58193084426a555a54ba73031a44164fba910e..7ec5c5ed963b104bd0baaeb5400b89fe718fdc34 100644 (file)
@@ -147,6 +147,14 @@ public class TileCache implements ITileListener {
         for (ITileListener l : tileListeners) {
             l.tileUpdated(key, image);
         }
-       }
+    }
+
+    public void clear() {
+        synchronized (this) {
+            for (LevelCache level : levels.values()) {
+                level.cache.clear();
+            }
+        }
+    }
 
 }
index f688024b0d078ef8250593a2878202eaa1dc6cef..0cbf3fa5e03f31f80a50d9f796c66780f37715af 100644 (file)
@@ -111,7 +111,7 @@ public class TiffTileInterface implements Closeable {
         try {
             c4326 = CRS.decode("EPSG:4326");
         } catch (Exception e) {
-            LOGGER.error("Could not initialize epsg:4326", e);
+            LOGGER.error("Could not initialize EPSG:4326", e);
         }
     }
 
@@ -128,7 +128,7 @@ public class TiffTileInterface implements Closeable {
                     tifInterface.close();
                 }
             } else {
-                System.out.println("not found");
+                //System.out.println("not found");
             }
         }
         return new Double(0); // use 0 by default for now
index 73e4b27bd01f3b3eeae40b7bbba7114a708dd685..ec29b0265984dcfd1d80b7cb684890fb81b7a76a 100644 (file)
@@ -13,6 +13,7 @@ Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.e4.core.commands,
  org.eclipse.e4.core.contexts,
  org.simantics.ui,
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.district.network.ui;bundle-version="1.0.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-ActivationPolicy: lazy
index 78b2e7b24118b0a793be76d4ad26074e073c8349..14d121013b48e0a725da838014263128da45990e 100644 (file)
@@ -33,7 +33,7 @@ public class Activator implements BundleActivator {
             // execute in a separate thread to not slow down the startup process
             if (LOGGER.isDebugEnabled())
                 LOGGER.debug("Starting tileserver mapnik automatically");
-            new TileserverMapnikStartJob().schedule();
+            new TileserverMapnikStartJob(status -> {}).schedule();
         }
     }
 
index a729bfc135498560ba7b2cc1ad3f65acb7ef561b..f6d9b221063a97bd33b5aa94901d5c4e691935f3 100644 (file)
@@ -1,6 +1,7 @@
 package org.simantics.maps.server.ui;
 
 import java.util.Optional;
+import java.util.function.Consumer;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -14,24 +15,28 @@ import org.slf4j.LoggerFactory;
 public class TileserverMapnikStartJob extends Job {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(TileserverMapnikStartJob.class);
+    private Consumer<IStatus> callback;
     
-    public TileserverMapnikStartJob() {
+    public TileserverMapnikStartJob(Consumer<IStatus> callback) {
         super("Tileserver start job");
+        this.callback = callback;
     }
 
     @Override
     protected IStatus run(IProgressMonitor monitor) {
         monitor.beginTask("Starting tileserver", 100);
+        IStatus status = Status.OK_STATUS;
         try {
             StartListener startListener = new StartListener(monitor);
             TileserverMapnikInstance.get().start(Optional.of(startListener));
             if (startListener.module != null || startListener.returnValue != 0)
-                return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not install " + String.valueOf(startListener.module) + " with returnValue " + startListener.returnValue);
-            return Status.OK_STATUS;
+                status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not install " + String.valueOf(startListener.module) + " with returnValue " + startListener.returnValue);
         } catch (Exception e) {
             LOGGER.error("Could not start tileserver-mapnik", e);
-            return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not start tileserver-mapnik: " + e.getMessage());
+            status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not start tileserver-mapnik: " + e.getMessage());
         }
+        callback.accept(status);
+        return status;
     }
 
     private class StartListener implements TileserverStartListener {
index 8a1a6f91271f2bd2d54372f5724f5c68d99a59d3..c9e01cb0e36ab575d7f80c2aab882f4ede6bab7d 100644 (file)
@@ -16,6 +16,7 @@ import org.eclipse.jface.preference.FieldEditorPreferencePage;
 import org.eclipse.jface.preference.FileFieldEditor;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.jface.preference.StringFieldEditor;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.swt.SWT;
@@ -31,6 +32,7 @@ import org.eclipse.ui.preferences.ScopedPreferenceStore;
 import org.simantics.district.maps.server.TileserverMapnik;
 import org.simantics.district.maps.server.TileserverMapnikInstance;
 import org.simantics.district.maps.server.prefs.MapsServerPreferences;
+import org.simantics.district.network.ui.DynamicComboFieldEditor;
 import org.simantics.maps.server.ui.TileserverMapnikStartJob;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,6 +45,8 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
 
     private FileFieldEditor addNew;
 
+    private DynamicComboFieldEditor currentTilesSelector;
+
     public MapsServerPreferencePage() {
         super(GRID);
         setDescription("Maps server preferences");
@@ -64,8 +68,10 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
 
     private void createServerStatusField(Composite parent) {
         Label label = new Label(parent, SWT.NONE);
-
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(label);
+        
         Button b = new Button(parent, SWT.NONE);
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(b);
         updateWidgets(label, b);
         b.addSelectionListener(new SelectionAdapter() {
             
@@ -76,7 +82,11 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
                         server.stop();
                         updateWidgets(label, b);
                     } else {
-                        new TileserverMapnikStartJob().schedule();
+                        new TileserverMapnikStartJob(status -> {
+                            parent.getDisplay().asyncExec(() -> {
+                                updateWidgets(label, b);
+                            });
+                        }).schedule();
                     }
                 } catch (Exception ex) {
                     LOGGER.error("Could not start/stop server", ex);
@@ -122,16 +132,10 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
         BooleanFieldEditor automatically = new BooleanFieldEditor(MapsServerPreferences.P_START_AUTOMATICALLY, "Start tileserver automatically", serverGroup);
         addField(automatically);
         
-        Button openInExplorer = new Button(serverGroup, SWT.NONE);
-        openInExplorer.setText("Open server folder");
-        openInExplorer.addSelectionListener(new SelectionAdapter() {
-            
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-//                E4WorkbenchUtils.showInSystemExplorer("");
-            }
-        });
-        
+        StringFieldEditor serverFolder = new StringFieldEditor(MapsServerPreferences.P_SERVER_FOLDER, "Server folder", serverGroup);
+        serverFolder.setEnabled(false, serverGroup);
+        addField(serverFolder);
+
         GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(serverGroup);
     }
     
@@ -167,7 +171,8 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
                 namesAndValues[i] = nameAndValue;
             }
             
-            ComboFieldEditor selector = new ComboFieldEditor(MapsServerPreferences.P_CURRENT_TM2STYLE, "Tile Styles", namesAndValues, parent);
+            ComboFieldEditor selector = new ComboFieldEditor(MapsServerPreferences.P_CURRENT_TM2STYLE, "Selected Style", namesAndValues, parent);
+            GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(selector.getLabelControl(parent));
             addField(selector);
         } catch (IOException e) {
             e.printStackTrace();
@@ -176,31 +181,29 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
     
     private void createTilesGroup() {
         Group tilesGroup = new Group(getFieldEditorParent(), SWT.NONE);
-        tilesGroup.setText("MBTiles");
-        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(tilesGroup);
-        
+        tilesGroup.setText("Vector Tiles");
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(tilesGroup);
         createTilesField(tilesGroup);
         
-        GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(tilesGroup);
+        GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(tilesGroup);
     }
 
     private void createTilesField(Composite parent) {
         try {
-            List<String> tiles = server.availableMBTiles();
-            
-            String[][] namesAndValues = new String[tiles.size()][];
-            for (int i = 0; i < tiles.size(); i++) {
-                String style = tiles.get(i);
-                String[] nameAndValue = new String[2];
-                nameAndValue[0] = style;
-                nameAndValue[1] = style;
-                namesAndValues[i] = nameAndValue;
-            }
+
+            String[][] namesAndValues = computeNamesAndValues();
+            currentTilesSelector = new DynamicComboFieldEditor(MapsServerPreferences.P_CURRENT_MBTILES, "Current Tiles", namesAndValues, parent);
             
-            ComboFieldEditor selector = new ComboFieldEditor(MapsServerPreferences.P_CURRENT_MBTILES, "MBTiles", namesAndValues, parent);
-            addField(selector);
+            GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(currentTilesSelector.getLabelControl(parent));
+            addField(currentTilesSelector);
+
+            Composite newParent = new Composite(parent, SWT.NONE);
+            GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(newParent);
+            GridLayoutFactory.fillDefaults().numColumns(3).applyTo(newParent);
             
-            addNew = new FileFieldEditor("Add new tiles", "Add new tiles", parent);
+            addNew = new FileFieldEditor("Add new tiles", "Add new tiles", newParent);
+            //GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(addNew.getTextControl(newParent));
+            //addField(addNew);
             addNew.setPropertyChangeListener(new IPropertyChangeListener() {
                 
                 @Override
@@ -214,6 +217,19 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
         }
     }
     
+    private String[][] computeNamesAndValues() throws IOException {
+        List<String> tiles = server.availableMBTiles();
+        String[][] namesAndValues = new String[tiles.size()][];
+        for (int i = 0; i < tiles.size(); i++) {
+            String style = tiles.get(i);
+            String[] nameAndValue = new String[2];
+            nameAndValue[0] = style;
+            nameAndValue[1] = style;
+            namesAndValues[i] = nameAndValue;
+        }
+        return namesAndValues;
+    }
+
     @Override
     protected void performApply() {
         // Upload new mbtiles file
@@ -223,12 +239,19 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
             Path target = server.getDataDirectory().resolve(p.getFileName());
             try {
                 Files.copy(p, target);
+                addNew.setStringValue("");
             } catch (IOException e) {
                 String message = "Could not upload " + fileLocation + " to " + target.toAbsolutePath(); 
                 LOGGER.error(message, e);
                 setErrorMessage(message);
             }
         }
+        try {
+            currentTilesSelector.updateCombo(computeNamesAndValues());
+            currentTilesSelector.load();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
         super.performApply();
     }
     
@@ -238,7 +261,7 @@ public class MapsServerPreferencePage extends FieldEditorPreferencePage implemen
         
         try {
             server.stop();
-            new TileserverMapnikStartJob().schedule();
+            new TileserverMapnikStartJob(status -> {}).schedule();
         } catch (Exception e) {
             LOGGER.error("Could not restart tileserver-mapnik", e);
         }
index 18b6bca64046713a60deffd7b0509fcc000da31b..129999ca0e15f519a47086f4fd4a9b414b59df6a 100644 (file)
@@ -2,6 +2,9 @@ package org.simantics.district.maps.server;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.nio.file.Paths;
+
+import org.simantics.district.maps.server.prefs.MapsServerPreferences;
 
 public class TileserverMapnikInstance {
 
@@ -9,7 +12,7 @@ public class TileserverMapnikInstance {
     
     public static synchronized TileserverMapnik get() throws IOException, URISyntaxException {
         if (INSTANCE == null)
-            INSTANCE = new TileserverMapnik(Activator.getTileserverMapnikRoot());
+            INSTANCE = new TileserverMapnik(Paths.get(MapsServerPreferences.serverFolder()));
         return INSTANCE;
     }
 }
index 816fdbb430fb34e3f1e9788c78d7c7044399ec85..ea8b2f78ca4db00c5a4f04d862acf7ed836c189a 100644 (file)
@@ -1,5 +1,8 @@
 package org.simantics.district.maps.server.prefs;
 
+import java.io.IOException;
+import java.net.URISyntaxException;
+
 import org.eclipse.core.runtime.preferences.InstanceScope;
 import org.osgi.service.prefs.Preferences;
 import org.simantics.district.maps.server.Activator;
@@ -16,6 +19,8 @@ public class MapsServerPreferences {
     
     public static final String P_CURRENT_TM2STYLE = "org.simantics.maps.server.currentTM2Style";
 
+    public static final String P_SERVER_FOLDER = "org.simantics.maps.server.serverFolder";
+
     public static Preferences getPreferences() {
         return InstanceScope.INSTANCE.getNode(MapsServerPreferences.P_NODE);
     }
@@ -36,4 +41,7 @@ public class MapsServerPreferences {
         return getPreferences().get(P_CURRENT_TM2STYLE, "mapbox-studio-osm-bright.tm2");
     }
 
+    public static String serverFolder() throws IOException, URISyntaxException {
+        return getPreferences().get(P_SERVER_FOLDER, Activator.getTileserverMapnikRoot().toAbsolutePath().toString());
+    }
 }