]> gitweb.fperrin.net Git - GpsPrune.git/blobdiff - src/tim/prune/function/FullRangeDetails.java
Moved source into separate src directory due to popular request
[GpsPrune.git] / src / tim / prune / function / FullRangeDetails.java
diff --git a/src/tim/prune/function/FullRangeDetails.java b/src/tim/prune/function/FullRangeDetails.java
new file mode 100644 (file)
index 0000000..07ef39e
--- /dev/null
@@ -0,0 +1,367 @@
+package tim.prune.function;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import tim.prune.App;
+import tim.prune.GenericFunction;
+import tim.prune.I18nManager;
+import tim.prune.config.Config;
+import tim.prune.data.RangeStats;
+import tim.prune.data.Selection;
+import tim.prune.data.Unit;
+import tim.prune.gui.DisplayUtils;
+import tim.prune.gui.profile.SpeedData;
+
+/**
+ * Class to show the full range details in a separate popup
+ */
+public class FullRangeDetails extends GenericFunction
+{
+       /** Dialog */
+       private JDialog _dialog = null;
+       /** Label for number of points */
+       private JLabel _numPointsLabel = null;
+       /** Label for number of segments */
+       private JLabel _numSegsLabel = null;
+       /** Label for the maximum speed */
+       private JLabel _maxSpeedLabel = null;
+
+       /** Label for heading of "total" column */
+       private JLabel _colTotalLabel = null;
+       /** Label for heading of "segments" column */
+       private JLabel _colSegmentsLabel = null;
+       /** Labels for distances */
+       private JLabel _totalDistanceLabel = null, _movingDistanceLabel = null;
+       /** Labels for durations */
+       private JLabel _totalDurationLabel = null, _movingDurationLabel = null;
+       /** Labels for climbs */
+       private JLabel _totalClimbLabel = null, _movingClimbLabel = null;
+       /** Labels for descents */
+       private JLabel _totalDescentLabel = null, _movingDescentLabel = null;
+       /** Labels for pace */
+       private JLabel _totalPaceLabel = null, _movingPaceLabel = null;
+       /** Labels for gradient */
+       private JLabel _totalGradientLabel = null, _movingGradientLabel = null;
+       /** Labels for speed */
+       private JLabel _totalSpeedLabel, _movingSpeedLabel = null;
+       /** Labels for vertical speed */
+       private JLabel _totalVertSpeedLabel, _movingVertSpeedLabel = null;
+
+
+       /**
+        * Constructor
+        * @param inApp App object
+        */
+       public FullRangeDetails(App inApp)
+       {
+               super(inApp);
+       }
+
+       /** Get the name key */
+       public String getNameKey() {
+               return "function.fullrangedetails";
+       }
+
+       /**
+        * Begin the function
+        */
+       public void begin()
+       {
+               if (_dialog == null)
+               {
+                       _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true);
+                       _dialog.setLocationRelativeTo(_parentFrame);
+                       _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+                       _dialog.getContentPane().add(makeDialogComponents());
+                       _dialog.pack();
+               }
+               updateDetails();
+               _dialog.setVisible(true);
+       }
+
+       /**
+        * Create dialog components
+        * @return Panel containing all gui elements in dialog
+        */
+       private Component makeDialogComponents()
+       {
+               JPanel dialogPanel = new JPanel();
+               dialogPanel.setLayout(new BorderLayout(5, 5));
+               // Label at top
+               JLabel topLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.intro") + ":");
+               topLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+               dialogPanel.add(topLabel, BorderLayout.NORTH);
+
+               // Details panel in middle
+               JPanel midPanel = new JPanel();
+               midPanel.setLayout(new GridLayout(0, 3, 6, 2));
+               midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 15));
+               // Number of points
+               JLabel pointsLabel = new JLabel(I18nManager.getText("details.track.points") + ": ");
+               pointsLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(pointsLabel);
+               _numPointsLabel = new JLabel("100");
+               midPanel.add(_numPointsLabel);
+               midPanel.add(new JLabel(" "));
+               // Number of segments
+               JLabel segLabel = new JLabel(I18nManager.getText("details.range.numsegments") + ": ");
+               segLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(segLabel);
+               _numSegsLabel = new JLabel("100");
+               midPanel.add(_numSegsLabel);
+               midPanel.add(new JLabel(" "));
+               // Maximum speed
+               JLabel maxSpeedLabel = new JLabel(I18nManager.getText("details.range.maxspeed") + ": ");
+               maxSpeedLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(maxSpeedLabel);
+               _maxSpeedLabel = new JLabel("10 km/h");
+               midPanel.add(_maxSpeedLabel);
+               midPanel.add(new JLabel(" "));
+
+               // blank row
+               for (int i=0; i<3; i++) midPanel.add(new JLabel(" "));
+
+               // Row for column headings
+               midPanel.add(new JLabel(" "));
+               _colTotalLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.coltotal"));
+               midPanel.add(_colTotalLabel);
+               _colSegmentsLabel = new JLabel(I18nManager.getText("dialog.fullrangedetails.colsegments"));
+               midPanel.add(_colSegmentsLabel);
+
+               // Distance
+               JLabel distLabel = new JLabel(I18nManager.getText("fieldname.distance") + ": ");
+               distLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(distLabel);
+               _totalDistanceLabel = new JLabel("5 km");
+               midPanel.add(_totalDistanceLabel);
+               _movingDistanceLabel = new JLabel("5 km");
+               midPanel.add(_movingDistanceLabel);
+
+               // Duration
+               JLabel durationLabel = new JLabel(I18nManager.getText("fieldname.duration") + ": ");
+               durationLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(durationLabel);
+               _totalDurationLabel = new JLabel("15 min");
+               midPanel.add(_totalDurationLabel);
+               _movingDurationLabel = new JLabel("15 min");
+               midPanel.add(_movingDurationLabel);
+
+               // Speed
+               JLabel speedLabel = new JLabel(I18nManager.getText("details.range.avespeed") + ": ");
+               speedLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(speedLabel);
+               _totalSpeedLabel = new JLabel("5.5 km/h");
+               midPanel.add(_totalSpeedLabel);
+               _movingSpeedLabel = new JLabel("5.5 km/h");
+               midPanel.add(_movingSpeedLabel);
+
+               // Pace
+               JLabel paceLabel = new JLabel(I18nManager.getText("details.range.pace") + ": ");
+               paceLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(paceLabel);
+               _totalPaceLabel = new JLabel("8 min/km");
+               midPanel.add(_totalPaceLabel);
+               _movingPaceLabel = new JLabel("8 min/km");
+               midPanel.add(_movingPaceLabel);
+
+               // Climb
+               JLabel climbLabel = new JLabel(I18nManager.getText("details.range.climb") + ": ");
+               climbLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(climbLabel);
+               _totalClimbLabel = new JLabel("1000 m");
+               midPanel.add(_totalClimbLabel);
+               _movingClimbLabel = new JLabel("1000 m");
+               midPanel.add(_movingClimbLabel);
+               // Descent
+               JLabel descentLabel = new JLabel(I18nManager.getText("details.range.descent") + ": ");
+               descentLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(descentLabel);
+               _totalDescentLabel = new JLabel("1000 m");
+               midPanel.add(_totalDescentLabel);
+               _movingDescentLabel = new JLabel("1000 m");
+               midPanel.add(_movingDescentLabel);
+
+               // Gradient
+               JLabel gradientLabel = new JLabel(I18nManager.getText("details.range.gradient") + ": ");
+               gradientLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(gradientLabel);
+               _totalGradientLabel = new JLabel("10 %");
+               midPanel.add(_totalGradientLabel);
+               _movingGradientLabel = new JLabel("10 %");
+               midPanel.add(_movingGradientLabel);
+
+               // Vertical speed
+               JLabel vSpeedLabel = new JLabel(I18nManager.getText("fieldname.verticalspeed") + ": ");
+               vSpeedLabel.setHorizontalAlignment(JLabel.RIGHT);
+               midPanel.add(vSpeedLabel);
+               _totalVertSpeedLabel = new JLabel("1 m/s");
+               midPanel.add(_totalVertSpeedLabel);
+               _movingVertSpeedLabel = new JLabel("1 m/s");
+               midPanel.add(_movingVertSpeedLabel);
+
+               dialogPanel.add(midPanel, BorderLayout.CENTER);
+               // button panel at bottom
+               JPanel buttonPanel = new JPanel();
+               buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+               JButton closeButton = new JButton(I18nManager.getText("button.close"));
+               closeButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e)
+                       {
+                               _dialog.dispose();
+                       }
+               });
+               closeButton.addKeyListener(new KeyAdapter() {
+                       public void keyPressed(KeyEvent inE) {
+                               if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();}
+                               super.keyPressed(inE);
+                       }
+               });
+               buttonPanel.add(closeButton);
+               dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
+               return dialogPanel;
+       }
+
+
+       /**
+        * Update the labels with the current details
+        */
+       private void updateDetails()
+       {
+               Selection selection = _app.getTrackInfo().getSelection();
+               // Do the calculations with a separate class
+               RangeStats stats = new RangeStats(_app.getTrackInfo().getTrack(), selection.getStart(), selection.getEnd());
+
+               // Number of points
+               _numPointsLabel.setText("" + stats.getNumPoints());
+               // Number of segments
+               _numSegsLabel.setText("" + stats.getNumSegments());
+               final boolean isMultiSegments = (stats.getNumSegments() > 1);
+               // Set visibility of third column accordingly
+               _movingDistanceLabel.setVisible(isMultiSegments);
+               _movingDurationLabel.setVisible(isMultiSegments || stats.getTimestampsOutOfSequence());
+               // FIXME: What to show if timestamps are out of sequence? Warning message?
+               _movingClimbLabel.setVisible(isMultiSegments);
+               _movingDescentLabel.setVisible(isMultiSegments);
+               _movingSpeedLabel.setVisible(isMultiSegments);
+               _movingPaceLabel.setVisible(isMultiSegments);
+               _movingGradientLabel.setVisible(isMultiSegments);
+               _movingVertSpeedLabel.setVisible(isMultiSegments);
+
+               // Total and moving distance in current units
+               final Unit distUnit = Config.getUnitSet().getDistanceUnit();
+               final String distUnitsStr = I18nManager.getText(distUnit.getShortnameKey());
+               _totalDistanceLabel.setText(DisplayUtils.roundedNumber(stats.getTotalDistance()) + " " + distUnitsStr);
+               _movingDistanceLabel.setText(DisplayUtils.roundedNumber(stats.getMovingDistance()) + " " + distUnitsStr);
+
+               // Duration
+               _totalDurationLabel.setText(DisplayUtils.buildDurationString(stats.getTotalDurationInSeconds()));
+               _movingDurationLabel.setText(DisplayUtils.buildDurationString(stats.getMovingDurationInSeconds()));
+
+               // Climb and descent
+               final Unit altUnit = Config.getUnitSet().getAltitudeUnit();
+               final String altUnitsStr = " " + I18nManager.getText(altUnit.getShortnameKey());
+               if (stats.getTotalAltitudeRange().hasRange()) {
+                       _totalClimbLabel.setText(stats.getTotalAltitudeRange().getClimb(altUnit) + altUnitsStr);
+                       _totalDescentLabel.setText(stats.getTotalAltitudeRange().getDescent(altUnit) + altUnitsStr);
+               }
+               else {
+                       _totalClimbLabel.setText("");
+                       _totalDescentLabel.setText("");
+               }
+               if (stats.getMovingAltitudeRange().hasRange()) {
+                       _movingClimbLabel.setText(stats.getMovingAltitudeRange().getClimb(altUnit) + altUnitsStr);
+                       _movingDescentLabel.setText(stats.getMovingAltitudeRange().getDescent(altUnit) + altUnitsStr);
+               }
+               else {
+                       _movingClimbLabel.setText("");
+                       _movingDescentLabel.setText("");
+               }
+
+               // Overall pace and speed
+               final String speedUnitsStr = I18nManager.getText(Config.getUnitSet().getSpeedUnit().getShortnameKey());
+               long numSecs = stats.getTotalDurationInSeconds();
+               double dist = stats.getTotalDistance();
+               if (numSecs > 0 && dist > 0)
+               {
+                       _totalSpeedLabel.setText(DisplayUtils.roundedNumber(dist/numSecs*3600.0) + " " + speedUnitsStr);
+                       _totalPaceLabel.setText(DisplayUtils.buildDurationString((long) (numSecs/dist))
+                               + " / " + distUnitsStr);
+               }
+               else {
+                       _totalSpeedLabel.setText("");
+                       _totalPaceLabel.setText("");
+               }
+               // and same for within the segments
+               numSecs = stats.getMovingDurationInSeconds();
+               dist = stats.getMovingDistance();
+               if (numSecs > 0 && dist > 0)
+               {
+                       _movingSpeedLabel.setText(DisplayUtils.roundedNumber(dist/numSecs*3600.0) + " " + speedUnitsStr);
+                       _movingPaceLabel.setText(DisplayUtils.buildDurationString((long) (numSecs/dist))
+                               + " / " + distUnitsStr);
+               }
+               else {
+                       _movingSpeedLabel.setText("");
+                       _movingPaceLabel.setText("");
+               }
+
+               // Gradient
+               if (stats.getTotalAltitudeRange().hasRange()) {
+                       _totalGradientLabel.setText(DisplayUtils.formatOneDp(stats.getTotalGradient()) + " %");
+               }
+               else {
+                       _totalGradientLabel.setText("");
+               }
+               if (stats.getMovingAltitudeRange().hasRange()) {
+                       _movingGradientLabel.setText(DisplayUtils.formatOneDp(stats.getMovingGradient()) + " %");
+               }
+               else {
+                       _movingGradientLabel.setText("");
+               }
+
+               // Maximum speed
+               SpeedData speeds = new SpeedData(_app.getTrackInfo().getTrack());
+               speeds.init(Config.getUnitSet());
+               double maxSpeed = 0.0;
+               for (int i=selection.getStart(); i<=selection.getEnd(); i++)
+               {
+                       if (speeds.hasData(i) && (speeds.getData(i) > maxSpeed)) {
+                               maxSpeed = speeds.getData(i);
+                       }
+               }
+               if (maxSpeed > 0.0) {
+                       _maxSpeedLabel.setText(DisplayUtils.roundedNumber(maxSpeed) + " " + speedUnitsStr);
+               }
+               else {
+                       _maxSpeedLabel.setText("");
+               }
+
+               // vertical speed
+               final String vertSpeedUnitsStr = I18nManager.getText(Config.getUnitSet().getVerticalSpeedUnit().getShortnameKey());
+               if (stats.getMovingAltitudeRange().hasRange() && stats.getTotalDurationInSeconds() > 0)
+               {
+                       // got an altitude and time - do totals
+                       _totalVertSpeedLabel.setText(DisplayUtils.roundedNumber(stats.getTotalVerticalSpeed()) + " " + vertSpeedUnitsStr);
+                       _movingVertSpeedLabel.setText(DisplayUtils.roundedNumber(stats.getMovingVerticalSpeed()) + " " + vertSpeedUnitsStr);
+               }
+               else
+               {
+                       // no vertical speed available
+                       _totalVertSpeedLabel.setText("");
+                       _movingVertSpeedLabel.setText("");
+               }
+       }
+}