Subversion Repositories public

Compare Revisions

Ignore whitespace Rev 279 → Rev 280

/sportwatcher/trunk/src/render.cpp
10,8 → 10,14
// Copyright: See COPYING file that comes with this distribution
//
//
#include "config.h"
 
// This module will only exist, if Mapnik is available!
#if defined HAVE_MAPNIK
 
#define BOOST_SPIRIT_THREADSAFE
#include <QLabel>
#include <QPixmap>
#include <QBitmap>
#include <QString>
#include <QXmlReader>
#include <QDir>
25,7 → 31,6
#include <KConfigGroup>
#include <KIconLoader>
 
#include "config.h"
#include "render.h"
#include <iostream>
 
131,7 → 136,7
 
SRender::SRender()
{
label = 0;
_width = _height = 0;
shapePath = QString::null;
XmlPath = QString::null;
Lay = firstLayer = lastLayer = 0;
192,10 → 197,17
 
SRender::~SRender()
{
_width = _height = 0;
startDocument(); // Clean everything
ControlSet = false;
}
 
void SRender::setDrawArea(int w, int h)
{
_width = w;
_height = h;
}
 
bool SRender::startDocument()
{
m.remove_all(); // delete styles and layers from map
1477,7 → 1489,6
 
bool SRender::getMap (double lx, double ly, double rx, double ry)
{
int width, height;
QXmlSimpleReader reader;
QString hv0;
QFile file(XmlPath);
1484,6 → 1495,9
QDir dir(fontPath);
double plx, ply, prx, pry;
 
if (_width <= 0 || _height <= 0)
return false;
 
hv0 = pluginPath;
 
if (hv0.right(1) != QString("/"))
1517,15 → 1531,9
freetype_engine::register_font(f.toAscii().data());
}
 
// hv0 += "DejaVuSans.ttf"; // Default font
// freetype_engine::register_font(hv0.toAscii().data());
m.setWidth(_width);
m.setHeight(_height);
 
width = label->width();
height = label->height();
 
m.setWidth(width);
m.setHeight(height);
 
try
{
if (!ControlSet) // Initialize the map?
1563,7 → 1571,7
 
// Put the image into a Qt object
QImage image((uchar*)buf.raw_data(), m.getWidth(), m.getHeight(), QImage::Format_ARGB32);
label->setPixmap(QPixmap::fromImage(image.rgbSwapped()));
pxmap = QPixmap::fromImage(image.rgbSwapped());
}
 
catch (const mapnik::config_error &ex)
1956,3 → 1964,5
ls->next = 0;
return ls;
}
 
#endif // HAVE_MAPNIK
/sportwatcher/trunk/src/main.cpp
59,6 → 59,7
KLocalizedString(), "http://www.theosys.at", "andreas@theosys.at");
about.addAuthor( ki18n("Andreas Theofilu"), ki18n("Maintainer, Project Management, Developer"), "andreas@theosys.at" );
about.addCredit( ki18n("Dave Bailey"), KLocalizedString(), "dave@daveb.net");
about.addCredit( ki18n("Paul"), KLocalizedString(), "paul@ant.sbrk.co.uk");
about.setTranslator (ki18n("Andreas Theofilu"), ki18n("andreas@theosys.at"));
 
KCmdLineArgs::init(argc, argv, &about);
/sportwatcher/trunk/src/sportwatcherwidget.h
120,7 → 120,7
void showTrack(int zoom, const QRect &pan, LAP *lap);
void showCurves();
void showCurves(LAP *lap);
void showThreeCurve();
void showThreeCurve(int pw=0, int ph=0);
void resizeEvent(QResizeEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent *e);
141,6 → 141,7
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);
151,10 → 152,11
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
KLocale *kl; // This is for translating date and time to the locale
manageFile spw;
disassemble ds;
garmin_data *gmn;
170,6 → 172,8
LAP *mapLap;
int curTab;
bool tabDirt0, tabDirt1, tabDirt2, tabDirt3;
bool ActivePrint;
QPainter printArea;
#if defined HAVE_GDAL
GDALDataset *poDataset;
int mFactor;
/sportwatcher/trunk/src/render.h
12,6 → 12,11
#ifndef _RENDER_H
#define _RENDER_H
 
#include "config.h"
 
// Everything here is only available, if Mapnik is available!
#if defined HAVE_MAPNIK
 
#include <mapnik/map.hpp>
#include <mapnik/datasource_cache.hpp>
#include <mapnik/font_engine_freetype.hpp>
259,7 → 264,8
SRender();
~SRender();
 
