Subversion Repositories public

Compare Revisions

Ignore whitespace Rev 313 → Rev 314

/sportwatcher/trunk/config.h.cmake
4,7 → 4,7
/* config.h. Generated by cmake from config.h.cmake */
 
#define PACKAGE "sportwatcher"
#define VERSION "0.7"
#define VERSION "0.7.1"
 
#cmakedefine MAPNIK_PLUGIN_BASE "${MAPNIK_PLUGIN_PATH}"
#cmakedefine MAPNIK_PLUGINS "${MAPNIK_PLUGIN_PATH}/input"
/sportwatcher/trunk/ChangeLog
1,3 → 1,13
Version: 0.7.1
==============
 
Added to "import.cpp" a callback function. It is used ba class
"sportwatcherwidget" and enables the import to save each track sepeartely.
This allows the correct reading of multisport events.
 
Added to "import.cpp" recognizing of XML attribute "Sport". This attribute
describes the type of sport a Garmin watch have recorded.
 
Version: 0.7
============
 
/sportwatcher/trunk/src/import.h
1,5 → 1,5
/***************************************************************************
* Copyright (C) 2007 - 2009 by Andreas Theofilu *
* Copyright (C) 2007 - 2013 by Andreas Theofilu *
* andreas@theosys.at *
* *
* This program is free software; you can redistribute it and/or modify *
26,6 → 26,7
 
#include "garmin.h"
#include "disassemble.h"
#include "callback.h"
 
#define eMax 7
 
67,6 → 68,8
void setFile (const QString &sfile);
void setDisassemble (disassemble *dis) { ds = dis; };
 
void connectCallback(CallbackInterface *cb) { m_cb = cb; }
 
int import ();
garmin_data *getGarminData() { if (gmn) return gmn; else return 0; };
 
77,6 → 80,7
bool startElement (const QString&, const QString&, const QString& , const QXmlAttributes&);
bool endElement (const QString&, const QString&, const QString&);
bool characters (const QString&);
void saveImported(void *g);
 
protected:
unsigned int garmin_time (const QString&);
83,6 → 87,9
QString getKey (int pos);
 
private:
CallbackInterface *m_cb;
bool doCallback;
gmn_import *inst;
disassemble *ds;
QFile file;
bool qfstat, qfopen;
/sportwatcher/trunk/src/sportwatcherwidget.h
1,5 → 1,5
/***************************************************************************
* Copyright (C) 2007 - 2009 by Andreas Theofilu *
* Copyright (C) 2007 - 2013 by Andreas Theofilu *
* andreas@theosys.at *
* *
* This program is free software; you can redistribute it and/or modify *
33,163 → 33,167
#include <KLocale>
 
#if defined HAVE_GDAL
#include <gdal/gdal_priv.h>
#include <gdal/gdal_priv.h>
#endif
 
#include "garmin.h"
#include "managefile.h"
#include "disassemble.h"
#include "import.h"
 
#include <QtGui/QWidget>
#include <QTreeWidget>
#include "ui_sportwatcherwidgetbase.h"
 
typedef enum {
MPT_BMP = 0,
MPT_SHP = 1,
MPT_VRT = 2,
MPT_GIF = 3,
MPT_PNG = 4,
MPT_SGI = 5,
MPT_TIF = 6,
MPT_WMS = 7,
MPT_OSM = 8
typedef enum
{
MPT_BMP = 0,
MPT_SHP = 1,
MPT_VRT = 2,
MPT_GIF = 3,
MPT_PNG = 4,
MPT_SGI = 5,
MPT_TIF = 6,
MPT_WMS = 7,
MPT_OSM = 8
} MPT;
 
typedef struct GEORECT
{
double llat;
double llon;
double rlat;
double rlon;
int width;
int height;
double llat;
double llon;
double rlat;
double rlon;
int width;
int height;
} GEORECT;
 
typedef struct AVGHEIGHT
{
double alt; // Altitude
int pos; // Position in the chain, starting with 0
struct AVGHEIGHT *prev;
struct AVGHEIGHT *next;
double alt; // Altitude
int pos; // Position in the chain, starting with 0
struct AVGHEIGHT *prev;
struct AVGHEIGHT *next;
} AVGHEIGHT;
 
//class sportwatcherWidget : public QWidget, public Ui::sportwatcherWidgetBase
class sportwatcherWidget : public QWidget, public Ui::sportwatcherWidgetBase
class sportwatcherWidget : public QWidget, public Ui::sportwatcherWidgetBase, public CallbackInterface
{
Q_OBJECT
Q_OBJECT
 
public:
sportwatcherWidget(QWidget *parent = 0);
~sportwatcherWidget();
/* $PUBLIC_FUNCTIONS$ */
void Initialize();
sportwatcherWidget (QWidget *parent = 0);
~sportwatcherWidget();
/* $PUBLIC_FUNCTIONS$ */
void Initialize();
virtual int cbiCallbackFunction(void *g) { saveImported(g); return 0; }
void saveImported (void *g); // Callback function
 
private:
Ui::sportwatcherWidgetBase ui_sportwatcherWidgetBase;
Ui::sportwatcherWidgetBase ui_sportwatcherWidgetBase;
 
public slots:
/* $PUBLIC_SLOTS$ */
void btFullscreenSlot();
void btGlasMinusSlot();
void btGlasPlusSlot();
void btHandSlot();
void btGlasSlot();
void btFlagSlot();
void liLapsSlot(Q3ListViewItem *item);
void liActivitiesSlot(QTreeWidgetItem *item, int col);
void tabViewSlot(int tab);
void filePrint();
void fileSaveAs();
void fileSave();
void fileOpen();
void fileImport();
void fileNew();
void editRename();
void extrasSaveHR();
void extrasSettings();
void extrasWMSSettings();
void kcbCurveSlot(int idx);
/* $PUBLIC_SLOTS$ */
void btFullscreenSlot();
void btGlasMinusSlot();
void btGlasPlusSlot();
void btHandSlot();
void btGlasSlot();
void btFlagSlot();
void liLapsSlot ( Q3ListViewItem *item );
void liActivitiesSlot ( QTreeWidgetItem *item, int col );
void tabViewSlot ( int tab );
void filePrint();
void fileSaveAs();
void fileSave();
void fileOpen();
void fileImport();
void fileNew();
void editRename();
void extrasSaveHR();
void extrasSettings();
void extrasWMSSettings();
void kcbCurveSlot ( int idx );
 
protected:
/* $PROTECTED_FUNCTIONS$ */
void destroy();
void showLaps();
void showTrack();
void showTrack(int zoom);
void showTrack(int zoom, const QRect &pan, LAP *lap);
void showCurves();
void showCurves(LAP *lap);
void showThreeCurve(int pw=0, int ph=0);
void resizeEvent(QResizeEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
/* $PROTECTED_FUNCTIONS$ */
void destroy();
void showLaps();
void showTrack();
void showTrack ( int zoom );
void showTrack ( int zoom, const QRect &pan, LAP *lap );
void showCurves();
void showCurves ( LAP *lap );
void showThreeCurve ( int pw=0, int ph=0 );
void resizeEvent ( QResizeEvent *e );
void mouseMoveEvent ( QMouseEvent *e );
void mousePressEvent ( QMouseEvent *e );
void mouseReleaseEvent ( QMouseEvent *e );
 
protected:
QTimer timer;
QTimer timer;
 
private:
void getActivities();
QDateTime *garmin_dtime (uint32 t);
bool writeTag(const QFile &fn, const QString &str, int indent);
double getAvgAlt (AVGHEIGHT *avgHeight, int pos);
AVGHEIGHT *getAvgPtr (AVGHEIGHT *avgHeight, int pos);
void saveGPX(const QString &fn);
void saveOSM(const QString &fn);
QTreeWidgetItem *findElement(QTreeWidget *wdg, const QString &val);
void drawGrHR (int x, int y);
void drawGrElev (int x, int y);
void drawGrSpeed (int x, int y);
qreal milToPixel(qreal, QPrinter &pr, bool dir=false);
#if defined HAVE_GDAL
bool writeWMSTag(double llat, double llon, double rlat, double rlon, int width, int height);
bool transCoords (double *x1, double *y1, double *x2, double *y2, int code, int width, int height, bool square);
QString *getProjection (int isrs, QString *srs);
bool warpImage(QString fn, QString *fName);
#endif
void getActivities();
QDateTime *garmin_dtime ( uint32 t );
bool writeTag ( const QFile &fn, const QString &str, int indent );
double getAvgAlt ( AVGHEIGHT *avgHeight, int pos );
AVGHEIGHT *getAvgPtr ( AVGHEIGHT *avgHeight, int pos );
void saveGPX ( const QString &fn );
void saveOSM ( const QString &fn );
QTreeWidgetItem *findElement ( QTreeWidget *wdg, const QString &val );
void drawGrHR ( int x, int y );
void drawGrElev ( int x, int y );
void drawGrSpeed ( int x, int y );
qreal milToPixel ( qreal, QPrinter &pr, bool dir=false );
#if defined HAVE_GDAL
bool writeWMSTag ( double llat, double llon, double rlat, double rlon, int width, int height );
bool transCoords ( double *x1, double *y1, double *x2, double *y2, int code, int width, int height, bool square );
QString *getProjection ( int isrs, QString *srs );
bool warpImage ( QString fn, QString *fName );
#endif
 
private:
QWidget *mama;
QPixmap pmProfile, pmMap, pmHR, pmElevation, pmSpeed;
QPixmap pmPrMap, prHR, prElevation, prSpeed; // These are used for printing
QDateTime StartTime;
QStringList files;
QRect mapPan;
KLocale *kl; // This is for translating date and time to the locale
manageFile spw;
disassemble ds;
garmin_data *gmn;
int min_hr, max_hr, avg_hr;
int zfactor;
double min_height, max_height;
double min_speed, max_speed;
double total_distance;
double oldTransX, oldTransY;
unsigned long max_time;
bool stateHand, stateFlag, stateGlas;
int lmbPressed;
LAP *mapLap;
int curTab;
bool tabDirt0, tabDirt1, tabDirt2, tabDirt3;
bool ActivePrint;
QPainter printArea;
#if defined HAVE_GDAL
GDALDataset *poDataset;
int mFactor;
GEORECT geoRect;
#endif
QWidget *mama;
QPixmap pmProfile, pmMap, pmHR, pmElevation, pmSpeed;
QPixmap pmPrMap, prHR, prElevation, prSpeed; // These are used for printing
QDateTime StartTime;
QStringList files;
QRect mapPan;
KLocale *kl; // This is for translating date and time to the locale
manageFile spw;
disassemble ds;
garmin_data *gmn;
int min_hr, max_hr, avg_hr;
int zfactor;
double min_height, max_height;
double min_speed, max_speed;
double total_distance;
double oldTransX, oldTransY;
unsigned long max_time;
bool stateHand, stateFlag, stateGlas;
int lmbPressed;
LAP *mapLap;
int curTab;
bool tabDirt0, tabDirt1, tabDirt2, tabDirt3;
bool ActivePrint;
QPainter printArea;
#if defined HAVE_GDAL
GDALDataset *poDataset;
int mFactor;
GEORECT geoRect;
#endif
 
private:
/* Config Parameters */
int lower1, lower2, lower3;
int upper1, upper2, upper3;
int MaxHr, restHr;
int vo2max, weight, sampleTime;
int Units, MapType;
bool Serial, Contour, Forerunner;
bool DIRTY;
QString Device, Data, HRM, MAP;
/* Config Parameters */
int lower1, lower2, lower3;
int upper1, upper2, upper3;
int MaxHr, restHr;
int vo2max, weight, sampleTime;
int Units, MapType;
bool Serial, Contour, Forerunner;
bool DIRTY;
QString Device, Data, HRM, MAP;
};
 
#endif
/sportwatcher/trunk/src/import.cpp
1,5 → 1,5
/***************************************************************************
* Copyright (C) 2007 - 2009 by Andreas Theofilu *
* Copyright (C) 2007 - 2013 by Andreas Theofilu *
* andreas@theosys.at *
* *
* This program is free software; you can redistribute it and/or modify *
20,6 → 20,7
#include <string.h>
#include <math.h>
 
#include <iostream>
#include <qlistview.h>
#include <qdatetime.h>
#include <QXmlReader>
28,131 → 29,132
 
#include "import.h"
 
#define FLD_NAME 1
#define FLD_TOTALTIMESECONDS 2
#define FLD_DISTANCEMETERS 3
#define FLD_LATITUDEDEGREES 4
#define FLD_LONGITUDEDEGREES 5
#define FLD_VALUE 6
#define FLD_INTENSITY 7
#define FLD_TIME 8
#define FLD_ALTITUDEMETERS 9
#define FLD_SENSORSTATE 10
#define FLD_STARTTIME 11
#define FLD_AVERAGECADENCE 12
#define FLD_SPORTTYPE 13
#define FLD_VERSIONMAJOR 14
#define FLD_VERSIONMINOR 15
#define FLD_BUILDMAJOR 16
#define FLD_BUILDMINOR 17
#define FLD_TYPE 18
#define FLD_BUILDER 19
#define FLD_LANGID 20
#define FLD_PARTNUMBER 21
#define FLD_CADENCE 22
#define FLD_MAXSPEED 23
#define FLD_CALORIES 24
#define FLD_ID 25
#define FLD_TRIGGERMETHOD 26
#define FLD_TPX 27
#define FLD_UNITID 28
#define FLD_PRODUCTID 29
#define FLD_NOTES 30
#define FLD_NAME 1
#define FLD_TOTALTIMESECONDS 2
#define FLD_DISTANCEMETERS 3
#define FLD_LATITUDEDEGREES 4
#define FLD_LONGITUDEDEGREES 5
#define FLD_VALUE 6
#define FLD_INTENSITY 7
#define FLD_TIME 8
#define FLD_ALTITUDEMETERS 9
#define FLD_SENSORSTATE 10
#define FLD_STARTTIME 11
#define FLD_AVERAGECADENCE 12
#define FLD_SPORTTYPE 13
#define FLD_VERSIONMAJOR 14
#define FLD_VERSIONMINOR 15
#define FLD_BUILDMAJOR 16
#define FLD_BUILDMINOR 17
#define FLD_TYPE 18
#define FLD_BUILDER 19
#define FLD_LANGID 20
#define FLD_PARTNUMBER 21
#define FLD_CADENCE 22
#define FLD_MAXSPEED 23
#define FLD_CALORIES 24
#define FLD_ID 25
#define FLD_TRIGGERMETHOD 26
#define FLD_TPX 27
#define FLD_UNITID 28
#define FLD_PRODUCTID 29
#define FLD_NOTES 30
 
#define CON_COURSES 100
#define CON_COURSE 101
#define CON_LAP 102
#define CON_BEGINPOSITION 103
#define CON_ENDPOSITION 104
#define CON_AVERAGEHEARTRATEBPM 105
#define CON_MAXIMUMHEARTRATEBPM 106
#define CON_TRACK 107
#define CON_TRACKPOINT 108
#define CON_POSITION 109
#define CON_HEARTRATEBPM 110
#define CON_AUTHOR 111
#define CON_VERSION 112
#define CON_BUILD 113
#define CON_ACTIVITY 114
#define CON_EXTENSIONS 115
#define CON_CREATOR 116
#define CON_MULTISPORTSESSION 117
#define CON_FIRSTSPORT 118
#define CON_NEXTSPORT 119
#define CON_TRAINING 120
#define CON_QUICKWORKOUTRESULTS 121
#define CON_COURSES 100
#define CON_COURSE 101
#define CON_LAP 102
#define CON_BEGINPOSITION 103
#define CON_ENDPOSITION 104
#define CON_AVERAGEHEARTRATEBPM 105
#define CON_MAXIMUMHEARTRATEBPM 106
#define CON_TRACK 107
#define CON_TRACKPOINT 108
#define CON_POSITION 109
#define CON_HEARTRATEBPM 110
#define CON_AUTHOR 111
#define CON_VERSION 112
#define CON_BUILD 113
#define CON_ACTIVITY 114
#define CON_EXTENSIONS 115
#define CON_CREATOR 116
#define CON_MULTISPORTSESSION 117
#define CON_FIRSTSPORT 118
#define CON_NEXTSPORT 119
#define CON_TRAINING 120
#define CON_QUICKWORKOUTRESULTS 121
 
#define ATT_CADENCESENSOR 200
#define ATT_CADENCESENSOR 200
 
#define STOPSTOP 0
#define STOPSTOP 0
 
KEYS keys[] = {
KEYS keys[] =
{
/* Fields */
{ FLD_NAME, QString("name") },
{ FLD_NAME, QString("name") },
{ FLD_TOTALTIMESECONDS, QString("TotalTimeSeconds") },
{ FLD_DISTANCEMETERS, QString("DistanceMeters") },
{ FLD_LATITUDEDEGREES, QString("LatitudeDegrees") },
{ FLD_LONGITUDEDEGREES, QString("LongitudeDegrees") },
{ FLD_VALUE, QString("Value") },
{ FLD_INTENSITY, QString("Intensity") },
{ FLD_TIME, QString("Time") },
{ FLD_VALUE, QString("Value") },
{ FLD_INTENSITY, QString("Intensity") },
{ FLD_TIME, QString("Time") },
{ FLD_ALTITUDEMETERS, QString("AltitudeMeters") },
{ FLD_SENSORSTATE, QString("SensorState") },
{ FLD_STARTTIME, QString("StartTime") },
{ FLD_SENSORSTATE, QString("SensorState") },
{ FLD_STARTTIME, QString("StartTime") },
{ FLD_AVERAGECADENCE, QString("AverageCadence") },
{ FLD_SPORTTYPE, QString("SportType") },
{ FLD_VERSIONMAJOR, QString("VersionMajor") },
{ FLD_VERSIONMINOR, QString("VersionMinor") },
{ FLD_BUILDMAJOR, QString("BuildMajor") },
{ FLD_BUILDMINOR, QString("BuildMinor") },
{ FLD_TYPE, QString("Type") },
{ FLD_BUILDER, QString("Builder") },
{ FLD_LANGID, QString("LangID") },
{ FLD_PARTNUMBER, QString("PartNumber") },
{ FLD_CADENCE, QString("Cadence") },
{ FLD_CALORIES, QString("Calories") },
{ FLD_MAXSPEED, QString("MaximumSpeed") },
{ FLD_ID, QString("Id") },
{ FLD_SPORTTYPE, QString("SportType") },
{ FLD_VERSIONMAJOR, QString("VersionMajor") },
{ FLD_VERSIONMINOR, QString("VersionMinor") },
{ FLD_BUILDMAJOR, QString("BuildMajor") },
{ FLD_BUILDMINOR, QString("BuildMinor") },
{ FLD_TYPE, QString("Type") },
{ FLD_BUILDER, QString("Builder") },
{ FLD_LANGID, QString("LangID") },
{ FLD_PARTNUMBER, QString("PartNumber") },
{ FLD_CADENCE, QString("Cadence") },
{ FLD_CALORIES, QString("Calories") },
{ FLD_MAXSPEED, QString("MaximumSpeed") },
{ FLD_ID, QString("Id") },
{ FLD_TRIGGERMETHOD, QString("TriggerMethod") },
{ FLD_TPX, QString("TPX") },
{ FLD_UNITID, QString("UnitId") },
{ FLD_PRODUCTID, QString("ProductID") },
{ FLD_NOTES, QString("Notes") },
{ FLD_TPX, QString("TPX") },
{ FLD_UNITID, QString("UnitId") },
{ FLD_PRODUCTID, QString("ProductID") },
{ FLD_NOTES, QString("Notes") },
/* Attributes */
{ ATT_CADENCESENSOR, QString("CadenceSensor") },
/* Container */
{ CON_COURSES, QString("Courses") },
{ CON_COURSE, QString("Course") },
{ CON_LAP, QString("Lap") },
{ CON_COURSES, QString("Courses") },
{ CON_COURSE, QString("Course") },
{ CON_LAP, QString("Lap") },
{ CON_BEGINPOSITION, QString("BeginPosition") },
{ CON_ENDPOSITION, QString("EndPosition") },
{ CON_ENDPOSITION, QString("EndPosition") },
{ CON_AVERAGEHEARTRATEBPM, QString("AverageHeartRateBpm") },
{ CON_MAXIMUMHEARTRATEBPM, QString("MaximumHeartRateBpm") },
{ CON_TRACK, QString("Track") },
{ CON_TRACKPOINT, QString("Trackpoint") },
{ CON_POSITION, QString("Position") },
{ CON_HEARTRATEBPM, QString("HeartRateBpm") },
{ CON_AUTHOR, QString("Author") },
{ CON_VERSION, QString("Version") },
{ CON_BUILD, QString("Build") },
{ CON_ACTIVITY, QString("Activity") },
{ CON_EXTENSIONS, QString("Extensions") },
{ CON_CREATOR, QString("Creator") },
{ CON_TRACK, QString("Track") },
{ CON_TRACKPOINT, QString("Trackpoint") },
{ CON_POSITION, QString("Position") },
{ CON_HEARTRATEBPM, QString("HeartRateBpm") },
{ CON_AUTHOR, QString("Author") },
{ CON_VERSION, QString("Version") },
{ CON_BUILD, QString("Build") },
{ CON_ACTIVITY, QString("Activity") },
{ CON_EXTENSIONS, QString("Extensions") },
{ CON_CREATOR, QString("Creator") },
{ CON_MULTISPORTSESSION, QString("MultiSportSession") },
{ CON_FIRSTSPORT, QString("FirstSport") },
{ CON_NEXTSPORT, QString("NextSport") },
{ CON_TRAINING, QString("Training") },
{ CON_FIRSTSPORT, QString("FirstSport") },
{ CON_NEXTSPORT, QString("NextSport") },
{ CON_TRAINING, QString("Training") },
{ CON_QUICKWORKOUTRESULTS, QString("QuickWorkoutResults") },
/* Errors */
{ ERR_OK, QString("OK") }, // this is no error
{ ERR_NOFILE, i18n("IMPORT: No file name to parse XML!") }, // but this
{ ERR_TAGS, i18n("IMPORT: More end tags than open tags! Invalid XML file.") },
{ ERR_ALLOCGMN, i18n("IMPORT: Error allocating memory for base Garmin structure.") },
{ ERR_ALLOCLAP, i18n("IMPORT: Error allocating memory for a lap.") },
{ ERR_ALLOCPOINT, i18n("IMPORT: Error allocating memory for a track point.") },
{ ERR_ALLOCRUN, i18n("IMPORT: Error allocating memory for running information.") },
{ ERR_ALLOCLIST, i18n("IMPORT: Error allocating memory for a list node.") },
{ STOPSTOP, QString::null }
{ ERR_OK, QString("OK") }, // this is no error
{ ERR_NOFILE, i18n("IMPORT: No file name to parse XML!") }, // but this
{ ERR_TAGS, i18n("IMPORT: More end tags than open tags! Invalid XML file.") },
{ ERR_ALLOCGMN, i18n("IMPORT: Error allocating memory for base Garmin structure.") },
{ ERR_ALLOCLAP, i18n("IMPORT: Error allocating memory for a lap.") },
{ ERR_ALLOCPOINT, i18n("IMPORT: Error allocating memory for a track point.") },
{ ERR_ALLOCRUN, i18n("IMPORT: Error allocating memory for running information.") },
{ ERR_ALLOCLIST, i18n("IMPORT: Error allocating memory for a list node.") },
{ STOPSTOP, QString::null }
};
 
void gmn_import::Initialize()
164,55 → 166,58
list_lap = list_track = 0;
ds = 0;
history = false;
inst = 0;
m_cb = 0;
doCallback = FALSE;
}
 
gmn_import::gmn_import (const QFile &qfile)
gmn_import::gmn_import(const QFile &qfile)
{
Initialize ();
file.setFileName (qfile.fileName ());
Initialize();
file.setFileName(qfile.fileName());
 
if (file.exists ())
qfstat = true;
if(file.exists())
qfstat = true;
}
 
void gmn_import::setFile (const QFile &qfile)
void gmn_import::setFile(const QFile &qfile)
{
if (qfopen)
if(qfopen)
{
file.close ();
qfopen = false;
file.close();
qfopen = false;
}
 
qfstat = false;
file.setFileName (qfile.fileName ());
file.setFileName(qfile.fileName());
 
if (file.exists ())
qfstat = true;
if(file.exists())
qfstat = true;
}
 
void gmn_import::setFile (const QString &sfile)
void gmn_import::setFile(const QString &sfile)
{
if (qfopen)
if(qfopen)
{
file.close ();
qfopen = false;
__error = 1;
file.close();
qfopen = false;
__error = 1;
}
 
qfstat = false;
file.setFileName (sfile);
file.setFileName(sfile);
 
if (file.exists ())
qfstat = true;
if(file.exists())
qfstat = true;
}
 
/*
* Convert an ISO8601 formated date into garmin epoch.
*/
unsigned int gmn_import::garmin_time (const QString& tstamp)
unsigned int gmn_import::garmin_time(const QString& tstamp)
{
QDateTime dt;
time_t tval;
QDateTime dt;
time_t tval;
 
/*
* tstamp should contain a valid ISO8601 formated date and time stamp.
221,8 → 226,8
*/
dt = dt.fromString(tstamp, Qt::ISODate);
 
if (!dt.isValid())
return 0;
if(!dt.isValid())
return 0;
 
tval = dt.toTime_t() - TIME_OFFSET;
return (unsigned int)tval;
247,108 → 252,112
/*
* This is called every time a new start element was parsed.
*/
bool gmn_import::startElement( const QString&, const QString&,
const QString& qName,
const QXmlAttributes& att)
bool gmn_import::startElement(const QString&, const QString&,
const QString& qName,
const QXmlAttributes& att)
{
int i = CON_FIRST;
int index;
int i = CON_FIRST;
int index;
 
while (i <= CON_LAST)
while(i <= CON_LAST)
{
if (qName.toLower() == getKey(i).toLower())
{
if (qName.toLower() == QString("course") || qName.toLower() == QString("activity"))
{
memset (&run, 0, sizeof (D1009));
if(qName.toLower() == getKey(i).toLower())
{
if(i == CON_MULTISPORTSESSION)
doCallback = TRUE;
 
if (i == CON_ACTIVITY)
{
con = "activity";
history = true;
}
else
con = "course";
if(qName.toLower() == QString("course") || qName.toLower() == QString("activity"))
{
memset(&run, 0, sizeof(D1009));
 
run.track_index = 0;
run.first_lap_index = 0;
// Find sport type, if there is one
if ((index = att.index(QString("Sport"))) != -1)
{
if (att.value(index).toAscii().toLower() == QString("Running").toLower())
run.sport_type = D1000_running;
else if (att.value(index).toAscii().toLower() == QString("Biking").toLower())
run.sport_type = D1000_biking;
else if (att.value(index).toAscii().toLower() == QString("Other").toLower())
run.sport_type = D1000_other;
else
run.sport_type = D1000_other;
}
else
run.sport_type = D1000_other; // Other
if(i == CON_ACTIVITY)
{
con = "activity";
history = true;
}
else
con = "course";
 
tk = i;
}
run.track_index = 0;
run.first_lap_index = 0;
 
if (qName.toLower() == QString("lap"))
{
memset (&lap, 0, sizeof (D1015));
lap.index = lpos;
lap.begin.lat = 0x7fffffff;
lap.begin.lon = 0x7fffffff;
lap.end.lat = 0x7fffffff;
lap.end.lon = 0x7fffffff;
con = "lap";
lpos++;
tk = i;
}
// Find sport type, if there is one
if((index = att.index(QString("Sport"))) != -1)
{
if(att.value(index).toAscii().toLower() == QString("Running").toLower())
run.sport_type = D1000_running;
else if(att.value(index).toAscii().toLower() == QString("Biking").toLower())
run.sport_type = D1000_biking;
else if(att.value(index).toAscii().toLower() == QString("Other").toLower())
run.sport_type = D1000_other;
else
run.sport_type = D1000_other;
}
else
run.sport_type = D1000_other; // Other
 
if (con == QString("lap") && qName.toLower() == QString("BeginPosition").toLower())
subCon = qName.toLower();
else if (con == QString("lap") && qName.toLower() == QString("EndPosition").toLower())
subCon = qName.toLower();
else if (con == QString("lap") && qName.toLower() == QString("AverageHeartRateBpm").toLower())
subCon = qName.toLower();
else if (con == QString("lap") && qName.toLower() == QString("MaximumHeartRateBpm").toLower())
subCon = qName.toLower();
tk = i;
}
 
if (history && qName.toLower() == QString("track") && con.toLower() == QString("lap"))
{
first_tpos = tpos + 1;
endElement (QString::null, QString::null, QString("Lap"));
indent++;
con = "lap";
fakeLap = true;
}
if(qName.toLower() == QString("lap"))
{
memset(&lap, 0, sizeof(D1015));
lap.index = lpos;
lap.begin.lat = 0x7fffffff;
lap.begin.lon = 0x7fffffff;
lap.end.lat = 0x7fffffff;
lap.end.lon = 0x7fffffff;
con = "lap";
lpos++;
tk = i;
}
 
if (qName.toLower() == QString("trackpoint"))
{
memset (&point, 0, sizeof (D304));
point.alt = 1.0e24;
point.posn.lat = 0x7fffffff;
point.posn.lon = 0x7fffffff;
con = "trackpoint";
tpos++;
tk = i;
}
if(con == QString("lap") && qName.toLower() == QString("BeginPosition").toLower())
subCon = qName.toLower();
else if(con == QString("lap") && qName.toLower() == QString("EndPosition").toLower())
subCon = qName.toLower();
else if(con == QString("lap") && qName.toLower() == QString("AverageHeartRateBpm").toLower())
subCon = qName.toLower();
else if(con == QString("lap") && qName.toLower() == QString("MaximumHeartRateBpm").toLower())
subCon = qName.toLower();
 
if (con == QString("trackpoint") && qName.toLower() == QString("position"))
subCon = qName.toLower();
else if (con == QString("trackpoint") && qName.toLower() == QString("heartratebpm"))
subCon = qName.toLower();
}
if(history && qName.toLower() == QString("track") && con.toLower() == QString("lap"))
{
first_tpos = tpos + 1;
endElement(QString::null, QString::null, QString("Lap"));
indent++;
con = "lap";
fakeLap = true;
}
 
i++;
if(qName.toLower() == QString("trackpoint"))
{
memset(&point, 0, sizeof(D304));
point.alt = 1.0e24;
point.posn.lat = 0x7fffffff;
point.posn.lon = 0x7fffffff;
con = "trackpoint";
tpos++;
tk = i;
}
 
if(con == QString("trackpoint") && qName.toLower() == QString("position"))
subCon = qName.toLower();
else if(con == QString("trackpoint") && qName.toLower() == QString("heartratebpm"))
subCon = qName.toLower();
}
 
i++;
}
 
i = FLD_FIRST;
 
while (i <= FLD_LAST)
while(i <= FLD_LAST)
{
if (qName.toLower() == getKey(i).toLower())
tk = i;
if(qName.toLower() == getKey(i).toLower())
tk = i;
 
i++;
i++;
}
 
indent++;
358,208 → 367,229
/*
* This is called every time an element is closed.
*/
bool gmn_import::endElement( const QString&, const QString&, const QString& qName)
bool gmn_import::endElement(const QString&, const QString&, const QString& qName)
{
if (!fakeLap)
indent--;
if(!fakeLap)
indent--;
 
if (qName.toLower() == QString("lap"))
if(qName.toLower() == QString("lap"))
{
garmin_data *gdt;
garmin_list *l;
garmin_data *gdt;
garmin_list *l;
 
if (!fakeLap)
con.clear();
if(!fakeLap)
con.clear();
 
if (history && fakeLap)
{
fakeLap = false;
return TRUE;
}
if(history && fakeLap)
{
fakeLap = false;
return TRUE;
}
 
if (!gmn) /* allocating space for first structure */
{
if ((gmn = garmin_alloc_data (data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
if(!gmn) /* allocating space for first structure */
{
if((gmn = garmin_alloc_data(data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
 
list = (garmin_list *)gmn->data;
/*
* This is the first data structure. It contains the total
* number of laps and the name of the course, if it was
* named.
*/
if ((gdt = garmin_alloc_data (data_D1009)) == NULL)
{
__error = 6;
return FALSE;
}
list = (garmin_list *)gmn->data;
 
memmove (gdt->data, &run, sizeof (D1009));
prun = (D1009 *)gdt->data;
/*
* This is the first data structure. It contains the total
* number of laps and the name of the course, if it was
* named.
*/
if((gdt = garmin_alloc_data(data_D1009)) == NULL)
{
__error = 6;
return FALSE;
}
 
if (ds)
ds->garmin_print_data (gdt);
memmove(gdt->data, &run, sizeof(D1009));
prun = (D1009 *)gdt->data;
 
if ((l = garmin_list_append (list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
if(ds)
ds->garmin_print_data(gdt);
 
list = l;
}
if((l = garmin_list_append(list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
 
if (!list_lap)
{
if ((gmn_lap = garmin_alloc_data (data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
list = l;
}
 
list_lap = (garmin_list *)gmn_lap->data;
if(!list_lap)
{
if((gmn_lap = garmin_alloc_data(data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
 
if (garmin_list_append (list, gmn_lap) == NULL)
{
__error = 7;
return FALSE;
}
list_lap = (garmin_list *)gmn_lap->data;
 
list = list_lap;
}
else
list = list_lap;
if(garmin_list_append(list, gmn_lap) == NULL)
{
__error = 7;
return FALSE;
}
 
if ((gdt = garmin_alloc_data (data_D1015)) == NULL)
{
__error = 4;
return FALSE;
}
list = list_lap;
}
else
list = list_lap;
 
memmove (gdt->data, &lap, sizeof (D1015));
plap = (D1015 *)gdt->data;
if((gdt = garmin_alloc_data(data_D1015)) == NULL)
{
__error = 4;
return FALSE;
}
 
if (ds)
ds->garmin_print_data (gdt);
memmove(gdt->data, &lap, sizeof(D1015));
plap = (D1015 *)gdt->data;
 
if ((l = garmin_list_append (list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
if(ds)
ds->garmin_print_data(gdt);
 
list = l;
if((l = garmin_list_append(list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
 
list = l;
}
 
if (history && qName.toLower() == QString("track"))
first_tpos = 0;
if(history && qName.toLower() == QString("track"))
first_tpos = 0;
 
if (qName.toLower() == QString("trackpoint"))
if(qName.toLower() == QString("trackpoint"))
{
garmin_data *gdt;
garmin_list *l;
garmin_data *gdt;
garmin_list *l;
 
con.clear();
con.clear();
 
if (!gmn) /* allocating space for first structure */
{
if ((gmn = garmin_alloc_data (data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
if(!gmn) /* allocating space for first structure */
{
if((gmn = garmin_alloc_data(data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
 
list = (garmin_list *)gmn->data;
/*
* This is the first data structure. It contains the total
* number of laps and the name of the course, if it was
* named.
*/
if ((gdt = garmin_alloc_data (data_D1009)) == NULL)
{
__error = 6;
return FALSE;
}
list = (garmin_list *)gmn->data;
 
memmove (gdt->data, &run, sizeof (D1009));
prun = (D1009 *)gdt->data;
/*
* This is the first data structure. It contains the total
* number of laps and the name of the course, if it was
* named.
*/
if((gdt = garmin_alloc_data(data_D1009)) == NULL)
{
__error = 6;
return FALSE;
}
 
if (ds)
ds->garmin_print_data (gdt);
memmove(gdt->data, &run, sizeof(D1009));
prun = (D1009 *)gdt->data;
 
if ((l = garmin_list_append (list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
if(ds)
ds->garmin_print_data(gdt);
 
list = l;
}
if((l = garmin_list_append(list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
 
if (!list_track)
{
if ((gmn_track = garmin_alloc_data (data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
list = l;
}
 
list_track = (garmin_list *)gmn_track->data;
if(!list_track)
{
if((gmn_track = garmin_alloc_data(data_Dlist)) == NULL)
{
__error = 3;
return FALSE;
}
 
if (garmin_list_append (list, gmn_track) == NULL)
{
__error = 7;
return FALSE;
}
list_track = (garmin_list *)gmn_track->data;
 
list = list_track;
}
else
list = list_track;
if(garmin_list_append(list, gmn_track) == NULL)
{
__error = 7;
return FALSE;
}
 
if ((gdt = garmin_alloc_data (data_D304)) == NULL)
{
__error = 5;
return FALSE;
}
list = list_track;
}
else
list = list_track;
 
memmove (gdt->data, &point, sizeof (D304));
if((gdt = garmin_alloc_data(data_D304)) == NULL)
{
__error = 5;
return FALSE;
}
 
if (ds)
ds->garmin_print_data (gdt);
memmove(gdt->data, &point, sizeof(D304));
 
if ((l = garmin_list_append (list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
if(ds)
ds->garmin_print_data(gdt);
 
list = l;
if((l = garmin_list_append(list, gdt)) == NULL)
{
__error = 7;
return FALSE;
}
 
list = l;
}
 
if (qName.toLower() == QString("course") || qName.toLower() == QString("activity"))
if(qName.toLower() == QString("course") || qName.toLower() == QString("activity"))
{
con.clear();
run.track_index = tpos - 1;
run.last_lap_index = lpos - 1;
memmove (prun, &run, sizeof (D1009));
history = false;
con.clear();
run.track_index = tpos - 1;
run.last_lap_index = lpos - 1;
memmove(prun, &run, sizeof(D1009));
 
if (doCallback && m_cb)
{
m_cb->cbiCallbackFunction((void *)gmn);
subCon.clear();
lpos = tpos = oldLPos = 0;
fakeLap = false;
first_tpos = 0;
garmin_free_data(gmn);
gmn = 0;
}
else if (doCallback)
std::cerr << "No callback function was defined! Can't save single track!" << std::endl;
}
 
if (qName.toLower() == QString("beginposition") || qName.toLower() == QString("endposition") ||
qName.toLower() == QString("averageheartratebpm") || qName.toLower() == QString("maximumheartratebpm"))
subCon.clear();
if (qName.toLower() == QString("activities"))
{
con.clear();
subCon.clear();
history = false;
}
 
if (qName.toLower() == QString("heartratebpm") || qName.toLower() == QString("position"))
subCon.clear();
if(qName.toLower() == QString("beginposition") || qName.toLower() == QString("endposition") ||
qName.toLower() == QString("averageheartratebpm") || qName.toLower() == QString("maximumheartratebpm"))
subCon.clear();
 
if (indent < 0)
if(qName.toLower() == QString("heartratebpm") || qName.toLower() == QString("position"))
subCon.clear();
 
if(indent < 0)
{
__error = 2;
return FALSE;
__error = 2;
return FALSE;
}
 
return TRUE;
569,196 → 599,196
* The reader calls this function when it has parsed a chunk of character data
* - either normal character data or character data inside a CDATA section.
*/
bool gmn_import::characters (const QString& ch)
bool gmn_import::characters(const QString& ch)
{
if (con == QString("course"))
if(con == QString("course"))
{
if (tk == FLD_NAME)
{
strncpy (run.workout.name, ch.toAscii(), 15);
run.workout.name[15] = 0;
tk = 0;
}
if(tk == FLD_NAME)
{
strncpy(run.workout.name, ch.toAscii(), 15);
run.workout.name[15] = 0;
tk = 0;
}
}
 
if (history && con == QString("activity"))
if(history && con == QString("activity"))
{
if (tk == FLD_ID)
{
strncpy (run.workout.name, ch.toAscii(), 15);
run.workout.name[15] = 0;
tk = 0;
}
if(tk == FLD_ID)
{
strncpy(run.workout.name, ch.toAscii(), 15);
run.workout.name[15] = 0;
tk = 0;
}
}
 
if (con == QString("lap"))
if(con == QString("lap"))
{
if (tk == FLD_DISTANCEMETERS)
{
lap.total_dist = (float32)ch.toFloat();
tk = 0;
}
if(tk == FLD_DISTANCEMETERS)
{
lap.total_dist = (float32)ch.toFloat();
tk = 0;
}
 
if (tk == FLD_INTENSITY)
{
lap.intensity = (ch.toLower() == QString("activ")) ? 0 : 1;
tk = 0;
}
if(tk == FLD_INTENSITY)
{
lap.intensity = (ch.toLower() == QString("activ")) ? 0 : 1;
tk = 0;
}
 
if (tk == FLD_STARTTIME)
{
lap.start_time = garmin_time (ch);
tk = 0;
}
if(tk == FLD_STARTTIME)
{
lap.start_time = garmin_time(ch);
tk = 0;
}
 
if (tk == FLD_TOTALTIMESECONDS)
{
lap.total_time = (uint32)(ch.toDouble() * 100.0);
tk = 0;
}
if(tk == FLD_TOTALTIMESECONDS)
{
lap.total_time = (uint32)(ch.toDouble() * 100.0);
tk = 0;
}
 
if (tk == FLD_CADENCE)
{
lap.avg_cadence = (uint8)ch.toUInt();
tk = 0;
}
if(tk == FLD_CADENCE)
{
lap.avg_cadence = (uint8)ch.toUInt();
tk = 0;
}
 
if (tk == FLD_CALORIES)
{
lap.calories = (uint16)ch.toUInt();
tk = 0;
}
if(tk == FLD_CALORIES)
{
lap.calories = (uint16)ch.toUInt();
tk = 0;
}
 
if (tk == FLD_MAXSPEED)
{
lap.max_speed = (float32)ch.toFloat();
tk = 0;
}
if(tk == FLD_MAXSPEED)
{
lap.max_speed = (float32)ch.toFloat();
tk = 0;
}
 
if (tk == FLD_TRIGGERMETHOD)
{
if (ch.toLower() == QString("manual"))
lap.trigger_method = D1011_manual;
else if (ch.toLower() == QString("distance"))
lap.trigger_method = D1011_distance;
else if (ch.toLower() == QString("location"))
lap.trigger_method = D1011_location;
else if (ch.toLower() == QString("time"))
lap.trigger_method = D1011_time;
else if (ch.toLower() == QString("HeartRate"))
lap.trigger_method = D1011_heart_rate;
}
if(tk == FLD_TRIGGERMETHOD)
{
if(ch.toLower() == QString("manual"))
lap.trigger_method = D1011_manual;
else if(ch.toLower() == QString("distance"))
lap.trigger_method = D1011_distance;
else if(ch.toLower() == QString("location"))
lap.trigger_method = D1011_location;
else if(ch.toLower() == QString("time"))
lap.trigger_method = D1011_time;
else if(ch.toLower() == QString("HeartRate"))
lap.trigger_method = D1011_heart_rate;
}
 
if (subCon.toLower() == QString("BeginPosition").toLower())
{
if (tk == FLD_LATITUDEDEGREES)
{
lap.begin.lat = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
if(subCon.toLower() == QString("BeginPosition").toLower())
{
if(tk == FLD_LATITUDEDEGREES)
{
lap.begin.lat = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
 
if (tk == FLD_LONGITUDEDEGREES)
{
lap.begin.lon = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
}
else if (subCon.toLower() == QString("EndPosition").toLower())
{
if (tk == FLD_LATITUDEDEGREES)
{
lap.end.lat = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
if(tk == FLD_LONGITUDEDEGREES)
{
lap.begin.lon = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
}
else if(subCon.toLower() == QString("EndPosition").toLower())
{
if(tk == FLD_LATITUDEDEGREES)
{
lap.end.lat = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
 
if (tk == FLD_LONGITUDEDEGREES)
{
lap.end.lon = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
}
else if (subCon.toLower() == QString("AverageHeartRateBpm").toLower())
{
if (tk == FLD_VALUE)
{
lap.avg_heart_rate = (uint8)ch.toInt();
tk = 0;
}
}
else if (subCon.toLower() == QString("MaximumHeartRateBpm").toLower())
{
if (tk == FLD_VALUE)
{
lap.max_heart_rate = (uint8)ch.toInt();
tk = 0;
}
}
if(tk == FLD_LONGITUDEDEGREES)
{
lap.end.lon = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
tk = 0;
}
}
else if(subCon.toLower() == QString("AverageHeartRateBpm").toLower())
{
if(tk == FLD_VALUE)
{
lap.avg_heart_rate = (uint8)ch.toInt();
tk = 0;
}
}
else if(subCon.toLower() == QString("MaximumHeartRateBpm").toLower())
{
if(tk == FLD_VALUE)
{
lap.max_heart_rate = (uint8)ch.toInt();
tk = 0;
}
}
}
 
if (con == QString("trackpoint"))
if(con == QString("trackpoint"))
{
if (tk == FLD_TIME)
{
point.time = garmin_time (ch);
if(tk == FLD_TIME)
{
point.time = garmin_time(ch);
 
if (history && first_tpos == tpos && plap)
plap->start_time = point.time;
if(history && first_tpos == tpos && plap)
plap->start_time = point.time;
 
tk = 0;
}
tk = 0;
}
 
if (tk == FLD_ALTITUDEMETERS)
{
point.alt = (ch.toFloat() >= 1.0e24) ? 1.0e24 : (float32)ch.toFloat();
tk = 0;
}
if(tk == FLD_ALTITUDEMETERS)
{
point.alt = (ch.toFloat() >= 1.0e24) ? 1.0e24 : (float32)ch.toFloat();
tk = 0;
}
 
if (tk == FLD_DISTANCEMETERS)
{
point.distance = (ch.toFloat() >= 1.0e24) ? 1.0e24 : (float32)ch.toFloat();
tk = 0;
}
if(tk == FLD_DISTANCEMETERS)
{
point.distance = (ch.toFloat() >= 1.0e24) ? 1.0e24 : (float32)ch.toFloat();
tk = 0;
}
 
if (tk == FLD_SENSORSTATE)
{
point.sensor = (ch.toLower() == QString("absent")) ? false : true;
tk = 0;
}
if(tk == FLD_SENSORSTATE)
{
point.sensor = (ch.toLower() == QString("absent")) ? false : true;
tk = 0;
}
 
if (subCon.toLower() == QString("position"))
{
if (tk == FLD_LATITUDEDEGREES)
{
point.posn.lat = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
if(subCon.toLower() == QString("position"))
{
if(tk == FLD_LATITUDEDEGREES)
{
point.posn.lat = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
 
if (history && tpos == first_tpos && plap) // Add mising information to first lap
plap->begin.lat = point.posn.lat;
else if (history && point.posn.lat != 0x7fffffff && plap)
plap->end.lat = point.posn.lat;
if(history && tpos == first_tpos && plap) // Add mising information to first lap
plap->begin.lat = point.posn.lat;
else if(history && point.posn.lat != 0x7fffffff && plap)
plap->end.lat = point.posn.lat;
 
tk = 0;
}
tk = 0;
}
 
if (tk == FLD_LONGITUDEDEGREES)
{
point.posn.lon = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
if(tk == FLD_LONGITUDEDEGREES)
{
point.posn.lon = (ch.toDouble() == 180.0) ? 0x7fffffff : (sint32)DEG2SEMI(ch.toDouble());
 
if (history && tpos == first_tpos && plap) // Add mising information to first lap
plap->begin.lon = point.posn.lon;
else if (history && point.posn.lon != 0x7fffffff && plap)
plap->end.lat = point.posn.lon;
if(history && tpos == first_tpos && plap) // Add mising information to first lap
plap->begin.lon = point.posn.lon;
else if(history && point.posn.lon != 0x7fffffff && plap)
plap->end.lat = point.posn.lon;
 
tk = 0;
}
}
else if (subCon.toLower() == QString("heartratebpm"))
{
if (tk == FLD_VALUE)
{
point.heart_rate = (unsigned char)ch.toInt();
tk = 0;
}
}
tk = 0;
}
}
else if(subCon.toLower() == QString("heartratebpm"))
{
if(tk == FLD_VALUE)
{
point.heart_rate = (unsigned char)ch.toInt();
tk = 0;
}
}
}
 
return TRUE;
769,44 → 799,44
* content and creates the gmn files. If there already exists a file,
* it's not overwritten.
*/
int gmn_import::import ()
int gmn_import::import()
{
QXmlSimpleReader reader;
QXmlSimpleReader reader;
 
if (!qfstat)
return 1;
if(!qfstat)
return 1;
 
QXmlInputSource source (&file);
reader.setContentHandler (this);
reader.parse (source);
QXmlInputSource source(&file);
reader.setContentHandler(this);
reader.parse(source);
return 0;
}
 
QString gmn_import::getKey (int pos)
QString gmn_import::getKey(int pos)
{
int i = 0;
int i = 0;
 
while (keys[i].id > 0)
while(keys[i].id > 0)
{
if (keys[i].id == pos)
return keys[i].name;
if(keys[i].id == pos)
return keys[i].name;
 
i++;
i++;
}
 
return QString::null;
}
 
QString gmn_import::getError (int err)
QString gmn_import::getError(int err)
{
if (err > eMax || err < 1)
return 0;
if(err > eMax || err < 1)
return 0;
 
return getKey (ERR_FIRST + err);
return getKey(ERR_FIRST + err);
}
 
QString gmn_import::getError ()
QString gmn_import::getError()
{
return getKey (ERR_FIRST + __error);
return getKey(ERR_FIRST + __error);
}
 
/sportwatcher/trunk/src/sportwatcherwidget.cpp
1,5 → 1,5
/***************************************************************************
* Copyright (C) 2007 - 2009 by Andreas Theofilu *
* Copyright (C) 2007 - 2013 by Andreas Theofilu *
* andreas@theosys.at *
* *
* This program is free software; you can redistribute it and/or modify *
52,19 → 52,18
#include <QPrinter>
 
#if defined HAVE_GDAL
#include <gdal/ogr_spatialref.h>
#include <gdal/ogrsf_frmts.h>
#include <gdal/gdalwarper.h>
#include <gdal/ogrsf_frmts.h>
#include "GDALError.h"
#include <gdal/ogr_spatialref.h>
#include <gdal/ogrsf_frmts.h>
#include <gdal/gdalwarper.h>
#include <gdal/ogrsf_frmts.h>
#include "GDALError.h"
#endif
 
#include "garmin.h"
#include "transform.h"
#include "import.h"
 
#if defined HAVE_MAPNIK
#include "render.h"
#include "render.h"
#endif
 
using std::cout;
84,7 → 83,7
{
char msg[4096];
ERRMSG *next;
}ERRMSG;
} ERRMSG;
 
ERRMSG *firstError;
#endif
115,8 → 114,8
kl = new KLocale(QString("kdesktop"), 0);
 
// Load the config parameters
KConfig cfg (QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup ic (&cfg, "SportWatcher");
KConfig cfg(QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup ic(&cfg, "SportWatcher");
lower1 = ic.readEntry("lower1", 0);
lower2 = ic.readEntry("lower2", 0);
lower3 = ic.readEntry("lower3", 0);
156,8 → 155,8
 
void sportwatcherWidget::destroy()
{
if (gmn)
garmin_free_data (gmn);
if(gmn)
garmin_free_data(gmn);
 
gmn = 0;
oldTransX = oldTransY = 0.0;
173,10 → 172,10
ui_sportwatcherWidgetBase.btFlag->setIcon(KIcon("flag"));
ui_sportwatcherWidgetBase.btFullscreen->setIcon(KIcon("fullscreen"));
 
if (curTab != 0)
if(curTab != 0)
{
ui_sportwatcherWidgetBase.tabView->setCurrentIndex(0);
curTab = ui_sportwatcherWidgetBase.tabView->currentIndex();
ui_sportwatcherWidgetBase.tabView->setCurrentIndex(0);
curTab = ui_sportwatcherWidgetBase.tabView->currentIndex();
}
 
// btHand->setToggleButton(true);
192,33 → 191,33
 
QTreeWidgetItem *sportwatcherWidget::findElement(QTreeWidget *wdg, const QString &val)
{
QTreeWidgetItem *item, *child, *subchild;
QTreeWidgetItem *item, *child, *subchild;
 
if (!wdg)
return 0;
if(!wdg)
return 0;
 
for (int a = 0; a < wdg->topLevelItemCount(); a++)
for(int a = 0; a < wdg->topLevelItemCount(); a++)
{
if (!(item = wdg->topLevelItem(a)))
continue;
if(!(item = wdg->topLevelItem(a)))
continue;
 
for (int j = 0; j < item->childCount(); j++)
{
if (!(child = item->child(j)))
continue;
for(int j = 0; j < item->childCount(); j++)
{
if(!(child = item->child(j)))
continue;
 
if (child->data(0, Qt::UserRole).toString() == val)
return child;
if(child->data(0, Qt::UserRole).toString() == val)
return child;
 
for (int i = 0; i < child->childCount(); i++)
{
if (!(subchild = child->child(i)))
continue;
for(int i = 0; i < child->childCount(); i++)
{
if(!(subchild = child->child(i)))
continue;
 
if (subchild->data(0, Qt::UserRole).toString() == val)
return subchild;
}
}
if(subchild->data(0, Qt::UserRole).toString() == val)
return subchild;
}
}
}
 
return 0;
232,40 → 231,40
*/
void sportwatcherWidget::getActivities()
{
QString path, txt;
QDir mdir, dir = QDir::home();
QStringList years, months;
QTreeWidgetItem *running, *biking, *other, *year_run, *year_bike, *year_other;
QTreeWidgetItem *el;
QList<QTreeWidgetItem *> item;
int i, j;
int y_run, y_bike, y_other;
RUN_NODE *rn;
LAP *lap;
QString path, txt;
QDir mdir, dir = QDir::home();
QStringList years, months;
QTreeWidgetItem *running, *biking, *other, *year_run, *year_bike, *year_other;
QTreeWidgetItem *el;
QList<QTreeWidgetItem *> item;
int i, j;
int y_run, y_bike, y_other;
RUN_NODE *rn;
LAP *lap;
 
if (Data.isEmpty())
if(Data.isEmpty())
{
path = dir.homePath();
path.append("/.sportwatcher");
path = dir.homePath();
path.append("/.sportwatcher");
}
else
path = Data;
path = Data;
 
dir.setPath(path);
dir.refresh();
 
if (!dir.exists())
if(!dir.exists())
{
dir.mkdir(path);
return;
dir.mkdir(path);
return;
}
 
destroy();
 
if (!ui_sportwatcherWidgetBase.liActivities)
if(!ui_sportwatcherWidgetBase.liActivities)
{
KMessageBox::error(this, i18n("Error initializing some widgets of main window!"));
return;
KMessageBox::error(this, i18n("Error initializing some widgets of main window!"));
return;
}
 
ui_sportwatcherWidgetBase.liActivities->clear();
276,10 → 275,10
biking = new QTreeWidgetItem(ui_sportwatcherWidgetBase.liActivities);
other = new QTreeWidgetItem(ui_sportwatcherWidgetBase.liActivities);
 
if (!other || !biking || !running)
if(!other || !biking || !running)
{
KMessageBox::error(this, i18n("Not enough memory to initilize application!"));
return;
KMessageBox::error(this, i18n("Not enough memory to initilize application!"));
return;
}
 
running->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
305,194 → 304,195
dir.refresh();
QFileInfoList list = dir.entryInfoList();
 
if (!list.size())
return;
if(!list.size())
return;
 
for (i = 0; i < list.size(); i++) // Years
for(i = 0; i < list.size(); i++) // Years
{
QFileInfo fileInfo = list.at(i);
QFileInfo fileInfo = list.at(i);
 
if (fileInfo.fileName() == QString(".") || fileInfo.fileName() == QString(".."))
continue;
if(fileInfo.fileName() == QString(".") || fileInfo.fileName() == QString(".."))
continue;
 
years += fileInfo.absoluteFilePath();
years += fileInfo.absoluteFilePath();
}
 
for (i = 0; i < years.size(); ++i)
for(i = 0; i < years.size(); ++i)
{
if (months.size() > 0)
months.clear();
if(months.size() > 0)
months.clear();
 
dir.setPath(years.at(i));
dir.refresh();
list = dir.entryInfoList();
dir.setPath(years.at(i));
dir.refresh();
list = dir.entryInfoList();
 
if (!list.size())
continue;
if(!list.size())
continue;
 
for (j = 0; j < list.size(); j++) // Months
{
QFileInfo fileInfo = list.at(j);
for(j = 0; j < list.size(); j++) // Months
{
QFileInfo fileInfo = list.at(j);
 
if (fileInfo.fileName() == QString(".") || fileInfo.fileName() == QString(".."))
continue;
if(fileInfo.fileName() == QString(".") || fileInfo.fileName() == QString(".."))
continue;
 
months += fileInfo.absoluteFilePath();
}
months += fileInfo.absoluteFilePath();
}
 
for (j = 0; j < months.size(); ++j)
{
mdir.setPath(months.at(j));
mdir.cd(months.at(j));
mdir.setFilter(QDir::Files | QDir::NoSymLinks);
mdir.setSorting(QDir::Name);
mdir.setNameFilters(QStringList("*.gmn"));
mdir.refresh();
list = mdir.entryInfoList();
for(j = 0; j < months.size(); ++j)
{
mdir.setPath(months.at(j));
mdir.cd(months.at(j));
mdir.setFilter(QDir::Files | QDir::NoSymLinks);
mdir.setSorting(QDir::Name);
mdir.setNameFilters(QStringList("*.gmn"));
mdir.refresh();
list = mdir.entryInfoList();
 
if (!list.size())
continue;
if(!list.size())
continue;
 
for (int a = 0; a < list.size(); a++) // Files
{
QFileInfo fileInfo = list.at(a);
for(int a = 0; a < list.size(); a++) // Files
{
QFileInfo fileInfo = list.at(a);
 
files += fileInfo.absoluteFilePath();
}
}
files += fileInfo.absoluteFilePath();
}
}
}
 
y_run = y_bike = y_other = 0;
year_run = year_bike = year_other = 0;
 
// Open every file and read its head
for (i = 0; i < files.size(); ++i)
for(i = 0; i < files.size(); ++i)
{
QTreeWidgetItem *yr, *yb, *yo;
QTreeWidgetItem *yr, *yb, *yo;
 
if (findElement(ui_sportwatcherWidgetBase.liActivities, files.at(i)))
continue;
if(findElement(ui_sportwatcherWidgetBase.liActivities, files.at(i)))
continue;
 
spw.destroy();
spw.destroy();
 
if (spw.setFileName(files.at(i).toAscii().constData()) == -1)
return;
if(spw.setFileName(files.at(i).toAscii().constData()) == -1)
return;
 
if (gmn)
{
garmin_free_data (gmn);
gmn = 0;
}
if(gmn)
{
garmin_free_data(gmn);
gmn = 0;
}
 
if (!(gmn = spw.readFile()))
continue;
if(!(gmn = spw.readFile()))
continue;
 
ds.destroy();
ds.garmin_print_data(gmn);
rn = ds.getRunNode();
ds.destroy();
ds.garmin_print_data(gmn);
rn = ds.getRunNode();
 
if (!rn)
return;
if(!rn)
return;
 
lap = ds.getLap(rn->run->first_lap_index);
lap = ds.getLap(rn->run->first_lap_index);
 
if (!lap)
return;
if(!lap)
return;
 
const QDateTime *qt = garmin_dtime (lap->start_time);
// By default set the name of the session to the date and time
// it was recorded.
QString idx = kl->formatDateTime (*qt, KLocale::ShortDate, true);
QString stTip = kl->formatDateTime (*qt, KLocale::LongDate, true);
const QDateTime *qt = garmin_dtime(lap->start_time);
// By default set the name of the session to the date and time
// it was recorded.
QString idx = kl->formatDateTime(*qt, KLocale::ShortDate, true);
QString stTip = kl->formatDateTime(*qt, KLocale::LongDate, true);
 
// If we have a custom name for this session, set it.
if (strlen (rn->run->workout.name) > 1 && strlen (rn->run->workout.name) < 16 && isalpha (rn->run->workout.name[0]))
idx = QString (rn->run->workout.name);
// If we have a custom name for this session, set it.
if(strlen(rn->run->workout.name) > 1 && strlen(rn->run->workout.name) < 16 && isalpha(rn->run->workout.name[0]))
idx = QString(rn->run->workout.name);
 
switch (rn->run->sport_type)
{
case D1000_running:
yr = findElement(ui_sportwatcherWidgetBase.liActivities, QString("run_%1").arg(qt->date().year()));
switch(rn->run->sport_type)
{
case D1000_running:
yr = findElement(ui_sportwatcherWidgetBase.liActivities, QString("run_%1").arg(qt->date().year()));
 
if (!yr && qt->date().year() != y_run)
{
year_run = new QTreeWidgetItem(running, running, QTreeWidgetItem::Type);
y_run = qt->date().year();
year_run->setText(0, QString("%1").arg(y_run));
year_run->setData(0, Qt::UserRole, QString("run_%1").arg(y_run));
year_run->setIcon(0, KIcon(QString("today")));
year_run->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
else
year_run = yr;
if(!yr && qt->date().year() != y_run)
{
year_run = new QTreeWidgetItem(running, running, QTreeWidgetItem::Type);
y_run = qt->date().year();
year_run->setText(0, QString("%1").arg(y_run));
year_run->setData(0, Qt::UserRole, QString("run_%1").arg(y_run));
year_run->setIcon(0, KIcon(QString("today")));
year_run->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
else
year_run = yr;
 
el = new QTreeWidgetItem(year_run, year_run, QTreeWidgetItem::Type);
el->setText(0, idx);
el->setData(0, Qt::UserRole, files.at(i));
el->setIcon(0, KIcon(QString("spw-running")));
el->setStatusTip(0, stTip);
el->setToolTip(0, stTip);
el->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
break;
el = new QTreeWidgetItem(year_run, year_run, QTreeWidgetItem::Type);
el->setText(0, idx);
el->setData(0, Qt::UserRole, files.at(i));
el->setIcon(0, KIcon(QString("spw-running")));
el->setStatusTip(0, stTip);
el->setToolTip(0, stTip);
el->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
break;
 
case D1000_biking:
yb = findElement(ui_sportwatcherWidgetBase.liActivities, QString("bike_%1").arg(qt->date().year()));
case D1000_biking:
yb = findElement(ui_sportwatcherWidgetBase.liActivities, QString("bike_%1").arg(qt->date().year()));
 
if (!yb && qt->date().year() != y_bike)
{
year_bike = new QTreeWidgetItem(biking, biking, QTreeWidgetItem::Type);
y_bike = qt->date().year();
year_bike->setText(0, QString("%1").arg(y_bike));
year_bike->setData(0, Qt::UserRole, QString("bike_%1").arg(y_bike));
year_bike->setIcon(0, KIcon(QString("today")));
year_bike->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
else
year_bike = yb;
if(!yb && qt->date().year() != y_bike)
{
year_bike = new QTreeWidgetItem(biking, biking, QTreeWidgetItem::Type);
y_bike = qt->date().year();
year_bike->setText(0, QString("%1").arg(y_bike));
year_bike->setData(0, Qt::UserRole, QString("bike_%1").arg(y_bike));
year_bike->setIcon(0, KIcon(QString("today")));
year_bike->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
else
year_bike = yb;
 
el = new QTreeWidgetItem(year_bike, year_bike, QTreeWidgetItem::Type);
el->setText(0, idx);
el->setData(0, Qt::UserRole, files.at(i));
el->setStatusTip(0, stTip);
el->setToolTip(0, stTip);
el->setIcon(0, KIcon(QString("bike")));
el->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
break;
el = new QTreeWidgetItem(year_bike, year_bike, QTreeWidgetItem::Type);
el->setText(0, idx);
el->setData(0, Qt::UserRole, files.at(i));
el->setStatusTip(0, stTip);
el->setToolTip(0, stTip);
el->setIcon(0, KIcon(QString("bike")));
el->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
break;
 
case D1000_other:
default:
yo = findElement(ui_sportwatcherWidgetBase.liActivities, QString("other_%1").arg(qt->date().year()));
case D1000_other:
default:
yo = findElement(ui_sportwatcherWidgetBase.liActivities, QString("other_%1").arg(qt->date().year()));
 
if (!yo && qt->date().year() != y_other)
{
year_other = new QTreeWidgetItem(other, other, QTreeWidgetItem::Type);
y_other = qt->date().year();
year_other->setText(0, QString("%1").arg(y_other));
year_other->setData(0, Qt::UserRole, QString("other_%1").arg(y_other));
year_other->setIcon(0, KIcon(QString("today")));
year_other->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
else
year_other = yo;
if(!yo && qt->date().year() != y_other)
{
year_other = new QTreeWidgetItem(other, other, QTreeWidgetItem::Type);
y_other = qt->date().year();
year_other->setText(0, QString("%1").arg(y_other));
year_other->setData(0, Qt::UserRole, QString("other_%1").arg(y_other));
year_other->setIcon(0, KIcon(QString("today")));
year_other->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
else
year_other = yo;
 
el = new QTreeWidgetItem(year_other, year_other, QTreeWidgetItem::Type);
el->setText(0, idx);
el->setData(0, Qt::UserRole, files.at(i));
el->setStatusTip(0, stTip);
el->setToolTip(0, stTip);
el->setIcon(0, KIcon(QString("other")));
el->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
el = new QTreeWidgetItem(year_other, year_other, QTreeWidgetItem::Type);
el->setText(0, idx);
el->setData(0, Qt::UserRole, files.at(i));
el->setStatusTip(0, stTip);
el->setToolTip(0, stTip);
el->setIcon(0, KIcon(QString("other")));
el->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
 
delete qt;
delete qt;
}
 
ui_sportwatcherWidgetBase.liActivities->setItemExpanded(running, true);
 
if (year_run)
ui_sportwatcherWidgetBase.liActivities->setItemExpanded(year_run, true);
if(year_run)
ui_sportwatcherWidgetBase.liActivities->setItemExpanded(year_run, true);
 
if (gmn)
garmin_free_data (gmn);
if(gmn)
garmin_free_data(gmn);
 
gmn = 0;
}
509,7 → 509,7
 
void sportwatcherWidget::btGlasMinusSlot()
{
bool sh = stateHand;
bool sh = stateHand;
 
stateHand = false;
DIRTY = true;
520,7 → 520,7
 
void sportwatcherWidget::btGlasPlusSlot()
{
bool sh = stateHand;
bool sh = stateHand;
 
stateHand = false;
DIRTY = true;
531,20 → 531,20
 
void sportwatcherWidget::btHandSlot()
{
QCursor cs;
QCursor cs;
 
if (stateGlas)
if(stateGlas)
{
stateGlas = false;
ui_sportwatcherWidgetBase.btGlas->toggle();
stateGlas = false;
ui_sportwatcherWidgetBase.btGlas->toggle();
}
 
stateHand = (stateHand) ? false : true;
 
if (stateHand)
cs.setShape(Qt::PointingHandCursor);
if(stateHand)
cs.setShape(Qt::PointingHandCursor);
else
cs.setShape(Qt::ArrowCursor);
cs.setShape(Qt::ArrowCursor);
 
ui_sportwatcherWidgetBase.imgMap->setCursor(cs);
}
551,20 → 551,20
 
void sportwatcherWidget::btGlasSlot()
{
QCursor cs;
QCursor cs;
 
if (stateHand)
if(stateHand)
{
stateHand = false;
ui_sportwatcherWidgetBase.btHand->toggle();
stateHand = false;
ui_sportwatcherWidgetBase.btHand->toggle();
}
 
stateGlas = (stateGlas) ? false : true;
 
if (stateGlas)
cs.setShape(Qt::ForbiddenCursor);
if(stateGlas)
cs.setShape(Qt::ForbiddenCursor);
else
cs.setShape(Qt::ArrowCursor);
cs.setShape(Qt::ArrowCursor);
 
ui_sportwatcherWidgetBase.imgMap->setCursor(cs);
}
575,26 → 575,26
 
void sportwatcherWidget::liLapsSlot(Q3ListViewItem *item)
{
QString sl;
int l;
int idx;
RUN_NODE *rn;
LAP *lap;
QString sl;
int l;
int idx;
RUN_NODE *rn;
LAP *lap;
 
if (!item)
return;
if(!item)
return;
 
DIRTY = true;
sl = item->text(0).mid(4, 3);
l = sl.toInt();
 
if (l <= 0)
if(l <= 0)
{
// Show the whole map and track
showTrack(zfactor, mapPan, 0);
// Don't mark any lap. Just display normal.
showCurves(0);
return;
// Show the whole map and track
showTrack(zfactor, mapPan, 0);
// Don't mark any lap. Just display normal.
showCurves(0);
return;
}
 
rn = ds.getRunNode();
609,16 → 609,16
 
void sportwatcherWidget::liActivitiesSlot(QTreeWidgetItem *item, int)
{
if (!item)
return;
if(!item)
return;
 
spw.destroy();
 
if (spw.setFileName(item->data(0, Qt::UserRole).toString().toAscii().constData()) == -1)
return;
if(spw.setFileName(item->data(0, Qt::UserRole).toString().toAscii().constData()) == -1)
return;
 
if (gmn)
garmin_free_data (gmn);
if(gmn)
garmin_free_data(gmn);
 
gmn = spw.readFile();
zfactor = 0;
625,12 → 625,12
 
// Make sure, the currently not visible tabs will be redrawn as soon
// as they are visible.
switch (curTab)
switch(curTab)
{
case 0: tabDirt1 = tabDirt2 = tabDirt3 = true; break;
case 1: tabDirt0 = tabDirt2 = tabDirt3 = true; break;
case 2: tabDirt0 = tabDirt1 = tabDirt3 = true; break;
case 3: tabDirt0 = tabDirt1 = tabDirt2 = true; break;
case 0: tabDirt1 = tabDirt2 = tabDirt3 = true; break;
case 1: tabDirt0 = tabDirt2 = tabDirt3 = true; break;
case 2: tabDirt0 = tabDirt1 = tabDirt3 = true; break;
case 3: tabDirt0 = tabDirt1 = tabDirt2 = true; break;
}
 
// Display the just loaded sport session
639,10 → 639,10
showTrack();
showCurves();
 
if (curTab == 2)
if(curTab == 2)
{
showThreeCurve();
tabDirt2 = false;
showThreeCurve();
tabDirt2 = false;
}
 
DIRTY = false;
660,27 → 660,27
*/
void sportwatcherWidget::filePrint()
{
QPrinter printer(QPrinter::HighResolution);
QDateTime dt;
QTime t, st;
QDateTime *qt;
QRectF rect;
QString qs_name, qs_distance, qs_etime, qs_avgpace, qs_avgspeed, qs_maxspeed;
QString qs_calories, qs_avghr, qs_maxhr, qs_avgcadence, qs_ascent, qs_descent;
QString qs_totdist, hv0;
LAP *lap;
POINT *point;
RUN_NODE *rakt, *rn;
int laps, i, anz, cad, page, firstPage, lastPage;
qreal extMil[4];
double sum_asc, sum_dsc, old_asc, old_dsc;
double totdist, lineH, aktLine;
bool printed = false;
QPrinter printer(QPrinter::HighResolution);
QDateTime dt;
QTime t, st;
QDateTime *qt;
QRectF rect;
QString qs_name, qs_distance, qs_etime, qs_avgpace, qs_avgspeed, qs_maxspeed;
QString qs_calories, qs_avghr, qs_maxhr, qs_avgcadence, qs_ascent, qs_descent;
QString qs_totdist, hv0;
LAP *lap;
POINT *point;
RUN_NODE *rakt, *rn;
int laps, i, anz, cad, page, firstPage, lastPage;
qreal extMil[4];
double sum_dsc, old_asc, old_dsc;
double totdist, lineH, aktLine;
bool printed = false;
 
if (!gmn)
if(!gmn)
{
KMessageBox::error(this, i18n("You must select an activity first!"));
return;
KMessageBox::error(this, i18n("You must select an activity first!"));
return;
}
 
printer.setCreator(QString("SportWatcher"));
687,11 → 687,11
printer.setDocName(QString("SportWatcher_%1").arg(QString(VERSION)));
QPrintDialog printDialog(&printer, this);
 
if (!printDialog.exec() == QDialog::Accepted)
return;
if(!printDialog.exec() == QDialog::Accepted)
return;
 
if (!(rn = ds.getRunNode()))
return;
if(!(rn = ds.getRunNode()))
return;
 
// We dont care about page margins of a printer. Instead we assume
// a frame from about 20mm arround the page. European paper size is
706,479 → 706,483
firstPage = printer.fromPage();
lastPage = printer.toPage();
 
if (!printArea.begin(&printer))
if(!printArea.begin(&printer))
{
KMessageBox::error(this, i18n("Error initializing printer! Printing is currently not available!"));
return;
KMessageBox::error(this, i18n("Error initializing printer! Printing is currently not available!"));
return;
}
 
ActivePrint = true;
rakt = rn;
QApplication::setOverrideCursor (QCursor(Qt::WaitCursor));
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 
while (rakt)
while(rakt)
{
// Check for a supported run type
if (rakt->run->type == data_D1000 || rakt->run->type == data_D1009 ||
rakt->run->type == data_D1010)
{
int ahr;
double distance, speed, mspeed;
QDate dat;
// Check for a supported run type
if(rakt->run->type == data_D1000 || rakt->run->type == data_D1009 ||
rakt->run->type == data_D1010)
{
int ahr;
double distance, speed, mspeed;
QDate dat;
 
printArea.setFont(QFont(QString("Helvetica"), 12, QFont::Bold, false));
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(extMil[1], printer, true),
milToPixel(extMil[0]+170, printer),
milToPixel(extMil[1] + 7.0, printer, true));
printArea.setPen(QPen(QBrush(QColor("black")), (qreal)milToPixel(0.5, printer, false)));
printArea.setFont(QFont(QString("Helvetica"), 12, QFont::Bold, false));
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(extMil[1], printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(extMil[1] + 7.0, printer, true));
printArea.setPen(QPen(QBrush(QColor("black")), (qreal)milToPixel(0.5, printer, false)));
 
if ((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.drawRect(rect);
printed = true;
}
if((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.drawRect(rect);
printed = true;
}
 
if (!(lap = ds.getLap(rakt->run->first_lap_index)))
{
ActivePrint = false;
QApplication::restoreOverrideCursor();
return;
}
if(!(lap = ds.getLap(rakt->run->first_lap_index)))
{
ActivePrint = false;
QApplication::restoreOverrideCursor();
return;
}
 
if (strlen (rn->run->workout.name) > 1 && strlen (rn->run->workout.name) < 16 && isalpha (rn->run->workout.name[0]))
hv0 = QString(rakt->run->workout.name);
else
{
qt = garmin_dtime(lap->start_time);
hv0 = kl->formatDate(qt->date(), KLocale::ShortDate) + " ";
hv0.append(qt->toString("hh:mm:ss"));
delete qt;
}
if(strlen(rn->run->workout.name) > 1 && strlen(rn->run->workout.name) < 16 && isalpha(rn->run->workout.name[0]))
hv0 = QString(rakt->run->workout.name);
else
{
qt = garmin_dtime(lap->start_time);
hv0 = kl->formatDate(qt->date(), KLocale::ShortDate) + " ";
hv0.append(qt->toString("hh:mm:ss"));
delete qt;
}
 
// Set the name depending on the sport type
// This is used on the tab "Summary"
switch (rakt->run->sport_type)
{
case D1000_running: qs_name = i18n("Running: "); break;
case D1000_biking: qs_name = i18n("Biking: "); break;
case D1000_other: qs_name = i18n("Other: "); break;
default:
qs_name = i18n("Unknown: ");
}
// Set the name depending on the sport type
// This is used on the tab "Summary"
switch(rakt->run->sport_type)
{
case D1000_running: qs_name = i18n("Running: "); break;
case D1000_biking: qs_name = i18n("Biking: "); break;
case D1000_other: qs_name = i18n("Other: "); break;
default:
qs_name = i18n("Unknown: ");
}
 
// Print the headline inside the frame
if ((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.drawText(rect, Qt::AlignHCenter, QString("%1%2").arg(qs_name).arg(hv0));
// Print the headline of the table
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Bold, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(extMil[1]+10, printer, true), milToPixel(extMil[0]+35, printer), milToPixel(extMil[0]+10+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Lap"));
rect.setCoords(milToPixel(extMil[0]+35, printer), milToPixel(extMil[1]+10, printer, true), milToPixel(extMil[0]+60, printer), milToPixel(extMil[0]+10+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Distance"));
rect.setCoords(milToPixel(extMil[0]+60, printer), milToPixel(extMil[1]+10, printer, true), milToPixel(extMil[0]+85, printer), milToPixel(extMil[0]+10+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Time"));
rect.setCoords(milToPixel(extMil[0]+85, printer), milToPixel(extMil[1]+10, printer, true), milToPixel(extMil[0]+122, printer), milToPixel(extMil[0]+10+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Speed"));
rect.setCoords(milToPixel(extMil[0]+122, printer), milToPixel(extMil[1]+10, printer, true), milToPixel(extMil[0]+147, printer), milToPixel(extMil[0]+10+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Heart rate"));
rect.setCoords(milToPixel(extMil[0]+147, printer), milToPixel(extMil[1]+10, printer, true), milToPixel(extMil[0]+170, printer), milToPixel(extMil[0]+10+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Cadence"));
aktLine = extMil[1] + 10.0 + lineH;
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine, printer, true));
aktLine += 1.0;
printed = true;
}
else
{
aktLine = extMil[1] + 10.0 + lineH;
aktLine += 1.0;
}
// Print the headline inside the frame
if((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.drawText(rect, Qt::AlignHCenter, QString("%1%2").arg(qs_name).arg(hv0));
// Print the headline of the table
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Bold, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(extMil[1] + 10, printer, true), milToPixel(extMil[0] + 35, printer), milToPixel(extMil[0] + 10 + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Lap"));
rect.setCoords(milToPixel(extMil[0] + 35, printer), milToPixel(extMil[1] + 10, printer, true), milToPixel(extMil[0] + 60, printer), milToPixel(extMil[0] + 10 + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Distance"));
rect.setCoords(milToPixel(extMil[0] + 60, printer), milToPixel(extMil[1] + 10, printer, true), milToPixel(extMil[0] + 85, printer), milToPixel(extMil[0] + 10 + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Time"));
rect.setCoords(milToPixel(extMil[0] + 85, printer), milToPixel(extMil[1] + 10, printer, true), milToPixel(extMil[0] + 122, printer), milToPixel(extMil[0] + 10 + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Speed"));
rect.setCoords(milToPixel(extMil[0] + 122, printer), milToPixel(extMil[1] + 10, printer, true), milToPixel(extMil[0] + 147, printer), milToPixel(extMil[0] + 10 + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Heart rate"));
rect.setCoords(milToPixel(extMil[0] + 147, printer), milToPixel(extMil[1] + 10, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(extMil[0] + 10 + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Cadence"));
aktLine = extMil[1] + 10.0 + lineH;
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine, printer, true));
aktLine += 1.0;
printed = true;
}
else
{
aktLine = extMil[1] + 10.0 + lineH;
aktLine += 1.0;
}
 
// Prepare to print the first line
qt = garmin_dtime (lap->start_time);
StartTime = *qt;
st = qt->time();
dat = qt->date();
delete qt;
qt = 0;
// Find the last track
if (!(point = ds.getLastPoint()))
{
QApplication::restoreOverrideCursor();
KMessageBox::error(this, i18n("Error getting the last messure point!"));
ActivePrint = false;
return;
}
// Prepare to print the first line
qt = garmin_dtime(lap->start_time);
StartTime = *qt;
st = qt->time();
dat = qt->date();
delete qt;
qt = 0;
 
qt = garmin_dtime(point->time);
t = qt->time();
t.setHMS(0, 0, 0);
t = t.addSecs(ds.getTotalTime());
qt->setDate(dat);
qt->setTime(t);
qs_name = kl->formatDate(dat, KLocale::ShortDate);
qs_name.append(" ");
qs_name.append(kl->formatTime(st, true));
max_time = ds.getTotalTime();
qs_etime = QString(qt->toString("hh:mm:ss.zzz"));
// Find the last track
if(!(point = ds.getLastPoint()))
{
QApplication::restoreOverrideCursor();
KMessageBox::error(this, i18n("Error getting the last messure point!"));
ActivePrint = false;
return;
}
 
distance = 0.0;
mspeed = 0;
ahr = 0;
anz = 0;
cad = 0;
sum_asc = sum_dsc = old_asc = old_dsc = 0;
qt = garmin_dtime(point->time);
t = qt->time();
t.setHMS(0, 0, 0);
t = t.addSecs(ds.getTotalTime());
qt->setDate(dat);
qt->setTime(t);
qs_name = kl->formatDate(dat, KLocale::ShortDate);
qs_name.append(" ");
qs_name.append(kl->formatTime(st, true));
max_time = ds.getTotalTime();
qs_etime = QString(qt->toString("hh:mm:ss.zzz"));
 
// Find out the total distance, calories, maximum speed,
// maximum heart rate and the average heart rate. Get this
// values from the lap summary the watch made.
for (i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
if ((lap = ds.getLap(i)) == NULL)
continue;
distance = 0.0;
mspeed = 0;
ahr = 0;
anz = 0;
cad = 0;
sum_dsc = old_asc = old_dsc = 0;
 
distance += lap->total_distance;
// Find out the total distance, calories, maximum speed,
// maximum heart rate and the average heart rate. Get this
// values from the lap summary the watch made.
for(i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
if((lap = ds.getLap(i)) == NULL)
continue;
 
if (lap->avg_cadence != 0xff)
cad += lap->avg_cadence;
distance += lap->total_distance;
 
ahr += lap->avg_heart_rate;
anz++;
if(lap->avg_cadence != 0xff)
cad += lap->avg_cadence;
 
if (lap->max_speed > mspeed)
mspeed = lap->max_speed;
}
ahr += lap->avg_heart_rate;
anz++;
 
total_distance = distance = ds.getTotalDistance();
if(lap->max_speed > mspeed)
mspeed = lap->max_speed;
}
 
if (Units == 1) // Statute?
qs_distance.sprintf("%.2f ft", distance / 0.304);
else
qs_distance.sprintf("%.2f m", distance);
total_distance = distance = ds.getTotalDistance();
 
if (distance > 0)
{
QTime tt = qt->time();
long secs = (double)(tt.hour() * 3600 + tt.minute() * 60 + tt.second()) / 100.0;
if(Units == 1) // Statute?
qs_distance.sprintf("%.2f ft", distance / 0.304);
else
qs_distance.sprintf("%.2f m", distance);
 
if (Units == 0)
secs = secs * (1000.0 / distance * 100.0);
else
secs = secs * (1609.344 / distance * 100.0);
if(distance > 0)
{
QTime tt = qt->time();
long secs = (double)(tt.hour() * 3600 + tt.minute() * 60 + tt.second()) / 100.0;
 
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = QString(" ") + kl->formatTime(t, true);
if(Units == 0)
secs = secs * (1000.0 / distance * 100.0);
else
secs = secs * (1609.344 / distance * 100.0);
 
if (Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = QString(" ") + kl->formatTime(t, true);
 
if (Units == 1) // Statute?
speed = distance / ds.getTotalTime() * 3.6 / 1.609344;
else
speed = distance / ds.getTotalTime() * 3.6;
if(Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
 
qs_avgspeed.sprintf("%.2f %s", speed, (Units == 1) ? "mph" : "km/h");
qs_maxspeed.sprintf("%.2f %s", (Units == 1) ? mspeed * 3.6 / 1.609344 : mspeed * 3.6, (Units == 1) ? "mph" : "km/h");
qs_avghr.sprintf("%d bpm", ahr / anz);
if(Units == 1) // Statute?
speed = distance / ds.getTotalTime() * 3.6 / 1.609344;
else
speed = distance / ds.getTotalTime() * 3.6;
 
if (cad > 0)
qs_avgcadence.sprintf("%d", cad / anz);
qs_avgspeed.sprintf("%.2f %s", speed, (Units == 1) ? "mph" : "km/h");
qs_maxspeed.sprintf("%.2f %s", (Units == 1) ? mspeed * 3.6 / 1.609344 : mspeed * 3.6, (Units == 1) ? "mph" : "km/h");
qs_avghr.sprintf("%d bpm", ahr / anz);
 
// Print out the summary line and draw twi thin lines underneath
if ((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+35, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, qs_name);
rect.setCoords(milToPixel(extMil[0]+35, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+60, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_distance, false));
rect.setCoords(milToPixel(extMil[0]+60, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+85, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_etime);
rect.setCoords(milToPixel(extMil[0]+85, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+122, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_avgspeed, false));
rect.setCoords(milToPixel(extMil[0]+122, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+147, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avghr);
rect.setCoords(milToPixel(extMil[0]+147, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+170, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avgcadence);
aktLine += (lineH + (lineH / 3.0));
printArea.setPen(QPen(QBrush(QColor("black")), milToPixel(0.1, printer, false)));
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine, printer, true));
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine+0.5, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine+0.5, printer, true));
aktLine += (lineH / 3.0);
printed = true;
}
else
{
aktLine += (lineH + (lineH / 3.0));
aktLine += (lineH / 3.0);
}
if(cad > 0)
qs_avgcadence.sprintf("%d", cad / anz);
 
delete qt;
/* Get the laps. */
laps = 1;
// Print out the summary line and draw twi thin lines underneath
if((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 35, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, qs_name);
rect.setCoords(milToPixel(extMil[0] + 35, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 60, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_distance, false));
rect.setCoords(milToPixel(extMil[0] + 60, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 85, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_etime);
rect.setCoords(milToPixel(extMil[0] + 85, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 122, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_avgspeed, false));
rect.setCoords(milToPixel(extMil[0] + 122, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 147, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avghr);
rect.setCoords(milToPixel(extMil[0] + 147, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avgcadence);
aktLine += (lineH + (lineH / 3.0));
printArea.setPen(QPen(QBrush(QColor("black")), milToPixel(0.1, printer, false)));
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine, printer, true));
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine + 0.5, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine + 0.5, printer, true));
aktLine += (lineH / 3.0);
printed = true;
}
else
{
aktLine += (lineH + (lineH / 3.0));
aktLine += (lineH / 3.0);
}
 
for (i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
double spd;
char *un;
delete qt;
/* Get the laps. */
laps = 1;
 
if ((lap = ds.getLap(i)) == NULL)
continue;
for(i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
double spd;
char *un;
 
qt = garmin_dtime (lap->start_time);
qs_name.sprintf("Lap %03d - ", laps);
qs_name.append(kl->formatTime(qt->time(), true));
qs_distance.sprintf("%.2f %s", (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance, (Units == 1) ? "ft" : "m");
totdist += (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance;
qs_totdist.sprintf("%2.f %s", totdist, (Units == 1) ? "ft" : "m");
t = QTime(0, 0, 0, 0);
t = t.addMSecs(lap->total_time * 10);
qs_etime = t.toString("hh:mm:ss.zzz");
spd = lap->total_distance / (lap->total_time / 100.0);
delete qt;
qt = 0;
if((lap = ds.getLap(i)) == NULL)
continue;
 
if (Units == 0)
{
un = (char *)"km/h";
spd *= 3.6;
}
else
{
spd *= 3.6 / 1.609344;
un = (char *)"mph";
}
qt = garmin_dtime(lap->start_time);
qs_name.sprintf("Lap %03d - ", laps);
qs_name.append(kl->formatTime(qt->time(), true));
qs_distance.sprintf("%.2f %s", (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance, (Units == 1) ? "ft" : "m");
totdist += (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance;
qs_totdist.sprintf("%2.f %s", totdist, (Units == 1) ? "ft" : "m");
t = QTime(0, 0, 0, 0);
t = t.addMSecs(lap->total_time * 10);
qs_etime = t.toString("hh:mm:ss.zzz");
spd = lap->total_distance / (lap->total_time / 100.0);
delete qt;
qt = 0;
 
qs_avgspeed.sprintf("%.2f %s", spd, un);
if(Units == 0)
{
un = (char *)"km/h";
spd *= 3.6;
}
else
{
spd *= 3.6 / 1.609344;
un = (char *)"mph";
}
 
if (lap->total_distance > 0 && lap->total_time != 0)
{
double fact;
qs_avgspeed.sprintf("%.2f %s", spd, un);
 
if (Units == 0)
fact = 1000.0; // 1 km
else
fact = 1609.344; // 1 mile in meters
if(lap->total_distance > 0 && lap->total_time != 0)
{
double fact;
 
long secs = (double)lap->total_time / 10000.0 * (fact / lap->total_distance * 100.0);
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = kl->formatTime(t, true);
if(Units == 0)
fact = 1000.0; // 1 km
else
fact = 1609.344; // 1 mile in meters
 
if (Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
long secs = (double)lap->total_time / 10000.0 * (fact / lap->total_distance * 100.0);
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = kl->formatTime(t, true);
 
qs_avghr.sprintf("%d bpm", lap->avg_heart_rate);
if(Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
 
if (lap->avg_cadence != 0xff)
qs_avgcadence.sprintf("%d", lap->avg_cadence);
// Draw a new detail line
if ((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+35, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, qs_name);
rect.setCoords(milToPixel(extMil[0]+35, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+60, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_distance, false));
rect.setCoords(milToPixel(extMil[0]+60, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+85, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_etime);
rect.setCoords(milToPixel(extMil[0]+85, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+122, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_avgspeed, false));
rect.setCoords(milToPixel(extMil[0]+122, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+147, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avghr);
rect.setCoords(milToPixel(extMil[0]+147, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+170, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avgcadence);
printed = true;
}
qs_avghr.sprintf("%d bpm", lap->avg_heart_rate);
 
aktLine += lineH;
if(lap->avg_cadence != 0xff)
qs_avgcadence.sprintf("%d", lap->avg_cadence);
 
if (aktLine >= extMil[3]) // Print on the next page
{
aktLine = extMil[3] + 10.0;
// Draw a new detail line
if((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 35, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, qs_name);
rect.setCoords(milToPixel(extMil[0] + 35, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 60, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_distance, false));
rect.setCoords(milToPixel(extMil[0] + 60, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 85, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_etime);
rect.setCoords(milToPixel(extMil[0] + 85, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 122, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, kl->formatNumber(qs_avgspeed, false));
rect.setCoords(milToPixel(extMil[0] + 122, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 147, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avghr);
rect.setCoords(milToPixel(extMil[0] + 147, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, qs_avgcadence);
printed = true;
}
 
if ((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 8, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+170, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, i18n("Page %1").arg(page));
aktLine = extMil[1];
printed = true;
}
else
aktLine = extMil[1];
aktLine += lineH;
 
if (printed)
printer.newPage();
if(aktLine >= extMil[3]) // Print on the next page
{
aktLine = extMil[3] + 10.0;
 
page++;
// Print the headline of the table
if ((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Bold, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+35, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Lap"));
rect.setCoords(milToPixel(extMil[0]+35, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+60, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Distance"));
rect.setCoords(milToPixel(extMil[0]+60, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+85, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Time"));
rect.setCoords(milToPixel(extMil[0]+85, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+122, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Speed"));
rect.setCoords(milToPixel(extMil[0]+122, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+147, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Heart rate"));
rect.setCoords(milToPixel(extMil[0]+147, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0]+170, printer), milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Cadence"));
aktLine += lineH;
printArea.setPen(QPen(QBrush(QColor("black")), milToPixel(0.5, printer, false)));
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine, printer, true));
aktLine += 1.0;
printed = true;
}
else
{
aktLine += lineH;
aktLine += 1.0;
}
if((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 8, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, i18n("Page %1").arg(page));
aktLine = extMil[1];
printed = true;
}
else
aktLine = extMil[1];
 
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Normal, false));
}
if(printed)
printer.newPage();
 
delete qt;
laps++;
}
page++;
 
aktLine = extMil[3] + 10.0;
if ((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 8, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[0]+170, printer),
milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, i18n("Page %1").arg(page));
printed = true;
}
// Print the headline of the table
if((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Bold, false));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 35, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Lap"));
rect.setCoords(milToPixel(extMil[0] + 35, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 60, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Distance"));
rect.setCoords(milToPixel(extMil[0] + 60, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 85, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Time"));
rect.setCoords(milToPixel(extMil[0] + 85, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 122, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Speed"));
rect.setCoords(milToPixel(extMil[0] + 122, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 147, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Heart rate"));
rect.setCoords(milToPixel(extMil[0] + 147, printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignHCenter, i18n("Cadence"));
aktLine += lineH;
printArea.setPen(QPen(QBrush(QColor("black")), milToPixel(0.5, printer, false)));
printArea.drawLine(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true), milToPixel(extMil[0] + 170, printer), milToPixel(aktLine, printer, true));
aktLine += 1.0;
printed = true;
}
else
{
aktLine += lineH;
aktLine += 1.0;
}
 
aktLine = extMil[1];
page++;
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Normal, false));
}
 
if (printed && (page <= lastPage || lastPage == 0))
printer.newPage();
delete qt;
laps++;
}
 
if ((lastPage > 0 && (page < firstPage || page > lastPage)))
break;
aktLine = extMil[3] + 10.0;
 
// Draw the map on top of a new page
// Use 1/3 of the available height for the map
qreal resFact = 8; // The factor to calculate the resolution for pixmaps
int width = (int)(milToPixel(170, printer) / resFact);
int height = (int)(milToPixel(extMil[3] - extMil[1], printer, true) / resFact);
pmPrMap = QPixmap(width, height / 3); // 1/3 of page height
DIRTY = true;
int ct = curTab;
curTab = 1;
QApplication::restoreOverrideCursor();
showTrack();
QApplication::setOverrideCursor (QCursor(Qt::WaitCursor));
DIRTY = false;
curTab = ct;
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(extMil[1], printer),
pmPrMap.scaled((int)milToPixel(170, printer),
(int)milToPixel(extMil[3] - extMil[1], printer, true) / 3,
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
// Put a frame around the map
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(extMil[1], printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(extMil[1], printer, true) + (milToPixel(extMil[3] - extMil[1], printer, true) / 3));
printArea.setPen(QPen(QBrush(QColor("black")), milToPixel(0.2, printer)));
printArea.drawRect(rect);
aktLine = (extMil[3] - extMil[1]) / 3.0 + extMil[1] + lineH;
if((lastPage > 0 && page >= firstPage && page <= lastPage) ||
(lastPage == 0 && firstPage == 0))
{
printArea.setFont(QFont(QString("Helvetica"), 8, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, i18n("Page %1").arg(page));
printed = true;
}
 
// Draw the heart rate diagram
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[2], printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, i18n("Heart rate:"));
aktLine += lineH;
qreal pixHeight = (extMil[3] - aktLine) / 3.0 - lineH * 2.0;
int realH = (int)milToPixel(pixHeight, printer, true);
height = realH / (int)resFact;
showThreeCurve(width, height); // Calculate the curves
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
prHR.scaled((int)milToPixel(170, printer),
realH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + pixHeight, printer, true));
printArea.drawRect(rect);
aktLine += pixHeight + lineH;
aktLine = extMil[1];
page++;
 
// Draw the elevation diagram
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[2], printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, i18n("Elevation:"));
aktLine += lineH;
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
prElevation.scaled((int)milToPixel(170, printer),
realH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + pixHeight, printer, true));
printArea.drawRect(rect);
aktLine += pixHeight + lineH;
if(printed && (page <= lastPage || lastPage == 0))
printer.newPage();
 
// Draw the speed diagram
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[2], printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, i18n("Speed:"));
aktLine += lineH;
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
prSpeed.scaled((int)milToPixel(170, printer),
realH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + pixHeight, printer, true));
printArea.drawRect(rect);
if((lastPage > 0 && (page < firstPage || page > lastPage)))
break;
 
// Print the page number at the right bottom of the page
aktLine = extMil[3] + 10.0;
printArea.setFont(QFont(QString("Helvetica"), 8, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[0]+170, printer),
milToPixel(aktLine+lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, i18n("Page %1").arg(page));
}
// Draw the map on top of a new page
// Use 1/3 of the available height for the map
qreal resFact = 8; // The factor to calculate the resolution for pixmaps
int width = (int)(milToPixel(170, printer) / resFact);
int height = (int)(milToPixel(extMil[3] - extMil[1], printer, true) / resFact);
pmPrMap = QPixmap(width, height / 3); // 1/3 of page height
DIRTY = true;
int ct = curTab;
curTab = 1;
QApplication::restoreOverrideCursor();
showTrack();
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
DIRTY = false;
curTab = ct;
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(extMil[1], printer),
pmPrMap.scaled((int)milToPixel(170, printer),
(int)milToPixel(extMil[3] - extMil[1], printer, true) / 3,
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
// Put a frame around the map
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(extMil[1], printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(extMil[1], printer, true) + (milToPixel(extMil[3] - extMil[1], printer, true) / 3));
printArea.setPen(QPen(QBrush(QColor("black")), milToPixel(0.2, printer)));
printArea.drawRect(rect);
aktLine = (extMil[3] - extMil[1]) / 3.0 + extMil[1] + lineH;
 
rakt = rakt->next;
// Draw the heart rate diagram
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[2], printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, i18n("Heart rate:"));
aktLine += lineH;
qreal pixHeight = (extMil[3] - aktLine) / 3.0 - lineH * 2.0;
int realH = (int)milToPixel(pixHeight, printer, true);
height = realH / (int)resFact;
showThreeCurve(width, height); // Calculate the curves
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
prHR.scaled((int)milToPixel(170, printer),
realH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + pixHeight, printer, true));
printArea.drawRect(rect);
aktLine += pixHeight + lineH;
 
// Draw the elevation diagram
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[2], printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, i18n("Elevation:"));
aktLine += lineH;
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
prElevation.scaled((int)milToPixel(170, printer),
realH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + pixHeight, printer, true));
printArea.drawRect(rect);
aktLine += pixHeight + lineH;
 
// Draw the speed diagram
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[2], printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignLeft, i18n("Speed:"));
aktLine += lineH;
printArea.drawPixmap(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
prSpeed.scaled((int)milToPixel(170, printer),
realH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
rect.setCoords(milToPixel(extMil[0], printer), milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + pixHeight, printer, true));
printArea.drawRect(rect);
 
// Print the page number at the right bottom of the page
aktLine = extMil[3] + 10.0;
printArea.setFont(QFont(QString("Helvetica"), 8, QFont::Normal, false));
rect.setCoords(milToPixel(extMil[0], printer),
milToPixel(aktLine, printer, true),
milToPixel(extMil[0] + 170, printer),
milToPixel(aktLine + lineH, printer, true));
printArea.drawText(rect, Qt::AlignRight, i18n("Page %1").arg(page));
}
 
rakt = rakt->next;
}
 
printArea.end();
1192,10 → 1196,10
QSizeF r = pr.paperSize(QPrinter::DevicePixel);
QSizeF m = pr.paperSize(QPrinter::Millimeter);
 
if (!dir) // width
return r.width() / m.width() * dist;
if(!dir) // width
return r.width() / m.width() * dist;
else
return r.height() / m.height() * dist;
return r.height() / m.height() * dist;
}
 
/*
1206,59 → 1210,59
*/
void sportwatcherWidget::fileSaveAs()
{
QString fname;
QFile fn;
QString buffer;
RUN_NODE *rn, *rakt;
LAP *lap;
POINT *point;
int indent, i;
QDateTime *qt;
KUrl sDir("~/");
QRegExp rx("(\\.tcx|\\.gpx|\\.osm)$");
QString fname;
QFile fn;
QString buffer;
RUN_NODE *rn, *rakt;
LAP *lap;
POINT *point;
int indent, i;
QDateTime *qt;
KUrl sDir("~/");
QRegExp rx("(\\.tcx|\\.gpx|\\.osm)$");
 
if (!gmn)
if(!gmn)
{
KMessageBox::error(this, i18n("Currently no activity is selected!"));
return;
KMessageBox::error(this, i18n("Currently no activity is selected!"));
return;
}
 
rx.setPatternSyntax(QRegExp::RegExp);
fname = KFileDialog::getSaveFileName(sDir, QString("*.tcx|Garmin Training Center (*.tcx)\n*.gpx|GPS Excange Format (*.gpx)\n*.osm|OpenStreetMap (*.osm)"), this, QString("SportWatcher"));
 
if (fname.isEmpty())
return;
if(fname.isEmpty())
return;
 
if (rx.indexIn(fname) < 0)
if(rx.indexIn(fname) < 0)
{
KMessageBox::error(this, i18n("The file %1 has no valid file extension!").arg(fname));
return;
KMessageBox::error(this, i18n("The file %1 has no valid file extension!").arg(fname));
return;
}
 
fn.setFileName(fname);
 
if (fn.exists())
if(fn.exists())
{
if (KMessageBox::questionYesNo(this, i18n("Do you really want to overwrite this file?")) == KMessageBox::No)
return;
if(KMessageBox::questionYesNo(this, i18n("Do you really want to overwrite this file?")) == KMessageBox::No)
return;
}
 
rx.setPattern("*.gpx");
rx.setPatternSyntax(QRegExp::Wildcard);
 
if (rx.exactMatch(fname)) // Should we create a *.gpx file?
if(rx.exactMatch(fname)) // Should we create a *.gpx file?
{
sportwatcherWidget::saveGPX(fname);
return;
sportwatcherWidget::saveGPX(fname);
return;
}
 
rx.setPattern("*.osm");
rx.setPatternSyntax(QRegExp::Wildcard);
 
if (rx.exactMatch(fname)) // Should we create a *.osm file?
if(rx.exactMatch(fname)) // Should we create a *.osm file?
{
sportwatcherWidget::saveOSM(fname);
return;
sportwatcherWidget::saveOSM(fname);
return;
}
 
// No, we create a *.tcx file!
1266,16 → 1270,16
rn = ds.getRunNode();
lap = ds.getLap(rn->run->first_lap_index);
 
if ((point = ds.getPoint(lap->start_time)) == 0)
if((point = ds.getPoint(lap->start_time)) == 0)
{
KMessageBox::error(this, i18n("No data to save!"));
return;
KMessageBox::error(this, i18n("No data to save!"));
return;
}
 
if (!fn.open(QIODevice::ReadWrite | QIODevice::Truncate))
if(!fn.open(QIODevice::ReadWrite | QIODevice::Truncate))
{
KMessageBox::error(this, i18n("Error creating file %1!\nPlease check permissions").arg(fname));
return;
KMessageBox::error(this, i18n("Error creating file %1!\nPlease check permissions").arg(fname));
return;
}
 
buffer = QString("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n");
1283,186 → 1287,186
buffer.append("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
buffer.append("xsi:schemaLocation=\"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 ");
buffer.append("http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd\">\n\n");
writeTag (fn, buffer, indent);
writeTag(fn, buffer, indent);
buffer = QString("<folders/>\n\n");
writeTag (fn, buffer, indent);
writeTag(fn, buffer, indent);
 
// Open a course
QFileInfo finfo(fname);
buffer = QString("<Courses>\n <Course>\n <name>%1</name>\n").arg(QFileInfo(finfo).baseName());
writeTag (fn, buffer, indent);
writeTag(fn, buffer, indent);
indent = 2;
 
rakt = rn;
 
while (rakt)
while(rakt)
{
if (rakt->run->type != data_D1000 && rakt->run->type != data_D1009 &&
rakt->run->type != data_D1010)
{
rakt = rakt->next;
continue;
}
if(rakt->run->type != data_D1000 && rakt->run->type != data_D1009 &&
rakt->run->type != data_D1010)
{
rakt = rakt->next;
continue;
}
 
for (i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
if ((lap = ds.getLap(i)) == NULL)
continue;
for(i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
if((lap = ds.getLap(i)) == NULL)
continue;
 
// Write the information of the lap
writeTag (fn, QString("<Lap>\n"), indent);
indent++;
buffer.sprintf("<TotalTimeSeconds>%f</TotalTimeSeconds>\n", (double)lap->total_time / 100.0);
writeTag (fn, buffer, indent);
qt = garmin_dtime(lap->start_time);
buffer = QString("<StartTime>%1</StartTime>\n").arg(qt->toString("yyyy-MM-ddThh:mm:ssZ"));
writeTag (fn, buffer, indent);
buffer.sprintf("<DistanceMeters>%f</DistanceMeters>\n", lap->total_distance);
writeTag (fn, buffer, indent);
// Write the information of the lap
writeTag(fn, QString("<Lap>\n"), indent);
indent++;
buffer.sprintf("<TotalTimeSeconds>%f</TotalTimeSeconds>\n", (double)lap->total_time / 100.0);
writeTag(fn, buffer, indent);
qt = garmin_dtime(lap->start_time);
buffer = QString("<StartTime>%1</StartTime>\n").arg(qt->toString("yyyy-MM-ddThh:mm:ssZ"));
writeTag(fn, buffer, indent);
buffer.sprintf("<DistanceMeters>%f</DistanceMeters>\n", lap->total_distance);
writeTag(fn, buffer, indent);
 
writeTag (fn, QString("<BeginPosition>\n"), indent);
indent++;
buffer.sprintf("<LatitudeDegrees>%f</LatitudeDegrees>\n", SEMI2DEG(lap->begin.lat));
writeTag (fn, buffer, indent);
buffer.sprintf("<LongitudeDegrees>%f</LongitudeDegrees>\n", SEMI2DEG(lap->begin.lon));
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</BeginPosition>\n"), indent);
writeTag(fn, QString("<BeginPosition>\n"), indent);
indent++;
buffer.sprintf("<LatitudeDegrees>%f</LatitudeDegrees>\n", SEMI2DEG(lap->begin.lat));
writeTag(fn, buffer, indent);
buffer.sprintf("<LongitudeDegrees>%f</LongitudeDegrees>\n", SEMI2DEG(lap->begin.lon));
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</BeginPosition>\n"), indent);
 
writeTag (fn, QString("<EndPosition>\n"), indent);
indent++;
buffer.sprintf("<LatitudeDegrees>%f</LatitudeDegrees>\n", SEMI2DEG(lap->end.lat));
writeTag (fn, buffer, indent);
buffer.sprintf("<LongitudeDegrees>%f</LongitudeDegrees>\n", SEMI2DEG(lap->end.lon));
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</EndPosition>\n"), indent);
writeTag(fn, QString("<EndPosition>\n"), indent);
indent++;
buffer.sprintf("<LatitudeDegrees>%f</LatitudeDegrees>\n", SEMI2DEG(lap->end.lat));
writeTag(fn, buffer, indent);
buffer.sprintf("<LongitudeDegrees>%f</LongitudeDegrees>\n", SEMI2DEG(lap->end.lon));
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</EndPosition>\n"), indent);
 
writeTag (fn, QString("<AverageHeartRateBpm xsi:type=\"HeartRateInBeatsPerMinute_t\">\n"), indent);
indent++;
buffer.sprintf("<Value>%d</Value>\n", lap->avg_heart_rate);
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</AverageHeartRateBpm>\n"), indent);
writeTag(fn, QString("<AverageHeartRateBpm xsi:type=\"HeartRateInBeatsPerMinute_t\">\n"), indent);
indent++;
buffer.sprintf("<Value>%d</Value>\n", lap->avg_heart_rate);
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</AverageHeartRateBpm>\n"), indent);
 
writeTag (fn, QString("<MaximumHeartRateBpm xsi:type=\"HeartRateInBeatsPerMinute_t\">\n"), indent);
indent++;
buffer.sprintf("<Value>%d</Value>\n", lap->max_heart_rate);
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</MaximumHeartRateBpm>\n"), indent);
writeTag(fn, QString("<MaximumHeartRateBpm xsi:type=\"HeartRateInBeatsPerMinute_t\">\n"), indent);
indent++;
buffer.sprintf("<Value>%d</Value>\n", lap->max_heart_rate);
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</MaximumHeartRateBpm>\n"), indent);
 
if (lap->avg_cadence < 255)
{
buffer.sprintf("<AverageCadence>%d</AverageCadence>\n", lap->avg_cadence);
writeTag (fn, buffer, indent);
buffer.sprintf("<Cadence>%d</Cadence>\n", lap->avg_cadence);
writeTag (fn, buffer, indent);
}
if(lap->avg_cadence < 255)
{
buffer.sprintf("<AverageCadence>%d</AverageCadence>\n", lap->avg_cadence);
writeTag(fn, buffer, indent);
buffer.sprintf("<Cadence>%d</Cadence>\n", lap->avg_cadence);
writeTag(fn, buffer, indent);
}
 
buffer = QString("<Intensity>%1</Intensity>\n").arg((!lap->intensity) ? "Active" : "Resting");
writeTag (fn, buffer, indent);
buffer = QString("<Intensity>%1</Intensity>\n").arg((!lap->intensity) ? "Active" : "Resting");
writeTag(fn, buffer, indent);
 
buffer.sprintf("<Calories>%d</Calories>\n", lap->calories);
writeTag (fn, buffer, indent);
buffer.sprintf("<Calories>%d</Calories>\n", lap->calories);
writeTag(fn, buffer, indent);
 
buffer.sprintf("<MaximumSpeed>%f</MaximumSpeed>\n", lap->max_speed);
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</Lap>\n"), indent);
buffer.sprintf("<MaximumSpeed>%f</MaximumSpeed>\n", lap->max_speed);
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</Lap>\n"), indent);
 
point = ds.getPoint(lap->start_time);
writeTag (fn, QString("<Track>\n"), indent);
indent++;
point = ds.getPoint(lap->start_time);
writeTag(fn, QString("<Track>\n"), indent);
indent++;
 
while (point)
{
if (point->time > (lap->start_time + (lap->total_time / 100)))
break;
while(point)
{
if(point->time > (lap->start_time + (lap->total_time / 100)))
break;
 
writeTag (fn, QString("<Trackpoint>\n"), indent);
indent++;
qt = garmin_dtime(point->time);
buffer = QString("<Time>%1</Time>\n").arg(qt->toString("yyyy-MM-ddThh:mm:ssZ"));
writeTag (fn, buffer, indent);
delete qt;
writeTag (fn, QString("<Position>\n"), indent);
indent++;
buffer.sprintf("<LatitudeDegrees>%f</LatitudeDegrees>\n", SEMI2DEG(point->posn.lat));
writeTag (fn, buffer, indent);
buffer.sprintf("<LongitudeDegrees>%f</LongitudeDegrees>\n", SEMI2DEG(point->posn.lon));
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</Position>\n"), indent);
writeTag(fn, QString("<Trackpoint>\n"), indent);
indent++;
qt = garmin_dtime(point->time);
buffer = QString("<Time>%1</Time>\n").arg(qt->toString("yyyy-MM-ddThh:mm:ssZ"));
writeTag(fn, buffer, indent);
delete qt;
writeTag(fn, QString("<Position>\n"), indent);
indent++;
buffer.sprintf("<LatitudeDegrees>%f</LatitudeDegrees>\n", SEMI2DEG(point->posn.lat));
writeTag(fn, buffer, indent);
buffer.sprintf("<LongitudeDegrees>%f</LongitudeDegrees>\n", SEMI2DEG(point->posn.lon));
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</Position>\n"), indent);
 
if (point->alt < 20000.0)
{
buffer.sprintf("<AltitudeMeters>%f</AltitudeMeters>\n", point->alt);
writeTag (fn, buffer, indent);
}
if(point->alt < 20000.0)
{
buffer.sprintf("<AltitudeMeters>%f</AltitudeMeters>\n", point->alt);
writeTag(fn, buffer, indent);
}
 
buffer.sprintf("<DistanceMeters>%f</DistanceMeters>\n", point->distance);
writeTag (fn, buffer, indent);
buffer.sprintf("<DistanceMeters>%f</DistanceMeters>\n", point->distance);
writeTag(fn, buffer, indent);
 
if (point->heart_rate > 0 && point->heart_rate < 250)
{
writeTag (fn, QString("<HeartRateBpm xsi:type=\"HeartRateInBeatsPerMinute_t\">\n"), indent);
indent++;
buffer.sprintf("<Value>%d</Value>\n", point->heart_rate);
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</HeartRateBpm>\n"), indent);
}
if(point->heart_rate > 0 && point->heart_rate < 250)
{
writeTag(fn, QString("<HeartRateBpm xsi:type=\"HeartRateInBeatsPerMinute_t\">\n"), indent);
indent++;
buffer.sprintf("<Value>%d</Value>\n", point->heart_rate);
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</HeartRateBpm>\n"), indent);
}
 
if (point->cadence < 0xff)
{
buffer.sprintf("<Cadence>%d</Cadence>\n", point->cadence);
writeTag (fn, buffer, indent);
}
if(point->cadence < 0xff)
{
buffer.sprintf("<Cadence>%d</Cadence>\n", point->cadence);
writeTag(fn, buffer, indent);
}
 
buffer.sprintf("<SensorState>%s</SensorState>\n", (!point->sensor) ? "Absent" : "Present");
writeTag (fn, buffer, indent);
indent--;
writeTag (fn, QString("</Trackpoint>\n"), indent);
point = ds.getPoint(point->time + 1);
}
buffer.sprintf("<SensorState>%s</SensorState>\n", (!point->sensor) ? "Absent" : "Present");
writeTag(fn, buffer, indent);
indent--;
writeTag(fn, QString("</Trackpoint>\n"), indent);
point = ds.getPoint(point->time + 1);
}
 
indent--;
writeTag (fn, QString("</Track>\n"), indent);
}
indent--;
writeTag(fn, QString("</Track>\n"), indent);
}
 
indent--;
writeTag (fn, QString("</Course>\n"), indent);
indent--;
writeTag (fn, QString("</Courses>\n"), indent);
rakt = rakt->next;
indent--;
writeTag(fn, QString("</Course>\n"), indent);
indent--;
writeTag(fn, QString("</Courses>\n"), indent);
rakt = rakt->next;
}
 
// Write information about device
// Here my personal signature is written :-)
writeTag (fn, QString("<Author xsi:type=\"Application_t\">\n"), indent);
writeTag(fn, QString("<Author xsi:type=\"Application_t\">\n"), indent);
indent++;
writeTag (fn, QString("<Name>SportWatcher</Name>\n"), indent);
writeTag (fn, QString("<Build>\n"), indent);
writeTag(fn, QString("<Name>SportWatcher</Name>\n"), indent);
writeTag(fn, QString("<Build>\n"), indent);
indent++;
writeTag (fn, QString("<Version>\n"), indent);
writeTag(fn, QString("<Version>\n"), indent);
indent++;
writeTag (fn, QString("<VersionMajor>0</VersionMajor>\n"), indent);
writeTag (fn, QString("<VersionMinor>1</VersionMinor>\n"), indent);
writeTag (fn, QString("<BuildMajor>0</BuildMajor>\n"), indent);
writeTag (fn, QString("<BuildMinor>0</BuildMinor>\n"), indent);
writeTag(fn, QString("<VersionMajor>0</VersionMajor>\n"), indent);
writeTag(fn, QString("<VersionMinor>1</VersionMinor>\n"), indent);
writeTag(fn, QString("<BuildMajor>0</BuildMajor>\n"), indent);
writeTag(fn, QString("<BuildMinor>0</BuildMinor>\n"), indent);
indent--;
writeTag (fn, QString("</Version>\n"), indent);
writeTag (fn, QString("<Type>Beta</Type>\n"), indent);
writeTag (fn, QString("<Time>Jan 31 2008, 00:00:00</Time>\n"), indent);
writeTag (fn, QString("<Builder>theosys</Builder>\n"), indent);
writeTag(fn, QString("</Version>\n"), indent);
writeTag(fn, QString("<Type>Beta</Type>\n"), indent);
writeTag(fn, QString("<Time>Jan 31 2008, 00:00:00</Time>\n"), indent);
writeTag(fn, QString("<Builder>theosys</Builder>\n"), indent);
indent--;
writeTag (fn, QString("</Build>\n"), indent);
writeTag (fn, QString("<LangID>EN</LangID>\n"), indent);
writeTag (fn, QString("<PartNumber>000-00000-00</PartNumber>\n"), indent);
writeTag(fn, QString("</Build>\n"), indent);
writeTag(fn, QString("<LangID>EN</LangID>\n"), indent);
writeTag(fn, QString("<PartNumber>000-00000-00</PartNumber>\n"), indent);
indent--;
writeTag (fn, QString("</Author>\n"), indent);
writeTag (fn, QString("</TrainingCenterDatabase>\n"), indent);
writeTag(fn, QString("</Author>\n"), indent);
writeTag(fn, QString("</TrainingCenterDatabase>\n"), indent);
 
fn.close();
KMessageBox::information(this, i18n("File ") + fname + i18n(" was written successfully."));
1475,32 → 1479,32
 
void sportwatcherWidget::saveGPX(const QString &fn)
{
QFile qf;
QString buffer;
RUN_NODE *rn, *rakt;
LAP *lap;
POINT *point;
int indent;
unsigned int i;
QDateTime *qt;
double minLat, minLon, maxLat, maxLon;
QFile qf;
QString buffer;
RUN_NODE *rn, *rakt;
LAP *lap;
POINT *point;
int indent;
unsigned int i;
QDateTime *qt;
double minLat, minLon, maxLat, maxLon;
 
indent = 0;
rn = ds.getRunNode();
lap = ds.getLap(rn->run->first_lap_index);
 
if ((point = ds.getPoint(lap->start_time)) == 0)
if((point = ds.getPoint(lap->start_time)) == 0)
{
KMessageBox::error(this, i18n("No data to save!"));
return;
KMessageBox::error(this, i18n("No data to save!"));
return;
}
 
qf.setFileName(fn);
 
if (!qf.open(QIODevice::ReadWrite | QIODevice::Truncate))
if(!qf.open(QIODevice::ReadWrite | QIODevice::Truncate))
{
KMessageBox::error(this, i18n("Error creating file %1!\nPlease check permissions").arg(fn));
return;
KMessageBox::error(this, i18n("Error creating file %1!\nPlease check permissions").arg(fn));
return;
}
 
buffer = QString("<?xml version='1.0' encoding='UTF-8'?>\n");
1507,7 → 1511,7
buffer.append("<gpx version=\"1.1\" creator=\"TheoSys SportWatcher\" xmlns=\"http://www.topografix.com/GPX/1/1\">\n");
buffer.append(" <metadata>\n");
indent = 0;
writeTag (qf, buffer, indent);
writeTag(qf, buffer, indent);
 
// Find the edges of our coordinates
// We need this information in the header (metadata)
1517,79 → 1521,81
maxLat = 90.0;
maxLon = 180.0;
 
while (rakt)
while(rakt)
{
if (rakt->run->type != data_D1000 && rakt->run->type != data_D1009 &&
rakt->run->type != data_D1010)
{
rakt = rakt->next;
continue;
}
if(rakt->run->type != data_D1000 && rakt->run->type != data_D1009 &&
rakt->run->type != data_D1010)
{
rakt = rakt->next;
continue;
}
 
i = rakt->run->first_lap_index;
// get the first lap
if ((lap = ds.getLap(i)) == NULL)
continue;
i = rakt->run->first_lap_index;
 
i = 0;
// iterate the points associated with the laps
while ((point = ds.getPoint(i)) != 0)
{
if (point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
// get the first lap
if((lap = ds.getLap(i)) == NULL)
continue;
 
if (SEMI2DEG(point->posn.lat) > minLat)
minLat = SEMI2DEG(point->posn.lat);
i = 0;
 
if (SEMI2DEG(point->posn.lat) < maxLat)
maxLat = SEMI2DEG(point->posn.lat);
// iterate the points associated with the laps
while((point = ds.getPoint(i)) != 0)
{
if(point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
 
if (SEMI2DEG(point->posn.lon) > minLon)
minLon = SEMI2DEG(point->posn.lon);
if(SEMI2DEG(point->posn.lat) > minLat)
minLat = SEMI2DEG(point->posn.lat);
 
if (SEMI2DEG(point->posn.lon) < maxLon)
maxLon = SEMI2DEG(point->posn.lon);
if(SEMI2DEG(point->posn.lat) < maxLat)
maxLat = SEMI2DEG(point->posn.lat);
 
i = point->time + 1;
}
if(SEMI2DEG(point->posn.lon) > minLon)
minLon = SEMI2DEG(point->posn.lon);
 
rakt = rakt->next;
if(SEMI2DEG(point->posn.lon) < maxLon)
maxLon = SEMI2DEG(point->posn.lon);
 
i = point->time + 1;
}
 
rakt = rakt->next;
}
 
buffer.sprintf(" <bounds minlat=\"%f\" minlon=\"%f\" maxlat=\"%f\" maxlon=\"%f\" />\n",
maxLat, minLon, minLat, maxLon);
maxLat, minLon, minLat, maxLon);
buffer.append(" </metadata>\n");
buffer.append(" <trk>\n");
buffer.append(" <trkseg>\n");
writeTag (qf, buffer, indent);
writeTag(qf, buffer, indent);
indent = 3;
rn = ds.getRunNode();
lap = ds.getLap(rn->run->first_lap_index);
i = 0;
 
while ((point = ds.getPoint(i)) != 0)
while((point = ds.getPoint(i)) != 0)
{
if (point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
if(point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
 
buffer.sprintf("<trkpt lat=\"%f\" lon=\"%f\">\n",
SEMI2DEG(point->posn.lat), SEMI2DEG(point->posn.lon));
writeTag(qf, buffer, indent);
indent++;
buffer.sprintf("<ele>%f</ele>\n", point->alt);
writeTag(qf, buffer, indent);
qt = garmin_dtime(point->time);
buffer = QString("<Time>%1</Time>\n").arg(qt->toString("yyyy-MM-ddThh:mm:ssZ"));
writeTag(qf, buffer, indent);
indent--;
writeTag(qf, QString("</trkpt>\n"), indent);
i = point->time + 1;
buffer.sprintf("<trkpt lat=\"%f\" lon=\"%f\">\n",
SEMI2DEG(point->posn.lat), SEMI2DEG(point->posn.lon));
writeTag(qf, buffer, indent);
indent++;
buffer.sprintf("<ele>%f</ele>\n", point->alt);
writeTag(qf, buffer, indent);
qt = garmin_dtime(point->time);
buffer = QString("<Time>%1</Time>\n").arg(qt->toString("yyyy-MM-ddThh:mm:ssZ"));
writeTag(qf, buffer, indent);
indent--;
writeTag(qf, QString("</trkpt>\n"), indent);
i = point->time + 1;
}
 
indent = 0;
1603,38 → 1609,38
 
void sportwatcherWidget::saveOSM(const QString &fn)
{
QFile qf;
QString buffer;
RUN_NODE *rn, *rakt;
LAP *lap;
POINT *point;
int indent, id, j;
unsigned int i;
double minLat, minLon, maxLat, maxLon;
QDateTime *qt;
QFile qf;
QString buffer;
RUN_NODE *rn, *rakt;
LAP *lap;
POINT *point;
int indent, id, j;
unsigned int i;
double minLat, minLon, maxLat, maxLon;
QDateTime *qt;
 
indent = 0;
rn = ds.getRunNode();
lap = ds.getLap(rn->run->first_lap_index);
 
if ((point = ds.getPoint(lap->start_time)) == 0)
if((point = ds.getPoint(lap->start_time)) == 0)
{
KMessageBox::error(this, i18n("No data to save!"));
return;
KMessageBox::error(this, i18n("No data to save!"));
return;
}
 
qf.setFileName(fn);
 
if (!qf.open(QIODevice::ReadWrite | QIODevice::Truncate))
if(!qf.open(QIODevice::ReadWrite | QIODevice::Truncate))
{
KMessageBox::error(this, i18n("Error creating file %1!\nPlease check permissions").arg(fn));
return;
KMessageBox::error(this, i18n("Error creating file %1!\nPlease check permissions").arg(fn));
return;
}
 
buffer = QString("<?xml version='1.0' encoding='UTF-8'?>\n");
buffer.append("<osm version=\"0.5\" generator=\"TheoSys SportWatcher\">\n");
indent = 0;
writeTag (qf, buffer, indent);
writeTag(qf, buffer, indent);
// Find the edges of our coordinates
// We need this information in the header (metadata)
rakt = rn;
1643,51 → 1649,53
maxLat = 90.0;
maxLon = 180.0;
 
while (rakt)
while(rakt)
{
if (rakt->run->type != data_D1000 && rakt->run->type != data_D1009 &&
rakt->run->type != data_D1010)
{
rakt = rakt->next;
continue;
}
if(rakt->run->type != data_D1000 && rakt->run->type != data_D1009 &&
rakt->run->type != data_D1010)
{
rakt = rakt->next;
continue;
}
 
i = rakt->run->first_lap_index;
// get the first lap
if ((lap = ds.getLap(i)) == NULL)
continue;
i = rakt->run->first_lap_index;
 
i = 0;
// iterate the points associated with the laps
while ((point = ds.getPoint(i)) != 0)
{
if (point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
// get the first lap
if((lap = ds.getLap(i)) == NULL)
continue;
 
if (SEMI2DEG(point->posn.lat) > minLat)
minLat = SEMI2DEG(point->posn.lat);
i = 0;
 
if (SEMI2DEG(point->posn.lat) < maxLat)
maxLat = SEMI2DEG(point->posn.lat);
// iterate the points associated with the laps
while((point = ds.getPoint(i)) != 0)
{
if(point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
 
if (SEMI2DEG(point->posn.lon) > minLon)
minLon = SEMI2DEG(point->posn.lon);
if(SEMI2DEG(point->posn.lat) > minLat)
minLat = SEMI2DEG(point->posn.lat);
 
if (SEMI2DEG(point->posn.lon) < maxLon)
maxLon = SEMI2DEG(point->posn.lon);
if(SEMI2DEG(point->posn.lat) < maxLat)
maxLat = SEMI2DEG(point->posn.lat);
 
i = point->time + 1;
}
if(SEMI2DEG(point->posn.lon) > minLon)
minLon = SEMI2DEG(point->posn.lon);
 
rakt = rakt->next;
if(SEMI2DEG(point->posn.lon) < maxLon)
maxLon = SEMI2DEG(point->posn.lon);
 
i = point->time + 1;
}
 
rakt = rakt->next;
}
 
buffer.sprintf(" <bound box='%f,%f,%f,%f' origin='http://www.openstreetmap.org/api/0.5' />\n",
maxLat, minLon, minLat, maxLon);
writeTag (qf, buffer, indent);
maxLat, minLon, minLat, maxLon);
writeTag(qf, buffer, indent);
indent = 1;
rn = ds.getRunNode();
lap = ds.getLap(rn->run->first_lap_index);
1694,38 → 1702,38
i = 0;
id = -1;
 
while ((point = ds.getPoint(i)) != 0)
while((point = ds.getPoint(i)) != 0)
{
if (point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
if(point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
 
buffer.sprintf("<node id='%d' action='modify' visible='true' lat=\"%f\" lon=\"%f\">\n",
id, SEMI2DEG(point->posn.lat), SEMI2DEG(point->posn.lon));
writeTag(qf, buffer, indent);
indent++;
buffer = QString("<tag k='created_by' v='TheoSys Sportwatcher' />\n");
writeTag(qf, buffer, indent);
buffer = QString("<tag k='highway' v='tertiary' />\n");
writeTag(qf, buffer, indent);
indent--;
writeTag(qf, QString("</node>\n"), indent);
id--;
i = point->time + 1;
buffer.sprintf("<node id='%d' action='modify' visible='true' lat=\"%f\" lon=\"%f\">\n",
id, SEMI2DEG(point->posn.lat), SEMI2DEG(point->posn.lon));
writeTag(qf, buffer, indent);
indent++;
buffer = QString("<tag k='created_by' v='TheoSys Sportwatcher' />\n");
writeTag(qf, buffer, indent);
buffer = QString("<tag k='highway' v='tertiary' />\n");
writeTag(qf, buffer, indent);
indent--;
writeTag(qf, QString("</node>\n"), indent);
id--;
i = point->time + 1;
}
 
qt = garmin_dtime(lap->start_time);
buffer.sprintf("<way id='%d' action='modify' visible='true' timestamp='%s'>\n",
id, QString(qt->toString("yyyy-MM-ddThh:mm:ssZ")).toAscii().data());
id, QString(qt->toString("yyyy-MM-ddThh:mm:ssZ")).toAscii().data());
writeTag(qf, buffer, indent);
indent++;
 
for (j = -1; j > id; j--)
for(j = -1; j > id; j--)
{
buffer.sprintf("<nd ref='%d' />\n", j);
writeTag(qf, buffer, indent);
buffer.sprintf("<nd ref='%d' />\n", j);
writeTag(qf, buffer, indent);
}
 
indent--;
1738,32 → 1746,32
 
void sportwatcherWidget::fileOpen()
{
QString fname = KFileDialog::getOpenFileName(Data, QString("*.gmn"), this, QString("SportWatcher"));
int m;
QString fname = KFileDialog::getOpenFileName(Data, QString("*.gmn"), this, QString("SportWatcher"));
int m;
 
if (fname.isEmpty())
return;
if(fname.isEmpty())
return;
 
spw.destroy();
 
if (spw.setFileName(fname.toAscii().data()) == -1)
return;
if(spw.setFileName(fname.toAscii().data()) == -1)
return;
 
if (gmn)
garmin_free_data (gmn);
if(gmn)
garmin_free_data(gmn);
 
gmn = spw.readFile();
zfactor = 0;
 
if ((m = garmin_count_error()) > 0)
if((m = garmin_count_error()) > 0)
{
int i, key = -1;
int i, key = -1;
 
for (i = 0; i < m; i++)
KMessageBox::error(this, QString(garmin_get_next_error(&key)));
for(i = 0; i < m; i++)
KMessageBox::error(this, QString(garmin_get_next_error(&key)));
 
garmin_clear_errors();
return;
garmin_clear_errors();
return;
}
 
DIRTY = true;
1772,10 → 1780,10
showTrack();
showCurves();
 
if (curTab == 2)
if(curTab == 2)
{
showThreeCurve();
tabDirt2 = false;
showThreeCurve();
tabDirt2 = false;
}
 
tabDirt0 = tabDirt3 = false;
1782,6 → 1790,98
DIRTY = false;
}
 
/**
* This function is called from the XML parser in "gmn_import"
* whenever an activity is complete.
* Necessary because there may be more than one activity in a history
* file.
*/
void sportwatcherWidget::saveImported(void *gd)
{
gmn_import import;
QString tgfile, fld, px;
RUN_NODE *rn;
LAP *lap;
garmin_data *g = (garmin_data *)gd;
QFileInfo datei;
QPixmap qpx;
QList<QTreeWidgetItem *>item;
QTreeWidgetItem *el, *it;
 
if(!g)
{
std::cerr << "sportwatcherWidget::saveImported: Empty data! Nothing was saved!" << std::endl;
return;
}
 
// Find the filename;
// It consists of the date and the time.
// We need this information to set the correct path to store the file.
tgfile = Data; // The base path
rn = ds.getRunNode();
lap = ds.getLap(rn->run->first_lap_index);
QDateTime *qt = garmin_dtime(lap->start_time);
tgfile.append(qt->toString("/yyyy")); // year is a folder
tgfile.append(qt->toString("/MM")); // month is a folder
tgfile.append(qt->toString("/yyyyMMddThhmmss")); // The file name
tgfile.append(".gmn"); // Extension of file name
datei.setFile(tgfile);
std:cerr << "sportwatcherWidget::saveImported:Saving to file " << datei.absoluteFilePath().toAscii().data() << std::endl;
// save the data to a real file, but only if it doesn't exist allready.
garmin_save_all(g, datei.fileName().toAscii().data(), datei.absolutePath().toAscii().data(), 0);
 
// in case the item is already in the list on the left side, we
// only highlight the item.
item = ui_sportwatcherWidgetBase.liActivities->findItems(tgfile, Qt::MatchExactly);
 
if(item.size() > 0)
{
ui_sportwatcherWidgetBase.liActivities->setItemSelected(item.at(0), true);
ui_sportwatcherWidgetBase.liActivities->setCurrentItem(item.at(0));
return;
}
 
// insert everything into the list on the left side
switch(rn->run->sport_type)
{
case D1000_running:
fld = i18n("Running");
px = QString("spw-running");
break;
 
case D1000_biking:
fld = i18n("Biking");
px = QString("bike");
break;
 
default:
fld = i18n("Others");
px = QString("other");
}
 
// Do we have allready so items in the list?
item = ui_sportwatcherWidgetBase.liActivities->findItems(fld, Qt::MatchExactly);
 
if(item.size() > 0)
{
el = new QTreeWidgetItem(item.at(0));
el->setText(0, kl->formatDateTime(*qt, KLocale::ShortDate, true));
el->setData(0, Qt::UserRole, tgfile);
el->setIcon(0, KIcon(px));
}
else // no, this is the first item. (shouldn't be!)
{
it = new QTreeWidgetItem(ui_sportwatcherWidgetBase.liActivities);
it->setText(0, fld);
it->setIcon(0, KIcon(QString("history")));
 
el = new QTreeWidgetItem(item.at(0));
el->setText(0, kl->formatDateTime(*qt, KLocale::ShortDate, true));
el->setData(0, Qt::UserRole, tgfile);
el->setIcon(0, KIcon(px));
}
}
 
void sportwatcherWidget::fileImport()
{
QString fname = KFileDialog::getOpenFileName(QString("~/"), QString("*.tcx"), this, QString("SportWatcher"));
1795,25 → 1895,26
LAP *lap;
RUN_NODE *rn;
 
if (fname.isEmpty())
return;
if(fname.isEmpty())
return;
 
import.setFile(fname);
import.connectCallback(this);
import.setFile(fname);
 
if ((m = import.import()) != 0)
if((m = import.import()) != 0)
{
KMessageBox::error(this, QString(import.getError(m)));
return;
KMessageBox::error(this, QString(import.getError(m)));
return;
}
 
if (gmn)
if(gmn)
{
garmin_free_data (gmn);
gmn = 0;
garmin_free_data(gmn);
gmn = 0;
}
 
if (!(gmn = import.getGarminData ()))
return;
if(!(gmn = import.getGarminData()))
return;
 
DIRTY = true;
tabDirt0 = tabDirt1 = tabDirt2 = tabDirt3 = true;
1821,10 → 1922,10
showTrack();
showCurves();
 
if (curTab == 2)
if(curTab == 2)
{
showThreeCurve();
tabDirt2 = false;
showThreeCurve();
tabDirt2 = false;
}
 
tabDirt0 = tabDirt3 = false;
1836,64 → 1937,65
tgfile = Data; // The base path
rn = ds.getRunNode();
lap = ds.getLap(rn->run->first_lap_index);
QDateTime *qt = garmin_dtime (lap->start_time);
tgfile.append (qt->toString ("/yyyy")); // year is a folder
tgfile.append (qt->toString ("/MM")); // month is a folder
tgfile.append (qt->toString ("/yyyyMMddThhmmss")); // The file name
tgfile.append (".gmn"); // Extension of file name
datei.setFile (tgfile);
QDateTime *qt = garmin_dtime(lap->start_time);
tgfile.append(qt->toString("/yyyy")); // year is a folder
tgfile.append(qt->toString("/MM")); // month is a folder
tgfile.append(qt->toString("/yyyyMMddThhmmss")); // The file name
tgfile.append(".gmn"); // Extension of file name
datei.setFile(tgfile);
std:cerr << "sportwatcherWidget::fileImport:Saving to file " << datei.absoluteFilePath().toAscii().data() << std::endl;
// save the data to a real file, but only if it doesn't exist allready.
garmin_save_all (gmn, datei.fileName().toAscii().data(), datei.absolutePath().toAscii().data(), 0);
garmin_save_all(gmn, datei.fileName().toAscii().data(), datei.absolutePath().toAscii().data(), 0);
 
// in case the item is already in the list on the left side, we
// only highlight the item.
item = ui_sportwatcherWidgetBase.liActivities->findItems (tgfile, Qt::MatchExactly);
item = ui_sportwatcherWidgetBase.liActivities->findItems(tgfile, Qt::MatchExactly);
 
if (item.size() > 0)
if(item.size() > 0)
{
ui_sportwatcherWidgetBase.liActivities->setItemSelected (item.at(0), true);
ui_sportwatcherWidgetBase.liActivities->setCurrentItem (item.at(0));
return;
ui_sportwatcherWidgetBase.liActivities->setItemSelected(item.at(0), true);
ui_sportwatcherWidgetBase.liActivities->setCurrentItem(item.at(0));
return;
}
 
// insert everything into the list on the left side
switch (rn->run->sport_type)
switch(rn->run->sport_type)
{
case D1000_running:
fld = i18n("Running");
px = QString("spw-running");
break;
case D1000_running:
fld = i18n("Running");
px = QString("spw-running");
break;
 
case D1000_biking:
fld = i18n("Biking");
px = QString("bike");
break;
case D1000_biking:
fld = i18n("Biking");
px = QString("bike");
break;
 
default:
fld = i18n("Others");
px = QString("other");
default:
fld = i18n("Others");
px = QString("other");
}
 
// Do we have allready so items in the list?
item = ui_sportwatcherWidgetBase.liActivities->findItems (fld, Qt::MatchExactly);
item = ui_sportwatcherWidgetBase.liActivities->findItems(fld, Qt::MatchExactly);
 
if (item.size() > 0)
if(item.size() > 0)
{
el = new QTreeWidgetItem(item.at(0));
el->setText(0, kl->formatDateTime(*qt, KLocale::ShortDate, true));
el->setData(0, Qt::UserRole, tgfile);
el->setIcon(0, KIcon(px));
el = new QTreeWidgetItem(item.at(0));
el->setText(0, kl->formatDateTime(*qt, KLocale::ShortDate, true));
el->setData(0, Qt::UserRole, tgfile);
el->setIcon(0, KIcon(px));
}
else // no, this is the first item. (shouldn't be!)
{
it = new QTreeWidgetItem(ui_sportwatcherWidgetBase.liActivities);
it->setText(0, fld);
it->setIcon(0, KIcon(QString("history")));
it = new QTreeWidgetItem(ui_sportwatcherWidgetBase.liActivities);
it->setText(0, fld);
it->setIcon(0, KIcon(QString("history")));
 
el = new QTreeWidgetItem(item.at(0));
el->setText(0, kl->formatDateTime(*qt, KLocale::ShortDate, true));
el->setData(0, Qt::UserRole, tgfile);
el->setIcon(0, KIcon(px));
el = new QTreeWidgetItem(item.at(0));
el->setText(0, kl->formatDateTime(*qt, KLocale::ShortDate, true));
el->setData(0, Qt::UserRole, tgfile);
el->setIcon(0, KIcon(px));
}
}
 
1902,90 → 2004,90
*/
void sportwatcherWidget::editRename()
{
bool ok;
QString name, inhalt;
QList<QTreeWidgetItem *> item;
QTreeWidgetItem *lvItem;
QFileInfo datei;
RUN_NODE *rn;
LAP *lap;
garmin_list *list;
D1009 *n;
bool ok;
QString name, inhalt;
QList<QTreeWidgetItem *> item;
QTreeWidgetItem *lvItem;
QFileInfo datei;
RUN_NODE *rn;
LAP *lap;
garmin_list *list;
D1009 *n;
 
if (!gmn)
if(!gmn)
{
KMessageBox::error(this, i18n("There is no session selected!"));
return;
KMessageBox::error(this, i18n("There is no session selected!"));
return;
}
 
rn = ds.getRunNode();
item = ui_sportwatcherWidgetBase.liActivities->selectedItems ();
item = ui_sportwatcherWidgetBase.liActivities->selectedItems();
lvItem = item.first();
 
if (!isdigit(rn->run->workout.name[0]))
inhalt = lvItem->text(0);
if(!isdigit(rn->run->workout.name[0]))
inhalt = lvItem->text(0);
else
inhalt.clear();
inhalt.clear();
 
name = KInputDialog::getText(i18n("Rename session"), i18n("Session name"),
inhalt, &ok, this, (QValidator *)0, QString("Nxxxxxxxxxxxxxx"),
i18n("Enter a new name for the currently selected activity."));
inhalt, &ok, this, (QValidator *)0, QString("Nxxxxxxxxxxxxxx"),
i18n("Enter a new name for the currently selected activity."));
 
if (!ok)
return;
if(!ok)
return;
 
if (name.length() <= 1)
if(name.length() <= 1)
{
lap = ds.getLap(rn->run->first_lap_index);
const QDateTime *qt = garmin_dtime (lap->start_time);
QString idx = kl->formatDateTime(*qt, KLocale::ShortDate, true);
lvItem->setText (0, idx);
datei.setFile (lvItem->data(0, Qt::UserRole).toString());
garmin_save_all (gmn, datei.fileName().toAscii().data(), datei.absolutePath().toAscii().data(), 1);
delete qt;
return;
lap = ds.getLap(rn->run->first_lap_index);
const QDateTime *qt = garmin_dtime(lap->start_time);
QString idx = kl->formatDateTime(*qt, KLocale::ShortDate, true);
lvItem->setText(0, idx);
datei.setFile(lvItem->data(0, Qt::UserRole).toString());
garmin_save_all(gmn, datei.fileName().toAscii().data(), datei.absolutePath().toAscii().data(), 1);
delete qt;
return;
}
 
strncpy (rn->run->workout.name, name.toAscii().data(), 16);
strncpy(rn->run->workout.name, name.toAscii().data(), 16);
 
if (gmn->type != data_Dlist)
if(gmn->type != data_Dlist)
{
KMessageBox::error(this, i18n("editRename: Unexpected structure type %1 found!").arg(gmn->type));
return;
KMessageBox::error(this, i18n("editRename: Unexpected structure type %1 found!").arg(gmn->type));
return;
}
 
list = (garmin_list *)gmn->data;
 
if (list->head->data->type != data_D1009) // This should be the run node
if(list->head->data->type != data_D1009) // This should be the run node
{
KMessageBox::error(this, i18n("editRename: The run node was not found!"));
return;
KMessageBox::error(this, i18n("editRename: The run node was not found!"));
return;
}
 
n = (D1009 *)list->head->data->data;
strncpy (n->workout.name, rn->run->workout.name, 15);
lvItem->setText (0, name);
datei.setFile (lvItem->data(0, Qt::UserRole).toString());
garmin_save_all (gmn, datei.fileName().toAscii().data(), datei.absolutePath().toAscii().data(), 1);
strncpy(n->workout.name, rn->run->workout.name, 15);
lvItem->setText(0, name);
datei.setFile(lvItem->data(0, Qt::UserRole).toString());
garmin_save_all(gmn, datei.fileName().toAscii().data(), datei.absolutePath().toAscii().data(), 1);
}
 
void sportwatcherWidget::fileNew()
{
progressWidget *dlg = new progressWidget(this);
progressWidget *dlg = new progressWidget(this);
 
dlg->show();
 
if (!dlg->Download())
if(!dlg->Download())
{
int m, key;
int m, key;
 
key = -1;
key = -1;
 
for (m = 0; m < garmin_count_error(); m++)
KMessageBox::error(this, QString(garmin_get_next_error(&key)));
for(m = 0; m < garmin_count_error(); m++)
KMessageBox::error(this, QString(garmin_get_next_error(&key)));
}
else
getActivities();
getActivities();
 
garmin_clear_errors();
delete dlg;
2003,49 → 2105,49
*/
void sportwatcherWidget::extrasSaveHR()
{
QString fname, str1, str2;
QFile fdfile;
QDateTime *qt, *oldqt;
QDate dat;
QTime t;
QDir dir = QDir::home();
char hv0[256];
RUN_NODE *rn;
LAP *lap, *alap;
POINT *point;
int samples, smp, seconds, anz, nsec, samsec;
int avgHeart, minHeart, maxHeart, aktHeart;
int secRange1, secRange2, secRange3, secAbove, secBeyond;
QString fname, str1, str2;
QFile fdfile;
QDateTime *qt, *oldqt;
QDate dat;
QTime t;
QDir dir = QDir::home();
char hv0[256];
RUN_NODE *rn;
LAP *lap, *alap;
POINT *point;
int samples, smp, seconds, anz, nsec, samsec;
int avgHeart, minHeart, maxHeart, aktHeart;
int secRange1, secRange2, secRange3, secAbove, secBeyond;
 
if (!gmn)
if(!gmn)
{
KMessageBox::information(this, i18n("There is no activity open"));
return;
KMessageBox::information(this, i18n("There is no activity open"));
return;
}
 
if (HRM.isEmpty())
str1 = dir.path();
if(HRM.isEmpty())
str1 = dir.path();
else
str1 = HRM;
str1 = HRM;
 
str1 += "/" + StartTime.toString("yyyyMMddThhmmss.zzz.hrm");
fname = KFileDialog::getSaveFileName(str1, QString("*.hrm"), this, QString("SportWatcher"));
 
if (fname.isEmpty())
return;
if(fname.isEmpty())
return;
 
fdfile.setFileName(fname);
 
if (fdfile.exists())
if(fdfile.exists())
{
if (KMessageBox::questionYesNo(this, i18n("Do you really want to overwrite this file?")) == KMessageBox::No)
return;
if(KMessageBox::questionYesNo(this, i18n("Do you really want to overwrite this file?")) == KMessageBox::No)
return;
}
 
if (!fdfile.open(QIODevice::ReadWrite | QIODevice::Truncate))
if(!fdfile.open(QIODevice::ReadWrite | QIODevice::Truncate))
{
KMessageBox::error(this, i18n("Error creating a file!\nPlease check permissions."));
return;
KMessageBox::error(this, i18n("Error creating a file!\nPlease check permissions."));
return;
}
 
rn = ds.getRunNode();
2053,43 → 2155,43
t = StartTime.time();
dat = StartTime.date();
 
if ((point = ds.getPoint(lap->start_time)) == 0)
if((point = ds.getPoint(lap->start_time)) == 0)
{
fdfile.close();
return;
fdfile.close();
return;
}
 
strcpy (hv0, "[Params]\n");
strcpy(hv0, "[Params]\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
str1 = dat.toString("yyyyMMdd");
str2 = t.toString("hh:mm:ss.z");
sprintf(hv0, "Version=106\nMonitor=11\nSMode=000000000\nDate=%s\nStartTime=%s\n",
str1.toAscii().data(), str2.toAscii().data());
str1.toAscii().data(), str2.toAscii().data());
write(fdfile.handle(), &hv0[0], strlen(hv0));
t.setHMS(0, 0, 0);
t = t.addSecs(max_time);
str2 = t.toString("hh:mm:ss.z");
 
switch (sampleTime)
switch(sampleTime)
{
case 0: samsec = 5; break;
case 1: samsec = 15; break;
case 2: samsec = 30; break;
case 3: samsec = 60; break;
default:
samsec = 15;
case 0: samsec = 5; break;
case 1: samsec = 15; break;
case 2: samsec = 30; break;
case 3: samsec = 60; break;
default:
samsec = 15;
}
 
sprintf(hv0, "Length=%s\nInterval=%d\nUpper1=%d\nLower1=%d\nUpper2=%d\n",
str2.toAscii().data(), samsec, upper1, lower1, upper2);
str2.toAscii().data(), samsec, upper1, lower1, upper2);
write(fdfile.handle(), &hv0[0], strlen(hv0));
sprintf(hv0, "Lower2=%d\nUpper3=%d\nLower3=%d\nTimer1=00:00:00.0\n",
lower2, upper3, lower3);
lower2, upper3, lower3);
write(fdfile.handle(), &hv0[0], strlen(hv0));
strcpy(hv0, "Timer2=00:00:00.0\nTimer3=00:00:00.0\nActiveLimit=0\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
sprintf(hv0, "MaxHR=%d\nRestHR=%d\nStartDelay=0\nVO2max=%d\nWeight=%d\n\n",
MaxHr, restHr, vo2max, weight);
MaxHr, restHr, vo2max, weight);
write(fdfile.handle(), &hv0[0], strlen(hv0));
 
// Write the intervall times. One block for every lap
2098,73 → 2200,73
write(fdfile.handle(), &hv0[0], strlen(hv0));
t.setHMS(0, 0, 0);
 
for (unsigned int i = rn->run->first_lap_index; i < rn->run->last_lap_index; i++)
for(unsigned int i = rn->run->first_lap_index; i < rn->run->last_lap_index; i++)
{
alap = ds.getLap(i);
point = ds.getPoint(alap->start_time);
oldqt = garmin_dtime(point->time);
avgHeart = minHeart = maxHeart = aktHeart = 0;
anz = 0;
unsigned long lastTime = point->time;
int totSec = 0;
alap = ds.getLap(i);
point = ds.getPoint(alap->start_time);
oldqt = garmin_dtime(point->time);
avgHeart = minHeart = maxHeart = aktHeart = 0;
anz = 0;
unsigned long lastTime = point->time;
int totSec = 0;
 
while (point)
{
if (point->time > (alap->start_time + (alap->total_time / 100)))
break;
while(point)
{
if(point->time > (alap->start_time + (alap->total_time / 100)))
break;
 
if (point->heart_rate > 0)
{
avgHeart += point->heart_rate;
nsec = point->time - lastTime;
totSec += nsec;
if(point->heart_rate > 0)
{
avgHeart += point->heart_rate;
nsec = point->time - lastTime;
totSec += nsec;
 
if (minHeart == 0 || minHeart > point->heart_rate)
minHeart = point->heart_rate;
if(minHeart == 0 || minHeart > point->heart_rate)
minHeart = point->heart_rate;
 
if (maxHeart < point->heart_rate)
maxHeart = point->heart_rate;
if(maxHeart < point->heart_rate)
maxHeart = point->heart_rate;
 
if (aktHeart == 0 && totSec >= samsec)
aktHeart = avgHeart / (anz + 1);
if(aktHeart == 0 && totSec >= samsec)
aktHeart = avgHeart / (anz + 1);
 
if (point->heart_rate < lower1)
secBeyond += nsec;
else if (point->heart_rate < lower2)
secRange1 += nsec;
else if (point->heart_rate < lower3)
secRange2 += nsec;
else if (point->heart_rate < upper3)
secRange3 += nsec;
else
secAbove += nsec;
if(point->heart_rate < lower1)
secBeyond += nsec;
else if(point->heart_rate < lower2)
secRange1 += nsec;
else if(point->heart_rate < lower3)
secRange2 += nsec;
else if(point->heart_rate < upper3)
secRange3 += nsec;
else
secAbove += nsec;
 
lastTime = point->time;
anz++;
}
lastTime = point->time;
anz++;
}
 
point = ds.getPoint(point->time+1);
}
point = ds.getPoint(point->time + 1);
}
 
t = t.addSecs(alap->total_time / 100);
str1 = t.toString("hh:mm:ss.z");
t = t.addSecs(alap->total_time / 100);
str1 = t.toString("hh:mm:ss.z");
 
if (anz > 0)
avgHeart = avgHeart / anz;
else
avgHeart = 0;
if(anz > 0)
avgHeart = avgHeart / anz;
else
avgHeart = 0;
 
sprintf(hv0, "%s\t %d\t %d\t %d\t %d\n",
str1.toAscii().data(), aktHeart, minHeart, avgHeart, maxHeart);
write(fdfile.handle(), &hv0[0], strlen(hv0));
strcpy(hv0, "32\t 0\t 0\t 0\t 0\t 0\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
strcpy(hv0, "0\t 0\t 0\t 0\t 0\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
sprintf(hv0, "0\t %d\t 0\t 0\t 0\t 0\n", (int)alap->total_distance);
write(fdfile.handle(), &hv0[0], strlen(hv0));
strcpy(hv0, "0\t 0\t 0\t 0\t 0\t 0\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
sprintf(hv0, "%s\t %d\t %d\t %d\t %d\n",
str1.toAscii().data(), aktHeart, minHeart, avgHeart, maxHeart);
write(fdfile.handle(), &hv0[0], strlen(hv0));
strcpy(hv0, "32\t 0\t 0\t 0\t 0\t 0\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
strcpy(hv0, "0\t 0\t 0\t 0\t 0\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
sprintf(hv0, "0\t %d\t 0\t 0\t 0\t 0\n", (int)alap->total_distance);
write(fdfile.handle(), &hv0[0], strlen(hv0));
strcpy(hv0, "0\t 0\t 0\t 0\t 0\t 0\n");
write(fdfile.handle(), &hv0[0], strlen(hv0));
}
 
strcpy(hv0, "\n[IntNotes]\n\n[ExtraData]\n\n");
2174,25 → 2276,25
write(fdfile.handle(), &hv0[0], strlen(hv0)); // Time limits 1
smp = max_time - secBeyond - secRange1 - secRange2 - secRange3 - secAbove;
sprintf(hv0, "%lu\t %u\t %u\t %u\t %u\n",
max_time, secRange1, secRange2 + secRange3,
secAbove + secBeyond, smp);
max_time, secRange1, secRange2 + secRange3,
secAbove + secBeyond, smp);
write(fdfile.handle(), &hv0[0], strlen(hv0)); // limits 1
sprintf(hv0, "%d\t %d\t %d\t %d\n",
MaxHr, upper1, lower1, restHr);
MaxHr, upper1, lower1, restHr);
write(fdfile.handle(), &hv0[0], strlen(hv0)); // Time limits 1
sprintf(hv0, "%lu\t %u\t %u\t %u\t %u\n",
max_time, secRange2, secRange1 + secRange3,
secAbove + secBeyond, smp);
max_time, secRange2, secRange1 + secRange3,
secAbove + secBeyond, smp);
write(fdfile.handle(), &hv0[0], strlen(hv0)); // limits 2
sprintf(hv0, "%d\t %d\t %d\t %d\n",
MaxHr, upper2, lower2, restHr);
MaxHr, upper2, lower2, restHr);
write(fdfile.handle(), &hv0[0], strlen(hv0)); // Time limits 2
sprintf(hv0, "%lu\t %u\t %u\t %u\t %u\n",
max_time, secRange3, secRange1 + secRange2,
secAbove + secBeyond, smp);
max_time, secRange3, secRange1 + secRange2,
secAbove + secBeyond, smp);
write(fdfile.handle(), &hv0[0], strlen(hv0)); // limits 3
sprintf(hv0, "%d\t %d\t %d\t %d\n",
MaxHr, upper3, lower3, restHr);
MaxHr, upper3, lower3, restHr);
write(fdfile.handle(), &hv0[0], strlen(hv0)); // Time limits 3
samples = max_time / samsec;
sprintf(hv0, "0\t %u\n\n", samples); // samples
2208,7 → 2310,7
write(fdfile.handle(), &hv0[0], strlen(hv0));
 
sprintf(hv0, "[HRZones]\n%d\n%d\n%d\n%d\n%d\n%d\n0\n0\n0\n0\n0\n\n",
MaxHr, upper3, upper2, upper1, lower1, restHr);
MaxHr, upper3, upper2, upper1, lower1, restHr);
write(fdfile.handle(), &hv0[0], strlen(hv0));
 
strcpy(hv0, "[HRData]\n");
2222,46 → 2324,46
qt = 0;
point = ds.getPoint(lap->start_time);
 
while (point)
while(point)
{
if (seconds >= nsec)
{
if (anz > 0)
{
sprintf(hv0, "%d\n", smp / anz);
write(fdfile.handle(), &hv0[0], strlen(hv0));
}
if(seconds >= nsec)
{
if(anz > 0)
{
sprintf(hv0, "%d\n", smp / anz);
write(fdfile.handle(), &hv0[0], strlen(hv0));
}
 
if (smp > 0 && seconds >= (nsec + samsec))
{
if (anz <= 0)
anz = 0;
if(smp > 0 && seconds >= (nsec + samsec))
{
if(anz <= 0)
anz = 0;
 
for (int x = nsec; x < seconds; x += samsec)
{
sprintf(hv0, "%d\n", smp / anz);
write(fdfile.handle(), &hv0[0], strlen(hv0));
nsec += samsec;
}
}
anz = 0;
smp = 0;
nsec += samsec;
}
for(int x = nsec; x < seconds; x += samsec)
{
sprintf(hv0, "%d\n", smp / anz);
write(fdfile.handle(), &hv0[0], strlen(hv0));
nsec += samsec;
}
}
 
qt = garmin_dtime (point->time);
seconds += oldqt->secsTo(*qt);
anz = 0;
smp = 0;
nsec += samsec;
}
 
if (point->heart_rate > 0)
{
smp += point->heart_rate;
anz++;
}
qt = garmin_dtime(point->time);
seconds += oldqt->secsTo(*qt);
 
delete oldqt;
oldqt = qt;
point = ds.getPoint(point->time + 1);
if(point->heart_rate > 0)
{
smp += point->heart_rate;
anz++;
}
 
delete oldqt;
oldqt = qt;
point = ds.getPoint(point->time + 1);
}
 
fdfile.close();
2270,32 → 2372,32
 
void sportwatcherWidget::extrasSettings()
{
settingsWidget *dlg = new settingsWidget(this);
settingsWidget *dlg = new settingsWidget(this);
 
if (dlg->exec() == QDialog::Accepted)
if(dlg->exec() == QDialog::Accepted)
{
KConfig cfg(QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup ic (&cfg, "SportWatcher");
lower1 = ic.readEntry("lower1", 0);
lower2 = ic.readEntry("lower2", 0);
lower3 = ic.readEntry("lower3", 0);
upper1 = ic.readEntry("upper1", 0);
upper2 = ic.readEntry("upper2", 0);
upper3 = ic.readEntry("upper3", 0);
MaxHr = ic.readEntry("maxHr", 0);
restHr = ic.readEntry("restHr", 0);
vo2max = ic.readEntry("vo2max", 0);
weight = ic.readEntry("weight", 0);
sampleTime = ic.readEntry("seconds", 1);
Serial = ic.readEntry("Serial", false);
Contour = ic.readEntry("Contour", false);
Device = ic.readEntry("Device", QString("/dev/ttyUSB0"));
Forerunner = ic.readEntry("Forerunner", false);
Data = ic.readEntry("Data", QString("/"));
HRM = ic.readEntry("HRM", QString("/"));
MAP = ic.readEntry("MAP", QString("/"));
Units = ic.readEntry("Units", 0);
MapType = ic.readEntry("MapType", 0);
KConfig cfg(QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup ic(&cfg, "SportWatcher");
lower1 = ic.readEntry("lower1", 0);
lower2 = ic.readEntry("lower2", 0);
lower3 = ic.readEntry("lower3", 0);
upper1 = ic.readEntry("upper1", 0);
upper2 = ic.readEntry("upper2", 0);
upper3 = ic.readEntry("upper3", 0);
MaxHr = ic.readEntry("maxHr", 0);
restHr = ic.readEntry("restHr", 0);
vo2max = ic.readEntry("vo2max", 0);
weight = ic.readEntry("weight", 0);
sampleTime = ic.readEntry("seconds", 1);
Serial = ic.readEntry("Serial", false);
Contour = ic.readEntry("Contour", false);
Device = ic.readEntry("Device", QString("/dev/ttyUSB0"));
Forerunner = ic.readEntry("Forerunner", false);
Data = ic.readEntry("Data", QString("/"));
HRM = ic.readEntry("HRM", QString("/"));
MAP = ic.readEntry("MAP", QString("/"));
Units = ic.readEntry("Units", 0);
MapType = ic.readEntry("MapType", 0);
}
 
delete dlg;
2304,55 → 2406,61
void sportwatcherWidget::extrasWMSSettings()
{
#if defined HAVE_GDAL
if (MapType == MPT_BMP || MapType == MPT_GIF || MapType == MPT_PNG ||
MapType == MPT_TIF)
 
if(MapType == MPT_BMP || MapType == MPT_GIF || MapType == MPT_PNG ||
MapType == MPT_TIF)
{
coordinatesWidget *idlg = new coordinatesWidget(this);
idlg->exec();
delete idlg;
return;
coordinatesWidget *idlg = new coordinatesWidget(this);
idlg->exec();
delete idlg;
return;
}
 
if (MapType == MPT_WMS)
if(MapType == MPT_WMS)
{
wmsbase *dlg = new wmsbase(this);
dlg->exec();
delete dlg;
wmsbase *dlg = new wmsbase(this);
dlg->exec();
delete dlg;
}
 
#if defined HAVE_MAPNIK
if (MapType == MPT_SHP || MapType == MPT_OSM)
 
if(MapType == MPT_SHP || MapType == MPT_OSM)
{
shapeWidget *dlg = new shapeWidget(this);
shapeWidget *dlg = new shapeWidget(this);
 
if (MapType == MPT_SHP)
dlg->setMapType(shapeWidget::MAP_SHAPE);
else
dlg->setMapType(shapeWidget::MAP_OSM);
if(MapType == MPT_SHP)
dlg->setMapType(shapeWidget::MAP_SHAPE);
else
dlg->setMapType(shapeWidget::MAP_OSM);
 
dlg->exec();
delete dlg;
dlg->exec();
delete dlg;
}
 
#else
KMessageBox::detailedSorry(this,
i18n("This function was disabled at compile time because of missing Mapnik!"),
i18n("SportWatcher needs Mapnik 0.6 or newer, to enable this function.\n") +
i18n("If you like this to be working, install Mapnik and recompile the source."));
i18n("This function was disabled at compile time because of missing Mapnik!"),
i18n("SportWatcher needs Mapnik 0.6 or newer, to enable this function.\n") +
i18n("If you like this to be working, install Mapnik and recompile the source."));
#endif
if (MapType != MPT_WMS && MapType != MPT_SHP && MapType != MPT_OSM)
 
if(MapType != MPT_WMS && MapType != MPT_SHP && MapType != MPT_OSM)
{
KMessageBox::detailedSorry(this,
i18n("You have not choosen a WMS tag file or shape file directory!"),
i18n("This dialog is especialy to set map specific parameters. ") +
i18n("Therefore this dialog is temporary disabled. It will be ") +
i18n("available again, as soon as you choose \"WMS server\" or ") +
i18n("Shape file as your map type."));
return;
KMessageBox::detailedSorry(this,
i18n("You have not choosen a WMS tag file or shape file directory!"),
i18n("This dialog is especialy to set map specific parameters. ") +
i18n("Therefore this dialog is temporary disabled. It will be ") +
i18n("available again, as soon as you choose \"WMS server\" or ") +
i18n("Shape file as your map type."));
return;
}
 
#else
KMessageBox::detailedSorry(this,
i18n("This function was disabled at compile time because of missing GDAL v1.x.x!"),
i18n("Sportwatcher needs GDAL v1.5.x or newer, to enable this function.\n") +
i18n("If you like this to be working, install GDAL and recompile the source!"));
i18n("This function was disabled at compile time because of missing GDAL v1.x.x!"),
i18n("Sportwatcher needs GDAL v1.5.x or newer, to enable this function.\n") +
i18n("If you like this to be working, install GDAL and recompile the source!"));
#endif
}
 
2361,36 → 2469,36
*/
void sportwatcherWidget::showLaps()
{
QString qs_name, qs_distance, qs_etime, qs_avgpace, qs_avgspeed, qs_maxspeed;
QString qs_calories, qs_avghr, qs_maxhr, qs_avgcadence, qs_ascent, qs_descent;
QString qs_totdist;
QDateTime dt;
QTime t, st;
QDateTime *qt;
LAP *lap;
POINT *point;
RUN_NODE *rakt, *rn;
int laps, i, anz, men, cad;
double alt_asc, alt_dsc, sum_asc, sum_dsc, old_asc, old_dsc;
double totdist;
bool pause;
QString qs_name, qs_distance, qs_etime, qs_avgpace, qs_avgspeed, qs_maxspeed;
QString qs_calories, qs_avghr, qs_maxhr, qs_avgcadence, qs_ascent, qs_descent;
QString qs_totdist;
QDateTime dt;
QTime t, st;
QDateTime *qt;
LAP *lap;
POINT *point;
RUN_NODE *rakt, *rn;
int laps, i, anz, men, cad;
double alt_asc, alt_dsc, sum_asc, sum_dsc, old_asc, old_dsc;
double totdist;
bool pause;
 
if (!DIRTY)
return;
if(!DIRTY)
return;
 
if (!gmn)
return;
if(!gmn)
return;
 
if (gmn->type == data_Dnil)
if(gmn->type == data_Dnil)
{
KMessageBox::error(this, i18n("No data found!"));
return;
KMessageBox::error(this, i18n("No data found!"));
return;
}
 
if (gmn->type != data_Dlist) /* List of data */
if(gmn->type != data_Dlist) /* List of data */
{
KMessageBox::error(this, i18n("Found unexpected data type %1!").arg(gmn->type));
return;
KMessageBox::error(this, i18n("Found unexpected data type %1!").arg(gmn->type));
return;
}
 
ds.destroy();
2405,15 → 2513,16
ui_sportwatcherWidgetBase.twLaps->clear();
ds.garmin_print_data(gmn);
 
if (!(rn = ds.getRunNode()))
return;
if(!(rn = ds.getRunNode()))
return;
 
rakt = rn;
// Tab Summary
ui_sportwatcherWidgetBase.liLaps->setRootIsDecorated(true);
 
for (i = 1; i < 12; i++)
ui_sportwatcherWidgetBase.liLaps->setColumnAlignment(i, Qt::AlignRight);
for(i = 1; i < 12; i++)
ui_sportwatcherWidgetBase.liLaps->setColumnAlignment(i, Qt::AlignRight);
 
// Tab Laps
ui_sportwatcherWidgetBase.edTotalDistance->clear();
ui_sportwatcherWidgetBase.edTotalTime->clear();
2429,459 → 2538,461
 
// The main loop.
// If a supported run type is detected, it will be processed.
while (rakt)
while(rakt)
{
// Check for a supported run type
if (rakt->run->type == data_D1000 || rakt->run->type == data_D1009 ||
rakt->run->type == data_D1010)
{
int cal, ahr, mhr;
double distance, speed, mspeed;
QDate dat;
// Check for a supported run type
if(rakt->run->type == data_D1000 || rakt->run->type == data_D1009 ||
rakt->run->type == data_D1010)
{
int cal, ahr, mhr;
double distance, speed, mspeed;
QDate dat;
 
// Set the name depending on the sport type
// This is used on the tab "Summary"
switch (rakt->run->sport_type)
{
case D1000_running: qs_name = i18n("Running: "); break;
case D1000_biking: qs_name = i18n("Biking: "); break;
case D1000_other: qs_name = i18n("Other: "); break;
default:
qs_name = i18n("Unknown: ");
}
// Set the name depending on the sport type
// This is used on the tab "Summary"
switch(rakt->run->sport_type)
{
case D1000_running: qs_name = i18n("Running: "); break;
case D1000_biking: qs_name = i18n("Biking: "); break;
case D1000_other: qs_name = i18n("Other: "); break;
default:
qs_name = i18n("Unknown: ");
}
 
if (!(lap = ds.getLap(rakt->run->first_lap_index)))
return;
if(!(lap = ds.getLap(rakt->run->first_lap_index)))
return;
 
qt = garmin_dtime (lap->start_time);
StartTime = *qt;
st = qt->time();
dat = qt->date();
delete qt;
qt = 0;
// Find the last track;
// It is possible to delete laps directly on the watch,
// so we can't be sure the last lap is really the last one.
// Tracks are not deleted and the last track contains the
// summuraries we need.
if (!(point = ds.getLastPoint()))
{
KMessageBox::error(this, i18n("Error getting the last messure point!"));
return;
}
qt = garmin_dtime(lap->start_time);
StartTime = *qt;
st = qt->time();
dat = qt->date();
delete qt;
qt = 0;
 
qt = garmin_dtime(point->time);
t = qt->time();
t.setHMS(0, 0, 0);
t = t.addSecs(ds.getTotalTime());
qt->setDate(dat);
qt->setTime(t);
qs_name.append(kl->formatDate(dat, KLocale::ShortDate));
qs_name.append(" ");
qs_name.append(kl->formatTime(st, true));
max_time = ds.getTotalTime();
qs_etime = QString(qt->toString("hh:mm:ss.zzz"));
// Find the last track;
// It is possible to delete laps directly on the watch,
// so we can't be sure the last lap is really the last one.
// Tracks are not deleted and the last track contains the
// summuraries we need.
if(!(point = ds.getLastPoint()))
{
KMessageBox::error(this, i18n("Error getting the last messure point!"));
return;
}
 
distance = 0.0;
cal = 0;
mspeed = 0;
ahr = mhr = 0;
anz = 0;
cad = 0;
sum_asc = sum_dsc = old_asc = old_dsc = 0;
qt = garmin_dtime(point->time);
t = qt->time();
t.setHMS(0, 0, 0);
t = t.addSecs(ds.getTotalTime());
qt->setDate(dat);
qt->setTime(t);
qs_name.append(kl->formatDate(dat, KLocale::ShortDate));
qs_name.append(" ");
qs_name.append(kl->formatTime(st, true));
max_time = ds.getTotalTime();
qs_etime = QString(qt->toString("hh:mm:ss.zzz"));
 
// Find out the total distance, calories, maximum speed,
// maximum heart rate and the average heart rate. Get this
// values from the lap summary the watch made.
for (i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
if ((lap = ds.getLap(i)) == NULL)
continue;
distance = 0.0;
cal = 0;
mspeed = 0;
ahr = mhr = 0;
anz = 0;
cad = 0;
sum_asc = sum_dsc = old_asc = old_dsc = 0;
 
distance += lap->total_distance;
cal += lap->calories;
// Find out the total distance, calories, maximum speed,
// maximum heart rate and the average heart rate. Get this
// values from the lap summary the watch made.
for(i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
if((lap = ds.getLap(i)) == NULL)
continue;
 
if (lap->avg_cadence != 0xff)
cad += lap->avg_cadence;
distance += lap->total_distance;
cal += lap->calories;
 
ahr += lap->avg_heart_rate;
anz++;
if(lap->avg_cadence != 0xff)
cad += lap->avg_cadence;
 
if (lap->max_speed > mspeed)
mspeed = lap->max_speed;
ahr += lap->avg_heart_rate;
anz++;
 
if (lap->max_heart_rate > mhr)
mhr = lap->max_heart_rate;
}
if(lap->max_speed > mspeed)
mspeed = lap->max_speed;
 
total_distance = distance = ds.getTotalDistance();
if(lap->max_heart_rate > mhr)
mhr = lap->max_heart_rate;
}
 
if (Units == 1) // Statute?
qs_distance.sprintf("%.2f ft", distance / 0.304);
else
qs_distance.sprintf("%.2f m", distance);
total_distance = distance = ds.getTotalDistance();
 
if (distance > 0)
{
QTime tt = qt->time();
long secs = (double)(tt.hour() * 3600 + tt.minute() * 60 + tt.second()) / 100.0;
if(Units == 1) // Statute?
qs_distance.sprintf("%.2f ft", distance / 0.304);
else
qs_distance.sprintf("%.2f m", distance);
 
if (Units == 0)
secs = secs * (1000.0 / distance * 100.0);
else
secs = secs * (1609.344 / distance * 100.0);
if(distance > 0)
{
QTime tt = qt->time();
long secs = (double)(tt.hour() * 3600 + tt.minute() * 60 + tt.second()) / 100.0;
 
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = QString(" ") + kl->formatTime(t, true);
if(Units == 0)
secs = secs * (1000.0 / distance * 100.0);
else
secs = secs * (1609.344 / distance * 100.0);
 
if (Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = QString(" ") + kl->formatTime(t, true);
 
if (Units == 1) // Statute?
speed = distance / ds.getTotalTime() * 3.6 / 1.609344;
else
speed = distance / ds.getTotalTime() * 3.6;
if(Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
 
qs_avgspeed.sprintf("%.2f %s", speed, (Units == 1) ? "mph" : "km/h");
qs_maxspeed.sprintf("%.2f %s", (Units == 1) ? mspeed * 3.6 / 1.609344 : mspeed * 3.6, (Units == 1) ? "mph" : "km/h");
qs_calories.sprintf("%d", cal);
qs_avghr.sprintf("%d bpm", ahr / anz);
qs_maxhr.sprintf("%d bpm", mhr);
if(Units == 1) // Statute?
speed = distance / ds.getTotalTime() * 3.6 / 1.609344;
else
speed = distance / ds.getTotalTime() * 3.6;
 
if (cad > 0)
qs_avgcadence.sprintf("%d", cad / anz);
qs_avgspeed.sprintf("%.2f %s", speed, (Units == 1) ? "mph" : "km/h");
qs_maxspeed.sprintf("%.2f %s", (Units == 1) ? mspeed * 3.6 / 1.609344 : mspeed * 3.6, (Units == 1) ? "mph" : "km/h");
qs_calories.sprintf("%d", cal);
qs_avghr.sprintf("%d bpm", ahr / anz);
qs_maxhr.sprintf("%d bpm", mhr);
 
// Add the summary line columns to the tab "Summary"
K3ListViewItem *element = new K3ListViewItem(ui_sportwatcherWidgetBase.liLaps,
qs_name, kl->formatNumber(qs_distance, false),
qs_etime, qs_avgpace, kl->formatNumber(qs_avgspeed, false),
kl->formatNumber(qs_maxspeed, false), qs_calories, qs_avghr);
element->setText(8, qs_maxhr);
element->setText(9, qs_avgcadence);
element->setText(10, kl->formatNumber(qs_ascent, false));
element->setText(11, kl->formatNumber(qs_descent, false));
element->sortChildItems(0, false);
element->setOpen(true);
element->setPixmap(0, KIcon(QString("activity")).pixmap(16));
ui_sportwatcherWidgetBase.liLaps->insertItem(element);
// Add some of the summaries to the fields on the tab "Lap details"
ui_sportwatcherWidgetBase.edTotalDistance->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edTotalDistance->insert(kl->formatNumber(qs_distance, false));
ui_sportwatcherWidgetBase.edTotalTime->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edTotalTime->insert(qs_etime);
ui_sportwatcherWidgetBase.edAvgSpeed->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edAvgSpeed->insert(kl->formatNumber(qs_avgspeed, false));
ui_sportwatcherWidgetBase.edTotalHeight->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edTotalHeight->insert(kl->formatNumber(qs_ascent, false));
ui_sportwatcherWidgetBase.edAvgHR->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edAvgHR->insert(qs_avghr);
delete qt;
/* Get the laps. */
laps = 1;
if(cad > 0)
qs_avgcadence.sprintf("%d", cad / anz);
 
for (i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
double spd;
char *un;
// Add the summary line columns to the tab "Summary"
K3ListViewItem *element = new K3ListViewItem(ui_sportwatcherWidgetBase.liLaps,
qs_name, kl->formatNumber(qs_distance, false),
qs_etime, qs_avgpace, kl->formatNumber(qs_avgspeed, false),
kl->formatNumber(qs_maxspeed, false), qs_calories, qs_avghr);
element->setText(8, qs_maxhr);
element->setText(9, qs_avgcadence);
element->setText(10, kl->formatNumber(qs_ascent, false));
element->setText(11, kl->formatNumber(qs_descent, false));
element->sortChildItems(0, false);
element->setOpen(true);
element->setPixmap(0, KIcon(QString("activity")).pixmap(16));
ui_sportwatcherWidgetBase.liLaps->insertItem(element);
// Add some of the summaries to the fields on the tab "Lap details"
ui_sportwatcherWidgetBase.edTotalDistance->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edTotalDistance->insert(kl->formatNumber(qs_distance, false));
ui_sportwatcherWidgetBase.edTotalTime->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edTotalTime->insert(qs_etime);
ui_sportwatcherWidgetBase.edAvgSpeed->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edAvgSpeed->insert(kl->formatNumber(qs_avgspeed, false));
ui_sportwatcherWidgetBase.edTotalHeight->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edTotalHeight->insert(kl->formatNumber(qs_ascent, false));
ui_sportwatcherWidgetBase.edAvgHR->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edAvgHR->insert(qs_avghr);
delete qt;
/* Get the laps. */
laps = 1;
 
if ((lap = ds.getLap(i)) == NULL)
continue;
for(i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
double spd;
char *un;
 
qt = garmin_dtime (lap->start_time);
qs_name.sprintf("Lap %03d - ", laps);
qs_name.append(kl->formatTime(qt->time(), true));
qs_distance.sprintf("%.2f %s", (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance, (Units == 1) ? "ft" : "m");
totdist += (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance;
qs_totdist.sprintf("%2.f %s", totdist, (Units == 1) ? "ft" : "m");
t = QTime(0, 0, 0, 0);
t = t.addMSecs(lap->total_time * 10);
qs_etime = t.toString("hh:mm:ss.zzz");
spd = lap->total_distance / (lap->total_time / 100.0);
delete qt;
qt = 0;
if((lap = ds.getLap(i)) == NULL)
continue;
 
if (Units == 0)
{
un = (char *)"km/h";
spd *= 3.6;
}
else
{
spd *= 3.6 / 1.609344;
un = (char *)"mph";
}
qt = garmin_dtime(lap->start_time);
qs_name.sprintf("Lap %03d - ", laps);
qs_name.append(kl->formatTime(qt->time(), true));
qs_distance.sprintf("%.2f %s", (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance, (Units == 1) ? "ft" : "m");
totdist += (Units == 1) ? lap->total_distance / 0.304 : lap->total_distance;
qs_totdist.sprintf("%2.f %s", totdist, (Units == 1) ? "ft" : "m");
t = QTime(0, 0, 0, 0);
t = t.addMSecs(lap->total_time * 10);
qs_etime = t.toString("hh:mm:ss.zzz");
spd = lap->total_distance / (lap->total_time / 100.0);
delete qt;
qt = 0;
 
qs_avgspeed.sprintf("%.2f %s", spd, un);
qs_maxspeed.sprintf("%.2f %s", (Units == 1) ? lap->max_speed * 3.6 / 1.609344 : lap->max_speed * 3.6, un);
qs_calories.sprintf("%d", lap->calories);
if(Units == 0)
{
un = (char *)"km/h";
spd *= 3.6;
}
else
{
spd *= 3.6 / 1.609344;
un = (char *)"mph";
}
 
if (lap->total_distance > 0 && lap->total_time != 0)
{
double fact;
qs_avgspeed.sprintf("%.2f %s", spd, un);
qs_maxspeed.sprintf("%.2f %s", (Units == 1) ? lap->max_speed * 3.6 / 1.609344 : lap->max_speed * 3.6, un);
qs_calories.sprintf("%d", lap->calories);
 
if (Units == 0)
fact = 1000.0; // 1 km
else
fact = 1609.344; // 1 mile in meters
if(lap->total_distance > 0 && lap->total_time != 0)
{
double fact;
 
long secs = (double)lap->total_time / 10000.0 * (fact / lap->total_distance * 100.0);
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = kl->formatTime(t, true);
if(Units == 0)
fact = 1000.0; // 1 km
else
fact = 1609.344; // 1 mile in meters
 
if (Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
long secs = (double)lap->total_time / 10000.0 * (fact / lap->total_distance * 100.0);
int h = secs / 3600;
int m = (secs - (h * 3600)) / 60;
int s = secs - ((h * 3600) + (m * 60));
t = QTime(h, m, s, 0);
qs_avgpace = kl->formatTime(t, true);
 
qs_avghr.sprintf("%d bpm", lap->avg_heart_rate);
qs_maxhr.sprintf("%d bpm", lap->max_heart_rate);
if(Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
 
anz = 0;
alt_asc = alt_dsc = 0;
// Add a new detail line to the tab "Lap details"
QTreeWidgetItem * trdetail = new QTreeWidgetItem(ui_sportwatcherWidgetBase.twLaps);
qs_avghr.sprintf("%d bpm", lap->avg_heart_rate);
qs_maxhr.sprintf("%d bpm", lap->max_heart_rate);
 
if ((point = ds.getPoint(lap->start_time)) != 0)
{
if (point->alt < 20000)
{
alt_dsc = alt_asc = point->alt;
anz = 0;
alt_asc = alt_dsc = 0;
// Add a new detail line to the tab "Lap details"
QTreeWidgetItem * trdetail = new QTreeWidgetItem(ui_sportwatcherWidgetBase.twLaps);
 
if (old_asc == 0)
old_asc = alt_asc;
if((point = ds.getPoint(lap->start_time)) != 0)
{
if(point->alt < 20000)
{
alt_dsc = alt_asc = point->alt;
 
if (old_dsc == 0)
old_dsc = alt_dsc;
}
else
alt_dsc = alt_asc = 0;
if(old_asc == 0)
old_asc = alt_asc;
 
POINT *oldPoint = 0;
double sc, dist, speed;
unsigned long t1, t2;
t1 = t2 = 0;
pause = false;
bool ignore = false;
if(old_dsc == 0)
old_dsc = alt_dsc;
}
else
alt_dsc = alt_asc = 0;
 
while (point)
{
if (point->time > (lap->start_time + (lap->total_time / 100)))
break;
POINT *oldPoint = 0;
double sc, dist, speed;
unsigned long t1, t2;
t1 = t2 = 0;
pause = false;
bool ignore = false;
 
QTreeWidgetItem *child = new QTreeWidgetItem(trdetail);
qt = garmin_dtime (point->time);
child->setText(0, kl->formatTime(qt->time(), true));
child->setTextAlignment(0, Qt::AlignRight);
child->setText(8, QString("%1 %2").arg(kl->formatNumber((double)point->heart_rate, 0)).arg(" bpm"));
child->setTextAlignment(8, Qt::AlignRight);
while(point)
{
if(point->time > (lap->start_time + (lap->total_time / 100)))
break;
 
if (point->cadence < 0xff)
{
child->setText(10, kl->formatNumber((double)point->cadence, 0));
child->setTextAlignment(10, Qt::AlignRight);
}
QTreeWidgetItem *child = new QTreeWidgetItem(trdetail);
qt = garmin_dtime(point->time);
child->setText(0, kl->formatTime(qt->time(), true));
child->setTextAlignment(0, Qt::AlignRight);
child->setText(8, QString("%1 %2").arg(kl->formatNumber((double)point->heart_rate, 0)).arg(" bpm"));
child->setTextAlignment(8, Qt::AlignRight);
 
if (point->alt < 20000)
{
double alt = (Units == 0) ? (double)point->alt : (double)point->alt / 0.304;
if(point->cadence < 0xff)
{
child->setText(10, kl->formatNumber((double)point->cadence, 0));
child->setTextAlignment(10, Qt::AlignRight);
}
 
child->setText(11, QString("%1 %2").arg(kl->formatNumber(alt, 2)).arg((Units == 0) ? QString(" m") : QString(" ft")));
child->setTextAlignment(11, Qt::AlignRight);
}
if(point->alt < 20000)
{
double alt = (Units == 0) ? (double)point->alt : (double)point->alt / 0.304;
 
if (!oldPoint)
oldPoint = point;
child->setText(11, QString("%1 %2").arg(kl->formatNumber(alt, 2)).arg((Units == 0) ? QString(" m") : QString(" ft")));
child->setTextAlignment(11, Qt::AlignRight);
}
 
if (point->alt > alt_asc && point->alt < 20000)
{
alt_asc = point->alt;
if(!oldPoint)
oldPoint = point;
 
if (alt_dsc == 0)
alt_dsc = point->alt;
}
if(point->alt > alt_asc && point->alt < 20000)
{
alt_asc = point->alt;
 
if (point->alt < alt_dsc)
alt_dsc = point->alt;
if(alt_dsc == 0)
alt_dsc = point->alt;
}
 
// save the min and max values. We need this information to
// build the graphics.
if (point->heart_rate > max_hr && point->heart_rate < 250)
max_hr = point->heart_rate;
if(point->alt < alt_dsc)
alt_dsc = point->alt;
 
if ((min_hr == 0 && point->heart_rate > 0 && point->heart_rate < 250)
|| (point->heart_rate > 0 && point->heart_rate < min_hr))
min_hr = point->heart_rate;
// save the min and max values. We need this information to
// build the graphics.
if(point->heart_rate > max_hr && point->heart_rate < 250)
max_hr = point->heart_rate;
 
if (point->alt < 20000 && max_height < point->alt)
max_height = point->alt;
if((min_hr == 0 && point->heart_rate > 0 && point->heart_rate < 250)
|| (point->heart_rate > 0 && point->heart_rate < min_hr))
min_hr = point->heart_rate;
 
if (point->alt < 20000 && (min_height == 0.0 || min_height > point->alt))
min_height = point->alt;
if(point->alt < 20000 && max_height < point->alt)
max_height = point->alt;
 
// Calculate speed of current track
if (!pause && point->distance > 1.0e10)
{
t1 = point->time;
pause = true;
ignore = true;
}
else if (pause)
{
t2 = point->time;
pause = false;
point = ds.getPoint(point->time + 1);
continue;
}
if(point->alt < 20000 && (min_height == 0.0 || min_height > point->alt))
min_height = point->alt;
 
if (!ignore && !pause)
{
sc = point->time - oldPoint->time;
dist = point->distance - oldPoint->distance;
// Calculate speed of current track
if(!pause && point->distance > 1.0e10)
{
t1 = point->time;
pause = true;
ignore = true;
}
else if(pause)
{
t2 = point->time;
pause = false;
point = ds.getPoint(point->time + 1);
continue;
}
 
child->setText(1, QString("%1 %2").arg(kl->formatNumber((Units == 0) ? (double)dist : (double)dist / 0.304, 2)).arg((Units == 0) ? QString(" m") : QString(" ft")));
child->setTextAlignment(1, Qt::AlignRight);
if(!ignore && !pause)
{
sc = point->time - oldPoint->time;
dist = point->distance - oldPoint->distance;
 
if (t2 > t1)
sc -= t2 - t1;
child->setText(1, QString("%1 %2").arg(kl->formatNumber((Units == 0) ? (double)dist : (double)dist / 0.304, 2)).arg((Units == 0) ? QString(" m") : QString(" ft")));
child->setTextAlignment(1, Qt::AlignRight);
 
if (sc > 0.0)
{
speed = (dist / sc) * 3.6;
if(t2 > t1)
sc -= t2 - t1;
 
if (speed > lap->max_speed * 3.6)
speed = lap->max_speed * 3.6;
}
else
speed = 0.0;
if(sc > 0.0)
{
speed = (dist / sc) * 3.6;
 
if (Units == 1)
speed /= 1.609344;
if(speed > lap->max_speed * 3.6)
speed = lap->max_speed * 3.6;
}
else
speed = 0.0;
 
child->setText(5, QString("%1 %2").arg(kl->formatNumber(speed, 2)).arg((Units == 0) ? QString(" Km/h") : QString(" mi/h")));
child->setTextAlignment(5, Qt::AlignRight);
if(Units == 1)
speed /= 1.609344;
 
if (speed > 0.0 && speed < 400.0 && max_speed < speed)
max_speed = speed;
child->setText(5, QString("%1 %2").arg(kl->formatNumber(speed, 2)).arg((Units == 0) ? QString(" Km/h") : QString(" mi/h")));
child->setTextAlignment(5, Qt::AlignRight);
 
if (speed > 0.0 && (min_speed == 0.0 || min_speed > speed))
min_speed = speed;
if(speed > 0.0 && speed < 400.0 && max_speed < speed)
max_speed = speed;
 
oldPoint = point;
}
if(speed > 0.0 && (min_speed == 0.0 || min_speed > speed))
min_speed = speed;
 
if (!pause && ignore)
ignore = false;
oldPoint = point;
}
 
if (point->heart_rate > 0 && point->heart_rate < 250)
{
avg_hr += point->heart_rate;
men++;
}
if(!pause && ignore)
ignore = false;
 
point = ds.getPoint(point->time + 1);
}
if(point->heart_rate > 0 && point->heart_rate < 250)
{
avg_hr += point->heart_rate;
men++;
}
 
if (old_asc < alt_asc)
sum_asc += (alt_asc - old_asc);
point = ds.getPoint(point->time + 1);
}
 
if (old_dsc > alt_dsc)
sum_dsc += (old_dsc - alt_dsc);
if(old_asc < alt_asc)
sum_asc += (alt_asc - old_asc);
 
old_asc = alt_asc;
old_dsc = alt_dsc;
qs_ascent.sprintf("%.2f %s", (Units == 1) ? (alt_asc / 0.304) : alt_asc, (Units == 1) ? "ft" : "m");
qs_descent.sprintf("%.2f %s", (Units == 1) ? (alt_dsc / 0.304) : alt_dsc, (Units == 1) ? "ft" : "m");
}
if(old_dsc > alt_dsc)
sum_dsc += (old_dsc - alt_dsc);
 
if (lap->avg_cadence != 0xff)
qs_avgcadence.sprintf("%d", lap->avg_cadence);
// Add a new detail line to the tab "Summary"
K3ListViewItem *edetail = new K3ListViewItem(element, qs_name,
kl->formatNumber(qs_distance, false),
qs_etime, qs_avgpace, kl->formatNumber(qs_avgspeed, false),
kl->formatNumber(qs_maxspeed, false), qs_calories, qs_avghr);
edetail->setText(8, qs_maxhr);
edetail->setText(9, qs_avgcadence);
edetail->setText(10, kl->formatNumber(qs_ascent, false));
edetail->setText(11, kl->formatNumber(qs_descent, false));
edetail->setPixmap(0, KIcon(QString("history")).pixmap(16));
QPixmap qpx = KIcon(QString("other")).pixmap(16);
trdetail->setText(0, qs_etime);
trdetail->setTextAlignment(0, Qt::AlignRight);
trdetail->setText(1, kl->formatNumber(qs_distance));
trdetail->setTextAlignment(1, Qt::AlignRight);
trdetail->setText(2, kl->formatNumber(qs_totdist));
trdetail->setTextAlignment(2, Qt::AlignRight);
trdetail->setText(4, qs_avgpace);
trdetail->setTextAlignment(4, Qt::AlignRight);
trdetail->setText(5, kl->formatNumber(qs_avgspeed, false));
trdetail->setTextAlignment(5, Qt::AlignRight);
trdetail->setText(6, kl->formatNumber(qs_maxspeed, false));
trdetail->setTextAlignment(6, Qt::AlignRight);
trdetail->setText(7, qs_calories);
trdetail->setTextAlignment(7, Qt::AlignRight);
trdetail->setText(8, qs_avghr);
trdetail->setTextAlignment(8, Qt::AlignRight);
trdetail->setText(9, qs_maxhr);
trdetail->setTextAlignment(9, Qt::AlignRight);
trdetail->setText(10, qs_avgcadence);
trdetail->setTextAlignment(10, Qt::AlignRight);
trdetail->setText(11, kl->formatNumber(qs_ascent, false));
trdetail->setTextAlignment(11, Qt::AlignRight);
switch (rakt->run->sport_type)
{
case D1000_running:
edetail->setPixmap(0, KIcon(QString("spw-running")).pixmap(16));
break;
old_asc = alt_asc;
old_dsc = alt_dsc;
qs_ascent.sprintf("%.2f %s", (Units == 1) ? (alt_asc / 0.304) : alt_asc, (Units == 1) ? "ft" : "m");
qs_descent.sprintf("%.2f %s", (Units == 1) ? (alt_dsc / 0.304) : alt_dsc, (Units == 1) ? "ft" : "m");
}
 
case D1000_biking:
edetail->setPixmap(0, KIcon(QString("bike")).pixmap(16));
break;
if(lap->avg_cadence != 0xff)
qs_avgcadence.sprintf("%d", lap->avg_cadence);
 
case D1000_other:
edetail->setPixmap(0, qpx);
break;
// Add a new detail line to the tab "Summary"
K3ListViewItem *edetail = new K3ListViewItem(element, qs_name,
kl->formatNumber(qs_distance, false),
qs_etime, qs_avgpace, kl->formatNumber(qs_avgspeed, false),
kl->formatNumber(qs_maxspeed, false), qs_calories, qs_avghr);
edetail->setText(8, qs_maxhr);
edetail->setText(9, qs_avgcadence);
edetail->setText(10, kl->formatNumber(qs_ascent, false));
edetail->setText(11, kl->formatNumber(qs_descent, false));
edetail->setPixmap(0, KIcon(QString("history")).pixmap(16));
QPixmap qpx = KIcon(QString("other")).pixmap(16);
 
default:
edetail->setPixmap(0, qpx);
}
trdetail->setText(0, qs_etime);
trdetail->setTextAlignment(0, Qt::AlignRight);
trdetail->setText(1, kl->formatNumber(qs_distance));
trdetail->setTextAlignment(1, Qt::AlignRight);
trdetail->setText(2, kl->formatNumber(qs_totdist));
trdetail->setTextAlignment(2, Qt::AlignRight);
trdetail->setText(4, qs_avgpace);
trdetail->setTextAlignment(4, Qt::AlignRight);
trdetail->setText(5, kl->formatNumber(qs_avgspeed, false));
trdetail->setTextAlignment(5, Qt::AlignRight);
trdetail->setText(6, kl->formatNumber(qs_maxspeed, false));
trdetail->setTextAlignment(6, Qt::AlignRight);
trdetail->setText(7, qs_calories);
trdetail->setTextAlignment(7, Qt::AlignRight);
trdetail->setText(8, qs_avghr);
trdetail->setTextAlignment(8, Qt::AlignRight);
trdetail->setText(9, qs_maxhr);
trdetail->setTextAlignment(9, Qt::AlignRight);
trdetail->setText(10, qs_avgcadence);
trdetail->setTextAlignment(10, Qt::AlignRight);
trdetail->setText(11, kl->formatNumber(qs_ascent, false));
trdetail->setTextAlignment(11, Qt::AlignRight);
 
ui_sportwatcherWidgetBase.liLaps->clearSelection();
element->insertItem(edetail);
delete qt;
laps++;
}
switch(rakt->run->sport_type)
{
case D1000_running:
edetail->setPixmap(0, KIcon(QString("spw-running")).pixmap(16));
break;
 
qs_ascent.sprintf("%.2f %s", (Units == 1) ? sum_asc / 0.304 : sum_asc, (Units == 1) ? "ft" : "m");
qs_descent.sprintf("%.2f %s", (Units == 1) ? sum_dsc / 0.304 : sum_dsc, (Units == 1) ? "ft" : "m");
element->setText(10, qs_ascent);
element->setText(11, qs_descent);
qs_ascent.sprintf("%s %s", (Units == 1) ? kl->formatNumber(ds.getAscend() / 0.304, 2).toAscii().data() : kl->formatNumber(ds.getAscend(), 2).toAscii().data(), (Units == 1) ? "ft" : "m");
ui_sportwatcherWidgetBase.edTotalHeight->clear();
ui_sportwatcherWidgetBase.edTotalHeight->insert(qs_ascent);
ui_sportwatcherWidgetBase.edLapNumber->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edLapNumber->insert(kl->formatNumber((double)laps, 0));
}
case D1000_biking:
edetail->setPixmap(0, KIcon(QString("bike")).pixmap(16));
break;
 
rakt = rakt->next;
case D1000_other:
edetail->setPixmap(0, qpx);
break;
 
default:
edetail->setPixmap(0, qpx);
}
 
ui_sportwatcherWidgetBase.liLaps->clearSelection();
element->insertItem(edetail);
delete qt;
laps++;
}
 
qs_ascent.sprintf("%.2f %s", (Units == 1) ? sum_asc / 0.304 : sum_asc, (Units == 1) ? "ft" : "m");
qs_descent.sprintf("%.2f %s", (Units == 1) ? sum_dsc / 0.304 : sum_dsc, (Units == 1) ? "ft" : "m");
element->setText(10, qs_ascent);
element->setText(11, qs_descent);
qs_ascent.sprintf("%s %s", (Units == 1) ? kl->formatNumber(ds.getAscend() / 0.304, 2).toAscii().data() : kl->formatNumber(ds.getAscend(), 2).toAscii().data(), (Units == 1) ? "ft" : "m");
ui_sportwatcherWidgetBase.edTotalHeight->clear();
ui_sportwatcherWidgetBase.edTotalHeight->insert(qs_ascent);
ui_sportwatcherWidgetBase.edLapNumber->setAlignment(Qt::AlignRight);
ui_sportwatcherWidgetBase.edLapNumber->insert(kl->formatNumber((double)laps, 0));
}
 
rakt = rakt->next;
}
 
if (men > 0)
avg_hr /= men;
if(men > 0)
avg_hr /= men;
else
min_hr = max_hr = avg_hr = 0;
min_hr = max_hr = avg_hr = 0;
}
 
void sportwatcherWidget::showTrack()
2896,55 → 3007,55
 
void sportwatcherWidget::showTrack(int zoom, const QRect &pan, LAP *lap)
{
int width, height;
double x1, y1, x2, y2;
int a, top, left, panX, panY;
uint32 i;
double coordW, coordH, tick;
double meterW, dist, fact;
QPainter paint;
posn_type posNW, posSE, posLXY, posRXY;
POINT *point;
bool Fgeo = false;
bool Data = false;
int width, height;
double x1, y1, x2, y2;
int a, top, left, panX, panY;
uint32 i;
double coordW, coordH, tick;
double meterW, dist, fact;
QPainter paint;
posn_type posNW, posSE, posLXY, posRXY;
POINT *point;
bool Fgeo = false;
bool Data = false;
#if defined HAVE_GDAL
QString fName = MAP;
QString fName = MAP;
//double adfGeoTransform[6];
GDALDataset *poDataset = 0;
GDALRasterBand *poBand = 0;
unsigned char *pafScanline = 0;
unsigned char *pafScanlineRed = 0;
unsigned char *pafScanlineGreen = 0;
unsigned char *pafScanlineBlue = 0;
unsigned char *pafScanlineAlpha = 0;
int nXSize, nYSize;
int xOff, yOff;
double oriLeftLon, oriLeftLat, oriRightLon, oriRightLat;
GDALDataset *poDataset = 0;
GDALRasterBand *poBand = 0;
unsigned char *pafScanline = 0;
unsigned char *pafScanlineRed = 0;
unsigned char *pafScanlineGreen = 0;
unsigned char *pafScanlineBlue = 0;
unsigned char *pafScanlineAlpha = 0;
int nXSize, nYSize;
int xOff, yOff;
double oriLeftLon, oriLeftLat, oriRightLon, oriRightLat;
#endif
 
if (!DIRTY || curTab == 2 || curTab == 3)
return;
if(!DIRTY || curTab == 2 || curTab == 3)
return;
 
if (!gmn)
return;
if(!gmn)
return;
 
QApplication::setOverrideCursor (QCursor(Qt::WaitCursor));
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
 
if (zoom != zfactor)
zfactor = zoom;
if(zoom != zfactor)
zfactor = zoom;
 
if (mapLap != lap)
mapLap = lap;
if(mapLap != lap)
mapLap = lap;
 
y2 = x2 = 0;
#if defined HAVE_GDAL
nXSize = nYSize = 0;
KConfig cfg (QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup wms (&cfg, "WMS");
KConfig cfg(QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup wms(&cfg, "WMS");
bool square = wms.readEntry("Square", false);
int CorrX = wms.readEntry("CorrX", 0);
int CorrY = wms.readEntry("CorrY", 0);
KConfigGroup ic (&cfg, "ImageCoords");
KConfigGroup ic(&cfg, "ImageCoords");
oriLeftLon = ic.readEntry("LeftLon", 0.0);
oriLeftLat = ic.readEntry("LeftLat", 0.0);
oriRightLon = ic.readEntry("RightLon", 0.0);
2951,44 → 3062,49
oriRightLat = ic.readEntry("RightLat", 0.0);
// int isrs = ic.readEntry("SRS", 0);
#endif
if (curTab == 0 && !ActivePrint)
 
if(curTab == 0 && !ActivePrint)
{
width = ui_sportwatcherWidgetBase.imgMap->width() - 2;
height = ui_sportwatcherWidgetBase.imgMap->height();
width = ui_sportwatcherWidgetBase.imgMap->width() - 2;
height = ui_sportwatcherWidgetBase.imgMap->height();
}
else if (ActivePrint)
else if(ActivePrint)
{
width = pmPrMap.width();
height = pmPrMap.height();
width = pmPrMap.width();
height = pmPrMap.height();
}
else
{
width = ui_sportwatcherWidgetBase.grMap->width() - 2;
height = ui_sportwatcherWidgetBase.grMap->height();
width = ui_sportwatcherWidgetBase.grMap->width() - 2;
height = ui_sportwatcherWidgetBase.grMap->height();
}
 
#if defined HAVE_GDAL
if (MapType == MPT_WMS && square)
pmMap = QPixmap(width / (int)mFactor * (int)mFactor, height / (int)mFactor * (int)mFactor);
 
if(MapType == MPT_WMS && square)
pmMap = QPixmap(width / (int)mFactor * (int)mFactor, height / (int)mFactor * (int)mFactor);
else
pmMap = QPixmap(width, height);
pmMap = QPixmap(width, height);
 
#else
pmMap = QPixmap(width, height);
#endif
if (pmMap.isNull())
return;
 
if(pmMap.isNull())
return;
 
// Here we begin do draw something
paint.begin(&pmMap);
 
panX = panY = 0;
 
if (stateHand && mapPan != pan)
if(stateHand && mapPan != pan)
{
mapPan = pan;
panX = mapPan.right() - mapPan.left();
panY = mapPan.bottom() - mapPan.top();
oldTransX += (double)panX;
oldTransY += (double)panY;
mapPan = pan;
panX = mapPan.right() - mapPan.left();
panY = mapPan.bottom() - mapPan.top();
oldTransX += (double)panX;
oldTransY += (double)panY;
}
 
memset(&posNW, 0, sizeof(posn_type));
3002,36 → 3118,36
/*
* Find out the corners of our track (NW, NE, SE, SW)
*/
if (mapLap)
i = mapLap->start_time;
if(mapLap)
i = mapLap->start_time;
else
i = 0;
while ((point = ds.getPoint(i)) != 0)
i = 0;
 
while((point = ds.getPoint(i)) != 0)
{
if (mapLap && point->time > (mapLap->start_time + (mapLap->total_time / 100)))
break;
if(mapLap && point->time > (mapLap->start_time + (mapLap->total_time / 100)))
break;
 
if (point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
if(point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
 
if (SEMI2DEG(point->posn.lat) > posNW.lat)
posNW.lat = SEMI2DEG(point->posn.lat);
if(SEMI2DEG(point->posn.lat) > posNW.lat)
posNW.lat = SEMI2DEG(point->posn.lat);
 
if (SEMI2DEG(point->posn.lat) < posSE.lat)
posSE.lat = SEMI2DEG(point->posn.lat);
if(SEMI2DEG(point->posn.lat) < posSE.lat)
posSE.lat = SEMI2DEG(point->posn.lat);
 
if (SEMI2DEG(point->posn.lon) > posNW.lon)
posNW.lon = SEMI2DEG(point->posn.lon);
if(SEMI2DEG(point->posn.lon) > posNW.lon)
posNW.lon = SEMI2DEG(point->posn.lon);
 
if (SEMI2DEG(point->posn.lon) < posSE.lon)
posSE.lon = SEMI2DEG(point->posn.lon);
if(SEMI2DEG(point->posn.lon) < posSE.lon)
posSE.lon = SEMI2DEG(point->posn.lon);
 
i = point->time + 1;
Data = true;
i = point->time + 1;
Data = true;
}
 
coordW = (posNW.lon > posSE.lon) ? posNW.lon - posSE.lon : posSE.lon - posNW.lon;
3041,19 → 3157,19
// define the ticks to translate the GPS coordinates into pixels.
// The track should be centered and we have to calculate the
// rectangular within we draw the track.
if (coordW < coordH)
if(coordW < coordH)
{
tick = (double)width / coordW + (double)zoom;
tick = (double)width / coordW + (double)zoom;
 
if ((tick * coordH) > height)
tick = (double)height / coordH + (double)zoom;
if((tick * coordH) > height)
tick = (double)height / coordH + (double)zoom;
}
else
{
tick = (double)height / coordH + (double)zoom;
tick = (double)height / coordH + (double)zoom;
 
if ((tick * coordW) > width)
tick = (double)width / coordW + (double)zoom;
if((tick * coordW) > width)
tick = (double)width / coordW + (double)zoom;
}
 
left = width - (width - tick * coordW) / 2;
3061,10 → 3177,10
 
a = tick * coordW;
 
if (Units == 0)
dist = meterW / a; // Meters
if(Units == 0)
dist = meterW / a; // Meters
else
dist = meterW * 1.609344 / a; // 1/1000 mile (5.28 feet)
dist = meterW * 1.609344 / a; // 1/1000 mile (5.28 feet)
 
#if defined HAVE_GDAL
geoRect.llat = 0.0;
3073,6 → 3189,7
geoRect.rlon = 0.0;
geoRect.width = width;
geoRect.height = height;
 
/*
* If we have a map file, we try to read it and if successfull,
* we should get a map painted.
3080,331 → 3197,338
* Currently only WMS-Server is supported, allthough GDAL allows
* several other formats too.
*/
if (!MAP.isEmpty() && Data)
if(!MAP.isEmpty() && Data)
{
bool writeTag = true;
double mtx, mty;
double vx, vy;
bool writeTag = true;
double mtx, mty;
double vx, vy;
 
xOff = yOff = 0;
posRXY.lon = posNW.lon + (width - left + oldTransX) / tick;
posLXY.lat = posNW.lat + (top + oldTransY) / tick;
posLXY.lon = posSE.lon - (left - a - oldTransX) / tick;
posRXY.lat = posSE.lat - (height - top - (tick * coordH) - oldTransY) / tick;
geoRect.llat = posLXY.lat;
geoRect.llon = posLXY.lon;
geoRect.rlat = posRXY.lat;
geoRect.rlon = posRXY.lon;
// width and height of map in meters
mtx = ds.earth_distance(posRXY.lat, posRXY.lon, posRXY.lat, posLXY.lon);
mty = ds.earth_distance(posRXY.lat, posRXY.lon, posLXY.lat, posRXY.lon);
xOff = yOff = 0;
posRXY.lon = posNW.lon + (width - left + oldTransX) / tick;
posLXY.lat = posNW.lat + (top + oldTransY) / tick;
posLXY.lon = posSE.lon - (left - a - oldTransX) / tick;
posRXY.lat = posSE.lat - (height - top - (tick * coordH) - oldTransY) / tick;
geoRect.llat = posLXY.lat;
geoRect.llon = posLXY.lon;
geoRect.rlat = posRXY.lat;
geoRect.rlon = posRXY.lon;
// width and height of map in meters
mtx = ds.earth_distance(posRXY.lat, posRXY.lon, posRXY.lat, posLXY.lon);
mty = ds.earth_distance(posRXY.lat, posRXY.lon, posLXY.lat, posRXY.lon);
 
// factor to correct the map, in case we use a WMS server
if (MapType == MPT_WMS)
{
vx = (posRXY.lon - posLXY.lon) / mtx * CorrX;
vy = (posRXY.lat - posLXY.lat) / mty * CorrY;
posRXY.lon += vx;
posRXY.lat += vy;
posLXY.lon += vx;
posLXY.lat += vy;
}
// factor to correct the map, in case we use a WMS server
if(MapType == MPT_WMS)
{
vx = (posRXY.lon - posLXY.lon) / mtx * CorrX;
vy = (posRXY.lat - posLXY.lat) / mty * CorrY;
posRXY.lon += vx;
posRXY.lat += vy;
posLXY.lon += vx;
posLXY.lat += vy;
}
 
/*
* Write a control file for GDAL, if we use a WMS server.
* Warp an image if we use PNG or BMP or GIF.
* Warp a region if we use TIFF
*/
if (MapType == MPT_WMS)
writeTag = writeWMSTag(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat, width, height);
/*
* Write a control file for GDAL, if we use a WMS server.
* Warp an image if we use PNG or BMP or GIF.
* Warp a region if we use TIFF
*/
if(MapType == MPT_WMS)
writeTag = writeWMSTag(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat, width, height);
 
if (MapType == MPT_GIF || MapType == MPT_BMP || MapType == MPT_PNG ||
MapType == MPT_SGI || MapType == MPT_TIF)
writeTag = warpImage(MAP, &fName);
if(MapType == MPT_GIF || MapType == MPT_BMP || MapType == MPT_PNG ||
MapType == MPT_SGI || MapType == MPT_TIF)
writeTag = warpImage(MAP, &fName);
 
if (writeTag)
{
if (MapType != MPT_SHP && (poDataset = (GDALDataset *)GDALOpen (fName.toAscii().constData(), GA_ReadOnly)) != NULL)
{
QPixmap bild;
int nRasterCount = poDataset->GetRasterCount();
int nXBlock, nYBlock;
GDALColorTable *pCT, *pCTb, *pCTr, *pCTg, *pCTa;
if(writeTag)
{
if(MapType != MPT_SHP && (poDataset = (GDALDataset *)GDALOpen(fName.toAscii().constData(), GA_ReadOnly)) != NULL)
{
QPixmap bild;
int nRasterCount = poDataset->GetRasterCount();
int nXBlock, nYBlock;
GDALColorTable *pCT, *pCTb, *pCTr, *pCTg, *pCTa;
 
int bGotMin, bGotMax;
int tTypeLen, tColor, tColorEntrys;
GDALDataType tRasterType;
double adfMinMax[2];
int bGotMin, bGotMax;
int tTypeLen; //, tColorEntrys;
GDALDataType tRasterType;
double adfMinMax[2];
 
pCT = pCTb = pCTr = pCTg = pCTa = 0;
tTypeLen = 0;
pafScanlineRed = pafScanlineGreen = pafScanlineBlue = pafScanlineAlpha = 0;
Fgeo = true;
/*
* Read every raster band.
*
* If we get 3 raster bands, the image is a 24 bit image.
* If we get 4 raster bands, the image is probably a 24 bit
* image with an alpha channel. Currently the alpha channel
* is ignored!
* If we have 1 raster band, the image is 8 bit monochrom.
* Otherwise the image is undefined and the results are also.
*/
for (a = 1; a <= nRasterCount; a++)
{
if (!Fgeo)
break;
pCT = pCTb = pCTr = pCTg = pCTa = 0;
tTypeLen = 0;
pafScanlineRed = pafScanlineGreen = pafScanlineBlue = pafScanlineAlpha = 0;
Fgeo = true;
 
if (!(poBand = poDataset->GetRasterBand (a)))
{
paint.end();
return;
}
/*
* Read every raster band.
*
* If we get 3 raster bands, the image is a 24 bit image.
* If we get 4 raster bands, the image is probably a 24 bit
* image with an alpha channel. Currently the alpha channel
* is ignored!
* If we have 1 raster band, the image is 8 bit monochrom.
* Otherwise the image is undefined and the results are also.
*/
for(a = 1; a <= nRasterCount; a++)
{
if(!Fgeo)
break;
 
poBand->GetBlockSize (&nXBlock, &nYBlock);
nXSize = poBand->GetXSize();
nYSize = poBand->GetYSize();
tRasterType = poBand->GetRasterDataType ();
tTypeLen = GDALGetDataTypeSize (tRasterType) / 8; // We need Bytes not Bits!
tColor = poBand->GetColorInterpretation ();
if(!(poBand = poDataset->GetRasterBand(a)))
{
paint.end();
return;
}
 
adfMinMax[0] = poBand->GetMinimum (&bGotMin);
adfMinMax[1] = poBand->GetMaximum (&bGotMax);
poBand->GetBlockSize(&nXBlock, &nYBlock);
nXSize = poBand->GetXSize();
nYSize = poBand->GetYSize();
tRasterType = poBand->GetRasterDataType();
tTypeLen = GDALGetDataTypeSize(tRasterType) / 8; // We need Bytes not Bits!
// tColor = poBand->GetColorInterpretation();
 
if (!(bGotMin && bGotMax))
GDALComputeRasterMinMax ((GDALRasterBandH)poBand, TRUE, adfMinMax);
adfMinMax[0] = poBand->GetMinimum(&bGotMin);
adfMinMax[1] = poBand->GetMaximum(&bGotMax);
 
if ((pCT = poBand->GetColorTable()) != NULL)
tColorEntrys = poBand->GetColorTable()->GetColorEntryCount();
if(!(bGotMin && bGotMax))
GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
 
switch (a)
{
case 1: pafScanlineRed = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineRed; pCTr = pCT; break;
case 2: pafScanlineGreen = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineGreen; pCTg = pCT; break;
case 3: pafScanlineBlue = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineBlue; pCTb = pCT; break;
case 4: pafScanlineAlpha = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineAlpha; pCTa = pCT; break;
}
// if((pCT = poBand->GetColorTable()) != NULL)
// tColorEntrys = poBand->GetColorTable()->GetColorEntryCount();
 
if (!pafScanline)
{
paint.end();
KMessageBox::error(this, i18n("Not enough memory for a raster operation!"));
return;
}
switch(a)
{
case 1: pafScanlineRed = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineRed; pCTr = pCT; break;
case 2: pafScanlineGreen = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineGreen; pCTg = pCT; break;
case 3: pafScanlineBlue = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineBlue; pCTb = pCT; break;
case 4: pafScanlineAlpha = new unsigned char[tTypeLen * nXSize * nYSize]; pafScanline = pafScanlineAlpha; pCTa = pCT; break;
}
 
memset (pafScanline, 0, tTypeLen * nXSize * nYSize);
if(!pafScanline)
{
paint.end();
KMessageBox::error(this, i18n("Not enough memory for a raster operation!"));
return;
}
 
/*
* Get the image (from the server) and put the tiles together.
*
* The function reads only one raster band. This is,
* because the function is called for every raster band and
* every raster band is stored into a separate array.
*/
if (poBand->RasterIO (GF_Read, 0, 0, nXSize, nYSize, pafScanline, nXSize, nYSize, tRasterType, 0, 0) == CE_Failure)
{
paint.end();
KMessageBox::error(this, i18n("Error reading a raster band!"));
paint.begin(&pmMap);
Fgeo = false;
break;
}
else
Fgeo = true;
}
memset(pafScanline, 0, tTypeLen * nXSize * nYSize);
 
/*
* Only if Fgeo is TRUE, we've read successfully all raster
* bands. Now we have to put the bands together to get
* an image.
*/
if (Fgeo)
{
unsigned char *pCombinedBytes = new unsigned char[(tTypeLen * nXSize * nYSize * nRasterCount)];
unsigned char *ptr_dest, *ptr_src;
int j;
/*
* Get the image (from the server) and put the tiles together.
*
* The function reads only one raster band. This is,
* because the function is called for every raster band and
* every raster band is stored into a separate array.
*/
if(poBand->RasterIO(GF_Read, 0, 0, nXSize, nYSize, pafScanline, nXSize, nYSize, tRasterType, 0, 0) == CE_Failure)
{
paint.end();
KMessageBox::error(this, i18n("Error reading a raster band!"));
paint.begin(&pmMap);
Fgeo = false;
break;
}
else
Fgeo = true;
}
 
ptr_dest = ptr_src = 0;
/*
* Only if Fgeo is TRUE, we've read successfully all raster
* bands. Now we have to put the bands together to get
* an image.
*/
if(Fgeo)
{
unsigned char *pCombinedBytes = new unsigned char[(tTypeLen * nXSize * nYSize * nRasterCount)];
unsigned char *ptr_dest, *ptr_src;
int j;
 
/*
* We need two nested loops to set the pixels in the wanted
* order.
*/
for (a = 0, j = 0; a < (nXSize * nYSize * nRasterCount); a += nRasterCount, j++)
{
int k = a;
ptr_dest = ptr_src = 0;
 
for (int m = nRasterCount - 1; m >= 0; m--, k++)
{
unsigned char *pBytes = 0;
/*
* We need two nested loops to set the pixels in the wanted
* order.
*/
for(a = 0, j = 0; a < (nXSize * nYSize * nRasterCount); a += nRasterCount, j++)
{
int k = a;
 
switch (m)
{
case 3: pBytes = pafScanlineAlpha; pCT = pCTa; break;
case 2: pBytes = pafScanlineBlue; pCT = pCTb; break;
case 1: pBytes = pafScanlineGreen; pCT = pCTg; break;
default: pBytes = pafScanlineRed; pCT = pCTr;
}
for(int m = nRasterCount - 1; m >= 0; m--, k++)
{
unsigned char *pBytes = 0;
 
ptr_dest = pCombinedBytes + k;
unsigned char b = pBytes[j];
switch(m)
{
case 3: pBytes = pafScanlineAlpha; pCT = pCTa; break;
case 2: pBytes = pafScanlineBlue; pCT = pCTb; break;
case 1: pBytes = pafScanlineGreen; pCT = pCTg; break;
default: pBytes = pafScanlineRed; pCT = pCTr;
}
 
/*
* If we have a color table, the pixels are pointers
* to the color table. We need to convert them into
* 24 bit pixels plus an optional alpha channel.
*/
if (pCT != NULL)
{
GDALColorEntry ce;
unsigned int c = (unsigned int)b;
c = pCT->GetColorEntryAsRGB (c, &ce);
ptr_dest = pCombinedBytes + k;
unsigned char b = pBytes[j];
 
if (m == 0) c = ce.c1;
if (m == 1) c = ce.c2;
if (m == 2) c = ce.c3;
if (m == 3) c = ce.c4;
/*
* If we have a color table, the pixels are pointers
* to the color table. We need to convert them into
* 24 bit pixels plus an optional alpha channel.
*/
if(pCT != NULL)
{
GDALColorEntry ce;
unsigned int c = (unsigned int)b;
c = pCT->GetColorEntryAsRGB(c, &ce);
 
b = (unsigned char)c;
}
if(m == 0) c = ce.c1;
 
ptr_src = &b;
memcpy (ptr_dest, ptr_src, 1);
}
}
if(m == 1) c = ce.c2;
 
x1 = y1 = 0;
if(m == 2) c = ce.c3;
 
/*
* The following loop is QT specific! It sets the pixels
* of the raw image, pixel by pixel. This may be slow, but
* everything else didn't work :-(
*
* FIXME: We need a more effective routine to put the
* raw image into QT's "painter" class.
*/
for (a = 0; a < (nXSize * nYSize * nRasterCount); a += nRasterCount)
{
if (x1 < width && y1 < height)
{
if (nRasterCount == 3)
paint.setPen (QPen(QColor((int)pCombinedBytes[a+2], (int)pCombinedBytes[a+1], (int)pCombinedBytes[a]), Qt::SolidLine));
else if (nRasterCount > 3)
paint.setPen (QPen(QColor(qRgba((int)pCombinedBytes[a+3], (int)pCombinedBytes[a+2], (int)pCombinedBytes[a+1], (int)pCombinedBytes[a])), Qt::SolidLine));
else if (nRasterCount == 2)
paint.setPen (QPen(QColor((int)pCombinedBytes[a+1], (int)pCombinedBytes[a], (int)pCombinedBytes[a+1]), Qt::SolidLine));
else if (nRasterCount == 1)
paint.setPen (QPen(QColor((int)pCombinedBytes[a], (int)pCombinedBytes[a], (int)pCombinedBytes[a]), Qt::SolidLine));
if(m == 3) c = ce.c4;
 
paint.drawPoint(x1, y1);
}
b = (unsigned char)c;
}
 
x1++;
ptr_src = &b;
memcpy(ptr_dest, ptr_src, 1);
}
}
 
if (x1 >= nXSize)
{
x1 = 0;
y1++;
}
}
x1 = y1 = 0;
 
delete pCombinedBytes;
pCombinedBytes = 0;
}
/*
* The following loop is QT specific! It sets the pixels
* of the raw image, pixel by pixel. This may be slow, but
* everything else didn't work :-(
*
* FIXME: We need a more effective routine to put the
* raw image into QT's "painter" class.
*/
for(a = 0; a < (nXSize * nYSize * nRasterCount); a += nRasterCount)
{
if(x1 < width && y1 < height)
{
if(nRasterCount == 3)
paint.setPen(QPen(QColor((int)pCombinedBytes[a + 2], (int)pCombinedBytes[a + 1], (int)pCombinedBytes[a]), Qt::SolidLine));
else if(nRasterCount > 3)
paint.setPen(QPen(QColor(qRgba((int)pCombinedBytes[a + 3], (int)pCombinedBytes[a + 2], (int)pCombinedBytes[a + 1], (int)pCombinedBytes[a])), Qt::SolidLine));
else if(nRasterCount == 2)
paint.setPen(QPen(QColor((int)pCombinedBytes[a + 1], (int)pCombinedBytes[a], (int)pCombinedBytes[a + 1]), Qt::SolidLine));
else if(nRasterCount == 1)
paint.setPen(QPen(QColor((int)pCombinedBytes[a], (int)pCombinedBytes[a], (int)pCombinedBytes[a]), Qt::SolidLine));
 
if (pafScanlineRed)
delete pafScanlineRed;
paint.drawPoint(x1, y1);
}
 
if (pafScanlineGreen)
delete pafScanlineGreen;
x1++;
 
if (pafScanlineBlue)
delete pafScanlineBlue;
if(x1 >= nXSize)
{
x1 = 0;
y1++;
}
}
 
if (pafScanlineAlpha)
delete pafScanlineAlpha;
delete pCombinedBytes;
pCombinedBytes = 0;
}
 
GDALClose (poDataset);
poDataset = 0;
if(pafScanlineRed)
delete pafScanlineRed;
 
if (MAP != fName)
unlink (fName.toAscii().data());
}
if(pafScanlineGreen)
delete pafScanlineGreen;
 
if(pafScanlineBlue)
delete pafScanlineBlue;
 
if(pafScanlineAlpha)
delete pafScanlineAlpha;
 
GDALClose(poDataset);
poDataset = 0;
 
if(MAP != fName)
unlink(fName.toAscii().data());
}
 
#if defined HAVE_MAPNIK
else if (MapType == MPT_SHP)
{
QDir shpd(MAP, QString("*.shp"));
else if(MapType == MPT_SHP)
{
QDir shpd(MAP, QString("*.shp"));
 
if (shpd.count() < 1)
{
KMessageBox::error(this, i18n("There is no shape file in directory %1").arg(MAP));
Fgeo = false;
}
else
{
SRender rd;
QColor bg(220, 220, 220); // background color
if(shpd.count() < 1)
{
KMessageBox::error(this, i18n("There is no shape file in directory %1").arg(MAP));
Fgeo = false;
}
else
{
SRender rd;
QColor bg(220, 220, 220); // background color
 
if (curTab == 0 && !ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.imgMap->width(), ui_sportwatcherWidgetBase.imgMap->height());
else if (!ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.grMap->width(), ui_sportwatcherWidgetBase.grMap->height());
else if (ActivePrint)
rd.setDrawArea(pmPrMap.width(), pmPrMap.height());
if(curTab == 0 && !ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.imgMap->width(), ui_sportwatcherWidgetBase.imgMap->height());
else if(!ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.grMap->width(), ui_sportwatcherWidgetBase.grMap->height());
else if(ActivePrint)
rd.setDrawArea(pmPrMap.width(), pmPrMap.height());
 
rd.setMapType(SRender::MAP_SHAPE);
rd.setMapType(SRender::MAP_SHAPE);
 
if (rd.getMap(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat))
{
paint.fillRect(0, 0, width+2, height+2, bg);
paint.drawPixmap(0, 0, rd.pixmap());
Fgeo = true;
}
else
Fgeo = false;
}
}
else if (MapType == MPT_OSM)
{
QFileInfo osmf(MAP);
if(rd.getMap(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat))
{
paint.fillRect(0, 0, width + 2, height + 2, bg);
paint.drawPixmap(0, 0, rd.pixmap());
Fgeo = true;
}
else
Fgeo = false;
}
}
else if(MapType == MPT_OSM)
{
QFileInfo osmf(MAP);
 
if (!osmf.exists())
{
KMessageBox::error(this, i18n("The OSM file %1 does not exist!").arg(MAP));
Fgeo = false;
}
else
{
SRender rd;
QColor bg(220, 220, 220); // background color
if(!osmf.exists())
{
KMessageBox::error(this, i18n("The OSM file %1 does not exist!").arg(MAP));
Fgeo = false;
}
else
{
SRender rd;
QColor bg(220, 220, 220); // background color
 
if (curTab == 0 && !ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.imgMap->width(), ui_sportwatcherWidgetBase.imgMap->height());
else if (!ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.grMap->width(), ui_sportwatcherWidgetBase.grMap->height());
else if (ActivePrint)
rd.setDrawArea(pmPrMap.width(), pmPrMap.height());
if(curTab == 0 && !ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.imgMap->width(), ui_sportwatcherWidgetBase.imgMap->height());
else if(!ActivePrint)
rd.setDrawArea(ui_sportwatcherWidgetBase.grMap->width(), ui_sportwatcherWidgetBase.grMap->height());
else if(ActivePrint)
rd.setDrawArea(pmPrMap.width(), pmPrMap.height());
 
rd.setMapType(SRender::MAP_OSM);
rd.setMapType(SRender::MAP_OSM);
 
if (rd.getMap(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat))
{
paint.fillRect(0, 0, width+2, height+2, bg);
paint.drawPixmap(0, 0, rd.pixmap());
Fgeo = true;
}
else
Fgeo = false;
}
}
if(rd.getMap(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat))
{
paint.fillRect(0, 0, width + 2, height + 2, bg);
paint.drawPixmap(0, 0, rd.pixmap());
Fgeo = true;
}
else
Fgeo = false;
}
}
 
#endif // HAVE_MAPNIK
else
{
KMessageBox::error(this, i18n("Error opening map file!"));
Fgeo = false;
}
}
else
{
KMessageBox::error(this, i18n("Error opening map file!"));
Fgeo = false;
}
}
}
 
#endif // HAVE_GDAL
/*
* Here we come to draw the track. It will be drawn over the previous
3422,14 → 3546,15
QPen dot(red, 4, Qt::SolidLine);
QPen line(black, 2, Qt::SolidLine);
QPen yline(yellow, 4, Qt::SolidLine);
 
// Fill background with background colors, if there is no map.
if (!Fgeo)
paint.fillRect(0, 0, width+2, height+2, background);
if(!Fgeo)
paint.fillRect(0, 0, width + 2, height + 2, background);
 
if (Units == 0)
fact = 1000.0;
if(Units == 0)
fact = 1000.0;
else
fact = 1609.344;
fact = 1609.344;
 
paint.setPen(line);
paint.drawLine(10, height - 9, 10, height - 4);
3437,112 → 3562,114
paint.drawLine(10 + (fact / dist), height - 9, 10 + (fact / dist), height - 4);
paint.setFont(fntNormal);
 
if (Units == 0)
paint.drawText(10, height - 10, QString("1000 m"));
if(Units == 0)
paint.drawText(10, height - 10, QString("1000 m"));
else
paint.drawText(10, height - 10, QString("5280 ft"));
paint.drawText(10, height - 10, QString("5280 ft"));
 
// Draw track
if (mapLap)
i = mapLap->start_time;
if(mapLap)
i = mapLap->start_time;
else
i = 0;
i = 0;
 
x1 = y1 = 0.0;
bool wStart = false;
 
while ((point = ds.getPoint(i)) != 0)
while((point = ds.getPoint(i)) != 0)
{
if (mapLap && point->time > (mapLap->start_time + (mapLap->total_time / 100)))
break;
if(mapLap && point->time > (mapLap->start_time + (mapLap->total_time / 100)))
break;
 
if (point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
if(point->posn.lat == 0x7fffffff || point->posn.lon == 0x7fffffff)
{
i = point->time + 1;
continue;
}
 
x2 = (left + ((posNW.lon - SEMI2DEG(point->posn.lon)) * tick * -1)) + oldTransX;
y2 = (top + ((posNW.lat - SEMI2DEG(point->posn.lat)) * tick)) + oldTransY;
x2 = (left + ((posNW.lon - SEMI2DEG(point->posn.lon)) * tick * -1)) + oldTransX;
y2 = (top + ((posNW.lat - SEMI2DEG(point->posn.lat)) * tick)) + oldTransY;
 
if (!wStart && x1 != 0.0 && y1 != 0.0)
{
// Load the start symbol
QPixmap qpx (KIcon(QString("wstart")).pixmap(16));
// Find the angle of the track and turn the symbol accordingly
// we use Pythagoras to calculate the triangle
double xl = (x1 < x2) ? x2 - x1 : x1 - x2;
double yl = (y1 < y2) ? y2 - y1 : y1 - y2;
double da = fmin (xl, yl);
double db = fmax (xl, yl);
double zl = sqrt (pow (da, 2) + pow (db, 2));
double angle = (asin(da / zl) / M_PIl) * 180.0;
if(!wStart && x1 != 0.0 && y1 != 0.0)
{
// Load the start symbol
QPixmap qpx(KIcon(QString("wstart")).pixmap(16));
// Find the angle of the track and turn the symbol accordingly
// we use Pythagoras to calculate the triangle
double xl = (x1 < x2) ? x2 - x1 : x1 - x2;
double yl = (y1 < y2) ? y2 - y1 : y1 - y2;
double da = fmin(xl, yl);
double db = fmax(xl, yl);
double zl = sqrt(pow(da, 2) + pow(db, 2));
double angle = (asin(da / zl) / M_PIl) * 180.0;
 
angle = (angle > 45.0) ? 90.0 - angle : angle;
angle = (angle > 45.0) ? 90.0 - angle : angle;
 
// cout << "Winkel: " << angle << " ---- X: " << xl << ", Y: " << yl << ", Z: " << zl << ", Point (x1,y1,x2,y2): " << x1 << ", " << y1 << ", " << x2 << ", " << y2 << endl;
if (x1 < x2 && y1 < y2) // right, down
angle = 90.0 + angle;
else if (x1 > x2 && y1 < y2) // left, down
angle = 270.0 - angle;
else if (x1 > x2 && y1 > y2) // left, up
angle = 270.0 + angle;
else // right, up
angle = 90.0 - angle;
if(x1 < x2 && y1 < y2) // right, down
angle = 90.0 + angle;
else if(x1 > x2 && y1 < y2) // left, down
angle = 270.0 - angle;
else if(x1 > x2 && y1 > y2) // left, up
angle = 270.0 + angle;
else // right, up
angle = 90.0 - angle;
 
// cout << "Realer Winkel: " << angle << endl;
// Set the center of the symbol
paint.save ();
paint.translate (x1, y1);
// rotate the symbol
paint.rotate (angle);
paint.drawPixmap (-8, -8, qpx);
paint.restore ();
wStart = true;
}
// Set the center of the symbol
paint.save();
paint.translate(x1, y1);
// rotate the symbol
paint.rotate(angle);
paint.drawPixmap(-8, -8, qpx);
paint.restore();
wStart = true;
}
 
if (x1 == 0.0 && y1 == 0.0)
{
x1 = x2;
y1 = y2;
}
if(x1 == 0.0 && y1 == 0.0)
{
x1 = x2;
y1 = y2;
}
 
paint.setPen(yline);
paint.drawLine(x1, y1, x2, y2);
paint.setPen(yline);
paint.drawLine(x1, y1, x2, y2);
 
if ((point->distance - dist) >= fact) // a dot at every 1000 meters or at 1 mile
{
paint.setPen(dot);
paint.drawEllipse(x2-2, y2-2, 3, 3);
dist = (int)(point->distance / fact) * fact;
}
if((point->distance - dist) >= fact) // a dot at every 1000 meters or at 1 mile
{
paint.setPen(dot);
paint.drawEllipse(x2 - 2, y2 - 2, 3, 3);
dist = (int)(point->distance / fact) * fact;
}
 
paint.setPen(line);
paint.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
i = point->time + 1;
paint.setPen(line);
paint.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
i = point->time + 1;
}
 
bool lastLap = false;
 
if (mapLap)
if (ds.getRunNode()->run->last_lap_index == mapLap->index)
lastLap = true;
if(mapLap)
if(ds.getRunNode()->run->last_lap_index == mapLap->index)
lastLap = true;
 
if ((!mapLap || lastLap) && wStart)
if((!mapLap || lastLap) && wStart)
{
// load the end symbol
QPixmap qpx (KIcon(QString("wtarget")).pixmap(16));
paint.drawPixmap (x2, y2 - 16, qpx);
// load the end symbol
QPixmap qpx(KIcon(QString("wtarget")).pixmap(16));
paint.drawPixmap(x2, y2 - 16, qpx);
}
 
paint.end();
 
if (curTab == 0 && !ActivePrint)
ui_sportwatcherWidgetBase.imgMap->setPixmap(pmMap);
else if (ActivePrint)
pmPrMap = pmMap;
if(curTab == 0 && !ActivePrint)
ui_sportwatcherWidgetBase.imgMap->setPixmap(pmMap);
else if(ActivePrint)
pmPrMap = pmMap;
else
ui_sportwatcherWidgetBase.grMap->setPixmap(pmMap);
ui_sportwatcherWidgetBase.grMap->setPixmap(pmMap);
 
QApplication::restoreOverrideCursor();
}
3558,73 → 3685,74
{
curTab = tab;
 
if (tab == 0 && tabDirt0)
if(tab == 0 && tabDirt0)
{
DIRTY = true;
showLaps();
showTrack();
showCurves();
DIRTY = false;
tabDirt0 = false;
DIRTY = true;
showLaps();
showTrack();
showCurves();
DIRTY = false;
tabDirt0 = false;
}
else if (tab == 1 && tabDirt1)
else if(tab == 1 && tabDirt1)
{
DIRTY = true;
DIRTY = true;
 
if (tabDirt0)
showLaps();
if(tabDirt0)
showLaps();
 
showTrack();
DIRTY = false;
tabDirt1 = false;
showTrack();
DIRTY = false;
tabDirt1 = false;
}
else if (tab == 2 && tabDirt2)
else if(tab == 2 && tabDirt2)
{
DIRTY = true;
DIRTY = true;
 
if (tabDirt0)
showLaps();
if(tabDirt0)
showLaps();
 
setMouseTracking (true);
ui_sportwatcherWidgetBase.tabView->setMouseTracking (true);
ui_sportwatcherWidgetBase.grHR->setMouseTracking (true);
ui_sportwatcherWidgetBase.grElevation->setMouseTracking (true);
ui_sportwatcherWidgetBase.grSpeed->setMouseTracking (true);
showThreeCurve();
tabDirt2 = false;
DIRTY = false;
setMouseTracking(true);
ui_sportwatcherWidgetBase.tabView->setMouseTracking(true);
ui_sportwatcherWidgetBase.grHR->setMouseTracking(true);
ui_sportwatcherWidgetBase.grElevation->setMouseTracking(true);
ui_sportwatcherWidgetBase.grSpeed->setMouseTracking(true);
showThreeCurve();
tabDirt2 = false;
DIRTY = false;
}
}
 
void sportwatcherWidget::showCurves()
{
showCurves (mapLap);
showCurves(mapLap);
}
 
void sportwatcherWidget::showCurves(LAP *lap)
{
QPainter paint;
int width, height;
int i, secs, cuType;
int lineHeight, margin_left, margin_right, margin_bottom;
int x1, y1, x2, y2; // Coordinates
bool meter;
double maxHeight, minHeight, maxSpeed, minSpeed;
int maxHr, minHr, rh;
POINT *point;
RUN_NODE *rn;
LAP *lp;
double w_tick, h_tick; // Number of pixels one "tick" has;
// This depends on the width and height
// of the image.
QPainter paint;
int width, height;
int i, secs, cuType;
int lineHeight, margin_left, margin_right, margin_bottom;
int x1, y1, x2, y2; // Coordinates
bool meter;
double maxHeight, minHeight, maxSpeed, minSpeed;
int maxHr, minHr, rh;
POINT *point;
RUN_NODE *rn;
LAP *lp;
double w_tick, h_tick; // Number of pixels one "tick" has;
 
// This depends on the width and height
// of the image.
// First we draw a grid based on the min and max
// values detected in the function showLap(). In case
// all values are 0, we exit here.
if (min_hr == 0 && max_hr == 0 && min_height == 0.0 && max_height == 0.0)
return;
if(min_hr == 0 && max_hr == 0 && min_height == 0.0 && max_height == 0.0)
return;
 
if (!DIRTY || curTab != 0)
return;
if(!DIRTY || curTab != 0)
return;
 
// Look up, what curves we should draw
cuType = ui_sportwatcherWidgetBase.kcbCurveTypes->currentIndex();
3636,42 → 3764,42
 
// we need a somewhat bigger area to draw our curves than
// we have with the real min and max values.
if (max_height > 0.0)
if(max_height > 0.0)
{
double add = (max_height - min_height) / 100.0 * 5.0; // Percent
double add = (max_height - min_height) / 100.0 * 5.0; // Percent
 
maxHeight = max_height + add;
minHeight = min_height - add;
maxHeight = max_height + add;
minHeight = min_height - add;
 
if (minHeight < 0.0) // make sure, we are not too deep
minHeight = 0.0;
if(minHeight < 0.0) // make sure, we are not too deep
minHeight = 0.0;
}
else
maxHeight = minHeight = 0.0;
maxHeight = minHeight = 0.0;
 
if (max_speed > 0.0)
if(max_speed > 0.0)
{
double add = (max_speed - min_speed) / 100.0 * 5.0; // Percent
double add = (max_speed - min_speed) / 100.0 * 5.0; // Percent
 
maxSpeed = max_speed + add;
minSpeed = min_speed - add;
maxSpeed = max_speed + add;
minSpeed = min_speed - add;
 
if (minSpeed < 0.0) // make sure, we are not too deep
minSpeed = 0.0;
if(minSpeed < 0.0) // make sure, we are not too deep
minSpeed = 0.0;
}
else
maxSpeed = minSpeed = 0.0;
maxSpeed = minSpeed = 0.0;
 
if (max_hr > 0)
if(max_hr > 0)
{
maxHr = max_hr + 10;
minHr = min_hr - 10;
maxHr = max_hr + 10;
minHr = min_hr - 10;
 
if (minHr < 0)
minHr = 0;
if(minHr < 0)
minHr = 0;
}
else
maxHr = minHr = 0;
maxHr = minHr = 0;
 
// Define colors
QColor background(220, 220, 220); // Background of graphic
3698,44 → 3826,44
 
w_tick = (double)(width - (margin_left + margin_right)) / (max_time + ds.getPauseTime()); // 1 tick = 1 second
 
if (cuType == 1) // Speed and heart rate?
if(cuType == 1) // Speed and heart rate?
{
if ((maxSpeed - minSpeed) > (double)(maxHr - minHr))
{
h_tick = (double)rh / (maxSpeed - minSpeed); // 1 tick = 1 km/h
meter = true;
}
else
{
h_tick = (double)rh / ((double)maxHr - (double)minHr); // 1 tick = 1 bpm
meter = false;
}
if((maxSpeed - minSpeed) > (double)(maxHr - minHr))
{
h_tick = (double)rh / (maxSpeed - minSpeed); // 1 tick = 1 km/h
meter = true;
}
else
{
h_tick = (double)rh / ((double)maxHr - (double)minHr); // 1 tick = 1 bpm
meter = false;
}
}
else if (cuType == 2) // Elevation and speed?
else if(cuType == 2) // Elevation and speed?
{
if ((maxHeight - minHeight) > (double)(maxHr - minHr))
{
h_tick = (double)rh / (maxHeight - minHeight); // 1 tick = 1 meter
meter = true;
}
else
{
h_tick = (double)rh / (maxSpeed - minSpeed); // 1 tick = 1 km/h
meter = false;
}
if((maxHeight - minHeight) > (double)(maxHr - minHr))
{
h_tick = (double)rh / (maxHeight - minHeight); // 1 tick = 1 meter
meter = true;
}
else
{
h_tick = (double)rh / (maxSpeed - minSpeed); // 1 tick = 1 km/h
meter = false;
}
}
else // Elevation and heart rate
{
if ((maxHeight - minHeight) > (double)(maxHr - minHr))
{
h_tick = (double)rh / (maxHeight - minHeight); // 1 tick = 1 meter
meter = true;
}
else
{
h_tick = (double)rh / ((double)maxHr - (double)minHr); // 1 tick = 1 bpm
meter = false;
}
if((maxHeight - minHeight) > (double)(maxHr - minHr))
{
h_tick = (double)rh / (maxHeight - minHeight); // 1 tick = 1 meter
meter = true;
}
else
{
h_tick = (double)rh / ((double)maxHr - (double)minHr); // 1 tick = 1 bpm
meter = false;
}
}
 
// Fill background with background colors
3764,20 → 3892,20
rn = ds.getRunNode();
paint.setPen(QPen(hlight, 1, Qt::SolidLine));
 
for (i = rn->run->first_lap_index; (unsigned int)i <= rn->run->last_lap_index; i++)
for(i = rn->run->first_lap_index; (unsigned int)i <= rn->run->last_lap_index; i++)
{
if ((lp = ds.getLap(i)) == NULL)
continue;
if((lp = ds.getLap(i)) == NULL)
continue;
 
qt = garmin_dtime(lp->start_time);
secs = zeit.secsTo(qt->time());
delete qt;
x1 = secs * w_tick + margin_left + 1;
qt = garmin_dtime(lp->start_time);
secs = zeit.secsTo(qt->time());
delete qt;
x1 = secs * w_tick + margin_left + 1;
 
if (lap && lp->start_time == lap->start_time)
paint.fillRect(x1, 2, (int)((double)lap->total_time / 100.0 * w_tick), height - margin_bottom - 2, hlight);
else
paint.drawLine(x1, 2, x1, height - margin_bottom);
if(lap && lp->start_time == lap->start_time)
paint.fillRect(x1, 2, (int)((double)lap->total_time / 100.0 * w_tick), height - margin_bottom - 2, hlight);
else
paint.drawLine(x1, 2, x1, height - margin_bottom);
}
 
// Grid vertical
3787,52 → 3915,53
paint.save();
paint.rotate(270);
 
if (cuType == 1)
paint.setPen(QPen(red, 1, Qt::SolidLine));
if(cuType == 1)
paint.setPen(QPen(red, 1, Qt::SolidLine));
else
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
 
// Information on left side
if (cuType == 0)
paint.drawText((height + 4) * -1, 3, height - 2, lineHeight, Qt::AlignCenter, i18n("Elevation (%1)").arg((Units == 1) ? "ft" : "m"));
else if (cuType == 1)
paint.drawText((height + 4) * -1, 3, height - 2, lineHeight, Qt::AlignCenter, i18n("Speed (%1)").arg((Units == 1) ? "mph" : "km/h"));
if(cuType == 0)
paint.drawText((height + 4) * -1, 3, height - 2, lineHeight, Qt::AlignCenter, i18n("Elevation (%1)").arg((Units == 1) ? "ft" : "m"));
else if(cuType == 1)
paint.drawText((height + 4) * -1, 3, height - 2, lineHeight, Qt::AlignCenter, i18n("Speed (%1)").arg((Units == 1) ? "mph" : "km/h"));
else
paint.drawText((height + 4) * -1, 3, height - 2, lineHeight, Qt::AlignCenter, i18n("Elevation (%1)").arg((Units == 1) ? "ft" : "m"));
paint.drawText((height + 4) * -1, 3, height - 2, lineHeight, Qt::AlignCenter, i18n("Elevation (%1)").arg((Units == 1) ? "ft" : "m"));
 
if (cuType == 2)
paint.setPen(QPen(red, 1, Qt::SolidLine));
if(cuType == 2)
paint.setPen(QPen(red, 1, Qt::SolidLine));
else
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.setPen(QPen(blue, 1, Qt::SolidLine));
 
// Information on right side
if (cuType < 2)
paint.drawText((height + 4) * -1, width - 1 - lineHeight, height - 2, lineHeight, Qt::AlignCenter, i18n("Heart Rate (bpm)"));
if(cuType < 2)
paint.drawText((height + 4) * -1, width - 1 - lineHeight, height - 2, lineHeight, Qt::AlignCenter, i18n("Heart Rate (bpm)"));
else
paint.drawText((height + 4) * -1, width - 1 - lineHeight, height - 2, lineHeight, Qt::AlignCenter, i18n("Speed (%1)").arg((Units == 1) ? "mph" : "km/h"));
paint.drawText((height + 4) * -1, width - 1 - lineHeight, height - 2, lineHeight, Qt::AlignCenter, i18n("Speed (%1)").arg((Units == 1) ? "mph" : "km/h"));
 
paint.restore();
paint.setPen(QPen(mark, 1, Qt::SolidLine));
 
// Draw the time scale on the bottom of the graphic
for (i = 0; (unsigned int)i < (max_time + ds.getPauseTime()); i++)
for(i = 0; (unsigned int)i < (max_time + ds.getPauseTime()); i++)
{
if (i > 0 && !(i % 600)) // every 10 minutes
{
x1 = x2 = margin_left + w_tick * i;
if(i > 0 && !(i % 600)) // every 10 minutes
{
x1 = x2 = margin_left + w_tick * i;
 
if (x1 == (width - margin_right))
continue;
if(x1 == (width - margin_right))
continue;
 
y1 = 2;
y2 = height - margin_bottom;
paint.drawLine(x1, y1, x2, y2);
QTime tm(0, 0, 0);
tm = tm.addSecs(i);
paint.setPen(QPen(frame, 1, Qt::SolidLine));
y1 = 2;
y2 = height - margin_bottom;
paint.drawLine(x1, y1, x2, y2);
QTime tm(0, 0, 0);
tm = tm.addSecs(i);
paint.setPen(QPen(frame, 1, Qt::SolidLine));
// paint.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, tm.toString((i >= 3600) ? "hh:mm:ss" : "mm:ss"));
paint.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime (tm, (i >= 3600) ? true : false));
paint.setPen(QPen(mark, 1, Qt::SolidLine));
}
paint.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime(tm, (i >= 3600) ? true : false));
paint.setPen(QPen(mark, 1, Qt::SolidLine));
}
}
 
// This is the total time, with pauses included, at the lower right
3845,34 → 3974,34
paint.drawText(width - margin_right - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime(tm, (max_time >= 3600) ? true : false));
 
// Draw the minimal elevation, speed and/or heart rate
if (max_height > 0.0 || max_speed > 0.0)
if(max_height > 0.0 || max_speed > 0.0)
{
// left side
if (cuType == 1)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(12, height - margin_bottom - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", minSpeed));
}
else
{
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
paint.drawText(12, height - margin_bottom - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", (Units == 1) ? minHeight / 0.304 : minHeight));
}
// left side
if(cuType == 1)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(12, height - margin_bottom - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", minSpeed));
}
else
{
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
paint.drawText(12, height - margin_bottom - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", (Units == 1) ? minHeight / 0.304 : minHeight));
}
}
if (max_hr > 0 || max_speed > 0.0)
 
if(max_hr > 0 || max_speed > 0.0)
{
// right side
if (cuType == 2)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, height - margin_bottom - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.0f", minSpeed));
}
else
{
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, height - margin_bottom - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", minHr));
}
// right side
if(cuType == 2)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, height - margin_bottom - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.0f", minSpeed));
}
else
{
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, height - margin_bottom - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", minHr));
}
}
 
paint.setPen(QPen(mark, 1, Qt::SolidLine));
3881,156 → 4010,157
int factor = 0;
int target = 0;
 
if (cuType == 0) // Elevation and heart rate
if(cuType == 0) // Elevation and heart rate
{
factor = (meter) ? (maxHeight - minHeight) / (rh / 12) : (maxHr - minHr) / (rh / 12);
target = (meter) ? (int)(maxHeight - minHeight) : (maxHr - minHr);
factor = (meter) ? (maxHeight - minHeight) / (rh / 12) : (maxHr - minHr) / (rh / 12);
target = (meter) ? (int)(maxHeight - minHeight) : (maxHr - minHr);
}
else if (cuType == 1) // Speed and heart rate
else if(cuType == 1) // Speed and heart rate
{
factor = (meter) ? (maxSpeed - minSpeed) / (rh / 12) : (maxHr - minHr) / (rh / 12);
target = (meter) ? (int)(maxSpeed - minSpeed) : (maxHr - minHr);
factor = (meter) ? (maxSpeed - minSpeed) / (rh / 12) : (maxHr - minHr) / (rh / 12);
target = (meter) ? (int)(maxSpeed - minSpeed) : (maxHr - minHr);
}
else // Elevation and speed
{
factor = (meter) ? (maxHeight - minHeight) / (rh /12) : (maxSpeed - minSpeed) / (rh / 12);
target = (meter) ? (int)(maxHeight - minHeight) : (int)(maxSpeed - minSpeed);
factor = (meter) ? (maxHeight - minHeight) / (rh / 12) : (maxSpeed - minSpeed) / (rh / 12);
target = (meter) ? (int)(maxHeight - minHeight) : (int)(maxSpeed - minSpeed);
}
 
// To prevent a division by zero error, we check the <factor>
if (factor == 0)
factor = 1;
if(factor == 0)
factor = 1;
 
// Beside the horizontal part of the grid, we draw the scale on the
// left and the right side.
int oldy = height;
 
for (i = 0; i < target; i++)
for(i = 0; i < target; i++)
{
if (i > 0 && !(i % factor))
{
x1 = margin_left + 1;
x2 = width - margin_right - 1;
y1 = y2 = rh - h_tick * i;
if(i > 0 && !(i % factor))
{
x1 = margin_left + 1;
x2 = width - margin_right - 1;
y1 = y2 = rh - h_tick * i;
 
if (y1 < 12)
break;
if(y1 < 12)
break;
 
paint.drawLine(x1, y1, x2, y2);
paint.drawLine(x1, y1, x2, y2);
 
if (y1 < (oldy - lineHeight))
{
if (meter)
{
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
// left side
if (cuType == 1)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.1f", minSpeed + i));
}
else
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", (Units == 1) ? (minHeight + i) / 0.304 : minHeight + i));
if(y1 < (oldy - lineHeight))
{
if(meter)
{
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
 
// right side
if (maxHr > 0 && cuType != 2)
{
double hrscale = (double)(maxHr - minHr) / (double)target;
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", (int)((double)minHr + hrscale * (double)i)));
}
else
{
double spscale = (maxSpeed - minSpeed) / (double)target;
// left side
if(cuType == 1)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.1f", minSpeed + i));
}
else
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", (Units == 1) ? (minHeight + i) / 0.304 : minHeight + i));
 
if (cuType == 2)
paint.setPen(QPen(red, 1, Qt::SolidLine));
else
paint.setPen(QPen(blue, 1, Qt::SolidLine));
// right side
if(maxHr > 0 && cuType != 2)
{
double hrscale = (double)(maxHr - minHr) / (double)target;
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", (int)((double)minHr + hrscale * (double)i)));
}
else
{
double spscale = (maxSpeed - minSpeed) / (double)target;
 
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.1f", (minSpeed + spscale * (double)i)));
}
}
else
{
// right side
if (cuType == 2)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.1f", minSpeed + i));
}
else
{
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", minHr + i));
}
if(cuType == 2)
paint.setPen(QPen(red, 1, Qt::SolidLine));
else
paint.setPen(QPen(blue, 1, Qt::SolidLine));
 
// left side
if ((cuType == 0 || cuType == 2) && max_height > 0)
{
double hrscale = (maxHeight - minHeight) / (double)target;
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", minHeight + hrscale * (double)i));
}
else if (max_speed > 0 && cuType == 1)
{
double hrscale = (maxSpeed - minSpeed) / (double)target;
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.1f", minSpeed + hrscale * (double)i));
}
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.1f", (minSpeed + spscale * (double)i)));
}
}
else
{
// right side
if(cuType == 2)
{
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.1f", minSpeed + i));
}
else
{
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", minHr + i));
}
 
// left side
if((cuType == 0 || cuType == 2) && max_height > 0)
{
double hrscale = (maxHeight - minHeight) / (double)target;
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.0f", minHeight + hrscale * (double)i));
}
else if(max_speed > 0 && cuType == 1)
{
double hrscale = (maxSpeed - minSpeed) / (double)target;
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawText(12, y1 - lineHeight / 2, margin_left - 14, lineHeight, Qt::AlignRight, qs.sprintf("%.1f", minSpeed + hrscale * (double)i));
}
}
 
paint.setPen(QPen(mark, 1, Qt::SolidLine));
oldy = y1;
}
}
 
paint.setPen(QPen(mark, 1, Qt::SolidLine));
oldy = y1;
}
}
}
 
// To make our graphics more beautiful, we draw lines for the
// heart rate limits and the average heart rate.
if (max_hr > 0 && cuType != 2)
if(max_hr > 0 && cuType != 2)
{
int ay1, ay2, ay3, ay4, ay5;
int ay1, ay2, ay3, ay4, ay5;
 
x1 = margin_left + 1;
x2 = width - margin_right - 1;
x1 = margin_left + 1;
x2 = width - margin_right - 1;
 
if (meter)
{
double hrscale = rh / (double)(maxHr - minHr);
ay1 = (double)rh - (double)(lower1 - minHr) * hrscale;
ay2 = (double)rh - (double)(lower2 - minHr) * hrscale;
ay3 = (double)rh - (double)(lower3 - minHr) * hrscale;
ay4 = (double)rh - (double)(upper3 - minHr) * hrscale;
ay5 = (double)rh - (double)(avg_hr - minHr) * hrscale;
}
else
{
ay1 = (double)rh - (double)(lower1 - minHr) * h_tick;
ay2 = (double)rh - (double)(lower2 - minHr) * h_tick;
ay3 = (double)rh - (double)(lower3 - minHr) * h_tick;
ay4 = (double)rh - (double)(upper3 - minHr) * h_tick;
ay5 = (double)rh - (double)(avg_hr - minHr) * h_tick;
}
if(meter)
{
double hrscale = rh / (double)(maxHr - minHr);
ay1 = (double)rh - (double)(lower1 - minHr) * hrscale;
ay2 = (double)rh - (double)(lower2 - minHr) * hrscale;
ay3 = (double)rh - (double)(lower3 - minHr) * hrscale;
ay4 = (double)rh - (double)(upper3 - minHr) * hrscale;
ay5 = (double)rh - (double)(avg_hr - minHr) * hrscale;
}
else
{
ay1 = (double)rh - (double)(lower1 - minHr) * h_tick;
ay2 = (double)rh - (double)(lower2 - minHr) * h_tick;
ay3 = (double)rh - (double)(lower3 - minHr) * h_tick;
ay4 = (double)rh - (double)(upper3 - minHr) * h_tick;
ay5 = (double)rh - (double)(avg_hr - minHr) * h_tick;
}
 
paint.setPen(QPen(barcol2, 1, Qt::DashLine)); // color for limits
paint.setPen(QPen(barcol2, 1, Qt::DashLine)); // color for limits
 
if (lower1 > minHr && lower1 < maxHr)
paint.drawLine(x1, ay1, x2, ay1);
if(lower1 > minHr && lower1 < maxHr)
paint.drawLine(x1, ay1, x2, ay1);
 
if (lower2 > minHr && lower2 < maxHr)
paint.drawLine(x1, ay2, x2, ay2);
if(lower2 > minHr && lower2 < maxHr)
paint.drawLine(x1, ay2, x2, ay2);
 
if (lower3 > minHr && lower3 < maxHr)
paint.drawLine(x1, ay3, x2, ay3);
if(lower3 > minHr && lower3 < maxHr)
paint.drawLine(x1, ay3, x2, ay3);
 
if (upper3 > minHr && upper3 < maxHr)
paint.drawLine(x1, ay4, x2, ay4);
if(upper3 > minHr && upper3 < maxHr)
paint.drawLine(x1, ay4, x2, ay4);
 
paint.setPen(QPen(red, 1, Qt::DashDotLine)); // color for average heart rate
paint.setPen(QPen(red, 1, Qt::DashDotLine)); // color for average heart rate
 
if (avg_hr > minHr && avg_hr < maxHr)
paint.drawLine(x1, ay5, x2, ay5);
if(avg_hr > minHr && avg_hr < maxHr)
paint.drawLine(x1, ay5, x2, ay5);
}
 
// Now we have a grid and we've done the scaling.
4050,90 → 4180,92
i = 0;
AVGHEIGHT *avgHakt, *avgHfirst, *avgHlast, *avgHeight = 0;
avgHfirst = avgHlast = 0;
 
// To even the surface lines, we store every altitude in the
// memory, by building a chain. Then, if the user has set in the
// settings (Contour == true), we will even the line by calculating
// the average of 10 messure points and setting every value to the
// average, who is up or down more than 2 meters from the average.
while ((point = ds.getPoint(i)) != 0)
while((point = ds.getPoint(i)) != 0)
{
if (point->alt > 20000.0 || point->alt < -1000.0)
{
i++;
continue;
}
if(point->alt > 20000.0 || point->alt < -1000.0)
{
i++;
continue;
}
 
if (!avgHeight)
{
avgHeight = new AVGHEIGHT;
avgHeight->alt = point->alt;
avgHeight->pos = hEc;
avgHeight->prev = 0;
avgHeight->next = 0;
avgHakt = avgHeight;
avgHfirst = avgHeight;
}
else
{
avgHakt = new AVGHEIGHT;
avgHakt->alt = point->alt;
avgHakt->pos = hEc;
avgHakt->next = 0;
avgHakt->prev = avgHeight;
avgHeight->next = avgHakt;
avgHeight = avgHakt;
}
if(!avgHeight)
{
avgHeight = new AVGHEIGHT;
avgHeight->alt = point->alt;
avgHeight->pos = hEc;
avgHeight->prev = 0;
avgHeight->next = 0;
avgHakt = avgHeight;
avgHfirst = avgHeight;
}
else
{
avgHakt = new AVGHEIGHT;
avgHakt->alt = point->alt;
avgHakt->pos = hEc;
avgHakt->next = 0;
avgHakt->prev = avgHeight;
avgHeight->next = avgHakt;
avgHeight = avgHakt;
}
 
// FIXME: Currently we can not draw below 0 meters, because the
// base line is always 0!
if (avgHakt->alt < minHeight)
avgHakt->alt = minHeight;
// FIXME: Currently we can not draw below 0 meters, because the
// base line is always 0!
if(avgHakt->alt < minHeight)
avgHakt->alt = minHeight;
 
hEc++;
i++;
hEc++;
i++;
}
 
avgHlast = avgHeight;
 
// If wanted, even the lines
if (Contour && hEc > 0 && cuType != 0)
if(Contour && hEc > 0 && cuType != 0)
{
double alt[100], avg, avg1, avg2, avg3, avg4;
int a, pos;
double alt[100], avg, avg1, avg2, avg3, avg4;
int a, pos;
 
for (i = 0; i < (hEc + 100); i += 100)
{
avg = avg1 = avg2 = avg3 = avg4 = 0.0;
pos = 0;
for(i = 0; i < (hEc + 100); i += 100)
{
avg = avg1 = avg2 = avg3 = avg4 = 0.0;
pos = 0;
 
for (a = 0; a < 100; a++)
{
alt[a] = getAvgAlt(avgHfirst, i + a);
avg += alt[a];
for(a = 0; a < 100; a++)
{
alt[a] = getAvgAlt(avgHfirst, i + a);
avg += alt[a];
 
if (a < 25)
avg1 += alt[a];
else if (a < 50)
avg2 += alt[a];
else if (a < 75)
avg3 += alt[a];
else
avg4 += alt[a];
}
if(a < 25)
avg1 += alt[a];
else if(a < 50)
avg2 += alt[a];
else if(a < 75)
avg3 += alt[a];
else
avg4 += alt[a];
}
 
if ((i + 100) >= hEc)
avg /= (double)(hEc - i) + 1.0;
else
avg /= 100.0;
if((i + 100) >= hEc)
avg /= (double)(hEc - i) + 1.0;
else
avg /= 100.0;
 
for (a = 0; a < 100; a++)
{
if ((avgHakt = getAvgPtr(avgHfirst, i + a)) != 0)
{
if ((avgHakt->alt - avg) > 2 || (avgHakt->alt - avg) < -2)
avgHakt->alt = avg;
}
}
}
for(a = 0; a < 100; a++)
{
if((avgHakt = getAvgPtr(avgHfirst, i + a)) != 0)
{
if((avgHakt->alt - avg) > 2 || (avgHakt->alt - avg) < -2)
avgHakt->alt = avg;
}
}
}
}
 
// plot the elevation, speed and/or heart rate. Depends on <cuType>)
4144,144 → 4276,144
bool pause = false; // filter pause out of speed
unsigned long t1, t2;
t1 = t2 = 0;
while ((point = ds.getPoint(i)) != 0)
 
while((point = ds.getPoint(i)) != 0)
{
if (!oldPoint)
oldPoint = point;
if(!oldPoint)
oldPoint = point;
 
// calculate the y position based on the time
qt = garmin_dtime(point->time);
secs = zeit.secsTo(qt->time());
delete qt;
x2 = secs * w_tick + margin_left + 1;
hx2 = x2;
sx2 = x2;
// calculate the y position based on the time
qt = garmin_dtime(point->time);
secs = zeit.secsTo(qt->time());
delete qt;
x2 = secs * w_tick + margin_left + 1;
hx2 = x2;
sx2 = x2;
 
if (x1 == 0)
x1 = x2;
if(x1 == 0)
x1 = x2;
 
if (hx1 == 0)
hx1 = hx2;
if(hx1 == 0)
hx1 = hx2;
 
if (sx1 == 0)
sx1 = sx2;
if(sx1 == 0)
sx1 = sx2;
 
// The speed is not very exact, because smallest time is
// one second. This allows a maximum error of 99 hundredths
// of a second, what is very close to one second. Because of
// this, speed seems to hop for every messure point. This
// looks ugly, but currently I don't know how to make it
// better.
if (cuType == 1 || cuType == 2) // Draw speed?
{
double dist;
double sc;
// The speed is not very exact, because smallest time is
// one second. This allows a maximum error of 99 hundredths
// of a second, what is very close to one second. Because of
// this, speed seems to hop for every messure point. This
// looks ugly, but currently I don't know how to make it
// better.
if(cuType == 1 || cuType == 2) // Draw speed?
{
double dist;
double sc;
 
if (!pause && point->distance > 1.0e10)
{
pause = true;
t1 = point->time;
}
else if (pause)
{
pause = false;
t2 = point->time;
i += 2;
continue;
}
if(!pause && point->distance > 1.0e10)
{
pause = true;
t1 = point->time;
}
else if(pause)
{
pause = false;
t2 = point->time;
i += 2;
continue;
}
 
if (point->distance >= 0.1 && point->distance < 1.0e10)
{
dist = point->distance - oldPoint->distance;
sc = point->time - oldPoint->time;
LAP *runde = ds.getLapT (point->time);
if(point->distance >= 0.1 && point->distance < 1.0e10)
{
dist = point->distance - oldPoint->distance;
sc = point->time - oldPoint->time;
LAP *runde = ds.getLapT(point->time);
 
if (t2 > t1)
{
sc -= t2 - t1;
if(t2 > t1)
{
sc -= t2 - t1;
 
if (sc <= 0.0)
sc = 1.0; // at least 1 second!
}
if(sc <= 0.0)
sc = 1.0; // at least 1 second!
}
 
speed = (dist / sc) * 3.6;
speed = (dist / sc) * 3.6;
 
if (runde && runde->max_speed > 0.0 && speed > (runde->max_speed * 3.6))
speed = runde->max_speed * 3.6;
if(runde && runde->max_speed > 0.0 && speed > (runde->max_speed * 3.6))
speed = runde->max_speed * 3.6;
 
if (Units == 1)
speed /= 1.609344;
if(Units == 1)
speed /= 1.609344;
 
if (speed < minSpeed || speed > 400.0)
speed = minSpeed;
if(speed < minSpeed || speed > 400.0)
speed = minSpeed;
 
if ((meter && cuType == 1) || (!meter && cuType == 2))
y2 = (double)rh - (speed - minSpeed) * h_tick;
else
{
double hrscale = rh / (maxSpeed - minSpeed);
y2 = (double)rh - (speed - minSpeed) * hrscale;
}
if((meter && cuType == 1) || (!meter && cuType == 2))
y2 = (double)rh - (speed - minSpeed) * h_tick;
else
{
double hrscale = rh / (maxSpeed - minSpeed);
y2 = (double)rh - (speed - minSpeed) * hrscale;
}
 
if (y1 == 0)
y1 = y2;
if(y1 == 0)
y1 = y2;
 
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawLine(x1, y1, x2, y2);
y1 = y2;
x1 = x2;
t1 = t2 = 0;
oldPoint = point;
}
}
paint.setPen(QPen(red, 1, Qt::SolidLine));
paint.drawLine(x1, y1, x2, y2);
y1 = y2;
x1 = x2;
t1 = t2 = 0;
oldPoint = point;
}
}
 
if (cuType == 0 || cuType == 2) // Draw elevation?
{
if (point->alt < 20000.0 && point->alt > -1000.0)
{
double alt = getAvgAlt(avgHfirst, j);
if(cuType == 0 || cuType == 2) // Draw elevation?
{
if(point->alt < 20000.0 && point->alt > -1000.0)
{
double alt = getAvgAlt(avgHfirst, j);
 
j++;
j++;
 
if (meter)
sy2 = (double)rh - (alt - minHeight) * h_tick;
else
{
double hrscale = rh / (maxHeight - minHeight);
sy2 = (double)rh - (alt - minHeight) * hrscale;
}
if(meter)
sy2 = (double)rh - (alt - minHeight) * h_tick;
else
{
double hrscale = rh / (maxHeight - minHeight);
sy2 = (double)rh - (alt - minHeight) * hrscale;
}
 
if (sy1 == 0)
sy1 = sy2;
if(sy1 == 0)
sy1 = sy2;
 
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
paint.drawLine(sx1, sy1, sx2, sy2);
sy1 = sy2;
sx1 = sx2;
}
}
paint.setPen(QPen(barcol, 1, Qt::SolidLine));
paint.drawLine(sx1, sy1, sx2, sy2);
sy1 = sy2;
sx1 = sx2;
}
}
 
if (point->heart_rate > 0 && cuType < 2) // Draw heart rate?
{
if (meter)
{
double hrscale = rh / (double)(maxHr - minHr);
hy2 = (double)rh - (double)(point->heart_rate - minHr) * hrscale;
}
else
hy2 = (double)rh - (double)(point->heart_rate - minHr) * h_tick;
if(point->heart_rate > 0 && cuType < 2) // Draw heart rate?
{
if(meter)
{
double hrscale = rh / (double)(maxHr - minHr);
hy2 = (double)rh - (double)(point->heart_rate - minHr) * hrscale;
}
else
hy2 = (double)rh - (double)(point->heart_rate - minHr) * h_tick;
 
if (hy1 == 0)
hy1 = hy2;
if(hy1 == 0)
hy1 = hy2;
 
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawLine(hx1, hy1, hx2, hy2);
hy1 = hy2;
hx1 = hx2;
}
paint.setPen(QPen(blue, 1, Qt::SolidLine));
paint.drawLine(hx1, hy1, hx2, hy2);
hy1 = hy2;
hx1 = hx2;
}
 
i++;
i++;
}
 
paint.end();
4290,11 → 4422,11
// free the chain of altitudes
avgHakt = avgHfirst;
 
while (avgHakt)
while(avgHakt)
{
avgHeight = avgHakt->next;
delete avgHakt;
avgHakt = avgHeight;
avgHeight = avgHakt->next;
delete avgHakt;
avgHakt = avgHeight;
}
 
DIRTY = false;
4302,102 → 4434,104
 
void sportwatcherWidget::showThreeCurve(int pw, int ph)
{
QPainter ptHR, ptElevation, ptSpeed;
int width, height, wdHR, htHR, wdElev, htElev, wdSpeed, htSpeed;
int i, secs;
int lineHeight, margin_left, margin_right, margin_bottom;
int x1, y1, x2, y2; // Coordinates
double maxHeight, minHeight, maxSpeed, minSpeed;
int maxHr, minHr, rh, rhHR, rhElev, rhSpeed;
POINT *point;
RUN_NODE *rn;
LAP *lp;
double wtiHR, htiHR, wtiElev, htiElev, wtiSpeed, htiSpeed;
double w_tick, h_tick; // Number of pixels one "tick" has;
// This depends on the width and height
// of the image.
QPainter ptHR, ptElevation, ptSpeed;
int width, height, wdHR, htHR, wdElev, htElev, wdSpeed, htSpeed;
int i, secs;
int lineHeight, margin_left, margin_right, margin_bottom;
int x1, y1, x2, y2; // Coordinates
double maxHeight, minHeight, maxSpeed, minSpeed;
int maxHr, minHr, rh, rhHR, rhElev, rhSpeed;
POINT *point;
RUN_NODE *rn;
LAP *lp;
double wtiHR, htiHR, wtiElev, htiElev, wtiSpeed, htiSpeed;
double w_tick, h_tick; // Number of pixels one "tick" has;
 
// This depends on the width and height
// of the image.
// First we draw a grid based on the min and max
// values detected in the function showLap(). In case
// all values are 0, we exit here.
if (min_hr == 0 && max_hr == 0 && min_height == 0.0 && max_height == 0.0)
return;
if(min_hr == 0 && max_hr == 0 && min_height == 0.0 && max_height == 0.0)
return;
 
if (!ActivePrint && (!DIRTY || curTab != 2))
return;
if(!ActivePrint && (!DIRTY || curTab != 2))
return;
 
w_tick = h_tick = 0.0;
rh = 0;
width = height = 0;
 
// Get the dimensions of the available draw area
// First for heart rate
if (!ActivePrint)
if(!ActivePrint)
{
wdHR = ui_sportwatcherWidgetBase.grHR->width() - 2;
htHR = ui_sportwatcherWidgetBase.grHR->height();
pmHR = QPixmap(wdHR, htHR);
// Then for elevation
wdElev = ui_sportwatcherWidgetBase.grElevation->width() - 2;
htElev = ui_sportwatcherWidgetBase.grElevation->height();
pmElevation = QPixmap(wdElev, htElev);
// And at last for speed
wdSpeed = ui_sportwatcherWidgetBase.grSpeed->width() - 2;
htSpeed = ui_sportwatcherWidgetBase.grSpeed->height();
pmSpeed = QPixmap(wdSpeed, htSpeed);
// Initialize QPainter
ptHR.begin(&pmHR);
ptElevation.begin(&pmElevation);
ptSpeed.begin(&pmSpeed);
wdHR = ui_sportwatcherWidgetBase.grHR->width() - 2;
htHR = ui_sportwatcherWidgetBase.grHR->height();
pmHR = QPixmap(wdHR, htHR);
// Then for elevation
wdElev = ui_sportwatcherWidgetBase.grElevation->width() - 2;
htElev = ui_sportwatcherWidgetBase.grElevation->height();
pmElevation = QPixmap(wdElev, htElev);
// And at last for speed
wdSpeed = ui_sportwatcherWidgetBase.grSpeed->width() - 2;
htSpeed = ui_sportwatcherWidgetBase.grSpeed->height();
pmSpeed = QPixmap(wdSpeed, htSpeed);
// Initialize QPainter
ptHR.begin(&pmHR);
ptElevation.begin(&pmElevation);
ptSpeed.begin(&pmSpeed);
}
else if (ActivePrint && pw > 0 && ph > 0)
else if(ActivePrint && pw > 0 && ph > 0)
{
wdHR = wdElev = wdSpeed = pw;
htHR = htElev = htSpeed = ph;
prHR = prElevation = prSpeed = QPixmap(pw, ph);
ptHR.begin(&prHR);
ptElevation.begin(&prElevation);
ptSpeed.begin(&prSpeed);
wdHR = wdElev = wdSpeed = pw;
htHR = htElev = htSpeed = ph;
prHR = prElevation = prSpeed = QPixmap(pw, ph);
ptHR.begin(&prHR);
ptElevation.begin(&prElevation);
ptSpeed.begin(&prSpeed);
}
else
return;
return;
 
// we need a somewhat bigger area to draw our curves than
// we have with the real min and max values.
if (max_height > 0.0)
if(max_height > 0.0)
{
double add = (max_height - min_height) / 100.0 * 5.0; // Percent
double add = (max_height - min_height) / 100.0 * 5.0; // Percent
 
maxHeight = max_height + add;
minHeight = min_height - add;
maxHeight = max_height + add;
minHeight = min_height - add;
 
if (minHeight < 0.0) // make sure, we are not too deep
minHeight = 0.0;
if(minHeight < 0.0) // make sure, we are not too deep
minHeight = 0.0;
}
else
maxHeight = minHeight = 0.0;
maxHeight = minHeight = 0.0;
 
if (max_speed > 0.0)
if(max_speed > 0.0)
{
double add = (max_speed - min_speed) / 100.0 * 5.0; // Percent
double add = (max_speed - min_speed) / 100.0 * 5.0; // Percent
 
maxSpeed = max_speed + add;
minSpeed = min_speed - add;
maxSpeed = max_speed + add;
minSpeed = min_speed - add;
 
if (minSpeed < 0.0) // make sure, we are not too deep
minSpeed = 0.0;
if(minSpeed < 0.0) // make sure, we are not too deep
minSpeed = 0.0;
}
else
maxSpeed = minSpeed = 0.0;
maxSpeed = minSpeed = 0.0;
 
if (max_hr > 0)
if(max_hr > 0)
{
maxHr = max_hr + 10;
minHr = min_hr - 10;
maxHr = max_hr + 10;
minHr = min_hr - 10;
 
if (minHr < 0)
minHr = 0;
if(minHr < 0)
minHr = 0;
}
else
maxHr = minHr = 0;
maxHr = minHr = 0;
 
// Define colors
QColor background(220, 220, 220); // Background of graphic
4423,26 → 4557,26
// rh = height - margin_bottom - 1;
 
// Calculate the ticks for width and height for every draw area
for (i = 0; i < 3; i++)
for(i = 0; i < 3; i++)
{
if (i == 2) // Speed?
{
rhSpeed = htSpeed - margin_bottom - 1;
wtiSpeed = (double)(wdSpeed - (margin_left + margin_right)) / (max_time + ds.getPauseTime()); // 1 tick = 1 second
htiSpeed = (double)rhSpeed / (maxSpeed - minSpeed); // 1 tick = 1 km/h
}
else if (i == 1) // Elevation?
{
rhElev = htElev - margin_bottom - 1;
wtiElev = (double)(wdElev - (margin_left + margin_right)) / (max_time + ds.getPauseTime()); // 1 tick = 1 second
htiElev = (double)rhElev / (maxHeight - minHeight); // 1 tick = 1 meter
}
else // heart rate
{
rhHR = htHR - margin_bottom - 1;
wtiHR = (double)(wdHR - (margin_left + margin_right)) / (max_time + ds.getPauseTime()); // 1 tick = 1 second
htiHR = (double)rhHR / ((double)maxHr - (double)minHr); // 1 tick = 1 bpm
}
if(i == 2) // Speed?
{
rhSpeed = htSpeed - margin_bottom - 1;
wtiSpeed = (double)(wdSpeed - (margin_left + margin_right)) / (max_time + ds.getPauseTime()); // 1 tick = 1 second
htiSpeed = (double)rhSpeed / (maxSpeed - minSpeed); // 1 tick = 1 km/h
}
else if(i == 1) // Elevation?
{
rhElev = htElev - margin_bottom - 1;
wtiElev = (double)(wdElev - (margin_left + margin_right)) / (max_time + ds.getPauseTime()); // 1 tick = 1 second
htiElev = (double)rhElev / (maxHeight - minHeight); // 1 tick = 1 meter
}
else // heart rate
{
rhHR = htHR - margin_bottom - 1;
wtiHR = (double)(wdHR - (margin_left + margin_right)) / (max_time + ds.getPauseTime()); // 1 tick = 1 second
htiHR = (double)rhHR / ((double)maxHr - (double)minHr); // 1 tick = 1 bpm
}
}
 
// Fill background with background colors
4476,13 → 4610,13
y1 = 2;
y2 = htHR - margin_bottom;
ptHR.drawLine(x1, y1, x2, y2);
 
y2 = htElev - margin_bottom;
ptElevation.drawLine(x1, y1, x2, y2);
 
y2 = htSpeed - margin_bottom;
ptSpeed.drawLine(x1, y1, x2, y2);
 
// right border line
x1 = x2 = wdHR - margin_right;
ptHR.drawLine(x1, y1, x2, y2);
4501,23 → 4635,23
ptElevation.setPen(QPen(hlight, 1, Qt::SolidLine));
ptSpeed.setPen(QPen(hlight, 1, Qt::SolidLine));
 
for (i = rn->run->first_lap_index; (unsigned int)i <= rn->run->last_lap_index; i++)
for(i = rn->run->first_lap_index; (unsigned int)i <= rn->run->last_lap_index; i++)
{
if ((lp = ds.getLap(i)) == NULL)
continue;
if((lp = ds.getLap(i)) == NULL)
continue;
 
qt = garmin_dtime(lp->start_time);
secs = zeit.secsTo(qt->time());
delete qt;
// heart rate
x1 = secs * wtiHR + margin_left + 1;
ptHR.drawLine(x1, 2, x1, htHR - margin_bottom);
// Elevation
x1 = secs * wtiElev + margin_left + 1;
ptElevation.drawLine(x1, 2, x1, htElev - margin_bottom);
// Speed
x1 = secs * wtiSpeed + margin_left + 1;
ptSpeed.drawLine(x1, 2, x1, htSpeed - margin_bottom);
qt = garmin_dtime(lp->start_time);
secs = zeit.secsTo(qt->time());
delete qt;
// heart rate
x1 = secs * wtiHR + margin_left + 1;
ptHR.drawLine(x1, 2, x1, htHR - margin_bottom);
// Elevation
x1 = secs * wtiElev + margin_left + 1;
ptElevation.drawLine(x1, 2, x1, htElev - margin_bottom);
// Speed
x1 = secs * wtiSpeed + margin_left + 1;
ptSpeed.drawLine(x1, 2, x1, htSpeed - margin_bottom);
}
 
// Grid vertical
4524,15 → 4658,15
ptHR.setPen(QPen(frame, 1, Qt::SolidLine));
ptHR.setFont(fntNormal);
ptHR.drawText(margin_left, htHR - lineHeight, 40, lineHeight, Qt::AlignLeft, QString("0"));
 
ptElevation.setPen(QPen(frame, 1, Qt::SolidLine));
ptElevation.setFont(fntNormal);
ptElevation.drawText(margin_left, htElev - lineHeight, 40, lineHeight, Qt::AlignLeft, QString("0"));
 
ptSpeed.setPen(QPen(frame, 1, Qt::SolidLine));
ptSpeed.setFont(fntNormal);
ptSpeed.drawText(margin_left, htSpeed - lineHeight, 40, lineHeight, Qt::AlignLeft, QString("0"));
 
ptHR.save();
ptHR.rotate(270);
ptHR.setPen(QPen(blue, 1, Qt::SolidLine));
4540,7 → 4674,7
ptElevation.save();
ptElevation.rotate(270);
ptElevation.setPen(QPen(barcol, 1, Qt::SolidLine));
 
ptSpeed.save();
ptSpeed.rotate(270);
ptSpeed.setPen(QPen(red, 1, Qt::SolidLine));
4559,64 → 4693,65
 
ptSpeed.restore();
ptSpeed.setPen(QPen(mark, 1, Qt::SolidLine));
 
// Draw the time scale on the bottom of the graphic
for (i = 0; (unsigned int)i < (max_time + ds.getPauseTime()); i++)
for(i = 0; (unsigned int)i < (max_time + ds.getPauseTime()); i++)
{
bool loop = false;
bool loop = false;
 
if (i > 0 && !(i % 600)) // every 10 minutes
{
for (int j = 0; j < 3; j++)
{
switch (j)
{
case 0: w_tick = wtiHR; width = wdHR; height = htHR; break;
case 1: w_tick = wtiElev; width = wdElev; height = htElev; break;
case 2: w_tick = wtiSpeed; width = wdSpeed; height = htSpeed; break;
}
if(i > 0 && !(i % 600)) // every 10 minutes
{
for(int j = 0; j < 3; j++)
{
switch(j)
{
case 0: w_tick = wtiHR; width = wdHR; height = htHR; break;
case 1: w_tick = wtiElev; width = wdElev; height = htElev; break;
case 2: w_tick = wtiSpeed; width = wdSpeed; height = htSpeed; break;
}
 
x1 = x2 = margin_left + w_tick * i;
x1 = x2 = margin_left + w_tick * i;
 
if (x1 == (width - margin_right - 25))
{
loop = true;
break;
}
if(x1 == (width - margin_right - 25))
{
loop = true;
break;
}
 
y1 = 2;
y2 = height - margin_bottom;
QTime tm(0, 0, 0);
tm = tm.addSecs(i);
y1 = 2;
y2 = height - margin_bottom;
QTime tm(0, 0, 0);
tm = tm.addSecs(i);
 
if (j == 0)
{
ptHR.drawLine(x1, y1, x2, y2);
ptHR.setPen(QPen(frame, 1, Qt::SolidLine));
ptHR.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime (tm, (i >= 3600) ? true : false));
ptHR.setPen(QPen(mark, 1, Qt::SolidLine));
}
else if (j == 1)
{
ptElevation.drawLine(x1, y1, x2, y2);
ptElevation.setPen(QPen(frame, 1, Qt::SolidLine));
ptElevation.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime (tm, (i >= 3600) ? true : false));
ptElevation.setPen(QPen(mark, 1, Qt::SolidLine));
}
else
{
ptSpeed.drawLine(x1, y1, x2, y2);
ptSpeed.setPen(QPen(frame, 1, Qt::SolidLine));
ptSpeed.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime (tm, (i >= 3600) ? true : false));
ptSpeed.setPen(QPen(mark, 1, Qt::SolidLine));
}
}
if(j == 0)
{
ptHR.drawLine(x1, y1, x2, y2);
ptHR.setPen(QPen(frame, 1, Qt::SolidLine));
ptHR.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime(tm, (i >= 3600) ? true : false));
ptHR.setPen(QPen(mark, 1, Qt::SolidLine));
}
else if(j == 1)
{
ptElevation.drawLine(x1, y1, x2, y2);
ptElevation.setPen(QPen(frame, 1, Qt::SolidLine));
ptElevation.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime(tm, (i >= 3600) ? true : false));
ptElevation.setPen(QPen(mark, 1, Qt::SolidLine));
}
else
{
ptSpeed.drawLine(x1, y1, x2, y2);
ptSpeed.setPen(QPen(frame, 1, Qt::SolidLine));
ptSpeed.drawText(x1 - 25, height - lineHeight, 50, lineHeight, Qt::AlignCenter, kl->formatTime(tm, (i >= 3600) ? true : false));
ptSpeed.setPen(QPen(mark, 1, Qt::SolidLine));
}
}
 
if (loop)
{
loop = false;
continue;
}
}
if(loop)
{
loop = false;
continue;
}
}
}
 
// This is the total time, with pauses included, at the lower right
4652,107 → 4787,107
int factor = 0;
int target = 0;
 
for (int j = 0; j < 3; j++)
for(int j = 0; j < 3; j++)
{
switch (j)
{
case 0: width = wdHR; height = htHR; w_tick = wtiHR; h_tick = htiHR; rh = rhHR;
factor = (maxHr - minHr) / (rhHR / 12);
target = (maxHr - minHr);
break;
switch(j)
{
case 0: width = wdHR; height = htHR; w_tick = wtiHR; h_tick = htiHR; rh = rhHR;
factor = (maxHr - minHr) / (rhHR / 12);
target = (maxHr - minHr);
break;
 
case 1: width = wdElev; height = htElev; w_tick = wtiElev; h_tick = htiElev; rh = rhElev;
factor = (maxHeight - minHeight) / (rhElev / 12);
target = (int)(maxHeight - minHeight);
break;
case 1: width = wdElev; height = htElev; w_tick = wtiElev; h_tick = htiElev; rh = rhElev;
factor = (maxHeight - minHeight) / (rhElev / 12);
target = (int)(maxHeight - minHeight);
break;
 
case 2: width = wdSpeed; height = htSpeed; w_tick = wtiSpeed; h_tick = htiSpeed; rh = rhSpeed;
factor = (maxSpeed - minSpeed) / (rhSpeed / 12);
target = (int)(maxSpeed - minSpeed);
break;
}
case 2: width = wdSpeed; height = htSpeed; w_tick = wtiSpeed; h_tick = htiSpeed; rh = rhSpeed;
factor = (maxSpeed - minSpeed) / (rhSpeed / 12);
target = (int)(maxSpeed - minSpeed);
break;
}
 
// To prevent a division by zero error, we check the <factor>
if (factor == 0)
factor = 1;
// To prevent a division by zero error, we check the <factor>
if(factor == 0)
factor = 1;
 
// Beside the horizontal part of the grid, we draw the scale on the
// the right side too.
int oldy = height;
// Beside the horizontal part of the grid, we draw the scale on the
// the right side too.
int oldy = height;
 
for (i = 0; i < target; i++)
{
if (i > 0 && !(i % factor))
{
x1 = margin_left + 1;
x2 = width - margin_right - 1;
y1 = y2 = rh - h_tick * i;
for(i = 0; i < target; i++)
{
if(i > 0 && !(i % factor))
{
x1 = margin_left + 1;
x2 = width - margin_right - 1;
y1 = y2 = rh - h_tick * i;
 
if (y1 < 12)
break;
if(y1 < 12)
break;
 
switch (j)
{
case 0:
ptHR.drawLine(x1, y1, x2, y2);
ptHR.setPen(QPen(blue, 1, Qt::SolidLine));
ptHR.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", minHr + i));
ptHR.setPen(QPen(mark, 1, Qt::SolidLine));
break;
switch(j)
{
case 0:
ptHR.drawLine(x1, y1, x2, y2);
ptHR.setPen(QPen(blue, 1, Qt::SolidLine));
ptHR.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%d", minHr + i));
ptHR.setPen(QPen(mark, 1, Qt::SolidLine));
break;
 
case 1:
ptElevation.drawLine(x1, y1, x2, y2);
ptElevation.setPen(QPen(barcol, 1, Qt::SolidLine));
ptElevation.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.0f", (Units == 1) ? (minHeight + i) / 0.304 : minHeight + i));
ptElevation.setPen(QPen(mark, 1, Qt::SolidLine));
break;
case 1:
ptElevation.drawLine(x1, y1, x2, y2);
ptElevation.setPen(QPen(barcol, 1, Qt::SolidLine));
ptElevation.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.0f", (Units == 1) ? (minHeight + i) / 0.304 : minHeight + i));
ptElevation.setPen(QPen(mark, 1, Qt::SolidLine));
break;
 
case 2:
ptSpeed.drawLine(x1, y1, x2, y2);
ptSpeed.setPen(QPen(red, 1, Qt::SolidLine));
ptSpeed.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.1f", minSpeed + i));
ptSpeed.setPen(QPen(mark, 1, Qt::SolidLine));
break;
}
case 2:
ptSpeed.drawLine(x1, y1, x2, y2);
ptSpeed.setPen(QPen(red, 1, Qt::SolidLine));
ptSpeed.drawText(width - margin_right + 2, y1 - lineHeight / 2, margin_right - 14, lineHeight, Qt::AlignLeft, qs.sprintf("%.1f", minSpeed + i));
ptSpeed.setPen(QPen(mark, 1, Qt::SolidLine));
break;
}
 
oldy = y1;
}
}
oldy = y1;
}
}
}
 
// To make our graphics more beautiful, we draw lines for the
// heart rate limits and the average heart rate.
if (max_hr > 0)
if(max_hr > 0)
{
int ay1, ay2, ay3, ay4, ay5;
int ay1, ay2, ay3, ay4, ay5;
 
x1 = margin_left + 1;
x2 = wdHR - margin_right - 1;
x1 = margin_left + 1;
x2 = wdHR - margin_right - 1;
 
ay1 = (double)rh - (double)(lower1 - minHr) * htiHR;
ay2 = (double)rh - (double)(lower2 - minHr) * htiHR;
ay3 = (double)rh - (double)(lower3 - minHr) * htiHR;
ay4 = (double)rh - (double)(upper3 - minHr) * htiHR;
ay5 = (double)rh - (double)(avg_hr - minHr) * htiHR;
ay1 = (double)rh - (double)(lower1 - minHr) * htiHR;
ay2 = (double)rh - (double)(lower2 - minHr) * htiHR;
ay3 = (double)rh - (double)(lower3 - minHr) * htiHR;
ay4 = (double)rh - (double)(upper3 - minHr) * htiHR;
ay5 = (double)rh - (double)(avg_hr - minHr) * htiHR;
 
ptHR.setPen(QPen(barcol2, 1, Qt::DashLine)); // color for limits
ptHR.setPen(QPen(barcol2, 1, Qt::DashLine)); // color for limits
 
if (lower1 > minHr && lower1 < maxHr)
ptHR.drawLine(x1, ay1, x2, ay1);
if(lower1 > minHr && lower1 < maxHr)
ptHR.drawLine(x1, ay1, x2, ay1);
 
if (lower2 > minHr && lower2 < maxHr)
ptHR.drawLine(x1, ay2, x2, ay2);
if(lower2 > minHr && lower2 < maxHr)
ptHR.drawLine(x1, ay2, x2, ay2);
 
if (lower3 > minHr && lower3 < maxHr)
ptHR.drawLine(x1, ay3, x2, ay3);
if(lower3 > minHr && lower3 < maxHr)
ptHR.drawLine(x1, ay3, x2, ay3);
 
if (upper3 > minHr && upper3 < maxHr)
ptHR.drawLine(x1, ay4, x2, ay4);
if(upper3 > minHr && upper3 < maxHr)
ptHR.drawLine(x1, ay4, x2, ay4);
 
ptHR.setPen(QPen(red, 1, Qt::DashDotLine)); // color for average heart rate
ptHR.setPen(QPen(red, 1, Qt::DashDotLine)); // color for average heart rate
 
if (avg_hr > minHr && avg_hr < maxHr)
ptHR.drawLine(x1, ay5, x2, ay5);
if(avg_hr > minHr && avg_hr < maxHr)
ptHR.drawLine(x1, ay5, x2, ay5);
}
 
// Now we have a grid and we've done the scaling.
4772,90 → 4907,92
i = 0;
AVGHEIGHT *avgHakt, *avgHfirst, *avgHlast, *avgHeight = 0;
avgHfirst = avgHlast = 0;
 
// To even the surface lines, we store every altitude in the
// memory, by building a chain. Then, if the user has set in the
// settings (Contour == true), we will even the line by calculating
// the average of 10 messure points and setting every value to the
// average, who is up or down more than 2 meters from the average.
while ((point = ds.getPoint(i)) != 0)
while((point = ds.getPoint(i)) != 0)
{
if (point->alt > 20000.0 || point->alt < -1000.0)
{
i++;
continue;
}
if(point->alt > 20000.0 || point->alt < -1000.0)
{
i++;
continue;
}
 
if (!avgHeight)
{
avgHeight = new AVGHEIGHT;
avgHeight->alt = point->alt;
avgHeight->pos = hEc;
avgHeight->prev = 0;
avgHeight->next = 0;
avgHakt = avgHeight;
avgHfirst = avgHeight;
}
else
{
avgHakt = new AVGHEIGHT;
avgHakt->alt = point->alt;
avgHakt->pos = hEc;
avgHakt->next = 0;
avgHakt->prev = avgHeight;
avgHeight->next = avgHakt;
avgHeight = avgHakt;
}
if(!avgHeight)
{
avgHeight = new AVGHEIGHT;
avgHeight->alt = point->alt;
avgHeight->pos = hEc;
avgHeight->prev = 0;
avgHeight->next = 0;
avgHakt = avgHeight;
avgHfirst = avgHeight;
}
else
{
avgHakt = new AVGHEIGHT;
avgHakt->alt = point->alt;
avgHakt->pos = hEc;
avgHakt->next = 0;
avgHakt->prev = avgHeight;
avgHeight->next = avgHakt;
avgHeight = avgHakt;
}
 
// FIXME: Currently we can not draw below 0 meters, because the
// base line is always 0!
if (avgHakt->alt < minHeight)
avgHakt->alt = minHeight;
// FIXME: Currently we can not draw below 0 meters, because the
// base line is always 0!
if(avgHakt->alt < minHeight)
avgHakt->alt = minHeight;
 
hEc++;
i++;
hEc++;
i++;
}
 
avgHlast = avgHeight;
 
// If wanted, even the lines
if (Contour && hEc > 0)
if(Contour && hEc > 0)
{
double alt[100], avg, avg1, avg2, avg3, avg4;
int a, pos;
double alt[100], avg, avg1, avg2, avg3, avg4;
int a, pos;
 
for (i = 0; i < (hEc + 100); i += 100)
{
avg = avg1 = avg2 = avg3 = avg4 = 0.0;
pos = 0;
for(i = 0; i < (hEc + 100); i += 100)
{
avg = avg1 = avg2 = avg3 = avg4 = 0.0;
pos = 0;
 
for (a = 0; a < 100; a++)
{
alt[a] = getAvgAlt(avgHfirst, i + a);
avg += alt[a];
for(a = 0; a < 100; a++)
{
alt[a] = getAvgAlt(avgHfirst, i + a);
avg += alt[a];
 
if (a < 25)
avg1 += alt[a];
else if (a < 50)
avg2 += alt[a];
else if (a < 75)
avg3 += alt[a];
else
avg4 += alt[a];
}
if(a < 25)
avg1 += alt[a];
else if(a < 50)
avg2 += alt[a];
else if(a < 75)
avg3 += alt[a];
else
avg4 += alt[a];
}
 
if ((i + 100) >= hEc)
avg /= (double)(hEc - i) + 1.0;
else
avg /= 100.0;
if((i + 100) >= hEc)
avg /= (double)(hEc - i) + 1.0;
else
avg /= 100.0;
 
for (a = 0; a < 100; a++)
{
if ((avgHakt = getAvgPtr(avgHfirst, i + a)) != 0)
{
if ((avgHakt->alt - avg) > 2 || (avgHakt->alt - avg) < -2)
avgHakt->alt = avg;
}
}
}
for(a = 0; a < 100; a++)
{
if((avgHakt = getAvgPtr(avgHfirst, i + a)) != 0)
{
if((avgHakt->alt - avg) > 2 || (avgHakt->alt - avg) < -2)
avgHakt->alt = avg;
}
}
}
}
 
// plot the elevation, speed and/or heart rate. Depends on <cuType>)
4866,170 → 5003,171
bool pause = false; // filter pause out of speed
unsigned long t1, t2;
t1 = t2 = 0;
while ((point = ds.getPoint(i)) != 0)
 
while((point = ds.getPoint(i)) != 0)
{
bool loop = false;
bool loop = false;
 
if (!oldPoint)
oldPoint = point;
if(!oldPoint)
oldPoint = point;
 
// calculate the y position based on the time
qt = garmin_dtime(point->time);
secs = zeit.secsTo(qt->time());
delete qt;
// calculate the y position based on the time
qt = garmin_dtime(point->time);
secs = zeit.secsTo(qt->time());
delete qt;
 
for (int c = 0; c < 3; c++)
{
if (c == 0)
{
x2 = secs * wtiHR + margin_left + 1;
hx2 = x2;
sx2 = x2;
for(int c = 0; c < 3; c++)
{
if(c == 0)
{
x2 = secs * wtiHR + margin_left + 1;
hx2 = x2;
sx2 = x2;
 
if (x1 == 0)
x1 = x2;
if(x1 == 0)
x1 = x2;
 
if (hx1 == 0)
hx1 = hx2;
if(hx1 == 0)
hx1 = hx2;
 
if (sx1 == 0)
sx1 = sx2;
}
else if (c == 1)
{
x2 = secs * wtiElev + margin_left + 1;
hx2 = x2;
sx2 = x2;
if(sx1 == 0)
sx1 = sx2;
}
else if(c == 1)
{
x2 = secs * wtiElev + margin_left + 1;
hx2 = x2;
sx2 = x2;
 
if (x1 == 0)
x1 = x2;
if(x1 == 0)
x1 = x2;
 
if (hx1 == 0)
hx1 = hx2;
if(hx1 == 0)
hx1 = hx2;
 
if (sx1 == 0)
sx1 = sx2;
}
else
{
x2 = secs * wtiSpeed + margin_left + 1;
hx2 = x2;
sx2 = x2;
if(sx1 == 0)
sx1 = sx2;
}
else
{
x2 = secs * wtiSpeed + margin_left + 1;
hx2 = x2;
sx2 = x2;
 
if (x1 == 0)
x1 = x2;
if(x1 == 0)
x1 = x2;
 
if (hx1 == 0)
hx1 = hx2;
if(hx1 == 0)
hx1 = hx2;
 
if (sx1 == 0)
sx1 = sx2;
}
// The speed is not very exact, because smallest time is
// one second. This allows a maximum error of 99 hundredths
// of a second, what is very close to one second. Because of
// this, speed seems to hop for every messure point. This
// looks ugly, but currently I don't know how to make it
// better.
if (c == 2) // Draw speed?
{
double dist;
double sc;
if(sx1 == 0)
sx1 = sx2;
}
 
if (!pause && point->distance > 1.0e10)
{
pause = true;
t1 = point->time;
}
else if (pause)
{
pause = false;
t2 = point->time;
i += 2;
loop = true;
}
// The speed is not very exact, because smallest time is
// one second. This allows a maximum error of 99 hundredths
// of a second, what is very close to one second. Because of
// this, speed seems to hop for every messure point. This
// looks ugly, but currently I don't know how to make it
// better.
if(c == 2) // Draw speed?
{
double dist;
double sc;
 
if (point->distance >= 0.1 && point->distance < 1.0e10)
{
dist = point->distance - oldPoint->distance;
sc = point->time - oldPoint->time;
LAP *runde = ds.getLapT (point->time);
if(!pause && point->distance > 1.0e10)
{
pause = true;
t1 = point->time;
}
else if(pause)
{
pause = false;
t2 = point->time;
i += 2;
loop = true;
}
 
if (t2 > t1)
{
sc -= t2 - t1;
if(point->distance >= 0.1 && point->distance < 1.0e10)
{
dist = point->distance - oldPoint->distance;
sc = point->time - oldPoint->time;
LAP *runde = ds.getLapT(point->time);
 
if (sc <= 0.0)
sc = 1.0; // at least 1 second!
}
if(t2 > t1)
{
sc -= t2 - t1;
 
speed = (dist / sc) * 3.6;
if(sc <= 0.0)
sc = 1.0; // at least 1 second!
}
 
if (runde && runde->max_speed > 0.0 && speed > (runde->max_speed * 3.6))
speed = runde->max_speed * 3.6;
speed = (dist / sc) * 3.6;
 
if (Units == 1)
speed /= 1.609344;
if(runde && runde->max_speed > 0.0 && speed > (runde->max_speed * 3.6))
speed = runde->max_speed * 3.6;
 
if (speed < minSpeed || speed > 400.0)
speed = minSpeed;
if(Units == 1)
speed /= 1.609344;
 
y2 = (double)rh - (speed - minSpeed) * htiSpeed;
if(speed < minSpeed || speed > 400.0)
speed = minSpeed;
 
if (y1 == 0)
y1 = y2;
y2 = (double)rh - (speed - minSpeed) * htiSpeed;
 
ptSpeed.setPen(QPen(red, 1, Qt::SolidLine));
ptSpeed.drawLine(x1, y1, x2, y2);
y1 = y2;
x1 = x2;
t1 = t2 = 0;
oldPoint = point;
}
}
if(y1 == 0)
y1 = y2;
 
if (c == 1) // Draw elevation?
{
if (point->alt < 20000.0 && point->alt > -1000.0)
{
double alt = getAvgAlt(avgHfirst, j);
ptSpeed.setPen(QPen(red, 1, Qt::SolidLine));
ptSpeed.drawLine(x1, y1, x2, y2);
y1 = y2;
x1 = x2;
t1 = t2 = 0;
oldPoint = point;
}
}
 
j++;
if(c == 1) // Draw elevation?
{
if(point->alt < 20000.0 && point->alt > -1000.0)
{
double alt = getAvgAlt(avgHfirst, j);
 
sy2 = (double)rh - (alt - minHeight) * htiElev;
j++;
 
if (sy1 == 0)
sy1 = sy2;
sy2 = (double)rh - (alt - minHeight) * htiElev;
 
ptElevation.setPen(QPen(barcol, 1, Qt::SolidLine));
ptElevation.drawLine(sx1, sy1, sx2, sy2);
sy1 = sy2;
sx1 = sx2;
}
}
if(sy1 == 0)
sy1 = sy2;
 
if (point->heart_rate > 0 && c == 0) // Draw heart rate?
{
hy2 = (double)rh - (double)(point->heart_rate - minHr) * htiHR;
ptElevation.setPen(QPen(barcol, 1, Qt::SolidLine));
ptElevation.drawLine(sx1, sy1, sx2, sy2);
sy1 = sy2;
sx1 = sx2;
}
}
 
if (hy1 == 0)
hy1 = hy2;
if(point->heart_rate > 0 && c == 0) // Draw heart rate?
{
hy2 = (double)rh - (double)(point->heart_rate - minHr) * htiHR;
 
ptHR.setPen(QPen(blue, 1, Qt::SolidLine));
ptHR.drawLine(hx1, hy1, hx2, hy2);
hy1 = hy2;
hx1 = hx2;
}
}
if(hy1 == 0)
hy1 = hy2;
 
if (loop)
{
loop = false;
continue;
}
ptHR.setPen(QPen(blue, 1, Qt::SolidLine));
ptHR.drawLine(hx1, hy1, hx2, hy2);
hy1 = hy2;
hx1 = hx2;
}
}
 
i++;
if(loop)
{
loop = false;
continue;
}
 
i++;
}
 
ptHR.end();
5036,20 → 5174,21
ptElevation.end();
ptSpeed.end();
 
if (!ActivePrint)
if(!ActivePrint)
{
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
}
 
// free the chain of altitudes
avgHakt = avgHfirst;
 
while (avgHakt)
while(avgHakt)
{
avgHeight = avgHakt->next;
delete avgHakt;
avgHakt = avgHeight;
avgHeight = avgHakt->next;
delete avgHakt;
avgHakt = avgHeight;
}
 
DIRTY = false;
5057,19 → 5196,19
 
double sportwatcherWidget::getAvgAlt(AVGHEIGHT *avgHeight, int pos)
{
AVGHEIGHT *akt;
AVGHEIGHT *akt;
 
if (!avgHeight)
return 0.0;
if(!avgHeight)
return 0.0;
 
akt = avgHeight;
 
while (akt)
while(akt)
{
if (akt->pos == pos)
return akt->alt;
if(akt->pos == pos)
return akt->alt;
 
akt = akt->next;
akt = akt->next;
}
 
return 0.0;
5077,16 → 5216,16
 
AVGHEIGHT *sportwatcherWidget::getAvgPtr(AVGHEIGHT *avgHeight, int pos)
{
AVGHEIGHT *akt;
AVGHEIGHT *akt;
 
akt = avgHeight;
 
while (akt)
while(akt)
{
if (akt->pos == pos)
return akt;
if(akt->pos == pos)
return akt;
 
akt = akt->next;
akt = akt->next;
}
 
return 0;
5094,125 → 5233,125
 
void sportwatcherWidget::resizeEvent(QResizeEvent *e)
{
if (e->size() != e->oldSize())
DIRTY=true;
if(e->size() != e->oldSize())
DIRTY = true;
 
showTrack(zfactor);
showCurves();
tabDirt2 = true;
 
if (curTab == 2)
if(curTab == 2)
{
showThreeCurve();
tabDirt2 = false;
showThreeCurve();
tabDirt2 = false;
}
 
DIRTY=false;
DIRTY = false;
}
 
void sportwatcherWidget::mouseMoveEvent(QMouseEvent *e)
{
QPoint pos(0, 0);
QPoint ev = ui_sportwatcherWidgetBase.imgMap->mapFrom(this, e->pos());
static QRect coord;
QPoint pos(0, 0);
QPoint ev = ui_sportwatcherWidgetBase.imgMap->mapFrom(this, e->pos());
static QRect coord;
 
DIRTY=true;
DIRTY = true;
 
if (curTab == 0)
if(curTab == 0)
{
if (!stateHand)
return;
if(!stateHand)
return;
 
if (ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.imgMap->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.imgMap->geometry().height()))
{
if (lmbPressed == 1)
{
coord.setCoords(ev.x(), ev.y(), 0, 0);
lmbPressed = 0;
}
else
{
coord.setRight(ev.x());
coord.setBottom(ev.y());
}
if(ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.imgMap->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.imgMap->geometry().height()))
{
if(lmbPressed == 1)
{
coord.setCoords(ev.x(), ev.y(), 0, 0);
lmbPressed = 0;
}
else
{
coord.setRight(ev.x());
coord.setBottom(ev.y());
}
 
if (lmbPressed == 2)
{
showTrack(zfactor, coord, mapLap);
lmbPressed = 0;
}
}
if(lmbPressed == 2)
{
showTrack(zfactor, coord, mapLap);
lmbPressed = 0;
}
}
}
 
if (curTab == 2)
if(curTab == 2)
{
// look in which of the three QLabels the mouse is, if it is in
// one of them.
ev = ui_sportwatcherWidgetBase.grHR->mapFrom(this, e->pos());
// look in which of the three QLabels the mouse is, if it is in
// one of them.
ev = ui_sportwatcherWidgetBase.grHR->mapFrom(this, e->pos());
 
if (ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.grHR->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.grHR->geometry().height()))
{
drawGrHR (ev.x(), ev.y());
drawGrElev (ev.x(), -1);
drawGrSpeed (ev.x(), -1);
}
if(ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.grHR->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.grHR->geometry().height()))
{
drawGrHR(ev.x(), ev.y());
drawGrElev(ev.x(), -1);
drawGrSpeed(ev.x(), -1);
}
 
ev = ui_sportwatcherWidgetBase.grElevation->mapFrom(this, e->pos());
ev = ui_sportwatcherWidgetBase.grElevation->mapFrom(this, e->pos());
 
if (ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.grElevation->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.grElevation->geometry().height()))
{
drawGrHR (ev.x(), -1);
drawGrElev (ev.x(), ev.y());
drawGrSpeed (ev.x(), -1);
}
if(ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.grElevation->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.grElevation->geometry().height()))
{
drawGrHR(ev.x(), -1);
drawGrElev(ev.x(), ev.y());
drawGrSpeed(ev.x(), -1);
}
 
ev = ui_sportwatcherWidgetBase.grSpeed->mapFrom(this, e->pos());
ev = ui_sportwatcherWidgetBase.grSpeed->mapFrom(this, e->pos());
 
if (ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.grSpeed->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.grSpeed->geometry().height()))
{
drawGrHR (ev.x(), -1);
drawGrElev (ev.x(), -1);
drawGrSpeed (ev.x(), ev.y());
}
if(ev.x() >= pos.x() &&
ev.y() >= pos.y() &&
ev.x() <= (pos.x() + ui_sportwatcherWidgetBase.grSpeed->geometry().width()) &&
ev.y() <= (pos.y() + ui_sportwatcherWidgetBase.grSpeed->geometry().height()))
{
drawGrHR(ev.x(), -1);
drawGrElev(ev.x(), -1);
drawGrSpeed(ev.x(), ev.y());
}
}
 
DIRTY=false;
DIRTY = false;
}
 
void sportwatcherWidget::mousePressEvent(QMouseEvent *e)
{
if (stateHand && e->button() == Qt::LeftButton)
lmbPressed = 1; // Left Mouse Button is pressed
else if (stateHand)
lmbPressed = 0; // Wrong button is pressed
if(stateHand && e->button() == Qt::LeftButton)
lmbPressed = 1; // Left Mouse Button is pressed
else if(stateHand)
lmbPressed = 0; // Wrong button is pressed
 
if (stateGlas)
if(stateGlas)
{
if (e->button() == Qt::LeftButton)
btGlasPlusSlot();
else if (e->button() == Qt::RightButton)
btGlasMinusSlot();
if(e->button() == Qt::LeftButton)
btGlasPlusSlot();
else if(e->button() == Qt::RightButton)
btGlasMinusSlot();
}
}
 
void sportwatcherWidget::mouseReleaseEvent(QMouseEvent *e)
{
if (stateHand && e->button() == Qt::LeftButton)
if(stateHand && e->button() == Qt::LeftButton)
{
lmbPressed = 2; // Left Mouse Button was released
mouseMoveEvent(e);
lmbPressed = 2; // Left Mouse Button was released
mouseMoveEvent(e);
}
}
 
5220,38 → 5359,39
* Private functions to draw cross and/or a bar to reflect the mouse
* pointer on tab 2.
*/
void sportwatcherWidget::drawGrHR (int x, int y)
void sportwatcherWidget::drawGrHR(int x, int y)
{
int width, height;
QPixmap pm = pmHR.copy(pmHR.rect());
QPainter paint;
int width, height;
QPixmap pm = pmHR.copy(pmHR.rect());
QPainter paint;
 
width = ui_sportwatcherWidgetBase.grHR->width();
height = ui_sportwatcherWidgetBase.grHR->height();
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
 
if (x > (width - 40) || y > (height - 12) || x < 1)
if(x > (width - 40) || y > (height - 12) || x < 1)
{
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
return;
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
return;
}
 
if (tabDirt2)
if(tabDirt2)
{
DIRTY = true;
showThreeCurve ();
tabDirt2 = false;
DIRTY = false;
DIRTY = true;
showThreeCurve();
tabDirt2 = false;
DIRTY = false;
}
 
paint.begin(&pm);
QColor black(0, 0, 0);
black.setAlpha (128);
black.setAlpha(128);
paint.setPen(QPen(black, 1, Qt::SolidLine));
 
// horizontal line, if y != -1
if (y >= 0)
paint.drawLine(2, y, width - 41, y);
if(y >= 0)
paint.drawLine(2, y, width - 41, y);
 
// vertical line
paint.drawLine(x, 1, x, height - 13);
5259,38 → 5399,39
ui_sportwatcherWidgetBase.grHR->setPixmap(pm);
}
 
void sportwatcherWidget::drawGrElev (int x, int y)
void sportwatcherWidget::drawGrElev(int x, int y)
{
int width, height;
QPixmap pm = pmElevation.copy(pmElevation.rect());
QPainter paint;
int width, height;
QPixmap pm = pmElevation.copy(pmElevation.rect());
QPainter paint;
 
width = ui_sportwatcherWidgetBase.grElevation->width();
height = ui_sportwatcherWidgetBase.grElevation->height();
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
 
if (x > (width - 40) || y > (height - 12) || x < 1)
if(x > (width - 40) || y > (height - 12) || x < 1)
{
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
return;
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
return;
}
 
if (tabDirt2)
if(tabDirt2)
{
DIRTY = true;
showThreeCurve ();
tabDirt2 = false;
DIRTY = false;
DIRTY = true;
showThreeCurve();
tabDirt2 = false;
DIRTY = false;
}
 
paint.begin(&pm);
QColor black(0, 0, 0);
black.setAlpha (128);
black.setAlpha(128);
paint.setPen(QPen(black, 1, Qt::SolidLine));
 
// horizontal line, if y != -1
if (y >= 0)
paint.drawLine(2, y, width - 41, y);
if(y >= 0)
paint.drawLine(2, y, width - 41, y);
 
// vertical line
paint.drawLine(x, 1, x, height - 13);
5298,38 → 5439,39
ui_sportwatcherWidgetBase.grElevation->setPixmap(pm);
}
 
void sportwatcherWidget::drawGrSpeed (int x, int y)
void sportwatcherWidget::drawGrSpeed(int x, int y)
{
int width, height;
QPixmap pm = pmSpeed.copy(pmSpeed.rect());
QPainter paint;
int width, height;
QPixmap pm = pmSpeed.copy(pmSpeed.rect());
QPainter paint;
 
width = ui_sportwatcherWidgetBase.grSpeed->width();
height = ui_sportwatcherWidgetBase.grSpeed->height();
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
 
if (x > (width - 40) || y > (height - 12) || x < 1)
if(x > (width - 40) || y > (height - 12) || x < 1)
{
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
return;
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
return;
}
 
if (tabDirt2)
if(tabDirt2)
{
DIRTY = true;
showThreeCurve ();
tabDirt2 = false;
DIRTY = false;
DIRTY = true;
showThreeCurve();
tabDirt2 = false;
DIRTY = false;
}
 
paint.begin(&pm);
QColor black(0, 0, 0);
black.setAlpha (128);
black.setAlpha(128);
paint.setPen(QPen(black, 1, Qt::SolidLine));
 
// horizontal line, if y != -1
if (y >= 0)
paint.drawLine(2, y, width - 41, y);
if(y >= 0)
paint.drawLine(2, y, width - 41, y);
 
// vertical line
paint.drawLine(x, 1, x, height - 13);
5340,21 → 5482,21
/*
* Private functions to help decode the data
*/
QDateTime *sportwatcherWidget::garmin_dtime (uint32 t)
QDateTime *sportwatcherWidget::garmin_dtime(uint32 t)
{
time_t tval;
struct tm tmval;
QTime ti;
QDate dt;
QDateTime *qt;
time_t tval;
struct tm tmval;
QTime ti;
QDate dt;
QDateTime *qt;
 
if (t == 0)
return new QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0, 0));
if(t == 0)
return new QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0, 0));
 
tval = t + TIME_OFFSET;
localtime_r (&tval, &tmval);
localtime_r(&tval, &tmval);
qt = new QDateTime();
qt->setDate(QDate(tmval.tm_year+1900, tmval.tm_mon+1, tmval.tm_mday));
qt->setDate(QDate(tmval.tm_year + 1900, tmval.tm_mon + 1, tmval.tm_mday));
qt->setTime(QTime(tmval.tm_hour, tmval.tm_min, tmval.tm_sec, 0));
/* OK. Done. */
return qt;
5362,27 → 5504,27
 
bool sportwatcherWidget::writeTag(const QFile &fn, const QString &str, int indent)
{
QString qs;
char *p;
QString qs;
char *p;
//QCString qcs;
int i;
int i;
 
if (indent > 0)
qs.fill(' ', indent * 3);
if(indent > 0)
qs.fill(' ', indent * 3);
 
qs.append(str);
// qcs = qs.utf8();
// qstrcpy(p, qcs);
p = strdup (qs.toUtf8().data());
p = strdup(qs.toUtf8().data());
i = strlen(p);
 
if (write(fn.handle(), p, i) != i)
if(write(fn.handle(), p, i) != i)
{
free (p);
return false;
free(p);
return false;
}
 
free (p);
free(p);
return true;
}
 
5389,22 → 5531,22
#if defined HAVE_GDAL
bool sportwatcherWidget::writeWMSTag(double llat, double llon, double rlat, double rlon, int width, int height)
{
QFile fl(MAP);
QString xml, s, srs, crs, styles, bSize, ext;
QDir dir = QDir::home();
QString path = dir.absolutePath();
int item, isrs;
double _llat, _llon, _rlat, _rlon;
bool offline, square;
QFile fl(MAP);
QString xml, s, srs, crs, styles, bSize, ext;
QDir dir = QDir::home();
QString path = dir.absolutePath();
int item, isrs;
double _llat, _llon, _rlat, _rlon;
bool offline, square;
 
if (!fl.open(QIODevice::ReadWrite | QIODevice::Truncate))
if(!fl.open(QIODevice::ReadWrite | QIODevice::Truncate))
{
KMessageBox::error (this, i18n("Error opening or creating the WMS tag file!\nPlease check file name and/or permissions."));
return false;
KMessageBox::error(this, i18n("Error opening or creating the WMS tag file!\nPlease check file name and/or permissions."));
return false;
}
 
KConfig cfg (QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup wms (&cfg, "WMS");
KConfig cfg(QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup wms(&cfg, "WMS");
square = wms.readEntry("Square", false);
styles = wms.readEntry("Styles", QString(""));
 
5419,66 → 5561,66
_rlat = rlat;
offline = false;
 
switch (isrs)
switch(isrs)
{
case 0: srs = QString("EPSG:4326"); break;
case 0: srs = QString("EPSG:4326"); break;
 
case 1:
srs = QString("EPSG:31257");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31257, width, height, square);
break;
case 1:
srs = QString("EPSG:31257");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31257, width, height, square);
break;
 
case 2:
srs = QString("EPSG:31258");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31258, width, height, square);
break;
case 2:
srs = QString("EPSG:31258");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31258, width, height, square);
break;
 
case 3:
srs = QString("EPSG:31259");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31259, width, height, square);
break;
case 3:
srs = QString("EPSG:31259");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31259, width, height, square);
break;
 
case 4:
srs = QString("EPSG:31286");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31286, width, height, square);
break;
case 4:
srs = QString("EPSG:31286");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31286, width, height, square);
break;
 
case 5:
srs = QString("EPSG:31287");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31287, width, height, square);
break;
case 5:
srs = QString("EPSG:31287");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31287, width, height, square);
break;
 
case 6:
srs = QString("EPSG:31288");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31288, width, height, square);
break;
case 6:
srs = QString("EPSG:31288");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 31288, width, height, square);
break;
 
case 7:
srs = QString("EPSG:900913");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 900913, width, height, square);
break;
case 7:
srs = QString("EPSG:900913");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 900913, width, height, square);
break;
 
case 8:
srs = QString("EPSG:3395");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 3395, width, height, square);
break;
case 8:
srs = QString("EPSG:3395");
offline = transCoords(&_llat, &_llon, &_rlat, &_rlon, 3395, width, height, square);
break;
 
default: srs = QString("EPSG:4326");
default: srs = QString("EPSG:4326");
}
 
xml += " <SRS>" + srs + "</SRS>\n";
item = wms.readEntry("CRS", 0);
 
switch (item)
switch(item)
{
case 0: crs = QString("CRS:83"); break;
case 1: crs = QString("CRS:84"); break;
case 2: crs = QString("EPSG:4326"); break;
case 3: crs = QString("EPSG:31259"); break;
case 4: crs = QString("EPSG:31287"); break;
case 5: crs = QString("EPSG:900913"); break;
case 6: crs = QString("EPSG:3395"); break;
default: crs = QString("CRS:84"); break;
case 0: crs = QString("CRS:83"); break;
case 1: crs = QString("CRS:84"); break;
case 2: crs = QString("EPSG:4326"); break;
case 3: crs = QString("EPSG:31259"); break;
case 4: crs = QString("EPSG:31287"); break;
case 5: crs = QString("EPSG:900913"); break;
case 6: crs = QString("EPSG:3395"); break;
default: crs = QString("CRS:84"); break;
}
 
xml += " <CRS>" + crs + "</CRS>\n";
5485,13 → 5627,13
item = wms.readEntry("Image", 2);
xml += " <ImageFormat>image/";
 
switch (item)
switch(item)
{
case 0: xml += "gif"; ext = QString(".gif"); break;
case 1: xml += "jpeg"; ext = QString(".jpg"); break;
case 2: xml += "png"; ext = QString(".png"); break;
case 3: xml += "tiff"; ext = QString(".tif"); break;
default: xml += "png"; ext = QString(".png");
case 0: xml += "gif"; ext = QString(".gif"); break;
case 1: xml += "jpeg"; ext = QString(".jpg"); break;
case 2: xml += "png"; ext = QString(".png"); break;
case 3: xml += "tiff"; ext = QString(".tif"); break;
default: xml += "png"; ext = QString(".png");
}
 
xml += "</ImageFormat>\n";
5498,49 → 5640,49
 
xml += " <Layers>" + wms.readEntry("Layer", QString("")) + "</Layers>\n";
 
if (!styles.isEmpty())
xml += " <Styles>" + styles + "</Styles>\n";
if(!styles.isEmpty())
xml += " <Styles>" + styles + "</Styles>\n";
 
xml += " <BBoxOrder>xyXY</BBoxOrder>\n";
xml += " </Service>\n";
xml += " <DataWindow>\n";
s.sprintf ("%f", _llat);
s.sprintf("%f", _llat);
xml += " <UpperLeftX>" + s + "</UpperLeftX>\n";
s.sprintf ("%f", _llon);
s.sprintf("%f", _llon);
xml += " <UpperLeftY>" + s + "</UpperLeftY>\n";
s.sprintf ("%f", _rlat);
s.sprintf("%f", _rlat);
xml += " <LowerRightX>" + s + "</LowerRightX>\n";
s.sprintf ("%f", _rlon);
s.sprintf("%f", _rlon);
xml += " <LowerRightY>" + s + "</LowerRightY>\n";
s.sprintf ("%d", width);
s.sprintf("%d", width);
xml += " <SizeX>" + s + "</SizeX>\n";
s.sprintf ("%d", height);
s.sprintf("%d", height);
xml += " <SizeY>" + s + "</SizeY>\n";
xml += " </DataWindow>\n";
 
/* switch (isrs)
{
case 0: srs = QString("EPSG:4326"); break;
case 1: srs = QString("EPSG:31259"); break;
case 2: srs = QString("EPSG:31286"); break;
case 3: srs = QString("EPSG:31287"); break;
case 4: srs = QString("EPSG:31288"); break;
default: srs = QString("EPSG:4326");
}
*/
/* switch (isrs)
{
case 0: srs = QString("EPSG:4326"); break;
case 1: srs = QString("EPSG:31259"); break;
case 2: srs = QString("EPSG:31286"); break;
case 3: srs = QString("EPSG:31287"); break;
case 4: srs = QString("EPSG:31288"); break;
default: srs = QString("EPSG:4326");
}
*/
// srs = QString("EPSG:4326");
xml += " <Projection>" + crs + "</Projection>\n";
xml += " <BandsCount>" + wms.readEntry("Bands", QString("3")) + "</BandsCount>\n";
item = wms.readEntry("Tile", 2);
 
switch (item)
switch(item)
{
case 0: bSize = QString("64"); break;
case 1: bSize = QString("128"); break;
case 2: bSize = QString("256"); break;
case 3: bSize = QString("512"); break;
case 4: bSize = QString("1024"); break;
default: bSize = QString("256");
case 0: bSize = QString("64"); break;
case 1: bSize = QString("128"); break;
case 2: bSize = QString("256"); break;
case 3: bSize = QString("512"); break;
case 4: bSize = QString("1024"); break;
default: bSize = QString("256");
}
 
xml += " <BlockSizeX>" + bSize + "</BlockSizeX>\n";
5555,77 → 5697,77
QString adv((wms.readEntry("Advice", false)) ? "true" : "false");
QString ver((wms.readEntry("Verify", true)) ? "true" : "false");
 
if (offline)
xml += " <OfflineMode>true</OfflineMode>\n";
if(offline)
xml += " <OfflineMode>true</OfflineMode>\n";
else
xml += " <OfflineMode>" + off + "</OfflineMode>\n";
xml += " <OfflineMode>" + off + "</OfflineMode>\n";
 
xml += " <AdviseRead>" + adv + "</AdviseRead>\n";
xml += " <VerifyAdviseRead>" + ver + "</VerifyAdviseRead>\n";
xml += "</GDAL_WMS>\n";
 
write (fl.handle(), xml.toAscii().data(), strlen (xml.toAscii().data()));
write(fl.handle(), xml.toAscii().data(), strlen(xml.toAscii().data()));
fl.close();
return true;
}
 
bool sportwatcherWidget::transCoords (double *x1, double *y1, double *x2, double *y2, int code, int width, int height, bool square)
bool sportwatcherWidget::transCoords(double *x1, double *y1, double *x2, double *y2, int code, int width, int height, bool square)
{
OGRSpatialReference oSourceSRS, oTargetSRS;
OGRCoordinateTransformation *poCT;
OGRSpatialReference oSourceSRS, oTargetSRS;
OGRCoordinateTransformation *poCT;
 
oSourceSRS.SetWellKnownGeogCS ("WGS84");
oSourceSRS.SetWellKnownGeogCS("WGS84");
oTargetSRS.importFromEPSG(code);
poCT = OGRCreateCoordinateTransformation (&oSourceSRS, &oTargetSRS);
poCT = OGRCreateCoordinateTransformation(&oSourceSRS, &oTargetSRS);
 
if (poCT == NULL || !poCT->Transform( 1, x1, y1))
if(poCT == NULL || !poCT->Transform(1, x1, y1))
{
KMessageBox::error(this, i18n("Translation between coordinate systems failed!"));
KMessageBox::error(this, i18n("Translation between coordinate systems failed!"));
 
if (poCT != NULL)
delete poCT;
if(poCT != NULL)
delete poCT;
 
return true;
return true;
}
 
if (poCT != NULL)
if(poCT != NULL)
{
poCT->Transform (1, x2, y2);
delete poCT;
poCT->Transform(1, x2, y2);
delete poCT;
}
 
if (square)
if(square)
{
double wdiff = (double)((long)(*x1 - *x2) / (width / 2 * 2) * (width / 2 * 2));
double hdiff = (double)((long)(*y2 - *y1) / (height / 2 * 2) * (height / 2 * 2));
double wdiff = (double)((long)(*x1 - *x2) / (width / 2 * 2) * (width / 2 * 2));
double hdiff = (double)((long)(*y2 - *y1) / (height / 2 * 2) * (height / 2 * 2));
 
*x2 = *x1 - wdiff; // * (double)mFactor;
*y2 = *y1 + hdiff; // * (double)mFactor;
*x2 = *x1 - wdiff; // * (double)mFactor;
*y2 = *y1 + hdiff; // * (double)mFactor;
// *x2 = *x1 - (double)((long)(wdiff / mFactor * mFactor));
// *y2 = *y1 - (double)((long)(hdiff / mFactor * mFactor));
/* wdiff = wdiff - (*x1 - *x2);
hdiff = hdiff - (*y2 - *y1);
*x1 -= wdiff / 2.0;
*x2 -= wdiff / 2.0;
*y1 += hdiff / 2.0;
*y2 += hdiff / 2.0; */
/* wdiff = wdiff - (*x1 - *x2);
hdiff = hdiff - (*y2 - *y1);
*x1 -= wdiff / 2.0;
*x2 -= wdiff / 2.0;
*y1 += hdiff / 2.0;
*y2 += hdiff / 2.0; */
}
 
return false;
}
 
QString *sportwatcherWidget::getProjection (int isrs, QString *srs)
QString *sportwatcherWidget::getProjection(int isrs, QString *srs)
{
switch (isrs)
switch(isrs)
{
case 0: *srs = QString("EPSG:4326"); break;
case 1: *srs = QString("EPSG:31257"); break;
case 2: *srs = QString("EPSG:31258"); break;
case 3: *srs = QString("EPSG:31259"); break;
case 4: *srs = QString("EPSG:31286"); break;
case 5: *srs = QString("EPSG:31287"); break;
case 6: *srs = QString("EPSG:31288"); break;
default: *srs = QString("EPSG:4326");
case 0: *srs = QString("EPSG:4326"); break;
case 1: *srs = QString("EPSG:31257"); break;
case 2: *srs = QString("EPSG:31258"); break;
case 3: *srs = QString("EPSG:31259"); break;
case 4: *srs = QString("EPSG:31286"); break;
case 5: *srs = QString("EPSG:31287"); break;
case 6: *srs = QString("EPSG:31288"); break;
default: *srs = QString("EPSG:4326");
}
 
return srs;
5633,21 → 5775,21
 
bool sportwatcherWidget::warpImage(QString fn, QString *fName)
{
GDALDatasetH hSrcDS, hDstDS;
GDALDataset *inSet, *outSet;
GDALDataType eDT;
GDALRasterBand *poBand;
GDALDriverH hDriver;
char hv0[256];
int nXSize, nYSize;
double adfGeoTransform[6];
double oriLeftLon, oriRightLon, oriLeftLat, oriRightLat;
GDALDatasetH hSrcDS, hDstDS;
GDALDataset *inSet, *outSet;
GDALDataType eDT;
GDALRasterBand *poBand;
GDALDriverH hDriver;
char hv0[256];
int nXSize, nYSize;
double adfGeoTransform[6];
double oriLeftLon, oriRightLon, oriLeftLat, oriRightLat;
 
 
// Loading the user set geo coords of our source image and
// load the projection used for that image
KConfig cfg (QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup ic (&cfg, "ImageCoords");
KConfig cfg(QString("sportwatcher.rc"), KConfig::SimpleConfig);
KConfigGroup ic(&cfg, "ImageCoords");
oriLeftLon = ic.readEntry("LeftLon", 0.0);
oriLeftLat = ic.readEntry("LeftLat", 0.0);
oriRightLon = ic.readEntry("RightLon", 0.0);
5655,27 → 5797,27
int isrs = ic.readEntry("SRS", 0);
 
// Create a temporary file name for our output file
strcpy (hv0, "/tmp/SportWatcherTIFFXXXXXX");
mkdtemp (&hv0[0]);
strcpy(hv0, "/tmp/SportWatcherTIFFXXXXXX");
mkdtemp(&hv0[0]);
*fName = QString(hv0) + ".tif";
 
// Open input and output files.
if ((hSrcDS = GDALOpen(fn.toAscii().data(), GA_ReadOnly)) == NULL)
if((hSrcDS = GDALOpen(fn.toAscii().data(), GA_ReadOnly)) == NULL)
{
KMessageBox::error(this, i18n("Error opening an image file!"));
return false;
KMessageBox::error(this, i18n("Error opening an image file!"));
return false;
}
 
inSet = (GDALDataset *)hSrcDS;
// Create output with same datatype as first input band.
poBand = inSet->GetRasterBand (1);
eDT = poBand->GetRasterDataType ();
poBand = inSet->GetRasterBand(1);
eDT = poBand->GetRasterDataType();
 
if ((hDriver = GDALGetDriverByName ("GTiff")) == NULL)
if((hDriver = GDALGetDriverByName("GTiff")) == NULL)
{
KMessageBox::error(this, i18n("Error loading the TIFF driver!"));
GDALClose (hSrcDS);
return false;
KMessageBox::error(this, i18n("Error loading the TIFF driver!"));
GDALClose(hSrcDS);
return false;
}
 
// Get dimensions of image and set transform data
5684,36 → 5826,36
nYSize = inSet->GetRasterYSize();
 
// cut the wanted region out of image
transform *tf = new transform (oriLeftLat, oriLeftLon, oriRightLat, oriRightLon);
transform *tf = new transform(oriLeftLat, oriLeftLon, oriRightLat, oriRightLon);
tf->setDimensions(nXSize, nYSize);
 
if (!tf->cutImage (geoRect.llat, geoRect.llon, geoRect.rlat, geoRect.rlon, fn))
if(!tf->cutImage(geoRect.llat, geoRect.llon, geoRect.rlat, geoRect.rlon, fn))
{
GDALClose (hSrcDS);
return false;
GDALClose(hSrcDS);
return false;
}
 
GDALClose (hSrcDS);
GDALClose(hSrcDS);
QString nfn = fn + "_tmp.png";
 
// repeat the part above and open the now cutted part of the image.
// Open input and output files.
if ((hSrcDS = GDALOpen(nfn.toAscii().data(), GA_ReadOnly)) == NULL)
if((hSrcDS = GDALOpen(nfn.toAscii().data(), GA_ReadOnly)) == NULL)
{
KMessageBox::error(this, i18n("Error opening an image file!"));
return false;
KMessageBox::error(this, i18n("Error opening an image file!"));
return false;
}
 
inSet = (GDALDataset *)hSrcDS;
// Create output with same datatype as first input band.
poBand = inSet->GetRasterBand (1);
eDT = poBand->GetRasterDataType ();
poBand = inSet->GetRasterBand(1);
eDT = poBand->GetRasterDataType();
 
if ((hDriver = GDALGetDriverByName ("GTiff")) == NULL)
if((hDriver = GDALGetDriverByName("GTiff")) == NULL)
{
KMessageBox::error(this, i18n("Error loading the TIFF driver!"));
GDALClose (hSrcDS);
return false;
KMessageBox::error(this, i18n("Error loading the TIFF driver!"));
GDALClose(hSrcDS);
return false;
}
 
// Get dimensions of image and set transform data
5724,26 → 5866,26
// Set the values needed to transform the image
OGRSpatialReference iSRS;
const char *iWKT;
switch (isrs)
 
switch(isrs)
{
case 0: iSRS.importFromEPSG(4326); break;
case 1: iSRS.importFromEPSG(31257); break;
case 2: iSRS.importFromEPSG(31258); break;
case 3: iSRS.importFromEPSG(31259); break;
case 4: iSRS.importFromEPSG(31286); break;
case 5: iSRS.importFromEPSG(31287); break;
case 6: iSRS.importFromEPSG(31288); break;
default: iSRS.importFromEPSG(4326);
case 0: iSRS.importFromEPSG(4326); break;
case 1: iSRS.importFromEPSG(31257); break;
case 2: iSRS.importFromEPSG(31258); break;
case 3: iSRS.importFromEPSG(31259); break;
case 4: iSRS.importFromEPSG(31286); break;
case 5: iSRS.importFromEPSG(31287); break;
case 6: iSRS.importFromEPSG(31288); break;
default: iSRS.importFromEPSG(4326);
}
 
iSRS.exportToWkt ((char **)&iWKT);
iSRS.exportToWkt((char **)&iWKT);
 
if (inSet->SetProjection (iWKT) != CE_None)
if(inSet->SetProjection(iWKT) != CE_None)
{
KMessageBox::error(this, i18n("Error setting projection on source!"));
GDALClose (hSrcDS);
return false;
KMessageBox::error(this, i18n("Error setting projection on source!"));
GDALClose(hSrcDS);
return false;
}
 
adfGeoTransform[0] = geoRect.llon;
5753,21 → 5895,21
adfGeoTransform[4] = 0.0;
adfGeoTransform[5] = -1.0 * ((geoRect.llat - geoRect.rlat) / (double)nYSize);
 
if (inSet->SetGeoTransform (&adfGeoTransform[0]) != CE_None)
if(inSet->SetGeoTransform(&adfGeoTransform[0]) != CE_None)
{
KMessageBox::error(this, i18n("Error setting geo transform data to source!"));
GDALClose (hSrcDS);
return false;
KMessageBox::error(this, i18n("Error setting geo transform data to source!"));
GDALClose(hSrcDS);
return false;
}
 
// Get Source coordinate system.
const char *pszSrcWKT, *pszDstWKT = NULL;
 
if ((pszSrcWKT = GDALGetProjectionRef (hSrcDS)) == NULL)
if((pszSrcWKT = GDALGetProjectionRef(hSrcDS)) == NULL)
{
KMessageBox::error(this, i18n("Error getting the projection reference"));
GDALClose (hSrcDS);
return false;
KMessageBox::error(this, i18n("Error getting the projection reference"));
GDALClose(hSrcDS);
return false;
}
 
// Setup output coordinate system that is UTM ? WGS84.
5775,7 → 5917,7
 
// oSRS.SetUTM( 0, TRUE );
oSRS.SetWellKnownGeogCS("WGS84");
oSRS.exportToWkt ((char **)&pszDstWKT);
oSRS.exportToWkt((char **)&pszDstWKT);
 
// Create the output file.
double adfDstGeoTransform[6];
5786,49 → 5928,49
adfDstGeoTransform[4] = 0.0;
adfDstGeoTransform[5] = -1.0 * ((geoRect.llat - geoRect.rlat) / (double)geoRect.height);
 
if ((hDstDS = GDALCreate(hDriver, fName->toAscii().data(), geoRect.width, geoRect.height,
nRasterCount, eDT, NULL )) == NULL)
if((hDstDS = GDALCreate(hDriver, fName->toAscii().data(), geoRect.width, geoRect.height,
nRasterCount, eDT, NULL)) == NULL)
{
KMessageBox::error(this, i18n("Error creating a temporary image file! (%1)").arg(*fName));
GDALClose (hSrcDS);
return false;
KMessageBox::error(this, i18n("Error creating a temporary image file! (%1)").arg(*fName));
GDALClose(hSrcDS);
return false;
}
 
outSet = (GDALDataset *)hDstDS;
 
for (int i = 0; i < nRasterCount; i++)
for(int i = 0; i < nRasterCount; i++)
{
poBand = outSet->GetRasterBand (i+1);
poBand->Fill (0.0);
poBand = outSet->GetRasterBand(i + 1);
poBand->Fill(0.0);
}
 
if (outSet->SetProjection (pszDstWKT) != CE_None)
if(outSet->SetProjection(pszDstWKT) != CE_None)
{
KMessageBox::error(this, i18n("Error setting projection on destination!"));
GDALClose (hDstDS);
GDALClose (hSrcDS);
unlink (fName->toAscii().data());
return false;
KMessageBox::error(this, i18n("Error setting projection on destination!"));
GDALClose(hDstDS);
GDALClose(hSrcDS);
unlink(fName->toAscii().data());
return false;
}
 
if (outSet->SetGeoTransform (&adfDstGeoTransform[0]) != CE_None)
if(outSet->SetGeoTransform(&adfDstGeoTransform[0]) != CE_None)
{
KMessageBox::error(this, i18n("Error setting geo transform data to destination!"));
GDALClose (hDstDS);
GDALClose (hSrcDS);
unlink (fName->toAscii().data());
return false;
KMessageBox::error(this, i18n("Error setting geo transform data to destination!"));
GDALClose(hDstDS);
GDALClose(hSrcDS);
unlink(fName->toAscii().data());
return false;
}
 
// Copy the color table, if required.
GDALColorTableH hCT;
 
for (int i = 0; i < nRasterCount; i++)
for(int i = 0; i < nRasterCount; i++)
{
hCT = GDALGetRasterColorTable (inSet->GetRasterBand (i+1));
hCT = GDALGetRasterColorTable(inSet->GetRasterBand(i + 1));
 
if (hCT != NULL)
GDALSetRasterColorTable (outSet->GetRasterBand (i+1), hCT);
if(hCT != NULL)
GDALSetRasterColorTable(outSet->GetRasterBand(i + 1), hCT);
}
 
// Setup warp options.
5839,14 → 5981,14
 
psWarpOptions->nBandCount = nRasterCount;
psWarpOptions->panSrcBands =
(int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount );
(int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount);
psWarpOptions->panDstBands =
(int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount );
(int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount);
 
for (int i = 0; i < nRasterCount; i++)
for(int i = 0; i < nRasterCount; i++)
{
psWarpOptions->panSrcBands[i] = i+1;
psWarpOptions->panDstBands[i] = i+1;
psWarpOptions->panSrcBands[i] = i + 1;
psWarpOptions->panDstBands[i] = i + 1;
}
 
// psWarpOptions->pfnProgress = GDALTermProgress;
5853,11 → 5995,11
 
// Establish reprojection transformer.
psWarpOptions->pTransformerArg =
GDALCreateGenImgProjTransformer(hSrcDS,
GDALGetProjectionRef(hSrcDS),
hDstDS,
GDALGetProjectionRef(hDstDS),
FALSE, 0.0, 1);
GDALCreateGenImgProjTransformer(hSrcDS,
GDALGetProjectionRef(hSrcDS),
hDstDS,
GDALGetProjectionRef(hDstDS),
FALSE, 0.0, 1);
 
psWarpOptions->pfnTransformer = GDALGenImgProjTransform;
 
5864,22 → 6006,22
// Initialize and execute the warp operation.
GDALWarpOperation oOperation;
 
if (oOperation.Initialize (psWarpOptions) != CE_None)
if(oOperation.Initialize(psWarpOptions) != CE_None)
{
KMessageBox::error(this, i18n("Error initializing warp operation!"));
GDALClose (hDstDS);
GDALClose (hSrcDS);
unlink (fName->toAscii().data());
return false;
KMessageBox::error(this, i18n("Error initializing warp operation!"));
GDALClose(hDstDS);
GDALClose(hSrcDS);
unlink(fName->toAscii().data());
return false;
}
 
oOperation.ChunkAndWarpMulti (0, 0, geoRect.width, geoRect.height);
GDALDestroyGenImgProjTransformer (psWarpOptions->pTransformerArg);
oOperation.ChunkAndWarpMulti(0, 0, geoRect.width, geoRect.height);
GDALDestroyGenImgProjTransformer(psWarpOptions->pTransformerArg);
GDALDestroyWarpOptions(psWarpOptions);
 
GDALClose (hDstDS);
GDALClose (hSrcDS);
unlink (nfn.toAscii().data());
GDALClose(hDstDS);
GDALClose(hSrcDS);
unlink(nfn.toAscii().data());
return true;
}
 
5888,66 → 6030,66
#ifdef HAVE_GDAL
void spwErrorHandler(CPLErr err, int num, const char *msg)
{
ERRMSG *akt;
char et[32], hv0[4096];
ERRMSG *akt;
char et[32], hv0[4096];
 
if (err == CE_None || !msg)
return;
if(err == CE_None || !msg)
return;
 
if (err == CE_Fatal)
std::cerr << "ERROR " << num << ": " << msg << endl;
if(err == CE_Fatal)
std::cerr << "ERROR " << num << ": " << msg << endl;
 
if (!firstError)
if(!firstError)
{
firstError = new ERRMSG;
memset (firstError, 0, sizeof(ERRMSG));
akt = firstError;
firstError = new ERRMSG;
memset(firstError, 0, sizeof(ERRMSG));
akt = firstError;
}
else
{
akt = firstError;
akt = firstError;
 
while (akt)
{
if (!akt->next)
break;
while(akt)
{
if(!akt->next)
break;
 
akt = akt->next;
}
akt = akt->next;
}
 
akt->next = new ERRMSG;
akt = akt->next;
memset (akt, 0, sizeof(ERRMSG));
akt->next = new ERRMSG;
akt = akt->next;
memset(akt, 0, sizeof(ERRMSG));
}
 
switch (err)
switch(err)
{
case CE_None: strcpy (et, "None"); break;
case CE_Debug: strcpy (et, "DEBUG"); break;
case CE_Warning: strcpy (et, "Warning"); break;
case CE_Failure: strcpy (et, "Failure"); break;
case CE_Fatal: strcpy (et, "Fatal"); break;
case CE_None: strcpy(et, "None"); break;
case CE_Debug: strcpy(et, "DEBUG"); break;
case CE_Warning: strcpy(et, "Warning"); break;
case CE_Failure: strcpy(et, "Failure"); break;
case CE_Fatal: strcpy(et, "Fatal"); break;
}
 
memset(hv0, 0, sizeof(hv0));
strncpy (hv0, msg, 4000);
sprintf (akt->msg, "ERROR TYPE %s - %d: %s", et, num, hv0);
strncpy(hv0, msg, 4000);
sprintf(akt->msg, "ERROR TYPE %s - %d: %s", et, num, hv0);
}
 
void destroyErrors()
{
ERRMSG *akt;
ERRMSG *akt;
 
if (!firstError)
return;
if(!firstError)
return;
 
akt = firstError;
 
while (akt)
while(akt)
{
firstError = akt->next;
delete akt;
akt = firstError;
firstError = akt->next;
delete akt;
akt = firstError;
}
 
firstError = 0;
5955,13 → 6097,13
 
QString catGDALError()
{
QString err;
ERRMSG *akt = firstError;
QString err;
ERRMSG *akt = firstError;
 
while (akt)
while(akt)
{
err += QString(akt->msg) + "\n";
akt = akt->next;
err += QString(akt->msg) + "\n";
akt = akt->next;
}
 
destroyErrors();
/sportwatcher/trunk/src/disassemble.cpp
20,6 → 20,7
#include <time.h>
#include <string.h>
#include <math.h>
#include <boost/concept_check.hpp>
#include "garmin.h"
#include "disassemble.h"
 
284,6 → 285,9
float32 oldAlt, arrAlt[20];
int distPos;
 
if (!l || !l->head)
return;
 
for (n = l->head; n != NULL; n = n->next)
{
garmin_print_data(n->data);
293,6 → 297,7
// figure out some statistics
akt = point_node;
pTime = 0;
stTime = 0;
distPos = 0;
oldAlt = 0;
descend = 99999;
484,6 → 489,9
 
void disassemble::garmin_print_dpos (position_type *pos, double *lat, double *lon)
{
if (!pos || !lat || !lon)
return;
 
if ( pos->lat != 0x7fffffff )
*lat = SEMI2DEG(pos->lat);
 
500,7 → 508,7
char *disassemble::garmin_print_float32 (float32 f, char *ret)
{
if (!ret)
return NULL;
return 0;
 
if ( f > 100000000.0 || f < -100000000.0 )
sprintf(ret, "%.9e",f);
538,6 → 546,9
 
char *disassemble::garmin_print_float64 (float64 f, char *ret)
{
if (!ret)
return 0;
 
if ( f > 10000000000000000.0 || f < -10000000000000000.0 )
sprintf(ret,"%.17e",f);
else if ( f > 1000000000000000.0 || f < -1000000000000000.0 )
1732,7 → 1743,7
 
void disassemble::garmin_print_data (garmin_data *d)
{
if (!d)
if (!d || !d->data)
return;
 
#define CASE_PRINT(x) \
/sportwatcher/trunk/libgarmin/datatype.c
15,6 → 15,7
if (!d)
return NULL;
 
memset(d, 0, sizeof(garmin_data));
d->type = type;
 
#define CASE_DATA(x) \
93,6 → 94,7
if ((l = calloc(1,sizeof(garmin_list))) == NULL)
return NULL;
 
memset(l, 0, sizeof(garmin_list));
l->id = ++gListId;
 
return l;
102,70 → 104,74
garmin_list *
garmin_list_append ( garmin_list * list, garmin_data * data )
{
garmin_list * l = list;
garmin_list_node * n;
garmin_list * l = list;
garmin_list_node * n;
 
if ( data != NULL )
{
if ( l == NULL )
{
if ((l = garmin_alloc_list()) == NULL)
return NULL;
}
if ( data != NULL )
{
if ( l == NULL )
{
if ( ( l = garmin_alloc_list() ) == NULL )
return NULL;
}
 
if ((n = malloc(sizeof(garmin_list_node))) == NULL)
return NULL;
if ( ( n = malloc ( sizeof ( garmin_list_node ) ) ) == NULL )
return NULL;
 
n->data = data;
n->next = NULL;
memset(n, 0, sizeof(garmin_list_node));
n->data = data;
n->next = NULL;
 
if ( l->head == NULL )
l->head = n;
if ( l->head == NULL )
l->head = n;
 
if ( l->tail != NULL )
l->tail->next = n;
if ( l->tail != NULL )
l->tail->next = n;
 
l->tail = n;
l->elements++;
}
l->tail = n;
l->elements++;
}
 
return l;
return l;
}
 
 
garmin_data *
garmin_list_data ( garmin_data * data, uint32 which )
garmin_data *garmin_list_data (garmin_data *data, uint32 which)
{
garmin_data * ret = NULL;
garmin_list * list;
garmin_list_node * n;
unsigned int i;
garmin_data * ret = NULL;
garmin_list * list;
garmin_list_node * n;
unsigned int i;
 
if ( data != NULL &&
data->type == data_Dlist &&
(list = data->data) != NULL ) {
for ( i = 0, n = list->head; i < which && n != NULL; i++, n = n->next );
if ( n != NULL ) ret = n->data;
}
if (data != NULL && data->type == data_Dlist && (list = data->data) != NULL)
{
for ( i = 0, n = list->head; i < which && n != NULL; i++, n = n->next );
 
return ret;
if ( n != NULL )
ret = n->data;
}
 
return ret;
}
 
 
void
garmin_free_list ( garmin_list * l )
garmin_free_list (garmin_list *l)
{
garmin_list_node * n;
garmin_list_node * x;
garmin_list_node *n;
garmin_list_node *x;
 
if ( l != NULL ) {
for ( n = l->head; n != NULL; n = x ) {
x = n->next;
garmin_free_data(n->data);
free(n);
if ( l != NULL )
{
for ( n = l->head; n != NULL; n = x )
{
x = n->next;
garmin_free_data (n->data);
free (n);
}
 
free (l);
}
free(l);
}
}
 
 
172,16 → 178,18
void
garmin_free_list_only ( garmin_list * l )
{
garmin_list_node * n;
garmin_list_node * x;
garmin_list_node * n;
garmin_list_node * x;
 
if ( l != NULL ) {
for ( n = l->head; n != NULL; n = x ) {
x = n->next;
free(n);
if ( l != NULL )
{
for ( n = l->head; n != NULL; n = x )
{
x = n->next;
free ( n );
}
free ( l );
}
free(l);
}
}
 
 
191,95 → 199,101
void
garmin_free_data ( garmin_data * d )
{
D105 * d105;
D106 * d106;
D108 * d108;
D109 * d109;
D110 * d110;
D202 * d202;
D210 * d210;
D310 * d310;
D312 * d312;
D650 * d650;
D105 * d105;
D106 * d106;
D108 * d108;
D109 * d109;
D110 * d110;
D202 * d202;
D210 * d210;
D310 * d310;
D312 * d312;
D650 * d650;
 
if ( d != NULL ) {
if ( d->data != NULL ) {
if ( d->type == data_Dlist ) {
garmin_free_list((garmin_list *)d->data);
} else {
switch ( d->type ) {
case data_D105:
d105 = d->data;
TRYFREE(d105->wpt_ident);
break;
case data_D106:
d106 = d->data;
TRYFREE(d106->wpt_ident);
TRYFREE(d106->lnk_ident);
break;
case data_D108:
d108 = d->data;
TRYFREE(d108->ident);
TRYFREE(d108->comment);
TRYFREE(d108->facility);
TRYFREE(d108->city);
TRYFREE(d108->addr);
TRYFREE(d108->cross_road);
break;
case data_D109:
d109 = d->data;
TRYFREE(d109->ident);
TRYFREE(d109->comment);
TRYFREE(d109->facility);
TRYFREE(d109->city);
TRYFREE(d109->addr);
TRYFREE(d109->cross_road);
break;
case data_D110:
d110 = d->data;
TRYFREE(d110->ident);
TRYFREE(d110->comment);
TRYFREE(d110->facility);
TRYFREE(d110->city);
TRYFREE(d110->addr);
TRYFREE(d110->cross_road);
break;
case data_D202:
d202 = d->data;
TRYFREE(d202->rte_ident);
break;
case data_D210:
d210 = d->data;
TRYFREE(d210->ident);
break;
case data_D310:
d310 = d->data;
TRYFREE(d310->trk_ident);
break;
case data_D312:
d312 = d->data;
TRYFREE(d312->trk_ident);
break;
case data_D650:
d650 = d->data;
TRYFREE(d650->departure_name);
TRYFREE(d650->departure_ident);
TRYFREE(d650->arrival_name);
TRYFREE(d650->arrival_ident);
TRYFREE(d650->ac_id);
break;
default:
break;
}
free(d->data);
}
if ( d != NULL )
{
if ( d->data != NULL )
{
if ( d->type == data_Dlist )
{
garmin_free_list ( ( garmin_list * ) d->data );
}
else
{
switch ( d->type )
{
case data_D105:
d105 = d->data;
TRYFREE ( d105->wpt_ident );
break;
case data_D106:
d106 = d->data;
TRYFREE ( d106->wpt_ident );
TRYFREE ( d106->lnk_ident );
break;
case data_D108:
d108 = d->data;
TRYFREE ( d108->ident );
TRYFREE ( d108->comment );
TRYFREE ( d108->facility );
TRYFREE ( d108->city );
TRYFREE ( d108->addr );
TRYFREE ( d108->cross_road );
break;
case data_D109:
d109 = d->data;
TRYFREE ( d109->ident );
TRYFREE ( d109->comment );
TRYFREE ( d109->facility );
TRYFREE ( d109->city );
TRYFREE ( d109->addr );
TRYFREE ( d109->cross_road );
break;
case data_D110:
d110 = d->data;
TRYFREE ( d110->ident );
TRYFREE ( d110->comment );
TRYFREE ( d110->facility );
TRYFREE ( d110->city );
TRYFREE ( d110->addr );
TRYFREE ( d110->cross_road );
break;
case data_D202:
d202 = d->data;
TRYFREE ( d202->rte_ident );
break;
case data_D210:
d210 = d->data;
TRYFREE ( d210->ident );
break;
case data_D310:
d310 = d->data;
TRYFREE ( d310->trk_ident );
break;
case data_D312:
d312 = d->data;
TRYFREE ( d312->trk_ident );
break;
case data_D650:
d650 = d->data;
TRYFREE ( d650->departure_name );
TRYFREE ( d650->departure_ident );
TRYFREE ( d650->arrival_name );
TRYFREE ( d650->arrival_ident );
TRYFREE ( d650->ac_id );
break;
default:
break;
}
free ( d->data );
}
}
free ( d );
}
free(d);
}
}
 
 
/*
/*
Returns the number of bytes needed in order to serialize the data. Note
that this is an upper bound! Some of the Garmin data structures do not
align to word boundaries. Their memory representation will take up more
294,11 → 308,11
uint32 bytes = 0;
char hv0[256];
 
/*
/*
The number of bytes needed in order to serialize a Garmin data structure
is almost equal to the size of its data structure - but not quite. If
we have variable length strings, we need to add their string lengths
(including space for the terminating '\0') and subtract the size of the
(including space for the terminating '\0') and subtract the size of the
char * placeholders. We also need 4 bytes for the data type, and 4
additional bytes in which we store the number of bytes that we should
seek forward in order to skip this record. This allows us to handle