1 package org.simantics.maps.server.ui.prefs;
3 import java.io.IOException;
4 import java.net.URISyntaxException;
5 import java.nio.file.Files;
6 import java.nio.file.Path;
7 import java.nio.file.Paths;
10 import org.eclipse.core.runtime.preferences.InstanceScope;
11 import org.eclipse.jface.layout.GridDataFactory;
12 import org.eclipse.jface.layout.GridLayoutFactory;
13 import org.eclipse.jface.preference.BooleanFieldEditor;
14 import org.eclipse.jface.preference.ComboFieldEditor;
15 import org.eclipse.jface.preference.FieldEditorPreferencePage;
16 import org.eclipse.jface.preference.FileFieldEditor;
17 import org.eclipse.jface.preference.IPreferenceStore;
18 import org.eclipse.jface.preference.IntegerFieldEditor;
19 import org.eclipse.jface.util.IPropertyChangeListener;
20 import org.eclipse.jface.util.PropertyChangeEvent;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.widgets.Button;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Group;
27 import org.eclipse.swt.widgets.Label;
28 import org.eclipse.ui.IWorkbench;
29 import org.eclipse.ui.IWorkbenchPreferencePage;
30 import org.eclipse.ui.preferences.ScopedPreferenceStore;
31 import org.simantics.district.maps.server.TileserverMapnik;
32 import org.simantics.district.maps.server.TileserverMapnikInstance;
33 import org.simantics.district.maps.server.prefs.MapsServerPreferences;
34 import org.simantics.maps.server.ui.TileserverMapnikStartJob;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 public class MapsServerPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
40 private static final Logger LOGGER = LoggerFactory.getLogger(MapsServerPreferencePage.class);
42 private TileserverMapnik server;
44 private FileFieldEditor addNew;
46 public MapsServerPreferencePage() {
48 setDescription("Maps server preferences");
52 public void init(IWorkbench workbench) {
54 server = TileserverMapnikInstance.get();
55 } catch (IOException | URISyntaxException e) {
56 LOGGER.error("Could not initialize " + getClass(), e);
61 protected IPreferenceStore doGetPreferenceStore() {
62 return new ScopedPreferenceStore(InstanceScope.INSTANCE, MapsServerPreferences.P_NODE);
65 private void createServerStatusField(Composite parent) {
66 Label label = new Label(parent, SWT.NONE);
68 Button b = new Button(parent, SWT.NONE);
69 updateWidgets(label, b);
70 b.addSelectionListener(new SelectionAdapter() {
73 public void widgetSelected(SelectionEvent e) {
75 if (server.isRunning()) {
77 updateWidgets(label, b);
79 new TileserverMapnikStartJob().schedule();
81 } catch (Exception ex) {
82 LOGGER.error("Could not start/stop server", ex);
88 private void updateWidgets(Label label, Button b) {
89 String labelText = "";
90 String buttonText = "";
92 boolean running = false;
94 if (server.isRunning()) {
97 labelText = "running";
98 labelColor = SWT.COLOR_DARK_GREEN;
100 labelText = "stopped";
101 buttonText = "Start";
103 } catch (IOException | InterruptedException e) {
104 LOGGER.error("Could not create server status field!", e);
105 labelText = "unknown";
106 labelColor = SWT.COLOR_DARK_RED;
108 label.setText("Tileserver is currently " + labelText);
109 label.setForeground(getShell().getDisplay().getSystemColor(labelColor));
111 b.setText(buttonText + " server");
114 private void createGeneralGroup() {
115 Group serverGroup = new Group(getFieldEditorParent(), SWT.NONE);
116 serverGroup.setText("General");
117 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(serverGroup);
119 createServerStatusField(serverGroup);
121 IntegerFieldEditor port = new IntegerFieldEditor(MapsServerPreferences.P_DEFAULT_PORT, "Tileserver port", serverGroup);
124 BooleanFieldEditor automatically = new BooleanFieldEditor(MapsServerPreferences.P_START_AUTOMATICALLY, "Start tileserver automatically", serverGroup);
125 addField(automatically);
127 Button openInExplorer = new Button(serverGroup, SWT.NONE);
128 openInExplorer.setText("Open server folder");
129 openInExplorer.addSelectionListener(new SelectionAdapter() {
132 public void widgetSelected(SelectionEvent e) {
133 // E4WorkbenchUtils.showInSystemExplorer("");
137 GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(serverGroup);
141 protected void createFieldEditors() {
142 createGeneralGroup();
149 private void createStylesGroup() {
150 Group stylesGroup = new Group(getFieldEditorParent(), SWT.NONE);
151 stylesGroup.setText("Styles");
152 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(stylesGroup);
154 createTM2StylesField(stylesGroup);
156 GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(stylesGroup);
159 private void createTM2StylesField(Composite parent) {
161 List<String> styles = server.listStyles();
163 String[][] namesAndValues = new String[styles.size()][];
164 for (int i = 0; i < styles.size(); i++) {
165 String style = styles.get(i);
166 String[] nameAndValue = new String[2];
167 nameAndValue[0] = style;
168 nameAndValue[1] = style;
169 namesAndValues[i] = nameAndValue;
172 ComboFieldEditor selector = new ComboFieldEditor(MapsServerPreferences.P_CURRENT_TM2STYLE, "Tile Styles", namesAndValues, parent);
174 } catch (IOException e) {
179 private void createTilesGroup() {
180 Group tilesGroup = new Group(getFieldEditorParent(), SWT.NONE);
181 tilesGroup.setText("MBTiles");
182 GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(tilesGroup);
184 createTilesField(tilesGroup);
186 GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(tilesGroup);
189 private void createTilesField(Composite parent) {
191 List<String> tiles = server.availableMBTiles();
193 String[][] namesAndValues = new String[tiles.size()][];
194 for (int i = 0; i < tiles.size(); i++) {
195 String style = tiles.get(i);
196 String[] nameAndValue = new String[2];
197 nameAndValue[0] = style;
198 nameAndValue[1] = style;
199 namesAndValues[i] = nameAndValue;
202 ComboFieldEditor selector = new ComboFieldEditor(MapsServerPreferences.P_CURRENT_MBTILES, "MBTiles", namesAndValues, parent);
205 addNew = new FileFieldEditor("Add new tiles", "Add new tiles", parent);
206 addNew.setPropertyChangeListener(new IPropertyChangeListener() {
209 public void propertyChange(PropertyChangeEvent event) {
210 System.out.println(event);
214 } catch (IOException e) {
215 LOGGER.error("Could not create tiles field", e);
220 protected void performApply() {
221 // Upload new mbtiles file
222 String fileLocation = addNew.getStringValue();
223 if (fileLocation != null && !fileLocation.isEmpty()) {
224 Path p = Paths.get(fileLocation);
225 Path target = server.getDataDirectory().resolve(p.getFileName());
227 Files.copy(p, target);
228 } catch (IOException e) {
229 String message = "Could not upload " + fileLocation + " to " + target.toAbsolutePath();
230 LOGGER.error(message, e);
231 setErrorMessage(message);
234 super.performApply();
238 public boolean performOk() {
239 boolean success = super.performOk();
243 new TileserverMapnikStartJob().schedule();
244 } catch (Exception e) {
245 LOGGER.error("Could not restart tileserver-mapnik", e);