Logo Search packages:      
Sourcecode: qlandkarte version File versions  Download package

CCanvas.cpp

/**********************************************************************************************
    Copyright (C) 2006, 2007 Oliver Eichler oliver.eichler@gmx.de,
    Michael Ritzert michael.ritzert@googlemail.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details1.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA

**********************************************************************************************/

#include "CCanvas.h"
#include "CMainWindow.h"
#include "CGarminMap.h"
#include "CGarminLiveLog.h"
#include "CGarminDBRoute.h"
#include "CGarminRoute.h"
#include "CInfoScreen.h"
#include "CDetailStatus.h"
#include "CDetailDetail.h"
#include "GeoMath.h"
#include "cursor.h"

#include <QtGui>
#include <QDebug>

#include <vector>

CCanvas::CCanvas(CMainWindow * parent)
: QWidget(parent)
, pfMousePressEvent(&CCanvas::mousePressMoveArea)
, pfMouseMoveEvent(&CCanvas::mouseMoveMoveArea)
, pfMouseReleaseEvent(&CCanvas::mouseReleaseMoveArea)
, mouseMode(eMouseMoveArea)
, m_lon(0)
, m_lat(0)
, moveMap(false)
, zoomMap(false)
, selectMap(false)
, waypoint(0)
, wptIsMoving(false)
, defineSearch(false)
, searchRadius(0)
, searchRadiusLimit(0)
, radius(0)
, trkpt1st(0)
, trkpt2nd(0)
, headingPixmap(":/pics/heading.png")
{
    setMouseTracking(true);
    setFocusPolicy(Qt::StrongFocus);

    map = new CGarminMap(this);

    details2 = new CDetailDetail(parent->statusBar());
    parent->statusBar()->addPermanentWidget(details2);
    connect(details2->butIncDetail,SIGNAL(clicked()),this,SLOT(incDetails()));
    connect(details2->butDecDetail,SIGNAL(clicked()),this,SLOT(decDetails()));

    details1 = new CDetailStatus(parent->statusBar());
    parent->statusBar()->addPermanentWidget(details1);
    details1->checkCity->setChecked(map->seeCityNames());
    details1->checkPOI->setChecked(map->seePOIs());
    details1->checkStreet->setChecked(map->seeStreetNames());
    connect(details1->checkCity,SIGNAL(toggled (bool)),this,SLOT(slotToggleCityNames()));
    connect(details1->checkPOI,SIGNAL(toggled (bool)),this,SLOT(slotTogglePOIs()));
    connect(details1->checkStreet,SIGNAL(toggled (bool)),this,SLOT(slotToggleStreetNames()));

    coord = new QLabel(parent->statusBar());
    parent->statusBar()->addPermanentWidget(coord);

    timerZoomDetailDelay = new QTimer(this);
    timerZoomDetailDelay->setSingleShot(true);
    connect(timerZoomDetailDelay,SIGNAL(timeout()),this,SLOT(slotIncreaseDetails()));

    setMouseMode(eMouseMoveArea);

    // any change in the database objects has to be reflected in the map
    connect(&gpResources->mapdb(),SIGNAL(sigMapChanged(QRectF&)),this,SLOT(update()));
    connect(&gpResources->mapdb(),SIGNAL(sigMapChanged()),this,SLOT(update()));
    connect(&gpResources->trackdb(),SIGNAL(sigTrackListChanged()),this,SLOT(update()));
    connect(&gpResources->wptdb(),SIGNAL(sigWaypointListChanged()),this,SLOT(update()));
    connect(&gpResources->routedb(),SIGNAL(sigDistListChanged()),this,SLOT(update()));
    connect(&gpResources->routedb(),SIGNAL(sigRouteListChanged()),this,SLOT(update()));

    infoScreen = new CInfoScreen(this);
    infoScreen->setMinimumSize(200,50);
    infoScreen->setMaximumWidth(200);

    QSettings cfg;
    showInfo = cfg.value("map/showInfo",true).toBool();

    contextMenu = new QMenu(this);
    contextMenu->addAction(QIcon(":/icons/iconEditPaste16x16.png"),tr("Copy Position"),this,SLOT(slotCopyPosition()));

}


CCanvas::~CCanvas()
{
    QSettings cfg;
    cfg.setValue("map/showInfo",showInfo);
}


void CCanvas::print(QPrinter& printer)
{
    QPainter p;

    qreal s1 = (qreal)printer.pageRect().size().width() / (qreal)size().width();
    qreal s2 = (qreal)printer.pageRect().size().height() / (qreal)size().height();
    qreal s = (s1 > s2) ? s2 : s1;

    p.begin(&printer);
    p.scale(s,s);
    p.setClipRegion(rect());
    p.setFont(gpResources->getMapFont());
    draw(p,false);
    p.end();

}


void CCanvas::slotIncreaseDetails()
{
    timerZoomDetailDelay->stop();
    map->setEasyDraw(false);
    update();
}


void CCanvas::move(double lng, double lat, const QString& info)
{
    XY pt;

    pt.u = DEG_TO_RAD * lng;
    pt.v = DEG_TO_RAD * lat;

    pt = pj_fwd(pt,*gpProj);

    QPoint p1 = rect().center();
    QPoint p2(map->u2px(pt.u),map->v2px(pt.v));

    map->move(p2,p1);

    if(!info.isEmpty()) {
        searchPoint.setX(pt.u);
        searchPoint.setY(pt.v);
        searchPointInfo = " " + info + " ";
    }
    else {
        searchPoint = QPoint();
    }
    update();
}


void CCanvas::move(move_direction_e dir)
{
    QPoint p1 = geometry().center();
    QPoint p2 = p1;

    switch(dir) {

        case eMoveLeft:
            p2.rx() += width() / 4;
            break;

        case eMoveRight:
            p2.rx() -= width() / 4;
            break;

        case eMoveUp:
            p2.ry() += height() / 4;
            break;

        case eMoveDown:
            p2.ry() -= height() / 4;
            break;
    }
    map->move(p1, p2);

    update();
}


void CCanvas::zoom(const QRectF& area)
{
    XY pt1,pt2;
    pt1.u = area.left() * DEG_TO_RAD;
    pt1.v = area.top() * DEG_TO_RAD;
    pt2.u = area.right() * DEG_TO_RAD;
    pt2.v = area.bottom() * DEG_TO_RAD;

    pt1 = pj_fwd(pt1,*gpProj);
    pt2 = pj_fwd(pt2,*gpProj);

    QRect r;
    r.setTopLeft(QPoint(map->u2px(pt1.u),map->v2px(pt1.v)));
    r.setBottomRight(QPoint(map->u2px(pt2.u),map->v2px(pt2.v)));

    map->zoom(r);

    update();
}


