]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/function/SelectTracksFunction.java
Version 13, August 2011
[GpsPrune.git] / tim / prune / function / SelectTracksFunction.java
1 package tim.prune.function;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.FlowLayout;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8
9 import javax.swing.BorderFactory;
10 import javax.swing.JButton;
11 import javax.swing.JDialog;
12 import javax.swing.JLabel;
13 import javax.swing.JList;
14 import javax.swing.JPanel;
15 import javax.swing.JScrollPane;
16 import javax.swing.ListSelectionModel;
17
18 import tim.prune.App;
19 import tim.prune.GenericFunction;
20 import tim.prune.I18nManager;
21 import tim.prune.data.DataPoint;
22 import tim.prune.data.SourceInfo;
23 import tim.prune.data.Track;
24 import tim.prune.load.TrackNameList;
25
26 /**
27  * Function to allow the selection of which tracks to load from the file / stream
28  */
29 public class SelectTracksFunction extends GenericFunction
30 {
31         private Track _track = null;
32         private SourceInfo _sourceInfo = null;
33         private TrackNameList _trackNameList = null;
34         private JDialog _dialog = null;
35         private JList _trackList = null;
36
37         /**
38          * Constructor
39          * @param inApp app object to use for load
40          * @param inTrack loaded track object
41          * @param inSourceInfo source information
42          * @param inTrackNameList track name list
43          */
44         public SelectTracksFunction(App inApp, Track inTrack, SourceInfo inSourceInfo,
45                 TrackNameList inTrackNameList)
46         {
47                 super(inApp);
48                 _track = inTrack;
49                 _sourceInfo = inSourceInfo;
50                 _trackNameList = inTrackNameList;
51         }
52
53         /**
54          * Start the function
55          */
56         public void begin()
57         {
58                 _dialog = new JDialog(_parentFrame, I18nManager.getText("function.open"));
59                 _dialog.setLocationRelativeTo(_parentFrame);
60                 _dialog.getContentPane().add(makeContents());
61                 _dialog.pack();
62                 _dialog.setVisible(true);
63                 selectAll();
64         }
65
66         /**
67          * @return the contents of the window as a Component
68          */
69         private Component makeContents()
70         {
71                 JPanel mainPanel = new JPanel();
72                 mainPanel.setLayout(new BorderLayout());
73                 mainPanel.add(new JLabel(I18nManager.getText("dialog.selecttracks.intro")), BorderLayout.NORTH);
74                 // track list
75                 final int numTracks = _trackNameList.getNumTracks();
76                 String[] names = new String[numTracks];
77                 for (int i=0; i<numTracks; i++)
78                 {
79                         String name = _trackNameList.getTrackName(i);
80                         if (name == null || name.equals("")) {
81                                 name = I18nManager.getText("dialog.selecttracks.noname");
82                         }
83                         names[i] = name + " (" + _trackNameList.getNumPointsInTrack(i) + ")";
84                 }
85                 _trackList = new JList(names);
86                 _trackList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
87                 mainPanel.add(new JScrollPane(_trackList), BorderLayout.CENTER);
88                 // select all button
89                 JButton selectAllButton = new JButton(I18nManager.getText("button.selectall"));
90                 selectAllButton.addActionListener(new ActionListener() {
91                         public void actionPerformed(ActionEvent e) {
92                                 selectAll();
93                         }
94                 });
95                 JPanel eastPanel = new JPanel();
96                 eastPanel.add(selectAllButton);
97                 mainPanel.add(eastPanel, BorderLayout.EAST);
98
99                 // button panel at bottom
100                 JPanel buttonPanel = new JPanel();
101                 buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
102                 JButton okButton = new JButton(I18nManager.getText("button.ok"));
103                 okButton.addActionListener(new ActionListener() {
104                         public void actionPerformed(ActionEvent e)
105                         {
106                                 finish();
107                         }
108                 });
109                 buttonPanel.add(okButton);
110                 JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
111                 cancelButton.addActionListener(new ActionListener() {
112                         public void actionPerformed(ActionEvent e)
113                         {
114                                 _dialog.dispose();
115                                 _app.informNoDataLoaded();
116                         }
117                 });
118                 buttonPanel.add(cancelButton);
119                 mainPanel.add(buttonPanel, BorderLayout.SOUTH);
120                 mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
121                 return mainPanel;
122         }
123
124         /** @return name key */
125         public String getNameKey() {
126                 return "dialog.selecttracks";
127         }
128
129         /**
130          * Select all the tracks in the list
131          */
132         private void selectAll()
133         {
134                 _trackList.setSelectionInterval(0, _trackNameList.getNumTracks()-1);
135         }
136
137         /**
138          * OK pressed, so finish the load
139          */
140         private void finish()
141         {
142                 _dialog.dispose();
143                 int[] tracks = _trackList.getSelectedIndices();
144                 // Check if all tracks are selected, then don't have to filter at all
145                 if (tracks.length == _trackNameList.getNumTracks()) {
146                         _app.informDataLoaded(_track, _sourceInfo);
147                 }
148                 else
149                 {
150                         // build array of which tracks have been selected
151                         boolean[] selectedTracks = new boolean[_trackNameList.getNumTracks()];
152                         for (int i=0; i<tracks.length; i++) {
153                                 selectedTracks[tracks[i]] = true;
154                         }
155                         // Loop over all points, counting points which survive filter and making flag array
156                         int numPointsSelected = 0;
157                         int currentTrack = -1;
158                         final int totalPoints = _track.getNumPoints();
159                         boolean[] selectedPoints = new boolean[totalPoints];
160                         for (int i=0; i<totalPoints; i++)
161                         {
162                                 final int startOfNextTrack = _trackNameList.getStartIndex(currentTrack+1);
163                                 if (i == startOfNextTrack) {currentTrack++;}
164                                 if (currentTrack < 0 || selectedTracks[currentTrack] || _track.getPoint(i).isWaypoint()) {
165                                         selectedPoints[i] = true;
166                                         numPointsSelected++;
167                                 }
168                         }
169                         // If none of the points have been selected, then load nothing
170                         if (numPointsSelected <= 0) {
171                                 _app.informNoDataLoaded();
172                         }
173                         else
174                         {
175                                 // Create new point array of required length
176                                 DataPoint[] croppedPoints = new DataPoint[numPointsSelected];
177                                 // Loop over all points again, copying surviving ones
178                                 int currPoint = 0;
179                                 for (int i=0; i<totalPoints; i++)
180                                 {
181                                         if (selectedPoints[i]) {
182                                                 croppedPoints[currPoint] = _track.getPoint(i);
183                                                 currPoint++;
184                                         }
185                                 }
186                                 // Construct Track and call informDataLoaded
187                                 Track filteredTrack = new Track(_track.getFieldList(), croppedPoints);
188                                 // Tell source info object which points were selected (pass selectedPoints array)
189                                 _sourceInfo.setPointIndices(selectedPoints);
190                                 _app.informDataLoaded(filteredTrack, _sourceInfo);
191                         }
192                 }
193         }
194 }