Index: trunk/KDE/kdeedu/marble/src/lib/TileLoader.h =================================================================== --- trunk/KDE/kdeedu/marble/src/lib/TileLoader.h (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/lib/TileLoader.h (revision 1011005) @@ -1,204 +1,214 @@ /** * This file is part of the Marble Desktop Globe. * * Copyright 2005-2007 Torsten Rahn " * Copyright 2007 Inge Wallin " + * Copyright 2009 Jens-Michael Hoffmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef MARBLE_TILELOADER_H #define MARBLE_TILELOADER_H #include +#include "TileId.h" + class QString; namespace Marble { class SunLocator; class TextureTile; class HttpDownloadManager; class MarbleModel; class GeoSceneLayer; class TileLoaderPrivate; /** * @short Tile loading from a quad tree * * This class loads tiles into memory. For faster access * we keep the tileIDs and their respective pointers to * the tiles in a hashtable. * The class also contains convenience methods to remove entries * from the hashtable and to return more detailed properties * about each tile level and their tiles. * * @author Torsten Rahn **/ class TileLoader : public QObject { Q_OBJECT public: /** * Creates a new tile loader. * * @param downloadManager The download manager that shall be used to fetch * the tiles from a remote resource. * @param sunLocator The sun locator that shall be used to 'sunnify' the tiles. */ TileLoader( HttpDownloadManager *downloadManager, MarbleModel* parent); /** * Destroys the tile loader. */ virtual ~TileLoader(); /** * Sets the download manager that shall be used to fetch the * tiles from a remote resource. */ void setDownloadManager( HttpDownloadManager *downloadManager ); /** * Loads a tile and returns it. * * @param tilx The x coordinate of the requested tile. * @param tily The y coordinate of the requested tile. * @param tileLevel The zoom level of the requested tile. */ TextureTile* loadTile( int tilx, int tily, int tileLevel ); /** * Sets the texture layer @p the tiles shall be loaded for. */ void setLayer( Marble::GeoSceneLayer * layer ); /** * Returns the texture layer the tiles shall be loaded for. */ Marble::GeoSceneLayer * layer() const; /** * Resets the internal tile hash. */ void resetTilehash(); /** * Cleans up the internal tile hash. * * Removes all superfluous tiles from the hash. */ void cleanupTilehash(); /** * Clears the internal tile hash. * * Removes all tiles from the hash. */ void flush(); /** * Returns the width of a tile loaded by this tile loader. */ int tileWidth() const; /** * Returns the height of a tile loaded by this tile loader. */ int tileHeight() const; /** * Returns the global width for the given @p level. */ int globalWidth( int level ) const; /** * Returns the global height for the given @p level. */ int globalHeight( int level ) const; /** * @brief Returns the limit of the volatile (in RAM) cache. * @return the cache limit in kilobytes */ quint64 volatileCacheLimit() const; /** + * @brief Returns a list of TileIds of the tiles which are currently + * displayed. This is used for example for the map reload + * functionality. + */ + QList tilesOnDisplay() const; + + /** * Returns the highest level in which some tiles are available for the given @p * texture layer. */ static int maxPartialTileLevel( Marble::GeoSceneLayer * layer ); /** * Returns whether the mandatory most basic tile level is fully available for * the given @p texture layer. */ static bool baseTilesAvailable( Marble::GeoSceneLayer * layer ); public Q_SLOTS: /** * @brief Set the limit of the volatile (in RAM) cache. * @param bytes The limit in kilobytes. */ void setVolatileCacheLimit( quint64 kiloBytes ); /** * Reloads the tile with the given @p id. */ void reloadTile( const QString &relativeUrlString, const QString &id ); /** * Reloads the tile with the given @p id. */ void reloadTile( const QString &serverUrlString, const QString &relativeUrlString, const QString &id ); /** * Effectively triggers a reload of all tiles that are currently in use * and clears the tile cache in physical memory. */ void update(); Q_SIGNALS: /** * This signal is emitted whenever a requested tile has been * downloaded and is available now. */ void tileUpdateAvailable(); void paintTile(TextureTile* tile, int x, int y, int level, Marble::GeoSceneLayer * layer, bool requestTileUpdate); private: /** * @brief Helper method for the slots reloadTile. */ void reloadTile( const QString &idStr ); Q_DISABLE_COPY( TileLoader ) TileLoaderPrivate* const d; MarbleModel* m_parent; }; } #endif // MARBLE_TILELOADER_H Index: trunk/KDE/kdeedu/marble/src/lib/MarbleMap.cpp =================================================================== --- trunk/KDE/kdeedu/marble/src/lib/MarbleMap.cpp (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/lib/MarbleMap.cpp (revision 1011005) @@ -1,1313 +1,1319 @@ // // This file is part of the Marble Desktop 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 2006-2009 Torsten Rahn " // Copyright 2007 Inge Wallin " // Copyright 2008 Carlos Licea +// Copyright 2009 Jens-Michael Hoffmann // // Own #include "MarbleMap.h" #include "MarbleMap_p.h" // Posix #include // Qt #include #include #include #include #include #include #include #ifdef MARBLE_DBUS #include #endif // Marble #include "AbstractProjection.h" #include "AbstractScanlineTextureMapper.h" #include "GeoPainter.h" #include "FileStorageWatcher.h" #include "FileViewModel.h" #include "GeoDataFeature.h" #include "GeoDataCoordinates.h" #include "GeoSceneDocument.h" #include "GeoSceneHead.h" #include "GeoSceneZoom.h" #include "GpxFileViewItem.h" #include "HttpDownloadManager.h" #include "MarbleDirs.h" #include "MarbleLocale.h" #include "MarbleModel.h" #include "MarblePlacemarkModel.h" #include "MeasureTool.h" #include "MergedLayerDecorator.h" #include "PlacemarkLayout.h" #include "Planet.h" #include "Quaternion.h" #include "StoragePolicy.h" #include "SunLocator.h" #include "TextureColorizer.h" #include "ViewParams.h" #include "ViewportParams.h" #include "RenderPlugin.h" #include "gps/GpsLayer.h" using namespace Marble; #ifdef Q_CC_MSVC # ifndef KDEWIN_MATH_H static long double sqrt(int a) { return sqrt((long double)a); } # endif #endif MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent ) : m_parent( parent ), m_persistentTileCacheLimit( 0 ), // No limit m_volatileTileCacheLimit( 1024*1024*30 ) // 30 MB { } void MarbleMapPrivate::construct() { // Some point that tackat defined. :-) m_parent->setHome( -9.4, 54.8, 1050 ); m_parent->connect( m_model, SIGNAL( themeChanged( QString ) ), m_parent, SIGNAL( themeChanged( QString ) ) ); m_parent->connect( m_model, SIGNAL( modelChanged() ), m_parent, SLOT( updateChangedMap() ) ); m_justModified = false; m_dirtyAtmosphere = false; m_measureTool = new MeasureTool( m_model, m_parent ); m_parent->connect( m_model, SIGNAL( timeout() ), m_parent, SLOT( updateGps() ) ); m_logzoom = 0; m_zoomStep = 40; m_parent->goHome(); // FloatItems m_showFrameRate = false; m_parent->connect( m_model->sunLocator(), SIGNAL( updateSun() ), m_parent, SLOT( updateSun() ) ); m_parent->connect( m_model->sunLocator(), SIGNAL( centerSun() ), m_parent, SLOT( centerSun() ) ); m_parent->connect( m_model, SIGNAL( repaintNeeded( QRegion ) ), m_parent, SIGNAL( repaintNeeded( QRegion ) ) ); // A new instance of FileStorageWatcher. // The thread will be started at setting persistent tile cache size. m_storageWatcher = new FileStorageWatcher( MarbleDirs::localPath(), m_parent ); m_parent->connect( m_parent, SIGNAL( themeChanged( QString ) ), m_storageWatcher, SLOT( updateTheme( QString ) ) ); // Setting the theme to the current theme. m_storageWatcher->updateTheme( m_parent->mapThemeId() ); // connect the StoragePolicy used by the download manager to the FileStorageWatcher StoragePolicy * const storagePolicy = m_model->downloadManager()->storagePolicy(); QObject::connect( storagePolicy, SIGNAL( cleared() ), m_storageWatcher, SLOT( resetCurrentSize() ) ); QObject::connect( storagePolicy, SIGNAL( sizeChanged( qint64 ) ), m_storageWatcher, SLOT( addToCurrentSize( qint64 ) ) ); } // Used to be resizeEvent() void MarbleMapPrivate::doResize() { QSize size(m_parent->width(), m_parent->height()); m_viewParams.viewport()->setSize( size ); // Recreate the canvas image with the new size. m_viewParams.setCanvasImage( new QImage( m_parent->width(), m_parent->height(), QImage::Format_RGB32 )); if ( m_viewParams.showAtmosphere() ) { m_dirtyAtmosphere=true; } // Recreate the m_viewParams.setCoastImage( new QImage( m_parent->width(), m_parent->height(), QImage::Format_RGB32 )); m_justModified = true; } void MarbleMapPrivate::paintMarbleSplash( GeoPainter &painter, QRect &dirtyRect ) { Q_UNUSED( dirtyRect ) painter.save(); QPixmap logoPixmap( MarbleDirs::path( "svg/marble-logo-inverted-72dpi.png" ) ); if ( logoPixmap.width() > m_parent->width() * 0.7 || logoPixmap.height() > m_parent->height() * 0.7 ) { logoPixmap = logoPixmap.scaled( QSize( m_parent->width(), m_parent->height() ) * 0.7, Qt::KeepAspectRatio, Qt::SmoothTransformation ); } QPoint logoPosition( ( m_parent->width() - logoPixmap.width() ) / 2, ( m_parent->height() - logoPixmap.height() ) / 2 ); painter.drawPixmap( logoPosition, logoPixmap ); QString message; // "Please assign a map theme!"; painter.setPen( Qt::white ); int yTop = logoPosition.y() + logoPixmap.height() + 10; QRect textRect( 0, yTop, m_parent->width(), m_parent->height() - yTop ); painter.drawText( textRect, Qt::AlignHCenter | Qt::AlignTop, message ); painter.restore(); } void MarbleMapPrivate::drawAtmosphere() { // Only draw an atmosphere if planet is earth GeoSceneDocument * mapTheme = m_viewParams.mapTheme(); if ( mapTheme ) { if ( mapTheme->head()->target() != "earth" ) return; } // Only draw an atmosphere if projection is spherical if ( m_viewParams.projection() != Spherical ) return; // No use to draw atmosphere if it's not visible in the area. if ( m_viewParams.viewport()->mapCoversViewport() ) return; // Ok, now we know that at least a little of the atmosphere is // visible, if nothing else in the corners. Draw the atmosphere // by using a circular gradient. This is a pure visual effect and // has nothing to do with real physics. int imageHalfWidth = m_parent->width() / 2; int imageHalfHeight = m_parent->height() / 2; // Recalculate the atmosphere effect and paint it to canvasImage. QRadialGradient grad1( QPointF( imageHalfWidth, imageHalfHeight ), 1.05 * m_parent->radius() ); grad1.setColorAt( 0.91, QColor( 255, 255, 255, 255 ) ); grad1.setColorAt( 1.00, QColor( 255, 255, 255, 0 ) ); QBrush brush1( grad1 ); QPen pen1( Qt::NoPen ); QPainter painter( m_viewParams.canvasImage() ); painter.setBrush( brush1 ); painter.setPen( pen1 ); painter.setRenderHint( QPainter::Antialiasing, false ); painter.drawEllipse( imageHalfWidth - (int)( (qreal)(m_parent->radius()) * 1.05 ), imageHalfHeight - (int)( (qreal)(m_parent->radius()) * 1.05 ), (int)( 2.1 * (qreal)(m_parent->radius()) ), (int)( 2.1 * (qreal)(m_parent->radius()) ) ); } void MarbleMapPrivate::drawFog( QPainter &painter ) { if ( m_viewParams.projection() != Spherical) return; // No use to draw the fog if it's not visible in the area. if ( m_viewParams.viewport()->mapCoversViewport() ) return; int imgWidth2 = m_parent->width() / 2; int imgHeight2 = m_parent->height() / 2; // Recalculate the atmosphere effect and paint it to canvasImage. QRadialGradient grad1( QPointF( imgWidth2, imgHeight2 ), m_parent->radius() ); // FIXME: Add a cosine relationship grad1.setColorAt( 0.85, QColor( 255, 255, 255, 0 ) ); grad1.setColorAt( 1.00, QColor( 255, 255, 255, 64 ) ); QBrush brush1( grad1 ); QPen pen1( Qt::NoPen ); painter.save(); painter.setBrush( brush1 ); painter.setPen( pen1 ); painter.setRenderHint( QPainter::Antialiasing, false ); // FIXME: Cut out what's really needed painter.drawEllipse( imgWidth2 - m_parent->radius(), imgHeight2 - m_parent->radius(), 2 * m_parent->radius(), 2 * m_parent->radius() ); painter.restore(); } void MarbleMapPrivate::paintGround( GeoPainter &painter, QRect &dirtyRect ) { if ( !m_viewParams.mapTheme() ) { qDebug() << "No theme yet!"; paintMarbleSplash( painter, dirtyRect ); return; } if ( m_dirtyAtmosphere ) { drawAtmosphere(); m_dirtyAtmosphere = false; } m_model->paintGlobe( &painter, m_parent->width(), m_parent->height(), &m_viewParams, m_parent->needsUpdate() || m_viewParams.canvasImage()->isNull(), dirtyRect ); // FIXME: this is ugly, add method updatePlanetAxis() to ViewParams m_viewParams.setPlanetAxisUpdated( m_viewParams.planetAxis() ); // FIXME: this is ugly, add method updateRadius() to ViewParams m_viewParams.setRadiusUpdated( m_viewParams.radius() ); m_justModified = false; // FIXME: This is really slow. That's why we defer this to // PrintQuality. Either cache on a pixmap - or maybe // better: Add to GlobeScanlineTextureMapper. if ( m_viewParams.mapQuality() == Marble::PrintQuality ) drawFog( painter ); } void MarbleMapPrivate::paintOverlay( GeoPainter &painter, QRect &dirtyRect ) { Q_UNUSED( dirtyRect ) if ( !m_viewParams.mapTheme() ) { return; } // FIXME: Add this stuff into the Layermanager as something to be // called before the float items. bool antialiased = false; if ( m_viewParams.mapQuality() == Marble::HighQuality || m_viewParams.mapQuality() == Marble::PrintQuality ) { antialiased = true; } m_measureTool->paint( &painter, m_viewParams.viewport(), antialiased ); } void MarbleMapPrivate::paintFps( GeoPainter &painter, QRect &dirtyRect, qreal fps) { Q_UNUSED(dirtyRect); if ( m_showFrameRate ) { QString fpsString = QString( "Speed: %1 fps" ).arg( fps, 5, 'f', 1, QChar(' ') ); QPoint fpsLabelPos( 10, 20 ); painter.setFont( QFont( "Sans Serif", 10 ) ); painter.setPen( Qt::black ); painter.setBrush( Qt::black ); painter.drawText( fpsLabelPos, fpsString ); painter.setPen( Qt::white ); painter.setBrush( Qt::white ); painter.drawText( fpsLabelPos.x() - 1, fpsLabelPos.y() - 1, fpsString ); } } // ---------------------------------------------------------------- MarbleMap::MarbleMap() : d( new MarbleMapPrivate( this ) ) { #ifdef MARBLE_DBUS QDBusConnection::sessionBus().registerObject( "/MarbleMap", this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals | QDBusConnection::ExportAllProperties ); #endif QTime t; t.start(); d->m_model = new MarbleModel( this ); d->m_modelIsOwned = true; d->construct(); qDebug("Model: Time elapsed: %d ms", t.elapsed()); } MarbleMap::MarbleMap(MarbleModel *model) : d( new MarbleMapPrivate( this ) ) { // QDBusConnection::sessionBus().registerObject( "/marble", this, // QDBusConnection::ExportAllSlots ); d->m_model = model; d->m_modelIsOwned = false; d->construct(); } MarbleMap::~MarbleMap() { // Some basic initializations. d->m_width = 0; d->m_height = 0; if ( d->m_modelIsOwned ) delete d->m_model; delete d; } MarbleModel *MarbleMap::model() const { return d->m_model; } ViewParams *MarbleMap::viewParams() { return &d->m_viewParams; } MeasureTool *MarbleMap::measureTool() { return d->m_measureTool; } void MarbleMap::setSize(int width, int height) { d->m_width = width; d->m_height = height; d->doResize(); } void MarbleMap::setSize(QSize size) { d->m_width = size.width(); d->m_height = size.height(); d->doResize(); } QSize MarbleMap::size() const { return QSize( d->m_width, d->m_height ); } int MarbleMap::width() const { return d->m_width; } int MarbleMap::height() const { return d->m_height; } Quaternion MarbleMap::planetAxis() const { return d->m_viewParams.planetAxis(); } int MarbleMap::radius() const { return d->m_viewParams.radius(); } void MarbleMap::setRadius(int radius) { d->m_viewParams.setRadius( radius ); if ( !mapCoversViewport() ) { setNeedsUpdate(); } } bool MarbleMap::needsUpdate() const { return ( d->m_justModified || d->m_viewParams.radius() != d->m_viewParams.radiusUpdated() || !( d->m_viewParams.planetAxis() == d->m_viewParams.planetAxisUpdated() ) ); } void MarbleMap::setNeedsUpdate() { d->m_justModified = true; } QAbstractItemModel *MarbleMap::placemarkModel() const { return d->m_model->placemarkModel(); } QItemSelectionModel *MarbleMap::placemarkSelectionModel() const { return d->m_model->placemarkSelectionModel(); } qreal MarbleMap::moveStep() { if ( radius() < sqrt( (qreal)(width() * width() + height() * height()) ) ) return 180.0 * 0.1; else return 180.0 * atan( (qreal)width() / (qreal)( 2 * radius() ) ) * 0.2; } int MarbleMap::zoom() const { return d->m_logzoom; } qreal MarbleMap::distance() const { // Due to Marble's orthographic projection ("we have no focus") // it's actually not possible to calculate a "real" distance. // Additionally the viewing angle of the earth doesn't adjust to // the window's size. // // So the only possible workaround is to come up with a distance // definition which gives a reasonable approximation of // reality. Therefore we assume that the average window width // (about 800 pixels) equals the viewing angle of a human being. const qreal VIEW_ANGLE = 110.0; return ( model()->planet()->radius() * 0.4 / (qreal)( radius() ) / tan( 0.5 * VIEW_ANGLE * DEG2RAD ) ); } void MarbleMap::setDistance( qreal distance ) { qreal minDistance = 0.001; if ( distance <= minDistance ) { qDebug() << "Invalid distance: 0 m"; distance = minDistance; } const qreal VIEW_ANGLE = 110.0; setRadius( (int)( model()->planet()->radius() * 0.4 / distance / tan( 0.5 * VIEW_ANGLE * DEG2RAD ) ) ); // We don't do this on every paintEvent to improve performance. // Redrawing the atmosphere is only needed if the size of the // globe changes. if ( d->m_viewParams.showAtmosphere() ) { d->m_dirtyAtmosphere=true; } } qreal MarbleMap::centerLatitude() const { // Calculate translation of center point qreal centerLon; qreal centerLat; d->m_viewParams.centerCoordinates( centerLon, centerLat ); return centerLat * RAD2DEG; } qreal MarbleMap::centerLongitude() const { // Calculate translation of center point qreal centerLon; qreal centerLat; d->m_viewParams.centerCoordinates(centerLon, centerLat); return centerLon * RAD2DEG; } int MarbleMap::minimumZoom() const { if ( d->m_viewParams.mapTheme() ) return d->m_viewParams.mapTheme()->head()->zoom()->minimum(); return 950; } int MarbleMap::maximumZoom() const { if ( d->m_viewParams.mapTheme() ) return d->m_viewParams.mapTheme()->head()->zoom()->maximum(); return 2100; } void MarbleMap::addPlacemarkFile( const QString &filename ) { d->m_model->addPlacemarkFile( filename ); } void MarbleMap::addPlacemarkData( const QString &data, const QString &key ) { d->m_model->addPlacemarkData( data, key ); } void MarbleMap::removePlacemarkKey( const QString &key ) { d->m_model->removePlacemarkKey( key ); } QPixmap MarbleMap::mapScreenShot() { QPixmap screenshotPixmap( size() ); screenshotPixmap.fill( Qt::transparent ); GeoPainter painter( &screenshotPixmap, viewParams()->viewport(), Marble::PrintQuality ); painter.begin( &screenshotPixmap ); QRect dirtyRect( QPoint(), size() ); paint( painter, dirtyRect ); painter.end(); return screenshotPixmap; } +void MarbleMap::reload() const +{ + d->m_model->reloadMap(); +} + bool MarbleMap::propertyValue( const QString& name ) const { bool value; d->m_viewParams.propertyValue( name, value ); return value; } bool MarbleMap::showOverviewMap() const { return propertyValue( "overviewmap" ); } bool MarbleMap::showScaleBar() const { return propertyValue( "scalebar" ); } bool MarbleMap::showCompass() const { return propertyValue( "compass" ); } bool MarbleMap::showGrid() const { return propertyValue( "coordinate-grid" ); } bool MarbleMap::showClouds() const { return d->m_model->layerDecorator()->showClouds(); } bool MarbleMap::showAtmosphere() const { return d->m_viewParams.showAtmosphere(); } bool MarbleMap::showCrosshairs() const { bool visible = false; QList pluginList = renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { if ( (*i)->nameId() == "crosshairs" ) { visible = (*i)->visible(); } } return visible; } bool MarbleMap::showPlaces() const { return propertyValue( "places" ); } bool MarbleMap::showCities() const { return propertyValue( "cities" ); } bool MarbleMap::showTerrain() const { return propertyValue( "terrain" ); } bool MarbleMap::showOtherPlaces() const { return propertyValue( "otherplaces" ); } bool MarbleMap::showRelief() const { return propertyValue( "relief" ); } bool MarbleMap::showElevationModel() const { return d->m_viewParams.showElevationModel(); } bool MarbleMap::showIceLayer() const { return propertyValue( "ice" ); } bool MarbleMap::showBorders() const { return propertyValue( "borders" ); } bool MarbleMap::showRivers() const { return propertyValue( "rivers" ); } bool MarbleMap::showLakes() const { return propertyValue( "lakes" ); } bool MarbleMap::showGps() const { return d->m_model->gpsLayer()->visible(); } bool MarbleMap::showFrameRate() const { return d->m_showFrameRate; } quint64 MarbleMap::persistentTileCacheLimit() const { return d->m_persistentTileCacheLimit; } quint64 MarbleMap::volatileTileCacheLimit() const { return d->m_volatileTileCacheLimit; } void MarbleMap::zoomView(int newZoom) { // Check for under and overflow. if ( newZoom < minimumZoom() ) newZoom = minimumZoom(); else if ( newZoom > maximumZoom() ) newZoom = maximumZoom(); // Prevent infinite loops. if ( newZoom == d->m_logzoom ) return; d->m_logzoom = newZoom; setRadius( d->fromLogScale( newZoom ) ); // We don't do this on every paintEvent to improve performance. // Redrawing the atmosphere is only needed if the size of the // globe changes. if ( d->m_viewParams.showAtmosphere() ) { d->m_dirtyAtmosphere=true; } emit zoomChanged( newZoom ); } void MarbleMap::zoomViewBy( int zoomStep ) { zoomView( d->toLogScale( radius() ) + zoomStep ); } void MarbleMap::zoomIn() { zoomViewBy( d->m_zoomStep ); } void MarbleMap::zoomOut() { zoomViewBy( -d->m_zoomStep ); } void MarbleMap::rotateBy(const Quaternion& incRot) { d->m_viewParams.setPlanetAxis( incRot * d->m_viewParams.planetAxis() ); } void MarbleMap::rotateBy( const qreal& deltaLon, const qreal& deltaLat) { Quaternion rotPhi( 1.0, deltaLat / 180.0, 0.0, 0.0 ); Quaternion rotTheta( 1.0, 0.0, deltaLon / 180.0, 0.0 ); Quaternion axis = d->m_viewParams.planetAxis(); axis = rotTheta * axis; axis *= rotPhi; axis.normalize(); d->m_viewParams.setPlanetAxis( axis ); } void MarbleMap::centerOn(const qreal& lon, const qreal& lat) { Quaternion quat; quat.createFromEuler( -lat * DEG2RAD, lon * DEG2RAD, 0.0 ); d->m_viewParams.setPlanetAxis( quat ); } void MarbleMap::centerOn(const QModelIndex& index) { QItemSelectionModel *selectionModel = d->m_model->placemarkSelectionModel(); Q_ASSERT( selectionModel ); selectionModel->clear(); if ( index.isValid() ) { const GeoDataCoordinates point = index.data( MarblePlacemarkModel::CoordinateRole ).value(); qreal lon; qreal lat; point.geoCoordinates( lon, lat ); centerOn( lon * RAD2DEG, lat * RAD2DEG ); selectionModel->select( index, QItemSelectionModel::SelectCurrent ); } } void MarbleMap::setCenterLatitude( qreal lat ) { centerOn( centerLongitude(), lat ); } void MarbleMap::setCenterLongitude( qreal lon ) { centerOn( lon, centerLatitude() ); } Projection MarbleMap::projection() const { return d->m_viewParams.projection(); } void MarbleMap::setProjection( Projection projection ) { emit projectionChanged( projection ); d->m_viewParams.setProjection( projection ); if ( d->m_viewParams.showAtmosphere() ) { d->m_dirtyAtmosphere=true; } d->m_model->setupTextureMapper( projection ); // Update texture map during the repaint that follows: setNeedsUpdate(); } void MarbleMap::home( qreal &lon, qreal &lat, int& zoom ) { d->m_homePoint.geoCoordinates( lon, lat, GeoDataCoordinates::Degree ); zoom = d->m_homeZoom; } void MarbleMap::setHome( qreal lon, qreal lat, int zoom) { d->m_homePoint = GeoDataCoordinates( lon, lat, 0, GeoDataCoordinates::Degree ); d->m_homeZoom = zoom; } void MarbleMap::setHome(const GeoDataCoordinates& homePoint, int zoom) { d->m_homePoint = homePoint; d->m_homeZoom = zoom; } void MarbleMap::moveLeft() { int polarity = viewParams()->viewport()->polarity(); if ( polarity < 0 ) rotateBy( +moveStep(), 0 ); else rotateBy( -moveStep(), 0 ); } void MarbleMap::moveRight() { int polarity = viewParams()->viewport()->polarity(); if ( polarity < 0 ) rotateBy( -moveStep(), 0 ); else rotateBy( +moveStep(), 0 ); } void MarbleMap::moveUp() { rotateBy( 0, -moveStep() ); } void MarbleMap::moveDown() { rotateBy( 0, +moveStep() ); } int MarbleMap::northPoleY() { Quaternion northPole = GeoDataCoordinates( 0.0, M_PI * 0.5 ).quaternion(); Quaternion invPlanetAxis = d->m_viewParams.planetAxis().inverse(); northPole.rotateAroundAxis( invPlanetAxis ); return (int)( d->m_viewParams.radius() * northPole.v[Q_Y] ); } bool MarbleMap::screenCoordinates( qreal lon, qreal lat, qreal& x, qreal& y ) { return d->m_viewParams.currentProjection() ->screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, d->m_viewParams.viewport(), x, y ); } bool MarbleMap::geoCoordinates( int x, int y, qreal& lon, qreal& lat, GeoDataCoordinates::Unit unit ) { return d->m_viewParams.currentProjection() ->geoCoordinates( x, y, d->m_viewParams.viewport(), lon, lat, unit ); } // Used to be paintEvent() void MarbleMap::paint(GeoPainter &painter, QRect &dirtyRect) { QTime t; t.start(); d->paintGround( painter, dirtyRect ); customPaint( &painter ); d->paintOverlay( painter, dirtyRect ); qreal fps = 1000.0 / (qreal)( t.elapsed() ); d->paintFps( painter, dirtyRect, fps ); emit framesPerSecond( fps ); } void MarbleMap::customPaint(GeoPainter *painter) { Q_UNUSED( painter ); if ( !viewParams()->mapTheme() ) { return; } } void MarbleMap::goHome() { qreal homeLon = 0; qreal homeLat = 0; d->m_homePoint.geoCoordinates( homeLon, homeLat ); centerOn( homeLon * RAD2DEG, homeLat * RAD2DEG ); zoomView( d->m_homeZoom ); // default 1050 } QString MarbleMap::mapThemeId() const { return d->m_model->mapThemeId(); } void MarbleMap::setMapThemeId( const QString& mapThemeId ) { if ( !mapThemeId.isEmpty() && mapThemeId == d->m_model->mapThemeId() ) return; d->m_viewParams.setMapThemeId( mapThemeId ); GeoSceneDocument *mapTheme = d->m_viewParams.mapTheme(); d->m_model->setMapTheme( mapTheme, d->m_viewParams.projection() ); // We don't do this on every paintEvent to improve performance. // Redrawing the atmosphere is only needed if the size of the // globe changes. d->doResize(); d->m_dirtyAtmosphere=true; centerSun(); // Update texture map during the repaint that follows: setNeedsUpdate(); } void MarbleMap::setPropertyValue( const QString& name, bool value ) { qDebug() << "In MarbleMap the property " << name << "was set to " << value; d->m_viewParams.setPropertyValue( name, value ); } void MarbleMap::setShowOverviewMap( bool visible ) { setPropertyValue( "overviewmap", visible ); } void MarbleMap::setShowScaleBar( bool visible ) { setPropertyValue( "scalebar", visible ); } void MarbleMap::setShowCompass( bool visible ) { setPropertyValue( "compass", visible ); } void MarbleMap::setShowAtmosphere( bool visible ) { bool previousVisible = showAtmosphere(); if ( visible != previousVisible ) { d->m_viewParams.setShowAtmosphere( visible ); // Quick and dirty way to force a whole update of the view d->doResize(); } } void MarbleMap::setShowCrosshairs( bool visible ) { QList pluginList = renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { if ( (*i)->nameId() == "crosshairs" ) { (*i)->setVisible( visible ); } } } void MarbleMap::setShowClouds( bool visible ) { bool previousVisible = d->m_model->layerDecorator()->showClouds(); d->m_model->layerDecorator()->setShowClouds( visible ); if ( previousVisible != visible ) { qDebug() << "Changing cloud layer"; d->m_model->update(); } } void MarbleMap::setShowTileId( bool visible ) { d->m_model->layerDecorator()->setShowTileId( visible ); } void MarbleMap::setShowGrid( bool visible ) { setPropertyValue( "coordinate-grid", visible ); } void MarbleMap::setShowPlaces( bool visible ) { setPropertyValue( "places", visible ); } void MarbleMap::setShowCities( bool visible ) { setPropertyValue( "cities", visible ); } void MarbleMap::setShowTerrain( bool visible ) { setPropertyValue( "terrain", visible ); } void MarbleMap::setShowOtherPlaces( bool visible ) { setPropertyValue( "otherplaces", visible ); } void MarbleMap::setShowRelief( bool visible ) { setPropertyValue( "relief", visible ); // Update texture map during the repaint that follows: setNeedsUpdate(); } void MarbleMap::setShowElevationModel( bool visible ) { d->m_viewParams.setShowElevationModel( visible ); // Update texture map during the repaint that follows: setNeedsUpdate(); } void MarbleMap::setShowIceLayer( bool visible ) { setPropertyValue( "ice", visible ); // Update texture map during the repaint that follows: setNeedsUpdate(); } void MarbleMap::setShowBorders( bool visible ) { setPropertyValue( "borders", visible ); } void MarbleMap::setShowRivers( bool visible ) { setPropertyValue( "rivers", visible ); } void MarbleMap::setShowLakes( bool visible ) { setPropertyValue( "lakes", visible ); // Update texture map during the repaint that follows: setNeedsUpdate(); } void MarbleMap::setShowFrameRate( bool visible ) { d->m_showFrameRate = visible; } void MarbleMap::setShowGps( bool visible ) { d->m_viewParams.setShowGps( visible ); } void MarbleMap::changeCurrentPosition( qreal lon, qreal lat) { d->m_model->gpsLayer()->changeCurrentPosition( lat, lon ); } void MarbleMap::notifyMouseClick( int x, int y) { qreal lon = 0; qreal lat = 0; const bool valid = geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian ); if ( valid ) { emit mouseClickGeoPosition( lon, lat, GeoDataCoordinates::Radian); } } void MarbleMap::updateGps() { QRegion temp; // const bool draw = d->m_model->gpsLayer()->updateGps( size(),&d->m_viewParams, temp ); #if 0 // FIXME: move to MarbleWidget? if ( draw ) { update(temp); } #endif } void MarbleMap::openGpxFile(QString &filename) { #ifndef KML_GSOC d->m_model->gpsLayer()->loadGpx( filename ); #else GpxFileViewItem* item = new GpxFileViewItem( new GpxFile( filename ) ); d->m_model->fileViewModel()->append( item ); #endif } GpxFileModel *MarbleMap::gpxFileModel() { return d->m_model->gpxFileModel(); } FileViewModel* MarbleMap::fileViewModel() const { return d->m_model->fileViewModel(); } void MarbleMap::clearPersistentTileCache() { d->m_model->clearPersistentTileCache(); } void MarbleMap::setPersistentTileCacheLimit( quint64 kiloBytes ) { d->m_persistentTileCacheLimit = kiloBytes; d->m_storageWatcher->setCacheLimit( kiloBytes * 1024 ); if( kiloBytes != 0 ) { if( !d->m_storageWatcher->isRunning() ) d->m_storageWatcher->start( QThread::IdlePriority ); } else { d->m_storageWatcher->quit(); } // TODO: trigger update } void MarbleMap::clearVolatileTileCache() { d->m_model->clearVolatileTileCache(); } void MarbleMap::setVolatileTileCacheLimit( quint64 kilobytes ) { qDebug() << "kiloBytes" << kilobytes; d->m_volatileTileCacheLimit = kilobytes; d->m_model->setVolatileTileCacheLimit( kilobytes ); } void MarbleMap::updateChangedMap() { // Update texture map during the repaint that follows: setNeedsUpdate(); } QString MarbleMap::distanceString() const { const qreal VIEW_ANGLE = 110.0; // Due to Marble's orthographic projection ("we have no focus") // it's actually not possible to calculate a "real" distance. // Additionally the viewing angle of the earth doesn't adjust to // the window's size. // // So the only possible workaround is to come up with a distance // definition which gives a reasonable approximation of // reality. Therefore we assume that the average window width // (about 800 pixels) equals the viewing angle of a human being. // qreal distance = ( model()->planet()->radius() * 0.4 / (qreal)( radius() ) / tan( 0.5 * VIEW_ANGLE * DEG2RAD ) ); QString distanceUnitString; const Marble::DistanceUnit distanceUnit = MarbleGlobal::getInstance()->locale()->distanceUnit(); // FIXME: why is "km" translated and "mi" not? if ( distanceUnit == Marble::Meter ) { distanceUnitString = tr("km"); } else { distance *= KM2MI; distanceUnitString = "mi"; } return QString( "%L1 %2" ).arg( distance, 8, 'f', 1, QChar(' ') ).arg( distanceUnitString ); } bool MarbleMap::mapCoversViewport() { return d->m_viewParams.viewport()->mapCoversViewport(); } Marble::AngleUnit MarbleMap::defaultAngleUnit() const { if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::Decimal ) { return Marble::DecimalDegree; } return Marble::DMSDegree; } void MarbleMap::setDefaultAngleUnit( Marble::AngleUnit angleUnit ) { if ( angleUnit == Marble::DecimalDegree ) { GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::Decimal ); return; } GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::DMS ); } QFont MarbleMap::defaultFont() const { return GeoDataFeature::defaultFont(); } void MarbleMap::setDefaultFont( const QFont& font ) { GeoDataFeature::setDefaultFont( font ); d->m_model->placemarkLayout()->requestStyleReset(); } void MarbleMap::updateSun() { // Update the sun shading. //SunLocator *sunLocator = d->m_model->sunLocator(); qDebug() << "MarbleMap: Updating the sun shading map..."; d->m_model->update(); setNeedsUpdate(); //qDebug() << "Finished updating the sun shading map"; } void MarbleMap::centerSun() { SunLocator *sunLocator = d->m_model->sunLocator(); if ( sunLocator && sunLocator->getCentered() ) { qreal lon = sunLocator->getLon(); qreal lat = sunLocator->getLat(); centerOn( lon, lat ); qDebug() << "Centering on Sun at " << lat << lon; } } SunLocator* MarbleMap::sunLocator() { return d->m_model->sunLocator(); } QList MarbleMap::renderPlugins() const { return d->m_model->renderPlugins(); } QList MarbleMap::floatItems() const { return d->m_model->floatItems(); } #include "MarbleMap.moc" Index: trunk/KDE/kdeedu/marble/src/lib/TileLoader.cpp =================================================================== --- trunk/KDE/kdeedu/marble/src/lib/TileLoader.cpp (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/lib/TileLoader.cpp (revision 1011005) @@ -1,394 +1,405 @@ /** * This file is part of the Marble Desktop Globe. * * Copyright 2005-2007 Torsten Rahn " * Copyright 2007 Inge Wallin " - * Copyright 2008 Jens-Michael Hoffmann + * Copyright 2008,2009 Jens-Michael Hoffmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "TileLoader.h" #include "global.h" #include "GeoSceneLayer.h" #include "GeoSceneTexture.h" #include "HttpDownloadManager.h" #include "DatasetProvider.h" #include "TextureTile.h" #include "MarbleDirs.h" -#include "TileId.h" #include "MarbleModel.h" #include "TileLoaderHelper.h" #include #include #include #include #ifdef Q_CC_MSVC # ifndef KDEWIN_MATH_H long double log(int i) { return log((long double)i); } # endif #endif namespace Marble { class TileLoaderPrivate { public: TileLoaderPrivate() : m_datasetProvider( 0 ), m_downloadManager( 0 ), m_layer( 0 ), m_tileWidth( 0 ), m_tileHeight( 0 ) { m_tileCache.setMaxCost( 20000 * 1024 ); // Cache size measured in bytes } DatasetProvider *m_datasetProvider; HttpDownloadManager *m_downloadManager; GeoSceneLayer *m_layer; QHash m_tileHash; int m_tileWidth; int m_tileHeight; QCache m_tileCache; }; TileLoader::TileLoader( HttpDownloadManager *downloadManager, MarbleModel* parent) : d( new TileLoaderPrivate() ), m_parent(parent) { setDownloadManager( downloadManager ); } TileLoader::~TileLoader() { flush(); d->m_tileCache.clear(); if ( d->m_downloadManager != 0 ) d->m_downloadManager->disconnect( this ); delete d; } void TileLoader::setDownloadManager( HttpDownloadManager *downloadManager ) { if ( d->m_downloadManager != 0 ) { d->m_downloadManager->disconnect( this ); d->m_downloadManager = 0; } d->m_downloadManager = downloadManager; if ( d->m_downloadManager != 0 ) { connect( d->m_downloadManager, SIGNAL( downloadComplete( QString, QString ) ), this, SLOT( reloadTile( QString, QString ) ) ); } } void TileLoader::setLayer( GeoSceneLayer * layer ) { // Initialize map theme. flush(); d->m_tileCache.clear(); if ( !layer ) { qDebug() << "No layer specified! (GeoSceneLayer * layer = 0)"; return; } d->m_layer = layer; TileId id; TextureTile tile( id ); GeoSceneTexture * texture = static_cast( d->m_layer->groundDataset() ); tile.loadDataset( texture, 0, 0, 0 ); // We assume that all tiles have the same size. TODO: check to be safe d->m_tileWidth = tile.rawtile().width(); d->m_tileHeight = tile.rawtile().height(); } void TileLoader::resetTilehash() { QHash::const_iterator it = d->m_tileHash.constBegin(); while ( it != d->m_tileHash.constEnd() ) { it.value()->setUsed( false ); ++it; } } void TileLoader::cleanupTilehash() { // Make sure that tiles which haven't been used during the last // rendering of the map at all get removed from the tile hash. QHashIterator it( d->m_tileHash ); while ( it.hasNext() ) { it.next(); if ( !it.value()->used() ) { // If insert call result is false then the cache is too small to store the tile // but the item will get deleted nevertheless and the pointer we have // doesn't get set to zero (so don't delete it in this case or it will crash!) d->m_tileCache.insert( it.key(), it.value(), it.value()->numBytes() ); d->m_tileHash.remove( it.key() ); } } } void TileLoader::flush() { // Remove all tiles from m_tileHash QHashIterator it( d->m_tileHash ); while ( it.hasNext() ) { it.next(); // If insert call result is false then the cache is too small to store the tile // but the item will get deleted nevertheless and the pointer we have // doesn't get set to zero (so don't delete it in this case or it will crash!) d->m_tileCache.insert( it.key(), it.value(), it.value()->numBytes() ); d->m_tileHash.remove( it.key() ); } d->m_tileHash.clear(); } int TileLoader::tileWidth() const { return d->m_tileWidth; } int TileLoader::tileHeight() const { return d->m_tileHeight; } int TileLoader::globalWidth( int level ) const { if ( !d->m_layer ) return 0; GeoSceneTexture * texture = static_cast( d->m_layer->groundDataset() ); return d->m_tileWidth * TileLoaderHelper::levelToColumn( texture->levelZeroColumns(), level ); } int TileLoader::globalHeight( int level ) const { if ( !d->m_layer ) return 0; GeoSceneTexture * texture = static_cast( d->m_layer->groundDataset() ); return d->m_tileHeight * TileLoaderHelper::levelToRow( texture->levelZeroRows(), level ); } TextureTile* TileLoader::loadTile( int tilx, int tily, int tileLevel ) { if ( !d->m_layer ) return 0; TileId tileId( tileLevel, tilx, tily ); // check if the tile is in the hash TextureTile * tile = d->m_tileHash.value( tileId, 0 ); if ( tile ) { tile->setUsed( true ); return tile; } // here ends the performance critical section of this method // the tile was not in the hash or has been removed because of expiration // so check if it is in the cache tile = d->m_tileCache.take( tileId ); GeoSceneTexture * texture = static_cast( d->m_layer->groundDataset() ); if ( tile ) { // the tile was in the cache, but is it up to date? const QDateTime now = QDateTime::currentDateTime(); if ( tile->created().secsTo( now ) < texture->expire()) { d->m_tileHash[tileId] = tile; tile->setUsed( true ); return tile; } else { delete tile; tile = 0; } } // tile (valid) has not been found in hash or cache, so load it from disk // and place it in the hash from where it will get transfered to the cache // qDebug() << "load Tile from Disk: " << tileId.toString(); tile = new TextureTile( tileId ); d->m_tileHash[tileId] = tile; // FIXME: Implement asynchronous tile loading // d->m_datasetProvider->loadDatasets( tile ); if ( d->m_downloadManager != 0 ) { connect( tile, SIGNAL( downloadTile( QUrl, QString, QString ) ), d->m_downloadManager, SLOT( addJob( QUrl, QString, QString ) ) ); } connect( tile, SIGNAL( tileUpdateDone() ), this, SIGNAL( tileUpdateAvailable() ) ); tile->loadDataset( texture, tileLevel, tilx, tily, &( d->m_tileCache ) ); tile->initJumpTables( false ); // TODO should emit signal rather than directly calling paintTile // emit paintTile( tile, tilx, tily, tileLevel, d->m_theme, false ); m_parent->paintTile( tile, tilx, tily, tileLevel, texture, false ); return tile; } GeoSceneLayer * TileLoader::layer() const { return d->m_layer; } quint64 TileLoader::volatileCacheLimit() const { return d->m_tileCache.maxCost() / 1024; } +QList TileLoader::tilesOnDisplay() const +{ + QList result; + QHash::const_iterator pos = d->m_tileHash.constBegin(); + QHash::const_iterator const end = d->m_tileHash.constEnd(); + for (; pos != end; ++pos ) { + if ( pos.value()->used() ) { + result.append( pos.key() ); + } + } + return result; +} int TileLoader::maxPartialTileLevel( GeoSceneLayer * layer ) { int maxtilelevel = -1; if ( !layer ) return maxtilelevel; GeoSceneTexture * texture = static_cast( layer->groundDataset() ); if ( !texture ) return maxtilelevel; QString tilepath = MarbleDirs::path( TileLoaderHelper::themeStr( texture ) ); // qDebug() << "TileLoader::maxPartialTileLevel tilepath" << tilepath; QStringList leveldirs = ( QDir( tilepath ) ).entryList( QDir::AllDirs | QDir::NoSymLinks | QDir::NoDotAndDotDot ); bool ok = true; QStringList::const_iterator constIterator = leveldirs.constBegin(); for (; constIterator != leveldirs.constEnd(); ++constIterator ) { int value = (*constIterator).toInt( &ok, 10 ); if ( ok && value > maxtilelevel ) maxtilelevel = value; } // qDebug() << "Detected maximum tile level that contains data: " // << maxtilelevel; return maxtilelevel; } bool TileLoader::baseTilesAvailable( GeoSceneLayer * layer ) { if ( !layer ) return false; GeoSceneTexture * texture = static_cast( layer->groundDataset() ); const int levelZeroColumns = texture->levelZeroColumns(); const int levelZeroRows = texture->levelZeroRows(); bool noerr = true; // Check whether the tiles from the lowest texture level are available // for ( int column = 0; noerr && column < levelZeroColumns; ++column ) { for ( int row = 0; noerr && row < levelZeroRows; ++row ) { const QString tilepath = MarbleDirs::path( TileLoaderHelper::relativeTileFileName( texture, 0, column, row )); noerr = QFile::exists( tilepath ); } } return noerr; } void TileLoader::setVolatileCacheLimit( quint64 kiloBytes ) { qDebug() << QString("Setting tile cache to %1 kilobytes.").arg( kiloBytes ); d->m_tileCache.setMaxCost( kiloBytes * 1024 ); } void TileLoader::reloadTile( const QString &idStr ) { if ( !d->m_layer ) return; // qDebug() << "TileLoader::reloadTile:" << idStr; const TileId id = TileId::fromString( idStr ); if ( d->m_tileHash.contains( id ) ) { int level = id.zoomLevel(); int y = id.y(); int x = id.x(); // TODO should emit signal rather than directly calling paintTile // emit paintTile( d->m_tileHash[id], x, y, level, d->m_theme, true ); GeoSceneTexture * texture = static_cast( d->m_layer->groundDataset() ); (d->m_tileHash[id])->loadDataset( texture, level, x, y, &( d->m_tileCache ) ); m_parent->paintTile( d->m_tileHash[id], x, y, level, texture, true ); // (d->m_tileHash[id])->reloadTile( x, y, level, d->m_theme ); } else { // Remove "false" tile from cache so it doesn't get loaded anymore d->m_tileCache.remove( id ); qDebug() << "No such ID:" << idStr; } } void TileLoader::reloadTile( const QString &relativeUrlString, const QString &_id ) { Q_UNUSED( relativeUrlString ); // qDebug() << "Reloading Tile" << relativeUrlString << "id:" << _id; reloadTile( _id ); } void TileLoader::reloadTile( const QString& serverUrlString, const QString &relativeUrlString, const QString &_id ) { Q_UNUSED( serverUrlString ); Q_UNUSED( relativeUrlString ); // qDebug() << "Reloading Tile" << serverUrlString << relativeUrlString << "id:" << _id; reloadTile( _id ); } void TileLoader::update() { qDebug() << "TileLoader::update()"; flush(); // trigger a reload of all tiles that are currently in use d->m_tileCache.clear(); // clear the tile cache in physical memory emit tileUpdateAvailable(); } } #include "TileLoader.moc" Index: trunk/KDE/kdeedu/marble/src/lib/MarbleModel.h =================================================================== --- trunk/KDE/kdeedu/marble/src/lib/MarbleModel.h (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/lib/MarbleModel.h (revision 1011005) @@ -1,370 +1,375 @@ // // This file is part of the Marble Desktop 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 2005-2007 Torsten Rahn " // Copyright 2007 Inge Wallin " // // // MarbleModel is the data store and index class for the MarbleWidget. // #ifndef MARBLEMODEL_H #define MARBLEMODEL_H /** @file * This file contains the headers for MarbleModel * * @author Torsten Rahn * @author Inge Wallin */ #include "marble_export.h" #include #include #include #include #include #include "global.h" #include "ExtDateTime.h" class QItemSelectionModel; class QAbstractItemModel; class QPoint; class QRect; namespace Marble { class AbstractDataPlugin; class AbstractDataPluginItem; class AbstractScanlineTextureMapper; class GeoPainter; class FileViewModel; class GpsLayer; class GpxFileModel; class HttpDownloadManager; class MarbleModelPrivate; class PlacemarkLayout; class ExtDateTime; class SunLocator; class TextureColorizer; class TileCreator; class VectorComposer; class ViewParams; class TextureTile; class MergedLayerDecorator; class RenderPlugin; class AbstractFloatItem; class GeoDataDocument; class GeoSceneDocument; class GeoSceneTexture; class Planet; /** * @short The data model (not based on QAbstractModel) for a MarbleWidget. * * This class provides a data storage and indexer that can be * displayed in a MarbleWidget. It contains 3 different datatypes: * tiles which provide the background, vectors which * provide things like country borders and coastlines and * placemarks which can show points of interest, such as * cities, mountain tops or the poles. * * The tiles provide the background of the image and can be for * instance height and depth fields, magnetic strength, topographic * data or anything else that is area based. * * The vectors provide things like country borders and * coastlines. They are stored in separate files and can be added or * removed at anytime. * * The placemarks contain points of interest, such as cities, * mountain tops or the poles. These are sorted by size (for cities) * and category (capitals, other important cities, less important * cities, etc) and are displayed with different color or shape like * square or round. * * @see MarbleWidget */ class MARBLE_EXPORT MarbleModel : public QObject { friend class MarbleModelPrivate; Q_OBJECT public: /** * @brief Construct a new MarbleModel. * @param parent the parent widget */ explicit MarbleModel( QObject *parent ); virtual ~MarbleModel(); /** * @brief Paint the model into the view * @param painter the QPainter used to paint the view * @param width the width of the widget * @param height the height of the widget * @param viewParams the view parameters controlling the paint process * @param redrawBackground a boolean controlling if the background should be redrawn in addition to the globe itself * @param dirtyRect the rectangle of the widget that needs redrawing. * * The model has the responsibility to actually paint into the * MarbleWidget. This function is called by MarbleWidget when it * receives a paintEvent and should repaint whole or part of the * widget's contents based on the parameters. * * NOTE: This function will probably move to MarbleWidget in KDE * 4.1, making the MarbleModel/MarbleWidget pair truly follow the * Model/View paradigm. */ void paintGlobe(GeoPainter *painter, int width, int height, ViewParams *viewParams, bool redrawBackground, const QRect& dirtyRect); /** * @brief Return the list of Placemarks as a QAbstractItemModel * * @return a list of all Placemarks in the MarbleModel. */ QAbstractItemModel* placemarkModel() const; QItemSelectionModel* placemarkSelectionModel() const; QAbstractItemModel* geometryModel() const; /** * @brief Return the name of the current map theme. * @return the identifier of the current MapTheme. * To ensure that a unique identifier is being used the theme does NOT * get represented by its name but the by relative location of the file * that specifies the theme: * * Example: * maptheme = "earth/bluemarble/bluemarble.dgml" */ QString mapThemeId() const; Marble::GeoSceneDocument *mapTheme() const; /** * @brief Set a new map theme to use. * @param selectedMap the identifier of the selected map theme * @param currentProjection the current projection * * This function sets the map theme, i.e. combination of tile set * and color scheme to use. If the map theme is not previously * used, some basic tiles are created and a progress dialog is * shown. * * NOTE: The currentProjection parameters will * disappear soon. * * The ID of the new maptheme. To ensure that a unique * identifier is being used the theme does NOT get represented by its * name but the by relative location of the file that specifies the theme: * * Example: * maptheme = "earth/bluemarble/bluemarble.dgml" */ void setMapTheme( Marble::GeoSceneDocument* mapTheme, Projection currentProjection ); /** * @brief Set the Projection used for the map * @param projection projection type (e.g. Spherical, Equirectangular, Mercator) */ void setupTextureMapper( Projection projection ); /** * @brief Return the downloadmanager to load missing tiles * @return the HttpDownloadManager instance. */ HttpDownloadManager* downloadManager() const; /** * @brief Set the downloadmanager to load missing tiles * @param downloadManager the HttpDownloadManager instance * * This function sets the downloadmanager to load tiles that * are missing locally. The desctruction of the instance * will be handled by MarbleModel. */ void setDownloadManager( HttpDownloadManager *downloadManager ); void addPlacemarkFile( const QString& filename ); void addPlacemarkData( const QString& data, const QString& key = "data" ); void removePlacemarkKey( const QString& key ); QVector whichFeatureAt( const QPoint& ) const; PlacemarkLayout *placemarkLayout() const; VectorComposer *vectorComposer() const; /** * @brief Returns the map's TextureColorizer * @warning The TextureColorizer pointer may be null since it is only * initialized if the map theme requires it. Check for this possibility. * @return A pointer to the TextureColorizer */ TextureColorizer *textureColorizer() const; AbstractScanlineTextureMapper *textureMapper() const; GpsLayer *gpsLayer() const; GpxFileModel *gpxFileModel() const; FileViewModel *fileViewModel() const; /** * @brief Return whether the Gps Data is visible. * @return The Gps Data visibility. */ bool showGps() const; /** * @brief Set whether the Gps Data is visible. * @param visible visibility of the Gps Data. */ void setShowGps( bool visible ); /** * @brief Start the model's timer polling * @param time the amount of milliseconds between each poll * * This is default behaviour so does not need to be started unless * it was previously stopped */ void startPolling( int time = 1000 ); /** * @brief stop the model from polling */ void stopPolling(); qreal planetRadius() const; QString planetName() const; ExtDateTime* dateTime() const; SunLocator* sunLocator() const; MergedLayerDecorator* layerDecorator() const; /** * @brief Returns the limit of the volatile (in RAM) tile cache. * @return the cache limit in kilobytes */ quint64 volatileTileCacheLimit() const; /** * @brief Returns a list of all RenderPlugins in the model, this includes float items * @return the list of RenderPlugins */ QList renderPlugins() const; /** * @brief Returns a list of all FloatItems in the model * @return the list of the floatItems */ QList floatItems() const; /** * @brief Returns a list of all DataPlugins on the layer * @return the list of DataPlugins */ QList dataPlugins() const; /** * @brief Returns all widgets of dataPlugins on the position curpos */ QList whichItemAt( const QPoint& curpos ) const; /** * @brief Returns the planet object for the current map. * @return the planet object for the current map */ Planet* planet() const; /** * @brief Return the current tile zoom level. For example for OpenStreetMap * possible values are 1..18, for BlueMarble 0..6. */ int tileZoomLevel() const; + void reloadMap() const; + public Q_SLOTS: void clearVolatileTileCache(); /** * @brief Set the limit of the volatile (in RAM) tile cache. * @param kilobytes The limit in kilobytes. */ void setVolatileTileCacheLimit( quint64 kiloBytes ); void clearPersistentTileCache(); // private Q_SLOTS: void paintTile( TextureTile* tile, int x, int y, int level, Marble::GeoSceneTexture *textureLayer, bool requestTileUpdate ); /** * @brief Update the model */ void update(); Q_SIGNALS: /** * @brief Signal that the MarbleModel has started to create a new set of tiles. * @param * @see zoomView() */ void creatingTilesStart( TileCreator*, const QString& name, const QString& description ); /** * @brief Signal that the map theme has changed, and to which theme. * @param mapTheme the identifier of the new map theme. * @see mapTheme * @see setMapTheme */ void themeChanged( QString mapTheme ); /** * @brief Signal that the MarbleModel has changed in general */ void modelChanged(); /** * @brief Signal that a timer has gone off. * * This is currently used only for GPS things right now, but will * likely be used for more things in the future. */ void timeout(); /** * This signal is emit when the settings of a plugin changed. */ void pluginSettingsChanged(); /** * This signal is emitted when the repaint of the view was requested. * If available with the @p dirtyRegion which is the region the view will change in. * If dirtyRegion.isEmpty() returns true, the whole viewport has to be repainted. */ void repaintNeeded( QRegion dirtyRegion ); + void downloadTile( const QUrl& sourceUrl, const QString& destinationFileName, + const QString& id ) const; + private: Q_DISABLE_COPY( MarbleModel ) MarbleModelPrivate * const d; Q_PRIVATE_SLOT( d, void notifyModelChanged() ) Q_PRIVATE_SLOT( d, void geoDataDocumentAdded( const GeoDataDocument& ) ) }; } #endif // MARBLEMODEL_H Index: trunk/KDE/kdeedu/marble/src/lib/MarbleModel.cpp =================================================================== --- trunk/KDE/kdeedu/marble/src/lib/MarbleModel.cpp (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/lib/MarbleModel.cpp (revision 1011005) @@ -1,894 +1,922 @@ // // This file is part of the Marble Desktop 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 2006-2007 Torsten Rahn " // Copyright 2007 Inge Wallin " -// Copyright 2008 Jens-Michael Hoffmann +// Copyright 2008,2009 Jens-Michael Hoffmann // Copyright 2008-2009 Patrick Spendrin // #include "MarbleModel.h" #include #include #include #include #include #include #include #include #include "global.h" #include "gps/GpsLayer.h" #include "GeoSceneDocument.h" #include "GeoSceneFilter.h" #include "GeoSceneHead.h" #include "GeoSceneLayer.h" #include "GeoSceneMap.h" #include "GeoScenePalette.h" #include "GeoSceneTexture.h" #include "GeoSceneVector.h" #include "GeoSceneXmlDataSource.h" #include "GeoDataDocument.h" #include "GeoDataStyle.h" #include "DgmlAuxillaryDictionary.h" #include "FileStoragePolicy.h" #include "GeoPainter.h" #include "FileViewModel.h" #include "SphericalScanlineTextureMapper.h" #include "EquirectScanlineTextureMapper.h" #include "MercatorScanlineTextureMapper.h" #include "gps/GpxFileModel.h" #include "HttpDownloadManager.h" #include "KmlFileViewItem.h" #include "LayerManager.h" #include "MarbleDataFacade.h" #include "MarbleDirs.h" #include "MarblePlacemarkModel.h" #include "MarbleGeometryModel.h" #include "MergedLayerDecorator.h" #include "PlacemarkManager.h" #include "PlacemarkLayout.h" #include "PlacemarkPainter.h" #include "Planet.h" #include "StoragePolicy.h" #include "SunLocator.h" #include "TextureColorizer.h" #include "TextureTile.h" #include "TileCreator.h" #include "TileCreatorDialog.h" #include "TileLoader.h" +#include "TileLoaderHelper.h" #include "VectorComposer.h" #include "ViewParams.h" #include "ViewportParams.h" namespace Marble { class MarbleModelPrivate { public: MarbleModelPrivate( MarbleModel *parent ) : m_parent( parent ), m_dataFacade( 0 ), m_mapTheme( 0 ), m_layerManager( 0 ), m_downloadManager( new HttpDownloadManager( QUrl(), new FileStoragePolicy( MarbleDirs::localPath() ))) { } ~MarbleModelPrivate() { delete m_downloadManager; } void resize( int width, int height ); void notifyModelChanged(); void geoDataDocumentAdded( const GeoDataDocument& document ); static QAtomicInt refCounter; MarbleModel *m_parent; MarbleDataFacade *m_dataFacade; // View and paint stuff GeoSceneDocument *m_mapTheme; LayerManager *m_layerManager; static TextureColorizer *m_texcolorizer; //left as null if unused HttpDownloadManager *m_downloadManager; TileLoader *m_tileLoader; AbstractScanlineTextureMapper *m_texmapper; static VectorComposer *m_veccomposer; // FIXME: Make not a pointer. // Places on the map PlacemarkManager *m_placemarkmanager; MarblePlacemarkModel *m_placemarkmodel; PlacemarkLayout *m_placemarkLayout; MarbleGeometryModel *m_geometrymodel; QSortFilterProxyModel *m_popSortModel; // Misc stuff. ExtDateTime *m_dateTime; SunLocator *m_sunLocator; MergedLayerDecorator *m_layerDecorator; // Selection handling QItemSelectionModel *m_placemarkselectionmodel; //Gps Stuff GpsLayer *m_gpsLayer; GpxFileModel *m_gpxFileModel; QTimer *m_timer; Planet *m_planet; }; VectorComposer *MarbleModelPrivate::m_veccomposer = 0; TextureColorizer *MarbleModelPrivate::m_texcolorizer = 0; QAtomicInt MarbleModelPrivate::refCounter(0); MarbleModel::MarbleModel( QObject *parent ) : QObject( parent ), d( new MarbleModelPrivate( this ) ) { MarbleModelPrivate::refCounter.ref(); + connect( this, SIGNAL( downloadTile( QUrl, QString, QString )), + d->m_downloadManager, SLOT( addJob( QUrl, QString, QString ))); d->m_dataFacade = new MarbleDataFacade( this ); d->m_tileLoader = new TileLoader( d->m_downloadManager, this ); d->m_texmapper = 0; if( MarbleModelPrivate::refCounter == 1 ) { d->m_veccomposer = new VectorComposer(); d->m_texcolorizer = 0; /* d->m_texcolorizer is not initialized here since it takes a long time to create the palette and it might not even be used. Instead it's created in setMapTheme if the theme being loaded does need it. If the theme doesn't need it, it's left as is. */ } d->m_placemarkmanager = new PlacemarkManager(); connect( d->m_placemarkmanager, SIGNAL( geoDataDocumentAdded( const GeoDataDocument& ) ), this, SLOT( geoDataDocumentAdded( const GeoDataDocument& ) ) ); d->m_placemarkmodel = new MarblePlacemarkModel( d->m_placemarkmanager, this ); d->m_popSortModel = new QSortFilterProxyModel( this ); d->m_popSortModel->setSourceModel( d->m_placemarkmodel ); // d->m_popSortModel->setSortLocaleAware( true ); // d->m_popSortModel->setDynamicSortFilter( true ); d->m_popSortModel->setSortRole( MarblePlacemarkModel::PopularityIndexRole ); d->m_popSortModel->sort( 0, Qt::DescendingOrder ); d->m_placemarkselectionmodel = new QItemSelectionModel( d->m_popSortModel ); d->m_geometrymodel = new MarbleGeometryModel(); d->m_placemarkmanager->setGeoModel( d->m_geometrymodel ); d->m_placemarkLayout = new PlacemarkLayout( this ); connect( d->m_placemarkmanager, SIGNAL( finalize() ), d->m_placemarkLayout, SLOT( requestStyleReset() ) ); connect( d->m_placemarkselectionmodel, SIGNAL( selectionChanged( QItemSelection, QItemSelection) ), d->m_placemarkLayout, SLOT( requestStyleReset() ) ); connect( d->m_placemarkmodel, SIGNAL( layoutChanged() ), d->m_placemarkLayout, SLOT( requestStyleReset() ) ); /* * Create FileViewModel */ connect( fileViewModel(), SIGNAL( modelChanged() ), this, SIGNAL( modelChanged() ) ); d->m_gpxFileModel = new GpxFileModel( this ); d->m_gpsLayer = new GpsLayer( d->m_gpxFileModel ); connect( fileViewModel(), SIGNAL(layoutChanged()), d->m_gpsLayer, SLOT(clearModel() ) ); d->m_layerManager = new LayerManager( d->m_dataFacade, this ); // FIXME: more on the spot update names and API connect ( d->m_layerManager, SIGNAL( floatItemsChanged() ), this, SIGNAL( modelChanged() ) ); connect ( d->m_layerManager, SIGNAL( pluginSettingsChanged() ), this, SIGNAL( pluginSettingsChanged() ) ); connect ( d->m_layerManager, SIGNAL( repaintNeeded( QRegion ) ), this, SIGNAL( repaintNeeded( QRegion ) ) ); d->m_timer = new QTimer( this ); d->m_timer->start( 200 ); connect( d->m_timer, SIGNAL( timeout() ), this, SIGNAL( timeout() ) ); d->m_dateTime = new ExtDateTime(); /* Assume we are dealing with the earth */ d->m_planet = new Planet( "earth" ); d->m_sunLocator = new SunLocator( d->m_dateTime, d->m_planet ); d->m_layerDecorator = new MergedLayerDecorator( d->m_sunLocator ); connect(d->m_dateTime, SIGNAL( timeChanged() ), d->m_sunLocator, SLOT( update() ) ); connect( d->m_layerDecorator, SIGNAL( repaintMap() ), SIGNAL( modelChanged() ) ); } MarbleModel::~MarbleModel() { // qDebug() << "MarbleModel::~MarbleModel"; delete d->m_texmapper; delete d->m_tileLoader; // disconnects from downloadManager in dtor if( MarbleModelPrivate::refCounter == 1 ) { delete d->m_veccomposer; delete d->m_texcolorizer; } delete d->m_geometrymodel; delete d->m_placemarkmodel; delete d->m_popSortModel; delete d->m_placemarkmanager; delete d->m_gpsLayer; delete d->m_mapTheme; delete d->m_timer; delete d->m_layerManager; delete d->m_dataFacade; delete d->m_layerDecorator; delete d->m_sunLocator; delete d->m_dateTime; delete d->m_planet; delete d; MarbleModelPrivate::refCounter.deref(); qDebug() << "Model deleted:" << this; } bool MarbleModel::showGps() const { return d->m_gpsLayer->visible(); } void MarbleModel::setShowGps( bool visible ) { d->m_gpsLayer->setVisible( visible ); } void MarbleModel::startPolling( int time ) { d->m_timer->start( time ); } void MarbleModel::stopPolling() { d->m_timer->stop(); } QString MarbleModel::mapThemeId() const { QString mapThemeId = ""; if (d->m_mapTheme) mapThemeId = d->m_mapTheme->head()->mapThemeId(); return mapThemeId; } GeoSceneDocument* MarbleModel::mapTheme() const { return d->m_mapTheme; } // Set a particular theme for the map and load the appropriate tile level. // If the tiles (for the lowest tile level) haven't been created already // then create them here and now. // // FIXME: Move the tile creation dialogs out of this function. Change // them into signals instead. // FIXME: Get rid of 'currentProjection' here. It's totally misplaced. // void MarbleModel::setMapTheme( GeoSceneDocument* mapTheme, Projection currentProjection ) { d->m_mapTheme = mapTheme; // Some output to show how to use this stuff ... qDebug() << "DGML2 Name : " << d->m_mapTheme->head()->name(); /* qDebug() << "DGML2 Description: " << d->m_mapTheme->head()->description(); if ( d->m_mapTheme->map()->hasTextureLayers() ) qDebug() << "Contains texture layers! "; else qDebug() << "Does not contain any texture layers! "; qDebug() << "Number of SRTM textures: " << d->m_mapTheme->map()->layer("srtm")->datasets().count(); if ( d->m_mapTheme->map()->hasVectorLayers() ) qDebug() << "Contains vector layers! "; else qDebug() << "Does not contain any vector layers! "; */ //Don't change the planet unless we have to... if( d->m_mapTheme->head()->target().toLower() != d->m_planet->id() ) { qDebug() << "Changing Planet"; *(d->m_planet) = Planet( d->m_mapTheme->head()->target().toLower() ); sunLocator()->setPlanet(d->m_planet); } if ( d->m_mapTheme->map()->hasTextureLayers() ) { // If the tiles aren't already there, put up a progress dialog // while creating them. // As long as we don't have an Layer Management Class we just lookup // the name of the layer that has the same name as the theme ID QString themeID = d->m_mapTheme->head()->theme(); GeoSceneLayer *layer = static_cast( d->m_mapTheme->map()->layer( themeID ) ); GeoSceneTexture *texture = static_cast( layer->groundDataset() ); QString sourceDir = texture->sourceDir(); QString installMap = texture->installMap(); QString role = d->m_mapTheme->map()->layer( themeID )->role(); if ( !TileLoader::baseTilesAvailable( layer ) && !installMap.isEmpty() ) { qDebug() << "Base tiles not available. Creating Tiles ... \n" << "SourceDir: " << sourceDir << "InstallMap:" << installMap; MarbleDirs::debug(); TileCreator *tileCreator = new TileCreator( sourceDir, installMap, (role == "dem") ? "true" : "false" ); TileCreatorDialog tileCreatorDlg( tileCreator, 0 ); tileCreatorDlg.setSummary( d->m_mapTheme->head()->name(), d->m_mapTheme->head()->description() ); tileCreatorDlg.exec(); qDebug("Tile creation completed"); } d->m_tileLoader->setLayer( layer ); } else { d->m_tileLoader->flush(); } setupTextureMapper( currentProjection ); // Set all the colors for the vector layers if ( d->m_mapTheme->map()->hasVectorLayers() ) { d->m_veccomposer->setOceanColor( d->m_mapTheme->map()->backgroundColor() ); // Just as with textures, this is a workaround for DGML2 to // emulate the old behaviour. GeoSceneLayer *layer = d->m_mapTheme->map()->layer( "mwdbii" ); if ( layer ) { GeoSceneVector *vector = 0; vector = static_cast( layer->dataset("pdiffborder") ); if ( vector ) d->m_veccomposer->setCountryBorderColor( vector->pen().color() ); vector = static_cast( layer->dataset("rivers") ); if ( vector ) d->m_veccomposer->setRiverColor( vector->pen().color() ); vector = static_cast( layer->dataset("pusa48") ); if ( vector ) d->m_veccomposer->setStateBorderColor( vector->pen().color() ); vector = static_cast( layer->dataset("plake") ); if ( vector ) d->m_veccomposer->setLakeColor( vector->pen().color() ); vector = static_cast( layer->dataset("pcoast") ); if ( vector ) { d->m_veccomposer->setLandColor( vector->brush().color() ); d->m_veccomposer->setCoastColor( vector->pen().color() ); } } } d->m_geometrymodel->setGeoDataRoot( 0 ); QStringList loadedContainers = d->m_placemarkmanager->containers(); QStringList loadList; const QVector & layers = d->m_mapTheme->map()->layers(); QVector::const_iterator it = layers.constBegin(); QVector::const_iterator end = layers.constEnd(); for (; it != end; ++it) { GeoSceneLayer* layer = *it; if ( layer->backend() == dgml::dgmlValue_geodata && layer->datasets().count() > 0 ) { // look for documents const QVector & datasets = layer->datasets(); QVector::const_iterator itds = datasets.constBegin(); QVector::const_iterator endds = datasets.constEnd(); for (; itds != endds; ++itds) { GeoSceneAbstractDataset* dataset = *itds; if( dataset->fileFormat() == "KML" ) { QString containername = reinterpret_cast(dataset)->filename(); if( containername.endsWith(".kml") ) containername.remove(".kml"); loadedContainers.removeOne( containername ); loadList << containername; } } } } // unload old standard Placemarks which are not part of the new map foreach(const QString& container, loadedContainers) { loadedContainers.pop_front(); d->m_placemarkmanager->removePlacemarkKey( container ); } // load new standard Placemarks foreach(const QString& container, loadList) { loadList.pop_front(); d->m_placemarkmanager->addPlacemarkFile( container, loadList.isEmpty() ); } d->notifyModelChanged(); d->m_placemarkLayout->requestStyleReset(); // FIXME: Still needs to get fixed for the DGML2 refactoring // d->m_placemarkLayout->placemarkPainter()->setDefaultLabelColor( d->m_maptheme->labelColor() ); if( !d->m_mapTheme->map()->filters().isEmpty() ) { GeoSceneFilter *filter= d->m_mapTheme->map()->filters().first(); if( filter->type() == "colorize" ) { //no need to look up with MarbleDirs twice so they are left null for now QString seafile, landfile; QList palette = filter->palette(); foreach ( GeoScenePalette *curPalette, palette ) { if( curPalette->type() == "sea" ) { seafile = MarbleDirs::path( curPalette->file() ); } else if( curPalette->type() == "land" ) { landfile = MarbleDirs::path( curPalette->file() ); } } //look up locations if they are empty if(seafile.isEmpty()) seafile = MarbleDirs::path( "seacolors.leg" ); if(landfile.isEmpty()) landfile = MarbleDirs::path( "landcolors.leg" ); if( !d->m_texcolorizer ) { /* This is where the TextureColorizer is created if it's needed by the new map theme. */ d->m_texcolorizer = new TextureColorizer( seafile, landfile ); } else if( d->m_texcolorizer->seafile() != seafile || d->m_texcolorizer->landfile() != landfile ) { d->m_texcolorizer->generatePalette( seafile, landfile ); } } } qDebug() << "THEME CHANGED: ***" << mapTheme->head()->mapThemeId(); emit themeChanged( mapTheme->head()->mapThemeId() ); d->m_layerManager->syncViewParamsAndPlugins( mapTheme ); d->notifyModelChanged(); } void MarbleModel::setupTextureMapper( Projection projection ) { // FIXME: replace this with an approach based on the factory method pattern. delete d->m_texmapper; switch( projection ) { case Spherical: d->m_texmapper = new SphericalScanlineTextureMapper( d->m_tileLoader, this ); break; case Equirectangular: d->m_texmapper = new EquirectScanlineTextureMapper( d->m_tileLoader, this ); break; case Mercator: d->m_texmapper = new MercatorScanlineTextureMapper( d->m_tileLoader, this ); break; } connect( d->m_texmapper, SIGNAL( mapChanged() ), this, SLOT( notifyModelChanged() ) ); } HttpDownloadManager* MarbleModel::downloadManager() const { return d->m_downloadManager; } void MarbleModel::setDownloadManager( HttpDownloadManager *downloadManager ) { HttpDownloadManager *previousDownloadManager = d->m_downloadManager; d->m_tileLoader->setDownloadManager( downloadManager ); d->m_downloadManager = downloadManager; delete previousDownloadManager; } void MarbleModelPrivate::resize( int width, int height ) { if ( m_mapTheme->map()->hasTextureLayers() ) { m_texmapper->resizeMap( width, height ); } m_veccomposer->resizeMap( width, height ); } void MarbleModel::paintGlobe( GeoPainter *painter, int width, int height, ViewParams *viewParams, bool redrawBackground, const QRect& dirtyRect ) { if ( !d->m_texmapper ) return; d->resize( width, height ); // FIXME: Remove this once the LMC is there: QString themeID = d->m_mapTheme->head()->theme(); GeoSceneLayer *layer = static_cast( d->m_mapTheme->map()->layer( themeID ) ); QStringList renderPositions; renderPositions << "STARS" << "BEHIND_TARGET"; d->m_layerManager->renderLayers( painter, viewParams, renderPositions ); if ( redrawBackground ) { if ( d->m_mapTheme->map()->hasTextureLayers() ) { // Create the height map image a.k.a viewParams->m_canvasImage. d->m_texmapper->mapTexture( viewParams ); if ( !viewParams->showElevationModel() && layer->role() == "dem" && !d->m_mapTheme->map()->filters().isEmpty() ) { GeoSceneFilter *filter= d->m_mapTheme->map()->filters().first(); viewParams->coastImage()->fill( Qt::transparent ); // Create VectorMap d->m_veccomposer->drawTextureMap( viewParams ); // Colorize using settings from when the map was loaded // there's no need to check the palette because it's set with the map theme if( filter->type() == "colorize" ) { d->m_texcolorizer->colorize( viewParams ); } } //else { qDebug() << "No filters to act on..."; } } } // Paint the map on the Widget // QTime t; // t.start(); int radius = (int)(1.05 * (qreal)(viewParams->radius())); if ( d->m_mapTheme->map()->hasTextureLayers() ) { if ( viewParams->projection() == Spherical ) { QRect rect( width / 2 - radius, height / 2 - radius, 2 * radius, 2 * radius); rect = rect.intersect( dirtyRect ); painter->drawImage( rect, *viewParams->canvasImage(), rect ); } else { painter->drawImage( dirtyRect, *viewParams->canvasImage(), dirtyRect ); } } // qDebug( "Painted in %ims", t.elapsed() ); renderPositions.clear(); renderPositions << "SURFACE"; // Paint the vector layer. if ( d->m_mapTheme->map()->hasVectorLayers() ) { if ( !d->m_mapTheme->map()->hasTextureLayers() ) { d->m_veccomposer->paintBaseVectorMap( painter, viewParams ); } d->m_layerManager->renderLayers( painter, viewParams, renderPositions ); // Add further Vectors d->m_veccomposer->paintVectorMap( painter, viewParams ); } else { d->m_layerManager->renderLayers( painter, viewParams, renderPositions ); } // Paint the GeoDataPlacemark layer bool showPlaces, showCities, showTerrain, showOtherPlaces; viewParams->propertyValue( "places", showPlaces ); viewParams->propertyValue( "cities", showCities ); viewParams->propertyValue( "terrain", showTerrain ); viewParams->propertyValue( "otherplaces", showOtherPlaces ); if ( showPlaces && ( showCities || showTerrain || showOtherPlaces ) && d->m_popSortModel->rowCount() > 0 ) { d->m_placemarkLayout->paintPlaceFolder( painter, viewParams, d->m_popSortModel, d->m_placemarkselectionmodel ); } // Paint the Gps Layer // d->m_gpsLayer->setVisible( viewParams->showGps() ); //FIXME:We might just send ViewParams instead of this bunch of parameters d->m_gpsLayer->paintLayer( painter, viewParams->canvasImage()->size(), viewParams ); renderPositions.clear(); renderPositions << "HOVERS_ABOVE_SURFACE" << "ATMOSPHERE" << "ORBIT" << "ALWAYS_ON_TOP" << "FLOAT_ITEM" << "USER_TOOLS"; d->m_layerManager->renderLayers( painter, viewParams, renderPositions ); } QAbstractItemModel *MarbleModel::placemarkModel() const { return d->m_placemarkmodel; } QItemSelectionModel *MarbleModel::placemarkSelectionModel() const { return d->m_placemarkselectionmodel; } QAbstractItemModel *MarbleModel::geometryModel() const { return d->m_geometrymodel; } VectorComposer *MarbleModel::vectorComposer() const { return d->m_veccomposer; } TextureColorizer *MarbleModel::textureColorizer() const { return d->m_texcolorizer; } AbstractScanlineTextureMapper *MarbleModel::textureMapper() const { return d->m_texmapper; } PlacemarkLayout *MarbleModel::placemarkLayout() const { return d->m_placemarkLayout; } GpsLayer *MarbleModel::gpsLayer() const { return d->m_gpsLayer; } GpxFileModel *MarbleModel::gpxFileModel() const { return d->m_gpxFileModel; } FileViewModel *MarbleModel::fileViewModel() const { return d->m_placemarkmanager->fileViewModel(); } void MarbleModel::addPlacemarkFile( const QString& filename ) { d->m_placemarkmanager->loadKml( filename, false ); d->notifyModelChanged(); } void MarbleModel::addPlacemarkData( const QString& data, const QString& key ) { d->m_placemarkmanager->addPlacemarkData( data, key ); d->notifyModelChanged(); } void MarbleModel::removePlacemarkKey( const QString& key ) { d->m_placemarkmanager->removePlacemarkKey( key ); d->notifyModelChanged(); } QVector MarbleModel::whichFeatureAt( const QPoint& curpos ) const { return d->m_placemarkLayout->whichPlacemarkAt( curpos ); } void MarbleModelPrivate::notifyModelChanged() { emit m_parent->modelChanged(); } void MarbleModelPrivate::geoDataDocumentAdded( const GeoDataDocument& document ) { /* QVector::Iterator end = document->end(); QVector::Iterator itr = document->begin(); for ( ; itr != end; ++itr ) { // use *itr (or itr.value()) here QString styleUrl = itr->styleUrl().remove('#'); itr->setStyle( &document->style( styleUrl ) ); } m_geometrymodel->setGeoDataRoot( document );*/ } void MarbleModel::update() { qDebug() << "MarbleModel::update()"; QTimer::singleShot( 0, d->m_tileLoader, SLOT( update() ) ); } qreal MarbleModel::planetRadius() const { return d->m_planet->radius(); } QString MarbleModel::planetName() const { return d->m_planet->name(); } ExtDateTime* MarbleModel::dateTime() const { // qDebug() << "In dateTime, model:" << this; // qDebug() << d << ":" << d->m_dateTime; return d->m_dateTime; } SunLocator* MarbleModel::sunLocator() const { return d->m_sunLocator; } MergedLayerDecorator* MarbleModel::layerDecorator() const { return d->m_layerDecorator; } void MarbleModel::clearVolatileTileCache() { d->m_tileLoader->update(); qDebug() << "Cleared Volatile Cache!"; } quint64 MarbleModel::volatileTileCacheLimit() const { return d->m_tileLoader->volatileCacheLimit(); } void MarbleModel::setVolatileTileCacheLimit( quint64 kiloBytes ) { d->m_tileLoader->setVolatileCacheLimit( kiloBytes ); } void MarbleModel::clearPersistentTileCache() { downloadManager()->storagePolicy()->clearCache(); // Now create base tiles again if needed if ( d->m_mapTheme->map()->hasTextureLayers() ) { // If the tiles aren't already there, put up a progress dialog // while creating them. // As long as we don't have an Layer Management Class we just lookup // the name of the layer that has the same name as the theme ID QString themeID = d->m_mapTheme->head()->theme(); GeoSceneLayer *layer = static_cast( d->m_mapTheme->map()->layer( themeID ) ); GeoSceneTexture *texture = static_cast( layer->groundDataset() ); QString sourceDir = texture->sourceDir(); QString installMap = texture->installMap(); QString role = d->m_mapTheme->map()->layer( themeID )->role(); if ( !TileLoader::baseTilesAvailable( layer ) && !installMap.isEmpty() ) { qDebug() << "Base tiles not available. Creating Tiles ... \n" << "SourceDir: " << sourceDir << "InstallMap:" << installMap; MarbleDirs::debug(); TileCreator *tileCreator = new TileCreator( sourceDir, installMap, (role == "dem") ? "true" : "false" ); TileCreatorDialog tileCreatorDlg( tileCreator, 0 ); tileCreatorDlg.setSummary( d->m_mapTheme->head()->name(), d->m_mapTheme->head()->description() ); tileCreatorDlg.exec(); qDebug("Tile creation completed"); } } } void MarbleModel::paintTile( TextureTile* tile, int x, int y, int level, GeoSceneTexture *textureLayer, bool requestTileUpdate ) { // qDebug() << "MarbleModel::paintTile: " << "x: " << x << "y:" << y << "level: " << level // << "requestTileUpdate" << requestTileUpdate; if ( d->m_downloadManager != 0 ) { connect( d->m_layerDecorator, SIGNAL( downloadTile( QUrl, QString, QString ) ), d->m_downloadManager, SLOT( addJob( QUrl, QString, QString ) ) ); } d->m_layerDecorator->setInfo( x, y, level, tile->id() ); d->m_layerDecorator->setTile( tile->tile() ); d->m_layerDecorator->paint( "maps/" + textureLayer->sourceDir(), mapTheme() ); tile->initJumpTables( requestTileUpdate ); } QList MarbleModel::renderPlugins() const { return d->m_layerManager->renderPlugins(); } QList MarbleModel::floatItems() const { return d->m_layerManager->floatItems(); } QList MarbleModel::dataPlugins() const { return d->m_layerManager->dataPlugins(); } QList MarbleModel::whichItemAt( const QPoint& curpos ) const { return d->m_layerManager->whichItemAt( curpos ); } Planet* MarbleModel::planet() const { return d->m_planet; } int MarbleModel::tileZoomLevel() const { if (!d->m_texmapper) return -1; return d->m_texmapper->tileZoomLevel(); } +void MarbleModel::reloadMap() const +{ + if ( !d->m_mapTheme->map()->hasTextureLayers() ) + return; + + const QString themeId = d->m_mapTheme->head()->theme(); + GeoSceneLayer * const layer = static_cast( d->m_mapTheme->map()-> + layer( themeId )); + Q_ASSERT( layer ); + GeoSceneTexture * const texture = static_cast( layer->groundDataset() ); + Q_ASSERT( texture ); + + Q_ASSERT( d->m_tileLoader ); + QList displayed = d->m_tileLoader->tilesOnDisplay(); + QList::const_iterator pos = displayed.constBegin(); + QList::const_iterator const end = displayed.constEnd(); + for (; pos != end; ++pos ) { + TileId const & id = *pos; + QUrl sourceUrl = TileLoaderHelper::downloadUrl( texture, id.zoomLevel(), id.x(), id.y() ); + QString destFileName = TileLoaderHelper::relativeTileFileName( texture, id.zoomLevel(), + id.x(), id.y() ); + emit downloadTile( sourceUrl, destFileName, id.toString() ); + } +} + } #include "MarbleModel.moc" Index: trunk/KDE/kdeedu/marble/src/lib/MarbleMap.h =================================================================== --- trunk/KDE/kdeedu/marble/src/lib/MarbleMap.h (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/lib/MarbleMap.h (revision 1011005) @@ -1,817 +1,825 @@ // // This file is part of the Marble Desktop 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 2006-2008 Torsten Rahn " // Copyright 2007 Inge Wallin " +// Copyright 2009 Jens-Michael Hoffmann // #ifndef MARBLEMAP_H #define MARBLEMAP_H /** @file * This file contains the headers for MarbleMap. * * @author Torsten Rahn * @author Inge Wallin */ #include #include #include #include #include #include "marble_export.h" #include "GeoDataCoordinates.h" // In geodata/data/ #include "Quaternion.h" #include "global.h" // types needed in all of marble. // Qt class QAbstractItemModel; class QModelIndex; class QItemSelectionModel; class QStyleOptionGraphicsItem; class QUrl; namespace Marble { // MarbleMap //class MarbleWidgetInputHandler; //class MarbleWidgetPopupMenu; class MarbleMapPrivate; // Marble class MarbleModel; class ViewParams; class MeasureTool; class SunLocator; class GpxFileModel; class FileViewModel; class GeoPainter; class RenderPlugin; class AbstractFloatItem; /** * @short A class that can paint a view of the earth. * * FIXME: Change this description when we are done. * * This class can paint a view of the earth or any other globe, * depending on which dataset is used. It can be used to show the * globe in a widget like MarbleWidget does, or on any other * QPaintDevice. * * The projection and other view parameters that control how MarbleMap * paints the map is given through the class ViewParams. If the * programmer wants to allow the user to control the map, he/she has * to provide a way for the user to interact with it. An example of * this can be seen in the class MarbleWidgetInputHandler, that lets * the user control a MarbleWidget that uses MarbleMap internally. * * The MarbleMap needs to be provided with a data model to * work. This model is contained in the MarbleModel class. The widget * can also construct its own model if none is given to the * constructor. This data model contains 3 separate datatypes: * tiles which provide the background, vectors which * provide things like country borders and coastlines and * placemarks which can show points of interest, such as * cities, mountain tops or the poles. * * @see MarbleWidget * @see MarbleControlBox * @see MarbleModel */ class MARBLE_EXPORT MarbleMap : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.MarbleMap") public: friend class MarbleWidget; /** * @brief Construct a new MarbleMap. * * This constructor should be used when you will only use one * MarbleMap. The widget will create its own MarbleModel when * created. */ MarbleMap(); /** * @brief Construct a new MarbleMap. * @param model the data model for the widget. * * This constructor should be used when you plan to use more than * one MarbleMap for the same MarbleModel (not yet supported, * but will be soon). */ explicit MarbleMap( MarbleModel *model ); virtual ~MarbleMap(); /** * @brief Return the model that this view shows. */ MarbleModel *model() const; // Accessors to internal objects; ViewParams *viewParams(); MeasureTool *measureTool(); void setSize(int width, int height); void setSize(QSize size); QSize size() const; int width() const; int height() const; /** * @brief Return the radius of the globe in pixels. */ int radius() const; /** * @brief Set the radius of the globe in pixels. * @param radius The new globe radius value in pixels. */ void setRadius(int radius); /** * @brief Return the current zoom level. */ int zoom() const; /** * @brief Return the current distance. */ qreal distance() const; /** * @brief Set the distance of the observer to the globe in km. * @param distance The new distance in km. */ void setDistance( qreal distance ); /** * @brief Return the current distance string. */ QString distanceString() const; /** * @brief return the minimum zoom value for the current map theme. */ int minimumZoom() const; /** * @brief return the minimum zoom value for the current map theme. */ int maximumZoom() const; /** * @brief return if the map needs to be updated. */ bool needsUpdate() const; /** * @brief Mark the map as needing an update. */ void setNeedsUpdate(); /** * @brief Get the screen coordinates corresponding to geographical coordinates in the map. * @param lon the lon coordinate of the requested pixel position * @param lat the lat coordinate of the requested pixel position * @param x the x coordinate of the pixel is returned through this parameter * @param y the y coordinate of the pixel is returned through this parameter * @return @c true if the geographical coordinates are visible on the screen * @c false if the geographical coordinates are not visible on the screen */ bool screenCoordinates( qreal lon, qreal lat, qreal& x, qreal& y ); /** * @brief Get the Y coordinate of the North Pole. * @return the pixel address of the geographical north pole. */ int northPoleY(); /** * @brief Get the earth coordinates corresponding to a pixel in the map. * @param x the x coordinate of the pixel * @param y the y coordinate of the pixel * @param lon the longitude angle is returned through this parameter * @param lat the latitude angle is returned through this parameter * @return @c true if the pixel (x, y) is within the globe * @c false if the pixel (x, y) is outside the globe, i.e. in space. */ bool geoCoordinates( int x, int y, qreal& lon, qreal& lat, GeoDataCoordinates::Unit = GeoDataCoordinates::Degree ); /** * @brief Return the longitude of the center point. */ qreal centerLongitude() const; /** * @brief Return the latitude of the center point. */ qreal centerLatitude() const; /** * @brief returns the model for all the placemarks on the globe. */ QAbstractItemModel *placemarkModel() const; /** * @brief returns the selection model for all the placemarks on the globe. */ QItemSelectionModel *placemarkSelectionModel() const; /** * @brief Return how much the map will move if one of the move slots are called. * @return The move step. */ qreal moveStep(); /** * @brief Add a GeoDataPlacemark file to the model. * @param filename the filename of the file containing the Placemarks. */ void addPlacemarkFile( const QString &filename ); /** * @brief Add GeoDataPlacemark data as string to the model. * @param data the string containing the Placemarks. * @param key the string needed to identify the data */ void addPlacemarkData( const QString& data, const QString& key = "data" ); /** * @brief remove data or files from the model. * @param key either the filename or the string used to identify the data in addPlacemarkFile and addPlacemarkData */ void removePlacemarkKey( const QString& key ); /** * @brief Return the quaternion that specifies the rotation of the globe. * @return The quaternion that describes the rotation of the globe. */ Quaternion planetAxis() const; /** * @brief Return a QPixmap with the current contents of the map. */ QPixmap mapScreenShot(); /** + * @brief Reload the currently displayed map by reloading texture tiles + * from the internet. In the future this should be extended to all + * kinds of data which is used in the map. + */ + void reload() const; + + /** * @brief Return the property value by name. * @return The property value (usually: visibility). */ bool propertyValue( const QString& name) const; /** * @brief Return whether the overview map is visible. * @return The overview map visibility. */ bool showOverviewMap() const; /** * @brief Return whether the scale bar is visible. * @return The scale bar visibility. */ bool showScaleBar() const; /** * @brief Return whether the compass bar is visible. * @return The compass visibility. */ bool showCompass() const; /** * @brief Return whether the cloud cover is visible. * @return The cloud cover visibility. */ bool showClouds() const; /** * @brief Return whether the atmospheric glow is visible. * @return The cloud cover visibility. */ bool showAtmosphere() const; /** * @brief Return whether the crosshairs are visible. * @return The crosshairs' visibility. */ bool showCrosshairs() const; /** * @brief Return whether the coordinate grid is visible. * @return The coordinate grid visibility. */ bool showGrid() const; /** * @brief Return whether the place marks are visible. * @return The place mark visibility. */ bool showPlaces() const; /** * @brief Return whether the city place marks are visible. * @return The city place mark visibility. */ bool showCities() const; /** * @brief Return whether the terrain place marks are visible. * @return The terrain place mark visibility. */ bool showTerrain() const; /** * @brief Return whether other places are visible. * @return The visibility of other places. */ bool showOtherPlaces() const; /** * @brief Return whether the relief is visible. * @return The relief visibility. */ bool showRelief() const; /** * @brief Return whether the elevation model is visible. * @return The elevation model visibility. */ bool showElevationModel() const; /** * @brief Return whether the ice layer is visible. * @return The ice layer visibility. */ bool showIceLayer() const; /** * @brief Return whether the borders are visible. * @return The border visibility. */ bool showBorders() const; /** * @brief Return whether the rivers are visible. * @return The rivers' visibility. */ bool showRivers() const; /** * @brief Return whether the lakes are visible. * @return The lakes' visibility. */ bool showLakes() const; /** * @brief Return whether Gps Data is visible. * @return The Gps Data's visibility. */ bool showGps() const; /** * @brief Return whether the frame rate gets displayed. * @return the frame rates visibility */ bool showFrameRate() const; /** * @brief Returns the limit in kilobytes of the persistent (on hard disc) tile cache. * @return the limit of persistent tile cache in kilobytes. */ quint64 persistentTileCacheLimit() const; /** * @brief Returns the limit in kilobytes of the volatile (in RAM) tile cache. * @return the limit of volatile tile cache in kilobytes. */ quint64 volatileTileCacheLimit() const; /** * @brief Return the sun locator object. * @return the sun locator object */ SunLocator* sunLocator(); QList renderPlugins() const; QList floatItems() const; public Q_SLOTS: void updateSun(); void centerSun(); /** * @brief Paint the map using a give painter. * @param painter The painter to use. * @param dirtyRect the rectangle that actually needs repainting. */ void paint( GeoPainter &painter, QRect &dirtyRect); /** * @brief Zoom the view to a certain zoomlevel * @param zoom the new zoom level. * * The zoom level is an abstract value without physical * interpretation. A zoom value around 1000 lets the viewer see * all of the earth in the default window. */ void zoomView(int zoom); /** * @brief Zoom the view by a certain step * @param zoomStep the difference between the old zoom and the new */ void zoomViewBy(int zoomStep); /** * @brief Zoom in by the amount zoomStep. */ void zoomIn(); /** * @brief Zoom out by the amount zoomStep. */ void zoomOut(); /** * @brief Rotate the view by the two angles phi and theta. * @param deltaLon an angle that specifies the change in terms of longitude * @param deltaLat an angle that specifies the change in terms of latitude * * This function rotates the view by two angles, * deltaLon ("theta") and deltaLat ("phi"). * If we start at (0, 0), the result will be the exact equivalent * of (lon, lat), otherwise the resulting angle will be the sum of * the previous position and the two offsets. */ void rotateBy( const qreal &deltaLon, const qreal &deltaLat ); /** * @brief Rotate the view by the angle specified by a Quaternion. * @param incRot a quaternion specifying the rotation */ void rotateBy( const Quaternion& incRot ); /** * @brief Center the view on a geographical point * @param lat an angle parallel to the latitude lines * +90(N) - -90(S) * @param lon an angle parallel to the longitude lines * +180(W) - -180(E) */ void centerOn( const qreal &lon, const qreal &lat ); /** * @brief Center the view on a point * @param index an index for a QModel, indicating a city */ void centerOn( const QModelIndex& index ); /** * @brief Set the latitude for the center point * @param lat the new value for the latitude */ void setCenterLatitude( qreal lat ); /** * @brief Set the longitude for the center point * @param lon the new value for the longitude */ void setCenterLongitude( qreal lon ); /** * @brief Get the Projection used for the map * @return @c Spherical a Globe * @return @c Equirectangular a flat map * @return @c Mercator another flat map */ Projection projection() const; /** * @brief Set the Projection used for the map * @param projection projection type (e.g. Spherical, Equirectangular, Mercator) */ void setProjection( Projection projection ); /** * @brief get the home point * @param lon the longitude of the home point. * @param lat the latitude of the home point. * @param zoom the default zoom level of the home point. */ void home(qreal &lon, qreal &lat, int& zoom); /** * @brief Set the home point * @param lon the longitude of the new home point. * @param lat the latitude of the new home point. * @param zoom the default zoom level for the new home point. */ void setHome(qreal lon, qreal lat, int zoom = 1050); /** * @brief Set the home point * @param homePoint the new home point. * @param zoom the default zoom level for the new home point. */ void setHome(const GeoDataCoordinates& homePoint, int zoom = 1050); /** * @brief Move left by the moveStep. */ void moveLeft(); /** * @brief Move right by the moveStep. */ void moveRight(); /** * @brief Move up by the moveStep. */ void moveUp(); /** * @brief Move down by the moveStep. */ void moveDown(); /** * @brief Center the view on the default start point with the default zoom. */ void goHome(); /** * @brief Get the ID of the current map theme * To ensure that a unique identifier is being used the theme does NOT * get represented by its name but the by relative location of the file * that specifies the theme: * * Example: * maptheme = "earth/bluemarble/bluemarble.dgml" */ QString mapThemeId() const; /** * @brief Set a new map theme * @param maptheme The ID of the new maptheme. To ensure that a unique * identifier is being used the theme does NOT get represented by its * name but the by relative location of the file that specifies the theme: * * Example: * maptheme = "earth/bluemarble/bluemarble.dgml" */ void setMapThemeId( const QString& maptheme ); /** * @brief Sets the value of a map theme property * @param value value of the property (usually: visibility) * * Later on we might add a "setPropertyType and a QVariant * if needed. */ void setPropertyValue( const QString& name, bool value ); /** * @brief Set whether the overview map overlay is visible * @param visible visibility of the overview map */ void setShowOverviewMap( bool visible ); /** * @brief Set whether the scale bar overlay is visible * @param visible visibility of the scale bar */ void setShowScaleBar( bool visible ); /** * @brief Set whether the compass overlay is visible * @param visible visibility of the compass */ void setShowCompass( bool visible ); /** * @brief Set whether the cloud cover is visible * @param visible visibility of the cloud cover */ void setShowClouds( bool visible ); /** * @brief Set whether the is tile is visible * NOTE: This is part of the transitional debug API * and might be subject to changes until Marble 0.8 * @param visible visibility of the tile */ void setShowTileId( bool visible ); /** * @brief Set whether the atmospheric glow is visible * @param visible visibility of the atmospheric glow */ void setShowAtmosphere( bool visible ); /** * @brief Set whether the crosshairs are visible * @param visible visibility of the crosshairs */ void setShowCrosshairs( bool visible ); /** * @brief Set whether the coordinate grid overlay is visible * @param visible visibility of the coordinate grid */ void setShowGrid( bool visible ); /** * @brief Set whether the place mark overlay is visible * @param visible visibility of the place marks */ void setShowPlaces( bool visible ); /** * @brief Set whether the city place mark overlay is visible * @param visible visibility of the city place marks */ void setShowCities( bool visible ); /** * @brief Set whether the terrain place mark overlay is visible * @param visible visibility of the terrain place marks */ void setShowTerrain( bool visible ); /** * @brief Set whether the other places overlay is visible * @param visible visibility of other places */ void setShowOtherPlaces( bool visible ); /** * @brief Set whether the relief is visible * @param visible visibility of the relief */ void setShowRelief( bool visible ); /** * @brief Set whether the elevation model is visible * @param visible visibility of the elevation model */ void setShowElevationModel( bool visible ); /** * @brief Set whether the ice layer is visible * @param visible visibility of the ice layer */ void setShowIceLayer( bool visible ); /** * @brief Set whether the borders visible * @param visible visibility of the borders */ void setShowBorders( bool visible ); /** * @brief Set whether the rivers are visible * @param visible visibility of the rivers */ void setShowRivers( bool visible ); /** * @brief Set whether the lakes are visible * @param visible visibility of the lakes */ void setShowLakes( bool visible ); /** * @brief Set whether Gps Data is visible * @param visible visibility of the Gps Data */ void setShowGps( bool visible ); /** * @brief Set whether the frame rate gets shown * @param visible visibility of the frame rate */ void setShowFrameRate( bool visible ); /** * @brief Set the current Gps position * @param lat the new latitude value * @param lon the new longitude value */ void changeCurrentPosition( qreal lon, qreal lat ); /** * @brief used to notify about the position of the mouse click */ void notifyMouseClick( int x, int y ); /** * @brief updates the gps tracking point by polling */ void updateGps(); /** * @brief Opens a gpx file for viewing on the Marble Map */ void openGpxFile( QString &filename ); /** * @brief Return a QAbstractItemModel containing GPX files. */ GpxFileModel *gpxFileModel(); /** * @brief Return a QAbstractItemModel containing files. */ FileViewModel* fileViewModel() const; void clearPersistentTileCache(); /** * @brief Set the limit of the persistent (on hard disc) tile cache. * @param bytes The limit in kilobytes, 0 means no limit. */ void setPersistentTileCacheLimit( quint64 kiloBytes ); void clearVolatileTileCache(); /** * @brief Set the limit of the volatile (in RAM) tile cache. * @param bytes The limit in kilobytes. */ void setVolatileTileCacheLimit( quint64 kiloBytes ); /** * @brief Update the map because the model changed. */ void updateChangedMap(); bool mapCoversViewport(); Marble::AngleUnit defaultAngleUnit() const; void setDefaultAngleUnit( Marble::AngleUnit angleUnit ); QFont defaultFont() const; void setDefaultFont( const QFont& font ); Q_SIGNALS: /** * @brief Signal that the zoom has changed, and to what. * @param zoom The new zoom value. * @see zoomView() */ void zoomChanged( int zoom ); void distanceChanged( const QString& distanceString ); /** * @brief Signal that the theme has changed * @param theme Name of the new theme. */ void themeChanged( QString theme ); void projectionChanged( Projection ); void mouseMoveGeoPosition( QString ); void mouseClickGeoPosition( qreal lon, qreal lat, GeoDataCoordinates::Unit ); void timeout(); void framesPerSecond( qreal fps ); /** * This signal is emitted when the repaint of the view was requested. * If available with the @p dirtyRegion which is the region the view will change in. * If dirtyRegion.isEmpty() returns true, the whole viewport has to be repainted. */ void repaintNeeded( QRegion dirtyRegion ); protected: /** * @brief Enables custom drawing onto the MarbleMap straight after * @brief the globe and before all other layers have been rendered. * @param painter */ virtual void customPaint( GeoPainter *painter ); private: Q_DISABLE_COPY( MarbleMap ) MarbleMapPrivate * const d; }; } #endif // MARBLEMAP_H Index: trunk/KDE/kdeedu/marble/src/marble_part.h =================================================================== --- trunk/KDE/kdeedu/marble/src/marble_part.h (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/marble_part.h (revision 1011005) @@ -1,213 +1,214 @@ // // This file is part of the Marble Desktop 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 2007 Tobias Koenig // Copyright 2008 Inge Wallin // Copyright 2009 Jens-Michael Hoffmann // #ifndef MARBLE_PART_H #define MARBLE_PART_H #include #include #include "global.h" class KAboutData; class KAction; class KConfigDialog; class QLabel; class QProgressBar; class QStandardItemModel; namespace KParts { class StatusBarExtension; } namespace Marble { class ControlView; class SunControlWidget; class MarblePart: public KParts::ReadOnlyPart { Q_OBJECT public: MarblePart( QWidget *parentWidget, QObject *parent, const QStringList& ); virtual ~MarblePart(); ControlView *controlView() const; static KAboutData* createAboutData(); void createInfoBoxesMenu(); void createOnlineServicesMenu(); public Q_SLOTS: bool openUrl( const KUrl &url ); bool openFile(); void showPosition( const QString& position); void showDistance( const QString& position); void showZoomLevel( int zoomLevel ); void mapThemeChanged( const QString& newMapTheme ); void createPluginMenus(); private Q_SLOTS: void initObject(); void exportMapScreenShot(); void printMapScreenShot(); void copyMap(); void copyCoordinates(); void setShowClouds( bool ); void setShowAtmosphere( bool ); void setShowCurrentLocation( bool ); void showFullScreen( bool ); void showSideBar( bool ); void showStatusBar( bool ); /** * @brief Show the position label in the status bar. * This slot is connected with the "triggered" signal of * m_showPositionAction. */ void showPositionLabel( bool isChecked ); /** * @brief Show the altitude label in the status bar. * This slot is connected with the "triggered" signal of * m_showAltitudeAction. */ void showAltitudeLabel( bool isChecked ); /** * @brief Show the tile zoom level label in the status bar. * This slot is connected with the "triggered" signal of * m_showTileZoomLevelAction. */ void showTileZoomLevelLabel( bool isChecked ); /** * @brief Show the download progress bar in the status bar. * This slot is connected with the "triggered" signal of * m_showDownloadProgressAction. */ void showDownloadProgressBar( bool isChecked ); void downloadJobAdded(); void downloadJobRemoved(); void lockFloatItemPosition( bool ); void controlSun(); void showSun( bool ); void workOffline( bool ); void setupStatusBar(); void showNewStuffDialog(); void showStatusBarContextMenu( const QPoint& pos ); void editSettings(); void slotEnableButtonApply(); void applyPluginState(); void retrievePluginState(); void slotUpdateSettings(); + void reload(); /** * Shows the about dialog for the plugin with the corresponding @p nameId. */ void showPluginAboutDialog( QString nameId ); /** * Shows the configuration dialog for the plugin with the corresponding @p nameId. */ void showPluginConfigDialog( QString nameId ); /** * Saves the settings of all plugins. */ void writePluginSettings(); /** * Reads the settings of all plugins. */ void readPluginSettings(); private: void setupActions(); void setupDownloadProgressBar(); void setupStatusBarActions(); QLabel * setupStatusBarLabel( const QString& templateString ); void readSettings(); void readStatusBarSettings(); void writeSettings(); void writeStatusBarSettings(); /** Only updates member variable m_tileZoomLevel, does not trigger screen update. */ void updateTileZoomLevel(); private: // All the functionality is provided by this widget. ControlView *m_controlView; // MarbleControlBox and MarbleWidget SunControlWidget *m_sunControlDialog; // Actions for the GUI. KAction *m_exportMapAction; KAction *m_printMapAction; KAction *m_workOfflineAction; KAction *m_copyMapAction; KAction *m_copyCoordinatesAction; KAction *m_currentLocationAction; KAction *m_showCloudsAction; KAction *m_showAtmosphereAction; KAction *m_sideBarAct; KAction *m_fullScreenAct; KAction *m_openAct; KAction *m_newStuffAction; KAction *m_controlSunAction; KAction *m_lockFloatItemsAct; // Actions for the status bar KAction *m_showPositionAction; KAction *m_showAltitudeAction; KAction *m_showTileZoomLevelAction; KAction *m_showDownloadProgressAction; QStandardItemModel* m_pluginModel; KConfigDialog *m_configDialog; QHash m_pluginEnabled; QString m_position; QString m_distance; QString m_tileZoomLevel; // Items for the statusbar. QLabel *m_positionLabel; QLabel *m_distanceLabel; QLabel *m_tileZoomLevelLabel; QProgressBar *m_downloadProgressBar; void updateStatusBar(); KParts::StatusBarExtension *m_statusBarExtension; // Information about the graphics system Marble::GraphicsSystem m_initialGraphicsSystem; Marble::GraphicsSystem m_previousGraphicsSystem; }; } #endif Index: trunk/KDE/kdeedu/marble/src/marble_part.rc =================================================================== --- trunk/KDE/kdeedu/marble/src/marble_part.rc (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/marble_part.rc (revision 1011005) @@ -1,61 +1,62 @@ &File &Edit &View &Info Boxes &Online Services + &Settings Index: trunk/KDE/kdeedu/marble/src/marble_part.cpp =================================================================== --- trunk/KDE/kdeedu/marble/src/marble_part.cpp (revision 1011004) +++ trunk/KDE/kdeedu/marble/src/marble_part.cpp (revision 1011005) @@ -1,1223 +1,1230 @@ // // This file is part of the Marble Desktop 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 2007 Tobias Koenig // Copyright 2008 Inge Wallin // Copyright 2009 Jens-Michael Hoffmann // // Own #include "marble_part.h" // Qt #include #include #include #include #include #include #include #include #include #include #include #include // KDE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Marble library #include "GeoDataCoordinates.h" #include "lib/SunControlWidget.h" // Local dir #include "MarbleCacheSettingsWidget.h" #include "MarblePluginSettingsWidget.h" #include #include #include "MarbleLocale.h" #include "settings.h" #include "AbstractFloatItem.h" #include "AbstractDataPlugin.h" #include "HttpDownloadManager.h" #include "MarbleMap.h" #include "MarbleModel.h" using namespace Marble; #include "ui_MarbleViewSettingsWidget.h" #include "ui_MarbleNavigationSettingsWidget.h" namespace Marble { namespace { const char* POSITION_STRING = I18N_NOOP( "Position: %1" ); const char* DISTANCE_STRING = I18N_NOOP( "Altitude: %1" ); const char* TILEZOOMLEVEL_STRING = I18N_NOOP( "Tile Zoom Level: %1" ); } typedef KParts::GenericFactory< MarblePart > MarblePartFactory; K_EXPORT_COMPONENT_FACTORY( libmarble_part, MarblePartFactory ) MarblePart::MarblePart( QWidget *parentWidget, QObject *parent, const QStringList &arguments ) : KParts::ReadOnlyPart( parent ), m_sunControlDialog( 0 ), m_pluginModel( 0 ), m_configDialog( 0 ), m_positionLabel( 0 ), m_distanceLabel( 0 ) { // only set marble data path when a path was given if ( arguments.count() != 0 && !arguments.first().isEmpty() ) MarbleDirs::setMarbleDataPath( arguments.first() ); // Setting measure system to provide nice standards for all unit questions. // This has to happen before any initialization so plugins (for example) can // use it during initialization. MarbleLocale *marbleLocale = MarbleGlobal::getInstance()->locale(); KLocale *kLocale = KGlobal::locale(); if ( kLocale->measureSystem() == KLocale::Metric ) { marbleLocale->setMeasureSystem( Marble::Metric ); } else { marbleLocale->setMeasureSystem( Marble::Imperial ); } m_controlView = new ControlView( parentWidget ); setComponentData( MarblePartFactory::componentData() ); setWidget( m_controlView ); setupActions(); setXMLFile( "marble_part.rc" ); m_statusBarExtension = new KParts::StatusBarExtension( this ); m_statusBarExtension->statusBar()->setUpdatesEnabled( false ); m_position = NOT_AVAILABLE; m_distance = m_controlView->marbleWidget()->distanceString(); m_tileZoomLevel = NOT_AVAILABLE; QTimer::singleShot( 0, this, SLOT( initObject() ) ); } MarblePart::~MarblePart() { writeSettings(); // Check whether this delete is really needed. delete m_configDialog; } void MarblePart::initObject() { QCoreApplication::processEvents (); setupStatusBar(); readSettings(); m_statusBarExtension->statusBar()->setUpdatesEnabled( true ); } ControlView* MarblePart::controlView() const { return m_controlView; } KAboutData *MarblePart::createAboutData() { return new KAboutData( I18N_NOOP( "marble_part" ), 0, ki18n( "A Desktop Globe" ), MARBLE_VERSION_STRING.toLatin1() ); } bool MarblePart::openUrl( const KUrl &url ) { Q_UNUSED( url ); return true; } bool MarblePart::openFile() { QString fileName; fileName = KFileDialog::getOpenFileName( KUrl(), i18n("*.gpx *.kml|All Supported Files\n*.gpx|GPS Data\n*.kml|Google Earth KML"), widget(), i18n("Open File") ); if ( ! fileName.isNull() ) { QString extension = fileName.section( '.', -1 ); if ( extension.compare( "gpx", Qt::CaseInsensitive ) == 0 ) { m_controlView->marbleWidget()->openGpxFile( fileName ); } else if ( extension.compare( "kml", Qt::CaseInsensitive ) == 0 ) { m_controlView->marbleWidget()->addPlacemarkFile( fileName ); } } return true; } void MarblePart::exportMapScreenShot() { QString fileName = KFileDialog::getSaveFileName( QDir::homePath(), i18n( "Images *.jpg *.png" ), widget(), i18n("Export Map") ); if ( !fileName.isEmpty() ) { // Take the case into account where no file format is indicated const char * format = 0; if ( !fileName.endsWith("png", Qt::CaseInsensitive) && !fileName.endsWith("jpg", Qt::CaseInsensitive) ) { format = "JPG"; } QPixmap mapPixmap = m_controlView->mapScreenShot(); bool success = mapPixmap.save( fileName, format ); if ( !success ) { KMessageBox::error( widget(), i18nc( "Application name", "Marble" ), i18n( "An error occurred while trying to save the file.\n" ), KMessageBox::Notify ); } } } void MarblePart::printMapScreenShot() { QPixmap mapPixmap = m_controlView->mapScreenShot(); QSize printSize = mapPixmap.size(); QPrinter printer; QPrintDialog *printDialog = KdePrint::createPrintDialog(&printer, widget()); if ( printDialog->exec() ) { QRect mapPageRect = printer.pageRect(); printSize.scale( ( printer.pageRect() ).size(), Qt::KeepAspectRatio ); QPoint printTopLeft( mapPageRect.x() + mapPageRect.width() / 2 - printSize.width() / 2, mapPageRect.y() + mapPageRect.height() / 2 - printSize.height() / 2 ); QRect mapPrintRect( printTopLeft, printSize ); QPainter painter( &printer ); painter.drawPixmap( mapPrintRect, mapPixmap, mapPixmap.rect() ); } delete printDialog; } void MarblePart::setShowClouds( bool isChecked ) { m_controlView->marbleWidget()->setShowClouds( isChecked ); m_showCloudsAction->setChecked( isChecked ); // Sync state with the GUI } void MarblePart::setShowAtmosphere( bool isChecked ) { m_controlView->marbleWidget()->setShowAtmosphere( isChecked ); m_showAtmosphereAction->setChecked( isChecked ); // Sync state with the GUI } void MarblePart::showPositionLabel( bool isChecked ) { m_positionLabel->setVisible( isChecked ); } void MarblePart::showAltitudeLabel( bool isChecked ) { m_distanceLabel->setVisible( isChecked ); } void MarblePart::showTileZoomLevelLabel( bool isChecked ) { m_tileZoomLevelLabel->setVisible( isChecked ); } void MarblePart::showDownloadProgressBar( bool isChecked ) { MarbleSettings::setShowDownloadProgressBar( isChecked ); // Change visibility only if there is a download happening m_downloadProgressBar->setVisible( isChecked && m_downloadProgressBar->value() >= 0 ); } void MarblePart::showFullScreen( bool isChecked ) { if ( KApplication::activeWindow() ) KToggleFullScreenAction::setFullScreen( KApplication::activeWindow(), isChecked ); m_fullScreenAct->setChecked( isChecked ); // Sync state with the GUI } void MarblePart::showSideBar( bool isChecked ) { m_controlView->setSideBarShown( isChecked ); m_sideBarAct->setChecked( isChecked ); // Sync state with the GUI } void MarblePart::showStatusBar( bool isChecked ) { if ( !m_statusBarExtension->statusBar() ) return; m_statusBarExtension->statusBar()->setVisible( isChecked ); } void MarblePart::controlSun() { if ( !m_sunControlDialog ) { m_sunControlDialog = new SunControlWidget( NULL, m_controlView->sunLocator() ); connect( m_sunControlDialog, SIGNAL( showSun( bool ) ), this, SLOT ( showSun( bool ) ) ); } m_sunControlDialog->show(); m_sunControlDialog->raise(); m_sunControlDialog->activateWindow(); } void MarblePart::showSun( bool active ) { m_controlView->marbleWidget()->sunLocator()->setShow( active ); } void MarblePart::workOffline( bool offline ) { HttpDownloadManager * const downloadManager = m_controlView->marbleWidget()->map()->model()->downloadManager(); downloadManager->setDownloadEnabled( !offline ); } void MarblePart::copyMap() { QPixmap mapPixmap = m_controlView->mapScreenShot(); QClipboard *clipboard = KApplication::clipboard(); clipboard->setPixmap( mapPixmap ); } void MarblePart::copyCoordinates() { qreal lon = m_controlView->marbleWidget()->centerLongitude(); qreal lat = m_controlView->marbleWidget()->centerLatitude(); QString positionString = GeoDataCoordinates( lon, lat, 0.0, GeoDataCoordinates::Degree ).toString(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText( positionString ); } void MarblePart::setShowCurrentLocation( bool show ) { m_controlView->setCurrentLocationTabShown( show ); } void MarblePart::readSettings() { qDebug() << "Start: MarblePart::readSettings()"; // Last location on quit if ( MarbleSettings::onStartup() == Marble::LastLocationVisited ) { m_controlView->marbleWidget()->centerOn( MarbleSettings::quitLongitude(), MarbleSettings::quitLatitude() ); m_controlView->marbleWidget()->zoomView( MarbleSettings::quitZoom() ); } // Set home position m_controlView->marbleWidget()->setHome( MarbleSettings::homeLongitude(), MarbleSettings::homeLatitude(), MarbleSettings::homeZoom() ); if ( MarbleSettings::onStartup() == Marble::ShowHomeLocation ) { m_controlView->marbleWidget()->goHome(); } // Map theme and projection m_controlView->marbleWidget()->setMapThemeId( MarbleSettings::mapTheme() ); m_controlView->marbleWidget()->setProjection( (Projection) MarbleSettings::projection() ); m_controlView->marbleWidget()->setShowClouds( MarbleSettings::showClouds() ); m_showCloudsAction->setChecked( MarbleSettings::showClouds() ); workOffline( MarbleSettings::workOffline() ); m_workOfflineAction->setChecked( MarbleSettings::workOffline() ); setShowCurrentLocation( MarbleSettings::showCurrentLocation() ); m_currentLocationAction->setChecked( MarbleSettings::showCurrentLocation() ); m_controlView->marbleWidget()->setShowAtmosphere( MarbleSettings::showAtmosphere() ); m_showAtmosphereAction->setChecked( MarbleSettings::showAtmosphere() ); m_lockFloatItemsAct->setChecked(MarbleSettings::lockFloatItemPositions()); lockFloatItemPosition(MarbleSettings::lockFloatItemPositions()); // Sun m_controlView->sunLocator()->setShow( MarbleSettings::showSun() ); m_controlView->sunLocator()->setCitylights( MarbleSettings::showCitylights() ); m_controlView->sunLocator()->setCentered( MarbleSettings::centerOnSun() ); // View m_initialGraphicsSystem = (Marble::GraphicsSystem) MarbleSettings::graphicsSystem(); m_previousGraphicsSystem = m_initialGraphicsSystem; // Plugins QHash pluginEnabled; QHash pluginVisible; int nameIdSize = MarbleSettings::pluginNameId().size(); int enabledSize = MarbleSettings::pluginEnabled().size(); int visibleSize = MarbleSettings::pluginVisible().size(); if ( nameIdSize == enabledSize ) { for ( int i = 0; i < enabledSize; ++i ) { pluginEnabled[ MarbleSettings::pluginNameId()[i] ] = MarbleSettings::pluginEnabled()[i]; } } if ( nameIdSize == visibleSize ) { for ( int i = 0; i < visibleSize; ++i ) { pluginVisible[ MarbleSettings::pluginNameId()[i] ] = MarbleSettings::pluginVisible()[i]; } } QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { if ( pluginEnabled.contains( (*i)->nameId() ) ) { (*i)->setEnabled( pluginEnabled[ (*i)->nameId() ] ); // I think this isn't needed, as it is part of setEnabled() // (*i)->item()->setCheckState( pluginEnabled[ (*i)->nameId() ] ? Qt::Checked : Qt::Unchecked ); } if ( pluginVisible.contains( (*i)->nameId() ) ) { (*i)->setVisible( pluginVisible[ (*i)->nameId() ] ); } } readStatusBarSettings(); slotUpdateSettings(); readPluginSettings(); disconnect( m_controlView->marbleWidget(), SIGNAL( pluginSettingsChanged() ), this, SLOT( writePluginSettings() ) ); connect( m_controlView->marbleWidget(), SIGNAL( pluginSettingsChanged() ), this, SLOT( writePluginSettings() ) ); } void MarblePart::readStatusBarSettings() { const bool showPos = MarbleSettings::showPositionLabel(); m_showPositionAction->setChecked( showPos ); showPositionLabel( showPos ); const bool showAlt = MarbleSettings::showAltitudeLabel(); m_showAltitudeAction->setChecked( showAlt ); showAltitudeLabel( showAlt ); const bool showTileZoom = MarbleSettings::showTileZoomLevelLabel(); m_showTileZoomLevelAction->setChecked( showTileZoom ); showTileZoomLevelLabel( showTileZoom ); const bool showProgress = MarbleSettings::showDownloadProgressBar(); m_showDownloadProgressAction->setChecked( showProgress ); showDownloadProgressBar( showProgress ); } void MarblePart::writeSettings() { // Get the 'quit' values from the widget and store them in the settings. qreal quitLon = m_controlView->marbleWidget()->centerLongitude(); qreal quitLat = m_controlView->marbleWidget()->centerLatitude(); int quitZoom = m_controlView->marbleWidget()->zoom(); MarbleSettings::setQuitLongitude( quitLon ); MarbleSettings::setQuitLatitude( quitLat ); MarbleSettings::setQuitZoom( quitZoom ); // Get the 'home' values from the widget and store them in the settings. qreal homeLon = 0; qreal homeLat = 0; int homeZoom = 0; m_controlView->marbleWidget()->home( homeLon, homeLat, homeZoom ); MarbleSettings::setHomeLongitude( homeLon ); MarbleSettings::setHomeLatitude( homeLat ); MarbleSettings::setHomeZoom( homeZoom ); // Set default font MarbleSettings::setMapFont( m_controlView->marbleWidget()->defaultFont() ); // Get whether animations to the target are enabled MarbleSettings::setAnimateTargetVoyage( m_controlView->marbleWidget()->animationsEnabled() ); m_controlView->marbleWidget()->home( homeLon, homeLat, homeZoom ); // Map theme and projection MarbleSettings::setMapTheme( m_controlView->marbleWidget()->mapThemeId() ); MarbleSettings::setProjection( m_controlView->marbleWidget()->projection() ); MarbleSettings::setShowClouds( m_controlView->marbleWidget()->showClouds() ); MarbleSettings::setWorkOffline( m_workOfflineAction->isChecked() ); MarbleSettings::setShowAtmosphere( m_controlView->marbleWidget()->showAtmosphere() ); MarbleSettings::setShowCurrentLocation( m_currentLocationAction->isChecked() ); MarbleSettings::setStillQuality( m_controlView->marbleWidget()->mapQuality( Marble::Still ) ); MarbleSettings::setAnimationQuality( m_controlView->marbleWidget()-> mapQuality( Marble::Animation ) ); // FIXME: Hopefully Qt will have a getter for this one in the future ... Marble::GraphicsSystem graphicsSystem = (Marble::GraphicsSystem) MarbleSettings::graphicsSystem(); MarbleSettings::setGraphicsSystem( graphicsSystem ); MarbleSettings::setDistanceUnit( MarbleGlobal::getInstance()->locale()->distanceUnit() ); MarbleSettings::setAngleUnit( m_controlView->marbleWidget()->defaultAngleUnit() ); // Sun MarbleSettings::setShowSun( m_controlView->sunLocator()->getShow() ); MarbleSettings::setShowCitylights( m_controlView->sunLocator()->getCitylights() ); MarbleSettings::setCenterOnSun( m_controlView->sunLocator()->getCentered() ); // Caches MarbleSettings::setVolatileTileCacheLimit( m_controlView->marbleWidget()-> volatileTileCacheLimit() / 1024 ); MarbleSettings::setPersistentTileCacheLimit( m_controlView->marbleWidget()-> persistentTileCacheLimit() / 1024 ); // Plugins QList pluginEnabled; QList pluginVisible; QStringList pluginNameId; QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { pluginEnabled << static_cast( (*i)->enabled() ); pluginVisible << static_cast( (*i)->visible() ); pluginNameId << (*i)->nameId(); } MarbleSettings::setPluginEnabled( pluginEnabled ); MarbleSettings::setPluginVisible( pluginVisible ); MarbleSettings::setPluginNameId( pluginNameId ); MarbleSettings::setLockFloatItemPositions( m_lockFloatItemsAct->isChecked() ); writeStatusBarSettings(); MarbleSettings::self()->writeConfig(); } void MarblePart::writeStatusBarSettings() { MarbleSettings::setShowPositionLabel( m_showPositionAction->isChecked() ); MarbleSettings::setShowAltitudeLabel( m_showAltitudeAction->isChecked() ); MarbleSettings::setShowTileZoomLevelLabel( m_showTileZoomLevelAction->isChecked() ); MarbleSettings::setShowDownloadProgressBar( m_showDownloadProgressAction->isChecked() ); } void MarblePart::setupActions() { // Action: Print Map m_printMapAction = KStandardAction::print( this, SLOT( printMapScreenShot() ), actionCollection() ); // Action: Export Map m_exportMapAction = new KAction( this ); actionCollection()->addAction( "exportMap", m_exportMapAction ); m_exportMapAction->setText( i18nc( "Action for saving the map to a file", "&Export Map..." ) ); m_exportMapAction->setIcon( KIcon( "document-save-as" ) ); m_exportMapAction->setShortcut( Qt::CTRL + Qt::Key_S ); connect( m_exportMapAction, SIGNAL(triggered( bool ) ), this, SLOT( exportMapScreenShot() ) ); // Action: Work Offline m_workOfflineAction = new KAction( this ); actionCollection()->addAction( "workOffline", m_workOfflineAction ); m_workOfflineAction->setText( i18nc( "Action for toggling offline mode", "&Work Offline" ) ); m_workOfflineAction->setIcon( KIcon( "user-offline" ) ); m_workOfflineAction->setCheckable( true ); m_workOfflineAction->setChecked( false ); connect( m_workOfflineAction, SIGNAL( triggered( bool ) ), this, SLOT( workOffline( bool ) ) ); // Action: Current Location m_currentLocationAction = new KAction( this ); actionCollection()->addAction( "show_currentlocation", m_currentLocationAction ); m_currentLocationAction->setText( i18nc( "Action for toggling the 'current location' box", "Current Location" ) ); m_currentLocationAction->setCheckable( true ); m_currentLocationAction->setChecked( false ); connect( m_currentLocationAction, SIGNAL( triggered( bool ) ), this, SLOT( setShowCurrentLocation( bool ) ) ); // Action: Copy Map to the Clipboard m_copyMapAction = KStandardAction::copy( this, SLOT( copyMap() ), actionCollection() ); m_copyMapAction->setText( i18nc( "Action for copying the map to the clipboard", "&Copy Map" ) ); // Action: Copy Coordinates string m_copyCoordinatesAction = new KAction( this ); actionCollection()->addAction( "edit_copy_coordinates", m_copyCoordinatesAction ); m_copyCoordinatesAction->setText( i18nc( "Action for copying the coordinates to the clipboard", "C&opy Coordinates" ) ); connect( m_copyCoordinatesAction, SIGNAL( triggered( bool ) ), this, SLOT( copyCoordinates() ) ); // Action: Open a Gpx or a Kml File m_openAct = KStandardAction::open( this, SLOT( openFile() ), actionCollection() ); m_openAct->setText( i18nc( "Action for opening a file", "&Open..." ) ); // Standard actions. So far only Quit. KStandardAction::quit( kapp, SLOT( closeAllWindows() ), actionCollection() ); // Action: Get hot new stuff m_newStuffAction = KNS::standardAction( i18nc( "Action for downloading maps (GHNS)", "Download Maps..."), this, SLOT( showNewStuffDialog() ), actionCollection(), "new_stuff" ); m_newStuffAction->setStatusTip( i18nc( "Status tip", "Download new maps")); m_newStuffAction->setShortcut( Qt::CTRL + Qt::Key_N ); KStandardAction::showStatusbar( this, SLOT( showStatusBar( bool ) ), actionCollection() ); m_sideBarAct = new KAction( i18nc( "Action for toggling the navigation panel", "Show &Navigation Panel"), this ); actionCollection()->addAction( "options_show_sidebar", m_sideBarAct ); m_sideBarAct->setShortcut( Qt::Key_F9 ); m_sideBarAct->setCheckable( true ); m_sideBarAct->setChecked( true ); m_sideBarAct->setStatusTip( i18nc( "Status tip", "Show Navigation Panel" ) ); connect( m_sideBarAct, SIGNAL( triggered( bool ) ), this, SLOT( showSideBar( bool ) ) ); m_fullScreenAct = KStandardAction::fullScreen( 0, 0, widget(), actionCollection() ); connect( m_fullScreenAct, SIGNAL( triggered( bool ) ), this, SLOT( showFullScreen( bool ) ) ); // Action: Show Atmosphere option m_showAtmosphereAction = new KAction( this ); actionCollection()->addAction( "show_atmosphere", m_showAtmosphereAction ); m_showAtmosphereAction->setCheckable( true ); m_showAtmosphereAction->setChecked( true ); m_showAtmosphereAction->setText( i18nc( "Action for toggling the atmosphere", "&Atmosphere" ) ); connect( m_showAtmosphereAction, SIGNAL( triggered( bool ) ), this, SLOT( setShowAtmosphere( bool ) ) ); // Action: Show Crosshairs option QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { if ( (*i)->nameId() == "crosshairs" ) { actionCollection()->addAction( "show_crosshairs", (*i)->action() ); } } // Action: Show Clouds option m_showCloudsAction = new KAction( this ); actionCollection()->addAction( "show_clouds", m_showCloudsAction ); m_showCloudsAction->setCheckable( true ); m_showCloudsAction->setChecked( true ); m_showCloudsAction->setText( i18nc( "Action for toggling clouds", "&Clouds" ) ); connect( m_showCloudsAction, SIGNAL( triggered( bool ) ), this, SLOT( setShowClouds( bool ) ) ); // Action: Show Sunshade options m_controlSunAction = new KAction( this ); actionCollection()->addAction( "control_sun", m_controlSunAction ); m_controlSunAction->setText( i18nc( "Action for sun control dialog", "S&un Control..." ) ); connect( m_controlSunAction, SIGNAL( triggered( bool ) ), this, SLOT( controlSun() ) ); + KStandardAction::redisplay( this, SLOT( reload() ), actionCollection() ); + // Action: Lock float items m_lockFloatItemsAct = new KAction ( this ); actionCollection()->addAction( "options_lock_floatitems", m_lockFloatItemsAct ); m_lockFloatItemsAct->setText( i18nc( "Action for locking float items on the map", "Lock Position" ) ); m_lockFloatItemsAct->setCheckable( true ); m_lockFloatItemsAct->setChecked( false ); connect( m_lockFloatItemsAct, SIGNAL( triggered( bool ) ), this, SLOT( lockFloatItemPosition( bool ) ) ); KStandardAction::preferences( this, SLOT( editSettings() ), actionCollection() ); // FIXME: Discuss if this is the best place to put this QList::const_iterator it = pluginList.constBegin(); for (; it != pluginList.constEnd(); ++it) { connect( (*it), SIGNAL( actionGroupsChanged() ), this, SLOT( createPluginMenus() ) ); } } void MarblePart::createInfoBoxesMenu() { QList floatItemList = m_controlView->marbleWidget()->floatItems(); QList actionList; QList::const_iterator i = floatItemList.constBegin(); for (; i != floatItemList.constEnd(); ++i) { actionList.append( (*i)->action() ); } unplugActionList( "infobox_actionlist" ); plugActionList( "infobox_actionlist", actionList ); } void MarblePart::createOnlineServicesMenu() { QList renderPluginList = m_controlView->marbleWidget()->renderPlugins(); QList actionList; QList::const_iterator i; for( i = renderPluginList.constBegin(); i != renderPluginList.constEnd(); ++i ) { // FIXME: This will go into the layer manager when AbstractDataPlugin is an interface AbstractDataPlugin *dataPlugin = qobject_cast(*i); if( dataPlugin ) { actionList.append( (*i)->action() ); } } unplugActionList( "onlineservices_actionlist" ); plugActionList( "onlineservices_actionlist", actionList ); } void MarblePart::showPosition( const QString& position ) { m_position = position; updateStatusBar(); } void MarblePart::showDistance( const QString& distance ) { m_distance = distance; updateStatusBar(); } void MarblePart::showZoomLevel( int zoomLevel ) { Q_UNUSED( zoomLevel ); updateTileZoomLevel(); updateStatusBar(); } void MarblePart::mapThemeChanged( const QString& newMapTheme ) { Q_UNUSED( newMapTheme ); updateTileZoomLevel(); updateStatusBar(); } void MarblePart::createPluginMenus() { unplugActionList("plugins_actionlist"); QList *tmp_toolbarActionGroups; QList renderPluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i; //Load the toolbars for( i = renderPluginList.constBegin(); i != renderPluginList.constEnd(); ++i ) { tmp_toolbarActionGroups = (*i)->toolbarActionGroups(); if ( tmp_toolbarActionGroups ) { foreach( QActionGroup* ag, *tmp_toolbarActionGroups ) { plugActionList( "plugins_actionlist", ag->actions() ); } } } } void MarblePart::updateTileZoomLevel() { const int tileZoomLevel = m_controlView->marbleWidget()->map()->model()->tileZoomLevel(); if ( tileZoomLevel == -1 ) m_tileZoomLevel = NOT_AVAILABLE; else { QString s; s.setNum( tileZoomLevel ); m_tileZoomLevel = s; } } void MarblePart::updateStatusBar() { if ( m_positionLabel ) m_positionLabel->setText( i18n( POSITION_STRING, m_position ) ); if ( m_distanceLabel ) m_distanceLabel->setText( i18n( DISTANCE_STRING, m_distance ) ); if ( m_tileZoomLevelLabel ) m_tileZoomLevelLabel->setText( i18n( TILEZOOMLEVEL_STRING, m_tileZoomLevel ) ); } void MarblePart::setupStatusBar() { QFontMetrics statusBarFontMetrics( m_statusBarExtension->statusBar()->fontMetrics() ); QString templatePositionString = QString( "%1 000\xb0 00\' 00\"_, 000\xb0 00\' 00\"_" ).arg(POSITION_STRING); m_positionLabel = setupStatusBarLabel( templatePositionString ); QString templateDistanceString = QString( "%1 00.000,0 mu" ).arg(DISTANCE_STRING); m_distanceLabel = setupStatusBarLabel( templateDistanceString ); const QString templateTileZoomLevelString = QString( "%1" ).arg( TILEZOOMLEVEL_STRING ); m_tileZoomLevelLabel = setupStatusBarLabel( templateTileZoomLevelString ); connect( m_controlView->marbleWidget(), SIGNAL( mouseMoveGeoPosition( QString ) ), this, SLOT( showPosition( QString ) ) ); connect( m_controlView->marbleWidget(), SIGNAL( distanceChanged( QString ) ), this, SLOT( showDistance( QString ) ) ); connect( m_controlView->marbleWidget(), SIGNAL( zoomChanged( int ) ), this, SLOT( showZoomLevel( int ) ) ); connect( m_controlView->marbleWidget()->model(), SIGNAL( themeChanged( QString )), this, SLOT( mapThemeChanged( QString )), Qt::QueuedConnection ); setupDownloadProgressBar(); setupStatusBarActions(); updateStatusBar(); } QLabel * MarblePart::setupStatusBarLabel( const QString& templateString ) { QFontMetrics statusBarFontMetrics( m_statusBarExtension->statusBar()->fontMetrics() ); QLabel * const label = new QLabel( m_statusBarExtension->statusBar() ); label->setIndent( 5 ); int maxWidth = statusBarFontMetrics.boundingRect( templateString ).width() + 2 * label->margin() + 2 * label->indent(); label->setFixedWidth( maxWidth ); m_statusBarExtension->addStatusBarItem( label, -1, false ); return label; } void MarblePart::setupDownloadProgressBar() { // get status bar and add progress widget KStatusBar * const statusBar = m_statusBarExtension->statusBar(); Q_ASSERT( statusBar ); m_downloadProgressBar = new QProgressBar; m_downloadProgressBar->setVisible( MarbleSettings::showDownloadProgressBar() ); statusBar->addPermanentWidget( m_downloadProgressBar ); HttpDownloadManager * const downloadManager = m_controlView->marbleWidget()->map()->model()->downloadManager(); kDebug() << "got download manager:" << downloadManager; connect( downloadManager, SIGNAL( jobAdded() ), SLOT( downloadJobAdded() ) ); connect( downloadManager, SIGNAL( jobRemoved() ), SLOT( downloadJobRemoved() ) ); } void MarblePart::setupStatusBarActions() { KStatusBar * const statusBar = m_statusBarExtension->statusBar(); Q_ASSERT( statusBar ); statusBar->setContextMenuPolicy( Qt::CustomContextMenu ); connect( statusBar, SIGNAL( customContextMenuRequested( QPoint )), this, SLOT( showStatusBarContextMenu( QPoint ))); m_showPositionAction = new KToggleAction( i18nc( "Action for toggling", "Show Position" ), this ); m_showAltitudeAction = new KToggleAction( i18nc( "Action for toggling", "Show Altitude" ), this ); m_showTileZoomLevelAction = new KToggleAction( i18nc( "Action for toggling", "Show Tile Zoom Level" ), this ); m_showDownloadProgressAction = new KToggleAction( i18nc( "Action for toggling", "Show Download Progress Bar" ), this ); connect( m_showPositionAction, SIGNAL( triggered( bool ) ), this, SLOT( showPositionLabel( bool ) ) ); connect( m_showAltitudeAction, SIGNAL( triggered( bool ) ), this, SLOT( showAltitudeLabel( bool ) ) ); connect( m_showTileZoomLevelAction, SIGNAL( triggered( bool ) ), this, SLOT( showTileZoomLevelLabel( bool ) ) ); connect( m_showDownloadProgressAction, SIGNAL( triggered( bool ) ), this, SLOT( showDownloadProgressBar( bool ) ) ); } void MarblePart::showNewStuffDialog() { QString newStuffConfig = KStandardDirs::locate ( "data", "marble/marble.knsrc" ); kDebug() << "KNS config file:" << newStuffConfig; KNS::Engine engine; bool ret = engine.init( newStuffConfig ); if ( ret ) { KNS::Entry::List entries = engine.downloadDialogModal(0); } // Update the map theme widget by updating the model. // Shouldn't be needed anymore ... //m_controlView->marbleControl()->updateMapThemes(); } void MarblePart::showStatusBarContextMenu( const QPoint& pos ) { KStatusBar * const statusBar = m_statusBarExtension->statusBar(); Q_ASSERT( statusBar ); KMenu statusBarContextMenu( m_controlView->marbleWidget() ); statusBarContextMenu.addAction( m_showPositionAction ); statusBarContextMenu.addAction( m_showAltitudeAction ); statusBarContextMenu.addAction( m_showTileZoomLevelAction ); statusBarContextMenu.addAction( m_showDownloadProgressAction ); statusBarContextMenu.exec( statusBar->mapToGlobal( pos )); } void MarblePart::editSettings() { if ( KConfigDialog::showDialog( "settings" ) ) return; m_configDialog = new KConfigDialog( m_controlView, "settings", MarbleSettings::self() ); // view page Ui_MarbleViewSettingsWidget ui_viewSettings; QWidget *w_viewSettings = new QWidget( 0 ); w_viewSettings->setObjectName( "view_page" ); ui_viewSettings.setupUi( w_viewSettings ); m_configDialog->addPage( w_viewSettings, i18n( "View" ), "configure" ); // It's experimental -- so we remove it for now. // FIXME: Delete the following line once OpenGL support is officially supported. ui_viewSettings.kcfg_graphicsSystem->removeItem( Marble::OpenGLGraphics ); QString nativeString ( i18n("Native") ); #ifdef Q_WS_X11 nativeString = i18n( "Native (X11)" ); #endif #ifdef Q_WS_MAC nativeString = i18n( "Native (Mac OS X Core Graphics)" ); #endif ui_viewSettings.kcfg_graphicsSystem->setItemText( Marble::NativeGraphics, nativeString ); // navigation page Ui_MarbleNavigationSettingsWidget ui_navigationSettings; QWidget *w_navigationSettings = new QWidget( 0 ); w_navigationSettings->setObjectName( "navigation_page" ); ui_navigationSettings.setupUi( w_navigationSettings ); m_configDialog->addPage( w_navigationSettings, i18n( "Navigation" ), "transform-move" ); // cache page MarbleCacheSettingsWidget *w_cacheSettings = new MarbleCacheSettingsWidget(); w_cacheSettings->setObjectName( "cache_page" ); m_configDialog->addPage( w_cacheSettings, i18n( "Cache & Proxy" ), "preferences-web-browser-cache" ); connect( w_cacheSettings, SIGNAL( clearVolatileCache() ), m_controlView->marbleWidget(), SLOT( clearVolatileTileCache() ) ); connect( w_cacheSettings, SIGNAL( clearPersistentCache() ), m_controlView->marbleWidget(), SLOT( clearPersistentTileCache() ) ); // plugin page m_pluginModel = new QStandardItemModel( this ); QStandardItem *parentItem = m_pluginModel->invisibleRootItem(); QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { parentItem->appendRow( (*i)->item() ); } MarblePluginSettingsWidget *w_pluginSettings = new MarblePluginSettingsWidget(); w_pluginSettings->setModel( m_pluginModel ); w_pluginSettings->setObjectName( "plugin_page" ); m_configDialog->addPage( w_pluginSettings, i18n( "Plugins" ), "preferences-plugin" ); // Setting the icons of the pluginSettings page. w_pluginSettings->setConfigIcon( KIcon( "configure" ) ); w_pluginSettings->setAboutIcon( KIcon( "help-about" ) ); connect( w_pluginSettings, SIGNAL( pluginListViewClicked() ), SLOT( slotEnableButtonApply() ) ); connect( m_configDialog, SIGNAL( settingsChanged( const QString &) ), SLOT( slotUpdateSettings() ) ); connect( m_configDialog, SIGNAL( applyClicked() ), SLOT( applyPluginState() ) ); connect( m_configDialog, SIGNAL( okClicked() ), SLOT( applyPluginState() ) ); connect( m_configDialog, SIGNAL( cancelClicked() ), SLOT( retrievePluginState() ) ); connect( w_pluginSettings, SIGNAL( aboutPluginClicked( QString ) ), SLOT( showPluginAboutDialog( QString ) ) ); connect( w_pluginSettings, SIGNAL( configPluginClicked( QString ) ), SLOT( showPluginConfigDialog( QString ) ) ); m_configDialog->show(); } void MarblePart::slotEnableButtonApply() { m_configDialog->enableButtonApply( true ); } void MarblePart::applyPluginState() { QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { (*i)->applyItemState(); } } void MarblePart::retrievePluginState() { QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = pluginList.constBegin(); for (; i != pluginList.constEnd(); ++i) { (*i)->retrieveItemState(); } } void MarblePart::slotUpdateSettings() { qDebug() << "Updating Settings ..."; // FIXME: Font doesn't get updated instantly. m_controlView->marbleWidget()->setDefaultFont( MarbleSettings::mapFont() ); m_controlView->marbleWidget()-> setMapQuality( (Marble::MapQuality) MarbleSettings::stillQuality(), Marble::Still ); m_controlView->marbleWidget()-> setMapQuality( (Marble::MapQuality) MarbleSettings::animationQuality(), Marble::Animation ); Marble::GraphicsSystem graphicsSystem = (Marble::GraphicsSystem) MarbleSettings::graphicsSystem(); m_controlView->marbleWidget()-> setDefaultAngleUnit( (Marble::AngleUnit) MarbleSettings::angleUnit() ); MarbleGlobal::getInstance()->locale()-> setDistanceUnit( (Marble::DistanceUnit) MarbleSettings::distanceUnit() ); m_distance = m_controlView->marbleWidget()->distanceString(); updateStatusBar(); m_controlView->marbleWidget()->setAnimationsEnabled( MarbleSettings::animateTargetVoyage() ); // Cache m_controlView->marbleWidget()-> setPersistentTileCacheLimit( MarbleSettings::persistentTileCacheLimit() * 1024 ); m_controlView->marbleWidget()-> setVolatileTileCacheLimit( MarbleSettings::volatileTileCacheLimit() * 1024 ); /* m_controlView->marbleWidget()->setProxy( MarbleSettings::proxyUrl(), MarbleSettings::proxyPort(), MarbleSettings::user(), MarbleSettings::password() ); */ //Create and export the proxy QNetworkProxy proxy; // Make sure that no proxy is used for an empty string or the default value: if ( MarbleSettings::proxyUrl().isEmpty() || MarbleSettings::proxyUrl() == "http://" ) { proxy.setType( QNetworkProxy::NoProxy ); } else { if ( MarbleSettings::proxyType() == Marble::Socks5Proxy ) { proxy.setType( QNetworkProxy::Socks5Proxy ); } else if ( MarbleSettings::proxyType() == Marble::HttpProxy ) { proxy.setType( QNetworkProxy::HttpProxy ); } else { qDebug() << "Unknown proxy type! Using Http Proxy instead."; proxy.setType( QNetworkProxy::HttpProxy ); } } proxy.setHostName( MarbleSettings::proxyUrl() ); proxy.setPort( MarbleSettings::proxyPort() ); if ( MarbleSettings::proxyAuth() ) { proxy.setUser( MarbleSettings::proxyUser() ); proxy.setPassword( MarbleSettings::proxyPass() ); } QNetworkProxy::setApplicationProxy(proxy); m_controlView->marbleWidget()->updateChangedMap(); // Show message box if ( m_initialGraphicsSystem != graphicsSystem && m_previousGraphicsSystem != graphicsSystem ) { KMessageBox::information (m_controlView->marbleWidget(), i18n("You have decided to run Marble with a different graphics system.\n" "For this change to become effective, Marble has to be restarted.\n" "Please close the application and start Marble again."), i18n("Graphics System Change") ); } m_previousGraphicsSystem = graphicsSystem; } +void MarblePart::reload() +{ + m_controlView->marbleWidget()->map()->reload(); +} + void MarblePart::showPluginAboutDialog( QString nameId ) { QList renderItemList = m_controlView->marbleWidget()->renderPlugins(); foreach ( RenderPlugin *renderItem, renderItemList ) { if( renderItem->nameId() == nameId ) { QDialog *aboutDialog = renderItem->aboutDialog(); if ( aboutDialog ) { aboutDialog->show(); } } } } void MarblePart::showPluginConfigDialog( QString nameId ) { QList renderItemList = m_controlView->marbleWidget()->renderPlugins(); foreach ( RenderPlugin *renderItem, renderItemList ) { if( renderItem->nameId() == nameId ) { QDialog *configDialog = renderItem->configDialog(); if ( configDialog ) { configDialog->show(); } } } } void MarblePart::writePluginSettings() { KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); foreach( RenderPlugin *plugin, m_controlView->marbleWidget()->renderPlugins() ) { KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() ); QHash hash = plugin->settings(); QHash::iterator it = hash.begin(); while( it != hash.end() ) { group.writeEntry( it.key(), it.value() ); ++it; } group.sync(); } } void MarblePart::readPluginSettings() { KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); foreach( RenderPlugin *plugin, m_controlView->marbleWidget()->renderPlugins() ) { KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() ); QHash hash = plugin->settings(); foreach ( const QString& key, group.keyList() ) { hash.insert( key, group.readEntry( key ) ); } plugin->setSettings( hash ); } } void MarblePart::lockFloatItemPosition( bool enabled ) { QList floatItemList = m_controlView->marbleWidget()->floatItems(); QList::const_iterator i = floatItemList.constBegin(); for (; i != floatItemList.constEnd(); ++i) { // Locking one would suffice as it affects all. // Nevertheless go through all. (*i)->setPositionLocked(enabled); } } void MarblePart::downloadJobAdded() { m_downloadProgressBar->setUpdatesEnabled( false ); if ( m_downloadProgressBar->value() < 0 ) { m_downloadProgressBar->setMaximum( 1 ); m_downloadProgressBar->setValue( 0 ); m_downloadProgressBar->setVisible( MarbleSettings::showDownloadProgressBar() ); } else { m_downloadProgressBar->setMaximum( m_downloadProgressBar->maximum() + 1 ); } // qDebug() << "downloadProgressJobAdded: value/maximum: " // << m_downloadProgressBar->value() << '/' << m_downloadProgressBar->maximum(); m_downloadProgressBar->setUpdatesEnabled( true ); } void MarblePart::downloadJobRemoved() { m_downloadProgressBar->setUpdatesEnabled( false ); m_downloadProgressBar->setValue( m_downloadProgressBar->value() + 1 ); if ( m_downloadProgressBar->value() == m_downloadProgressBar->maximum() ) { m_downloadProgressBar->reset(); m_downloadProgressBar->setVisible( false ); } // qDebug() << "downloadProgressJobCompleted: value/maximum: " // << m_downloadProgressBar->value() << '/' << m_downloadProgressBar->maximum(); m_downloadProgressBar->setUpdatesEnabled( true ); } } #include "marble_part.moc"