void CCanvas::zoom(bool in, const QPoint& p)
{
    map->setEasyDraw(true);
    map->zoom(in, p);
    timerZoomDetailDelay->start(500);
    update();
}


void CCanvas::setMouseMode(mouse_mode_e mode)
{
    QApplication::restoreOverrideCursor();

    switch(mode) {

        case eMouseMoveArea:
            cursor = QCursor(QCursor(cursorMoveAreaHoover,0,0));
            pfMousePressEvent   = &CCanvas::mousePressMoveArea;
            pfMouseMoveEvent    = &CCanvas::mouseMoveMoveArea;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseMoveArea;
            break;

        case eMouseZoomArea:
            cursor = QCursor(cursorZoom,0,0);
            pfMousePressEvent   = &CCanvas::mousePressZoomArea;
            pfMouseMoveEvent    = &CCanvas::mouseMoveZoomArea;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseZoomArea;
            break;

        case eMouseSelectArea:
            cursor = QCursor(cursorSelectTiles,0,0);
            pfMousePressEvent   = &CCanvas::mousePressSelectArea;
            pfMouseMoveEvent    = &CCanvas::mouseMoveSelectArea;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseSelectArea;
            break;

        case eMouseNewWpt:
            cursor = QCursor(cursorAddWpt,0,0);
            pfMousePressEvent   = &CCanvas::mousePressNewWpt;
            pfMouseMoveEvent    = &CCanvas::mouseMoveNewWpt;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseNewWpt;
            break;

        case eMouseEditWpt:
            cursor = QCursor(cursorEditWpt,0,0);
            pfMousePressEvent   = &CCanvas::mousePressEditWpt;
            pfMouseMoveEvent    = &CCanvas::mouseMoveEditWpt;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseEditWpt;
            break;

        case eMouseMoveWpt:
            cursor = QCursor(cursorMoveWpt,0,0);
            pfMousePressEvent   = &CCanvas::mousePressMoveWpt;
            pfMouseMoveEvent    = &CCanvas::mouseMoveMoveWpt;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseMoveWpt;
            break;

        case eMouseSearchOC:
            cursor = QCursor(cursorSearch,0,0);
            pfMousePressEvent   = &CCanvas::mousePressSearchOC;
            pfMouseMoveEvent    = &CCanvas::mouseMoveSearchOC;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseSearchOC;
            break;

        case eMouseCutTrack:
            cursor = QCursor(cursorCut,0,0);
            pfMousePressEvent   = &CCanvas::mousePressCutTrack;
            pfMouseMoveEvent    = &CCanvas::mouseMoveCutTrack;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseCutTrack;
            break;

        case eMouseEditRte:
            cursor   = QCursor(cursorAddWpt,0,0);
            pfMousePressEvent   = &CCanvas::mousePressEditRte;
            pfMouseMoveEvent    = &CCanvas::mouseMoveEditRte;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseEditRte;
            break;

        case eMouseMoveRte:
            cursor   = QCursor(cursorMoveWpt,0,0);
            pfMousePressEvent   = &CCanvas::mousePressMoveRte;
            pfMouseMoveEvent    = &CCanvas::mouseMoveMoveRte;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseMoveRte;
            break;

        case eMouseDelRte:
            cursor   = QCursor(cursorDelete,0,0);
            pfMousePressEvent   = &CCanvas::mousePressDelRte;
            pfMouseMoveEvent    = &CCanvas::mouseMoveDelRte;
            pfMouseReleaseEvent = &CCanvas::mouseReleaseDelRte;
            break;

    }
    if(underMouse()) {
        QApplication::setOverrideCursor(cursor);
    }
    mouseMode = mode;
    update();
}


void CCanvas::resizeEvent(QResizeEvent * e)
{
    map->resize(e->size());

    infoScreen->move(e->size().width() - 210,10);
    infoScreen->setMaximumHeight(e->size().height() - 20);
}


void CCanvas::paintEvent(QPaintEvent * e)
{
    QWidget::paintEvent(e);

    QPainter p;
    p.begin(this);
    p.fillRect(rect(),Qt::white);
    p.setFont(gpResources->getMapFont());
    draw(p,true);
    p.end();

}


void CCanvas::draw(QPainter& p, bool buffered)
{
    map->draw(p, buffered);

    drawTracks(p);
    drawWaypoints(p);
    drawSelectedMaps(p);
    drawZoomRect(p);
    drawInfoCursor(p);
    drawSearchResultMark(p);
    drawCacheSearchRadius(p);
    drawLiveLogPosition(p);
    drawRoutes(p);
}


