package tim.prune.function; import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import tim.prune.App; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.data.DataPoint; import tim.prune.data.SourceInfo; import tim.prune.data.Track; import tim.prune.load.TrackNameList; /** * Function to allow the selection of which tracks to load from the file / stream */ public class SelectTracksFunction extends GenericFunction { private Track _track = null; private SourceInfo _sourceInfo = null; private TrackNameList _trackNameList = null; private JDialog _dialog = null; private JList<String> _trackList = null; /** * Constructor * @param inApp app object to use for load * @param inTrack loaded track object * @param inSourceInfo source information * @param inTrackNameList track name list */ public SelectTracksFunction(App inApp, Track inTrack, SourceInfo inSourceInfo, TrackNameList inTrackNameList) { super(inApp); _track = inTrack; _sourceInfo = inSourceInfo; _trackNameList = inTrackNameList; } /** * Start the function */ public void begin() { _dialog = new JDialog(_parentFrame, I18nManager.getText("function.open")); _dialog.setLocationRelativeTo(_parentFrame); _dialog.getContentPane().add(makeContents()); _dialog.pack(); _dialog.setVisible(true); selectAll(); } /** * @return the contents of the window as a Component */ private Component makeContents() { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); mainPanel.add(new JLabel(I18nManager.getText("dialog.selecttracks.intro")), BorderLayout.NORTH); // track list final int numTracks = _trackNameList.getNumTracks(); String[] names = new String[numTracks]; for (int i=0; i<numTracks; i++) { String name = _trackNameList.getTrackName(i); if (name == null || name.equals("")) { name = I18nManager.getText("dialog.selecttracks.noname"); } names[i] = name + " (" + _trackNameList.getNumPointsInTrack(i) + ")"; } _trackList = new JList<String>(names); _trackList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); mainPanel.add(new JScrollPane(_trackList), BorderLayout.CENTER); // select all button JButton selectAllButton = new JButton(I18nManager.getText("button.selectall")); selectAllButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { selectAll(); } }); JPanel eastPanel = new JPanel(); eastPanel.add(selectAllButton); mainPanel.add(eastPanel, BorderLayout.EAST); // button panel at bottom JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); JButton okButton = new JButton(I18nManager.getText("button.ok")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { finish(); } }); buttonPanel.add(okButton); JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _dialog.dispose(); _app.informNoDataLoaded(); } }); buttonPanel.add(cancelButton); mainPanel.add(buttonPanel, BorderLayout.SOUTH); mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15)); return mainPanel; } /** @return name key */ public String getNameKey() { return "dialog.selecttracks"; } /** * Select all the tracks in the list */ private void selectAll() { _trackList.setSelectionInterval(0, _trackNameList.getNumTracks()-1); } /** * OK pressed, so finish the load */ private void finish() { _dialog.dispose(); int[] tracks = _trackList.getSelectedIndices(); // Check if all tracks are selected, then don't have to filter at all if (tracks.length == _trackNameList.getNumTracks()) { _app.informDataLoaded(_track, _sourceInfo); } else { // build array of which tracks have been selected boolean[] selectedTracks = new boolean[_trackNameList.getNumTracks()]; for (int i=0; i<tracks.length; i++) { selectedTracks[tracks[i]] = true; } // Loop over all points, counting points which survive filter and making flag array int numPointsSelected = 0; int currentTrack = -1; final int totalPoints = _track.getNumPoints(); boolean[] selectedPoints = new boolean[totalPoints]; for (int i=0; i<totalPoints; i++) { final int startOfNextTrack = _trackNameList.getStartIndex(currentTrack+1); if (i == startOfNextTrack) {currentTrack++;} if (currentTrack < 0 || selectedTracks[currentTrack] || _track.getPoint(i).isWaypoint()) { selectedPoints[i] = true; numPointsSelected++; } } // If none of the points have been selected, then load nothing if (numPointsSelected <= 0) { _app.informNoDataLoaded(); } else { // Create new point array of required length DataPoint[] croppedPoints = new DataPoint[numPointsSelected]; // Loop over all points again, copying surviving ones int currPoint = 0; for (int i=0; i<totalPoints; i++) { if (selectedPoints[i]) { croppedPoints[currPoint] = _track.getPoint(i); currPoint++; } } // Construct Track and call informDataLoaded Track filteredTrack = new Track(_track.getFieldList(), croppedPoints); // Tell source info object which points were selected (pass selectedPoints array) _sourceInfo.setPointIndices(selectedPoints); _app.informDataLoaded(filteredTrack, _sourceInfo); } } } }