Add more patches
authorDennis Nienhüser <nienhues@fzi.de>
Sun, 19 Dec 2010 21:58:14 +0000 (16:58 -0500)
committerDennis Nienhüser <nienhues@fzi.de>
Sun, 19 Dec 2010 21:58:14 +0000 (16:58 -0500)
packaging/debian/patches/fastmercator.diff [new file with mode: 0644]
packaging/debian/patches/install-lang-files.diff [new file with mode: 0644]
packaging/debian/patches/series
packaging/debian/patches/tracking-dialog.diff [new file with mode: 0644]

diff --git a/packaging/debian/patches/fastmercator.diff b/packaging/debian/patches/fastmercator.diff
new file mode 100644 (file)
index 0000000..5f60db3
--- /dev/null
@@ -0,0 +1,257 @@
+Index: marble-0.85+svn1207808/src/lib/AbstractScanlineTextureMapper.cpp
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/AbstractScanlineTextureMapper.cpp      2010-12-19 16:51:17.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/AbstractScanlineTextureMapper.cpp   2010-12-19 16:51:30.000000000 -0500
+@@ -36,8 +36,8 @@
+       m_tileLoader( tileLoader ),
+       m_tilePosX( 0 ),
+       m_tilePosY( 0 ),
+-      m_textureLayer( textureLayer ),
+       m_tileSize( textureLayer->tileSize() ),  // cache tile size
++      m_textureLayer( textureLayer ),
+       m_tile( 0 ),
+       m_previousRadius( 0 ),
+       m_tileLevel( 0 ),
+Index: marble-0.85+svn1207808/src/lib/AbstractScanlineTextureMapper.h
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/AbstractScanlineTextureMapper.h        2010-12-19 16:51:17.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/AbstractScanlineTextureMapper.h     2010-12-19 16:51:30.000000000 -0500
+@@ -120,24 +120,26 @@
+     int          m_tilePosX;
+     int          m_tilePosY;
++    /// size of the tiles of of the current texture layer
++    QSize const m_tileSize;
++
++    int         m_tileLevel;
++    uint        m_mapThemeIdHash;
++
+  private:
+     Q_DISABLE_COPY( AbstractScanlineTextureMapper )
+     void initGlobalWidth();
+     void initGlobalHeight();
+     GeoSceneTexture const * const m_textureLayer;
+-    /// size of the tiles of of the current texture layer
+-    QSize const m_tileSize;
+     StackedTile *m_tile;
+     int         m_previousRadius;
+-    int         m_tileLevel;
+     int         m_maxTileLevel;
+     int         m_globalWidth;
+     int         m_globalHeight;
+     qreal       m_normGlobalWidth;
+     qreal       m_normGlobalHeight;
+-    uint        m_mapThemeIdHash;
+ };
+ inline bool AbstractScanlineTextureMapper::interlaced() const
+Index: marble-0.85+svn1207808/src/lib/CMakeLists.txt
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/CMakeLists.txt 2010-12-19 16:51:17.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/CMakeLists.txt      2010-12-19 16:51:30.000000000 -0500
+@@ -130,6 +130,7 @@
+     SphericalScanlineTextureMapper.cpp
+     EquirectScanlineTextureMapper.cpp
+     MercatorScanlineTextureMapper.cpp
++    FastMercatorTextureMapper.cpp
+     DiscCache.cpp
+     ServerLayout.cpp
+     StoragePolicy.cpp
+Index: marble-0.85+svn1207808/src/lib/FastMercatorTextureMapper.cpp
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ marble-0.85+svn1207808/src/lib/FastMercatorTextureMapper.cpp       2010-12-19 16:51:30.000000000 -0500
+@@ -0,0 +1,124 @@
++//
++// This file is part of the Marble Virtual Globe.
++//
++// This program is free software licensed under the GNU LGPL. You can
++// find a copy of this license in LICENSE.txt in the top directory of
++// the source code.
++//
++// Copyright 2010      Bernhard Beschow <bbeschow@cs.tu-berlin.de>
++//
++
++
++// local
++#include"FastMercatorTextureMapper.h"
++
++// posix
++#include <cmath>
++
++// Qt
++#include <QtCore/qmath.h>
++#include <QtGui/QImage>
++#include <QtGui/QPainter>
++
++// Marble
++#include "StackedTileLoader.h"
++#include "ViewParams.h"
++#include "TileLoaderHelper.h"
++#include "StackedTile.h"
++#include "MathHelper.h"
++
++using namespace Marble;
++
++FastMercatorTextureMapper::FastMercatorTextureMapper( GeoSceneTexture *textureLayer,
++                                                      StackedTileLoader *tileLoader,
++                                                      QObject *parent )
++    : AbstractScanlineTextureMapper( textureLayer, tileLoader, parent ),
++      m_oldYPaintedTop( 0 )
++{
++}
++
++
++void FastMercatorTextureMapper::mapTexture( ViewParams *viewParams )
++{
++    QImage       *canvasImage = viewParams->canvasImage();
++    const int imageHeight = canvasImage->height();
++    const int imageWidth  = canvasImage->width();
++    const qint64  radius      = viewParams->radius();
++
++    m_tilePosX = 65535;
++    m_tilePosY = 65535;
++    m_toTileCoordinatesLon = (qreal)(globalWidth() / 2 - m_tilePosX);
++    m_toTileCoordinatesLat = (qreal)(globalHeight() / 2 - m_tilePosY);
++
++    // Reset backend
++    m_tileLoader->resetTilehash();
++    selectTileLevel( viewParams );
++
++    // Calculate translation of center point
++    qreal centerLon, centerLat;
++
++    viewParams->centerCoordinates( centerLon, centerLat );
++
++    const qreal xNormalizedCenter = 0.5 + 0.5 * centerLon / M_PI;
++    const int numTilesX = globalWidth() / m_tileSize.width();
++    const int minTileX = qFloor( numTilesX * ( xNormalizedCenter - imageWidth/( 8.0 * radius ) ) );
++    const int maxTileX = numTilesX * ( xNormalizedCenter + imageWidth/( 8.0 * radius ) );
++
++    const qreal yNormalizedCenter = 0.5 - 0.5 * asinh( tan( centerLat ) ) / M_PI;
++    const int numTilesY = globalHeight() / m_tileSize.height();
++    const int minTileY = qMax( numTilesY * ( yNormalizedCenter - imageHeight/( 8.0 * radius ) ), 0.0 );
++    const int maxTileY = qMin( numTilesY * ( yNormalizedCenter + imageHeight/( 8.0 * radius ) ), numTilesY - 1.0 );
++
++    QPainter painter( canvasImage );
++
++    for ( int tileY = minTileY; tileY <= maxTileY; ++tileY ) {
++        for ( int tileX = minTileX; tileX <= maxTileX; ++tileX ) {
++            const int xLeft   = ( 4.0 * radius ) * ( ( tileX     ) / (qreal)numTilesX - xNormalizedCenter + imageWidth/( 8.0 * radius ) );
++            const int xRight  = ( 4.0 * radius ) * ( ( tileX + 1 ) / (qreal)numTilesX - xNormalizedCenter + imageWidth/( 8.0 * radius ) ) - 1;
++            const int yTop    = ( 4.0 * radius ) * ( ( tileY     ) / (qreal)numTilesY - yNormalizedCenter + imageHeight/( 8.0 * radius ) );
++            const int yBottom = ( 4.0 * radius ) * ( ( tileY + 1 ) / (qreal)numTilesY - yNormalizedCenter + imageHeight/( 8.0 * radius ) ) - 1;
++
++            const QRect rect = QRect( QPoint( xLeft, yTop ), QPoint( xRight, yBottom ) );
++            const TileId id = TileId( m_mapThemeIdHash, m_tileLevel, ( ( tileX % numTilesX ) + numTilesX ) % numTilesX, tileY );
++            StackedTile *const tile = m_tileLoader->loadTile( id, DownloadBrowse );
++
++            painter.drawImage( rect, *tile->resultTile() );
++        }
++    }
++
++    painter.end();
++
++    int yTop;
++    int yPaintedTop;
++    int yPaintedBottom;
++
++    // Calculate y-range the represented by the center point, yTop and
++    // what actually can be painted
++    yPaintedTop = yTop = (     - yNormalizedCenter ) * ( 4 * radius ) + imageHeight / 2;
++    yPaintedBottom    = ( 1.0 - yNormalizedCenter ) * ( 4 * radius ) + imageHeight / 2;
++
++    if (yPaintedTop < 0)                yPaintedTop = 0;
++    if (yPaintedTop > imageHeight)    yPaintedTop = imageHeight;
++    if (yPaintedBottom < 0)             yPaintedBottom = 0;
++    if (yPaintedBottom > imageHeight) yPaintedBottom = imageHeight;
++
++    // Remove unused lines
++    const int clearStart = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? yPaintedBottom : 0;
++    const int clearStop  = ( yPaintedTop - m_oldYPaintedTop <= 0 ) ? imageHeight  : yTop;
++
++    QRgb * const clearBegin = (QRgb*)( canvasImage->scanLine( clearStart ) );
++    QRgb * const clearEnd = (QRgb*)( canvasImage->scanLine( clearStop ) );
++
++    QRgb * it = clearBegin;
++
++    for ( ; it < clearEnd; ++it ) {
++        *(it) = 0;
++    }
++
++    m_oldYPaintedTop = yPaintedTop;
++
++    m_tileLoader->cleanupTilehash();
++}
++
++
++#include "FastMercatorTextureMapper.moc"
+Index: marble-0.85+svn1207808/src/lib/FastMercatorTextureMapper.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ marble-0.85+svn1207808/src/lib/FastMercatorTextureMapper.h 2010-12-19 16:51:30.000000000 -0500
+@@ -0,0 +1,35 @@
++//
++// This file is part of the Marble Virtual Globe.
++//
++// This program is free software licensed under the GNU LGPL. You can
++// find a copy of this license in LICENSE.txt in the top directory of
++// the source code.
++//
++// Copyright 2010      Bernhard Beschow <bbeschow@cs.tu-berlin.de>
++//
++
++#ifndef MARBLE_FASTMERCATORTEXTUREMAPPER_H
++#define MARBLE_FASTMERCATORTEXTUREMAPPER_H
++
++
++#include "AbstractScanlineTextureMapper.h"
++
++namespace Marble
++{
++
++class FastMercatorTextureMapper : public AbstractScanlineTextureMapper
++{
++    Q_OBJECT
++
++ public:
++    FastMercatorTextureMapper( GeoSceneTexture *textureLayer, StackedTileLoader *tileLoader,
++                               QObject *parent = 0 );
++    void mapTexture( ViewParams *viewParams );
++
++  private:
++    int m_oldYPaintedTop;
++};
++
++}
++
++#endif
+Index: marble-0.85+svn1207808/src/lib/TextureLayer.cpp
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/TextureLayer.cpp       2010-12-19 16:51:17.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/TextureLayer.cpp    2010-12-19 16:51:30.000000000 -0500
+@@ -18,6 +18,7 @@
+ #include "SphericalScanlineTextureMapper.h"
+ #include "EquirectScanlineTextureMapper.h"
+ #include "MercatorScanlineTextureMapper.h"
++#include "FastMercatorTextureMapper.h"
+ #include "GeoPainter.h"
+ #include "GeoSceneDocument.h"
+ #include "GeoSceneFilter.h"
+@@ -249,8 +250,13 @@
+                                                                 this );
+             break;
+         case Mercator:
+-            d->m_texmapper = new MercatorScanlineTextureMapper( d->textureLayer(), &d->m_tileLoader,
++            if ( d->textureLayer()->projection() == GeoSceneTexture::Mercator ) {
++                d->m_texmapper = new FastMercatorTextureMapper( d->textureLayer(), &d->m_tileLoader,
+                                                                 this );
++            } else {
++                d->m_texmapper = new MercatorScanlineTextureMapper( d->textureLayer(), &d->m_tileLoader,
++                                                                    this );
++            }
+             break;
+         default:
+             d->m_texmapper = 0;
diff --git a/packaging/debian/patches/install-lang-files.diff b/packaging/debian/patches/install-lang-files.diff
new file mode 100644 (file)
index 0000000..0a30de0
--- /dev/null
@@ -0,0 +1,16 @@
+Index: marble-0.85+svn1207808/data/CMakeLists.txt
+===================================================================
+--- marble-0.85+svn1207808.orig/data/CMakeLists.txt    2010-12-19 16:56:16.000000000 -0500
++++ marble-0.85+svn1207808/data/CMakeLists.txt 2010-12-19 16:56:21.000000000 -0500
+@@ -229,6 +229,11 @@
+   ${PLACEMARK_FILES}
+ DESTINATION ${MARBLE_DATA_INSTALL_PATH}/placemarks)
++FILE (GLOB LANG_FILES lang/marble-*)
++install (FILES
++  ${LANG_FILES}
++DESTINATION ${MARBLE_DATA_INSTALL_PATH}/lang)
++
+ if(NOT APPLE AND NOT WIN32)
+   if(QTONLY)
+     set(ICON_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/../../usr/share/icons)
index 373c36c..c18d97e 100644 (file)
@@ -1 +1,4 @@
 maemo-startup-files.diff