void CCanvas::drawTracks(QPainter& p)
{
    // list of selected points
    QPolygon selected;

    // pointer to selected track point, if any
    QPair<const Garmin::TrkPt_t*,QPoint> cursor;
    cursor.first = 0;

    QMap<QString,CGarminTrack*>& tracks = gpResources->trackdb().getTracks();
    QMap<QString,CGarminTrack*>::iterator highlighted = tracks.end();
    QMap<QString,CGarminTrack*>::iterator track = tracks.begin();

    // draw all tracks except highlighted
    while(track != tracks.end()) {
        // convert track into polyline
        QPolygon& line = (*track)->polyline();

        line.clear();
        QVector<CGarminTrack::TrkPt_t>::iterator pt = (*track)->begin();
        while(pt != (*track)->end()) {
            // convert position to coordinate
            XY pt1;
            pt1.u = DEG_TO_RAD * pt->lon;
            pt1.v = DEG_TO_RAD * pt->lat;
            pt1 = pj_fwd(pt1,*gpProj);

            pt->point = QPoint(map->u2px(pt1.u),map->v2px(pt1.v));

            // skip deleted points, however if they are selected the
            // selection mark is shown
            if(pt->flags & CGarminTrack::eDeleted) {
                if(pt->flags & CGarminTrack::eSelected) {
                    selected << pt->point;
                }
                ++pt; continue;
            }

            line <<  pt->point;

            if((*track)->isHighlighted()) {
                // is point selected by CViewTrackInfo?
                if(pt->flags & CGarminTrack::eSelected) {
                    selected << line.last();
                }
                // is point close to cursor?
                if(pt->flags & CGarminTrack::eCursor) {
                    cursor.first    = &(*pt);
                    cursor.second   = line.last();
                }
            }
            ++pt;
        }

        if(!rect().intersects(line.boundingRect())) {
            ++track; continue;
        }

        if((*track)->isHighlighted()) {
            // store highlighted track to draw it later
            // it must be drawn above all other tracks
            highlighted = track;
        }
        else {
            // draw normal track
            p.setPen(QPen((*track)->getColor(),3));
            p.drawPolyline(line);
            p.setPen(Qt::white);
            p.drawPolyline(line);
        }
        ++track;
    }

    // if there is a highlighted track, draw it
    if(highlighted != tracks.end()) {
        track = highlighted;

        QPolygon& line = (*track)->polyline();

        // draw skunk line
        p.setPen(QPen((*track)->getColor(),5));
        p.drawPolyline(line);
        p.setPen(Qt::white);
        p.drawPolyline(line);

        // draw bubbles
        QPoint pt;
        foreach(pt,line) {
            p.setPen((*track)->getColor());
            p.setBrush(Qt::white);
            p.drawEllipse(pt.x() - 2 ,pt.y() - 2,5,5);

        }
        foreach(pt,selected) {
            p.setPen(Qt::black);
            p.setBrush(Qt::red);
            p.drawEllipse(pt.x() - 3 ,pt.y() - 3,7,7);

        }

        // draw cursor mark
        if(cursor.first) {
            const Garmin::TrkPt_t * trkpt  = cursor.first;
            QPoint pt                      = cursor.second;
            p.setBrush(QColor(255,255,0,128));
            p.setPen(Qt::darkYellow);
            p.drawEllipse(pt.x() - 4 ,pt.y() - 4,11,11);

            QString str;
            if(trkpt->time != 0x00000000 && trkpt->time != 0xFFFFFFFF) {
                QDateTime time = QDateTime::fromTime_t(trkpt->time + gpResources->getUTCOffset());
                time.setTimeSpec(Qt::LocalTime);
                str = time.toString();
            }

            if(trkpt->alt != 1e25f  || trkpt->dpth != 1e25f) {
                str += str.isEmpty() ? tr("elev: ") : tr("\nelev: ");
                if(gpResources->doMetric()) {
                    if(trkpt->alt != 1e25f) {
                        str += QString::number(trkpt->alt,'f',0) + "m";
                    }
                    else if(trkpt->dpth != 1e25f) {
                        str += QString::number(-trkpt->dpth,'f',0) + "m";
                    }
                }
                else {
                    if(trkpt->alt != 1e25f) {
                        str += QString::number(trkpt->alt * 3.28084,'f',0) + "ft";
                    }
                    else if(trkpt->dpth != 1e25f) {
                        str += QString::number(-trkpt->dpth  * 3.28084,'f',0) + "ft";
                    }
                }
            }

            if(!str.isEmpty()) {
                QRect r = p.boundingRect(QRect(pt + QPoint(11,+8),QSize(1,1)),Qt::AlignLeft|Qt::AlignVCenter," " + str + " ");

                p.setBrush(QBrush( QColor(220,220,255,220) ));
                p.setPen(QColor(150,150,255));
                p.drawRect(r);
                p.setPen(Qt::darkBlue);
                p.setBrush(Qt::darkBlue);
                p.drawText(r,Qt::AlignLeft|Qt::AlignVCenter,str);
            }
        }
    }

    // draw track cut mark
    if((mouseMode == eMouseCutTrack) && trkpt1st && trkpt2nd && (trkpt1st != trkpt2nd)) {
        QPoint& p1 = trkpt1st->point;
        QPoint& p2 = trkpt2nd->point;

        p.setPen(QPen(Qt::black,5));
        p.drawLine(p1,p2);
        p.setPen(QPen(Qt::red,2));
        p.drawLine(p1,p2);

        p.setPen(Qt::black);
        p.setBrush(Qt::red);
        p.drawEllipse(p1.x() - 3 ,p1.y() - 3,7,7);
        p.drawEllipse(p2.x() - 3 ,p2.y() - 3,7,7);

    }

}


void CCanvas::drawWaypoints(QPainter& p)
{
    // draw waypoints
    const QMap<QString,CGarminWpt*>& waypoints = gpResources->wptdb().getWaypoints();
    QMap<QString,CGarminWpt*>::const_iterator wpt = waypoints.begin();
    while(wpt != waypoints.end()) {
        XY pt1;
        pt1.u = DEG_TO_RAD * (*wpt)->lon;
        pt1.v = DEG_TO_RAD * (*wpt)->lat;
        pt1 = pj_fwd(pt1,*gpProj);

        QPoint pt2(map->u2px(pt1.u),map->v2px(pt1.v));

        // waypoint outside viewport?
        if(!rect().contains(pt2)) {
            ++wpt; continue;
        }

        // waypoint is selected?
        if((waypoint == (*wpt)) && !wptIsMoving) {
            p.setBrush(QColor(255,255,0,128));
            p.setPen(Qt::darkYellow);
            p.drawEllipse(pt2.x() - 10 ,pt2.y() - 10,21,21);

            QString str;
            if((*wpt)->time != 0x00000000 && (*wpt)->time != 0xFFFFFFFF) {
                QDateTime time = QDateTime::fromTime_t((*wpt)->time + gpResources->getUTCOffset());
                time.setTimeSpec(Qt::LocalTime);
                str = time.toString();
            }

            if(!(*wpt)->comment.isEmpty()) {
                str += str.isEmpty() ? (*wpt)->comment : "\n" + (*wpt)->comment;
            }

            if((*wpt)->alt != 1e25f  || (*wpt)->dpth != 1e25f) {
                str += str.isEmpty() ? tr("elev: ") : tr("\nelev: ");
                if(gpResources->doMetric()) {
                    if((*wpt)->alt != 1e25f) {
                        str += QString::number((*wpt)->alt,'f',0) + "m";
                    }
                    else if((*wpt)->dpth != 1e25f) {
                        str += QString::number(-(*wpt)->dpth,'f',0) + "m";
                    }
                }
                else {
                    if((*wpt)->alt != 1e25f) {
                        str += QString::number((*wpt)->alt * 3.28084,'f',0) + "ft";
                    }
                    else if((*wpt)->dpth != 1e25f) {
                        str += QString::number(-(*wpt)->dpth  * 3.28084,'f',0) + "ft";
                    }
                }
            }

            if(!str.isEmpty()) {
                QRect r = p.boundingRect(QRect(pt2 + QPoint(11,+8),QSize(1,1)),Qt::AlignLeft," " + str + " ");

                p.setBrush(QBrush( QColor(220,220,255,220) ));
                p.setPen(QColor(150,150,255));
                p.drawRect(r);
                p.setPen(Qt::darkBlue);
                p.setBrush(Qt::darkBlue);
                p.drawText(r,Qt::AlignLeft,str);
            }
        }

        // draw proximity distance circle
        if(((*wpt)->dist != 1e25f) && !wptIsMoving) {
            int u = map->u2px(pt1.u + (*wpt)->dist) - pt2.x();
            int v = map->v2px(pt1.v + (*wpt)->dist) - pt2.y();
            p.setPen(Qt::black);
            p.setBrush(Qt::NoBrush);
            p.drawEllipse(pt2.x() - u , pt2.y() - v, 2*u + 1, 2*v + 1);
        }

        // draw symbol and identification text
        p.drawPixmap(pt2 + QPoint(-7,-7),(*wpt)->icon);
        if(!wptIsMoving) {
            p.setPen(Qt::darkBlue);
            p.setBrush(Qt::darkBlue);
            p.drawText(pt2 + QPoint(11,-8),(*wpt)->ident);
        }
        ++wpt;
    }

    // draw distance line for moving waypoints
    if(wptIsMoving) {
        XY pt1,pt2;
        pt1.u = DEG_TO_RAD * wptStartDeg.u;
        pt1.v = DEG_TO_RAD * wptStartDeg.v;

        pt2.u = DEG_TO_RAD * m_lon;
        pt2.v = DEG_TO_RAD * m_lat;

        double a1 = 0,a2 = 0;
        double d = gpProj->distance(pt1,pt2,a1,a2);

        pt1 = pj_fwd(pt1,*gpProj);

        wptStartPx = QPoint(map->u2px(pt1.u),map->v2px(pt1.v));

        p.setPen(Qt::darkBlue);
        p.drawLine(wptStartPx,m_pos);

        // distance and azimuth
        QString str;
        str = QString(" %1 %2\260> <%3\260 ").arg(gpResources->distance2str(d)).arg(a1,0,'f',0).arg(a2,0,'f',0);

        QRect r = p.boundingRect(QRect(m_pos + QPoint(11,-QFontMetrics(p.font()).height()),QSize(1,1)),Qt::AlignLeft, str);

        p.setBrush(QBrush( QColor(220,220,255,220) ));
        p.setPen(QColor(150,150,255));
        p.drawRect(r);
        p.setPen(Qt::darkBlue);
        p.setBrush(Qt::darkBlue);
        p.drawText(r,Qt::AlignLeft,str);
        p.setPen(Qt::darkBlue);
        p.setBrush(Qt::white);
        p.drawEllipse(wptStartPx.x() - 3 ,wptStartPx.y() - 3,5,5);
        p.drawEllipse(m_pos.x() - 3 ,m_pos.y() - 3,5,5);
    }
}