void setDrawArea(const QLabel &lb) { label = (QLabel *)&lb; };
void setDrawArea(int, int);
QPixmap pixmap() { return pxmap; };
void setShapePath(const QString &str) { if (str.isNull()) return; shapePath = str; };
void setXmlPath(const QString &path) { if (path.isNull()) return; XmlPath = path; };
bool getMap(double lx, double ly, double rx, double ry);
305,7 → 311,7
LINEPATTERNSYMBOLIZER *allocLinePatternSymbolizer();
 
private:
QLabel *label;
QPixmap pxmap;
QString shapePath;
QString pluginPath;
QString fontPath;
312,6 → 318,7
QString XmlPath;
bool geographic;
map_type __map_type;
int _width, _height;
CONTAINER Container;
bool ControlSet;
int Field;
333,4 → 340,5
LINEPATTERNSYMBOLIZER *LinePatternSymbolizer;
};
 
#endif // HAVE_MAPNIK
#endif // _RENDER_H
/sportwatcher/trunk/src/sportwatcherwidget.cpp
48,6 → 48,8
#include <QRect>
#include <QRegion>
#include <KIcon>
#include <QPrintDialog>
#include <QPrinter>
 
#if defined HAVE_GDAL
#include <gdal/ogr_spatialref.h>
59,9 → 61,10
#include "garmin.h"
#include "transform.h"
#include "import.h"
#include "render.h"
 
//#define DEBUG 1
#if defined HAVE_MAPNIK
#include "render.h"
#endif
 
using std::cout;
using std::cerr;
96,6 → 99,7
DIRTY = true;
curTab = ui_sportwatcherWidgetBase.tabView->currentIndex();
tabDirt0 = tabDirt1 = tabDirt2 = tabDirt3 = true;
ActivePrint = false; // true if we are printing on paper
kl = new KLocale(QString("kdesktop"), 0);
 
// Load the config parameters
623,11 → 627,555
DIRTY = false;
}
 
/*
* The following function is called, when the user clicks the print button.
* It then prints the currently loaded activity. First the laps and on a
* seperate page the map, heart rate, elevation and speed.
*
* The function uses the already existing function showTrack() to draw an
* optional map and the track on it. It uses the function showThreeCurve()
* to draw the heart rate, elevation and speed. Only the laps are drawn
* directly in this function.
*/
void sportwatcherWidget::filePrint()
{
KMessageBox::information(this, i18n("This function is currently not implemented!"));
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;
 
if (!gmn)
{
KMessageBox::error(this, i18n("You must select an activity first!"));
return;
}
 
printer.setCreator(QString("SportWatcher"));
printer.setDocName(QString("SportWatcher_%1").arg(QString(VERSION)));
QPrintDialog printDialog(&printer, this);
 
if (!printDialog.exec() == QDialog::Accepted)
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
// A4 (210x297mm) and the output is optimized for this.
extMil[0] = 20.0;
extMil[1] = 20.0;
extMil[2] = 210.0 - 20.0;
extMil[3] = 279.0 - 20.0;
lineH = 4.5; // The height of a line with 10pt letters
page = 1; // The page number
firstPage = printer.fromPage();
lastPage = printer.toPage();
 
if (!printArea.begin(&printer))
{
KMessageBox::error(this, i18n("Error initializing printer! Printing is currently not available!"));
return;
}
 
ActivePrint = true;
rakt = rn;
QApplication::setOverrideCursor (QCursor(Qt::WaitCursor));
 
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;
 
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 (!(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;
}
 
// 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;
}
 
// 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;
}
 
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"));
 
distance = 0.0;
mspeed = 0;
ahr = 0;
anz = 0;
cad = 0;
sum_asc = sum_dsc = old_asc = old_dsc = 0;
 
// 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 += lap->total_distance;
 
if (lap->avg_cadence != 0xff)
cad += lap->avg_cadence;
 
ahr += lap->avg_heart_rate;
anz++;
 
if (lap->max_speed > mspeed)
mspeed = lap->max_speed;
}
 
total_distance = distance = ds.getTotalDistance();
 
if (Units == 1) // Statute?
qs_distance.sprintf("%.2f ft", distance / 0.304);
else
qs_distance.sprintf("%.2f m", distance);
 
