/* * Copyright (c) 2013, Andreas Billmann <abi@geofroggerfx.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package de.geofroggerfx.fx.geofrogger; import de.geofroggerfx.application.ProgressEvent; import de.geofroggerfx.application.SessionConstants; import de.geofroggerfx.application.SessionContext; import de.geofroggerfx.gpx.GPXReader; import de.geofroggerfx.model.Cache; import de.geofroggerfx.model.CacheList; import de.geofroggerfx.plugins.Plugin; import de.geofroggerfx.plugins.PluginService; import de.geofroggerfx.service.CacheService; import javafx.application.Platform; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.concurrent.Service; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.*; import javafx.scene.layout.BorderPane; import javafx.stage.FileChooser; import org.controlsfx.dialog.Dialog; import org.controlsfx.dialog.Dialogs; import org.scenicview.ScenicView; import javax.inject.Inject; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.List; import java.util.Optional; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import static de.geofroggerfx.application.SessionConstants.CACHE_LIST; import static de.geofroggerfx.application.SessionConstants.CACHE_LISTS; import static de.geofroggerfx.service.CacheSortField.NAME; import static de.geofroggerfx.service.SortDirection.ASC; import static java.util.logging.Level.SEVERE; /** * FXML Controller class * * @author Andreas */ public class GeofroggerController implements Initializable { private static final String LICENSE = "/*\n" + " * Copyright (c) 2013-2014, Andreas Billmann <abi@geofroggerfx.de>\n" + " * All rights reserved.\n" + " *\n" + " * Redistribution and use in source and binary forms, with or without\n" + " * modification, are permitted provided that the following conditions are met:\n" + " *\n" + " * * Redistributions of source code must retain the above copyright notice, this\n" + " * list of conditions and the following disclaimer.\n" + " * * Redistributions in binary form must reproduce the above copyright notice,\n" + " * this list of conditions and the following disclaimer in the documentation\n" + " * and/or other materials provided with the distribution.\n" + " *\n" + " * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n" + " * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n" + " * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n" + " * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n" + " * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n" + " * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n" + " * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n" + " * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n" + " * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n" + " * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n" + " * POSSIBILITY OF SUCH DAMAGE.\n" + " */"; private static final String MASTHEAD_TEXT = "GeoFroggerFX by Andreas Billmann <abi@geofroggerfx.de>"; private static final String ABOUT_TEXT = "Used libs:\n" + "\t- JFXtras 8.0 r1\n" + "\t- ControlsFX 8.0.6\n" + "\t- jdom 2.x\n" + "\t- H2 1.3.173\n" + "\t- Icons by http://iconmonstr.com/\n"; @Inject private SessionContext sessionContext; private final LoadCachesFromFileService loadService = new LoadCachesFromFileService(); private final LoadCachesFromDatabaseService loadFromDBService = new LoadCachesFromDatabaseService(); private final LoadCacheListsFromDatabaseService loadListsFromDBService = new LoadCacheListsFromDatabaseService(); private ResourceBundle resourceBundle; @Inject private GPXReader gpxReader; @Inject private CacheService cacheService; @Inject private PluginService pluginService; @FXML private Label leftStatus; @FXML private ProgressBar progress; @FXML private Menu pluginsMenu; @FXML private BorderPane mainPane; @FXML private SplitPane contentPane; /** * Initializes the controller class. * * @param url * @param rb */ @Override public void initialize(URL url, ResourceBundle rb) { resourceBundle = rb; List<Plugin> plugins = pluginService.getAllPlugins(); for (Plugin plugin: plugins) { MenuItem menuItem = new MenuItem(plugin.getName()+" ("+plugin.getVersion()+")"); menuItem.setOnAction(actionEvent -> pluginService.executePlugin(plugin)); pluginsMenu.getItems().add(menuItem); } gpxReader.addListener((ProgressEvent event) -> updateStatus(event.getMessage(), event.getProgress())); cacheService.addListener((ProgressEvent event) -> updateStatus(event.getMessage(), event.getProgress())); loadListsFromDBService.start(); loadFromDBService.start(); } @FXML public void importGpx(ActionEvent actionEvent) { final FileChooser fileChooser = new FileChooser(); //Set extension filter final FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("GPX files (*.gpx)", "*.gpx"); fileChooser.getExtensionFilters().add(extFilter); //Show open file dialog final File file = fileChooser.showOpenDialog(null); loadService.setFile(file); loadService.restart(); } @FXML public void showAboutDialog(ActionEvent actionEvent) { Dialog dialog = new Dialog(null, resourceBundle.getString("dialog.title.about")); dialog.setMasthead(MASTHEAD_TEXT); dialog.setContent(ABOUT_TEXT); dialog.setExpandableContent(new TextArea(LICENSE)); dialog.show(); } @FXML public void showSettings(ActionEvent actionEvent) { // mainPane.setCenter(); // FXMLLoader.load() } @FXML public void newList(ActionEvent actionEvent) { final Optional<String> listNameOption = Dialogs. create(). title(resourceBundle.getString("dialog.title.new_list")). message(resourceBundle.getString("dialog.label.listname")). showTextInput(); if (hasValue(listNameOption)) { final String listName = listNameOption.get().trim(); if (cacheService.doesCacheListNameExist(listName)) { Dialogs. create(). message(resourceBundle.getString("dialog.msg.list.does.exist")). showError(); } else { CacheList list = new CacheList(); list.setName(listName); cacheService.storeCacheList(list); setCacheListInContext(); } } } @FXML public void deleteList(ActionEvent actionEvent) { final Optional<CacheList> listOption = Dialogs. create(). title("dialog.title.delete_list"). message("dialog.label.listname"). showChoices(cacheService.getAllCacheLists()); if (listOption.isPresent()) { cacheService.deleteCacheList(listOption.get()); setCacheListInContext(); } } @FXML public void exit(ActionEvent actionEvent) { Platform.exit(); } private void setCacheListInContext() { sessionContext.setData(CACHE_LISTS, cacheService.getAllCacheLists()); } private void updateStatus(String text, double progressValue) { Platform.runLater(() -> { leftStatus.setText(text); progress.setProgress(progressValue); }); } private boolean hasValue(Optional<String> listNameOption) { return listNameOption.isPresent() && !listNameOption.get().trim().isEmpty(); } private class LoadCacheListsFromDatabaseService extends Service { @Override protected Task createTask() { return new Task() { @Override protected Void call() throws Exception { updateStatus(resourceBundle.getString("status.load.all.caches.from.db"), ProgressIndicator.INDETERMINATE_PROGRESS); sessionContext.setData(CACHE_LISTS, cacheService.getAllCacheLists()); updateStatus(resourceBundle.getString("status.all.cache.lists.loaded"), 0); return null; } }; } } private class LoadCachesFromDatabaseService extends Service { @Override protected Task createTask() { return new Task() { @Override protected Void call() throws Exception { updateStatus(resourceBundle.getString("status.load.caches.from.db"), ProgressIndicator.INDETERMINATE_PROGRESS); sessionContext.setData(CACHE_LIST, cacheService.getAllCaches(NAME, ASC)); updateStatus(resourceBundle.getString("status.all.caches.loaded"), 0); return null; } }; } } private class LoadCachesFromFileService extends Service { private final ObjectProperty<File> file = new SimpleObjectProperty(); public final void setFile(File value) { file.set(value); } public final File getFile() { return file.get(); } public final ObjectProperty<File> fileProperty() { return file; } @Override protected Task createTask() { return new Task() { @Override protected Void call() throws Exception { try { final List<Cache> cacheList = gpxReader.load(file.get().getAbsolutePath()); if (cacheList != null && !cacheList.isEmpty()) { updateStatus(resourceBundle.getString("status.store.all.caches"), ProgressIndicator.INDETERMINATE_PROGRESS); cacheService.storeCaches(cacheList); updateStatus(resourceBundle.getString("status.all.caches.stored"), 0); updateStatus(resourceBundle.getString("status.load.caches.from.db"), ProgressIndicator.INDETERMINATE_PROGRESS); sessionContext.setData(CACHE_LIST, cacheService.getAllCaches(NAME, ASC)); updateStatus(resourceBundle.getString("status.all.caches.loaded"), 0); } } catch (IOException ex) { Logger.getLogger(GeofroggerController.class.getName()).log(SEVERE, null, ex); } return null; } }; } } }