void CCanvas::drawSelectedMaps(QPainter& p)
{
    // draw selected map overlays only in map mode
    if(gpResources->fsm().getMode() != CFunctionStateMachine::eMap) return;

    // draw transparent overlay for selected maps
    p.setBrush(QBrush( QColor(230,230,255,80) ));
    p.setPen(QColor(50,50,255));
    const QList<CGarminDBMap::tile_t*>& tiles = gpResources->mapdb().getSelectedTiles();
    QList<CGarminDBMap::tile_t*>::const_iterator tile = tiles.begin();
    while(tile != tiles.end()) {
        QPolygonF poly; XY pt;

        foreach(pt,(*tile)->definitionArea) {
            poly << QPointF(map->u2px(pt.u),map->v2px(pt.v));
        }
        p.drawPolygon(poly);

        ++tile;
    }

    // draw select rectangle
    QRect rect = rectSelect.normalized();
    if(!rect.isEmpty()) {
        p.setBrush(QBrush( QColor(230,230,255,100) ));
        p.setPen(QColor(150,150,255));
        p.drawRect(rect);
    }

}


void CCanvas::drawZoomRect(QPainter& p)
{
    // draw zoom rectangle
    QRect rect = rectZoom.normalized();
    if(!rect.isEmpty()) {
        p.setBrush(QBrush( QColor(230,230,255,100) ));
        p.setPen(QColor(150,150,255));
        p.drawRect(rect);
    }
}


void CCanvas::drawInfoCursor(QPainter& p)
{
    // draw cursor for selected polylines
    if(!infoScreen->isHidden()) {
        double x = map->u2px(infoPoint.x());
        double y = map->v2px(infoPoint.y());
        p.setPen(Qt::black);
        p.setBrush(QColor(255,100,100));
        p.drawEllipse((int)x - 4 ,(int)y - 4,10,10);
        p.setPen(Qt::red);
        p.setBrush(Qt::red);
        p.drawEllipse((int)x - 3 ,(int)y - 3,6,6);
        p.setPen(Qt::yellow);
        p.setBrush(Qt::yellow);
        p.drawEllipse((int)x - 2 ,(int)y - 2,3,3);
    }
}


void CCanvas::drawSearchResultMark(QPainter& p)
{
    // draw location marker for found and selected points
    if(!searchPoint.isNull()) {
        int x = (int)map->u2px(searchPoint.x());
        int y = (int)map->v2px(searchPoint.y());
        if(rect().contains(x,y)) {

            p.setBrush(QBrush( QColor(220,220,255,220) ));
            p.setPen(QColor(150,150,255));
            p.drawEllipse(x - 4 ,y - 4,9,9);

            QRect r = p.boundingRect(QRect(),Qt::AlignLeft|Qt::AlignVCenter,searchPointInfo);
            r.moveBottomLeft(QPoint(x+10,y-10));
            p.drawRect(r);

            p.setPen(Qt::blue);
            p.setBrush(Qt::blue);
            p.drawEllipse(x - 1 ,y - 1,2,2);
            p.setPen(Qt::darkBlue);
            p.setBrush(Qt::darkBlue);
            p.drawText(r,searchPointInfo);
        }
    }
}


void CCanvas::drawCacheSearchRadius(QPainter& p)
{
    // draw search radius for geo cache search
    if(defineSearch) {
        QPointF p1(searchCenter.x() - searchRadius, searchCenter.y() - searchRadius);
        p.setBrush(QBrush( QColor(230,230,255,100) ));
        p.setPen(QColor(150,150,255));
        p.drawEllipse((int)p1.x(),(int)p1.y(),2*searchRadius,2*searchRadius);

        p.setPen(Qt::darkBlue);

        p.drawLine((int)searchCenter.x(), (int)searchCenter.y()
            ,(int)searchCenter.x() + searchRadius, (int)searchCenter.y());

        int fontheight = QFontMetrics(p.font()).height();
        QString str = gpResources->distance2str(radius);
        p.drawText(QRectF(searchCenter.x(),searchCenter.y(),searchRadius,-fontheight)
            ,Qt::AlignCenter,gpResources->distance2str(radius));
    }

}


