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