+fastmercator.diff
+tracking-dialog.diff
+install-lang-files.diff
diff --git a/packaging/debian/patches/tracking-dialog.diff b/packaging/debian/patches/tracking-dialog.diff
new file mode 100644 (file)
index 0000000..bef4ce6
--- /dev/null
@@ -0,0 +1,304 @@
+Index: marble-0.85+svn1207808/src/lib/CurrentLocationWidget.cpp
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/CurrentLocationWidget.cpp      2010-12-19 16:53:43.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/CurrentLocationWidget.cpp   2010-12-19 16:53:53.000000000 -0500
+@@ -31,6 +31,9 @@
+ // Ui
+ #include "ui_CurrentLocationWidget.h"
++#include <QDateTime>
++#include <QFileDialog>
++
+ namespace Marble
+ {
+@@ -52,6 +55,8 @@
+     void updateRecenterComboBox( int centerMode );
+     void updateAutoZoomCheckBox( bool autoZoom );
+     void updateActivePositionProvider( PositionProviderPlugin* );
++    void saveTrack();
++    void clearTrack();
+ };
+ CurrentLocationWidget::CurrentLocationWidget( QWidget *parent, Qt::WindowFlags f )
+@@ -62,11 +67,15 @@
+     d->m_locale = MarbleGlobal::getInstance()->locale();
+-    connect( d->m_currentLocationUi.recenterComboBox, SIGNAL ( highlighted( int ) ),
++    connect( d->m_currentLocationUi.recenterComboBox, SIGNAL ( currentIndexChanged( int ) ),
+             this, SLOT( setRecenterMode( int ) ) );
+     connect( d->m_currentLocationUi.autoZoomCheckBox, SIGNAL( clicked( bool ) ),
+              this, SLOT( setAutoZoom( bool ) ) );
++
++    bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
++    d->m_currentLocationUi.positionTrackingComboBox->setVisible( !smallScreen );
++    d->m_currentLocationUi.locationLabel->setVisible( !smallScreen );
+ }
+ CurrentLocationWidget::~CurrentLocationWidget()
+@@ -91,6 +100,9 @@
+         QString html = "<p>No Position Tracking Plugin installed.</p>";
+         d->m_currentLocationUi.locationLabel->setText( html );
+         d->m_currentLocationUi.locationLabel->setEnabled ( true );
++        d->m_currentLocationUi.showTrackCheckBox->setEnabled( false );
++        d->m_currentLocationUi.saveTrackPushButton->setEnabled( false );
++        d->m_currentLocationUi.clearTrackPushButton->setEnabled( false );
+     }
+     //disconnect CurrentLocation Signals
+@@ -120,6 +132,7 @@
+     connect( d->m_widget->model()->positionTracking(),
+              SIGNAL( positionProviderPluginChanged( PositionProviderPlugin* ) ),
+              this, SLOT( updateActivePositionProvider( PositionProviderPlugin* ) ) );
++    d->updateActivePositionProvider( d->m_widget->model()->positionTracking()->positionProviderPlugin() );
+     connect( d->m_currentLocationUi.positionTrackingComboBox, SIGNAL( currentIndexChanged( QString ) ),
+              this, SLOT( changePositionProvider( QString ) ) );
+     connect( d->m_currentLocationUi.locationLabel, SIGNAL( linkActivated( QString ) ),
+@@ -132,6 +145,17 @@
+              this, SLOT( updateRecenterComboBox( int ) ) );
+     connect( d->m_adjustNavigation, SIGNAL( autoZoomToggled( bool ) ),
+              this, SLOT( updateAutoZoomCheckBox( bool ) ) );
++    connect (d->m_currentLocationUi.showTrackCheckBox, SIGNAL( clicked(bool) ),
++             d->m_widget->model()->positionTracking(), SLOT( setTrackVisible(bool) ));
++    connect (d->m_currentLocationUi.showTrackCheckBox, SIGNAL( clicked(bool) ),
++             d->m_widget, SLOT(repaint()));
++    if ( d->m_widget->model()->positionTracking()->trackVisible() ) {
++        d->m_currentLocationUi.showTrackCheckBox->setCheckState(Qt::Checked);
++    }
++    connect (d->m_currentLocationUi.saveTrackPushButton, SIGNAL( clicked(bool)),
++             this, SLOT(saveTrack()));
++    connect (d->m_currentLocationUi.clearTrackPushButton, SIGNAL( clicked(bool)),
++             this, SLOT(clearTrack()));
+ }
+ void CurrentLocationWidgetPrivate::adjustPositionTrackingStatus( PositionProviderStatus status )
+@@ -177,6 +201,10 @@
+         }
+     }
+     m_currentLocationUi.positionTrackingComboBox->blockSignals( false );
++    m_currentLocationUi.recenterLabel->setEnabled( plugin );
++    m_currentLocationUi.recenterComboBox->setEnabled( plugin );
++    m_currentLocationUi.autoZoomCheckBox->setEnabled( plugin );
++
+ }
+ void CurrentLocationWidget::receiveGpsCoordinates( const GeoDataCoordinates &position, qreal speed )
+@@ -222,14 +250,14 @@
+     html = html.arg( position.lonToString() ).arg( position.latToString() );
+     html = html.arg( distanceString ).arg( speedString + ' ' + unitString );
+     d->m_currentLocationUi.locationLabel->setText( html );
++    d->m_currentLocationUi.showTrackCheckBox->setEnabled( true );
++    d->m_currentLocationUi.saveTrackPushButton->setEnabled( true );
++    d->m_currentLocationUi.clearTrackPushButton->setEnabled( true );
+ }
+ void CurrentLocationWidgetPrivate::changePositionProvider( const QString &provider )
+ {
+     bool hasProvider = ( provider != QObject::tr("Disabled") );
+-    m_currentLocationUi.recenterLabel->setEnabled( hasProvider );
+-    m_currentLocationUi.recenterComboBox->setEnabled( hasProvider );
+-    m_currentLocationUi.autoZoomCheckBox->setEnabled( hasProvider );
+     if ( hasProvider ) {
+         foreach( PositionProviderPlugin* plugin, m_positionProviderPlugins ) {
+@@ -277,6 +305,23 @@
+     m_widget->centerOn(m_currentPosition, true);
+ }
++void CurrentLocationWidgetPrivate::saveTrack()
++{
++    QString fileName = QFileDialog::getSaveFileName(m_widget, QObject::tr("Save Track"), // krazy:exclude=qclasses
++                                                    QDir::homePath().append('/' + QDateTime::currentDateTime().toString("yyyy-MM-dd_hhmmss") + ".kml"),
++                            QObject::tr("KML File (*.kml)"));
++
++    m_widget->model()->positionTracking()->saveTrack( fileName );
++}
++
++void CurrentLocationWidgetPrivate::clearTrack()
++{
++    m_widget->model()->positionTracking()->clearTrack();
++    m_widget->repaint();
++    m_currentLocationUi.saveTrackPushButton->setEnabled( false );
++    m_currentLocationUi.clearTrackPushButton->setEnabled( false );
++}
++
+ }
+ #include "CurrentLocationWidget.moc"
+Index: marble-0.85+svn1207808/src/lib/CurrentLocationWidget.h
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/CurrentLocationWidget.h        2010-12-19 16:53:43.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/CurrentLocationWidget.h     2010-12-19 16:53:53.000000000 -0500
+@@ -72,6 +72,9 @@
+      Q_PRIVATE_SLOT( d, void updateAutoZoomCheckBox( bool autoZoom ) )
+      Q_PRIVATE_SLOT( d, void updateActivePositionProvider( PositionProviderPlugin* ) )
++
++     Q_PRIVATE_SLOT( d, void saveTrack() )
++     Q_PRIVATE_SLOT( d, void clearTrack() )
+ };
+ }
+Index: marble-0.85+svn1207808/src/lib/CurrentLocationWidget.ui
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/CurrentLocationWidget.ui       2010-12-19 16:53:43.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/CurrentLocationWidget.ui    2010-12-19 16:53:53.000000000 -0500
+@@ -7,7 +7,7 @@
+     <x>0</x>
+     <y>0</y>
+     <width>137</width>
+-    <height>190</height>
++    <height>237</height>
+    </rect>
+   </property>
+   <property name="windowTitle">
+@@ -40,6 +40,36 @@
+     </widget>
+    </item>
+    <item>
++    <widget class="QCheckBox" name="showTrackCheckBox">
++     <property name="enabled">
++      <bool>false</bool>
++     </property>
++     <property name="text">
++      <string>Show Track</string>
++     </property>
++    </widget>
++   </item>
++   <item>
++    <widget class="QPushButton" name="saveTrackPushButton">
++     <property name="enabled">
++      <bool>false</bool>
++     </property>
++     <property name="text">
++      <string>Save Track</string>
++     </property>
++    </widget>
++   </item>
++   <item>
++    <widget class="QPushButton" name="clearTrackPushButton">
++     <property name="enabled">
++      <bool>false</bool>
++     </property>
++     <property name="text">
++      <string>Clear Track</string>
++     </property>
++    </widget>
++   </item>
++   <item>
+     <widget class="QLabel" name="locationLabel">
+      <property name="enabled">
+       <bool>false</bool>
+@@ -65,6 +95,19 @@
+     </widget>
+    </item>
+    <item>
++    <spacer name="verticalSpacer">
++     <property name="orientation">
++      <enum>Qt::Vertical</enum>
++     </property>
++     <property name="sizeHint" stdset="0">
++      <size>
++       <width>20</width>
++       <height>20</height>
++      </size>
++     </property>
++    </spacer>
++   </item>
++   <item>
+     <widget class="QLabel" name="recenterLabel">
+      <property name="enabled">
+       <bool>false</bool>
+Index: marble-0.85+svn1207808/src/lib/PositionTracking.cpp
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/PositionTracking.cpp   2010-12-19 16:53:43.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/PositionTracking.cpp        2010-12-19 16:53:53.000000000 -0500
+@@ -16,14 +16,19 @@
+ #include "GeoDataPlacemark.h"
+ #include "GeoDataStyle.h"
+ #include "GeoDataStyleMap.h"
++#include "GeoWriter.h"
++#include "KmlElementDictionary.h"
+ #include "AbstractProjection.h"
+ #include "FileManager.h"
+ #include "MarbleMath.h"
+ #include "MarbleDebug.h"
++#include "MarbleDirs.h"
+ #include "PositionProviderPlugin.h"
+ #include "PositionTracking_p.h"
++#include <QFile>
++
+ using namespace Marble;
+ void PositionTrackingPrivate::setPosition( GeoDataCoordinates position,
+@@ -173,6 +178,26 @@
+     d->m_document->setVisible( visible );
+ }
++bool PositionTracking::saveTrack(QString& fileName)
++{
++
++    if ( !fileName.isEmpty() )
++    {
++        if ( !fileName.endsWith("kml", Qt::CaseInsensitive) )
++        {
++            fileName.append( ".kml" );
++        }
++
++        GeoWriter writer;
++        //FIXME: a better way to do this?
++        writer.setDocumentType( kml::kmlTag_nameSpace22 );
++        QFile file( fileName );
++        file.open( QIODevice::ReadWrite );
++        return writer.write(&file, *d->m_document);
++    }
++    return false;
++}
++
+ void PositionTracking::clearTrack()
+ {
+     GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(d->m_document->child(d->m_document->size()-1));
+Index: marble-0.85+svn1207808/src/lib/PositionTracking.h
+===================================================================
+--- marble-0.85+svn1207808.orig/src/lib/PositionTracking.h     2010-12-19 16:53:43.000000000 -0500
++++ marble-0.85+svn1207808/src/lib/PositionTracking.h  2010-12-19 16:53:53.000000000 -0500
+@@ -84,6 +84,11 @@
+     void setTrackVisible ( bool visible );
+     /**
++      * Saves the track document to file
++      */
++    bool saveTrack( QString& fileName );
++
++    /**
+       * Removes all track segments which were recorded
+       */
+     void clearTrack();
+Index: marble-0.85+svn1207808/src/QtMainWindow.h
+===================================================================
+--- marble-0.85+svn1207808.orig/src/QtMainWindow.h     2010-12-19 16:53:43.000000000 -0500
++++ marble-0.85+svn1207808/src/QtMainWindow.h  2010-12-19 16:53:53.000000000 -0500
+@@ -120,6 +120,7 @@
+     void showMapViewDialog();
+     void showLegendTab( bool enabled );
+     void showRoutingDialog();
++    void showTrackingDialog();
+  private:
+     void setupZoomButtons();
+@@ -194,9 +195,11 @@
+     QAction *m_showMapViewDialogAction;
+     QAction *m_toggleLegendTabAction;
+     QAction *m_toggleRoutingTabAction;
++    QAction *m_showTrackingDialogAction;
+     QDialog *m_mapViewDialog;
+     QDialog *m_routingDialog;
++    QDialog *m_trackingDialog;
+     RoutingWidget *m_routingWidget;
+ };