void CCanvas::drawLiveLogPosition(QPainter& p)
{
    CGarminLiveLog::Pvt_t * pvt = gpResources->livelog().getPosition();
    if(pvt == 0) return;

    XY pos;
    pos.u = pvt->lon * DEG_TO_RAD;
    pos.v = pvt->lat * DEG_TO_RAD;

    pos = pj_fwd(pos,*gpProj);

    QMultiMap<QString,QString> dict;
    QPointF streetPoint;

    streetPoint.setX(pos.u);
    streetPoint.setY(pos.v);

    gpResources->mapdb().getInfo(streetPoint,dict,map,true);

    if (!dict.isEmpty()) {
        pos.u=(double)streetPoint.x();
        pos.v=(double)streetPoint.y();
    }

    int x = (int)map->u2px(pos.u);
    int y = (int)map->v2px(pos.v);

    int rh = (int)map->u2px(pos.u + pvt->eph) - x;

    p.setBrush(Qt::NoBrush);

    if(rh > 6) {
        p.setPen(QPen(Qt::black,3));
        p.drawEllipse(x - rh/2, y - rh/2,rh,rh);
        p.setPen(QPen(Qt::white,1));
        p.drawEllipse(x - rh/2, y - rh/2,rh,rh);
    }

    float heading = pvt->heading();
    if(isnan(heading) || pvt->velocity()*3.6<0.2) {
        p.setPen(QPen(Qt::black,3));
        p.drawLine(x-4,y,x+4,y);
        p.drawLine(x,y-4,x,y+4);
        p.setPen(QPen(Qt::white,1));
        p.drawLine(x-3,y,x+3,y);
        p.drawLine(x,y-3,x,y+3);
    }
    else {
        p.save();
        p.translate(x,y);
        p.rotate(heading);
        p.drawPixmap(-8,-12,headingPixmap);
        p.restore();
    }

}


void CCanvas::drawRoutes(QPainter& p)
{
    double a1 = 0, a2 = 0, d = 0;
    XY pt1,pt2;

    CGarminRoute * actRoute = gpResources->routedb().getCurrentRoute();

    // draw rubber band to position of cursor
    if(actRoute && actRoute->routeMeter.size() && mouseMode == eMouseEditRte) {
        // distance and azimuth
        pt1 = actRoute->routeDegree.last();
        pt1.u *= DEG_TO_RAD;
        pt1.v *= DEG_TO_RAD;
        pt2.u = m_lon * DEG_TO_RAD;
        pt2.v = m_lat * DEG_TO_RAD;
        d = gpProj->distance(pt1,pt2,a1,a2);

        QString str = QString(" %1 %2\260> <%3\260 ").arg(gpResources->distance2str(d)).arg(a1,0,'f',0).arg(a2,0,'f',0);
        QRect   r   = p.boundingRect(QRect(m_pos + QPoint(11,-p.fontMetrics().height()),QSize(1,1)),Qt::AlignLeft, str);

        p.setBrush(QBrush( QColor(220,220,255,220) ));
        p.setPen(QColor(150,150,255));
        p.drawRect(r);
        p.setPen(Qt::darkBlue);
        p.setBrush(Qt::darkBlue);
        p.drawText(r,Qt::AlignLeft,str);

        pt1 = actRoute->routeMeter.last();
        QPoint routeLastPoint = QPoint(map->u2px(pt1.u),map->v2px(pt1.v));

        p.setPen(QPen(Qt::magenta,2));
        p.drawLine(routeLastPoint,m_pos);
    }

    // draw all other routes
    routePolyline.clear();
    const QMap<QString,CGarminRoute*>& distances = gpResources->routedb().getDistanceDict();
    QMap<QString,CGarminRoute*>::const_iterator route = distances.begin();
    while(route != distances.end()) {
        drawRoutePolygon(*route, *route == actRoute, p);
        ++route;
    }

    const QMap<QString,CGarminRoute*>& routes = gpResources->routedb().getRouteDict();
    route = routes.begin();
    while(route != routes.end()) {
        drawRoutePolygon(*route, *route == actRoute, p);
        ++route;
    }
}


void CCanvas::drawRoutePolygon(CGarminRoute * route, bool isActRoute, QPainter& p)
{
    double a1 = 0, a2 = 0, d = 0;
    XY pt1,pt2;

    QPolygon line;
    XY pt;

    foreach(pt,route->routeMeter) {
        line << QPoint(map->u2px(pt.u),map->v2px(pt.v));
    }

    // actual route is special case
    if(isActRoute) {
        routePolyline = line;
        p.setPen(QPen(Qt::magenta,5));
        p.drawPolyline(routePolyline);
        p.setPen(QPen(Qt::white,1));
        p.drawPolyline(routePolyline);

        QPoint pt;
        foreach(pt,routePolyline) {

            // draw position cursor mark if necessary
            if(routeCursorPoint.valid && routeCursorPoint.pt == pt) {
                p.setPen(Qt::black);
                p.setBrush(Qt::magenta);
                p.drawEllipse(pt.x() - 4 ,pt.y() - 4,9,9);
            }
            else {
                p.setPen(Qt::magenta);
                p.setBrush(Qt::white);
                p.drawEllipse(pt.x() - 3 ,pt.y() - 3,7,7);
            }

            // draw distance information prev -> current
            if(selRoutePoint.valid && selRoutePoint.pt == pt) {
                if(selRoutePointPrev.valid) {
                    pt1 = selRoutePointPrev.pos;
                    pt2 = selRoutePoint.pos;
                    pt1.u *= DEG_TO_RAD;
                    pt1.v *= DEG_TO_RAD;
                    pt2.u *= DEG_TO_RAD;
                    pt2.v *= DEG_TO_RAD;
                    d = gpProj->distance(pt1,pt2,a1,a2);

                    QString str = QString("%1: %2 %3\260> <%4\260 ").arg(tr("pt1")).arg(gpResources->distance2str(d)).arg(a1,0,'f',0).arg(a2,0,'f',0);
                    QRect   r   = p.boundingRect(QRect(m_pos + QPoint(11,-p.fontMetrics().height()),QSize(1,1)),Qt::AlignLeft, str);

                    p.setBrush(QBrush( QColor(220,220,255,220) ));
                    p.setPen(QColor(150,150,255));
                    p.drawRect(r);
                    p.setPen(Qt::darkBlue);
                    p.setBrush(Qt::darkBlue);
                    p.drawText(r,Qt::AlignLeft,str);

                    p.drawText(selRoutePointPrev.pt  + QPoint(5,5),tr("pt1"));
                }

                // draw distance information current -> next
                if(selRoutePointNext.valid) {
                    pt1 = selRoutePointNext.pos;
                    pt2 = selRoutePoint.pos;
                    pt1.u *= DEG_TO_RAD;
                    pt1.v *= DEG_TO_RAD;
                    pt2.u *= DEG_TO_RAD;
                    pt2.v *= DEG_TO_RAD;
                    d = gpProj->distance(pt1,pt2,a1,a2);

                    QString str = QString("%1: %2 %3\260> <%4\260 ").arg(tr("pt2")).arg(gpResources->distance2str(d)).arg(a1,0,'f',0).arg(a2,0,'f',0);
                    QRect   r   = p.boundingRect(QRect(m_pos + QPoint(-11 -p.fontMetrics().width(str) ,-p.fontMetrics().height()),QSize(1,1)),Qt::AlignLeft, str);

                    p.setBrush(QBrush( QColor(220,220,255,220) ));
                    p.setPen(QColor(150,150,255));
                    p.drawRect(r);
                    p.setPen(Qt::darkBlue);
                    p.setBrush(Qt::darkBlue);
                    p.drawText(r,Qt::AlignLeft,str);

                    p.drawText(selRoutePointNext.pt + QPoint(5,5),tr("pt2"));
                }

            }

        }
    }
    else {
        p.setPen(QPen(Qt::darkYellow,5));
        p.drawPolyline(line);
        p.setPen(QPen(Qt::white,1));
        p.drawPolyline(line);
    }

}


