]> gitweb.fperrin.net Git - GpsPrune.git/blob - src/tim/prune/function/FullRangeDetails.java
07ef39e36a1151d06af5b4f2238857c278bc7d44
[GpsPrune.git] / src / tim / prune / function / FullRangeDetails.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.GridLayout;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.awt.event.KeyAdapter;
10 import java.awt.event.KeyEvent;
11
12 import javax.swing.BorderFactory;
13 import javax.swing.JButton;
14 import javax.swing.JDialog;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17
18 import tim.prune.App;
19 import tim.prune.GenericFunction;
20 import tim.prune.I18nManager;
21 import tim.prune.config.Config;
22 import tim.prune.data.RangeStats;
23 import tim.prune.data.Selection;
24 import tim.prune.data.Unit;
25 import tim.prune.gui.DisplayUtils;
26 import tim.prune.gui.profile.SpeedData;
27
28 /**
29  * Class to show the full range details in a separate popup
30  */
31 public class FullRangeDetails extends GenericFunction
32 {
33         /** Dialog */
34         private JDialog _dialog = null;
35         /** Label for number of points */
36         private JLabel _numPointsLabel = null;
37         /** Label for number of segments */
38         private JLabel _numSegsLabel = null;
39         /** Label for the maximum speed */
40         private JLabel _maxSpeedLabel = null;
41
42         /** Label for heading of "total" column */
43         private JLabel _colTotalLabel = null;
44         /** Label for heading of "segments" column */
45         private JLabel _colSegmentsLabel = null;
46         /** Labels for distances */
47         private JLabel _totalDistanceLabel = null, _movingDistanceLabel = null;
48         /** Labels for durations */
49         private JLabel _totalDurationLabel = null, _movingDurationLabel = null;
50         /** Labels for climbs */
51         private JLabel _totalClimbLabel = null, _movingClimbLabel = null;
52         /** Labels for descents */
53         private JLabel _totalDescentLabel = null, _movingDescentLabel = null;
54         /** Labels for pace */
55         private JLabel _totalPaceLabel = null, _movingPaceLabel = null;
56         /** Labels for gradient */
57         private JLabel _totalGradientLabel = null, _movingGradientLabel = null;
58         /** Labels for speed */
59         private JLabel _totalSpeedLabel, _movingSpeedLabel = null;
60         /** Labels for vertical speed */
61         private JLabel _totalVertSpeedLabel, _movingVertSpeedLabel = null;
62
63
64         /**
65          * Constructor
66          * @param inApp App object
67          */
68         public FullRangeDetails(App inApp)
69         {
70                 super(inApp);
71         }
72
73         /** Get the name key */
74         public String getNameKey() {
75                 return "function.fullrangedetails";
76         }
77
78         /**
79          * Begin the function
80          */
81         public void begin()
82         {
83                 if (_dialog == null)
84                 {
85                         _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
86                         _dialog.setLocationRelativeTo(_parentFrame);
87                         _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
88                         _dialog.getContentPane().add(makeDialogComponents());
89                         _dialog.pack();
90                 }
91                 updateDetails();
92                 _dialog.setVisible(true);
93         }
94
95         /**
96          * Create dialog components
97          * @return Panel containing all gui elements in dialog
98          */
99         private Component makeDialogComponents()
100         {
101                 JPanel dialogPanel = new JPanel();
102                 dialogPanel.setLayout(new BorderLayout(5, 5));
103                 // Label at top
104                 JLabel topLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.intro") + ":");
105                 topLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
106                 dialogPanel.add(topLabel, BorderLayout.NORTH);
107
108                 // Details panel in middle
109                 JPanel midPanel = new JPanel();
110                 midPanel.setLayout(new GridLayout(0, 3, 6, 2));
111                 midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
112                 // Number of points
113                 JLabel pointsLabel = new JLabel(I18nManager.getText("details.track.points") + ": ");
114                 pointsLabel.setHorizontalAlignment(JLabel.RIGHT);
115                 midPanel.add(pointsLabel);
116                 _numPointsLabel = new JLabel("100");
117                 midPanel.add(_numPointsLabel);
118                 midPanel.add(new JLabel(" "));
119                 // Number of segments
120                 JLabel segLabel = new JLabel(I18nManager.getText("details.range.numsegments") + ": ");
121                 segLabel.setHorizontalAlignment(JLabel.RIGHT);
122                 midPanel.add(segLabel);
123                 _numSegsLabel = new JLabel("100");
124                 midPanel.add(_numSegsLabel);
125                 midPanel.add(new JLabel(" "));
126                 // Maximum speed
127                 JLabel maxSpeedLabel = new JLabel(I18nManager.getText("details.range.maxspeed") + ": ");
128                 maxSpeedLabel.setHorizontalAlignment(JLabel.RIGHT);
129                 midPanel.add(maxSpeedLabel);
130                 _maxSpeedLabel = new JLabel("10 km/h");
131                 midPanel.add(_maxSpeedLabel);
132                 midPanel.add(new JLabel(" "));
133
134                 // blank row
135                 for (int i=0; i<3; i++) midPanel.add(new JLabel(" "));
136
137                 // Row for column headings
138                 midPanel.add(new JLabel(" "));
139                 _colTotalLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.coltotal"));
140                 midPanel.add(_colTotalLabel);
141                 _colSegmentsLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.colsegments"));
142                 midPanel.add(_colSegmentsLabel);
143
144                 // Distance
145                 JLabel distLabel = new JLabel(I18nManager.getText("fieldname.distance") + ": ");
146                 distLabel.setHorizontalAlignment(JLabel.RIGHT);
147                 midPanel.add(distLabel);
148                 _totalDistanceLabel = new JLabel("5 km");
149                 midPanel.add(_totalDistanceLabel);
150                 _movingDistanceLabel = new JLabel("5 km");
151                 midPanel.add(_movingDistanceLabel);
152
153                 // Duration
154                 JLabel durationLabel = new JLabel(I18nManager.getText("fieldname.duration") + ": ");
155                 durationLabel.setHorizontalAlignment(JLabel.RIGHT);
156                 midPanel.add(durationLabel);
157                 _totalDurationLabel = new JLabel("15 min");
158                 midPanel.add(_totalDurationLabel);
159                 _movingDurationLabel = new JLabel("15 min");
160                 midPanel.add(_movingDurationLabel);
161
162                 // Speed
163                 JLabel speedLabel = new JLabel(I18nManager.getText("details.range.avespeed") + ": ");
164                 speedLabel.setHorizontalAlignment(JLabel.RIGHT);
165                 midPanel.add(speedLabel);
166                 _totalSpeedLabel = new JLabel("5.5 km/h");
167                 midPanel.add(_totalSpeedLabel);
168                 _movingSpeedLabel = new JLabel("5.5 km/h");
169                 midPanel.add(_movingSpeedLabel);
170
171                 // Pace
172                 JLabel paceLabel = new JLabel(I18nManager.getText("details.range.pace") + ": ");
173                 paceLabel.setHorizontalAlignment(JLabel.RIGHT);
174                 midPanel.add(paceLabel);
175                 _totalPaceLabel = new JLabel("8 min/km");
176                 midPanel.add(_totalPaceLabel);
177                 _movingPaceLabel = new JLabel("8 min/km");
178                 midPanel.add(_movingPaceLabel);
179
180                 // Climb
181                 JLabel climbLabel = new JLabel(I18nManager.getText("details.range.climb") + ": ");
182                 climbLabel.setHorizontalAlignment(JLabel.RIGHT);
183                 midPanel.add(climbLabel);
184                 _totalClimbLabel = new JLabel("1000 m");
185                 midPanel.add(_totalClimbLabel);
186                 _movingClimbLabel = new JLabel("1000 m");
187                 midPanel.add(_movingClimbLabel);
188                 // Descent
189                 JLabel descentLabel = new JLabel(I18nManager.getText("details.range.descent") + ": ");
190                 descentLabel.setHorizontalAlignment(JLabel.RIGHT);
191                 midPanel.add(descentLabel);
192                 _totalDescentLabel = new JLabel("1000 m");
193                 midPanel.add(_totalDescentLabel);
194                 _movingDescentLabel = new JLabel("1000 m");
195                 midPanel.add(_movingDescentLabel);
196
197                 // Gradient
198                 JLabel gradientLabel = new JLabel(I18nManager.getText("details.range.gradient") + ": ");
199                 gradientLabel.setHorizontalAlignment(JLabel.RIGHT);
200                 midPanel.add(gradientLabel);
201                 _totalGradientLabel = new JLabel("10 %");
202                 midPanel.add(_totalGradientLabel);
203                 _movingGradientLabel = new JLabel("10 %");
204                 midPanel.add(_movingGradientLabel);
205
206                 // Vertical speed
207                 JLabel vSpeedLabel = new JLabel(I18nManager.getText("fieldname.verticalspeed") + ": ");
208                 vSpeedLabel.setHorizontalAlignment(JLabel.RIGHT);
209                 midPanel.add(vSpeedLabel);
210                 _totalVertSpeedLabel = new JLabel("1 m/s");
211                 midPanel.add(_totalVertSpeedLabel);
212                 _movingVertSpeedLabel = new JLabel("1 m/s");
213                 midPanel.add(_movingVertSpeedLabel);
214
215                 dialogPanel.add(midPanel, BorderLayout.CENTER);
216                 // button panel at bottom
217                 JPanel buttonPanel = new JPanel();
218                 buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
219                 JButton closeButton = new JButton(I18nManager.getText("button.close"));
220                 closeButton.addActionListener(new ActionListener() {
221                         public void actionPerformed(ActionEvent e)
222                         {
223                                 _dialog.dispose();
224                         }
225                 });
226                 closeButton.addKeyListener(new KeyAdapter() {
227                         public void keyPressed(KeyEvent inE) {
228                                 if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();}
229                                 super.keyPressed(inE);
230                         }
231                 });
232                 buttonPanel.add(closeButton);
233                 dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
234                 return dialogPanel;
235         }
236
237
238         /**
239          * Update the labels with the current details
240          */
241         private void updateDetails()
242         {
243                 Selection selection = _app.getTrackInfo().getSelection();
244                 // Do the calculations with a separate class
245                 RangeStats stats = new RangeStats(_app.getTrackInfo().getTrack(), selection.getStart(), selection.getEnd());
246
247                 // Number of points
248                 _numPointsLabel.setText("" + stats.getNumPoints());
249                 // Number of segments
250                 _numSegsLabel.setText("" + stats.getNumSegments());
251                 final boolean isMultiSegments = (stats.getNumSegments() > 1);
252                 // Set visibility of third column accordingly
253                 _movingDistanceLabel.setVisible(isMultiSegments);
254                 _movingDurationLabel.setVisible(isMultiSegments || stats.getTimestampsOutOfSequence());
255                 // FIXME: What to show if timestamps are out of sequence? Warning message?
256                 _movingClimbLabel.setVisible(isMultiSegments);
257                 _movingDescentLabel.setVisible(isMultiSegments);
258                 _movingSpeedLabel.setVisible(isMultiSegments);
259                 _movingPaceLabel.setVisible(isMultiSegments);
260                 _movingGradientLabel.setVisible(isMultiSegments);
261                 _movingVertSpeedLabel.setVisible(isMultiSegments);
262
263                 // Total and moving distance in current units
264                 final Unit distUnit = Config.getUnitSet().getDistanceUnit();
265                 final String distUnitsStr = I18nManager.getText(distUnit.getShortnameKey());
266                 _totalDistanceLabel.setText(DisplayUtils.roundedNumber(stats.getTotalDistance()) + " " + distUnitsStr);
267                 _movingDistanceLabel.setText(DisplayUtils.roundedNumber(stats.getMovingDistance()) + " " + distUnitsStr);
268
269                 // Duration
270                 _totalDurationLabel.setText(DisplayUtils.buildDurationString(stats.getTotalDurationInSeconds()));
271                 _movingDurationLabel.setText(DisplayUtils.buildDurationString(stats.getMovingDurationInSeconds()));
272
273                 // Climb and descent
274                 final Unit altUnit = Config.getUnitSet().getAltitudeUnit();
275                 final String altUnitsStr = " " + I18nManager.getText(altUnit.getShortnameKey());
276                 if (stats.getTotalAltitudeRange().hasRange()) {
277                         _totalClimbLabel.setText(stats.getTotalAltitudeRange().getClimb(altUnit) + altUnitsStr);
278                         _totalDescentLabel.setText(stats.getTotalAltitudeRange().getDescent(altUnit) + altUnitsStr);
279                 }
280                 else {
281                         _totalClimbLabel.setText("");
282                         _totalDescentLabel.setText("");
283                 }
284                 if (stats.getMovingAltitudeRange().hasRange()) {
285                         _movingClimbLabel.setText(stats.getMovingAltitudeRange().getClimb(altUnit) + altUnitsStr);
286                         _movingDescentLabel.setText(stats.getMovingAltitudeRange().getDescent(altUnit) + altUnitsStr);
287                 }
288                 else {
289                         _movingClimbLabel.setText("");
290                         _movingDescentLabel.setText("");
291                 }
292
293                 // Overall pace and speed
294                 final String speedUnitsStr = I18nManager.getText(Config.getUnitSet().getSpeedUnit().getShortnameKey());
295                 long numSecs = stats.getTotalDurationInSeconds();
296                 double dist = stats.getTotalDistance();
297                 if (numSecs > 0 && dist > 0)
298                 {
299                         _totalSpeedLabel.setText(DisplayUtils.roundedNumber(dist/numSecs*3600.0) + " " + speedUnitsStr);
300                         _totalPaceLabel.setText(DisplayUtils.buildDurationString((long) (numSecs/dist))
301                                 + " / " + distUnitsStr);
302                 }
303                 else {
304                         _totalSpeedLabel.setText("");
305                         _totalPaceLabel.setText("");
306                 }
307                 // and same for within the segments
308                 numSecs = stats.getMovingDurationInSeconds();
309                 dist = stats.getMovingDistance();
310                 if (numSecs > 0 && dist > 0)
311                 {
312                         _movingSpeedLabel.setText(DisplayUtils.roundedNumber(dist/numSecs*3600.0) + " " + speedUnitsStr);
313                         _movingPaceLabel.setText(DisplayUtils.buildDurationString((long) (numSecs/dist))
314                                 + " / " + distUnitsStr);
315                 }
316                 else {
317                         _movingSpeedLabel.setText("");
318                         _movingPaceLabel.setText("");
319                 }
320
321                 // Gradient
322                 if (stats.getTotalAltitudeRange().hasRange()) {
323                         _totalGradientLabel.setText(DisplayUtils.formatOneDp(stats.getTotalGradient()) + " %");
324                 }
325                 else {
326                         _totalGradientLabel.setText("");
327                 }
328                 if (stats.getMovingAltitudeRange().hasRange()) {
329                         _movingGradientLabel.setText(DisplayUtils.formatOneDp(stats.getMovingGradient()) + " %");
330                 }
331                 else {
332                         _movingGradientLabel.setText("");
333                 }
334
335                 // Maximum speed
336                 SpeedData speeds = new SpeedData(_app.getTrackInfo().getTrack());
337                 speeds.init(Config.getUnitSet());
338                 double maxSpeed = 0.0;
339                 for (int i=selection.getStart(); i<=selection.getEnd(); i++)
340                 {
341                         if (speeds.hasData(i) && (speeds.getData(i) > maxSpeed)) {
342                                 maxSpeed = speeds.getData(i);
343                         }
344                 }
345                 if (maxSpeed > 0.0) {
346                         _maxSpeedLabel.setText(DisplayUtils.roundedNumber(maxSpeed) + " " + speedUnitsStr);
347                 }
348                 else {
349                         _maxSpeedLabel.setText("");
350                 }
351
352                 // vertical speed
353                 final String vertSpeedUnitsStr = I18nManager.getText(Config.getUnitSet().getVerticalSpeedUnit().getShortnameKey());
354                 if (stats.getMovingAltitudeRange().hasRange() && stats.getTotalDurationInSeconds() > 0)
355                 {
356                         // got an altitude and time - do totals
357                         _totalVertSpeedLabel.setText(DisplayUtils.roundedNumber(stats.getTotalVerticalSpeed()) + " " + vertSpeedUnitsStr);
358                         _movingVertSpeedLabel.setText(DisplayUtils.roundedNumber(stats.getMovingVerticalSpeed()) + " " + vertSpeedUnitsStr);
359                 }
360                 else
361                 {
362                         // no vertical speed available
363                         _totalVertSpeedLabel.setText("");
364                         _movingVertSpeedLabel.setText("");
365                 }
366         }
367 }