+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);
+ }
+ }
+ }
+}