void CCanvas::enterEvent(QEvent * )
{
    QApplication::setOverrideCursor(cursor);
}


void CCanvas::leaveEvent(QEvent * )
{
    QApplication::restoreOverrideCursor();
}


void CCanvas::mousePressEvent(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        if(trkpt1st) {
            CGarminTrack * track = gpResources->trackdb().highlightedTrack();
            if(track) {
                track->setPointOfFocus(trkpt1st->idx);
            }
        }

        if(waypoint) {
            waypoint->select();
        }
    }
    (this->*pfMousePressEvent)(e);
}


void CCanvas::mouseMoveEvent(QMouseEvent * e)
{
    m_pos = e->pos();

    mouseMoveEventCoord(e);
    mouseMoveEventSelWpt(e);
    mouseMoveEventSelTrk(e);
    mouseMoveEventSelElem(e);

    (this->*pfMouseMoveEvent)(e);
}


void CCanvas::mouseMoveEventCoord(QMouseEvent * e)
{
    // set cursor coordinates in statusbar
    double u = (double)e->pos().x();
    double v = (double)e->pos().y();
    map->convertPt2Deg(u,v);

    m_lon = u;
    m_lat = v;

    qint32 degN,degE;
    double minN,minE;

    GPS_Math_Deg_To_DegMin(v, &degN, &minN);

    GPS_Math_Deg_To_DegMin(u, &degE, &minE);

    QString str,lat,lng;
    lat = degN < 0 ? "S" : "N";
    lng = degE < 0 ? "W" : "E";
    str.sprintf(" %s%02d\260 %06.3f %s%03d\260 %06.3f ",lat.toUtf8().data(),abs(degN),minN,lng.toUtf8().data(),abs(degE),minE);

    coord->setText(str);

}


void CCanvas::mouseMoveEventSelWpt(QMouseEvent * e)
{
    // try to select waypoint
    if(!wptIsMoving) {
        waypoint = 0;
        const QMap<QString,CGarminWpt*>& waypoints = gpResources->wptdb().getWaypoints();
        QMap<QString,CGarminWpt*>::const_iterator wpt = waypoints.begin();
        while(wpt != waypoints.end()) {
            XY pt1;
            pt1.u = DEG_TO_RAD * (*wpt)->lon;
            pt1.v = DEG_TO_RAD * (*wpt)->lat;
            pt1 = pj_fwd(pt1,*gpProj);

            QPoint pt2(map->u2px(pt1.u),map->v2px(pt1.v));

            int d = abs(pt2.x() - e->pos().x()) + abs(pt2.y() - e->pos().y());

            if(d < 20) {
                waypoint    = (*wpt);
                wptkey      = wpt.key();
                update();
                break;
            }
            ++wpt;
        }
    }
}


void CCanvas::mouseMoveEventSelTrk(QMouseEvent *)
{
    // try to find point in selected track
    // reset cursor flag
    if(trkpt1st) {
        trkpt1st->flags &= ~CGarminTrack::eCursor;
    }

    // temp. hold last trakpoint to detect changes in selection at the end
    Garmin::TrkPt_t * oldTrackpoint = trkpt1st;

    // reset pointer to first and second trackpoint
    trkpt1st = 0;
    trkpt2nd = 0;

    // depending on the mouse mode the first and second trackpoint pointer are
    // handled different. In normal (no cut track) mode only the first trackpoint
    // pointer is moved to operatie the cursor flag. In cut track mode both pointers
    // are moved to subsequent visible points. No cursor flag is operated in this
    // mode
    if(mouseMode == eMouseCutTrack) {
        QMap<QString,CGarminTrack*>& tracks = gpResources->trackdb().getTracks();
        QMap<QString,CGarminTrack*>::iterator track = tracks.begin();
        while(track != tracks.end()) {
            if((*track)->isHighlighted()) {
                QVector<CGarminTrack::TrkPt_t>::iterator trkpt1 = (*track)->begin();
                QVector<CGarminTrack::TrkPt_t>::iterator trkpt2 = (*track)->begin();

                // skip leading deleted points
                while((trkpt1->flags & CGarminTrack::eDeleted) && (trkpt1 != (*track)->end())) {
                    ++trkpt1; ++trkpt2;
                }

                int d1 = 20;
                while(++trkpt2 != (*track)->end()) {
                    if(trkpt2->flags & CGarminTrack::eDeleted) {
                        ++trkpt2; continue;
                    }
                    int d2 = abs(m_pos.x() - trkpt1->point.x()) + abs(m_pos.y() - trkpt1->point.y());
                    if(d2 < d1) {
                        trkpt1st = &(*trkpt1);
                        trkpt2nd = &(*trkpt2);
                        d1 = d2;
                    }
                    trkpt1 = trkpt2;
                }
            }
            ++track;
        }
    }
    else {

        QMap<QString,CGarminTrack*>& tracks = gpResources->trackdb().getTracks();
        QMap<QString,CGarminTrack*>::iterator track = tracks.begin();
        // Iterate over all tracks. Use only the highlighted one
        while(track != tracks.end()) {

            if((*track)->isHighlighted()) {
                int d1 = 20;
                QVector<CGarminTrack::TrkPt_t>::iterator trkpt1 = (*track)->begin();
                // test all points for manhatten distance less than threshold
                while(trkpt1 != (*track)->end()) {
                    if(trkpt1->flags & CGarminTrack::eDeleted) {
                        ++trkpt1; continue;
                    }
                    int d2 = abs(m_pos.x() - trkpt1->point.x()) + abs(m_pos.y() - trkpt1->point.y());
                    if(d2 < d1) {
                        trkpt1st = &(*trkpt1);
                        d1 = d2;
                    }
                    ++trkpt1;
                }
            }
            ++track;
        }
        if(trkpt1st) {
            trkpt1st->flags |= CGarminTrack::eCursor;
        }
    }

    // update the screen if the trackpoint focus changed
    if(oldTrackpoint != trkpt1st) update();
}