if (distance > 0)
{
QTime tt = qt->time();
long secs = (double)(tt.hour() * 3600 + tt.minute() * 60 + tt.second()) / 100.0;
 
if (Units == 0)
secs = secs * (1000.0 / distance * 100.0);
else
secs = secs * (1609.344 / 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 = QString(" ") + kl->formatTime(t, true);
 
if (Units == 0)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
 
if (Units == 1) // Statute?
speed = distance / ds.getTotalTime() * 3.6 / 1.609344;
else
speed = distance / ds.getTotalTime() * 3.6;
 
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 (cad > 0)
qs_avgcadence.sprintf("%d", cad / 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);
}
 
delete qt;
/* Get the laps. */
laps = 1;
 
for (i = rakt->run->first_lap_index; (unsigned int)i <= rakt->run->last_lap_index; i++)
{
double spd;
char *un;
 
if ((lap = ds.getLap(i)) == NULL)
continue;
 
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 (Units == 0)
{
un = (char *)"km/h";
spd *= 3.6;
}
else
{
spd *= 3.6 / 1.609344;
un = (char *)"mph";
}
 
qs_avgspeed.sprintf("%.2f %s", spd, un);
 
if (lap->total_distance > 0 && lap->total_time != 0)
{
double fact;
 
if (Units == 0)
fact = 1000.0; // 1 km
else
fact = 1609.344; // 1 mile in meters
 
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)
qs_avgpace.append(QString(" /km"));
else
qs_avgpace.append(QString(" /mi"));
}
 
qs_avghr.sprintf("%d bpm", lap->avg_heart_rate);
 
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;
}
 
aktLine += lineH;
 
if (aktLine >= extMil[3]) // Print on the next 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));
aktLine = extMil[1];
printed = true;
}
else
aktLine = extMil[1];
 
if (printed)
printer.newPage();
 
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;
}
 
printArea.setFont(QFont(QString("Helvetica"), 10, QFont::Normal, false));
}
 
delete qt;
laps++;
}
 
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;
}
 
aktLine = extMil[1];
page++;
 
if (printed && (page <= lastPage || lastPage == 0))
printer.newPage();
 
if ((lastPage > 0 && (page < firstPage || page > lastPage)))
break;
 
// 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;
 
// 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();
// Mark printing as done
ActivePrint = false;
QApplication::restoreOverrideCursor();
}
 
qreal sportwatcherWidget::milToPixel(qreal dist, QPrinter &pr, bool dir)
{
QSizeF r = pr.paperSize(QPrinter::DevicePixel);
QSizeF m = pr.paperSize(QPrinter::Millimeter);
 
if (!dir) // width
return r.width() / m.width() * dist;
else
return r.height() / m.height() * dist;
}
 
/*
* This function allows the user to choose a file name, where we save the
* actual lap in Garmins own TCX format. This format is simply a XML-file.
1749,7 → 2297,7
dlg->exec();
delete dlg;
}
 
#if defined HAVE_MAPNIK
if (MapType == MPT_SHP || MapType == MPT_OSM)
{
shapeWidget *dlg = new shapeWidget(this);
1762,7 → 2310,12
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."));
#endif
if (MapType != MPT_WMS && MapType != MPT_SHP && MapType != MPT_OSM)
{
KMessageBox::detailedSorry(this,
1775,9 → 2328,9
}
#else
KMessageBox::detailedSorry(this,
i18n("This function was disabled at compile time because of missing GDAL v1.5.x!"),
i18n("Sportwatcher needs GDAL v1.5.x to enable this function.\n") +
i18n("If you like this to be working, install GDAL version 1.5.x 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
}
 
1804,20 → 2357,17
return;
 
if (!gmn)
{
// KMessageBox::error(this, i18n("No data were loaded!"));
return;
}
 
if (gmn->type == data_Dnil)
{
KMessageBox::error(0, i18n("No data found!"));
KMessageBox::error(this, i18n("No data found!"));
return;
}
 
if (gmn->type != data_Dlist) /* List of data */
{
KMessageBox::error(0, i18n("Found unexpected data type %1!").arg(gmn->type));
KMessageBox::error(this, i18n("Found unexpected data type %1!").arg(gmn->type));
return;
}
 
1871,11 → 2421,11
// This is used on the tab "Summary"
switch (rakt->run->sport_type)
{
case D1000_running: qs_name = QString("Running: "); break;
case D1000_biking: qs_name = QString("Biking: "); break;
case D1000_other: qs_name = QString("Other: "); break;
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 = QString("Unknown: ");
qs_name = i18n("Unknown: ");
}
 
