]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - tim/prune/save/BaseImageConfigDialog.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / tim / prune / save / BaseImageConfigDialog.java
diff --git a/tim/prune/save/BaseImageConfigDialog.java b/tim/prune/save/BaseImageConfigDialog.java
deleted file mode 100644 (file)
index 8e7e9ae..0000000
+++ /dev/null
@@ -1,565 +0,0 @@
-package tim.prune.save;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.FlowLayout;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.io.File;
-
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JProgressBar;
-
-import tim.prune.I18nManager;
-import tim.prune.config.Config;
-import tim.prune.data.Track;
-import tim.prune.gui.map.MapSource;
-import tim.prune.gui.map.MapSourceLibrary;
-import tim.prune.threedee.ImageDefinition;
-
-/**
- * Dialog to let you choose the parameters for a base image
- * (source and zoom) including preview
- */
-public class BaseImageConfigDialog implements Runnable
-{
-       /** Parent to notify */
-       private BaseImageConsumer _parent = null;
-       /** Parent dialog for position */
-       private JDialog _parentDialog = null;
-       /** Track to use for preview image */
-       private Track _track = null;
-       /** Dialog to show */
-       private JDialog _dialog = null;
-       /** Checkbox for using an image or not */
-       private JCheckBox _useImageCheckbox = null;
-       /** Panel to hold the other controls */
-       private JPanel _mainPanel = null;
-       /** Dropdown for map source */
-       private JComboBox<String> _mapSourceDropdown = null;
-       /** Dropdown for zoom levels */
-       private JComboBox<String> _zoomDropdown = null;
-       /** Button to trigger a download of the missing map tiles */
-       private JButton _downloadTilesButton = null;
-       /** Progress bar for downloading additional tiles */
-       private JProgressBar _progressBar = null;
-       /** Label for number of tiles found */
-       private JLabel _tilesFoundLabel = null;
-       /** Label for image size in pixels */
-       private JLabel _imageSizeLabel = null;
-       /** Image preview panel */
-       private ImagePreviewPanel _previewPanel = null;
-       /** Grouter, used to avoid regenerating images */
-       private MapGrouter _grouter = new MapGrouter();
-       /** OK button, needs to be enabled/disabled */
-       private JButton _okButton = null;
-       /** Flag for rebuilding dialog, don't bother refreshing and recalculating */
-       private boolean _rebuilding = false;
-       /** Cached values to allow cancellation of dialog */
-       private ImageDefinition _imageDef = new ImageDefinition();
-
-
-       /**
-        * Constructor
-        * @param inParent parent object to notify on completion of dialog
-        * @param inParentDialog parent dialog
-        * @param inTrack track object
-        */
-       public BaseImageConfigDialog(BaseImageConsumer inParent, JDialog inParentDialog, Track inTrack)
-       {
-               _parent = inParent;
-               _parentDialog = inParentDialog;
-               _dialog = new JDialog(inParentDialog, I18nManager.getText("dialog.baseimage.title"), true);
-               _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-               _dialog.getContentPane().add(makeDialogComponents());
-               _dialog.pack();
-               _track = inTrack;
-       }
-
-       /**
-        * @param inDefinition image definition object from previous dialog
-        */
-       public void setImageDefinition(ImageDefinition inDefinition)
-       {
-               _imageDef = inDefinition;
-               if (_imageDef == null) {
-                       _imageDef = new ImageDefinition();
-               }
-       }
-
-       /**
-        * Begin the function
-        */
-       public void begin()
-       {
-               initDialog();
-               _dialog.setLocationRelativeTo(_parentDialog);
-               _dialog.setVisible(true);
-       }
-
-       /**
-        * Begin the function with a default of using an image
-        */
-       public void beginWithImageYes()
-       {
-               initDialog();
-               _useImageCheckbox.setSelected(true);
-               refreshDialog();
-               _dialog.setVisible(true);
-       }
-
-       /**
-        * Initialise the dialog from the cached values
-        */
-       private void initDialog()
-       {
-               _rebuilding = true;
-               _useImageCheckbox.setSelected(_imageDef.getUseImage());
-               // Populate the dropdown of map sources from the library in case it has changed
-               _mapSourceDropdown.removeAllItems();
-               for (int i=0; i<MapSourceLibrary.getNumSources(); i++)
-               {
-                       _mapSourceDropdown.addItem(MapSourceLibrary.getSource(i).getName());
-               }
-               int sourceIndex = _imageDef.getSourceIndex();
-               if (sourceIndex < 0 || sourceIndex >= _mapSourceDropdown.getItemCount()) {
-                       sourceIndex = 0;
-               }
-               _mapSourceDropdown.setSelectedIndex(sourceIndex);
-
-               // Zoom level
-               int zoomLevel = _imageDef.getZoom();
-               if (_imageDef.getUseImage())
-               {
-                       for (int i=0; i<_zoomDropdown.getItemCount(); i++)
-                       {
-                               String item = _zoomDropdown.getItemAt(i).toString();
-                               try {
-                                       if (Integer.parseInt(item) == zoomLevel)
-                                       {
-                                               _zoomDropdown.setSelectedIndex(i);
-                                               break;
-                                       }
-                               }
-                               catch (NumberFormatException nfe) {}
-                       }
-               }
-               _rebuilding = false;
-               refreshDialog();
-       }
-
-       /**
-        * Update the visibility of the controls, and update the zoom dropdown based on the selected map source
-        */
-       private void refreshDialog()
-       {
-               _mainPanel.setVisible(_useImageCheckbox.isSelected());
-               // Exit if we're in the middle of something
-               if (_rebuilding) {return;}
-               int currentZoom = 0;
-               try {
-                       currentZoom = Integer.parseInt(_zoomDropdown.getSelectedItem().toString());
-               }
-               catch (Exception nfe) {}
-               // First time in, the dropdown might be empty but we still might have a zoom in the definition
-               if (_zoomDropdown.getItemCount() == 0) {
-                       currentZoom = _imageDef.getZoom();
-               }
-               // Get the extent of the track so we can work out how big the images are going to be for each zoom level
-               final double xyExtent = Math.max(_track.getXRange().getRange(), _track.getYRange().getRange());
-               int zoomToSelect = -1;
-
-               _rebuilding = true;
-               _zoomDropdown.removeAllItems();
-               if (_useImageCheckbox.isSelected() && _mapSourceDropdown.getItemCount() > 0)
-               {
-                       int currentSource = _mapSourceDropdown.getSelectedIndex();
-                       for (int i=5; i<18; i++)
-                       {
-                               // How many pixels does this give?
-                               final int zoomFactor = 1 << i;
-                               final int pixCount = (int) (xyExtent * zoomFactor * 256);
-                               if (pixCount > 100      // less than this isn't worth it
-                                       && pixCount < 4000  // don't want to run out of memory
-                                       && isZoomAvailable(i, MapSourceLibrary.getSource(currentSource)))
-                               {
-                                       _zoomDropdown.addItem("" + i);
-                                       if (i == currentZoom) {
-                                               zoomToSelect = _zoomDropdown.getItemCount() - 1;
-                                       }
-                               }
-                               // else System.out.println("Not using zoom " + i + " because pixCount=" + pixCount + " and xyExtent=" + xyExtent);
-                       }
-               }
-               _zoomDropdown.setSelectedIndex(zoomToSelect);
-               _rebuilding = false;
-
-               _okButton.setEnabled(!_useImageCheckbox.isSelected() ||
-                       (_zoomDropdown.getItemCount() > 0 && _zoomDropdown.getSelectedIndex() >= 0));
-               updateImagePreview();
-       }
-
-       /**
-        * @return true if it should be possible to use an image, false if no disk cache or cache empty
-        */
-       public static boolean isImagePossible()
-       {
-               String path = Config.getConfigString(Config.KEY_DISK_CACHE);
-               if (path != null && !path.equals(""))
-               {
-                       File cacheDir = new File(path);
-                       if (cacheDir.exists() && cacheDir.isDirectory())
-                       {
-                               // Check if there are any directories in the cache
-                               for (File subdir : cacheDir.listFiles())
-                               {
-                                       if (subdir.exists() && subdir.isDirectory()) {
-                                               return true;
-                                       }
-                               }
-                       }
-               }
-               return false;
-       }
-
-       /**
-        * See if the requested zoom level is available
-        * @param inZoom zoom level
-        * @param inSource selected map source
-        * @return true if there is a zoom directory for each of the source's layers
-        */
-       private static boolean isZoomAvailable(int inZoom, MapSource inSource)
-       {
-               if (inSource == null) {return false;}
-               String path = Config.getConfigString(Config.KEY_DISK_CACHE);
-               if (path == null || path.equals("")) {
-                       return false;
-               }
-               File cacheDir = new File(path);
-               if (!cacheDir.exists() || !cacheDir.isDirectory()) {
-                       return false;
-               }
-               // First layer
-               File layer0 = new File(cacheDir, inSource.getSiteName(0) + inZoom);
-               if (!layer0.exists() || !layer0.isDirectory() || !layer0.canRead()) {
-                       return false;
-               }
-               // Second layer, if any
-               if (inSource.getNumLayers() > 1)
-               {
-                       File layer1 = new File(cacheDir, inSource.getSiteName(1) + inZoom);
-                       if (!layer1.exists() || !layer1.isDirectory() || !layer1.canRead()) {
-                               return false;
-                       }
-               }
-               // must be ok
-               return true;
-       }
-
-
-       /**
-        * @return image definition object
-        */
-       public ImageDefinition getImageDefinition() {
-               return _imageDef;
-       }
-
-       /**
-        * Make the dialog components to select the options
-        * @return Component holding gui elements
-        */
-       private Component makeDialogComponents()
-       {
-               JPanel panel = new JPanel();
-               panel.setLayout(new BorderLayout());
-               _useImageCheckbox = new JCheckBox(I18nManager.getText("dialog.baseimage.useimage"));
-               _useImageCheckbox.setBorder(BorderFactory.createEmptyBorder(4, 4, 6, 4));
-               _useImageCheckbox.setHorizontalAlignment(JLabel.CENTER);
-               _useImageCheckbox.addActionListener(new ActionListener() {
-                       public void actionPerformed(ActionEvent arg0) {
-                               refreshDialog();
-                       }
-               });
-               panel.add(_useImageCheckbox, BorderLayout.NORTH);
-
-               // Outer panel with the grid and the map preview
-               _mainPanel = new JPanel();
-               _mainPanel.setLayout(new BorderLayout(1, 10));
-               // Central stuff with labels and dropdowns
-               JPanel controlsPanel = new JPanel();
-               controlsPanel.setLayout(new GridLayout(0, 2, 10, 4));
-               // map source
-               JLabel sourceLabel = new JLabel(I18nManager.getText("dialog.baseimage.mapsource") + ": ");
-               sourceLabel.setHorizontalAlignment(JLabel.RIGHT);
-               controlsPanel.add(sourceLabel);
-               _mapSourceDropdown = new JComboBox<String>();
-               _mapSourceDropdown.addItem("name of map source");
-               // Add listener to dropdown to change zoom levels
-               _mapSourceDropdown.addActionListener(new ActionListener() {
-                       public void actionPerformed(ActionEvent arg0) {
-                               refreshDialog();
-                       }
-               });
-               controlsPanel.add(_mapSourceDropdown);
-               // zoom level
-               JLabel zoomLabel = new JLabel(I18nManager.getText("dialog.baseimage.zoom") + ": ");
-               zoomLabel.setHorizontalAlignment(JLabel.RIGHT);
-               controlsPanel.add(zoomLabel);
-               _zoomDropdown = new JComboBox<String>();
-               // Add action listener to enable ok button when zoom changed
-               _zoomDropdown.addActionListener(new ActionListener() {
-                       public void actionPerformed(ActionEvent arg0) {
-                               if (_zoomDropdown.getSelectedIndex() >= 0) {
-                                       _okButton.setEnabled(true);
-                                       updateImagePreview();
-                               }
-                       }
-               });
-               controlsPanel.add(_zoomDropdown);
-               _mainPanel.add(controlsPanel, BorderLayout.NORTH);
-
-               JPanel imagePanel = new JPanel();
-               imagePanel.setLayout(new BorderLayout(10, 1));
-               // image preview
-               _previewPanel = new ImagePreviewPanel();
-               imagePanel.add(_previewPanel, BorderLayout.CENTER);
-
-               // Label panel on right
-               JPanel labelPanel = new JPanel();
-               labelPanel.setLayout(new BorderLayout());
-               JPanel downloadPanel = new JPanel();
-               downloadPanel.setLayout(new BorderLayout(4, 4));
-               _downloadTilesButton = new JButton(I18nManager.getText("button.load"));
-               _downloadTilesButton.addActionListener(new ActionListener() {
-                       public void actionPerformed(ActionEvent arg0) {
-                               downloadRemainingTiles();
-                       }
-               });
-               _downloadTilesButton.setVisible(false);
-               downloadPanel.add(_downloadTilesButton, BorderLayout.NORTH);
-               _progressBar = new JProgressBar();
-               _progressBar.setIndeterminate(true);
-               _progressBar.setVisible(false);
-               downloadPanel.add(_progressBar, BorderLayout.SOUTH);
-               labelPanel.add(downloadPanel, BorderLayout.NORTH);
-               JPanel labelGridPanel = new JPanel();
-               labelGridPanel.setLayout(new GridLayout(0, 2, 10, 4));
-               labelGridPanel.add(new JLabel(I18nManager.getText("dialog.baseimage.tiles") + ": "));
-               _tilesFoundLabel = new JLabel("11 / 11");
-               labelGridPanel.add(_tilesFoundLabel);
-               labelGridPanel.add(new JLabel(I18nManager.getText("dialog.baseimage.size") + ": "));
-               _imageSizeLabel = new JLabel("1430");
-               labelGridPanel.add(_imageSizeLabel);
-               labelGridPanel.add(new JLabel(" ")); // just for spacing
-               labelPanel.add(labelGridPanel, BorderLayout.SOUTH);
-               imagePanel.add(labelPanel, BorderLayout.EAST);
-
-               _mainPanel.add(imagePanel, BorderLayout.CENTER);
-               panel.add(_mainPanel, BorderLayout.CENTER);
-
-               // OK, Cancel buttons
-               JPanel buttonPanel = new JPanel();
-               buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
-               _okButton = new JButton(I18nManager.getText("button.ok"));
-               _okButton.addActionListener(new ActionListener() {
-                       public void actionPerformed(ActionEvent e)
-                       {
-                               // Check values, maybe don't want to exit
-                               if (!_useImageCheckbox.isSelected()
-                                       || (_mapSourceDropdown.getSelectedIndex() >= 0 && _zoomDropdown.getSelectedIndex() >= 0))
-                               {
-                                       storeValues();
-                                       _dialog.dispose();
-                               }
-                       }
-               });
-               buttonPanel.add(_okButton);
-               JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
-               cancelButton.addActionListener(new ActionListener() {
-                       public void actionPerformed(ActionEvent e)
-                       {
-                               _dialog.dispose();
-                       }
-               });
-               buttonPanel.add(cancelButton);
-               panel.add(buttonPanel, BorderLayout.SOUTH);
-
-               // Listener to close dialog if escape pressed
-               KeyAdapter closer = new KeyAdapter() {
-                       public void keyReleased(KeyEvent e)
-                       {
-                               if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
-                                       _dialog.dispose();
-                               }
-                       }
-               };
-               _useImageCheckbox.addKeyListener(closer);
-               _mapSourceDropdown.addKeyListener(closer);
-               _zoomDropdown.addKeyListener(closer);
-               _okButton.addKeyListener(closer);
-               cancelButton.addKeyListener(closer);
-
-               return panel;
-       }
-
-       /**
-        * Use the selected settings to make a preview image and (asynchronously) update the preview panel
-        */
-       private void updateImagePreview()
-       {
-               // Clear labels
-               _downloadTilesButton.setVisible(false);
-               _tilesFoundLabel.setText("");
-               _imageSizeLabel.setText("");
-               if (_useImageCheckbox.isSelected() && _mapSourceDropdown.getSelectedIndex() >= 0
-                       && _zoomDropdown.getItemCount() > 0 && _zoomDropdown.getSelectedIndex() >= 0)
-               {
-                       _previewPanel.startLoading();
-                       // Launch a separate thread to create an image and pass it to the preview panel
-                       new Thread(this).start();
-               }
-               else {
-                       // clear preview
-                       _previewPanel.setImage(null);
-               }
-       }
-
-       /**
-        * Store the selected details in the variables
-        */
-       private void storeValues()
-       {
-               // Store values of controls in variables
-               _imageDef.setUseImage(_useImageCheckbox.isSelected(),
-                       _mapSourceDropdown.getSelectedIndex(),
-                       getSelectedZoomLevel());
-               // Inform parent that details have changed
-               _parent.baseImageChanged();
-       }
-
-       /**
-        * Run method for separate thread.  Uses the current dialog parameters
-        * to trigger a call to the Grouter, and pass the image to the preview panel
-        */
-       public void run()
-       {
-               // Remember the current dropdown indices, so we know whether they've changed or not
-               final int mapIndex = _mapSourceDropdown.getSelectedIndex();
-               final int zoomIndex = _zoomDropdown.getSelectedIndex();
-               if (!_useImageCheckbox.isSelected() || mapIndex < 0 || zoomIndex < 0) {return;}
-
-               // Get the map source from the index
-               MapSource mapSource = MapSourceLibrary.getSource(mapIndex);
-
-               // Use the Grouter to create an image (slow, blocks thread)
-               GroutedImage groutedImage = _grouter.createMapImage(_track, mapSource, getSelectedZoomLevel());
-
-               // If the dialog hasn't changed, pass the generated image to the preview panel
-               if (_useImageCheckbox.isSelected()
-                       && _mapSourceDropdown.getSelectedIndex() == mapIndex
-                       && _zoomDropdown.getSelectedIndex() == zoomIndex
-                       && groutedImage != null)
-               {
-                       _previewPanel.setImage(groutedImage);
-                       final int numTilesRemaining = groutedImage.getNumTilesTotal() - groutedImage.getNumTilesUsed();
-                       final boolean offerDownload = numTilesRemaining > 0 && numTilesRemaining < 50 && Config.getConfigBoolean(Config.KEY_ONLINE_MODE);
-                       // Set values of labels
-                       _downloadTilesButton.setVisible(offerDownload);
-                       _downloadTilesButton.setEnabled(offerDownload);
-                       _tilesFoundLabel.setText(groutedImage.getNumTilesUsed() + " / " + groutedImage.getNumTilesTotal());
-                       if (groutedImage.getImageSize() > 0) {
-                               _imageSizeLabel.setText("" + groutedImage.getImageSize());
-                       }
-                       else {
-                               _imageSizeLabel.setText("");
-                       }
-               }
-               else
-               {
-                       _previewPanel.setImage(null);
-                       // Clear labels
-                       _downloadTilesButton.setVisible(false);
-                       _tilesFoundLabel.setText("");
-                       _imageSizeLabel.setText("");
-               }
-       }
-
-       /**
-        * @return zoom level selected in the dropdown
-        */
-       private int getSelectedZoomLevel()
-       {
-               int zoomLevel = 0;
-               try {
-                       zoomLevel = Integer.parseInt(_zoomDropdown.getSelectedItem().toString());
-               }
-               catch (NullPointerException npe) {}
-               catch (Exception e) {
-                       System.err.println("Exception: " + e.getClass().getName() + " : " + e.getMessage());
-               }
-               return zoomLevel;
-       }
-
-       /**
-        * @return true if any map data has been found for the image
-        */
-       public boolean getFoundData()
-       {
-               return _imageDef.getUseImage() && _imageDef.getZoom() > 0
-                       && _previewPanel != null && _previewPanel.getTilesFound();
-       }
-
-       /**
-        * @return true if selected zoom is valid for the current track (based only on pixel size)
-        */
-       public boolean isSelectedZoomValid()
-       {
-               final double xyExtent = Math.max(_track.getXRange().getRange(), _track.getYRange().getRange());
-               // How many pixels does this give?
-               final int zoomFactor = 1 << _imageDef.getZoom();
-               final int pixCount = (int) (xyExtent * zoomFactor * 256);
-               return (pixCount > 100     // less than this isn't worth it
-                       && pixCount < 4000);   // don't want to run out of memory
-       }
-
-       /**
-        * @return the map grouter for retrieval of generated image
-        */
-       public MapGrouter getGrouter()
-       {
-               return _grouter;
-       }
-
-       /**
-        * @return method triggered by "download" button, to asynchronously download the missing tiles
-        */
-       private void downloadRemainingTiles()
-       {
-               _downloadTilesButton.setEnabled(false);
-               new Thread(new Runnable() {
-                       public void run()
-                       {
-                               _progressBar.setVisible(true);
-                               // Use a grouter to get all tiles from the TileManager, including downloading
-                               MapGrouter grouter = new MapGrouter();
-                               final int mapIndex = _mapSourceDropdown.getSelectedIndex();
-                               if (!_useImageCheckbox.isSelected() || mapIndex < 0) {return;}
-                               MapSource mapSource = MapSourceLibrary.getSource(mapIndex);
-                               grouter.createMapImage(_track, mapSource, getSelectedZoomLevel(), true);
-                               _progressBar.setVisible(false);
-                               // And then refresh the dialog
-                               _grouter.clearMapImage();
-                               updateImagePreview();
-                       }
-               }).start();
-       }
-}