void CCanvas::mouseMoveEventSelElem(QMouseEvent * e)
{
    // get info about map elements close to mouse pointer
    if(e->buttons() == Qt::NoButton && showInfo) {
        QMultiMap<QString,QString> dict;
        double u = (double)e->pos().x();
        double v = (double)e->pos().y();
        map->convertPt2M(u,v);
        infoPoint.setX(u);
        infoPoint.setY(v);
        gpResources->mapdb().getInfo(infoPoint,dict,map);

        QString key;
        QStringList keys = dict.uniqueKeys();
        qSort(keys);

        info.clear();
        foreach(key,keys) {
            info += "<b>" + key + ":</b><br/>";
            const QStringList& values = dict.values(key).toSet().toList();
            info += values.join("<br/>");
            info += "<br/>";
        }

        infoScreen->clear();
        infoScreen->setFont(gpResources->getMapFont());
        if(!info.isEmpty()) {
            infoScreen->show();
            infoScreen->setText(info);
            infoScreen->adjustSize();
            update();
        }
        else {
            infoScreen->hide();
        }
    }
    else {
        infoScreen->hide();
    }
}


void CCanvas::mouseReleaseEvent(QMouseEvent * e)
{
    (this->*pfMouseReleaseEvent)(e);
}


void CCanvas::mousePressMoveArea(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        QApplication::setOverrideCursor(QCursor(cursorMoveAreaActive));
        map->setEasyDraw(true);
        moveMap     = true;
        oldPoint    = e->pos();
    }
    else if(e->button() == Qt::RightButton) {
        QPoint p = mapToGlobal(e->pos());
        contextMenu->exec(p);
    }
}


void CCanvas::mouseMoveMoveArea(QMouseEvent * e)
{
    if(moveMap) {
        map->move(oldPoint, e->pos());
        oldPoint = e->pos();
        update();
    }
}


void CCanvas::mouseReleaseMoveArea(QMouseEvent * e)
{
    if(moveMap && (e->button() == Qt::LeftButton)) {
        moveMap = false;
        map->setEasyDraw(false);
        QApplication::restoreOverrideCursor();
        update();
    }
}


void CCanvas::mousePressZoomArea(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        zoomMap = true;
        rectZoom.moveTopLeft(e->pos());
    }
}


void CCanvas::mouseMoveZoomArea(QMouseEvent * e)
{
    if(zoomMap) {
        rectZoom.setBottomRight(e->pos());
        update();
    }
}


void CCanvas::mouseReleaseZoomArea(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        map->zoom(rectZoom);
        zoomMap     = false;
        rectZoom    = QRect();
        setMouseMode(eMouseMoveArea);
        update();
    }
}


void CCanvas::mousePressSelectArea(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        selectMap = true;
        rectSelect.moveTopLeft(e->pos());
    }
}


void CCanvas::mouseMoveSelectArea(QMouseEvent * e)
{
    if(selectMap) {
        rectSelect.setBottomRight(e->pos());
        update();
    }
}


void CCanvas::mouseReleaseSelectArea(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {

        XY pt;
        QVector<XY> area;

        pt.u = map->px2u(rectSelect.left());
        pt.v = map->px2v(rectSelect.top());
        area << pt;
        pt.u = map->px2u(rectSelect.right());
        pt.v = map->px2v(rectSelect.top());
        area << pt;
        pt.u = map->px2u(rectSelect.right());
        pt.v = map->px2v(rectSelect.bottom());
        area << pt;
        pt.u = map->px2u(rectSelect.left());
        pt.v = map->px2v(rectSelect.bottom());
        area << pt;

        gpResources->mapdb().selectTiles(area);
        selectMap   = false;
        rectSelect  = QRect();
        update();
    }
}


void CCanvas::mousePressNewWpt(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        gpResources->wptdb().newWaypoint();
        setMouseMode(eMouseMoveArea);
    }
}


void CCanvas::mousePressEditWpt(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton && waypoint) {
        gpResources->wptdb().editWaypoint(wptkey);
    }
}


void CCanvas::mouseMoveEditWpt(QMouseEvent * )
{
}


void CCanvas::mouseReleaseEditWpt(QMouseEvent * )
{

}


void CCanvas::mousePressMoveWpt(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton && waypoint && !wptIsMoving) {
        wptIsMoving = true;
        wptStartDeg.u = waypoint->lon;
        wptStartDeg.v = waypoint->lat;
    }
    else if(e->button() == Qt::LeftButton && waypoint && wptIsMoving) {
        wptIsMoving = false;
        update();
    }
    else if(e->button() == Qt::RightButton && waypoint && wptIsMoving) {
        waypoint->lon = wptStartDeg.u;
        waypoint->lat = wptStartDeg.v;
        wptIsMoving = false;
        update();
    }
}


void CCanvas::mouseMoveMoveWpt(QMouseEvent * )
{
    if(waypoint && wptIsMoving) {
        waypoint->lon = m_lon;
        waypoint->lat = m_lat;
        update();
    }
}


void CCanvas::mouseReleaseMoveWpt(QMouseEvent * )
{
}


void CCanvas::mousePressSearchOC(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        searchCenter = e->pos();
        defineSearch = true;
    }
}