if (!(lap = ds.getLap(rakt->run->first_lap_index)))
2377,11 → 2927,16
oriRightLat = ic.readEntry("RightLat", 0.0);
// int isrs = ic.readEntry("SRS", 0);
#endif
if (curTab == 0)
if (curTab == 0 && !ActivePrint)
{
width = ui_sportwatcherWidgetBase.imgMap->width() - 2;
height = ui_sportwatcherWidgetBase.imgMap->height();
}
else if (ActivePrint)
{
width = pmPrMap.width();
height = pmPrMap.height();
}
else
{
width = ui_sportwatcherWidgetBase.grMap->width() - 2;
2749,6 → 3304,7
if (MAP != fName)
unlink (fName.toAscii().data());
}
#if defined HAVE_MAPNIK
else if (MapType == MPT_SHP)
{
QDir shpd(MAP, QString("*.shp"));
2763,10 → 3319,12
SRender rd;
QColor bg(220, 220, 220); // background color
 
if (curTab == 0)
rd.setDrawArea(*ui_sportwatcherWidgetBase.imgMap);
else
rd.setDrawArea(*ui_sportwatcherWidgetBase.grMap);
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);
 
2773,12 → 3331,7
if (rd.getMap(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat))
{
paint.fillRect(0, 0, width+2, height+2, bg);
 
if (curTab == 0)
paint.drawPixmap(0, 0, *ui_sportwatcherWidgetBase.imgMap->pixmap());
else
paint.drawPixmap(0, 0, *ui_sportwatcherWidgetBase.grMap->pixmap());
 
paint.drawPixmap(0, 0, rd.pixmap());
Fgeo = true;
}
else
2799,10 → 3352,12
SRender rd;
QColor bg(220, 220, 220); // background color
 
if (curTab == 0)
rd.setDrawArea(*ui_sportwatcherWidgetBase.imgMap);
else
rd.setDrawArea(*ui_sportwatcherWidgetBase.grMap);
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);
 
2809,12 → 3364,7
if (rd.getMap(posLXY.lon, posLXY.lat, posRXY.lon, posRXY.lat))
{
paint.fillRect(0, 0, width+2, height+2, bg);
 
if (curTab == 0)
paint.drawPixmap(0, 0, *ui_sportwatcherWidgetBase.imgMap->pixmap());
else
paint.drawPixmap(0, 0, *ui_sportwatcherWidgetBase.grMap->pixmap());
 
paint.drawPixmap(0, 0, rd.pixmap());
Fgeo = true;
}
else
2821,6 → 3371,7
Fgeo = false;
}
}
#endif // HAVE_MAPNIK
else
{
KMessageBox::error(this, i18n("Error opening map file!"));
2828,7 → 3379,7
}
}
}
#endif
#endif // HAVE_GDAL
/*
* Here we come to draw the track. It will be drawn over the previous
* created map image.
2960,8 → 3511,10
 
paint.end();
 
if (curTab == 0)
if (curTab == 0 && !ActivePrint)
ui_sportwatcherWidgetBase.imgMap->setPixmap(pmMap);
else if (ActivePrint)
pmPrMap = pmMap;
else
ui_sportwatcherWidgetBase.grMap->setPixmap(pmMap);
 
3721,7 → 4274,7
DIRTY = false;
}
 
void sportwatcherWidget::showThreeCurve()
void sportwatcherWidget::showThreeCurve(int pw, int ph)
{
QPainter ptHR, ptElevation, ptSpeed;
int width, height, wdHR, htHR, wdElev, htElev, wdSpeed, htSpeed;
3744,26 → 4297,40
if (min_hr == 0 && max_hr == 0 && min_height == 0.0 && max_height == 0.0)
return;
 
if (!DIRTY || curTab != 2)
if (!ActivePrint && (!DIRTY || curTab != 2))
return;
 
// Get the dimensions of the available draw area
// First for heart rate
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);
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);
}
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);
}
else
return;
 
// we need a somewhat bigger area to draw our curves than
// we have with the real min and max values.
4452,10 → 5019,13
ptHR.end();
ptElevation.end();
ptSpeed.end();
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
 
if (!ActivePrint)
{
ui_sportwatcherWidgetBase.grHR->setPixmap(pmHR);
ui_sportwatcherWidgetBase.grElevation->setPixmap(pmElevation);
ui_sportwatcherWidgetBase.grSpeed->setPixmap(pmSpeed);
}
// free the chain of altitudes
avgHakt = avgHfirst;