void CCanvas::mouseMoveSearchOC(QMouseEvent * e)
{
    if(defineSearch) {
        QPointF p = e->pos();

        XY p1,p2;
        double a1 = 0, a2 = 0;
        p1.u = searchCenter.x();
        p1.v = searchCenter.y();
        map->convertPt2Rad(p1.u,p1.v);

        p2.u = (double)e->pos().x();
        p2.v = (double)e->pos().y();
        map->convertPt2Rad(p2.u,p2.v);
        radius = gpProj->distance(p1,p2,a1,a2);

        if(radius > 250000.0) {
            radius = 250000.0;
        }
        else {
            searchRadius = (quint32)sqrt((e->pos().x() - searchCenter.x())*(e->pos().x() - searchCenter.x()) + (e->pos().y() - searchCenter.y())*(e->pos().y() - searchCenter.y()));
        }
        update();
    }
}


void CCanvas::mouseReleaseSearchOC(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton && defineSearch) {
        defineSearch = false;
        XY p1,p2;
        double a1 = 0, a2 = 0;
        p1.u = searchCenter.x();
        p1.v = searchCenter.y();
        map->convertPt2Rad(p1.u,p1.v);

        p2.u = (double)e->pos().x();
        p2.v = (double)e->pos().y();
        map->convertPt2Rad(p2.u,p2.v);
        radius = gpProj->distance(p1,p2,a1,a2);
        if(radius > 250000.0) radius = 250000.0;

        double lon = searchCenter.x();
        double lat = searchCenter.y();
        map->convertPt2Deg(lon,lat);

        gpResources->wptdb().queryOpenChachingDe(lon,lat,radius);
        update();

        setMouseMode(eMouseMoveArea);
    }
}


void CCanvas::mousePressCutTrack(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        if(trkpt1st && trkpt2nd && (trkpt1st != trkpt2nd)) {
            gpResources->trackdb().split(trkpt1st->idx);
        }
    }
}


void CCanvas::mouseMoveCutTrack(QMouseEvent * )
{
}


void CCanvas::mouseReleaseCutTrack(QMouseEvent * )
{
}


void CCanvas::mousePressEditRte(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        CGarminRoute * actRoute  = gpResources->routedb().getCurrentRoute();
        if(actRoute == 0) return;

        double lon = 0, lat = 0;
        getCursorPos(lon,lat);
        actRoute->addPosition(lon,lat);
    }
}


void CCanvas::mouseMoveEditRte(QMouseEvent * /*e*/)
{
    update();
}


void CCanvas::mouseReleaseEditRte(QMouseEvent * /*e*/)
{
}


void CCanvas::mousePressMoveRte(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton) {
        selRoutePoint.valid = selRoutePoint.valid ? false : routeCursorPoint.valid;
        selRoutePoint.idx   = selRoutePoint.valid ? selRoutePoint.idx : -1;
    }
}


void CCanvas::mouseMoveMoveRte(QMouseEvent * /*e*/)
{

    CGarminRoute * actRoute = gpResources->routedb().getCurrentRoute();

    if(selRoutePoint.valid && actRoute) {
        actRoute->movePosition(selRoutePoint.idx,m_lon,m_lat);
        selRoutePoint.pos.u = m_lon;
        selRoutePoint.pos.v = m_lat;
        selRoutePoint.pt    = m_pos;
        update();
        return;
    }

    QPoint pt;
    bool oldFlag = routeCursorPoint.valid;

    routeCursorPoint.valid = false;

    foreach(pt,routePolyline) {
        if( (abs(pt.x() - m_pos.x()) + abs(pt.y() - m_pos.y())) < 5) {
            routeCursorPoint.pt     = pt;
            routeCursorPoint.valid  = true;

            // selected point has to be made valid by a mouse click. see CCanvas::mousePressMoveRte()
            selRoutePoint.idx       = routePolyline.indexOf(pt);
            selRoutePoint.pos       = actRoute->getPosition(selRoutePoint.idx);
            selRoutePoint.pt        = pt;

            selRoutePointPrev.idx   = selRoutePoint.idx - 1;
            selRoutePointPrev.valid = selRoutePointPrev.idx >= 0;
            selRoutePointPrev.pos   = actRoute->getPosition(selRoutePointPrev.idx);
            selRoutePointPrev.pt    = selRoutePointPrev.valid ? routePolyline[selRoutePointPrev.idx] : QPoint();

            selRoutePointNext.idx   = selRoutePoint.idx + 1;
            selRoutePointNext.valid = selRoutePointNext.idx < routePolyline.size();
            selRoutePointNext.pos   = actRoute->getPosition(selRoutePointNext.idx);
            selRoutePointNext.pt    = selRoutePointNext.valid ? routePolyline[selRoutePointNext.idx] : QPoint();

        }
    }

    if(oldFlag != routeCursorPoint.valid) update();

}


void CCanvas::mouseReleaseMoveRte(QMouseEvent * /*e*/)
{

}


void CCanvas::mousePressDelRte(QMouseEvent * e)
{
    if(e->button() == Qt::LeftButton && routeCursorPoint.valid) {
        CGarminRoute * actRoute = gpResources->routedb().getCurrentRoute();
        if(actRoute) {
            actRoute->delPosition(selRoutePoint.idx);
        }
        routeCursorPoint.reset(); selRoutePoint.reset();
    }
}


void CCanvas::mouseMoveDelRte(QMouseEvent * e)
{
    mouseMoveMoveRte(e);
}


void CCanvas::mouseReleaseDelRte(QMouseEvent * /*e*/)
{
}


void CCanvas::wheelEvent(QWheelEvent * e)
{
    zoom((e->delta() < 0), e->pos());
}


void CCanvas::fitMapToScreen()
{
    map->world();
    update();
}


void CCanvas::incDetails()
{
    map->incDetails();
    update();
}


void CCanvas::decDetails()
{
    map->decDetails();
    update();
}


void CCanvas::toggleCityNames()
{
    details1->checkCity->setChecked(!map->seeCityNames());
}


void CCanvas::slotToggleCityNames()
{
    map->toggleCityNames();
    update();
}


void CCanvas::togglePOIs()
{
    details1->checkPOI->setChecked(!map->seePOIs());
}


void CCanvas::slotTogglePOIs()
{
    map->togglePOIs();
    update();
}


void CCanvas::toggleStreetNames()
{
    details1->checkStreet->setChecked(!map->seeStreetNames());
}


void CCanvas::slotToggleStreetNames()
{
    map->toggleStreetNames();
    update();
}


void CCanvas::toggleInfo()
{
    showInfo = !showInfo;
    showInfo ? infoScreen->show() : infoScreen->hide();
    update();
}


void CCanvas::slotCopyPosition()
{
    QClipboard *clipboard = QApplication::clipboard();
    clipboard->setText(coord->text());
}

Generated by  Doxygen 1.6.0   Back to index