No OneTemporary

File Metadata

Created
Thu, May 23, 4:47 AM
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/examples/cpp/marble-game/ClickOnThat.cpp b/examples/cpp/marble-game/ClickOnThat.cpp
index a508f22cb..a0ef76a03 100644
--- a/examples/cpp/marble-game/ClickOnThat.cpp
+++ b/examples/cpp/marble-game/ClickOnThat.cpp
@@ -1,374 +1,374 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
// Self
#include "ClickOnThat.h"
// Qt
#include <QTime>
#include <QVector>
#include <QVariant>
#include <QStringList>
#include <QDir>
// Marble
#include <marble/MarbleWidget.h>
#include <marble/MarbleMap.h>
#include <marble/MarbleModel.h>
#include <marble/GeoDataTreeModel.h>
#include <marble/MarbleDirs.h>
#include <marble/MarblePlacemarkModel.h>
#include <marble/GeoDataDocument.h>
#include <marble/GeoDataPlacemark.h>
#include <marble/GeoDataStyle.h>
#include <marble/GeoDataStyleMap.h>
#include <marble/GeoDataIconStyle.h>
#include <marble/GeoDataLinearRing.h>
#include <marble/GeoDataPoint.h>
#include <marble/GeoDataPolygon.h>
#include <marble/GeoDataMultiGeometry.h>
namespace Marble
{
class ClickOnThatPrivate
{
public:
ClickOnThatPrivate( MarbleWidget *marbleWidget )
: m_marbleWidget( marbleWidget ),
- m_parent( 0 ),
- m_correctAnswerPlacemark( 0 ),
- m_selectPinDocument( 0 ),
- m_countryNames( 0 ),
- m_countryBoundaries( 0 )
+ m_parent( nullptr ),
+ m_correctAnswerPlacemark( nullptr ),
+ m_selectPinDocument( nullptr ),
+ m_countryNames( nullptr ),
+ m_countryBoundaries( nullptr )
{
m_continentsAndOceans
<< QStringLiteral("Asia") << QStringLiteral("Africa")
<< QStringLiteral("North America") << QStringLiteral("South America")
<< QStringLiteral("Antarctica") << QStringLiteral("Europe")
<< QStringLiteral("Australia")
<< QStringLiteral("Arctic Ocean") << QStringLiteral("Indian Ocean")
<< QStringLiteral("North Atlantic Ocean") << QStringLiteral("North Pacific Ocean")
<< QStringLiteral("South Pacific Ocean") << QStringLiteral("South Atlantic Ocean")
<< QStringLiteral("Southern Ocean");
}
~ClickOnThatPrivate()
{
delete m_selectPinDocument;
}
MarbleWidget *m_marbleWidget;
ClickOnThat *m_parent;
/**
* Store the GeoDataPlacemark also
* for the correct answer so that
* we can highlight and zoom in
* ( to fit in the current view port )
* to this placemark when user
* choses to view the right answer.
*/
GeoDataPlacemark *m_correctAnswerPlacemark;
GeoDataCoordinates m_correctAnswer;
/**
* @p m_selectPinDocument shows a pin
* on map indicating whether the user
* has clicked on right country
*/
GeoDataDocument *m_selectPinDocument;
/**
* Document to store point placemarks which
* have country names ( from file "boundaryplacemarks.cache" )
*/
GeoDataDocument *m_countryNames;
/**
* Document which have placemarks whose geometry
* specifies the boundaries of a country
* (from file "ne_50m_admin_0_countries.pn2" )
*/
GeoDataDocument *m_countryBoundaries;
/*
* If the placemark used for posting question
* represent a continent, the user needs to click exactly on
* a particular country whose geometry contains this point
* placemark on map ( Ideally it should be any country
* within that continent ). Also, oceans are point placemark, so
* user needs to click exactly on same point this placemark
* represents ( Ideally it should anywhere within the ocean territory ).
* So, to avoid such placemark we will use this list.
*/
QStringList m_continentsAndOceans;
};
ClickOnThat::ClickOnThat( MarbleWidget *marbleWidget )
: QObject(),
d( new ClickOnThatPrivate(marbleWidget) )
{
d->m_parent = this;
connect( this, SIGNAL(announceHighlight(qreal,qreal,GeoDataCoordinates::Unit)),
d->m_marbleWidget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)) );
}
ClickOnThat::~ClickOnThat()
{
delete d;
}
void ClickOnThat::disablePinDocument()
{
if ( d->m_selectPinDocument ) {
d->m_selectPinDocument->setVisible( false );
d->m_marbleWidget->model()->treeModel()->updateFeature( d->m_selectPinDocument );
}
}
void ClickOnThat::initiateGame()
{
/**
* First remove the GeoDataDocument, which displays
* country names, from map.
*/
if ( !d->m_countryNames ) {
const GeoDataTreeModel *const treeModel = d->m_marbleWidget->model()->treeModel();
for ( int i = 0; i < treeModel->rowCount(); ++i ) {
QVariant const data = treeModel->data ( treeModel->index ( i, 0 ), MarblePlacemarkModel::ObjectPointerRole );
GeoDataObject *object = qvariant_cast<GeoDataObject*>( data );
Q_ASSERT_X( object, "CountryByShape::initiateGame",
"failed to get valid data from treeModel for GeoDataObject" );
if (auto doc = geodata_cast<GeoDataDocument>(object)) {
QFileInfo fileInfo( doc->fileName() );
if (fileInfo.fileName() == QLatin1String("boundaryplacemarks.cache")) {
d->m_countryNames = doc;
break;
}
}
}
}
if ( !d->m_countryBoundaries ) {
const GeoDataTreeModel *const treeModel = d->m_marbleWidget->model()->treeModel();
for ( int i = 0; i < treeModel->rowCount(); ++i ) {
QVariant const data = treeModel->data ( treeModel->index ( i, 0 ), MarblePlacemarkModel::ObjectPointerRole );
GeoDataObject *object = qvariant_cast<GeoDataObject*>( data );
Q_ASSERT_X( object, "MainWindow::initiateGame",
"failed to get valid data from treeModel for GeoDataObject" );
if (auto doc = geodata_cast<GeoDataDocument>(object)) {
QFileInfo fileInfo( doc->fileName() );
if (fileInfo.fileName() == QLatin1String("ne_50m_admin_0_countries.pn2")) {
d->m_countryBoundaries = doc;
break;
}
}
}
}
if ( !d->m_selectPinDocument ) {
d->m_selectPinDocument = new GeoDataDocument;
GeoDataPlacemark *pinPlacemark = new GeoDataPlacemark;
GeoDataStyle::Ptr pinStyle(new GeoDataStyle);
pinStyle->setId(QStringLiteral("answer"));
GeoDataIconStyle iconStyle;
iconStyle.setIconPath(MarbleDirs::path(QStringLiteral("bitmaps/target.png")));
pinStyle->setIconStyle( iconStyle );
GeoDataStyleMap styleMap;
styleMap.setId(QStringLiteral("default-map"));
styleMap.insert(QStringLiteral("normal"), QLatin1Char('#') + pinStyle->id());
d->m_selectPinDocument->addStyle( pinStyle );
d->m_selectPinDocument->addStyleMap( styleMap );
d->m_selectPinDocument->append( pinPlacemark );
pinPlacemark->setStyleUrl(QLatin1Char('#') + styleMap.id());
d->m_selectPinDocument->setVisible( false );
// Add this document to treeModel
d->m_marbleWidget->model()->treeModel()->addDocument( d->m_selectPinDocument );
}
d->m_marbleWidget->setHighlightEnabled( true );
d->m_marbleWidget->centerOn( 23.0, 42.0 );
d->m_marbleWidget->setDistance( 7500 );
connect( d->m_marbleWidget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
this, SLOT(determineResult(qreal,qreal,GeoDataCoordinates::Unit)) );
if ( d->m_countryBoundaries &&
d->m_countryNames )
{
d->m_countryNames->setVisible( false );
d->m_marbleWidget->model()->treeModel()->updateFeature( d->m_countryNames );
emit gameInitialized();
}
}
void ClickOnThat::postQuestion( QObject *gameObject )
{
/**
* Find a random placemark
*/
Q_ASSERT_X( d->m_countryNames, "ClickOnThat::postQuestion",
"CountryByShapePrivate::m_countryNames is NULL" );
QVector<GeoDataPlacemark*> countryPlacemarks = d->m_countryNames->placemarkList();
uint randomSeed = uint(QTime::currentTime().msec());
qsrand( randomSeed );
- GeoDataPlacemark *placemark = 0;
- GeoDataPoint *point = 0;
+ GeoDataPlacemark *placemark = nullptr;
+ GeoDataPoint *point = nullptr;
bool found = false;
while( !found ) {
placemark = countryPlacemarks[qrand()%countryPlacemarks.size()];
if ( !d->m_continentsAndOceans.contains(placemark->name(), Qt::CaseSensitive) ) {
found = true;
point = dynamic_cast<GeoDataPoint*>( placemark->geometry() );
}
}
if ( point ) {
d->m_correctAnswerPlacemark = placemark;
d->m_correctAnswer = point->coordinates();
if ( gameObject ) {
QMetaObject::invokeMethod( gameObject, "clickOnThatQuestion",
Q_ARG(QVariant, QVariant(placemark->name())) );
}
}
}
void ClickOnThat::updateSelectPin(bool result, const GeoDataCoordinates &clickedPoint )
{
QDir dir;
QString iconPath = dir.absolutePath();
if ( result ) {
//iconPath = MarbleDirs::path("bitmaps/MapTackRoundHeadGreen.png");
iconPath += QLatin1String("/MapTackRoundHeadGreen.png");
}
else {
iconPath += QLatin1String("/MapTackRoundHeadRed.png");
}
GeoDataStyle::Ptr style = d->m_selectPinDocument->style(QStringLiteral("answer"));
style->iconStyle().setIconPath( iconPath );
d->m_selectPinDocument->addStyle( style );
QVector<GeoDataPlacemark*> placemarkList = d->m_selectPinDocument->placemarkList();
if ( placemarkList.size() > 0 ) {
placemarkList[0]->setCoordinate( clickedPoint );
}
if ( !d->m_selectPinDocument->isVisible() ) {
d->m_selectPinDocument->setVisible( true );
}
d->m_marbleWidget->model()->treeModel()->updateFeature( d->m_selectPinDocument );
}
void ClickOnThat::determineResult( qreal lon, qreal lat, GeoDataCoordinates::Unit unit )
{
GeoDataCoordinates coord( lon, lat, 0, unit );
Q_ASSERT_X( d->m_countryNames, "ClickOnThat::determineResult",
"CountryByShapePrivate::m_countryBoundaries is NULL" );
QVector<GeoDataFeature*>::Iterator i = d->m_countryBoundaries->begin();
QVector<GeoDataFeature*>::Iterator const end = d->m_countryBoundaries->end();
bool foundStandardPoint = false;
bool foundClickedPoint = false;
for ( ; i != end; ++i ) {
GeoDataPlacemark *country = static_cast<GeoDataPlacemark*>( *i );
GeoDataPolygon *polygon = dynamic_cast<GeoDataPolygon*>( country->geometry() );
GeoDataLinearRing *linearring = dynamic_cast<GeoDataLinearRing*>( country->geometry() );
GeoDataMultiGeometry *multigeom = dynamic_cast<GeoDataMultiGeometry*>( country->geometry() );
foundClickedPoint = false;
foundStandardPoint = false;
if ( polygon &&
polygon->contains( coord ) &&
polygon->contains(d->m_correctAnswer) )
{
foundClickedPoint = true;
foundStandardPoint = true;
d->m_correctAnswerPlacemark = country;
break;
}
if ( linearring &&
linearring->contains( coord ) &&
linearring->contains(d->m_correctAnswer) )
{
foundClickedPoint = true;
foundStandardPoint = true;
d->m_correctAnswerPlacemark = country;
break;
}
if ( multigeom ) {
QVector<GeoDataGeometry*>::Iterator iter = multigeom->begin();
QVector<GeoDataGeometry*>::Iterator const end = multigeom->end();
for ( ; iter != end; ++iter ) {
GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>( *iter );
if ( poly &&
poly->contains( coord ) )
{
foundClickedPoint = true;
}
if ( poly &&
poly->contains( d->m_correctAnswer ) )
{
foundStandardPoint = true;
d->m_correctAnswerPlacemark = country;
}
if ( foundClickedPoint && foundStandardPoint ) {
break;
}
}
}
if ( foundClickedPoint && foundStandardPoint ) {
break;
}
}
if ( foundClickedPoint && foundStandardPoint ) {
updateSelectPin( true, coord );
emit updateResult( true );
}
else {
updateSelectPin( false, coord );
emit updateResult( false );
}
}
void ClickOnThat::highlightCorrectAnswer()
{
disconnect( d->m_marbleWidget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
this, SLOT(determineResult(qreal,qreal,GeoDataCoordinates::Unit)) );
emit announceHighlight( d->m_correctAnswer.longitude(GeoDataCoordinates::Degree),
d->m_correctAnswer.latitude(GeoDataCoordinates::Degree),
GeoDataCoordinates::Degree );
updateSelectPin( true, d->m_correctAnswer );
/**
* Zoom to highlighted placemark
* so that it fits the current
* view port
*/
d->m_marbleWidget->centerOn( *(d->m_correctAnswerPlacemark), true );
connect( d->m_marbleWidget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
this, SLOT(determineResult(qreal,qreal,GeoDataCoordinates::Unit)) );
}
} // namespace Marble
diff --git a/examples/cpp/marble-game/CountryByFlag.cpp b/examples/cpp/marble-game/CountryByFlag.cpp
index 0a3c0f7cc..6afa1ab40 100644
--- a/examples/cpp/marble-game/CountryByFlag.cpp
+++ b/examples/cpp/marble-game/CountryByFlag.cpp
@@ -1,173 +1,173 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
// Self
#include "CountryByFlag.h"
// Qt
#include <QTime>
#include <QImage>
#include <QString>
#include <QVector>
#include <QVariant>
#include <QVariantList>
// Marble
#include <marble/MarbleWidget.h>
#include <marble/MarbleModel.h>
#include <marble/GeoDataTreeModel.h>
#include <marble/MarbleDirs.h>
#include <marble/MarbleDebug.h>
#include <marble/MarblePlacemarkModel.h>
#include <marble/GeoDataDocument.h>
#include <marble/GeoDataPlacemark.h>
#include <marble/GeoDataTypes.h>
namespace Marble
{
class CountryByFlagPrivate
{
public:
CountryByFlagPrivate( MarbleWidget *marbleWidget )
: m_marbleWidget( marbleWidget ),
- m_parent( 0 ),
- m_countryNames( 0 )
+ m_parent( nullptr ),
+ m_countryNames( nullptr )
{
m_continentsAndOceans
<< QStringLiteral("Asia") << QStringLiteral("Africa")
<< QStringLiteral("North America") << QStringLiteral("South America")
<< QStringLiteral("Antarctica") << QStringLiteral("Europe")
<< QStringLiteral("Australia")
<< QStringLiteral("Arctic Ocean") << QStringLiteral("Indian Ocean")
<< QStringLiteral("North Atlantic Ocean") << QStringLiteral("North Pacific Ocean")
<< QStringLiteral("South Pacific Ocean") << QStringLiteral("South Atlantic Ocean")
<< QStringLiteral("Southern Ocean");
}
MarbleWidget *m_marbleWidget;
CountryByFlag *m_parent;
/**
* Document to store point placemarks which
* have country names ( from file "boundaryplacemarks.cache" )
*/
GeoDataDocument *m_countryNames;
/*
* When I select a random placemark form boundaryplacemarks.cache
* it may represent a continent. Since there is no flag
* for a continent, we will not use this placemark to post question.
* This list will help checking whether the placemark chosen to
* post question is a continent/ocean .
*/
QStringList m_continentsAndOceans;
};
CountryByFlag::CountryByFlag( MarbleWidget *marbleWidget )
: QObject(),
d ( new CountryByFlagPrivate(marbleWidget) )
{
d->m_parent = this;
}
CountryByFlag::~CountryByFlag()
{
delete d->m_countryNames;
delete d;
}
void CountryByFlag::initiateGame()
{
/**
* First remove the GeoDataDocument, which displays
* country names, from map.
*/
if ( !d->m_countryNames ) {
const GeoDataTreeModel *const treeModel = d->m_marbleWidget->model()->treeModel();
for ( int i = 0; i < treeModel->rowCount(); ++i ) {
QVariant const data = treeModel->data ( treeModel->index ( i, 0 ), MarblePlacemarkModel::ObjectPointerRole );
GeoDataObject *object = qvariant_cast<GeoDataObject*>( data );
Q_ASSERT_X( object, "CountryByFlag::initiateGame",
"failed to get valid data from treeModel for GeoDataObject" );
if (auto doc = geodata_cast<GeoDataDocument>(object)) {
QFileInfo fileInfo( doc->fileName() );
if (fileInfo.fileName() == QLatin1String("boundaryplacemarks.cache")) {
d->m_countryNames = doc;
break;
}
}
}
}
if ( d->m_countryNames ) {
d->m_countryNames->setVisible( false );
d->m_marbleWidget->model()->treeModel()->updateFeature( d->m_countryNames );
d->m_marbleWidget->centerOn( 23.0, 42.0 );
d->m_marbleWidget->setDistance( 7500 );
d->m_marbleWidget->setHighlightEnabled( false );
emit gameInitialized();
}
}
void CountryByFlag::postQuestion( QObject *gameObject )
{
/**
* Find a random placemark
*/
Q_ASSERT_X( d->m_countryNames, "CountryByFlag::postQuestion",
"CountryByFlagPrivate::m_countryNames is NULL" );
QVector<GeoDataPlacemark*> countryPlacemarks = d->m_countryNames->placemarkList();
uint randomSeed = uint(QTime::currentTime().msec());
qsrand( randomSeed );
bool found = false;
- GeoDataPlacemark *placemark = 0;
+ GeoDataPlacemark *placemark = nullptr;
QVariantList answerOptions;
QString flagPath;
while ( !found ) {
int randomIndex = qrand()%countryPlacemarks.size();
placemark = countryPlacemarks[randomIndex];
if ( !d->m_continentsAndOceans.contains(placemark->name(), Qt::CaseSensitive) ) {
const QString countryCode = placemark->countryCode().toLower();
flagPath = MarbleDirs::path(QLatin1String("flags/flag_") + countryCode + QLatin1String(".svg"));
QImage flag = QFile::exists( flagPath ) ? QImage( flagPath ) : QImage();
if ( !flag.isNull() ) {
flagPath = QLatin1String("../../../data/flags/flag_") + countryCode + QLatin1String(".svg");
found = true;
}
}
}
answerOptions << placemark->name()
<< countryPlacemarks[qrand()%countryPlacemarks.size()]->name()
<< countryPlacemarks[qrand()%countryPlacemarks.size()]->name()
<< countryPlacemarks[qrand()%countryPlacemarks.size()]->name();
// Randomize the options in the list answerOptions
for ( int i = 0; i < answerOptions.size(); ++i ) {
QVariant option = answerOptions.takeAt( qrand()%answerOptions.size() );
answerOptions.append( option );
}
if ( gameObject ) {
QMetaObject::invokeMethod( gameObject, "countryByFlagQuestion",
Q_ARG(QVariant, QVariant(answerOptions)),
Q_ARG(QVariant, QVariant(flagPath)),
Q_ARG(QVariant, QVariant(placemark->name())) );
}
}
} // namespace Marble
#include "moc_CountryByFlag.cpp"
diff --git a/examples/cpp/marble-game/CountryByShape.cpp b/examples/cpp/marble-game/CountryByShape.cpp
index 19094ca98..4a138f264 100644
--- a/examples/cpp/marble-game/CountryByShape.cpp
+++ b/examples/cpp/marble-game/CountryByShape.cpp
@@ -1,265 +1,265 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
// Self
#include "CountryByShape.h"
// Qt
#include <QVector>
#include <QTime>
#include <QVariant>
#include <QVariantList>
#include <QFileInfo>
// Marble
#include <marble/MarbleWidget.h>
#include <marble/MarbleModel.h>
#include <marble/GeoDataTreeModel.h>
#include <marble/MarblePlacemarkModel.h>
#include <marble/GeoDataDocument.h>
#include <marble/GeoDataPlacemark.h>
#include <marble/GeoDataGeometry.h>
#include <marble/GeoDataPolygon.h>
#include <marble/GeoDataLinearRing.h>
#include <marble/GeoDataMultiGeometry.h>
#include <marble/GeoDataPoint.h>
#include <marble/GeoDataCoordinates.h>
#include <marble/GeoDataLatLonAltBox.h>
namespace Marble
{
class CountryByShapePrivate
{
public:
CountryByShapePrivate( MarbleWidget *marbleWidget )
- : m_parent( 0 ),
+ : m_parent( nullptr ),
m_marbleWidget( marbleWidget ),
- m_countryNames( 0 ),
- m_countryBoundaries( 0 )
+ m_countryNames( nullptr ),
+ m_countryBoundaries( nullptr )
{
m_continentsAndOceans
<< QStringLiteral("Asia") << QStringLiteral("Africa")
<< QStringLiteral("North America") << QStringLiteral("South America")
<< QStringLiteral("Antarctica") << QStringLiteral("Europe")
<< QStringLiteral("Australia")
<< QStringLiteral("Arctic Ocean") << QStringLiteral("Indian Ocean")
<< QStringLiteral("North Atlantic Ocean") << QStringLiteral("North Pacific Ocean")
<< QStringLiteral("South Pacific Ocean") << QStringLiteral("South Atlantic Ocean")
<< QStringLiteral("Southern Ocean");
}
CountryByShape *m_parent;
MarbleWidget *m_marbleWidget;
/**
* Document to store point placemarks which
* have country names ( from file "boundaryplacemarks.cache" )
*/
GeoDataDocument *m_countryNames;
/**
* Document which have placemarks whose geometry
* specifies the boundaries of a country
* (from file "ne_50m_admin_0_countries.pn2" )
*/
GeoDataDocument *m_countryBoundaries;
/**
* If the placemark, we select from boundaryplacemarks.cache,
* is a continent, the game will highlight a country,
* on map, which contains this point placemark in its geometry
* instead of highlighting the whole continent.
* Also, oceans are point placemark and we don't have
* any geometry, provided for oceans , that we can highlight.
* So, to avoid placemarks which represent continent or ocean
* we will use this list.
*/
QStringList m_continentsAndOceans;
};
CountryByShape::CountryByShape( MarbleWidget *marbleWidget )
: QObject(),
d( new CountryByShapePrivate(marbleWidget) )
{
d->m_parent = this;
connect( this, SIGNAL(announceHighlight(qreal,qreal,GeoDataCoordinates::Unit)),
d->m_marbleWidget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)) );
}
CountryByShape::~CountryByShape()
{
delete d;
}
void CountryByShape::initiateGame()
{
if ( !d->m_countryNames ) {
const GeoDataTreeModel *const treeModel = d->m_marbleWidget->model()->treeModel();
for ( int i = 0; i < treeModel->rowCount(); ++i ) {
QVariant const data = treeModel->data ( treeModel->index ( i, 0 ), MarblePlacemarkModel::ObjectPointerRole );
GeoDataObject *object = qvariant_cast<GeoDataObject*>( data );
Q_ASSERT_X( object, "CountryByShape::initiateGame",
"failed to get valid data from treeModel for GeoDataObject" );
if (auto doc = geodata_cast<GeoDataDocument>(object)) {
QFileInfo fileInfo( doc->fileName() );
if (fileInfo.fileName() == QLatin1String("boundaryplacemarks.cache")) {
d->m_countryNames = doc;
break;
}
}
}
}
if ( !d->m_countryBoundaries ) {
const GeoDataTreeModel *const treeModel = d->m_marbleWidget->model()->treeModel();
for ( int i = 0; i < treeModel->rowCount(); ++i ) {
QVariant const data = treeModel->data ( treeModel->index ( i, 0 ), MarblePlacemarkModel::ObjectPointerRole );
GeoDataObject *object = qvariant_cast<GeoDataObject*>( data );
Q_ASSERT_X( object, "MainWindow::initiateGame",
"failed to get valid data from treeModel for GeoDataObject" );
if (auto doc = geodata_cast<GeoDataDocument>(object)) {
QFileInfo fileInfo( doc->fileName() );
if (fileInfo.fileName() == QLatin1String("ne_50m_admin_0_countries.pn2")) {
d->m_countryBoundaries = doc;
break;
}
}
}
}
d->m_marbleWidget->setHighlightEnabled( true );
if ( d->m_countryBoundaries &&
d->m_countryNames )
{
d->m_countryNames->setVisible( false );
d->m_marbleWidget->model()->treeModel()->updateFeature( d->m_countryNames );
emit gameInitialized();
}
}
void CountryByShape::postQuestion( QObject *gameObject )
{
//Find a random placemark
Q_ASSERT_X( d->m_countryNames, "CountryByShape::postQuestion",
"CountryByShapePrivate::m_countryNames is NULL" );
QVector<GeoDataPlacemark*> countryPlacemarks = d->m_countryNames->placemarkList();
uint randomSeed = uint(QTime::currentTime().msec());
qsrand( randomSeed );
bool found = false;
- GeoDataPlacemark *placemark =0;
- GeoDataPoint *point = 0;
+ GeoDataPlacemark *placemark =nullptr;
+ GeoDataPoint *point = nullptr;
GeoDataCoordinates coord;
GeoDataLatLonAltBox box;
QVariantList answerOptions;
while ( !found ) {
int randomIndex = qrand()%countryPlacemarks.size();
placemark = countryPlacemarks[randomIndex];
point = dynamic_cast<GeoDataPoint*>( placemark->geometry() );
coord = point->coordinates();
if ( point ) {
/**
* Find the country geometry and fetch corresponding
* GeoDataLatLonAltBox to zoom in to that country so that
* it fills the viewport.
*/
Q_ASSERT_X( d->m_countryBoundaries, "CountryByShape::postQuestion",
"CountryByShapePrivate::m_countryBoundaries is NULL" );
QVector<GeoDataFeature*>::Iterator i = d->m_countryBoundaries->begin();
QVector<GeoDataFeature*>::Iterator const end = d->m_countryBoundaries->end();
for ( ; i != end; ++i ) {
GeoDataPlacemark *country = static_cast<GeoDataPlacemark*>( *i );
GeoDataPolygon *polygon = dynamic_cast<GeoDataPolygon*>( country->geometry() );
GeoDataLinearRing *linearring = dynamic_cast<GeoDataLinearRing*>( country->geometry() );
GeoDataMultiGeometry *multigeom = dynamic_cast<GeoDataMultiGeometry*>( country->geometry() );
if ( polygon &&
polygon->contains( coord ) &&
!d->m_continentsAndOceans.contains(country->name(), Qt::CaseSensitive) )
{
box = polygon->latLonAltBox();
found = true;
break;
}
if ( linearring &&
linearring->contains( coord ) &&
!d->m_continentsAndOceans.contains(country->name(), Qt::CaseSensitive) )
{
box = linearring->latLonAltBox();
found = true;
break;
}
if ( multigeom ) {
QVector<GeoDataGeometry*>::Iterator iter = multigeom->begin();
QVector<GeoDataGeometry*>::Iterator const end = multigeom->end();
for ( ; iter != end; ++iter ) {
GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>( *iter );
if ( poly &&
poly->contains( coord ) &&
!d->m_continentsAndOceans.contains(country->name(), Qt::CaseSensitive) )
{
box = poly->latLonAltBox();
found = true;
break;
}
}
}
if ( found ) {
break;
}
}
}
}
d->m_marbleWidget->setHighlightEnabled( true );
emit announceHighlight( coord.longitude(GeoDataCoordinates::Degree),
coord.latitude(GeoDataCoordinates::Degree),
GeoDataCoordinates::Degree );
/**
* Now disable the highlight feature so that
* the user click doesn't disturbe the highlight
* we did to ask question.
*/
d->m_marbleWidget->setHighlightEnabled( false );
d->m_marbleWidget->centerOn( box, true );
answerOptions << placemark->name()
<< countryPlacemarks[qrand()%countryPlacemarks.size()]->name()
<< countryPlacemarks[qrand()%countryPlacemarks.size()]->name()
<< countryPlacemarks[qrand()%countryPlacemarks.size()]->name();
// Randomize options in list answerOptions
for ( int i = 0; i < answerOptions.size(); ++i ) {
QVariant option = answerOptions.takeAt( qrand()%answerOptions.size() );
answerOptions.append( option );
}
if ( gameObject ) {
QMetaObject::invokeMethod( gameObject, "countryByShapeQuestion",
Q_ARG(QVariant, QVariant(answerOptions)),
Q_ARG(QVariant, QVariant(placemark->name())) );
}
}
} // namespace Marble
#include "moc_CountryByShape.cpp"
diff --git a/examples/cpp/marble-game/GameMainWindow.cpp b/examples/cpp/marble-game/GameMainWindow.cpp
index 4c6aa0b58..fa5e5fb78 100644
--- a/examples/cpp/marble-game/GameMainWindow.cpp
+++ b/examples/cpp/marble-game/GameMainWindow.cpp
@@ -1,286 +1,286 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
// Self
#include "GameMainWindow.h"
#include "CountryByShape.h"
#include "CountryByFlag.h"
#include "ClickOnThat.h"
#include "ui_game.h"
// Qt
#include <QSettings>
#include <QDebug>
#include <QString>
#include <QVector>
#include <QVBoxLayout>
#include <QQuickView>
#include <QQuickItem>
#include <QUrl>
#include <QSize>
#include <QResizeEvent>
#include <QFileInfo>
// Marble
#include <marble/MarbleDirs.h>
#include <marble/MarbleWidget.h>
#include <marble/MarbleMap.h>
#include <marble/MarbleModel.h>
#include <marble/GeoDataTreeModel.h>
#include <marble/RenderPlugin.h>
#include <marble/MarblePlacemarkModel.h>
#include <marble/GeoDataDocument.h>
#include <marble/GeoDataPlacemark.h>
#include <marble/GeoDataGeometry.h>
#include <marble/GeoDataMultiGeometry.h>
#include <marble/GeoDataPoint.h>
#include <marble/GeoDataCoordinates.h>
#include <marble/GeoDataPolygon.h>
#include <marble/GeoDataLinearRing.h>
#include <marble/GeoDataLatLonAltBox.h>
namespace Marble {
class Private : public Ui_MainWindow
{
public:
- Private( QWidget *parent = 0 );
+ Private( QWidget *parent = nullptr );
MarbleWidget *m_marbleWidget;
QWidget *m_parent;
QQuickView m_view;
CountryByShape *m_countryByShape;
CountryByFlag *m_countryByFlag;
ClickOnThat *m_clickOnThat;
QString readMarbleDataPath() const;
void setupMarbleWidget();
void setupGameSignals();
};
Private::Private(QWidget* parent) :
m_marbleWidget( new MarbleWidget( parent ) ),
m_parent( parent ),
m_view(),
m_countryByShape( new CountryByShape(m_marbleWidget) ),
m_countryByFlag( new CountryByFlag(m_marbleWidget) ),
m_clickOnThat( new ClickOnThat(m_marbleWidget) )
{
// nothing to do
}
QString Private::readMarbleDataPath() const
{
return QSettings().value(QStringLiteral("MarbleWidget/marbleDataPath"), QString()).toString();
}
void Private::setupMarbleWidget()
{
m_marbleWidget->setMapThemeId(QStringLiteral( "earth/political/political.dgml"));
foreach ( RenderPlugin *renderPlugin, m_marbleWidget->renderPlugins() ) {
if (renderPlugin->nameId() == QLatin1String("stars")
|| renderPlugin->nameId() == QLatin1String("overviewmap")
|| renderPlugin->nameId() == QLatin1String("compass")
|| renderPlugin->nameId() == QLatin1String("scalebar")
|| renderPlugin->nameId() == QLatin1String("navigation"))
{
renderPlugin->setVisible( false );
}
}
m_marbleWidget->centerOn( 23.0, 42.0 );
m_marbleWidget->setDistance( 7500 );
m_parent->connect( m_parent, SIGNAL(announceHighlight(qreal,qreal,GeoDataCoordinates::Unit)),
m_marbleWidget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)) );
}
void Private::setupGameSignals()
{
QObject *root = m_view.rootObject();
if ( root ) {
m_parent->connect( root, SIGNAL(browseMapButtonClicked()),
m_parent, SLOT(browseMapButtonClicked()) );
QObject *gameOptions = root->findChild<QObject*>(QStringLiteral("gameOptions"));
m_parent->connect( gameOptions, SIGNAL(nextButtonClicked()),
m_parent, SLOT(createQuestion()) );
m_parent->connect( gameOptions, SIGNAL(gameClosed()),
m_parent, SLOT(disableGames()) );
// For "Identify the highlighted country" game
m_parent->connect( gameOptions, SIGNAL(countryByShapeGameRequested()),
m_parent, SLOT(enableCountryShapeGame()) );
m_parent->connect( m_countryByShape, SIGNAL(gameInitialized()),
m_parent, SLOT(createQuestion()) );
// For "Identify the flag" game
m_parent->connect( gameOptions, SIGNAL(countryByFlagGameRequested()),
m_parent, SLOT(enableCountryFlagGame()) );
m_parent->connect( m_countryByFlag, SIGNAL(gameInitialized()),
m_parent, SLOT(createQuestion()) );
// For "Click on that country" game
m_parent->connect( gameOptions, SIGNAL(clickOnThatGameRequested()),
m_parent, SLOT(enableClickOnThatGame()) );
m_parent->connect( m_clickOnThat, SIGNAL(gameInitialized()),
m_parent, SLOT(createQuestion()) );
m_parent->connect( gameOptions, SIGNAL(answerDisplayButtonClicked()),
m_clickOnThat, SLOT(highlightCorrectAnswer()) );
}
}
MainWindow::MainWindow( const QString &marbleDataPath, QWidget *parent, Qt::WindowFlags flags ) :
QMainWindow( parent, flags ),
d( new Private( this ) )
{
d->setupUi( this );
QString const dataPath = marbleDataPath.isEmpty() ? d->readMarbleDataPath() : marbleDataPath;
if ( !dataPath.isEmpty() ) {
MarbleDirs::setMarbleDataPath( dataPath );
}
d->setupMarbleWidget();
setCentralWidget( d->m_marbleWidget );
d->m_view.setSource(QUrl(QStringLiteral("qrc:/Window.qml")));
QWidget *leftPanel = QWidget::createWindowContainer( &d->m_view, d->dockWidgetContents );
QVBoxLayout *layout = new QVBoxLayout( d->dockWidgetContents );
layout->addWidget( leftPanel );
d->dockWidgetContents->setLayout( layout );
d->setupGameSignals();
}
MainWindow::~MainWindow()
{
delete d;
}
MarbleWidget *MainWindow::marbleWidget()
{
return d->m_marbleWidget;
}
void MainWindow::createQuestion()
{
QObject *gameObject = d->m_view.rootObject()->findChild<QObject*>(QStringLiteral("gameOptions"));
if ( gameObject ) {
emit postQuestion( gameObject );
}
}
void MainWindow::browseMapButtonClicked()
{
d->m_marbleWidget->setMapThemeId(QStringLiteral("earth/political/political.dgml"));
/**
* Now display the country names which
* were removed to initiate the game
*/
const GeoDataTreeModel *const treeModel = d->m_marbleWidget->model()->treeModel();
for ( int i = 0; i < treeModel->rowCount(); ++i ) {
QVariant const data = treeModel->data ( treeModel->index ( i, 0 ), MarblePlacemarkModel::ObjectPointerRole );
GeoDataObject *object = qvariant_cast<GeoDataObject*>( data );
Q_ASSERT_X( object, "MainWindow::browseMapButtonClicked",
"failed to get valid data from treeModel for GeoDataObject" );
if (auto doc = geodata_cast<GeoDataDocument>(object)) {
QFileInfo fileInfo( doc->fileName() );
QString fileName = fileInfo.fileName();
if (fileName == QLatin1String("boundaryplacemarks.cache")) {
doc->setVisible( true );
d->m_marbleWidget->model()->treeModel()->updateFeature( doc );
d->m_marbleWidget->setHighlightEnabled( true );
break;
}
}
}
}
void MainWindow::disableGames()
{
disconnect( this, SIGNAL(postQuestion(QObject*)),
d->m_countryByShape, SLOT(postQuestion(QObject*)) );
disconnect( this, SIGNAL(postQuestion(QObject*)),
d->m_countryByFlag, SLOT(postQuestion(QObject*)) );
disconnect( this, SIGNAL(postQuestion(QObject*)),
d->m_clickOnThat, SLOT(postQuestion(QObject*)) );
disconnect( d->m_clickOnThat, SIGNAL(updateResult(bool)),
this, SLOT(displayResult(bool)) );
disconnect( d->m_marbleWidget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
d->m_clickOnThat, SLOT(determineResult(qreal,qreal,GeoDataCoordinates::Unit)) );
d->m_clickOnThat->disablePinDocument();
// Reset the map view
d->m_marbleWidget->centerOn( 23.0, 42.0 );
d->m_marbleWidget->setDistance( 7500 );
}
void MainWindow::enableCountryShapeGame()
{
connect( this, SIGNAL(postQuestion(QObject*)),
d->m_countryByShape, SLOT(postQuestion(QObject*)) );
d->m_countryByShape->initiateGame();
}
void MainWindow::enableCountryFlagGame()
{
connect( this, SIGNAL(postQuestion(QObject*)),
d->m_countryByFlag, SLOT(postQuestion(QObject*)) );
d->m_countryByFlag->initiateGame();
}
void MainWindow::enableClickOnThatGame()
{
connect( this, SIGNAL(postQuestion(QObject*)),
d->m_clickOnThat, SLOT(postQuestion(QObject*)) );
connect( d->m_clickOnThat, SIGNAL(updateResult(bool)),
this, SLOT(displayResult(bool)) );
d->m_clickOnThat->initiateGame();
}
void MainWindow::displayResult(bool result )
{
QObject *gameObject = d->m_view.rootObject()->findChild<QObject*>(QStringLiteral("gameOptions"));
if ( gameObject ) {
QMetaObject::invokeMethod( gameObject, "displayResult",
Q_ARG(QVariant, QVariant(result)) );
}
}
/*
* As the height of main window is changed, update the
* height ( leftPanelHeight ) in window.qml
*/
void MainWindow::resizeEvent(QResizeEvent* event)
{
const QSize size = event->size();
QObject *root = d->m_view.rootObject();
if ( root ) {
QMetaObject::invokeMethod( root, "resizeWindow",
Q_ARG(QVariant, QVariant(size.height()*9/10)) );
}
}
} // namespace Marble
#include "moc_GameMainWindow.cpp"
diff --git a/examples/cpp/marble-game/GameMainWindow.h b/examples/cpp/marble-game/GameMainWindow.h
index fe4c9eb99..cce443f71 100644
--- a/examples/cpp/marble-game/GameMainWindow.h
+++ b/examples/cpp/marble-game/GameMainWindow.h
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
#ifndef MARBLE_GAMEMAINWINDOW_H
#define MARBLE_GAMEMAINWINDOW_H
#include <marble/GeoDataCoordinates.h>
#include <QMainWindow>
namespace Marble
{
class Private;
class MarbleWidget;
class MainWindow: public QMainWindow
{
Q_OBJECT
public:
- explicit MainWindow( const QString &marbleDataPath, QWidget *parent = 0, Qt::WindowFlags flags = 0 );
+ explicit MainWindow( const QString &marbleDataPath, QWidget *parent = nullptr, Qt::WindowFlags flags = nullptr );
virtual ~MainWindow();
MarbleWidget *marbleWidget();
Q_SIGNALS:
void announceHighlight(qreal, qreal, GeoDataCoordinates::Unit );
void postQuestion( QObject* );
private Q_SLOTS:
void createQuestion();
void browseMapButtonClicked();
void disableGames();
void enableCountryShapeGame();
void enableCountryFlagGame();
void enableClickOnThatGame();
void displayResult( bool );
protected:
void resizeEvent( QResizeEvent *event );
private:
Private * const d;
};
} // namespace Marble
#endif // MARBLE_GAMEMAINWINDOW_H
diff --git a/examples/cpp/marbleQuick2/main.cpp b/examples/cpp/marbleQuick2/main.cpp
index fc3543a72..8b1c75cee 100644
--- a/examples/cpp/marbleQuick2/main.cpp
+++ b/examples/cpp/marbleQuick2/main.cpp
@@ -1,98 +1,98 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Adam Dabrowski <adamdbrw@gmail.com>
//
#include <QApplication>
#include <QQuickView>
#include <marble/declarative/MarbleQuickItem.h>
#include <marble/MarbleMap.h>
#include <marble/declarative/MarbleDeclarativePlugin.h>
using namespace Marble;
class MarbleDemoItem : public MarbleQuickItem
{
Q_OBJECT
public:
- MarbleDemoItem(QQuickItem *parent = 0) : MarbleQuickItem(parent)
+ MarbleDemoItem(QQuickItem *parent = nullptr) : MarbleQuickItem(parent)
{
// nothing to do
}
void componentComplete()
{
QQuickItem *pinch = findChild<QQuickItem*>(QStringLiteral("pinchArea"));
if (pinch)
{
pinch->installEventFilter(getEventFilter());
}
}
public Q_SLOTS:
void handlePinchStart(QPointF center)
{
makePinch(center, Qt::GestureStarted);
}
void handlePinchUpdate(QPointF center, qreal scale)
{
makePinch(center, Qt::GestureUpdated, scale);
}
void handlePinchEnd(QPointF center, bool canceled)
{
makePinch(center, canceled ? Qt::GestureCanceled : Qt::GestureFinished);
}
private:
void makePinch(QPointF center, Qt::GestureState state, qreal scale = 1)
{
scale = sqrt(sqrt(scale));
scale = qBound(static_cast<qreal>(0.5), scale, static_cast<qreal>(2.0));
pinch(center, scale, state);
}
};
class MapTestWrap : public QQuickView
{
public:
void start()
{
MarbleDeclarativePlugin plugin;
plugin.registerTypes("org.kde.marble");
setSource(QUrl(QStringLiteral("qrc:/main.qml")));
if(status()!=QQuickView::Ready)
qDebug("can't initialise view");
QSurfaceFormat format;
format.setAlphaBufferSize(8);
setFormat(format);
setClearBeforeRendering(true);
setColor(QColor(Qt::transparent));
setTitle(QStringLiteral("Marble in QML 2.0 demo"));
show();
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MapTestWrap test;
test.start();
return app.exec();
}
#include "main.moc"
diff --git a/examples/cpp/vehicletracking/vehicletracking.h b/examples/cpp/vehicletracking/vehicletracking.h
index fd2d8a04e..4b1210120 100644
--- a/examples/cpp/vehicletracking/vehicletracking.h
+++ b/examples/cpp/vehicletracking/vehicletracking.h
@@ -1,74 +1,74 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef VEHICLETRACKING
#define VEHICLETRACKING
class QTimer;
#include <marble/GeoDataCoordinates.h>
#include <marble/GeoDataPlacemark.h>
#include <QWidget>
#include <QObject>
namespace Marble {
class MarbleWidget;
// CarWorker Class
class CarWorker : public QObject
{
Q_OBJECT
public:
CarWorker(const GeoDataCoordinates& city, qreal radius, qreal speed);
Q_SIGNALS:
void coordinatesChanged(GeoDataCoordinates coord);
public Q_SLOTS:
void startWork();
void finishWork();
private Q_SLOTS:
void iterate();
private:
QTimer *m_timer;
GeoDataCoordinates m_city;
qreal m_radius;
qreal m_speed;
qreal m_alpha;
};
// Window Class
class Window : public QWidget
{
Q_OBJECT
public:
- explicit Window(QWidget *parent = 0);
+ explicit Window(QWidget *parent = nullptr);
void startCars();
public Q_SLOTS:
void setCarCoordinates(const GeoDataCoordinates &coord);
private:
MarbleWidget *m_marbleWidget;
CarWorker *m_firstWorker;
CarWorker *m_secondWorker;
GeoDataPlacemark *m_carFirst;
GeoDataPlacemark *m_carSecond;
QThread *m_threadFirst;
QThread *m_threadSecond;
};
}
#endif // VEHICLETRACKING
diff --git a/src/apps/marble-kde/KdeMainWindow.h b/src/apps/marble-kde/KdeMainWindow.h
index 837cbd21f..d9c23d938 100644
--- a/src/apps/marble-kde/KdeMainWindow.h
+++ b/src/apps/marble-kde/KdeMainWindow.h
@@ -1,56 +1,56 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
#ifndef MARBLE_MAINWINDOW_H
#define MARBLE_MAINWINDOW_H
#include <KXmlGui/KXmlGuiWindow>
class QActionGroup;
class QAction;
namespace Marble
{
class ControlView;
class MarblePart;
class MarbleWidget;
class MainWindow : public KXmlGuiWindow
{
Q_OBJECT
public:
explicit MainWindow( const QString& marbleDataPath = QString(),
- QWidget *parent = 0 );
+ QWidget *parent = nullptr );
~MainWindow() override;
ControlView* marbleControl() const;
MarbleWidget* marbleWidget() const;
public Q_SLOTS:
void updateWindowTitle();
void changeViewSize( QAction* );
protected:
void closeEvent( QCloseEvent *event ) override;
private:
QSize m_savedSize;
MarblePart *m_part;
QActionGroup *m_viewSizeActsGroup;
};
}
#endif
diff --git a/src/apps/marble-kde/marble_part.cpp b/src/apps/marble-kde/marble_part.cpp
index ab56d0a31..596f64ce5 100644
--- a/src/apps/marble-kde/marble_part.cpp
+++ b/src/apps/marble-kde/marble_part.cpp
@@ -1,1832 +1,1832 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Tobias Koenig <tokoe@kde.org>
// Copyright 2008 Inge Wallin <inge@lysator.liu.se>
// Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
// Own
#include "marble_part.h"
// Qt
#include <QDir>
#include <QPointer>
#include <QStringList>
#include <QClipboard>
#include <QLabel>
#include <QFontMetrics>
#include <QPrinter>
#include <QPrintDialog>
#include <QProgressBar>
#include <QStandardItemModel>
#include <QNetworkProxy>
#include <QDomDocument>
#include <QDomNodeList>
#include <QFileDialog>
#include <QMenu>
#include <QStatusBar>
// KF
#include <kaboutdata.h>
#include <kactioncollection.h>
#include <kconfigdialog.h>
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <kpluginfactory.h>
#include <kparts/statusbarextension.h>
#include <kstandardaction.h>
#include <ktoggleaction.h>
#include <ktogglefullscreenaction.h>
#include <kns3/knewstuffaction.h>
#include <kns3/uploaddialog.h>
// Marble library classes
#include "AbstractFloatItem.h"
#include "EditBookmarkDialog.h"
#include "BookmarkManager.h"
#include "BookmarkManagerDialog.h"
#include "CurrentLocationWidget.h"
#include "DownloadRegionDialog.h"
#include "GeoDataCoordinates.h"
#include "GeoDataFolder.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataLookAt.h"
#include "GeoDataPlacemark.h"
#include "HttpDownloadManager.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "MarbleModel.h"
#include "MarblePluginSettingsWidget.h"
#include "MapWizard.h"
#include "NewBookmarkFolderDialog.h"
#include "RenderPluginModel.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingProfilesModel.h"
#include "routing/RoutingProfilesWidget.h"
#include "routing/RouteRequest.h"
#include "SunControlWidget.h"
#include "TimeControlWidget.h"
#include "TileCoordsPyramid.h"
#include "ViewportParams.h"
#include "MarbleClock.h"
#include "ParseRunnerPlugin.h"
#include "PositionTracking.h"
#include "PositionProviderPlugin.h"
#include "PluginManager.h"
#include "SearchInputWidget.h"
#include "MarbleWidgetInputHandler.h"
#include "Planet.h"
#include "MapThemeDownloadDialog.h"
#include "cloudsync/BookmarkSyncManager.h"
#include "MovieCaptureDialog.h"
#include "cloudsync/RouteSyncManager.h"
#include "cloudsync/CloudSyncManager.h"
// Marble non-library classes
#include "ControlView.h"
#include "settings.h"
using namespace Marble;
#include "ui_MarbleCacheSettingsWidget.h"
#include "ui_MarbleViewSettingsWidget.h"
#include "ui_MarbleNavigationSettingsWidget.h"
#include "ui_MarbleTimeSettingsWidget.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" );
const char DATETIME_STRING[] = I18N_NOOP( "Time: %1" );
}
K_PLUGIN_FACTORY(MarblePartFactory, registerPlugin<MarblePart>();)
K_EXPORT_PLUGIN(MarblePartFactory("marble"))
MarblePart::MarblePart( QWidget *parentWidget, QObject *parent, const QVariantList &arguments )
: KParts::ReadOnlyPart( parent ),
- m_sunControlDialog( 0 ),
- m_timeControlDialog( 0 ),
- m_downloadRegionDialog( 0 ),
- m_movieCaptureDialog( 0 ),
- m_externalMapEditorAction( 0 ),
- m_recordMovieAction( 0 ),
- m_stopRecordingAction( 0 ),
- m_recentFilesAction( 0 ),
- m_configDialog( 0 ),
+ m_sunControlDialog( nullptr ),
+ m_timeControlDialog( nullptr ),
+ m_downloadRegionDialog( nullptr ),
+ m_movieCaptureDialog( nullptr ),
+ m_externalMapEditorAction( nullptr ),
+ m_recordMovieAction( nullptr ),
+ m_stopRecordingAction( nullptr ),
+ m_recentFilesAction( nullptr ),
+ m_configDialog( nullptr ),
m_position( QCoreApplication::translate( "Marble", NOT_AVAILABLE ) ),
m_tileZoomLevel( QCoreApplication::translate( "Marble", NOT_AVAILABLE ) ),
- m_positionLabel( 0 ),
- m_distanceLabel( 0 )
+ m_positionLabel( nullptr ),
+ m_distanceLabel( nullptr )
{
// only set marble data path when a path was given
if ( arguments.count() != 0 && !arguments.first().toString().isEmpty() )
MarbleDirs::setMarbleDataPath( arguments.first().toString() );
// 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();
// KF5 TODO: Read Connecting Calls to Catalogs" in ki18n programmer's guide
// and enable translations
// KLocale *kLocale = KGlobal::locale();
// if ( kLocale->measureSystem() == KLocale::Metric ) {
// marbleLocale->setMeasurementSystem( QLocale::MetricSystem );
// }
// else {
// marbleLocale->setMeasurementSystem( QLocale::ImperialSystem );
// }
marbleLocale->setMeasurementSystem( MarbleLocale::ImperialSystem );
migrateNewstuffConfigFiles();
m_externalEditorMapping[0] = "";
m_externalEditorMapping[1] = "potlatch";
m_externalEditorMapping[2] = "josm";
m_externalEditorMapping[3] = "merkaartor";
m_controlView = new ControlView( parentWidget );
setWidget( m_controlView );
setupActions();
setXMLFile( "marble_part.rc" );
m_statusBarExtension = new KParts::StatusBarExtension( this );
m_statusBarExtension->statusBar()->setUpdatesEnabled( false );
// Load bookmark file. If it does not exist, a default one will be used.
m_controlView->marbleModel()->bookmarkManager()->loadFile( "bookmarks/bookmarks.kml" );
initializeCustomTimezone();
setupStatusBar();
readSettings();
m_statusBarExtension->statusBar()->setUpdatesEnabled( true );
// Show startup location
switch ( MarbleSettings::onStartup() ) {
case LastLocationVisited: {
GeoDataLookAt target;
target.setLongitude( MarbleSettings::quitLongitude() );
target.setLatitude( MarbleSettings::quitLatitude() );
target.setRange( MarbleSettings::quitRange() );
m_controlView->marbleWidget()->flyTo( target, Instant );
}
break;
case ShowHomeLocation:
m_controlView->marbleWidget()->goHome( Instant );
break;
}
connect( m_controlView, SIGNAL(showUploadDialog()), this, SLOT(showUploadNewStuffDialog()) );
connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) );
connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) );
}
MarblePart::~MarblePart()
{
writeSettings();
// Check whether this delete is really needed.
delete m_configDialog;
}
ControlView* MarblePart::controlView() const
{
return m_controlView;
}
KAboutData *MarblePart::createAboutData()
{
return new KAboutData( QString( I18N_NOOP( "marble_part" ) ),
QString( "Marble" ),
ControlView::applicationVersion(),
i18n( "A Virtual Globe" ),
KAboutLicense::LGPL_V2 );
}
bool MarblePart::openUrl( const QUrl &url )
{
QFileInfo fileInfo( url.toLocalFile() );
if ( fileInfo.isReadable() ) {
m_controlView->marbleModel()->addGeoDataFile( url.toLocalFile() );
m_recentFilesAction->addUrl( url );
return true;
}
KMessageBox::error( widget(),
i18n( "Sorry, unable to open '%1'. The file is not accessible.", fileInfo.fileName() ),
i18n( "File not accessible" ) );
return false;
}
bool MarblePart::openFile()
{
const PluginManager *const pluginManager = m_controlView->marbleModel()->pluginManager();
QStringList allFileExtensions;
QStringList filters;
for ( const ParseRunnerPlugin *plugin: pluginManager->parsingRunnerPlugins() ) {
if (plugin->nameId() == QLatin1String("Cache"))
continue;
const QStringList fileExtensions = plugin->fileExtensions().replaceInStrings( QRegExp( "^" ), "*." );
const QString filter = plugin->fileFormatDescription() + QLatin1String(" (") + fileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
filters << filter;
allFileExtensions << fileExtensions;
}
allFileExtensions.sort(); // sort since file extensions are visible under Windows
const QString allFileTypes = i18n("All Supported Files") + QLatin1String(" (") + allFileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
filters.sort();
filters.prepend( allFileTypes );
const QString filter = filters.join( ";;" );
QStringList fileNames = QFileDialog::getOpenFileNames( widget(), i18n("Open File"),
m_lastFileOpenPath, filter );
if ( !fileNames.isEmpty() ) {
const QString firstFile = fileNames.first();
m_lastFileOpenPath = QFileInfo( firstFile ).absolutePath();
}
for( const QString &fileName: fileNames ) {
openUrl( QUrl::fromLocalFile(fileName) );
}
return true;
}
void MarblePart::exportMapScreenShot()
{
QString fileName = QFileDialog::getSaveFileName( widget(), i18n("Export Map"), QDir::homePath(),
i18n( "Images *.jpg *.png" ) );
if ( !fileName.isEmpty() ) {
// Take the case into account where no file format is indicated
- const char * format = 0;
+ const char * format = nullptr;
if ( !fileName.endsWith(QLatin1String( "png" ), Qt::CaseInsensitive)
&& !fileName.endsWith(QLatin1String( "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::setShowBookmarks( bool show )
{
m_controlView->marbleModel()->bookmarkManager()->setShowBookmarks( show );
m_toggleBookmarkDisplayAction->setChecked( show ); // Sync state with the GUI
}
void MarblePart::setShowClouds( bool isChecked )
{
m_controlView->marbleWidget()->setShowClouds( isChecked );
m_showCloudsAction->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::showDateTimeLabel( bool isChecked )
{
m_clockLabel->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 ( QApplication::activeWindow() )
KToggleFullScreenAction::setFullScreen( QApplication::activeWindow(), isChecked );
m_fullScreenAct->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( m_controlView->marbleWidget(), m_controlView );
connect( m_sunControlDialog, SIGNAL(showSun(bool)),
this, SLOT (showSun(bool)) );
connect( m_sunControlDialog, SIGNAL(showSun(bool)),
m_showShadow, SLOT (setChecked(bool)) );
connect( m_sunControlDialog, SIGNAL(isLockedToSubSolarPoint(bool)),
m_lockToSubSolarPoint, SLOT (setChecked(bool)) );
connect( m_sunControlDialog, SIGNAL(isSubSolarPointIconVisible(bool)),
m_setSubSolarPointIconVisible, SLOT (setChecked(bool)) );
}
m_sunControlDialog->show();
m_sunControlDialog->raise();
m_sunControlDialog->activateWindow();
}
void MarblePart::controlTime()
{
if ( !m_timeControlDialog )
{
m_timeControlDialog = new TimeControlWidget( m_controlView->marbleModel()->clock() );
}
m_timeControlDialog->show();
m_timeControlDialog->raise();
m_timeControlDialog->activateWindow();
}
void MarblePart::showSun( bool active )
{
m_controlView->marbleWidget()->setShowSunShading( active );
m_sunControlDialog->setSunShading( active );
}
void MarblePart::lockToSubSolarPoint( bool lock )
{
m_controlView->marbleWidget()->setLockToSubSolarPoint( lock );
}
void MarblePart::setSubSolarPointIconVisible( bool show )
{
m_controlView->marbleWidget()->setSubSolarPointIconVisible( show );
}
void MarblePart::workOffline( bool offline )
{
m_controlView->setWorkOffline( offline );
m_newStuffAction->setEnabled( !offline );
m_downloadRegionAction->setEnabled( !offline );
}
void MarblePart::copyMap()
{
QPixmap mapPixmap = m_controlView->mapScreenShot();
QClipboard *clipboard = QApplication::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::readSettings()
{
qDebug() << "Start: MarblePart::readSettings()";
// Set home position
m_controlView->marbleModel()->setHome( MarbleSettings::homeLongitude(),
MarbleSettings::homeLatitude(),
MarbleSettings::homeZoom() );
// Map theme and projection
QString mapTheme = MarbleSettings::mapTheme();
if ( mapTheme.isEmpty() ) {
mapTheme = m_controlView->defaultMapThemeId();
}
m_controlView->marbleWidget()->setMapThemeId( 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() );
m_lockFloatItemsAct->setChecked(MarbleSettings::lockFloatItemPositions());
lockFloatItemPosition(MarbleSettings::lockFloatItemPositions());
setShowBookmarks( MarbleSettings::showBookmarks() );
// Sun
m_controlView->marbleWidget()->setShowSunShading( MarbleSettings::showSun() );
m_showShadow->setChecked( MarbleSettings::showSun() );
m_controlView->marbleWidget()->setShowCityLights( MarbleSettings::showCitylights() );
m_controlView->marbleWidget()->setSubSolarPointIconVisible( MarbleSettings::subSolarPointIconVisible() );
m_controlView->marbleWidget()->setLockToSubSolarPoint( MarbleSettings::lockToSubSolarPoint() );
m_setSubSolarPointIconVisible->setChecked( MarbleSettings::subSolarPointIconVisible() );
m_lockToSubSolarPoint->setChecked( MarbleSettings::lockToSubSolarPoint() );
// View
m_lastFileOpenPath = MarbleSettings::lastFileOpenDir();
// Tracking settings
readTrackingSettings();
// Load previous route settings
m_controlView->marbleModel()->routingManager()->readSettings();
bool const startupWarning = MarbleSettings::showGuidanceModeStartupWarning();
m_controlView->marbleModel()->routingManager()->setShowGuidanceModeStartupWarning( startupWarning );
KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
if ( sharedConfig->hasGroup( "Routing Profiles" ) ) {
QList<RoutingProfile> profiles;
KConfigGroup profilesGroup = sharedConfig->group( "Routing Profiles" );
int numProfiles = profilesGroup.readEntry( "Num", 0 );
for ( int i = 0; i < numProfiles; ++i ) {
KConfigGroup profileGroup = profilesGroup.group( QString( "Profile %0" ).arg(i) );
QString name = profileGroup.readEntry( "Name", i18n( "Unnamed" ) );
RoutingProfile profile( name );
for ( const QString& pluginName: profileGroup.groupList() ) {
KConfigGroup pluginGroup = profileGroup.group( pluginName );
profile.pluginSettings().insert( pluginName, QHash<QString, QVariant>() );
for ( const QString& key: pluginGroup.keyList() ) {
if (key != QLatin1String("Enabled")) {
profile.pluginSettings()[ pluginName ].insert( key, pluginGroup.readEntry( key ) );
}
}
}
profiles << profile;
}
m_controlView->marbleModel()->routingManager()->profilesModel()->setProfiles( profiles );
} else {
m_controlView->marbleModel()->routingManager()->profilesModel()->loadDefaultProfiles();
}
int const profileIndex = MarbleSettings::currentRoutingProfile();
if ( profileIndex >= 0 && profileIndex < m_controlView->marbleModel()->routingManager()->profilesModel()->rowCount() ) {
RoutingProfile profile = m_controlView->marbleModel()->routingManager()->profilesModel()->profiles().at( profileIndex );
m_controlView->marbleModel()->routingManager()->routeRequest()->setRoutingProfile( profile );
}
PositionTracking *const tracking = m_controlView->marbleModel()->positionTracking();
tracking->readSettings();
QString positionProvider = MarbleSettings::activePositionTrackingPlugin();
if ( !positionProvider.isEmpty() ) {
const PluginManager* pluginManager = m_controlView->marbleModel()->pluginManager();
for( const PositionProviderPlugin* plugin: pluginManager->positionProviderPlugins() ) {
if ( plugin->nameId() == positionProvider ) {
PositionProviderPlugin* instance = plugin->newInstance();
tracking->setPositionProviderPlugin( instance );
break;
}
}
}
readStatusBarSettings();
updateSettings();
// Time
if( MarbleSettings::systemTime() == true )
{
/* nothing to do */
}
else if( MarbleSettings::lastSessionTime() == true )
{
m_controlView->marbleModel()->setClockDateTime( MarbleSettings::dateTime() );
m_controlView->marbleModel()->setClockSpeed( MarbleSettings::speedSlider() );
}
readPluginSettings();
m_controlView->setExternalMapEditor( m_externalEditorMapping[MarbleSettings::externalMapEditor()] );
CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
cloudSyncManager->setOwncloudCredentials( MarbleSettings::owncloudServer(),
MarbleSettings::owncloudUsername(),
MarbleSettings::owncloudPassword());
cloudSyncManager->setSyncEnabled( MarbleSettings::enableSync() );
cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( MarbleSettings::syncRoutes() );
cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( MarbleSettings::syncBookmarks() );
}
void MarblePart::readTrackingSettings()
{
if( MarbleSettings::autoCenter() || MarbleSettings::recenterMode() ) {
CurrentLocationWidget *trackingWidget = m_controlView->currentLocationWidget();
if( trackingWidget ) {
trackingWidget->setRecenterMode( MarbleSettings::recenterMode() );
trackingWidget->setAutoZoom( MarbleSettings::autoZoom() );
trackingWidget->setTrackVisible( MarbleSettings::trackVisible() );
trackingWidget->setLastOpenPath( MarbleSettings::lastTrackOpenPath() );
trackingWidget->setLastSavePath( MarbleSettings::lastTrackSavePath() );
}
}
}
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 showDateTime = MarbleSettings::showDateTimeLabel();
m_showDateTimeAction->setChecked( showDateTime );
showDateTimeLabel( showDateTime );
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()->lookAt().longitude();
qreal quitLat = m_controlView->marbleWidget()->lookAt().latitude();
qreal quitRange = m_controlView->marbleWidget()->lookAt().range();
MarbleSettings::setQuitLongitude( quitLon );
MarbleSettings::setQuitLatitude( quitLat );
MarbleSettings::setQuitRange( quitRange );
// Get the 'home' values from the widget and store them in the settings.
qreal homeLon = 0;
qreal homeLat = 0;
int homeZoom = 0;
m_controlView->marbleModel()->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() );
// 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::setStillQuality( m_controlView->marbleWidget()->mapQuality( Still ) );
MarbleSettings::setAnimationQuality( m_controlView->marbleWidget()->
mapQuality( Animation ) );
MarbleSettings::setShowBookmarks( m_controlView->marbleModel()->bookmarkManager()->showBookmarks() );
MarbleSettings::setLastFileOpenDir( m_lastFileOpenPath );
MarbleSettings::setDistanceUnit( MarbleGlobal::getInstance()->locale()->measurementSystem() );
MarbleSettings::setAngleUnit( m_controlView->marbleWidget()->defaultAngleUnit() );
// Sun
MarbleSettings::setShowSun( m_controlView->marbleWidget()->showSunShading() );
MarbleSettings::setShowCitylights( m_controlView->marbleWidget()->showCityLights() );
MarbleSettings::setLockToSubSolarPoint( m_controlView->marbleWidget()->isLockedToSubSolarPoint() );
MarbleSettings::setSubSolarPointIconVisible( m_controlView->marbleWidget()->isSubSolarPointIconVisible() );
// Tracking
CurrentLocationWidget *trackingWidget = m_controlView->currentLocationWidget();
if( trackingWidget )
{
MarbleSettings::setRecenterMode( trackingWidget->recenterMode() );
MarbleSettings::setAutoZoom( trackingWidget->autoZoom() );
MarbleSettings::setTrackVisible( trackingWidget->trackVisible() );
MarbleSettings::setLastTrackOpenPath( trackingWidget->lastOpenPath() );
MarbleSettings::setLastTrackSavePath( trackingWidget->lastSavePath() );
}
// Caches
MarbleSettings::setVolatileTileCacheLimit( m_controlView->marbleWidget()->
volatileTileCacheLimit() / 1024 );
MarbleSettings::setPersistentTileCacheLimit( m_controlView->marbleModel()->
persistentTileCacheLimit() / 1024 );
// Time
MarbleSettings::setDateTime( m_controlView->marbleModel()->clockDateTime() );
MarbleSettings::setSpeedSlider( m_controlView->marbleModel()->clockSpeed() );
// Plugins
writePluginSettings();
QString positionProvider;
PositionTracking* tracking = m_controlView->marbleModel()->positionTracking();
tracking->writeSettings();
if ( tracking->positionProviderPlugin() ) {
positionProvider = tracking->positionProviderPlugin()->nameId();
}
MarbleSettings::setActivePositionTrackingPlugin( positionProvider );
MarbleSettings::setLockFloatItemPositions( m_lockFloatItemsAct->isChecked() );
writeStatusBarSettings();
// Store recent files
KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
m_recentFilesAction->saveEntries( sharedConfig->group( "RecentFiles" ) );
// Store current route settings
RoutingManager *routingManager = m_controlView->marbleWidget()->model()->routingManager();
routingManager->writeSettings();
bool const startupWarning = routingManager->showGuidanceModeStartupWarning();
MarbleSettings::setShowGuidanceModeStartupWarning( startupWarning );
QList<RoutingProfile> profiles = routingManager->profilesModel()->profiles();
RoutingProfile const profile = routingManager->routeRequest()->routingProfile();
MarbleSettings::setCurrentRoutingProfile( profiles.indexOf( profile ) );
QList<QString> const editors = m_externalEditorMapping.values();
MarbleSettings::setExternalMapEditor( editors.indexOf( m_controlView->externalMapEditor() ) );
applyPluginState();
MarbleSettings::self()->save();
}
void MarblePart::writeStatusBarSettings()
{
MarbleSettings::setShowPositionLabel( m_showPositionAction->isChecked() );
MarbleSettings::setShowAltitudeLabel( m_showAltitudeAction->isChecked() );
MarbleSettings::setShowTileZoomLevelLabel( m_showTileZoomLevelAction->isChecked() );
MarbleSettings::setShowDateTimeLabel( m_showDateTimeAction->isChecked() );
MarbleSettings::setShowDownloadProgressBar( m_showDownloadProgressAction->isChecked() );
}
void MarblePart::setupActions()
{
// Action: Recent Files
m_recentFilesAction = KStandardAction::openRecent( this, SLOT(openUrl(QUrl)),
actionCollection() );
KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
m_recentFilesAction->loadEntries( sharedConfig->group( "RecentFiles" ) );
// Action: Download Region
m_downloadRegionAction = new QAction( this );
m_downloadRegionAction->setText( i18nc( "Action for downloading an entire region of a map",
"Download Region..." ));
actionCollection()->addAction( "file_download_region", m_downloadRegionAction );
connect( m_downloadRegionAction, SIGNAL(triggered()), SLOT(showDownloadRegionDialog()));
// Action: Print Map
m_printMapAction = KStandardAction::print( this, SLOT(printMapScreenShot()),
actionCollection() );
m_printPreviewAction = KStandardAction::printPreview( m_controlView, SLOT(printPreview()),
actionCollection() );
// Action: Export Map
m_exportMapAction = new QAction( this );
actionCollection()->addAction( "exportMap", m_exportMapAction );
m_exportMapAction->setText( i18nc( "Action for saving the map to a file", "&Export Map..." ) );
m_exportMapAction->setIcon( QIcon::fromTheme( "document-save-as" ) );
actionCollection()->setDefaultShortcut( m_exportMapAction, Qt::CTRL + Qt::Key_S );
connect( m_exportMapAction, SIGNAL(triggered(bool)),
this, SLOT(exportMapScreenShot()) );
// Action: Work Offline
m_workOfflineAction = new QAction( this );
actionCollection()->addAction( "workOffline", m_workOfflineAction );
m_workOfflineAction->setText( i18nc( "Action for toggling offline mode", "&Work Offline" ) );
m_workOfflineAction->setIcon( QIcon::fromTheme( "user-offline" ) );
m_workOfflineAction->setCheckable( true );
m_workOfflineAction->setChecked( false );
connect( m_workOfflineAction, SIGNAL(triggered(bool)),
this, SLOT(workOffline(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 QAction( this );
actionCollection()->addAction( "edit_copy_coordinates",
m_copyCoordinatesAction );
m_copyCoordinatesAction->setText( i18nc( "Action for copying the coordinates to the clipboard",
"C&opy Coordinates" ) );
m_copyCoordinatesAction->setIcon(QIcon(QStringLiteral(":/icons/copy-coordinates.png")));
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( qApp, SLOT(closeAllWindows()),
actionCollection() );
// Action: Get hot new stuff
m_newStuffAction = KNS3::standardAction( i18nc( "Action for downloading maps (GHNS)",
"Download Maps..."),
this,
SLOT(showNewStuffDialog()),
actionCollection(), "new_stuff" );
m_newStuffAction->setStatusTip( i18nc( "Status tip", "Download new maps"));
actionCollection()->setDefaultShortcut( m_newStuffAction, Qt::CTRL + Qt::Key_N );
// Action: Create a New Map
m_mapWizardAct = new QAction( i18nc( "Action for creating new maps",
"&Create a New Map..." ),
this );
m_mapWizardAct->setIcon(QIcon(QStringLiteral(":/icons/create-new-map.png")));
actionCollection()->addAction( "createMap", m_mapWizardAct );
m_mapWizardAct->setStatusTip( i18nc( "Status tip",
"A wizard guides you through the creation of your own map theme." ) );
connect( m_mapWizardAct, SIGNAL(triggered()), SLOT(showMapWizard()) );
KStandardAction::showStatusbar( this, SLOT(showStatusBar(bool)),
actionCollection() );
- m_fullScreenAct = KStandardAction::fullScreen( 0, 0, widget(),
+ m_fullScreenAct = KStandardAction::fullScreen( nullptr, nullptr, widget(),
actionCollection() );
connect( m_fullScreenAct, SIGNAL(triggered(bool)),
this, SLOT(showFullScreen(bool)) );
// Action: Show Crosshairs option
QList<RenderPlugin *> pluginList = m_controlView->marbleWidget()->renderPlugins();
QList<RenderPlugin *>::const_iterator i = pluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
for (; i != end; ++i ) {
if ((*i)->nameId() == QLatin1String("crosshairs")) {
actionCollection()->addAction( "show_crosshairs", (*i)->action() );
}
}
// Action: Show Clouds option
m_showCloudsAction = new QAction( this );
actionCollection()->addAction( "show_clouds", m_showCloudsAction );
m_showCloudsAction->setCheckable( true );
m_showCloudsAction->setChecked( true );
m_showCloudsAction->setIcon(QIcon(QStringLiteral(":/icons/clouds.png")));
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 QAction( 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( m_controlView->marbleWidget(), SLOT(reloadMap()), actionCollection() );
// Action: Show Time options
m_controlTimeAction = new QAction( this );
actionCollection()->addAction( "control_time", m_controlTimeAction );
m_controlTimeAction->setIcon(QIcon(QStringLiteral(":/icons/clock.png")));
m_controlTimeAction->setText( i18nc( "Action for time control dialog", "&Time Control..." ) );
connect( m_controlTimeAction, SIGNAL(triggered(bool)),
this, SLOT(controlTime()) );
// Action: Lock float items
m_lockFloatItemsAct = new QAction ( this );
actionCollection()->addAction( "options_lock_floatitems",
m_lockFloatItemsAct );
m_lockFloatItemsAct->setText( i18nc( "Action for locking float items on the map",
"Lock Position" ) );
m_lockFloatItemsAct->setIcon(QIcon(QStringLiteral(":/icons/unlock.png")));
m_lockFloatItemsAct->setCheckable( true );
m_lockFloatItemsAct->setChecked( false );
connect( m_lockFloatItemsAct, SIGNAL(triggered(bool)),
this, SLOT(lockFloatItemPosition(bool)) );
KStandardAction::preferences( this, SLOT(editSettings()),
actionCollection() );
//Toggle Action: Show sun shadow
m_showShadow = new KToggleAction( i18n( "Show Shadow" ), this );
// m_showShadow->setIcon(QIcon(QStringLiteral(""))); // Fixme: Add Icon
actionCollection()->addAction( "sun_shadow", m_showShadow );
m_showShadow->setCheckedState( KGuiItem( i18n( "Hide Shadow" ) ) );
m_showShadow->setToolTip(i18n("Shows and hides the shadow of the sun"));
connect( m_showShadow, SIGNAL(triggered(bool)), this, SLOT(showSun(bool)));
//Toggle Action: Show Sun icon on the Sub-Solar Point
m_setSubSolarPointIconVisible = new KToggleAction( i18n( "Show sun icon on the Sub-Solar Point" ), this );
actionCollection()->addAction( "show_icon_on_subsolarpoint", m_setSubSolarPointIconVisible );
m_setSubSolarPointIconVisible->setCheckedState( KGuiItem( i18n( "Hide sun icon on the Sub-Solar Point" ) ) );
m_setSubSolarPointIconVisible->setToolTip( i18n( "Show sun icon on the sub-solar point" ) );
connect( m_setSubSolarPointIconVisible, SIGNAL(triggered(bool)), this, SLOT(setSubSolarPointIconVisible(bool)));
//Toggle Action: Lock globe to the Sub-Solar Point
m_lockToSubSolarPoint = new KToggleAction( i18n( "Lock Globe to the Sub-Solar Point" ), this );
actionCollection()->addAction( "lock_to_subsolarpoint", m_lockToSubSolarPoint );
m_lockToSubSolarPoint->setCheckedState( KGuiItem( i18n( "Unlock Globe to the Sub-Solar Point" ) ) );
m_lockToSubSolarPoint->setToolTip( i18n( "Lock globe to the sub-solar point" ) );
connect( m_lockToSubSolarPoint, SIGNAL(triggered(bool)), this, SLOT(lockToSubSolarPoint(bool)));
// FIXME: Discuss if this is the best place to put this
QList<RenderPlugin *>::const_iterator it = pluginList.constBegin();
QList<RenderPlugin *>::const_iterator const itEnd = pluginList.constEnd();
for (; it != itEnd; ++it ) {
if ((*it)->nameId() != QLatin1String("annotation")) {
connect( (*it), SIGNAL(actionGroupsChanged()),
this, SLOT(createPluginMenus()) );
}
}
m_addBookmarkAction = new QAction( this );
actionCollection()->addAction( "add_bookmark", m_addBookmarkAction );
m_addBookmarkAction->setText( i18nc( "Add Bookmark", "&Add Bookmark" ) );
m_addBookmarkAction->setIcon(QIcon(QStringLiteral(":/icons/bookmark-new.png")));
actionCollection()->setDefaultShortcut( m_addBookmarkAction, Qt::CTRL + Qt::Key_B );
connect( m_addBookmarkAction, SIGNAL(triggered()),
this, SLOT(openEditBookmarkDialog()) );
m_toggleBookmarkDisplayAction = new QAction( this );
actionCollection()->addAction( "show_bookmarks", m_toggleBookmarkDisplayAction );
m_toggleBookmarkDisplayAction->setText( i18nc( "Show Bookmarks", "Show &Bookmarks" ) );
m_toggleBookmarkDisplayAction->setStatusTip( i18n( "Show or hide bookmarks in the map" ) );
m_toggleBookmarkDisplayAction->setCheckable( true );
m_toggleBookmarkDisplayAction->setChecked( m_controlView->marbleModel()->bookmarkManager()->showBookmarks() );
connect( m_toggleBookmarkDisplayAction, SIGNAL(toggled(bool)),
m_controlView->marbleModel()->bookmarkManager(), SLOT(setShowBookmarks(bool)) );
m_setHomeAction = new QAction( this );
actionCollection()->addAction( "set_home", m_setHomeAction );
m_setHomeAction->setText( i18n( "&Set Home Location" ) );
m_setHomeAction->setIcon( QIcon::fromTheme( "go-home" ) );
connect( m_setHomeAction, SIGNAL(triggered()),
this, SLOT(setHome()) );
m_manageBookmarksAction = new QAction( this );
actionCollection()->addAction( "manage_bookmarks", m_manageBookmarksAction );
m_manageBookmarksAction->setText( i18nc( "Manage Bookmarks", "&Manage Bookmarks" ) );
m_manageBookmarksAction->setIcon(QIcon(QStringLiteral(":/icons/bookmarks-organize.png")));
connect( m_manageBookmarksAction, SIGNAL(triggered()),
this, SLOT(openManageBookmarksDialog()) );
createFolderList();
connect( m_controlView->marbleModel()->bookmarkManager(),
SIGNAL(bookmarksChanged()), this, SLOT(createFolderList()) );
m_externalMapEditorAction = new QAction( this );
actionCollection()->addAction( "external_editor", m_externalMapEditorAction );
m_externalMapEditorAction->setText( i18nc( "Edit the map in an external application", "&Edit Map" ) );
m_externalMapEditorAction->setIcon(QIcon(QStringLiteral(":/icons/edit-map.png")));
actionCollection()->setDefaultShortcut( m_externalMapEditorAction, Qt::CTRL + Qt::Key_E );
connect( m_externalMapEditorAction, SIGNAL(triggered()),
m_controlView, SLOT(launchExternalMapEditor()) );
connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)),
this, SLOT(updateMapEditButtonVisibility(QString)) );
m_recordMovieAction = new QAction( i18n( "&Record Movie" ), this );
actionCollection()->addAction( "record_movie" , m_recordMovieAction );
m_recordMovieAction->setStatusTip( i18n( "Records a movie of the globe" ) );
actionCollection()->setDefaultShortcut( m_recordMovieAction, Qt::CTRL + Qt::SHIFT + Qt::Key_R );
m_recordMovieAction->setIcon(QIcon(QStringLiteral(":/icons/animator.png")));
connect( m_recordMovieAction, SIGNAL(triggered()),
this, SLOT(showMovieCaptureDialog()) );
m_stopRecordingAction = new QAction( i18n( "&Stop recording" ), this );
actionCollection()->addAction( "stop_recording" , m_stopRecordingAction );
m_stopRecordingAction->setStatusTip( i18n( "Stop recording a movie of the globe" ) );
actionCollection()->setDefaultShortcut( m_recordMovieAction, Qt::CTRL + Qt::SHIFT + Qt::Key_S );
m_stopRecordingAction->setEnabled( false );
connect( m_stopRecordingAction, SIGNAL(triggered()),
this, SLOT(stopRecording()) );
}
void MarblePart::createFolderList()
{
QList<QAction*> actionList;
QVector<GeoDataFolder*> folders = m_controlView->marbleModel()->bookmarkManager()->folders();
QVector<GeoDataFolder*>::const_iterator i = folders.constBegin();
QVector<GeoDataFolder*>::const_iterator end = folders.constEnd();
for (; i != end; ++i ) {
QMenu *m_bookmarksListMenu = new QMenu( (*i)->name() );
createBookmarksListMenu( m_bookmarksListMenu, *(*i) );
connect( m_bookmarksListMenu, SIGNAL(triggered(QAction*)),
this, SLOT(lookAtBookmark(QAction*)) );
actionList.append( m_bookmarksListMenu->menuAction() );
}
unplugActionList("folders");
plugActionList( "folders", actionList );
}
void MarblePart::createBookmarksListMenu( QMenu *m_bookmarksListMenu, const GeoDataFolder &folder )
{
m_bookmarksListMenu->clear();
QVector<GeoDataPlacemark*> bookmarks = folder.placemarkList();
QVector<GeoDataPlacemark*>::const_iterator i = bookmarks.constBegin();
QVector<GeoDataPlacemark*>::const_iterator end = bookmarks.constEnd();
for (; i != end; ++i ) {
QAction *bookmarkAct = new QAction( (*i)->name(), this );
QVariant var;
GeoDataLookAt* lookAt = (*i)->lookAt();
if ( !lookAt ) {
GeoDataLookAt coordinateToLookAt;
coordinateToLookAt.setCoordinates( (*i)->coordinate() );
coordinateToLookAt.setRange( (*i)->coordinate().altitude() );
} else {
var.setValue( *lookAt );
}
bookmarkAct->setData( var );
m_bookmarksListMenu->addAction( bookmarkAct );
}
}
void MarblePart::createInfoBoxesMenu()
{
QList<AbstractFloatItem *> floatItemList = m_controlView->marbleWidget()->floatItems();
QList<QAction*> actionList;
QList<AbstractFloatItem *>::const_iterator i = floatItemList.constBegin();
QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd();
for (; i != end; ++i ) {
actionList.append( (*i)->action() );
}
unplugActionList( "infobox_actionlist" );
plugActionList( "infobox_actionlist", actionList );
}
void MarblePart::createOnlineServicesMenu()
{
QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
QList<QAction*> actionList;
QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
for (; i != end; ++i ) {
// FIXME: This will go into the layer manager when AbstractDataPlugin is an interface
if( (*i)->renderType() == RenderPlugin::OnlineRenderType ) {
actionList.append( (*i)->action() );
}
}
unplugActionList( "onlineservices_actionlist" );
plugActionList( "onlineservices_actionlist", actionList );
}
void MarblePart::createRenderPluginActions()
{
QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
QList<QAction*> actionList;
QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
for (; i != end; ++i ) {
if( (*i)->renderType() == RenderPlugin::ThemeRenderType ) {
actionList.append( (*i)->action() );
}
}
unplugActionList( "themerender_actionlist" );
plugActionList( "themerender_actionlist", actionList );
}
void MarblePart::showDateTime()
{
m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat );
updateStatusBar();
}
void MarblePart::showPosition( const QString& position )
{
m_position = position;
updateStatusBar();
}
void MarblePart::showZoomLevel( const int tileLevel )
{
if ( tileLevel == -1 )
m_tileZoomLevel = QCoreApplication::translate( "Marble", NOT_AVAILABLE );
else {
m_tileZoomLevel.setNum( tileLevel );
}
updateStatusBar();
}
void MarblePart::mapThemeChanged( const QString& newMapTheme )
{
Q_UNUSED( newMapTheme );
updateTileZoomLevel();
updateStatusBar();
}
void MarblePart::createPluginMenus()
{
unplugActionList("plugins_actionlist");
unplugActionList("plugins_menuactionlist");
QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
for (; i != end; ++i ) {
// menus
const QList<QActionGroup*> *tmp_actionGroups = (*i)->actionGroups();
if( (*i)->enabled() && tmp_actionGroups ) {
for( QActionGroup *ag: *tmp_actionGroups ) {
plugActionList( "plugins_menuactionlist", ag->actions() );
}
}
// toolbars
const QList<QActionGroup*> *tmp_toolbarActionGroups = (*i)->toolbarActionGroups();
if ( (*i)->enabled() && tmp_toolbarActionGroups ) {
for( QActionGroup* ag: *tmp_toolbarActionGroups ) {
plugActionList( "plugins_actionlist", ag->actions() );
}
}
}
}
void MarblePart::updateTileZoomLevel()
{
const int tileZoomLevel =
m_controlView->marbleWidget()->tileZoomLevel();
if ( tileZoomLevel == -1 )
m_tileZoomLevel = QCoreApplication::translate( "Marble", NOT_AVAILABLE );
else {
m_tileZoomLevel.setNum( tileZoomLevel );
}
}
void MarblePart::migrateNewstuffConfigFiles()
{
// Newstuff config files used to be in the KDE data directory of the user, but are now
// shared between Marble KDE and Marble Qt in Marble's data path of the user.
// This method moves an old KDE newstuff config file to the new location if the former
// exists and the latter not.
QFileInfo const target(MarbleDirs::localPath() + QLatin1String("/newstuff/marble-map-themes.knsregistry"));
if ( !target.exists() ) {
QString const source = QStandardPaths::locate( QStandardPaths::GenericDataLocation, "knewstuff3/marble.knsregistry" );
if ( !source.isEmpty() ) {
if ( !target.absoluteDir().exists() ) {
if ( !QDir::root().mkpath( target.absolutePath() ) ) {
mDebug() << "Failed to create target directory " << target.absolutePath() << " needed for newstuff migration";
return;
}
}
QFile registryFile( source );
if ( !registryFile.open( QFile::ReadOnly ) ) {
mDebug() << "Cannot parse newstuff xml file";
return;
}
QDomDocument xml;
if ( !xml.setContent( registryFile.readAll() ) ) {
mDebug() << "Cannot parse newstuff xml data";
return;
}
QDomNodeList items = xml.elementsByTagName( "stuff" );
for ( int i = 0; i < items.length(); ++i ) {
repairNode( items.item(i), QString("summary") );
repairNode( items.item(i), QString("author") );
}
QFile output( target.absoluteFilePath() );
if ( !output.open( QFile::WriteOnly ) ) {
mDebug() << "Cannot open " << target.absoluteFilePath() << " for writing";
} else {
QTextStream outStream( &output );
outStream << xml.toString( 2 );
outStream.flush();
output.close();
}
}
}
}
void MarblePart::repairNode( QDomNode node, const QString &child )
{
int const size = node.namedItem( child ).toElement().text().size();
if ( size > 1024 ) {
QString const theme = node.namedItem(QStringLiteral("name")).toElement().text();
mDebug() << "Removing GHNS field " << child << " of map theme " << theme << ": Size " << size << " exceeds maximum size (see bug 319542).";
node.removeChild( node.namedItem( child ) );
}
}
void MarblePart::updateCloudSyncStatus(const QString& status )
{
m_ui_cloudSyncSettings.cloudSyncStatus->setText(status);
switch (m_controlView->cloudSyncManager()->status()){
case CloudSyncManager::Success:
m_ui_cloudSyncSettings.cloudSyncStatus->setStyleSheet("QLabel { color : green; }");
break;
case CloudSyncManager::Error:
m_ui_cloudSyncSettings.cloudSyncStatus->setStyleSheet("QLabel { color : red; }");
break;
case CloudSyncManager::Unknown:
m_ui_cloudSyncSettings.cloudSyncStatus->setStyleSheet("QLabel { color : grey; }");
break;
}
}
void MarblePart::updateCloudSyncCredentials()
{
m_controlView->cloudSyncManager()->setOwncloudCredentials( m_ui_cloudSyncSettings.kcfg_owncloudServer->text(),
m_ui_cloudSyncSettings.kcfg_owncloudUsername->text(),
m_ui_cloudSyncSettings.kcfg_owncloudPassword->text() );
}
void MarblePart::updateStatusBar()
{
if ( m_positionLabel )
m_positionLabel->setText( i18n( POSITION_STRING, m_position ) );
if ( m_distanceLabel )
m_distanceLabel->setText( i18n( DISTANCE_STRING, m_controlView->marbleWidget()->distanceString() ) );
if ( m_tileZoomLevelLabel )
m_tileZoomLevelLabel->setText( i18n( TILEZOOMLEVEL_STRING,
m_tileZoomLevel ) );
if ( m_clockLabel )
m_clockLabel->setText( i18n( DATETIME_STRING, m_clock ) );
}
void MarblePart::setupStatusBar()
{
QFontMetrics statusBarFontMetrics( m_statusBarExtension->statusBar()->fontMetrics() );
// UTM syntax is used in the template string, as it is longer than the lon/lat one
QString templatePositionString =
QString( "%1 00Z 000000.00 m E, 00000000.00 m N_" ).arg(POSITION_STRING);
m_positionLabel = setupStatusBarLabel( templatePositionString );
QString templateDistanceString =
QString( "%1 00.000,0 mu" ).arg(DISTANCE_STRING);
m_distanceLabel = setupStatusBarLabel( templateDistanceString );
QString templateDateTimeString = QString( "%1 %2" ).arg( DATETIME_STRING , QLocale().toString( QDateTime::fromString ( "01:01:1000", "dd:mm:yyyy"), QLocale::ShortFormat ) );
m_clockLabel = setupStatusBarLabel( templateDateTimeString );
const QString templateTileZoomLevelString = i18n( TILEZOOMLEVEL_STRING, m_tileZoomLevel );
m_tileZoomLevelLabel = setupStatusBarLabel( templateTileZoomLevelString );
connect( m_controlView->marbleWidget(), SIGNAL(mouseMoveGeoPosition(QString)),
this, SLOT(showPosition(QString)) );
connect( m_controlView->marbleWidget(), SIGNAL(distanceChanged(QString)),
this, SLOT(updateStatusBar()) );
connect( m_controlView->marbleWidget(), SIGNAL(tileLevelChanged(int)),
SLOT(showZoomLevel(int)));
connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)),
this, SLOT(mapThemeChanged(QString)), Qt::QueuedConnection );
connect( m_controlView->marbleModel()->clock(), SIGNAL(timeChanged()),
this, SLOT(showDateTime()) );
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
QStatusBar * 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->marbleModel()->downloadManager();
Q_ASSERT( downloadManager );
connect( downloadManager, SIGNAL(progressChanged(int,int)), SLOT(handleProgress(int,int)) );
connect( downloadManager, SIGNAL(jobRemoved()), SLOT(removeProgressItem()) );
}
void MarblePart::setupStatusBarActions()
{
QStatusBar * 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_showDateTimeAction = new KToggleAction( i18nc( "Action for toggling", "Show Date and Time" ),
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_showDateTimeAction, SIGNAL(triggered(bool)),
this, SLOT(showDateTimeLabel(bool)) );
connect( m_showDownloadProgressAction, SIGNAL(triggered(bool)),
this, SLOT(showDownloadProgressBar(bool)) );
}
void MarblePart::showNewStuffDialog()
{
QPointer<MapThemeDownloadDialog> dialog( new MapThemeDownloadDialog( m_controlView->marbleWidget() ) );
dialog->exec();
delete dialog;
}
void MarblePart::showUploadNewStuffDialog()
{
QString newStuffConfig = QStandardPaths::locate( QStandardPaths::GenericDataLocation, "marble/marble.knsrc" );
qDebug() << "KNS config file:" << newStuffConfig;
QPointer<KNS3::UploadDialog> dialog( new KNS3::UploadDialog( newStuffConfig, m_controlView ) );
qDebug() << "Creating the archive";
dialog->setUploadFile( QUrl( MapWizard::createArchive( m_controlView, m_controlView->marbleWidget()->mapThemeId() ) ) );
dialog->exec();
MapWizard::deleteArchive( m_controlView->marbleWidget()->mapThemeId() );
delete dialog;
}
void MarblePart::showDownloadRegionDialog()
{
MarbleWidget * const marbleWidget = m_controlView->marbleWidget();
if ( !m_downloadRegionDialog ) {
m_downloadRegionDialog = new DownloadRegionDialog( marbleWidget, widget() );
// it might be tempting to move the connects to DownloadRegionDialog's "accepted" and
// "applied" signals, be aware that the "hidden" signal might be come before the "accepted"
// signal, leading to a too early disconnect.
connect( m_downloadRegionDialog, SIGNAL(accepted()), SLOT(downloadRegion()));
connect( m_downloadRegionDialog, SIGNAL(applied()), SLOT(downloadRegion()));
}
// FIXME: get allowed range from current map theme
m_downloadRegionDialog->setAllowedTileLevelRange( 0, 16 );
m_downloadRegionDialog->setSelectionMethod( DownloadRegionDialog::VisibleRegionMethod );
ViewportParams const * const viewport = marbleWidget->viewport();
m_downloadRegionDialog->setSpecifiedLatLonAltBox( viewport->viewLatLonAltBox() );
m_downloadRegionDialog->setVisibleLatLonAltBox( viewport->viewLatLonAltBox() );
m_downloadRegionDialog->setVisibleTileLevel( marbleWidget->tileZoomLevel() );
m_downloadRegionDialog->show();
m_downloadRegionDialog->raise();
m_downloadRegionDialog->activateWindow();
}
void MarblePart::downloadRegion()
{
Q_ASSERT( m_downloadRegionDialog );
QVector<TileCoordsPyramid> const pyramid = m_downloadRegionDialog->region();
if ( !pyramid.isEmpty() ) {
m_controlView->marbleWidget()->downloadRegion( pyramid );
}
}
void MarblePart::showStatusBarContextMenu( const QPoint& pos )
{
QStatusBar * const statusBar = m_statusBarExtension->statusBar();
Q_ASSERT( statusBar );
QMenu statusBarContextMenu( m_controlView->marbleWidget() );
statusBarContextMenu.addAction( m_showPositionAction );
statusBarContextMenu.addAction( m_showDateTimeAction );
statusBarContextMenu.addAction( m_showAltitudeAction );
statusBarContextMenu.addAction( m_showTileZoomLevelAction );
statusBarContextMenu.addAction( m_showDownloadProgressAction );
statusBarContextMenu.exec( statusBar->mapToGlobal( pos ));
}
void MarblePart::showMapWizard()
{
// Map Wizard
QPointer<MapWizard> mapWizard = new MapWizard( m_controlView );
mapWizard->setWmsServers( MarbleSettings::wmsServers() );
mapWizard->setStaticUrlServers( MarbleSettings::staticUrlServers() );
mapWizard->exec();
MarbleSettings::setWmsServers( mapWizard->wmsServers() );
MarbleSettings::setStaticUrlServers( mapWizard->staticUrlServers() );
mapWizard->deleteLater();
}
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 );
+ QWidget *w_viewSettings = new QWidget( nullptr );
w_viewSettings->setObjectName( "view_page" );
ui_viewSettings.setupUi( w_viewSettings );
m_configDialog->addPage( w_viewSettings, i18n( "View" ), "configure" );
ui_viewSettings.label_labelLocalization->hide();
ui_viewSettings.kcfg_labelLocalization->hide();
// navigation page
Ui_MarbleNavigationSettingsWidget ui_navigationSettings;
- QWidget *w_navigationSettings = new QWidget( 0 );
+ QWidget *w_navigationSettings = new QWidget( nullptr );
w_navigationSettings->setObjectName( "navigation_page" );
ui_navigationSettings.setupUi( w_navigationSettings );
m_configDialog->addPage( w_navigationSettings, i18n( "Navigation" ),
"transform-move" );
ui_navigationSettings.kcfg_dragLocation->hide();
ui_navigationSettings.label_dragLocation->hide();
// cache page
Ui_MarbleCacheSettingsWidget ui_cacheSettings;
- QWidget *w_cacheSettings = new QWidget( 0 );
+ QWidget *w_cacheSettings = new QWidget( nullptr );
w_cacheSettings->setObjectName( "cache_page" );
ui_cacheSettings.setupUi( w_cacheSettings );
m_configDialog->addPage( w_cacheSettings, i18n( "Cache & Proxy" ),
"preferences-web-browser-cache" );
connect( ui_cacheSettings.button_clearVolatileCache, SIGNAL(clicked()),
m_controlView->marbleWidget(), SLOT(clearVolatileTileCache()) );
connect( ui_cacheSettings.button_clearPersistentCache, SIGNAL(clicked()),
m_controlView->marbleModel(), SLOT(clearPersistentTileCache()) );
// time page
Ui_MarbleTimeSettingsWidget ui_timeSettings;
- QWidget *w_timeSettings = new QWidget( 0 );
+ QWidget *w_timeSettings = new QWidget( nullptr );
w_timeSettings->setObjectName( "time_page" );
ui_timeSettings.setupUi( w_timeSettings );
m_configDialog->addPage( w_timeSettings, i18n( "Date & Time" ), "clock" );
// Sync page
- QWidget *w_cloudSyncSettings = new QWidget( 0 );
+ QWidget *w_cloudSyncSettings = new QWidget( nullptr );
w_cloudSyncSettings->setObjectName( "sync_page" );
m_ui_cloudSyncSettings.setupUi( w_cloudSyncSettings );
m_ui_cloudSyncSettings.button_syncNow->setEnabled( MarbleSettings::syncBookmarks() );
m_configDialog->addPage( w_cloudSyncSettings, i18n( "Synchronization" ), "folder-sync" );
connect( m_ui_cloudSyncSettings.button_syncNow, SIGNAL(clicked()),
m_controlView->cloudSyncManager()->bookmarkSyncManager(), SLOT(startBookmarkSync()) );
connect( m_ui_cloudSyncSettings.testLoginButton, SIGNAL(clicked()),
this, SLOT(updateCloudSyncCredentials()) );
connect( m_controlView->cloudSyncManager(), SIGNAL(statusChanged(QString)),
this, SLOT(updateCloudSyncStatus(QString)));
// routing page
RoutingProfilesWidget *w_routingSettings = new RoutingProfilesWidget( m_controlView->marbleModel() );
w_routingSettings->setObjectName( "routing_page" );
m_configDialog->addPage( w_routingSettings, i18n( "Routing" ), "flag");
// plugin page
MarblePluginSettingsWidget *w_pluginSettings = new MarblePluginSettingsWidget();
RenderPluginModel *const pluginModel = new RenderPluginModel( w_pluginSettings );
pluginModel->setRenderPlugins( m_controlView->marbleWidget()->renderPlugins() );
w_pluginSettings->setModel( 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( QIcon::fromTheme( "configure" ) );
w_pluginSettings->setAboutIcon( QIcon::fromTheme( "help-about" ) );
connect( w_pluginSettings, SIGNAL(pluginListViewClicked()),
SLOT(enableApplyButton()) );
connect( m_configDialog, SIGNAL(settingsChanged(QString)),
SLOT(updateSettings()) );
connect( m_configDialog, SIGNAL(accepted()),
SLOT(applyPluginState()) );
connect( m_configDialog, SIGNAL(accepted()),
pluginModel, SLOT(applyPluginState()) );
connect( m_configDialog, SIGNAL(rejected()),
pluginModel, SLOT(retrievePluginState()) );
m_configDialog->show();
}
void MarblePart::enableApplyButton()
{
//m_configDialog->enableButtonApply( true );
}
void MarblePart::applyPluginState()
{
QList<RoutingProfile> profiles = m_controlView->marbleWidget()
->model()->routingManager()->profilesModel()->profiles();
KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
KConfigGroup profilesGroup = sharedConfig->group( "Routing Profiles" );
profilesGroup.writeEntry( "Num", profiles.count() );
for ( int i = 0; i < profiles.count(); ++i ) {
KConfigGroup profileGroup = profilesGroup.group( QString( "Profile %0" ).arg(i) );
RoutingProfile profile = profiles.at( i );
profileGroup.writeEntry( "Name", profile.name() );
for ( const QString &pluginName: profileGroup.groupList() ) {
profileGroup.group( pluginName ).deleteGroup();
}
for ( const QString &key: profile.pluginSettings().keys() ) {
KConfigGroup pluginGroup = profileGroup.group( key );
pluginGroup.writeEntry( "Enabled", true );
for ( const QString& settingKey: profile.pluginSettings()[ key ].keys() ) {
Q_ASSERT(settingKey != QLatin1String("Enabled"));
pluginGroup.writeEntry( settingKey, profile.pluginSettings()[ key ][ settingKey ] );
}
}
}
}
void MarblePart::updateSettings()
{
qDebug() << "Updating Settings ...";
// FIXME: Font doesn't get updated instantly.
m_controlView->marbleWidget()->setDefaultFont( MarbleSettings::mapFont() );
m_controlView->marbleWidget()->
setMapQualityForViewContext( (MapQuality) MarbleSettings::stillQuality(),
Still );
m_controlView->marbleWidget()->
setMapQualityForViewContext( (MapQuality) MarbleSettings::animationQuality(),
Animation );
m_controlView->marbleWidget()->
setDefaultAngleUnit( (AngleUnit) MarbleSettings::angleUnit() );
MarbleGlobal::getInstance()->locale()->
setMeasurementSystem( (MarbleLocale::MeasurementSystem) MarbleSettings::distanceUnit() );
updateStatusBar();
m_controlView->marbleWidget()->setAnimationsEnabled( MarbleSettings::animateTargetVoyage() );
// Cache
m_controlView->marbleModel()->
setPersistentTileCacheLimit( MarbleSettings::persistentTileCacheLimit() * 1024 );
m_controlView->marbleWidget()->
setVolatileTileCacheLimit( MarbleSettings::volatileTileCacheLimit() * 1024 );
//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() == QLatin1String("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()->update();
// Time
if( MarbleSettings::systemTimezone() == true )
{
QDateTime localTime = QDateTime::currentDateTime().toLocalTime();
localTime.setTimeSpec( Qt::UTC );
m_controlView->marbleModel()->setClockTimezone( QDateTime::currentDateTime().toUTC().secsTo( localTime ) );
}
else if( MarbleSettings::utc() == true )
{
m_controlView->marbleModel()->setClockTimezone( 0 );
}
else if( MarbleSettings::customTimezone() == true )
{
m_controlView->marbleModel()->setClockTimezone( m_timezone.value( MarbleSettings::chosenTimezone() ) );
}
// Route rendering colors and alpha values
QColor tempColor;
tempColor = MarbleSettings::routeColorStandard();
tempColor.setAlpha( MarbleSettings::routeAlphaStandard() );
m_controlView->marbleModel()->routingManager()->setRouteColorStandard( tempColor );
tempColor = MarbleSettings::routeColorHighlighted();
tempColor.setAlpha( MarbleSettings::routeAlphaHighlighted() );
m_controlView->marbleModel()->routingManager()->setRouteColorHighlighted( tempColor );
tempColor = MarbleSettings::routeColorAlternative();
tempColor.setAlpha( MarbleSettings::routeAlphaAlternative() );
m_controlView->marbleModel()->routingManager()->setRouteColorAlternative( tempColor );
// External map editor
m_controlView->setExternalMapEditor( m_externalEditorMapping[MarbleSettings::externalMapEditor()] );
m_controlView->marbleWidget()->inputHandler()->setInertialEarthRotationEnabled( MarbleSettings::inertialEarthRotation() );
CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
cloudSyncManager->setOwncloudCredentials( MarbleSettings::owncloudServer(),
MarbleSettings::owncloudUsername(),
MarbleSettings::owncloudPassword());
cloudSyncManager->setSyncEnabled( MarbleSettings::enableSync() );
cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( MarbleSettings::syncRoutes() );
cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( MarbleSettings::syncBookmarks() );
}
void MarblePart::writePluginSettings()
{
KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
for( RenderPlugin *plugin: m_controlView->marbleWidget()->renderPlugins() ) {
KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() );
const QHash<QString,QVariant> hash = plugin->settings();
QHash<QString,QVariant>::const_iterator it = hash.begin();
while( it != hash.end() ) {
group.writeEntry( it.key(), it.value() );
++it;
}
group.sync();
}
}
void MarblePart::readPluginSettings()
{
disconnect( m_controlView->marbleWidget(), SIGNAL(pluginSettingsChanged()),
this, SLOT(writePluginSettings()) );
KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
for( RenderPlugin *plugin: m_controlView->marbleWidget()->renderPlugins() ) {
KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() );
QHash<QString,QVariant> hash;
for ( const QString& key: group.keyList() ) {
hash.insert( key, group.readEntry( key ) );
}
plugin->setSettings( hash );
}
connect( m_controlView->marbleWidget(), SIGNAL(pluginSettingsChanged()),
this, SLOT(writePluginSettings()) );
}
void MarblePart::lockFloatItemPosition( bool enabled )
{
QList<AbstractFloatItem *> floatItemList = m_controlView->marbleWidget()->floatItems();
QList<AbstractFloatItem *>::const_iterator i = floatItemList.constBegin();
QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd();
for (; i != end; ++i ) {
// Locking one would suffice as it affects all.
// Nevertheless go through all.
(*i)->setPositionLocked(enabled);
}
}
void MarblePart::handleProgress( int active, int queued )
{
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( qMax<int>( m_downloadProgressBar->maximum(), active + queued ) );
}
// qDebug() << "downloadProgressJobAdded: value/maximum: "
// << m_downloadProgressBar->value() << '/' << m_downloadProgressBar->maximum();
m_downloadProgressBar->setUpdatesEnabled( true );
}
void MarblePart::removeProgressItem()
{
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 );
}
void MarblePart::openEditBookmarkDialog()
{
MarbleWidget *widget = m_controlView->marbleWidget();
QPointer<EditBookmarkDialog> dialog = new EditBookmarkDialog( widget->model()->bookmarkManager(), widget );
dialog->setCoordinates( widget->lookAt().coordinates() );
dialog->setRange( widget->lookAt().range() );
dialog->setMarbleWidget( widget );
dialog->setReverseGeocodeName();
if ( dialog->exec() == QDialog::Accepted ) {
widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() );
}
delete dialog;
}
void MarblePart::setHome()
{
MarbleWidget *widget = m_controlView->marbleWidget();
widget->model()->setHome( widget->centerLongitude(), widget->centerLatitude(), widget->zoom() );
}
void MarblePart::openManageBookmarksDialog()
{
MarbleModel * const model = m_controlView->marbleModel();
QPointer<BookmarkManagerDialog> dialog = new BookmarkManagerDialog( model, m_controlView->marbleWidget() );
dialog->exec();
delete dialog;
}
void MarblePart::lookAtBookmark( QAction *action)
{
GeoDataLookAt temp = qvariant_cast<GeoDataLookAt>( action->data() ) ;
m_controlView->marbleWidget()->flyTo( temp ) ;
mDebug() << " looking at bookmark having longitude : "<< temp.longitude(GeoDataCoordinates::Degree)
<< " latitude : "<< temp.latitude(GeoDataCoordinates::Degree)
<< " distance : " << temp.range();
}
void MarblePart::initializeCustomTimezone()
{
if( m_timezone.count() == 0)
{
m_timezone.insert( 0, 0 );
m_timezone.insert( 1, 3600 );
m_timezone.insert( 2, 7200 );
m_timezone.insert( 3, 7200 );
m_timezone.insert( 4, 10800 );
m_timezone.insert( 5, 12600 );
m_timezone.insert( 6, 14400 );
m_timezone.insert( 7, 18000 );
m_timezone.insert( 8, 19800 );
m_timezone.insert( 9, 21600 );
m_timezone.insert( 10, 25200 );
m_timezone.insert( 11, 28800 );
m_timezone.insert( 12, 32400 );
m_timezone.insert( 13, 34200 );
m_timezone.insert( 14, 36000 );
m_timezone.insert( 15, 39600 );
m_timezone.insert( 16, 43200 );
m_timezone.insert( 17, -39600 );
m_timezone.insert( 18, -36000 );
m_timezone.insert( 19, -32400 );
m_timezone.insert( 20, -28800 );
m_timezone.insert( 21, -25200 );
m_timezone.insert( 22, -25200 );
m_timezone.insert( 23, -21600 );
m_timezone.insert( 24, -18000 );
m_timezone.insert( 25, -18000 );
m_timezone.insert( 26, -14400 );
m_timezone.insert( 27, -12600 );
m_timezone.insert( 28, -10800 );
m_timezone.insert( 29, -10800 );
m_timezone.insert( 30, -3600 );
}
}
void MarblePart::printMapScreenShot()
{
#ifndef QT_NO_PRINTER
QPrinter printer( QPrinter::HighResolution );
QPointer<QPrintDialog> printDialog = new QPrintDialog( &printer, widget() );
m_controlView->printMapScreenShot( printDialog );
delete printDialog;
#endif
}
void MarblePart::updateMapEditButtonVisibility( const QString &mapTheme )
{
Q_ASSERT( m_externalMapEditorAction );
m_externalMapEditorAction->setVisible(mapTheme == QLatin1String("earth/openstreetmap/openstreetmap.dgml"));
}
void MarblePart::fallBackToDefaultTheme()
{
m_controlView->marbleWidget()->setMapThemeId( m_controlView->defaultMapThemeId() );
}
void MarblePart::showMovieCaptureDialog()
{
- if (m_movieCaptureDialog == 0) {
+ if (m_movieCaptureDialog == nullptr) {
m_movieCaptureDialog = new MovieCaptureDialog(m_controlView->marbleWidget(),
m_controlView->marbleWidget());
connect( m_movieCaptureDialog, SIGNAL(started()), this, SLOT(changeRecordingState()));
}
m_movieCaptureDialog->show();
}
void MarblePart::stopRecording()
{
if ( m_movieCaptureDialog ) {
m_movieCaptureDialog->stopRecording();
changeRecordingState();
}
}
void MarblePart::changeRecordingState()
{
m_recordMovieAction->setEnabled( !m_recordMovieAction->isEnabled() );
m_stopRecordingAction->setEnabled( !m_stopRecordingAction->isEnabled() );
}
}
#include "moc_marble_part.cpp"
#include "marble_part.moc"
diff --git a/src/apps/marble-maps/MarbleMaps.h b/src/apps/marble-maps/MarbleMaps.h
index dd928396b..af2537687 100644
--- a/src/apps/marble-maps/MarbleMaps.h
+++ b/src/apps/marble-maps/MarbleMaps.h
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Dennis Nienhüser <nienhueser@kde.org>
//
#include <declarative/MarbleQuickItem.h>
#ifndef MARBLE_MAPS_H
#define MARBLE_MAPS_H
namespace Marble {
class MarbleMaps : public MarbleQuickItem
{
Q_OBJECT
Q_PROPERTY( bool suspended READ isSuspended NOTIFY isSuspendedChanged )
Q_PROPERTY(bool keepScreenOn READ keepScreenOn WRITE setKeepScreenOn NOTIFY keepScreenOnChanged)
public:
- explicit MarbleMaps(QQuickItem *parent = 0);
+ explicit MarbleMaps(QQuickItem *parent = nullptr);
bool isSuspended() const;
bool keepScreenOn() const;
public Q_SLOTS:
void setKeepScreenOn(bool keepScreenOn);
Q_SIGNALS:
void isSuspendedChanged(bool isSuspended);
void keepScreenOnChanged(bool keepScreenOn);
private Q_SLOTS:
void handleApplicationStateChange(Qt::ApplicationState state);
private:
bool m_suspended;
bool m_keepScreenOn;
};
}
#endif
diff --git a/src/apps/marble-maps/TextToSpeechClient.h b/src/apps/marble-maps/TextToSpeechClient.h
index 1b6715bea..c2428cd03 100644
--- a/src/apps/marble-maps/TextToSpeechClient.h
+++ b/src/apps/marble-maps/TextToSpeechClient.h
@@ -1,29 +1,29 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Gábor Péterffy <peterffy95@gmail.com>
//
#ifndef TEXTTOSPEECHCLIENT_H
#define TEXTTOSPEECHCLIENT_H
#include <QObject>
class TextToSpeechClient : public QObject
{
Q_OBJECT
public:
- explicit TextToSpeechClient(QObject * parent = 0);
+ explicit TextToSpeechClient(QObject * parent = nullptr);
~TextToSpeechClient() override;
public Q_SLOTS:
Q_INVOKABLE void readText(const QString & text);
Q_INVOKABLE void setLocale(const QString & locale);
};
#endif
diff --git a/src/apps/marble-qt/QtMainWindow.cpp b/src/apps/marble-qt/QtMainWindow.cpp
index 03bfd79d3..e601bbbfb 100644
--- a/src/apps/marble-qt/QtMainWindow.cpp
+++ b/src/apps/marble-qt/QtMainWindow.cpp
@@ -1,1666 +1,1666 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2010 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "QtMainWindow.h"
#include "MarbleDebug.h"
#include <QList>
#include <QSettings>
#include <QUrl>
#include <QCloseEvent>
#include <QVariant>
#include <QVector>
#include <QAction>
#include <QLabel>
#include <QWhatsThis>
#include <QApplication>
#include <QIcon>
#include <QMenuBar>
#include <QStatusBar>
#include <QProgressBar>
#include <QToolBar>
#include <QDesktopServices>
#include <QFileDialog>
#include <QMessageBox>
#include <QPrintDialog>
#include <QPrinter>
#include <QDialogButtonBox>
#include <QClipboard>
#include <QNetworkProxy>
#include "EditBookmarkDialog.h"
#include "BookmarkManagerDialog.h"
#include "CurrentLocationWidget.h"
#include "MapViewWidget.h"
#include "MarbleDirs.h"
#include "MarbleAboutDialog.h"
#include "QtMarbleConfigDialog.h"
#include "SunControlWidget.h"
#include "TimeControlWidget.h"
#include "MarbleLocale.h"
#include "DownloadRegionDialog.h"
#include "ViewportParams.h"
#include "AbstractFloatItem.h"
#include "MarbleModel.h"
#include "MarbleClock.h"
#include "HttpDownloadManager.h"
#include "BookmarkManager.h"
#include "NewBookmarkFolderDialog.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "GeoDataLookAt.h"
#include "GeoDataCoordinates.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataPlacemark.h"
#include "GeoUriParser.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingProfilesModel.h"
#include "routing/RoutingWidget.h"
#include "routing/RouteRequest.h"
#include "ParseRunnerPlugin.h"
#include "PositionTracking.h"
#include "PositionProviderPlugin.h"
#include "PluginManager.h"
#include "MapThemeDownloadDialog.h"
#include "MapWizard.h"
#include "MarbleWidgetInputHandler.h"
#include "Planet.h"
#include "cloudsync/CloudSyncManager.h"
#include "cloudsync/BookmarkSyncManager.h"
#include "cloudsync/RouteSyncManager.h"
#include "MovieCaptureDialog.h"
#include "DataMigration.h"
#include "TileCoordsPyramid.h"
using namespace Marble;
/* TRANSLATOR Marble::MainWindow */
MainWindow::MainWindow(const QString& marbleDataPath, const QVariantMap& cmdLineSettings, QWidget *parent) :
QMainWindow(parent),
- m_controlView( 0 ),
+ m_controlView( nullptr ),
m_savedSize( QSize(-1, -1) ),
- m_sunControlDialog( 0 ),
- m_timeControlDialog( 0 ),
- m_configDialog( 0 ),
- m_downloadRegionDialog( 0 ),
- m_movieCaptureDialog( 0 ),
+ m_sunControlDialog( nullptr ),
+ m_timeControlDialog( nullptr ),
+ m_configDialog( nullptr ),
+ m_downloadRegionDialog( nullptr ),
+ m_movieCaptureDialog( nullptr ),
// File Menu
- m_fileMenu( 0 ),
- m_viewMenu( 0 ),
- m_helpMenu( 0 ),
- m_settingsMenu( 0 ),
- m_panelMenu( 0 ),
- m_viewSizeMenu( 0 ),
- m_infoBoxesMenu( 0 ),
- m_onlineServicesMenu( 0 ),
- m_bookmarkMenu( 0 ),
- m_openAction( 0 ),
- m_exportMapAction( 0 ),
- m_downloadAction( 0 ),
- m_downloadRegionAction( 0 ),
- m_printPreviewAction( 0 ),
- m_printAction( 0 ),
- m_workOfflineAction( 0 ),
- m_quitAction( 0 ),
- m_mapWizardAction( 0 ),
+ m_fileMenu( nullptr ),
+ m_viewMenu( nullptr ),
+ m_helpMenu( nullptr ),
+ m_settingsMenu( nullptr ),
+ m_panelMenu( nullptr ),
+ m_viewSizeMenu( nullptr ),
+ m_infoBoxesMenu( nullptr ),
+ m_onlineServicesMenu( nullptr ),
+ m_bookmarkMenu( nullptr ),
+ m_openAction( nullptr ),
+ m_exportMapAction( nullptr ),
+ m_downloadAction( nullptr ),
+ m_downloadRegionAction( nullptr ),
+ m_printPreviewAction( nullptr ),
+ m_printAction( nullptr ),
+ m_workOfflineAction( nullptr ),
+ m_quitAction( nullptr ),
+ m_mapWizardAction( nullptr ),
// Edit Menu
- m_copyMapAction( 0 ),
- m_copyCoordinatesAction( 0 ),
- m_osmEditAction( 0 ),
- m_recordMovieAction( 0 ),
- m_stopRecordingAction( 0 ),
+ m_copyMapAction( nullptr ),
+ m_copyCoordinatesAction( nullptr ),
+ m_osmEditAction( nullptr ),
+ m_recordMovieAction( nullptr ),
+ m_stopRecordingAction( nullptr ),
// View Menu
- m_showCloudsAction( 0 ),\
- m_controlSunAction( 0 ),
- m_controlTimeAction( 0 ),
- m_reloadAction( 0 ),
+ m_showCloudsAction( nullptr ),\
+ m_controlSunAction( nullptr ),
+ m_controlTimeAction( nullptr ),
+ m_reloadAction( nullptr ),
// Settings Menu
- m_fullScreenAction( 0 ),
- m_statusBarAction( 0 ),
- m_configDialogAction( 0 ),
- m_viewSizeActsGroup( 0 ),
+ m_fullScreenAction( nullptr ),
+ m_statusBarAction( nullptr ),
+ m_configDialogAction( nullptr ),
+ m_viewSizeActsGroup( nullptr ),
// Help Menu
- m_whatsThisAction( 0 ),
- m_aboutMarbleAction( 0 ),
- m_aboutQtAction( 0 ),
- m_lockFloatItemsAction( 0 ),
- m_handbookAction( 0 ),
- m_forumAction( 0 ),
+ m_whatsThisAction( nullptr ),
+ m_aboutMarbleAction( nullptr ),
+ m_aboutQtAction( nullptr ),
+ m_lockFloatItemsAction( nullptr ),
+ m_handbookAction( nullptr ),
+ m_forumAction( nullptr ),
// Status Bar
- m_positionLabel( 0 ),
- m_distanceLabel( 0 ),
- m_zoomLabel( 0 ),
- m_clockLabel( 0 ),
- m_downloadProgressBar( 0 ),
- m_toggleTileLevelAction( 0 ),
- m_angleDisplayUnitActionGroup( 0 ),
- m_dmsDegreeAction( 0 ),
- m_decimalDegreeAction( 0 ),
- m_utmAction( 0 ),
+ m_positionLabel( nullptr ),
+ m_distanceLabel( nullptr ),
+ m_zoomLabel( nullptr ),
+ m_clockLabel( nullptr ),
+ m_downloadProgressBar( nullptr ),
+ m_toggleTileLevelAction( nullptr ),
+ m_angleDisplayUnitActionGroup( nullptr ),
+ m_dmsDegreeAction( nullptr ),
+ m_decimalDegreeAction( nullptr ),
+ m_utmAction( nullptr ),
//Bookmark Menu
- m_addBookmarkAction( 0 ),
- m_setHomeAction( 0 ),
- m_toggleBookmarkDisplayAction( 0 ),
- m_manageBookmarksAction( 0 )
+ m_addBookmarkAction( nullptr ),
+ m_setHomeAction( nullptr ),
+ m_toggleBookmarkDisplayAction( nullptr ),
+ m_manageBookmarksAction( nullptr )
{
setUpdatesEnabled( false );
QString selectedPath = marbleDataPath.isEmpty() ? readMarbleDataPath() : marbleDataPath;
if ( !selectedPath.isEmpty() )
MarbleDirs::setMarbleDataPath( selectedPath );
#ifdef Q_OS_WIN
QPointer<DataMigration> migration = new DataMigration(this);
migration->exec();
#endif
m_controlView = new ControlView( this );
setWindowIcon(QIcon(QStringLiteral(":/icons/marble.png")));
setCentralWidget( m_controlView );
// Initializing config dialog
m_configDialog = new QtMarbleConfigDialog( m_controlView->marbleWidget(),
m_controlView->cloudSyncManager(),
this );
connect( m_configDialog, SIGNAL(settingsChanged()),
this, SLOT(updateSettings()) );
connect( m_configDialog, SIGNAL(clearVolatileCacheClicked()),
m_controlView->marbleWidget(), SLOT(clearVolatileTileCache()) );
connect( m_configDialog, SIGNAL(clearPersistentCacheClicked()),
m_controlView->marbleModel(), SLOT(clearPersistentTileCache()) );
connect( m_configDialog, SIGNAL(syncNowClicked()),
m_controlView->cloudSyncManager()->bookmarkSyncManager(), SLOT(startBookmarkSync()) );
connect(m_configDialog, SIGNAL(syncNowClicked()),
m_configDialog, SLOT(disableSyncNow()));
// Load bookmark file. If it does not exist, a default one will be used.
m_controlView->marbleModel()->bookmarkManager()->loadFile( "bookmarks/bookmarks.kml" );
createActions();
QList<QAction*> const panelActions = m_controlView->setupDockWidgets( this );
createMenus( panelActions );
createStatusBar();
connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)),
this, SLOT(updateMapEditButtonVisibility(QString)) );
connect(m_controlView->marbleModel(), SIGNAL(themeChanged(QString)),
this, SLOT(updateWindowTitle()));
connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) );
connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) );
updateWindowTitle();
setUpdatesEnabled( true );
m_position = QCoreApplication::translate( "Marble", NOT_AVAILABLE );
m_distance = marbleWidget()->distanceString();
m_zoom = QString::number( marbleWidget()->tileZoomLevel() );
m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat );
QMetaObject::invokeMethod(this,
"initObject", Qt::QueuedConnection,
Q_ARG(QVariantMap, cmdLineSettings));
}
MainWindow::~MainWindow()
{
delete m_movieCaptureDialog;
}
void MainWindow::addGeoDataFile( const QString &fileName )
{
QFileInfo file( fileName );
if ( !file.exists() )
return;
// delay file loading to initObject(), such that restoring view from previous session in readSettings()
// doesn't interfere with focusing on these files
m_commandlineFilePaths << file.absoluteFilePath();
}
void MainWindow::initObject(const QVariantMap& cmdLineSettings)
{
QCoreApplication::processEvents ();
setupStatusBar();
readSettings(cmdLineSettings);
for ( const QString &path: m_commandlineFilePaths ) {
m_controlView->marbleModel()->addGeoDataFile( path );
}
if ( cmdLineSettings.contains( "tour" ) ) {
QString const tour = cmdLineSettings.value( "tour" ).toString();
m_controlView->openTour( tour );
}
m_commandlineFilePaths.clear();
}
void MainWindow::createActions()
{
m_openAction = new QAction(QIcon(QStringLiteral(":/icons/document-open.png")), tr("&Open..."), this);
m_openAction->setShortcut( tr( "Ctrl+O" ) );
m_openAction->setStatusTip( tr( "Open a file for viewing on Marble"));
connect( m_openAction, SIGNAL(triggered()),
this, SLOT(openFile()) );
m_downloadAction = new QAction(QIcon(QStringLiteral(":/icons/get-hot-new-stuff.png")), tr("&Download Maps..."), this);
connect(m_downloadAction, SIGNAL(triggered()), this, SLOT(openMapDialog()));
m_exportMapAction = new QAction(QIcon(QStringLiteral(":/icons/document-save-as.png")), tr("&Export Map..."), this);
m_exportMapAction->setShortcut(tr("Ctrl+S"));
m_exportMapAction->setStatusTip(tr("Save a screenshot of the map"));
connect(m_exportMapAction, SIGNAL(triggered()), this, SLOT(exportMapScreenShot()));
// Action: Download Region
m_downloadRegionAction = new QAction( tr( "Download &Region..." ), this );
m_downloadRegionAction->setStatusTip( tr( "Download a map region in different zoom levels for offline usage" ) );
connect( m_downloadRegionAction, SIGNAL(triggered()), SLOT(showDownloadRegionDialog()) );
m_printAction = new QAction(QIcon(QStringLiteral(":/icons/document-print.png")), tr("&Print..."), this);
m_printAction->setShortcut(tr("Ctrl+P"));
m_printAction->setStatusTip(tr("Print a screenshot of the map"));
connect(m_printAction, SIGNAL(triggered()), this, SLOT(printMapScreenShot()));
m_printPreviewAction = new QAction(QIcon(QStringLiteral(":/icons/document-print-preview.png")), tr("Print Previe&w ..."), this);
m_printPreviewAction->setStatusTip(tr("Print a screenshot of the map"));
connect(m_printPreviewAction, SIGNAL(triggered()), m_controlView, SLOT(printPreview()));
m_quitAction = new QAction(QIcon(QStringLiteral(":/icons/application-exit.png")), tr("&Quit"), this);
m_quitAction->setShortcut(tr("Ctrl+Q"));
m_quitAction->setStatusTip(tr("Quit the Application"));
connect(m_quitAction, SIGNAL(triggered()), this, SLOT(close()));
m_copyMapAction = new QAction(QIcon(QStringLiteral(":/icons/edit-copy.png")), tr("&Copy Map"), this);
m_copyMapAction->setShortcut(tr("Ctrl+C"));
m_copyMapAction->setStatusTip(tr("Copy a screenshot of the map"));
connect(m_copyMapAction, SIGNAL(triggered()), this, SLOT(copyMap()));
m_osmEditAction = new QAction(QIcon(QStringLiteral(":/icons/edit-map.png")), tr("&Edit Map"), this );
m_osmEditAction->setShortcut(tr( "Ctrl+E" ) );
m_osmEditAction->setStatusTip(tr( "Edit the current map region in an external editor" ) );
updateMapEditButtonVisibility( m_controlView->marbleWidget()->mapThemeId() );
connect( m_osmEditAction, SIGNAL(triggered()), m_controlView, SLOT(launchExternalMapEditor()) );
m_recordMovieAction = new QAction(tr("&Record Movie"), this);
m_recordMovieAction->setStatusTip(tr("Records a movie of the globe"));
m_recordMovieAction->setShortcut(QKeySequence("Ctrl+Shift+R"));
m_recordMovieAction->setIcon(QIcon(QStringLiteral(":/icons/animator.png")));
connect(m_recordMovieAction, SIGNAL(triggered()),
this, SLOT(showMovieCaptureDialog()));
m_stopRecordingAction = new QAction( tr("&Stop Recording"), this );
m_stopRecordingAction->setStatusTip( tr("Stop recording a movie of the globe") );
m_stopRecordingAction->setShortcut(QKeySequence( "Ctrl+Shift+S" ));
m_stopRecordingAction->setEnabled( false );
connect( m_stopRecordingAction, SIGNAL(triggered()),
this, SLOT(stopRecording()) );
m_configDialogAction = new QAction(QIcon(QStringLiteral(":/icons/settings-configure.png")), tr("&Configure Marble"), this);
m_configDialogAction->setStatusTip(tr("Show the configuration dialog"));
connect(m_configDialogAction, SIGNAL(triggered()), this, SLOT(editSettings()));
m_copyCoordinatesAction = new QAction(QIcon(QStringLiteral(":/icons/copy-coordinates.png")), tr("C&opy Coordinates"), this);
m_copyCoordinatesAction->setStatusTip(tr("Copy the center coordinates as text"));
connect(m_copyCoordinatesAction, SIGNAL(triggered()), this, SLOT(copyCoordinates()));
m_fullScreenAction = new QAction(QIcon(QStringLiteral(":/icons/view-fullscreen.png")), tr("&Full Screen Mode"), this);
m_fullScreenAction->setShortcut(tr("Ctrl+Shift+F"));
m_fullScreenAction->setCheckable( true );
m_fullScreenAction->setStatusTip(tr("Full Screen Mode"));
connect(m_fullScreenAction, SIGNAL(triggered(bool)), this, SLOT(showFullScreen(bool)));
m_statusBarAction = new QAction( tr("&Show Status Bar"), this);
m_statusBarAction->setCheckable( true );
m_statusBarAction->setStatusTip(tr("Show Status Bar"));
connect(m_statusBarAction, SIGNAL(triggered(bool)), this, SLOT(showStatusBar(bool)));
m_lockFloatItemsAction = new QAction(QIcon(QStringLiteral(":/icons/unlock.png")), tr("Lock Position"), this);
m_lockFloatItemsAction->setCheckable( true );
m_lockFloatItemsAction->setStatusTip(tr("Lock Position of Floating Items"));
connect(m_lockFloatItemsAction, SIGNAL(triggered(bool)), this, SLOT(lockPosition(bool)));
m_showCloudsAction = new QAction(QIcon(QStringLiteral(":/icons/clouds.png")), tr("&Clouds"), this);
m_showCloudsAction->setCheckable( true );
m_showCloudsAction->setStatusTip(tr("Show Real Time Cloud Cover"));
connect(m_showCloudsAction, SIGNAL(triggered(bool)), this, SLOT(showClouds(bool)));
m_workOfflineAction = new QAction(QIcon(QStringLiteral(":/icons/user-offline.png")), tr("Work Off&line"), this);
m_workOfflineAction->setCheckable( true );
connect(m_workOfflineAction, SIGNAL(triggered(bool)), this, SLOT(workOffline(bool)));
m_controlTimeAction = new QAction(QIcon(QStringLiteral(":/icons/clock.png")), tr("&Time Control..."), this );
m_controlTimeAction->setStatusTip( tr( "Configure Time Control " ) );
connect( m_controlTimeAction, SIGNAL(triggered()), this, SLOT(controlTime()) );
m_controlSunAction = new QAction( tr( "S&un Control..." ), this );
m_controlSunAction->setStatusTip( tr( "Configure Sun Control" ) );
connect( m_controlSunAction, SIGNAL(triggered()), this, SLOT(controlSun()) );
m_reloadAction = new QAction(QIcon(QStringLiteral(":/icons/view-refresh.png")), tr("&Redisplay"), this);
m_reloadAction->setShortcut(tr("F5"));
m_reloadAction->setStatusTip(tr("Reload Current Map"));
connect(m_reloadAction, SIGNAL(triggered()), this, SLOT(reload()));
m_handbookAction = new QAction(QIcon(QStringLiteral(":/icons/help-contents.png")), tr("Marble Virtual Globe &Handbook"), this);
m_handbookAction->setShortcut(tr("F1"));
m_handbookAction->setStatusTip(tr("Show the Handbook for Marble Virtual Globe"));
connect(m_handbookAction, SIGNAL(triggered()), this, SLOT(handbook()));
m_whatsThisAction = new QAction(QIcon(QStringLiteral(":/icons/help-whatsthis.png")), tr("What's &This"), this);
m_whatsThisAction->setShortcut(tr("Shift+F1"));
m_whatsThisAction->setStatusTip(tr("Show a detailed explanation of the action."));
connect(m_whatsThisAction, SIGNAL(triggered()), this, SLOT(enterWhatsThis()));
m_forumAction = new QAction( tr("&Community Forum"), this);
m_forumAction->setStatusTip(tr("Visit Marble's Community Forum"));
connect(m_forumAction, SIGNAL(triggered()), this, SLOT(openForum()));
m_aboutMarbleAction = new QAction(QIcon(QStringLiteral(":/icons/marble.png")), tr("&About Marble Virtual Globe"), this);
m_aboutMarbleAction->setStatusTip(tr("Show the application's About Box"));
connect(m_aboutMarbleAction, SIGNAL(triggered()), this, SLOT(aboutMarble()));
m_aboutQtAction = new QAction(tr("About &Qt"), this);
m_aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));
connect(m_aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
//Bookmark Actions
m_addBookmarkAction = new QAction(QIcon(QStringLiteral(":/icons/bookmark-new.png")), tr("&Add Bookmark"), this);
m_addBookmarkAction->setShortcut(tr("Ctrl+B"));
m_addBookmarkAction->setStatusTip(tr("Add Bookmark"));
connect( m_addBookmarkAction, SIGNAL(triggered()), this, SLOT(openEditBookmarkDialog()) );
m_setHomeAction = new QAction(QIcon(QStringLiteral(":/icons/go-home.png")), tr("&Set Home Location"), this);
m_setHomeAction->setStatusTip( tr( "&Set Home Location" ) );
connect( m_setHomeAction, SIGNAL(triggered()), this, SLOT(setHome()) );
m_toggleBookmarkDisplayAction = new QAction(tr( "Show &Bookmarks" ), this);
m_toggleBookmarkDisplayAction->setStatusTip( tr( "Toggle display of Bookmarks" ) );
m_toggleBookmarkDisplayAction->setCheckable( true );
connect( m_toggleBookmarkDisplayAction, SIGNAL(triggered(bool)), this, SLOT(showBookmarks(bool)) );
m_manageBookmarksAction = new QAction(QIcon(QStringLiteral(":/icons/bookmarks-organize.png")), tr("&Manage Bookmarks"), this);
m_manageBookmarksAction->setStatusTip( tr( "Manage Bookmarks" ) );
connect( m_manageBookmarksAction, SIGNAL(triggered()), this, SLOT(manageBookmarks()) );
// Map Wizard action
m_mapWizardAction = new QAction(QIcon(QStringLiteral(":/icons/create-new-map.png")), tr("&Create a New Map..."), this);
m_mapWizardAction->setStatusTip( tr( "A wizard guides you through the creation of your own map theme." ) );
connect( m_mapWizardAction, SIGNAL(triggered()), SLOT(showMapWizard()) );
// Statusbar Actions
m_toggleTileLevelAction = new QAction( tr( "Show Tile Zoom Level" ), statusBar() );
m_toggleTileLevelAction->setCheckable( true );
m_toggleTileLevelAction->setChecked( false );
connect( m_toggleTileLevelAction, SIGNAL(triggered(bool)),
this, SLOT(showZoomLevel(bool)) );
m_angleDisplayUnitActionGroup = new QActionGroup( statusBar() );
m_dmsDegreeAction = new QAction( tr( "Degree (DMS)" ), statusBar() );
m_dmsDegreeAction->setCheckable( true );
m_dmsDegreeAction->setData( (int)DMSDegree );
m_angleDisplayUnitActionGroup->addAction(m_dmsDegreeAction);
m_decimalDegreeAction = new QAction( tr( "Degree (Decimal)" ), statusBar() );
m_decimalDegreeAction->setCheckable( true );
m_decimalDegreeAction->setData( (int)DecimalDegree );
m_angleDisplayUnitActionGroup->addAction(m_decimalDegreeAction);
m_utmAction = new QAction( tr( "Universal Transverse Mercator (UTM)" ), statusBar() );
m_utmAction->setCheckable( true );
m_utmAction->setData( (int)UTM );
m_angleDisplayUnitActionGroup->addAction(m_utmAction);
connect( m_angleDisplayUnitActionGroup, SIGNAL(triggered(QAction*)),
this, SLOT(changeAngleDisplayUnit(QAction*)) );
// View size actions
m_viewSizeActsGroup = ControlView::createViewSizeActionGroup( this );
connect( m_viewSizeActsGroup, SIGNAL(triggered(QAction*)), this, SLOT(changeViewSize(QAction*)) );
}
void MainWindow::createMenus( const QList<QAction*> &panelActions )
{
m_fileMenu = menuBar()->addMenu(tr("&File"));
m_fileMenu->addAction(m_openAction);
m_fileMenu->addAction(m_downloadAction);
m_fileMenu->addAction( m_downloadRegionAction );
m_fileMenu->addAction( m_mapWizardAction );
m_fileMenu->addAction(m_exportMapAction);
m_fileMenu->addSeparator();
m_fileMenu->addAction(m_printAction);
m_fileMenu->addAction(m_printPreviewAction);
m_fileMenu->addSeparator();
m_fileMenu->addAction(m_workOfflineAction);
m_fileMenu->addAction(m_quitAction);
m_fileMenu = menuBar()->addMenu(tr("&Edit"));
m_fileMenu->addAction(m_copyMapAction);
m_fileMenu->addAction(m_copyCoordinatesAction);
m_fileMenu->addAction( m_osmEditAction );
m_fileMenu->addSeparator();
m_fileMenu->addAction(m_recordMovieAction);
m_fileMenu->addAction(m_stopRecordingAction);
m_viewMenu = menuBar()->addMenu(tr("&View"));
m_infoBoxesMenu = new QMenu(tr("&Info Boxes"), this);
m_onlineServicesMenu = new QMenu(tr("&Online Services"), this);
createPluginsMenus();
m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks"));
createBookmarkMenu();
connect( m_bookmarkMenu, SIGNAL(aboutToShow()), this, SLOT(createBookmarkMenu()) );
m_panelMenu = new QMenu(tr("&Panels"), this);
for( QAction* action: panelActions ) {
m_panelMenu->addAction( action );
}
m_viewSizeMenu = new QMenu(tr("&View Size"), this);
m_viewSizeMenu->addActions( m_viewSizeActsGroup->actions() );
m_settingsMenu = menuBar()->addMenu(tr("&Settings"));
m_settingsMenu->addMenu( m_panelMenu );
m_settingsMenu->addAction(m_statusBarAction);
m_settingsMenu->addSeparator();
m_settingsMenu->addMenu( m_viewSizeMenu );
m_settingsMenu->addAction(m_fullScreenAction);
m_settingsMenu->addSeparator();
m_settingsMenu->addAction(m_configDialogAction);
m_helpMenu = menuBar()->addMenu(tr("&Help"));
m_helpMenu->addAction(m_handbookAction);
m_helpMenu->addAction(m_forumAction);
m_helpMenu->addSeparator();
m_helpMenu->addAction(m_whatsThisAction);
m_helpMenu->addSeparator();
m_helpMenu->addAction(m_aboutMarbleAction);
m_helpMenu->addAction(m_aboutQtAction);
// FIXME: Discuss if this is the best place to put this
QList<RenderPlugin *> pluginList = m_controlView->marbleWidget()->renderPlugins();
QList<RenderPlugin *>::const_iterator it = pluginList.constBegin();
QList<RenderPlugin *>::const_iterator const listEnd = pluginList.constEnd();
for (; it != listEnd; ++it ) {
connect( (*it), SIGNAL(actionGroupsChanged()),
this, SLOT(createPluginMenus()) );
}
}
void MainWindow::createPluginsMenus()
{
m_onlineServicesMenu->clear();
m_infoBoxesMenu->clear();
m_viewMenu->clear();
m_viewMenu->addAction(m_reloadAction);
m_viewMenu->addSeparator();
// Do not create too many menu entries on a MID
// FIXME: Set up another way of switching the plugins on and off.
if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
return;
}
m_infoBoxesMenu->addAction(m_lockFloatItemsAction);
m_infoBoxesMenu->addSeparator();
QList<QAction*> themeActions;
QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
for (; i != end; ++i ) {
switch( (*i)->renderType() ) {
case RenderPlugin::TopLevelRenderType:
m_viewMenu->addAction( (*i)->action() );
break;
case RenderPlugin::PanelRenderType:
m_infoBoxesMenu->addAction( (*i)->action() );
break;
case RenderPlugin::OnlineRenderType:
m_onlineServicesMenu->addAction( (*i)->action() );
break;
case RenderPlugin::ThemeRenderType:
themeActions.append( (*i)->action() );
break;
default:
mDebug() << "No menu entry created for plugin with unknown render type:" << (*i)->nameId();
break;
}
}
m_viewMenu->addMenu( m_infoBoxesMenu );
m_viewMenu->addMenu( m_onlineServicesMenu );
m_viewMenu->addActions( themeActions );
m_viewMenu->addAction( m_showCloudsAction );
m_viewMenu->addSeparator();
m_viewMenu->addAction(m_controlSunAction);
m_viewMenu->addAction(m_controlTimeAction);
}
void MainWindow::createBookmarksListMenu( QMenu *bookmarksListMenu, const GeoDataContainer *container )
{
//m_bookmarksListMenu->clear();
QVector<GeoDataPlacemark*> bookmarks = container->placemarkList();
for ( const GeoDataPlacemark *placemark: bookmarks ) {
QAction *bookmarkAction = new QAction( placemark->name(), this );
QVariant var;
const GeoDataLookAt* lookAt = placemark->lookAt();
if ( !lookAt ) {
GeoDataCoordinates coordinates = placemark->coordinate();
GeoDataLookAt coordinateToLookAt;
coordinateToLookAt.setCoordinates( coordinates );
coordinateToLookAt.setRange( marbleWidget()->lookAt().range() );
var.setValue( coordinateToLookAt );
} else {
var.setValue( *lookAt );
}
bookmarkAction->setData( var );
bookmarksListMenu->addAction( bookmarkAction );
}
}
void MainWindow::createBookmarkMenu()
{
m_bookmarkMenu->clear();
m_bookmarkMenu->addAction( m_addBookmarkAction );
m_bookmarkMenu->addAction( m_toggleBookmarkDisplayAction );
m_toggleBookmarkDisplayAction->setChecked( m_controlView->marbleModel()->bookmarkManager()->document()->isVisible() );
m_bookmarkMenu->addAction( m_setHomeAction );
m_bookmarkMenu->addAction( m_manageBookmarksAction );
m_bookmarkMenu->addSeparator();
m_bookmarkMenu->addAction( QIcon(QStringLiteral(":/icons/go-home.png")), tr("&Home"),
m_controlView->marbleWidget(), SLOT(goHome()) );
createFolderList( m_bookmarkMenu, m_controlView->marbleModel()->bookmarkManager()->document() );
}
void MainWindow::createFolderList( QMenu *bookmarksListMenu, const GeoDataContainer *container )
{
QVector<GeoDataFolder*> folders = container->folderList();
if ( folders.size() == 1 && folders.first()->name() == tr("Default")) {
createBookmarksListMenu( bookmarksListMenu, folders.first() );
}
else {
for ( const GeoDataFolder *folder: folders ) {
QMenu *subMenu = bookmarksListMenu->addMenu(QIcon(QStringLiteral(":/icons/folder-bookmark.png")), folder->name());
createFolderList( subMenu, folder );
connect( subMenu, SIGNAL(triggered(QAction*)),
this, SLOT(lookAtBookmark(QAction*)) );
}
}
createBookmarksListMenu( bookmarksListMenu, container );
connect( bookmarksListMenu, SIGNAL(triggered(QAction*)),
this, SLOT(lookAtBookmark(QAction*)) );
}
void MainWindow::lookAtBookmark( QAction *action)
{
if ( action->data().isNull() ) {
return;
}
GeoDataLookAt temp = qvariant_cast<GeoDataLookAt>( action->data() ) ;
m_controlView->marbleWidget()->flyTo( temp ) ;
mDebug() << " looking at bookmark having longitude : "<< temp.longitude(GeoDataCoordinates::Degree)
<< " latitude : "<< temp.latitude(GeoDataCoordinates::Degree)
<< " distance : " << temp.range();
}
void MainWindow::manageBookmarks()
{
MarbleModel * const model = m_controlView->marbleModel();
QPointer<BookmarkManagerDialog> dialog = new BookmarkManagerDialog( model, this );
dialog->exec();
delete dialog;
}
void MainWindow::setHome()
{
MarbleWidget *widget = m_controlView->marbleWidget();
widget->model()->setHome( widget->centerLongitude(), widget->centerLatitude(), widget->zoom() );
}
void MainWindow::openEditBookmarkDialog()
{
MarbleWidget *widget = m_controlView->marbleWidget();
QPointer<EditBookmarkDialog> dialog = new EditBookmarkDialog( widget->model()->bookmarkManager(), widget );
dialog->setMarbleWidget( widget );
dialog->setCoordinates( widget->lookAt().coordinates() );
dialog->setRange( widget->lookAt().range() );
dialog->setReverseGeocodeName();
if ( dialog->exec() == QDialog::Accepted ) {
widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() );
}
delete dialog;
}
void MainWindow::createPluginMenus()
{
// Remove and delete toolbars if they exist
while( !m_pluginToolbars.isEmpty() ) {
QToolBar* tb = m_pluginToolbars.takeFirst();
this->removeToolBar(tb);
tb->deleteLater();
}
// Do not create too many menu entries on a MID
// FIXME: Set up another way of switching the plugins on and off.
if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
return;
}
//remove and delete old menus if they exist
while( !m_pluginMenus.isEmpty() ) {
m_viewMenu->removeAction( m_pluginMenus.takeFirst() );
}
QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
for (; i != end; ++i ) {
// menus
const QList<QActionGroup*> *tmp_actionGroups = (*i)->actionGroups();
if ((*i)->enabled() && tmp_actionGroups && (*i)->nameId() != QLatin1String("annotation")) {
for( QActionGroup *ag: *tmp_actionGroups ) {
if( !ag->actions().isEmpty() ) {
m_pluginMenus.append( m_viewMenu->addSeparator() );
}
for( QAction *action: ag->actions() ) {
m_viewMenu->addAction( action );
m_pluginMenus.append( action );
}
}
}
// toolbars
const QList<QActionGroup*> *tmp_toolbarActionGroups = (*i)->toolbarActionGroups();
if ( (*i)->enabled() && tmp_toolbarActionGroups ) {
QToolBar* toolbar = new QToolBar(this);
toolbar->setObjectName(QLatin1String("plugin-toolbar-") + (*i)->nameId());
for( QActionGroup* ag: *tmp_toolbarActionGroups ) {
toolbar->addActions( ag->actions() );
if ( tmp_toolbarActionGroups->last() != ag ) {
toolbar->addSeparator();
}
}
m_pluginToolbars.append( toolbar );
this->addToolBar( toolbar );
}
}
// FIXME: load the menus once the method has been settled on
}
void MainWindow::createStatusBar()
{
statusBar()->showMessage(tr("Ready"));
statusBar()->hide();
}
void MainWindow::openMapDialog()
{
QPointer<MapThemeDownloadDialog> dialog( new MapThemeDownloadDialog( m_controlView->marbleWidget() ) );
dialog->exec();
delete dialog;
}
void MainWindow::exportMapScreenShot()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Export Map"), // krazy:exclude=qclasses
QDir::homePath(),
tr("Images (*.jpg *.png)"));
if ( !fileName.isEmpty() )
{
// Take the case into account where no file format is indicated
- const char * format = 0;
+ const char * format = nullptr;
if ( !fileName.endsWith(QLatin1String( "png" ), Qt::CaseInsensitive)
&& !fileName.endsWith(QLatin1String( "jpg" ), Qt::CaseInsensitive) )
{
format = "JPG";
}
QPixmap mapPixmap = m_controlView->mapScreenShot();
bool success = mapPixmap.save( fileName, format );
if ( !success )
{
QMessageBox::warning(this, tr("Marble"), // krazy:exclude=qclasses
tr( "An error occurred while trying to save the file.\n" ),
QMessageBox::Ok);
}
}
}
void MainWindow::showFullScreen( bool isChecked )
{
if ( isChecked ) {
setWindowState( windowState() | Qt::WindowFullScreen ); // set
}
else {
setWindowState( windowState() & ~Qt::WindowFullScreen ); // reset
}
m_fullScreenAction->setChecked( isChecked ); // Sync state with the GUI
}
void MainWindow::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 MainWindow::copyMap()
{
QPixmap mapPixmap = m_controlView->mapScreenShot();
QClipboard *clipboard = QApplication::clipboard();
clipboard->setPixmap( mapPixmap );
}
void MainWindow::showStatusBar( bool isChecked )
{
if ( isChecked )
{
statusBar()->show();
}
else
{
statusBar()->hide();
}
m_statusBarAction->setChecked( isChecked ); // Sync state with the GUI
}
void MainWindow::showClouds( bool isChecked )
{
m_controlView->marbleWidget()->setShowClouds( isChecked );
m_showCloudsAction->setChecked( isChecked ); // Sync state with the GUI
}
void MainWindow::showBookmarks( bool show )
{
m_controlView->marbleModel()->bookmarkManager()->setShowBookmarks( show );
m_toggleBookmarkDisplayAction->setChecked( show ); // Sync state with the GUI
}
void MainWindow::workOffline( bool offline )
{
m_controlView->setWorkOffline( offline );
m_workOfflineAction->setChecked( offline ); // Sync state with the GUI
}
void MainWindow::lockPosition( bool isChecked )
{
QList<AbstractFloatItem *> floatItemList = m_controlView->marbleWidget()->floatItems();
QList<AbstractFloatItem *>::const_iterator i = floatItemList.constBegin();
QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd();
for (; i != end; ++i )
{
// Locking one would suffice as it affects all.
// Nevertheless go through all.
(*i)->setPositionLocked(isChecked);
}
}
void MainWindow::controlSun()
{
if (!m_sunControlDialog) {
m_sunControlDialog = new SunControlWidget( m_controlView->marbleWidget(), this );
connect( m_sunControlDialog, SIGNAL(showSun(bool)),
this, SLOT (showSun(bool)) );
}
m_sunControlDialog->show();
m_sunControlDialog->raise();
m_sunControlDialog->activateWindow();
}
void MainWindow::controlTime()
{
if ( !m_timeControlDialog )
{
m_timeControlDialog = new TimeControlWidget( m_controlView->marbleModel()->clock() );
}
/* m_timeControlDialog is a modeless dialog so that user may adjust time and interact with main application simultaneously.*/
m_timeControlDialog->show();
m_timeControlDialog->raise();
m_timeControlDialog->activateWindow();
}
void MainWindow::showSun( bool active )
{
m_controlView->marbleWidget()->setShowSunShading( active );
}
void MainWindow::reload()
{
m_controlView->marbleWidget()->reloadMap();
}
void MainWindow::enterWhatsThis()
{
QWhatsThis::enterWhatsThisMode();
}
void MainWindow::aboutMarble()
{
MarbleAboutDialog dlg(this);
dlg.setApplicationTitle( tr( "Marble Virtual Globe %1" ).arg( ControlView::applicationVersion() ) );
dlg.exec();
}
void MainWindow::handbook()
{
const QString code = MarbleLocale::languageCode();
QUrl handbookLocation(QLatin1String("http://docs.kde.org/stable/") + code + QLatin1String("/kdeedu/marble/index.html"));
// TODO: this logic seems broken. Should that check "code.isEmpty()" instead?
// and how do we konw there is a doc for the code?
if ( handbookLocation.isEmpty() )
handbookLocation = QUrl("http://docs.kde.org/stable/en/kdeedu/marble/index.html");
if( !QDesktopServices::openUrl( handbookLocation ) )
qDebug() << "URL not opened";
}
void MainWindow::openForum()
{
QUrl forumLocation("https://forum.kde.org/viewforum.php?f=217");
if( !QDesktopServices::openUrl( forumLocation ) ) {
mDebug() << "Failed to open URL " << forumLocation.toString();
}
}
void MainWindow::showPosition( const QString& position )
{
m_position = position;
updateStatusBar();
}
void MainWindow::showDistance( const QString& distance )
{
m_distance = distance;
updateStatusBar();
}
void MainWindow::showZoom( int zoom )
{
m_zoom = QString::number( zoom );
updateStatusBar();
}
void MainWindow::showDateTime()
{
m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat );
updateStatusBar();
}
void MainWindow::updateStatusBar()
{
if ( m_positionLabel )
m_positionLabel->setText(tr("Position: %1").arg(m_position));
if ( m_distanceLabel )
m_distanceLabel->setText(tr("Altitude: %1").arg(m_distance));
if ( m_zoomLabel )
m_zoomLabel->setText(tr("Zoom: %1").arg(m_zoom));
if ( m_clockLabel )
m_clockLabel->setText(tr("Time: %1").arg(m_clock));
switch ( m_configDialog->angleUnit() ) {
case DMSDegree:
m_dmsDegreeAction->setChecked( true );
break;
case DecimalDegree:
m_decimalDegreeAction->setChecked( true );
break;
case UTM:
m_utmAction->setChecked( true );
break;
}
}
void MainWindow::openFile()
{
const PluginManager *const pluginManager = m_controlView->marbleModel()->pluginManager();
QStringList allFileExtensions;
QStringList filters;
for ( const ParseRunnerPlugin *plugin: pluginManager->parsingRunnerPlugins() ) {
if (plugin->nameId() == QLatin1String("Cache"))
continue;
const QStringList fileExtensions = plugin->fileExtensions().replaceInStrings( QRegExp( "^" ), "*." );
const QString filter = plugin->fileFormatDescription() + QLatin1String(" (") + fileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
filters << filter;
allFileExtensions << fileExtensions;
}
allFileExtensions.sort(); // sort since file extensions are visible under Windows
const QString allFileTypes = tr("All Supported Files") + QLatin1String(" (") + allFileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
filters.sort();
filters.prepend( allFileTypes );
const QString filter = filters.join( ";;" );
QStringList fileNames = QFileDialog::getOpenFileNames( this, tr( "Open File" ), m_lastFileOpenPath, filter );
if ( !fileNames.isEmpty() ) {
const QString firstFile = fileNames.first();
m_lastFileOpenPath = QFileInfo( firstFile ).absolutePath();
}
for( const QString &fileName: fileNames ) {
m_controlView->marbleModel()->addGeoDataFile( fileName );
}
}
void MainWindow::setupStatusBar()
{
statusBar()->setSizeGripEnabled( true );
statusBar()->setContextMenuPolicy( Qt::ActionsContextMenu );
statusBar()->addAction( m_toggleTileLevelAction );
QMenu *angleDisplayUnitMenu = new QMenu(this);
angleDisplayUnitMenu->addActions( m_angleDisplayUnitActionGroup->actions() );
QAction *angleDisplayUnitMenuAction = new QAction( tr("&Angle Display Unit"), statusBar() );
angleDisplayUnitMenuAction->setMenu( angleDisplayUnitMenu );
statusBar()->addAction( angleDisplayUnitMenuAction );
setupDownloadProgressBar();
m_positionLabel = new QLabel( );
m_positionLabel->setIndent( 5 );
// UTM syntax is used in the template string, as it is longer than the lon/lat one
QString templatePositionString = tr("Position: %1").arg(QLatin1String(" 00Z 000000.00 m E, 00000000.00 m N_"));
int maxPositionWidth = fontMetrics().boundingRect(templatePositionString).width()
+ 2 * m_positionLabel->margin() + 2 * m_positionLabel->indent();
m_positionLabel->setFixedWidth( maxPositionWidth );
statusBar()->addPermanentWidget ( m_positionLabel );
m_distanceLabel = new QLabel( );
m_distanceLabel->setIndent( 5 );
QString templateDistanceString = tr("Altitude: %1").arg(QLatin1String(" 00.000,0 mu"));
int maxDistanceWidth = fontMetrics().boundingRect(templateDistanceString).width()
+ 2 * m_distanceLabel->margin() + 2 * m_distanceLabel->indent();
m_distanceLabel->setFixedWidth( maxDistanceWidth );
statusBar()->addPermanentWidget ( m_distanceLabel );
m_zoomLabel = new QLabel( );
m_zoomLabel->setIndent( 5 );
QString templateZoomString = tr("Zoom: %1").arg(QLatin1String(" 00"));
int maxZoomWidth = fontMetrics().boundingRect(templateZoomString).width()
+ 2 * m_zoomLabel->margin() + 2 * m_zoomLabel->indent();
m_zoomLabel->setFixedWidth( maxZoomWidth );
// Not added here, but activated by the user with the context menu
m_clockLabel = new QLabel( );
m_clockLabel->setIndent( 5 );
QString templateDateTimeString = tr("Time: %1").arg(QLocale().toString(QDateTime::fromString( "01:01:1000", "dd:mm:yyyy"), QLocale::ShortFormat));
int maxDateTimeWidth = fontMetrics().boundingRect( templateDateTimeString ).width()
+ 2 * m_clockLabel->margin() + 2 * m_clockLabel->indent();
m_clockLabel->setFixedWidth( maxDateTimeWidth );
statusBar()->addPermanentWidget ( m_clockLabel );
connect( marbleWidget(), SIGNAL(mouseMoveGeoPosition(QString)),
this, SLOT(showPosition(QString)) );
connect( marbleWidget(), SIGNAL(distanceChanged(QString)),
this, SLOT(showDistance(QString)) );
connect( marbleWidget(), SIGNAL(tileLevelChanged(int)),
this, SLOT(showZoom(int)) );
connect( m_controlView->marbleModel()->clock(), SIGNAL(timeChanged()),
this, SLOT(showDateTime()) );
updateStatusBar();
}
void MainWindow::setupDownloadProgressBar()
{
m_downloadProgressBar = new QProgressBar;
m_downloadProgressBar->setVisible( true );
statusBar()->addPermanentWidget( m_downloadProgressBar );
HttpDownloadManager * const downloadManager =
m_controlView->marbleModel()->downloadManager();
Q_ASSERT( downloadManager );
connect( downloadManager, SIGNAL(progressChanged(int,int)), SLOT(handleProgress(int,int)) );
connect( downloadManager, SIGNAL(jobRemoved()), SLOT(removeProgressItem()) );
}
void MainWindow::handleProgress( int active, int queued ){
m_downloadProgressBar->setUpdatesEnabled( false );
if ( m_downloadProgressBar->value() < 0 ) {
m_downloadProgressBar->setMaximum( 1 );
m_downloadProgressBar->setValue( 0 );
m_downloadProgressBar->setVisible( true );
} else {
m_downloadProgressBar->setMaximum( qMax<int>( m_downloadProgressBar->maximum(), active + queued ) );
}
m_downloadProgressBar->setUpdatesEnabled( true );
}
void MainWindow::removeProgressItem(){
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 );
}
m_downloadProgressBar->setUpdatesEnabled( true );
}
void MainWindow::closeEvent( QCloseEvent *event )
{
writeSettings();
QCloseEvent newEvent;
QCoreApplication::sendEvent( m_controlView, &newEvent );
if ( newEvent.isAccepted() ) {
event->accept();
} else {
event->ignore();
}
}
QString MainWindow::readMarbleDataPath()
{
QSettings settings;
settings.beginGroup("MarbleWidget");
QString marbleDataPath;
marbleDataPath = settings.value("marbleDataPath", "").toString(),
settings.endGroup();
return marbleDataPath;
}
void MainWindow::readSettings(const QVariantMap& overrideSettings)
{
QSettings settings;
settings.beginGroup("MainWindow");
resize(settings.value("size", QSize(640, 480)).toSize());
move(settings.value("pos", QPoint(200, 200)).toPoint());
showFullScreen(settings.value("fullScreen", false ).toBool());
showStatusBar(settings.value("statusBar", false ).toBool());
showZoomLevel(settings.value("showZoomLevel",false).toBool());
show();
showClouds(settings.value("showClouds", true ).toBool());
workOffline(settings.value("workOffline", false ).toBool());
m_controlView->marbleWidget()->setShowAtmosphere(settings.value("showAtmosphere", true ).toBool());
m_lastFileOpenPath = settings.value("lastFileOpenDir", QDir::homePath()).toString();
showBookmarks( settings.value( "showBookmarks", true ).toBool() );
restoreState( settings.value("windowState").toByteArray() );
settings.endGroup();
setUpdatesEnabled(false);
settings.beginGroup("MarbleWidget");
QString mapThemeId;
const QVariantMap::ConstIterator mapThemeIdIt = overrideSettings.find(QLatin1String("mapTheme"));
if ( mapThemeIdIt != overrideSettings.constEnd() ) {
mapThemeId = mapThemeIdIt.value().toString();
} else {
mapThemeId = settings.value("mapTheme", m_controlView->defaultMapThemeId() ).toString();
}
mDebug() << Q_FUNC_INFO << "mapThemeId:" << mapThemeId;
m_controlView->marbleWidget()->setMapThemeId( mapThemeId );
m_controlView->marbleWidget()->setProjection(
(Projection)(settings.value("projection", Spherical ).toInt())
);
// Set home position
m_controlView->marbleModel()->setHome(
settings.value("homeLongitude", 9.4).toDouble(),
settings.value("homeLatitude", 54.8).toDouble(),
settings.value("homeZoom", 1050 ).toInt()
);
// Center on/Distance
const QVariantMap::ConstIterator distanceIt = overrideSettings.find(QLatin1String("distance"));
const bool isDistanceOverwritten = (distanceIt != overrideSettings.constEnd());
const QVariantMap::ConstIterator lonLatIt = overrideSettings.find(QLatin1String("lonlat"));
if ( lonLatIt != overrideSettings.constEnd() ) {
const QVariantList lonLat = lonLatIt.value().toList();
m_controlView->marbleWidget()->centerOn( lonLat.at(0).toDouble(), lonLat.at(1).toDouble() );
} else {
switch ( m_configDialog->onStartup() ) {
case Marble::LastLocationVisited:
m_controlView->marbleWidget()->centerOn(
settings.value("quitLongitude", 0.0).toDouble(),
settings.value("quitLatitude", 0.0).toDouble() );
if (! isDistanceOverwritten) {
// set default radius to 1350 (Atlas theme's "sharp" radius)
m_controlView->marbleWidget()->setRadius( settings.value("quitRadius", 1350).toInt() );
}
break;
case Marble::ShowHomeLocation:
m_controlView->marbleWidget()->goHome();
break;
default:
break;
}
}
if (isDistanceOverwritten) {
m_controlView->marbleWidget()->setDistance(distanceIt.value().toDouble());
}
// Geo URI parsing
QString geoUriString = qvariant_cast<QString>( overrideSettings.value("geo-uri", ""));
if ( !geoUriString.isEmpty() ) {
m_controlView->openGeoUri( geoUriString );
}
bool isLocked = settings.value( "lockFloatItemPositions", false ).toBool();
m_lockFloatItemsAction->setChecked( isLocked );
lockPosition(isLocked);
settings.endGroup();
settings.beginGroup( "Sun" );
m_controlView->marbleWidget()->setShowSunShading( settings.value( "showSun", false ).toBool() );
m_controlView->marbleWidget()->setShowCityLights( settings.value( "showCitylights", false ).toBool() );
m_controlView->marbleWidget()->setLockToSubSolarPoint( settings.value( "lockToSubSolarPoint", false ).toBool() );
m_controlView->marbleWidget()->setSubSolarPointIconVisible( settings.value( "subSolarPointIconVisible", false ).toBool() );
settings.endGroup();
settings.beginGroup( "Time" );
if( settings.value( "systemTime", "true" ).toBool() == true )
{
/* nothing to do */
}
else if( settings.value( "lastSessionTime", "true" ).toBool() == true )
{
m_controlView->marbleModel()->setClockDateTime( settings.value( "dateTime" ).toDateTime() );
m_controlView->marbleModel()->setClockSpeed( settings.value( "speedSlider", 1 ).toInt() );
}
settings.endGroup();
setUpdatesEnabled(true);
// Load previous route settings
settings.beginGroup( "Routing" );
{
RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager();
routingManager->readSettings();
bool const startupWarning = settings.value( "showGuidanceModeStartupWarning", QVariant( true ) ).toBool();
routingManager->setShowGuidanceModeStartupWarning( startupWarning );
routingManager->setLastOpenPath( settings.value( "lastRouteOpenPath", QDir::homePath() ).toString() );
routingManager->setLastSavePath( settings.value( "lastRouteSavePath", QDir::homePath() ).toString() );
QColor tempColor;
tempColor = QColor( settings.value( "routeColorStandard", Oxygen::skyBlue4.name() ).toString() );
tempColor.setAlpha( settings.value( "routeAlphaStandard", 200 ).toInt() );
routingManager->setRouteColorStandard( tempColor );
tempColor = QColor( settings.value( "routeColorHighlighted", Oxygen::skyBlue1.name() ).toString() );
tempColor.setAlpha( settings.value( "routeAlphaHighlighted", 200 ).toInt() );
routingManager->setRouteColorHighlighted( tempColor );
tempColor = QColor( settings.value( "routeColorAlternative", Oxygen::aluminumGray4.name() ).toString() );
tempColor.setAlpha( settings.value( "routeAlphaAlternative", 200 ).toInt() );
routingManager->setRouteColorAlternative( tempColor );
}
settings.endGroup();
settings.beginGroup( "Routing Profile" );
if ( settings.contains( "Num" ) ) {
QList<RoutingProfile> profiles;
int numProfiles = settings.value( "Num", 0 ).toInt();
for ( int i = 0; i < numProfiles; ++i ) {
settings.beginGroup( QString( "Profile %0" ).arg(i) );
QString name = settings.value( "Name", tr( "Unnamed" ) ).toString();
RoutingProfile profile( name );
for ( const QString& pluginName: settings.childGroups() ) {
settings.beginGroup( pluginName );
profile.pluginSettings().insert( pluginName, QHash<QString, QVariant>() );
for ( const QString& key: settings.childKeys() ) {
if (key != QLatin1String("Enabled")) {
profile.pluginSettings()[ pluginName ].insert( key, settings.value( key ) );
}
}
settings.endGroup();
}
profiles << profile;
settings.endGroup();
}
m_controlView->marbleModel()->routingManager()->profilesModel()->setProfiles( profiles );
} else {
m_controlView->marbleModel()->routingManager()->profilesModel()->loadDefaultProfiles();
}
int const profileIndex = settings.value( "currentIndex", 0 ).toInt();
if ( profileIndex >= 0 && profileIndex < m_controlView->marbleModel()->routingManager()->profilesModel()->rowCount() ) {
RoutingProfile profile = m_controlView->marbleModel()->routingManager()->profilesModel()->profiles().at( profileIndex );
m_controlView->marbleModel()->routingManager()->routeRequest()->setRoutingProfile( profile );
}
settings.endGroup();
settings.beginGroup( "Plugins");
PositionTracking* tracking = m_controlView->marbleModel()->positionTracking();
tracking->readSettings();
QString positionProvider = settings.value( "activePositionTrackingPlugin", QString() ).toString();
if ( !positionProvider.isEmpty() ) {
const PluginManager* pluginManager = m_controlView->marbleModel()->pluginManager();
for( const PositionProviderPlugin* plugin: pluginManager->positionProviderPlugins() ) {
if ( plugin->nameId() == positionProvider ) {
PositionProviderPlugin* instance = plugin->newInstance();
tracking->setPositionProviderPlugin( instance );
break;
}
}
}
settings.endGroup();
settings.beginGroup( "Tracking" );
if ( settings.contains( "autoCenter" ) || settings.contains( "recenterMode" ) ) {
CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget();
Q_ASSERT( trackingWidget );
trackingWidget->setRecenterMode( settings.value( "recenterMode", 0 ).toInt() );
trackingWidget->setAutoZoom( settings.value( "autoZoom", false ).toBool() );
trackingWidget->setTrackVisible( settings.value( "trackVisible", true ).toBool() );
trackingWidget->setLastOpenPath( settings.value( "lastTrackOpenPath", QDir::homePath() ).toString() );
trackingWidget->setLastSavePath( settings.value( "lastTrackSavePath", QDir::homePath() ).toString() );
}
settings.endGroup();
// The config dialog has to read settings.
m_configDialog->readSettings();
settings.beginGroup( "Navigation" );
m_controlView->setExternalMapEditor( settings.value( "externalMapEditor", "" ).toString() );
settings.endGroup();
settings.beginGroup( "CloudSync" );
CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
cloudSyncManager->setOwncloudCredentials( settings.value( "owncloudServer", "" ).toString(),
settings.value( "owncloudUsername", "" ).toString(),
settings.value( "owncloudPassword", "" ).toString() );
cloudSyncManager->setSyncEnabled( settings.value( "enableSync", false ).toBool() );
cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( settings.value( "syncRoutes", true ).toBool() );
cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( settings.value( "syncBookmarks", true ).toBool() );
settings.endGroup();
}
void MainWindow::writeSettings()
{
QSettings settings;
settings.beginGroup( "MainWindow" );
settings.setValue( "size", size() );
settings.setValue( "pos", pos() );
settings.setValue( "fullScreen", m_fullScreenAction->isChecked() );
settings.setValue( "statusBar", m_statusBarAction->isChecked() );
settings.setValue( "showZoomLevel", m_toggleTileLevelAction->isChecked() );
settings.setValue( "showClouds", m_showCloudsAction->isChecked() );
settings.setValue( "workOffline", m_workOfflineAction->isChecked() );
settings.setValue( "showAtmosphere", m_controlView->marbleWidget()->showAtmosphere() );
settings.setValue( "lastFileOpenDir", m_lastFileOpenPath );
settings.setValue( "showBookmarks", m_toggleBookmarkDisplayAction->isChecked() );
settings.setValue( "windowState", saveState() );
settings.endGroup();
settings.beginGroup( "MarbleWidget" );
// Get the 'home' values from the widget and store them in the settings.
qreal homeLon = 0;
qreal homeLat = 0;
int homeZoom = 0;
m_controlView->marbleModel()->home( homeLon, homeLat, homeZoom );
QString mapTheme = m_controlView->marbleWidget()->mapThemeId();
int projection = (int)( m_controlView->marbleWidget()->projection() );
settings.setValue( "homeLongitude", homeLon );
settings.setValue( "homeLatitude", homeLat );
settings.setValue( "homeZoom", homeZoom );
settings.setValue( "mapTheme", mapTheme );
settings.setValue( "projection", projection );
// 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();
const int quitRadius = m_controlView->marbleWidget()->radius();
settings.setValue( "quitLongitude", quitLon );
settings.setValue( "quitLatitude", quitLat );
settings.setValue( "quitRadius", quitRadius );
settings.setValue( "lockFloatItemPositions", m_lockFloatItemsAction->isChecked() );
settings.endGroup();
settings.beginGroup( "Sun" );
settings.setValue( "showSun", m_controlView->marbleWidget()->showSunShading() );
settings.setValue( "showCitylights", m_controlView->marbleWidget()->showCityLights() );
settings.setValue( "lockToSubSolarPoint", m_controlView->marbleWidget()->isLockedToSubSolarPoint() );
settings.setValue( "subSolarPointIconVisible", m_controlView->marbleWidget()->isSubSolarPointIconVisible() );
settings.endGroup();
settings.beginGroup( "Time" );
settings.setValue( "dateTime", m_controlView->marbleModel()->clockDateTime() );
settings.setValue( "speedSlider", m_controlView->marbleModel()->clockSpeed() );
settings.endGroup();
settings.beginGroup( "Routing Profile" );
QList<RoutingProfile> profiles = m_controlView->marbleWidget()
->model()->routingManager()->profilesModel()->profiles();
settings.setValue( "Num", profiles.count() );
for ( int i = 0; i < profiles.count(); ++i ) {
settings.beginGroup( QString( "Profile %0" ).arg(i) );
const RoutingProfile& profile = profiles.at( i );
settings.setValue( "Name", profile.name() );
for ( const QString& pluginName: settings.childGroups() ) {
settings.beginGroup( pluginName );
settings.remove(QString()); //remove all keys
settings.endGroup();
}
for ( const QString &key: profile.pluginSettings().keys() ) {
settings.beginGroup( key );
settings.setValue( "Enabled", true );
for ( const QString& settingKey: profile.pluginSettings()[ key ].keys() ) {
Q_ASSERT(settingKey != QLatin1String("Enabled"));
settings.setValue( settingKey, profile.pluginSettings()[ key ][ settingKey ] );
}
settings.endGroup();
}
settings.endGroup();
}
RoutingProfile const profile = m_controlView->marbleWidget()->model()->routingManager()->routeRequest()->routingProfile();
settings.setValue( "currentIndex", profiles.indexOf( profile ) );
settings.endGroup();
settings.beginGroup( "Plugins");
QString positionProvider;
PositionTracking* tracking = m_controlView->marbleModel()->positionTracking();
tracking->writeSettings();
if ( tracking->positionProviderPlugin() ) {
positionProvider = tracking->positionProviderPlugin()->nameId();
}
settings.setValue( "activePositionTrackingPlugin", positionProvider );
settings.endGroup();
settings.beginGroup( "Tracking" );
CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget();
if ( trackingWidget ) {
// Can be null due to lazy initialization
settings.setValue( "recenterMode", trackingWidget->recenterMode() );
settings.setValue( "autoZoom", trackingWidget->autoZoom() );
settings.setValue( "trackVisible", trackingWidget->trackVisible() );
settings.setValue( "lastTrackOpenPath", trackingWidget->lastOpenPath() );
settings.setValue( "lastTrackSavePath", trackingWidget->lastSavePath() );
}
settings.endGroup();
// The config dialog has to write settings.
m_configDialog->writeSettings();
// Store current route settings
settings.beginGroup( "Routing" );
{
RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager();
routingManager->writeSettings();
settings.setValue( "showGuidanceModeStartupWarning", routingManager->showGuidanceModeStartupWarning() );
settings.setValue( "lastRouteOpenPath", routingManager->lastOpenPath() );
settings.setValue( "lastRouteSavePath", routingManager->lastSavePath() );
settings.setValue( "routeColorStandard", routingManager->routeColorStandard().name() );
settings.setValue( "routeAlphaStandard", routingManager->routeColorStandard().alpha() );
settings.setValue( "routeColorHighlighted", routingManager->routeColorHighlighted().name() );
settings.setValue( "routeAlphaHighlighted", routingManager->routeColorHighlighted().alpha() );
settings.setValue( "routeColorAlternative", routingManager->routeColorAlternative().name() );
settings.setValue( "routeAlphaAlternative", routingManager->routeColorAlternative().alpha() );
}
settings.endGroup();
settings.beginGroup( "Navigation");
settings.setValue( "externalMapEditor", m_controlView->externalMapEditor() );
settings.endGroup();
}
void MainWindow::editSettings()
{
// Show the settings dialog.
m_configDialog->show();
m_configDialog->raise();
m_configDialog->activateWindow();
}
void MainWindow::updateSettings()
{
mDebug() << Q_FUNC_INFO << "Updating Settings ...";
// FIXME: Font doesn't get updated instantly.
m_controlView->marbleWidget()->setDefaultFont( m_configDialog->mapFont() );
m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->stillQuality(), Marble::Still );
m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->animationQuality(), Marble::Animation );
m_controlView->marbleWidget()->setDefaultAngleUnit( m_configDialog->angleUnit() );
MarbleGlobal::getInstance()->locale()->setMeasurementSystem( m_configDialog->measurementSystem() );
m_distance = m_controlView->marbleWidget()->distanceString();
updateStatusBar();
m_controlView->marbleWidget()->setAnimationsEnabled( m_configDialog->animateTargetVoyage() );
m_controlView->marbleWidget()->inputHandler()->setInertialEarthRotationEnabled( m_configDialog->inertialEarthRotation() );
if ( !m_configDialog->externalMapEditor().isEmpty() ) {
m_controlView->setExternalMapEditor( m_configDialog->externalMapEditor() );
}
// Cache
m_controlView->marbleModel()->setPersistentTileCacheLimit( m_configDialog->persistentTileCacheLimit() * 1024 );
m_controlView->marbleWidget()->setVolatileTileCacheLimit( m_configDialog->volatileTileCacheLimit() * 1024 );
/*
m_controlView->marbleWidget()->setProxy( m_configDialog->proxyUrl(), m_configDialog->proxyPort(), m_configDialog->user(), m_configDialog->password() );
*/
CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
cloudSyncManager->setOwncloudCredentials( m_configDialog->owncloudServer(),
m_configDialog->owncloudUsername(),
m_configDialog->owncloudPassword() );
cloudSyncManager->setSyncEnabled( m_configDialog->syncEnabled() );
cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( m_configDialog->syncRoutes() );
cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( m_configDialog->syncBookmarks() );
m_controlView->marbleWidget()->update();
}
void MainWindow::showDownloadRegionDialog()
{
if ( !m_downloadRegionDialog ) {
m_downloadRegionDialog = new DownloadRegionDialog( m_controlView->marbleWidget(), m_controlView );
// it might be tempting to move the connects to DownloadRegionDialog's "accepted" and
// "applied" signals, be aware that the "hidden" signal might be come before the "accepted"
// signal, leading to a too early disconnect.
connect( m_downloadRegionDialog, SIGNAL(accepted()), SLOT(downloadRegion()));
connect( m_downloadRegionDialog, SIGNAL(applied()), SLOT(downloadRegion()));
}
// FIXME: get allowed range from current map theme
m_downloadRegionDialog->setAllowedTileLevelRange( 0, 16 );
m_downloadRegionDialog->setSelectionMethod( DownloadRegionDialog::VisibleRegionMethod );
ViewportParams const * const viewport =
m_controlView->marbleWidget()->viewport();
m_downloadRegionDialog->setSpecifiedLatLonAltBox( viewport->viewLatLonAltBox() );
m_downloadRegionDialog->setVisibleLatLonAltBox( viewport->viewLatLonAltBox() );
m_downloadRegionDialog->show();
m_downloadRegionDialog->raise();
m_downloadRegionDialog->activateWindow();
}
void MainWindow::downloadRegion()
{
Q_ASSERT( m_downloadRegionDialog );
QVector<TileCoordsPyramid> const pyramid = m_downloadRegionDialog->region();
if ( !pyramid.isEmpty() ) {
m_controlView->marbleWidget()->downloadRegion( pyramid );
}
}
void MainWindow::printMapScreenShot()
{
#ifndef QT_NO_PRINTER
QPrinter printer( QPrinter::HighResolution );
QPointer<QPrintDialog> printDialog = new QPrintDialog( &printer, this );
m_controlView->printMapScreenShot( printDialog );
delete printDialog;
#endif
}
void MainWindow::updateMapEditButtonVisibility( const QString &mapTheme )
{
Q_ASSERT( m_osmEditAction );
QStringList osmThemes = QStringList()
<< "earth/openstreetmap/openstreetmap.dgml"
<< "earth/hikebikemap/hikebikemap.dgml"
<< "earth/opencyclemap/opencyclemap.dgml"
<< "earth/public-transport/public-transport.dgml"
<< "earth/openseamap/openseamap.dgml"
<< "earth/vectorosm/vectorosm.dgml";
m_osmEditAction->setVisible(osmThemes.contains(mapTheme));
}
void MainWindow::showMovieCaptureDialog()
{
- if (m_movieCaptureDialog == 0) {
+ if (m_movieCaptureDialog == nullptr) {
m_movieCaptureDialog = new MovieCaptureDialog(m_controlView->marbleWidget(),
m_controlView->marbleWidget());
connect( m_movieCaptureDialog, SIGNAL(started()), this, SLOT(changeRecordingState()));
}
m_movieCaptureDialog->show();
}
void MainWindow::stopRecording()
{
if ( m_movieCaptureDialog ) {
m_movieCaptureDialog->stopRecording();
changeRecordingState();
}
}
void MainWindow::changeRecordingState()
{
m_recordMovieAction->setEnabled( !m_recordMovieAction->isEnabled() );
m_stopRecordingAction->setEnabled( !m_stopRecordingAction->isEnabled() );
}
void MainWindow::updateWindowTitle()
{
GeoSceneDocument *theme = m_controlView->marbleModel()->mapTheme();
setWindowTitle(theme ? theme->head()->name() : QString());
}
void MainWindow::showMapWizard()
{
QPointer<MapWizard> mapWizard = new MapWizard();
QSettings settings;
settings.beginGroup( "MapWizard" );
mapWizard->setWmsServers( settings.value( "wmsServers" ).toStringList() );
mapWizard->setStaticUrlServers( settings.value( "staticUrlServers" ).toStringList() );
settings.endGroup();
mapWizard->exec();
settings.beginGroup( "MapWizard" );
settings.setValue( "wmsServers", mapWizard->wmsServers() );
settings.setValue( "staticUrlServers", mapWizard->staticUrlServers() );
settings.endGroup();
mapWizard->deleteLater();
}
void MainWindow::showZoomLevel(bool show)
{
if ( show ) {
m_zoomLabel->show();
statusBar()->insertPermanentWidget( 2, m_zoomLabel );
} else {
statusBar()->removeWidget( m_zoomLabel );
}
// update from last modification
m_toggleTileLevelAction->setChecked( show );
}
void MainWindow::changeAngleDisplayUnit( QAction *action )
{
m_configDialog->setAngleUnit((Marble::AngleUnit)action->data().toInt());
}
void MainWindow::fallBackToDefaultTheme()
{
m_controlView->marbleWidget()->setMapThemeId( m_controlView->defaultMapThemeId() );
}
void MainWindow::changeViewSize( QAction* action )
{
if ( action->data().type() == QVariant::Size ) {
if ( m_savedSize.isEmpty() ) {
m_savedSize = m_controlView->size();
}
m_controlView->setFixedSize( action->data().toSize() );
adjustSize();
} else {
m_controlView->setMinimumSize( QSize( 0, 0 ) );
m_controlView->setMaximumSize( QSize( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ) );
m_controlView->resize( m_savedSize );
m_controlView->setMinimumSize( m_savedSize );
adjustSize();
m_controlView->setMinimumSize( QSize( 0, 0 ) );
m_savedSize.setHeight( -1 );
}
}
#include "moc_QtMainWindow.cpp"
diff --git a/src/apps/marble-qt/QtMainWindow.h b/src/apps/marble-qt/QtMainWindow.h
index 4b3604a3a..14797271a 100644
--- a/src/apps/marble-qt/QtMainWindow.h
+++ b/src/apps/marble-qt/QtMainWindow.h
@@ -1,235 +1,235 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2010 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_MAINWINDOW_H
#define MARBLE_MAINWINDOW_H
#include <QMainWindow>
#include <QVariantMap>
#include "ControlView.h"
class QActionGroup;
class QAction;
class QLabel;
class QMenu;
class QProgressBar;
namespace Marble
{
class GeoDataContainer;
class MarbleWidget;
class SunControlWidget;
class TimeControlWidget;
class QtMarbleConfigDialog;
class DownloadRegionDialog;
class MovieCaptureDialog;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(const QString& marbleDataPath = QString(),
const QVariantMap& cmdLineSettings = QVariantMap(),
- QWidget *parent=0);
+ QWidget *parent=nullptr);
~MainWindow() override;
ControlView* marbleControl() {
return m_controlView;
}
MarbleWidget* marbleWidget() {
return m_controlView->marbleWidget();
}
void addGeoDataFile( const QString &fileName );
protected:
void closeEvent( QCloseEvent *event ) override;
private:
void createActions();
void createMenus( const QList<QAction*> &panelActions );
void createStatusBar();
static QString readMarbleDataPath();
void readSettings(const QVariantMap& overrideSettings = QVariantMap());
void writeSettings();
private Q_SLOTS:
void showPosition( const QString& position);
void showDistance( const QString& position);
void showZoom( int );
void showDateTime();
void initObject(const QVariantMap& cmdLineSettings);
void editSettings();
void updateSettings();
void fallBackToDefaultTheme();
void changeRecordingState();
void updateWindowTitle();
// File Menu
void openFile();
void openMapDialog();
void exportMapScreenShot();
void showDownloadRegionDialog();
void printMapScreenShot();
void workOffline( bool );
void showMapWizard();
// Edit Menu
void copyMap();
void copyCoordinates();
void updateMapEditButtonVisibility( const QString &mapTheme );
void showMovieCaptureDialog();
void stopRecording();
// View Menu
void lockPosition( bool );
void createPluginsMenus();
void createPluginMenus();
void showClouds( bool );
void controlSun();
void controlTime();
void showSun( bool );
void reload();
// Settings Menu
void changeViewSize( QAction* );
void showFullScreen( bool );
void showStatusBar( bool );
void setupStatusBar();
void setupDownloadProgressBar();
// Help Menu
void enterWhatsThis();
void aboutMarble();
void handbook();
void openForum();
//Bookmark Menu
void openEditBookmarkDialog();
void setHome();
void createBookmarksListMenu( QMenu *bookmarksListMenu, const GeoDataContainer *container );
void lookAtBookmark( QAction * action );
void manageBookmarks();
void createBookmarkMenu();
void createFolderList( QMenu *bookmarksListMenu, const GeoDataContainer *container );
void showBookmarks( bool show );
// Download region dialog
void downloadRegion();
void showZoomLevel( bool show );
void changeAngleDisplayUnit( QAction *action );
void handleProgress( int, int );
void removeProgressItem();
private:
ControlView *m_controlView;
QSize m_savedSize;
SunControlWidget* m_sunControlDialog;
TimeControlWidget* m_timeControlDialog;
QtMarbleConfigDialog *m_configDialog;
DownloadRegionDialog* m_downloadRegionDialog;
MovieCaptureDialog* m_movieCaptureDialog;
/// Store plugin toolbar pointers so that they can be removed/updated later
QList<QToolBar*> m_pluginToolbars;
/// Store plugin menus so that they can be removed/updated later
QList<QAction*> m_pluginMenus;
QMenu *m_fileMenu;
QMenu *m_viewMenu;
QMenu *m_helpMenu;
QMenu *m_settingsMenu;
QMenu *m_panelMenu;
QMenu *m_viewSizeMenu;
QMenu *m_infoBoxesMenu;
QMenu *m_onlineServicesMenu;
QMenu *m_bookmarkMenu;
// File Menu
QAction *m_openAction;
QAction *m_exportMapAction;
QAction *m_downloadAction;
QAction *m_downloadRegionAction;
QAction *m_printPreviewAction;
QAction *m_printAction;
QAction *m_workOfflineAction;
QAction *m_quitAction;
QAction *m_mapWizardAction;
// Edit Menu
QAction *m_copyMapAction;
QAction *m_copyCoordinatesAction;
QAction *m_osmEditAction;
QAction *m_recordMovieAction;
QAction *m_stopRecordingAction;
// View Menu
QAction *m_showCloudsAction;
QAction *m_controlSunAction;
QAction *m_controlTimeAction;
QAction *m_reloadAction;
// Settings Menu
QAction *m_fullScreenAction;
QAction *m_statusBarAction;
QAction *m_configDialogAction;
QActionGroup *m_viewSizeActsGroup;
// Help Menu
QAction *m_whatsThisAction;
QAction *m_aboutMarbleAction;
QAction *m_aboutQtAction;
QAction *m_lockFloatItemsAction;
QAction *m_handbookAction;
QAction *m_forumAction;
// Status Bar
QString m_position;
QString m_distance;
QString m_zoom;
QString m_clock;
QLabel *m_positionLabel;
QLabel *m_distanceLabel;
QLabel *m_zoomLabel;
QLabel *m_clockLabel;
QProgressBar *m_downloadProgressBar;
QAction *m_toggleTileLevelAction;
QActionGroup *m_angleDisplayUnitActionGroup;
QAction *m_dmsDegreeAction;
QAction *m_decimalDegreeAction;
QAction *m_utmAction;
void updateStatusBar();
//Bookmark Menu
QAction *m_addBookmarkAction;
QAction *m_setHomeAction;
QAction *m_toggleBookmarkDisplayAction;
QAction *m_manageBookmarksAction;
QString m_lastFileOpenPath;
QStringList m_commandlineFilePaths;
};
} // namespace Marble
#endif
diff --git a/src/apps/marble-ui/ControlView.cpp b/src/apps/marble-ui/ControlView.cpp
index 6719933ee..db47b7a58 100644
--- a/src/apps/marble-ui/ControlView.cpp
+++ b/src/apps/marble-ui/ControlView.cpp
@@ -1,982 +1,982 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
#include "ControlView.h"
#include <QCloseEvent>
#include <QLayout>
#include <QPrintDialog>
#include <QPrintPreviewDialog>
#include <QPrinter>
#include <QPainter>
#include <QTextDocument>
#include <QPointer>
#include <QUrl>
#include <QDesktopServices>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QProcess>
#include <QTimer>
#include <QFileInfo>
#include <QMessageBox>
#include <QMainWindow>
#include <QDockWidget>
#include <QShortcut>
#include <QToolBar>
#include <QMimeData>
#include <QPixmap>
#ifdef MARBLE_DBUS
#include <QDBusConnection>
#include "MarbleDBusInterface.h"
#endif
#include "GeoDataLatLonAltBox.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "GeoUriParser.h"
#include "MarbleWidget.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "MarbleMap.h"
#include "MapThemeManager.h"
#include "PrintOptionsWidget.h"
#include "ViewportParams.h"
#include "ViewParams.h"
#include "routing/Route.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingModel.h"
#include "routing/RouteRequest.h"
#include "routing/RoutingWidget.h"
#include "ExternalEditorDialog.h"
#include "CurrentLocationWidget.h"
#include "SearchWidget.h"
#include "TourWidget.h"
#include "MapViewWidget.h"
#include "FileViewWidget.h"
#include "LegendWidget.h"
#include "BookmarkManager.h"
#include "cloudsync/CloudSyncManager.h"
#include "cloudsync/BookmarkSyncManager.h"
#include "cloudsync/RouteSyncManager.h"
#include "cloudsync/ConflictDialog.h"
#include "cloudsync/MergeItem.h"
#include "RenderPlugin.h"
namespace Marble
{
ControlView::ControlView( QWidget *parent )
: QWidget( parent ),
m_mapThemeManager( new MapThemeManager( this ) ),
- m_searchDock( 0 ),
- m_locationWidget( 0 ),
- m_conflictDialog( 0 ),
- m_togglePanelVisibilityAction( 0 ),
+ m_searchDock( nullptr ),
+ m_locationWidget( nullptr ),
+ m_conflictDialog( nullptr ),
+ m_togglePanelVisibilityAction( nullptr ),
m_isPanelVisible( true ),
- m_tourWidget( 0 ),
- m_annotationDock( 0 ),
- m_annotationPlugin( 0 )
+ m_tourWidget( nullptr ),
+ m_annotationDock( nullptr ),
+ m_annotationPlugin( nullptr )
{
setWindowTitle( tr( "Marble - Virtual Globe" ) );
resize( 680, 640 );
m_marbleWidget = new MarbleWidget( this );
m_marbleWidget->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding ) );
#ifdef MARBLE_DBUS
new MarbleDBusInterface( m_marbleWidget );
QDBusConnection::sessionBus().registerObject( "/Marble", m_marbleWidget );
if (!QDBusConnection::sessionBus().registerService( "org.kde.marble" )) {
QString const urlWithPid = QString("org.kde.marble-%1").arg( QCoreApplication::applicationPid() );
if ( !QDBusConnection::sessionBus().registerService( urlWithPid ) ) {
mDebug() << "Failed to register service org.kde.marble and " << urlWithPid << " with the DBus session bus.";
}
}
#endif
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget( m_marbleWidget );
layout->setMargin( 0 );
setLayout( layout );
m_cloudSyncManager = new CloudSyncManager( this );
m_cloudSyncManager->routeSyncManager()->setRoutingManager( m_marbleWidget->model()->routingManager() );
BookmarkSyncManager* bookmarkSyncManager = m_cloudSyncManager->bookmarkSyncManager();
bookmarkSyncManager->setBookmarkManager( m_marbleWidget->model()->bookmarkManager() );
m_conflictDialog = new ConflictDialog( m_marbleWidget );
connect( bookmarkSyncManager, SIGNAL(mergeConflict(MergeItem*)), this, SLOT(showConflictDialog(MergeItem*)) );
connect( bookmarkSyncManager, SIGNAL(syncComplete()), m_conflictDialog, SLOT(stopAutoResolve()) );
connect( m_conflictDialog, SIGNAL(resolveConflict(MergeItem*)), bookmarkSyncManager, SLOT(resolveConflict(MergeItem*)) );
setAcceptDrops(true);
}
ControlView::~ControlView()
{
// nothing to do
}
QString ControlView::applicationVersion()
{
return "2.2.20 (2.3 development version)";
}
MapThemeManager *ControlView::mapThemeManager()
{
return m_mapThemeManager;
}
void ControlView::zoomIn()
{
m_marbleWidget->zoomIn();
}
void ControlView::zoomOut()
{
m_marbleWidget->zoomOut();
}
void ControlView::moveLeft()
{
m_marbleWidget->moveLeft();
}
void ControlView::moveRight()
{
m_marbleWidget->moveRight();
}
void ControlView::moveUp()
{
m_marbleWidget->moveUp();
}
void ControlView::moveDown()
{
m_marbleWidget->moveDown();
}
QString ControlView::defaultMapThemeId() const
{
QStringList fallBackThemes;
fallBackThemes << "earth/srtm/srtm.dgml";
fallBackThemes << "earth/bluemarble/bluemarble.dgml";
fallBackThemes << "earth/openstreetmap/openstreetmap.dgml";
const QStringList installedThemes = m_mapThemeManager->mapThemeIds();
for(const QString &fallback: fallBackThemes) {
if (installedThemes.contains(fallback)) {
return fallback;
}
}
if (installedThemes.size()) {
return installedThemes.first();
}
return QString();
}
void ControlView::printMapScreenShot( const QPointer<QPrintDialog>& printDialog)
{
#ifndef QT_NO_PRINTER
PrintOptionsWidget* printOptions = new PrintOptionsWidget( this );
bool const mapCoversViewport = m_marbleWidget->viewport()->mapCoversViewport();
printOptions->setBackgroundControlsEnabled( !mapCoversViewport );
- bool hasLegend = m_marbleWidget->model()->legend() != 0;
+ bool hasLegend = m_marbleWidget->model()->legend() != nullptr;
printOptions->setLegendControlsEnabled( hasLegend );
bool hasRoute = marbleWidget()->model()->routingManager()->routingModel()->rowCount() > 0;
printOptions->setPrintRouteSummary( hasRoute );
printOptions->setPrintDrivingInstructions( hasRoute );
printOptions->setPrintDrivingInstructionsAdvice( hasRoute );
printOptions->setRouteControlsEnabled( hasRoute );
printDialog->setOptionTabs( QList<QWidget*>() << printOptions );
if ( printDialog->exec() == QDialog::Accepted ) {
QTextDocument document;
QString text = "<html><head><title>Marble Printout</title></head><body>";
QPalette const originalPalette = m_marbleWidget->palette();
bool const wasBackgroundVisible = m_marbleWidget->showBackground();
bool const hideBackground = !mapCoversViewport && !printOptions->printBackground();
if ( hideBackground ) {
// Temporarily remove the black background and layers painting on it
m_marbleWidget->setShowBackground( false );
m_marbleWidget->setPalette( QPalette ( Qt::white ) );
m_marbleWidget->update();
}
if ( printOptions->printMap() ) {
printMap( document, text, printDialog->printer() );
}
if ( printOptions->printLegend() ) {
printLegend( document, text );
}
if ( printOptions->printRouteSummary() ) {
printRouteSummary( document, text );
}
if ( printOptions->printDrivingInstructions() ) {
printDrivingInstructions( document, text );
}
if ( printOptions->printDrivingInstructionsAdvice() ) {
printDrivingInstructionsAdvice( document, text );
}
text += QLatin1String("</body></html>");
document.setHtml( text );
document.print( printDialog->printer() );
if ( hideBackground ) {
m_marbleWidget->setShowBackground( wasBackgroundVisible );
m_marbleWidget->setPalette( originalPalette );
m_marbleWidget->update();
}
}
#endif
}
bool ControlView::openGeoUri( const QString& geoUriString )
{
GeoUriParser uriParser( geoUriString );
const bool success = uriParser.parse();
if ( success ) {
if ( uriParser.planet().id() != marbleModel()->planet()->id() ) {
MapThemeManager *manager = mapThemeManager();
for( const QString& planetName: manager->mapThemeIds()) {
if ( planetName.startsWith(uriParser.planet().id(), Qt::CaseInsensitive)) {
m_marbleWidget->setMapThemeId(planetName);
break;
}
}
}
m_marbleWidget->centerOn( uriParser.coordinates() );
if ( uriParser.coordinates().altitude() > 0.0 )
{
m_marbleWidget->setDistance( uriParser.coordinates().altitude() * METER2KM );
}
}
return success;
}
QActionGroup *ControlView::createViewSizeActionGroup( QObject* parent )
{
QActionGroup* actionGroup = new QActionGroup( parent );
QAction *defaultAction = new QAction( tr( "Default (Resizable)" ), parent );
defaultAction->setCheckable( true );
defaultAction->setChecked( true );
actionGroup->addAction(defaultAction);
QAction *separator = new QAction( parent );
separator->setSeparator( true );
actionGroup->addAction(separator);
addViewSizeAction( actionGroup, tr("NTSC (%1x%2)"), 720, 486 );
addViewSizeAction( actionGroup, tr("PAL (%1x%2)"), 720, 576 );
addViewSizeAction( actionGroup, tr("NTSC 16:9 (%1x%2)"), 864, 486 );
addViewSizeAction( actionGroup, tr("PAL 16:9 (%1x%2)"), 1024, 576 );
// xgettext:no-c-format
addViewSizeAction( actionGroup, tr("DVD (%1x%2p)"), 852, 480 );
// xgettext:no-c-format
addViewSizeAction( actionGroup, tr("HD (%1x%2p)"), 1280, 720 );
// xgettext:no-c-format
addViewSizeAction( actionGroup, tr("Full HD (%1x%2p)"), 1920, 1080 );
addViewSizeAction( actionGroup, tr("Digital Cinema (%1x%2)"), 2048, 1536 );
/** FIXME: Needs testing, worked with errors.
addViewSizeAction(actionGroup, "4K UHD (%1x%2)", 3840, 2160);
addViewSizeAction(actionGroup, "4K (%1x%2)", 4096, 3072);
*/
return actionGroup;
}
void ControlView::printPixmap( QPrinter * printer, const QPixmap& pixmap )
{
#ifndef QT_NO_PRINTER
QSize printSize = pixmap.size();
QRect mapPageRect = printer->pageRect();
printSize.scale( printer->pageRect().size(), Qt::KeepAspectRatio );
QPoint printTopLeft( ( mapPageRect.width() - printSize.width() ) / 2 ,
( mapPageRect.height() - printSize.height() ) / 2 );
QRect mapPrintRect( printTopLeft, printSize );
QPainter painter;
if (!painter.begin(printer))
return;
painter.drawPixmap( mapPrintRect, pixmap, pixmap.rect() );
painter.end();
#endif
}
// QPointer is used because of issues described in http://www.kdedevelopers.org/node/3919
void ControlView::printPreview()
{
#ifndef QT_NO_PRINTER
QPrinter printer( QPrinter::HighResolution );
QPointer<QPrintPreviewDialog> preview = new QPrintPreviewDialog( &printer, this );
preview->setWindowFlags ( Qt::Window );
preview->resize(640, 480);
connect( preview, SIGNAL(paintRequested(QPrinter*)), SLOT(paintPrintPreview(QPrinter*)) );
preview->exec();
delete preview;
#endif
}
void ControlView::paintPrintPreview( QPrinter * printer )
{
#ifndef QT_NO_PRINTER
QPixmap mapPixmap = mapScreenShot();
printPixmap( printer, mapPixmap );
#endif
}
void ControlView::printMap( QTextDocument &document, QString &text, QPrinter *printer )
{
#ifndef QT_NO_PRINTER
QPixmap image = mapScreenShot();
if ( m_marbleWidget->viewport()->mapCoversViewport() ) {
// Paint a black frame. Looks better.
QPainter painter(&image);
painter.setPen( Qt::black );
painter.drawRect( 0, 0, image.width() - 2, image.height() - 2 );
}
QString uri = "marble://screenshot.png";
document.addResource( QTextDocument::ImageResource, QUrl( uri ), QVariant( image) );
QString img = "<img src=\"%1\" width=\"%2\" align=\"center\">";
int width = qRound( printer->pageRect( QPrinter::Point ).width() );
text += img.arg( uri ).arg( width );
#endif
}
void ControlView::printLegend( QTextDocument &document, QString &text )
{
#ifndef QT_NO_PRINTER
QTextDocument *legend = m_marbleWidget->model()->legend();
if ( legend ) {
legend->adjustSize();
QSize size = legend->size().toSize();
QSize imageSize = size + QSize( 4, 4 );
QImage image( imageSize, QImage::Format_ARGB32);
QPainter painter( &image );
painter.setRenderHint( QPainter::Antialiasing, true );
painter.drawRoundedRect( QRect( QPoint( 0, 0 ), size ), 5, 5 );
legend->drawContents( &painter );
document.addResource( QTextDocument::ImageResource, QUrl( "marble://legend.png" ), QVariant(image) );
QString img = "<p><img src=\"%1\" align=\"center\"></p>";
text += img.arg( "marble://legend.png" );
}
#endif
}
void ControlView::printRouteSummary( QTextDocument &document, QString &text)
{
#ifndef QT_NO_PRINTER
RoutingModel* routingModel = m_marbleWidget->model()->routingManager()->routingModel();
if ( !routingModel ) {
return;
}
RouteRequest* routeRequest = m_marbleWidget->model()->routingManager()->routeRequest();
if ( routeRequest ) {
QString summary = "<h3>Route to %1: %2 %3</h3>";
QString destination;
if ( routeRequest->size() ) {
destination = routeRequest->name( routeRequest->size()-1 );
}
QString label = "<p>%1 %2</p>";
qreal distance = routingModel->route().distance();
QString unit = distance > 1000 ? "km" : "m";
int precision = distance > 1000 ? 1 : 0;
if ( distance > 1000 ) {
distance /= 1000;
}
summary = summary.arg(destination).arg( distance, 0, 'f', precision ).arg( unit );
text += summary;
text += QLatin1String("<table cellpadding=\"2\">");
QString pixmapTemplate = "marble://viaPoint-%1.png";
for ( int i=0; i<routeRequest->size(); ++i ) {
text += QLatin1String("<tr><td>");
QPixmap pixmap = routeRequest->pixmap(i);
QString pixmapResource = pixmapTemplate.arg( i );
document.addResource(QTextDocument::ImageResource,
QUrl( pixmapResource ), QVariant( pixmap ) );
QString myimg = "<img src=\"%1\">";
text += myimg.arg(pixmapResource) +
QLatin1String("</td><td>");
routeRequest->name(i) +
QLatin1String("</td></tr>");
}
text += QLatin1String("</table>");
}
#endif
}
void ControlView::printDrivingInstructions( QTextDocument &document, QString &text )
{
#ifndef QT_NO_PRINTER
RoutingModel* routingModel = m_marbleWidget->model()->routingManager()->routingModel();
if (!routingModel) {
return;
}
GeoDataLineString total = routingModel->route().path();
text += QLatin1String("<table cellpadding=\"4\">"
"<tr><th>No.</th><th>Distance</th><th>Instruction</th></tr>");
for ( int i=0; i<routingModel->rowCount(); ++i ) {
QModelIndex index = routingModel->index(i, 0);
GeoDataCoordinates coordinates = index.data( RoutingModel::CoordinateRole ).value<GeoDataCoordinates>();
GeoDataLineString accumulator;
for (int k=0; k<total.size(); ++k) {
accumulator << total.at(k);
if (total.at(k) == coordinates)
break;
}
if ( i%2 == 0 ) {
text += QLatin1String("<tr bgcolor=\"lightGray\"><td align=\"right\" valign=\"middle\">");
}
else {
text += QLatin1String("<tr><td align=\"right\" valign=\"middle\">");
}
text += QString::number(i+1) +
QLatin1String("</td><td align=\"right\" valign=\"middle\">");
qreal planetRadius = marbleModel()->planet()->radius();
text += QString::number(accumulator.length(planetRadius) * METER2KM, 'f', 1) +
/** @todo: support localization */
QLatin1String(" km</td><td valign=\"middle\">");
QPixmap instructionIcon = index.data( Qt::DecorationRole ).value<QPixmap>();
if ( !instructionIcon.isNull() ) {
QString uri = QString("marble://turnIcon%1.png").arg(i);
document.addResource( QTextDocument::ImageResource, QUrl( uri ), QVariant( instructionIcon ) );
text += QString("<img src=\"%1\">").arg(uri);
}
text += routingModel->data( index ).toString() +
QLatin1String("</td></tr>");
}
text += QLatin1String("</table>");
#endif
}
void ControlView::printDrivingInstructionsAdvice( QTextDocument &, QString &text )
{
#ifndef QT_NO_PRINTER
text += QLatin1String("<p>") + tr("The Marble development team wishes you a pleasant and safe journey.") + QLatin1String("</p>") +
QLatin1String("<p>") + tr("Caution: Driving instructions may be incomplete or inaccurate.") +
QLatin1Char(' ') + tr("Road construction, weather and other unforeseen variables can result in this suggested route not to be the most expedient or safest route to your destination.") +
QLatin1Char(' ') + tr("Please use common sense while navigating.") + QLatin1String("</p>");
#endif
}
void ControlView::addViewSizeAction( QActionGroup* actionGroup, const QString &nameTemplate, int width, int height )
{
QString const name = nameTemplate.arg( width ).arg( height );
QAction *action = new QAction( name, actionGroup->parent() );
action->setCheckable( true );
action->setData( QSize( width, height ) );
actionGroup->addAction( action );
}
void ControlView::launchExternalMapEditor()
{
QString editor = m_externalEditor;
if ( editor.isEmpty() ) {
QPointer<ExternalEditorDialog> dialog = new ExternalEditorDialog( this );
if( dialog->exec() == QDialog::Accepted ) {
editor = dialog->externalEditor();
if ( dialog->saveDefault() ) {
m_externalEditor = editor;
}
} else {
return;
}
}
if (editor == QLatin1String("josm")) {
// JOSM, the java based editor
synchronizeWithExternalMapEditor( editor, "--download=%1,%4,%3,%2" );
}
else if (editor == QLatin1String("merkaartor")) {
// Merkaartor, a Qt based editor
QString argument = "osm://download/load_and_zoom?top=%1&right=%2&bottom=%3&left=%4";
synchronizeWithExternalMapEditor( editor, argument );
}
else {
// Potlatch, the flash based editor running at the osm main website
QString url = "http://www.openstreetmap.org/edit?lat=%1&lon=%2&zoom=%3";
qreal lat = m_marbleWidget->centerLatitude();
qreal lon = m_marbleWidget->centerLongitude();
int zoom = m_marbleWidget->tileZoomLevel();
url = url.arg( lat, 0, 'f', 8 ).arg( lon, 0, 'f', 8 ).arg( zoom );
QDesktopServices::openUrl( QUrl(url) );
}
}
void ControlView::synchronizeWithExternalMapEditor( const QString &application, const QString &argument )
{
QTimer watchdog; // terminates network connection after a short timeout
watchdog.setSingleShot( true );
QEventLoop localEventLoop;
connect( &watchdog, SIGNAL(timeout()), &localEventLoop, SLOT(quit()) );
QNetworkAccessManager manager;
connect( &manager, SIGNAL(finished(QNetworkReply*)), &localEventLoop, SLOT(quit()) );
// Wait at most two seconds for the local server to respond
QNetworkReply *reply = manager.get( QNetworkRequest( QUrl( "http://localhost:8111/") ) );
watchdog.start( 2000 );
localEventLoop.exec();
GeoDataLatLonAltBox box = m_marbleWidget->viewport()->viewLatLonAltBox();
qreal north = box.north( GeoDataCoordinates::Degree );
qreal east = box.east( GeoDataCoordinates::Degree );
qreal south = box.south( GeoDataCoordinates::Degree );
qreal west = box.west( GeoDataCoordinates::Degree );
if( watchdog.isActive() && reply->bytesAvailable() > 0 ) {
// The local server is alive. Tell it to download the current region
watchdog.stop();
QString serverUrl = "http://localhost:8111/load_and_zoom?top=%1&right=%2&bottom=%3&left=%4";
serverUrl = serverUrl.arg( north, 0, 'f', 8 ).arg( east, 0, 'f', 8 );
serverUrl = serverUrl.arg( south, 0, 'f', 8 ).arg( west, 0, 'f', 8 );
mDebug() << "Connecting to local server URL " << serverUrl;
manager.get( QNetworkRequest( QUrl( serverUrl ) ) );
// Give it five seconds to process the request
watchdog.start( 5000 );
localEventLoop.exec();
} else {
// The local server is not alive. Start the application
QString applicationArgument = argument.arg( south, 0, 'f', 8 ).arg( east, 0, 'f', 8 );
applicationArgument = applicationArgument.arg( north, 0, 'f', 8 ).arg( west, 0, 'f', 8 );
mDebug() << "No local server found. Launching " << application << " with argument " << applicationArgument;
if ( !QProcess::startDetached( application, QStringList() << applicationArgument ) ) {
QString text = tr( "Unable to start the external editor. Check that %1 is installed or choose a different external editor in the settings dialog." );
text = text.arg( application );
QMessageBox::warning( this, tr( "Cannot start external editor" ), text );
}
}
}
void ControlView::setExternalMapEditor( const QString &editor )
{
m_externalEditor = editor;
}
QList<QAction*> ControlView::setupDockWidgets( QMainWindow *mainWindow )
{
Q_ASSERT( !m_searchDock && "Please create dock widgets just once" );
mainWindow->setTabPosition( Qt::LeftDockWidgetArea, QTabWidget::North );
mainWindow->setTabPosition( Qt::RightDockWidgetArea, QTabWidget::North );
QDockWidget* legendDock = new QDockWidget( tr( "Legend" ), this );
legendDock->setObjectName( "legendDock" );
legendDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
LegendWidget* legendWidget = new LegendWidget( this );
legendWidget->setMarbleModel( m_marbleWidget->model() );
connect( legendWidget, SIGNAL(tourLinkClicked(QString)),
this, SLOT(handleTourLinkClicked(QString)) );
connect( legendWidget, SIGNAL(propertyValueChanged(QString,bool)),
marbleWidget(), SLOT(setPropertyValue(QString,bool)) );
legendDock->setWidget( legendWidget );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( smallScreen ) {
// Show only the legend as a dock widget on small screen, the others are dialogs
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, legendDock );
return QList<QAction*>() << legendDock->toggleViewAction();
}
QDockWidget *routingDock = new QDockWidget( tr( "Routing" ), mainWindow );
routingDock->setObjectName( "routingDock" );
routingDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
RoutingWidget* routingWidget = new RoutingWidget( marbleWidget(), mainWindow );
routingWidget->setRouteSyncManager( cloudSyncManager()->routeSyncManager() );
routingDock->setWidget( routingWidget );
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, routingDock );
QDockWidget *locationDock = new QDockWidget( tr( "Location" ), this );
locationDock->setObjectName( "locationDock" );
locationDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
m_locationWidget = new CurrentLocationWidget( this );
m_locationWidget->setMarbleWidget( marbleWidget() );
locationDock->setWidget( m_locationWidget );
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, locationDock );
m_searchDock = new QDockWidget( tr( "Search" ), this );
m_searchDock->setObjectName( "searchDock" );
m_searchDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
SearchWidget* searchWidget = new SearchWidget( this );
searchWidget->setMarbleWidget( marbleWidget() );
m_searchDock->setWidget( searchWidget );
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, m_searchDock );
mainWindow->tabifyDockWidget( m_searchDock, routingDock );
mainWindow->tabifyDockWidget( routingDock, locationDock );
m_searchDock->raise();
QKeySequence searchSequence( Qt::CTRL + Qt::Key_F );
searchWidget->setToolTip( tr( "Search for cities, addresses, points of interest and more (%1)" ).arg( searchSequence.toString() ) );
QShortcut* searchShortcut = new QShortcut( mainWindow );
connect( searchShortcut, SIGNAL(activated()), this, SLOT(showSearch()) );
QDockWidget *mapViewDock = new QDockWidget( tr( "Map View" ), this );
mapViewDock->setObjectName( "mapViewDock" );
mapViewDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
MapViewWidget* mapViewWidget = new MapViewWidget( this );
mapViewWidget->setMarbleWidget( marbleWidget(), m_mapThemeManager );
connect( mapViewWidget, SIGNAL(showMapWizard()), this, SIGNAL(showMapWizard()) );
connect( mapViewWidget, SIGNAL(showUploadDialog()), this, SIGNAL(showUploadDialog()) );
connect( mapViewWidget, SIGNAL(mapThemeDeleted()), this, SIGNAL(mapThemeDeleted()) );
mapViewDock->setWidget( mapViewWidget );
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, mapViewDock );
QDockWidget *fileViewDock = new QDockWidget( tr( "Files" ), this );
fileViewDock->setObjectName( "fileViewDock" );
fileViewDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
FileViewWidget* fileViewWidget = new FileViewWidget( this );
fileViewWidget->setMarbleWidget( marbleWidget() );
fileViewDock->setWidget( fileViewWidget );
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, fileViewDock );
fileViewDock->hide();
QDockWidget *tourDock = new QDockWidget( tr( "Tour" ), this );
tourDock->setObjectName( "tourDock" );
tourDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
m_tourWidget = new TourWidget( this );
m_tourWidget->setMarbleWidget( marbleWidget() );
tourDock->setWidget( m_tourWidget );
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, tourDock );
tourDock->hide();
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, legendDock );
mainWindow->tabifyDockWidget( mapViewDock, legendDock );
mapViewDock->raise();
m_annotationDock = new QDockWidget( QObject::tr( "Edit Maps" ) );
m_annotationDock->setObjectName( "annotateDock" );
m_annotationDock->hide();
m_annotationDock->toggleViewAction()->setVisible( false );
QList<RenderPlugin *> renderPluginList = marbleWidget()->renderPlugins();
QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
for (; i != end; ++i ) {
if ((*i)->nameId() == QLatin1String("annotation")) {
m_annotationPlugin = *i;
QObject::connect(m_annotationPlugin, SIGNAL(enabledChanged(bool)),
this, SLOT(updateAnnotationDockVisibility()));
QObject::connect(m_annotationPlugin, SIGNAL(visibilityChanged(bool,QString)),
this, SLOT(updateAnnotationDockVisibility()));
QObject::connect(m_annotationPlugin, SIGNAL(actionGroupsChanged()),
this, SLOT(updateAnnotationDock()));
updateAnnotationDock();
updateAnnotationDockVisibility();
mainWindow->addDockWidget( Qt::LeftDockWidgetArea, m_annotationDock );
}
}
mainWindow->tabifyDockWidget( tourDock, m_annotationDock );
mainWindow->tabifyDockWidget( m_annotationDock, fileViewDock );
QList<QAction*> panelActions;
panelActions << routingDock->toggleViewAction();
panelActions << locationDock->toggleViewAction();
panelActions << m_searchDock->toggleViewAction();
panelActions << mapViewDock->toggleViewAction();
panelActions << fileViewDock->toggleViewAction();
panelActions << m_annotationDock->toggleViewAction();
panelActions << legendDock->toggleViewAction();
panelActions << tourDock->toggleViewAction();
// Local list of panel view toggle actions
m_panelActions << routingDock->toggleViewAction();
m_panelActions << locationDock->toggleViewAction();
m_panelActions << m_searchDock->toggleViewAction();
m_panelActions << mapViewDock->toggleViewAction();
m_panelActions << fileViewDock->toggleViewAction();
m_panelActions << m_annotationDock->toggleViewAction();
m_panelActions << legendDock->toggleViewAction();
m_panelActions << tourDock->toggleViewAction();
for( QAction* action: m_panelActions ) {
m_panelVisibility << action->isVisible();
}
// Create Settings->Panels Menu
// Toggle All Panels action
m_togglePanelVisibilityAction = new QAction( tr("Hide &All Panels"), this);
m_togglePanelVisibilityAction->setShortcut( Qt::Key_F9 );
m_togglePanelVisibilityAction->setStatusTip(tr("Show or hide all panels."));
connect(m_togglePanelVisibilityAction, SIGNAL(triggered()), this, SLOT(togglePanelVisibility()));
// Include a Separator in the List
QAction *panelSeparatorAct = new QAction( this );
panelSeparatorAct->setSeparator( true );
// Return a list of panel view actions for Marble Menu including show/hide all
QList<QAction*> panelMenuActions;
panelMenuActions << m_togglePanelVisibilityAction;
panelMenuActions << panelSeparatorAct;
for( QAction* action: m_panelActions ) {
panelMenuActions << action;
}
return panelMenuActions;
}
CurrentLocationWidget *ControlView::currentLocationWidget()
{
return m_locationWidget;
}
void ControlView::setWorkOffline( bool offline )
{
marbleWidget()->model()->setWorkOffline( offline );
if ( !offline ) {
marbleWidget()->clearVolatileTileCache();
}
}
CloudSyncManager *ControlView::cloudSyncManager()
{
return m_cloudSyncManager;
}
QString ControlView::externalMapEditor() const
{
return m_externalEditor;
}
void ControlView::addGeoDataFile( const QString &filename )
{
QFileInfo const file( filename );
if ( file.exists() ) {
m_marbleWidget->model()->addGeoDataFile( file.absoluteFilePath() );
} else {
qWarning() << "File" << filename << "does not exist, cannot open it.";
}
}
void ControlView::showSearch()
{
if ( !m_searchDock ) {
return;
}
m_searchDock->show();
m_searchDock->raise();
m_searchDock->widget()->setFocus();
}
void ControlView::showConflictDialog( MergeItem *item )
{
Q_ASSERT( m_conflictDialog );
m_conflictDialog->setMergeItem( item );
m_conflictDialog->open();
}
void ControlView::updateAnnotationDockVisibility()
{
- if( m_annotationPlugin != 0 && m_annotationDock != 0 ) {
+ if( m_annotationPlugin != nullptr && m_annotationDock != nullptr ) {
if( m_annotationPlugin->visible() && m_annotationPlugin->enabled() ) {
m_annotationDock->toggleViewAction()->setVisible( true );
} else {
m_annotationDock->setVisible( false );
m_annotationDock->toggleViewAction()->setVisible( false );
}
}
}
void ControlView::updateAnnotationDock()
{
const QList<QActionGroup*> *tmp_actionGroups = m_annotationPlugin->actionGroups();
QWidget *widget = new QWidget( m_annotationDock );
QVBoxLayout *layout = new QVBoxLayout;
QToolBar *firstToolbar = new QToolBar( widget );
QToolBar *secondToolbar = new QToolBar( widget );
QSpacerItem *spacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
if( !tmp_actionGroups->isEmpty() ) {
bool firstToolbarFilled = false;
for( QAction *action: tmp_actionGroups->first()->actions() ) {
if (action->objectName() == QLatin1String("toolbarSeparator")) {
firstToolbarFilled = true;
} else {
if( !firstToolbarFilled ) {
firstToolbar->addAction( action );
} else {
secondToolbar->addAction( action );
}
}
}
}
layout->addWidget( firstToolbar );
layout->addWidget( secondToolbar );
layout->addSpacerItem( spacer );
widget->setLayout( layout );
m_annotationDock->setWidget( widget );
}
void ControlView::togglePanelVisibility()
{
Q_ASSERT( m_panelVisibility.size() == m_panelActions.size() );
if ( m_isPanelVisible ) {
for( int p=0; p<m_panelActions.size(); ++p ) {
// Save state of individual dock visibility
m_panelVisibility[p] = m_panelActions.at(p)->isChecked();
// hide panel if it is showing
if ( m_panelActions.at(p)->isChecked() ) {
m_panelActions.at(p)->activate( QAction::Trigger );
}
}
// Change Menu Item Text
m_togglePanelVisibilityAction->setText( tr("Show &All Panels") );
m_isPanelVisible = false;
} else {
for( int p=0; p<m_panelActions.size(); ++p ) {
// show panel if it was showing before all panels were hidden
if ( m_panelVisibility.at(p) && !m_panelActions.at(p)->isChecked() ) {
m_panelActions.at(p)->activate( QAction::Trigger );
}
}
// Change Menu Item Text
m_togglePanelVisibilityAction->setText( tr("Hide &All Panels") );
m_isPanelVisible = true;
}
}
void ControlView::handleTourLinkClicked(const QString& path)
{
QString tourPath = MarbleDirs::path( path );
if ( !tourPath.isEmpty() ) {
openTour( tourPath );
}
}
void ControlView::openTour( const QString &filename )
{
if ( m_tourWidget->openTour( filename ) ) {
m_tourWidget->startPlaying();
}
}
void ControlView::closeEvent( QCloseEvent *event )
{
QCloseEvent newEvent;
QCoreApplication::sendEvent( m_tourWidget, &newEvent );
if ( newEvent.isAccepted() ) {
event->accept();
} else {
event->ignore();
}
}
void ControlView::dragEnterEvent(QDragEnterEvent *event)
{
bool success = false;
const QMimeData *mimeData = event->mimeData();
GeoUriParser uriParser;
// prefer urls
if (mimeData->hasUrls()) {
// be generous and take the first usable url
for(const QUrl& url: mimeData->urls()) {
uriParser.setGeoUri(url.url());
success = uriParser.parse();
if (success) {
break;
}
}
}
// fall back to own string parsing
if (!success && mimeData->hasText()) {
const QString text = mimeData->text();
// first try human readable coordinates
GeoDataCoordinates::fromString(text, success);
// next geo uri
if (!success) {
uriParser.setGeoUri(text);
success = uriParser.parse();
}
}
if (success) {
event->acceptProposedAction();
}
}
void ControlView::dropEvent(QDropEvent *event)
{
bool success = false;
const QMimeData *mimeData = event->mimeData();
// prefer urls
if (mimeData->hasUrls()) {
// be generous and take the first usable url
for(const QUrl& url: mimeData->urls()) {
success = openGeoUri(url.url());
if (success) {
break;
}
}
}
// fall back to own string parsing
if (!success && mimeData->hasText()) {
const QString text = mimeData->text();
// first try human readable coordinates
const GeoDataCoordinates coordinates = GeoDataCoordinates::fromString(text, success);
if (success) {
const qreal longitude = coordinates.longitude(GeoDataCoordinates::Degree);
const qreal latitude = coordinates.latitude(GeoDataCoordinates::Degree);
m_marbleWidget->centerOn(longitude, latitude);
} else {
success = openGeoUri(text);
}
}
if (success) {
event->acceptProposedAction();
}
}
}
#include "moc_ControlView.cpp"
diff --git a/src/apps/marble-ui/ControlView.h b/src/apps/marble-ui/ControlView.h
index 464e11e6f..32502905a 100644
--- a/src/apps/marble-ui/ControlView.h
+++ b/src/apps/marble-ui/ControlView.h
@@ -1,188 +1,188 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
//
// Testapplication with controls
//
#ifndef MARBLE_CONTROLVIEW_H
#define MARBLE_CONTROLVIEW_H
#include <QWidget>
#include <QPointer>
#include "MarbleWidget.h"
class QPrintDialog;
class QTextDocument;
class QMainWindow;
class QDockWidget;
class QPrinter;
class QActionGroup;
class QPixmap;
namespace Marble
{
class TourWidget;
class CurrentLocationWidget;
class MapThemeManager;
class ConflictDialog;
class MarbleModel;
class MergeItem;
class CloudSyncManager;
class ControlView : public QWidget
{
Q_OBJECT
public:
- explicit ControlView( QWidget * = 0 );
+ explicit ControlView( QWidget * = nullptr );
~ControlView() override;
/**
* Returns the version of the Marble applications (which differs from
* the Marble library version).
*/
static QString applicationVersion();
MarbleWidget *marbleWidget() { return m_marbleWidget; }
MarbleModel *marbleModel() { return m_marbleWidget->model(); }
MapThemeManager *mapThemeManager();
void zoomIn();
void zoomOut();
void moveLeft();
void moveRight();
void moveUp();
void moveDown();
void addGeoDataFile( const QString &filename );
QPixmap mapScreenShot() { return m_marbleWidget->mapScreenShot(); }
/**
* Returns a default map theme: earth/srtm/srtm.dgml if installed,
* any other theme id if earth/srtm/srtm.dgml is not installed,
* or an empty string if no themes are installed at all
*/
QString defaultMapThemeId() const;
/**
* Returns the editor used to launch a map editor application
*/
QString externalMapEditor() const;
/**
* Change the editor to launch via @see launchExternalMapEditor. Recognized values
* are 'potlatch', 'josm', 'merkaartor'
*/
void setExternalMapEditor( const QString &editor );
QList<QAction*> setupDockWidgets( QMainWindow* mainWindow );
CurrentLocationWidget* currentLocationWidget();
void setWorkOffline( bool workOffline );
CloudSyncManager* cloudSyncManager();
/**
* Opens the passed Geo URI
* @return true if uri could be parsed and opened
* @see Marble::GeoUriParser for details
*/
bool openGeoUri( const QString& geoUriString );
static QActionGroup* createViewSizeActionGroup( QObject* parent );
public Q_SLOTS:
void printMapScreenShot( const QPointer<QPrintDialog>& dialog );
void printPreview();
void paintPrintPreview( QPrinter * printer );
/**
* Start the configured external map editor (or update it if it is already running)
*/
void launchExternalMapEditor();
/**
* Toggles all of the docking panels on or off
*/
void togglePanelVisibility();
void handleTourLinkClicked( const QString &path );
void openTour( const QString &filename );
Q_SIGNALS:
void showMapWizard();
void showUploadDialog();
void mapThemeDeleted();
protected:
void closeEvent( QCloseEvent *event ) override;
/**
* @brief Reimplementation of the dragEnterEvent() function in QWidget.
*/
void dragEnterEvent(QDragEnterEvent *event) override;
/**
* @brief Reimplementation of the dropEvent() function in QWidget.
*/
void dropEvent(QDropEvent *event) override;
private Q_SLOTS:
void showSearch();
// Bookmark sync slots
void showConflictDialog( MergeItem *item );
void updateAnnotationDockVisibility();
void updateAnnotationDock();
private:
/**
* Try to reach an external application server at localhost:8111. If none is running,
* start the given application
* @param application Executable to start when no server is running
* @param argument Argument to set the download region for the external application.
* Use placeholders %1-%4 for the borders
*/
void synchronizeWithExternalMapEditor( const QString &application, const QString &argument );
static void printPixmap( QPrinter * printer, const QPixmap& pixmap );
void printMap( QTextDocument &document, QString &text, QPrinter *printer );
void printLegend( QTextDocument &document, QString &text );
void printRouteSummary( QTextDocument &document, QString &text );
void printDrivingInstructions( QTextDocument &document, QString &text );
static void printDrivingInstructionsAdvice( QTextDocument &document, QString &text );
static void addViewSizeAction( QActionGroup* actionGroup, const QString &nameTemplate, int width, int height );
MapThemeManager *const m_mapThemeManager;
MarbleWidget *m_marbleWidget;
QString m_externalEditor;
QDockWidget *m_searchDock;
CurrentLocationWidget* m_locationWidget;
ConflictDialog *m_conflictDialog;
CloudSyncManager *m_cloudSyncManager;
QAction *m_togglePanelVisibilityAction;
QList<QAction*> m_panelActions;
QList<bool> m_panelVisibility;
bool m_isPanelVisible;
TourWidget *m_tourWidget;
QDockWidget *m_annotationDock;
RenderPlugin *m_annotationPlugin;
};
}
#endif
diff --git a/src/lib/marble/AbstractDataPlugin.cpp b/src/lib/marble/AbstractDataPlugin.cpp
index b7701190d..bc28cedd6 100644
--- a/src/lib/marble/AbstractDataPlugin.cpp
+++ b/src/lib/marble/AbstractDataPlugin.cpp
@@ -1,188 +1,188 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "AbstractDataPlugin.h"
// Marble
#include "AbstractDataPluginModel.h"
#include "AbstractDataPluginItem.h"
#include "GeoPainter.h"
#include "GeoSceneLayer.h"
#include "MarbleModel.h"
#include "ViewportParams.h"
#include "MarbleDebug.h"
// Qt
#include <QTimer>
#include <QRegion>
namespace Marble
{
class AbstractDataPluginPrivate
{
public:
AbstractDataPluginPrivate()
- : m_model( 0 ),
+ : m_model( nullptr ),
m_numberOfItems( 10 )
{
m_updateTimer.setSingleShot( true );
}
~AbstractDataPluginPrivate() {
delete m_model;
}
AbstractDataPluginModel *m_model;
quint32 m_numberOfItems;
QTimer m_updateTimer;
};
AbstractDataPlugin::AbstractDataPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
d( new AbstractDataPluginPrivate )
{
connect( &d->m_updateTimer, SIGNAL(timeout()), this, SIGNAL(repaintNeeded()) );
}
AbstractDataPlugin::~AbstractDataPlugin()
{
delete d;
}
bool AbstractDataPlugin::isInitialized() const
{
- return model() != 0;
+ return model() != nullptr;
}
QStringList AbstractDataPlugin::backendTypes() const
{
return QStringList( name() );
}
QString AbstractDataPlugin::renderPolicy() const
{
return QString( "ALWAYS" );
}
QStringList AbstractDataPlugin::renderPosition() const
{
return QStringList( "ALWAYS_ON_TOP" );
}
bool AbstractDataPlugin::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos, GeoSceneLayer * layer)
{
Q_UNUSED( renderPos );
Q_UNUSED( layer );
QList<AbstractDataPluginItem*> items = d->m_model->items( viewport, numberOfItems() );
painter->save();
// Paint the most important item at last
for( int i = items.size() - 1; i >= 0; --i ) {
items.at( i )->paintEvent( painter, viewport );
}
painter->restore();
return true;
}
AbstractDataPluginModel *AbstractDataPlugin::model()
{
return d->m_model;
}
const AbstractDataPluginModel *AbstractDataPlugin::model() const
{
return d->m_model;
}
void AbstractDataPlugin::setModel( AbstractDataPluginModel* model )
{
if ( d->m_model ) {
disconnect( d->m_model, SIGNAL(itemsUpdated()), this, SLOT(delayedUpdate()) );
delete d->m_model;
}
d->m_model = model;
connect( d->m_model, SIGNAL(itemsUpdated()), this, SLOT(delayedUpdate()) );
connect( d->m_model, SIGNAL(favoriteItemsChanged(QStringList)), this,
SLOT(favoriteItemsChanged(QStringList)) );
connect( d->m_model, SIGNAL(favoriteItemsOnlyChanged()), this,
SIGNAL(favoriteItemsOnlyChanged()) );
emit favoritesModelChanged();
}
quint32 AbstractDataPlugin::numberOfItems() const
{
return d->m_numberOfItems;
}
void AbstractDataPlugin::setNumberOfItems( quint32 number )
{
bool changed = ( number != d->m_numberOfItems );
d->m_numberOfItems = number;
if ( changed )
emit changedNumberOfItems( number );
}
QList<AbstractDataPluginItem *> AbstractDataPlugin::whichItemAt( const QPoint& curpos )
{
if ( d->m_model && enabled() && visible()) {
return d->m_model->whichItemAt( curpos );
}
else {
return QList<AbstractDataPluginItem *>();
}
}
RenderPlugin::RenderType AbstractDataPlugin::renderType() const
{
return OnlineRenderType;
}
void AbstractDataPlugin::setFavoriteItemsOnly( bool favoriteOnly )
{
if ( d->m_model && d->m_model->isFavoriteItemsOnly() != favoriteOnly ) {
d->m_model->setFavoriteItemsOnly( favoriteOnly );
}
}
bool AbstractDataPlugin::isFavoriteItemsOnly() const
{
return d->m_model && d->m_model->isFavoriteItemsOnly();
}
QObject *AbstractDataPlugin::favoritesModel()
{
- return d->m_model ? d->m_model->favoritesModel() : 0;
+ return d->m_model ? d->m_model->favoritesModel() : nullptr;
}
void AbstractDataPlugin::favoriteItemsChanged( const QStringList& favoriteItems )
{
Q_UNUSED( favoriteItems )
}
void AbstractDataPlugin::delayedUpdate()
{
if ( !d->m_updateTimer.isActive() )
{
d->m_updateTimer.start( 500 );
}
}
} // namespace Marble
#include "moc_AbstractDataPlugin.cpp"
diff --git a/src/lib/marble/AbstractDataPlugin.h b/src/lib/marble/AbstractDataPlugin.h
index 7fb657f3d..113446d23 100644
--- a/src/lib/marble/AbstractDataPlugin.h
+++ b/src/lib/marble/AbstractDataPlugin.h
@@ -1,138 +1,138 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_ABSTRACTDATAPLUGIN_H
#define MARBLE_ABSTRACTDATAPLUGIN_H
// Marble
#include "marble_export.h"
#include "RenderPlugin.h"
namespace Marble
{
class ViewportParams;
class GeoSceneLayer;
class AbstractDataPluginItem;
class AbstractDataPluginModel;
class AbstractDataPluginPrivate;
/**
* @short An abstract class for plugins that show data that has a geo coordinate
*
* This is the abstract class for plugins that show data on Marble map.
* It takes care of painting all items it gets from the corresponding AbstractDataPluginModel
* that has to be set on initialisation.
*
* The user has to set the nameId as well as the number of items to fetch.
* Additionally it should be useful to set standard values via setEnabled (often true)
* and setVisible (often false) in the constructor of a subclass.
**/
class MARBLE_EXPORT AbstractDataPlugin : public RenderPlugin
{
Q_OBJECT
Q_PROPERTY( bool favoriteItemsOnly READ isFavoriteItemsOnly WRITE setFavoriteItemsOnly NOTIFY favoriteItemsOnlyChanged )
/** @todo FIXME Qt Quick segfaults if using the real class here instead of QObject */
Q_PROPERTY( QObject* favoritesModel READ favoritesModel NOTIFY favoritesModelChanged )
Q_PROPERTY( int numberOfItems READ numberOfItems WRITE setNumberOfItems NOTIFY changedNumberOfItems )
public:
explicit AbstractDataPlugin( const MarbleModel *marbleModel );
~AbstractDataPlugin() override;
bool isInitialized() const override;
/**
* @brief Returns the name(s) of the backend that the plugin can render
*/
QStringList backendTypes() const override;
/**
* @brief Return how the plugin settings should be used.
*/
QString renderPolicy() const override;
/**
* @brief Preferred level in the layer stack for the rendering
*/
QStringList renderPosition() const override;
/**
* @brief Renders the content provided by the plugin on the viewport.
* @return @c true Returns whether the rendering has been successful
*/
bool render( GeoPainter *painter, ViewportParams *viewport,
- const QString& renderPos = QLatin1String("NONE"), GeoSceneLayer * layer = 0 ) override;
+ const QString& renderPos = QLatin1String("NONE"), GeoSceneLayer * layer = nullptr ) override;
/**
* @return The model associated with the plugin.
*/
AbstractDataPluginModel *model();
const AbstractDataPluginModel *model() const;
/**
* Set the model of the plugin.
*/
void setModel( AbstractDataPluginModel* model );
/**
* Set the number of items to be shown at the same time.
*/
void setNumberOfItems( quint32 number );
/**
* @return The number of items to be shown at the same time.
*/
quint32 numberOfItems() const;
/**
* This function returns all items at the position @p curpos. Depending on where they have
* been painted the last time.
*
* @return The items at the given position.
*/
QList<AbstractDataPluginItem *> whichItemAt( const QPoint& curpos );
/**
* Function for returning the type of plugin this is for.
* This affects where in the menu tree the action() is placed.
*
* @return: The type of render plugin this is.
*/
RenderType renderType() const override;
/** Convenience method to set the favorite item state on the current model */
void setFavoriteItemsOnly( bool favoriteOnly );
bool isFavoriteItemsOnly() const;
QObject* favoritesModel();
private Q_SLOTS:
virtual void favoriteItemsChanged( const QStringList& favoriteItems );
void delayedUpdate();
Q_SIGNALS:
void changedNumberOfItems( quint32 number );
void favoriteItemsOnlyChanged();
void favoritesModelChanged();
private:
AbstractDataPluginPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/AbstractDataPluginItem.cpp b/src/lib/marble/AbstractDataPluginItem.cpp
index 38c1db968..71d99bffc 100644
--- a/src/lib/marble/AbstractDataPluginItem.cpp
+++ b/src/lib/marble/AbstractDataPluginItem.cpp
@@ -1,151 +1,151 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// self
#include "AbstractDataPluginItem.h"
// Marble
#include "GeoDataCoordinates.h"
#include "ViewportParams.h"
#include "MarbleDebug.h"
// Qt
#include <QAction>
#include <QRect>
#include <QSize>
namespace Marble
{
class AbstractDataPluginItemPrivate
{
public:
QString m_id;
QString m_toolTip;
bool m_favorite;
bool m_sticky;
qreal m_addedAngularResolution;
AbstractDataPluginItemPrivate();
};
AbstractDataPluginItemPrivate::AbstractDataPluginItemPrivate()
: m_favorite( false ),
m_sticky( false ),
m_addedAngularResolution( 0 )
{
// nothing to do
}
AbstractDataPluginItem::AbstractDataPluginItem( QObject *parent )
: QObject( parent ),
BillboardGraphicsItem(),
d( new AbstractDataPluginItemPrivate )
{
// nothing to do
}
AbstractDataPluginItem::~AbstractDataPluginItem()
{
delete d;
}
QString AbstractDataPluginItem::toolTip() const
{
return d->m_toolTip;
}
void AbstractDataPluginItem::setToolTip( const QString& toolTip )
{
d->m_toolTip = toolTip;
}
QString AbstractDataPluginItem::id() const
{
return d->m_id;
}
void AbstractDataPluginItem::setId( const QString& id )
{
d->m_id = id;
}
bool AbstractDataPluginItem::isFavorite() const
{
return d->m_favorite;
}
void AbstractDataPluginItem::setFavorite( bool favorite )
{
if ( isFavorite() != favorite ) {
d->m_favorite = favorite;
emit favoriteChanged( id(), favorite );
}
}
bool AbstractDataPluginItem::isSticky() const
{
return d->m_sticky;
}
void AbstractDataPluginItem::setSticky( bool sticky )
{
if ( d->m_sticky != sticky ) {
d->m_sticky = sticky;
emit stickyChanged();
}
}
void AbstractDataPluginItem::toggleFavorite()
{
setFavorite( !isFavorite() );
}
qreal AbstractDataPluginItem::addedAngularResolution() const
{
return d->m_addedAngularResolution;
}
void AbstractDataPluginItem::setAddedAngularResolution( qreal resolution )
{
d->m_addedAngularResolution = resolution;
}
void AbstractDataPluginItem::setSettings( const QHash<QString, QVariant>& settings )
{
Q_UNUSED( settings )
}
QAction *AbstractDataPluginItem::action()
{
- return 0;
+ return nullptr;
}
void AbstractDataPluginItem::addDownloadedFile( const QString& url, const QString& type )
{
Q_UNUSED( url )
Q_UNUSED( type )
}
QList<QAction*> AbstractDataPluginItem::actions()
{
QList<QAction*> result;
QAction* pluginAction = action();
if ( pluginAction ) {
result << pluginAction;
}
return result;
}
} // Marble namespace
#include "moc_AbstractDataPluginItem.cpp"
diff --git a/src/lib/marble/AbstractDataPluginItem.h b/src/lib/marble/AbstractDataPluginItem.h
index cf16935b7..6fae8eee3 100644
--- a/src/lib/marble/AbstractDataPluginItem.h
+++ b/src/lib/marble/AbstractDataPluginItem.h
@@ -1,103 +1,103 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_ABSTRACTDATAPLUGINITEM_H
#define MARBLE_ABSTRACTDATAPLUGINITEM_H
#include <QObject>
#include <QString>
#include <QHash>
#include "BillboardGraphicsItem.h"
#include "marble_export.h"
class QAction;
namespace Marble
{
class AbstractDataPluginItemPrivate;
class MARBLE_EXPORT AbstractDataPluginItem : public QObject, public BillboardGraphicsItem
{
Q_OBJECT
Q_PROPERTY( QString identifier READ id WRITE setId NOTIFY idChanged )
Q_PROPERTY( bool favorite READ isFavorite WRITE setFavorite NOTIFY favoriteChanged )
Q_PROPERTY( bool sticky READ isSticky WRITE setSticky NOTIFY stickyChanged )
public:
- explicit AbstractDataPluginItem( QObject *parent = 0 );
+ explicit AbstractDataPluginItem( QObject *parent = nullptr );
~AbstractDataPluginItem() override;
/**
* Returns the item's tool tip.
*/
QString toolTip() const;
/**
* Set the tool tip for the item.
*/
void setToolTip( const QString& toolTip );
QString id() const;
void setId( const QString& id );
bool isFavorite() const;
virtual void setFavorite( bool favorite );
bool isSticky() const;
void setSticky( bool sticky );
/**
* @brief Set the settings of the item.
* This is usually called automatically before painting. If you reimplement this it would be
* useful to check for changes before copying.
*/
virtual void setSettings( const QHash<QString, QVariant>& settings );
/**
* Returns the action of this specific item.
*/
virtual QAction *action();
virtual bool initialized() const = 0;
virtual void addDownloadedFile( const QString& url, const QString& type );
virtual bool operator<( const AbstractDataPluginItem *other ) const = 0;
virtual QList<QAction*> actions();
Q_SIGNALS:
void updated();
void idChanged();
void favoriteChanged( const QString& id, bool favorite );
void stickyChanged();
public Q_SLOTS:
void toggleFavorite();
private:
friend class AbstractDataPluginModel;
/**
* Returning the angular resolution of the viewport when the item was added to it the last
* time.
*/
qreal addedAngularResolution() const;
void setAddedAngularResolution( qreal resolution );
AbstractDataPluginItemPrivate * const d;
};
} // Marble namespace
#endif
diff --git a/src/lib/marble/AbstractDataPluginModel.cpp b/src/lib/marble/AbstractDataPluginModel.cpp
index 5450a3290..d048fb1aa 100644
--- a/src/lib/marble/AbstractDataPluginModel.cpp
+++ b/src/lib/marble/AbstractDataPluginModel.cpp
@@ -1,673 +1,673 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "AbstractDataPluginModel.h"
// Qt
#include <QUrl>
#include <QTimer>
#include <QPointF>
#include <QRectF>
#include <QtAlgorithms>
#include <QVariant>
#include <QAbstractListModel>
#include <QMetaProperty>
// Marble
#include "MarbleDebug.h"
#include "AbstractDataPluginItem.h"
#include "CacheStoragePolicy.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLatLonAltBox.h"
#include "HttpDownloadManager.h"
#include "MarbleModel.h"
#include "MarbleDirs.h"
#include "ViewportParams.h"
#include <cmath>
namespace Marble
{
const QString descriptionPrefix( "description_" );
// Time between two tried description file downloads (we decided not to download anything) in ms
const int timeBetweenTriedDownloads = 500;
// Time between two real description file downloads in ms
const int timeBetweenDownloads = 1500;
// The factor describing how much the box has to be changed to download a new description file.
// A higher factor means more downloads.
const qreal boxComparisonFactor = 16.0;
// Separator to separate the id of the item from the file type
const QChar fileIdSeparator = QLatin1Char('_');
class FavoritesModel;
class AbstractDataPluginModelPrivate
{
public:
AbstractDataPluginModelPrivate( const QString& name,
const MarbleModel *marbleModel,
AbstractDataPluginModel * parent );
~AbstractDataPluginModelPrivate();
static QString generateFilename(const QString &id, const QString &type);
QString generateFilepath( const QString& id, const QString& type ) const;
void updateFavoriteItems();
AbstractDataPluginModel *m_parent;
const QString m_name;
const MarbleModel *const m_marbleModel;
GeoDataLatLonAltBox m_lastBox;
GeoDataLatLonAltBox m_downloadedBox;
qint32 m_lastNumber;
qint32 m_downloadedNumber;
QString m_currentPlanetId;
QList<AbstractDataPluginItem*> m_itemSet;
QHash<QString, AbstractDataPluginItem*> m_downloadingItems;
QList<AbstractDataPluginItem*> m_displayedItems;
QTimer m_downloadTimer;
quint32 m_descriptionFileNumber;
QHash<QString, QVariant> m_itemSettings;
QStringList m_favoriteItems;
bool m_favoriteItemsOnly;
CacheStoragePolicy m_storagePolicy;
HttpDownloadManager m_downloadManager;
FavoritesModel* m_favoritesModel;
QMetaObject m_metaObject;
bool m_hasMetaObject;
bool m_needsSorting;
};
class FavoritesModel : public QAbstractListModel
{
public:
AbstractDataPluginModelPrivate* d;
- explicit FavoritesModel( AbstractDataPluginModelPrivate* d, QObject* parent = 0 );
+ explicit FavoritesModel( AbstractDataPluginModelPrivate* d, QObject* parent = nullptr );
int rowCount ( const QModelIndex & parent = QModelIndex() ) const override;
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const override;
void reset();
QHash<int, QByteArray> roleNames() const override;
private:
QHash<int, QByteArray> m_roleNames;
};
AbstractDataPluginModelPrivate::AbstractDataPluginModelPrivate( const QString& name,
const MarbleModel *marbleModel,
AbstractDataPluginModel * parent )
: m_parent( parent ),
m_name( name ),
m_marbleModel( marbleModel ),
m_lastBox(),
m_downloadedBox(),
m_lastNumber( 0 ),
m_downloadedNumber( 0 ),
m_currentPlanetId( marbleModel->planetId() ),
m_downloadTimer( m_parent ),
m_descriptionFileNumber( 0 ),
m_itemSettings(),
m_favoriteItemsOnly( false ),
m_storagePolicy(MarbleDirs::localPath() + QLatin1String("/cache/") + m_name + QLatin1Char('/')),
m_downloadManager( &m_storagePolicy ),
- m_favoritesModel( 0 ),
+ m_favoritesModel( nullptr ),
m_hasMetaObject( false ),
m_needsSorting( false )
{
}
AbstractDataPluginModelPrivate::~AbstractDataPluginModelPrivate() {
QList<AbstractDataPluginItem*>::iterator lIt = m_itemSet.begin();
QList<AbstractDataPluginItem*>::iterator const lItEnd = m_itemSet.end();
for (; lIt != lItEnd; ++lIt ) {
(*lIt)->deleteLater();
}
QHash<QString,AbstractDataPluginItem*>::iterator hIt = m_downloadingItems.begin();
QHash<QString,AbstractDataPluginItem*>::iterator const hItEnd = m_downloadingItems.end();
for (; hIt != hItEnd; ++hIt ) {
(*hIt)->deleteLater();
}
m_storagePolicy.clearCache();
}
void AbstractDataPluginModelPrivate::updateFavoriteItems()
{
if ( m_favoriteItemsOnly ) {
for( const QString &id: m_favoriteItems ) {
if ( !m_parent->findItem( id ) ) {
m_parent->getItem( id );
}
}
}
}
void AbstractDataPluginModel::themeChanged()
{
if ( d->m_currentPlanetId != d->m_marbleModel->planetId() ) {
clear();
d->m_currentPlanetId = d->m_marbleModel->planetId();
}
}
static bool lessThanByPointer( const AbstractDataPluginItem *item1,
const AbstractDataPluginItem *item2 )
{
if( item1 && item2 ) {
// Compare by sticky and favorite status (sticky first, then favorites), last by operator<
bool const sticky1 = item1->isSticky();
bool const favorite1 = item1->isFavorite();
if ( sticky1 != item2->isSticky() ) {
return sticky1;
} else if ( favorite1 != item2->isFavorite() ) {
return favorite1;
} else {
return item1->operator<( item2 );
}
}
else {
return false;
}
}
FavoritesModel::FavoritesModel( AbstractDataPluginModelPrivate *_d, QObject* parent ) :
QAbstractListModel( parent ), d(_d)
{
QHash<int,QByteArray> roles;
int const size = d->m_hasMetaObject ? d->m_metaObject.propertyCount() : 0;
for ( int i=0; i<size; ++i ) {
QMetaProperty property = d->m_metaObject.property( i );
roles[Qt::UserRole+i] = property.name();
}
roles[Qt::DisplayRole] = "display";
roles[Qt::DecorationRole] = "decoration";
m_roleNames = roles;
}
int FavoritesModel::rowCount ( const QModelIndex &parent ) const
{
if ( parent.isValid() ) {
return 0;
}
int count = 0;
for( AbstractDataPluginItem* item: d->m_itemSet ) {
if ( item->initialized() && item->isFavorite() ) {
++count;
}
}
return count;
}
QVariant FavoritesModel::data( const QModelIndex &index, int role ) const
{
int const row = index.row();
if ( row >= 0 && row < rowCount() ) {
int count = 0;
for( AbstractDataPluginItem* item: d->m_itemSet ) {
if ( item->initialized() && item->isFavorite() ) {
if ( count == row ) {
QString const roleName = roleNames().value( role );
return item->property(roleName.toLatin1().constData());
}
++count;
}
}
}
return QVariant();
}
void FavoritesModel::reset()
{
beginResetModel();
endResetModel();
}
QHash<int, QByteArray> FavoritesModel::roleNames() const
{
return m_roleNames;
}
AbstractDataPluginModel::AbstractDataPluginModel( const QString &name, const MarbleModel *marbleModel, QObject *parent )
: QObject( parent ),
d( new AbstractDataPluginModelPrivate( name, marbleModel, this ) )
{
- Q_ASSERT( marbleModel != 0 );
+ Q_ASSERT( marbleModel != nullptr );
// Initializing file and download System
connect( &d->m_downloadManager, SIGNAL(downloadComplete(QString,QString)),
this , SLOT(processFinishedJob(QString,QString)) );
connect( marbleModel, SIGNAL(themeChanged(QString)),
this, SLOT(themeChanged()) );
// We want to download a new description file every timeBetweenDownloads ms
connect( &d->m_downloadTimer, SIGNAL(timeout()),
this, SLOT(handleChangedViewport()),
Qt::QueuedConnection );
d->m_downloadTimer.start( timeBetweenDownloads );
}
AbstractDataPluginModel::~AbstractDataPluginModel()
{
delete d;
}
const MarbleModel *AbstractDataPluginModel::marbleModel() const
{
return d->m_marbleModel;
}
QList<AbstractDataPluginItem*> AbstractDataPluginModel::items( const ViewportParams *viewport,
qint32 number )
{
GeoDataLatLonAltBox currentBox = viewport->viewLatLonAltBox();
QList<AbstractDataPluginItem*> list;
Q_ASSERT( !d->m_displayedItems.contains( 0 ) && "Null item in m_displayedItems. Please report a bug to marble-devel@kde.org" );
Q_ASSERT( !d->m_itemSet.contains( 0 ) && "Null item in m_itemSet. Please report a bug to marble-devel@kde.org" );
QList<AbstractDataPluginItem*> candidates = d->m_displayedItems + d->m_itemSet;
if ( d->m_needsSorting ) {
// Both the candidates list and the list of all items need to be sorted
std::sort( candidates.begin(), candidates.end(), lessThanByPointer );
std::sort( d->m_itemSet.begin(), d->m_itemSet.end(), lessThanByPointer );
d->m_needsSorting = false;
}
QList<AbstractDataPluginItem*>::const_iterator i = candidates.constBegin();
QList<AbstractDataPluginItem*>::const_iterator end = candidates.constEnd();
// Items that are already shown have the highest priority
for (; i != end && list.size() < number; ++i ) {
// Only show items that are initialized
if( !(*i)->initialized() ) {
continue;
}
// Hide non-favorite items if necessary
if( d->m_favoriteItemsOnly && !(*i)->isFavorite() ) {
continue;
}
(*i)->setProjection( viewport );
if( (*i)->positions().isEmpty() ) {
continue;
}
if ( list.contains( *i ) ) {
continue;
}
// If the item was added initially at a nearer position, they don't have priority,
// because we zoomed out since then.
bool const alreadyDisplayed = d->m_displayedItems.contains( *i );
if ( !alreadyDisplayed || (*i)->addedAngularResolution() >= viewport->angularResolution() || (*i)->isSticky() ) {
bool collides = false;
int const length = list.length();
for ( int j=0; !collides && j<length; ++j ) {
for( const QRectF &rect: list[j]->boundingRects() ) {
for( const QRectF &itemRect: (*i)->boundingRects() ) {
if ( rect.intersects( itemRect ) )
collides = true;
}
}
}
if ( !collides ) {
list.append( *i );
(*i)->setSettings( d->m_itemSettings );
// We want to save the angular resolution of the first time the item got added.
if( !alreadyDisplayed ) {
(*i)->setAddedAngularResolution( viewport->angularResolution() );
}
}
}
// TODO: Do we have to cleanup at some point? The list of all items keeps growing
}
d->m_lastBox = currentBox;
d->m_lastNumber = number;
d->m_displayedItems = list;
return list;
}
QList<AbstractDataPluginItem *> AbstractDataPluginModel::whichItemAt( const QPoint& curpos )
{
QList<AbstractDataPluginItem *> itemsAt;
const QPointF curposF(curpos);
for( AbstractDataPluginItem* item: d->m_displayedItems ) {
if (item && item->contains(curposF)) {
itemsAt.append( item );
}
}
return itemsAt;
}
void AbstractDataPluginModel::parseFile( const QByteArray& file )
{
Q_UNUSED( file );
}
void AbstractDataPluginModel::downloadItem( const QUrl& url,
const QString& type,
AbstractDataPluginItem *item )
{
if( !item ) {
return;
}
QString id = d->generateFilename( item->id(), type );
d->m_downloadManager.addJob( url, id, id, DownloadBrowse );
d->m_downloadingItems.insert( id, item );
}
void AbstractDataPluginModel::downloadDescriptionFile( const QUrl& url )
{
if( !url.isEmpty() ) {
QString name( descriptionPrefix );
name += QString::number( d->m_descriptionFileNumber );
d->m_downloadManager.addJob( url, name, name, DownloadBrowse );
d->m_descriptionFileNumber++;
}
}
void AbstractDataPluginModel::addItemToList( AbstractDataPluginItem *item )
{
addItemsToList( QList<AbstractDataPluginItem*>() << item );
}
void AbstractDataPluginModel::addItemsToList( const QList<AbstractDataPluginItem *> &items )
{
bool needsUpdate = false;
bool favoriteChanged = false;
for( AbstractDataPluginItem *item: items ) {
if( !item ) {
continue;
}
// If the item is already in our list, don't add it.
if ( d->m_itemSet.contains( item ) ) {
continue;
}
if( itemExists( item->id() ) ) {
item->deleteLater();
continue;
}
mDebug() << "New item " << item->id();
// This find the right position in the sorted to insert the new item
QList<AbstractDataPluginItem*>::iterator i = std::lower_bound( d->m_itemSet.begin(),
d->m_itemSet.end(),
item,
lessThanByPointer );
// Insert the item on the right position in the list
d->m_itemSet.insert( i, item );
connect( item, SIGNAL(stickyChanged()), this, SLOT(scheduleItemSort()) );
connect( item, SIGNAL(destroyed(QObject*)), this, SLOT(removeItem(QObject*)) );
connect( item, SIGNAL(updated()), this, SIGNAL(itemsUpdated()) );
connect( item, SIGNAL(favoriteChanged(QString,bool)), this,
SLOT(favoriteItemChanged(QString,bool)) );
if ( !needsUpdate && item->initialized() ) {
needsUpdate = true;
}
if ( !favoriteChanged && item->initialized() && item->isFavorite() ) {
favoriteChanged = true;
}
}
if ( favoriteChanged && d->m_favoritesModel ) {
d->m_favoritesModel->reset();
}
if ( needsUpdate ) {
emit itemsUpdated();
}
}
void AbstractDataPluginModel::getItem( const QString & )
{
qWarning() << "Retrieving items by identifier is not implemented by this plugin";
}
void AbstractDataPluginModel::setFavoriteItems( const QStringList& list )
{
if ( d->m_favoriteItems != list) {
d->m_favoriteItems = list;
d->updateFavoriteItems();
if ( d->m_favoritesModel ) {
d->m_favoritesModel->reset();
}
emit favoriteItemsChanged( d->m_favoriteItems );
}
}
QStringList AbstractDataPluginModel::favoriteItems() const
{
return d->m_favoriteItems;
}
void AbstractDataPluginModel::setFavoriteItemsOnly( bool favoriteOnly )
{
if ( isFavoriteItemsOnly() != favoriteOnly ) {
d->m_favoriteItemsOnly = favoriteOnly;
d->updateFavoriteItems();
emit favoriteItemsOnlyChanged();
}
}
bool AbstractDataPluginModel::isFavoriteItemsOnly() const
{
return d->m_favoriteItemsOnly;
}
QObject *AbstractDataPluginModel::favoritesModel()
{
if ( !d->m_favoritesModel ) {
d->m_favoritesModel = new FavoritesModel( d, this );
d->updateFavoriteItems();
}
return d->m_favoritesModel;
}
void AbstractDataPluginModel::favoriteItemChanged( const QString& id, bool isFavorite )
{
QStringList favorites = d->m_favoriteItems;
if ( isFavorite ) {
if ( !favorites.contains(id) )
favorites.append( id );
} else {
favorites.removeOne( id );
}
setFavoriteItems( favorites );
scheduleItemSort();
}
void AbstractDataPluginModel::scheduleItemSort()
{
d->m_needsSorting = true;
}
QString AbstractDataPluginModelPrivate::generateFilename(const QString &id, const QString &type)
{
QString name;
name += id;
name += fileIdSeparator;
name += type;
return name;
}
QString AbstractDataPluginModelPrivate::generateFilepath( const QString& id, const QString& type ) const
{
return MarbleDirs::localPath() + QLatin1String("/cache/") + m_name + QLatin1Char('/') + generateFilename(id, type);
}
AbstractDataPluginItem *AbstractDataPluginModel::findItem( const QString& id ) const
{
for ( AbstractDataPluginItem *item: d->m_itemSet ) {
if( item->id() == id ) {
return item;
}
}
- return 0;
+ return nullptr;
}
bool AbstractDataPluginModel::itemExists( const QString& id ) const
{
return findItem( id );
}
void AbstractDataPluginModel::setItemSettings(const QHash<QString, QVariant> &itemSettings)
{
d->m_itemSettings = itemSettings;
}
void AbstractDataPluginModel::handleChangedViewport()
{
if( d->m_favoriteItemsOnly ) {
return;
}
// All this is to prevent to often downloads
if( d->m_lastNumber != 0
// We don't need to download if nothing changed
&& ( !( d->m_downloadedBox == d->m_lastBox )
|| d->m_downloadedNumber != d->m_lastNumber )
// We try to filter little changes of the bounding box
&& ( fabs( d->m_downloadedBox.east() - d->m_lastBox.east() ) * boxComparisonFactor
> d->m_lastBox.width()
|| fabs( d->m_downloadedBox.south() - d->m_lastBox.south() ) * boxComparisonFactor
> d->m_lastBox.height()
|| fabs( d->m_downloadedBox.north() - d->m_lastBox.north() ) * boxComparisonFactor
> d->m_lastBox.height()
|| fabs( d->m_downloadedBox.west() - d->m_lastBox.west() ) * boxComparisonFactor
> d->m_lastBox.width() ) )
{
// We will wait a little bit longer to start the
// next download as we will really download something now.
d->m_downloadTimer.setInterval( timeBetweenDownloads );
// Save the download parameter
d->m_downloadedBox = d->m_lastBox;
d->m_downloadedNumber = d->m_lastNumber;
// Get items
getAdditionalItems( d->m_lastBox, d->m_lastNumber );
}
else {
// Don't wait to long to start the next download as we decided not to download anything.
// This will enhance response.
d->m_downloadTimer.setInterval( timeBetweenTriedDownloads );
}
}
void AbstractDataPluginModel::processFinishedJob( const QString& relativeUrlString,
const QString& id )
{
Q_UNUSED( relativeUrlString );
if( id.startsWith( descriptionPrefix ) ) {
parseFile( d->m_storagePolicy.data( id ) );
}
else {
// The downloaded file contains item data.
// Splitting the id in itemId and fileType
QStringList fileInformation = id.split( fileIdSeparator );
if( fileInformation.size() < 2) {
mDebug() << "Strange file information " << id;
return;
}
QString itemId = fileInformation.at( 0 );
fileInformation.removeAt( 0 );
QString fileType = fileInformation.join( QString( fileIdSeparator ) );
// Searching for the right item in m_downloadingItems
QHash<QString, AbstractDataPluginItem *>::iterator i = d->m_downloadingItems.find( id );
if( i != d->m_downloadingItems.end() ) {
if( itemId != (*i)->id() ) {
return;
}
(*i)->addDownloadedFile( d->generateFilepath( itemId, fileType ),
fileType );
d->m_downloadingItems.erase( i );
}
}
}
void AbstractDataPluginModel::removeItem( QObject *item )
{
AbstractDataPluginItem * pluginItem = qobject_cast<AbstractDataPluginItem*>( item );
d->m_itemSet.removeAll( pluginItem );
QHash<QString, AbstractDataPluginItem *>::iterator i;
for( i = d->m_downloadingItems.begin(); i != d->m_downloadingItems.end(); ++i ) {
if( *i == pluginItem ) {
i = d->m_downloadingItems.erase( i );
}
}
}
void AbstractDataPluginModel::clear()
{
d->m_displayedItems.clear();
QList<AbstractDataPluginItem*>::iterator iter = d->m_itemSet.begin();
QList<AbstractDataPluginItem*>::iterator const end = d->m_itemSet.end();
for (; iter != end; ++iter ) {
(*iter)->deleteLater();
}
d->m_itemSet.clear();
d->m_lastBox = GeoDataLatLonAltBox();
d->m_downloadedBox = GeoDataLatLonAltBox();
d->m_downloadedNumber = 0;
emit itemsUpdated();
}
void AbstractDataPluginModel::registerItemProperties( const QMetaObject &item )
{
d->m_metaObject = item;
d->m_hasMetaObject = true;
}
} // namespace Marble
#include "moc_AbstractDataPluginModel.cpp"
diff --git a/src/lib/marble/AbstractDataPluginModel.h b/src/lib/marble/AbstractDataPluginModel.h
index 40128e100..45a824289 100644
--- a/src/lib/marble/AbstractDataPluginModel.h
+++ b/src/lib/marble/AbstractDataPluginModel.h
@@ -1,189 +1,189 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_ABSTRACTDATAPLUGINMODEL_H
#define MARBLE_ABSTRACTDATAPLUGINMODEL_H
#include <QObject>
#include <QList>
#include <QHash>
#include "marble_export.h"
class QPoint;
class QUrl;
class QString;
class QStringList;
namespace Marble
{
class AbstractDataPluginModelPrivate;
class AbstractDataPluginItem;
class GeoDataLatLonAltBox;
class MarbleModel;
class ViewportParams;
/**
* @short An abstract data model (not based on QAbstractModel) for a AbstractDataPlugin.
*
* This class is an abstract model for a AbstractDataPlugin.
* It provides the storage and selection of added <b>items</b> and it is also responsible for
* downloading item data.
*
* The functions <b>getAdditionalItems()</b> and <b>parseFile()</b> have to be reimplemented in
* a subclass.
**/
class MARBLE_EXPORT AbstractDataPluginModel : public QObject
{
Q_OBJECT
/** @todo FIXME Qt Quick segfaults if using the real class here instead of QObject */
Q_PROPERTY( QObject* favoritesModel READ favoritesModel CONSTANT )
public:
- explicit AbstractDataPluginModel( const QString& name, const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit AbstractDataPluginModel( const QString& name, const MarbleModel *marbleModel, QObject *parent = nullptr );
~AbstractDataPluginModel() override;
const MarbleModel *marbleModel() const;
/**
* @brief Get the items on the viewport
* Returns the currently downloaded images in the @p viewport.
* The maximum number of images can be specified with @p number,
* 0 means no limit.
* @return The list of item with most important item first.
*/
QList<AbstractDataPluginItem*> items( const ViewportParams *viewport,
qint32 number = 10 );
/**
* @brief Get all items that contain the given point
* Returns a list of all items that contain the point @p curpos
*/
QList<AbstractDataPluginItem *> whichItemAt( const QPoint& curpos );
/**
* @brief Sets the settings for all items.
* Sets the settings for all items before painting. This ensures that all items react on
* changed settings.
*/
void setItemSettings(const QHash<QString, QVariant> &itemSettings);
virtual void setFavoriteItems( const QStringList& list );
QStringList favoriteItems() const;
void setFavoriteItemsOnly( bool favoriteOnly );
bool isFavoriteItemsOnly() const;
QObject* favoritesModel();
/**
* Finds the item with @p id in the list.
* @return The pointer to the item or (if no item has been found) 0
*/
AbstractDataPluginItem *findItem( const QString& id ) const;
/**
* Testing the existence of the item @p id in the list
*/
bool itemExists( const QString& id ) const;
public Q_SLOTS:
/**
* Adds the @p items to the list of initialized items. It checks if items with the same id are
* already in the list and ignores and deletes them in this case.
*/
void addItemsToList( const QList<AbstractDataPluginItem*> &items );
/**
* Convenience method to add one item to the list. See addItemsToList
*/
void addItemToList( AbstractDataPluginItem *item );
/**
* Removes all items
*/
void clear();
protected:
/**
* Managing to get @p number additional items in @p box. This includes generating a url and
* downloading the corresponding file.
* This method has to be implemented in a subclass.
**/
virtual void getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number = 10 ) = 0;
/**
* @brief Retrieve data for a specific item
* @param id Item id of the item to retrieve
*/
virtual void getItem( const QString &id );
/**
* Parse the @p file and generate items. The items will be added to the list or the method
* starts additionally needed downloads.
* This method has to be implemented in a subclass.
**/
virtual void parseFile( const QByteArray& file );
/**
* Downloads the file from @p url. @p item -> addDownloadedFile() will be called when the
* download is finished.
* @param: The type of the download (to be specified by the subclasser)
**/
void downloadItem( const QUrl& url, const QString& type, AbstractDataPluginItem *item );
/**
* Download the description file from the @p url.
*/
void downloadDescriptionFile( const QUrl& url );
void registerItemProperties( const QMetaObject& item );
private Q_SLOTS:
/**
* @brief Get new items with getAdditionalItems if it is reasonable.
*/
void handleChangedViewport();
/**
* @brief This method will assign downloaded files to the corresponding items
* @param relativeUrlString The string containing the relative (to the downloader path)
* url of the downloaded file.
* @param id The id of the downloaded file
*/
void processFinishedJob( const QString& relativeUrlString, const QString& id );
/**
* @brief Removes the item from the list.
*/
void removeItem( QObject *item );
void favoriteItemChanged( const QString& id, bool isFavorite );
void scheduleItemSort();
void themeChanged();
Q_SIGNALS:
void itemsUpdated();
void favoriteItemsChanged( const QStringList& favoriteItems );
void favoriteItemsOnlyChanged();
private:
AbstractDataPluginModelPrivate * const d;
friend class AbstractDataPluginModelPrivate;
};
}
#endif
diff --git a/src/lib/marble/AbstractFloatItem.cpp b/src/lib/marble/AbstractFloatItem.cpp
index 49ba5b627..afcb072c6 100644
--- a/src/lib/marble/AbstractFloatItem.cpp
+++ b/src/lib/marble/AbstractFloatItem.cpp
@@ -1,266 +1,266 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <rahn@kde.org>
//
// Self
#include "AbstractFloatItem.h"
// Qt
#include <QMenu>
#include <QAction>
#include <QContextMenuEvent>
#include <QDialog>
#include <QHelpEvent>
#include <QPen>
// Marble
#include "DialogConfigurationInterface.h"
#include "GeoPainter.h"
#include "MarbleDebug.h"
namespace Marble
{
class AbstractFloatItemPrivate
{
public:
- AbstractFloatItemPrivate() : m_contextMenu( 0 )
+ AbstractFloatItemPrivate() : m_contextMenu( nullptr )
{
}
~AbstractFloatItemPrivate()
{
delete m_contextMenu;
}
static QPen s_pen;
static QFont s_font;
QMenu* m_contextMenu;
};
QPen AbstractFloatItemPrivate::s_pen = QPen( Qt::black );
#ifdef Q_OS_MACX
QFont AbstractFloatItemPrivate::s_font = QFont( QStringLiteral("Sans Serif"), 10 );
#else
QFont AbstractFloatItemPrivate::s_font = QFont( QStringLiteral("Sans Serif"), 8 );
#endif
AbstractFloatItem::AbstractFloatItem( const MarbleModel *marbleModel, const QPointF &point, const QSizeF &size )
: RenderPlugin( marbleModel ),
FrameGraphicsItem(),
d( new AbstractFloatItemPrivate() )
{
setCacheMode( ItemCoordinateCache );
setFrame( RectFrame );
setPadding( 4.0 );
setContentSize( size );
setPosition( point );
}
AbstractFloatItem::~AbstractFloatItem()
{
delete d;
}
QHash<QString,QVariant> AbstractFloatItem::settings() const
{
QHash<QString,QVariant> updated = RenderPlugin::settings();
#ifdef Q_OS_OSX
updated.insert(QStringLiteral("position"), position().toPoint());
#else
updated.insert(QStringLiteral("position"), position());
#endif
return updated;
}
void AbstractFloatItem::setSettings(const QHash<QString, QVariant> &settings)
{
if (settings.value(QStringLiteral("position")).type() == QVariant::String) {
#ifdef Q_OS_OSX
setPosition(settings.value(QStringLiteral("position"), position()).toPointF());
#else
// work around KConfig turning QPointFs into QStrings
const QStringList coordinates = settings.value(QStringLiteral("position")).toString().split(QLatin1Char(','));
setPosition( QPointF( coordinates.at( 0 ).toFloat(), coordinates.at( 1 ).toFloat() ) );
#endif
}
else {
setPosition(settings.value(QStringLiteral("position"), position()).toPointF());
}
RenderPlugin::setSettings(settings);
}
RenderPlugin::RenderType AbstractFloatItem::renderType() const
{
return RenderPlugin::PanelRenderType;
}
QPen AbstractFloatItem::pen() const
{
return d->s_pen;
}
void AbstractFloatItem::setPen( const QPen &pen )
{
d->s_pen = pen;
update();
}
QFont AbstractFloatItem::font() const
{
return d->s_font;
}
void AbstractFloatItem::setFont( const QFont &font )
{
d->s_font = font;
update();
}
QString AbstractFloatItem::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList AbstractFloatItem::renderPosition() const
{
return QStringList(QStringLiteral("FLOAT_ITEM"));
}
void AbstractFloatItem::setVisible( bool visible )
{
// Reimplemented since AbstractFloatItem does multiple inheritance
// and the (set)Visible() methods are available in both base classes!
RenderPlugin::setVisible( visible );
}
bool AbstractFloatItem::visible() const
{
// Reimplemented since AbstractFloatItem does multiple inheritance
// and the (set)Visible() methods are available in both base classes!
return RenderPlugin::visible();
}
void AbstractFloatItem::setPositionLocked( bool lock )
{
ScreenGraphicsItem::GraphicsItemFlags flags = this->flags();
if ( lock ) {
flags &= ~ScreenGraphicsItem::ItemIsMovable;
}
else {
flags |= ScreenGraphicsItem::ItemIsMovable;
}
setFlags( flags );
}
bool AbstractFloatItem::positionLocked() const
{
return ( flags() & ScreenGraphicsItem::ItemIsMovable ) == 0;
}
bool AbstractFloatItem::eventFilter( QObject *object, QEvent *e )
{
if ( !enabled() || !visible() ) {
return false;
}
if( e->type() == QEvent::ContextMenu )
{
QWidget *widget = qobject_cast<QWidget *>( object );
QContextMenuEvent *menuEvent = dynamic_cast<QContextMenuEvent *> ( e );
- if( widget != NULL && menuEvent != NULL && contains( menuEvent->pos() ) )
+ if( widget != nullptr && menuEvent != nullptr && contains( menuEvent->pos() ) )
{
contextMenuEvent( widget, menuEvent );
return true;
}
return false;
}
else if( e->type() == QEvent::ToolTip )
{
QHelpEvent *helpEvent = dynamic_cast<QHelpEvent *>( e );
- if( helpEvent != NULL && contains( helpEvent->pos() ) )
+ if( helpEvent != nullptr && contains( helpEvent->pos() ) )
{
toolTipEvent( helpEvent );
return true;
}
return false;
}
else
return ScreenGraphicsItem::eventFilter( object, e );
}
void AbstractFloatItem::contextMenuEvent ( QWidget *w, QContextMenuEvent *e )
{
contextMenu()->exec( w->mapToGlobal( e->pos() ) );
}
void AbstractFloatItem::toolTipEvent ( QHelpEvent *e )
{
Q_UNUSED( e );
}
bool AbstractFloatItem::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos, GeoSceneLayer * layer )
{
Q_UNUSED(painter)
Q_UNUSED(viewport)
Q_UNUSED(renderPos)
Q_UNUSED(layer)
return true;
}
void AbstractFloatItem::show()
{
setVisible( true );
}
void AbstractFloatItem::hide()
{
setVisible( false );
}
QMenu* AbstractFloatItem::contextMenu()
{
if ( !d->m_contextMenu )
{
d->m_contextMenu = new QMenu;
QAction *lockAction = d->m_contextMenu->addAction(QIcon(QStringLiteral(":/icons/unlock.png")), tr("&Lock"));
lockAction->setCheckable( true );
lockAction->setChecked( positionLocked() );
connect( lockAction, SIGNAL(triggered(bool)), this, SLOT(setPositionLocked(bool)) );
if(!(flags() & ItemIsHideable)) {
QAction *hideAction = d->m_contextMenu->addAction( tr( "&Hide" ) );
connect( hideAction, SIGNAL(triggered()), this, SLOT(hide()) );
}
DialogConfigurationInterface *configInterface = qobject_cast<DialogConfigurationInterface *>( this );
- QDialog *dialog = configInterface ? configInterface->configDialog() : 0;
+ QDialog *dialog = configInterface ? configInterface->configDialog() : nullptr;
if( dialog )
{
d->m_contextMenu->addSeparator();
QAction *configAction = d->m_contextMenu->addAction(QIcon(QStringLiteral(":/icons/settings-configure.png")), tr("&Configure..."));
connect( configAction, SIGNAL(triggered()), dialog, SLOT(exec()) );
}
}
Q_ASSERT( d->m_contextMenu );
return d->m_contextMenu;
}
}
#include "moc_AbstractFloatItem.cpp"
diff --git a/src/lib/marble/AbstractFloatItem.h b/src/lib/marble/AbstractFloatItem.h
index 25b8ea84a..5900e94de 100644
--- a/src/lib/marble/AbstractFloatItem.h
+++ b/src/lib/marble/AbstractFloatItem.h
@@ -1,175 +1,175 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef MARBLE_ABSTRACTFLOATITEM_H
#define MARBLE_ABSTRACTFLOATITEM_H
#include <QPointF>
#include <QSizeF>
#include "RenderPlugin.h"
#include "FrameGraphicsItem.h"
#include "marble_export.h"
class QContextMenuEvent;
class QHelpEvent;
class QMenu;
class QWidget;
class QFont;
class QPen;
namespace Marble
{
class AbstractFloatItemPrivate;
/**
* @brief The abstract class for float item plugins
*
* Float Item is a variant of Marble render plugins
* It keeps floating on top of the map at a given screen position
*
* Good examples are Overview Map, License
*
*/
class MARBLE_EXPORT AbstractFloatItem : public RenderPlugin, public FrameGraphicsItem
{
Q_OBJECT
public:
explicit AbstractFloatItem( const MarbleModel *marbleModel,
const QPointF &point = QPointF( 10.0, 10.0 ),
const QSizeF &size = QSizeF( 150.0, 50.0 ) );
~AbstractFloatItem() override;
QHash<QString,QVariant> settings() const override;
void setSettings(const QHash<QString, QVariant> &settings) override;
RenderType renderType() const override;
/**
* @brief current pen for rendering
* @return pen
*/
QPen pen() const;
/**
* @brief setting current pen for rendering
* @param pen
*/
void setPen( const QPen &pen );
/**
* @brief current font for rendering
* @return font
*/
QFont font() const;
/**
* @brief setting current font for rendering
* @param font
*/
void setFont( const QFont &font );
/**
* @brief Paints the float item on the map.
* @deprecated Do not override this method since it won't be called any longer.
* Override one of FrameGraphicsItem's paint methods instead.
*/
MARBLE_DEPRECATED bool render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos = QLatin1String("FLOAT_ITEM"),
- GeoSceneLayer * layer = 0 ) override;
+ GeoSceneLayer * layer = nullptr ) override;
QString renderPolicy() const override;
/**
* @brief Returns the rendering position of this float item.
* @deprecated The return value of method is ignored. The float item's rendering position
* will always be "FLOAT_ITEM".
*/
MARBLE_DEPRECATED QStringList renderPosition() const override;
/**
* @brief Set visibility of the float item
*
* Float items can be visible or invisible.
* It's possible to check visibility with @see visible
*
* @param visible visibility of the item
*/
void setVisible( bool visible );
/**
* @brief Check visibility of the float item
*
* Float items can be visible or invisible.
* It's possible to set visibility with @see setVisible
*
* @return visible or not
*/
bool visible() const;
/**
* @brief Check is position locked
*
* Float Item position can be locked. If it is,
* the item can't be moved with the cursor (in the UI)
*
* To set it use @see setPositionLocked
*
* @return position locked or not
*/
bool positionLocked() const;
public Q_SLOTS:
/**
* @brief Set is position locked
* @param lock is locked?
*
* Float Item position can be locked. If it is,
* item can't be moved with cursor (in UI)
*
* To check it use @see positionLocked
*
*/
void setPositionLocked( bool lock );
/**
* @brief Show the item
*
* If the item was hidden this function will show it
*
*/
void show();
/**
* @brief Hide the item
*
* If the item was shown this function will hide it
*
*/
void hide();
protected:
bool eventFilter(QObject *object, QEvent *e) override;
virtual void contextMenuEvent ( QWidget *w, QContextMenuEvent *e );
virtual void toolTipEvent( QHelpEvent *e );
QMenu* contextMenu();
private:
Q_DISABLE_COPY( AbstractFloatItem )
AbstractFloatItemPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/AbstractWorkerThread.h b/src/lib/marble/AbstractWorkerThread.h
index 364f07679..875b0c25f 100644
--- a/src/lib/marble/AbstractWorkerThread.h
+++ b/src/lib/marble/AbstractWorkerThread.h
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_ABSTRACTWORKERTHREAD_H
#define MARBLE_ABSTRACTWORKERTHREAD_H
// Marble
#include "marble_export.h"
// Qt
#include <QThread>
namespace Marble
{
class AbstractWorkerThreadPrivate;
/**
* The AbstractWorkerThread is a class written for small tasks that have to run
* multiple times on different data asynchronously.
* You should be able to use this class for many different tasks, but you'll have to
* think about Multi-Threading additionally.
* The AbstractWorkerThread runs the function work() as long as workAvailable()
* returns true. If there is no work available for a longer time, the thread will
* switch itself off. As a result you have to call ensureRunning() every time you
* want something to be worked on. You'll probably want to call this in your
* addSchedule() function.
*/
class MARBLE_EXPORT AbstractWorkerThread : public QThread
{
Q_OBJECT
public:
- explicit AbstractWorkerThread( QObject *parent = 0 );
+ explicit AbstractWorkerThread( QObject *parent = nullptr );
~AbstractWorkerThread() override;
void ensureRunning();
protected:
virtual bool workAvailable() = 0;
virtual void work() = 0;
void run() override;
private:
AbstractWorkerThreadPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/AddLinkDialog.h b/src/lib/marble/AddLinkDialog.h
index 13979ec3d..4747a9b93 100644
--- a/src/lib/marble/AddLinkDialog.h
+++ b/src/lib/marble/AddLinkDialog.h
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Mikhail Ivchenko <ematirov@gmail.com>
//
#ifndef ADDLINKDIALOG_H
#define ADDLINKDIALOG_H
#include "marble_export.h"
#include <QDialog>
namespace Marble {
class MARBLE_EXPORT AddLinkDialog : public QDialog
{
Q_OBJECT
public:
- explicit AddLinkDialog(QWidget *parent = 0 );
+ explicit AddLinkDialog(QWidget *parent = nullptr );
~AddLinkDialog() override;
QString name() const;
QString url() const;
private Q_SLOTS:
void checkFields();
private:
class Private;
Private * const d;
};
}
#endif
diff --git a/src/lib/marble/AutoNavigation.h b/src/lib/marble/AutoNavigation.h
index 524f50057..17e59c993 100644
--- a/src/lib/marble/AutoNavigation.h
+++ b/src/lib/marble/AutoNavigation.h
@@ -1,107 +1,107 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Siddharth Srivastava <akssps011@gmail.com>
//
#ifndef MARBLE_AUTONAVIGATION_H
#define MARBLE_AUTONAVIGATION_H
#include "marble_export.h"
#include "MarbleGlobal.h"
#include <QObject>
namespace Marble
{
class GeoDataCoordinates;
class MarbleModel;
class ViewportParams;
class MARBLE_EXPORT AutoNavigation : public QObject
{
Q_OBJECT
public:
/**
* @brief Constructor
* @param widget the marble widget. It cannot be null.
* @param parent optional parent object
*/
- explicit AutoNavigation( MarbleModel *model, const ViewportParams *viewport, QObject *parent = 0 );
+ explicit AutoNavigation( MarbleModel *model, const ViewportParams *viewport, QObject *parent = nullptr );
/** Destructor */
~AutoNavigation() override;
/**
* An enum type
* Represents which recentering method is selected
*/
enum CenterMode {
DontRecenter = 0,
AlwaysRecenter = 1, /**< Enum Value AlwaysRecenter. Recenter always to the map center */
RecenterOnBorder = 2 /**< Enum Value RecenterOnBorder. Recenter when reaching map border */
};
/**
* @brief For Auto Centering adjustment of map in Navigation Mode
* @param recenterMode toggles among the recenteing method chosen
* @see CenterMode
*/
void setRecenter( CenterMode recenterMode );
/**
* @brief For Auto Zooming adjustment of map in Navigation Mode
* @param activate true to enable auto zooming
*/
void setAutoZoom( bool activate );
AutoNavigation::CenterMode recenterMode() const;
bool autoZoom() const;
public Q_SLOTS:
/**
* @brief For adjusting the gps location (recentering) or map(autozooming)
* @param position current gps location
* @param speed of the gps device
*/
void adjust( const GeoDataCoordinates &position, qreal speed );
/**
* Temporarily inhibits auto-centering and auto-zooming
*/
void inhibitAutoAdjustments();
Q_SIGNALS:
/**
* signal emitted when auto center is turned on (Always re-center, re-center when required ) or off(Disabled)
* @param recenterMode the mode for re-centering selected
*/
void recenterModeChanged( AutoNavigation::CenterMode mode );
/**
* signal emitted when auto zoom is toggled
*/
void autoZoomToggled( bool enabled );
void zoomIn( FlyToMode );
void zoomOut( FlyToMode );
void centerOn( const GeoDataCoordinates &position, bool animated );
private:
class Private;
Private * const d;
};
} //namespace marble
#endif // MARBLE_AUTONAVIGATION_H
diff --git a/src/lib/marble/BookmarkManager.cpp b/src/lib/marble/BookmarkManager.cpp
index 37c57246a..8ec2dbfff 100644
--- a/src/lib/marble/BookmarkManager.cpp
+++ b/src/lib/marble/BookmarkManager.cpp
@@ -1,322 +1,322 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
//
#include "BookmarkManager.h"
#include "BookmarkManager_p.h"
#include "GeoDataParser.h"
#include "GeoDataContainer.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTreeModel.h"
#include "GeoDataDocumentWriter.h"
#include "GeoDataIconStyle.h"
#include "KmlElementDictionary.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "StyleBuilder.h"
#include <QFile>
namespace Marble
{
BookmarkManagerPrivate::BookmarkManagerPrivate( GeoDataTreeModel *treeModel ) :
m_treeModel( treeModel ),
- m_bookmarkDocument( 0 ),
+ m_bookmarkDocument( nullptr ),
m_bookmarkFileRelativePath( "bookmarks/bookmarks.kml" ),
m_styleBuilder(nullptr)
{
resetBookmarkDocument();
}
BookmarkManagerPrivate::~BookmarkManagerPrivate()
{
Q_ASSERT( m_bookmarkDocument && "BookmarkManagerPrivate::m_bookmarkDocument is 0. Please report a Marble bug at http://bugs.kde.org" );
if ( m_bookmarkDocument )
{
m_treeModel->removeDocument( m_bookmarkDocument );
}
delete m_bookmarkDocument;
}
void BookmarkManagerPrivate::resetBookmarkDocument()
{
if ( m_bookmarkDocument ) {
m_treeModel->removeDocument( m_bookmarkDocument );
delete m_bookmarkDocument;
}
GeoDataFolder* folder = new GeoDataFolder;
folder->setName( QObject::tr( "Default" ) );
m_bookmarkDocument = new GeoDataDocument;
m_bookmarkDocument->setDocumentRole( BookmarkDocument );
m_bookmarkDocument->setName( QObject::tr("Bookmarks") );
m_bookmarkDocument->append( folder );
m_treeModel->addDocument( m_bookmarkDocument );
}
void BookmarkManagerPrivate::setVisualCategory( GeoDataContainer *container ) {
for( GeoDataFolder* folder: container->folderList() ) {
setVisualCategory( folder );
}
for( GeoDataPlacemark* placemark: container->placemarkList() ) {
placemark->setVisualCategory(GeoDataPlacemark::Bookmark);
placemark->setZoomLevel( 1 );
}
}
BookmarkManager::BookmarkManager( GeoDataTreeModel *treeModel, QObject *parent ) :
QObject( parent ),
d( new BookmarkManagerPrivate( treeModel ) )
{
}
BookmarkManager::~BookmarkManager()
{
delete d;
}
QString BookmarkManager::bookmarkFile() const
{
return MarbleDirs::path( d->m_bookmarkFileRelativePath );
}
bool BookmarkManager::loadFile( const QString &relativeFilePath )
{
d->m_bookmarkFileRelativePath = relativeFilePath;
QString absoluteFilePath = bookmarkFile();
mDebug() << Q_FUNC_INFO << "Loading Bookmark File:" << absoluteFilePath;
if (absoluteFilePath.isEmpty())
return false;
if ( relativeFilePath.isNull() )
return false;
GeoDataDocument *document = openFile( absoluteFilePath );
bool recover = false;
if ( !document ) {
mDebug() << "Could not parse file" << absoluteFilePath;
mDebug() << "This could be caused by a previous broken bookmark file. Trying to recover.";
/** @todo: Remove this workaround and return false around Marble 1.4 */
recover = true;
// return false;
}
d->m_treeModel->removeDocument( d->m_bookmarkDocument );
delete d->m_bookmarkDocument;
d->m_bookmarkDocument = document;
if ( recover ) {
d->resetBookmarkDocument();
updateBookmarkFile();
} else {
Q_ASSERT( d->m_bookmarkDocument && "d->m_bookmarkDocument is 0 but must not be. Please report a bug at http://bugs.kde.org" );
d->m_treeModel->addDocument( d->m_bookmarkDocument );
}
ensureDefaultFolder();
emit bookmarksChanged();
return true;
}
void BookmarkManager::addBookmark( GeoDataContainer *container, const GeoDataPlacemark &placemark )
{
GeoDataPlacemark *bookmark = new GeoDataPlacemark( placemark );
bookmark->setVisualCategory(GeoDataPlacemark::Bookmark);
bookmark->setZoomLevel( 1 );
if (bookmark->name().isEmpty()) {
bookmark->setName(bookmark->coordinate().toString(GeoDataCoordinates::Decimal).trimmed());
}
if (d->m_styleBuilder && bookmark->style()->iconStyle().iconPath().isEmpty()) {
StyleParameters style;
style.placemark = bookmark;
bookmark->setStyle(GeoDataStyle::Ptr(new GeoDataStyle(*d->m_styleBuilder->createStyle(style))));
}
d->m_treeModel->addFeature( container, bookmark );
updateBookmarkFile();
}
void BookmarkManager::updateBookmark( GeoDataPlacemark *bookmark )
{
d->m_treeModel->updateFeature( bookmark );
}
void BookmarkManager::removeBookmark( GeoDataPlacemark *bookmark )
{
d->m_treeModel->removeFeature( bookmark );
delete bookmark;
updateBookmarkFile();
}
GeoDataPlacemark* BookmarkManager::bookmarkAt(GeoDataContainer *container, const GeoDataCoordinates &coordinate)
{
for ( GeoDataFolder *folder: container->folderList() ) {
GeoDataPlacemark *placemark = bookmarkAt(folder, coordinate);
if ( placemark )
return placemark;
}
for ( GeoDataPlacemark *placemark: container->placemarkList() ) {
if ( placemark->coordinate() == coordinate )
return placemark;
}
return Q_NULLPTR;
}
GeoDataDocument * BookmarkManager::document()
{
return d->m_bookmarkDocument;
}
const GeoDataDocument * BookmarkManager::document() const
{
return d->m_bookmarkDocument;
}
bool BookmarkManager::showBookmarks() const
{
return d->m_bookmarkDocument->isVisible();
}
void BookmarkManager::setShowBookmarks( bool visible )
{
d->m_bookmarkDocument->setVisible( visible );
d->m_treeModel->updateFeature( d->m_bookmarkDocument );
}
QVector<GeoDataFolder*> BookmarkManager::folders() const
{
return d->m_bookmarkDocument->folderList();
}
GeoDataFolder* BookmarkManager::addNewBookmarkFolder( GeoDataContainer *container, const QString &name )
{
//If name is empty string
if ( name.isEmpty() ) {
mDebug() << "Folder with empty name is not acceptable, please give it another name" ;
return Q_NULLPTR;
}
//If folder with same name already exist
QVector<GeoDataFolder*> folderList = container->folderList();
QVector<GeoDataFolder*>::const_iterator i = folderList.constBegin();
QVector<GeoDataFolder*>::const_iterator end = folderList.constEnd();
for ( ; i != end; ++i ) {
if ( name == ( *i )->name() ) {
mDebug() << "Folder with same name already exist, please give it another name";
return *i;
}
}
GeoDataFolder *bookmarkFolder = new GeoDataFolder();
bookmarkFolder->setName( name );
d->m_treeModel->addFeature( container, bookmarkFolder );
updateBookmarkFile();
return bookmarkFolder;
}
void BookmarkManager::renameBookmarkFolder( GeoDataFolder *folder, const QString &name )
{
folder->setName( name );
d->m_treeModel->updateFeature( folder );
}
void BookmarkManager::removeBookmarkFolder( GeoDataFolder *folder )
{
d->m_treeModel->removeFeature( folder );
delete folder;
}
void BookmarkManager::ensureDefaultFolder()
{
if ( d->m_bookmarkDocument->size() == 0 ) {
addNewBookmarkFolder( d->m_bookmarkDocument, tr("Default") );
}
}
void BookmarkManager::removeAllBookmarks()
{
d->resetBookmarkDocument();
updateBookmarkFile();
}
void BookmarkManager::setStyleBuilder(const StyleBuilder *styleBuilder)
{
d->m_styleBuilder = styleBuilder;
}
bool BookmarkManager::updateBookmarkFile()
{
const QString absoluteLocalFilePath = MarbleDirs::localPath() + QLatin1Char('/') + d->m_bookmarkFileRelativePath;
if ( ! d->m_bookmarkFileRelativePath.isNull() ) {
QFile file( absoluteLocalFilePath );
if ( !file.exists() ) {
// Extracting directory of file : for bookmarks it will be MarbleDirs::localPath()+/bookmarks/
QFileInfo fileInfo( absoluteLocalFilePath );
QString directoryPath = fileInfo.path();
//Creating all directories, which doesn't exist
QDir directory( MarbleDirs::localPath() );
directory.mkpath( directoryPath );
}
if (!GeoDataDocumentWriter::write(absoluteLocalFilePath, *d->m_bookmarkDocument)) {
mDebug() << "Could not write the bookmarks file" << absoluteLocalFilePath;
file.close();
return false;
}
emit bookmarksChanged();
file.close();
return true;
}
return false;
}
GeoDataDocument* BookmarkManager::openFile( const QString &fileName )
{
GeoDataParser parser( GeoData_KML );
QFile file( fileName );
if ( !file.exists() ) {
- return 0;
+ return nullptr;
}
if ( !file.open( QIODevice::ReadOnly ) || !parser.read( &file ) ) {
mDebug() << "Could not open/parse file" << fileName;
- return 0;
+ return nullptr;
}
GeoDataDocument *result = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() );
if ( !result ) {
- return 0;
+ return nullptr;
}
result->setDocumentRole( BookmarkDocument );
for( GeoDataFolder* folder: result->folderList() ) {
BookmarkManagerPrivate::setVisualCategory( folder );
}
return result;
}
}
#include "moc_BookmarkManager.cpp"
diff --git a/src/lib/marble/BookmarkManager.h b/src/lib/marble/BookmarkManager.h
index b7eff95cf..7cdcef27e 100644
--- a/src/lib/marble/BookmarkManager.h
+++ b/src/lib/marble/BookmarkManager.h
@@ -1,138 +1,138 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
//
#ifndef MARBLE_BOOKMARKMANAGER_H
#define MARBLE_BOOKMARKMANAGER_H
#include <QObject>
#include <QVector>
#include "MarbleGlobal.h"
class QString;
namespace Marble
{
class BookmarkManagerPrivate;
class GeoDataContainer;
class GeoDataDocument;
class GeoDataPlacemark;
class GeoDataCoordinates;
class GeoDataFolder;
class GeoDataTreeModel;
class StyleBuilder;
/**
* This class is responsible for loading the
* book mark objects from the files and various
* book mark operations
*/
class MARBLE_EXPORT BookmarkManager : public QObject
{
Q_OBJECT
public:
- explicit BookmarkManager( GeoDataTreeModel *treeModel, QObject *parent = 0 );
+ explicit BookmarkManager( GeoDataTreeModel *treeModel, QObject *parent = nullptr );
~BookmarkManager() override;
/**
* @brief load bookmark file as GeoDataDocument and return true
* if loaded successfully else false
* @param relativeFilePath relative path of bookmark file
*/
bool loadFile( const QString &relativeFilePath );
/**
* @brief return bookmark file path
*/
QString bookmarkFile() const;
/**
* @brief add bookmark in a folder
* @param bookmark bookmark to be added
* @param folder folder to add bookmark to
*/
void addBookmark( GeoDataContainer *folder, const GeoDataPlacemark &bookmark ) ;
void updateBookmark( GeoDataPlacemark *bookmark );
void removeBookmark( GeoDataPlacemark *bookmark );
/**
* @brief checks all the bookmarks in container recursively and returns
* pointer to the one having the same coordinate as the provided
*/
GeoDataPlacemark* bookmarkAt(GeoDataContainer *container, const GeoDataCoordinates &coordinate);
GeoDataDocument * document();
const GeoDataDocument * document() const;
bool showBookmarks() const;
/**
* @brief return Vector of folders
*/
QVector<GeoDataFolder*> folders() const;
/**
* @brief add a folder
* @param name name of folder to be created
* @return pointer to the newly added folder
*/
GeoDataFolder* addNewBookmarkFolder( GeoDataContainer *container, const QString &name );
void renameBookmarkFolder( GeoDataFolder *folder, const QString &name );
void removeBookmarkFolder( GeoDataFolder *folder );
/**
* @brief checks that there is at least one folder
*/
void ensureDefaultFolder();
/**
* @brief remove all folders and bookmarks except default folder
*/
void removeAllBookmarks();
/**
* @since 0.26.0
*/
void setStyleBuilder(const StyleBuilder* styleBuilder);
public Q_SLOTS:
void setShowBookmarks( bool visible );
Q_SIGNALS:
/** One or more bookmarks were added or removed */
void bookmarksChanged();
private:
friend class BookmarkManagerDialog;
/**
* @brief updates bookmark file and return true if updated successfully
*/
bool updateBookmarkFile();
static GeoDataDocument* openFile( const QString& fileName );
BookmarkManagerPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/BookmarkManagerDialog.h b/src/lib/marble/BookmarkManagerDialog.h
index 7d901d335..56cb6862d 100644
--- a/src/lib/marble/BookmarkManagerDialog.h
+++ b/src/lib/marble/BookmarkManagerDialog.h
@@ -1,70 +1,70 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_BOOKMARKMANAGERDIALOG_H
#define MARBLE_BOOKMARKMANAGERDIALOG_H
#include "ui_BookmarkManagerDialog.h"
#include "marble_export.h"
#include <QDialog>
namespace Marble
{
class GeoDataDocument;
class GeoDataContainer;
class MarbleModel;
class BookmarkManagerDialogPrivate;
class MARBLE_EXPORT BookmarkManagerDialog : public QDialog, private Ui::UiBookmarkManagerDialog
{
Q_OBJECT
public:
/** Constructor. The model is used to retrieve the bookmark manager */
- explicit BookmarkManagerDialog( MarbleModel* model, QWidget *parent = 0 );
+ explicit BookmarkManagerDialog( MarbleModel* model, QWidget *parent = nullptr );
/** Destructor */
~BookmarkManagerDialog() override;
void setButtonBoxVisible( bool visible );
private Q_SLOTS:
void saveBookmarks();
void exportBookmarks();
void importBookmarks();
private:
Q_PRIVATE_SLOT( d, void updateButtonState() )
Q_PRIVATE_SLOT( d, void addNewFolder() )
Q_PRIVATE_SLOT( d, void renameFolder() )
Q_PRIVATE_SLOT( d, void deleteFolder() )
Q_PRIVATE_SLOT( d, void editBookmark() )
Q_PRIVATE_SLOT( d, void deleteBookmark() )
Q_PRIVATE_SLOT( d, void handleFolderSelection( const QModelIndex &index ) )
Q_PRIVATE_SLOT( d, void discardChanges() )
Q_DISABLE_COPY( BookmarkManagerDialog )
BookmarkManagerDialogPrivate* const d;
friend class BookmarkManagerDialogPrivate;
};
}
#endif
diff --git a/src/lib/marble/BranchFilterProxyModel.cpp b/src/lib/marble/BranchFilterProxyModel.cpp
index 6c36baac4..dbc0736b2 100644
--- a/src/lib/marble/BranchFilterProxyModel.cpp
+++ b/src/lib/marble/BranchFilterProxyModel.cpp
@@ -1,65 +1,65 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
#include "BranchFilterProxyModel.h"
#include "MarblePlacemarkModel.h"
#include "GeoDataContainer.h"
#include "GeoDataTreeModel.h"
namespace Marble
{
BranchFilterProxyModel::BranchFilterProxyModel( QObject *parent ) :
- QSortFilterProxyModel( parent ), m_treeModel( 0 )
+ QSortFilterProxyModel( parent ), m_treeModel( nullptr )
{
// nothing to do
}
/// sets the folder index for which we want to see bookmarks
void BranchFilterProxyModel::setBranchIndex( GeoDataTreeModel* treeModel, const QModelIndex &index )
{
Q_ASSERT( index.isValid() );
Q_ASSERT( index.model() == treeModel );
m_treeModel = treeModel;
m_branchIndex = index;
invalidateFilter();
}
/// determines if such row should be filtered.
/// Beware, all parents of our folder must be accepted as well
bool BranchFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
{
if ( !m_treeModel || !m_branchIndex.isValid() ) {
return true;
}
Q_ASSERT( m_treeModel == sourceModel() );
if ( sourceParent.isValid() ) {
Q_ASSERT( sourceParent.model() == m_treeModel );
}
QModelIndex rowIndex = sourceModel()->index( sourceRow, 0, sourceParent );
Q_ASSERT( rowIndex.isValid() );
// return true for all non folder children of m_branchIndex
if( sourceParent == m_branchIndex ) {
GeoDataObject* obj = qvariant_cast<GeoDataObject*>( rowIndex.data( MarblePlacemarkModel::ObjectPointerRole ) );
return dynamic_cast<const GeoDataContainer *>(obj);
}
// return true if rowIndex is a parent of m_branchIndex
QModelIndex tmpIndex = m_branchIndex;
while ( tmpIndex.isValid() && tmpIndex != rowIndex ) {
tmpIndex = tmpIndex.parent();
}
return tmpIndex == rowIndex;
}
}
diff --git a/src/lib/marble/BranchFilterProxyModel.h b/src/lib/marble/BranchFilterProxyModel.h
index 6665f0f27..e83ef2f61 100644
--- a/src/lib/marble/BranchFilterProxyModel.h
+++ b/src/lib/marble/BranchFilterProxyModel.h
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
#ifndef BRANCHFILTERPROXYMODEL_H
#define BRANCHFILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
namespace Marble
{
class GeoDataTreeModel;
class BranchFilterProxyModel : public QSortFilterProxyModel
{
public:
- explicit BranchFilterProxyModel( QObject *parent = 0 );
+ explicit BranchFilterProxyModel( QObject *parent = nullptr );
void setBranchIndex( GeoDataTreeModel *sourceModel, const QModelIndex &index );
protected:
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
private:
GeoDataTreeModel *m_treeModel;
QPersistentModelIndex m_branchIndex;
};
}
#endif // BRANCHFILTERPROXYMODEL_H
diff --git a/src/lib/marble/CurrentLocationWidget.cpp b/src/lib/marble/CurrentLocationWidget.cpp
index 4aec22a4a..1dbe74209 100644
--- a/src/lib/marble/CurrentLocationWidget.cpp
+++ b/src/lib/marble/CurrentLocationWidget.cpp
@@ -1,460 +1,460 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2007 Thomas Zander <zander@kde.org>
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "CurrentLocationWidget.h"
// Marble
#include "AutoNavigation.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "MarbleWidgetPopupMenu.h"
#include "GeoDataCoordinates.h"
#include "PositionProviderPlugin.h"
#include "PluginManager.h"
#include "PositionTracking.h"
#include "routing/RoutingManager.h"
using namespace Marble;
/* TRANSLATOR Marble::CurrentLocationWidget */
// Ui
#include "ui_CurrentLocationWidget.h"
#include <QDateTime>
#include <QFileDialog>
#include <QMessageBox>
namespace Marble
{
class CurrentLocationWidgetPrivate
{
public:
CurrentLocationWidgetPrivate();
Ui::CurrentLocationWidget m_currentLocationUi;
MarbleWidget *m_widget;
AutoNavigation *m_adjustNavigation;
QList<const PositionProviderPlugin*> m_positionProviderPlugins;
GeoDataCoordinates m_currentPosition;
QString m_lastOpenPath;
QString m_lastSavePath;
void receiveGpsCoordinates( const GeoDataCoordinates &position, qreal speed );
void adjustPositionTrackingStatus( PositionProviderStatus status );
void changePositionProvider( const QString &provider );
void trackPlacemark();
void centerOnCurrentLocation();
void updateRecenterComboBox( AutoNavigation::CenterMode centerMode );
void updateAutoZoomCheckBox( bool autoZoom );
void updateActivePositionProvider( PositionProviderPlugin* );
void updateGuidanceMode();
void saveTrack();
void openTrack();
void clearTrack();
};
CurrentLocationWidgetPrivate::CurrentLocationWidgetPrivate()
- : m_widget( 0 ),
- m_adjustNavigation( 0 ),
+ : m_widget( nullptr ),
+ m_adjustNavigation( nullptr ),
m_positionProviderPlugins(),
m_currentPosition(),
m_lastOpenPath(),
m_lastSavePath()
{
}
CurrentLocationWidget::CurrentLocationWidget( QWidget *parent, Qt::WindowFlags f )
: QWidget( parent, f ),
d( new CurrentLocationWidgetPrivate() )
{
d->m_currentLocationUi.setupUi( this );
layout()->setMargin( 0 );
connect( d->m_currentLocationUi.recenterComboBox, SIGNAL (currentIndexChanged(int)),
this, SLOT(setRecenterMode(int)) );
connect( d->m_currentLocationUi.autoZoomCheckBox, SIGNAL(clicked(bool)),
this, SLOT(setAutoZoom(bool)) );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
d->m_currentLocationUi.positionTrackingComboBox->setVisible( !smallScreen );
d->m_currentLocationUi.locationLabel->setVisible( !smallScreen );
}
CurrentLocationWidget::~CurrentLocationWidget()
{
delete d;
}
void CurrentLocationWidget::setMarbleWidget( MarbleWidget *widget )
{
d->m_widget = widget;
delete d->m_adjustNavigation;
d->m_adjustNavigation = new AutoNavigation( widget->model(), widget->viewport(), this );
const PluginManager* pluginManager = d->m_widget->model()->pluginManager();
d->m_positionProviderPlugins = pluginManager->positionProviderPlugins();
for( const PositionProviderPlugin *plugin: d->m_positionProviderPlugins ) {
d->m_currentLocationUi.positionTrackingComboBox->addItem( plugin->guiString() );
}
if ( d->m_positionProviderPlugins.isEmpty() ) {
d->m_currentLocationUi.positionTrackingComboBox->setEnabled( false );
QString html = "<p>No Position Tracking Plugin installed.</p>";
d->m_currentLocationUi.locationLabel->setText( html );
d->m_currentLocationUi.locationLabel->setEnabled ( true );
bool const hasTrack = !d->m_widget->model()->positionTracking()->isTrackEmpty();
d->m_currentLocationUi.showTrackCheckBox->setEnabled( hasTrack );
d->m_currentLocationUi.saveTrackButton->setEnabled( hasTrack );
d->m_currentLocationUi.clearTrackButton->setEnabled( hasTrack );
}
//disconnect CurrentLocation Signals
disconnect( d->m_widget->model()->positionTracking(),
SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
this, SLOT(receiveGpsCoordinates(GeoDataCoordinates,qreal)) );
disconnect( d->m_widget->model()->positionTracking(),
SIGNAL(positionProviderPluginChanged(PositionProviderPlugin*)),
this, SLOT(updateActivePositionProvider(PositionProviderPlugin*)) );
disconnect( d->m_currentLocationUi.positionTrackingComboBox, SIGNAL(currentIndexChanged(QString)),
this, SLOT(changePositionProvider(QString)) );
disconnect( d->m_currentLocationUi.locationLabel, SIGNAL(linkActivated(QString)),
this, SLOT(centerOnCurrentLocation()) );
disconnect( d->m_widget->model()->positionTracking(),
SIGNAL(statusChanged(PositionProviderStatus)),this,
SLOT(adjustPositionTrackingStatus(PositionProviderStatus)) );
disconnect( d->m_widget->model(), SIGNAL(trackedPlacemarkChanged(const GeoDataPlacemark*)),
this, SLOT(trackPlacemark()) );
//connect CurrentLocation signals
connect( d->m_widget->model()->positionTracking(),
SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
this, SLOT(receiveGpsCoordinates(GeoDataCoordinates,qreal)) );
connect( d->m_widget->model()->positionTracking(),
SIGNAL(positionProviderPluginChanged(PositionProviderPlugin*)),
this, SLOT(updateActivePositionProvider(PositionProviderPlugin*)) );
d->updateActivePositionProvider( d->m_widget->model()->positionTracking()->positionProviderPlugin() );
connect( d->m_currentLocationUi.positionTrackingComboBox, SIGNAL(currentIndexChanged(QString)),
this, SLOT(changePositionProvider(QString)) );
connect( d->m_currentLocationUi.locationLabel, SIGNAL(linkActivated(QString)),
this, SLOT(centerOnCurrentLocation()) );
connect( d->m_widget->model()->positionTracking(),
SIGNAL(statusChanged(PositionProviderStatus)), this,
SLOT(adjustPositionTrackingStatus(PositionProviderStatus)) );
connect( d->m_adjustNavigation, SIGNAL(recenterModeChanged(AutoNavigation::CenterMode)),
this, SLOT(updateRecenterComboBox(AutoNavigation::CenterMode)) );
connect( d->m_adjustNavigation, SIGNAL(autoZoomToggled(bool)),
this, SLOT(updateAutoZoomCheckBox(bool)) );
connect( d->m_adjustNavigation, SIGNAL(zoomIn(FlyToMode)),
d->m_widget, SLOT(zoomIn(FlyToMode)) );
connect( d->m_adjustNavigation, SIGNAL(zoomOut(FlyToMode)),
d->m_widget, SLOT(zoomOut(FlyToMode)) );
connect( d->m_adjustNavigation, SIGNAL(centerOn(GeoDataCoordinates,bool)),
d->m_widget, SLOT(centerOn(GeoDataCoordinates,bool)) );
connect( d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
d->m_adjustNavigation, SLOT(inhibitAutoAdjustments()) );
connect( d->m_widget->model()->routingManager(), SIGNAL(guidanceModeEnabledChanged(bool)),
this, SLOT(updateGuidanceMode()) );
connect (d->m_currentLocationUi.showTrackCheckBox, SIGNAL(clicked(bool)),
d->m_widget->model()->positionTracking(), SLOT(setTrackVisible(bool)));
connect (d->m_currentLocationUi.showTrackCheckBox, SIGNAL(clicked(bool)),
d->m_widget, SLOT(update()));
if ( d->m_widget->model()->positionTracking()->trackVisible() ) {
d->m_currentLocationUi.showTrackCheckBox->setCheckState(Qt::Checked);
}
connect ( d->m_currentLocationUi.saveTrackButton, SIGNAL(clicked(bool)),
this, SLOT(saveTrack()));
connect ( d->m_currentLocationUi.openTrackButton, SIGNAL(clicked(bool)),
this, SLOT(openTrack()));
connect (d->m_currentLocationUi.clearTrackButton, SIGNAL(clicked(bool)),
this, SLOT(clearTrack()));
connect( d->m_widget->model(), SIGNAL(trackedPlacemarkChanged(const GeoDataPlacemark*)),
this, SLOT(trackPlacemark()) );
}
void CurrentLocationWidgetPrivate::adjustPositionTrackingStatus( PositionProviderStatus status )
{
if ( status == PositionProviderStatusAvailable ) {
return;
}
QString html = "<html><body><p>";
switch ( status ) {
case PositionProviderStatusUnavailable:
html += QObject::tr( "No position available." );
break;
case PositionProviderStatusAcquiring:
html += QObject::tr( "Waiting for current location information..." );
break;
case PositionProviderStatusAvailable:
Q_ASSERT( false );
break;
case PositionProviderStatusError:
html += QObject::tr( "Error when determining current location: " );
html += m_widget->model()->positionTracking()->error();
break;
}
html += QLatin1String("</p></body></html>");
m_currentLocationUi.locationLabel->setEnabled( true );
m_currentLocationUi.locationLabel->setText( html );
}
void CurrentLocationWidgetPrivate::updateActivePositionProvider( PositionProviderPlugin *plugin )
{
m_currentLocationUi.positionTrackingComboBox->blockSignals( true );
if ( !plugin ) {
m_currentLocationUi.positionTrackingComboBox->setCurrentIndex( 0 );
} else {
for( int i=0; i<m_currentLocationUi.positionTrackingComboBox->count(); ++i ) {
if ( m_currentLocationUi.positionTrackingComboBox->itemText( i ) == plugin->guiString() ) {
m_currentLocationUi.positionTrackingComboBox->setCurrentIndex( i );
break;
}
}
}
m_currentLocationUi.positionTrackingComboBox->blockSignals( false );
m_currentLocationUi.recenterLabel->setEnabled( plugin );
m_currentLocationUi.recenterComboBox->setEnabled( plugin );
m_currentLocationUi.autoZoomCheckBox->setEnabled( plugin );
}
void CurrentLocationWidgetPrivate::updateGuidanceMode()
{
const bool enabled = m_widget->model()->routingManager()->guidanceModeEnabled();
m_adjustNavigation->setAutoZoom( enabled );
m_adjustNavigation->setRecenter( enabled ? AutoNavigation::RecenterOnBorder : AutoNavigation::DontRecenter );
}
void CurrentLocationWidgetPrivate::receiveGpsCoordinates( const GeoDataCoordinates &position, qreal speed )
{
m_currentPosition = position;
QString unitString;
QString altitudeUnitString;
QString distanceUnitString;
qreal unitSpeed = 0.0;
qreal altitude = 0.0;
qreal length = m_widget->model()->positionTracking()->length( m_widget->model()->planetRadius() );
QString html = QLatin1String("<html><body>"
"<table cellspacing=\"2\" cellpadding=\"2\">"
"<tr><td>Longitude</td><td><a href=\"http://edu.kde.org/marble\">%1</a></td></tr>"
"<tr><td>Latitude</td><td><a href=\"http://edu.kde.org/marble\">%2</a></td></tr>"
"<tr><td>Altitude</td><td>%3</td></tr>"
"<tr><td>Speed</td><td>%4</td></tr>"
"<tr><td>Distance</td><td>%5</td></tr>"
"</table>"
"</body></html>");
switch ( MarbleGlobal::getInstance()->locale()->measurementSystem() ) {
case MarbleLocale::MetricSystem:
//kilometers per hour
unitString = QObject::tr("km/h");
unitSpeed = speed * HOUR2SEC * METER2KM;
altitudeUnitString = QObject::tr("m");
distanceUnitString = QObject::tr("m");
if ( length > 1000.0 ) {
length /= 1000.0;
distanceUnitString = QObject::tr("km");
}
altitude = position.altitude();
break;
case MarbleLocale::ImperialSystem:
//miles per hour
unitString = QObject::tr("m/h");
unitSpeed = speed * HOUR2SEC * METER2KM * KM2MI;
altitudeUnitString = QObject::tr("ft");
distanceUnitString = QObject::tr("ft");
altitude = position.altitude() * M2FT;
length *= M2FT;
break;
case MarbleLocale::NauticalSystem:
// nautical miles
unitString = QObject::tr("kt");
unitSpeed = speed * HOUR2SEC * METER2KM * KM2NM;
altitudeUnitString = QObject::tr("m");
distanceUnitString = QObject::tr("nm");
altitude = position.altitude();
length *= METER2KM*KM2NM;
break;
}
// TODO read this value from the incoming signal
const QString speedString = QLocale::system().toString( unitSpeed, 'f', 1);
const QString altitudeString = QString( "%1 %2" ).arg( altitude, 0, 'f', 1, QChar(' ') ).arg( altitudeUnitString );
const QString distanceString = QString( "%1 %2" ).arg( length, 0, 'f', 1, QChar(' ') ).arg( distanceUnitString );
html = html.arg( position.lonToString(), position.latToString() );
html = html.arg(altitudeString, speedString + QLatin1Char(' ') + unitString);
html = html.arg( distanceString );
m_currentLocationUi.locationLabel->setText( html );
m_currentLocationUi.showTrackCheckBox->setEnabled( true );
m_currentLocationUi.saveTrackButton->setEnabled( true );
m_currentLocationUi.clearTrackButton->setEnabled( true );
}
void CurrentLocationWidgetPrivate::changePositionProvider( const QString &provider )
{
for( const PositionProviderPlugin* plugin: m_positionProviderPlugins ) {
if ( plugin->guiString() == provider ) {
m_currentLocationUi.locationLabel->setEnabled( true );
PositionProviderPlugin* instance = plugin->newInstance();
PositionTracking *tracking = m_widget->model()->positionTracking();
tracking->setPositionProviderPlugin( instance );
m_widget->update();
return;
}
}
// requested provider not found -> disable position tracking
m_currentLocationUi.locationLabel->setEnabled( false );
- m_widget->model()->positionTracking()->setPositionProviderPlugin( 0 );
+ m_widget->model()->positionTracking()->setPositionProviderPlugin( nullptr );
m_widget->update();
}
void CurrentLocationWidgetPrivate::trackPlacemark()
{
changePositionProvider( QObject::tr( "Placemark" ) );
m_adjustNavigation->setRecenter( AutoNavigation::AlwaysRecenter );
}
void CurrentLocationWidget::setRecenterMode( int mode )
{
if ( mode >= 0 && mode <= AutoNavigation::RecenterOnBorder ) {
AutoNavigation::CenterMode centerMode = ( AutoNavigation::CenterMode ) mode;
d->m_adjustNavigation->setRecenter( centerMode );
}
}
void CurrentLocationWidget::setAutoZoom( bool autoZoom )
{
d->m_adjustNavigation->setAutoZoom( autoZoom );
}
void CurrentLocationWidgetPrivate::updateAutoZoomCheckBox( bool autoZoom )
{
m_currentLocationUi.autoZoomCheckBox->setChecked( autoZoom );
}
void CurrentLocationWidgetPrivate::updateRecenterComboBox( AutoNavigation::CenterMode centerMode )
{
m_currentLocationUi.recenterComboBox->setCurrentIndex( centerMode );
}
void CurrentLocationWidgetPrivate::centerOnCurrentLocation()
{
m_widget->centerOn(m_currentPosition, true);
}
void CurrentLocationWidgetPrivate::saveTrack()
{
QString suggested = m_lastSavePath;
QString fileName = QFileDialog::getSaveFileName(m_widget, QObject::tr("Save Track"), // krazy:exclude=qclasses
suggested.append(QLatin1Char('/') + QDateTime::currentDateTime().toString("yyyy-MM-dd_hhmmss") + QLatin1String(".kml")),
QObject::tr("KML File (*.kml)"));
if ( fileName.isEmpty() ) {
return;
}
if ( !fileName.endsWith(QLatin1String( ".kml" ), Qt::CaseInsensitive) ) {
fileName += QLatin1String(".kml");
}
QFileInfo file( fileName );
m_lastSavePath = file.absolutePath();
m_widget->model()->positionTracking()->saveTrack( fileName );
}
void CurrentLocationWidgetPrivate::openTrack()
{
QString suggested = m_lastOpenPath;
QString fileName = QFileDialog::getOpenFileName( m_widget, QObject::tr("Open Track"), // krazy:exclude=qclasses
suggested, QObject::tr("KML File (*.kml)"));
if ( !fileName.isEmpty() ) {
QFileInfo file( fileName );
m_lastOpenPath = file.absolutePath();
m_widget->model()->addGeoDataFile( fileName );
}
}
void CurrentLocationWidgetPrivate::clearTrack()
{
const int result = QMessageBox::question( m_widget,
QObject::tr( "Clear current track" ),
QObject::tr( "Are you sure you want to clear the current track?" ),
QMessageBox::Yes,
QMessageBox::No );
if ( result == QMessageBox::Yes ) {
m_widget->model()->positionTracking()->clearTrack();
m_widget->update();
m_currentLocationUi.saveTrackButton->setEnabled( false );
m_currentLocationUi.clearTrackButton->setEnabled( false );
}
}
AutoNavigation::CenterMode CurrentLocationWidget::recenterMode() const
{
return d->m_adjustNavigation->recenterMode();
}
bool CurrentLocationWidget::autoZoom() const
{
return d->m_adjustNavigation->autoZoom();
}
bool CurrentLocationWidget::trackVisible() const
{
return d->m_widget->model()->positionTracking()->trackVisible();
}
QString CurrentLocationWidget::lastOpenPath() const
{
return d->m_lastOpenPath;
}
QString CurrentLocationWidget::lastSavePath() const
{
return d->m_lastSavePath;
}
void CurrentLocationWidget::setTrackVisible( bool visible )
{
d->m_currentLocationUi.showTrackCheckBox->setChecked( visible );
d->m_widget->model()->positionTracking()->setTrackVisible( visible );
}
void CurrentLocationWidget::setLastOpenPath( const QString &path )
{
d->m_lastOpenPath = path;
}
void CurrentLocationWidget::setLastSavePath( const QString &path )
{
d->m_lastSavePath = path;
}
}
#include "moc_CurrentLocationWidget.cpp"
diff --git a/src/lib/marble/CurrentLocationWidget.h b/src/lib/marble/CurrentLocationWidget.h
index 01864a4d0..037e29516 100644
--- a/src/lib/marble/CurrentLocationWidget.h
+++ b/src/lib/marble/CurrentLocationWidget.h
@@ -1,102 +1,102 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_CURRENTLOCATIONWIDGET_H
#define MARBLE_CURRENTLOCATIONWIDGET_H
// Marble
#include "marble_export.h"
#include "AutoNavigation.h"
// Qt
#include <QWidget>
namespace Marble
{
class CurrentLocationWidgetPrivate;
class GeoDataCoordinates;
class MarbleWidget;
class PositionProviderPlugin;
class MARBLE_EXPORT CurrentLocationWidget : public QWidget
{
Q_OBJECT
public:
- explicit CurrentLocationWidget( QWidget *parent = 0, Qt::WindowFlags f = 0 );
+ explicit CurrentLocationWidget( QWidget *parent = nullptr, Qt::WindowFlags f = nullptr );
~CurrentLocationWidget() override;
/**
* @brief Set a MarbleWidget associated to this widget.
* @param widget the MarbleWidget to be set.
*/
void setMarbleWidget( MarbleWidget *widget );
AutoNavigation::CenterMode recenterMode() const;
bool autoZoom() const;
bool trackVisible() const;
QString lastOpenPath() const;
QString lastSavePath() const;
public Q_SLOTS:
/// Slot that decides whether recentering should be done
void setRecenterMode( int recenterMode );
/// Slot for Auto Zooming while navigating
void setAutoZoom( bool activate );
void setTrackVisible( bool visible );
void setLastOpenPath( const QString &path );
void setLastSavePath( const QString &path );
private:
Q_DISABLE_COPY( CurrentLocationWidget )
CurrentLocationWidgetPrivate * const d;
Q_PRIVATE_SLOT( d, void receiveGpsCoordinates( const GeoDataCoordinates &in, qreal speed ) )
Q_PRIVATE_SLOT( d, void adjustPositionTrackingStatus( PositionProviderStatus status ) )
Q_PRIVATE_SLOT( d, void changePositionProvider( const QString &provider ) )
Q_PRIVATE_SLOT( d, void centerOnCurrentLocation() )
Q_PRIVATE_SLOT( d, void trackPlacemark() )
/**
* @brief Slot for setting re-center combobox if re-centering is enabled other than from CurrentLocationWidget
* @see RoutingPlugin
*/
Q_PRIVATE_SLOT( d, void updateRecenterComboBox( AutoNavigation::CenterMode centerMode ) )
/**
* @brief Slot for toggling auto zoom checkbox if auto zooming is enabled other than from CurrentLocationWidget
* @see RoutingPlugin
*/
Q_PRIVATE_SLOT( d, void updateAutoZoomCheckBox( bool autoZoom ) )
Q_PRIVATE_SLOT( d, void updateActivePositionProvider( PositionProviderPlugin* ) )
Q_PRIVATE_SLOT( d, void updateGuidanceMode() )
Q_PRIVATE_SLOT( d, void saveTrack() )
Q_PRIVATE_SLOT( d, void openTrack() )
Q_PRIVATE_SLOT( d, void clearTrack() )
};
}
#endif
diff --git a/src/lib/marble/DownloadQueueSet.h b/src/lib/marble/DownloadQueueSet.h
index 58725a6b4..c6f61f844 100644
--- a/src/lib/marble/DownloadQueueSet.h
+++ b/src/lib/marble/DownloadQueueSet.h
@@ -1,149 +1,149 @@
// Copyright 2009 Jens-Michael Hoffmann <jmho@c-xx.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library. If not, see <http://www.gnu.org/licenses/>.
#ifndef MARBLE_DOWNLOADQUEUESET_H
#define MARBLE_DOWNLOADQUEUESET_H
#include <QList>
#include <QQueue>
#include <QObject>
#include <QSet>
#include <QStack>
#include "DownloadPolicy.h"
class QUrl;
namespace Marble
{
class HttpJob;
/**
Life of a HttpJob
=================
- Job is added to the QueueSet (by calling addJob() )
the HttpJob is put into the m_jobQueue where it waits for "activation"
signal jobAdded is emitted
- Job is activated
Job is moved from m_jobQueue to m_activeJobs and signals of the job
are connected to slots (local or HttpDownloadManager)
Job is executed by calling the jobs execute() method
now there are different possibilities:
1) Job emits jobDone (some error occurred, or canceled (kio))
Job is disconnected
signal jobRemoved is emitted
Job is either moved from m_activeJobs to m_retryQueue
or destroyed and blacklisted
2) Job emits redirected
Job is removed from m_activeJobs, disconnected and destroyed
signal jobRemoved is emitted
(HttpDownloadManager creates new Job with new source url)
3) Job emits dataReceived
Job is removed from m_activeJobs, disconnected and destroyed
signal jobRemoved is emitted
so we can conclude following rules:
- Job is only connected to signals when in "active" state
questions:
- update of initiatorId needed?
"We update the initiatorId as the previous initiator
likely doesn't exist anymore"
- blacklist or black list?
*/
class DownloadQueueSet: public QObject
{
Q_OBJECT
public:
- explicit DownloadQueueSet( QObject * const parent = 0 );
- explicit DownloadQueueSet( const DownloadPolicy& policy, QObject * const parent = 0 );
+ explicit DownloadQueueSet( QObject * const parent = nullptr );
+ explicit DownloadQueueSet( const DownloadPolicy& policy, QObject * const parent = nullptr );
~DownloadQueueSet() override;
DownloadPolicy downloadPolicy() const;
void setDownloadPolicy( const DownloadPolicy& );
bool canAcceptJob( const QUrl& sourceUrl,
const QString& destinationFileName ) const;
void addJob( HttpJob * const job );
void activateJobs();
void retryJobs();
void purgeJobs();
Q_SIGNALS:
void jobAdded();
void jobRemoved();
void jobRetry();
void jobFinished( const QByteArray& data, const QString& destinationFileName,
const QString& id );
void jobRedirected( const QUrl& newSourceUrl, const QString& destinationFileName,
const QString& id, DownloadUsage );
void progressChanged( int active, int queued );
private Q_SLOTS:
void finishJob( HttpJob * job, const QByteArray& data );
void redirectJob( HttpJob * job, const QUrl& newSourceUrl );
void retryOrBlacklistJob( HttpJob * job, const int errorCode );
private:
void activateJob( HttpJob * const job );
void deactivateJob( HttpJob * const job );
bool jobIsActive( const QString& destinationFileName ) const;
bool jobIsQueued( const QString& destinationFileName ) const;
bool jobIsWaitingForRetry( const QString& destinationFileName ) const;
bool jobIsBlackListed( const QUrl& sourceUrl ) const;
DownloadPolicy m_downloadPolicy;
/** This is the first stage a job enters, from this queue it will get
* into the activatedJobs container.
*/
class JobStack
{
public:
bool contains( const QString& destinationFileName ) const;
int count() const;
bool isEmpty() const;
HttpJob * pop();
void push( HttpJob * const );
private:
QStack<HttpJob*> m_jobs;
QSet<QString> m_jobsContent;
};
JobStack m_jobs;
/// Contains the jobs which are currently being downloaded.
QList<HttpJob*> m_activeJobs;
/** Contains jobs which failed to download and which are scheduled for
* retry according to retry settings.
*/
QQueue<HttpJob*> m_retryQueue;
/// Contains the blacklisted source urls
QSet<QString> m_jobBlackList;
};
}
#endif
diff --git a/src/lib/marble/DownloadRegion.cpp b/src/lib/marble/DownloadRegion.cpp
index 5980df8d6..1cb9b01f8 100644
--- a/src/lib/marble/DownloadRegion.cpp
+++ b/src/lib/marble/DownloadRegion.cpp
@@ -1,257 +1,257 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "DownloadRegion.h"
#include "MarbleModel.h"
#include "MarbleMap.h"
#include "MarbleMath.h"
#include "MarbleDebug.h"
#include "TextureLayer.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataLineString.h"
#include "GeoSceneAbstractTileProjection.h"
#include "TileCoordsPyramid.h"
namespace Marble {
class DownloadRegionPrivate
{
public:
MarbleModel* m_marbleModel;
QPair<int,int> m_tileLevelRange;
int m_visibleTileLevel;
DownloadRegionPrivate();
int rad2PixelX( qreal const lon, const TextureLayer *textureLayer ) const;
int rad2PixelY( qreal const lat, const TextureLayer *textureLayer ) const;
};
-DownloadRegionPrivate::DownloadRegionPrivate() : m_marbleModel( 0 ),
+DownloadRegionPrivate::DownloadRegionPrivate() : m_marbleModel( nullptr ),
m_tileLevelRange( 0, 0 ), m_visibleTileLevel( 0 )
{
// nothing to do
}
// copied from AbstractScanlineTextureMapper and slightly adjusted
int DownloadRegionPrivate::rad2PixelX( qreal const lon, const TextureLayer *textureLayer ) const
{
qreal const globalWidth = textureLayer->tileSize().width()
* textureLayer->tileColumnCount( m_visibleTileLevel );
return static_cast<int>( globalWidth * 0.5 + lon * ( globalWidth / ( 2.0 * M_PI ) ) );
}
// copied from AbstractScanlineTextureMapper and slightly adjusted
int DownloadRegionPrivate::rad2PixelY( qreal const lat, const TextureLayer *textureLayer ) const
{
qreal const globalHeight = textureLayer->tileSize().height()
* textureLayer->tileRowCount( m_visibleTileLevel );
qreal const normGlobalHeight = globalHeight / M_PI;
switch (textureLayer->tileProjection()->type()) {
case GeoSceneAbstractTileProjection::Equirectangular:
return static_cast<int>( globalHeight * 0.5 - lat * normGlobalHeight );
case GeoSceneAbstractTileProjection::Mercator:
if ( fabs( lat ) < 1.4835 )
return static_cast<int>( globalHeight * 0.5 - gdInv( lat ) * 0.5 * normGlobalHeight );
if ( lat >= +1.4835 )
return static_cast<int>( globalHeight * 0.5 - 3.1309587 * 0.5 * normGlobalHeight );
if ( lat <= -1.4835 )
return static_cast<int>( globalHeight * 0.5 + 3.1309587 * 0.5 * normGlobalHeight );
}
// Dummy value to avoid a warning.
return 0;
}
DownloadRegion::DownloadRegion( QObject* parent ) : QObject( parent ),
d( new DownloadRegionPrivate )
{
// nothing to do
}
void DownloadRegion::setMarbleModel( MarbleModel* model )
{
d->m_marbleModel = model;
}
DownloadRegion::~DownloadRegion()
{
delete d;
}
void DownloadRegion::setTileLevelRange( const int minimumTileLevel, const int maximumTileLevel )
{
Q_ASSERT( minimumTileLevel >= 0 );
Q_ASSERT( maximumTileLevel >= 0 );
Q_ASSERT( minimumTileLevel <= maximumTileLevel );
d->m_tileLevelRange.first = minimumTileLevel;
d->m_tileLevelRange.second = maximumTileLevel;
}
QVector<TileCoordsPyramid> DownloadRegion::region( const TextureLayer *textureLayer, const GeoDataLatLonAltBox &downloadRegion ) const
{
Q_ASSERT( textureLayer );
int const westX = d->rad2PixelX( downloadRegion.west(), textureLayer );
int const northY = d->rad2PixelY( downloadRegion.north(), textureLayer );
int const eastX = d->rad2PixelX( downloadRegion.east(), textureLayer );
int const southY = d->rad2PixelY( downloadRegion.south(), textureLayer );
// FIXME: remove this stuff
mDebug() << "DownloadRegionDialog downloadRegion:"
<< "north:" << downloadRegion.north()
<< "south:" << downloadRegion.south()
<< "east:" << downloadRegion.east()
<< "west:" << downloadRegion.west();
mDebug() << "north/west (x/y):" << westX << northY;
mDebug() << "south/east (x/y):" << eastX << southY;
int const tileWidth = textureLayer->tileSize().width();
int const tileHeight = textureLayer->tileSize().height();
mDebug() << "DownloadRegionDialog downloadRegion: tileSize:" << tileWidth << tileHeight;
int const visibleLevelX1 = qMin( westX, eastX );
int const visibleLevelY1 = qMin( northY, southY );
int const visibleLevelX2 = qMax( westX, eastX );
int const visibleLevelY2 = qMax( northY, southY );
mDebug() << "visible level pixel coords (level/x1/y1/x2/y2):" << d->m_visibleTileLevel
<< visibleLevelX1 << visibleLevelY1 << visibleLevelX2 << visibleLevelY2;
int bottomLevelX1, bottomLevelY1, bottomLevelX2, bottomLevelY2;
// the pixel coords calculated above are referring to the visible tile level,
// if the bottom level is a different level, we have to take it into account
if ( d->m_visibleTileLevel > d->m_tileLevelRange.second ) {
int const deltaLevel = d->m_visibleTileLevel - d->m_tileLevelRange.second;
bottomLevelX1 = visibleLevelX1 >> deltaLevel;
bottomLevelY1 = visibleLevelY1 >> deltaLevel;
bottomLevelX2 = visibleLevelX2 >> deltaLevel;
bottomLevelY2 = visibleLevelY2 >> deltaLevel;
}
else if ( d->m_visibleTileLevel < d->m_tileLevelRange.second ) {
int const deltaLevel = d->m_tileLevelRange.second - d->m_visibleTileLevel;
bottomLevelX1 = visibleLevelX1 << deltaLevel;
bottomLevelY1 = visibleLevelY1 << deltaLevel;
bottomLevelX2 = visibleLevelX2 << deltaLevel;
bottomLevelY2 = visibleLevelY2 << deltaLevel;
}
else {
bottomLevelX1 = visibleLevelX1;
bottomLevelY1 = visibleLevelY1;
bottomLevelX2 = visibleLevelX2;
bottomLevelY2 = visibleLevelY2;
}
mDebug() << "bottom level pixel coords (level/x1/y1/x2/y2):"
<< d->m_tileLevelRange.second
<< bottomLevelX1 << bottomLevelY1 << bottomLevelX2 << bottomLevelY2;
TileCoordsPyramid coordsPyramid( d->m_tileLevelRange.first, d->m_tileLevelRange.second );
QRect bottomLevelTileCoords;
bottomLevelTileCoords.setCoords
( bottomLevelX1 / tileWidth,
bottomLevelY1 / tileHeight,
bottomLevelX2 / tileWidth + ( bottomLevelX2 % tileWidth > 0 ? 1 : 0 ),
bottomLevelY2 / tileHeight + ( bottomLevelY2 % tileHeight > 0 ? 1 : 0 ));
mDebug() << "bottom level tile coords: (x1/y1/size):" << bottomLevelTileCoords;
coordsPyramid.setBottomLevelCoords( bottomLevelTileCoords );
mDebug() << "tiles count:" << coordsPyramid.tilesCount( );
QVector<TileCoordsPyramid> pyramid;
pyramid << coordsPyramid;
return pyramid;
}
void DownloadRegion::setVisibleTileLevel(const int tileLevel)
{
d->m_visibleTileLevel = tileLevel;
}
QVector<TileCoordsPyramid> DownloadRegion::fromPath( const TextureLayer *textureLayer, qreal offset, const GeoDataLineString &waypoints ) const
{
if ( !d->m_marbleModel ) {
return QVector<TileCoordsPyramid>();
}
int const topLevel = d->m_tileLevelRange.first;
int const bottomLevel = d->m_tileLevelRange.second;
TileCoordsPyramid coordsPyramid( topLevel, bottomLevel );
int const tileWidth = textureLayer->tileSize().width();
int const tileHeight = textureLayer->tileSize().height();
qreal radius = d->m_marbleModel->planetRadius();
QVector<TileCoordsPyramid> pyramid;
qreal radianOffset = offset / radius;
for( int i = 1; i < waypoints.size(); ++i ) {
GeoDataCoordinates position = waypoints[i];
qreal lonCenter = position.longitude();
qreal latCenter = position.latitude();
// coordinates of the of the vertices of the square(topleft and bottomright) at an offset distance from the waypoint
qreal latNorth = asin( sin( latCenter ) * cos( radianOffset ) + cos( latCenter ) * sin( radianOffset ) * cos( 7*M_PI/4 ) );
qreal dlonWest = atan2( sin( 7*M_PI/4 ) * sin( radianOffset ) * cos( latCenter ), cos( radianOffset ) - sin( latCenter ) * sin( latNorth ) );
qreal lonWest = fmod( lonCenter - dlonWest + M_PI, 2*M_PI ) - M_PI;
qreal latSouth = asin( sin( latCenter ) * cos( radianOffset ) + cos( latCenter ) * sin( radianOffset ) * cos( 3*M_PI/4 ) );
qreal dlonEast = atan2( sin( 3*M_PI/4 ) * sin( radianOffset ) * cos( latCenter ), cos( radianOffset ) - sin( latCenter ) * sin( latSouth ) );
qreal lonEast = fmod( lonCenter - dlonEast+M_PI, 2*M_PI ) - M_PI;
int const northY = d->rad2PixelY( latNorth, textureLayer );
int const southY = d->rad2PixelY( latSouth, textureLayer );
int const eastX = d->rad2PixelX( lonEast, textureLayer );
int const westX = d->rad2PixelX( lonWest, textureLayer );
int const west = qMin( westX, eastX );
int const north = qMin( northY, southY );
int const east = qMax( westX, eastX );
int const south = qMax( northY, southY );
int bottomLevelTileX1 = 0;
int bottomLevelTileY1 = 0;
int bottomLevelTileX2 = 0;
int bottomLevelTileY2 = 0;
if ( d->m_visibleTileLevel > d->m_tileLevelRange.second ) {
int const deltaLevel = d->m_visibleTileLevel - d->m_tileLevelRange.second;
bottomLevelTileX1 = west >> deltaLevel;
bottomLevelTileY1 = north >> deltaLevel;
bottomLevelTileX2 = east >> deltaLevel;
bottomLevelTileY2 = south >> deltaLevel;
}
else if ( d->m_visibleTileLevel < bottomLevel ) {
int const deltaLevel = bottomLevel - d->m_visibleTileLevel;
bottomLevelTileX1 = west << deltaLevel;
bottomLevelTileY1 = north << deltaLevel;
bottomLevelTileX2 = east << deltaLevel;
bottomLevelTileY2 = south << deltaLevel;
}
else {
bottomLevelTileX1 = west;
bottomLevelTileY1 = north;
bottomLevelTileX2 = east;
bottomLevelTileY2 = south;
}
QRect waypointRegion;
//square region around the waypoint
waypointRegion.setCoords( bottomLevelTileX1/tileWidth, bottomLevelTileY1/tileHeight,
bottomLevelTileX2/tileWidth, bottomLevelTileY2/tileHeight );
coordsPyramid.setBottomLevelCoords( waypointRegion );
pyramid << coordsPyramid;
}
return pyramid;
}
}
#include "moc_DownloadRegion.cpp"
diff --git a/src/lib/marble/DownloadRegion.h b/src/lib/marble/DownloadRegion.h
index dbdfd859a..f28ad717c 100644
--- a/src/lib/marble/DownloadRegion.h
+++ b/src/lib/marble/DownloadRegion.h
@@ -1,56 +1,56 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DOWNLOADREGION_H
#define MARBLE_DOWNLOADREGION_H
#include <QObject>
#include <QVector>
#include "marble_export.h"
namespace Marble
{
class DownloadRegionPrivate;
class GeoDataLatLonAltBox;
class GeoDataLineString;
class TileCoordsPyramid;
class MarbleModel;
class TextureLayer;
class MARBLE_EXPORT DownloadRegion : public QObject
{
Q_OBJECT
public:
- explicit DownloadRegion( QObject* parent=0 );
+ explicit DownloadRegion( QObject* parent=nullptr );
void setMarbleModel( MarbleModel *model );
~DownloadRegion() override;
void setTileLevelRange( int const minimumTileLevel, int const maximumTileLevel );
QVector<TileCoordsPyramid> region( const TextureLayer *textureLayer, const GeoDataLatLonAltBox &region ) const;
void setVisibleTileLevel( int const tileLevel );
/**
* @brief calculates the region to be downloaded around a path
*/
QVector<TileCoordsPyramid> fromPath( const TextureLayer *textureLayer, qreal offset, const GeoDataLineString &path ) const;
private:
DownloadRegionPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/DownloadRegionDialog.cpp b/src/lib/marble/DownloadRegionDialog.cpp
index 98fac1e8e..abe32035e 100644
--- a/src/lib/marble/DownloadRegionDialog.cpp
+++ b/src/lib/marble/DownloadRegionDialog.cpp
@@ -1,514 +1,514 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
//
#include "DownloadRegionDialog.h"
#include <cmath>
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QHideEvent>
#include <QLabel>
#include <QPushButton>
#include <QRadioButton>
#include <QShowEvent>
#include <QVBoxLayout>
#include <QSpinBox>
#include <QScrollArea>
#include <QSet>
#include "GeoDataLatLonAltBox.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "LatLonBoxWidget.h"
#include "TextureLayer.h"
#include "TileId.h"
#include "TileCoordsPyramid.h"
#include "TileLevelRangeWidget.h"
#include "TileLoaderHelper.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingModel.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLineString.h"
#include "DownloadRegion.h"
#include "GeoSceneDocument.h"
#include "GeoSceneMap.h"
#include "Route.h"
namespace Marble
{
int const maxTilesCount = 100000;
int const minimumRouteOffset = 0;
int const maximumRouteOffset = 10000;
int averageTileSize = 13; //The average size of a tile in kilobytes
class Q_DECL_HIDDEN DownloadRegionDialog::Private
{
public:
Private( MarbleWidget *const widget, QDialog * const dialog );
QWidget * createSelectionMethodBox();
QLayout * createTilesCounter();
QWidget * createOkCancelButtonBox();
bool hasRoute() const;
bool hasTextureLayer() const;
QDialog * m_dialog;
QRadioButton * m_visibleRegionMethodButton;
QRadioButton * m_specifiedRegionMethodButton;
LatLonBoxWidget * m_latLonBoxWidget;
TileLevelRangeWidget * m_tileLevelRangeWidget;
QRadioButton *m_routeDownloadMethodButton;
QLabel* m_routeOffsetLabel;
QDoubleSpinBox *m_routeOffsetSpinBox;
QLabel * m_tilesCountLabel;
QLabel * m_tileSizeInfo;
QPushButton * m_okButton;
QPushButton * m_applyButton;
TextureLayer const * m_textureLayer;
int m_visibleTileLevel;
MarbleModel const*const m_model;
MarbleWidget *const m_widget;
SelectionMethod m_selectionMethod;
GeoDataLatLonAltBox m_visibleRegion;
RoutingModel *m_routingModel;
DownloadRegion m_downloadRegion;
};
DownloadRegionDialog::Private::Private( MarbleWidget * const widget,
QDialog * const dialog )
: m_dialog( dialog ),
- m_visibleRegionMethodButton( 0 ),
- m_specifiedRegionMethodButton( 0 ),
+ m_visibleRegionMethodButton( nullptr ),
+ m_specifiedRegionMethodButton( nullptr ),
m_latLonBoxWidget( new LatLonBoxWidget ),
m_tileLevelRangeWidget( new TileLevelRangeWidget ),
- m_routeDownloadMethodButton( 0 ),
- m_routeOffsetLabel( 0 ),
- m_routeOffsetSpinBox( 0 ),
- m_tilesCountLabel( 0 ),
- m_tileSizeInfo( 0 ),
- m_okButton( 0 ),
- m_applyButton( 0 ),
+ m_routeDownloadMethodButton( nullptr ),
+ m_routeOffsetLabel( nullptr ),
+ m_routeOffsetSpinBox( nullptr ),
+ m_tilesCountLabel( nullptr ),
+ m_tileSizeInfo( nullptr ),
+ m_okButton( nullptr ),
+ m_applyButton( nullptr ),
m_textureLayer( widget->textureLayer() ),
m_visibleTileLevel( m_textureLayer->tileZoomLevel() ),
m_model( widget->model() ),
m_widget( widget ),
m_selectionMethod( VisibleRegionMethod ),
m_visibleRegion(),
m_routingModel( widget->model()->routingManager()->routingModel() )
{
m_latLonBoxWidget->setEnabled( false );
m_latLonBoxWidget->setLatLonBox( m_visibleRegion );
m_tileLevelRangeWidget->setDefaultLevel( m_visibleTileLevel );
m_downloadRegion.setMarbleModel( widget->model() );
}
QWidget * DownloadRegionDialog::Private::createSelectionMethodBox()
{
m_visibleRegionMethodButton = new QRadioButton( tr( "Visible region" ) );
m_specifiedRegionMethodButton = new QRadioButton( tr( "Specify region" ) );
m_routeDownloadMethodButton = new QRadioButton( tr( "Download Route" ) );
m_routeDownloadMethodButton->setToolTip( tr( "Enabled when a route exists" ) );
m_routeDownloadMethodButton->setEnabled( hasRoute() );
m_routeDownloadMethodButton->setChecked( hasRoute() );
m_routeOffsetSpinBox = new QDoubleSpinBox();
m_routeOffsetSpinBox->setEnabled( hasRoute() );
m_routeOffsetSpinBox->setRange( minimumRouteOffset, maximumRouteOffset );
int defaultOffset = 500;
m_routeOffsetSpinBox->setValue( defaultOffset );
m_routeOffsetSpinBox->setSingleStep( 100 );
m_routeOffsetSpinBox->setSuffix( " m" );
m_routeOffsetSpinBox->setDecimals( 0 );
m_routeOffsetSpinBox->setAlignment( Qt::AlignRight );
m_routeOffsetLabel = new QLabel( tr( "Offset from route:" ) );
m_routeOffsetLabel->setAlignment( Qt::AlignHCenter );
connect( m_visibleRegionMethodButton, SIGNAL(toggled(bool)),
m_dialog, SLOT(toggleSelectionMethod()) );
connect( m_specifiedRegionMethodButton, SIGNAL(toggled(bool)),
m_dialog, SLOT(toggleSelectionMethod()));
connect( m_routeDownloadMethodButton, SIGNAL(toggled(bool)),
m_dialog, SLOT(toggleSelectionMethod()) );
connect( m_routingModel, SIGNAL(modelReset()), m_dialog, SLOT(updateRouteDialog()) );
connect( m_routingModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
m_dialog, SLOT(updateRouteDialog()) );
connect( m_routingModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
m_dialog, SLOT(updateRouteDialog()) );
QHBoxLayout *routeOffsetLayout = new QHBoxLayout;
routeOffsetLayout->addWidget( m_routeOffsetLabel );
routeOffsetLayout->insertSpacing( 0, 25 );
routeOffsetLayout->addWidget( m_routeOffsetSpinBox );
QVBoxLayout * const routeLayout = new QVBoxLayout;
routeLayout->addWidget( m_routeDownloadMethodButton );
routeLayout->addLayout( routeOffsetLayout );
QVBoxLayout * const layout = new QVBoxLayout;
layout->addWidget( m_visibleRegionMethodButton );
layout->addLayout( routeLayout );
layout->addWidget( m_specifiedRegionMethodButton );
layout->addWidget( m_latLonBoxWidget );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
m_specifiedRegionMethodButton->setVisible( !smallScreen );
m_latLonBoxWidget->setVisible( !smallScreen );
if ( smallScreen ) {
QWidget * const selectionMethodWidget = new QWidget;
selectionMethodWidget->setLayout( layout );
return selectionMethodWidget;
} else {
QGroupBox * const selectionMethodBox = new QGroupBox( tr( "Selection Method" ) );
selectionMethodBox->setLayout( layout );
return selectionMethodBox;
}
}
QLayout * DownloadRegionDialog::Private::createTilesCounter()
{
QLabel * const description = new QLabel( tr( "Number of tiles to download:" ) );
m_tilesCountLabel = new QLabel;
m_tileSizeInfo = new QLabel;
QHBoxLayout * const tilesCountLayout = new QHBoxLayout;
tilesCountLayout->addWidget( description );
tilesCountLayout->addWidget( m_tilesCountLabel );
//tilesCountLayout->insertSpacing( 0, 5 );
QVBoxLayout * const layout = new QVBoxLayout;
layout->addLayout( tilesCountLayout );
layout->addWidget( m_tileSizeInfo );
return layout;
}
QWidget * DownloadRegionDialog::Private::createOkCancelButtonBox()
{
QDialogButtonBox * const buttonBox = new QDialogButtonBox;
m_okButton = buttonBox->addButton( QDialogButtonBox::Ok );
m_applyButton = buttonBox->addButton( QDialogButtonBox::Apply );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
buttonBox->removeButton( m_applyButton );
m_applyButton->setVisible( false );
}
buttonBox->addButton( QDialogButtonBox::Cancel );
connect( buttonBox, SIGNAL(accepted()), m_dialog, SLOT(accept()) );
connect( buttonBox, SIGNAL(rejected()), m_dialog, SLOT(reject()) );
connect( m_applyButton, SIGNAL(clicked()), m_dialog, SIGNAL(applied()) );
return buttonBox;
}
bool DownloadRegionDialog::Private::hasRoute() const
{
return !m_routingModel->route().path().isEmpty();
}
bool DownloadRegionDialog::Private::hasTextureLayer() const
{
return m_model->mapTheme()->map()->hasTextureLayers();
}
DownloadRegionDialog::DownloadRegionDialog( MarbleWidget *const widget, QWidget * const parent,
Qt::WindowFlags const f )
: QDialog( parent, f ),
d( new Private( widget, this ))
{
setWindowTitle( tr( "Download Region" ));
QVBoxLayout * const layout = new QVBoxLayout;
layout->addWidget( d->createSelectionMethodBox() );
layout->addWidget( d->m_tileLevelRangeWidget );
layout->addLayout( d->createTilesCounter() );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
QWidget* widget = new QWidget( this );
widget->setLayout( layout );
QScrollArea* scrollArea = new QScrollArea( this );
scrollArea->setFrameShape( QFrame::NoFrame );
scrollArea->setWidget( widget );
QVBoxLayout * const mainLayout = new QVBoxLayout;
mainLayout->addWidget( scrollArea );
mainLayout->addWidget( d->createOkCancelButtonBox() );
setLayout( mainLayout );
} else {
layout->addWidget( d->createOkCancelButtonBox() );
setLayout( layout );
}
connect( d->m_latLonBoxWidget, SIGNAL(valueChanged()), SLOT(updateTilesCount()) );
connect( d->m_tileLevelRangeWidget, SIGNAL(topLevelChanged(int)),
SLOT(updateTilesCount()) );
connect( d->m_tileLevelRangeWidget, SIGNAL(bottomLevelChanged(int)),
SLOT(updateTilesCount()) );
connect( d->m_routeOffsetSpinBox, SIGNAL(valueChanged(double)), SLOT(updateTilesCount()) );
connect( d->m_routeOffsetSpinBox, SIGNAL(valueChanged(double)), SLOT(setOffsetUnit()) );
connect( d->m_model, SIGNAL(themeChanged(QString)), SLOT(updateTilesCount()) );
}
DownloadRegionDialog::~DownloadRegionDialog()
{
delete d;
}
void DownloadRegionDialog::setAllowedTileLevelRange( int const minimumTileLevel,
int const maximumTileLevel )
{
d->m_tileLevelRangeWidget->setAllowedLevelRange( minimumTileLevel, maximumTileLevel );
}
void DownloadRegionDialog::setVisibleTileLevel( int const tileLevel )
{
d->m_visibleTileLevel = tileLevel;
d->m_tileLevelRangeWidget->setDefaultLevel( tileLevel );
d->m_downloadRegion.setVisibleTileLevel( tileLevel );
}
void DownloadRegionDialog::setSelectionMethod( SelectionMethod const selectionMethod )
{
// block signals to prevent infinite recursion:
// radioButton->setChecked() -> toggleSelectionMethod() -> setSelectionMethod()
// -> radioButton->setChecked() -> ...
d->m_visibleRegionMethodButton->blockSignals( true );
d->m_specifiedRegionMethodButton->blockSignals( true );
d->m_routeDownloadMethodButton->blockSignals( true );
d->m_selectionMethod = selectionMethod;
switch ( selectionMethod ) {
case VisibleRegionMethod:
d->m_visibleRegionMethodButton->setChecked( true );
d->m_routeOffsetLabel->setEnabled( false );
d->m_routeOffsetSpinBox->setEnabled( false );
d->m_latLonBoxWidget->setEnabled( false );
setSpecifiedLatLonAltBox( d->m_visibleRegion );
break;
case SpecifiedRegionMethod:
d->m_specifiedRegionMethodButton->setChecked( true );
d->m_routeOffsetLabel->setEnabled( false );
d->m_routeOffsetSpinBox->setEnabled( false );
d->m_latLonBoxWidget->setEnabled( true );
break;
case RouteDownloadMethod:
d->m_routeDownloadMethodButton->setChecked( true );
d->m_routeOffsetLabel->setEnabled( true );
d->m_routeOffsetSpinBox->setEnabled( true );
d->m_latLonBoxWidget->setEnabled( false );
}
updateTilesCount();
d->m_visibleRegionMethodButton->blockSignals( false );
d->m_specifiedRegionMethodButton->blockSignals( false );
d->m_routeDownloadMethodButton->blockSignals( false );
}
QVector<TileCoordsPyramid> DownloadRegionDialog::region() const
{
if ( !d->hasTextureLayer() ) {
return QVector<TileCoordsPyramid>();
}
d->m_downloadRegion.setTileLevelRange( d->m_tileLevelRangeWidget->topLevel(),
d->m_tileLevelRangeWidget->bottomLevel() );
d->m_downloadRegion.setVisibleTileLevel( d->m_visibleTileLevel );
// check whether "visible region" or "lat/lon region" is selection method
GeoDataLatLonAltBox downloadRegion;
switch ( d->m_selectionMethod ) {
case VisibleRegionMethod:
downloadRegion = d->m_visibleRegion;
break;
case SpecifiedRegionMethod:
downloadRegion = GeoDataLatLonAltBox( d->m_latLonBoxWidget->latLonBox(), 0, 0 );
break;
case RouteDownloadMethod:
qreal offset = d->m_routeOffsetSpinBox->value();
if (d->m_routeOffsetSpinBox->suffix() == QLatin1String(" km")) {
offset *= KM2METER;
}
const GeoDataLineString waypoints = d->m_model->routingManager()->routingModel()->route().path();
return d->m_downloadRegion.fromPath( d->m_textureLayer, offset, waypoints );
break;
}
return d->m_downloadRegion.region( d->m_textureLayer, downloadRegion );
}
void DownloadRegionDialog::setSpecifiedLatLonAltBox( GeoDataLatLonAltBox const & region )
{
d->m_latLonBoxWidget->setLatLonBox( region );
}
void DownloadRegionDialog::setVisibleLatLonAltBox( GeoDataLatLonAltBox const & region )
{
d->m_visibleRegion = region;
// update lat/lon widget only if not active to prevent that users unintentionally loose
// entered values
if ( d->m_selectionMethod == VisibleRegionMethod ) {
setSpecifiedLatLonAltBox( region );
}
updateTilesCount();
}
void DownloadRegionDialog::updateTextureLayer()
{
mDebug() << "DownloadRegionDialog::updateTextureLayer";
updateTilesCount();
}
void DownloadRegionDialog::hideEvent( QHideEvent * event )
{
disconnect( d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this, SLOT(setVisibleLatLonAltBox(GeoDataLatLonAltBox)) );
disconnect( d->m_widget, SIGNAL(themeChanged(QString)),
this, SLOT(updateTextureLayer()) );
emit hidden();
event->accept();
}
void DownloadRegionDialog::showEvent( QShowEvent * event )
{
connect( d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this, SLOT(setVisibleLatLonAltBox(GeoDataLatLonAltBox)) );
connect( d->m_widget, SIGNAL(themeChanged(QString)),
this, SLOT(updateTextureLayer()) );
emit shown();
event->accept();
}
void DownloadRegionDialog::toggleSelectionMethod()
{
// TODO:QButtonGroup would be easier to handle
switch ( d->m_selectionMethod ) {
case VisibleRegionMethod:
if( d->m_specifiedRegionMethodButton->isChecked() ) {
setSelectionMethod( SpecifiedRegionMethod );
}
else if( d->m_routeDownloadMethodButton->isChecked() ) {
setSelectionMethod( RouteDownloadMethod );
}
break;
case SpecifiedRegionMethod:
if( d->m_visibleRegionMethodButton->isChecked() ) {
setSelectionMethod( VisibleRegionMethod );
}
else if ( d->m_routeDownloadMethodButton->isChecked() ) {
setSelectionMethod( RouteDownloadMethod );
}
break;
case RouteDownloadMethod:
if( d->m_specifiedRegionMethodButton->isChecked() ) {
setSelectionMethod( SpecifiedRegionMethod );
}
else if ( d->m_visibleRegionMethodButton->isChecked() ) {
setSelectionMethod( VisibleRegionMethod );
}
break;
}
}
void DownloadRegionDialog::updateTilesCount()
{
if ( !isVisible() || !d->hasTextureLayer() ) {
return;
}
qint64 tilesCount = 0;
QString themeId( d->m_model->mapThemeId() );
QVector<TileCoordsPyramid> const pyramid = region();
Q_ASSERT( !pyramid.isEmpty() );
if( pyramid.size() == 1 ) {
tilesCount = pyramid[0].tilesCount();
}
else {
for( int level = pyramid[0].bottomLevel(); level>= pyramid[0].topLevel(); --level ) {
QSet<TileId> tileIdSet;
for( int i = 0; i < pyramid.size(); ++i ) {
QRect const coords = pyramid[i].coords( level );
int x1, y1, x2, y2;
coords.getCoords( &x1, &y1, &x2, &y2 );
for ( int x = x1; x <= x2; ++x ) {
for ( int y = y1; y <= y2; ++y ) {
TileId const tileId( 0, level, x, y );
tileIdSet.insert( tileId );
}
}
}
tilesCount += tileIdSet.count();
}
}
if ( tilesCount > maxTilesCount ) {
d->m_tileSizeInfo->setToolTip( QString() );
//~ singular There is a limit of %n tile to download.
//~ plural There is a limit of %n tiles to download.
d->m_tileSizeInfo->setText( tr( "There is a limit of %n tile(s) to download.", "",
maxTilesCount ) );
} else if (themeId == QLatin1String("earth/openstreetmap/openstreetmap.dgml")) {
qreal tileDownloadSize = tilesCount * averageTileSize;
d->m_tileSizeInfo->setToolTip( tr( "Approximate size of the tiles to be downloaded" ) );
if( tileDownloadSize > 1024 ) {
tileDownloadSize = tileDownloadSize / 1024;
d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 MB" ).arg( ceil( tileDownloadSize ) ) );
}
else {
d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 kB" ).arg( tileDownloadSize ) );
}
}
else {
d->m_tileSizeInfo->setToolTip( QString() );
d->m_tileSizeInfo->clear();
}
d->m_tilesCountLabel->setText( QString::number( tilesCount ) );
bool const tilesCountWithinLimits = tilesCount > 0 && tilesCount <= maxTilesCount;
d->m_okButton->setEnabled( tilesCountWithinLimits );
d->m_applyButton->setEnabled( tilesCountWithinLimits );
}
void DownloadRegionDialog::updateRouteDialog()
{
d->m_routeDownloadMethodButton->setEnabled( d->hasRoute() );
d->m_routeDownloadMethodButton->setChecked( d->hasRoute() );
if( !d->hasRoute() ) {
setSelectionMethod( VisibleRegionMethod );
}
}
void DownloadRegionDialog::setOffsetUnit()
{
qreal offset = d->m_routeOffsetSpinBox->value();
if( offset >= 1100 ) {
d->m_routeOffsetSpinBox->setSuffix( " km" );
d->m_routeOffsetSpinBox->setRange( minimumRouteOffset * METER2KM, maximumRouteOffset * METER2KM );
d->m_routeOffsetSpinBox->setDecimals( 1 );
d->m_routeOffsetSpinBox->setValue( offset * METER2KM );
d->m_routeOffsetSpinBox->setSingleStep( 0.1 );
}
else if (offset <= 1 && d->m_routeOffsetSpinBox->suffix() == QLatin1String(" km")) {
d->m_routeOffsetSpinBox->setSuffix( " m" );
d->m_routeOffsetSpinBox->setRange( minimumRouteOffset, maximumRouteOffset );
d->m_routeOffsetSpinBox->setDecimals( 0 );
d->m_routeOffsetSpinBox->setValue( offset * KM2METER );
d->m_routeOffsetSpinBox->setSingleStep( 100 );
}
}
}
#include "moc_DownloadRegionDialog.cpp"
diff --git a/src/lib/marble/DownloadRegionDialog.h b/src/lib/marble/DownloadRegionDialog.h
index f2b550962..0536fe8af 100644
--- a/src/lib/marble/DownloadRegionDialog.h
+++ b/src/lib/marble/DownloadRegionDialog.h
@@ -1,80 +1,80 @@
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library. If not, see <http://www.gnu.org/licenses/>.
#ifndef MARBLE_DOWNLOADREGIONDIALOG_H
#define MARBLE_DOWNLOADREGIONDIALOG_H
#include <QDialog>
#include <QVector>
#include "marble_export.h"
namespace Marble
{
class GeoDataLatLonAltBox;
class TileCoordsPyramid;
class MarbleWidget;
class MARBLE_EXPORT DownloadRegionDialog: public QDialog
{
Q_OBJECT
public:
enum SelectionMethod { VisibleRegionMethod, SpecifiedRegionMethod, RouteDownloadMethod };
- explicit DownloadRegionDialog( MarbleWidget *const widget, QWidget * const parent = 0,
- Qt::WindowFlags const f = 0 );
+ explicit DownloadRegionDialog( MarbleWidget *const widget, QWidget * const parent = nullptr,
+ Qt::WindowFlags const f = nullptr );
~DownloadRegionDialog() override;
void setAllowedTileLevelRange( int const minimumTileLevel,
int const maximumTileLevel );
void setVisibleTileLevel( int const tileLevel );
void setSelectionMethod( SelectionMethod const );
QVector<TileCoordsPyramid> region() const;
public Q_SLOTS:
void setSpecifiedLatLonAltBox( GeoDataLatLonAltBox const & );
void setVisibleLatLonAltBox( GeoDataLatLonAltBox const & );
void updateTextureLayer();
Q_SIGNALS:
/// This signal is emitted when the "Apply" button is pressed.
void applied();
/// This signal is emitted when the dialog receives a QHideEvent.
void hidden();
/// This signal is emitted when the dialog receives a QShowEvent
void shown();
protected:
void hideEvent( QHideEvent * event ) override;
void showEvent( QShowEvent * event ) override;
private Q_SLOTS:
void toggleSelectionMethod();
void updateTilesCount();
/// This slot is called upon to update the route download UI when a route exists
void updateRouteDialog();
/// This slot sets the unit of the offset(m or km) in the spinbox
void setOffsetUnit();
private:
Q_DISABLE_COPY( DownloadRegionDialog )
class Private;
Private * const d;
};
}
#endif
diff --git a/src/lib/marble/EditBookmarkDialog.cpp b/src/lib/marble/EditBookmarkDialog.cpp
index 15c06afbc..a1669e6c6 100644
--- a/src/lib/marble/EditBookmarkDialog.cpp
+++ b/src/lib/marble/EditBookmarkDialog.cpp
@@ -1,314 +1,314 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
//
#include "EditBookmarkDialog.h"
#include "ui_EditBookmarkDialog.h"
#include "BookmarkManager.h"
#include "GeoDataLookAt.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataFolder.h"
#include "GeoDataCoordinates.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "NewBookmarkFolderDialog.h"
#include "ReverseGeocodingRunnerManager.h"
#include <QPointer>
namespace Marble {
class EditBookmarkDialogPrivate {
public:
MarbleWidget *m_widget;
ReverseGeocodingRunnerManager* m_manager;
BookmarkManager* m_bookmarkManager;
GeoDataCoordinates m_bookmarkCoordinates;
qreal m_range;
Ui::UiEditBookmarkDialog m_ui;
EditBookmarkDialogPrivate( EditBookmarkDialog* q, BookmarkManager *bookmarkManager );
void initComboBox(const GeoDataContainer* const container , int level=0);
void initialize();
void setFolderName( const QString &name );
static QString append( const QString &bookmark, const QString &text);
void openNewFolderDialog();
void retrieveGeocodeResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark);
void updateCoordinates();
private:
EditBookmarkDialog* const q;
};
EditBookmarkDialogPrivate::EditBookmarkDialogPrivate( EditBookmarkDialog* q_, BookmarkManager *bookmarkManager ) :
- m_widget( 0 ), m_manager( 0 ), m_bookmarkManager( bookmarkManager ), m_range( 0 ), q( q_ )
+ m_widget( nullptr ), m_manager( nullptr ), m_bookmarkManager( bookmarkManager ), m_range( 0 ), q( q_ )
{
// nothing to do
}
void EditBookmarkDialogPrivate::initialize()
{
m_ui.setupUi( q );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
m_ui.m_header->setPositionVisible(!smallScreen);
m_ui.m_header->setIdVisible( false );
m_ui.m_header->setIconLink(MarbleDirs::path(QStringLiteral("bitmaps/bookmark.png")));
QObject::connect( m_ui.m_newFolderButton, SIGNAL(clicked()), q, SLOT(openNewFolderDialog()) );
QObject::connect( m_ui.m_header, SIGNAL(valueChanged()), q, SLOT(updateCoordinates()) );
m_ui.m_folders->clear();
initComboBox( m_bookmarkManager->document() );
}
void EditBookmarkDialogPrivate::initComboBox( const GeoDataContainer* const container, int level )
{
m_bookmarkManager->ensureDefaultFolder();
for( GeoDataFolder *folder: container->folderList() ) {
QVariant folderVariant;
folderVariant.setValue(folder);
QString name = QString(' ').repeated(4*level) + folder->name();
m_ui.m_folders->addItem( name, folderVariant );
if( !folder->folderList().isEmpty() ) {
initComboBox( folder, level+1 );
}
}
}
void EditBookmarkDialogPrivate::setFolderName( const QString &name )
{
for ( int i=0; i<m_ui.m_folders->count(); ++i ) {
if ( m_ui.m_folders->itemText( i ) == name ) {
m_ui.m_folders->setCurrentIndex( i );
return;
}
}
}
EditBookmarkDialog::EditBookmarkDialog( BookmarkManager *bookmarkManager, QWidget *parent )
: QDialog( parent ), d( new EditBookmarkDialogPrivate( this, bookmarkManager ) )
{
d->initialize();
}
void EditBookmarkDialog::setCoordinates( const GeoDataCoordinates &coordinates )
{
d->m_bookmarkCoordinates = coordinates;
QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
if ( d->m_ui.m_header->name().isEmpty() ) {
d->m_ui.m_header->setName( coordinates.toString() );
}
d->m_ui.m_header->setLongitude( coordinates.longitude(GeoDataCoordinates::Degree) );
d->m_ui.m_header->setLatitude( coordinates.latitude(GeoDataCoordinates::Degree) );
QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
}
void EditBookmarkDialog::setRange( qreal range ) {
d->m_range = range;
}
void EditBookmarkDialog::setName( const QString &text )
{
QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
d->m_ui.m_header->setName( text );
d->m_ui.m_header->selectAll();
QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
}
void EditBookmarkDialog::setDescription( const QString &text )
{
QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
d->m_ui.m_description->setText( text );
QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
}
void EditBookmarkDialog::setFolderName( const QString &name )
{
d->setFolderName( name );
}
void EditBookmarkDialog::setIconLink(const QString &iconLink)
{
QObject::disconnect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
d->m_ui.m_header->setIconLink( iconLink );
QObject::connect( d->m_ui.m_header, SIGNAL(valueChanged()), this, SLOT(updateCoordinates()) );
}
void EditBookmarkDialog::setMarbleWidget( MarbleWidget* widget )
{
d->m_widget = widget;
const AngleUnit defaultAngleUnit = d->m_widget->defaultAngleUnit();
const GeoDataCoordinates::Notation notation =
(defaultAngleUnit == DecimalDegree) ? GeoDataCoordinates::Decimal :
(defaultAngleUnit == DMSDegree) ? GeoDataCoordinates::DMS :
/* else, UTM */ GeoDataCoordinates::UTM;
d->m_ui.m_header->setNotation(notation);
d->m_manager = new ReverseGeocodingRunnerManager( d->m_widget->model(), this );
QObject::connect( d->m_manager, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)),
this, SLOT(retrieveGeocodeResult(GeoDataCoordinates,GeoDataPlacemark)) );
}
void EditBookmarkDialog::setReverseGeocodeName()
{
if ( !d->m_manager ) {
return;
}
//reverse geocode the bookmark point for better user experience
d->m_manager->reverseGeocoding( d->m_bookmarkCoordinates );
}
EditBookmarkDialog::~EditBookmarkDialog()
{
delete d;
}
void EditBookmarkDialogPrivate::retrieveGeocodeResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark)
{
Q_UNUSED(coordinates)
GeoDataExtendedData data = placemark.extendedData();
QString bookmarkName;
qreal distance = m_widget->distance() * KM2METER;
//FIXME : Optimal logic for suggestion with distance consideration is required
if( distance >= 3500 ) {
bookmarkName = data.value(QStringLiteral("country")).value().toString();
}
else if( distance >= 200 ) {
bookmarkName = append(data.value(QStringLiteral("city")).value().toString(),
data.value(QStringLiteral("state")).value().toString());
bookmarkName = append(bookmarkName, data.value(QStringLiteral("country")).value().toString());
}
else {
bookmarkName = append(data.value(QStringLiteral("road")).value().toString(),
data.value(QStringLiteral("city")).value().toString());
bookmarkName = append(bookmarkName, data.value(QStringLiteral("country")).value().toString());
}
if( bookmarkName.isEmpty() ) {
bookmarkName = placemark.address();
}
m_ui.m_header->setName( bookmarkName );
m_ui.m_header->selectAll();
}
QString EditBookmarkDialogPrivate::append( const QString &bookmark, const QString &text)
{
if( bookmark.isEmpty() && text.isEmpty() ) {
return "";
}
else if( bookmark.isEmpty() ) {
return text;
}
else if( text.isEmpty() ) {
return bookmark;
}
return bookmark + ", " + text;
}
void EditBookmarkDialogPrivate::openNewFolderDialog()
{
QPointer<NewBookmarkFolderDialog> dialog = new NewBookmarkFolderDialog( q );
if ( dialog->exec() == QDialog::Accepted ) {
m_bookmarkManager->addNewBookmarkFolder( m_bookmarkManager->document(), dialog->folderName() );
m_ui.m_folders->clear();
initComboBox( m_bookmarkManager->document() );
setFolderName( dialog->folderName() );
}
delete dialog;
}
void EditBookmarkDialogPrivate::updateCoordinates()
{
m_bookmarkCoordinates.setLongitude( m_ui.m_header->longitude(), GeoDataCoordinates::Degree );
m_bookmarkCoordinates.setLatitude( m_ui.m_header->latitude(), GeoDataCoordinates::Degree );
}
GeoDataPlacemark EditBookmarkDialog::bookmark() const
{
//Create a bookmark object
GeoDataPlacemark bookmark;
bookmark.setName( name() );
bookmark.setDescription( description() );
GeoDataStyle::Ptr newStyle(new GeoDataStyle( *bookmark.style() ));
newStyle->iconStyle().setIconPath( iconLink() );
bookmark.setStyle( newStyle );
//allow for HTML in the description
bookmark.setDescriptionCDATA( true );
bookmark.setCoordinate( coordinates() );
if ( d->m_range ) {
GeoDataLookAt *lookat = new GeoDataLookAt;
lookat->setCoordinates( coordinates() );
lookat->setRange( range() );
bookmark.setAbstractView( lookat );
}
bookmark.extendedData().addValue(GeoDataData(QStringLiteral("isBookmark"), true));
- if(d->m_widget != 0) {
+ if(d->m_widget != nullptr) {
const QString celestialName = d->m_widget->model()->planetId();
if (celestialName != QLatin1String("earth")) {
bookmark.extendedData().addValue(GeoDataData(QStringLiteral("celestialBody"), celestialName));
}
}
return bookmark;
}
QString EditBookmarkDialog::name() const
{
return d->m_ui.m_header->name();
}
GeoDataFolder *EditBookmarkDialog::folder() const
{
return qvariant_cast<GeoDataFolder*>(d->m_ui.m_folders->itemData(d->m_ui.m_folders->currentIndex()));
}
QString EditBookmarkDialog::description() const
{
return d->m_ui.m_description->toPlainText();
}
GeoDataCoordinates EditBookmarkDialog::coordinates() const
{
return d->m_bookmarkCoordinates;
}
qreal EditBookmarkDialog::range() const {
return d->m_range;
}
QString EditBookmarkDialog::iconLink() const
{
return d->m_ui.m_header->iconLink();
}
}
#include "moc_EditBookmarkDialog.cpp"
diff --git a/src/lib/marble/EditBookmarkDialog.h b/src/lib/marble/EditBookmarkDialog.h
index c473614d4..9e3d5ab7c 100644
--- a/src/lib/marble/EditBookmarkDialog.h
+++ b/src/lib/marble/EditBookmarkDialog.h
@@ -1,84 +1,84 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
//
#ifndef MARBLE_EDITBOOKMARKDIALOG_H
#define MARBLE_EDITBOOKMARKDIALOG_H
#include <QDialog>
#include "marble_export.h"
/** @todo FIXME after freeze: Rename to AddBookmarkDialog*/
namespace Marble
{
class EditBookmarkDialogPrivate;
class BookmarkManager;
class GeoDataFolder;
class GeoDataCoordinates;
class GeoDataPlacemark;
class MarbleWidget;
class MARBLE_EXPORT EditBookmarkDialog : public QDialog
{
Q_OBJECT
public:
- explicit EditBookmarkDialog( BookmarkManager *manager, QWidget *parent = 0 );
+ explicit EditBookmarkDialog( BookmarkManager *manager, QWidget *parent = nullptr );
/** Destructor */
~EditBookmarkDialog() override;
void setMarbleWidget( MarbleWidget* widget );
GeoDataPlacemark bookmark() const;
QString name() const;
GeoDataFolder* folder() const;
QString description() const;
GeoDataCoordinates coordinates() const;
qreal range() const;
QString iconLink() const;
void setName( const QString &name );
void setReverseGeocodeName();
void setCoordinates( const GeoDataCoordinates &coordinates );
void setRange( qreal range );
void setDescription( const QString &text );
void setFolderName( const QString &name );
void setIconLink( const QString &iconLink );
private:
Q_PRIVATE_SLOT( d, void openNewFolderDialog() )
Q_PRIVATE_SLOT( d, void retrieveGeocodeResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark) )
Q_PRIVATE_SLOT( d, void updateCoordinates() )
Q_DISABLE_COPY( EditBookmarkDialog )
EditBookmarkDialogPrivate* const d;
friend class EditBookmarkDialogPrivate;
};
}
#endif
diff --git a/src/lib/marble/EditPlacemarkDialog.cpp b/src/lib/marble/EditPlacemarkDialog.cpp
index 4e2d931b7..f6a4cb403 100644
--- a/src/lib/marble/EditPlacemarkDialog.cpp
+++ b/src/lib/marble/EditPlacemarkDialog.cpp
@@ -1,497 +1,497 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
// Copyright 2015 Ilya Kowalewski <illya.kovalevskyy@gmail.com>
//
// self
#include "EditPlacemarkDialog.h"
#include "ui_EditPlacemarkDialog.h"
#include "ui_ElevationWidget.h"
// Qt
#include <QMessageBox>
#include <QFileInfo>
#include <QColorDialog>
#include <QCheckBox>
// Marble
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataLabelStyle.h"
#include "GeoDataPlacemark.h"
#include "MarbleWidget.h"
#include "MarbleLocale.h"
#include "FormattedTextWidget.h"
#include "StyleBuilder.h"
#include "osm/OsmTagEditorWidget.h"
#include "osm/OsmPlacemarkData.h"
#include "osm/OsmRelationManagerWidget.h"
namespace Marble {
class Q_DECL_HIDDEN EditPlacemarkDialog::Private : public Ui::UiEditPlacemarkDialog
{
public:
Private( GeoDataPlacemark *placemark );
~Private();
GeoDataPlacemark *m_placemark;
// Attached to label/icon/text color selectors.
QColorDialog *m_iconColorDialog;
QColorDialog *m_labelColorDialog;
// Used to restore if the Cancel button is pressed.
QString m_initialDescription;
QString m_initialName;
GeoDataCoordinates m_initialCoords;
GeoDataStyle m_initialStyle;
GeoDataPlacemark::GeoDataVisualCategory m_initialVisualCategory;
OsmPlacemarkData m_initialOsmData;
QString m_styleColorTabName;
bool m_initialIsPlacemarkVisible;
bool m_initialIsBaloonVisible;
bool m_initialDescriptionIsCDATA;
bool m_hadInitialOsmData;
QString m_initialId;
Ui::ElevationWidget *m_elevationWidget;
OsmTagEditorWidget *m_osmTagEditorWidget;
OsmRelationManagerWidget *m_osmRelationManagerWidget;
MarbleLocale::MeasureUnit m_elevationUnit;
QString m_initialTargetId;
};
EditPlacemarkDialog::Private::Private( GeoDataPlacemark *placemark ) :
Ui::UiEditPlacemarkDialog(),
m_placemark( placemark ),
- m_iconColorDialog( 0 ),
- m_labelColorDialog( 0 ),
- m_osmTagEditorWidget( 0 ),
- m_osmRelationManagerWidget( 0 )
+ m_iconColorDialog( nullptr ),
+ m_labelColorDialog( nullptr ),
+ m_osmTagEditorWidget( nullptr ),
+ m_osmRelationManagerWidget( nullptr )
{
// nothing to do
}
EditPlacemarkDialog::Private::~Private()
{
delete m_elevationWidget;
delete m_osmTagEditorWidget;
delete m_osmRelationManagerWidget;
delete m_iconColorDialog;
delete m_labelColorDialog;
}
EditPlacemarkDialog::EditPlacemarkDialog( GeoDataPlacemark *placemark,
const QHash<qint64, OsmPlacemarkData> *relations,
QWidget *parent ) :
QDialog( parent ),
d( new Private( placemark ) )
{
d->setupUi( this );
// Store initial style so that it can be restored if the 'Cancel' button is pressed.
d->m_initialStyle = *placemark->style();
d->m_initialVisualCategory = placemark->visualCategory();
d->m_hadInitialOsmData = placemark->hasOsmData();
if ( d->m_hadInitialOsmData ) {
d->m_initialOsmData = placemark->osmData();
}
// If the placemark has just been created, assign it a default name.
if ( placemark->name().isNull() ) {
placemark->setName( tr("Untitled Placemark") );
}
// Setup id, name, icon link and latitude/longitude values.
d->m_header->setId( placemark->id() );
d->m_initialId = placemark->id();
d->m_header->setName( placemark->name() );
d->m_initialName = placemark->name();
d->m_isPlacemarkVisible->setChecked( placemark->isVisible() );
d->m_initialIsPlacemarkVisible = placemark->isVisible();
d->m_header->setIconLink( placemark->style()->iconStyle().iconPath() );
d->m_header->setTargetId( placemark->targetId() );
d->m_initialTargetId = placemark->targetId();
MarbleWidget* marbleWidget = dynamic_cast<MarbleWidget*>( parent );
- if( marbleWidget != 0 ) {
+ if( marbleWidget != nullptr ) {
const AngleUnit defaultAngleUnit = marbleWidget->defaultAngleUnit();
const GeoDataCoordinates::Notation notation =
(defaultAngleUnit == DecimalDegree) ? GeoDataCoordinates::Decimal :
(defaultAngleUnit == DMSDegree) ? GeoDataCoordinates::DMS :
/* else, UTM */ GeoDataCoordinates::UTM;
d->m_header->setNotation( notation );
}
connect( d->m_header, SIGNAL(valueChanged()), this, SLOT(
updateTextAnnotation()) );
d->m_formattedTextWidget->setText( placemark->description() );
d->m_initialDescription = placemark->description();
d->m_initialDescriptionIsCDATA = placemark->descriptionIsCDATA();
d->m_isBalloonVisible->setChecked( placemark->isBalloonVisible() );
d->m_initialIsBaloonVisible = placemark->isBalloonVisible();
d->m_header->setLatitude( placemark->coordinate().latitude( GeoDataCoordinates::Degree ) );
d->m_header->setLongitude( placemark->coordinate().longitude( GeoDataCoordinates::Degree ) );
d->m_initialCoords = GeoDataCoordinates( d->m_header->longitude(),
d->m_header->latitude(),
0,
GeoDataCoordinates::Degree );
// There's no point showing Relations and Tags tabs if the editor was not
// loaded from the annotate plugin ( loaded from tourWidget.. )
if ( relations ) {
// Adding the osm tag editor widget tab
d->m_osmTagEditorWidget = new OsmTagEditorWidget( placemark, this );
d->tabWidget->addTab( d->m_osmTagEditorWidget, tr( "Tags" ) );
QObject::connect( d->m_osmTagEditorWidget, SIGNAL( placemarkChanged( GeoDataFeature* ) ),
this, SLOT( updateTextAnnotation() ) );
// Adding the osm relation editor widget tab
d->m_osmRelationManagerWidget = new OsmRelationManagerWidget( placemark, relations, this );
d->tabWidget->addTab( d->m_osmRelationManagerWidget, tr( "Relations" ) );
QObject::connect( d->m_osmRelationManagerWidget, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SIGNAL( relationCreated( const OsmPlacemarkData& ) ) );
}
// Adding the elevation widget tab
d->m_elevationWidget = new Ui::ElevationWidget;
QWidget *elevationTab = new QWidget;
d->m_elevationWidget->setupUi( elevationTab );
d->tabWidget->addTab( elevationTab, tr("Elevation") );
qreal altitude = d->m_placemark->coordinate().altitude();
MarbleLocale *locale = MarbleGlobal::getInstance()->locale();
if ( altitude == 0.0 ) {
switch ( locale->measurementSystem() ) {
case MarbleLocale::MetricSystem:
d->m_elevationUnit = MarbleLocale::Meter;
break;
case MarbleLocale::ImperialSystem:
d->m_elevationUnit = MarbleLocale::Foot;
break;
case MarbleLocale::NauticalSystem:
d->m_elevationUnit = MarbleLocale::NauticalMile;
break;
}
d->m_elevationWidget->elevationSpinBox->setSuffix( locale->unitAbbreviation((d->m_elevationUnit)) );
} else {
qreal convertedAltitude;
const MarbleLocale::MeasurementSystem currentSystem = locale->measurementSystem();
locale->meterToTargetUnit( altitude, currentSystem, convertedAltitude, d->m_elevationUnit );
d->m_elevationWidget->elevationSpinBox->setValue( convertedAltitude );
d->m_elevationWidget->elevationSpinBox->setSuffix( locale->unitAbbreviation(d->m_elevationUnit) );
}
// Adjust icon and label scales.
d->m_iconScale->setValue( placemark->style()->iconStyle().scale() );
connect( d->m_iconScale, SIGNAL(valueChanged(double)), this, SLOT(updateTextAnnotation()) );
d->m_labelScale->setValue( placemark->style()->labelStyle().scale() );
connect( d->m_labelScale, SIGNAL(valueChanged(double)), this, SLOT(updateTextAnnotation()) );
// Adjust the current color of the two push buttons' pixmap to resemble the label and icon colors.
const GeoDataLabelStyle labelStyle = placemark->style()->labelStyle();
const GeoDataIconStyle iconStyle = placemark->style()->iconStyle();
QPixmap labelPixmap( d->m_labelButton->iconSize().width(),
d->m_labelButton->iconSize().height() );
labelPixmap.fill( labelStyle.color() );
d->m_labelButton->setIcon( QIcon( labelPixmap ) );
QPixmap iconPixmap( d->m_iconButton->iconSize().width(),
d->m_iconButton->iconSize().height() );
iconPixmap.fill( iconStyle.color() );
d->m_iconButton->setIcon( QIcon( iconPixmap ) );
// Setup the color dialogs.
d->m_labelColorDialog = new QColorDialog( this );
d->m_labelColorDialog->setOption( QColorDialog::ShowAlphaChannel );
d->m_labelColorDialog->setCurrentColor( labelStyle.color() );
connect( d->m_labelButton, SIGNAL(clicked()), d->m_labelColorDialog, SLOT(exec()) );
connect( d->m_labelColorDialog, SIGNAL(colorSelected(QColor)), this, SLOT(updateLabelDialog(QColor)) );
connect( d->m_labelColorDialog, SIGNAL(colorSelected(QColor)), this, SLOT(updateTextAnnotation()) );
d->m_iconColorDialog = new QColorDialog( this );
d->m_iconColorDialog->setOption( QColorDialog::ShowAlphaChannel );
d->m_iconColorDialog->setCurrentColor( iconStyle.color() );
connect( d->m_iconButton, SIGNAL(clicked()), d->m_iconColorDialog, SLOT(exec()) );
connect( d->m_iconColorDialog, SIGNAL(colorSelected(QColor)), this, SLOT(updateIconDialog(QColor)) );
connect( d->m_iconColorDialog, SIGNAL(colorSelected(QColor)), this, SLOT(updateTextAnnotation()) );
connect( d->m_isBalloonVisible, SIGNAL(toggled(bool)), this, SLOT(updateTextAnnotation()) );
// Promote "Ok" button to default button.
d->buttonBox->button( QDialogButtonBox::Ok )->setDefault( true );
connect( d->buttonBox->button( QDialogButtonBox::Ok ), SIGNAL(pressed()), this, SLOT(checkFields()) );
connect( this, SIGNAL(accepted()), SLOT(updateTextAnnotation()) );
connect( this, SIGNAL(accepted()), SLOT(updatePlacemarkAltitude()) );
connect( this, SIGNAL(finished(int)), SLOT(restoreInitial(int)) );
// Ensure that the dialog gets deleted when closing it (either when clicking OK or
// Close).
connect( this, SIGNAL(finished(int)), SLOT(deleteLater()) );
}
EditPlacemarkDialog::~EditPlacemarkDialog()
{
delete d;
}
void EditPlacemarkDialog::setLabelColor( const QColor &color )
{
d->m_labelColorDialog->setCurrentColor(color);
updateLabelDialog(color);
}
QStringList EditPlacemarkDialog::idFilter() const
{
return d->m_header->idFilter();
}
QStringList EditPlacemarkDialog::targetIds() const
{
return d->m_header->targetIdList();
}
bool EditPlacemarkDialog::isTargetIdFieldVisible() const
{
return d->m_header->isTargetIdVisible();
}
bool EditPlacemarkDialog::isIdFieldVisible() const
{
return d->m_header->isIdVisible();
}
void EditPlacemarkDialog::updateDialogFields()
{
d->m_header->setLatitude( d->m_placemark->coordinate().latitude( GeoDataCoordinates::Degree ) );
d->m_header->setLongitude( d->m_placemark->coordinate().longitude( GeoDataCoordinates::Degree ) );
}
void EditPlacemarkDialog::setIdFilter(const QStringList &filter)
{
d->m_header->setIdFilter( filter );
}
void EditPlacemarkDialog::setTargetIds(const QStringList &targetIds)
{
d->m_header->setTargetIdList( targetIds );
}
void EditPlacemarkDialog::setTargetIdFieldVisible(bool visible)
{
d->m_header->setTargetIdVisible( visible );
}
void EditPlacemarkDialog::setIdFieldVisible(bool visible)
{
d->m_header->setIdVisible( visible );
}
void EditPlacemarkDialog::setReadOnly(bool state)
{
d->m_header->setReadOnly(state);
d->m_formattedTextWidget->setReadOnly(state);
d->m_isBalloonVisible->setDisabled(state);
d->m_isPlacemarkVisible->setDisabled(state);
d->style_color_tab->setDisabled(state);
}
void EditPlacemarkDialog::updateTextAnnotation()
{
d->m_placemark->setDescription( d->m_formattedTextWidget->text() );
//allow for HTML in the description
d->m_placemark->setDescriptionCDATA( true );
d->m_placemark->setName( d->m_header->name() );
d->m_placemark->setCoordinate( GeoDataCoordinates( d->m_header->longitude(),
d->m_header->latitude(),
0,
GeoDataCoordinates::Degree ) );
d->m_placemark->setVisible( d->m_isPlacemarkVisible->isChecked() );
d->m_placemark->setBalloonVisible( d->m_isBalloonVisible->isChecked() );
d->m_placemark->setId( d->m_header->id() );
d->m_placemark->setTargetId( d->m_header->targetId() );
if ( !d->m_header->iconLink().isEmpty() ) {
QFileInfo fileInfo( d->m_header->iconLink() );
GeoDataStyle::Ptr newStyle(new GeoDataStyle( *d->m_placemark->style() ));
if ( fileInfo.exists() ) {
newStyle->iconStyle().setIconPath( d->m_header->iconLink() );
}
newStyle->iconStyle().setScale( d->m_iconScale->value() );
newStyle->labelStyle().setScale( d->m_labelScale->value() );
newStyle->iconStyle().setColor( d->m_iconColorDialog->currentColor() );
newStyle->labelStyle().setColor( d->m_labelColorDialog->currentColor() );
d->m_placemark->setStyle( newStyle );
}
else {
const OsmPlacemarkData osmData = d->m_osmTagEditorWidget->placemarkData();
const GeoDataPlacemark::GeoDataVisualCategory category = StyleBuilder::determineVisualCategory(osmData);
if (category != GeoDataPlacemark::None) {
d->m_placemark->setStyle(GeoDataStyle::Ptr());
d->m_placemark->setVisualCategory( category );
}
}
emit textAnnotationUpdated( d->m_placemark );
}
void EditPlacemarkDialog::checkFields()
{
if ( d->m_header->name().isEmpty() ) {
QMessageBox::warning( this,
tr( "No name specified" ),
tr( "Please specify a name for this placemark." ) );
} else if ( isIdFieldVisible() && d->m_header->id().isEmpty() ) {
QMessageBox::warning( this,
tr( "No ID specified" ),
tr( "Please specify a ID for this placemark." ) );
} else if ( isIdFieldVisible() && !d->m_header->isIdValid() ) {
QMessageBox::warning( this,
tr( "ID is invalid" ),
tr( "Please specify a valid ID for this placemark." ) );
} else if (d->m_header->iconLink().isEmpty() && d->m_placemark->visualCategory() == GeoDataPlacemark::None) {
QMessageBox::warning( this,
tr( "No image specified" ),
tr( "Please specify an icon for this placemark or add a valid tag." ) );
} else if( !d->m_header->iconLink().isEmpty() && !QFileInfo( d->m_header->iconLink() ).exists() ) {
QMessageBox::warning( this,
tr( "Invalid icon path" ),
tr( "Please specify a valid path for the icon file." ) );
} else {
accept();
}
}
void EditPlacemarkDialog::updateLabelDialog( const QColor &color )
{
QPixmap labelPixmap( d->m_labelButton->iconSize().width(),
d->m_labelButton->iconSize().height() );
labelPixmap.fill( color );
d->m_labelButton->setIcon( QIcon( labelPixmap ) );
}
void EditPlacemarkDialog::updateIconDialog( const QColor &color )
{
QPixmap iconPixmap( d->m_iconButton->iconSize().width(),
d->m_iconButton->iconSize().height() );
iconPixmap.fill( color );
d->m_iconButton->setIcon( QIcon( iconPixmap ) );
}
void EditPlacemarkDialog::updatePlacemarkAltitude()
{
GeoDataCoordinates coord = d->m_placemark->coordinate();
qreal altitude = d->m_elevationWidget->elevationSpinBox->value();
switch (d->m_elevationUnit) {
case MarbleLocale::Meter:
break;
case MarbleLocale::Milimeter:
altitude *= MM2M;
break;
case MarbleLocale::Kilometer:
altitude *= KM2METER;
break;
case MarbleLocale::Centimeter:
altitude *= CM2M;
break;
case MarbleLocale::Foot:
altitude *= FT2M;
break;
case MarbleLocale::Inch:
altitude *= IN2M;
break;
case MarbleLocale::Yard:
altitude *= YD2M;
break;
case MarbleLocale::Mile:
altitude *= MI2KM * KM2METER;
break;
case MarbleLocale::NauticalMile:
altitude *= NM2KM * KM2METER;
break;
default:
break;
}
coord.setAltitude(altitude);
d->m_placemark->setCoordinate(coord);
}
void EditPlacemarkDialog::restoreInitial( int result )
{
if ( result ) {
return;
}
if ( d->m_placemark->name() != d->m_initialName ) {
d->m_placemark->setName( d->m_initialName );
}
if ( isIdFieldVisible() && d->m_placemark->id() != d->m_initialId ) {
d->m_placemark->setId( d->m_initialId );
}
if ( isTargetIdFieldVisible() && d->m_placemark->targetId() != d->m_initialTargetId ) {
d->m_placemark->setTargetId( d->m_initialTargetId );
}
if ( d->m_placemark->description() != d->m_initialDescription ) {
d->m_placemark->setDescription( d->m_initialDescription );
}
if ( d->m_placemark->descriptionIsCDATA() != d->m_initialDescriptionIsCDATA ) {
d->m_placemark->setDescriptionCDATA( d->m_initialDescriptionIsCDATA );
}
if ( d->m_placemark->coordinate().latitude( GeoDataCoordinates::Degree ) !=
d->m_initialCoords.latitude( GeoDataCoordinates::Degree ) ||
d->m_placemark->coordinate().longitude( GeoDataCoordinates::Degree ) !=
d->m_initialCoords.longitude( GeoDataCoordinates::Degree ) ) {
d->m_placemark->setCoordinate( d->m_initialCoords );
}
if ( d->m_placemark->visualCategory() != d->m_initialVisualCategory ) {
d->m_placemark->setVisualCategory( d->m_initialVisualCategory );
}
if ( *d->m_placemark->style() != d->m_initialStyle ) {
d->m_placemark->setStyle( GeoDataStyle::Ptr(new GeoDataStyle( d->m_initialStyle )) );
}
if( d->m_placemark->isVisible() != d->m_initialIsPlacemarkVisible ) {
d->m_placemark->setVisible( d->m_initialIsPlacemarkVisible );
}
if( d->m_hadInitialOsmData ) {
d->m_placemark->setOsmData( d->m_initialOsmData );
}
if( d->m_placemark->isBalloonVisible() != d->m_initialIsBaloonVisible ) {
d->m_placemark->setVisible( d->m_initialIsBaloonVisible );
}
emit textAnnotationUpdated( d->m_placemark );
}
}
#include "moc_EditPlacemarkDialog.cpp"
diff --git a/src/lib/marble/EditPlacemarkDialog.h b/src/lib/marble/EditPlacemarkDialog.h
index 68e0f9afe..896551da1 100644
--- a/src/lib/marble/EditPlacemarkDialog.h
+++ b/src/lib/marble/EditPlacemarkDialog.h
@@ -1,165 +1,165 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
#ifndef EDITPLACEMARKDIALOG_H
#define EDITPLACEMARKDIALOG_H
#include "marble_export.h"
#include <QDialog>
namespace Marble {
class GeoDataFeature;
class GeoDataPlacemark;
class OsmPlacemarkData;
/**
* @brief The EditPlacemarkDialog class deals with customizing placemarks.
*/
class MARBLE_EXPORT EditPlacemarkDialog : public QDialog
{
Q_OBJECT
public:
EditPlacemarkDialog( GeoDataPlacemark *placemark,
- const QHash<qint64,OsmPlacemarkData> *relations = 0,
- QWidget *parent = 0 );
+ const QHash<qint64,OsmPlacemarkData> *relations = nullptr,
+ QWidget *parent = nullptr );
~EditPlacemarkDialog() override;
/**
* @brief setLabelColor tells the dialog what the label color is
*/
void setLabelColor( const QColor &color );
/**
* @brief idFilter gets filter for id of placemark
* @return QStringList of ids which could not be used as id.
*/
QStringList idFilter() const;
/**
* @brief targetIds gets ids which could be target of placemark.
* @return QStringList of ids which could be target of placemark.
*/
QStringList targetIds() const;
/**
* @brief isTargetIdFieldVisible tells if targetId field is shown.
*/
bool isTargetIdFieldVisible() const;
/**
* @brief isIdFieldVisible tells if targetId field is shown.
*/
bool isIdFieldVisible() const;
public Q_SLOTS:
/**
* @brief updateDialogFields is connected to a signal from AnnotatePlugin in order
* to update some fields in the dialog as the user interacts directly with the text
* annotation item.
*/
void updateDialogFields();
/**
* @brief setIdFilter sets filter for id of placemark.
* @param filter QStringList with ids which could not be used as id.
*/
void setIdFilter( const QStringList &filter );
/**
* @brief setTargetIds sets ids which could be target of placemark.
* @param targetIds QStringList with ids which could be target of placemark.
*/
void setTargetIds( const QStringList &targetIds );
/**
* @brief setTargetIdFieldVisible tells the dialog whether targetId field should be shown.
*/
void setTargetIdFieldVisible( bool visible );
/**
* @brief setIdFieldVisible tells the dialog whether id field should be shown.
*/
void setIdFieldVisible( bool visible );
/**
* @brief Protecting data from input fields changes
*/
void setReadOnly( bool state );
private Q_SLOTS:
/**
* @brief checkFields shows warnings if there are important fields which don't hold
* accurate information.
*/
void checkFields();
/**
* @brief updateTextAnnotation is the main slot which synchronizes the information
* from the dialog with the way the text annotation item is painted.
*/
void updateTextAnnotation();
/**
* @brief updateLabelDialog The color chooser for label is represented as a push
* button with a filled pixmap as its icon. This slot updates the color fill of this
* pixmap.
*/
void updateLabelDialog( const QColor &color );
/**
* @brief updateIconDialog The same as above, but for icons.
* FIXME: This is not functional ATM - we need some mechanism for customizing existing
* icons.
*/
void updateIconDialog( const QColor &color );
/**
* @brief updatePlacemarkAltitude changes an actual elevation value of placemark instance
* according to the value/unit of elevation widget spin box representing it
*/
void updatePlacemarkAltitude();
/**
* @brief restoreInitial restores the dialog's previous settings if the dialog closes with
* a zero return value.
*/
void restoreInitial( int result );
/**
* @brief toogleDescriptionEditMode toggles edit mode for description field.
*/
Q_SIGNALS:
/**
* @brief textAnnotationUpdated signals that some property of the PlacemarkTextAnnotation
* instance has changed.
* @param feature The instance's placemark.
*/
void textAnnotationUpdated( GeoDataFeature *feature );
/**
* @brief relationCreated signals the annotate plugin that a new relation has been
* created( or modified ) within the relation editor
* @param relation the relation's osmData
*/
void relationCreated( const OsmPlacemarkData &relation );
private:
class Private;
Private * const d;
};
}
#endif
diff --git a/src/lib/marble/ElevationModel.cpp b/src/lib/marble/ElevationModel.cpp
index d9d9fbd4f..cafd98ed7 100644
--- a/src/lib/marble/ElevationModel.cpp
+++ b/src/lib/marble/ElevationModel.cpp
@@ -1,221 +1,221 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "ElevationModel.h"
#include "GeoSceneHead.h"
#include "GeoSceneLayer.h"
#include "GeoSceneMap.h"
#include "GeoSceneDocument.h"
#include "GeoSceneTextureTileDataset.h"
#include "HttpDownloadManager.h"
#include "Tile.h"
#include "TileLoader.h"
#include "TileLoaderHelper.h"
#include "MarbleDebug.h"
#include "MapThemeManager.h"
#include "TileId.h"
#include "PluginManager.h"
#include <QCache>
#include <QImage>
#include <qmath.h>
namespace Marble
{
class ElevationModelPrivate
{
public:
ElevationModelPrivate( ElevationModel *_q, HttpDownloadManager *downloadManager, PluginManager* pluginManager )
: q( _q ),
m_tileLoader( downloadManager, pluginManager ),
- m_textureLayer( 0 ),
- m_srtmTheme(0)
+ m_textureLayer( nullptr ),
+ m_srtmTheme(nullptr)
{
m_cache.setMaxCost( 10 ); //keep 10 tiles in memory (~17MB)
m_srtmTheme = MapThemeManager::loadMapTheme( "earth/srtm2/srtm2.dgml" );
if ( !m_srtmTheme ) {
mDebug() << "Failed to load map theme earth/srtm2/srtm2.dgml. Check your installation. No elevation will be returned.";
return;
}
const GeoSceneHead *head = m_srtmTheme->head();
Q_ASSERT( head );
const GeoSceneMap *map = m_srtmTheme->map();
Q_ASSERT( map );
const GeoSceneLayer *sceneLayer = map->layer( head->theme() );
Q_ASSERT( sceneLayer );
m_textureLayer = dynamic_cast<GeoSceneTextureTileDataset*>( sceneLayer->datasets().first() );
Q_ASSERT( m_textureLayer );
}
~ElevationModelPrivate()
{
delete m_srtmTheme;
}
void tileCompleted( const TileId & tileId, const QImage &image )
{
m_cache.insert( tileId, new QImage( image ) );
emit q->updateAvailable();
}
public:
ElevationModel *q;
TileLoader m_tileLoader;
const GeoSceneTextureTileDataset *m_textureLayer;
QCache<TileId, const QImage> m_cache;
GeoSceneDocument *m_srtmTheme;
};
ElevationModel::ElevationModel( HttpDownloadManager *downloadManager, PluginManager* pluginManager, QObject *parent ) :
QObject( parent ),
d( new ElevationModelPrivate( this, downloadManager, pluginManager ) )
{
connect( &d->m_tileLoader, SIGNAL(tileCompleted(TileId,QImage)),
this, SLOT(tileCompleted(TileId,QImage)) );
}
ElevationModel::~ElevationModel()
{
delete d;
}
qreal ElevationModel::height( qreal lon, qreal lat ) const
{
if ( !d->m_textureLayer ) {
return invalidElevationData;
}
const int tileZoomLevel = TileLoader::maximumTileLevel( *( d->m_textureLayer ) );
Q_ASSERT( tileZoomLevel == 9 );
const int width = d->m_textureLayer->tileSize().width();
const int height = d->m_textureLayer->tileSize().height();
const int numTilesX = TileLoaderHelper::levelToColumn( d->m_textureLayer->levelZeroColumns(), tileZoomLevel );
const int numTilesY = TileLoaderHelper::levelToRow( d->m_textureLayer->levelZeroRows(), tileZoomLevel );
Q_ASSERT( numTilesX > 0 );
Q_ASSERT( numTilesY > 0 );
qreal textureX = 180 + lon;
textureX *= numTilesX * width / 360;
qreal textureY = 90 - lat;
textureY *= numTilesY * height / 180;
qreal ret = 0;
bool hasHeight = false;
qreal noData = 0;
for ( int i = 0; i < 4; ++i ) {
const int x = static_cast<int>( textureX + ( i % 2 ) );
const int y = static_cast<int>( textureY + ( i / 2 ) );
//mDebug() << "x" << x << ( x / width );
//mDebug() << "y" << y << ( y / height );
const TileId id( 0, tileZoomLevel, ( x % ( numTilesX * width ) ) / width, ( y % ( numTilesY * height ) ) / height );
//mDebug() << "LAT" << lat << "LON" << lon << "tile" << ( x % ( numTilesX * width ) ) / width << ( y % ( numTilesY * height ) ) / height;
const QImage *image = d->m_cache[id];
- if ( image == 0 ) {
+ if ( image == nullptr ) {
image = new QImage( d->m_tileLoader.loadTileImage( d->m_textureLayer, id, DownloadBrowse ) );
d->m_cache.insert( id, image );
}
Q_ASSERT( image );
Q_ASSERT( !image->isNull() );
Q_ASSERT( width == image->width() );
Q_ASSERT( height == image->height() );
const qreal dx = ( textureX > ( qreal )x ) ? textureX - ( qreal )x : ( qreal )x - textureX;
const qreal dy = ( textureY > ( qreal )y ) ? textureY - ( qreal )y : ( qreal )y - textureY;
Q_ASSERT( 0 <= dx && dx <= 1 );
Q_ASSERT( 0 <= dy && dy <= 1 );
unsigned int pixel = image->pixel( x % width, y % height ) & 0xffff; // 16 valid bits
short int elevation = (short int) pixel; // and signed type, so just cast it
//mDebug() << "(1-dx)" << (1-dx) << "(1-dy)" << (1-dy);
if ( pixel != invalidElevationData ) { //no data?
//mDebug() << "got at x" << x % width << "y" << y % height << "a height of" << pixel << "** RGB" << qRed(pixel) << qGreen(pixel) << qBlue(pixel);
ret += ( qreal )elevation * ( 1 - dx ) * ( 1 - dy );
hasHeight = true;
} else {
//mDebug() << "no data at" << x % width << "y" << y % height;
noData += ( 1 - dx ) * ( 1 - dy );
}
}
if ( !hasHeight ) {
ret = invalidElevationData; //no data
} else {
if ( noData ) {
//mDebug() << "NO DATA" << noData;
ret += ( ret / ( 1 - noData ) ) * noData;
}
}
//mDebug() << ">>>" << lat << lon << "returning an elevation of" << ret;
return ret;
}
QVector<GeoDataCoordinates> ElevationModel::heightProfile( qreal fromLon, qreal fromLat, qreal toLon, qreal toLat ) const
{
if ( !d->m_textureLayer ) {
return QVector<GeoDataCoordinates>();
}
const int tileZoomLevel = TileLoader::maximumTileLevel( *( d->m_textureLayer ) );
const int width = d->m_textureLayer->tileSize().width();
const int numTilesX = TileLoaderHelper::levelToColumn( d->m_textureLayer->levelZeroColumns(), tileZoomLevel );
qreal distPerPixel = ( qreal )360 / ( width * numTilesX );
//mDebug() << "heightProfile" << fromLat << fromLon << toLat << toLon << "distPerPixel" << distPerPixel;
qreal lat = fromLat;
qreal lon = fromLon;
char dirLat = fromLat < toLat ? 1 : -1;
char dirLon = fromLon < toLon ? 1 : -1;
qreal k = qAbs( ( fromLat - toLat ) / ( fromLon - toLon ) );
//mDebug() << "fromLon" << fromLon << "fromLat" << fromLat;
//mDebug() << "diff lon" << ( fromLon - toLon ) << "diff lat" << ( fromLat - toLat );
//mDebug() << "dirLon" << QString::number(dirLon) << "dirLat" << QString::number(dirLat) << "k" << k;
QVector<GeoDataCoordinates> ret;
while ( lat*dirLat <= toLat*dirLat && lon*dirLon <= toLon * dirLon ) {
//mDebug() << lat << lon;
qreal h = height( lon, lat );
if ( h < 32000 ) {
ret << GeoDataCoordinates( lon, lat, h, GeoDataCoordinates::Degree );
}
if ( k < 0.5 ) {
//mDebug() << "lon(x) += distPerPixel";
lat += distPerPixel * k * dirLat;
lon += distPerPixel * dirLon;
} else {
//mDebug() << "lat(y) += distPerPixel";
lat += distPerPixel * dirLat;
lon += distPerPixel / k * dirLon;
}
}
//mDebug() << ret;
return ret;
}
}
#include "moc_ElevationModel.cpp"
diff --git a/src/lib/marble/ElevationModel.h b/src/lib/marble/ElevationModel.h
index c132967f1..50b315c4b 100644
--- a/src/lib/marble/ElevationModel.h
+++ b/src/lib/marble/ElevationModel.h
@@ -1,61 +1,61 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#ifndef MARBLE_ELEVATIONMODEL_H
#define MARBLE_ELEVATIONMODEL_H
#include "marble_export.h"
#include <QObject>
class QImage;
namespace Marble
{
class GeoDataCoordinates;
namespace {
unsigned int const invalidElevationData = 32768;
}
class TileId;
class ElevationModelPrivate;
class HttpDownloadManager;
class PluginManager;
class MARBLE_EXPORT ElevationModel : public QObject
{
Q_OBJECT
public:
- explicit ElevationModel( HttpDownloadManager *downloadManager, PluginManager* pluginManager, QObject *parent = 0 );
+ explicit ElevationModel( HttpDownloadManager *downloadManager, PluginManager* pluginManager, QObject *parent = nullptr );
~ElevationModel() override;
qreal height( qreal lon, qreal lat ) const;
QVector<GeoDataCoordinates> heightProfile( qreal fromLon, qreal fromLat, qreal toLon, qreal toLat ) const;
Q_SIGNALS:
/**
* Elevation tiles loaded. You will get more accurate results when querying height
* for at least one that was queried before.
**/
void updateAvailable();
private:
Q_PRIVATE_SLOT( d, void tileCompleted( const TileId&, const QImage& ) )
private:
friend class ElevationModelPrivate;
ElevationModelPrivate *d;
};
}
#endif // MARBLE_ELEVATIONMODEL_H
diff --git a/src/lib/marble/ExternalEditorDialog.h b/src/lib/marble/ExternalEditorDialog.h
index 3b0ad26fb..74dde5653 100644
--- a/src/lib/marble/ExternalEditorDialog.h
+++ b/src/lib/marble/ExternalEditorDialog.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_EXTERNALEDITORDIALOG_H
#define MARBLE_EXTERNALEDITORDIALOG_H
#include "marble_export.h"
#include <QDialog>
#include "ui_ExternalEditor.h"
namespace Marble
{
class ExternalEditorDialogPrivate;
class MARBLE_EXPORT ExternalEditorDialog: public QDialog, private Ui::ExternalEditor
{
Q_OBJECT
public:
- explicit ExternalEditorDialog( QWidget * parent = 0, Qt::WindowFlags f = 0 );
+ explicit ExternalEditorDialog( QWidget * parent = nullptr, Qt::WindowFlags f = nullptr );
~ExternalEditorDialog() override;
QString externalEditor() const;
bool saveDefault() const;
private Q_SLOTS:
void updateDefaultEditor( int index );
private:
ExternalEditorDialogPrivate * const d;
};
} // namespace Marble
#endif // MARBLE_EXTERNALEDITORDIALOG_H
diff --git a/src/lib/marble/FileLoader.cpp b/src/lib/marble/FileLoader.cpp
index 7b15b0097..61330a795 100644
--- a/src/lib/marble/FileLoader.cpp
+++ b/src/lib/marble/FileLoader.cpp
@@ -1,567 +1,567 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Patrick Spendrin <ps_ml@gmx.de>
//
#include "FileLoader.h"
#include <QBuffer>
#include <QDataStream>
#include <QFile>
#include <QThread>
#include "GeoDataParser.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataPlacemark.h"
#include "GeoDataData.h"
#include "GeoDataExtendedData.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataPoint.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataLineStyle.h"
#include "GeoDataPolygon.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataTour.h"
#include "GeoDataTrack.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "ParsingRunnerManager.h"
namespace Marble
{
class FileLoaderPrivate
{
public:
FileLoaderPrivate( FileLoader* parent, const PluginManager *pluginManager, bool recenter,
const QString &file, const QString &property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder) :
q(parent),
m_runner(pluginManager),
m_filepath (file),
m_property(property),
m_style(style),
m_styleMap(new GeoDataStyleMap),
- m_document(0),
+ m_document(nullptr),
m_renderOrder(renderOrder),
m_documentRole(role),
m_recenter(recenter)
{
if( m_style ) {
m_styleMap->setId(QStringLiteral("default-map"));
m_styleMap->insert(QStringLiteral("normal"), QLatin1Char('#') + m_style->id());
}
}
FileLoaderPrivate( FileLoader* parent, const PluginManager *pluginManager,
const QString &contents, const QString &file, DocumentRole role) :
q(parent),
m_runner(pluginManager),
m_filepath(file),
m_contents(contents),
- m_styleMap(0),
- m_document(0),
+ m_styleMap(nullptr),
+ m_document(nullptr),
m_documentRole(role),
m_recenter(false)
{
}
~FileLoaderPrivate()
{
delete m_styleMap;
}
void createFilterProperties( GeoDataContainer *container );
static int cityPopIdx( qint64 population );
static int spacePopIdx( qint64 population );
static int areaPopIdx( qreal area );
void documentParsed( GeoDataDocument *doc, const QString& error);
FileLoader *q;
ParsingRunnerManager m_runner;
QString m_filepath;
QString m_contents;
QString m_property;
GeoDataStyle::Ptr m_style;
GeoDataStyleMap* m_styleMap;
GeoDataDocument *m_document;
QString m_error;
int m_renderOrder;
DocumentRole m_documentRole;
bool m_recenter;
};
FileLoader::FileLoader( QObject* parent, const PluginManager *pluginManager, bool recenter, const QString& file,
const QString& property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder )
: QThread( parent ),
d( new FileLoaderPrivate( this, pluginManager, recenter, file, property, style, role, renderOrder ) )
{
}
FileLoader::FileLoader( QObject* parent, const PluginManager *pluginManager,
const QString& contents, const QString& file, DocumentRole role )
: QThread( parent ),
d( new FileLoaderPrivate( this, pluginManager, contents, file, role ) )
{
}
FileLoader::~FileLoader()
{
delete d;
}
QString FileLoader::path() const
{
return d->m_filepath;
}
GeoDataDocument* FileLoader::document()
{
return d->m_document;
}
QString FileLoader::error() const
{
return d->m_error;
}
void FileLoader::run()
{
if ( d->m_contents.isEmpty() ) {
QString defaultSourceName;
mDebug() << "starting parser for" << d->m_filepath;
QFileInfo fileinfo( d->m_filepath );
QString path = fileinfo.path();
if (path == QLatin1String(".")) path.clear();
QString name = fileinfo.completeBaseName();
QString suffix = fileinfo.suffix();
// determine source, cache names
if ( fileinfo.isAbsolute() ) {
// We got an _absolute_ path now: e.g. "/patrick.kml"
defaultSourceName = path + QLatin1Char('/') + name + QLatin1Char('.') + suffix;
}
else if ( d->m_filepath.contains( '/' ) ) {
// _relative_ path: "maps/mars/viking/patrick.kml"
defaultSourceName = MarbleDirs::path(path + QLatin1Char('/') + name + QLatin1Char('.') + suffix);
if ( !QFile::exists( defaultSourceName ) ) {
defaultSourceName = MarbleDirs::path(path + QLatin1Char('/') + name + QLatin1String(".cache"));
}
}
else {
// _standard_ shared placemarks: "placemarks/patrick.kml"
defaultSourceName = MarbleDirs::path(QLatin1String("placemarks/") + path + name + QLatin1Char('.') + suffix);
if ( !QFile::exists( defaultSourceName ) ) {
defaultSourceName = MarbleDirs::path(QLatin1String("placemarks/") + path + name + QLatin1String(".cache"));
}
}
if ( QFile::exists( defaultSourceName ) ) {
mDebug() << "No recent Default Placemark Cache File available!";
// use runners: pnt, gpx, osm
connect( &d->m_runner, SIGNAL(parsingFinished(GeoDataDocument*,QString)),
this, SLOT(documentParsed(GeoDataDocument*,QString)) );
d->m_runner.parseFile( defaultSourceName, d->m_documentRole );
}
else {
mDebug() << "No Default Placemark Source File for " << name;
}
// content is not empty, we load from data
} else {
// Read the KML Data
GeoDataParser parser( GeoData_KML );
QByteArray ba( d->m_contents.toUtf8() );
QBuffer buffer( &ba );
buffer.open( QIODevice::ReadOnly );
if ( !parser.read( &buffer ) ) {
qWarning( "Could not import kml buffer!" );
emit loaderFinished( this );
return;
}
GeoDocument* document = parser.releaseDocument();
Q_ASSERT( document );
d->m_document = static_cast<GeoDataDocument*>( document );
d->m_document->setProperty( d->m_property );
d->m_document->setDocumentRole( d->m_documentRole );
d->createFilterProperties( d->m_document );
buffer.close();
mDebug() << "newGeoDataDocumentAdded" << d->m_filepath;
emit newGeoDataDocumentAdded( d->m_document );
emit loaderFinished( this );
}
}
bool FileLoader::recenter() const
{
return d->m_recenter;
}
void FileLoaderPrivate::documentParsed( GeoDataDocument* doc, const QString& error )
{
m_error = error;
if ( doc ) {
m_document = doc;
doc->setProperty( m_property );
if( m_style ) {
doc->addStyleMap( *m_styleMap );
doc->addStyle( m_style );
}
if (m_renderOrder != 0) {
for (GeoDataPlacemark* placemark: doc->placemarkList()) {
if (GeoDataPolygon *polygon = geodata_cast<GeoDataPolygon>(placemark->geometry())) {
polygon->setRenderOrder(m_renderOrder);
}
}
}
createFilterProperties( doc );
emit q->newGeoDataDocumentAdded( m_document );
}
emit q->loaderFinished( q );
}
void FileLoaderPrivate::createFilterProperties( GeoDataContainer *container )
{
const QString styleUrl = QLatin1Char('#') + m_styleMap->id();
QVector<GeoDataFeature*>::Iterator i = container->begin();
QVector<GeoDataFeature*>::Iterator const end = container->end();
for (; i != end; ++i ) {
if (auto child = dynamic_cast<GeoDataContainer *>(*i)) {
createFilterProperties( child );
} else if (geodata_cast<GeoDataTour>(*i)
|| geodata_cast<GeoDataGroundOverlay>(*i)
|| geodata_cast<GeoDataPhotoOverlay>(*i)
|| geodata_cast<GeoDataScreenOverlay>(*i)) {
/** @todo: How to handle this ? */
} else if (auto placemark = geodata_cast<GeoDataPlacemark>(*i)) {
const QString placemarkRole = placemark->role();
Q_ASSERT( placemark->geometry() );
bool hasPopularity = false;
if (!geodata_cast<GeoDataTrack>(placemark->geometry()) &&
!geodata_cast<GeoDataPoint>(placemark->geometry())
&& m_documentRole == MapDocument
&& m_style ) {
placemark->setStyleUrl(styleUrl);
}
// Mountain (H), Volcano (V), Shipwreck (W)
if (placemarkRole == QLatin1String("H") ||
placemarkRole == QLatin1String("V") ||
placemarkRole == QLatin1String("W"))
{
qreal altitude = placemark->coordinate().altitude();
if ( altitude != 0.0 )
{
hasPopularity = true;
placemark->setPopularity( (qint64)(altitude * 1000.0) );
placemark->setZoomLevel( cityPopIdx( qAbs( (qint64)(altitude * 1000.0) ) ) );
}
}
// Continent (K), Ocean (O), Nation (S)
else if (placemarkRole == QLatin1String("K") ||
placemarkRole == QLatin1String("O") ||
placemarkRole == QLatin1String("S"))
{
qreal area = placemark->area();
if ( area >= 0.0 )
{
hasPopularity = true;
// mDebug() << placemark->name() << " " << (qint64)(area);
placemark->setPopularity( (qint64)(area * 100) );
placemark->setZoomLevel( areaPopIdx( area ) );
}
}
// Pole (P)
else if (placemarkRole == QLatin1String("P") )
{
placemark->setPopularity( 1000000000 );
placemark->setZoomLevel( 1 );
}
// Magnetic Pole (M)
else if (placemarkRole == QLatin1String("M"))
{
placemark->setPopularity( 10000000 );
placemark->setZoomLevel( 3 );
}
// MannedLandingSite (h)
else if (placemarkRole == QLatin1String("h"))
{
placemark->setPopularity( 1000000000 );
placemark->setZoomLevel( 1 );
}
// RoboticRover (r)
else if (placemarkRole == QLatin1String("r"))
{
placemark->setPopularity( 10000000 );
placemark->setZoomLevel( 2 );
}
// UnmannedSoftLandingSite (u)
else if (placemarkRole == QLatin1String("u"))
{
placemark->setPopularity( 1000000 );
placemark->setZoomLevel( 3 );
}
// UnmannedSoftLandingSite (i)
else if (placemarkRole == QLatin1String("i"))
{
placemark->setPopularity( 1000000 );
placemark->setZoomLevel( 3 );
}
// Space Terrain: Craters, Maria, Montes, Valleys, etc.
else if (placemarkRole == QLatin1String("m") ||
placemarkRole == QLatin1String("v") ||
placemarkRole == QLatin1String("o") ||
placemarkRole == QLatin1String("c") ||
placemarkRole == QLatin1String("a"))
{
qint64 diameter = placemark->population();
if ( diameter >= 0 )
{
hasPopularity = true;
placemark->setPopularity( diameter );
if (placemarkRole == QLatin1String("c")) {
placemark->setZoomLevel( spacePopIdx( diameter ) );
if (placemark->name() == QLatin1String("Tycho") ||
placemark->name() == QLatin1String("Copernicus")) {
placemark->setZoomLevel( 1 );
}
}
else {
placemark->setZoomLevel( spacePopIdx( diameter ) );
}
if (placemarkRole == QLatin1String("a") && diameter == 0) {
placemark->setPopularity( 1000000000 );
placemark->setZoomLevel( 1 );
}
}
}
else
{
qint64 population = placemark->population();
if ( population >= 0 )
{
hasPopularity = true;
placemark->setPopularity( population );
placemark->setZoomLevel( cityPopIdx( population ) );
}
}
// Then we set the visual category:
if (placemarkRole == QLatin1String("H")) placemark->setVisualCategory( GeoDataPlacemark::Mountain );
else if (placemarkRole == QLatin1String("V")) placemark->setVisualCategory( GeoDataPlacemark::Volcano );
else if (placemarkRole == QLatin1String("m")) placemark->setVisualCategory( GeoDataPlacemark::Mons );
else if (placemarkRole == QLatin1String("v")) placemark->setVisualCategory( GeoDataPlacemark::Valley );
else if (placemarkRole == QLatin1String("o")) placemark->setVisualCategory( GeoDataPlacemark::OtherTerrain );
else if (placemarkRole == QLatin1String("c")) placemark->setVisualCategory( GeoDataPlacemark::Crater );
else if (placemarkRole == QLatin1String("a")) placemark->setVisualCategory( GeoDataPlacemark::Mare );
else if (placemarkRole == QLatin1String("P")) placemark->setVisualCategory( GeoDataPlacemark::GeographicPole );
else if (placemarkRole == QLatin1String("M")) placemark->setVisualCategory( GeoDataPlacemark::MagneticPole );
else if (placemarkRole == QLatin1String("W")) placemark->setVisualCategory( GeoDataPlacemark::ShipWreck );
else if (placemarkRole == QLatin1String("F")) placemark->setVisualCategory( GeoDataPlacemark::AirPort );
else if (placemarkRole == QLatin1String("A")) placemark->setVisualCategory( GeoDataPlacemark::Observatory );
else if (placemarkRole == QLatin1String("K")) placemark->setVisualCategory( GeoDataPlacemark::Continent );
else if (placemarkRole == QLatin1String("O")) placemark->setVisualCategory( GeoDataPlacemark::Ocean );
else if (placemarkRole == QLatin1String("S")) placemark->setVisualCategory( GeoDataPlacemark::Nation );
else if (placemarkRole == QLatin1String("PPL") ||
placemarkRole == QLatin1String("PPLF") ||
placemarkRole == QLatin1String("PPLG") ||
placemarkRole == QLatin1String("PPLL") ||
placemarkRole == QLatin1String("PPLQ") ||
placemarkRole == QLatin1String("PPLR") ||
placemarkRole == QLatin1String("PPLS") ||
placemarkRole == QLatin1String("PPLW")) {
switch (placemark->zoomLevel()) {
case 3:
case 4:
placemark->setVisualCategory(GeoDataPlacemark::LargeCity);
break;
case 5:
case 6:
placemark->setVisualCategory(GeoDataPlacemark::BigCity);
break;
case 7:
case 8:
placemark->setVisualCategory(GeoDataPlacemark::MediumCity);
break;
default:
placemark->setVisualCategory(GeoDataPlacemark::SmallCity);
break;
}
}
else if (placemarkRole == QLatin1String("PPLA")) {
switch (placemark->zoomLevel()) {
case 3:
case 4:
placemark->setVisualCategory(GeoDataPlacemark::LargeStateCapital);
break;
case 5:
case 6:
placemark->setVisualCategory(GeoDataPlacemark::BigStateCapital);
break;
case 7:
case 8:
placemark->setVisualCategory(GeoDataPlacemark::MediumStateCapital);
break;
default:
placemark->setVisualCategory(GeoDataPlacemark::SmallStateCapital);
break;
}
}
else if (placemarkRole == QLatin1String("PPLC")) {
switch (placemark->zoomLevel()) {
case 3:
case 4:
placemark->setVisualCategory(GeoDataPlacemark::LargeNationCapital);
break;
case 5:
case 6:
placemark->setVisualCategory(GeoDataPlacemark::BigNationCapital);
break;
case 7:
case 8:
placemark->setVisualCategory(GeoDataPlacemark::MediumNationCapital);
break;
default:
placemark->setVisualCategory(GeoDataPlacemark::SmallNationCapital);
break;
}
}
else if (placemarkRole == QLatin1String("PPLA2") ||
placemarkRole == QLatin1String("PPLA3") ||
placemarkRole == QLatin1String("PPLA4")) {
switch (placemark->zoomLevel()) {
case 3:
case 4:
placemark->setVisualCategory(GeoDataPlacemark::LargeCountyCapital);
break;
case 5:
case 6:
placemark->setVisualCategory(GeoDataPlacemark::BigCountyCapital);
break;
case 7:
case 8:
placemark->setVisualCategory(GeoDataPlacemark::MediumCountyCapital);
break;
default:
placemark->setVisualCategory(GeoDataPlacemark::SmallCountyCapital);
break;
}
}
else if (placemarkRole == QLatin1String(" ") && !hasPopularity && placemark->visualCategory() == GeoDataPlacemark::Unknown) {
placemark->setVisualCategory( GeoDataPlacemark::Unknown ); // default location
placemark->setZoomLevel(0);
}
else if (placemarkRole == QLatin1String("h")) {
placemark->setVisualCategory( GeoDataPlacemark::MannedLandingSite );
}
else if (placemarkRole == QLatin1String("r")) {
placemark->setVisualCategory( GeoDataPlacemark::RoboticRover );
}
else if (placemarkRole == QLatin1String("u")) {
placemark->setVisualCategory( GeoDataPlacemark::UnmannedSoftLandingSite );
}
else if (placemarkRole == QLatin1String("i")) {
placemark->setVisualCategory( GeoDataPlacemark::UnmannedHardLandingSite );
}
// At last fine-tune zoomlevel:
if (!placemark->isVisible()) {
placemark->setZoomLevel( 18 );
}
// Workaround: Emulate missing "setVisible" serialization by allowing for population
// values smaller than -1 which are considered invisible.
else if (placemark->population() < -1) {
placemark->setZoomLevel( 18 );
}
else if (placemarkRole == QLatin1String("W")) {
if (placemark->zoomLevel() < 4) {
placemark->setZoomLevel( 4 );
}
}
else if (placemarkRole == QLatin1String("O")) {
placemark->setZoomLevel( 2 );
}
else if (placemarkRole == QLatin1String("K")) {
placemark->setZoomLevel( 0 );
}
} else {
qWarning() << Q_FUNC_INFO << "Unknown feature" << (*i)->nodeType() << ". Skipping.";
}
}
}
int FileLoaderPrivate::cityPopIdx( qint64 population )
{
int popidx = 3;
if ( population < 2500 ) popidx=10;
else if ( population < 5000) popidx=9;
else if ( population < 25000) popidx=8;
else if ( population < 75000) popidx=7;
else if ( population < 250000) popidx=6;
else if ( population < 750000) popidx=5;
else if ( population < 2500000) popidx=4;
return popidx;
}
int FileLoaderPrivate::spacePopIdx( qint64 population )
{
int popidx = 1;
if ( population < 1000 ) popidx=10;
else if ( population < 2000) popidx=9;
else if ( population < 8000) popidx=8;
else if ( population < 20000) popidx=7;
else if ( population < 60000) popidx=6;
else if ( population < 100000) popidx=5;
else if ( population < 200000 ) popidx=4;
else if ( population < 400000 ) popidx=2;
else if ( population < 600000 ) popidx=1;
return popidx;
}
int FileLoaderPrivate::areaPopIdx( qreal area )
{
int popidx = 1;
if ( area < 200000 ) popidx=5;
else if ( area < 1000000 ) popidx=4;
else if ( area < 2500000 ) popidx=3;
else if ( area < 5000000 ) popidx=2;
return popidx;
}
#include "moc_FileLoader.cpp"
} // namespace Marble
diff --git a/src/lib/marble/FileManager.cpp b/src/lib/marble/FileManager.cpp
index c73fb0368..bed549efe 100644
--- a/src/lib/marble/FileManager.cpp
+++ b/src/lib/marble/FileManager.cpp
@@ -1,211 +1,211 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
#include "FileManager.h"
#include <QFileInfo>
#include <QTime>
#include <QMessageBox>
#include "FileLoader.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "GeoDataTreeModel.h"
#include "GeoDataDocument.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataStyle.h"
using namespace Marble;
namespace Marble
{
class FileManagerPrivate
{
public:
FileManagerPrivate( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, FileManager* parent ) :
q( parent ),
m_treeModel( treeModel ),
m_pluginManager( pluginManager )
{
}
~FileManagerPrivate()
{
for ( FileLoader *loader: m_loaderList ) {
if ( loader ) {
loader->wait();
}
}
}
void appendLoader( FileLoader *loader );
void closeFile( const QString &key );
void cleanupLoader( FileLoader *loader );
FileManager *const q;
GeoDataTreeModel *const m_treeModel;
const PluginManager *const m_pluginManager;
QList<FileLoader*> m_loaderList;
QHash < QString, GeoDataDocument* > m_fileItemHash;
GeoDataLatLonBox m_latLonBox;
QTime m_timer;
};
}
FileManager::FileManager( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, QObject *parent )
: QObject( parent )
, d( new FileManagerPrivate( treeModel, pluginManager, this ) )
{
}
FileManager::~FileManager()
{
delete d;
}
void FileManager::addFile( const QString& filepath, const QString& property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder, bool recenter )
{
if( d->m_fileItemHash.contains( filepath ) ) {
return; // already loaded
}
for ( const FileLoader *loader: d->m_loaderList ) {
if ( loader->path() == filepath )
return; // currently loading
}
mDebug() << "adding container:" << filepath;
mDebug() << "Starting placemark loading timer";
d->m_timer.start();
FileLoader* loader = new FileLoader( this, d->m_pluginManager, recenter, filepath, property, style, role, renderOrder );
d->appendLoader( loader );
}
void FileManager::addData( const QString &name, const QString &data, DocumentRole role )
{
FileLoader* loader = new FileLoader( this, d->m_pluginManager, data, name, role );
d->appendLoader( loader );
}
void FileManagerPrivate::appendLoader( FileLoader *loader )
{
QObject::connect( loader, SIGNAL(loaderFinished(FileLoader*)),
q, SLOT(cleanupLoader(FileLoader*)) );
m_loaderList.append( loader );
loader->start();
}
void FileManager::removeFile( const QString& key )
{
for ( FileLoader *loader: d->m_loaderList ) {
if ( loader->path() == key ) {
- disconnect( loader, 0, this, 0 );
+ disconnect( loader, nullptr, this, nullptr );
loader->wait();
d->m_loaderList.removeAll( loader );
delete loader->document();
return;
}
}
if( d->m_fileItemHash.contains( key ) ) {
d->closeFile( key );
}
mDebug() << "could not identify " << key;
}
void FileManagerPrivate::closeFile( const QString& key )
{
mDebug() << "FileManager::closeFile " << key;
if( m_fileItemHash.contains( key ) ) {
GeoDataDocument *doc = m_fileItemHash.value( key );
m_treeModel->removeDocument( doc );
emit q->fileRemoved( key );
delete doc;
m_fileItemHash.remove( key );
}
}
void FileManager::closeFile( const GeoDataDocument *document )
{
QHash < QString, GeoDataDocument* >::iterator itpoint = d->m_fileItemHash.begin();
QHash < QString, GeoDataDocument* >::iterator const endpoint = d->m_fileItemHash.end();
for (; itpoint != endpoint; ++itpoint ) {
if( d->m_fileItemHash.value( itpoint.key() ) == document ) {
d->closeFile( itpoint.key() );
return;
}
}
}
int FileManager::size() const
{
return d->m_fileItemHash.size();
}
GeoDataDocument * FileManager::at( const QString &key )
{
if ( d->m_fileItemHash.contains( key ) ) {
return d->m_fileItemHash.value( key );
}
- return 0;
+ return nullptr;
}
int FileManager::pendingFiles() const
{
return d->m_loaderList.size();
}
void FileManagerPrivate::cleanupLoader( FileLoader* loader )
{
GeoDataDocument *doc = loader->document();
m_loaderList.removeAll( loader );
if ( loader->isFinished() ) {
if ( doc ) {
if ( doc->name().isEmpty() && !doc->fileName().isEmpty() )
{
QFileInfo file( doc->fileName() );
doc->setName( file.baseName() );
}
m_treeModel->addDocument( doc );
m_fileItemHash.insert( loader->path(), doc );
emit q->fileAdded( loader->path() );
if( loader->recenter() ) {
m_latLonBox |= doc->latLonAltBox();
}
}
if ( !loader->error().isEmpty() ) {
QMessageBox errorBox;
errorBox.setWindowTitle( QObject::tr("File Parsing Error"));
errorBox.setText( loader->error() );
errorBox.setIcon( QMessageBox::Warning );
errorBox.exec();
qWarning() << "File Parsing error " << loader->error();
}
delete loader;
}
if ( m_loaderList.isEmpty() )
{
mDebug() << "Finished loading all placemarks " << m_timer.elapsed();
if ( !m_latLonBox.isEmpty() ) {
emit q->centeredDocument( m_latLonBox );
}
m_latLonBox.clear();
}
}
#include "moc_FileManager.cpp"
diff --git a/src/lib/marble/FileManager.h b/src/lib/marble/FileManager.h
index dda834f71..cb9b69bfc 100644
--- a/src/lib/marble/FileManager.h
+++ b/src/lib/marble/FileManager.h
@@ -1,95 +1,95 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
#ifndef MARBLE_FILEMANAGER_H
#define MARBLE_FILEMANAGER_H
#include "GeoDataDocument.h"
#include <QObject>
class QString;
namespace Marble
{
class FileManagerPrivate;
class FileLoader;
class GeoDataLatLonBox;
class GeoDataTreeModel;
class PluginManager;
/**
* This class is responsible for loading the
* different files into Geodata model.
*
* The loaded data are accessible via
* various models in MarbleModel.
*/
class FileManager : public QObject
{
Q_OBJECT
public:
/**
* Creates a new file manager.
*
* @param parent The parent object.
*/
- explicit FileManager( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, QObject *parent = 0 );
+ explicit FileManager( GeoDataTreeModel *treeModel, const PluginManager *pluginManager, QObject *parent = nullptr );
/**
* Destroys the file manager.
*/
~FileManager() override;
/**
* Loads a new file into the manager.
*/
void addFile(const QString &fileName, const QString &property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder = 0, bool recenter = false );
/**
* removes an existing file from the manager
*/
void removeFile( const QString &fileName );
/**
* add Data containing KML code as string
*/
void addData( const QString &name, const QString &data, DocumentRole role );
void closeFile( const GeoDataDocument *document );
int size() const;
GeoDataDocument *at( const QString &key );
/** Returns the number of files being opened at the moment */
int pendingFiles() const;
Q_SIGNALS:
void fileAdded( const QString &key );
void fileRemoved( const QString &key );
void centeredDocument( const GeoDataLatLonBox& );
private:
Q_PRIVATE_SLOT( d, void cleanupLoader( FileLoader *loader ) )
Q_DISABLE_COPY( FileManager )
friend class FileManagerPrivate;
FileManagerPrivate *const d;
};
}
#endif
diff --git a/src/lib/marble/FileStoragePolicy.h b/src/lib/marble/FileStoragePolicy.h
index 246eb1a21..f83d9b36a 100644
--- a/src/lib/marble/FileStoragePolicy.h
+++ b/src/lib/marble/FileStoragePolicy.h
@@ -1,65 +1,65 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Tobias Koenig <tokoe@kde.org>
//
#ifndef MARBLE_FILESTORAGEPOLICY_H
#define MARBLE_FILESTORAGEPOLICY_H
#include "StoragePolicy.h"
namespace Marble
{
class FileStoragePolicy : public StoragePolicy
{
Q_OBJECT
public:
/**
* Creates a new file storage policy.
*
* @param dataDirectory The directory where the data should go to.
*/
- explicit FileStoragePolicy( const QString &dataDirectory = QString(), QObject *parent = 0 );
+ explicit FileStoragePolicy( const QString &dataDirectory = QString(), QObject *parent = nullptr );
/**
* Destroys the cache storage policy.
*/
~FileStoragePolicy() override;
/**
* Returns whether the @p fileName exists already.
*/
bool fileExists( const QString &fileName ) const override;
/**
* Updates the @p fileName with the given @p data.
*/
bool updateFile( const QString &fileName, const QByteArray &data ) override;
/**
* Clears the cache.
*/
void clearCache() override;
/**
* Returns the last error message.
*/
QString lastErrorMessage() const override;
private:
Q_DISABLE_COPY( FileStoragePolicy )
QString m_dataDirectory;
QString m_errorMsg;
};
}
#endif
diff --git a/src/lib/marble/FileStorageWatcher.cpp b/src/lib/marble/FileStorageWatcher.cpp
index c8146555e..c67c58b41 100644
--- a/src/lib/marble/FileStorageWatcher.cpp
+++ b/src/lib/marble/FileStorageWatcher.cpp
@@ -1,278 +1,278 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Own
#include "FileStorageWatcher.h"
// Qt
#include <QDir>
#include <QDirIterator>
#include <QFileInfo>
#include <QTimer>
// Marble
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
using namespace Marble;
// Only remove 20 files without checking
// changed cacheLimits and changed themes etc.
static const int maxFilesDelete = 20;
static const int softLimitPercent = 5;
// Methods of FileStorageWatcherThread
FileStorageWatcherThread::FileStorageWatcherThread( const QString &dataDirectory, QObject *parent )
: QObject( parent ),
m_dataDirectory( dataDirectory ),
m_deleting( false ),
m_willQuit( false )
{
// For now setting cache limit to 0. This won't delete anything
setCacheLimit( 0 );
connect( this, SIGNAL(variableChanged()),
this, SLOT(ensureCacheSize()),
Qt::QueuedConnection );
emit variableChanged();
}
FileStorageWatcherThread::~FileStorageWatcherThread()
{
}
quint64 FileStorageWatcherThread::cacheLimit()
{
return m_cacheLimit;
}
void FileStorageWatcherThread::setCacheLimit( quint64 bytes )
{
m_limitMutex.lock();
m_cacheLimit = bytes;
m_cacheSoftLimit = bytes / 100 * ( 100 - softLimitPercent );
m_limitMutex.unlock();
emit variableChanged();
}
void FileStorageWatcherThread::addToCurrentSize( qint64 bytes )
{
// mDebug() << "Current cache size changed by " << bytes;
qint64 changedSize = bytes + m_currentCacheSize;
if( changedSize >= 0 )
m_currentCacheSize = changedSize;
else
m_currentCacheSize = 0;
emit variableChanged();
}
void FileStorageWatcherThread::resetCurrentSize()
{
m_currentCacheSize = 0;
emit variableChanged();
}
void FileStorageWatcherThread::prepareQuit()
{
m_willQuit = true;
}
void FileStorageWatcherThread::getCurrentCacheSize()
{
mDebug() << "FileStorageWatcher: Creating cache size";
quint64 dataSize = 0;
const QString basePath = m_dataDirectory + QLatin1String("/maps");
QDirIterator it( basePath,
QDir::Files | QDir::Writable,
QDirIterator::Subdirectories );
const int basePathDepth = basePath.split(QLatin1Char('/')).size();
while( it.hasNext() && !m_willQuit ) {
it.next();
QFileInfo file = it.fileInfo();
// We try to be very careful and just delete images
// FIXME, when vectortiling I suppose also vector tiles will have
// to be deleted
QString suffix = file.suffix().toLower();
const QStringList path = file.path().split(QLatin1Char('/'));
// planet/theme/tilelevel should be deeper than 4
if ( ( path.size() > basePathDepth + 3 ) &&
( path[basePathDepth + 2].toInt() >= maxBaseTileLevel ) &&
((suffix == QLatin1String("jpg") ||
suffix == QLatin1String("png") ||
suffix == QLatin1String("gif") ||
suffix == QLatin1String("svg")))) {
dataSize += file.size();
m_filesCache.insert(file.lastModified(), file.absoluteFilePath());
}
}
m_currentCacheSize = dataSize;
}
void FileStorageWatcherThread::ensureCacheSize()
{
// mDebug() << "Size of tile cache: " << m_currentCacheSize;
// We start deleting files if m_currentCacheSize is larger than
// the hard cache limit. Then we delete files until our cache size
// is smaller than the cache limit.
// m_cacheLimit = 0 means no limit.
if( ( ( m_currentCacheSize > m_cacheLimit )
|| ( m_deleting && ( m_currentCacheSize > m_cacheSoftLimit ) ) )
&& ( m_cacheLimit != 0 )
&& ( m_cacheSoftLimit != 0 )
&& !m_willQuit ) {
mDebug() << "Deleting extra cached tiles";
// The counter for deleted files
m_filesDeleted = 0;
// We have not reached our soft limit, yet.
m_deleting = true;
QMultiMap<QDateTime, QString>::iterator it= m_filesCache.begin();
while ( it != m_filesCache.end() &&
keepDeleting() ) {
QString filePath = it.value();
QFileInfo info( filePath );
m_filesDeleted++;
m_currentCacheSize -= info.size();
it = m_filesCache.erase(it);
QFile::remove( filePath );
}
// We have deleted enough files.
// Perhaps there are changes.
if( m_filesDeleted > maxFilesDelete ) {
QTimer::singleShot( 1000, this, SLOT(ensureCacheSize()) );
return;
}
else {
// We haven't stopped because of too many files
m_deleting = false;
}
if( m_currentCacheSize > m_cacheSoftLimit ) {
mDebug() << "FileStorageWatcher: Could not set cache size.";
// Set the cache limit to a higher value, so we won't start
// trying to delete something next time. Softlimit is now exactly
// on the current cache size.
setCacheLimit( m_currentCacheSize / ( 100 - softLimitPercent ) * 100 );
}
}
}
bool FileStorageWatcherThread::keepDeleting() const
{
return ( ( m_currentCacheSize > m_cacheSoftLimit ) &&
( m_filesDeleted <= maxFilesDelete ) &&
!m_willQuit );
}
// End of methods of our Thread
// Beginning of Methods of the main class
FileStorageWatcher::FileStorageWatcher( const QString &dataDirectory, QObject * parent )
: QThread( parent ),
m_dataDirectory( dataDirectory )
{
if ( m_dataDirectory.isEmpty() )
m_dataDirectory = MarbleDirs::localPath() + QLatin1String("/cache/");
if ( ! QDir( m_dataDirectory ).exists() )
QDir::root().mkpath( m_dataDirectory );
m_started = false;
m_limitMutex = new QMutex();
- m_thread = 0;
+ m_thread = nullptr;
m_quitting = false;
}
FileStorageWatcher::~FileStorageWatcher()
{
mDebug() << "Deleting FileStorageWatcher";
// Making sure that Thread is stopped.
m_quitting = true;
if( m_thread )
m_thread->prepareQuit();
quit();
if( !wait( 5000 ) ) {
mDebug() << "Failed to stop FileStorageWatcher-Thread, terminating!";
terminate();
}
delete m_thread;
delete m_limitMutex;
}
void FileStorageWatcher::setCacheLimit( quint64 bytes )
{
QMutexLocker locker( m_limitMutex );
if( m_started )
// This is done directly to ensure that a running ensureCacheSize()
// recognizes the new size.
m_thread->setCacheLimit( bytes );
// Save the limit, thread has to be initialized with the right one.
m_limit = bytes;
}
quint64 FileStorageWatcher::cacheLimit()
{
if( m_started )
return m_thread->cacheLimit();
else
return m_limit;
}
void FileStorageWatcher::addToCurrentSize( qint64 bytes )
{
emit sizeChanged( bytes );
}
void FileStorageWatcher::resetCurrentSize()
{
emit cleared();
}
void FileStorageWatcher::run()
{
m_thread = new FileStorageWatcherThread( m_dataDirectory );
if( !m_quitting ) {
m_limitMutex->lock();
m_thread->setCacheLimit( m_limit );
m_started = true;
m_limitMutex->unlock();
m_thread->getCurrentCacheSize();
connect( this, SIGNAL(sizeChanged(qint64)),
m_thread, SLOT(addToCurrentSize(qint64)) );
connect( this, SIGNAL(cleared()),
m_thread, SLOT(resetCurrentSize()) );
// Make sure that we don't want to stop process.
// The thread wouldn't exit from event loop.
if( !m_quitting )
exec();
m_started = false;
}
delete m_thread;
- m_thread = 0;
+ m_thread = nullptr;
}
// End of all methods
#include "moc_FileStorageWatcher.cpp"
diff --git a/src/lib/marble/FileStorageWatcher.h b/src/lib/marble/FileStorageWatcher.h
index 25ca469eb..2b17470d1 100644
--- a/src/lib/marble/FileStorageWatcher.h
+++ b/src/lib/marble/FileStorageWatcher.h
@@ -1,157 +1,157 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_FILESTORAGEWATCHER_H
#define MARBLE_FILESTORAGEWATCHER_H
#include <QThread>
#include <QMutex>
#include <QMultiMap>
#include <QDateTime>
namespace Marble
{
// Lives inside the new Thread
class FileStorageWatcherThread : public QObject
{
Q_OBJECT
public:
- explicit FileStorageWatcherThread( const QString &dataDirectory, QObject * parent = 0 );
+ explicit FileStorageWatcherThread( const QString &dataDirectory, QObject * parent = nullptr );
~FileStorageWatcherThread() override;
quint64 cacheLimit();
Q_SIGNALS:
/**
* Is emitted when a variable has changed.
*/
void variableChanged();
public Q_SLOTS:
/**
* Sets the limit of the cache in @p bytes.
*/
void setCacheLimit( quint64 bytes );
/**
* Add @p bytes to the current cache size.
* So FileStorageWatcher is aware of the current cache size.
*/
void addToCurrentSize( qint64 bytes );
/**
* Setting current cache size to 0.
*/
void resetCurrentSize();
/**
* Stop doing things that take a long time to quit.
*/
void prepareQuit();
/**
* Getting the current size of the data stored on the disc
*/
void getCurrentCacheSize();
private Q_SLOTS:
/**
* Ensures that the cache doesn't exceed limits.
*/
void ensureCacheSize();
private:
Q_DISABLE_COPY( FileStorageWatcherThread )
/**
* Returns true if it is necessary to delete files.
*/
bool keepDeleting() const;
QString m_dataDirectory;
QMultiMap<QDateTime,QString> m_filesCache;
quint64 m_cacheLimit;
quint64 m_cacheSoftLimit;
quint64 m_currentCacheSize;
int m_filesDeleted;
bool m_deleting;
QMutex m_limitMutex;
bool m_willQuit;
};
// Lives inside main thread
class FileStorageWatcher : public QThread
{
Q_OBJECT
public:
/**
* Creates a new FileStorageWatcher, which is a thread watching the
* space Marble takes on the hard drive and deletes files if necessary.
*
* @param dataDirectory The directory where the data is stored
* @param parent The parent of the object.
*/
- explicit FileStorageWatcher( const QString &dataDirectory = QString(), QObject * parent = 0 );
+ explicit FileStorageWatcher( const QString &dataDirectory = QString(), QObject * parent = nullptr );
~FileStorageWatcher() override;
/**
* Returns the limit of the cache in bytes.
*/
quint64 cacheLimit();
public Q_SLOTS:
/**
* Sets the limit of the cache in @p bytes.
*/
void setCacheLimit( quint64 bytes );
/**
* Add @p bytes to the current cache size.
* So FileStorageWatcher is aware of the current cache size.
*/
void addToCurrentSize( qint64 bytes );
/**
* Setting current cache size to 0.
*/
void resetCurrentSize();
Q_SIGNALS:
void sizeChanged( qint64 bytes );
void cleared();
protected:
/**
* The function being called at starting Thread.
* The thread is started by QThread::start().
*/
void run() override;
private:
Q_DISABLE_COPY( FileStorageWatcher )
QString m_dataDirectory;
FileStorageWatcherThread *m_thread;
QMutex *m_limitMutex;
quint64 m_limit;
bool m_started;
bool m_quitting;
};
}
#endif
diff --git a/src/lib/marble/FileViewWidget.cpp b/src/lib/marble/FileViewWidget.cpp
index 695bc4e05..951925daa 100644
--- a/src/lib/marble/FileViewWidget.cpp
+++ b/src/lib/marble/FileViewWidget.cpp
@@ -1,230 +1,230 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "FileViewWidget.h"
// Qt
#include <QFileDialog>
#include <QMenu>
#include <QAction>
#include <QPointer>
// Marble
#include "GeoDataLatLonAltBox.h"
#include "GeoDataContainer.h"
#include "GeoDataDocument.h"
#include "GeoDataDocumentWriter.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTreeModel.h"
#include "FileManager.h"
#include "KmlElementDictionary.h"
#include "MarblePlacemarkModel.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "TreeViewDecoratorModel.h"
#include "EditPlacemarkDialog.h"
using namespace Marble;
// Ui
#include "ui_FileViewWidget.h"
namespace Marble
{
class FileViewWidgetPrivate
{
public:
explicit FileViewWidgetPrivate( FileViewWidget *parent );
void setTreeModel( GeoDataTreeModel *model );
void setFileManager( FileManager *manager );
public Q_SLOTS:
void saveFile();
void closeFile();
void enableFileViewActions();
void contextMenu(const QPoint &pt);
void showPlacemarkDialog();
public:
FileViewWidget *q;
Ui::FileViewWidget m_fileViewUi;
MarbleWidget *m_widget;
TreeViewDecoratorModel m_treeSortProxy;
FileManager *m_fileManager;
QMenu *m_contextMenu;
QAction *m_viewPropertiesAction;
};
FileViewWidgetPrivate::FileViewWidgetPrivate( FileViewWidget *parent )
:q( parent ),
- m_widget( 0 ),
- m_fileManager( 0 )
+ m_widget( nullptr ),
+ m_fileManager( nullptr )
{
m_contextMenu = new QMenu(q);
m_viewPropertiesAction = new QAction(q);
m_viewPropertiesAction->setText(QObject::tr("View Properties"));
m_contextMenu->addAction(m_viewPropertiesAction);
QObject::connect(m_viewPropertiesAction, SIGNAL(triggered()),
q, SLOT(showPlacemarkDialog()));
}
FileViewWidget::FileViewWidget( QWidget *parent, Qt::WindowFlags f )
: QWidget( parent, f ),
d( new FileViewWidgetPrivate( this ) )
{
d->m_fileViewUi.setupUi( this );
layout()->setMargin( 0 );
}
FileViewWidget::~FileViewWidget()
{
delete d;
}
void FileViewWidget::setMarbleWidget( MarbleWidget *widget )
{
d->m_widget = widget;
d->setTreeModel( d->m_widget->model()->treeModel() );
d->setFileManager( d->m_widget->model()->fileManager() );
connect( this, SIGNAL(centerOn(GeoDataPlacemark,bool)),
d->m_widget, SLOT(centerOn(GeoDataPlacemark,bool)) );
connect( this, SIGNAL(centerOn(GeoDataLatLonBox,bool)),
d->m_widget, SLOT(centerOn(GeoDataLatLonBox,bool)) );
}
void FileViewWidgetPrivate::setTreeModel( GeoDataTreeModel *model )
{
m_treeSortProxy.setSourceModel( model );
m_treeSortProxy.setDynamicSortFilter( true );
m_fileViewUi.m_treeView->setModel( &m_treeSortProxy );
m_fileViewUi.m_treeView->setSortingEnabled( true );
m_fileViewUi.m_treeView->sortByColumn( 0, Qt::AscendingOrder );
m_fileViewUi.m_treeView->resizeColumnToContents( 0 );
m_fileViewUi.m_treeView->resizeColumnToContents( 1 );
m_fileViewUi.m_treeView->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect( m_fileViewUi.m_treeView,
SIGNAL(expanded(QModelIndex)),
&m_treeSortProxy, SLOT(trackExpandedState(QModelIndex)) );
QObject::connect( m_fileViewUi.m_treeView,
SIGNAL(collapsed(QModelIndex)),
&m_treeSortProxy, SLOT(trackCollapsedState(QModelIndex)) );
QObject::connect( m_fileViewUi.m_treeView->selectionModel(),
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(enableFileViewActions()) );
QObject::connect( m_fileViewUi.m_treeView, SIGNAL(activated(QModelIndex)),
q, SLOT(mapCenterOnTreeViewModel(QModelIndex)) );
QObject::connect( m_fileViewUi.m_treeView, SIGNAL(customContextMenuRequested(QPoint)),
q, SLOT(contextMenu(QPoint)) );
}
void FileViewWidgetPrivate::setFileManager( FileManager *manager )
{
m_fileManager = manager;
QObject::connect( m_fileViewUi.m_saveButton, SIGNAL(clicked()) ,
q, SLOT(saveFile()) );
QObject::connect( m_fileViewUi.m_closeButton, SIGNAL(clicked()) ,
q, SLOT(closeFile()) );
}
void FileViewWidgetPrivate::saveFile()
{
QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
GeoDataObject *object
= index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
GeoDataDocument *document = dynamic_cast<GeoDataDocument*>(object);
if ( document && !document->fileName().isEmpty() ) {
const QString saveFileName = QFileDialog::getSaveFileName(q, QObject::tr("Select filename for KML document"));
GeoDataDocumentWriter::write(saveFileName, *document, kml::kmlTag_nameSpaceOgc22);
}
}
void FileViewWidgetPrivate::closeFile()
{
QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
GeoDataObject *object
= index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
GeoDataDocument *document = dynamic_cast<GeoDataDocument*>(object);
if ( document ) {
m_fileManager->closeFile( document );
}
}
void FileViewWidgetPrivate::enableFileViewActions()
{
bool isUserDocument = false;
if ( !m_fileViewUi.m_treeView->selectionModel()->selectedRows().isEmpty() ) {
QModelIndex index = m_fileViewUi.m_treeView->selectionModel()->selectedRows().first();
GeoDataObject *object
= index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
GeoDataDocument *document = dynamic_cast<GeoDataDocument*>(object);
if ( document ) {
isUserDocument = document->documentRole() == Marble::UserDocument;
}
}
m_fileViewUi.m_saveButton->setEnabled( isUserDocument );
m_fileViewUi.m_closeButton->setEnabled( isUserDocument );
}
void FileViewWidgetPrivate::contextMenu(const QPoint &pt)
{
const QModelIndex index = m_fileViewUi.m_treeView->indexAt(pt);
const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
if (index.isValid()) {
GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject*>();
const GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>(obj);
if (placemark) {
m_contextMenu->popup(m_fileViewUi.m_treeView->mapToGlobal(pt));
}
}
}
void FileViewWidgetPrivate::showPlacemarkDialog()
{
const QModelIndex index = m_fileViewUi.m_treeView->currentIndex();
const QAbstractItemModel *model = m_fileViewUi.m_treeView->model();
GeoDataObject *obj = model->data(index, MarblePlacemarkModel::ObjectPointerRole).value<GeoDataObject*>();
GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>(obj);
if (placemark) {
QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog(placemark, nullptr, q);
dialog->setReadOnly(true);
dialog->exec();
delete dialog;
}
}
void FileViewWidget::mapCenterOnTreeViewModel( const QModelIndex &index )
{
if( !index.isValid() ) {
return;
}
const GeoDataObject *object
= index.model()->data( index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
if (const GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(object)) {
d->m_widget->model()->placemarkSelectionModel()->select( index, QItemSelectionModel::ClearAndSelect );
emit centerOn( *placemark, true );
}
else if (const GeoDataContainer *container = dynamic_cast<const GeoDataContainer *>(object)) {
const GeoDataLatLonAltBox box = container->latLonAltBox();
emit centerOn( box, true );
}
}
}
#include "moc_FileViewWidget.cpp"
diff --git a/src/lib/marble/FileViewWidget.h b/src/lib/marble/FileViewWidget.h
index 7f0f042ea..a3f834b0e 100644
--- a/src/lib/marble/FileViewWidget.h
+++ b/src/lib/marble/FileViewWidget.h
@@ -1,62 +1,62 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_FILEVIEWWIDGET_H
#define MARBLE_FILEVIEWWIDGET_H
// Marble
#include "marble_export.h"
// Qt
#include <QWidget>
class QModelIndex;
namespace Marble
{
class GeoDataPlacemark;
class GeoDataLatLonBox;
class MarbleWidget;
class FileViewWidgetPrivate;
class MARBLE_EXPORT FileViewWidget : public QWidget
{
Q_OBJECT
public:
- explicit FileViewWidget( QWidget *parent = 0, Qt::WindowFlags f = 0 );
+ explicit FileViewWidget( QWidget *parent = nullptr, Qt::WindowFlags f = nullptr );
~FileViewWidget() override;
void setMarbleWidget( MarbleWidget *widget );
Q_SIGNALS:
void centerOn( const GeoDataPlacemark &, bool animated );
void centerOn( const GeoDataLatLonBox &, bool animated );
private Q_SLOTS:
void mapCenterOnTreeViewModel( const QModelIndex & );
private:
Q_PRIVATE_SLOT( d, void enableFileViewActions() )
Q_PRIVATE_SLOT( d, void saveFile() )
Q_PRIVATE_SLOT( d, void closeFile() )
Q_PRIVATE_SLOT( d, void contextMenu(const QPoint&) )
Q_PRIVATE_SLOT( d, void showPlacemarkDialog() )
Q_DISABLE_COPY( FileViewWidget )
FileViewWidgetPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/FlyToEditWidget.cpp b/src/lib/marble/FlyToEditWidget.cpp
index bb5e817a8..1e1f3fd55 100644
--- a/src/lib/marble/FlyToEditWidget.cpp
+++ b/src/lib/marble/FlyToEditWidget.cpp
@@ -1,155 +1,155 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
// Copyright 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include <QDoubleSpinBox>
#include <QToolButton>
#include <QLabel>
#include <QHBoxLayout>
#include <QComboBox>
#include "FlyToEditWidget.h"
#include "MarbleWidget.h"
#include "geodata/data/GeoDataFlyTo.h"
#include "GeoDataLookAt.h"
#include "GeoDataCamera.h"
#include "MarblePlacemarkModel.h"
namespace Marble
{
FlyToEditWidget::FlyToEditWidget( const QModelIndex &index, MarbleWidget* widget, QWidget *parent ) :
QWidget( parent ),
m_widget( widget ),
m_index( index ),
m_button( new QToolButton )
{
QHBoxLayout *layout = new QHBoxLayout;
layout->setSpacing( 5 );
QLabel* iconLabel = new QLabel;
iconLabel->setPixmap(QPixmap(QStringLiteral(":/marble/flag.png")));
layout->addWidget( iconLabel );
QHBoxLayout *pairLayout = new QHBoxLayout;
pairLayout->setSpacing( 10 );
QHBoxLayout *durationLayout = new QHBoxLayout;
durationLayout->setSpacing( 5 );
QLabel *durationLabel = new QLabel;
durationLabel->setText( tr("Duration:") );
durationLayout->addWidget( durationLabel );
m_durationSpin = new QDoubleSpinBox;
durationLayout->addWidget( m_durationSpin );
m_durationSpin->setValue( flyToElement()->duration() );
m_durationSpin->setSuffix( tr(" s", "seconds") );
QHBoxLayout *modeLayout = new QHBoxLayout;
modeLayout->addSpacing( 5 );
QLabel *modeLabel = new QLabel;
modeLabel->setText( tr("Mode:") );
modeLayout->addWidget( modeLabel );
m_modeCombo = new QComboBox;
modeLayout->addWidget( m_modeCombo );
m_modeCombo->addItem( tr("Smooth") );
m_modeCombo->addItem( tr("Bounce") );
if( flyToElement()->flyToMode() == GeoDataFlyTo::Smooth ){
m_modeCombo->setCurrentIndex( 0 );
} else if( flyToElement()->flyToMode() == GeoDataFlyTo::Bounce ){
m_modeCombo->setCurrentIndex( 1 );
} else {
m_modeCombo->setCurrentIndex( -1 );
}
pairLayout->addLayout( durationLayout );
pairLayout->addLayout( modeLayout );
layout->addLayout( pairLayout );
QToolButton* flyToPinCenter = new QToolButton;
flyToPinCenter->setIcon(QIcon(QStringLiteral(":/marble/places.png")));
flyToPinCenter->setToolTip(tr("Current map center"));
connect(flyToPinCenter, SIGNAL(clicked()), this, SLOT(updateCoordinates()));
layout->addWidget(flyToPinCenter);
m_button->setIcon(QIcon(QStringLiteral(":/marble/document-save.png")));
connect(m_button, SIGNAL(clicked()), this, SLOT(save()));
layout->addWidget( m_button );
setLayout( layout );
}
bool FlyToEditWidget::editable() const
{
return m_button->isEnabled();
}
void FlyToEditWidget::setEditable( bool editable )
{
m_button->setEnabled( editable );
}
void FlyToEditWidget::setFirstFlyTo(const QPersistentModelIndex &index)
{
if( m_index.internalPointer() == index.internalPointer() ) {
m_durationSpin->setValue(0);
}
}
void FlyToEditWidget::updateCoordinates()
{
m_coord = m_widget->focusPoint();
m_coord.setAltitude( m_widget->lookAt().range() );
}
void FlyToEditWidget::save()
{
- if (flyToElement()->view() != 0 && m_coord != GeoDataCoordinates()) {
+ if (flyToElement()->view() != nullptr && m_coord != GeoDataCoordinates()) {
GeoDataCoordinates coords = m_coord;
if (auto camera = geodata_cast<GeoDataCamera>(flyToElement()->view())) {
camera->setCoordinates( coords );
} else if (auto lookAt = geodata_cast<GeoDataLookAt>(flyToElement()->view())) {
lookAt->setCoordinates( coords );
} else{
lookAt = new GeoDataLookAt;
lookAt->setCoordinates( coords );
flyToElement()->setView( lookAt );
}
}
flyToElement()->setDuration(m_durationSpin->value());
if (m_modeCombo->currentIndex() == 0) {
flyToElement()->setFlyToMode( GeoDataFlyTo::Smooth );
} else if (m_modeCombo->currentIndex() == 1) {
flyToElement()->setFlyToMode( GeoDataFlyTo::Bounce );
}
emit editingDone(m_index);
}
GeoDataFlyTo* FlyToEditWidget::flyToElement()
{
GeoDataObject *object = qvariant_cast<GeoDataObject*>(m_index.data( MarblePlacemarkModel::ObjectPointerRole ) );
Q_ASSERT( object );
auto flyTo = geodata_cast<GeoDataFlyTo>(object);
Q_ASSERT(flyTo);
return flyTo;
}
} // namespace Marble
#include "moc_FlyToEditWidget.cpp"
diff --git a/src/lib/marble/FlyToEditWidget.h b/src/lib/marble/FlyToEditWidget.h
index 4f247a15f..774b11941 100644
--- a/src/lib/marble/FlyToEditWidget.h
+++ b/src/lib/marble/FlyToEditWidget.h
@@ -1,64 +1,64 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
// Copyright 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef FLYTOEDITWIDGET_H
#define FLYTOEDITWIDGET_H
#include <QWidget>
#include <QPersistentModelIndex>
#include "GeoDataCoordinates.h"
class QDoubleSpinBox;
class QToolButton;
class QComboBox;
namespace Marble
{
class GeoDataFlyTo;
class MarbleWidget;
class FlyToEditWidget: public QWidget
{
Q_OBJECT
public:
- FlyToEditWidget( const QModelIndex& index, MarbleWidget* widget, QWidget* parent=0 );
+ FlyToEditWidget( const QModelIndex& index, MarbleWidget* widget, QWidget* parent=nullptr );
bool editable() const;
Q_SIGNALS:
void editingDone( const QModelIndex& index );
public Q_SLOTS:
void setEditable( bool editable );
/** We disable editing of wait duration for first flyto in playlist. */
void setFirstFlyTo(const QPersistentModelIndex &index );
private Q_SLOTS:
void save();
void updateCoordinates();
private:
GeoDataFlyTo* flyToElement();
MarbleWidget* m_widget;
QPersistentModelIndex m_index;
QDoubleSpinBox *m_durationSpin;
QComboBox *m_modeCombo;
GeoDataCoordinates m_coord;
QToolButton *m_button;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/FormattedTextWidget.cpp b/src/lib/marble/FormattedTextWidget.cpp
index 2885af4ef..b1a4c20c0 100644
--- a/src/lib/marble/FormattedTextWidget.cpp
+++ b/src/lib/marble/FormattedTextWidget.cpp
@@ -1,259 +1,259 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
// Copyright 2015 Constantin Mihalache <mihalache.c94@gmail.com>
//
//self
#include "FormattedTextWidget.h"
#include "ui_FormattedTextWidget.h"
//Qt
#include <QFileDialog>
#include <QColorDialog>
#include <QFontComboBox>
#include <QLineEdit>
#include <QPointer>
//Marble
#include "MarbleWidget.h"
#include "AddLinkDialog.h"
namespace Marble{
class Q_DECL_HIDDEN FormattedTextWidget::Private : public Ui::FormattedTextWidget
{
public:
Private();
~Private();
QColorDialog *m_textColorDialog;
};
FormattedTextWidget::Private::Private() :
Ui::FormattedTextWidget(),
- m_textColorDialog( 0 )
+ m_textColorDialog( nullptr )
{
//nothing to do
}
FormattedTextWidget::Private::~Private()
{
delete m_textColorDialog;
}
FormattedTextWidget::FormattedTextWidget( QWidget *parent ) :
QWidget( parent ),
d( new Private() )
{
d->setupUi( this );
d->m_formattedTextToolBar->insertSeparator( d->m_actionAddImage );
QPixmap textColorPixmap(20, 20);
textColorPixmap.fill( d->m_description->textCursor().charFormat().foreground().color() );
d->m_actionColor->setIcon( textColorPixmap );
d->m_textColorDialog = new QColorDialog( this );
d->m_textColorDialog->setOption( QColorDialog::ShowAlphaChannel );
d->m_textColorDialog->setCurrentColor( d->m_description->textCursor().charFormat().foreground().color() );
d->m_fontSize->setValidator( new QIntValidator( 1, 9000, this ) );
int index = d->m_fontSize->findText( QString::number( d->m_description->textCursor().charFormat().font().pointSize() ) );
if( index != -1 ) {
d->m_fontSize->setCurrentIndex( index );
} else {
d->m_fontSize->lineEdit()->setText( QString::number( d->m_description->textCursor().charFormat().font().pointSize() ) );
}
connect( d->m_actionColor, SIGNAL(triggered()), d->m_textColorDialog, SLOT(exec()) );
connect( d->m_textColorDialog, SIGNAL(colorSelected(QColor)), this, SLOT(setTextCursorColor(QColor)) );
connect( d->m_isFormattedTextMode, SIGNAL(toggled(bool)), this, SLOT(toggleDescriptionEditMode(bool)) );
connect( d->m_fontFamily, SIGNAL(currentFontChanged(QFont)), this, SLOT(setTextCursorFont(QFont)) );
connect( d->m_fontSize, SIGNAL(editTextChanged(QString)), this, SLOT(setTextCursorFontSize(QString)) );
connect( d->m_actionBold, SIGNAL(toggled(bool)), this, SLOT(setTextCursorBold(bool)) );
connect( d->m_actionItalics, SIGNAL(toggled(bool)), this, SLOT(setTextCursorItalic(bool)) );
connect( d->m_actionUnderlined, SIGNAL(toggled(bool)), this, SLOT(setTextCursorUnderlined(bool)) );
connect( d->m_actionAddImage, SIGNAL(triggered()), this, SLOT(addImageToDescription()) );
connect( d->m_actionAddLink, SIGNAL(triggered()), this, SLOT(addLinkToDescription()) );
connect( d->m_description, SIGNAL(cursorPositionChanged()), this, SLOT(updateDescriptionEditButtons()) );
}
FormattedTextWidget::~FormattedTextWidget()
{
delete d;
}
void FormattedTextWidget::setText( const QString &text )
{
d->m_description->setHtml( text );
}
const QString FormattedTextWidget::text()
{
return d->m_description->toHtml();
}
void FormattedTextWidget::toggleDescriptionEditMode( bool isFormattedTextMode )
{
d->m_formattedTextToolBar->setVisible( isFormattedTextMode );
d->m_fontSize->setVisible( isFormattedTextMode );
d->m_fontFamily->setVisible( isFormattedTextMode );
if( isFormattedTextMode ) {
d->m_description->setHtml( d->m_description->toPlainText() );
} else {
QTextCursor cursor = d->m_description->textCursor();
QTextCharFormat format;
format.setFont( QFont() );
format.setFontWeight( QFont::Normal );
format.setFontItalic( false );
format.setFontUnderline( false );
format.clearForeground();
cursor.setCharFormat( format );
d->m_description->setTextCursor( cursor );
d->m_description->setPlainText( d->m_description->toHtml() );
}
}
void FormattedTextWidget::setTextCursorBold( bool bold )
{
QTextCursor cursor = d->m_description->textCursor();
QTextCharFormat format;
format.setFontWeight( bold ? QFont::Bold : QFont::Normal );
cursor.mergeCharFormat( format );
d->m_description->setTextCursor( cursor );
}
void FormattedTextWidget::setTextCursorItalic( bool italic )
{
QTextCursor cursor = d->m_description->textCursor();
QTextCharFormat format;
format.setFontItalic( italic );
cursor.mergeCharFormat( format );
d->m_description->setTextCursor( cursor );
}
void FormattedTextWidget::setTextCursorUnderlined( bool underlined )
{
QTextCursor cursor = d->m_description->textCursor();
QTextCharFormat format;
format.setFontUnderline( underlined );
cursor.mergeCharFormat( format );
d->m_description->setTextCursor( cursor );
}
void FormattedTextWidget::setTextCursorColor( const QColor &color )
{
QTextCursor cursor = d->m_description->textCursor();
QTextCharFormat format;
QBrush brush( color );
format.setForeground( brush );
cursor.mergeCharFormat( format );
d->m_description->setTextCursor( cursor );
QPixmap textColorPixmap(22, 22);
textColorPixmap.fill( format.foreground().color() );
d->m_actionColor->setIcon( QIcon( textColorPixmap ) );
d->m_textColorDialog->setCurrentColor( format.foreground().color() );
}
void FormattedTextWidget::setTextCursorFont( const QFont &font )
{
QTextCursor cursor = d->m_description->textCursor();
QTextCharFormat format;
format.setFontFamily( font.family() );
cursor.mergeCharFormat( format );
d->m_description->setTextCursor( cursor );
}
void FormattedTextWidget::setTextCursorFontSize( const QString &fontSize )
{
bool ok = false;
int size = fontSize.toInt( &ok );
if( ok ) {
QTextCursor cursor = d->m_description->textCursor();
QTextCharFormat format;
format.setFontPointSize( size );
cursor.mergeCharFormat( format );
d->m_description->setTextCursor( cursor );
}
}
void FormattedTextWidget::addImageToDescription()
{
QString filename = QFileDialog::getOpenFileName( this, tr( "Choose image" ), tr( "All Supported Files (*.png *.jpg *.jpeg)" ) );
QImage image( filename );
if( !image.isNull() ) {
QTextCursor cursor = d->m_description->textCursor();
cursor.insertImage( image, filename );
}
}
void FormattedTextWidget::addLinkToDescription()
{
QPointer<AddLinkDialog> dialog = new AddLinkDialog( this );
if( dialog->exec() ) {
QTextCharFormat oldFormat = d->m_description->textCursor().charFormat();
QTextCharFormat linkFormat = oldFormat;
linkFormat.setAnchor( true );
linkFormat.setFontUnderline( true );
linkFormat.setForeground( QApplication::palette().link() );
linkFormat.setAnchorHref( dialog->url() );
d->m_description->textCursor().insertText( dialog->name(), linkFormat );
QTextCursor cursor = d->m_description->textCursor();
cursor.setCharFormat( oldFormat );
d->m_description->setTextCursor( cursor );
d->m_description->textCursor().insertText( " " );
}
}
void FormattedTextWidget::updateDescriptionEditButtons()
{
disconnect( d->m_actionBold, SIGNAL(toggled(bool)), this, SLOT(setTextCursorBold(bool)) );
disconnect( d->m_actionItalics, SIGNAL(toggled(bool)), this, SLOT(setTextCursorItalic(bool)) );
disconnect( d->m_actionUnderlined, SIGNAL(toggled(bool)), this, SLOT(setTextCursorUnderlined(bool)) );
disconnect( d->m_fontFamily, SIGNAL(currentFontChanged(QFont)), this, SLOT(setTextCursorFont(QFont)) );
disconnect( d->m_fontSize, SIGNAL(editTextChanged(QString)), this, SLOT(setTextCursorFontSize(QString)) );
QTextCharFormat format = d->m_description->textCursor().charFormat();
d->m_fontFamily->setCurrentFont( format.font() );
if( format.fontWeight() == QFont::Bold ) {
d->m_actionBold->setChecked( true );
} else if ( format.fontWeight() == QFont::Normal ) {
d->m_actionBold->setChecked( false );
}
d->m_actionItalics->setChecked( format.fontItalic() );
d->m_actionUnderlined->setChecked( format.fontUnderline() );
QPixmap textColorPixmap(22, 22);
textColorPixmap.fill( format.foreground().color() );
d->m_actionColor->setIcon( QIcon( textColorPixmap ) );
d->m_textColorDialog->setCurrentColor( format.foreground().color() );
int index = d->m_fontSize->findText( QString::number( d->m_description->textCursor().charFormat().font().pointSize() ) );
if( index != -1 ) {
d->m_fontSize->setCurrentIndex( index );
} else {
d->m_fontSize->lineEdit()->setText( QString::number( d->m_description->textCursor().charFormat().font().pointSize() ) );
}
connect( d->m_actionBold, SIGNAL(toggled(bool)), this, SLOT(setTextCursorBold(bool)) );
connect( d->m_actionItalics, SIGNAL(toggled(bool)), this, SLOT(setTextCursorItalic(bool)) );
connect( d->m_actionUnderlined, SIGNAL(toggled(bool)), this, SLOT(setTextCursorUnderlined(bool)) );
connect( d->m_fontFamily, SIGNAL(currentFontChanged(QFont)), this, SLOT(setTextCursorFont(QFont)) );
connect( d->m_fontSize, SIGNAL(editTextChanged(QString)), this, SLOT(setTextCursorFontSize(QString)) );
}
void FormattedTextWidget::setReadOnly( bool state )
{
d->m_description->setReadOnly( state );
d->m_formattedTextToolBar->setDisabled( state );
d->m_fontFamily->setDisabled( state );
d->m_fontSize->setDisabled( state );
d->m_actionColor->setDisabled( state );
}
}
#include "moc_FormattedTextWidget.cpp"
diff --git a/src/lib/marble/FormattedTextWidget.h b/src/lib/marble/FormattedTextWidget.h
index b656c0d3f..278d459a3 100644
--- a/src/lib/marble/FormattedTextWidget.h
+++ b/src/lib/marble/FormattedTextWidget.h
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
// Copyright 2015 Constantin Mihalache <mihalache.c94@gmail.com>
//
#ifndef FORMATTEDTEXTWIDGET_H
#define FORMATTEDTEXTWIDGET_H
// Marble
#include "marble_export.h"
//Qt
#include <QWidget>
class QString;
namespace Marble {
class MARBLE_EXPORT FormattedTextWidget : public QWidget
{
Q_OBJECT
public:
- explicit FormattedTextWidget(QWidget *parent = 0);
+ explicit FormattedTextWidget(QWidget *parent = nullptr);
~FormattedTextWidget() override;
void setText( const QString &text );
const QString text();
void setReadOnly( bool state );
private Q_SLOTS:
void toggleDescriptionEditMode( bool isFormattedTextMode = false );
void setTextCursorBold( bool bold );
void setTextCursorItalic( bool italic );
void setTextCursorUnderlined( bool underlined );
void setTextCursorColor( const QColor &color );
void setTextCursorFont( const QFont &font );
void setTextCursorFontSize( const QString &fontSize );
void addImageToDescription();
void addLinkToDescription();
void updateDescriptionEditButtons();
Q_SIGNALS:
void textUpdated();
private:
class Private;
Private * const d;
};
}
#endif // FORMATTEDTEXTWIDGET_H
diff --git a/src/lib/marble/GeoDataTreeModel.cpp b/src/lib/marble/GeoDataTreeModel.cpp
index 8b096a452..53586c2bd 100644
--- a/src/lib/marble/GeoDataTreeModel.cpp
+++ b/src/lib/marble/GeoDataTreeModel.cpp
@@ -1,873 +1,873 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Thibaut Gridel <tgridel@free.fr>
// Copyright 2013 Levente Kurusa <levex@linux.com>
//
// Own
#include "GeoDataTreeModel.h"
// Qt
#include <QBrush>
#include <QModelIndex>
#include <QList>
#include <QItemSelectionModel>
// Marble
#include "GeoDataObject.h"
#include "GeoDataDocument.h"
#include "GeoDataContainer.h"
#include "GeoDataExtendedData.h"
#include "GeoDataFolder.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataPolygon.h"
#include "GeoDataLinearRing.h"
#include "GeoDataLookAt.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataPlaylist.h"
#include "GeoDataTour.h"
#include "GeoDataWait.h"
#include "GeoDataFlyTo.h"
#include "GeoDataCamera.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataListStyle.h"
#include "FileManager.h"
#include "MarbleDebug.h"
#include "MarblePlacemarkModel.h"
using namespace Marble;
class Q_DECL_HIDDEN GeoDataTreeModel::Private {
public:
Private( QAbstractItemModel* model );
~Private();
static void checkParenting( GeoDataObject *object );
GeoDataDocument* m_rootDocument;
bool m_ownsRootDocument;
QItemSelectionModel m_selectionModel;
QHash<int, QByteArray> m_roleNames;
};
GeoDataTreeModel::Private::Private( QAbstractItemModel *model ) :
m_rootDocument( new GeoDataDocument ),
m_ownsRootDocument( true ),
m_selectionModel( model )
{
m_roleNames[MarblePlacemarkModel::DescriptionRole] = "description";
m_roleNames[MarblePlacemarkModel::IconPathRole] = "iconPath";
m_roleNames[MarblePlacemarkModel::PopularityIndexRole] = "zoomLevel";
m_roleNames[MarblePlacemarkModel::VisualCategoryRole] = "visualCategory";
m_roleNames[MarblePlacemarkModel::AreaRole] = "area";
m_roleNames[MarblePlacemarkModel::PopulationRole] = "population";
m_roleNames[MarblePlacemarkModel::CountryCodeRole] = "countryCode";
m_roleNames[MarblePlacemarkModel::StateRole] = "state";
m_roleNames[MarblePlacemarkModel::PopularityRole] = "popularity";
m_roleNames[MarblePlacemarkModel::GeoTypeRole] = "role";
m_roleNames[MarblePlacemarkModel::CoordinateRole] = "coordinate";
m_roleNames[MarblePlacemarkModel::StyleRole] = "style";
m_roleNames[MarblePlacemarkModel::GmtRole] = "gmt";
m_roleNames[MarblePlacemarkModel::DstRole] = "dst";
m_roleNames[MarblePlacemarkModel::GeometryRole] = "geometry";
m_roleNames[MarblePlacemarkModel::ObjectPointerRole] = "objectPointer";
m_roleNames[MarblePlacemarkModel::LongitudeRole] = "longitude";
m_roleNames[MarblePlacemarkModel::LatitudeRole] = "latitude";
}
GeoDataTreeModel::Private::~Private()
{
if ( m_ownsRootDocument ) {
delete m_rootDocument;
}
}
void GeoDataTreeModel::Private::checkParenting( GeoDataObject *object )
{
if (const auto container = dynamic_cast<const GeoDataContainer *>(object)) {
for( GeoDataFeature *child: container->featureList() ) {
if ( child->parent() != container ) {
qWarning() << "Parenting mismatch for " << child->name();
Q_ASSERT( 0 );
}
}
}
}
GeoDataTreeModel::GeoDataTreeModel( QObject *parent )
: QAbstractItemModel( parent ),
d( new Private( this ) )
{
auto const roleNames = QAbstractItemModel::roleNames();
for(auto iter = roleNames.constBegin(); iter != roleNames.constEnd(); ++iter) {
d->m_roleNames[iter.key()] = iter.value();
}
}
GeoDataTreeModel::~GeoDataTreeModel()
{
delete d;
}
int GeoDataTreeModel::rowCount( const QModelIndex &parent ) const
{
// mDebug() << "rowCount";
const GeoDataObject *parentItem;
if ( parent.column() > 0 ) {
// mDebug() << "rowCount bad column";
return 0;
}
if ( !parent.isValid() ) {
// mDebug() << "rowCount root parent";
parentItem = d->m_rootDocument;
} else {
parentItem = static_cast<const GeoDataObject *>(parent.internalPointer());
}
if ( !parentItem ) {
// mDebug() << "rowCount bad parent";
return 0;
}
if (const GeoDataContainer *container = dynamic_cast<const GeoDataContainer *>(parentItem)) {
// mDebug() << "rowCount " << type << "(" << parentItem << ") =" << container->size();
return container->size();
// } else {
// mDebug() << "rowCount bad container " << container;
}
if (const auto placemark = geodata_cast<GeoDataPlacemark>(parentItem)) {
if ( dynamic_cast<const GeoDataMultiGeometry*>( placemark->geometry() ) ) {
// mDebug() << "rowCount " << type << "(" << parentItem << ") = 1";
return 1;
}
}
if (const auto geometry = geodata_cast<GeoDataMultiGeometry>(parentItem)) {
// mDebug() << "rowCount " << parent << " " << type << " " << geometry->size();
return geometry->size();
// } else {
// mDebug() << "rowCount bad geometry " << geometry;
}
if (const auto tour = geodata_cast<GeoDataTour>(parentItem)) {
const GeoDataPlaylist *playlist = tour->playlist();
if ( playlist ) {
// mDebug() << "rowCount " << parent << " Playlist " << 1;
return 1;
}
}
if (const auto playlist = geodata_cast<GeoDataPlaylist>(parentItem)) {
// mDebug() << "rowCount " << parent << " Playlist " << playlist->size();
return playlist->size();
}
// mDebug() << "rowcount end";
return 0;//parentItem->childCount();
}
QVariant GeoDataTreeModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if ( role == Qt::DisplayRole && orientation == Qt::Horizontal )
{
switch ( section ) {
case 0:
return tr("Name");
break;
case 1:
return tr("Type");
break;
case 2:
return tr("Popularity");
break;
case 3:
return tr("PopIndex", "Popularity index");
break;
}
}
return QVariant();
}
QHash<int, QByteArray> GeoDataTreeModel::roleNames() const
{
return d->m_roleNames;
}
QVariant GeoDataTreeModel::data( const QModelIndex &index, int role ) const
{
// mDebug() << "data";
if ( !index.isValid() )
return QVariant();
GeoDataObject *object = static_cast<GeoDataObject*>( index.internalPointer() );
if ( role == Qt::DisplayRole ) {
if (const auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
if ( index.column() == 0 ){
if ( placemark->countryCode().isEmpty() ) {
return QVariant( placemark->name() );
} else {
return QVariant(placemark->name() + QLatin1String(" (") + placemark->countryCode() + QLatin1Char(')'));
}
}
else if ( index.column() == 1 ){
return QVariant( placemark->nodeType() );
}
else if ( index.column() == 2 ){
return QVariant( placemark->popularity() );
}
else if ( index.column() == 3 ){
return QVariant( placemark->zoomLevel() );
}
}
if (const auto feature = dynamic_cast<const GeoDataFeature *>(object)) {
if ( index.column() == 0 ){
return QVariant( feature->name() );
}
else if ( index.column() == 1 ){
return QVariant( feature->nodeType() );
}
}
GeoDataGeometry *geometry = dynamic_cast<GeoDataGeometry*>( object );
if ( geometry && index.column() == 1 ){
return QVariant( geometry->nodeType() );
}
GeoDataPlaylist *playlist = dynamic_cast<GeoDataPlaylist*>( object );
if ( playlist && index.column() == 0 ) {
return tr( "Playlist" );
}
GeoDataObject *item = dynamic_cast<GeoDataObject*>( object );
if ( item && index.column() == 1 ){
return QVariant( item->nodeType() );
}
}
else if ( role == Qt::CheckStateRole
&& index.column() == 0 ) {
if (const auto feature = geodata_cast<GeoDataPlacemark>(object)) {
if (const auto folder = geodata_cast<GeoDataFolder>(feature->parent())) {
if ( folder->style()->listStyle().listItemType() == GeoDataListStyle::RadioFolder
|| folder->style()->listStyle().listItemType() == GeoDataListStyle::CheckOffOnly) {
if ( feature->isVisible() ) {
return QVariant ( Qt::Checked );
} else {
return QVariant ( Qt::Unchecked );
}
}
}
if (feature->isGloballyVisible()) {
return QVariant(Qt::Checked);
}
if (feature->isVisible()) {
return QVariant(Qt::PartiallyChecked);
}
return QVariant(Qt::Unchecked);
} else if (auto feature = dynamic_cast<GeoDataContainer *>(object)) {
if (auto folder = geodata_cast<GeoDataFolder>(object)) {
if ( folder->style()->listStyle().listItemType() == GeoDataListStyle::RadioFolder) {
bool anyVisible = false;
QVector<GeoDataFeature *>::Iterator i = folder->begin();
for (; i < folder->end(); ++i) {
if ((*i)->isVisible()) {
anyVisible = true;
break;
}
}
if (anyVisible) {
return QVariant( Qt::PartiallyChecked );
} else {
return QVariant( Qt::Unchecked );
}
} else if ( folder->style()->listStyle().listItemType() == GeoDataListStyle::CheckOffOnly) {
QVector<GeoDataFeature *>::Iterator i = folder->begin();
bool anyVisible = false;
bool allVisible = true;
for (; i < folder->end(); ++i) {
if ((*i)->isVisible()) {
anyVisible = true;
} else {
allVisible = false;
}
}
if (allVisible) {
return QVariant( Qt::Checked );
} else if (anyVisible) {
return QVariant( Qt::PartiallyChecked );
} else {
return QVariant( Qt::Unchecked );
}
}
}
if ( feature->isGloballyVisible() ) {
return QVariant( Qt::Checked );
} else if ( feature->isVisible() ) {
return QVariant( Qt::PartiallyChecked );
} else {
return QVariant( Qt::Unchecked );
}
}
}
else if ( role == Qt::DecorationRole
&& index.column() == 0 ) {
if (const auto feature = dynamic_cast<const GeoDataFeature *>(object)) {
if (feature->style()->iconStyle().icon().isNull()) {
return QImage();
}
return QVariant(feature->style()->iconStyle().icon().scaled( QSize(16,16), Qt::KeepAspectRatio, Qt::SmoothTransformation ));
}
} else if ( role == Qt::ToolTipRole
&& index.column() == 0 ) {
if (const auto feature = dynamic_cast<const GeoDataFeature *>(object)) {
return QVariant( feature->description() );
}
} else if ( role == MarblePlacemarkModel::ObjectPointerRole ) {
return qVariantFromValue( object );
} else if ( role == MarblePlacemarkModel::PopularityIndexRole ) {
if (const auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
return QVariant( placemark->zoomLevel() );
}
} else if ( role == MarblePlacemarkModel::PopularityRole ) {
if (const auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
return QVariant( placemark->popularity() );
}
} else if ( role == MarblePlacemarkModel::CoordinateRole ) {
if (const auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
return qVariantFromValue( placemark->coordinate() );
} else if (const auto flyTo = geodata_cast<GeoDataFlyTo>(object)) {
if (const auto camera = geodata_cast<GeoDataCamera>(flyTo->view())) {
return QVariant::fromValue<GeoDataCoordinates>( camera->coordinates() );
- } else if (const auto lookAt = (flyTo->view() ? geodata_cast<GeoDataLookAt>(flyTo->view()) : 0)) {
+ } else if (const auto lookAt = (flyTo->view() ? geodata_cast<GeoDataLookAt>(flyTo->view()) : nullptr)) {
return QVariant::fromValue<GeoDataCoordinates>( lookAt->coordinates() );
}
}
} else if ( role == Qt::BackgroundRole ) {
if (const auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
if (const GeoDataContainer *container = dynamic_cast<const GeoDataContainer *>(placemark->parent())) {
return container->customStyle() ? QVariant( QBrush( container->customStyle()->listStyle().backgroundColor() )) : QVariant();
}
}
} else if (role == MarblePlacemarkModel::IconPathRole) {
if (const auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
return placemark->style()->iconStyle().iconPath();
}
}
return QVariant();
}
QModelIndex GeoDataTreeModel::index( int row, int column, const QModelIndex &parent ) const
{
// mDebug() << "index";
if ( !hasIndex( row, column, parent ) ) {
// mDebug() << "index bad index";
return QModelIndex();
}
GeoDataObject *parentItem;
if ( !parent.isValid() )
parentItem = d->m_rootDocument;
else
parentItem = static_cast<GeoDataObject*>( parent.internalPointer() );
if ( !parentItem ) {
// mDebug() << "index bad parent";
return QModelIndex();
}
- GeoDataObject *childItem = 0;
+ GeoDataObject *childItem = nullptr;
if (auto container = dynamic_cast<GeoDataContainer *>(parentItem)) {
childItem = container->child( row );
return createIndex( row, column, childItem );
}
if (const auto placemark = geodata_cast<GeoDataPlacemark>(parentItem)) {
childItem = placemark->geometry();
if ( dynamic_cast<GeoDataMultiGeometry*>( childItem ) ) {
return createIndex( row, column, childItem );
}
}
if (const auto geometry = geodata_cast<GeoDataMultiGeometry>(parentItem)) {
childItem = geometry->child( row );
return createIndex( row, column, childItem );
}
if (const auto tour = geodata_cast<GeoDataTour>(parentItem)) {
childItem = tour->playlist();
return createIndex( row, column, childItem );
}
if (const auto playlist = geodata_cast<GeoDataPlaylist>(parentItem)) {
childItem = playlist->primitive( row );
return createIndex(row, column, childItem);
}
return QModelIndex();
}
QModelIndex GeoDataTreeModel::parent( const QModelIndex &index ) const
{
// mDebug() << "parent";
if ( !index.isValid() ) {
// mDebug() << "parent bad index";
return QModelIndex();
}
GeoDataObject *childObject = static_cast<GeoDataObject*>( index.internalPointer() );
if ( childObject ) {
/// parentObject can be a container, placemark, multigeometry or playlist
GeoDataObject *parentObject = childObject->parent();
if ( parentObject == d->m_rootDocument )
{
return QModelIndex();
}
GeoDataObject *greatParentObject = parentObject->parent();
// Avoid crashing when there is no grandparent
- if ( greatParentObject == 0 )
+ if ( greatParentObject == nullptr )
{
return QModelIndex();
}
// greatParent can be a container
if (auto greatparentContainer = dynamic_cast<GeoDataContainer *>(greatParentObject)) {
GeoDataFeature *parentFeature = static_cast<GeoDataFeature*>( parentObject );
// mDebug() << "parent " << childObject->nodeType() << "(" << childObject << ") = "
// << parentObject->nodeType() << "[" << greatparentContainer->childPosition( parentFeature ) << "](" << parentObject << ")";
return createIndex( greatparentContainer->childPosition( parentFeature ), 0, parentObject );
}
// greatParent can be a placemark
if (geodata_cast<GeoDataPlacemark>(greatParentObject)) {
// GeoDataPlacemark *greatparentPlacemark = static_cast<GeoDataPlacemark*>( greatParentObject );
// mDebug() << "parent " << childObject->nodeType() << "(" << childObject << ") = "
// << parentObject->nodeType() << "[0](" << parentObject << ")";
return createIndex( 0, 0, parentObject );
}
// greatParent can be a multigeometry
if (GeoDataMultiGeometry *greatparentMultiGeo = geodata_cast<GeoDataMultiGeometry>(greatParentObject)) {
GeoDataGeometry *parentGeometry = static_cast<GeoDataGeometry*>( parentObject );
// mDebug() << "parent " << childObject->nodeType() << "(" << childObject << ") = "
// << parentObject->nodeType() << "[" << greatParentItem->childPosition( parentGeometry ) << "](" << parentObject << ")";
return createIndex( greatparentMultiGeo->childPosition( parentGeometry ), 0, parentObject );
}
if (GeoDataTour *tour = geodata_cast<GeoDataTour>(greatParentObject)) {
return createIndex( 0, 0, tour->playlist() );
}
}
// mDebug() << "parent unknown index";
return QModelIndex();
}
int GeoDataTreeModel::columnCount( const QModelIndex & ) const
{
return 4;
}
bool GeoDataTreeModel::setData ( const QModelIndex & index, const QVariant & value, int role )
{
if ( !index.isValid() )
return false;
GeoDataObject *object = static_cast<GeoDataObject*>( index.internalPointer() );
if ( role == Qt::CheckStateRole ) {
if (auto feature = dynamic_cast<GeoDataFeature *>(object)) {
bool bValue = value.toBool();
if (auto pfolder = geodata_cast<GeoDataFolder>(feature->parent())) {
if ( pfolder->style()->listStyle().listItemType() == GeoDataListStyle::RadioFolder) {
if ( bValue ) {
QVector< GeoDataFeature * >::Iterator i = pfolder->begin();
for(; i < pfolder->end(); ++i) {
(*i)->setVisible( false );
}
}
}
}
if (auto folder = geodata_cast<GeoDataFolder>(object)) {
if ( bValue ) {
} else {
if ( folder->style()->listStyle().listItemType() == GeoDataListStyle::RadioFolder
|| folder->style()->listStyle().listItemType() == GeoDataListStyle::CheckOffOnly ) {
QVector< GeoDataFeature * >::Iterator i = folder->begin();
for(; i < folder->end(); ++i) {
(*i)->setVisible( false );
}
folder->setVisible( false );
}
}
}
feature->setVisible( bValue );
mDebug() << "setData " << feature->name();
updateFeature( feature );
return true;
}
} else if ( role == Qt::EditRole ) {
if (auto feature = dynamic_cast<GeoDataFeature *>(object)) {
feature->setName( value.toString() );
mDebug() << "setData " << feature->name() << " " << value.toString();
updateFeature( feature );
return true;
}
}
return false;
}
Qt::ItemFlags GeoDataTreeModel::flags ( const QModelIndex & index ) const
{
if ( !index.isValid() )
return Qt::NoItemFlags;
const GeoDataObject *object = static_cast<const GeoDataObject *>(index.internalPointer());
if (const auto feature = geodata_cast<GeoDataPlacemark>(object)) {
const GeoDataObject *parent = feature->parent();
if (const auto parentfolder = geodata_cast<GeoDataFolder>(parent)) {
if ( parentfolder->style()->listStyle().listItemType() == GeoDataListStyle::RadioFolder ) {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
} else if ( parentfolder->style()->listStyle().listItemType() == GeoDataListStyle::CheckHideChildren ) {
- return 0;
+ return nullptr;
}
}
}
if (const auto folder = geodata_cast<GeoDataFolder>(object)) {
if ( folder->style()->listStyle().listItemType() == GeoDataListStyle::RadioFolder) {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
} else if ( folder->style()->listStyle().listItemType() == GeoDataListStyle::CheckOffOnly ) {
QVector<GeoDataFeature *>::ConstIterator i = folder->constBegin();
bool allVisible = true;
for (; i < folder->constEnd(); ++i) {
if( ! (*i)->isVisible() ) {
allVisible = false;
break;
}
}
if ( allVisible ) {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
} else {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}
} else if ( folder->style()->listStyle().listItemType() == GeoDataListStyle::CheckHideChildren) {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
}
}
if (geodata_cast<GeoDataTour>(object)) {
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
}
if (dynamic_cast<const GeoDataFeature *>(object)) {
const GeoDataObject *parent = object;
while (!geodata_cast<GeoDataDocument>(parent)) {
parent = parent->parent();
}
const GeoDataDocument *document = static_cast<const GeoDataDocument *>(parent);
if( document->documentRole() == UserDocument ) {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable;;
}
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
}
if (geodata_cast<GeoDataWait>(object)
|| geodata_cast<GeoDataFlyTo>(object)
|| geodata_cast<GeoDataPlaylist>(object)) {
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QModelIndex GeoDataTreeModel::index(const GeoDataObject *object) const
{
- if ( object == 0 )
+ if ( object == nullptr )
return QModelIndex();
//It first runs bottom-top, storing every ancestor of the object, and
//then goes top-down retrieving the QModelIndex of every ancestor until reaching the
//index of the requested object.
//The TreeModel contains: Documents, Folders, Placemarks, MultiGeometries
//and Geometries that are children of MultiGeometries
//You can not call this function with an element that does not belong to the tree
Q_ASSERT(geodata_cast<GeoDataFolder>(object)
|| geodata_cast<GeoDataDocument>(object)
|| geodata_cast<GeoDataPlacemark>(object)
|| geodata_cast<GeoDataTour>(object)
|| ( geodata_cast<GeoDataPlaylist>(object)
&& geodata_cast<GeoDataTour>(object->parent()))
|| (geodata_cast<GeoDataWait>(object)
&& geodata_cast<GeoDataPlaylist>(object->parent()))
|| ( geodata_cast<GeoDataFlyTo>(object)
&& geodata_cast<GeoDataPlaylist>(object->parent()))
|| (geodata_cast<GeoDataLineString>(object)
&& geodata_cast<GeoDataMultiGeometry>(object->parent()))
|| (geodata_cast<GeoDataLinearRing>(object)
&& geodata_cast<GeoDataMultiGeometry>(object->parent()))
|| (geodata_cast<GeoDataPoint>(object)
&& geodata_cast<GeoDataMultiGeometry>(object->parent()))
|| (geodata_cast<GeoDataPolygon>(object)
&& geodata_cast<GeoDataMultiGeometry>(object->parent()))
|| geodata_cast<GeoDataMultiGeometry>(object));
QList<const GeoDataObject *> ancestors;
const GeoDataObject *itup = object; //Iterator to reach the top of the GeoDataDocument (bottom-up)
while ( itup && ( itup != d->m_rootDocument ) ) {//We reach up to the rootDocument
ancestors.append( itup );
itup = itup->parent() ;
}
QModelIndex itdown;
if ( !ancestors.isEmpty() ) {
itdown = index(d->m_rootDocument->childPosition(static_cast<const GeoDataFeature *>(ancestors.last())), 0, QModelIndex());//Iterator to go top down
while ( ( ancestors.size() > 1 ) ) {
const GeoDataObject *parent = static_cast<const GeoDataObject*>(ancestors.last());
if (const auto container = dynamic_cast<const GeoDataContainer *>(parent)) {
ancestors.removeLast();
itdown = index(container->childPosition(static_cast<const GeoDataFeature *>(ancestors.last())), 0, itdown);
} else if (geodata_cast<GeoDataPlacemark>(parent)) {
//The only child of the model is a Geometry or MultiGeometry object
//If it is a geometry object, we should be on the bottom of the list
ancestors.removeLast();
if (geodata_cast<GeoDataMultiGeometry>(ancestors.last()))
itdown = index( 0 , 0, itdown );
else
itdown = QModelIndex();
} else if (auto multiGeometry = geodata_cast<GeoDataMultiGeometry>(parent)) {
//The child is one of the geometry children of MultiGeometry
ancestors.removeLast();
itdown = index(multiGeometry->childPosition(static_cast<const GeoDataGeometry *>(ancestors.last())), 0, itdown);
} else if (geodata_cast<GeoDataTour>(parent)) {
ancestors.removeLast();
itdown = index( 0, 0, itdown );
} else if (auto playlist = geodata_cast<GeoDataPlaylist>(parent)) {
for ( int i=0; i< playlist->size(); i++ )
{
if ( playlist->primitive(i) == ancestors.last() )
{
ancestors.removeLast();
itdown = index( i, 0, itdown );
break;
}
}
}
else { //If the element is not found on the tree, it will be added under m_rootDocument
itdown = QModelIndex();
break;
}
}
}
return itdown;
}
QItemSelectionModel *GeoDataTreeModel::selectionModel()
{
return &d->m_selectionModel;
}
int GeoDataTreeModel::addFeature( GeoDataContainer *parent, GeoDataFeature *feature, int row )
{
if ( parent && feature ) {
QModelIndex modelindex = index( parent );
//index(GeoDataObject*) returns QModelIndex() if parent == m_rootDocument
//or if parent is not found on the tree.
//We must check that we are in top of the tree (then QModelIndex() is
//the right parent to insert the child object) or that we have a valid QModelIndex
if( ( parent == d->m_rootDocument ) || modelindex.isValid() )
{
if( row < 0 || row > parent->size()) {
row = parent->size();
}
beginInsertRows( modelindex , row , row );
parent->insert( row, feature );
d->checkParenting( parent );
endInsertRows();
emit added(feature);
}
else
qWarning() << "GeoDataTreeModel::addFeature (parent " << parent << " - feature" << feature << ") : parent not found on the TreeModel";
}
else
qWarning() << "Null pointer in call to GeoDataTreeModel::addFeature (parent " << parent << " - feature" << feature << ")";
return row; //-1 if it failed, the relative index otherwise.
}
int GeoDataTreeModel::addDocument( GeoDataDocument *document )
{
return addFeature( d->m_rootDocument, document );
}
bool GeoDataTreeModel::removeFeature( GeoDataContainer *parent, int row )
{
if ( row<parent->size() ) {
beginRemoveRows( index( parent ), row , row );
GeoDataFeature *feature = parent->child( row );
parent->remove( row );
emit removed(feature);
endRemoveRows();
return true;
}
return false; //Tried to remove a row that is not contained in the parent.
}
int GeoDataTreeModel::removeFeature(GeoDataFeature *feature)
{
if ( feature && ( feature!=d->m_rootDocument ) ) {
if (!feature->parent()) {
return -1;
}
//We check to see we are not removing the
//top level element m_rootDocument
GeoDataObject *parent = static_cast< GeoDataObject* >( feature->parent() );
if (dynamic_cast<const GeoDataContainer *>(parent)) {
int row = static_cast< GeoDataContainer* >( feature->parent() )->childPosition( feature );
if ( row != -1 ) {
bool removed = removeFeature( static_cast< GeoDataContainer* >( feature->parent() ) , row );
if( removed ) {
return row;
}
}
//The feature is not contained in the parent it points to
}
}
return -1; //We can not remove the rootDocument
}
void GeoDataTreeModel::updateFeature( GeoDataFeature *feature )
{
GeoDataContainer *container = static_cast<GeoDataContainer*>( feature->parent() );
int index = removeFeature( feature );
Q_ASSERT( index != -1 );
addFeature( container, feature, index );
}
void GeoDataTreeModel::removeDocument( int index )
{
removeFeature( d->m_rootDocument, index );
}
void GeoDataTreeModel::removeDocument( GeoDataDocument *document )
{
removeFeature( document );
}
void GeoDataTreeModel::setRootDocument( GeoDataDocument* document )
{
beginResetModel();
if ( d->m_ownsRootDocument ) {
delete d->m_rootDocument;
}
- d->m_ownsRootDocument = ( document == 0 );
+ d->m_ownsRootDocument = ( document == nullptr );
d->m_rootDocument = document ? document : new GeoDataDocument;
endResetModel();
}
GeoDataDocument * GeoDataTreeModel::rootDocument()
{
return d->m_rootDocument;
}
int GeoDataTreeModel::addTourPrimitive( const QModelIndex &parent, GeoDataTourPrimitive *primitive, int row )
{
GeoDataObject *parentObject = static_cast<GeoDataObject*>( parent.internalPointer() );
if (auto playlist = geodata_cast<GeoDataPlaylist>(parentObject)) {
if( row == -1 ) {
row = playlist->size();
}
beginInsertRows( parent, row, row );
playlist->insertPrimitive( row, primitive );
endInsertRows();
return row;
}
return -1;
}
bool GeoDataTreeModel::removeTourPrimitive( const QModelIndex &parent , int index)
{
GeoDataObject *parentObject = static_cast<GeoDataObject*>( parent.internalPointer() );
- if (auto playlist = (parent.isValid() ? geodata_cast<GeoDataPlaylist>(parentObject) : 0)) {
+ if (auto playlist = (parent.isValid() ? geodata_cast<GeoDataPlaylist>(parentObject) : nullptr)) {
if( playlist->size() > index ) {
beginRemoveRows( parent, index, index );
playlist->removePrimitiveAt( index );
endRemoveRows();
return true;
}
}
return false;
}
bool GeoDataTreeModel::swapTourPrimitives( const QModelIndex &parent, int indexA, int indexB )
{
GeoDataObject *parentObject = static_cast<GeoDataObject*>( parent.internalPointer() );
- if (auto playlist = (parent.isValid() ? geodata_cast<GeoDataPlaylist>(parentObject) : 0)) {
+ if (auto playlist = (parent.isValid() ? geodata_cast<GeoDataPlaylist>(parentObject) : nullptr)) {
if( indexA > indexB ) {
qSwap(indexA, indexB);
}
if ( indexB - indexA == 1 ) {
beginMoveRows( parent, indexA, indexA, parent, indexB+1 );
} else {
beginMoveRows( parent, indexA, indexA, parent, indexB );
beginMoveRows( parent, indexB, indexB, parent, indexA );
}
playlist->swapPrimitives( indexA, indexB );
if( indexB - indexA != 1 ) {
endMoveRows();
}
endMoveRows();
return true;
}
return false;
}
#include "moc_GeoDataTreeModel.cpp"
diff --git a/src/lib/marble/GeoDataTreeModel.h b/src/lib/marble/GeoDataTreeModel.h
index 49a03a810..3380b5744 100644
--- a/src/lib/marble/GeoDataTreeModel.h
+++ b/src/lib/marble/GeoDataTreeModel.h
@@ -1,119 +1,119 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Thibaut Gridel <tgridel@free.fr>
//
#ifndef MARBLE_GEODATATREEMODEL_H
#define MARBLE_GEODATATREEMODEL_H
#include "marble_export.h"
#include <QAbstractItemModel>
class QItemSelectionModel;
namespace Marble
{
class GeoDataObject;
class GeoDataDocument;
class GeoDataFeature;
class GeoDataContainer;
class GeoDataTourPrimitive;
/**
* @short The representation of GeoData in a model
* This class represents all available data given by kml-data files.
*/
class MARBLE_EXPORT GeoDataTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
/**
* Creates a new GeoDataTreeModel.
*
* @param parent The parent object.
*/
- explicit GeoDataTreeModel( QObject *parent = 0 );
+ explicit GeoDataTreeModel( QObject *parent = nullptr );
/**
* Destroys the GeoDataModel.
*/
~GeoDataTreeModel() override;
/**
* Return the number of Items in the Model.
*/
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
QVariant data(const QModelIndex &index, int role) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex index(const GeoDataObject *object) const;
QModelIndex parent(const QModelIndex &index) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
QItemSelectionModel *selectionModel();
GeoDataDocument *rootDocument();
public Q_SLOTS:
/**
* Sets the root document to use. This replaces previously loaded data, if any.
* @param document The new root document. Ownership retains with the caller,
* i.e. GeoDataTreeModel will not delete the passed document at its destruction.
*/
void setRootDocument( GeoDataDocument *document );
int addFeature( GeoDataContainer *parent, GeoDataFeature *feature, int row = -1 );
bool removeFeature( GeoDataContainer *parent, int index );
int removeFeature(GeoDataFeature *feature);
void updateFeature( GeoDataFeature *feature );
int addDocument( GeoDataDocument *document );
void removeDocument( int index );
void removeDocument( GeoDataDocument* document );
int addTourPrimitive( const QModelIndex &parent, GeoDataTourPrimitive *primitive, int row = -1 );
bool removeTourPrimitive( const QModelIndex &parent, int index );
bool swapTourPrimitives( const QModelIndex &parent, int indexA, int indexB );
Q_SIGNALS:
/// insert and remove row don't trigger any signal that proxies forward
/// this signal will refresh geometry layer and placemark layout
void removed( GeoDataObject *object );
void added( GeoDataObject *object );
private:
Q_DISABLE_COPY( GeoDataTreeModel )
class Private;
Private* const d;
};
}
#endif // MARBLE_GEODATATREEMODEL_H
diff --git a/src/lib/marble/GeoGraphicsScene.h b/src/lib/marble/GeoGraphicsScene.h
index fd143c44b..b7b76fb26 100644
--- a/src/lib/marble/GeoGraphicsScene.h
+++ b/src/lib/marble/GeoGraphicsScene.h
@@ -1,90 +1,90 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
// Copyright 2011 Konstantin Oblaukhov <oblaukhov.konstantin@gmail.com>
//
#ifndef MARBLE_GEOGRAPHICSSCENE_H
#define MARBLE_GEOGRAPHICSSCENE_H
#include "marble_export.h"
#include "MarbleGlobal.h"
#include <QObject>
#include <QList>
namespace Marble
{
class GeoGraphicsItem;
class GeoDataFeature;
class GeoDataLatLonBox;
class GeoGraphicsScenePrivate;
class GeoDataPlacemark;
/**
* @short This is the home of all GeoGraphicsItems to be shown on the map.
*/
class MARBLE_EXPORT GeoGraphicsScene : public QObject
{
Q_OBJECT
public:
/**
* Creates a new instance of GeoGraphicsScene
* @param parent the QObject parent of the Scene
*/
- explicit GeoGraphicsScene( QObject *parent = 0 );
+ explicit GeoGraphicsScene( QObject *parent = nullptr );
~GeoGraphicsScene() override;
/**
* @brief Add an item to the GeoGraphicsScene
* Adds the item @p item to the GeoGraphicsScene
*/
void addItem( GeoGraphicsItem *item );
/**
* @brief Remove all concerned items from the GeoGraphicsScene
* Removes all items which are associated with @p object from the GeoGraphicsScene
*/
void removeItem( const GeoDataFeature *feature );
/**
* @brief Remove all items from the GeoGraphicsScene
*/
void clear();
/**
* @brief Get the list of items in the specified Box
*
* @param box The box around the items.
* @param maxZoomLevel The max zoom level of tiling
* @return The list of items in the specified box in no specific order.
*/
QList<GeoGraphicsItem *> items( const GeoDataLatLonBox &box, int maxZoomLevel ) const;
/**
* @brief Get the list of items which belong to a placemark
* that has been clicked.
* @return Returns a list of selected Items
*/
QList<GeoGraphicsItem*> selectedItems() const;
void resetStyle();
public Q_SLOTS:
void applyHighlight( const QVector<GeoDataPlacemark*>& );
Q_SIGNALS:
void repaintNeeded();
private:
GeoGraphicsScenePrivate * const d;
};
}
#endif // MARBLE_GEOGRAPHICSSCENE_H
diff --git a/src/lib/marble/GeoPainter.h b/src/lib/marble/GeoPainter.h
index 63b6a454f..b5d7cd609 100644
--- a/src/lib/marble/GeoPainter.h
+++ b/src/lib/marble/GeoPainter.h
@@ -1,530 +1,530 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008-2009 Torsten Rahn <tackat@kde.org>
//
#ifndef MARBLE_GEOPAINTER_H
#define MARBLE_GEOPAINTER_H
#include "marble_export.h"
// Marble
#include "MarbleGlobal.h"
#include "ClipPainter.h"
#include <QSizeF>
class QImage;
class QPaintDevice;
class QRegion;
class QString;
namespace Marble
{
class ViewportParams;
class GeoPainterPrivate;
class GeoDataCoordinates;
class GeoDataLineString;
class GeoDataLinearRing;
class GeoDataPoint;
class GeoDataPolygon;
/*!
\class GeoPainter
\brief A painter that allows to draw geometric primitives on the map.
This class allows application developers to draw simple geometric shapes
and objects onto the map.
The API is modeled after the QPainter API.
The GeoPainter provides a wide range of methods that are using geographic
("geodesic") coordinates to position the item.
For example a point or the nodes of a polygon can fully be described in
geographic coordinates.
In all these cases the position of the object is specified in geographic
coordinates.
There are however some cases where there are two viable cases:
\li the shape of the object could still use screen coordinates (like a label
or an icon).
\li Alternatively the shape of the object can get projected according
to the current projection (e.g. a texture projected onto the spherical
surface)
If screen coordinates are used then e.g. width and height are assumed to be
expressed in pixels, otherwise degrees are used.
Painter transformations (e.g. translate) always happen in screen
coordinates.
Like in QPainter drawing objects onto a widget should always considered to
be a volatile operation. This means that e.g. placemarks don't get added to
the globe permanently.
So the drawing needs to be done on every repaint to prevent that drawings
will disappear during the next paint event.
So if you want to add placemarks to your map widget permanently (i.e. you
don't want to take care of repainting) then you need to use other solutions
such as the KML import of the Marble framework or Marble's GeoGraphicsItems.
\note By default the GeoPainter automatically filters geographical content
in order to provide fast painting:
\li Geographically positioned objects which are outside the viewport are not
drawn at all.
Parts of objects which are specified through geographic coordinates
(like polygons, ellipses etc.) get cut off if they are not placed within the
viewport.
\li Objects which have a shape that is specified through geographic
coordinates get filtered according to the viewport resolution:
If the object is much smaller than a pixel then it won't get drawn at all.
*/
class MARBLE_EXPORT GeoPainter : public ClipPainter
{
public:
enum Frame {
NoOptions = 0x0,
RoundFrame = 0x1
};
Q_DECLARE_FLAGS(Frames, Frame)
/*!
\brief Creates a new geo painter.
To create a geo painter it's necessary to provide \a paintDevice
as a canvas and the viewportParams to specify the map projection
inside the viewport.
*/
GeoPainter( QPaintDevice * paintDevice,
const ViewportParams *viewportParams,
MapQuality mapQuality = NormalQuality );
/*!
\brief Destroys the geo painter.
*/
~GeoPainter();
/*!
\brief Returns the map quality.
\return The map quality that got assigned to the painter.
*/
MapQuality mapQuality() const;
/*!
\brief Draws a text annotation that points to a geodesic position.
The annotation consists of a bubble with the specified \a text inside.
By choosing an appropriate pen for the painter it's possible to change
the color and line style of the bubble outline and the text. The brush
chosen for the painter is used to paint the background of the bubble
The optional parameters which describe the layout of the bubble are
similar to those used by QPainter::drawRoundedRect().
Unlike in QPainter the rounded corners are not specified in percentage
but in pixels to provide for optimal aesthetics.
By choosing a positive or negative bubbleOffset it's possible to
place the annotation on top, bottom, left or right of the annotated
position.
\param position The geodesic position
\param text The text contained by the bubble
\param bubbleSize The size of the bubble that holds the annotation text.
A height of 0 can be used to have the height calculated
automatically to fit the needed text height.
\param bubbleOffsetX The x-axis offset between the annotated position and
the "root" of the speech bubble's "arrow".
\param bubbleOffsetY The y-axis offset between the annotated position and
the "root" of the speech bubble's "arrow".
\param xRnd Specifies the geometry of the rounded corners in pixels along
the x-axis.
\param yRnd Specifies the geometry of the rounded corners in pixels along
the y-axis.
\see GeoDataCoordinates
*/
void drawAnnotation( const GeoDataCoordinates & position,
const QString & text,
QSizeF bubbleSize = QSizeF( 130, 100 ),
qreal bubbleOffsetX = -10, qreal bubbleOffsetY = -30,
qreal xRnd = 5, qreal yRnd = 5 );
/*!
\brief Draws a single point at a given geographic position.
The point is drawn using the painter's pen color.
\see GeoDataCoordinates
*/
void drawPoint ( const GeoDataCoordinates & position );
/*!
\brief Creates a region for a given geographic position.
A QRegion object is created that represents the area covered by
GeoPainter::drawPoint( GeoDataCoordinates ). It can be used e.g. for
input event handling of objects that have been painted using
GeoPainter::drawPoint( GeoDataCoordinates ).
The width allows to set the "stroke width" for the region. For input
event handling it's always advisable to use a width that is slightly
bigger than the width of the painter's pen.
\see GeoDataCoordinates
*/
QRegion regionFromPoint ( const GeoDataCoordinates & position,
qreal strokeWidth = 3) const;
/*!
\brief Draws a single point at a given geographic position.
The point is drawn using the painter's pen color.
\see GeoDataPoint
*/
void drawPoint ( const GeoDataPoint & point );
/*!
\brief Create a region for a given geographic position.
A QRegion object is created that represents the area covered by
GeoPainter::drawPoint( GeoDataPoint ). It can be used e.g. for
input event handling of objects that have been painted using
GeoPainter::drawPoint( GeoDataPoint ).
The width allows to set the "stroke width" for the region. For input
event handling it's always advisable to use a width that is slightly
bigger than the width of the painter's pen.
*/
QRegion regionFromPoint ( const GeoDataPoint & point,
qreal strokeWidth = 3) const;
/*!
\brief Draws the given text at a given geographic position.
The \a text is drawn starting at the given \a position using the painter's
font property. The text rendering is performed in screen coordinates and is
not subject to the current projection.
An offset given in screenPixels can be provided via xOffset and yOffset
in order to tweak the text position.
By optionally adding a width, height and text options the text flow can be
further influenced.
*/
void drawText ( const GeoDataCoordinates & position, const QString & text,
qreal xOffset = 0.0, qreal yOffset = 0.0,
qreal width = 0.0, qreal height = 0.0,
const QTextOption & option = QTextOption() );
/*!
\brief Draws an ellipse at the given position.
The ellipse is placed with its center located at the given \a centerPosition.
For the outline it uses the painter's pen and for the background the
painter's brush.
If \a isGeoProjected is true then the outline of the ellipse is drawn
in geographic coordinates. In this case the \a width and the \a height
are interpreted to be degrees.
If \a isGeoProjected is false then the outline of the ellipse is drawn
in screen coordinates. In this case the \a width and the \a height
are interpreted to be pixels.
\see GeoDataCoordinates
*/
void drawEllipse ( const GeoDataCoordinates & centerPosition,
qreal width, qreal height, bool isGeoProjected = false );
/*!
\brief Creates a region for an ellipse at a given position
A QRegion object is created that represents the area covered by
GeoPainter::drawEllipse(). As such it can be used e.g. for input event
handling for objects that have been painted using GeoPainter::drawEllipse().
The \a strokeWidth allows to extrude the QRegion by half the amount of
"stroke width" pixels. For input event handling it's always advisable to use
a width that is slightly bigger than the width of the painter's pen.
\see GeoDataCoordinates
*/
QRegion regionFromEllipse ( const GeoDataCoordinates & centerPosition,
qreal width, qreal height, bool isGeoProjected = false,
qreal strokeWidth = 3 ) const;
/*!
\brief Draws an image at the given position.
The image is placed with its center located at the given \a centerPosition.
The image rendering is performed in screen coordinates and is
not subject to the current projection.
\see GeoDataCoordinates
*/
void drawImage ( const GeoDataCoordinates & centerPosition,
const QImage & image /* , bool isGeoProjected = false */ );
/*!
\brief Draws a pixmap at the given position.
The pixmap is placed with its center located at the given \a centerPosition.
The image rendering is performed in screen coordinates and is
not subject to the current projection.
\see GeoDataCoordinates
*/
void drawPixmap ( const GeoDataCoordinates & centerPosition,
const QPixmap & pixmap /*, bool isGeoProjected = false */ );
/*!
\brief Creates a region for a rectangle for a pixmap at a given position.
A QRegion object is created that represents the area covered by
GeoPainter::drawPixmap(). This can be used e.g. for input event handling
for objects that have been painted using GeoPainter::drawPixmap().
The \a margin allows to extrude the QRegion by "margin" pixels on every side.
\see GeoDataCoordinates
*/
QRegion regionFromPixmapRect(const GeoDataCoordinates &centerCoordinates,
int width, int height,
int margin = 0) const;
/*!
\brief Helper method for safe and quick linestring conversion.
In general drawPolyline() should be used instead. However
in situations where the same linestring is supposed to be
drawn multiple times it's a good idea to cache the
screen polygons using this method.
\see GeoDataLineString
*/
void polygonsFromLineString( const GeoDataLineString &lineString,
QVector<QPolygonF*> &polygons) const;
/*!
\brief Draws a given line string (a "polyline") with a label.
The \a lineString is drawn using the current pen. It's possible to
provide a \a labelText for the \a lineString. The text is rendered using
the painter's font property.
The position of the \a labelText can be specified using the
\a labelPositionFlags.
\see GeoDataLineString
*/
void drawPolyline ( const GeoDataLineString & lineString,
const QString& labelText,
LabelPositionFlags labelPositionFlags = LineCenter,
const QColor& labelcolor = Qt::black);
/*!
\brief Draws Labels for a given set of screen polygons.
In common cases the drawPolyline overload can be used instead.
However in certain more complex cases this particular method
might be helpful for further optimization.
*/
void drawLabelsForPolygons( const QVector<QPolygonF*> &polygons,
const QString& labelText,
LabelPositionFlags labelPositionFlags,
const QColor& labelColor );
/*!
\brief Draws a given line string (a "polyline").
The \a lineString is drawn using the current pen.
\see GeoDataLineString
*/
void drawPolyline(const GeoDataLineString & lineString);
/*!
\brief Creates a region for a given line string (a "polyline").
A QRegion object is created that represents the area covered by
GeoPainter::drawPolyline( GeoDataLineString ). As such it can be used
e.g. for input event handling for objects that have been painted using
GeoPainter::drawPolyline( GeoDataLineString ).
The \a strokeWidth allows to extrude the QRegion by half the amount of
"stroke width" pixels. For input event handling it's always advisable to use
a width that is slightly bigger than the width of the painter's pen.
\see GeoDataLineString
*/
QRegion regionFromPolyline ( const GeoDataLineString & lineString,
qreal strokeWidth = 3 ) const;
/*!
\brief Draws a given linear ring (a "polygon without holes").
The outline of the \a linearRing is drawn using the current pen. The
background is painted using the current brush of the painter.
Like in QPainter::drawPolygon() the \a fillRule specifies the
fill algorithm that is used to fill the polygon.
\see GeoDataLinearRing
*/
void drawPolygon ( const GeoDataLinearRing & linearRing,
Qt::FillRule fillRule = Qt::OddEvenFill );
/*!
\brief Creates a region for a given linear ring (a "polygon without holes").
A QRegion object is created that represents the area covered by
GeoPainter::drawPolygon( GeoDataLinearRing ). As such it can be used
e.g. for input event handling for objects that have been painted using
GeoPainter::drawPolygon( GeoDataLinearRing ).
Like in drawPolygon() the \a fillRule specifies the fill algorithm that is
used to fill the polygon.
The \a strokeWidth allows to extrude the QRegion by half the amount of
"stroke width" pixels. For input event handling it's always advisable to use
a width that is slightly bigger than the width of the painter's pen.
For the polygon case a "cosmetic" strokeWidth of zero should provide the
best performance.
\see GeoDataLinearRing
*/
QRegion regionFromPolygon ( const GeoDataLinearRing & linearRing,
Qt::FillRule fillRule, qreal strokeWidth = 3 ) const;
/*!
\brief Draws a given polygon (which may contain holes).
The outline of the \a polygon is drawn using the current pen. The
background is painted using the current brush of the painter.
Like in QPainter::drawPolygon() the \a fillRule specifies the
fill algorithm that is used to fill the polygon.
\see GeoDataPolygon
*/
void drawPolygon ( const GeoDataPolygon & polygon,
Qt::FillRule fillRule = Qt::OddEvenFill );
QVector<QPolygonF*> createFillPolygons( const QVector<QPolygonF*> & outerPolygons,
const QVector<QPolygonF*> & innerPolygons ) const;
/*!
\brief Draws a rectangle at the given position.
The rectangle is placed with its center located at the given
\a centerPosition.
For the outline it uses the painter's pen and for the background the
painter's brush.
If \a isGeoProjected is true then the outline of the rectangle is drawn
in geographic coordinates. In this case the \a width and the \a height
are interpreted to be degrees.
If \a isGeoProjected is false then the outline of the rectangle is drawn
in screen coordinates. In this case the \a width and the \a height
are interpreted to be pixels.
\see GeoDataCoordinates
*/
void drawRect ( const GeoDataCoordinates & centerPosition,
qreal width, qreal height,
bool isGeoProjected = false );
/*!
\brief Creates a region for a rectangle at a given position.
A QRegion object is created that represents the area covered by
GeoPainter::drawRect(). This can be used e.g. for input event handling
for objects that have been painted using GeoPainter::drawRect().
The isGeoProjected parameter is used the same way as for
GeoPainter::drawRect().
The \a strokeWidth allows to extrude the QRegion by half the amount of
"stroke width" pixels. For input event handling it's always advisable to use
a width that is slightly bigger than the width of the painter's pen. This is
especially true for small objects.
\see GeoDataCoordinates
*/
QRegion regionFromRect ( const GeoDataCoordinates & centerPosition,
qreal width, qreal height,
bool isGeoProjected = false,
qreal strokeWidth = 3 ) const;
/*!
\brief Draws a rectangle with rounded corners at the given position.
The rectangle is placed with its center located at the given
\a centerPosition.
For the outline it uses the painter's pen and for the background the
painter's brush.
Unlike in QPainter::drawRoundedRect() the rounded corners are not specified
in percentage but in pixels to provide for optimal aesthetics.
\param width Width of the rectangle in pixels
\param height Height of the rectangle in pixels
\param xRnd Specifies the geometry of the rounded corners in pixels along
the x-axis.
\param yRnd Specifies the geometry of the rounded corners in pixels along
the y-axis.
\see GeoDataCoordinates
*/
void drawRoundedRect(const GeoDataCoordinates &centerPosition,
qreal width, qreal height,
qreal xRnd = 25.0, qreal yRnd = 25.0);
void drawTextFragment(const QPoint &position, const QString &text,
const qreal fontSize, const QColor &color = Qt::black,
- const Frames &flags = 0);
+ const Frames &flags = nullptr);
// Reenabling QPainter+ClipPainter methods.
using QPainter::drawText;
using QPainter::drawEllipse;
using QPainter::drawImage;
using QPainter::drawPixmap;
using QPainter::drawPoint;
using ClipPainter::drawPolyline;
using ClipPainter::drawPolygon;
using QPainter::drawRect;
using QPainter::drawRoundedRect;
private:
Q_DISABLE_COPY( GeoPainter )
GeoPainterPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/GoToDialog.cpp b/src/lib/marble/GoToDialog.cpp
index dcf41219e..e9b24b572 100644
--- a/src/lib/marble/GoToDialog.cpp
+++ b/src/lib/marble/GoToDialog.cpp
@@ -1,448 +1,448 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "GoToDialog.h"
#include "ui_GoToDialog.h"
#include "BookmarkManager.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarblePlacemarkModel.h"
#include "GeoDataLookAt.h"
#include "GeoDataTreeModel.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataPlacemark.h"
#include "PositionTracking.h"
#include "SearchRunnerManager.h"
#include "routing/RoutingManager.h"
#include "routing/RouteRequest.h"
#include <QAbstractListModel>
#include <QTimer>
#include <QPainter>
namespace Marble
{
class TargetModel : public QAbstractListModel
{
Q_OBJECT
public:
- TargetModel( MarbleModel* marbleModel, QObject * parent = 0 );
+ TargetModel( MarbleModel* marbleModel, QObject * parent = nullptr );
int rowCount ( const QModelIndex & parent = QModelIndex() ) const override;
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const override;
void setShowRoutingItems( bool show );
private:
QVariant currentLocationData ( int role ) const;
QVariant routeData ( const QVector<GeoDataPlacemark> &via, int index, int role ) const;
QVariant homeData ( int role ) const;
QVariant bookmarkData ( int index, int role ) const;
QVector<GeoDataPlacemark> viaPoints() const;
MarbleModel *const m_marbleModel;
QVector<GeoDataPlacemark*> m_bookmarks;
bool m_hasCurrentLocation;
bool m_showRoutingItems;
};
class GoToDialogPrivate : public Ui::GoTo
{
public:
GoToDialog* m_parent;
GeoDataCoordinates m_coordinates;
MarbleModel *const m_marbleModel;
TargetModel m_targetModel;
SearchRunnerManager m_runnerManager;
GeoDataDocument *m_searchResult;
GeoDataTreeModel m_searchResultModel;
QTimer m_progressTimer;
int m_currentFrame;
QVector<QIcon> m_progressAnimation;
GoToDialogPrivate( GoToDialog* parent, MarbleModel* marbleModel );
void saveSelection( const QModelIndex &index );
void createProgressAnimation();
void startSearch();
void updateSearchResult( const QVector<GeoDataPlacemark*>& placemarks );
void updateSearchMode();
void updateProgress();
void stopProgressAnimation();
void updateResultMessage( int results );
};
TargetModel::TargetModel( MarbleModel *marbleModel, QObject * parent ) :
QAbstractListModel( parent ),
m_marbleModel( marbleModel ),
m_hasCurrentLocation( false ),
m_showRoutingItems( true )
{
BookmarkManager* manager = m_marbleModel->bookmarkManager();
for( GeoDataFolder * folder: manager->folders() ) {
QVector<GeoDataPlacemark*> bookmarks = folder->placemarkList();
QVector<GeoDataPlacemark*>::const_iterator iter = bookmarks.constBegin();
QVector<GeoDataPlacemark*>::const_iterator end = bookmarks.constEnd();
for ( ; iter != end; ++iter ) {
m_bookmarks.push_back( *iter );
}
}
PositionTracking* tracking = m_marbleModel->positionTracking();
m_hasCurrentLocation = tracking && tracking->status() == PositionProviderStatusAvailable;
}
QVector<GeoDataPlacemark> TargetModel::viaPoints() const
{
if ( !m_showRoutingItems ) {
return QVector<GeoDataPlacemark>();
}
RouteRequest* request = m_marbleModel->routingManager()->routeRequest();
QVector<GeoDataPlacemark> result;
for ( int i = 0; i < request->size(); ++i ) {
if ( request->at( i ).isValid() ) {
GeoDataPlacemark placemark;
placemark.setCoordinate( request->at( i ) );
placemark.setName( request->name( i ) );
result.push_back( placemark );
}
}
return result;
}
int TargetModel::rowCount ( const QModelIndex & parent ) const
{
int result = 0;
if ( !parent.isValid() ) {
result += m_hasCurrentLocation ? 1 : 0;
result += viaPoints().size(); // route
result += 1; // home location
result += m_bookmarks.size(); // bookmarks
return result;
}
return result;
}
QVariant TargetModel::currentLocationData ( int role ) const
{
const PositionTracking* tracking = m_marbleModel->positionTracking();
if ( tracking->status() == PositionProviderStatusAvailable ) {
GeoDataCoordinates currentLocation = tracking->currentLocation();
switch( role ) {
case Qt::DisplayRole: return tr( "Current Location: %1" ).arg( currentLocation.toString() ) ;
case Qt::DecorationRole: return QIcon(QStringLiteral(":/icons/gps.png"));
case MarblePlacemarkModel::CoordinateRole: {
return qVariantFromValue( currentLocation );
}
}
}
return QVariant();
}
QVariant TargetModel::routeData ( const QVector<GeoDataPlacemark> &via, int index, int role ) const
{
RouteRequest* request = m_marbleModel->routingManager()->routeRequest();
switch( role ) {
case Qt::DisplayRole: return via.at( index ).name();
case Qt::DecorationRole: return QIcon( request->pixmap( index ) );
case MarblePlacemarkModel::CoordinateRole: {
const GeoDataCoordinates coordinates = via.at( index ).coordinate();
return qVariantFromValue( coordinates );
}
}
return QVariant();
}
QVariant TargetModel::homeData ( int role ) const
{
switch( role ) {
case Qt::DisplayRole: return tr( "Home" );
case Qt::DecorationRole: return QIcon(QStringLiteral(":/icons/go-home.png"));
case MarblePlacemarkModel::CoordinateRole: {
qreal lon( 0.0 ), lat( 0.0 );
int zoom( 0 );
m_marbleModel->home( lon, lat, zoom );
const GeoDataCoordinates coordinates = GeoDataCoordinates( lon, lat, 0, GeoDataCoordinates::Degree );
return qVariantFromValue( coordinates );
}
}
return QVariant();
}
QVariant TargetModel::bookmarkData ( int index, int role ) const
{
switch( role ) {
case Qt::DisplayRole: {
GeoDataFolder* folder = dynamic_cast<GeoDataFolder*>( m_bookmarks[index]->parent() );
Q_ASSERT( folder && "Internal bookmark representation has changed. Please report this as a bug at http://bugs.kde.org." );
if ( folder ) {
return QString(folder->name() + QLatin1String(" / ") + m_bookmarks[index]->name());
}
return QVariant();
}
case Qt::DecorationRole: return QIcon(QStringLiteral(":/icons/bookmarks.png"));
case MarblePlacemarkModel::CoordinateRole: return qVariantFromValue( m_bookmarks[index]->lookAt()->coordinates() );
}
return QVariant();
}
QVariant TargetModel::data ( const QModelIndex & index, int role ) const
{
if ( index.isValid() && index.row() >= 0 && index.row() < rowCount() ) {
int row = index.row();
bool const isCurrentLocation = row == 0 && m_hasCurrentLocation;
int homeOffset = m_hasCurrentLocation ? 1 : 0;
QVector<GeoDataPlacemark> via = viaPoints();
bool const isRoute = row >= homeOffset && row < homeOffset + via.size();
if ( isCurrentLocation ) {
return currentLocationData( role );
} else if ( isRoute ) {
int routeIndex = row - homeOffset;
Q_ASSERT( routeIndex >= 0 && routeIndex < via.size() );
return routeData( via, routeIndex, role );
} else {
int bookmarkIndex = row - homeOffset - via.size();
if ( bookmarkIndex == 0 ) {
return homeData( role );
} else {
--bookmarkIndex;
Q_ASSERT( bookmarkIndex >= 0 && bookmarkIndex < m_bookmarks.size() );
return bookmarkData( bookmarkIndex, role );
}
}
}
return QVariant();
}
void TargetModel::setShowRoutingItems( bool show )
{
m_showRoutingItems = show;
beginResetModel();
endResetModel();
}
void GoToDialogPrivate::createProgressAnimation()
{
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
int const iconSize = smallScreen ? 32 : 16;
// Size parameters
qreal const h = iconSize / 2.0; // Half of the icon size
qreal const q = h / 2.0; // Quarter of the icon size
qreal const d = 7.5; // Circle diameter
qreal const r = d / 2.0; // Circle radius
// Canvas parameters
QImage canvas( iconSize, iconSize, QImage::Format_ARGB32 );
QPainter painter( &canvas );
painter.setRenderHint( QPainter::Antialiasing, true );
painter.setPen( QColor ( Qt::gray ) );
painter.setBrush( QColor( Qt::white ) );
// Create all frames
for( double t = 0.0; t < 2 * M_PI; t += M_PI / 8.0 ) {
canvas.fill( Qt::transparent );
QRectF firstCircle( h - r + q * cos( t ), h - r + q * sin( t ), d, d );
QRectF secondCircle( h - r + q * cos( t + M_PI ), h - r + q * sin( t + M_PI ), d, d );
painter.drawEllipse( firstCircle );
painter.drawEllipse( secondCircle );
m_progressAnimation.push_back( QIcon( QPixmap::fromImage( canvas ) ) );
}
}
GoToDialogPrivate::GoToDialogPrivate( GoToDialog* parent, MarbleModel* marbleModel ) :
m_parent( parent),
m_marbleModel( marbleModel ),
m_targetModel( marbleModel ),
m_runnerManager( marbleModel ),
m_searchResult( new GeoDataDocument ),
m_currentFrame( 0 )
{
setupUi( parent );
m_progressTimer.setInterval( 100 );
}
void GoToDialogPrivate::saveSelection( const QModelIndex &index )
{
if ( searchButton->isChecked() && m_searchResult->size() ) {
QVariant coordinates = m_searchResultModel.data( index, MarblePlacemarkModel::CoordinateRole );
m_coordinates = coordinates.value<GeoDataCoordinates>();
} else {
QVariant coordinates = index.data( MarblePlacemarkModel::CoordinateRole );
m_coordinates = coordinates.value<GeoDataCoordinates>();
}
m_parent->accept();
}
void GoToDialogPrivate::startSearch()
{
QString const searchTerm = searchLineEdit->text().trimmed();
if ( searchTerm.isEmpty() ) {
return;
}
m_runnerManager.findPlacemarks( searchTerm );
if ( m_progressAnimation.isEmpty() ) {
createProgressAnimation();
}
m_progressTimer.start();
progressButton->setVisible( true );
searchLineEdit->setEnabled( false );
updateResultMessage( 0 );
}
void GoToDialogPrivate::updateSearchResult( const QVector<GeoDataPlacemark*>& placemarks )
{
- m_searchResultModel.setRootDocument( 0 );
+ m_searchResultModel.setRootDocument( nullptr );
m_searchResult->clear();
for (GeoDataPlacemark *placemark: placemarks) {
m_searchResult->append( new GeoDataPlacemark( *placemark ) );
}
m_searchResultModel.setRootDocument( m_searchResult );
bookmarkListView->setModel( &m_searchResultModel );
updateResultMessage( m_searchResultModel.rowCount() );
}
GoToDialog::GoToDialog( MarbleModel* marbleModel, QWidget * parent, Qt::WindowFlags flags ) :
QDialog( parent, flags ),
d( new GoToDialogPrivate( this, marbleModel ) )
{
d->searchLineEdit->setPlaceholderText( tr( "Address or search term" ) );
d->m_searchResultModel.setRootDocument( d->m_searchResult );
d->bookmarkListView->setModel( &d->m_targetModel );
connect( d->bookmarkListView, SIGNAL(activated(QModelIndex)),
this, SLOT(saveSelection(QModelIndex)) );
connect( d->searchLineEdit, SIGNAL(returnPressed()),
this, SLOT(startSearch()) );
d->buttonBox->button( QDialogButtonBox::Close )->setAutoDefault( false );
connect( d->searchButton, SIGNAL(clicked(bool)),
this, SLOT(updateSearchMode()) );
connect( d->browseButton, SIGNAL(clicked(bool)),
this, SLOT(updateSearchMode()) );
connect( &d->m_progressTimer, SIGNAL(timeout()),
this, SLOT(updateProgress()) );
connect( d->progressButton, SIGNAL(clicked(bool)),
this, SLOT(stopProgressAnimation()) );
d->updateSearchMode();
d->progressButton->setVisible( false );
connect( &d->m_runnerManager, SIGNAL(searchResultChanged(QVector<GeoDataPlacemark*>)),
this, SLOT(updateSearchResult(QVector<GeoDataPlacemark*>)) );
connect( &d->m_runnerManager, SIGNAL(searchFinished(QString)),
this, SLOT(stopProgressAnimation()) );
}
GoToDialog::~GoToDialog()
{
delete d;
}
GeoDataCoordinates GoToDialog::coordinates() const
{
return d->m_coordinates;
}
void GoToDialog::setShowRoutingItems( bool show )
{
d->m_targetModel.setShowRoutingItems( show );
}
void GoToDialog::setSearchEnabled( bool enabled )
{
d->browseButton->setVisible( enabled );
d->searchButton->setVisible( enabled );
if ( !enabled ) {
d->searchButton->setChecked( false );
d->updateSearchMode();
}
}
void GoToDialogPrivate::updateSearchMode()
{
bool const searchEnabled = searchButton->isChecked();
searchLineEdit->setVisible( searchEnabled );
descriptionLabel->setVisible( searchEnabled );
progressButton->setVisible( searchEnabled && m_progressTimer.isActive() );
if ( searchEnabled ) {
bookmarkListView->setModel( &m_searchResultModel );
searchLineEdit->setFocus();
} else {
bookmarkListView->setModel( &m_targetModel );
}
}
void GoToDialogPrivate::updateProgress()
{
if ( !m_progressAnimation.isEmpty() ) {
m_currentFrame = ( m_currentFrame + 1 ) % m_progressAnimation.size();
QIcon frame = m_progressAnimation[m_currentFrame];
progressButton->setIcon( frame );
}
}
void GoToDialogPrivate::stopProgressAnimation()
{
searchLineEdit->setEnabled( true );
m_progressTimer.stop();
updateResultMessage( bookmarkListView->model()->rowCount() );
progressButton->setVisible( false );
}
void GoToDialogPrivate::updateResultMessage( int results )
{
//~ singular %n result found.
//~ plural %n results found.
descriptionLabel->setText( QObject::tr( "%n result(s) found.", "Number of search results", results ) );
}
}
#include "moc_GoToDialog.cpp" // needed for private slots in header
#include "GoToDialog.moc" // needed for Q_OBJECT here in source
diff --git a/src/lib/marble/GoToDialog.h b/src/lib/marble/GoToDialog.h
index 2daffd1a5..7972908f4 100644
--- a/src/lib/marble/GoToDialog.h
+++ b/src/lib/marble/GoToDialog.h
@@ -1,73 +1,73 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_GOTODIALOG_H
#define MARBLE_GOTODIALOG_H
#include "marble_export.h"
#include <QDialog>
class QModelIndex;
namespace Marble
{
class GeoDataPlacemark;
class GeoDataCoordinates;
class GoToDialogPrivate;
class MarbleModel;
/**
* A dialog that provides a list of targets to go to: The current location,
* route start, destination and via points and bookmarks. Clicking on a target
* centers the map on the selected position
*/
class MARBLE_EXPORT GoToDialog: public QDialog
{
Q_OBJECT
public:
- explicit GoToDialog( MarbleModel* marbleModel, QWidget * parent = 0, Qt::WindowFlags f = 0 );
+ explicit GoToDialog( MarbleModel* marbleModel, QWidget * parent = nullptr, Qt::WindowFlags f = nullptr );
~GoToDialog() override;
/** Toggle whether routing items (source, destination and via points) are visible */
void setShowRoutingItems( bool show );
/** Toggle whether the dialog can be used to search for placemarks */
void setSearchEnabled( bool enabled );
/**
* Returns the position of the item selected by the user, or a default
* constructed GeoDataLookAt if the dialog was cancelled by the user
*/
GeoDataCoordinates coordinates() const;
Q_PRIVATE_SLOT( d, void saveSelection( const QModelIndex &index ) )
Q_PRIVATE_SLOT( d, void startSearch() )
Q_PRIVATE_SLOT( d, void updateSearchResult( const QVector<GeoDataPlacemark*>& placemarks ) )
Q_PRIVATE_SLOT( d, void updateSearchMode() )
Q_PRIVATE_SLOT( d, void updateProgress() )
Q_PRIVATE_SLOT( d, void stopProgressAnimation() )
private:
GoToDialogPrivate * const d;
friend class GoToDialogPrivate;
};
} // namespace Marble
#endif // MARBLE_GOTODIALOG_H
diff --git a/src/lib/marble/HttpDownloadManager.cpp b/src/lib/marble/HttpDownloadManager.cpp
index e1a09491b..ebe0d7f3f 100644
--- a/src/lib/marble/HttpDownloadManager.cpp
+++ b/src/lib/marble/HttpDownloadManager.cpp
@@ -1,236 +1,236 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008,2009 Jens-Michael Hoffmann <jensmh@gmx.de>
//
#include "HttpDownloadManager.h"
#include <QList>
#include <QMap>
#include <QTimer>
#include <QNetworkAccessManager>
#include "DownloadPolicy.h"
#include "DownloadQueueSet.h"
#include "HttpJob.h"
#include "MarbleDebug.h"
#include "StoragePolicy.h"
using namespace Marble;
// Time before a failed download job is requeued in ms
const quint32 requeueTime = 60000;
class Q_DECL_HIDDEN HttpDownloadManager::Private
{
public:
Private( HttpDownloadManager* parent, StoragePolicy *policy );
~Private();
void connectDefaultQueueSets();
void connectQueueSet( DownloadQueueSet * );
bool hasDownloadPolicy( const DownloadPolicy& policy ) const;
void finishJob( const QByteArray&, const QString&, const QString& id );
void requeue();
void startRetryTimer();
DownloadQueueSet *findQueues( const QString& hostName, const DownloadUsage usage );
HttpDownloadManager* m_downloadManager;
QTimer m_requeueTimer;
/**
* Contains per download policy a queue set containing of
* - a queue where jobs are waiting for being activated (=downloaded)
* - a queue containing currently being downloaded
* - a queue for retries of failed downloads */
QList<QPair<DownloadPolicyKey, DownloadQueueSet *> > m_queueSets;
QMap<DownloadUsage, DownloadQueueSet *> m_defaultQueueSets;
StoragePolicy *const m_storagePolicy;
QNetworkAccessManager m_networkAccessManager;
bool m_acceptJobs;
};
HttpDownloadManager::Private::Private(HttpDownloadManager *parent, StoragePolicy *policy )
: m_downloadManager( parent ),
m_requeueTimer(),
m_storagePolicy( policy ),
m_networkAccessManager(),
m_acceptJobs( true )
{
// setup default download policy and associated queue set
DownloadPolicy defaultBrowsePolicy;
defaultBrowsePolicy.setMaximumConnections( 20 );
m_defaultQueueSets[ DownloadBrowse ] = new DownloadQueueSet( defaultBrowsePolicy );
DownloadPolicy defaultBulkDownloadPolicy;
defaultBulkDownloadPolicy.setMaximumConnections( 2 );
m_defaultQueueSets[ DownloadBulk ] = new DownloadQueueSet( defaultBulkDownloadPolicy );
}
HttpDownloadManager::Private::~Private()
{
QMap<DownloadUsage, DownloadQueueSet *>::iterator pos = m_defaultQueueSets.begin();
QMap<DownloadUsage, DownloadQueueSet *>::iterator const end = m_defaultQueueSets.end();
for (; pos != end; ++pos )
delete pos.value();
}
DownloadQueueSet *HttpDownloadManager::Private::findQueues( const QString& hostName,
const DownloadUsage usage )
{
- DownloadQueueSet * result = 0;
+ DownloadQueueSet * result = nullptr;
QList<QPair<DownloadPolicyKey, DownloadQueueSet*> >::iterator pos = m_queueSets.begin();
QList<QPair<DownloadPolicyKey, DownloadQueueSet*> >::iterator const end = m_queueSets.end();
for (; pos != end; ++pos ) {
if ( (*pos).first.matches( hostName, usage )) {
result = (*pos).second;
break;
}
}
if ( !result ) {
mDebug() << "No download policy found for" << hostName << usage
<< ", using default policy.";
result = m_defaultQueueSets[ usage ];
}
return result;
}
HttpDownloadManager::HttpDownloadManager( StoragePolicy *policy )
: d( new Private( this, policy ) )
{
d->m_requeueTimer.setInterval( requeueTime );
connect( &d->m_requeueTimer, SIGNAL(timeout()), this, SLOT(requeue()) );
d->connectDefaultQueueSets();
}
HttpDownloadManager::~HttpDownloadManager()
{
delete d;
}
void HttpDownloadManager::setDownloadEnabled( const bool enable )
{
d->m_networkAccessManager.setNetworkAccessible( enable ? QNetworkAccessManager::Accessible : QNetworkAccessManager::NotAccessible );
d->m_acceptJobs = enable;
QList<QPair<DownloadPolicyKey, DownloadQueueSet *> >::iterator pos = d->m_queueSets.begin();
QList<QPair<DownloadPolicyKey, DownloadQueueSet *> >::iterator const end = d->m_queueSets.end();
for (; pos != end; ++pos ) {
pos->second->purgeJobs();
}
}
void HttpDownloadManager::addDownloadPolicy( const DownloadPolicy& policy )
{
if ( d->hasDownloadPolicy( policy ))
return;
DownloadQueueSet * const queueSet = new DownloadQueueSet( policy, this );
d->connectQueueSet( queueSet );
d->m_queueSets.append( QPair<DownloadPolicyKey, DownloadQueueSet *>
( queueSet->downloadPolicy().key(), queueSet ));
}
void HttpDownloadManager::addJob( const QUrl& sourceUrl, const QString& destFileName,
const QString &id, const DownloadUsage usage )
{
if ( !d->m_acceptJobs ) {
mDebug() << Q_FUNC_INFO << "Working offline, not adding job";
return;
}
DownloadQueueSet * const queueSet = d->findQueues( sourceUrl.host(), usage );
if ( queueSet->canAcceptJob( sourceUrl, destFileName )) {
HttpJob * const job = new HttpJob( sourceUrl, destFileName, id, &d->m_networkAccessManager );
job->setUserAgentPluginId( "QNamNetworkPlugin" );
job->setDownloadUsage( usage );
mDebug() << "adding job " << sourceUrl;
queueSet->addJob( job );
}
}
void HttpDownloadManager::Private::finishJob( const QByteArray& data, const QString& destinationFileName,
const QString& id )
{
mDebug() << "emitting downloadComplete( QByteArray, " << id << ")";
emit m_downloadManager->downloadComplete( data, id );
if ( m_storagePolicy ) {
const bool saved = m_storagePolicy->updateFile( destinationFileName, data );
if ( saved ) {
mDebug() << "emitting downloadComplete( " << destinationFileName << ", " << id << ")";
emit m_downloadManager->downloadComplete( destinationFileName, id );
} else {
qWarning() << "Could not save:" << destinationFileName;
}
}
}
void HttpDownloadManager::Private::requeue()
{
m_requeueTimer.stop();
QList<QPair<DownloadPolicyKey, DownloadQueueSet *> >::iterator pos = m_queueSets.begin();
QList<QPair<DownloadPolicyKey, DownloadQueueSet *> >::iterator const end = m_queueSets.end();
for (; pos != end; ++pos ) {
(*pos).second->retryJobs();
}
}
void HttpDownloadManager::Private::startRetryTimer()
{
if ( !m_requeueTimer.isActive() )
m_requeueTimer.start();
}
void HttpDownloadManager::Private::connectDefaultQueueSets()
{
QMap<DownloadUsage, DownloadQueueSet *>::iterator pos = m_defaultQueueSets.begin();
QMap<DownloadUsage, DownloadQueueSet *>::iterator const end = m_defaultQueueSets.end();
for (; pos != end; ++pos )
connectQueueSet( pos.value() );
}
void HttpDownloadManager::Private::connectQueueSet( DownloadQueueSet * queueSet )
{
connect( queueSet, SIGNAL(jobFinished(QByteArray,QString,QString)),
m_downloadManager, SLOT(finishJob(QByteArray,QString,QString)));
connect( queueSet, SIGNAL(jobRetry()), m_downloadManager, SLOT(startRetryTimer()));
connect( queueSet, SIGNAL(jobRedirected(QUrl,QString,QString,DownloadUsage)),
m_downloadManager, SLOT(addJob(QUrl,QString,QString,DownloadUsage)));
// relay jobAdded/jobRemoved signals (interesting for progress bar)
connect( queueSet, SIGNAL(jobAdded()), m_downloadManager, SIGNAL(jobAdded()));
connect( queueSet, SIGNAL(jobRemoved()), m_downloadManager, SIGNAL(jobRemoved()));
connect( queueSet, SIGNAL(progressChanged(int,int)), m_downloadManager, SIGNAL(progressChanged(int,int)) );
}
bool HttpDownloadManager::Private::hasDownloadPolicy( const DownloadPolicy& policy ) const
{
bool found = false;
QList<QPair<DownloadPolicyKey, DownloadQueueSet*> >::const_iterator pos = m_queueSets.constBegin();
QList<QPair<DownloadPolicyKey, DownloadQueueSet*> >::const_iterator const end = m_queueSets.constEnd();
for (; pos != end; ++pos ) {
if ( (*pos).second->downloadPolicy() == policy ) {
found = true;
break;
}
}
return found;
}
QByteArray HttpDownloadManager::userAgent(const QString &platform, const QString &component)
{
QString result( "Mozilla/5.0 (compatible; Marble/%1; %2; %3; %4)" );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
QString const device = smallScreen ? "MobileDevice" : "DesktopDevice";
result = result.arg( MARBLE_VERSION_STRING, device, platform, component);
return result.toLatin1();
}
#include "moc_HttpDownloadManager.cpp"
diff --git a/src/lib/marble/HttpJob.cpp b/src/lib/marble/HttpJob.cpp
index c78d68a53..cc1461c35 100644
--- a/src/lib/marble/HttpJob.cpp
+++ b/src/lib/marble/HttpJob.cpp
@@ -1,201 +1,201 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008,2009 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2008 Pino Toscano <pino@kde.org>
//
#include "HttpJob.h"
#include "MarbleDebug.h"
#include "HttpDownloadManager.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
using namespace Marble;
class Marble::HttpJobPrivate
{
public:
HttpJobPrivate( const QUrl & sourceUrl, const QString & destFileName,
const QString &id, QNetworkAccessManager *networkAccessManager );
QUrl m_sourceUrl;
QString m_destinationFileName;
QString m_initiatorId;
int m_trialsLeft;
DownloadUsage m_downloadUsage;
QString m_userAgent;
QNetworkAccessManager *const m_networkAccessManager;
QNetworkReply *m_networkReply;
};
HttpJobPrivate::HttpJobPrivate( const QUrl & sourceUrl, const QString & destFileName,
const QString &id, QNetworkAccessManager *networkAccessManager )
: m_sourceUrl( sourceUrl ),
m_destinationFileName( destFileName ),
m_initiatorId( id ),
m_trialsLeft( 3 ),
m_downloadUsage( DownloadBrowse ),
// FIXME: remove initialization depending on if empty pluginId
// results in valid user agent string
m_userAgent( "unknown" ),
m_networkAccessManager( networkAccessManager ),
- m_networkReply( 0 )
+ m_networkReply( nullptr )
{
}
HttpJob::HttpJob( const QUrl & sourceUrl, const QString & destFileName, const QString &id, QNetworkAccessManager *networkAccessManager )
: d( new HttpJobPrivate( sourceUrl, destFileName, id, networkAccessManager ) )
{
}
HttpJob::~HttpJob()
{
delete d;
}
QUrl HttpJob::sourceUrl() const
{
return d->m_sourceUrl;
}
void HttpJob::setSourceUrl( const QUrl &url )
{
d->m_sourceUrl = url;
}
QString HttpJob::initiatorId() const
{
return d->m_initiatorId;
}
void HttpJob::setInitiatorId( const QString &id )
{
d->m_initiatorId = id;
}
QString HttpJob::destinationFileName() const
{
return d->m_destinationFileName;
}
void HttpJob::setDestinationFileName( const QString &fileName )
{
d->m_destinationFileName = fileName;
}
bool HttpJob::tryAgain()
{
if( d->m_trialsLeft > 0 ) {
d->m_trialsLeft--;
return true;
}
else {
return false;
}
}
DownloadUsage HttpJob::downloadUsage() const
{
return d->m_downloadUsage;
}
void HttpJob::setDownloadUsage( const DownloadUsage usage )
{
d->m_downloadUsage = usage;
}
void HttpJob::setUserAgentPluginId( const QString & pluginId ) const
{
d->m_userAgent = pluginId;
}
QByteArray HttpJob::userAgent() const
{
switch ( d->m_downloadUsage ) {
case DownloadBrowse:
return HttpDownloadManager::userAgent("Browser", d->m_userAgent);
break;
case DownloadBulk:
return HttpDownloadManager::userAgent("BulkDownloader", d->m_userAgent);
break;
default:
qCritical() << "Unknown download usage value:" << d->m_downloadUsage;
return HttpDownloadManager::userAgent("unknown", d->m_userAgent);
}
}
void HttpJob::execute()
{
QNetworkRequest request( d->m_sourceUrl );
request.setAttribute( QNetworkRequest::HttpPipeliningAllowedAttribute, true );
request.setRawHeader( "User-Agent", userAgent() );
d->m_networkReply = d->m_networkAccessManager->get( request );
connect( d->m_networkReply, SIGNAL(downloadProgress(qint64,qint64)),
SLOT(downloadProgress(qint64,qint64)));
connect( d->m_networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
SLOT(error(QNetworkReply::NetworkError)));
connect( d->m_networkReply, SIGNAL(finished()),
SLOT(finished()));
}
void HttpJob::downloadProgress( qint64 bytesReceived, qint64 bytesTotal )
{
Q_UNUSED(bytesReceived);
Q_UNUSED(bytesTotal);
// mDebug() << "downloadProgress" << destinationFileName()
// << bytesReceived << '/' << bytesTotal;
}
void HttpJob::error( QNetworkReply::NetworkError code )
{
mDebug() << "error" << destinationFileName() << code;
}
void HttpJob::finished()
{
QNetworkReply::NetworkError const error = d->m_networkReply->error();
// mDebug() << "finished" << destinationFileName()
// << "error" << error;
const QVariant httpPipeliningWasUsed =
d->m_networkReply->attribute( QNetworkRequest::HttpPipeliningWasUsedAttribute );
if ( !httpPipeliningWasUsed.isNull() )
mDebug() << "http pipelining used:" << httpPipeliningWasUsed.toBool();
switch ( error ) {
case QNetworkReply::NoError: {
// check if we are redirected
const QVariant redirectionAttribute =
d->m_networkReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirectionAttribute.isNull() ) {
emit redirected( this, redirectionAttribute.toUrl() );
}
else {
// no redirection occurred
const QByteArray data = d->m_networkReply->readAll();
emit dataReceived( this, data );
}
}
break;
default:
emit jobDone( this, 1 );
}
d->m_networkReply->disconnect( this );
// No delete. This method is called by a signal QNetworkReply::finished.
d->m_networkReply->deleteLater();
- d->m_networkReply = 0;
+ d->m_networkReply = nullptr;
}
#include "moc_HttpJob.cpp"
diff --git a/src/lib/marble/LatLonBoxWidget.h b/src/lib/marble/LatLonBoxWidget.h
index 302866186..c1a915603 100644
--- a/src/lib/marble/LatLonBoxWidget.h
+++ b/src/lib/marble/LatLonBoxWidget.h
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Torsten Rahn <tackat@kde.org>
#ifndef MARBLE_LATLONBOXWIDGET_H
#define MARBLE_LATLONBOXWIDGET_H
#include <QWidget>
#include "marble_export.h"
namespace Marble
{
class GeoDataLatLonBox;
class MARBLE_EXPORT LatLonBoxWidget: public QWidget
{
Q_OBJECT
public:
- explicit LatLonBoxWidget( QWidget * const parent = 0, Qt::WindowFlags const f = 0 );
+ explicit LatLonBoxWidget( QWidget * const parent = nullptr, Qt::WindowFlags const f = nullptr );
~LatLonBoxWidget() override;
GeoDataLatLonBox latLonBox() const;
void setLatLonBox( GeoDataLatLonBox const & );
Q_SIGNALS:
void valueChanged();
private Q_SLOTS:
void updateLatSingleStep();
void updateLonSingleStep();
private:
Q_DISABLE_COPY( LatLonBoxWidget )
class Private;
Private * const d;
};
}
#endif
diff --git a/src/lib/marble/LatLonEdit.cpp b/src/lib/marble/LatLonEdit.cpp
index 95e9aab8a..10c29fe15 100644
--- a/src/lib/marble/LatLonEdit.cpp
+++ b/src/lib/marble/LatLonEdit.cpp
@@ -1,670 +1,670 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
#include "LatLonEdit.h"
#include "ui_LatLonEdit.h"
#include <QWidget>
#include "MarbleDebug.h"
#include "MarbleGlobal.h"
namespace Marble
{
// This widget can have 3 different designs, one per notation (Decimal, DMS, DM)
// To reduce the footprint this was not implemented using a stack of widgets
// where each widget offer the needed design for another notation.
// Instead, as Decimal and DM are both using subsets of the UI elements used
// for DMS, just the UI elements for DMS are created and modified as needed,
// if another notation is selected. This involves showing and hiding them and
// setting the proper suffix and min/max values.
// The logic per notation is moved into specialized subclasses of a class
// AbstractInputHandler.
// TODO: simply remove the LatLonEdit.ui file and embed code directly here?
enum { PositiveSphereIndex = 0, NegativeSphereIndex = 1 };
class LatLonEditPrivate;
class AbstractInputHandler // TODO: better name
{
protected:
explicit AbstractInputHandler(LatLonEditPrivate *ui) : m_ui(ui) {}
public:
virtual ~AbstractInputHandler() {}
public: // API to be implemented
virtual void setupUi() = 0;
virtual void setupMinMax(LatLonEdit::Dimension dimension) = 0;
virtual void setValue(qreal value) = 0;
virtual void handleIntEditChange() = 0;
virtual void handleUIntEditChange() = 0;
virtual void handleFloatEditChange() = 0;
virtual qreal calculateValue() const = 0;
protected:
LatLonEditPrivate * const m_ui;
};
class DecimalInputHandler : public AbstractInputHandler
{
public:
explicit DecimalInputHandler(LatLonEditPrivate *ui) : AbstractInputHandler(ui) {}
public: // AbstractInputHandler API
void setupUi() override;
void setupMinMax(LatLonEdit::Dimension dimension) override;
void setValue(qreal value) override;
void handleIntEditChange() override;
void handleUIntEditChange() override;
void handleFloatEditChange() override;
qreal calculateValue() const override;
};
class DMSInputHandler : public AbstractInputHandler
{
public:
explicit DMSInputHandler(LatLonEditPrivate *ui) : AbstractInputHandler(ui) {}
public: // AbstractInputHandler API
void setupUi() override;
void setupMinMax(LatLonEdit::Dimension dimension) override;
void setValue(qreal value) override;
void handleIntEditChange() override;
void handleUIntEditChange() override;
void handleFloatEditChange() override;
qreal calculateValue() const override;
};
class DMInputHandler : public AbstractInputHandler
{
public:
explicit DMInputHandler(LatLonEditPrivate *ui) : AbstractInputHandler(ui) {}
public: // AbstractInputHandler API
void setupUi() override;
void setupMinMax(LatLonEdit::Dimension dimension) override;
void setValue(qreal value) override;
void handleIntEditChange() override;
void handleUIntEditChange() override;
void handleFloatEditChange() override;
qreal calculateValue() const override;
};
class LatLonEditPrivate : public Ui::LatLonEditPrivate
{
friend class DecimalInputHandler;
friend class DMSInputHandler;
friend class DMInputHandler;
public:
LatLonEdit::Dimension m_dimension;
qreal m_value;
GeoDataCoordinates::Notation m_notation;
AbstractInputHandler *m_inputHandler;
// flag which indicates that the widgets are updated due to a change
// in one of the other widgets. Q*SpinBox does not have a signal which is
// only emitted by a change due to user input, not code setting a new value.
// This flag should be less expensive then disconnecting from and reconnecting
// to the valueChanged signal of all widgets.
bool m_updating : 1;
LatLonEditPrivate();
~LatLonEditPrivate();
void init(QWidget* parent);
};
static void
switchSign( QComboBox *sign )
{
const bool isNegativeSphere = (sign->currentIndex() == NegativeSphereIndex);
sign->setCurrentIndex( isNegativeSphere ? PositiveSphereIndex : NegativeSphereIndex );
}
void DecimalInputHandler::setupUi()
{
m_ui->m_floatValueEditor->setSuffix(LatLonEdit::trUtf8("\xC2\xB0")); // the degree symbol °
m_ui->m_floatValueEditor->setDecimals(5);
m_ui->m_intValueEditor->hide();
m_ui->m_uintValueEditor->hide();
}
void DecimalInputHandler::setupMinMax(LatLonEdit::Dimension dimension)
{
const qreal maxValue = (dimension == LatLonEdit::Longitude) ? 180.0 : 90.0;
m_ui->m_floatValueEditor->setMinimum(-maxValue);
m_ui->m_floatValueEditor->setMaximum( maxValue);
}
void DecimalInputHandler::setValue(qreal value)
{
value = qAbs(value);
m_ui->m_floatValueEditor->setValue(value);
}
void DecimalInputHandler::handleIntEditChange()
{
// nothing to do, perhaps rather disconnect the signal with this notation
}
void DecimalInputHandler::handleUIntEditChange()
{
// nothing to do, perhaps rather disconnect the signal with this notation
}
void DecimalInputHandler::handleFloatEditChange()
{
// nothing to do, perhaps rather disconnect the signal with this notation
}
qreal DecimalInputHandler::calculateValue() const
{
qreal value = m_ui->m_floatValueEditor->value();
if (m_ui->m_sign->currentIndex() == NegativeSphereIndex) {
value *= -1;
}
return value;
}
void DMSInputHandler::setupUi()
{
m_ui->m_uintValueEditor->setSuffix(LatLonEdit::tr("'"));
m_ui->m_floatValueEditor->setSuffix(LatLonEdit::tr("\""));
m_ui->m_floatValueEditor->setDecimals(2);
m_ui->m_intValueEditor->show();
m_ui->m_uintValueEditor->show();
}
void DMSInputHandler::setupMinMax(LatLonEdit::Dimension dimension)
{
const int maxValue = (dimension == LatLonEdit::Longitude) ? 180 : 90;
m_ui->m_intValueEditor->setMinimum(-maxValue);
m_ui->m_intValueEditor->setMaximum( maxValue);
}
void DMSInputHandler::setValue(qreal value)
{
value = qAbs( value );
int degValue = (int) value;
qreal minFValue = 60 * (value - degValue);
int minValue = (int) minFValue;
qreal secFValue = 60 * (minFValue - minValue);
// Adjustment for fuzziness (like 49.999999999999999999999)
int secValue = qRound(secFValue);
if (secValue > 59) {
secFValue = 0.0;
++minValue;
}
if (minValue > 59) {
minValue = 0;
++degValue;
}
m_ui->m_intValueEditor->setValue( degValue );
m_ui->m_uintValueEditor->setValue( minValue );
m_ui->m_floatValueEditor->setValue( secFValue );
}
void DMSInputHandler::handleIntEditChange()
{
const int degValue = m_ui->m_intValueEditor->value();
const int minDegValue = m_ui->m_intValueEditor->minimum();
const int maxDegValue = m_ui->m_intValueEditor->maximum();
// at max/min?
if (degValue <= minDegValue || maxDegValue <= degValue) {
m_ui->m_uintValueEditor->setValue( 0 );
m_ui->m_floatValueEditor->setValue( 0.0 );
}
}
void DMSInputHandler::handleUIntEditChange()
{
const int degValue = m_ui->m_intValueEditor->value();
const int minValue = m_ui->m_uintValueEditor->value();
if (minValue < 0) {
if (degValue != 0) {
m_ui->m_uintValueEditor->setValue( 59 );
const int degDec = (degValue > 0) ? 1 : -1;
m_ui->m_intValueEditor->setValue( degValue - degDec );
} else {
switchSign( m_ui->m_sign );
m_ui->m_uintValueEditor->setValue( 1 );
}
} else {
const int minDegValue = m_ui->m_intValueEditor->minimum();
const int maxDegValue = m_ui->m_intValueEditor->maximum();
// at max/min already?
if (degValue <= minDegValue || maxDegValue <= degValue) {
// ignore
m_ui->m_uintValueEditor->setValue( 0 );
// overflow?
} else if (minValue >= 60) {
m_ui->m_uintValueEditor->setValue( 0 );
// will reach max/min?
if (minDegValue+1 == degValue || degValue == maxDegValue-1) {
// reset also sec
m_ui->m_floatValueEditor->setValue( 0.0 );
}
const int degInc = (degValue > 0) ? 1 : -1;
m_ui->m_intValueEditor->setValue( degValue + degInc );
}
}
}
void DMSInputHandler::handleFloatEditChange()
{
const int degValue = m_ui->m_intValueEditor->value();
const int minValue = m_ui->m_uintValueEditor->value();
const qreal secValue = m_ui->m_floatValueEditor->value();
if (secValue < 0.0) {
const qreal secDiff = -secValue;
if (degValue == 0 && minValue == 0) {
switchSign( m_ui->m_sign );
m_ui->m_floatValueEditor->setValue( secDiff );
} else {
m_ui->m_floatValueEditor->setValue( 60.0 - secDiff );
if (minValue > 0) {
m_ui->m_uintValueEditor->setValue( minValue - 1 );
} else {
m_ui->m_uintValueEditor->setValue( 59 );
const int degDec = (degValue > 0) ? 1 : -1;
m_ui->m_intValueEditor->setValue( degValue - degDec );
}
}
} else {
const int minDegValue = m_ui->m_intValueEditor->minimum();
const int maxDegValue = m_ui->m_intValueEditor->maximum();
// at max/min already?
if (degValue <= minDegValue || maxDegValue <= degValue) {
// ignore
m_ui->m_floatValueEditor->setValue( 0.0 );
// need to inc minutes?
} else if (secValue >= 60.0) {
qreal newSec = secValue - 60.0;
// will reach max/min?
if (minValue == 59) {
m_ui->m_uintValueEditor->setValue( 0 );
// will reach max/min?
if (minDegValue+1 == degValue || degValue == maxDegValue-1) {
// reset also sec
newSec = 0.0;
}
const int degInc = (degValue > 0) ? 1 : -1;
m_ui->m_intValueEditor->setValue( degValue + degInc );
} else {
m_ui->m_uintValueEditor->setValue( minValue + 1 );
}
m_ui->m_floatValueEditor->setValue( newSec );
}
}
}
qreal DMSInputHandler::calculateValue() const
{
const bool isNegativeDeg = ( m_ui->m_intValueEditor->value() < 0 );
const qreal deg = (qreal)(qAbs(m_ui->m_intValueEditor->value()));
const qreal min = (qreal)(m_ui->m_uintValueEditor->value()) / 60.0;
const qreal sec = m_ui->m_floatValueEditor->value() / 3600.0;
qreal value = deg + min + sec;
if (isNegativeDeg) {
value *= -1;
}
if (m_ui->m_sign->currentIndex() == NegativeSphereIndex) {
value *= -1;
}
return value;
}
void DMInputHandler::setupUi()
{
m_ui->m_floatValueEditor->setSuffix(LatLonEdit::tr("'"));
m_ui->m_floatValueEditor->setDecimals(2);
m_ui->m_intValueEditor->show();
m_ui->m_uintValueEditor->hide();
}
void DMInputHandler::setupMinMax(LatLonEdit::Dimension dimension)
{
const int maxValue = (dimension == LatLonEdit::Longitude) ? 180 : 90;
m_ui->m_intValueEditor->setMinimum(-maxValue);
m_ui->m_intValueEditor->setMaximum( maxValue);
}
void DMInputHandler::setValue(qreal value)
{
value = qAbs(value);
int degValue = (int)value;
qreal minFValue = 60 * (value - degValue);
// Adjustment for fuzziness (like 49.999999999999999999999)
int minValue = qRound( minFValue );
if (minValue > 59) {
minFValue = 0.0;
++degValue;
}
m_ui->m_intValueEditor->setValue( degValue );
m_ui->m_floatValueEditor->setValue( minFValue );
}
void DMInputHandler::handleIntEditChange()
{
const int degValue = m_ui->m_intValueEditor->value();
const int minDegValue = m_ui->m_intValueEditor->minimum();
const int maxDegValue = m_ui->m_intValueEditor->maximum();
// at max/min?
if (degValue <= minDegValue || maxDegValue <= degValue) {
m_ui->m_floatValueEditor->setValue( 0.0 );
}
}
void DMInputHandler::handleUIntEditChange()
{
// nothing to be done here, should be never called
}
void DMInputHandler::handleFloatEditChange()
{
const int degValue = m_ui->m_intValueEditor->value();
const qreal minValue = m_ui->m_floatValueEditor->value();
if (minValue < 0.0) {
const qreal minDiff = -minValue;
if (degValue == 0) {
switchSign( m_ui->m_sign );
m_ui->m_floatValueEditor->setValue( minDiff );
} else {
m_ui->m_floatValueEditor->setValue( 60.0 - minDiff );
m_ui->m_intValueEditor->setValue( degValue - 1 );
}
} else {
const int minDegValue = m_ui->m_intValueEditor->minimum();
const int maxDegValue = m_ui->m_intValueEditor->maximum();
// at max/min already?
if (degValue <= minDegValue || maxDegValue <= degValue) {
// ignore
m_ui->m_floatValueEditor->setValue( 0.0 );
// need to inc degrees?
} else if (minValue >= 60.0) {
qreal newMin = minValue - 60.0;
// will reach max/min?
if (minDegValue+1 == degValue || degValue == maxDegValue-1) {
// reset also sec
newMin = 0.0;
} else {
m_ui->m_intValueEditor->setValue( degValue + 1 );
}
m_ui->m_floatValueEditor->setValue( newMin );
}
}
}
qreal DMInputHandler::calculateValue() const
{
const bool isNegativeDeg = ( m_ui->m_intValueEditor->value() < 0 );
const qreal deg = (qreal)(qAbs(m_ui->m_intValueEditor->value()));
const qreal min = m_ui->m_floatValueEditor->value() / 60.0;
qreal value = deg + min;
if (isNegativeDeg) {
value *= -1;
}
if (m_ui->m_sign->currentIndex() == NegativeSphereIndex) {
value *= -1;
}
return value;
}
LatLonEditPrivate::LatLonEditPrivate()
: m_dimension(LatLonEdit::Latitude)
, m_value(0.0)
, m_notation(GeoDataCoordinates::DMS)
, m_inputHandler(new DMSInputHandler(this))
, m_updating(false)
{}
LatLonEditPrivate::~LatLonEditPrivate()
{
delete m_inputHandler;
}
void LatLonEditPrivate::init(QWidget* parent) { setupUi(parent); }
}
using namespace Marble;
LatLonEdit::LatLonEdit(QWidget *parent, LatLonEdit::Dimension dimension, GeoDataCoordinates::Notation notation)
: QWidget( parent ), d(new LatLonEditPrivate())
{
d->init(this);
setDimension(dimension);
setNotation(notation);
connect(d->m_intValueEditor, SIGNAL(valueChanged(int)), this, SLOT(checkIntValueOverflow()));
connect(d->m_uintValueEditor, SIGNAL(valueChanged(int)), this, SLOT(checkUIntValueOverflow()));
connect(d->m_floatValueEditor, SIGNAL(valueChanged(double)), this, SLOT(checkFloatValueOverflow()));
connect(d->m_sign, SIGNAL(currentIndexChanged(int)),
this, SLOT(onSignChanged()));
}
LatLonEdit::~LatLonEdit()
{
delete d;
}
qreal LatLonEdit::value() const
{
return d->m_value;
}
GeoDataCoordinates::Notation LatLonEdit::notation() const
{
return d->m_notation;
}
void LatLonEdit::onSignChanged()
{
if( d->m_updating )
return;
// Only flip the value if it does not match the sign
if (d->m_sign->currentIndex() == PositiveSphereIndex) {
if (d->m_value < 0.0) {
d->m_value *= -1;
}
} else {
if (d->m_value > 0.0) {
d->m_value *= -1;
}
}
emit valueChanged( d->m_value );
}
void LatLonEdit::setDimension( Dimension dimension )
{
d->m_dimension = dimension;
d->m_updating = true;
d->m_inputHandler->setupMinMax(dimension);
// update sign widget content
{
d->m_sign->clear();
switch (dimension) {
case Longitude:
d->m_sign->addItem( tr("E", "East, the direction" ) );
d->m_sign->addItem( tr("W", "West, the direction" ) );
break;
case Latitude:
d->m_sign->addItem( tr("N", "North, the direction" ) );
d->m_sign->addItem( tr("S", "South, the direction" ) );
break;
}
}
d->m_updating = false;
// reset value, old one is useless
setValue( 0.0 );
}
void LatLonEdit::setNotation(GeoDataCoordinates::Notation notation)
{
delete d->m_inputHandler;
- d->m_inputHandler = 0;
+ d->m_inputHandler = nullptr;
switch (notation) {
case GeoDataCoordinates::Decimal:
d->m_inputHandler = new DecimalInputHandler(d);
break;
case GeoDataCoordinates::DMS:
d->m_inputHandler = new DMSInputHandler(d);
break;
case GeoDataCoordinates::DM:
d->m_inputHandler = new DMInputHandler(d);
break;
case GeoDataCoordinates::UTM:
/** @todo see below */
break;
case GeoDataCoordinates::Astro:
/** @todo see below */
break;
}
if (!d->m_inputHandler) {
/** @todo Temporary fallback to DecimalInputHandler
* Implement proper handlers for UTM and Astro */
d->m_inputHandler = new DecimalInputHandler(d);
}
d->m_notation = notation;
d->m_inputHandler->setupUi();
d->m_inputHandler->setupMinMax(d->m_dimension);
d->m_inputHandler->setValue(d->m_value);
}
void LatLonEdit::checkFloatValueOverflow()
{
if( d->m_updating )
return;
d->m_updating = true;
d->m_inputHandler->handleFloatEditChange();
d->m_updating = false;
recalculate();
}
void LatLonEdit::checkUIntValueOverflow()
{
if( d->m_updating )
return;
d->m_updating = true;
d->m_inputHandler->handleUIntEditChange();
d->m_updating = false;
recalculate();
}
void LatLonEdit::checkIntValueOverflow()
{
if( d->m_updating )
return;
d->m_updating = true;
d->m_inputHandler->handleIntEditChange();
d->m_updating = false;
recalculate();
}
void LatLonEdit::setValue( qreal value )
{
// limit to allowed values
const qreal maxValue = (d->m_dimension == Longitude) ? 180.0 : 90.0;
if (value > maxValue) {
value = maxValue;
} else {
const qreal minValue = -maxValue;
if (value < minValue) {
value = minValue;
}
}
// no change?
if( value == d->m_value ) {
return;
}
d->m_value = value;
// calculate sub values
// calculation is done similar to GeoDataCoordinates::lonToString,
// perhaps should be moved with similar methods into some utility class/namespace
d->m_updating = true;
d->m_inputHandler->setValue(value);
const bool isNegative = (value < 0.0);
d->m_sign->setCurrentIndex( isNegative ? NegativeSphereIndex : PositiveSphereIndex );
d->m_updating = false;
}
void LatLonEdit::recalculate()
{
d->m_value = d->m_inputHandler->calculateValue();
emit valueChanged( d->m_value );
}
#include "moc_LatLonEdit.cpp"
diff --git a/src/lib/marble/LatLonEdit.h b/src/lib/marble/LatLonEdit.h
index 99878f2ac..8dba69e3c 100644
--- a/src/lib/marble/LatLonEdit.h
+++ b/src/lib/marble/LatLonEdit.h
@@ -1,67 +1,67 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
#ifndef MARBLE_LATLONEDIT_H
#define MARBLE_LATLONEDIT_H
#include <QWidget>
#include "GeoDataCoordinates.h"
#include "MarbleGlobal.h"
#include "marble_export.h"
namespace Marble
{
class LatLonEditPrivate;
class MARBLE_EXPORT LatLonEdit : public QWidget
{
Q_OBJECT
//FIXME: make the dimension enum work
//Q_PROPERTY( qreal value READ value WRITE setValue )
//Q_PROPERTY( int dimension READ dimension WRITE setDimension )
public:
/**
* @brief This enum is used to choose the dimension.
*/
enum Dimension {
Latitude, ///< Latitude
Longitude ///< Longitude
};
- explicit LatLonEdit(QWidget *parent = 0, Dimension dimension = Longitude,
+ explicit LatLonEdit(QWidget *parent = nullptr, Dimension dimension = Longitude,
GeoDataCoordinates::Notation notation = GeoDataCoordinates::DMS);
~LatLonEdit() override;
qreal value() const;
Dimension dimension() const;
GeoDataCoordinates::Notation notation() const;
public Q_SLOTS:
void setValue(qreal newvalue);
void setDimension( Dimension dimension );
void setNotation(GeoDataCoordinates::Notation notation);
Q_SIGNALS:
void valueChanged( qreal value );
private Q_SLOTS:
void checkIntValueOverflow();
void checkUIntValueOverflow();
void checkFloatValueOverflow();
void onSignChanged();
private:
// recalculates m_value based on spinboxes
void recalculate();
private:
LatLonEditPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/LayerManager.cpp b/src/lib/marble/LayerManager.cpp
index ea94f647c..057ee82cf 100644
--- a/src/lib/marble/LayerManager.cpp
+++ b/src/lib/marble/LayerManager.cpp
@@ -1,245 +1,245 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2011,2012 Bernahrd Beschow <bbeschow@cs.tu-berlin.de>
//
// Own
#include "LayerManager.h"
// Local dir
#include "MarbleDebug.h"
#include "AbstractDataPlugin.h"
#include "AbstractDataPluginItem.h"
#include "GeoPainter.h"
#include "RenderPlugin.h"
#include "LayerInterface.h"
#include "RenderState.h"
#include <QTime>
namespace Marble
{
class Q_DECL_HIDDEN LayerManager::Private
{
public:
Private(LayerManager *parent);
~Private();
void updateVisibility( bool visible, const QString &nameId );
LayerManager *const q;
QList<RenderPlugin *> m_renderPlugins;
QList<AbstractDataPlugin *> m_dataPlugins;
QList<LayerInterface *> m_internalLayers;
RenderState m_renderState;
bool m_showBackground;
bool m_showRuntimeTrace;
};
LayerManager::Private::Private(LayerManager *parent) :
q(parent),
m_renderPlugins(),
m_showBackground(true),
m_showRuntimeTrace(false)
{
}
LayerManager::Private::~Private()
{
}
void LayerManager::Private::updateVisibility( bool visible, const QString &nameId )
{
emit q->visibilityChanged( nameId, visible );
}
LayerManager::LayerManager(QObject *parent) :
QObject(parent),
d(new Private(this))
{
}
LayerManager::~LayerManager()
{
delete d;
}
bool LayerManager::showBackground() const
{
return d->m_showBackground;
}
bool LayerManager::showRuntimeTrace() const
{
return d->m_showRuntimeTrace;
}
void LayerManager::addRenderPlugin(RenderPlugin *renderPlugin)
{
d->m_renderPlugins.append(renderPlugin);
QObject::connect(renderPlugin, SIGNAL(settingsChanged(QString)),
this, SIGNAL(pluginSettingsChanged()));
QObject::connect(renderPlugin, SIGNAL(repaintNeeded(QRegion)),
this, SIGNAL(repaintNeeded(QRegion)));
QObject::connect(renderPlugin, SIGNAL(visibilityChanged(bool,QString)),
this, SLOT(updateVisibility(bool,QString)));
// get data plugins
AbstractDataPlugin *const dataPlugin = qobject_cast<AbstractDataPlugin *>(renderPlugin);
if(dataPlugin) {
d->m_dataPlugins.append(dataPlugin);
}
}
QList<AbstractDataPlugin *> LayerManager::dataPlugins() const
{
return d->m_dataPlugins;
}
QList<AbstractDataPluginItem *> LayerManager::whichItemAt( const QPoint& curpos ) const
{
QList<AbstractDataPluginItem *> itemList;
for( auto *plugin: d->m_dataPlugins ) {
itemList.append( plugin->whichItemAt( curpos ) );
}
return itemList;
}
void LayerManager::renderLayers( GeoPainter *painter, ViewportParams *viewport )
{
d->m_renderState = RenderState(QStringLiteral("Marble"));
const QTime totalTime = QTime::currentTime();
QStringList renderPositions;
if ( d->m_showBackground ) {
renderPositions
<< QStringLiteral("STARS")
<< QStringLiteral("BEHIND_TARGET");
}
renderPositions
<< QStringLiteral("SURFACE")
<< QStringLiteral("HOVERS_ABOVE_SURFACE")
<< QStringLiteral("GRATICULE")
<< QStringLiteral("PLACEMARKS")
<< QStringLiteral("ATMOSPHERE")
<< QStringLiteral("ORBIT")
<< QStringLiteral("ALWAYS_ON_TOP")
<< QStringLiteral("FLOAT_ITEM")
<< QStringLiteral("USER_TOOLS");
QStringList traceList;
for( const auto& renderPosition: renderPositions ) {
QList<LayerInterface*> layers;
// collect all RenderPlugins of current renderPosition
for( auto *renderPlugin: d->m_renderPlugins ) {
if ( renderPlugin && renderPlugin->renderPosition().contains( renderPosition ) ) {
if ( renderPlugin->enabled() && renderPlugin->visible() ) {
if ( !renderPlugin->isInitialized() ) {
renderPlugin->initialize();
emit renderPluginInitialized( renderPlugin );
}
layers.push_back( renderPlugin );
}
}
}
// collect all internal LayerInterfaces of current renderPosition
for( auto *layer: d->m_internalLayers ) {
if ( layer && layer->renderPosition().contains( renderPosition ) ) {
layers.push_back( layer );
}
}
// sort them according to their zValue()s
std::sort( layers.begin(), layers.end(), [] ( const LayerInterface * const one, const LayerInterface * const two ) -> bool {
Q_ASSERT( one && two );
return one->zValue() < two->zValue();
} );
// render the layers of the current renderPosition
QTime timer;
for( auto *layer: layers ) {
timer.start();
- layer->render( painter, viewport, renderPosition, 0 );
+ layer->render( painter, viewport, renderPosition, nullptr );
d->m_renderState.addChild( layer->renderState() );
traceList.append( QString("%2 ms %3").arg( timer.elapsed(),3 ).arg( layer->runtimeTrace() ) );
}
}
if ( d->m_showRuntimeTrace ) {
const int totalElapsed = totalTime.elapsed();
const int fps = 1000.0/totalElapsed;
traceList.append( QString( "Total: %1 ms (%2 fps)" ).arg( totalElapsed, 3 ).arg( fps ) );
painter->save();
painter->setBackgroundMode( Qt::OpaqueMode );
painter->setBackground( Qt::gray );
painter->setFont( QFont( QStringLiteral("Sans Serif"), 10, QFont::Bold ) );
int i=0;
int const top = 150;
int const lineHeight = painter->fontMetrics().height();
for ( const auto &text: traceList ) {
painter->setPen( Qt::black );
painter->drawText( QPoint(10,top+1+lineHeight*i), text );
painter->setPen( Qt::white );
painter->drawText( QPoint(9,top+lineHeight*i), text );
++i;
}
painter->restore();
}
}
void LayerManager::setShowBackground( bool show )
{
d->m_showBackground = show;
}
void LayerManager::setShowRuntimeTrace( bool show )
{
d->m_showRuntimeTrace = show;
}
void LayerManager::addLayer(LayerInterface *layer)
{
if (!d->m_internalLayers.contains(layer)) {
d->m_internalLayers.push_back(layer);
}
}
void LayerManager::removeLayer(LayerInterface *layer)
{
d->m_internalLayers.removeAll(layer);
}
QList<LayerInterface *> LayerManager::internalLayers() const
{
return d->m_internalLayers;
}
RenderState LayerManager::renderState() const
{
return d->m_renderState;
}
}
#include "moc_LayerManager.cpp"
diff --git a/src/lib/marble/LegendWidget.h b/src/lib/marble/LegendWidget.h
index 715ded7a3..202da49da 100644
--- a/src/lib/marble/LegendWidget.h
+++ b/src/lib/marble/LegendWidget.h
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_LEGENDWIDGET_H
#define MARBLE_LEGENDWIDGET_H
// Marble
#include "marble_export.h"
// Qt
#include <QWidget>
namespace Marble
{
class LegendWidgetPrivate;
class MarbleModel;
class MARBLE_EXPORT LegendWidget : public QWidget
{
Q_OBJECT
public:
- explicit LegendWidget( QWidget *parent = 0, Qt::WindowFlags f = 0 );
+ explicit LegendWidget( QWidget *parent = nullptr, Qt::WindowFlags f = nullptr );
~LegendWidget() override;
/**
* @brief Set a MarbleModel associated to this widget.
* @param model the MarbleModel to be set.
*/
void setMarbleModel( MarbleModel *model );
Q_SIGNALS:
void propertyValueChanged( const QString &propertyName, bool value );
void tourLinkClicked( const QString &url );
private:
Q_DISABLE_COPY( LegendWidget )
LegendWidgetPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/MapThemeManager.cpp b/src/lib/marble/MapThemeManager.cpp
index 159409741..07bd73bf3 100644
--- a/src/lib/marble/MapThemeManager.cpp
+++ b/src/lib/marble/MapThemeManager.cpp
@@ -1,599 +1,599 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
//
// Own
#include "MapThemeManager.h"
// Qt
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFileSystemWatcher>
#include <QScopedPointer>
#include <QString>
#include <QStringList>
#include <QStandardItemModel>
// Local dir
#include "GeoDataPhotoOverlay.h"
#include "GeoSceneDocument.h"
#include "GeoSceneMap.h"
#include "GeoSceneHead.h"
#include "GeoSceneIcon.h"
#include "GeoSceneParser.h"
#include "GeoSceneLayer.h"
#include "GeoSceneTileDataset.h"
#include "GeoSceneTextureTileDataset.h"
#include "GeoSceneProperty.h"
#include "GeoSceneZoom.h"
#include "GeoSceneSettings.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "Planet.h"
#include "PlanetFactory.h"
// Std
#include <limits>
namespace
{
static const QString mapDirName = "maps";
static const int columnRelativePath = 1;
}
namespace Marble
{
class Q_DECL_HIDDEN MapThemeManager::Private
{
public:
Private( MapThemeManager *parent );
~Private();
void directoryChanged( const QString& path );
void fileChanged( const QString & path );
/**
* @brief Updates the map theme model on request.
*
* This method should usually get invoked on startup or
* by a QFileSystemWatcher instance.
*/
void updateMapThemeModel();
void watchPaths();
/**
* @brief Adds directory paths and .dgml file paths to the given QStringList.
*/
static void addMapThemePaths( const QString& mapPathName, QStringList& result );
/**
* @brief Helper method for findMapThemes(). Searches for .dgml files below
* given directory path.
*/
static QStringList findMapThemes( const QString& basePath );
/**
* @brief Searches for .dgml files below local and system map directory.
*/
static QStringList findMapThemes();
static GeoSceneDocument* loadMapThemeFile( const QString& mapThemeId );
/**
* @brief Helper method for updateMapThemeModel().
*/
static QList<QStandardItem *> createMapThemeRow( const QString& mapThemeID );
/**
* @brief Deletes any directory with its contents.
* @param directory Path to directory
* WARNING: Please do not raise this method's visibility in future, keep it private.
*/
static bool deleteDirectory( const QString &directory );
MapThemeManager *const q;
QStandardItemModel m_mapThemeModel;
QStandardItemModel m_celestialList;
QFileSystemWatcher m_fileSystemWatcher;
bool m_isInitialized;
private:
/**
* @brief Returns all directory paths and .dgml file paths below local and
* system map directory.
*/
static QStringList pathsToWatch();
};
MapThemeManager::Private::Private( MapThemeManager *parent )
: q( parent ),
m_mapThemeModel( 0, 3 ),
m_celestialList(),
m_fileSystemWatcher(),
m_isInitialized( false )
{
}
MapThemeManager::Private::~Private()
{
}
MapThemeManager::MapThemeManager( QObject *parent )
: QObject( parent ),
d( new Private( this ) )
{
d->watchPaths();
connect( &d->m_fileSystemWatcher, SIGNAL(directoryChanged(QString)),
this, SLOT(directoryChanged(QString)));
connect( &d->m_fileSystemWatcher, SIGNAL(fileChanged(QString)),
this, SLOT(fileChanged(QString)));
}
MapThemeManager::~MapThemeManager()
{
delete d;
}
QStringList MapThemeManager::mapThemeIds() const
{
QStringList result;
if ( !d->m_isInitialized ) {
d->updateMapThemeModel();
d->m_isInitialized = true;
}
const int mapThemeIdCount = d->m_mapThemeModel.rowCount();
result.reserve(mapThemeIdCount);
for (int i = 0; i < mapThemeIdCount; ++i) {
const QString id = d->m_mapThemeModel.data( d->m_mapThemeModel.index( i, 0 ), Qt::UserRole + 1 ).toString();
result << id;
}
return result;
}
GeoSceneDocument* MapThemeManager::loadMapTheme( const QString& mapThemeStringID )
{
if ( mapThemeStringID.isEmpty() )
- return 0;
+ return nullptr;
return Private::loadMapThemeFile( mapThemeStringID );
}
void MapThemeManager::deleteMapTheme( const QString &mapThemeId )
{
const QString dgmlPath = MarbleDirs::localPath() + QLatin1String("/maps/") + mapThemeId;
QFileInfo dgmlFile(dgmlPath);
QString themeDir = dgmlFile.dir().absolutePath();
Private::deleteDirectory( themeDir );
}
bool MapThemeManager::Private::deleteDirectory( const QString& directory )
{
QDir dir( directory );
bool result = true;
if ( dir.exists() ) {
for( const QFileInfo &info: dir.entryInfoList(
QDir::NoDotAndDotDot | QDir::System | QDir::Hidden |
QDir::AllDirs | QDir::Files,
QDir::DirsFirst ) ) {
if ( info.isDir() ) {
result = deleteDirectory( info.absoluteFilePath() );
} else {
result = QFile::remove( info.absoluteFilePath() );
}
if ( !result ) {
return result;
}
}
result = dir.rmdir( directory );
if( !result ) {
return result;
}
}
return result;
}
GeoSceneDocument* MapThemeManager::Private::loadMapThemeFile( const QString& mapThemeStringID )
{
const QString mapThemePath = mapDirName + QLatin1Char('/') + mapThemeStringID;
const QString dgmlPath = MarbleDirs::path( mapThemePath );
// Check whether file exists
QFile file( dgmlPath );
if ( !file.exists() ) {
qWarning() << "Map theme file does not exist:" << dgmlPath;
- return 0;
+ return nullptr;
}
// Open file in right mode
const bool fileReadable = file.open( QIODevice::ReadOnly );
if ( !fileReadable ) {
qWarning() << "Map theme file not readable:" << dgmlPath;
- return 0;
+ return nullptr;
}
GeoSceneParser parser( GeoScene_DGML );
if ( !parser.read( &file )) {
qWarning() << "Map theme file not well-formed:" << dgmlPath;
- return 0;
+ return nullptr;
}
mDebug() << "Map theme file successfully loaded:" << dgmlPath;
// Get result document
GeoSceneDocument* document = static_cast<GeoSceneDocument*>( parser.releaseDocument() );
Q_ASSERT( document );
return document;
}
QStringList MapThemeManager::Private::pathsToWatch()
{
QStringList result;
const QString localMapPathName = MarbleDirs::localPath() + QLatin1Char('/') + mapDirName;
const QString systemMapPathName = MarbleDirs::systemPath() + QLatin1Char('/') + mapDirName;
if( !QDir().exists( localMapPathName ) ) {
QDir().mkpath( localMapPathName );
}
result << localMapPathName;
result << systemMapPathName;
addMapThemePaths( localMapPathName, result );
addMapThemePaths( systemMapPathName, result );
return result;
}
QStringList MapThemeManager::Private::findMapThemes( const QString& basePath )
{
const QString mapPathName = basePath + QLatin1Char('/') + mapDirName;
QDir paths = QDir( mapPathName );
QStringList mapPaths = paths.entryList( QStringList( "*" ),
QDir::AllDirs
| QDir::NoSymLinks
| QDir::NoDotAndDotDot );
QStringList mapDirs;
for ( int planet = 0; planet < mapPaths.size(); ++planet ) {
QDir themeDir = QDir(mapPathName + QLatin1Char('/') + mapPaths.at(planet));
QStringList themeMapPaths = themeDir.entryList(
QStringList( "*" ),
QDir::AllDirs |
QDir::NoSymLinks |
QDir::NoDotAndDotDot );
for ( int theme = 0; theme < themeMapPaths.size(); ++theme ) {
mapDirs << mapPathName + QLatin1Char('/') + mapPaths.at(planet) + QLatin1Char('/')
+ themeMapPaths.at( theme );
}
}
QStringList mapFiles;
QStringListIterator it( mapDirs );
while ( it.hasNext() ) {
QString themeDir = it.next() + QLatin1Char('/');
QString themeDirName = QDir(themeDir).path().section(QLatin1Char('/'), -2, -1);
QStringList tmp = QDir( themeDir ).entryList( QStringList( "*.dgml" ),
QDir::Files | QDir::NoSymLinks );
if ( !tmp.isEmpty() ) {
QStringListIterator k( tmp );
while ( k.hasNext() ) {
QString themeXml = k.next();
mapFiles << themeDirName + QLatin1Char('/') + themeXml;
}
}
}
return mapFiles;
}
QStringList MapThemeManager::Private::findMapThemes()
{
QStringList mapFilesLocal = findMapThemes( MarbleDirs::localPath() );
QStringList mapFilesSystem = findMapThemes( MarbleDirs::systemPath() );
QStringList allMapFiles( mapFilesLocal );
allMapFiles << mapFilesSystem;
// remove duplicate entries
allMapFiles.sort();
for ( int i = 1; i < allMapFiles.size(); ++i ) {
if ( allMapFiles.at(i) == allMapFiles.at( i-1 ) ) {
allMapFiles.removeAt( i );
--i;
}
}
return allMapFiles;
}
QStandardItemModel* MapThemeManager::mapThemeModel()
{
if ( !d->m_isInitialized ) {
d->updateMapThemeModel();
d->m_isInitialized = true;
}
return &d->m_mapThemeModel;
}
QStandardItemModel *MapThemeManager::celestialBodiesModel()
{
if ( !d->m_isInitialized ) {
d->updateMapThemeModel();
d->m_isInitialized = true;
}
return &d->m_celestialList;
}
QList<QStandardItem *> MapThemeManager::Private::createMapThemeRow( QString const& mapThemeID )
{
QList<QStandardItem *> itemList;
QScopedPointer<GeoSceneDocument> mapTheme( loadMapThemeFile( mapThemeID ) );
if ( !mapTheme || !mapTheme->head()->visible() ) {
return itemList;
}
QPixmap themeIconPixmap;
QString relativePath = mapDirName + QLatin1Char('/')
+ mapTheme->head()->target() + QLatin1Char('/') + mapTheme->head()->theme() + QLatin1Char('/')
+ mapTheme->head()->icon()->pixmap();
themeIconPixmap.load( MarbleDirs::path( relativePath ) );
if ( themeIconPixmap.isNull() ) {
relativePath = "svg/application-x-marble-gray.png";
themeIconPixmap.load( MarbleDirs::path( relativePath ) );
}
else {
// Make sure we don't keep excessively large previews in memory
// TODO: Scale the icon down to the default icon size in MarbleSelectView.
// For now maxIconSize already equals what's expected by the listview.
QSize maxIconSize( 136, 136 );
if ( themeIconPixmap.size() != maxIconSize ) {
mDebug() << "Smooth scaling theme icon";
themeIconPixmap = themeIconPixmap.scaled( maxIconSize,
Qt::KeepAspectRatio,
Qt::SmoothTransformation );
}
}
QIcon mapThemeIcon = QIcon( themeIconPixmap );
QString name = mapTheme->head()->name();
const QString translatedDescription = QCoreApplication::translate("DGML", mapTheme->head()->description().toUtf8().constData());
const QString toolTip = QLatin1String("<span style=\" max-width: 150 px;\"> ") + translatedDescription + QLatin1String(" </span>");
QStandardItem *item = new QStandardItem( name );
item->setData(QCoreApplication::translate("DGML", name.toUtf8().constData()), Qt::DisplayRole);
item->setData( mapThemeIcon, Qt::DecorationRole );
item->setData(toolTip, Qt::ToolTipRole);
item->setData( mapThemeID, Qt::UserRole + 1 );
item->setData(translatedDescription, Qt::UserRole + 2);
itemList << item;
return itemList;
}
void MapThemeManager::Private::updateMapThemeModel()
{
mDebug() << "updateMapThemeModel";
m_mapThemeModel.clear();
m_mapThemeModel.setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));
QStringList stringlist = findMapThemes();
QStringListIterator it( stringlist );
while ( it.hasNext() ) {
QString mapThemeID = it.next();
QList<QStandardItem *> itemList = createMapThemeRow( mapThemeID );
if ( !itemList.empty() ) {
m_mapThemeModel.appendRow( itemList );
}
}
for ( const QString &mapThemeId: stringlist ) {
const QString celestialBodyId = mapThemeId.section(QLatin1Char('/'), 0, 0);
QString celestialBodyName = PlanetFactory::localizedName( celestialBodyId );
QList<QStandardItem*> matchingItems = m_celestialList.findItems( celestialBodyId, Qt::MatchExactly, 1 );
if ( matchingItems.isEmpty() ) {
m_celestialList.appendRow( QList<QStandardItem*>()
<< new QStandardItem( celestialBodyName )
<< new QStandardItem( celestialBodyId ) );
}
}
}
void MapThemeManager::Private::watchPaths()
{
QStringList const paths = pathsToWatch();
QStringList const files = m_fileSystemWatcher.files();
QStringList const directories = m_fileSystemWatcher.directories();
// Check each resource to add that it is not being watched already,
// otherwise some qWarning appears
for( const QString &resource: paths ) {
if ( !directories.contains( resource ) && !files.contains( resource ) ) {
m_fileSystemWatcher.addPath( resource );
}
}
}
void MapThemeManager::Private::directoryChanged( const QString& path )
{
mDebug() << "directoryChanged:" << path;
watchPaths();
mDebug() << "Emitting themesChanged()";
updateMapThemeModel();
emit q->themesChanged();
}
void MapThemeManager::Private::fileChanged( const QString& path )
{
mDebug() << "fileChanged:" << path;
// 1. if the file does not (anymore) exist, it got deleted and we
// have to delete the corresponding item from the model
// 2. if the file exists it is changed and we have to replace
// the item with a new one.
const QString mapThemeId = path.section(QLatin1Char('/'), -3);
mDebug() << "mapThemeId:" << mapThemeId;
QList<QStandardItem *> matchingItems = m_mapThemeModel.findItems( mapThemeId,
Qt::MatchFixedString
| Qt::MatchCaseSensitive,
columnRelativePath );
mDebug() << "matchingItems:" << matchingItems.size();
Q_ASSERT( matchingItems.size() <= 1 );
int insertAtRow = 0;
if ( matchingItems.size() == 1 ) {
const int row = matchingItems.front()->row();
insertAtRow = row;
QList<QStandardItem *> toBeDeleted = m_mapThemeModel.takeRow( row );
while ( !toBeDeleted.isEmpty() ) {
delete toBeDeleted.takeFirst();
}
}
QFileInfo fileInfo( path );
if ( fileInfo.exists() ) {
QList<QStandardItem *> newMapThemeRow = createMapThemeRow( mapThemeId );
if ( !newMapThemeRow.empty() ) {
m_mapThemeModel.insertRow( insertAtRow, newMapThemeRow );
}
}
emit q->themesChanged();
}
//
// <mapPathName>/<orbDirName>/<themeDirName>
//
void MapThemeManager::Private::addMapThemePaths( const QString& mapPathName, QStringList& result )
{
QDir mapPath( mapPathName );
QStringList orbDirNames = mapPath.entryList( QStringList( "*" ),
QDir::AllDirs
| QDir::NoSymLinks
| QDir::NoDotAndDotDot );
QStringListIterator itOrb( orbDirNames );
while ( itOrb.hasNext() ) {
const QString orbPathName = mapPathName + QLatin1Char('/') + itOrb.next();
result << orbPathName;
QDir orbPath( orbPathName );
QStringList themeDirNames = orbPath.entryList( QStringList( "*" ),
QDir::AllDirs
| QDir::NoSymLinks
| QDir::NoDotAndDotDot );
QStringListIterator itThemeDir( themeDirNames );
while ( itThemeDir.hasNext() ) {
const QString themePathName = orbPathName + QLatin1Char('/') + itThemeDir.next();
result << themePathName;
QDir themePath( themePathName );
QStringList themeFileNames = themePath.entryList( QStringList( "*.dgml" ),
QDir::Files
| QDir::NoSymLinks );
QStringListIterator itThemeFile( themeFileNames );
while ( itThemeFile.hasNext() ) {
const QString themeFilePathName = themePathName + QLatin1Char('/') + itThemeFile.next();
result << themeFilePathName;
}
}
}
}
GeoSceneDocument *MapThemeManager::createMapThemeFromOverlay( const GeoDataPhotoOverlay *overlayData )
{
GeoSceneDocument * document = new GeoSceneDocument();
document->head()->setDescription( overlayData->description() );
document->head()->setName( overlayData->name() );
document->head()->setTheme( "photo" );
document->head()->setTarget( "panorama" );
document->head()->setRadius(36000);
document->head()->setVisible(true);
document->head()->zoom()->setMaximum(3500);
document->head()->zoom()->setMinimum(900);
document->head()->zoom()->setDiscrete(false);
GeoSceneLayer * layer = new GeoSceneLayer( "photo" );
layer->setBackend("texture");
GeoSceneTextureTileDataset * texture = new GeoSceneTextureTileDataset( "map" );
texture->setExpire(std::numeric_limits<int>::max());
QString fileName = overlayData->absoluteIconFile();
QFileInfo fileInfo( fileName );
fileName = fileInfo.fileName();
QString sourceDir = fileInfo.absoluteDir().path();
QString extension = fileInfo.suffix();
texture->setSourceDir( sourceDir );
texture->setFileFormat( extension );
texture->setInstallMap( fileName );
texture->setTileProjection(GeoSceneAbstractTileProjection::Equirectangular);
layer->addDataset(texture);
document->map()->addLayer(layer);
GeoSceneSettings *settings = document->settings();
GeoSceneProperty *gridProperty = new GeoSceneProperty( "coordinate-grid" );
gridProperty->setValue( false );
gridProperty->setAvailable( false );
settings->addProperty( gridProperty );
GeoSceneProperty *overviewmap = new GeoSceneProperty( "overviewmap" );
overviewmap->setValue( false );
overviewmap->setAvailable( false );
settings->addProperty( overviewmap );
GeoSceneProperty *compass = new GeoSceneProperty( "compass" );
compass->setValue( false );
compass->setAvailable( false );
settings->addProperty( compass );
GeoSceneProperty *scalebar = new GeoSceneProperty( "scalebar" );
scalebar->setValue( true );
scalebar->setAvailable( true );
settings->addProperty( scalebar );
return document;
}
}
#include "moc_MapThemeManager.cpp"
diff --git a/src/lib/marble/MapThemeManager.h b/src/lib/marble/MapThemeManager.h
index 51d8826cb..3cffd7e8a 100644
--- a/src/lib/marble/MapThemeManager.h
+++ b/src/lib/marble/MapThemeManager.h
@@ -1,115 +1,115 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2008 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
//
#ifndef MARBLE_MAPTHEMEMANAGER_H
#define MARBLE_MAPTHEMEMANAGER_H
#include <QObject>
#include "marble_export.h"
class QStandardItemModel;
class QString;
class QStringList;
namespace Marble
{
class GeoSceneDocument;
class GeoDataPhotoOverlay;
/**
* @short The class that handles map themes that are locally available .
*
* This class which is able to check for maps that are locally available.
* After parsing the data it only stores the name, description and path
* into a QStandardItemModel.
*
* The MapThemeManager is not owned by the MarbleWidget/Map itself.
* Instead it is owned by the widget or application that contains
* MarbleWidget/Map ( usually: the ControlView convenience class )
*
* For convenience MarbleThemeManager provides a static helper class
* that loads the properties of a map theme into a GeoSceneDocument
* object.
*
* @see GeoSceneDocument
*/
class MARBLE_EXPORT MapThemeManager : public QObject
{
Q_OBJECT
public:
- explicit MapThemeManager(QObject *parent = 0);
+ explicit MapThemeManager(QObject *parent = nullptr);
~MapThemeManager() override;
/**
* @brief Returns a list of all locally available map theme IDs
*/
QStringList mapThemeIds() const;
/**
* @brief Provides a model of the locally existing themes.
*
* This method provides a QStandardItemModel of all themes
* that are available via MarbleDirs.
*/
QStandardItemModel* mapThemeModel();
/**
* @brief Provides a model of all installed planets.
*/
QStandardItemModel *celestialBodiesModel();
/**
* @brief Returns the map theme as a GeoSceneDocument object
* @param mapThemeStringID the string ID that refers to the map theme
*
* This helper method should only get used by MarbleModel to load the
* current theme into memory or by the MapThemeManager.
*/
static GeoSceneDocument* loadMapTheme( const QString& mapThemeStringID );
/**
* @brief Returns a map as a GeoSceneDocument object created from a GeoDataPhotoOverlay
*/
static GeoSceneDocument* createMapThemeFromOverlay( const GeoDataPhotoOverlay *overlayData );
/**
* @brief Deletes the map theme with the specified map theme ID.
* @param mapThemeId ID of the map theme to be deleted
*
* Deletion will only succeed for local map themes, that is, if the map
* theme's directory structure resides in the user's home directory.
*/
static void deleteMapTheme( const QString &mapThemeId );
Q_SIGNALS:
/**
* @brief This signal will be emitted, when the themes change.
*/
void themesChanged();
private:
Q_PRIVATE_SLOT( d, void directoryChanged( const QString& path ) )
Q_PRIVATE_SLOT( d, void fileChanged( const QString & path ) )
Q_DISABLE_COPY( MapThemeManager )
class Private;
friend class Private;
Private * const d;
};
}
#endif
diff --git a/src/lib/marble/MapThemeSortFilterProxyModel.h b/src/lib/marble/MapThemeSortFilterProxyModel.h
index 794fff86b..6aceef5f5 100644
--- a/src/lib/marble/MapThemeSortFilterProxyModel.h
+++ b/src/lib/marble/MapThemeSortFilterProxyModel.h
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Claudiu Covaci <claudiu.covaci@gmail.com>
// Copyright 2009 Torsten Rahn <tackat@kde.org>
//
#ifndef MARBLE_MAPTHEMESORTFILTERPROXYMODEL_H
#define MARBLE_MAPTHEMESORTFILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
class QDateTime;
namespace Marble
{
class MapThemeSortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
- explicit MapThemeSortFilterProxyModel(QObject *parent = 0);
+ explicit MapThemeSortFilterProxyModel(QObject *parent = nullptr);
protected:
bool lessThan( const QModelIndex &left, const QModelIndex &right ) const override;
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
private:
static bool isFavorite( const QModelIndex& index );
static QDateTime favoriteDateTime( const QModelIndex& index );
};
}
#endif
diff --git a/src/lib/marble/MapViewWidget.cpp b/src/lib/marble/MapViewWidget.cpp
index 626875e6e..3ab399a5f 100644
--- a/src/lib/marble/MapViewWidget.cpp
+++ b/src/lib/marble/MapViewWidget.cpp
@@ -1,710 +1,710 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2007 Thomas Zander <zander@kde.org>
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
// Coprright 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
// Self
#include "MapViewWidget.h"
// Marble
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MapThemeManager.h"
#include "MapThemeSortFilterProxyModel.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "MapViewItemDelegate.h"
#include "CelestialSortFilterProxyModel.h"
// Qt
#include <QResizeEvent>
#include <QFileInfo>
#include <QSettings>
#include <QMenu>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QGridLayout>
#include <QPainter>
#include <QToolBar>
#include <QToolButton>
#include <QDateTime>
using namespace Marble;
// Ui
#include "ui_MapViewWidget.h"
namespace Marble
{
class Q_DECL_HIDDEN MapViewWidget::Private {
public:
Private( MapViewWidget *parent )
: q( parent ),
- m_marbleModel( 0 ),
+ m_marbleModel( nullptr ),
m_mapSortProxy(),
m_celestialListProxy(),
- m_toolBar( 0 ),
- m_globeViewButton( 0 ),
- m_mercatorViewButton( 0 ),
- m_popupMenuFlat( 0 ),
- m_flatViewAction( 0 ),
- m_mercatorViewAction( 0 ),
- m_celestialBodyAction( 0 ),
- m_gnomonicViewAction( 0 ),
- m_stereographicViewAction( 0 ),
- m_lambertAzimuthalViewAction( 0 ),
- m_azimuthalEquidistantViewAction( 0 ),
- m_verticalPerspectiveViewAction( 0 ),
- m_globeViewAction( 0 ),
+ m_toolBar( nullptr ),
+ m_globeViewButton( nullptr ),
+ m_mercatorViewButton( nullptr ),
+ m_popupMenuFlat( nullptr ),
+ m_flatViewAction( nullptr ),
+ m_mercatorViewAction( nullptr ),
+ m_celestialBodyAction( nullptr ),
+ m_gnomonicViewAction( nullptr ),
+ m_stereographicViewAction( nullptr ),
+ m_lambertAzimuthalViewAction( nullptr ),
+ m_azimuthalEquidistantViewAction( nullptr ),
+ m_verticalPerspectiveViewAction( nullptr ),
+ m_globeViewAction( nullptr ),
m_mapViewDelegate(nullptr)
{
m_mapSortProxy.setDynamicSortFilter( true );
m_celestialListProxy.setDynamicSortFilter( true );
}
~Private()
{
delete m_mapViewDelegate;
}
void applyExtendedLayout()
{
m_mapViewUi.projectionLabel_2->setVisible(true);
m_mapViewUi.celestialBodyLabel->setVisible(true);
m_mapViewUi.projectionComboBox->setVisible(true);
m_mapViewUi.mapThemeLabel->setVisible(true);
m_mapViewUi.line->setVisible(true);
m_toolBar->setVisible(false);
const int labelId = m_mapViewUi.verticalLayout->indexOf(m_mapViewUi.celestialBodyLabel);
m_mapViewUi.verticalLayout->insertWidget(labelId+1, m_mapViewUi.celestialBodyComboBox);
m_toolBar->removeAction(m_celestialBodyAction);
m_mapViewUi.celestialBodyComboBox->show();
}
void applyReducedLayout()
{
m_mapViewUi.projectionLabel_2->setVisible(false);
m_mapViewUi.celestialBodyLabel->setVisible(false);
m_mapViewUi.projectionComboBox->setVisible(false);
m_mapViewUi.mapThemeLabel->setVisible(false);
m_mapViewUi.line->setVisible(false);
m_toolBar->setVisible(true);
m_celestialBodyAction = m_toolBar->addWidget(m_mapViewUi.celestialBodyComboBox);
m_mapViewUi.verticalLayout->removeWidget(m_mapViewUi.celestialBodyComboBox);
m_mapViewUi.celestialBodyComboBox->show();
}
void setupToolBar()
{
m_toolBar = new QToolBar;
m_globeViewButton = new QToolButton;
m_globeViewButton->setIcon(QIcon(QStringLiteral(":/icons/map-globe.png")));
m_globeViewButton->setToolTip( tr("Globe View") );
m_globeViewButton->setCheckable(true);
m_globeViewButton->setChecked(false);
m_globeViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
tr( "Spherical view" ),
m_globeViewButton );
m_globeViewAction->setCheckable( true );
m_globeViewAction->setChecked( false );
m_mercatorViewButton = new QToolButton;
m_mercatorViewButton->setIcon(QIcon(QStringLiteral(":/icons/map-mercator.png")));
m_mercatorViewButton->setToolTip( tr("Mercator View") );
m_mercatorViewButton->setCheckable(true);
m_mercatorViewButton->setChecked(false);
m_mercatorViewButton->setPopupMode(QToolButton::MenuButtonPopup);
m_popupMenuFlat = new QMenu(q);
m_mercatorViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-mercator.png")),
tr("Mercator View"),
m_popupMenuFlat );
m_mercatorViewAction->setCheckable(true);
m_mercatorViewAction->setChecked(false);
m_flatViewAction = new QAction( QIcon(QStringLiteral(":/icons/map-flat.png")),
tr("Flat View"),
m_popupMenuFlat );
m_flatViewAction->setCheckable(true);
m_flatViewAction->setChecked(false);
m_gnomonicViewAction = new QAction( QIcon(QStringLiteral(":/icons/map-gnomonic.png")),
tr( "Gnomonic view" ),
m_popupMenuFlat);
m_gnomonicViewAction->setCheckable( true );
m_gnomonicViewAction->setChecked( false );
m_stereographicViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
tr( "Stereographic view" ),
m_popupMenuFlat);
m_stereographicViewAction->setCheckable( true );
m_stereographicViewAction->setChecked( false );
m_lambertAzimuthalViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
tr( "Lambert Azimuthal Equal-Area view" ),
m_popupMenuFlat);
m_lambertAzimuthalViewAction->setCheckable( true );
m_lambertAzimuthalViewAction->setChecked( false );
m_azimuthalEquidistantViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
tr( "Azimuthal Equidistant view" ),
m_popupMenuFlat);
m_azimuthalEquidistantViewAction->setCheckable( true );
m_azimuthalEquidistantViewAction->setChecked( false );
m_verticalPerspectiveViewAction = new QAction(QIcon(QStringLiteral(":/icons/map-globe.png")),
tr( "Perspective Globe view" ),
m_popupMenuFlat);
m_verticalPerspectiveViewAction->setCheckable( true );
m_verticalPerspectiveViewAction->setChecked( false );
m_popupMenuFlat->addAction(m_mercatorViewAction);
m_popupMenuFlat->addAction(m_flatViewAction);
m_popupMenuFlat->addAction(m_gnomonicViewAction);
m_popupMenuFlat->addAction(m_stereographicViewAction);
m_popupMenuFlat->addAction(m_lambertAzimuthalViewAction);
m_popupMenuFlat->addAction(m_azimuthalEquidistantViewAction);
m_popupMenuFlat->addAction(m_verticalPerspectiveViewAction);
m_mercatorViewButton->setMenu(m_popupMenuFlat);
m_toolBar->addWidget(m_globeViewButton);
m_toolBar->addWidget(m_mercatorViewButton);
m_toolBar->addSeparator();
m_toolBar->setContentsMargins(0,0,0,0);
m_toolBar->setIconSize(QSize(16, 16));
m_mapViewUi.toolBarLayout->insertWidget(0, m_toolBar);
QObject::connect(m_globeViewButton, SIGNAL(clicked()),
q, SLOT(globeViewRequested()));
QObject::connect(m_mercatorViewButton, SIGNAL(clicked()),
q, SLOT(mercatorViewRequested()));
QObject::connect(m_mercatorViewAction, SIGNAL(triggered()),
q, SLOT(mercatorViewRequested()));
QObject::connect(m_flatViewAction, SIGNAL(triggered()),
q, SLOT(flatViewRequested()));
QObject::connect(m_gnomonicViewAction, SIGNAL(triggered()),
q, SLOT(gnomonicViewRequested()));
QObject::connect(m_stereographicViewAction, SIGNAL(triggered()),
q, SLOT(stereographicViewRequested()));
QObject::connect(m_lambertAzimuthalViewAction, SIGNAL(triggered()),
q, SLOT(lambertAzimuthalViewRequested()));
QObject::connect(m_azimuthalEquidistantViewAction, SIGNAL(triggered()),
q, SLOT(azimuthalEquidistantViewRequested()));
QObject::connect(m_verticalPerspectiveViewAction, SIGNAL(triggered()),
q, SLOT(verticalPerspectiveViewRequested()));
QObject::connect(m_globeViewAction, SIGNAL(triggered()),
q, SLOT(globeViewRequested()));
applyReducedLayout();
}
void updateMapFilter()
{
int currentIndex = m_mapViewUi.celestialBodyComboBox->currentIndex();
const QString selectedId = m_celestialListProxy.data( m_celestialListProxy.index( currentIndex, 1 ) ).toString();
if ( !selectedId.isEmpty() ) {
m_mapSortProxy.setFilterRegExp( QRegExp( selectedId, Qt::CaseInsensitive,QRegExp::FixedString ) );
}
}
void celestialBodySelected( int comboIndex );
void projectionSelected( int projectionIndex );
void mapThemeSelected( QModelIndex index );
void mapThemeSelected( int index );
void showContextMenu( const QPoint& pos );
void deleteMap();
void toggleFavorite();
void toggleIconSize();
bool isCurrentFavorite() const;
QString currentThemeName() const;
QString currentThemePath() const;
QString favoriteKey(const QModelIndex &index) const;
MapViewWidget *const q;
Ui::MapViewWidget m_mapViewUi;
MarbleModel *m_marbleModel;
MapThemeSortFilterProxyModel m_mapSortProxy;
CelestialSortFilterProxyModel m_celestialListProxy;
QSettings m_settings;
QToolBar *m_toolBar;
QToolButton *m_globeViewButton;
QToolButton *m_mercatorViewButton;
QMenu *m_popupMenuFlat;
QAction *m_flatViewAction;
QAction *m_mercatorViewAction;
QAction *m_celestialBodyAction;
QAction *m_gnomonicViewAction;
QAction *m_stereographicViewAction;
QAction *m_lambertAzimuthalViewAction;
QAction *m_azimuthalEquidistantViewAction;
QAction *m_verticalPerspectiveViewAction;
QAction *m_globeViewAction;
MapViewItemDelegate* m_mapViewDelegate;
};
MapViewWidget::MapViewWidget( QWidget *parent, Qt::WindowFlags f )
: QWidget( parent, f ),
d( new Private( this ) )
{
d->m_mapViewUi.setupUi( this );
layout()->setMargin( 0 );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
QGridLayout* layout = new QGridLayout;
layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 1 ), 0, 0 );
layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 1 ), 0, 1 );
d->m_mapViewUi.line->setVisible( false );
layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 2 ), 1, 0 );
layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 2 ), 1, 1 );
layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 3 ), 2, 0 );
layout->addItem( d->m_mapViewUi.verticalLayout->takeAt( 4 ), 2, 1 );
d->m_mapViewUi.verticalLayout->insertLayout( 0, layout );
d->m_mapViewUi.mapThemeComboBox->setModel( &d->m_mapSortProxy );
d->m_mapViewUi.mapThemeComboBox->setIconSize( QSize( 48, 48 ) );
connect( d->m_mapViewUi.mapThemeComboBox, SIGNAL(activated(int)),
this, SLOT(mapThemeSelected(int)) );
d->m_mapViewUi.marbleThemeSelectView->setVisible( false );
}
else {
d->m_mapViewUi.marbleThemeSelectView->setViewMode( QListView::IconMode );
QSize const iconSize = d->m_settings.value(QStringLiteral("MapView/iconSize"), QSize(90, 90)).toSize();
d->m_mapViewUi.marbleThemeSelectView->setIconSize( iconSize );
delete d->m_mapViewDelegate;
d->m_mapViewDelegate = new MapViewItemDelegate(d->m_mapViewUi.marbleThemeSelectView);
d->m_mapViewUi.marbleThemeSelectView->setItemDelegate(d->m_mapViewDelegate);
d->m_mapViewUi.marbleThemeSelectView->setAlternatingRowColors( true );
d->m_mapViewUi.marbleThemeSelectView->setFlow( QListView::LeftToRight );
d->m_mapViewUi.marbleThemeSelectView->setWrapping( true );
d->m_mapViewUi.marbleThemeSelectView->setResizeMode( QListView::Adjust );
d->m_mapViewUi.marbleThemeSelectView->setUniformItemSizes( true );
d->m_mapViewUi.marbleThemeSelectView->setMovement( QListView::Static );
d->m_mapViewUi.marbleThemeSelectView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
d->m_mapViewUi.marbleThemeSelectView->setEditTriggers( QListView::NoEditTriggers );
d->m_mapViewUi.marbleThemeSelectView->setSelectionMode( QListView::SingleSelection );
d->m_mapViewUi.marbleThemeSelectView->setModel( &d->m_mapSortProxy );
connect( d->m_mapViewUi.marbleThemeSelectView, SIGNAL(pressed(QModelIndex)),
this, SLOT(mapThemeSelected(QModelIndex)) );
connect( d->m_mapViewUi.marbleThemeSelectView, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(showContextMenu(QPoint)) );
d->m_mapViewUi.mapThemeComboBox->setVisible( false );
d->setupToolBar();
}
connect( d->m_mapViewUi.projectionComboBox, SIGNAL(activated(int)),
this, SLOT(projectionSelected(int)) );
d->m_mapViewUi.projectionComboBox->setEnabled( true );
d->m_mapViewUi.celestialBodyComboBox->setModel( &d->m_celestialListProxy );
connect( d->m_mapViewUi.celestialBodyComboBox, SIGNAL(activated(int)),
this, SLOT(celestialBodySelected(int)) );
d->m_settings.beginGroup(QStringLiteral("Favorites"));
if (!d->m_settings.contains(QStringLiteral("initialized"))) {
d->m_settings.setValue(QStringLiteral("initialized"), true);
QDateTime currentDateTime = QDateTime::currentDateTime();
d->m_settings.setValue(QStringLiteral("Atlas"), currentDateTime);
d->m_settings.setValue(QStringLiteral("OpenStreetMap"), currentDateTime);
d->m_settings.setValue(QStringLiteral("Satellite View"), currentDateTime);
}
d->m_settings.endGroup();
}
MapViewWidget::~MapViewWidget()
{
delete d;
}
void MapViewWidget::setMarbleWidget( MarbleWidget *widget, MapThemeManager *mapThemeManager )
{
d->m_marbleModel = widget->model();
d->m_mapSortProxy.setSourceModel( mapThemeManager->mapThemeModel() );
d->m_mapSortProxy.sort( 0 );
d->m_celestialListProxy.setSourceModel( mapThemeManager->celestialBodiesModel() );
d->m_celestialListProxy.sort( 0 );
connect( this, SIGNAL(projectionChanged(Projection)),
widget, SLOT(setProjection(Projection)) );
connect( widget, SIGNAL(themeChanged(QString)),
this, SLOT(setMapThemeId(QString)) );
connect( widget, SIGNAL(projectionChanged(Projection)),
this, SLOT(setProjection(Projection)) );
connect( this, SIGNAL(mapThemeIdChanged(QString)),
widget, SLOT(setMapThemeId(QString)) );
setProjection(widget->projection());
setMapThemeId(widget->mapThemeId());
}
void MapViewWidget::resizeEvent(QResizeEvent *event)
{
if (!d->m_toolBar)
return;
if (d->m_toolBar->isVisible() && event->size().height() > 400) {
d->applyExtendedLayout();
} else if (!d->m_toolBar->isVisible() && event->size().height() <= 400) {
d->applyReducedLayout();
}
}
void MapViewWidget::setMapThemeId( const QString &themeId )
{
const bool smallscreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
const int currentRow = smallscreen ? d->m_mapViewUi.mapThemeComboBox->currentIndex() :
d->m_mapViewUi.marbleThemeSelectView->currentIndex().row();
const QString oldThemeId = d->m_mapSortProxy.data( d->m_mapSortProxy.index( currentRow, 0 ), Qt::UserRole + 1 ).toString();
// Check if the new selected theme is different from the current one
if ( themeId == oldThemeId )
return;
const QString oldCelestialBodyId = oldThemeId.section(QLatin1Char('/'), 0, 0);
const QString celestialBodyId = themeId.section(QLatin1Char('/'), 0, 0);
// select celestialBodyId in GUI
if ( celestialBodyId != oldCelestialBodyId ) {
for ( int row = 0; row < d->m_celestialListProxy.rowCount(); ++row ) {
if ( d->m_celestialListProxy.data( d->m_celestialListProxy.index( row, 1 ) ).toString() == celestialBodyId ) {
d->m_mapViewUi.celestialBodyComboBox->setCurrentIndex( row );
break;
}
}
d->updateMapFilter();
}
// select themeId in GUI
for ( int row = 0; row < d->m_mapSortProxy.rowCount(); ++row ) {
if( d->m_mapSortProxy.data( d->m_mapSortProxy.index( row, 0 ), Qt::UserRole + 1 ).toString() == themeId ) {
if ( smallscreen ) {
d->m_mapViewUi.mapThemeComboBox->setCurrentIndex( row );
}
else {
const QModelIndex index = d->m_mapSortProxy.index( row, 0 );
d->m_mapViewUi.marbleThemeSelectView->setCurrentIndex( index );
d->m_mapViewUi.marbleThemeSelectView->scrollTo( index );
}
break;
}
}
}
void MapViewWidget::setProjection( Projection projection )
{
if ( (int)projection != d->m_mapViewUi.projectionComboBox->currentIndex() )
d->m_mapViewUi.projectionComboBox->setCurrentIndex( (int) projection );
if (d->m_toolBar) {
switch (projection) {
case Marble::Spherical:
d->m_globeViewButton->setChecked(true);
d->m_globeViewAction->setChecked(true);
d->m_mercatorViewButton->setChecked(false);
d->m_mercatorViewAction->setChecked(false);
d->m_flatViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(false);
d->m_lambertAzimuthalViewAction->setChecked(false);
d->m_azimuthalEquidistantViewAction->setChecked(false);
d->m_verticalPerspectiveViewAction->setChecked(false);
break;
case Marble::Mercator:
d->m_mercatorViewButton->setChecked(true);
d->m_mercatorViewAction->setChecked(true);
d->m_globeViewButton->setChecked(false);
d->m_flatViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(false);
d->m_globeViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(false);
d->m_lambertAzimuthalViewAction->setChecked(false);
d->m_azimuthalEquidistantViewAction->setChecked(false);
d->m_verticalPerspectiveViewAction->setChecked(false);
break;
case Marble::Equirectangular:
d->m_flatViewAction->setChecked(true);
d->m_mercatorViewButton->setChecked(true);
d->m_globeViewButton->setChecked(false);
d->m_mercatorViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(false);
d->m_globeViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(false);
d->m_lambertAzimuthalViewAction->setChecked(false);
d->m_azimuthalEquidistantViewAction->setChecked(false);
d->m_verticalPerspectiveViewAction->setChecked(false);
break;
case Marble::Gnomonic:
d->m_flatViewAction->setChecked(false);
d->m_mercatorViewButton->setChecked(true);
d->m_globeViewButton->setChecked(false);
d->m_mercatorViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(true);
d->m_globeViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(false);
d->m_lambertAzimuthalViewAction->setChecked(false);
d->m_azimuthalEquidistantViewAction->setChecked(false);
d->m_verticalPerspectiveViewAction->setChecked(false);
break;
case Marble::Stereographic:
d->m_flatViewAction->setChecked(false);
d->m_mercatorViewButton->setChecked(true);
d->m_globeViewButton->setChecked(false);
d->m_mercatorViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(false);
d->m_globeViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(true);
d->m_lambertAzimuthalViewAction->setChecked(false);
d->m_azimuthalEquidistantViewAction->setChecked(false);
d->m_verticalPerspectiveViewAction->setChecked(false);
break;
case Marble::LambertAzimuthal:
d->m_flatViewAction->setChecked(false);
d->m_mercatorViewButton->setChecked(true);
d->m_globeViewButton->setChecked(false);
d->m_mercatorViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(false);
d->m_globeViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(false);
d->m_lambertAzimuthalViewAction->setChecked(true);
d->m_azimuthalEquidistantViewAction->setChecked(false);
d->m_verticalPerspectiveViewAction->setChecked(false);
break;
case Marble::AzimuthalEquidistant:
d->m_flatViewAction->setChecked(false);
d->m_mercatorViewButton->setChecked(true);
d->m_globeViewButton->setChecked(false);
d->m_mercatorViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(false);
d->m_globeViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(false);
d->m_lambertAzimuthalViewAction->setChecked(false);
d->m_azimuthalEquidistantViewAction->setChecked(true);
d->m_verticalPerspectiveViewAction->setChecked(false);
break;
case Marble::VerticalPerspective:
d->m_flatViewAction->setChecked(false);
d->m_mercatorViewButton->setChecked(true);
d->m_globeViewButton->setChecked(false);
d->m_mercatorViewAction->setChecked(false);
d->m_gnomonicViewAction->setChecked(false);
d->m_globeViewAction->setChecked(false);
d->m_stereographicViewAction->setChecked(false);
d->m_lambertAzimuthalViewAction->setChecked(false);
d->m_azimuthalEquidistantViewAction->setChecked(false);
d->m_verticalPerspectiveViewAction->setChecked(true);
break;
}
}
}
void MapViewWidget::globeViewRequested()
{
emit projectionChanged(Marble::Spherical);
}
void MapViewWidget::flatViewRequested()
{
emit projectionChanged(Marble::Equirectangular);
}
void MapViewWidget::mercatorViewRequested()
{
emit projectionChanged(Marble::Mercator);
}
void MapViewWidget::gnomonicViewRequested()
{
emit projectionChanged(Marble::Gnomonic);
}
void MapViewWidget::stereographicViewRequested()
{
emit projectionChanged(Marble::Stereographic);
}
void MapViewWidget::lambertAzimuthalViewRequested()
{
emit projectionChanged(Marble::LambertAzimuthal);
}
void MapViewWidget::azimuthalEquidistantViewRequested()
{
emit projectionChanged(Marble::AzimuthalEquidistant);
}
void MapViewWidget::verticalPerspectiveViewRequested()
{
emit projectionChanged(Marble::VerticalPerspective);
}
void MapViewWidget::Private::celestialBodySelected( int comboIndex )
{
Q_UNUSED( comboIndex )
updateMapFilter();
bool foundMapTheme = false;
QString currentMapThemeId = m_marbleModel->mapThemeId();
QString oldPlanetId = m_marbleModel->planetId();
int row = m_mapSortProxy.rowCount();
for ( int i = 0; i < row; ++i )
{
QModelIndex index = m_mapSortProxy.index(i,0);
QString itMapThemeId = m_mapSortProxy.data(index, Qt::UserRole + 1).toString();
if ( currentMapThemeId == itMapThemeId )
{
foundMapTheme = true;
break;
}
}
if ( !foundMapTheme ) {
QModelIndex index = m_mapSortProxy.index(0,0);
emit q->mapThemeIdChanged( m_mapSortProxy.data( index, Qt::UserRole + 1 ).toString() );
}
if( oldPlanetId != m_marbleModel->planetId() ) {
emit q->celestialBodyChanged( m_marbleModel->planetId() );
}
}
// Relay a signal and convert the parameter from an int to a Projection.
void MapViewWidget::Private::projectionSelected( int projectionIndex )
{
emit q->projectionChanged( (Projection) projectionIndex );
}
void MapViewWidget::Private::mapThemeSelected( QModelIndex index )
{
mapThemeSelected( index.row() );
}
void MapViewWidget::Private::mapThemeSelected( int index )
{
const QModelIndex columnIndex = m_mapSortProxy.index( index, 0 );
const QString currentmaptheme = m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
mDebug() << Q_FUNC_INFO << currentmaptheme;
emit q->mapThemeIdChanged( currentmaptheme );
}
QString MapViewWidget::Private::currentThemeName() const
{
const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0, QModelIndex() );
return m_mapSortProxy.data( columnIndex ).toString();
}
QString MapViewWidget::Private::currentThemePath() const
{
const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
const QModelIndex columnIndex = m_mapSortProxy.index( index.row(), 0 );
return m_mapSortProxy.data( columnIndex, Qt::UserRole + 1 ).toString();
}
QString MapViewWidget::Private::favoriteKey(const QModelIndex &index) const
{
return QLatin1String("Favorites/") + m_mapSortProxy.data(index).toString();
}
void MapViewWidget::Private::showContextMenu( const QPoint& pos )
{
QMenu menu;
QAction* iconSizeAction = menu.addAction( tr( "&Show Large Icons" ), q, SLOT(toggleIconSize()) );
iconSizeAction->setCheckable( true );
iconSizeAction->setChecked( m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 ) );
QAction *favAction = menu.addAction(QIcon(QStringLiteral(":/icons/bookmarks.png")), tr("&Favorite"), q, SLOT(toggleFavorite()));
favAction->setCheckable( true );
favAction->setChecked( isCurrentFavorite() );
menu.addSeparator();
menu.addAction(QIcon(QStringLiteral(":/icons/create-new-map.png")), tr("&Create a New Map..."), q, SIGNAL(showMapWizard()));
if (QFileInfo(MarbleDirs::localPath() + QLatin1String("/maps/") + currentThemePath()).exists()) {
menu.addAction( tr( "&Delete Map Theme" ), q, SLOT(deleteMap()) );
}
menu.addAction( tr( "&Upload Map..." ), q, SIGNAL(showUploadDialog()) );
menu.exec( m_mapViewUi.marbleThemeSelectView->mapToGlobal( pos ) );
}
void MapViewWidget::Private::deleteMap()
{
if(QMessageBox::warning( q,
tr( "Marble" ),
tr( "Are you sure that you want to delete \"%1\"?" ).arg( currentThemeName() ),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes )
{
MapThemeManager::deleteMapTheme( currentThemePath() );
emit q->mapThemeDeleted();
}
}
void MapViewWidget::Private::toggleFavorite()
{
QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
if( isCurrentFavorite() ) {
m_settings.remove(favoriteKey(index));
} else {
m_settings.setValue(favoriteKey(index), QDateTime::currentDateTime() );
}
QStandardItemModel* sourceModel = qobject_cast<QStandardItemModel*>(m_mapSortProxy.sourceModel());
const QModelIndex sourceIndex = m_mapSortProxy.mapToSource(index);
emit sourceModel->dataChanged( sourceIndex, sourceIndex );
index = m_mapViewUi.marbleThemeSelectView->currentIndex();
m_mapViewUi.marbleThemeSelectView->scrollTo(index);
}
void MapViewWidget::Private::toggleIconSize()
{
bool const isLarge = m_mapViewUi.marbleThemeSelectView->iconSize() == QSize( 96, 96 );
int const size = isLarge ? 52 : 96;
m_mapViewUi.marbleThemeSelectView->setIconSize( QSize( size, size ) );
m_settings.setValue(QStringLiteral("MapView/iconSize"), m_mapViewUi.marbleThemeSelectView->iconSize() );
}
bool MapViewWidget::Private::isCurrentFavorite() const
{
const QModelIndex index = m_mapViewUi.marbleThemeSelectView->currentIndex();
return m_settings.contains(favoriteKey(index));
}
}
#include "moc_MapViewWidget.cpp"
diff --git a/src/lib/marble/MapViewWidget.h b/src/lib/marble/MapViewWidget.h
index b2701bcce..ef1868385 100644
--- a/src/lib/marble/MapViewWidget.h
+++ b/src/lib/marble/MapViewWidget.h
@@ -1,91 +1,91 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2007 Thomas Zander <zander@kde.org>
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_MAPVIEWWIDGET_H
#define MARBLE_MAPVIEWWIDGET_H
// Marble
#include "MarbleGlobal.h"
#include "marble_export.h"
// Qt
#include <QWidget>
namespace Marble
{
class MapThemeManager;
class MarbleWidget;
class MARBLE_EXPORT MapViewWidget : public QWidget
{
Q_OBJECT
public:
- explicit MapViewWidget( QWidget *parent = 0, Qt::WindowFlags f = 0 );
+ explicit MapViewWidget( QWidget *parent = nullptr, Qt::WindowFlags f = nullptr );
~MapViewWidget() override;
/**
* @brief Set a MarbleWidget associated to this widget.
* @param widget the MarbleWidget to be set.
*/
void setMarbleWidget( MarbleWidget *widget, MapThemeManager *mapThemeManager );
protected:
void resizeEvent(QResizeEvent *event) override;
public Q_SLOTS:
void setMapThemeId( const QString & );
void setProjection( Projection projection );
private Q_SLOTS:
void globeViewRequested();
void mercatorViewRequested();
void flatViewRequested();
void gnomonicViewRequested();
void stereographicViewRequested();
void lambertAzimuthalViewRequested();
void azimuthalEquidistantViewRequested();
void verticalPerspectiveViewRequested();
private:
Q_PRIVATE_SLOT( d, void celestialBodySelected( int comboIndex ) )
Q_PRIVATE_SLOT( d, void projectionSelected( int projectionIndex ) )
Q_PRIVATE_SLOT( d, void mapThemeSelected( QModelIndex index ) )
Q_PRIVATE_SLOT( d, void mapThemeSelected( int index ) )
Q_PRIVATE_SLOT( d, void showContextMenu( const QPoint& pos ) )
Q_PRIVATE_SLOT( d, void deleteMap() )
Q_PRIVATE_SLOT( d, void toggleFavorite() )
Q_PRIVATE_SLOT( d, void toggleIconSize() )
Q_SIGNALS:
void celestialBodyChanged( const QString& );
void mapThemeIdChanged( const QString& );
void projectionChanged( Projection );
void showMapWizard();
void showUploadDialog();
void mapThemeDeleted();
private:
Q_DISABLE_COPY( MapViewWidget )
friend class Private;
class Private;
Private * const d;
};
}
#endif
diff --git a/src/lib/marble/MapWizard.h b/src/lib/marble/MapWizard.h
index f2f6db4ec..b433fa7d6 100644
--- a/src/lib/marble/MapWizard.h
+++ b/src/lib/marble/MapWizard.h
@@ -1,87 +1,87 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Utku Aydın <utkuaydin34@gmail.com>
//
#ifndef MARBLE_MAPWIZARD_H
#define MARBLE_MAPWIZARD_H
#include <QWizard>
#include "marble_export.h"
/**
* @file
* This file contains the header for MapWizard
* @author Utku Aydın <utkuaydin34@gmail.com>
*/
class QNetworkReply;
namespace Marble {
class GeoSceneDocument;
class MapWizardPrivate;
class MARBLE_EXPORT MapWizard : public QWizard
{
Q_OBJECT
public:
- explicit MapWizard(QWidget *parent = 0);
+ explicit MapWizard(QWidget *parent = nullptr);
~MapWizard() override;
QStringList wmsServers() const;
void setWmsServers( const QStringList& uris );
QStringList staticUrlServers() const;
void setStaticUrlServers( const QStringList& uris );
static QString createArchive( QWidget *parent, const QString& mapId );
static void deleteArchive( const QString& mapId );
// QWizard's functions
void accept() override;
bool validateCurrentPage() override;
int nextId() const override;
public Q_SLOTS:
// WMS protocol
void queryServerCapabilities();
void parseServerCapabilities( QNetworkReply* reply );
void createWmsLegend( QNetworkReply* reply );
// Open file dialogs
void querySourceImage();
void queryPreviewImage();
void queryLegendImage();
// Other
void autoFillDetails();
void downloadLevelZero();
- void createLevelZero( QNetworkReply* reply = 0 );
+ void createLevelZero( QNetworkReply* reply = nullptr );
void showPreview();
private:
Q_PRIVATE_SLOT( d, void pageEntered( int ) )
GeoSceneDocument* createDocument();
bool createFiles( const GeoSceneDocument* head );
static QString createLegendHtml( const QString& image = QLatin1String("./legend/legend.png") );
void createLegendFile( const QString& legendHtml );
void createLegend();
void downloadLegend( const QString& url );
Q_DISABLE_COPY( MapWizard )
MapWizardPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/MarbleAboutDialog.h b/src/lib/marble/MarbleAboutDialog.h
index 94b53b6b1..d2f1ce3d5 100644
--- a/src/lib/marble/MarbleAboutDialog.h
+++ b/src/lib/marble/MarbleAboutDialog.h
@@ -1,65 +1,65 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
//
// The about dialog
//
#ifndef MARBLE_MARBLEABOUTDIALOG_H
#define MARBLE_MARBLEABOUTDIALOG_H
#include <QDialog>
#include "marble_export.h"
namespace Marble
{
class MarbleAboutDialogPrivate;
class MARBLE_EXPORT MarbleAboutDialog : public QDialog
{
Q_OBJECT
public:
enum Tab {
About,
Authors,
Data,
License
};
- explicit MarbleAboutDialog(QWidget *parent = 0);
+ explicit MarbleAboutDialog(QWidget *parent = nullptr);
~MarbleAboutDialog() override;
/**
* Set the application title (usually name and version) to show
* The default application title is 'Marble Virtual Globe'
*/
void setApplicationTitle( const QString &title );
/**
* @brief setInitialTab Change the tab shown when executing the dialog
* @param tab The tab to show
*/
void setInitialTab( Tab tab );
private:
Q_PRIVATE_SLOT( d, void loadPageContents( int idx ) )
Q_DISABLE_COPY( MarbleAboutDialog )
MarbleAboutDialogPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/MarbleAbstractPresenter.h b/src/lib/marble/MarbleAbstractPresenter.h
index de85fca98..b03540dfb 100644
--- a/src/lib/marble/MarbleAbstractPresenter.h
+++ b/src/lib/marble/MarbleAbstractPresenter.h
@@ -1,156 +1,156 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2008 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2014 Adam Dabrowski <adamdbrw@gmail.com>
//
#ifndef MARBLEABSTRACTPRESENTER_H
#define MARBLEABSTRACTPRESENTER_H
#include <QList>
#include "GeoDataLatLonBox.h"
#include "MarblePhysics.h"
#include <marble_export.h>
namespace Marble
{
class GeoDataPlacemark;
class GeoDataLookAt;
class MarbleMap;
class MarbleModel;
class ViewportParams;
class MARBLE_EXPORT MarbleAbstractPresenter : public QObject
{
Q_OBJECT
Q_SIGNALS:
void zoomChanged(int zoom);
void distanceChanged(const QString& distanceString);
/**
* This signal is emit when a new rectangle region is selected over the map.
*
* @param boundingBox The geographical coordinates of the selected region
*/
void regionSelected(const GeoDataLatLonBox &boundingBox);
public:
- explicit MarbleAbstractPresenter(MarbleMap *map, QObject *parent = 0);
+ explicit MarbleAbstractPresenter(MarbleMap *map, QObject *parent = nullptr);
~MarbleAbstractPresenter() override;
qreal moveStep() const;
int radius() const;
GeoDataLookAt lookAt() const;
QString distanceString() const;
/**
* @brief Approximated altitude of the camera in km
*/
qreal distance() const;
/**
* @brief An approximate distance from @p radius
* @param radius radius of planet disc in screen pixels
*/
qreal distanceFromRadius(qreal radius) const;
/**
* @brief The radius of the rendered planet disc derived from the approximate apparent @p distance
*/
qreal radiusFromDistance(qreal distance) const;
/**
* @brief Rotate the globe in the given direction in discrete steps
* @param stepsRight Number of steps to go right. Negative values go left.
* @param stepsDown Number of steps to go down. Negative values go up.
* @param mode Interpolation mode to use when traveling to the target
*/
void moveByStep(int stepsRight, int stepsDown, FlyToMode mode = Automatic);
int polarity() const;
int zoom() const;
int minimumZoom() const;
int maximumZoom() const;
qreal distanceFromZoom(qreal zoom) const;
qreal zoomFromDistance(qreal distance) const;
void zoomAt(const QPoint &pos, qreal newDistance);
void moveTo(const QPoint &pos, qreal factor);
qreal centerLongitude() const;
qreal centerLatitude() const;
ViewContext viewContext() const;
qreal zoom(qreal radius) const;
qreal radius(qreal zoom) const;
MarbleMap* map();
MarbleModel* model();
const MarbleMap* map() const;
const MarbleModel* model() const;
int logzoom() const;
void setLogzoom(int value);
int zoomStep() const;
qreal viewAngle() const;
bool animationsEnabled() const;
ViewportParams *viewport();
const ViewportParams* viewport() const;
public Q_SLOTS:
void rotateBy(const qreal deltaLon, const qreal deltaLat, FlyToMode mode = Instant);
void flyTo(const GeoDataLookAt &newLookAt, FlyToMode mode = Automatic);
void goHome(FlyToMode mode = Automatic);
void setZoom(int newZoom, FlyToMode mode = Instant);
void zoomView(int zoom, FlyToMode mode = Instant);
void zoomViewBy(int zoomStep, FlyToMode mode = Instant);
void zoomIn(FlyToMode mode = Automatic);
void zoomOut(FlyToMode mode = Automatic);
void zoomAtBy(const QPoint &pos, int zoomStep);
void setViewContext(ViewContext viewContext);
void centerOn(const qreal lon, const qreal lat, bool animated = false);
void centerOn(const GeoDataCoordinates &point, bool animated = false);
void centerOn(const GeoDataLatLonBox& box, bool animated = false);
void centerOn(const GeoDataPlacemark& placemark, bool animated = false);
void headingOn(qreal heading);
void setCenterLatitude(qreal lat, FlyToMode mode);
void setCenterLongitude(qreal lon, FlyToMode mode);
void setAnimationsEnabled(bool enabled);
void setRadius(int radius);
void setDistance(qreal newDistance);
void setSelection(const QRect& region);
private:
MarbleMap *const m_map;
MarblePhysics m_physics;
bool m_animationsEnabled;
int m_logzoom;
int m_zoomStep;
const qreal m_viewAngle;
};
}
#endif // MARBLEABSTRACTPRESENTER_H
diff --git a/src/lib/marble/MarbleClock.h b/src/lib/marble/MarbleClock.h
index b379deaba..d45e1eb8a 100644
--- a/src/lib/marble/MarbleClock.h
+++ b/src/lib/marble/MarbleClock.h
@@ -1,114 +1,114 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007-2008 David Roberts <dvdr18@gmail.com>
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#ifndef MARBLE_MARBLECLOCK_H
#define MARBLE_MARBLECLOCK_H
#include "geodata_export.h"
#include <QObject>
class QDateTime;
namespace Marble
{
class MarbleClockPrivate;
class GEODATA_EXPORT MarbleClock : public QObject
{
Q_OBJECT
public:
- explicit MarbleClock( QObject* parent = 0 );
+ explicit MarbleClock( QObject* parent = nullptr );
~MarbleClock() override;
/**
* @brief Determine how much of the current day has elapsed
* @return A value between 0 and 1 corresponding to the fraction of the day that has elapsed
*/
qreal dayFraction() const;
Q_SIGNALS:
/**
* @brief the timeChanged signal will be triggered at updateInterval() rate
* or at most every second.
**/
void timeChanged();
/**
* @brief Emitted when setUpdateInterval() is called.
*/
void updateIntervalChanged( int seconds );
public:
/**
* @brief Sets the internal date and time a custom one
* @param datetime The custom date and time
**/
void setDateTime( const QDateTime& datetime );
/**
* @brief Returns the internal date and time
**/
QDateTime dateTime() const;
/**
* @brief Set the interval at which dateTime() is updated and timeChanged() is emitted.
* @param seconds The interval in seconds
* @see updateInterval
*/
void setUpdateInterval( int seconds );
/**
* @brief Returns the interval at which dateTime() is updated and timeChanged() is emitted,
* The default is 60 seconds.
* @return The interval in seconds.
* @see setUpdateInterval
*/
int updateInterval() const;
/**
* @brief Sets the speed of the timer which is how fast the marble clock can run relative to actual speed of time.
* @param speed The new speed (integer)
**/
void setSpeed( int speed );
/**
* @brief Returns the speed of the timer
**/
int speed() const;
/**
* @brief Sets the timezone of the clock
* @param timeInSec The new timezone ( in seconds w.r.t. UTC )
**/
void setTimezone( int timeInSec );
/**
* @brief Returns the timezone of the clock
**/
int timezone() const;
private:
Q_DISABLE_COPY( MarbleClock )
Q_PRIVATE_SLOT( d, void timerTimeout() )
MarbleClockPrivate* const d;
friend class MarbleClockPrivate;
};
}
#endif
diff --git a/src/lib/marble/MarbleDirs.cpp b/src/lib/marble/MarbleDirs.cpp
index dc48da58c..61bc4b67c 100644
--- a/src/lib/marble/MarbleDirs.cpp
+++ b/src/lib/marble/MarbleDirs.cpp
@@ -1,351 +1,351 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include <QDir>
#include <QFile>
#include <QString>
#include <QStringList>
#include <QCoreApplication>
#include <cstdlib>
#include <QStandardPaths>
#ifdef Q_OS_WIN
//for getting appdata path
//mingw-w64 Internet Explorer 5.01
#define _WIN32_IE 0x0501
#include <shlobj.h>
#endif
#ifdef Q_OS_MACX
//for getting app bundle path
#include <ApplicationServices/ApplicationServices.h>
#endif
#include <config-marble.h>
using namespace Marble;
namespace
{
QString runTimeMarbleDataPath;
QString runTimeMarblePluginPath;
}
MarbleDirs::MarbleDirs()
- : d( 0 )
+ : d( nullptr )
{
}
QString MarbleDirs::path( const QString& relativePath )
{
QString localpath = localPath() + QLatin1Char('/') + relativePath; // local path
QString systempath = systemPath() + QLatin1Char('/') + relativePath; // system path
QString fullpath = systempath;
if ( QFile::exists( localpath ) ) {
fullpath = localpath;
}
return QDir( fullpath ).canonicalPath();
}
QString MarbleDirs::pluginPath( const QString& relativePath )
{
const QString localpath = pluginLocalPath() + QDir::separator() + relativePath; // local path
const QString systempath = pluginSystemPath() + QDir::separator() + relativePath; // system path
QString fullpath = systempath;
if ( QFile::exists( localpath ) ) {
fullpath = localpath;
}
return QDir( fullpath ).canonicalPath();
}
QStringList MarbleDirs::entryList( const QString& relativePath, QDir::Filters filters )
{
QStringList filesLocal = QDir(MarbleDirs::localPath() + QLatin1Char('/') + relativePath).entryList(filters);
QStringList filesSystem = QDir(MarbleDirs::systemPath() + QLatin1Char('/') + relativePath).entryList(filters);
QStringList allFiles( filesLocal );
allFiles << filesSystem;
// remove duplicate entries
allFiles.sort();
for ( int i = 1; i < allFiles.size(); ++i ) {
if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
allFiles.removeAt(i);
--i;
}
}
return allFiles;
}
QStringList MarbleDirs::pluginEntryList( const QString& relativePath, QDir::Filters filters )
{
QStringList allFiles = QDir(MarbleDirs::pluginLocalPath() + QLatin1Char('/') + relativePath).entryList(filters);
auto const pluginSystemPath = MarbleDirs::pluginSystemPath();
if (!pluginSystemPath.isEmpty()) {
allFiles << QDir(pluginSystemPath + QLatin1Char('/') + relativePath).entryList(filters);
}
// remove duplicate entries
allFiles.sort();
for ( int i = 1; i < allFiles.size(); ++i ) {
if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
allFiles.removeAt(i);
--i;
}
}
return allFiles;
}
QString MarbleDirs::systemPath()
{
if (!runTimeMarbleDataPath.isEmpty()) {
return runTimeMarbleDataPath;
}
QString systempath;
#ifdef Q_OS_WIN
return QCoreApplication::applicationDirPath() + QDir::separator() + QLatin1String("data");
#endif
#ifdef Q_OS_MACX
//
// On OSX lets try to find any file first in the bundle
// before branching out to home and sys dirs
//
CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
CFRelease(myBundleRef);
QString myPath(mypPathPtr);
CFRelease(myMacPath);
//do some magick so that we can still find data dir if
//marble was not built as a bundle
if (myPath.contains(QLatin1String(".app"))) { //its a bundle!
systempath = myPath + QLatin1String("/Contents/Resources/data");
}
if ( QFile::exists( systempath ) ){
return systempath;
}
#endif // mac bundle
#ifdef Q_OS_ANDROID
systempath = "assets:/data";
return systempath;
#endif
#ifdef MARBLE_DATA_PATH
//MARBLE_DATA_PATH is a compiler define set by cmake
QString compileTimeMarbleDataPath(MARBLE_DATA_PATH);
if(QDir(compileTimeMarbleDataPath).exists())
return compileTimeMarbleDataPath;
#endif // MARBLE_DATA_PATH
return QDir( QCoreApplication::applicationDirPath()
// TODO: QTONLY definition was removed during Qt5/KF5 port, check what code should do
#if defined(QTONLY)
+ QLatin1String( "/data" )
#else
+ QLatin1String( "/../share/apps/marble/data" )
#endif
).canonicalPath();
}
QString MarbleDirs::pluginSystemPath()
{
if (!runTimeMarblePluginPath.isEmpty()) {
return runTimeMarblePluginPath;
}
QString systempath;
#ifdef Q_OS_MACX
//
// On OSX lets try to find any file first in the bundle
// before branching out to home and sys dirs
//
CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
CFRelease(myBundleRef);
CFRelease(myMacPath);
QString myPath(mypPathPtr);
//do some magick so that we can still find data dir if
//marble was not built as a bundle
if (myPath.contains(QLatin1String(".app"))) { //its a bundle!
systempath = myPath + QLatin1String("/Contents/Resources/plugins");
}
if ( QFile::exists( systempath ) ){
return systempath;
}
#endif // mac bundle
#ifdef Q_OS_WIN
return QCoreApplication::applicationDirPath() + QDir::separator() + QLatin1String("plugins");
#endif
#ifdef Q_OS_ANDROID
return "assets:/plugins";
#endif
#ifdef MARBLE_PLUGIN_PATH
//MARBLE_PLUGIN_PATH is a compiler define set by cmake
QString compileTimeMarblePluginPath(MARBLE_PLUGIN_PATH);
if(QDir(compileTimeMarblePluginPath).exists())
return compileTimeMarblePluginPath;
#endif // MARBLE_PLUGIN_PATH
return QDir( QCoreApplication::applicationDirPath()
// TODO: QTONLY definition was removed during Qt5/KF5 port, check what code should do
#if defined(QTONLY)
+ QLatin1String( "/plugins" )
#else
+ QLatin1String( "/../lib/kde4/plugins/marble" )
#endif
).canonicalPath();
}
QString MarbleDirs::localPath()
{
#ifndef Q_OS_WIN
QString dataHome = getenv( "XDG_DATA_HOME" );
if( dataHome.isEmpty() )
dataHome = QDir::homePath() + QLatin1String("/.local/share");
return dataHome + QLatin1String("/marble"); // local path
#else
return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/.marble/data");
#endif
}
QStringList MarbleDirs::oldLocalPaths()
{
QStringList possibleOldPaths;
#ifndef Q_OS_WIN
const QString oldDefault = QDir::homePath() + QLatin1String("/.marble/data");
possibleOldPaths.append( oldDefault );
const QString xdgDefault = QDir::homePath() + QLatin1String("/.local/share/marble");
possibleOldPaths.append( xdgDefault );
QString xdg = getenv( "XDG_DATA_HOME" );
xdg += QLatin1String("/marble/");
possibleOldPaths.append( xdg );
#endif
#ifdef Q_OS_WIN
HWND hwnd = 0;
WCHAR *appdata_path = new WCHAR[MAX_PATH + 1];
SHGetSpecialFolderPathW(hwnd, appdata_path, CSIDL_APPDATA, 0);
QString appdata = QString::fromUtf16(reinterpret_cast<ushort*>(appdata_path));
delete[] appdata_path;
possibleOldPaths << QString(QDir::fromNativeSeparators(appdata) + QLatin1String("/.marble/data")); // local path
#endif
QString currentLocalPath = QDir( MarbleDirs::localPath() ).canonicalPath();
QStringList oldPaths;
for( const QString& possibleOldPath: possibleOldPaths ) {
if( !QDir().exists( possibleOldPath ) ) {
continue;
}
QString canonicalPossibleOldPath = QDir( possibleOldPath ).canonicalPath();
if( canonicalPossibleOldPath == currentLocalPath ) {
continue;
}
oldPaths.append( canonicalPossibleOldPath );
}
return oldPaths;
}
QString MarbleDirs::pluginLocalPath()
{
#ifndef Q_OS_WIN
return QDir::homePath() + QLatin1String("/.marble/plugins"); // local path
#else
return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/.marble/plugins");
#endif
}
QString MarbleDirs::marbleDataPath()
{
return runTimeMarbleDataPath;
}
QString MarbleDirs::marblePluginPath()
{
return runTimeMarblePluginPath;
}
void MarbleDirs::setMarbleDataPath( const QString& adaptedPath )
{
if ( !QDir::root().exists( adaptedPath ) )
{
qWarning() << QString( "Invalid MarbleDataPath \"%1\". Using \"%2\" instead." ).arg( adaptedPath, systemPath() );
return;
}
runTimeMarbleDataPath = adaptedPath;
}
void MarbleDirs::setMarblePluginPath( const QString& adaptedPath )
{
if ( !QDir::root().exists( adaptedPath ) )
{
qWarning() << QString( "Invalid MarblePluginPath \"%1\". Using \"%2\" instead." ).arg( adaptedPath, pluginSystemPath() );
return;
}
runTimeMarblePluginPath = adaptedPath;
}
void MarbleDirs::debug()
{
mDebug() << "=== MarbleDirs: ===";
mDebug() << "Local Path:" << localPath();
mDebug() << "Plugin Local Path:" << pluginLocalPath();
mDebug() << "";
mDebug() << "Marble Data Path (Run Time) :" << runTimeMarbleDataPath;
mDebug() << "Marble Data Path (Compile Time):" << QString(MARBLE_DATA_PATH);
mDebug() << "";
mDebug() << "Marble Plugin Path (Run Time) :" << runTimeMarblePluginPath;
mDebug() << "Marble Plugin Path (Compile Time):" << QString(MARBLE_PLUGIN_PATH);
mDebug() << "";
mDebug() << "System Path:" << systemPath();
mDebug() << "Plugin System Path:" << pluginSystemPath();
mDebug() << "===================";
}
diff --git a/src/lib/marble/MarbleInputHandler.cpp b/src/lib/marble/MarbleInputHandler.cpp
index f99b82d79..d40ea3ccf 100644
--- a/src/lib/marble/MarbleInputHandler.cpp
+++ b/src/lib/marble/MarbleInputHandler.cpp
@@ -1,994 +1,994 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2014 Adam Dabrowski <adamdbrw@gmail.com>
//
#include "MarbleInputHandler.h"
#include <QPoint>
#include <QPointer>
#include <QTimer>
#include <QCursor>
#include <QMouseEvent>
#include <QPixmap>
#include <QGestureEvent>
#include <QPinchGesture>
#include "kineticmodel.h"
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "MarbleMap.h"
#include "GeoDataCoordinates.h"
#include "MarbleAbstractPresenter.h"
#include "ViewportParams.h"
#include "AbstractFloatItem.h"
#include "AbstractDataPluginItem.h"
#include "RenderPlugin.h"
namespace Marble {
const int TOOLTIP_START_INTERVAL = 1000;
class Q_DECL_HIDDEN MarbleInputHandler::Protected
{
public:
Protected(MarbleAbstractPresenter *marblePresenter);
MarbleAbstractPresenter *const m_marblePresenter;
bool m_positionSignalConnected;
QTimer *m_mouseWheelTimer;
Qt::MouseButtons m_disabledMouseButtons;
qreal m_wheelZoomTargetDistance;
bool m_panViaArrowsEnabled;
bool m_inertialEarthRotation;
int m_steps;
const int m_discreteZoomSteps = 120;
};
MarbleInputHandler::Protected::Protected(MarbleAbstractPresenter *marblePresenter)
: m_marblePresenter( marblePresenter ),
m_positionSignalConnected( false ),
- m_mouseWheelTimer( 0 ),
+ m_mouseWheelTimer( nullptr ),
m_disabledMouseButtons( Qt::NoButton ),
m_wheelZoomTargetDistance( 0.0 ),
m_panViaArrowsEnabled( true ),
m_inertialEarthRotation( true ),
m_steps(0)
{
}
MarbleInputHandler::MarbleInputHandler(MarbleAbstractPresenter *marblePresenter)
: d(new Protected(marblePresenter))
{
d->m_mouseWheelTimer = new QTimer( this );
connect(d->m_mouseWheelTimer, SIGNAL(timeout()), this, SLOT(restoreViewContext()));
connect(d->m_marblePresenter->map(), SIGNAL(renderPluginInitialized(RenderPlugin*)),
this, SLOT(installPluginEventFilter(RenderPlugin*)));
}
MarbleInputHandler::~MarbleInputHandler()
{
delete d->m_mouseWheelTimer;
delete d;
}
void MarbleInputHandler::setPositionSignalConnected(bool connected)
{
d->m_positionSignalConnected = connected;
}
bool MarbleInputHandler::isPositionSignalConnected() const
{
return d->m_positionSignalConnected;
}
void MarbleInputHandler::setMouseButtonPopupEnabled(Qt::MouseButton mouseButton, bool enabled)
{
if (enabled)
{
d->m_disabledMouseButtons &= ~Qt::MouseButtons(mouseButton);
}
else
{
d->m_disabledMouseButtons |= mouseButton;
}
}
bool MarbleInputHandler::isMouseButtonPopupEnabled(Qt::MouseButton mouseButton) const
{
return !(d->m_disabledMouseButtons & mouseButton);
}
void MarbleInputHandler::setPanViaArrowsEnabled(bool enabled)
{
d->m_panViaArrowsEnabled = enabled;
}
bool MarbleInputHandler::panViaArrowsEnabled() const
{
return d->m_panViaArrowsEnabled;
}
void MarbleInputHandler::setInertialEarthRotationEnabled(bool enabled)
{
d->m_inertialEarthRotation = enabled;
}
bool MarbleInputHandler::inertialEarthRotationEnabled() const
{
return d->m_inertialEarthRotation;
}
class Q_DECL_HIDDEN MarbleDefaultInputHandler::Private
{
public:
Private();
~Private();
QPixmap m_curpmtl;
QPixmap m_curpmtc;
QPixmap m_curpmtr;
QPixmap m_curpmcr;
QPixmap m_curpmcl;
QPixmap m_curpmbl;
QPixmap m_curpmbc;
QPixmap m_curpmbr;
QCursor m_arrowCur[3][3];
// Indicates if the left mouse button has been pressed already.
bool m_leftPressed;
// Indicates if the middle mouse button has been pressed already.
bool m_midPressed;
// The mouse pointer x position when the left mouse button has been pressed.
int m_leftPressedX;
// The mouse pointer y position when the left mouse button has been pressed.
int m_leftPressedY;
// The mouse pointer y position when the middle mouse button has been pressed.
int m_midPressedY;
int m_startingRadius;
// Indicates if the right mouse button has been pressed already.
bool m_rightPressed;
// Point where the right mouse button has been pressed on.
QPoint m_rightOrigin;
// Position to calculate the heading.
// Indicates previous position since mouse has been moved.
QPoint m_rightPosition;
// Indicates the heading when the right mouse button has been pressed
// and mouse is moving.
qreal m_heading;
// The center longitude in radian when the left mouse button has been pressed.
qreal m_leftPressedLon;
// The center latitude in radian when the left mouse button has been pressed.
qreal m_leftPressedLat;
int m_dragThreshold;
QTimer m_lmbTimer;
QTimer m_pressAndHoldTimer;
// Models to handle the kinetic spinning.
KineticModel m_kineticSpinning;
QPoint m_selectionOrigin;
QPointer<AbstractDataPluginItem> m_lastToolTipItem;
QTimer m_toolTipTimer;
QPoint m_toolTipPosition;
};
MarbleDefaultInputHandler::Private::Private()
: m_leftPressed(false),
m_midPressed(false),
m_rightPressed(false),
m_heading(0),
m_dragThreshold(MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ? 15 : 3)
{
m_curpmtl.load(QStringLiteral(":/marble/cursor/tl.png"));
m_curpmtc.load(QStringLiteral(":/marble/cursor/tc.png"));
m_curpmtr.load(QStringLiteral(":/marble/cursor/tr.png"));
m_curpmcr.load(QStringLiteral(":/marble/cursor/cr.png"));
m_curpmcl.load(QStringLiteral(":/marble/cursor/cl.png"));
m_curpmbl.load(QStringLiteral(":/marble/cursor/bl.png"));
m_curpmbc.load(QStringLiteral(":/marble/cursor/bc.png"));
m_curpmbr.load(QStringLiteral(":/marble/cursor/br.png"));
m_arrowCur[0][0] = QCursor( m_curpmtl, 2, 2 );
m_arrowCur[1][0] = QCursor( m_curpmtc, 10, 3 );
m_arrowCur[2][0] = QCursor( m_curpmtr, 19, 2 );
m_arrowCur[0][1] = QCursor( m_curpmcl, 3, 10 );
m_arrowCur[1][1] = QCursor( Qt::OpenHandCursor );
m_arrowCur[2][1] = QCursor( m_curpmcr, 18, 10 );
m_arrowCur[0][2] = QCursor( m_curpmbl, 2, 19 );
m_arrowCur[1][2] = QCursor( m_curpmbc, 11, 18 );
m_arrowCur[2][2] = QCursor( m_curpmbr, 19, 19 );
}
MarbleDefaultInputHandler::Private::~Private()
{
}
MarbleDefaultInputHandler::MarbleDefaultInputHandler(MarbleAbstractPresenter *marblePresenter)
: MarbleInputHandler(marblePresenter),
d(new Private())
{
d->m_toolTipTimer.setSingleShot(true);
d->m_toolTipTimer.setInterval(TOOLTIP_START_INTERVAL);
connect(&d->m_toolTipTimer, SIGNAL(timeout()), this, SLOT(openItemToolTip()));
d->m_lmbTimer.setSingleShot(true);
connect(&d->m_lmbTimer, SIGNAL(timeout()), this, SLOT(lmbTimeout()));
d->m_kineticSpinning.setUpdateInterval(35);
connect(&d->m_kineticSpinning, SIGNAL(positionChanged(qreal,qreal)),
MarbleInputHandler::d->m_marblePresenter, SLOT(centerOn(qreal,qreal)));
connect(&d->m_kineticSpinning, SIGNAL(headingChanged(qreal)),
MarbleInputHandler::d->m_marblePresenter, SLOT(headingOn(qreal)));
connect(&d->m_kineticSpinning, SIGNAL(finished()), SLOT(restoreViewContext()));
// Left and right mouse button signals.
connect(this, SIGNAL(rmbRequest(int,int)), this, SLOT(showRmbMenu(int,int)));
connect(this, SIGNAL(lmbRequest(int,int)), this, SLOT(showLmbMenu(int,int)));
d->m_pressAndHoldTimer.setInterval(800);
d->m_pressAndHoldTimer.setSingleShot(true);
connect(&d->m_pressAndHoldTimer, SIGNAL(timeout()), this, SLOT(handlePressAndHold()));
}
MarbleDefaultInputHandler::~MarbleDefaultInputHandler()
{
delete d;
}
void MarbleDefaultInputHandler::lmbTimeout()
{
if (!selectionRubber()->isVisible())
{
qreal clickedLon = 0;
qreal clickedLat = 0;
bool isPointOnGlobe = MarbleInputHandler::d->m_marblePresenter->map()->geoCoordinates( d->m_leftPressedX, d->m_leftPressedY,
clickedLon, clickedLat,
GeoDataCoordinates::Degree );
emit lmbRequest(d->m_leftPressedX, d->m_leftPressedY);
/**
* emit mouse click only when the clicked
* position is within the globe.
*/
if ( isPointOnGlobe ) {
emit mouseClickGeoPosition( clickedLon, clickedLat,
GeoDataCoordinates::Degree );
}
}
}
void MarbleInputHandler::restoreViewContext()
{
// Needs to stop the timer since it repeats otherwise.
d->m_mouseWheelTimer->stop();
// Redraw the map with the quality set for Still (if necessary).
d->m_marblePresenter->setViewContext(Still);
d->m_marblePresenter->map()->viewport()->resetFocusPoint();
d->m_wheelZoomTargetDistance = 0.0;
}
void MarbleDefaultInputHandler::hideSelectionIfCtrlReleased(QEvent *e)
{
if (selectionRubber()->isVisible() && e->type() == QEvent::MouseMove)
{
QMouseEvent *event = static_cast<QMouseEvent*>(e);
if (!(event->modifiers() & Qt::ControlModifier))
{
selectionRubber()->hide();
}
}
}
bool MarbleDefaultInputHandler::handleDoubleClick(QMouseEvent *event)
{
qreal mouseLon;
qreal mouseLat;
const bool isMouseAboveMap = MarbleInputHandler::d->m_marblePresenter->map()->geoCoordinates(event->x(), event->y(),
mouseLon, mouseLat, GeoDataCoordinates::Radian);
if(isMouseAboveMap)
{
d->m_pressAndHoldTimer.stop();
d->m_lmbTimer.stop();
MarbleInputHandler::d->m_marblePresenter->moveTo(event->pos(), 0.67);
}
return acceptMouse();
}
bool MarbleDefaultInputHandler::handleWheel(QWheelEvent *wheelevt)
{
MarbleAbstractPresenter *marblePresenter = MarbleInputHandler::d->m_marblePresenter;
marblePresenter->setViewContext(Animation);
if( (MarbleInputHandler::d->m_steps > 0 && wheelevt->delta() < 0) ||
(MarbleInputHandler::d->m_steps < 0 && wheelevt->delta() > 0) )
{
MarbleInputHandler::d->m_steps = wheelevt->delta();
}
else
{
MarbleInputHandler::d->m_steps += wheelevt->delta();
}
if (marblePresenter->map()->discreteZoom())
{
if(qAbs(MarbleInputHandler::d->m_steps) >= MarbleInputHandler::d->m_discreteZoomSteps)
{
marblePresenter->zoomAtBy(wheelevt->pos(), MarbleInputHandler::d->m_steps);
MarbleInputHandler::d->m_steps = 0;
}
}
else
{
qreal zoom = marblePresenter->zoom();
qreal target = MarbleInputHandler::d->m_wheelZoomTargetDistance;
if (marblePresenter->animationsEnabled() && target > 0.0)
{
// Do not use intermediate (interpolated) distance values caused by animations
zoom = marblePresenter->zoomFromDistance(target);
}
qreal newDistance = marblePresenter->distanceFromZoom(zoom + MarbleInputHandler::d->m_steps);
MarbleInputHandler::d->m_wheelZoomTargetDistance = newDistance;
marblePresenter->zoomAt(wheelevt->pos(), newDistance);
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.jumpToPosition(MarbleInputHandler::d->m_marblePresenter->centerLongitude(),
MarbleInputHandler::d->m_marblePresenter->centerLatitude());
}
MarbleInputHandler::d->m_steps = 0;
}
MarbleInputHandler::d->m_mouseWheelTimer->start(400);
return true;
}
bool MarbleDefaultInputHandler::handlePinch(const QPointF &center, qreal scaleFactor, Qt::GestureState state)
{
qreal destLat;
qreal destLon;
MarbleAbstractPresenter *marblePresenter = MarbleInputHandler::d->m_marblePresenter;
bool isValid = marblePresenter->map()->geoCoordinates(center.x(), center.y(),
destLon, destLat, GeoDataCoordinates::Radian );
if (isValid)
{
marblePresenter->map()->viewport()->setFocusPoint(GeoDataCoordinates(destLon, destLat));
}
qreal zoom, target, newDistance;
qreal zoomDelta = scaleFactor > 1.0 ? scaleFactor : -1.0/scaleFactor;
switch (state)
{
case Qt::NoGesture:
break;
case Qt::GestureStarted:
marblePresenter->setViewContext(Animation);
d->m_pressAndHoldTimer.stop();
d->m_lmbTimer.stop();
d->m_midPressed = false;
d->m_leftPressed = false;
break;
case Qt::GestureUpdated:
zoom = marblePresenter->zoom();
target = MarbleInputHandler::d->m_wheelZoomTargetDistance;
if (marblePresenter->animationsEnabled() && target > 0.0)
{
// Do not use intermediate (interpolated) distance values caused by animations
zoom = marblePresenter->zoomFromDistance(target);
}
newDistance = marblePresenter->distanceFromZoom(zoom + 20 * zoomDelta);
MarbleInputHandler::d->m_wheelZoomTargetDistance = newDistance;
marblePresenter->zoomAt(center.toPoint(), newDistance);
break;
case Qt::GestureFinished:
marblePresenter->map()->viewport()->resetFocusPoint();
marblePresenter->setViewContext(Still);
break;
case Qt::GestureCanceled:
marblePresenter->map()->viewport()->resetFocusPoint();
marblePresenter->setViewContext(Still);
break;
}
return true;
}
bool MarbleDefaultInputHandler::handleGesture(QGestureEvent *ge)
{
QPinchGesture *pinch = static_cast<QPinchGesture*>(ge->gesture(Qt::PinchGesture));
if (!pinch)
{
return false;
}
qreal scaleFactor = pinch->scaleFactor();
QPointF center = pinch->centerPoint();
return handlePinch(center, scaleFactor, pinch->state());
}
void MarbleDefaultInputHandler::checkReleasedMove(QMouseEvent *event)
{
// To prevent error from lost MouseButtonRelease events
if (event->type() == QEvent::MouseMove && !(event->buttons() & Qt::LeftButton))
{
if (d->m_leftPressed)
{
d->m_leftPressed = false;
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.start();
}
else
{
MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
}
}
}
if (event->type() == QEvent::MouseMove && !(event->buttons() & Qt::MidButton))
{
d->m_midPressed = false;
}
}
void MarbleDefaultInputHandler::handleMouseButtonPress(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton )
{
d->m_pressAndHoldTimer.start();
handleLeftMouseButtonPress(event);
}
if ( event->button() == Qt::MidButton )
{
handleMiddleMouseButtonPress(event);
}
if ( event->button() == Qt::RightButton )
{
handleRightMouseButtonPress(event);
}
}
void MarbleDefaultInputHandler::handleLeftMouseButtonPress(QMouseEvent *event)
{
// silently enable the animation context without triggering a repaint
MarbleInputHandler::d->m_marblePresenter->map()->blockSignals(true);
MarbleInputHandler::d->m_marblePresenter->setViewContext(Animation);
MarbleInputHandler::d->m_marblePresenter->map()->blockSignals(false);
if (isMouseButtonPopupEnabled(Qt::LeftButton))
{
d->m_lmbTimer.start(400);
}
d->m_leftPressed = true;
d->m_midPressed = false;
selectionRubber()->hide();
// On the single event of a mouse button press these
// values get stored, to enable us to e.g. calculate the
// distance of a mouse drag while the mouse button is
// still down.
d->m_leftPressedX = event->x();
d->m_leftPressedY = event->y();
// Calculate translation of center point
d->m_leftPressedLon = MarbleInputHandler::d->m_marblePresenter->centerLongitude();
d->m_leftPressedLat = MarbleInputHandler::d->m_marblePresenter->centerLatitude();
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.stop();
d->m_kineticSpinning.setPosition(d->m_leftPressedLon, d->m_leftPressedLat);
}
if (event->modifiers() & Qt::ControlModifier)
{
mDebug() << Q_FUNC_INFO << "Starting selection";
d->m_pressAndHoldTimer.stop();
d->m_lmbTimer.stop();
d->m_selectionOrigin = event->pos();
selectionRubber()->setGeometry(QRect(d->m_selectionOrigin, QSize()));
selectionRubber()->show();
}
}
void MarbleDefaultInputHandler::handleMiddleMouseButtonPress(QMouseEvent *event)
{
d->m_midPressed = true;
d->m_leftPressed = false;
d->m_startingRadius = MarbleInputHandler::d->m_marblePresenter->radius();
d->m_midPressedY = event->y();
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.start();
}
selectionRubber()->hide();
MarbleInputHandler::d->m_marblePresenter->setViewContext(Animation);
}
void MarbleDefaultInputHandler::handleRightMouseButtonPress(QMouseEvent *event)
{
d->m_rightPressed = true;
d->m_rightOrigin = event->pos();
d->m_rightPosition = event->pos();
d->m_heading = MarbleInputHandler::d->m_marblePresenter->map()->heading();
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.stop();
d->m_kineticSpinning.setHeading(d->m_heading);
}
}
void MarbleDefaultInputHandler::handleMouseButtonRelease(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
d->m_pressAndHoldTimer.stop();
//emit current coordinates to be interpreted
//as requested
emit mouseClickScreenPosition(d->m_leftPressedX, d->m_leftPressedY);
d->m_leftPressed = false;
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.start();
}
else
{
MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
}
}
if (event->button() == Qt::MidButton)
{
d->m_midPressed = false;
MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
}
if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::RightButton)
{
if (d->m_rightOrigin == event->pos())
{
emit rmbRequest(event->x(), event->y());
}
d->m_rightPressed = false;
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.start();
}
else
{
MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
}
}
if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::LeftButton
&& selectionRubber()->isVisible())
{
mDebug() << Q_FUNC_INFO << "Leaving selection";
MarbleInputHandler::d->m_marblePresenter->setSelection(selectionRubber()->geometry());
selectionRubber()->hide();
}
}
void MarbleDefaultInputHandler::notifyPosition(bool isMouseAboveMap, qreal mouseLon, qreal mouseLat)
{
// emit the position string only if the signal got attached
if (MarbleInputHandler::d->m_positionSignalConnected) {
if (!isMouseAboveMap)
{
emit mouseMoveGeoPosition(QCoreApplication::translate( "Marble", NOT_AVAILABLE));
}
else
{
QString position = GeoDataCoordinates(mouseLon, mouseLat).toString();
emit mouseMoveGeoPosition(position);
}
}
}
void MarbleDefaultInputHandler::adjustCursorShape(const QPoint &mousePosition, const QPoint &mouseDirection)
{
// Find out if there are data items and if one has defined an action
QList<AbstractDataPluginItem *> dataItems
= MarbleInputHandler::d->m_marblePresenter->map()->whichItemAt(mousePosition);
bool dataAction = false;
QPointer<AbstractDataPluginItem> toolTipItem;
QList<AbstractDataPluginItem *>::iterator it = dataItems.begin();
QList<AbstractDataPluginItem *>::iterator const end = dataItems.end();
for (; it != end && dataAction == false && toolTipItem.isNull(); ++it)
{
if ((*it)->action())
{
dataAction = true;
}
if (!(*it)->toolTip().isNull() && toolTipItem.isNull())
{
toolTipItem = (*it);
}
}
if (toolTipItem.isNull()) {
d->m_toolTipTimer.stop();
}
else if (!( d->m_lastToolTipItem.data() == toolTipItem.data()))
{
d->m_toolTipTimer.start();
d->m_lastToolTipItem = toolTipItem;
d->m_toolTipPosition = mousePosition;
}
else
{
if (!d->m_toolTipTimer.isActive())
{
d->m_toolTipTimer.start();
}
d->m_toolTipPosition = mousePosition;
}
if (!dataAction && !MarbleInputHandler::d->m_marblePresenter->map()->hasFeatureAt(mousePosition)) {
if (!d->m_leftPressed)
{
d->m_arrowCur [1][1] = QCursor(Qt::OpenHandCursor);
}
else
{
d->m_arrowCur [1][1] = QCursor(Qt::ClosedHandCursor);
}
}
else
{
if (!d->m_leftPressed)
{
d->m_arrowCur [1][1] = QCursor(Qt::PointingHandCursor);
}
}
if (panViaArrowsEnabled())
{
setCursor(d->m_arrowCur[mouseDirection.x()+1][mouseDirection.y()+1]);
}
else
{
setCursor(d->m_arrowCur[1][1]);
}
}
QPoint MarbleDefaultInputHandler::mouseMovedOutside(QMouseEvent *event)
{ //Returns a 2d vector representing the direction in which the mouse left
int dirX = 0;
int dirY = 0;
int polarity = MarbleInputHandler::d->m_marblePresenter->viewport()->polarity();
if (d->m_leftPressed) {
d->m_leftPressed = false;
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.start();
}
}
QRect boundingRect = MarbleInputHandler::d->m_marblePresenter->viewport()->mapRegion().boundingRect();
if (boundingRect.width() != 0)
{
dirX = (int)( 3 * (event->x() - boundingRect.left()) / boundingRect.width()) - 1;
}
if (dirX > 1)
{
dirX = 1;
}
if (dirX < -1)
{
dirX = -1;
}
if (boundingRect.height() != 0)
{
dirY = (int)(3 * (event->y() - boundingRect.top()) / boundingRect.height()) - 1;
}
if (dirY > 1)
{
dirY = 1;
}
if (dirY < -1)
{
dirY = -1;
}
if (event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress
&& panViaArrowsEnabled() && !d->m_kineticSpinning.hasVelocity())
{
d->m_pressAndHoldTimer.stop();
d->m_lmbTimer.stop();
qreal moveStep = MarbleInputHandler::d->m_marblePresenter->moveStep();
if (polarity < 0)
{
MarbleInputHandler::d->m_marblePresenter->rotateBy(-moveStep * (qreal)(+dirX), moveStep * (qreal)(+dirY));
}
else
{
MarbleInputHandler::d->m_marblePresenter->rotateBy(-moveStep * (qreal)(-dirX), moveStep * (qreal)(+dirY));
}
}
if (!MarbleInputHandler::d->m_inertialEarthRotation)
{
MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
}
return QPoint(dirX, dirY);
}
bool MarbleDefaultInputHandler::handleMouseEvent(QMouseEvent *event)
{
QPoint direction;
checkReleasedMove(event);
// Do not handle (and therefore eat) mouse press and release events
// that occur above visible float items. Mouse motion events are still
// handled, however.
if (event->type() != QEvent::MouseMove && !selectionRubber()->isVisible())
{
auto const floatItems = MarbleInputHandler::d->m_marblePresenter->map()->floatItems();
for (AbstractFloatItem *floatItem: floatItems)
{
if ( floatItem->enabled() && floatItem->visible()
&& floatItem->contains( event->pos() ) )
{
d->m_pressAndHoldTimer.stop();
d->m_lmbTimer.stop();
return false;
}
}
}
qreal mouseLon;
qreal mouseLat;
const bool isMouseAboveMap = MarbleInputHandler::d->m_marblePresenter->map()->geoCoordinates(event->x(), event->y(),
mouseLon, mouseLat, GeoDataCoordinates::Radian);
notifyPosition(isMouseAboveMap, mouseLon, mouseLat);
QPoint mousePosition(event->x(), event->y());
if (isMouseAboveMap || selectionRubber()->isVisible()
|| MarbleInputHandler::d->m_marblePresenter->map()->hasFeatureAt(mousePosition))
{
if (event->type() == QEvent::MouseButtonPress)
{
handleMouseButtonPress(event);
}
if (event->type() == QEvent::MouseButtonRelease)
{
handleMouseButtonRelease(event);
}
// Regarding all kinds of mouse moves:
if (d->m_leftPressed && !selectionRubber()->isVisible())
{
qreal radius = (qreal)(MarbleInputHandler::d->m_marblePresenter->radius());
qreal deltax = event->x() - d->m_leftPressedX;
qreal deltay = event->y() - d->m_leftPressedY;
if (qAbs(deltax) > d->m_dragThreshold
|| qAbs(deltay) > d->m_dragThreshold
|| !d->m_lmbTimer.isActive())
{
MarbleInputHandler::d->m_marblePresenter->setViewContext(Animation);
d->m_pressAndHoldTimer.stop();
d->m_lmbTimer.stop();
const Quaternion rotation = Quaternion::fromEuler( 0, 0, MarbleInputHandler::d->m_marblePresenter->map()->heading() * DEG2RAD );
Quaternion quat = Quaternion::fromSpherical( - M_PI/2 * deltax / radius, + M_PI/2 * deltay / radius );
quat.rotateAroundAxis( rotation );
qreal lon, lat;
quat.getSpherical( lon, lat );
const qreal posLon = d->m_leftPressedLon + RAD2DEG * lon;
const qreal posLat = d->m_leftPressedLat + RAD2DEG * lat;
MarbleInputHandler::d->m_marblePresenter->centerOn(posLon, posLat);
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.setPosition(posLon, posLat);
}
}
}
if (d->m_midPressed)
{
int eventy = event->y();
int dy = d->m_midPressedY - eventy;
MarbleInputHandler::d->m_marblePresenter->setRadius(d->m_startingRadius * pow(1.005, dy));
}
if (d->m_rightPressed)
{
qreal centerX, centerY;
MarbleInputHandler::d->m_marblePresenter->map()->screenCoordinates(
MarbleInputHandler::d->m_marblePresenter->centerLongitude(),
MarbleInputHandler::d->m_marblePresenter->centerLatitude(), centerX, centerY);
// Deltas from previous position.
int dx = event->x() - d->m_rightPosition.x();
int dy = event->y() - d->m_rightPosition.y();
d->m_rightPosition = event->pos();
// Moving on the bottom should be opposite direction.
int sign = event->y() > centerY ? -1 : 1;
// Left top and right bottom sides for y axis should be opposite direction.
if ((event->x() < centerX && event->y() < centerY) || (event->x() > centerX && event->y() > centerY))
{
dy *= -1;
}
const qreal speedFactor = 0.3;
d->m_heading += (dx + dy) * sign * speedFactor;
MarbleInputHandler::d->m_marblePresenter->map()->setHeading(d->m_heading);
if (MarbleInputHandler::d->m_inertialEarthRotation)
{
d->m_kineticSpinning.setHeading(d->m_heading);
}
}
if (selectionRubber()->isVisible())
{
// We change selection.
selectionRubber()->setGeometry(QRect(d->m_selectionOrigin, event->pos()).normalized());
}
}
else
{
direction = mouseMovedOutside(event);
}
if (MarbleInputHandler::d->m_marblePresenter->viewContext() != Animation) {
adjustCursorShape(mousePosition, direction);
}
return acceptMouse();
}
bool MarbleDefaultInputHandler::acceptMouse()
{
// let others, especially float items, still process the event
// Note: This caused a bug in combination with oxygen, see https://bugs.kde.org/show_bug.cgi?id=242414
// and changing it a related regression, see https://bugs.kde.org/show_bug.cgi?id=324862
return false;
}
bool MarbleDefaultInputHandler::eventFilter(QObject* o, QEvent* e)
{
Q_UNUSED(o);
if (layersEventFilter(o, e))
{
return true;
}
hideSelectionIfCtrlReleased(e);
switch (e->type())
{
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
return handleTouch(static_cast<QTouchEvent *>(e));
case QEvent::KeyPress:
return handleKeyPress(static_cast<QKeyEvent *>(e));
case QEvent::Gesture:
return handleGesture(static_cast<QGestureEvent *>(e));
case QEvent::Wheel:
return handleWheel(static_cast<QWheelEvent*>(e));
case QEvent::MouseButtonDblClick:
return handleDoubleClick(static_cast<QMouseEvent*>(e));
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
return handleMouseEvent(static_cast<QMouseEvent*>(e));
default:
return false;
}
}
bool MarbleDefaultInputHandler::handleTouch(QTouchEvent*)
{
return false; //reimplement to handle in cases of QML and PinchArea element
}
bool MarbleDefaultInputHandler::handleKeyPress(QKeyEvent* event)
{
if ( event->type() == QEvent::KeyPress ) {
MarbleAbstractPresenter *marblePresenter = MarbleInputHandler::d->m_marblePresenter;
bool handled = true;
switch ( event->key() ) {
case Qt::Key_Left:
marblePresenter->moveByStep(-1, 0);
break;
case Qt::Key_Right:
marblePresenter->moveByStep(1, 0);
break;
case Qt::Key_Up:
marblePresenter->moveByStep(0, -1);
break;
case Qt::Key_Down:
marblePresenter->moveByStep(0, 1);
break;
case Qt::Key_Plus:
if (event->modifiers() != Qt::ControlModifier) {
marblePresenter->zoomIn();
}
break;
case Qt::Key_Minus:
if (event->modifiers() != Qt::ControlModifier) {
marblePresenter->zoomOut();
}
break;
case Qt::Key_Home:
marblePresenter->goHome();
break;
default:
handled = false;
break;
}
return handled;
}
return false;
}
void MarbleDefaultInputHandler::handleMouseButtonPressAndHold(const QPoint &)
{
// Default implementation does nothing
}
void MarbleDefaultInputHandler::handlePressAndHold()
{
handleMouseButtonPressAndHold(QPoint(d->m_leftPressedX, d->m_leftPressedY));
}
const AbstractDataPluginItem *MarbleDefaultInputHandler::lastToolTipItem() const
{
return d->m_lastToolTipItem;
}
QTimer* MarbleDefaultInputHandler::toolTipTimer()
{
return &d->m_toolTipTimer;
}
QPoint MarbleDefaultInputHandler::toolTipPosition() const
{
return d->m_toolTipPosition;
}
}
#include "moc_MarbleInputHandler.cpp"
diff --git a/src/lib/marble/MarbleLegendBrowser.cpp b/src/lib/marble/MarbleLegendBrowser.cpp
index 2fb25a33f..c06fe9a87 100644
--- a/src/lib/marble/MarbleLegendBrowser.cpp
+++ b/src/lib/marble/MarbleLegendBrowser.cpp
@@ -1,396 +1,396 @@
//
// This file is part of the Marble Project.
//
// 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 <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
// Copyright 2013 Yazeed Zoabi <yazeedz.zoabi@gmail.com>
//
#include "MarbleLegendBrowser.h"
#include <QCoreApplication>
#include <QUrl>
#include <QDesktopServices>
#include <QEvent>
#include <QFile>
#include <QMouseEvent>
#include <QPainter>
#include <QRegExp>
#ifndef MARBLE_NO_WEBKITWIDGETS
#include <QWebFrame>
#include <QWebElement>
#endif
#include <QTextDocument>
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "GeoSceneLegend.h"
#include "GeoSceneSection.h"
#include "GeoSceneIcon.h"
#include "GeoSceneItem.h"
#include "GeoSceneProperty.h"
#include "GeoSceneSettings.h"
#include "MarbleModel.h"
#include "MarbleDebug.h"
#include "TemplateDocument.h"
#include "MarbleDirs.h"
namespace Marble
{
class MarbleLegendBrowserPrivate
{
public:
MarbleModel *m_marbleModel;
QMap<QString, bool> m_checkBoxMap;
QMap<QString, QPixmap> m_symbolMap;
QString m_currentThemeId;
};
// ================================================================
MarbleLegendBrowser::MarbleLegendBrowser( QWidget *parent )
: MarbleWebView( parent ),
d( new MarbleLegendBrowserPrivate )
{
- d->m_marbleModel = 0;
+ d->m_marbleModel = nullptr;
#ifndef MARBLE_NO_WEBKITWIDGETS
QWebFrame *frame = page()->mainFrame();
connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
this, SLOT(injectCheckBoxChecker()));
page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
connect( this, SIGNAL(linkClicked(QUrl)), this, SLOT(openLinkExternally(QUrl)) );
#endif
}
MarbleLegendBrowser::~MarbleLegendBrowser()
{
delete d;
}
void MarbleLegendBrowser::setMarbleModel( MarbleModel *marbleModel )
{
// We need this to be able to get to the MapTheme.
d->m_marbleModel = marbleModel;
if ( d->m_marbleModel ) {
connect ( d->m_marbleModel, SIGNAL(themeChanged(QString)),
this, SLOT(initTheme()) );
}
}
QSize MarbleLegendBrowser::sizeHint() const
{
return QSize( 180, 320 );
}
void MarbleLegendBrowser::initTheme()
{
// Check for a theme specific legend.html first
- if ( d->m_marbleModel != 0 && d->m_marbleModel->mapTheme() != 0 )
+ if ( d->m_marbleModel != nullptr && d->m_marbleModel->mapTheme() != nullptr )
{
const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
d->m_checkBoxMap.clear();
for ( const GeoSceneProperty *property: currentMapTheme->settings()->allProperties() ) {
if ( property->available() ) {
d->m_checkBoxMap[ property->name() ] = property->value();
}
}
- disconnect ( currentMapTheme, SIGNAL(valueChanged(QString,bool)), 0, 0 );
+ disconnect ( currentMapTheme, SIGNAL(valueChanged(QString,bool)), nullptr, nullptr );
connect ( currentMapTheme, SIGNAL(valueChanged(QString,bool)),
this, SLOT(setCheckedProperty(QString,bool)) );
}
if ( isVisible() ) {
loadLegend();
}
}
void MarbleLegendBrowser::loadLegend()
{
if (!d->m_marbleModel) {
return;
}
#ifndef MARBLE_NO_WEBKITWIDGETS
if (d->m_currentThemeId != d->m_marbleModel->mapThemeId()) {
d->m_currentThemeId = d->m_marbleModel->mapThemeId();
} else {
return;
}
// Read the html string.
QString legendPath;
// Check for a theme specific legend.html first
- if (d->m_marbleModel->mapTheme() != 0 ) {
+ if (d->m_marbleModel->mapTheme() != nullptr ) {
const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
legendPath = MarbleDirs::path(QLatin1String("maps/") +
currentMapTheme->head()->target() + QLatin1Char('/') +
currentMapTheme->head()->theme() + QLatin1String("/legend.html"));
}
if ( legendPath.isEmpty() ) {
legendPath = MarbleDirs::path(QStringLiteral("legend.html"));
}
QString finalHtml = readHtml( QUrl::fromLocalFile( legendPath ) );
TemplateDocument doc(finalHtml);
finalHtml = doc.finalText();
reverseSupportCheckboxes(finalHtml);
// Generate some parts of the html from the MapTheme <Legend> tag.
const QString sectionsHtml = generateSectionsHtml();
// And then create the final html from these two parts.
finalHtml.replace( QString( "<!-- ##customLegendEntries:all## -->" ), sectionsHtml );
translateHtml( finalHtml );
QUrl baseUrl = QUrl::fromLocalFile( legendPath );
// Set the html string in the QTextBrowser.
setHtml(finalHtml, baseUrl);
QTextDocument *document = new QTextDocument(page()->mainFrame()->toHtml());
d->m_marbleModel->setLegend( document );
#endif
}
void MarbleLegendBrowser::injectCheckBoxChecker()
{
#ifndef MARBLE_NO_WEBKITWIDGETS
QWebFrame *frame = page()->mainFrame();
frame->addToJavaScriptWindowObject( "Marble", this );
#endif
}
void MarbleLegendBrowser::openLinkExternally( const QUrl &url )
{
if (url.scheme() == QLatin1String("tour")) {
emit tourLinkClicked(QLatin1String("maps/") + url.host() + url.path());
} else {
QDesktopServices::openUrl( url );
}
}
bool MarbleLegendBrowser::event( QEvent * event )
{
// "Delayed initialization": legend gets created only
if ( event->type() == QEvent::Show ) {
loadLegend();
return true;
}
return MarbleWebView::event( event );
}
QString MarbleLegendBrowser::readHtml( const QUrl & name )
{
QString html;
QFile data( name.toLocalFile() );
if ( data.open( QFile::ReadOnly ) ) {
QTextStream in( &data );
html = in.readAll();
data.close();
}
return html;
}
void MarbleLegendBrowser::translateHtml( QString & html )
{
// must match string extraction in Messages.sh
// TODO: html.remove also changes html, is that intended?
QString s = html.remove(0, html.indexOf(QLatin1String("<body>")));
QRegExp rx( "</?\\w+((\\s+\\w+(\\s*=\\s*(?:\".*\"|'.*'|[^'\">\\s]+))?)+\\s*|\\s*)/?>" );
rx.setMinimal( true );
s.replace( rx, "\n" );
s.replace( QRegExp( "\\s*\n\\s*" ), "\n" );
const QStringList words = s.split(QLatin1Char('\n'), QString::SkipEmptyParts);
QStringList::const_iterator i = words.constBegin();
QStringList::const_iterator const end = words.constEnd();
for (; i != end; ++i )
html.replace(*i, QCoreApplication::translate("Legends", (*i).toUtf8().constData()));
}
void MarbleLegendBrowser::reverseSupportCheckboxes(QString &html)
{
const QString old = "<a href=\"checkbox:cities\"/>";
QString checked;
if (d->m_checkBoxMap["cities"])
checked = "checked";
const QString repair = QLatin1String(
"<input type=\"checkbox\" "
"onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ") + checked + QLatin1String(" name=\"cities\"/>");
html.replace(old, repair);
}
QString MarbleLegendBrowser::generateSectionsHtml()
{
// Generate HTML to include into legend.html here.
QString customLegendString;
- if ( d->m_marbleModel == 0 || d->m_marbleModel->mapTheme() == 0 )
+ if ( d->m_marbleModel == nullptr || d->m_marbleModel->mapTheme() == nullptr )
return QString();
const GeoSceneDocument *currentMapTheme = d->m_marbleModel->mapTheme();
d->m_symbolMap.clear();
/* Okay, if you are reading it now, be ready for hell!
* We can't optimize this part of Legend Browser, but we will
* do it, anyway. It's complicated a lot, the most important
* thing is to understand everything.
*/
for ( const GeoSceneSection *section: currentMapTheme->legend()->sections() ) {
// Each section is divided into the "well"
// Well is like a block of data with rounded corners
customLegendString += QLatin1String("<div class=\"well well-small well-legend\">");
const QString heading = QCoreApplication::translate("DGML", section->heading().toUtf8().constData());
QString checkBoxString;
if (section->checkable()) {
// If it's needed to make a checkbox here, we will
QString const checked = d->m_checkBoxMap[section->connectTo()] ? "checked" : "";
/* Important comment:
* We inject Marble object into JavaScript of each legend html file
* This is only one way to handle checkbox changes we see, so
* Marble.setCheckedProperty is a function that does it
*/
if(!section->radio().isEmpty()) {
checkBoxString = QLatin1String(
"<label class=\"section-head\">"
"<input type=\"radio\" "
"onchange=\"Marble.setRadioCheckedProperty(this.value, this.name ,this.checked);\" ") +
checked + QLatin1String(" value=\"") + section->connectTo() + QLatin1String("\" name=\"") + section->radio() + QLatin1String("\" /><span>")
+ heading +
QLatin1String("</span></label>");
} else {
checkBoxString = QLatin1String(
"<label class=\"section-head\">"
"<input type=\"checkbox\" "
"onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ") + checked + QLatin1String(" name=\"") + section->connectTo() + QLatin1String("\" /><span>")
+ heading +
QLatin1String("</span></label>");
}
customLegendString += checkBoxString;
} else {
customLegendString += QLatin1String("<h4 class=\"section-head\">") + heading + QLatin1String("</h4>");
}
for (const GeoSceneItem *item: section->items()) {
// checkbox for item
QString checkBoxString;
if (item->checkable()) {
QString const checked = d->m_checkBoxMap[item->connectTo()] ? "checked" : "";
checkBoxString = QLatin1String(
"<input type=\"checkbox\" "
"onchange=\"Marble.setCheckedProperty(this.name, this.checked);\" ")
+ checked + QLatin1String(" name=\"") + item->connectTo() + QLatin1String("\" />");
}
// pixmap and text
QString src;
QString styleDiv;
int pixmapWidth = 24;
int pixmapHeight = 12;
if (!item->icon()->pixmap().isEmpty()) {
QString path = MarbleDirs::path( item->icon()->pixmap() );
const QPixmap oncePixmap(path);
pixmapWidth = oncePixmap.width();
pixmapHeight = oncePixmap.height();
src = QUrl::fromLocalFile( path ).toString();
styleDiv = QLatin1String("width: ") + QString::number(pixmapWidth) + QLatin1String("px; height: ") +
QString::number(pixmapHeight) + QLatin1String("px;");
}
// NOTICE. There are some pixmaps without image, so we should
// create just a plain rectangle with set color
else if (item->icon()->color().isValid()) {
const QColor color = item->icon()->color();
styleDiv = QLatin1String("width: ") + QString::number(pixmapWidth) + QLatin1String("px; height: ") +
QString::number(pixmapHeight) + QLatin1String("px; background-color: ") + color.name() + QLatin1Char(';');
}
const QString text = QCoreApplication::translate("DGML", item->text().toUtf8().constData());
QString html = QLatin1String(
"<div class=\"legend-entry\">"
" <label>") + checkBoxString + QLatin1String(
" <img class=\"image-pic\" src=\"") + src + QLatin1String("\" style=\"") + styleDiv + QLatin1String("\"/>"
" <span class=\"notation\">") + text + QLatin1String("</span>"
" </label>"
"</div>");
customLegendString += html;
}
customLegendString += QLatin1String("</div>"); // <div class="well">
}
return customLegendString;
}
void MarbleLegendBrowser::setCheckedProperty( const QString& name, bool checked )
{
#ifndef MARBLE_NO_WEBKITWIDGETS
QWebElement box = page()->mainFrame()->findFirstElement(QLatin1String("input[name=") + name + QLatin1Char(']'));
if (!box.isNull()) {
if (checked != d->m_checkBoxMap[name]) {
d->m_checkBoxMap[name] = checked;
emit toggledShowProperty( name, checked );
}
}
update();
#endif
}
void MarbleLegendBrowser::setRadioCheckedProperty( const QString& value, const QString& name , bool checked )
{
#ifndef MARBLE_NO_WEBKITWIDGETS
QWebElement box = page()->mainFrame()->findFirstElement(QLatin1String("input[value=") + value + QLatin1Char(']'));
QWebElementCollection boxes = page()->mainFrame()->findAllElements(QLatin1String("input[name=") + name + QLatin1Char(']'));
QString currentValue;
for(int i=0; i<boxes.count(); ++i) {
currentValue = boxes.at(i).attribute("value");
d->m_checkBoxMap[currentValue]=false;
emit toggledShowProperty( currentValue, false );
}
if (!box.isNull()) {
if (checked != d->m_checkBoxMap[value]) {
d->m_checkBoxMap[value] = checked;
emit toggledShowProperty( value, checked );
}
}
update();
#endif
}
}
#include "moc_MarbleLegendBrowser.cpp"
diff --git a/src/lib/marble/MarbleLineEdit.cpp b/src/lib/marble/MarbleLineEdit.cpp
index c122e7566..32f8ca9a4 100644
--- a/src/lib/marble/MarbleLineEdit.cpp
+++ b/src/lib/marble/MarbleLineEdit.cpp
@@ -1,211 +1,211 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// The code in this file is largely based on KDE's KLineEdit class
// as included in KDE 4.5. See there for its authors:
// http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/klineedit_8cpp.html
//
// Copyright 2010,2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "MarbleLineEdit.h"
#include "MarbleGlobal.h"
#include <QApplication>
#include <QClipboard>
#include <QLabel>
#include <QStyle>
#include <QMouseEvent>
#include <QPainter>
#include <QTimer>
namespace Marble
{
class MarbleLineEditPrivate
{
public:
QLabel* m_clearButton;
QLabel* m_decoratorButton;
QPixmap m_clearPixmap;
QPixmap m_decoratorPixmap;
QTimer m_progressTimer;
QVector<QPixmap> m_progressAnimation;
int m_currentFrame;
int m_iconSize;
explicit MarbleLineEditPrivate( MarbleLineEdit* parent );
void createProgressAnimation();
};
MarbleLineEditPrivate::MarbleLineEditPrivate( MarbleLineEdit* parent ) :
m_clearButton( new QLabel( parent ) ), m_decoratorButton( new QLabel( parent ) ),
m_currentFrame( 0 ), m_iconSize( 16 )
{
m_clearButton->setCursor( Qt::ArrowCursor );
m_clearButton->setToolTip( QObject::tr( "Clear" ) );
m_decoratorButton->setCursor( Qt::ArrowCursor );
createProgressAnimation();
m_progressTimer.setInterval( 100 );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
m_iconSize = 32;
}
}
void MarbleLineEditPrivate::createProgressAnimation()
{
// Size parameters
qreal const h = m_iconSize / 2.0; // Half of the icon size
qreal const q = h / 2.0; // Quarter of the icon size
qreal const d = 7.5; // Circle diameter
qreal const r = d / 2.0; // Circle radius
// Canvas parameters
QImage canvas( m_iconSize, m_iconSize, QImage::Format_ARGB32 );
QPainter painter( &canvas );
painter.setRenderHint( QPainter::Antialiasing, true );
painter.setPen( QColor ( Qt::gray ) );
painter.setBrush( QColor( Qt::white ) );
// Create all frames
for( double t = 0.0; t < 2 * M_PI; t += M_PI / 8.0 ) {
canvas.fill( Qt::transparent );
QRectF firstCircle( h - r + q * cos( t ), h - r + q * sin( t ), d, d );
QRectF secondCircle( h - r + q * cos( t + M_PI ), h - r + q * sin( t + M_PI ), d, d );
painter.drawEllipse( firstCircle );
painter.drawEllipse( secondCircle );
m_progressAnimation.push_back( QPixmap::fromImage( canvas ) );
}
}
MarbleLineEdit::MarbleLineEdit( QWidget *parent ) :
QLineEdit( parent ), d( new MarbleLineEditPrivate( this ) )
{
updateClearButtonIcon( text() );
updateClearButton();
setDecorator( d->m_decoratorPixmap );
connect( this, SIGNAL(textChanged(QString)),
SLOT(updateClearButtonIcon(QString)) );
connect( &d->m_progressTimer, SIGNAL(timeout()),
this, SLOT(updateProgress()) );
}
MarbleLineEdit::~MarbleLineEdit()
{
delete d;
}
void MarbleLineEdit::setDecorator(const QPixmap &decorator)
{
d->m_decoratorPixmap = decorator;
d->m_decoratorButton->setPixmap( d->m_decoratorPixmap );
int const padding = 2 + d->m_decoratorPixmap.width();
QString const prefixDirection = layoutDirection() == Qt::LeftToRight ? "left" : "right";
QString decoratorStyleSheet;
if ( !d->m_decoratorPixmap.isNull() ) {
decoratorStyleSheet = QString( "; padding-%1: %2" ).arg( prefixDirection ).arg( padding );
}
// Padding for clear button to avoid text underflow
QString const postfixDirection = layoutDirection() == Qt::LeftToRight ? "right" : "left";
QString styleSheet = QString( ":enabled { padding-%1: %2; %3}").arg( postfixDirection ).arg( padding ).arg( decoratorStyleSheet );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( !smallScreen ) {
setStyleSheet( styleSheet );
}
}
void MarbleLineEdit::setBusy(bool busy)
{
if ( busy ) {
d->m_progressTimer.start();
} else {
d->m_progressTimer.stop();
d->m_decoratorButton->setPixmap( d->m_decoratorPixmap );
}
}
void MarbleLineEdit::updateClearButtonIcon( const QString& text )
{
d->m_clearButton->setVisible( text.length() > 0 );
if ( d->m_clearButton->pixmap() && !d->m_clearButton->pixmap()->isNull() ) {
return;
}
QString const direction = layoutDirection() == Qt::LeftToRight ? "rtl" : "ltr";
int const size = (MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen) ? 32 : 16;
QPixmap pixmap = QPixmap(QStringLiteral(":/icons/%1x%1/edit-clear-locationbar-%2.png").arg(size).arg(direction));
d->m_clearButton->setPixmap( pixmap );
}
void MarbleLineEdit::updateClearButton()
{
const QSize geom = size();
- const int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth, 0, this );
+ const int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth, nullptr, this );
const int pixmapSize = d->m_clearButton->pixmap()->width() + 1;
const int decoratorSize = d->m_decoratorPixmap.width() + 1;
int y = ( geom.height() - pixmapSize ) / 2;
if ( layoutDirection() == Qt::LeftToRight ) {
d->m_clearButton->move( geom.width() - frameWidth - pixmapSize - decoratorSize, y );
d->m_decoratorButton->move( frameWidth - decoratorSize + 1, y );
} else {
d->m_clearButton->move( frameWidth - decoratorSize + 1, y );
d->m_decoratorButton->move( geom.width() - frameWidth - pixmapSize - decoratorSize, y );
}
}
void MarbleLineEdit::updateProgress()
{
if ( !d->m_progressAnimation.isEmpty() ) {
d->m_currentFrame = ( d->m_currentFrame + 1 ) % d->m_progressAnimation.size();
QPixmap frame = d->m_progressAnimation[d->m_currentFrame];
d->m_decoratorButton->setPixmap( frame );
}
}
void MarbleLineEdit::mouseReleaseEvent( QMouseEvent* e )
{
if ( d->m_clearButton == childAt( e->pos() ) ) {
QString newText;
if ( e->button() == Qt::MidButton ) {
newText = QApplication::clipboard()->text( QClipboard::Selection );
setText( newText );
} else {
setSelection( 0, text().size() );
del();
emit clearButtonClicked();
}
emit textChanged( newText );
}
if ( d->m_decoratorButton == childAt( e->pos() ) ) {
emit decoratorButtonClicked();
}
QLineEdit::mouseReleaseEvent( e );
}
void MarbleLineEdit::resizeEvent( QResizeEvent * event )
{
updateClearButton();
QLineEdit::resizeEvent( event );
}
} // namespace Marble
#include "moc_MarbleLineEdit.cpp"
diff --git a/src/lib/marble/MarbleLineEdit.h b/src/lib/marble/MarbleLineEdit.h
index 7b5dd0657..9944201ca 100644
--- a/src/lib/marble/MarbleLineEdit.h
+++ b/src/lib/marble/MarbleLineEdit.h
@@ -1,71 +1,71 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// The code in this file is largely based on KDE's KLineEdit class
// as included in KDE 4.5. See there for its authors:
// http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/klineedit_8cpp.html
//
// Copyright 2010,2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_MARBLELINEEDIT_H
#define MARBLE_MARBLELINEEDIT_H
#include "marble_export.h"
#include <QLineEdit>
namespace Marble
{
class MarbleLineEditPrivate;
/**
* A QLineEdit with an embedded clear button. The clear button removes any input
* in the line edit when clicked with the left mouse button. It replaces the line
* edit input with the current clipboard content on a middle mouse button click.
*/
class MARBLE_EXPORT MarbleLineEdit : public QLineEdit
{
Q_OBJECT
public:
/** Constructor */
- explicit MarbleLineEdit( QWidget *parent = 0 );
+ explicit MarbleLineEdit( QWidget *parent = nullptr );
/** Destructor */
~MarbleLineEdit() override;
void setDecorator( const QPixmap &decorator );
void setBusy( bool busy );
Q_SIGNALS:
/** The clear button was clicked with the left mouse button */
void clearButtonClicked();
void decoratorButtonClicked();
protected:
void mouseReleaseEvent( QMouseEvent* event ) override;
void resizeEvent( QResizeEvent* event ) override;
private Q_SLOTS:
void updateClearButtonIcon( const QString& text );
void updateClearButton();
void updateProgress();
private:
MarbleLineEditPrivate* const d;
};
} // namespace Marble
#endif // MARBLE_MARBLELINEEDIT_H
diff --git a/src/lib/marble/MarbleMap.cpp b/src/lib/marble/MarbleMap.cpp
index cb19e7356..3bc8ab02b 100644
--- a/src/lib/marble/MarbleMap.cpp
+++ b/src/lib/marble/MarbleMap.cpp
@@ -1,1492 +1,1492 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2009 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008 Carlos Licea <carlos.licea@kdemail.net>
// Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
// Own
#include "MarbleMap.h"
// Posix
#include <cmath>
// Qt
#include <QTime>
#include <QRegion>
#include <QtMath>
// Marble
#include "layers/FloatItemsLayer.h"
#include "layers/FogLayer.h"
#include "layers/FpsLayer.h"
#include "layers/GeometryLayer.h"
#include "layers/GroundLayer.h"
#include "layers/MarbleSplashLayer.h"
#include "layers/PlacemarkLayer.h"
#include "layers/TextureLayer.h"
#include "layers/VectorTileLayer.h"
#include "AbstractFloatItem.h"
#include "DgmlAuxillaryDictionary.h"
#include "FileManager.h"
#include "GeoDataTreeModel.h"
#include "GeoPainter.h"
#include "GeoSceneDocument.h"
#include "GeoSceneFilter.h"
#include "GeoSceneGeodata.h"
#include "GeoSceneHead.h"
#include "GeoSceneLayer.h"
#include "GeoSceneMap.h"
#include "GeoScenePalette.h"
#include "GeoSceneSettings.h"
#include "GeoSceneVector.h"
#include "GeoSceneVectorTileDataset.h"
#include "GeoSceneTextureTileDataset.h"
#include "GeoSceneZoom.h"
#include "GeoDataDocument.h"
#include "GeoDataFeature.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "LayerManager.h"
#include "MapThemeManager.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "PluginManager.h"
#include "RenderPlugin.h"
#include "StyleBuilder.h"
#include "SunLocator.h"
#include "TileId.h"
#include "TileCoordsPyramid.h"
#include "TileCreator.h"
#include "TileCreatorDialog.h"
#include "TileLoader.h"
#include "ViewParams.h"
#include "ViewportParams.h"
#include "RenderState.h"
#include "BookmarkManager.h"
namespace Marble
{
class MarbleMap::CustomPaintLayer : public LayerInterface
{
public:
explicit CustomPaintLayer( MarbleMap *map )
: m_map( map )
{
}
QStringList renderPosition() const override { return QStringList() << "USER_TOOLS"; }
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos, GeoSceneLayer *layer ) override
{
Q_UNUSED( viewport );
Q_UNUSED( renderPos );
Q_UNUSED( layer );
m_map->customPaint( painter );
return true;
}
qreal zValue() const override { return 1.0e6; }
RenderState renderState() const override { return RenderState(QStringLiteral("Custom Map Paint")); }
QString runtimeTrace() const override { return QStringLiteral("CustomPaint"); }
private:
MarbleMap *const m_map;
};
class MarbleMapPrivate
{
friend class MarbleWidget;
public:
explicit MarbleMapPrivate( MarbleMap *parent, MarbleModel *model );
void updateMapTheme();
void updateProperty( const QString &, bool );
void setDocument( const QString& key );
void updateTileLevel();
void addPlugins();
MarbleMap *const q;
// The model we are showing.
MarbleModel *const m_model;
bool m_modelIsOwned;
// Parameters for the maps appearance.
ViewParams m_viewParams;
ViewportParams m_viewport;
bool m_showFrameRate;
bool m_showDebugPolygons;
bool m_showDebugBatchRender;
GeoDataRelation::RelationTypes m_visibleRelationTypes;
StyleBuilder m_styleBuilder;
QList<RenderPlugin *> m_renderPlugins;
LayerManager m_layerManager;
MarbleSplashLayer m_marbleSplashLayer;
MarbleMap::CustomPaintLayer m_customPaintLayer;
GeometryLayer m_geometryLayer;
FloatItemsLayer m_floatItemsLayer;
FogLayer m_fogLayer;
GroundLayer m_groundLayer;
TextureLayer m_textureLayer;
PlacemarkLayer m_placemarkLayer;
VectorTileLayer m_vectorTileLayer;
bool m_isLockedToSubSolarPoint;
bool m_isSubSolarPointIconVisible;
RenderState m_renderState;
};
MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) :
q( parent ),
m_model( model ),
m_viewParams(),
m_showFrameRate( false ),
m_showDebugPolygons( false ),
m_showDebugBatchRender( false ),
m_visibleRelationTypes(GeoDataRelation::RouteFerry),
m_styleBuilder(),
m_layerManager( parent ),
m_customPaintLayer( parent ),
m_geometryLayer(model->treeModel(), &m_styleBuilder),
m_floatItemsLayer(parent),
m_textureLayer( model->downloadManager(), model->pluginManager(), model->sunLocator(), model->groundOverlayModel() ),
m_placemarkLayer( model->placemarkModel(), model->placemarkSelectionModel(), model->clock(), &m_styleBuilder ),
m_vectorTileLayer( model->downloadManager(), model->pluginManager(), model->treeModel() ),
m_isLockedToSubSolarPoint( false ),
m_isSubSolarPointIconVisible( false )
{
m_layerManager.addLayer(&m_floatItemsLayer);
m_layerManager.addLayer( &m_fogLayer );
m_layerManager.addLayer( &m_groundLayer );
m_layerManager.addLayer( &m_geometryLayer );
m_layerManager.addLayer( &m_placemarkLayer );
m_layerManager.addLayer( &m_customPaintLayer );
m_model->bookmarkManager()->setStyleBuilder(&m_styleBuilder);
QObject::connect( m_model, SIGNAL(themeChanged(QString)),
parent, SLOT(updateMapTheme()) );
QObject::connect( m_model->fileManager(), SIGNAL(fileAdded(QString)),
parent, SLOT(setDocument(QString)) );
QObject::connect( &m_placemarkLayer, SIGNAL(repaintNeeded()),
parent, SIGNAL(repaintNeeded()));
QObject::connect ( &m_layerManager, SIGNAL(pluginSettingsChanged()),
parent, SIGNAL(pluginSettingsChanged()) );
QObject::connect ( &m_layerManager, SIGNAL(repaintNeeded(QRegion)),
parent, SIGNAL(repaintNeeded(QRegion)) );
QObject::connect ( &m_layerManager, SIGNAL(renderPluginInitialized(RenderPlugin*)),
parent, SIGNAL(renderPluginInitialized(RenderPlugin*)) );
QObject::connect ( &m_layerManager, SIGNAL(visibilityChanged(QString,bool)),
parent, SLOT(setPropertyValue(QString,bool)) );
QObject::connect( &m_geometryLayer, SIGNAL(repaintNeeded()),
parent, SIGNAL(repaintNeeded()));
/*
* Slot handleHighlight finds all placemarks
* that contain the clicked point.
* The placemarks under the clicked position may
* have their styleUrl set to a style map which
* doesn't specify any highlight styleId. Such
* placemarks will be fletered out in GeoGraphicsScene
* and will not be highlighted.
*/
QObject::connect( parent, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
&m_geometryLayer, SLOT(handleHighlight(qreal,qreal,GeoDataCoordinates::Unit)) );
QObject::connect(&m_floatItemsLayer, SIGNAL(repaintNeeded(QRegion)),
parent, SIGNAL(repaintNeeded(QRegion)));
QObject::connect(&m_floatItemsLayer, SIGNAL(renderPluginInitialized(RenderPlugin*)),
parent, SIGNAL(renderPluginInitialized(RenderPlugin*)));
QObject::connect(&m_floatItemsLayer, SIGNAL(visibilityChanged(QString,bool)),
parent, SLOT(setPropertyValue(QString,bool)));
QObject::connect(&m_floatItemsLayer, SIGNAL(pluginSettingsChanged()),
parent, SIGNAL(pluginSettingsChanged()));
QObject::connect( &m_textureLayer, SIGNAL(tileLevelChanged(int)),
parent, SLOT(updateTileLevel()) );
QObject::connect( &m_vectorTileLayer, SIGNAL(tileLevelChanged(int)),
parent, SLOT(updateTileLevel()) );
QObject::connect( parent, SIGNAL(radiusChanged(int)),
parent, SLOT(updateTileLevel()) );
QObject::connect( &m_textureLayer, SIGNAL(repaintNeeded()),
parent, SIGNAL(repaintNeeded()) );
QObject::connect( parent, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
parent, SIGNAL(repaintNeeded()) );
addPlugins();
QObject::connect(model->pluginManager(), SIGNAL(renderPluginsChanged()),
parent, SLOT(addPlugins()));
}
void MarbleMapPrivate::updateProperty( const QString &name, bool show )
{
// earth
if (name == QLatin1String("places")) {
m_placemarkLayer.setShowPlaces( show );
} else if (name == QLatin1String("cities")) {
m_placemarkLayer.setShowCities( show );
} else if (name == QLatin1String("terrain")) {
m_placemarkLayer.setShowTerrain( show );
} else if (name == QLatin1String("otherplaces")) {
m_placemarkLayer.setShowOtherPlaces( show );
}
// other planets
else if (name == QLatin1String("landingsites")) {
m_placemarkLayer.setShowLandingSites( show );
} else if (name == QLatin1String("craters")) {
m_placemarkLayer.setShowCraters( show );
} else if (name == QLatin1String("maria")) {
m_placemarkLayer.setShowMaria( show );
}
else if (name == QLatin1String("relief")) {
m_textureLayer.setShowRelief( show );
}
for(RenderPlugin *renderPlugin: m_renderPlugins) {
if ( name == renderPlugin->nameId() ) {
if ( renderPlugin->visible() == show ) {
break;
}
renderPlugin->setVisible( show );
break;
}
}
}
void MarbleMapPrivate::addPlugins()
{
for (const RenderPlugin *factory: m_model->pluginManager()->renderPlugins()) {
bool alreadyCreated = false;
for(const RenderPlugin *existing: m_renderPlugins) {
if (existing->nameId() == factory->nameId()) {
alreadyCreated = true;
break;
}
}
if (alreadyCreated) {
continue;
}
RenderPlugin *const renderPlugin = factory->newInstance(m_model);
Q_ASSERT(renderPlugin && "Plugin must not return null when requesting a new instance.");
m_renderPlugins << renderPlugin;
if (AbstractFloatItem *const floatItem = qobject_cast<AbstractFloatItem *>(renderPlugin)) {
m_floatItemsLayer.addFloatItem(floatItem);
}
else {
m_layerManager.addRenderPlugin(renderPlugin);
}
}
}
// ----------------------------------------------------------------
MarbleMap::MarbleMap()
: d( new MarbleMapPrivate( this, new MarbleModel( this ) ) )
{
// nothing to do
}
MarbleMap::MarbleMap(MarbleModel *model)
: d( new MarbleMapPrivate( this, model ) )
{
d->m_modelIsOwned = false;
}
MarbleMap::~MarbleMap()
{
- MarbleModel *model = d->m_modelIsOwned ? d->m_model : 0;
+ MarbleModel *model = d->m_modelIsOwned ? d->m_model : nullptr;
d->m_layerManager.removeLayer( &d->m_customPaintLayer );
d->m_layerManager.removeLayer( &d->m_geometryLayer );
d->m_layerManager.removeLayer(&d->m_floatItemsLayer);
d->m_layerManager.removeLayer( &d->m_fogLayer );
d->m_layerManager.removeLayer( &d->m_placemarkLayer );
d->m_layerManager.removeLayer( &d->m_textureLayer );
d->m_layerManager.removeLayer( &d->m_groundLayer );
qDeleteAll(d->m_renderPlugins);
delete d;
delete model; // delete the model after private data
}
MarbleModel *MarbleMap::model() const
{
return d->m_model;
}
ViewportParams *MarbleMap::viewport()
{
return &d->m_viewport;
}
const ViewportParams *MarbleMap::viewport() const
{
return &d->m_viewport;
}
void MarbleMap::setMapQualityForViewContext( MapQuality quality, ViewContext viewContext )
{
d->m_viewParams.setMapQualityForViewContext( quality, viewContext );
// Update texture map during the repaint that follows:
d->m_textureLayer.setNeedsUpdate();
}
MapQuality MarbleMap::mapQuality( ViewContext viewContext ) const
{
return d->m_viewParams.mapQuality( viewContext );
}
MapQuality MarbleMap::mapQuality() const
{
return d->m_viewParams.mapQuality();
}
void MarbleMap::setViewContext( ViewContext viewContext )
{
if ( d->m_viewParams.viewContext() == viewContext ) {
return;
}
const MapQuality oldQuality = d->m_viewParams.mapQuality();
d->m_viewParams.setViewContext( viewContext );
emit viewContextChanged( viewContext );
if ( d->m_viewParams.mapQuality() != oldQuality ) {
// Update texture map during the repaint that follows:
d->m_textureLayer.setNeedsUpdate();
emit repaintNeeded();
}
}
ViewContext MarbleMap::viewContext() const
{
return d->m_viewParams.viewContext();
}
void MarbleMap::setSize( int width, int height )
{
setSize( QSize( width, height ) );
}
void MarbleMap::setSize( const QSize& size )
{
d->m_viewport.setSize( size );
emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
}
QSize MarbleMap::size() const
{
return QSize( d->m_viewport.width(), d->m_viewport.height() );
}
int MarbleMap::width() const
{
return d->m_viewport.width();
}
int MarbleMap::height() const
{
return d->m_viewport.height();
}
int MarbleMap::radius() const
{
return d->m_viewport.radius();
}
void MarbleMap::setRadius( int radius )
{
const int oldRadius = d->m_viewport.radius();
d->m_viewport.setRadius( radius );
if ( oldRadius != d->m_viewport.radius() ) {
emit radiusChanged( radius );
emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
}
}
int MarbleMap::preferredRadiusCeil(int radius) const
{
return d->m_textureLayer.preferredRadiusCeil( radius );
}
int MarbleMap::preferredRadiusFloor(int radius) const
{
return d->m_textureLayer.preferredRadiusFloor( radius );
}
int MarbleMap::tileZoomLevel() const
{
auto const tileZoomLevel = qMax(d->m_textureLayer.tileZoomLevel(), d->m_vectorTileLayer.tileZoomLevel());
return tileZoomLevel >= 0 ? tileZoomLevel : qMin<int>(qMax<int>(qLn(d->m_viewport.radius()*4/256)/qLn(2.0), 1), d->m_styleBuilder.maximumZoomLevel());
}
qreal MarbleMap::centerLatitude() const
{
// Calculate translation of center point
const qreal centerLat = d->m_viewport.centerLatitude();
return centerLat * RAD2DEG;
}
bool MarbleMap::hasFeatureAt(const QPoint &position) const
{
return d->m_placemarkLayer.hasPlacemarkAt(position) || d->m_geometryLayer.hasFeatureAt(position, viewport());
}
qreal MarbleMap::centerLongitude() const
{
// Calculate translation of center point
const qreal centerLon = d->m_viewport.centerLongitude();
return centerLon * RAD2DEG;
}
int MarbleMap::minimumZoom() const
{
if ( d->m_model->mapTheme() )
return d->m_model->mapTheme()->head()->zoom()->minimum();
return 950;
}
int MarbleMap::maximumZoom() const
{
if ( d->m_model->mapTheme() )
return d->m_model->mapTheme()->head()->zoom()->maximum();
return 2100;
}
bool MarbleMap::discreteZoom() const
{
if ( d->m_model->mapTheme() )
return d->m_model->mapTheme()->head()->zoom()->discrete();
return false;
}
QVector<const GeoDataFeature*> MarbleMap::whichFeatureAt( const QPoint& curpos ) const
{
return d->m_placemarkLayer.whichPlacemarkAt( curpos ) + d->m_geometryLayer.whichFeatureAt( curpos, viewport() );
}
void MarbleMap::reload()
{
d->m_textureLayer.reload();
d->m_vectorTileLayer.reload();
}
void MarbleMap::downloadRegion( QVector<TileCoordsPyramid> const & pyramid )
{
Q_ASSERT( textureLayer() );
Q_ASSERT( !pyramid.isEmpty() );
QTime t;
t.start();
// When downloading a region (the author of these lines thinks) most users probably expect
// the download to begin with the low resolution tiles and then procede level-wise to
// higher resolution tiles. In order to achieve this, we start requesting downloads of
// high resolution tiles and request the low resolution tiles at the end because
// DownloadQueueSet (silly name) is implemented as stack.
int const first = 0;
int tilesCount = 0;
for ( int level = pyramid[first].bottomLevel(); level >= pyramid[first].topLevel(); --level ) {
QSet<TileId> tileIdSet;
for( int i = 0; i < pyramid.size(); ++i ) {
QRect const coords = pyramid[i].coords( level );
mDebug() << "MarbleMap::downloadRegion level:" << level << "tile coords:" << coords;
int x1, y1, x2, y2;
coords.getCoords( &x1, &y1, &x2, &y2 );
for ( int x = x1; x <= x2; ++x ) {
for ( int y = y1; y <= y2; ++y ) {
TileId const stackedTileId( 0, level, x, y );
tileIdSet.insert( stackedTileId );
// FIXME: use lazy evaluation to not generate up to 100k tiles in one go
// this can take considerable time even on very fast systems
// in contrast generating the TileIds on the fly when they are needed
// does not seem to affect download speed.
}
}
}
QSetIterator<TileId> i( tileIdSet );
while( i.hasNext() ) {
TileId const tileId = i.next();
d->m_textureLayer.downloadStackedTile( tileId );
}
tilesCount += tileIdSet.count();
}
// Needed for downloading unique tiles only. Much faster than if tiles for each level is downloaded separately
int const elapsedMs = t.elapsed();
mDebug() << "MarbleMap::downloadRegion:" << tilesCount << "tiles, " << elapsedMs << "ms";
}
void MarbleMap::highlightRouteRelation(qint64 osmId, bool enabled)
{
d->m_geometryLayer.highlightRouteRelation(osmId, enabled);
}
bool MarbleMap::propertyValue( const QString& name ) const
{
bool value;
if ( d->m_model->mapTheme() ) {
d->m_model->mapTheme()->settings()->propertyValue( name, value );
}
else {
value = false;
mDebug() << "WARNING: Failed to access a map theme! Property: " << name;
}
return value;
}
bool MarbleMap::showOverviewMap() const
{
return propertyValue(QStringLiteral("overviewmap"));
}
bool MarbleMap::showScaleBar() const
{
return propertyValue(QStringLiteral("scalebar"));
}
bool MarbleMap::showCompass() const
{
return propertyValue(QStringLiteral("compass"));
}
bool MarbleMap::showGrid() const
{
return propertyValue(QStringLiteral("coordinate-grid"));
}
bool MarbleMap::showClouds() const
{
return d->m_viewParams.showClouds();
}
bool MarbleMap::showSunShading() const
{
return d->m_textureLayer.showSunShading();
}
bool MarbleMap::showCityLights() const
{
return d->m_textureLayer.showCityLights();
}
bool MarbleMap::isLockedToSubSolarPoint() const
{
return d->m_isLockedToSubSolarPoint;
}
bool MarbleMap::isSubSolarPointIconVisible() const
{
return d->m_isSubSolarPointIconVisible;
}
bool MarbleMap::showAtmosphere() const
{
return d->m_viewParams.showAtmosphere();
}
bool MarbleMap::showCrosshairs() const
{
bool visible = false;
QList<RenderPlugin *> pluginList = renderPlugins();
QList<RenderPlugin *>::const_iterator i = pluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
for (; i != end; ++i ) {
if ((*i)->nameId() == QLatin1String("crosshairs")) {
visible = (*i)->visible();
}
}
return visible;
}
bool MarbleMap::showPlaces() const
{
return propertyValue(QStringLiteral("places"));
}
bool MarbleMap::showCities() const
{
return propertyValue(QStringLiteral("cities"));
}
bool MarbleMap::showTerrain() const
{
return propertyValue(QStringLiteral("terrain"));
}
bool MarbleMap::showOtherPlaces() const
{
return propertyValue(QStringLiteral("otherplaces"));
}
bool MarbleMap::showRelief() const
{
return propertyValue(QStringLiteral("relief"));
}
bool MarbleMap::showIceLayer() const
{
return propertyValue(QStringLiteral("ice"));
}
bool MarbleMap::showBorders() const
{
return propertyValue(QStringLiteral("borders"));
}
bool MarbleMap::showRivers() const
{
return propertyValue(QStringLiteral("rivers"));
}
bool MarbleMap::showLakes() const
{
return propertyValue(QStringLiteral("lakes"));
}
bool MarbleMap::showFrameRate() const
{
return d->m_showFrameRate;
}
bool MarbleMap::showBackground() const
{
return d->m_layerManager.showBackground();
}
GeoDataRelation::RelationTypes MarbleMap::visibleRelationTypes() const
{
return d->m_visibleRelationTypes;
}
quint64 MarbleMap::volatileTileCacheLimit() const
{
return d->m_textureLayer.volatileCacheLimit();
}
void MarbleMap::rotateBy(qreal deltaLon, qreal deltaLat)
{
centerOn( d->m_viewport.centerLongitude() * RAD2DEG + deltaLon,
d->m_viewport.centerLatitude() * RAD2DEG + deltaLat );
}
void MarbleMap::centerOn( const qreal lon, const qreal lat )
{
d->m_viewport.centerOn( lon * DEG2RAD, lat * DEG2RAD );
emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
}
void MarbleMap::setCenterLatitude( qreal lat )
{
centerOn( centerLongitude(), lat );
}
void MarbleMap::setCenterLongitude( qreal lon )
{
centerOn( lon, centerLatitude() );
}
Projection MarbleMap::projection() const
{
return d->m_viewport.projection();
}
void MarbleMap::setProjection( Projection projection )
{
if ( d->m_viewport.projection() == projection )
return;
emit projectionChanged( projection );
d->m_viewport.setProjection( projection );
d->m_textureLayer.setProjection( projection );
emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
}
bool MarbleMap::screenCoordinates( qreal lon, qreal lat,
qreal& x, qreal& y ) const
{
return d->m_viewport.screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, x, y );
}
bool MarbleMap::geoCoordinates( int x, int y,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit ) const
{
return d->m_viewport.geoCoordinates( x, y, lon, lat, unit );
}
void MarbleMapPrivate::setDocument( const QString& key )
{
if ( !m_model->mapTheme() ) {
// Happens if no valid map theme is set or at application startup
// if a file is passed via command line parameters and the last
// map theme has not been loaded yet
/**
* @todo Do we need to queue the document and process it once a map
* theme becomes available?
*/
return;
}
GeoDataDocument* doc = m_model->fileManager()->at( key );
for ( const GeoSceneLayer *layer: m_model->mapTheme()->map()->layers() ) {
if ( layer->backend() != dgml::dgmlValue_geodata
&& layer->backend() != dgml::dgmlValue_vector )
continue;
// look for documents
for ( const GeoSceneAbstractDataset *dataset: layer->datasets() ) {
const GeoSceneGeodata *data = static_cast<const GeoSceneGeodata*>( dataset );
QString containername = data->sourceFile();
QString colorize = data->colorize();
if( key == containername ) {
if (colorize == QLatin1String("land")) {
m_textureLayer.addLandDocument( doc );
}
if (colorize == QLatin1String("sea")) {
m_textureLayer.addSeaDocument( doc );
}
// set visibility according to theme property
if( !data->property().isEmpty() ) {
bool value;
m_model->mapTheme()->settings()->propertyValue( data->property(), value );
doc->setVisible( value );
m_model->treeModel()->updateFeature( doc );
}
}
}
}
}
void MarbleMapPrivate::updateTileLevel()
{
auto const tileZoomLevel = q->tileZoomLevel();
m_geometryLayer.setTileLevel(tileZoomLevel);
m_placemarkLayer.setTileLevel(tileZoomLevel);
emit q->tileLevelChanged(tileZoomLevel);
}
// Used to be paintEvent()
void MarbleMap::paint( GeoPainter &painter, const QRect &dirtyRect )
{
Q_UNUSED( dirtyRect );
if (d->m_showDebugPolygons ) {
if (viewContext() == Animation) {
painter.setDebugPolygonsLevel(1);
}
else {
painter.setDebugPolygonsLevel(2);
}
}
painter.setDebugBatchRender(d->m_showDebugBatchRender);
if ( !d->m_model->mapTheme() ) {
mDebug() << "No theme yet!";
d->m_marbleSplashLayer.render( &painter, &d->m_viewport );
return;
}
QTime t;
t.start();
RenderStatus const oldRenderStatus = d->m_renderState.status();
d->m_layerManager.renderLayers( &painter, &d->m_viewport );
d->m_renderState = d->m_layerManager.renderState();
bool const parsing = d->m_model->fileManager()->pendingFiles() > 0;
d->m_renderState.addChild(RenderState(QStringLiteral("Files"), parsing ? WaitingForData : Complete));
RenderStatus const newRenderStatus = d->m_renderState.status();
if ( oldRenderStatus != newRenderStatus ) {
emit renderStatusChanged( newRenderStatus );
}
emit renderStateChanged( d->m_renderState );
if ( d->m_showFrameRate ) {
FpsLayer fpsPainter( &t );
fpsPainter.paint( &painter );
}
const qreal fps = 1000.0 / (qreal)( t.elapsed() );
emit framesPerSecond( fps );
}
void MarbleMap::customPaint( GeoPainter *painter )
{
Q_UNUSED( painter );
}
QString MarbleMap::mapThemeId() const
{
return d->m_model->mapThemeId();
}
void MarbleMap::setMapThemeId( const QString& mapThemeId )
{
d->m_model->setMapThemeId( mapThemeId );
}
void MarbleMapPrivate::updateMapTheme()
{
m_layerManager.removeLayer( &m_textureLayer );
// FIXME Find a better way to do this reset. Maybe connect to themeChanged SIGNAL?
m_vectorTileLayer.reset();
m_layerManager.removeLayer( &m_vectorTileLayer );
m_layerManager.removeLayer( &m_groundLayer );
QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)),
q, SLOT(updateProperty(QString,bool)) );
QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)),
m_model, SLOT(updateProperty(QString,bool)) );
q->setPropertyValue(QStringLiteral("clouds_data"), m_viewParams.showClouds());
m_groundLayer.setColor( m_model->mapTheme()->map()->backgroundColor() );
// Check whether there is a texture layer and vectortile layer available:
if ( m_model->mapTheme()->map()->hasTextureLayers() ) {
const GeoSceneSettings *const settings = m_model->mapTheme()->settings();
- const GeoSceneGroup *const textureLayerSettings = settings ? settings->group( "Texture Layers" ) : 0;
- const GeoSceneGroup *const vectorTileLayerSettings = settings ? settings->group( "VectorTile Layers" ) : 0;
+ const GeoSceneGroup *const textureLayerSettings = settings ? settings->group( "Texture Layers" ) : nullptr;
+ const GeoSceneGroup *const vectorTileLayerSettings = settings ? settings->group( "VectorTile Layers" ) : nullptr;
bool textureLayersOk = true;
bool vectorTileLayersOk = true;
// textures will contain texture layers and
// vectorTiles vectortile layers
QVector<const GeoSceneTextureTileDataset *> textures;
QVector<const GeoSceneVectorTileDataset *> vectorTiles;
for( GeoSceneLayer* layer: m_model->mapTheme()->map()->layers() ){
if ( layer->backend() == dgml::dgmlValue_texture ){
for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) {
const GeoSceneTextureTileDataset *const texture = dynamic_cast<GeoSceneTextureTileDataset const *>( pos );
if ( !texture )
continue;
const QString sourceDir = texture->sourceDir();
const QString installMap = texture->installMap();
const QString role = layer->role();
// If the tiles aren't already there, put up a progress dialog
// while creating them.
if ( !TileLoader::baseTilesAvailable( *texture )
&& !installMap.isEmpty() )
{
mDebug() << "Base tiles not available. Creating Tiles ... \n"
<< "SourceDir: " << sourceDir << "InstallMap:" << installMap;
TileCreator *tileCreator = new TileCreator(
sourceDir,
installMap,
(role == QLatin1String("dem")) ? "true" : "false" );
tileCreator->setTileFormat( texture->fileFormat().toLower() );
- QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, 0 );
+ QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr );
tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(),
m_model->mapTheme()->head()->description() );
tileCreatorDlg->exec();
if ( TileLoader::baseTilesAvailable( *texture ) ) {
mDebug() << "Base tiles for" << sourceDir << "successfully created.";
} else {
qWarning() << "Some or all base tiles for" << sourceDir << "could not be created.";
}
delete tileCreatorDlg;
}
if ( TileLoader::baseTilesAvailable( *texture ) ) {
textures.append( texture );
} else {
qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers.";
textureLayersOk = false;
}
}
}
else if ( layer->backend() == dgml::dgmlValue_vectortile ){
for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) {
const GeoSceneVectorTileDataset *const vectorTile = dynamic_cast<GeoSceneVectorTileDataset const *>( pos );
if ( !vectorTile )
continue;
const QString sourceDir = vectorTile->sourceDir();
const QString installMap = vectorTile->installMap();
const QString role = layer->role();
// If the tiles aren't already there, put up a progress dialog
// while creating them.
if ( !TileLoader::baseTilesAvailable( *vectorTile )
&& !installMap.isEmpty() )
{
mDebug() << "Base tiles not available. Creating Tiles ... \n"
<< "SourceDir: " << sourceDir << "InstallMap:" << installMap;
TileCreator *tileCreator = new TileCreator(
sourceDir,
installMap,
(role == QLatin1String("dem")) ? "true" : "false" );
tileCreator->setTileFormat( vectorTile->fileFormat().toLower() );
- QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, 0 );
+ QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr );
tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(),
m_model->mapTheme()->head()->description() );
tileCreatorDlg->exec();
if ( TileLoader::baseTilesAvailable( *vectorTile ) ) {
qDebug() << "Base tiles for" << sourceDir << "successfully created.";
} else {
qDebug() << "Some or all base tiles for" << sourceDir << "could not be created.";
}
delete tileCreatorDlg;
}
if ( TileLoader::baseTilesAvailable( *vectorTile ) ) {
vectorTiles.append( vectorTile );
} else {
qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers.";
vectorTileLayersOk = false;
}
}
}
}
QString seafile, landfile;
if( !m_model->mapTheme()->map()->filters().isEmpty() ) {
const GeoSceneFilter *filter= m_model->mapTheme()->map()->filters().first();
if (filter->type() == QLatin1String("colorize")) {
//no need to look up with MarbleDirs twice so they are left null for now
QList<const GeoScenePalette*> palette = filter->palette();
for (const GeoScenePalette *curPalette: palette ) {
if (curPalette->type() == QLatin1String("sea")) {
seafile = MarbleDirs::path( curPalette->file() );
} else if (curPalette->type() == QLatin1String("land")) {
landfile = MarbleDirs::path( curPalette->file() );
}
}
//look up locations if they are empty
if( seafile.isEmpty() )
seafile = MarbleDirs::path(QStringLiteral("seacolors.leg"));
if( landfile.isEmpty() )
landfile = MarbleDirs::path(QStringLiteral("landcolors.leg"));
}
}
m_textureLayer.setMapTheme( textures, textureLayerSettings, seafile, landfile );
m_textureLayer.setProjection( m_viewport.projection() );
m_textureLayer.setShowRelief( q->showRelief() );
m_vectorTileLayer.setMapTheme( vectorTiles, vectorTileLayerSettings );
if (m_textureLayer.textureLayerCount() == 0) {
m_layerManager.addLayer( &m_groundLayer );
}
if ( textureLayersOk )
m_layerManager.addLayer( &m_textureLayer );
if ( vectorTileLayersOk && !vectorTiles.isEmpty() )
m_layerManager.addLayer( &m_vectorTileLayer );
}
else {
m_layerManager.addLayer( &m_groundLayer );
- m_textureLayer.setMapTheme( QVector<const GeoSceneTextureTileDataset *>(), 0, "", "" );
- m_vectorTileLayer.setMapTheme( QVector<const GeoSceneVectorTileDataset *>(), 0 );
+ m_textureLayer.setMapTheme( QVector<const GeoSceneTextureTileDataset *>(), nullptr, "", "" );
+ m_vectorTileLayer.setMapTheme( QVector<const GeoSceneVectorTileDataset *>(), nullptr );
}
// earth
m_placemarkLayer.setShowPlaces( q->showPlaces() );
m_placemarkLayer.setShowCities( q->showCities() );
m_placemarkLayer.setShowTerrain( q->showTerrain() );
m_placemarkLayer.setShowOtherPlaces( q->showOtherPlaces() );
m_placemarkLayer.setShowLandingSites(q->propertyValue(QStringLiteral("landingsites")));
m_placemarkLayer.setShowCraters(q->propertyValue(QStringLiteral("craters")));
m_placemarkLayer.setShowMaria(q->propertyValue(QStringLiteral("maria")));
m_styleBuilder.setDefaultLabelColor(m_model->mapTheme()->map()->labelColor());
m_placemarkLayer.requestStyleReset();
for (RenderPlugin *renderPlugin: m_renderPlugins) {
bool propertyAvailable = false;
m_model->mapTheme()->settings()->propertyAvailable( renderPlugin->nameId(), propertyAvailable );
bool propertyValue = false;
m_model->mapTheme()->settings()->propertyValue( renderPlugin->nameId(), propertyValue );
if ( propertyAvailable ) {
renderPlugin->setVisible( propertyValue );
}
}
emit q->themeChanged( m_model->mapTheme()->head()->mapThemeId() );
}
void MarbleMap::setPropertyValue( const QString& name, bool value )
{
mDebug() << "In MarbleMap the property " << name << "was set to " << value;
if ( d->m_model->mapTheme() ) {
d->m_model->mapTheme()->settings()->setPropertyValue( name, value );
d->m_textureLayer.setNeedsUpdate();
}
else {
mDebug() << "WARNING: Failed to access a map theme! Property: " << name;
}
if (d->m_textureLayer.textureLayerCount() == 0) {
d->m_layerManager.addLayer( &d->m_groundLayer );
}
else {
d->m_layerManager.removeLayer( &d->m_groundLayer );
}
}
void MarbleMap::setShowOverviewMap( bool visible )
{
setPropertyValue(QStringLiteral("overviewmap"), visible);
}
void MarbleMap::setShowScaleBar( bool visible )
{
setPropertyValue(QStringLiteral("scalebar"), visible);
}
void MarbleMap::setShowCompass( bool visible )
{
setPropertyValue(QStringLiteral("compass"), visible);
}
void MarbleMap::setShowAtmosphere( bool visible )
{
for ( RenderPlugin *plugin: renderPlugins() ) {
if (plugin->nameId() == QLatin1String("atmosphere")) {
plugin->setVisible( visible );
}
}
d->m_viewParams.setShowAtmosphere( visible );
}
void MarbleMap::setShowCrosshairs( bool visible )
{
QList<RenderPlugin *> pluginList = renderPlugins();
QList<RenderPlugin *>::const_iterator i = pluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
for (; i != end; ++i ) {
if ((*i)->nameId() == QLatin1String("crosshairs")) {
(*i)->setVisible( visible );
}
}
}
void MarbleMap::setShowClouds( bool visible )
{
d->m_viewParams.setShowClouds( visible );
setPropertyValue(QStringLiteral("clouds_data"), visible);
}
void MarbleMap::setShowSunShading( bool visible )
{
d->m_textureLayer.setShowSunShading( visible );
}
void MarbleMap::setShowCityLights( bool visible )
{
d->m_textureLayer.setShowCityLights( visible );
setPropertyValue(QStringLiteral("citylights"), visible);
}
void MarbleMap::setLockToSubSolarPoint( bool visible )
{
disconnect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)),
this, SLOT(centerOn(qreal,qreal)) );
if( isLockedToSubSolarPoint() != visible ) {
d->m_isLockedToSubSolarPoint = visible;
}
if ( isLockedToSubSolarPoint() ) {
connect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)),
this, SLOT(centerOn(qreal,qreal)) );
centerOn( d->m_model->sunLocator()->getLon(), d->m_model->sunLocator()->getLat() );
} else if ( visible ) {
mDebug() << "Ignoring centering on sun, since the sun plugin is not loaded.";
}
}
void MarbleMap::setSubSolarPointIconVisible( bool visible )
{
if ( isSubSolarPointIconVisible() != visible ) {
d->m_isSubSolarPointIconVisible = visible;
}
}
void MarbleMap::setShowTileId( bool visible )
{
d->m_textureLayer.setShowTileId( visible );
}
void MarbleMap::setShowGrid( bool visible )
{
setPropertyValue(QStringLiteral("coordinate-grid"), visible);
}
void MarbleMap::setShowPlaces( bool visible )
{
setPropertyValue(QStringLiteral("places"), visible);
}
void MarbleMap::setShowCities( bool visible )
{
setPropertyValue(QStringLiteral("cities"), visible);
}
void MarbleMap::setShowTerrain( bool visible )
{
setPropertyValue(QStringLiteral("terrain"), visible);
}
void MarbleMap::setShowOtherPlaces( bool visible )
{
setPropertyValue(QStringLiteral("otherplaces"), visible);
}
void MarbleMap::setShowRelief( bool visible )
{
setPropertyValue(QStringLiteral("relief"), visible);
}
void MarbleMap::setShowIceLayer( bool visible )
{
setPropertyValue(QStringLiteral("ice"), visible);
}
void MarbleMap::setShowBorders( bool visible )
{
setPropertyValue(QStringLiteral("borders"), visible);
}
void MarbleMap::setShowRivers( bool visible )
{
setPropertyValue(QStringLiteral("rivers"), visible);
}
void MarbleMap::setShowLakes( bool visible )
{
setPropertyValue(QStringLiteral("lakes"), visible);
}
void MarbleMap::setShowFrameRate( bool visible )
{
d->m_showFrameRate = visible;
}
void MarbleMap::setShowRuntimeTrace( bool visible )
{
if (visible != d->m_layerManager.showRuntimeTrace()) {
d->m_layerManager.setShowRuntimeTrace(visible);
emit repaintNeeded();
}
}
bool MarbleMap::showRuntimeTrace() const
{
return d->m_layerManager.showRuntimeTrace();
}
void MarbleMap::setShowDebugPolygons( bool visible)
{
if (visible != d->m_showDebugPolygons) {
d->m_showDebugPolygons = visible;
emit repaintNeeded();
}
}
bool MarbleMap::showDebugPolygons() const
{
return d->m_showDebugPolygons;
}
void MarbleMap::setShowDebugBatchRender( bool visible)
{
qDebug() << Q_FUNC_INFO << visible;
if (visible != d->m_showDebugBatchRender) {
d->m_showDebugBatchRender = visible;
emit repaintNeeded();
}
}
bool MarbleMap::showDebugBatchRender() const
{
return d->m_showDebugBatchRender;
}
void MarbleMap::setShowDebugPlacemarks( bool visible)
{
if (visible != d->m_placemarkLayer.isDebugModeEnabled()) {
d->m_placemarkLayer.setDebugModeEnabled(visible);
emit repaintNeeded();
}
}
bool MarbleMap::showDebugPlacemarks() const
{
return d->m_placemarkLayer.isDebugModeEnabled();
}
void MarbleMap::setLevelTagDebugModeEnabled(bool visible)
{
if (visible != d->m_geometryLayer.levelTagDebugModeEnabled()) {
d->m_geometryLayer.setLevelTagDebugModeEnabled(visible);
d->m_placemarkLayer.setLevelTagDebugModeEnabled(visible);
emit repaintNeeded();
}
}
bool MarbleMap::levelTagDebugModeEnabled() const
{
return d->m_geometryLayer.levelTagDebugModeEnabled() &&
d->m_placemarkLayer.levelTagDebugModeEnabled();
}
void MarbleMap::setDebugLevelTag(int level)
{
d->m_geometryLayer.setDebugLevelTag(level);
d->m_placemarkLayer.setDebugLevelTag(level);
}
int MarbleMap::debugLevelTag() const
{
return d->m_geometryLayer.debugLevelTag();
}
void MarbleMap::setShowBackground( bool visible )
{
d->m_layerManager.setShowBackground( visible );
}
void MarbleMap::setVisibleRelationTypes(GeoDataRelation::RelationTypes relationTypes)
{
if (d->m_visibleRelationTypes != relationTypes) {
d->m_visibleRelationTypes = relationTypes;
d->m_geometryLayer.setVisibleRelationTypes(relationTypes);
emit visibleRelationTypesChanged(d->m_visibleRelationTypes);
}
}
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::clearVolatileTileCache()
{
d->m_vectorTileLayer.reset();
d->m_textureLayer.reset();
mDebug() << "Cleared Volatile Cache!";
}
void MarbleMap::setVolatileTileCacheLimit( quint64 kilobytes )
{
mDebug() << "kiloBytes" << kilobytes;
d->m_textureLayer.setVolatileCacheLimit( kilobytes );
}
AngleUnit MarbleMap::defaultAngleUnit() const
{
if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::Decimal ) {
return DecimalDegree;
} else if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::UTM ) {
return UTM;
}
return DMSDegree;
}
void MarbleMap::setDefaultAngleUnit( AngleUnit angleUnit )
{
if ( angleUnit == DecimalDegree ) {
GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::Decimal );
return;
} else if ( angleUnit == UTM ) {
GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::UTM );
return;
}
GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::DMS );
}
QFont MarbleMap::defaultFont() const
{
return d->m_styleBuilder.defaultFont();
}
void MarbleMap::setDefaultFont( const QFont& font )
{
d->m_styleBuilder.setDefaultFont(font);
d->m_placemarkLayer.requestStyleReset();
}
QList<RenderPlugin *> MarbleMap::renderPlugins() const
{
return d->m_renderPlugins;
}
QList<AbstractFloatItem *> MarbleMap::floatItems() const
{
return d->m_floatItemsLayer.floatItems();
}
AbstractFloatItem * MarbleMap::floatItem( const QString &nameId ) const
{
for ( AbstractFloatItem * floatItem: floatItems() ) {
if ( floatItem && floatItem->nameId() == nameId ) {
return floatItem;
}
}
- return 0; // No item found
+ return nullptr; // No item found
}
QList<AbstractDataPlugin *> MarbleMap::dataPlugins() const
{
return d->m_layerManager.dataPlugins();
}
QList<AbstractDataPluginItem *> MarbleMap::whichItemAt( const QPoint& curpos ) const
{
return d->m_layerManager.whichItemAt( curpos );
}
void MarbleMap::addLayer( LayerInterface *layer )
{
d->m_layerManager.addLayer(layer);
}
void MarbleMap::removeLayer( LayerInterface *layer )
{
d->m_layerManager.removeLayer(layer);
}
RenderStatus MarbleMap::renderStatus() const
{
return d->m_layerManager.renderState().status();
}
RenderState MarbleMap::renderState() const
{
return d->m_layerManager.renderState();
}
QString MarbleMap::addTextureLayer(GeoSceneTextureTileDataset *texture)
{
return textureLayer()->addTextureLayer(texture);
}
void MarbleMap::removeTextureLayer(const QString &key)
{
textureLayer()->removeTextureLayer(key);
}
// this method will only temporarily "pollute" the MarbleModel class
TextureLayer *MarbleMap::textureLayer() const
{
return &d->m_textureLayer;
}
const StyleBuilder* MarbleMap::styleBuilder() const
{
return &d->m_styleBuilder;
}
qreal MarbleMap::heading() const
{
return d->m_viewport.heading() * RAD2DEG;
}
void MarbleMap::setHeading( qreal heading )
{
d->m_viewport.setHeading( heading * DEG2RAD );
d->m_textureLayer.setNeedsUpdate();
emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
}
}
#include "moc_MarbleMap.cpp"
diff --git a/src/lib/marble/MarbleModel.cpp b/src/lib/marble/MarbleModel.cpp
index e8d190cf4..645274027 100644
--- a/src/lib/marble/MarbleModel.cpp
+++ b/src/lib/marble/MarbleModel.cpp
@@ -1,884 +1,884 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008, 2009, 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
// Copyright 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
#include "MarbleModel.h"
#include <cmath>
#include <QAtomicInt>
#include <QPointer>
#include <QAbstractItemModel>
#include <QItemSelectionModel>
#include <QSortFilterProxyModel>
#include <QTextDocument>
#include "kdescendantsproxymodel.h"
#include "MapThemeManager.h"
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "GeoSceneDocument.h"
#include "GeoSceneGeodata.h"
#include "GeoSceneHead.h"
#include "GeoSceneLayer.h"
#include "GeoSceneMap.h"
#include "GeoScenePalette.h"
#include "GeoSceneTileDataset.h"
#include "GeoSceneVector.h"
#include "GeoDataDocument.h"
#include "GeoDataFeature.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataTrack.h"
#include "GeoDataLineStyle.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataTypes.h"
#include "DgmlAuxillaryDictionary.h"
#include "MarbleClock.h"
#include "FileStoragePolicy.h"
#include "FileStorageWatcher.h"
#include "PositionTracking.h"
#include "HttpDownloadManager.h"
#include "MarbleDirs.h"
#include "FileManager.h"
#include "GeoDataTreeModel.h"
#include "PlacemarkPositionProviderPlugin.h"
#include "Planet.h"
#include "PlanetFactory.h"
#include "PluginManager.h"
#include "StoragePolicy.h"
#include "SunLocator.h"
#include "TileCreator.h"
#include "TileCreatorDialog.h"
#include "TileLoader.h"
#include "routing/RoutingManager.h"
#include "RouteSimulationPositionProviderPlugin.h"
#include "BookmarkManager.h"
#include "ElevationModel.h"
namespace Marble
{
class MarbleModelPrivate
{
public:
MarbleModelPrivate()
: m_clock(),
m_planet(PlanetFactory::construct(QStringLiteral("earth"))),
m_sunLocator( &m_clock, &m_planet ),
m_pluginManager(),
m_homePoint( -9.4, 54.8, 0.0, GeoDataCoordinates::Degree ), // Some point that tackat defined. :-)
m_homeZoom( 1050 ),
- m_mapTheme( 0 ),
+ m_mapTheme( nullptr ),
m_storagePolicy( MarbleDirs::localPath() ),
m_downloadManager( &m_storagePolicy ),
m_storageWatcher( MarbleDirs::localPath() ),
m_treeModel(),
m_descendantProxy(),
m_placemarkProxyModel(),
- m_placemarkSelectionModel( 0 ),
+ m_placemarkSelectionModel( nullptr ),
m_fileManager( &m_treeModel, &m_pluginManager ),
m_positionTracking( &m_treeModel ),
- m_trackedPlacemark( 0 ),
+ m_trackedPlacemark( nullptr ),
m_bookmarkManager( &m_treeModel ),
- m_routingManager( 0 ),
- m_legend( 0 ),
+ m_routingManager( nullptr ),
+ m_legend( nullptr ),
m_workOffline( false ),
m_elevationModel( &m_downloadManager, &m_pluginManager )
{
m_descendantProxy.setSourceModel( &m_treeModel );
m_placemarkProxyModel.setFilterFixedString( GeoDataTypes::GeoDataPlacemarkType );
m_placemarkProxyModel.setFilterKeyColumn( 1 );
m_placemarkProxyModel.setSourceModel( &m_descendantProxy );
m_placemarkSelectionModel.setModel(&m_placemarkProxyModel);
m_groundOverlayProxyModel.setFilterFixedString( GeoDataTypes::GeoDataGroundOverlayType );
m_groundOverlayProxyModel.setFilterKeyColumn( 1 );
m_groundOverlayProxyModel.setSourceModel( &m_descendantProxy );
}
~MarbleModelPrivate()
{
delete m_mapTheme;
delete m_legend;
}
/**
* @brief Assigns each placemark an inline
* style based on the color values specified
* by colorMap attribute under <brush> element
* in theme file.
*/
void assignFillColors( const QString &filePath );
void assignFillColors(GeoDataDocument *doc, const GeoSceneGeodata &data) const;
void addHighlightStyle(GeoDataDocument *doc) const;
// Misc stuff.
MarbleClock m_clock;
Planet m_planet;
SunLocator m_sunLocator;
PluginManager m_pluginManager;
// The home position
GeoDataCoordinates m_homePoint;
int m_homeZoom;
// View and paint stuff
GeoSceneDocument *m_mapTheme;
FileStoragePolicy m_storagePolicy;
HttpDownloadManager m_downloadManager;
// Cache related
FileStorageWatcher m_storageWatcher;
// Places on the map
GeoDataTreeModel m_treeModel;
KDescendantsProxyModel m_descendantProxy;
QSortFilterProxyModel m_placemarkProxyModel;
QSortFilterProxyModel m_groundOverlayProxyModel;
// Selection handling
QItemSelectionModel m_placemarkSelectionModel;
FileManager m_fileManager;
//Gps Stuff
PositionTracking m_positionTracking;
const GeoDataPlacemark *m_trackedPlacemark;
BookmarkManager m_bookmarkManager;
RoutingManager *m_routingManager;
QTextDocument *m_legend;
bool m_workOffline;
ElevationModel m_elevationModel;
};
MarbleModel::MarbleModel( QObject *parent )
: QObject( parent ),
d( new MarbleModelPrivate() )
{
// connect the StoragePolicy used by the download manager to the FileStorageWatcher
connect( &d->m_storagePolicy, SIGNAL(cleared()),
&d->m_storageWatcher, SLOT(resetCurrentSize()) );
connect( &d->m_storagePolicy, SIGNAL(sizeChanged(qint64)),
&d->m_storageWatcher, SLOT(addToCurrentSize(qint64)) );
connect( &d->m_fileManager, SIGNAL(fileAdded(QString)),
this, SLOT(assignFillColors(QString)) );
d->m_routingManager = new RoutingManager( this, this );
connect(&d->m_clock, SIGNAL(timeChanged()),
&d->m_sunLocator, SLOT(update()) );
d->m_pluginManager.addPositionProviderPlugin(new PlacemarkPositionProviderPlugin(this, this));
d->m_pluginManager.addPositionProviderPlugin(new RouteSimulationPositionProviderPlugin(this, this));
}
MarbleModel::~MarbleModel()
{
delete d;
mDebug() << "Model deleted:" << this;
}
BookmarkManager *MarbleModel::bookmarkManager()
{
return &d->m_bookmarkManager;
}
QString MarbleModel::mapThemeId() const
{
QString mapThemeId;
if (d->m_mapTheme)
mapThemeId = d->m_mapTheme->head()->mapThemeId();
return mapThemeId;
}
GeoSceneDocument *MarbleModel::mapTheme()
{
return d->m_mapTheme;
}
const 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::setMapThemeId( const QString &mapThemeId )
{
if ( !mapThemeId.isEmpty() && mapThemeId == this->mapThemeId() )
return;
GeoSceneDocument *mapTheme = MapThemeManager::loadMapTheme( mapThemeId );
setMapTheme( mapTheme );
}
void MarbleModel::setMapTheme( GeoSceneDocument *document )
{
GeoSceneDocument *mapTheme = document;
if ( !mapTheme ) {
// Check whether the previous theme works
if ( d->m_mapTheme ){
qWarning() << "Selected theme doesn't work, so we stick to the previous one";
return;
}
// Fall back to default theme
QString defaultTheme = "earth/srtm/srtm.dgml";
qWarning() << "Falling back to default theme:" << defaultTheme;
mapTheme = MapThemeManager::loadMapTheme( defaultTheme );
}
// If this last resort doesn't work either shed a tear and exit
if ( !mapTheme ) {
qWarning() << "Couldn't find a valid DGML map.";
return;
}
// find the list of previous theme's geodata
QList<GeoSceneGeodata> currentDatasets;
if ( d->m_mapTheme ) {
for ( GeoSceneLayer *layer: d->m_mapTheme->map()->layers() ) {
if ( layer->backend() != dgml::dgmlValue_geodata
&& layer->backend() != dgml::dgmlValue_vector )
continue;
// look for documents
for ( GeoSceneAbstractDataset *dataset: layer->datasets() ) {
GeoSceneGeodata *data = dynamic_cast<GeoSceneGeodata*>( dataset );
Q_ASSERT( data );
currentDatasets << *data;
}
}
}
delete d->m_mapTheme;
d->m_mapTheme = mapTheme;
addDownloadPolicies( d->m_mapTheme );
// Some output to show how to use this stuff ...
mDebug() << "DGML2 Name : " << d->m_mapTheme->head()->name();
/*
mDebug() << "DGML2 Description: " << d->m_mapTheme->head()->description();
if ( d->m_mapTheme->map()->hasTextureLayers() )
mDebug() << "Contains texture layers! ";
else
mDebug() << "Does not contain any texture layers! ";
mDebug() << "Number of SRTM textures: " << d->m_mapTheme->map()->layer("srtm")->datasets().count();
if ( d->m_mapTheme->map()->hasVectorLayers() )
mDebug() << "Contains vector layers! ";
else
mDebug() << "Does not contain any vector layers! ";
*/
//Don't change the planet unless we have to...
qreal const radiusAttributeValue = d->m_mapTheme->head()->radius();
if( d->m_mapTheme->head()->target().toLower() != d->m_planet.id() || radiusAttributeValue != d->m_planet.radius() ) {
mDebug() << "Changing Planet";
d->m_planet = Magrathea::construct( d->m_mapTheme->head()->target().toLower() );
if ( radiusAttributeValue > 0.0 ) {
d->m_planet.setRadius( radiusAttributeValue );
}
sunLocator()->setPlanet( &d->m_planet );
}
QStringList fileList;
QStringList propertyList;
QList<GeoDataStyle::Ptr> styleList;
QList<int> renderOrderList;
for ( GeoSceneLayer *layer: d->m_mapTheme->map()->layers() ) {
if ( layer->backend() != dgml::dgmlValue_geodata
&& layer->backend() != dgml::dgmlValue_vector )
continue;
// look for datasets which are different from currentDatasets
for ( const GeoSceneAbstractDataset *dataset: layer->datasets() ) {
const GeoSceneGeodata *data = dynamic_cast<const GeoSceneGeodata*>( dataset );
Q_ASSERT( data );
bool skip = false;
GeoDataDocument *doc = nullptr;
for ( int i = 0; i < currentDatasets.size(); ++i ) {
if ( currentDatasets[i] == *data ) {
currentDatasets.removeAt( i );
skip = true;
break;
}
/*
* If the sourcefile of data matches any in the currentDatasets then there
* is no need to parse the file again just update the style
* i.e. <brush> and <pen> values of already parsed file. assignNewStyle() does that
*/
if ( currentDatasets[i].sourceFile() == data->sourceFile() ) {
doc = d->m_fileManager.at(data->sourceFile());
currentDatasets.removeAt(i);
}
}
if ( skip ) {
continue;
}
if (doc) {
d->assignFillColors(doc, *data);
}
else {
const QString filename = data->sourceFile();
const QString property = data->property();
const QPen pen = data->pen();
const QBrush brush = data->brush();
GeoDataStyle::Ptr style;
const int renderOrder = data->renderOrder();
/*
* data->colors() are the colorMap values from dgml file. If this is not
* empty then we are supposed to assign every placemark a different style
* by giving it a color from colorMap values based on color index
* of that placemark. See assignFillColors() for details. So, we need to
* send an empty style to fileManeger otherwise the FileLoader::createFilterProperties()
* will overwrite the parsed value of color index ( GeoDataPolyStyle::d->m_colorIndex ).
*/
if ( data->colors().isEmpty() ) {
GeoDataLineStyle lineStyle( pen.color() );
lineStyle.setPenStyle( pen.style() );
lineStyle.setWidth( pen.width() );
GeoDataPolyStyle polyStyle( brush.color() );
polyStyle.setFill( true );
style = GeoDataStyle::Ptr(new GeoDataStyle);
style->setLineStyle( lineStyle );
style->setPolyStyle( polyStyle );
style->setId(QStringLiteral("default"));
}
fileList << filename;
propertyList << property;
styleList << style;
renderOrderList << renderOrder;
}
}
}
// unload old currentDatasets which are not part of the new map
for(const GeoSceneGeodata &data: currentDatasets) {
d->m_fileManager.removeFile( data.sourceFile() );
}
// load new datasets
for ( int i = 0 ; i < fileList.size(); ++i ) {
d->m_fileManager.addFile( fileList.at(i), propertyList.at(i), styleList.at(i), MapDocument, renderOrderList.at(i) );
}
mDebug() << "THEME CHANGED: ***" << mapTheme->head()->mapThemeId();
emit themeChanged( mapTheme->head()->mapThemeId() );
}
void MarbleModelPrivate::addHighlightStyle(GeoDataDocument *doc) const
{
if ( doc ) {
/*
* Add a highlight style to GeoDataDocument if
*the theme file specifies any highlight color.
*/
QColor highlightBrushColor = m_mapTheme->map()->highlightBrushColor();
QColor highlightPenColor = m_mapTheme->map()->highlightPenColor();
GeoDataStyle::Ptr highlightStyle(new GeoDataStyle);
highlightStyle->setId(QStringLiteral("highlight"));
if ( highlightBrushColor.isValid() ) {
GeoDataPolyStyle highlightPolyStyle;
highlightPolyStyle.setColor( highlightBrushColor );
highlightPolyStyle.setFill( true );
highlightStyle->setPolyStyle( highlightPolyStyle );
}
if ( highlightPenColor.isValid() ) {
GeoDataLineStyle highlightLineStyle( highlightPenColor );
highlightStyle->setLineStyle( highlightLineStyle );
}
if ( highlightBrushColor.isValid()
|| highlightPenColor.isValid() )
{
GeoDataStyleMap styleMap = doc->styleMap(QStringLiteral("default-map"));
styleMap.insert(QStringLiteral("highlight"), QLatin1Char('#') + highlightStyle->id());
doc->addStyle( highlightStyle );
doc->addStyleMap( styleMap );
}
}
}
void MarbleModel::home( qreal &lon, qreal &lat, int& zoom ) const
{
d->m_homePoint.geoCoordinates( lon, lat, GeoDataCoordinates::Degree );
zoom = d->m_homeZoom;
}
void MarbleModel::setHome( qreal lon, qreal lat, int zoom )
{
d->m_homePoint = GeoDataCoordinates( lon, lat, 0, GeoDataCoordinates::Degree );
d->m_homeZoom = zoom;
emit homeChanged( d->m_homePoint );
}
void MarbleModel::setHome( const GeoDataCoordinates& homePoint, int zoom )
{
d->m_homePoint = homePoint;
d->m_homeZoom = zoom;
emit homeChanged( d->m_homePoint );
}
HttpDownloadManager *MarbleModel::downloadManager()
{
return &d->m_downloadManager;
}
const HttpDownloadManager *MarbleModel::downloadManager() const
{
return &d->m_downloadManager;
}
GeoDataTreeModel *MarbleModel::treeModel()
{
return &d->m_treeModel;
}
const GeoDataTreeModel *MarbleModel::treeModel() const
{
return &d->m_treeModel;
}
QAbstractItemModel *MarbleModel::placemarkModel()
{
return &d->m_placemarkProxyModel;
}
const QAbstractItemModel *MarbleModel::placemarkModel() const
{
return &d->m_placemarkProxyModel;
}
QAbstractItemModel *MarbleModel::groundOverlayModel()
{
return &d->m_groundOverlayProxyModel;
}
const QAbstractItemModel *MarbleModel::groundOverlayModel() const
{
return &d->m_groundOverlayProxyModel;
}
QItemSelectionModel *MarbleModel::placemarkSelectionModel()
{
return &d->m_placemarkSelectionModel;
}
PositionTracking *MarbleModel::positionTracking() const
{
return &d->m_positionTracking;
}
FileManager *MarbleModel::fileManager()
{
return &d->m_fileManager;
}
qreal MarbleModel::planetRadius() const
{
return d->m_planet.radius();
}
QString MarbleModel::planetName() const
{
return d->m_planet.name();
}
QString MarbleModel::planetId() const
{
return d->m_planet.id();
}
MarbleClock *MarbleModel::clock()
{
return &d->m_clock;
}
const MarbleClock *MarbleModel::clock() const
{
return &d->m_clock;
}
SunLocator *MarbleModel::sunLocator()
{
return &d->m_sunLocator;
}
const SunLocator *MarbleModel::sunLocator() const
{
return &d->m_sunLocator;
}
quint64 MarbleModel::persistentTileCacheLimit() const
{
return d->m_storageWatcher.cacheLimit() / 1024;
}
void MarbleModel::clearPersistentTileCache()
{
d->m_storagePolicy.clearCache();
// Now create base tiles again if needed
if ( d->m_mapTheme->map()->hasTextureLayers() || d->m_mapTheme->map()->hasVectorLayers() ) {
// 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();
const GeoSceneLayer *layer =
static_cast<const GeoSceneLayer*>( d->m_mapTheme->map()->layer( themeID ) );
const GeoSceneTileDataset *texture =
static_cast<const GeoSceneTileDataset*>( layer->groundDataset() );
QString sourceDir = texture->sourceDir();
QString installMap = texture->installMap();
QString role = d->m_mapTheme->map()->layer( themeID )->role();
if ( !TileLoader::baseTilesAvailable( *texture )
&& !installMap.isEmpty() )
{
mDebug() << "Base tiles not available. Creating Tiles ... \n"
<< "SourceDir: " << sourceDir << "InstallMap:" << installMap;
MarbleDirs::debug();
TileCreator *tileCreator = new TileCreator(
sourceDir,
installMap,
(role == QLatin1String("dem")) ? "true" : "false" );
tileCreator->setTileFormat( texture->fileFormat().toLower() );
- QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, 0 );
+ QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr );
tileCreatorDlg->setSummary( d->m_mapTheme->head()->name(),
d->m_mapTheme->head()->description() );
tileCreatorDlg->exec();
qDebug("Tile creation completed");
delete tileCreatorDlg;
}
}
}
void MarbleModel::setPersistentTileCacheLimit(quint64 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 MarbleModel::setTrackedPlacemark( const GeoDataPlacemark *placemark )
{
d->m_trackedPlacemark = placemark;
emit trackedPlacemarkChanged( placemark );
}
const GeoDataPlacemark* MarbleModel::trackedPlacemark() const
{
return d->m_trackedPlacemark;
}
const PluginManager* MarbleModel::pluginManager() const
{
return &d->m_pluginManager;
}
PluginManager* MarbleModel::pluginManager()
{
return &d->m_pluginManager;
}
const Planet *MarbleModel::planet() const
{
return &d->m_planet;
}
void MarbleModel::addDownloadPolicies( const GeoSceneDocument *mapTheme )
{
if ( !mapTheme )
return;
if ( !mapTheme->map()->hasTextureLayers() && !mapTheme->map()->hasVectorLayers() )
return;
// 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
const QString themeId = mapTheme->head()->theme();
const GeoSceneLayer * const layer = static_cast<const GeoSceneLayer*>( mapTheme->map()->layer( themeId ));
if ( !layer )
return;
const GeoSceneTileDataset * const texture = static_cast<const GeoSceneTileDataset*>( layer->groundDataset() );
if ( !texture )
return;
QList<const DownloadPolicy *> policies = texture->downloadPolicies();
QList<const DownloadPolicy *>::const_iterator pos = policies.constBegin();
QList<const DownloadPolicy *>::const_iterator const end = policies.constEnd();
for (; pos != end; ++pos ) {
d->m_downloadManager.addDownloadPolicy( **pos );
}
}
RoutingManager* MarbleModel::routingManager()
{
return d->m_routingManager;
}
const RoutingManager* MarbleModel::routingManager() const
{
return d->m_routingManager;
}
void MarbleModel::setClockDateTime( const QDateTime& datetime )
{
d->m_clock.setDateTime( datetime );
}
QDateTime MarbleModel::clockDateTime() const
{
return d->m_clock.dateTime();
}
int MarbleModel::clockSpeed() const
{
return d->m_clock.speed();
}
void MarbleModel::setClockSpeed( int speed )
{
d->m_clock.setSpeed( speed );
}
void MarbleModel::setClockTimezone( int timeInSec )
{
d->m_clock.setTimezone( timeInSec );
}
int MarbleModel::clockTimezone() const
{
return d->m_clock.timezone();
}
QTextDocument * MarbleModel::legend()
{
return d->m_legend;
}
void MarbleModel::setLegend( QTextDocument * legend )
{
delete d->m_legend;
d->m_legend = legend;
}
void MarbleModel::addGeoDataFile( const QString& filename )
{
d->m_fileManager.addFile( filename, filename, GeoDataStyle::Ptr(), UserDocument, true );
}
void MarbleModel::addGeoDataString( const QString& data, const QString& key )
{
d->m_fileManager.addData( key, data, UserDocument );
}
void MarbleModel::removeGeoData( const QString& fileName )
{
d->m_fileManager.removeFile( fileName );
}
void MarbleModel::updateProperty( const QString &property, bool value )
{
for( GeoDataFeature *feature: d->m_treeModel.rootDocument()->featureList()) {
if (auto document = geodata_cast<GeoDataDocument>(feature)) {
if( document->property() == property ){
document->setVisible( value );
d->m_treeModel.updateFeature( document );
}
}
}
}
void MarbleModelPrivate::assignFillColors(const QString &filePath)
{
const GeoSceneGeodata *data = nullptr;
for (auto layer : m_mapTheme->map()->layers()) {
if (layer->backend() != dgml::dgmlValue_geodata
&& layer->backend() != dgml::dgmlValue_vector) {
continue;
}
for (auto dataset: layer->datasets()) {
auto sceneData = dynamic_cast<const GeoSceneGeodata *>(dataset);
if (sceneData != nullptr && sceneData->sourceFile() == filePath) {
data = sceneData;
break;
}
}
if (data) {
break;
}
}
if (data == nullptr) {
return;
}
GeoDataDocument *doc = m_fileManager.at(filePath);
Q_ASSERT( doc );
assignFillColors(doc, *data);
}
void MarbleModelPrivate::assignFillColors(GeoDataDocument *doc, const GeoSceneGeodata &data) const
{
addHighlightStyle( doc );
const QPen pen = data.pen();
const QBrush brush = data.brush();
const QVector<QColor> colors = data.colors();
GeoDataLineStyle lineStyle( pen.color() );
lineStyle.setPenStyle( pen.style() );
lineStyle.setWidth( pen.width() );
if (!colors.isEmpty()) {
const qreal alpha = data.alpha();
for (auto feature : *doc) {
auto placemark = geodata_cast<GeoDataPlacemark>(feature);
if (placemark == nullptr) {
continue;
}
GeoDataStyle::Ptr style(new GeoDataStyle);
style->setId(QStringLiteral("normal"));
style->setLineStyle( lineStyle );
quint8 colorIndex = placemark->style()->polyStyle().colorIndex();
GeoDataPolyStyle polyStyle;
// Set the colorIndex so that it's not lost after setting new style.
polyStyle.setColorIndex( colorIndex );
QColor color;
// color index having value 99 is undefined
Q_ASSERT( colors.size() );
if (colorIndex > colors.size() || (colorIndex - 1) < 0) {
color = colors[0]; // Assign the first color as default
}
else {
color = colors[colorIndex-1];
}
color.setAlphaF( alpha );
polyStyle.setColor( color );
polyStyle.setFill( true );
style->setPolyStyle( polyStyle );
placemark->setStyle( style );
}
}
else {
GeoDataStyle::Ptr style(new GeoDataStyle);
GeoDataPolyStyle polyStyle( brush.color() );
polyStyle.setFill( true );
style->setLineStyle( lineStyle );
style->setPolyStyle( polyStyle );
style->setId(QStringLiteral("default"));
GeoDataStyleMap styleMap;
styleMap.setId(QStringLiteral("default-map"));
styleMap.insert(QStringLiteral("normal"), QLatin1Char('#') + style->id());
doc->addStyle( style );
doc->addStyleMap( styleMap );
const QString styleUrl = QLatin1Char('#') + styleMap.id();
for (auto feature : *doc) {
auto placemark = geodata_cast<GeoDataPlacemark>(feature);
if (placemark == nullptr) {
continue;
}
if (geodata_cast<GeoDataTrack>(placemark->geometry()) ||
geodata_cast<GeoDataPoint>(placemark->geometry())) {
continue;
}
placemark->setStyleUrl(styleUrl);
}
}
}
bool MarbleModel::workOffline() const
{
return d->m_workOffline;
}
void MarbleModel::setWorkOffline( bool workOffline )
{
if ( d->m_workOffline != workOffline ) {
downloadManager()->setDownloadEnabled( !workOffline );
d->m_workOffline = workOffline;
emit workOfflineChanged();
}
}
ElevationModel* MarbleModel::elevationModel()
{
return &d->m_elevationModel;
}
const ElevationModel* MarbleModel::elevationModel() const
{
return &d->m_elevationModel;
}
}
#include "moc_MarbleModel.cpp"
diff --git a/src/lib/marble/MarbleModel.h b/src/lib/marble/MarbleModel.h
index d6061b987..81aac019f 100644
--- a/src/lib/marble/MarbleModel.h
+++ b/src/lib/marble/MarbleModel.h
@@ -1,341 +1,341 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
//
// MarbleModel is the data store and index class for the MarbleWidget.
//
#ifndef MARBLE_MARBLEMODEL_H
#define MARBLE_MARBLEMODEL_H
/** @file
* This file contains the headers for MarbleModel
*
* @author Torsten Rahn <tackat@kde.org>
* @author Inge Wallin <inge@lysator.liu.se>
*/
#include "marble_export.h"
#include <QObject>
#include <QString>
#include "MarbleGlobal.h"
class QItemSelectionModel;
class QAbstractItemModel;
class QTextDocument;
class QDateTime;
namespace Marble
{
class GeoDataPlacemark;
class GeoPainter;
class MeasureTool;
class PositionTracking;
class HttpDownloadManager;
class MarbleModelPrivate;
class MarbleClock;
class SunLocator;
class TileCreator;
class PluginManager;
class GeoDataCoordinates;
class GeoDataTreeModel;
class GeoSceneDocument;
class Planet;
class RoutingManager;
class BookmarkManager;
class FileManager;
class ElevationModel;
/**
* @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:
* <b>tiles</b> which provide the background, <b>vectors</b> which
* provide things like country borders and coastlines and
* <b>placemarks</b> which can show points of interest, such as
* cities, mountain tops or the poles.
*
* The <b>tiles</b> 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 <b>vectors</b> provide things like country borders and
* coastlines. They are stored in separate files and can be added or
* removed at anytime.
*
* The <b>placemarks</b> 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
Q_PROPERTY( QString mapThemeId READ mapThemeId WRITE setMapThemeId NOTIFY themeChanged )
Q_PROPERTY( bool workOffline READ workOffline WRITE setWorkOffline NOTIFY workOfflineChanged )
public:
/**
* @brief Construct a new MarbleModel.
* @param parent the parent widget
*/
- explicit MarbleModel( QObject *parent = 0 );
+ explicit MarbleModel( QObject *parent = nullptr );
~MarbleModel() override;
/**
* @brief Return the list of Placemarks as a QAbstractItemModel *
* @return a list of all Placemarks in the MarbleModel.
*/
GeoDataTreeModel *treeModel();
const GeoDataTreeModel *treeModel() const;
QAbstractItemModel *groundOverlayModel();
const QAbstractItemModel *groundOverlayModel() const;
QAbstractItemModel *placemarkModel();
const QAbstractItemModel *placemarkModel() const;
QItemSelectionModel *placemarkSelectionModel();
/**
* @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;
GeoSceneDocument *mapTheme();
const GeoSceneDocument *mapTheme() const;
void setMapTheme( GeoSceneDocument * document );
/**
* @brief Set a new map theme to use.
* @param mapThemeId the identifier of the new map theme
*
* 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.
*
* 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 &mapThemeId );
/**
* @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 ) const;
/**
* @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 Return the downloadmanager to load missing tiles
* @return the HttpDownloadManager instance.
*/
HttpDownloadManager *downloadManager();
const HttpDownloadManager *downloadManager() const;
/**
* @brief Handle file loading into the treeModel
* @param filename the file to load
*/
void addGeoDataFile( const QString& filename );
/**
* @brief Handle raw data loading into the treeModel
* @param data the raw data to load
* @param key the name to remove this raw data later
*/
void addGeoDataString( const QString& data, const QString& key = QLatin1String("data") );
/**
* @brief Remove the file or raw data from the treeModel
* @param key either the file name or the key for raw data
*/
void removeGeoData( const QString& key );
FileManager *fileManager();
PositionTracking *positionTracking() const;
qreal planetRadius() const;
QString planetName() const;
QString planetId() const;
MarbleClock *clock();
const MarbleClock *clock() const;
SunLocator *sunLocator();
const SunLocator *sunLocator() 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 of the volatile (in RAM) tile cache.
* @return the cache limit in kilobytes
*/
quint64 volatileTileCacheLimit() const;
const PluginManager* pluginManager() const;
PluginManager* pluginManager();
/**
* @brief Returns the planet object for the current map.
* @return the planet object for the current map
*/
const Planet *planet() const;
RoutingManager* routingManager();
const RoutingManager* routingManager() const;
void setClockDateTime( const QDateTime& datetime );
QDateTime clockDateTime() const;
int clockSpeed() const;
void setClockSpeed( int speed );
void setClockTimezone( int timeInSec );
int clockTimezone() const;
/**
* return instance of BookmarkManager
*/
BookmarkManager *bookmarkManager();
QTextDocument * legend();
/**
* @brief Uses the given text document as the new content of the legend
* Any previous legend content is overwritten. MarbleModel takes ownership
* of the passed document.
*/
void setLegend( QTextDocument * document );
bool workOffline() const;
void setWorkOffline( bool workOffline );
ElevationModel* elevationModel();
const ElevationModel* elevationModel() const;
/**
* Returns the placemark being tracked by this model or 0 if no
* placemark is currently tracked.
* @see setTrackedPlacemark(), trackedPlacemarkChanged()
*/
const GeoDataPlacemark *trackedPlacemark() const;
public Q_SLOTS:
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 );
/**
* @brief Change the placemark tracked by this model
* @see trackedPlacemark(), trackedPlacemarkChanged()
*/
void setTrackedPlacemark( const GeoDataPlacemark *placemark );
void updateProperty( const QString &property, bool value );
Q_SIGNALS:
/**
* @brief Signal that the MarbleModel has started to create a new set of tiles.
* @param
*/
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( const QString &mapTheme );
void workOfflineChanged();
/**
* @brief Emitted when the placemark tracked by this model has changed
* @see setTrackedPlacemark(), trackedPlacemark()
*/
void trackedPlacemarkChanged( const GeoDataPlacemark *placemark );
/** @brief Emitted when the home location is changed
* @see home(), setHome()
*/
void homeChanged( const GeoDataCoordinates &newHomePoint );
private:
Q_DISABLE_COPY( MarbleModel )
Q_PRIVATE_SLOT( d, void assignFillColors( const QString &filePath ) )
void addDownloadPolicies( const GeoSceneDocument *mapTheme );
MarbleModelPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/MarbleNavigator.h b/src/lib/marble/MarbleNavigator.h
index e405daaaa..c0b2383db 100644
--- a/src/lib/marble/MarbleNavigator.h
+++ b/src/lib/marble/MarbleNavigator.h
@@ -1,132 +1,132 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
//
// This widget is a control box for the Marble widget.
//
#ifndef MARBLE_MARBLENAVIGATOR_H
#define MARBLE_MARBLENAVIGATOR_H
#include <QWidget>
#include "marble_export.h"
/** @file
* This file contains the header for MarbleNavigator
*
* @author Torsten Rahn <tackat@kde.org>
* @author Inge Wallin <inge@lysator.liu.se>
*/
namespace Marble
{
class MarbleNavigatorPrivate;
/**
* @short A widget class that contains simple controls for a
* MarbleWidget.
*
* This widget lets the user control an instance of MarbleWidget. The
* user can control panning and zooming as well as returning to a
* predefined view called the 'Home' position. You cannot change the
* Home position from the MarbleNavigator, though.
*
* @see MarbleWidget
*/
class MARBLE_EXPORT MarbleNavigator : public QWidget
{
Q_OBJECT
public:
/**
* @brief Construct a new MarbleNavigator
* @param parent the parent widget
*/
- explicit MarbleNavigator(QWidget *parent = 0);
+ explicit MarbleNavigator(QWidget *parent = nullptr);
~MarbleNavigator() override;
/**
* @brief Return the minimum zoom level set in the widget.
* @return the minimum zoom level set in the widget.
*/
int minimumZoom() const;
Q_SIGNALS:
/**
* @brief Signal emitted when the Home button has been pressed.
*/
void goHome();
/**
* @brief Signal emitted when the Zoom In button has been pressed.
*/
void zoomIn();
/**
* @brief Signal emitted when the Zoom Out button has been pressed.
*/
void zoomOut();
/**
* @brief Signal emitted when the zoom slider has been moved.
* @param zoom The new zoom value.
*/
void zoomChanged(int zoom);
/**
* @brief Signal emitted when the Move Left button has been pressed.
*/
void moveLeft();
/**
* @brief Signal emitted when the Move Right button has been pressed.
*/
void moveRight();
/**
* @brief Signal emitted when the Move Up button has been pressed.
*/
void moveUp();
/**
* @brief Signal emitted when the Move Down button has been pressed.
*/
void moveDown();
//void centerOn(const QModelIndex&);
public Q_SLOTS:
/**
* @brief Sets the value of the slider.
* @param zoom The new zoom value.
*
* This slot should be called when the zoom value is changed from
* the widget itself, e.g. by using the scroll wheel. It sets the
* value of the slider, but nothing more. In particular it
* doesn't emit the zoomChanged signal.
*/
void changeZoom(int zoom);
protected:
/**
* @brief Reimplementation of the resizeEvent() of the widget.
*
* If the MarbleNavigator gets shrunk enough, the slider will be
* hidden, leaving only the Zoom Up and Zoom Down buttons.
*/
void resizeEvent ( QResizeEvent * ) override;
private:
Q_DISABLE_COPY( MarbleNavigator )
MarbleNavigatorPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/MarblePlacemarkModel.cpp b/src/lib/marble/MarblePlacemarkModel.cpp
index a51a7a5fc..bcb855167 100644
--- a/src/lib/marble/MarblePlacemarkModel.cpp
+++ b/src/lib/marble/MarblePlacemarkModel.cpp
@@ -1,240 +1,240 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
// Own
#include "MarblePlacemarkModel.h"
#include "MarblePlacemarkModel_P.h"
// Qt
#include <QTime>
#include <QImage>
// Marble
#include "MarbleDebug.h"
#include "GeoDataPlacemark.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "GeoDataGeometry.h"
#include "GeoDataStyle.h" // In geodata/data/
#include "GeoDataIconStyle.h"
using namespace Marble;
class Q_DECL_HIDDEN MarblePlacemarkModel::Private
{
public:
Private()
: m_size(0),
- m_placemarkContainer( 0 )
+ m_placemarkContainer( nullptr )
{
}
~Private()
{
}
int m_size;
QVector<GeoDataPlacemark*> *m_placemarkContainer;
};
// ---------------------------------------------------------------------------
MarblePlacemarkModel::MarblePlacemarkModel( QObject *parent )
: QAbstractListModel( parent ),
d( new Private )
{
QHash<int,QByteArray> roles;
roles[DescriptionRole] = "description";
roles[Qt::DisplayRole] = "name";
roles[Qt::DecorationRole] = "icon";
roles[IconPathRole] = "iconPath";
roles[PopularityIndexRole] = "zoomLevel";
roles[VisualCategoryRole] = "visualCategory";
roles[AreaRole] = "area";
roles[PopulationRole] = "population";
roles[CountryCodeRole] = "countryCode";
roles[StateRole] = "state";
roles[PopularityRole] = "popularity";
roles[GeoTypeRole] = "role";
roles[CoordinateRole] = "coordinate";
roles[StyleRole] = "style";
roles[GmtRole] = "gmt";
roles[DstRole] = "dst";
roles[GeometryRole] = "geometry";
roles[ObjectPointerRole] = "objectPointer";
roles[LongitudeRole] = "longitude";
roles[LatitudeRole] = "latitude";
m_roleNames = roles;
}
MarblePlacemarkModel::~MarblePlacemarkModel()
{
delete d;
}
void MarblePlacemarkModel::setPlacemarkContainer( QVector<GeoDataPlacemark*> *container )
{
d->m_placemarkContainer = container;
}
int MarblePlacemarkModel::rowCount( const QModelIndex &parent ) const
{
if ( !parent.isValid() )
return d->m_size;
else
return 0;
}
int MarblePlacemarkModel::columnCount( const QModelIndex &parent ) const
{
if ( !parent.isValid() )
return 1;
else
return 0;
}
QHash<int, QByteArray> MarblePlacemarkModel::roleNames() const
{
return m_roleNames;
}
QVariant MarblePlacemarkModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() )
return QVariant();
if ( index.row() >= d->m_placemarkContainer->size() )
return QVariant();
if ( role == Qt::DisplayRole ) {
return d->m_placemarkContainer->at( index.row() )->name();
} else if ( role == Qt::DecorationRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->style()->iconStyle().icon() );
} else if ( role == IconPathRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->style()->iconStyle().iconPath() );
} else if ( role == PopularityIndexRole ) {
return d->m_placemarkContainer->at( index.row() )->zoomLevel();
} else if ( role == VisualCategoryRole ) {
return d->m_placemarkContainer->at( index.row() )->visualCategory();
} else if ( role == AreaRole ) {
return d->m_placemarkContainer->at( index.row() )->area();
} else if ( role == PopulationRole ) {
return d->m_placemarkContainer->at( index.row() )->population();
} else if ( role == CountryCodeRole ) {
return d->m_placemarkContainer->at( index.row() )->countryCode();
} else if ( role == StateRole ) {
return d->m_placemarkContainer->at( index.row() )->state();
} else if ( role == PopularityRole ) {
return d->m_placemarkContainer->at( index.row() )->popularity();
} else if ( role == DescriptionRole ) {
return d->m_placemarkContainer->at( index.row() )->description();
} else if ( role == Qt::ToolTipRole ) {
return d->m_placemarkContainer->at( index.row() )->description();
} else if ( role == GeoTypeRole ) {
return d->m_placemarkContainer->at( index.row() )->role();
} else if ( role == CoordinateRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->coordinate() );
} else if ( role == StyleRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->style().data() );
} else if ( role == GmtRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->extendedData().value(QStringLiteral("gmt")).value() );
} else if ( role == DstRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->extendedData().value(QStringLiteral("dst")).value() );
} else if ( role == GeometryRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->geometry() );
} else if ( role == ObjectPointerRole ) {
return qVariantFromValue( dynamic_cast<GeoDataObject*>( d->m_placemarkContainer->at( index.row() ) ) );
} else if ( role == LongitudeRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->coordinate().longitude( GeoDataCoordinates::Degree ) );
} else if ( role == LatitudeRole ) {
return qVariantFromValue( d->m_placemarkContainer->at( index.row() )->coordinate().latitude( GeoDataCoordinates::Degree ) );
} else
return QVariant();
}
QModelIndexList MarblePlacemarkModel::approxMatch( const QModelIndex & start, int role,
const QVariant & value, int hits,
Qt::MatchFlags flags ) const
{
QList<QModelIndex> results;
int count = 0;
QModelIndex entryIndex;
QString listName;
QString queryString = value.toString().toLower();
QString simplifiedListName;
int row = start.row();
const int rowNum = rowCount();
while ( row < rowNum && count != hits ) {
if ( flags & Qt::MatchStartsWith ) {
entryIndex = index( row, 0 );
listName = data( entryIndex, role ).toString().toLower();
simplifiedListName = GeoString::deaccent( listName );
if ( listName.startsWith( queryString )
|| simplifiedListName.startsWith( queryString )
)
{
results << entryIndex;
++count;
}
}
++row;
}
return results;
}
void MarblePlacemarkModel::addPlacemarks( int start,
int length )
{
Q_UNUSED(start);
// performance wise a reset is far better when the provided list
// is significant. That is an issue because we have
// MarbleControlBox::m_sortproxy as a sorting customer.
// I leave the balance search as an exercise to the reader...
QTime t;
t.start();
// beginInsertRows( QModelIndex(), start, start + length );
d->m_size += length;
// endInsertRows();
beginResetModel();
endResetModel();
emit countChanged();
mDebug() << "addPlacemarks: Time elapsed:" << t.elapsed() << "ms for" << length << "Placemarks.";
}
void MarblePlacemarkModel::removePlacemarks( const QString &containerName,
int start,
int length )
{
if ( length > 0 ) {
QTime t;
t.start();
beginRemoveRows( QModelIndex(), start, start + length );
d->m_size -= length;
endRemoveRows();
emit layoutChanged();
emit countChanged();
mDebug() << "removePlacemarks(" << containerName << "): Time elapsed:" << t.elapsed() << "ms for" << length << "Placemarks.";
}
}
#include "moc_MarblePlacemarkModel.cpp"
diff --git a/src/lib/marble/MarblePlacemarkModel.h b/src/lib/marble/MarblePlacemarkModel.h
index 0fc34362f..c3bc98853 100644
--- a/src/lib/marble/MarblePlacemarkModel.h
+++ b/src/lib/marble/MarblePlacemarkModel.h
@@ -1,134 +1,134 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
//
// MarblePlacemarkModel exposes the model for Placemarks
//
#ifndef MARBLE_MARBLEPLACEMARKMODEL_H
#define MARBLE_MARBLEPLACEMARKMODEL_H
#include <QAbstractListModel>
#include <QModelIndex>
#include "marble_export.h"
namespace Marble
{
class GeoDataCoordinates;
class GeoDataPlacemark;
/**
* This class represents a model of all place marks which
* are currently available through a given PlacemarkManager.
*/
class MARBLE_EXPORT MarblePlacemarkModel : public QAbstractListModel
{
friend class PlacemarkManager;
Q_OBJECT
Q_PROPERTY( int count READ rowCount NOTIFY countChanged )
public:
/**
* The roles of the place marks.
*/
enum Roles
{
GeoTypeRole = Qt::UserRole + 1, ///< The geo type (e.g. city or mountain)
DescriptionRole, ///< The description
CoordinateRole, ///< The GeoDataCoordinates coordinate
PopulationRole, ///< The population
AreaRole, ///< The area size
CountryCodeRole, ///< The country code
StateRole, ///< The state
VisualCategoryRole, ///< The category
StyleRole, ///< The style
PopularityIndexRole, ///< The popularity index
PopularityRole, ///< The popularity
ObjectPointerRole, ///< The pointer to a specific object
GmtRole, ///< The Greenwich Mean Time
DstRole, ///< The Daylight Saving Time
GeometryRole, ///< The GeoDataGeometry geometry
LongitudeRole, ///< The longitude in degree (for use in QML)
LatitudeRole, ///< The latitude in degree (for use in QML)
IconPathRole ///< Path to the image, if known
};
/**
* Creates a new place mark model.
*
* @param parent The parent object.
*/
- explicit MarblePlacemarkModel( QObject *parent = 0 );
+ explicit MarblePlacemarkModel( QObject *parent = nullptr );
/**
* Destroys the place mark model.
*/
~MarblePlacemarkModel() override;
void setPlacemarkContainer( QVector<GeoDataPlacemark*> *container );
/**
* Return the number of Placemarks in the Model.
*/
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
/**
* Return the supported role names
*/
QHash<int, QByteArray> roleNames() const override;
/**
* Return the data according to the index.
*
* @param index the index of the data
* @param role which part of the data to return. @see Roles
*/
QVariant data( const QModelIndex &index, int role ) const override;
QModelIndexList approxMatch( const QModelIndex &start, int role,
const QVariant &value, int hits = 1,
Qt::MatchFlags flags = Qt::MatchFlags( Qt::MatchStartsWith | Qt::MatchWrap ) ) const;
/**
* This method is used by the PlacemarkManager to add new
* place marks to the model.
*/
void addPlacemarks( int start,
int length );
/**
* This method is used by the PlacemarkManager to remove
* place marks from the model.
*/
void removePlacemarks( const QString &containerName,
int start,
int length );
Q_SIGNALS:
void countChanged();
private:
Q_DISABLE_COPY( MarblePlacemarkModel )
class Private;
Private* const d;
QHash<int, QByteArray> m_roleNames;
};
}
#endif
diff --git a/src/lib/marble/MarblePluginSettingsWidget.cpp b/src/lib/marble/MarblePluginSettingsWidget.cpp
index 3664a3b30..aaaef5239 100644
--- a/src/lib/marble/MarblePluginSettingsWidget.cpp
+++ b/src/lib/marble/MarblePluginSettingsWidget.cpp
@@ -1,128 +1,128 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Torsten Rahn <rahn@kde.org>
// Copyright 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
//
#include "MarblePluginSettingsWidget.h"
#include "ui_MarblePluginSettingsWidget.h"
// Qt
#include <QPointer>
#include <QDialog>
// Marble
#include "DialogConfigurationInterface.h"
#include "PluginAboutDialog.h"
#include "PluginItemDelegate.h"
#include "RenderPluginModel.h"
namespace Marble
{
class MarblePluginSettingsWidgetPrivate : public Ui::MarblePluginSettingsWidget
{
public:
explicit MarblePluginSettingsWidgetPrivate( Marble::MarblePluginSettingsWidget *parent ) :
q( parent ),
- m_itemDelegate( 0 )
+ m_itemDelegate( nullptr )
{}
/**
* Shows the about dialog for the plugin with the corresponding @p nameId.
*/
void showPluginAboutDialog( const QModelIndex &index );
/**
* Shows the configuration dialog for the plugin with the corresponding @p nameId.
*/
void showPluginConfigDialog( const QModelIndex &index );
Marble::MarblePluginSettingsWidget *const q;
PluginItemDelegate *m_itemDelegate;
QPointer<RenderPluginModel> m_pluginModel;
};
void MarblePluginSettingsWidgetPrivate::showPluginAboutDialog( const QModelIndex &index )
{
if ( m_pluginModel.isNull() )
return;
QPointer<PluginAboutDialog> aboutDialog = new PluginAboutDialog( q );
aboutDialog->setName( m_pluginModel->data( index, RenderPluginModel::Name ).toString() );
aboutDialog->setIcon( qvariant_cast<QIcon>( m_pluginModel->data( index, RenderPluginModel::Icon ) ) );
aboutDialog->setVersion( m_pluginModel->data( index, RenderPluginModel::Version ).toString() );
aboutDialog->setDataText( m_pluginModel->data( index, RenderPluginModel::AboutDataText ).toString() );
const QString copyrightText = QObject::tr( "<br/>(c) %1 The Marble Project<br /><br/><a href=\"http://edu.kde.org/marble\">http://edu.kde.org/marble</a>" );
aboutDialog->setAboutText( copyrightText.arg( m_pluginModel->data( index, RenderPluginModel::CopyrightYears ).toString() ) );
aboutDialog->setAuthors( m_pluginModel->pluginAuthors( index ) );
aboutDialog->exec();
delete aboutDialog;
}
void MarblePluginSettingsWidgetPrivate::showPluginConfigDialog( const QModelIndex &index )
{
if ( m_pluginModel.isNull() )
return;
DialogConfigurationInterface *configInterface = m_pluginModel->pluginDialogConfigurationInterface( index );;
- QDialog *configDialog = configInterface ? configInterface->configDialog() : 0;
+ QDialog *configDialog = configInterface ? configInterface->configDialog() : nullptr;
if ( configDialog ) {
configDialog->show();
}
}
MarblePluginSettingsWidget::MarblePluginSettingsWidget( QWidget *parent )
: QWidget( parent ),
d( new MarblePluginSettingsWidgetPrivate( this ) )
{
d->setupUi( this );
d->m_itemDelegate = new PluginItemDelegate( d->m_pluginListView, this );
d->m_pluginListView->setItemDelegate( d->m_itemDelegate );
connect( d->m_itemDelegate, SIGNAL(aboutPluginClicked(QModelIndex)),
this, SLOT(showPluginAboutDialog(QModelIndex)) );
connect( d->m_itemDelegate, SIGNAL(configPluginClicked(QModelIndex)),
this, SLOT(showPluginConfigDialog(QModelIndex)) );
}
void MarblePluginSettingsWidget::setAboutIcon( const QIcon& icon )
{
d->m_itemDelegate->setAboutIcon( icon );
}
MarblePluginSettingsWidget::~MarblePluginSettingsWidget()
{
delete d;
}
void MarblePluginSettingsWidget::setConfigIcon( const QIcon& icon )
{
d->m_itemDelegate->setConfigIcon( icon );
}
void MarblePluginSettingsWidget::setModel( RenderPluginModel* pluginModel )
{
if ( !d->m_pluginModel.isNull() ) {
- disconnect( d->m_pluginModel.data(), 0, this, 0 );
+ disconnect( d->m_pluginModel.data(), nullptr, this, nullptr );
}
d->m_pluginModel = pluginModel;
d->m_pluginListView->setModel( pluginModel );
if ( !d->m_pluginModel.isNull() ) {
connect( d->m_pluginModel.data(), SIGNAL(itemChanged(QStandardItem*)),
this, SIGNAL(pluginListViewClicked()) );
}
}
} // namespace Marble
#include "moc_MarblePluginSettingsWidget.cpp"
diff --git a/src/lib/marble/MarblePluginSettingsWidget.h b/src/lib/marble/MarblePluginSettingsWidget.h
index 6e63b7871..442f32880 100644
--- a/src/lib/marble/MarblePluginSettingsWidget.h
+++ b/src/lib/marble/MarblePluginSettingsWidget.h
@@ -1,65 +1,65 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
//
#ifndef MARBLE_MARBLEPLUGINSETTINGSWIDGET_H
#define MARBLE_MARBLEPLUGINSETTINGSWIDGET_H
/** @file
* This file contains the multiple inheritance ui-wrapper for the
* MarblePluginSettingsWidget ui file.
*
* @author Torsten Rahn <torsten@kde.org>
*/
#include <QWidget>
#include "marble_export.h"
class QModelIndex;
/**
* @short A public class that adds methods to the UI Plugins Settings Widget.
*
*/
namespace Marble
{
class MarblePluginSettingsWidgetPrivate;
class RenderPluginModel;
class MARBLE_EXPORT MarblePluginSettingsWidget : public QWidget
{
Q_OBJECT
public:
- explicit MarblePluginSettingsWidget( QWidget *parent = 0 );
+ explicit MarblePluginSettingsWidget( QWidget *parent = nullptr );
~MarblePluginSettingsWidget() override;
void setModel( RenderPluginModel* pluginModel );
void setAboutIcon( const QIcon& icon );
void setConfigIcon( const QIcon& icon );
Q_SIGNALS:
void pluginListViewClicked();
private:
Q_PRIVATE_SLOT( d, void showPluginAboutDialog( const QModelIndex & ) )
Q_PRIVATE_SLOT( d, void showPluginConfigDialog( const QModelIndex & ) )
private:
MarblePluginSettingsWidgetPrivate *d;
};
}
#endif
diff --git a/src/lib/marble/MarbleWebView.h b/src/lib/marble/MarbleWebView.h
index 69be7cf35..8c84b7ba8 100644
--- a/src/lib/marble/MarbleWebView.h
+++ b/src/lib/marble/MarbleWebView.h
@@ -1,36 +1,36 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef MARBLEWEBVIEW_H
#define MARBLEWEBVIEW_H
#include <QWebView>
#include "marble_export.h"
class MARBLE_EXPORT MarbleWebView : public QWebView
{
Q_OBJECT
public:
- explicit MarbleWebView(QWidget *parent = 0);
+ explicit MarbleWebView(QWidget *parent = nullptr);
protected:
void contextMenuEvent(QContextMenuEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
private Q_SLOTS:
void copySelectedText();
private:
QMenu *m_contextMenu;
QAction *m_copyAction;
};
#endif // MARBLEWEBVIEW_H
diff --git a/src/lib/marble/MarbleWidget.cpp b/src/lib/marble/MarbleWidget.cpp
index 2e79f7d64..c6d01d983 100644
--- a/src/lib/marble/MarbleWidget.cpp
+++ b/src/lib/marble/MarbleWidget.cpp
@@ -1,1252 +1,1252 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "MarbleWidget.h"
#include <qmath.h>
#include <QHash>
#include <QSettings>
#include <QTime>
#include <QPaintEvent>
#include <QPaintEngine>
#include <QRegion>
#include <QNetworkProxy>
#include <QMetaMethod>
#include "DataMigration.h"
#include "FpsLayer.h"
#include "FileManager.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLookAt.h"
#include "GeoPainter.h"
#include "MarbleClock.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleLocale.h"
#include "MarbleMap.h"
#include "MarbleModel.h"
#include "MarbleWidgetInputHandler.h"
#include "MarbleWidgetPopupMenu.h"
#include "Planet.h"
#include "PopupLayer.h"
#include "RenderState.h"
#include "RenderPlugin.h"
#include "SunLocator.h"
#include "TileCreatorDialog.h"
#include "ViewportParams.h"
#include "routing/RoutingLayer.h"
#include "MarbleAbstractPresenter.h"
#include "StyleBuilder.h"
namespace Marble
{
class MarbleWidget::CustomPaintLayer : public LayerInterface
{
public:
explicit CustomPaintLayer( MarbleWidget *widget )
: m_widget( widget )
{
}
QStringList renderPosition() const override { return QStringList() << "USER_TOOLS"; }
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos, GeoSceneLayer *layer ) override
{
Q_UNUSED( viewport );
Q_UNUSED( renderPos );
Q_UNUSED( layer );
painter->setPen( Qt::black );
m_widget->customPaint( painter );
return true;
}
qreal zValue() const override { return 1.0e7; }
RenderState renderState() const override { return RenderState(QStringLiteral("Custom Widget Paint")); }
QString runtimeTrace() const override { return QStringLiteral("MarbleWidget::CustomPaintLayer"); }
private:
MarbleWidget *const m_widget;
};
class MarbleWidgetPrivate
{
public:
explicit MarbleWidgetPrivate( MarbleWidget *parent ) :
m_widget( parent ),
m_model(),
m_map( &m_model ),
m_presenter( &m_map ),
- m_inputhandler( 0 ),
- m_routingLayer( 0 ),
- m_mapInfoDialog( 0 ),
+ m_inputhandler( nullptr ),
+ m_routingLayer( nullptr ),
+ m_mapInfoDialog( nullptr ),
m_customPaintLayer( parent ),
- m_popupmenu( 0 ),
+ m_popupmenu( nullptr ),
m_showFrameRate( false )
{
}
~MarbleWidgetPrivate()
{
m_map.removeLayer( &m_customPaintLayer );
m_map.removeLayer( m_mapInfoDialog );
delete m_mapInfoDialog;
delete m_popupmenu;
}
void construct();
void updateMapTheme();
void setInputHandler();
void setInputHandler( MarbleWidgetInputHandler *handler );
/**
* @brief Update widget flags and cause a full repaint
*
* The background of the widget only needs to be redrawn in certain cases. This
* method sets the widget flags accordingly and triggers a repaint.
*/
void updateSystemBackgroundAttribute();
MarbleWidget *const m_widget;
MarbleModel m_model;
MarbleMap m_map;
MarbleAbstractPresenter m_presenter;
MarbleWidgetInputHandler *m_inputhandler;
RoutingLayer *m_routingLayer;
PopupLayer *m_mapInfoDialog;
MarbleWidget::CustomPaintLayer m_customPaintLayer;
MarbleWidgetPopupMenu *m_popupmenu;
bool m_showFrameRate;
};
MarbleWidget::MarbleWidget(QWidget *parent)
: QWidget( parent ),
d( new MarbleWidgetPrivate( this ) )
{
// setAttribute( Qt::WA_PaintOnScreen, true );
d->construct();
}
MarbleWidget::~MarbleWidget()
{
// Remove and delete an existing InputHandler
// initialized in d->construct()
- setInputHandler( 0 );
+ setInputHandler( nullptr );
delete d;
}
void MarbleWidgetPrivate::construct()
{
QPointer<DataMigration> dataMigration = new DataMigration( m_widget );
dataMigration->exec();
delete dataMigration;
// Widget settings
m_widget->setMinimumSize( 200, 300 );
m_widget->setFocusPolicy( Qt::WheelFocus );
m_widget->setFocus( Qt::OtherFocusReason );
// Set background: black.
m_widget->setPalette( QPalette ( Qt::black ) );
// Set whether the black space gets displayed or the earth gets simply
// displayed on the widget background.
m_widget->setAutoFillBackground( true );
// Initialize the map and forward some signals.
m_map.setSize( m_widget->width(), m_widget->height() );
m_map.setShowFrameRate( false ); // never let the map draw the frame rate,
// we do this differently here in the widget
m_widget->connect( &m_presenter, SIGNAL(regionSelected(GeoDataLatLonBox)), m_widget, SIGNAL(regionSelected(GeoDataLatLonBox)) );
m_widget->connect( &m_presenter, SIGNAL(zoomChanged(int)), m_widget, SIGNAL(zoomChanged(int)) );
m_widget->connect( &m_presenter, SIGNAL(distanceChanged(QString)), m_widget, SIGNAL(distanceChanged(QString)) );
// forward some signals of m_map
m_widget->connect( &m_map, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)) );
m_widget->connect( &m_map, SIGNAL(projectionChanged(Projection)),
m_widget, SIGNAL(projectionChanged(Projection)) );
m_widget->connect( &m_map, SIGNAL(tileLevelChanged(int)),
m_widget, SIGNAL(tileLevelChanged(int)) );
m_widget->connect( &m_map, SIGNAL(framesPerSecond(qreal)),
m_widget, SIGNAL(framesPerSecond(qreal)) );
m_widget->connect( &m_map, SIGNAL(viewContextChanged(ViewContext)),
m_widget, SLOT(setViewContext(ViewContext)) );
m_widget->connect( &m_map, SIGNAL(pluginSettingsChanged()),
m_widget, SIGNAL(pluginSettingsChanged()) );
m_widget->connect( &m_map, SIGNAL(renderPluginInitialized(RenderPlugin*)),
m_widget, SIGNAL(renderPluginInitialized(RenderPlugin*)) );
// react to some signals of m_map
m_widget->connect( &m_map, SIGNAL(themeChanged(QString)),
m_widget, SLOT(updateMapTheme()) );
m_widget->connect( &m_map, SIGNAL(viewContextChanged(ViewContext)),
m_widget, SIGNAL(viewContextChanged(ViewContext)) );
m_widget->connect( &m_map, SIGNAL(repaintNeeded(QRegion)),
m_widget, SLOT(update()) );
m_widget->connect( &m_map, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
m_widget, SLOT(updateSystemBackgroundAttribute()) );
m_widget->connect( &m_map, SIGNAL(renderStatusChanged(RenderStatus)),
m_widget, SIGNAL(renderStatusChanged(RenderStatus)) );
m_widget->connect( &m_map, SIGNAL(renderStateChanged(RenderState)),
m_widget, SIGNAL(renderStateChanged(RenderState)) );
m_widget->connect( m_model.fileManager(), SIGNAL(centeredDocument(GeoDataLatLonBox)),
m_widget, SLOT(centerOn(GeoDataLatLonBox)) );
// Show a progress dialog when the model calculates new map tiles.
m_widget->connect( &m_model, SIGNAL( creatingTilesStart( TileCreator*, const QString&,
const QString& ) ),
m_widget, SLOT( creatingTilesStart( TileCreator*, const QString&,
const QString& ) ) );
m_popupmenu = new MarbleWidgetPopupMenu( m_widget, &m_model );
m_routingLayer = new RoutingLayer( m_widget, m_widget );
- m_routingLayer->setPlacemarkModel( 0 );
+ m_routingLayer->setPlacemarkModel( nullptr );
QObject::connect( m_routingLayer, SIGNAL(repaintNeeded(QRect)),
m_widget, SLOT(update()) );
m_mapInfoDialog = new PopupLayer( m_widget, m_widget );
m_mapInfoDialog->setVisible( false );
m_widget->connect( m_mapInfoDialog, SIGNAL(repaintNeeded()), m_widget, SLOT(update()) );
m_map.addLayer( m_mapInfoDialog );
setInputHandler();
m_widget->setMouseTracking( true );
m_map.addLayer( &m_customPaintLayer );
m_widget->connect( m_inputhandler, SIGNAL(mouseClickGeoPosition(qreal,qreal,GeoDataCoordinates::Unit)),
m_widget, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)) );
m_widget->setHighlightEnabled( true );
}
void MarbleWidgetPrivate::setInputHandler()
{
setInputHandler( new MarbleWidgetInputHandler( &m_presenter, m_widget ) );
}
void MarbleWidgetPrivate::setInputHandler( MarbleWidgetInputHandler *handler )
{
delete m_inputhandler;
m_inputhandler = handler;
if ( m_inputhandler )
{
m_widget->installEventFilter( m_inputhandler );
QObject::connect( m_inputhandler, SIGNAL(mouseClickScreenPosition(int,int)),
m_widget, SLOT(notifyMouseClick(int,int)) );
QObject::connect( m_inputhandler, SIGNAL(mouseMoveGeoPosition(QString)),
m_widget, SIGNAL(mouseMoveGeoPosition(QString)) );
}
}
void MarbleWidgetPrivate::updateSystemBackgroundAttribute()
{
// We only have to repaint the background every time if the earth
// doesn't cover the whole image.
const bool isOn = m_map.viewport()->mapCoversViewport() && !m_model.mapThemeId().isEmpty();
m_widget->setAttribute( Qt::WA_NoSystemBackground, isOn );
}
// ----------------------------------------------------------------
MarbleModel *MarbleWidget::model()
{
return &d->m_model;
}
const MarbleModel *MarbleWidget::model() const
{
return &d->m_model;
}
ViewportParams* MarbleWidget::viewport()
{
return d->m_map.viewport();
}
const ViewportParams* MarbleWidget::viewport() const
{
return d->m_map.viewport();
}
MarbleWidgetPopupMenu *MarbleWidget::popupMenu()
{
return d->m_popupmenu;
}
void MarbleWidget::setInputHandler( MarbleWidgetInputHandler *handler )
{
d->setInputHandler(handler);
}
MarbleWidgetInputHandler *MarbleWidget::inputHandler() const
{
return d->m_inputhandler;
}
int MarbleWidget::radius() const
{
return d->m_map.radius();
}
void MarbleWidget::setRadius( int radius )
{
d->m_map.setRadius( radius );
}
qreal MarbleWidget::moveStep() const
{
return d->m_presenter.moveStep();
}
int MarbleWidget::zoom() const
{
return d->m_presenter.logzoom();
}
int MarbleWidget::tileZoomLevel() const
{
return d->m_map.tileZoomLevel();
}
int MarbleWidget::minimumZoom() const
{
return d->m_map.minimumZoom();
}
int MarbleWidget::maximumZoom() const
{
return d->m_map.maximumZoom();
}
QVector<const GeoDataFeature*> MarbleWidget::whichFeatureAt( const QPoint &curpos ) const
{
return d->m_map.whichFeatureAt( curpos );
}
QList<AbstractDataPluginItem*> MarbleWidget::whichItemAt( const QPoint &curpos ) const
{
return d->m_map.whichItemAt( curpos );
}
void MarbleWidget::addLayer( LayerInterface *layer )
{
d->m_map.addLayer( layer );
}
void MarbleWidget::removeLayer( LayerInterface *layer )
{
d->m_map.removeLayer( layer );
}
Marble::TextureLayer* MarbleWidget::textureLayer() const
{
return d->m_map.textureLayer();
}
QPixmap MarbleWidget::mapScreenShot()
{
return QPixmap::grabWidget( this );
}
RenderStatus MarbleWidget::renderStatus() const
{
return d->m_map.renderStatus();
}
RenderState MarbleWidget::renderState() const
{
return d->m_map.renderState();
}
void MarbleWidget::setHighlightEnabled(bool enabled)
{
if ( enabled ) {
connect( this, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
&d->m_map, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
Qt::UniqueConnection );
}
else {
disconnect( this, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
&d->m_map, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)) );
}
}
bool MarbleWidget::showOverviewMap() const
{
return d->m_map.showOverviewMap();
}
bool MarbleWidget::showScaleBar() const
{
return d->m_map.showScaleBar();
}
bool MarbleWidget::showCompass() const
{
return d->m_map.showCompass();
}
bool MarbleWidget::showClouds() const
{
return d->m_map.showClouds();
}
bool MarbleWidget::showSunShading() const
{
return d->m_map.showSunShading();
}
bool MarbleWidget::showCityLights() const
{
return d->m_map.showCityLights();
}
bool MarbleWidget::isLockedToSubSolarPoint() const
{
return d->m_map.isLockedToSubSolarPoint();
}
bool MarbleWidget::isSubSolarPointIconVisible() const
{
return d->m_map.isSubSolarPointIconVisible();
}
bool MarbleWidget::showAtmosphere() const
{
return d->m_map.showAtmosphere();
}
bool MarbleWidget::showCrosshairs() const
{
return d->m_map.showCrosshairs();
}
bool MarbleWidget::showGrid() const
{
return d->m_map.showGrid();
}
bool MarbleWidget::showPlaces() const
{
return d->m_map.showPlaces();
}
bool MarbleWidget::showCities() const
{
return d->m_map.showCities();
}
bool MarbleWidget::showTerrain() const
{
return d->m_map.showTerrain();
}
bool MarbleWidget::showOtherPlaces() const
{
return d->m_map.showOtherPlaces();
}
bool MarbleWidget::showRelief() const
{
return d->m_map.showRelief();
}
bool MarbleWidget::showIceLayer() const
{
return d->m_map.showIceLayer();
}
bool MarbleWidget::showBorders() const
{
return d->m_map.showBorders();
}
bool MarbleWidget::showRivers() const
{
return d->m_map.showRivers();
}
bool MarbleWidget::showLakes() const
{
return d->m_map.showLakes();
}
bool MarbleWidget::showFrameRate() const
{
return d->m_showFrameRate;
}
bool MarbleWidget::showBackground() const
{
return d->m_map.showBackground();
}
quint64 MarbleWidget::volatileTileCacheLimit() const
{
return d->m_map.volatileTileCacheLimit();
}
void MarbleWidget::setZoom( int newZoom, FlyToMode mode )
{
d->m_presenter.setZoom( newZoom, mode );
}
void MarbleWidget::zoomView( int zoom, FlyToMode mode )
{
d->m_presenter.zoomView( zoom, mode );
}
void MarbleWidget::zoomViewBy( int zoomStep, FlyToMode mode )
{
d->m_presenter.zoomViewBy( zoomStep, mode );
}
void MarbleWidget::zoomIn( FlyToMode mode )
{
d->m_presenter.zoomIn( mode );
}
void MarbleWidget::zoomOut( FlyToMode mode )
{
d->m_presenter.zoomOut( mode );
}
void MarbleWidget::rotateBy( const qreal deltaLon, const qreal deltaLat, FlyToMode mode )
{
d->m_presenter.rotateBy( deltaLon, deltaLat, mode );
}
void MarbleWidget::centerOn( const qreal lon, const qreal lat, bool animated )
{
d->m_presenter.centerOn( lon, lat, animated );
}
void MarbleWidget::centerOn( const GeoDataCoordinates &position, bool animated )
{
d->m_presenter.centerOn( position, animated );
}
void MarbleWidget::centerOn( const GeoDataLatLonBox &box, bool animated )
{
d->m_presenter.centerOn( box, animated );
}
void MarbleWidget::centerOn( const GeoDataPlacemark& placemark, bool animated )
{
d->m_presenter.centerOn( placemark, animated );
}
void MarbleWidget::setCenterLatitude( qreal lat, FlyToMode mode )
{
d->m_presenter.setCenterLatitude( lat, mode );
}
void MarbleWidget::setCenterLongitude( qreal lon, FlyToMode mode )
{
d->m_presenter.setCenterLongitude( lon, mode );
}
Projection MarbleWidget::projection() const
{
return d->m_map.projection();
}
void MarbleWidget::setProjection( Projection projection )
{
d->m_map.setProjection( projection );
}
void MarbleWidget::setProjection( int projection )
{
setProjection( Projection( qAbs( projection ) % (Mercator+1) ) );
}
void MarbleWidget::moveLeft( FlyToMode mode )
{
d->m_presenter.moveByStep( -1, 0, mode );
}
void MarbleWidget::moveRight( FlyToMode mode )
{
d->m_presenter.moveByStep( 1, 0, mode );
}
void MarbleWidget::moveUp( FlyToMode mode )
{
d->m_presenter.moveByStep( 0, -1, mode );
}
void MarbleWidget::moveDown( FlyToMode mode )
{
d->m_presenter.moveByStep( 0, 1, mode );
}
void MarbleWidget::leaveEvent( QEvent* )
{
emit mouseMoveGeoPosition( QCoreApplication::translate( "Marble", NOT_AVAILABLE ) );
}
void MarbleWidget::resizeEvent( QResizeEvent *event )
{
setUpdatesEnabled( false );
d->m_map.setSize( event->size() );
setUpdatesEnabled( true );
QWidget::resizeEvent( event );
}
void MarbleWidget::connectNotify( const QMetaMethod &signal )
{
if ( d->m_inputhandler && signal == QMetaMethod::fromSignal( &MarbleWidget::mouseMoveGeoPosition ) ) {
d->m_inputhandler->setPositionSignalConnected( true );
}
}
void MarbleWidget::disconnectNotify( const QMetaMethod &signal )
{
if ( d->m_inputhandler && signal == QMetaMethod::fromSignal( &MarbleWidget::mouseMoveGeoPosition ) ) {
d->m_inputhandler->setPositionSignalConnected( false );
}
}
bool MarbleWidget::screenCoordinates( qreal lon, qreal lat,
qreal& x, qreal& y ) const
{
return d->m_map.screenCoordinates( lon, lat, x, y );
}
bool MarbleWidget::geoCoordinates( int x, int y,
qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit ) const
{
return d->m_map.geoCoordinates( x, y, lon, lat, unit );
}
qreal MarbleWidget::centerLatitude() const
{
return d->m_map.centerLatitude();
}
qreal MarbleWidget::centerLongitude() const
{
return d->m_map.centerLongitude();
}
QRegion MarbleWidget::mapRegion() const
{
return viewport()->mapRegion();
}
void MarbleWidget::paintEvent( QPaintEvent *evt )
{
QTime t;
t.start();
QPaintDevice *paintDevice = this;
QImage image;
if (!isEnabled())
{
// If the globe covers fully the screen then we can use the faster
// RGB32 as there are no translucent areas involved.
QImage::Format imageFormat = ( d->m_map.viewport()->mapCoversViewport() )
? QImage::Format_RGB32
: QImage::Format_ARGB32_Premultiplied;
// Paint to an intermediate image
image = QImage( rect().size(), imageFormat );
image.fill( Qt::transparent );
paintDevice = &image;
}
{
// FIXME: Better way to get the GeoPainter
// Create a painter that will do the painting.
GeoPainter geoPainter( paintDevice, d->m_map.viewport(), d->m_map.mapQuality() );
d->m_map.paint( geoPainter, evt->rect() );
}
if ( !isEnabled() )
{
// Draw a grayscale version of the intermediate image
QRgb* pixel = reinterpret_cast<QRgb*>( image.scanLine( 0 ));
for (int i=0; i<image.width()*image.height(); ++i, ++pixel) {
int gray = qGray( *pixel );
*pixel = qRgb( gray, gray, gray );
}
QPainter widgetPainter( this );
widgetPainter.drawImage( rect(), image );
}
if ( d->m_showFrameRate )
{
QPainter painter( this );
FpsLayer fpsPainter( &t );
fpsPainter.paint( &painter );
const qreal fps = 1000.0 / (qreal)( t.elapsed() + 1 );
emit framesPerSecond( fps );
}
}
void MarbleWidget::customPaint( GeoPainter *painter )
{
Q_UNUSED( painter );
/* This is a NOOP in the base class*/
}
void MarbleWidget::goHome( FlyToMode mode )
{
d->m_presenter.goHome( mode );
}
QString MarbleWidget::mapThemeId() const
{
return d->m_model.mapThemeId();
}
void MarbleWidget::setMapThemeId( const QString& mapThemeId )
{
d->m_map.setMapThemeId( mapThemeId );
}
void MarbleWidgetPrivate::updateMapTheme()
{
m_map.removeLayer( m_routingLayer );
m_widget->setRadius( m_widget->radius() ); // Corrects zoom range, if needed
if (m_model.planetId() == QLatin1String("earth")) {
m_map.addLayer( m_routingLayer );
}
emit m_widget->themeChanged( m_map.mapThemeId() );
// Now we want a full repaint as the atmosphere might differ
m_widget->setAttribute( Qt::WA_NoSystemBackground, false );
m_widget->update();
}
GeoSceneDocument *MarbleWidget::mapTheme() const
{
return d->m_model.mapTheme();
}
void MarbleWidget::setPropertyValue( const QString& name, bool value )
{
mDebug() << "In MarbleWidget the property " << name << "was set to " << value;
d->m_map.setPropertyValue( name, value );
}
void MarbleWidget::setShowOverviewMap( bool visible )
{
d->m_map.setShowOverviewMap( visible );
}
void MarbleWidget::setShowScaleBar( bool visible )
{
d->m_map.setShowScaleBar( visible );
}
void MarbleWidget::setShowCompass( bool visible )
{
d->m_map.setShowCompass( visible );
}
void MarbleWidget::setShowClouds( bool visible )
{
d->m_map.setShowClouds( visible );
}
void MarbleWidget::setShowSunShading( bool visible )
{
d->m_map.setShowSunShading( visible );
}
void MarbleWidget::setShowCityLights( bool visible )
{
d->m_map.setShowCityLights( visible );
}
void MarbleWidget::setLockToSubSolarPoint( bool visible )
{
if ( d->m_map.isLockedToSubSolarPoint() != visible ) { // Toggling input modifies event filters, so avoid that if not needed
d->m_map.setLockToSubSolarPoint( visible );
setInputEnabled( !d->m_map.isLockedToSubSolarPoint() );
}
}
void MarbleWidget::setSubSolarPointIconVisible( bool visible )
{
if ( d->m_map.isSubSolarPointIconVisible() != visible ) {
d->m_map.setSubSolarPointIconVisible( visible );
}
QList<RenderPlugin *> pluginList = renderPlugins();
QList<RenderPlugin *>::const_iterator i = pluginList.constBegin();
QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
for (; i != end; ++i ) {
if ((*i)->nameId() == QLatin1String("sun")) {
(*i)->setVisible( visible );
}
}
}
void MarbleWidget::setShowAtmosphere( bool visible )
{
d->m_map.setShowAtmosphere( visible );
}
void MarbleWidget::setShowCrosshairs( bool visible )
{
d->m_map.setShowCrosshairs( visible );
}
void MarbleWidget::setShowGrid( bool visible )
{
d->m_map.setShowGrid( visible );
}
void MarbleWidget::setShowPlaces( bool visible )
{
d->m_map.setShowPlaces( visible );
}
void MarbleWidget::setShowCities( bool visible )
{
d->m_map.setShowCities( visible );
}
void MarbleWidget::setShowTerrain( bool visible )
{
d->m_map.setShowTerrain( visible );
}
void MarbleWidget::setShowOtherPlaces( bool visible )
{
d->m_map.setShowOtherPlaces( visible );
}
void MarbleWidget::setShowRelief( bool visible )
{
d->m_map.setShowRelief( visible );
}
void MarbleWidget::setShowIceLayer( bool visible )
{
d->m_map.setShowIceLayer( visible );
}
void MarbleWidget::setShowBorders( bool visible )
{
d->m_map.setShowBorders( visible );
}
void MarbleWidget::setShowRivers( bool visible )
{
d->m_map.setShowRivers( visible );
}
void MarbleWidget::setShowLakes( bool visible )
{
d->m_map.setShowLakes( visible );
}
void MarbleWidget::setShowFrameRate( bool visible )
{
d->m_showFrameRate = visible;
update();
}
void MarbleWidget::setShowBackground( bool visible )
{
d->m_map.setShowBackground( visible );
}
void MarbleWidget::setShowRuntimeTrace( bool visible )
{
d->m_map.setShowRuntimeTrace( visible );
}
bool MarbleWidget::showRuntimeTrace() const
{
return d->m_map.showRuntimeTrace();
}
void MarbleWidget::setShowDebugPolygons( bool visible)
{
d->m_map.setShowDebugPolygons( visible );
}
bool MarbleWidget::showDebugPolygons() const
{
return d->m_map.showDebugPolygons();
}
void MarbleWidget::setShowDebugBatchRender( bool visible)
{
d->m_map.setShowDebugBatchRender( visible );
}
bool MarbleWidget::showDebugBatchRender() const
{
return d->m_map.showDebugBatchRender();
}
void MarbleWidget::setShowDebugPlacemarks( bool visible)
{
d->m_map.setShowDebugPlacemarks( visible );
}
bool MarbleWidget::showDebugPlacemarks() const
{
return d->m_map.showDebugPlacemarks();
}
void MarbleWidget::setDebugLevelTags(bool visible)
{
d->m_map.setLevelTagDebugModeEnabled(visible);
}
bool MarbleWidget::debugLevelTags() const
{
return d->m_map.levelTagDebugModeEnabled();
}
void MarbleWidget::setShowTileId( bool visible )
{
d->m_map.setShowTileId( visible );
}
void MarbleWidget::notifyMouseClick( int x, int y)
{
qreal lon = 0;
qreal lat = 0;
bool const valid = geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian );
if ( valid ) {
emit mouseClickGeoPosition( lon, lat, GeoDataCoordinates::Radian );
}
}
void MarbleWidget::clearVolatileTileCache()
{
mDebug() << "About to clear VolatileTileCache";
d->m_map.clearVolatileTileCache();
}
void MarbleWidget::setVolatileTileCacheLimit( quint64 kiloBytes )
{
d->m_map.setVolatileTileCacheLimit( kiloBytes );
}
// This slot will called when the Globe starts to create the tiles.
void MarbleWidget::creatingTilesStart( TileCreator *creator,
const QString &name,
const QString &description )
{
QPointer<TileCreatorDialog> dialog = new TileCreatorDialog( creator, this );
dialog->setSummary( name, description );
dialog->exec();
delete dialog;
}
MapQuality MarbleWidget::mapQuality( ViewContext viewContext ) const
{
return d->m_map.mapQuality( viewContext );
}
void MarbleWidget::setMapQualityForViewContext( MapQuality quality, ViewContext viewContext )
{
d->m_map.setMapQualityForViewContext( quality, viewContext );
}
ViewContext MarbleWidget::viewContext() const
{
return d->m_map.viewContext();
}
void MarbleWidget::setViewContext( ViewContext viewContext )
{
// Inform routing layer about view context change. If not done,
// the routing layer causes severe performance problems when dragging the
// map. So either do not remove this line, or keep a similar call in place
// when you refactor it and test your changes wrt drag performance at
// high zoom level with long routes!
d->m_routingLayer->setViewContext( viewContext );
d->m_map.setViewContext( viewContext );
}
bool MarbleWidget::animationsEnabled() const
{
return d->m_presenter.animationsEnabled();
}
void MarbleWidget::setAnimationsEnabled( bool enabled )
{
d->m_presenter.setAnimationsEnabled( enabled );
}
AngleUnit MarbleWidget::defaultAngleUnit() const
{
return d->m_map.defaultAngleUnit();
}
void MarbleWidget::setDefaultAngleUnit( AngleUnit angleUnit )
{
d->m_map.setDefaultAngleUnit( angleUnit );
}
QFont MarbleWidget::defaultFont() const
{
return d->m_map.defaultFont();
}
void MarbleWidget::setDefaultFont( const QFont& font )
{
d->m_map.setDefaultFont( font );
}
void MarbleWidget::setSelection( const QRect& region )
{
d->m_presenter.setSelection( region );
}
qreal MarbleWidget::distance() const
{
return d->m_presenter.distance();
}
void MarbleWidget::setDistance( qreal newDistance )
{
d->m_presenter.setDistance( newDistance );
}
QString MarbleWidget::distanceString() const
{
return d->m_presenter.distanceString();
}
void MarbleWidget::setInputEnabled( bool enabled )
{
//if input is set as enabled
if ( enabled )
{
if ( !d->m_inputhandler ) {
d->setInputHandler();
}
else {
installEventFilter( d->m_inputhandler );
}
}
else // input is disabled
{
mDebug() << "MarbleWidget::disableInput";
removeEventFilter( d->m_inputhandler );
setCursor( Qt::ArrowCursor );
}
}
QList<RenderPlugin *> MarbleWidget::renderPlugins() const
{
return d->m_map.renderPlugins();
}
void MarbleWidget::readPluginSettings( QSettings& settings )
{
for( RenderPlugin *plugin: renderPlugins() ) {
settings.beginGroup(QLatin1String("plugin_") + plugin->nameId());
QHash<QString,QVariant> hash;
for ( const QString& key: settings.childKeys() ) {
hash.insert( key, settings.value( key ) );
}
plugin->setSettings( hash );
settings.endGroup();
}
}
void MarbleWidget::writePluginSettings( QSettings& settings ) const
{
for( RenderPlugin *plugin: renderPlugins() ) {
settings.beginGroup(QLatin1String("plugin_") + plugin->nameId());
QHash<QString,QVariant> hash = plugin->settings();
QHash<QString,QVariant>::iterator it = hash.begin();
while( it != hash.end() ) {
settings.setValue( it.key(), it.value() );
++it;
}
settings.endGroup();
}
}
QList<AbstractFloatItem *> MarbleWidget::floatItems() const
{
return d->m_map.floatItems();
}
AbstractFloatItem * MarbleWidget::floatItem( const QString &nameId ) const
{
return d->m_map.floatItem( nameId );
}
void MarbleWidget::changeEvent( QEvent * event )
{
if ( event->type() == QEvent::EnabledChange )
{
setInputEnabled(isEnabled());
}
QWidget::changeEvent(event);
}
void MarbleWidget::flyTo( const GeoDataLookAt &newLookAt, FlyToMode mode )
{
d->m_presenter.flyTo( newLookAt, mode );
}
void MarbleWidget::reloadMap()
{
d->m_map.reload();
}
void MarbleWidget::downloadRegion( QVector<TileCoordsPyramid> const & pyramid )
{
d->m_map.downloadRegion( pyramid );
}
GeoDataLookAt MarbleWidget::lookAt() const
{
return d->m_presenter.lookAt();
}
GeoDataCoordinates MarbleWidget::focusPoint() const
{
return d->m_map.viewport()->focusPoint();
}
void MarbleWidget::setFocusPoint( const GeoDataCoordinates &focusPoint )
{
d->m_map.viewport()->setFocusPoint( focusPoint );
}
void MarbleWidget::resetFocusPoint()
{
d->m_map.viewport()->resetFocusPoint();
}
qreal MarbleWidget::radiusFromDistance( qreal distance ) const
{
return d->m_presenter.radiusFromDistance( distance );
}
qreal MarbleWidget::distanceFromRadius( qreal radius ) const
{
return d->m_presenter.distanceFromRadius( radius );
}
qreal MarbleWidget::zoomFromDistance( qreal distance ) const
{
return d->m_presenter.zoomFromDistance( distance );
}
qreal MarbleWidget::distanceFromZoom( qreal zoom ) const
{
return d->m_presenter.distanceFromZoom( zoom );
}
RoutingLayer* MarbleWidget::routingLayer()
{
return d->m_routingLayer;
}
PopupLayer *MarbleWidget::popupLayer()
{
return d->m_mapInfoDialog;
}
const StyleBuilder* MarbleWidget::styleBuilder() const
{
return d->m_map.styleBuilder();
}
void MarbleWidget::setHeading( qreal heading )
{
d->m_map.setHeading( heading );
}
qreal MarbleWidget::heading() const
{
return d->m_map.heading();
}
void MarbleWidget::setLevelToDebug(int level)
{
d->m_map.setDebugLevelTag(level);
}
int MarbleWidget::levelToDebug() const
{
return d->m_map.debugLevelTag();
}
}
#include "moc_MarbleWidget.cpp"
diff --git a/src/lib/marble/MarbleWidget.h b/src/lib/marble/MarbleWidget.h
index 91ca60bfe..26420aa94 100644
--- a/src/lib/marble/MarbleWidget.h
+++ b/src/lib/marble/MarbleWidget.h
@@ -1,1174 +1,1174 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2008 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
#ifndef MARBLE_MARBLEWIDGET_H
#define MARBLE_MARBLEWIDGET_H
/** @file
* This file contains the headers for MarbleWidget.
*
* @author Torsten Rahn <tackat@kde.org>
* @author Inge Wallin <inge@lysator.liu.se>
*/
#include <QWidget>
#include "GeoDataCoordinates.h"
#include "MarbleGlobal.h" // types needed in all of marble.
#include "marble_export.h"
// Qt
class QSettings;
class QPixmap;
namespace Marble
{
class AbstractDataPluginItem;
class AbstractFloatItem;
class GeoDataLatLonAltBox;
class GeoDataLatLonBox;
class GeoDataFeature;
class GeoDataPlacemark;
class GeoDataLookAt;
class GeoPainter;
class GeoSceneDocument;
class LayerInterface;
class MarbleModel;
class MarbleWidgetPopupMenu;
class MarbleWidgetInputHandler;
class MarbleWidgetPrivate;
class RenderPlugin;
class RenderState;
class RoutingLayer;
class TextureLayer;
class TileCoordsPyramid;
class TileCreator;
class ViewportParams;
class PopupLayer;
class StyleBuilder;
/**
* @short A widget class that displays a view of the earth.
*
* This widget displays a view of the earth or any other globe,
* depending on which dataset is used. The user can navigate the
* globe using either a control widget, e.g. the MarbleNavigator, or
* the mouse. The mouse and keyboard control is done through a
* MarbleWidgetInputHandler. Only some aspects of the widget can be
* controlled by the mouse and/or keyboard.
*
* By clicking on the globe and moving the mouse, the position can be
* changed. The user can also zoom by using the scroll wheel of the
* mouse in the widget. The zoom value is not tied to any units, but
* is an abstract value without any physical meaning. A value around
* 1000 shows the full globe in a normal-sized window. Higher zoom
* values give a more zoomed-in view.
*
* The MarbleWidget owns a data model to work. This model is contained
* in the MarbleModel class, and it is painted by using a MarbleMap.
* The widget takes care of creating the map and model. A MarbleModel
* contains several datatypes, among them <b>tiles</b> which provide the
* background, <b>vectors</b> which provide things like country
* borders and coastlines and <b>placemarks</b> which can show points
* of interest, such as cities, mountain tops or the poles.
*
* In addition to navigating with the mouse, you can also use it to
* get information about items on the map. You can either click on a
* placemark with the left mouse button or with the right mouse button
* anywhere on the map.
*
* The left mouse button opens up a menu with all the placemarks
* within a certain distance from the mouse pointer. When you choose
* one item from the menu, Marble will open up a dialog window with
* some information about the placemark and also try to connect to
* Wikipedia to retrieve an article about it. If there is such an
* article, you will get a mini-browser window with the article in a tab.
*
* @see MarbleNavigator
* @see MarbleMap
* @see MarbleModel
*/
class MARBLE_EXPORT MarbleWidget : public QWidget
{
Q_OBJECT
#ifdef MARBLE_DBUS
Q_CLASSINFO("D-Bus Interface", "org.kde.MarbleWidget")
#endif
Q_PROPERTY(int zoom READ zoom WRITE setZoom)
Q_PROPERTY(QString mapThemeId READ mapThemeId WRITE setMapThemeId)
Q_PROPERTY(int projection READ projection WRITE setProjection)
Q_PROPERTY(qreal longitude READ centerLongitude WRITE setCenterLongitude)
Q_PROPERTY(qreal latitude READ centerLatitude WRITE setCenterLatitude)
Q_PROPERTY(bool showOverviewMap READ showOverviewMap WRITE setShowOverviewMap)
Q_PROPERTY(bool showScaleBar READ showScaleBar WRITE setShowScaleBar)
Q_PROPERTY(bool showCompass READ showCompass WRITE setShowCompass)
Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid)
Q_PROPERTY(bool showClouds READ showClouds WRITE setShowClouds)
Q_PROPERTY(bool showSunShading READ showSunShading WRITE setShowSunShading)
Q_PROPERTY(bool showCityLights READ showCityLights WRITE setShowCityLights)
Q_PROPERTY(bool isLockedToSubSolarPoint READ isLockedToSubSolarPoint WRITE setLockToSubSolarPoint)
Q_PROPERTY(bool isSubSolarPointIconVisible READ isSubSolarPointIconVisible WRITE setSubSolarPointIconVisible)
Q_PROPERTY(bool showAtmosphere READ showAtmosphere WRITE setShowAtmosphere)
Q_PROPERTY(bool showCrosshairs READ showCrosshairs WRITE setShowCrosshairs)
Q_PROPERTY(bool showPlaces READ showPlaces WRITE setShowPlaces)
Q_PROPERTY(bool showCities READ showCities WRITE setShowCities)
Q_PROPERTY(bool showTerrain READ showTerrain WRITE setShowTerrain)
Q_PROPERTY(bool showOtherPlaces READ showOtherPlaces WRITE setShowOtherPlaces)
Q_PROPERTY(bool showRelief READ showRelief WRITE setShowRelief)
Q_PROPERTY(bool showIceLayer READ showIceLayer WRITE setShowIceLayer)
Q_PROPERTY(bool showBorders READ showBorders WRITE setShowBorders)
Q_PROPERTY(bool showRivers READ showRivers WRITE setShowRivers)
Q_PROPERTY(bool showLakes READ showLakes WRITE setShowLakes)
Q_PROPERTY(ViewContext viewContext READ viewContext WRITE setViewContext NOTIFY viewContextChanged)
Q_PROPERTY( RenderStatus renderStatus READ renderStatus NOTIFY renderStatusChanged )
Q_PROPERTY(quint64 volatileTileCacheLimit READ volatileTileCacheLimit WRITE setVolatileTileCacheLimit)
public:
/**
* @brief Construct a new MarbleWidget.
* @param parent the parent widget
*
* This constructor should be used when you will only use one
* MarbleWidget. The widget will create its own MarbleModel when
* created.
*/
- explicit MarbleWidget( QWidget *parent = 0 );
+ explicit MarbleWidget( QWidget *parent = nullptr );
~MarbleWidget() override;
/// @name Access to helper objects
//@{
/**
* @brief Return the model that this view shows.
*/
MarbleModel *model();
const MarbleModel *model() const;
ViewportParams *viewport();
const ViewportParams *viewport() const;
MarbleWidgetPopupMenu *popupMenu();
/**
* Returns the current input handler
*/
MarbleWidgetInputHandler *inputHandler() const;
/**
* @brief Set the input handler
*/
void setInputHandler( MarbleWidgetInputHandler *handler );
/**
* @brief Returns a list of all RenderPlugins on the widget, this includes float items
* @return the list of RenderPlugins
*/
QList<RenderPlugin *> renderPlugins() const;
/**
* @brief Returns a list of all FloatItems on the widget
* @return the list of the floatItems
*/
QList<AbstractFloatItem *> floatItems() const;
/**
* @brief Returns the FloatItem with the given id
* @return The pointer to the requested floatItem,
*
* If no item is found the null pointer is returned.
*/
AbstractFloatItem * floatItem( const QString &nameId ) const;
/**
* Reads the plugin settings from the passed QSettings.
* You shouldn't use this in a KDE application as these use KConfig. Here you could
* use MarblePart which is handling this automatically.
* @param settings The QSettings object to be used.
*/
void readPluginSettings( QSettings& settings );
/**
* Writes the plugin settings in the passed QSettings.
* You shouldn't use this in a KDE application as these use KConfig. Here you could
* use MarblePart which is handling this automatically.
* @param settings The QSettings object to be used.
*/
void writePluginSettings( QSettings& settings ) const;
/**
* @brief Retrieve the view context (i.e. still or animated map)
*/
ViewContext viewContext() const;
/**
* @brief Get the GeoSceneDocument object of the current map theme
*/
GeoSceneDocument * mapTheme() const;
/**
* @brief Returns all widgets of dataPlugins on the position curpos
*/
QList<AbstractDataPluginItem *> whichItemAt( const QPoint& curpos ) const;
/**
* @brief Add a layer to be included in rendering.
*/
void addLayer( LayerInterface *layer );
/**
* @brief Remove a layer from being included in rendering.
*/
void removeLayer( LayerInterface *layer );
RoutingLayer* routingLayer();
PopupLayer* popupLayer();
/**
* @since 0.26.0
*/
const StyleBuilder* styleBuilder() const;
/**
* @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;
// int projection() const;
//@}
/// @name Visible map area
//@{
/**
* @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:
* mapThemeId = "earth/bluemarble/bluemarble.dgml"
*/
QString mapThemeId() const;
/**
* @brief Return the projected region which describes the (shape of the) projected surface.
*/
QRegion mapRegion() const;
/**
* @brief Return the radius of the globe in pixels.
*/
int radius() const;
/**
* @brief Return the current zoom amount.
*/
int zoom() const;
int tileZoomLevel() const;
/**
* @brief Return the current distance.
*/
qreal distance() const;
/**
* @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;
//@}
/// @name Position management
//@{
/**
* @brief Get the screen coordinates corresponding to geographical coordinates in the widget.
* @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 ) const;
/**
* @brief Get the earth coordinates corresponding to a pixel in the widget.
* @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 ) const;
/**
* @brief Return the longitude of the center point.
* @return The longitude of the center point in degree.
*/
qreal centerLongitude() const;
/**
* @brief Return the latitude of the center point.
* @return The latitude of the center point in degree.
*/
qreal centerLatitude() const;
qreal heading() const;
/**
* @brief Return how much the map will move if one of the move slots are called.
* @return The move step.
*/
qreal moveStep() const;
/**
* @brief Return the lookAt
*/
GeoDataLookAt lookAt() const;
/**
* @return The current point of focus, e.g. the point that is not moved
* when changing the zoom level. If not set, it defaults to the
* center point.
* @see centerLongitude centerLatitude setFocusPoint resetFocusPoint
*/
GeoDataCoordinates focusPoint() const;
/**
* @brief Change the point of focus, overridding any previously set focus point.
* @param focusPoint New focus point
* @see focusPoint resetFocusPoint
*/
void setFocusPoint( const GeoDataCoordinates &focusPoint );
/**
* @brief Invalidate any focus point set with @ref setFocusPoint.
* @see focusPoint setFocusPoint
*/
void resetFocusPoint();
/**
* @brief Return the globe radius (pixel) for the given distance (km)
*/
qreal radiusFromDistance( qreal distance ) const;
/**
* @brief Return the distance (km) at the given globe radius (pixel)
*/
qreal distanceFromRadius( qreal radius ) const;
/**
* Returns the zoom value (no unit) corresponding to the given camera distance (km)
*/
qreal zoomFromDistance( qreal distance ) const;
/**
* Returns the distance (km) corresponding to the given zoom value
*/
qreal distanceFromZoom( qreal zoom ) const;
//@}
/// @name Placemark management
//@{
QVector<const GeoDataFeature *> whichFeatureAt( const QPoint& ) const;
//@}
/// @name Float items and map appearance
//@{
/**
* @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 night shadow is visible.
* @return visibility of night shadow
*/
bool showSunShading() const;
/**
* @brief Return whether the city lights are shown instead of the night shadow.
* @return visibility of city lights
*/
bool showCityLights() const;
/**
* @brief Return whether the globe is locked to the sub solar point
* @return if globe is locked to sub solar point
*/
bool isLockedToSubSolarPoint() const;
/**
* @brief Return whether the sun icon is shown in the sub solar point.
* @return visibility of the sun icon in the sub solar point
*/
bool isSubSolarPointIconVisible() 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 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 the frame rate gets displayed.
* @return the frame rates visibility
*/
bool showFrameRate() const;
bool showBackground() const;
/**
* @brief Retrieve the map quality depending on the view context
*/
MapQuality mapQuality( ViewContext = Still ) const;
/**
* @brief Retrieve whether travels to a point should get animated
*/
bool animationsEnabled() const;
AngleUnit defaultAngleUnit() const;
void setDefaultAngleUnit( AngleUnit angleUnit );
QFont defaultFont() const;
void setDefaultFont( const QFont& font );
//@}
/// @name Tile management
//@{
/**
* @brief Returns the limit in kilobytes of the volatile (in RAM) tile cache.
* @return the limit of volatile tile cache
*/
quint64 volatileTileCacheLimit() const;
//@}
/// @name Miscellaneous
//@{
/**
* @brief Return a QPixmap with the current contents of the widget.
*/
QPixmap mapScreenShot();
//@}
/// @todo Enable this instead of the zoomView slot below for proper deprecation warnings
/// around Marble 1.8
// @deprecated Please use setZoom
//MARBLE_DEPRECATED( void zoomView( int zoom, FlyToMode mode = Instant ) );
/**
* Summarized render status of the current map view
* @see renderState
*/
RenderStatus renderStatus() const;
/**
* Detailed render status of the current map view
*/
RenderState renderState() const;
/**
* Toggle whether regions are highlighted when user selects them
*/
void setHighlightEnabled( bool enabled );
public Q_SLOTS:
/// @name Position management slots
//@{
/**
* @brief Set the radius of the globe in pixels.
* @param radius The new globe radius value in pixels.
*/
void setRadius( int radius );
/**
* @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 setZoom( int zoom, FlyToMode mode = Instant );
/**
* @deprecated To be removed soon. Please use setZoom instead. Same parameters.
*/
void zoomView( int zoom, FlyToMode mode = Instant );
/**
* @brief Zoom the view by a certain step
* @param zoomStep the difference between the old zoom and the new
*/
void zoomViewBy( int zoomStep, FlyToMode mode = Instant );
/**
* @brief Zoom in by the amount zoomStep.
*/
void zoomIn( FlyToMode mode = Automatic );
/**
* @brief Zoom out by the amount zoomStep.
*/
void zoomOut( FlyToMode mode = Automatic );
/**
* @brief Set the distance of the observer to the globe in km.
* @param distance The new distance in km.
*/
void setDistance( qreal distance );
/**
* @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, FlyToMode mode = Instant );
/**
* @brief Center the view on a geographical point
* @param lat an angle in degrees parallel to the latitude lines
* +90(N) - -90(S)
* @param lon an angle in degrees parallel to the longitude lines
* +180(W) - -180(E)
*/
void centerOn( const qreal lon, const qreal lat, bool animated = false );
/**
* @brief Center the view on a point
* This method centers the Marble map on the point described by the latitude
* and longitude in the GeoDataCoordinate parameter @c point. It also zooms
* the map to be at the elevation described by the altitude. If this is
* not the desired functionality or you do not have an accurate altitude
* then use @see centerOn(qreal, qreal, bool)
* @param point the point in 3 dimensions above the globe to move the view
* to. It will always be looking vertically down.
*/
void centerOn( const GeoDataCoordinates &point, bool animated = false );
/**
* @brief Center the view on a bounding box so that it completely fills the viewport
* This method not only centers on the center of the GeoDataLatLon box but it also
* adjusts the zoom of the marble widget so that the LatLon box provided fills
* the viewport.
* @param box The GeoDataLatLonBox to zoom and move the MarbleWidget to.
*/
void centerOn( const GeoDataLatLonBox& box, bool animated = false );
/**
* @brief Center the view on a placemark according to the following logic:
* - if the placemark has a lookAt, zoom and center on that lookAt
* - otherwise use the placemark geometry's latLonAltBox
* @param box The GeoDataPlacemark to zoom and move the MarbleWidget to.
*/
void centerOn( const GeoDataPlacemark& placemark, bool animated = false );
/**
* @brief Set the latitude for the center point
* @param lat the new value for the latitude in degree.
* @param mode the FlyToMode that will be used.
*/
void setCenterLatitude( qreal lat, FlyToMode mode = Instant );
/**
* @brief Set the longitude for the center point
* @param lon the new value for the longitude in degree.
* @param mode the FlyToMode that will be used.
*/
void setCenterLongitude( qreal lon, FlyToMode mode = Instant );
void setHeading( qreal heading );
/**
* @brief Move left by the moveStep.
*/
void moveLeft( FlyToMode mode = Automatic );
/**
* @brief Move right by the moveStep.
*/
void moveRight( FlyToMode mode = Automatic );
/**
* @brief Move up by the moveStep.
*/
void moveUp( FlyToMode mode = Automatic );
/**
* @brief Move down by the moveStep.
*/
void moveDown( FlyToMode mode = Automatic );
/**
* @brief Center the view on the default start point with the default zoom.
*/
void goHome( FlyToMode mode = Automatic );
/**
* @brief Change the camera position to the given position.
* @param lookAt New camera position. Changing the camera position means
* that both the current center position as well as the zoom value may change
* @param mode Interpolation type for intermediate camera positions. Automatic
* (default) chooses a suitable interpolation among Instant, Lenar and Jump.
* Instant will directly set the new zoom and position values, while
* Linear results in a linear interpolation of intermediate center coordinates
* along the sphere and a linear interpolation of changes in the camera distance
* to the ground. Finally, Jump will behave the same as Linear with regard to
* the center position interpolation, but use a parabolic height increase
* towards the middle point of the intermediate positions. This appears
* like a jump of the camera.
*/
void flyTo( const GeoDataLookAt &lookAt, FlyToMode mode = Automatic );
//@}
/// @name Float items and map appearance slots
//@{
/**
* @brief Set the Projection used for the map
* @param projection projection type (e.g. Spherical, Equirectangular, Mercator)
*/
void setProjection( int projection );
void setProjection( Projection projection );
/**
* @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 night shadow is visible.
* @param visibile visibility of shadow
*/
void setShowSunShading( bool visible );
/**
* @brief Set whether city lights instead of night shadow are visible.
* @param visible visibility of city lights
*/
void setShowCityLights( bool visible );
/**
* @brief Set the globe locked to the sub solar point
* @param vsible if globe is locked to the sub solar point
*/
void setLockToSubSolarPoint( bool visible );
/**
* @brief Set whether the sun icon is shown in the sub solar point
* @param visible if the sun icon is shown in the sub solar point
*/
void setSubSolarPointIconVisible( 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 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 the frame rate gets shown
* @param visible visibility of the frame rate
*/
void setShowFrameRate( bool visible );
void setShowBackground( 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 runtime tracing for layers gets shown
* @param visible visibility of the runtime tracing
*/
void setShowRuntimeTrace( bool visible );
bool showRuntimeTrace() const;
/**
* @brief Set whether to enter the debug mode for
* polygon node drawing
* @param visible visibility of the node debug mode
*/
void setShowDebugPolygons( bool visible);
bool showDebugPolygons() const;
/**
* @brief Set whether to enter the debug mode for
* batch rendering
* @param visible visibility of the batch rendering
*/
void setShowDebugBatchRender( bool visible);
bool showDebugBatchRender() const;
/**
* @brief Set whether to enter the debug mode for
* placemark drawing
* @param visible visibility of the node debug mode
*/
void setShowDebugPlacemarks(bool visible);
bool showDebugPlacemarks() const;
/**
* @brief Set whether to render according to OSM indoor level tags
* @param visible visibility of entities (placemarks, buildings etc.) level-wise
*/
void setDebugLevelTags(bool visible);
bool debugLevelTags() const;
/**
* @brief Set the level to debug
* @param level the level to debug
*/
void setLevelToDebug(int level);
int levelToDebug() const;
/**
* @brief Set the map quality for the specified view context.
*
* @param quality map quality for the specified view context
* @param viewContext view context whose map quality should be set
*/
void setMapQualityForViewContext( MapQuality quality, ViewContext viewContext );
/**
* @brief Set the view context (i.e. still or animated map)
*/
void setViewContext( ViewContext viewContext );
/**
* @brief Set whether travels to a point should get animated
*/
void setAnimationsEnabled( bool enabled );
//@}
/// @name Tile management slots
//@{
void clearVolatileTileCache();
/**
* @brief Set the limit of the volatile (in RAM) tile cache.
* @param kilobytes The limit in kilobytes.
*/
void setVolatileTileCacheLimit( quint64 kiloBytes );
/**
* @brief A slot that is called when the model starts to create new tiles.
* @param creator the tile creator object.
* @param name the name of the created theme.
* @param description a descriptive text that can be shown in a dialog.
* @see creatingTilesProgress
*
* This function is connected to the models signal with the same
* name. When the model needs to create a cache of tiles in
* several different resolutions, it will emit creatingTilesStart
* once with a name of the theme and a descriptive text. The
* widget can then pop up a dialog to explain why there is a
* delay. The model will then call creatingTilesProgress several
* times until the parameter reaches 100 (100%), after which the
* creation process is finished. After this there will be no more
* calls to creatingTilesProgress, and the poup dialog can then be
* closed.
*/
void creatingTilesStart( TileCreator *creator, const QString& name, const QString& description );
/**
* @brief Re-download all visible tiles.
*/
void reloadMap();
void downloadRegion( QVector<TileCoordsPyramid> const & );
//@}
/// @name Miscellaneous slots
//@{
/**
* @brief Used to notify about the position of the mouse click
*/
void notifyMouseClick( int x, int y );
void setSelection( const QRect& region );
void setInputEnabled( bool );
TextureLayer *textureLayer() const;
//@}
Q_SIGNALS:
/**
* @brief Signal that the zoom has changed, and to what.
* @param zoom The new zoom value.
* @see setZoom()
*/
void zoomChanged( int zoom );
void distanceChanged( const QString& distanceString );
void tileLevelChanged( int level );
void viewContextChanged(ViewContext newViewContext);
/**
* @brief Signal that the theme has changed
* @param theme Name of the new theme.
*/
void themeChanged( const QString& theme );
void projectionChanged( Projection );
void mouseMoveGeoPosition( const QString& );
void mouseClickGeoPosition( qreal lon, qreal lat, GeoDataCoordinates::Unit );
void framesPerSecond( qreal fps );
/**
* This signal is emit when a new rectangle region is selected over the map.
*
* @param boundingBox The geographical coordinates of the selected region
*/
void regionSelected(const GeoDataLatLonBox &boundingBox);
/**
* This signal is emit when the settings of a plugin changed.
*/
void pluginSettingsChanged();
/**
* @brief Signal that a render item has been initialized
*/
void renderPluginInitialized( RenderPlugin *renderPlugin );
/**
* This signal is emitted when the visible region of the map changes. This typically happens
* when the user moves the map around or zooms.
*/
void visibleLatLonAltBoxChanged( const GeoDataLatLonAltBox& visibleLatLonAltBox );
/**
* @brief Emitted when the layer rendering status has changed
* @param status New render status
*/
void renderStatusChanged( RenderStatus status );
void renderStateChanged( const RenderState &state );
void highlightedPlacemarksChanged( qreal lon, qreal lat, GeoDataCoordinates::Unit unit );
protected:
/**
* @brief Reimplementation of the leaveEvent() function in QWidget.
*/
void leaveEvent( QEvent *event ) override;
/**
* @brief Reimplementation of the paintEvent() function in QWidget.
*/
void paintEvent( QPaintEvent *event ) override;
/**
* @brief Reimplementation of the resizeEvent() function in QWidget.
*/
void resizeEvent( QResizeEvent *event ) override;
void connectNotify(const QMetaMethod &signal) override;
void disconnectNotify(const QMetaMethod &signal) override;
/**
* @brief Reimplementation of the changeEvent() function in QWidget to
* react to changes of the enabled state
*/
void changeEvent( QEvent * event ) override;
/**
* @brief Enables custom drawing onto the MarbleWidget straight after
* @brief the globe and before all other layers has been rendered.
* @param painter
*
* @deprecated implement LayerInterface and add it using @p addLayer()
*/
virtual void customPaint( GeoPainter *painter );
private:
Q_PRIVATE_SLOT( d, void updateMapTheme() )
Q_PRIVATE_SLOT( d, void updateSystemBackgroundAttribute() )
private:
Q_DISABLE_COPY( MarbleWidget )
MarbleWidgetPrivate * const d;
friend class MarbleWidgetPrivate;
class CustomPaintLayer;
friend class CustomPaintLayer;
friend class MarbleWidgetDefaultInputHandler;
};
}
#endif
diff --git a/src/lib/marble/MarbleWidgetPopupMenu.cpp b/src/lib/marble/MarbleWidgetPopupMenu.cpp
index b99a46100..75824b4c5 100644
--- a/src/lib/marble/MarbleWidgetPopupMenu.cpp
+++ b/src/lib/marble/MarbleWidgetPopupMenu.cpp
@@ -1,919 +1,919 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
// Copyright 2014 Gábor Péterffy <peterffy95@gmail.com>
//
// Self
#include "MarbleWidgetPopupMenu.h"
// Marble
#include "AbstractDataPluginItem.h"
#include "AbstractFloatItem.h"
#include "MarbleAboutDialog.h"
#include "MarbleDirs.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "GeoDataExtendedData.h"
#include "GeoDataFolder.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLookAt.h"
#include "GeoDataData.h"
#include "GeoDataSnippet.h"
#include "GeoDataStyle.h"
#include "GeoDataBalloonStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataPoint.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "MarbleClock.h"
#include "MarbleDebug.h"
#include "PopupLayer.h"
#include "Planet.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingLayer.h"
#include "routing/RouteRequest.h"
#include "EditBookmarkDialog.h"
#include "BookmarkManager.h"
#include "ReverseGeocodingRunnerManager.h"
#include "TemplateDocument.h"
#include "OsmPlacemarkData.h"
#include "StyleBuilder.h"
// Qt
#include <QApplication>
#include <QFile>
#include <QMimeData>
#include <QPointer>
#include <QAction>
#include <QClipboard>
#include <QMenu>
#include <QMessageBox>
namespace Marble {
/* TRANSLATOR Marble::MarbleWidgetPopupMenu */
class Q_DECL_HIDDEN MarbleWidgetPopupMenu::Private {
public:
const MarbleModel *const m_model;
MarbleWidget *const m_widget;
QVector<const GeoDataFeature*> m_featurelist;
QList<AbstractDataPluginItem *> m_itemList;
QMenu m_lmbMenu;
QMenu m_rmbMenu;
QAction *m_infoDialogAction;
QAction *m_directionsFromHereAction;
QAction *m_directionsToHereAction;
QAction *const m_copyCoordinateAction;
QAction *m_rmbExtensionPoint;
ReverseGeocodingRunnerManager m_runnerManager;
QPoint m_mousePosition;
public:
Private( MarbleWidget *widget, const MarbleModel *model, MarbleWidgetPopupMenu* parent );
QMenu* createInfoBoxMenu(QWidget *parent);
/**
* Returns the geo coordinates of the mouse pointer at the last right button menu.
* You must not pass 0 as coordinates parameter. The result indicates whether the
* coordinates are valid, which will be true if the right button menu was opened at least once.
*/
GeoDataCoordinates mouseCoordinates( QAction* dataContainer ) const;
static QString filterEmptyShortDescription( const QString &description );
void setupDialogOsm( PopupLayer *popup, const GeoDataPlacemark* placemark );
void setupDialogSatellite( const GeoDataPlacemark *placemark );
static void setupDialogCity( PopupLayer *popup, const GeoDataPlacemark *placemark );
static void setupDialogNation( PopupLayer *popup, const GeoDataPlacemark *placemark );
static void setupDialogGeoPlaces( PopupLayer *popup, const GeoDataPlacemark *placemark );
static void setupDialogSkyPlaces( PopupLayer *popup, const GeoDataPlacemark *placemark );
static void setupDialogPhotoOverlay( PopupLayer *popup, const GeoDataPhotoOverlay *overlay);
};
MarbleWidgetPopupMenu::Private::Private( MarbleWidget *widget, const MarbleModel *model, MarbleWidgetPopupMenu* parent ) :
m_model(model),
m_widget(widget),
m_lmbMenu( m_widget ),
m_rmbMenu( m_widget ),
- m_directionsFromHereAction( 0 ),
- m_directionsToHereAction( 0 ),
+ m_directionsFromHereAction( nullptr ),
+ m_directionsToHereAction( nullptr ),
m_copyCoordinateAction(new QAction(QIcon(QStringLiteral(":/icons/copy-coordinates.png")), tr("Copy Coordinates"), parent)),
- m_rmbExtensionPoint( 0 ),
+ m_rmbExtensionPoint( nullptr ),
m_runnerManager( model )
{
// Property actions (Left mouse button)
m_infoDialogAction = new QAction( parent );
m_infoDialogAction->setData( 0 );
// Tool actions (Right mouse button)
m_directionsFromHereAction = new QAction( tr( "Directions &from here" ), parent );
m_directionsToHereAction = new QAction( tr( "Directions &to here" ), parent );
RouteRequest* request = m_widget->model()->routingManager()->routeRequest();
if ( request ) {
m_directionsFromHereAction->setIcon( QIcon( request->pixmap( 0, 16 ) ) );
int const lastIndex = qMax( 1, request->size()-1 );
m_directionsToHereAction->setIcon( QIcon( request->pixmap( lastIndex, 16 ) ) );
}
QAction* addBookmark = new QAction( QIcon(QStringLiteral(":/icons/bookmark-new.png")),
tr( "Add &Bookmark" ), parent );
QAction* fullscreenAction = new QAction( tr( "&Full Screen Mode" ), parent );
fullscreenAction->setCheckable( true );
QAction* aboutDialogAction = new QAction(QIcon(QStringLiteral(":/icons/marble.png")), tr("&About"), parent);
QMenu* infoBoxMenu = createInfoBoxMenu(m_widget);
const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( !smallScreen ) {
m_rmbExtensionPoint = m_rmbMenu.addSeparator();
}
m_rmbMenu.addAction( m_directionsFromHereAction );
m_rmbMenu.addAction( m_directionsToHereAction );
m_rmbMenu.addSeparator();
m_rmbMenu.addAction( addBookmark );
if ( !smallScreen ) {
m_rmbMenu.addAction( m_copyCoordinateAction );
}
m_rmbMenu.addAction(QIcon(QStringLiteral(":/icons/addressbook-details.png")), tr("&Address Details"), parent, SLOT(startReverseGeocoding()));
m_rmbMenu.addSeparator();
m_rmbMenu.addMenu( infoBoxMenu );
if ( !smallScreen ) {
m_rmbMenu.addAction( aboutDialogAction );
} else {
m_rmbMenu.addAction( fullscreenAction );
}
parent->connect( &m_lmbMenu, SIGNAL(aboutToHide()), SLOT(resetMenu()) );
parent->connect( m_directionsFromHereAction, SIGNAL(triggered()), SLOT(directionsFromHere()) );
parent->connect( m_directionsToHereAction, SIGNAL(triggered()), SLOT(directionsToHere()) );
parent->connect( addBookmark, SIGNAL(triggered()), SLOT(addBookmark()) );
parent->connect( aboutDialogAction, SIGNAL(triggered()), SLOT(slotAboutDialog()) );
parent->connect( m_copyCoordinateAction, SIGNAL(triggered()), SLOT(slotCopyCoordinates()) );
parent->connect( m_infoDialogAction, SIGNAL(triggered()), SLOT(slotInfoDialog()) );
parent->connect( fullscreenAction, SIGNAL(triggered(bool)), parent, SLOT(toggleFullscreen(bool)) );
parent->connect( &m_runnerManager, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)),
parent, SLOT(showAddressInformation(GeoDataCoordinates,GeoDataPlacemark)) );
}
QString MarbleWidgetPopupMenu::Private::filterEmptyShortDescription(const QString &description)
{
if(description.isEmpty())
return tr("No description available.");
return description;
}
void MarbleWidgetPopupMenu::Private::setupDialogOsm( PopupLayer *popup, const GeoDataPlacemark *placemark )
{
const GeoDataCoordinates location = placemark->coordinate();
popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter);
QFile descriptionFile(QStringLiteral(":/marble/webpopup/osm.html"));
if (!descriptionFile.open(QIODevice::ReadOnly)) {
return;
}
const QString none = QStringLiteral("none");
QString description = descriptionFile.readAll();
const OsmPlacemarkData& data = placemark->osmData();
if (!data.containsTagKey("addr:street") && !data.containsTagKey("addr:housenumber")){
description.replace(QStringLiteral("<br> %postcode%"), QStringLiteral("%postcode%"));
}
TemplateDocument doc(description);
doc[QStringLiteral("name")] = data.tagValue(QStringLiteral("name"));
QString natural = data.tagValue(QStringLiteral("natural"));
if (!natural.isEmpty()) {
natural[0] = natural[0].toUpper();
if (natural == QLatin1String("Peak")) {
QString elevation = data.tagValue(QStringLiteral("ele"));
if (!elevation.isEmpty()) {
natural = natural + QLatin1String(" - ") + elevation + QLatin1String(" m");
}
}
doc[QStringLiteral("details")] = natural;
} else {
doc[QStringLiteral("detailsVisibility")] = none;
}
QString amenity;
QString shop = data.tagValue(QStringLiteral("shop"));
if (!shop.isEmpty()) {
shop[0] = shop[0].toUpper();
if (shop == QLatin1String("Clothes")) {
QString type = data.tagValue(QStringLiteral("clothes"));
if (type.isEmpty()) {
type = data.tagValue(QStringLiteral("designation"));
}
if (!type.isEmpty()) {
type[0] = type[0].toUpper();
amenity = QLatin1String("Shop - ") + shop + QLatin1String(" (") + type + QLatin1Char(')');
}
}
if (amenity.isEmpty()) {
amenity = QLatin1String("Shop - ") + shop;
}
} else {
amenity = data.tagValue(QStringLiteral("amenity"));
if (!amenity.isEmpty()) {
amenity[0] = amenity[0].toUpper();
}
}
if (!amenity.isEmpty()) {
doc[QStringLiteral("amenity")] = amenity;
} else {
doc[QStringLiteral("amenityVisibility")] = none;
}
QString cuisine = data.tagValue(QStringLiteral("cuisine"));
if (!cuisine.isEmpty()) {
cuisine[0] = cuisine[0].toUpper();
doc[QStringLiteral("cuisine")] = cuisine;
} else {
doc[QStringLiteral("cuisineVisibility")] = none;
}
QString openingHours = data.tagValue(QStringLiteral("opening_hours"));
if (!openingHours.isEmpty()) {
doc[QStringLiteral("openinghours")] = openingHours;
} else {
doc[QStringLiteral("openinghoursVisibility")] = none;
}
bool hasContactsData = false;
const QStringList addressItemKeys = QStringList()
<< QStringLiteral("street")
<< QStringLiteral("housenumber")
<< QStringLiteral("postcode")
<< QStringLiteral("city");
bool hasAddressItem = false;
QStringList addressItems;
for (const QString& key: addressItemKeys) {
const QString item = data.tagValue(QLatin1String("addr:") + key);
if (!item.isEmpty()) {
hasAddressItem = true;
}
addressItems << item;
}
if (hasAddressItem) {
hasContactsData = true;
for(int i = 0; i < addressItemKeys.size(); ++i) {
doc[addressItemKeys[i]] = addressItems[i];
}
} else {
doc[QStringLiteral("addressVisibility")] = none;
}
QString phoneData = data.tagValue(QStringLiteral("phone"));
if (!phoneData.isEmpty()) {
hasContactsData = true;
doc[QStringLiteral("phone")] = phoneData;
} else {
doc[QStringLiteral("phoneVisibility")] = none;
}
QString websiteData;
auto const tags = QStringList() << "website" << "contact:website" << "facebook" << "contact:facebook" << "url";
for(const QString &tag: tags) {
websiteData = data.tagValue(tag);
if (!websiteData.isEmpty()) {
break;
}
}
if (!websiteData.isEmpty()) {
hasContactsData = true;
doc[QStringLiteral("website")] = websiteData;
} else {
doc[QStringLiteral("websiteVisibility")] = none;
}
if (!hasContactsData) {
doc[QStringLiteral("contactVisibility")] = none;
}
bool hasFacilitiesData = false;
const QString wheelchair = data.tagValue(QStringLiteral("wheelchair"));
if (!wheelchair.isEmpty()) {
hasFacilitiesData = true;
doc[QStringLiteral("wheelchair")] = wheelchair;
} else {
doc[QStringLiteral("wheelchairVisibility")] = none;
}
const QString internetAccess = data.tagValue(QStringLiteral("internet_access"));
if (!internetAccess.isEmpty()) {
hasFacilitiesData = true;
doc[QStringLiteral("internetaccess")] = internetAccess;
} else {
doc[QStringLiteral("internetVisibility")] = none;
}
const QString smoking = data.tagValue(QStringLiteral("smoking"));
if (!smoking.isEmpty()) {
hasFacilitiesData = true;
doc[QStringLiteral("smoking")] = smoking;
} else {
doc[QStringLiteral("smokingVisibility")] = none;
}
if (!hasFacilitiesData) {
doc[QStringLiteral("facilitiesVisibility")] = none;
}
const QString flagPath = m_widget->styleBuilder()->createStyle(StyleParameters(placemark))->iconStyle().iconPath();
doc["flag"] = flagPath;
popup->setContent(doc.finalText());
}
void MarbleWidgetPopupMenu::Private::setupDialogSatellite( const GeoDataPlacemark *placemark )
{
PopupLayer *const popup = m_widget->popupLayer();
const GeoDataCoordinates location = placemark->coordinate(m_widget->model()->clockDateTime());
popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter);
const QString description = placemark->description();
TemplateDocument doc(description);
doc["altitude"] = QString::number(location.altitude(), 'f', 2);
doc["latitude"] = location.latToString();
doc["longitude"] = location.lonToString();
popup->setContent(doc.finalText());
}
void MarbleWidgetPopupMenu::Private::setupDialogCity( PopupLayer *popup, const GeoDataPlacemark *placemark )
{
const GeoDataCoordinates location = placemark->coordinate();
popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter);
QFile descriptionFile(QStringLiteral(":/marble/webpopup/city.html"));
if (!descriptionFile.open(QIODevice::ReadOnly)) {
return;
}
const QString description = descriptionFile.readAll();
TemplateDocument doc(description);
doc["name"] = placemark->name();
QString roleString;
const QString role = placemark->role();
if (role == QLatin1String("PPLC")) {
roleString = tr("National Capital");
} else if (role == QLatin1String("PPL")) {
roleString = tr("City");
} else if (role == QLatin1String("PPLA")) {
roleString = tr("State Capital");
} else if (role == QLatin1String("PPLA2")) {
roleString = tr("County Capital");
} else if (role == QLatin1String("PPLA3") ||
role == QLatin1String("PPLA4")) {
roleString = tr("Capital");
} else if (role == QLatin1String("PPLF") ||
role == QLatin1String("PPLG") ||
role == QLatin1String("PPLL") ||
role == QLatin1String("PPLQ") ||
role == QLatin1String("PPLR") ||
role == QLatin1String("PPLS") ||
role == QLatin1String("PPLW")) {
roleString = tr("Village");
}
doc["category"] = roleString;
doc["shortDescription"] = filterEmptyShortDescription(placemark->description());
doc["latitude"] = location.latToString();
doc["longitude"] = location.lonToString();
doc["elevation"] = QString::number(location.altitude(), 'f', 2);
doc["population"] = QString::number(placemark->population());
doc["country"] = placemark->countryCode();
doc["state"] = placemark->state();
QString dst = QStringLiteral("%1").arg((placemark->extendedData().value(QStringLiteral("gmt")).value().toInt() +
placemark->extendedData().value(QStringLiteral("dst")).value().toInt()) /
( double ) 100, 0, 'f', 1 );
// There is an issue about UTC.
// It's possible to variants (e.g.):
// +1.0 and -1.0, but dst does not have + an the start
if (dst.startsWith(QLatin1Char('-'))) {
doc["timezone"] = dst;
} else {
doc["timezone"] = QLatin1Char('+') + dst;
}
const QString flagPath = MarbleDirs::path(
QLatin1String("flags/flag_") + placemark->countryCode().toLower() + QLatin1String(".svg"));
doc["flag"] = flagPath;
popup->setContent(doc.finalText());
}
void MarbleWidgetPopupMenu::Private::setupDialogNation( PopupLayer *popup, const GeoDataPlacemark *index)
{
const GeoDataCoordinates location = index->coordinate();
popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter);
QFile descriptionFile(QStringLiteral(":/marble/webpopup/nation.html"));
if (!descriptionFile.open(QIODevice::ReadOnly)) {
return;
}
const QString description = descriptionFile.readAll();
TemplateDocument doc(description);
doc["name"] = index->name();
doc["shortDescription"] = filterEmptyShortDescription(index->description());
doc["latitude"] = location.latToString();
doc["longitude"] = location.lonToString();
doc["elevation"] = QString::number(location.altitude(), 'f', 2);
doc["population"] = QString::number(index->population());
doc["area"] = QString::number(index->area(), 'f', 2);
const QString flagPath = MarbleDirs::path(QString("flags/flag_%1.svg").arg(index->countryCode().toLower()) );
doc["flag"] = flagPath;
popup->setContent(doc.finalText());
}
void MarbleWidgetPopupMenu::Private::setupDialogGeoPlaces( PopupLayer *popup, const GeoDataPlacemark *index)
{
const GeoDataCoordinates location = index->coordinate();
popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter);
QFile descriptionFile(QStringLiteral(":/marble/webpopup/geoplace.html"));
if (!descriptionFile.open(QIODevice::ReadOnly)) {
return;
}
const QString description = descriptionFile.readAll();
TemplateDocument doc(description);
doc["name"] = index->name();
doc["latitude"] = location.latToString();
doc["longitude"] = location.lonToString();
doc["elevation"] = QString::number(location.altitude(), 'f', 2);
doc["shortDescription"] = filterEmptyShortDescription(index->description());
popup->setContent(doc.finalText());
}
void MarbleWidgetPopupMenu::Private::setupDialogSkyPlaces( PopupLayer *popup, const GeoDataPlacemark *index)
{
const GeoDataCoordinates location = index->coordinate();
popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter);
QFile descriptionFile(QStringLiteral(":/marble/webpopup/skyplace.html"));
if (!descriptionFile.open(QIODevice::ReadOnly)) {
return;
}
const QString description = descriptionFile.readAll();
TemplateDocument doc(description);
doc["name"] = index->name();
doc["latitude"] = GeoDataCoordinates::latToString(
location.latitude(), GeoDataCoordinates::Astro, GeoDataCoordinates::Radian, -1, 'f');
doc["longitude"] = GeoDataCoordinates::lonToString(
location.longitude(), GeoDataCoordinates::Astro, GeoDataCoordinates::Radian, -1, 'f');
doc["shortDescription"] = filterEmptyShortDescription(index->description());
popup->setContent(doc.finalText());
}
void MarbleWidgetPopupMenu::Private::setupDialogPhotoOverlay( PopupLayer *popup, const GeoDataPhotoOverlay *index )
{
const GeoDataCoordinates location = index->point().coordinates();
popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter);
QFile descriptionFile(QStringLiteral(":/marble/webpopup/photooverlay.html"));
if ( !descriptionFile.open(QIODevice::ReadOnly) ) {
return;
}
const QString description = descriptionFile.readAll();
TemplateDocument doc(description);
doc["name"] = index->name();
doc["latitude"] = location.latToString();
doc["longitude"] = location.lonToString();
doc["elevation"] = QString::number(location.altitude(), 'f', 2);
doc["shortDescription"] = filterEmptyShortDescription(index->description());
doc["source"] = index->absoluteIconFile();
doc["width"] = QString::number(200);
doc["height"] = QString::number(100);
QString const basePath = index->resolvePath(".");
QUrl const baseUrl = (basePath != QLatin1String(".")) ? QUrl::fromLocalFile(basePath + QLatin1Char('/')) : QUrl();
popup->setContent(doc.finalText(), baseUrl );
}
MarbleWidgetPopupMenu::MarbleWidgetPopupMenu(MarbleWidget *widget,
const MarbleModel *model)
: QObject(widget),
d( new Private( widget, model, this ) )
{
// nothing to do
}
MarbleWidgetPopupMenu::~MarbleWidgetPopupMenu()
{
delete d;
}
QMenu* MarbleWidgetPopupMenu::Private::createInfoBoxMenu(QWidget* parent)
{
QMenu* menu = new QMenu(tr("&Info Boxes"), parent);
QList<AbstractFloatItem *> floatItemList = m_widget->floatItems();
QList<AbstractFloatItem *>::const_iterator iter = floatItemList.constBegin();
QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd();
for (; iter != end; ++iter )
{
menu->addAction( (*iter)->action() );
}
return menu;
}
void MarbleWidgetPopupMenu::showLmbMenu( int xpos, int ypos )
{
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( smallScreen ) {
showRmbMenu( xpos, ypos );
return;
}
d->m_mousePosition.setX(xpos);
d->m_mousePosition.setY(ypos);
const QPoint curpos = QPoint( xpos, ypos );
d->m_featurelist = d->m_widget->whichFeatureAt( curpos );
int actionidx = 1;
QVector<const GeoDataFeature*>::const_iterator it = d->m_featurelist.constBegin();
QVector<const GeoDataFeature*>::const_iterator const itEnd = d->m_featurelist.constEnd();
for (; it != itEnd; ++it )
{
QString name = (*it)->name();
QPixmap icon = QPixmap::fromImage( ( *it)->style()->iconStyle().icon() );
d->m_infoDialogAction->setData( actionidx );
d->m_infoDialogAction->setText( name );
d->m_infoDialogAction->setIcon( icon );
// Insert as first action in the menu
- QAction *firstAction = 0;
+ QAction *firstAction = nullptr;
if( !d->m_lmbMenu.actions().isEmpty() ) {
firstAction = d->m_lmbMenu.actions().first();
}
d->m_lmbMenu.insertAction( firstAction, d->m_infoDialogAction );
actionidx++;
}
d->m_itemList = d->m_widget->whichItemAt( curpos );
QList<AbstractDataPluginItem *>::const_iterator itW = d->m_itemList.constBegin();
QList<AbstractDataPluginItem *>::const_iterator const itWEnd = d->m_itemList.constEnd();
for (; itW != itWEnd; ++itW )
{
for ( QAction* action: (*itW)->actions() ) {
d->m_lmbMenu.addAction( action );
}
}
switch ( d->m_lmbMenu.actions().size() ) {
case 0: // nothing to do, ignore
break;
case 1: // one action? perform immediately
d->m_lmbMenu.actions().first()->activate( QAction::Trigger );
d->m_lmbMenu.clear();
break;
default:
d->m_lmbMenu.popup( d->m_widget->mapToGlobal( curpos ) );
}
}
void MarbleWidgetPopupMenu::showRmbMenu( int xpos, int ypos )
{
qreal lon, lat;
const bool visible = d->m_widget->geoCoordinates( xpos, ypos, lon, lat, GeoDataCoordinates::Radian );
if ( !visible )
return;
d->m_mousePosition.setX(xpos);
d->m_mousePosition.setY(ypos);
QPoint curpos = QPoint( xpos, ypos );
d->m_copyCoordinateAction->setData( curpos );
bool const showDirectionButtons = d->m_widget->routingLayer() && d->m_widget->routingLayer()->isInteractive();
d->m_directionsFromHereAction->setVisible( showDirectionButtons );
d->m_directionsToHereAction->setVisible( showDirectionButtons );
RouteRequest* request = d->m_widget->model()->routingManager()->routeRequest();
if ( request ) {
int const lastIndex = qMax( 1, request->size()-1 );
d->m_directionsToHereAction->setIcon( QIcon( request->pixmap( lastIndex, 16 ) ) );
}
d->m_rmbMenu.popup( d->m_widget->mapToGlobal( curpos ) );
}
void MarbleWidgetPopupMenu::resetMenu()
{
d->m_lmbMenu.clear();
}
void MarbleWidgetPopupMenu::slotInfoDialog()
{
QAction *action = qobject_cast<QAction *>( sender() );
- if ( action == 0 ) {
+ if ( action == nullptr ) {
mDebug() << "Warning: slotInfoDialog should be called by a QAction signal";
return;
}
int actionidx = action->data().toInt();
if ( actionidx > 0 ) {
const GeoDataPlacemark *placemark = dynamic_cast<const GeoDataPlacemark*>(d->m_featurelist.at( actionidx -1 ));
const GeoDataPhotoOverlay *overlay = dynamic_cast<const GeoDataPhotoOverlay*>(d->m_featurelist.at( actionidx - 1 ));
PopupLayer* popup = d->m_widget->popupLayer();
bool isSatellite = false;
bool isCity = false;
bool isNation = false;
const OsmPlacemarkData& data = placemark->osmData();
bool hasOsmData = false;
QStringList recognizedTags;
recognizedTags << "name" << "amenity" << "cuisine" << "opening_hours";
recognizedTags << "addr:street" << "addr:housenumber" << "addr:postcode";
recognizedTags << "addr:city" << "phone" << "wheelchair" << "internet_access";
recognizedTags << "smoking" << "website" << "contact:website" << "facebook";
recognizedTags << "contact:facebook" << "url";
for(const QString &tag: recognizedTags) {
if (data.containsTagKey(tag)) {
hasOsmData = true;
break;
}
}
if ( placemark ) {
isSatellite = (placemark->visualCategory() == GeoDataPlacemark::Satellite);
isCity = (placemark->visualCategory() >= GeoDataPlacemark::SmallCity &&
placemark->visualCategory() <= GeoDataPlacemark::LargeNationCapital);
isNation = (placemark->visualCategory() == GeoDataPlacemark::Nation);
}
bool isSky = false;
if ( d->m_widget->model()->mapTheme() ) {
isSky = d->m_widget->model()->mapTheme()->head()->target() == QLatin1String("sky");
}
popup->setSize(QSizeF(420, 420));
if (hasOsmData){
d->setupDialogOsm( popup, placemark );
} else if (isSatellite) {
d->setupDialogSatellite( placemark );
} else if (isCity) {
Private::setupDialogCity( popup, placemark );
} else if (isNation) {
Private::setupDialogNation( popup, placemark );
} else if (isSky) {
Private::setupDialogSkyPlaces( popup, placemark );
} else if ( overlay ) {
Private::setupDialogPhotoOverlay( popup, overlay );
} else if ( placemark && placemark->role().isEmpty() ) {
popup->setContent( placemark->description() );
} else if ( placemark ) {
Private::setupDialogGeoPlaces( popup, placemark );
}
if ( placemark ) {
- if ( placemark->style() == 0 ) {
+ if ( placemark->style() == nullptr ) {
popup->setBackgroundColor(QColor(Qt::white));
popup->setTextColor(QColor(Qt::black));
return;
}
if ( placemark->style()->balloonStyle().displayMode() == GeoDataBalloonStyle::Hide ) {
popup->setVisible(false);
return;
}
QString content = placemark->style()->balloonStyle().text();
if (content.length() > 0) {
content.replace(QStringLiteral("$[name]"), placemark->name(), Qt::CaseInsensitive);
content.replace(QStringLiteral("$[description]"), placemark->description(), Qt::CaseInsensitive);
content.replace(QStringLiteral("$[address]"), placemark->address(), Qt::CaseInsensitive);
// @TODO: implement the line calculation, so that snippet().maxLines actually has effect.
content.replace(QStringLiteral("$[snippet]"), placemark->snippet().text(), Qt::CaseInsensitive);
content.replace(QStringLiteral("$[id]"), placemark->id(), Qt::CaseInsensitive);
QString const basePath = placemark->resolvePath(".");
QUrl const baseUrl = (basePath != QLatin1String(".")) ? QUrl::fromLocalFile(basePath + QLatin1Char('/')) : QUrl();
popup->setContent(content, baseUrl );
}
popup->setBackgroundColor(placemark->style()->balloonStyle().backgroundColor());
popup->setTextColor(placemark->style()->balloonStyle().textColor());
}
popup->popup();
}
}
void MarbleWidgetPopupMenu::slotCopyCoordinates()
{
const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction );
if ( coordinates.isValid() ) {
const qreal longitude_degrees = coordinates.longitude(GeoDataCoordinates::Degree);
const qreal latitude_degrees = coordinates.latitude(GeoDataCoordinates::Degree);
// importing this representation into Marble does not show anything,
// but Merkaartor shows the point
const QString kmlRepresentation = QString::fromLatin1(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n"
"<Document>\n"
" <Placemark>\n"
// " <name></name>\n"
" <Point>\n"
" <coordinates>%1,%2</coordinates>\n"
" </Point>\n"
" </Placemark>\n"
"</Document>\n"
"</kml>\n"
).arg(longitude_degrees, 0, 'f', 10).arg(latitude_degrees, 0, 'f', 10);
// importing this data into Marble and Merkaartor works
const QString gpxRepresentation = QString::fromLatin1(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
"<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" creator=\"trippy\" version=\"0.1\"\n"
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n"
" <wpt lat=\"%1\" lon=\"%2\">\n"
// " <ele>%3</ele>\n"
// " <time></time>\n"
// " <name>%4</name>\n"
" </wpt>\n"
"</gpx>\n"
).arg(latitude_degrees, 0, 'f', 10).arg(longitude_degrees, 0, 'f', 10);
QString positionString = coordinates.toString();
QMimeData * const myMimeData = new QMimeData();
myMimeData->setText(positionString);
myMimeData->setData(QLatin1String("application/vnd.google-earth.kml+xml"), kmlRepresentation.toUtf8());
myMimeData->setData(QLatin1String("application/gpx+xml"), gpxRepresentation.toUtf8());
QClipboard * const clipboard = QApplication::clipboard();
clipboard->setMimeData(myMimeData);
}
}
void MarbleWidgetPopupMenu::slotAboutDialog()
{
QPointer<MarbleAboutDialog> dialog = new MarbleAboutDialog( d->m_widget );
dialog->exec();
delete dialog;
}
void MarbleWidgetPopupMenu::addAction( Qt::MouseButton button, QAction* action )
{
if ( button == Qt::RightButton ) {
d->m_rmbMenu.insertAction( d->m_rmbExtensionPoint, action );
} else {
d->m_lmbMenu.addAction( action );
}
}
void MarbleWidgetPopupMenu::directionsFromHere()
{
RouteRequest* request = d->m_widget->model()->routingManager()->routeRequest();
if ( request )
{
const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction );
if ( coordinates.isValid() ) {
if ( request->size() > 0 ) {
request->setPosition( 0, coordinates );
} else {
request->append( coordinates );
}
d->m_widget->model()->routingManager()->retrieveRoute();
}
}
}
void MarbleWidgetPopupMenu::directionsToHere()
{
RouteRequest* request = d->m_widget->model()->routingManager()->routeRequest();
if ( request )
{
const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction );
if ( coordinates.isValid() ) {
if ( request->size() > 1 ) {
request->setPosition( request->size()-1, coordinates );
} else {
request->append( coordinates );
}
d->m_widget->model()->routingManager()->retrieveRoute();
}
}
}
GeoDataCoordinates MarbleWidgetPopupMenu::Private::mouseCoordinates( QAction* dataContainer ) const
{
if ( !dataContainer ) {
return GeoDataCoordinates();
}
if ( !m_featurelist.isEmpty() && geodata_cast<GeoDataPlacemark>(m_featurelist.first())) {
const GeoDataPlacemark * placemark = static_cast<const GeoDataPlacemark*>( m_featurelist.first() );
return placemark->coordinate( m_model->clock()->dateTime() );
} else {
QPoint p = dataContainer->data().toPoint();
qreal lat( 0.0 ), lon( 0.0 );
const bool valid = m_widget->geoCoordinates( p.x(), p.y(), lon, lat, GeoDataCoordinates::Radian );
if ( valid ) {
return GeoDataCoordinates( lon, lat );
}
}
return GeoDataCoordinates();
}
void MarbleWidgetPopupMenu::startReverseGeocoding()
{
const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction );
if ( coordinates.isValid() ) {
d->m_runnerManager.reverseGeocoding( coordinates );
}
}
void MarbleWidgetPopupMenu::showAddressInformation(const GeoDataCoordinates &, const GeoDataPlacemark &placemark)
{
QString text = placemark.address();
if ( !text.isEmpty() ) {
QMessageBox::information( d->m_widget, tr( "Address Details" ), text, QMessageBox::Ok );
}
}
void MarbleWidgetPopupMenu::addBookmark()
{
const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction );
if ( coordinates.isValid() ) {
QPointer<EditBookmarkDialog> dialog = new EditBookmarkDialog( d->m_widget->model()->bookmarkManager(), d->m_widget );
dialog->setMarbleWidget( d->m_widget );
dialog->setCoordinates( coordinates );
dialog->setRange( d->m_widget->lookAt().range() );
dialog->setReverseGeocodeName();
if ( dialog->exec() == QDialog::Accepted ) {
d->m_widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() );
}
delete dialog;
}
}
void MarbleWidgetPopupMenu::toggleFullscreen( bool enabled )
{
QWidget* parent = d->m_widget;
for ( ; parent->parentWidget(); parent = parent->parentWidget() ) {
// nothing to do
}
if ( enabled ) {
parent->setWindowState( parent->windowState() | Qt::WindowFullScreen );
} else {
parent->setWindowState( parent->windowState() & ~Qt::WindowFullScreen );
}
}
QPoint MarbleWidgetPopupMenu::mousePosition() const
{
return d->m_mousePosition;
}
}
#include "moc_MarbleWidgetPopupMenu.cpp"
diff --git a/src/lib/marble/MarbleZip.cpp b/src/lib/marble/MarbleZip.cpp
index 92519707d..4a7945dd7 100644
--- a/src/lib/marble/MarbleZip.cpp
+++ b/src/lib/marble/MarbleZip.cpp
@@ -1,1282 +1,1282 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// This file is based on qzip.cpp from Qt with the original license
// below, taken from
// http://code.qt.io/cgit/qt/qt.git/plain/src/gui/text/qzip.cpp
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qglobal.h>
#ifndef QT_NO_TEXTODFWRITER
#include "MarbleZipReader.h"
#include "MarbleZipWriter.h"
#include <qdatetime.h>
#include <qplatformdefs.h>
#include <qendian.h>
#include <qdebug.h>
#include <qdir.h>
#include <zlib.h>
#if defined(Q_OS_WIN)
# undef S_IFREG
# define S_IFREG 0100000
# ifndef S_IFDIR
# define S_IFDIR 0040000
# endif
# ifndef S_ISDIR
# define S_ISDIR(x) ((x) & S_IFDIR) > 0
# endif
# ifndef S_ISREG
# define S_ISREG(x) ((x) & 0170000) == S_IFREG
# endif
# define S_IFLNK 020000
# define S_ISLNK(x) ((x) & S_IFLNK) > 0
# ifndef S_IRUSR
# define S_IRUSR 0400
# endif
# ifndef S_IWUSR
# define S_IWUSR 0200
# endif
# ifndef S_IXUSR
# define S_IXUSR 0100
# endif
# define S_IRGRP 0040
# define S_IWGRP 0020
# define S_IXGRP 0010
# define S_IROTH 0004
# define S_IWOTH 0002
# define S_IXOTH 0001
#endif
#if 0
#define ZDEBUG qDebug
#else
#define ZDEBUG if (0) qDebug
#endif
namespace Marble {
static inline uint readUInt(const uchar *data)
{
return (data[0]) + (data[1]<<8) + (data[2]<<16) + (data[3]<<24);
}
static inline ushort readUShort(const uchar *data)
{
return (data[0]) + (data[1]<<8);
}
static inline void writeUInt(uchar *data, uint i)
{
data[0] = i & 0xff;
data[1] = (i>>8) & 0xff;
data[2] = (i>>16) & 0xff;
data[3] = (i>>24) & 0xff;
}
static inline void writeUShort(uchar *data, ushort i)
{
data[0] = i & 0xff;
data[1] = (i>>8) & 0xff;
}
static inline void copyUInt(uchar *dest, const uchar *src)
{
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
}
static inline void copyUShort(uchar *dest, const uchar *src)
{
dest[0] = src[0];
dest[1] = src[1];
}
static void writeMSDosDate(uchar *dest, const QDateTime& dt)
{
if (dt.isValid()) {
quint16 time =
(dt.time().hour() << 11) // 5 bit hour
| (dt.time().minute() << 5) // 6 bit minute
| (dt.time().second() >> 1); // 5 bit double seconds
dest[0] = time & 0xff;
dest[1] = time >> 8;
quint16 date =
((dt.date().year() - 1980) << 9) // 7 bit year 1980-based
| (dt.date().month() << 5) // 4 bit month
| (dt.date().day()); // 5 bit day
dest[2] = char(date);
dest[3] = char(date >> 8);
} else {
dest[0] = 0;
dest[1] = 0;
dest[2] = 0;
dest[3] = 0;
}
}
static quint32 permissionsToMode(QFile::Permissions perms)
{
quint32 mode = 0;
if (perms & QFile::ReadOwner)
mode |= S_IRUSR;
if (perms & QFile::WriteOwner)
mode |= S_IWUSR;
if (perms & QFile::ExeOwner)
mode |= S_IXUSR;
if (perms & QFile::ReadUser)
mode |= S_IRUSR;
if (perms & QFile::WriteUser)
mode |= S_IWUSR;
if (perms & QFile::ExeUser)
mode |= S_IXUSR;
if (perms & QFile::ReadGroup)
mode |= S_IRGRP;
if (perms & QFile::WriteGroup)
mode |= S_IWGRP;
if (perms & QFile::ExeGroup)
mode |= S_IXGRP;
if (perms & QFile::ReadOther)
mode |= S_IROTH;
if (perms & QFile::WriteOther)
mode |= S_IWOTH;
if (perms & QFile::ExeOther)
mode |= S_IXOTH;
return mode;
}
static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
if ((uLong)stream.avail_in != sourceLen)
return Z_BUF_ERROR;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen)
return Z_BUF_ERROR;
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
+ stream.zalloc = (alloc_func)nullptr;
+ stream.zfree = (free_func)nullptr;
err = inflateInit2(&stream, -MAX_WBITS);
if (err != Z_OK)
return err;
err = inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
inflateEnd(&stream);
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
return Z_DATA_ERROR;
return err;
}
*destLen = stream.total_out;
err = inflateEnd(&stream);
return err;
}
static int deflate (Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
{
z_stream stream;
int err;
stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen;
stream.next_out = dest;
stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
+ stream.zalloc = (alloc_func)nullptr;
+ stream.zfree = (free_func)nullptr;
+ stream.opaque = (voidpf)nullptr;
err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK) return err;
err = deflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
deflateEnd(&stream);
return err == Z_OK ? Z_BUF_ERROR : err;
}
*destLen = stream.total_out;
err = deflateEnd(&stream);
return err;
}
static QFile::Permissions modeToPermissions(quint32 mode)
{
QFile::Permissions ret;
if (mode & S_IRUSR)
ret |= QFile::ReadOwner;
if (mode & S_IWUSR)
ret |= QFile::WriteOwner;
if (mode & S_IXUSR)
ret |= QFile::ExeOwner;
if (mode & S_IRUSR)
ret |= QFile::ReadUser;
if (mode & S_IWUSR)
ret |= QFile::WriteUser;
if (mode & S_IXUSR)
ret |= QFile::ExeUser;
if (mode & S_IRGRP)
ret |= QFile::ReadGroup;
if (mode & S_IWGRP)
ret |= QFile::WriteGroup;
if (mode & S_IXGRP)
ret |= QFile::ExeGroup;
if (mode & S_IROTH)
ret |= QFile::ReadOther;
if (mode & S_IWOTH)
ret |= QFile::WriteOther;
if (mode & S_IXOTH)
ret |= QFile::ExeOther;
return ret;
}
static QDateTime readMSDosDate(const uchar *src)
{
uint dosDate = readUInt(src);
quint64 uDate;
uDate = (quint64)(dosDate >> 16);
uint tm_mday = (uDate & 0x1f);
uint tm_mon = ((uDate & 0x1E0) >> 5);
uint tm_year = (((uDate & 0x0FE00) >> 9) + 1980);
uint tm_hour = ((dosDate & 0xF800) >> 11);
uint tm_min = ((dosDate & 0x7E0) >> 5);
uint tm_sec = ((dosDate & 0x1f) << 1);
return QDateTime(QDate(tm_year, tm_mon, tm_mday), QTime(tm_hour, tm_min, tm_sec));
}
struct LocalFileHeader
{
uchar signature[4]; // 0x04034b50
uchar version_needed[2];
uchar general_purpose_bits[2];
uchar compression_method[2];
uchar last_mod_file[4];
uchar crc_32[4];
uchar compressed_size[4];
uchar uncompressed_size[4];
uchar file_name_length[2];
uchar extra_field_length[2];
};
struct DataDescriptor
{
uchar crc_32[4];
uchar compressed_size[4];
uchar uncompressed_size[4];
};
struct CentralFileHeader
{
uchar signature[4]; // 0x02014b50
uchar version_made[2];
uchar version_needed[2];
uchar general_purpose_bits[2];
uchar compression_method[2];
uchar last_mod_file[4];
uchar crc_32[4];
uchar compressed_size[4];
uchar uncompressed_size[4];
uchar file_name_length[2];
uchar extra_field_length[2];
uchar file_comment_length[2];
uchar disk_start[2];
uchar internal_file_attributes[2];
uchar external_file_attributes[4];
uchar offset_local_header[4];
LocalFileHeader toLocalHeader() const;
};
struct EndOfDirectory
{
uchar signature[4]; // 0x06054b50
uchar this_disk[2];
uchar start_of_directory_disk[2];
uchar num_dir_entries_this_disk[2];
uchar num_dir_entries[2];
uchar directory_size[4];
uchar dir_start_offset[4];
uchar comment_length[2];
};
struct FileHeader
{
CentralFileHeader h;
QByteArray file_name;
QByteArray extra_field;
QByteArray file_comment;
};
MarbleZipReader::FileInfo::FileInfo()
: isDir(false), isFile(false), isSymLink(false), crc32(0), size(0)
{
}
MarbleZipReader::FileInfo::~FileInfo()
{
}
MarbleZipReader::FileInfo::FileInfo(const FileInfo &other)
{
operator=(other);
}
MarbleZipReader::FileInfo& MarbleZipReader::FileInfo::operator=(const FileInfo &other)
{
filePath = other.filePath;
isDir = other.isDir;
isFile = other.isFile;
isSymLink = other.isSymLink;
permissions = other.permissions;
crc32 = other.crc32;
size = other.size;
lastModified = other.lastModified;
return *this;
}
bool MarbleZipReader::FileInfo::isValid() const
{
return isDir || isFile || isSymLink;
}
class QZipPrivate
{
public:
QZipPrivate(QIODevice *device, bool ownDev)
: device(device), ownDevice(ownDev), dirtyFileTree(true), start_of_directory(0)
{
}
~QZipPrivate()
{
if (ownDevice)
delete device;
}
void fillFileInfo(int index, MarbleZipReader::FileInfo &fileInfo) const;
QIODevice *device;
bool ownDevice;
bool dirtyFileTree;
QList<FileHeader> fileHeaders;
QByteArray comment;
uint start_of_directory;
};
void QZipPrivate::fillFileInfo(int index, MarbleZipReader::FileInfo &fileInfo) const
{
FileHeader header = fileHeaders.at(index);
fileInfo.filePath = QString::fromLocal8Bit(header.file_name);
const quint32 mode = (qFromLittleEndian<quint32>(&header.h.external_file_attributes[0]) >> 16) & 0xFFFF;
if (mode == 0) {
fileInfo.isDir = false;
fileInfo.isFile = true;
fileInfo.isSymLink = false;
fileInfo.permissions = QFile::ReadOwner;
} else {
fileInfo.isDir = S_ISDIR(mode);
fileInfo.isFile = S_ISREG(mode);
fileInfo.isSymLink = S_ISLNK(mode);
fileInfo.permissions = modeToPermissions(mode);
}
fileInfo.crc32 = readUInt(header.h.crc_32);
fileInfo.size = readUInt(header.h.uncompressed_size);
fileInfo.lastModified = readMSDosDate(header.h.last_mod_file);
}
class MarbleZipReaderPrivate : public QZipPrivate
{
public:
MarbleZipReaderPrivate(QIODevice *device, bool ownDev)
: QZipPrivate(device, ownDev), status(MarbleZipReader::NoError)
{
}
void scanFiles();
MarbleZipReader::Status status;
};
class MarbleZipWriterPrivate : public QZipPrivate
{
public:
MarbleZipWriterPrivate(QIODevice *device, bool ownDev)
: QZipPrivate(device, ownDev),
status(MarbleZipWriter::NoError),
permissions(QFile::ReadOwner | QFile::WriteOwner),
compressionPolicy(MarbleZipWriter::AlwaysCompress)
{
}
MarbleZipWriter::Status status;
QFile::Permissions permissions;
MarbleZipWriter::CompressionPolicy compressionPolicy;
enum EntryType { Directory, File, Symlink };
void addEntry(EntryType type, const QString &fileName, const QByteArray &contents);
};
LocalFileHeader CentralFileHeader::toLocalHeader() const
{
LocalFileHeader h;
writeUInt(h.signature, 0x04034b50);
copyUShort(h.version_needed, version_needed);
copyUShort(h.general_purpose_bits, general_purpose_bits);
copyUShort(h.compression_method, compression_method);
copyUInt(h.last_mod_file, last_mod_file);
copyUInt(h.crc_32, crc_32);
copyUInt(h.compressed_size, compressed_size);
copyUInt(h.uncompressed_size, uncompressed_size);
copyUShort(h.file_name_length, file_name_length);
copyUShort(h.extra_field_length, extra_field_length);
return h;
}
void MarbleZipReaderPrivate::scanFiles()
{
if (!dirtyFileTree)
return;
if (! (device->isOpen() || device->open(QIODevice::ReadOnly))) {
status = MarbleZipReader::FileOpenError;
return;
}
if ((device->openMode() & QIODevice::ReadOnly) == 0) { // only read the index from readable files.
status = MarbleZipReader::FileReadError;
return;
}
dirtyFileTree = false;
uchar tmp[4];
device->read((char *)tmp, 4);
if (readUInt(tmp) != 0x04034b50) {
qWarning() << "QZip: not a zip file!";
return;
}
// find EndOfDirectory header
int i = 0;
int start_of_directory = -1;
int num_dir_entries = 0;
EndOfDirectory eod;
while (start_of_directory == -1) {
int pos = device->size() - sizeof(EndOfDirectory) - i;
if (pos < 0 || i > 65535) {
qWarning() << "QZip: EndOfDirectory not found";
return;
}
device->seek(pos);
device->read((char *)&eod, sizeof(EndOfDirectory));
if (readUInt(eod.signature) == 0x06054b50)
break;
++i;
}
// have the eod
start_of_directory = readUInt(eod.dir_start_offset);
num_dir_entries = readUShort(eod.num_dir_entries);
ZDEBUG("start_of_directory at %d, num_dir_entries=%d", start_of_directory, num_dir_entries);
int comment_length = readUShort(eod.comment_length);
if (comment_length != i)
qWarning() << "QZip: failed to parse zip file.";
comment = device->read(qMin(comment_length, i));
device->seek(start_of_directory);
for (i = 0; i < num_dir_entries; ++i) {
FileHeader header;
int read = device->read((char *) &header.h, sizeof(CentralFileHeader));
if (read < (int)sizeof(CentralFileHeader)) {
qWarning() << "QZip: Failed to read complete header, index may be incomplete";
break;
}
if (readUInt(header.h.signature) != 0x02014b50) {
qWarning() << "QZip: invalid header signature, index may be incomplete";
break;
}
int l = readUShort(header.h.file_name_length);
header.file_name = device->read(l);
if (header.file_name.length() != l) {
qWarning() << "QZip: Failed to read filename from zip index, index may be incomplete";
break;
}
l = readUShort(header.h.extra_field_length);
header.extra_field = device->read(l);
if (header.extra_field.length() != l) {
qWarning() << "QZip: Failed to read extra field in zip file, skipping file, index may be incomplete";
break;
}
l = readUShort(header.h.file_comment_length);
header.file_comment = device->read(l);
if (header.file_comment.length() != l) {
qWarning() << "QZip: Failed to read file comment, index may be incomplete";
break;
}
ZDEBUG("found file '%s'", header.file_name.data());
fileHeaders.append(header);
}
}
void MarbleZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const QByteArray &contents/*, QFile::Permissions permissions, QZip::Method m*/)
{
#ifndef NDEBUG
static const char *entryTypes[] = {
"directory",
"file ",
"symlink " };
ZDEBUG() << "adding" << entryTypes[type] <<":" << fileName.toUtf8().data() << (type == 2 ? QByteArray(" -> " + contents).constData() : "");
#endif
if (! (device->isOpen() || device->open(QIODevice::WriteOnly))) {
status = MarbleZipWriter::FileOpenError;
return;
}
device->seek(start_of_directory);
// don't compress small files
MarbleZipWriter::CompressionPolicy compression = compressionPolicy;
if (compressionPolicy == MarbleZipWriter::AutoCompress) {
if (contents.length() < 64)
compression = MarbleZipWriter::NeverCompress;
else
compression = MarbleZipWriter::AlwaysCompress;
}
FileHeader header;
memset(&header.h, 0, sizeof(CentralFileHeader));
writeUInt(header.h.signature, 0x02014b50);
writeUShort(header.h.version_needed, 0x14);
writeUInt(header.h.uncompressed_size, contents.length());
writeMSDosDate(header.h.last_mod_file, QDateTime::currentDateTime());
QByteArray data = contents;
if (compression == MarbleZipWriter::AlwaysCompress) {
writeUShort(header.h.compression_method, 8);
ulong len = contents.length();
// shamelessly copied form zlib
len += (len >> 12) + (len >> 14) + 11;
int res;
do {
data.resize(len);
res = deflate((uchar*)data.data(), &len, (const uchar*)contents.constData(), contents.length());
switch (res) {
case Z_OK:
data.resize(len);
break;
case Z_MEM_ERROR:
qWarning("QZip: Z_MEM_ERROR: Not enough memory to compress file, skipping");
data.resize(0);
break;
case Z_BUF_ERROR:
len *= 2;
break;
}
} while (res == Z_BUF_ERROR);
}
// TODO add a check if data.length() > contents.length(). Then try to store the original and revert the compression method to be uncompressed
writeUInt(header.h.compressed_size, data.length());
- uint crc_32 = ::crc32(0, 0, 0);
+ uint crc_32 = ::crc32(0, nullptr, 0);
crc_32 = ::crc32(crc_32, (const uchar *)contents.constData(), contents.length());
writeUInt(header.h.crc_32, crc_32);
header.file_name = fileName.toLocal8Bit();
if (header.file_name.size() > 0xffff) {
qWarning("QZip: Filename too long, chopping it to 65535 characters");
header.file_name = header.file_name.left(0xffff);
}
writeUShort(header.h.file_name_length, header.file_name.length());
//h.extra_field_length[2];
writeUShort(header.h.version_made, 3 << 8);
//uchar internal_file_attributes[2];
//uchar external_file_attributes[4];
quint32 mode = permissionsToMode(permissions);
switch (type) {
case File: mode |= S_IFREG; break;
case Directory: mode |= S_IFDIR; break;
case Symlink: mode |= S_IFLNK; break;
}
writeUInt(header.h.external_file_attributes, mode << 16);
writeUInt(header.h.offset_local_header, start_of_directory);
fileHeaders.append(header);
LocalFileHeader h = header.h.toLocalHeader();
device->write((const char *)&h, sizeof(LocalFileHeader));
device->write(header.file_name);
device->write(data);
start_of_directory = device->pos();
dirtyFileTree = true;
}
////////////////////////////// Reader
/*!
\class QZipReader::FileInfo
\internal
Represents one entry in the zip table of contents.
*/
/*!
\variable FileInfo::filePath
The full filepath inside the archive.
*/
/*!
\variable FileInfo::isDir
A boolean type indicating if the entry is a directory.
*/
/*!
\variable FileInfo::isFile
A boolean type, if it is one this entry is a file.
*/
/*!
\variable FileInfo::isSymLink
A boolean type, if it is one this entry is symbolic link.
*/
/*!
\variable FileInfo::permissions
A list of flags for the permissions of this entry.
*/
/*!
\variable FileInfo::crc32
The calculated checksum as a crc32 type.
*/
/*!
\variable FileInfo::size
The total size of the unpacked content.
*/
/*!
\variable FileInfo::d
\internal
private pointer.
*/
/*!
\class QZipReader
\internal
\since 4.5
\brief the QZipReader class provides a way to inspect the contents of a zip
archive and extract individual files from it.
QZipReader can be used to read a zip archive either from a file or from any
device. An in-memory QBuffer for instance. The reader can be used to read
which files are in the archive using fileInfoList() and entryInfoAt() but
also to extract individual files using fileData() or even to extract all
files in the archive using extractAll()
*/
/*!
Create a new zip archive that operates on the \a fileName. The file will be
opened with the \a mode.
*/
MarbleZipReader::MarbleZipReader(const QString &archive, QIODevice::OpenMode mode)
{
QScopedPointer<QFile> f(new QFile(archive));
f->open(mode);
MarbleZipReader::Status status;
if (f->error() == QFile::NoError)
status = NoError;
else {
if (f->error() == QFile::ReadError)
status = FileReadError;
else if (f->error() == QFile::OpenError)
status = FileOpenError;
else if (f->error() == QFile::PermissionsError)
status = FilePermissionsError;
else
status = FileError;
}
d = new MarbleZipReaderPrivate(f.data(), /*ownDevice=*/true);
f.take();
d->status = status;
}
/*!
Create a new zip archive that operates on the archive found in \a device.
You have to open the device previous to calling the constructor and only a
device that is readable will be scanned for zip filecontent.
*/
MarbleZipReader::MarbleZipReader(QIODevice *device)
: d(new MarbleZipReaderPrivate(device, /*ownDevice=*/false))
{
Q_ASSERT(device);
}
/*!
Desctructor
*/
MarbleZipReader::~MarbleZipReader()
{
close();
delete d;
}
/*!
Returns device used for reading zip archive.
*/
QIODevice* MarbleZipReader::device() const
{
return d->device;
}
/*!
Returns true if the user can read the file; otherwise returns false.
*/
bool MarbleZipReader::isReadable() const
{
return d->device->isReadable();
}
/*!
Returns true if the file exists; otherwise returns false.
*/
bool MarbleZipReader::exists() const
{
QFile *f = qobject_cast<QFile*> (d->device);
- if (f == 0)
+ if (f == nullptr)
return true;
return f->exists();
}
/*!
Returns the list of files the archive contains.
*/
QList<MarbleZipReader::FileInfo> MarbleZipReader::fileInfoList() const
{
d->scanFiles();
QList<MarbleZipReader::FileInfo> files;
for (int i = 0; i < d->fileHeaders.size(); ++i) {
MarbleZipReader::FileInfo fi;
d->fillFileInfo(i, fi);
files.append(fi);
}
return files;
}
/*!
Return the number of items in the zip archive.
*/
int MarbleZipReader::count() const
{
d->scanFiles();
return d->fileHeaders.count();
}
/*!
Returns a FileInfo of an entry in the zipfile.
The \a index is the index into the directory listing of the zipfile.
Returns an invalid FileInfo if \a index is out of boundaries.
\sa fileInfoList()
*/
MarbleZipReader::FileInfo MarbleZipReader::entryInfoAt(int index) const
{
d->scanFiles();
MarbleZipReader::FileInfo fi;
if (index >= 0 && index < d->fileHeaders.count())
d->fillFileInfo(index, fi);
return fi;
}
/*!
Fetch the file contents from the zip archive and return the uncompressed bytes.
*/
QByteArray MarbleZipReader::fileData(const QString &fileName) const
{
d->scanFiles();
int i;
for (i = 0; i < d->fileHeaders.size(); ++i) {
if (QString::fromLocal8Bit(d->fileHeaders.at(i).file_name) == fileName)
break;
}
if (i == d->fileHeaders.size())
return QByteArray();
FileHeader header = d->fileHeaders.at(i);
int compressed_size = readUInt(header.h.compressed_size);
int uncompressed_size = readUInt(header.h.uncompressed_size);
int start = readUInt(header.h.offset_local_header);
//qDebug("uncompressing file %d: local header at %d", i, start);
d->device->seek(start);
LocalFileHeader lh;
d->device->read((char *)&lh, sizeof(LocalFileHeader));
uint skip = readUShort(lh.file_name_length) + readUShort(lh.extra_field_length);
d->device->seek(d->device->pos() + skip);
int compression_method = readUShort(lh.compression_method);
//qDebug("file=%s: compressed_size=%d, uncompressed_size=%d", fileName.toLocal8Bit().data(), compressed_size, uncompressed_size);
//qDebug("file at %lld", d->device->pos());
QByteArray compressed = d->device->read(compressed_size);
if (compression_method == 0) {
// no compression
compressed.truncate(uncompressed_size);
return compressed;
} else if (compression_method == 8) {
// Deflate
//qDebug("compressed=%d", compressed.size());
compressed.truncate(compressed_size);
QByteArray baunzip;
ulong len = qMax(uncompressed_size, 1);
int res;
do {
baunzip.resize(len);
res = inflate((uchar*)baunzip.data(), &len,
(uchar*)compressed.constData(), compressed_size);
switch (res) {
case Z_OK:
if ((int)len != baunzip.size())
baunzip.resize(len);
break;
case Z_MEM_ERROR:
qWarning("QZip: Z_MEM_ERROR: Not enough memory");
break;
case Z_BUF_ERROR:
len *= 2;
break;
case Z_DATA_ERROR:
qWarning("QZip: Z_DATA_ERROR: Input data is corrupted");
break;
}
} while (res == Z_BUF_ERROR);
return baunzip;
}
qWarning() << "QZip: Unknown compression method";
return QByteArray();
}
/*!
Extracts the full contents of the zip file into \a destinationDir on
the local filesystem.
In case writing or linking a file fails, the extraction will be aborted.
*/
bool MarbleZipReader::extractAll(const QString &destinationDir) const
{
QDir baseDir(destinationDir);
// create directories first
QList<FileInfo> allFiles = fileInfoList();
for (const FileInfo& fi: allFiles) {
const QString absPath = destinationDir + QDir::separator() + fi.filePath;
if (fi.isDir) {
if (!baseDir.mkpath(fi.filePath))
return false;
if (!QFile::setPermissions(absPath, fi.permissions))
return false;
}
}
// set up symlinks
for (const FileInfo& fi: allFiles) {
const QString absPath = destinationDir + QDir::separator() + fi.filePath;
if (fi.isSymLink) {
QString destination = QFile::decodeName(fileData(fi.filePath));
if (destination.isEmpty())
return false;
QFileInfo linkFi(absPath);
if (!QFile::exists(linkFi.absolutePath()))
QDir::root().mkpath(linkFi.absolutePath());
if (!QFile::link(destination, absPath))
return false;
/* cannot change permission of links
if (!QFile::setPermissions(absPath, fi.permissions))
return false;
*/
}
}
for (const FileInfo& fi: allFiles) {
const QString absPath = destinationDir + QDir::separator() + fi.filePath;
if (fi.isFile) {
QDir::root().mkpath(QFileInfo(absPath).dir().absolutePath());
QFile f(absPath);
if (!f.open(QIODevice::WriteOnly))
return false;
f.write(fileData(fi.filePath));
f.setPermissions(fi.permissions);
f.close();
}
}
return true;
}
/*!
\enum QZipReader::Status
The following status values are possible:
\value NoError No error occurred.
\value FileReadError An error occurred when reading from the file.
\value FileOpenError The file could not be opened.
\value FilePermissionsError The file could not be accessed.
\value FileError Another file error occurred.
*/
/*!
Returns a status code indicating the first error that was met by QZipReader,
or QZipReader::NoError if no error occurred.
*/
MarbleZipReader::Status MarbleZipReader::status() const
{
return d->status;
}
/*!
Close the zip file.
*/
void MarbleZipReader::close()
{
d->device->close();
}
////////////////////////////// Writer
/*!
\class QZipWriter
\internal
\since 4.5
\brief the QZipWriter class provides a way to create a new zip archive.
QZipWriter can be used to create a zip archive containing any number of files
and directories. The files in the archive will be compressed in a way that is
compatible with common zip reader applications.
*/
/*!
Create a new zip archive that operates on the \a archive filename. The file will
be opened with the \a mode.
\sa isValid()
*/
MarbleZipWriter::MarbleZipWriter(const QString &fileName, QIODevice::OpenMode mode)
{
QScopedPointer<QFile> f(new QFile(fileName));
f->open(mode);
MarbleZipWriter::Status status;
if (f->error() == QFile::NoError)
status = MarbleZipWriter::NoError;
else {
if (f->error() == QFile::WriteError)
status = MarbleZipWriter::FileWriteError;
else if (f->error() == QFile::OpenError)
status = MarbleZipWriter::FileOpenError;
else if (f->error() == QFile::PermissionsError)
status = MarbleZipWriter::FilePermissionsError;
else
status = MarbleZipWriter::FileError;
}
d = new MarbleZipWriterPrivate(f.data(), /*ownDevice=*/true);
f.take();
d->status = status;
}
/*!
Create a new zip archive that operates on the archive found in \a device.
You have to open the device previous to calling the constructor and
only a device that is readable will be scanned for zip filecontent.
*/
MarbleZipWriter::MarbleZipWriter(QIODevice *device)
: d(new MarbleZipWriterPrivate(device, /*ownDevice=*/false))
{
Q_ASSERT(device);
}
MarbleZipWriter::~MarbleZipWriter()
{
close();
delete d;
}
/*!
Returns device used for writing zip archive.
*/
QIODevice* MarbleZipWriter::device() const
{
return d->device;
}
/*!
Returns true if the user can write to the archive; otherwise returns false.
*/
bool MarbleZipWriter::isWritable() const
{
return d->device->isWritable();
}
/*!
Returns true if the file exists; otherwise returns false.
*/
bool MarbleZipWriter::exists() const
{
QFile *f = qobject_cast<QFile*> (d->device);
- if (f == 0)
+ if (f == nullptr)
return true;
return f->exists();
}
/*!
\enum QZipWriter::Status
The following status values are possible:
\value NoError No error occurred.
\value FileWriteError An error occurred when writing to the device.
\value FileOpenError The file could not be opened.
\value FilePermissionsError The file could not be accessed.
\value FileError Another file error occurred.
*/
/*!
Returns a status code indicating the first error that was met by QZipWriter,
or QZipWriter::NoError if no error occurred.
*/
MarbleZipWriter::Status MarbleZipWriter::status() const
{
return d->status;
}
/*!
\enum QZipWriter::CompressionPolicy
\value AlwaysCompress A file that is added is compressed.
\value NeverCompress A file that is added will be stored without changes.
\value AutoCompress A file that is added will be compressed only if that will give a smaller file.
*/
/*!
Sets the policy for compressing newly added files to the new \a policy.
\note the default policy is AlwaysCompress
\sa compressionPolicy()
\sa addFile()
*/
void MarbleZipWriter::setCompressionPolicy(CompressionPolicy policy)
{
d->compressionPolicy = policy;
}
/*!
Returns the currently set compression policy.
\sa setCompressionPolicy()
\sa addFile()
*/
MarbleZipWriter::CompressionPolicy MarbleZipWriter::compressionPolicy() const
{
return d->compressionPolicy;
}
/*!
Sets the permissions that will be used for newly added files.
\note the default permissions are QFile::ReadOwner | QFile::WriteOwner.
\sa creationPermissions()
\sa addFile()
*/
void MarbleZipWriter::setCreationPermissions(QFile::Permissions permissions)
{
d->permissions = permissions;
}
/*!
Returns the currently set creation permissions.
\sa setCreationPermissions()
\sa addFile()
*/
QFile::Permissions MarbleZipWriter::creationPermissions() const
{
return d->permissions;
}
/*!
Add a file to the archive with \a data as the file contents.
The file will be stored in the archive using the \a fileName which
includes the full path in the archive.
The new file will get the file permissions based on the current
creationPermissions and it will be compressed using the zip compression
based on the current compression policy.
\sa setCreationPermissions()
\sa setCompressionPolicy()
*/
void MarbleZipWriter::addFile(const QString &fileName, const QByteArray &data)
{
d->addEntry(MarbleZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), data);
}
/*!
Add a file to the archive with \a device as the source of the contents.
The contents returned from QIODevice::readAll() will be used as the
filedata.
The file will be stored in the archive using the \a fileName which
includes the full path in the archive.
*/
void MarbleZipWriter::addFile(const QString &fileName, QIODevice *device)
{
Q_ASSERT(device);
QIODevice::OpenMode mode = device->openMode();
bool opened = false;
if ((mode & QIODevice::ReadOnly) == 0) {
opened = true;
if (! device->open(QIODevice::ReadOnly)) {
d->status = FileOpenError;
return;
}
}
d->addEntry(MarbleZipWriterPrivate::File, QDir::fromNativeSeparators(fileName), device->readAll());
if (opened)
device->close();
}
/*!
Create a new directory in the archive with the specified \a dirName and
the \a permissions;
*/
void MarbleZipWriter::addDirectory(const QString &dirName)
{
QString name(QDir::fromNativeSeparators(dirName));
// separator is mandatory
if (!name.endsWith(QLatin1Char('/')))
name.append(QLatin1Char('/'));
d->addEntry(MarbleZipWriterPrivate::Directory, name, QByteArray());
}
/*!
Create a new symbolic link in the archive with the specified \a dirName
and the \a permissions;
A symbolic link contains the destination (relative) path and name.
*/
void MarbleZipWriter::addSymLink(const QString &fileName, const QString &destination)
{
d->addEntry(MarbleZipWriterPrivate::Symlink, QDir::fromNativeSeparators(fileName), QFile::encodeName(destination));
}
/*!
Closes the zip file.
*/
void MarbleZipWriter::close()
{
if (!(d->device->openMode() & QIODevice::WriteOnly)) {
d->device->close();
return;
}
//qDebug("QZip::close writing directory, %d entries", d->fileHeaders.size());
d->device->seek(d->start_of_directory);
// write new directory
for (int i = 0; i < d->fileHeaders.size(); ++i) {
const FileHeader &header = d->fileHeaders.at(i);
d->device->write((const char *)&header.h, sizeof(CentralFileHeader));
d->device->write(header.file_name);
d->device->write(header.extra_field);
d->device->write(header.file_comment);
}
int dir_size = d->device->pos() - d->start_of_directory;
// write end of directory
EndOfDirectory eod;
memset(&eod, 0, sizeof(EndOfDirectory));
writeUInt(eod.signature, 0x06054b50);
//uchar this_disk[2];
//uchar start_of_directory_disk[2];
writeUShort(eod.num_dir_entries_this_disk, d->fileHeaders.size());
writeUShort(eod.num_dir_entries, d->fileHeaders.size());
writeUInt(eod.directory_size, dir_size);
writeUInt(eod.dir_start_offset, d->start_of_directory);
writeUShort(eod.comment_length, d->comment.length());
d->device->write((const char *)&eod, sizeof(EndOfDirectory));
d->device->write(d->comment);
d->device->close();
}
}
#endif // QT_NO_TEXTODFWRITER
diff --git a/src/lib/marble/MergedLayerDecorator.cpp b/src/lib/marble/MergedLayerDecorator.cpp
index 71007a95f..77cc39934 100644
--- a/src/lib/marble/MergedLayerDecorator.cpp
+++ b/src/lib/marble/MergedLayerDecorator.cpp
@@ -1,622 +1,622 @@
// Copyright 2008 David Roberts <dvdr18@gmail.com>
// Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "MergedLayerDecorator.h"
#include "blendings/Blending.h"
#include "blendings/BlendingFactory.h"
#include "SunLocator.h"
#include "MarbleMath.h"
#include "MarbleDebug.h"
#include "GeoDataGroundOverlay.h"
#include "GeoSceneTextureTileDataset.h"
#include "ImageF.h"
#include "StackedTile.h"
#include "TileLoaderHelper.h"
#include "TextureTile.h"
#include "TileLoader.h"
#include "RenderState.h"
#include "GeoDataCoordinates.h"
#include <QPointer>
#include <QPainter>
using namespace Marble;
class Q_DECL_HIDDEN MergedLayerDecorator::Private
{
public:
Private( TileLoader *tileLoader, const SunLocator *sunLocator );
static int maxDivisor( int maximum, int fullLength );
StackedTile *createTile( const QVector<QSharedPointer<TextureTile> > &tiles ) const;
void renderGroundOverlays( QImage *tileImage, const QVector<QSharedPointer<TextureTile> > &tiles ) const;
void paintSunShading( QImage *tileImage, const TileId &id ) const;
void paintTileId( QImage *tileImage, const TileId &id ) const;
void detectMaxTileLevel();
QVector<const GeoSceneTextureTileDataset *> findRelevantTextureLayers( const TileId &stackedTileId ) const;
TileLoader *const m_tileLoader;
const SunLocator *const m_sunLocator;
BlendingFactory m_blendingFactory;
QVector<const GeoSceneTextureTileDataset *> m_textureLayers;
QList<const GeoDataGroundOverlay *> m_groundOverlays;
int m_maxTileLevel;
QString m_themeId;
int m_levelZeroColumns;
int m_levelZeroRows;
bool m_showSunShading;
bool m_showCityLights;
bool m_showTileId;
};
MergedLayerDecorator::Private::Private( TileLoader *tileLoader, const SunLocator *sunLocator ) :
m_tileLoader( tileLoader ),
m_sunLocator( sunLocator ),
m_blendingFactory( sunLocator ),
m_textureLayers(),
m_maxTileLevel( 0 ),
m_themeId(),
m_levelZeroColumns( 0 ),
m_levelZeroRows( 0 ),
m_showSunShading( false ),
m_showCityLights( false ),
m_showTileId( false )
{
}
MergedLayerDecorator::MergedLayerDecorator( TileLoader * const tileLoader,
const SunLocator* sunLocator )
: d( new Private( tileLoader, sunLocator ) )
{
}
MergedLayerDecorator::~MergedLayerDecorator()
{
delete d;
}
void MergedLayerDecorator::setTextureLayers( const QVector<const GeoSceneTextureTileDataset *> &textureLayers )
{
if ( textureLayers.count() > 0 ) {
const GeoSceneTileDataset *const firstTexture = textureLayers.at( 0 );
d->m_levelZeroColumns = firstTexture->levelZeroColumns();
d->m_levelZeroRows = firstTexture->levelZeroRows();
d->m_blendingFactory.setLevelZeroLayout( d->m_levelZeroColumns, d->m_levelZeroRows );
d->m_themeId = QLatin1String("maps/") + firstTexture->sourceDir();
}
d->m_textureLayers = textureLayers;
d->detectMaxTileLevel();
}
void MergedLayerDecorator::updateGroundOverlays(const QList<const GeoDataGroundOverlay *> &groundOverlays )
{
d->m_groundOverlays = groundOverlays;
}
int MergedLayerDecorator::textureLayersSize() const
{
return d->m_textureLayers.size();
}
int MergedLayerDecorator::maximumTileLevel() const
{
return d->m_maxTileLevel;
}
int MergedLayerDecorator::tileColumnCount( int level ) const
{
Q_ASSERT( !d->m_textureLayers.isEmpty() );
const int levelZeroColumns = d->m_textureLayers.at( 0 )->levelZeroColumns();
return TileLoaderHelper::levelToColumn( levelZeroColumns, level );
}
int MergedLayerDecorator::tileRowCount( int level ) const
{
Q_ASSERT( !d->m_textureLayers.isEmpty() );
const int levelZeroRows = d->m_textureLayers.at( 0 )->levelZeroRows();
return TileLoaderHelper::levelToRow( levelZeroRows, level );
}
const GeoSceneAbstractTileProjection *MergedLayerDecorator::tileProjection() const
{
Q_ASSERT( !d->m_textureLayers.isEmpty() );
return d->m_textureLayers.at(0)->tileProjection();
}
QSize MergedLayerDecorator::tileSize() const
{
Q_ASSERT( !d->m_textureLayers.isEmpty() );
return d->m_textureLayers.at( 0 )->tileSize();
}
StackedTile *MergedLayerDecorator::Private::createTile( const QVector<QSharedPointer<TextureTile> > &tiles ) const
{
Q_ASSERT( !tiles.isEmpty() );
const TileId firstId = tiles.first()->id();
const TileId id( 0, firstId.zoomLevel(), firstId.x(), firstId.y() );
// Image for blending all the texture tiles on it
QImage resultImage;
// if there are more than one active texture layers, we have to convert the
// result tile into QImage::Format_ARGB32_Premultiplied to make blending possible
const bool withConversion = tiles.count() > 1 || m_showSunShading || m_showTileId || !m_groundOverlays.isEmpty();
for ( const QSharedPointer<TextureTile> &tile: tiles ) {
// Image blending. If there are several images in the same tile (like clouds
// or hillshading images over the map) blend them all into only one image
const Blending *const blending = tile->blending();
if ( blending ) {
mDebug() << Q_FUNC_INFO << "blending";
if ( resultImage.isNull() ) {
resultImage = QImage( tile->image()->size(), QImage::Format_ARGB32_Premultiplied );
}
blending->blend( &resultImage, tile.data() );
}
else {
mDebug() << Q_FUNC_INFO << "no blending defined => copying top over bottom image";
if ( withConversion ) {
resultImage = tile->image()->convertToFormat( QImage::Format_ARGB32_Premultiplied );
} else {
resultImage = tile->image()->copy();
}
}
}
renderGroundOverlays( &resultImage, tiles );
if ( m_showSunShading && !m_showCityLights ) {
paintSunShading( &resultImage, id );
}
if ( m_showTileId ) {
paintTileId( &resultImage, id );
}
return new StackedTile( id, resultImage, tiles );
}
void MergedLayerDecorator::Private::renderGroundOverlays( QImage *tileImage, const QVector<QSharedPointer<TextureTile> > &tiles ) const
{
/* All tiles are covering the same area. Pick one. */
const TileId tileId = tiles.first()->id();
const GeoDataLatLonBox tileLatLonBox = findRelevantTextureLayers(tileId).first()->tileProjection()->geoCoordinates(tileId);
/* Map the ground overlay to the image. */
for ( int i = 0; i < m_groundOverlays.size(); ++i ) {
const GeoDataGroundOverlay* overlay = m_groundOverlays.at( i );
if ( !overlay->isGloballyVisible() ) {
continue;
}
const GeoDataLatLonBox overlayLatLonBox = overlay->latLonBox();
if ( !tileLatLonBox.intersects( overlayLatLonBox.toCircumscribedRectangle() ) ) {
continue;
}
const qreal pixelToLat = tileLatLonBox.height() / tileImage->height();
const qreal pixelToLon = tileLatLonBox.width() / tileImage->width();
const qreal latToPixel = overlay->icon().height() / overlayLatLonBox.height();
const qreal lonToPixel = overlay->icon().width() / overlayLatLonBox.width();
const qreal global_height = tileImage->height()
* TileLoaderHelper::levelToRow( m_levelZeroRows, tileId.zoomLevel() );
const qreal pixel2Rad = M_PI / global_height;
const qreal rad2Pixel = global_height / M_PI;
qreal latPixelPosition = rad2Pixel/2 * gdInv(tileLatLonBox.north());
const bool isMercatorTileProjection = (m_textureLayers.at( 0 )->tileProjectionType() == GeoSceneAbstractTileProjection::Mercator);
for ( int y = 0; y < tileImage->height(); ++y ) {
QRgb *scanLine = ( QRgb* ) ( tileImage->scanLine( y ) );
qreal lat = 0;
if (isMercatorTileProjection) {
lat = gd(2 * (latPixelPosition - y) * pixel2Rad );
}
else {
lat = tileLatLonBox.north() - y * pixelToLat;
}
for ( int x = 0; x < tileImage->width(); ++x, ++scanLine ) {
qreal lon = GeoDataCoordinates::normalizeLon( tileLatLonBox.west() + x * pixelToLon );
GeoDataCoordinates coords(lon, lat);
GeoDataCoordinates rotatedCoords(coords);
if (overlay->latLonBox().rotation() != 0) {
// Possible TODO: Make this faster by creating the axisMatrix beforehand
// and just call Quaternion::rotateAroundAxis(const matrix &m) here.
rotatedCoords = coords.rotateAround(overlayLatLonBox.center(), -overlay->latLonBox().rotation());
}
// TODO: The rotated latLonBox is bigger. We need to take this into account.
// (Currently the GroundOverlay sometimes gets clipped because of that)
if ( overlay->latLonBox().contains( rotatedCoords ) ) {
qreal px = GeoDataLatLonBox::width( rotatedCoords.longitude(), overlayLatLonBox.west() ) * lonToPixel;
qreal py = (qreal)( overlay->icon().height() ) - ( GeoDataLatLonBox::height( rotatedCoords.latitude(), overlayLatLonBox.south() ) * latToPixel ) - 1;
if ( px >= 0 && px < overlay->icon().width() && py >= 0 && py < overlay->icon().height() ) {
int alpha = qAlpha( overlay->icon().pixel( px, py ) );
if ( alpha != 0 )
{
QRgb result = ImageF::pixelF( overlay->icon(), px, py );
if (alpha == 255)
{
*scanLine = result;
}
else
{
*scanLine = qRgb( ( alpha * qRed(result) + (255 - alpha) * qRed(*scanLine) ) / 255,
( alpha * qGreen(result) + (255 - alpha) * qGreen(*scanLine) ) / 255,
( alpha * qBlue(result) + (255 - alpha) * qBlue(*scanLine) ) / 255 );
}
}
}
}
}
}
}
}
StackedTile *MergedLayerDecorator::loadTile( const TileId &stackedTileId )
{
const QVector<const GeoSceneTextureTileDataset *> textureLayers = d->findRelevantTextureLayers( stackedTileId );
QVector<QSharedPointer<TextureTile> > tiles;
tiles.reserve(textureLayers.size());
for ( const GeoSceneTextureTileDataset *layer: textureLayers ) {
const TileId tileId( layer->sourceDir(), stackedTileId.zoomLevel(),
stackedTileId.x(), stackedTileId.y() );
mDebug() << Q_FUNC_INFO << layer->sourceDir() << tileId << layer->tileSize() << layer->fileFormat();
// Blending (how to merge the images into an only image)
const Blending *blending = d->m_blendingFactory.findBlending( layer->blending() );
- if ( blending == 0 && !layer->blending().isEmpty() ) {
+ if ( blending == nullptr && !layer->blending().isEmpty() ) {
mDebug() << Q_FUNC_INFO << "could not find blending" << layer->blending();
}
const GeoSceneTextureTileDataset *const textureLayer = static_cast<const GeoSceneTextureTileDataset *>( layer );
const QImage tileImage = d->m_tileLoader->loadTileImage( textureLayer, tileId, DownloadBrowse );
QSharedPointer<TextureTile> tile( new TextureTile( tileId, tileImage, blending ) );
tiles.append( tile );
}
Q_ASSERT( !tiles.isEmpty() );
return d->createTile( tiles );
}
RenderState MergedLayerDecorator::renderState( const TileId &stackedTileId ) const
{
QString const nameTemplate = "Tile %1/%2/%3";
RenderState state( nameTemplate.arg( stackedTileId.zoomLevel() )
.arg( stackedTileId.x() )
.arg( stackedTileId.y() ) );
const QVector<const GeoSceneTextureTileDataset *> textureLayers = d->findRelevantTextureLayers( stackedTileId );
for ( const GeoSceneTextureTileDataset *layer: textureLayers ) {
const TileId tileId( layer->sourceDir(), stackedTileId.zoomLevel(),
stackedTileId.x(), stackedTileId.y() );
RenderStatus tileStatus = Complete;
switch ( TileLoader::tileStatus( layer, tileId ) ) {
case TileLoader::Available:
tileStatus = Complete;
break;
case TileLoader::Expired:
tileStatus = WaitingForUpdate;
break;
case TileLoader::Missing:
tileStatus = WaitingForData;
break;
}
state.addChild( RenderState( layer->name(), tileStatus ) );
}
return state;
}
bool MergedLayerDecorator::hasTextureLayer() const
{
return !d->m_textureLayers.isEmpty();
}
StackedTile *MergedLayerDecorator::updateTile( const StackedTile &stackedTile, const TileId &tileId, const QImage &tileImage )
{
Q_ASSERT( !tileImage.isNull() );
d->detectMaxTileLevel();
QVector<QSharedPointer<TextureTile> > tiles = stackedTile.tiles();
for ( int i = 0; i < tiles.count(); ++ i) {
if ( tiles[i]->id() == tileId ) {
const Blending *blending = tiles[i]->blending();
tiles[i] = QSharedPointer<TextureTile>( new TextureTile( tileId, tileImage, blending ) );
}
}
return d->createTile( tiles );
}
void MergedLayerDecorator::downloadStackedTile( const TileId &id, DownloadUsage usage )
{
const QVector<const GeoSceneTextureTileDataset *> textureLayers = d->findRelevantTextureLayers( id );
for ( const GeoSceneTextureTileDataset *textureLayer: textureLayers ) {
if ( TileLoader::tileStatus( textureLayer, id ) != TileLoader::Available || usage == DownloadBrowse ) {
d->m_tileLoader->downloadTile( textureLayer, id, usage );
}
}
}
void MergedLayerDecorator::setShowSunShading( bool show )
{
d->m_showSunShading = show;
}
bool MergedLayerDecorator::showSunShading() const
{
return d->m_showSunShading;
}
void MergedLayerDecorator::setShowCityLights( bool show )
{
d->m_showCityLights = show;
}
bool MergedLayerDecorator::showCityLights() const
{
return d->m_showCityLights;
}
void MergedLayerDecorator::setShowTileId( bool visible )
{
d->m_showTileId = visible;
}
void MergedLayerDecorator::Private::paintSunShading( QImage *tileImage, const TileId &id ) const
{
if ( tileImage->depth() != 32 )
return;
// TODO add support for 8-bit maps?
// add sun shading
const qreal global_width = tileImage->width()
* TileLoaderHelper::levelToColumn( m_levelZeroColumns, id.zoomLevel() );
const qreal global_height = tileImage->height()
* TileLoaderHelper::levelToRow( m_levelZeroRows, id.zoomLevel() );
const qreal lon_scale = 2*M_PI / global_width;
const qreal lat_scale = -M_PI / global_height;
const int tileHeight = tileImage->height();
const int tileWidth = tileImage->width();
// First we determine the supporting point interval for the interpolation.
const int n = maxDivisor( 30, tileWidth );
const int ipRight = n * (int)( tileWidth / n );
for ( int cur_y = 0; cur_y < tileHeight; ++cur_y ) {
const qreal lat = lat_scale * ( id.y() * tileHeight + cur_y ) - 0.5*M_PI;
const qreal a = sin( (lat+DEG2RAD * m_sunLocator->getLat() )/2.0 );
const qreal c = cos(lat)*cos( -DEG2RAD * m_sunLocator->getLat() );
QRgb* scanline = (QRgb*)tileImage->scanLine( cur_y );
qreal lastShade = -10.0;
int cur_x = 0;
while ( cur_x < tileWidth ) {
const bool interpolate = ( cur_x != 0 && cur_x < ipRight && cur_x + n < tileWidth );
qreal shade = 0;
if ( interpolate ) {
const int check = cur_x + n;
const qreal checklon = lon_scale * ( id.x() * tileWidth + check );
shade = m_sunLocator->shading( checklon, a, c );
// if the shading didn't change across the interpolation
// interval move on and don't change anything.
if ( shade == lastShade && shade == 1.0 ) {
scanline += n;
cur_x += n;
continue;
}
if ( shade == lastShade && shade == 0.0 ) {
for ( int t = 0; t < n; ++t ) {
SunLocator::shadePixel(*scanline, shade);
++scanline;
}
cur_x += n;
continue;
}
for ( int t = 0; t < n ; ++t ) {
const qreal lon = lon_scale * ( id.x() * tileWidth + cur_x );
shade = m_sunLocator->shading( lon, a, c );
SunLocator::shadePixel(*scanline, shade);
++scanline;
++cur_x;
}
}
else {
// Make sure we don't exceed the image memory
if ( cur_x < tileWidth ) {
const qreal lon = lon_scale * ( id.x() * tileWidth + cur_x );
shade = m_sunLocator->shading( lon, a, c );
SunLocator::shadePixel(*scanline, shade);
++scanline;
++cur_x;
}
}
lastShade = shade;
}
}
}
void MergedLayerDecorator::Private::paintTileId( QImage *tileImage, const TileId &id ) const
{
QString filename = QString( "%1_%2.jpg" )
.arg(id.x(), tileDigits, 10, QLatin1Char('0'))
.arg(id.y(), tileDigits, 10, QLatin1Char('0'));
QPainter painter( tileImage );
QColor foreground;
QColor background;
if ( ( (qreal)(id.x())/2 == id.x()/2 && (qreal)(id.y())/2 == id.y()/2 )
|| ( (qreal)(id.x())/2 != id.x()/2 && (qreal)(id.y())/2 != id.y()/2 )
)
{
foreground.setNamedColor( "#FFFFFF" );
background.setNamedColor( "#000000" );
}
else {
foreground.setNamedColor( "#000000" );
background.setNamedColor( "#FFFFFF" );
}
int strokeWidth = 10;
QPen testPen( foreground );
testPen.setWidth( strokeWidth );
testPen.setJoinStyle( Qt::MiterJoin );
painter.setPen( testPen );
painter.drawRect( strokeWidth / 2, strokeWidth / 2,
tileImage->width() - strokeWidth,
tileImage->height() - strokeWidth );
QFont testFont(QStringLiteral("Sans Serif"), 12);
QFontMetrics testFm( testFont );
painter.setFont( testFont );
QPen outlinepen( foreground );
outlinepen.setWidthF( 6 );
painter.setPen( outlinepen );
painter.setBrush( background );
QPainterPath outlinepath;
QPointF baseline1( ( tileImage->width() - testFm.boundingRect(filename).width() ) / 2,
( tileImage->height() * 0.25) );
outlinepath.addText( baseline1, testFont, QString( "level: %1" ).arg(id.zoomLevel()) );
QPointF baseline2( ( tileImage->width() - testFm.boundingRect(filename).width() ) / 2,
tileImage->height() * 0.50 );
outlinepath.addText( baseline2, testFont, filename );
QPointF baseline3( ( tileImage->width() - testFm.boundingRect(filename).width() ) / 2,
tileImage->height() * 0.75 );
outlinepath.addText( baseline3, testFont, m_themeId );
painter.drawPath( outlinepath );
painter.setPen( Qt::NoPen );
painter.drawPath( outlinepath );
}
void MergedLayerDecorator::Private::detectMaxTileLevel()
{
if ( m_textureLayers.isEmpty() ) {
m_maxTileLevel = -1;
return;
}
m_maxTileLevel = TileLoader::maximumTileLevel( *m_textureLayers.at( 0 ) );
}
QVector<const GeoSceneTextureTileDataset *> MergedLayerDecorator::Private::findRelevantTextureLayers( const TileId &stackedTileId ) const
{
QVector<const GeoSceneTextureTileDataset *> result;
for ( const GeoSceneTextureTileDataset *candidate: m_textureLayers ) {
Q_ASSERT( candidate );
// check, if layer provides tiles for the current level
if ( !candidate->hasMaximumTileLevel() ||
candidate->maximumTileLevel() >= stackedTileId.zoomLevel() ) {
//check if the tile intersects with texture bounds
if (candidate->latLonBox().isNull()) {
result.append(candidate);
}
else {
const GeoDataLatLonBox bbox = candidate->tileProjection()->geoCoordinates(stackedTileId);
if (candidate->latLonBox().intersects(bbox)) {
result.append( candidate );
}
}
}
}
return result;
}
// TODO: This should likely go into a math class in the future ...
int MergedLayerDecorator::Private::maxDivisor( int maximum, int fullLength )
{
// Find the optimal interpolation interval n for the
// current image canvas width
int best = 2;
int nEvalMin = fullLength;
for ( int it = 1; it <= maximum; ++it ) {
// The optimum is the interval which results in the least amount
// supporting points taking into account the rest which can't
// get used for interpolation.
int nEval = fullLength / it + fullLength % it;
if ( nEval < nEvalMin ) {
nEvalMin = nEval;
best = it;
}
}
return best;
}
diff --git a/src/lib/marble/MovieCaptureDialog.h b/src/lib/marble/MovieCaptureDialog.h
index 0f40dc7bb..6ca4a14d2 100644
--- a/src/lib/marble/MovieCaptureDialog.h
+++ b/src/lib/marble/MovieCaptureDialog.h
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef MOVIECAPTUREDIALOG_H
#define MOVIECAPTUREDIALOG_H
#include <QDialog>
#include "marble_export.h"
namespace Ui {
class MovieCaptureDialog;
}
namespace Marble {
class MarbleWidget;
class MovieCapture;
class MARBLE_EXPORT MovieCaptureDialog : public QDialog
{
Q_OBJECT
public:
- explicit MovieCaptureDialog(MarbleWidget *widget, QWidget *parent = 0);
+ explicit MovieCaptureDialog(MarbleWidget *widget, QWidget *parent = nullptr);
~MovieCaptureDialog() override;
public Q_SLOTS:
void startRecording();
void stopRecording();
private Q_SLOTS:
void loadDestinationFile();
Q_SIGNALS:
void started();
private:
Ui::MovieCaptureDialog *ui;
MovieCapture *m_recorder;
};
} // namespace Marble
#endif // MOVIECAPTUREDIALOG_H
diff --git a/src/lib/marble/NewBookmarkFolderDialog.h b/src/lib/marble/NewBookmarkFolderDialog.h
index c0efef7a0..fe8ba125d 100644
--- a/src/lib/marble/NewBookmarkFolderDialog.h
+++ b/src/lib/marble/NewBookmarkFolderDialog.h
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
//
#ifndef MARBLE_NEWBOOKMARKFOLDERDIALOG_H
#define MARBLE_NEWBOOKMARKFOLDERDIALOG_H
#include "ui_NewBookmarkFolderDialog.h"
#include "marble_export.h"
namespace Marble
{
class MARBLE_EXPORT NewBookmarkFolderDialog : public QDialog, private Ui::UiNewBookmarkFolderDialog
{
Q_OBJECT
public:
- explicit NewBookmarkFolderDialog( QWidget *parent = 0 );
+ explicit NewBookmarkFolderDialog( QWidget *parent = nullptr );
~NewBookmarkFolderDialog() override;
void setFolderName( const QString &name );
QString folderName() const;
private:
Q_DISABLE_COPY( NewBookmarkFolderDialog )
};
}
#endif
diff --git a/src/lib/marble/NewstuffModel.cpp b/src/lib/marble/NewstuffModel.cpp
index 05d1d7788..23bb182ac 100644
--- a/src/lib/marble/NewstuffModel.cpp
+++ b/src/lib/marble/NewstuffModel.cpp
@@ -1,963 +1,963 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "NewstuffModel.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleZipReader.h"
#include <QUrl>
#include <QVector>
#include <QTemporaryFile>
#include <QDir>
#include <QFuture>
#include <QPair>
#include <QFutureWatcher>
#include <QtConcurrentRun>
#include <QProcessEnvironment>
#include <QMutexLocker>
#include <QIcon>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDomDocument>
namespace Marble
{
class NewstuffItem
{
public:
QString m_category;
QString m_name;
QString m_author;
QString m_license;
QString m_summary;
QString m_version;
QString m_releaseDate;
QUrl m_previewUrl;
QIcon m_preview;
QUrl m_payloadUrl;
QDomNode m_registryNode;
qint64 m_payloadSize;
qint64 m_downloadedSize;
NewstuffItem();
QString installedVersion() const;
QString installedReleaseDate() const;
bool isUpgradable() const;
QStringList installedFiles() const;
static bool deeperThan( const QString &one, const QString &two );
};
class FetchPreviewJob;
class NewstuffModelPrivate
{
public:
enum NodeAction {
Append,
Replace
};
enum UserAction {
Install,
Uninstall
};
typedef QPair<int, UserAction> Action;
NewstuffModel* m_parent;
QVector<NewstuffItem> m_items;
QNetworkAccessManager m_networkAccessManager;
QString m_provider;
QMap<QNetworkReply *, FetchPreviewJob *> m_networkJobs;
QNetworkReply* m_currentReply;
QTemporaryFile* m_currentFile;
QString m_targetDirectory;
QString m_registryFile;
NewstuffModel::IdTag m_idTag;
QDomDocument m_registryDocument;
QDomElement m_root;
Action m_currentAction;
QProcess* m_unpackProcess;
QMutex m_mutex;
QList<Action> m_actionQueue;
QHash<int, QByteArray> m_roleNames;
explicit NewstuffModelPrivate( NewstuffModel* parent );
QIcon preview( int index );
void setPreview( int index, const QIcon &previewIcon );
void handleProviderData( QNetworkReply* reply );
static bool canExecute( const QString &executable );
void installMap();
void updateModel();
void saveRegistry();
void uninstall( int index );
static void changeNode( QDomNode &node, QDomDocument &domDocument, const QString &key, const QString &value, NodeAction action );
void readInstalledFiles( QStringList* target, const QDomNode &node );
void processQueue();
static NewstuffItem importNode( const QDomNode &node );
bool isTransitioning( int index ) const;
void unzip();
void updateRegistry(const QStringList &files);
template<class T>
static void readValue( const QDomNode &node, const QString &key, T* target );
};
class FetchPreviewJob
{
public:
FetchPreviewJob( NewstuffModelPrivate *modelPrivate, int index );
void run( const QByteArray &data );
private:
NewstuffModelPrivate *const m_modelPrivate;
const int m_index;
};
NewstuffItem::NewstuffItem() : m_payloadSize( -2 ), m_downloadedSize( 0 )
{
// nothing to do
}
QString NewstuffItem::installedVersion() const
{
QDomNodeList const nodes = m_registryNode.toElement().elementsByTagName( "version" );
if ( nodes.size() == 1 ) {
return nodes.at( 0 ).toElement().text();
}
return QString();
}
QString NewstuffItem::installedReleaseDate() const
{
QDomNodeList const nodes = m_registryNode.toElement().elementsByTagName( "releasedate" );
if ( nodes.size() == 1 ) {
return nodes.at( 0 ).toElement().text();
}
return QString();
}
bool NewstuffItem::isUpgradable() const
{
bool installedOk, remoteOk;
double const installed = installedVersion().toDouble( &installedOk );
double const remote= m_version.toDouble( &remoteOk );
return installedOk && remoteOk && remote > installed;
}
QStringList NewstuffItem::installedFiles() const
{
QStringList result;
QDomNodeList const nodes = m_registryNode.toElement().elementsByTagName( "installedfile" );
for ( int i=0; i<nodes.count(); ++i ) {
result << nodes.at( i ).toElement().text();
}
return result;
}
bool NewstuffItem::deeperThan(const QString &one, const QString &two)
{
return one.length() > two.length();
}
FetchPreviewJob::FetchPreviewJob( NewstuffModelPrivate *modelPrivate, int index ) :
m_modelPrivate( modelPrivate ),
m_index( index )
{
}
void FetchPreviewJob::run( const QByteArray &data )
{
const QImage image = QImage::fromData( data );
if ( image.isNull() )
return;
const QPixmap pixmap = QPixmap::fromImage( image );
const QIcon previewIcon( pixmap );
m_modelPrivate->setPreview( m_index, previewIcon );
}
NewstuffModelPrivate::NewstuffModelPrivate( NewstuffModel* parent ) : m_parent( parent ),
- m_networkAccessManager( 0 ), m_currentReply( 0 ), m_currentFile( 0 ),
- m_idTag( NewstuffModel::PayloadTag ), m_currentAction( -1, Install ), m_unpackProcess( 0 )
+ m_networkAccessManager( nullptr ), m_currentReply( nullptr ), m_currentFile( nullptr ),
+ m_idTag( NewstuffModel::PayloadTag ), m_currentAction( -1, Install ), m_unpackProcess( nullptr )
{
// nothing to do
}
QIcon NewstuffModelPrivate::preview( int index )
{
if ( m_items.at( index ).m_preview.isNull() ) {
QPixmap dummyPixmap( 136, 136 );
dummyPixmap.fill( Qt::transparent );
setPreview( index, QIcon( dummyPixmap ) );
QNetworkReply *reply = m_networkAccessManager.get( QNetworkRequest( m_items.at( index ).m_previewUrl ) );
m_networkJobs.insert( reply, new FetchPreviewJob( this, index ) );
}
Q_ASSERT( !m_items.at( index ).m_preview.isNull() );
return m_items.at( index ).m_preview;
}
void NewstuffModelPrivate::setPreview( int index, const QIcon &previewIcon )
{
NewstuffItem &item = m_items[index];
item.m_preview = previewIcon;
const QModelIndex affected = m_parent->index( index );
emit m_parent->dataChanged( affected, affected );
}
void NewstuffModelPrivate::handleProviderData(QNetworkReply *reply)
{
if ( reply->operation() == QNetworkAccessManager::HeadOperation ) {
const QVariant redirectionAttribute = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirectionAttribute.isNull() ) {
for ( int i=0; i<m_items.size(); ++i ) {
NewstuffItem &item = m_items[i];
if ( item.m_payloadUrl == reply->url() ) {
item.m_payloadUrl = redirectionAttribute.toUrl();
}
}
m_networkAccessManager.head( QNetworkRequest( redirectionAttribute.toUrl() ) );
return;
}
QVariant const size = reply->header( QNetworkRequest::ContentLengthHeader );
if ( size.isValid() ) {
qint64 length = size.value<qint64>();
for ( int i=0; i<m_items.size(); ++i ) {
NewstuffItem &item = m_items[i];
if ( item.m_payloadUrl == reply->url() ) {
item.m_payloadSize = length;
QModelIndex const affected = m_parent->index( i );
emit m_parent->dataChanged( affected, affected );
}
}
}
return;
}
FetchPreviewJob *const job = m_networkJobs.take( reply );
// check if we are redirected
const QVariant redirectionAttribute = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirectionAttribute.isNull() ) {
QNetworkReply *redirectReply = m_networkAccessManager.get( QNetworkRequest( QUrl( redirectionAttribute.toUrl() ) ) );
if ( job ) {
m_networkJobs.insert( redirectReply, job );
}
return;
}
if ( job ) {
job->run( reply->readAll() );
delete job;
return;
}
QDomDocument xml;
if ( !xml.setContent( reply->readAll() ) ) {
mDebug() << "Cannot parse newstuff xml data ";
return;
}
m_items.clear();
QDomElement root = xml.documentElement();
QDomNodeList items = root.elementsByTagName( "stuff" );
for (int i=0 ; i < items.length(); ++i ) {
m_items << importNode( items.item( i ) );
}
updateModel();
}
bool NewstuffModelPrivate::canExecute( const QString &executable )
{
QString path = QProcessEnvironment::systemEnvironment().value(QStringLiteral("PATH"), QStringLiteral("/usr/local/bin:/usr/bin:/bin"));
for( const QString &dir: path.split( QLatin1Char( ':' ) ) ) {
QFileInfo application( QDir( dir ), executable );
if ( application.exists() ) {
return true;
}
}
return false;
}
void NewstuffModelPrivate::installMap()
{
if ( m_unpackProcess ) {
m_unpackProcess->close();
delete m_unpackProcess;
- m_unpackProcess = 0;
+ m_unpackProcess = nullptr;
} else if ( m_currentFile->fileName().endsWith( QLatin1String( "zip" ) ) ) {
unzip();
}
else if ( m_currentFile->fileName().endsWith( QLatin1String( "tar.gz" ) ) && canExecute( "tar" ) ) {
m_unpackProcess = new QProcess;
QObject::connect( m_unpackProcess, SIGNAL(finished(int)),
m_parent, SLOT(contentsListed(int)) );
QStringList arguments = QStringList() << "-t" << "-z" << "-f" << m_currentFile->fileName();
m_unpackProcess->setWorkingDirectory( m_targetDirectory );
m_unpackProcess->start( "tar", arguments );
} else {
if ( !m_currentFile->fileName().endsWith( QLatin1String( "tar.gz" ) ) ) {
mDebug() << "Can only handle tar.gz files";
} else {
mDebug() << "Cannot extract archive: tar executable not found in PATH.";
}
}
}
void NewstuffModelPrivate::unzip()
{
MarbleZipReader zipReader(m_currentFile->fileName());
QStringList files;
for(const MarbleZipReader::FileInfo &fileInfo: zipReader.fileInfoList()) {
files << fileInfo.filePath;
}
updateRegistry(files);
zipReader.extractAll(m_targetDirectory);
m_parent->mapInstalled(0);
}
void NewstuffModelPrivate::updateModel()
{
QDomNodeList items = m_root.elementsByTagName( "stuff" );
for (int i=0 ; i < items.length(); ++i ) {
QString const key = m_idTag == NewstuffModel::PayloadTag ? "payload" : "name";
QDomNodeList matches = items.item( i ).toElement().elementsByTagName( key );
if ( matches.size() == 1 ) {
QString const value = matches.at( 0 ).toElement().text();
bool found = false;
for ( int j=0; j<m_items.size() && !found; ++j ) {
NewstuffItem &item = m_items[j];
if ( m_idTag == NewstuffModel::PayloadTag && item.m_payloadUrl.toString() == value ) {
item.m_registryNode = items.item( i );
found = true;
}
if ( m_idTag == NewstuffModel::NameTag && item.m_name == value ) {
item.m_registryNode = items.item( i );
found = true;
}
}
if ( !found ) {
// Not found in newstuff or newstuff not there yet
NewstuffItem item = importNode( items.item( i ) );
if ( m_idTag == NewstuffModel::PayloadTag ) {
item.m_registryNode = items.item( i );
} else if ( m_idTag == NewstuffModel::NameTag ) {
item.m_registryNode = items.item( i );
}
m_items << item;
}
}
}
m_parent->beginResetModel();
m_parent->endResetModel();
}
void NewstuffModelPrivate::saveRegistry()
{
QFile output( m_registryFile );
if ( !output.open( QFile::WriteOnly ) ) {
mDebug() << "Cannot open " << m_registryFile << " for writing";
} else {
QTextStream outStream( &output );
outStream << m_registryDocument.toString( 2 );
outStream.flush();
output.close();
}
}
void NewstuffModelPrivate::uninstall( int index )
{
// Delete all files first, then directories (deeper ones first)
QStringList directories;
QStringList const files = m_items[index].installedFiles();
for( const QString &file: files ) {
if (file.endsWith(QLatin1Char('/'))) {
directories << file;
} else {
QFile::remove( file );
}
}
std::sort( directories.begin(), directories.end(), NewstuffItem::deeperThan );
for( const QString &dir: directories ) {
QDir::root().rmdir( dir );
}
m_items[index].m_registryNode.parentNode().removeChild( m_items[index].m_registryNode );
m_items[index].m_registryNode.clear();
saveRegistry();
}
void NewstuffModelPrivate::changeNode( QDomNode &node, QDomDocument &domDocument, const QString &key, const QString &value, NodeAction action )
{
if ( action == Append ) {
QDomNode newNode = node.appendChild( domDocument.createElement( key ) );
newNode.appendChild( domDocument.createTextNode( value ) );
} else {
QDomNode oldNode = node.namedItem( key );
if ( !oldNode.isNull() ) {
oldNode.removeChild( oldNode.firstChild() );
oldNode.appendChild( domDocument.createTextNode( value ) );
}
}
}
template<class T>
void NewstuffModelPrivate::readValue( const QDomNode &node, const QString &key, T* target )
{
QDomNodeList matches = node.toElement().elementsByTagName( key );
if ( matches.size() == 1 ) {
*target = T(matches.at( 0 ).toElement().text());
} else {
for ( int i=0; i<matches.size(); ++i ) {
if ( matches.at( i ).attributes().contains(QStringLiteral("lang")) &&
matches.at( i ).attributes().namedItem(QStringLiteral("lang")).toAttr().value() == QLatin1String("en")) {
*target = T(matches.at( i ).toElement().text());
return;
}
}
}
}
NewstuffModel::NewstuffModel( QObject *parent ) :
QAbstractListModel( parent ), d( new NewstuffModelPrivate( this ) )
{
setTargetDirectory(MarbleDirs::localPath() + QLatin1String("/maps"));
// no default registry file
connect( &d->m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(handleProviderData(QNetworkReply*)) );
QHash<int,QByteArray> roles;
roles[Qt::DisplayRole] = "display";
roles[Name] = "name";
roles[Author] = "author";
roles[License] = "license";
roles[Summary] = "summary";
roles[Version] = "version";
roles[ReleaseDate] = "releasedate";
roles[Preview] = "preview";
roles[Payload] = "payload";
roles[InstalledVersion] = "installedversion";
roles[InstalledReleaseDate] = "installedreleasedate";
roles[InstalledFiles] = "installedfiles";
roles[IsInstalled] = "installed";
roles[IsUpgradable] = "upgradable";
roles[Category] = "category";
roles[IsTransitioning] = "transitioning";
roles[PayloadSize] = "size";
roles[DownloadedSize] = "downloaded";
d->m_roleNames = roles;
}
NewstuffModel::~NewstuffModel()
{
delete d;
}
int NewstuffModel::rowCount ( const QModelIndex &parent ) const
{
if ( !parent.isValid() ) {
return d->m_items.size();
}
return 0;
}
QVariant NewstuffModel::data ( const QModelIndex &index, int role ) const
{
if ( index.isValid() && index.row() >= 0 && index.row() < d->m_items.size() ) {
switch ( role ) {
case Qt::DisplayRole: return d->m_items.at( index.row() ).m_name;
case Qt::DecorationRole: return d->preview( index.row() );
case Name: return d->m_items.at( index.row() ).m_name;
case Author: return d->m_items.at( index.row() ).m_author;
case License: return d->m_items.at( index.row() ).m_license;
case Summary: return d->m_items.at( index.row() ).m_summary;
case Version: return d->m_items.at( index.row() ).m_version;
case ReleaseDate: return d->m_items.at( index.row() ).m_releaseDate;
case Preview: return d->m_items.at( index.row() ).m_previewUrl;
case Payload: return d->m_items.at( index.row() ).m_payloadUrl;
case InstalledVersion: return d->m_items.at( index.row() ).installedVersion();
case InstalledReleaseDate: return d->m_items.at( index.row() ).installedReleaseDate();
case InstalledFiles: return d->m_items.at( index.row() ).installedFiles();
case IsInstalled: return !d->m_items.at( index.row() ).m_registryNode.isNull();
case IsUpgradable: return d->m_items.at( index.row() ).isUpgradable();
case Category: return d->m_items.at( index.row() ).m_category;
case IsTransitioning: return d->isTransitioning( index.row() );
case PayloadSize: {
qint64 const size = d->m_items.at( index.row() ).m_payloadSize;
QUrl const url = d->m_items.at( index.row() ).m_payloadUrl;
if ( size < -1 && !url.isEmpty() ) {
d->m_items[index.row()].m_payloadSize = -1; // prevent several head requests for the same item
d->m_networkAccessManager.head( QNetworkRequest( url ) );
}
return qMax<qint64>( -1, size );
}
case DownloadedSize: return d->m_items.at( index.row() ).m_downloadedSize;
}
}
return QVariant();
}
QHash<int, QByteArray> NewstuffModel::roleNames() const
{
return d->m_roleNames;
}
int NewstuffModel::count() const
{
return rowCount();
}
void NewstuffModel::setProvider( const QString &downloadUrl )
{
if ( downloadUrl == d->m_provider ) {
return;
}
d->m_provider = downloadUrl;
emit providerChanged();
d->m_networkAccessManager.get( QNetworkRequest( QUrl( downloadUrl ) ) );
}
QString NewstuffModel::provider() const
{
return d->m_provider;
}
void NewstuffModel::setTargetDirectory( const QString &targetDirectory )
{
if ( targetDirectory != d->m_targetDirectory ) {
QFileInfo targetDir( targetDirectory );
if ( !targetDir.exists() ) {
if ( !QDir::root().mkpath( targetDir.absoluteFilePath() ) ) {
qDebug() << "Failed to create directory " << targetDirectory << ", newstuff installation might fail.";
}
}
d->m_targetDirectory = targetDirectory;
emit targetDirectoryChanged();
}
}
QString NewstuffModel::targetDirectory() const
{
return d->m_targetDirectory;
}
void NewstuffModel::setRegistryFile( const QString &filename, IdTag idTag )
{
QString registryFile = filename;
if (registryFile.startsWith(QLatin1Char('~')) && registryFile.length() > 1) {
registryFile = QDir::homePath() + registryFile.mid( 1 );
}
if ( d->m_registryFile != registryFile ) {
d->m_registryFile = registryFile;
d->m_idTag = idTag;
emit registryFileChanged();
QFileInfo inputFile( registryFile );
if ( !inputFile.exists() ) {
QDir::root().mkpath( inputFile.absolutePath() );
d->m_registryDocument = QDomDocument( "khotnewstuff3" );
QDomProcessingInstruction header = d->m_registryDocument.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"utf-8\"" );
d->m_registryDocument.appendChild( header );
d->m_root = d->m_registryDocument.createElement( "hotnewstuffregistry" );
d->m_registryDocument.appendChild( d->m_root );
} else {
QFile input( registryFile );
if ( !input.open( QFile::ReadOnly ) ) {
mDebug() << "Cannot open newstuff registry " << registryFile;
return;
}
if ( !d->m_registryDocument.setContent( &input ) ) {
mDebug() << "Cannot parse newstuff registry " << registryFile;
return;
}
input.close();
d->m_root = d->m_registryDocument.documentElement();
}
d->updateModel();
}
}
QString NewstuffModel::registryFile() const
{
return d->m_registryFile;
}
void NewstuffModel::install( int index )
{
if ( index < 0 || index >= d->m_items.size() ) {
return;
}
NewstuffModelPrivate::Action action( index, NewstuffModelPrivate::Install );
{ // <-- do not remove, mutex locker scope
QMutexLocker locker( &d->m_mutex );
if ( d->m_actionQueue.contains( action ) ) {
return;
}
d->m_actionQueue << action;
}
d->processQueue();
}
void NewstuffModel::uninstall( int idx )
{
if ( idx < 0 || idx >= d->m_items.size() ) {
return;
}
if ( d->m_items[idx].m_registryNode.isNull() ) {
emit uninstallationFinished( idx );
}
NewstuffModelPrivate::Action action( idx, NewstuffModelPrivate::Uninstall );
{ // <-- do not remove, mutex locker scope
QMutexLocker locker( &d->m_mutex );
if ( d->m_actionQueue.contains( action ) ) {
return;
}
d->m_actionQueue << action;
}
d->processQueue();
}
void NewstuffModel::cancel( int index )
{
if ( !d->isTransitioning( index ) ) {
return;
}
{ // <-- do not remove, mutex locker scope
QMutexLocker locker( &d->m_mutex );
if ( d->m_currentAction.first == index ) {
if ( d->m_currentAction.second == NewstuffModelPrivate::Install ) {
if ( d->m_currentReply ) {
d->m_currentReply->abort();
d->m_currentReply->deleteLater();
- d->m_currentReply = 0;
+ d->m_currentReply = nullptr;
}
if ( d->m_unpackProcess ) {
d->m_unpackProcess->terminate();
d->m_unpackProcess->deleteLater();
- d->m_unpackProcess = 0;
+ d->m_unpackProcess = nullptr;
}
if ( d->m_currentFile ) {
d->m_currentFile->deleteLater();
- d->m_currentFile = 0;
+ d->m_currentFile = nullptr;
}
d->m_items[d->m_currentAction.first].m_downloadedSize = 0;
emit installationFailed( d->m_currentAction.first, tr( "Installation aborted by user." ) );
d->m_currentAction = NewstuffModelPrivate::Action( -1, NewstuffModelPrivate::Install );
} else {
// Shall we interrupt this?
}
} else {
if ( d->m_currentAction.second == NewstuffModelPrivate::Install ) {
NewstuffModelPrivate::Action install( index, NewstuffModelPrivate::Install );
d->m_actionQueue.removeAll( install );
emit installationFailed( index, tr( "Installation aborted by user." ) );
} else {
NewstuffModelPrivate::Action uninstall( index, NewstuffModelPrivate::Uninstall );
d->m_actionQueue.removeAll( uninstall );
emit uninstallationFinished( index ); // do we need failed here?
}
}
}
d->processQueue();
}
void NewstuffModel::updateProgress( qint64 bytesReceived, qint64 bytesTotal )
{
qreal const progress = qBound<qreal>( 0.0, 0.9 * bytesReceived / qreal( bytesTotal ), 1.0 );
emit installationProgressed( d->m_currentAction.first, progress );
NewstuffItem &item = d->m_items[d->m_currentAction.first];
item.m_payloadSize = bytesTotal;
if ( qreal(bytesReceived-item.m_downloadedSize)/bytesTotal >= 0.01 || progress >= 0.9 ) {
// Only consider download progress of 1% and more as a data change
item.m_downloadedSize = bytesReceived;
QModelIndex const affected = index( d->m_currentAction.first );
emit dataChanged( affected, affected );
}
}
void NewstuffModel::retrieveData()
{
if ( d->m_currentReply && d->m_currentReply->isReadable() ) {
// check if we are redirected
const QVariant redirectionAttribute = d->m_currentReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirectionAttribute.isNull() ) {
d->m_currentReply = d->m_networkAccessManager.get( QNetworkRequest( redirectionAttribute.toUrl() ) );
QObject::connect( d->m_currentReply, SIGNAL(readyRead()), this, SLOT(retrieveData()) );
QObject::connect( d->m_currentReply, SIGNAL(readChannelFinished()), this, SLOT(retrieveData()) );
QObject::connect( d->m_currentReply, SIGNAL(downloadProgress(qint64,qint64)),
this, SLOT(updateProgress(qint64,qint64)) );
} else {
d->m_currentFile->write( d->m_currentReply->readAll() );
if ( d->m_currentReply->isFinished() ) {
d->m_currentReply->deleteLater();
- d->m_currentReply = 0;
+ d->m_currentReply = nullptr;
d->m_currentFile->flush();
d->installMap();
}
}
}
}
void NewstuffModel::mapInstalled( int exitStatus )
{
if ( d->m_unpackProcess ) {
d->m_unpackProcess->deleteLater();
- d->m_unpackProcess = 0;
+ d->m_unpackProcess = nullptr;
}
if ( d->m_currentFile ) {
d->m_currentFile->deleteLater();
- d->m_currentFile = 0;
+ d->m_currentFile = nullptr;
}
emit installationProgressed( d->m_currentAction.first, 1.0 );
d->m_items[d->m_currentAction.first].m_downloadedSize = 0;
if ( exitStatus == 0 ) {
emit installationFinished( d->m_currentAction.first );
} else {
mDebug() << "Process exit status " << exitStatus << " indicates an error.";
emit installationFailed( d->m_currentAction.first , QString( "Unable to unpack file. Process exited with status code %1." ).arg( exitStatus ) );
}
QModelIndex const affected = index( d->m_currentAction.first );
{ // <-- do not remove, mutex locker scope
QMutexLocker locker( &d->m_mutex );
d->m_currentAction = NewstuffModelPrivate::Action( -1, NewstuffModelPrivate::Install );
}
emit dataChanged( affected, affected );
d->processQueue();
}
void NewstuffModel::mapUninstalled()
{
QModelIndex const affected = index( d->m_currentAction.first );
emit uninstallationFinished( d->m_currentAction.first );
{ // <-- do not remove, mutex locker scope
QMutexLocker locker( &d->m_mutex );
d->m_currentAction = NewstuffModelPrivate::Action( -1, NewstuffModelPrivate::Install );
}
emit dataChanged( affected, affected );
d->processQueue();
}
void NewstuffModel::contentsListed( int exitStatus )
{
if ( exitStatus == 0 ) {
QStringList const files = QString(d->m_unpackProcess->readAllStandardOutput()).split(QLatin1Char('\n'), QString::SkipEmptyParts);
d->updateRegistry(files);
QObject::disconnect( d->m_unpackProcess, SIGNAL(finished(int)),
this, SLOT(contentsListed(int)) );
QObject::connect( d->m_unpackProcess, SIGNAL(finished(int)),
this, SLOT(mapInstalled(int)) );
QStringList arguments = QStringList() << "-x" << "-z" << "-f" << d->m_currentFile->fileName();
d->m_unpackProcess->start( "tar", arguments );
} else {
mDebug() << "Process exit status " << exitStatus << " indicates an error.";
emit installationFailed( d->m_currentAction.first , QString( "Unable to list file contents. Process exited with status code %1." ).arg( exitStatus ) );
{ // <-- do not remove, mutex locker scope
QMutexLocker locker( &d->m_mutex );
d->m_currentAction = NewstuffModelPrivate::Action( -1, NewstuffModelPrivate::Install );
}
d->processQueue();
}
}
void NewstuffModelPrivate::updateRegistry(const QStringList &files)
{
emit m_parent->installationProgressed( m_currentAction.first, 0.92 );
if ( !m_registryFile.isEmpty() ) {
NewstuffItem &item = m_items[m_currentAction.first];
QDomNode node = item.m_registryNode;
NewstuffModelPrivate::NodeAction action = node.isNull() ? NewstuffModelPrivate::Append : NewstuffModelPrivate::Replace;
if ( node.isNull() ) {
node = m_root.appendChild( m_registryDocument.createElement( "stuff" ) );
}
node.toElement().setAttribute( "category", m_items[m_currentAction.first].m_category );
changeNode( node, m_registryDocument, "name", item.m_name, action );
changeNode( node, m_registryDocument, "providerid", m_provider, action );
changeNode( node, m_registryDocument, "author", item.m_author, action );
changeNode( node, m_registryDocument, "homepage", QString(), action );
changeNode( node, m_registryDocument, "licence", item.m_license, action );
changeNode( node, m_registryDocument, "version", item.m_version, action );
QString const itemId = m_idTag == NewstuffModel::PayloadTag ? item.m_payloadUrl.toString() : item.m_name;
changeNode( node, m_registryDocument, "id", itemId, action );
changeNode( node, m_registryDocument, "releasedate", item.m_releaseDate, action );
changeNode( node, m_registryDocument, "summary", item.m_summary, action );
changeNode( node, m_registryDocument, "changelog", QString(), action );
changeNode( node, m_registryDocument, "preview", item.m_previewUrl.toString(), action );
changeNode( node, m_registryDocument, "previewBig", item.m_previewUrl.toString(), action );
changeNode( node, m_registryDocument, "payload", item.m_payloadUrl.toString(), action );
changeNode( node, m_registryDocument, "status", "installed", action );
m_items[m_currentAction.first].m_registryNode = node;
bool hasChildren = true;
while ( hasChildren ) {
/** @todo FIXME: fileList does not contain all elements opposed to what docs say */
QDomNodeList fileList = node.toElement().elementsByTagName( "installedfile" );
hasChildren = !fileList.isEmpty();
for ( int i=0; i<fileList.count(); ++i ) {
node.removeChild( fileList.at( i ) );
}
}
for( const QString &file: files ) {
QDomNode fileNode = node.appendChild( m_registryDocument.createElement( "installedfile" ) );
fileNode.appendChild(m_registryDocument.createTextNode(m_targetDirectory + QLatin1Char('/') + file));
}
saveRegistry();
}
}
void NewstuffModelPrivate::processQueue()
{
if ( m_actionQueue.empty() || m_currentAction.first >= 0 ) {
return;
}
{ // <-- do not remove, mutex locker scope
QMutexLocker locker( &m_mutex );
m_currentAction = m_actionQueue.takeFirst();
}
if ( m_currentAction.second == Install ) {
if ( !m_currentFile ) {
QFileInfo const file = m_items.at( m_currentAction.first ).m_payloadUrl.path();
m_currentFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/marble-XXXXXX-") + file.fileName());
}
if ( m_currentFile->open() ) {
QUrl const payload = m_items.at( m_currentAction.first ).m_payloadUrl;
m_currentReply = m_networkAccessManager.get( QNetworkRequest( payload ) );
QObject::connect( m_currentReply, SIGNAL(readyRead()), m_parent, SLOT(retrieveData()) );
QObject::connect( m_currentReply, SIGNAL(readChannelFinished()), m_parent, SLOT(retrieveData()) );
QObject::connect( m_currentReply, SIGNAL(downloadProgress(qint64,qint64)),
m_parent, SLOT(updateProgress(qint64,qint64)) );
/** @todo: handle download errors */
} else {
mDebug() << "Failed to write to " << m_currentFile->fileName();
}
} else {
// Run in a separate thread to keep the ui responsive
QFutureWatcher<void>* watcher = new QFutureWatcher<void>( m_parent );
QObject::connect( watcher, SIGNAL(finished()), m_parent, SLOT(mapUninstalled()) );
QObject::connect( watcher, SIGNAL(finished()), watcher, SLOT(deleteLater()) );
QFuture<void> future = QtConcurrent::run( this, &NewstuffModelPrivate::uninstall, m_currentAction.first );
watcher->setFuture( future );
}
}
NewstuffItem NewstuffModelPrivate::importNode(const QDomNode &node)
{
NewstuffItem item;
item.m_category = node.attributes().namedItem(QStringLiteral("category")).toAttr().value();
readValue<QString>( node, "name", &item.m_name );
readValue<QString>( node, "author", &item.m_author );
readValue<QString>( node, "licence", &item.m_license );
readValue<QString>( node, "summary", &item.m_summary );
readValue<QString>( node, "version", &item.m_version );
readValue<QString>( node, "releasedate", &item.m_releaseDate );
readValue<QUrl>( node, "preview", &item.m_previewUrl );
readValue<QUrl>( node, "payload", &item.m_payloadUrl );
return item;
}
bool NewstuffModelPrivate::isTransitioning( int index ) const
{
if ( m_currentAction.first == index ) {
return true;
}
for( const Action &action: m_actionQueue ) {
if ( action.first == index ) {
return true;
}
}
return false;
}
}
#include "moc_NewstuffModel.cpp"
diff --git a/src/lib/marble/NewstuffModel.h b/src/lib/marble/NewstuffModel.h
index 469597832..373cb4dd5 100644
--- a/src/lib/marble/NewstuffModel.h
+++ b/src/lib/marble/NewstuffModel.h
@@ -1,137 +1,137 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_NEWSTUFFMODEL_H
#define MARBLE_NEWSTUFFMODEL_H
#include "marble_export.h"
#include <QAbstractListModel>
class QNetworkReply;
namespace Marble
{
class NewstuffModelPrivate;
class MARBLE_EXPORT NewstuffModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(QString provider READ provider WRITE setProvider NOTIFY providerChanged)
Q_PROPERTY(QString targetDirectory READ targetDirectory WRITE setTargetDirectory NOTIFY targetDirectoryChanged)
Q_PROPERTY(QString registryFile READ registryFile WRITE setRegistryFile NOTIFY registryFileChanged)
public:
enum NewstuffRoles {
Name = Qt::UserRole + 1,
Author,
License,
Summary,
Version,
ReleaseDate,
Preview,
Payload,
InstalledVersion,
InstalledReleaseDate,
InstalledFiles,
IsInstalled,
IsUpgradable,
Category,
IsTransitioning,
PayloadSize,
DownloadedSize
};
enum IdTag {
PayloadTag,
NameTag
};
/** Constructor */
- explicit NewstuffModel( QObject *parent = 0 );
+ explicit NewstuffModel( QObject *parent = nullptr );
/** Destructor */
~NewstuffModel() override;
/** Overload of QAbstractListModel */
int rowCount ( const QModelIndex &parent = QModelIndex() ) const override;
/** Overload of QAbstractListModel */
QVariant data ( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
/** Overload of QAbstractListModel */
QHash<int, QByteArray> roleNames() const override;
/** @todo FIXME https://bugreports.qt-project.org/browse/QTCOMPONENTS-1206 */
int count() const;
/**
* Add a newstuff provider
*/
void setProvider( const QString &downloadUrl );
QString provider() const;
void setTargetDirectory( const QString &targetDirectory );
QString targetDirectory() const;
void setRegistryFile( const QString &registryFile, IdTag idTag = PayloadTag );
QString registryFile() const;
public Q_SLOTS:
void install( int index );
void uninstall( int index );
void cancel( int index );
Q_SIGNALS:
void countChanged();
void providerChanged();
void targetDirectoryChanged();
void registryFileChanged();
void installationProgressed( int newstuffindex, qreal progress );
void installationFinished( int newstuffindex );
void installationFailed( int newstuffindex, const QString &error );
void uninstallationFinished( int newstuffindex );
private Q_SLOTS:
void updateProgress( qint64 bytesReceived, qint64 bytesTotal );
void retrieveData();
void mapInstalled( int exitStatus );
void mapUninstalled();
void contentsListed( int exitStatus );
private:
NewstuffModelPrivate* const d;
friend class NewstuffModelPrivate;
Q_PRIVATE_SLOT( d, void handleProviderData( QNetworkReply* ) )
};
}
#endif // MARBLE_NEWSTUFFMODEL_H
diff --git a/src/lib/marble/ParseRunnerPlugin.h b/src/lib/marble/ParseRunnerPlugin.h
index f105017b4..e868e40ca 100644
--- a/src/lib/marble/ParseRunnerPlugin.h
+++ b/src/lib/marble/ParseRunnerPlugin.h
@@ -1,70 +1,70 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_PARSERUNNERPLUGIN_H
#define MARBLE_PARSERUNNERPLUGIN_H
#include <QObject>
#include "PluginInterface.h"
namespace Marble
{
class ParsingRunner;
/**
* A plugin for Marble to execute a parsing task.
*/
class MARBLE_EXPORT ParseRunnerPlugin : public QObject, public PluginInterface
{
Q_OBJECT
public:
/** Constructor with optional parent object */
- explicit ParseRunnerPlugin( QObject* parent = 0 );
+ explicit ParseRunnerPlugin( QObject* parent = nullptr );
/** Destructor */
~ParseRunnerPlugin() override;
/**
* Returns a short description of the supported file format.
*
* Example: "Google Earth KML"
*/
virtual QString fileFormatDescription() const = 0;
/**
* Returns the file extensions associated with the file format.
*
* Example: "kml", "kmz"
*/
virtual QStringList fileExtensions() const = 0;
/** Plugin factory method to create a new runner instance.
* Method caller gets ownership of the returned object
*/
virtual ParsingRunner *newRunner() const = 0;
// Overridden methods with default implementations
QIcon icon() const override;
private:
class Private;
Private *const d;
};
}
Q_DECLARE_INTERFACE( Marble::ParseRunnerPlugin, "org.kde.Marble.ParseRunnerPlugin/1.01" )
#endif // MARBLE_PARSERUNNERPLUGIN_H
diff --git a/src/lib/marble/ParsingRunner.h b/src/lib/marble/ParsingRunner.h
index c375c3da3..e45ba8a40 100644
--- a/src/lib/marble/ParsingRunner.h
+++ b/src/lib/marble/ParsingRunner.h
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
#ifndef MARBLE_PARSINGRUNNER_H
#define MARBLE_PARSINGRUNNER_H
#include <QObject>
#include "marble_export.h"
#include "GeoDataDocument.h"
namespace Marble
{
class MARBLE_EXPORT ParsingRunner : public QObject
{
Q_OBJECT
public:
- explicit ParsingRunner( QObject *parent = 0 );
+ explicit ParsingRunner( QObject *parent = nullptr );
/**
* Start a file parsing.
* If implemented in a plugin, make sure to include Parsing in the
* plugin capabilities, otherwise MarbleRunnerManager will ignore the plugin
*/
virtual GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) = 0;
};
}
#endif
diff --git a/src/lib/marble/ParsingRunnerManager.cpp b/src/lib/marble/ParsingRunnerManager.cpp
index db7b828e4..128f44c37 100644
--- a/src/lib/marble/ParsingRunnerManager.cpp
+++ b/src/lib/marble/ParsingRunnerManager.cpp
@@ -1,139 +1,139 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#include "ParsingRunnerManager.h"
#include "MarbleDebug.h"
#include "GeoDataDocument.h"
#include "PluginManager.h"
#include "ParseRunnerPlugin.h"
#include "RunnerTask.h"
#include <QFileInfo>
#include <QList>
#include <QThreadPool>
#include <QTimer>
#include <QMutex>
namespace Marble
{
class MarbleModel;
class Q_DECL_HIDDEN ParsingRunnerManager::Private
{
public:
Private( ParsingRunnerManager *parent, const PluginManager *pluginManager );
~Private();
void cleanupParsingTask();
void addParsingResult(GeoDataDocument *document, const QString &error);
ParsingRunnerManager *const q;
const PluginManager *const m_pluginManager;
QMutex m_parsingTasksMutex;
int m_parsingTasks;
GeoDataDocument *m_fileResult;
};
ParsingRunnerManager::Private::Private( ParsingRunnerManager *parent, const PluginManager *pluginManager ) :
q( parent ),
m_pluginManager( pluginManager ),
m_parsingTasks(0),
- m_fileResult( 0 )
+ m_fileResult( nullptr )
{
qRegisterMetaType<GeoDataDocument*>( "GeoDataDocument*" );
}
ParsingRunnerManager::Private::~Private()
{
// nothing to do
}
void ParsingRunnerManager::Private::cleanupParsingTask()
{
QMutexLocker locker(&m_parsingTasksMutex);
m_parsingTasks = qMax(0, m_parsingTasks-1);
if (m_parsingTasks == 0) {
emit q->parsingFinished();
}
}
ParsingRunnerManager::ParsingRunnerManager( const PluginManager *pluginManager, QObject *parent ) :
QObject( parent ),
d( new Private( this, pluginManager ) )
{
if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
QThreadPool::globalInstance()->setMaxThreadCount( 4 );
}
}
ParsingRunnerManager::~ParsingRunnerManager()
{
delete d;
}
void ParsingRunnerManager::parseFile( const QString &fileName, DocumentRole role )
{
QList<const ParseRunnerPlugin*> plugins = d->m_pluginManager->parsingRunnerPlugins();
const QFileInfo fileInfo( fileName );
const QString suffix = fileInfo.suffix().toLower();
const QString completeSuffix = fileInfo.completeSuffix().toLower();
d->m_parsingTasks = 0;
for( const ParseRunnerPlugin *plugin: plugins ) {
QStringList const extensions = plugin->fileExtensions();
if ( extensions.isEmpty() || extensions.contains( suffix ) || extensions.contains( completeSuffix ) ) {
ParsingTask *task = new ParsingTask( plugin->newRunner(), this, fileName, role );
connect( task, SIGNAL(finished()), this, SLOT(cleanupParsingTask()) );
mDebug() << "parse task " << plugin->nameId() << " " << (quintptr)task;
++d->m_parsingTasks;
QThreadPool::globalInstance()->start( task );
}
}
if (d->m_parsingTasks == 0) {
emit parsingFinished();
}
}
GeoDataDocument *ParsingRunnerManager::openFile( const QString &fileName, DocumentRole role, int timeout )
{
d->m_fileResult = nullptr;
QEventLoop localEventLoop;
QTimer watchdog;
watchdog.setSingleShot(true);
connect( &watchdog, SIGNAL(timeout()),
&localEventLoop, SLOT(quit()));
connect(this, SIGNAL(parsingFinished()),
&localEventLoop, SLOT(quit()), Qt::QueuedConnection );
watchdog.start( timeout );
parseFile( fileName, role);
localEventLoop.exec();
return d->m_fileResult;
}
void ParsingRunnerManager::Private::addParsingResult(GeoDataDocument *document, const QString &error)
{
if ( document || !error.isEmpty() ) {
if (document) {
m_fileResult = document;
}
emit q->parsingFinished( document, error );
}
}
}
#include "moc_ParsingRunnerManager.cpp"
diff --git a/src/lib/marble/ParsingRunnerManager.h b/src/lib/marble/ParsingRunnerManager.h
index 4080696a1..08fbcaf06 100644
--- a/src/lib/marble/ParsingRunnerManager.h
+++ b/src/lib/marble/ParsingRunnerManager.h
@@ -1,73 +1,73 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLE_PARSINGRUNNERMANAGER_H
#define MARBLE_PARSINGRUNNERMANAGER_H
#include <QObject>
#include "marble_export.h"
#include "GeoDataDocument.h"
namespace Marble
{
class PluginManager;
class MARBLE_EXPORT ParsingRunnerManager : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
* @param pluginManager The plugin manager that gives access to RunnerPlugins
* @param parent Optional parent object
*/
- explicit ParsingRunnerManager( const PluginManager *pluginManager, QObject *parent = 0 );
+ explicit ParsingRunnerManager( const PluginManager *pluginManager, QObject *parent = nullptr );
~ParsingRunnerManager() override;
/**
* Parse the file using the runners for various formats
* @see parseFile is asynchronous with results returned using the
* @see parsingFinished signal.
* @see openFile is blocking.
* @see parsingFinished signal indicates all runners are finished.
*/
void parseFile( const QString &fileName, DocumentRole role = UserDocument );
GeoDataDocument *openFile( const QString &fileName, DocumentRole role = UserDocument, int timeout = 30000 );
Q_SIGNALS:
/**
* The file was parsed and potential error message
*/
void parsingFinished( GeoDataDocument *document, const QString &error = QString() );
/**
* Emitted whenever all runners are finished for the query
*/
void parsingFinished();
private:
Q_PRIVATE_SLOT( d, void cleanupParsingTask() )
Q_PRIVATE_SLOT( d, void addParsingResult( GeoDataDocument *document, const QString &error ) )
class Private;
friend class Private;
Private *const d;
};
}
#endif
diff --git a/src/lib/marble/PlacemarkEditHeader.h b/src/lib/marble/PlacemarkEditHeader.h
index cc3914f5d..508f367e7 100644
--- a/src/lib/marble/PlacemarkEditHeader.h
+++ b/src/lib/marble/PlacemarkEditHeader.h
@@ -1,77 +1,77 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Mikhail Ivchenko <ematirov@gmail.com>
#ifndef MARBLE_PLACEMARKEDITHEADER_H
#define MARBLE_PLACEMARKEDITHEADER_H
#include <QWidget>
#include "GeoDataCoordinates.h"
#include "MarbleGlobal.h"
#include "marble_export.h"
namespace Marble
{
class PlacemarkEditHeaderPrivate;
class MARBLE_EXPORT PlacemarkEditHeader : public QWidget
{
Q_OBJECT
public:
- explicit PlacemarkEditHeader(QWidget *parent = 0,
+ explicit PlacemarkEditHeader(QWidget *parent = nullptr,
GeoDataCoordinates::Notation notation = GeoDataCoordinates::DMS,
const QString& name = QString(),
const QString& iconLink = QString(),
const QString& id = QString(),
const QStringList &idFilter = QStringList() );
~PlacemarkEditHeader() override;
QString name() const;
QString iconLink() const;
qreal latitude() const;
qreal longitude() const;
GeoDataCoordinates::Notation notation() const;
bool positionVisible() const;
QString id() const;
QStringList idFilter() const;
bool isIdVisible() const;
bool isIdValid() const;
QString targetId() const;
QStringList targetIdList() const;
bool isTargetIdVisible() const;
public Q_SLOTS:
void setName(const QString &name);
void setIconLink(const QString &iconLink);
void setLatitude(qreal latitude);
void setLongitude(qreal longitude);
void setNotation(GeoDataCoordinates::Notation notation);
void setPositionVisible( bool visible );
QString setId( const QString &id );
void setIdFilter( const QStringList &filter );
void setIdVisible( bool visible );
void setTargetId( const QString &targetId );
void setTargetIdList( const QStringList &targetIdList );
void setTargetIdVisible( bool visible );
void selectAll();
void setReadOnly(bool state);
Q_SIGNALS:
void valueChanged();
private Q_SLOTS:
void updateValues();
private:
PlacemarkEditHeaderPrivate* const d;
Q_PRIVATE_SLOT(d, void loadIconFile())
friend class PlacemarkEditHeaderPrivate;
};
}
#endif
diff --git a/src/lib/marble/PlacemarkLayout.h b/src/lib/marble/PlacemarkLayout.h
index 05cc97b9c..b37ed8bf5 100644
--- a/src/lib/marble/PlacemarkLayout.h
+++ b/src/lib/marble/PlacemarkLayout.h
@@ -1,180 +1,180 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
//
// PlacemarkLayout is responsible for drawing the Placemarks on the map
//
#ifndef MARBLE_PLACEMARKLAYOUT_H
#define MARBLE_PLACEMARKLAYOUT_H
#include <QHash>
#include <QRect>
#include <QSet>
#include <QMap>
#include <QVector>
#include <QPointer>
#include "GeoDataPlacemark.h"
#include <GeoDataStyle.h>
class QAbstractItemModel;
class QItemSelectionModel;
class QPoint;
class QModelIndex;
namespace Marble
{
class GeoDataCoordinates;
class GeoPainter;
class MarbleClock;
class PlacemarkPainter;
class TileId;
class VisiblePlacemark;
class ViewportParams;
class StyleBuilder;
/**
* Layouts the place marks with a passed QPainter.
*/
class PlacemarkLayout : public QObject
{
Q_OBJECT
public:
/**
* Creates a new place mark layout.
*/
PlacemarkLayout( QAbstractItemModel *placemarkModel,
QItemSelectionModel *selectionModel,
MarbleClock *clock,
const StyleBuilder* styleBuilder,
- QObject *parent = 0 );
+ QObject *parent = nullptr );
/**
* Destroys the place mark painter.
*/
~PlacemarkLayout() override;
/**
* @reimp
*/
QVector<VisiblePlacemark *> generateLayout(const ViewportParams *viewport , int tileLevel);
/**
* Returns a list of model indexes that are at position @p pos.
*/
QVector<const GeoDataFeature *> whichPlacemarkAt( const QPoint &pos );
QString runtimeTrace() const;
QList<VisiblePlacemark *> visiblePlacemarks() const;
bool hasPlacemarkAt(const QPoint &pos);
public Q_SLOTS:
// earth
void setShowPlaces( bool show );
void setShowCities( bool show );
void setShowTerrain( bool show );
void setShowOtherPlaces( bool show );
// other planets
void setShowLandingSites( bool show );
void setShowCraters( bool show );
void setShowMaria( bool show );
void requestStyleReset();
void addPlacemarks( const QModelIndex& index, int first, int last );
void removePlacemarks( const QModelIndex& index, int first, int last );
void resetCacheData();
Q_SIGNALS:
void repaintNeeded();
private:
/**
* Returns a the maximum height of all possible labels.
* WARNING: This is a really slow method as it traverses all placemarks
* to check the labelheight.
* FIXME: Once a StyleManager that manages all styles has been implemented
* just traverse all existing styles.
*/
static int maxLabelHeight();
void styleReset();
void clearCache();
static QSet<TileId> visibleTiles(const ViewportParams &viewport, int tileLevel);
bool layoutPlacemark(const GeoDataPlacemark *placemark, const GeoDataCoordinates &coordinates, qreal x, qreal y, bool selected );
/**
* Returns the coordinates at which an icon should be drawn for the @p placemark.
* @p ok is set to true if the coordinates are valid and should be used for drawing,
* it is set to false otherwise.
*/
GeoDataCoordinates placemarkIconCoordinates( const GeoDataPlacemark *placemark ) const;
QRectF roomForLabel(const GeoDataStyle::ConstPtr &style,
const qreal x, const qreal y,
const QString &labelText , const VisiblePlacemark *placemark) const;
bool hasRoomForPixmap(const qreal y, const VisiblePlacemark *placemark) const;
bool placemarksOnScreenLimit( const QSize &screenSize ) const;
private:
Q_DISABLE_COPY( PlacemarkLayout )
QAbstractItemModel* m_placemarkModel;
QItemSelectionModel *const m_selectionModel;
MarbleClock *const m_clock;
QVector<VisiblePlacemark*> m_paintOrder;
QString m_runtimeTrace;
int m_labelArea;
QHash<const GeoDataPlacemark*, VisiblePlacemark*> m_visiblePlacemarks;
QVector< QVector< VisiblePlacemark* > > m_rowsection;
/// map providing the list of placemark belonging in TileId as key
QMap<TileId, QList<const GeoDataPlacemark*> > m_placemarkCache;
QSet<qint64> m_osmIds;
const QSet<GeoDataPlacemark::GeoDataVisualCategory> m_acceptedVisualCategories;
// earth
bool m_showPlaces;
bool m_showCities;
bool m_showTerrain;
bool m_showOtherPlaces;
// other planets
bool m_showLandingSites;
bool m_showCraters;
bool m_showMaria;
int m_maxLabelHeight;
bool m_styleResetRequested;
const StyleBuilder* m_styleBuilder;
// Referencing these properties by value
// instead of using a more fragile pointer
bool m_lastPlacemarkAvailable;
QRectF m_lastPlacemarkLabelRect;
QRectF m_lastPlacemarkSymbolRect;
};
}
#endif
diff --git a/src/lib/marble/PlacemarkPositionProviderPlugin.cpp b/src/lib/marble/PlacemarkPositionProviderPlugin.cpp
index 566c0b052..162befdf6 100644
--- a/src/lib/marble/PlacemarkPositionProviderPlugin.cpp
+++ b/src/lib/marble/PlacemarkPositionProviderPlugin.cpp
@@ -1,188 +1,188 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
// Copyright 2011,2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "PlacemarkPositionProviderPlugin.h"
#include "GeoDataPlacemark.h"
#include "MarbleClock.h"
#include "MarbleModel.h"
#include "MarbleDebug.h"
#include <QIcon>
using namespace Marble;
PlacemarkPositionProviderPlugin::PlacemarkPositionProviderPlugin( MarbleModel *marbleModel, QObject* parent )
: PositionProviderPlugin(parent),
m_marbleModel( marbleModel ),
- m_placemark( 0 ),
+ m_placemark( nullptr ),
m_speed( 0 ),
m_direction( 0.0 ),
m_status( PositionProviderStatusUnavailable ),
m_isInitialized( false )
{
m_accuracy.level = GeoDataAccuracy::Detailed;
}
QString PlacemarkPositionProviderPlugin::name() const
{
return tr( "Placemark position provider Plugin" );
}
QString PlacemarkPositionProviderPlugin::nameId() const
{
return QStringLiteral("Placemark");
}
QString PlacemarkPositionProviderPlugin::guiString() const
{
return tr( "Placemark" );
}
QString PlacemarkPositionProviderPlugin::version() const
{
return QStringLiteral("1.0");
}
QString PlacemarkPositionProviderPlugin::description() const
{
return tr( "Reports the position of a placemark" );
}
QString PlacemarkPositionProviderPlugin::copyrightYears() const
{
return QStringLiteral("2011, 2012");
}
QVector<PluginAuthor> PlacemarkPositionProviderPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Guillaume Martres"), QStringLiteral("smarter@ubuntu.com"))
<< PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"));
}
QIcon PlacemarkPositionProviderPlugin::icon() const
{
return QIcon();
}
void PlacemarkPositionProviderPlugin::initialize()
{
if ( m_marbleModel ) {
setPlacemark( m_marbleModel->trackedPlacemark() );
connect( m_marbleModel, SIGNAL(trackedPlacemarkChanged(const GeoDataPlacemark*)),
this, SLOT(setPlacemark(const GeoDataPlacemark*)) );
} else {
mDebug() << "PlacemarkPositionProviderPlugin: MarbleModel not set, cannot track placemarks.";
}
m_isInitialized = true;
}
bool PlacemarkPositionProviderPlugin::isInitialized() const
{
return m_isInitialized;
}
PositionProviderPlugin* PlacemarkPositionProviderPlugin::newInstance() const
{
return new PlacemarkPositionProviderPlugin( m_marbleModel );
}
PositionProviderStatus PlacemarkPositionProviderPlugin::status() const
{
return m_status;
}
GeoDataCoordinates PlacemarkPositionProviderPlugin::position() const
{
return m_coordinates;
}
GeoDataAccuracy PlacemarkPositionProviderPlugin::accuracy() const
{
return m_accuracy;
}
qreal PlacemarkPositionProviderPlugin::speed() const
{
return m_speed;
}
qreal PlacemarkPositionProviderPlugin::direction() const
{
return m_direction;
}
QDateTime PlacemarkPositionProviderPlugin::timestamp() const
{
return m_marbleModel->clockDateTime();
}
void PlacemarkPositionProviderPlugin::setPlacemark( const GeoDataPlacemark *placemark )
{
const GeoDataPlacemark *const oldPlacemark = m_placemark;
- if ( oldPlacemark != 0 ) {
+ if ( oldPlacemark != nullptr ) {
emit statusChanged( PositionProviderStatusUnavailable );
}
m_placemark = placemark;
m_timestamp = placemark ? m_marbleModel->clockDateTime() : QDateTime();
GeoDataCoordinates const newCoordinates = placemark ? placemark->coordinate( m_timestamp ) : GeoDataCoordinates();
if ( m_coordinates.isValid() && newCoordinates.isValid() ) {
m_direction = m_coordinates.bearing( newCoordinates, GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing );
}
m_coordinates = newCoordinates;
m_status = placemark ? PositionProviderStatusAvailable : PositionProviderStatusUnavailable;
m_speed = 0.0;
disconnect( m_marbleModel->clock(), SIGNAL(timeChanged()), this, SLOT(updatePosition()) );
if ( placemark ) {
connect( m_marbleModel->clock(), SIGNAL(timeChanged()), this, SLOT(updatePosition()) );
}
- if ( oldPlacemark != m_placemark && m_placemark != 0 ) {
+ if ( oldPlacemark != m_placemark && m_placemark != nullptr ) {
emit statusChanged( m_status );
}
if ( m_status == PositionProviderStatusAvailable ) {
emit positionChanged( m_coordinates, m_accuracy );
}
}
void PlacemarkPositionProviderPlugin::updatePosition()
{
- if ( m_placemark == 0 ) {
+ if ( m_placemark == nullptr ) {
return;
}
Q_ASSERT( m_marbleModel && "MarbleModel missing in PlacemarkPositionProviderPlugin" );
const GeoDataCoordinates previousCoordinates = m_coordinates;
m_coordinates = m_placemark->coordinate( m_marbleModel->clock()->dateTime() );
m_direction = previousCoordinates.bearing( m_coordinates, GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing );
if ( m_timestamp.isValid() ) {
const qreal averageAltitude = ( m_coordinates.altitude() + m_coordinates.altitude() ) / 2.0 + m_marbleModel->planetRadius();
const qreal distance = previousCoordinates.sphericalDistanceTo(m_coordinates) * averageAltitude;
const qreal seconds = m_timestamp.msecsTo( m_marbleModel->clockDateTime() ) / 1000.0;
m_speed = ( seconds > 0 ) ? ( distance / seconds ) : 0;
}
else {
m_speed = 0;
}
m_timestamp = m_marbleModel->clockDateTime();
emit positionChanged( m_coordinates, m_accuracy );
}
#include "moc_PlacemarkPositionProviderPlugin.cpp"
diff --git a/src/lib/marble/PlaybackAnimatedUpdateItem.cpp b/src/lib/marble/PlaybackAnimatedUpdateItem.cpp
index 778acc8b7..2e73c1132 100644
--- a/src/lib/marble/PlaybackAnimatedUpdateItem.cpp
+++ b/src/lib/marble/PlaybackAnimatedUpdateItem.cpp
@@ -1,255 +1,255 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "PlaybackAnimatedUpdateItem.h"
#include "GeoDataAnimatedUpdate.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataCreate.h"
#include "GeoDataUpdate.h"
#include "GeoDataDelete.h"
#include "GeoDataChange.h"
#include "GeoDataFolder.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataScreenOverlay.h"
#include <QString>
namespace Marble
{
PlaybackAnimatedUpdateItem::PlaybackAnimatedUpdateItem( GeoDataAnimatedUpdate* animatedUpdate )
{
m_animatedUpdate = animatedUpdate;
m_rootDocument = rootDocument( m_animatedUpdate );
m_playing = false;
}
const GeoDataAnimatedUpdate* PlaybackAnimatedUpdateItem::animatedUpdate() const
{
return m_animatedUpdate;
}
double PlaybackAnimatedUpdateItem::duration() const
{
return m_animatedUpdate->duration();
}
void PlaybackAnimatedUpdateItem::play()
{
if( m_playing ){
return;
}
m_playing = true;
if ( !m_rootDocument || !m_animatedUpdate->update() ) {
return;
}
// Apply updates of elements
if ( m_animatedUpdate->update()->change() ) {
QVector<GeoDataPlacemark*> placemarkList = m_animatedUpdate->update()->change()->placemarkList();
for( int i = 0; i < placemarkList.size(); i++ ){
GeoDataPlacemark* placemark = placemarkList.at( i );
QString targetId = placemark->targetId();
if( targetId.isEmpty() ) {
continue;
}
if( placemark->isBalloonVisible() ){
GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) {
emit balloonShown(placemark);
}
} else {
emit balloonHidden();
}
}
}
// Create new elements
if( m_animatedUpdate->update()->create() ){
for( int index = 0; index < m_animatedUpdate->update()->create()->size(); ++index ) {
GeoDataFeature* child = m_animatedUpdate->update()->create()->child( index );
if( child &&
(geodata_cast<GeoDataDocument>(child)||
geodata_cast<GeoDataFolder>(child))) {
GeoDataContainer *addContainer = static_cast<GeoDataContainer*>( child );
QString targetId = addContainer->targetId();
GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
if( feature &&
(geodata_cast<GeoDataDocument>(feature) ||
geodata_cast<GeoDataFolder>(feature))) {
GeoDataContainer* container = static_cast<GeoDataContainer*>( feature );
for( int i = 0; i < addContainer->size(); ++i ) {
emit added( container, addContainer->child( i ), -1 );
if (auto placemark = geodata_cast<GeoDataPlacemark>(addContainer->child(i)))
{
if( placemark->isBalloonVisible() ) {
emit balloonShown( placemark );
}
}
}
}
}
}
}
// Delete elements
if( m_animatedUpdate->update()->getDelete() ){
for( int index = 0; index < m_animatedUpdate->update()->getDelete()->size(); ++index ) {
GeoDataFeature* child = m_animatedUpdate->update()->getDelete()->child( index );
QString targetId = child->targetId();
if( targetId.isEmpty() ) {
continue;
}
GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
if (feature && canDelete(*feature)) {
m_deletedObjects.append( feature );
emit removed( feature );
if (auto placemark = geodata_cast<GeoDataPlacemark>(feature))
{
if( placemark->isBalloonVisible() ) {
emit balloonHidden();
}
}
}
}
}
}
GeoDataFeature* PlaybackAnimatedUpdateItem::findFeature(GeoDataFeature* feature, const QString& id ) const
{
if ( feature && feature->id() == id ){
return feature;
}
GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( feature );
if ( container ){
QVector<GeoDataFeature*>::Iterator end = container->end();
QVector<GeoDataFeature*>::Iterator iter = container->begin();
for( ; iter != end; ++iter ){
GeoDataFeature *foundFeature = findFeature( *iter, id );
if ( foundFeature ){
return foundFeature;
}
}
}
- return 0;
+ return nullptr;
}
GeoDataDocument *PlaybackAnimatedUpdateItem::rootDocument( GeoDataObject* object ) const
{
if( !object || !object->parent() ){
GeoDataDocument* document = dynamic_cast<GeoDataDocument*>( object );
return document;
} else {
return rootDocument( object->parent() );
}
- return 0;
+ return nullptr;
}
void PlaybackAnimatedUpdateItem::pause()
{
//do nothing
}
void PlaybackAnimatedUpdateItem::seek( double position )
{
Q_UNUSED( position );
play();
}
void PlaybackAnimatedUpdateItem::stop()
{
if( !m_playing ){
return;
}
m_playing = false;
if ( m_animatedUpdate->update()->change() ) {
QVector<GeoDataPlacemark*> placemarkList = m_animatedUpdate->update()->change()->placemarkList();
for( int i = 0; i < placemarkList.size(); i++ ){
GeoDataPlacemark* placemark = placemarkList.at( i );
QString targetId = placemark->targetId();
if( targetId.isEmpty() ) {
continue;
}
GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
if( placemark->isBalloonVisible() ){
if (geodata_cast<GeoDataPlacemark>(feature)) {
emit balloonHidden();
}
} else {
emit balloonShown( static_cast<GeoDataPlacemark*>( feature ) );
}
}
}
if( m_animatedUpdate->update()->create() ){
for( int index = 0; index < m_animatedUpdate->update()->create()->size(); ++index ) {
GeoDataFeature* feature = m_animatedUpdate->update()->create()->child( index );
if( feature &&
(geodata_cast<GeoDataDocument>(feature) ||
geodata_cast<GeoDataFolder>(feature))) {
GeoDataContainer* container = static_cast<GeoDataContainer*>( feature );
for( int i = 0; i < container->size(); ++i ) {
emit removed( container->child( i ) );
if (auto placemark = geodata_cast<GeoDataPlacemark>(container->child(i)))
{
if( placemark->isBalloonVisible() ) {
emit balloonHidden();
}
}
}
}
}
}
for( GeoDataFeature* feature: m_deletedObjects ) {
if( feature->targetId().isEmpty() ) {
continue;
}
GeoDataFeature* target = findFeature( m_rootDocument, feature->targetId() );
if ( target ) {
/** @todo Do we have to note the original row position and restore it? */
Q_ASSERT( dynamic_cast<GeoDataContainer*>( target ) );
emit added( static_cast<GeoDataContainer*>( target ), feature, -1 );
if (auto placemark = geodata_cast<GeoDataPlacemark>(feature))
{
if( placemark->isBalloonVisible() ) {
emit balloonShown( placemark );
}
}
} // else the root document was modified in an unfortunate way and we cannot restore it at this point
}
m_deletedObjects.clear();
}
bool PlaybackAnimatedUpdateItem::isApplied() const
{
return m_playing;
}
bool PlaybackAnimatedUpdateItem::canDelete(const GeoDataFeature &feature)
{
return geodata_cast<GeoDataDocument>(&feature) ||
geodata_cast<GeoDataFolder>(&feature) ||
geodata_cast<GeoDataGroundOverlay>(&feature) ||
geodata_cast<GeoDataPlacemark>(&feature) ||
geodata_cast<GeoDataScreenOverlay>(&feature) ||
geodata_cast<GeoDataPhotoOverlay>(&feature);
}
}
#include "moc_PlaybackAnimatedUpdateItem.cpp"
diff --git a/src/lib/marble/PlaybackFlyToItem.cpp b/src/lib/marble/PlaybackFlyToItem.cpp
index 052aad621..3184acb29 100644
--- a/src/lib/marble/PlaybackFlyToItem.cpp
+++ b/src/lib/marble/PlaybackFlyToItem.cpp
@@ -1,135 +1,135 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "PlaybackFlyToItem.h"
#include "GeoDataLookAt.h"
#include "GeoDataCamera.h"
#include "GeoDataFlyTo.h"
#include "Quaternion.h"
#include <QTimer>
namespace Marble
{
PlaybackFlyToItem::PlaybackFlyToItem( const GeoDataFlyTo* flyTo ):
m_flyTo( flyTo ),
- m_before( 0 ),
- m_next( 0 ),
+ m_before( nullptr ),
+ m_next( nullptr ),
m_isPlaying( false ),
m_isFirst( false )
{
//do nothing
}
const GeoDataFlyTo* PlaybackFlyToItem::flyTo() const
{
return m_flyTo;
}
double PlaybackFlyToItem::duration() const
{
// We use duration 0 for first FlyTo for instantly flight to it.
return m_isFirst ? 0 : m_flyTo->duration();
}
void PlaybackFlyToItem::play()
{
if( m_isPlaying ){
return;
} else {
m_isPlaying = true;
if ( !( m_start.isValid() ) ){
m_start = QDateTime::currentDateTime();
Q_ASSERT( m_start.isValid() );
} else {
m_start = m_start.addMSecs( m_pause.msecsTo( QDateTime::currentDateTime() ) );
}
playNext();
}
}
void PlaybackFlyToItem::playNext()
{
if( !m_start.isValid() ){
return;
}
double const progress = m_start.msecsTo( QDateTime::currentDateTime() ) / 1000.0;
Q_ASSERT( progress >= 0.0 );
double const t = progress / duration();
if( t <= 1 ){
if( m_isPlaying ){
center( t );
emit progressChanged( progress );
QTimer::singleShot( 5, this, SLOT(playNext()) );
}
} else {
center( 1.0 );
emit finished();
stop();
}
}
void PlaybackFlyToItem::pause()
{
m_isPlaying = false;
m_pause = QDateTime::currentDateTime();
}
void PlaybackFlyToItem::seek( double t )
{
m_start = QDateTime::currentDateTime().addMSecs( -t * duration() * 1000 );
m_pause = QDateTime::currentDateTime();
center( t );
}
void PlaybackFlyToItem::stop()
{
m_isPlaying = false;
m_start = QDateTime();
m_pause = QDateTime();
}
void PlaybackFlyToItem::center( double t )
{
Q_ASSERT( t >= 0.0 && t <= 1.0 );
Q_ASSERT( m_before );
if ( m_flyTo->flyToMode() == GeoDataFlyTo::Bounce || !m_before->m_before || !m_next ) {
GeoDataCoordinates const a = m_before->m_flyTo->view()->coordinates();
GeoDataCoordinates const b = m_flyTo->view()->coordinates();
emit centerOn( a.interpolate( b, t ) );
} else {
Q_ASSERT( m_flyTo->flyToMode() == GeoDataFlyTo::Smooth );
GeoDataCoordinates const a = m_before->m_before->m_flyTo->view()->coordinates();
GeoDataCoordinates const b = m_before->m_flyTo->view()->coordinates();
GeoDataCoordinates const c = m_flyTo->view()->coordinates();
GeoDataCoordinates const d = m_next->m_flyTo->view()->coordinates();
emit centerOn( b.interpolate( a, c, d, t ) );
}
}
void PlaybackFlyToItem::setBefore( PlaybackFlyToItem *before )
{
m_before = before;
}
void PlaybackFlyToItem::setNext( PlaybackFlyToItem *next )
{
m_next = next;
}
void PlaybackFlyToItem::setFirst(bool isFirst)
{
m_isFirst = isFirst;
}
}
#include "moc_PlaybackFlyToItem.cpp"
diff --git a/src/lib/marble/PluginAboutDialog.h b/src/lib/marble/PluginAboutDialog.h
index 4be9d82de..569241e10 100644
--- a/src/lib/marble/PluginAboutDialog.h
+++ b/src/lib/marble/PluginAboutDialog.h
@@ -1,108 +1,108 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_PLUGINABOUTDIALOG_H
#define MARBLE_PLUGINABOUTDIALOG_H
#include <QDialog>
#include <QList>
// Marble
#include "marble_export.h"
#include "PluginInterface.h"
namespace Marble
{
class PluginAboutDialogPrivate;
class MARBLE_EXPORT PluginAboutDialog : public QDialog
{
Q_OBJECT
public:
enum LicenseKey {
// License_Unknown = 0,
// License_GPL = 1,
// License_GPL_V2 = 1,
// License_LGPL = 2,
License_LGPL_V2 = 2
// License_BSD = 3,
// License_Artistic = 4,
// License_QPL = 5,
// License_QPL_V1_0 = 5,
// License_GPL_V3 = 6,
// License_LGPL_V3 = 7
};
- explicit PluginAboutDialog( QWidget *parent = 0 );
+ explicit PluginAboutDialog( QWidget *parent = nullptr );
~PluginAboutDialog() override;
/**
* Sets the name of the plugin.
*/
void setName( const QString& name );
/**
* Sets the version of the plugin;
*/
void setVersion( const QString& version );
/**
* Sets the icon to be displayed at the top of the dialog.
*/
void setIcon( const QIcon& icon );
/**
* Sets the text displayed in the "About" tab of the dialog.
*/
void setAboutText( const QString& about );
/**
* Sets the authors working on this plugin.
* @since 0.26.0
*/
void setAuthors(const QVector<PluginAuthor>& authors);
/**
* Sets the text displayed in the "Authors" tab of the dialog.
* @warning You would want to use setAuthors instead.
*/
void setAuthorsText( const QString& authors );
/**
* Sets the text displayed in the "Data" tab of the dialog.
* An null QString will result into no "Data" tab at all.
*/
void setDataText( const QString& data );
/**
* Sets the license for the "License Agreement" tab of the dialog.
*/
void setLicense( PluginAboutDialog::LicenseKey license );
/**
* Sets the text displayed in the "License Agreement" tab of the dialog.
* A null QString will result into the default LGPLv2 license agreement.
* If your plugin is not part of the official Marble distribution, please set it
* manually to the license agreement you prefer (even if it is LGPLv2).
* @warning You would want to use setLicense instead.
*/
void setLicenseAgreementText( const QString& license );
private:
Q_DISABLE_COPY( PluginAboutDialog )
PluginAboutDialogPrivate * const d;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/PluginItemDelegate.h b/src/lib/marble/PluginItemDelegate.h
index 664838b8d..1f1e2b675 100644
--- a/src/lib/marble/PluginItemDelegate.h
+++ b/src/lib/marble/PluginItemDelegate.h
@@ -1,90 +1,90 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_PLUGINITEMDELEGATE_H
#define MARBLE_PLUGINITEMDELEGATE_H
#include <QAbstractItemDelegate>
#include <QModelIndex>
#include <QIcon>
class QPainter;
class QRect;
class QStyleOptionButton;
class QStyleOptionViewItem;
namespace Marble
{
class PluginItemDelegate : public QAbstractItemDelegate
{
Q_OBJECT
public:
- explicit PluginItemDelegate( QAbstractItemView *view, QObject * parent = 0 );
+ explicit PluginItemDelegate( QAbstractItemView *view, QObject * parent = nullptr );
~PluginItemDelegate() override;
void paint( QPainter *painter,
const QStyleOptionViewItem& option,
const QModelIndex& index ) const override;
QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex & index ) const override;
void setAboutIcon( const QIcon& icon );
void setConfigIcon( const QIcon& icon );
Q_SIGNALS:
/**
* This signal is emitted if the user clicks on a "about"-button of an item in the view
* passed to the constructor.
*/
void aboutPluginClicked( const QModelIndex &index );
/**
* This signal is emitted if the user clicks on a "configure"-button of an item in the view
* passed to the constructor.
*/
void configPluginClicked( const QModelIndex &index );
protected:
bool editorEvent( QEvent *event,
QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index ) override;
private:
enum ButtonType {
About,
Configure
};
static QStyleOptionButton checkboxOption( const QStyleOptionViewItem& option,
const QModelIndex& index,
int position = 0,
Qt::AlignmentFlag alignment = Qt::AlignLeft );
QStyleOptionButton buttonOption( const QStyleOptionViewItem& option,
const QModelIndex& index,
PluginItemDelegate::ButtonType type,
int position = 0,
Qt::AlignmentFlag alignment = Qt::AlignLeft ) const;
static QSize nameSize( const QModelIndex& index );
static QRect alignRect( const QRect& object, const QRect& frame, int position, Qt::AlignmentFlag alignment );
QModelIndex m_configPressedIndex;
QModelIndex m_aboutPressedIndex;
QIcon m_aboutIcon;
QIcon m_configIcon;
};
}
#endif
diff --git a/src/lib/marble/PluginManager.h b/src/lib/marble/PluginManager.h
index 0b1f73bfe..348041eea 100644
--- a/src/lib/marble/PluginManager.h
+++ b/src/lib/marble/PluginManager.h
@@ -1,178 +1,178 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2008 Torsten Rahn <tackat@kde.org>
// Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
//
#ifndef MARBLE_PLUGINMANAGER_H
#define MARBLE_PLUGINMANAGER_H
#include <QObject>
#include <QList>
#include "marble_export.h"
namespace Marble
{
class RenderPlugin;
class PositionProviderPlugin;
class PluginManagerPrivate;
class SearchRunnerPlugin;
class ReverseGeocodingRunnerPlugin;
class RoutingRunnerPlugin;
class ParseRunnerPlugin;
/**
* @short The class that handles Marble's plugins.
*
* Ownership policy for plugins:
*
* On every invocation of createNetworkPlugins and
* createFloatItems the PluginManager creates new objects and transfers
* ownership to the calling site. In order to create
* the objects, the PluginManager internally has a list of the plugins
* which are owned by the PluginManager and destroyed by it.
*
*/
class MARBLE_EXPORT PluginManager : public QObject
{
Q_OBJECT
public:
- explicit PluginManager( QObject* parent = 0 );
+ explicit PluginManager( QObject* parent = nullptr );
~PluginManager() override;
/**
* @brief Returns all available RenderPlugins.
*
* Ownership of the items remains in PluginManager.
* In order to use the RenderPlugins, first create new instances using
* RenderPlugin::newInstance().
*/
QList<const RenderPlugin *> renderPlugins() const;
/**
* @brief Add a RenderPlugin manually to the list of known plugins. Normally you
* don't need to call this method since all plugins are loaded automatically.
* @param plugin The plugin to add. Ownership retains with the caller.
*/
void addRenderPlugin( const RenderPlugin *plugin );
/**
* @brief Returns all available PositionProviderPlugins.
*
* Ownership of the items remains in PluginManager.
* In order to use the PositionProviderPlugins, first create new instances using
* PositionProviderPlugin::newInstance().
*/
QList<const PositionProviderPlugin *> positionProviderPlugins() const;
/**
* @brief Add a PositionProviderPlugin manually to the list of known plugins. Normally you
* don't need to call this method since all plugins are loaded automatically.
* @param plugin The plugin to add. Ownership retains with the caller.
*/
void addPositionProviderPlugin( const PositionProviderPlugin *plugin );
/**
* Returns all search runner plugins.
* @note: Runner plugins are owned by the PluginManager, do not delete them.
*/
QList<const SearchRunnerPlugin *> searchRunnerPlugins() const;
/**
* @brief Add a SearchRunnerPlugin manually to the list of known plugins. Normally you
* don't need to call this method since all plugins are loaded automatically.
* @param plugin The plugin to add. Ownership retains with the caller.
*/
void addSearchRunnerPlugin( const SearchRunnerPlugin *plugin );
/**
* Returns all reverse geocoding runner plugins.
* @note: The runner plugins are owned by the PluginManager, do not delete them.
*/
QList<const ReverseGeocodingRunnerPlugin *> reverseGeocodingRunnerPlugins() const;
/**
* @brief Add a ReverseGeocodingRunnerPlugin manually to the list of known plugins. Normally you
* don't need to call this method since all plugins are loaded automatically.
* @param plugin The plugin to add. Ownership retains with the caller.
*/
void addReverseGeocodingRunnerPlugin( const ReverseGeocodingRunnerPlugin *plugin );
/**
* Returns all routing runner plugins.
* @note: The runner plugins are owned by the PluginManager, do not delete them.
*/
QList<RoutingRunnerPlugin *> routingRunnerPlugins() const;
/**
* @brief Add a RoutingRunnerPlugin manually to the list of known plugins. Normally you
* don't need to call this method since all plugins are loaded automatically.
* @param plugin The plugin to add. Ownership retains with the caller.
*/
void addRoutingRunnerPlugin( RoutingRunnerPlugin * plugin );
/**
* Returns all parse runner plugins.
* @note: The runner plugins are owned by the PluginManager, do not delete them.
*/
QList<const ParseRunnerPlugin *> parsingRunnerPlugins() const;
/**
* @brief Add a ParseRunnerPlugin manually to the list of known plugins. Normally you
* don't need to call this method since all plugins are loaded automatically.
* @param plugin The plugin to add. Ownership retains with the caller.
*/
void addParseRunnerPlugin( const ParseRunnerPlugin *plugin );
/**
* @brief blacklistPlugin Prevent that a plugin is loaded from the given filename
* @param filename The name of the file (excluding prefix and file extension) to blacklist. E.g.
* to ignore "libWikipedia.so" on Linux and "Wikipedia.dll" on Windows, pass "Wikipedia"
*/
static void blacklistPlugin(const QString &filename);
/**
* @brief whitelistPlugin Add a plugin to the whitelist of plugins. If the whitelist is not
* empty, only whitelisted plugins are loaded. If a plugin is both whitelisted and blacklisted,
* it will not be loaded
* @param filename The name of the file (excluding prefix and file extension) to whitelist. E.g.
* to ignore "libWikipedia.so" on Linux and "Wikipedia.dll" on Windows, pass "Wikipedia"
*/
static void whitelistPlugin(const QString &filename);
Q_SIGNALS:
void renderPluginsChanged();
void positionProviderPluginsChanged();
void searchRunnerPluginsChanged();
void reverseGeocodingRunnerPluginsChanged();
void routingRunnerPluginsChanged();
void parseRunnerPluginsChanged();
private:
Q_DISABLE_COPY( PluginManager )
#ifdef Q_OS_ANDROID
void installPluginsFromAssets() const;
#endif
PluginManagerPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/PopupItem.cpp b/src/lib/marble/PopupItem.cpp
index 68fad7ed4..d26679894 100644
--- a/src/lib/marble/PopupItem.cpp
+++ b/src/lib/marble/PopupItem.cpp
@@ -1,416 +1,416 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Torsten Rahn <tackat@kde.org>
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "PopupItem.h"
#include "MarbleWidget.h"
#ifdef MARBLE_NO_WEBKITWIDGETS
#include "NullMarbleWebView.h"
#else
#include <QWebView>
#include <QWebHistory>
#include "MarbleWebView.h"
#endif
#include <QPointer>
#include <QPrinter>
#include <QPrintDialog>
#include <QMouseEvent>
#include <QApplication>
#include <QDesktopServices>
#include <QPixmapCache>
#include <qdrawutil.h>
#include <QPainter>
namespace Marble
{
PopupItem::PopupItem( QObject* parent ) :
QObject( parent ),
BillboardGraphicsItem(),
m_widget( new QWidget ),
m_textColor( QColor(Qt::black) ),
m_backColor( QColor(Qt::white) ),
m_needMouseRelease(false)
{
setCacheMode( ItemCoordinateCache );
setVisible( false );
setSize( QSizeF( 300.0, 320.0 ) );
m_ui.setupUi( m_widget );
m_ui.goBackButton->setVisible( false );
connect( m_ui.goBackButton, SIGNAL(clicked()), this, SLOT(goBack()) );
#ifdef QT_NO_PRINTER
m_ui.printButton->setVisible( false );
#else
m_ui.printButton->setVisible( true );
connect( m_ui.printButton, SIGNAL(clicked()), this, SLOT(printContent()) );
#endif
m_widget->setAttribute( Qt::WA_NoSystemBackground, true );
QPalette palette = m_ui.webView->palette();
palette.setBrush(QPalette::Base, Qt::transparent);
m_ui.webView->setPalette(palette);
#ifndef MARBLE_NO_WEBKITWIDGETS
m_ui.webView->page()->setPalette(palette);
m_ui.webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
#endif
m_ui.webView->setAttribute(Qt::WA_OpaquePaintEvent, false);
m_ui.webView->setUrl( QUrl( "about:blank" ) );
connect( m_ui.webView, SIGNAL(titleChanged(QString)), m_ui.titleText, SLOT(setText(QString)) );
connect( m_ui.webView, SIGNAL(urlChanged(QUrl)), this, SLOT(updateBackButton()) );
connect( m_ui.hideButton, SIGNAL(clicked()), this, SIGNAL(hide()) );
#ifndef MARBLE_NO_WEBKITWIDGETS
// Update the popupitem on changes while loading the webpage
connect( m_ui.webView->page(), SIGNAL(repaintRequested(QRect)), this, SLOT(requestUpdate()) );
connect(m_ui.webView->page(), SIGNAL(linkClicked(QUrl)), this, SLOT(openUrl(QUrl)));
#endif
}
PopupItem::~PopupItem()
{
delete m_widget;
}
bool PopupItem::isPrintButtonVisible() const
{
return m_ui.printButton->isVisible();
}
void PopupItem::setPrintButtonVisible( bool display )
{
m_ui.printButton->setVisible( display );
}
void PopupItem::setUrl( const QUrl &url )
{
m_ui.webView->setUrl( url );
setVisible( true );
QPalette palette = m_ui.webView->palette();
palette.setBrush(QPalette::Base, Qt::transparent);
m_ui.webView->setPalette(palette);
#ifndef MARBLE_NO_WEBKITWIDGETS
m_ui.webView->page()->setPalette(palette);
#endif
m_ui.webView->setAttribute(Qt::WA_OpaquePaintEvent, false);
requestUpdate();
}
void PopupItem::setContent( const QString &html, const QUrl &baseUrl )
{
m_content = html;
m_baseUrl = baseUrl;
#ifndef MARBLE_NO_WEBKITWIDGETS
m_ui.webView->setHtml( html, baseUrl );
#endif
requestUpdate();
}
void PopupItem::setTextColor(const QColor &color)
{
- if(color.isValid() && m_ui.titleText != 0) {
+ if(color.isValid() && m_ui.titleText != nullptr) {
m_textColor = color;
QPalette palette(m_ui.titleText->palette());
palette.setColor(QPalette::WindowText, m_textColor);
m_ui.titleText->setPalette(palette);
requestUpdate();
}
}
void PopupItem::setBackgroundColor(const QColor &color)
{
if(color.isValid()) {
m_backColor = color;
QPixmapCache::remove( "marble/webpopup/webpopup2" );
QPixmapCache::remove( "marble/webpopup/arrow2_topleft" );
QPixmapCache::remove( "marble/webpopup/arrow2_bottomleft" );
QPixmapCache::remove( "marble/webpopup/arrow2_topright" );
QPixmapCache::remove( "marble/webpopup/arrow2_bottomright" );
requestUpdate();
}
}
void PopupItem::colorize( QImage &img, const QColor &col )
{
if (img.depth() <= 8) return;
int pixels = img.width()*img.height();
unsigned int *data = (unsigned int *) img.bits();
for (int i=0; i < pixels; ++i) {
int val = qGray(data[i]);
data[i] = qRgba(col.red()*val/255,col.green()*val/255, col.blue()*val/255, qAlpha(data[i]));
}
}
void PopupItem::paint( QPainter *painter )
{
QRect popupRect;
QPixmap image = pixmap("marble/webpopup/arrow2_vertical_topright");
if ( alignment() & Qt::AlignRight ) {
popupRect.setRect( image.width() - 13, -10,
size().width() - ( image.width() - 3 ),
size().height() );
qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ),
pixmap("marble/webpopup/webpopup2"));
if ( alignment() & Qt::AlignTop ) {
image = pixmap("marble/webpopup/arrow2_bottomleft");
painter->drawPixmap( 0, size().height() - image.height(), image );
} else if ( alignment() & Qt::AlignBottom ) {
image = pixmap("marble/webpopup/arrow2_topleft");
painter->drawPixmap( 0, 0, image );
} else { // for no horizontal align value and Qt::AlignVCenter
image = pixmap("marble/webpopup/arrow2_topleft");
painter->drawPixmap( 0, size().height() / 2, image );
}
m_widget->render( painter, QPoint( image.width() - 3, 0 ), QRegion() );
} else if ( alignment() & Qt::AlignLeft ) {
popupRect.setRect( -10, -10,
size().width() - ( image.width() - 3 ),
size().height() );
qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ),
pixmap("marble/webpopup/webpopup2"));
if ( alignment() & Qt::AlignTop ) {
image = pixmap("marble/webpopup/arrow2_bottomright");
painter->drawPixmap( size().width() - image.width(),
size().height() - image.height(), image );
} else if ( alignment() & Qt::AlignBottom ) {
image = pixmap("marble/webpopup/arrow2_topright");
painter->drawPixmap( size().width() - image.width(),
0, image );
} else { // for no horizontal align value and Qt::AlignVCenter
image = pixmap("marble/webpopup/arrow2_topright");
painter->drawPixmap( size().width() - image.width(),
size().height() / 2 - image.height() / 2 + 23, image );
}
m_widget->render( painter, QPoint( 5, 0 ), QRegion() );
} else if ( alignment() & Qt::AlignHCenter )
{
if ( alignment() & Qt::AlignTop )
{
image = pixmap("marble/webpopup/arrow2_vertical_bottomright");
popupRect.setRect( -10, -10, size().width(),
size().height() - image.height() + 3 );
qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ),
pixmap("marble/webpopup/webpopup2"));
painter->drawPixmap( size().width() / 2 - image.width(),
size().height() - image.height(), image );
m_widget->render( painter, QPoint( 0, 0 ), QRegion() );
} else if ( alignment() & Qt::AlignBottom ) {
image = pixmap("marble/webpopup/arrow2_vertical_topleft");
popupRect.setRect( -10, image.height() - 13, size().width(),
size().height() - image.height() + 3 );
qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ),
pixmap("marble/webpopup/webpopup2"));
painter->drawPixmap( size().width() / 2, 0, image );
m_widget->render( painter, QPoint( 5, image.height() - 7 ), QRegion() );
} else { // for no horizontal align value and Qt::AlignVCenter
popupRect.setRect( -10, -10, size().width(),
size().height());
qDrawBorderPixmap(painter, popupRect, QMargins( 20, 20, 20, 20 ),
pixmap("marble/webpopup/webpopup2"));
m_widget->render( painter, QPoint( 0, 0 ), QRegion() );
}
}
m_widget->setFixedSize( popupRect.width() - 20,
popupRect.height() - 20 );
}
bool PopupItem::eventFilter( QObject *object, QEvent *e )
{
MarbleWidget *widget = dynamic_cast<MarbleWidget*> ( object );
if ( !widget ) {
return BillboardGraphicsItem::eventFilter( object, e );
}
if ( e->type() == QEvent::ContextMenu) {
QApplication::sendEvent( m_ui.webView, e );
return BillboardGraphicsItem::eventFilter( object, e );
}
if ( e->type() == QEvent::KeyPress ) {
QApplication::sendEvent( m_ui.webView, e );
return BillboardGraphicsItem::eventFilter( object, e );
}
if ( e->type() == QEvent::MouseButtonDblClick
|| e->type() == QEvent::MouseMove
|| e->type() == QEvent::MouseButtonPress
|| e->type() == QEvent::MouseButtonRelease )
{
// Mouse events are forwarded to the underlying widget
QMouseEvent *event = static_cast<QMouseEvent*> ( e );
QPoint shiftedPos = event->pos();
QWidget* child = transform( shiftedPos );
bool const forcedMouseRelease = m_needMouseRelease && e->type() == QEvent::MouseButtonRelease;
if ( child || forcedMouseRelease ) {
if ( !m_needMouseRelease && e->type() == QEvent::MouseButtonPress ) {
m_needMouseRelease = true;
} else if ( forcedMouseRelease ) {
m_needMouseRelease = false;
}
if ( !child ) {
child = m_ui.webView;
}
QMouseEvent shiftedEvent = QMouseEvent( e->type(), shiftedPos,
event->globalPos(), event->button(), event->buttons(),
event->modifiers() );
if ( QApplication::sendEvent( child, &shiftedEvent ) ) {
widget->setCursor( child->cursor() );
emit repaintNeeded();
return true;
}
}
} else if ( e->type() == QEvent::Wheel ) {
// Wheel events are forwarded to the underlying widget
QWheelEvent *event = static_cast<QWheelEvent*> ( e );
QPoint shiftedPos = event->pos();
QWidget* child = transform( shiftedPos );
if ( child ) {
QWheelEvent shiftedEvent = QWheelEvent( shiftedPos,
event->globalPos(), event->delta(), event->buttons(),
event->modifiers() );
if ( QApplication::sendEvent( child, &shiftedEvent ) ) {
widget->setCursor( child->cursor() );
emit repaintNeeded();
return true;
}
}
}
return BillboardGraphicsItem::eventFilter( object, e );
}
QWidget* PopupItem::transform( QPoint &point ) const
{
/*
* Fixes for mouse events to trigger when the web popup
* is shifted in accordance with the horizontal alignment
*/
if ( alignment() & Qt::AlignRight )
point -= QPoint( 117, 0 );
else if ( alignment() & Qt::AlignLeft )
point -= QPoint( 5, 0 );
else if ( alignment() & Qt::AlignHCenter )
{
if ( alignment() & Qt::AlignTop )
{
point -= QPoint( 0, 0 );
} else if ( alignment() & Qt::AlignBottom )
{
point-= QPoint( 5, 57 );
} else {
point -= QPoint( 0, 0 );
}
}
const QVector<QPointF> widgetPositions = positions();
QVector<QPointF>::const_iterator it = widgetPositions.constBegin();
for( ; it != widgetPositions.constEnd(); ++it ) {
if ( QRectF( *it, size() ).contains( point ) ) {
point -= it->toPoint();
QWidget* child = m_widget->childAt( point );
if ( child ) {
point -= child->pos();
}
return child;
}
}
- return 0;
+ return nullptr;
}
void PopupItem::clearHistory()
{
m_content.clear();
m_ui.webView->setUrl( QUrl( "about:blank" ) );
#ifndef MARBLE_NO_WEBKITWIDGETS
m_ui.webView->history()->clear();
#endif
}
void PopupItem::requestUpdate()
{
update();
emit repaintNeeded();
}
void PopupItem::printContent() const
{
#ifndef QT_NO_PRINTER
#ifndef MARBLE_NO_WEBKITWIDGETS
QPrinter printer;
QPointer<QPrintDialog> dialog = new QPrintDialog(&printer);
if (dialog->exec() == QPrintDialog::Accepted) {
m_ui.webView->print(&printer);
}
delete dialog;
#endif
#endif
}
void PopupItem::updateBackButton()
{
#ifndef MARBLE_NO_WEBKITWIDGETS
bool const hasHistory = m_ui.webView->history()->count() > 1;
bool const previousIsHtml = !m_content.isEmpty() && m_ui.webView->history()->currentItemIndex() == 1;
bool const atStart = m_ui.webView->history()->currentItemIndex() <= 1;
bool const currentIsHtml = m_ui.webView->url() == QUrl( "about:blank" );
m_ui.goBackButton->setVisible( hasHistory && !currentIsHtml && ( previousIsHtml || !atStart ) );
#endif
}
void PopupItem::goBack()
{
#ifndef MARBLE_NO_WEBKITWIDGETS
if ( m_ui.webView->history()->currentItemIndex() == 1 && !m_content.isEmpty() ) {
m_ui.webView->setHtml( m_content, m_baseUrl );
} else {
m_ui.webView->back();
}
updateBackButton();
#endif
}
void PopupItem::openUrl(const QUrl &url)
{
QDesktopServices::openUrl(url);
}
QPixmap PopupItem::pixmap( const QString &imageId ) const
{
QPixmap result;
if ( !QPixmapCache::find( imageId, result ) ) {
QImage bottom = QImage(QLatin1String(":/") + imageId + QLatin1String("_shadow.png"));
QImage top = QImage(QLatin1String(":/") + imageId + QLatin1String(".png"));
colorize( top, m_backColor );
QPainter painter( &bottom );
painter.drawImage( QPoint(0,0), top );
result = QPixmap::fromImage( bottom );
QPixmapCache::insert( imageId, result );
}
return result;
}
}
#include "moc_PopupItem.cpp"
diff --git a/src/lib/marble/PopupItem.h b/src/lib/marble/PopupItem.h
index 51c77f440..bf2f20988 100644
--- a/src/lib/marble/PopupItem.h
+++ b/src/lib/marble/PopupItem.h
@@ -1,195 +1,195 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Torsten Rahn <tackat@kde.org>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef POPUPITEM_H
#define POPUPITEM_H
#include <QObject>
#include <QUrl>
#include "BillboardGraphicsItem.h"
#ifdef MARBLE_NO_WEBKITWIDGETS
#include "ui_NullWebPopupWidget.h"
#else
#include "ui_WebPopupWidget.h"
#endif
class QPainter;
namespace Marble
{
/**
* @brief The PopupItem Class
*
* This class represents graphics item for information bubble.
* Mostly used by @see MapInfoDialog.
*
* It has nice API for QWebView and methods for styling it.
*
*/
class PopupItem : public QObject, public BillboardGraphicsItem
{
Q_OBJECT
public:
- explicit PopupItem( QObject* parent = 0 );
+ explicit PopupItem( QObject* parent = nullptr );
~PopupItem() override;
/**
* @brief Print button visibility indicator
*
* There is a button in the header of item with print icon.
* It used to print the content of QWebView inside.
* This method indicates visibility of this button.
*
* @see setPrintButtonVisible();
*
* @return visibility of the print button
*/
bool isPrintButtonVisible() const;
/**
* @brief Sets visibility of the print button
*
* There is a button in the header of item with print icon.
* It used to print the content of QWebView inside
*
* This method sets visibility of this button.
*
* If @p display is `true`, button will be displayed,
* otherwise - button won't be displayed
*
* @param display visibility of the print button
*/
void setPrintButtonVisible(bool display);
/**
* @brief Set URL for web window
*
* There is a small web browser inside.
* It can show open websites.
*
* This method sets @p url for its window.
*
* @param url new url for web window
*/
void setUrl( const QUrl &url );
/**
* @brief Set content of the popup
*
* There is a small web browser inside. It can show custom HTML.
* This method sets custom @p html for its window
*
* @param html custom html for popup
*/
void setContent( const QString &html, const QUrl & baseUrl = QUrl() );
/**
* @brief Sets text color of the header
*
* Frame of the web browser is called bubble. Bubble has
* a header - part of the bubble at the top. Usually
* it contains the name of the page which can be set via
* TITLE html tag in HTML document loaded.
* This method sets text @p color of the header.
*
* @param color text color of the header
*/
void setTextColor( const QColor &color );
/**
* @brief Sets background color of the bubble
*
* Frame of the web browser is called bubble. This method
* sets background @p color of this bubble.
*
* @param color background color of the bubble
*/
void setBackgroundColor( const QColor &color );
bool eventFilter( QObject *, QEvent *e ) override;
void clearHistory();
private Q_SLOTS:
/**
* @brief Marks cache as dirty and tells the world its need for repainting.
*/
void requestUpdate();
/**
* @brief Print content of the web browser
*
* Popup Item has built-in mini-browser. This function
* executes print dialog for printing its content.
*
*/
void printContent() const;
/**
* @brief Updates Back Button (web surfing history)
*
* When you are browsing the site you may need to visit
* the page, you have visited before (Go Back).
*
* For this action Popup Item has a button Go Back placed
* in the left of the header.
*
* @note it's visible only if web surfing history is not clear or
* you are not on its first page.
*
* @see goBack();
*
*/
void updateBackButton();
/**
* @brief Go Back (web surfing history)
*
* This method moves you one step backwards in
* web surfing history.
*
*/
void goBack();
/**
* @brief Opens clicked URL in external browser.
* @param url URL to be opened in external browser
*/
void openUrl(const QUrl &url);
protected:
void paint( QPainter *painter ) override;
Q_SIGNALS:
void repaintNeeded();
void hide();
private:
QPixmap pixmap( const QString &imageid ) const;
static void colorize( QImage &img, const QColor &col );
QWidget* transform( QPoint &point ) const;
QWidget *m_widget;
Ui::WebPopupWidget m_ui;
QString m_content;
QColor m_textColor;
QColor m_backColor;
bool m_needMouseRelease;
QUrl m_baseUrl;
};
}
#endif
diff --git a/src/lib/marble/PositionProviderPlugin.h b/src/lib/marble/PositionProviderPlugin.h
index 597377d95..6144dc4b4 100644
--- a/src/lib/marble/PositionProviderPlugin.h
+++ b/src/lib/marble/PositionProviderPlugin.h
@@ -1,61 +1,61 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
//
#ifndef MARBLE_POSITIONPROVIDERPLUGIN_H
#define MARBLE_POSITIONPROVIDERPLUGIN_H
#include "PositionProviderPluginInterface.h"
#include "marble_export.h"
namespace Marble
{
class PositionProviderPluginPrivate;
/**
* @short The abstract class that provides position information.
*/
class MARBLE_EXPORT PositionProviderPlugin : public QObject, public PositionProviderPluginInterface
{
Q_OBJECT
public:
~PositionProviderPlugin() override;
/**
* @brief Returns the string that should appear in the user interface.
*
* Example: "GPS"
*/
virtual QString guiString() const = 0;
/**
* Create a new PositionProvider Plugin and return it.
* Has to be defined in concrete position provider plugin classes.
*/
virtual PositionProviderPlugin * newInstance() const = 0;
Q_SIGNALS:
void statusChanged( PositionProviderStatus status ) const;
void positionChanged( const GeoDataCoordinates& position,
const GeoDataAccuracy& accuracy ) const;
protected:
- PositionProviderPlugin(QObject* parent=0);
+ PositionProviderPlugin(QObject* parent=nullptr);
private:
Q_DISABLE_COPY( PositionProviderPlugin )
PositionProviderPluginPrivate *d;
};
}
#endif
diff --git a/src/lib/marble/PositionTracking.cpp b/src/lib/marble/PositionTracking.cpp
index 75dbba859..f8e35bafb 100644
--- a/src/lib/marble/PositionTracking.cpp
+++ b/src/lib/marble/PositionTracking.cpp
@@ -1,398 +1,398 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Andrew Manson <g.real.ate@gmail.com>
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
// Copyright 2010 Thibaut Gridel <tgridel@free.fr>
//
#include "PositionTracking.h"
#include "GeoDataDocument.h"
#include "GeoDataMultiTrack.h"
#include "GeoDataPlacemark.h"
#include "GeoDataParser.h"
#include "GeoDataStyle.h"
#include "GeoDataLineStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataTrack.h"
#include "GeoDataTreeModel.h"
#include "GeoDataLineString.h"
#include "GeoDataAccuracy.h"
#include "GeoDataDocumentWriter.h"
#include "KmlElementDictionary.h"
#include "FileManager.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "PositionProviderPlugin.h"
#include <QFile>
namespace Marble
{
class PositionTrackingPrivate
{
public:
PositionTrackingPrivate( GeoDataTreeModel *model, PositionTracking *parent ) :
q( parent ),
m_treeModel( model ),
m_currentPositionPlacemark( new GeoDataPlacemark ),
m_currentTrackPlacemark( new GeoDataPlacemark ),
m_trackSegments( new GeoDataMultiTrack ),
m_document(),
- m_currentTrack( 0 ),
- m_positionProvider( 0 ),
+ m_currentTrack( nullptr ),
+ m_positionProvider( nullptr ),
m_length( 0.0 )
{
}
void updatePosition();
void updateStatus();
static QString statusFile();
PositionTracking *const q;
GeoDataTreeModel *const m_treeModel;
GeoDataPlacemark *const m_currentPositionPlacemark;
GeoDataPlacemark *m_currentTrackPlacemark;
GeoDataMultiTrack *m_trackSegments;
GeoDataDocument m_document;
GeoDataCoordinates m_gpsPreviousPosition;
GeoDataTrack *m_currentTrack;
PositionProviderPlugin* m_positionProvider;
qreal m_length;
};
void PositionTrackingPrivate::updatePosition()
{
- Q_ASSERT( m_positionProvider != 0 );
+ Q_ASSERT( m_positionProvider != nullptr );
const GeoDataAccuracy accuracy = m_positionProvider->accuracy();
const GeoDataCoordinates position = m_positionProvider->position();
const QDateTime timestamp = m_positionProvider->timestamp();
if ( m_positionProvider->status() == PositionProviderStatusAvailable ) {
if ( accuracy.horizontal < 250 ) {
if ( m_currentTrack->size() ) {
m_length += m_currentTrack->coordinatesAt(m_currentTrack->size() - 1).sphericalDistanceTo(position);
}
m_currentTrack->addPoint( timestamp, position );
}
//if the position has moved then update the current position
if ( m_gpsPreviousPosition != position ) {
m_currentPositionPlacemark->setCoordinate( position );
qreal speed = m_positionProvider->speed();
emit q->gpsLocation( position, speed );
}
}
}
void PositionTrackingPrivate::updateStatus()
{
- Q_ASSERT( m_positionProvider != 0 );
+ Q_ASSERT( m_positionProvider != nullptr );
const PositionProviderStatus status = m_positionProvider->status();
if (status == PositionProviderStatusAvailable) {
m_currentTrack = new GeoDataTrack;
m_treeModel->removeFeature( m_currentTrackPlacemark );
m_trackSegments->append( m_currentTrack );
m_treeModel->addFeature( &m_document, m_currentTrackPlacemark );
}
emit q->statusChanged( status );
}
QString PositionTrackingPrivate::statusFile()
{
QString const subdir = "tracking";
QDir dir( MarbleDirs::localPath() );
if ( !dir.exists( subdir ) ) {
if ( !dir.mkdir( subdir ) ) {
mDebug() << "Unable to create dir " << dir.absoluteFilePath( subdir );
return dir.absolutePath();
}
}
if ( !dir.cd( subdir ) ) {
mDebug() << "Cannot change into " << dir.absoluteFilePath( subdir );
}
return dir.absoluteFilePath( "track.kml" );
}
PositionTracking::PositionTracking( GeoDataTreeModel *model )
: QObject( model ),
d( new PositionTrackingPrivate( model, this ) )
{
d->m_document.setDocumentRole( TrackingDocument );
d->m_document.setName(QStringLiteral("Position Tracking"));
// First point is current position
d->m_currentPositionPlacemark->setName(QStringLiteral("Current Position"));
d->m_currentPositionPlacemark->setVisible(false);
d->m_document.append( d->m_currentPositionPlacemark );
// Second point is position track
d->m_currentTrack = new GeoDataTrack;
d->m_trackSegments->append(d->m_currentTrack);
d->m_currentTrackPlacemark->setGeometry(d->m_trackSegments);
d->m_currentTrackPlacemark->setName(QStringLiteral("Current Track"));
GeoDataStyle::Ptr style(new GeoDataStyle);
GeoDataLineStyle lineStyle;
QColor transparentRed = Oxygen::brickRed4;
transparentRed.setAlpha( 200 );
lineStyle.setColor( transparentRed );
lineStyle.setWidth( 4 );
style->setLineStyle(lineStyle);
style->setId(QStringLiteral("track"));
GeoDataStyleMap styleMap;
styleMap.setId(QStringLiteral("map-track"));
styleMap.insert(QStringLiteral("normal"), QLatin1Char('#') + style->id());
d->m_document.addStyleMap(styleMap);
d->m_document.addStyle(style);
d->m_document.append( d->m_currentTrackPlacemark );
d->m_currentTrackPlacemark->setStyleUrl(QLatin1Char('#') + styleMap.id());
d->m_treeModel->addDocument( &d->m_document );
}
PositionTracking::~PositionTracking()
{
d->m_treeModel->removeDocument( &d->m_document );
delete d;
}
void PositionTracking::setPositionProviderPlugin( PositionProviderPlugin* plugin )
{
const PositionProviderStatus oldStatus = status();
if ( d->m_positionProvider ) {
delete d->m_positionProvider;
}
d->m_positionProvider = plugin;
if ( d->m_positionProvider ) {
d->m_positionProvider->setParent( this );
mDebug() << "Initializing position provider:" << d->m_positionProvider->name();
connect( d->m_positionProvider, SIGNAL(statusChanged(PositionProviderStatus)),
this, SLOT(updateStatus()) );
connect( d->m_positionProvider, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)),
this, SLOT(updatePosition()) );
d->m_positionProvider->initialize();
}
emit positionProviderPluginChanged( plugin );
if ( oldStatus != status() ) {
emit statusChanged( status() );
}
if ( status() == PositionProviderStatusAvailable ) {
emit gpsLocation( d->m_positionProvider->position(), d->m_positionProvider->speed() );
}
}
PositionProviderPlugin* PositionTracking::positionProviderPlugin()
{
return d->m_positionProvider;
}
QString PositionTracking::error() const
{
return d->m_positionProvider ? d->m_positionProvider->error() : QString();
}
//get speed from provider
qreal PositionTracking::speed() const
{
return d->m_positionProvider ? d->m_positionProvider->speed() : 0 ;
}
//get direction from provider
qreal PositionTracking::direction() const
{
return d->m_positionProvider ? d->m_positionProvider->direction() : 0 ;
}
QDateTime PositionTracking::timestamp() const
{
return d->m_positionProvider ? d->m_positionProvider->timestamp() : QDateTime();
}
bool PositionTracking::trackVisible() const
{
return d->m_currentTrackPlacemark->isVisible();
}
void PositionTracking::setTrackVisible( bool visible )
{
d->m_currentTrackPlacemark->setVisible( visible );
d->m_treeModel->updateFeature( d->m_currentTrackPlacemark );
}
bool PositionTracking::saveTrack( const QString& fileName )
{
if ( fileName.isEmpty() ) {
return false;
}
GeoDataDocument *document = new GeoDataDocument;
QFileInfo fileInfo( fileName );
QString name = fileInfo.baseName();
document->setName( name );
for( const GeoDataStyle::Ptr &style: d->m_document.styles() ) {
document->addStyle( style );
}
for( const GeoDataStyleMap &map: d->m_document.styleMaps() ) {
document->addStyleMap( map );
}
GeoDataPlacemark *track = new GeoDataPlacemark( *d->m_currentTrackPlacemark );
track->setName(QLatin1String("Track ") + name);
document->append( track );
bool const result = GeoDataDocumentWriter::write(fileName, *document);
delete document;
return result;
}
void PositionTracking::clearTrack()
{
d->m_treeModel->removeFeature( d->m_currentTrackPlacemark );
d->m_currentTrack = new GeoDataTrack;
d->m_trackSegments->clear();
d->m_trackSegments->append( d->m_currentTrack );
d->m_treeModel->addFeature( &d->m_document, d->m_currentTrackPlacemark );
d->m_length = 0.0;
}
void PositionTracking::readSettings()
{
QFile file( d->statusFile() );
if ( !file.open( QIODevice::ReadOnly ) ) {
mDebug() << "Can not read track from " << file.fileName();
return;
}
GeoDataParser parser( GeoData_KML );
if ( !parser.read( &file ) ) {
mDebug() << "Could not parse tracking file: " << parser.errorString();
return;
}
GeoDataDocument *doc = dynamic_cast<GeoDataDocument*>( parser.releaseDocument() );
file.close();
if( !doc ){
mDebug() << "tracking document not available";
return;
}
GeoDataPlacemark *track = dynamic_cast<GeoDataPlacemark*>( doc->child( 0 ) );
if( !track ) {
mDebug() << "tracking document doesn't have a placemark";
delete doc;
return;
}
d->m_trackSegments = dynamic_cast<GeoDataMultiTrack*>( track->geometry() );
if( !d->m_trackSegments ) {
mDebug() << "tracking document doesn't have a multitrack";
delete doc;
return;
}
if( d->m_trackSegments->size() < 1 ) {
mDebug() << "tracking document doesn't have a track";
delete doc;
return;
}
d->m_currentTrack = dynamic_cast<GeoDataTrack*>( d->m_trackSegments->child( d->m_trackSegments->size() - 1 ) );
if( !d->m_currentTrack ) {
mDebug() << "tracking document doesn't have a last track";
delete doc;
return;
}
doc->remove( 0 );
delete doc;
d->m_treeModel->removeDocument( &d->m_document );
d->m_document.remove( 1 );
delete d->m_currentTrackPlacemark;
d->m_currentTrackPlacemark = track;
d->m_currentTrackPlacemark->setName(QStringLiteral("Current Track"));
d->m_document.append( d->m_currentTrackPlacemark );
d->m_currentTrackPlacemark->setStyleUrl( d->m_currentTrackPlacemark->styleUrl() );
d->m_treeModel->addDocument( &d->m_document );
d->m_length = 0.0;
for ( int i = 0; i < d->m_trackSegments->size(); ++i ) {
d->m_length += d->m_trackSegments->at( i ).lineString()->length( 1 );
}
}
void PositionTracking::writeSettings()
{
saveTrack( d->statusFile() );
}
bool PositionTracking::isTrackEmpty() const
{
if ( d->m_trackSegments->size() < 1 ) {
return true;
}
if ( d->m_trackSegments->size() == 1 ) {
return ( d->m_currentTrack->size() == 0 );
}
return false;
}
qreal PositionTracking::length( qreal planetRadius ) const
{
return d->m_length * planetRadius;
}
GeoDataAccuracy PositionTracking::accuracy() const
{
return d->m_positionProvider ? d->m_positionProvider->accuracy() : GeoDataAccuracy();
}
GeoDataCoordinates PositionTracking::currentLocation() const
{
return d->m_positionProvider ? d->m_positionProvider->position() : GeoDataCoordinates();
}
PositionProviderStatus PositionTracking::status() const
{
return d->m_positionProvider ? d->m_positionProvider->status() : PositionProviderStatusUnavailable;
}
}
#include "moc_PositionTracking.cpp"
diff --git a/src/lib/marble/PrintOptionsWidget.h b/src/lib/marble/PrintOptionsWidget.h
index 9ceba3767..71b1f25ff 100644
--- a/src/lib/marble/PrintOptionsWidget.h
+++ b/src/lib/marble/PrintOptionsWidget.h
@@ -1,63 +1,63 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_PRINTOPTIONSWIDGET_H
#define MARBLE_PRINTOPTIONSWIDGET_H
#include "marble_export.h"
#include <QWidget>
#include "ui_PrintOptions.h"
namespace Marble
{
class MARBLE_EXPORT PrintOptionsWidget: public QWidget, private Ui::PrintOptions
{
Q_OBJECT
public:
- explicit PrintOptionsWidget( QWidget * parent = 0, Qt::WindowFlags f = 0 );
+ explicit PrintOptionsWidget( QWidget * parent = nullptr, Qt::WindowFlags f = nullptr );
bool printMap() const;
void setPrintMap( bool print );
bool printBackground() const;
void setPrintBackground( bool print );
bool printLegend() const;
void setPrintLegend( bool print );
bool printRouteSummary() const;
void setPrintRouteSummary( bool print );
bool printDrivingInstructions() const;
void setPrintDrivingInstructions( bool print );
bool printDrivingInstructionsAdvice() const;
void setPrintDrivingInstructionsAdvice( bool print );
void setBackgroundControlsEnabled( bool enabled );
void setRouteControlsEnabled( bool enabled );
void setLegendControlsEnabled( bool enabled );
};
} // namespace Marble
#endif // MARBLE_PRINTOPTIONSWIDGET_H
diff --git a/src/lib/marble/QtMarbleConfigDialog.cpp b/src/lib/marble/QtMarbleConfigDialog.cpp
index 3b40f9c45..d1d100cfe 100644
--- a/src/lib/marble/QtMarbleConfigDialog.cpp
+++ b/src/lib/marble/QtMarbleConfigDialog.cpp
@@ -1,658 +1,658 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
// Own
#include "QtMarbleConfigDialog.h"
#include "ui_MarbleCacheSettingsWidget.h"
#include "ui_MarbleViewSettingsWidget.h"
#include "ui_MarbleNavigationSettingsWidget.h"
#include "ui_MarbleTimeSettingsWidget.h"
#include "ui_MarbleCloudSyncSettingsWidget.h"
// Qt
#include <QSettings>
#include <QNetworkProxy>
#include <QApplication>
#include <QDialogButtonBox>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QWidget>
#include <QDateTime>
#include <QTimer>
// Marble
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarblePluginSettingsWidget.h"
#include "MarbleLocale.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "RenderPlugin.h"
#include "RenderPluginModel.h"
#include "MarbleClock.h"
#include "routing/RoutingProfilesWidget.h"
#include "BookmarkSyncManager.h"
#include "CloudSyncManager.h"
namespace Marble
{
class QtMarbleConfigDialogPrivate
{
public:
QtMarbleConfigDialogPrivate( MarbleWidget *marbleWidget, CloudSyncManager *cloudSyncManager )
: ui_viewSettings(),
ui_navigationSettings(),
ui_timeSettings(),
ui_cacheSettings(),
- w_pluginSettings( 0 ),
- m_cloudSyncStatusLabel( 0 ),
+ w_pluginSettings( nullptr ),
+ m_cloudSyncStatusLabel( nullptr ),
m_marbleWidget( marbleWidget ),
- m_syncManager( cloudSyncManager ? cloudSyncManager->bookmarkSyncManager() : 0 ),
+ m_syncManager( cloudSyncManager ? cloudSyncManager->bookmarkSyncManager() : nullptr ),
m_cloudSyncManager(cloudSyncManager),
m_pluginModel()
{
}
Ui::MarbleViewSettingsWidget ui_viewSettings;
Ui::MarbleNavigationSettingsWidget ui_navigationSettings;
Ui::MarbleTimeSettingsWidget ui_timeSettings;
Ui::MarbleCacheSettingsWidget ui_cacheSettings;
Ui::MarbleCloudSyncSettingsWidget ui_cloudSyncSettings;
MarblePluginSettingsWidget *w_pluginSettings;
QSettings m_settings;
QLabel *m_cloudSyncStatusLabel;
MarbleWidget *const m_marbleWidget;
BookmarkSyncManager *const m_syncManager;
CloudSyncManager *const m_cloudSyncManager;
RenderPluginModel m_pluginModel;
QHash< int, int > m_timezone;
};
QtMarbleConfigDialog::QtMarbleConfigDialog(MarbleWidget *marbleWidget, CloudSyncManager *cloudSyncManager,
QWidget *parent )
: QDialog( parent ),
d( new QtMarbleConfigDialogPrivate( marbleWidget, cloudSyncManager ) )
{
QTabWidget *tabWidget = new QTabWidget( this );
QDialogButtonBox *buttons =
new QDialogButtonBox( QDialogButtonBox::Ok
| QDialogButtonBox::Apply
| QDialogButtonBox::Cancel,
Qt::Horizontal,
this );
// Connect the signals of the ButtonBox
// to the corresponding slots of the dialog.
connect( buttons, SIGNAL(accepted()), this, SLOT(accept()) ); // Ok
connect( buttons, SIGNAL(rejected()), this, SLOT(reject()) ); // Cancel
connect( buttons->button( QDialogButtonBox::Apply ),SIGNAL(clicked()),
this, SLOT(writeSettings()) ); // Apply
// If the dialog is accepted. Save the settings.
connect( this, SIGNAL(accepted()), this, SLOT(writeSettings()) );
// view page
QWidget *w_viewSettings = new QWidget( this );
d->ui_viewSettings.setupUi( w_viewSettings );
tabWidget->addTab( w_viewSettings, tr( "View" ) );
d->ui_viewSettings.kcfg_labelLocalization->hide();
d->ui_viewSettings.label_labelLocalization->hide();
// navigation page
QWidget *w_navigationSettings = new QWidget( this );
d->ui_navigationSettings.setupUi( w_navigationSettings );
tabWidget->addTab( w_navigationSettings, tr( "Navigation" ) );
d->ui_navigationSettings.kcfg_dragLocation->hide();
d->ui_navigationSettings.label_dragLocation->hide();
// cache page
QWidget *w_cacheSettings = new QWidget( this );
d->ui_cacheSettings.setupUi( w_cacheSettings );
tabWidget->addTab( w_cacheSettings, tr( "Cache and Proxy" ) );
// Forwarding clear button signals
connect( d->ui_cacheSettings.button_clearVolatileCache, SIGNAL(clicked()), SIGNAL(clearVolatileCacheClicked()) );
connect( d->ui_cacheSettings.button_clearPersistentCache, SIGNAL(clicked()), SIGNAL(clearPersistentCacheClicked()) );
// time page
QWidget *w_timeSettings = new QWidget( this );
d->ui_timeSettings.setupUi( w_timeSettings );
tabWidget->addTab( w_timeSettings, tr( "Date and Time" ) );
// routing page
QWidget *w_routingSettings = new RoutingProfilesWidget( marbleWidget->model() );
tabWidget->addTab( w_routingSettings, tr( "Routing" ) );
// plugin page
d->m_pluginModel.setRenderPlugins( d->m_marbleWidget->renderPlugins() );
d->w_pluginSettings = new MarblePluginSettingsWidget( this );
d->w_pluginSettings->setModel( &d->m_pluginModel );
d->w_pluginSettings->setObjectName( "plugin_page" );
tabWidget->addTab( d->w_pluginSettings, tr( "Plugins" ) );
// Setting the icons for the plugin dialog.
d->w_pluginSettings->setAboutIcon(QIcon(QStringLiteral(":/icons/help-about.png")));
d->w_pluginSettings->setConfigIcon(QIcon(QStringLiteral(":/icons/settings-configure.png")));
connect( this, SIGNAL(rejected()), &d->m_pluginModel, SLOT(retrievePluginState()) );
connect( this, SIGNAL(accepted()), &d->m_pluginModel, SLOT(applyPluginState()) );
QWidget *w_cloudSyncSettings = new QWidget( this );
d->ui_cloudSyncSettings.setupUi( w_cloudSyncSettings );
tabWidget->addTab( w_cloudSyncSettings, tr( "Synchronization" ) );
d->ui_cloudSyncSettings.button_syncNow->setEnabled( syncBookmarks() );
d->m_cloudSyncStatusLabel = d->ui_cloudSyncSettings.cloudSyncStatus;
connect( d->ui_cloudSyncSettings.button_syncNow, SIGNAL(clicked()), SIGNAL(syncNowClicked()) );
connect( d->ui_cloudSyncSettings.testLoginButton, SIGNAL(clicked()), this, SLOT(updateCloudSyncCredentials()) );
if ( d->m_syncManager ) {
connect(d->m_syncManager, SIGNAL(syncComplete()), this, SLOT(updateLastSync()));
updateLastSync();
}
if ( d->m_cloudSyncManager ) {
connect( d->m_cloudSyncManager, SIGNAL(statusChanged(QString)),
this, SLOT(updateCloudSyncStatus(QString)));
}
// Layout
QVBoxLayout *layout = new QVBoxLayout( this );
layout->addWidget( tabWidget );
layout->addWidget( buttons );
this->setLayout( layout );
// When the settings have been changed, write to disk.
connect( this, SIGNAL(settingsChanged()), this, SLOT(syncSettings()) );
initializeCustomTimezone();
}
QtMarbleConfigDialog::~QtMarbleConfigDialog()
{
delete d;
}
void QtMarbleConfigDialog::syncSettings()
{
d->m_settings.sync();
QNetworkProxy proxy;
// Make sure that no proxy is used for an empty string or the default value:
if (proxyUrl().isEmpty() || proxyUrl() == QLatin1String("http://")) {
proxy.setType( QNetworkProxy::NoProxy );
} else {
if ( proxyType() == Marble::Socks5Proxy ) {
proxy.setType( QNetworkProxy::Socks5Proxy );
}
else if ( proxyType() == Marble::HttpProxy ) {
proxy.setType( QNetworkProxy::HttpProxy );
}
else {
mDebug() << "Unknown proxy type! Using Http Proxy instead.";
proxy.setType( QNetworkProxy::HttpProxy );
}
}
proxy.setHostName( proxyUrl() );
proxy.setPort( proxyPort() );
if ( proxyAuth() ) {
proxy.setUser( proxyUser() );
proxy.setPassword( proxyPass() );
}
QNetworkProxy::setApplicationProxy(proxy);
}
void QtMarbleConfigDialog::updateCloudSyncCredentials()
{
if ( d->m_cloudSyncManager ) {
d->m_cloudSyncManager->setOwncloudCredentials(
d->ui_cloudSyncSettings.kcfg_owncloudServer->text(),
d->ui_cloudSyncSettings.kcfg_owncloudUsername->text(),
d->ui_cloudSyncSettings.kcfg_owncloudPassword->text() );
}
}
void QtMarbleConfigDialog::disableSyncNow()
{
if ( !d->m_syncManager ) {
return;
}
d->ui_cloudSyncSettings.button_syncNow->setDisabled(true);
QTimer *timeoutTimer = new QTimer(this);
connect(timeoutTimer, SIGNAL(timeout()),
timeoutTimer, SLOT(stop()));
connect(timeoutTimer, SIGNAL(timeout()),
this, SLOT(enableSyncNow()));
connect(d->m_syncManager, SIGNAL(syncComplete()),
this, SLOT(enableSyncNow()));
connect(d->m_syncManager, SIGNAL(syncComplete()),
timeoutTimer, SLOT(stop()));
connect(d->m_syncManager, SIGNAL(syncComplete()),
timeoutTimer, SLOT(deleteLater()));
timeoutTimer->start(30*1000); // 30 sec
}
void QtMarbleConfigDialog::enableSyncNow()
{
if ( !d->m_syncManager ) {
return;
}
d->ui_cloudSyncSettings.button_syncNow->setEnabled(true);
}
void QtMarbleConfigDialog::updateLastSync()
{
if ( !d->m_syncManager ) {
return;
}
if (!d->m_syncManager->lastSync().isValid()) {
d->ui_cloudSyncSettings.labelLastSync->setText(tr("Never synchronized."));
return;
}
const QString title = tr("Last synchronization: %1")
.arg(d->m_syncManager->lastSync().toString());
d->ui_cloudSyncSettings.labelLastSync->setText(title);
}
void QtMarbleConfigDialog::readSettings()
{
// Sync settings to make sure that we read the current settings.
syncSettings();
// View
d->ui_viewSettings.kcfg_distanceUnit->setCurrentIndex( measurementSystem() );
d->ui_viewSettings.kcfg_angleUnit->setCurrentIndex( angleUnit() );
d->ui_viewSettings.kcfg_stillQuality->setCurrentIndex( stillQuality() );
d->ui_viewSettings.kcfg_animationQuality->setCurrentIndex( animationQuality() );
d->ui_viewSettings.kcfg_labelLocalization->setCurrentIndex( Marble::Native );
d->ui_viewSettings.kcfg_mapFont->setCurrentFont( mapFont() );
// Navigation
d->ui_navigationSettings.kcfg_dragLocation->setCurrentIndex( Marble::KeepAxisVertically );
d->ui_navigationSettings.kcfg_onStartup->setCurrentIndex( onStartup() );
d->ui_navigationSettings.kcfg_inertialEarthRotation->setChecked( inertialEarthRotation() );
d->ui_navigationSettings.kcfg_animateTargetVoyage->setChecked( animateTargetVoyage() );
int editorIndex = 0;
if (externalMapEditor() == QLatin1String("potlatch")) {
editorIndex = 1;
} else if (externalMapEditor() == QLatin1String("josm")) {
editorIndex = 2;
} else if (externalMapEditor() == QLatin1String("merkaartor")) {
editorIndex = 3;
}
d->ui_navigationSettings.kcfg_externalMapEditor->setCurrentIndex( editorIndex );
// Cache
d->ui_cacheSettings.kcfg_volatileTileCacheLimit->setValue( volatileTileCacheLimit() );
d->ui_cacheSettings.kcfg_persistentTileCacheLimit->setValue( persistentTileCacheLimit() );
d->ui_cacheSettings.kcfg_proxyUrl->setText( proxyUrl() );
d->ui_cacheSettings.kcfg_proxyPort->setValue( proxyPort() );
d->ui_cacheSettings.kcfg_proxyUser->setText( proxyUser() );
d->ui_cacheSettings.kcfg_proxyPass->setText( proxyPass() );
d->ui_cacheSettings.kcfg_proxyType->setCurrentIndex( proxyType() );
d->ui_cacheSettings.kcfg_proxyAuth->setChecked( proxyAuth() );
// Time
d->ui_timeSettings.kcfg_systemTimezone->setChecked( systemTimezone() );
d->ui_timeSettings.kcfg_customTimezone->setChecked( customTimezone() );
d->ui_timeSettings.kcfg_chosenTimezone->setCurrentIndex( chosenTimezone() );
d->ui_timeSettings.kcfg_utc->setChecked( UTC() );
d->ui_timeSettings.kcfg_systemTime->setChecked( systemTime() );
d->ui_timeSettings.kcfg_lastSessionTime->setChecked( lastSessionTime() );
if( systemTimezone() == true )
{
QDateTime localTime = QDateTime::currentDateTime().toLocalTime();
localTime.setTimeSpec( Qt::UTC );
d->m_marbleWidget->model()->setClockTimezone( QDateTime::currentDateTime().toUTC().secsTo( localTime ) );
}
else if( UTC() == true )
{
d->m_marbleWidget->model()->setClockTimezone( 0 );
}
else if( customTimezone() == true )
{
d->m_marbleWidget->model()->setClockTimezone( d->m_timezone.value( chosenTimezone() ) );
}
// Routing
// ownCloud
d->ui_cloudSyncSettings.kcfg_enableSync->setChecked( syncEnabled() );
d->ui_cloudSyncSettings.kcfg_syncBookmarks->setChecked( syncBookmarks() );
d->ui_cloudSyncSettings.kcfg_syncRoutes->setChecked( syncRoutes() );
d->ui_cloudSyncSettings.kcfg_owncloudServer->setText( owncloudServer() );
d->ui_cloudSyncSettings.kcfg_owncloudUsername->setText( owncloudUsername() );
d->ui_cloudSyncSettings.kcfg_owncloudPassword->setText( owncloudPassword() );
// Read the settings of the plugins
d->m_marbleWidget->readPluginSettings( d->m_settings );
// The settings loaded in the config dialog have been changed.
emit settingsChanged();
}
void QtMarbleConfigDialog::updateCloudSyncStatus( const QString &status )
{
d->m_cloudSyncStatusLabel->setText(status);
CloudSyncManager::Status status_type =
d->m_cloudSyncManager ? d->m_cloudSyncManager->status() : CloudSyncManager::Unknown;
switch (status_type) {
case CloudSyncManager::Success:
d->m_cloudSyncStatusLabel->setStyleSheet("QLabel { color : green; }");
break;
case CloudSyncManager::Error:
d->m_cloudSyncStatusLabel->setStyleSheet("QLabel { color : red; }");
break;
case CloudSyncManager::Unknown:
d->m_cloudSyncStatusLabel->setStyleSheet("QLabel { color : grey; }");
break;
}
}
void QtMarbleConfigDialog::writeSettings()
{
syncSettings();
d->m_settings.beginGroup( "View" );
d->m_settings.setValue( "distanceUnit", d->ui_viewSettings.kcfg_distanceUnit->currentIndex() );
d->m_settings.setValue( "angleUnit", d->ui_viewSettings.kcfg_angleUnit->currentIndex() );
d->m_settings.setValue( "stillQuality", d->ui_viewSettings.kcfg_stillQuality->currentIndex() );
d->m_settings.setValue( "animationQuality", d->ui_viewSettings.kcfg_animationQuality->currentIndex() );
d->m_settings.setValue( "mapFont", d->ui_viewSettings.kcfg_mapFont->currentFont() );
d->m_settings.endGroup();
d->m_settings.beginGroup( "Navigation" );
d->m_settings.setValue( "onStartup", d->ui_navigationSettings.kcfg_onStartup->currentIndex() );
d->m_settings.setValue( "inertialEarthRotation", d->ui_navigationSettings.kcfg_inertialEarthRotation->isChecked() );
d->m_settings.setValue( "animateTargetVoyage", d->ui_navigationSettings.kcfg_animateTargetVoyage->isChecked() );
if( d->ui_navigationSettings.kcfg_externalMapEditor->currentIndex() == 0 ) {
d->m_settings.setValue( "externalMapEditor", "" );
} else if( d->ui_navigationSettings.kcfg_externalMapEditor->currentIndex() == 1 ) {
d->m_settings.setValue( "externalMapEditor", "potlatch" );
} else if( d->ui_navigationSettings.kcfg_externalMapEditor->currentIndex() == 2 ) {
d->m_settings.setValue( "externalMapEditor", "josm" );
} else if( d->ui_navigationSettings.kcfg_externalMapEditor->currentIndex() == 3 ) {
d->m_settings.setValue( "externalMapEditor", "merkaartor" );
} else {
Q_ASSERT( false && "Unexpected index of the external editor setting" );
}
d->m_settings.endGroup();
d->m_settings.beginGroup( "Cache" );
d->m_settings.setValue( "volatileTileCacheLimit", d->ui_cacheSettings.kcfg_volatileTileCacheLimit->value() );
d->m_settings.setValue( "persistentTileCacheLimit", d->ui_cacheSettings.kcfg_persistentTileCacheLimit->value() );
d->m_settings.setValue( "proxyUrl", d->ui_cacheSettings.kcfg_proxyUrl->text() );
d->m_settings.setValue( "proxyPort", d->ui_cacheSettings.kcfg_proxyPort->value() );
d->m_settings.setValue( "proxyType", d->ui_cacheSettings.kcfg_proxyType->currentIndex() );
if ( d->ui_cacheSettings.kcfg_proxyAuth->isChecked() ) {
d->m_settings.setValue( "proxyAuth", true );
d->m_settings.setValue( "proxyUser", d->ui_cacheSettings.kcfg_proxyUser->text() );
d->m_settings.setValue( "proxyPass", d->ui_cacheSettings.kcfg_proxyPass->text() );
} else {
d->m_settings.setValue( "proxyAuth", false );
}
d->m_settings.endGroup();
d->m_settings.beginGroup( "Time" );
d->m_settings.setValue( "systemTimezone", d->ui_timeSettings.kcfg_systemTimezone->isChecked() );
d->m_settings.setValue( "UTC", d->ui_timeSettings.kcfg_utc->isChecked() );
d->m_settings.setValue( "customTimezone", d->ui_timeSettings.kcfg_customTimezone->isChecked() );
d->m_settings.setValue( "systemTime", d->ui_timeSettings.kcfg_systemTime->isChecked() );
d->m_settings.setValue( "lastSessionTime", d->ui_timeSettings.kcfg_lastSessionTime->isChecked() );
d->m_settings.setValue( "chosenTimezone", d->ui_timeSettings.kcfg_chosenTimezone->currentIndex() );
d->m_settings.endGroup();
d->m_settings.beginGroup( "CloudSync" );
d->m_settings.setValue( "enableSync", d->ui_cloudSyncSettings.kcfg_enableSync->isChecked() );
d->m_settings.setValue( "syncBackend", "owncloud" );
d->m_settings.setValue( "syncBookmarks", d->ui_cloudSyncSettings.kcfg_syncBookmarks->isChecked() );
d->m_settings.setValue( "syncRoutes", d->ui_cloudSyncSettings.kcfg_syncRoutes->isChecked() );
d->m_settings.setValue( "owncloudServer", d->ui_cloudSyncSettings.kcfg_owncloudServer->text() );
d->m_settings.setValue( "owncloudUsername", d->ui_cloudSyncSettings.kcfg_owncloudUsername->text() );
d->m_settings.setValue( "owncloudPassword", d->ui_cloudSyncSettings.kcfg_owncloudPassword->text() );
d->m_settings.endGroup();
// Plugins
d->m_marbleWidget->writePluginSettings( d->m_settings );
emit settingsChanged();
}
MarbleLocale::MeasurementSystem QtMarbleConfigDialog::measurementSystem() const
{
if( d->m_settings.contains( "View/distanceUnit" ) ) {
return (MarbleLocale::MeasurementSystem)d->m_settings.value( "View/distanceUnit" ).toInt();
}
MarbleLocale *locale = MarbleGlobal::getInstance()->locale();
return locale->measurementSystem();
}
Marble::AngleUnit QtMarbleConfigDialog::angleUnit() const
{
return (Marble::AngleUnit) d->m_settings.value( "View/angleUnit", Marble::DMSDegree ).toInt();
}
void QtMarbleConfigDialog::setAngleUnit(Marble::AngleUnit unit)
{
d->m_settings.setValue( "View/angleUnit", (int)unit );
d->ui_viewSettings.kcfg_angleUnit->setCurrentIndex( angleUnit() );
emit settingsChanged();
}
Marble::MapQuality QtMarbleConfigDialog::stillQuality() const
{
return (Marble::MapQuality) d->m_settings.value( "View/stillQuality",
Marble::HighQuality ).toInt();
}
Marble::MapQuality QtMarbleConfigDialog::animationQuality() const
{
return (Marble::MapQuality) d->m_settings.value( "View/animationQuality",
Marble::LowQuality ).toInt();
}
QFont QtMarbleConfigDialog::mapFont() const
{
return d->m_settings.value( "View/mapFont", QApplication::font() ).value<QFont>();
}
int QtMarbleConfigDialog::onStartup() const
{
bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
int defaultValue = smallScreen ? Marble::LastLocationVisited : Marble::ShowHomeLocation;
return d->m_settings.value( "Navigation/onStartup", defaultValue ).toInt();
}
QString QtMarbleConfigDialog::externalMapEditor() const
{
return d->m_settings.value( "Navigation/externalMapEditor", "" ).toString();
}
bool QtMarbleConfigDialog::animateTargetVoyage() const
{
const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
return d->m_settings.value( "Navigation/animateTargetVoyage", smallScreen ).toBool();
}
bool QtMarbleConfigDialog::inertialEarthRotation() const
{
return d->m_settings.value( "Navigation/inertialEarthRotation", true ).toBool();
}
int QtMarbleConfigDialog::volatileTileCacheLimit() const
{
int defaultValue = (MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen) ? 6 : 100;
return d->m_settings.value( "Cache/volatileTileCacheLimit", defaultValue ).toInt();
}
int QtMarbleConfigDialog::persistentTileCacheLimit() const
{
return d->m_settings.value( "Cache/persistentTileCacheLimit", 0 ).toInt(); // default to unlimited
}
QString QtMarbleConfigDialog::proxyUrl() const
{
return d->m_settings.value( "Cache/proxyUrl", "" ).toString();
}
int QtMarbleConfigDialog::proxyPort() const
{
return d->m_settings.value( "Cache/proxyPort", 8080 ).toInt();
}
QString QtMarbleConfigDialog::proxyUser() const
{
return d->m_settings.value( "Cache/proxyUser", "" ).toString();
}
QString QtMarbleConfigDialog::proxyPass() const
{
return d->m_settings.value( "Cache/proxyPass", "" ).toString();
}
bool QtMarbleConfigDialog::proxyType() const
{
return d->m_settings.value( "Cache/proxyType", Marble::HttpProxy ).toInt();
}
bool QtMarbleConfigDialog::proxyAuth() const
{
return d->m_settings.value( "Cache/proxyAuth", false ).toBool();
}
bool QtMarbleConfigDialog::systemTimezone() const
{
return d->m_settings.value( "Time/systemTimezone", true ).toBool();
}
bool QtMarbleConfigDialog::customTimezone() const
{
return d->m_settings.value( "Time/customTimezone", false ).toBool();
}
bool QtMarbleConfigDialog::UTC() const
{
return d->m_settings.value( "Time/UTC", false ).toBool();
}
bool QtMarbleConfigDialog::systemTime() const
{
return d->m_settings.value( "Time/systemTime", true ).toBool();
}
bool QtMarbleConfigDialog::lastSessionTime() const
{
return d->m_settings.value( "Time/lastSessionTime", false ).toBool();
}
int QtMarbleConfigDialog::chosenTimezone() const
{
return d->m_settings.value( "Time/chosenTimezone", 0 ).toInt();
}
void QtMarbleConfigDialog::initializeCustomTimezone()
{
if( d->m_timezone.count() == 0)
{
d->m_timezone.insert( 0, 0 );
d->m_timezone.insert( 1, 3600 );
d->m_timezone.insert( 2, 7200 );
d->m_timezone.insert( 3, 7200 );
d->m_timezone.insert( 4, 10800 );
d->m_timezone.insert( 5, 12600 );
d->m_timezone.insert( 6, 14400 );
d->m_timezone.insert( 7, 18000 );
d->m_timezone.insert( 8, 19800 );
d->m_timezone.insert( 9, 21600 );
d->m_timezone.insert( 10, 25200 );
d->m_timezone.insert( 11, 28800 );
d->m_timezone.insert( 12, 32400 );
d->m_timezone.insert( 13, 34200 );
d->m_timezone.insert( 14, 36000 );
d->m_timezone.insert( 15, 39600 );
d->m_timezone.insert( 16, 43200 );
d->m_timezone.insert( 17, -39600 );
d->m_timezone.insert( 18, -36000 );
d->m_timezone.insert( 19, -32400 );
d->m_timezone.insert( 20, -28800 );
d->m_timezone.insert( 21, -25200 );
d->m_timezone.insert( 22, -25200 );
d->m_timezone.insert( 23, -21600 );
d->m_timezone.insert( 24, -18000 );
d->m_timezone.insert( 25, -18000 );
d->m_timezone.insert( 26, -14400 );
d->m_timezone.insert( 27, -12600 );
d->m_timezone.insert( 28, -10800 );
d->m_timezone.insert( 29, -10800 );
d->m_timezone.insert( 30, -3600 );
}
}
bool QtMarbleConfigDialog::syncEnabled() const
{
return d->m_settings.value( "CloudSync/enableSync", false ).toBool();
}
QString QtMarbleConfigDialog::syncBackend() const
{
return d->m_settings.value( "CloudSync/syncBackend", "" ).toString();
}
bool QtMarbleConfigDialog::syncBookmarks() const
{
return d->m_settings.value( "CloudSync/syncBookmarks", true ).toBool();
}
bool QtMarbleConfigDialog::syncRoutes() const
{
return d->m_settings.value( "CloudSync/syncRoutes", true ).toBool();
}
QString QtMarbleConfigDialog::owncloudServer() const
{
return d->m_settings.value( "CloudSync/owncloudServer", "" ).toString();
}
QString QtMarbleConfigDialog::owncloudUsername() const
{
return d->m_settings.value( "CloudSync/owncloudUsername", "" ).toString();
}
QString QtMarbleConfigDialog::owncloudPassword() const
{
return d->m_settings.value( "CloudSync/owncloudPassword", "" ).toString();
}
}
#include "moc_QtMarbleConfigDialog.cpp"
diff --git a/src/lib/marble/QtMarbleConfigDialog.h b/src/lib/marble/QtMarbleConfigDialog.h
index d200ae122..ef33bb447 100644
--- a/src/lib/marble/QtMarbleConfigDialog.h
+++ b/src/lib/marble/QtMarbleConfigDialog.h
@@ -1,170 +1,170 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_QTMARBLECONFIGDIALOG_H
#define MARBLE_QTMARBLECONFIGDIALOG_H
#include <QDialog>
#include "marble_export.h"
#include "MarbleGlobal.h"
#include "MarbleLocale.h"
namespace Marble
{
class MarbleWidget;
class CloudSyncManager;
class QtMarbleConfigDialogPrivate;
class MARBLE_EXPORT QtMarbleConfigDialog : public QDialog
{
Q_OBJECT
public:
- explicit QtMarbleConfigDialog(MarbleWidget *marbleWidget, CloudSyncManager *syncManager = 0,
- QWidget *parent = 0 );
+ explicit QtMarbleConfigDialog(MarbleWidget *marbleWidget, CloudSyncManager *syncManager = nullptr,
+ QWidget *parent = nullptr );
~QtMarbleConfigDialog() override;
// View Settings
MarbleLocale::MeasurementSystem measurementSystem() const;
Marble::AngleUnit angleUnit() const;
void setAngleUnit(Marble::AngleUnit unit);
Marble::MapQuality stillQuality() const;
Marble::MapQuality animationQuality() const;
QFont mapFont() const;
// Navigation Settings
int onStartup() const;
bool animateTargetVoyage() const;
QString externalMapEditor() const;
bool inertialEarthRotation() const;
// Cache Settings
int volatileTileCacheLimit() const;
int persistentTileCacheLimit() const;
QString proxyUrl() const;
int proxyPort() const;
QString proxyUser() const;
QString proxyPass() const;
bool proxyType() const;
bool proxyAuth() const;
// Time Settings
/**
* Read the value of 'Time/systemTime' key from settings
*/
bool systemTime() const;
/**
* Read the value of 'Time/lastSessionTime' key from settings
*/
bool lastSessionTime() const;
/**
* Read the value of 'Time/systemTimezone' key from settings
*/
bool systemTimezone() const;
/**
* Read the value of 'Time/UTC' key from settings
*/
bool UTC() const;
/**
* Read the value of 'Time/customTimezone' key from settings
*/
bool customTimezone() const;
/**
* Read the value of 'Time/chosenTimezone' key from settings
*/
int chosenTimezone() const;
void initializeCustomTimezone();
// CloudSync settings
bool syncEnabled() const;
QString syncBackend() const;
bool syncBookmarks() const;
bool syncRoutes() const;
QString owncloudServer() const;
QString owncloudUsername() const;
QString owncloudPassword() const;
Q_SIGNALS:
/**
* This signal is emitted when the loaded settings were changed.
* Either by the user or by loading them initially from disk.
*/
void settingsChanged();
/**
* The user clicked on the button to clear volatile tile cache.
*/
void clearVolatileCacheClicked();
/**
* The user clicked on the button to clear persistent tile cache.
*/
void clearPersistentCacheClicked();
/**
* The user clicked on the button to manually synchronize bookmarks.
*/
void syncNowClicked();
public Q_SLOTS:
/**
* Disable "Sync Now" button while sync or for 30 sec of timout
*/
void disableSyncNow();
void enableSyncNow();
/**
* Sets new title for the "Last Sync" label indicator
*/
void updateLastSync();
/**
* Read settings and update interface.
*/
void readSettings();
/**
* Show status on cloud sync settings tab
*/
void updateCloudSyncStatus( const QString &status );
/**
* Write settings to disk.
*/
void writeSettings();
private Q_SLOTS:
/**
* Synchronize the loaded settings with the file on hard disk.
*/
void syncSettings();
void updateCloudSyncCredentials();
private:
Q_DISABLE_COPY( QtMarbleConfigDialog )
QtMarbleConfigDialogPrivate * const d;
};
} // Marble namespace
#endif
diff --git a/src/lib/marble/RemoteIconLoader.h b/src/lib/marble/RemoteIconLoader.h
index aaaad1979..d614256cf 100644
--- a/src/lib/marble/RemoteIconLoader.h
+++ b/src/lib/marble/RemoteIconLoader.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
#ifndef MARBLE_REMOTEICONLOADER_H
#define MARBLE_REMOTEICONLOADER_H
#include <QObject>
class QString;
class QByteArray;
class QImage;
class QUrl;
namespace Marble
{
class RemoteIconLoaderPrivate;
class RemoteIconLoader : public QObject
{
Q_OBJECT;
public:
- explicit RemoteIconLoader( QObject *parent = 0 );
+ explicit RemoteIconLoader( QObject *parent = nullptr );
~RemoteIconLoader() override;
/**
* Handles the icon request for passed url( whether icon is available
* in cache or on disk or it should gor for a download
*/
QImage load( const QUrl& url );
Q_SIGNALS:
/**
* Signal to indicate that image has been downloaded
* and is ready to be display now
*/
void iconReady();
private Q_SLOTS:
void storeIcon( const QByteArray&, const QString& );
private:
RemoteIconLoaderPrivate *d;
};
}
#endif // MARBLE_REMOTEICONLOADER_H
diff --git a/src/lib/marble/RemoveItemEditWidget.h b/src/lib/marble/RemoveItemEditWidget.h
index a57e8f547..e96897971 100644
--- a/src/lib/marble/RemoveItemEditWidget.h
+++ b/src/lib/marble/RemoveItemEditWidget.h
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Mihail Ivchenko <ematirov@gmail.com>
//
#ifndef REMOVEITEMEDITWIDGET_H
#define REMOVEITEMEDITWIDGET_H
#include <QWidget>
class QToolButton;
class QComboBox;
class QModelIndex;
namespace Marble
{
class GeoDataAnimatedUpdate;
class RemoveItemEditWidget: public QWidget
{
Q_OBJECT
public:
- explicit RemoveItemEditWidget( const QModelIndex& index, QWidget* parent=0 );
+ explicit RemoveItemEditWidget( const QModelIndex& index, QWidget* parent=nullptr );
bool editable() const;
Q_SIGNALS:
void editingDone( const QModelIndex& index );
public Q_SLOTS:
void setEditable( bool editable );
void setFeatureIds( const QStringList &ids );
void setDefaultFeatureId( const QString &featureId );
private Q_SLOTS:
void save();
private:
GeoDataAnimatedUpdate* animatedUpdateElement();
QPersistentModelIndex m_index;
QToolButton *m_button;
QComboBox* m_comboBox;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/RenderPlugin.cpp b/src/lib/marble/RenderPlugin.cpp
index 2cb264ffa..dbf08d62d 100644
--- a/src/lib/marble/RenderPlugin.cpp
+++ b/src/lib/marble/RenderPlugin.cpp
@@ -1,252 +1,252 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <rahn@kde.org>
// Copyright 2008 Inge Wallin <inge@lysator.liu.se>
// Copyright 2011,2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
// Self
#include "RenderPlugin.h"
// Marble
#include "DialogConfigurationInterface.h"
#include "MarbleModel.h"
#include "MarbleDebug.h"
#include "RenderPluginModel.h"
#include "RenderState.h"
// Qt
#include <QAction>
#include <QStandardItem>
namespace Marble
{
class Q_DECL_HIDDEN RenderPlugin::Private
{
public:
Private( const MarbleModel *marbleModel )
: m_marbleModel( marbleModel ),
- m_action(0),
+ m_action(nullptr),
m_item(),
m_enabled(true),
m_visible(true),
m_userCheckable(true)
{
}
~Private()
{
}
// const: RenderPlugins should only read the model, not modify it
const MarbleModel *const m_marbleModel;
QAction m_action;
QStandardItem m_item;
bool m_enabled;
bool m_visible;
bool m_userCheckable;
};
RenderPlugin::RenderPlugin( const MarbleModel *marbleModel )
: d( new Private( marbleModel ) )
{
connect( &d->m_action, SIGNAL(toggled(bool)),
this, SLOT(setVisible(bool)) );
connect( this, SIGNAL(visibilityChanged(bool,QString)),
&d->m_action, SLOT(setChecked(bool)) );
connect( this, SIGNAL(enabledChanged(bool)),
&d->m_action, SLOT(setVisible(bool)) );
connect( this, SIGNAL(enabledChanged(bool)),
SIGNAL(actionGroupsChanged()) );
connect( this, SIGNAL(visibilityChanged(bool,QString)),
this, SIGNAL(repaintNeeded()) );
connect( this, SIGNAL(settingsChanged(QString)),
this, SIGNAL(repaintNeeded()) );
}
RenderPlugin::~RenderPlugin()
{
delete d;
}
const MarbleModel* RenderPlugin::marbleModel() const
{
return d->m_marbleModel;
}
QAction* RenderPlugin::action() const
{
d->m_action.setCheckable( true );
d->m_action.setChecked( visible() );
d->m_action.setIcon( icon() );
d->m_action.setText( guiString() );
d->m_action.setToolTip( description() );
return &d->m_action;
}
const QList<QActionGroup*>* RenderPlugin::actionGroups() const
{
- return 0;
+ return nullptr;
}
const QList<QActionGroup*>* RenderPlugin::toolbarActionGroups() const
{
- return 0;
+ return nullptr;
}
QStandardItem* RenderPlugin::item()
{
d->m_item.setIcon( icon() );
d->m_item.setText( name() );
d->m_item.setEditable( false );
d->m_item.setCheckable( true );
d->m_item.setCheckState( enabled() ? Qt::Checked : Qt::Unchecked );
d->m_item.setToolTip( description() );
d->m_item.setFlags( d->m_item.flags() & ~Qt::ItemIsSelectable );
// Custom data
d->m_item.setData( nameId(), RenderPluginModel::NameId );
d->m_item.setData( (bool) qobject_cast<DialogConfigurationInterface *>( this ), RenderPluginModel::ConfigurationDialogAvailable );
d->m_item.setData( backendTypes(), RenderPluginModel::BackendTypes );
d->m_item.setData( version(), RenderPluginModel::Version );
d->m_item.setData( aboutDataText(), RenderPluginModel::AboutDataText );
d->m_item.setData( copyrightYears(), RenderPluginModel::CopyrightYears );
return &d->m_item;
}
void RenderPlugin::applyItemState()
{
setEnabled( d->m_item.checkState() == Qt::Checked );
}
void RenderPlugin::retrieveItemState()
{
d->m_item.setCheckState( enabled() ? Qt::Checked : Qt::Unchecked );
}
void RenderPlugin::setEnabled( bool enabled )
{
if ( enabled == d->m_enabled )
return;
d->m_enabled = enabled;
d->m_item.setCheckState( enabled ? Qt::Checked : Qt::Unchecked );
emit enabledChanged( enabled );
}
void RenderPlugin::setVisible( bool visible )
{
if ( visible == d->m_visible )
return;
d->m_visible = visible;
emit visibilityChanged( visible, nameId() );
}
void RenderPlugin::setUserCheckable( bool checkable )
{
if ( checkable != d->m_userCheckable ) {
d->m_action.setEnabled( checkable );
d->m_userCheckable = checkable;
emit userCheckableChanged( checkable );
}
}
bool RenderPlugin::enabled() const
{
return d->m_enabled;
}
bool RenderPlugin::visible() const
{
return d->m_visible;
}
bool RenderPlugin::isUserCheckable() const
{
return d->m_userCheckable;
}
QHash<QString,QVariant> RenderPlugin::settings() const
{
QHash<QString,QVariant> result;
result.insert(QStringLiteral("enabled"), enabled());
result.insert(QStringLiteral("visible"), visible());
return result;
}
void RenderPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
setEnabled(settings.value(QStringLiteral("enabled"), enabled()).toBool());
setVisible(settings.value(QStringLiteral("visible"), visible()).toBool());
}
RenderPlugin::RenderType RenderPlugin::renderType() const
{
return UnknownRenderType;
}
RenderState RenderPlugin::renderState() const
{
return RenderState( name() );
}
QString RenderPlugin::runtimeTrace() const
{
return name();
}
bool RenderPlugin::eventFilter( QObject *, QEvent * )
{
return false;
}
void RenderPlugin::restoreDefaultSettings()
{
setSettings( QHash<QString,QVariant>() );
}
QStringList RenderPlugin::settingKeys() const
{
return settings().keys();
}
bool RenderPlugin::setSetting( const QString & key, const QVariant & value )
{
QHash< QString, QVariant> settings = this->settings();
if( settings.contains( key ) )
{
settings [ key ] = value;
setSettings( settings );
return true;
} else {
return false;
}
}
QVariant RenderPlugin::setting( const QString & name ) const
{
return settings().value( name, QVariant() );
}
} // namespace Marble
#include "moc_RenderPlugin.cpp"
diff --git a/src/lib/marble/RenderPluginModel.cpp b/src/lib/marble/RenderPluginModel.cpp
index 613480670..f77800124 100644
--- a/src/lib/marble/RenderPluginModel.cpp
+++ b/src/lib/marble/RenderPluginModel.cpp
@@ -1,109 +1,109 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "RenderPluginModel.h"
#include "DialogConfigurationInterface.h"
#include "RenderPlugin.h"
namespace Marble
{
class Q_DECL_HIDDEN RenderPluginModel::Private
{
public:
Private();
static bool renderPluginGuiStringLessThan( RenderPlugin* one, RenderPlugin* two )
{
// Sort by gui string ignoring keyboard accelerators
return one->guiString().remove( QLatin1Char( '&' ) ) < two->guiString().remove( QLatin1Char( '&' ) );
}
QList<RenderPlugin *> m_renderPlugins;
};
RenderPluginModel::Private::Private() :
m_renderPlugins()
{
}
RenderPluginModel::RenderPluginModel( QObject *parent ) :
QStandardItemModel( parent ),
d( new Private )
{
}
RenderPluginModel::~RenderPluginModel()
{
// our model doesn't own the items, so take them away
while ( invisibleRootItem()->hasChildren() ) {
invisibleRootItem()->takeRow( 0 );
}
delete d;
}
void RenderPluginModel::setRenderPlugins( const QList<RenderPlugin *> &renderPlugins )
{
// our model doesn't own the items, so take them away
while ( invisibleRootItem()->hasChildren() ) {
invisibleRootItem()->takeRow( 0 );
}
d->m_renderPlugins = renderPlugins;
std::sort( d->m_renderPlugins.begin(), d->m_renderPlugins.end(), Private::renderPluginGuiStringLessThan );
QStandardItem *parentItem = invisibleRootItem();
for ( RenderPlugin *plugin: d->m_renderPlugins ) {
parentItem->appendRow( plugin->item() );
}
}
QVector<PluginAuthor> RenderPluginModel::pluginAuthors( const QModelIndex &index ) const
{
if ( !index.isValid() )
return QVector<PluginAuthor>();
if ( index.row() < 0 || index.row() >= d->m_renderPlugins.count() )
return QVector<PluginAuthor>();
return d->m_renderPlugins.at( index.row() )->pluginAuthors();
}
DialogConfigurationInterface *RenderPluginModel::pluginDialogConfigurationInterface( const QModelIndex &index )
{
if ( !index.isValid() )
- return 0;
+ return nullptr;
if ( index.row() < 0 || index.row() >= d->m_renderPlugins.count() )
- return 0;
+ return nullptr;
RenderPlugin *plugin = d->m_renderPlugins.at( index.row() );
return qobject_cast<DialogConfigurationInterface *>( plugin );
}
void RenderPluginModel::retrievePluginState()
{
for ( RenderPlugin *plugin: d->m_renderPlugins ) {
plugin->retrieveItemState();
}
}
void RenderPluginModel::applyPluginState()
{
for ( RenderPlugin *plugin: d->m_renderPlugins ) {
plugin->applyItemState();
}
}
}
#include "moc_RenderPluginModel.cpp"
diff --git a/src/lib/marble/RenderPluginModel.h b/src/lib/marble/RenderPluginModel.h
index 6b3e6aaba..1c8a6728f 100644
--- a/src/lib/marble/RenderPluginModel.h
+++ b/src/lib/marble/RenderPluginModel.h
@@ -1,87 +1,87 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_RENDERPLUGINMODEL_H
#define MARBLE_RENDERPLUGINMODEL_H
#include "marble_export.h"
#include <QStandardItemModel>
#include <QList>
#include "PluginInterface.h"
namespace Marble
{
class DialogConfigurationInterface;
class RenderPlugin;
/**
* @brief Provides common access to various kinds of plugins without having to know about their details.
*/
class MARBLE_EXPORT RenderPluginModel : public QStandardItemModel
{
Q_OBJECT
public:
/**
* This enum contains the data roles for the QStandardItems.
*/
enum ItemDataRole {
Name = Qt::DisplayRole, // QString
Icon = Qt::DecorationRole, // QIcon
Description = Qt::ToolTipRole, // QString
NameId = Qt::UserRole + 2, // QString
ConfigurationDialogAvailable, // bool
BackendTypes, // QStringList
Version, // QString
AboutDataText, // QString
CopyrightYears // QString
};
- explicit RenderPluginModel( QObject *parent = 0 );
+ explicit RenderPluginModel( QObject *parent = nullptr );
~RenderPluginModel() override;
/**
* @brief Set the RenderPlugins the model should manage.
*
* The given plugins must not be deleted as long as the model has a hold on them,
* i.e. until the model is deleted or a different set of plugins is assigned.
*
* @param renderPlugins the RenderPlugins to be managed
*/
void setRenderPlugins( const QList<RenderPlugin *> &renderPlugins );
QVector<PluginAuthor> pluginAuthors( const QModelIndex &index ) const;
DialogConfigurationInterface *pluginDialogConfigurationInterface( const QModelIndex &index );
public Q_SLOTS:
/**
* Retrieve the current plugin state for the user interface.
*/
void retrievePluginState();
/**
* Apply the plugin state from the user interface.
*/
void applyPluginState();
private:
class Private;
Private *const d;
friend class Private;
};
}
#endif // MARBLE_RENDERPLUGINMODEL_H
diff --git a/src/lib/marble/ReverseGeocodingRunnerManager.cpp b/src/lib/marble/ReverseGeocodingRunnerManager.cpp
index adf3128a4..18146cc56 100644
--- a/src/lib/marble/ReverseGeocodingRunnerManager.cpp
+++ b/src/lib/marble/ReverseGeocodingRunnerManager.cpp
@@ -1,175 +1,175 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#include "ReverseGeocodingRunnerManager.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "GeoDataCoordinates.h"
#include "GeoDataPlacemark.h"
#include "Planet.h"
#include "PluginManager.h"
#include "ReverseGeocodingRunnerPlugin.h"
#include "RunnerTask.h"
#include <QList>
#include <QThreadPool>
#include <QTimer>
namespace Marble
{
class MarbleModel;
class Q_DECL_HIDDEN ReverseGeocodingRunnerManager::Private
{
public:
Private( ReverseGeocodingRunnerManager *parent, const MarbleModel *marbleModel );
QList<const ReverseGeocodingRunnerPlugin *> plugins( const QList<const ReverseGeocodingRunnerPlugin *> &plugins ) const;
void addReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark );
void cleanupReverseGeocodingTask( ReverseGeocodingTask *task );
ReverseGeocodingRunnerManager *const q;
const MarbleModel *const m_marbleModel;
const PluginManager* m_pluginManager;
QList<ReverseGeocodingTask*> m_reverseTasks;
QVector<GeoDataCoordinates> m_reverseGeocodingResults;
QString m_reverseGeocodingResult;
};
ReverseGeocodingRunnerManager::Private::Private( ReverseGeocodingRunnerManager *parent, const MarbleModel *marbleModel ) :
q( parent ),
m_marbleModel( marbleModel ),
m_pluginManager( marbleModel->pluginManager() )
{
qRegisterMetaType<GeoDataPlacemark>( "GeoDataPlacemark" );
qRegisterMetaType<GeoDataCoordinates>( "GeoDataCoordinates" );
}
QList<const ReverseGeocodingRunnerPlugin *> ReverseGeocodingRunnerManager::Private::plugins( const QList<const ReverseGeocodingRunnerPlugin *> &plugins ) const
{
QList<const ReverseGeocodingRunnerPlugin *> result;
for( const ReverseGeocodingRunnerPlugin *plugin: plugins ) {
if ( ( m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline() ) ) {
continue;
}
if ( !plugin->canWork() ) {
continue;
}
if ( m_marbleModel && !plugin->supportsCelestialBody( m_marbleModel->planet()->id() ) )
{
continue;
}
result << plugin;
}
return result;
}
void ReverseGeocodingRunnerManager::Private::addReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark )
{
if ( !m_reverseGeocodingResults.contains( coordinates ) && !placemark.address().isEmpty() ) {
m_reverseGeocodingResults.push_back( coordinates );
m_reverseGeocodingResult = placemark.address();
emit q->reverseGeocodingFinished( coordinates, placemark );
}
if ( m_reverseTasks.isEmpty() ) {
emit q->reverseGeocodingFinished();
}
}
void ReverseGeocodingRunnerManager::Private::cleanupReverseGeocodingTask( ReverseGeocodingTask *task )
{
m_reverseTasks.removeAll( task );
mDebug() << "removing task " << m_reverseTasks.size() << " " << (quintptr)task;
if ( m_reverseTasks.isEmpty() ) {
emit q->reverseGeocodingFinished();
}
}
ReverseGeocodingRunnerManager::ReverseGeocodingRunnerManager( const MarbleModel *marbleModel, QObject *parent ) :
QObject( parent ),
d( new Private( this, marbleModel ) )
{
if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
QThreadPool::globalInstance()->setMaxThreadCount( 4 );
}
}
ReverseGeocodingRunnerManager::~ReverseGeocodingRunnerManager()
{
delete d;
}
void ReverseGeocodingRunnerManager::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
d->m_reverseTasks.clear();
d->m_reverseGeocodingResult.clear();
#if QT_VERSION >= 0x050400
d->m_reverseGeocodingResults.removeAll( coordinates );
#else
QVector<GeoDataCoordinates> &vector = d->m_reverseGeocodingResults;
QVector<GeoDataCoordinates>::iterator it = vector.begin();
while (it != vector.end()) {
if (*it == coordinates) {
it = vector.erase(it);
} else {
++it;
}
}
#endif
QList<const ReverseGeocodingRunnerPlugin*> plugins = d->plugins( d->m_pluginManager->reverseGeocodingRunnerPlugins() );
for( const ReverseGeocodingRunnerPlugin* plugin: plugins ) {
ReverseGeocodingTask* task = new ReverseGeocodingTask( plugin->newRunner(), this, d->m_marbleModel, coordinates );
connect( task, SIGNAL(finished(ReverseGeocodingTask*)), this, SLOT(cleanupReverseGeocodingTask(ReverseGeocodingTask*)) );
mDebug() << "reverse task " << plugin->nameId() << " " << (quintptr)task;
d->m_reverseTasks << task;
}
for( ReverseGeocodingTask* task: d->m_reverseTasks ) {
QThreadPool::globalInstance()->start( task );
}
if ( plugins.isEmpty() ) {
GeoDataPlacemark anonymous;
anonymous.setCoordinate( coordinates );
emit reverseGeocodingFinished( coordinates, anonymous );
- d->cleanupReverseGeocodingTask( 0 );
+ d->cleanupReverseGeocodingTask( nullptr );
}
}
QString ReverseGeocodingRunnerManager::searchReverseGeocoding( const GeoDataCoordinates &coordinates, int timeout ) {
QEventLoop localEventLoop;
QTimer watchdog;
watchdog.setSingleShot(true);
connect( &watchdog, SIGNAL(timeout()),
&localEventLoop, SLOT(quit()));
connect(this, SIGNAL(reverseGeocodingFinished()),
&localEventLoop, SLOT(quit()), Qt::QueuedConnection );
watchdog.start( timeout );
reverseGeocoding( coordinates );
localEventLoop.exec();
return d->m_reverseGeocodingResult;
}
}
#include "moc_ReverseGeocodingRunnerManager.cpp"
diff --git a/src/lib/marble/ReverseGeocodingRunnerManager.h b/src/lib/marble/ReverseGeocodingRunnerManager.h
index fb2eade43..f34d1ee65 100644
--- a/src/lib/marble/ReverseGeocodingRunnerManager.h
+++ b/src/lib/marble/ReverseGeocodingRunnerManager.h
@@ -1,80 +1,80 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLE_REVERSEGEOCODINGRUNNERMANAGER_H
#define MARBLE_REVERSEGEOCODINGRUNNERMANAGER_H
#include <QObject>
#include "marble_export.h"
class QAbstractItemModel;
namespace Marble
{
class GeoDataCoordinates;
class GeoDataPlacemark;
class MarbleModel;
class ReverseGeocodingTask;
class MARBLE_EXPORT ReverseGeocodingRunnerManager : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
* @param pluginManager The plugin manager that gives access to RunnerPlugins
* @param parent Optional parent object
*/
- explicit ReverseGeocodingRunnerManager( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit ReverseGeocodingRunnerManager( const MarbleModel *marbleModel, QObject *parent = nullptr );
~ReverseGeocodingRunnerManager() override;
/**
* Find the address and other meta information for a given geoposition.
* @see reverseGeocoding is asynchronous with currently one result
* returned using the @see reverseGeocodingFinished signal.
* @see searchReverseGeocoding is blocking.
* @see reverseGeocodingFinished signal indicates all runners are finished.
*/
void reverseGeocoding( const GeoDataCoordinates &coordinates );
QString searchReverseGeocoding( const GeoDataCoordinates &coordinates, int timeout = 30000 );
Q_SIGNALS:
/**
* The reverse geocoding request is finished, the result is stored
* in the given placemark. This signal is emitted when the first
* runner found a result, subsequent results are discarded and do not
* emit further signals. If no result is found, this signal is emitted
* with an empty (default constructed) placemark.
*/
void reverseGeocodingFinished( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark );
/**
* Emitted whenever all runners are finished for the query
*/
void reverseGeocodingFinished();
private:
Q_PRIVATE_SLOT( d, void addReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark ) )
Q_PRIVATE_SLOT( d, void cleanupReverseGeocodingTask( ReverseGeocodingTask *task ) )
class Private;
friend class Private;
Private *const d;
};
}
#endif
diff --git a/src/lib/marble/ReverseGeocodingRunnerPlugin.h b/src/lib/marble/ReverseGeocodingRunnerPlugin.h
index 39aff2deb..4723c8343 100644
--- a/src/lib/marble/ReverseGeocodingRunnerPlugin.h
+++ b/src/lib/marble/ReverseGeocodingRunnerPlugin.h
@@ -1,82 +1,82 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_REVERSEGEOCODINGRUNNERPLUGIN_H
#define MARBLE_REVERSEGEOCODINGRUNNERPLUGIN_H
#include <QObject>
#include "PluginInterface.h"
namespace Marble
{
class ReverseGeocodingRunner;
/**
* A plugin for Marble to execute a reverse geocoding task.
*/
class MARBLE_EXPORT ReverseGeocodingRunnerPlugin : public QObject, public PluginInterface
{
Q_OBJECT
public:
/** Constructor with optional parent object */
- explicit ReverseGeocodingRunnerPlugin( QObject* parent = 0 );
+ explicit ReverseGeocodingRunnerPlugin( QObject* parent = nullptr );
/** Destructor */
~ReverseGeocodingRunnerPlugin() override;
/**
* @brief Returns the string that should appear in the user interface.
*
* For example, "Nominatim" should be returned for the Nominatim reverse geocoding plugin.
*/
virtual QString guiString() const = 0;
/** Plugin factory method to create a new runner instance.
* Method caller gets ownership of the returned object
*/
virtual ReverseGeocodingRunner *newRunner() const = 0;
/** True if the plugin supports its tasks on the given planet */
bool supportsCelestialBody( const QString &celestialBodyId ) const;
/** True if the plugin can execute its tasks without network access */
bool canWorkOffline() const;
/**
* @brief Returns @code true @endcode if the plugin is able to perform its claimed task.
*
* The default implementation returns @code true @endcode. This method can be
* overridden for example to indicate an incomplete installation.
*/
virtual bool canWork() const;
// Overridden methods with default implementations
QIcon icon() const override;
protected:
void setSupportedCelestialBodies( const QStringList &celestialBodies );
void setCanWorkOffline( bool canWorkOffline );
private:
class Private;
Private * const d;
};
}
Q_DECLARE_INTERFACE( Marble::ReverseGeocodingRunnerPlugin, "org.kde.Marble.ReverseGeocodingRunnerPlugin/1.01" )
#endif // MARBLE_REVERSEGEOCODINGRUNNERPLUGIN_H
diff --git a/src/lib/marble/RoutingRunnerManager.cpp b/src/lib/marble/RoutingRunnerManager.cpp
index 1fd22eea6..84864e73d 100644
--- a/src/lib/marble/RoutingRunnerManager.cpp
+++ b/src/lib/marble/RoutingRunnerManager.cpp
@@ -1,173 +1,173 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#include "RoutingRunnerManager.h"
#include "MarblePlacemarkModel.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "Planet.h"
#include "GeoDataDocument.h"
#include "PluginManager.h"
#include "RoutingRunnerPlugin.h"
#include "RunnerTask.h"
#include "routing/RouteRequest.h"
#include "routing/RoutingProfilesModel.h"
#include <QThreadPool>
#include <QTimer>
namespace Marble
{
class MarbleModel;
class Q_DECL_HIDDEN RoutingRunnerManager::Private
{
public:
Private( RoutingRunnerManager *parent, const MarbleModel *marbleModel );
~Private();
template<typename T>
QList<T*> plugins( const QList<T*> &plugins ) const;
void addRoutingResult( GeoDataDocument *route );
void cleanupRoutingTask( RoutingTask *task );
RoutingRunnerManager *const q;
const MarbleModel *const m_marbleModel;
const PluginManager *const m_pluginManager;
QList<RoutingTask*> m_routingTasks;
QVector<GeoDataDocument*> m_routingResult;
};
RoutingRunnerManager::Private::Private( RoutingRunnerManager *parent, const MarbleModel *marbleModel ) :
q( parent ),
m_marbleModel( marbleModel ),
m_pluginManager( marbleModel->pluginManager() )
{
qRegisterMetaType<GeoDataDocument*>( "GeoDataDocument*" );
}
RoutingRunnerManager::Private::~Private()
{
// nothing to do
}
template<typename T>
QList<T*> RoutingRunnerManager::Private::plugins( const QList<T*> &plugins ) const
{
QList<T*> result;
for( T* plugin: plugins ) {
if ( ( m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline() ) ) {
continue;
}
if ( !plugin->canWork() ) {
continue;
}
if ( m_marbleModel && !plugin->supportsCelestialBody( m_marbleModel->planet()->id() ) )
{
continue;
}
result << plugin;
}
return result;
}
void RoutingRunnerManager::Private::addRoutingResult( GeoDataDocument *route )
{
if ( route ) {
mDebug() << "route retrieved";
m_routingResult.push_back( route );
emit q->routeRetrieved( route );
}
}
void RoutingRunnerManager::Private::cleanupRoutingTask( RoutingTask *task )
{
m_routingTasks.removeAll( task );
mDebug() << "removing task" << m_routingTasks.size() << " " << (quintptr)task;
if ( m_routingTasks.isEmpty() ) {
if ( m_routingResult.isEmpty() ) {
- emit q->routeRetrieved( 0 );
+ emit q->routeRetrieved( nullptr );
}
emit q->routingFinished();
}
}
RoutingRunnerManager::RoutingRunnerManager( const MarbleModel *marbleModel, QObject *parent )
: QObject( parent ),
d( new Private( this, marbleModel ) )
{
if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
QThreadPool::globalInstance()->setMaxThreadCount( 4 );
}
}
RoutingRunnerManager::~RoutingRunnerManager()
{
delete d;
}
void RoutingRunnerManager::retrieveRoute( const RouteRequest *request )
{
RoutingProfile profile = request->routingProfile();
d->m_routingTasks.clear();
d->m_routingResult.clear();
QList<RoutingRunnerPlugin*> plugins = d->plugins( d->m_pluginManager->routingRunnerPlugins() );
for( RoutingRunnerPlugin* plugin: plugins ) {
if ( !profile.name().isEmpty() && !profile.pluginSettings().contains( plugin->nameId() ) ) {
continue;
}
RoutingTask* task = new RoutingTask( plugin->newRunner(), this, request );
connect( task, SIGNAL(finished(RoutingTask*)), this, SLOT(cleanupRoutingTask(RoutingTask*)) );
mDebug() << "route task" << plugin->nameId() << " " << (quintptr)task;
d->m_routingTasks << task;
}
for( RoutingTask* task: d->m_routingTasks ) {
QThreadPool::globalInstance()->start( task );
}
if ( d->m_routingTasks.isEmpty() ) {
mDebug() << "No suitable routing plugins found, cannot retrieve a route";
- d->cleanupRoutingTask( 0 );
+ d->cleanupRoutingTask( nullptr );
}
}
QVector<GeoDataDocument*> RoutingRunnerManager::searchRoute( const RouteRequest *request, int timeout ) {
QEventLoop localEventLoop;
QTimer watchdog;
watchdog.setSingleShot(true);
connect( &watchdog, SIGNAL(timeout()),
&localEventLoop, SLOT(quit()));
connect(this, SIGNAL(routingFinished()),
&localEventLoop, SLOT(quit()), Qt::QueuedConnection );
watchdog.start( timeout );
retrieveRoute( request );
localEventLoop.exec();
return d->m_routingResult;
}
}
#include "moc_RoutingRunnerManager.cpp"
diff --git a/src/lib/marble/RoutingRunnerManager.h b/src/lib/marble/RoutingRunnerManager.h
index 69f08037e..bb1464ce1 100644
--- a/src/lib/marble/RoutingRunnerManager.h
+++ b/src/lib/marble/RoutingRunnerManager.h
@@ -1,75 +1,75 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLE_ROUTINGRUNNERMANAGER_H
#define MARBLE_ROUTINGRUNNERMANAGER_H
#include <QObject>
#include <QVector>
#include "marble_export.h"
namespace Marble
{
class GeoDataDocument;
class MarbleModel;
class RouteRequest;
class RoutingTask;
class MARBLE_EXPORT RoutingRunnerManager : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
* @param pluginManager The plugin manager that gives access to RunnerPlugins
* @param parent Optional parent object
*/
- explicit RoutingRunnerManager( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit RoutingRunnerManager( const MarbleModel *marbleModel, QObject *parent = nullptr );
~RoutingRunnerManager() override;
/**
* Download routes traversing the stopover points in the given route request
* @see retrieveRoute is asynchronous with results returned using the
* @see routeRetrieved signal.
* @see searchRoute is blocking.
* @see routingFinished signal indicates all runners are finished.
*/
void retrieveRoute( const RouteRequest *request );
QVector<GeoDataDocument *> searchRoute( const RouteRequest *request, int timeout = 30000 );
Q_SIGNALS:
/**
* A route was retrieved
*/
void routeRetrieved( GeoDataDocument *route );
/**
* Emitted whenever all runners are finished for the query
*/
void routingFinished();
private:
Q_PRIVATE_SLOT( d, void addRoutingResult( GeoDataDocument *route ) )
Q_PRIVATE_SLOT( d, void cleanupRoutingTask( RoutingTask *task ) )
class Private;
friend class Private;
Private *const d;
};
}
#endif
diff --git a/src/lib/marble/RoutingRunnerPlugin.cpp b/src/lib/marble/RoutingRunnerPlugin.cpp
index cd774abd5..10dce08f7 100644
--- a/src/lib/marble/RoutingRunnerPlugin.cpp
+++ b/src/lib/marble/RoutingRunnerPlugin.cpp
@@ -1,110 +1,110 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "RoutingRunnerPlugin.h"
#include <QIcon>
namespace Marble
{
class Q_DECL_HIDDEN RoutingRunnerPlugin::Private
{
public:
QStringList m_supportedCelestialBodies;
bool m_canWorkOffline;
QString m_statusMessage;
Private();
};
RoutingRunnerPlugin::Private::Private()
: m_canWorkOffline( true )
{
// nothing to do
}
RoutingRunnerPlugin::RoutingRunnerPlugin( QObject *parent ) :
QObject( parent ),
d( new Private )
{
}
RoutingRunnerPlugin::~RoutingRunnerPlugin()
{
delete d;
}
QIcon RoutingRunnerPlugin::icon() const
{
return QIcon();
}
bool RoutingRunnerPlugin::supportsCelestialBody( const QString &celestialBodyId ) const
{
if ( d->m_supportedCelestialBodies.isEmpty() ) {
return true;
}
return d->m_supportedCelestialBodies.contains( celestialBodyId );
}
void RoutingRunnerPlugin::setSupportedCelestialBodies( const QStringList &celestialBodies )
{
d->m_supportedCelestialBodies = celestialBodies;
}
void RoutingRunnerPlugin::setCanWorkOffline( bool canWorkOffline )
{
d->m_canWorkOffline = canWorkOffline;
}
bool RoutingRunnerPlugin::canWorkOffline() const
{
return d->m_canWorkOffline;
}
bool RoutingRunnerPlugin::canWork() const
{
return true;
}
RoutingRunnerPlugin::ConfigWidget *RoutingRunnerPlugin::configWidget()
{
- return 0;
+ return nullptr;
}
bool RoutingRunnerPlugin::supportsTemplate( RoutingProfilesModel::ProfileTemplate ) const
{
return false;
}
QHash< QString, QVariant > RoutingRunnerPlugin::templateSettings( RoutingProfilesModel::ProfileTemplate ) const
{
return QHash< QString, QVariant >();
}
QString RoutingRunnerPlugin::statusMessage() const
{
return d->m_statusMessage;
}
void RoutingRunnerPlugin::setStatusMessage( const QString &message )
{
d->m_statusMessage = message;
}
}
#include "moc_RoutingRunnerPlugin.cpp"
diff --git a/src/lib/marble/RoutingRunnerPlugin.h b/src/lib/marble/RoutingRunnerPlugin.h
index 1155a1b27..225ee614e 100644
--- a/src/lib/marble/RoutingRunnerPlugin.h
+++ b/src/lib/marble/RoutingRunnerPlugin.h
@@ -1,112 +1,112 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_ROUTINGRUNNERPLUGIN_H
#define MARBLE_ROUTINGRUNNERPLUGIN_H
#include <QObject>
#include "PluginInterface.h"
#include <QHash>
#include <QWidget>
#include "routing/RoutingProfilesModel.h"
namespace Marble
{
class MarbleAbstractRunner;
class RoutingRunner;
/**
* A plugin for Marble to execute a routing task.
*/
class MARBLE_EXPORT RoutingRunnerPlugin : public QObject, public PluginInterface
{
Q_OBJECT
public:
/** Constructor with optional parent object */
- explicit RoutingRunnerPlugin( QObject* parent = 0 );
+ explicit RoutingRunnerPlugin( QObject* parent = nullptr );
/** Destructor */
~RoutingRunnerPlugin() override;
/**
* @brief Returns the string that should appear in the user interface.
*
* For example, "OpenRouteService" should be returned for the OpenRouteService routing plugin.
*/
virtual QString guiString() const = 0;
/** Plugin factory method to create a new runner instance.
* Method caller gets ownership of the returned object
*/
virtual RoutingRunner *newRunner() const = 0;
/** True if the plugin supports its tasks on the given planet */
bool supportsCelestialBody( const QString &celestialBodyId ) const;
/** True if the plugin can execute its tasks without network access */
bool canWorkOffline() const;
/**
* @brief Returns @code true @endcode if the plugin is able to perform its claimed task.
*
* The default implementation returns @code true @endcode. This method can be
* overridden for example to indicate an incomplete installation.
*/
virtual bool canWork() const;
// Overridden methods with default implementations
QIcon icon() const override;
/** A status message showing whether the plugin will be able to deliver results */
QString statusMessage() const;
class ConfigWidget : public QWidget
{
public:
virtual void loadSettings( const QHash<QString, QVariant> &settings ) = 0;
virtual QHash<QString, QVariant> settings() const = 0;
};
/**
* @brief Method for getting a pointer to the configuration widget of the plugin.
*
* @return The configuration widget or, if no configuration widget exists, 0.
*/
virtual ConfigWidget *configWidget();
/** True if the plugin supports the given routing profile template */
virtual bool supportsTemplate( RoutingProfilesModel::ProfileTemplate profileTemplate ) const;
/** Settings for the given routing profile template */
virtual QHash<QString, QVariant> templateSettings( RoutingProfilesModel::ProfileTemplate profileTemplate ) const;
protected:
void setStatusMessage( const QString &message );
void setSupportedCelestialBodies( const QStringList &celestialBodies );
void setCanWorkOffline( bool canWorkOffline );
private:
class Private;
Private *const d;
};
}
Q_DECLARE_INTERFACE( Marble::RoutingRunnerPlugin, "org.kde.Marble.RunnerRunnerPlugin/1.01" )
#endif // MARBLE_ROUTINGRUNNERPLUGIN_H
diff --git a/src/lib/marble/ScanlineTextureMapperContext.cpp b/src/lib/marble/ScanlineTextureMapperContext.cpp
index cb1296649..29f14f3ad 100644
--- a/src/lib/marble/ScanlineTextureMapperContext.cpp
+++ b/src/lib/marble/ScanlineTextureMapperContext.cpp
@@ -1,507 +1,507 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Carlos Licea <carlos _licea@hotmail.com>
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de
//
#include "ScanlineTextureMapperContext.h"
#include "GeoSceneAbstractTileProjection.h"
#include "MarbleDebug.h"
#include "StackedTile.h"
#include "StackedTileLoader.h"
#include "TileId.h"
#include "ViewParams.h"
#include "ViewportParams.h"
#include <QImage>
using namespace Marble;
ScanlineTextureMapperContext::ScanlineTextureMapperContext( StackedTileLoader * const tileLoader, int tileLevel )
: m_tileLoader( tileLoader ),
m_textureProjection(tileLoader->tileProjection()->type()), // cache texture projection
m_tileSize( tileLoader->tileSize() ), // cache tile size
m_tileLevel( tileLevel ),
m_globalWidth( m_tileSize.width() * m_tileLoader->tileColumnCount( m_tileLevel ) ),
m_globalHeight( m_tileSize.height() * m_tileLoader->tileRowCount( m_tileLevel ) ),
m_normGlobalWidth( m_globalWidth / ( 2 * M_PI ) ),
m_normGlobalHeight( m_globalHeight / M_PI ),
- m_tile( 0 ),
+ m_tile( nullptr ),
m_tilePosX( 65535 ),
m_tilePosY( 65535 ),
m_toTileCoordinatesLon( 0.5 * m_globalWidth - m_tilePosX ),
m_toTileCoordinatesLat( 0.5 * m_globalHeight - m_tilePosY ),
m_prevLat( 0.0 ),
m_prevLon( 0.0 ),
m_prevPixelX( 0.0 ),
m_prevPixelY( 0.0 )
{
}
void ScanlineTextureMapperContext::pixelValueF( const qreal lon, const qreal lat,
QRgb* const scanLine )
{
// The same method using integers performs about 33% faster.
// However we need the qreal version to create the high quality mode.
// Convert the lon and lat coordinates of the position on the scanline
// measured in radian to the pixel position of the requested
// coordinate on the current tile.
m_prevPixelX = rad2PixelX( lon );
m_prevPixelY = rad2PixelY( lat );
qreal posX = m_toTileCoordinatesLon + m_prevPixelX;
qreal posY = m_toTileCoordinatesLat + m_prevPixelY;
// Most of the time while moving along the scanLine we'll stay on the
// same tile. However at the tile border we might "fall off". If that
// happens we need to find out the next tile that needs to be loaded.
if ( posX >= (qreal)( m_tileSize.width() )
|| posX < 0.0
|| posY >= (qreal)( m_tileSize.height() )
|| posY < 0.0 )
{
nextTile( posX, posY );
}
if ( m_tile ) {
*scanLine = m_tile->pixelF( posX, posY );
}
else {
*scanLine = 0;
}
m_prevLon = lon;
m_prevLat = lat; // preparing for interpolation
}
void ScanlineTextureMapperContext::pixelValue( const qreal lon, const qreal lat,
QRgb* const scanLine )
{
// The same method using integers performs about 33% faster.
// However we need the qreal version to create the high quality mode.
// Convert the lon and lat coordinates of the position on the scanline
// measured in radian to the pixel position of the requested
// coordinate on the current tile.
m_prevPixelX = rad2PixelX( lon );
m_prevPixelY = rad2PixelY( lat );
int iPosX = (int)( m_toTileCoordinatesLon + m_prevPixelX );
int iPosY = (int)( m_toTileCoordinatesLat + m_prevPixelY );
// Most of the time while moving along the scanLine we'll stay on the
// same tile. However at the tile border we might "fall off". If that
// happens we need to find out the next tile that needs to be loaded.
if ( iPosX >= m_tileSize.width()
|| iPosX < 0
|| iPosY >= m_tileSize.height()
|| iPosY < 0 )
{
nextTile( iPosX, iPosY );
}
if ( m_tile ) {
*scanLine = m_tile->pixel( iPosX, iPosY );
}
else {
*scanLine = 0;
}
m_prevLon = lon;
m_prevLat = lat; // preparing for interpolation
}
// This method interpolates color values for skipped pixels in a scanline.
//
// While moving along the scanline we don't move from pixel to pixel but
// leave out n pixels each time and calculate the exact position and
// color value for the new pixel. The pixel values in between get
// approximated through linear interpolation across the direct connecting
// line on the original tiles directly.
// This method will do by far most of the calculations for the
// texturemapping, so we move towards integer math to improve speed.
void ScanlineTextureMapperContext::pixelValueApproxF( const qreal lon, const qreal lat,
QRgb *scanLine, const int n )
{
// stepLon/Lat: Distance between two subsequent approximated positions
qreal stepLat = lat - m_prevLat;
qreal stepLon = lon - m_prevLon;
// As long as the distance is smaller than 180 deg we can assume that
// we didn't cross the dateline.
const qreal nInverse = 1.0 / (qreal)(n);
if ( fabs(stepLon) < M_PI ) {
const qreal itStepLon = ( rad2PixelX( lon ) - m_prevPixelX ) * nInverse;
const qreal itStepLat = ( rad2PixelY( lat ) - m_prevPixelY ) * nInverse;
// To improve speed we unroll
// AbstractScanlineTextureMapper::pixelValue(...) here and
// calculate the performance critical issues via integers
qreal itLon = m_prevPixelX + m_toTileCoordinatesLon;
qreal itLat = m_prevPixelY + m_toTileCoordinatesLat;
const int tileWidth = m_tileSize.width();
const int tileHeight = m_tileSize.height();
// int oldR = 0;
// int oldG = 0;
// int oldB = 0;
QRgb oldRgb = qRgb( 0, 0, 0 );
qreal oldPosX = -1;
qreal oldPosY = 0;
const bool alwaysCheckTileRange =
isOutOfTileRangeF( itLon, itLat, itStepLon, itStepLat, n );
for ( int j=1; j < n; ++j ) {
qreal posX = itLon + itStepLon * j;
qreal posY = itLat + itStepLat * j;
if ( alwaysCheckTileRange )
if ( posX >= tileWidth
|| posX < 0.0
|| posY >= tileHeight
|| posY < 0.0 )
{
nextTile( posX, posY );
itLon = m_prevPixelX + m_toTileCoordinatesLon;
itLat = m_prevPixelY + m_toTileCoordinatesLat;
posX = qBound <qreal>( 0.0, (itLon + itStepLon * j), tileWidth-1.0 );
posY = qBound <qreal>( 0.0, (itLat + itStepLat * j), tileHeight-1.0 );
oldPosX = -1;
}
*scanLine = m_tile->pixelF( posX, posY );
// Just perform bilinear interpolation if there's a color change compared to the
// last pixel that was evaluated. This speeds up things greatly for maps like OSM
if ( *scanLine != oldRgb ) {
if ( oldPosX != -1 ) {
*(scanLine - 1) = m_tile->pixelF( oldPosX, oldPosY, *(scanLine - 1) );
oldPosX = -1;
}
oldRgb = m_tile->pixelF( posX, posY, *scanLine );
*scanLine = oldRgb;
}
else {
oldPosX = posX;
oldPosY = posY;
}
// if ( needsFilter( *scanLine, oldR, oldB, oldG ) ) {
// *scanLine = m_tile->pixelF( posX, posY );
// }
++scanLine;
}
}
// For the case where we cross the dateline between (lon, lat) and
// (prevlon, prevlat) we need a more sophisticated calculation.
// However as this will happen rather rarely, we use
// pixelValue(...) directly to make the code more readable.
else {
stepLon = ( TWOPI - fabs(stepLon) ) * nInverse;
stepLat = stepLat * nInverse;
// We need to distinguish two cases:
// crossing the dateline from east to west ...
if ( m_prevLon < lon ) {
for ( int j = 1; j < n; ++j ) {
m_prevLat += stepLat;
m_prevLon -= stepLon;
if ( m_prevLon <= -M_PI )
m_prevLon += TWOPI;
pixelValueF( m_prevLon, m_prevLat, scanLine );
++scanLine;
}
}
// ... and vice versa: from west to east.
else {
qreal curStepLon = lon - n * stepLon;
for ( int j = 1; j < n; ++j ) {
m_prevLat += stepLat;
curStepLon += stepLon;
qreal evalLon = curStepLon;
if ( curStepLon <= -M_PI )
evalLon += TWOPI;
pixelValueF( evalLon, m_prevLat, scanLine );
++scanLine;
}
}
}
}
bool ScanlineTextureMapperContext::isOutOfTileRangeF( const qreal itLon, const qreal itLat,
const qreal itStepLon, const qreal itStepLat,
const int n ) const
{
const qreal minIPosX = itLon + itStepLon;
const qreal minIPosY = itLat + itStepLat;
const qreal maxIPosX = itLon + itStepLon * ( n - 1 );
const qreal maxIPosY = itLat + itStepLat * ( n - 1 );
return ( maxIPosX >= m_tileSize.width() || maxIPosX < 0
|| maxIPosY >= m_tileSize.height() || maxIPosY < 0
|| minIPosX >= m_tileSize.width() || minIPosX < 0
|| minIPosY >= m_tileSize.height() || minIPosY < 0 );
}
void ScanlineTextureMapperContext::pixelValueApprox( const qreal lon, const qreal lat,
QRgb *scanLine, const int n )
{
// stepLon/Lat: Distance between two subsequent approximated positions
qreal stepLat = lat - m_prevLat;
qreal stepLon = lon - m_prevLon;
// As long as the distance is smaller than 180 deg we can assume that
// we didn't cross the dateline.
const qreal nInverse = 1.0 / (qreal)(n);
if ( fabs(stepLon) < M_PI ) {
const int itStepLon = (int)( ( rad2PixelX( lon ) - m_prevPixelX ) * nInverse * 128.0 );
const int itStepLat = (int)( ( rad2PixelY( lat ) - m_prevPixelY ) * nInverse * 128.0 );
// To improve speed we unroll
// AbstractScanlineTextureMapper::pixelValue(...) here and
// calculate the performance critical issues via integers
int itLon = (int)( ( m_prevPixelX + m_toTileCoordinatesLon ) * 128.0 );
int itLat = (int)( ( m_prevPixelY + m_toTileCoordinatesLat ) * 128.0 );
const int tileWidth = m_tileSize.width();
const int tileHeight = m_tileSize.height();
const bool alwaysCheckTileRange =
isOutOfTileRange( itLon, itLat, itStepLon, itStepLat, n );
if ( !alwaysCheckTileRange ) {
int iPosXf = itLon;
int iPosYf = itLat;
for ( int j = 1; j < n; ++j ) {
iPosXf += itStepLon;
iPosYf += itStepLat;
*scanLine = m_tile->pixel( iPosXf >> 7, iPosYf >> 7 );
++scanLine;
}
}
else {
for ( int j = 1; j < n; ++j ) {
int iPosX = ( itLon + itStepLon * j ) >> 7;
int iPosY = ( itLat + itStepLat * j ) >> 7;
if ( iPosX >= tileWidth
|| iPosX < 0
|| iPosY >= tileHeight
|| iPosY < 0 )
{
nextTile( iPosX, iPosY );
itLon = (int)( ( m_prevPixelX + m_toTileCoordinatesLon ) * 128.0 );
itLat = (int)( ( m_prevPixelY + m_toTileCoordinatesLat ) * 128.0 );
iPosX = ( itLon + itStepLon * j ) >> 7;
iPosY = ( itLat + itStepLat * j ) >> 7;
}
*scanLine = m_tile->pixel( iPosX, iPosY );
++scanLine;
}
}
}
// For the case where we cross the dateline between (lon, lat) and
// (prevlon, prevlat) we need a more sophisticated calculation.
// However as this will happen rather rarely, we use
// pixelValue(...) directly to make the code more readable.
else {
stepLon = ( TWOPI - fabs(stepLon) ) * nInverse;
stepLat = stepLat * nInverse;
// We need to distinguish two cases:
// crossing the dateline from east to west ...
if ( m_prevLon < lon ) {
for ( int j = 1; j < n; ++j ) {
m_prevLat += stepLat;
m_prevLon -= stepLon;
if ( m_prevLon <= -M_PI )
m_prevLon += TWOPI;
pixelValue( m_prevLon, m_prevLat, scanLine );
++scanLine;
}
}
// ... and vice versa: from west to east.
else {
qreal curStepLon = lon - n * stepLon;
for ( int j = 1; j < n; ++j ) {
m_prevLat += stepLat;
curStepLon += stepLon;
qreal evalLon = curStepLon;
if ( curStepLon <= -M_PI )
evalLon += TWOPI;
pixelValue( evalLon, m_prevLat, scanLine );
++scanLine;
}
}
}
}
bool ScanlineTextureMapperContext::isOutOfTileRange( const int itLon, const int itLat,
const int itStepLon, const int itStepLat,
const int n ) const
{
const int minIPosX = ( itLon + itStepLon ) >> 7;
const int minIPosY = ( itLat + itStepLat ) >> 7;
const int maxIPosX = ( itLon + itStepLon * ( n - 1 ) ) >> 7;
const int maxIPosY = ( itLat + itStepLat * ( n - 1 ) ) >> 7;
return ( maxIPosX >= m_tileSize.width() || maxIPosX < 0
|| maxIPosY >= m_tileSize.height() || maxIPosY < 0
|| minIPosX >= m_tileSize.width() || minIPosX < 0
|| minIPosY >= m_tileSize.height() || minIPosY < 0 );
}
int ScanlineTextureMapperContext::interpolationStep( const ViewportParams *viewport, MapQuality mapQuality )
{
if ( mapQuality == PrintQuality ) {
return 1; // Don't interpolate for print quality.
}
if ( ! viewport->mapCoversViewport() ) {
return 8;
}
// Find the optimal interpolation interval m_nBest for the
// current image canvas width
const int width = viewport->width();
int nBest = 2;
int nEvalMin = width - 1;
for ( int it = 1; it < 48; ++it ) {
int nEval = ( width - 1 ) / it + ( width - 1 ) % it;
if ( nEval < nEvalMin ) {
nEvalMin = nEval;
nBest = it;
}
}
return nBest;
}
QImage::Format ScanlineTextureMapperContext::optimalCanvasImageFormat( const ViewportParams *viewport )
{
// If the globe covers fully the screen then we can use the faster
// RGB32 as there are no translucent areas involved.
QImage::Format imageFormat = ( viewport->mapCoversViewport() )
? QImage::Format_RGB32
: QImage::Format_ARGB32_Premultiplied;
return imageFormat;
}
void ScanlineTextureMapperContext::nextTile( int &posX, int &posY )
{
// Move from tile coordinates to global texture coordinates
// ( with origin in upper left corner, measured in pixel)
int lon = posX + m_tilePosX;
if ( lon >= m_globalWidth )
lon -= m_globalWidth;
else if ( lon < 0 )
lon += m_globalWidth;
int lat = posY + m_tilePosY;
if ( lat >= m_globalHeight )
lat -= m_globalHeight;
else if ( lat < 0 )
lat += m_globalHeight;
// tileCol counts the tile columns left from the current tile.
// tileRow counts the tile rows on the top from the current tile.
const int tileCol = lon / m_tileSize.width();
const int tileRow = lat / m_tileSize.height();
m_tile = m_tileLoader->loadTile( TileId( 0, m_tileLevel, tileCol, tileRow ) );
// Update position variables:
// m_tilePosX/Y stores the position of the tiles in
// global texture coordinates
// ( origin upper left, measured in pixels )
m_tilePosX = tileCol * m_tileSize.width();
m_toTileCoordinatesLon = (qreal)(0.5 * m_globalWidth - m_tilePosX);
posX = lon - m_tilePosX;
m_tilePosY = tileRow * m_tileSize.height();
m_toTileCoordinatesLat = (qreal)(0.5 * m_globalHeight - m_tilePosY);
posY = lat - m_tilePosY;
}
void ScanlineTextureMapperContext::nextTile( qreal &posX, qreal &posY )
{
// Move from tile coordinates to global texture coordinates
// ( with origin in upper left corner, measured in pixel)
int lon = (int)(posX + m_tilePosX);
if ( lon >= m_globalWidth )
lon -= m_globalWidth;
else if ( lon < 0 )
lon += m_globalWidth;
int lat = (int)(posY + m_tilePosY);
if ( lat >= m_globalHeight )
lat -= m_globalHeight;
else if ( lat < 0 )
lat += m_globalHeight;
// tileCol counts the tile columns left from the current tile.
// tileRow counts the tile rows on the top from the current tile.
const int tileCol = lon / m_tileSize.width();
const int tileRow = lat / m_tileSize.height();
m_tile = m_tileLoader->loadTile( TileId( 0, m_tileLevel, tileCol, tileRow ) );
// Update position variables:
// m_tilePosX/Y stores the position of the tiles in
// global texture coordinates
// ( origin upper left, measured in pixels )
m_tilePosX = tileCol * m_tileSize.width();
m_toTileCoordinatesLon = (qreal)(0.5 * m_globalWidth - m_tilePosX);
posX = lon - m_tilePosX;
m_tilePosY = tileRow * m_tileSize.height();
m_toTileCoordinatesLat = (qreal)(0.5 * m_globalHeight - m_tilePosY);
posY = lat - m_tilePosY;
}
diff --git a/src/lib/marble/SearchInputWidget.h b/src/lib/marble/SearchInputWidget.h
index af350e20f..2a650f4c6 100644
--- a/src/lib/marble/SearchInputWidget.h
+++ b/src/lib/marble/SearchInputWidget.h
@@ -1,68 +1,68 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_SEARCHINPUTWIDGET_H
#define MARBLE_SEARCHINPUTWIDGET_H
#include <QSortFilterProxyModel>
#include "MarbleLineEdit.h"
#include "MarbleGlobal.h"
#include "marble_export.h"
class QAbstractItemModel;
class QCompleter;
class QModelIndex;
namespace Marble {
class GeoDataCoordinates;
class MARBLE_EXPORT SearchInputWidget : public MarbleLineEdit
{
Q_OBJECT
public:
- explicit SearchInputWidget( QWidget* parent = 0 );
+ explicit SearchInputWidget( QWidget* parent = nullptr );
void setCompletionModel( QAbstractItemModel *completionModel );
public Q_SLOTS:
void disableSearchAnimation();
Q_SIGNALS:
void search( const QString &searchTerm, SearchMode searchMode );
void centerOn( const GeoDataCoordinates &coordinates );
private Q_SLOTS:
void search();
void centerOnSearchSuggestion( const QModelIndex &suggestionIndex );
void showDropDownMenu();
void setGlobalSearch();
void setAreaSearch();
private:
void updatePlaceholderText();
QSortFilterProxyModel m_sortFilter;
QCompleter *const m_completer;
bool m_areaSearch;
};
}
#endif
diff --git a/src/lib/marble/SearchRunner.h b/src/lib/marble/SearchRunner.h
index 094c8a423..9b6e7e9d9 100644
--- a/src/lib/marble/SearchRunner.h
+++ b/src/lib/marble/SearchRunner.h
@@ -1,66 +1,66 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012,2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
#ifndef MARBLE_SEARCHRUNNER_H
#define MARBLE_SEARCHRUNNER_H
#include "marble_export.h"
#include <QObject>
#include <QVector>
namespace Marble
{
class GeoDataLatLonBox;
class GeoDataPlacemark;
class MarbleModel;
class MARBLE_EXPORT SearchRunner : public QObject
{
Q_OBJECT
public:
- explicit SearchRunner( QObject *parent = 0 );
+ explicit SearchRunner( QObject *parent = nullptr );
/**
* Stores a pointer to the currently used model
*/
void setModel( const MarbleModel *model );
/**
* Start a placemark search. Called by MarbleRunnerManager, runners
* are expected to return the result via the searchFinished signal.
* If implemented in a plugin, make sure to include Search in the
* plugin capabilities, otherwise MarbleRunnerManager will ignore the plugin
*/
virtual void search( const QString &searchTerm, const GeoDataLatLonBox &preferred ) = 0;
Q_SIGNALS:
/**
* This is emitted to indicate that the runner has finished the placemark search.
* @param result the result of the search.
*/
void searchFinished( const QVector<GeoDataPlacemark*>& result );
protected:
/**
* Access to the currently used model, or null if no was set with @see setModel
*/
const MarbleModel *model() const;
private:
const MarbleModel *m_model;
};
}
#endif
diff --git a/src/lib/marble/SearchRunnerManager.cpp b/src/lib/marble/SearchRunnerManager.cpp
index 6ea9479f1..32ee156ce 100644
--- a/src/lib/marble/SearchRunnerManager.cpp
+++ b/src/lib/marble/SearchRunnerManager.cpp
@@ -1,232 +1,232 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#include "SearchRunnerManager.h"
#include "MarblePlacemarkModel.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "Planet.h"
#include "GeoDataPlacemark.h"
#include "PluginManager.h"
#include "ParseRunnerPlugin.h"
#include "ReverseGeocodingRunnerPlugin.h"
#include "RoutingRunnerPlugin.h"
#include "SearchRunnerPlugin.h"
#include "RunnerTask.h"
#include "routing/RouteRequest.h"
#include "routing/RoutingProfilesModel.h"
#include <QObject>
#include <QString>
#include <QVector>
#include <QThreadPool>
#include <QTimer>
#include <QMutex>
namespace Marble
{
class MarbleModel;
class Q_DECL_HIDDEN SearchRunnerManager::Private
{
public:
Private( SearchRunnerManager *parent, const MarbleModel *marbleModel );
template<typename T>
QList<T*> plugins( const QList<T*> &plugins ) const;
void addSearchResult( const QVector<GeoDataPlacemark *> &result );
void cleanupSearchTask( SearchTask *task );
void notifySearchResultChange();
void notifySearchFinished();
SearchRunnerManager *const q;
const MarbleModel *const m_marbleModel;
const PluginManager* m_pluginManager;
QString m_lastSearchTerm;
GeoDataLatLonBox m_lastPreferredBox;
QMutex m_modelMutex;
MarblePlacemarkModel m_model;
QList<SearchTask *> m_searchTasks;
QVector<GeoDataPlacemark *> m_placemarkContainer;
};
SearchRunnerManager::Private::Private( SearchRunnerManager *parent, const MarbleModel *marbleModel ) :
q( parent ),
m_marbleModel( marbleModel ),
m_pluginManager( marbleModel->pluginManager() ),
m_model( new MarblePlacemarkModel( parent ) )
{
m_model.setPlacemarkContainer( &m_placemarkContainer );
qRegisterMetaType<QVector<GeoDataPlacemark *> >( "QVector<GeoDataPlacemark*>" );
}
template<typename T>
QList<T*> SearchRunnerManager::Private::plugins( const QList<T*> &plugins ) const
{
QList<T*> result;
for( T* plugin: plugins ) {
if ( ( m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline() ) ) {
continue;
}
if ( !plugin->canWork() ) {
continue;
}
if ( m_marbleModel && !plugin->supportsCelestialBody( m_marbleModel->planet()->id() ) )
{
continue;
}
result << plugin;
}
return result;
}
void SearchRunnerManager::Private::addSearchResult( const QVector<GeoDataPlacemark *> &result )
{
mDebug() << "Runner reports" << result.size() << " search results";
if( result.isEmpty() )
return;
m_modelMutex.lock();
int start = m_placemarkContainer.size();
int count = 0;
- bool distanceCompare = m_marbleModel->planet() != 0;
+ bool distanceCompare = m_marbleModel->planet() != nullptr;
for( int i=0; i<result.size(); ++i ) {
bool same = false;
for ( int j=0; j<m_placemarkContainer.size(); ++j ) {
if ( distanceCompare &&
(result[i]->coordinate().sphericalDistanceTo(m_placemarkContainer[j]->coordinate())
* m_marbleModel->planet()->radius() < 1 ) ) {
same = true;
}
}
if ( !same ) {
m_placemarkContainer.append( result[i] );
++count;
}
}
m_model.addPlacemarks( start, count );
m_modelMutex.unlock();
notifySearchResultChange();
}
void SearchRunnerManager::Private::cleanupSearchTask( SearchTask *task )
{
m_searchTasks.removeAll( task );
mDebug() << "removing search task" << m_searchTasks.size() << (quintptr)task;
if ( m_searchTasks.isEmpty() ) {
if( m_placemarkContainer.isEmpty() ) {
notifySearchResultChange();
}
notifySearchFinished();
}
}
void SearchRunnerManager::Private::notifySearchResultChange()
{
emit q->searchResultChanged(&m_model);
emit q->searchResultChanged(m_placemarkContainer);
}
void SearchRunnerManager::Private::notifySearchFinished()
{
emit q->searchFinished(m_lastSearchTerm);
emit q->placemarkSearchFinished();
}
SearchRunnerManager::SearchRunnerManager( const MarbleModel *marbleModel, QObject *parent ) :
QObject( parent ),
d( new Private( this, marbleModel ) )
{
if ( QThreadPool::globalInstance()->maxThreadCount() < 4 ) {
QThreadPool::globalInstance()->setMaxThreadCount( 4 );
}
}
SearchRunnerManager::~SearchRunnerManager()
{
delete d;
}
void SearchRunnerManager::findPlacemarks( const QString &searchTerm, const GeoDataLatLonBox &preferred )
{
if ( searchTerm == d->m_lastSearchTerm && preferred == d->m_lastPreferredBox ) {
d->notifySearchResultChange();
d->notifySearchFinished();
return;
}
d->m_lastSearchTerm = searchTerm;
d->m_lastPreferredBox = preferred;
d->m_searchTasks.clear();
d->m_modelMutex.lock();
bool placemarkContainerChanged = false;
if (!d->m_placemarkContainer.isEmpty()) {
d->m_model.removePlacemarks( "PlacemarkRunnerManager", 0, d->m_placemarkContainer.size() );
qDeleteAll( d->m_placemarkContainer );
d->m_placemarkContainer.clear();
placemarkContainerChanged = true;
}
d->m_modelMutex.unlock();
if (placemarkContainerChanged) {
d->notifySearchResultChange();
}
if ( searchTerm.trimmed().isEmpty() ) {
d->notifySearchFinished();
return;
}
QList<const SearchRunnerPlugin *> plugins = d->plugins( d->m_pluginManager->searchRunnerPlugins() );
for( const SearchRunnerPlugin *plugin: plugins ) {
SearchTask *task = new SearchTask( plugin->newRunner(), this, d->m_marbleModel, searchTerm, preferred );
connect( task, SIGNAL(finished(SearchTask*)), this, SLOT(cleanupSearchTask(SearchTask*)) );
d->m_searchTasks << task;
mDebug() << "search task " << plugin->nameId() << " " << (quintptr)task;
}
for( SearchTask *task: d->m_searchTasks ) {
QThreadPool::globalInstance()->start( task );
}
if ( plugins.isEmpty() ) {
- d->cleanupSearchTask( 0 );
+ d->cleanupSearchTask( nullptr );
}
}
QVector<GeoDataPlacemark *> SearchRunnerManager::searchPlacemarks( const QString &searchTerm, const GeoDataLatLonBox &preferred, int timeout )
{
QEventLoop localEventLoop;
QTimer watchdog;
watchdog.setSingleShot(true);
connect( &watchdog, SIGNAL(timeout()),
&localEventLoop, SLOT(quit()));
connect(this, SIGNAL(placemarkSearchFinished()),
&localEventLoop, SLOT(quit()), Qt::QueuedConnection );
watchdog.start( timeout );
findPlacemarks( searchTerm, preferred );
localEventLoop.exec();
return d->m_placemarkContainer;
}
}
#include "moc_SearchRunnerManager.cpp"
diff --git a/src/lib/marble/SearchRunnerManager.h b/src/lib/marble/SearchRunnerManager.h
index 05225bbe7..877772ae5 100644
--- a/src/lib/marble/SearchRunnerManager.h
+++ b/src/lib/marble/SearchRunnerManager.h
@@ -1,88 +1,88 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLE_SEARCHRUNNERMANAGER_H
#define MARBLE_SEARCHRUNNERMANAGER_H
#include "GeoDataLatLonBox.h"
#include "marble_export.h"
#include <QObject>
#include <QVector>
class QAbstractItemModel;
class QString;
namespace Marble
{
class GeoDataPlacemark;
class MarbleModel;
class SearchTask;
class MARBLE_EXPORT SearchRunnerManager : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
* @param pluginManager The plugin manager that gives access to RunnerPlugins
* @param parent Optional parent object
*/
- explicit SearchRunnerManager( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit SearchRunnerManager( const MarbleModel *marbleModel, QObject *parent = nullptr );
~SearchRunnerManager() override;
/**
* Search for placemarks matching the given search term.
* @see findPlacemark is asynchronous with results returned using the
* @see searchResultChanged signal.
* @see searchPlacemark is blocking.
* @see searchFinished signal indicates all runners are finished.
*/
void findPlacemarks( const QString &searchTerm, const GeoDataLatLonBox &preferred = GeoDataLatLonBox() );
QVector<GeoDataPlacemark *> searchPlacemarks( const QString &searchTerm, const GeoDataLatLonBox &preferred = GeoDataLatLonBox(), int timeout = 30000 );
Q_SIGNALS:
/**
* Placemarks were added to or removed from the model
* @todo FIXME: this sounds like a duplication of QAbstractItemModel signals
*/
void searchResultChanged( QAbstractItemModel *model );
void searchResultChanged( const QVector<GeoDataPlacemark *> &result );
/**
* The search request for the given search term has finished, i.e. all
* runners are finished and reported their results via the
* @see searchResultChanged signal
*/
void searchFinished( const QString &searchTerm );
/**
* Emitted whenever all runners are finished for the query
*/
void placemarkSearchFinished();
private:
Q_PRIVATE_SLOT( d, void addSearchResult( const QVector<GeoDataPlacemark *> &result ) )
Q_PRIVATE_SLOT( d, void cleanupSearchTask( SearchTask *task ) )
class Private;
friend class Private;
Private *const d;
};
}
#endif
diff --git a/src/lib/marble/SearchRunnerPlugin.h b/src/lib/marble/SearchRunnerPlugin.h
index b6ed5ddb7..8365c3252 100644
--- a/src/lib/marble/SearchRunnerPlugin.h
+++ b/src/lib/marble/SearchRunnerPlugin.h
@@ -1,80 +1,80 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLE_SEARCHRUNNERPLUGIN_H
#define MARBLE_SEARCHRUNNERPLUGIN_H
#include <QObject>
#include "PluginInterface.h"
namespace Marble
{
class SearchRunner;
/**
* A plugin for Marble to execute a placemark search.
*/
class MARBLE_EXPORT SearchRunnerPlugin : public QObject, public PluginInterface
{
Q_OBJECT
public:
/** Constructor with optional parent object */
- explicit SearchRunnerPlugin( QObject* parent = 0 );
+ explicit SearchRunnerPlugin( QObject* parent = nullptr );
/** Destructor */
~SearchRunnerPlugin() override;
/**
* @brief Returns the string that should appear in the user interface.
*
* For example, "Nominatim" should be returned for the Nominatim search plugin.
*/
virtual QString guiString() const = 0;
/** Plugin factory method to create a new runner instance.
* Method caller gets ownership of the returned object
*/
virtual SearchRunner *newRunner() const = 0;
/** True if the plugin supports its tasks on the given planet */
bool supportsCelestialBody( const QString &celestialBodyId ) const;
/** True if the plugin can execute its tasks without network access */
bool canWorkOffline() const;
/**
* @brief Returns @code true @endcode if the plugin is able to perform its claimed task.
*
* The default implementation returns @code true @endcode. This method can be
* overridden for example to indicate an incomplete installation.
*/
virtual bool canWork() const;
// Overridden methods with default implementations
QIcon icon() const override;
protected:
void setSupportedCelestialBodies( const QStringList &celestialBodies );
void setCanWorkOffline( bool canWorkOffline );
private:
class Private;
Private *const d;
};
}
Q_DECLARE_INTERFACE( Marble::SearchRunnerPlugin, "org.kde.Marble.SearchRunnerPlugin/1.01" )
#endif // MARBLE_SEARCHRUNNERPLUGIN_H
diff --git a/src/lib/marble/SearchWidget.cpp b/src/lib/marble/SearchWidget.cpp
index 4555f1b4e..8c5bbb230 100644
--- a/src/lib/marble/SearchWidget.cpp
+++ b/src/lib/marble/SearchWidget.cpp
@@ -1,214 +1,214 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "SearchWidget.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataDocument.h"
#include "GeoDataTreeModel.h"
#include "SearchInputWidget.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "BranchFilterProxyModel.h"
#include "MarblePlacemarkModel.h"
#include "SearchRunnerManager.h"
#include "ViewportParams.h"
#include "MarbleDebug.h"
#include <QListView>
#include <QVBoxLayout>
namespace Marble {
class SearchWidgetPrivate
{
public:
SearchRunnerManager* m_runnerManager;
SearchInputWidget *m_searchField;
QListView *m_searchResultView;
MarbleWidget *m_widget;
BranchFilterProxyModel m_branchfilter;
QSortFilterProxyModel m_sortproxy;
GeoDataDocument *m_document;
QString m_planetId;
SearchWidgetPrivate();
void setSearchResult( const QVector<GeoDataPlacemark*>& );
void search( const QString &searchTerm, SearchMode searchMode );
void clearSearch();
void centerMapOn( const QModelIndex &index );
void handlePlanetChange();
};
SearchWidgetPrivate::SearchWidgetPrivate() :
- m_runnerManager( 0 ),
- m_searchField( 0 ),
- m_searchResultView( 0 ),
- m_widget( 0 ),
+ m_runnerManager( nullptr ),
+ m_searchField( nullptr ),
+ m_searchResultView( nullptr ),
+ m_widget( nullptr ),
m_branchfilter(),
m_sortproxy(),
m_document( new GeoDataDocument )
{
m_document->setName( QObject::tr( "Search Results" ) );
}
void SearchWidgetPrivate::setSearchResult( const QVector<GeoDataPlacemark *>& locations )
{
if( locations.isEmpty() ) {
return;
}
QTime timer;
timer.start();
// fill the local document with results
m_widget->model()->placemarkSelectionModel()->clear();
GeoDataTreeModel *treeModel = m_widget->model()->treeModel();
treeModel->removeDocument( m_document );
m_document->clear();
m_document->setName( QString( QObject::tr( "Search for '%1'" ) ).arg( m_searchField->text() ) );
for (GeoDataPlacemark *placemark: locations ) {
m_document->append( new GeoDataPlacemark( *placemark ) );
}
treeModel->addDocument( m_document );
m_branchfilter.setBranchIndex( treeModel, treeModel->index( m_document ) );
m_searchResultView->setRootIndex(
m_sortproxy.mapFromSource(
m_branchfilter.mapFromSource( treeModel->index( m_document ) ) ) );
m_widget->centerOn( m_document->latLonAltBox() );
mDebug() << Q_FUNC_INFO << " Time elapsed:"<< timer.elapsed() << " ms";
}
SearchWidget::SearchWidget( QWidget *parent, Qt::WindowFlags flags ) :
QWidget( parent, flags ),
d( new SearchWidgetPrivate )
{
d->m_sortproxy.setSortRole( MarblePlacemarkModel::PopularityIndexRole );
d->m_sortproxy.sort( 0, Qt::AscendingOrder );
d->m_sortproxy.setDynamicSortFilter( true );
d->m_sortproxy.setSourceModel( &d->m_branchfilter );
d->m_searchField = new SearchInputWidget( this );
setFocusProxy( d->m_searchField );
connect( d->m_searchField, SIGNAL(search(QString,SearchMode)),
this, SLOT(search(QString,SearchMode)) );
d->m_searchResultView = new QListView( this );
d->m_searchResultView->setModel( &d->m_sortproxy );
d->m_searchResultView->setMinimumSize( 0, 0 );
connect( d->m_searchResultView, SIGNAL(activated(QModelIndex)),
this, SLOT(centerMapOn(QModelIndex)) );
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget( d->m_searchField );
layout->addWidget( d->m_searchResultView );
layout->setMargin( 0 );
setLayout( layout );
}
SearchWidget::~SearchWidget()
{
delete d;
}
void SearchWidget::setMarbleWidget( MarbleWidget* widget )
{
if ( d->m_widget ) {
return;
}
d->m_widget = widget;
d->m_planetId = widget->model()->planetId();
connect( widget->model(), SIGNAL(themeChanged(QString)),
this, SLOT(handlePlanetChange()) );
d->m_searchField->setCompletionModel( widget->model()->placemarkModel() );
connect( d->m_searchField, SIGNAL(centerOn(GeoDataCoordinates)),
widget, SLOT(centerOn(GeoDataCoordinates)) );
d->m_runnerManager = new SearchRunnerManager( widget->model(), this );
connect( d->m_runnerManager, SIGNAL(searchResultChanged(QVector<GeoDataPlacemark*>)),
this, SLOT(setSearchResult(QVector<GeoDataPlacemark*>)) );
connect( d->m_runnerManager, SIGNAL(searchFinished(QString)),
d->m_searchField, SLOT(disableSearchAnimation()));
GeoDataTreeModel* treeModel = d->m_widget->model()->treeModel();
treeModel->addDocument( d->m_document );
d->m_branchfilter.setSourceModel( treeModel );
d->m_branchfilter.setBranchIndex( treeModel, treeModel->index( d->m_document ) );
d->m_searchResultView->setRootIndex(
d->m_sortproxy.mapFromSource(
d->m_branchfilter.mapFromSource( treeModel->index( d->m_document ) ) ) );
}
void SearchWidgetPrivate::search( const QString &searchTerm, SearchMode searchMode )
{
if( searchTerm.isEmpty() ) {
clearSearch();
} else {
if ( searchMode == AreaSearch ) {
m_runnerManager->findPlacemarks( searchTerm, m_widget->viewport()->viewLatLonAltBox() );
} else {
m_runnerManager->findPlacemarks( searchTerm );
}
}
}
void SearchWidgetPrivate::clearSearch()
{
m_widget->model()->placemarkSelectionModel()->clear();
// clear the local document
GeoDataTreeModel *treeModel = m_widget->model()->treeModel();
treeModel->removeDocument( m_document );
m_document->clear();
treeModel->addDocument( m_document );
m_branchfilter.setBranchIndex( treeModel, treeModel->index( m_document ) );
m_searchResultView->setRootIndex(
m_sortproxy.mapFromSource(
m_branchfilter.mapFromSource( treeModel->index( m_document ) ) ) );
// clear cached search results
m_runnerManager->findPlacemarks( QString() );
}
void SearchWidgetPrivate::centerMapOn( const QModelIndex &index )
{
if( !index.isValid() ) {
return;
}
GeoDataObject *object
= index.model()->data(index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>( object );
if ( placemark ) {
m_widget->centerOn( *placemark, true );
m_widget->model()->placemarkSelectionModel()->select( index, QItemSelectionModel::ClearAndSelect );
}
}
void SearchWidgetPrivate::handlePlanetChange()
{
const QString newPlanetId = m_widget->model()->planetId();
if (newPlanetId == m_planetId) {
return;
}
m_planetId = newPlanetId;
clearSearch();
}
}
#include "moc_SearchWidget.cpp"
diff --git a/src/lib/marble/SearchWidget.h b/src/lib/marble/SearchWidget.h
index 9aa70bfd4..611b7c893 100644
--- a/src/lib/marble/SearchWidget.h
+++ b/src/lib/marble/SearchWidget.h
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_SEARCHWIDGET_H
#define MARBLE_SEARCHWIDGET_H
#include "marble_export.h"
#include <QWidget>
namespace Marble {
class GeoDataPlacemark;
class MarbleWidget;
class SearchWidgetPrivate;
class MARBLE_EXPORT SearchWidget : public QWidget
{
Q_OBJECT
public:
- explicit SearchWidget( QWidget * parent = 0, Qt::WindowFlags flags = 0 );
+ explicit SearchWidget( QWidget * parent = nullptr, Qt::WindowFlags flags = nullptr );
void setMarbleWidget( MarbleWidget* widget );
~SearchWidget() override;
private:
Q_PRIVATE_SLOT( d, void setSearchResult( const QVector<GeoDataPlacemark*>& ) )
Q_PRIVATE_SLOT( d, void search( const QString &searchTerm, SearchMode searchMode ) )
Q_PRIVATE_SLOT( d, void centerMapOn( const QModelIndex &index ) )
Q_PRIVATE_SLOT( d, void handlePlanetChange() )
SearchWidgetPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/SerialTrack.cpp b/src/lib/marble/SerialTrack.cpp
index d40b09e0d..632d81277 100644
--- a/src/lib/marble/SerialTrack.cpp
+++ b/src/lib/marble/SerialTrack.cpp
@@ -1,177 +1,177 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "SerialTrack.h"
#include "PlaybackFlyToItem.h"
#include "PlaybackWaitItem.h"
#include "PlaybackTourControlItem.h"
#include "GeoDataCamera.h"
#include "GeoDataLookAt.h"
#include "TourPlayback.h"
namespace Marble
{
SerialTrack::SerialTrack(): QObject()
{
m_currentIndex = 0;
m_finishedPosition = 0;
m_currentPosition = 0;
m_paused = true;
}
SerialTrack::~SerialTrack()
{
clear();
}
void SerialTrack::append(PlaybackItem* item)
{
connect( item, SIGNAL(progressChanged(double)), this, SLOT(changeProgress(double)) );
connect( item, SIGNAL(centerOn(GeoDataCoordinates)), this, SIGNAL(centerOn(GeoDataCoordinates)) );
connect( item, SIGNAL(finished()), this, SLOT(handleFinishedItem()) ) ;
connect( item, SIGNAL(paused()), this, SLOT(pause()) ) ;
m_items.append( item );
if( m_items.size() == 1 ) {
PlaybackFlyToItem *flyTo = dynamic_cast<PlaybackFlyToItem*>( item );
- if( flyTo != 0 ) {
+ if( flyTo != nullptr ) {
flyTo->setFirst( true )
; }
}
}
void SerialTrack::play()
{
m_paused = false;
m_items[m_currentIndex]->play();
}
void SerialTrack::pause()
{
m_paused = true;
m_items[m_currentIndex]->pause();
}
void SerialTrack::stop()
{
m_paused = true;
if( m_items.size() != 0 && m_currentIndex >= 0 && m_currentIndex <= m_items.size() - 1 ){
m_items[m_currentIndex]->stop();
}
m_finishedPosition = 0;
emit progressChanged( m_finishedPosition );
m_currentIndex = 0;
}
void SerialTrack::seek( double offset )
{
m_currentPosition = offset;
int index = -1;
for( int i = 0; i < m_items.size(); i++ ){
if( offset < m_items[i]->duration() ){
index = i;
break;
} else {
m_items[i]->stop();
offset -= m_items[i]->duration();
}
}
if( index == -1 ){
index = m_items.size() - 1;
}
if( index < m_items.size() - 1 ){
for( int i = index + 1; i < m_items.size(); i++ ){
m_items[ i ]->stop();
}
}
if( index > m_currentIndex ){
for( int i = m_currentIndex; i < index ; i++ ){
m_finishedPosition += m_items[ i ]->duration();
}
}else{
for( int i = m_currentIndex - 1; i >= index && i >= 0; i-- ){
m_finishedPosition -= m_items[ i ]->duration();
}
}
if (m_currentIndex != index && !m_paused) {
m_items[ index ]->play();
}
m_currentIndex = index;
if ( m_currentIndex != -1 ){
double t = offset / m_items[ m_currentIndex ]->duration();
Q_ASSERT( t >= 0 && t <= 1 );
m_items[ m_currentIndex ]->seek( t );
}
}
double SerialTrack::duration() const
{
double duration = 0.0;
for (PlaybackItem* item: m_items) {
duration += item->duration();
}
return duration;
}
void SerialTrack::clear()
{
qDeleteAll( m_items );
m_items.clear();
m_currentIndex = 0;
m_finishedPosition = 0;
m_currentPosition = 0;
m_paused = true;
}
void SerialTrack::handleFinishedItem()
{
if( m_paused ){
return;
}
if ( m_currentIndex + 1 < m_items.size() ) {
m_finishedPosition += m_items[m_currentIndex]->duration();
m_currentIndex++;
m_items[m_currentIndex]->play();
emit itemFinished( m_currentIndex + 1 );
} else {
emit finished();
}
}
void SerialTrack::changeProgress( double progress )
{
m_currentPosition = m_finishedPosition + progress;
emit progressChanged( m_currentPosition );
}
int SerialTrack::size() const
{
return m_items.size();
}
PlaybackItem* SerialTrack::at( int i )
{
return m_items.at( i );
}
double SerialTrack::currentPosition()
{
return m_currentPosition;
}
}
#include "moc_SerialTrack.cpp"
diff --git a/src/lib/marble/SoundCueEditWidget.h b/src/lib/marble/SoundCueEditWidget.h
index 9eb6a9062..89a1619f1 100644
--- a/src/lib/marble/SoundCueEditWidget.h
+++ b/src/lib/marble/SoundCueEditWidget.h
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
// Copyright 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef SOUNDCUEEDITWIDGET_H
#define SOUNDCUEEDITWIDGET_H
#include <QWidget>
#include <QPersistentModelIndex>
class QLineEdit;
class QToolButton;
namespace Marble
{
class GeoDataSoundCue;
class SoundCueEditWidget: public QWidget
{
Q_OBJECT
public:
- explicit SoundCueEditWidget( const QModelIndex& index, QWidget* parent=0 );
+ explicit SoundCueEditWidget( const QModelIndex& index, QWidget* parent=nullptr );
bool editable() const;
Q_SIGNALS:
void editingDone( const QModelIndex& index );
public Q_SLOTS:
void setEditable( bool editable );
private Q_SLOTS:
void save();
void open();
private:
GeoDataSoundCue* soundCueElement();
QPersistentModelIndex m_index;
QLineEdit* m_lineEdit;
QToolButton *m_button;
QToolButton *m_button2;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/StackedTile.cpp b/src/lib/marble/StackedTile.cpp
index f85f76464..0191436e4 100644
--- a/src/lib/marble/StackedTile.cpp
+++ b/src/lib/marble/StackedTile.cpp
@@ -1,266 +1,266 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2010 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008-2010 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "StackedTile.h"
#include "MarbleDebug.h"
#include "TextureTile.h"
using namespace Marble;
static const uint **jumpTableFromQImage32( const QImage &img )
{
if ( img.depth() != 48 && img.depth() != 32 )
- return 0;
+ return nullptr;
const int height = img.height();
const int bpl = img.bytesPerLine() / 4;
const uint *data = reinterpret_cast<const QRgb*>(img.bits());
const uint **jumpTable = new const uint*[height];
for ( int y = 0; y < height; ++y ) {
jumpTable[ y ] = data;
data += bpl;
}
return jumpTable;
}
static const uchar **jumpTableFromQImage8( const QImage &img )
{
if ( img.depth() != 8 && img.depth() != 1 )
- return 0;
+ return nullptr;
const int height = img.height();
const int bpl = img.bytesPerLine();
const uchar *data = img.bits();
const uchar **jumpTable = new const uchar*[height];
for ( int y = 0; y < height; ++y ) {
jumpTable[ y ] = data;
data += bpl;
}
return jumpTable;
}
StackedTile::StackedTile( const TileId &id, const QImage &resultImage, QVector<QSharedPointer<TextureTile> > const &tiles ) :
Tile( id ),
m_resultImage( resultImage ),
m_depth( resultImage.depth() ),
m_isGrayscale( resultImage.isGrayscale() ),
m_tiles( tiles ),
jumpTable8( jumpTableFromQImage8( m_resultImage ) ),
jumpTable32( jumpTableFromQImage32( m_resultImage ) ),
m_byteCount( calcByteCount( resultImage, tiles ) ),
m_isUsed( false )
{
Q_ASSERT( !tiles.isEmpty() );
- if ( jumpTable32 == 0 && jumpTable8 == 0 ) {
+ if ( jumpTable32 == nullptr && jumpTable8 == nullptr ) {
qWarning() << "Color depth" << m_depth << " is not supported.";
}
}
StackedTile::~StackedTile()
{
delete [] jumpTable32;
delete [] jumpTable8;
}
uint StackedTile::pixel( int x, int y ) const
{
if ( m_depth == 8 ) {
if ( m_isGrayscale )
return (jumpTable8)[y][x];
else
return m_resultImage.color( (jumpTable8)[y][x] );
}
if ( m_depth == 32 )
return (jumpTable32)[y][x];
if ( m_depth == 1 && !m_isGrayscale )
return m_resultImage.color((jumpTable8)[y][x/8] >> 7);
return m_resultImage.pixel( x, y );
}
uint StackedTile::pixelF( qreal x, qreal y, const QRgb& topLeftValue ) const
{
// Bilinear interpolation to determine the color of a subpixel
int iX = (int)(x);
int iY = (int)(y);
qreal fY = y - iY;
// Interpolation in y-direction
if ( ( iY + 1 ) < m_resultImage.height() ) {
QRgb bottomLeftValue = pixel( iX, iY + 1 );
// #define CHEAPHIGH
#ifdef CHEAPHIGH
QRgb leftValue;
if ( fY < 0.33 )
leftValue = topLeftValue;
else if ( fY < 0.66 )
leftValue = (((bottomLeftValue ^ topLeftValue) & 0xfefefefeUL) >> 1)
+ (bottomLeftValue & topLeftValue);
else
leftValue = bottomLeftValue;
#else
// blending the color values of the top left and bottom left point
qreal ml_red = ( 1.0 - fY ) * qRed ( topLeftValue ) + fY * qRed ( bottomLeftValue );
qreal ml_green = ( 1.0 - fY ) * qGreen( topLeftValue ) + fY * qGreen( bottomLeftValue );
qreal ml_blue = ( 1.0 - fY ) * qBlue ( topLeftValue ) + fY * qBlue ( bottomLeftValue );
#endif
// Interpolation in x-direction
if ( iX + 1 < m_resultImage.width() ) {
qreal fX = x - iX;
QRgb topRightValue = pixel( iX + 1, iY );
QRgb bottomRightValue = pixel( iX + 1, iY + 1 );
#ifdef CHEAPHIGH
QRgb rightValue;
if ( fY < 0.33 )
rightValue = topRightValue;
else if ( fY < 0.66 )
rightValue = (((bottomRightValue ^ topRightValue) & 0xfefefefeUL) >> 1)
+ (bottomRightValue & topRightValue);
else
rightValue = bottomRightValue;
QRgb averageValue;
if ( fX < 0.33 )
averageValue = leftValue;
else if ( fX < 0.66 )
averageValue = (((leftValue ^ rightValue) & 0xfefefefeUL) >> 1)
+ (leftValue & rightValue);
else
averageValue = rightValue;
return averageValue;
#else
// blending the color values of the top right and bottom right point
qreal mr_red = ( 1.0 - fY ) * qRed ( topRightValue ) + fY * qRed ( bottomRightValue );
qreal mr_green = ( 1.0 - fY ) * qGreen( topRightValue ) + fY * qGreen( bottomRightValue );
qreal mr_blue = ( 1.0 - fY ) * qBlue ( topRightValue ) + fY * qBlue ( bottomRightValue );
// blending the color values of the resulting middle left
// and middle right points
int mm_red = (int)( ( 1.0 - fX ) * ml_red + fX * mr_red );
int mm_green = (int)( ( 1.0 - fX ) * ml_green + fX * mr_green );
int mm_blue = (int)( ( 1.0 - fX ) * ml_blue + fX * mr_blue );
return qRgb( mm_red, mm_green, mm_blue );
#endif
}
else {
#ifdef CHEAPHIGH
return leftValue;
#else
return qRgb( ml_red, ml_green, ml_blue );
#endif
}
}
else {
// Interpolation in x-direction
if ( iX + 1 < m_resultImage.width() ) {
qreal fX = x - iX;
if ( fX == 0.0 )
return topLeftValue;
QRgb topRightValue = pixel( iX + 1, iY );
#ifdef CHEAPHIGH
QRgb topValue;
if ( fX < 0.33 )
topValue = topLeftValue;
else if ( fX < 0.66 )
topValue = (((topLeftValue ^ topRightValue) & 0xfefefefeUL) >> 1)
+ (topLeftValue & topRightValue);
else
topValue = topRightValue;
return topValue;
#else
// blending the color values of the top left and top right point
int tm_red = (int)( ( 1.0 - fX ) * qRed ( topLeftValue ) + fX * qRed ( topRightValue ) );
int tm_green = (int)( ( 1.0 - fX ) * qGreen( topLeftValue ) + fX * qGreen( topRightValue ) );
int tm_blue = (int)( ( 1.0 - fX ) * qBlue ( topLeftValue ) + fX * qBlue ( topRightValue ) );
return qRgb( tm_red, tm_green, tm_blue );
#endif
}
}
return topLeftValue;
}
int StackedTile::calcByteCount( const QImage &resultImage, const QVector<QSharedPointer<TextureTile> > &tiles )
{
int byteCount = resultImage.byteCount();
QVector<QSharedPointer<TextureTile> >::const_iterator pos = tiles.constBegin();
QVector<QSharedPointer<TextureTile> >::const_iterator const end = tiles.constEnd();
for (; pos != end; ++pos )
byteCount += (*pos)->byteCount();
return byteCount;
}
void StackedTile::setUsed( bool used )
{
m_isUsed = used;
}
bool StackedTile::used() const
{
return m_isUsed;
}
uint StackedTile::pixelF( qreal x, qreal y ) const
{
int iX = (int)(x);
int iY = (int)(y);
QRgb topLeftValue = pixel( iX, iY );
return pixelF( x, y, topLeftValue );
}
int StackedTile::depth() const
{
return m_depth;
}
int StackedTile::byteCount() const
{
return m_byteCount;
}
QVector<QSharedPointer<TextureTile> > StackedTile::tiles() const
{
return m_tiles;
}
QImage const * StackedTile::resultImage() const
{
return &m_resultImage;
}
diff --git a/src/lib/marble/StackedTileLoader.cpp b/src/lib/marble/StackedTileLoader.cpp
index 3f3619595..5885c5ad4 100644
--- a/src/lib/marble/StackedTileLoader.cpp
+++ b/src/lib/marble/StackedTileLoader.cpp
@@ -1,231 +1,231 @@
/*
* This file is part of the Marble Virtual Globe.
*
* Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
* Copyright 2007 Inge Wallin <ingwa@kde.org>
* Copyright 2008, 2009, 2010 Jens-Michael Hoffmann <jensmh@gmx.de>
* Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
*
* 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 "StackedTileLoader.h"
#include "MarbleDebug.h"
#include "MergedLayerDecorator.h"
#include "StackedTile.h"
#include "TileLoader.h"
#include "TileLoaderHelper.h"
#include "MarbleGlobal.h"
#include <QCache>
#include <QHash>
#include <QReadWriteLock>
#include <QImage>
namespace Marble
{
class StackedTileLoaderPrivate
{
public:
explicit StackedTileLoaderPrivate( MergedLayerDecorator *mergedLayerDecorator )
: m_layerDecorator( mergedLayerDecorator )
{
m_tileCache.setMaxCost( 20000 * 1024 ); // Cache size measured in bytes
}
MergedLayerDecorator *const m_layerDecorator;
QHash <TileId, StackedTile*> m_tilesOnDisplay;
QCache <TileId, StackedTile> m_tileCache;
QReadWriteLock m_cacheLock;
};
StackedTileLoader::StackedTileLoader( MergedLayerDecorator *mergedLayerDecorator, QObject *parent )
: QObject( parent ),
d( new StackedTileLoaderPrivate( mergedLayerDecorator ) )
{
}
StackedTileLoader::~StackedTileLoader()
{
qDeleteAll( d->m_tilesOnDisplay );
delete d;
}
int StackedTileLoader::tileColumnCount( int level ) const
{
return d->m_layerDecorator->tileColumnCount( level );
}
int StackedTileLoader::tileRowCount( int level ) const
{
return d->m_layerDecorator->tileRowCount( level );
}
const GeoSceneAbstractTileProjection *StackedTileLoader::tileProjection() const
{
return d->m_layerDecorator->tileProjection();
}
QSize StackedTileLoader::tileSize() const
{
return d->m_layerDecorator->tileSize();
}
void StackedTileLoader::resetTilehash()
{
QHash<TileId, StackedTile*>::const_iterator it = d->m_tilesOnDisplay.constBegin();
QHash<TileId, StackedTile*>::const_iterator const end = d->m_tilesOnDisplay.constEnd();
for (; it != end; ++it ) {
Q_ASSERT( it.value()->used() && "contained in m_tilesOnDisplay should imply used()" );
it.value()->setUsed( false );
}
}
void StackedTileLoader::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<TileId, StackedTile*> it( d->m_tilesOnDisplay );
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()->byteCount() );
d->m_tilesOnDisplay.remove( it.key() );
}
}
}
const StackedTile* StackedTileLoader::loadTile( TileId const & stackedTileId )
{
// check if the tile is in the hash
d->m_cacheLock.lockForRead();
StackedTile * stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
d->m_cacheLock.unlock();
if ( stackedTile ) {
stackedTile->setUsed( true );
return stackedTile;
}
// here ends the performance critical section of this method
d->m_cacheLock.lockForWrite();
// has another thread loaded our tile due to a race condition?
stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
if ( stackedTile ) {
Q_ASSERT( stackedTile->used() && "other thread should have marked tile as used" );
d->m_cacheLock.unlock();
return stackedTile;
}
// the tile was not in the hash so check if it is in the cache
stackedTile = d->m_tileCache.take( stackedTileId );
if ( stackedTile ) {
Q_ASSERT( !stackedTile->used() && "tiles in m_tileCache are invisible and should thus be marked as unused" );
stackedTile->setUsed( true );
d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
d->m_cacheLock.unlock();
return stackedTile;
}
// 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 transferred to the cache
mDebug() << "load tile from disk:" << stackedTileId;
stackedTile = d->m_layerDecorator->loadTile( stackedTileId );
Q_ASSERT( stackedTile );
stackedTile->setUsed( true );
d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
d->m_cacheLock.unlock();
emit tileLoaded( stackedTileId );
return stackedTile;
}
quint64 StackedTileLoader::volatileCacheLimit() const
{
return d->m_tileCache.maxCost() / 1024;
}
QList<TileId> StackedTileLoader::visibleTiles() const
{
return d->m_tilesOnDisplay.keys();
}
int StackedTileLoader::tileCount() const
{
return d->m_tileCache.count() + d->m_tilesOnDisplay.count();
}
void StackedTileLoader::setVolatileCacheLimit( quint64 kiloBytes )
{
mDebug() << QString("Setting tile cache to %1 kilobytes.").arg( kiloBytes );
d->m_tileCache.setMaxCost( kiloBytes * 1024 );
}
void StackedTileLoader::updateTile( TileId const &tileId, QImage const &tileImage )
{
const TileId stackedTileId( 0, tileId.zoomLevel(), tileId.x(), tileId.y() );
StackedTile * displayedTile = d->m_tilesOnDisplay.take( stackedTileId );
if ( displayedTile ) {
Q_ASSERT( !d->m_tileCache.contains( stackedTileId ) );
StackedTile *const stackedTile = d->m_layerDecorator->updateTile( *displayedTile, tileId, tileImage );
stackedTile->setUsed( true );
d->m_tilesOnDisplay.insert( stackedTileId, stackedTile );
delete displayedTile;
- displayedTile = 0;
+ displayedTile = nullptr;
emit tileLoaded( stackedTileId );
} else {
d->m_tileCache.remove( stackedTileId );
}
}
RenderState StackedTileLoader::renderState() const
{
RenderState renderState( "Stacked Tiles" );
QHash<TileId, StackedTile*>::const_iterator it = d->m_tilesOnDisplay.constBegin();
QHash<TileId, StackedTile*>::const_iterator const end = d->m_tilesOnDisplay.constEnd();
for (; it != end; ++it ) {
renderState.addChild( d->m_layerDecorator->renderState( it.key() ) );
}
return renderState;
}
void StackedTileLoader::clear()
{
qDeleteAll( d->m_tilesOnDisplay );
d->m_tilesOnDisplay.clear();
d->m_tileCache.clear(); // clear the tile cache in physical memory
emit cleared();
}
}
#include "moc_StackedTileLoader.cpp"
diff --git a/src/lib/marble/StackedTileLoader.h b/src/lib/marble/StackedTileLoader.h
index d89046575..e018bdf18 100644
--- a/src/lib/marble/StackedTileLoader.h
+++ b/src/lib/marble/StackedTileLoader.h
@@ -1,149 +1,149 @@
/*
* This file is part of the Marble Virtual Globe.
*
* Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
* Copyright 2007 Inge Wallin <ingwa@kde.org>
* Copyright 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
* Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
*
* 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_STACKEDTILELOADER_H
#define MARBLE_STACKEDTILELOADER_H
#include <QObject>
#include "RenderState.h"
class QImage;
class QString;
class QSize;
namespace Marble
{
class GeoSceneAbstractTileProjection;
class MergedLayerDecorator;
class StackedTile;
class TileId;
class StackedTileLoaderPrivate;
/**
* @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 <rahn@kde.org>
**/
class StackedTileLoader : 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.
*/
- explicit StackedTileLoader( MergedLayerDecorator *mergedLayerDecorator, QObject *parent = 0 );
+ explicit StackedTileLoader( MergedLayerDecorator *mergedLayerDecorator, QObject *parent = nullptr );
~StackedTileLoader() override;
int tileColumnCount( int level ) const;
int tileRowCount( int level ) const;
const GeoSceneAbstractTileProjection *tileProjection() const;
QSize tileSize() const;
/**
* Loads a tile and returns it.
*
* @param stackedTileId The Id of the requested tile, containing the x and y coordinate
* and the zoom level.
*/
const StackedTile* loadTile( TileId const &stackedTileId );
/**
* Resets the internal tile hash.
*/
void resetTilehash();
/**
* Cleans up the internal tile hash.
*
* Removes all superfluous tiles from the hash.
*/
void cleanupTilehash();
/**
* @brief Returns the limit of the volatile (in RAM) cache.
* @return the cache limit in kilobytes
*/
quint64 volatileCacheLimit() const;
/**
* @brief Reloads the tiles that are currently displayed.
*/
QList<TileId> visibleTiles() const;
/**
* @brief Return the number of tiles in the cache.
* @return number of tiles in cache
*/
int tileCount() const;
/**
* @brief Set the limit of the volatile (in RAM) cache.
* @param bytes The limit in kilobytes.
*/
void setVolatileCacheLimit( quint64 kiloBytes );
/**
* Effectively triggers a reload of all tiles that are currently in use
* and clears the tile cache in physical memory.
*/
void clear();
/**
*/
void updateTile(TileId const & tileId, QImage const &tileImage );
RenderState renderState() const;
Q_SIGNALS:
void tileLoaded( TileId const &tileId );
void cleared();
private:
Q_DISABLE_COPY( StackedTileLoader )
friend class StackedTileLoaderPrivate;
StackedTileLoaderPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/StoragePolicy.h b/src/lib/marble/StoragePolicy.h
index 66b3bbe3f..6c0b43ee2 100644
--- a/src/lib/marble/StoragePolicy.h
+++ b/src/lib/marble/StoragePolicy.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Tobias Koenig <tokoe@kde.org>
// Copyright 2009 Bastian Holst <bastianholst@gmx.de
//
#ifndef MARBLE_STORAGEPOLICY_H
#define MARBLE_STORAGEPOLICY_H
#include <QObject>
class QByteArray;
class QString;
namespace Marble
{
class StoragePolicy : public QObject
{
Q_OBJECT
public:
- explicit StoragePolicy( QObject *parent = 0 );
+ explicit StoragePolicy( QObject *parent = nullptr );
~StoragePolicy() override {}
virtual bool fileExists( const QString &fileName ) const = 0;
/**
* Return true if file was written successfully.
*/
virtual bool updateFile( const QString &fileName, const QByteArray &data ) = 0;
virtual void clearCache() = 0;
virtual QString lastErrorMessage() const = 0;
Q_SIGNALS:
void cleared();
void sizeChanged( qint64 );
private:
Q_DISABLE_COPY( StoragePolicy )
};
}
#endif
diff --git a/src/lib/marble/SunControlWidget.h b/src/lib/marble/SunControlWidget.h
index d904d5a2b..12eb3a1b6 100644
--- a/src/lib/marble/SunControlWidget.h
+++ b/src/lib/marble/SunControlWidget.h
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 David Roberts <dvdr18@gmail.com>
// Copyright 2008 Inge Wallin <inge@lysator.liu.se>
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#ifndef MARBLE_SUNCONTROLWIDGET_H
#define MARBLE_SUNCONTROLWIDGET_H
#include <QDialog>
#include "marble_export.h"
namespace Ui
{
class SunControlWidget;
}
namespace Marble
{
class MarbleWidget;
class MARBLE_EXPORT SunControlWidget : public QDialog
{
Q_OBJECT
public:
- explicit SunControlWidget( MarbleWidget *marbleWidget, QWidget* parent = 0 );
+ explicit SunControlWidget( MarbleWidget *marbleWidget, QWidget* parent = nullptr );
~SunControlWidget() override;
void setSunShading( bool );
private Q_SLOTS:
void apply();
Q_SIGNALS:
void showSun( bool show );
void isLockedToSubSolarPoint( bool show );
void isSubSolarPointIconVisible( bool show );
protected:
Q_DISABLE_COPY( SunControlWidget )
void showEvent(QShowEvent* event) override;
Ui::SunControlWidget *m_uiWidget;
MarbleWidget *const m_marbleWidget;
QString m_shadow;
};
}
#endif
diff --git a/src/lib/marble/TileCreator.cpp b/src/lib/marble/TileCreator.cpp
index 9b8dd5553..44b9ddf03 100644
--- a/src/lib/marble/TileCreator.cpp
+++ b/src/lib/marble/TileCreator.cpp
@@ -1,622 +1,622 @@
//
// This file is part of the Marble Project.
//
// 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 <tackat@kde.org>
// Copyright 2007-2008 Inge Wallin <ingwa@kde.org>
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "TileCreator.h"
#include <cmath>
#include <QDir>
#include <QRect>
#include <QSize>
#include <QVector>
#include <QApplication>
#include <QImage>
#include <QPainter>
#include "MarbleGlobal.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "TileLoaderHelper.h"
namespace Marble
{
class TileCreatorPrivate
{
public:
TileCreatorPrivate( TileCreatorSource *source,
const QString& dem, const QString& targetDir=QString() )
: m_dem( dem ),
m_targetDir( targetDir ),
m_cancelled( false ),
m_tileFormat( "jpg" ),
m_resume( false ),
m_verify( false ),
m_source( source )
{
if (m_dem == QLatin1String("true")) {
m_tileQuality = 70;
} else {
m_tileQuality = 85;
}
}
~TileCreatorPrivate()
{
delete m_source;
}
public:
QString m_dem;
QString m_targetDir;
bool m_cancelled;
QString m_tileFormat;
int m_tileQuality;
bool m_resume;
bool m_verify;
TileCreatorSource *m_source;
};
class TileCreatorSourceImage : public TileCreatorSource
{
public:
explicit TileCreatorSourceImage( const QString &sourcePath )
: m_sourceImage( QImage( sourcePath ) ),
m_cachedRowNum( -1 )
{
}
QSize fullImageSize() const override
{
if ( m_sourceImage.size().width() > 21600 || m_sourceImage.height() > 10800 ) {
qDebug("Install map too large!");
return QSize();
}
return m_sourceImage.size();
}
QImage tile(int n, int m, int maxTileLevel) override
{
int mmax = TileLoaderHelper::levelToColumn( defaultLevelZeroColumns, maxTileLevel );
int nmax = TileLoaderHelper::levelToRow( defaultLevelZeroRows, maxTileLevel );
int imageHeight = m_sourceImage.height();
int imageWidth = m_sourceImage.width();
// If the image size of the image source does not match the expected
// geometry we need to smooth-scale the image in advance to match
// the required size
bool needsScaling = ( imageWidth != 2 * nmax * (int)( c_defaultTileSize )
|| imageHeight != nmax * (int)( c_defaultTileSize ) );
if ( needsScaling )
mDebug() << "Image Size doesn't match 2*n*TILEWIDTH x n*TILEHEIGHT geometry. Scaling ...";
int stdImageWidth = 2 * nmax * c_defaultTileSize;
if ( stdImageWidth == 0 )
stdImageWidth = 2 * c_defaultTileSize;
int stdImageHeight = nmax * c_defaultTileSize;
if ( stdImageWidth != imageWidth ) {
mDebug() <<
QString( "TileCreator::createTiles() The size of the final image will measure %1 x %2 pixels").arg(stdImageWidth).arg(stdImageHeight);
}
QImage row;
if ( m_cachedRowNum == n ) {
row = m_rowCache;
} else {
QRect sourceRowRect( 0, (int)( (qreal)( n * imageHeight ) / (qreal)( nmax )),
imageWidth,(int)( (qreal)( imageHeight ) / (qreal)( nmax ) ) );
row = m_sourceImage.copy( sourceRowRect );
if ( needsScaling ) {
// Pick the current row and smooth scale it
// to make it match the expected size
QSize destSize( stdImageWidth, c_defaultTileSize );
row = row.scaled( destSize,
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation );
}
m_cachedRowNum = n;
m_rowCache = row;
}
if ( row.isNull() ) {
mDebug() << "Read-Error! Null QImage!";
return QImage();
}
QImage tile = row.copy( m * stdImageWidth / mmax, 0, c_defaultTileSize, c_defaultTileSize );
return tile;
}
private:
QImage m_sourceImage;
QImage m_rowCache;
int m_cachedRowNum;
};
TileCreator::TileCreator(const QString& sourceDir, const QString& installMap,
const QString& dem, const QString& targetDir)
- : QThread(0),
- d( new TileCreatorPrivate( 0, dem, targetDir ) )
+ : QThread(nullptr),
+ d( new TileCreatorPrivate( nullptr, dem, targetDir ) )
{
mDebug() << "Prefix: " << sourceDir
<< "installmap:" << installMap;
QString sourcePath;
// If the sourceDir starts with a '/' assume an absolute path.
// Otherwise assume a relative marble data path
if ( QDir::isAbsolutePath( sourceDir ) ) {
sourcePath = sourceDir + QLatin1Char('/') + installMap;
mDebug() << "Trying absolute path*:" << sourcePath;
}
else {
sourcePath = MarbleDirs::path(QLatin1String("maps/") + sourceDir + QLatin1Char('/') + installMap);
mDebug() << "Trying relative path*:"
<< QLatin1String("maps/") + sourceDir + QLatin1Char('/') + installMap;
}
mDebug() << "Creating tiles from*: " << sourcePath;
d->m_source = new TileCreatorSourceImage( sourcePath );
if ( d->m_targetDir.isNull() )
d->m_targetDir = MarbleDirs::localPath() + QLatin1String("/maps/")
+ sourcePath.section(QLatin1Char('/'), -3, -2) + QLatin1Char('/');
setTerminationEnabled( true );
}
TileCreator::TileCreator( TileCreatorSource* source, const QString& dem, const QString& targetDir )
- : QThread(0),
+ : QThread(nullptr),
d( new TileCreatorPrivate( source, dem, targetDir ) )
{
setTerminationEnabled( true );
}
TileCreator::~TileCreator()
{
delete d;
}
void TileCreator::cancelTileCreation()
{
d->m_cancelled = true;
}
void TileCreator::run()
{
if (d->m_resume && d->m_tileFormat == QLatin1String("jpg") && d->m_tileQuality != 100) {
qWarning() << "Resuming jpegs is only supported with tileQuality 100";
return;
}
if (!d->m_targetDir.endsWith(QLatin1Char('/')))
d->m_targetDir += QLatin1Char('/');
mDebug() << "Installing tiles to: " << d->m_targetDir;
QVector<QRgb> grayScalePalette;
for ( int cnt = 0; cnt <= 255; ++cnt ) {
grayScalePalette.insert(cnt, qRgb(cnt, cnt, cnt));
}
QSize fullImageSize = d->m_source->fullImageSize();
int imageWidth = fullImageSize.width();
int imageHeight = fullImageSize.height();
mDebug() << QString( "TileCreator::createTiles() image dimensions %1 x %2").arg(imageWidth).arg(imageHeight);
if ( imageWidth < 1 || imageHeight < 1 ) {
qDebug("Invalid imagemap!");
return;
}
// Calculating Maximum Tile Level
float approxMaxTileLevel = std::log( imageWidth / ( 2.0 * c_defaultTileSize ) ) / std::log( 2.0 );
int maxTileLevel = 0;
if ( approxMaxTileLevel == int( approxMaxTileLevel ) )
maxTileLevel = static_cast<int>( approxMaxTileLevel );
else
maxTileLevel = static_cast<int>( approxMaxTileLevel + 1 );
if ( maxTileLevel < 0 ) {
mDebug()
<< QString( "TileCreator::createTiles(): Invalid Maximum Tile Level: %1" )
.arg( maxTileLevel );
}
mDebug() << "Maximum Tile Level: " << maxTileLevel;
if ( !QDir( d->m_targetDir ).exists() )
( QDir::root() ).mkpath( d->m_targetDir );
// Counting total amount of tiles to be generated for the progressbar
// to prevent compiler warnings this var should
// match the type of maxTileLevel
int tileLevel = 0;
int totalTileCount = 0;
while ( tileLevel <= maxTileLevel ) {
totalTileCount += ( TileLoaderHelper::levelToRow( defaultLevelZeroRows, tileLevel )
* TileLoaderHelper::levelToColumn( defaultLevelZeroColumns, tileLevel ) );
tileLevel++;
}
mDebug() << totalTileCount << " tiles to be created in total.";
int mmax = TileLoaderHelper::levelToColumn( defaultLevelZeroColumns, maxTileLevel );
int nmax = TileLoaderHelper::levelToRow( defaultLevelZeroRows, maxTileLevel );
// Loading each row at highest spatial resolution and cropping tiles
int percentCompleted = 0;
int createdTilesCount = 0;
QString tileName;
// Creating directory structure for the highest level
QString dirName( d->m_targetDir
+ QString("%1").arg(maxTileLevel) );
if ( !QDir( dirName ).exists() )
( QDir::root() ).mkpath( dirName );
for ( int n = 0; n < nmax; ++n ) {
QString dirName( d->m_targetDir
+ QString("%1/%2").arg(maxTileLevel).arg(n, tileDigits, 10, QLatin1Char('0')));
if ( !QDir( dirName ).exists() )
( QDir::root() ).mkpath( dirName );
}
for ( int n = 0; n < nmax; ++n ) {
for ( int m = 0; m < mmax; ++m ) {
mDebug() << "** tile" << m << "x" << n;
if ( d->m_cancelled )
return;
tileName = d->m_targetDir + QString("%1/%2/%2_%3.%4")
.arg( maxTileLevel )
.arg(n, tileDigits, 10, QLatin1Char('0'))
.arg(m, tileDigits, 10, QLatin1Char('0'))
.arg( d->m_tileFormat );
if ( QFile::exists( tileName ) && d->m_resume ) {
//mDebug() << tileName << "exists already";
} else {
QImage tile = d->m_source->tile( n, m, maxTileLevel );
if ( tile.isNull() ) {
mDebug() << "Read-Error! Null QImage!";
return;
}
if (d->m_dem == QLatin1String("true")) {
tile = tile.convertToFormat(QImage::Format_Indexed8,
grayScalePalette,
Qt::ThresholdDither);
}
bool ok = tile.save(tileName, d->m_tileFormat.toLatin1().data(), d->m_tileFormat == QLatin1String("jpg") ? 100 : d->m_tileQuality);
if ( !ok )
mDebug() << "Error while writing Tile: " << tileName;
mDebug() << tileName << "size" << QFile( tileName ).size();
if ( d->m_verify ) {
QImage writtenTile(tileName);
Q_ASSERT( writtenTile.size() == tile.size() );
for ( int i=0; i < writtenTile.size().width(); ++i) {
for ( int j=0; j < writtenTile.size().height(); ++j) {
if ( writtenTile.pixel( i, j ) != tile.pixel( i, j ) ) {
unsigned int pixel = tile.pixel( i, j);
unsigned int writtenPixel = writtenTile.pixel( i, j);
qWarning() << "***** pixel" << i << j << "is off by" << (pixel - writtenPixel) << "pixel" << pixel << "writtenPixel" << writtenPixel;
QByteArray baPixel((char*)&pixel, sizeof(unsigned int));
qWarning() << "pixel" << baPixel.size() << "0x" << baPixel.toHex();
QByteArray baWrittenPixel((char*)&writtenPixel, sizeof(unsigned int));
qWarning() << "writtenPixel" << baWrittenPixel.size() << "0x" << baWrittenPixel.toHex();
Q_ASSERT(false);
}
}
}
}
}
percentCompleted = (int) ( 90 * (qreal)(createdTilesCount)
/ (qreal)(totalTileCount) );
createdTilesCount++;
mDebug() << "percentCompleted" << percentCompleted;
emit progress( percentCompleted );
}
}
mDebug() << "tileLevel: " << maxTileLevel << " successfully created.";
tileLevel = maxTileLevel;
// Now that we have the tiles at the highest resolution lets build
// them together four by four.
while( tileLevel > 0 ) {
tileLevel--;
int nmaxit = TileLoaderHelper::levelToRow( defaultLevelZeroRows, tileLevel );
for ( int n = 0; n < nmaxit; ++n ) {
QString dirName( d->m_targetDir
+ QString("%1/%2")
.arg(tileLevel)
.arg(n, tileDigits, 10, QLatin1Char('0')));
// mDebug() << "dirName: " << dirName;
if ( !QDir( dirName ).exists() )
( QDir::root() ).mkpath( dirName );
int mmaxit = TileLoaderHelper::levelToColumn( defaultLevelZeroColumns, tileLevel );
for ( int m = 0; m < mmaxit; ++m ) {
if ( d->m_cancelled )
return;
QString newTileName = d->m_targetDir + QString("%1/%2/%2_%3.%4")
.arg( tileLevel )
.arg(n, tileDigits, 10, QLatin1Char('0'))
.arg(m, tileDigits, 10, QLatin1Char('0'))
.arg( d->m_tileFormat );
if ( QFile::exists( newTileName ) && d->m_resume ) {
//mDebug() << newTileName << "exists already";
} else {
tileName = d->m_targetDir + QString("%1/%2/%2_%3.%4")
.arg( tileLevel + 1 )
.arg(2*n, tileDigits, 10, QLatin1Char('0'))
.arg(2*m, tileDigits, 10, QLatin1Char('0'))
.arg( d->m_tileFormat );
QImage img_topleft( tileName );
tileName = d->m_targetDir + QString("%1/%2/%2_%3.%4")
.arg( tileLevel + 1 )
.arg(2*n, tileDigits, 10, QLatin1Char('0'))
.arg(2*m+1, tileDigits, 10, QLatin1Char('0'))
.arg( d->m_tileFormat );
QImage img_topright( tileName );
tileName = d->m_targetDir + QString("%1/%2/%2_%3.%4")
.arg( tileLevel + 1 )
.arg(2*n+1, tileDigits, 10, QLatin1Char('0'))
.arg(2*m, tileDigits, 10, QLatin1Char('0'))
.arg( d->m_tileFormat );
QImage img_bottomleft( tileName );
tileName = d->m_targetDir + QString("%1/%2/%2_%3.%4")
.arg( tileLevel + 1 )
.arg(2*n+1, tileDigits, 10, QLatin1Char('0'))
.arg(2*m+1, tileDigits, 10, QLatin1Char('0'))
.arg( d->m_tileFormat );
QImage img_bottomright( tileName );
QSize const expectedSize( c_defaultTileSize, c_defaultTileSize );
if ( img_topleft.size() != expectedSize ||
img_topright.size() != expectedSize ||
img_bottomleft.size() != expectedSize ||
img_bottomright.size() != expectedSize ) {
mDebug() << "Tile write failure. Missing write permissions?";
emit progress( 100 );
return;
}
QImage tile = img_topleft;
if (d->m_dem == QLatin1String("true")) {
tile.setColorTable( grayScalePalette );
uchar* destLine;
for ( uint y = 0; y < c_defaultTileSize / 2; ++y ) {
destLine = tile.scanLine( y );
const uchar* srcLine = img_topleft.scanLine( 2 * y );
for ( uint x = 0; x < c_defaultTileSize / 2; ++x )
destLine[x] = srcLine[ 2*x ];
}
for ( uint y = 0; y < c_defaultTileSize / 2; ++y ) {
destLine = tile.scanLine( y );
const uchar* srcLine = img_topright.scanLine( 2 * y );
for ( uint x = c_defaultTileSize / 2; x < c_defaultTileSize; ++x )
destLine[x] = srcLine[ 2 * ( x - c_defaultTileSize / 2 ) ];
}
for ( uint y = c_defaultTileSize / 2; y < c_defaultTileSize; ++y ) {
destLine = tile.scanLine( y );
const uchar* srcLine = img_bottomleft.scanLine( 2 * ( y - c_defaultTileSize / 2 ) );
for ( uint x = 0; x < c_defaultTileSize / 2; ++x )
destLine[ x ] = srcLine[ 2 * x ];
}
for ( uint y = c_defaultTileSize / 2; y < c_defaultTileSize; ++y ) {
destLine = tile.scanLine( y );
const uchar* srcLine = img_bottomright.scanLine( 2 * ( y - c_defaultTileSize/2 ) );
for ( uint x = c_defaultTileSize / 2; x < c_defaultTileSize; ++x )
destLine[x] = srcLine[ 2 * ( x - c_defaultTileSize / 2 ) ];
}
}
else {
// tile.depth() != 8
img_topleft = img_topleft.convertToFormat( QImage::Format_ARGB32 );
img_topright = img_topright.convertToFormat( QImage::Format_ARGB32 );
img_bottomleft = img_bottomleft.convertToFormat( QImage::Format_ARGB32 );
img_bottomright = img_bottomright.convertToFormat( QImage::Format_ARGB32 );
tile = img_topleft;
QRgb* destLine;
for ( uint y = 0; y < c_defaultTileSize / 2; ++y ) {
destLine = (QRgb*) tile.scanLine( y );
const QRgb* srcLine = (QRgb*) img_topleft.scanLine( 2 * y );
for ( uint x = 0; x < c_defaultTileSize / 2; ++x )
destLine[x] = srcLine[ 2 * x ];
}
for ( uint y = 0; y < c_defaultTileSize / 2; ++y ) {
destLine = (QRgb*) tile.scanLine( y );
const QRgb* srcLine = (QRgb*) img_topright.scanLine( 2 * y );
for ( uint x = c_defaultTileSize / 2; x < c_defaultTileSize; ++x )
destLine[x] = srcLine[ 2 * ( x - c_defaultTileSize / 2 ) ];
}
for ( uint y = c_defaultTileSize / 2; y < c_defaultTileSize; ++y ) {
destLine = (QRgb*) tile.scanLine( y );
const QRgb* srcLine = (QRgb*) img_bottomleft.scanLine( 2 * ( y-c_defaultTileSize/2 ) );
for ( uint x = 0; x < c_defaultTileSize / 2; ++x )
destLine[x] = srcLine[ 2 * x ];
}
for ( uint y = c_defaultTileSize / 2; y < c_defaultTileSize; ++y ) {
destLine = (QRgb*) tile.scanLine( y );
const QRgb* srcLine = (QRgb*) img_bottomright.scanLine( 2 * ( y-c_defaultTileSize / 2 ) );
for ( uint x = c_defaultTileSize / 2; x < c_defaultTileSize; ++x )
destLine[x] = srcLine[ 2*( x-c_defaultTileSize / 2 ) ];
}
}
mDebug() << newTileName;
// Saving at 100% JPEG quality to have a high-quality
// version to create the remaining needed tiles from.
bool ok = tile.save(newTileName, d->m_tileFormat.toLatin1().data(), d->m_tileFormat == QLatin1String("jpg") ? 100 : d->m_tileQuality);
if ( ! ok )
mDebug() << "Error while writing Tile: " << newTileName;
}
percentCompleted = (int) ( 90 * (qreal)(createdTilesCount)
/ (qreal)(totalTileCount) );
createdTilesCount++;
emit progress( percentCompleted );
mDebug() << "percentCompleted" << percentCompleted;
}
}
mDebug() << "tileLevel: " << tileLevel << " successfully created.";
}
mDebug() << "Tile creation completed.";
if (d->m_tileFormat == QLatin1String("jpg") && d->m_tileQuality != 100) {
// Applying correct lower JPEG compression now that we created all tiles
int savedTilesCount = 0;
tileLevel = 0;
while ( tileLevel <= maxTileLevel ) {
int nmaxit = TileLoaderHelper::levelToRow( defaultLevelZeroRows, tileLevel );
for ( int n = 0; n < nmaxit; ++n) {
int mmaxit = TileLoaderHelper::levelToColumn( defaultLevelZeroColumns, tileLevel );
for ( int m = 0; m < mmaxit; ++m) {
if ( d->m_cancelled )
return;
savedTilesCount++;
tileName = d->m_targetDir + QString("%1/%2/%2_%3.%4")
.arg( tileLevel )
.arg(n, tileDigits, 10, QLatin1Char('0'))
.arg(m, tileDigits, 10, QLatin1Char('0'))
.arg( d->m_tileFormat );
QImage tile( tileName );
bool ok;
ok = tile.save( tileName, d->m_tileFormat.toLatin1().data(), d->m_tileQuality );
if ( !ok )
mDebug() << "Error while writing Tile: " << tileName;
// Don't exceed 99% as this would cancel the thread unexpectedly
percentCompleted = 90 + (int)( 9 * (qreal)(savedTilesCount)
/ (qreal)(totalTileCount) );
emit progress( percentCompleted );
mDebug() << "percentCompleted" << percentCompleted;
//mDebug() << "Saving Tile #" << savedTilesCount
// << " of " << totalTileCount
// << " Percent: " << percentCompleted;
}
}
tileLevel++;
}
}
percentCompleted = 100;
emit progress( percentCompleted );
mDebug() << "percentCompleted: " << percentCompleted;
}
void TileCreator::setTileFormat(const QString& format)
{
d->m_tileFormat = format;
}
QString TileCreator::tileFormat() const
{
return d->m_tileFormat;
}
void TileCreator::setTileQuality(int quality)
{
d->m_tileQuality = quality;
}
int TileCreator::tileQuality() const
{
return d->m_tileQuality;
}
void TileCreator::setResume(bool resume)
{
d->m_resume = resume;
}
bool TileCreator::resume() const
{
return d->m_resume;
}
void TileCreator::setVerifyExactResult(bool verify)
{
d->m_verify = verify;
}
bool TileCreator::verifyExactResult() const
{
return d->m_verify;
}
}
#include "moc_TileCreator.cpp"
diff --git a/src/lib/marble/TileCreatorDialog.h b/src/lib/marble/TileCreatorDialog.h
index 47412adcd..39245e913 100644
--- a/src/lib/marble/TileCreatorDialog.h
+++ b/src/lib/marble/TileCreatorDialog.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
//
// The TileCreatorDialog displays the progress of the tile creation.
//
#ifndef MARBLE_TILECREATORDIALOG_H
#define MARBLE_TILECREATORDIALOG_H
#include <QDialog>
#include "marble_export.h"
class QString;
namespace Marble
{
class TileCreator;
class TileCreatorDialogPrivate;
class MARBLE_EXPORT TileCreatorDialog : public QDialog
{
Q_OBJECT
public:
- explicit TileCreatorDialog( TileCreator *creator, QWidget *parent = 0 );
+ explicit TileCreatorDialog( TileCreator *creator, QWidget *parent = nullptr );
~TileCreatorDialog() override;
public Q_SLOTS:
void setProgress( int progress );
void setSummary( const QString& name, const QString& description );
private Q_SLOTS:
void cancelTileCreation();
private:
Q_DISABLE_COPY( TileCreatorDialog )
TileCreatorDialogPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/TileLevelRangeWidget.h b/src/lib/marble/TileLevelRangeWidget.h
index a0fa82789..3d8a0b9f7 100644
--- a/src/lib/marble/TileLevelRangeWidget.h
+++ b/src/lib/marble/TileLevelRangeWidget.h
@@ -1,56 +1,56 @@
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library. If not, see <http://www.gnu.org/licenses/>.
#ifndef MARBLE_TILELEVELRANGEWIDGET_H
#define MARBLE_TILELEVELRANGEWIDGET_H
#include <QWidget>
#include "marble_export.h"
namespace Marble
{
class MARBLE_EXPORT TileLevelRangeWidget: public QWidget
{
Q_OBJECT
public:
- explicit TileLevelRangeWidget( QWidget * const parent = 0, Qt::WindowFlags const f = 0 );
+ explicit TileLevelRangeWidget( QWidget * const parent = nullptr, Qt::WindowFlags const f = nullptr );
~TileLevelRangeWidget() override;
QSize sizeHint() const override;
void setAllowedLevelRange( int const minimumLevel, int const maximumLevel );
void setDefaultLevel( int const );
int topLevel() const;
int bottomLevel() const;
Q_SIGNALS:
void topLevelChanged( int );
void bottomLevelChanged( int );
private Q_SLOTS:
void setMaximumTopLevel( int const );
void setMinimumBottomLevel( int const );
private:
Q_DISABLE_COPY( TileLevelRangeWidget )
class Private;
Private * const d;
};
}
#endif
diff --git a/src/lib/marble/TileScalingTextureMapper.cpp b/src/lib/marble/TileScalingTextureMapper.cpp
index 90dc41eaf..82cdf4725 100644
--- a/src/lib/marble/TileScalingTextureMapper.cpp
+++ b/src/lib/marble/TileScalingTextureMapper.cpp
@@ -1,196 +1,196 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
// local
#include "TileScalingTextureMapper.h"
// posix
#include <cmath>
// Qt
#include <qmath.h>
#include <QImage>
// Marble
#include "GeoPainter.h"
#include "ScanlineTextureMapperContext.h"
#include "StackedTileLoader.h"
#include "TextureColorizer.h"
#include "TileLoaderHelper.h"
#include "StackedTile.h"
#include "MathHelper.h"
#include "ViewportParams.h"
using namespace Marble;
TileScalingTextureMapper::TileScalingTextureMapper( StackedTileLoader *tileLoader, QObject *parent )
: QObject( parent ),
TextureMapperInterface(),
m_tileLoader( tileLoader ),
m_cache( 100 ),
m_radius( 0 )
{
connect( tileLoader, SIGNAL(tileLoaded(TileId)),
this, SLOT(removePixmap(TileId)) );
connect( tileLoader, SIGNAL(cleared()),
this, SLOT(clearPixmaps()) );
}
void TileScalingTextureMapper::mapTexture( GeoPainter *painter,
const ViewportParams *viewport,
int tileZoomLevel,
const QRect &dirtyRect,
TextureColorizer *texColorizer )
{
if ( viewport->radius() <= 0 )
return;
if ( texColorizer || m_radius != viewport->radius() ) {
if ( m_canvasImage.size() != viewport->size() || m_radius != viewport->radius() ) {
const QImage::Format optimalFormat = ScanlineTextureMapperContext::optimalCanvasImageFormat( viewport );
if ( m_canvasImage.size() != viewport->size() || m_canvasImage.format() != optimalFormat ) {
m_canvasImage = QImage( viewport->size(), optimalFormat );
}
if ( !viewport->mapCoversViewport() ) {
m_canvasImage.fill( 0 );
}
m_repaintNeeded = true;
}
if ( m_repaintNeeded ) {
mapTexture( painter, viewport, tileZoomLevel, texColorizer );
m_radius = viewport->radius();
m_repaintNeeded = false;
}
painter->drawImage( dirtyRect, m_canvasImage, dirtyRect );
} else {
mapTexture( painter, viewport, tileZoomLevel, texColorizer );
m_radius = viewport->radius();
}
}
void TileScalingTextureMapper::mapTexture( GeoPainter *painter, const ViewportParams *viewport, int tileZoomLevel, TextureColorizer *texColorizer )
{
const int imageHeight = viewport->height();
const int imageWidth = viewport->width();
const qint64 radius = viewport->radius();
const bool highQuality = ( painter->mapQuality() == HighQuality
|| painter->mapQuality() == PrintQuality );
// Reset backend
m_tileLoader->resetTilehash();
// Calculate translation of center point
const qreal centerLon = viewport->centerLongitude();
const qreal centerLat = viewport->centerLatitude();
const int numTilesX = m_tileLoader->tileRowCount( tileZoomLevel );
const int numTilesY = m_tileLoader->tileColumnCount( tileZoomLevel );
Q_ASSERT( numTilesX > 0 );
Q_ASSERT( numTilesY > 0 );
const qreal xNormalizedCenter = 0.5 + 0.5 * centerLon / M_PI;
const int minTileX = qFloor( numTilesX * ( xNormalizedCenter - imageWidth/( 8.0 * radius ) ) );
const int maxTileX = numTilesX * ( xNormalizedCenter + imageWidth/( 8.0 * radius ) );
const qreal yNormalizedCenter = 0.5 - 0.5 * asinh( tan( centerLat ) ) / M_PI;
const int minTileY = qMax( qreal( numTilesY * ( yNormalizedCenter - imageHeight/( 8.0 * radius ) ) ),
qreal( 0.0 ) );
const int maxTileY = qMin( qreal( numTilesY * ( yNormalizedCenter + imageHeight/( 8.0 * radius ) ) ),
qreal( numTilesY - 1.0 ) );
if ( m_radius != radius ) {
m_cache.clear();
}
if ( texColorizer || m_radius != radius ) {
QPainter imagePainter( &m_canvasImage );
imagePainter.setRenderHint( QPainter::SmoothPixmapTransform, highQuality );
for ( int tileY = minTileY; tileY <= maxTileY; ++tileY ) {
for ( int tileX = minTileX; tileX <= maxTileX; ++tileX ) {
const qreal xLeft = ( 4.0 * radius ) * ( ( tileX ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
const qreal xRight = ( 4.0 * radius ) * ( ( tileX + 1 ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
const qreal yTop = ( 4.0 * radius ) * ( ( tileY ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
const qreal yBottom = ( 4.0 * radius ) * ( ( tileY + 1 ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
const QRectF rect = QRectF( QPointF( xLeft, yTop ), QPointF( xRight, yBottom ) );
const TileId stackedId = TileId( 0, tileZoomLevel, ( ( tileX % numTilesX ) + numTilesX ) % numTilesX, tileY );
const StackedTile *const tile = m_tileLoader->loadTile( stackedId );
imagePainter.drawImage( rect, *tile->resultImage() );
}
}
if ( texColorizer ) {
texColorizer->colorize( &m_canvasImage, viewport, painter->mapQuality() );
}
} else {
painter->save();
painter->setRenderHint( QPainter::SmoothPixmapTransform, highQuality );
for ( int tileY = minTileY; tileY <= maxTileY; ++tileY ) {
for ( int tileX = minTileX; tileX <= maxTileX; ++tileX ) {
const qreal xLeft = ( 4.0 * radius ) * ( ( tileX ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
const qreal xRight = ( 4.0 * radius ) * ( ( tileX + 1 ) / (qreal)numTilesX - xNormalizedCenter ) + ( imageWidth / 2.0 );
const qreal yTop = ( 4.0 * radius ) * ( ( tileY ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
const qreal yBottom = ( 4.0 * radius ) * ( ( tileY + 1 ) / (qreal)numTilesY - yNormalizedCenter ) + ( imageHeight / 2.0 );
const QRectF rect = QRectF( QPointF( xLeft, yTop ), QPointF( xRight, yBottom ) );
const TileId stackedId = TileId( 0, tileZoomLevel, ( ( tileX % numTilesX ) + numTilesX ) % numTilesX, tileY );
const StackedTile *const tile = m_tileLoader->loadTile( stackedId ); // load tile here for every frame, otherwise cleanupTilehash() clears all visible tiles
const QSize size = QSize( qCeil( rect.right() - rect.left() ), qCeil( rect.bottom() - rect.top() ) );
const int cacheHash = 2 * ( size.width() % 2 ) + ( size.height() % 2 );
const TileId cacheId = TileId( cacheHash, stackedId.zoomLevel(), stackedId.x(), stackedId.y() );
const QPixmap *const im_cached = m_cache[cacheId];
const QPixmap *im = im_cached;
- if ( im == 0 ) {
+ if ( im == nullptr ) {
im = new QPixmap( QPixmap::fromImage( tile->resultImage()->scaled( size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ) );
}
painter->drawPixmap( rect.topLeft(), *im );
if (im != im_cached)
m_cache.insert( cacheId, im );
}
}
painter->restore();
}
m_tileLoader->cleanupTilehash();
}
void TileScalingTextureMapper::removePixmap( const TileId &tileId )
{
const TileId stackedTileId( 0, tileId.zoomLevel(), tileId.x(), tileId.y() );
for ( int i = 0; i < 4; ++i ) {
const TileId id = TileId( i, stackedTileId.zoomLevel(), stackedTileId.x(), stackedTileId.y() );
m_cache.remove( id );
}
}
void TileScalingTextureMapper::clearPixmaps()
{
m_cache.clear();
}
#include "moc_TileScalingTextureMapper.cpp"
diff --git a/src/lib/marble/TileScalingTextureMapper.h b/src/lib/marble/TileScalingTextureMapper.h
index 3102d997c..e4d05c8a3 100644
--- a/src/lib/marble/TileScalingTextureMapper.h
+++ b/src/lib/marble/TileScalingTextureMapper.h
@@ -1,61 +1,61 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_TILESCALINGTEXTUREMAPPER_H
#define MARBLE_TILESCALINGTEXTUREMAPPER_H
#include <QObject>
#include "TextureMapperInterface.h"
#include "TileId.h"
#include <QCache>
#include <QImage>
#include <QPixmap>
namespace Marble
{
class StackedTileLoader;
class TileScalingTextureMapper : public QObject, public TextureMapperInterface
{
Q_OBJECT
public:
- explicit TileScalingTextureMapper( StackedTileLoader *tileLoader, QObject *parent = 0 );
+ explicit TileScalingTextureMapper( StackedTileLoader *tileLoader, QObject *parent = nullptr );
void mapTexture( GeoPainter *painter,
const ViewportParams *viewport,
int tileZoomLevel,
const QRect &dirtyRect,
TextureColorizer *texColorizer ) override;
private Q_SLOTS:
void removePixmap( const TileId &tileId );
void clearPixmaps();
private:
void mapTexture( GeoPainter *painter,
const ViewportParams *viewport,
int tileZoomLevel,
TextureColorizer *texColorizer );
private:
StackedTileLoader *const m_tileLoader;
QCache<TileId, const QPixmap> m_cache;
QImage m_canvasImage;
int m_radius;
};
}
#endif
diff --git a/src/lib/marble/TimeControlWidget.h b/src/lib/marble/TimeControlWidget.h
index 97022349f..0db5c5523 100644
--- a/src/lib/marble/TimeControlWidget.h
+++ b/src/lib/marble/TimeControlWidget.h
@@ -1,78 +1,78 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#ifndef MARBLE_TIMECONTROLWIDGET_H
#define MARBLE_TIMECONTROLWIDGET_H
// Qt
#include <QDateTime>
#include <QDialog>
// Marble
#include "marble_export.h"
namespace Ui
{
class TimeControlWidget;
}
namespace Marble
{
class MarbleClock;
class MARBLE_EXPORT TimeControlWidget : public QDialog
{
Q_OBJECT
public:
- explicit TimeControlWidget( MarbleClock* clock, QWidget* parent = 0 );
+ explicit TimeControlWidget( MarbleClock* clock, QWidget* parent = nullptr );
~TimeControlWidget() override;
private Q_SLOTS:
/**
* @brief apply the settings to internal clock
*/
void apply();
/**
* @brief set the newDateTimeEdit to current system time
*/
void nowClicked();
/**
* @brief Set the refreshIntervalSpinBox value to @p seconds.
*/
void updateRefreshRate( int seconds );
/**
* @brief set the text of speedLabel to @p speed
*/
void updateSpeedLabel( int speed );
/**
* @brief update the currentDateTimeEdit to current internal time
*/
void updateDateTime();
protected:
Q_DISABLE_COPY( TimeControlWidget )
void showEvent( QShowEvent* event ) override;
Ui::TimeControlWidget *m_uiWidget;
MarbleClock *m_clock;
QDateTime m_lastDateTime;
};
}
#endif //MARBLE_TIMECONTROLWIDGET_H
diff --git a/src/lib/marble/TinyWebBrowser.cpp b/src/lib/marble/TinyWebBrowser.cpp
index 0900d8861..dbce339d3 100644
--- a/src/lib/marble/TinyWebBrowser.cpp
+++ b/src/lib/marble/TinyWebBrowser.cpp
@@ -1,106 +1,106 @@
//
// This file is part of the Marble Project.
//
// 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 <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008 Simon Hausmann <hausmann@kde.org>
//
// Self
#include "TinyWebBrowser.h"
// Qt
#include <QPointer>
#include <QAction>
#include <QDesktopServices>
#include <QPainter>
#include <QPrintDialog>
#include <QPrinter>
// Marble
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleLocale.h"
namespace Marble
{
class TinyWebBrowserPrivate
{
};
static QString guessWikipediaDomain()
{
const QString code = MarbleLocale::languageCode();
return QLatin1String("https://") + code + QLatin1String(".m.wikipedia.org/");
}
TinyWebBrowser::TinyWebBrowser( QWidget* parent )
: QWebView( parent ),
- d( 0 )
+ d( nullptr )
{
connect( this, SIGNAL(statusBarMessage(QString)),
this, SIGNAL(statusMessage(QString)) );
page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
connect( this, SIGNAL(linkClicked(QUrl)),
this, SLOT(openExternalLink(QUrl)) );
connect( this, SIGNAL(titleChanged(QString)),
this, SLOT(setWindowTitle(QString)) );
pageAction( QWebPage::OpenLinkInNewWindow )->setEnabled( false );
pageAction( QWebPage::OpenLinkInNewWindow )->setVisible( false );
}
TinyWebBrowser::~TinyWebBrowser()
{
// not yet needed
//delete d;
}
void TinyWebBrowser::setWikipediaPath( const QString& relativeUrl )
{
QUrl url(relativeUrl);
if ( url.isRelative() )
url = QUrl( guessWikipediaDomain() ).resolved( url );
load( url );
}
void TinyWebBrowser::print()
{
#ifndef QT_NO_PRINTER
QPrinter printer;
QPointer<QPrintDialog> dlg = new QPrintDialog( &printer, this );
if ( dlg->exec() )
QWebView::print( &printer );
delete dlg;
#endif
}
QWebView *TinyWebBrowser::createWindow( QWebPage::WebWindowType type )
{
TinyWebBrowser *view = new TinyWebBrowser( this );
if ( type == QWebPage::WebModalDialog ) {
view->setWindowModality( Qt::WindowModal );
}
return view;
}
void TinyWebBrowser::openExternalLink( const QUrl& url )
{
QDesktopServices::openUrl( url );
}
} // namespace Marble
#include "moc_TinyWebBrowser.cpp"
diff --git a/src/lib/marble/TinyWebBrowser.h b/src/lib/marble/TinyWebBrowser.h
index f4c54a8e0..c6103b22f 100644
--- a/src/lib/marble/TinyWebBrowser.h
+++ b/src/lib/marble/TinyWebBrowser.h
@@ -1,62 +1,62 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
#ifndef MARBLE_TINYWEBBROWSER_H
#define MARBLE_TINYWEBBROWSER_H
// Qt
#include <QWebView>
// Marble
#include "marble_export.h"
class QString;
class QUrl;
namespace Marble
{
class TinyWebBrowserPrivate;
/**
* This class provides a tiny web browser based on QWebView (WebKit).
* It is different from QWebView as it has the button "Open in new Window"
* disabled per default and instead opens every link in the default web
* browser of the user.
*/
class MARBLE_EXPORT TinyWebBrowser : public QWebView
{
Q_OBJECT
public:
- explicit TinyWebBrowser( QWidget* parent = 0 );
+ explicit TinyWebBrowser( QWidget* parent = nullptr );
~TinyWebBrowser() override;
public Q_SLOTS:
void setWikipediaPath( const QString& relativeUrl );
void print();
Q_SIGNALS:
void statusMessage( const QString& );
protected:
QWebView *createWindow( QWebPage::WebWindowType type ) override;
private Q_SLOTS:
void openExternalLink( const QUrl& );
private:
TinyWebBrowserPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/TourCaptureDialog.cpp b/src/lib/marble/TourCaptureDialog.cpp
index c8ee38f82..f4bd4bf19 100644
--- a/src/lib/marble/TourCaptureDialog.cpp
+++ b/src/lib/marble/TourCaptureDialog.cpp
@@ -1,204 +1,204 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "TourCaptureDialog.h"
#include "ui_TourCaptureDialog.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QTimer>
#include "MarbleWidget.h"
#include "MovieCapture.h"
#include "TourPlayback.h"
namespace Marble {
TourCaptureDialog::TourCaptureDialog(MarbleWidget *widget, QWidget *parent) :
QDialog(parent),
ui(new Ui::TourCaptureDialog),
m_recorder(new MovieCapture(widget, parent)),
- m_playback(0),
+ m_playback(nullptr),
m_writingPossible( true ),
m_current_position( 0.0 )
{
ui->setupUi(this);
m_recorder->setSnapshotMethod(MovieCapture::DataDriven);
ui->progressBar->setValue(0);
connect(ui->fpsSlider, SIGNAL(valueChanged(int)),
ui->fpsSpin, SLOT(setValue(int)));
connect(ui->fpsSpin, SIGNAL(valueChanged(int)),
ui->fpsSlider, SLOT(setValue(int)));
connect(ui->fpsSlider, SIGNAL(valueChanged(int)),
m_recorder, SLOT(setFps(int)));
connect(ui->closeButton, SIGNAL(clicked()),
this, SLOT(close()));
connect(ui->startButton, SIGNAL(clicked()),
this, SLOT(startRecording()));
connect(ui->openButton, SIGNAL(clicked()),
this, SLOT(loadDestinationFile()));
connect(m_recorder, SIGNAL(rateCalculated(double)),
this, SLOT(setRate(double))) ;
connect(m_recorder, SIGNAL(errorOccured()),
this, SLOT(handleError()) );
}
TourCaptureDialog::~TourCaptureDialog()
{
delete ui;
}
void TourCaptureDialog::loadDestinationFile()
{
const QVector<MovieFormat> formats = m_recorder->availableFormats();
if( formats.isEmpty() ) {
QMessageBox::warning( this, tr( "Codecs are unavailable" ), tr( "Supported codecs are not found." ) );
return;
}
QString filter = formats.first().name() + QLatin1String(" (*.") + formats.first().extension() + QLatin1Char(')');
for( int i = 1; i < formats.size(); i++ )
{
filter += QLatin1String(";;") + formats.at(i).name() + QLatin1String(" (*.") + formats.at(i).extension() + QLatin1Char(')');
}
const QString defaultFileName =
ui->destinationEdit->text().isEmpty() ? m_defaultFileName : ui->destinationEdit->text();
const QString destination =
QFileDialog::getSaveFileName(this, tr("Save video file"), defaultFileName,
filter );
if (destination.isEmpty()) {
return;
}
bool supported = false;
for(const MovieFormat &format: formats) {
if (destination.endsWith(QLatin1Char('.') + format.extension())) {
supported = true;
break;
}
}
if (!supported) {
QString formatsExtensions = QLatin1Char('.') + formats.at(0).extension();
for( int i = 1; i < formats.size(); ++i )
{
formatsExtensions += QLatin1String(", .") + formats.at(i).extension();
}
QMessageBox::warning(this, tr("Filename is not valid"),
tr("This file format is not supported. "
"Please, use %1 instead").arg( formatsExtensions ) );
return;
}
ui->destinationEdit->setText(destination);
m_recorder->setFilename(destination);
}
void TourCaptureDialog::startRecording()
{
if( ui->startButton->text() == tr("Start") ){
ui->startButton->setText(tr("Cancel"));
ui->closeButton->setDisabled(true);
const QString path = ui->destinationEdit->text();
if( path.isEmpty() ){
QMessageBox::warning(this, tr("Missing filename"),
tr("Destination video file is not set. "
"I don't know where to save recorded "
"video. Please, specify one."));
return;
}
m_recorder->setSnapshotMethod( MovieCapture::DataDriven );
m_recorder->setFps(ui->fpsSlider->value());
m_recorder->startRecording();
m_current_position = 0.0;
recordNextFrame();
}
else{
ui->startButton->setText(tr("Start"));
m_recorder->cancelRecording();
ui->progressBar->setValue(0);
ui->closeButton->setEnabled(true);
}
}
void TourCaptureDialog::updateProgress(double position)
{
ui->progressBar->setValue(position);
}
void TourCaptureDialog::recordNextFrame()
{
double const shift = 1.0 / ( ui->fpsSlider->value() );
double const duration = m_playback->duration();
if (!m_writingPossible) {
ui->rate->setText(QString("<font color=\"red\">%1</font>").arg(tr("Video writing failed.")));
return;
}
if (ui->startButton->text() == QLatin1String("Start")) {
return;
}
if (m_current_position <= duration) {
m_playback->seek( m_current_position );
m_recorder->recordFrame();
updateProgress( m_current_position * 100 );
m_current_position += shift;
QTimer::singleShot(1, this, SLOT(recordNextFrame()));
} else {
m_recorder->stopRecording();
ui->progressBar->setValue(duration*100);
ui->startButton->setText(tr("Start"));
ui->rate->setText(QString("<font color=\"green\">%1</font>").arg(tr("Video export completed.")));
ui->closeButton->setEnabled(true);
}
}
void TourCaptureDialog::setRate(double rate)
{
ui->rate->setText(QString("%1 KBytes/sec").arg(rate));
}
void TourCaptureDialog::stopRecording()
{
m_recorder->stopRecording();
}
void TourCaptureDialog::setTourPlayback( TourPlayback* playback )
{
m_playback = playback;
ui->progressBar->setMaximum(playback->duration() * 100);
}
void TourCaptureDialog::setDefaultFilename(const QString &filename)
{
m_defaultFileName = filename;
}
void TourCaptureDialog::handleError()
{
m_writingPossible = false;
}
} // namespace Marble
#include "moc_TourCaptureDialog.cpp"
diff --git a/src/lib/marble/TourCaptureDialog.h b/src/lib/marble/TourCaptureDialog.h
index 2c72b9bac..558618cdd 100644
--- a/src/lib/marble/TourCaptureDialog.h
+++ b/src/lib/marble/TourCaptureDialog.h
@@ -1,60 +1,60 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#ifndef TOURCAPTUREDIALOG_H
#define TOURCAPTUREDIALOG_H
#include <QDialog>
#include "marble_export.h"
namespace Ui {
class TourCaptureDialog;
}
namespace Marble {
class MarbleWidget;
class MovieCapture;
class TourPlayback;
class MARBLE_EXPORT TourCaptureDialog : public QDialog
{
Q_OBJECT
public:
- explicit TourCaptureDialog(MarbleWidget *widget, QWidget *parent = 0);
+ explicit TourCaptureDialog(MarbleWidget *widget, QWidget *parent = nullptr);
~TourCaptureDialog() override;
public Q_SLOTS:
void startRecording();
void stopRecording();
void setRate( double rate );
void setTourPlayback( TourPlayback* playback );
void setDefaultFilename( const QString &filename );
void handleError();
private Q_SLOTS:
void loadDestinationFile();
void updateProgress( double position );
void recordNextFrame();
private:
Ui::TourCaptureDialog *ui;
MovieCapture *m_recorder;
TourPlayback *m_playback;
bool m_writingPossible;
double m_current_position;
QString m_defaultFileName;
};
} // namespace Marble
#endif // MOVIECAPTUREDIALOG_H
diff --git a/src/lib/marble/TourControlEditWidget.h b/src/lib/marble/TourControlEditWidget.h
index 9476121a4..2cb42fbe7 100644
--- a/src/lib/marble/TourControlEditWidget.h
+++ b/src/lib/marble/TourControlEditWidget.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
// Copyright 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef TOURCONTROLEDITWIDGET_H
#define TOURCONTROLEDITWIDGET_H
#include <QWidget>
#include <QPersistentModelIndex>
class QRadioButton;
class QToolButton;
namespace Marble
{
class GeoDataTourControl;
class TourControlEditWidget: public QWidget
{
Q_OBJECT
public:
- explicit TourControlEditWidget( const QModelIndex& index, QWidget* parent=0 );
+ explicit TourControlEditWidget( const QModelIndex& index, QWidget* parent=nullptr );
bool editable() const;
Q_SIGNALS:
void editingDone( const QModelIndex& index );
public Q_SLOTS:
void setEditable( bool editable );
private Q_SLOTS:
void save();
private:
GeoDataTourControl* tourControlElement();
QPersistentModelIndex m_index;
QRadioButton *m_radio_play;
QRadioButton *m_radio_pause;
QToolButton *m_button;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/TourItemDelegate.cpp b/src/lib/marble/TourItemDelegate.cpp
index 153a870b7..421b2a5a9 100644
--- a/src/lib/marble/TourItemDelegate.cpp
+++ b/src/lib/marble/TourItemDelegate.cpp
@@ -1,537 +1,537 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
// Copyright 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include <QAbstractTextDocumentLayout>
#include <QStyleOptionButton>
#include <QPainter>
#include <QApplication>
#include <QListView>
#include <QPointer>
#include "TourItemDelegate.h"
#include "MarblePlacemarkModel.h"
#include "geodata/data/GeoDataContainer.h"
#include "geodata/data/GeoDataFlyTo.h"
#include "geodata/data/GeoDataObject.h"
#include "geodata/data/GeoDataTourControl.h"
#include "geodata/data/GeoDataWait.h"
#include "geodata/data/GeoDataCoordinates.h"
#include "geodata/data/GeoDataSoundCue.h"
#include "geodata/data/GeoDataAnimatedUpdate.h"
#include "FlyToEditWidget.h"
#include "TourControlEditWidget.h"
#include "SoundCueEditWidget.h"
#include "WaitEditWidget.h"
#include "RemoveItemEditWidget.h"
#include "GeoDataPlacemark.h"
#include "GeoDataCreate.h"
#include "GeoDataUpdate.h"
#include "GeoDataDelete.h"
#include "GeoDataChange.h"
#include "EditPlacemarkDialog.h"
#include "MarbleWidget.h"
#include "GeoDataPlaylist.h"
#include "TourWidget.h"
namespace Marble
{
TourItemDelegate::TourItemDelegate( QListView* view, MarbleWidget* widget, TourWidget* tour ):
m_listView( view ), m_widget( widget ), m_editable( true ), m_tourWidget( tour )
{
QObject::connect( this, SIGNAL(editingChanged(QModelIndex)), m_listView, SLOT(update(QModelIndex)) );
m_listView->setEditTriggers( QAbstractItemView::NoEditTriggers );
}
void TourItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
QStyleOptionViewItem styleOption = option;
styleOption.text = QString();
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &styleOption, painter);
QAbstractTextDocumentLayout::PaintContext paintContext;
if (styleOption.state & QStyle::State_Selected) {
paintContext.palette.setColor(QPalette::Text,
styleOption.palette.color(QPalette::Active, QPalette::HighlightedText));
}
if ( m_listView->currentIndex() == index && m_tourWidget->isPlaying() ) {
painter->fillRect( option.rect, paintContext.palette.color( QPalette::Midlight ) );
QStyledItemDelegate::paint( painter, option, index );
}
QTextDocument label;
QRect const labelRect = position(Label, option);
label.setTextWidth( labelRect.width() );
label.setDefaultFont( option.font );
QStyleOptionButton button;
button.state = option.state;
button.palette = option.palette;
button.features = QStyleOptionButton::None;
button.iconSize = QSize( 16, 16 );
button.state &= ~QStyle::State_HasFocus;
if( !editable() ) {
button.state &= ~QStyle::State_Enabled;
}
QRect const iconRect = position( GeoDataElementIcon, option );
const GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data(MarblePlacemarkModel::ObjectPointerRole));
if (!m_editingIndices.contains(index)) {
if (const GeoDataTourControl *tourControl = geodata_cast<GeoDataTourControl>(object)) {
GeoDataTourControl::PlayMode const playMode = tourControl->playMode();
if ( playMode == GeoDataTourControl::Play ) {
label.setHtml( tr("Play the tour") );
} else if ( playMode == GeoDataTourControl::Pause ) {
label.setHtml( tr("Pause the tour") );
}
painter->save();
painter->translate( labelRect.topLeft() );
painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
label.documentLayout()->draw( painter, paintContext );
painter->restore();
button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
QRect const buttonRect = position( EditButton, option );;
button.rect = buttonRect;
QIcon const icon = QIcon(QStringLiteral(":/marble/media-playback-pause.png"));
painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
} else if (geodata_cast<GeoDataFlyTo>(object)) {
GeoDataCoordinates const flyToCoords = index.data( MarblePlacemarkModel::CoordinateRole ).value<GeoDataCoordinates>();
label.setHtml( flyToCoords.toString() );
button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
painter->save();
painter->translate( labelRect.topLeft() );
painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
label.documentLayout()->draw( painter, paintContext );
painter->restore();
QRect const buttonRect = position( EditButton, option );
button.rect = buttonRect;
QIcon const icon = QIcon(QStringLiteral(":/marble/flag.png"));
painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
} else if (const GeoDataWait *wait = geodata_cast<GeoDataWait>(object)) {
label.setHtml( tr("Wait for %1 seconds").arg( QString::number( wait->duration() ) ) );
painter->save();
painter->translate( labelRect.topLeft() );
painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
label.documentLayout()->draw( painter, paintContext );
painter->restore();
button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
QRect const buttonRect = position( EditButton, option );
button.rect = buttonRect;
QIcon const icon = QIcon(QStringLiteral(":/marble/player-time.png"));
painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
} else if (const GeoDataSoundCue *soundCue = geodata_cast<GeoDataSoundCue>(object)) {
label.setHtml(soundCue->href().section(QLatin1Char('/'), -1));
painter->save();
painter->translate( labelRect.topLeft() );
painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
label.documentLayout()->draw( painter, paintContext );
painter->restore();
QStyleOptionButton playButton = button;
button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
QRect const buttonRect = position( EditButton, option );
button.rect = buttonRect;
playButton.icon = QIcon(QStringLiteral(":/marble/playback-play.png"));
QRect const playButtonRect = position( ActionButton, option );
playButton.rect = playButtonRect;
QApplication::style()->drawControl( QStyle::CE_PushButton, &playButton, painter );
QIcon const icon = QIcon(QStringLiteral(":/marble/audio-x-generic.png"));
painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
} else if (const GeoDataAnimatedUpdate *animUpdate = geodata_cast<GeoDataAnimatedUpdate>(object)) {
const GeoDataUpdate *update = animUpdate->update();
bool ok = false;
QString iconString;
if( update && update->create() && update->create()->size() != 0
&& (dynamic_cast<const GeoDataContainer *>(&update->create()->first()))) {
const GeoDataContainer *container = static_cast<const GeoDataContainer*>(update->create()->child(0));
if( container->size() > 0 ) {
label.setHtml( tr( "Create item %1" ).arg( container->first().id() ) );
ok = true;
iconString = QStringLiteral(":/icons/add-placemark.png");
}
} else if( update && update->getDelete() && update->getDelete()->size() != 0 ){
label.setHtml( tr( "Remove item %1" ).arg( update->getDelete()->first().targetId() ) );
ok = true;
iconString = QStringLiteral(":/icons/remove.png");
} else if( update && update->change() && update->change()->size() != 0 ){
label.setHtml( tr( "Change item %1" ).arg( update->change()->first().targetId() ) );
ok = true;
iconString = QStringLiteral(":/marble/document-edit.png");
}
if( update && !ok ) {
label.setHtml( tr( "Update items" ) );
button.state &= ~QStyle::State_Enabled & ~QStyle::State_Sunken;
}
painter->save();
painter->translate( labelRect.topLeft() );
painter->setClipRect( 0, 0, labelRect.width(), labelRect.height() );
label.documentLayout()->draw( painter, paintContext );
painter->restore();
button.icon = QIcon(QStringLiteral(":/marble/document-edit.png"));
QRect const buttonRect = position( EditButton, option );
button.rect = buttonRect;
QIcon const icon = QIcon( iconString );
painter->drawPixmap( iconRect, icon.pixmap( iconRect.size() ) );
}
}
QApplication::style()->drawControl( QStyle::CE_PushButton, &button, painter );
}
QRect TourItemDelegate::position( Element element, const QStyleOptionViewItem &option )
{
QPoint const topCol1 = option.rect.topLeft() + QPoint(10, 10);
QPoint const topCol2 = topCol1 + QPoint(30, 0);
QPoint const topCol3 = topCol2 + QPoint(210, 0);
QPoint const topCol4 = topCol3 + QPoint(30, 0);
QSize const labelSize = QSize(220, 30);
QSize const iconsSize = QSize(22, 22);
switch(element)
{
case GeoDataElementIcon:
return QRect( topCol1, iconsSize );
case Label:
return QRect( topCol2, labelSize );
case EditButton:
return QRect( topCol3, iconsSize );
case ActionButton:
return QRect( topCol4, iconsSize );
}
return QRect();
}
QStringList TourItemDelegate::findIds(const GeoDataPlaylist &playlist, bool onlyFeatures)
{
QStringList result;
for (int i = 0; i < playlist.size(); ++i) {
const GeoDataTourPrimitive *primitive = playlist.primitive(i);
if( !primitive->id().isEmpty() && !onlyFeatures ) {
result << primitive->id();
}
if (const GeoDataAnimatedUpdate *animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
- if( animatedUpdate->update() != 0 ) {
+ if( animatedUpdate->update() != nullptr ) {
const GeoDataUpdate *update = animatedUpdate->update();
if( !update->id().isEmpty() && !onlyFeatures ) {
result << update->id();
}
- if( update->create() != 0 ) {
+ if( update->create() != nullptr ) {
if( !update->create()->id().isEmpty() && !onlyFeatures ) {
result << update->create()->id();
}
for( int j = 0; j < update->create()->size(); ++j ) {
if( !update->create()->at( j ).id().isEmpty() ) {
result << update->create()->at( j ).id();
}
}
}
- if( update->change() != 0 ) {
+ if( update->change() != nullptr ) {
if( !update->change()->id().isEmpty() && !onlyFeatures ) {
result << update->change()->id();
}
for( int j = 0; j < update->change()->size(); ++j ) {
if( !update->change()->at( j ).id().isEmpty() ) {
result << update->change()->at( j ).id();
}
}
}
- if( update->getDelete() != 0 ) {
+ if( update->getDelete() != nullptr ) {
if( !update->getDelete()->id().isEmpty() && !onlyFeatures ) {
result << update->getDelete()->id();
}
for( int j = 0; j < update->getDelete()->size(); ++j ) {
if( !update->getDelete()->at( j ).id().isEmpty() ) {
result << update->getDelete()->at( j ).id();
}
}
}
}
}
}
return result;
}
GeoDataPlaylist *TourItemDelegate::playlist() const
{
QModelIndex const rootIndex = m_listView->rootIndex();
if( rootIndex.isValid() ) {
GeoDataObject *rootObject = static_cast<GeoDataObject*>( rootIndex.internalPointer() );
if (GeoDataPlaylist *playlist = geodata_cast<GeoDataPlaylist>(rootObject)) {
return playlist;
}
}
- return 0;
+ return nullptr;
}
QSize TourItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED( option );
Q_UNUSED( index );
return QSize(290,50);
}
QWidget* TourItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
Q_UNUSED( option );
GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data( MarblePlacemarkModel::ObjectPointerRole ) );
if (geodata_cast<GeoDataFlyTo>(object)) {
FlyToEditWidget* widget = new FlyToEditWidget(index, m_widget, parent);
widget->setFirstFlyTo( m_firstFlyTo );
connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
connect( this, SIGNAL(firstFlyToChanged(QPersistentModelIndex)), widget, SLOT(setFirstFlyTo(QPersistentModelIndex)) );
return widget;
} else if (geodata_cast<GeoDataTourControl>(object)) {
TourControlEditWidget* widget = new TourControlEditWidget(index, parent);
connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
return widget;
} else if (geodata_cast<GeoDataWait>(object)) {
WaitEditWidget* widget = new WaitEditWidget(index, parent);
connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
return widget;
} else if (geodata_cast<GeoDataSoundCue>(object)) {
SoundCueEditWidget* widget = new SoundCueEditWidget(index, parent);
connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
return widget;
} else if (geodata_cast<GeoDataAnimatedUpdate>(object)) {
RemoveItemEditWidget* widget = new RemoveItemEditWidget(index, parent);
GeoDataPlaylist *playlistObject = playlist();
- if( playlistObject != 0 ) {
+ if( playlistObject != nullptr ) {
widget->setFeatureIds(findIds(*playlistObject));
}
widget->setDefaultFeatureId( m_defaultFeatureId );
connect(widget, SIGNAL(editingDone(QModelIndex)), this, SLOT(closeEditor(QModelIndex)));
connect( this, SIGNAL(editableChanged(bool)), widget, SLOT(setEditable(bool)) );
connect( this, SIGNAL(featureIdsChanged(QStringList)), widget, SLOT(setFeatureIds(QStringList)) );
connect( this, SIGNAL(defaultFeatureIdChanged(QString)), widget, SLOT(setDefaultFeatureId(QString)) );
return widget;
}
- return 0;
+ return nullptr;
}
bool TourItemDelegate::editable() const
{
return m_editable;
}
void TourItemDelegate::setEditable( bool editable )
{
if( m_editable != editable ) {
m_editable = editable;
emit editableChanged( m_editable );
}
}
QModelIndex TourItemDelegate::firstFlyTo() const
{
return m_firstFlyTo;
}
bool TourItemDelegate::editAnimatedUpdate(GeoDataAnimatedUpdate *animatedUpdate, bool create)
{
- if( animatedUpdate->update() == 0 ) {
+ if( animatedUpdate->update() == nullptr ) {
return false;
}
- GeoDataFeature *feature = 0;
- if( create && !( animatedUpdate->update()->create() == 0 || animatedUpdate->update()->create()->size() == 0 ) ) {
+ GeoDataFeature *feature = nullptr;
+ if( create && !( animatedUpdate->update()->create() == nullptr || animatedUpdate->update()->create()->size() == 0 ) ) {
GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( animatedUpdate->update()->create()->child( 0 ) );
- if( container != 0 && container->size() ) {
+ if( container != nullptr && container->size() ) {
feature = container->child( 0 );
}
- } else if ( !create && !( animatedUpdate->update()->change() == 0 || animatedUpdate->update()->change()->size() == 0 ) ) {
+ } else if ( !create && !( animatedUpdate->update()->change() == nullptr || animatedUpdate->update()->change()->size() == 0 ) ) {
GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( animatedUpdate->update()->change()->child( 0 ) );
- if( container != 0 && container->size() ) {
+ if( container != nullptr && container->size() ) {
feature = container->child( 0 );
}
}
- if( feature == 0 ) {
+ if( feature == nullptr ) {
return false;
}
QStringList ids;
GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>( feature );
if( !create ) {
if( placemark->targetId().isEmpty() && !defaultFeatureId().isEmpty() ) {
GeoDataFeature *feature = findFeature( defaultFeatureId() );
- if (GeoDataPlacemark *targetPlacemark = (feature != 0 ? geodata_cast<GeoDataPlacemark>(feature) : 0)) {
+ if (GeoDataPlacemark *targetPlacemark = (feature != nullptr ? geodata_cast<GeoDataPlacemark>(feature) : nullptr)) {
animatedUpdate->update()->change()->placemarkList().remove( 0 );
delete placemark;
placemark = new GeoDataPlacemark( *targetPlacemark );
animatedUpdate->update()->change()->placemarkList().insert( 0, placemark );
placemark->setTargetId( defaultFeatureId() );
placemark->setId(QString());
}
}
}
QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog( placemark, nullptr, m_widget );
if( create ) {
dialog->setWindowTitle( QObject::tr( "Add Placemark to Tour" ) );
} else {
dialog->setWindowTitle( QObject::tr( "Change Placemark in Tour" ) );
dialog->setTargetIdFieldVisible( true );
dialog->setIdFieldVisible( false );
}
GeoDataPlaylist* playlistObject = playlist();
- if( playlistObject != 0 ) {
+ if( playlistObject != nullptr ) {
ids.append(findIds(*playlistObject, true));
}
ids.removeOne( placemark->id() );
if( create ) {
dialog->setIdFilter( ids );
} else {
dialog->setTargetIds( ids );
}
bool status = dialog->exec();
if( !create ) {
placemark->setId(QString());
}
return status;
}
QString TourItemDelegate::defaultFeatureId() const
{
return m_defaultFeatureId;
}
GeoDataFeature *TourItemDelegate::findFeature(const QString &id) const
{
GeoDataPlaylist *playlistObject = playlist();
- if( playlistObject == 0 ) {
- return 0;
+ if( playlistObject == nullptr ) {
+ return nullptr;
}
- GeoDataFeature *result = 0;
+ GeoDataFeature *result = nullptr;
for( int i = 0; i < playlistObject->size(); ++i ) {
GeoDataTourPrimitive *primitive = playlistObject->primitive( i );
if (GeoDataAnimatedUpdate *animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
- if( animatedUpdate->update() != 0 ) {
+ if( animatedUpdate->update() != nullptr ) {
GeoDataUpdate *update = animatedUpdate->update();
- if( update->create() != 0 ) {
+ if( update->create() != nullptr ) {
for( int j = 0; j < update->create()->featureList().size(); ++j ) {
if( update->create()->at( j ).id() == id ) {
result = update->create()->featureList().at( j );
}
}
}
- if( update->change() != 0 ) {
+ if( update->change() != nullptr ) {
for( int j = 0; j < update->change()->featureList().size(); ++j ) {
if( update->change()->at( j ).id() == id ) {
result = update->change()->featureList().at( j );
}
}
}
- if( update->getDelete() != 0 ) {
+ if( update->getDelete() != nullptr ) {
for( int j = 0; j < update->getDelete()->featureList().size(); ++j ) {
if( update->getDelete()->at( j ).id() == id ) {
result = update->getDelete()->featureList().at( j );
}
}
}
}
}
}
return result;
}
void TourItemDelegate::setFirstFlyTo(const QPersistentModelIndex &index )
{
m_firstFlyTo = index;
emit firstFlyToChanged( m_firstFlyTo );
}
void TourItemDelegate::setDefaultFeatureId(const QString &id)
{
m_defaultFeatureId = id;
const QStringList ids = playlist() ? findIds(*playlist()) : QStringList();
emit featureIdsChanged( ids );
emit defaultFeatureIdChanged( id );
}
bool TourItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
{
Q_UNUSED( model );
if ( ( event->type() == QEvent::MouseButtonRelease ) && editable() ) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
QRect editRect = position( EditButton, option );
if ( editRect.contains( mouseEvent->pos() ) ) {
if( m_editingIndices.contains( index ) ) {
m_editingIndices.removeOne( index );
emit editingChanged( index );
return true;
}else{
GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data( MarblePlacemarkModel::ObjectPointerRole ) );
if (GeoDataAnimatedUpdate *animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(object)) {
if( animatedUpdate->update() && animatedUpdate->update()->create() ) {
if( editAnimatedUpdate( animatedUpdate ) ) {
setDefaultFeatureId( m_defaultFeatureId );
}
} else if( animatedUpdate->update() && animatedUpdate->update()->change() ) {
editAnimatedUpdate( animatedUpdate, false );
} else if ( animatedUpdate->update() && animatedUpdate->update()->getDelete() ) {
m_editingIndices.append( index );
m_listView->openPersistentEditor( index );
}
} else {
m_editingIndices.append( index );
m_listView->openPersistentEditor( index );
}
}
emit editingChanged( index );
return true;
}
}
return false;
}
void TourItemDelegate::closeEditor( const QModelIndex &index )
{
emit edited( index );
m_listView->closePersistentEditor( index );
m_editingIndices.removeOne( index );
}
}
#include "moc_TourItemDelegate.cpp"
diff --git a/src/lib/marble/TourPlayback.cpp b/src/lib/marble/TourPlayback.cpp
index 94516d981..fee849cd4 100644
--- a/src/lib/marble/TourPlayback.cpp
+++ b/src/lib/marble/TourPlayback.cpp
@@ -1,311 +1,311 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "TourPlayback.h"
#include <QList>
#include <QUrl>
#include <QPointer>
#include "MarbleDebug.h"
#include "MarbleWidget.h"
#include "PopupLayer.h"
#include "GeoDataPoint.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPlaylist.h"
#include "GeoDataTour.h"
#include "GeoDataWait.h"
#include "GeoDataFlyTo.h"
#include "GeoDataLookAt.h"
#include "GeoDataTourControl.h"
#include "GeoDataSoundCue.h"
#include "GeoDataAnimatedUpdate.h"
#include "MarbleModel.h"
#include "GeoDataTreeModel.h"
#include "PlaybackFlyToItem.h"
#include "PlaybackAnimatedUpdateItem.h"
#include "PlaybackWaitItem.h"
#include "PlaybackTourControlItem.h"
#include "PlaybackSoundCueItem.h"
#include "SerialTrack.h"
#include "SoundTrack.h"
#include "AnimatedUpdateTrack.h"
namespace Marble
{
class TourPlaybackPrivate
{
public:
TourPlaybackPrivate();
~TourPlaybackPrivate();
GeoDataTour *m_tour;
bool m_pause;
SerialTrack m_mainTrack;
QList<SoundTrack*> m_soundTracks;
QList<AnimatedUpdateTrack*> m_animatedUpdateTracks;
GeoDataFlyTo m_mapCenter;
QPointer<MarbleWidget> m_widget;
QUrl m_baseUrl;
};
TourPlaybackPrivate::TourPlaybackPrivate() :
- m_tour( 0 ),
+ m_tour( nullptr ),
m_pause( false ),
m_mainTrack(),
- m_widget( 0 )
+ m_widget( nullptr )
{
// do nothing
}
TourPlaybackPrivate::~TourPlaybackPrivate()
{
qDeleteAll(m_soundTracks);
qDeleteAll(m_animatedUpdateTracks);
}
TourPlayback::TourPlayback(QObject *parent) :
QObject(parent),
d(new TourPlaybackPrivate())
{
connect( &d->m_mainTrack, SIGNAL(centerOn(GeoDataCoordinates)), this, SLOT(centerOn(GeoDataCoordinates)) );
connect( &d->m_mainTrack, SIGNAL(progressChanged(double)), this, SIGNAL(progressChanged(double)) );
connect( &d->m_mainTrack, SIGNAL(finished()), this, SLOT(stopTour()) );
connect( &d->m_mainTrack, SIGNAL(itemFinished(int)), this, SLOT(handleFinishedItem(int)) );
}
TourPlayback::~TourPlayback()
{
stop();
delete d;
}
void TourPlayback::handleFinishedItem( int index )
{
emit itemFinished( index );
}
void TourPlayback::stopTour()
{
for( SoundTrack* track: d->m_soundTracks ){
track->stop();
track->setPaused( false );
}
for( int i = d->m_animatedUpdateTracks.size()-1; i >= 0; i-- ){
d->m_animatedUpdateTracks[ i ]->stop();
d->m_animatedUpdateTracks[ i ]->setPaused( false );
}
emit finished();
}
void TourPlayback::showBalloon( GeoDataPlacemark* placemark )
{
GeoDataPoint* point = static_cast<GeoDataPoint*>( placemark->geometry() );
d->m_widget->popupLayer()->setCoordinates( point->coordinates(), Qt::AlignRight | Qt::AlignVCenter );
d->m_widget->popupLayer()->setContent( placemark->description(), d->m_baseUrl );
d->m_widget->popupLayer()->setVisible( true );
d->m_widget->popupLayer()->setSize(QSizeF(500, 520));
}
void TourPlayback::hideBalloon()
{
if( d->m_widget ){
d->m_widget->popupLayer()->setVisible( false );
}
}
bool TourPlayback::isPlaying() const
{
return !d->m_pause;
}
void TourPlayback::setMarbleWidget(MarbleWidget* widget)
{
d->m_widget = widget;
connect( this, SIGNAL(added(GeoDataContainer*,GeoDataFeature*,int)),
d->m_widget->model()->treeModel(), SLOT(addFeature(GeoDataContainer*,GeoDataFeature*,int)) );
connect( this, SIGNAL(removed(GeoDataFeature*)),
d->m_widget->model()->treeModel(), SLOT(removeFeature(GeoDataFeature*)) );
connect( this, SIGNAL(updated(GeoDataFeature*)),
d->m_widget->model()->treeModel(), SLOT(updateFeature(GeoDataFeature*)) );
}
void TourPlayback::setBaseUrl( const QUrl &baseUrl )
{
d->m_baseUrl = baseUrl;
}
QUrl TourPlayback::baseUrl() const
{
return d->m_baseUrl;
}
void TourPlayback::centerOn( const GeoDataCoordinates &coordinates )
{
if ( d->m_widget ) {
GeoDataLookAt lookat;
lookat.setCoordinates( coordinates );
lookat.setRange( coordinates.altitude() );
d->m_widget->flyTo( lookat, Instant );
}
}
void TourPlayback::setTour(GeoDataTour *tour)
{
d->m_tour = tour;
if ( !d->m_tour ) {
clearTracks();
return;
}
updateTracks();
}
void TourPlayback::play()
{
d->m_pause = false;
GeoDataLookAt* lookat = new GeoDataLookAt( d->m_widget->lookAt() );
lookat->setAltitude( lookat->range() );
d->m_mapCenter.setView( lookat );
d->m_mainTrack.play();
for( SoundTrack* track: d->m_soundTracks) {
track->play();
}
for( AnimatedUpdateTrack* track: d->m_animatedUpdateTracks) {
track->play();
}
}
void TourPlayback::pause()
{
d->m_pause = true;
d->m_mainTrack.pause();
for( SoundTrack* track: d->m_soundTracks) {
track->pause();
}
for( AnimatedUpdateTrack* track: d->m_animatedUpdateTracks) {
track->pause();
}
}
void TourPlayback::stop()
{
d->m_pause = true;
d->m_mainTrack.stop();
for( SoundTrack* track: d->m_soundTracks) {
track->stop();
}
for( int i = d->m_animatedUpdateTracks.size()-1; i >= 0; i-- ){
d->m_animatedUpdateTracks[ i ]->stop();
}
hideBalloon();
}
void TourPlayback::seek( double value )
{
double const offset = qBound( 0.0, value, d->m_mainTrack.duration() );
d->m_mainTrack.seek( offset );
for( SoundTrack* track: d->m_soundTracks ){
track->seek( offset );
}
for( AnimatedUpdateTrack* track: d->m_animatedUpdateTracks ){
track->seek( offset );
}
}
int TourPlayback::mainTrackSize()
{
return d->m_mainTrack.size();
}
PlaybackItem* TourPlayback::mainTrackItemAt( int i )
{
return d->m_mainTrack.at( i );
}
void TourPlayback::updateTracks()
{
clearTracks();
double delay = 0;
for( int i = 0; i < d->m_tour->playlist()->size(); i++){
GeoDataTourPrimitive* primitive = d->m_tour->playlist()->primitive( i );
if (const auto flyTo = geodata_cast<GeoDataFlyTo>(primitive)){
d->m_mainTrack.append( new PlaybackFlyToItem( flyTo ) );
delay += flyTo->duration();
}
else if (const auto wait = geodata_cast<GeoDataWait>(primitive)) {
d->m_mainTrack.append( new PlaybackWaitItem( wait ) );
delay += wait->duration();
}
else if (const auto tourControl = geodata_cast<GeoDataTourControl>(primitive)) {
d->m_mainTrack.append( new PlaybackTourControlItem( tourControl ) );
}
else if (const auto soundCue = geodata_cast<GeoDataSoundCue>(primitive)) {
PlaybackSoundCueItem *item = new PlaybackSoundCueItem( soundCue );
SoundTrack *track = new SoundTrack( item );
track->setDelayBeforeTrackStarts( delay );
d->m_soundTracks.append( track );
}
else if (const auto animatedUpdate = geodata_cast<GeoDataAnimatedUpdate>(primitive)) {
PlaybackAnimatedUpdateItem *item = new PlaybackAnimatedUpdateItem( animatedUpdate );
AnimatedUpdateTrack *track = new AnimatedUpdateTrack( item );
track->setDelayBeforeTrackStarts( delay + animatedUpdate->delayedStart() );
d->m_animatedUpdateTracks.append( track );
connect( track, SIGNAL(balloonHidden()), this, SLOT(hideBalloon()) );
connect( track, SIGNAL(balloonShown(GeoDataPlacemark*)), this, SLOT(showBalloon(GeoDataPlacemark*)) );
connect( track, SIGNAL(updated(GeoDataFeature*)), this, SIGNAL(updated(GeoDataFeature*)) );
connect( track, SIGNAL(added(GeoDataContainer*,GeoDataFeature*,int)), this, SIGNAL(added(GeoDataContainer*,GeoDataFeature*,int)) );
connect( track, SIGNAL(removed(const GeoDataFeature*)), this, SIGNAL(removed(const GeoDataFeature*)) );
}
}
Q_ASSERT( d->m_widget );
GeoDataLookAt* lookat = new GeoDataLookAt( d->m_widget->lookAt() );
lookat->setAltitude( lookat->range() );
d->m_mapCenter.setView( lookat );
PlaybackFlyToItem* mapCenterItem = new PlaybackFlyToItem( &d->m_mapCenter );
PlaybackFlyToItem* before = mapCenterItem;
for ( int i=0; i<d->m_mainTrack.size(); ++i ) {
PlaybackFlyToItem* item = qobject_cast<PlaybackFlyToItem*>( d->m_mainTrack.at(i) );
if ( item ) {
item->setBefore( before );
before = item;
}
}
- PlaybackFlyToItem* next = 0;
+ PlaybackFlyToItem* next = nullptr;
for ( int i=d->m_mainTrack.size()-1; i>=0; --i ) {
PlaybackFlyToItem* item = qobject_cast<PlaybackFlyToItem*>( d->m_mainTrack.at(i) );
if ( item ) {
item->setNext( next );
next = item;
}
}
}
void TourPlayback::clearTracks()
{
d->m_mainTrack.clear();
qDeleteAll(d->m_soundTracks);
qDeleteAll(d->m_animatedUpdateTracks);
d->m_soundTracks.clear();
d->m_animatedUpdateTracks.clear();
}
double TourPlayback::duration() const
{
return d->m_mainTrack.duration();
}
} // namespace Marble
#include "moc_TourPlayback.cpp"
diff --git a/src/lib/marble/TourPlayback.h b/src/lib/marble/TourPlayback.h
index deb32cbce..e7ef5b717 100644
--- a/src/lib/marble/TourPlayback.h
+++ b/src/lib/marble/TourPlayback.h
@@ -1,102 +1,102 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#ifndef TOURPLAYBACK_H
#define TOURPLAYBACK_H
#include <QObject>
#include "marble_export.h"
class QUrl;
namespace Marble
{
class MarbleWidget;
class GeoDataCoordinates;
class GeoDataTour;
class GeoDataPlacemark;
class GeoDataFeature;
class GeoDataContainer;
class PlaybackItem;
class TourPlaybackPrivate;
class MARBLE_EXPORT TourPlayback : public QObject
{
Q_OBJECT
public:
- explicit TourPlayback(QObject *parent=0);
+ explicit TourPlayback(QObject *parent=nullptr);
~TourPlayback() override;
void setTour(GeoDataTour *tour);
void setMarbleWidget( MarbleWidget *widget );
/**
* @brief setBaseUrl - sets base url for using in QWebView.
*/
void setBaseUrl( const QUrl &baseUrl );
/**
* @brief baseUrl - gets base url which is using in QWebView.
*/
QUrl baseUrl() const;
/** Tour duration in seconds */
double duration() const;
bool isPlaying() const;
void play();
void pause();
void stop();
/**
* Seek to the given timestamp (in seconds)
* @param offset Target timestamp in seconds in the range 0..duration()
*/
void seek( double offset );
/** Size of main track (flyto, wait, tourcontrol primitives) **/
int mainTrackSize();
/**
* Element of main track (flyto, wait, tourcontrol primitives)
* @param i Position of element.
*/
PlaybackItem* mainTrackItemAt( int i );
public Q_SLOTS:
void updateTracks();
void clearTracks();
Q_SIGNALS:
void finished();
void paused();
void stopped();
void progressChanged( double );
void updated( GeoDataFeature* );
void added( GeoDataContainer *parent, GeoDataFeature *feature, int row );
void removed(GeoDataFeature *feature);
void itemFinished( int index );
private Q_SLOTS:
void stopTour();
void showBalloon( GeoDataPlacemark* );
void hideBalloon();
void centerOn( const GeoDataCoordinates &coordinates );
void handleFinishedItem( int index );
private:
TourPlaybackPrivate * const d;
};
} // namespace Marble
#endif // TOURPLAYBACK_H
diff --git a/src/lib/marble/TourWidget.cpp b/src/lib/marble/TourWidget.cpp
index 8bbf2e9b7..235a29a57 100644
--- a/src/lib/marble/TourWidget.cpp
+++ b/src/lib/marble/TourWidget.cpp
@@ -1,972 +1,972 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "TourWidget.h"
#include "FlyToEditWidget.h"
#include "TourControlEditWidget.h"
#include "WaitEditWidget.h"
#include "SoundCueEditWidget.h"
#include "TourItemDelegate.h"
#include "ui_TourWidget.h"
#include "GeoDataPlacemark.h"
#include "GeoDataDocument.h"
#include "GeoDataLookAt.h"
#include "GeoDataPlaylist.h"
#include "GeoDataTour.h"
#include "GeoDataTreeModel.h"
#include "GeoDataFlyTo.h"
#include "GeoDataWait.h"
#include "GeoDataCamera.h"
#include "GeoDataTourControl.h"
#include "GeoDataSoundCue.h"
#include "GeoDataCreate.h"
#include "GeoDataUpdate.h"
#include "GeoDataDelete.h"
#include "GeoDataChange.h"
#include "GeoDataAnimatedUpdate.h"
#include "GeoDataDocumentWriter.h"
#include "KmlElementDictionary.h"
#include "MarbleModel.h"
#include "MarblePlacemarkModel.h"
#include "MarbleWidget.h"
#include "ParsingRunnerManager.h"
#include "TourPlayback.h"
#include "MovieCapture.h"
#include "TourCaptureDialog.h"
#include "MarbleDebug.h"
#include "PlaybackFlyToItem.h"
#include "EditPlacemarkDialog.h"
#include "MarbleDirs.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include <QFileDialog>
#include <QDir>
#include <QModelIndex>
#include <QMessageBox>
#include <QPainter>
#include <QToolButton>
#include <QMenu>
#include <QUrl>
#include <QKeyEvent>
#include <QCloseEvent>
#include <QPointer>
namespace Marble
{
class TourWidgetPrivate
{
public:
explicit TourWidgetPrivate( TourWidget *parent );
~TourWidgetPrivate();
GeoDataFeature *getPlaylistFeature() const;
void updateRootIndex();
public:
void openFile();
bool openFile( const QString &filename );
void createTour();
void saveTour();
void saveTourAs();
void mapCenterOn(const QModelIndex &index );
void addFlyTo();
void addWait();
void addSoundCue();
void addPlacemark();
void addRemovePlacemark();
void addChangePlacemark();
void addTourPrimitive(GeoDataTourPrimitive *primitive );
void deleteSelected();
void updateButtonsStates();
void moveUp();
void moveDown();
void captureTour();
void handlePlaybackProgress( const double position );
void handlePlaybackFinish();
GeoDataObject *rootIndexObject() const;
private:
GeoDataTour* findTour( GeoDataFeature* feature ) const;
bool openDocument( GeoDataDocument *document );
bool saveTourAs( const QString &filename );
bool overrideModifications();
public:
TourWidget *q;
MarbleWidget *m_widget;
Ui::TourWidget m_tourUi;
TourCaptureDialog *m_tourCaptureDialog;
TourPlayback m_playback;
TourItemDelegate *m_delegate;
bool m_isChanged;
bool m_playState;
bool m_isLoopingStopped;
GeoDataDocument* m_document;
QAction *m_actionToggleLoopPlay;
QToolButton *m_addPrimitiveButton;
QAction *m_actionAddFlyTo;
QAction *m_actionAddWait;
QAction *m_actionAddSoundCue;
QAction *m_actionAddPlacemark;
QAction *m_actionAddRemovePlacemark;
QAction *m_actionAddChangePlacemark;
};
TourWidgetPrivate::TourWidgetPrivate( TourWidget *parent )
: q( parent ),
- m_widget( 0 ),
- m_playback( 0 ),
- m_delegate( 0 ),
+ m_widget( nullptr ),
+ m_playback( nullptr ),
+ m_delegate( nullptr ),
m_isChanged( false ),
m_playState( false ),
- m_document( 0 ),
+ m_document( nullptr ),
m_addPrimitiveButton( new QToolButton )
{
m_tourUi.setupUi( parent );
m_tourUi.m_actionRecord->setEnabled( false );
QAction *separator = m_tourUi.m_toolBarControl->insertSeparator( m_tourUi.m_actionMoveUp );
m_addPrimitiveButton->setIcon(QIcon(QStringLiteral(":/marble/flag.png")));
m_addPrimitiveButton->setToolTip( QObject::tr( "Add FlyTo" ) );
m_addPrimitiveButton->setPopupMode( QToolButton::MenuButtonPopup );
QMenu *addPrimitiveMenu = new QMenu(q);
m_actionAddFlyTo = new QAction(QIcon(QStringLiteral(":/marble/flag.png")), QObject::tr("Add FlyTo"), addPrimitiveMenu);
addPrimitiveMenu->addAction( m_actionAddFlyTo );
m_actionAddWait = new QAction(QIcon(QStringLiteral(":/marble/player-time.png")), QObject::tr("Add Wait"), addPrimitiveMenu);
addPrimitiveMenu->addAction( m_actionAddWait );
m_actionAddSoundCue = new QAction(QIcon(QStringLiteral(":/marble/audio-x-generic.png")), QObject::tr("Add SoundCue"), addPrimitiveMenu);
addPrimitiveMenu->addAction( m_actionAddSoundCue );
addPrimitiveMenu->addSeparator();
m_actionAddPlacemark = new QAction(QIcon(QStringLiteral(":/icons/add-placemark.png")), QObject::tr("Add Placemark"), addPrimitiveMenu);
addPrimitiveMenu->addAction( m_actionAddPlacemark );
m_actionAddRemovePlacemark = new QAction(QIcon(QStringLiteral(":/icons/remove.png")), QObject::tr("Remove placemark"), addPrimitiveMenu);
addPrimitiveMenu->addAction( m_actionAddRemovePlacemark );
m_actionAddChangePlacemark = new QAction(QIcon(QStringLiteral(":/marble/document-edit.png")), QObject::tr("Change placemark"), addPrimitiveMenu);
addPrimitiveMenu->addAction( m_actionAddChangePlacemark );
m_actionToggleLoopPlay = new QAction( QObject::tr( "Loop" ), m_tourUi.m_slider );
m_actionToggleLoopPlay->setCheckable( true );
m_actionToggleLoopPlay->setChecked( false );
m_tourUi.m_slider->setContextMenuPolicy( Qt::ActionsContextMenu );
m_tourUi.m_slider->addAction( m_actionToggleLoopPlay );
m_addPrimitiveButton->setMenu( addPrimitiveMenu );
m_addPrimitiveButton->setEnabled( false );
m_tourUi.m_toolBarControl->insertWidget( separator, m_addPrimitiveButton );
QObject::connect( m_tourUi.m_listView, SIGNAL(activated(QModelIndex)), q, SLOT(mapCenterOn(QModelIndex)) );
QObject::connect( m_addPrimitiveButton, SIGNAL(clicked()), q, SLOT(addFlyTo()) );
QObject::connect( m_actionAddFlyTo, SIGNAL(triggered()), q, SLOT(addFlyTo()) );
QObject::connect( m_actionAddWait, SIGNAL(triggered()), q, SLOT(addWait()) );
QObject::connect( m_actionAddSoundCue, SIGNAL(triggered()), q, SLOT(addSoundCue()) );
QObject::connect( m_actionAddPlacemark, SIGNAL(triggered()), q, SLOT(addPlacemark()) );
QObject::connect( m_actionAddRemovePlacemark, SIGNAL(triggered()), q, SLOT(addRemovePlacemark()) );
QObject::connect( m_actionAddChangePlacemark, SIGNAL(triggered()), q, SLOT(addChangePlacemark()) );
QObject::connect( m_tourUi.m_actionDelete, SIGNAL(triggered()), q, SLOT(deleteSelected()) );
QObject::connect( m_tourUi.m_actionMoveUp, SIGNAL(triggered()), q, SLOT(moveUp()) );
QObject::connect( m_tourUi.m_actionMoveDown, SIGNAL(triggered()), q, SLOT(moveDown()) );
QObject::connect( m_tourUi.m_actionNewTour, SIGNAL(triggered()), q, SLOT(createTour()) );
QObject::connect( m_tourUi.m_actionOpenTour, SIGNAL(triggered()), q, SLOT(openFile()) );
QObject::connect( m_tourUi.m_actionSaveTour, SIGNAL(triggered()), q, SLOT(saveTour()) );
QObject::connect( m_tourUi.m_actionSaveTourAs, SIGNAL(triggered()), q, SLOT(saveTourAs()) );
QObject::connect( m_tourUi.m_actionRecord, SIGNAL(triggered()), q, SLOT(captureTour()) );
QObject::connect( &m_playback, SIGNAL(finished()), q, SLOT(stopPlaying()) );
QObject::connect( &m_playback, SIGNAL(itemFinished(int)), q, SLOT(setHighlightedItemIndex(int)) );
}
TourWidgetPrivate::~TourWidgetPrivate()
{
delete m_delegate;
}
TourWidget::TourWidget( QWidget *parent, Qt::WindowFlags flags )
: QWidget( parent, flags ),
d( new TourWidgetPrivate( this ) )
{
layout()->setMargin( 0 );
connect( d->m_tourUi.actionPlay, SIGNAL(triggered()),
this, SLOT(togglePlaying()) );
connect( d->m_tourUi.actionStop, SIGNAL(triggered()),
this, SLOT(stopLooping()) );
connect( d->m_tourUi.actionStop, SIGNAL(triggered()),
this, SLOT(stopPlaying()) );
connect( d->m_tourUi.m_slider, SIGNAL(sliderMoved(int)),
this, SLOT(handleSliderMove(int)) );
d->m_tourUi.m_toolBarPlayback->setDisabled( true );
d->m_tourUi.m_slider->setDisabled( true );
d->m_tourUi.m_listView->installEventFilter( this );
}
TourWidget::~TourWidget()
{
delete d;
}
bool TourWidget::eventFilter( QObject *watched, QEvent *event )
{
Q_UNUSED(watched);
Q_ASSERT( watched == d->m_tourUi.m_listView );
GeoDataObject *rootObject = d->rootIndexObject();
if ( !rootObject ) {
return false;
}
if ( event->type() == QEvent::KeyPress ) {
QKeyEvent *key = static_cast<QKeyEvent*>( event );
QModelIndexList selectedIndexes = d->m_tourUi.m_listView->selectionModel()->selectedIndexes();
if ( key->key() == Qt::Key_Delete ) {
if ( !selectedIndexes.isEmpty() ) {
deleteSelected();
}
return true;
}
if ( key->key() == Qt::Key_PageDown && key->modifiers().testFlag( Qt::ControlModifier )
&& !selectedIndexes.isEmpty() )
{
QModelIndexList::iterator end = selectedIndexes.end() - 1;
- if (const GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : 0)) {
+ if (const GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
if ( end->row() != playlist->size() - 1 ) {
moveDown();
}
}
return true;
}
if ( key->key() == Qt::Key_PageUp && key->modifiers().testFlag( Qt::ControlModifier )
&& !selectedIndexes.isEmpty() )
{
QModelIndexList::iterator start = selectedIndexes.begin();
if ( start->row() != 0 ) {
moveUp();
}
return true;
}
}
return false;
}
void TourWidget::setMarbleWidget( MarbleWidget *widget )
{
d->m_widget = widget;
delete d->m_delegate;
d->m_delegate = new TourItemDelegate( d->m_tourUi.m_listView, d->m_widget, this );
connect( d->m_delegate, SIGNAL(edited(QModelIndex)), this, SLOT(updateDuration()) );
connect( d->m_delegate, SIGNAL(edited(QModelIndex)), &d->m_playback, SLOT(updateTracks()) );
d->m_tourUi.m_listView->setItemDelegate( d->m_delegate );
}
void TourWidget::togglePlaying()
{
if( !d->m_playState ){
d->m_playState = true;
startPlaying();
} else {
d->m_playState = false;
pausePlaying();
}
}
void TourWidget::startPlaying()
{
setHighlightedItemIndex( 0 );
d->m_isLoopingStopped = false;
d->m_playback.play();
d->m_tourUi.actionPlay->setIcon(QIcon(QStringLiteral(":/marble/playback-pause.png")));
d->m_tourUi.actionPlay->setEnabled( true );
d->m_tourUi.actionStop->setEnabled( true );
d->m_tourUi.m_actionRecord->setEnabled( false );
d->m_delegate->setEditable( false );
d->m_addPrimitiveButton->setEnabled( false );
d->m_playState = true;
}
void TourWidget::pausePlaying()
{
d->m_playback.pause();
d->m_tourUi.actionPlay->setIcon(QIcon(QStringLiteral(":/marble/playback-play.png")));
d->m_tourUi.actionPlay->setEnabled( true );
d->m_tourUi.actionStop->setEnabled( true );
}
void TourWidget::stopPlaying()
{
removeHighlight();
d->m_playback.stop();
d->m_tourUi.actionPlay->setIcon(QIcon(QStringLiteral(":/marble/playback-play.png")));
d->m_tourUi.actionPlay->setEnabled( true );
d->m_tourUi.m_actionRecord->setEnabled( true );
d->m_tourUi.actionStop->setEnabled( false );
d->m_playState = false;
d->m_delegate->setEditable( true );
d->m_addPrimitiveButton->setEnabled( true );
// Loop if the option ( m_actionLoopPlay ) is checked
if ( d->m_actionToggleLoopPlay->isChecked() && !d->m_isLoopingStopped ) {
startPlaying();
}
}
void TourWidget::stopLooping()
{
d->m_isLoopingStopped = true;
}
void TourWidget::closeEvent( QCloseEvent *event )
{
if ( !d->m_document || !d->m_isChanged ) {
event->accept();
return;
}
const int result = QMessageBox::question( d->m_widget,
QObject::tr( "Save tour" ),
QObject::tr( "There are unsaved Tours. Do you want to save your changes?" ),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel );
switch ( result ) {
case QMessageBox::Save:
d->saveTour();
event->accept();
break;
case QMessageBox::Discard:
event->accept();
break;
case QMessageBox::Cancel:
event->ignore();
}
}
void TourWidget::handleSliderMove( int value )
{
removeHighlight();
d->m_playback.seek( value / 100.0 );
QTime nullTime( 0, 0, 0 );
QTime time = nullTime.addSecs( value / 100.0 );
d->m_tourUi.m_elapsedTime->setText(QString("%L1:%L2").arg(time.minute(), 2, 10, QLatin1Char('0')).arg(time.second(), 2, 10, QLatin1Char('0')));
}
void TourWidgetPrivate::openFile()
{
if ( overrideModifications() ) {
QString const filename = QFileDialog::getOpenFileName( q, QObject::tr( "Open Tour" ), QDir::homePath(), QObject::tr( "KML Tours (*.kml)" ) );
if ( !filename.isEmpty() ) {
ParsingRunnerManager manager( m_widget->model()->pluginManager() );
GeoDataDocument* document = manager.openFile( filename );
m_playback.setBaseUrl( QUrl::fromLocalFile( filename ) );
openDocument( document );
}
}
}
bool TourWidgetPrivate::openFile( const QString &filename )
{
if ( overrideModifications() ) {
if ( !filename.isEmpty() ) {
ParsingRunnerManager manager( m_widget->model()->pluginManager() );
GeoDataDocument* document = manager.openFile( filename );
m_playback.setBaseUrl( QUrl::fromLocalFile( filename ) );
return openDocument( document );
}
}
return false;
}
GeoDataTour *TourWidgetPrivate::findTour( GeoDataFeature *feature ) const
{
- if (GeoDataTour *tour = (feature ? geodata_cast<GeoDataTour>(feature) : 0)) {
+ if (GeoDataTour *tour = (feature ? geodata_cast<GeoDataTour>(feature) : nullptr)) {
return tour;
}
GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( feature );
if ( container ) {
QVector<GeoDataFeature*>::Iterator end = container->end();
QVector<GeoDataFeature*>::Iterator iter = container->begin();
for( ; iter != end; ++iter ) {
GeoDataTour *tour = findTour( *iter );
if ( tour ) {
return tour;
}
}
}
- return 0;
+ return nullptr;
}
void TourWidgetPrivate::mapCenterOn( const QModelIndex &index )
{
QVariant coordinatesVariant = m_widget->model()->treeModel()->data( index, MarblePlacemarkModel::CoordinateRole );
if ( !coordinatesVariant.isNull() ) {
GeoDataCoordinates const coordinates = coordinatesVariant.value<GeoDataCoordinates>();
GeoDataLookAt lookat;
lookat.setCoordinates( coordinates );
lookat.setRange( coordinates.altitude() );
m_widget->flyTo( lookat, Instant );
}
}
void TourWidgetPrivate::addFlyTo()
{
GeoDataFlyTo *flyTo = new GeoDataFlyTo();
GeoDataLookAt *lookat = new GeoDataLookAt( m_widget->lookAt() );
lookat->setAltitude( lookat->range() );
flyTo->setView( lookat );
bool isMainTrackEmpty = m_playback.mainTrackSize() == 0;
flyTo->setDuration( isMainTrackEmpty ? 0.0 : 1.0 );
addTourPrimitive( flyTo );
}
void TourWidgetPrivate::addWait()
{
GeoDataWait *wait = new GeoDataWait();
wait->setDuration( 1.0 );
addTourPrimitive( wait );
}
void TourWidgetPrivate::addSoundCue()
{
GeoDataSoundCue *soundCue = new GeoDataSoundCue();
addTourPrimitive( soundCue );
}
void TourWidgetPrivate::addPlacemark()
{
// Get the normalized coordinates of the focus point. There will be automatically added a new
// placemark.
qreal lat = m_widget->focusPoint().latitude();
qreal lon = m_widget->focusPoint().longitude();
GeoDataCoordinates::normalizeLonLat( lon, lat );
GeoDataDocument *document = new GeoDataDocument;
if( m_document->id().isEmpty() ) {
if( m_document->name().isEmpty() ) {
m_document->setId(QStringLiteral("untitled_tour"));
} else {
m_document->setId( m_document->name().trimmed().replace( QLatin1Char(' '), QLatin1Char('_') ).toLower() );
}
}
document->setTargetId( m_document->id() );
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setCoordinate( lon, lat );
placemark->setVisible( true );
placemark->setBalloonVisible( true );
GeoDataStyle *newStyle = new GeoDataStyle( *placemark->style() );
newStyle->iconStyle().setIconPath(MarbleDirs::path(QStringLiteral("bitmaps/redflag_22.png")));
placemark->setStyle( GeoDataStyle::Ptr(newStyle) );
document->append( placemark );
GeoDataCreate *create = new GeoDataCreate;
create->append( document );
GeoDataUpdate *update = new GeoDataUpdate;
update->setCreate( create );
GeoDataAnimatedUpdate *animatedUpdate = new GeoDataAnimatedUpdate;
animatedUpdate->setUpdate( update );
if( m_delegate->editAnimatedUpdate( animatedUpdate ) ) {
addTourPrimitive( animatedUpdate );
m_delegate->setDefaultFeatureId( placemark->id() );
} else {
delete animatedUpdate;
}
}
void TourWidgetPrivate::addRemovePlacemark()
{
GeoDataDelete *deleteItem = new GeoDataDelete;
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setTargetId( m_delegate->defaultFeatureId() );
deleteItem->append( placemark );
GeoDataUpdate *update = new GeoDataUpdate;
update->setDelete( deleteItem );
GeoDataAnimatedUpdate *animatedUpdate = new GeoDataAnimatedUpdate;
animatedUpdate->setUpdate( update );
addTourPrimitive( animatedUpdate );
}
void TourWidgetPrivate::addChangePlacemark()
{
GeoDataChange *change = new GeoDataChange;
- GeoDataPlacemark *placemark = 0;
+ GeoDataPlacemark *placemark = nullptr;
GeoDataFeature *lastFeature = m_delegate->findFeature( m_delegate->defaultFeatureId() );
- if (GeoDataPlacemark *target = (lastFeature != 0 ? geodata_cast<GeoDataPlacemark>(lastFeature) : 0)) {
+ if (GeoDataPlacemark *target = (lastFeature != nullptr ? geodata_cast<GeoDataPlacemark>(lastFeature) : nullptr)) {
placemark = new GeoDataPlacemark( *target );
placemark->setTargetId( m_delegate->defaultFeatureId() );
placemark->setId(QString());
} else {
placemark = new GeoDataPlacemark;
}
change->append( placemark );
GeoDataUpdate *update = new GeoDataUpdate;
update->setChange( change );
GeoDataAnimatedUpdate *animatedUpdate = new GeoDataAnimatedUpdate;
animatedUpdate->setUpdate( update );
addTourPrimitive( animatedUpdate );
}
void TourWidgetPrivate::addTourPrimitive( GeoDataTourPrimitive *primitive )
{
GeoDataObject *rootObject = rootIndexObject();
if (auto playlist = geodata_cast<GeoDataPlaylist>(rootObject)) {
QModelIndex currentIndex = m_tourUi.m_listView->currentIndex();
QModelIndex playlistIndex = m_widget->model()->treeModel()->index( playlist );
int row = currentIndex.isValid() ? currentIndex.row()+1 : playlist->size();
m_widget->model()->treeModel()->addTourPrimitive( playlistIndex, primitive, row );
m_isChanged = true;
m_tourUi.m_actionSaveTour->setEnabled( true );
// Scrolling to the inserted item.
if ( currentIndex.isValid() ) {
m_tourUi.m_listView->scrollTo( currentIndex );
}
else {
m_tourUi.m_listView->scrollToBottom();
}
}
}
void TourWidgetPrivate::deleteSelected()
{
QString title = QObject::tr( "Remove Selected Items" );
QString text = QObject::tr( "Are you sure want to remove selected items?" );
QPointer<QMessageBox> dialog = new QMessageBox( QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::No, q );
dialog->setDefaultButton( QMessageBox::No );
if ( dialog->exec() == QMessageBox::Yes ) {
GeoDataObject *rootObject = rootIndexObject();
- if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : 0)) {
+ if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
QModelIndex playlistIndex = m_widget->model()->treeModel()->index( playlist );
QModelIndexList selected = m_tourUi.m_listView->selectionModel()->selectedIndexes();
std::sort( selected.begin(), selected.end(), [](const QModelIndex &a, const QModelIndex &b) { return b < a; } );
QModelIndexList::iterator end = selected.end();
QModelIndexList::iterator iter = selected.begin();
for( ; iter != end; ++iter ) {
m_widget->model()->treeModel()->removeTourPrimitive( playlistIndex, iter->row() );
}
m_isChanged = true;
m_tourUi.m_actionSaveTour->setEnabled( true );
}
}
delete dialog;
}
void TourWidgetPrivate::updateButtonsStates()
{
QModelIndexList selectedIndexes = m_tourUi.m_listView->selectionModel()->selectedIndexes();
if ( selectedIndexes.isEmpty() ) {
m_tourUi.m_actionDelete->setEnabled( false );
m_tourUi.m_actionMoveDown->setEnabled( false );
m_tourUi.m_actionMoveUp->setEnabled( false );
} else {
m_tourUi.m_actionDelete->setEnabled( true );
std::sort( selectedIndexes.begin(), selectedIndexes.end(), std::less<QModelIndex>() );
QModelIndexList::iterator end = selectedIndexes.end()-1;
QModelIndexList::iterator start = selectedIndexes.begin();
m_tourUi.m_actionMoveUp->setEnabled( ( start->row() != 0 ) ); // if we can move up enable action else disable.
GeoDataObject *rootObject = rootIndexObject();
- if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : 0)) {
+ if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
m_tourUi.m_actionMoveDown->setEnabled( ( end->row() != playlist->size()-1 ) ); // if we can move down enable action else disable.
}
}
}
void TourWidgetPrivate::moveUp()
{
GeoDataObject *rootObject = rootIndexObject();
- if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : 0)) {
+ if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
QModelIndex playlistIndex = m_widget->model()->treeModel()->index( playlist );
QModelIndexList selected = m_tourUi.m_listView->selectionModel()->selectedIndexes();
std::sort( selected.begin(), selected.end(), std::less<QModelIndex>() );
QModelIndexList::iterator end = selected.end();
QModelIndexList::iterator iter = selected.begin();
for( ; iter != end; ++iter ) {
int const index = iter->row();
Q_ASSERT( index > 0 );
m_widget->model()->treeModel()->swapTourPrimitives( playlistIndex, index-1, index );
}
m_isChanged = true;
m_tourUi.m_actionSaveTour->setEnabled( true );
updateButtonsStates();
}
}
void TourWidgetPrivate::moveDown()
{
GeoDataObject *rootObject = rootIndexObject();
- if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : 0)) {
+ if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
QModelIndex playlistIndex = m_widget->model()->treeModel()->index( playlist );
QModelIndexList selected = m_tourUi.m_listView->selectionModel()->selectedIndexes();
std::sort( selected.begin(), selected.end(), [](const QModelIndex &a, const QModelIndex &b) { return b < a; } );
QModelIndexList::iterator end = selected.end();
QModelIndexList::iterator iter = selected.begin();
for( ; iter != end; ++iter ) {
int const index = iter->row();
Q_ASSERT( index < playlist->size()-1 );
m_widget->model()->treeModel()->swapTourPrimitives( playlistIndex, index, index+1 );
}
m_isChanged = true;
m_tourUi.m_actionSaveTour->setEnabled( true );
updateButtonsStates();
}
}
GeoDataFeature* TourWidgetPrivate::getPlaylistFeature() const
{
GeoDataObject *rootObject = rootIndexObject();
- if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : 0)) {
+ if (GeoDataPlaylist *playlist = (rootObject ? geodata_cast<GeoDataPlaylist>(rootObject) : nullptr)) {
GeoDataObject *object = playlist->parent();
- if (GeoDataTour *tour = (object ? geodata_cast<GeoDataTour>(object) : 0)) {
+ if (GeoDataTour *tour = (object ? geodata_cast<GeoDataTour>(object) : nullptr)) {
return tour;
}
}
- return 0;
+ return nullptr;
}
void TourWidgetPrivate::updateRootIndex()
{
GeoDataTour *tour = findTour( m_document );
if ( tour ){
GeoDataPlaylist *playlist = tour->playlist();
if ( playlist ) {
m_tourUi.m_listView->setModel( m_widget->model()->treeModel() );
m_tourUi.m_listView->setRootIndex( m_widget->model()->treeModel()->index( playlist ) );
QObject::connect( m_tourUi.m_listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
q, SLOT(updateButtonsStates()) );
}
m_playback.setMarbleWidget( m_widget );
m_playback.setTour( tour );
m_tourUi.m_slider->setMaximum( m_playback.duration() * 100 );
QTime nullTime( 0, 0, 0 );
QTime time = nullTime.addSecs( m_playback.duration() );
m_tourUi.m_totalTime->setText(QString("%L1:%L2").arg(time.minute(), 2, 10, QLatin1Char('0')).arg(time.second(), 2, 10, QLatin1Char('0')));
QObject::connect( &m_playback, SIGNAL(progressChanged(double)),
q, SLOT(handlePlaybackProgress(double)) );
q->stopPlaying();
m_tourUi.m_toolBarPlayback->setEnabled( true );
bool isPlaybackEmpty = m_playback.mainTrackSize() != 0;
m_tourUi.actionPlay->setEnabled( isPlaybackEmpty );
m_tourUi.m_slider->setEnabled( isPlaybackEmpty );
m_tourUi.m_actionRecord->setEnabled( isPlaybackEmpty );
m_tourUi.actionStop->setEnabled( false );
if( m_playback.mainTrackSize() > 0 ) {
if( dynamic_cast<PlaybackFlyToItem*>( m_playback.mainTrackItemAt( 0 ) ) ) {
QModelIndex playlistIndex = m_widget->model()->treeModel()->index( playlist );
for( int i = 0; playlist && i < playlist->size(); ++i ) {
if (geodata_cast<GeoDataFlyTo>(playlist->primitive(i))) {
m_delegate->setFirstFlyTo( m_widget->model()->treeModel()->index( i, 0, playlistIndex ) );
break;
}
}
} else {
m_delegate->setFirstFlyTo( QPersistentModelIndex() );
}
}
}
}
void TourWidget::addFlyTo()
{
d->addFlyTo();
finishAddingItem();
}
void TourWidget::addWait()
{
d->addWait();
finishAddingItem();
}
void TourWidget::addSoundCue()
{
d->addSoundCue();
finishAddingItem();
}
void TourWidget::addPlacemark()
{
d->addPlacemark();
finishAddingItem();
}
void TourWidget::addRemovePlacemark()
{
d->addRemovePlacemark();
finishAddingItem();
}
void TourWidget::addChangePlacemark()
{
d->addChangePlacemark();
finishAddingItem();
}
void TourWidget::deleteSelected()
{
d->deleteSelected();
GeoDataFeature *feature = d->getPlaylistFeature();
if ( feature ) {
emit featureUpdated( feature );
d->updateRootIndex();
}
}
void TourWidget::updateDuration()
{
d->m_tourUi.m_slider->setMaximum( d->m_playback.duration() * 100 );
QTime nullTime( 0, 0, 0 );
QTime totalTime = nullTime.addSecs( d->m_playback.duration() );
d->m_tourUi.m_totalTime->setText(QString("%L1:%L2").arg(totalTime.minute(), 2, 10, QLatin1Char('0') ).arg(totalTime.second(), 2, 10, QLatin1Char('0')));
d->m_tourUi.m_slider->setValue( 0 );
d->m_tourUi.m_elapsedTime->setText(QString("%L1:%L2").arg(0, 2, 10, QLatin1Char('0')).arg(0, 2, 10, QLatin1Char('0')));
}
void TourWidget::finishAddingItem()
{
GeoDataFeature *feature = d->getPlaylistFeature();
if ( feature ) {
emit featureUpdated( feature );
d->updateRootIndex();
}
}
void TourWidget::moveDown()
{
d->moveDown();
GeoDataFeature *feature = d->getPlaylistFeature();
if ( feature ) {
emit featureUpdated( feature );
d->updateRootIndex();
}
}
void TourWidget::moveUp()
{
d->moveUp();
GeoDataFeature *feature = d->getPlaylistFeature();
if ( feature ) {
emit featureUpdated( feature );
d->updateRootIndex();
}
}
GeoDataObject *TourWidgetPrivate::rootIndexObject() const
{
QModelIndex const rootIndex = m_tourUi.m_listView->rootIndex();
- return rootIndex.isValid() ? static_cast<GeoDataObject*>( rootIndex.internalPointer() ) : 0;
+ return rootIndex.isValid() ? static_cast<GeoDataObject*>( rootIndex.internalPointer() ) : nullptr;
}
void TourWidgetPrivate::createTour()
{
if ( overrideModifications() ) {
GeoDataDocument *document = new GeoDataDocument();
document->setDocumentRole( UserDocument );
document->setName(QStringLiteral("New Tour"));
document->setId(QStringLiteral("new_tour"));
GeoDataTour *tour = new GeoDataTour();
tour->setName(QStringLiteral("New Tour"));
GeoDataPlaylist *playlist = new GeoDataPlaylist;
tour->setPlaylist( playlist );
document->append( static_cast<GeoDataFeature*>( tour ) );
m_playback.setBaseUrl( QUrl::fromLocalFile( MarbleDirs::marbleDataPath() ) );
openDocument( document );
m_isChanged = true;
m_tourUi.m_actionSaveTour->setEnabled( true );
m_tourUi.m_slider->setEnabled( true );
}
}
bool TourWidgetPrivate::openDocument(GeoDataDocument* document)
{
if ( document ) {
if ( m_document ) {
m_widget->model()->treeModel()->removeDocument( m_document );
delete m_document;
}
m_document = document;
m_widget->model()->treeModel()->addDocument( m_document );
m_isChanged = false;
updateRootIndex();
m_addPrimitiveButton->setEnabled( true );
m_tourUi.m_actionSaveTourAs->setEnabled( true );
m_tourUi.m_actionSaveTour->setEnabled( false );
m_isChanged = false;
return true;
}
return false;
}
void TourWidgetPrivate::saveTour()
{
if ( m_document ) {
if ( !m_document->fileName().isEmpty() ) {
saveTourAs( m_document->fileName() );
} else {
saveTourAs();
}
}
}
void TourWidgetPrivate::saveTourAs()
{
if ( m_document )
{
QString const filename = QFileDialog::getSaveFileName( q, QObject::tr( "Save Tour as" ), QDir::homePath(), QObject::tr( "KML Tours (*.kml)" ) );
if ( !filename.isEmpty() ) {
saveTourAs( filename );
}
}
}
bool TourWidgetPrivate::saveTourAs(const QString &filename)
{
if ( !filename.isEmpty() ) {
if (GeoDataDocumentWriter::write(filename, *m_document)) {
m_tourUi.m_actionSaveTour->setEnabled( false );
m_isChanged = false;
GeoDataDocument* document = m_document;
if ( !document->fileName().isNull() ) {
m_widget->model()->removeGeoData( document->fileName() );
}
m_widget->model()->addGeoDataFile( filename );
m_document->setFileName( filename );
return true;
}
}
return false;
}
void TourWidgetPrivate::captureTour()
{
MarbleWidget* widget = new MarbleWidget;
widget->setMapThemeId( m_widget->mapThemeId() );
widget->resize( 1280, 720 );
m_widget->model()->treeModel()->removeDocument(m_document);
widget->model()->treeModel()->addDocument(m_document);
GeoDataTour* tour = findTour( m_document );
TourPlayback* playback = new TourPlayback;
playback->setMarbleWidget( widget );
playback->setTour( tour );
m_tourUi.m_listView->setModel( widget->model()->treeModel() );
if( tour ){
m_tourUi.m_listView->setRootIndex( widget->model()->treeModel()->index( tour->playlist() ) );
m_tourUi.m_listView->repaint();
QPointer<TourCaptureDialog> tourCaptureDialog = new TourCaptureDialog( widget, m_widget );
tourCaptureDialog->setDefaultFilename( tour->name() );
tourCaptureDialog->setTourPlayback( playback );
tourCaptureDialog->exec();
}
delete playback;
widget->model()->treeModel()->removeDocument(m_document);
m_widget->model()->treeModel()->addDocument(m_document);
updateRootIndex();
delete widget;
}
bool TourWidgetPrivate::overrideModifications()
{
if ( m_document && m_isChanged ) {
QString title = QObject::tr( "Discard Changes" );
QString text = QObject::tr( "Are you sure want to discard all unsaved changes and close current document?" );
QPointer<QMessageBox> dialog = new QMessageBox( QMessageBox::Question, title, text, QMessageBox::Yes | QMessageBox::No, q );
dialog->setDefaultButton( QMessageBox::No );
if ( dialog->exec() != QMessageBox::Yes ) {
delete dialog;
return false;
}
delete dialog;
}
return true;
}
bool TourWidget::openTour( const QString &filename)
{
return d->openFile( filename );
}
void TourWidgetPrivate::handlePlaybackProgress(const double position)
{
if( !m_tourUi.m_slider->isSliderDown() ){
m_tourUi.m_slider->setValue( position * 100 );
QTime nullTime( 0, 0, 0 );
QTime time = nullTime.addSecs( position );
m_tourUi.m_elapsedTime->setText(QString("%L1:%L2").arg(time.minute(), 2, 10, QLatin1Char('0')).arg(time.second(), 2, 10, QLatin1Char('0')));
}
}
void TourWidget::setHighlightedItemIndex( int index )
{
GeoDataObject* rootObject = d->rootIndexObject();
GeoDataPlaylist* playlist = static_cast<GeoDataPlaylist*>( rootObject );
QModelIndex playlistIndex = d->m_widget->model()->treeModel()->index( playlist );
// Only flyTo and wait items have duration, so the other types have to be skipped.
int searchedIndex = 0;
for ( int i = 0; i < playlist->size(); i++ ) {
QModelIndex currentIndex = d->m_widget->model()->treeModel()->index( i, 0, playlistIndex );
GeoDataObject* object = qvariant_cast<GeoDataObject*>(currentIndex.data( MarblePlacemarkModel::ObjectPointerRole ) );
if (geodata_cast<GeoDataFlyTo>(object)
|| geodata_cast<GeoDataWait>(object))
++searchedIndex;
if ( index == searchedIndex ) {
d->m_tourUi.m_listView->selectionModel()->setCurrentIndex( currentIndex, QItemSelectionModel::NoUpdate );
d->m_tourUi.m_listView->scrollTo( currentIndex );
break;
}
}
d->m_tourUi.m_listView->viewport()->update();
}
void TourWidget::removeHighlight()
{
QModelIndex index;
// Restoring the CurrentIndex to the previously selected item
// or clearing it if there was no selected item.
if ( d->m_tourUi.m_listView->selectionModel()->hasSelection() ) {
index = d->m_tourUi.m_listView->selectionModel()->selectedIndexes().last();
}
else {
index = QModelIndex();
}
d->m_tourUi.m_listView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::NoUpdate );
d->m_tourUi.m_listView->viewport()->update();
}
bool TourWidget::isPlaying() const
{
return d->m_playState;
}
}
#include "moc_TourWidget.cpp"
diff --git a/src/lib/marble/TourWidget.h b/src/lib/marble/TourWidget.h
index 02459c494..e645b3985 100644
--- a/src/lib/marble/TourWidget.h
+++ b/src/lib/marble/TourWidget.h
@@ -1,94 +1,94 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#ifndef MARBLE_TOURWIDGET_H
#define MARBLE_TOURWIDGET_H
#include "marble_export.h"
#include <QWidget>
class QModelIndex;
namespace Marble
{
class GeoDataFeature;
class GeoDataContainer;
class MarbleWidget;
class TourWidgetPrivate;
class MARBLE_EXPORT TourWidget : public QWidget
{
Q_OBJECT
public:
- explicit TourWidget( QWidget *parent = 0, Qt::WindowFlags f = 0 );
+ explicit TourWidget( QWidget *parent = nullptr, Qt::WindowFlags f = nullptr );
~TourWidget() override;
void setMarbleWidget( MarbleWidget *widget );
bool openTour( const QString &filename );
bool isPlaying() const;
bool eventFilter( QObject *watched, QEvent *event ) override;
public Q_SLOTS:
void startPlaying();
void pausePlaying();
void togglePlaying();
void stopPlaying();
void handleSliderMove( int );
/**
* Highlights the item curently being played.
*/
void setHighlightedItemIndex( int index );
Q_SIGNALS:
void featureUpdated( GeoDataFeature *feature );
void featureAdded( GeoDataContainer *parent, GeoDataFeature *feature, int row );
void featureRemoved( const GeoDataFeature *feature );
private Q_SLOTS:
void moveUp();
void moveDown();
void addFlyTo();
void addWait();
void addSoundCue();
void addPlacemark();
void addRemovePlacemark();
void addChangePlacemark();
void deleteSelected();
void updateDuration();
void finishAddingItem();
void stopLooping();
protected:
void closeEvent( QCloseEvent *event ) override;
private:
Q_PRIVATE_SLOT( d, void openFile() )
Q_PRIVATE_SLOT( d, void createTour() )
Q_PRIVATE_SLOT( d, void saveTour() )
Q_PRIVATE_SLOT( d, void saveTourAs() )
Q_PRIVATE_SLOT( d, void captureTour() )
Q_PRIVATE_SLOT( d, void updateButtonsStates() )
Q_PRIVATE_SLOT( d, void mapCenterOn( const QModelIndex &index ) )
Q_PRIVATE_SLOT( d, void handlePlaybackProgress( const double position ) )
Q_DISABLE_COPY( TourWidget )
void removeHighlight();
TourWidgetPrivate * const d;
};
}
#endif
diff --git a/src/lib/marble/TreeViewDecoratorModel.h b/src/lib/marble/TreeViewDecoratorModel.h
index ff5be9ff6..ef30da435 100644
--- a/src/lib/marble/TreeViewDecoratorModel.h
+++ b/src/lib/marble/TreeViewDecoratorModel.h
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Levente Kurusa <levex@linux.com>
#ifndef TREEVIEWDECORATORMODEL_H
#define TREEVIEWDECORATORMODEL_H
#include <QSortFilterProxyModel>
namespace Marble
{
class TreeViewDecoratorModel : public QSortFilterProxyModel
{
Q_OBJECT
public Q_SLOTS:
void trackExpandedState( const QModelIndex &index );
void trackCollapsedState( const QModelIndex &index );
public:
- explicit TreeViewDecoratorModel( QObject *parent = 0 );
+ explicit TreeViewDecoratorModel( QObject *parent = nullptr );
QVariant data( const QModelIndex & proxyIndex, int role = Qt::DisplayRole ) const override;
protected:
bool filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const override;
private:
QList<QPersistentModelIndex> m_expandedRows;
};
}
#endif // TREEVIEWDECORATORMODEL_H
diff --git a/src/lib/marble/ViewportParams.cpp b/src/lib/marble/ViewportParams.cpp
index 58715f5a8..33661821b 100644
--- a/src/lib/marble/ViewportParams.cpp
+++ b/src/lib/marble/ViewportParams.cpp
@@ -1,485 +1,485 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
// Copyright 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "ViewportParams.h"
#include <QRect>
#include <QPainterPath>
#include <QRegion>
#include "MarbleDebug.h"
#include "GeoDataLatLonAltBox.h"
#include "SphericalProjection.h"
#include "EquirectProjection.h"
#include "MercatorProjection.h"
#include "GnomonicProjection.h"
#include "LambertAzimuthalProjection.h"
#include "AzimuthalEquidistantProjection.h"
#include "StereographicProjection.h"
#include "VerticalPerspectiveProjection.h"
namespace Marble
{
class ViewportParamsPrivate
{
public:
ViewportParamsPrivate( Projection projection,
qreal centerLongitude, qreal centerLatitude,
int radius,
const QSize &size );
static const AbstractProjection *abstractProjection( Projection projection );
// These two go together. m_currentProjection points to one of
// the static Projection classes at the bottom.
Projection m_projection;
const AbstractProjection *m_currentProjection;
// Parameters that determine the painting
qreal m_centerLongitude;
qreal m_centerLatitude;
qreal m_heading;
Quaternion m_planetAxis; // Position, coded in a quaternion
matrix m_planetAxisMatrix;
int m_radius; // Zoom level (pixels / globe radius)
qreal m_angularResolution;
QSize m_size; // width, height
bool m_dirtyBox;
GeoDataLatLonAltBox m_viewLatLonAltBox;
static const SphericalProjection s_sphericalProjection;
static const EquirectProjection s_equirectProjection;
static const MercatorProjection s_mercatorProjection;
static const GnomonicProjection s_gnomonicProjection;
static const StereographicProjection s_stereographicProjection;
static const LambertAzimuthalProjection s_lambertAzimuthalProjection;
static const AzimuthalEquidistantProjection s_azimuthalEquidistantProjection;
static const VerticalPerspectiveProjection s_verticalPerspectiveProjection;
GeoDataCoordinates m_focusPoint;
};
const SphericalProjection ViewportParamsPrivate::s_sphericalProjection;
const EquirectProjection ViewportParamsPrivate::s_equirectProjection;
const MercatorProjection ViewportParamsPrivate::s_mercatorProjection;
const GnomonicProjection ViewportParamsPrivate::s_gnomonicProjection;
const StereographicProjection ViewportParamsPrivate::s_stereographicProjection;
const LambertAzimuthalProjection ViewportParamsPrivate::s_lambertAzimuthalProjection;
const AzimuthalEquidistantProjection ViewportParamsPrivate::s_azimuthalEquidistantProjection;
const VerticalPerspectiveProjection ViewportParamsPrivate::s_verticalPerspectiveProjection;
ViewportParamsPrivate::ViewportParamsPrivate( Projection projection,
qreal centerLongitude, qreal centerLatitude,
int radius,
const QSize &size )
: m_projection( projection ),
m_currentProjection( abstractProjection( projection ) ),
m_centerLongitude( centerLongitude ),
m_centerLatitude( centerLatitude ),
m_heading( 0 ),
m_planetAxis(),
m_planetAxisMatrix(),
m_radius( radius ),
m_angularResolution(4.0 / abs(m_radius)),
m_size( size ),
m_dirtyBox( true ),
m_viewLatLonAltBox()
{
}
const AbstractProjection *ViewportParamsPrivate::abstractProjection(Projection projection)
{
switch ( projection ) {
case Spherical:
return &s_sphericalProjection;
case Equirectangular:
return &s_equirectProjection;
case Mercator:
return &s_mercatorProjection;
case Gnomonic:
return &s_gnomonicProjection;
case Stereographic:
return &s_stereographicProjection;
case LambertAzimuthal:
return &s_lambertAzimuthalProjection;
case AzimuthalEquidistant:
return &s_azimuthalEquidistantProjection;
case VerticalPerspective:
return &s_verticalPerspectiveProjection;
}
- return 0;
+ return nullptr;
}
ViewportParams::ViewportParams()
: d( new ViewportParamsPrivate( Spherical, 0, 0, 2000, QSize( 100, 100 ) ) )
{
centerOn( d->m_centerLongitude, d->m_centerLatitude );
}
ViewportParams::ViewportParams( Projection projection,
qreal centerLongitude, qreal centerLatitude,
int radius,
const QSize &size )
: d( new ViewportParamsPrivate( projection, centerLongitude, centerLatitude, radius, size ) )
{
centerOn( d->m_centerLongitude, d->m_centerLatitude );
}
ViewportParams::~ViewportParams()
{
delete d;
}
// ================================================================
// Getters and setters
Projection ViewportParams::projection() const
{
return d->m_projection;
}
const AbstractProjection *ViewportParams::currentProjection() const
{
return d->m_currentProjection;
}
void ViewportParams::setProjection(Projection newProjection)
{
d->m_projection = newProjection;
d->m_currentProjection = ViewportParamsPrivate::abstractProjection( newProjection );
// We now need to reset the planetAxis to make sure
// that it's a valid axis orientation!
// So this line is important (although it might look odd) ! :
centerOn( d->m_centerLongitude, d->m_centerLatitude );
}
int ViewportParams::polarity() const
{
// For mercator this just gives the extreme latitudes
// instead of the actual poles but it works fine as well:
GeoDataCoordinates northPole( 0.0, +currentProjection()->maxLat() );
GeoDataCoordinates southPole( 0.0, -currentProjection()->maxLat() );
bool globeHidesN, globeHidesS;
qreal x;
qreal yN, yS;
currentProjection()->screenCoordinates( northPole, this,
x, yN, globeHidesN );
currentProjection()->screenCoordinates( southPole, this,
x, yS, globeHidesS );
int polarity = 0;
// case of the flat map:
if ( !globeHidesN && !globeHidesS ) {
if ( yN < yS ) {
polarity = +1;
}
if ( yS < yN ) {
polarity = -1;
}
}
else {
if ( !globeHidesN && yN < height() / 2 ) {
polarity = +1;
}
if ( !globeHidesN && yN > height() / 2 ) {
polarity = -1;
}
if ( !globeHidesS && yS > height() / 2 ) {
polarity = +1;
}
if ( !globeHidesS && yS < height() / 2 ) {
polarity = -1;
}
}
return polarity;
}
int ViewportParams::radius() const
{
return d->m_radius;
}
void ViewportParams::setRadius(int newRadius)
{
if ( newRadius > 0 ) {
d->m_dirtyBox = true;
d->m_radius = newRadius;
d->m_angularResolution = 4.0 / d->m_radius;
}
}
void ViewportParams::centerOn( qreal lon, qreal lat )
{
if ( !d->m_currentProjection->traversablePoles() ) {
if ( lat > d->m_currentProjection->maxLat() )
lat = d->m_currentProjection->maxLat();
if ( lat < d->m_currentProjection->minLat() )
lat = d->m_currentProjection->minLat();
} else {
while ( lat > M_PI )
lat -= 2 * M_PI;
while ( lat < -M_PI )
lat += 2 * M_PI;
}
while ( lon > M_PI )
lon -= 2 * M_PI;
while ( lon < -M_PI )
lon += 2 * M_PI;
d->m_centerLongitude = lon;
d->m_centerLatitude = lat;
const Quaternion roll = Quaternion::fromEuler( 0, 0, d->m_heading );
const Quaternion quat = Quaternion::fromEuler( -lat, lon, 0.0 );
d->m_planetAxis = quat * roll;
d->m_planetAxis.normalize();
d->m_dirtyBox = true;
d->m_planetAxis.inverse().toMatrix( d->m_planetAxisMatrix );
d->m_planetAxis.normalize();
}
void ViewportParams::setHeading( qreal heading )
{
d->m_heading = heading;
const Quaternion roll = Quaternion::fromEuler( 0, 0, heading );
const qreal centerLat = centerLatitude();
const qreal centerLon = centerLongitude();
const Quaternion quat = Quaternion::fromEuler( -centerLat, centerLon, 0 );
d->m_planetAxis = quat * roll;
d->m_planetAxis.normalize();
d->m_dirtyBox = true;
d->m_planetAxis.inverse().toMatrix( d->m_planetAxisMatrix );
d->m_planetAxis.normalize();
}
qreal ViewportParams::heading() const
{
return d->m_heading;
}
Quaternion ViewportParams::planetAxis() const
{
return d->m_planetAxis;
}
const matrix &ViewportParams::planetAxisMatrix() const
{
return d->m_planetAxisMatrix;
}
int ViewportParams::width() const
{
return d->m_size.width();
}
int ViewportParams::height() const
{
return d->m_size.height();
}
QSize ViewportParams::size() const
{
return d->m_size;
}
void ViewportParams::setWidth(int newWidth)
{
setSize( QSize( newWidth, height() ) );
}
void ViewportParams::setHeight(int newHeight)
{
setSize( QSize( width(), newHeight ) );
}
void ViewportParams::setSize(const QSize& newSize)
{
if ( newSize == d->m_size )
return;
d->m_dirtyBox = true;
d->m_size = newSize;
}
// ================================================================
// Other functions
qreal ViewportParams::centerLongitude() const
{
return d->m_centerLongitude;
}
qreal ViewportParams::centerLatitude() const
{
return d->m_centerLatitude;
}
const GeoDataLatLonAltBox& ViewportParams::viewLatLonAltBox() const
{
if (d->m_dirtyBox) {
d->m_viewLatLonAltBox = d->m_currentProjection->latLonAltBox( QRect( QPoint( 0, 0 ),
d->m_size ),
this );
d->m_dirtyBox = false;
}
return d->m_viewLatLonAltBox;
}
GeoDataLatLonAltBox ViewportParams::latLonAltBox( const QRect &screenRect ) const
{
return d->m_currentProjection->latLonAltBox( screenRect, this );
}
qreal ViewportParams::angularResolution() const
{
// We essentially divide the diameter by 180 deg and
// take half of the result as a guess for the angle per pixel resolution.
// d->m_angularResolution = 0.25 * M_PI / fabs( (qreal)(d->m_radius);
return d->m_angularResolution;
}
bool ViewportParams::resolves ( const GeoDataLatLonBox &latLonBox, qreal pixel ) const
{
return latLonBox.width() + latLonBox.height() > pixel * d->m_angularResolution;
}
bool ViewportParams::resolves ( const GeoDataLatLonAltBox &latLonAltBox, qreal pixel, qreal altitude ) const
{
return latLonAltBox.width() + latLonAltBox.height() > pixel * d->m_angularResolution
|| latLonAltBox.maxAltitude() - latLonAltBox.minAltitude() > altitude;
}
bool ViewportParams::resolves ( const GeoDataCoordinates &coord1,
const GeoDataCoordinates &coord2 ) const
{
qreal lon1, lat1;
coord1.geoCoordinates( lon1, lat1 );
qreal lon2, lat2;
coord2.geoCoordinates( lon2, lat2 );
// We take the manhattan length as an approximation for the distance
return ( fabs( lon2 - lon1 ) + fabs( lat2 - lat1 ) > d->m_angularResolution );
}
bool ViewportParams::screenCoordinates( const qreal lon, const qreal lat,
qreal &x, qreal &y ) const
{
return d->m_currentProjection->screenCoordinates( lon, lat, this, x, y );
}
bool ViewportParams::screenCoordinates( const GeoDataCoordinates &geopoint,
qreal &x, qreal &y,
bool &globeHidesPoint ) const
{
return d->m_currentProjection->screenCoordinates( geopoint, this, x, y, globeHidesPoint );
}
bool ViewportParams::screenCoordinates( const GeoDataCoordinates &geopoint,
qreal &x, qreal &y ) const
{
return d->m_currentProjection->screenCoordinates( geopoint, this, x, y );
}
bool ViewportParams::screenCoordinates( const GeoDataCoordinates &coordinates,
qreal *x, qreal &y, int &pointRepeatNum,
const QSizeF& size,
bool &globeHidesPoint ) const
{
return d->m_currentProjection->screenCoordinates( coordinates, this, x, y, pointRepeatNum, size, globeHidesPoint );
}
bool ViewportParams::screenCoordinates( const GeoDataLineString &lineString,
QVector<QPolygonF*> &polygons ) const
{
return d->m_currentProjection->screenCoordinates( lineString, this, polygons );
}
bool ViewportParams::geoCoordinates( const int x, const int y,
qreal &lon, qreal &lat,
GeoDataCoordinates::Unit unit ) const
{
return d->m_currentProjection->geoCoordinates( x, y, this, lon, lat, unit );
}
bool ViewportParams::mapCoversViewport() const
{
return d->m_currentProjection->mapCoversViewport( this );
}
QPainterPath ViewportParams::mapShape() const
{
return d->m_currentProjection->mapShape( this );
}
QRegion ViewportParams::mapRegion() const
{
return d->m_currentProjection->mapRegion( this );
}
GeoDataCoordinates ViewportParams::focusPoint() const
{
if (d->m_focusPoint.isValid()) {
return d->m_focusPoint;
}
else {
const qreal lon = d->m_centerLongitude;
const qreal lat = d->m_centerLatitude;
return GeoDataCoordinates(lon, lat, 0.0, GeoDataCoordinates::Radian);
}
}
void ViewportParams::setFocusPoint(const GeoDataCoordinates &focusPoint)
{
d->m_focusPoint = focusPoint;
}
void ViewportParams::resetFocusPoint()
{
d->m_focusPoint = GeoDataCoordinates();
}
}
diff --git a/src/lib/marble/WaitEditWidget.h b/src/lib/marble/WaitEditWidget.h
index d2a982588..070a77035 100644
--- a/src/lib/marble/WaitEditWidget.h
+++ b/src/lib/marble/WaitEditWidget.h
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
// Copyright 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef WAITEDITWIDGET_H
#define WAITEDITWIDGET_H
#include <QWidget>
#include <QModelIndex>
class QDoubleSpinBox;
class QToolButton;
namespace Marble
{
class GeoDataWait;
class WaitEditWidget: public QWidget
{
Q_OBJECT
public:
- explicit WaitEditWidget( const QModelIndex& index, QWidget* parent=0 );
+ explicit WaitEditWidget( const QModelIndex& index, QWidget* parent=nullptr );
bool editable() const;
Q_SIGNALS:
void editingDone( const QModelIndex& index );
public Q_SLOTS:
void setEditable( bool editable );
private Q_SLOTS:
void save();
private:
GeoDataWait* waitElement();
QPersistentModelIndex m_index;
QDoubleSpinBox *m_spinBox;
QToolButton *m_button;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/blendings/BlendingFactory.cpp b/src/lib/marble/blendings/BlendingFactory.cpp
index 6230b0eb9..95724d9a7 100644
--- a/src/lib/marble/blendings/BlendingFactory.cpp
+++ b/src/lib/marble/blendings/BlendingFactory.cpp
@@ -1,100 +1,100 @@
// Copyright 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "BlendingFactory.h"
#include <QDebug>
#include "blendings/SunLightBlending.h"
#include "BlendingAlgorithms.h"
namespace Marble
{
void BlendingFactory::setLevelZeroLayout( int levelZeroColumns, int levelZeroRows )
{
m_sunLightBlending->setLevelZeroLayout( levelZeroColumns, levelZeroRows );
}
Blending const * BlendingFactory::findBlending( QString const & name ) const
{
if ( name.isEmpty() )
- return 0;
+ return nullptr;
Blending const * const result = m_blendings.value( name, 0 );
if ( !result )
qWarning() << "Unknown blending" << name << "specified in .dgml file. Please fix the .dgml file.";
return result;
}
BlendingFactory::BlendingFactory( const SunLocator *sunLocator )
: m_sunLightBlending( new SunLightBlending( sunLocator ) )
{
m_blendings.insert( "OverpaintBlending", new OverpaintBlending );
// Neutral blendings
m_blendings.insert( "AllanonBlending", new AllanonBlending );
m_blendings.insert( "ArcusTangentBlending", new ArcusTangentBlending );
m_blendings.insert( "GeometricMeanBlending", new GeometricMeanBlending );
m_blendings.insert( "LinearLightBlending", new LinearLightBlending );
//m_blendings.insert( "NoiseBlending", new NoiseBlending );
m_blendings.insert( "OverlayBlending", new OverlayBlending );
//m_blendings.insert( "ParallelBlending", new ParallelBlending );
//m_blendings.insert( "TextureBlending", new TextureBlending );
// Darkening blendings
m_blendings.insert( "AlphaBlending", new OverpaintBlending ); // for backwards compatibility
m_blendings.insert( "ColorBurnBlending", new ColorBurnBlending );
m_blendings.insert( "DarkBlending", new DarkBlending );
m_blendings.insert( "DarkenBlending", new DarkenBlending );
m_blendings.insert( "DivideBlending", new DivideBlending );
m_blendings.insert( "GammaDarkBlending", new GammaDarkBlending );
m_blendings.insert( "LinearBurnBlending", new LinearBurnBlending );
m_blendings.insert( "MultiplyBlending", new MultiplyBlending );
m_blendings.insert( "SubtractiveBlending", new SubtractiveBlending );
// Lightening blendings
m_blendings.insert( "AdditiveBlending", new AdditiveBlending );
m_blendings.insert( "ColorDodgeBlending", new ColorDodgeBlending );
m_blendings.insert( "GammaLightBlending", new GammaLightBlending );
m_blendings.insert( "HardLightBlending", new HardLightBlending );
m_blendings.insert( "LightBlending", new LightBlending );
m_blendings.insert( "LightenBlending", new LightenBlending );
m_blendings.insert( "PinLightBlending", new PinLightBlending );
m_blendings.insert( "ScreenBlending", new ScreenBlending );
m_blendings.insert( "SoftLightBlending", new SoftLightBlending );
m_blendings.insert( "VividLightBlending", new VividLightBlending );
// Inverter blendings
//m_blendings.insert( "AdditiveSubtractiveBlending", new AdditiveSubtractiveBlending );
m_blendings.insert( "BleachBlending", new BleachBlending );
m_blendings.insert( "DifferenceBlending", new DifferenceBlending );
m_blendings.insert( "EquivalenceBlending", new EquivalenceBlending );
m_blendings.insert( "HalfDifferenceBlending", new HalfDifferenceBlending );
// Special purpose blendings
m_blendings.insert( "CloudsBlending", new CloudsBlending );
m_blendings.insert( "SunLightBlending", m_sunLightBlending );
m_blendings.insert( "GrayscaleBlending", new GrayscaleBlending );
}
BlendingFactory::~BlendingFactory()
{
m_blendings.remove( "SunLightBlending" );
delete m_sunLightBlending;
qDeleteAll( m_blendings );
}
}
diff --git a/src/lib/marble/cloudsync/BookmarkSyncManager.cpp b/src/lib/marble/cloudsync/BookmarkSyncManager.cpp
index dc8659ebd..a36c1a9a7 100644
--- a/src/lib/marble/cloudsync/BookmarkSyncManager.cpp
+++ b/src/lib/marble/cloudsync/BookmarkSyncManager.cpp
@@ -1,808 +1,808 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#include "BookmarkSyncManager.h"
#include "GeoWriter.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "GeoDataParser.h"
#include "GeoDataFolder.h"
#include "GeoDataDocument.h"
#include "GeoDataLookAt.h"
#include "CloudSyncManager.h"
#include "GeoDataCoordinates.h"
#include "OwncloudSyncBackend.h"
#include "MarbleModel.h"
#include "BookmarkManager.h"
#include <QFile>
#include <QBuffer>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>
namespace Marble {
class DiffItem
{
public:
enum Action {
NoAction,
Created,
Changed,
Deleted
};
enum Status {
Source,
Destination
};
QString m_path;
Action m_action;
Status m_origin;
GeoDataPlacemark m_placemarkA;
GeoDataPlacemark m_placemarkB;
};
class Q_DECL_HIDDEN BookmarkSyncManager::Private
{
public:
Private( BookmarkSyncManager* parent, CloudSyncManager *cloudSyncManager );
BookmarkSyncManager* m_q;
CloudSyncManager *m_cloudSyncManager;
QNetworkAccessManager m_network;
QString m_uploadEndpoint;
QString m_downloadEndpoint;
QString m_timestampEndpoint;
QNetworkReply* m_uploadReply;
QNetworkReply* m_downloadReply;
QNetworkReply* m_timestampReply;
QString m_cloudTimestamp;
QString m_cachePath;
QString m_localBookmarksPath;
QString m_bookmarksTimestamp;
QList<DiffItem> m_diffA;
QList<DiffItem> m_diffB;
QList<DiffItem> m_merged;
DiffItem m_conflictItem;
BookmarkManager* m_bookmarkManager;
QTimer m_syncTimer;
bool m_bookmarkSyncEnabled;
/**
* Returns an API endpoint
* @param endpoint Endpoint itself without server info
* @return Complete API URL as QUrl
*/
QUrl endpointUrl( const QString &endpoint ) const;
/**
* Uploads local bookmarks.kml to cloud.
*/
void uploadBookmarks();
/**
* Downloads bookmarks.kml from cloud.
*/
void downloadBookmarks();
/**
* Gets cloud bookmarks.kml's timestamp from cloud.
*/
void downloadTimestamp();
/**
* Compares cloud bookmarks.kml's timestamp to last synced bookmarks.kml's timestamp.
* @return true if cloud one is different from last synced one.
*/
bool cloudBookmarksModified( const QString &cloudTimestamp ) const;
/**
* Removes all KMLs in the cache except the
* one with yougnest timestamp.
*/
void clearCache();
/**
* Finds the last synced bookmarks.kml file and returns its path
* @return Path of last synced bookmarks.kml file.
*/
QString lastSyncedKmlPath() const;
/**
* Gets all placemarks in a document as DiffItems, compares them to another document and puts the result in a list.
* @param document The document whose placemarks will be compared to another document's placemarks.
* @param other The document whose placemarks will be compared to the first document's placemarks.
* @param diffDirection Direction of comparison, e.g. must be DiffItem::Destination if direction is source to destination.
* @return A list of DiffItems
*/
QList<DiffItem> getPlacemarks(GeoDataDocument *document, GeoDataDocument *other, DiffItem::Status diffDirection );
/**
* Gets all placemarks in a document as DiffItems, compares them to another document and puts the result in a list.
* @param folder The folder whose placemarks will be compared to another document's placemarks.
* @param path Path of the folder.
* @param other The document whose placemarks will be compared to the first document's placemarks.
* @param diffDirection Direction of comparison, e.g. must be DiffItem::Destination if direction is source to destination.
* @return A list of DiffItems
*/
QList<DiffItem> getPlacemarks( GeoDataFolder *folder, QString &path, GeoDataDocument *other, DiffItem::Status diffDirection );
/**
* Finds the placemark which has the same coordinates with given bookmark
* @param container Container of placemarks which will be compared. Can be document or folder.
* @param bookmark The bookmark whose counterpart will be searched in the container.
* @return Counterpart of the given placemark.
*/
const GeoDataPlacemark* findPlacemark( GeoDataContainer* container, const GeoDataPlacemark &bookmark ) const;
/**
* Determines the status (created, deleted, changed or unchanged) of given DiffItem
* by comparing the item's placemark with placemarks of given GeoDataDocument.
* @param item The item whose status will be determined.
* @param document The document whose placemarks will be used to determine DiffItem's status.
*/
void determineDiffStatus( DiffItem &item, GeoDataDocument* document ) const;
/**
* Finds differences between two bookmark files.
* @param sourcePath Source bookmark
* @param destinationPath Destination bookmark
* @return A list of differences
*/
QList<DiffItem> diff( QString &sourcePath, QString &destinationPath );
QList<DiffItem> diff( QString &sourcePath, QIODevice* destination );
QList<DiffItem> diff( QIODevice* source, QString &destinationPath );
QList<DiffItem> diff( QIODevice *source, QIODevice* destination );
/**
* Merges two diff lists.
* @param diffListA First diff list.
* @param diffListB Second diff list.
* @return Merged DiffItems.
*/
void merge();
/**
* Creates GeoDataFolders using strings in path list.
* @param container Container which created GeoDataFolder will be attached to.
* @param pathList Names of folders. Note that each item will be the child of the previous one.
* @return A pointer to created folder.
*/
GeoDataFolder* createFolders( GeoDataContainer *container, QStringList &pathList );
/**
* Creates a GeoDataDocument using a list of DiffItems.
* @param mergedList DiffItems which will be used as placemarks.
* @return A pointer to created document.
*/
GeoDataDocument* constructDocument( const QList<DiffItem> &mergedList );
void saveDownloadedToCache( const QByteArray &kml );
void parseTimestamp();
void copyLocalToCache();
void continueSynchronization();
void completeSynchronization();
void completeMerge();
void completeUpload();
};
BookmarkSyncManager::Private::Private(BookmarkSyncManager *parent, CloudSyncManager *cloudSyncManager ) :
m_q( parent ),
m_cloudSyncManager( cloudSyncManager ),
- m_bookmarkManager( 0 ),
+ m_bookmarkManager( nullptr ),
m_bookmarkSyncEnabled( false )
{
m_cachePath = MarbleDirs::localPath() + QLatin1String("/cloudsync/cache/bookmarks");
m_localBookmarksPath = MarbleDirs::localPath() + QLatin1String("/bookmarks/bookmarks.kml");
m_downloadEndpoint = "bookmarks/kml";
m_uploadEndpoint = "bookmarks/update";
m_timestampEndpoint = "bookmarks/timestamp";
}
BookmarkSyncManager::BookmarkSyncManager( CloudSyncManager *cloudSyncManager ) :
QObject(),
d( new Private( this, cloudSyncManager ) )
{
d->m_syncTimer.setInterval( 60 * 60 * 1000 ); // 1 hour. TODO: Make this configurable.
connect( &d->m_syncTimer, SIGNAL(timeout()), this, SLOT(startBookmarkSync()) );
}
BookmarkSyncManager::~BookmarkSyncManager()
{
delete d;
}
QDateTime BookmarkSyncManager::lastSync() const
{
const QString last = d->lastSyncedKmlPath();
if (last.isEmpty())
return QDateTime();
return QFileInfo(last).created();
}
bool BookmarkSyncManager::isBookmarkSyncEnabled() const
{
return d->m_bookmarkSyncEnabled;
}
void BookmarkSyncManager::setBookmarkSyncEnabled( bool enabled )
{
bool const old_state = isBookmarkSyncEnabled();
d->m_bookmarkSyncEnabled = enabled;
if ( old_state != isBookmarkSyncEnabled() ) {
emit bookmarkSyncEnabledChanged( d->m_bookmarkSyncEnabled );
if ( isBookmarkSyncEnabled() ) {
startBookmarkSync();
}
}
}
void BookmarkSyncManager::setBookmarkManager(BookmarkManager *manager)
{
d->m_bookmarkManager = manager;
connect( manager, SIGNAL(bookmarksChanged()), this, SLOT(startBookmarkSync()) );
startBookmarkSync();
}
void BookmarkSyncManager::startBookmarkSync()
{
if ( !d->m_cloudSyncManager->isSyncEnabled() || !isBookmarkSyncEnabled() )
{
return;
}
d->m_syncTimer.start();
d->downloadTimestamp();
}
QUrl BookmarkSyncManager::Private::endpointUrl( const QString &endpoint ) const
{
return QUrl(m_cloudSyncManager->apiUrl().toString() + QLatin1Char('/') + endpoint);
}
void BookmarkSyncManager::Private::uploadBookmarks()
{
QByteArray data;
QByteArray lineBreak = "\r\n";
QString word = "----MarbleCloudBoundary";
QString boundary = QString( "--%0" ).arg( word );
QNetworkRequest request( endpointUrl( m_uploadEndpoint ) );
request.setHeader( QNetworkRequest::ContentTypeHeader, QString( "multipart/form-data; boundary=%0" ).arg( word ) );
data.append( QString( boundary + lineBreak ).toUtf8() );
data.append( "Content-Disposition: form-data; name=\"bookmarks\"; filename=\"bookmarks.kml\"" + lineBreak );
data.append( "Content-Type: application/vnd.google-earth.kml+xml" + lineBreak + lineBreak );
QFile bookmarksFile( m_localBookmarksPath );
if( !bookmarksFile.open( QFile::ReadOnly ) ) {
mDebug() << "Failed to open file" << bookmarksFile.fileName()
<< ". It is either missing or not readable.";
return;
}
QByteArray kmlContent = bookmarksFile.readAll();
data.append( kmlContent + lineBreak + lineBreak );
data.append( QString( boundary ).toUtf8() );
bookmarksFile.close();
m_uploadReply = m_network.post( request, data );
connect( m_uploadReply, SIGNAL(uploadProgress(qint64,qint64)),
m_q, SIGNAL(uploadProgress(qint64,qint64)) );
connect( m_uploadReply, SIGNAL(finished()),
m_q, SLOT(completeUpload()) );
}
void BookmarkSyncManager::Private::downloadBookmarks()
{
QNetworkRequest request( endpointUrl( m_downloadEndpoint ) );
m_downloadReply = m_network.get( request );
connect( m_downloadReply, SIGNAL(finished()),
m_q, SLOT(completeSynchronization()) );
connect( m_downloadReply, SIGNAL(downloadProgress(qint64,qint64)),
m_q, SIGNAL(downloadProgress(qint64,qint64)) );
}
void BookmarkSyncManager::Private::downloadTimestamp()
{
mDebug() << "Determining remote bookmark state.";
m_timestampReply = m_network.get( QNetworkRequest( endpointUrl( m_timestampEndpoint ) ) );
connect( m_timestampReply, SIGNAL(finished()),
m_q, SLOT(parseTimestamp()) );
}
bool BookmarkSyncManager::Private::cloudBookmarksModified( const QString &cloudTimestamp ) const
{
QStringList entryList = QDir( m_cachePath ).entryList(
// TODO: replace with regex filter that only
// allows timestamp filenames
QStringList() << "*.kml",
QDir::NoFilter, QDir::Name );
if( !entryList.isEmpty() ) {
QString lastSynced = entryList.last();
lastSynced.chop( 4 );
return cloudTimestamp != lastSynced;
} else {
return true; // That will let cloud one get downloaded.
}
}
void BookmarkSyncManager::Private::clearCache()
{
QDir cacheDir( m_cachePath );
QFileInfoList fileInfoList = cacheDir.entryInfoList(
QStringList() << "*.kml",
QDir::NoFilter, QDir::Name );
if( !fileInfoList.isEmpty() ) {
for ( const QFileInfo& fileInfo: fileInfoList ) {
QFile file( fileInfo.absoluteFilePath() );
bool removed = file.remove();
if( !removed ) {
mDebug() << "Could not delete" << file.fileName() <<
"Make sure you have sufficient permissions.";
}
}
}
}
QString BookmarkSyncManager::Private::lastSyncedKmlPath() const
{
QDir cacheDir( m_cachePath );
QFileInfoList fileInfoList = cacheDir.entryInfoList(
QStringList() << "*.kml",
QDir::NoFilter, QDir::Name );
if( !fileInfoList.isEmpty() ) {
return fileInfoList.last().absoluteFilePath();
} else {
return QString();
}
}
QList<DiffItem> BookmarkSyncManager::Private::getPlacemarks( GeoDataDocument *document, GeoDataDocument *other, DiffItem::Status diffDirection )
{
QList<DiffItem> diffItems;
for ( GeoDataFolder *folder: document->folderList() ) {
QString path = QString( "/%0" ).arg( folder->name() );
diffItems.append( getPlacemarks( folder, path, other, diffDirection ) );
}
return diffItems;
}
QList<DiffItem> BookmarkSyncManager::Private::getPlacemarks( GeoDataFolder *folder, QString &path, GeoDataDocument *other, DiffItem::Status diffDirection )
{
QList<DiffItem> diffItems;
for ( GeoDataFolder *subFolder: folder->folderList() ) {
QString newPath = QString( "%0/%1" ).arg( path, subFolder->name() );
diffItems.append( getPlacemarks( subFolder, newPath, other, diffDirection ) );
}
for( GeoDataPlacemark *placemark: folder->placemarkList() ) {
DiffItem diffItem;
diffItem.m_path = path;
diffItem.m_placemarkA = *placemark;
switch ( diffDirection ) {
case DiffItem::Source:
diffItem.m_origin = DiffItem::Destination;
break;
case DiffItem::Destination:
diffItem.m_origin = DiffItem::Source;
break;
default:
break;
}
determineDiffStatus( diffItem, other );
if( !( diffItem.m_action == DiffItem::NoAction && diffItem.m_origin == DiffItem::Destination )
&& !( diffItem.m_action == DiffItem::Changed && diffItem.m_origin == DiffItem::Source ) ) {
diffItems.append( diffItem );
}
}
return diffItems;
}
const GeoDataPlacemark* BookmarkSyncManager::Private::findPlacemark( GeoDataContainer* container, const GeoDataPlacemark &bookmark ) const
{
for( GeoDataPlacemark* placemark: container->placemarkList() ) {
if (EARTH_RADIUS * placemark->coordinate().sphericalDistanceTo(bookmark.coordinate()) <= 1) {
return placemark;
}
}
for( GeoDataFolder* folder: container->folderList() ) {
const GeoDataPlacemark* placemark = findPlacemark( folder, bookmark );
if ( placemark ) {
return placemark;
}
}
- return 0;
+ return nullptr;
}
void BookmarkSyncManager::Private::determineDiffStatus( DiffItem &item, GeoDataDocument *document ) const
{
const GeoDataPlacemark *match = findPlacemark( document, item.m_placemarkA );
- if( match != 0 ) {
+ if( match != nullptr ) {
item.m_placemarkB = *match;
bool nameChanged = item.m_placemarkA.name() != item.m_placemarkB.name();
bool descChanged = item.m_placemarkA.description() != item.m_placemarkB.description();
bool lookAtChanged = item.m_placemarkA.lookAt()->latitude() != item.m_placemarkB.lookAt()->latitude() ||
item.m_placemarkA.lookAt()->longitude() != item.m_placemarkB.lookAt()->longitude() ||
item.m_placemarkA.lookAt()->altitude() != item.m_placemarkB.lookAt()->altitude() ||
item.m_placemarkA.lookAt()->range() != item.m_placemarkB.lookAt()->range();
if( nameChanged || descChanged || lookAtChanged ) {
item.m_action = DiffItem::Changed;
} else {
item.m_action = DiffItem::NoAction;
}
} else {
switch( item.m_origin ) {
case DiffItem::Source:
item.m_action = DiffItem::Deleted;
item.m_placemarkB = item.m_placemarkA; // for conflict purposes
break;
case DiffItem::Destination:
item.m_action = DiffItem::Created;
break;
}
}
}
QList<DiffItem> BookmarkSyncManager::Private::diff( QString &sourcePath, QString &destinationPath )
{
QFile fileB( destinationPath );
if( !fileB.open( QFile::ReadOnly ) ) {
mDebug() << "Could not open file " << fileB.fileName();
}
return diff( sourcePath, &fileB );
}
QList<DiffItem> BookmarkSyncManager::Private::diff( QString &sourcePath, QIODevice *fileB )
{
QFile fileA( sourcePath );
if( !fileA.open( QFile::ReadOnly ) ) {
mDebug() << "Could not open file " << fileA.fileName();
}
return diff( &fileA, fileB );
}
QList<DiffItem> BookmarkSyncManager::Private::diff( QIODevice *source, QString &destinationPath )
{
QFile fileB( destinationPath );
if( !fileB.open( QFile::ReadOnly ) ) {
mDebug() << "Could not open file " << fileB.fileName();
}
return diff( source, &fileB );
}
QList<DiffItem> BookmarkSyncManager::Private::diff( QIODevice *fileA, QIODevice *fileB )
{
GeoDataParser parserA( GeoData_KML );
parserA.read( fileA );
GeoDataDocument *documentA = dynamic_cast<GeoDataDocument*>( parserA.releaseDocument() );
GeoDataParser parserB( GeoData_KML );
parserB.read( fileB );
GeoDataDocument *documentB = dynamic_cast<GeoDataDocument*>( parserB.releaseDocument() );
QList<DiffItem> diffItems = getPlacemarks( documentA, documentB, DiffItem::Destination ); // Compare old to new
diffItems.append( getPlacemarks( documentB, documentA, DiffItem::Source ) ); // Compare new to old
// Compare paths
for( int i = 0; i < diffItems.count(); i++ ) {
for( int p = i + 1; p < diffItems.count(); p++ ) {
if( ( diffItems[i].m_origin == DiffItem::Source )
&& ( diffItems[i].m_action == DiffItem::NoAction )
&& ( EARTH_RADIUS * diffItems[i].m_placemarkA.coordinate().sphericalDistanceTo(diffItems[p].m_placemarkB.coordinate()) <= 1 )
&& ( EARTH_RADIUS * diffItems[i].m_placemarkB.coordinate().sphericalDistanceTo(diffItems[p].m_placemarkA.coordinate()) <= 1 )
&& ( diffItems[i].m_path != diffItems[p].m_path ) ) {
diffItems[p].m_action = DiffItem::Changed;
}
}
}
return diffItems;
}
void BookmarkSyncManager::Private::merge()
{
for( const DiffItem &itemA: m_diffA ) {
if( itemA.m_action == DiffItem::NoAction ) {
bool deleted = false;
bool changed = false;
DiffItem other;
for( const DiffItem &itemB: m_diffB ) {
if( EARTH_RADIUS * itemA.m_placemarkA.coordinate().sphericalDistanceTo(itemB.m_placemarkA.coordinate()) <= 1 ) {
if( itemB.m_action == DiffItem::Deleted ) {
deleted = true;
} else if( itemB.m_action == DiffItem::Changed ) {
changed = true;
other = itemB;
}
}
}
if( changed ) {
m_merged.append( other );
} else if( !deleted ) {
m_merged.append( itemA );
}
} else if( itemA.m_action == DiffItem::Created ) {
m_merged.append( itemA );
} else if( itemA.m_action == DiffItem::Changed || itemA.m_action == DiffItem::Deleted ) {
bool conflict = false;
DiffItem other;
for( const DiffItem &itemB: m_diffB ) {
if (EARTH_RADIUS * itemA.m_placemarkB.coordinate().sphericalDistanceTo(itemB.m_placemarkB.coordinate()) <= 1) {
if( ( itemA.m_action == DiffItem::Changed && ( itemB.m_action == DiffItem::Changed || itemB.m_action == DiffItem::Deleted ) )
|| ( itemA.m_action == DiffItem::Deleted && itemB.m_action == DiffItem::Changed ) ) {
conflict = true;
other = itemB;
}
}
}
if( !conflict && itemA.m_action == DiffItem::Changed ) {
m_merged.append( itemA );
} else if ( conflict ) {
m_conflictItem = other;
MergeItem *mergeItem = new MergeItem();
mergeItem->setPathA( itemA.m_path );
mergeItem->setPathB( other.m_path );
mergeItem->setPlacemarkA( itemA.m_placemarkA );
mergeItem->setPlacemarkB( other.m_placemarkA );
switch( itemA.m_action ) {
case DiffItem::Changed:
mergeItem->setActionA( MergeItem::Changed );
break;
case DiffItem::Deleted:
mergeItem->setActionA( MergeItem::Deleted );
break;
default:
break;
}
switch( other.m_action ) {
case DiffItem::Changed:
mergeItem->setActionB( MergeItem::Changed );
break;
case DiffItem::Deleted:
mergeItem->setActionB( MergeItem::Deleted );
break;
default:
break;
}
emit m_q->mergeConflict( mergeItem );
return;
}
}
if( !m_diffA.isEmpty() ) {
m_diffA.removeFirst();
}
}
for( const DiffItem &itemB: m_diffB ) {
if( itemB.m_action == DiffItem::Created ) {
m_merged.append( itemB );
}
}
completeMerge();
}
GeoDataFolder* BookmarkSyncManager::Private::createFolders( GeoDataContainer *container, QStringList &pathList )
{
- GeoDataFolder *folder = 0;
+ GeoDataFolder *folder = nullptr;
if( pathList.count() > 0 ) {
QString name = pathList.takeFirst();
for( GeoDataFolder *otherFolder: container->folderList() ) {
if( otherFolder->name() == name ) {
folder = otherFolder;
}
}
- if( folder == 0 ) {
+ if( folder == nullptr ) {
folder = new GeoDataFolder();
folder->setName( name );
container->append( folder );
}
if( pathList.count() == 0 ) {
return folder;
}
}
return createFolders( folder, pathList );
}
GeoDataDocument* BookmarkSyncManager::Private::constructDocument( const QList<DiffItem> &mergedList )
{
GeoDataDocument *document = new GeoDataDocument();
document->setName( tr( "Bookmarks" ) );
for( const DiffItem &item: mergedList ) {
GeoDataPlacemark *placemark = new GeoDataPlacemark( item.m_placemarkA );
QStringList splitten = item.m_path.split(QLatin1Char('/'), QString::SkipEmptyParts);
GeoDataFolder *folder = createFolders( document, splitten );
folder->append( placemark );
}
return document;
}
void BookmarkSyncManager::resolveConflict( MergeItem *item )
{
DiffItem diffItem;
switch( item->resolution() ) {
case MergeItem::A:
if( !d->m_diffA.isEmpty() ) {
diffItem = d->m_diffA.first();
break;
}
case MergeItem::B:
diffItem = d->m_conflictItem;
break;
default:
return; // It shouldn't happen.
}
if( diffItem.m_action != DiffItem::Deleted ) {
d->m_merged.append( diffItem );
}
if( !d->m_diffA.isEmpty() ) {
d->m_diffA.removeFirst();
}
d->merge();
}
void BookmarkSyncManager::Private::saveDownloadedToCache( const QByteArray &kml )
{
QString localBookmarksDir = m_localBookmarksPath;
QDir().mkdir( localBookmarksDir.remove( "bookmarks.kml" ) );
QFile bookmarksFile( m_localBookmarksPath );
if( !bookmarksFile.open( QFile::ReadWrite ) ) {
mDebug() << "Failed to open file" << bookmarksFile.fileName()
<< ". It is either missing or not readable.";
return;
}
bookmarksFile.write( kml );
bookmarksFile.close();
copyLocalToCache();
}
void BookmarkSyncManager::Private::parseTimestamp()
{
QJsonDocument jsonDoc = QJsonDocument::fromJson(m_timestampReply->readAll());
QJsonValue dataValue = jsonDoc.object().value(QStringLiteral("data"));
m_cloudTimestamp = dataValue.toString();
mDebug() << "Remote bookmark timestamp is " << m_cloudTimestamp;
continueSynchronization();
}
void BookmarkSyncManager::Private::copyLocalToCache()
{
QDir().mkpath( m_cachePath );
clearCache();
QFile bookmarksFile( m_localBookmarksPath );
bookmarksFile.copy( QString( "%0/%1.kml" ).arg( m_cachePath, m_cloudTimestamp ) );
}
// Bookmark synchronization steps
void BookmarkSyncManager::Private::continueSynchronization()
{
bool cloudModified = cloudBookmarksModified( m_cloudTimestamp );
if( cloudModified ) {
downloadBookmarks();
} else {
QString lastSyncedPath = lastSyncedKmlPath();
if( lastSyncedPath.isEmpty() ) {
mDebug() << "Never synced. Uploading bookmarks.";
uploadBookmarks();
} else {
QList<DiffItem> diffList = diff( lastSyncedPath, m_localBookmarksPath );
bool localModified = false;
for( const DiffItem &item: diffList ) {
if( item.m_action != DiffItem::NoAction ) {
localModified = true;
}
}
if( localModified ) {
mDebug() << "Local modifications, uploading.";
uploadBookmarks();
}
}
}
}
void BookmarkSyncManager::Private::completeSynchronization()
{
mDebug() << "Merging remote and local bookmark file";
QString lastSyncedPath = lastSyncedKmlPath();
QFile localBookmarksFile( m_localBookmarksPath );
QByteArray result = m_downloadReply->readAll();
QBuffer buffer( &result );
buffer.open( QIODevice::ReadOnly );
if( lastSyncedPath.isEmpty() ) {
if( localBookmarksFile.exists() ) {
mDebug() << "Conflict between remote bookmarks and local ones";
m_diffA = diff( &buffer, m_localBookmarksPath );
m_diffB = diff( m_localBookmarksPath, &buffer );
} else {
saveDownloadedToCache( result );
return;
}
}
else
{
m_diffA = diff( lastSyncedPath, m_localBookmarksPath );
m_diffB = diff( lastSyncedPath, &buffer );
}
m_merged.clear();
merge();
}
void BookmarkSyncManager::Private::completeMerge()
{
QFile localBookmarksFile( m_localBookmarksPath );
GeoDataDocument *doc = constructDocument( m_merged );
GeoWriter writer;
localBookmarksFile.remove();
localBookmarksFile.open( QFile::ReadWrite );
writer.write( &localBookmarksFile, doc );
localBookmarksFile.close();
uploadBookmarks();
}
void BookmarkSyncManager::Private::completeUpload()
{
QJsonDocument jsonDoc = QJsonDocument::fromJson(m_uploadReply->readAll());
QJsonValue dataValue = jsonDoc.object().value(QStringLiteral("data"));
m_cloudTimestamp = dataValue.toString();
mDebug() << "Uploaded bookmarks to remote server. Timestamp is " << m_cloudTimestamp;
copyLocalToCache();
emit m_q->syncComplete();
}
}
#include "moc_BookmarkSyncManager.cpp"
diff --git a/src/lib/marble/cloudsync/CloudRouteModel.h b/src/lib/marble/cloudsync/CloudRouteModel.h
index 41013c9dd..fdfa51971 100644
--- a/src/lib/marble/cloudsync/CloudRouteModel.h
+++ b/src/lib/marble/cloudsync/CloudRouteModel.h
@@ -1,113 +1,113 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#ifndef CLOUDROUTEMODEL_H
#define CLOUDROUTEMODEL_H
#include "marble_export.h"
#include <QModelIndex>
#include <QAbstractListModel>
class QNetworkReply;
namespace Marble
{
class RouteItem;
class MARBLE_EXPORT CloudRouteModel : public QAbstractListModel
{
Q_OBJECT
public:
enum RouteRoles {
Timestamp = Qt::UserRole + 1,
Name,
PreviewUrl,
Distance,
Duration,
IsCached,
IsDownloading,
IsOnCloud
};
- explicit CloudRouteModel( QObject *parent = 0 );
+ explicit CloudRouteModel( QObject *parent = nullptr );
~CloudRouteModel() override;
QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override;
int rowCount( const QModelIndex& parent = QModelIndex() ) const override;
/** Overload of QAbstractListModel */
QHash<int, QByteArray> roleNames() const override;
/**
* Sets the list of routes that will show up in CloudRoutesDialog.
* @param items List of routes.
*/
void setItems( const QVector<RouteItem> &items );
/**
* Checks if specified route exists in the local cache.
* @param index Index of the route.
* @return true, if exists.
*/
bool isCached( const QModelIndex &index ) const;
/**
* Getter for the item currently being downloaded.
* @return Model for the item currently being downloaded
*/
QPersistentModelIndex downloadingItem() const;
/**
* Marks the route at given index as being downloaded.
* @param index Index of the route.
*/
void setDownloadingItem( const QPersistentModelIndex &index );
/**
* Checks if route is being downloaded.
* @param index Index of the route.
* @return true, if downloading.
*/
bool isDownloading( const QModelIndex &index ) const;
/**
* Total size of the item currently being downloaded.
* @return Total size of the item, -1 if no route is being downloaded
*/
qint64 totalSize() const;
/**
* Returns how much of the route are downloaded as bytes
* @return Downloaded bytes
*/
qint64 downloadedSize() const;
/**
* Checks whether a preview for the route available and
* returns or downloads the preview
* @param index Index of the item whose preview is requested
* @return Route's preview as QIcon
*/
QIcon preview( const QModelIndex &index ) const;
public Q_SLOTS:
void updateProgress( qint64 currentSize, qint64 totalSize );
void setPreview( QNetworkReply *reply );
private:
class Private;
Private *d;
};
}
#endif // CLOUDROUTEMODEL_H
diff --git a/src/lib/marble/cloudsync/CloudRoutesDialog.h b/src/lib/marble/cloudsync/CloudRoutesDialog.h
index a4ba03074..13359f145 100644
--- a/src/lib/marble/cloudsync/CloudRoutesDialog.h
+++ b/src/lib/marble/cloudsync/CloudRoutesDialog.h
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#ifndef CLOUDROUTESDIALOG_H
#define CLOUDROUTESDIALOG_H
#include <QDialog>
namespace Marble {
class CloudRouteModel;
class CloudRoutesDialog : public QDialog
{
Q_OBJECT
public:
- explicit CloudRoutesDialog( CloudRouteModel *model, QWidget *parent = 0 );
+ explicit CloudRoutesDialog( CloudRouteModel *model, QWidget *parent = nullptr );
~CloudRoutesDialog() override;
CloudRouteModel *model();
public Q_SLOTS:
void updateListDownloadProgressbar( qint64 received, qint64 total );
Q_SIGNALS:
void downloadButtonClicked( const QString& timestamp );
void openButtonClicked( const QString& timestamp );
void deleteButtonClicked( const QString& timestamp );
void removeFromCacheButtonClicked( const QString& timestamp );
void uploadToCloudButtonClicked( const QString& timestamp );
private:
class Private;
Private *d;
private Q_SLOTS:
void updateNoRouteLabel();
};
}
#endif // CLOUDROUTESDIALOG_H
diff --git a/src/lib/marble/cloudsync/CloudSyncManager.cpp b/src/lib/marble/cloudsync/CloudSyncManager.cpp
index c496b8749..78a75a773 100644
--- a/src/lib/marble/cloudsync/CloudSyncManager.cpp
+++ b/src/lib/marble/cloudsync/CloudSyncManager.cpp
@@ -1,218 +1,218 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#include "CloudSyncManager.h"
#include "BookmarkSyncManager.h"
#include "RouteSyncManager.h"
namespace Marble
{
class Q_DECL_HIDDEN CloudSyncManager::Private {
public:
Private();
~Private();
bool m_workOffline;
bool m_syncEnabled;
QString m_owncloudProtocol;
QString m_ownloudServer;
QString m_owncloudUsername;
QString m_owncloudPassword;
QString m_status;
CloudSyncManager::Status m_status_type;
RouteSyncManager* m_routeSyncManager;
BookmarkSyncManager* m_bookmarkSyncManager;
};
CloudSyncManager::Private::~Private()
{
delete m_routeSyncManager;
delete m_bookmarkSyncManager;
}
CloudSyncManager::Private::Private() :
m_workOffline( false ),
m_syncEnabled( false ),
m_owncloudProtocol( "http" ),
m_ownloudServer(),
m_owncloudUsername(),
m_owncloudPassword(),
m_status(),
m_status_type( CloudSyncManager::Unknown),
- m_routeSyncManager( 0 ),
- m_bookmarkSyncManager( 0 )
+ m_routeSyncManager( nullptr ),
+ m_bookmarkSyncManager( nullptr )
{
}
CloudSyncManager::CloudSyncManager( QObject *parent ) :
QObject( parent ),
d( new Private )
{
}
CloudSyncManager::~CloudSyncManager()
{
delete d;
}
bool CloudSyncManager::workOffline() const
{
return d->m_workOffline;
}
void CloudSyncManager::setWorkOffline( bool offline )
{
if ( offline != d->m_workOffline ) {
d->m_workOffline = offline;
emit workOfflineChanged( d->m_workOffline );
}
}
bool CloudSyncManager::isSyncEnabled() const
{
return d->m_syncEnabled;
}
QString CloudSyncManager::owncloudServer() const
{
return d->m_owncloudProtocol + d->m_ownloudServer;
}
QString CloudSyncManager::owncloudUsername() const
{
return d->m_owncloudUsername;
}
QString CloudSyncManager::owncloudPassword() const
{
return d->m_owncloudPassword;
}
void CloudSyncManager::setSyncEnabled( bool enabled )
{
if ( d->m_syncEnabled != enabled ) {
d->m_syncEnabled = enabled;
emit syncEnabledChanged( d->m_syncEnabled );
}
}
void CloudSyncManager::setOwncloudCredentials( const QString &server, const QString &user, const QString &password )
{
QUrl const oldApiUrl = apiUrl();
blockSignals( true );
setOwncloudServer( server );
setOwncloudUsername( user );
setOwncloudPassword( password );
blockSignals( false );
if ( oldApiUrl != apiUrl() ) {
emit apiUrlChanged( apiUrl() );
}
}
void CloudSyncManager::setOwncloudServer( const QString &server )
{
QString const oldProtocol = d->m_owncloudProtocol;
QString const oldServer = d->m_ownloudServer;
if (server.startsWith(QLatin1String("http://"))) {
d->m_owncloudProtocol = "http://";
d->m_ownloudServer = server.mid( 7 );
} else if (server.startsWith(QLatin1String("https://"))) {
d->m_owncloudProtocol = "https://";
d->m_ownloudServer = server.mid ( 8 );
} else {
d->m_owncloudProtocol = "http://";
d->m_ownloudServer = server;
}
if ( oldServer != d->m_ownloudServer ) {
emit owncloudServerChanged( owncloudServer() );
emit apiUrlChanged( apiUrl() );
} else if ( oldProtocol != d->m_owncloudProtocol ) {
emit apiUrlChanged( apiUrl() );
}
}
void CloudSyncManager::setOwncloudUsername( const QString &username )
{
if ( d->m_owncloudUsername != username ) {
d->m_owncloudUsername = username;
emit owncloudUsernameChanged( d->m_owncloudUsername );
emit apiUrlChanged( apiUrl() );
}
}
void CloudSyncManager::setOwncloudPassword( const QString &password )
{
if ( d->m_owncloudPassword != password ) {
d->m_owncloudPassword = password;
emit owncloudPasswordChanged( d->m_owncloudPassword );
emit apiUrlChanged( apiUrl() );
}
}
void CloudSyncManager::setStatus( const QString &status, CloudSyncManager::Status status_type )
{
if( d->m_status != status && d->m_status_type != status_type) {
d->m_status = status;
d->m_status_type = status_type;
emit statusChanged( d->m_status );
}
}
CloudSyncManager::Status CloudSyncManager::status() const
{
return d->m_status_type;
}
QString CloudSyncManager::statusDescription() const
{
return d->m_status;
}
QString CloudSyncManager::apiPath() const
{
return "index.php/apps/marble/api/v1";
}
QUrl CloudSyncManager::apiUrl() const
{
return QUrl( QString( "%0%1:%2@%3/%4" )
.arg( d->m_owncloudProtocol )
.arg( d->m_owncloudUsername ).arg( d->m_owncloudPassword )
.arg( d->m_ownloudServer ).arg( apiPath() ) );
}
RouteSyncManager *CloudSyncManager::routeSyncManager()
{
if ( !d->m_routeSyncManager ) {
d->m_routeSyncManager = new RouteSyncManager( this );
}
return d->m_routeSyncManager;
}
BookmarkSyncManager *CloudSyncManager::bookmarkSyncManager()
{
if ( !d->m_bookmarkSyncManager ) {
d->m_bookmarkSyncManager = new BookmarkSyncManager( this );
}
return d->m_bookmarkSyncManager;
}
}
#include "moc_CloudSyncManager.cpp"
diff --git a/src/lib/marble/cloudsync/CloudSyncManager.h b/src/lib/marble/cloudsync/CloudSyncManager.h
index caec0dbf4..f40bcf872 100644
--- a/src/lib/marble/cloudsync/CloudSyncManager.h
+++ b/src/lib/marble/cloudsync/CloudSyncManager.h
@@ -1,177 +1,177 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#ifndef CLOUDSYNCMANAGER_H
#define CLOUDSYNCMANAGER_H
#include <QObject>
#include <QUrl>
#include "marble_export.h"
namespace Marble {
class BookmarkSyncManager;
class RouteSyncManager;
class MARBLE_EXPORT CloudSyncManager : public QObject
{
Q_OBJECT
Q_PROPERTY( bool workOffline READ workOffline WRITE setWorkOffline NOTIFY workOfflineChanged )
Q_PROPERTY( bool syncEnabled READ isSyncEnabled WRITE setSyncEnabled NOTIFY syncEnabledChanged )
Q_PROPERTY( QString owncloudUsername READ owncloudUsername WRITE setOwncloudUsername NOTIFY owncloudUsernameChanged )
Q_PROPERTY( QString owncloudPassword READ owncloudPassword WRITE setOwncloudPassword NOTIFY owncloudPasswordChanged )
Q_PROPERTY( QString owncloudServer READ owncloudServer WRITE setOwncloudServer NOTIFY owncloudServerChanged )
Q_PROPERTY( QUrl apiUrl READ apiUrl NOTIFY apiUrlChanged )
Q_PROPERTY( BookmarkSyncManager* bookmarkSyncManager READ bookmarkSyncManager NOTIFY bookmarkSyncManagerChanged )
Q_PROPERTY( RouteSyncManager* routeSyncManager READ routeSyncManager NOTIFY routeSyncManagerChanged )
public:
- explicit CloudSyncManager( QObject *parent = 0 );
+ explicit CloudSyncManager( QObject *parent = nullptr );
~CloudSyncManager() override;
/**
* Status enumeration
*/
enum Status { Unknown, Success, Error };
/**
* Getter for offine mode.
* @return true if offline mode enabled
*/
bool workOffline() const;
/**
* Setter for offine mode.
* @param offline Status of offline mode
*/
void setWorkOffline( bool offline );
/**
* Checks if the user enabled synchronization.
* @return true if synchronization enabled
*/
bool isSyncEnabled() const;
/**
* Gets ownCloud server from settings.
* @return ownCloud server
*/
QString owncloudServer() const;
/**
* Gets ownCloud username from settings.
* @return ownCloud username
*/
QString owncloudUsername() const;
/**
* Gets ownCloud password from settings
* @return ownCloud password
*/
QString owncloudPassword() const;
/**
* Setter for enabling/disabling synchronization.
* @param enabled Status of synchronization.
*/
void setSyncEnabled( bool enabled );
/**
* Change owncloud server URL, username and password at once without emitting change
* signals like setOwncloudServer, setOwncloudUsername, setOwncloudPassword do.
* The apiUrlChanged signal is emitted, if needed, however.
* @brief setOwncloudCredentials
* @param server
* @param user
* @param password
*/
void setOwncloudCredentials( const QString &server, const QString &user, const QString &password );
/**
* Setter for ownCloud server.
* @param server ownCloud server
*/
void setOwncloudServer( const QString &owncloudServer );
/**
* Setter for ownCloud username.
* @param username ownCloud username
*/
void setOwncloudUsername( const QString &owncloudUsername );
/**
* Setter for ownCloud password.
* @param password ownCloud password
*/
void setOwncloudPassword( const QString &owncloudPassword );
/**
* Setter for authentication error.
* @param error authentication error
*/
void setStatus( const QString &status, CloudSyncManager::Status status_type );
/**
* @return Last synchronization status
*/
CloudSyncManager::Status status() const;
/**
* @return A human readable description of the last synchronization status
*/
QString statusDescription() const;
/**
* Returns API path as a QString.
* @return API path
*/
QString apiPath() const;
/**
* Returns an API url ready for use.
* @return API url as QString
*/
QUrl apiUrl() const;
/**
* @return A ready to use BookmarkSyncManager instance
*/
RouteSyncManager* routeSyncManager();
/**
* @return A ready to use BookmarkSyncManager instance
*/
BookmarkSyncManager* bookmarkSyncManager();
Q_SIGNALS:
void workOfflineChanged(bool workOffline);
void syncEnabledChanged(bool enabled);
void owncloudUsernameChanged(const QString &username);
void owncloudPasswordChanged(const QString &password);
void owncloudServerChanged(const QString &server);
void statusChanged(const QString &status);
void apiUrlChanged(const QUrl &url);
void routeSyncManagerChanged();
void bookmarkSyncManagerChanged();
private:
class Private;
Private *d;
};
}
#endif // CLOUDSYNCMANAGER_H
diff --git a/src/lib/marble/cloudsync/ConflictDialog.cpp b/src/lib/marble/cloudsync/ConflictDialog.cpp
index 31732b6d2..a5fdb32bd 100644
--- a/src/lib/marble/cloudsync/ConflictDialog.cpp
+++ b/src/lib/marble/cloudsync/ConflictDialog.cpp
@@ -1,188 +1,188 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#include "ConflictDialog.h"
#include "MergeItem.h"
#include <QLabel>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QVariant>
namespace Marble {
ConflictDialog::ConflictDialog( QWidget *parent ) :
QDialog( parent ),
- m_mergeItem( 0 ),
- m_box( 0 ),
+ m_mergeItem( nullptr ),
+ m_box( nullptr ),
m_resolveAction(ConflictDialog::AskUser)
{
// nothing to do
}
void ConflictDialog::setMergeItem( MergeItem *item )
{
m_mergeItem = item;
}
void ConflictDialog::stopAutoResolve()
{
m_resolveAction = ConflictDialog::AskUser;
}
void ConflictDialog::open()
{
- if( m_mergeItem == 0 ) {
+ if( m_mergeItem == nullptr ) {
return;
}
switch( m_resolveAction ) {
case ConflictDialog::AskUser:
prepareLayout();
QDialog::open();
break;
case ConflictDialog::PreferLocal:
m_mergeItem->setResolution( MergeItem::A );
emit resolveConflict( m_mergeItem );
break;
case ConflictDialog::PreferCloud:
m_mergeItem->setResolution( MergeItem::B );
emit resolveConflict( m_mergeItem );
break;
}
}
void ConflictDialog::resolveConflict( QAbstractButton *button )
{
accept();
QDialogButtonBox::StandardButton standardButton = m_box->standardButton( button );
switch(standardButton) {
case QDialogButtonBox::NoButton:
{
int actionRole = button->property( "ActionRole" ).toInt();
switch( actionRole ) {
case ConflictDialog::Local:
m_mergeItem->setResolution( MergeItem::A );
emit resolveConflict( m_mergeItem );
break;
case ConflictDialog::Cloud:
m_mergeItem->setResolution( MergeItem::B );
emit resolveConflict( m_mergeItem );
break;
case ConflictDialog::AllLocal:
m_mergeItem->setResolution( MergeItem::A );
m_resolveAction = ConflictDialog::PreferLocal;
emit resolveConflict( m_mergeItem );
break;
case ConflictDialog::AllCloud:
m_mergeItem->setResolution( MergeItem::B );
m_resolveAction = ConflictDialog::PreferCloud;
emit resolveConflict( m_mergeItem );
break;
default:
break;
}
}
default:
break;
}
}
void ConflictDialog::prepareLayout()
{
delete layout();
qDeleteAll( children() );
m_box = new QDialogButtonBox( QDialogButtonBox::Cancel );
QPushButton *localButton = new QPushButton( tr( "Use local" ) );
QPushButton *cloudButton = new QPushButton( tr( "Use cloud" ) );
QPushButton *allLocalButton = new QPushButton( tr( "Always use local" ) );
QPushButton *allCloudButton = new QPushButton( tr( "Always use cloud" ) );
localButton->setDefault( true );
localButton->setProperty( "ActionRole", ConflictDialog::Local );
cloudButton->setProperty( "ActionRole", ConflictDialog::Cloud );
allLocalButton->setProperty( "ActionRole", ConflictDialog::AllLocal );
allCloudButton->setProperty( "ActionRole", ConflictDialog::AllCloud );
m_box->addButton( localButton, QDialogButtonBox::ActionRole );
m_box->addButton( cloudButton, QDialogButtonBox::ActionRole );
m_box->addButton( allLocalButton, QDialogButtonBox::ActionRole );
m_box->addButton( allCloudButton, QDialogButtonBox::ActionRole );
QVBoxLayout *leftLayout = new QVBoxLayout();
QString localHeaderText = tr( "Local placemark" );
QString localDetailText = tr( "Path: %0 <br /> Name: %1 <br /> Description: %2 <br /> Status: %3" )
.arg( m_mergeItem->pathA(), m_mergeItem->nameA(), m_mergeItem->descriptionA() );
switch( m_mergeItem->actionA() ) {
case MergeItem::Changed:
localDetailText = localDetailText.arg( tr( "Changed" ) );
break;
case MergeItem::Deleted:
localDetailText = localDetailText.arg( tr( "Deleted" ) );
break;
default:
break;
}
QLabel *localHeaderLabel = new QLabel( localHeaderText );
QLabel *localDetailLabel = new QLabel( localDetailText );
leftLayout->addWidget( localHeaderLabel );
leftLayout->addWidget( localDetailLabel );
QVBoxLayout *rightLayout = new QVBoxLayout();
QString cloudHeaderText = tr( "Cloud placemark" );
QString cloudDetailText = tr( "Path: %0 <br /> Name: %1 <br /> Description: %2 <br /> Status: %3" )
.arg( m_mergeItem->pathB(), m_mergeItem->nameB(), m_mergeItem->descriptionB() );
switch( m_mergeItem->actionB() ) {
case MergeItem::Changed:
cloudDetailText = cloudDetailText.arg( tr( "Changed" ) );
break;
case MergeItem::Deleted:
cloudDetailText = cloudDetailText.arg( tr( "Deleted" ) );
break;
default:
break;
}
QLabel *cloudHeaderLabel = new QLabel( cloudHeaderText );
QLabel *cloudDetailLabel = new QLabel( cloudDetailText );
rightLayout->addWidget( cloudHeaderLabel );
rightLayout->addWidget( cloudDetailLabel );
QHBoxLayout *detailLayout = new QHBoxLayout();
detailLayout->addLayout( leftLayout );
detailLayout->addLayout( rightLayout );
QLabel *descriptionLabel = new QLabel();
QString descriptionText = tr( "A bookmark on this device conflicts " \
"with a cloud bookmark. Which one do " \
"you want to keep?" );
descriptionLabel->setText( descriptionText );
QVBoxLayout *mainLayout = new QVBoxLayout();
mainLayout->addWidget( descriptionLabel );
mainLayout->addLayout( detailLayout );
mainLayout->addWidget( m_box );
setLayout( mainLayout );
setWindowTitle( tr( "Synchronization Conflict" ) );
connect( m_box, SIGNAL(clicked(QAbstractButton*)),
this, SLOT(resolveConflict(QAbstractButton*)) );
}
}
#include "moc_ConflictDialog.cpp"
diff --git a/src/lib/marble/cloudsync/ConflictDialog.h b/src/lib/marble/cloudsync/ConflictDialog.h
index c8171e9e6..7b382b48a 100644
--- a/src/lib/marble/cloudsync/ConflictDialog.h
+++ b/src/lib/marble/cloudsync/ConflictDialog.h
@@ -1,67 +1,67 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#ifndef CONFLICTDIALOG_H
#define CONFLICTDIALOG_H
#include "marble_export.h"
#include <QDialog>
class QDialogButtonBox;
class QAbstractButton;
namespace Marble
{
class MergeItem;
class MARBLE_EXPORT ConflictDialog : public QDialog
{
Q_OBJECT
public:
enum Button {
Local = 1,
Cloud,
AllLocal,
AllCloud
};
enum ResolveAction {
AskUser,
PreferLocal,
PreferCloud
};
- explicit ConflictDialog( QWidget *parent = 0 );
+ explicit ConflictDialog( QWidget *parent = nullptr );
void setMergeItem( MergeItem *item );
public Q_SLOTS:
void open() override;
void stopAutoResolve();
Q_SIGNALS:
void resolveConflict( MergeItem *mergeItem );
private Q_SLOTS:
void resolveConflict( QAbstractButton *button );
private:
void prepareLayout();
MergeItem *m_mergeItem;
QDialogButtonBox *m_box;
ConflictDialog::ResolveAction m_resolveAction;
};
}
#endif // CONFLICTDIALOG_H
diff --git a/src/lib/marble/cloudsync/RouteSyncManager.cpp b/src/lib/marble/cloudsync/RouteSyncManager.cpp
index 103b81578..943f1b6e4 100644
--- a/src/lib/marble/cloudsync/RouteSyncManager.cpp
+++ b/src/lib/marble/cloudsync/RouteSyncManager.cpp
@@ -1,285 +1,285 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Utku Aydın <utkuaydin34@gmail.com>
//
#include "RouteSyncManager.h"
#include "GeoDataParser.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "GeoDataFolder.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "CloudRouteModel.h"
#include "CloudRoutesDialog.h"
#include "CloudSyncManager.h"
#include "OwncloudSyncBackend.h"
#include "RouteItem.h"
#include "RoutingManager.h"
#include <QDir>
#include <QUrl>
#include <QFile>
#include <QIcon>
#include <QPointer>
namespace Marble
{
/**
* Private class for RouteSyncManager.
*/
class Q_DECL_HIDDEN RouteSyncManager::Private {
public:
Private( CloudSyncManager *cloudSyncManager );
~Private();
bool m_routeSyncEnabled;
CloudSyncManager *m_cloudSyncManager;
RoutingManager *m_routingManager;
CloudRouteModel *m_model;
QDir m_cacheDir;
OwncloudSyncBackend m_owncloudBackend;
QVector<RouteItem> m_routeList;
};
RouteSyncManager::Private::Private( CloudSyncManager *cloudSyncManager ) :
m_routeSyncEnabled( false ),
m_cloudSyncManager( cloudSyncManager ),
- m_routingManager( 0 ),
+ m_routingManager( nullptr ),
m_model( new CloudRouteModel() ),
m_owncloudBackend( cloudSyncManager )
{
m_cacheDir = QDir(MarbleDirs::localPath() + QLatin1String("/cloudsync/cache/routes/"));
}
RouteSyncManager::Private::~Private()
{
delete m_model;
}
RouteSyncManager::RouteSyncManager(CloudSyncManager *cloudSyncManager) :
d( new Private( cloudSyncManager ) )
{
connect( &d->m_owncloudBackend, SIGNAL(routeUploadProgress(qint64,qint64)), this, SLOT(updateUploadProgressbar(qint64,qint64)) );
connect( &d->m_owncloudBackend, SIGNAL(routeListDownloaded(QVector<RouteItem>)), this, SLOT(setRouteModelItems(QVector<RouteItem>)) );
connect( &d->m_owncloudBackend, SIGNAL(routeListDownloadProgress(qint64,qint64)), this, SIGNAL(routeListDownloadProgress(qint64,qint64)) );
connect( &d->m_owncloudBackend, SIGNAL(routeDownloadProgress(qint64,qint64)), d->m_model, SLOT(updateProgress(qint64,qint64)) );
connect( &d->m_owncloudBackend, SIGNAL(routeDownloaded()), this, SLOT(prepareRouteList()) );
connect( &d->m_owncloudBackend, SIGNAL(routeDeleted()), this, SLOT(prepareRouteList()) );
connect( &d->m_owncloudBackend, SIGNAL(removedFromCache(QString)), this, SLOT(prepareRouteList()) );
}
RouteSyncManager::~RouteSyncManager()
{
delete d;
}
void RouteSyncManager::setRoutingManager(RoutingManager *routingManager)
{
d->m_routingManager = routingManager;
}
bool RouteSyncManager::isRouteSyncEnabled() const
{
return d->m_routeSyncEnabled && d->m_cloudSyncManager && d->m_cloudSyncManager->isSyncEnabled();
}
void RouteSyncManager::setRouteSyncEnabled( bool enabled )
{
if ( d->m_routeSyncEnabled != enabled ) {
d->m_routeSyncEnabled = enabled;
emit routeSyncEnabledChanged( d->m_routeSyncEnabled );
}
}
CloudRouteModel* RouteSyncManager::model()
{
return d->m_model;
}
QString RouteSyncManager::generateTimestamp() const
{
qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
return QString::number( timestamp );
}
QString RouteSyncManager::saveDisplayedToCache() const
{
if ( !d->m_routingManager ) {
qWarning() << "RoutingManager instance not set in RouteSyncManager. Cannot save current route.";
return QString();
}
d->m_cacheDir.mkpath( d->m_cacheDir.absolutePath() );
const QString timestamp = generateTimestamp();
const QString filename = d->m_cacheDir.absolutePath() + QLatin1Char('/') + timestamp + QLatin1String(".kml");
d->m_routingManager->saveRoute( filename );
return timestamp;
}
void RouteSyncManager::uploadRoute()
{
if( !d->m_cloudSyncManager->workOffline() ) {
d->m_owncloudBackend.uploadRoute( saveDisplayedToCache() );
}
}
QVector<RouteItem> RouteSyncManager::cachedRouteList() const
{
QVector<RouteItem> routeList;
QStringList cachedRoutes = d->m_cacheDir.entryList( QStringList() << "*.kml", QDir::Files );
for ( const QString &routeFilename: cachedRoutes ) {
QFile file(d->m_cacheDir.absolutePath() + QLatin1Char('/') + routeFilename);
file.open( QFile::ReadOnly );
GeoDataParser parser( GeoData_KML );
if( !parser.read( &file ) ) {
mDebug() << QLatin1String("Could not read ") + routeFilename;
}
file.close();
QString routeName;
GeoDocument *geoDoc = parser.releaseDocument();
GeoDataDocument *container = dynamic_cast<GeoDataDocument*>( geoDoc );
if ( container && container->size() > 0 ) {
GeoDataFolder *folder = container->folderList().at( 0 );
for ( GeoDataPlacemark *placemark: folder->placemarkList() ) {
routeName += placemark->name() + QLatin1String(" - ");
}
}
routeName = routeName.left( routeName.length() - 3 );
QString timestamp = routeFilename.left( routeFilename.length() - 4 );
QString distance(QLatin1Char('0'));
QString duration(QLatin1Char('0'));
QString previewPath = QString( "%0/preview/%1.jpg" ).arg( d->m_cacheDir.absolutePath(), timestamp );
QIcon preview;
if( QFile( previewPath ).exists() ) {
preview = QIcon( previewPath );
}
// Would that work on Windows?
QUrl previewUrl( QString( "file://%0" ).arg( previewPath ) );
RouteItem item;
item.setIdentifier( timestamp );
item.setName( routeName );
item.setDistance( distance );
item.setDistance( duration );
item.setPreview( preview );
item.setPreviewUrl( previewUrl );
item.setOnCloud( false );
routeList.append( item );
}
return routeList;
}
void RouteSyncManager::uploadRoute( const QString &timestamp )
{
if( !d->m_cloudSyncManager->workOffline() ) {
d->m_owncloudBackend.uploadRoute( timestamp );
}
}
void RouteSyncManager::prepareRouteList()
{
d->m_routeList.clear();
QVector<RouteItem> cachedRoutes = cachedRouteList();
for( const RouteItem &item: cachedRoutes ) {
d->m_routeList.append( item );
}
if( !d->m_cloudSyncManager->workOffline() ) {
d->m_owncloudBackend.downloadRouteList();
} else {
// If not offline, setRouteModelItems() does this after
// appending downloaded items to the list.
d->m_model->setItems( d->m_routeList );
}
}
void RouteSyncManager::downloadRoute( const QString &timestamp )
{
d->m_owncloudBackend.downloadRoute( timestamp );
}
void RouteSyncManager::openRoute(const QString &timestamp )
{
if ( !d->m_routingManager ) {
qWarning() << "RoutingManager instance not set in RouteSyncManager. Cannot open route " << timestamp;
return;
}
d->m_routingManager->loadRoute( QString( "%0/%1.kml" )
.arg( d->m_cacheDir.absolutePath() )
.arg( timestamp ) );
}
void RouteSyncManager::deleteRoute(const QString &timestamp )
{
d->m_owncloudBackend.deleteRoute( timestamp );
}
void RouteSyncManager::removeRouteFromCache( const QString &timestamp )
{
d->m_owncloudBackend.removeFromCache( d->m_cacheDir, timestamp );
}
void RouteSyncManager::updateUploadProgressbar( qint64 sent, qint64 total )
{
emit routeUploadProgress( sent, total );
if( sent == total ) {
prepareRouteList();
}
}
void RouteSyncManager::setRouteModelItems( const QVector<RouteItem> &routeList )
{
if( d->m_routeList.count() > 0 ) {
QStringList cloudRoutes;
for( const RouteItem &item: routeList ) {
cloudRoutes.append( item.identifier() );
}
for( int position = 0; position < d->m_routeList.count(); position++ ) {
if( cloudRoutes.contains( d->m_routeList.at( position ).identifier() ) ) {
d->m_routeList[ position ].setOnCloud( true );
}
}
QStringList cachedRoutes;
for( const RouteItem &item: d->m_routeList ) {
cachedRoutes.append( item.identifier() );
}
for( const RouteItem &item: routeList ) {
if( !cachedRoutes.contains( item.identifier() ) ) {
d->m_routeList.append( item );
}
}
} else {
for( const RouteItem &item: routeList ) {
d->m_routeList.append( item );
}
}
d->m_model->setItems( d->m_routeList );
}
}
#include "moc_RouteSyncManager.cpp"
diff --git a/src/lib/marble/declarative/Bookmarks.cpp b/src/lib/marble/declarative/Bookmarks.cpp
index e82e15799..7a772c8cf 100644
--- a/src/lib/marble/declarative/Bookmarks.cpp
+++ b/src/lib/marble/declarative/Bookmarks.cpp
@@ -1,216 +1,216 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "Bookmarks.h"
#include "Planet.h"
#include "MarbleQuickItem.h"
#include "MarbleModel.h"
#include "MarblePlacemarkModel.h"
#include "BookmarkManager.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataFolder.h"
#include "GeoDataTypes.h"
#include "GeoDataExtendedData.h"
#include "GeoDataTreeModel.h"
#include "kdescendantsproxymodel.h"
#include "osm/OsmPlacemarkData.h"
#include <QSortFilterProxyModel>
namespace Marble {
Bookmarks::Bookmarks( QObject* parent ) : QObject( parent ),
- m_marbleQuickItem( 0 ), m_proxyModel( 0 )
+ m_marbleQuickItem( nullptr ), m_proxyModel( nullptr )
{
// nothing to do
}
MarbleQuickItem *Bookmarks::map()
{
return m_marbleQuickItem;
}
void Bookmarks::setMap( MarbleQuickItem* item )
{
m_marbleQuickItem = item;
if (item) {
connect(item->model()->bookmarkManager(), SIGNAL(bookmarksChanged()),
this, SLOT(updateBookmarkDocument()));
}
updateBookmarkDocument();
emit modelChanged();
}
bool Bookmarks::isBookmark( qreal longitude, qreal latitude ) const
{
if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) {
return false;
}
Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
Marble::GeoDataDocument *bookmarks = manager->document();
Marble::GeoDataCoordinates const compareTo( longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree );
qreal planetRadius = m_marbleQuickItem->model()->planet()->radius();
for( const Marble::GeoDataFolder* folder: bookmarks->folderList() ) {
for( const Marble::GeoDataPlacemark * const placemark: folder->placemarkList() ) {
if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) {
return true;
}
}
}
return false;
}
Placemark *Bookmarks::placemark(int row)
{
Placemark* placemark = new Placemark;
QModelIndex index = model()->index(row, 0);
GeoDataObject *object = model()->data(index, MarblePlacemarkModel::ObjectPointerRole ).value<GeoDataObject*>();
if (GeoDataPlacemark *geoDataPlacemark = geodata_cast<GeoDataPlacemark>(object)) {
placemark->setGeoDataPlacemark(*geoDataPlacemark);
}
return placemark;
}
void Bookmarks::addBookmark(Placemark *placemark, const QString &folderName )
{
if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) {
return;
}
Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
Marble::GeoDataDocument *bookmarks = manager->document();
- Marble::GeoDataContainer *target = 0;
+ Marble::GeoDataContainer *target = nullptr;
for( Marble::GeoDataFolder* const folder: bookmarks->folderList() ) {
if ( folder->name() == folderName ) {
target = folder;
break;
}
}
if ( !target ) {
manager->addNewBookmarkFolder( bookmarks, folderName );
for( Marble::GeoDataFolder* const folder: bookmarks->folderList() ) {
if ( folder->name() == folderName ) {
target = folder;
break;
}
}
Q_ASSERT( target );
}
Marble::GeoDataPlacemark bookmark = placemark->placemark();
if (bookmark.name().isEmpty()) {
bookmark.setName(placemark->address());
}
if (bookmark.name().isEmpty()) {
bookmark.setName(bookmark.coordinate().toString(GeoDataCoordinates::Decimal).trimmed());
}
bookmark.clearOsmData();
bookmark.setCoordinate(bookmark.coordinate()); // replace non-point geometries with their center
manager->addBookmark( target, bookmark );
}
void Bookmarks::removeBookmark( qreal longitude, qreal latitude )
{
if ( !m_marbleQuickItem || !m_marbleQuickItem->model()->bookmarkManager() ) {
return;
}
Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
Marble::GeoDataDocument *bookmarks = manager->document();
Marble::GeoDataCoordinates const compareTo( longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree );
qreal planetRadius = m_marbleQuickItem->model()->planet()->radius();
for( const Marble::GeoDataFolder* folder: bookmarks->folderList() ) {
for( Marble::GeoDataPlacemark * placemark: folder->placemarkList() ) {
if (placemark->coordinate().sphericalDistanceTo(compareTo) * planetRadius < 5) {
manager->removeBookmark( placemark );
return;
}
}
}
}
void Bookmarks::updateBookmarkDocument()
{
if (m_marbleQuickItem) {
Marble::BookmarkManager* manager = m_marbleQuickItem->model()->bookmarkManager();
m_treeModel.setRootDocument( manager->document() );
}
}
BookmarksModel *Bookmarks::model()
{
if ( !m_proxyModel && m_marbleQuickItem && m_marbleQuickItem->model()->bookmarkManager() ) {
KDescendantsProxyModel* flattener = new KDescendantsProxyModel( this );
flattener->setSourceModel(&m_treeModel);
m_proxyModel = new BookmarksModel( this );
m_proxyModel->setFilterFixedString( Marble::GeoDataTypes::GeoDataPlacemarkType );
m_proxyModel->setFilterKeyColumn( 1 );
m_proxyModel->setSourceModel( flattener );
}
return m_proxyModel;
}
BookmarksModel::BookmarksModel( QObject *parent ) : QSortFilterProxyModel( parent )
{
connect( this, SIGNAL(layoutChanged()), this, SIGNAL(countChanged()) );
connect( this, SIGNAL(modelReset()), this, SIGNAL(countChanged()) );
connect( this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged()) );
connect( this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged()) );
}
int BookmarksModel::count() const
{
return rowCount();
}
qreal BookmarksModel::longitude( int idx ) const
{
if ( idx >= 0 && idx < rowCount() ) {
QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole );
Marble::GeoDataCoordinates const coordinates = value.value<Marble::GeoDataCoordinates>();
return coordinates.longitude( Marble::GeoDataCoordinates::Degree );
}
return 0.0;
}
qreal BookmarksModel::latitude( int idx ) const
{
if ( idx >= 0 && idx < rowCount() ) {
QVariant const value = data( index( idx, 0 ), Marble::MarblePlacemarkModel::CoordinateRole );
Marble::GeoDataCoordinates const coordinates = value.value<Marble::GeoDataCoordinates>();
return coordinates.latitude( Marble::GeoDataCoordinates::Degree );
}
return 0.0;
}
QString BookmarksModel::name( int idx ) const
{
if ( idx >= 0 && idx < rowCount() ) {
return data( index( idx, 0 ) ).toString();
}
return QString();
}
}
#include "moc_Bookmarks.cpp"
diff --git a/src/lib/marble/declarative/Bookmarks.h b/src/lib/marble/declarative/Bookmarks.h
index ef5c63c66..6eb56d13b 100644
--- a/src/lib/marble/declarative/Bookmarks.h
+++ b/src/lib/marble/declarative/Bookmarks.h
@@ -1,82 +1,82 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_BOOKMARKS_H
#define MARBLE_DECLARATIVE_BOOKMARKS_H
#include <QObject>
#include <QSortFilterProxyModel>
#include <GeoDataTreeModel.h>
#include "Placemark.h"
namespace Marble {
class MarbleQuickItem;
class BookmarksModel: public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY( int count READ count NOTIFY countChanged )
public:
- explicit BookmarksModel( QObject *parent = 0 );
+ explicit BookmarksModel( QObject *parent = nullptr );
int count() const;
public Q_SLOTS:
qreal longitude( int index ) const;
qreal latitude( int index ) const;
QString name( int index ) const;
Q_SIGNALS:
void countChanged();
};
class Bookmarks : public QObject
{
Q_OBJECT
Q_PROPERTY( Marble::MarbleQuickItem* map READ map WRITE setMap NOTIFY mapChanged)
Q_PROPERTY( BookmarksModel* model READ model NOTIFY modelChanged )
public:
- explicit Bookmarks( QObject* parent = 0 );
+ explicit Bookmarks( QObject* parent = nullptr );
MarbleQuickItem* map();
void setMap(MarbleQuickItem *widget );
BookmarksModel* model();
Q_INVOKABLE bool isBookmark( qreal longitude, qreal latitude ) const;
Q_INVOKABLE Placemark* placemark(int index);
public Q_SLOTS:
void addBookmark(Placemark *placemark, const QString &folder );
void removeBookmark( qreal longitude, qreal latitude );
void updateBookmarkDocument();
Q_SIGNALS:
void mapChanged();
void modelChanged();
private:
MarbleQuickItem* m_marbleQuickItem;
BookmarksModel* m_proxyModel;
GeoDataTreeModel m_treeModel;
};
}
#endif
diff --git a/src/lib/marble/declarative/Coordinate.h b/src/lib/marble/declarative/Coordinate.h
index 7f9f66cbc..9c57ed55c 100644
--- a/src/lib/marble/declarative/Coordinate.h
+++ b/src/lib/marble/declarative/Coordinate.h
@@ -1,81 +1,81 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_COORDINATE_H
#define MARBLE_DECLARATIVE_COORDINATE_H
#include "GeoDataCoordinates.h"
#include <QObject>
#include <QtQml>
/**
* Represents a coordinate with the properties of a name and coordinates
*
* @todo: Introduce GeoDataCoordinates
*/
class Coordinate : public QObject
{
Q_OBJECT
Q_PROPERTY( qreal longitude READ longitude WRITE setLongitude NOTIFY longitudeChanged )
Q_PROPERTY( qreal latitude READ latitude WRITE setLatitude NOTIFY latitudeChanged )
Q_PROPERTY( qreal altitude READ altitude WRITE setAltitude NOTIFY altitudeChanged )
public:
/** Constructor */
- explicit Coordinate( qreal lon = 0.0, qreal lat = 0.0, qreal altitude = 0.0, QObject *parent = 0 );
+ explicit Coordinate( qreal lon = 0.0, qreal lat = 0.0, qreal altitude = 0.0, QObject *parent = nullptr );
explicit Coordinate( const Marble::GeoDataCoordinates & coordinates );
/** Provides access to the longitude (degree) of the coordinate */
qreal longitude() const;
/** Change the longitude of the coordinate */
void setLongitude( qreal lon );
/** Provides access to the latitude (degree) of the coordinate */
qreal latitude() const;
/** Change the latitude of the coordinate */
void setLatitude( qreal lat );
/** Provides access to the altitude (meters) of the coordinate */
qreal altitude() const;
/** Change the altitude of the coordinate */
void setAltitude( qreal alt );
/** Change the altitude of the coordinate */
Marble::GeoDataCoordinates coordinates() const;
/** Change all coordinates at once */
void setCoordinates( const Marble::GeoDataCoordinates &coordinates );
/** Distance (in meter) to the given coordinate */
Q_INVOKABLE qreal distance( qreal longitude, qreal latitude ) const;
/** Bearing (in degree) to the given coordinate */
Q_INVOKABLE qreal bearing( qreal longitude, qreal latitude ) const;
bool operator == ( const Coordinate &other ) const;
bool operator != ( const Coordinate &other ) const;
Q_SIGNALS:
void longitudeChanged();
void latitudeChanged();
void altitudeChanged();
private:
Marble::GeoDataCoordinates m_coordinate;
};
QML_DECLARE_TYPE( Coordinate )
#endif // MARBLE_DECLARATIVE_COORDINATE_H
diff --git a/src/lib/marble/declarative/DeclarativeMapThemeManager.h b/src/lib/marble/declarative/DeclarativeMapThemeManager.h
index af28e2b6e..c8134b494 100644
--- a/src/lib/marble/declarative/DeclarativeMapThemeManager.h
+++ b/src/lib/marble/declarative/DeclarativeMapThemeManager.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef DECLARATIVE_MAPTHEMEMANAGER_H
#define DECLARATIVE_MAPTHEMEMANAGER_H
#include "MapThemeManager.h"
#include <QQuickImageProvider>
class MapThemeImageProvider : public QQuickImageProvider
{
public:
MapThemeImageProvider();
QPixmap requestPixmap( const QString &id, QSize *size, const QSize &requestedSize ) override;
private:
/** @todo FIXME It is a bit ugly to keep a separate object that loads all themes again
* just to provide their images to QML. The API change before Qt 4.7 made this necessary
* however (it's not possible anymore to assign a QPixmap property to QML images) */
Marble::MapThemeManager m_mapThemeManager;
};
/**
* Provides access to all map themes installed locally
*/
class MapThemeManager : public QObject
{
Q_OBJECT
public:
/** Constructor. Map themes are loaded later on demand. */
- explicit MapThemeManager( QObject *parent = 0 );
+ explicit MapThemeManager( QObject *parent = nullptr );
/**
* A list of all installed map theme ids, each entry has the form
* "planet/themeid/themeid.dgml", e.g. "earth/bluemarble/bluemarble.dgml"
*/
QStringList mapThemeIds() const;
private:
/** Marble map theme manager doing the real work */
Marble::MapThemeManager m_mapThemeManager;
};
#endif // DECLARATIVE_MAPTHEMEMANAGER_H
diff --git a/src/lib/marble/declarative/MapThemeModel.h b/src/lib/marble/declarative/MapThemeModel.h
index 88baa0c7d..b3da0eba4 100644
--- a/src/lib/marble/declarative/MapThemeModel.h
+++ b/src/lib/marble/declarative/MapThemeModel.h
@@ -1,78 +1,78 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_STREETMAPTHEMEMODEL_H
#define MARBLE_DECLARATIVE_STREETMAPTHEMEMODEL_H
#include <QSortFilterProxyModel>
namespace Marble { class MapThemeManager; }
class MapThemeModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY( int count READ count NOTIFY countChanged )
public:
enum MapThemeFilter {
AnyTheme = 0x0,
Terrestrial = 0x1,
Extraterrestrial = 0x2,
LowZoom = 0x4,
HighZoom = 0x8
};
Q_DECLARE_FLAGS(MapThemeFilters, MapThemeFilter)
Q_FLAGS(MapThemeFilter MapThemeFilters)
Q_PROPERTY( MapThemeFilters mapThemeFilter READ mapThemeFilter WRITE setMapThemeFilter NOTIFY mapThemeFilterChanged )
public:
- explicit MapThemeModel( QObject* parent = 0 );
+ explicit MapThemeModel( QObject* parent = nullptr );
/** @todo FIXME https://bugreports.qt-project.org/browse/QTCOMPONENTS-1206 */
int count() const;
QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE QString name( const QString &id ) const;
Q_INVOKABLE int indexOf( const QString &id ) const;
Q_INVOKABLE MapThemeFilters mapThemeFilter() const;
public Q_SLOTS:
void setMapThemeFilter( MapThemeFilters filters );
Q_SIGNALS:
void countChanged();
void mapThemeFilterChanged();
protected:
bool filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const override;
private Q_SLOTS:
void handleChangedThemes();
private:
Marble::MapThemeManager* m_themeManager;
QList<QString> m_streetMapThemeIds;
MapThemeFilters m_mapThemeFilters;
QHash<int, QByteArray> m_roleNames;
};
#endif
diff --git a/src/lib/marble/declarative/MarbleDeclarativeObject.h b/src/lib/marble/declarative/MarbleDeclarativeObject.h
index f3661cc55..0a50ae407 100644
--- a/src/lib/marble/declarative/MarbleDeclarativeObject.h
+++ b/src/lib/marble/declarative/MarbleDeclarativeObject.h
@@ -1,59 +1,59 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_OBJECT_H
#define MARBLE_DECLARATIVE_OBJECT_H
#include <QObject>
class MarbleDeclarativeObjectPrivate;
/**
* Provides access to global Marble related properties and methods
* to QML (intended to be registered as a global QML object)
*/
class MarbleDeclarativeObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString version READ version CONSTANT)
public:
- explicit MarbleDeclarativeObject( QObject* parent = 0 );
+ explicit MarbleDeclarativeObject( QObject* parent = nullptr );
~MarbleDeclarativeObject() override;
/** Returns the Marble library version */
QString version() const;
public Q_SLOTS:
/**
* @brief resolvePath Resolves files in the marble data path
* @param path Relative path to a file installed in Marble's data path
* @return The absolute path to the given file, or an empty string if the
* relative path cannot be resolved
* @see #MarbleDirs
*/
QString resolvePath( const QString &path ) const;
/**
* @brief canExecute Check whether a given program is found in the path
* @param program The name of the program
* @return Returns true iff the given program is found in one of
* directories defined by the PATH environment variable (as reported by
* QProcessEnvironment) and has the executable bit set
*/
bool canExecute( const QString &program ) const;
private:
MarbleDeclarativeObjectPrivate* const d;
};
#endif
diff --git a/src/lib/marble/declarative/MarbleQuickItem.h b/src/lib/marble/declarative/MarbleQuickItem.h
index d013a1cdc..28be60d6c 100644
--- a/src/lib/marble/declarative/MarbleQuickItem.h
+++ b/src/lib/marble/declarative/MarbleQuickItem.h
@@ -1,251 +1,251 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Adam Dabrowski <adabrowski@piap.pl> <adamdbrw@gmail.com>
//
#ifndef MARBLEQUICKITEM_H
#define MARBLEQUICKITEM_H
#include "marble_declarative_export.h"
#include <QSharedPointer>
#include <QQuickPaintedItem>
#include "GeoDataAccuracy.h"
#include "MarbleGlobal.h"
#include "PositionProviderPluginInterface.h"
#include "MarbleMap.h"
#include "Placemark.h"
#include "Coordinate.h"
namespace Marble
{
class GeoDataLatLonBox;
class GeoDataPlacemark;
class MarbleModel;
class MarbleInputHandler;
class MarbleQuickItemPrivate;
//Class is still being developed
class MARBLE_DECLARATIVE_EXPORT MarbleQuickItem : public QQuickPaintedItem
{
Q_OBJECT
Q_ENUMS(Projection)
Q_PROPERTY(int mapWidth READ mapWidth WRITE setMapWidth NOTIFY mapWidthChanged)
Q_PROPERTY(int mapHeight READ mapHeight WRITE setMapHeight NOTIFY mapHeightChanged)
Q_PROPERTY(int zoom READ zoom WRITE setZoom NOTIFY zoomChanged)
Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged)
Q_PROPERTY(bool showFrameRate READ showFrameRate WRITE setShowFrameRate NOTIFY showFrameRateChanged)
Q_PROPERTY(Projection projection READ projection WRITE setProjection NOTIFY projectionChanged)
Q_PROPERTY(QString mapThemeId READ mapThemeId WRITE setMapThemeId NOTIFY mapThemeIdChanged)
Q_PROPERTY(bool showAtmosphere READ showAtmosphere WRITE setShowAtmosphere NOTIFY showAtmosphereChanged)
Q_PROPERTY(bool showCompass READ showCompass WRITE setShowCompass NOTIFY showCompassChanged)
Q_PROPERTY(bool showClouds READ showClouds WRITE setShowClouds NOTIFY showCloudsChanged)
Q_PROPERTY(bool showCrosshairs READ showCrosshairs WRITE setShowCrosshairs NOTIFY showCrosshairsChanged)
Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid NOTIFY showGridChanged)
Q_PROPERTY(bool showOverviewMap READ showOverviewMap WRITE setShowOverviewMap NOTIFY showOverviewMapChanged)
Q_PROPERTY(bool showOtherPlaces READ showOtherPlaces WRITE setShowOtherPlaces NOTIFY showOtherPlacesChanged)
Q_PROPERTY(bool showScaleBar READ showScaleBar WRITE setShowScaleBar NOTIFY showScaleBarChanged)
Q_PROPERTY(bool showBackground READ showBackground WRITE setShowBackground NOTIFY showBackgroundChanged)
Q_PROPERTY(bool showPositionMarker READ showPositionMarker WRITE setShowPositionMarker NOTIFY showPositionMarkerChanged)
Q_PROPERTY(bool showPublicTransport READ showPublicTransport WRITE setShowPublicTransport NOTIFY showPublicTransportChanged)
Q_PROPERTY(bool showOutdoorActivities READ showOutdoorActivities WRITE setShowOutdoorActivities NOTIFY showOutdoorActivitiesChanged)
Q_PROPERTY(QString positionProvider READ positionProvider WRITE setPositionProvider NOTIFY positionProviderChanged)
Q_PROPERTY(bool positionAvailable READ positionAvailable NOTIFY positionAvailableChanged)
Q_PROPERTY(bool positionVisible READ positionVisible NOTIFY positionVisibleChanged)
Q_PROPERTY(MarbleMap* marbleMap READ map NOTIFY marbleMapChanged)
Q_PROPERTY(Placemark* currentPosition READ currentPosition NOTIFY currentPositionChanged)
Q_PROPERTY(qreal speed READ speed NOTIFY speedChanged)
Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged)
Q_PROPERTY(bool inertialGlobeRotation READ inertialGlobeRotation WRITE setInertialGlobeRotation NOTIFY inertialGlobeRotationChanged)
Q_PROPERTY(bool animationViewContext READ animationViewContext WRITE setAnimationViewContext NOTIFY animationViewContextChanged)
Q_PROPERTY(QQmlComponent* placemarkDelegate READ placemarkDelegate WRITE setPlacemarkDelegate NOTIFY placemarkDelegateChanged)
public:
- explicit MarbleQuickItem(QQuickItem *parent = 0);
+ explicit MarbleQuickItem(QQuickItem *parent = nullptr);
enum Projection{
Spherical = Marble::Spherical,
Equirectangular = Marble::Equirectangular,
Mercator = Marble::Mercator,
Gnomonic = Marble::Gnomonic,
Stereographic = Marble::Stereographic,
LambertAzimuthal = Marble::LambertAzimuthal,
AzimuthalEquidistant = Marble::AzimuthalEquidistant,
VerticalPerspective = Marble::VerticalPerspective
};
MarbleInputHandler *inputHandler();
int zoom() const;
int radius() const;
public Q_SLOTS:
void goHome();
void setZoom(int zoom, FlyToMode mode = Instant);
Q_INVOKABLE void setZoomToMaximumLevel();
void setRadius(int radius);
void centerOn(const GeoDataPlacemark& placemark, bool animated = false);
void centerOn(const GeoDataLatLonBox& box, bool animated = false);
void centerOn(const GeoDataCoordinates& coordinate);
void centerOn(qreal longitude, qreal latitude);
Q_INVOKABLE void centerOnCoordinates(qreal longitude, qreal latitude);
Q_INVOKABLE void centerOnCurrentPosition();
Q_INVOKABLE void selectPlacemarkAt(int x, int y);
void zoomIn(FlyToMode mode = Automatic);
void zoomOut(FlyToMode mode = Automatic);
Q_INVOKABLE void handlePinchStarted(const QPointF &point);
Q_INVOKABLE void handlePinchFinished(const QPointF &point);
Q_INVOKABLE void handlePinchUpdated(const QPointF &point, qreal scale);
void setMapWidth(int mapWidth);
void setMapHeight(int mapHeight);
void setShowFrameRate(bool showFrameRate);
void setProjection(Projection projection);
void setMapThemeId(const QString& mapThemeId);
void setShowAtmosphere(bool showAtmosphere);
void setShowCompass(bool showCompass);
void setShowClouds(bool showClouds);
void setShowCrosshairs(bool showCrosshairs);
void setShowGrid(bool showGrid);
void setShowOverviewMap(bool showOverviewMap);
void setShowOtherPlaces(bool showOtherPlaces);
void setShowScaleBar(bool showScaleBar);
void setShowBackground(bool showBackground);
void setShowPositionMarker(bool showPositionMarker);
void setShowPublicTransport(bool showPublicTransport);
void setShowOutdoorActivities(bool showOutdoorActivities);
void setPositionProvider(const QString & positionProvider);
void setInertialGlobeRotation(bool inertialGlobeRotation);
void setAnimationViewContext(bool animationViewContext);
void setPluginSetting(const QString &plugin, const QString &key, const QString &value);
void setPropertyEnabled(const QString &property, bool enabled);
bool isPropertyEnabled(const QString &property) const;
Q_INVOKABLE void setShowRuntimeTrace(bool showRuntimeTrace);
Q_INVOKABLE void setShowDebugPolygons(bool showDebugPolygons);
Q_INVOKABLE void setShowDebugPlacemarks(bool showDebugPlacemarks);
Q_INVOKABLE void setShowDebugBatches(bool showDebugBatches);
void setPlacemarkDelegate(QQmlComponent* placemarkDelegate);
Q_INVOKABLE void loadSettings();
Q_INVOKABLE void writeSettings();
Q_INVOKABLE void reloadTiles();
Q_INVOKABLE void highlightRouteRelation(qint64 osmId, bool enabled);
Q_INVOKABLE void setRelationTypeVisible(const QString &relationType, bool visible);
Q_INVOKABLE bool isRelationTypeVisible(const QString &relationType) const;
public:
void paint(QPainter *painter) override;
// QQmlParserStatus interface
public:
void classBegin() override;
void componentComplete() override;
public:
virtual bool layersEventFilter(QObject *o, QEvent *e);
int mapWidth() const;
int mapHeight() const;
bool showFrameRate() const;
Projection projection() const;
QString mapThemeId() const;
bool showAtmosphere() const;
bool showCompass() const;
bool showClouds() const;
bool showCrosshairs() const;
bool showGrid() const;
bool showOverviewMap() const;
bool showOtherPlaces() const;
bool showScaleBar() const;
bool showBackground() const;
bool showPositionMarker() const;
bool showPublicTransport() const;
bool showOutdoorActivities() const;
QString positionProvider() const;
bool positionAvailable() const;
bool positionVisible() const;
Q_INVOKABLE qreal distanceFromPointToCurrentLocation(const QPoint & position) const;
Q_INVOKABLE qreal angleFromPointToCurrentLocation(const QPoint & position) const;
Placemark* currentPosition() const;
Q_INVOKABLE QPointF screenCoordinatesFromCoordinate(Coordinate * coordinate) const;
qreal speed() const;
qreal angle() const;
MarbleModel* model();
const MarbleModel* model() const;
MarbleMap* map();
const MarbleMap* map() const;
bool inertialGlobeRotation() const;
bool animationViewContext() const;
QQmlComponent* placemarkDelegate() const;
void reverseGeocoding(const QPoint &point);
Q_SIGNALS:
void mapWidthChanged(int mapWidth);
void mapHeightChanged(int mapHeight);
void showFrameRateChanged(bool showFrameRate);
void projectionChanged(Projection projection);
void mapThemeIdChanged(const QString& mapThemeId);
void showAtmosphereChanged(bool showAtmosphere);
void showCompassChanged(bool showCompass);
void showCloudsChanged(bool showClouds);
void showCrosshairsChanged(bool showCrosshairs);
void showGridChanged(bool showGrid);
void showOverviewMapChanged(bool showOverviewMap);
void showOtherPlacesChanged(bool showOtherPlaces);
void showScaleBarChanged(bool showScaleBar);
void showBackgroundChanged(bool showBackground);
void showPositionMarkerChanged(bool showPositionMarker);
void showPublicTransportChanged(bool showPublicTransport);
void showOutdoorActivitiesChanged(bool showOutdoorActivities);
void positionProviderChanged(const QString & positionProvider);
void positionAvailableChanged(bool positionAvailable);
void positionVisibleChanged(bool positionVisible);
void marbleMapChanged();
void visibleLatLonAltBoxChanged();
void currentPositionChanged(Placemark* currentPosition);
void angleChanged();
void speedChanged();
void zoomChanged();
void radiusChanged(int radius);
void inertialGlobeRotationChanged(bool inertialGlobeRotation);
void animationViewContextChanged(bool animationViewContext);
void placemarkDelegateChanged(QQmlComponent* placemarkDelegate);
protected:
QObject *getEventFilter() const;
void pinch(const QPointF& center, qreal scale, Qt::GestureState state);
private Q_SLOTS:
void resizeMap();
void positionDataStatusChanged(PositionProviderStatus status);
void positionChanged(const GeoDataCoordinates &, GeoDataAccuracy);
void updatePositionVisibility();
void updateCurrentPosition(const GeoDataCoordinates & coordinates);
void updatePlacemarks();
void handleReverseGeocoding(const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark);
private:
typedef QSharedPointer<MarbleQuickItemPrivate> MarbleQuickItemPrivatePtr;
MarbleQuickItemPrivatePtr d;
friend class MarbleQuickItemPrivate;
};
}
#endif // MARBLEQUICKITEM_H
diff --git a/src/lib/marble/declarative/Navigation.cpp b/src/lib/marble/declarative/Navigation.cpp
index 3b34af06a..bd663fbc8 100644
--- a/src/lib/marble/declarative/Navigation.cpp
+++ b/src/lib/marble/declarative/Navigation.cpp
@@ -1,354 +1,354 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "Navigation.h"
#include "Planet.h"
#include "MarbleModel.h"
#include "MarbleQuickItem.h"
#include "routing/Route.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingModel.h"
#include "PositionTracking.h"
#include "AutoNavigation.h"
#include "routing/VoiceNavigationModel.h"
#include "ViewportParams.h"
#include "GeoDataAccuracy.h"
namespace Marble {
class NavigationPrivate
{
public:
NavigationPrivate();
MarbleQuickItem * m_marbleQuickItem;
bool m_muted;
RouteSegment m_currentSegment;
AutoNavigation* m_autoNavigation;
VoiceNavigationModel m_voiceNavigation;
qreal m_nextInstructionDistance;
qreal m_destinationDistance;
double m_screenAccuracy;
QPointF m_screenPosition;
RouteSegment nextRouteSegment() const;
void updateNextInstructionDistance( const Route &route );
MarbleModel * model() const;
QPointF positionOnRoute() const;
QPointF currentPosition() const;
RouteSegment m_secondLastSegment;
RouteSegment m_lastSegment;
};
NavigationPrivate::NavigationPrivate() :
- m_marbleQuickItem( nullptr ), m_muted( false ), m_autoNavigation( 0 ), m_nextInstructionDistance( 0.0 ),
+ m_marbleQuickItem( nullptr ), m_muted( false ), m_autoNavigation( nullptr ), m_nextInstructionDistance( 0.0 ),
m_destinationDistance( 0.0 ), m_screenAccuracy(0)
{
// nothing to do
}
void NavigationPrivate::updateNextInstructionDistance( const Route &route )
{
const GeoDataCoordinates position = route.position();
const GeoDataCoordinates interpolated = route.positionOnRoute();
const GeoDataCoordinates onRoute = route.currentWaypoint();
qreal planetRadius = 0;
if (model()){
planetRadius = model()->planet()->radius();
}
qreal distance = planetRadius * (position.sphericalDistanceTo(interpolated) + interpolated.sphericalDistanceTo(onRoute));
qreal remaining = 0.0;
const RouteSegment &segment = route.currentSegment();
for ( int i=0; i<segment.path().size(); ++i ) {
if ( segment.path()[i] == onRoute ) {
distance += segment.path().length( planetRadius, i );
break;
}
}
bool upcoming = false;
for ( int i=0; i<route.size(); ++i ) {
const RouteSegment &segment = route.at( i );
if ( upcoming ) {
remaining += segment.path().length( planetRadius );
}
if ( segment == route.currentSegment() ) {
upcoming = true;
}
}
m_nextInstructionDistance = distance;
m_destinationDistance = distance + remaining;
}
MarbleModel * NavigationPrivate::model() const
{
return m_marbleQuickItem ? m_marbleQuickItem->model() : nullptr;
}
RouteSegment NavigationPrivate::nextRouteSegment() const
{
// Not using m_currentSegment on purpose
return m_marbleQuickItem ? model()->routingManager()->routingModel()->route().currentSegment().nextRouteSegment() : RouteSegment();
}
Navigation::Navigation( QObject* parent) :
QObject( parent ), d( new NavigationPrivate )
{
connect( &d->m_voiceNavigation, SIGNAL(instructionChanged()), this, SIGNAL(voiceNavigationAnnouncementChanged()) );
}
Navigation::~Navigation()
{
delete d;
}
bool Navigation::guidanceModeEnabled() const
{
return d->m_marbleQuickItem ? d->model()->routingManager()->guidanceModeEnabled() : false;
}
void Navigation::setGuidanceModeEnabled( bool enabled )
{
if ( d->m_marbleQuickItem ) {
d->model()->routingManager()->setGuidanceModeEnabled( enabled );
d->m_autoNavigation->setAutoZoom( enabled );
d->m_autoNavigation->setRecenter( enabled ? AutoNavigation::RecenterOnBorder : AutoNavigation::DontRecenter );
if ( enabled && !d->m_muted ) {
//d->m_audio.announceStart();
}
}
}
bool Navigation::muted() const
{
return d->m_muted;
}
void Navigation::setMuted(bool enabled)
{
d->m_muted = enabled;
}
QString Navigation::nextInstructionText() const
{
return d->nextRouteSegment().maneuver().instructionText();
}
QString Navigation::nextRoad() const
{
return d->nextRouteSegment().maneuver().roadName();
}
QString Navigation::nextInstructionImage() const
{
switch ( d->nextRouteSegment().maneuver().direction() ) {
case Maneuver::Continue: return QStringLiteral("qrc:/marble/turn-continue.svg");
case Maneuver::Merge: return QStringLiteral("qrc:/marble/turn-merge.svg");
case Maneuver::Straight: return QStringLiteral("qrc:/marble/turn-continue.svg");
case Maneuver::SlightRight: return QStringLiteral("qrc:/marble/turn-slight-right.svg");
case Maneuver::Right: return QStringLiteral("qrc:/marble/turn-right.svg");
case Maneuver::SharpRight: return QStringLiteral("qrc:/marble/turn-sharp-right.svg");
case Maneuver::TurnAround: return QStringLiteral("qrc:/marble/turn-around.svg");
case Maneuver::SharpLeft: return QStringLiteral("qrc:/marble/turn-sharp-left.svg");
case Maneuver::Left: return QStringLiteral("qrc:/marble/turn-left.svg");
case Maneuver::SlightLeft: return QStringLiteral("qrc:/marble/turn-slight-left.svg");
case Maneuver::RoundaboutFirstExit: return QStringLiteral("qrc:/marble/turn-roundabout-first.svg");
case Maneuver::RoundaboutSecondExit: return QStringLiteral("qrc:/marble/turn-roundabout-second.svg");
case Maneuver::RoundaboutThirdExit: return QStringLiteral("qrc:/marble/turn-roundabout-third.svg");
case Maneuver::RoundaboutExit: return QStringLiteral("qrc:/marble/turn-roundabout-far.svg");
case Maneuver::ExitLeft: return QStringLiteral("qrc:/marble/turn-exit-left.svg");
case Maneuver::ExitRight: return QStringLiteral("qrc:/marble/turn-exit-right.svg");
case Maneuver::Unknown:
default:
return QString();
}
}
qreal Navigation::nextInstructionDistance() const
{
return d->m_nextInstructionDistance;
}
qreal Navigation::destinationDistance() const
{
return d->m_destinationDistance;
}
QString Navigation::voiceNavigationAnnouncement() const
{
return d->m_voiceNavigation.instruction();
}
QString Navigation::speaker() const
{
return d->m_voiceNavigation.speaker();
}
void Navigation::setSpeaker( const QString &speaker )
{
d->m_voiceNavigation.setSpeaker( speaker );
}
bool Navigation::deviated() const
{
if ( d->m_marbleQuickItem ) {
RoutingModel const * routingModel = d->model()->routingManager()->routingModel();
return routingModel->deviatedFromRoute();
}
return true;
}
MarbleQuickItem *Navigation::marbleQuickItem() const
{
return d->m_marbleQuickItem;
}
QPointF NavigationPrivate::positionOnRoute() const
{
RoutingModel const * routingModel = model()->routingManager()->routingModel();
GeoDataCoordinates coordinates = routingModel->route().positionOnRoute();
qreal x = 0;
qreal y = 0;
if (coordinates.isValid()) {
m_marbleQuickItem->map()->viewport()->screenCoordinates(coordinates, x, y);
}
return QPointF(x,y);
}
QPointF NavigationPrivate::currentPosition() const
{
GeoDataCoordinates coordinates = model()->positionTracking()->currentLocation();
qreal x = 0;
qreal y = 0;
m_marbleQuickItem->map()->viewport()->screenCoordinates(coordinates, x, y);
return QPointF(x,y);
}
QPointF Navigation::screenPosition() const
{
return d->m_screenPosition;
}
double Navigation::screenAccuracy() const
{
return d->m_screenAccuracy;
}
void Navigation::setMarbleQuickItem(MarbleQuickItem *marbleQuickItem)
{
if ( d->m_marbleQuickItem == marbleQuickItem) {
return;
}
if (d->m_marbleQuickItem) {
disconnect( d->model()->routingManager()->routingModel(),
SIGNAL(positionChanged()), this, SLOT(update()) );
disconnect( d->m_autoNavigation, SIGNAL(zoomIn(FlyToMode)),
d->m_marbleQuickItem, SLOT(zoomIn()) );
disconnect( d->m_autoNavigation, SIGNAL(zoomOut(FlyToMode)),
d->m_marbleQuickItem, SLOT(zoomOut()) );
disconnect( d->m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates,bool)),
d->m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)) );
disconnect( d->m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()),
d->m_autoNavigation, SLOT(inhibitAutoAdjustments()) );
}
d->m_marbleQuickItem = marbleQuickItem;
if ( d->m_marbleQuickItem ) {
d->model()->routingManager()->setShowGuidanceModeStartupWarning( false );
connect( d->model()->routingManager()->routingModel(),
SIGNAL(positionChanged()), this, SLOT(update()) );
connect( d->model()->routingManager()->routingModel(),
SIGNAL(deviatedFromRoute(bool)), this, SIGNAL(deviationChanged()) );
delete d->m_autoNavigation;
d->m_autoNavigation = new AutoNavigation( d->model(), d->m_marbleQuickItem->map()->viewport(), this );
connect( d->m_autoNavigation, SIGNAL(zoomIn(FlyToMode)),
d->m_marbleQuickItem, SLOT(zoomIn()) );
connect( d->m_autoNavigation, SIGNAL(zoomOut(FlyToMode)),
d->m_marbleQuickItem, SLOT(zoomOut()) );
connect( d->m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates,bool)),
d->m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)) );
connect( d->m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()),
d->m_autoNavigation, SLOT(inhibitAutoAdjustments()) );
connect( d->m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()),
this, SLOT(updateScreenPosition()) );
connect( d->model()->positionTracking(), SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
this, SLOT(updateScreenPosition()) );
connect( d->model()->positionTracking(), SIGNAL(statusChanged(PositionProviderStatus)),
this, SLOT(updateScreenPosition()) );
}
emit marbleQuickItemChanged(marbleQuickItem);
}
void Navigation::update()
{
if (!d->model()) {
return;
}
RoutingModel const * routingModel = d->model()->routingManager()->routingModel();
d->updateNextInstructionDistance( routingModel->route() );
emit nextInstructionDistanceChanged();
emit destinationDistanceChanged();
RouteSegment segment = routingModel->route().currentSegment();
if ( !d->m_muted ) {
d->m_voiceNavigation.update( routingModel->route(), d->m_nextInstructionDistance, d->m_destinationDistance, routingModel->deviatedFromRoute() );
}
if ( segment != d->m_currentSegment ) {
d->m_currentSegment = segment;
emit nextInstructionTextChanged();
emit nextInstructionImageChanged();
emit nextRoadChanged();
}
updateScreenPosition();
}
void Navigation::updateScreenPosition()
{
if(d->m_marbleQuickItem) {
double distanceMeter = d->model()->positionTracking()->accuracy().horizontal;
d->m_screenAccuracy = distanceMeter * d->m_marbleQuickItem->map()->radius() / d->model()->planetRadius();
emit screenAccuracyChanged();
d->m_screenPosition = deviated() ? d->currentPosition() : d->positionOnRoute();
emit screenPositionChanged();
}
}
}
#include "moc_Navigation.cpp"
diff --git a/src/lib/marble/declarative/Navigation.h b/src/lib/marble/declarative/Navigation.h
index 144774c5d..e82d8de43 100644
--- a/src/lib/marble/declarative/Navigation.h
+++ b/src/lib/marble/declarative/Navigation.h
@@ -1,120 +1,120 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_NAVIGATION_H
#define MARBLE_DECLARATIVE_NAVIGATION_H
#include <QObject>
#include <QtQml>
namespace Marble {
class MarbleQuickItem;
class NavigationPrivate;
class Navigation : public QObject
{
Q_OBJECT
Q_PROPERTY(Marble::MarbleQuickItem * marbleQuickItem READ marbleQuickItem WRITE setMarbleQuickItem NOTIFY marbleQuickItemChanged)
Q_PROPERTY(bool guidanceModeEnabled READ guidanceModeEnabled WRITE setGuidanceModeEnabled NOTIFY guidanceModeEnabledChanged)
Q_PROPERTY(bool muted READ muted WRITE setMuted NOTIFY mutedChanged)
Q_PROPERTY(QString speaker READ speaker WRITE setSpeaker NOTIFY speakerChanged)
Q_PROPERTY(QString nextInstructionText READ nextInstructionText NOTIFY nextInstructionTextChanged)
Q_PROPERTY(QString nextRoad READ nextRoad NOTIFY nextRoadChanged)
Q_PROPERTY(QString nextInstructionImage READ nextInstructionImage NOTIFY nextInstructionImageChanged)
Q_PROPERTY(qreal nextInstructionDistance READ nextInstructionDistance NOTIFY nextInstructionDistanceChanged)
Q_PROPERTY(qreal destinationDistance READ destinationDistance NOTIFY destinationDistanceChanged)
Q_PROPERTY(QString voiceNavigationAnnouncement READ voiceNavigationAnnouncement NOTIFY voiceNavigationAnnouncementChanged)
Q_PROPERTY(bool deviated READ deviated NOTIFY deviationChanged)
Q_PROPERTY(double screenAccuracy READ screenAccuracy NOTIFY screenAccuracyChanged)
Q_PROPERTY(QPointF screenPosition READ screenPosition NOTIFY screenPositionChanged)
public:
- explicit Navigation( QObject* parent = 0 );
+ explicit Navigation( QObject* parent = nullptr );
~Navigation() override;
bool guidanceModeEnabled() const;
void setGuidanceModeEnabled( bool enabled );
bool muted() const;
void setMuted(bool enabled);
QString nextInstructionText() const;
QString nextRoad() const;
QString nextInstructionImage() const;
qreal nextInstructionDistance() const;
qreal destinationDistance() const;
QString voiceNavigationAnnouncement() const;
QString speaker() const;
void setSpeaker( const QString &speaker );
bool deviated() const;
Marble::MarbleQuickItem * marbleQuickItem() const;
double screenAccuracy() const;
QPointF screenPosition() const;
public Q_SLOTS:
void setMarbleQuickItem(Marble::MarbleQuickItem * marbleQuickItem);
Q_SIGNALS:
void mapChanged();
void guidanceModeEnabledChanged();
void mutedChanged(bool arg);
void nextInstructionTextChanged();
void nextInstructionImageChanged();
void nextInstructionDistanceChanged();
void destinationDistanceChanged();
void nextRoadChanged();
void voiceNavigationAnnouncementChanged();
void soundEnabledChanged();
void speakerChanged();
void deviationChanged();
void marbleQuickItemChanged(Marble::MarbleQuickItem * marbleQuickItem);
void screenAccuracyChanged();
void screenPositionChanged();
private Q_SLOTS:
void update();
void updateScreenPosition();
private:
NavigationPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/declarative/OfflineDataModel.h b/src/lib/marble/declarative/OfflineDataModel.h
index 75769a35b..f7068e7c3 100644
--- a/src/lib/marble/declarative/OfflineDataModel.h
+++ b/src/lib/marble/declarative/OfflineDataModel.h
@@ -1,90 +1,90 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_OFFLINEDATAMODEL_H
#define MARBLE_DECLARATIVE_OFFLINEDATAMODEL_H
#include "NewstuffModel.h"
#include <QSortFilterProxyModel>
class OfflineDataModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY( int count READ count NOTIFY countChanged )
Q_FLAGS(VehicleType VehicleTypes)
public:
enum VehicleType {
None = 0x0,
Motorcar = 0x1,
Bicycle = 0x2,
Pedestrian = 0x4,
Any = Motorcar | Bicycle | Pedestrian
};
Q_DECLARE_FLAGS(VehicleTypes, VehicleType)
- explicit OfflineDataModel( QObject* parent = 0 );
+ explicit OfflineDataModel( QObject* parent = nullptr );
/** @todo FIXME https://bugreports.qt-project.org/browse/QTCOMPONENTS-1206 */
int count() const;
QHash<int, QByteArray> roleNames() const override;
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const override;
public Q_SLOTS:
void setVehicleTypeFilter( VehicleTypes filter );
void install( int index );
void uninstall( int index );
void cancel( int index );
Q_SIGNALS:
void countChanged();
void installationProgressed( int newstuffindex, qreal progress );
void installationFinished( int newstuffindex );
void installationFailed( int newstuffindex, const QString &error );
void uninstallationFinished( int newstuffindex );
protected:
bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const override;
private Q_SLOTS:
void handleInstallationProgress( int index, qreal progress );
void handleInstallationFinished( int index );
void handleInstallationFailed( int index, const QString &error );
void handleUninstallationFinished( int index );
private:
int fromSource( int idx ) const;
int toSource( int idx ) const;
Marble::NewstuffModel m_newstuffModel;
VehicleTypes m_vehicleTypeFilter;
QHash<int, QByteArray> m_roleNames;
};
#endif
diff --git a/src/lib/marble/declarative/Placemark.cpp b/src/lib/marble/declarative/Placemark.cpp
index 9e36d6cca..c0ca6d5d4 100644
--- a/src/lib/marble/declarative/Placemark.cpp
+++ b/src/lib/marble/declarative/Placemark.cpp
@@ -1,748 +1,748 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "Placemark.h"
#ifdef HAVE_QT5_POSITIONING
#include <GeoDataExtendedData.h>
#include <QGeoAddress>
#endif // HAVE_QT5_POSITIONING
#include <osm/OsmPlacemarkData.h>
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataTypes.h"
#include "GeoDataDocument.h"
namespace Marble {
Placemark::Placemark(QObject *parent ) :
QObject( parent )
{
// nothing to do
}
void Placemark::setGeoDataPlacemark( const Marble::GeoDataPlacemark &placemark )
{
m_placemark = placemark;
m_address = QString();
m_description = QString();
m_website = QString();
m_wikipedia = QString();
m_openingHours = QString();
m_wheelchairInfo = QString();
m_wifiAvailable = QString();
m_phone = QString();
updateTags();
updateRelations(placemark);
emit coordinatesChanged();
emit nameChanged();
emit descriptionChanged();
emit addressChanged();
emit websiteChanged();
emit wikipediaChanged();
emit openingHoursChanged();
emit wheelchairInfoChanged();
emit wifiAvailabilityChanged();
emit phoneChanged();
emit tagsChanged();
}
Marble::GeoDataPlacemark & Placemark::placemark()
{
return m_placemark;
}
const GeoDataPlacemark &Placemark::placemark() const
{
return m_placemark;
}
QString Placemark::name() const
{
return m_placemark.displayName();
}
QString Placemark::description() const
{
if (m_description.isEmpty()) {
auto const category = m_placemark.visualCategory();
m_description = m_placemark.categoryName();
if (category == GeoDataPlacemark::AccomodationHotel || category == GeoDataPlacemark::FoodRestaurant) {
QString const stars = m_placemark.osmData().tagValue(QStringLiteral("stars"));
if (!stars.isEmpty()) {
bool hasStars;
int const numStars = stars.mid(0, 1).toInt(&hasStars);
if (hasStars) {
m_description += QString(' ') + QString("★").repeated(numStars) + stars.mid(1);
} else {
addTagValue(m_description, QStringLiteral("stars"));
}
}
addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
}
if ((category >= GeoDataPlacemark::AccomodationHostel &&
category <= GeoDataPlacemark::AccomodationGuestHouse) ||
category == GeoDataPlacemark::HealthHospital) {
int const rooms = m_placemark.osmData().tagValue(QStringLiteral("rooms")).toInt();
if (rooms > 0) {
//~ singular %n room
//~ plural %n rooms
- addTagValue(m_description, QStringLiteral("rooms"), tr("%n rooms", 0, rooms));
+ addTagValue(m_description, QStringLiteral("rooms"), tr("%n rooms", nullptr, rooms));
}
int const beds = m_placemark.osmData().tagValue(QStringLiteral("beds")).toInt();
if (beds > 0) {
//~ singular %n bed
//~ plural %n beds
- addTagValue(m_description, QStringLiteral("beds"), tr("%n beds", 0, beds));
+ addTagValue(m_description, QStringLiteral("beds"), tr("%n beds", nullptr, beds));
}
}
if (category == GeoDataPlacemark::TransportParking || category == GeoDataPlacemark::TransportBicycleParking || category == GeoDataPlacemark::TransportMotorcycleParking) {
addTagValue(m_description, QStringLiteral("capacity"), tr("%1 parking spaces"));
addTagValue(m_description, QStringLiteral("maxstay"), tr("Maximum parking time %1"));
}
if (category >= GeoDataPlacemark::FoodBar && category <= GeoDataPlacemark::FoodRestaurant) {
if (category != GeoDataPlacemark::FoodRestaurant) {
addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
} else {
// Do nothing, already added in stars section above
}
addTagValue(m_description, "cuisine");
addTagValue(m_description, "brewery");
addTagDescription(m_description, "self_service", "yes", "Self Service");
addTagDescription(m_description, "takeaway", "yes", "Take Away");
addTagDescription(m_description, "outdoor_seating", "yes", "Outdoor Seating");
addTagDescription(m_description, "ice_cream", "yes", "Ice Cream");
addTagDescription(m_description, "smoking", "dedicated", "Smoking (dedicated)");
addTagDescription(m_description, "smoking", "yes", "Smoking allowed");
addTagDescription(m_description, "smoking", "separated", "Smoking (separated)");
addTagDescription(m_description, "smoking", "isolated", "Smoking (isolated)");
addTagDescription(m_description, "smoking", "no", "No smoking");
addTagDescription(m_description, "smoking", "outside", "Smoking (outside)");
addTagDescription(m_description, "smoking:outside", "yes", "Smoking (outside)");
addTagDescription(m_description, "smoking:outside", "separated", "Smoking (outside separated)");
addTagDescription(m_description, "smoking:outside", "no", "No smoking outside");
} else if (category >= GeoDataPlacemark::ShopBeverages && category <= GeoDataPlacemark::Shop) {
addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
addTagValue(m_description, "clothes");
addTagValue(m_description, "designation");
if (category == GeoDataPlacemark::ShopButcher) {
addTagValue(m_description, "butcher");
} else if (category == GeoDataPlacemark::ShopCopy) {
addTagDescription(m_description, QStringLiteral("service:computer"), QStringLiteral("yes"), tr("Computers available", "A copy shop provides computers for customer use"));
addTagDescription(m_description, QStringLiteral("service:computer"), QStringLiteral("no"), tr("No computers available", "A copy shop does not provide computers for customer use"));
addTagDescription(m_description, QStringLiteral("service:copy"), QStringLiteral("yes"), tr("Photocopying service", "A copy shop provides photocopying service"));
addTagDescription(m_description, QStringLiteral("service:copy"), QStringLiteral("no"), tr("No photocopying service", "A copy shop does not provide photocopying service"));
addTagDescription(m_description, QStringLiteral("service:scan"), QStringLiteral("yes"), tr("Digital scanning", "A copy shop provides a service for scanning documents into digital files"));
addTagDescription(m_description, QStringLiteral("service:scan"), QStringLiteral("no"), tr("No digital scanning", "A copy shop does not provide a service for scanning documents into digital files"));
addTagDescription(m_description, QStringLiteral("service:fax"), QStringLiteral("yes"), tr("Fax service", "A copy shop provides a service to send documents through fax"));
addTagDescription(m_description, QStringLiteral("service:fax"), QStringLiteral("no"), tr("No fax service", "A copy shop does not provide a service to send documents through fax"));
addTagDescription(m_description, QStringLiteral("service:phone"), QStringLiteral("yes"), tr("Phone service", "A copy shop provides a paid service to make phone calls"));
addTagDescription(m_description, QStringLiteral("service:phone"), QStringLiteral("no"), tr("No phone service", "A copy shop does not provide a paid service to make phone calls"));
addTagDescription(m_description, QStringLiteral("service:print"), QStringLiteral("yes"), tr("Digital printing", "A copy shop provides services to print paper documents from digital files"));
addTagDescription(m_description, QStringLiteral("service:print"), QStringLiteral("no"), tr("No digital printing", "A copy shop does not provide services to print paper documents from digital files"));
addTagDescription(m_description, QStringLiteral("service:press"), QStringLiteral("yes"), tr("Press printing service", "A copy shop provides a professional service to print a large number of copies of a document"));
addTagDescription(m_description, QStringLiteral("service:press"), QStringLiteral("no"), tr("No press printing service", "A copy shop does not provide a professional service to print a large number of copies of a document"));
addTagDescription(m_description, QStringLiteral("service:prepress"), QStringLiteral("yes"), tr("Press printing assistance", "A copy shop provides help with preparing special printing techniques"));
addTagDescription(m_description, QStringLiteral("service:prepress"), QStringLiteral("no"), tr("No press printing assistance", "A copy shop does not provide help with preparing special printing techniques"));
addTagDescription(m_description, QStringLiteral("service:self"), QStringLiteral("yes"), tr("Self service", "A copy shop provides individual copy machines for self-service"));
addTagDescription(m_description, QStringLiteral("service:self"), QStringLiteral("no"), tr(" No self service", "A copy shop does not provide individual machines for self-service"));
} else if (category == GeoDataPlacemark::ShopDeli) {
addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("yes"), tr("Sells organic food", "A deli that sells organic food"));
addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("no"), tr("Does not sell organic food", "A deli that does not sell organic food"));
addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("only"), tr("Only sells organic food", "A deli that only sells organic food"));
addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("yes"), tr("Sells gluten free food", "A deli that sells gluten free food"));
addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("no"), tr("Does not sell gluten free food", "A deli that does not sell gluten free food"));
addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("only"), tr("Only sells gluten free food", "A deli that only sells gluten free food"));
addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("yes"), tr("Sells lactose free food", "A deli that sells lactose free food"));
addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("no"), tr("Does not sell lactose free food", "A deli that does not sell lactose free food"));
addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("only"), tr("Only sells lactose free food", "A deli that only sells lactose free food"));
} else if (category == GeoDataPlacemark::ShopTobacco) {
addTagDescription(m_description, QStringLiteral("lottery"), QStringLiteral("yes"), tr("Sells lottery tickets", "A tobacco shop that also sells lottery tickets"));
addTagDescription(m_description, QStringLiteral("stamps"), QStringLiteral("yes"), tr("Sells revenue stamps", "A tobacco shop that also sells revenue stamps"));
addTagDescription(m_description, QStringLiteral("salt"), QStringLiteral("yes"), tr("Sells salt", "A tobacco shop that also sells salt"));
}
} else if (category == GeoDataPlacemark::TransportBusStop) {
addTagValue(m_description, "network");
addTagValue(m_description, "operator");
addTagValue(m_description, "ref");
} else if (category == GeoDataPlacemark::TransportCarShare) {
addTagValue(m_description, "network");
addTagValue(m_description, "operator");
} else if (category == GeoDataPlacemark::TransportRentalBicycle ||
category == GeoDataPlacemark::TransportRentalCar ||
category == GeoDataPlacemark::TransportRentalSki) {
addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
} else if (category == GeoDataPlacemark::TransportFuel) {
addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
addTagDescription(m_description, "fuel:diesel", "yes", tr("Diesel"));
addTagDescription(m_description, "fuel:biodiesel", "yes", tr("Biodiesel"));
addTagDescription(m_description, "fuel:octane_91", "yes", tr("Octane 91"));
addTagDescription(m_description, "fuel:octane_95", "yes", tr("Octane 95"));
addTagDescription(m_description, "fuel:octane_98", "yes", tr("Octane 98"));
addTagDescription(m_description, "fuel:octane_100", "yes", tr("Octane 100"));
addTagDescription(m_description, "fuel:e10", "yes", tr("E10"));
addTagDescription(m_description, "fuel:lpg", "yes", tr("LPG"));
} else if (category == GeoDataPlacemark::NaturalTree) {
addTagValue(m_description, "species:en");
addTagValue(m_description, "genus:en");
addTagValue(m_description, "leaf_type");
} else if (category == GeoDataPlacemark::NaturalCave){
addTagValue(m_description, "cave:ref");
} else if (category == GeoDataPlacemark::AmenityRecycling) {
addTagDescription(m_description, QStringLiteral("recycling:batteries"), "yes", tr("Batteries"));
addTagDescription(m_description, QStringLiteral("recycling:clothes"), "yes", tr("Clothes"));
addTagDescription(m_description, QStringLiteral("recycling:glass"), "yes", tr("Glass"));
addTagDescription(m_description, QStringLiteral("recycling:glass_bottles"), "yes", tr("Glass bottles"));
addTagDescription(m_description, QStringLiteral("recycling:green_waste"), "yes", tr("Green waste"));
addTagDescription(m_description, QStringLiteral("recycling:garden_waste"), "yes", tr("Garden waste"));
addTagDescription(m_description, QStringLiteral("recycling:electrical_items"), "yes", tr("Electrical items"));
addTagDescription(m_description, QStringLiteral("recycling:metal"), "yes", tr("Metal"));
addTagDescription(m_description, QStringLiteral("recycling:mobile_phones"), "yes", tr("Mobile phones"));
addTagDescription(m_description, QStringLiteral("recycling:newspaper"), "yes", tr("Newspaper"));
addTagDescription(m_description, QStringLiteral("recycling:paint"), "yes", tr("Paint"));
addTagDescription(m_description, QStringLiteral("recycling:paper"), "yes", tr("Paper"));
addTagDescription(m_description, QStringLiteral("recycling:paper_packaging"), "yes", tr("Paper packaging"));
addTagDescription(m_description, QStringLiteral("recycling:PET"), "yes", tr("PET"));
addTagDescription(m_description, QStringLiteral("recycling:plastic"), "yes", tr("Plastic"));
addTagDescription(m_description, QStringLiteral("recycling:plastic_bags"), "yes", tr("Plastic bags"));
addTagDescription(m_description, QStringLiteral("recycling:plastic_bottles"), "yes", tr("Plastic bottles"));
addTagDescription(m_description, QStringLiteral("recycling:plastic_packaging"), "yes", tr("Plastic packaging"));
addTagDescription(m_description, QStringLiteral("recycling:polyester"), "yes", tr("Polyester"));
addTagDescription(m_description, QStringLiteral("recycling:tyres"), "yes", tr("Tyres"));
addTagDescription(m_description, QStringLiteral("recycling:waste"), "yes", tr("Waste"));
addTagDescription(m_description, QStringLiteral("recycling:white_goods"), "yes", tr("White goods"));
addTagDescription(m_description, QStringLiteral("recycling:wood"), "yes", tr("Wood"));
} else if (category == GeoDataPlacemark::NaturalVolcano) {
addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("active"), tr("Active", "An active volcano"));
addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("dormant"), tr("Dormant", "A dormant volcano that will erupt at some point in the future."));
addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("extinct"), tr("Extinct", "A volcano considered extinct, it has not erupted within the last 10000 years and likely never will again."));
addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("stratovolcano"), tr("Stratovolcano"));
addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("shield"), tr("Shield volcano"));
addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("scoria"), tr("Scoria cone", "A scoria cone volcano."));
} else if (category == GeoDataPlacemark::HealthDoctors) {
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("alternative"), tr("Alternative medicine"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("audiologist"), tr("Audiologist"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("blood_bank"), tr("Blood bank"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("blood_donation"), tr("Blood donation"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("centre"), tr("Medical center"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("clinic"), tr("Clinic"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("dentist"), tr("Dentist"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("doctor"), tr("Medical practitioner"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("hospital"), tr("Hospital"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("midwife"), tr("Midwife"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("optometrist"), tr("Optometrist"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("physiotherapist"), tr("Physiotherapist"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("podiatrist"), tr("Podiatrist"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("psychotherapist"), tr("Psychotherapist"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("rehabilitation"), tr("Rehabilitation"));
addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("speech_therapist"), tr("Speech therapist"));
addTagValue(m_description, QStringLiteral("healthcare:speciality"));
} else if (category == GeoDataPlacemark::AmenityBench) {
int const seats = m_placemark.osmData().tagValue(QStringLiteral("seats")).toInt();
if (seats > 0) {
//~ singular %n seat
//~ plural %n seats
addTagValue(m_description, QStringLiteral("seats"), tr("%n seats", "number of seats a bench provides", seats));
}
addTagValue(m_description, QStringLiteral("material"));
addTagDescription(m_description, QStringLiteral("backrest"), QStringLiteral("yes"), tr("Has backrest", "A bench provides a backrest to lean against"));
addTagDescription(m_description, QStringLiteral("backrest"), QStringLiteral("no"), tr("No backrest", "A bench provides no backrest to lean against"));
} else if (category == GeoDataPlacemark::AmenityWasteBasket) {
addTagValue(m_description, QStringLiteral("waste"));
} else if (category == GeoDataPlacemark::TransportSpeedCamera) {
addTagValue(m_description, QStringLiteral("maxspeed"), tr("%1 km/h"));
addTagValue(m_description, "ref");
} else if (category == GeoDataPlacemark::TransportParking) {
addTagDescription(m_description, QStringLiteral("supervised"), QStringLiteral("yes"), tr("Is supervised", "Parking spaces are supervised by guards"));
addTagDescription(m_description, QStringLiteral("supervised"), QStringLiteral("no"), tr("Not supervised", "Parking spaces are not supervised by guards"));
int const disabledSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:disabled")).toInt();
if (disabledSpaces > 0) {
addTagValue(m_description, QStringLiteral("capacity:disabled"), tr("%1 disabled spaces", "Parking spaces"));
}
int const womenSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:women")).toInt();
if (womenSpaces > 0) {
addTagValue(m_description, QStringLiteral("capacity:women"), tr("%1 women spaces", "Parking spaces"));
}
int const parentSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:parent")).toInt();
if (parentSpaces > 0) {
addTagValue(m_description, QStringLiteral("capacity:parent"), tr("%1 parent and child spaces", "Parking spaces"));
}
int const electricChargers = m_placemark.osmData().tagValue(QStringLiteral("capacity:charging")).toInt();
if (electricChargers > 0) {
addTagValue(m_description, QStringLiteral("capacity:charging"), tr("%1 spaces with electric chargers", "Parking spaces"));
}
} else if (category == GeoDataPlacemark::TransportBicycleParking) {
addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("outdoor"), tr("Has outdoor surveillance", "A parking space has outdoor surveillance"));
addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("indoor"), tr("Has indoor surveillance", "A parking space has indoor surveillance"));
addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("public"), tr("Has public surveillance", "A parking space has public surveillance"));
} else if (category == GeoDataPlacemark::TourismWildernessHut) {
addTagDescription(m_description, QStringLiteral("shower"), QStringLiteral("yes"), tr("Has shower", "A hut provides showers inside or aside"));
addTagDescription(m_description, QStringLiteral("shower"), QStringLiteral("no"), tr("Has no shower", "A hut does not provide showers inside or aside"));
addTagDescription(m_description, QStringLiteral("mattress"), QStringLiteral("yes"), tr("Has mattress", "A hut provides mattress"));
addTagDescription(m_description, QStringLiteral("mattress"), QStringLiteral("no"), tr("Has no mattress", "A hut does not provide mattress"));
addTagDescription(m_description, QStringLiteral("drinking_water"), QStringLiteral("yes"), tr("Has water", "Water is available inside or aside"));
addTagDescription(m_description, QStringLiteral("drinking_water"), QStringLiteral("no"), tr("Has no water", "Water is not available inside nor aside"));
addTagDescription(m_description, QStringLiteral("toilets"), QStringLiteral("yes"), tr("Has toilets", "A hut provides toilets"));
addTagDescription(m_description, QStringLiteral("toilets"), QStringLiteral("no"), tr("Has no toilets", "A hut does not provide toilets"));
addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("yes"), tr("Reservation is possible"));
addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("no"), tr("No reservation possible"));
addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("required"), tr("Reservation is required"));
addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("recommended"), tr("Reservation is recommended", "You should make reservation"));
addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("members_only"), tr("Only for members", "Reservation is only possible for members of the organisation running the hut"));
} else if (category == GeoDataPlacemark::TourismArtwork) {
addTagValue(m_description, QStringLiteral("artist_name"), tr("By %1"));
} else if (category == GeoDataPlacemark::AmenityChargingStation) {
addTagValue(m_description, QStringLiteral("capacity"), tr("%1 vehicles"));
addTagValue(m_description, QStringLiteral("amperage"), tr("%1 ampere"));
addTagValue(m_description, QStringLiteral("voltage"), tr("%1 volt"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_blue"), tr("%1 blue CEE sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_16a"), tr("%1 red CEE sockets (16 A)"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_32a"), tr("%1 red CEE sockets (32 A)"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_64a"), tr("%1 red CEE sockets (64 A)"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_125a"), tr("%1 red CEE sockets (125 A)"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_5_15"), tr("%1 NEMA-5-15P plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("typeb"), tr("%1 NEMA-5-15P plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_5_20"), tr("%1 NEMA-5-20P plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_14_30"), tr("%1 NEMA 14-30 sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_14_50"), tr("%1 NEMA 14-50 sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("schuko"), tr("%1 Schuko sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("bs1363"), tr("%1 BS 1363 sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type1"), tr("%1 Type 1 plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type1_combo"), tr("%1 Type 1 combo plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type2"), tr("%1 Type 2 sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type2_combo"), tr("%1 Type 2 combo sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type3"), tr("%1 Type 3 sockets"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("chademo"), tr("%1 CHAdeMO plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("magne_charge"), tr("%1 Magne Charge plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_standard"), tr("%1 Tesla standard plugs"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_supercharger"), tr("%1 Tesla standard plugs (Supercharger)"));
addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_roadster"), tr("%1 Tesla roadster plugs"));
} else if (category == GeoDataPlacemark::AmenityCarWash) {
addTagValue(m_description, QStringLiteral("maxwidth"), tr("Maximum vehicle width: %1"));
addTagValue(m_description, QStringLiteral("maxheight"), tr("Maximum vehicle height: %1"));
addTagDescription(m_description, QStringLiteral("self_service"), QStringLiteral("yes"), tr("Self-service"));
addTagDescription(m_description, QStringLiteral("self_service"), QStringLiteral("no"), tr("No self-service"));
addTagDescription(m_description, QStringLiteral("automated"), QStringLiteral("yes"), tr("Automated"));
addTagDescription(m_description, QStringLiteral("automated"), QStringLiteral("no"), tr("Manual"));
} else if (category == GeoDataPlacemark::AmenitySocialFacility) {
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("group_home"), tr("Group home"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("nursing_home"), tr("Nursing home"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("assisted_living"), tr("Assisted living", "Like group home but for more independent people, e.g. who have flats"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("day_care"), tr("Nursing services on a daily basis"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("shelter"), tr("Shelter"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("ambulatory_care"), tr("Ambulatory care"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("outreach"), tr("Social welfare services"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("workshop"), tr("Employment and workshops for offenders and people with disabilities"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("food_bank"), tr("Pre-packaged food for free or below market price"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("soup_kitchen"), tr("Prepared meals for free or below market price"));
addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("dairy_kitchen"), tr("Free dairy food (subject to local regulations)"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("abused"), tr("For abused"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("child"), tr("For children"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("disabled"), tr("For people with physical disabilities"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("diseased"), tr("For those who suffer of a disease"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("drug_addicted"), tr("For drug-addicted"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("homeless"), tr("For homeless"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("juvenile"), tr("For juvenile"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("mental_health"), tr("For those with mental/psychological problems"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("migrant"), tr("For migrants"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("orphan"), tr("For orphans"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("senior"), tr("For elder people"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("underprivileged"), tr("For poor or disadvantaged people"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("unemployed"), tr("For unemployed"));
addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("victim"), tr("For victims of crimes"));
} else if (category == GeoDataPlacemark::HistoricMemorial) {
addTagValue(m_description, QStringLiteral("inscription"), tr("Inscription: %1"));
} else if (category >= GeoDataPlacemark::AerialwayCableCar && category <= GeoDataPlacemark::AerialwayGoods) {
addTagValue(m_description, QStringLiteral("occupancy"), tr("%1 places per carriage"));
addTagValue(m_description, QStringLiteral("capacity"), tr("%1 people per hour"));
addTagValue(m_description, QStringLiteral("duration"), tr("%1 minutes"));
addTagDescription(m_description, QStringLiteral("bubble"), QStringLiteral("yes"), tr("Has weather protection", "A carriage is protected from the weather"));
addTagDescription(m_description, QStringLiteral("bubble"), QStringLiteral("no"), tr("No weather protection", "A carriage is not protected from the weather"));
addTagDescription(m_description, QStringLiteral("heating"), QStringLiteral("yes"), tr("Is heated", "A carriage is heated"));
addTagDescription(m_description, QStringLiteral("heating"), QStringLiteral("no"), tr("Not heated", "A carriage is not heated"));
addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("yes"), tr("Bicycle transportation possible", "Bicycles can be transported"));
addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("summer"), tr("Bicycle transportation only in summer", "Bicycles can only be transported in summer"));
addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("no"), tr("Bicycle transportation impossible", "Bicyles cannot be transported"));
} else if (category >= GeoDataPlacemark::PisteDownhill && category <= GeoDataPlacemark::PisteSkiJump) {
addTagDescription(m_description, QStringLiteral("lit"), QStringLiteral("yes"), tr("Lit at night"));
addTagDescription(m_description, QStringLiteral("piste:lit"), QStringLiteral("yes"), tr("Lit in winter"));
addTagDescription(m_description, QStringLiteral("gladed"), QStringLiteral("yes"), tr("Contains trees", "A ski piste with trees (gladed)"));
addTagDescription(m_description, QStringLiteral("patrolled"), QStringLiteral("no"), tr("Not patrolled"));
addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic"), tr("Groomed for classic style nordic or downhill skiing"));
addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("mogul"), tr("Mogul piste"));
addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("skating"), tr("Groomed for free style or skating"));
addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic;skating"), tr("Groomed for classic and free style skiing"));
addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic+skating"), tr("Groomed for classic and free style skiing"));
addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("scooter"), tr("Groomed by a smaller snowmobile"));
addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("backcountry"), tr("Unmarked piste (backcountry touring)"));
}
if (category == GeoDataPlacemark::TransportBicycleParking || category == GeoDataPlacemark::TransportMotorcycleParking) {
addTagDescription(m_description, QStringLiteral("covered"), QStringLiteral("yes"), tr("Is covered", "A parking space is covered"));
addTagDescription(m_description, QStringLiteral("covered"), QStringLiteral("no"), tr("Not covered", "A parking space is not covered"));
}
if (category == GeoDataPlacemark::AmenityRecycling || category == GeoDataPlacemark::AmenityPostBox) {
addTagValue(m_description, QStringLiteral("collection_times"), tr("Collection times %1"), QStringLiteral(", "));
}
if (category == GeoDataPlacemark::AerialwayStation) {
addTagDescription(m_description, "aerialway:access", "entry", tr("Entry", "Entry station of an aerialway"));
addTagDescription(m_description, "aerialway:access", "exit", tr("Exit", "Exit station of an aerialway"));
addTagDescription(m_description, "aerialway:access", "both", tr("Entry and exit", "Entry and exit station of an aerialway"));
addTagDescription(m_description, "aerialway:access", "no", tr("No entry or exit", "Transit only station of an aerialway"));
addTagDescription(m_description, "aerialway:summer:access", "entry", tr("Entry during summer", "Entry station of an aerialway during summer"));
addTagDescription(m_description, "aerialway:summer:access", "exit", tr("Exit during summer", "Exit station of an aerialway during summer"));
addTagDescription(m_description, "aerialway:summer:access", "both", tr("Entry and exit during summer", "Entry and exit station of an aerialway during summer"));
addTagDescription(m_description, "aerialway:summer:access", "no", tr("No entry or exit during summer", "Transit only station of an aerialway during summer"));
}
if (category != GeoDataPlacemark::AerialwayStation) {
addTagValue(m_description, QStringLiteral("ele"), tr("Elevation: %1 m"));
}
addTagDescription(m_description, "access", "customers", tr("Customers only"));
addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("yes"), tr("Accessible by anyone", "The public has an official, legally-enshrined right of access; i.e., it's a right of way"));
addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("private"), tr("Private", "Only with permission of the owner on an individual basis."));
addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("permissive"), tr("Open to general traffic", "Open to general traffic but permission can be revoked by the owner"));
addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("no"), tr("No access", "No access for the general public"));
addTagDescription(m_description, QStringLiteral("fee"), QStringLiteral("no"), tr("no fee"));
addTagValue(m_description, QStringLiteral("description"));
addTagValue(m_description, QStringLiteral("old_name"), tr("formerly <i>%1</i>"));
const int level = m_placemark.osmData().tagValue(QStringLiteral("level")).toInt();
if (level > 2) {
addTagValue(m_description, QStringLiteral("level"), tr("Floor %1", "Positive floor level"));
} else if (level < -2) {
addTagValue(m_description, QStringLiteral("level"), tr("Basement %1", "Negative floor level"));
} else {
addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("2"), tr("Floor 2", "Floor level 2, two levels above ground level"));
addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("1"), tr("Floor 1", "Floor level 1, one level above ground level"));
addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("0"), tr("Ground floor", "Floor level 0"));
addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("-1"), tr("Basement 1", "Floor level -1, one level below ground level"));
addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("-2"), tr("Basement 2", "Floor level -2, two levels below ground level"));
}
}
return m_description;
}
QString Placemark::address() const
{
if (m_address.isEmpty()) {
m_address = addressFromOsmData();
}
return m_address;
}
QString Placemark::website() const
{
if (!m_website.isEmpty()) {
return m_website;
}
auto const tags = QStringList() << "website" << "contact:website" << "facebook" << "contact:facebook" << "url";
for(const QString &tag: tags) {
QString const value = m_placemark.osmData().tagValue(tag);
if (!value.isEmpty()) {
QUrl url = QUrl(value);
if (url.isValid()) {
if (url.scheme().isEmpty()) {
m_website = QStringLiteral("http://%1").arg(value);
} else {
m_website = value;
}
if (!m_website.isEmpty()) {
return m_website;
}
}
}
}
return m_website;
}
QString Placemark::wikipedia() const
{
if (!m_wikipedia.isEmpty()) {
return m_wikipedia;
}
// TODO: also support "wikipedia:lang=page title" tags
const QString wikipedia = m_placemark.osmData().tagValue("wikipedia");
if (!wikipedia.isEmpty()) {
// full URL?
if (wikipedia.startsWith(QLatin1String("http://")) ||
wikipedia.startsWith(QLatin1String("https://"))) {
m_wikipedia = wikipedia;
} else {
// match "(lang:)human readable title"
QRegularExpression re("^(?:([a-z]{2,}):)?(.*)$");
QRegularExpressionMatch match = re.match(wikipedia);
QString lang = match.captured(1);
if (lang.isEmpty()) {
lang = QStringLiteral("en");
}
const QString title = QString::fromLatin1(QUrl::toPercentEncoding(match.captured(2)));
m_wikipedia = QLatin1String("https://") + lang + QLatin1String(".wikipedia.org/wiki/") + title;
}
}
return m_wikipedia;
}
QString Placemark::openingHours() const
{
if (!m_openingHours.isEmpty()) {
return m_openingHours;
}
addTagValue(m_openingHours, "opening_hours");
return m_openingHours;
}
QString Placemark::coordinates() const
{
return m_placemark.coordinate().toString(GeoDataCoordinates::Decimal).trimmed();
}
QString Placemark::wheelchairInfo() const
{
if (!m_wheelchairInfo.isEmpty())
return m_wheelchairInfo;
addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("yes"), tr("Wheelchair accessible"));
addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("no"), tr("Wheelchair inaccessible"));
addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("limited"), tr("Limited wheelchair accessibility"));
addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("designated"), tr("Designated wheelchair access"));
// Check if there is localized description
auto const & osmData = m_placemark.osmData();
QStringList const uiLanguages = QLocale::system().uiLanguages();
const QString tag = QLatin1String("wheelchair:description:");
for (const QString &uiLanguage: uiLanguages) {
for (auto tagIter = osmData.tagsBegin(), end = osmData.tagsEnd(); tagIter != end; ++tagIter) {
if (tagIter.key().startsWith(tag)) {
QStringRef const tagLanguage = tagIter.key().midRef(tag.length());
if (tagLanguage == uiLanguage) {
append(m_wheelchairInfo, tagIter.value());
return m_wheelchairInfo;
}
}
}
}
addTagValue(m_wheelchairInfo, "wheelchair:description");
return m_wheelchairInfo;
}
QString Placemark::wifiAvailable() const
{
if (!m_wifiAvailable.isEmpty()) {
return m_wifiAvailable;
}
const auto& osmData = m_placemark.osmData();
addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("no"), tr("No public Internet access", "This location does not provide public Internet access"));
addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("yes"), tr("Public Internet access available", "This location provides an unknown type of public Internet access."));
if (osmData.containsTag(QStringLiteral("internet_access:fee"), QStringLiteral("yes"))) {
addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Charged public wifi available", "Public wireless Internet access is available here for a fee."));
} else if (osmData.containsTag(QStringLiteral("internet_access:fee"), QStringLiteral("no"))) {
addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Free public wifi available", "Public wireless Internet access is available here for no cost."));
} else {
addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Public wifi available", "Public wireless Internet access is available here."));
}
if (m_wifiAvailable.isEmpty()) {
addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("no"), tr("No public wifi", "Public wifi is not available here."));
addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("yes"), tr("Public wifi available", "Public wireless Internet is available here."));
addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("free"), tr("Free public wifi available", "Public wireless Internet is available here for no cost."));
}
return m_wifiAvailable;
}
QString Placemark::phone() const
{
if (!m_phone.isEmpty()) {
return m_phone;
}
addTagValue(m_phone, "phone");
return m_phone;
}
void Placemark::setName(const QString & name)
{
if (m_placemark.displayName() == name) {
return;
}
m_placemark.setName(name);
emit nameChanged();
}
RouteRelationModel* Placemark::routeRelationModel()
{
return &m_relationModel;
}
double Placemark::longitude() const
{
return m_placemark.coordinate().longitude(GeoDataCoordinates::Degree);
}
double Placemark::latitude() const
{
return m_placemark.coordinate().latitude(GeoDataCoordinates::Degree);
}
const QStringList &Placemark::tags() const
{
return m_tags;
}
bool Placemark::addTagValue(QString &target, const QString &key, const QString &format, const QString& separator) const
{
auto const & osmData = m_placemark.osmData();
QString const value = osmData.tagValue(key);
if (!value.isEmpty()) {
QString description = format.isEmpty() ? value : format.arg(value);
description.replace(QLatin1Char(';'), separator);
append(target, description);
return true;
}
return false;
}
void Placemark::addFirstTagValueOf(QString &target, const QStringList &keys) const
{
for (auto const &key: keys) {
if (addTagValue(target, key)) {
return;
}
}
}
void Placemark::addTagDescription(QString &target, const QString &key, const QString &value, const QString &description) const
{
auto const & osmData = m_placemark.osmData();
if (osmData.containsTag(key, value)) {
append(target, description);
}
}
void Placemark::append(QString &target, const QString &value)
{
if (!target.isEmpty()) {
target += QStringLiteral(" · "); // non-latin1
}
target += value;
}
QString Placemark::addressFromOsmData() const
{
#ifdef HAVE_QT5_POSITIONING
QGeoAddress address;
OsmPlacemarkData const data = m_placemark.osmData();
address.setCountry(data.tagValue("addr:country"));
address.setState(data.tagValue("addr:state"));
address.setCity(data.tagValue("addr:city"));
address.setDistrict(data.tagValue("district"));
address.setPostalCode(data.tagValue("addr:postcode"));
QString const street = data.tagValue("addr:street");
QString const houseNumber = data.tagValue("addr:housenumber");
address.setStreet(formatStreet(street, houseNumber));
return address.text().replace("<br/>", ", ");
#else
return QString();
#endif
}
QString Placemark::formatStreet(const QString &street, const QString &houseNumber)
{
return houseNumber.isEmpty() ? street : tr("%1 %2",
"House number (first argument) and street name (second argument) in an address").arg(houseNumber).arg(street).trimmed();
}
void Placemark::updateTags()
{
m_tags.clear();
QString const tag = QStringLiteral("%1 = %2");
for (auto iter = m_placemark.osmData().tagsBegin(), end = m_placemark.osmData().tagsEnd(); iter != end; ++iter) {
m_tags << tag.arg(iter.key()).arg(iter.value());
}
}
void Placemark::updateRelations(const Marble::GeoDataPlacemark &placemark)
{
- if (const auto document = (placemark.parent() ? geodata_cast<GeoDataDocument>(placemark.parent()) : 0)) {
+ if (const auto document = (placemark.parent() ? geodata_cast<GeoDataDocument>(placemark.parent()) : nullptr)) {
QVector<const GeoDataRelation*> allRelations;
QSet<const GeoDataRelation*> relevantRelations;
QSet<qint64> placemarkIds;
auto const & osmData = placemark.osmData();
placemarkIds << osmData.oid();
bool searchRelations = true;
for (auto feature: document->featureList()) {
if (const auto relation = geodata_cast<GeoDataRelation>(feature)) {
allRelations << relation;
if (relation->memberIds().contains(osmData.oid())) {
relevantRelations << relation;
auto const isRoute = relation->osmData().tagValue(QStringLiteral("type")) == QStringLiteral("route");
searchRelations &= !isRoute;
}
}
}
if (searchRelations) {
for (auto feature: document->featureList()) {
if (const auto relation = geodata_cast<GeoDataRelation>(feature)) {
if (relevantRelations.contains(relation) &&
relation->osmData().containsTag(QStringLiteral("type"), QStringLiteral("public_transport")) &&
relation->osmData().containsTag(QStringLiteral("public_transport"), QStringLiteral("stop_area"))) {
for (auto iter = relation->osmData().relationReferencesBegin(), end = relation->osmData().relationReferencesEnd();
iter != end; ++iter) {
if (iter.value() == QStringLiteral("stop") || iter.value() == QStringLiteral("platform")) {
placemarkIds << iter.key();
}
}
}
}
}
}
for (auto relation: allRelations) {
if (relation->containsAnyOf(placemarkIds)) {
relevantRelations << relation;
}
}
m_relationModel.setRelations(relevantRelations);
}
}
}
#include "moc_Placemark.cpp"
diff --git a/src/lib/marble/declarative/Placemark.h b/src/lib/marble/declarative/Placemark.h
index 3ff00f4e5..9ef4803ed 100644
--- a/src/lib/marble/declarative/Placemark.h
+++ b/src/lib/marble/declarative/Placemark.h
@@ -1,117 +1,117 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_PLACEMARK_H
#define MARBLE_DECLARATIVE_PLACEMARK_H
#include "GeoDataPlacemark.h"
#include "RouteRelationModel.h"
#include <QObject>
#include <QtQml>
#include <QStringListModel>
namespace Marble {
/**
* Wraps a GeoDataPlacemark for QML access
*/
class Placemark : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name WRITE setName READ name NOTIFY nameChanged)
Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
Q_PROPERTY(QString address READ address NOTIFY addressChanged)
Q_PROPERTY(QString website READ website NOTIFY websiteChanged)
Q_PROPERTY(QString wikipedia READ wikipedia NOTIFY wikipediaChanged)
Q_PROPERTY(QString openingHours READ openingHours NOTIFY openingHoursChanged)
Q_PROPERTY(QString coordinates READ coordinates NOTIFY coordinatesChanged)
Q_PROPERTY(QString wheelchairInfo READ wheelchairInfo NOTIFY wheelchairInfoChanged)
Q_PROPERTY(QString wifiAvailable READ wifiAvailable NOTIFY wifiAvailabilityChanged)
Q_PROPERTY(QString phone READ phone NOTIFY phoneChanged)
Q_PROPERTY(double longitude READ longitude NOTIFY coordinatesChanged)
Q_PROPERTY(double latitude READ latitude NOTIFY coordinatesChanged)
Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged)
Q_PROPERTY(RouteRelationModel* routeRelationModel READ routeRelationModel CONSTANT)
public:
/** Constructor */
- explicit Placemark( QObject *parent = 0 );
+ explicit Placemark( QObject *parent = nullptr );
void setGeoDataPlacemark( const Marble::GeoDataPlacemark &placemark );
Marble::GeoDataPlacemark & placemark();
const Marble::GeoDataPlacemark & placemark() const;
QString name() const;
QString description() const;
QString address() const;
QString website() const;
QString wikipedia() const;
QString openingHours() const;
QString coordinates() const;
QString wheelchairInfo() const;
QString wifiAvailable() const;
QString phone() const;
double longitude() const;
double latitude() const;
const QStringList & tags() const;
RouteRelationModel* routeRelationModel();
public Q_SLOTS:
void setName(const QString &name);
Q_SIGNALS:
void nameChanged();
void coordinatesChanged();
void descriptionChanged();
void addressChanged();
void websiteChanged();
void wikipediaChanged();
void openingHoursChanged();
void wheelchairInfoChanged();
void wifiAvailabilityChanged();
void phoneChanged();
void tagsChanged();
void routeRelationModelChanged();
private:
bool addTagValue(QString &target, const QString &key, const QString &format=QString(), const QString& separator = QStringLiteral(" · ")) const;
void addFirstTagValueOf(QString &target, const QStringList &keys) const;
void addTagDescription(QString &target, const QString &key, const QString &value, const QString &description) const;
static void append(QString &target, const QString &value);
QString addressFromOsmData() const;
static QString formatStreet(const QString &street, const QString &houseNumber);
void updateTags();
void updateRelations(const GeoDataPlacemark &placemark);
Marble::GeoDataPlacemark m_placemark;
mutable QString m_address; // mutable to allow lazy calculation in the getter
mutable QString m_description;
mutable QString m_website;
mutable QString m_wikipedia;
mutable QString m_openingHours;
mutable QString m_wheelchairInfo;
mutable QString m_wifiAvailable;
mutable QString m_phone;
QStringList m_tags;
RouteRelationModel m_relationModel;
};
}
QML_DECLARE_TYPE(Marble::Placemark)
#endif // MARBLE_DECLARATIVE_PLACEMARK_H
diff --git a/src/lib/marble/declarative/PositionSource.cpp b/src/lib/marble/declarative/PositionSource.cpp
index 680eaf0a5..29b4c40c7 100644
--- a/src/lib/marble/declarative/PositionSource.cpp
+++ b/src/lib/marble/declarative/PositionSource.cpp
@@ -1,163 +1,163 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "PositionSource.h"
#include "MarbleQuickItem.h"
#include "MarbleModel.h"
#include "PluginManager.h"
#include "PositionTracking.h"
#include "PositionProviderPlugin.h"
namespace Marble {
PositionSource::PositionSource( QObject* parent) : QObject( parent ),
m_active( false ),
m_hasPosition( false ),
m_position( 0 ),
- m_marbleQuickItem( 0 ),
+ m_marbleQuickItem( nullptr ),
m_speed( 0.0 )
{
// nothing to do
}
bool PositionSource::active() const
{
return m_active;
}
void PositionSource::setActive( bool active )
{
if ( active != m_active ) {
if ( active ) {
start();
} else if ( m_marbleQuickItem ) {
PositionTracking *tracking = m_marbleQuickItem->model()->positionTracking();
- tracking->setPositionProviderPlugin( 0 );
+ tracking->setPositionProviderPlugin( nullptr );
}
if ( m_hasPosition ) {
m_hasPosition = false;
emit hasPositionChanged();
}
m_active = active;
emit activeChanged();
}
}
QString PositionSource::source() const
{
return m_source;
}
void PositionSource::setSource( const QString &source )
{
if ( source != m_source ) {
m_source = source;
if ( m_hasPosition ) {
m_hasPosition = false;
emit hasPositionChanged();
}
if ( active() ) {
start();
}
emit sourceChanged();
}
}
bool PositionSource::hasPosition() const
{
return m_hasPosition;
}
Coordinate* PositionSource::position()
{
return &m_position;
}
void PositionSource::start()
{
if ( !m_marbleQuickItem ) {
return;
}
const PluginManager* pluginManager = m_marbleQuickItem->model()->pluginManager();
for( const Marble::PositionProviderPlugin *plugin: pluginManager->positionProviderPlugins() ) {
if ( m_source.isEmpty() || plugin->nameId() == m_source ) {
PositionProviderPlugin* instance = plugin->newInstance();
PositionTracking *tracking = m_marbleQuickItem->model()->positionTracking();
tracking->setPositionProviderPlugin( instance );
break;
}
}
}
MarbleQuickItem *PositionSource::map()
{
return m_marbleQuickItem;
}
void PositionSource::setMap( MarbleQuickItem *map )
{
if ( map != m_marbleQuickItem ) {
m_marbleQuickItem = map;
if ( m_marbleQuickItem ) {
connect( m_marbleQuickItem->model()->positionTracking(), SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
this, SLOT(updatePosition()) );
connect( m_marbleQuickItem->model()->positionTracking(), SIGNAL(statusChanged(PositionProviderStatus)),
this, SLOT(updatePosition()) );
emit mapChanged();
}
if ( active() ) {
start();
}
}
}
qreal PositionSource::speed() const
{
return m_speed;
}
void PositionSource::updatePosition()
{
if ( m_marbleQuickItem ) {
bool const hasPosition = m_marbleQuickItem->model()->positionTracking()->status() == Marble::PositionProviderStatusAvailable;
if ( hasPosition ) {
Marble::GeoDataCoordinates position = m_marbleQuickItem->model()->positionTracking()->currentLocation();
m_position.setLongitude( position.longitude( Marble::GeoDataCoordinates::Degree ) );
m_position.setLatitude( position.latitude( Marble::GeoDataCoordinates::Degree ) );
m_position.setAltitude( position.altitude() );
}
m_speed = m_marbleQuickItem->model()->positionTracking()->speed() * Marble::METER2KM / Marble::SEC2HOUR;
emit speedChanged();
if ( hasPosition != m_hasPosition ) {
m_hasPosition = hasPosition;
emit hasPositionChanged();
}
if ( hasPosition ) {
emit positionChanged();
}
}
}
}
#include "moc_PositionSource.cpp"
diff --git a/src/lib/marble/declarative/PositionSource.h b/src/lib/marble/declarative/PositionSource.h
index b9726cd9c..986901b10 100644
--- a/src/lib/marble/declarative/PositionSource.h
+++ b/src/lib/marble/declarative/PositionSource.h
@@ -1,88 +1,88 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_POSITIONSOURCE_H
#define MARBLE_DECLARATIVE_POSITIONSOURCE_H
#include "Coordinate.h"
#include <QObject>
namespace Marble {
class MarbleQuickItem;
class PositionSource : public QObject
{
Q_OBJECT
Q_PROPERTY( MarbleQuickItem* map READ map WRITE setMap NOTIFY mapChanged )
Q_PROPERTY( bool active READ active WRITE setActive NOTIFY activeChanged )
Q_PROPERTY( QString source READ source WRITE setSource NOTIFY sourceChanged )
Q_PROPERTY( bool hasPosition READ hasPosition NOTIFY hasPositionChanged )
Q_PROPERTY( Coordinate* position READ position NOTIFY positionChanged )
Q_PROPERTY( qreal speed READ speed NOTIFY speedChanged )
public:
- explicit PositionSource( QObject* parent = 0);
+ explicit PositionSource( QObject* parent = nullptr);
bool active() const;
void setActive( bool active );
QString source() const;
void setSource( const QString &source );
bool hasPosition() const;
Coordinate* position();
MarbleQuickItem *map();
void setMap( MarbleQuickItem *map );
qreal speed() const;
Q_SIGNALS:
void mapChanged();
void activeChanged();
void sourceChanged();
void hasPositionChanged();
void positionChanged();
void speedChanged();
private Q_SLOTS:
void updatePosition();
private:
void start();
bool m_active;
QString m_source;
bool m_hasPosition;
Coordinate m_position;
QPointer<MarbleQuickItem> m_marbleQuickItem;
qreal m_speed;
};
}
#endif
diff --git a/src/lib/marble/declarative/RouteRelationModel.h b/src/lib/marble/declarative/RouteRelationModel.h
index b7fff768d..7fb06578a 100644
--- a/src/lib/marble/declarative/RouteRelationModel.h
+++ b/src/lib/marble/declarative/RouteRelationModel.h
@@ -1,60 +1,60 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2017 Sergey Popov <sergobot@protonmail.com>
//
#ifndef MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H
#define MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H
#include <QAbstractListModel>
#include <QSet>
#include "GeoDataRelation.h"
namespace Marble {
class RouteRelationModel : public QAbstractListModel
{
Q_OBJECT
public:
enum RouteRelationRoles {
IconSource = Qt::UserRole + 1,
Description,
Network,
RouteColor,
TextColor,
RouteFrom,
RouteTo,
RouteRef,
RouteVia,
OsmId,
RouteVisible
};
- RouteRelationModel(QObject* parent = 0);
+ RouteRelationModel(QObject* parent = nullptr);
void setRelations(const QSet<const GeoDataRelation *> &relations);
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
protected:
QHash<int, QByteArray> roleNames() const override;
private:
static QString svgFile(const QString &path);
QVector<const Marble::GeoDataRelation*> m_relations;
QMap<QString, QString> m_networks;
};
}
#endif // ROUTERELATIONMODEL
diff --git a/src/lib/marble/declarative/RouteRequestModel.cpp b/src/lib/marble/declarative/RouteRequestModel.cpp
index 81d8709ed..43fcbd772 100644
--- a/src/lib/marble/declarative/RouteRequestModel.cpp
+++ b/src/lib/marble/declarative/RouteRequestModel.cpp
@@ -1,144 +1,144 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "RouteRequestModel.h"
#include "routing/RoutingManager.h"
#include "routing/RouteRequest.h"
#include "MarbleMap.h"
#include "MarbleModel.h"
#include "Routing.h"
#include <GeoDataPlacemark.h>
RouteRequestModel::RouteRequestModel( QObject *parent ) :
QAbstractListModel( parent ),
- m_request( 0 ),
- m_routing( 0 )
+ m_request( nullptr ),
+ m_routing( nullptr )
{
QHash<int,QByteArray> roles;
roles[Qt::DisplayRole] = "name";
roles[LongitudeRole] = "longitude";
roles[LatitudeRole] = "latitude";
m_roleNames = roles;
}
RouteRequestModel::~RouteRequestModel()
{
// nothing to do
}
int RouteRequestModel::rowCount ( const QModelIndex &parent ) const
{
if ( !parent.isValid() && m_request ) {
return m_request->size();
}
return 0;
}
QHash<int, QByteArray> RouteRequestModel::roleNames() const
{
return m_roleNames;
}
QVariant RouteRequestModel::headerData ( int section, Qt::Orientation orientation, int role ) const
{
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0 ) {
return QStringLiteral("Waypoint");
}
return QVariant();
}
QVariant RouteRequestModel::data ( const QModelIndex &index, int role ) const
{
if ( index.isValid() && m_request && index.row() >= 0 && index.row() < m_request->size() ) {
switch ( role ) {
case Qt::DisplayRole: {
Marble::GeoDataPlacemark const & placemark = (*m_request)[index.row()];
if (!placemark.name().isEmpty()) {
return placemark.name();
}
if (!placemark.address().isEmpty()) {
return placemark.address();
}
return placemark.coordinate().toString(Marble::GeoDataCoordinates::Decimal).trimmed();
}
case LongitudeRole: return m_request->at( index.row() ).longitude( Marble::GeoDataCoordinates::Degree );
case LatitudeRole: return m_request->at( index.row() ).latitude( Marble::GeoDataCoordinates::Degree );
}
}
return QVariant();
}
Marble::Routing *RouteRequestModel::routing()
{
return m_routing;
}
void RouteRequestModel::setRouting( Marble::Routing *routing )
{
if ( routing != m_routing ) {
m_routing = routing;
updateMap();
connect( m_routing, SIGNAL(marbleMapChanged()), this, SLOT(updateMap()) );
emit routingChanged();
}
}
void RouteRequestModel::updateMap()
{
if ( m_routing && m_routing->marbleMap() ) {
m_request = m_routing->marbleMap()->model()->routingManager()->routeRequest();
connect( m_request, SIGNAL(positionChanged(int,GeoDataCoordinates)),
this, SLOT(updateData(int)), Qt::UniqueConnection );
connect( m_request, SIGNAL(positionAdded(int)),
this, SLOT(updateAfterAddition(int)), Qt::UniqueConnection );
connect( m_request, SIGNAL(positionRemoved(int)),
this, SLOT(updateAfterRemoval(int)), Qt::UniqueConnection );
emit layoutChanged();
}
}
void RouteRequestModel::updateData( int idx )
{
QModelIndex affected = index( idx );
emit dataChanged( affected, affected );
}
void RouteRequestModel::updateAfterRemoval( int idx )
{
beginRemoveRows( QModelIndex(), idx, idx );
removeRow( idx );
endRemoveRows();
emit rowCountChanged();
}
void RouteRequestModel::updateAfterAddition( int idx )
{
beginInsertRows( QModelIndex(), idx, idx );
insertRow( idx );
endInsertRows();
emit rowCountChanged();
}
void RouteRequestModel::setPosition ( int index, qreal longitude, qreal latitude )
{
if ( index >= 0 && index < m_request->size() ) {
m_request->setPosition( index, Marble::GeoDataCoordinates( longitude, latitude, 0.0, Marble::GeoDataCoordinates::Degree ) );
}
}
#include "moc_RouteRequestModel.cpp"
diff --git a/src/lib/marble/declarative/RouteRequestModel.h b/src/lib/marble/declarative/RouteRequestModel.h
index c2b962030..808c45da2 100644
--- a/src/lib/marble/declarative/RouteRequestModel.h
+++ b/src/lib/marble/declarative/RouteRequestModel.h
@@ -1,80 +1,80 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTEREQUESTMODEL_H
#define MARBLE_ROUTEREQUESTMODEL_H
#include <QAbstractListModel>
namespace Marble {
class RouteRequest;
class Routing;
}
class RouteRequestModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY( Marble::Routing* routing READ routing WRITE setRouting NOTIFY routingChanged )
Q_PROPERTY( int count READ rowCount NOTIFY rowCountChanged )
public:
enum RouteRequestModelRoles {
LongitudeRole = Qt::UserRole+1,
LatitudeRole = Qt::UserRole+2
};
/** Constructor */
- explicit RouteRequestModel( QObject *parent = 0 );
+ explicit RouteRequestModel( QObject *parent = nullptr );
/** Destructor */
~RouteRequestModel() override;
// Model querying
/** Overload of QAbstractListModel */
int rowCount ( const QModelIndex &parent = QModelIndex() ) const override;
/** Overload of QAbstractListModel */
QHash<int, QByteArray> roleNames() const override;
/** Overload of QAbstractListModel */
QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
/** Overload of QAbstractListModel */
QVariant data ( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
Marble::Routing *routing();
public Q_SLOTS:
void setRouting( Marble::Routing *routing );
void setPosition ( int index, qreal longitude, qreal latitude );
Q_SIGNALS:
void routingChanged();
void rowCountChanged();
private Q_SLOTS:
void updateMap();
void updateData( int index );
void updateAfterRemoval( int index );
void updateAfterAddition( int index );
private:
Marble::RouteRequest* m_request;
Marble::Routing *m_routing;
QHash<int, QByteArray> m_roleNames;
};
#endif // MARBLE_ROUTEREQUESTMODEL_H
diff --git a/src/lib/marble/declarative/Routing.cpp b/src/lib/marble/declarative/Routing.cpp
index 4ebd316ed..cdba57b0c 100644
--- a/src/lib/marble/declarative/Routing.cpp
+++ b/src/lib/marble/declarative/Routing.cpp
@@ -1,528 +1,528 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "Routing.h"
#include <MarbleMap.h>
#include <MarbleModel.h>
#include "MarbleDirs.h"
#include "routing/AlternativeRoutesModel.h"
#include "routing/RoutingManager.h"
#include "routing/RouteRequest.h"
#include "routing/RoutingProfilesModel.h"
#include <GeoDataLatLonAltBox.h>
#include <GeoPainter.h>
#include <routing/Route.h>
#include <declarative/RouteRequestModel.h>
#include <ViewportParams.h>
#include <PositionTracking.h>
#include <QDebug>
#include <QQmlContext>
#include <QOpenGLPaintDevice>
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
namespace Marble {
class RoutingPrivate
{
public:
explicit RoutingPrivate(QObject * parent = nullptr);
MarbleMap* m_marbleMap;
QMap<QString, Marble::RoutingProfile> m_profiles;
QString m_routingProfile;
QQmlComponent * m_waypointDelegate;
QMap<int,QQuickItem*> m_waypointItems;
RouteRequestModel* m_routeRequestModel;
QObject * m_parent;
QVector<Placemark *> m_searchResultPlacemarks;
QMap<int, QQuickItem*> m_searchResultItems;
};
RoutingPrivate::RoutingPrivate(QObject *parent) :
m_marbleMap( nullptr ),
m_waypointDelegate( nullptr ),
m_routeRequestModel( new RouteRequestModel(parent) ),
m_parent( parent )
{
// nothing to do
}
Routing::Routing( QQuickItem *parent) :
QQuickItem( parent ), d( new RoutingPrivate(this) )
{
setFlag(ItemHasContents, true);
d->m_routeRequestModel->setRouting(this);
connect(d->m_routeRequestModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(updateWaypointItems()));
connect(d->m_routeRequestModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), this, SLOT(updateWaypointItems()));
connect(d->m_routeRequestModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(updateWaypointItems()));
emit routeRequestModelChanged(d->m_routeRequestModel);
}
Routing::~Routing()
{
delete d;
}
QSGNode * Routing::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) {
if (!d->m_marbleMap) {
- return 0;
+ return nullptr;
}
QOpenGLPaintDevice paintDevice(QSize(width(), height()));
Marble::GeoPainter geoPainter(&paintDevice, d->m_marbleMap->viewport(), d->m_marbleMap->mapQuality());
RoutingManager const * const routingManager = d->m_marbleMap->model()->routingManager();
GeoDataLineString const & waypoints = routingManager->routingModel()->route().path();
if (waypoints.isEmpty()) {
- return 0;
+ return nullptr;
}
int const dpi = qMax(paintDevice.logicalDpiX(), paintDevice.logicalDpiY());
qreal const halfWidth = 0.5 * 2.5 * MM2M * M2IN * dpi;
QColor standardRouteColor = routingManager->state() == RoutingManager::Downloading ?
routingManager->routeColorStandard() :
routingManager->routeColorStandard().darker( 200 );
QVector<QPolygonF*> polygons;
geoPainter.polygonsFromLineString( waypoints, polygons);
if (!polygons.isEmpty()) {
delete oldNode;
oldNode = new QSGNode;
for(const QPolygonF* itPolygon: polygons) {
QPolygonF const & polygon = *itPolygon;
QVector<QVector2D> normals;
int segmentCount = itPolygon->size() - 1;
normals.reserve(segmentCount);
for(int i = 0; i < segmentCount; ++i) {
normals << QVector2D(polygon[i+1] - polygon[i]).normalized();
}
QSGGeometryNode* lineNode = new QSGGeometryNode;
QSGGeometry * lineNodeGeo = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), segmentCount*4);
lineNodeGeo->setDrawingMode(GL_TRIANGLE_STRIP);
lineNodeGeo->allocate(segmentCount*4);
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(standardRouteColor);
lineNode->setGeometry(lineNodeGeo);
lineNode->setFlag(QSGNode::OwnsGeometry);
lineNode->setMaterial(material);
lineNode->setFlag(QSGNode::OwnsMaterial);
auto points = lineNodeGeo->vertexDataAsPoint2D();
int k = -1;
for(int i = 0; i < segmentCount; ++i) {
auto const & a = polygon[i];
auto const & b = polygon[i+1];
auto const & n = normals[i];
points[++k].set(a.x() - halfWidth * n.y(), a.y() + halfWidth * n.x());
points[++k].set(a.x() + halfWidth * n.y(), a.y() - halfWidth * n.x());
points[++k].set(b.x() - halfWidth * n.y(), b.y() + halfWidth * n.x());
points[++k].set(b.x() + halfWidth * n.y(), b.y() - halfWidth * n.x());
}
oldNode->appendChildNode(lineNode);
}
} else {
if (oldNode && oldNode->childCount() > 0) {
delete oldNode;
oldNode = new QSGNode;
}
}
qDeleteAll(polygons);
return oldNode;
}
QObject* Routing::waypointModel()
{
- return d->m_marbleMap ? d->m_marbleMap->model()->routingManager()->routingModel() : 0;
+ return d->m_marbleMap ? d->m_marbleMap->model()->routingManager()->routingModel() : nullptr;
}
void Routing::setWaypointDelegate(QQmlComponent *waypointDelegate)
{
if (d->m_waypointDelegate == waypointDelegate) {
return;
}
d->m_waypointDelegate = waypointDelegate;
emit waypointDelegateChanged(waypointDelegate);
}
void Routing::updateWaypointItems()
{
if ( d->m_marbleMap && d->m_routeRequestModel ) {
for (int i = d->m_waypointItems.keys().size(); i < d->m_routeRequestModel->rowCount(); i++ ) {
QQmlContext * context = new QQmlContext( qmlContext( d->m_waypointDelegate ) );
QObject * component = d->m_waypointDelegate->create(context);
QQuickItem* item = qobject_cast<QQuickItem*>( component );
if ( item ) {
item->setParentItem( this );
item->setProperty("index", i);
d->m_waypointItems[i] = item;
} else {
delete component;
}
}
for (int i = d->m_waypointItems.keys().size()-1; i >= d->m_routeRequestModel->rowCount(); i--) {
QQuickItem* item = d->m_waypointItems[i];
item->setProperty("visible", QVariant(false) );
d->m_waypointItems.erase(d->m_waypointItems.find(i));
item->deleteLater();
}
QMap<int, QQuickItem*>::iterator iter = d->m_waypointItems.begin();
while ( iter != d->m_waypointItems.end() ) {
qreal x = 0;
qreal y = 0;
const qreal lon = d->m_routeRequestModel->data(d->m_routeRequestModel->index( iter.key() ), RouteRequestModel::LongitudeRole).toFloat();
const qreal lat = d->m_routeRequestModel->data(d->m_routeRequestModel->index( iter.key() ), RouteRequestModel::LatitudeRole).toFloat();
const bool visible = d->m_marbleMap->viewport()->screenCoordinates(lon * DEG2RAD, lat * DEG2RAD, x, y);
QQuickItem * item = iter.value();
if ( item ) {
item->setVisible( visible );
if ( visible ) {
item->setProperty("xPos", QVariant(x));
item->setProperty("yPos", QVariant(y));
if (iter.key() == 0 && waypointCount() == 1) {
item->setProperty("type", QVariant(QStringLiteral("departure")));
}
else if (iter.key() == d->m_waypointItems.keys().size()-1) {
item->setProperty("type", QVariant(QStringLiteral("destination")));
}
else if (iter.key() > 0) {
item->setProperty("type", QVariant(QStringLiteral("waypoint")));
}
else {
item->setProperty("type", QVariant(QStringLiteral("departure")));
}
}
}
++iter;
}
}
}
int Routing::addSearchResultPlacemark(Placemark *placemark)
{
if ( d->m_marbleMap ) {
for (int i = 0; i < d->m_searchResultItems.size(); i++) {
if (d->m_searchResultPlacemarks[i]->placemark().coordinate() == placemark->placemark().coordinate()) {
return i;
}
}
Placemark * newPlacemark = new Placemark(this);
newPlacemark->setGeoDataPlacemark(placemark->placemark());
d->m_searchResultPlacemarks.push_back(newPlacemark);
}
updateSearchResultPlacemarks();
return d->m_searchResultPlacemarks.size()-1;
}
void Routing::clearSearchResultPlacemarks()
{
for(Placemark* placemark: d->m_searchResultPlacemarks) {
placemark->deleteLater();
}
d->m_searchResultPlacemarks.clear();
for(QQuickItem* item: d->m_searchResultItems) {
item->deleteLater();
}
d->m_searchResultItems.clear();
}
void Routing::updateSearchResultPlacemarks()
{
for (int i = d->m_searchResultItems.keys().size(); i < d->m_searchResultPlacemarks.size(); i++ ) {
QQmlContext * context = new QQmlContext( qmlContext( d->m_waypointDelegate ) );
QObject * component = d->m_waypointDelegate->create(context);
QQuickItem* item = qobject_cast<QQuickItem*>( component );
if ( item ) {
item->setParentItem( this );
item->setProperty("index", i);
item->setProperty("type", QVariant(QStringLiteral("searchResult")));
item->setProperty("placemark", QVariant::fromValue(d->m_searchResultPlacemarks[i]));
d->m_searchResultItems[i] = item;
} else {
delete component;
}
}
for (int i = d->m_searchResultItems.keys().size()-1; i >= d->m_searchResultPlacemarks.size(); i--) {
QQuickItem* item = d->m_searchResultItems[i];
item->setProperty("visible", QVariant(false) );
d->m_searchResultItems.erase(d->m_searchResultItems.find(i));
item->deleteLater();
}
for (int i = 0; i < d->m_searchResultItems.keys().size() && i < d->m_searchResultPlacemarks.size(); i++) {
qreal x = 0;
qreal y = 0;
const qreal lon = d->m_searchResultPlacemarks[i]->placemark().coordinate().longitude();
const qreal lat = d->m_searchResultPlacemarks[i]->placemark().coordinate().latitude();
const bool visible = d->m_marbleMap->viewport()->screenCoordinates(lon, lat, x, y);
QQuickItem * item = d->m_searchResultItems[i];
if ( item ) {
item->setVisible( visible );
if ( visible ) {
item->setProperty("xPos", QVariant(x));
item->setProperty("yPos", QVariant(y));
}
}
}
}
void Routing::setMarbleMap( MarbleMap* marbleMap )
{
d->m_marbleMap = marbleMap;
if ( d->m_marbleMap ) {
connect(d->m_marbleMap, SIGNAL(repaintNeeded(QRegion)), this, SLOT(update()));
RoutingManager* routingManager = d->m_marbleMap->model()->routingManager();
if (routingManager->profilesModel()->rowCount() == 0) {
routingManager->profilesModel()->loadDefaultProfiles();
routingManager->readSettings();
}
connect( routingManager, SIGNAL(stateChanged(RoutingManager::State)), this, SLOT(update()));
connect( routingManager, SIGNAL(routeRetrieved(GeoDataDocument*)), this, SLOT(update()));
connect( routingManager, SIGNAL(stateChanged(RoutingManager::State)),
this, SIGNAL(hasRouteChanged()) );
connect( routingModel(), SIGNAL(currentRouteChanged()),
this, SIGNAL(hasRouteChanged()) );
connect( routingManager, SIGNAL(stateChanged(RoutingManager::State)),
this, SIGNAL(hasWaypointsChanged()) );
connect( routingModel(), SIGNAL(currentRouteChanged()),
this, SIGNAL(hasWaypointsChanged()) );
connect( routingModel(), SIGNAL(currentRouteChanged()),
this, SLOT(update()) );
connect( d->m_marbleMap, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this, SLOT(updateWaypointItems()) );
connect( d->m_marbleMap, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this, SLOT(updateSearchResultPlacemarks()) );
emit routingModelChanged();
QList<Marble::RoutingProfile> profiles = routingManager->profilesModel()->profiles();
if ( profiles.size() == 4 ) {
/** @todo FIXME: Restrictive assumptions on available plugins and certain profile loading implementation */
d->m_profiles[QStringLiteral("Motorcar")] = profiles.at( 0 );
d->m_profiles[QStringLiteral("Bicycle")] = profiles.at( 2 );
d->m_profiles[QStringLiteral("Pedestrian")] = profiles.at( 3 );
} else {
qDebug() << "Unexpected size of default routing profiles: " << profiles.size();
}
}
emit marbleMapChanged();
emit routingProfileChanged();
emit hasRouteChanged();
emit hasWaypointsChanged();
}
MarbleMap *Routing::marbleMap()
{
return d->m_marbleMap;
}
QString Routing::routingProfile() const
{
return d->m_routingProfile;
}
void Routing::setRoutingProfile( const QString & profile )
{
if ( d->m_routingProfile != profile ) {
d->m_routingProfile = profile;
if ( d->m_marbleMap ) {
d->m_marbleMap->model()->routingManager()->routeRequest()->setRoutingProfile( d->m_profiles[profile] );
}
emit routingProfileChanged();
}
}
bool Routing::hasRoute() const
{
return d->m_marbleMap && !d->m_marbleMap->model()->routingManager()->routingModel()->route().path().isEmpty();
}
bool Routing::hasWaypoints() const
{
return d->m_marbleMap && d->m_marbleMap->model()->routingManager()->routingModel()->rowCount() > 0;
}
RoutingModel *Routing::routingModel()
{
- return d->m_marbleMap == 0 ? 0 : d->m_marbleMap->model()->routingManager()->routingModel();
+ return d->m_marbleMap == nullptr ? nullptr : d->m_marbleMap->model()->routingManager()->routingModel();
}
QQmlComponent *Routing::waypointDelegate() const
{
return d->m_waypointDelegate;
}
int Routing::waypointCount() const
{
return d->m_routeRequestModel ? d->m_routeRequestModel->rowCount() : 0;
}
RouteRequestModel *Routing::routeRequestModel()
{
return d->m_routeRequestModel;
}
void Routing::addVia( qreal lon, qreal lat )
{
if ( d->m_marbleMap ) {
Marble::RouteRequest* request = d->m_marbleMap->model()->routingManager()->routeRequest();
request->addVia( Marble::GeoDataCoordinates( lon, lat, 0.0, Marble::GeoDataCoordinates::Degree ) );
updateRoute();
}
}
void Routing::addViaAtIndex(int index, qreal lon, qreal lat)
{
if ( d->m_marbleMap ) {
Marble::RouteRequest * request = d->m_marbleMap->model()->routingManager()->routeRequest();
request->insert(index, Marble::GeoDataCoordinates( lon, lat, 0.0, Marble::GeoDataCoordinates::Degree) );
updateRoute();
}
}
void Routing::addViaByPlacemark(Placemark *placemark)
{
if (d->m_marbleMap && placemark) {
Marble::RouteRequest * request = d->m_marbleMap->model()->routingManager()->routeRequest();
request->addVia(placemark->placemark());
updateRoute();
}
}
void Routing::addViaByPlacemarkAtIndex(int index, Placemark *placemark)
{
if (d->m_marbleMap && placemark) {
Marble::RouteRequest * request = d->m_marbleMap->model()->routingManager()->routeRequest();
request->insert(index, placemark->placemark());
updateRoute();
}
}
void Routing::setVia( int index, qreal lon, qreal lat )
{
if ( index < 0 || index > 200 || !d->m_marbleMap ) {
return;
}
Marble::RouteRequest* request = d->m_marbleMap->model()->routingManager()->routeRequest();
Q_ASSERT( request );
if ( index < request->size() ) {
request->setPosition( index, Marble::GeoDataCoordinates( lon, lat, 0.0, Marble::GeoDataCoordinates::Degree ) );
} else {
for ( int i=request->size(); i<index; ++i ) {
request->append( Marble::GeoDataCoordinates( 0.0, 0.0 ) );
}
request->append( Marble::GeoDataCoordinates( lon, lat, 0.0, Marble::GeoDataCoordinates::Degree ) );
}
updateRoute();
}
void Routing::removeVia( int index )
{
if ( index < 0 || !d->m_marbleMap ) {
return;
}
Marble::RouteRequest* request = d->m_marbleMap->model()->routingManager()->routeRequest();
if ( index < request->size() ) {
d->m_marbleMap->model()->routingManager()->routeRequest()->remove( index );
}
updateRoute();
}
void Routing::swapVias(int index1, int index2)
{
if ( !d->m_marbleMap || !d->m_routeRequestModel ) {
return;
}
Marble::RouteRequest* request = d->m_marbleMap->model()->routingManager()->routeRequest();
request->swap(index1, index2);
updateRoute();
updateWaypointItems();
}
void Routing::reverseRoute()
{
if ( d->m_marbleMap ) {
d->m_marbleMap->model()->routingManager()->reverseRoute();
}
}
void Routing::clearRoute()
{
if ( d->m_marbleMap ) {
d->m_marbleMap->model()->routingManager()->clearRoute();
}
}
void Routing::updateRoute()
{
if ( d->m_marbleMap ) {
d->m_marbleMap->model()->routingManager()->retrieveRoute();
}
}
void Routing::openRoute( const QString &fileName )
{
if ( d->m_marbleMap ) {
Marble::RoutingManager * const routingManager = d->m_marbleMap->model()->routingManager();
/** @todo FIXME: replace the file:// prefix on QML side */
routingManager->clearRoute();
QString target = fileName.startsWith( QLatin1String( "file://" ) ) ? fileName.mid( 7 ) : fileName;
routingManager->loadRoute( target );
const Marble::GeoDataDocument *route = routingManager->alternativeRoutesModel()->currentRoute();
if ( route ) {
const Marble::GeoDataLineString* waypoints = Marble::AlternativeRoutesModel::waypoints( route );
if ( waypoints ) {
GeoDataCoordinates const center = waypoints->latLonAltBox().center();
GeoDataCoordinates::Unit const inDegree = GeoDataCoordinates::Degree;
d->m_marbleMap->centerOn( center.longitude(inDegree), center.latitude(inDegree) );
}
}
}
}
void Routing::saveRoute( const QString &fileName )
{
if ( d->m_marbleMap ) {
/** @todo FIXME: replace the file:// prefix on QML side */
QString target = fileName.startsWith( QLatin1String( "file://" ) ) ? fileName.mid( 7 ) : fileName;
d->m_marbleMap->model()->routingManager()->saveRoute( target );
}
}
}
#include "moc_Routing.cpp"
diff --git a/src/lib/marble/declarative/Routing.h b/src/lib/marble/declarative/Routing.h
index 64f9cb627..68c8daed8 100644
--- a/src/lib/marble/declarative/Routing.h
+++ b/src/lib/marble/declarative/Routing.h
@@ -1,126 +1,126 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_ROUTING_H
#define MARBLE_DECLARATIVE_ROUTING_H
#include <QQuickItem>
#include <Placemark.h>
#include <routing/RoutingModel.h>
#include <RouteRequestModel.h>
namespace Marble {
class MarbleMap;
class RoutingPrivate;
class Routing : public QQuickItem
{
Q_OBJECT
Q_PROPERTY( MarbleMap* marbleMap READ marbleMap WRITE setMarbleMap NOTIFY marbleMapChanged)
Q_PROPERTY( QString routingProfile READ routingProfile WRITE setRoutingProfile NOTIFY routingProfileChanged )
Q_PROPERTY( bool hasRoute READ hasRoute NOTIFY hasRouteChanged )
Q_PROPERTY( bool hasWaypoints READ hasWaypoints NOTIFY hasWaypointsChanged )
Q_PROPERTY( RoutingModel* routingModel READ routingModel NOTIFY routingModelChanged)
Q_PROPERTY( QQmlComponent* waypointDelegate READ waypointDelegate WRITE setWaypointDelegate NOTIFY waypointDelegateChanged)
Q_PROPERTY( RouteRequestModel* routeRequestModel READ routeRequestModel NOTIFY routeRequestModelChanged)
public:
enum RoutingProfile { Motorcar, Bicycle, Pedestrian };
- explicit Routing( QQuickItem* parent = 0 );
+ explicit Routing( QQuickItem* parent = nullptr );
~Routing() override;
void setMarbleMap( MarbleMap* marbleMap );
MarbleMap *marbleMap();
QString routingProfile() const;
void setRoutingProfile( const QString & profile );
bool hasRoute() const;
bool hasWaypoints() const;
RoutingModel *routingModel();
QQmlComponent * waypointDelegate() const;
Q_INVOKABLE int waypointCount() const;
RouteRequestModel* routeRequestModel();
public Q_SLOTS:
void addVia( qreal lon, qreal lat );
void addViaAtIndex( int index, qreal lon, qreal lat );
void addViaByPlacemark( Placemark * placemark );
void addViaByPlacemarkAtIndex( int index, Placemark * placemark );
void setVia( int index, qreal lon, qreal lat );
void removeVia( int index );
void swapVias( int index1, int index2 );
void reverseRoute();
void clearRoute();
void updateRoute();
void openRoute( const QString &filename );
void saveRoute( const QString &filename );
QObject* waypointModel();
void setWaypointDelegate(QQmlComponent * waypointDelegate);
int addSearchResultPlacemark( Placemark * placemark );
void clearSearchResultPlacemarks();
Q_SIGNALS:
void marbleMapChanged();
void routingProfileChanged();
void hasRouteChanged();
void hasWaypointsChanged();
void routingModelChanged();
void waypointDelegateChanged(QQmlComponent * waypointDelegate);
void routeRequestModelChanged(RouteRequestModel* routeRequestModel);
protected:
// Implements QQuickItem interface
QSGNode * updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override;
private Q_SLOTS:
void updateWaypointItems();
void updateSearchResultPlacemarks();
private:
RoutingPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/declarative/SearchBackend.h b/src/lib/marble/declarative/SearchBackend.h
index b1b574fd5..6a23bc558 100644
--- a/src/lib/marble/declarative/SearchBackend.h
+++ b/src/lib/marble/declarative/SearchBackend.h
@@ -1,70 +1,70 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Gábor Péterffy <peterffy95@gmail.com>
//
#ifndef MARBLE_SEARCHBACKEND_H
#define MARBLE_SEARCHBACKEND_H
#include <QObject>
#include <QSortFilterProxyModel>
#include "MarbleQuickItem.h"
#include "MarblePlacemarkModel.h"
#include "Placemark.h"
class QCompleter;
namespace Marble
{
class SearchRunnerManager;
class SearchBackend : public QObject
{
Q_OBJECT
Q_PROPERTY(QObject *marbleQuickItem READ marbleQuickItem WRITE setMarbleQuickItem NOTIFY marbleQuickItemChanged)
Q_PROPERTY(MarblePlacemarkModel *completionModel READ completionModel NOTIFY completionModelChanged)
Q_PROPERTY(Placemark* selectedPlacemark READ selectedPlacemark NOTIFY selectedPlacemarkChanged)
public:
- explicit SearchBackend(QObject *parent = 0);
+ explicit SearchBackend(QObject *parent = nullptr);
Q_INVOKABLE void search(const QString &place);
Q_INVOKABLE void setCompletionPrefix(const QString &prefix);
QObject *marbleQuickItem();
MarblePlacemarkModel *completionModel();
const QObject* marbleQuickItem() const;
Placemark* selectedPlacemark();
Q_SIGNALS:
void marbleQuickItemChanged(QObject *marbleQuickItem);
void completionModelChanged(MarblePlacemarkModel *model);
void searchResultChanged(MarblePlacemarkModel *model);
void searchFinished(const QString &searchTerm);
void selectedPlacemarkChanged(Placemark * selectedPlacemark);
public Q_SLOTS:
Q_INVOKABLE void setSelectedPlacemark(int placemarkIndex);
void setMarbleQuickItem(QObject *marbleQuickItem);
void updateSearchResult(QAbstractItemModel *result);
private:
static GeoDataPlacemark *placemarkFromQVariant(const QVariant &data);
QSortFilterProxyModel m_model;
SearchRunnerManager *m_searchManager;
MarbleQuickItem *m_marbleQuickItem;
MarblePlacemarkModel *m_placemarkModel;
QCompleter *m_completer;
MarblePlacemarkModel *m_completionModel;
QVector<GeoDataPlacemark*> *m_completionContainer;
Placemark m_selectedPlacemark;
QString m_lastSuccessfulCompletion;
};
}
#endif
diff --git a/src/lib/marble/declarative/Tracking.cpp b/src/lib/marble/declarative/Tracking.cpp
index bd089e7f8..ae04ad482 100644
--- a/src/lib/marble/declarative/Tracking.cpp
+++ b/src/lib/marble/declarative/Tracking.cpp
@@ -1,304 +1,304 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "Tracking.h"
#include "MarbleQuickItem.h"
#include "MarbleModel.h"
#include "PositionTracking.h"
#include "RenderPlugin.h"
#include "ViewportParams.h"
#include "AutoNavigation.h"
namespace Marble {
Tracking::Tracking( QObject* parent) : QObject( parent ),
m_showTrack( true ),
- m_positionSource( 0 ),
- m_positionMarker( 0 ),
- m_marbleQuickItem( 0 ),
+ m_positionSource( nullptr ),
+ m_positionMarker( nullptr ),
+ m_marbleQuickItem( nullptr ),
m_hasLastKnownPosition( false ),
- m_autoNavigation( 0 ),
+ m_autoNavigation( nullptr ),
m_positionMarkerType( None )
{
connect( &m_lastKnownPosition, SIGNAL(longitudeChanged()), this, SLOT(setHasLastKnownPosition()) );
connect( &m_lastKnownPosition, SIGNAL(latitudeChanged()), this, SLOT(setHasLastKnownPosition()) );
}
bool Tracking::showTrack() const
{
return m_showTrack;
}
void Tracking::setShowTrack( bool show )
{
if ( show != m_showTrack ) {
if ( m_marbleQuickItem ) {
m_marbleQuickItem->model()->positionTracking()->setTrackVisible( show );
m_marbleQuickItem->update();
}
m_showTrack = show;
emit showTrackChanged();
}
}
PositionSource* Tracking::positionSource()
{
return m_positionSource;
}
void Tracking::setPositionSource( PositionSource* source )
{
if ( source != m_positionSource ) {
m_positionSource = source;
if ( source ) {
connect( source, SIGNAL(positionChanged()),
this, SLOT(updatePositionMarker()) );
connect( source, SIGNAL(positionChanged()),
this, SLOT(updateLastKnownPosition()) );
connect( source, SIGNAL(hasPositionChanged()),
this, SLOT(updatePositionMarker()) );
connect( source, SIGNAL(positionChanged()),
this, SIGNAL(distanceChanged()) );
}
emit positionSourceChanged();
}
}
MarbleQuickItem* Tracking::map()
{
return m_marbleQuickItem;
}
void Tracking::setMap( MarbleQuickItem* item )
{
if ( item != m_marbleQuickItem ) {
m_marbleQuickItem = item;
if ( m_marbleQuickItem ) {
m_marbleQuickItem->model()->positionTracking()->setTrackVisible( showTrack() );
setShowPositionMarkerPlugin( m_positionMarkerType == Arrow );
connect( m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()), this, SLOT(updatePositionMarker()) );
connect( m_marbleQuickItem, SIGNAL(mapThemeChanged()), this, SLOT(updatePositionMarker()) );
}
emit mapChanged();
}
}
void Tracking::setPositionMarker( QObject* marker )
{
if ( marker != m_positionMarker ) {
m_positionMarker = marker;
emit positionMarkerChanged();
}
}
QObject* Tracking::positionMarker()
{
return m_positionMarker;
}
void Tracking::updatePositionMarker()
{
if ( m_marbleQuickItem && m_positionMarker && m_positionMarkerType == Circle ) {
- Coordinate* position = 0;
+ Coordinate* position = nullptr;
bool visible = (m_marbleQuickItem->model()->planetId() == QLatin1String("earth"));
if ( m_positionSource && m_positionSource->hasPosition() ) {
position = m_positionSource->position();
} else if ( hasLastKnownPosition() ) {
position = lastKnownPosition();
} else {
visible = false;
}
qreal x(0), y(0);
if ( position ) {
Marble::GeoDataCoordinates const pos( position->longitude(), position->latitude(), 0.0, GeoDataCoordinates::Degree );
visible = visible && m_marbleQuickItem->map()->viewport()->screenCoordinates( pos.longitude(), pos.latitude(), x, y );
QQuickItem* item = qobject_cast<QQuickItem*>( m_positionMarker );
if ( item ) {
item->setVisible( visible );
if ( visible ) {
item->setX( x - item->width() / 2.0 );
item->setY( y - item->height() / 2.0 );
}
}
}
} else if ( m_positionMarkerType != Circle ) {
QQuickItem* item = qobject_cast<QQuickItem*>( m_positionMarker );
if ( item ) {
item->setVisible( false );
}
}
}
void Tracking::updateLastKnownPosition()
{
if ( m_positionSource && m_positionSource->hasPosition() ) {
setLastKnownPosition( m_positionSource->position() );
}
}
void Tracking::setHasLastKnownPosition()
{
if ( !m_hasLastKnownPosition ) {
m_hasLastKnownPosition = true;
emit hasLastKnownPositionChanged();
}
}
void Tracking::setShowPositionMarkerPlugin( bool visible )
{
if ( m_marbleQuickItem ) {
QList<RenderPlugin*> const renderPlugins = m_marbleQuickItem->map()->renderPlugins();
for( RenderPlugin* renderPlugin: renderPlugins ) {
Q_ASSERT( renderPlugin );
if (renderPlugin->nameId() == QLatin1String("positionMarker")) {
renderPlugin->setEnabled( true );
renderPlugin->setVisible( visible );
}
}
}
}
bool Tracking::hasLastKnownPosition() const
{
return m_hasLastKnownPosition;
}
Coordinate * Tracking::lastKnownPosition()
{
return &m_lastKnownPosition;
}
void Tracking::setLastKnownPosition( Coordinate* lastKnownPosition )
{
if ( lastKnownPosition && *lastKnownPosition != m_lastKnownPosition ) {
m_lastKnownPosition.setCoordinates( lastKnownPosition->coordinates() );
emit lastKnownPositionChanged();
}
}
bool Tracking::autoCenter() const
{
if ( m_autoNavigation ) {
return m_autoNavigation->recenterMode() != Marble::AutoNavigation::DontRecenter;
}
return false;
}
void Tracking::setAutoCenter( bool enabled )
{
if ( autoCenter() != enabled ) {
if ( enabled && !m_autoNavigation && m_marbleQuickItem ) {
m_autoNavigation = new Marble::AutoNavigation( m_marbleQuickItem->model(), m_marbleQuickItem->map()->viewport(), this );
connect( m_autoNavigation, SIGNAL(zoomIn(FlyToMode)),
m_marbleQuickItem, SLOT(zoomIn()) );
connect( m_autoNavigation, SIGNAL(zoomOut(FlyToMode)),
m_marbleQuickItem, SLOT(zoomOut()) );
connect( m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates,bool)),
m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)) );
connect( m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()),
m_autoNavigation, SLOT(inhibitAutoAdjustments()) );
}
if ( m_autoNavigation ) {
m_autoNavigation->setRecenter( Marble::AutoNavigation::RecenterOnBorder );
}
emit autoCenterChanged();
}
}
bool Tracking::autoZoom() const
{
if ( m_autoNavigation ) {
return m_autoNavigation->autoZoom();
}
return false;
}
void Tracking::setAutoZoom( bool enabled )
{
if ( autoZoom() != enabled ) {
if ( enabled && !m_autoNavigation && m_marbleQuickItem ) {
m_autoNavigation = new Marble::AutoNavigation( m_marbleQuickItem->model(), m_marbleQuickItem->map()->viewport(), this );
connect( m_autoNavigation, SIGNAL(zoomIn(FlyToMode)),
m_marbleQuickItem, SLOT(zoomIn()) );
connect( m_autoNavigation, SIGNAL(zoomOut(FlyToMode)),
m_marbleQuickItem, SLOT(zoomOut()) );
connect( m_autoNavigation, SIGNAL(centerOn(GeoDataCoordinates,bool)),
m_marbleQuickItem, SLOT(centerOn(GeoDataCoordinates)) );
connect( m_marbleQuickItem, SIGNAL(visibleLatLonAltBoxChanged()),
m_autoNavigation, SLOT(inhibitAutoAdjustments()) );
}
if ( m_autoNavigation ) {
m_autoNavigation->setAutoZoom( enabled );
}
emit autoZoomChanged();
}
}
Tracking::PositionMarkerType Tracking::positionMarkerType() const
{
return m_positionMarkerType;
}
void Tracking::setPositionMarkerType( Tracking::PositionMarkerType type )
{
setShowPositionMarkerPlugin( type == Arrow );
if ( type != m_positionMarkerType ) {
m_positionMarkerType = type;
emit positionMarkerTypeChanged();
}
}
double Tracking::distance() const
{
return m_marbleQuickItem ? m_marbleQuickItem->model()->positionTracking()->length( m_marbleQuickItem->model()->planetRadius() ) : 0.0;
}
void Tracking::saveTrack( const QString &fileName )
{
if ( m_marbleQuickItem ) {
/** @todo FIXME: replace the file:// prefix on QML side */
QString target = fileName.startsWith( QLatin1String( "file://" ) ) ? fileName.mid( 7 ) : fileName;
m_marbleQuickItem->model()->positionTracking()->saveTrack( target );
}
}
void Tracking::openTrack(const QString &fileName)
{
if ( m_marbleQuickItem ) {
/** @todo FIXME: replace the file:// prefix on QML side */
QString target = fileName.startsWith( QLatin1String( "file://" ) ) ? fileName.mid( 7 ) : fileName;
m_marbleQuickItem->model()->addGeoDataFile( target );
}
}
void Tracking::clearTrack()
{
if ( m_marbleQuickItem ) {
m_marbleQuickItem->model()->positionTracking()->clearTrack();
}
}
}
#include "moc_Tracking.cpp"
diff --git a/src/lib/marble/declarative/Tracking.h b/src/lib/marble/declarative/Tracking.h
index 35e2b63b6..507f91830 100644
--- a/src/lib/marble/declarative/Tracking.h
+++ b/src/lib/marble/declarative/Tracking.h
@@ -1,141 +1,141 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_DECLARATIVE_TRACKING_H
#define MARBLE_DECLARATIVE_TRACKING_H
#include "PositionSource.h"
#include <QObject>
namespace Marble {
class AutoNavigation;
class MarbleQuickItem;
class Tracking : public QObject
{
Q_OBJECT
Q_ENUMS( PositionMarkerType )
Q_PROPERTY( MarbleQuickItem* map READ map WRITE setMap NOTIFY mapChanged )
Q_PROPERTY( bool showTrack READ showTrack WRITE setShowTrack NOTIFY showTrackChanged )
Q_PROPERTY( bool autoCenter READ autoCenter WRITE setAutoCenter NOTIFY autoCenterChanged )
Q_PROPERTY( bool autoZoom READ autoZoom WRITE setAutoZoom NOTIFY autoZoomChanged )
Q_PROPERTY( PositionSource* positionSource READ positionSource WRITE setPositionSource NOTIFY positionSourceChanged )
Q_PROPERTY( QObject* positionMarker READ positionMarker WRITE setPositionMarker NOTIFY positionMarkerChanged )
Q_PROPERTY( bool hasLastKnownPosition READ hasLastKnownPosition NOTIFY hasLastKnownPositionChanged )
Q_PROPERTY( Coordinate* lastKnownPosition READ lastKnownPosition WRITE setLastKnownPosition NOTIFY lastKnownPositionChanged )
Q_PROPERTY( PositionMarkerType positionMarkerType READ positionMarkerType WRITE setPositionMarkerType NOTIFY positionMarkerTypeChanged )
Q_PROPERTY( double distance READ distance NOTIFY distanceChanged )
public:
enum PositionMarkerType {
None,
Circle,
Arrow
};
- explicit Tracking( QObject* parent = 0 );
+ explicit Tracking( QObject* parent = nullptr );
bool showTrack() const;
void setShowTrack( bool show );
PositionSource* positionSource();
void setPositionSource( PositionSource* source );
QObject* positionMarker();
void setPositionMarker( QObject* marker );
MarbleQuickItem* map();
void setMap( MarbleQuickItem* widget );
bool hasLastKnownPosition() const;
Coordinate *lastKnownPosition();
void setLastKnownPosition( Coordinate* lastKnownPosition );
bool autoCenter() const;
void setAutoCenter( bool enabled );
bool autoZoom() const;
void setAutoZoom( bool enabled );
PositionMarkerType positionMarkerType() const;
void setPositionMarkerType( PositionMarkerType type );
double distance() const;
public Q_SLOTS:
void saveTrack( const QString &fileName );
void openTrack( const QString &fileName );
void clearTrack();
Q_SIGNALS:
void mapChanged();
void showTrackChanged();
void positionSourceChanged();
void positionMarkerChanged();
void hasLastKnownPositionChanged();
void lastKnownPositionChanged();
void autoCenterChanged();
void autoZoomChanged();
void positionMarkerTypeChanged();
void distanceChanged();
private Q_SLOTS:
void updatePositionMarker();
void updateLastKnownPosition();
void setHasLastKnownPosition();
private:
void setShowPositionMarkerPlugin( bool visible );
bool m_showTrack;
PositionSource* m_positionSource;
QObject* m_positionMarker;
MarbleQuickItem* m_marbleQuickItem;
bool m_hasLastKnownPosition;
Coordinate m_lastKnownPosition;
Marble::AutoNavigation* m_autoNavigation;
PositionMarkerType m_positionMarkerType;
};
}
#endif
diff --git a/src/lib/marble/geodata/data/GeoDataAnimatedUpdate.cpp b/src/lib/marble/geodata/data/GeoDataAnimatedUpdate.cpp
index e6897177b..59d5cab56 100644
--- a/src/lib/marble/geodata/data/GeoDataAnimatedUpdate.cpp
+++ b/src/lib/marble/geodata/data/GeoDataAnimatedUpdate.cpp
@@ -1,115 +1,115 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "GeoDataAnimatedUpdate.h"
#include "GeoDataUpdate.h"
#include "GeoDataTypes.h"
#include "GeoDataAbstractView.h"
namespace Marble {
class GeoDataAnimatedUpdatePrivate
{
public:
double m_duration;
double m_delayedStart;
GeoDataUpdate* m_update;
GeoDataAnimatedUpdatePrivate();
};
GeoDataAnimatedUpdatePrivate::GeoDataAnimatedUpdatePrivate() :
- m_duration( 0.0 ), m_delayedStart( 0 ), m_update( 0 )
+ m_duration( 0.0 ), m_delayedStart( 0 ), m_update( nullptr )
{
}
GeoDataAnimatedUpdate::GeoDataAnimatedUpdate() : d( new GeoDataAnimatedUpdatePrivate )
{
}
GeoDataAnimatedUpdate::GeoDataAnimatedUpdate( const Marble::GeoDataAnimatedUpdate &other ) :
GeoDataTourPrimitive( other ), d( new GeoDataAnimatedUpdatePrivate( *other.d ) )
{
}
GeoDataAnimatedUpdate &GeoDataAnimatedUpdate::operator=( const GeoDataAnimatedUpdate &other )
{
GeoDataTourPrimitive::operator=( other );
*d = *other.d;
return *this;
}
bool GeoDataAnimatedUpdate::operator==(const GeoDataAnimatedUpdate& other) const
{
if( ( !d->m_update && other.d->m_update ) || ( d->m_update && !other.d->m_update) ){
return false;
} else if( d->m_update && other.d->m_update ){
return d->m_duration == other.d->m_duration && *(d->m_update) == *(other.d->m_update);
}
return d->m_duration == other.d->m_duration;
}
bool GeoDataAnimatedUpdate::operator!=(const GeoDataAnimatedUpdate& other) const
{
return !this->operator==(other);
}
GeoDataAnimatedUpdate::~GeoDataAnimatedUpdate()
{
delete d;
}
const char *GeoDataAnimatedUpdate::nodeType() const
{
return GeoDataTypes::GeoDataAnimatedUpdateType;
}
const GeoDataUpdate* GeoDataAnimatedUpdate::update() const
{
return d->m_update;
}
GeoDataUpdate* GeoDataAnimatedUpdate::update()
{
return d->m_update;
}
void GeoDataAnimatedUpdate::setUpdate( GeoDataUpdate *update )
{
delete d->m_update;
d->m_update = update;
if ( d->m_update ) {
d->m_update->setParent( this );
}
}
double GeoDataAnimatedUpdate::duration() const
{
return d->m_duration;
}
void GeoDataAnimatedUpdate::setDuration( double duration )
{
d->m_duration = duration;
}
double GeoDataAnimatedUpdate::delayedStart() const
{
return d->m_delayedStart;
}
void GeoDataAnimatedUpdate::setDelayedStart( double delayedStart )
{
d->m_delayedStart = delayedStart;
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataCoordinates.cpp b/src/lib/marble/geodata/data/GeoDataCoordinates.cpp
index 250daef96..3954d560e 100644
--- a/src/lib/marble/geodata/data/GeoDataCoordinates.cpp
+++ b/src/lib/marble/geodata/data/GeoDataCoordinates.cpp
@@ -1,1179 +1,1179 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007-2008 Inge Wallin <ingwa@kde.org>
// Copyright 2008 Patrick Spendrin <ps_ml@gmx.de>
// Copyright 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2015 Alejandro Garcia Montoro <alejandro.garciamontoro@gmail.com>
//
#include "GeoDataCoordinates.h"
#include "GeoDataCoordinates_p.h"
#include "LonLatParser_p.h"
#include <qmath.h>
#include <QDataStream>
#include <QPointF>
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "MarbleMath.h"
#include "Quaternion.h"
namespace Marble
{
const qreal GeoDataCoordinatesPrivate::sm_semiMajorAxis = 6378137.0;
const qreal GeoDataCoordinatesPrivate::sm_semiMinorAxis = 6356752.314;
const qreal GeoDataCoordinatesPrivate::sm_eccentricitySquared = 6.69437999013e-03;
const qreal GeoDataCoordinatesPrivate::sm_utmScaleFactor = 0.9996;
GeoDataCoordinates::Notation GeoDataCoordinates::s_notation = GeoDataCoordinates::DMS;
const GeoDataCoordinates GeoDataCoordinates::null = GeoDataCoordinates( 0, 0, 0 ); // don't use default constructor!
GeoDataCoordinates::GeoDataCoordinates( qreal _lon, qreal _lat, qreal _alt, GeoDataCoordinates::Unit unit, int _detail )
: d( new GeoDataCoordinatesPrivate( _lon, _lat, _alt, unit, _detail ) )
{
d->ref.ref();
}
/* simply copy the d pointer
* it will be replaced in the detach function instead
*/
GeoDataCoordinates::GeoDataCoordinates( const GeoDataCoordinates& other )
: d( other.d )
{
d->ref.ref();
}
/* simply copy null's d pointer
* it will be replaced in the detach function
*/
GeoDataCoordinates::GeoDataCoordinates()
: d( null.d )
{
d->ref.ref();
}
/*
* only delete the private d pointer if the number of references is 0
* remember that all copies share the same d pointer!
*/
GeoDataCoordinates::~GeoDataCoordinates()
{
delete d->m_q;
- d->m_q = 0;
+ d->m_q = nullptr;
if (!d->ref.deref())
delete d;
#ifdef DEBUG_GEODATA
// mDebug() << "delete coordinates";
#endif
}
bool GeoDataCoordinates::isValid() const
{
return d != null.d;
}
/*
* if only one copy exists, return
* else make a new private d pointer object and assign the values of the current
* one to it
* at the end, if the number of references thus reaches 0 delete it
* this state shouldn't happen, but if it does, we have to clean up behind us.
*/
void GeoDataCoordinates::detach()
{
delete d->m_q;
- d->m_q = 0;
+ d->m_q = nullptr;
if(d->ref.load() == 1) {
return;
}
GeoDataCoordinatesPrivate *new_d = new GeoDataCoordinatesPrivate( *d );
if (!d->ref.deref()) {
delete d;
}
d = new_d;
d->ref.ref();
}
/*
* call detach() at the start of all non-static, non-const functions
*/
void GeoDataCoordinates::set( qreal _lon, qreal _lat, qreal _alt, GeoDataCoordinates::Unit unit )
{
detach();
d->m_altitude = _alt;
switch( unit ){
default:
case Radian:
d->m_lon = _lon;
d->m_lat = _lat;
break;
case Degree:
d->m_lon = _lon * DEG2RAD;
d->m_lat = _lat * DEG2RAD;
break;
}
}
/*
* call detach() at the start of all non-static, non-const functions
*/
void GeoDataCoordinates::setLongitude( qreal _lon, GeoDataCoordinates::Unit unit )
{
detach();
switch( unit ){
default:
case Radian:
d->m_lon = _lon;
break;
case Degree:
d->m_lon = _lon * DEG2RAD;
break;
}
}
/*
* call detach() at the start of all non-static, non-const functions
*/
void GeoDataCoordinates::setLatitude( qreal _lat, GeoDataCoordinates::Unit unit )
{
detach();
switch( unit ){
case Radian:
d->m_lat = _lat;
break;
case Degree:
d->m_lat = _lat * DEG2RAD;
break;
}
}
void GeoDataCoordinates::geoCoordinates( qreal& lon, qreal& lat,
GeoDataCoordinates::Unit unit ) const
{
switch ( unit )
{
default:
case Radian:
lon = d->m_lon;
lat = d->m_lat;
break;
case Degree:
lon = d->m_lon * RAD2DEG;
lat = d->m_lat * RAD2DEG;
break;
}
}
void GeoDataCoordinates::geoCoordinates(qreal &lon, qreal &lat) const
{
lon = d->m_lon;
lat = d->m_lat;
}
void GeoDataCoordinates::geoCoordinates( qreal& lon, qreal& lat, qreal& alt,
GeoDataCoordinates::Unit unit ) const
{
geoCoordinates( lon, lat, unit );
alt = d->m_altitude;
}
void GeoDataCoordinates::geoCoordinates(qreal &lon, qreal &lat, qreal &alt) const
{
lon = d->m_lon;
lat = d->m_lat;
alt = d->m_altitude;
}
qreal GeoDataCoordinates::longitude( GeoDataCoordinates::Unit unit ) const
{
switch ( unit )
{
default:
case Radian:
return d->m_lon;
case Degree:
return d->m_lon * RAD2DEG;
}
}
qreal GeoDataCoordinates::longitude() const
{
return d->m_lon;
}
qreal GeoDataCoordinates::latitude( GeoDataCoordinates::Unit unit ) const
{
switch ( unit )
{
default:
case Radian:
return d->m_lat;
case Degree:
return d->m_lat * RAD2DEG;
}
}
qreal GeoDataCoordinates::latitude() const
{
return d->m_lat;
}
//static
GeoDataCoordinates::Notation GeoDataCoordinates::defaultNotation()
{
return s_notation;
}
//static
void GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::Notation notation )
{
s_notation = notation;
}
//static
qreal GeoDataCoordinates::normalizeLon( qreal lon, GeoDataCoordinates::Unit unit )
{
qreal halfCircle;
if ( unit == GeoDataCoordinates::Radian ) {
halfCircle = M_PI;
}
else {
halfCircle = 180;
}
if ( lon > halfCircle ) {
int cycles = (int)( ( lon + halfCircle ) / ( 2 * halfCircle ) );
return lon - ( cycles * 2 * halfCircle );
}
if ( lon < -halfCircle ) {
int cycles = (int)( ( lon - halfCircle ) / ( 2 * halfCircle ) );
return lon - ( cycles * 2 * halfCircle );
}
return lon;
}
//static
qreal GeoDataCoordinates::normalizeLat( qreal lat, GeoDataCoordinates::Unit unit )
{
qreal halfCircle;
if ( unit == GeoDataCoordinates::Radian ) {
halfCircle = M_PI;
}
else {
halfCircle = 180;
}
if ( lat > ( halfCircle / 2.0 ) ) {
int cycles = (int)( ( lat + halfCircle ) / ( 2 * halfCircle ) );
qreal temp;
if( cycles == 0 ) { // pi/2 < lat < pi
temp = halfCircle - lat;
} else {
temp = lat - ( cycles * 2 * halfCircle );
}
if ( temp > ( halfCircle / 2.0 ) ) {
return ( halfCircle - temp );
}
if ( temp < ( -halfCircle / 2.0 ) ) {
return ( -halfCircle - temp );
}
return temp;
}
if ( lat < ( -halfCircle / 2.0 ) ) {
int cycles = (int)( ( lat - halfCircle ) / ( 2 * halfCircle ) );
qreal temp;
if( cycles == 0 ) {
temp = -halfCircle - lat;
} else {
temp = lat - ( cycles * 2 * halfCircle );
}
if ( temp > ( +halfCircle / 2.0 ) ) {
return ( +halfCircle - temp );
}
if ( temp < ( -halfCircle / 2.0 ) ) {
return ( -halfCircle - temp );
}
return temp;
}
return lat;
}
//static
void GeoDataCoordinates::normalizeLonLat( qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit )
{
qreal halfCircle;
if ( unit == GeoDataCoordinates::Radian ) {
halfCircle = M_PI;
}
else {
halfCircle = 180;
}
if ( lon > +halfCircle ) {
int cycles = (int)( ( lon + halfCircle ) / ( 2 * halfCircle ) );
lon = lon - ( cycles * 2 * halfCircle );
}
if ( lon < -halfCircle ) {
int cycles = (int)( ( lon - halfCircle ) / ( 2 * halfCircle ) );
lon = lon - ( cycles * 2 * halfCircle );
}
if ( lat > ( +halfCircle / 2.0 ) ) {
int cycles = (int)( ( lat + halfCircle ) / ( 2 * halfCircle ) );
qreal temp;
if( cycles == 0 ) { // pi/2 < lat < pi
temp = halfCircle - lat;
} else {
temp = lat - ( cycles * 2 * halfCircle );
}
if ( temp > ( +halfCircle / 2.0 ) ) {
lat = +halfCircle - temp;
}
if ( temp < ( -halfCircle / 2.0 ) ) {
lat = -halfCircle - temp;
}
lat = temp;
if( lon > 0 ) {
lon = -halfCircle + lon;
} else {
lon = halfCircle + lon;
}
}
if ( lat < ( -halfCircle / 2.0 ) ) {
int cycles = (int)( ( lat - halfCircle ) / ( 2 * halfCircle ) );
qreal temp;
if( cycles == 0 ) {
temp = -halfCircle - lat;
} else {
temp = lat - ( cycles * 2 * halfCircle );
}
if ( temp > ( +halfCircle / 2.0 ) ) {
lat = +halfCircle - temp;
}
if ( temp < ( -halfCircle / 2.0 ) ) {
lat = -halfCircle - temp;
}
lat = temp;
if( lon > 0 ) {
lon = -halfCircle + lon;
} else {
lon = halfCircle + lon;
}
}
return;
}
GeoDataCoordinates GeoDataCoordinates::fromString( const QString& string, bool& successful )
{
LonLatParser parser;
successful = parser.parse(string);
if (successful) {
return GeoDataCoordinates( parser.lon(), parser.lat(), 0, GeoDataCoordinates::Degree );
} else {
return GeoDataCoordinates();
}
}
QString GeoDataCoordinates::toString() const
{
return GeoDataCoordinates::toString( s_notation );
}
QString GeoDataCoordinates::toString( GeoDataCoordinates::Notation notation, int precision ) const
{
QString coordString;
if( notation == GeoDataCoordinates::UTM ){
int zoneNumber = GeoDataCoordinatesPrivate::lonLatToZone(d->m_lon, d->m_lat);
// Handle lack of UTM zone number in the poles
const QString zoneString = (zoneNumber > 0) ? QString::number(zoneNumber) : QString();
QString bandString = GeoDataCoordinatesPrivate::lonLatToLatitudeBand(d->m_lon, d->m_lat);
QString eastingString = QString::number(GeoDataCoordinatesPrivate::lonLatToEasting(d->m_lon, d->m_lat), 'f', 2);
QString northingString = QString::number(GeoDataCoordinatesPrivate::lonLatToNorthing(d->m_lon, d->m_lat), 'f', 2);
return QString("%1%2 %3 m E, %4 m N").arg(zoneString, bandString, eastingString, northingString);
}
else{
coordString = lonToString( d->m_lon, notation, Radian, precision )
+ QLatin1String(", ")
+ latToString( d->m_lat, notation, Radian, precision );
}
return coordString;
}
QString GeoDataCoordinates::lonToString( qreal lon, GeoDataCoordinates::Notation notation,
GeoDataCoordinates::Unit unit,
int precision,
char format )
{
if( notation == GeoDataCoordinates::UTM ){
/**
* @FIXME: UTM needs lon + lat to know zone number and easting
* By now, this code returns the zone+easting of the point
* (lon, equator), but this can differ a lot at different locations
* See bug 347536 https://bugs.kde.org/show_bug.cgi?id=347536
*/
qreal lonRad = ( unit == Radian ) ? lon : lon * DEG2RAD;
int zoneNumber = GeoDataCoordinatesPrivate::lonLatToZone(lonRad, 0);
// Handle lack of UTM zone number in the poles
QString result = (zoneNumber > 0) ? QString::number(zoneNumber) : QString();
if(precision > 0){
QString eastingString = QString::number( GeoDataCoordinatesPrivate::lonLatToEasting(lonRad, 0), 'f', 2 );
result += QString(" %1 m E").arg(eastingString);
}
return result;
}
QString weString = ( lon < 0 ) ? tr("W") : tr("E");
QString lonString;
qreal lonDegF = ( unit == Degree ) ? fabs( lon ) : fabs( (qreal)(lon) * RAD2DEG );
// Take care of -1 case
precision = ( precision < 0 ) ? 5 : precision;
if ( notation == DMS || notation == DM ) {
int lonDeg = (int) lonDegF;
qreal lonMinF = 60 * (lonDegF - lonDeg);
int lonMin = (int) lonMinF;
qreal lonSecF = 60 * (lonMinF - lonMin);
int lonSec = (int) lonSecF;
// Adjustment for fuzziness (like 49.999999999999999999999)
if ( precision == 0 ) {
lonDeg = qRound( lonDegF );
} else if ( precision <= 2 ) {
lonMin = qRound( lonMinF );
} else if ( precision <= 4 && notation == DMS ) {
lonSec = qRound( lonSecF );
} else {
if ( notation == DMS ) {
lonSec = lonSecF = qRound( lonSecF * qPow( 10, precision - 4 ) ) / qPow( 10, precision - 4 );
}
else {
lonMin = lonMinF = qRound( lonMinF * qPow( 10, precision - 2 ) ) / qPow( 10, precision - 2 );
}
}
if (lonSec > 59 && notation == DMS ) {
lonSec = lonSecF = 0;
lonMin = lonMinF = lonMinF + 1;
}
if (lonMin > 59) {
lonMin = lonMinF = 0;
lonDeg = lonDegF = lonDegF + 1;
}
// Evaluate the string
lonString = QString::fromUtf8("%1\xc2\xb0").arg(lonDeg, 3, 10, QLatin1Char(' '));
if ( precision == 0 ) {
return lonString + weString;
}
if ( notation == DMS || precision < 3 ) {
lonString += QString(" %2\'").arg(lonMin, 2, 10, QLatin1Char('0'));
}
if ( precision < 3 ) {
return lonString + weString;
}
if ( notation == DMS ) {
// Includes -1 case!
if ( precision < 5 ) {
lonString += QString(" %3\"").arg(lonSec, 2, 'f', 0, QLatin1Char('0'));
return lonString + weString;
}
lonString += QString(" %L3\"").arg(lonSecF, precision - 1, 'f', precision - 4, QLatin1Char('0'));
}
else {
lonString += QString(" %L3'").arg(lonMinF, precision + 1, 'f', precision - 2, QLatin1Char('0'));
}
}
else if ( notation == GeoDataCoordinates::Decimal )
{
lonString = QString::fromUtf8("%L1\xc2\xb0").arg(lonDegF, 4 + precision, format, precision, QLatin1Char(' '));
}
else if ( notation == GeoDataCoordinates::Astro )
{
if (lon < 0) {
lon += ( unit == Degree ) ? 360 : 2 * M_PI;
}
qreal lonHourF = ( unit == Degree ) ? fabs( lon/15.0 ) : fabs( (qreal)(lon/15.0) * RAD2DEG );
int lonHour = (int) lonHourF;
qreal lonMinF = 60 * (lonHourF - lonHour);
int lonMin = (int) lonMinF;
qreal lonSecF = 60 * (lonMinF - lonMin);
int lonSec = (int) lonSecF;
// Adjustment for fuzziness (like 49.999999999999999999999)
if ( precision == 0 ) {
lonHour = qRound( lonHourF );
} else if ( precision <= 2 ) {
lonMin = qRound( lonMinF );
} else if ( precision <= 4 ) {
lonSec = qRound( lonSecF );
} else {
lonSec = lonSecF = qRound( lonSecF * qPow( 10, precision - 4 ) ) / qPow( 10, precision - 4 );
}
if (lonSec > 59 ) {
lonSec = lonSecF = 0;
lonMin = lonMinF = lonMinF + 1;
}
if (lonMin > 59) {
lonMin = lonMinF = 0;
lonHour = lonHourF = lonHourF + 1;
}
// Evaluate the string
lonString = QString::fromUtf8("%1h").arg(lonHour, 3, 10, QLatin1Char(' '));
if ( precision == 0 ) {
return lonString;
}
lonString += QString(" %2\'").arg(lonMin, 2, 10, QLatin1Char('0'));
if ( precision < 3 ) {
return lonString;
}
// Includes -1 case!
if ( precision < 5 ) {
lonString += QString(" %3\"").arg(lonSec, 2, 'f', 0, QLatin1Char('0'));
return lonString;
}
lonString += QString(" %L3\"").arg(lonSecF, precision - 1, 'f', precision - 4, QLatin1Char('0'));
return lonString;
}
return lonString + weString;
}
QString GeoDataCoordinates::lonToString() const
{
return GeoDataCoordinates::lonToString( d->m_lon , s_notation );
}
QString GeoDataCoordinates::latToString( qreal lat, GeoDataCoordinates::Notation notation,
GeoDataCoordinates::Unit unit,
int precision,
char format )
{
if( notation == GeoDataCoordinates::UTM ){
/**
* @FIXME: UTM needs lon + lat to know latitude band and northing
* By now, this code returns the band+northing of the point
* (meridian, lat), but this can differ a lot at different locations
* See bug 347536 https://bugs.kde.org/show_bug.cgi?id=347536
*/
qreal latRad = ( unit == Radian ) ? lat : lat * DEG2RAD;
QString result = GeoDataCoordinatesPrivate::lonLatToLatitudeBand(0, latRad);
if ( precision > 0 ){
QString northingString = QString::number( GeoDataCoordinatesPrivate::lonLatToNorthing(0, latRad), 'f', 2 );
result += QString(" %1 m N").arg(northingString);
}
return result;
}
QString pmString;
QString nsString;
if (notation == GeoDataCoordinates::Astro){
pmString = ( lat > 0 ) ? "+" : "-";
}
else {
nsString = ( lat > 0 ) ? tr("N") : tr("S");
}
QString latString;
qreal latDegF = ( unit == Degree ) ? fabs( lat ) : fabs( (qreal)(lat) * RAD2DEG );
// Take care of -1 case
precision = ( precision < 0 ) ? 5 : precision;
if ( notation == DMS || notation == DM || notation == Astro) {
int latDeg = (int) latDegF;
qreal latMinF = 60 * (latDegF - latDeg);
int latMin = (int) latMinF;
qreal latSecF = 60 * (latMinF - latMin);
int latSec = (int) latSecF;
// Adjustment for fuzziness (like 49.999999999999999999999)
if ( precision == 0 ) {
latDeg = qRound( latDegF );
} else if ( precision <= 2 ) {
latMin = qRound( latMinF );
} else if ( precision <= 4 && notation == DMS ) {
latSec = qRound( latSecF );
} else {
if ( notation == DMS || notation == Astro ) {
latSec = latSecF = qRound( latSecF * qPow( 10, precision - 4 ) ) / qPow( 10, precision - 4 );
}
else {
latMin = latMinF = qRound( latMinF * qPow( 10, precision - 2 ) ) / qPow( 10, precision - 2 );
}
}
if (latSec > 59 && ( notation == DMS || notation == Astro )) {
latSecF = 0;
latSec = latSecF;
latMin = latMin + 1;
}
if (latMin > 59) {
latMinF = 0;
latMin = latMinF;
latDeg = latDeg + 1;
}
// Evaluate the string
latString = QString::fromUtf8("%1\xc2\xb0").arg(latDeg, 3, 10, QLatin1Char(' '));
if ( precision == 0 ) {
return pmString + latString + nsString;
}
if ( notation == DMS || notation == Astro || precision < 3 ) {
latString += QString(" %2\'").arg(latMin, 2, 10, QLatin1Char('0'));
}
if ( precision < 3 ) {
return pmString + latString + nsString;
}
if ( notation == DMS || notation == Astro ) {
// Includes -1 case!
if ( precision < 5 ) {
latString += QString(" %3\"").arg(latSec, 2, 'f', 0, QLatin1Char('0'));
return latString + nsString;
}
latString += QString(" %L3\"").arg(latSecF, precision - 1, 'f', precision - 4, QLatin1Char('0'));
}
else {
latString += QString(" %L3'").arg(latMinF, precision + 1, 'f', precision - 2, QLatin1Char('0'));
}
}
else // notation = GeoDataCoordinates::Decimal
{
latString = QString::fromUtf8("%L1\xc2\xb0").arg(latDegF, 4 + precision, format, precision, QLatin1Char(' '));
}
return pmString + latString + nsString;
}
QString GeoDataCoordinates::latToString() const
{
return GeoDataCoordinates::latToString( d->m_lat, s_notation );
}
bool GeoDataCoordinates::operator==( const GeoDataCoordinates &rhs ) const
{
return *d == *rhs.d;
}
bool GeoDataCoordinates::operator!=( const GeoDataCoordinates &rhs ) const
{
return *d != *rhs.d;
}
void GeoDataCoordinates::setAltitude( const qreal altitude )
{
detach();
d->m_altitude = altitude;
}
qreal GeoDataCoordinates::altitude() const
{
return d->m_altitude;
}
int GeoDataCoordinates::utmZone() const{
return GeoDataCoordinatesPrivate::lonLatToZone(d->m_lon, d->m_lat);
}
qreal GeoDataCoordinates::utmEasting() const{
return GeoDataCoordinatesPrivate::lonLatToEasting(d->m_lon, d->m_lat);
}
QString GeoDataCoordinates::utmLatitudeBand() const{
return GeoDataCoordinatesPrivate::lonLatToLatitudeBand(d->m_lon, d->m_lat);
}
qreal GeoDataCoordinates::utmNorthing() const{
return GeoDataCoordinatesPrivate::lonLatToNorthing(d->m_lon, d->m_lat);
}
quint8 GeoDataCoordinates::detail() const
{
return d->m_detail;
}
void GeoDataCoordinates::setDetail(quint8 detail)
{
detach();
d->m_detail = detail;
}
GeoDataCoordinates GeoDataCoordinates::rotateAround( const GeoDataCoordinates &axis, qreal angle, Unit unit ) const
{
const Quaternion quatAxis = Quaternion::fromEuler( -axis.latitude() , axis.longitude(), 0 );
const Quaternion rotationAmount = Quaternion::fromEuler( 0, 0, unit == Radian ? angle : angle * DEG2RAD );
const Quaternion resultAxis = quatAxis * rotationAmount * quatAxis.inverse();
Quaternion rotatedQuat = quaternion();
rotatedQuat.rotateAroundAxis(resultAxis);
qreal rotatedLon, rotatedLat;
rotatedQuat.getSpherical(rotatedLon, rotatedLat);
return GeoDataCoordinates(rotatedLon, rotatedLat, altitude());
}
qreal GeoDataCoordinates::bearing( const GeoDataCoordinates &other, Unit unit, BearingType type ) const
{
if ( type == FinalBearing ) {
double const offset = unit == Degree ? 180.0 : M_PI;
return offset + other.bearing( *this, unit, InitialBearing );
}
qreal const delta = other.d->m_lon - d->m_lon;
double const bearing = atan2( sin ( delta ) * cos ( other.d->m_lat ),
cos( d->m_lat ) * sin( other.d->m_lat ) - sin( d->m_lat ) * cos( other.d->m_lat ) * cos ( delta ) );
return unit == Radian ? bearing : bearing * RAD2DEG;
}
GeoDataCoordinates GeoDataCoordinates::moveByBearing( qreal bearing, qreal distance ) const
{
qreal newLat = asin( sin(d->m_lat) * cos(distance) +
cos(d->m_lat) * sin(distance) * cos(bearing) );
qreal newLon = d->m_lon + atan2( sin(bearing) * sin(distance) * cos(d->m_lat),
cos(distance) - sin(d->m_lat) * sin(newLat) );
return GeoDataCoordinates( newLon, newLat );
}
const Quaternion& GeoDataCoordinates::quaternion() const
{
- if (d->m_q == 0) {
+ if (d->m_q == nullptr) {
d->m_q = new Quaternion(Quaternion::fromSpherical( d->m_lon , d->m_lat ));
}
return *d->m_q;
}
GeoDataCoordinates GeoDataCoordinates::interpolate( const GeoDataCoordinates &target, double t_ ) const
{
double const t = qBound( 0.0, t_, 1.0 );
Quaternion const quat = Quaternion::slerp( quaternion(), target.quaternion(), t );
qreal lon, lat;
quat.getSpherical( lon, lat );
double const alt = (1.0-t) * d->m_altitude + t * target.d->m_altitude;
return GeoDataCoordinates( lon, lat, alt );
}
GeoDataCoordinates GeoDataCoordinates::interpolate( const GeoDataCoordinates &before, const GeoDataCoordinates &target, const GeoDataCoordinates &after, double t_ ) const
{
double const t = qBound( 0.0, t_, 1.0 );
Quaternion const b1 = GeoDataCoordinatesPrivate::basePoint( before.quaternion(), quaternion(), target.quaternion() );
Quaternion const a2 = GeoDataCoordinatesPrivate::basePoint( quaternion(), target.quaternion(), after.quaternion() );
Quaternion const a = Quaternion::slerp( quaternion(), target.quaternion(), t );
Quaternion const b = Quaternion::slerp( b1, a2, t );
Quaternion c = Quaternion::slerp( a, b, 2 * t * (1.0-t) );
qreal lon, lat;
c.getSpherical( lon, lat );
// @todo spline interpolation of altitude?
double const alt = (1.0-t) * d->m_altitude + t * target.d->m_altitude;
return GeoDataCoordinates( lon, lat, alt );
}
bool GeoDataCoordinates::isPole( Pole pole ) const
{
// Evaluate the most likely case first:
// The case where we haven't hit the pole and where our latitude is normalized
// to the range of 90 deg S ... 90 deg N
if ( fabs( (qreal) 2.0 * d->m_lat ) < M_PI ) {
return false;
}
else {
if ( fabs( (qreal) 2.0 * d->m_lat ) == M_PI ) {
// Ok, we have hit a pole. Now let's check whether it's the one we've asked for:
if ( pole == AnyPole ){
return true;
}
else {
if ( pole == NorthPole && 2.0 * d->m_lat == +M_PI ) {
return true;
}
if ( pole == SouthPole && 2.0 * d->m_lat == -M_PI ) {
return true;
}
return false;
}
}
//
else {
// FIXME: Should we just normalize latitude and longitude and be done?
// While this might work well for persistent data it would create some
// possible overhead for temporary data, so this needs careful thinking.
mDebug() << "GeoDataCoordinates not normalized!";
// Only as a last resort we cover the unlikely case where
// the latitude is not normalized to the range of
// 90 deg S ... 90 deg N
if ( fabs( (qreal) 2.0 * normalizeLat( d->m_lat ) ) < M_PI ) {
return false;
}
else {
// Ok, we have hit a pole. Now let's check whether it's the one we've asked for:
if ( pole == AnyPole ){
return true;
}
else {
if ( pole == NorthPole && 2.0 * d->m_lat == +M_PI ) {
return true;
}
if ( pole == SouthPole && 2.0 * d->m_lat == -M_PI ) {
return true;
}
return false;
}
}
}
}
}
qreal GeoDataCoordinates::sphericalDistanceTo(const GeoDataCoordinates &other) const
{
qreal lon2, lat2;
other.geoCoordinates( lon2, lat2 );
// FIXME: Take the altitude into account!
return distanceSphere(d->m_lon, d->m_lat, lon2, lat2);
}
GeoDataCoordinates& GeoDataCoordinates::operator=( const GeoDataCoordinates &other )
{
qAtomicAssign(d, other.d);
return *this;
}
void GeoDataCoordinates::pack( QDataStream& stream ) const
{
stream << d->m_lon;
stream << d->m_lat;
stream << d->m_altitude;
}
void GeoDataCoordinates::unpack( QDataStream& stream )
{
// call detach even though it shouldn't be needed - one never knows
detach();
stream >> d->m_lon;
stream >> d->m_lat;
stream >> d->m_altitude;
}
Quaternion GeoDataCoordinatesPrivate::basePoint( const Quaternion &q1, const Quaternion &q2, const Quaternion &q3 )
{
Quaternion const a = (q2.inverse() * q3).log();
Quaternion const b = (q2.inverse() * q1).log();
return q2 * ((a+b)*-0.25).exp();
}
qreal GeoDataCoordinatesPrivate::arcLengthOfMeridian( qreal phi )
{
// Precalculate n
qreal const n = (GeoDataCoordinatesPrivate::sm_semiMajorAxis - GeoDataCoordinatesPrivate::sm_semiMinorAxis)
/ (GeoDataCoordinatesPrivate::sm_semiMajorAxis + GeoDataCoordinatesPrivate::sm_semiMinorAxis);
// Precalculate alpha
qreal const alpha = ( (GeoDataCoordinatesPrivate::sm_semiMajorAxis + GeoDataCoordinatesPrivate::sm_semiMinorAxis) / 2.0)
* (1.0 + (qPow (n, 2.0) / 4.0) + (qPow (n, 4.0) / 64.0) );
// Precalculate beta
qreal const beta = (-3.0 * n / 2.0)
+ (9.0 * qPow (n, 3.0) / 16.0)
+ (-3.0 * qPow (n, 5.0) / 32.0);
// Precalculate gamma
qreal const gamma = (15.0 * qPow (n, 2.0) / 16.0)
+ (-15.0 * qPow (n, 4.0) / 32.0);
// Precalculate delta
qreal const delta = (-35.0 * qPow (n, 3.0) / 48.0)
+ (105.0 * qPow (n, 5.0) / 256.0);
// Precalculate epsilon
qreal const epsilon = (315.0 * qPow (n, 4.0) / 512.0);
// Now calculate the sum of the series and return
qreal const result = alpha * (phi + (beta * qSin (2.0 * phi))
+ (gamma * qSin (4.0 * phi))
+ (delta * qSin (6.0 * phi))
+ (epsilon * qSin (8.0 * phi)));
return result;
}
qreal GeoDataCoordinatesPrivate::centralMeridianUTM( qreal zone )
{
return DEG2RAD*(-183.0 + (zone * 6.0));
}
qreal GeoDataCoordinatesPrivate::footpointLatitude( qreal northing )
{
// Precalculate n (Eq. 10.18)
qreal const n = (GeoDataCoordinatesPrivate::sm_semiMajorAxis - GeoDataCoordinatesPrivate::sm_semiMinorAxis)
/ (GeoDataCoordinatesPrivate::sm_semiMajorAxis + GeoDataCoordinatesPrivate::sm_semiMinorAxis);
// Precalculate alpha (Eq. 10.22)
// (Same as alpha in Eq. 10.17)
qreal const alpha = ((GeoDataCoordinatesPrivate::sm_semiMajorAxis + GeoDataCoordinatesPrivate::sm_semiMinorAxis) / 2.0)
* (1 + (qPow (n, 2.0) / 4) + (qPow (n, 4.0) / 64));
// Precalculate y (Eq. 10.23)
qreal const y = northing / alpha;
// Precalculate beta (Eq. 10.22)
qreal const beta = (3.0 * n / 2.0) + (-27.0 * qPow (n, 3.0) / 32.0)
+ (269.0 * qPow (n, 5.0) / 512.0);
// Precalculate gamma (Eq. 10.22)
qreal const gamma = (21.0 * qPow (n, 2.0) / 16.0)
+ (-55.0 * qPow (n, 4.0) / 32.0);
// Precalculate delta (Eq. 10.22)
qreal const delta = (151.0 * qPow (n, 3.0) / 96.0)
+ (-417.0 * qPow (n, 5.0) / 128.0);
// Precalculate epsilon (Eq. 10.22)
qreal const epsilon = (1097.0 * qPow (n, 4.0) / 512.0);
// Now calculate the sum of the series (Eq. 10.21)
qreal const result = y + (beta * qSin (2.0 * y))
+ (gamma * qSin (4.0 * y))
+ (delta * qSin (6.0 * y))
+ (epsilon * qSin (8.0 * y));
return result;
}
QPointF GeoDataCoordinatesPrivate::mapLonLatToXY( qreal lambda, qreal phi, qreal lambda0 )
{
// Equation (10.15)
// Precalculate second numerical eccentricity
const qreal ep2 = (qPow(GeoDataCoordinatesPrivate::sm_semiMajorAxis, 2.0) - qPow(GeoDataCoordinatesPrivate::sm_semiMinorAxis, 2.0))
/ qPow(GeoDataCoordinatesPrivate::sm_semiMinorAxis, 2.0);
// Precalculate the square of nu, just an auxiliar quantity
const qreal nu2 = ep2 * qPow(qCos(phi), 2.0);
// Precalculate the radius of curvature in prime vertical
const qreal N = qPow(GeoDataCoordinatesPrivate::sm_semiMajorAxis, 2.0) / (GeoDataCoordinatesPrivate::sm_semiMinorAxis * qSqrt(1 + nu2));
// Precalculate the tangent of phi and its square
const qreal t = qTan(phi);
const qreal t2 = t * t;
// Precalculate longitude difference
const qreal l = lambda - lambda0;
/*
* Precalculate coefficients for l**n in the equations below
* so a normal human being can read the expressions for easting
* and northing
* -- l**1 and l**2 have coefficients of 1.0
*
* The actual used coefficients starts at coef[1], just to
* follow the meaningful nomenclature in equation 10.15
* (coef[n] corresponds to qPow(l,n) factor)
*/
const qreal coef1 = 1;
const qreal coef2 = 1;
const qreal coef3 = 1.0 - t2 + nu2;
const qreal coef4 = 5.0 - t2 + 9 * nu2 + 4.0 * (nu2 * nu2);
const qreal coef5 = 5.0 - 18.0 * t2 + (t2 * t2) + 14.0 * nu2 - 58.0 * t2 * nu2;
const qreal coef6 = 61.0 - 58.0 * t2 + (t2 * t2) + 270.0 * nu2 - 330.0 * t2 * nu2;
const qreal coef7 = 61.0 - 479.0 * t2 + 179.0 * (t2 * t2) - (t2 * t2 * t2);
const qreal coef8 = 1385.0 - 3111.0 * t2 + 543.0 * (t2 * t2) - (t2 * t2 * t2);
// Calculate easting (x)
const qreal easting = N * qCos(phi) * coef1 * l
+ (N / 6.0 * qPow(qCos(phi), 3.0) * coef3 * qPow(l, 3.0))
+ (N / 120.0 * qPow(qCos(phi), 5.0) * coef5 * qPow(l, 5.0))
+ (N / 5040.0 * qPow(qCos(phi), 7.0) * coef7 * qPow(l, 7.0));
// Calculate northing (y)
const qreal northing = arcLengthOfMeridian (phi)
+ (t / 2.0 * N * qPow(qCos(phi), 2.0) * coef2 * qPow(l, 2.0))
+ (t / 24.0 * N * qPow(qCos(phi), 4.0) * coef4 * qPow(l, 4.0))
+ (t / 720.0 * N * qPow(qCos(phi), 6.0) * coef6 * qPow(l, 6.0))
+ (t / 40320.0 * N * qPow(qCos(phi), 8.0) * coef8 * qPow(l, 8.0));
return QPointF(easting, northing);
}
int GeoDataCoordinatesPrivate::lonLatToZone( qreal lon, qreal lat ){
// Converts lon and lat to degrees
qreal lonDeg = lon * RAD2DEG;
qreal latDeg = lat * RAD2DEG;
/* Round the value of the longitude when the distance to the nearest integer
* is less than 0.0000001. This avoids fuzzy values such as -114.0000000001, which
* can produce a misbehaviour when calculating the zone associated at the borders
* of the zone intervals (for example, the interval [-114, -108[ is associated with
* zone number 12; if the following rounding is not done, the value returned by
* lonLatToZone(114,0) is 11 instead of 12, as the function actually receives
* -114.0000000001, which is in the interval [-120,-114[, associated to zone 11
*/
qreal precision = 0.0000001;
if ( qAbs(lonDeg - qFloor(lonDeg)) < precision || qAbs(lonDeg - qCeil(lonDeg)) < precision ){
lonDeg = qRound(lonDeg);
}
// There is no numbering associated to the poles, special value 0 is returned.
if ( latDeg < -80 || latDeg > 84 ) {
return 0;
}
// Obtains the zone number handling all the so called "exceptions"
// See problem: http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system#Exceptions
// See solution: http://gis.stackexchange.com/questions/13291/computing-utm-zone-from-lat-long-point
// General
int zoneNumber = static_cast<int>( (lonDeg+180) / 6.0 ) + 1;
// Southwest Norway
if ( latDeg >= 56 && latDeg < 64 && lonDeg >= 3 && lonDeg < 12 ) {
zoneNumber = 32;
}
// Svalbard
if ( latDeg >= 72 && latDeg < 84 ) {
if ( lonDeg >= 0 && lonDeg < 9 ) {
zoneNumber = 31;
} else if ( lonDeg >= 9 && lonDeg < 21 ) {
zoneNumber = 33;
} else if ( lonDeg >= 21 && lonDeg < 33 ) {
zoneNumber = 35;
} else if ( lonDeg >= 33 && lonDeg < 42 ) {
zoneNumber = 37;
}
}
return zoneNumber;
}
qreal GeoDataCoordinatesPrivate::lonLatToEasting( qreal lon, qreal lat ){
int zoneNumber = lonLatToZone( lon, lat );
if ( zoneNumber == 0 ){
qreal lonDeg = lon * RAD2DEG;
zoneNumber = static_cast<int>( (lonDeg+180) / 6.0 ) + 1;
}
QPointF coordinates = GeoDataCoordinatesPrivate::mapLonLatToXY( lon, lat, GeoDataCoordinatesPrivate::centralMeridianUTM(zoneNumber) );
// Adjust easting and northing for UTM system
qreal easting = coordinates.x() * GeoDataCoordinatesPrivate::sm_utmScaleFactor + 500000.0;
return easting;
}
QString GeoDataCoordinatesPrivate::lonLatToLatitudeBand( qreal lon, qreal lat ){
// Obtains the latitude bands handling all the so called "exceptions"
// Converts lon and lat to degrees
qreal lonDeg = lon * RAD2DEG;
qreal latDeg = lat * RAD2DEG;
// Regular latitude bands between 80 S and 80 N (that is, between 10 and 170 in the [0,180] interval)
int bandLetterIndex = 24; //Avoids "may be used uninitialized" warning
if ( latDeg < -80 ) {
// South pole (A for zones 1-30, B for zones 31-60)
bandLetterIndex = ( (lonDeg+180) < 6*31 ) ? 0 : 1;
} else if ( latDeg >= -80 && latDeg <= 80 ) {
// General (+2 because the general lettering starts in C)
bandLetterIndex = static_cast<int>( (latDeg+80.0) / 8.0 ) + 2;
} else if ( latDeg >= 80 && latDeg < 84 ) {
// Band X is extended 4 more degrees
bandLetterIndex = 21;
} else if ( latDeg >= 84 ) {
// North pole (Y for zones 1-30, Z for zones 31-60)
bandLetterIndex = ((lonDeg+180) < 6*31) ? 22 : 23;
}
return QString( "ABCDEFGHJKLMNPQRSTUVWXYZ?" ).at( bandLetterIndex );
}
qreal GeoDataCoordinatesPrivate::lonLatToNorthing( qreal lon, qreal lat ){
int zoneNumber = lonLatToZone( lon, lat );
if ( zoneNumber == 0 ){
qreal lonDeg = lon * RAD2DEG;
zoneNumber = static_cast<int>( (lonDeg+180) / 6.0 ) + 1;
}
QPointF coordinates = GeoDataCoordinatesPrivate::mapLonLatToXY( lon, lat, GeoDataCoordinatesPrivate::centralMeridianUTM(zoneNumber) );
qreal northing = coordinates.y() * GeoDataCoordinatesPrivate::sm_utmScaleFactor;
if ( northing < 0.0 ) {
northing += 10000000.0;
}
return northing;
}
uint qHash(const GeoDataCoordinates &coordinates)
{
uint seed = ::qHash(coordinates.altitude());
seed = ::qHash(coordinates.latitude(), seed);
return ::qHash(coordinates.longitude(), seed);
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataCoordinates_p.h b/src/lib/marble/geodata/data/GeoDataCoordinates_p.h
index e38ee2f75..15f0a4c77 100644
--- a/src/lib/marble/geodata/data/GeoDataCoordinates_p.h
+++ b/src/lib/marble/geodata/data/GeoDataCoordinates_p.h
@@ -1,236 +1,236 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Patrick Spendrin <ps_ml@gmx.de>
//
#ifndef MARBLE_GEODATACOORDINATES_P_H
#define MARBLE_GEODATACOORDINATES_P_H
#include "Quaternion.h"
#include <QAtomicInt>
namespace Marble
{
class GeoDataCoordinatesPrivate
{
public:
/*
* if this ctor is called there exists exactly one GeoDataCoordinates object
* with this data.
* changes will be made in the GeoDataCoordinates class
* ref must be called ref as qAtomicAssign used in GeoDataCoordinates::operator=
* needs this name. Maybe we can rename it to our scheme later on.
*/
GeoDataCoordinatesPrivate()
- : m_q( 0 ),
+ : m_q( nullptr ),
m_lon( 0 ),
m_lat( 0 ),
m_altitude( 0 ),
m_detail( 0 ),
ref( 0 )
{
}
/*
* if this ctor is called there exists exactly one GeoDataCoordinates object
* with this data.
* changes will be made in the GeoDataCoordinates class
* ref must be called ref as qAtomicAssign used in GeoDataCoordinates::operator=
* needs this name. Maybe we can rename it to our scheme later on.
*/
GeoDataCoordinatesPrivate( qreal _lon, qreal _lat, qreal _alt,
GeoDataCoordinates::Unit unit,
int _detail )
- : m_q( 0 ),
+ : m_q( nullptr ),
m_altitude( _alt ),
m_detail( _detail ),
ref( 0 )
{
switch( unit ){
default:
case GeoDataCoordinates::Radian:
m_lon = _lon;
m_lat = _lat;
break;
case GeoDataCoordinates::Degree:
m_lon = _lon * DEG2RAD;
m_lat = _lat * DEG2RAD;
break;
}
}
/*
* this constructor is needed as Quaternion doesn't define a copy ctor
* initialize the reference with the value of the other
*/
GeoDataCoordinatesPrivate( const GeoDataCoordinatesPrivate &other )
- : m_q( 0 ),
+ : m_q( nullptr ),
m_lon( other.m_lon ),
m_lat( other.m_lat ),
m_altitude( other.m_altitude ),
m_detail( other.m_detail ),
ref( 0 )
{
}
/*
* return this instead of &other
*/
GeoDataCoordinatesPrivate& operator=( const GeoDataCoordinatesPrivate &other )
{
m_lon = other.m_lon;
m_lat = other.m_lat;
m_altitude = other.m_altitude;
m_detail = other.m_detail;
ref = 0;
delete m_q;
- m_q = 0;
+ m_q = nullptr;
return *this;
}
bool operator==( const GeoDataCoordinatesPrivate &rhs ) const;
bool operator!=( const GeoDataCoordinatesPrivate &rhs ) const;
static Quaternion basePoint( const Quaternion &q1, const Quaternion &q2, const Quaternion &q3 );
// Helper functions for UTM-related development.
// Based on Chuck Taylor work:
// http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html
/**
* Computes the ellipsoidal distance from the equator to a point at a
* given latitude.
*
* Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
* GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
*
* @param phi Latitude of the point, in radians.
* @return The ellipsoidal distance of the point from the equator, in meters.
*/
static qreal arcLengthOfMeridian( qreal phi );
/**
* Determines the central meridian for the given UTM zone.
*
* @param zone An integer value designating the UTM zone, range [1,60].
* @return The central meridian for the given UTM zone, in radians, or zero
* if the UTM zone parameter is outside the range [1,60].
* Range of the central meridian is the radian equivalent of [-177,+177].
*/
static qreal centralMeridianUTM( qreal zone );
/**
* Computes the footpoint latitude for use in converting transverse
* Mercator coordinates to ellipsoidal coordinates.
*
* Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
* GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
*
* @param northing The UTM northing coordinate, in meters.
* @return The footpoint latitude, in radians.
*/
static qreal footpointLatitude( qreal northing );
/**
* Converts a latitude/longitude pair to x and y coordinates in the
* Transverse Mercator projection. Note that Transverse Mercator is not
* the same as UTM; a scale factor is required to convert between them.
*
* Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,
* GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.
*
* @param lambda Longitude of the point, in radians.
* @param phi Latitude of the point, in radians.
* @param lambda0 Longitude of the central meridian to be used, in radians.
* @return The computed point with its x and y coordinates
*/
static QPointF mapLonLatToXY( qreal lambda, qreal phi, qreal lambda0 );
/**
* Converts a latitude/longitude pair to x and y coordinates in the
* Universal Transverse Mercator projection.
*
* @param lon Longitude of the point, in radians.
* @param lat Latitude of the point, in radians.
* @param zone UTM zone between 1 and 60 to be used for calculating
* values for x and y.
* @return A point with its x and y coordinates representing
* easting and northing of the UTM coordinates computed.
*/
static QPointF lonLatToUTMXY( qreal lon, qreal lat, qreal zone );
/**
* @brief retrieves the UTM latitude band of a longitude/latitude
* pair
* @param lon longitude, in radians
* @param lat latitude, in radians
* @return latitude band
*/
static QString lonLatToLatitudeBand( qreal lon, qreal lat );
/**
* @brief retrieves the northing value of a longitude/latitude
* pair
* @param lon longitude, in radians
* @param lat latitude, in radians
* @return UTM northing value
*/
static qreal lonLatToNorthing( qreal lon, qreal lat );
/**
* @brief retrieves the UTM zone number of a longitude/latitude
* pair
* @param lon longitude, in radians
* @param lat latitude, in radians
* @return UTM zone number
*/
static int lonLatToZone( qreal lon, qreal lat );
/**
* @brief retrieves the easting value of a longitude/latitude
* pair
* @param lon longitude, in radians
* @param lat latitude, in radians
* @return UTM easting value
*/
static qreal lonLatToEasting( qreal lon, qreal lat );
Quaternion * m_q;
qreal m_lon;
qreal m_lat;
qreal m_altitude; // in meters above sea level
quint8 m_detail;
QAtomicInt ref;
/* UTM Ellipsoid model constants (actual values here are for WGS84) */
static const qreal sm_semiMajorAxis;
static const qreal sm_semiMinorAxis;
static const qreal sm_eccentricitySquared;
static const qreal sm_utmScaleFactor;
};
inline bool GeoDataCoordinatesPrivate::operator==( const GeoDataCoordinatesPrivate &rhs ) const
{
// do not compare the m_detail member as it does not really belong to
// GeoDataCoordinates and should be removed
return m_lon == rhs.m_lon && m_lat == rhs.m_lat && m_altitude == rhs.m_altitude;
}
inline bool GeoDataCoordinatesPrivate::operator!=( const GeoDataCoordinatesPrivate &rhs ) const
{
// do not compare the m_detail member as it does not really belong to
// GeoDataCoordinates and should be removed
return ! (*this == rhs);
}
}
#endif
diff --git a/src/lib/marble/geodata/data/GeoDataDocument.cpp b/src/lib/marble/geodata/data/GeoDataDocument.cpp
index 2d804548a..20b2bc495 100644
--- a/src/lib/marble/geodata/data/GeoDataDocument.cpp
+++ b/src/lib/marble/geodata/data/GeoDataDocument.cpp
@@ -1,313 +1,313 @@
/*
Copyright (C) 2007 Murad Tagirov <tmurad@gmail.com>
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "GeoDataDocument.h"
#include "GeoDataDocument_p.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataSchema.h"
#include "MarbleDebug.h"
#include <QDataStream>
namespace Marble
{
GeoDataDocument::GeoDataDocument()
: GeoDataContainer( new GeoDataDocumentPrivate )
{
}
GeoDataDocument::GeoDataDocument( const GeoDataDocument& other )
: GeoDocument(),
GeoDataContainer(other, new GeoDataDocumentPrivate(*other.d_func()))
{
}
GeoDataDocument::~GeoDataDocument()
{
}
GeoDataDocument& GeoDataDocument::operator=(const GeoDataDocument& other)
{
if (this != &other) {
Q_D(GeoDataDocument);
*d = *other.d_func();
}
return *this;
}
bool GeoDataDocument::operator==( const GeoDataDocument &other ) const
{
if (!GeoDataContainer::equals(other)) {
return false;
}
Q_D(const GeoDataDocument);
const GeoDataDocumentPrivate* const other_d = other.d_func();
if (!(d->m_styleHash.size() == other_d->m_styleHash.size() &&
d->m_styleMapHash == other_d->m_styleMapHash &&
d->m_schemaHash == other_d->m_schemaHash &&
d->m_filename == other_d->m_filename &&
d->m_baseUri == other_d->m_baseUri &&
d->m_networkLinkControl == other_d->m_networkLinkControl &&
d->m_property == other_d->m_property &&
d->m_documentRole == other_d->m_documentRole)) {
return false;
}
auto iter = d->m_styleHash.constBegin();
auto const end = d->m_styleHash.constEnd();
for (; iter != end; ++iter) {
if (!other_d->m_styleHash.contains(iter.key())) {
return false;
}
if (*iter.value() != *other_d->m_styleHash[iter.key()]) {
return false;
}
}
return true;
}
bool GeoDataDocument::operator!=( const GeoDataDocument &other ) const
{
return !this->operator==( other );
}
const char* GeoDataDocument::nodeType() const
{
return GeoDataTypes::GeoDataDocumentType;
}
GeoDataFeature * GeoDataDocument::clone() const
{
return new GeoDataDocument(*this);
}
DocumentRole GeoDataDocument::documentRole() const
{
Q_D(const GeoDataDocument);
return d->m_documentRole;
}
void GeoDataDocument::setDocumentRole( DocumentRole role )
{
Q_D(GeoDataDocument);
d->m_documentRole = role;
}
QString GeoDataDocument::property() const
{
Q_D(const GeoDataDocument);
return d->m_property;
}
void GeoDataDocument::setProperty( const QString& property )
{
Q_D(GeoDataDocument);
d->m_property = property;
}
QString GeoDataDocument::fileName() const
{
Q_D(const GeoDataDocument);
return d->m_filename;
}
void GeoDataDocument::setFileName( const QString &value )
{
Q_D(GeoDataDocument);
d->m_filename = value;
}
QString GeoDataDocument::baseUri() const
{
Q_D(const GeoDataDocument);
return d->m_baseUri;
}
void GeoDataDocument::setBaseUri( const QString &baseUrl )
{
Q_D(GeoDataDocument);
d->m_baseUri = baseUrl;
}
GeoDataNetworkLinkControl GeoDataDocument::networkLinkControl() const
{
Q_D(const GeoDataDocument);
return d->m_networkLinkControl;
}
void GeoDataDocument::setNetworkLinkControl( const GeoDataNetworkLinkControl &networkLinkControl )
{
Q_D(GeoDataDocument);
d->m_networkLinkControl = networkLinkControl;
}
void GeoDataDocument::addStyle( const GeoDataStyle::Ptr &style )
{
Q_D(GeoDataDocument);
d->m_styleHash.insert(style->id(), style);
d->m_styleHash[style->id()]->setParent(this);
}
void GeoDataDocument::removeStyle( const QString& styleId )
{
Q_D(GeoDataDocument);
d->m_styleHash.remove(styleId);
}
GeoDataStyle::Ptr GeoDataDocument::style( const QString& styleId )
{
/*
* FIXME: m_styleHash always should contain at least default
* GeoDataStyle element
*/
Q_D(GeoDataDocument);
return d->m_styleHash[styleId];
}
GeoDataStyle::ConstPtr GeoDataDocument::style( const QString &styleId ) const
{
Q_D(const GeoDataDocument);
return d->m_styleHash.value(styleId);
}
QList<GeoDataStyle::ConstPtr> GeoDataDocument::styles() const
{
Q_D(const GeoDataDocument);
QList<GeoDataStyle::ConstPtr> result;
for(auto const & style: d->m_styleHash.values()) {
result << style;
}
return result;
}
QList<GeoDataStyle::Ptr> GeoDataDocument::styles()
{
Q_D(GeoDataDocument);
return d->m_styleHash.values();
}
void GeoDataDocument::addStyleMap( const GeoDataStyleMap& map )
{
Q_D(GeoDataDocument);
d->m_styleMapHash.insert(map.id(), map);
d->m_styleMapHash[map.id()].setParent(this);
}
void GeoDataDocument::removeStyleMap( const QString& mapId )
{
Q_D(GeoDataDocument);
d->m_styleMapHash.remove(mapId);
}
GeoDataStyleMap& GeoDataDocument::styleMap( const QString& styleId )
{
Q_D(GeoDataDocument);
return d->m_styleMapHash[styleId];
}
GeoDataStyleMap GeoDataDocument::styleMap( const QString &styleId ) const
{
Q_D(const GeoDataDocument);
return d->m_styleMapHash.value(styleId);
}
QList<GeoDataStyleMap> GeoDataDocument::styleMaps() const
{
Q_D(const GeoDataDocument);
return d->m_styleMapHash.values();
}
void GeoDataDocument::addSchema( const GeoDataSchema& schema )
{
Q_D(GeoDataDocument);
d->m_schemaHash.insert(schema.id(), schema);
d->m_schemaHash[schema.id()].setParent(this);
}
void GeoDataDocument::removeSchema( const QString& schemaId )
{
Q_D(GeoDataDocument);
GeoDataSchema schema = d->m_schemaHash.take(schemaId);
- schema.setParent( 0 );
+ schema.setParent( nullptr );
}
GeoDataSchema GeoDataDocument::schema( const QString& schemaId ) const
{
Q_D(const GeoDataDocument);
return d->m_schemaHash.value(schemaId);
}
GeoDataSchema &GeoDataDocument::schema( const QString &schemaId )
{
Q_D(GeoDataDocument);
return d->m_schemaHash[schemaId];
}
QList<GeoDataSchema> GeoDataDocument::schemas() const
{
Q_D(const GeoDataDocument);
return d->m_schemaHash.values();
}
void GeoDataDocument::pack( QDataStream& stream ) const
{
Q_D(const GeoDataDocument);
GeoDataContainer::pack( stream );
stream << d->m_styleHash.size();
for( QMap<QString, GeoDataStyle::Ptr>::const_iterator iterator
= d->m_styleHash.constBegin();
iterator != d->m_styleHash.constEnd();
++iterator ) {
iterator.value()->pack( stream );
}
}
void GeoDataDocument::unpack( QDataStream& stream )
{
Q_D(GeoDataDocument);
GeoDataContainer::unpack( stream );
int size = 0;
stream >> size;
for( int i = 0; i < size; i++ ) {
GeoDataStyle::Ptr style;
style->unpack( stream );
d->m_styleHash.insert(style->id(), style);
}
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataExtendedData.cpp b/src/lib/marble/geodata/data/GeoDataExtendedData.cpp
index 725916d85..962c6384b 100644
--- a/src/lib/marble/geodata/data/GeoDataExtendedData.cpp
+++ b/src/lib/marble/geodata/data/GeoDataExtendedData.cpp
@@ -1,149 +1,149 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "GeoDataExtendedData.h"
#include "GeoDataExtendedData_p.h"
#include <QDataStream>
#include "GeoDataTypes.h"
namespace Marble
{
GeoDataExtendedData::GeoDataExtendedData()
: GeoDataObject(), d( new GeoDataExtendedDataPrivate )
{
}
GeoDataExtendedData::GeoDataExtendedData( const GeoDataExtendedData& other )
: GeoDataObject( other ), d( new GeoDataExtendedDataPrivate( *other.d ) )
{
}
bool GeoDataExtendedData::operator==( const GeoDataExtendedData& other ) const
{
return equals(other) &&
d->hash == other.d->hash &&
d->arrayHash == other.d->arrayHash;
}
GeoDataExtendedData::~GeoDataExtendedData()
{
qDeleteAll( d->arrayHash );
delete d;
}
GeoDataExtendedData& GeoDataExtendedData::operator=( const GeoDataExtendedData& other )
{
GeoDataObject::operator=( other );
*d = *other.d;
return *this;
}
bool GeoDataExtendedData::operator!=( const GeoDataExtendedData &other ) const
{
return !this->operator==(other);
}
const char* GeoDataExtendedData::nodeType() const
{
return GeoDataTypes::GeoDataExtendedDataType;
}
GeoDataData& GeoDataExtendedData::valueRef( const QString& key ) const
{
return d->hash[ key ];
}
GeoDataData GeoDataExtendedData::value( const QString& key ) const
{
return d->hash.value( key );
}
void GeoDataExtendedData::addValue( const GeoDataData& data )
{
d->hash.insert( data.name(), data );
}
void GeoDataExtendedData::removeKey(const QString &key)
{
d->hash.remove(key);
}
QHash< QString, GeoDataData >::const_iterator GeoDataExtendedData::constBegin( ) const
{
return d->hash.constBegin();
}
QHash< QString, GeoDataData >::const_iterator GeoDataExtendedData::constEnd( ) const
{
return d->hash.constEnd();
}
int GeoDataExtendedData::size() const
{
return d->hash.size();
}
bool GeoDataExtendedData::isEmpty( ) const
{
return d->hash.empty() && d->schemaDataHash.empty();
}
bool GeoDataExtendedData::contains( const QString &key ) const
{
return d->hash.contains( key );
}
void GeoDataExtendedData::setSimpleArrayData( const QString& key, GeoDataSimpleArrayData *values )
{
d->arrayHash[ key ] = values;
}
GeoDataSimpleArrayData* GeoDataExtendedData::simpleArrayData( const QString& key ) const
{
- if ( !d->arrayHash.contains( key ) ) return 0;
+ if ( !d->arrayHash.contains( key ) ) return nullptr;
return d->arrayHash[ key ];
}
GeoDataSchemaData& GeoDataExtendedData::schemaData( const QString& schemaUrl ) const
{
return d->schemaDataHash[ schemaUrl ];
}
void GeoDataExtendedData::addSchemaData( const GeoDataSchemaData& schemaData )
{
d->schemaDataHash.insert( schemaData.schemaUrl(), schemaData );
d->schemaDataHash[schemaData.schemaUrl()].setParent( this );
}
void GeoDataExtendedData::removeSchemaData( const QString& schemaUrl )
{
GeoDataSchemaData schemaData = d->schemaDataHash.take( schemaUrl );
- schemaData.setParent( 0 );
+ schemaData.setParent( nullptr );
}
QList<GeoDataSchemaData> GeoDataExtendedData::schemaDataList() const
{
return d->schemaDataHash.values();
}
void GeoDataExtendedData::pack( QDataStream& stream ) const
{
GeoDataObject::pack( stream );
}
void GeoDataExtendedData::unpack( QDataStream& stream )
{
GeoDataObject::unpack( stream );
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataFeature.cpp b/src/lib/marble/geodata/data/GeoDataFeature.cpp
index c37aee07c..be4012067 100644
--- a/src/lib/marble/geodata/data/GeoDataFeature.cpp
+++ b/src/lib/marble/geodata/data/GeoDataFeature.cpp
@@ -1,555 +1,555 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Murad Tagirov <tmurad@gmail.com>
// Copyright 2009 Patrick Spendrin <ps_ml@gmx.de>
//
#include "GeoDataFeature.h"
#include "GeoDataFeature_p.h"
#include <QDataStream>
#include <QSize>
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataContainer.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataNetworkLink.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataPlacemark.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataTour.h"
#include "GeoDataRegion.h"
#include "GeoDataCamera.h"
namespace Marble
{
const QSharedPointer<const GeoDataStyle> GeoDataFeaturePrivate::s_defaultStyle(new GeoDataStyle);
GeoDataFeature::GeoDataFeature()
: d_ptr(new GeoDataFeaturePrivate())
{
}
GeoDataFeature::GeoDataFeature( const GeoDataFeature& other )
: GeoDataObject(),
d_ptr(new GeoDataFeaturePrivate(*other.d_ptr))
{
}
GeoDataFeature::GeoDataFeature( const QString& name )
: d_ptr(new GeoDataFeaturePrivate())
{
d_ptr->m_name = name;
}
GeoDataFeature::GeoDataFeature(GeoDataFeaturePrivate *dd)
: GeoDataObject(),
d_ptr(dd)
{
}
GeoDataFeature::GeoDataFeature(const GeoDataFeature& other, GeoDataFeaturePrivate *dd)
: GeoDataObject(),
d_ptr(dd)
{
Q_UNUSED(other);
// TODO: some classes pass "other" on and thus get duplicated id, also in operator=. Align behaviour
}
GeoDataFeature::~GeoDataFeature()
{
delete d_ptr;
}
GeoDataFeature& GeoDataFeature::operator=( const GeoDataFeature& other )
{
if (this != &other) {
*d_ptr = *other.d_ptr;
}
return *this;
}
bool GeoDataFeature::operator==(const GeoDataFeature &other) const
{
if (nodeType() != other.nodeType()) {
return false;
}
if (nodeType() == GeoDataTypes::GeoDataDocumentType) {
const GeoDataDocument &thisDoc = static_cast<const GeoDataDocument &>(*this);
const GeoDataDocument &otherDoc = static_cast<const GeoDataDocument &>(other);
return thisDoc == otherDoc;
} else if (nodeType() == GeoDataTypes::GeoDataFolderType) {
const GeoDataFolder &thisFolder = static_cast<const GeoDataFolder &>(*this);
const GeoDataFolder &otherFolder = static_cast<const GeoDataFolder &>(other);
return thisFolder == otherFolder;
} else if (nodeType() == GeoDataTypes::GeoDataGroundOverlayType) {
const GeoDataGroundOverlay &thisGO = static_cast<const GeoDataGroundOverlay &>(*this);
const GeoDataGroundOverlay &otherGO = static_cast<const GeoDataGroundOverlay &>(other);
return thisGO == otherGO;
} else if (nodeType() == GeoDataTypes::GeoDataNetworkLinkType) {
const GeoDataNetworkLink &thisNetLink = static_cast<const GeoDataNetworkLink &>(*this);
const GeoDataNetworkLink &otherNetLink = static_cast<const GeoDataNetworkLink &>(other);
return thisNetLink == otherNetLink;
} else if (nodeType() == GeoDataTypes::GeoDataNetworkLinkControlType) {
const GeoDataNetworkLinkControl &thisNLC = static_cast<const GeoDataNetworkLinkControl &>(*this);
const GeoDataNetworkLinkControl &otherNLC = static_cast<const GeoDataNetworkLinkControl &>(other);
return thisNLC == otherNLC;
} else if (nodeType() == GeoDataTypes::GeoDataPhotoOverlayType) {
const GeoDataPhotoOverlay &thisPO = static_cast<const GeoDataPhotoOverlay &>(*this);
const GeoDataPhotoOverlay &otherPO = static_cast<const GeoDataPhotoOverlay &>(other);
return thisPO == otherPO;
} else if (nodeType() == GeoDataTypes::GeoDataPlacemarkType) {
const GeoDataPlacemark &thisPM = static_cast<const GeoDataPlacemark &>(*this);
const GeoDataPlacemark &otherPM = static_cast<const GeoDataPlacemark &>(other);
return thisPM == otherPM;
} else if (nodeType() == GeoDataTypes::GeoDataScreenOverlayType) {
const GeoDataScreenOverlay &thisSO = static_cast<const GeoDataScreenOverlay &>(*this);
const GeoDataScreenOverlay &otherSO = static_cast<const GeoDataScreenOverlay &>(other);
return thisSO == otherSO;
} else if (nodeType() == GeoDataTypes::GeoDataTourType) {
const GeoDataTour &thisTour = static_cast<const GeoDataTour &>(*this);
const GeoDataTour &otherTour = static_cast<const GeoDataTour &>(other);
return thisTour == otherTour;
}
return false;
}
bool GeoDataFeature::equals( const GeoDataFeature &other ) const
{
Q_D(const GeoDataFeature);
const GeoDataFeaturePrivate* const other_d = other.d_func();
if (!GeoDataObject::equals(other) ||
d->m_name != other_d->m_name ||
d->m_styleUrl != other_d->m_styleUrl ||
d->m_popularity != other_d->m_popularity ||
d->m_zoomLevel != other_d->m_zoomLevel ||
d->m_visible != other_d->m_visible ||
d->m_role != other_d->m_role ||
d->m_extendedData != other_d->m_extendedData ||
*style() != *other.style()) {
return false;
}
if ((!d->m_styleMap && other_d->m_styleMap) ||
(d->m_styleMap && !other_d->m_styleMap)) {
return false;
}
if ((d->m_styleMap && other_d->m_styleMap) &&
(*d->m_styleMap != *other_d->m_styleMap)) {
return false;
}
if ((!d->m_featureExtendedData && other_d->m_featureExtendedData && other_d->m_featureExtendedData->m_abstractView) ||
(d->m_featureExtendedData && d->m_featureExtendedData->m_abstractView && !other_d->m_featureExtendedData)) {
return false;
}
if ((d->m_featureExtendedData && other_d->m_featureExtendedData) &&
(*d->m_featureExtendedData != *other_d->m_featureExtendedData)) {
return false;
}
return true;
}
EnumFeatureId GeoDataFeature::featureId() const
{
Q_D(const GeoDataFeature);
return d->featureId();
}
QString GeoDataFeature::name() const
{
Q_D(const GeoDataFeature);
return d->m_name;
}
void GeoDataFeature::setName( const QString &value )
{
Q_D(GeoDataFeature);
d->m_name = value;
}
GeoDataSnippet GeoDataFeature::snippet() const
{
Q_D(const GeoDataFeature);
return d->featureExtendedData().m_snippet;
}
void GeoDataFeature::setSnippet( const GeoDataSnippet &snippet )
{
Q_D(GeoDataFeature);
d->featureExtendedData().m_snippet = snippet;
}
QString GeoDataFeature::address() const
{
Q_D(const GeoDataFeature);
if (!d->m_featureExtendedData) {
return QString();
}
return d->featureExtendedData().m_address;
}
void GeoDataFeature::setAddress( const QString &value)
{
Q_D(GeoDataFeature);
if (value.isEmpty() && !d->m_featureExtendedData) {
return; // nothing to change
}
d->featureExtendedData().m_address = value;
}
QString GeoDataFeature::phoneNumber() const
{
Q_D(const GeoDataFeature);
if (!d->m_featureExtendedData) {
return QString();
}
return d->featureExtendedData().m_phoneNumber;
}
void GeoDataFeature::setPhoneNumber( const QString &value)
{
Q_D(GeoDataFeature);
if (value.isEmpty() && !d->m_featureExtendedData) {
return; // nothing to change
}
d->featureExtendedData().m_phoneNumber = value;
}
QString GeoDataFeature::description() const
{
Q_D(const GeoDataFeature);
if (!d->m_featureExtendedData) {
return QString();
}
return d->featureExtendedData().m_description;
}
void GeoDataFeature::setDescription( const QString &value)
{
Q_D(GeoDataFeature);
if (value.isEmpty() && !d->m_featureExtendedData) {
return; // nothing to change
}
d->featureExtendedData().m_description = value;
}
bool GeoDataFeature::descriptionIsCDATA() const
{
Q_D(const GeoDataFeature);
if (!d->m_featureExtendedData) {
return false;
}
return d->featureExtendedData().m_descriptionCDATA;
}
void GeoDataFeature::setDescriptionCDATA( bool cdata )
{
Q_D(GeoDataFeature);
d->featureExtendedData().m_descriptionCDATA = cdata;
}
const GeoDataAbstractView* GeoDataFeature::abstractView() const
{
Q_D(const GeoDataFeature);
if (!d->m_featureExtendedData) {
return nullptr;
}
return d->featureExtendedData().m_abstractView;
}
GeoDataAbstractView *GeoDataFeature::abstractView()
{
// FIXME: Calling detach() doesn't help at all because the m_abstractView
// object isn't actually copied in the Private class as well.
// detach();
Q_D(GeoDataFeature);
return d->featureExtendedData().m_abstractView;
}
void GeoDataFeature::setAbstractView( GeoDataAbstractView *abstractView )
{
Q_D(GeoDataFeature);
if (abstractView == nullptr && !d->m_featureExtendedData) {
return; // nothing to change
}
d->featureExtendedData().m_abstractView = abstractView;
}
QString GeoDataFeature::styleUrl() const
{
Q_D(const GeoDataFeature);
return d->m_styleUrl;
}
void GeoDataFeature::setStyleUrl( const QString &value )
{
Q_D(GeoDataFeature);
d->m_styleUrl = value;
if ( value.isEmpty() ) {
d->m_style = GeoDataStyle::Ptr();
return;
}
QString styleUrl = value;
styleUrl.remove(QLatin1Char('#'));
for (auto object = parent(); object != nullptr; object = object->parent()) {
if (GeoDataDocument *doc = geodata_cast<GeoDataDocument>(object)) {
GeoDataStyleMap &styleMap = doc->styleMap( styleUrl );
const QString normalStyleUrl = styleMap.value(QStringLiteral("normal"));
if (!normalStyleUrl.isEmpty()) {
styleUrl = normalStyleUrl;
styleUrl.remove(QLatin1Char('#'));
}
// Not calling setStyle here because we don't want
// re-parenting of the style
d->m_style = doc->style( styleUrl );
break;
}
}
}
bool GeoDataFeature::isVisible() const
{
Q_D(const GeoDataFeature);
return d->m_visible;
}
void GeoDataFeature::setVisible( bool value )
{
Q_D(GeoDataFeature);
d->m_visible = value;
}
bool GeoDataFeature::isGloballyVisible() const
{
Q_D(const GeoDataFeature);
- if ( parent() == 0 ) {
+ if ( parent() == nullptr ) {
return d->m_visible;
}
const GeoDataContainer *container = static_cast<const GeoDataContainer*>(parent());
return d->m_visible && container->isGloballyVisible();
}
const GeoDataTimeSpan &GeoDataFeature::timeSpan() const
{
Q_D(const GeoDataFeature);
return d->featureExtendedData().m_timeSpan;
}
GeoDataTimeSpan &GeoDataFeature::timeSpan()
{
Q_D(GeoDataFeature);
return d->featureExtendedData().m_timeSpan;
}
void GeoDataFeature::setTimeSpan( const GeoDataTimeSpan &timeSpan )
{
Q_D(GeoDataFeature);
d->featureExtendedData().m_timeSpan = timeSpan;
}
const GeoDataTimeStamp &GeoDataFeature::timeStamp() const
{
Q_D(const GeoDataFeature);
return d->featureExtendedData().m_timeStamp;
}
GeoDataTimeStamp &GeoDataFeature::timeStamp()
{
Q_D(GeoDataFeature);
return d->featureExtendedData().m_timeStamp;
}
void GeoDataFeature::setTimeStamp( const GeoDataTimeStamp &timeStamp )
{
Q_D(GeoDataFeature);
d->featureExtendedData().m_timeStamp = timeStamp;
}
const GeoDataExtendedData &GeoDataFeature::extendedData() const
{
Q_D(const GeoDataFeature);
return d->m_extendedData;
}
GeoDataStyle::ConstPtr GeoDataFeature::style() const
{
Q_D(const GeoDataFeature);
if (d->m_style) {
return d->m_style;
}
return GeoDataFeaturePrivate::s_defaultStyle;
}
GeoDataStyle::ConstPtr GeoDataFeature::customStyle() const
{
Q_D(const GeoDataFeature);
return d->m_style;
}
void GeoDataFeature::setStyle( const GeoDataStyle::Ptr &style )
{
Q_D(GeoDataFeature);
if (style)
style->setParent( this );
d->m_style = style;
}
GeoDataExtendedData& GeoDataFeature::extendedData()
{
Q_D(GeoDataFeature);
return d->m_extendedData;
}
void GeoDataFeature::setExtendedData( const GeoDataExtendedData& extendedData )
{
Q_D(GeoDataFeature);
d->m_extendedData = extendedData;
}
const GeoDataRegion& GeoDataFeature::region() const
{
Q_D(const GeoDataFeature);
return d->featureExtendedData().m_region;
}
GeoDataRegion& GeoDataFeature::region()
{
Q_D(GeoDataFeature);
return d->featureExtendedData().m_region;
}
void GeoDataFeature::setRegion( const GeoDataRegion& region )
{
Q_D(GeoDataFeature);
d->featureExtendedData().m_region = region;
}
const QString GeoDataFeature::role() const
{
Q_D(const GeoDataFeature);
return d->m_role;
}
void GeoDataFeature::setRole( const QString &role )
{
Q_D(GeoDataFeature);
d->m_role = role;
}
const GeoDataStyleMap* GeoDataFeature::styleMap() const
{
Q_D(const GeoDataFeature);
return d->m_styleMap;
}
void GeoDataFeature::setStyleMap( const GeoDataStyleMap* styleMap )
{
Q_D(GeoDataFeature);
d->m_styleMap = styleMap;
}
int GeoDataFeature::zoomLevel() const
{
Q_D(const GeoDataFeature);
return d->m_zoomLevel;
}
void GeoDataFeature::setZoomLevel( int zoomLevel )
{
Q_D(GeoDataFeature);
d->m_zoomLevel = zoomLevel;
}
qint64 GeoDataFeature::popularity() const
{
Q_D(const GeoDataFeature);
return d->m_popularity;
}
void GeoDataFeature::setPopularity( qint64 popularity )
{
Q_D(GeoDataFeature);
d->m_popularity = popularity;
}
void GeoDataFeature::pack( QDataStream& stream ) const
{
Q_D(const GeoDataFeature);
GeoDataObject::pack( stream );
stream << d->m_name;
stream << d->featureExtendedData().m_address;
stream << d->featureExtendedData().m_phoneNumber;
stream << d->featureExtendedData().m_description;
stream << d->m_visible;
// stream << d->m_visualCategory;
stream << d->m_role;
stream << d->m_popularity;
stream << d->m_zoomLevel;
}
void GeoDataFeature::unpack( QDataStream& stream )
{
Q_D(GeoDataFeature);
GeoDataObject::unpack( stream );
stream >> d->m_name;
stream >> d->featureExtendedData().m_address;
stream >> d->featureExtendedData().m_phoneNumber;
stream >> d->featureExtendedData().m_description;
stream >> d->m_visible;
// stream >> (int)d->m_visualCategory;
stream >> d->m_role;
stream >> d->m_popularity;
stream >> d->m_zoomLevel;
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataFeature_p.h b/src/lib/marble/geodata/data/GeoDataFeature_p.h
index dbca11b5a..35c8869ff 100644
--- a/src/lib/marble/geodata/data/GeoDataFeature_p.h
+++ b/src/lib/marble/geodata/data/GeoDataFeature_p.h
@@ -1,220 +1,220 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Patrick Spendrin <ps_ml@gmx.de>
//
#ifndef MARBLE_GEODATAFEATUREPRIVATE_H
#define MARBLE_GEODATAFEATUREPRIVATE_H
#include <QString>
#include "GeoDataExtendedData.h"
#include "GeoDataAbstractView.h"
#include "GeoDataFeature.h"
#include "GeoDataRegion.h"
#include "GeoDataTimeStamp.h"
#include "GeoDataTimeSpan.h"
#include "GeoDataTypes.h"
#include "GeoDataStyle.h"
#include "GeoDataSnippet.h"
#include "GeoDataLookAt.h"
#include "GeoDataCamera.h"
namespace Marble
{
class GeoDataFeatureExtendedData
{
public:
GeoDataSnippet m_snippet; // Snippet of the feature.
QString m_description; // A longer textual description
bool m_descriptionCDATA; // True if description should be considered CDATA
QString m_address; // The address. Optional
QString m_phoneNumber; // Phone Optional
GeoDataAbstractView* m_abstractView; // AbstractView Optional
GeoDataTimeSpan m_timeSpan;
GeoDataTimeStamp m_timeStamp;
GeoDataRegion m_region;
GeoDataFeatureExtendedData() :
m_snippet(),
m_description(),
m_descriptionCDATA(false),
m_address(),
m_phoneNumber(),
- m_abstractView( 0 ),
+ m_abstractView( nullptr ),
m_timeSpan(),
m_timeStamp(),
m_region()
{
// nothing to do
}
GeoDataFeatureExtendedData(const GeoDataFeatureExtendedData &other) :
m_snippet( other.m_snippet ),
m_description( other.m_description ),
m_descriptionCDATA( other.m_descriptionCDATA),
m_address( other.m_address ),
m_phoneNumber( other.m_phoneNumber ),
m_abstractView( other.m_abstractView ),
m_timeSpan( other.m_timeSpan ),
m_timeStamp( other.m_timeStamp ),
m_region( other.m_region )
{
// nothing to do
}
GeoDataFeatureExtendedData& operator=(const GeoDataFeatureExtendedData &other)
{
m_snippet = other.m_snippet;
m_description = other.m_description;
m_descriptionCDATA = other.m_descriptionCDATA;
m_address = other.m_address;
m_phoneNumber = other.m_phoneNumber;
m_abstractView = other.m_abstractView;
m_timeSpan = other.m_timeSpan;
m_timeStamp = other.m_timeStamp;
m_region = other.m_region;
return *this;
}
bool operator==(const GeoDataFeatureExtendedData &other) const
{
if (m_snippet != other.m_snippet ||
m_description != other.m_description ||
m_descriptionCDATA != other.m_descriptionCDATA ||
m_address != other.m_address ||
m_phoneNumber != other.m_phoneNumber ||
m_timeSpan != other.m_timeSpan ||
m_timeStamp != other.m_timeStamp ||
m_region != other.m_region) {
return false;
}
if ( (!m_abstractView && other.m_abstractView) ||
(m_abstractView && !other.m_abstractView) ) {
return false;
}
if (m_abstractView && other.m_abstractView) {
if (*m_abstractView != *other.m_abstractView) {
return false;
}
}
return true;
}
bool operator!=(const GeoDataFeatureExtendedData &other) const
{
return !(*this == other);
}
};
class GeoDataFeaturePrivate
{
public:
GeoDataFeaturePrivate() :
m_name(),
m_styleUrl(),
m_popularity( 0 ),
m_zoomLevel( 1 ),
m_visible( true ),
m_role(" "),
- m_style( 0 ),
- m_styleMap( 0 ),
+ m_style( nullptr ),
+ m_styleMap( nullptr ),
m_extendedData(),
m_featureExtendedData(nullptr)
{
}
GeoDataFeaturePrivate( const GeoDataFeaturePrivate& other ) :
m_name( other.m_name ),
m_styleUrl( other.m_styleUrl ),
m_popularity( other.m_popularity ),
m_zoomLevel( other.m_zoomLevel ),
m_visible( other.m_visible ),
m_role( other.m_role ),
m_style( other.m_style ), //FIXME: both style and stylemap need to be reworked internally!!!!
m_styleMap( other.m_styleMap ),
m_extendedData( other.m_extendedData ),
m_featureExtendedData(nullptr)
{
if (other.m_featureExtendedData) {
m_featureExtendedData = new GeoDataFeatureExtendedData(*other.m_featureExtendedData);
}
}
GeoDataFeaturePrivate& operator=( const GeoDataFeaturePrivate& other )
{
m_name = other.m_name;
m_styleUrl = other.m_styleUrl;
m_popularity = other.m_popularity;
m_zoomLevel = other.m_zoomLevel;
m_visible = other.m_visible;
m_role = other.m_role;
m_style = other.m_style;
m_styleMap = other.m_styleMap;
m_extendedData = other.m_extendedData;
delete m_featureExtendedData;
m_featureExtendedData = nullptr;
if (other.m_featureExtendedData) {
m_featureExtendedData = new GeoDataFeatureExtendedData(*other.m_featureExtendedData);
}
return *this;
}
virtual EnumFeatureId featureId() const
{
return InvalidFeatureId;
}
virtual ~GeoDataFeaturePrivate()
{
delete m_featureExtendedData;
}
GeoDataFeatureExtendedData & featureExtendedData()
{
if (!m_featureExtendedData) {
m_featureExtendedData = new GeoDataFeatureExtendedData;
}
return *m_featureExtendedData;
}
const GeoDataFeatureExtendedData & featureExtendedData() const
{
if (!m_featureExtendedData) {
m_featureExtendedData = new GeoDataFeatureExtendedData;
}
return *m_featureExtendedData;
}
QString m_name; // Name of the feature. Is shown on screen
QString m_styleUrl; // styleUrl Url#tag to a document wide style
qint64 m_popularity; // Population/Area/Altitude depending on placemark(!)
int m_zoomLevel; // Zoom Level of the feature
bool m_visible; // True if this feature should be shown.
QString m_role;
GeoDataStyle::Ptr m_style;
const GeoDataStyleMap* m_styleMap;
GeoDataExtendedData m_extendedData;
mutable GeoDataFeatureExtendedData* m_featureExtendedData;
// Static members
static const QSharedPointer<const GeoDataStyle> s_defaultStyle;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/geodata/data/GeoDataFlyTo.cpp b/src/lib/marble/geodata/data/GeoDataFlyTo.cpp
index daa5db6be..aea4f7107 100644
--- a/src/lib/marble/geodata/data/GeoDataFlyTo.cpp
+++ b/src/lib/marble/geodata/data/GeoDataFlyTo.cpp
@@ -1,125 +1,125 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "GeoDataFlyTo.h"
#include "GeoDataTypes.h"
#include "GeoDataAbstractView.h"
namespace Marble {
class GeoDataFlyToPrivate
{
public:
double m_duration;
GeoDataFlyTo::FlyToMode m_flyToMode;
GeoDataAbstractView* m_view;
GeoDataFlyToPrivate();
};
GeoDataFlyToPrivate::GeoDataFlyToPrivate() :
- m_duration( 0.0 ), m_flyToMode(), m_view( 0 )
+ m_duration( 0.0 ), m_flyToMode(), m_view( nullptr )
{
}
GeoDataFlyTo::GeoDataFlyTo() : d( new GeoDataFlyToPrivate )
{
}
GeoDataFlyTo::GeoDataFlyTo( const Marble::GeoDataFlyTo &other ) :
GeoDataTourPrimitive( other ), d( new GeoDataFlyToPrivate( *other.d ) )
{
}
GeoDataFlyTo &GeoDataFlyTo::operator=( const GeoDataFlyTo &other )
{
GeoDataTourPrimitive::operator=( other );
*d = *other.d;
return *this;
}
bool GeoDataFlyTo::operator==( const GeoDataFlyTo& other ) const
{
if ( !equals(other) ||
d->m_duration != other.d->m_duration ||
d->m_flyToMode != other.d->m_flyToMode ) {
return false;
}
if ( (!d->m_view && other.d->m_view) ||
(d->m_view && !other.d->m_view) ) {
return false;
} else if ( !d->m_view && !other.d->m_view ) {
return true;
}
if (*d->m_view != *other.d->m_view) {
return false;
}
return true;
}
bool GeoDataFlyTo::operator!=( const GeoDataFlyTo& other ) const
{
return !this->operator==(other);
}
GeoDataFlyTo::~GeoDataFlyTo()
{
delete d;
}
const char *GeoDataFlyTo::nodeType() const
{
return GeoDataTypes::GeoDataFlyToType;
}
const GeoDataAbstractView *GeoDataFlyTo::view() const
{
return d->m_view;
}
GeoDataAbstractView *GeoDataFlyTo::view()
{
return d->m_view;
}
void GeoDataFlyTo::setView( GeoDataAbstractView *view )
{
d->m_view = view;
}
double GeoDataFlyTo::duration() const
{
return d->m_duration;
}
void GeoDataFlyTo::setDuration( double duration )
{
d->m_duration = duration;
}
GeoDataFlyTo::FlyToMode GeoDataFlyTo::flyToMode() const
{
return d->m_flyToMode;
}
void GeoDataFlyTo::setFlyToMode( const GeoDataFlyTo::FlyToMode flyToMode )
{
d->m_flyToMode = flyToMode;
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataLineString.cpp b/src/lib/marble/geodata/data/GeoDataLineString.cpp
index edb6133ae..1ae6aebef 100644
--- a/src/lib/marble/geodata/data/GeoDataLineString.cpp
+++ b/src/lib/marble/geodata/data/GeoDataLineString.cpp
@@ -1,964 +1,964 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <rahn@kde.org>
// Copyright 2009 Patrick Spendrin <ps_ml@gmx.de>
//
#include "GeoDataLineString.h"
#include "GeoDataLineString_p.h"
#include "GeoDataLinearRing.h"
#include "GeoDataTypes.h"
#include "Quaternion.h"
#include "MarbleDebug.h"
#include <QDataStream>
namespace Marble
{
GeoDataLineString::GeoDataLineString( TessellationFlags f )
: GeoDataGeometry( new GeoDataLineStringPrivate( f ) )
{
// mDebug() << "1) GeoDataLineString created:" << p();
}
GeoDataLineString::GeoDataLineString( GeoDataLineStringPrivate* priv )
: GeoDataGeometry( priv )
{
// mDebug() << "2) GeoDataLineString created:" << p();
}
GeoDataLineString::GeoDataLineString( const GeoDataGeometry & other )
: GeoDataGeometry( other )
{
// mDebug() << "3) GeoDataLineString created:" << p();
}
GeoDataLineString::~GeoDataLineString()
{
#ifdef DEBUG_GEODATA
mDebug() << "delete Linestring";
#endif
}
const char *GeoDataLineString::nodeType() const
{
return GeoDataTypes::GeoDataLineStringType;
}
EnumGeometryId GeoDataLineString::geometryId() const
{
return GeoDataLineStringId;
}
GeoDataGeometry *GeoDataLineString::copy() const
{
return new GeoDataLineString(*this);
}
void GeoDataLineStringPrivate::interpolateDateLine( const GeoDataCoordinates & previousCoords,
const GeoDataCoordinates & currentCoords,
GeoDataCoordinates & previousAtDateLine,
GeoDataCoordinates & currentAtDateLine,
TessellationFlags f ) const
{
GeoDataCoordinates dateLineCoords;
// mDebug() << Q_FUNC_INFO;
if ( f.testFlag( RespectLatitudeCircle ) && previousCoords.latitude() == currentCoords.latitude() ) {
dateLineCoords = currentCoords;
}
else {
int recursionCounter = 0;
dateLineCoords = findDateLine( previousCoords, currentCoords, recursionCounter );
}
previousAtDateLine = dateLineCoords;
currentAtDateLine = dateLineCoords;
if ( previousCoords.longitude() < 0 ) {
previousAtDateLine.setLongitude( -M_PI );
currentAtDateLine.setLongitude( +M_PI );
}
else {
previousAtDateLine.setLongitude( +M_PI );
currentAtDateLine.setLongitude( -M_PI );
}
}
GeoDataCoordinates GeoDataLineStringPrivate::findDateLine( const GeoDataCoordinates & previousCoords,
const GeoDataCoordinates & currentCoords,
int recursionCounter ) const
{
int currentSign = ( currentCoords.longitude() < 0.0 ) ? -1 : +1 ;
int previousSign = ( previousCoords.longitude() < 0.0 ) ? -1 : +1 ;
qreal longitudeDiff = fabs( previousSign * M_PI - previousCoords.longitude() )
+ fabs( currentSign * M_PI - currentCoords.longitude() );
if ( longitudeDiff < 0.001 || recursionCounter == 100 ) {
// mDebug() << "stopped at recursion" << recursionCounter << " and longitude difference " << longitudeDiff;
return currentCoords;
}
++recursionCounter;
qreal lon = 0.0;
qreal lat = 0.0;
qreal altDiff = currentCoords.altitude() - previousCoords.altitude();
const Quaternion itpos = Quaternion::nlerp( previousCoords.quaternion(), currentCoords.quaternion(), 0.5 );
itpos.getSpherical( lon, lat );
qreal altitude = previousCoords.altitude() + 0.5 * altDiff;
GeoDataCoordinates interpolatedCoords( lon, lat, altitude );
int interpolatedSign = ( interpolatedCoords.longitude() < 0.0 ) ? -1 : +1 ;
/*
mDebug() << "SRC" << previousCoords.toString();
mDebug() << "TAR" << currentCoords.toString();
mDebug() << "IPC" << interpolatedCoords.toString();
*/
if ( interpolatedSign != currentSign ) {
return findDateLine( interpolatedCoords, currentCoords, recursionCounter );
}
return findDateLine( previousCoords, interpolatedCoords, recursionCounter );
}
quint8 GeoDataLineStringPrivate::levelForResolution(qreal resolution) const {
if (m_previousResolution == resolution) return m_level;
m_previousResolution = resolution;
if (resolution < 0.0000005) m_level = 17;
else if (resolution < 0.0000010) m_level = 16;
else if (resolution < 0.0000020) m_level = 15;
else if (resolution < 0.0000040) m_level = 14;
else if (resolution < 0.0000080) m_level = 13;
else if (resolution < 0.0000160) m_level = 12;
else if (resolution < 0.0000320) m_level = 11;
else if (resolution < 0.0000640) m_level = 10;
else if (resolution < 0.0001280) m_level = 9;
else if (resolution < 0.0002560) m_level = 8;
else if (resolution < 0.0005120) m_level = 7;
else if (resolution < 0.0010240) m_level = 6;
else if (resolution < 0.0020480) m_level = 5;
else if (resolution < 0.0040960) m_level = 4;
else if (resolution < 0.0081920) m_level = 3;
else if (resolution < 0.0163840) m_level = 2;
else m_level = 1;
return m_level;
}
qreal GeoDataLineStringPrivate::resolutionForLevel(int level)
{
switch (level) {
case 0:
return 0.0655360;
break;
case 1:
return 0.0327680;
break;
case 2:
return 0.0163840;
break;
case 3:
return 0.0081920;
break;
case 4:
return 0.0040960;
break;
case 5:
return 0.0020480;
break;
case 6:
return 0.0010240;
break;
case 7:
return 0.0005120;
break;
case 8:
return 0.0002560;
break;
case 9:
return 0.0001280;
break;
case 10:
return 0.0000640;
break;
case 11:
return 0.0000320;
break;
case 12:
return 0.0000160;
break;
case 13:
return 0.0000080;
break;
case 14:
return 0.0000040;
break;
case 15:
return 0.0000020;
break;
case 16:
return 0.0000010;
break;
default:
case 17:
return 0.0000005;
break;
}
}
void GeoDataLineStringPrivate::optimize (GeoDataLineString& lineString) const
{
QVector<GeoDataCoordinates>::iterator itCoords = lineString.begin();
QVector<GeoDataCoordinates>::const_iterator itEnd = lineString.constEnd();
if (lineString.size() < 2) return;
// Calculate the least non-zero detail-level by checking the bounding box
quint8 startLevel = levelForResolution( ( lineString.latLonAltBox().width() + lineString.latLonAltBox().height() ) / 2 );
quint8 currentLevel = startLevel;
quint8 maxLevel = startLevel;
GeoDataCoordinates currentCoords;
lineString.first().setDetail(startLevel);
// Iterate through the linestring to assign different detail levels to the nodes.
// In general the first and last node should have the start level assigned as
// a detail level.
// Starting from the first node the algorithm picks those nodes which
// have a distance from each other that is just above the resolution that is
// associated with the start level (which we use as a "current level").
// Each of those nodes get the current level assigned as the detail level.
// After iterating through the linestring we increment the current level value
// and starting again with the first node we assign detail values in a similar way
// to the remaining nodes which have no final detail level assigned yet.
// We do as many iterations through the lineString as needed and bump up the
// current level until all nodes have a non-zero detail level assigned.
while ( currentLevel < 16 && currentLevel <= maxLevel + 1 ) {
itCoords = lineString.begin();
currentCoords = *itCoords;
++itCoords;
for( ; itCoords != itEnd; ++itCoords) {
if (itCoords->detail() != 0 && itCoords->detail() < currentLevel) continue;
if ( currentLevel == startLevel && (itCoords->longitude() == -M_PI || itCoords->longitude() == M_PI
|| itCoords->latitude() < -89 * DEG2RAD || itCoords->latitude() > 89 * DEG2RAD)) {
itCoords->setDetail(startLevel);
currentCoords = *itCoords;
maxLevel = currentLevel;
continue;
}
if (currentCoords.sphericalDistanceTo(*itCoords) < resolutionForLevel(currentLevel + 1)) {
itCoords->setDetail(currentLevel + 1);
}
else {
itCoords->setDetail(currentLevel);
currentCoords = *itCoords;
maxLevel = currentLevel;
}
}
++currentLevel;
}
lineString.last().setDetail(startLevel);
}
bool GeoDataLineString::isEmpty() const
{
Q_D(const GeoDataLineString);
return d->m_vector.isEmpty();
}
int GeoDataLineString::size() const
{
Q_D(const GeoDataLineString);
return d->m_vector.size();
}
GeoDataCoordinates& GeoDataLineString::at( int pos )
{
detach();
Q_D(GeoDataLineString);
d->m_dirtyRange = true;
d->m_dirtyBox = true;
return d->m_vector[pos];
}
const GeoDataCoordinates& GeoDataLineString::at( int pos ) const
{
Q_D(const GeoDataLineString);
return d->m_vector.at(pos);
}
GeoDataCoordinates& GeoDataLineString::operator[]( int pos )
{
detach();
Q_D(GeoDataLineString);
d->m_dirtyRange = true;
d->m_dirtyBox = true;
return d->m_vector[pos];
}
GeoDataLineString GeoDataLineString::mid(int pos, int length) const
{
GeoDataLineString substring;
auto d = substring.d_func();
d->m_vector = d_func()->m_vector.mid(pos, length);
d->m_dirtyBox = true;
d->m_dirtyRange = true;
d->m_tessellationFlags = d_func()->m_tessellationFlags;
d->m_extrude = d_func()->m_extrude;
return substring;
}
const GeoDataCoordinates& GeoDataLineString::operator[]( int pos ) const
{
Q_D(const GeoDataLineString);
return d->m_vector[pos];
}
GeoDataCoordinates& GeoDataLineString::last()
{
detach();
Q_D(GeoDataLineString);
d->m_dirtyRange = true;
d->m_dirtyBox = true;
return d->m_vector.last();
}
GeoDataCoordinates& GeoDataLineString::first()
{
detach();
Q_D(GeoDataLineString);
return d->m_vector.first();
}
const GeoDataCoordinates& GeoDataLineString::last() const
{
Q_D(const GeoDataLineString);
return d->m_vector.last();
}
const GeoDataCoordinates& GeoDataLineString::first() const
{
Q_D(const GeoDataLineString);
return d->m_vector.first();
}
QVector<GeoDataCoordinates>::Iterator GeoDataLineString::begin()
{
detach();
Q_D(GeoDataLineString);
return d->m_vector.begin();
}
QVector<GeoDataCoordinates>::ConstIterator GeoDataLineString::begin() const
{
Q_D(const GeoDataLineString);
return d->m_vector.constBegin();
}
QVector<GeoDataCoordinates>::Iterator GeoDataLineString::end()
{
detach();
Q_D(GeoDataLineString);
return d->m_vector.end();
}
QVector<GeoDataCoordinates>::ConstIterator GeoDataLineString::end() const
{
Q_D(const GeoDataLineString);
return d->m_vector.constEnd();
}
QVector<GeoDataCoordinates>::ConstIterator GeoDataLineString::constBegin() const
{
Q_D(const GeoDataLineString);
return d->m_vector.constBegin();
}
QVector<GeoDataCoordinates>::ConstIterator GeoDataLineString::constEnd() const
{
Q_D(const GeoDataLineString);
return d->m_vector.constEnd();
}
void GeoDataLineString::insert( int index, const GeoDataCoordinates& value )
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
d->m_vector.insert( index, value );
}
void GeoDataLineString::append ( const GeoDataCoordinates& value )
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
d->m_vector.append( value );
}
void GeoDataLineString::reserve(int size)
{
Q_D(GeoDataLineString);
d->m_vector.reserve(size);
}
void GeoDataLineString::append(const QVector<GeoDataCoordinates>& values)
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
#if QT_VERSION >= 0x050500
d->m_vector.append(values);
#else
d->m_vector.reserve(d->m_vector.size() + values.size());
for (const GeoDataCoordinates &coordinates: values) {
d->m_vector.append(coordinates);
}
#endif
}
GeoDataLineString& GeoDataLineString::operator << ( const GeoDataCoordinates& value )
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
d->m_vector.append( value );
return *this;
}
GeoDataLineString& GeoDataLineString::operator << ( const GeoDataLineString& value )
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
QVector<GeoDataCoordinates>::const_iterator itCoords = value.constBegin();
QVector<GeoDataCoordinates>::const_iterator itEnd = value.constEnd();
d->m_vector.reserve(d->m_vector.size() + value.size());
for( ; itCoords != itEnd; ++itCoords ) {
d->m_vector.append( *itCoords );
}
return *this;
}
bool GeoDataLineString::operator==( const GeoDataLineString &other ) const
{
if ( !GeoDataGeometry::equals(other) ||
size() != other.size() ||
tessellate() != other.tessellate() ) {
return false;
}
Q_D(const GeoDataLineString);
const GeoDataLineStringPrivate* other_d = other.d_func();
QVector<GeoDataCoordinates>::const_iterator itCoords = d->m_vector.constBegin();
QVector<GeoDataCoordinates>::const_iterator otherItCoords = other_d->m_vector.constBegin();
QVector<GeoDataCoordinates>::const_iterator itEnd = d->m_vector.constEnd();
QVector<GeoDataCoordinates>::const_iterator otherItEnd = other_d->m_vector.constEnd();
for ( ; itCoords != itEnd && otherItCoords != otherItEnd; ++itCoords, ++otherItCoords ) {
if ( *itCoords != *otherItCoords ) {
return false;
}
}
Q_ASSERT ( itCoords == itEnd && otherItCoords == otherItEnd );
return true;
}
bool GeoDataLineString::operator!=( const GeoDataLineString &other ) const
{
return !this->operator==(other);
}
void GeoDataLineString::clear()
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
d->m_vector.clear();
}
bool GeoDataLineString::isClosed() const
{
return false;
}
bool GeoDataLineString::tessellate() const
{
Q_D(const GeoDataLineString);
return d->m_tessellationFlags.testFlag(Tessellate);
}
void GeoDataLineString::setTessellate( bool tessellate )
{
detach();
Q_D(GeoDataLineString);
// According to the KML reference the tesselation of line strings in Google Earth
// is generally done along great circles. However for subsequent points that share
// the same latitude the latitude circles are followed. Our Tesselate and RespectLatitude
// Flags provide this behaviour. For true polygons the latitude circles don't get considered.
if (tessellate) {
d->m_tessellationFlags |= (Tessellate | RespectLatitudeCircle);
} else {
d->m_tessellationFlags &= ~(Tessellate | RespectLatitudeCircle);
}
}
TessellationFlags GeoDataLineString::tessellationFlags() const
{
Q_D(const GeoDataLineString);
return d->m_tessellationFlags;
}
void GeoDataLineString::setTessellationFlags( TessellationFlags f )
{
detach();
Q_D(GeoDataLineString);
d->m_tessellationFlags = f;
}
void GeoDataLineString::reverse()
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
std::reverse(begin(), end());
}
GeoDataLineString GeoDataLineString::toNormalized() const
{
Q_D(const GeoDataLineString);
GeoDataLineString normalizedLineString;
normalizedLineString.setTessellationFlags( tessellationFlags() );
qreal lon;
qreal lat;
// FIXME: Think about how we can avoid unnecessary copies
// if the linestring stays the same.
QVector<GeoDataCoordinates>::const_iterator end = d->m_vector.constEnd();
for( QVector<GeoDataCoordinates>::const_iterator itCoords
= d->m_vector.constBegin();
itCoords != end;
++itCoords ) {
itCoords->geoCoordinates( lon, lat );
qreal alt = itCoords->altitude();
GeoDataCoordinates::normalizeLonLat( lon, lat );
GeoDataCoordinates normalizedCoords( *itCoords );
normalizedCoords.set( lon, lat, alt );
normalizedLineString << normalizedCoords;
}
return normalizedLineString;
}
GeoDataLineString GeoDataLineString::toRangeCorrected() const
{
Q_D(const GeoDataLineString);
if (d->m_dirtyRange) {
delete d->m_rangeCorrected;
if( isClosed() ) {
d->m_rangeCorrected = new GeoDataLinearRing(toPoleCorrected());
} else {
d->m_rangeCorrected = new GeoDataLineString(toPoleCorrected());
}
d->m_dirtyRange = false;
}
return *d->m_rangeCorrected;
}
QVector<GeoDataLineString*> GeoDataLineString::toDateLineCorrected() const
{
Q_D(const GeoDataLineString);
QVector<GeoDataLineString*> lineStrings;
d->toDateLineCorrected(*this, lineStrings);
return lineStrings;
}
GeoDataLineString GeoDataLineString::toPoleCorrected() const
{
Q_D(const GeoDataLineString);
if( isClosed() ) {
GeoDataLinearRing poleCorrected;
d->toPoleCorrected(*this, poleCorrected);
return poleCorrected;
} else {
GeoDataLineString poleCorrected;
d->toPoleCorrected(*this, poleCorrected);
return poleCorrected;
}
}
void GeoDataLineStringPrivate::toPoleCorrected( const GeoDataLineString& q, GeoDataLineString& poleCorrected ) const
{
poleCorrected.setTessellationFlags( q.tessellationFlags() );
GeoDataCoordinates previousCoords;
GeoDataCoordinates currentCoords;
if ( q.isClosed() ) {
if ( !( m_vector.first().isPole() ) &&
( m_vector.last().isPole() ) ) {
qreal firstLongitude = ( m_vector.first() ).longitude();
GeoDataCoordinates modifiedCoords( m_vector.last() );
modifiedCoords.setLongitude( firstLongitude );
poleCorrected << modifiedCoords;
}
}
QVector<GeoDataCoordinates>::const_iterator itCoords = m_vector.constBegin();
QVector<GeoDataCoordinates>::const_iterator itEnd = m_vector.constEnd();
for( ; itCoords != itEnd; ++itCoords ) {
currentCoords = *itCoords;
if ( itCoords == m_vector.constBegin() ) {
previousCoords = currentCoords;
}
if ( currentCoords.isPole() ) {
if ( previousCoords.isPole() ) {
continue;
}
else {
qreal previousLongitude = previousCoords.longitude();
GeoDataCoordinates currentModifiedCoords( currentCoords );
currentModifiedCoords.setLongitude( previousLongitude );
poleCorrected << currentModifiedCoords;
}
}
else {
if ( previousCoords.isPole() ) {
qreal currentLongitude = currentCoords.longitude();
GeoDataCoordinates previousModifiedCoords( previousCoords );
previousModifiedCoords.setLongitude( currentLongitude );
poleCorrected << previousModifiedCoords;
poleCorrected << currentCoords;
}
else {
// No poles at all. Nothing special to handle
poleCorrected << currentCoords;
}
}
previousCoords = currentCoords;
}
if ( q.isClosed() ) {
if ( ( m_vector.first().isPole() ) &&
!( m_vector.last().isPole() ) ) {
qreal lastLongitude = ( m_vector.last() ).longitude();
GeoDataCoordinates modifiedCoords( m_vector.first() );
modifiedCoords.setLongitude( lastLongitude );
poleCorrected << modifiedCoords;
}
}
}
void GeoDataLineStringPrivate::toDateLineCorrected(
const GeoDataLineString & q,
QVector<GeoDataLineString*> & lineStrings
) const
{
const bool isClosed = q.isClosed();
const QVector<GeoDataCoordinates>::const_iterator itStartPoint = q.constBegin();
const QVector<GeoDataCoordinates>::const_iterator itEndPoint = q.constEnd();
QVector<GeoDataCoordinates>::const_iterator itPoint = itStartPoint;
QVector<GeoDataCoordinates>::const_iterator itPreviousPoint = itPoint;
TessellationFlags f = q.tessellationFlags();
- GeoDataLineString * unfinishedLineString = 0;
+ GeoDataLineString * unfinishedLineString = nullptr;
GeoDataLineString * dateLineCorrected = isClosed ? new GeoDataLinearRing( f )
: new GeoDataLineString( f );
qreal currentLon = 0.0;
qreal previousLon = 0.0;
int previousSign = 1;
bool unfinished = false;
for (; itPoint != itEndPoint; ++itPoint ) {
currentLon = itPoint->longitude();
int currentSign = ( currentLon < 0.0 ) ? -1 : +1 ;
if( itPoint == q.constBegin() ) {
previousSign = currentSign;
previousLon = currentLon;
}
// If we are crossing the date line ...
if ( previousSign != currentSign && fabs(previousLon) + fabs(currentLon) > M_PI ) {
unfinished = !unfinished;
GeoDataCoordinates previousTemp;
GeoDataCoordinates currentTemp;
interpolateDateLine( *itPreviousPoint, *itPoint,
previousTemp, currentTemp, q.tessellationFlags() );
*dateLineCorrected << previousTemp;
if ( isClosed && unfinished ) {
// If it's a linear ring and if it crossed the IDL only once then
// store the current string inside the unfinishedLineString for later use ...
unfinishedLineString = dateLineCorrected;
// ... and start a new linear ring for now.
dateLineCorrected = new GeoDataLinearRing( f );
}
else {
// Now it can only be a (finished) line string or a finished linear ring.
// Store it in the vector if the size is not zero.
if ( dateLineCorrected->size() > 0 ) {
lineStrings << dateLineCorrected;
}
else {
// Or delete it.
delete dateLineCorrected;
}
// If it's a finished linear ring restore the "remembered" unfinished String
if ( isClosed && !unfinished && unfinishedLineString ) {
dateLineCorrected = unfinishedLineString;
}
else {
// if it's a line string just create a new line string.
dateLineCorrected = new GeoDataLineString( f );
}
}
*dateLineCorrected << currentTemp;
*dateLineCorrected << *itPoint;
}
else {
*dateLineCorrected << *itPoint;
}
previousSign = currentSign;
previousLon = currentLon;
itPreviousPoint = itPoint;
}
// If the line string doesn't cross the dateline an even number of times
// then need to take care of the data stored in the unfinishedLineString
if ( unfinished && unfinishedLineString && !unfinishedLineString->isEmpty() ) {
*dateLineCorrected << *unfinishedLineString;
delete unfinishedLineString;
}
lineStrings << dateLineCorrected;
}
const GeoDataLatLonAltBox& GeoDataLineString::latLonAltBox() const
{
Q_D(const GeoDataLineString);
// GeoDataLatLonAltBox::fromLineString is very expensive
// that's why we recreate it only if the m_dirtyBox
// is TRUE.
// DO NOT REMOVE THIS CONSTRUCT OR MARBLE WILL BE SLOW.
if (d->m_dirtyBox) {
d->m_latLonAltBox = GeoDataLatLonAltBox::fromLineString(*this);
d->m_dirtyBox = false;
}
return d->m_latLonAltBox;
}
qreal GeoDataLineString::length( qreal planetRadius, int offset ) const
{
if( offset < 0 || offset >= size() ) {
return 0;
}
Q_D(const GeoDataLineString);
qreal length = 0.0;
QVector<GeoDataCoordinates> const & vector = d->m_vector;
int const start = qMax(offset+1, 1);
int const end = d->m_vector.size();
for( int i=start; i<end; ++i )
{
length += vector[i-1].sphericalDistanceTo(vector[i]);
}
return planetRadius * length;
}
QVector<GeoDataCoordinates>::Iterator GeoDataLineString::erase ( const QVector<GeoDataCoordinates>::Iterator& pos )
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
return d->m_vector.erase( pos );
}
QVector<GeoDataCoordinates>::Iterator GeoDataLineString::erase ( const QVector<GeoDataCoordinates>::Iterator& begin,
const QVector<GeoDataCoordinates>::Iterator& end )
{
detach();
Q_D(GeoDataLineString);
delete d->m_rangeCorrected;
- d->m_rangeCorrected = 0;
+ d->m_rangeCorrected = nullptr;
d->m_dirtyRange = true;
d->m_dirtyBox = true;
return d->m_vector.erase( begin, end );
}
void GeoDataLineString::remove ( int i )
{
detach();
Q_D(GeoDataLineString);
d->m_dirtyRange = true;
d->m_dirtyBox = true;
d->m_vector.remove( i );
}
GeoDataLineString GeoDataLineString::optimized () const
{
Q_D(const GeoDataLineString);
if( isClosed() ) {
GeoDataLinearRing linearRing(*this);
d->optimize(linearRing);
return linearRing;
} else {
GeoDataLineString lineString(*this);
d->optimize(lineString);
return lineString;
}
}
void GeoDataLineString::pack( QDataStream& stream ) const
{
Q_D(const GeoDataLineString);
GeoDataGeometry::pack( stream );
stream << size();
stream << (qint32)(d->m_tessellationFlags);
for( QVector<GeoDataCoordinates>::const_iterator iterator
= d->m_vector.constBegin();
iterator != d->m_vector.constEnd();
++iterator ) {
mDebug() << "innerRing: size" << d->m_vector.size();
GeoDataCoordinates coord = ( *iterator );
coord.pack( stream );
}
}
void GeoDataLineString::unpack( QDataStream& stream )
{
detach();
Q_D(GeoDataLineString);
GeoDataGeometry::unpack( stream );
qint32 size;
qint32 tessellationFlags;
stream >> size;
stream >> tessellationFlags;
d->m_tessellationFlags = (TessellationFlags)(tessellationFlags);
d->m_vector.reserve(d->m_vector.size() + size);
for(qint32 i = 0; i < size; i++ ) {
GeoDataCoordinates coord;
coord.unpack( stream );
d->m_vector.append( coord );
}
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataLineString_p.h b/src/lib/marble/geodata/data/GeoDataLineString_p.h
index f6ecd6ff0..5a07af37c 100644
--- a/src/lib/marble/geodata/data/GeoDataLineString_p.h
+++ b/src/lib/marble/geodata/data/GeoDataLineString_p.h
@@ -1,100 +1,100 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Patrick Spendrin <ps_ml@gmx.de>
//
#ifndef MARBLE_GEODATALINESTRINGPRIVATE_H
#define MARBLE_GEODATALINESTRINGPRIVATE_H
#include "GeoDataGeometry_p.h"
#include "GeoDataTypes.h"
namespace Marble
{
class GeoDataLineStringPrivate : public GeoDataGeometryPrivate
{
public:
explicit GeoDataLineStringPrivate( TessellationFlags f )
- : m_rangeCorrected( 0 ),
+ : m_rangeCorrected( nullptr ),
m_dirtyRange( true ),
m_dirtyBox( true ),
m_tessellationFlags( f ),
m_previousResolution( -1 ),
m_level( -1 )
{
}
GeoDataLineStringPrivate()
- : m_rangeCorrected( 0 ),
+ : m_rangeCorrected( nullptr ),
m_dirtyRange( true ),
m_dirtyBox( true )
{
}
~GeoDataLineStringPrivate() override
{
delete m_rangeCorrected;
}
GeoDataLineStringPrivate& operator=( const GeoDataLineStringPrivate &other)
{
GeoDataGeometryPrivate::operator=( other );
m_vector = other.m_vector;
- m_rangeCorrected = 0;
+ m_rangeCorrected = nullptr;
m_dirtyRange = true;
m_dirtyBox = other.m_dirtyBox;
m_tessellationFlags = other.m_tessellationFlags;
return *this;
}
GeoDataGeometryPrivate *copy() const override
{
GeoDataLineStringPrivate* copy = new GeoDataLineStringPrivate;
*copy = *this;
return copy;
}
void toPoleCorrected( const GeoDataLineString & q, GeoDataLineString & poleCorrected ) const;
void toDateLineCorrected( const GeoDataLineString & q,
QVector<GeoDataLineString*> & lineStrings ) const;
void interpolateDateLine( const GeoDataCoordinates & previousCoords,
const GeoDataCoordinates & currentCoords,
GeoDataCoordinates & previousAtDateline,
GeoDataCoordinates & currentAtDateline,
TessellationFlags f ) const;
GeoDataCoordinates findDateLine( const GeoDataCoordinates & previousCoords,
const GeoDataCoordinates & currentCoords,
int recursionCounter ) const;
quint8 levelForResolution(qreal resolution) const;
static qreal resolutionForLevel(int level);
void optimize(GeoDataLineString& lineString) const;
QVector<GeoDataCoordinates> m_vector;
mutable GeoDataLineString* m_rangeCorrected;
mutable bool m_dirtyRange;
mutable bool m_dirtyBox; // tells whether there have been changes to the
// GeoDataPoints since the LatLonAltBox has
// been calculated. Saves performance.
TessellationFlags m_tessellationFlags;
mutable qreal m_previousResolution;
mutable quint8 m_level;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/geodata/data/GeoDataNetworkLinkControl_p.h b/src/lib/marble/geodata/data/GeoDataNetworkLinkControl_p.h
index eecef4de9..94dbd61ee 100644
--- a/src/lib/marble/geodata/data/GeoDataNetworkLinkControl_p.h
+++ b/src/lib/marble/geodata/data/GeoDataNetworkLinkControl_p.h
@@ -1,97 +1,97 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#ifndef GEODATANETWORKLINKCONTROL_P_H
#define GEODATANETWORKLINKCONTROL_P_H
#include "GeoDataContainer_p.h"
#include "GeoDataTypes.h"
#include "GeoDataUpdate.h"
#include <QDateTime>
namespace Marble
{
class GeoDataNetworkLinkControlPrivate : public GeoDataContainerPrivate
{
public:
GeoDataNetworkLinkControlPrivate();
GeoDataNetworkLinkControlPrivate(const GeoDataNetworkLinkControlPrivate &other);
~GeoDataNetworkLinkControlPrivate() override;
GeoDataNetworkLinkControlPrivate& operator=(const GeoDataNetworkLinkControlPrivate &other);
qreal m_minRefreshPeriod;
qreal m_maxSessionLength;
QString m_cookie;
QString m_message;
QString m_linkName;
QString m_linkDescription;
QString m_linkSnippet;
int m_maxLines;
QDateTime m_expires;
GeoDataUpdate m_update;
GeoDataAbstractView *m_abstractView;
};
GeoDataNetworkLinkControlPrivate::GeoDataNetworkLinkControlPrivate() :
m_minRefreshPeriod( 0.0 ),
m_maxSessionLength( 0.0 ),
m_maxLines( 2 ),
m_expires(),
m_update(),
- m_abstractView( 0 )
+ m_abstractView( nullptr )
{
}
GeoDataNetworkLinkControlPrivate::GeoDataNetworkLinkControlPrivate( const GeoDataNetworkLinkControlPrivate &other )
: GeoDataContainerPrivate(other),
m_minRefreshPeriod(other.m_minRefreshPeriod),
m_maxSessionLength(other.m_maxSessionLength),
m_cookie(other.m_cookie),
m_message(other.m_message),
m_linkName(other.m_linkName),
m_linkDescription(other.m_linkDescription),
m_linkSnippet(other.m_linkSnippet),
m_maxLines(other.m_maxLines),
m_expires(other.m_expires),
m_update(other.m_update),
- m_abstractView(other.m_abstractView ? other.m_abstractView->copy() : 0)
+ m_abstractView(other.m_abstractView ? other.m_abstractView->copy() : nullptr)
{
}
GeoDataNetworkLinkControlPrivate::~GeoDataNetworkLinkControlPrivate()
{
delete m_abstractView;
}
GeoDataNetworkLinkControlPrivate& GeoDataNetworkLinkControlPrivate::operator=(const GeoDataNetworkLinkControlPrivate &other)
{
GeoDataContainerPrivate::operator=(other);
m_minRefreshPeriod = other.m_minRefreshPeriod;
m_maxSessionLength = other.m_maxSessionLength;
m_cookie = other.m_cookie;
m_message = other.m_message;
m_linkName = other.m_linkName;
m_linkDescription = other.m_linkDescription;
m_linkSnippet = other.m_linkSnippet;
m_maxLines = other.m_maxLines;
m_expires = other.m_expires;
m_update = other.m_update;
delete m_abstractView;
- m_abstractView = other.m_abstractView ? other.m_abstractView->copy() : 0;
+ m_abstractView = other.m_abstractView ? other.m_abstractView->copy() : nullptr;
return *this;
}
}
#endif
diff --git a/src/lib/marble/geodata/data/GeoDataObject.cpp b/src/lib/marble/geodata/data/GeoDataObject.cpp
index 15c098873..ae359260b 100644
--- a/src/lib/marble/geodata/data/GeoDataObject.cpp
+++ b/src/lib/marble/geodata/data/GeoDataObject.cpp
@@ -1,136 +1,136 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Murad Tagirov <tmurad@gmail.com>
// Copyright 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
//
#include "GeoDataObject.h"
#include <QtGlobal>
#include <QDataStream>
#include <QFileInfo>
#include <QUrl>
#include "GeoDataDocument.h"
#include "GeoDataTypes.h"
namespace Marble
{
class GeoDataObjectPrivate
{
public:
GeoDataObjectPrivate()
: m_id(),
m_targetId(),
- m_parent(0)
+ m_parent(nullptr)
{
}
QString m_id;
QString m_targetId;
GeoDataObject *m_parent;
};
GeoDataObject::GeoDataObject()
: GeoNode(), Serializable(),
d( new GeoDataObjectPrivate() )
{
}
GeoDataObject::GeoDataObject( GeoDataObject const & other )
: GeoNode(), Serializable( other ),
d( new GeoDataObjectPrivate( *other.d ) )
{
}
GeoDataObject & GeoDataObject::operator=( const GeoDataObject & rhs )
{
*d = *rhs.d;
return *this;
}
GeoDataObject::~GeoDataObject()
{
delete d;
}
const GeoDataObject *GeoDataObject::parent() const
{
return d->m_parent;
}
GeoDataObject *GeoDataObject::parent()
{
return d->m_parent;
}
void GeoDataObject::setParent(GeoDataObject *parent)
{
d->m_parent = parent;
}
QString GeoDataObject::id() const
{
return d->m_id;
}
void GeoDataObject::setId( const QString& value )
{
d->m_id = value;
}
QString GeoDataObject::targetId() const
{
return d->m_targetId;
}
void GeoDataObject::setTargetId( const QString& value )
{
d->m_targetId = value;
}
QString GeoDataObject::resolvePath( const QString &relativePath ) const
{
QUrl const url( relativePath );
QFileInfo const fileInfo( url.path() );
if ( url.isRelative() && fileInfo.isRelative() ) {
GeoDataDocument const * document = dynamic_cast<GeoDataDocument const*>( this );
if ( document ) {
QString const baseUri = document->baseUri();
QFileInfo const documentRoot = baseUri.isEmpty() ? document->fileName() : baseUri;
QFileInfo const absoluteImage(documentRoot.absolutePath() + QLatin1Char('/') + url.path());
return absoluteImage.absoluteFilePath();
} else if ( d->m_parent ) {
return d->m_parent->resolvePath( relativePath );
}
}
return relativePath;
}
void GeoDataObject::pack( QDataStream& stream ) const
{
stream << d->m_id;
stream << d->m_targetId;
}
void GeoDataObject::unpack( QDataStream& stream )
{
stream >> d->m_id;
stream >> d->m_targetId;
}
bool GeoDataObject::equals(const GeoDataObject &other) const
{
return d->m_id == other.d->m_id && d->m_targetId == other.d->m_targetId;
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataPlacemark.cpp b/src/lib/marble/geodata/data/GeoDataPlacemark.cpp
index db64651fb..b0bb95162 100644
--- a/src/lib/marble/geodata/data/GeoDataPlacemark.cpp
+++ b/src/lib/marble/geodata/data/GeoDataPlacemark.cpp
@@ -1,851 +1,851 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2004-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
//
// Own
#include "GeoDataPlacemark.h"
// Private
#include "GeoDataPlacemark_p.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataData.h"
#include "osm/OsmPlacemarkData.h"
// Qt
#include <QDataStream>
#include "MarbleDebug.h"
#include "GeoDataTrack.h"
#include "GeoDataModel.h"
#include <QString>
#include <QXmlStreamWriter>
namespace Marble
{
const OsmPlacemarkData GeoDataPlacemarkPrivate::s_nullOsmPlacemarkData = OsmPlacemarkData();
const GeoDataPlacemarkExtendedData GeoDataPlacemarkPrivate::s_nullPlacemarkExtendedData = GeoDataPlacemarkExtendedData();
GeoDataPlacemark::GeoDataPlacemark()
: GeoDataFeature( new GeoDataPlacemarkPrivate )
{
Q_D(GeoDataPlacemark);
d->m_geometry->setParent(this);
}
GeoDataPlacemark::GeoDataPlacemark( const GeoDataPlacemark& other )
: GeoDataFeature(other, new GeoDataPlacemarkPrivate(*other.d_func()))
{
Q_D(GeoDataPlacemark);
if (d->m_geometry) {
d->m_geometry->setParent(this);
}
}
GeoDataPlacemark::GeoDataPlacemark( const QString& name )
: GeoDataFeature( new GeoDataPlacemarkPrivate )
{
Q_D(GeoDataPlacemark);
d->m_name = name;
d->m_geometry->setParent(this);
}
GeoDataPlacemark::~GeoDataPlacemark()
{
// nothing to do
}
GeoDataPlacemark &GeoDataPlacemark::operator=( const GeoDataPlacemark &other )
{
if (this != &other) {
Q_D(GeoDataPlacemark);
*d = *other.d_func();
if (d->m_geometry) {
d->m_geometry->setParent(this);
}
}
return *this;
}
bool GeoDataPlacemark::operator==( const GeoDataPlacemark& other ) const
{
Q_D(const GeoDataPlacemark);
const GeoDataPlacemarkPrivate* const other_d = other.d_func();
if (!equals(other) ||
d->m_population != other_d->m_population) {
return false;
}
if ((d->m_placemarkExtendedData && !other_d->m_placemarkExtendedData) &&
(*d->m_placemarkExtendedData != GeoDataPlacemarkExtendedData())) {
return false;
}
if ((!d->m_placemarkExtendedData && other_d->m_placemarkExtendedData) &&
(GeoDataPlacemarkExtendedData() != *other_d->m_placemarkExtendedData)) {
return false;
}
if (d->m_placemarkExtendedData && other_d->m_placemarkExtendedData &&
!(*d->m_placemarkExtendedData == *other_d->m_placemarkExtendedData)) {
return false;
}
if (!d->m_geometry && !other_d->m_geometry) {
return true;
}
if ((!d->m_geometry && other_d->m_geometry) ||
(d->m_geometry && !other_d->m_geometry)) {
return false;
}
if (*d->m_geometry != *other_d->m_geometry) {
return false;
}
return true;
}
bool GeoDataPlacemark::operator!=( const GeoDataPlacemark& other ) const
{
return !this->operator==( other );
}
const char* GeoDataPlacemark::nodeType() const
{
return GeoDataTypes::GeoDataPlacemarkType;
}
GeoDataFeature * GeoDataPlacemark::clone() const
{
return new GeoDataPlacemark(*this);
}
GeoDataPlacemark::GeoDataVisualCategory GeoDataPlacemark::visualCategory() const
{
Q_D(const GeoDataPlacemark);
return d->m_visualCategory;
}
void GeoDataPlacemark::setVisualCategory(GeoDataPlacemark::GeoDataVisualCategory index)
{
Q_D(GeoDataPlacemark);
d->m_visualCategory = index;
}
GeoDataGeometry* GeoDataPlacemark::geometry()
{
Q_D(GeoDataPlacemark);
return d->m_geometry;
}
const GeoDataGeometry* GeoDataPlacemark::geometry() const
{
Q_D(const GeoDataPlacemark);
return d->m_geometry;
}
const OsmPlacemarkData& GeoDataPlacemark::osmData() const
{
Q_D(const GeoDataPlacemark);
return d->osmPlacemarkData();
}
void GeoDataPlacemark::setOsmData( const OsmPlacemarkData &osmData )
{
Q_D(GeoDataPlacemark);
d->osmPlacemarkData() = osmData;
}
OsmPlacemarkData& GeoDataPlacemark::osmData()
{
Q_D(GeoDataPlacemark);
return d->osmPlacemarkData();
}
bool GeoDataPlacemark::hasOsmData() const
{
Q_D(const GeoDataPlacemark);
return d->m_osmPlacemarkData != nullptr;
}
void GeoDataPlacemark::clearOsmData()
{
Q_D(GeoDataPlacemark);
delete d->m_osmPlacemarkData;
d->m_osmPlacemarkData = nullptr;
}
const GeoDataLookAt *GeoDataPlacemark::lookAt() const
{
return dynamic_cast<const GeoDataLookAt*>( abstractView() );
}
GeoDataLookAt *GeoDataPlacemark::lookAt()
{
return dynamic_cast<GeoDataLookAt*>( abstractView() );
}
bool GeoDataPlacemark::placemarkLayoutOrderCompare(const GeoDataPlacemark *left, const GeoDataPlacemark *right)
{
const GeoDataPlacemarkPrivate * const left_d = left->d_func();
const GeoDataPlacemarkPrivate * const right_d = right->d_func();
if (left_d->m_zoomLevel != right_d->m_zoomLevel) {
return (left_d->m_zoomLevel < right_d->m_zoomLevel); // lower zoom level comes first
}
if (left_d->m_popularity != right_d->m_popularity) {
return (left_d->m_popularity > right_d->m_popularity); // higher popularity comes first
}
return left < right; // lower pointer value comes first
}
GeoDataCoordinates GeoDataPlacemark::coordinate( const QDateTime &dateTime, bool *iconAtCoordinates ) const
{
Q_D(const GeoDataPlacemark);
bool hasIcon = false;
GeoDataCoordinates coord;
if (d->m_geometry) {
// Beware: comparison between pointers, not strings.
if (geodata_cast<GeoDataPoint>(d->m_geometry)
|| geodata_cast<GeoDataPolygon>(d->m_geometry)
|| geodata_cast<GeoDataLinearRing>(d->m_geometry)) {
hasIcon = true;
coord = d->m_geometry->latLonAltBox().center();
} else if (const auto multiGeometry = geodata_cast<GeoDataMultiGeometry>(d->m_geometry)) {
QVector<GeoDataGeometry*>::ConstIterator it = multiGeometry->constBegin();
QVector<GeoDataGeometry*>::ConstIterator end = multiGeometry->constEnd();
for ( ; it != end; ++it ) {
if (geodata_cast<GeoDataPoint>(*it)
|| geodata_cast<GeoDataPolygon>(*it)
|| geodata_cast<GeoDataLinearRing>(*it)) {
hasIcon = true;
break;
}
}
coord = d->m_geometry->latLonAltBox().center();
} else if (const auto track = geodata_cast<GeoDataTrack>(d->m_geometry)) {
hasIcon = track->size() != 0 && track->firstWhen() <= dateTime;
coord = track->coordinatesAt( dateTime );
} else if (const auto lineString = geodata_cast<GeoDataLineString>(d->m_geometry)) {
auto const size = lineString->size();
if (size == 0) {
return GeoDataCoordinates();
} else if (size < 3) {
// Approximate center if there are just two coordinates
return lineString->latLonAltBox().center();
} else {
return lineString->at(size / 2);
}
} else {
coord = d->m_geometry->latLonAltBox().center();
}
}
- if ( iconAtCoordinates != 0 ) {
+ if ( iconAtCoordinates != nullptr ) {
*iconAtCoordinates = hasIcon;
}
return coord;
}
void GeoDataPlacemark::coordinate( qreal& lon, qreal& lat, qreal& alt ) const
{
coordinate().geoCoordinates( lon, lat, alt );
}
void GeoDataPlacemark::setCoordinate( qreal lon, qreal lat, qreal alt, GeoDataPoint::Unit _unit)
{
setGeometry( new GeoDataPoint(lon, lat, alt, _unit ) );
}
void GeoDataPlacemark::setCoordinate( const GeoDataCoordinates &point )
{
setGeometry ( new GeoDataPoint( point ) );
}
void GeoDataPlacemark::setGeometry( GeoDataGeometry *entry )
{
Q_D(GeoDataPlacemark);
delete d->m_geometry;
d->m_geometry = entry;
d->m_geometry->setParent(this);
}
QString GeoDataPlacemark::displayName() const
{
if (hasOsmData()) {
OsmPlacemarkData const &data = osmData();
QStringList const uiLanguages = QLocale::system().uiLanguages();
for (const QString &uiLanguage: uiLanguages) {
for (auto tagIter = data.tagsBegin(), end = data.tagsEnd(); tagIter != end; ++tagIter) {
if (tagIter.key().startsWith(QLatin1String("name:"))) {
QStringRef const tagLanguage = tagIter.key().midRef(5);
if (tagLanguage == uiLanguage) {
return tagIter.value();
}
}
}
}
}
return name();
}
QString GeoDataPlacemark::categoryName() const
{
Q_D(const GeoDataPlacemark);
switch (d->m_visualCategory) {
case Valley: return GeoDataPlacemarkPrivate::tr("Valley");
case OtherTerrain: return GeoDataPlacemarkPrivate::tr("Terrain");
case Crater: return GeoDataPlacemarkPrivate::tr("Crater");
case Mare: return GeoDataPlacemarkPrivate::tr("Sea");
case MannedLandingSite: return GeoDataPlacemarkPrivate::tr("Manned Landing Site");
case RoboticRover: return GeoDataPlacemarkPrivate::tr("Robotic Rover");
case UnmannedSoftLandingSite: return GeoDataPlacemarkPrivate::tr("Unmanned Soft Landing Site");
case UnmannedHardLandingSite: return GeoDataPlacemarkPrivate::tr("Unmanned Hard Landing Site");
case Mons: return GeoDataPlacemarkPrivate::tr("Mountain");
case SmallCity: return GeoDataPlacemarkPrivate::tr("City");
case SmallCountyCapital: return GeoDataPlacemarkPrivate::tr("County Capital");
case SmallStateCapital: return GeoDataPlacemarkPrivate::tr("State Capital");
case SmallNationCapital: return GeoDataPlacemarkPrivate::tr("Nation Capital");
case MediumCity: return GeoDataPlacemarkPrivate::tr("City");
case MediumCountyCapital: return GeoDataPlacemarkPrivate::tr("County Capital");
case MediumStateCapital: return GeoDataPlacemarkPrivate::tr("State Capital");
case MediumNationCapital: return GeoDataPlacemarkPrivate::tr("Nation Capital");
case BigCity: return GeoDataPlacemarkPrivate::tr("City");
case BigCountyCapital: return GeoDataPlacemarkPrivate::tr("County Capital");
case BigStateCapital: return GeoDataPlacemarkPrivate::tr("State Capital");
case BigNationCapital: return GeoDataPlacemarkPrivate::tr("Nation Capital");
case LargeCity: return GeoDataPlacemarkPrivate::tr("City");
case LargeCountyCapital: return GeoDataPlacemarkPrivate::tr("County Capital");
case LargeStateCapital: return GeoDataPlacemarkPrivate::tr("State Capital");
case LargeNationCapital: return GeoDataPlacemarkPrivate::tr("Nation Capital");
case Nation: return GeoDataPlacemarkPrivate::tr("Nation");
case Mountain: return GeoDataPlacemarkPrivate::tr("Mountain");
case Volcano: return GeoDataPlacemarkPrivate::tr("Volcano");
case Continent: return GeoDataPlacemarkPrivate::tr("Continent");
case Ocean: return GeoDataPlacemarkPrivate::tr("Ocean");
case GeographicPole: return GeoDataPlacemarkPrivate::tr("Geographic Pole");
case MagneticPole: return GeoDataPlacemarkPrivate::tr("Magnetic Pole");
case ShipWreck: return GeoDataPlacemarkPrivate::tr("Ship Wreck");
case AirPort: return GeoDataPlacemarkPrivate::tr("Air Port");
case Observatory: return GeoDataPlacemarkPrivate::tr("Observatory");
case MilitaryDangerArea: return GeoDataPlacemarkPrivate::tr("Military Danger Area");
case OsmSite: return GeoDataPlacemarkPrivate::tr("OSM Site");
case Coordinate: return GeoDataPlacemarkPrivate::tr("Coordinate");
case Bookmark: return GeoDataPlacemarkPrivate::tr("Bookmark");
case Satellite: return GeoDataPlacemarkPrivate::tr("Satellite");
// OpenStreetMap categories
case PlaceCity: return GeoDataPlacemarkPrivate::tr("City");
case PlaceCityCapital: return GeoDataPlacemarkPrivate::tr("City Capital");
case PlaceCityNationalCapital: return GeoDataPlacemarkPrivate::tr("National Capital");
case PlaceSuburb: return GeoDataPlacemarkPrivate::tr("Suburb");
case PlaceHamlet: return GeoDataPlacemarkPrivate::tr("Hamlet");
case PlaceLocality: return GeoDataPlacemarkPrivate::tr("Locality");
case PlaceTown: return GeoDataPlacemarkPrivate::tr("Town");
case PlaceTownCapital: return GeoDataPlacemarkPrivate::tr("Town Capital");
case PlaceTownNationalCapital: return GeoDataPlacemarkPrivate::tr("National Capital");
case PlaceVillage: return GeoDataPlacemarkPrivate::tr("Village");
case PlaceVillageCapital: return GeoDataPlacemarkPrivate::tr("Village Capital");
case PlaceVillageNationalCapital: return GeoDataPlacemarkPrivate::tr("National Capital");
case NaturalWater: return GeoDataPlacemarkPrivate::tr("Water");
case NaturalReef: return GeoDataPlacemarkPrivate::tr("Reef");
case NaturalWood: return GeoDataPlacemarkPrivate::tr("Wood");
case NaturalBeach: return GeoDataPlacemarkPrivate::tr("Beach");
case NaturalWetland: return GeoDataPlacemarkPrivate::tr("Wetland");
case NaturalGlacier: return GeoDataPlacemarkPrivate::tr("Glacier");
case NaturalIceShelf: return GeoDataPlacemarkPrivate::tr("Ice Shelf");
case NaturalScrub: return GeoDataPlacemarkPrivate::tr("Scrub");
case NaturalCliff: return GeoDataPlacemarkPrivate::tr("Cliff");
case NaturalHeath: return GeoDataPlacemarkPrivate::tr("Heath");
case HighwayTrafficSignals: return GeoDataPlacemarkPrivate::tr("Traffic Signals");
case HighwayElevator: return GeoDataPlacemarkPrivate::tr("Elevator");
case HighwaySteps: return GeoDataPlacemarkPrivate::tr("Steps");
case HighwayUnknown: return GeoDataPlacemarkPrivate::tr("Unknown Road");
case HighwayPath: return GeoDataPlacemarkPrivate::tr("Path");
case HighwayFootway: return GeoDataPlacemarkPrivate::tr("Footway");
case HighwayTrack: return GeoDataPlacemarkPrivate::tr("Track");
case HighwayPedestrian: return GeoDataPlacemarkPrivate::tr("Footway");
case HighwayCycleway: return GeoDataPlacemarkPrivate::tr("Cycleway");
case HighwayService: return GeoDataPlacemarkPrivate::tr("Service Road");
case HighwayRoad: return GeoDataPlacemarkPrivate::tr("Road");
case HighwayResidential: return GeoDataPlacemarkPrivate::tr("Residential Road");
case HighwayLivingStreet: return GeoDataPlacemarkPrivate::tr("Living Street");
case HighwayUnclassified: return GeoDataPlacemarkPrivate::tr("Unclassified Road");
case HighwayTertiaryLink: return GeoDataPlacemarkPrivate::tr("Tertiary Link Road");
case HighwayTertiary: return GeoDataPlacemarkPrivate::tr("Tertiary Road");
case HighwaySecondaryLink: return GeoDataPlacemarkPrivate::tr("Secondary Link Road");
case HighwaySecondary: return GeoDataPlacemarkPrivate::tr("Secondary Road");
case HighwayPrimaryLink: return GeoDataPlacemarkPrivate::tr("Primary Link Road");
case HighwayPrimary: return GeoDataPlacemarkPrivate::tr("Primary Road");
case HighwayRaceway: return GeoDataPlacemarkPrivate::tr("Raceway");
case HighwayTrunkLink: return GeoDataPlacemarkPrivate::tr("Trunk Link Road");
case HighwayTrunk: return GeoDataPlacemarkPrivate::tr("Trunk Road");
case HighwayMotorwayLink: return GeoDataPlacemarkPrivate::tr("Motorway Link Road");
case HighwayMotorway: return GeoDataPlacemarkPrivate::tr("Motorway");
case HighwayCorridor: return GeoDataPlacemarkPrivate::tr("Corridor");
case Building: return GeoDataPlacemarkPrivate::tr("Building");
case AccomodationCamping: return GeoDataPlacemarkPrivate::tr("Camping");
case AccomodationHostel: return GeoDataPlacemarkPrivate::tr("Hostel");
case AccomodationHotel: return GeoDataPlacemarkPrivate::tr("Hotel");
case AccomodationMotel: return GeoDataPlacemarkPrivate::tr("Motel");
case AccomodationYouthHostel: return GeoDataPlacemarkPrivate::tr("Youth Hostel");
case AccomodationGuestHouse: return GeoDataPlacemarkPrivate::tr("Guest House");
case AmenityLibrary: return GeoDataPlacemarkPrivate::tr("Library");
case AmenityKindergarten: return GeoDataPlacemarkPrivate::tr("Kindergarten");
case EducationCollege: return GeoDataPlacemarkPrivate::tr("College");
case EducationSchool: return GeoDataPlacemarkPrivate::tr("School");
case EducationUniversity: return GeoDataPlacemarkPrivate::tr("University");
case FoodBar: return GeoDataPlacemarkPrivate::tr("Bar");
case FoodBiergarten: return GeoDataPlacemarkPrivate::tr("Biergarten");
case FoodCafe: return GeoDataPlacemarkPrivate::tr("Cafe");
case FoodFastFood: return GeoDataPlacemarkPrivate::tr("Fast Food");
case FoodPub: return GeoDataPlacemarkPrivate::tr("Pub");
case FoodRestaurant: return GeoDataPlacemarkPrivate::tr("Restaurant");
case HealthDentist: return GeoDataPlacemarkPrivate::tr("Dentist");
case HealthDoctors: return GeoDataPlacemarkPrivate::tr("Doctors");
case HealthHospital: return GeoDataPlacemarkPrivate::tr("Hospital");
case HealthPharmacy: return GeoDataPlacemarkPrivate::tr("Pharmacy");
case HealthVeterinary: return GeoDataPlacemarkPrivate::tr("Veterinary");
case MoneyAtm: return GeoDataPlacemarkPrivate::tr("ATM");
case MoneyBank: return GeoDataPlacemarkPrivate::tr("Bank");
case HistoricArchaeologicalSite: return GeoDataPlacemarkPrivate::tr("Archaeological Site");
case AmenityEmbassy: return GeoDataPlacemarkPrivate::tr("Embassy");
case AmenityEmergencyPhone: return GeoDataPlacemarkPrivate::tr("Emergency Phone");
case AmenityMountainRescue: return GeoDataPlacemarkPrivate::tr("Mountain Rescue");
case LeisureWaterPark: return GeoDataPlacemarkPrivate::tr("Water Park");
case AmenityCommunityCentre: return GeoDataPlacemarkPrivate::tr("Community Centre");
case AmenityFountain: return GeoDataPlacemarkPrivate::tr("Fountain");
case AmenityNightClub: return GeoDataPlacemarkPrivate::tr("Night Club");
case AmenityBench: return GeoDataPlacemarkPrivate::tr("Bench");
case AmenityCourtHouse: return GeoDataPlacemarkPrivate::tr("Court House");
case AmenityFireStation: return GeoDataPlacemarkPrivate::tr("Fire Station");
case AmenityHuntingStand: return GeoDataPlacemarkPrivate::tr("Hunting Stand");
case AmenityPolice: return GeoDataPlacemarkPrivate::tr("Police");
case AmenityPostBox: return GeoDataPlacemarkPrivate::tr("Post Box");
case AmenityPostOffice: return GeoDataPlacemarkPrivate::tr("Post Office");
case AmenityPrison: return GeoDataPlacemarkPrivate::tr("Prison");
case AmenityRecycling: return GeoDataPlacemarkPrivate::tr("Recycling");
case AmenityShelter: return GeoDataPlacemarkPrivate::tr("Shelter");
case AmenityTelephone: return GeoDataPlacemarkPrivate::tr("Telephone");
case AmenityToilets: return GeoDataPlacemarkPrivate::tr("Toilets");
case AmenityTownHall: return GeoDataPlacemarkPrivate::tr("Town Hall");
case AmenityWasteBasket: return GeoDataPlacemarkPrivate::tr("Waste Basket");
case AmenityDrinkingWater: return GeoDataPlacemarkPrivate::tr("Drinking Water");
case AmenityGraveyard: return GeoDataPlacemarkPrivate::tr("Graveyard");
case AmenityChargingStation: return GeoDataPlacemarkPrivate::tr("Charging Station");
case AmenityCarWash: return GeoDataPlacemarkPrivate::tr("Car Wash");
case AmenitySocialFacility: return GeoDataPlacemarkPrivate::tr("Social Facility");
case BarrierCityWall: return GeoDataPlacemarkPrivate::tr("City Wall");
case BarrierGate: return GeoDataPlacemarkPrivate::tr("Gate");
case BarrierLiftGate: return GeoDataPlacemarkPrivate::tr("Lift Gate");
case BarrierWall: return GeoDataPlacemarkPrivate::tr("Wall");
case NaturalVolcano: return GeoDataPlacemarkPrivate::tr("Volcano");
case NaturalPeak: return GeoDataPlacemarkPrivate::tr("Peak");
case NaturalTree: return GeoDataPlacemarkPrivate::tr("Tree");
case NaturalCave: return GeoDataPlacemarkPrivate::tr("Cave Entrance");
case ShopBeverages: return GeoDataPlacemarkPrivate::tr("Beverages");
case ShopHifi: return GeoDataPlacemarkPrivate::tr("Hifi");
case ShopSupermarket: return GeoDataPlacemarkPrivate::tr("Supermarket");
case ShopAlcohol: return GeoDataPlacemarkPrivate::tr("Liquor Store");
case ShopBakery: return GeoDataPlacemarkPrivate::tr("Bakery");
case ShopButcher: return GeoDataPlacemarkPrivate::tr("Butcher");
case ShopConfectionery: return GeoDataPlacemarkPrivate::tr("Confectionery");
case ShopConvenience: return GeoDataPlacemarkPrivate::tr("Convenience Shop");
case ShopGreengrocer: return GeoDataPlacemarkPrivate::tr("Greengrocer");
case ShopSeafood: return GeoDataPlacemarkPrivate::tr("Seafood Shop");
case ShopDepartmentStore: return GeoDataPlacemarkPrivate::tr("Department Store");
case ShopKiosk: return GeoDataPlacemarkPrivate::tr("Kiosk");
case ShopBag: return GeoDataPlacemarkPrivate::tr("Bag Shop");
case ShopClothes: return GeoDataPlacemarkPrivate::tr("Clothes Shop");
case ShopFashion: return GeoDataPlacemarkPrivate::tr("Fashion Shop");
case ShopJewelry: return GeoDataPlacemarkPrivate::tr("Jewelry Shop");
case ShopShoes: return GeoDataPlacemarkPrivate::tr("Shoe Shop");
case ShopVarietyStore: return GeoDataPlacemarkPrivate::tr("Variety Store");
case ShopBeauty: return GeoDataPlacemarkPrivate::tr("Beauty Services");
case ShopChemist: return GeoDataPlacemarkPrivate::tr("Chemist");
case ShopCosmetics: return GeoDataPlacemarkPrivate::tr("Cosmetics");
case ShopHairdresser: return GeoDataPlacemarkPrivate::tr("Hairdresser");
case ShopOptician: return GeoDataPlacemarkPrivate::tr("Optician");
case ShopPerfumery: return GeoDataPlacemarkPrivate::tr("Perfumery");
case ShopDoitYourself: return GeoDataPlacemarkPrivate::tr("Hardware Store");
case ShopFlorist: return GeoDataPlacemarkPrivate::tr("Florist");
case ShopHardware: return GeoDataPlacemarkPrivate::tr("Hardware Store");
case ShopFurniture: return GeoDataPlacemarkPrivate::tr("Furniture Store");
case ShopElectronics: return GeoDataPlacemarkPrivate::tr("Electronics Shop");
case ShopMobilePhone: return GeoDataPlacemarkPrivate::tr("Mobile Phone Shop");
case ShopBicycle: return GeoDataPlacemarkPrivate::tr("Bicycle Shop");
case ShopCar: return GeoDataPlacemarkPrivate::tr("Car Dealer");
case ShopCarRepair: return GeoDataPlacemarkPrivate::tr("Car Repair Shop");
case ShopCarParts: return GeoDataPlacemarkPrivate::tr("Car Parts");
case ShopMotorcycle: return GeoDataPlacemarkPrivate::tr("Motorcycle Shop");
case ShopOutdoor: return GeoDataPlacemarkPrivate::tr("Outdoor Shop");
case ShopSports: return GeoDataPlacemarkPrivate::tr("Sports Shop");
case ShopCopy: return GeoDataPlacemarkPrivate::tr("Printing Services");
case ShopArt: return GeoDataPlacemarkPrivate::tr("Art Shop");
case ShopMusicalInstrument: return GeoDataPlacemarkPrivate::tr("Musical Instrument Shop");
case ShopPhoto: return GeoDataPlacemarkPrivate::tr("Photo Shop");
case ShopBook: return GeoDataPlacemarkPrivate::tr("Bookshop");
case ShopGift: return GeoDataPlacemarkPrivate::tr("Gift Shop");
case ShopStationery: return GeoDataPlacemarkPrivate::tr("Stationery");
case ShopLaundry: return GeoDataPlacemarkPrivate::tr("Laundry");
case ShopPet: return GeoDataPlacemarkPrivate::tr("Pet Shop");
case ShopToys: return GeoDataPlacemarkPrivate::tr("Toy Store");
case ShopTravelAgency: return GeoDataPlacemarkPrivate::tr("Travel Agency");
case ShopDeli: return GeoDataPlacemarkPrivate::tr("Deli");
case ShopTobacco: return GeoDataPlacemarkPrivate::tr("Tobacco Shop");
case ShopTea: return GeoDataPlacemarkPrivate::tr("Tea Shop");
case ShopComputer: return GeoDataPlacemarkPrivate::tr("Computer Shop");
case ShopGardenCentre: return GeoDataPlacemarkPrivate::tr("Garden Centre");
case Shop: return GeoDataPlacemarkPrivate::tr("Shop");
case ManmadeBridge: return GeoDataPlacemarkPrivate::tr("Bridge");
case ManmadeLighthouse: return GeoDataPlacemarkPrivate::tr("Lighthouse");
case ManmadePier: return GeoDataPlacemarkPrivate::tr("Pier");
case ManmadeWaterTower: return GeoDataPlacemarkPrivate::tr("Water Tower");
case ManmadeWindMill: return GeoDataPlacemarkPrivate::tr("Wind Mill");
case ManmadeCommunicationsTower: return GeoDataPlacemarkPrivate::tr("Communications Tower");
case TourismAttraction: return GeoDataPlacemarkPrivate::tr("Tourist Attraction");
case TourismArtwork: return GeoDataPlacemarkPrivate::tr("Artwork");
case HistoricCastle: return GeoDataPlacemarkPrivate::tr("Castle");
case AmenityCinema: return GeoDataPlacemarkPrivate::tr("Cinema");
case TourismInformation: return GeoDataPlacemarkPrivate::tr("Information");
case HistoricMonument: return GeoDataPlacemarkPrivate::tr("Monument");
case TourismMuseum: return GeoDataPlacemarkPrivate::tr("Museum");
case HistoricRuins: return GeoDataPlacemarkPrivate::tr("Ruin");
case AmenityTheatre: return GeoDataPlacemarkPrivate::tr("Theatre");
case TourismThemePark: return GeoDataPlacemarkPrivate::tr("Theme Park");
case TourismViewPoint: return GeoDataPlacemarkPrivate::tr("View Point");
case TourismZoo: return GeoDataPlacemarkPrivate::tr("Zoo");
case TourismAlpineHut: return GeoDataPlacemarkPrivate::tr("Alpine Hut");
case TourismWildernessHut: return GeoDataPlacemarkPrivate::tr("Wilderness Hut");
case HistoricMemorial: return GeoDataPlacemarkPrivate::tr("Memorial");
case TransportAerodrome: return GeoDataPlacemarkPrivate::tr("Aerodrome");
case TransportHelipad: return GeoDataPlacemarkPrivate::tr("Helipad");
case TransportAirportGate: return GeoDataPlacemarkPrivate::tr("Airport Gate");
case TransportAirportRunway: return GeoDataPlacemarkPrivate::tr("Airport Runway");
case TransportAirportApron: return GeoDataPlacemarkPrivate::tr("Airport Apron");
case TransportAirportTaxiway: return GeoDataPlacemarkPrivate::tr("Airport Taxiway");
case TransportAirportTerminal: return GeoDataPlacemarkPrivate::tr("Airport Terminal");
case TransportBusStation: return GeoDataPlacemarkPrivate::tr("Bus Station");
case TransportBusStop: return GeoDataPlacemarkPrivate::tr("Bus Stop");
case TransportCarShare: return GeoDataPlacemarkPrivate::tr("Car Sharing");
case TransportFuel: return GeoDataPlacemarkPrivate::tr("Gas Station");
case TransportParking: return GeoDataPlacemarkPrivate::tr("Parking");
case TransportParkingSpace: return GeoDataPlacemarkPrivate::tr("Parking Space");
case TransportPlatform: return GeoDataPlacemarkPrivate::tr("Platform");
case TransportRentalBicycle: return GeoDataPlacemarkPrivate::tr("Bicycle Rental");
case TransportRentalCar: return GeoDataPlacemarkPrivate::tr("Car Rental");
case TransportRentalSki: return GeoDataPlacemarkPrivate::tr("Ski Rental");
case TransportTaxiRank: return GeoDataPlacemarkPrivate::tr("Taxi Rank");
case TransportTrainStation: return GeoDataPlacemarkPrivate::tr("Train Station");
case TransportTramStop: return GeoDataPlacemarkPrivate::tr("Tram Stop");
case TransportBicycleParking: return GeoDataPlacemarkPrivate::tr("Bicycle Parking");
case TransportMotorcycleParking: return GeoDataPlacemarkPrivate::tr("Motorcycle Parking");
case TransportSubwayEntrance: return GeoDataPlacemarkPrivate::tr("Subway Entrance");
case TransportSpeedCamera: return GeoDataPlacemarkPrivate::tr("Speed Camera");
case ReligionPlaceOfWorship: return GeoDataPlacemarkPrivate::tr("Place Of Worship");
case ReligionBahai: return GeoDataPlacemarkPrivate::tr("Bahai");
case ReligionBuddhist: return GeoDataPlacemarkPrivate::tr("Buddhist");
case ReligionChristian: return GeoDataPlacemarkPrivate::tr("Christian");
case ReligionMuslim: return GeoDataPlacemarkPrivate::tr("Muslim");
case ReligionHindu: return GeoDataPlacemarkPrivate::tr("Hindu");
case ReligionJain: return GeoDataPlacemarkPrivate::tr("Jain");
case ReligionJewish: return GeoDataPlacemarkPrivate::tr("Jewish");
case ReligionShinto: return GeoDataPlacemarkPrivate::tr("Shinto");
case ReligionSikh: return GeoDataPlacemarkPrivate::tr("Sikh");
case ReligionTaoist: return GeoDataPlacemarkPrivate::tr("Taoist");
case LeisureGolfCourse: return GeoDataPlacemarkPrivate::tr("Golf Course");
case LeisureMarina: return GeoDataPlacemarkPrivate::tr("Marina");
case LeisurePark: return GeoDataPlacemarkPrivate::tr("Park");
case LeisurePlayground: return GeoDataPlacemarkPrivate::tr("Playground");
case LeisurePitch: return GeoDataPlacemarkPrivate::tr("Pitch");
case LeisureSportsCentre: return GeoDataPlacemarkPrivate::tr("Sports Centre");
case LeisureStadium: return GeoDataPlacemarkPrivate::tr("Stadium");
case LeisureTrack: return GeoDataPlacemarkPrivate::tr("Track");
case LeisureSwimmingPool: return GeoDataPlacemarkPrivate::tr("Swimming Pool");
case LeisureMinigolfCourse: return GeoDataPlacemarkPrivate::tr("Miniature Golf Course");
case LanduseAllotments: return GeoDataPlacemarkPrivate::tr("Allotments");
case LanduseBasin: return GeoDataPlacemarkPrivate::tr("Basin");
case LanduseCemetery: return GeoDataPlacemarkPrivate::tr("Cemetery");
case LanduseCommercial: return GeoDataPlacemarkPrivate::tr("Commercial");
case LanduseConstruction: return GeoDataPlacemarkPrivate::tr("Construction");
case LanduseFarmland: return GeoDataPlacemarkPrivate::tr("Farmland");
case LanduseFarmyard: return GeoDataPlacemarkPrivate::tr("Farmyard");
case LanduseGarages: return GeoDataPlacemarkPrivate::tr("Garages");
case LanduseGrass: return GeoDataPlacemarkPrivate::tr("Grass");
case LanduseIndustrial: return GeoDataPlacemarkPrivate::tr("Industrial");
case LanduseLandfill: return GeoDataPlacemarkPrivate::tr("Landfill");
case LanduseMeadow: return GeoDataPlacemarkPrivate::tr("Meadow");
case LanduseMilitary: return GeoDataPlacemarkPrivate::tr("Military");
case LanduseQuarry: return GeoDataPlacemarkPrivate::tr("Quarry");
case LanduseRailway: return GeoDataPlacemarkPrivate::tr("Railway");
case LanduseReservoir: return GeoDataPlacemarkPrivate::tr("Reservoir");
case LanduseResidential: return GeoDataPlacemarkPrivate::tr("Residential");
case LanduseRetail: return GeoDataPlacemarkPrivate::tr("Retail");
case LanduseOrchard: return GeoDataPlacemarkPrivate::tr("Orchard");
case LanduseVineyard: return GeoDataPlacemarkPrivate::tr("Vineyard");
case RailwayRail: return GeoDataPlacemarkPrivate::tr("Rail");
case RailwayNarrowGauge: return GeoDataPlacemarkPrivate::tr("Narrow Gauge");
case RailwayTram: return GeoDataPlacemarkPrivate::tr("Tram");
case RailwayLightRail: return GeoDataPlacemarkPrivate::tr("Light Rail");
case RailwayAbandoned: return GeoDataPlacemarkPrivate::tr("Abandoned Railway");
case RailwaySubway: return GeoDataPlacemarkPrivate::tr("Subway");
case RailwayPreserved: return GeoDataPlacemarkPrivate::tr("Preserved Railway");
case RailwayMiniature: return GeoDataPlacemarkPrivate::tr("Miniature Railway");
case RailwayConstruction: return GeoDataPlacemarkPrivate::tr("Railway Construction");
case RailwayMonorail: return GeoDataPlacemarkPrivate::tr("Monorail");
case RailwayFunicular: return GeoDataPlacemarkPrivate::tr("Funicular Railway");
case PowerTower: return GeoDataPlacemarkPrivate::tr("Power Tower");
case AerialwayStation: return GeoDataPlacemarkPrivate::tr("Aerialway Station");
case AerialwayPylon: return GeoDataPlacemarkPrivate::tr("Pylon", "A pylon supporting the aerialway cable e.g. on a ski lift");
case AerialwayCableCar: return GeoDataPlacemarkPrivate::tr("Cable Car");
case AerialwayGondola: return GeoDataPlacemarkPrivate::tr("Gondola");
case AerialwayChairLift: return GeoDataPlacemarkPrivate::tr("Chair Lift");
case AerialwayMixedLift: return GeoDataPlacemarkPrivate::tr("Mixed Lift");
case AerialwayDragLift: return GeoDataPlacemarkPrivate::tr("Drag Lift");
case AerialwayTBar: return GeoDataPlacemarkPrivate::tr("T-Bar");
case AerialwayJBar: return GeoDataPlacemarkPrivate::tr("J-Bar");
case AerialwayPlatter: return GeoDataPlacemarkPrivate::tr("Platter");
case AerialwayRopeTow: return GeoDataPlacemarkPrivate::tr("Rope Tow");
case AerialwayMagicCarpet: return GeoDataPlacemarkPrivate::tr("Magic Carpet");
case AerialwayZipLine: return GeoDataPlacemarkPrivate::tr("Zip Line");
case AerialwayGoods: return GeoDataPlacemarkPrivate::tr("Goods");
case PisteDownhill: return GeoDataPlacemarkPrivate::tr("Downhill Piste");
case PisteNordic: return GeoDataPlacemarkPrivate::tr("Nordic Piste");
case PisteSkitour: return GeoDataPlacemarkPrivate::tr("Skitour");
case PisteSled: return GeoDataPlacemarkPrivate::tr("Sled Piste");
case PisteHike: return GeoDataPlacemarkPrivate::tr("Winter Hike");
case PisteSleigh: return GeoDataPlacemarkPrivate::tr("Sleigh Piste");
case PisteIceSkate: return GeoDataPlacemarkPrivate::tr("Ice Skate");
case PisteSnowPark: return GeoDataPlacemarkPrivate::tr("Snow Park");
case PistePlayground: return GeoDataPlacemarkPrivate::tr("Ski Playground");
case PisteSkiJump: return GeoDataPlacemarkPrivate::tr("Ski Jump");
case AdminLevel1: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 1)");
case AdminLevel2: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 2)");
case AdminLevel3: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 3)");
case AdminLevel4: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 4)");
case AdminLevel5: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 5)");
case AdminLevel6: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 6)");
case AdminLevel7: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 7)");
case AdminLevel8: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 8)");
case AdminLevel9: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 9)");
case AdminLevel10: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 10)");
case AdminLevel11: return GeoDataPlacemarkPrivate::tr("Admin Boundary (Level 11)");
case BoundaryMaritime: return GeoDataPlacemarkPrivate::tr("Boundary (Maritime)");
case Landmass: return GeoDataPlacemarkPrivate::tr("Land Mass");
case UrbanArea: return GeoDataPlacemarkPrivate::tr("Urban Area");
case InternationalDateLine: return GeoDataPlacemarkPrivate::tr("International Date Line");
case Bathymetry: return GeoDataPlacemarkPrivate::tr("Bathymetry");
case WaterwayCanal: return GeoDataPlacemarkPrivate::tr("Canal");
case WaterwayDrain: return GeoDataPlacemarkPrivate::tr("Drain");
case WaterwayDitch: return GeoDataPlacemarkPrivate::tr("Ditch");
case WaterwayStream: return GeoDataPlacemarkPrivate::tr("Stream");
case WaterwayRiver: return GeoDataPlacemarkPrivate::tr("River");
case WaterwayWeir: return GeoDataPlacemarkPrivate::tr("Weir");
case CrossingSignals: return GeoDataPlacemarkPrivate::tr("Crosswalk");
case CrossingIsland: return GeoDataPlacemarkPrivate::tr("Crosswalk");
case CrossingZebra: return GeoDataPlacemarkPrivate::tr("Crosswalk");
case CrossingRailway: return GeoDataPlacemarkPrivate::tr("Railway Crossing");
case IndoorDoor: return GeoDataPlacemarkPrivate::tr("Door");
case IndoorWall: return GeoDataPlacemarkPrivate::tr("Wall");
case IndoorRoom: return GeoDataPlacemarkPrivate::tr("Room");
case Default:
case Unknown:
case None:
case LastIndex: return QString();
}
return QString();
}
qreal GeoDataPlacemark::area() const
{
Q_D(const GeoDataPlacemark);
return d->m_placemarkExtendedData ? d->m_placemarkExtendedData->m_area : -1.0;
}
void GeoDataPlacemark::setArea( qreal area )
{
if (area == -1.0 && !d_func()->m_placemarkExtendedData) {
return; // nothing to do
}
Q_D(GeoDataPlacemark);
d->placemarkExtendedData().m_area = area;
}
qint64 GeoDataPlacemark::population() const
{
Q_D(const GeoDataPlacemark);
return d->m_population;
}
void GeoDataPlacemark::setPopulation( qint64 population )
{
Q_D(GeoDataPlacemark);
d->m_population = population;
}
const QString GeoDataPlacemark::state() const
{
Q_D(const GeoDataPlacemark);
return d->m_placemarkExtendedData ? d->m_placemarkExtendedData->m_state : QString();
}
void GeoDataPlacemark::setState( const QString &state )
{
if (state.isEmpty() && !d_func()->m_placemarkExtendedData) {
return; // nothing to do
}
Q_D(GeoDataPlacemark);
d->placemarkExtendedData().m_state = state;
}
const QString GeoDataPlacemark::countryCode() const
{
Q_D(const GeoDataPlacemark);
return d->m_placemarkExtendedData ? d->m_placemarkExtendedData->m_countrycode : QString();
}
void GeoDataPlacemark::setCountryCode( const QString &countrycode )
{
if (countrycode.isEmpty() && !d_func()->m_placemarkExtendedData) {
return; // nothing to do
}
Q_D(GeoDataPlacemark);
d->placemarkExtendedData().m_countrycode = countrycode;
}
bool GeoDataPlacemark::isBalloonVisible() const
{
Q_D(const GeoDataPlacemark);
return d->m_placemarkExtendedData ? d->m_placemarkExtendedData->m_isBalloonVisible : false;
}
void GeoDataPlacemark::setBalloonVisible( bool visible )
{
if (!visible && !d_func()->m_placemarkExtendedData) {
return; // nothing to do
}
Q_D(GeoDataPlacemark);
d->placemarkExtendedData().m_isBalloonVisible = visible;
}
void GeoDataPlacemark::pack( QDataStream& stream ) const
{
Q_D(const GeoDataPlacemark);
GeoDataFeature::pack( stream );
stream << d->placemarkExtendedData().m_countrycode;
stream << d->placemarkExtendedData().m_area;
stream << d->m_population;
if (d->m_geometry) {
stream << d->m_geometry->geometryId();
d->m_geometry->pack( stream );
}
else
{
stream << InvalidGeometryId;
}
}
QXmlStreamWriter& GeoDataPlacemark::pack( QXmlStreamWriter& stream ) const
{
stream.writeStartElement( "placemark" );
stream.writeEndElement();
return stream;
}
QXmlStreamWriter& GeoDataPlacemark::operator <<( QXmlStreamWriter& stream ) const
{
pack( stream );
return stream;
}
void GeoDataPlacemark::unpack( QDataStream& stream )
{
Q_D(GeoDataPlacemark);
GeoDataFeature::unpack( stream );
stream >> d->placemarkExtendedData().m_countrycode;
stream >> d->placemarkExtendedData().m_area;
stream >> d->m_population;
int geometryId;
stream >> geometryId;
GeoDataGeometry *geometry = nullptr;
switch( geometryId ) {
case InvalidGeometryId:
break;
case GeoDataPointId:
{
GeoDataPoint* point = new GeoDataPoint;
point->unpack( stream );
geometry = point;
}
break;
case GeoDataLineStringId:
{
GeoDataLineString* lineString = new GeoDataLineString;
lineString->unpack( stream );
geometry = lineString;
}
break;
case GeoDataLinearRingId:
{
GeoDataLinearRing* linearRing = new GeoDataLinearRing;
linearRing->unpack( stream );
geometry = linearRing;
}
break;
case GeoDataPolygonId:
{
GeoDataPolygon* polygon = new GeoDataPolygon;
polygon->unpack( stream );
geometry = polygon;
}
break;
case GeoDataMultiGeometryId:
{
GeoDataMultiGeometry* multiGeometry = new GeoDataMultiGeometry;
multiGeometry->unpack( stream );
geometry = multiGeometry;
}
break;
case GeoDataModelId:
break;
default: break;
};
if (geometry) {
delete d->m_geometry;
d->m_geometry = geometry;
d->m_geometry->setParent(this);
}
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataPlacemark.h b/src/lib/marble/geodata/data/GeoDataPlacemark.h
index 033308f37..c223732d8 100644
--- a/src/lib/marble/geodata/data/GeoDataPlacemark.h
+++ b/src/lib/marble/geodata/data/GeoDataPlacemark.h
@@ -1,713 +1,713 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
//
#ifndef MARBLE_GEODATAPLACEMARK_H
#define MARBLE_GEODATAPLACEMARK_H
#include <QDateTime>
#include "GeoDataCoordinates.h"
#include "GeoDataFeature.h"
#include "geodata_export.h"
class QXmlStreamWriter;
namespace Marble
{
class GeoDataPlacemarkPrivate;
class OsmPlacemarkData;
class GeoDataLookAt;
class GeoDataPolygon;
class GeoDataGeometry;
/**
* @short a class representing a point of interest on the map
*
* This class represents a point of interest, e.g. a city or a
* mountain. It is filled with data by the KML or GPX loader and the
* PlacemarkModel makes use of it.
*
* A Placemark can have an associated geometry which will be rendered to the map
* along with the placemark's point icon. If you would like to render more than
* one geometry for any one placemark than use @see setGeometry() to set add a
* @see MultiGeometry.
*
* This is more or less only a GeoDataFeature with a geographic
* position and a country code attached to it. The country code is
* not provided in a KML file.
*/
class GEODATA_EXPORT GeoDataPlacemark: public GeoDataFeature
{
public:
/**
* Create a new placemark.
*/
GeoDataPlacemark();
/**
* Create a new placemark from existing placemark @p placemark
*/
GeoDataPlacemark( const GeoDataPlacemark& placemark );
/**
* Create a new placemark with the given @p name.
*/
explicit GeoDataPlacemark( const QString &name );
/**
* Delete the placemark
*/
~GeoDataPlacemark() override;
GeoDataPlacemark &operator=( const GeoDataPlacemark &other );
/**
* Equality operators.
*/
bool operator==( const GeoDataPlacemark& other ) const;
bool operator!=( const GeoDataPlacemark& other ) const;
const char* nodeType() const override;
GeoDataFeature * clone() const override;
/**
* @brief A categorization of a placemark as defined by ...FIXME.
* There is an additional osm tag mapping to GeoDataVisualCategory
* in OsmPlacemarkData
*/
enum GeoDataVisualCategory {
None,
Default,
Unknown,
// The order of the cities needs to stay fixed as the
// algorithms rely on that.
SmallCity,
SmallCountyCapital,
SmallStateCapital,
SmallNationCapital,
MediumCity,
MediumCountyCapital,
MediumStateCapital,
MediumNationCapital,
BigCity,
BigCountyCapital,
BigStateCapital,
BigNationCapital,
LargeCity,
LargeCountyCapital,
LargeStateCapital,
LargeNationCapital,
Nation,
// Terrain
Mountain,
Volcano,
Mons, // m
Valley, // v
Continent,
Ocean,
OtherTerrain, // o
// Space Terrain
Crater, // c
Mare, // a
// Places of Interest
GeographicPole,
MagneticPole,
ShipWreck,
AirPort,
Observatory,
// Military
MilitaryDangerArea,
// Runners
OsmSite,
Coordinate,
// Planets
MannedLandingSite, // h
RoboticRover, // r
UnmannedSoftLandingSite, // u
UnmannedHardLandingSite, // i
Bookmark,
Satellite,
/*
* Start of OpenStreetMap categories
*/
PlaceCity, // please keep order (used in for loops)
PlaceCityCapital,
PlaceCityNationalCapital,
PlaceSuburb,
PlaceHamlet,
PlaceLocality,
PlaceTown,
PlaceTownCapital,
PlaceTownNationalCapital,
PlaceVillage,
PlaceVillageCapital,
PlaceVillageNationalCapital, // please keep order (used in for loops)
NaturalWater,
NaturalReef,
NaturalWood,
NaturalBeach,
NaturalWetland,
NaturalGlacier,
NaturalIceShelf,
NaturalScrub,
NaturalCliff,
NaturalHeath,
HighwayTrafficSignals,
HighwayElevator,
// OpenStreetMap highways
HighwaySteps, // please keep order (used in for loops)
HighwayUnknown,
HighwayPath,
HighwayFootway,
HighwayTrack,
HighwayPedestrian,
HighwayCorridor,
HighwayCycleway,
HighwayService,
HighwayRoad,
HighwayResidential,
HighwayLivingStreet,
HighwayUnclassified,
HighwayTertiaryLink,
HighwayTertiary,
HighwaySecondaryLink,
HighwaySecondary,
HighwayPrimaryLink,
HighwayPrimary,
HighwayRaceway,
HighwayTrunkLink,
HighwayTrunk,
HighwayMotorwayLink,
HighwayMotorway, // please keep order (used in for loops)
//OSM building
Building,
// OpenStreetMap category Accomodation
AccomodationCamping,
AccomodationHostel,
AccomodationHotel,
AccomodationMotel,
AccomodationYouthHostel,
AccomodationGuestHouse,
// OpenStreetMap category Education
EducationCollege,
EducationSchool,
EducationUniversity,
// OpenStreetMap category Food
FoodBar,
FoodBiergarten,
FoodCafe,
FoodFastFood,
FoodPub,
FoodRestaurant,
// OpenStreetMap category Health
HealthDentist,
HealthDoctors,
HealthHospital,
HealthPharmacy,
HealthVeterinary,
// OpenStreetMap category Money
MoneyAtm,
MoneyBank,
// OpenStreetMap category Amenity
AmenityLibrary,
AmenityKindergarten, ///< @since 0.26.0
AmenityEmbassy,
AmenityEmergencyPhone,
AmenityMountainRescue,
AmenityCommunityCentre,
AmenityCinema,
AmenityFountain,
AmenityNightClub,
AmenityBench,
AmenityCourtHouse,
AmenityFireStation,
AmenityHuntingStand,
AmenityPolice,
AmenityPostBox,
AmenityPostOffice,
AmenityPrison,
AmenityRecycling,
AmenityShelter, ///< @since 0.26.0
AmenityTelephone,
AmenityTheatre,
AmenityToilets,
AmenityTownHall,
AmenityWasteBasket,
AmenityDrinkingWater,
AmenityGraveyard,
AmenityChargingStation,
AmenityCarWash,
AmenitySocialFacility,
// OpenStreetMap category Barrier
BarrierCityWall,
BarrierGate,
BarrierLiftGate,
BarrierWall,
NaturalPeak,
NaturalVolcano,
NaturalTree,
NaturalCave,
// OpenStreetMap category Shopping
ShopBeverages, // please keep order (used in for loops)
ShopHifi,
ShopSupermarket,
ShopAlcohol,
ShopBakery,
ShopButcher,
ShopConfectionery,
ShopConvenience,
ShopGreengrocer,
ShopSeafood,
ShopDepartmentStore,
ShopKiosk,
ShopBag,
ShopClothes,
ShopFashion,
ShopJewelry,
ShopShoes,
ShopVarietyStore,
ShopBeauty,
ShopChemist,
ShopCosmetics,
ShopHairdresser,
ShopOptician,
ShopPerfumery,
ShopDoitYourself,
ShopFlorist,
ShopHardware,
ShopFurniture,
ShopElectronics,
ShopMobilePhone,
ShopBicycle,
ShopCar,
ShopCarRepair,
ShopCarParts,
ShopMotorcycle,
ShopOutdoor,
ShopSports,
ShopCopy,
ShopArt,
ShopMusicalInstrument,
ShopPhoto,
ShopBook,
ShopGift,
ShopStationery,
ShopLaundry,
ShopPet,
ShopToys,
ShopTravelAgency,
ShopDeli,
ShopTobacco,
ShopTea,
ShopComputer,
ShopGardenCentre,
Shop, // please keep order (used in for loops)
ManmadeBridge,
ManmadeLighthouse,
ManmadePier,
ManmadeWaterTower,
ManmadeWindMill,
ManmadeCommunicationsTower,
// OpenStreetMap category Tourist
TourismArtwork,
TourismAttraction,
TourismInformation,
TourismMuseum,
TourismThemePark,
TourismViewPoint,
TourismZoo,
TourismAlpineHut,
TourismWildernessHut,
// OpenStreetMap category Historic
HistoricArchaeologicalSite,
HistoricCastle,
HistoricMemorial,
HistoricMonument,
HistoricRuins,
// OpenStreetMap category Transport
TransportAerodrome,
TransportHelipad,
TransportAirportTerminal,
TransportAirportGate, ///< @since 0.26.0
TransportAirportRunway, ///< @since 0.26.0
TransportAirportTaxiway, ///< @since 0.26.0
TransportAirportApron, ///< @since 0.26.0
TransportBusStation,
TransportBusStop,
TransportCarShare,
TransportFuel,
TransportParking,
TransportParkingSpace,
TransportPlatform,
TransportRentalBicycle,
TransportRentalCar,
TransportRentalSki,
TransportTaxiRank,
TransportTrainStation,
TransportTramStop,
TransportBicycleParking,
TransportMotorcycleParking,
TransportSubwayEntrance,
TransportSpeedCamera,
// OpenStreetMap category religion
ReligionPlaceOfWorship,
ReligionBahai,
ReligionBuddhist,
ReligionChristian,
ReligionMuslim,
ReligionHindu,
ReligionJain,
ReligionJewish,
ReligionShinto,
ReligionSikh,
ReligionTaoist,
// OpenStreetMap category Leisure
LeisureGolfCourse,
LeisureMarina, ///< @since 0.26.0
LeisureWaterPark,
LeisurePark,
LeisurePlayground,
LeisurePitch,
LeisureSportsCentre,
LeisureStadium,
LeisureTrack,
LeisureSwimmingPool,
LeisureMinigolfCourse,
LanduseAllotments,
LanduseBasin,
LanduseCemetery,
LanduseCommercial,
LanduseConstruction,
LanduseFarmland,
LanduseFarmyard,
LanduseGarages,
LanduseGrass,
LanduseIndustrial,
LanduseLandfill,
LanduseMeadow,
LanduseMilitary,
LanduseQuarry,
LanduseRailway,
LanduseReservoir,
LanduseResidential,
LanduseRetail,
LanduseOrchard,
LanduseVineyard,
RailwayRail, // please keep order (used in for loops)
RailwayNarrowGauge,
RailwayTram,
RailwayLightRail,
RailwayAbandoned,
RailwaySubway,
RailwayPreserved,
RailwayMiniature,
RailwayConstruction,
RailwayMonorail,
RailwayFunicular, // please keep order (used in for loops)
// OpenStreetMap category Power
PowerTower,
// OpenStreetMap category Aerialway
AerialwayStation,
AerialwayPylon, // node only
// below please keep order (used in for loops)
AerialwayCableCar,
AerialwayGondola,
AerialwayChairLift,
AerialwayMixedLift,
AerialwayDragLift,
AerialwayTBar,
AerialwayJBar,
AerialwayPlatter,
AerialwayRopeTow,
AerialwayMagicCarpet,
AerialwayZipLine,
AerialwayGoods, // please keep order (used in for loops)
// OpenStreetMap category Piste
PisteDownhill,
PisteNordic,
PisteSkitour,
PisteSled,
PisteHike,
PisteSleigh,
PisteIceSkate,
PisteSnowPark,
PistePlayground,
PisteSkiJump,
// Waterways
WaterwayCanal, // please keep order (used in for loops)
WaterwayDitch,
WaterwayDrain,
WaterwayRiver,
WaterwayWeir,
WaterwayStream, // please keep order (used in for loops)
CrossingSignals, // pedestrian vs highway crossing with traffic signals
CrossingIsland, // pedestrian vs highway crossing with a traffic island
CrossingZebra, // pedestrian vs highway zebra crossing
CrossingRailway, // pedestrian or highway vs railway crossing
//Admin level tags for depicting boundary
AdminLevel1, // please keep order (used in for loops)
AdminLevel2,
AdminLevel3,
AdminLevel4,
AdminLevel5,
AdminLevel6,
AdminLevel7,
AdminLevel8,
AdminLevel9,
AdminLevel10,
AdminLevel11, // please keep order (used in for loops)
BoundaryMaritime,
IndoorDoor,
IndoorWall,
IndoorRoom,
//Custom OSM Tags
Landmass,
UrbanArea,
InternationalDateLine,
Bathymetry, ///< @since 0.26.0
// Important: Make sure that this is always the last
// item and just use it to specify the array size
LastIndex
};
/**
* Return the symbol index of the placemark.
*/
GeoDataVisualCategory visualCategory() const;
/**
* Sets the symbol @p index of the placemark.
* @param category the new category to be used.
*/
void setVisualCategory(GeoDataVisualCategory category);
/**
* Return the coordinates of the placemark at time @p dateTime as a GeoDataCoordinates
*
* The @p dateTime parameter should be used if the placemark geometry() is a
* GeoDataTrack and thus contains several coordinates associated with a date and time.
*
* The @p iconAtCoordinates boolean is set to true if an icon should be drawn to
* represent the placemark at these coordinates as described in
* https://code.google.com/apis/kml/documentation/kmlreference.html#placemark,
* it is set to false otherwise.
*
* @see GeoDataTrack::GeoDataTrack
*/
- GeoDataCoordinates coordinate( const QDateTime &dateTime = QDateTime(), bool *iconAtCoordinates = 0 ) const;
+ GeoDataCoordinates coordinate( const QDateTime &dateTime = QDateTime(), bool *iconAtCoordinates = nullptr ) const;
/**
* The geometry of the GeoDataPlacemark is to be rendered to the marble map
* along with the icon at the coordinate associated with this Placemark.
* @return a pointer to the current Geometry object
*/
GeoDataGeometry* geometry();
const GeoDataGeometry* geometry() const;
/**
* @brief displays the name of a place in the locale language of the user
*/
QString displayName() const;
/**
* @since 0.26.0
*/
QString categoryName() const;
/**
* Return the coordinates of the placemark as @p longitude,
* @p latitude and @p altitude.
*/
void coordinate( qreal &longitude, qreal &latitude, qreal &altitude ) const;
/**
* Quick, safe accessor to the placemark's OsmPlacemarkData stored within it's
* ExtendedData. If the extendedData does not contain osmData, the function
* inserts a default-constructed one, and returns a reference to it.
*/
OsmPlacemarkData &osmData();
const OsmPlacemarkData &osmData() const;
void setOsmData( const OsmPlacemarkData &osmData );
bool hasOsmData() const;
/**
* @since 0.26.0
*/
void clearOsmData();
/**
* Set the coordinate of the placemark in @p longitude and
* @p latitude.
*/
void setCoordinate( qreal longitude, qreal latitude, qreal altitude = 0,
GeoDataCoordinates::Unit _unit = GeoDataCoordinates::Radian );
/**
* Set the coordinate of the placemark with an @p GeoDataPoint.
*/
void setCoordinate( const GeoDataCoordinates &coordinate );
/**
* Sets the current Geometry of this Placemark. @see geometry() and the class
* overview for description of the geometry concept. The geometry can be set
* to any @see GeoDataGeometry like @see GeoDataPoint,@see GeoDataLineString,
* @see GeoDataLinearRing and @see GeoDataMultiGeometry
*/
void setGeometry( GeoDataGeometry *entry );
/**
* Return the area size of the feature in square km.
*
* FIXME: Once we make Marble more area-aware we need to
* move this into the GeoDataArea class which will get
* inherited from GeoDataPlacemark (or GeoDataFeature).
*/
qreal area() const;
/**
* Set the area size of the feature in square km.
*/
void setArea( qreal area );
/**
* Return the population of the placemark.
*/
qint64 population() const;
/**
* Sets the @p population of the placemark.
* @param population the new population value
*/
void setPopulation( qint64 population );
/**
* Return the state of the placemark.
*/
const QString state() const;
/**
* Set the state @p state of the placemark.
*/
void setState( const QString &state );
/**
* Return the country code of the placemark.
*/
const QString countryCode() const;
/**
* Set the country @p code of the placemark.
*/
void setCountryCode( const QString &code );
/**
* Returns whether balloon is visible or not
*/
bool isBalloonVisible() const;
/**
* Set visibility of the balloon
*/
void setBalloonVisible( bool visible );
/**
* Serialize the Placemark to a data stream. This is a binary serialisation
* and is deserialised using @see unpack()
* @param stream the QDataStream to serialise object to.
*/
void pack( QDataStream& stream ) const override;
/**
* Serialise this Placemark to a XML stream writer @see QXmlStreamWriter in
* the Qt documentation for more info. This will output the XML
* representation of this Placemark. The default XML format is KML, to have
* other formats supported you need to create a subclass and override this
* method.
* @param stream the XML Stream Reader to output to.
*/
virtual QXmlStreamWriter& pack( QXmlStreamWriter& stream ) const;
virtual QXmlStreamWriter& operator <<( QXmlStreamWriter& stream ) const;
/**
* Deserialize the Placemark from a data stream. This has the opposite effect
* from @see pack()
* @param stream the QDataStream to deserialise from.
*/
void unpack( QDataStream& stream ) override;
/**
* Returns GeoDataLookAt object if lookAt is setup earlier
* otherwise It will convert GeoDataCoordinates of Placemark
* to GeoDataLookAt with range equals to altitude of
* GeoDataCoordinate
*/
const GeoDataLookAt *lookAt() const;
GeoDataLookAt *lookAt();
static bool placemarkLayoutOrderCompare(const GeoDataPlacemark *a, const GeoDataPlacemark* b);
private:
Q_DECLARE_PRIVATE(GeoDataPlacemark)
};
}
#endif
diff --git a/src/lib/marble/geodata/data/GeoDataPlaylist.cpp b/src/lib/marble/geodata/data/GeoDataPlaylist.cpp
index 88c7bfe32..e3cff0e8f 100644
--- a/src/lib/marble/geodata/data/GeoDataPlaylist.cpp
+++ b/src/lib/marble/geodata/data/GeoDataPlaylist.cpp
@@ -1,93 +1,93 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "GeoDataPlaylist.h"
#include "GeoDataTourPrimitive.h"
#include "GeoDataTypes.h"
namespace Marble
{
bool GeoDataPlaylist::operator==(const GeoDataPlaylist& other) const
{
if( this->m_primitives.size() != other.m_primitives.size() ){
return false;
}
else{
int index = 0;
for( GeoDataTourPrimitive* m_primitive: m_primitives ){
if (*m_primitive != *other.m_primitives.at(index)) {
return false;
}
index++;
}
return true;
}
}
bool GeoDataPlaylist::operator!=(const GeoDataPlaylist& other) const
{
return !this->operator==(other);
}
const char *GeoDataPlaylist::nodeType() const
{
return GeoDataTypes::GeoDataPlaylistType;
}
GeoDataTourPrimitive* GeoDataPlaylist::primitive(int id)
{
if (size() <= id || id < 0) {
- return 0;
+ return nullptr;
}
return m_primitives.at(id);
}
const GeoDataTourPrimitive* GeoDataPlaylist::primitive(int id) const
{
if (size() <= id || id < 0) {
- return 0;
+ return nullptr;
}
return m_primitives.at(id);
}
void GeoDataPlaylist::addPrimitive( GeoDataTourPrimitive *primitive )
{
primitive->setParent( this );
m_primitives.push_back( primitive );
}
void GeoDataPlaylist::insertPrimitive( int position, GeoDataTourPrimitive *primitive )
{
primitive->setParent( this );
int const index = qBound( 0, position, m_primitives.size() );
m_primitives.insert( index, primitive );
}
void GeoDataPlaylist::removePrimitiveAt(int position)
{
m_primitives.removeAt( position );
}
void GeoDataPlaylist::swapPrimitives( int positionA, int positionB )
{
if ( qMin( positionA, positionB ) >= 0 && qMax( positionA, positionB ) < m_primitives.size() ) {
m_primitives.swap( positionA, positionB );
}
}
int GeoDataPlaylist::size() const
{
return m_primitives.size();
}
} // namespace Marble
diff --git a/src/lib/marble/geodata/data/GeoDataRegion_p.h b/src/lib/marble/geodata/data/GeoDataRegion_p.h
index 31b7a0616..68f7ccd7a 100644
--- a/src/lib/marble/geodata/data/GeoDataRegion_p.h
+++ b/src/lib/marble/geodata/data/GeoDataRegion_p.h
@@ -1,76 +1,76 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Torsten Rahn <rahn@kde.org>
//
#ifndef MARBLE_GEODATAREGIONPRIVATE_H
#define MARBLE_GEODATAREGIONPRIVATE_H
#include "GeoDataRegion.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataTypes.h"
#include "GeoDataLod.h"
namespace Marble
{
class GeoDataRegionPrivate
{
public:
GeoDataRegionPrivate()
- : m_parent( 0 ),
- m_latLonAltBox( 0 ),
- m_lod( 0 )
+ : m_parent( nullptr ),
+ m_latLonAltBox( nullptr ),
+ m_lod( nullptr )
{
}
GeoDataRegionPrivate( const GeoDataRegionPrivate& other )
: m_parent( other.m_parent )
{
if ( other.m_latLonAltBox ) {
m_latLonAltBox = new GeoDataLatLonAltBox( *other.m_latLonAltBox );
}
else {
- m_latLonAltBox = 0;
+ m_latLonAltBox = nullptr;
}
if ( other.m_lod ) {
m_lod = new GeoDataLod( *other.m_lod );
}
else {
- m_lod = 0;
+ m_lod = nullptr;
}
}
explicit GeoDataRegionPrivate( GeoDataFeature * feature )
: m_parent( feature ),
- m_latLonAltBox( 0 ),
- m_lod( 0 )
+ m_latLonAltBox( nullptr ),
+ m_lod( nullptr )
{
}
~GeoDataRegionPrivate()
{
delete m_latLonAltBox;
delete m_lod;
}
GeoDataFeature * m_parent;
GeoDataLatLonAltBox * m_latLonAltBox;
GeoDataLod * m_lod;
private:
// Preventing usage of operator=
GeoDataRegionPrivate &operator=( const GeoDataRegionPrivate& );
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/geodata/data/GeoDataSchemaData.cpp b/src/lib/marble/geodata/data/GeoDataSchemaData.cpp
index 1cdc881b6..7183989af 100644
--- a/src/lib/marble/geodata/data/GeoDataSchemaData.cpp
+++ b/src/lib/marble/geodata/data/GeoDataSchemaData.cpp
@@ -1,157 +1,157 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
#include "GeoDataSchemaData.h"
// Qt
#include <QDataStream>
#include <QString>
#include <QHash>
// Marble
#include "GeoDataSimpleData.h"
#include "GeoDataTypes.h"
namespace Marble
{
class GeoDataSchemaDataPrivate
{
public:
GeoDataSchemaDataPrivate()
- : m_parent( 0 )
+ : m_parent( nullptr )
{
// nothing to do
}
QString m_schemaUrl;
QHash<QString, GeoDataSimpleData> m_simpleData; // Map for name and SimpleData
GeoNode *m_parent;
};
GeoDataSchemaData::GeoDataSchemaData()
: d( new GeoDataSchemaDataPrivate )
{
}
GeoDataSchemaData::GeoDataSchemaData( const GeoDataSchemaData &other )
: d( new GeoDataSchemaDataPrivate( *other.d ) )
{
}
GeoDataSchemaData &GeoDataSchemaData::operator=( const GeoDataSchemaData &rhs )
{
*d = *rhs.d;
return *this;
}
bool GeoDataSchemaData::operator==( const GeoDataSchemaData &other ) const
{
if ( d->m_schemaUrl != other.d->m_schemaUrl ||
d->m_simpleData.size() != other.d->m_simpleData.size() )
{
return false;
}
QHash<QString, GeoDataSimpleData>::iterator begin = d->m_simpleData.begin();
QHash<QString, GeoDataSimpleData>::iterator end = d->m_simpleData.end();
QHash<QString, GeoDataSimpleData>::iterator beginOther = other.d->m_simpleData.begin();
for( ; begin != end; ++begin, ++beginOther ) {
if ( *begin != *beginOther ) {
return false;
}
}
return true;
}
bool GeoDataSchemaData::operator!=( const GeoDataSchemaData &other ) const
{
return !this->operator==(other);
}
GeoDataSchemaData::~GeoDataSchemaData()
{
delete d;
}
QString GeoDataSchemaData::schemaUrl() const
{
return d->m_schemaUrl;
}
void GeoDataSchemaData::setSchemaUrl( const QString &schemaUrl )
{
d->m_schemaUrl = schemaUrl;
}
GeoDataSimpleData &GeoDataSchemaData::simpleData( const QString &name ) const
{
return d->m_simpleData[ name ];
}
void GeoDataSchemaData::addSimpleData( const GeoDataSimpleData &data )
{
d->m_simpleData.insert( data.name(), data );
}
QList<GeoDataSimpleData> GeoDataSchemaData::simpleDataList() const
{
return d->m_simpleData.values();
}
void GeoDataSchemaData::setParent( GeoNode *parent )
{
d->m_parent = parent;
}
const GeoNode *GeoDataSchemaData::parent() const
{
return d->m_parent;
}
GeoNode *GeoDataSchemaData::parent()
{
return d->m_parent;
}
const char* GeoDataSchemaData::nodeType() const
{
return GeoDataTypes::GeoDataSchemaDataType;
}
void GeoDataSchemaData::pack( QDataStream &stream ) const
{
stream << d->m_schemaUrl;
stream << d->m_simpleData.size();
QHash<QString, GeoDataSimpleData>::const_iterator iter = d->m_simpleData.constBegin();
QHash<QString, GeoDataSimpleData>::const_iterator end = d->m_simpleData.constEnd();
for( ; iter != end; ++iter ) {
iter.value().pack( stream );
}
}
void GeoDataSchemaData::unpack( QDataStream &stream )
{
stream >> d->m_schemaUrl;
int size = 0;
stream >> size;
for( int i = 0; i < size; i++ ) {
GeoDataSimpleData simpleData;
simpleData.unpack( stream );
d->m_simpleData.insert( simpleData.name(), simpleData );
}
}
} // namespace Marble
diff --git a/src/lib/marble/geodata/data/GeoDataStyleSelector.cpp b/src/lib/marble/geodata/data/GeoDataStyleSelector.cpp
index 49736fb68..b8b2c3e63 100644
--- a/src/lib/marble/geodata/data/GeoDataStyleSelector.cpp
+++ b/src/lib/marble/geodata/data/GeoDataStyleSelector.cpp
@@ -1,67 +1,67 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Murad Tagirov <tmurad@gmail.com>
//
#include "GeoDataStyleSelector.h"
#include <QDataStream>
#include "GeoDataTypes.h"
namespace Marble
{
class GeoDataStyleSelectorPrivate
{
};
GeoDataStyleSelector::GeoDataStyleSelector() :
GeoDataObject(),
- d( 0 )
+ d( nullptr )
{
}
GeoDataStyleSelector::GeoDataStyleSelector( const GeoDataStyleSelector& other ) :
GeoDataObject( other ),
- d( 0 )
+ d( nullptr )
{
}
GeoDataStyleSelector::~GeoDataStyleSelector()
{
delete d;
}
GeoDataStyleSelector& GeoDataStyleSelector::operator=( const GeoDataStyleSelector& other )
{
GeoDataObject::operator=( other );
return *this;
}
bool GeoDataStyleSelector::operator==( const GeoDataStyleSelector &other ) const
{
return GeoDataObject::equals( other );
}
bool GeoDataStyleSelector::operator!=( const GeoDataStyleSelector &other ) const
{
return !this->operator==( other );
}
void GeoDataStyleSelector::pack( QDataStream& stream ) const
{
GeoDataObject::pack( stream );
}
void GeoDataStyleSelector::unpack( QDataStream& stream )
{
GeoDataObject::unpack( stream );
}
}
diff --git a/src/lib/marble/geodata/data/GeoDataTour_p.h b/src/lib/marble/geodata/data/GeoDataTour_p.h
index d1840519f..b0c7bb807 100644
--- a/src/lib/marble/geodata/data/GeoDataTour_p.h
+++ b/src/lib/marble/geodata/data/GeoDataTour_p.h
@@ -1,68 +1,68 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
// Copyright 2014 Calin Cruceru <calin@rosedu.org>
//
#ifndef MARBLE_GEODATATOURPRIVATE_H
#define MARBLE_GEODATATOURPRIVATE_H
#include "GeoDataFeature_p.h"
#include "GeoDataTypes.h"
#include "GeoDataPlaylist.h"
namespace Marble
{
class GeoDataTourPrivate : public GeoDataFeaturePrivate
{
public:
GeoDataTourPrivate()
- : m_playlist( 0 )
+ : m_playlist( nullptr )
{
// nothing to do
}
GeoDataTourPrivate(const GeoDataTourPrivate &other)
: GeoDataFeaturePrivate(other),
m_playlist(nullptr)
{
if (other.m_playlist) {
m_playlist = new GeoDataPlaylist(*other.m_playlist);
}
}
~GeoDataTourPrivate() override
{
delete m_playlist;
}
GeoDataTourPrivate& operator=( const GeoDataTourPrivate &other )
{
if ( this == &other ) {
return *this;
}
GeoDataFeaturePrivate::operator=( other );
- GeoDataPlaylist *newPlaylist = 0;
+ GeoDataPlaylist *newPlaylist = nullptr;
if ( other.m_playlist ) {
newPlaylist = new GeoDataPlaylist( *other.m_playlist );
}
delete m_playlist;
m_playlist = newPlaylist;
return *this;
}
GeoDataPlaylist *m_playlist;
};
}
#endif // MARBLE_GEODATATOURPRIVATE_H
diff --git a/src/lib/marble/geodata/data/GeoDataUpdate.cpp b/src/lib/marble/geodata/data/GeoDataUpdate.cpp
index 9408d478c..06b5c27bb 100644
--- a/src/lib/marble/geodata/data/GeoDataUpdate.cpp
+++ b/src/lib/marble/geodata/data/GeoDataUpdate.cpp
@@ -1,151 +1,151 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "GeoDataUpdate.h"
#include "GeoDataCreate.h"
#include "GeoDataDelete.h"
#include "GeoDataChange.h"
#include "GeoDataTypes.h"
#include <QString>
namespace Marble
{
class GeoDataUpdatePrivate
{
public:
GeoDataUpdatePrivate();
GeoDataCreate* m_create;
GeoDataDelete* m_delete;
GeoDataChange* m_change;
QString m_targetHref;
};
GeoDataUpdatePrivate::GeoDataUpdatePrivate() :
- m_create( 0 ), m_delete( 0 ), m_change( 0 )
+ m_create( nullptr ), m_delete( nullptr ), m_change( nullptr )
{
}
GeoDataUpdate::GeoDataUpdate() :
d( new GeoDataUpdatePrivate )
{
}
GeoDataUpdate::GeoDataUpdate( const Marble::GeoDataUpdate &other ) :
GeoDataObject(), d( new GeoDataUpdatePrivate( *other.d ) )
{
}
GeoDataUpdate &GeoDataUpdate::operator=( const GeoDataUpdate &other )
{
GeoDataObject::operator =( other );
*d = *other.d;
return *this;
}
bool GeoDataUpdate::operator==(const GeoDataUpdate& other) const
{
bool const changeEmpty = !d->m_change || d->m_change->size() == 0;
bool const otherChangeEmpty = !other.d->m_change || other.d->m_change->size() == 0;
if( changeEmpty != otherChangeEmpty ) {
return false;
} else if( d->m_change && other.d->m_change && *d->m_change != *other.d->m_change ) {
return false;
}
return d->m_targetHref == other.d->m_targetHref;
}
bool GeoDataUpdate::operator!=(const GeoDataUpdate& other) const
{
return !this->operator==(other);
}
GeoDataUpdate::~GeoDataUpdate()
{
delete d;
}
const char *GeoDataUpdate::nodeType() const
{
return GeoDataTypes::GeoDataUpdateType;
}
QString GeoDataUpdate::targetHref() const
{
return d->m_targetHref;
}
void GeoDataUpdate::setTargetHref( const QString &targetHref )
{
d->m_targetHref = targetHref;
}
const GeoDataChange *GeoDataUpdate::change() const
{
return d->m_change;
}
GeoDataChange *GeoDataUpdate::change()
{
return d->m_change;
}
void GeoDataUpdate::setChange( GeoDataChange* change )
{
delete d->m_change;
d->m_change = change;
if ( d->m_change ) {
d->m_change->setParent( this );
}
}
const GeoDataCreate *GeoDataUpdate::create() const
{
return d->m_create;
}
GeoDataCreate *GeoDataUpdate::create()
{
return d->m_create;
}
void GeoDataUpdate::setCreate( GeoDataCreate* create )
{
delete d->m_create;
d->m_create = create;
if ( d->m_create ) {
d->m_create->setParent( this );
}
}
const GeoDataDelete *GeoDataUpdate::getDelete() const
{
return d->m_delete;
}
GeoDataDelete *GeoDataUpdate::getDelete()
{
return d->m_delete;
}
void GeoDataUpdate::setDelete( GeoDataDelete* dataDelete )
{
delete d->m_delete;
d->m_delete = dataDelete;
if ( d->m_delete ) {
d->m_delete->setParent( this );
}
}
}
diff --git a/src/lib/marble/geodata/graphicsitem/AbstractGeoPolygonGraphicsItem.cpp b/src/lib/marble/geodata/graphicsitem/AbstractGeoPolygonGraphicsItem.cpp
index b05e608a5..58789ec08 100644
--- a/src/lib/marble/geodata/graphicsitem/AbstractGeoPolygonGraphicsItem.cpp
+++ b/src/lib/marble/geodata/graphicsitem/AbstractGeoPolygonGraphicsItem.cpp
@@ -1,240 +1,240 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Konstantin Oblaukhov <oblaukhov.konstantin@gmail.com>
//
#include "AbstractGeoPolygonGraphicsItem.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoDataBuilding.h"
#include "GeoPainter.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataLineStyle.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataTypes.h"
#include "OsmPlacemarkData.h"
#include "MarbleDebug.h"
#include "ViewportParams.h"
#include <QtMath>
#include <QImageReader>
#include <QPixmapCache>
namespace Marble
{
-const void *AbstractGeoPolygonGraphicsItem::s_previousStyle = 0;
+const void *AbstractGeoPolygonGraphicsItem::s_previousStyle = nullptr;
AbstractGeoPolygonGraphicsItem::AbstractGeoPolygonGraphicsItem(const GeoDataPlacemark *placemark, const GeoDataPolygon *polygon) :
GeoGraphicsItem(placemark),
m_polygon(polygon),
- m_ring(0),
- m_building(0)
+ m_ring(nullptr),
+ m_building(nullptr)
{
}
AbstractGeoPolygonGraphicsItem::AbstractGeoPolygonGraphicsItem(const GeoDataPlacemark *placemark, const GeoDataLinearRing *ring) :
GeoGraphicsItem(placemark),
- m_polygon(0),
+ m_polygon(nullptr),
m_ring(ring),
- m_building(0)
+ m_building(nullptr)
{
}
AbstractGeoPolygonGraphicsItem::AbstractGeoPolygonGraphicsItem(const GeoDataPlacemark *placemark, const GeoDataBuilding *building) :
GeoGraphicsItem(placemark),
- m_polygon(0),
- m_ring(0),
+ m_polygon(nullptr),
+ m_ring(nullptr),
m_building(building)
{
}
AbstractGeoPolygonGraphicsItem::~AbstractGeoPolygonGraphicsItem()
{
}
const GeoDataLatLonAltBox& AbstractGeoPolygonGraphicsItem::latLonAltBox() const
{
if(m_polygon) {
return m_polygon->latLonAltBox();
} else if (m_ring) {
return m_ring->latLonAltBox();
}
return m_building->latLonAltBox();
}
void AbstractGeoPolygonGraphicsItem::paint( GeoPainter* painter, const ViewportParams* viewport, const QString &layer, int tileZoomLevel)
{
Q_UNUSED(layer);
Q_UNUSED(tileZoomLevel);
bool isValid = true;
if (s_previousStyle != style().data()) {
isValid = configurePainter(painter, *viewport);
}
s_previousStyle = style().data();
if (!isValid) return;
if ( m_polygon ) {
bool innerResolved = false;
for(auto const & ring : m_polygon->innerBoundaries()) {
if (viewport->resolves(ring.latLonAltBox(), 4)) {
innerResolved = true;
break;
}
}
if (innerResolved) {
painter->drawPolygon(*m_polygon);
}
else {
painter->drawPolygon(m_polygon->outerBoundary());
}
} else if ( m_ring ) {
painter->drawPolygon( *m_ring );
}
}
bool AbstractGeoPolygonGraphicsItem::contains(const QPoint &screenPosition, const ViewportParams *viewport) const
{
auto const visualCategory = static_cast<const GeoDataPlacemark*>(feature())->visualCategory();
if (visualCategory == GeoDataPlacemark::Landmass ||
visualCategory == GeoDataPlacemark::UrbanArea ||
(visualCategory >= GeoDataPlacemark::LanduseAllotments && visualCategory <= GeoDataPlacemark::LanduseVineyard)) {
return false;
}
double lon, lat;
viewport->geoCoordinates(screenPosition.x(), screenPosition.y(), lon, lat, GeoDataCoordinates::Radian);
auto const coordinates = GeoDataCoordinates(lon, lat);
if (m_polygon) {
return m_polygon->contains(coordinates);
} else if (m_ring) {
return m_ring->contains(coordinates);
}
return false;
}
bool AbstractGeoPolygonGraphicsItem::configurePainter(GeoPainter *painter, const ViewportParams &viewport) const
{
QPen currentPen = painter->pen();
GeoDataStyle::ConstPtr style = this->style();
if (!style) {
painter->setPen( QPen() ); // "style-less" polygons: a 1px black solid line
}
else {
const GeoDataPolyStyle& polyStyle = style->polyStyle();
if (polyStyle.outline()) {
const GeoDataLineStyle& lineStyle = style->lineStyle();
// To save performance we avoid making changes to the painter's pen.
// So we first take a copy of the actual painter pen, make changes to it
// and only if the resulting pen is different from the actual pen
// we replace the painter's pen with our new pen.
// We want to avoid the mandatory detach in QPen::setColor(),
// so we carefully check whether applying the setter is needed
currentPen.setColor(lineStyle.paintedColor());
currentPen.setWidthF(lineStyle.width());
currentPen.setCapStyle(lineStyle.capStyle());
currentPen.setStyle(lineStyle.penStyle());
if (painter->pen().color() != currentPen.color()) {
painter->setPen(currentPen);
}
}
else {
// polygons without outline: Qt::NoPen (not drawn)
if (currentPen.style() != Qt::NoPen) {
painter->setPen(Qt::NoPen);
}
}
if (!polyStyle.fill()) {
painter->setBrush(Qt::transparent);
}
else {
const QColor paintedColor = polyStyle.paintedColor();
if (painter->brush().color() != paintedColor ||
painter->brush().style() != polyStyle.brushStyle()) {
if (!polyStyle.texturePath().isEmpty() || !polyStyle.textureImage().isNull()) {
GeoDataCoordinates coords = latLonAltBox().center();
qreal x, y;
viewport.screenCoordinates(coords, x, y);
QBrush brush(texture(polyStyle.texturePath(), paintedColor));
painter->setBrush(brush);
painter->setBrushOrigin(QPoint(x,y));
}
else {
painter->setBrush(QBrush(paintedColor, polyStyle.brushStyle()));
}
}
}
}
return true;
}
int AbstractGeoPolygonGraphicsItem::extractElevation(const GeoDataPlacemark &placemark)
{
int elevation = 0;
const OsmPlacemarkData &osmData = placemark.osmData();
const auto tagIter = osmData.findTag(QStringLiteral("ele"));
if (tagIter != osmData.tagsEnd()) {
elevation = tagIter.value().toInt();
}
return elevation;
}
QPixmap AbstractGeoPolygonGraphicsItem::texture(const QString &texturePath, const QColor &color) const
{
QString const key = QString::number(color.rgba()) + '/' + texturePath;
QPixmap texture;
if (!QPixmapCache::find(key, texture)) {
QImageReader imageReader(style()->polyStyle().resolvePath(texturePath));
texture = QPixmap::fromImageReader(&imageReader);
if (texture.hasAlphaChannel()) {
QPixmap pixmap (texture.size());
pixmap.fill(color);
QPainter imagePainter(&pixmap);
imagePainter.drawPixmap(0, 0, texture);
imagePainter.end();
texture = pixmap;
}
QPixmapCache::insert(key, texture);
}
return texture;
}
void AbstractGeoPolygonGraphicsItem::setLinearRing(GeoDataLinearRing *ring)
{
Q_ASSERT(m_building);
Q_ASSERT(!m_polygon);
m_ring = ring;
}
void AbstractGeoPolygonGraphicsItem::setPolygon(GeoDataPolygon *polygon)
{
Q_ASSERT(m_building);
Q_ASSERT(!m_ring);
m_polygon = polygon;
}
}
diff --git a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp
index 42d3247b3..5e3620859 100644
--- a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp
+++ b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp
@@ -1,511 +1,511 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Andrew Manson <g.real.ate@gmail.com>
//
#include "GeoLineStringGraphicsItem.h"
#include "GeoDataLineString.h"
#include "GeoDataLineStyle.h"
#include "GeoDataLabelStyle.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPolyStyle.h"
#include "GeoPainter.h"
#include "StyleBuilder.h"
#include "ViewportParams.h"
#include "GeoDataStyle.h"
#include "GeoDataColorStyle.h"
#include "MarbleDebug.h"
#include "OsmPlacemarkData.h"
#include <qmath.h>
#include <QPainterPathStroker>
namespace Marble
{
-const GeoDataStyle *GeoLineStringGraphicsItem::s_previousStyle = 0;
+const GeoDataStyle *GeoLineStringGraphicsItem::s_previousStyle = nullptr;
bool GeoLineStringGraphicsItem::s_paintInline = true;
bool GeoLineStringGraphicsItem::s_paintOutline = true;
GeoLineStringGraphicsItem::GeoLineStringGraphicsItem(const GeoDataPlacemark *placemark,
const GeoDataLineString *lineString) :
GeoGraphicsItem(placemark),
m_lineString(lineString),
m_renderLineString(lineString),
m_renderLabel(false),
m_penWidth(0.0),
m_name(placemark->name())
{
QString const category = StyleBuilder::visualCategoryName(placemark->visualCategory());
QStringList paintLayers;
paintLayers << QLatin1String("LineString/") + category + QLatin1String("/outline");
paintLayers << QLatin1String("LineString/") + category + QLatin1String("/inline");
if (!m_name.isEmpty()) {
paintLayers << QLatin1String("LineString/") + category + QLatin1String("/label");
}
setPaintLayers(paintLayers);
}
GeoLineStringGraphicsItem::~GeoLineStringGraphicsItem()
{
qDeleteAll(m_cachedPolygons);
}
void GeoLineStringGraphicsItem::setLineString( const GeoDataLineString* lineString )
{
m_lineString = lineString;
m_renderLineString = lineString;
}
const GeoDataLineString *GeoLineStringGraphicsItem::lineString() const
{
return m_lineString;
}
GeoDataLineString GeoLineStringGraphicsItem::merge(const QVector<const GeoDataLineString *> &lineStrings_)
{
if (lineStrings_.isEmpty()) {
return GeoDataLineString();
}
Q_ASSERT(!lineStrings_.isEmpty());
auto lineStrings = lineStrings_;
GeoDataLineString result = *lineStrings.first();
lineStrings.pop_front();
for (bool matched = true; matched && !lineStrings.isEmpty();) {
matched = false;
for (auto lineString: lineStrings) {
if (canMerge(result.first(), lineString->first())) {
result.remove(0);
result.reverse();
result << *lineString;
lineStrings.removeOne(lineString);
matched = true;
break;
} else if (canMerge(result.last(), lineString->first())) {
result.remove(result.size()-1);
result << *lineString;
lineStrings.removeOne(lineString);
matched = true;
break;
} else if (canMerge(result.first(), lineString->last())) {
GeoDataLineString behind = result;
result = *lineString;
behind.remove(0);
result << behind;
lineStrings.removeOne(lineString);
matched = true;
break;
} else if (canMerge(result.last(), lineString->last())) {
GeoDataLineString behind = *lineString;
behind.reverse();
behind.remove(0);
result << behind;
lineStrings.removeOne(lineString);
matched = true;
break;
}
}
if (!matched) {
return GeoDataLineString();
}
}
return lineStrings.isEmpty() ? result : GeoDataLineString();
}
void GeoLineStringGraphicsItem::setMergedLineString(const GeoDataLineString &mergedLineString)
{
m_mergedLineString = mergedLineString;
m_renderLineString = mergedLineString.isEmpty() ? m_lineString : &m_mergedLineString;
}
const GeoDataLatLonAltBox& GeoLineStringGraphicsItem::latLonAltBox() const
{
return m_renderLineString->latLonAltBox();
}
void GeoLineStringGraphicsItem::paint(GeoPainter* painter, const ViewportParams* viewport , const QString &layer, int tileLevel)
{
setRenderContext(RenderContext(tileLevel));
if (layer.endsWith(QLatin1String("/outline"))) {
qDeleteAll(m_cachedPolygons);
m_cachedPolygons.clear();
m_cachedRegion = QRegion();
painter->polygonsFromLineString(*m_renderLineString, m_cachedPolygons);
if (m_cachedPolygons.empty()) {
return;
}
if (painter->mapQuality() == HighQuality || painter->mapQuality() == PrintQuality) {
paintOutline(painter, viewport);
}
} else if (layer.endsWith(QLatin1String("/inline"))) {
if (m_cachedPolygons.empty()) {
return;
}
paintInline(painter, viewport);
} else if (layer.endsWith(QLatin1String("/label"))) {
if (!m_cachedPolygons.empty()) {
if (m_renderLabel) {
paintLabel(painter, viewport);
}
}
} else {
qDeleteAll(m_cachedPolygons);
m_cachedPolygons.clear();
m_cachedRegion = QRegion();
painter->polygonsFromLineString(*m_renderLineString, m_cachedPolygons);
if (m_cachedPolygons.empty()) {
return;
}
for(const QPolygonF* itPolygon: m_cachedPolygons) {
painter->drawPolyline(*itPolygon);
}
}
}
bool GeoLineStringGraphicsItem::contains(const QPoint &screenPosition, const ViewportParams *) const
{
if (m_penWidth <= 0.0) {
return false;
}
if (m_cachedRegion.isNull()) {
QPainterPath painterPath;
for (auto polygon: m_cachedPolygons) {
painterPath.addPolygon(*polygon);
}
QPainterPathStroker stroker;
qreal const margin = 6.0;
stroker.setWidth(m_penWidth + margin);
QPainterPath strokePath = stroker.createStroke(painterPath);
m_cachedRegion = QRegion(strokePath.toFillPolygon().toPolygon(), Qt::WindingFill);
}
return m_cachedRegion.contains(screenPosition);
}
void GeoLineStringGraphicsItem::handleRelationUpdate(const QVector<const GeoDataRelation *> &relations)
{
QHash<GeoDataRelation::RelationType, QStringList> names;
for (auto relation: relations) {
auto const ref = relation->osmData().tagValue(QStringLiteral("ref"));
if (relation->isVisible() && !ref.isEmpty()) {
names[relation->relationType()] << ref;
}
}
if (names.isEmpty()) {
m_name = feature()->name();
} else {
QStringList namesList;
for (auto iter = names.begin(); iter != names.end(); ++iter) {
QString value;
switch (iter.key()) {
case GeoDataRelation::UnknownType:
case GeoDataRelation::RouteRoad: break;
case GeoDataRelation::RouteDetour: value = tr("Detour"); break;
case GeoDataRelation::RouteFerry: value = tr("Ferry Route"); break;
case GeoDataRelation::RouteTrain: value = tr("Train"); break;
case GeoDataRelation::RouteSubway: value = tr("Subway"); break;
case GeoDataRelation::RouteTram: value = tr("Tram"); break;
case GeoDataRelation::RouteBus: value = tr("Bus"); break;
case GeoDataRelation::RouteTrolleyBus: value = tr("Trolley Bus"); break;
case GeoDataRelation::RouteBicycle: value = tr("Bicycle Route"); break;
case GeoDataRelation::RouteMountainbike: value = tr("Mountainbike Route"); break;
case GeoDataRelation::RouteFoot: value = tr("Walking Route"); break;
case GeoDataRelation::RouteHiking: value = tr("Hiking Route"); break;
case GeoDataRelation::RouteHorse: value = tr("Bridleway"); break;
case GeoDataRelation::RouteInlineSkates: value = tr("Inline Skates Route"); break;
case GeoDataRelation::RouteSkiDownhill: value = tr("Downhill Piste"); break;
case GeoDataRelation::RouteSkiNordic: value = tr("Nordic Ski Trail"); break;
case GeoDataRelation::RouteSkitour: value = tr("Skitour"); break;
case GeoDataRelation::RouteSled: value = tr("Sled Trail"); break;
}
QStringList &references = iter.value();
std::sort(references.begin(), references.end());
auto const last = std::unique(references.begin(), references.end());
references.erase(last, references.end());
auto const routes = references.join(", ");
namesList << (value.isEmpty() ? routes : QStringLiteral("%1 %2").arg(value, routes));
}
auto const allRoutes = namesList.join(QStringLiteral("; "));
if (feature()->name().isEmpty()) {
m_name = allRoutes;
} else {
m_name = QStringLiteral("%1 (%2)").arg(feature()->name(), allRoutes);
}
}
}
void GeoLineStringGraphicsItem::paintInline(GeoPainter* painter, const ViewportParams* viewport)
{
if ( ( !viewport->resolves( m_renderLineString->latLonAltBox(), 2) ) ) {
return;
}
if (s_previousStyle != style().data()) {
s_paintInline = configurePainterForLine(painter, viewport, false);
}
s_previousStyle = style().data();
if (s_paintInline) {
m_renderLabel = painter->pen().widthF() >= 6.0f;
m_penWidth = painter->pen().widthF();
for(const QPolygonF* itPolygon: m_cachedPolygons) {
painter->drawPolyline(*itPolygon);
}
}
}
void GeoLineStringGraphicsItem::paintOutline(GeoPainter *painter, const ViewportParams *viewport) const
{
if ( ( !viewport->resolves( m_renderLineString->latLonAltBox(), 2) ) ) {
return;
}
if (s_previousStyle != style().data()) {
s_paintOutline = configurePainterForLine(painter, viewport, true);
}
s_previousStyle = style().data();
if (s_paintOutline) {
for(const QPolygonF* itPolygon: m_cachedPolygons) {
painter->drawPolyline(*itPolygon);
}
}
}
void GeoLineStringGraphicsItem::paintLabel(GeoPainter *painter, const ViewportParams *viewport) const
{
if ( ( !viewport->resolves( m_renderLineString->latLonAltBox(), 2) ) ) {
return;
}
LabelPositionFlags labelPositionFlags = NoLabel;
bool isValid = configurePainterForLabel(painter, viewport, labelPositionFlags);
if (isValid) {
GeoDataStyle::ConstPtr style = this->style();
// Activate the lines below to paint a label background which
// prevents antialiasing overpainting glitches, but leads to
// other glitches.
//QColor const color = style->polyStyle().paintedColor();
//painter->setBackground(QBrush(color));
//painter->setBackgroundMode(Qt::OpaqueMode);
const GeoDataLabelStyle& labelStyle = style->labelStyle();
painter->drawLabelsForPolygons(m_cachedPolygons, m_name, FollowLine,
labelStyle.paintedColor());
}
}
bool GeoLineStringGraphicsItem::configurePainterForLine(GeoPainter *painter, const ViewportParams *viewport, const bool isOutline) const
{
QPen currentPen = painter->pen();
GeoDataStyle::ConstPtr style = this->style();
if (!style) {
painter->setPen( QPen() );
painter->setBackground(QBrush(Qt::transparent));
painter->setBackgroundMode(Qt::TransparentMode);
}
else {
if (isOutline && !style->polyStyle().outline()) {
return false;
}
const GeoDataLineStyle& lineStyle = style->lineStyle();
// To save performance we avoid making changes to the painter's pen.
// So we first take a copy of the actual painter pen, make changes to it
// and only if the resulting pen is different from the actual pen
// we replace the painter's pen with our new pen.
// We want to avoid the mandatory detach in QPen::setColor(),
// so we carefully check whether applying the setter is needed
const QColor linePaintedColor = (!isOutline && (lineStyle.cosmeticOutline() && lineStyle.penStyle() == Qt::SolidLine))
? style->polyStyle().paintedColor()
: lineStyle.paintedColor();
if (currentPen.color() != linePaintedColor) {
if (linePaintedColor.alpha() == 255) {
currentPen.setColor(linePaintedColor);
}
else {
if ( painter->mapQuality() != Marble::HighQuality
&& painter->mapQuality() != Marble::PrintQuality ) {
QColor penColor = linePaintedColor;
if (penColor.alpha() != 0) {
penColor.setAlpha( 255 );
}
if (currentPen.color() != penColor) {
currentPen.setColor( penColor );
}
}
else {
currentPen.setColor(linePaintedColor);
}
}
}
const float lineWidth = lineStyle.width();
const float linePhysicalWidth = lineStyle.physicalWidth();
float newLineWidth = lineWidth;
if (linePhysicalWidth != 0.0) {
const float scaledLinePhysicalWidth = float(viewport->radius()) / EARTH_RADIUS * linePhysicalWidth;
newLineWidth = scaledLinePhysicalWidth > lineWidth
? scaledLinePhysicalWidth
: lineWidth;
}
if (!isOutline && lineStyle.cosmeticOutline() && lineStyle.penStyle() == Qt::SolidLine) {
if (newLineWidth > 2.5) {
newLineWidth -= 2.0;
}
}
const qreal lineDrawThreshold = isOutline ? 2.5 : 0.5;
// We want to avoid the mandatory detach in QPen::setWidthF(),
// so we carefully check whether applying the setter is needed
if (currentPen.widthF() != newLineWidth && newLineWidth != 0.0) {
if (newLineWidth < lineDrawThreshold) {
if (painter->pen().style() != Qt::NoPen) {
painter->setPen(Qt::NoPen);
}
return false; // Don't draw any outline and abort painter configuration early
}
currentPen.setWidthF(newLineWidth);
}
// No need to avoid detaches inside QPen::setCapsStyle() since Qt does that for us
const Qt::PenCapStyle lineCapStyle = lineStyle.capStyle();
currentPen.setCapStyle(lineCapStyle);
// No need to avoid detaches inside QPen::setStyle() since Qt does that for us
if (painter->mapQuality() == HighQuality || painter->mapQuality() == PrintQuality) {
const Qt::PenStyle linePenStyle = lineStyle.penStyle();
currentPen.setStyle(linePenStyle);
if (linePenStyle == Qt::CustomDashLine) {
// We want to avoid the mandatory detach in QPen::setDashPattern(),
// so we carefully check whether applying the setter is needed
if (currentPen.dashPattern() != lineStyle.dashPattern()) {
currentPen.setDashPattern(lineStyle.dashPattern());
}
}
} else {
currentPen.setStyle(Qt::SolidLine);
}
if ( painter->pen() != currentPen ) {
painter->setPen( currentPen );
}
// Set the background
if (!isOutline) {
if (lineStyle.background()) {
QBrush brush = painter->background();
brush.setColor(style->polyStyle().paintedColor());
painter->setBackground( brush );
painter->setBackgroundMode( Qt::OpaqueMode );
}
else {
painter->setBackground(QBrush(Qt::transparent));
painter->setBackgroundMode(Qt::TransparentMode);
}
}
else {
painter->setBackground(QBrush(Qt::transparent));
painter->setBackgroundMode(Qt::TransparentMode);
}
}
return true;
}
bool GeoLineStringGraphicsItem::configurePainterForLabel(GeoPainter *painter, const ViewportParams *viewport, LabelPositionFlags &labelPositionFlags) const
{
QPen currentPen = painter->pen();
GeoDataStyle::ConstPtr style = this->style();
if (!style) {
painter->setPen( QPen() );
}
else {
const GeoDataLineStyle& lineStyle = style->lineStyle();
// To save performance we avoid making changes to the painter's pen.
// So we first take a copy of the actual painter pen, make changes to it
// and only if the resulting pen is different from the actual pen
// we replace the painter's pen with our new pen.
// We want to avoid the mandatory detach in QPen::setColor(),
// so we carefully check whether applying the setter is needed
const float lineWidth = lineStyle.width();
const float linePhysicalWidth = lineStyle.physicalWidth();
float newLineWidth = lineWidth;
if (linePhysicalWidth != 0.0) {
const float scaledLinePhysicalWidth = float(viewport->radius()) / EARTH_RADIUS * linePhysicalWidth;
newLineWidth = scaledLinePhysicalWidth > lineWidth
? scaledLinePhysicalWidth
: lineWidth;
}
// We want to avoid the mandatory detach in QPen::setWidthF(),
// so we carefully check whether applying the setter is needed
if (currentPen.widthF() != newLineWidth && newLineWidth != 0.0) {
if (newLineWidth < 6.0) {
return false; // Don't draw any labels and abort painter configuration early
}
currentPen.setWidthF(newLineWidth);
}
if ( painter->pen() != currentPen ) {
painter->setPen( currentPen );
}
// else qDebug() << "Detach and painter change successfully Avoided!" << Q_FUNC_INFO;
if (painter->brush().color() != Qt::transparent) {
painter->setBrush(QColor(Qt::transparent));
}
if (painter->backgroundMode() == Qt::OpaqueMode) {
painter->setBackgroundMode(Qt::TransparentMode);
painter->setBackground(QBrush(Qt::transparent));
}
// label styles
const GeoDataLabelStyle& labelStyle = style->labelStyle();
painter->setFont(labelStyle.font() );
switch (labelStyle.alignment()) {
case GeoDataLabelStyle::Corner:
case GeoDataLabelStyle::Right:
labelPositionFlags |= LineStart;
break;
case GeoDataLabelStyle::Center:
labelPositionFlags |= LineCenter;
break;
}
}
return true;
}
bool GeoLineStringGraphicsItem::canMerge(const GeoDataCoordinates &a, const GeoDataCoordinates &b)
{
return a.sphericalDistanceTo(b) * EARTH_RADIUS < 0.1;
}
}
diff --git a/src/lib/marble/geodata/graphicsitem/GeoPhotoGraphicsItem.cpp b/src/lib/marble/geodata/graphicsitem/GeoPhotoGraphicsItem.cpp
index 41ede41d4..3bd198e8d 100644
--- a/src/lib/marble/geodata/graphicsitem/GeoPhotoGraphicsItem.cpp
+++ b/src/lib/marble/geodata/graphicsitem/GeoPhotoGraphicsItem.cpp
@@ -1,104 +1,104 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "GeoPhotoGraphicsItem.h"
#include "GeoPainter.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataFeature.h"
#include "StyleBuilder.h"
#include "ViewportParams.h"
#include <QDebug>
namespace Marble
{
GeoPhotoGraphicsItem::GeoPhotoGraphicsItem( const GeoDataFeature *feature )
: GeoGraphicsItem( feature )
{
if (feature) {
QString const paintLayer = QStringLiteral("Photo");
setPaintLayers(QStringList() << paintLayer);
}
}
void GeoPhotoGraphicsItem::paint(GeoPainter* painter, const ViewportParams* viewport , const QString &layer, int tileZoomLevel)
{
Q_UNUSED(layer);
Q_UNUSED(tileZoomLevel);
/* The code below loads the image lazily (only
* when it will actually be displayed). Once it was
* loaded but moves out of the viewport, it is unloaded
* again. Otherwise memory consumption gets quite high
* for a large set of photos
*/
bool unloadImage = true;
qreal x(0.0), y( 0.0 );
viewport->screenCoordinates( m_point.coordinates(), x, y );
QRectF position( QPointF( x, y ), style()->iconStyle().icon().size() );
position.moveCenter( QPointF( x, y ) );
QRectF displayed = position & QRectF( QPointF( 0, 0 ), viewport->size() );
if ( !displayed.isEmpty() ) {
if ( m_photo.isNull() ) {
m_photo = style()->iconStyle().icon();
}
unloadImage = false;
painter->drawImage( position, m_photo );
}
if ( unloadImage ) {
m_photo = QImage();
}
}
const GeoDataLatLonAltBox& GeoPhotoGraphicsItem::latLonAltBox() const
{
return m_point.latLonAltBox();
}
bool GeoPhotoGraphicsItem::contains(const QPoint &curpos, const ViewportParams *viewport) const
{
qreal x(0.0), y( 0.0 );
viewport->screenCoordinates(m_point.coordinates(), x, y);
auto itemStyle = style();
- if (itemStyle != 0 && !itemStyle->iconStyle().icon().isNull()) {
+ if (itemStyle != nullptr && !itemStyle->iconStyle().icon().isNull()) {
int halfIconWidth = itemStyle->iconStyle().icon().size().width() / 2;
int halfIconHeight = itemStyle->iconStyle().icon().size().height() / 2;
if ( x - halfIconWidth < curpos.x() &&
curpos.x() < x + halfIconWidth &&
y - halfIconHeight / 2 < curpos.y() &&
curpos.y() < y + halfIconHeight / 2 ) {
return true;
}
} else if ( curpos.x() == x && curpos.y() == y ) {
return true;
}
return false;
}
void GeoPhotoGraphicsItem::setPoint( const GeoDataPoint &point )
{
m_point = point;
}
GeoDataPoint GeoPhotoGraphicsItem::point() const
{
return m_point;
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlAvailableTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlAvailableTagHandler.cpp
index 7bc57bb1d..1d44e9e24 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlAvailableTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlAvailableTagHandler.cpp
@@ -1,53 +1,53 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlAvailableTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneProperty.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Available)
GeoNode* DgmlAvailableTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Available)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Property)) {
QString parsedText = parser.readElementText().toLower().trimmed();
parentItem.nodeAs<GeoSceneProperty>()->setAvailable(parsedText == dgmlValue_true || parsedText == dgmlValue_on);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlBlendingTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlBlendingTagHandler.cpp
index d8decddc3..dc34e7433 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlBlendingTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlBlendingTagHandler.cpp
@@ -1,51 +1,51 @@
// Copyright 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include "DgmlBlendingTagHandler.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
#include "MarbleDebug.h"
namespace Marble
{
namespace dgml
{
static GeoTagHandlerRegistrar registrar( GeoParser::QualifiedName( dgmlTag_Blending,
dgmlTag_nameSpace20 ),
new DgmlBlendingTagHandler );
GeoNode* DgmlBlendingTagHandler::parse( GeoParser& parser ) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Blending)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( !parentItem.represents( dgmlTag_Texture ) && !parentItem.represents( dgmlTag_Vectortile ))
- return 0;
+ return nullptr;
// Attribute name, default to ""
const QString name = parser.attribute( dgmlAttr_name ).trimmed();
mDebug() << "DgmlBlendingTagHandler::parse" << name;
parentItem.nodeAs<GeoSceneTileDataset>()->setBlending( name );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlBrushTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlBrushTagHandler.cpp
index d69acbcd3..da732c261 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlBrushTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlBrushTagHandler.cpp
@@ -1,85 +1,85 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlBrushTagHandler.h"
#include <QBrush>
#include <QColor>
#include <QList>
#include <QString>
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneGeodata.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Brush)
GeoNode* DgmlBrushTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Brush)));
QString color = parser.attribute(dgmlAttr_color).trimmed();
QString colorMap = parser.attribute(dgmlAttr_colorMap).trimmed();
qreal alpha = parser.attribute(dgmlAttr_alpha).isEmpty() ? 1.0 : parser.attribute(dgmlAttr_alpha).toDouble();
QBrush brush;
if ( !color.isEmpty() && QColor( color ).isValid() ) {
QColor brushColor( color );
if (color.contains(QLatin1String("transparent"))) {
brushColor.setAlphaF( 0.0 );
}
else {
brushColor.setAlphaF( alpha );
}
brush.setColor( brushColor );
}
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( dgmlTag_Vector )
|| parentItem.represents( dgmlTag_Geodata ) ) {
GeoSceneGeodata *geodata = parentItem.nodeAs<GeoSceneGeodata>();
geodata->setBrush( brush );
if ( !colorMap.isEmpty() ) {
const QStringList colorString = colorMap.split(QLatin1Char(','));
QVector<QColor> colorList;
colorList.reserve(colorString.size());
for(const QString& colorName: colorString) {
colorList.append(QColor(colorName));
}
geodata->setColors( colorList );
}
geodata->setAlpha( alpha );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlDescriptionTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlDescriptionTagHandler.cpp
index ff74bbddf..6cfaf5a12 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlDescriptionTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlDescriptionTagHandler.cpp
@@ -1,48 +1,48 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlDescriptionTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Description)
GeoNode* DgmlDescriptionTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Description)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Head))
parentItem.nodeAs<GeoSceneHead>()->setDescription( parser.readElementText().trimmed() );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlDiscreteTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlDiscreteTagHandler.cpp
index 770be3664..0d732c12f 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlDiscreteTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlDiscreteTagHandler.cpp
@@ -1,51 +1,51 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlDiscreteTagHandler.h"
#include "DgmlElementDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneZoom.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Discrete)
GeoNode* DgmlDiscreteTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Discrete)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Zoom)) {
QString parsedText = parser.readElementText().toLower().trimmed();
parentItem.nodeAs<GeoSceneZoom>()->setDiscrete(parsedText == dgmlValue_true || parsedText == dgmlValue_on);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlDownloadPolicyTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlDownloadPolicyTagHandler.cpp
index f2c69d669..6edc6306e 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlDownloadPolicyTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlDownloadPolicyTagHandler.cpp
@@ -1,78 +1,78 @@
/*
Copyright 2009, 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DgmlDownloadPolicyTagHandler.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
namespace Marble
{
namespace dgml
{
static GeoTagHandlerRegistrar handler( GeoParser::QualifiedName( dgmlTag_DownloadPolicy,
dgmlTag_nameSpace20 ),
new DgmlDownloadPolicyTagHandler );
// Error handling:
// Here it is not possible to return an error code or throw an exception
// so in case of an error we just ignore the element.
GeoNode* DgmlDownloadPolicyTagHandler::parse( GeoParser& parser ) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_DownloadPolicy)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( !parentItem.represents( dgmlTag_Texture ) && !parentItem.represents( dgmlTag_Vectortile ) ) {
qCritical( "Parse error: parent element is not 'texture' or 'vectortile'" );
- return 0;
+ return nullptr;
}
// Attribute usage
DownloadUsage usage;
const QString usageStr = parser.attribute( dgmlAttr_usage ).trimmed();
if (usageStr == QLatin1String("Browse"))
usage = DownloadBrowse;
else if (usageStr == QLatin1String("Bulk"))
usage = DownloadBulk;
else {
qCritical( "Parse error: invalid attribute downloadPolicy/@usage" );
- return 0;
+ return nullptr;
}
// Attribute maximumConnections
const QString maximumConnectionsStr = parser.attribute( dgmlAttr_maximumConnections ).trimmed();
bool ok;
const int maximumConnections = maximumConnectionsStr.toInt( &ok );
if ( !ok ) {
qCritical( "Parse error: invalid attribute downloadPolicy/@maximumConnections" );
- return 0;
+ return nullptr;
}
parentItem.nodeAs<GeoSceneTileDataset>()->addDownloadPolicy( usage, maximumConnections );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlDownloadUrlTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlDownloadUrlTagHandler.cpp
index 408c4caca..9f39d2b64 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlDownloadUrlTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlDownloadUrlTagHandler.cpp
@@ -1,96 +1,96 @@
/*
Copyright (C) 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
// Own
#include "DgmlDownloadUrlTagHandler.h"
// Qt
#include <QUrl>
#include <QUrlQuery>
// Marble
#include "DgmlAttributeDictionary.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(DownloadUrl)
GeoNode* DgmlDownloadUrlTagHandler::parse( GeoParser& parser ) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_DownloadUrl)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( !parentItem.represents( dgmlTag_Texture ) && !parentItem.represents( dgmlTag_Vectortile ) )
- return 0;
+ return nullptr;
QUrl url;
// Attribute protocol, optional?
QString protocolStr = parser.attribute( dgmlAttr_protocol ).trimmed();
if ( !protocolStr.isEmpty() )
url.setScheme( protocolStr );
// Attribute user, optional
const QString userStr = parser.attribute( dgmlAttr_user ).trimmed();
if ( !userStr.isEmpty() )
url.setUserName( userStr );
// Attribute password, optional
const QString passwordStr = parser.attribute( dgmlAttr_password ).trimmed();
if ( !passwordStr.isEmpty() )
url.setPassword( passwordStr );
// Attribute host, mandatory
const QString hostStr = parser.attribute( dgmlAttr_host ).trimmed();
if ( !hostStr.isEmpty() )
url.setHost( hostStr );
// Attribute port, optional
const QString portStr = parser.attribute( dgmlAttr_port ).trimmed();
if ( !portStr.isEmpty() )
url.setPort( portStr.toInt() );
// Attribute path, mandatory
const QString pathStr = parser.attribute( dgmlAttr_path ).trimmed();
if ( !pathStr.isEmpty() )
url.setPath( pathStr );
// Attribute query, optional
const QString queryStr = parser.attribute( dgmlAttr_query ).trimmed();
if ( !queryStr.isEmpty() ) {
QUrlQuery query;
query.setQuery( queryStr.toLatin1() );
url.setQuery(query);
}
parentItem.nodeAs<GeoSceneTileDataset>()->addDownloadUrl( url );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlFilterTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlFilterTagHandler.cpp
index ab92306bb..344e56ce5 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlFilterTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlFilterTagHandler.cpp
@@ -1,68 +1,68 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2008 Torsten Rahn <tackat@kde.org>
Copyright (C) 2008 Henry de Valence <hdevalence@gmail.com>
This file is part of the KDE project
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
aint 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 "DgmlFilterTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneLayer.h"
#include "GeoSceneMap.h"
#include "GeoSceneFilter.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Filter)
GeoNode* DgmlFilterTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Filter)));
QString name = parser.attribute(dgmlAttr_name).trimmed();
QString type = parser.attribute(dgmlAttr_type).toLower().trimmed();
- GeoSceneFilter *filter = 0;
+ GeoSceneFilter *filter = nullptr;
// Checking for parent layer
GeoStackItem parentItem = parser.parentElement();
GeoStackItem grandParentItem = parser.parentElement(1);
if (parentItem.represents(dgmlTag_Layer) &&
grandParentItem.represents(dgmlTag_Map) ) {
filter = new GeoSceneFilter( name );
filter->setType( type );
parentItem.nodeAs<GeoSceneLayer>()->addFilter( filter );
grandParentItem.nodeAs<GeoSceneMap>()->addFilter( filter );
}
return filter;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlGeodataTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlGeodataTagHandler.cpp
index bee85a9d2..5f7355980 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlGeodataTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlGeodataTagHandler.cpp
@@ -1,80 +1,80 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "DgmlGeodataTagHandler.h"
#include <limits>
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneDocument.h"
#include "GeoSceneLayer.h"
#include "GeoSceneSettings.h"
#include "GeoSceneGeodata.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Geodata)
GeoNode* DgmlGeodataTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Geodata)));
const QString name = parser.attribute(dgmlAttr_name).trimmed();
const QString property = parser.attribute( dgmlAttr_property ).trimmed();
const QString colorize = parser.attribute( dgmlAttr_colorize ).trimmed();
const QString expireStr = parser.attribute(dgmlAttr_expire).trimmed();
int expire = std::numeric_limits<int>::max();
if ( !expireStr.isEmpty() )
expire = expireStr.toInt();
- GeoSceneGeodata *dataSource = 0;
+ GeoSceneGeodata *dataSource = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
// Check parent type and make sure that the dataSet type
// matches the backend of the parent layer
if (parentItem.represents(dgmlTag_Layer)
&& parentItem.nodeAs<GeoSceneLayer>()->backend() == dgmlValue_geodata) {
dataSource = new GeoSceneGeodata( name );
dataSource->setProperty( property );
dataSource->setColorize( colorize );
dataSource->setExpire( expire );
parentItem.nodeAs<GeoSceneLayer>()->addDataset( dataSource );
}
return dataSource;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlGroupTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlGroupTagHandler.cpp
index 075e4ecf3..c40c9d678 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlGroupTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlGroupTagHandler.cpp
@@ -1,59 +1,59 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlGroupTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneDocument.h"
#include "GeoSceneSettings.h"
#include "GeoSceneGroup.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Group)
GeoNode* DgmlGroupTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Group)));
QString name = parser.attribute(dgmlAttr_name);
- GeoSceneGroup* group = 0;
+ GeoSceneGroup* group = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Settings)) {
group = new GeoSceneGroup( name );
parentItem.nodeAs<GeoSceneSettings>()->addGroup( group );
}
return group;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlHeadTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlHeadTagHandler.cpp
index 7e04cacba..41eb04821 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlHeadTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlHeadTagHandler.cpp
@@ -1,50 +1,50 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlHeadTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Head)
GeoNode* DgmlHeadTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Head)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Document))
return parentItem.nodeAs<GeoSceneDocument>()->head();
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlHeadingTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlHeadingTagHandler.cpp
index 8a577e648..4f5a242b8 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlHeadingTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlHeadingTagHandler.cpp
@@ -1,49 +1,49 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2008 Torsten Rahn <tackat@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlHeadingTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneSection.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Heading)
GeoNode* DgmlHeadingTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Heading)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Section))
parentItem.nodeAs<GeoSceneSection>()->setHeading(parser.readElementText().trimmed());
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp
index 2b9212524..d0c49ec7f 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlIconTagHandler.cpp
@@ -1,73 +1,73 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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.
*/
// Own
#include "DgmlIconTagHandler.h"
// Qt
#include <QColor>
// Marble
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
#include "GeoSceneIcon.h"
#include "GeoSceneItem.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Icon)
GeoNode* DgmlIconTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Icon)));
QString pixmapRelativePath = parser.attribute(dgmlAttr_pixmap).trimmed();
QColor color;
if (pixmapRelativePath.isEmpty()) {
color.setNamedColor(parser.attribute(dgmlAttr_color).trimmed());
}
- GeoSceneIcon *icon = 0;
+ GeoSceneIcon *icon = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Head)) {
icon = parentItem.nodeAs<GeoSceneHead>()->icon();
icon->setPixmap( pixmapRelativePath );
icon->setColor( color );
}
if (parentItem.represents(dgmlTag_Item)) {
icon = parentItem.nodeAs<GeoSceneItem>()->icon();
icon->setPixmap( pixmapRelativePath );
icon->setColor( color );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlInstallMapTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlInstallMapTagHandler.cpp
index 737214e5a..a8156c8a0 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlInstallMapTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlInstallMapTagHandler.cpp
@@ -1,48 +1,48 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlInstallMapTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(InstallMap)
GeoNode* DgmlInstallMapTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_InstallMap)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Texture) || parentItem.represents(dgmlTag_Vectortile))
parentItem.nodeAs<GeoSceneTileDataset>()->setInstallMap( parser.readElementText().trimmed() );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlItemTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlItemTagHandler.cpp
index 5a55955b3..f3dff325d 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlItemTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlItemTagHandler.cpp
@@ -1,65 +1,65 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlItemTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneSection.h"
#include "GeoSceneItem.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Item)
GeoNode* DgmlItemTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Item)));
QString name = parser.attribute(dgmlAttr_name).trimmed();
QString checkable = parser.attribute(dgmlAttr_checkable).toLower().trimmed();
QString connectTo = parser.attribute(dgmlAttr_connect).trimmed();
int spacing = parser.attribute(dgmlAttr_spacing).toInt();
- GeoSceneItem *item = 0;
+ GeoSceneItem *item = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Section)) {
item = new GeoSceneItem( name );
item->setCheckable( checkable == dgmlValue_true || checkable == dgmlValue_on );
item->setConnectTo( connectTo );
item->setSpacing( spacing );
parentItem.nodeAs<GeoSceneSection>()->addItem( item );
}
return item;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlLayerTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlLayerTagHandler.cpp
index a17d32ec5..b4c2af792 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlLayerTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlLayerTagHandler.cpp
@@ -1,64 +1,64 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2008 Torsten Rahn <tackat@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlLayerTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneMap.h"
#include "GeoSceneLayer.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Layer)
GeoNode* DgmlLayerTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Layer)));
QString name = parser.attribute(dgmlAttr_name).trimmed();
QString backend = parser.attribute(dgmlAttr_backend).toLower().trimmed();
QString role = parser.attribute(dgmlAttr_role).toLower().trimmed();
- GeoSceneLayer *layer = 0;
+ GeoSceneLayer *layer = nullptr;
// Checking for parent layer
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Map)) {
layer = new GeoSceneLayer( name );
layer->setBackend( backend );
layer->setRole( role );
parentItem.nodeAs<GeoSceneMap>()->addLayer( layer );
}
return layer;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlLegendTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlLegendTagHandler.cpp
index 88ae1002b..4d742fd26 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlLegendTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlLegendTagHandler.cpp
@@ -1,51 +1,51 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2008 Torsten Rahn <tackat@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlLegendTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneDocument.h"
#include "GeoSceneLegend.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Legend)
GeoNode* DgmlLegendTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Legend)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Document))
return parentItem.nodeAs<GeoSceneDocument>()->legend();
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlLicenseTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlLicenseTagHandler.cpp
index 6ee50a36b..3b7bf8b66 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlLicenseTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlLicenseTagHandler.cpp
@@ -1,56 +1,56 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright (C) 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "DgmlLicenseTagHandler.h"
#include "GeoSceneLicense.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
#include "MarbleDebug.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(License)
GeoNode* DgmlLicenseTagHandler::parse( GeoParser& parser ) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_License)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( dgmlTag_Head ) ) {
QString const attribution = parser.attribute(dgmlAttr_attribution).trimmed().toLower();
if (attribution == QLatin1String("never")) {
parentItem.nodeAs<GeoSceneHead>()->license()->setAttribution( GeoSceneLicense::Never );
} else if (attribution == QLatin1String("opt-in") || attribution == QLatin1String("optin")) {
parentItem.nodeAs<GeoSceneHead>()->license()->setAttribution( GeoSceneLicense::OptIn );
} else if (attribution.isEmpty() || attribution == QLatin1String("opt-out") || attribution == QLatin1String("optout")) {
parentItem.nodeAs<GeoSceneHead>()->license()->setAttribution( GeoSceneLicense::OptOut );
} else if (attribution == QLatin1String("always")) {
parentItem.nodeAs<GeoSceneHead>()->license()->setAttribution( GeoSceneLicense::Always );
} else {
mDebug() << "Unknown license attribution value " << attribution << ", falling back to 'opt-out'.";
parentItem.nodeAs<GeoSceneHead>()->license()->setAttribution( GeoSceneLicense::OptOut );
}
QString const shortLicense = parser.attribute( dgmlAttr_short ).trimmed();
parentItem.nodeAs<GeoSceneHead>()->license()->setShortLicense( shortLicense );
QString const fullLicense = parser.readElementText().trimmed();
parentItem.nodeAs<GeoSceneHead>()->license()->setLicense( fullLicense );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlMapTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlMapTagHandler.cpp
index 2e4d87480..c023d1995 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlMapTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlMapTagHandler.cpp
@@ -1,67 +1,67 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2008 Torsten Rahn <tackat@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlMapTagHandler.h"
#include <QColor>
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneDocument.h"
#include "GeoSceneMap.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Map)
GeoNode* DgmlMapTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Map)));
QColor labelColor = parser.attribute(dgmlAttr_labelColor).trimmed();
if ( !labelColor.isValid() )
labelColor = Qt::black;
QColor highlightBrushColor = QColor ( parser.attribute(dgmlAttr_highlightBrush).trimmed() );
QColor highlightPenColor = QColor ( parser.attribute(dgmlAttr_highlightPen).trimmed() );
- GeoSceneMap* map = 0;
+ GeoSceneMap* map = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Document)) {
map = parentItem.nodeAs<GeoSceneDocument>()->map();
map->setBackgroundColor( QColor( parser.attribute( dgmlAttr_bgcolor ).trimmed() ) );
map->setLabelColor( labelColor );
map->setHighlightBrushColor( highlightBrushColor );
map->setHighlightPenColor( highlightPenColor );
}
return map;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlMaximumTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlMaximumTagHandler.cpp
index aae3490f1..9c367c84c 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlMaximumTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlMaximumTagHandler.cpp
@@ -1,57 +1,57 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlMaximumTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneZoom.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Maximum)
GeoNode* DgmlMaximumTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Maximum)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Zoom)) {
QString parsedText = parser.readElementText();
bool ok = false;
int parsedInt = parsedText.toInt(&ok);
if (ok)
parentItem.nodeAs<GeoSceneZoom>()->setMaximum(parsedInt);
else
parser.raiseWarning(QObject::tr("Could not convert <maximum> child text content to integer. Was: '%1'").arg(parsedText));
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlMinimumTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlMinimumTagHandler.cpp
index 274a2bfae..41b89c0d5 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlMinimumTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlMinimumTagHandler.cpp
@@ -1,58 +1,58 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlMinimumTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneZoom.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Minimum)
GeoNode* DgmlMinimumTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Minimum)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Zoom)) {
QString parsedText = parser.readElementText();
bool ok = false;
int parsedInt = parsedText.toInt(&ok);
if (ok)
parentItem.nodeAs<GeoSceneZoom>()->setMinimum(parsedInt);
else
parser.raiseWarning(QObject::tr("Could not convert <minimum> child text content to integer. Was: '%1'").arg(parsedText));
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlNameTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlNameTagHandler.cpp
index 945ae7683..da9c391a3 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlNameTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlNameTagHandler.cpp
@@ -1,48 +1,48 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlNameTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Name)
GeoNode* DgmlNameTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Name)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Head))
parentItem.nodeAs<GeoSceneHead>()->setName( parser.readElementText().trimmed() );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlPaletteTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlPaletteTagHandler.cpp
index 33103afb8..70104e568 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlPaletteTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlPaletteTagHandler.cpp
@@ -1,62 +1,62 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2008 Torsten Rahn <tackat@kde.org>
Copyright (C) 2008 Henry de Valence <hdevalence@gmail.com>
This file is part of the KDE project
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
aint 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 "DgmlPaletteTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneFilter.h"
#include "GeoScenePalette.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Palette)
GeoNode* DgmlPaletteTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Palette)));
QString type = parser.attribute(dgmlAttr_type).toLower().trimmed();
QString file = parser.readElementText().trimmed();
- GeoScenePalette *palette = 0;
+ GeoScenePalette *palette = nullptr;
// Checking for parent palette
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Filter)) {
palette = new GeoScenePalette( type, file );
parentItem.nodeAs<GeoSceneFilter>()->addPalette( palette );
}
return palette;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlPenTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlPenTagHandler.cpp
index b8027f188..989238d78 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlPenTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlPenTagHandler.cpp
@@ -1,87 +1,87 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlPenTagHandler.h"
#include <QPen>
#include <QColor>
#include <QString>
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneGeodata.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Pen)
GeoNode* DgmlPenTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Pen)));
QString color = parser.attribute(dgmlAttr_color).trimmed();
QString style = parser.attribute(dgmlAttr_style).toLower().trimmed();
QString widthString = parser.attribute(dgmlAttr_width);
qreal width = widthString.isEmpty() ? 1.0 : widthString.toDouble();
QPen pen;
if ( !color.isEmpty() && QColor( color ).isValid() ) {
pen.setColor( QColor( color ) );
}
if ( !style.isEmpty() ) {
if (style == QLatin1String("nopen")) {
pen.setStyle(Qt::NoPen);
} else if (style == QLatin1String("solidline")) {
pen.setStyle(Qt::SolidLine);
} else if (style == QLatin1String("dashline")) {
pen.setStyle(Qt::DashLine);
} else if (style == QLatin1String("dotline")) {
pen.setStyle(Qt::DotLine);
} else if (style == QLatin1String("dashdotline")) {
pen.setStyle(Qt::DashDotLine);
} else if (style == QLatin1String("dashdotdotline")) {
pen.setStyle(Qt::DashDotDotLine);
}
}
if ( width != 0.0 ) {
pen.setWidthF( width );
}
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( dgmlTag_Vector )
|| parentItem.represents( dgmlTag_Geodata ) ) {
GeoSceneGeodata *geodata = parentItem.nodeAs<GeoSceneGeodata>();
geodata->setPen( pen );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlProjectionTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlProjectionTagHandler.cpp
index e38bd7d20..27dc3dbbe 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlProjectionTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlProjectionTagHandler.cpp
@@ -1,65 +1,65 @@
/*
Copyright (C) 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
// Own
#include "DgmlProjectionTagHandler.h"
// Marble
#include "DgmlAttributeDictionary.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Projection)
GeoNode* DgmlProjectionTagHandler::parse( GeoParser& parser ) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Projection)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( !parentItem.represents( dgmlTag_Texture ) && !parentItem.represents( dgmlTag_Vectortile))
- return 0;
+ return nullptr;
// Attribute name, default to "Equirectangular"
const QString nameStr = parser.attribute( dgmlAttr_name ).trimmed();
if ( !nameStr.isEmpty() ) {
GeoSceneAbstractTileProjection::Type tileProjectionType = GeoSceneAbstractTileProjection::Equirectangular;
if (nameStr == QLatin1String("Equirectangular")) {
tileProjectionType = GeoSceneAbstractTileProjection::Equirectangular;
} else if (nameStr == QLatin1String("Mercator")) {
tileProjectionType = GeoSceneAbstractTileProjection::Mercator;
} else {
parser.raiseWarning( QString( "Value not allowed for attribute name: %1" ).arg( nameStr ));
}
parentItem.nodeAs<GeoSceneTileDataset>()->setTileProjection(tileProjectionType);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlPropertyTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlPropertyTagHandler.cpp
index b67b93d10..2490bbc09 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlPropertyTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlPropertyTagHandler.cpp
@@ -1,63 +1,63 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlPropertyTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneSettings.h"
#include "GeoSceneGroup.h"
#include "GeoSceneProperty.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Property)
GeoNode* DgmlPropertyTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Property)));
QString name = parser.attribute(dgmlAttr_name).trimmed();
- GeoSceneProperty* property = 0;
+ GeoSceneProperty* property = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Settings)) {
property = new GeoSceneProperty( name );
parentItem.nodeAs<GeoSceneSettings>()->addProperty( property );
}
if (parentItem.represents(dgmlTag_Group)) {
property = new GeoSceneProperty( name );
parentItem.nodeAs<GeoSceneGroup>()->addProperty( property);
}
return property;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlRenderOrderTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlRenderOrderTagHandler.cpp
index 75b00a614..9cc187384 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlRenderOrderTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlRenderOrderTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2016 Sanjiban Bairagya <sanjibanb@kde.org>
//
#include "DgmlRenderOrderTagHandler.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneGeodata.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(RenderOrder)
GeoNode* DgmlRenderOrderTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_RenderOrder)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( dgmlTag_Vector )
|| parentItem.represents( dgmlTag_Geodata ) ) {
- GeoSceneGeodata *dataSource = 0;
+ GeoSceneGeodata *dataSource = nullptr;
dataSource = parentItem.nodeAs<GeoSceneGeodata>();
dataSource->setRenderOrder( parser.readElementText().trimmed().toInt() );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlSectionTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlSectionTagHandler.cpp
index 32bda7f5b..f393675b2 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlSectionTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlSectionTagHandler.cpp
@@ -1,68 +1,68 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright (C) 2008 Torsten Rahn <tackat@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlSectionTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneLegend.h"
#include "GeoSceneSection.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Section)
GeoNode* DgmlSectionTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Section)));
QString name = parser.attribute(dgmlAttr_name);
QString checkable = parser.attribute(dgmlAttr_checkable).toLower().trimmed();
QString connectTo = parser.attribute(dgmlAttr_connect).trimmed();
QString radio = parser.attribute(dgmlAttr_radio);
int spacing = parser.attribute(dgmlAttr_spacing).toInt();
- GeoSceneSection* section = 0;
+ GeoSceneSection* section = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Legend)) {
section = new GeoSceneSection( name );
section->setCheckable( checkable == dgmlValue_true || checkable == dgmlValue_on );
section->setConnectTo( connectTo );
section->setSpacing( spacing );
section->setRadio( radio );
parentItem.nodeAs<GeoSceneLegend>()->addSection( section );
}
return section;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlSettingsTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlSettingsTagHandler.cpp
index f99d9c28c..0963e8c07 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlSettingsTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlSettingsTagHandler.cpp
@@ -1,50 +1,50 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlSettingsTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneDocument.h"
#include "GeoSceneSettings.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Settings)
GeoNode* DgmlSettingsTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Settings)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Document))
return parentItem.nodeAs<GeoSceneDocument>()->settings();
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlSourceDirTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlSourceDirTagHandler.cpp
index fbf06fc9c..e2119230f 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlSourceDirTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlSourceDirTagHandler.cpp
@@ -1,54 +1,54 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlSourceDirTagHandler.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(SourceDir)
GeoNode* DgmlSourceDirTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_SourceDir)));
QString format = parser.attribute(dgmlAttr_format).trimmed();
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Texture) || parentItem.represents(dgmlTag_Vectortile) ) {
GeoSceneTileDataset *texture = parentItem.nodeAs<GeoSceneTileDataset>();
texture->setSourceDir( parser.readElementText().trimmed() );
texture->setFileFormat(format);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlSourceFileTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlSourceFileTagHandler.cpp
index cfd5636b0..4f499042c 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlSourceFileTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlSourceFileTagHandler.cpp
@@ -1,53 +1,53 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlSourceFileTagHandler.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneGeodata.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(SourceFile)
GeoNode* DgmlSourceFileTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_SourceFile)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( dgmlTag_Vector )
|| parentItem.represents( dgmlTag_Geodata ) ) {
- GeoSceneGeodata *dataSource = 0;
+ GeoSceneGeodata *dataSource = nullptr;
dataSource = parentItem.nodeAs<GeoSceneGeodata>();
dataSource->setSourceFile( parser.readElementText().trimmed() );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlStorageLayoutTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlStorageLayoutTagHandler.cpp
index bc1f21841..11bdb3f5d 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlStorageLayoutTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlStorageLayoutTagHandler.cpp
@@ -1,117 +1,117 @@
/*
Copyright (C) 2008 Jens-Michael Hoffmann <jensmh@gmx.de>
This file is part of the KDE project
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
aint 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 "DgmlStorageLayoutTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
#include "ServerLayout.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(StorageLayout)
GeoNode* DgmlStorageLayoutTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_StorageLayout)));
// Attribute levelZeroColumns, default to value of the oldest tile themes
int levelZeroColumns = 2;
const QString levelZeroColumnsStr = parser.attribute(dgmlAttr_levelZeroColumns).trimmed();
if ( !levelZeroColumnsStr.isEmpty() ) {
levelZeroColumns = levelZeroColumnsStr.toInt();
}
// Attribute levelZeroRows, default to value of the oldest tile themes
int levelZeroRows = 1;
const QString levelZeroRowsStr = parser.attribute(dgmlAttr_levelZeroRows).trimmed();
if ( !levelZeroRowsStr.isEmpty() ) {
levelZeroRows = levelZeroRowsStr.toInt();
}
// Attribute minimumTileLevel
int minimumTileLevel = 0;
const QString minimumTileLevelStr = parser.attribute( dgmlAttr_minimumTileLevel ).trimmed();
if ( !minimumTileLevelStr.isEmpty() ) {
minimumTileLevel = minimumTileLevelStr.toInt();
}
// Attribute maximumTileLevel
int maximumTileLevel = -1;
const QString maximumTileLevelStr = parser.attribute( dgmlAttr_maximumTileLevel ).trimmed();
if ( !maximumTileLevelStr.isEmpty() ) {
maximumTileLevel = maximumTileLevelStr.toInt();
}
// Attribute maximumTileLevel
const QString tileLevels = parser.attribute( dgmlAttr_tileLevels ).trimmed();
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Texture) || parentItem.represents(dgmlTag_Vectortile)) {
GeoSceneTileDataset *texture = parentItem.nodeAs<GeoSceneTileDataset>();
// Attribute mode
GeoSceneTileDataset::StorageLayout storageLayout = GeoSceneTileDataset::OpenStreetMap;
- ServerLayout *serverLayout = 0;
+ ServerLayout *serverLayout = nullptr;
const QString modeStr = parser.attribute(dgmlAttr_mode).trimmed();
if (modeStr == QLatin1String("OpenStreetMap"))
serverLayout = new OsmServerLayout( texture );
else if (modeStr == QLatin1String("Custom"))
serverLayout = new CustomServerLayout( texture );
else if (modeStr == QLatin1String("WebMapService"))
serverLayout = new WmsServerLayout( texture );
else if (modeStr == QLatin1String("QuadTree"))
serverLayout = new QuadTreeServerLayout( texture );
else if (modeStr == QLatin1String("TileMapService"))
{
storageLayout = GeoSceneTileDataset::TileMapService;
serverLayout = new TmsServerLayout( texture );
} else {
storageLayout = GeoSceneTileDataset::Marble;
serverLayout = new MarbleServerLayout( texture );
if ( !modeStr.isEmpty() ) {
mDebug() << "Unknown storage layout mode " << modeStr << ", falling back to default.";
}
}
texture->setLevelZeroColumns( levelZeroColumns );
texture->setLevelZeroRows( levelZeroRows );
texture->setMinimumTileLevel( minimumTileLevel );
texture->setMaximumTileLevel( maximumTileLevel );
texture->setTileLevels( tileLevels );
texture->setStorageLayout( storageLayout );
texture->setServerLayout( serverLayout );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlTargetTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlTargetTagHandler.cpp
index eaee478f7..119ad0db7 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlTargetTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlTargetTagHandler.cpp
@@ -1,62 +1,62 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlTargetTagHandler.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
#include "GeoSceneLayer.h"
#include "GeoSceneMap.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Target)
GeoNode* DgmlTargetTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Target)));
QString const targetRadius = parser.attribute( dgmlAttr_radius ).trimmed();
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Head)) {
parentItem.nodeAs<GeoSceneHead>()->setTarget( parser.readElementText().trimmed() );
if ( !targetRadius.isEmpty() ) {
parentItem.nodeAs<GeoSceneHead>()->setRadius( targetRadius.toDouble() );
}
}
if (parentItem.represents(dgmlTag_Map)) {
/* GeoSceneLayer *layer = new GeoSceneLayer( "$MARBLETARGET$" );
parentItem.nodeAs<GeoSceneMap>()->addLayer( layer );*/
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlTextTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlTextTagHandler.cpp
index 89f286580..d343cbc38 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlTextTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlTextTagHandler.cpp
@@ -1,48 +1,48 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlTextTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneItem.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Text)
GeoNode* DgmlTextTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Text)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Item))
parentItem.nodeAs<GeoSceneItem>()->setText( parser.readElementText().trimmed() );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlTextureTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlTextureTagHandler.cpp
index 3da8c256b..023e3477e 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlTextureTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlTextureTagHandler.cpp
@@ -1,72 +1,72 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlTextureTagHandler.h"
#include <limits>
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneLayer.h"
#include "GeoSceneTextureTileDataset.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Texture)
GeoNode* DgmlTextureTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Texture)));
const QString name = parser.attribute(dgmlAttr_name).trimmed();
const QString expireStr = parser.attribute(dgmlAttr_expire).trimmed();
int expire = std::numeric_limits<int>::max();
if ( !expireStr.isEmpty() )
expire = expireStr.toInt();
- GeoSceneTileDataset *texture = 0;
+ GeoSceneTileDataset *texture = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
// Check parent type and make sure that the dataSet type
// matches the backend of the parent layer
if ( parentItem.represents(dgmlTag_Layer)
&& parentItem.nodeAs<GeoSceneLayer>()->backend() == dgmlValue_texture ) {
texture = new GeoSceneTextureTileDataset( name );
texture->setExpire( expire );
parentItem.nodeAs<GeoSceneLayer>()->addDataset( texture );
}
return texture;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlThemeTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlThemeTagHandler.cpp
index fd6d6f825..5b61c9f54 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlThemeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlThemeTagHandler.cpp
@@ -1,48 +1,48 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlThemeTagHandler.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Theme)
GeoNode* DgmlThemeTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Theme)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Head))
parentItem.nodeAs<GeoSceneHead>()->setTheme( parser.readElementText().trimmed() );
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlTileSizeTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlTileSizeTagHandler.cpp
index 532cc6e09..6fb0bad07 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlTileSizeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlTileSizeTagHandler.cpp
@@ -1,44 +1,44 @@
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "DgmlTileSizeTagHandler.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneTileDataset.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(TileSize)
GeoNode* DgmlTileSizeTagHandler::parse( GeoParser& parser ) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_TileSize)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( !parentItem.represents( dgmlTag_Texture ) && !parentItem.represents( dgmlTag_Vectortile ))
- return 0;
+ return nullptr;
int width = parser.attribute(dgmlAttr_width).toInt();
int height = parser.attribute(dgmlAttr_height).toInt();
QSize const size( width, height );
if ( !size.isEmpty() ) {
parentItem.nodeAs<GeoSceneTileDataset>()->setTileSize( size );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlValueTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlValueTagHandler.cpp
index c9e23fa7f..ad2c5b52e 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlValueTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlValueTagHandler.cpp
@@ -1,53 +1,53 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlValueTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneProperty.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Value)
GeoNode* DgmlValueTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Value)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Property)) {
QString parsedText = parser.readElementText().toLower().trimmed();
parentItem.nodeAs<GeoSceneProperty>()->setDefaultValue(parsedText == dgmlValue_true || parsedText == dgmlValue_on);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlVectorTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlVectorTagHandler.cpp
index 4937886c2..c27928027 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlVectorTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlVectorTagHandler.cpp
@@ -1,67 +1,67 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlVectorTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneLayer.h"
#include "GeoSceneGeodata.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Vector)
GeoNode* DgmlVectorTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Vector)));
QString name = parser.attribute(dgmlAttr_name).trimmed();
QString feature = parser.attribute(dgmlAttr_feature).trimmed();
- GeoSceneGeodata *vector = 0;
+ GeoSceneGeodata *vector = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
// Check parent type and make sure that the dataSet type
// matches the backend of the parent layer
if ( parentItem.represents(dgmlTag_Layer)
&& parentItem.nodeAs<GeoSceneLayer>()->backend() == dgmlValue_vector ) {
vector = new GeoSceneGeodata( name );
vector->setProperty( feature );
vector->setColorize( feature );
parentItem.nodeAs<GeoSceneLayer>()->addDataset( vector );
}
return vector;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlVectortileTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlVectortileTagHandler.cpp
index 15495b4d2..b3c0ca3cb 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlVectortileTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlVectortileTagHandler.cpp
@@ -1,64 +1,64 @@
/*
This file is part of the Marble Virtual Globe.
This program is free software licensed under the GNU LGPL. You can
find a copy of this license in LICENSE.txt in the top directory of
the source code.
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
Copyright 2012 Ander Pijoan <ander.pijoan@deusto.es>
*/
#include "DgmlVectortileTagHandler.h"
#include <limits>
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "DgmlAttributeDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneLayer.h"
#include "GeoSceneVectorTileDataset.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Vectortile)
GeoNode* DgmlVectortileTagHandler::parse( GeoParser& parser ) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Vectortile)));
const QString name = parser.attribute( dgmlAttr_name ).trimmed();
const QString expireStr = parser.attribute( dgmlAttr_expire ).trimmed();
int expire = std::numeric_limits<int>::max();
if ( !expireStr.isEmpty() )
expire = expireStr.toInt();
- GeoSceneTileDataset *texture = 0;
+ GeoSceneTileDataset *texture = nullptr;
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
// Check parent type and make sure that the dataSet type
// matches the backend of the parent layer
if ( parentItem.represents( dgmlTag_Layer )
&& parentItem.nodeAs<GeoSceneLayer>()->backend() == dgmlValue_vectortile ) {
texture = new GeoSceneVectorTileDataset( name );
texture->setExpire( expire );
parentItem.nodeAs<GeoSceneLayer>()->addDataset( texture );
}
return texture;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlVisibleTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlVisibleTagHandler.cpp
index 18c3b1e04..27e5c9ba7 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlVisibleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlVisibleTagHandler.cpp
@@ -1,51 +1,51 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlVisibleTagHandler.h"
#include "DgmlElementDictionary.h"
#include "DgmlAuxillaryDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Visible)
GeoNode* DgmlVisibleTagHandler::parse(GeoParser& parser) const
{
// Check whether the tag is valid
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Visible)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( dgmlTag_Head ) ) {
QString parsedText = parser.readElementText().toLower().trimmed();
parentItem.nodeAs<GeoSceneHead>()->setVisible(parsedText == dgmlValue_true || parsedText == dgmlValue_on);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlZoomTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlZoomTagHandler.cpp
index bc6fe32e1..ff018788d 100644
--- a/src/lib/marble/geodata/handlers/dgml/DgmlZoomTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/dgml/DgmlZoomTagHandler.cpp
@@ -1,50 +1,50 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "DgmlZoomTagHandler.h"
#include "MarbleDebug.h"
#include "DgmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoSceneHead.h"
#include "GeoSceneZoom.h"
namespace Marble
{
namespace dgml
{
DGML_DEFINE_TAG_HANDLER(Zoom)
GeoNode* DgmlZoomTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(dgmlTag_Zoom)));
// Checking for parent item
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(dgmlTag_Head))
return parentItem.nodeAs<GeoSceneHead>()->zoom();
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlAddressTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlAddressTagHandler.cpp
index 6290dc25b..e729b0a9b 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlAddressTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlAddressTagHandler.cpp
@@ -1,49 +1,49 @@
/*
Copyright (C) 2017 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
This file is part of the KDE project
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
aint 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 "KmlAddressTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER(address)
GeoNode *KmladdressTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_address)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.is<GeoDataFeature>()) {
const auto address = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataFeature>()->setAddress(address);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlAliasTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlAliasTagHandler.cpp
index 155bce4d9..1a0c6d52f 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlAliasTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlAliasTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlAliasTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataAlias.h"
#include "GeoDataResourceMap.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Alias )
GeoNode* KmlAliasTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Alias)));
GeoDataAlias alias;
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_ResourceMap ) ) {
parentItem.nodeAs<GeoDataResourceMap>()->setAlias(alias);
return &parentItem.nodeAs<GeoDataResourceMap>()->alias();
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlAltitudeModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlAltitudeModeTagHandler.cpp
index e768c6a27..3c4a54f53 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlAltitudeModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlAltitudeModeTagHandler.cpp
@@ -1,83 +1,83 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
Copyright (C) 2009 Bastian Holst <bastianholst@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlAltitudeModeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataGeometry.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataPoint.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTrack.h"
#include "GeoDataAbstractView.h"
#include "GeoDataModel.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( altitudeMode )
GeoNode* KmlaltitudeModeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_altitudeMode)));
QString content = parser.readElementText().trimmed();
AltitudeMode mode;
if (content == QLatin1String("relativeToGround")) {
mode = RelativeToGround;
} else if (content == QLatin1String("absolute")) {
mode = Absolute;
} else { // clampToGround is Standard
mode = ClampToGround;
}
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataPlacemark>() ) {
parentItem.nodeAs<GeoDataPlacemark>()->geometry()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataPoint>() ) {
parentItem.nodeAs<GeoDataPoint>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataLatLonAltBox>() ) {
parentItem.nodeAs<GeoDataLatLonAltBox>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataTrack>() ) {
parentItem.nodeAs<GeoDataTrack>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataGroundOverlay>() ) {
parentItem.nodeAs<GeoDataGroundOverlay>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataAbstractView>() ) {
parentItem.nodeAs<GeoDataAbstractView>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataModel>() ) {
parentItem.nodeAs<GeoDataModel>()->setAltitudeMode( mode );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlAltitudeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlAltitudeTagHandler.cpp
index a1e86f17e..77ac24e84 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlAltitudeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlAltitudeTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlAltitudeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "MarbleGlobal.h"
#include "GeoDataLookAt.h"
#include "GeoDataCamera.h"
#include "GeoDataGroundOverlay.h"
#include "GeoParser.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLocation.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( altitude )
GeoNode *KmlaltitudeTagHandler::parse(GeoParser & parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_altitude)));
GeoStackItem parentItem = parser.parentElement();
qreal const altitude = parser.readElementText().trimmed().toDouble();
if ( parentItem.is<GeoDataLookAt>() ){
parentItem.nodeAs<GeoDataLookAt>()->setAltitude( altitude );
} else if ( parentItem.is<GeoDataCamera>() ){
parentItem.nodeAs<GeoDataCamera>()->setAltitude( altitude );
} else if ( parentItem.is<GeoDataGroundOverlay>() ) {
parentItem.nodeAs<GeoDataGroundOverlay>()->setAltitude( altitude );
} else if ( parentItem.is<GeoDataLocation>() ) {
parentItem.nodeAs<GeoDataLocation>()->setAltitude( altitude );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlAnimatedUpdateTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlAnimatedUpdateTagHandler.cpp
index dc20a4317..7296fdb18 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlAnimatedUpdateTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlAnimatedUpdateTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
#include "KmlAnimatedUpdateTagHandler.h"
#include "GeoDataAnimatedUpdate.h"
#include "GeoDataPlaylist.h"
#include "GeoParser.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
namespace Marble
{
namespace kml
{
namespace gx
{
KML_DEFINE_TAG_HANDLER_GX22( AnimatedUpdate )
GeoNode* KmlAnimatedUpdateTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_AnimatedUpdate)));
GeoStackItem parentItem = parser.parentElement();
GeoDataAnimatedUpdate *animatedUpdate = new GeoDataAnimatedUpdate;
KmlObjectTagHandler::parseIdentifiers( parser, animatedUpdate );
if (parentItem.is<GeoDataPlaylist>()) {
parentItem.nodeAs<GeoDataPlaylist>()->addPrimitive( animatedUpdate );
return animatedUpdate;
} else {
delete animatedUpdate;
}
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlAreaTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlAreaTagHandler.cpp
index d340919b0..07e40cb19 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlAreaTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlAreaTagHandler.cpp
@@ -1,57 +1,57 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
#if KML_LAZY_IMP
#include "KmlAreaTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPlacemark.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( area )
GeoNode* KmlareaTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_area)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataPlacemark>() ) {
QString area = parser.readElementText().trimmed();
qreal ar = area.toDouble();
if( ar < 0.0 ) ar = 0.0;
parentItem.nodeAs<GeoDataPlacemark>()->setArea( ar );
}
- return 0;
+ return nullptr;
}
}
}
#endif //KML_LAZY_IMP
diff --git a/src/lib/marble/geodata/handlers/kml/KmlBalloonStyleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlBalloonStyleTagHandler.cpp
index 88661429a..5cb68e2fa 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlBalloonStyleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlBalloonStyleTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlBalloonStyleTagHandler.h"
#include "MarbleDebug.h"
#include "GeoDataBalloonStyle.h"
#include "GeoDataStyle.h"
#include "GeoDataParser.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( BalloonStyle )
GeoNode* KmlBalloonStyleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_BalloonStyle)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Style ) ) {
GeoDataBalloonStyle style;
KmlObjectTagHandler::parseIdentifiers( parser, &style );
parentItem.nodeAs<GeoDataStyle>()->setBalloonStyle( style );
return &parentItem.nodeAs<GeoDataStyle>()->balloonStyle();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlBalloonVisibilityTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlBalloonVisibilityTagHandler.cpp
index c44e2b9eb..c134b3f52 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlBalloonVisibilityTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlBalloonVisibilityTagHandler.cpp
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
#include "KmlBalloonVisibilityTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoParser.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include <QDebug>
namespace Marble
{
namespace kml
{
namespace gx
{
KML_DEFINE_TAG_HANDLER_GX22( balloonVisibility )
GeoNode* KmlballoonVisibilityTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_balloonVisibility)));
QString content = parser.readElementText().trimmed();
const bool visible = (content == QLatin1String("1"));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataPlacemark>() ){
parentItem.nodeAs<GeoDataPlacemark>()->setBalloonVisible( visible );
}
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlBeginTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlBeginTagHandler.cpp
index 2e1acb9a3..61fc2d367 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlBeginTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlBeginTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlBeginTagHandler.h"
#include "MarbleDebug.h"
#include "KmlWhenTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataTimeSpan.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( begin )
GeoNode* KmlbeginTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_begin)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_TimeSpan ) ) {
QString beginString = parser.readElementText().trimmed();
GeoDataTimeStamp beginStamp = KmlwhenTagHandler::parseTimestamp( beginString );
parentItem.nodeAs<GeoDataTimeSpan>()->setBegin( beginStamp );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlBgColorTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlBgColorTagHandler.cpp
index 8afbbbee6..d35d50aee 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlBgColorTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlBgColorTagHandler.cpp
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlBgColorTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlColorTagHandler.h"
#include "GeoDataBalloonStyle.h"
#include "GeoDataListStyle.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( bgColor )
GeoNode* KmlbgColorTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_bgColor)));
GeoStackItem parentItem = parser.parentElement();
QColor const color = KmlcolorTagHandler::parseColor( parser.readElementText().trimmed() );
if ( parentItem.represents( kmlTag_BalloonStyle ) )
{
parentItem.nodeAs<GeoDataBalloonStyle>()->setBackgroundColor( color );
}
else if ( parentItem.represents( kmlTag_ListStyle ) )
{
parentItem.nodeAs<GeoDataListStyle>()->setBackgroundColor( color );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlBottomFovTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlBottomFovTagHandler.cpp
index 12ce2efcc..db8168c2e 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlBottomFovTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlBottomFovTagHandler.cpp
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlBottomFovTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataViewVolume.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( bottomFov )
GeoNode* KmlbottomFovTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_bottomFov)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ViewVolume ))
{
qreal bottomFov = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataViewVolume>()->setBottomFov( bottomFov );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlCameraTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlCameraTagHandler.cpp
index 3f8dc1971..27047be9d 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlCameraTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlCameraTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlCameraTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataCamera.h"
#include "GeoParser.h"
#include "GeoDataFeature.h"
#include "GeoDataFlyTo.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Camera )
GeoNode *KmlCameraTagHandler::parse( GeoParser & parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Camera)));
- GeoDataCamera* camera = 0;
+ GeoDataCamera* camera = nullptr;
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataFeature>() ) {
camera = new GeoDataCamera;
KmlObjectTagHandler::parseIdentifiers( parser, camera );
parentItem.nodeAs<GeoDataFeature>()->setAbstractView( camera );
}
if ( parentItem.is<GeoDataFlyTo>() ) {
camera = new GeoDataCamera;
KmlObjectTagHandler::parseIdentifiers( parser, camera );
parentItem.nodeAs<GeoDataFlyTo>()->setView( camera );
}
return camera;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlChangeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlChangeTagHandler.cpp
index bdb51b378..86da3a660 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlChangeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlChangeTagHandler.cpp
@@ -1,43 +1,43 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlChangeTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataUpdate.h"
#include "GeoDataChange.h"
#include "GeoDataParser.h"
#include "KmlObjectTagHandler.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Change )
GeoNode* KmlChangeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Change)));
GeoDataChange *change = new GeoDataChange;
KmlObjectTagHandler::parseIdentifiers( parser, change );
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Update ) ) {
parentItem.nodeAs<GeoDataUpdate>()->setChange( change );
return change;
} else {
delete change;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlColorModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlColorModeTagHandler.cpp
index 3218c5e61..87d251bab 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlColorModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlColorModeTagHandler.cpp
@@ -1,53 +1,53 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlColorModeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataColorStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( colorMode )
GeoNode* KmlcolorModeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_colorMode)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataColorStyle>() ) {
if (parser.readElementText().trimmed() == QLatin1String("random")) {
parentItem.nodeAs<GeoDataColorStyle>()->setColorMode( GeoDataColorStyle::Random );
} else {
parentItem.nodeAs<GeoDataColorStyle>()->setColorMode( GeoDataColorStyle::Normal );
}
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlColorTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlColorTagHandler.cpp
index 32bc8e6bd..96838ab9e 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlColorTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlColorTagHandler.cpp
@@ -1,70 +1,70 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlColorTagHandler.h"
#include <QColor>
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataColorStyle.h"
#include "GeoDataOverlay.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( color )
GeoNode* KmlcolorTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_color)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataColorStyle>() || parentItem.is<GeoDataOverlay>() ) {
QColor const color = parseColor( parser.readElementText().trimmed() );
if ( parentItem.is<GeoDataColorStyle>() ) {
parentItem.nodeAs<GeoDataColorStyle>()->setColor( color );
} else if ( parentItem.is<GeoDataOverlay>() ) {
parentItem.nodeAs<GeoDataOverlay>()->setColor( color );
}
}
- return 0;
+ return nullptr;
}
QColor KmlcolorTagHandler::parseColor( const QString &colorString )
{
// color tag uses AABBGGRR whereas QColor uses AARRGGBB - use some shifts for that
// be aware that QRgb needs to be a typedef for 32 bit UInt for this to work properly
bool ok;
QRgb abgr = colorString.toUInt( &ok, 16 );
unsigned a = abgr >> 24; abgr = abgr << 8; //"rgb0"
unsigned b = abgr >> 24; abgr = abgr << 8; //"gb00"
unsigned g = abgr >> 24; abgr = abgr << 8; //"b000"
unsigned r = abgr >> 24;
QRgb rgba = (a << 24)|(r << 16)|(g << 8)|(b);
return ok ? QColor::fromRgba( rgba ) : QColor();
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlCookieTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlCookieTagHandler.cpp
index e1e0ff954..13be43316 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlCookieTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlCookieTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlCookieTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( cookie )
GeoNode* KmlcookieTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_cookie)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
QString cookie = parser.readElementText();
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setCookie( cookie );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlCoordinatesTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlCoordinatesTagHandler.cpp
index 98a5c80ee..cdfd678fe 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlCoordinatesTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlCoordinatesTagHandler.cpp
@@ -1,197 +1,197 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlCoordinatesTagHandler.h"
#include <QStringList>
#include <QRegExp>
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataTrack.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataModel.h"
#include "GeoDataLineString.h"
#include "GeoDataLinearRing.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataLatLonQuad.h"
#include "GeoParser.h"
#include "MarbleGlobal.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( coordinates )
static const bool kmlStrictSpecs = false;
// We can't use KML_DEFINE_TAG_HANDLER_GX22 because the name of the tag ("coord")
// and the TagHandler ("KmlcoordinatesTagHandler") don't match
static GeoTagHandlerRegistrar s_handlercoordkmlTag_nameSpaceGx22(GeoParser::QualifiedName(QLatin1String(kmlTag_coord), QLatin1String(kmlTag_nameSpaceGx22)),
new KmlcoordinatesTagHandler());
GeoNode* KmlcoordinatesTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement()
&& (parser.isValidElement(QLatin1String(kmlTag_coordinates))
|| parser.isValidElement(QLatin1String(kmlTag_coord))));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Point )
|| parentItem.represents( kmlTag_LineString )
|| parentItem.represents( kmlTag_MultiGeometry )
|| parentItem.represents( kmlTag_LinearRing )
|| parentItem.represents( kmlTag_LatLonQuad ) ) {
QStringList coordinatesLines;// = parser.readElementText().trimmed().split( QRegExp("\\s"), QString::SkipEmptyParts );
// Splitting using the "\\s" regexp is slow, split manually instead.
QString text = parser.readElementText().trimmed();
if ( !kmlStrictSpecs ) {
// Removing spaces before and after commas
for ( int i = 1; i < text.size() - 1; ++i ) {
if (text[i] == QLatin1Char(',')) {
// Before
int l = i - 1;
while ( l > 0 && text[l].isSpace() ) {
--l;
}
// After
int r = i + 1;
while ( r < text.size() && text[r].isSpace() ) {
++r;
}
text.remove(l + 1, r - l - 1).insert(l + 1, QLatin1Char(','));
}
}
}
int index = 0;
bool inside = true;
int const size = text.size();
for ( int i=0; i<size; ++i ) {
if ( text[i].isSpace() ) {
if ( inside ) {
coordinatesLines.append( text.mid( index, i-index ) );
inside = false;
}
index = i+1;
} else {
inside = true;
}
}
coordinatesLines.append( text.mid( index ) );
int coordinatesIndex = 0;
for( const QString& line: coordinatesLines ) {
const QStringList coordinates = line.trimmed().split(QLatin1Char(','));
if ( parentItem.represents( kmlTag_Point ) && parentItem.is<GeoDataFeature>() ) {
GeoDataCoordinates coord;
if ( coordinates.size() == 2 ) {
coord.set( coordinates.at( 0 ).toDouble(),
coordinates.at( 1 ).toDouble(), 0.0, GeoDataCoordinates::Degree );
} else if( coordinates.size() == 3 ) {
coord.set( coordinates.at( 0 ).toDouble(),
coordinates.at( 1 ).toDouble(),
coordinates.at( 2 ).toDouble(),
GeoDataCoordinates::Degree );
}
parentItem.nodeAs<GeoDataPlacemark>()->setCoordinate( coord );
} else {
GeoDataCoordinates coord;
if ( coordinates.size() == 2 ) {
coord.set( DEG2RAD * coordinates.at( 0 ).toDouble(),
DEG2RAD * coordinates.at( 1 ).toDouble() );
} else if( coordinates.size() == 3 ) {
coord.set( DEG2RAD * coordinates.at( 0 ).toDouble(),
DEG2RAD * coordinates.at( 1 ).toDouble(),
coordinates.at( 2 ).toDouble() );
}
if ( parentItem.represents( kmlTag_LineString ) ) {
parentItem.nodeAs<GeoDataLineString>()->append( coord );
} else if ( parentItem.represents( kmlTag_LinearRing ) ) {
parentItem.nodeAs<GeoDataLinearRing>()->append( coord );
} else if ( parentItem.represents( kmlTag_MultiGeometry ) ) {
GeoDataPoint *point = new GeoDataPoint( coord );
parentItem.nodeAs<GeoDataMultiGeometry>()->append( point );
} else if ( parentItem.represents( kmlTag_Model) ) {
parentItem.nodeAs<GeoDataModel>()->setCoordinates( coord);
} else if ( parentItem.represents( kmlTag_Point ) ) {
// photo overlay
parentItem.nodeAs<GeoDataPoint>()->setCoordinates( coord );
} else if ( parentItem.represents( kmlTag_LatLonQuad ) ) {
switch ( coordinatesIndex ) {
case 0:
parentItem.nodeAs<GeoDataLatLonQuad>()->setBottomLeft( coord );
break;
case 1:
parentItem.nodeAs<GeoDataLatLonQuad>()->setBottomRight( coord );
break;
case 2:
parentItem.nodeAs<GeoDataLatLonQuad>()->setTopRight( coord );
break;
case 3:
parentItem.nodeAs<GeoDataLatLonQuad>()->setTopLeft( coord );
break;
case 4:
mDebug() << "Ignoring excessive coordinates in LatLonQuad (must not have more than 4 pairs)";
break;
default:
// Silently ignore any more coordinates
break;
}
} else {
// raise warning as coordinates out of valid parents found
}
}
++coordinatesIndex;
}
}
if( parentItem.represents( kmlTag_Track ) ) {
QString input = parser.readElementText().trimmed();
if ( !kmlStrictSpecs ) {
input.replace(QRegExp(QStringLiteral("\\s*,\\s*")), QStringLiteral(","));
}
const QStringList coordinates = input.split(QLatin1Char(' '));
GeoDataCoordinates coord;
if ( coordinates.size() == 2 ) {
coord.set( DEG2RAD * coordinates.at( 0 ).toDouble(),
DEG2RAD * coordinates.at( 1 ).toDouble() );
} else if( coordinates.size() == 3 ) {
coord.set( DEG2RAD * coordinates.at( 0 ).toDouble(),
DEG2RAD * coordinates.at( 1 ).toDouble(),
coordinates.at( 2 ).toDouble() );
}
parentItem.nodeAs<GeoDataTrack>()->appendCoordinates( coord );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlCountryNameCodeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlCountryNameCodeTagHandler.cpp
index bcedbe3f1..590b73c3a 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlCountryNameCodeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlCountryNameCodeTagHandler.cpp
@@ -1,56 +1,56 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
#if KML_LAZY_IMP
#include "KmlCountryNameCodeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPlacemark.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( CountryNameCode )
GeoNode* KmlCountryNameCodeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_CountryNameCode)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.nodeAs<GeoDataPlacemark>() ) {
QString countrycode = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataPlacemark>()->setCountryCode( countrycode );
}
- return 0;
+ return nullptr;
}
}
}
#endif // KML_LAZY_IMP
diff --git a/src/lib/marble/geodata/handlers/kml/KmlCountrycodeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlCountrycodeTagHandler.cpp
index 92ba57c26..d721ecdc8 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlCountrycodeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlCountrycodeTagHandler.cpp
@@ -1,56 +1,56 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
#if KML_LAZY_IMP
#include "KmlCountrycodeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPlacemark.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( countrycode )
GeoNode* KmlcountrycodeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_countrycode)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataPlacemark>() ) {
QString countrycode = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataPlacemark>()->setCountryCode( countrycode );
}
- return 0;
+ return nullptr;
}
}
}
#endif //KML_LAZY_IMP
diff --git a/src/lib/marble/geodata/handlers/kml/KmlCreateTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlCreateTagHandler.cpp
index c39909991..6dc5ddc13 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlCreateTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlCreateTagHandler.cpp
@@ -1,43 +1,43 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlCreateTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataUpdate.h"
#include "GeoDataCreate.h"
#include "GeoDataParser.h"
#include "KmlObjectTagHandler.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Create )
GeoNode* KmlCreateTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Create)));
GeoDataCreate *create = new GeoDataCreate;
KmlObjectTagHandler::parseIdentifiers( parser, create );
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Update ) ) {
parentItem.nodeAs<GeoDataUpdate>()->setCreate( create );
return create;
} else {
delete create;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlDataTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlDataTagHandler.cpp
index a7442d686..d989a0ad0 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlDataTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlDataTagHandler.cpp
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlDataTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Data )
GeoNode* KmlDataTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Data)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_ExtendedData ) ) {
GeoDataData data;
QString name = parser.attribute( "name" ).trimmed();
data.setName( name );
parentItem.nodeAs< GeoDataExtendedData >()->addValue( data );
return static_cast<GeoDataData*>( &parentItem.nodeAs<GeoDataExtendedData>()->valueRef( name ) );
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlDeleteTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlDeleteTagHandler.cpp
index bed89132e..0b5051dd2 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlDeleteTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlDeleteTagHandler.cpp
@@ -1,43 +1,43 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlDeleteTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataUpdate.h"
#include "GeoDataDelete.h"
#include "GeoDataParser.h"
#include "KmlObjectTagHandler.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Delete )
GeoNode* KmlDeleteTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Delete)));
GeoDataDelete *dataDelete = new GeoDataDelete;
KmlObjectTagHandler::parseIdentifiers( parser, dataDelete );
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Update ) ) {
parentItem.nodeAs<GeoDataUpdate>()->setDelete( dataDelete );
return dataDelete;
} else {
delete dataDelete;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlDescriptionTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlDescriptionTagHandler.cpp
index 6d3cbfce0..7c27db9da 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlDescriptionTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlDescriptionTagHandler.cpp
@@ -1,80 +1,80 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlDescriptionTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( description )
GeoNode* KmldescriptionTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_description)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataFeature>() ) {
QString result;
bool finished = false;
bool isCDATA = false;
while( !finished ) {
switch ( parser.readNext() ) {
case QXmlStreamReader::Characters:
case QXmlStreamReader::EntityReference: {
result.append( parser.text() );
if( parser.isCDATA() ) {
isCDATA = true;
}
break;
}
case QXmlStreamReader::EndElement:
finished = true;
break;
case QXmlStreamReader::ProcessingInstruction:
case QXmlStreamReader::Comment:
break;
default:
finished = true;
break;
}
}
QString description = result.trimmed();
parentItem.nodeAs<GeoDataFeature>()->setDescription( description );
parentItem.nodeAs<GeoDataFeature>()->setDescriptionCDATA( isCDATA );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlDisplayModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlDisplayModeTagHandler.cpp
index 067da31b7..555e22bd3 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlDisplayModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlDisplayModeTagHandler.cpp
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlDisplayModeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataBalloonStyle.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( displayMode )
GeoNode* KmldisplayModeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_displayMode)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_BalloonStyle ) )
{
QString mode = parser.readElementText().trimmed();
GeoDataBalloonStyle::DisplayMode displayMode = GeoDataBalloonStyle::Default;
if (mode == QLatin1String("default")) {
displayMode = GeoDataBalloonStyle::Default;
} else if (mode == QLatin1String("hide")) {
displayMode = GeoDataBalloonStyle::Hide;
}
parentItem.nodeAs<GeoDataBalloonStyle>()->setDisplayMode( displayMode );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlDisplayNameTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlDisplayNameTagHandler.cpp
index 2db7a6778..7d4e183b3 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlDisplayNameTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlDisplayNameTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlDisplayNameTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataData.h"
#include "GeoDataSimpleField.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( displayName )
GeoNode* KmldisplayNameTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_displayName)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Data ) ) {
QString displayName = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataData>()->setDisplayName( displayName );
}
else if ( parentItem.represents( kmlTag_SimpleField ) ) {
QString displayName = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataSimpleField>()->setDisplayName( displayName );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlDocumentTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlDocumentTagHandler.cpp
index 89e2fa802..8009a5352 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlDocumentTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlDocumentTagHandler.cpp
@@ -1,62 +1,62 @@
/*
Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "KmlDocumentTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER(Document)
GeoNode* KmlDocumentTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Document)));
GeoStackItem parentItem = parser.parentElement();
if( !(parentItem.qualifiedName().first.isNull() && parentItem.qualifiedName().second.isNull()) ) {
// this happens if there is a parent element to the Document tag. We can work around that and simply expect that
// the new Document tag works like a Folder
if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) || parentItem.represents( kmlTag_Create ) ) {
GeoDataDocument *document = new GeoDataDocument;
KmlObjectTagHandler::parseIdentifiers( parser, document );
parentItem.nodeAs<GeoDataContainer>()->append( document );
return document;
}
else if (parentItem.qualifiedName().first == QLatin1String(kmlTag_kml)) {
GeoDataDocument* doc = geoDataDoc( parser );
KmlObjectTagHandler::parseIdentifiers( parser, doc );
return doc;
}
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlDurationTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlDurationTagHandler.cpp
index d8b30b621..715dcccf0 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlDurationTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlDurationTagHandler.cpp
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlDurationTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "MarbleGlobal.h"
#include "GeoDataFlyTo.h"
#include "GeoDataWait.h"
#include "GeoDataAnimatedUpdate.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( duration )
GeoNode *KmldurationTagHandler::parse(GeoParser & parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_duration)));
GeoStackItem parentItem = parser.parentElement();
qreal const duration = parser.readElementText().trimmed().toDouble();
if ( parentItem.is<GeoDataFlyTo>() ){
parentItem.nodeAs<GeoDataFlyTo>()->setDuration( duration );
}
if ( parentItem.is<GeoDataWait>() ){
parentItem.nodeAs<GeoDataWait>()->setDuration( duration );
}
if ( parentItem.is<GeoDataAnimatedUpdate>() ){
parentItem.nodeAs<GeoDataAnimatedUpdate>()->setDuration( duration );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlEastTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlEastTagHandler.cpp
index cdc584a0f..6180c7323 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlEastTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlEastTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlEastTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( east )
GeoNode* KmleastTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_east)));
GeoStackItem parentItem = parser.parentElement();
qreal const east = parser.readElementText().trimmed().toDouble();
if( parentItem.represents( kmlTag_LatLonAltBox ) ) {
parentItem.nodeAs<GeoDataLatLonAltBox>()->setEast( east, GeoDataCoordinates::Degree );
} else if( parentItem.represents( kmlTag_LatLonBox ) ) {
parentItem.nodeAs<GeoDataLatLonBox>()->setEast( east, GeoDataCoordinates::Degree );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlEndTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlEndTagHandler.cpp
index 3dfc10f91..de8116404 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlEndTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlEndTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlEndTagHandler.h"
#include "MarbleDebug.h"
#include "KmlWhenTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataTimeSpan.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( end )
GeoNode* KmlendTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_end)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_TimeSpan ) ) {
QString endString = parser.readElementText().trimmed();
GeoDataTimeStamp endStamp = KmlwhenTagHandler::parseTimestamp( endString );
parentItem.nodeAs<GeoDataTimeSpan>()->setEnd( endStamp );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlExpiresTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlExpiresTagHandler.cpp
index 9fc6ee9da..8d3f893b3 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlExpiresTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlExpiresTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlExpiresTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
#include <QDateTime>
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( expires )
GeoNode* KmlexpiresTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_expires)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
QDateTime time = QDateTime::fromString( parser.readElementText(), Qt::ISODate );
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setExpires( time );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlExtendedDataTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlExtendedDataTagHandler.cpp
index d8effef3f..5aaf85b81 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlExtendedDataTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlExtendedDataTagHandler.cpp
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlExtendedDataTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataExtendedData.h"
#include "GeoDataFeature.h"
#include "GeoDataTrack.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( ExtendedData )
GeoNode* KmlExtendedDataTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_ExtendedData)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataFeature>() ) {
GeoDataExtendedData extendedData;
parentItem.nodeAs<GeoDataFeature>()->setExtendedData( extendedData );
return static_cast<GeoDataExtendedData*>( &parentItem.nodeAs<GeoDataFeature>()->extendedData() );
} else if( parentItem.is<GeoDataTrack>() ) {
GeoDataExtendedData extendedData;
parentItem.nodeAs<GeoDataTrack>()->setExtendedData( extendedData );
return static_cast<GeoDataExtendedData*>( &parentItem.nodeAs<GeoDataTrack>()->extendedData() );
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlExtrudeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlExtrudeTagHandler.cpp
index 35ee7b461..52d5c86a2 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlExtrudeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlExtrudeTagHandler.cpp
@@ -1,79 +1,79 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
Copyright (C) 2014 Marek Hakala <hakala.marek@gmail.com>
This file is part of the KDE project
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
aint 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 "KmlExtrudeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataGeometry.h"
#include "GeoDataPoint.h"
#include "GeoDataPolygon.h"
#include "GeoDataLineString.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPlacemark.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( extrude )
GeoNode* KmlextrudeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_extrude)));
GeoStackItem parentItem = parser.parentElement();
GeoDataGeometry* geometry;
bool validParents = false;
if( parentItem.is<GeoDataPoint>() ) {
geometry = parentItem.nodeAs<GeoDataPoint>();
validParents = true;
} else if( parentItem.is<GeoDataPlacemark>() ) {
geometry = parentItem.nodeAs<GeoDataPlacemark>()->geometry();
validParents = true;
} else if( parentItem.is<GeoDataPolygon>() ) {
geometry = parentItem.nodeAs<GeoDataPolygon>();
validParents = true;
} else if( parentItem.is<GeoDataLineString>() ) {
geometry = parentItem.nodeAs<GeoDataLineString>();
validParents = true;
} else if( parentItem.is<GeoDataLinearRing>() ) {
geometry = parentItem.nodeAs<GeoDataLinearRing>();
validParents = true;
}
if( validParents ) {
QString content = parser.readElementText().trimmed();
const bool extrude = (content == QLatin1String("1"));
geometry->setExtrude(extrude);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlFillTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlFillTagHandler.cpp
index 2f935ebfe..f1a066f18 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlFillTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlFillTagHandler.cpp
@@ -1,52 +1,52 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlFillTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPolyStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( fill )
GeoNode* KmlfillTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_fill)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_PolyStyle ) ) {
bool fill = static_cast<bool>( parser.readElementText().trimmed().toInt() );
parentItem.nodeAs<GeoDataPolyStyle>()->setFill( fill );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlFlyToModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlFlyToModeTagHandler.cpp
index 447238f68..d74be2fcb 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlFlyToModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlFlyToModeTagHandler.cpp
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlFlyToModeTagHandler.h"
#include "GeoDataFlyTo.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
#include "MarbleDebug.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( flyToMode )
GeoNode* KmlflyToModeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_flyToMode)));
QString content = parser.readElementText().trimmed();
GeoDataFlyTo::FlyToMode mode;
if (content == QLatin1String("smooth")) {
mode = GeoDataFlyTo::Smooth;
} else if (content == QLatin1String("bounce")) {
mode = GeoDataFlyTo::Bounce;
} else {
mDebug() << "Unknown mode " << content << ", using 'bounce' instead.";
mode = GeoDataFlyTo::Bounce;
}
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataFlyTo>() ) {
parentItem.nodeAs<GeoDataFlyTo>()->setFlyToMode( mode );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlFlyToTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlFlyToTagHandler.cpp
index 36ebcece7..ca94bdf72 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlFlyToTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlFlyToTagHandler.cpp
@@ -1,43 +1,43 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
#include "KmlFlyToTagHandler.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataFlyTo.h"
#include "GeoDataPlaylist.h"
#include "GeoParser.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( FlyTo )
GeoNode* KmlFlyToTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_FlyTo)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.is<GeoDataPlaylist>()) {
GeoDataFlyTo *flyTo = new GeoDataFlyTo;
KmlObjectTagHandler::parseIdentifiers( parser, flyTo );
parentItem.nodeAs<GeoDataPlaylist>()->addPrimitive( flyTo );
return flyTo;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlFlyToViewTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlFlyToViewTagHandler.cpp
index 4bbda6967..4ea0b6fd3 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlFlyToViewTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlFlyToViewTagHandler.cpp
@@ -1,38 +1,38 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlFlyToViewTagHandler.h"
#include "GeoDataNetworkLink.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( flyToView )
GeoNode* KmlflyToViewTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_flyToView)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataNetworkLink>() ) {
QString content = parser.readElementText().trimmed();
GeoDataNetworkLink* networkLink = parentItem.nodeAs<GeoDataNetworkLink>();
networkLink->setFlyToView(content == QLatin1String("1"));
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlFolderTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlFolderTagHandler.cpp
index c489f910e..54b1b18fa 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlFolderTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlFolderTagHandler.cpp
@@ -1,62 +1,62 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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 "KmlFolderTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataContainer.h"
#include "GeoDataFolder.h"
#include "GeoDataParser.h"
#include "GeoDataDocument.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER(Folder)
GeoNode* KmlFolderTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Folder)));
GeoStackItem parentItem = parser.parentElement();
GeoDataFolder *folder = new GeoDataFolder;
KmlObjectTagHandler::parseIdentifiers( parser, folder );
if ( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ) {
GeoDataContainer *parentPtr = parentItem.nodeAs<GeoDataContainer>();
parentPtr->append( folder );
return folder;
} else if (parentItem.qualifiedName().first == QLatin1String(kmlTag_kml)) {
GeoDataDocument* doc = geoDataDoc( parser );
doc->append( folder );
return folder;
} else {
delete folder;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlGridOriginTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlGridOriginTagHandler.cpp
index ea6f277f6..114cebf15 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlGridOriginTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlGridOriginTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlGridOriginTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataImagePyramid.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( gridOrigin )
GeoNode* KmlgridOriginTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_gridOrigin)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ImagePyramid ))
{
GeoDataImagePyramid::GridOrigin gridOrigin = GeoDataImagePyramid::UpperLeft;
QString gridOriginText = parser.readElementText();
if (gridOriginText == QLatin1String("lowerLeft")) {
gridOrigin = GeoDataImagePyramid::LowerLeft;
} else if (gridOriginText == QLatin1String("upperLeft")) {
gridOrigin = GeoDataImagePyramid::UpperLeft;
}
parentItem.nodeAs<GeoDataImagePyramid>()->setGridOrigin( gridOrigin );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlGroundOverlayTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlGroundOverlayTagHandler.cpp
index 655506712..2b9cafb8f 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlGroundOverlayTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlGroundOverlayTagHandler.cpp
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "KmlGroundOverlayTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataContainer.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( GroundOverlay )
GeoNode* KmlGroundOverlayTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_GroundOverlay)));
GeoDataGroundOverlay *overlay = new GeoDataGroundOverlay;
KmlObjectTagHandler::parseIdentifiers( parser, overlay );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ||
parentItem.represents( kmlTag_Change ) || parentItem.represents( kmlTag_Create ) || parentItem.represents( kmlTag_Delete ) ) {
parentItem.nodeAs<GeoDataContainer>()->append( overlay );
return overlay;
} else if (parentItem.qualifiedName().first == QLatin1String(kmlTag_kml)) {
GeoDataDocument* doc = geoDataDoc( parser );
doc->append( overlay );
return overlay;
} else {
delete overlay;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlGxAltitudeModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlGxAltitudeModeTagHandler.cpp
index eec8fc412..825746024 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlGxAltitudeModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlGxAltitudeModeTagHandler.cpp
@@ -1,83 +1,83 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlGxAltitudeModeTagHandler.h"
#include "KmlAltitudeModeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataGeometry.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataPoint.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTrack.h"
#include "GeoDataAbstractView.h"
#include "GeoDataModel.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
namespace gx
{
KML_DEFINE_TAG_HANDLER_GX22( altitudeMode )
GeoNode* KmlaltitudeModeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_altitudeMode)));
QString content = parser.readElementText().trimmed();
AltitudeMode mode;
if (content == QLatin1String("relativeToGround")) {
mode = RelativeToGround;
} else if (content == QLatin1String("absolute")) {
mode = Absolute;
} else if (content == QLatin1String("relativeToSeaFloor")) {
mode = RelativeToSeaFloor;
} else if (content == QLatin1String("clampToSeaFloor")) {
mode = ClampToSeaFloor;
} else if (content == QLatin1String("clampToGround")) {
mode = ClampToGround;
} else {
mDebug() << "Unknown altitude mode " << content << ", falling back to 'clampToGround'";
mode = ClampToGround;
}
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataPlacemark>() ) {
parentItem.nodeAs<GeoDataPlacemark>()->geometry()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataPoint>() ) {
parentItem.nodeAs<GeoDataPoint>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataLatLonAltBox>() ) {
parentItem.nodeAs<GeoDataLatLonAltBox>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataTrack>() ) {
parentItem.nodeAs<GeoDataTrack>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataGroundOverlay>() ) {
parentItem.nodeAs<GeoDataGroundOverlay>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataAbstractView>() ) {
parentItem.nodeAs<GeoDataAbstractView>()->setAltitudeMode( mode );
} else if ( parentItem.is<GeoDataModel>() ) {
parentItem.nodeAs<GeoDataModel>()->setAltitudeMode( mode );
}
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlGxTimeSpanTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlGxTimeSpanTagHandler.cpp
index dc3000b60..134d20b50 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlGxTimeSpanTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlGxTimeSpanTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlGxTimeSpanTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataTimeSpan.h"
#include "GeoDataFeature.h"
#include "GeoDataAbstractView.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
namespace gx
{
KML_DEFINE_TAG_HANDLER_GX22( TimeSpan )
GeoNode* KmlTimeSpanTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_TimeSpan)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataFeature>() ) {
GeoDataTimeSpan timeSpan;
KmlObjectTagHandler::parseIdentifiers( parser, &timeSpan );
parentItem.nodeAs<GeoDataFeature>()->setTimeSpan( timeSpan );
return &parentItem.nodeAs<GeoDataFeature>()->timeSpan();
} else if ( parentItem.is<GeoDataAbstractView>() ) {
GeoDataTimeSpan timeSpan;
KmlObjectTagHandler::parseIdentifiers( parser, &timeSpan );
parentItem.nodeAs<GeoDataAbstractView>()->setTimeSpan( timeSpan );
return &parentItem.nodeAs<GeoDataAbstractView>()->timeSpan();
}
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlGxTimeStampTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlGxTimeStampTagHandler.cpp
index b8e3314c0..9ad82a775 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlGxTimeStampTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlGxTimeStampTagHandler.cpp
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlGxTimeStampTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataTimeStamp.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
#include <GeoDataAbstractView.h>
#include "KmlTimeStampTagHandler.h"
namespace Marble
{
namespace kml
{
namespace gx
{
KML_DEFINE_TAG_HANDLER_GX22( TimeStamp )
GeoNode* KmlTimeStampTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_TimeStamp)));
GeoStackItem parentItem = parser.parentElement();
GeoDataTimeStamp timestamp;
KmlObjectTagHandler::parseIdentifiers( parser, &timestamp );
if ( parentItem.is<GeoDataFeature>() ) {
parentItem.nodeAs<GeoDataFeature>()->setTimeStamp( timestamp );
return &parentItem.nodeAs<GeoDataFeature>()->timeStamp();
} else if ( parentItem.is<GeoDataAbstractView>() ) {
parentItem.nodeAs<GeoDataAbstractView>()->setTimeStamp( timestamp );
return &parentItem.nodeAs<GeoDataAbstractView>()->timeStamp();
}
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlHeadingTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlHeadingTagHandler.cpp
index dbe3c36fc..79997d171 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlHeadingTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlHeadingTagHandler.cpp
@@ -1,61 +1,61 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlHeadingTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataIconStyle.h"
#include "GeoDataCamera.h"
#include "GeoDataOrientation.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( heading )
GeoNode* KmlheadingTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_heading)));
GeoStackItem parentItem = parser.parentElement();
int const heading = parser.readElementText().toInt();
if ( heading >= 0 && heading <= 360 ) {
if ( parentItem.represents( kmlTag_IconStyle ) ) {
parentItem.nodeAs<GeoDataIconStyle>()->setHeading( heading );
} else if ( parentItem.represents( kmlTag_Camera ) ) {
parentItem.nodeAs<GeoDataCamera>()->setHeading( heading );
} else if ( parentItem.represents( kmlTag_Orientation ) ) {
parentItem.nodeAs<GeoDataOrientation>()->setHeading( heading );
}
} else {
mDebug() << "Invalid heading value " << heading << ", must be within 0..360. Using 0 instead.";
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlHotSpotTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlHotSpotTagHandler.cpp
index e08725e45..5bd9e4361 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlHotSpotTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlHotSpotTagHandler.cpp
@@ -1,74 +1,74 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlHotSpotTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataIconStyle.h"
#include "GeoDataHotSpot.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( hotSpot )
GeoNode* KmlhotSpotTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_hotSpot)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_IconStyle ) ) {
QPointF pf( parser.attribute( "x" ).trimmed().toFloat(),
parser.attribute( "y" ).trimmed().toFloat() );
QString xu = parser.attribute( "xunits" ).trimmed();
QString yu = parser.attribute( "yunits" ).trimmed();
GeoDataHotSpot::Units xunits;
GeoDataHotSpot::Units yunits;
if (xu == QLatin1String("pixels")) {
xunits = GeoDataHotSpot::Pixels;
} else if (xu == QLatin1String("insetPixels")) {
xunits = GeoDataHotSpot::InsetPixels;
} else {
xunits = GeoDataHotSpot::Fraction;
}
if (yu == QLatin1String("pixels")) {
yunits = GeoDataHotSpot::Pixels;
} else if (yu == QLatin1String("insetPixels")) {
yunits = GeoDataHotSpot::InsetPixels;
} else {
yunits = GeoDataHotSpot::Fraction;
}
parentItem.nodeAs<GeoDataIconStyle>()->setHotSpot( pf, xunits, yunits );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlHrefTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlHrefTagHandler.cpp
index a3ba9c7c8..6d799c27a 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlHrefTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlHrefTagHandler.cpp
@@ -1,72 +1,72 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlHrefTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataIconStyle.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataLink.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataSoundCue.h"
#include "GeoDataItemIcon.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( href )
GeoNode* KmlhrefTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_href)));
GeoStackItem parentItem = parser.parentElement();
QString content = parser.readElementText().trimmed();
if ( parentItem.represents( kmlTag_Icon ) ) {
// we need a more elaborate version of this part
if ( parentItem.is<GeoDataIconStyle>() ) {
parentItem.nodeAs<GeoDataIconStyle>()->setIconPath( content );
} else if ( parentItem.is<GeoDataGroundOverlay>() ) {
parentItem.nodeAs<GeoDataGroundOverlay>()->setIconFile( content );
} else if ( parentItem.is<GeoDataPhotoOverlay>() ) {
parentItem.nodeAs<GeoDataPhotoOverlay>()->setIconFile( content );
} else if ( parentItem.is<GeoDataScreenOverlay>() ) {
parentItem.nodeAs<GeoDataScreenOverlay>()->setIconFile( content );
}
} else if ( parentItem.represents( kmlTag_ItemIcon ) ) {
parentItem.nodeAs<GeoDataItemIcon>()->setIconPath( content );
} else if ( parentItem.is<GeoDataLink>() ) {
parentItem.nodeAs<GeoDataLink>()->setHref( content );
} else if ( parentItem.is<GeoDataSoundCue>() ) {
parentItem.nodeAs<GeoDataSoundCue>()->setHref( content );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlHttpQueryTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlHttpQueryTagHandler.cpp
index 940efda73..471cfe010 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlHttpQueryTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlHttpQueryTagHandler.cpp
@@ -1,38 +1,38 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlHttpQueryTagHandler.h"
#include "GeoDataLink.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( httpQuery )
GeoNode* KmlhttpQueryTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_httpQuery)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(kmlTag_Link))
{
QString content = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataLink>()->setHttpQuery(content);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlIconStyleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlIconStyleTagHandler.cpp
index 2e51befd1..78b4666b6 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlIconStyleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlIconStyleTagHandler.cpp
@@ -1,54 +1,54 @@
/*
Copyright (C) 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlIconStyleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( IconStyle )
GeoNode* KmlIconStyleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_IconStyle)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Style ) ) {
GeoDataIconStyle style;
KmlObjectTagHandler::parseIdentifiers( parser, &style );
parentItem.nodeAs<GeoDataStyle>()->setIconStyle( style );
return &parentItem.nodeAs<GeoDataStyle>()->iconStyle();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlIconTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlIconTagHandler.cpp
index 69f7a9de6..158183919 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlIconTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlIconTagHandler.cpp
@@ -1,58 +1,58 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlIconTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataIconStyle.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataScreenOverlay.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Icon )
GeoNode* KmlIconTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Icon)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_IconStyle ) ) {
return parentItem.nodeAs<GeoDataIconStyle>();
} else if ( parentItem.represents( kmlTag_GroundOverlay ) ) {
return parentItem.nodeAs<GeoDataGroundOverlay>();
} else if ( parentItem.represents( kmlTag_PhotoOverlay ) ) {
return parentItem.nodeAs<GeoDataPhotoOverlay>();
} else if ( parentItem.represents( kmlTag_ScreenOverlay ) ) {
return parentItem.nodeAs<GeoDataScreenOverlay>();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlImagePyramidTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlImagePyramidTagHandler.cpp
index 738038fa1..a6d37d6ec 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlImagePyramidTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlImagePyramidTagHandler.cpp
@@ -1,37 +1,37 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlImagePyramidTagHandler.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataImagePyramid.h"
#include "GeoDataParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( ImagePyramid )
GeoNode* KmlImagePyramidTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_ImagePyramid)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_PhotoOverlay ) ) {
return &parentItem.nodeAs<GeoDataPhotoOverlay>()->imagePyramid();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlItemIconTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlItemIconTagHandler.cpp
index 764dec71f..a8d86175f 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlItemIconTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlItemIconTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlItemIconTagHandler.h"
#include "MarbleDebug.h"
#include "GeoDataListStyle.h"
#include "GeoDataItemIcon.h"
#include "GeoDataParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( ItemIcon )
GeoNode* KmlItemIconTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_ItemIcon)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_ListStyle ) ) {
GeoDataItemIcon *itemIcon = new GeoDataItemIcon;
parentItem.nodeAs<GeoDataListStyle>()->append( itemIcon );
return itemIcon;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlKeyTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlKeyTagHandler.cpp
index ff775da56..40a54c43e 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlKeyTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlKeyTagHandler.cpp
@@ -1,54 +1,54 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlKeyTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataStyleMap.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( key )
GeoNode* KmlkeyTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_key)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Pair ) ) {
QString content = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataStyleMap>()->setLastKey( content );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLabelStyleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLabelStyleTagHandler.cpp
index fd899462d..094267447 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLabelStyleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLabelStyleTagHandler.cpp
@@ -1,55 +1,55 @@
/*
Copyright (C) 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlLabelStyleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataStyle.h"
#include "GeoDataLabelStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( LabelStyle )
GeoNode* KmlLabelStyleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LabelStyle)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Style ) ) {
GeoDataLabelStyle style;
KmlObjectTagHandler::parseIdentifiers( parser, &style );
parentItem.nodeAs<GeoDataStyle>()->setLabelStyle( style );
return &parentItem.nodeAs<GeoDataStyle>()->labelStyle();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLatLonAltBoxTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLatLonAltBoxTagHandler.cpp
index 41d5aa179..15baa5e52 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLatLonAltBoxTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLatLonAltBoxTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlLatLonAltBoxTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataRegion.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( LatLonAltBox )
GeoNode* KmlLatLonAltBoxTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LatLonAltBox)));
GeoDataLatLonAltBox box;
KmlObjectTagHandler::parseIdentifiers( parser, &box );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Region ) )
{
parentItem.nodeAs<GeoDataRegion>()->setLatLonAltBox( box );
return const_cast<GeoDataLatLonAltBox *>( &parentItem.nodeAs<GeoDataRegion>()->latLonAltBox() );
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLatLonBoxTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLatLonBoxTagHandler.cpp
index ad0b88da4..0bb3daaad 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLatLonBoxTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLatLonBoxTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "KmlLatLonBoxTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataLatLonBox.h"
#include "GeoDataGroundOverlay.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( LatLonBox )
GeoNode* KmlLatLonBoxTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LatLonBox)));
GeoDataLatLonBox box;
KmlObjectTagHandler::parseIdentifiers( parser, &box );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_GroundOverlay ) )
{
parentItem.nodeAs<GeoDataGroundOverlay>()->setLatLonBox( box );
return &parentItem.nodeAs<GeoDataGroundOverlay>()->latLonBox();
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLatLonQuadTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLatLonQuadTagHandler.cpp
index b24cef71f..b36cba834 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLatLonQuadTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLatLonQuadTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Dennis Nienhüser <nienhueser@kde.org>
//
#include "KmlLatLonQuadTagHandler.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataLatLonQuad.h"
#include "GeoDataGroundOverlay.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( LatLonQuad )
GeoNode* KmlLatLonQuadTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LatLonQuad)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_GroundOverlay ) )
{
GeoDataLatLonQuad* quad = &parentItem.nodeAs<GeoDataGroundOverlay>()->latLonQuad();
KmlObjectTagHandler::parseIdentifiers( parser, quad );
return quad;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLatitudeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLatitudeTagHandler.cpp
index b8736b78e..5b6353066 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLatitudeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLatitudeTagHandler.cpp
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlLatitudeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "MarbleGlobal.h"
#include "GeoDataLookAt.h"
#include "GeoDataCamera.h"
#include "GeoParser.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLocation.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( latitude )
GeoNode *KmllatitudeTagHandler::parse( GeoParser & parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_latitude)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataLookAt>() ) {
qreal latitude = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataLookAt>()->setLatitude(latitude, GeoDataCoordinates::Degree);
} else if ( parentItem.is<GeoDataCamera>() ) {
qreal latitude = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataCamera>()->setLatitude(latitude, GeoDataCoordinates::Degree);
} else if ( parentItem.is<GeoDataLocation>() ) {
qreal latitude = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataLocation>()->setLatitude(latitude, GeoDataCoordinates::Degree);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLeftFovTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLeftFovTagHandler.cpp
index 30660851e..14924554c 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLeftFovTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLeftFovTagHandler.cpp
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlLeftFovTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataViewVolume.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( leftFov )
GeoNode* KmlleftFovTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_leftFov)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ViewVolume ))
{
qreal leftFov = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataViewVolume>()->setLeftFov( leftFov );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLineStringTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLineStringTagHandler.cpp
index 6cb067142..9eb98f01e 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLineStringTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLineStringTagHandler.cpp
@@ -1,64 +1,64 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlLineStringTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLineString.h"
#include "GeoDataMultiGeometry.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( LineString )
GeoNode* KmlLineStringTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LineString)));
GeoStackItem parentItem = parser.parentElement();
GeoDataLineString *lineString = new GeoDataLineString;
KmlObjectTagHandler::parseIdentifiers( parser, lineString );
if( parentItem.represents( kmlTag_Placemark ) ) {
parentItem.nodeAs<GeoDataPlacemark>()->setGeometry( lineString );
return parentItem.nodeAs<GeoDataPlacemark>()->geometry();
} else if( parentItem.represents( kmlTag_MultiGeometry ) ) {
parentItem.nodeAs<GeoDataMultiGeometry>()->append( lineString );
return lineString;
} else {
delete lineString;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLineStyleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLineStyleTagHandler.cpp
index eddfbbcef..a4e8ad27f 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLineStyleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLineStyleTagHandler.cpp
@@ -1,54 +1,54 @@
/*
Copyright (C) 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlLineStyleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataStyle.h"
#include "GeoDataLineStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( LineStyle )
GeoNode* KmlLineStyleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LineStyle)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Style ) ) {
GeoDataLineStyle style;
KmlObjectTagHandler::parseIdentifiers( parser, &style );
parentItem.nodeAs<GeoDataStyle>()->setLineStyle( style );
return &parentItem.nodeAs<GeoDataStyle>()->lineStyle();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLinearRingTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLinearRingTagHandler.cpp
index 8041761da..b69f7b00a 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLinearRingTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLinearRingTagHandler.cpp
@@ -1,76 +1,76 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlLinearRingTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPolygon.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataLinearRing.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( LinearRing )
GeoNode* KmlLinearRingTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LinearRing)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_outerBoundaryIs ) ) {
GeoDataLinearRing linearRing;
KmlObjectTagHandler::parseIdentifiers( parser, &linearRing );
parentItem.nodeAs<GeoDataPolygon>()->setOuterBoundary( linearRing );
return &parentItem.nodeAs<GeoDataPolygon>()->outerBoundary();
} else if( parentItem.represents( kmlTag_innerBoundaryIs ) ) {
GeoDataLinearRing linearRing;
KmlObjectTagHandler::parseIdentifiers( parser, &linearRing );
parentItem.nodeAs<GeoDataPolygon>()->appendInnerBoundary( linearRing );
return &parentItem.nodeAs<GeoDataPolygon>()->innerBoundaries().last();
} else if( parentItem.represents( kmlTag_Placemark ) ) {
GeoDataLinearRing *linearRing = new GeoDataLinearRing;
KmlObjectTagHandler::parseIdentifiers( parser, linearRing );
GeoDataPlacemark *placemark = parentItem.nodeAs<GeoDataPlacemark>();
placemark->setGeometry( linearRing );
return placemark->geometry();
} else if( parentItem.is<GeoDataMultiGeometry>() ) {
GeoDataLinearRing *linearRing = new GeoDataLinearRing;
KmlObjectTagHandler::parseIdentifiers( parser, linearRing );
parentItem.nodeAs<GeoDataMultiGeometry>()->append( linearRing );
return linearRing;
} else
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLinkDescriptionTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLinkDescriptionTagHandler.cpp
index ade087e5a..cf6336291 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLinkDescriptionTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLinkDescriptionTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlLinkDescriptionTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( linkDescription )
GeoNode* KmllinkDescriptionTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_linkDescription)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
QString linkDescription = parser.readElementText();
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setLinkDescription( linkDescription );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLinkNameTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLinkNameTagHandler.cpp
index 1ff27d9ee..798b8cbce 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLinkNameTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLinkNameTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlLinkNameTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( linkName )
GeoNode* KmllinkNameTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_linkName)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
QString linkName = parser.readElementText();
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setLinkName( linkName );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLinkSnippetTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLinkSnippetTagHandler.cpp
index 5b99481be..48b980e20 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLinkSnippetTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLinkSnippetTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlLinkSnippetTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( linkSnippet )
GeoNode* KmllinkSnippetTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_linkSnippet)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
int maxLines = parser.attribute( "maxLines" ).trimmed().toInt();
QString linkSnippet = parser.readElementText();
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setLinkSnippet( linkSnippet );
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setMaxLines( maxLines );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLinkTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLinkTagHandler.cpp
index 5d3294e4c..8896e3ffb 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLinkTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLinkTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
#include "KmlLinkTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataLink.h"
#include "GeoDataNetworkLink.h"
#include "GeoDataModel.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Link )
GeoNode* KmlLinkTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Link)));
GeoDataLink link;
KmlObjectTagHandler::parseIdentifiers( parser, &link );
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLink )) {
return &parentItem.nodeAs<GeoDataNetworkLink>()->link();
} else if( parentItem.represents( kmlTag_Model ) ) {
parentItem.nodeAs<GeoDataModel>()->setLink(link);
return &parentItem.nodeAs<GeoDataModel>()->link();
}else{
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlListItemTypeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlListItemTypeTagHandler.cpp
index abdc07f00..033b101c7 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlListItemTypeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlListItemTypeTagHandler.cpp
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlListItemTypeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataListStyle.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( listItemType )
GeoNode* KmllistItemTypeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_listItemType)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_ListStyle ) )
{
QString typeText = parser.readElementText().trimmed();
GeoDataListStyle::ListItemType type = GeoDataListStyle::Check;
if (typeText == QLatin1String("check")) {
type = GeoDataListStyle::Check;
} else if (typeText == QLatin1String("radioFolder")) {
type = GeoDataListStyle::RadioFolder;
} else if (typeText == QLatin1String("checkOffOnly")) {
type = GeoDataListStyle::CheckOffOnly;
} else if (typeText == QLatin1String("checkHideChildren")) {
type = GeoDataListStyle::CheckHideChildren;
}
else
{
mDebug() << "listItemType value is inavlid"
<< "falling back to default - check";
}
parentItem.nodeAs<GeoDataListStyle>()->setListItemType( type );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlListStyleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlListStyleTagHandler.cpp
index 2759ab34c..8f375a395 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlListStyleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlListStyleTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlListStyleTagHandler.h"
#include "MarbleDebug.h"
#include "GeoDataListStyle.h"
#include "GeoDataStyle.h"
#include "GeoDataParser.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( ListStyle )
GeoNode* KmlListStyleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_ListStyle)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Style ) ) {
GeoDataListStyle style;
KmlObjectTagHandler::parseIdentifiers( parser, &style );
parentItem.nodeAs<GeoDataStyle>()->setListStyle( style );
return &parentItem.nodeAs<GeoDataStyle>()->listStyle();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLocationTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLocationTagHandler.cpp
index ee09991fe..4c986a229 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLocationTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLocationTagHandler.cpp
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlLocationTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataLocation.h"
#include "GeoDataGeometry.h"
#include "GeoDataModel.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Location )
GeoNode* KmlLocationTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Location)));
GeoDataLocation location;
KmlObjectTagHandler::parseIdentifiers( parser, &location );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Model ) ) {
parentItem.nodeAs<GeoDataModel>()->setLocation(location);
return &parentItem.nodeAs<GeoDataModel>()->location();
}
else{
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLodTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLodTagHandler.cpp
index 400e762f7..7dc8f1b68 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLodTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLodTagHandler.cpp
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlLodTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataLod.h"
#include "GeoDataRegion.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Lod )
GeoNode* KmlLodTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Lod)));
GeoDataLod lod;
KmlObjectTagHandler::parseIdentifiers( parser, &lod );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Region ) )
{
parentItem.nodeAs<GeoDataRegion>()->setLod( lod );
return &parentItem.nodeAs<GeoDataRegion>()->lod();
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLongitudeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLongitudeTagHandler.cpp
index a560b5c20..968c3627d 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLongitudeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLongitudeTagHandler.cpp
@@ -1,51 +1,51 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlLongitudeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLookAt.h"
#include "GeoDataCamera.h"
#include "GeoParser.h"
#include "GeoDataCoordinates.h"
#include "MarbleGlobal.h"
#include "GeoDataLocation.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( longitude )
GeoNode *KmllongitudeTagHandler::parse( GeoParser & parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_longitude)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataLookAt>() ) {
qreal longitude = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataLookAt>()->setLongitude(longitude, GeoDataCoordinates::Degree);
} else if ( parentItem.is<GeoDataCamera>() ) {
qreal longitude = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataCamera>()->setLongitude(longitude, GeoDataCoordinates::Degree);
} else if ( parentItem.is<GeoDataLocation>() ) {
qreal longitude = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataLocation>()->setLongitude(longitude, GeoDataCoordinates::Degree);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlLookAtTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlLookAtTagHandler.cpp
index 2cf1cb1e3..8cf3ffc68 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlLookAtTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlLookAtTagHandler.cpp
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Gaurav Gupta <1989.gaurav@googlemail.com>
//
#include "KmlLookAtTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLookAt.h"
#include "GeoParser.h"
#include "GeoDataFeature.h"
#include "GeoDataFlyTo.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( LookAt )
GeoNode *KmlLookAtTagHandler::parse( GeoParser & parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_LookAt)));
GeoDataLookAt *lookAt = new GeoDataLookAt();
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataFeature>() ) {
GeoDataFeature *feature = parentItem.nodeAs<GeoDataFeature>();
feature->setAbstractView( lookAt );
return lookAt;
} if ( parentItem.is<GeoDataFlyTo>() ) {
GeoDataFlyTo *feature = parentItem.nodeAs<GeoDataFlyTo>();
feature->setView( lookAt );
return lookAt;
} else {
delete lookAt;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMarblePlacemarkTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMarblePlacemarkTagHandler.cpp
index d333aad83..a33268c2d 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMarblePlacemarkTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMarblePlacemarkTagHandler.cpp
@@ -1,59 +1,59 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
#ifdef KML_LAZY_IMP
#include "KmlMarblePlacemarkTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataContainer.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( MarblePlacemark )
GeoNode* KmlMarblePlacemarkTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_MarblePlacemark)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ) {
GeoDataPlacemark *placemark = new GeoDataPlacemark;
parentItem.nodeAs<GeoDataContainer>()->append( placemark );
return placemark;
} else {
- return 0;
+ return nullptr;
}
}
}
}
#endif
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMaxAltitudeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMaxAltitudeTagHandler.cpp
index 60cc95c46..ee615e888 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMaxAltitudeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMaxAltitudeTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlMaxAltitudeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( maxAltitude )
GeoNode* KmlmaxAltitudeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_maxAltitude)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_LatLonAltBox ) ) {
float maxAltitude = parser.readElementText().trimmed().toFloat();
parentItem.nodeAs<GeoDataLatLonAltBox>()->setMaxAltitude( maxAltitude );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMaxFadeExtentTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMaxFadeExtentTagHandler.cpp
index cba403a07..6d09e69a2 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMaxFadeExtentTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMaxFadeExtentTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlMaxFadeExtentTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLod.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( maxFadeExtent )
GeoNode* KmlmaxFadeExtentTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_maxFadeExtent)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Lod ) ) {
float maxFadeExtent = parser.readElementText().trimmed().toFloat();
parentItem.nodeAs<GeoDataLod>()->setMaxFadeExtent( maxFadeExtent );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMaxHeightTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMaxHeightTagHandler.cpp
index 8b237e7d1..5e300da4a 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMaxHeightTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMaxHeightTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlMaxHeightTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataImagePyramid.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( maxHeight )
GeoNode* KmlmaxHeightTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_maxHeight)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ImagePyramid ))
{
int maxHeight = parser.readElementText().toInt();
parentItem.nodeAs<GeoDataImagePyramid>()->setMaxHeight( maxHeight );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMaxLodPixelsTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMaxLodPixelsTagHandler.cpp
index 498fd6b75..2c307ebe9 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMaxLodPixelsTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMaxLodPixelsTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlMaxLodPixelsTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLod.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( maxLodPixels )
GeoNode* KmlmaxLodPixelsTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_maxLodPixels)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Lod ) ) {
float maxLodPixels = parser.readElementText().trimmed().toFloat();
parentItem.nodeAs<GeoDataLod>()->setMaxLodPixels( maxLodPixels );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMaxSessionLengthTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMaxSessionLengthTagHandler.cpp
index f8a46c648..e37307b07 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMaxSessionLengthTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMaxSessionLengthTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlMaxSessionLengthTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( maxSessionLength )
GeoNode* KmlmaxSessionLengthTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_maxSessionLength)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
qreal maxSessionLength = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setMaxSessionLength( maxSessionLength );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMaxWidthTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMaxWidthTagHandler.cpp
index b1974399b..0d77fb4ea 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMaxWidthTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMaxWidthTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlMaxWidthTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataImagePyramid.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( maxWidth )
GeoNode* KmlmaxWidthTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_maxWidth)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ImagePyramid ))
{
int maxWidth = parser.readElementText().toInt();
parentItem.nodeAs<GeoDataImagePyramid>()->setMaxWidth( maxWidth );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMemberTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMemberTagHandler.cpp
index 33b0cb507..74e13d3f7 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMemberTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMemberTagHandler.cpp
@@ -1,67 +1,67 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com>
//
#include "KmlMemberTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoDataGeometry.h"
#include "GeoDataTypes.h"
#include "KmlElementDictionary.h"
#include "osm/OsmPlacemarkData.h"
#include "GeoParser.h"
#include <QtDebug>
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_MX( member )
GeoNode* KmlmemberTagHandler::parse( GeoParser& parser ) const
{
int memberIndex = parser.attribute( "index" ).toInt();
/* Only possible case: member of polygon placemark:
*...
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* <mx:member index="-1">
* <mx:OsmPlacemarkData>
* <mx:nd index="0">...</nd>
* <mx:nd index="1">...</nd>
* ...
*/
if( parser.parentElement( 2 ).is<GeoDataPlacemark>() ) {
GeoDataPlacemark *placemark = parser.parentElement( 2 ).nodeAs<GeoDataPlacemark>();
GeoDataPolygon *polygon = geodata_cast<GeoDataPolygon>(placemark->geometry());
if (!polygon) {
- return 0;
+ return nullptr;
}
// The memberIndex is used to determine which member this tag represents
if ( memberIndex == -1 ) {
return &polygon->outerBoundary();
}
else {
if ( memberIndex >= polygon->innerBoundaries().size() ) {
- return 0;
+ return nullptr;
}
return &polygon->innerBoundaries()[ memberIndex ];
}
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMessageTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMessageTagHandler.cpp
index 68b2e5281..b359e9554 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMessageTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMessageTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlMessageTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( message )
GeoNode* KmlmessageTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_message)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
QString message = parser.readElementText();
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setMessage( message );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMinAltitudeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMinAltitudeTagHandler.cpp
index a1864c41f..272eca0b7 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMinAltitudeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMinAltitudeTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlMinAltitudeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( minAltitude )
GeoNode* KmlminAltitudeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_minAltitude)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_LatLonAltBox ) ) {
float minAltitude = parser.readElementText().trimmed().toFloat();
parentItem.nodeAs<GeoDataLatLonAltBox>()->setMinAltitude( minAltitude );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMinFadeExtentTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMinFadeExtentTagHandler.cpp
index 3ed2019df..e54e50c59 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMinFadeExtentTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMinFadeExtentTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlMinFadeExtentTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLod.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( minFadeExtent )
GeoNode* KmlminFadeExtentTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_minFadeExtent)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Lod ) ) {
float minFadeExtent = parser.readElementText().trimmed().toFloat();
parentItem.nodeAs<GeoDataLod>()->setMinFadeExtent( minFadeExtent );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMinLodPixelsTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMinLodPixelsTagHandler.cpp
index 061ff1bdb..b8fe53bd3 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMinLodPixelsTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMinLodPixelsTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlMinLodPixelsTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLod.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( minLodPixels )
GeoNode* KmlminLodPixelsTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_minLodPixels)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Lod ) ) {
float minLodPixels = parser.readElementText().trimmed().toFloat();
parentItem.nodeAs<GeoDataLod>()->setMinLodPixels( minLodPixels );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMinRefreshPeriodTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMinRefreshPeriodTagHandler.cpp
index 71dd87bf3..e48e25e74 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMinRefreshPeriodTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMinRefreshPeriodTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlMinRefreshPeriodTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( minRefreshPeriod )
GeoNode* KmlminRefreshPeriodTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_minRefreshPeriod)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) )
{
qreal minRefreshPeriod = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataNetworkLinkControl>()->setMinRefreshPeriod( minRefreshPeriod );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlModelTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlModelTagHandler.cpp
index 22db1673e..5dfebce46 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlModelTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlModelTagHandler.cpp
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlModelTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataModel.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataPlacemark.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Model )
GeoNode* KmlModelTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Model)));
GeoDataModel *model = new GeoDataModel;
KmlObjectTagHandler::parseIdentifiers( parser, model );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Placemark ) ) {
parentItem.nodeAs<GeoDataPlacemark>()->setGeometry( model );
return model;
} else if( parentItem.represents( kmlTag_MultiGeometry ) ) {
parentItem.nodeAs<GeoDataMultiGeometry>()->append( model );
return model;
} else {
delete model;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMultiGeometryTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMultiGeometryTagHandler.cpp
index e4e3920b6..264f79c86 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMultiGeometryTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMultiGeometryTagHandler.cpp
@@ -1,61 +1,61 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlMultiGeometryTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoDataMultiGeometry.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( MultiGeometry )
GeoNode* KmlMultiGeometryTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_MultiGeometry)));
GeoStackItem parentItem = parser.parentElement();
GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
KmlObjectTagHandler::parseIdentifiers( parser, geom );
if( parentItem.represents( kmlTag_Placemark ) ) {
parentItem.nodeAs<GeoDataPlacemark>()->setGeometry( geom );
return parentItem.nodeAs<GeoDataPlacemark>()->geometry();
} else if( parentItem.represents( kmlTag_MultiGeometry ) ) {
parentItem.nodeAs<GeoDataMultiGeometry>()->append( geom );
return geom;
} else {
delete geom;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMultiTrackTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMultiTrackTagHandler.cpp
index bad5fad14..4a2b76dac 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMultiTrackTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMultiTrackTagHandler.cpp
@@ -1,51 +1,51 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Thibaut Gridel <tgridel@free.fr>
#include "KmlMultiTrackTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataMultiTrack.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( MultiTrack )
GeoNode* KmlMultiTrackTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_MultiTrack)));
GeoStackItem parentItem = parser.parentElement();
GeoDataMultiTrack *geom = new GeoDataMultiTrack;
KmlObjectTagHandler::parseIdentifiers( parser, geom );
if( parentItem.represents( kmlTag_Placemark ) ) {
parentItem.nodeAs<GeoDataPlacemark>()->setGeometry( geom );
return parentItem.nodeAs<GeoDataPlacemark>()->geometry();
} else if( parentItem.represents( kmlTag_MultiGeometry ) ) {
parentItem.nodeAs<GeoDataMultiGeometry>()->append( geom );
return geom;
} else {
delete geom;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlMxSizeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlMxSizeTagHandler.cpp
index 9103c6f09..d9dfd8d92 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlMxSizeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlMxSizeTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2016 Dennis Nienhüser <nienhueser@kde.org>
//
#include "KmlMxSizeTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataIconStyle.h"
#include "GeoParser.h"
#include "MarbleDebug.h"
namespace Marble
{
namespace kml
{
namespace mx
{
KML_DEFINE_TAG_HANDLER_MX( size )
GeoNode* KmlsizeTagHandler::parse( GeoParser& parser ) const
{
if ( parser.parentElement().is<GeoDataIconStyle>() ) {
auto const width = parser.attribute(kmlTag_width).toInt();
auto const height = parser.attribute(kmlTag_height).toInt();
auto const size = QSize(width, height);
if (size.isEmpty()) {
mDebug() << "Invalid size in icon style: width=" << width << ", height=" << height;
} else {
parser.parentElement().nodeAs<GeoDataIconStyle>()->setSize(size);
}
}
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlNameTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlNameTagHandler.cpp
index c14d3b333..7a1ffd87e 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlNameTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlNameTagHandler.cpp
@@ -1,51 +1,51 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlNameTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( name )
GeoNode* KmlnameTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_name)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataFeature>() ) {
QString name = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataFeature>()->setName( name );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlNdTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlNdTagHandler.cpp
index d9f3141d3..f6bb09ad4 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlNdTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlNdTagHandler.cpp
@@ -1,76 +1,76 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com>
//
// Self
#include "KmlNdTagHandler.h"
// Marble
#include "KmlElementDictionary.h"
#include "GeoDataExtendedData.h"
#include "GeoDataGeometry.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLineString.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoDataPoint.h"
#include "osm/OsmPlacemarkData.h"
// Qt
#include <QDebug>
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_MX( nd )
GeoNode* KmlndTagHandler::parse( GeoParser& parser ) const
{
int ndIndex = parser.attribute( "index" ).toInt();
/* Case 1: node of a line placemark:
*...
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* <mx:nd index="0">...</nd>
* <mx:nd index="1">...</nd>
* ...
*/
if( parser.parentElement().represents( kmlTag_OsmPlacemarkData ) && parser.parentElement( 2 ).is<GeoDataPlacemark>() ) {
GeoDataPlacemark *placemark = parser.parentElement( 2 ).nodeAs<GeoDataPlacemark>();
if (auto lineString = geodata_cast<GeoDataLineString>(placemark->geometry())) {
// Using GeoDataPoint because GeoDataCoordinates is not a GeoNode, so it can't be returned.
GeoDataPoint *point = new GeoDataPoint( lineString->at( ndIndex ) );
return point;
}
- return 0;
+ return nullptr;
}
/* Case 2: node of a polygon's boundary
*...
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* <mx:member>
* <mx:OsmPlacemarkData>
* <mx:nd index="0">...</nd>
* <mx:nd index="1">...</nd>
* ...
*/
else if ( parser.parentElement().represents( kmlTag_OsmPlacemarkData ) && parser.parentElement( 1 ).is<GeoDataLinearRing>() ) {
GeoDataLinearRing *linearRing = parser.parentElement( 1 ).nodeAs<GeoDataLinearRing>();
// Using GeoDataPoint because GeoDataCoordinates is not a GeoNode, so it can't be returned.
GeoDataPoint *point = new GeoDataPoint( linearRing->at( ndIndex ) );
return point;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlNearTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlNearTagHandler.cpp
index 8d66fcd77..afb389a8d 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlNearTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlNearTagHandler.cpp
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlNearTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataViewVolume.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( near )
GeoNode* KmlnearTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_near)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ViewVolume ))
{
qreal near = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataViewVolume>()->setNear( near );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkControlTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkControlTagHandler.cpp
index 5b7ea757a..cdeee7766 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkControlTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkControlTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlNetworkLinkControlTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( NetworkLinkControl )
GeoNode* KmlNetworkLinkControlTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_NetworkLinkControl)));
GeoStackItem parentItem = parser.parentElement();
GeoDataNetworkLinkControl *networkLinkControl = new GeoDataNetworkLinkControl;
if ( parentItem.qualifiedName().first == kmlTag_kml ) {
GeoDataDocument* doc = geoDataDoc( parser );
doc->append( networkLinkControl );
return networkLinkControl;
} else {
delete networkLinkControl;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkTagHandler.cpp
index e8c02b241..6bbac5894 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlNetworkLinkTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlNetworkLinkTagHandler.h"
#include "GeoDataNetworkLink.h"
#include "GeoDataContainer.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( NetworkLink )
GeoNode* KmlNetworkLinkTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_NetworkLink)));
GeoDataNetworkLink *networkLink = new GeoDataNetworkLink;
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ) {
parentItem.nodeAs<GeoDataContainer>()->append( networkLink );
return networkLink;
} else if ( parentItem.qualifiedName().first == kmlTag_kml ) {
GeoDataDocument* doc = geoDataDoc( parser );
doc->append( networkLink );
return networkLink;
} else {
delete networkLink;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlNorthTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlNorthTagHandler.cpp
index 7e70ae56e..90e91762c 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlNorthTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlNorthTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlNorthTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( north )
GeoNode* KmlnorthTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_north)));
GeoStackItem parentItem = parser.parentElement();
qreal const north = parser.readElementText().trimmed().toDouble();
if( parentItem.represents( kmlTag_LatLonAltBox ) ) {
parentItem.nodeAs<GeoDataLatLonAltBox>()->setNorth( north, GeoDataCoordinates::Degree );
} else if ( parentItem.represents( kmlTag_LatLonBox ) ) {
parentItem.nodeAs<GeoDataLatLonBox>()->setNorth( north, GeoDataCoordinates::Degree );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlOpenTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlOpenTagHandler.cpp
index fc8fa4f56..6ef814b71 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlOpenTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlOpenTagHandler.cpp
@@ -1,55 +1,55 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlOpenTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( open )
GeoNode* KmlopenTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_open)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataFeature>() ) {
QString open = parser.readElementText().trimmed();
/* if (open == QLatin1String("1"))
parentItem.nodeAs<GeoDataFeature>()->setOpen( true );
else
parentItem.nodeAs<GeoDataFeature>()->setOpen( false );*/
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlOrientationTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlOrientationTagHandler.cpp
index 2d7b20cbd..b3a5301bb 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlOrientationTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlOrientationTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlOrientationTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataOrientation.h"
#include "GeoDataGeometry.h"
#include "GeoDataModel.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Orientation )
GeoNode* KmlOrientationTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Orientation)));
GeoDataOrientation orientation;
KmlObjectTagHandler::parseIdentifiers( parser, &orientation );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Model ) ) {
parentItem.nodeAs<GeoDataModel>()->setOrientation(orientation);
return &parentItem.nodeAs<GeoDataModel>()->orientation();
}
else{
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlOsmPlacemarkDataTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlOsmPlacemarkDataTagHandler.cpp
index 83b7e6b24..ccc01f9bc 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlOsmPlacemarkDataTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlOsmPlacemarkDataTagHandler.cpp
@@ -1,95 +1,95 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com>
//
// Marble
#include "KmlOsmPlacemarkDataTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataExtendedData.h"
#include "GeoDataGeometry.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoDataData.h"
#include "GeoParser.h"
#include "GeoDataPoint.h"
#include "osm/OsmPlacemarkData.h"
#include <QVariant>
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_MX( OsmPlacemarkData )
GeoNode* KmlOsmPlacemarkDataTagHandler::parse( GeoParser& parser ) const
{
OsmPlacemarkData osmData = OsmPlacemarkData::fromParserAttributes( parser.attributes() );
/* Case 1: This is the main OsmPlacemarkData of a placemark:
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* ...
*/
if (parser.parentElement().is<GeoDataExtendedData>() && parser.parentElement(1).is<GeoDataPlacemark>()) {
auto placemark = parser.parentElement(1).nodeAs<GeoDataPlacemark>();
placemark->setOsmData(osmData);
return &placemark->osmData();
}
/* Case 2: This is the OsmPlacemarkData of a Nd
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* <mx:nd>
* <mx:OsmPlacemarkData>
* ...
*/
else if ( parser.parentElement( 1 ).is<OsmPlacemarkData>() && parser.parentElement().is<GeoDataPoint>() ) {
OsmPlacemarkData* placemarkOsmData = parser.parentElement( 1 ).nodeAs<OsmPlacemarkData>();
GeoDataPoint *point = parser.parentElement().nodeAs<GeoDataPoint>();
GeoDataCoordinates coordinates = point->coordinates();
/* The GeoDataPoint object was only used as GeoNode wrapper for the GeoDataCoordinates
* and it is no longer needed
*/
delete point;
placemarkOsmData->addNodeReference( coordinates, osmData );
return &placemarkOsmData->nodeReference( coordinates );
}
/* Case 3: This is the OsmPlacemarkData of a polygon's member
* <Placemark>
* <ExtendedData>
* <mx:OsmPlacemarkData>
* <mx:member>
* <mx:OsmPlacemarkData>
* ...
*/
else if ( parser.parentElement( 1 ).is<OsmPlacemarkData>() && parser.parentElement().is<GeoDataLinearRing>()
&& parser.parentElement( 3 ).is<GeoDataPlacemark>() ) {
OsmPlacemarkData *placemarkOsmData = parser.parentElement( 1 ).nodeAs<OsmPlacemarkData>();
GeoDataPlacemark *placemark = parser.parentElement( 3 ).nodeAs<GeoDataPlacemark>();
GeoDataLinearRing &ring = *parser.parentElement().nodeAs<GeoDataLinearRing>();
GeoDataPolygon *polygon = geodata_cast<GeoDataPolygon>(placemark->geometry());
if (!polygon) {
- return 0;
+ return nullptr;
}
/* The QVector's indexOf function is perfect: returns the index of the ring
* within the vector if the ring is an innerBoundary;
* Else it returns -1, meaning it's an outerBoundary
*/
int memberIndex = polygon->innerBoundaries().indexOf( ring );
placemarkOsmData->addMemberReference( memberIndex, osmData );
return &placemarkOsmData->memberReference( memberIndex );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlOutlineTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlOutlineTagHandler.cpp
index 2a60aa087..cf8357418 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlOutlineTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlOutlineTagHandler.cpp
@@ -1,52 +1,52 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlOutlineTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPolyStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( outline )
GeoNode* KmloutlineTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_outline)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_PolyStyle ) ) {
bool outline = static_cast<bool>( parser.readElementText().trimmed().toInt() );
parentItem.nodeAs<GeoDataPolyStyle>()->setOutline( outline );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlOverlayXYTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlOverlayXYTagHandler.cpp
index ac1248793..f074f98a9 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlOverlayXYTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlOverlayXYTagHandler.cpp
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlOverlayXYTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataParser.h"
#include "MarbleGlobal.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( overlayXY )
GeoNode* KmloverlayXYTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_overlayXY)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ScreenOverlay ))
{
GeoDataVec2 vec2(parser.attribute("x").trimmed().toFloat(),
parser.attribute("y").trimmed().toFloat(),
parser.attribute("xunits").trimmed(),
parser.attribute("yunits").trimmed());
parentItem.nodeAs<GeoDataScreenOverlay>()->setOverlayXY( vec2 );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPairTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPairTagHandler.cpp
index 199624338..6e054b559 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPairTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPairTagHandler.cpp
@@ -1,51 +1,51 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlPairTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataStyleMap.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Pair )
GeoNode* KmlPairTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Pair)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_StyleMap ) ) {
return parentItem.nodeAs<GeoDataStyleMap>();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPhotoOverlayTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPhotoOverlayTagHandler.cpp
index 8de843af0..3bd33a3a2 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPhotoOverlayTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPhotoOverlayTagHandler.cpp
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "KmlPhotoOverlayTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataContainer.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( PhotoOverlay )
GeoNode* KmlPhotoOverlayTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_PhotoOverlay)));
GeoDataPhotoOverlay *overlay = new GeoDataPhotoOverlay;
KmlObjectTagHandler::parseIdentifiers( parser, overlay );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ||
parentItem.represents( kmlTag_Change ) || parentItem.represents( kmlTag_Create ) || parentItem.represents( kmlTag_Delete ) ) {
parentItem.nodeAs<GeoDataContainer>()->append( overlay );
return overlay;
} else if ( parentItem.qualifiedName().first == kmlTag_kml ) {
GeoDataDocument* doc = geoDataDoc( parser );
doc->append( overlay );
return overlay;
} else {
delete overlay;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPlacemarkTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPlacemarkTagHandler.cpp
index 903e31ae8..d04935fac 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPlacemarkTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPlacemarkTagHandler.cpp
@@ -1,63 +1,63 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlPlacemarkTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataContainer.h"
#include "GeoDataPlacemark.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Placemark )
GeoNode* KmlPlacemarkTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Placemark)));
GeoDataPlacemark *placemark = new GeoDataPlacemark;
KmlObjectTagHandler::parseIdentifiers( parser, placemark );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ||
parentItem.represents( kmlTag_Change ) || parentItem.represents( kmlTag_Create ) || parentItem.represents( kmlTag_Delete ) ){
parentItem.nodeAs<GeoDataContainer>()->append( placemark );
return placemark;
} else if ( parentItem.qualifiedName().first == kmlTag_kml ) {
GeoDataDocument* doc = geoDataDoc(parser);
doc->append( placemark );
return placemark;
} else {
delete placemark;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPlaylistTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPlaylistTagHandler.cpp
index 1f42ec954..17aa90121 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPlaylistTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPlaylistTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "KmlPlaylistTagHandler.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataPlaylist.h"
#include "GeoDataTour.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( Playlist )
GeoNode* KmlPlaylistTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Playlist)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.is<GeoDataTour>()) {
GeoDataPlaylist *playlist = new GeoDataPlaylist;
KmlObjectTagHandler::parseIdentifiers( parser, playlist );
parentItem.nodeAs<GeoDataTour>()->setPlaylist(playlist);
return playlist;
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPointTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPointTagHandler.cpp
index a44662f97..98feca240 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPointTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPointTagHandler.cpp
@@ -1,63 +1,63 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlPointTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Point )
GeoNode* KmlPointTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Point)));
// FIXME: there needs to be a check that a coordinates subtag is contained
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Placemark ) ) {
return parentItem.nodeAs<GeoDataPlacemark>();
} else if( parentItem.represents( kmlTag_MultiGeometry ) ) {
GeoDataPoint *point = new GeoDataPoint;
KmlObjectTagHandler::parseIdentifiers( parser, point );
parentItem.nodeAs<GeoDataMultiGeometry>()->append( point );
return point;
} else if( parentItem.represents( kmlTag_PhotoOverlay ) ) {
GeoDataPoint *point = &parentItem.nodeAs<GeoDataPhotoOverlay>()->point();
KmlObjectTagHandler::parseIdentifiers( parser, point );
return point;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPolyStyleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPolyStyleTagHandler.cpp
index 9068e9329..69203696c 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPolyStyleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPolyStyleTagHandler.cpp
@@ -1,55 +1,55 @@
/*
Copyright (C) 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlPolyStyleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataStyle.h"
#include "GeoDataPolyStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( PolyStyle )
GeoNode* KmlPolyStyleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_PolyStyle)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_Style ) ) {
GeoDataPolyStyle style;
KmlObjectTagHandler::parseIdentifiers( parser, &style );
parentItem.nodeAs<GeoDataStyle>()->setPolyStyle( style );
return &parentItem.nodeAs<GeoDataStyle>()->polyStyle();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPolygonTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPolygonTagHandler.cpp
index 5f2b38498..3a90df8fb 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPolygonTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPolygonTagHandler.cpp
@@ -1,63 +1,63 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlPolygonTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataPlacemark.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataPolygon.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Polygon )
GeoNode* KmlPolygonTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Polygon)));
GeoStackItem parentItem = parser.parentElement();
GeoDataPolygon *polygon = new GeoDataPolygon;
KmlObjectTagHandler::parseIdentifiers( parser, polygon );
if( parentItem.represents( kmlTag_Placemark ) ) {
parentItem.nodeAs<GeoDataPlacemark>()->setGeometry( polygon );
return parentItem.nodeAs<GeoDataPlacemark>()->geometry();
} else if( parentItem.represents( kmlTag_MultiGeometry ) ) {
parentItem.nodeAs<GeoDataMultiGeometry>()->append( polygon );
return polygon;
} else {
delete polygon;
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlPopTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlPopTagHandler.cpp
index 617c09bbe..ae9a17562 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlPopTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlPopTagHandler.cpp
@@ -1,57 +1,57 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
#if KML_LAZY_IMP
#include "KmlPopTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPlacemark.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( pop )
GeoNode* KmlpopTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_pop)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataPlacemark>() ) {
QString population = parser.readElementText().trimmed();
qint64 pop = population.toLongLong();
if( pop < 0 ) pop = 0;
parentItem.nodeAs<GeoDataPlacemark>()->setPopulation( pop );
}
- return 0;
+ return nullptr;
}
}
}
#endif //KML_LAZY_IMP
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRangeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRangeTagHandler.cpp
index c3e682cef..95a55be60 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRangeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRangeTagHandler.cpp
@@ -1,37 +1,37 @@
#include "KmlRangeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "MarbleGlobal.h"
#include "GeoDataLookAt.h"
#include "GeoParser.h"
#include "GeoDataCoordinates.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER (range)
GeoNode *KmlrangeTagHandler::parse (GeoParser & parser) const
{
Q_ASSERT (parser.isStartElement ()
&& parser.isValidElement (kmlTag_range));
GeoStackItem parentItem = parser.parentElement ();
if ( parentItem.is<GeoDataLookAt>() ){
QString rangeTemp = parser.readElementText().trimmed();
qreal range = rangeTemp.toDouble();
parentItem.nodeAs<GeoDataLookAt>()->setRange( range );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRefreshIntervalTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRefreshIntervalTagHandler.cpp
index ec475b88a..9566b3c06 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRefreshIntervalTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRefreshIntervalTagHandler.cpp
@@ -1,35 +1,35 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlRefreshIntervalTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataLink.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( refreshInterval )
GeoNode *KmlrefreshIntervalTagHandler::parse(GeoParser & parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_refreshInterval)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataLink>() ) {
qreal const refreshInterval = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataLink>()->setRefreshInterval( refreshInterval );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRefreshModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRefreshModeTagHandler.cpp
index d506d1958..abd4ebaa4 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRefreshModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRefreshModeTagHandler.cpp
@@ -1,41 +1,41 @@
#include "KmlRefreshModeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLink.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( refreshMode )
GeoNode* KmlrefreshModeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_refreshMode)));
GeoStackItem parentItem = parser.parentElement();
QString content = parser.readElementText().trimmed();
GeoDataLink::RefreshMode mode;
if ( parentItem.is<GeoDataLink>()) {
if (content == QLatin1String("onChange")) {
mode = GeoDataLink::OnChange;
} else if (content == QLatin1String("onExpire")) {
mode = GeoDataLink::OnExpire;
} else if (content == QLatin1String("onInterval")) {
mode = GeoDataLink::OnInterval;
} else {
mode = GeoDataLink::OnChange;
mDebug() << "Value " << content << "set in kml file is invalid."
<< "Value of <refreshMode> has been reset to onChange" ;
}
parentItem.nodeAs<GeoDataLink>()->setRefreshMode( mode );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRefreshVisibilityTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRefreshVisibilityTagHandler.cpp
index 26d2b7a26..403277584 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRefreshVisibilityTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRefreshVisibilityTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlRefreshVisibilityTagHandler.h"
#include "GeoDataNetworkLink.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
#include "MarbleDebug.h"
#include "MarbleGlobal.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( refreshVisibility )
GeoNode *KmlrefreshVisibilityTagHandler::parse(GeoParser & parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_refreshVisibility)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataNetworkLink>() ) {
QString content = parser.readElementText().trimmed();
GeoDataNetworkLink* networkLink = parentItem.nodeAs<GeoDataNetworkLink>();
networkLink->setRefreshVisibility(content == QLatin1String("1"));
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRegionTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRegionTagHandler.cpp
index 81d283a74..3cf6ceecd 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRegionTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRegionTagHandler.cpp
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlRegionTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
#include "GeoDataRegion.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Region )
GeoNode* KmlRegionTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Region)));
GeoDataRegion region;
KmlObjectTagHandler::parseIdentifiers( parser, &region );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataFeature>() ) {
parentItem.nodeAs<GeoDataFeature>()->setRegion( region );
return &parentItem.nodeAs<GeoDataFeature>()->region();
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlResourceMapTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlResourceMapTagHandler.cpp
index dbfb2a360..ef3437b05 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlResourceMapTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlResourceMapTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlResourceMapTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataScale.h"
#include "GeoDataGeometry.h"
#include "GeoDataModel.h"
#include "GeoDataResourceMap.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( ResourceMap )
GeoNode* KmlResourceMapTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_ResourceMap)));
GeoDataResourceMap map;
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Model ) ) {
parentItem.nodeAs<GeoDataModel>()->setResourceMap(map);
return &parentItem.nodeAs<GeoDataModel>()->resourceMap();
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRightFovTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRightFovTagHandler.cpp
index de5ec2314..12d4d6bec 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRightFovTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRightFovTagHandler.cpp
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlRightFovTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataViewVolume.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( rightFov )
GeoNode* KmlrightFovTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_rightFov)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ViewVolume ))
{
qreal rightFov = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataViewVolume>()->setRightFov( rightFov );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRoleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRoleTagHandler.cpp
index a120625d3..1eb6f90c5 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRoleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRoleTagHandler.cpp
@@ -1,58 +1,58 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
#if KML_LAZY_IMP
#include "KmlRoleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPlacemark.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( role )
GeoNode* KmlroleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_role)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataPlacemark>() ) {
QString role = parser.readElementText().trimmed();
if ( role.isEmpty() ) {
role = QLatin1Char(' ');
}
parentItem.nodeAs<GeoDataPlacemark>()->setRole( role );
}
- return 0;
+ return nullptr;
}
}
}
#endif // KML_LAZY_IMP
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRollTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRollTagHandler.cpp
index 4f209ac7c..07b4e8e76 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRollTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRollTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlRollTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataCamera.h"
#include "GeoParser.h"
#include "GeoDataOrientation.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( roll )
GeoNode* KmlrollTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_roll)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataCamera>() ) {
qreal roll = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataCamera>()->setRoll(roll);
} else if (parentItem.is<GeoDataOrientation>() ) {
qreal roll = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataOrientation>()->setRoll(roll);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRotationTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRotationTagHandler.cpp
index 12ea75649..56208a3d2 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRotationTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRotationTagHandler.cpp
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlRotationTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataLatLonBox.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( rotation )
GeoNode* KmlrotationTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_rotation)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ScreenOverlay ))
{
qreal rotation = parser.readElementText().toFloat();
parentItem.nodeAs<GeoDataScreenOverlay>()->setRotation( rotation );
}
else if (parentItem.represents( kmlTag_LatLonBox ))
{
qreal rotation = parser.readElementText().toFloat();
parentItem.nodeAs<GeoDataLatLonBox>()->setRotation( rotation * DEG2RAD );
}
else if (parentItem.represents( kmlTag_PhotoOverlay ))
{
qreal rotation = parser.readElementText().toFloat();
parentItem.nodeAs<GeoDataPhotoOverlay>()->setRotation( rotation );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlRotationXYTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlRotationXYTagHandler.cpp
index 4b2270b95..731f62bf2 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlRotationXYTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlRotationXYTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlRotationXYTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( rotationXY )
GeoNode* KmlrotationXYTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_rotationXY)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ScreenOverlay ))
{
GeoDataVec2 vec2(parser.attribute("x").trimmed().toFloat(),
parser.attribute("y").trimmed().toFloat(),
parser.attribute("xunits").trimmed(),
parser.attribute("yunits").trimmed());
parentItem.nodeAs<GeoDataScreenOverlay>()->setRotationXY( vec2 );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlScaleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlScaleTagHandler.cpp
index cc3116812..8c86191cc 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlScaleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlScaleTagHandler.cpp
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlScaleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataScale.h"
#include "GeoDataGeometry.h"
#include "GeoDataModel.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Scale )
GeoNode* KmlScaleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Scale)));
GeoDataScale scale;
KmlObjectTagHandler::parseIdentifiers( parser, &scale );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Model ) ) {
parentItem.nodeAs<GeoDataModel>()->setScale(scale);
return &parentItem.nodeAs<GeoDataModel>()->scale();
} else {
- return 0;
+ return nullptr;
}
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSchemaDataTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSchemaDataTagHandler.cpp
index 02532622b..21421d52c 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSchemaDataTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSchemaDataTagHandler.cpp
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "KmlSchemaDataTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataExtendedData.h"
#include "GeoDataSchemaData.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( SchemaData )
GeoNode* KmlSchemaDataTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_SchemaData)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_ExtendedData ) ) {
GeoDataSchemaData schemaData;
QString schemaUrl = parser.attribute( "schemaUrl" ).trimmed();
schemaData.setSchemaUrl( schemaUrl );
parentItem.nodeAs<GeoDataExtendedData>()->addSchemaData( schemaData );
return &parentItem.nodeAs<GeoDataExtendedData>()->schemaData( schemaUrl );
}
- return 0;
+ return nullptr;
}
} //namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSchemaTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSchemaTagHandler.cpp
index 07fe483e2..ababdee9b 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSchemaTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSchemaTagHandler.cpp
@@ -1,59 +1,59 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlSchemaTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataDocument.h"
#include "GeoDataSchema.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Schema )
GeoNode* KmlSchemaTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Schema)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Document ) ) {
GeoDataSchema schema;
KmlObjectTagHandler::parseIdentifiers( parser, &schema );
QString name = parser.attribute( "name" ).trimmed();
schema.setSchemaName( name );
parentItem.nodeAs<GeoDataDocument>()->addSchema( schema );
return &parentItem.nodeAs<GeoDataDocument>()->schema( schema.id() );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlScreenOverlayTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlScreenOverlayTagHandler.cpp
index 88b6eba3e..2f8056e79 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlScreenOverlayTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlScreenOverlayTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlScreenOverlayTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataContainer.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( ScreenOverlay )
GeoNode* KmlScreenOverlayTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_ScreenOverlay)));
GeoDataScreenOverlay *overlay = new GeoDataScreenOverlay();
KmlObjectTagHandler::parseIdentifiers( parser, overlay );
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Folder ) || parentItem.represents( kmlTag_Document ) ||
parentItem.represents( kmlTag_Change ) || parentItem.represents( kmlTag_Create ) || parentItem.represents( kmlTag_Delete ) ) {
parentItem.nodeAs<GeoDataContainer>()->append( overlay );
return overlay;
} else if ( parentItem.qualifiedName().first == kmlTag_kml ) {
GeoDataDocument* doc = geoDataDoc( parser );
doc->append( overlay );
return overlay;
} else {
delete overlay;
- return 0;
+ return nullptr;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlScreenXYTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlScreenXYTagHandler.cpp
index 68285fa52..f70613bb6 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlScreenXYTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlScreenXYTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlScreenXYTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( screenXY )
GeoNode* KmlscreenXYTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_screenXY)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ScreenOverlay ))
{
GeoDataVec2 vec2(parser.attribute("x").trimmed().toFloat(),
parser.attribute("y").trimmed().toFloat(),
parser.attribute("xunits").trimmed(),
parser.attribute("yunits").trimmed());
parentItem.nodeAs<GeoDataScreenOverlay>()->setScreenXY( vec2 );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlShapeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlShapeTagHandler.cpp
index 61b6152cf..34ac2a7ea 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlShapeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlShapeTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlShapeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( shape )
GeoNode* KmlshapeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_shape)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_PhotoOverlay ))
{
GeoDataPhotoOverlay::Shape shape;
QString shapeText = parser.readElementText();
if (shapeText == QLatin1String("rectangle")) {
shape = GeoDataPhotoOverlay::Rectangle;
} else if (shapeText == QLatin1String("cylinder")) {
shape = GeoDataPhotoOverlay::Cylinder;
} else if (shapeText == QLatin1String("sphere")) {
shape = GeoDataPhotoOverlay::Sphere;
} else {
mDebug() << "Unknown shape attribute" << shapeText << ", falling back to default value 'rectangle'";
shape = GeoDataPhotoOverlay::Rectangle;
}
parentItem.nodeAs<GeoDataPhotoOverlay>()->setShape( shape );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSimpleArrayDataTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSimpleArrayDataTagHandler.cpp
index f24ac0496..4abfa620a 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSimpleArrayDataTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSimpleArrayDataTagHandler.cpp
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "KmlSimpleArrayDataTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataExtendedData.h"
#include "GeoDataSimpleArrayData.h"
#include "GeoDataSchemaData.h"
#include "GeoDataTypes.h"
#include "GeoParser.h"
#include "GeoDocument.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( SimpleArrayData )
GeoNode* KmlSimpleArrayDataTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_SimpleArrayData)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataExtendedData>() ) {
GeoDataSimpleArrayData *arrayData = new GeoDataSimpleArrayData();
QString name = parser.attribute( "name" ).trimmed();
parentItem.nodeAs<GeoDataExtendedData>()->setSimpleArrayData( name, arrayData );
return arrayData;
}
if ( parentItem.is<GeoDataSchemaData>() ) {
GeoNode *parent = parentItem.nodeAs<GeoDataSchemaData>()->parent();
if (GeoDataExtendedData *extendedData = geodata_cast<GeoDataExtendedData>(parent)) {
GeoDataSimpleArrayData *arrayData = new GeoDataSimpleArrayData;
const QString name = parser.attribute("name").trimmed();
extendedData->setSimpleArrayData(name, arrayData);
return arrayData;
}
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSimpleDataTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSimpleDataTagHandler.cpp
index cd7780d5d..44b2a135d 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSimpleDataTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSimpleDataTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
#include "KmlSimpleDataTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataSchemaData.h"
#include "GeoDataSimpleData.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( SimpleData )
GeoNode* KmlSimpleDataTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_SimpleData)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_SchemaData ) ) {
GeoDataSimpleData simpleData;
QString name = parser.attribute( "name" ).trimmed();
QString data = parser.readElementText().trimmed();
simpleData.setName( name );
simpleData.setData( data );
parentItem.nodeAs<GeoDataSchemaData>()->addSimpleData( simpleData );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSimpleFieldTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSimpleFieldTagHandler.cpp
index a6239577a..b32bd6578 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSimpleFieldTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSimpleFieldTagHandler.cpp
@@ -1,88 +1,88 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlSimpleFieldTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataSchema.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( SimpleField )
GeoNode* KmlSimpleFieldTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_SimpleField)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Schema ) ) {
GeoDataSimpleField simpleField;
QString name = parser.attribute( "name" ).trimmed();
QString type = parser.attribute( "type" ).trimmed();
simpleField.setName( name );
GeoDataSimpleField::SimpleFieldType fieldType = resolveType( type );
simpleField.setType( fieldType );
parentItem.nodeAs<GeoDataSchema>()->addSimpleField( simpleField );
return &parentItem.nodeAs<GeoDataSchema>()->simpleField( name );
}
- return 0;
+ return nullptr;
}
GeoDataSimpleField::SimpleFieldType KmlSimpleFieldTagHandler::resolveType( const QString& type )
{
GeoDataSimpleField::SimpleFieldType fieldType;
if (type == QLatin1String("string")) {
fieldType = GeoDataSimpleField::String;
}
else if (type == QLatin1String("int")) {
fieldType = GeoDataSimpleField::Int;
}
else if (type == QLatin1String("unit")) {
fieldType = GeoDataSimpleField::UInt;
}
else if (type == QLatin1String("short")) {
fieldType = GeoDataSimpleField::Short;
}
else if (type == QLatin1String("ushort")) {
fieldType = GeoDataSimpleField::UShort;
}
else if (type == QLatin1String("float")) {
fieldType = GeoDataSimpleField::Float;
}
else if (type == QLatin1String("double")) {
fieldType = GeoDataSimpleField::Double;
}
else {
fieldType = GeoDataSimpleField::Bool;
}
return fieldType;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSizeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSizeTagHandler.cpp
index e5611ab94..73cc3a12f 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSizeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSizeTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlSizeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataScreenOverlay.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( size )
GeoNode* KmlsizeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_size)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ScreenOverlay ))
{
GeoDataVec2 vec2(parser.attribute("x").trimmed().toFloat(),
parser.attribute("y").trimmed().toFloat(),
parser.attribute("xunits").trimmed(),
parser.attribute("yunits").trimmed());
parentItem.nodeAs<GeoDataScreenOverlay>()->setSize( vec2 );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSnippetTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSnippetTagHandler.cpp
index 7de61c05b..742b4a072 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSnippetTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSnippetTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Levente Kurusa <levex@linux.com>
//
#include "KmlSnippetTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataFeature.h"
#include "GeoDataParser.h"
#include "GeoDataSnippet.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Snippet )
GeoNode* KmlSnippetTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Snippet)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataFeature>() ) {
QString text = parser.readElementText().trimmed();
int maxLines = parser.attribute( "maxLines" ).trimmed().toInt();
parentItem.nodeAs<GeoDataFeature>()->setSnippet( GeoDataSnippet(text, maxLines) );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSoundCueTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSoundCueTagHandler.cpp
index 013cd136e..aab556bb4 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSoundCueTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSoundCueTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "KmlSoundCueTagHandler.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataPlaylist.h"
#include "GeoDataSoundCue.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( SoundCue )
GeoNode* KmlSoundCueTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_SoundCue)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.is<GeoDataPlaylist>()) {
GeoDataSoundCue *cue = new GeoDataSoundCue;
KmlObjectTagHandler::parseIdentifiers( parser, cue );
parentItem.nodeAs<GeoDataPlaylist>()->addPrimitive(cue);
return cue;
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSourceHrefTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSourceHrefTagHandler.cpp
index bcde45b50..52799e177 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSourceHrefTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSourceHrefTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlSourceHrefTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataAlias.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( sourceHref )
GeoNode* KmlsourceHrefTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_sourceHref)));
GeoStackItem parentItem = parser.parentElement();
QString content = parser.readElementText().trimmed();
if ( parentItem.is<GeoDataAlias>() ){
parentItem.nodeAs<GeoDataAlias>()->setSourceHref( content );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlSouthTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlSouthTagHandler.cpp
index 78c18635d..d79ebe805 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlSouthTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlSouthTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlSouthTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( south )
GeoNode* KmlsouthTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_south)));
GeoStackItem parentItem = parser.parentElement();
qreal const south = parser.readElementText().trimmed().toDouble();
if( parentItem.represents( kmlTag_LatLonAltBox ) ) {
parentItem.nodeAs<GeoDataLatLonAltBox>()->setSouth( south, GeoDataCoordinates::Degree );
} else if ( parentItem.represents( kmlTag_LatLonBox ) ) {
parentItem.nodeAs<GeoDataLatLonBox>()->setSouth( south, GeoDataCoordinates::Degree );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlStateTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlStateTagHandler.cpp
index aaaad52aa..7f4fe13a4 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlStateTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlStateTagHandler.cpp
@@ -1,63 +1,63 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlStateTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataItemIcon.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( state )
GeoNode* KmlstateTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_state)));
GeoStackItem parentItem = parser.parentElement();
GeoDataItemIcon::ItemIconStates itemIconState;
if ( parentItem.represents( kmlTag_ItemIcon ) )
{
QString value = parser.readElementText().trimmed();
QStringList iconStateTextList = value.split(QLatin1Char(' '));
for( const QString &value: iconStateTextList ) {
if (value == QLatin1String("open")) {
itemIconState |= GeoDataItemIcon::Open;
} else if (value == QLatin1String("closed")) {
itemIconState |= GeoDataItemIcon::Closed;
} else if (value == QLatin1String("error")) {
itemIconState |= GeoDataItemIcon::Error;
} else if (value == QLatin1String("fetching0")) {
itemIconState |= GeoDataItemIcon::Fetching0;
} else if (value == QLatin1String("fetching1")) {
itemIconState |= GeoDataItemIcon::Fetching1;
} else if (value == QLatin1String("fetching2")) {
itemIconState |= GeoDataItemIcon::Fetching2;
}
else {
mDebug() << "Cannot parse state value" << value;
}
}
parentItem.nodeAs<GeoDataItemIcon>()->setState( itemIconState );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlStyleMapTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlStyleMapTagHandler.cpp
index ed3845ced..eee4ca7e5 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlStyleMapTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlStyleMapTagHandler.cpp
@@ -1,60 +1,60 @@
/*
Copyright (C) 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlStyleMapTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataFeature.h"
#include "GeoDataDocument.h"
#include "GeoDataStyleMap.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( StyleMap )
GeoNode* KmlStyleMapTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_StyleMap)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Document ) ) {
GeoDataStyleMap styleMap;
KmlObjectTagHandler::parseIdentifiers( parser, &styleMap );
parentItem.nodeAs<GeoDataDocument>()->addStyleMap( styleMap );
return &parentItem.nodeAs<GeoDataDocument>()->styleMap( styleMap.id() );
} else if( parentItem.is<GeoDataFeature>() ) {
/* GeoDataStyleMap styleMap;
parentItem.nodeAs<GeoDataFeature>()->setStyleMap( styleMap );*/
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlStyleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlStyleTagHandler.cpp
index 4da592635..087beedcd 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlStyleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlStyleTagHandler.cpp
@@ -1,63 +1,63 @@
/*
Copyright (C) 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlStyleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataStyle.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
#include "GeoDataDocument.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Style )
GeoNode* KmlStyleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Style)));
GeoStackItem parentItem = parser.parentElement();
/// for documents several styles are allowed: document wide styles are saved different!!!!!
if( parentItem.represents( kmlTag_Document ) ) {
GeoDataStyle::Ptr style(new GeoDataStyle);
KmlObjectTagHandler::parseIdentifiers( parser, style.data() );
parentItem.nodeAs<GeoDataDocument>()->addStyle( style );
return parentItem.nodeAs<GeoDataDocument>()->style( style->id() ).data();
}
else if ( parentItem.represents( kmlTag_Placemark ) ) {
GeoDataStyle::Ptr style(new GeoDataStyle);
KmlObjectTagHandler::parseIdentifiers( parser, style.data() );
parentItem.nodeAs<GeoDataFeature>()->setStyle( style );
return style.data();
}
// FIXME: KMLStyle can be contained in MultiGeometry as well
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlStyleUrlTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlStyleUrlTagHandler.cpp
index 1021eeb37..3d2296009 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlStyleUrlTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlStyleUrlTagHandler.cpp
@@ -1,62 +1,62 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlStyleUrlTagHandler.h"
#include <QString>
#include "KmlElementDictionary.h"
#include "MarbleDebug.h"
#include "GeoDataFeature.h"
#include "GeoDataStyleMap.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( styleUrl )
GeoNode* KmlstyleUrlTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_styleUrl)));
GeoStackItem parentItem = parser.parentElement();
GeoStackItem grandParentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Pair ) ) {
QString content = parser.readElementText().trimmed();
QString key = parentItem.nodeAs<GeoDataStyleMap>()->lastKey();
(*parentItem.nodeAs<GeoDataStyleMap>())[ key ] = content;
parentItem.nodeAs<GeoDataStyleMap>()->setLastKey(QString());
} else if( parentItem.is<GeoDataFeature>() ) {
QString content = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataFeature>()->setStyleUrl( content );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTagTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTagTagHandler.cpp
index 2f111dd56..92c646347 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTagTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTagTagHandler.cpp
@@ -1,38 +1,38 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Marius-Valeriu Stanciu <stanciumarius94@gmail.com>
//
#include "KmlTagTagHandler.h"
#include "KmlElementDictionary.h"
#include "osm/OsmPlacemarkData.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_MX( tag )
GeoNode* KmltagTagHandler::parse( GeoParser& parser ) const
{
if ( parser.parentElement().is<OsmPlacemarkData>() ) {
QString key = parser.attribute( "k" );
QString value = parser.attribute( "v" );
OsmPlacemarkData *osmData = parser.parentElement().nodeAs<OsmPlacemarkData>();
osmData->addTag( key, value );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTargetHrefTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTargetHrefTagHandler.cpp
index af20709a9..e871a4911 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTargetHrefTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTargetHrefTagHandler.cpp
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlTargetHrefTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataAlias.h"
#include "GeoDataUpdate.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( targetHref )
GeoNode* KmltargetHrefTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_targetHref)));
GeoStackItem parentItem = parser.parentElement();
QString content = parser.readElementText().trimmed();
if ( parentItem.is<GeoDataAlias>() ){
parentItem.nodeAs<GeoDataAlias>()->setTargetHref( content );
}
else if ( parentItem.is<GeoDataUpdate>() ){
parentItem.nodeAs<GeoDataUpdate>()->setTargetHref( content );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTessellateTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTessellateTagHandler.cpp
index cba9c8a2e..7fa22aeeb 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTessellateTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTessellateTagHandler.cpp
@@ -1,72 +1,72 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlTessellateTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoDataGeometry.h"
#include "GeoDataPoint.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( tessellate )
GeoNode* KmltessellateTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_tessellate)));
GeoStackItem parentItem = parser.parentElement();
QString content = parser.readElementText().trimmed();
if( parentItem.is<GeoDataLineString>() ) {
GeoDataLineString* lineString = parentItem.nodeAs<GeoDataLineString>();
const bool tesselate = (content == QLatin1String("1"));
lineString->setTessellate(tesselate);
} else if( parentItem.is<GeoDataLinearRing>() ) {
GeoDataLinearRing* linearRing = parentItem.nodeAs<GeoDataLinearRing>();
const bool tesselate = (content == QLatin1String("1"));
linearRing->setTessellate(tesselate);
} else if( parentItem.is<GeoDataPolygon>() ) {
GeoDataPolygon* polygon = parentItem.nodeAs<GeoDataPolygon>();
const bool tesselate = (content == QLatin1String("1"));
polygon->setTessellate(tesselate);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTextColorTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTextColorTagHandler.cpp
index 64082e161..d0c69fb50 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTextColorTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTextColorTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlTextColorTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlColorTagHandler.h"
#include "GeoDataBalloonStyle.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( textColor )
GeoNode* KmltextColorTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_textColor)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_BalloonStyle ) )
{
QColor const color = KmlcolorTagHandler::parseColor( parser.readElementText().trimmed() );
parentItem.nodeAs<GeoDataBalloonStyle>()->setTextColor( color );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTextTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTextTagHandler.cpp
index b7d2b3a17..7c8abaf69 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTextTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTextTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlTextTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataBalloonStyle.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( text )
GeoNode* KmltextTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_text)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_BalloonStyle ) )
{
QString text = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataBalloonStyle>()->setText( text );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTileSizeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTileSizeTagHandler.cpp
index c41dea187..81fe12f30 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTileSizeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTileSizeTagHandler.cpp
@@ -1,41 +1,41 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlTileSizeTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataImagePyramid.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( tileSize )
GeoNode* KmltileSizeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_tileSize)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ImagePyramid ))
{
int tileSize = parser.readElementText().toInt();
parentItem.nodeAs<GeoDataImagePyramid>()->setTileSize( tileSize );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTiltTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTiltTagHandler.cpp
index 2832b2049..6d19917ac 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTiltTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTiltTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlTiltTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataCamera.h"
#include "GeoParser.h"
#include "GeoDataOrientation.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( tilt )
GeoNode* KmltiltTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_tilt)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataCamera>() ){
qreal tilt = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataCamera>()->setTilt(tilt);
} else if ( parentItem.is<GeoDataOrientation>() ){
double tilt = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataOrientation>()->setTilt(tilt);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTimeSpanTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTimeSpanTagHandler.cpp
index 7a8d8ad61..8f2499f07 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTimeSpanTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTimeSpanTagHandler.cpp
@@ -1,43 +1,43 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlTimeSpanTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataTimeSpan.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( TimeSpan )
GeoNode* KmlTimeSpanTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_TimeSpan)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataFeature>() ) {
GeoDataTimeSpan timeSpan;
KmlObjectTagHandler::parseIdentifiers( parser, &timeSpan );
parentItem.nodeAs<GeoDataFeature>()->setTimeSpan( timeSpan );
return &parentItem.nodeAs<GeoDataFeature>()->timeSpan();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTimeStampTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTimeStampTagHandler.cpp
index 16367dd1e..636507a23 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTimeStampTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTimeStampTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlTimeStampTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataTimeStamp.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( TimeStamp )
GeoNode* KmlTimeStampTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_TimeStamp)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataFeature>() ) {
GeoDataTimeStamp timestamp;
KmlObjectTagHandler::parseIdentifiers( parser, &timestamp );
parentItem.nodeAs<GeoDataFeature>()->setTimeStamp( timestamp );
return &parentItem.nodeAs<GeoDataFeature>()->timeStamp();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTopFovTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTopFovTagHandler.cpp
index 991d4d28c..d88e6a2c7 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTopFovTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTopFovTagHandler.cpp
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlTopFovTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataViewVolume.h"
#include "GeoDataParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( topFov )
GeoNode* KmltopFovTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_topFov)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents( kmlTag_ViewVolume ))
{
qreal topFov = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataViewVolume>()->setTopFov( topFov );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTourControlTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTourControlTagHandler.cpp
index 39a54164a..24f5f3c25 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTourControlTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTourControlTagHandler.cpp
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "KmlTourControlTagHandler.h"
#include "KmlPlaylistTagHandler.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataPlaylist.h"
#include "GeoDataTourControl.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( TourControl )
GeoNode* KmlTourControlTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_TourControl)));
GeoStackItem parentItem = parser.parentElement();
GeoDataTourControl *tourControl = new GeoDataTourControl;
KmlObjectTagHandler::parseIdentifiers( parser, tourControl );
if (parentItem.is<GeoDataPlaylist>()) {
//parentItem.nodeAs<GeoDataPlaylist>()->append(tourControl);
parentItem.nodeAs<GeoDataPlaylist>()->addPrimitive(tourControl);
return tourControl;
} else {
delete tourControl;
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTourTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTourTagHandler.cpp
index 851054f70..b797d8ad2 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTourTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTourTagHandler.cpp
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "KmlTourTagHandler.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataTour.h"
#include "GeoDataDocument.h"
#include "GeoDataParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( Tour )
GeoNode* KmlTourTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Tour)));
GeoStackItem parentItem = parser.parentElement();
GeoDataTour *tour = new GeoDataTour;
KmlObjectTagHandler::parseIdentifiers( parser, tour );
if (parentItem.represents(kmlTag_Folder) || parentItem.represents(kmlTag_Document)) {
parentItem.nodeAs<GeoDataContainer>()->append(tour);
return tour;
} else if ( parentItem.qualifiedName().first == kmlTag_kml ) {
GeoDataDocument* doc = geoDataDoc(parser);
doc->append(tour);
return tour;
} else {
delete tour;
- return 0;
+ return nullptr;
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmlTrackTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlTrackTagHandler.cpp
index 3bd9f9a4b..9731de4af 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlTrackTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlTrackTagHandler.cpp
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
//
#include "KmlTrackTagHandler.h"
#include "KmlObjectTagHandler.h"
#include "GeoDataMultiTrack.h"
#include "GeoDataTrack.h"
#include "GeoDataPlacemark.h"
#include "GeoDataMultiGeometry.h"
#include "KmlElementDictionary.h"
#include "MarbleDebug.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( Track )
GeoNode *KmlTrackTagHandler::parse( GeoParser &parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Track)));
GeoStackItem parentItem = parser.parentElement();
GeoDataTrack *track = new GeoDataTrack();
KmlObjectTagHandler::parseIdentifiers( parser, track );
if ( parentItem.represents( kmlTag_Placemark ) ) {
parentItem.nodeAs<GeoDataPlacemark>()->setGeometry( track );
return track;
} else if ( parentItem.represents( kmlTag_MultiTrack ) ) {
parentItem.nodeAs<GeoDataMultiTrack>()->append( track );
return track;
} else if ( parentItem.represents( kmlTag_MultiGeometry ) ) {
parentItem.nodeAs<GeoDataMultiGeometry>()->append( track );
return track;
} else {
delete track;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlUpdateTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlUpdateTagHandler.cpp
index 6cba7a4ee..8629c2fcc 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlUpdateTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlUpdateTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlUpdateTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataNetworkLinkControl.h"
#include "GeoDataUpdate.h"
#include "GeoDataAnimatedUpdate.h"
#include "GeoDataParser.h"
#include "KmlObjectTagHandler.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( Update )
GeoNode* KmlUpdateTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Update)));
GeoDataUpdate *update = new GeoDataUpdate;
KmlObjectTagHandler::parseIdentifiers( parser, update );
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_NetworkLinkControl ) ) {
return &parentItem.nodeAs<GeoDataNetworkLinkControl>()->update();
} else if ( parentItem.represents( kmlTag_AnimatedUpdate ) ) {
parentItem.nodeAs<GeoDataAnimatedUpdate>()->setUpdate( update );
return update;
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlValueTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlValueTagHandler.cpp
index fed2b4d15..dca07dbb4 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlValueTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlValueTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlValueTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataData.h"
#include "GeoDataSimpleArrayData.h"
#include "GeoParser.h"
#include <QVariant>
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( value )
KML_DEFINE_TAG_HANDLER_GX22( value )
GeoNode* KmlvalueTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_value)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_Data ) ) {
QString value = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataData>()->setValue( QVariant( value ) );
} else if( parentItem.represents( kmlTag_SimpleArrayData ) ) {
QString value = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataSimpleArrayData>()->append( QVariant( value ) );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlViewBoundScaleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlViewBoundScaleTagHandler.cpp
index 5ca3bfaf8..b04986559 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlViewBoundScaleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlViewBoundScaleTagHandler.cpp
@@ -1,37 +1,37 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlViewBoundScaleTagHandler.h"
#include "GeoDataLink.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( viewBoundScale )
GeoNode *KmlviewBoundScaleTagHandler::parse(GeoParser & parser) const
{
Q_ASSERT ( parser.isStartElement() && parser.isValidElement( kmlTag_viewBoundScale ) );
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataLink>() ){
qreal const viewBoundScale = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataLink>()->setViewBoundScale( viewBoundScale );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlViewFormatTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlViewFormatTagHandler.cpp
index 2a33dd040..779762f6a 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlViewFormatTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlViewFormatTagHandler.cpp
@@ -1,38 +1,38 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlViewFormatTagHandler.h"
#include "GeoDataLink.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( viewFormat )
GeoNode* KmlviewFormatTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_viewFormat)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(kmlTag_Link)) {
QString content = parser.readElementText().trimmed();
parentItem.nodeAs<GeoDataLink>()->setViewFormat(content);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlViewRefreshModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlViewRefreshModeTagHandler.cpp
index 50c402c1f..d36f2f567 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlViewRefreshModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlViewRefreshModeTagHandler.cpp
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlViewRefreshModeTagHandler.h"
#include "GeoDataLink.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( viewRefreshMode )
GeoNode* KmlviewRefreshModeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_viewRefreshMode)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataLink>() ) {
QString content = parser.readElementText().trimmed();
GeoDataLink::ViewRefreshMode mode = GeoDataLink::Never;
if (content == QLatin1String("onStop")) {
mode = GeoDataLink::OnStop;
} else if (content == QLatin1String("onRegion")) {
mode = GeoDataLink::OnRegion;
} else if (content == QLatin1String("onRequest")) {
mode = GeoDataLink::OnRequest;
}
parentItem.nodeAs<GeoDataLink>()->setViewRefreshMode( mode );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlViewRefreshTimeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlViewRefreshTimeTagHandler.cpp
index 1df8dd366..609530738 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlViewRefreshTimeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlViewRefreshTimeTagHandler.cpp
@@ -1,38 +1,38 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include "KmlViewRefreshTimeTagHandler.h"
#include "GeoDataLink.h"
#include "GeoParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( viewRefreshTime )
GeoNode *KmlviewRefreshTimeTagHandler::parse(GeoParser & parser) const
{
Q_ASSERT ( parser.isStartElement() && parser.isValidElement( kmlTag_viewRefreshTime ) );
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataLink>() ){
qreal const viewRefreshTime = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataLink>()->setViewRefreshTime( viewRefreshTime );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlViewVolumeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlViewVolumeTagHandler.cpp
index 0f3c03f91..b9dde2013 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlViewVolumeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlViewVolumeTagHandler.cpp
@@ -1,37 +1,37 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "KmlViewVolumeTagHandler.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataViewVolume.h"
#include "GeoDataParser.h"
#include "KmlElementDictionary.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( ViewVolume )
GeoNode* KmlViewVolumeTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_ViewVolume)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_PhotoOverlay ) ) {
return &parentItem.nodeAs<GeoDataPhotoOverlay>()->viewVolume();
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlVisibilityTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlVisibilityTagHandler.cpp
index c93091554..8ad8d81c1 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlVisibilityTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlVisibilityTagHandler.cpp
@@ -1,52 +1,52 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlVisibilityTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataFeature.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( visibility )
GeoNode* KmlvisibilityTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_visibility)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.is<GeoDataFeature>() ) {
QString visibility = parser.readElementText().trimmed();
const bool visible = (visibility == QLatin1String("1"));
parentItem.nodeAs<GeoDataFeature>()->setVisible(visible);
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlWaitTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlWaitTagHandler.cpp
index 7e7aa967a..b78b6ea97 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlWaitTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlWaitTagHandler.cpp
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
//
#include "KmlWaitTagHandler.h"
#include "KmlPlaylistTagHandler.h"
#include "KmlElementDictionary.h"
#include "KmlObjectTagHandler.h"
#include "GeoParser.h"
#include "GeoDataPlaylist.h"
#include "GeoDataWait.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( Wait )
GeoNode* KmlWaitTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_Wait)));
GeoStackItem parentItem = parser.parentElement();
GeoDataWait *wait = new GeoDataWait;
KmlObjectTagHandler::parseIdentifiers( parser, wait );
if (parentItem.is<GeoDataPlaylist>()) {
parentItem.nodeAs<GeoDataPlaylist>()->addPrimitive(wait);
return wait;
} else {
delete wait;
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmlWestTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlWestTagHandler.cpp
index e84a4d196..3119cfe37 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlWestTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlWestTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include "KmlWestTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( west )
GeoNode* KmlwestTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_west)));
GeoStackItem parentItem = parser.parentElement();
qreal const west = parser.readElementText().trimmed().toDouble();
if( parentItem.represents( kmlTag_LatLonAltBox ) ) {
parentItem.nodeAs<GeoDataLatLonAltBox>()->setWest( west, GeoDataCoordinates::Degree );
} else if( parentItem.represents( kmlTag_LatLonBox ) ) {
parentItem.nodeAs<GeoDataLatLonBox>()->setWest( west, GeoDataCoordinates::Degree );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlWhenTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlWhenTagHandler.cpp
index 400b0101c..635294b69 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlWhenTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlWhenTagHandler.cpp
@@ -1,83 +1,83 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Harshit Jain <hjain.itbhu@gmail.com>
//
#include "KmlWhenTagHandler.h"
#include "MarbleDebug.h"
#include <QDateTime>
#include "KmlElementDictionary.h"
#include "GeoDataTimeStamp.h"
#include "GeoDataTrack.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( when )
GeoNode* KmlwhenTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_when)));
GeoStackItem parentItem = parser.parentElement();
QString whenString = parser.readElementText().trimmed();
GeoDataTimeStamp::TimeResolution resolution = modify( whenString );
QDateTime when = QDateTime::fromString( whenString, Qt::ISODate );
if( parentItem.represents( kmlTag_TimeStamp ) ) {
parentItem.nodeAs<GeoDataTimeStamp>()->setWhen( when );
parentItem.nodeAs<GeoDataTimeStamp>()->setResolution( resolution );
} else if ( parentItem.represents( kmlTag_Track ) ) {
parentItem.nodeAs<GeoDataTrack>()->appendWhen( when );
}
- return 0;
+ return nullptr;
}
QDateTime KmlwhenTagHandler::parse( const QString &dateTime )
{
QString iso = dateTime;
modify( iso );
return QDateTime::fromString( iso, Qt::ISODate );
}
GeoDataTimeStamp KmlwhenTagHandler::parseTimestamp( const QString &dateTime )
{
GeoDataTimeStamp result;
QString input = dateTime;
result.setResolution( modify( input ) );
result.setWhen( parse( input) );
return result;
}
GeoDataTimeStamp::TimeResolution KmlwhenTagHandler::modify( QString& whenString )
{
switch( whenString.length() )
{
case 4:
whenString += QLatin1String("-01-01");
return GeoDataTimeStamp::YearResolution;
case 7:
whenString += QLatin1String("-01");
return GeoDataTimeStamp::MonthResolution;
case 10:
return GeoDataTimeStamp::DayResolution;
default:
return GeoDataTimeStamp::SecondResolution;
}
return GeoDataTimeStamp::SecondResolution;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlWidthTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlWidthTagHandler.cpp
index 6e10a7a7a..651ee4348 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlWidthTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlWidthTagHandler.cpp
@@ -1,52 +1,52 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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 "KmlWidthTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataLineStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( width )
GeoNode* KmlwidthTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_width)));
GeoStackItem parentItem = parser.parentElement();
if( parentItem.represents( kmlTag_LineStyle ) ) {
float width = parser.readElementText().trimmed().toFloat();
parentItem.nodeAs<GeoDataLineStyle>()->setWidth( width );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlXTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlXTagHandler.cpp
index 65644ab4d..3328be0cb 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlXTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlXTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlXTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataScale.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( x )
GeoNode* KmlxTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_x)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataScale>() ){
double x = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataScale>()->setX( x );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlYTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlYTagHandler.cpp
index 7c4d4c025..b5152132b 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlYTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlYTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlYTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataScale.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( y )
GeoNode* KmlyTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_y)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataScale>() ){
double y = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataScale>()->setY( y );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmlZTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlZTagHandler.cpp
index 16f0acb8b..5a22431ea 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlZTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlZTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include "KmlZTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataScale.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( z )
GeoNode* KmlzTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_z)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataScale>() ){
double z = parser.readElementText().trimmed().toDouble();
parentItem.nodeAs<GeoDataScale>()->setZ( z );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/Kml_scaleTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/Kml_scaleTagHandler.cpp
index b05344c6c..17663ace6 100644
--- a/src/lib/marble/geodata/handlers/kml/Kml_scaleTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/Kml_scaleTagHandler.cpp
@@ -1,58 +1,58 @@
/*
Copyright (C) 2008 Patrick Spendrin <ps_ml@gmx.de>
This file is part of the KDE project
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
aint 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.
*/
// be aware that there is another Tag called Scale which uses the name KmlscaleTagHandler.h
// as it is impossible to use the name KmlscaleTagHandler then, use an underscore
// to mark the lower case variant
#include "Kml_scaleTagHandler.h"
#include "MarbleDebug.h"
#include "KmlElementDictionary.h"
#include "GeoDataIconStyle.h"
#include "GeoDataLabelStyle.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( scale )
GeoNode* KmlscaleTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_scale)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( kmlTag_IconStyle ) ) {
parentItem.nodeAs<GeoDataIconStyle>()->setScale(
parser.readElementText().trimmed().toFloat() );
} else if( parentItem.represents( kmlTag_LabelStyle ) ) {
parentItem.nodeAs<GeoDataLabelStyle>()->setScale(
parser.readElementText().trimmed().toFloat() );
}
- return 0;
+ return nullptr;
}
}
}
diff --git a/src/lib/marble/geodata/handlers/kml/KmldelayedStartTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmldelayedStartTagHandler.cpp
index 56e4261eb..ce1fe86d3 100644
--- a/src/lib/marble/geodata/handlers/kml/KmldelayedStartTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmldelayedStartTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "KmldelayedStartTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataSoundCue.h"
#include "GeoDataAnimatedUpdate.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( delayedStart )
GeoNode* KmldelayedStartTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_delayedStart)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.is<GeoDataSoundCue>()) {
double const delay = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataSoundCue>()->setDelayedStart(delay);
} else if (parentItem.is<GeoDataAnimatedUpdate>()) {
double const delay = parser.readElementText().toDouble();
parentItem.nodeAs<GeoDataAnimatedUpdate>()->setDelayedStart(delay);
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmldrawOrderTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmldrawOrderTagHandler.cpp
index c44fb6c0b..989b9e761 100644
--- a/src/lib/marble/geodata/handlers/kml/KmldrawOrderTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmldrawOrderTagHandler.cpp
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "KmldrawOrderTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoDataOverlay.h"
#include "GeoParser.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER( drawOrder )
GeoNode* KmldrawOrderTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_drawOrder)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.is<GeoDataOverlay>()) {
bool ok = false;
int value = parser.readElementText().trimmed().toInt(&ok, 10);
if (ok) {
parentItem.nodeAs<GeoDataOverlay>()->setDrawOrder(value);
}
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/handlers/kml/KmlplayModeTagHandler.cpp b/src/lib/marble/geodata/handlers/kml/KmlplayModeTagHandler.cpp
index f242923b4..d81f11ffd 100644
--- a/src/lib/marble/geodata/handlers/kml/KmlplayModeTagHandler.cpp
+++ b/src/lib/marble/geodata/handlers/kml/KmlplayModeTagHandler.cpp
@@ -1,43 +1,43 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "KmlplayModeTagHandler.h"
#include "KmlElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataTourControl.h"
namespace Marble
{
namespace kml
{
KML_DEFINE_TAG_HANDLER_GX22( playMode )
GeoNode* KmlplayModeTagHandler::parse(GeoParser &parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(kmlTag_playMode)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.is<GeoDataTourControl>()) {
GeoDataTourControl *control = parentItem.nodeAs<GeoDataTourControl>();
if (parser.readElementText().trimmed().toLower() == QLatin1String("play")) {
control->setPlayMode(GeoDataTourControl::Play);
} else {
control->setPlayMode(GeoDataTourControl::Pause);
}
}
- return 0;
+ return nullptr;
}
} // namespace kml
} // namespace Marble
diff --git a/src/lib/marble/geodata/parser/GeoParser.cpp b/src/lib/marble/geodata/parser/GeoParser.cpp
index 06a8cd29b..639e37b43 100644
--- a/src/lib/marble/geodata/parser/GeoParser.cpp
+++ b/src/lib/marble/geodata/parser/GeoParser.cpp
@@ -1,216 +1,216 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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.
*/
// Own
#include "GeoParser.h"
// Marble
#include "MarbleDebug.h"
// Geodata
#include "GeoDocument.h"
#include "GeoTagHandler.h"
namespace Marble
{
// Set to a value greater than 0, to dump parent node chain while parsing
#define DUMP_PARENT_STACK 0
GeoParser::GeoParser( GeoDataGenericSourceType source )
: QXmlStreamReader(),
- m_document( 0 ),
+ m_document( nullptr ),
m_source( source )
{
}
GeoParser::~GeoParser()
{
delete m_document;
}
#if DUMP_PARENT_STACK > 0
static void dumpParentStack( const QString& name, int size, bool close )
{
static int depth = 0;
if ( !close )
depth++;
QString result;
for ( int i = 0; i < depth; ++i )
result += QLatin1Char(' ');
if ( close ) {
depth--;
result += QLatin1String("</");
} else
result += QLatin1Char('<');
result += name + QLatin1String("> stack size ") + QString::number(size);
fprintf( stderr, "%s\n", qPrintable( result ));
}
#endif
bool GeoParser::read( QIODevice* device )
{
// Assert previous document got released.
Q_ASSERT( !m_document );
m_document = createDocument();
Q_ASSERT( m_document );
// Set data source
setDevice( device );
// Start parsing
while ( !atEnd() ) {
readNext();
if ( isStartElement() ) {
if ( isValidRootElement() ) {
#if DUMP_PARENT_STACK > 0
dumpParentStack( name().toString(), m_nodeStack.size(), false );
#endif
parseDocument();
if ( !m_nodeStack.isEmpty() )
raiseError(
// Keep trailing space in both strings, to match translated string
// TODO: check if that space is kept through the tool pipeline
//~ singular Parsing failed line %1. Still %n unclosed tag after document end.
//~ plural Parsing failed line %1. Still %n unclosed tags after document end.
QObject::tr("Parsing failed line %1. Still %n unclosed tag(s) after document end. ", "",
m_nodeStack.size() ).arg( lineNumber() ) + errorString());
} else
return false;
}
}
if ( error() ) {
if ( lineNumber() == 1) {
raiseError(QString());
}
// Defer the deletion to the dtor
// This allows the BookmarkManager to recover the broken .kml files it produced in Marble 1.0 and 1.1
/** @todo: Remove this workaround around Marble 1.4 */
// delete releaseDocument();
}
return !error();
}
bool GeoParser::isValidElement( const QString& tagName ) const
{
return name() == tagName;
}
GeoStackItem GeoParser::parentElement( unsigned int depth ) const
{
QStack<GeoStackItem>::const_iterator it = m_nodeStack.constEnd() - 1;
if ( it - depth < m_nodeStack.constBegin() )
return GeoStackItem();
return *(it - depth);
}
void GeoParser::parseDocument()
{
if( !isStartElement() ) {
raiseError( QObject::tr("Error parsing file at line: %1 and column %2 . ")
.arg( lineNumber() ).arg( columnNumber() )
+ QObject::tr("This is an Invalid File") );
return;
}
bool processChildren = true;
QualifiedName qName( name().toString(), namespaceUri().toString() );
if( tokenType() == QXmlStreamReader::Invalid )
raiseWarning( QString( "%1: %2" ).arg( error() ).arg( errorString() ) );
- GeoStackItem stackItem( qName, 0 );
+ GeoStackItem stackItem( qName, nullptr );
if ( const GeoTagHandler* handler = GeoTagHandler::recognizes( qName )) {
stackItem.assignNode( handler->parse( *this ));
processChildren = !isEndElement();
}
// Only add GeoStackItem to the parent chain, if the tag handler
// for the current element possibly contains non-textual children.
// Consider following DGML snippet "<name>Test</name>" - the
// DGMLNameTagHandler assumes that <name> only contains textual
// children, and reads the joined value of all children using
// readElementText(). This implicates that tags like <name>
// don't contain any children that would need to be processed using
// this parseDocument() function.
if ( processChildren ) {
m_nodeStack.push( stackItem );
#if DUMP_PARENT_STACK > 0
dumpParentStack( name().toString(), m_nodeStack.size(), false );
#endif
while ( !atEnd() ) {
readNext();
if ( isEndElement() ) {
m_nodeStack.pop();
#if DUMP_PARENT_STACK > 0
dumpParentStack( name().toString(), m_nodeStack.size(), true );
#endif
break;
}
if ( isStartElement() ) {
parseDocument();
}
}
}
#if DUMP_PARENT_STACK > 0
else {
// This is only used for debugging purposes.
m_nodeStack.push( stackItem );
dumpParentStack(name().toString() + QLatin1String("-discarded"), m_nodeStack.size(), false);
m_nodeStack.pop();
dumpParentStack(name().toString() + QLatin1String("-discarded"), m_nodeStack.size(), true);
}
#endif
}
void GeoParser::raiseWarning( const QString& warning )
{
// TODO: Maybe introduce a strict parsing mode where we feed the warning to
// raiseError() (which stops parsing).
mDebug() << "[GeoParser::raiseWarning] -> " << warning;
}
QString GeoParser::attribute( const char* attributeName ) const
{
return attributes().value(QLatin1String(attributeName)).toString();
}
GeoDocument* GeoParser::releaseDocument()
{
GeoDocument* document = m_document;
- m_document = 0;
+ m_document = nullptr;
return document;
}
}
diff --git a/src/lib/marble/geodata/parser/GeoParser.h b/src/lib/marble/geodata/parser/GeoParser.h
index 5f6b415a9..913ef8bc8 100644
--- a/src/lib/marble/geodata/parser/GeoParser.h
+++ b/src/lib/marble/geodata/parser/GeoParser.h
@@ -1,144 +1,144 @@
/*
Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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_GEOPARSER_H
#define MARBLE_GEOPARSER_H
#include <QPair>
#include <QStack>
#include <QXmlStreamReader>
#include "geodata_export.h"
namespace Marble
{
typedef int GeoDataGenericSourceType;
class GeoDocument;
class GeoNode;
class GeoStackItem;
class GEODATA_EXPORT GeoParser : public QXmlStreamReader
{
public:
typedef QPair<QString, QString> QualifiedName; // Tag Name & Namespace pair
explicit GeoParser( GeoDataGenericSourceType sourceType );
virtual ~GeoParser();
/**
* @brief Main API for reading the XML document.
* This is the only method that is necessary to call to start the GeoParser.
* To retrieve the resulting data see @see releaseDocument() and
* @see releaseModel()
*/
bool read( QIODevice* );
/**
* @brief retrieve the parsed document and reset the parser
* If parsing was successful, retrieve the resulting document
* and set the contained m_document pointer to 0.
*/
GeoDocument* releaseDocument();
GeoDocument* activeDocument() { return m_document; }
// Used by tag handlers, to be overridden by GeoDataParser/GeoSceneParser
virtual bool isValidElement( const QString& tagName ) const;
// Used by tag handlers, to access a parent element's associated GeoStackItem
GeoStackItem parentElement( unsigned int depth = 0 ) const;
// Used by tag handlers, to emit a warning while parsing
void raiseWarning( const QString& );
// Used by tag handlers, to retrieve the value for an attribute of the currently parsed element
QString attribute( const char* attributeName ) const;
protected:
/**
* This method is intended to check if the current element being served by
* the GeoParser is a valid Document Root element. This method is to be
* implemented by GeoDataParser/GeoSceneParser and must check based on the
* current XML Document type, e.g. KML, GPX etc.
* @return @c true if the element is a valid document root.
*/
virtual bool isValidRootElement() = 0;
virtual GeoDocument* createDocument() const = 0;
protected:
GeoDocument* m_document;
GeoDataGenericSourceType m_source;
private:
void parseDocument();
QStack<GeoStackItem> m_nodeStack;
};
class GeoStackItem
{
public:
GeoStackItem()
: m_qualifiedName(),
- m_node( 0 )
+ m_node( nullptr )
{
}
GeoStackItem( const GeoParser::QualifiedName& qualifiedName, GeoNode* node )
: m_qualifiedName( qualifiedName ),
m_node( node )
{
}
// Fast path for tag handlers
bool represents( const char* tagName ) const
{
return m_node && tagName == m_qualifiedName.first;
}
// Helper for tag handlers. Does NOT guard against miscasting. Use with care.
template<class T>
T* nodeAs()
{
- Q_ASSERT( dynamic_cast<T*>( m_node ) != 0 );
+ Q_ASSERT( dynamic_cast<T*>( m_node ) != nullptr );
return static_cast<T*>(m_node);
}
template<class T>
bool is() const
{
- return 0 != dynamic_cast<T*>(m_node);
+ return nullptr != dynamic_cast<T*>(m_node);
}
GeoParser::QualifiedName qualifiedName() const { return m_qualifiedName; }
GeoNode* associatedNode() const { return m_node; }
private:
friend class GeoParser;
void assignNode( GeoNode* node ) { m_node = node; }
GeoParser::QualifiedName m_qualifiedName;
GeoNode* m_node;
};
}
#endif
diff --git a/src/lib/marble/geodata/parser/GeoTagHandler.cpp b/src/lib/marble/geodata/parser/GeoTagHandler.cpp
index 9282ac96d..266a2d234 100644
--- a/src/lib/marble/geodata/parser/GeoTagHandler.cpp
+++ b/src/lib/marble/geodata/parser/GeoTagHandler.cpp
@@ -1,88 +1,88 @@
/*
Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
This file is part of the KDE project
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
aint 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.
*/
// Own
#include "GeoTagHandler.h"
// Marble
#include "MarbleDebug.h"
namespace Marble
{
// Set to a value greater than 0, to dump tag handlers as they get registered
#define DUMP_TAG_HANDLER_REGISTRATION 0
-GeoTagHandler::TagHash* GeoTagHandler::s_tagHandlerHash = 0;
+GeoTagHandler::TagHash* GeoTagHandler::s_tagHandlerHash = nullptr;
GeoTagHandler::GeoTagHandler()
{
}
GeoTagHandler::~GeoTagHandler()
{
}
GeoTagHandler::TagHash* GeoTagHandler::tagHandlerHash()
{
if (!s_tagHandlerHash)
s_tagHandlerHash = new TagHash();
Q_ASSERT(s_tagHandlerHash);
return s_tagHandlerHash;
}
void GeoTagHandler::registerHandler(const GeoParser::QualifiedName& qName, const GeoTagHandler* handler)
{
TagHash* hash = tagHandlerHash();
Q_ASSERT(!hash->contains(qName));
hash->insert(qName, handler);
Q_ASSERT(hash->contains(qName));
#if DUMP_TAG_HANDLER_REGISTRATION > 0
mDebug() << "[GeoTagHandler] -> Recognizing" << qName.first << "tag with namespace" << qName.second;
#endif
}
void GeoTagHandler::unregisterHandler(const GeoParser::QualifiedName& qName)
{
TagHash* hash = tagHandlerHash();
Q_ASSERT(hash->contains(qName));
delete hash->value(qName);
hash->remove(qName);
Q_ASSERT(!hash->contains(qName));
}
const GeoTagHandler* GeoTagHandler::recognizes(const GeoParser::QualifiedName& qName)
{
TagHash* hash = tagHandlerHash();
if (!hash->contains(qName))
- return 0;
+ return nullptr;
return (*hash)[qName];
}
}
diff --git a/src/lib/marble/geodata/scene/GeoSceneGroup.cpp b/src/lib/marble/geodata/scene/GeoSceneGroup.cpp
index 8891ce007..33f7226cf 100644
--- a/src/lib/marble/geodata/scene/GeoSceneGroup.cpp
+++ b/src/lib/marble/geodata/scene/GeoSceneGroup.cpp
@@ -1,171 +1,171 @@
/*
Copyright (C) 2008 Torsten Rahn <rahn@kde.org>
This file is part of the KDE project
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
aint 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 "GeoSceneGroup.h"
#include "MarbleDebug.h"
#include "GeoSceneProperty.h"
#include "GeoSceneTypes.h"
namespace Marble
{
GeoSceneGroup::GeoSceneGroup( const QString& name )
: m_name( name )
{
}
GeoSceneGroup::~GeoSceneGroup()
{
qDeleteAll( m_properties );
}
bool GeoSceneGroup::propertyAvailable( const QString& name, bool& available ) const
{
QVector<GeoSceneProperty*>::const_iterator it = m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator end = m_properties.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
available = (*it)->available();
return true;
}
}
available = false;
return false;
}
bool GeoSceneGroup::setPropertyValue( const QString& name, bool value )
{
QVector<GeoSceneProperty*>::const_iterator it = m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator end = m_properties.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
(*it)->setValue( value );
emit valueChanged( name, value );
return true;
}
}
return false;
}
bool GeoSceneGroup::propertyValue( const QString& name, bool& value ) const
{
QVector<GeoSceneProperty*>::const_iterator it = m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator end = m_properties.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
value = (*it)->value();
return true;
}
}
value = false;
return false;
}
void GeoSceneGroup::addProperty( GeoSceneProperty* property )
{
Q_ASSERT(property);
if (!property) {
return;
}
// Remove any property that has the same name
QVector<GeoSceneProperty*>::iterator it = m_properties.begin();
while (it != m_properties.end()) {
GeoSceneProperty* currentProperty = *it;
if ( currentProperty->name() == property->name() ) {
delete currentProperty;
m_properties.erase(it);
break;
}
else {
++it;
}
}
m_properties.append( property );
// Establish connection to the outside, e.g. the LegendBrowser
connect ( property, SIGNAL(valueChanged(QString,bool)),
SIGNAL(valueChanged(QString,bool)) );
emit valueChanged( property->name(), property->value() );
}
const GeoSceneProperty* GeoSceneGroup::property( const QString& name ) const
{
- GeoSceneProperty* property = 0;
+ GeoSceneProperty* property = nullptr;
QVector<GeoSceneProperty*>::const_iterator it = m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator end = m_properties.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
property = *it;
break;
}
}
return property;
}
// implement non-const method by means of const method,
// for details, see "Effective C++" (third edition)
GeoSceneProperty* GeoSceneGroup::property( const QString& name )
{
return const_cast<GeoSceneProperty*>
( static_cast<GeoSceneGroup const *>( this )->property( name ));
}
QVector<GeoSceneProperty*> GeoSceneGroup::properties()
{
return m_properties;
}
QVector<const GeoSceneProperty*> GeoSceneGroup::properties() const
{
QVector<const GeoSceneProperty*> result;
result.reserve(m_properties.size());
for ( const GeoSceneProperty *property: m_properties ) {
result << property;
}
return result;
}
QString GeoSceneGroup::name() const
{
return m_name;
}
const char *GeoSceneGroup::nodeType() const
{
return GeoSceneTypes::GeoSceneGroupType;
}
}
#include "moc_GeoSceneGroup.cpp"
diff --git a/src/lib/marble/geodata/scene/GeoSceneMap.cpp b/src/lib/marble/geodata/scene/GeoSceneMap.cpp
index 0d547f5a2..0672e86a0 100644
--- a/src/lib/marble/geodata/scene/GeoSceneMap.cpp
+++ b/src/lib/marble/geodata/scene/GeoSceneMap.cpp
@@ -1,257 +1,257 @@
/*
Copyright (C) 2008 Torsten Rahn <rahn@kde.org>
This file is part of the KDE project
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
aint 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 "GeoSceneMap.h"
#include "GeoSceneTypes.h"
#include "GeoSceneLayer.h"
#include "GeoSceneFilter.h"
#include "DgmlAuxillaryDictionary.h"
#include <QColor>
namespace Marble
{
// FIXME: Filters are a Dataset.
class GeoSceneMapPrivate
{
public:
GeoSceneMapPrivate()
{
}
~GeoSceneMapPrivate()
{
qDeleteAll( m_layers );
qDeleteAll( m_filters );
}
/// The vector holding all the sections in the legend.
/// (We want to preserve the order and don't care
/// much about speed here), so we don't use a hash
QVector<GeoSceneLayer*> m_layers;
/// The vector holding all the filters in the map.
QVector<GeoSceneFilter*> m_filters;
QColor m_backgroundColor;
QColor m_labelColor;
/// This color will be used to highlight
/// a region when it's clicked on.
QColor m_highlightBrushColor;
QColor m_highlightPenColor;
};
GeoSceneMap::GeoSceneMap()
: d ( new GeoSceneMapPrivate )
{
}
GeoSceneMap::~GeoSceneMap()
{
delete d;
}
const char* GeoSceneMap::nodeType() const
{
return GeoSceneTypes::GeoSceneMapType;
}
void GeoSceneMap::addLayer( GeoSceneLayer* layer )
{
// Remove any layer that has the same name
QVector<GeoSceneLayer*>::iterator it = d->m_layers.begin();
while (it != d->m_layers.end()) {
GeoSceneLayer* currentLayer = *it;
if ( currentLayer->name() == layer->name() ) {
delete currentLayer;
d->m_layers.erase(it);
break;
}
else {
++it;
}
}
if ( layer ) {
d->m_layers.append( layer );
}
}
GeoSceneLayer* GeoSceneMap::layer( const QString& name )
{
- GeoSceneLayer* layer = 0;
+ GeoSceneLayer* layer = nullptr;
QVector<GeoSceneLayer*>::const_iterator it = d->m_layers.constBegin();
QVector<GeoSceneLayer*>::const_iterator end = d->m_layers.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
layer = *it;
break;
}
}
if ( !layer ) {
layer = new GeoSceneLayer( name );
addLayer( layer );
}
return layer;
}
const GeoSceneLayer* GeoSceneMap::layer( const QString& name ) const
{
- const GeoSceneLayer* layer = 0;
+ const GeoSceneLayer* layer = nullptr;
QVector<GeoSceneLayer*>::const_iterator it = d->m_layers.constBegin();
QVector<GeoSceneLayer*>::const_iterator end = d->m_layers.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
layer = *it;
break;
}
}
return layer;
}
QVector<GeoSceneLayer*> GeoSceneMap::layers() const
{
return d->m_layers;
}
void GeoSceneMap::addFilter( GeoSceneFilter* filter )
{
// Remove any filter that has the same name
QVector<GeoSceneFilter*>::iterator it = d->m_filters.begin();
while (it != d->m_filters.end()) {
GeoSceneFilter* currentFilter = *it;
if ( currentFilter->name() == filter->name() ) {
delete currentFilter;
d->m_filters.erase(it);
break;
}
else {
++it;
}
}
if ( filter ) {
d->m_filters.append( filter );
}
}
GeoSceneFilter* GeoSceneMap::filter( const QString& name )
{
- GeoSceneFilter* filter = 0;
+ GeoSceneFilter* filter = nullptr;
QVector<GeoSceneFilter*>::const_iterator it = d->m_filters.constBegin();
QVector<GeoSceneFilter*>::const_iterator end = d->m_filters.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
filter = *it;
break;
}
}
if ( !filter ) {
filter = new GeoSceneFilter( name );
addFilter( filter );
}
return filter;
}
QVector<GeoSceneFilter*> GeoSceneMap::filters() const
{
return d->m_filters;
}
bool GeoSceneMap::hasTextureLayers() const
{
QVector<GeoSceneLayer*>::const_iterator it = d->m_layers.constBegin();
QVector<GeoSceneLayer*>::const_iterator end = d->m_layers.constEnd();
for (; it != end; ++it) {
if (((*it)->backend() == QLatin1String(dgml::dgmlValue_texture) ||
(*it)->backend() == QLatin1String(dgml::dgmlValue_vectortile)) && (*it)->datasets().count() > 0)
return true;
}
return false;
}
bool GeoSceneMap::hasVectorLayers() const
{
QVector<GeoSceneLayer*>::const_iterator it = d->m_layers.constBegin();
QVector<GeoSceneLayer*>::const_iterator end = d->m_layers.constEnd();
for (; it != end; ++it) {
if (((*it)->backend() == QLatin1String(dgml::dgmlValue_vector)) && (*it)->datasets().count() > 0)
return true;
}
return false;
}
QColor GeoSceneMap::backgroundColor() const
{
return d->m_backgroundColor;
}
void GeoSceneMap::setBackgroundColor( const QColor& backgroundColor )
{
d->m_backgroundColor = backgroundColor;
}
QColor GeoSceneMap::labelColor() const
{
return d->m_labelColor;
}
void GeoSceneMap::setLabelColor( const QColor& backgroundColor )
{
d->m_labelColor = backgroundColor;
}
QColor GeoSceneMap::highlightBrushColor() const
{
return d->m_highlightBrushColor;
}
void GeoSceneMap::setHighlightBrushColor( const QColor & highlightBrushColor )
{
d->m_highlightBrushColor = highlightBrushColor;
}
QColor GeoSceneMap::highlightPenColor() const
{
return d->m_highlightPenColor;
}
void GeoSceneMap::setHighlightPenColor( const QColor &highlightPenColor )
{
d->m_highlightPenColor = highlightPenColor;
}
}
diff --git a/src/lib/marble/geodata/scene/GeoSceneSection.cpp b/src/lib/marble/geodata/scene/GeoSceneSection.cpp
index 7840f670a..dc9a09bd5 100644
--- a/src/lib/marble/geodata/scene/GeoSceneSection.cpp
+++ b/src/lib/marble/geodata/scene/GeoSceneSection.cpp
@@ -1,151 +1,151 @@
/*
Copyright (C) 2008 Torsten Rahn <rahn@kde.org>
This file is part of the KDE project
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
aint 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 "GeoSceneSection.h"
#include "MarbleDebug.h"
#include "GeoSceneTypes.h"
#include "GeoSceneItem.h"
namespace Marble
{
GeoSceneSection::GeoSceneSection( const QString& name )
: m_name( name ),
m_checkable( false ),
m_spacing( 12 )
{
}
GeoSceneSection::~GeoSceneSection()
{
qDeleteAll( m_items );
}
const char* GeoSceneSection::nodeType() const
{
return GeoSceneTypes::GeoSceneSectionType;
}
void GeoSceneSection::addItem( GeoSceneItem* item )
{
// Remove any item that has the same name
QVector<GeoSceneItem*>::iterator it = m_items.begin();
while (it != m_items.end()) {
GeoSceneItem* currentItem = *it;
if ( currentItem->name() == item->name() ) {
delete currentItem;
m_items.erase(it);
break;
}
else {
++it;
}
}
if ( item ) {
m_items.append( item );
}
}
GeoSceneItem* GeoSceneSection::item( const QString& name )
{
- GeoSceneItem* item = 0;
+ GeoSceneItem* item = nullptr;
QVector<GeoSceneItem*>::const_iterator it = m_items.constBegin();
QVector<GeoSceneItem*>::const_iterator end = m_items.constEnd();
for (; it != end; ++it) {
if ( (*it)->name() == name ) {
item = *it;
break;
}
}
if ( !item ) {
item = new GeoSceneItem( name );
addItem( item );
}
return item;
}
QVector<GeoSceneItem*> GeoSceneSection::items() const
{
return m_items;
}
QString GeoSceneSection::name() const
{
return m_name;
}
QString GeoSceneSection::heading() const
{
return m_heading;
}
void GeoSceneSection::setHeading( const QString& heading )
{
m_heading = heading;
}
bool GeoSceneSection::checkable() const
{
return m_checkable;
}
void GeoSceneSection::setCheckable( bool checkable )
{
m_checkable = checkable;
}
QString GeoSceneSection::connectTo() const
{
return m_connectTo;
}
void GeoSceneSection::setConnectTo( const QString& connectTo )
{
m_connectTo = connectTo;
}
int GeoSceneSection::spacing() const
{
return m_spacing;
}
void GeoSceneSection::setSpacing( int spacing )
{
m_spacing = spacing;
}
QString GeoSceneSection::radio() const
{
return m_radio;
}
void GeoSceneSection::setRadio( const QString& radio )
{
m_radio = radio;
}
}
diff --git a/src/lib/marble/geodata/scene/GeoSceneSettings.cpp b/src/lib/marble/geodata/scene/GeoSceneSettings.cpp
index 96c16fc4e..7c54cac84 100644
--- a/src/lib/marble/geodata/scene/GeoSceneSettings.cpp
+++ b/src/lib/marble/geodata/scene/GeoSceneSettings.cpp
@@ -1,276 +1,276 @@
/*
Copyright (C) 2008 Torsten Rahn <rahn@kde.org>
This file is part of the KDE project
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
aint 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 "GeoSceneSettings.h"
#include "MarbleDebug.h"
#include "GeoSceneProperty.h"
#include "GeoSceneGroup.h"
#include "GeoSceneTypes.h"
namespace Marble
{
class GeoSceneSettingsPrivate
{
public:
~GeoSceneSettingsPrivate()
{
qDeleteAll(m_properties);
qDeleteAll(m_groups);
}
/// The hash table holding all the properties in the settings.
QVector<GeoSceneProperty*> m_properties;
QVector<GeoSceneGroup*> m_groups;
};
GeoSceneSettings::GeoSceneSettings()
: d( new GeoSceneSettingsPrivate )
{
}
GeoSceneSettings::~GeoSceneSettings()
{
delete d;
}
const char* GeoSceneSettings::nodeType() const
{
return GeoSceneTypes::GeoSceneSettingsType;
}
bool GeoSceneSettings::propertyAvailable( const QString& name, bool& available ) const
{
QVector<GeoSceneProperty*>::const_iterator it = d->m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator propEnd = d->m_properties.constEnd();
for (; it != propEnd; ++it) {
if ( (*it)->name() == name ) {
available = (*it)->available();
return true;
}
}
QVector<GeoSceneGroup*>::const_iterator itGroup = d->m_groups.constBegin();
QVector<GeoSceneGroup*>::const_iterator groupEnd = d->m_groups.constEnd();
for (; itGroup != groupEnd; ++itGroup) {
bool success = (*itGroup)->propertyAvailable( name, available );
if ( success ) {
return true;
}
}
available = false;
return false;
}
bool GeoSceneSettings::setPropertyValue( const QString& name, bool value )
{
mDebug() << "GeoSceneSettings: Property " << name << "to" << value;
QVector<GeoSceneProperty*>::const_iterator it = d->m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator propEnd = d->m_properties.constEnd();
for (; it != propEnd; ++it) {
if ( (*it)->name() == name ) {
(*it)->setValue( value );
return true;
}
}
QVector<GeoSceneGroup*>::const_iterator itGroup = d->m_groups.constBegin();
QVector<GeoSceneGroup*>::const_iterator groupEnd = d->m_groups.constEnd();
for (; itGroup != groupEnd; ++itGroup) {
bool success = (*itGroup)->setPropertyValue( name, value );
if ( success ) {
return true;
}
}
return false;
}
bool GeoSceneSettings::propertyValue( const QString& name, bool& value ) const
{
QVector<GeoSceneProperty*>::const_iterator it = d->m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator propEnd = d->m_properties.constEnd();
for (; it != propEnd; ++it) {
if ( (*it)->name() == name ) {
value = (*it)->value();
return true;
}
}
QVector<GeoSceneGroup*>::const_iterator itGroup = d->m_groups.constBegin();
QVector<GeoSceneGroup*>::const_iterator groupEnd = d->m_groups.constEnd();
for (; itGroup != groupEnd; ++itGroup) {
bool success = (*itGroup)->propertyValue( name, value );
if ( success ) {
return true;
}
}
value = false;
return false;
}
QVector<GeoSceneProperty*> GeoSceneSettings::allProperties()
{
QVector<GeoSceneProperty*> allProperties;
QVector<GeoSceneGroup*>::const_iterator itGroup = d->m_groups.constBegin();
QVector<GeoSceneGroup*>::const_iterator groupEnd = d->m_groups.constEnd();
for (; itGroup != groupEnd; ++itGroup) {
allProperties << (*itGroup)->properties();
}
allProperties << d->m_properties;
return allProperties;
}
QVector<const GeoSceneProperty*> GeoSceneSettings::allProperties() const
{
QVector<const GeoSceneProperty*> allProperties;
QVector<GeoSceneGroup*>::const_iterator itGroup = d->m_groups.constBegin();
QVector<GeoSceneGroup*>::const_iterator groupEnd = d->m_groups.constEnd();
for (; itGroup != groupEnd; ++itGroup) {
allProperties << const_cast<const GeoSceneGroup*>(*itGroup)->properties();
}
allProperties.reserve(allProperties.size() + d->m_properties.size());
for ( const GeoSceneProperty *property: d->m_properties ) {
allProperties << property;
}
return allProperties;
}
void GeoSceneSettings::addGroup( GeoSceneGroup* group )
{
// Remove any property that has the same name
QVector<GeoSceneGroup*>::iterator it = d->m_groups.begin();
while (it != d->m_groups.end()) {
GeoSceneGroup* currentGroup = *it;
if ( currentGroup->name() == group->name() ) {
delete currentGroup;
d->m_groups.erase(it);
break;
}
else {
++it;
}
}
if ( group ) {
d->m_groups.append( group );
// Establish connection to the outside, e.g. the LegendBrowser
connect ( group, SIGNAL(valueChanged(QString,bool)),
SIGNAL(valueChanged(QString,bool)) );
}
}
const GeoSceneGroup* GeoSceneSettings::group( const QString& name ) const
{
- GeoSceneGroup* group = 0;
+ GeoSceneGroup* group = nullptr;
QVector<GeoSceneGroup*>::const_iterator it = d->m_groups.constBegin();
QVector<GeoSceneGroup*>::const_iterator groupEnd = d->m_groups.constEnd();
for (; it != groupEnd; ++it) {
if ( (*it)->name() == name ) {
group = *it;
break;
}
}
return group;
}
// implement non-const method by means of const method,
// for details, see "Effective C++" (third edition)
GeoSceneGroup* GeoSceneSettings::group( const QString& name )
{
return const_cast<GeoSceneGroup*>( static_cast<GeoSceneSettings const *>( this )->group( name ));
}
void GeoSceneSettings::addProperty( GeoSceneProperty* property )
{
// Remove any property that has the same name
QVector<GeoSceneProperty*>::iterator it = d->m_properties.begin();
while (it != d->m_properties.end()) {
GeoSceneProperty* currentProperty = *it;
if ( currentProperty->name() == property->name() ) {
delete currentProperty;
d->m_properties.erase(it);
break;
}
else {
++it;
}
}
if ( property ) {
d->m_properties.append( property );
// Establish connection to the outside, e.g. the LegendBrowser
connect ( property, SIGNAL(valueChanged(QString,bool)),
SIGNAL(valueChanged(QString,bool)) );
emit valueChanged( property->name(), property->value() );
}
}
const GeoSceneProperty* GeoSceneSettings::property( const QString& name ) const
{
- GeoSceneProperty* property = 0;
+ GeoSceneProperty* property = nullptr;
QVector<GeoSceneProperty*>::const_iterator it = d->m_properties.constBegin();
QVector<GeoSceneProperty*>::const_iterator propEnd = d->m_properties.constEnd();
for (; it != propEnd; ++it) {
if ( (*it)->name() == name ) {
property = *it;
break;
}
}
return property;
}
// implement non-const method by means of const method,
// for details, see "Effective C++" (third edition)
GeoSceneProperty* GeoSceneSettings::property( const QString& name )
{
return const_cast<GeoSceneProperty*>
( static_cast<GeoSceneSettings const *>( this )->property( name ));
}
QVector<GeoSceneProperty*> GeoSceneSettings::rootProperties()
{
return d->m_properties;
}
}
#include "moc_GeoSceneSettings.cpp"
diff --git a/src/lib/marble/geodata/writer/GeoTagWriter.cpp b/src/lib/marble/geodata/writer/GeoTagWriter.cpp
index 03b31e860..70c80c98b 100644
--- a/src/lib/marble/geodata/writer/GeoTagWriter.cpp
+++ b/src/lib/marble/geodata/writer/GeoTagWriter.cpp
@@ -1,74 +1,74 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Andrew Manson <g.real.ate@gmail.com>
// Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
//
#include "GeoTagWriter.h"
#include "GeoWriter.h"
#include <QDebug>
namespace Marble
{
GeoTagWriter::GeoTagWriter()
{
}
GeoTagWriter::~GeoTagWriter()
{
}
bool GeoTagWriter::writeElement( const GeoNode *object,
GeoWriter &writer)
{
return writer.writeElement( object );
}
void GeoTagWriter::registerWriter(const QualifiedName& name,
const GeoTagWriter* writer )
{
TagHash* tagHash = tagWriterHash();
if ( tagHash->contains( name ) ) {
qWarning() << "Warning: The tag" << name << "is already registered. Often this indicates that multiple versions of the marblewidget library are loaded at the same time. This will likely lead to problems. Please check your installation, especially internal Marble plugins and external applications that install Marble plugins.";
}
Q_ASSERT( !tagHash->contains( name ) );
tagHash->insert( name, writer );
Q_ASSERT( tagHash->contains( name ) );
}
void GeoTagWriter::unregisterWriter(const GeoTagWriter::QualifiedName &qName)
{
auto hash = tagWriterHash();
Q_ASSERT(hash->contains(qName));
delete hash->value(qName);
hash->remove(qName);
Q_ASSERT(!hash->contains(qName));
}
GeoTagWriter::TagHash* GeoTagWriter::tagWriterHash()
{
static TagHash s_tagWriterHash;
return &s_tagWriterHash;
}
const GeoTagWriter* GeoTagWriter::recognizes( const QualifiedName &qname )
{
TagHash* hash = tagWriterHash();
if( !hash->contains( qname ) ) {
- return 0;
+ return nullptr;
}
return hash->value( qname );
}
}
diff --git a/src/lib/marble/geodata/writer/GeoWriter.cpp b/src/lib/marble/geodata/writer/GeoWriter.cpp
index 4c8b20607..dbacf92de 100644
--- a/src/lib/marble/geodata/writer/GeoWriter.cpp
+++ b/src/lib/marble/geodata/writer/GeoWriter.cpp
@@ -1,111 +1,111 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Andrew Manson <g.real.ate@gmail.com>
//
#include "GeoWriter.h"
#include "GeoDocument.h"
#include "GeoTagWriter.h"
#include "KmlElementDictionary.h"
#include "DgmlElementDictionary.h"
#include "MarbleDebug.h"
namespace Marble
{
GeoWriter::GeoWriter()
{
//FIXME: work out a standard way to do this.
m_documentType = kml::kmlTag_nameSpaceOgc22;
}
bool GeoWriter::write(QIODevice* device, const GeoNode *feature)
{
setDevice( device );
setAutoFormatting( true );
writeStartDocument();
//FIXME: write the starting tags. Possibly register a tag handler to do this
// with a null string as the object name?
GeoTagWriter::QualifiedName name( "", m_documentType );
const GeoTagWriter* writer = GeoTagWriter::recognizes(name);
if( writer ) {
//FIXME is this too much of a hack?
- writer->write(/* node = */ 0, *this); // node is never used in write()
+ writer->write(/* node = */ nullptr, *this); // node is never used in write()
} else {
mDebug() << "There is no GeoWriter registered for: " << name;
return false;
}
if( ! writeElement( feature ) ) {
return false;
}
//close the document
writeEndElement();
return true;
}
bool GeoWriter::writeElement(const GeoNode *object)
{
// Add checks to see that everything is ok here
GeoTagWriter::QualifiedName name( object->nodeType(), m_documentType );
const GeoTagWriter* writer = GeoTagWriter::recognizes( name );
if( writer ) {
if( ! writer->write( object, *this ) ) {
mDebug() << "An error has been reported by the GeoWriter for: "
<< name;
return false;
}
} else {
mDebug() << "There is no GeoWriter registered for: " << name;
return true;
}
return true;
}
void GeoWriter::setDocumentType( const QString &documentType )
{
m_documentType = documentType;
}
void GeoWriter::writeElement( const QString &namespaceUri, const QString &key, const QString &value )
{
writeStartElement( namespaceUri, key );
writeCharacters( value );
writeEndElement();
}
void GeoWriter::writeElement( const QString &key, const QString &value )
{
writeStartElement( key );
writeCharacters( value );
writeEndElement();
}
void GeoWriter::writeOptionalElement( const QString &key, const QString &value, const QString &defaultValue )
{
if( value != defaultValue ) {
writeElement( key, value );
}
}
void GeoWriter::writeOptionalAttribute( const QString &key, const QString &value, const QString &defaultValue )
{
if( value != defaultValue ) {
writeAttribute( key, value );
}
}
}
diff --git a/src/lib/marble/graphicsview/FrameGraphicsItem.h b/src/lib/marble/graphicsview/FrameGraphicsItem.h
index 9988017f9..5180728c9 100644
--- a/src/lib/marble/graphicsview/FrameGraphicsItem.h
+++ b/src/lib/marble/graphicsview/FrameGraphicsItem.h
@@ -1,195 +1,195 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_FRAMEGRAPHICSITEM_H
#define MARBLE_FRAMEGRAPHICSITEM_H
// Marble
#include "marble_export.h"
#include "ScreenGraphicsItem.h"
#include <Qt> // for Qt::PenStyle
class QBrush;
class QPainterPath;
namespace Marble
{
class FrameGraphicsItemPrivate;
class MARBLE_EXPORT FrameGraphicsItem : public ScreenGraphicsItem
{
public:
enum FrameType {
NoFrame,
RectFrame,
RoundedRectFrame,
ShadowFrame
};
- explicit FrameGraphicsItem( MarbleGraphicsItem *parent = 0 );
+ explicit FrameGraphicsItem( MarbleGraphicsItem *parent = nullptr );
~FrameGraphicsItem() override;
/**
* Returns the type of the frame.
*/
FrameType frame() const;
/**
* Sets the type of the Frame. Standard is NoFrame.
*/
void setFrame( FrameType type );
/**
* Returns the margin of the item. This is used for all margins with the value 0.0.
* The padding is the space outside the painted space.
*/
qreal margin() const;
/**
* Sets the margin of the item. This is used for all margins with the value 0.0.
*/
void setMargin( qreal margin );
/**
* Returns the top margin of the item.
*/
qreal marginTop() const;
/**
* Set the top margin of the item.
*/
void setMarginTop( qreal marginTop );
/**
* Returns the bottom margin of the item.
*/
qreal marginBottom() const;
/**
* Set the bottom margin of the item.
*/
void setMarginBottom( qreal marginBottom );
/**
* Returns the left margin of the item.
*/
qreal marginLeft() const;
/**
* Set the left margin of the item.
*/
void setMarginLeft( qreal marginLeft );
/**
* Returns the right margin of the item.
*/
qreal marginRight() const;
/**
* Set the right margin of the item.
*/
void setMarginRight( qreal marginRight );
/**
* Returns the border width of the item.
*/
qreal borderWidth() const;
/**
* Set the border width of the item.
*/
void setBorderWidth( qreal width );
/**
* Returns the padding of the item.
* The padding is the empty space inside the border.
*/
qreal padding() const;
/**
* Set the padding of the item.
*/
void setPadding( qreal width );
/**
* Returns the brush of the border.
*/
QBrush borderBrush() const;
/**
* Change the brush of the border.
*/
void setBorderBrush( const QBrush &brush );
/**
* Returns the style of the border.
*/
Qt::PenStyle borderStyle () const;
/**
* Change the style of the border.
*/
void setBorderStyle( Qt::PenStyle style );
/**
* Returns the background brush of the item.
*/
QBrush background() const;
/**
* Changes the background brush of the item.
*/
void setBackground( const QBrush &background );
QRectF paintedRect() const;
QRectF contentRect() const override;
QSizeF contentSize() const override;
/**
* Sets the size of the content of the item.
* @p size is the size required for contents.
*/
void setContentSize( const QSizeF& size ) override;
protected:
/**
* Returns the shape of the background.
*/
virtual QPainterPath backgroundShape() const;
/**
* This function won't be reimplemented in most cases.
*/
void paint( QPainter *painter ) override;
/**
* Here the items paint their content.
*/
virtual void paintContent( QPainter *painter );
/**
* Paints the background. This function won't be reimplemented in most cases.
*/
virtual void paintBackground( QPainter *painter );
explicit FrameGraphicsItem(FrameGraphicsItemPrivate *dd);
private:
Q_DISABLE_COPY( FrameGraphicsItem )
Q_DECLARE_PRIVATE(FrameGraphicsItem)
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/graphicsview/LabelGraphicsItem.h b/src/lib/marble/graphicsview/LabelGraphicsItem.h
index d4c60f87a..22875d98f 100644
--- a/src/lib/marble/graphicsview/LabelGraphicsItem.h
+++ b/src/lib/marble/graphicsview/LabelGraphicsItem.h
@@ -1,65 +1,65 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_LABELGRAPHICSITEM_H
#define MARBLE_LABELGRAPHICSITEM_H
// Marble
#include "FrameGraphicsItem.h"
#include "marble_export.h"
#include <QSize>
class QImage;
class QIcon;
namespace Marble
{
class LabelGraphicsItemPrivate;
/**
* A label item provides an Item that displays text or images/pixmaps.
* The text is displayed as plain text.
* The item also provides frames.
*/
class MARBLE_EXPORT LabelGraphicsItem : public FrameGraphicsItem
{
public:
- explicit LabelGraphicsItem( MarbleGraphicsItem *parent = 0 );
+ explicit LabelGraphicsItem( MarbleGraphicsItem *parent = nullptr );
~LabelGraphicsItem() override;
void setContentSize( const QSizeF &contentSize ) override;
QString text() const;
void setText( const QString& text );
QImage image() const;
void setImage( const QImage& image, const QSize& size = QSize() );
QIcon icon() const;
void setIcon( const QIcon& icon, const QSize& size );
void setMinimumSize( const QSizeF& size );
QSizeF minimumSize() const;
void clear();
protected:
void paintContent( QPainter *painter ) override;
private:
Q_DISABLE_COPY( LabelGraphicsItem )
Q_DECLARE_PRIVATE(LabelGraphicsItem)
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/graphicsview/MarbleGraphicsGridLayout.cpp b/src/lib/marble/graphicsview/MarbleGraphicsGridLayout.cpp
index 94eca8389..11c10d231 100644
--- a/src/lib/marble/graphicsview/MarbleGraphicsGridLayout.cpp
+++ b/src/lib/marble/graphicsview/MarbleGraphicsGridLayout.cpp
@@ -1,214 +1,214 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "MarbleGraphicsGridLayout.h"
// Marble
#include "MarbleDebug.h"
#include "ScreenGraphicsItem.h"
// Qt
#include <QHash>
#include <QRectF>
#include <QSizeF>
#include <QVector>
namespace Marble
{
class MarbleGraphicsGridLayoutPrivate
{
public:
MarbleGraphicsGridLayoutPrivate( int rows, int columns )
: m_rows( rows ),
m_columns( columns ),
m_spacing( 0 ),
m_alignment( Qt::AlignLeft | Qt::AlignTop )
{
m_items = new ScreenGraphicsItem **[rows];
for ( int i = 0; i < rows; ++i ) {
m_items[i] = new ScreenGraphicsItem *[columns];
}
for ( int row = 0; row < rows; row++ ) {
for ( int column = 0; column < columns; column++ ) {
- m_items[row][column] = 0;
+ m_items[row][column] = nullptr;
}
}
}
~MarbleGraphicsGridLayoutPrivate()
{
for ( int i = 0; i < m_rows; ++i ) {
delete[] m_items[i];
}
delete[] m_items;
}
// A two dimensional array of pointers to ScreenGraphicsItems
ScreenGraphicsItem ***m_items;
int m_rows;
int m_columns;
int m_spacing;
Qt::Alignment m_alignment;
QHash<ScreenGraphicsItem*, Qt::Alignment> m_itemAlignment;
};
MarbleGraphicsGridLayout::MarbleGraphicsGridLayout( int rows, int columns )
: d( new MarbleGraphicsGridLayoutPrivate( rows, columns ) )
{
}
MarbleGraphicsGridLayout::~MarbleGraphicsGridLayout()
{
delete d;
}
void MarbleGraphicsGridLayout::addItem( ScreenGraphicsItem *item, int row, int column )
{
if ( row < d->m_rows
&& column < d->m_columns )
{
d->m_items[row][column] = item;
}
}
void MarbleGraphicsGridLayout::updatePositions( MarbleGraphicsItem *parent )
{
// Initialize with 0.0
QVector<double> maxWidth( d->m_columns, 0.0 );
QVector<double> maxHeight( d->m_rows, 0.0 );
// Determining the cell sizes
for ( int row = 0; row < d->m_rows; row++ ) {
for ( int column = 0; column < d->m_columns; column++ ) {
- if ( d->m_items[row][column] == 0 ) {
+ if ( d->m_items[row][column] == nullptr ) {
continue;
}
QSizeF size = d->m_items[row][column]->size();
double width = size.width();
double height = size.height();
if ( width > maxWidth[column] ) {
maxWidth[column] = width;
}
if ( height > maxHeight[row] ) {
maxHeight[row] = height;
}
}
}
QVector<double> startX( d->m_columns );
QVector<double> endX( d->m_columns );
QVector<double> startY( d->m_rows );
QVector<double> endY( d->m_rows );
QRectF contentRect = parent->contentRect();
for ( int i = 0; i < d->m_columns; i++ ) {
if ( i == 0 ) {
startX[0] = contentRect.left();
}
else if ( maxWidth[i] == 0 ) {
startX[i] = endX[i-1];
}
else {
startX[i] = endX[i-1] + d->m_spacing;
}
endX[i] = startX[i] + maxWidth[i];
}
for ( int i = 0; i < d->m_rows; i++ ) {
if ( i == 0 ) {
startY[0] = contentRect.left();
}
else if ( maxHeight[i] == 0 ) {
startY[i] = endY[i-1];
}
else {
startY[i] = endY[i-1] + d->m_spacing;
}
endY[i] = startY[i] + maxHeight[i];
}
// Setting the positions
for ( int row = 0; row < d->m_rows; row++ ) {
for ( int column = 0; column < d->m_columns; column++ ) {
- if ( d->m_items[row][column] == 0 ) {
+ if ( d->m_items[row][column] == nullptr ) {
continue;
}
double xPos, yPos;
Qt::Alignment align = alignment( d->m_items[row][column] );
if ( align & Qt::AlignRight ) {
xPos = endX[column] - d->m_items[row][column]->size().width();
}
else if ( align & Qt::AlignHCenter ) {
xPos = startX[column]
+ ( maxWidth[column] - d->m_items[row][column]->size().width() ) / 2.0;
}
else {
xPos = startX[column];
}
if ( align & Qt::AlignBottom ) {
yPos = endY[row] - d->m_items[row][column]->size().height();
}
else if ( align & Qt::AlignVCenter ) {
yPos = startY[row]
+ ( maxHeight[row] - d->m_items[row][column]->size().height() ) / 2.0;
}
else {
yPos = startY[row];
}
d->m_items[row][column]->setPosition( QPointF( xPos, yPos ) );
}
}
parent->setContentSize( QSizeF( endX[d->m_columns - 1] - contentRect.left(),
endY[d->m_rows - 1] - contentRect.top() ) );
}
Qt::Alignment MarbleGraphicsGridLayout::alignment() const
{
return d->m_alignment;
}
Qt::Alignment MarbleGraphicsGridLayout::alignment( ScreenGraphicsItem *item ) const
{
return d->m_itemAlignment.value( item, d->m_alignment );
}
void MarbleGraphicsGridLayout::setAlignment( Qt::Alignment align )
{
d->m_alignment = align;
}
void MarbleGraphicsGridLayout::setAlignment( ScreenGraphicsItem *item, Qt::Alignment align )
{
d->m_itemAlignment.insert( item, align );
}
int MarbleGraphicsGridLayout::spacing() const
{
return d->m_spacing;
}
void MarbleGraphicsGridLayout::setSpacing( int spacing )
{
d->m_spacing = spacing;
}
} // namespace Marble
diff --git a/src/lib/marble/graphicsview/MarbleGraphicsItem_p.h b/src/lib/marble/graphicsview/MarbleGraphicsItem_p.h
index dc11a7f55..91f5a9d9f 100644
--- a/src/lib/marble/graphicsview/MarbleGraphicsItem_p.h
+++ b/src/lib/marble/graphicsview/MarbleGraphicsItem_p.h
@@ -1,119 +1,119 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009-2010 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_MARBLEGRAPHICSITEMPRIVATE_H
#define MARBLE_MARBLEGRAPHICSITEMPRIVATE_H
// Marble
#include "AbstractMarbleGraphicsLayout.h"
#include "MarbleGraphicsItem.h"
// Qt
#include<QDebug>
#include<QList>
#include<QSet>
#include<QSize>
#include<QSizeF>
#include<QRect>
#include<QPixmap>
namespace Marble
{
class MarbleGraphicsItemPrivate
{
public:
explicit MarbleGraphicsItemPrivate( MarbleGraphicsItem *marbleGraphicsItem,
- MarbleGraphicsItem *parent = 0 )
+ MarbleGraphicsItem *parent = nullptr )
: m_repaintNeeded( true ),
m_cacheMode( MarbleGraphicsItem::NoCache ),
m_visibility( true ),
m_parent( parent ),
m_children(),
- m_layout( 0 ),
+ m_layout( nullptr ),
m_marbleGraphicsItem( marbleGraphicsItem )
{
if ( m_parent ) {
m_parent->d_func()->addChild(m_marbleGraphicsItem);
}
}
virtual ~MarbleGraphicsItemPrivate()
{
// Remove from parent
if ( m_parent ) {
m_parent->d_func()->removeChild(m_marbleGraphicsItem);
}
// Delete all children
qDeleteAll( m_children.toList() ); // delete using a copy, since children may invalidate m_children's iterator
// Delete Layout
delete m_layout;
}
void addChild( MarbleGraphicsItem *child )
{
m_children.insert( child );
}
void removeChild( MarbleGraphicsItem *child )
{
m_children.remove( child );
}
virtual QVector<QPointF> positions() const = 0;
virtual QVector<QPointF> absolutePositions() const = 0;
/**
* @brief Used to get the set of screen bounding rects
*/
QVector<QRectF> boundingRects() const;
virtual void setProjection( const ViewportParams *viewport ) = 0;
void updateChildPositions()
{
// This has to be done recursively because we need a correct size from all children.
for ( MarbleGraphicsItem *item: m_children ) {
item->d_func()->updateChildPositions();
}
// Adjust positions
if ( m_layout ) {
m_layout->updatePositions( m_marbleGraphicsItem );
}
}
QSizeF m_size;
bool m_repaintNeeded;
MarbleGraphicsItem::CacheMode m_cacheMode;
QPixmap m_pixmap;
bool m_visibility;
// The parent of the item
MarbleGraphicsItem *const m_parent;
// The set of children.
QSet<MarbleGraphicsItem *> m_children;
// The layout handling the positions of the children
AbstractMarbleGraphicsLayout *m_layout;
MarbleGraphicsItem *const m_marbleGraphicsItem;
};
}
#endif
diff --git a/src/lib/marble/graphicsview/ScreenGraphicsItem.h b/src/lib/marble/graphicsview/ScreenGraphicsItem.h
index 66849f48c..75304f6f6 100644
--- a/src/lib/marble/graphicsview/ScreenGraphicsItem.h
+++ b/src/lib/marble/graphicsview/ScreenGraphicsItem.h
@@ -1,105 +1,105 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_SCREENGRAPHICSITEM_H
#define MARBLE_SCREENGRAPHICSITEM_H
// Marble
#include "MarbleGraphicsItem.h"
#include "marble_export.h"
// Qt
#include <QVector>
namespace Marble
{
class ScreenGraphicsItemPrivate;
class MARBLE_EXPORT ScreenGraphicsItem : public MarbleGraphicsItem
{
public:
enum GraphicsItemFlag {
ItemIsMovable = 0x1,
ItemIsHideable = 0x2
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
- explicit ScreenGraphicsItem( MarbleGraphicsItem *parent = 0 );
+ explicit ScreenGraphicsItem( MarbleGraphicsItem *parent = nullptr );
~ScreenGraphicsItem() override;
/**
* @brief Set the position of the ScreenGraphicsItem
* @param pos Position
*
* Positive x-coordinates are counted left-aligned from the left border of the parent item.
* Negative x-coordinates are counted right-aligned from the right border of the parent item.
*
* Positive y-coordinates are counted top-aligned from the top border of the parent item.
* Negative y-coordinates are counted right-aligned from the bottom border of the parent item.
*/
void setPosition( const QPointF& position );
/**
* @brief Return the position of the ScreenGraphicsItem
*
* Positive x-coordinates are counted left-aligned from the left border of the parent item.
* Negative x-coordinates are counted right-aligned from the right border of the parent item.
*
* Positive y-coordinates are counted top-aligned from the top border of the parent item.
* Negative y-coordinates are counted right-aligned from the bottom border of the parent item.
*/
QPointF position() const;
/**
* @brief Return the positive position of the ScreenGraphicsItem
*
* All coordinates are counted positive and depend on the current viewport.
*
* Positive x-coordinates are counted left-aligned from the left border of the parent item.
* Positive y-coordinates are counted top-aligned from the top border of the parent item.
*/
QPointF positivePosition() const;
/**
* @brief Return the absolute position of the ScreenGraphicsItem
*
* All coordinates are counted positive and depend on the current viewport.
*
* Positive x-coordinates are counted left-aligned from the left border of the map.
* Positive y-coordinates are counted top-aligned from the top border of the map.
* @since 0.26.0
*/
QVector<QPointF> absolutePositions() const;
/**
* Returns the flags of the item.
*/
GraphicsItemFlags flags() const;
/**
* Sets the flags to flags. All flags in flags will be enabled and all other flags will
* be disabled. By default all flags are disabled.
*/
void setFlags( GraphicsItemFlags flags );
protected:
explicit ScreenGraphicsItem(ScreenGraphicsItemPrivate *dd);
bool eventFilter( QObject *, QEvent * ) override;
private:
Q_DECLARE_PRIVATE(ScreenGraphicsItem)
};
} // Namespace Marble
#endif
diff --git a/src/lib/marble/graphicsview/ScreenGraphicsItem_p.h b/src/lib/marble/graphicsview/ScreenGraphicsItem_p.h
index 68e4630e3..7ca1279df 100644
--- a/src/lib/marble/graphicsview/ScreenGraphicsItem_p.h
+++ b/src/lib/marble/graphicsview/ScreenGraphicsItem_p.h
@@ -1,118 +1,118 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009-2010 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_SCREENGRAPHICSITEMPRIVATE_H
#define MARBLE_SCREENGRAPHICSITEMPRIVATE_H
#include "MarbleGraphicsItem_p.h"
#include "MarbleDebug.h"
#include "BillboardGraphicsItem.h"
#include "ScreenGraphicsItem.h"
#include "ViewportParams.h"
namespace Marble
{
class ScreenGraphicsItemPrivate : public MarbleGraphicsItemPrivate
{
public:
ScreenGraphicsItemPrivate( ScreenGraphicsItem *screenGraphicsItem,
MarbleGraphicsItem *parent )
: MarbleGraphicsItemPrivate( screenGraphicsItem, parent ),
m_position(),
m_viewportSize(),
m_floatItemMoving( false ),
- m_flags( 0 )
+ m_flags( nullptr )
{
}
~ScreenGraphicsItemPrivate() override
{
}
QVector<QPointF> positions() const override
{
QVector<QPointF> list;
list.append( positivePosition() );
return list;
}
QPointF positivePosition() const
{
const QSizeF parentSize = m_parent ? m_parent->size() : m_viewportSize;
if ( !parentSize.isValid() ) {
mDebug() << "Invalid parent size";
return m_position;
}
QPointF position;
qreal x = m_position.x();
qreal y = m_position.y();
position.setX( ( x >= 0 ) ? x : parentSize.width() + x - m_size.width() );
position.setY( ( y >= 0 ) ? y : parentSize.height() + y - m_size.height() );
return position;
}
QVector<QPointF> absolutePositions() const override
{
- if( m_parent == 0 ) {
+ if( m_parent == nullptr ) {
return positions();
}
QVector<QPointF> parentPositions;
if( ScreenGraphicsItem *screenItem = dynamic_cast<ScreenGraphicsItem*>( m_parent ) ) {
parentPositions = screenItem->absolutePositions();
}
else if ( BillboardGraphicsItem *geoLabelItem = dynamic_cast<BillboardGraphicsItem *>( m_parent ) ) {
parentPositions = geoLabelItem->positions();
}
QPointF relativePosition = positivePosition();
QVector<QPointF> absolutePositions;
absolutePositions.reserve(parentPositions.size());
for( const QPointF &point: parentPositions ) {
absolutePositions.append( point + relativePosition );
}
return absolutePositions;
}
void setProjection(const ViewportParams *viewport) override
{
// If we have no parent
- if( m_parent == 0 ) {
+ if( m_parent == nullptr ) {
// Saving the screen size needed for positions()
m_viewportSize = viewport->size();
}
}
bool isMovable() const
{
return ( m_flags & ScreenGraphicsItem::ItemIsMovable ) ? true : false;
}
QPointF m_position;
// The size of the parent, or if no parent exists the size of the viewport.
QSizeF m_viewportSize;
QPoint m_floatItemMoveStartPos;
bool m_floatItemMoving;
ScreenGraphicsItem::GraphicsItemFlags m_flags;
};
}
#endif
diff --git a/src/lib/marble/graphicsview/WidgetGraphicsItem.cpp b/src/lib/marble/graphicsview/WidgetGraphicsItem.cpp
index b7ad8f8ec..2223f67d4 100644
--- a/src/lib/marble/graphicsview/WidgetGraphicsItem.cpp
+++ b/src/lib/marble/graphicsview/WidgetGraphicsItem.cpp
@@ -1,152 +1,152 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "WidgetGraphicsItem.h"
#include "WidgetGraphicsItem_p.h"
// Marble
#include "MarbleWidget.h"
#include "MarbleDebug.h"
// Qt
#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
#include <QWidget>
using namespace Marble;
WidgetGraphicsItemPrivate::WidgetGraphicsItemPrivate(WidgetGraphicsItem *widgetGraphicsItem,
MarbleGraphicsItem *parent)
: ScreenGraphicsItemPrivate(widgetGraphicsItem, parent),
- m_widget(0), m_marbleWidget(0), m_activeWidget( 0 )
+ m_widget(nullptr), m_marbleWidget(nullptr), m_activeWidget( nullptr )
{
// nothing to do
}
WidgetGraphicsItemPrivate::~WidgetGraphicsItemPrivate()
{
delete m_widget;
}
WidgetGraphicsItem::WidgetGraphicsItem( MarbleGraphicsItem *parent )
: ScreenGraphicsItem(new WidgetGraphicsItemPrivate(this, parent))
{
}
WidgetGraphicsItem::~WidgetGraphicsItem()
{
}
void WidgetGraphicsItem::setWidget(QWidget *widget)
{
Q_D(WidgetGraphicsItem);
d->m_widget = widget;
QSize size = widget->sizeHint().expandedTo( widget->size() );
size = size.expandedTo( widget->minimumSize() );
size = size.boundedTo( widget->maximumSize() );
setSize( size );
widget->resize( size );
}
QWidget *WidgetGraphicsItem::widget() const
{
Q_D(const WidgetGraphicsItem);
return d->m_widget;
}
void WidgetGraphicsItem::paint( QPainter *painter )
{
Q_D(WidgetGraphicsItem);
- if( d->m_widget == 0 )
+ if( d->m_widget == nullptr )
return;
// Paint widget without a background
d->m_widget->render( painter, QPoint( 0, 0 ), QRegion(), QWidget::RenderFlags( QWidget::DrawChildren) );
}
bool WidgetGraphicsItem::eventFilter( QObject *object, QEvent *e )
{
Q_D(WidgetGraphicsItem);
- if ( !visible() || d->m_widget == 0 ) {
+ if ( !visible() || d->m_widget == nullptr ) {
return false;
}
MarbleWidget *widget = dynamic_cast<MarbleWidget*> (object);
if ( !widget ) {
return ScreenGraphicsItem::eventFilter(object, e);
}
if ( d->m_marbleWidget != widget ) {
// Delayed initialization
d->m_marbleWidget = widget;
}
Q_ASSERT(d->m_marbleWidget);
if ( e->type() == QEvent::MouseButtonDblClick
|| e->type() == QEvent::MouseMove
|| e->type() == QEvent::MouseButtonPress
|| e->type() == QEvent::MouseButtonRelease )
{
// Mouse events are forwarded to the underlying widget
QMouseEvent *event = static_cast<QMouseEvent*> ( e );
const QVector<QPointF> widgetPositions = absolutePositions();
QRectF widgetItemRect;
QPoint shiftedPos;
QVector<QPointF>::ConstIterator it = widgetPositions.begin();
bool foundRightPosition = false;
for(; !foundRightPosition && it != widgetPositions.end(); ++it ) {
widgetItemRect = QRectF( *it, size() );
if ( widgetItemRect.contains( event->pos() ) ) {
foundRightPosition = true;
shiftedPos = event->pos() - widgetItemRect.topLeft().toPoint();
}
}
if ( foundRightPosition ) {
QWidget *child = d->m_widget->childAt( shiftedPos );
if ( d->m_activeWidget && d->m_activeWidget != child ) {
QEvent leaveEvent( QEvent::Leave );
QApplication::sendEvent( d->m_activeWidget, &leaveEvent );
}
if ( child && d->m_activeWidget != child ) {
QEvent enterEvent( QEvent::Enter );
QApplication::sendEvent( child, &enterEvent );
}
d->m_activeWidget = child;
if ( child ) {
shiftedPos -= child->pos(); // transform to children's coordinates
QMouseEvent shiftedEvent = QMouseEvent( e->type(), shiftedPos,
event->globalPos(), event->button(), event->buttons(),
event->modifiers() );
if ( QApplication::sendEvent( child, &shiftedEvent ) ) {
d->m_marbleWidget->setCursor( d->m_widget->cursor() );
return true;
}
}
} else {
if ( d->m_activeWidget ) {
QEvent leaveEvent( QEvent::Leave );
QApplication::sendEvent( d->m_activeWidget, &leaveEvent );
- d->m_activeWidget = 0;
+ d->m_activeWidget = nullptr;
}
}
}
return ScreenGraphicsItem::eventFilter(object, e);
}
diff --git a/src/lib/marble/graphicsview/WidgetGraphicsItem.h b/src/lib/marble/graphicsview/WidgetGraphicsItem.h
index 5c7f2d386..4c55d2165 100644
--- a/src/lib/marble/graphicsview/WidgetGraphicsItem.h
+++ b/src/lib/marble/graphicsview/WidgetGraphicsItem.h
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
//
#ifndef MARBLE_WIDGETGRAPHICSITEM_H
#define MARBLE_WIDGETGRAPHICSITEM_H
// Marble
#include "ScreenGraphicsItem.h"
#include "marble_export.h"
class QWidget;
namespace Marble
{
class WidgetGraphicsItemPrivate;
class MARBLE_EXPORT WidgetGraphicsItem : public ScreenGraphicsItem
{
public:
- explicit WidgetGraphicsItem( MarbleGraphicsItem *parent = 0 );
+ explicit WidgetGraphicsItem( MarbleGraphicsItem *parent = nullptr );
~WidgetGraphicsItem() override;
void setWidget( QWidget *widget );
QWidget *widget() const;
protected:
/**
* Paints the item in item coordinates.
*/
void paint( QPainter *painter ) override;
bool eventFilter( QObject *, QEvent * ) override;
private:
Q_DISABLE_COPY( WidgetGraphicsItem )
Q_DECLARE_PRIVATE(WidgetGraphicsItem)
};
} // Namespace Marble
#endif
diff --git a/src/lib/marble/kdescendantsproxymodel.h b/src/lib/marble/kdescendantsproxymodel.h
index 32e458d96..69b99a085 100644
--- a/src/lib/marble/kdescendantsproxymodel.h
+++ b/src/lib/marble/kdescendantsproxymodel.h
@@ -1,214 +1,214 @@
/*
Copyright (c) 2009 Stephen Kelly <steveire@gmail.com>
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_KDESCENDANTSPROXYMODEL_H
#define MARBLE_KDESCENDANTSPROXYMODEL_H
#include <QAbstractProxyModel>
#include "marble_export.h"
// namespace added to avoid symbol clashes with KF5::ItemModels
namespace Marble
{
class KDescendantsProxyModelPrivate;
/**
@brief Proxy Model for restructuring a Tree into a list.
A KDescendantsProxyModel may be used to alter how the items in the tree are presented.
Given a model which is represented as a tree:
\image html entitytreemodel.png "A plain EntityTreeModel in a view"
The KDescendantsProxyModel restructures the sourceModel to represent it as a flat list.
@code
// ... Create an entityTreeModel
KDescendantsProxyModel *descProxy = new KDescendantsProxyModel(this);
descProxy->setSourceModel(entityTree);
view->setModel(descProxy);
@endcode
\image html descendantentitiesproxymodel.png "A KDescendantsProxyModel."
KDescendantEntitiesProxyModel can also display the ancestors of the index in the source model as part of its display.
@code
// ... Create an entityTreeModel
KDescendantsProxyModel *descProxy = new KDescendantsProxyModel(this);
descProxy->setSourceModel(entityTree);
// #### This is new
descProxy->setDisplayAncestorData(true);
descProxy->setDisplayAncestorSeparator(QString(" / "));
view->setModel(descProxy);
@endcode
\image html descendantentitiesproxymodel-withansecnames.png "A KDescendantsProxyModel with ancestor names."
@since 4.6
@author Stephen Kelly <steveire@gmail.com>
*/
class MARBLE_EXPORT KDescendantsProxyModel : public QAbstractProxyModel
{
Q_OBJECT
public:
/**
* Creates a new descendant entities proxy model.
*
* @param parent The parent object.
*/
- explicit KDescendantsProxyModel(QObject *parent = 0);
+ explicit KDescendantsProxyModel(QObject *parent = nullptr);
/**
* Destroys the descendant entities proxy model.
*/
~KDescendantsProxyModel() override;
/**
* Sets the source @p model of the proxy.
*/
void setSourceModel(QAbstractItemModel *model) Q_DECL_OVERRIDE;
#if 0
/**
* @deprecated
*
* This method does nothing.
*/
void setRootIndex(const QModelIndex &index);
#endif
/**
* Set whether to show ancestor data in the model. If @p display is true, then
* a source model which is displayed as
*
* @code
* -> "Item 0-0" (this is row-depth)
* -> -> "Item 0-1"
* -> -> "Item 1-1"
* -> -> -> "Item 0-2"
* -> -> -> "Item 1-2"
* -> "Item 1-0"
* @endcode
*
* will be displayed as
*
* @code
* -> *Item 0-0"
* -> "Item 0-0 / Item 0-1"
* -> "Item 0-0 / Item 1-1"
* -> "Item 0-0 / Item 1-1 / Item 0-2"
* -> "Item 0-0 / Item 1-1 / Item 1-2"
* -> "Item 1-0"
* @endcode
*
* If @p display is false, the proxy will show
*
* @code
* -> *Item 0-0"
* -> "Item 0-1"
* -> "Item 1-1"
* -> "Item 0-2"
* -> "Item 1-2"
* -> "Item 1-0"
* @endcode
*
* Default is false.
*/
void setDisplayAncestorData(bool display);
/**
* Whether ancestor data will be displayed.
*/
bool displayAncestorData() const;
/**
* Sets the ancestor @p separator used between data of ancestors.
*/
void setAncestorSeparator(const QString &separator);
/**
* Separator used between data of ancestors.
*/
QString ancestorSeparator() const;
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const Q_DECL_OVERRIDE;
QModelIndex mapToSource(const QModelIndex &proxyIndex) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role) const Q_DECL_OVERRIDE;
QMimeData *mimeData(const QModelIndexList &indexes) const Q_DECL_OVERRIDE;
QStringList mimeTypes() const Q_DECL_OVERRIDE;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex parent(const QModelIndex &) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex &index = QModelIndex()) const Q_DECL_OVERRIDE;
Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE;
/**
Reimplemented to match all descendants.
*/
QModelIndexList match(const QModelIndex &start, int role, const QVariant &value,
int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchWrap)) const Q_DECL_OVERRIDE;
private:
Q_DECLARE_PRIVATE(KDescendantsProxyModel)
//@cond PRIVATE
KDescendantsProxyModelPrivate *d_ptr;
Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeInserted(const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(), void sourceRowsInserted(const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeRemoved(const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(), void sourceRowsRemoved(const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(), void sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))
Q_PRIVATE_SLOT(d_func(), void sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))
Q_PRIVATE_SLOT(d_func(), void sourceModelAboutToBeReset())
Q_PRIVATE_SLOT(d_func(), void sourceModelReset())
Q_PRIVATE_SLOT(d_func(), void sourceLayoutAboutToBeChanged())
Q_PRIVATE_SLOT(d_func(), void sourceLayoutChanged())
Q_PRIVATE_SLOT(d_func(), void sourceDataChanged(const QModelIndex &, const QModelIndex &))
Q_PRIVATE_SLOT(d_func(), void sourceModelDestroyed())
Q_PRIVATE_SLOT(d_func(), void processPendingParents())
// Make these private, they shouldn't be called by applications
// virtual bool insertRows(int , int, const QModelIndex & = QModelIndex());
// virtual bool insertColumns(int, int, const QModelIndex & = QModelIndex());
// virtual bool removeRows(int, int, const QModelIndex & = QModelIndex());
// virtual bool removeColumns(int, int, const QModelIndex & = QModelIndex());
//@endcond
};
}
#endif
diff --git a/src/lib/marble/kineticmodel.h b/src/lib/marble/kineticmodel.h
index b9433aca1..3226ae6f5 100644
--- a/src/lib/marble/kineticmodel.h
+++ b/src/lib/marble/kineticmodel.h
@@ -1,80 +1,80 @@
/*
This file is part of the Ofi Labs X2 project.
Copyright (C) 2010 Ariya Hidayat <ariya.hidayat@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OFILABS_KINETICMODEL
#define OFILABS_KINETICMODEL
#include <QObject>
#include <QScopedPointer>
#include <QPointF>
class KineticModelPrivate;
class KineticModel: public QObject
{
Q_OBJECT
Q_PROPERTY(int duration READ duration WRITE setDuration)
Q_PROPERTY(QPointF position READ position NOTIFY positionChanged)
Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval)
public:
- explicit KineticModel(QObject *parent = 0);
+ explicit KineticModel(QObject *parent = nullptr);
~KineticModel() override;
int duration() const;
QPointF position() const;
int updateInterval() const;
bool hasVelocity() const;
public Q_SLOTS:
void setDuration(int ms);
void setPosition(const QPointF& position);
void setPosition(qreal posX, qreal posY);
void setHeading(qreal heading);
void jumpToPosition(const QPointF& position);
void jumpToPosition(qreal posX, qreal posY);
void setUpdateInterval(int ms);
void stop();
void start();
Q_SIGNALS:
void positionChanged( qreal lon, qreal lat );
void headingChanged( qreal heading );
void finished();
private Q_SLOTS:
void update();
private:
QScopedPointer<KineticModelPrivate> d_ptr;
Q_DECLARE_PRIVATE(KineticModel);
Q_DISABLE_COPY(KineticModel);
};
#endif
diff --git a/src/lib/marble/layers/FloatItemsLayer.h b/src/lib/marble/layers/FloatItemsLayer.h
index f3d543806..2f7a96c84 100644
--- a/src/lib/marble/layers/FloatItemsLayer.h
+++ b/src/lib/marble/layers/FloatItemsLayer.h
@@ -1,77 +1,77 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012-2016 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_FLOATITEMSLAYER_H
#define MARBLE_FLOATITEMSLAYER_H
#include <QObject>
#include "LayerInterface.h"
#include <QList>
#include <QRegion>
namespace Marble
{
class AbstractFloatItem;
class RenderPlugin;
/**
* @brief Layer for handling the rendering of screen-positioned, 2D float items.
*/
class FloatItemsLayer : public QObject, public LayerInterface
{
Q_OBJECT
public:
- explicit FloatItemsLayer(QObject *parent = 0);
+ explicit FloatItemsLayer(QObject *parent = nullptr);
QStringList renderPosition() const override;
bool render(GeoPainter *painter, ViewportParams *viewport,
- const QString &renderPos = "NONE", GeoSceneLayer *layer = 0) override;
+ const QString &renderPos = "NONE", GeoSceneLayer *layer = nullptr) override;
void addFloatItem(AbstractFloatItem *floatItem);
/**
* @brief Returns a list of all FloatItems of the layer
* @return the list of the floatItems
*/
QList<AbstractFloatItem *> floatItems() const;
QString runtimeTrace() const override;
Q_SIGNALS:
/**
* @brief Signal that a render item has been initialized
*/
void renderPluginInitialized(RenderPlugin *renderPlugin);
/**
* This signal is emitted when the repaint of the view was requested by a plugin.
* 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(const QRegion &dirtyRegion = QRegion());
void visibilityChanged(const QString &nameId, bool visible);
void pluginSettingsChanged();
private Q_SLOTS:
void updateVisibility(bool visible, const QString &nameId);
private:
QList<AbstractFloatItem *> m_floatItems;
};
}
#endif
diff --git a/src/lib/marble/layers/FogLayer.h b/src/lib/marble/layers/FogLayer.h
index c78b2b802..dcf16baeb 100644
--- a/src/lib/marble/layers/FogLayer.h
+++ b/src/lib/marble/layers/FogLayer.h
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008, 2009, 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
// Copyright 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
//
#ifndef MARBLE_FOGLAYER_H
#define MARBLE_FOGLAYER_H
#include "LayerInterface.h"
#include <QString>
namespace Marble
{
class FogLayer : public LayerInterface
{
public:
QStringList renderPosition() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos = QLatin1String("NONE"),
- GeoSceneLayer * layer = 0 ) override;
+ GeoSceneLayer * layer = nullptr ) override;
RenderState renderState() const override;
QString runtimeTrace() const override { return QStringLiteral("FogLayer"); }
};
}
#endif
diff --git a/src/lib/marble/layers/GeometryLayer.cpp b/src/lib/marble/layers/GeometryLayer.cpp
index a16da8994..f43b3e552 100644
--- a/src/lib/marble/layers/GeometryLayer.cpp
+++ b/src/lib/marble/layers/GeometryLayer.cpp
@@ -1,715 +1,715 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
// Copyright 2010 Thibaut Gridel <tgridel@free.fr>
// Copyright 2011-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2014 Gábor Péterffy <peterffy95@gmail.com>
//
#include "GeometryLayer.h"
// Marble
#include "GeoDataLatLonAltBox.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataLineStyle.h"
#include "GeoDataMultiTrack.h"
#include "GeoDataObject.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLinearRing.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataPolygon.h"
#include "GeoDataBuilding.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataTrack.h"
#include "GeoDataFeature.h"
#include "MarbleDebug.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "RenderState.h"
#include "GeoGraphicsScene.h"
#include "GeoGraphicsItem.h"
#include "GeoLineStringGraphicsItem.h"
#include "GeoPolygonGraphicsItem.h"
#include "GeoTrackGraphicsItem.h"
#include "GeoDataPhotoOverlay.h"
#include "GeoDataScreenOverlay.h"
#include "GeoPhotoGraphicsItem.h"
#include "ScreenOverlayGraphicsItem.h"
#include "TileId.h"
#include "MarbleGraphicsItem.h"
#include "MarblePlacemarkModel.h"
#include "GeoDataTreeModel.h"
#include <OsmPlacemarkData.h>
#include "StyleBuilder.h"
#include "AbstractGeoPolygonGraphicsItem.h"
#include "GeoLineStringGraphicsItem.h"
#include "GeoDataRelation.h"
// Qt
#include <qmath.h>
#include <QAbstractItemModel>
#include <QModelIndex>
namespace Marble
{
class GeometryLayerPrivate
{
public:
typedef QVector<GeoLineStringGraphicsItem*> OsmLineStringItems;
typedef QSet<const GeoDataRelation *> Relations;
typedef QHash<const GeoDataFeature *, Relations> FeatureRelationHash;
typedef QVector<GeoGraphicsItem*> GeoGraphicItems;
struct PaintFragments {
// Three lists for different z values
// A z value of 0 is default and used by the majority of items, so sorting
// can be avoided for it
QVector<GeoGraphicsItem*> negative; // subways
QVector<GeoGraphicsItem*> null; // areas and roads
QVector<GeoGraphicsItem*> positive; // buildings
};
explicit GeometryLayerPrivate(const QAbstractItemModel *model, const StyleBuilder *styleBuilder);
void createGraphicsItems(const GeoDataObject *object);
void createGraphicsItems(const GeoDataObject *object, FeatureRelationHash &relations);
void createGraphicsItemFromGeometry(const GeoDataGeometry *object, const GeoDataPlacemark *placemark, const Relations &relations);
void createGraphicsItemFromOverlay(const GeoDataOverlay *overlay);
void removeGraphicsItems(const GeoDataFeature *feature);
void updateTiledLineStrings(const GeoDataPlacemark *placemark, GeoLineStringGraphicsItem* lineStringItem);
static void updateTiledLineStrings(OsmLineStringItems &lineStringItems);
void clearCache();
bool showRelation(const GeoDataRelation* relation) const;
void updateRelationVisibility();
const QAbstractItemModel *const m_model;
const StyleBuilder *const m_styleBuilder;
GeoGraphicsScene m_scene;
QString m_runtimeTrace;
QList<ScreenOverlayGraphicsItem*> m_screenOverlays;
QHash<qint64, OsmLineStringItems> m_osmLineStringItems;
int m_tileLevel;
GeoGraphicsItem* m_lastFeatureAt;
bool m_dirty;
int m_cachedItemCount;
QHash<QString, GeoGraphicItems> m_cachedPaintFragments;
typedef QPair<QString, GeoGraphicsItem*> LayerItem;
QList<LayerItem> m_cachedDefaultLayer;
QDateTime m_cachedDateTime;
GeoDataLatLonBox m_cachedLatLonBox;
QSet<qint64> m_highlightedRouteRelations;
GeoDataRelation::RelationTypes m_visibleRelationTypes;
bool m_levelTagDebugModeEnabled;
int m_debugLevelTag;
};
GeometryLayerPrivate::GeometryLayerPrivate(const QAbstractItemModel *model, const StyleBuilder *styleBuilder) :
m_model(model),
m_styleBuilder(styleBuilder),
m_tileLevel(0),
m_lastFeatureAt(nullptr),
m_dirty(true),
m_cachedItemCount(0),
m_visibleRelationTypes(GeoDataRelation::RouteFerry),
m_levelTagDebugModeEnabled(false),
m_debugLevelTag(0)
{
}
void GeometryLayerPrivate::createGraphicsItems(const GeoDataObject *object)
{
FeatureRelationHash noRelations;
createGraphicsItems(object, noRelations);
}
GeometryLayer::GeometryLayer(const QAbstractItemModel *model, const StyleBuilder *styleBuilder) :
d(new GeometryLayerPrivate(model, styleBuilder))
{
const GeoDataObject *object = static_cast<GeoDataObject*>(d->m_model->index(0, 0, QModelIndex()).internalPointer());
if (object && object->parent()) {
d->createGraphicsItems(object->parent());
}
connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
this, SLOT(resetCacheData()));
connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)),
this, SLOT(addPlacemarks(QModelIndex, int, int)));
connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
this, SLOT(removePlacemarks(QModelIndex, int, int)));
connect(model, SIGNAL(modelReset()),
this, SLOT(resetCacheData()));
connect(this, SIGNAL(highlightedPlacemarksChanged(QVector<GeoDataPlacemark*>)),
&d->m_scene, SLOT(applyHighlight(QVector<GeoDataPlacemark*>)));
connect(&d->m_scene, SIGNAL(repaintNeeded()),
this, SIGNAL(repaintNeeded()));
}
GeometryLayer::~GeometryLayer()
{
delete d;
}
QStringList GeometryLayer::renderPosition() const
{
return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE"));
}
bool GeometryLayer::render(GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos, GeoSceneLayer * layer)
{
Q_UNUSED(renderPos)
Q_UNUSED(layer)
painter->save();
auto const & box = viewport->viewLatLonAltBox();
bool isEqual = GeoDataLatLonBox::fuzzyCompare(d->m_cachedLatLonBox, box, 0.05);
if (d->m_cachedLatLonBox.isEmpty() || !isEqual) {
d->m_dirty = true;
}
// update the items cache at least every second since the last request
auto const now = QDateTime::currentDateTime();
if (!d->m_cachedDateTime.isValid() || d->m_cachedDateTime.msecsTo(now) > 1000) {
d->m_dirty = true;
}
if (d->m_dirty) {
d->m_dirty = false;
const int maxZoomLevel = qMin(d->m_tileLevel, d->m_styleBuilder->maximumZoomLevel());
auto const items = d->m_scene.items(box, maxZoomLevel);;
d->m_cachedLatLonBox = box;
d->m_cachedDateTime = now;
d->m_cachedItemCount = items.size();
d->m_cachedDefaultLayer.clear();
d->m_cachedPaintFragments.clear();
QHash<QString, GeometryLayerPrivate::PaintFragments> paintFragments;
QSet<QString> const knownLayers = QSet<QString>::fromList(d->m_styleBuilder->renderOrder());
for (GeoGraphicsItem* item: items) {
QStringList paintLayers = item->paintLayers();
if (paintLayers.isEmpty()) {
mDebug() << item << " provides no paint layers, so I force one onto it.";
paintLayers << QString();
}
for (const auto &layer: paintLayers) {
if (knownLayers.contains(layer)) {
GeometryLayerPrivate::PaintFragments &fragments = paintFragments[layer];
double const zValue = item->zValue();
// assign subway stations
if (zValue == 0.0) {
fragments.null << item;
// assign areas and streets
} else if (zValue < 0.0) {
fragments.negative << item;
// assign buildings
} else {
fragments.positive << item;
}
} else {
// assign symbols
d->m_cachedDefaultLayer << GeometryLayerPrivate::LayerItem(layer, item);
static QSet<QString> missingLayers;
if (!missingLayers.contains(layer)) {
mDebug() << "Missing layer " << layer << ", in render order, will render it on top";
missingLayers << layer;
}
}
}
}
// Sort each fragment by z-level
for (const QString &layer: d->m_styleBuilder->renderOrder()) {
GeometryLayerPrivate::PaintFragments & layerItems = paintFragments[layer];
std::sort(layerItems.negative.begin(), layerItems.negative.end(), GeoGraphicsItem::zValueLessThan);
// The idea here is that layerItems.null has most items and does not need to be sorted by z-value
// since they are all equal (=0). We do sort them by style pointer though for batch rendering
std::sort(layerItems.null.begin(), layerItems.null.end(), GeoGraphicsItem::styleLessThan);
std::sort(layerItems.positive.begin(), layerItems.positive.end(), GeoGraphicsItem::zValueAndStyleLessThan);
auto const count = layerItems.negative.size() + layerItems.null.size() + layerItems.positive.size();
d->m_cachedPaintFragments[layer].reserve(count);
d->m_cachedPaintFragments[layer] << layerItems.negative;
d->m_cachedPaintFragments[layer] << layerItems.null;
d->m_cachedPaintFragments[layer] << layerItems.positive;
}
}
for (const QString &layer: d->m_styleBuilder->renderOrder()) {
auto & layerItems = d->m_cachedPaintFragments[layer];
- AbstractGeoPolygonGraphicsItem::s_previousStyle = 0;
- GeoLineStringGraphicsItem::s_previousStyle = 0;
+ AbstractGeoPolygonGraphicsItem::s_previousStyle = nullptr;
+ GeoLineStringGraphicsItem::s_previousStyle = nullptr;
for (auto item: layerItems) {
if (d->m_levelTagDebugModeEnabled) {
if (const auto placemark = geodata_cast<GeoDataPlacemark>(item->feature())) {
if (placemark->hasOsmData()) {
QHash<QString, QString>::const_iterator tagIter = placemark->osmData().findTag(QStringLiteral("level"));
if (tagIter != placemark->osmData().tagsEnd()) {
const int val = tagIter.value().toInt();
if (val != d->m_debugLevelTag) {
continue;
}
}
}
}
}
item->paint(painter, viewport, layer, d->m_tileLevel);
}
}
for (const auto & item: d->m_cachedDefaultLayer) {
item.second->paint(painter, viewport, item.first, d->m_tileLevel);
}
for (ScreenOverlayGraphicsItem* item: d->m_screenOverlays) {
item->paintEvent(painter, viewport);
}
painter->restore();
d->m_runtimeTrace = QStringLiteral("Geometries: %1 Zoom: %2")
.arg(d->m_cachedItemCount)
.arg(d->m_tileLevel);
return true;
}
RenderState GeometryLayer::renderState() const
{
return RenderState(QStringLiteral("GeoGraphicsScene"));
}
QString GeometryLayer::runtimeTrace() const
{
return d->m_runtimeTrace;
}
bool GeometryLayer::hasFeatureAt(const QPoint &curpos, const ViewportParams *viewport)
{
if (d->m_lastFeatureAt && d->m_lastFeatureAt->contains(curpos, viewport)) {
return true;
}
auto const renderOrder = d->m_styleBuilder->renderOrder();
for (int i = renderOrder.size() - 1; i >= 0; --i) {
auto & layerItems = d->m_cachedPaintFragments[renderOrder[i]];
for (auto item : layerItems) {
if (item->contains(curpos, viewport)) {
d->m_lastFeatureAt = item;
return true;
}
}
}
return false;
}
void GeometryLayerPrivate::createGraphicsItems(const GeoDataObject *object, FeatureRelationHash &relations)
{
clearCache();
if (auto document = geodata_cast<GeoDataDocument>(object)) {
for (auto feature: document->featureList()) {
if (auto relation = geodata_cast<GeoDataRelation>(feature)) {
relation->setVisible(showRelation(relation));
for (auto member: relation->members()) {
relations[member] << relation;
}
}
}
}
if (auto placemark = geodata_cast<GeoDataPlacemark>(object)) {
createGraphicsItemFromGeometry(placemark->geometry(), placemark, relations.value(placemark));
} else if (const GeoDataOverlay* overlay = dynamic_cast<const GeoDataOverlay*>(object)) {
createGraphicsItemFromOverlay(overlay);
}
// parse all child objects of the container
if (const GeoDataContainer *container = dynamic_cast<const GeoDataContainer*>(object)) {
int rowCount = container->size();
for (int row = 0; row < rowCount; ++row) {
createGraphicsItems(container->child(row), relations);
}
}
}
void GeometryLayerPrivate::updateTiledLineStrings(const GeoDataPlacemark* placemark, GeoLineStringGraphicsItem* lineStringItem)
{
if (!placemark->hasOsmData()) {
return;
}
qint64 const osmId = placemark->osmData().oid();
if (osmId <= 0) {
return;
}
auto & lineStringItems = m_osmLineStringItems[osmId];
lineStringItems << lineStringItem;
updateTiledLineStrings(lineStringItems);
}
void GeometryLayerPrivate::updateTiledLineStrings(OsmLineStringItems &lineStringItems)
{
GeoDataLineString merged;
if (lineStringItems.size() > 1) {
QVector<const GeoDataLineString*> lineStrings;
for (auto item : lineStringItems) {
lineStrings << item->lineString();
}
merged = GeoLineStringGraphicsItem::merge(lineStrings);
}
// If merging failed, reset all. Otherwise only the first one
// gets the merge result and becomes visible.
bool visible = true;
for (auto item : lineStringItems) {
item->setVisible(visible);
if (visible) {
item->setMergedLineString(merged);
visible = merged.isEmpty();
}
}
}
void GeometryLayerPrivate::clearCache()
{
m_lastFeatureAt = nullptr;
m_dirty = true;
m_cachedDateTime = QDateTime();
m_cachedItemCount = 0;
m_cachedPaintFragments.clear();
m_cachedDefaultLayer.clear();
m_cachedLatLonBox = GeoDataLatLonBox();
}
inline bool GeometryLayerPrivate::showRelation(const GeoDataRelation *relation) const
{
return (m_visibleRelationTypes.testFlag(relation->relationType())
|| m_highlightedRouteRelations.contains(relation->osmData().oid()));
}
void GeometryLayerPrivate::updateRelationVisibility()
{
for (int i = 0; i < m_model->rowCount(); ++i) {
QVariant const data = m_model->data(m_model->index(i, 0), MarblePlacemarkModel::ObjectPointerRole);
GeoDataObject *object = qvariant_cast<GeoDataObject*> (data);
if (auto doc = geodata_cast<GeoDataDocument>(object)) {
for (auto feature: doc->featureList()) {
if (auto relation = geodata_cast<GeoDataRelation>(feature)) {
relation->setVisible(showRelation(relation));
}
}
}
}
m_scene.resetStyle();
}
void GeometryLayerPrivate::createGraphicsItemFromGeometry(const GeoDataGeometry* object, const GeoDataPlacemark *placemark, const Relations &relations)
{
if (!placemark->isGloballyVisible()) {
return; // Reconsider this when visibility can be changed dynamically
}
- GeoGraphicsItem *item = 0;
+ GeoGraphicsItem *item = nullptr;
if (const auto line = geodata_cast<GeoDataLineString>(object)) {
auto lineStringItem = new GeoLineStringGraphicsItem(placemark, line);
item = lineStringItem;
updateTiledLineStrings(placemark, lineStringItem);
} else if (const auto ring = geodata_cast<GeoDataLinearRing>(object)) {
item = GeoPolygonGraphicsItem::createGraphicsItem(placemark, ring);
} else if (const auto poly = geodata_cast<GeoDataPolygon>(object)) {
item = GeoPolygonGraphicsItem::createGraphicsItem(placemark, poly);
if (item->zValue() == 0) {
item->setZValue(poly->renderOrder());
}
} else if (const auto building = geodata_cast<GeoDataBuilding>(object)) {
item = GeoPolygonGraphicsItem::createGraphicsItem(placemark, building);
} else if (const auto multigeo = geodata_cast<GeoDataMultiGeometry>(object)) {
int rowCount = multigeo->size();
for (int row = 0; row < rowCount; ++row) {
createGraphicsItemFromGeometry(multigeo->child(row), placemark, relations);
}
} else if (const auto multitrack = geodata_cast<GeoDataMultiTrack>(object)) {
int rowCount = multitrack->size();
for (int row = 0; row < rowCount; ++row) {
createGraphicsItemFromGeometry(multitrack->child(row), placemark, relations);
}
} else if (const auto track = geodata_cast<GeoDataTrack>(object)) {
item = new GeoTrackGraphicsItem(placemark, track);
}
if (!item) {
return;
}
item->setRelations(relations);
item->setStyleBuilder(m_styleBuilder);
item->setVisible(item->visible() && placemark->isGloballyVisible());
item->setMinZoomLevel(m_styleBuilder->minimumZoomLevel(*placemark));
m_scene.addItem(item);
}
void GeometryLayerPrivate::createGraphicsItemFromOverlay(const GeoDataOverlay *overlay)
{
if (!overlay->isGloballyVisible()) {
return; // Reconsider this when visibility can be changed dynamically
}
- GeoGraphicsItem* item = 0;
+ GeoGraphicsItem* item = nullptr;
if (const auto photoOverlay = geodata_cast<GeoDataPhotoOverlay>(overlay)) {
GeoPhotoGraphicsItem *photoItem = new GeoPhotoGraphicsItem(overlay);
photoItem->setPoint(photoOverlay->point());
item = photoItem;
} else if (const auto screenOverlay = geodata_cast<GeoDataScreenOverlay>(overlay)) {
ScreenOverlayGraphicsItem *screenItem = new ScreenOverlayGraphicsItem(screenOverlay);
m_screenOverlays.push_back(screenItem);
}
if (item) {
item->setStyleBuilder(m_styleBuilder);
item->setVisible(overlay->isGloballyVisible());
m_scene.addItem(item);
}
}
void GeometryLayerPrivate::removeGraphicsItems(const GeoDataFeature *feature)
{
clearCache();
if (const auto placemark = geodata_cast<GeoDataPlacemark>(feature)) {
if (placemark->isGloballyVisible() &&
geodata_cast<GeoDataLineString>(placemark->geometry()) &&
placemark->hasOsmData() &&
placemark->osmData().oid() > 0) {
auto & items = m_osmLineStringItems[placemark->osmData().oid()];
bool removed = false;
for (auto item : items) {
if (item->feature() == feature) {
items.removeOne(item);
removed = true;
break;
}
}
Q_ASSERT(removed);
updateTiledLineStrings(items);
}
m_scene.removeItem(feature);
} else if (const auto container = dynamic_cast<const GeoDataContainer*>(feature)) {
for (const GeoDataFeature *child: container->featureList()) {
removeGraphicsItems(child);
}
} else if (geodata_cast<GeoDataScreenOverlay>(feature)) {
for (ScreenOverlayGraphicsItem *item: m_screenOverlays) {
if (item->screenOverlay() == feature) {
m_screenOverlays.removeAll(item);
}
}
}
}
void GeometryLayer::addPlacemarks(const QModelIndex& parent, int first, int last)
{
Q_ASSERT(first < d->m_model->rowCount(parent));
Q_ASSERT(last < d->m_model->rowCount(parent));
for (int i = first; i <= last; ++i) {
QModelIndex index = d->m_model->index(i, 0, parent);
Q_ASSERT(index.isValid());
const GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data(MarblePlacemarkModel::ObjectPointerRole));
Q_ASSERT(object);
d->createGraphicsItems(object);
}
emit repaintNeeded();
}
void GeometryLayer::removePlacemarks(const QModelIndex& parent, int first, int last)
{
Q_ASSERT(last < d->m_model->rowCount(parent));
bool isRepaintNeeded = false;
for (int i = first; i <= last; ++i) {
QModelIndex index = d->m_model->index(i, 0, parent);
Q_ASSERT(index.isValid());
const GeoDataObject *object = qvariant_cast<GeoDataObject*>(index.data(MarblePlacemarkModel::ObjectPointerRole));
const GeoDataFeature *feature = dynamic_cast<const GeoDataFeature*>(object);
- if (feature != 0) {
+ if (feature != nullptr) {
d->removeGraphicsItems(feature);
isRepaintNeeded = true;
}
}
if (isRepaintNeeded) {
emit repaintNeeded();
}
}
void GeometryLayer::resetCacheData()
{
d->clearCache();
d->m_scene.clear();
qDeleteAll(d->m_screenOverlays);
d->m_screenOverlays.clear();
d->m_osmLineStringItems.clear();
const GeoDataObject *object = static_cast<GeoDataObject*>(d->m_model->index(0, 0, QModelIndex()).internalPointer());
if (object && object->parent()) {
d->createGraphicsItems(object->parent());
}
emit repaintNeeded();
}
void GeometryLayer::setTileLevel(int tileLevel)
{
d->m_tileLevel = tileLevel;
}
QVector<const GeoDataFeature*> GeometryLayer::whichFeatureAt(const QPoint &curpos, const ViewportParams *viewport)
{
QVector<const GeoDataFeature*> result;
auto const renderOrder = d->m_styleBuilder->renderOrder();
QString const label = QStringLiteral("/label");
QSet<GeoGraphicsItem*> checked;
for (int i = renderOrder.size()-1; i >= 0; --i) {
if (renderOrder[i].endsWith(label)) {
continue;
}
auto & layerItems = d->m_cachedPaintFragments[renderOrder[i]];
for (auto j = layerItems.size()-1; j >= 0; --j) {
auto const & layerItem = layerItems[j];
if (!checked.contains(layerItem)) {
if (layerItem->contains(curpos, viewport)) {
result << layerItem->feature();
}
checked << layerItem;
}
}
}
return result;
}
void GeometryLayer::highlightRouteRelation(qint64 osmId, bool enabled)
{
if (enabled) {
d->m_highlightedRouteRelations << osmId;
} else {
d->m_highlightedRouteRelations.remove(osmId);
}
d->updateRelationVisibility();
}
void GeometryLayer::setVisibleRelationTypes(GeoDataRelation::RelationTypes relationTypes)
{
if (relationTypes != d->m_visibleRelationTypes) {
d->m_visibleRelationTypes = relationTypes;
d->updateRelationVisibility();
}
}
void GeometryLayer::handleHighlight(qreal lon, qreal lat, GeoDataCoordinates::Unit unit)
{
GeoDataCoordinates clickedPoint(lon, lat, 0, unit);
QVector<GeoDataPlacemark*> selectedPlacemarks;
for (int i = 0; i < d->m_model->rowCount(); ++i) {
QVariant const data = d->m_model->data(d->m_model->index(i, 0), MarblePlacemarkModel::ObjectPointerRole);
GeoDataObject *object = qvariant_cast<GeoDataObject*> (data);
Q_ASSERT(object);
if (const auto doc = geodata_cast<GeoDataDocument>(object)) {
bool isHighlight = false;
for (const GeoDataStyleMap &styleMap: doc->styleMaps()) {
if (styleMap.contains(QStringLiteral("highlight"))) {
isHighlight = true;
break;
}
}
/*
* If a document doesn't specify any highlight
* styleId in its style maps then there is no need
* to further check that document for placemarks
* which have been clicked because we won't
* highlight them.
*/
if (isHighlight) {
QVector<GeoDataFeature*>::Iterator iter = doc->begin();
QVector<GeoDataFeature*>::Iterator const end = doc->end();
for (; iter != end; ++iter) {
if (auto placemark = geodata_cast<GeoDataPlacemark>(*iter)) {
GeoDataPolygon *polygon = dynamic_cast<GeoDataPolygon*>(placemark->geometry());
if (polygon &&
polygon->contains(clickedPoint)) {
selectedPlacemarks.push_back(placemark);
}
if (auto linearRing = geodata_cast<GeoDataLinearRing>(placemark->geometry())) {
if (linearRing->contains(clickedPoint)) {
selectedPlacemarks.push_back(placemark);
}
}
if (auto multiGeometry = geodata_cast<GeoDataMultiGeometry>(placemark->geometry())) {
QVector<GeoDataGeometry*>::Iterator multiIter = multiGeometry->begin();
QVector<GeoDataGeometry*>::Iterator const multiEnd = multiGeometry->end();
for (; multiIter != multiEnd; ++multiIter) {
GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>(*multiIter);
if (poly &&
poly->contains(clickedPoint)) {
selectedPlacemarks.push_back(placemark);
break;
}
if (auto linearRing = geodata_cast<GeoDataLinearRing>(*multiIter)) {
if (linearRing->contains(clickedPoint)) {
selectedPlacemarks.push_back(placemark);
break;
}
}
}
}
}
}
}
}
}
emit highlightedPlacemarksChanged(selectedPlacemarks);
}
void GeometryLayer::setLevelTagDebugModeEnabled(bool enabled)
{
if (d->m_levelTagDebugModeEnabled != enabled) {
d->m_levelTagDebugModeEnabled = enabled;
emit repaintNeeded();
}
}
bool GeometryLayer::levelTagDebugModeEnabled() const
{
return d->m_levelTagDebugModeEnabled;
}
void GeometryLayer::setDebugLevelTag(int level)
{
if (d->m_debugLevelTag != level) {
d->m_debugLevelTag = level;
emit repaintNeeded();
}
}
int GeometryLayer::debugLevelTag() const
{
return d->m_debugLevelTag;
}
}
#include "moc_GeometryLayer.cpp"
diff --git a/src/lib/marble/layers/GeometryLayer.h b/src/lib/marble/layers/GeometryLayer.h
index 0f2055e66..2b555d797 100644
--- a/src/lib/marble/layers/GeometryLayer.h
+++ b/src/lib/marble/layers/GeometryLayer.h
@@ -1,103 +1,103 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Patrick Spendrin <ps_ml@gmx.de>
// Copyright 2010 Thibaut Gridel <tgridel@free.fr>
// Copyright 2011-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_GEOMETRYLAYER_H
#define MARBLE_GEOMETRYLAYER_H
#include <QObject>
#include "LayerInterface.h"
#include "GeoDataCoordinates.h"
#include "GeoDataRelation.h"
class QAbstractItemModel;
class QModelIndex;
class QPoint;
namespace Marble
{
class GeoPainter;
class GeoDataFeature;
class GeoDataPlacemark;
class GeoDataRelation;
class StyleBuilder;
class ViewportParams;
class GeometryLayerPrivate;
class GeometryLayer : public QObject, public LayerInterface
{
Q_OBJECT
public:
explicit GeometryLayer(const QAbstractItemModel *model, const StyleBuilder *styleBuilder);
~GeometryLayer() override;
QStringList renderPosition() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos = QLatin1String("NONE"),
- GeoSceneLayer * layer = 0 ) override;
+ GeoSceneLayer * layer = nullptr ) override;
RenderState renderState() const override;
QString runtimeTrace() const override;
bool hasFeatureAt(const QPoint& curpos, const ViewportParams * viewport);
QVector<const GeoDataFeature*> whichFeatureAt( const QPoint& curpos, const ViewportParams * viewport );
void highlightRouteRelation(qint64 osmId, bool enabled);
void setVisibleRelationTypes(GeoDataRelation::RelationTypes relationTypes);
void setLevelTagDebugModeEnabled(bool enabled);
bool levelTagDebugModeEnabled() const;
void setDebugLevelTag(int level);
int debugLevelTag() const;
public Q_SLOTS:
void addPlacemarks( const QModelIndex& index, int first, int last );
void removePlacemarks( const QModelIndex& index, int first, int last );
void resetCacheData();
void setTileLevel(int tileLevel);
/**
* Finds all placemarks that contain the clicked point.
*
* The placemarks under the clicked position may
* have their styleUrl set to a style map which
* doesn't specify any highlight styleId. Such
* placemarks will be fletered out in GeoGraphicsScene
* and will not be highlighted.
*/
void handleHighlight( qreal lon, qreal lat, GeoDataCoordinates::Unit unit );
Q_SIGNALS:
void repaintNeeded();
/**
* @p selectedPlacemarks may contain placemarks which don't have
* their styleUrl set to id of the style map which specifies
* a highlight styleId. Such placemarks will be filtered out
* in GeoGraphicsScene which will query for placemark->styleUrl()
* to decide whether the placemark should be highlighted ot not.
*/
void highlightedPlacemarksChanged( const QVector<GeoDataPlacemark*>& clickedPlacemarks );
private:
GeometryLayerPrivate *d;
};
} // namespace Marble
#endif // MARBLE_GEOMETRYLAYER_H
diff --git a/src/lib/marble/layers/GroundLayer.h b/src/lib/marble/layers/GroundLayer.h
index 1857dfb1a..b18b160cf 100644
--- a/src/lib/marble/layers/GroundLayer.h
+++ b/src/lib/marble/layers/GroundLayer.h
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Cezar Mocan <mocancezar@gmail.com>
//
#ifndef MARBLE_GROUNDLAYER_H
#define MARBLE_GROUNDLAYER_H
#include "LayerInterface.h"
#include <QColor>
namespace Marble
{
class GroundLayer : public LayerInterface
{
public:
GroundLayer();
~GroundLayer() override;
QStringList renderPosition() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos = QLatin1String("NONE"),
- GeoSceneLayer * layer = 0 ) override;
+ GeoSceneLayer * layer = nullptr ) override;
qreal zValue() const override;
void setColor( const QColor &color );
QColor color() const;
RenderState renderState() const override;
QString runtimeTrace() const override { return QStringLiteral("GroundLayer"); }
private:
QColor m_color; // Gets the color specified via DGML's <map bgcolor="">
};
}
#endif
diff --git a/src/lib/marble/layers/MarbleSplashLayer.h b/src/lib/marble/layers/MarbleSplashLayer.h
index ec5799c72..606b2cd20 100644
--- a/src/lib/marble/layers/MarbleSplashLayer.h
+++ b/src/lib/marble/layers/MarbleSplashLayer.h
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_MARBLESPLASHLAYER_H
#define MARBLE_MARBLESPLASHLAYER_H
#include "LayerInterface.h"
#include <QString>
namespace Marble
{
class MarbleSplashLayer : public LayerInterface
{
public:
MarbleSplashLayer();
QStringList renderPosition() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos = QLatin1String("SURFACE"),
- GeoSceneLayer *layer = 0 ) override;
+ GeoSceneLayer *layer = nullptr ) override;
RenderState renderState() const override;
QString runtimeTrace() const override { return QStringLiteral("SplashLayer"); }
};
}
#endif
diff --git a/src/lib/marble/layers/PlacemarkLayer.h b/src/lib/marble/layers/PlacemarkLayer.h
index d9c6318dd..7081838ca 100644
--- a/src/lib/marble/layers/PlacemarkLayer.h
+++ b/src/lib/marble/layers/PlacemarkLayer.h
@@ -1,128 +1,128 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007-2008 Inge Wallin <ingwa@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
//
// PlacemarkLayer is responsible for drawing the Placemarks on the map
//
#ifndef MARBLE_PLACEMARKLAYER_H
#define MARBLE_PLACEMARKLAYER_H
#include <QObject>
#include "LayerInterface.h"
#include <QVector>
#include <QPainter>
#include "PlacemarkLayout.h"
class QAbstractItemModel;
class QItemSelectionModel;
class QString;
namespace Marble
{
class GeoPainter;
class GeoSceneLayer;
class MarbleClock;
class ViewportParams;
class StyleBuilder;
struct Fragment
{
QVarLengthArray<QPainter::PixmapFragment, 16> fragments;
QPixmap pixmap;
};
class PlacemarkLayer : public QObject, public LayerInterface
{
Q_OBJECT
public:
PlacemarkLayer( QAbstractItemModel *placemarkModel,
QItemSelectionModel *selectionModel,
MarbleClock *clock,
const StyleBuilder *styleBuilder,
- QObject *parent = 0 );
+ QObject *parent = nullptr );
~PlacemarkLayer() override;
/**
* @reimp
*/
QStringList renderPosition() const override;
/**
* @reimp
*/
qreal zValue() const override;
/**
* @reimp
*/
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos = QLatin1String("NONE"),
- GeoSceneLayer *layer = 0 ) override;
+ GeoSceneLayer *layer = nullptr ) override;
RenderState renderState() const override;
QString runtimeTrace() const override;
/**
* Returns a list of model indexes that are at position @p pos.
*/
QVector<const GeoDataFeature *> whichPlacemarkAt( const QPoint &pos );
bool hasPlacemarkAt(const QPoint &pos);
bool isDebugModeEnabled() const;
void setDebugModeEnabled(bool enabled);
void setLevelTagDebugModeEnabled(bool enabled);
bool levelTagDebugModeEnabled() const;
void setDebugLevelTag(int level);
static bool m_useXWorkaround; // Indicates need for an X windows workaround.
public Q_SLOTS:
// earth
void setShowPlaces( bool show );
void setShowCities( bool show );
void setShowTerrain( bool show );
void setShowOtherPlaces( bool show );
// other planets
void setShowLandingSites( bool show );
void setShowCraters( bool show );
void setShowMaria( bool show );
void requestStyleReset();
void setTileLevel(int tileLevel);
Q_SIGNALS:
void repaintNeeded();
private:
void renderDebug(GeoPainter *painter, ViewportParams *viewport, const QVector<VisiblePlacemark*> & placemarks) const;
static bool testXBug();
PlacemarkLayout m_layout;
bool m_debugModeEnabled;
bool m_levelTagDebugModeEnabled;
int m_tileLevel;
int m_debugLevelTag;
};
}
#endif
diff --git a/src/lib/marble/layers/PopupLayer.h b/src/lib/marble/layers/PopupLayer.h
index 3af235df7..df26fec9c 100644
--- a/src/lib/marble/layers/PopupLayer.h
+++ b/src/lib/marble/layers/PopupLayer.h
@@ -1,155 +1,155 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef POPUPLAYER_H
#define POPUPLAYER_H
#include "LayerInterface.h"
#include <QObject>
#include <QUrl>
class QSizeF;
namespace Marble
{
class GeoDataCoordinates;
class MarbleWidget;
/**
* @brief The PopupLayer class
*
* A popup dialog opening on top of the map. The content is shown in a QWebView,
* acting like a minimalistic web browser.
*
*/
class MARBLE_EXPORT PopupLayer : public QObject, public LayerInterface
{
Q_OBJECT
public:
- explicit PopupLayer( MarbleWidget *widget, QObject* parent = 0 );
+ explicit PopupLayer( MarbleWidget *widget, QObject* parent = nullptr );
~PopupLayer() override;
QStringList renderPosition() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString &, GeoSceneLayer * ) override;
bool eventFilter( QObject *, QEvent * ) override;
qreal zValue() const override;
RenderState renderState() const override;
QString runtimeTrace() const override { return QStringLiteral("PopupLayer"); }
/**
* @brief Is popup item visible
*
* If popup item visible, it will return `true`,
* otherwise - `false`
*
* @return visibility of the item
*/
bool visible() const;
/**
* @brief Set visibility of the item
*
* If @p visible is `true`, popup will be visible,
* otherwise - popup won't be visible.
*
* @param visible visibility of the item
*/
void setVisible( bool visible );
/**
* @brief Make the dialog pop up
*
* This has the same effect as setVisible( true ) and additionally
* adjusts the viewport so that the dialog is fully visible.
*/
void popup();
/**
* @brief Sets coordinates
*
* Use a geo position as the dialog base position. The dialog will be shown if
* it is visible and if the map viewport includes the given coordinates.
* This invalidates a screen position set with setPosition(), if any.
*
* Alignment of the dialog from the point of view of the coordinates. For example,
* Qt::AlignRight | Qt::AlignVCenter shows the dialog to the right of the geo position,
* vertically centered. An arrow points from the dialog to the geo position.
*
* @param coordinates geo coordinates
* @param alignment alignment of popup when it visible
*/
void setCoordinates( const GeoDataCoordinates &coordinates, Qt::Alignment alignment );
/**
* @brief Sets URL of the browser
*
* @see PopupItem::setUrl();
*
* @param url url for web brower
*/
void setUrl( const QUrl &url );
/**
* @brief Sets size of popup item
*
* Sets the @p size of the dialog (including the arrow, if any).
*
* @param size popup size, arrows in count
*/
void setSize( const QSizeF &size );
/**
* @brief Sets content of the browser
*
* @see PopupItem::setContent();
*
* @param html content (in html format)
*/
void setContent( const QString &html, const QUrl & baseUrl = QUrl() );
/**
* @brief Sets background color of the header
*
* @see PopupItem::setBackgroundColor();
*
* @param color color to set
*/
void setBackgroundColor( const QColor &color );
/**
* @brief Sets text color of the header
*
* @see PopupItem::setTextColor();
*
* @param color color to set
*/
void setTextColor( const QColor &color );
Q_SIGNALS:
void repaintNeeded();
private Q_SLOTS:
void hidePopupItem();
private:
class Private;
Private *const d;
};
}
#endif
diff --git a/src/lib/marble/layers/TextureLayer.cpp b/src/lib/marble/layers/TextureLayer.cpp
index a01b09582..b9d103346 100644
--- a/src/lib/marble/layers/TextureLayer.cpp
+++ b/src/lib/marble/layers/TextureLayer.cpp
@@ -1,589 +1,589 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008, 2009, 2010 Jens-Michael Hoffmann <jmho@c-xx.com>
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>//
#include "TextureLayer.h"
#include <qmath.h>
#include <QTimer>
#include <QList>
#include <QSortFilterProxyModel>
#include "SphericalScanlineTextureMapper.h"
#include "EquirectScanlineTextureMapper.h"
#include "MercatorScanlineTextureMapper.h"
#include "GenericScanlineTextureMapper.h"
#include "TileScalingTextureMapper.h"
#include "GeoDataGroundOverlay.h"
#include "GeoPainter.h"
#include "GeoSceneGroup.h"
#include "GeoSceneTextureTileDataset.h"
#include "GeoSceneTypes.h"
#include "MergedLayerDecorator.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarblePlacemarkModel.h"
#include "StackedTile.h"
#include "StackedTileLoader.h"
#include "SunLocator.h"
#include "TextureColorizer.h"
#include "TileLoader.h"
#include "ViewportParams.h"
namespace Marble
{
const int REPAINT_SCHEDULING_INTERVAL = 1000;
class Q_DECL_HIDDEN TextureLayer::Private
{
public:
Private( HttpDownloadManager *downloadManager,
PluginManager* pluginManager,
const SunLocator *sunLocator,
QAbstractItemModel *groundOverlayModel,
TextureLayer *parent );
void requestDelayedRepaint();
void updateTextureLayers();
void updateTile( const TileId &tileId, const QImage &tileImage );
void addGroundOverlays( const QModelIndex& parent, int first, int last );
void removeGroundOverlays( const QModelIndex& parent, int first, int last );
void resetGroundOverlaysCache();
void updateGroundOverlays();
void addCustomTextures();
static bool drawOrderLessThan( const GeoDataGroundOverlay* o1, const GeoDataGroundOverlay* o2 );
public:
TextureLayer *const m_parent;
const SunLocator *const m_sunLocator;
TileLoader m_loader;
MergedLayerDecorator m_layerDecorator;
StackedTileLoader m_tileLoader;
GeoDataCoordinates m_centerCoordinates;
int m_tileZoomLevel;
TextureMapperInterface *m_texmapper;
TextureColorizer *m_texcolorizer;
QVector<const GeoSceneTextureTileDataset *> m_textures;
const GeoSceneGroup *m_textureLayerSettings;
QString m_runtimeTrace;
QSortFilterProxyModel m_groundOverlayModel;
QList<const GeoDataGroundOverlay *> m_groundOverlayCache;
QMap<QString, GeoSceneTextureTileDataset *> m_customTextures;
// For scheduling repaints
QTimer m_repaintTimer;
RenderState m_renderState;
};
TextureLayer::Private::Private( HttpDownloadManager *downloadManager,
PluginManager* pluginManager,
const SunLocator *sunLocator,
QAbstractItemModel *groundOverlayModel,
TextureLayer *parent )
: m_parent( parent )
, m_sunLocator( sunLocator )
, m_loader( downloadManager, pluginManager )
, m_layerDecorator( &m_loader, sunLocator )
, m_tileLoader( &m_layerDecorator )
, m_centerCoordinates()
, m_tileZoomLevel( -1 )
- , m_texmapper( 0 )
- , m_texcolorizer( 0 )
- , m_textureLayerSettings( 0 )
+ , m_texmapper( nullptr )
+ , m_texcolorizer( nullptr )
+ , m_textureLayerSettings( nullptr )
, m_repaintTimer()
{
m_groundOverlayModel.setSourceModel( groundOverlayModel );
m_groundOverlayModel.setDynamicSortFilter( true );
m_groundOverlayModel.setSortRole ( MarblePlacemarkModel::PopularityIndexRole );
m_groundOverlayModel.sort (0, Qt::AscendingOrder );
connect( &m_groundOverlayModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
m_parent, SLOT(addGroundOverlays(QModelIndex,int,int)) );
connect( &m_groundOverlayModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
m_parent, SLOT(removeGroundOverlays(QModelIndex,int,int)) );
connect( &m_groundOverlayModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
m_parent, SLOT(resetGroundOverlaysCache()) );
connect( &m_groundOverlayModel, SIGNAL(modelReset()),
m_parent, SLOT(resetGroundOverlaysCache()) );
updateGroundOverlays();
}
void TextureLayer::Private::requestDelayedRepaint()
{
if ( m_texmapper ) {
m_texmapper->setRepaintNeeded();
}
if ( !m_repaintTimer.isActive() ) {
m_repaintTimer.start();
}
}
void TextureLayer::Private::updateTextureLayers()
{
QVector<GeoSceneTextureTileDataset const *> result;
for ( const GeoSceneTextureTileDataset *candidate: m_textures ) {
bool enabled = true;
if ( m_textureLayerSettings ) {
const bool propertyExists = m_textureLayerSettings->propertyValue( candidate->name(), enabled );
enabled |= !propertyExists; // if property doesn't exist, enable texture nevertheless
}
if ( enabled ) {
result.append( candidate );
mDebug() << "enabling texture" << candidate->name();
} else {
mDebug() << "disabling texture" << candidate->name();
}
}
updateGroundOverlays();
m_layerDecorator.setTextureLayers( result );
m_tileLoader.clear();
m_tileZoomLevel = -1;
m_parent->setNeedsUpdate();
}
void TextureLayer::Private::updateTile( const TileId &tileId, const QImage &tileImage )
{
if ( tileImage.isNull() )
return; // keep tiles in cache to improve performance
m_tileLoader.updateTile( tileId, tileImage );
requestDelayedRepaint();
}
bool TextureLayer::Private::drawOrderLessThan( const GeoDataGroundOverlay* o1, const GeoDataGroundOverlay* o2 )
{
return o1->drawOrder() < o2->drawOrder();
}
void TextureLayer::Private::addGroundOverlays( const QModelIndex& parent, int first, int last )
{
for ( int i = first; i <= last; ++i ) {
QModelIndex index = m_groundOverlayModel.index( i, 0, parent );
const GeoDataGroundOverlay *overlay = static_cast<GeoDataGroundOverlay *>( qvariant_cast<GeoDataObject *>( index.data( MarblePlacemarkModel::ObjectPointerRole ) ) );
if ( overlay->icon().isNull() ) {
continue;
}
int pos = std::lower_bound( m_groundOverlayCache.begin(), m_groundOverlayCache.end(), overlay, drawOrderLessThan ) - m_groundOverlayCache.begin();
m_groundOverlayCache.insert( pos, overlay );
}
updateGroundOverlays();
m_parent->reset();
}
void TextureLayer::Private::removeGroundOverlays( const QModelIndex& parent, int first, int last )
{
for ( int i = first; i <= last; ++i ) {
QModelIndex index = m_groundOverlayModel.index( i, 0, parent );
const GeoDataGroundOverlay *overlay = static_cast<GeoDataGroundOverlay *>( qvariant_cast<GeoDataObject *>( index.data( MarblePlacemarkModel::ObjectPointerRole ) ) );
int pos = std::lower_bound( m_groundOverlayCache.begin(), m_groundOverlayCache.end(), overlay, drawOrderLessThan ) - m_groundOverlayCache.begin();
if (pos >= 0 && pos < m_groundOverlayCache.size() ) {
m_groundOverlayCache.removeAt( pos );
}
}
updateGroundOverlays();
m_parent->reset();
}
void TextureLayer::Private::resetGroundOverlaysCache()
{
m_groundOverlayCache.clear();
updateGroundOverlays();
m_parent->reset();
}
void TextureLayer::Private::updateGroundOverlays()
{
if ( !m_texcolorizer ) {
m_layerDecorator.updateGroundOverlays( m_groundOverlayCache );
}
else {
m_layerDecorator.updateGroundOverlays( QList<const GeoDataGroundOverlay *>() );
}
}
void TextureLayer::Private::addCustomTextures()
{
m_textures.reserve(m_textures.size() + m_customTextures.size());
for (GeoSceneTextureTileDataset *t: m_customTextures)
{
m_textures.append(t);
}
}
TextureLayer::TextureLayer( HttpDownloadManager *downloadManager,
PluginManager* pluginManager,
const SunLocator *sunLocator,
QAbstractItemModel *groundOverlayModel )
: QObject()
, d( new Private( downloadManager, pluginManager, sunLocator, groundOverlayModel, this ) )
{
connect( &d->m_loader, SIGNAL(tileCompleted(TileId,QImage)),
this, SLOT(updateTile(TileId,QImage)) );
// Repaint timer
d->m_repaintTimer.setSingleShot( true );
d->m_repaintTimer.setInterval( REPAINT_SCHEDULING_INTERVAL );
connect( &d->m_repaintTimer, SIGNAL(timeout()),
this, SIGNAL(repaintNeeded()) );
}
TextureLayer::~TextureLayer()
{
qDeleteAll(d->m_customTextures);
delete d->m_texmapper;
delete d->m_texcolorizer;
delete d;
}
QStringList TextureLayer::renderPosition() const
{
return QStringList(QStringLiteral("SURFACE"));
}
void TextureLayer::addSeaDocument( const GeoDataDocument *seaDocument )
{
if( d->m_texcolorizer ) {
d->m_texcolorizer->addSeaDocument( seaDocument );
reset();
}
}
void TextureLayer::addLandDocument( const GeoDataDocument *landDocument )
{
if( d->m_texcolorizer ) {
d->m_texcolorizer->addLandDocument( landDocument );
reset();
}
}
int TextureLayer::textureLayerCount() const
{
return d->m_layerDecorator.textureLayersSize();
}
bool TextureLayer::showSunShading() const
{
return d->m_layerDecorator.showSunShading();
}
bool TextureLayer::showCityLights() const
{
return d->m_layerDecorator.showCityLights();
}
bool TextureLayer::render( GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos, GeoSceneLayer *layer )
{
Q_UNUSED( renderPos );
Q_UNUSED( layer );
d->m_runtimeTrace = QStringLiteral("Texture Cache: %1 ").arg(d->m_tileLoader.tileCount());
d->m_renderState = RenderState(QStringLiteral("Texture Tiles"));
// Stop repaint timer if it is already running
d->m_repaintTimer.stop();
if ( d->m_textures.isEmpty() )
return false;
if ( d->m_layerDecorator.textureLayersSize() == 0 )
return false;
if ( !d->m_texmapper )
return false;
if ( d->m_centerCoordinates.longitude() != viewport->centerLongitude() ||
d->m_centerCoordinates.latitude() != viewport->centerLatitude() ) {
d->m_centerCoordinates.setLongitude( viewport->centerLongitude() );
d->m_centerCoordinates.setLatitude( viewport->centerLatitude() );
d->m_texmapper->setRepaintNeeded();
}
// choose the smaller dimension for selecting the tile level, leading to higher-resolution results
const int levelZeroWidth = d->m_layerDecorator.tileSize().width() * d->m_layerDecorator.tileColumnCount( 0 );
const int levelZeroHight = d->m_layerDecorator.tileSize().height() * d->m_layerDecorator.tileRowCount( 0 );
const int levelZeroMinDimension = qMin( levelZeroWidth, levelZeroHight );
// limit to 1 as dirty fix for invalid entry linearLevel
const qreal linearLevel = qMax<qreal>( 1.0, viewport->radius() * 4.0 / levelZeroMinDimension );
// As our tile resolution doubles with each level we calculate
// the tile level from tilesize and the globe radius via log(2)
const qreal tileLevelF = qLn( linearLevel ) / qLn( 2.0 ) * 1.00001; // snap to the sharper tile level a tiny bit earlier
// to work around rounding errors when the radius
// roughly equals the global texture width
const int tileLevel = qMin<int>( d->m_layerDecorator.maximumTileLevel(), tileLevelF );
if ( tileLevel != d->m_tileZoomLevel ) {
d->m_tileZoomLevel = tileLevel;
emit tileLevelChanged( d->m_tileZoomLevel );
}
const QRect dirtyRect = QRect( QPoint( 0, 0), viewport->size() );
d->m_texmapper->mapTexture( painter, viewport, d->m_tileZoomLevel, dirtyRect, d->m_texcolorizer );
d->m_renderState.addChild( d->m_tileLoader.renderState() );
return true;
}
QString TextureLayer::runtimeTrace() const
{
return d->m_runtimeTrace;
}
void TextureLayer::setShowRelief( bool show )
{
if ( d->m_texcolorizer ) {
d->m_texcolorizer->setShowRelief( show );
}
}
void TextureLayer::setShowSunShading( bool show )
{
disconnect( d->m_sunLocator, SIGNAL(positionChanged(qreal,qreal)),
this, SLOT(reset()) );
if ( show ) {
connect( d->m_sunLocator, SIGNAL(positionChanged(qreal,qreal)),
this, SLOT(reset()) );
}
d->m_layerDecorator.setShowSunShading( show );
reset();
}
void TextureLayer::setShowCityLights( bool show )
{
d->m_layerDecorator.setShowCityLights( show );
reset();
}
void TextureLayer::setShowTileId( bool show )
{
d->m_layerDecorator.setShowTileId( show );
reset();
}
void TextureLayer::setProjection( Projection projection )
{
if ( d->m_textures.isEmpty() ) {
return;
}
// 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 );
break;
case Equirectangular:
d->m_texmapper = new EquirectScanlineTextureMapper( &d->m_tileLoader );
break;
case Mercator:
if (d->m_textures.at(0)->tileProjectionType() == GeoSceneAbstractTileProjection::Mercator) {
d->m_texmapper = new TileScalingTextureMapper( &d->m_tileLoader );
} else {
d->m_texmapper = new MercatorScanlineTextureMapper( &d->m_tileLoader );
}
break;
case Gnomonic:
case Stereographic:
case LambertAzimuthal:
case AzimuthalEquidistant:
case VerticalPerspective:
d->m_texmapper = new GenericScanlineTextureMapper( &d->m_tileLoader );
break;
default:
- d->m_texmapper = 0;
+ d->m_texmapper = nullptr;
}
Q_ASSERT( d->m_texmapper );
}
void TextureLayer::setNeedsUpdate()
{
if ( d->m_texmapper ) {
d->m_texmapper->setRepaintNeeded();
}
emit repaintNeeded();
}
void TextureLayer::setVolatileCacheLimit( quint64 kilobytes )
{
d->m_tileLoader.setVolatileCacheLimit( kilobytes );
}
void TextureLayer::reset()
{
d->m_tileLoader.clear();
setNeedsUpdate();
}
void TextureLayer::reload()
{
for ( const TileId &id: d->m_tileLoader.visibleTiles() ) {
// it's debatable here, whether DownloadBulk or DownloadBrowse should be used
// but since "reload" or "refresh" seems to be a common action of a browser and it
// allows for more connections (in our model), use "DownloadBrowse"
d->m_layerDecorator.downloadStackedTile( id, DownloadBrowse );
}
}
void TextureLayer::downloadStackedTile( const TileId &stackedTileId )
{
d->m_layerDecorator.downloadStackedTile( stackedTileId, DownloadBulk );
}
void TextureLayer::setMapTheme( const QVector<const GeoSceneTextureTileDataset *> &textures, const GeoSceneGroup *textureLayerSettings, const QString &seaFile, const QString &landFile )
{
delete d->m_texcolorizer;
- d->m_texcolorizer = 0;
+ d->m_texcolorizer = nullptr;
if ( QFileInfo( seaFile ).isReadable() || QFileInfo( landFile ).isReadable() ) {
d->m_texcolorizer = new TextureColorizer( seaFile, landFile );
}
d->m_textures = textures;
d->addCustomTextures();
d->m_textureLayerSettings = textureLayerSettings;
if ( d->m_textureLayerSettings ) {
connect( d->m_textureLayerSettings, SIGNAL(valueChanged(QString,bool)),
this, SLOT(updateTextureLayers()) );
}
d->updateTextureLayers();
}
int TextureLayer::tileZoomLevel() const
{
return d->m_tileZoomLevel;
}
QSize TextureLayer::tileSize() const
{
return d->m_layerDecorator.tileSize();
}
const GeoSceneAbstractTileProjection *TextureLayer::tileProjection() const
{
return d->m_layerDecorator.tileProjection();
}
int TextureLayer::tileColumnCount( int level ) const
{
return d->m_layerDecorator.tileColumnCount( level );
}
int TextureLayer::tileRowCount( int level ) const
{
return d->m_layerDecorator.tileRowCount( level );
}
quint64 TextureLayer::volatileCacheLimit() const
{
return d->m_tileLoader.volatileCacheLimit();
}
int TextureLayer::preferredRadiusCeil( int radius ) const
{
if (!d->m_layerDecorator.hasTextureLayer()) {
return radius;
}
const int tileWidth = d->m_layerDecorator.tileSize().width();
const int levelZeroColumns = d->m_layerDecorator.tileColumnCount( 0 );
const qreal linearLevel = 4.0 * (qreal)( radius ) / (qreal)( tileWidth * levelZeroColumns );
const qreal tileLevelF = qLn( linearLevel ) / qLn( 2.0 );
const int tileLevel = qCeil( tileLevelF );
if ( tileLevel < 0 )
return ( tileWidth * levelZeroColumns / 4 ) >> (-tileLevel);
return ( tileWidth * levelZeroColumns / 4 ) << tileLevel;
}
int TextureLayer::preferredRadiusFloor( int radius ) const
{
if (!d->m_layerDecorator.hasTextureLayer()) {
return radius;
}
const int tileWidth = d->m_layerDecorator.tileSize().width();
const int levelZeroColumns = d->m_layerDecorator.tileColumnCount( 0 );
const qreal linearLevel = 4.0 * (qreal)( radius ) / (qreal)( tileWidth * levelZeroColumns );
const qreal tileLevelF = qLn( linearLevel ) / qLn( 2.0 );
const int tileLevel = qFloor( tileLevelF );
if ( tileLevel < 0 )
return ( tileWidth * levelZeroColumns / 4 ) >> (-tileLevel);
return ( tileWidth * levelZeroColumns / 4 ) << tileLevel;
}
RenderState TextureLayer::renderState() const
{
return d->m_renderState;
}
QString TextureLayer::addTextureLayer(GeoSceneTextureTileDataset* texture)
{
if (!texture)
return QString(); //Not a sane call
QString sourceDir = texture->sourceDir();
if (!d->m_customTextures.contains(sourceDir))
{ // Add if not present. For update, remove the old texture first.
d->m_customTextures.insert(sourceDir, texture);
d->m_textures.append(texture);
d->updateTextureLayers();
}
return sourceDir;
}
void TextureLayer::removeTextureLayer(const QString &key)
{
if (d->m_customTextures.contains(key))
{
GeoSceneTextureTileDataset *texture = d->m_customTextures.value(key);
d->m_customTextures.remove(key);
d->m_textures.remove(d->m_textures.indexOf(texture));
delete texture;
d->updateTextureLayers();
}
}
}
#include "moc_TextureLayer.cpp"
diff --git a/src/lib/marble/layers/TextureLayer.h b/src/lib/marble/layers/TextureLayer.h
index 71a8656ca..26305f7df 100644
--- a/src/lib/marble/layers/TextureLayer.h
+++ b/src/lib/marble/layers/TextureLayer.h
@@ -1,147 +1,147 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010,2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_MARBLETEXTURELAYER_H
#define MARBLE_MARBLETEXTURELAYER_H
#include "LayerInterface.h"
#include <QObject>
#include "MarbleGlobal.h"
class QAbstractItemModel;
class QImage;
class QSize;
namespace Marble
{
class GeoPainter;
class GeoDataDocument;
class GeoSceneGroup;
class GeoSceneAbstractTileProjection;
class GeoSceneTextureTileDataset;
class HttpDownloadManager;
class SunLocator;
class TileId;
class ViewportParams;
class PluginManager;
class MARBLE_EXPORT TextureLayer : public QObject, public LayerInterface
{
Q_OBJECT
public:
TextureLayer( HttpDownloadManager *downloadManager,
PluginManager* pluginManager,
const SunLocator *sunLocator,
QAbstractItemModel *groundOverlayModel );
~TextureLayer() override;
QStringList renderPosition() const override;
void addSeaDocument( const GeoDataDocument *seaDocument );
void addLandDocument( const GeoDataDocument *landDocument );
int textureLayerCount() const;
/**
* @brief Adds texture sublayer, taking ownership of the object's memory
* Does nothing if a texture with the same source directory was already
* added with this method.
* @return returned string is the key for the texture that can be later used to remove it
*/
QString addTextureLayer(GeoSceneTextureTileDataset *texture);
/**
* @brief Removes texture sublayer identified by a key.
* Deletes the texture object. Does nothing if key is not found.
* @param A key to identify the texture, returned from addTextureLayer
*/
void removeTextureLayer(const QString &key);
bool showSunShading() const;
bool showCityLights() const;
/**
* @brief Return the current tile zoom level. For example for OpenStreetMap
* possible values are 1..18, for BlueMarble 0..6.
*/
int tileZoomLevel() const;
QSize tileSize() const;
const GeoSceneAbstractTileProjection *tileProjection() const;
int tileColumnCount( int level ) const;
int tileRowCount( int level ) const;
quint64 volatileCacheLimit() const;
int preferredRadiusCeil( int radius ) const;
int preferredRadiusFloor( int radius ) const;
RenderState renderState() const override;
QString runtimeTrace() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos = QLatin1String("NONE"),
- GeoSceneLayer *layer = 0 ) override;
+ GeoSceneLayer *layer = nullptr ) override;
public Q_SLOTS:
void setShowRelief( bool show );
void setShowSunShading( bool show );
void setShowCityLights( bool show );
void setShowTileId( bool show );
/**
* @brief Set the Projection used for the map
* @param projection projection type (e.g. Spherical, Equirectangular, Mercator)
*/
void setProjection( Projection projection );
void setNeedsUpdate();
void setMapTheme( const QVector<const GeoSceneTextureTileDataset *> &textures, const GeoSceneGroup *textureLayerSettings, const QString &seaFile, const QString &landFile );
void setVolatileCacheLimit( quint64 kilobytes );
void reset();
void reload();
void downloadStackedTile( const TileId &stackedTileId );
Q_SIGNALS:
void tileLevelChanged( int );
void repaintNeeded();
private:
Q_PRIVATE_SLOT( d, void requestDelayedRepaint() )
Q_PRIVATE_SLOT( d, void updateTextureLayers() )
Q_PRIVATE_SLOT( d, void updateTile( const TileId &tileId, const QImage &tileImage ) )
Q_PRIVATE_SLOT( d, void addGroundOverlays( const QModelIndex& parent, int first, int last ) )
Q_PRIVATE_SLOT( d, void removeGroundOverlays( const QModelIndex& parent, int first, int last ) )
Q_PRIVATE_SLOT( d, void resetGroundOverlaysCache() )
private:
class Private;
Private *const d;
};
}
#endif
diff --git a/src/lib/marble/layers/VectorTileLayer.cpp b/src/lib/marble/layers/VectorTileLayer.cpp
index 505d7a6eb..8f2b8cc7c 100644
--- a/src/lib/marble/layers/VectorTileLayer.cpp
+++ b/src/lib/marble/layers/VectorTileLayer.cpp
@@ -1,213 +1,213 @@
/*
This file is part of the Marble Virtual Globe.
This program is free software licensed under the GNU LGPL. You can
find a copy of this license in LICENSE.txt in the top directory of
the source code.
Copyright 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
Copyright 2010 Thibaut Gridel <tgridel@free.fr>
Copyright 2012 Ander Pijoan <ander.pijoan@deusto.es>
Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
*/
#include "VectorTileLayer.h"
#include <qmath.h>
#include <QThreadPool>
#include "VectorTileModel.h"
#include "GeoPainter.h"
#include "GeoSceneGroup.h"
#include "GeoSceneTypes.h"
#include "GeoSceneVectorTileDataset.h"
#include "MarbleDebug.h"
#include "TileLoader.h"
#include "ViewportParams.h"
#include "RenderState.h"
#include "GeoDataDocument.h"
#include "GeoDataLatLonAltBox.h"
#include "HttpDownloadManager.h"
namespace Marble
{
class Q_DECL_HIDDEN VectorTileLayer::Private
{
public:
Private(HttpDownloadManager *downloadManager,
const PluginManager *pluginManager,
VectorTileLayer *parent,
GeoDataTreeModel *treeModel);
~Private();
void updateTile(const TileId &tileId, GeoDataDocument* document);
void updateLayerSettings();
public:
VectorTileLayer *const m_parent;
TileLoader m_loader;
QVector<VectorTileModel *> m_tileModels;
QVector<VectorTileModel *> m_activeTileModels;
const GeoSceneGroup *m_layerSettings;
// TreeModel for displaying GeoDataDocuments
GeoDataTreeModel *const m_treeModel;
QThreadPool m_threadPool; // a shared thread pool for all layers to keep CPU usage sane
};
VectorTileLayer::Private::Private(HttpDownloadManager *downloadManager,
const PluginManager *pluginManager,
VectorTileLayer *parent,
GeoDataTreeModel *treeModel) :
m_parent(parent),
m_loader(downloadManager, pluginManager),
m_tileModels(),
m_activeTileModels(),
- m_layerSettings(0),
+ m_layerSettings(nullptr),
m_treeModel(treeModel)
{
m_threadPool.setMaxThreadCount(1);
}
VectorTileLayer::Private::~Private()
{
qDeleteAll(m_activeTileModels);
}
void VectorTileLayer::Private::updateTile(const TileId &tileId, GeoDataDocument* document)
{
for (VectorTileModel *mapper: m_activeTileModels) {
mapper->updateTile(tileId, document);
}
}
void VectorTileLayer::Private::updateLayerSettings()
{
m_activeTileModels.clear();
for (VectorTileModel *candidate: m_tileModels) {
bool enabled = true;
if (m_layerSettings) {
const bool propertyExists = m_layerSettings->propertyValue(candidate->name(), enabled);
enabled |= !propertyExists; // if property doesn't exist, enable layer nevertheless
}
if (enabled) {
m_activeTileModels.append(candidate);
mDebug() << "enabling vector layer" << candidate->name();
} else {
candidate->clear();
mDebug() << "disabling vector layer" << candidate->name();
}
}
}
VectorTileLayer::VectorTileLayer(HttpDownloadManager *downloadManager,
const PluginManager *pluginManager,
GeoDataTreeModel *treeModel)
: QObject()
, d(new Private(downloadManager, pluginManager, this, treeModel))
{
qRegisterMetaType<TileId>("TileId");
qRegisterMetaType<GeoDataDocument*>("GeoDataDocument*");
connect(&d->m_loader, SIGNAL(tileCompleted(TileId, GeoDataDocument*)), this, SLOT(updateTile(TileId, GeoDataDocument*)));
}
VectorTileLayer::~VectorTileLayer()
{
delete d;
}
QStringList VectorTileLayer::renderPosition() const
{
return QStringList(QStringLiteral("SURFACE"));
}
RenderState VectorTileLayer::renderState() const
{
return RenderState(QStringLiteral("Vector Tiles"));
}
int VectorTileLayer::tileZoomLevel() const
{
int level = -1;
for (const auto *mapper: d->m_activeTileModels) {
level = qMax(level, mapper->tileZoomLevel());
}
return level;
}
QString VectorTileLayer::runtimeTrace() const
{
int tiles = 0;
for (const auto *mapper: d->m_activeTileModels) {
tiles += mapper->cachedDocuments();
}
int const layers = d->m_activeTileModels.size();
return QStringLiteral("Vector Tiles: %1 tiles in %2 layers").arg(tiles).arg(layers);
}
bool VectorTileLayer::render(GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos, GeoSceneLayer *layer)
{
Q_UNUSED(painter);
Q_UNUSED(renderPos);
Q_UNUSED(layer);
int const oldLevel = tileZoomLevel();
int level = 0;
for (VectorTileModel *mapper: d->m_activeTileModels) {
mapper->setViewport(viewport->viewLatLonAltBox());
level = qMax(level, mapper->tileZoomLevel());
}
if (oldLevel != level && level >= 0) {
emit tileLevelChanged(level);
}
return true;
}
void VectorTileLayer::reload()
{
for (auto mapper : d->m_activeTileModels) {
mapper->reload();
}
}
void VectorTileLayer::reset()
{
for (VectorTileModel *mapper: d->m_tileModels) {
mapper->clear();
}
}
void VectorTileLayer::setMapTheme(const QVector<const GeoSceneVectorTileDataset *> &textures, const GeoSceneGroup *textureLayerSettings)
{
qDeleteAll(d->m_tileModels);
d->m_tileModels.clear();
d->m_activeTileModels.clear();
for (const GeoSceneVectorTileDataset *layer: textures) {
d->m_tileModels << new VectorTileModel(&d->m_loader, layer, d->m_treeModel, &d->m_threadPool);
}
d->m_layerSettings = textureLayerSettings;
if (d->m_layerSettings) {
connect(d->m_layerSettings, SIGNAL(valueChanged(QString, bool)),
this, SLOT(updateLayerSettings()));
}
d->updateLayerSettings();
auto const level = tileZoomLevel();
if (level >= 0) {
emit tileLevelChanged(level);
}
}
}
#include "moc_VectorTileLayer.cpp"
diff --git a/src/lib/marble/layers/VectorTileLayer.h b/src/lib/marble/layers/VectorTileLayer.h
index ae8ce5a1e..ceef710f5 100644
--- a/src/lib/marble/layers/VectorTileLayer.h
+++ b/src/lib/marble/layers/VectorTileLayer.h
@@ -1,81 +1,81 @@
/*
This file is part of the Marble Virtual Globe.
This program is free software licensed under the GNU LGPL. You can
find a copy of this license in LICENSE.txt in the top directory of
the source code.
Copyright 2008 Patrick Spendrin <ps_ml@gmx.de>
Copyright 2010 Thibaut Gridel <tgridel@free.fr>
Copyright 2012 Ander Pijoan <ander.pijoan@deusto.es>
Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
*/
#ifndef MARBLE_VECTORTILELAYER_H
#define MARBLE_VECTORTILELAYER_H
#include "LayerInterface.h"
#include <QObject>
#include "MarbleGlobal.h"
namespace Marble
{
class GeoPainter;
class GeoDataDocument;
class GeoSceneGroup;
class GeoSceneVectorTileDataset;
class GeoDataTreeModel;
class PluginManager;
class HttpDownloadManager;
class ViewportParams;
class TileId;
class VectorTileLayer : public QObject, public LayerInterface
{
Q_OBJECT
public:
VectorTileLayer(HttpDownloadManager *downloadManager,
const PluginManager *pluginManager,
GeoDataTreeModel *treeModel);
~VectorTileLayer() override;
QStringList renderPosition() const override;
RenderState renderState() const override;
int tileZoomLevel() const;
QString runtimeTrace() const override;
bool render(GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos = QLatin1String("NONE"),
- GeoSceneLayer *layer = 0) override;
+ GeoSceneLayer *layer = nullptr) override;
void reload();
Q_SIGNALS:
void tileLevelChanged(int tileLevel);
public Q_SLOTS:
void setMapTheme(const QVector<const GeoSceneVectorTileDataset *> &textures, const GeoSceneGroup *textureLayerSettings);
void reset();
private:
Q_PRIVATE_SLOT(d, void updateLayerSettings())
Q_PRIVATE_SLOT(d, void updateTile(const TileId &tileId, GeoDataDocument* document))
private:
class Private;
Private *const d;
};
}
#endif // MARBLE_VECTORTILELAYER_H
diff --git a/src/lib/marble/osm/OsmRelationEditorDialog.h b/src/lib/marble/osm/OsmRelationEditorDialog.h
index 925546635..cbcc02521 100644
--- a/src/lib/marble/osm/OsmRelationEditorDialog.h
+++ b/src/lib/marble/osm/OsmRelationEditorDialog.h
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
//
#ifndef MARBLE_OSMRELATIONEDITORDIALOG_H
#define MARBLE_OSMRELATIONEDITORDIALOG_H
#include "marble_export.h"
#include <QDialog>
class QLineEdit;
class QDialogButtonBox;
namespace Marble {
class OsmRelationEditorDialogPrivate;
class OsmTagEditorWidget;
class OsmPlacemarkData;
class GeoDataPlacemark;
/**
* @brief The OsmRelationEditorDialog class small dialog that is used to edit relations
* The dialog has a line edit for name input, and a OsmTagEditorWidget for tag editing
*/
class MARBLE_EXPORT OsmRelationEditorDialog : public QDialog
{
Q_OBJECT
public:
- explicit OsmRelationEditorDialog( OsmPlacemarkData *relationData, QWidget *parent = 0 );
+ explicit OsmRelationEditorDialog( OsmPlacemarkData *relationData, QWidget *parent = nullptr );
~OsmRelationEditorDialog() override;
private Q_SLOTS:
void checkFields();
private:
void finish();
friend class OsmRelationEditorDialogPrivate;
QDialogButtonBox *m_buttonBox;
QLineEdit *m_nameLineEdit;
OsmTagEditorWidget *m_tagEditor;
GeoDataPlacemark *m_dummyPlacemark;
OsmPlacemarkData *m_relationData;
};
}
#endif
diff --git a/src/lib/marble/osm/OsmRelationManagerWidget.h b/src/lib/marble/osm/OsmRelationManagerWidget.h
index 3ba11982a..133c18524 100644
--- a/src/lib/marble/osm/OsmRelationManagerWidget.h
+++ b/src/lib/marble/osm/OsmRelationManagerWidget.h
@@ -1,74 +1,74 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
//
#ifndef MARBLE_OSMRELATIONMANAGERWIDGET_H
#define MARBLE_OSMRELATIONMANAGERWIDGET_H
#include <QWidget>
#include "MarbleGlobal.h"
#include "marble_export.h"
class QTreeWidgetItem;
namespace Marble
{
class OsmRelationManagerWidgetPrivate;
class GeoDataPlacemark;
class OsmPlacemarkData;
enum Column {
Name = 0,
Type = 1,
Role = 2
};
/**
* @brief The OsmRelationManagerWidget class is used to view and edit relations for any placemark
* within the Annotate Plugin.
* It can add the placemark to any relation the Annotate Plugin has loaded, or to newly created ones
*/
class MARBLE_EXPORT OsmRelationManagerWidget : public QWidget
{
Q_OBJECT
public:
explicit OsmRelationManagerWidget( GeoDataPlacemark *placemark,
const QHash<qint64, OsmPlacemarkData> *relations,
- QWidget *parent = 0 );
+ QWidget *parent = nullptr );
~OsmRelationManagerWidget() override;
public Q_SLOTS:
/**
* @brief addRelation adds the placemark to the relation specified in the action->text();
* If the text is "New Relation", a new relation is added
*/
void addRelation( QAction* action );
void handleItemChange( QTreeWidgetItem *item, int column );
void handleDoubleClick( QTreeWidgetItem * item, int column );
void handleRelationContextMenuRequest( const QPoint& point );
/**
* @brief update updates the relations list and the suggested relations drop menu
*/
void update();
Q_SIGNALS:
void relationCreated( const OsmPlacemarkData &relationData );
private:
friend class OsmRelationManagerWidgetPrivate;
OsmRelationManagerWidgetPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/osm/OsmTagEditorWidget.h b/src/lib/marble/osm/OsmTagEditorWidget.h
index 950073687..0867d1b2e 100644
--- a/src/lib/marble/osm/OsmTagEditorWidget.h
+++ b/src/lib/marble/osm/OsmTagEditorWidget.h
@@ -1,60 +1,60 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
//
#ifndef MARBLE_OSMTAGEDITORWIDGET_H
#define MARBLE_OSMTAGEDITORWIDGET_H
#include <QWidget>
#include "marble_export.h"
#include "MarbleGlobal.h"
class QTreeWidgetItem;
namespace Marble
{
class OsmTagEditorWidgetPrivate;
class GeoDataPlacemark;
class GeoDataFeature;
class OsmPlacemarkData;
class MARBLE_EXPORT OsmTagEditorWidget : public QWidget
{
Q_OBJECT
public:
- explicit OsmTagEditorWidget( GeoDataPlacemark *placemark, QWidget *parent = 0 );
+ explicit OsmTagEditorWidget( GeoDataPlacemark *placemark, QWidget *parent = nullptr );
~OsmTagEditorWidget() override;
/**
* @brief returns the current tag set for the placemark
*/
OsmPlacemarkData placemarkData() const;
public Q_SLOTS:
void update();
void addSelectedTag();
void removeSelectedTag();
void handleDoubleClick( QTreeWidgetItem *item, int column );
void handleItemChanged( QTreeWidgetItem *item, int column );
Q_SIGNALS:
void placemarkChanged( GeoDataFeature *);
private:
friend class OsmTagEditorWidgetPrivate;
OsmTagEditorWidgetPrivate* const d;
};
}
#endif
diff --git a/src/lib/marble/projections/AzimuthalProjection_p.h b/src/lib/marble/projections/AzimuthalProjection_p.h
index d3dcf825a..8502dfb19 100644
--- a/src/lib/marble/projections/AzimuthalProjection_p.h
+++ b/src/lib/marble/projections/AzimuthalProjection_p.h
@@ -1,109 +1,109 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
// Copyright 2014 Gábor Péterffy <peterffy95@gmail.com>
//
#ifndef MARBLE_AZIMUTHALPROJECTIONPRIVATE_H
#define MARBLE_AZIMUTHALPROJECTIONPRIVATE_H
#include "AbstractProjection_p.h"
namespace Marble
{
// Maximum amount of nodes that are created automatically between actual nodes.
static const int maxTessellationNodes = 200;
class AzimuthalProjection;
class AzimuthalProjectionPrivate : public AbstractProjectionPrivate
{
public:
explicit AzimuthalProjectionPrivate( AzimuthalProjection * parent )
: AbstractProjectionPrivate( parent ),
q_ptr( parent )
{
}
~AzimuthalProjectionPrivate() override {};
// This method tessellates a line segment in a way that the line segment
// follows great circles. The count parameter specifies the
// number of nodes generated for the polygon. If the
// clampToGround flag is added the polygon contains count + 2
// nodes as the clamped down start and end node get added.
// In order to ensure proper performance the current algorithm
// determines whether the linestring disappears
// behind the horizon by evaluating the actual node coordinates of the
// linestring.
// However in some cases only a tessellated portion of the linestring
// disappears behind the globe. In this case non-closed linestrings
// can still be cut into separate polygons without problems.
// But for linearrings the horizon detection at this stage happens too
// late already to be taken into account for rendering.
// The allowLatePolygonCut parameter allows to split at least
// non-closed linestrings properly at this point.
void tessellateLineSegment( const GeoDataCoordinates &aCoords,
qreal ax, qreal ay,
const GeoDataCoordinates &bCoords,
qreal bx, qreal by,
QVector<QPolygonF*> &polygons,
const ViewportParams *viewport,
- TessellationFlags f = 0,
+ TessellationFlags f = nullptr,
bool allowLatePolygonCut = false ) const;
void processTessellation( const GeoDataCoordinates &previousCoords,
const GeoDataCoordinates &currentCoords,
int count,
QVector<QPolygonF*> &polygons,
const ViewportParams *viewport,
- TessellationFlags f = 0,
+ TessellationFlags f = nullptr,
bool allowLatePolygonCut = false ) const;
void crossHorizon( const GeoDataCoordinates & bCoord,
QVector<QPolygonF*> &polygons,
const ViewportParams *viewport,
bool allowLatePolygonCut = false
) const;
virtual bool lineStringToPolygon( const GeoDataLineString &lineString,
const ViewportParams *viewport,
QVector<QPolygonF*> &polygons ) const;
void horizonToPolygon( const ViewportParams *viewport,
const GeoDataCoordinates & disappearCoords,
const GeoDataCoordinates & reappearCoords,
QPolygonF* ) const;
GeoDataCoordinates findHorizon( const GeoDataCoordinates & previousCoords,
const GeoDataCoordinates & currentCoords,
const ViewportParams *viewport,
- TessellationFlags f = 0) const;
+ TessellationFlags f = nullptr) const;
GeoDataCoordinates doFindHorizon(const GeoDataCoordinates & previousCoords,
const GeoDataCoordinates & currentCoords,
const ViewportParams *viewport,
TessellationFlags f,
bool currentHide,
int recursionCounter) const;
bool globeHidesPoint( const GeoDataCoordinates &coordinates,
const ViewportParams *viewport ) const;
AzimuthalProjection * const q_ptr;
Q_DECLARE_PUBLIC( AzimuthalProjection )
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/projections/CylindricalProjection_p.h b/src/lib/marble/projections/CylindricalProjection_p.h
index f1f16d958..6762e270c 100644
--- a/src/lib/marble/projections/CylindricalProjection_p.h
+++ b/src/lib/marble/projections/CylindricalProjection_p.h
@@ -1,80 +1,80 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Patrick Spendrin <ps_ml@gmx.de>
// Copyright 2012 Cezar Mocan <mocancezar@gmail.com>
//
#ifndef MARBLE_CYLINDRICALPROJECTIONPRIVATE_H
#define MARBLE_CYLINDRICALPROJECTIONPRIVATE_H
#include "AbstractProjection_p.h"
namespace Marble
{
class CylindricalProjection;
class CylindricalProjectionPrivate : public AbstractProjectionPrivate
{
public:
explicit CylindricalProjectionPrivate( CylindricalProjection * parent );
// This method tessellates a line segment in a way that the line segment
// follows great circles. The count parameter specifies the
// number of nodes generated for the polygon. If the
// clampToGround flag is added the polygon contains count + 2
// nodes as the clamped down start and end node get added.
int tessellateLineSegment( const GeoDataCoordinates &aCoords,
qreal ax, qreal ay,
const GeoDataCoordinates &bCoords,
qreal bx, qreal by,
QVector<QPolygonF*> &polygons,
const ViewportParams *viewport,
- TessellationFlags f = 0,
+ TessellationFlags f = nullptr,
int mirrorCount = 0,
qreal repeatDistance = 0 ) const;
int processTessellation( const GeoDataCoordinates &previousCoords,
const GeoDataCoordinates &currentCoords,
int count,
QVector<QPolygonF*> &polygons,
const ViewportParams *viewport,
- TessellationFlags f = 0,
+ TessellationFlags f = nullptr,
int mirrorCount = 0,
qreal repeatDistance = 0 ) const;
static int crossDateLine( const GeoDataCoordinates & aCoord,
const GeoDataCoordinates & bCoord,
qreal bx,
qreal by,
QVector<QPolygonF*> &polygons,
int mirrorCount = 0,
qreal repeatDistance = 0 );
bool lineStringToPolygon( const GeoDataLineString &lineString,
const ViewportParams *viewport,
QVector<QPolygonF*> &polygons ) const;
static void translatePolygons( const QVector<QPolygonF *> &polygons,
QVector<QPolygonF *> &translatedPolygons,
qreal xOffset );
void repeatPolygons( const ViewportParams *viewport,
QVector<QPolygonF *> &polygons ) const;
qreal repeatDistance( const ViewportParams *viewport ) const;
CylindricalProjection * const q_ptr;
Q_DECLARE_PUBLIC( CylindricalProjection )
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/routing/AlternativeRoutesModel.cpp b/src/lib/marble/routing/AlternativeRoutesModel.cpp
index f23f42d50..3f1a917b3 100644
--- a/src/lib/marble/routing/AlternativeRoutesModel.cpp
+++ b/src/lib/marble/routing/AlternativeRoutesModel.cpp
@@ -1,439 +1,439 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "AlternativeRoutesModel.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataExtendedData.h"
#include "GeoDataLineString.h"
#include "GeoDataPlacemark.h"
#include <QTimer>
#include <QPainter>
namespace Marble {
class Q_DECL_HIDDEN AlternativeRoutesModel::Private
{
public:
Private();
/**
* Returns true if there exists a route with high similarity to the given one
*/
bool filter( const GeoDataDocument* document ) const;
/**
* Returns a similarity measure in the range of [0..1]. Two routes with a similarity of 0 can
* be treated as totally different (e.g. different route requests), two routes with a similarity
* of 1 are considered equal. Otherwise the routes overlap to an extent indicated by the
* similarity value -- the higher, the more they do overlap.
* @note: The direction of routes is important; reversed routes are not considered equal
*/
static qreal similarity( const GeoDataDocument* routeA, const GeoDataDocument* routeB );
/**
* Returns the distance between the given polygon and the given point
*/
static qreal distance( const GeoDataLineString &wayPoints, const GeoDataCoordinates &position );
/**
* Returns the bearing of the great circle path defined by the coordinates one and two
* Based on http://www.movable-type.co.uk/scripts/latlong.html
*/
static qreal bearing( const GeoDataCoordinates &one, const GeoDataCoordinates &two );
/**
* Returns the distance between the given point and the line segment (not line) defined
* by the two coordinates lineA and lineB
*/
static qreal distance( const GeoDataCoordinates &satellite, const GeoDataCoordinates &lineA, const GeoDataCoordinates &lineB );
/**
* Returns the point reached when traveling the given distance from start with the given direction
*/
static GeoDataCoordinates coordinates( const GeoDataCoordinates &start, qreal distance, qreal bearing );
/**
* Returns the similarity between routeA and routeB. This method is not symmetric, i.e. in
* general unidirectionalSimilarity(a,b) != unidirectionalSimilarity(b,a)
*/
static qreal unidirectionalSimilarity( const GeoDataDocument* routeA, const GeoDataDocument* routeB );
/**
* (Primitive) scoring for routes
*/
static bool higherScore( const GeoDataDocument* one, const GeoDataDocument* two );
/**
* Returns true if the given route contains instructions (placemarks with turn instructions)
*/
static qreal instructionScore( const GeoDataDocument* document );
static const GeoDataLineString* waypoints( const GeoDataDocument* document );
static int nonZero( const QImage &image );
static QPolygonF polygon( const GeoDataLineString &lineString, qreal x, qreal y, qreal sx, qreal sy );
/** The currently shown alternative routes (model data) */
QVector<GeoDataDocument*> m_routes;
/** Pending route data (waiting for other results to come in) */
QVector<GeoDataDocument*> m_restrainedRoutes;
/** Counts the time between route request and first result */
QTime m_responseTime;
int m_currentIndex;
};
AlternativeRoutesModel::Private::Private() :
m_currentIndex( -1 )
{
// nothing to do
}
int AlternativeRoutesModel::Private::nonZero( const QImage &image )
{
QRgb const black = qRgb( 0, 0, 0 );
int count = 0;
for ( int y = 0; y < image.height(); ++y ) {
QRgb* destLine = (QRgb*) image.scanLine( y );
for ( int x = 0; x < image.width(); ++x ) {
count += destLine[x] == black ? 0 : 1;
}
}
return count;
}
QPolygonF AlternativeRoutesModel::Private::polygon( const GeoDataLineString &lineString, qreal x, qreal y, qreal sx, qreal sy )
{
QPolygonF poly;
for ( int i = 0; i < lineString.size(); ++i ) {
poly << QPointF( qAbs( ( lineString)[i].longitude() - x ) * sx,
qAbs( ( lineString)[i].latitude() - y ) * sy );
}
return poly;
}
bool AlternativeRoutesModel::Private::filter( const GeoDataDocument* document ) const
{
for ( int i=0; i<m_routes.size(); ++i ) {
qreal similarity = Private::similarity( document, m_routes.at( i ) );
if ( similarity > 0.8 ) {
return true;
}
}
return false;
}
qreal AlternativeRoutesModel::Private::similarity( const GeoDataDocument* routeA, const GeoDataDocument* routeB )
{
return qMax<qreal>( unidirectionalSimilarity( routeA, routeB ),
unidirectionalSimilarity( routeB, routeA ) );
}
qreal AlternativeRoutesModel::Private::distance( const GeoDataLineString &wayPoints, const GeoDataCoordinates &position )
{
Q_ASSERT( !wayPoints.isEmpty() );
qreal minDistance = 0;
for ( int i = 1; i < wayPoints.size(); ++i ) {
qreal dist = distance( position, wayPoints.at( i-1 ), wayPoints.at( i ) );
if ( minDistance <= 0 || dist < minDistance ) {
minDistance = dist;
}
}
return minDistance;
}
qreal AlternativeRoutesModel::Private::bearing( const GeoDataCoordinates &one, const GeoDataCoordinates &two )
{
qreal delta = two.longitude() - one.longitude();
qreal lat1 = one.latitude();
qreal lat2 = two.latitude();
return fmod( atan2( sin ( delta ) * cos ( lat2 ),
cos( lat1 ) * sin( lat2 ) - sin( lat1 ) * cos( lat2 ) * cos ( delta ) ), 2 * M_PI );
}
GeoDataCoordinates AlternativeRoutesModel::Private::coordinates( const GeoDataCoordinates &start, qreal distance, qreal bearing )
{
qreal lat1 = start.latitude();
qreal lon1 = start.longitude();
qreal lat2 = asin( sin( lat1 ) * cos( distance ) + cos( lat1 ) * sin( distance ) * cos( bearing ) );
qreal lon2 = lon1 + atan2( sin( bearing ) * sin( distance ) * cos( lat1 ), cos( distance ) - sin( lat1 ) * sin( lat2 ) );
return GeoDataCoordinates( lon2, lat2 );
}
qreal AlternativeRoutesModel::Private::distance( const GeoDataCoordinates &satellite, const GeoDataCoordinates &lineA, const GeoDataCoordinates &lineB )
{
const qreal dist = lineA.sphericalDistanceTo(satellite);
qreal bearA = bearing( lineA, satellite );
qreal bearB = bearing( lineA, lineB );
qreal result = asin( sin ( dist ) * sin( bearB - bearA ) );
Q_ASSERT(qMax<qreal>(satellite.sphericalDistanceTo(lineA), satellite.sphericalDistanceTo(lineB)) >= qAbs<qreal>(result));
result = acos( cos( dist ) / cos( result ) );
/** @todo: This is a naive approach. Look into the maths. */
const qreal final = qMin<qreal>(satellite.sphericalDistanceTo(lineA), satellite.sphericalDistanceTo(lineB));
if ( result >= 0 && result <= lineA.sphericalDistanceTo(lineB)) {
GeoDataCoordinates nearest = coordinates( lineA, result, bearB );
return qMin<qreal>(final, satellite.sphericalDistanceTo(nearest));
} else {
return final;
}
}
qreal AlternativeRoutesModel::Private::unidirectionalSimilarity( const GeoDataDocument* routeA, const GeoDataDocument* routeB )
{
const GeoDataLineString* waypointsA = waypoints( routeA );
const GeoDataLineString* waypointsB = waypoints( routeB );
if ( !waypointsA || !waypointsB )
{
return 0.0;
}
QImage image( 64, 64, QImage::Format_ARGB32_Premultiplied );
image.fill( qRgb( 0, 0, 0 ) );
GeoDataLatLonBox box = GeoDataLatLonBox::fromLineString( *waypointsA );
box = box.united( GeoDataLatLonBox::fromLineString( *waypointsB ) );
if ( !box.width() || !box.height() ) {
return 0.0;
}
qreal const sw = image.width() / box.width();
qreal const sh = image.height() / box.height();
QPainter painter( &image );
painter.setPen( QColor( Qt::white ) );
painter.drawPoints( Private::polygon( *waypointsA, box.west(), box.north(), sw, sh ) );
int const countA = Private::nonZero( image );
painter.drawPoints( Private::polygon( *waypointsB, box.west(), box.north(), sw, sh ) );
int const countB = Private::nonZero( image );
Q_ASSERT( countA <= countB );
return countB ? 1.0 - qreal( countB - countA ) / countB : 0;
}
bool AlternativeRoutesModel::Private::higherScore( const GeoDataDocument* one, const GeoDataDocument* two )
{
qreal instructionScoreA = instructionScore( one );
qreal instructionScoreB = instructionScore( two );
if ( instructionScoreA != instructionScoreB ) {
return instructionScoreA > instructionScoreB;
}
qreal lengthA = waypoints( one )->length( EARTH_RADIUS );
qreal lengthB = waypoints( two )->length( EARTH_RADIUS );
return lengthA < lengthB;
}
qreal AlternativeRoutesModel::Private::instructionScore( const GeoDataDocument* document )
{
bool hasInstructions = false;
QStringList blacklist = QStringList() << "" << "Route" << "Tessellated";
QVector<GeoDataFolder*> folders = document->folderList();
for( const GeoDataFolder *folder: folders ) {
for( const GeoDataPlacemark *placemark: folder->placemarkList() ) {
if ( !blacklist.contains( placemark->name() ) ) {
hasInstructions = true;
break;
}
}
}
for( const GeoDataPlacemark *placemark: document->placemarkList() ) {
if ( !blacklist.contains( placemark->name() ) ) {
hasInstructions = true;
if (placemark->extendedData().contains(QStringLiteral("turnType"))) {
return 1.0;
}
}
}
return hasInstructions ? 0.5 : 0.0;
}
const GeoDataLineString* AlternativeRoutesModel::Private::waypoints( const GeoDataDocument* document )
{
QVector<GeoDataFolder*> folders = document->folderList();
for( const GeoDataFolder *folder: folders ) {
for( const GeoDataPlacemark *placemark: folder->placemarkList() ) {
const GeoDataGeometry* geometry = placemark->geometry();
const GeoDataLineString* lineString = dynamic_cast<const GeoDataLineString*>( geometry );
if ( lineString ) {
return lineString;
}
}
}
for( const GeoDataPlacemark *placemark: document->placemarkList() ) {
const GeoDataGeometry* geometry = placemark->geometry();
const GeoDataLineString* lineString = dynamic_cast<const GeoDataLineString*>( geometry );
if ( lineString ) {
return lineString;
}
}
- return 0;
+ return nullptr;
}
AlternativeRoutesModel::AlternativeRoutesModel( QObject *parent ) :
QAbstractListModel( parent ),
d( new Private() )
{
// nothing to do
}
AlternativeRoutesModel::~AlternativeRoutesModel()
{
clear();
delete d;
}
int AlternativeRoutesModel::rowCount ( const QModelIndex & ) const
{
return d->m_routes.size();
}
QVariant AlternativeRoutesModel::headerData ( int, Qt::Orientation, int ) const
{
return QVariant();
}
QVariant AlternativeRoutesModel::data ( const QModelIndex &index, int role ) const
{
QVariant result;
if ( role == Qt::DisplayRole && index.column() == 0 && index.row() >= 0 && index.row() < d->m_routes.size() ) {
result = d->m_routes.at( index.row() )->name();
}
return result;
}
const GeoDataDocument *AlternativeRoutesModel::route(int index) const
{
if ( index >= 0 && index < d->m_routes.size() ) {
return d->m_routes.at(index);
}
- return 0;
+ return nullptr;
}
void AlternativeRoutesModel::newRequest( RouteRequest * )
{
d->m_responseTime.start();
d->m_currentIndex = -1;
clear();
}
void AlternativeRoutesModel::addRestrainedRoutes()
{
Q_ASSERT( d->m_routes.isEmpty() );
std::sort( d->m_restrainedRoutes.begin(), d->m_restrainedRoutes.end(), Private::higherScore );
for( GeoDataDocument* route: d->m_restrainedRoutes ) {
if ( !d->filter( route ) ) {
int affected = d->m_routes.size();
beginInsertRows( QModelIndex(), affected, affected );
// GeoDataDocument* base = d->m_routes.isEmpty() ? 0 : d->m_routes.first();
d->m_routes.push_back( route );
endInsertRows();
}
}
d->m_restrainedRoutes.clear();
Q_ASSERT( !d->m_routes.isEmpty() );
setCurrentRoute( 0 );
}
void AlternativeRoutesModel::addRoute( GeoDataDocument* document, WritePolicy policy )
{
if (policy != Instant) {
if (d->m_routes.isEmpty()) {
d->m_restrainedRoutes.push_back(document);
if (d->m_restrainedRoutes.isEmpty()) {
// First
const int responseTime = d->m_responseTime.elapsed();
const int timeout = qMin<int>(500, qMax<int>(50, responseTime * 2));
QTimer::singleShot(timeout, this, SLOT(addRestrainedRoutes()));
return;
}
}
for ( int i=0; i<d->m_routes.size(); ++i ) {
qreal similarity = Private::similarity( document, d->m_routes.at( i ) );
if ( similarity > 0.8 ) {
if ( Private::higherScore( document, d->m_routes.at( i ) ) ) {
d->m_routes[i] = document;
QModelIndex changed = index( i );
emit dataChanged( changed, changed );
}
return;
}
}
}
const int affected = d->m_routes.size();
beginInsertRows(QModelIndex(), affected, affected);
d->m_routes.push_back(document);
endInsertRows();
}
const GeoDataLineString* AlternativeRoutesModel::waypoints( const GeoDataDocument* document )
{
return Private::waypoints( document );
}
void AlternativeRoutesModel::setCurrentRoute( int index )
{
if ( index >= 0 && index < rowCount() && d->m_currentIndex != index ) {
d->m_currentIndex = index;
emit currentRouteChanged( currentRoute() );
emit currentRouteChanged( d->m_currentIndex );
}
}
const GeoDataDocument *AlternativeRoutesModel::currentRoute() const
{
- const GeoDataDocument *result = 0;
+ const GeoDataDocument *result = nullptr;
if ( d->m_currentIndex >= 0 && d->m_currentIndex < rowCount() ) {
result = d->m_routes[d->m_currentIndex];
}
return result;
}
void AlternativeRoutesModel::clear()
{
beginResetModel();
QVector<GeoDataDocument*> routes = d->m_routes;
d->m_currentIndex = -1;
d->m_routes.clear();
qDeleteAll(routes);
endResetModel();
}
} // namespace Marble
#include "moc_AlternativeRoutesModel.cpp"
diff --git a/src/lib/marble/routing/AlternativeRoutesModel.h b/src/lib/marble/routing/AlternativeRoutesModel.h
index 56fc281ed..9bff9547e 100644
--- a/src/lib/marble/routing/AlternativeRoutesModel.h
+++ b/src/lib/marble/routing/AlternativeRoutesModel.h
@@ -1,100 +1,100 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ALTERNATIVEROUTESMODEL_H
#define MARBLE_ALTERNATIVEROUTESMODEL_H
#include "marble_export.h"
#include <QAbstractListModel>
/**
* A QAbstractItemModel that contains a list of routing instructions.
* Each item represents a routing step in the way from source to
* destination. Steps near the source come first, steps near the target
* last.
*/
namespace Marble
{
class RouteRequest;
class GeoDataDocument;
class GeoDataLineString;
class MARBLE_EXPORT AlternativeRoutesModel : public QAbstractListModel
{
Q_OBJECT
public:
enum WritePolicy {
Instant,
Lazy
};
/** Constructor */
- explicit AlternativeRoutesModel( QObject *parent = 0 );
+ explicit AlternativeRoutesModel( QObject *parent = nullptr );
/** Destructor */
~AlternativeRoutesModel() override;
// Model querying
/** Overload of QAbstractListModel */
int rowCount ( const QModelIndex &parent = QModelIndex() ) const override;
/** Overload of QAbstractListModel */
QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
/** Overload of QAbstractListModel */
QVariant data ( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
const GeoDataDocument *route(int index) const;
// Model data filling
/** Invalidate the current alternative routes and prepare for new ones to arrive */
void newRequest( RouteRequest *request );
/**
* Old data in the model is discarded, the parsed content of the provided document
* is used as the new model data and a model reset is done
* @param document The route to add
* @param policy In lazy mode (default), a short amount of time is waited for
* other addRoute() calls before adding the route to the model. Otherwise, the
* model is changed immediately.
*/
void addRoute( GeoDataDocument* document, WritePolicy policy = Lazy );
/** Remove all alternative routes from the model */
void clear();
const GeoDataDocument *currentRoute() const;
/** Returns the waypoints contained in the route as a linestring */
static const GeoDataLineString* waypoints( const GeoDataDocument* document );
public Q_SLOTS:
void setCurrentRoute( int index );
Q_SIGNALS:
void currentRouteChanged(const GeoDataDocument *newRoute);
void currentRouteChanged( int index );
private Q_SLOTS:
void addRestrainedRoutes();
private:
class Private;
Private *const d;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/routing/RouteRequest.h b/src/lib/marble/routing/RouteRequest.h
index 7f154093a..175688a48 100644
--- a/src/lib/marble/routing/RouteRequest.h
+++ b/src/lib/marble/routing/RouteRequest.h
@@ -1,129 +1,129 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTEREQUEST_H
#define MARBLE_ROUTEREQUEST_H
#include "marble_export.h"
#include "RoutingProfile.h"
#include <QObject>
namespace Marble
{
class GeoDataCoordinates;
class GeoDataPlacemark;
class RouteRequestPrivate;
/**
* @brief Points to be included in a route. An ordered list of
* GeoDataCoordinates with change notification and Pixmap access, similar
* to QAbstractItemModel.
*/
class MARBLE_EXPORT RouteRequest: public QObject
{
Q_OBJECT
public:
/** Constructor */
- explicit RouteRequest( QObject *parent = 0 );
+ explicit RouteRequest( QObject *parent = nullptr );
/** Destructor */
~RouteRequest() override;
/** The first point, or a default constructed if empty */
GeoDataCoordinates source() const;
/** The last point, or a default constructed if empty */
GeoDataCoordinates destination() const;
/** Number of points in the route */
int size() const;
/** Accessor for the n-th position */
GeoDataCoordinates at( int index ) const;
/** Add the given element to the end */
void append( const GeoDataCoordinates &coordinates, const QString &name = QString() );
void append( const GeoDataPlacemark &placemark );
/** Add the given element at the given position */
void insert( int index, const GeoDataCoordinates &coordinates, const QString &name = QString() );
void insert(int index, const GeoDataPlacemark &placemark);
/** Swaps the given elements at the given positions*/
void swap( int index1, int index2 );
/** Change the value of the element at the given position */
void setPosition( int index, const GeoDataCoordinates &position, const QString &name = QString() );
/** Remove the element at the given position */
void remove( int index );
/** Remove all elements */
void clear();
/**
* Insert a via point. Order will be chosen such that the via point is not before
* the start or after the destination. Furthermore the distance between neighboring
* route points is minimized
*
* @note: This does not trigger an update of the route. It becomes "dirty"
*
* @todo: Minimizing the distance might not always be what the user wants
*/
void addVia( const GeoDataCoordinates &position );
void addVia( const GeoDataPlacemark &placemark );
/** Returns a pixmap which indicates the position of the element */
QPixmap pixmap( int index, int size=-1, int margin=2 ) const;
void setName( int index, const QString &name );
QString name( int index ) const;
void setVisited( int index, bool visited );
bool visited( int index ) const;
void reverse();
void setRoutingProfile( const RoutingProfile &profile );
RoutingProfile routingProfile() const;
GeoDataPlacemark & operator[] ( int index );
GeoDataPlacemark const & operator[] ( int index ) const;
Q_SIGNALS:
/** The value of the n-th element was changed */
void positionChanged( int index, const GeoDataCoordinates &position );
/** An element was added at the given position */
void positionAdded( int index );
/** The element at the given position was removed */
void positionRemoved( int index );
/** The routing profile was changed */
void routingProfileChanged();
private:
RouteRequestPrivate *const d;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/routing/RouteSegment.cpp b/src/lib/marble/routing/RouteSegment.cpp
index 1c9506f60..ec1705cc5 100644
--- a/src/lib/marble/routing/RouteSegment.cpp
+++ b/src/lib/marble/routing/RouteSegment.cpp
@@ -1,214 +1,214 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "RouteSegment.h"
#include "GeoDataLatLonAltBox.h"
namespace Marble
{
RouteSegment::RouteSegment() :
m_valid( false ),
m_distance( 0.0 ),
m_travelTime( 0 ),
- m_nextRouteSegment( 0 )
+ m_nextRouteSegment( nullptr )
{
// nothing to do
}
qreal RouteSegment::distance() const
{
return m_distance;
}
const Maneuver & RouteSegment::maneuver() const
{
return m_maneuver;
}
void RouteSegment::setManeuver( const Maneuver &maneuver )
{
m_maneuver = maneuver;
m_valid = true;
}
const GeoDataLineString & RouteSegment::path() const
{
return m_path;
}
void RouteSegment::setPath( const GeoDataLineString &path )
{
m_path = path;
m_distance = m_path.length( EARTH_RADIUS );
m_bounds = m_path.latLonAltBox();
m_valid = true;
}
int RouteSegment::travelTime() const
{
return m_travelTime;
}
void RouteSegment::setTravelTime( int seconds )
{
m_travelTime = seconds;
m_valid = true;
}
GeoDataLatLonBox RouteSegment::bounds() const
{
return m_bounds;
}
const RouteSegment & RouteSegment::nextRouteSegment() const
{
if ( m_nextRouteSegment ) {
return *m_nextRouteSegment;
}
static RouteSegment invalid;
return invalid;
}
void RouteSegment::setNextRouteSegment( const RouteSegment* segment )
{
m_nextRouteSegment = segment;
if ( segment ) {
m_valid = true;
}
}
bool RouteSegment::isValid() const
{
return m_valid;
}
qreal RouteSegment::distancePointToLine(const GeoDataCoordinates &p, const GeoDataCoordinates &a, const GeoDataCoordinates &b)
{
return EARTH_RADIUS * p.sphericalDistanceTo(projected(p, a, b));
}
GeoDataCoordinates RouteSegment::projected(const GeoDataCoordinates &p, const GeoDataCoordinates &a, const GeoDataCoordinates &b)
{
qreal const y0 = p.latitude();
qreal const x0 = p.longitude();
qreal const y1 = a.latitude();
qreal const x1 = a.longitude();
qreal const y2 = b.latitude();
qreal const x2 = b.longitude();
qreal const y01 = x0 - x1;
qreal const x01 = y0 - y1;
qreal const y21 = x2 - x1;
qreal const x21 = y2 - y1;
qreal const len = x21*x21 + y21*y21;
qreal const t = (x01*x21 + y01*y21) / len;
if ( t<0.0 ) {
return a;
} else if ( t > 1.0 ) {
return b;
} else {
// a + t (b - a);
qreal const lon = x1 + t * ( x2 - x1 );
qreal const lat = y1 + t * ( y2 - y1 );
return GeoDataCoordinates( lon, lat );
}
}
qreal RouteSegment::distanceTo( const GeoDataCoordinates &point, GeoDataCoordinates &closest, GeoDataCoordinates &interpolated ) const
{
Q_ASSERT( !m_path.isEmpty() );
if ( m_path.size() == 1 ) {
closest = m_path.first();
return EARTH_RADIUS * m_path.first().sphericalDistanceTo(point);
}
qreal minDistance = -1.0;
int minIndex = 0;
for ( int i=1; i<m_path.size(); ++i ) {
qreal const distance = distancePointToLine( point, m_path[i-1], m_path[i] );
if ( minDistance < 0.0 || distance < minDistance ) {
minDistance = distance;
minIndex = i;
}
}
closest = m_path[minIndex];
if ( minIndex == 0 ) {
interpolated = closest;
} else {
interpolated = projected( point, m_path[minIndex-1], m_path[minIndex] );
}
return minDistance;
}
qreal RouteSegment::minimalDistanceTo( const GeoDataCoordinates &point ) const
{
if ( bounds().contains( point) ) {
return 0.0;
}
qreal north(0.0), east(0.0), south(0.0), west(0.0);
bounds().boundaries( north, south, east, west );
GeoDataCoordinates const northWest( west, north );
GeoDataCoordinates const northEast( east, north );
GeoDataCoordinates const southhWest( west, south );
GeoDataCoordinates const southEast( east, south );
qreal distNorth = distancePointToLine( point, northWest, northEast );
qreal distEast = distancePointToLine( point, northEast, southEast );
qreal distSouth = distancePointToLine( point, southhWest, southEast );
qreal distWest = distancePointToLine( point, northWest, southhWest );
return qMin( qMin( distNorth, distEast ), qMin( distWest, distSouth ) );
}
qreal RouteSegment::projectedDirection(const GeoDataCoordinates &point) const
{
if (m_path.size() < 2){
return 0;
}
qreal minDistance = -1.0;
int minIndex = 0;
for ( int i=1; i<m_path.size(); ++i ) {
qreal const distance = distancePointToLine( point, m_path[i-1], m_path[i] );
if ( minDistance < 0.0 || distance < minDistance ) {
minDistance = distance;
minIndex = i;
}
}
if ( minIndex == 0 ) {
return m_path[0].bearing( m_path[1], GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing );
} else {
return m_path[minIndex-1].bearing( m_path[minIndex], GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing );
}
}
bool RouteSegment::operator ==(const RouteSegment &other) const
{
return m_valid == other.m_valid &&
m_distance == other.m_distance &&
m_maneuver == other.m_maneuver &&
m_travelTime == other.m_travelTime &&
m_bounds == other.m_bounds &&
m_nextRouteSegment == other.m_nextRouteSegment;
}
bool RouteSegment::operator !=(const RouteSegment &other) const
{
return !(other == *this);
}
}
diff --git a/src/lib/marble/routing/RoutingInputWidget.cpp b/src/lib/marble/routing/RoutingInputWidget.cpp
index 4b6e32b22..600c1692d 100644
--- a/src/lib/marble/routing/RoutingInputWidget.cpp
+++ b/src/lib/marble/routing/RoutingInputWidget.cpp
@@ -1,504 +1,504 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "RoutingInputWidget.h"
#include "MarblePlacemarkModel.h"
#include "RouteRequest.h"
#ifdef MARBLE_NO_WEBKITWIDGETS
#include "NullTinyWebBrowser.h"
#else
#include "TinyWebBrowser.h"
#endif
#include "BookmarkManager.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "routing/RoutingManager.h"
#include "GeoDataPlacemark.h"
#include "GeoDataFolder.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "PositionTracking.h"
#include "ReverseGeocodingRunnerManager.h"
#include "SearchRunnerManager.h"
#include "MarbleLineEdit.h"
#include "GoToDialog.h"
#include <QTimer>
#include <QHBoxLayout>
#include <QIcon>
#include <QPushButton>
#include <QMenu>
#include <QKeyEvent>
#include <QPainter>
namespace Marble
{
/**
* A MarbleLineEdit that swallows enter/return pressed
* key events
*/
class RoutingInputLineEdit : public MarbleLineEdit
{
public:
- explicit RoutingInputLineEdit( QWidget *parent = 0 );
+ explicit RoutingInputLineEdit( QWidget *parent = nullptr );
protected:
void keyPressEvent(QKeyEvent *) override;
};
class RoutingInputWidgetPrivate
{
public:
MarbleModel* m_marbleModel;
RoutingInputLineEdit *m_lineEdit;
QPushButton* m_removeButton;
SearchRunnerManager m_placemarkRunnerManager;
ReverseGeocodingRunnerManager m_reverseGeocodingRunnerManager;
MarblePlacemarkModel *m_placemarkModel;
RouteRequest *m_route;
int m_index;
QTimer m_nominatimTimer;
QAction* m_bookmarkAction;
QAction* m_mapInput;
QAction* m_currentLocationAction;
QAction* m_centerAction;
QMenu *m_menu;
/** Constructor */
RoutingInputWidgetPrivate( MarbleModel* model, int index, QWidget *parent );
/** Initiate reverse geocoding request to download address */
void adjustText();
void createMenu( RoutingInputWidget *parent );
QMenu* createBookmarkMenu( RoutingInputWidget *parent );
static void createBookmarkActions( QMenu* menu, GeoDataFolder* bookmarksFolder, QObject *parent );
static QPixmap addDropDownIndicator( const QPixmap &pixmap );
void updateDescription();
};
void RoutingInputWidgetPrivate::updateDescription()
{
GeoDataPlacemark const placemark = (*m_route)[m_index];
GeoDataExtendedData const address = placemark.extendedData();
if (address.contains(QStringLiteral("road")) && address.contains(QStringLiteral("city"))) {
QString const road = address.value(QStringLiteral("road")).value().toString();
QString const city = address.value(QStringLiteral("city")).value().toString();
if (address.contains(QStringLiteral("house_number"))) {
QString const houseNumber = address.value(QStringLiteral("house_number")).value().toString();
QString const name = QObject::tr("%1 %2, %3", "An address with parameters %1=house number, %2=road, %3=city");
m_lineEdit->setText( name.arg( houseNumber, road, city ) );
} else {
QString const name = QObject::tr("%2, %3", "An address with parameters %1=road, %2=city");
m_lineEdit->setText( name.arg( road, city ) );
}
}
else if ( m_route->name( m_index ).isEmpty() )
{
if ( !placemark.address().isEmpty() ) {
m_lineEdit->setText( placemark.address() );
}
else {
m_lineEdit->setText( placemark.coordinate().toString().trimmed() );
}
}
else
{
m_lineEdit->setText( placemark.name() );
}
m_lineEdit->setCursorPosition( 0 );
}
RoutingInputLineEdit::RoutingInputLineEdit( QWidget *parent ) :
MarbleLineEdit( parent )
{
setPlaceholderText( QObject::tr( "Address or search term..." ) );
}
void RoutingInputLineEdit::keyPressEvent(QKeyEvent *event)
{
MarbleLineEdit::keyPressEvent( event );
bool const returnPressed = event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter;
if ( returnPressed ) {
event->accept();
}
}
RoutingInputWidgetPrivate::RoutingInputWidgetPrivate( MarbleModel* model, int index, QWidget *parent ) :
m_marbleModel( model ),
- m_lineEdit( 0 ),
+ m_lineEdit( nullptr ),
m_placemarkRunnerManager( m_marbleModel ),
m_reverseGeocodingRunnerManager( m_marbleModel ),
- m_placemarkModel( 0 ), m_route( m_marbleModel->routingManager()->routeRequest() ), m_index( index ),
- m_bookmarkAction( 0 ), m_mapInput( 0 ), m_currentLocationAction( 0 ),
- m_centerAction( 0 ),
- m_menu( 0 )
+ m_placemarkModel( nullptr ), m_route( m_marbleModel->routingManager()->routeRequest() ), m_index( index ),
+ m_bookmarkAction( nullptr ), m_mapInput( nullptr ), m_currentLocationAction( nullptr ),
+ m_centerAction( nullptr ),
+ m_menu( nullptr )
{
m_lineEdit = new RoutingInputLineEdit( parent );
m_lineEdit->setDecorator( addDropDownIndicator( m_route->pixmap( m_index ) ) );
m_removeButton = new QPushButton( parent );
m_removeButton->setIcon(QIcon(QStringLiteral(":/marble/routing/icon-remove.png")));
m_removeButton->setToolTip( QObject::tr( "Remove via point" ) );
m_removeButton->setFlat( true );
m_removeButton->setMaximumWidth( 18 );
m_nominatimTimer.setInterval( 1000 );
m_nominatimTimer.setSingleShot( true );
}
void RoutingInputWidgetPrivate::adjustText()
{
m_nominatimTimer.start();
}
void RoutingInputWidgetPrivate::createMenu( RoutingInputWidget *parent )
{
QMenu* result = new QMenu( parent );
m_centerAction = result->addAction( QIcon( m_route->pixmap( m_index ) ), QObject::tr( "&Center Map here" ),
parent, SLOT(requestActivity()) );
result->addSeparator();
m_currentLocationAction = result->addAction( QIcon(QStringLiteral(":/icons/gps.png")), QObject::tr("Current &Location"),
parent, SLOT(setCurrentLocation()) );
m_currentLocationAction->setEnabled( false );
m_mapInput = result->addAction(QIcon(QStringLiteral(":/icons/crosshairs.png")), QObject::tr("From &Map..."));
m_mapInput->setCheckable( true );
QObject::connect( m_mapInput, SIGNAL(triggered(bool)), parent, SLOT(setMapInputModeEnabled(bool)) );
m_bookmarkAction = result->addAction(QIcon(QStringLiteral(":/icons/bookmarks.png")), QObject::tr("From &Bookmark"));
m_bookmarkAction->setMenu( createBookmarkMenu( parent ) );
m_menu = result;
}
QMenu* RoutingInputWidgetPrivate::createBookmarkMenu( RoutingInputWidget *parent )
{
QMenu* result = new QMenu( parent );
result->addAction(QIcon(QStringLiteral(":/icons/go-home.png")), QObject::tr("&Home"), parent, SLOT(setHomePosition()));
QVector<GeoDataFolder*> folders = m_marbleModel->bookmarkManager()->folders();
if ( folders.size() == 1 ) {
createBookmarkActions( result, folders.first(), parent );
} else {
QVector<GeoDataFolder*>::const_iterator i = folders.constBegin();
QVector<GeoDataFolder*>::const_iterator end = folders.constEnd();
for (; i != end; ++i ) {
QMenu* menu = result->addMenu(QIcon(QStringLiteral(":/icons/folder-bookmark.png")), (*i)->name());
createBookmarkActions( menu, *i, parent );
}
}
return result;
}
void RoutingInputWidgetPrivate::createBookmarkActions( QMenu* menu, GeoDataFolder* bookmarksFolder, QObject *parent )
{
QVector<GeoDataPlacemark*> bookmarks = bookmarksFolder->placemarkList();
QVector<GeoDataPlacemark*>::const_iterator i = bookmarks.constBegin();
QVector<GeoDataPlacemark*>::const_iterator end = bookmarks.constEnd();
for (; i != end; ++i ) {
QAction *bookmarkAction = new QAction( (*i)->name(), parent );
bookmarkAction->setData( qVariantFromValue( (*i)->coordinate() ) );
menu->addAction( bookmarkAction );
QObject::connect( menu, SIGNAL(triggered(QAction*)), parent, SLOT(setBookmarkPosition(QAction*)) );
}
}
QPixmap RoutingInputWidgetPrivate::addDropDownIndicator(const QPixmap &pixmap)
{
QPixmap result( pixmap.size() + QSize( 8, pixmap.height() ) );
result.fill( QColor( Qt::transparent ) );
QPainter painter( &result );
painter.drawPixmap( 0, 0, pixmap );
QPoint const one( pixmap.width() + 1, pixmap.height() - 8 );
QPoint const two( one.x() + 6, one.y() );
QPoint const three( one.x() + 3, one.y() + 4 );
painter.setRenderHint( QPainter::Antialiasing, true );
painter.setPen( Qt::NoPen );
painter.setBrush( QColor( Oxygen::aluminumGray4 ) );
painter.drawConvexPolygon( QPolygon() << one << two << three );
return result;
}
RoutingInputWidget::RoutingInputWidget( MarbleModel* model, int index, QWidget *parent ) :
QWidget( parent ), d( new RoutingInputWidgetPrivate( model, index, this ) )
{
QHBoxLayout *layout = new QHBoxLayout( this );
layout->setSizeConstraint( QLayout::SetMinimumSize );
layout->setSpacing( 0 );
layout->setMargin( 0 );
layout->addWidget( d->m_lineEdit );
layout->addWidget( d->m_removeButton );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( smallScreen ) {
connect( d->m_lineEdit, SIGNAL(decoratorButtonClicked()), this, SLOT(openTargetSelectionDialog()) );
} else {
d->createMenu( this );
connect(d->m_lineEdit, SIGNAL(decoratorButtonClicked()), this, SLOT(showMenu()));
}
connect( d->m_removeButton, SIGNAL(clicked()), this, SLOT(requestRemoval()) );
connect( d->m_marbleModel->bookmarkManager(), SIGNAL(bookmarksChanged()),
this, SLOT(reloadBookmarks()) );
connect( d->m_marbleModel->positionTracking(), SIGNAL(statusChanged(PositionProviderStatus)),
this, SLOT(updateCurrentLocationButton(PositionProviderStatus)) );
connect( &d->m_placemarkRunnerManager, SIGNAL(searchResultChanged(QAbstractItemModel*)),
this, SLOT(setPlacemarkModel(QAbstractItemModel*)) );
connect( &d->m_reverseGeocodingRunnerManager, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)),
this, SLOT(retrieveReverseGeocodingResult(GeoDataCoordinates,GeoDataPlacemark)) );
connect( d->m_lineEdit, SIGNAL(returnPressed()),
this, SLOT(findPlacemarks()) );
connect( d->m_lineEdit, SIGNAL(textEdited(QString)),
this, SLOT(setInvalid()) );
connect( &d->m_placemarkRunnerManager, SIGNAL(searchFinished(QString)),
this, SLOT(finishSearch()) );
connect( d->m_marbleModel->routingManager()->routeRequest(), SIGNAL(positionChanged(int,GeoDataCoordinates)),
this, SLOT(updatePosition(int,GeoDataCoordinates)) );
connect( &d->m_nominatimTimer, SIGNAL(timeout()),
this, SLOT(reverseGeocoding()) );
connect( this, SIGNAL(targetValidityChanged(bool)), this, SLOT(updateCenterButton(bool)) );
updateCenterButton( hasTargetPosition() );
d->adjustText();
}
RoutingInputWidget::~RoutingInputWidget()
{
delete d;
}
void RoutingInputWidget::reverseGeocoding()
{
if ( !hasTargetPosition() ) {
return;
}
QString const name = d->m_route->name( d->m_index );
if ( name.isEmpty() || name == tr( "Current Location" ) ) {
d->m_reverseGeocodingRunnerManager.reverseGeocoding( targetPosition() );
} else {
d->updateDescription();
}
}
void RoutingInputWidget::setPlacemarkModel( QAbstractItemModel *model )
{
d->m_placemarkModel = dynamic_cast<MarblePlacemarkModel*>(model);
}
void RoutingInputWidget::setTargetPosition( const GeoDataCoordinates &position, const QString &name )
{
if ( d->m_mapInput ) {
d->m_mapInput->setChecked( false );
}
d->m_route->setPosition( d->m_index, position, name );
if ( !name.isEmpty() ) {
d->updateDescription();
}
emit targetValidityChanged( true );
}
bool RoutingInputWidget::hasTargetPosition() const
{
return targetPosition().isValid();
}
GeoDataCoordinates RoutingInputWidget::targetPosition() const
{
if ( d->m_index < d->m_route->size() ) {
return d->m_route->at( d->m_index );
} else {
return GeoDataCoordinates();
}
}
void RoutingInputWidget::findPlacemarks()
{
QString text = d->m_lineEdit->text();
if ( text.isEmpty() ) {
setInvalid();
} else {
d->m_lineEdit->setBusy(true);
d->m_placemarkRunnerManager.findPlacemarks( text );
}
}
MarblePlacemarkModel *RoutingInputWidget::searchResultModel()
{
return d->m_placemarkModel;
}
void RoutingInputWidget::requestActivity()
{
if ( hasTargetPosition() ) {
emit activityRequest( this );
}
}
void RoutingInputWidget::requestRemoval()
{
emit removalRequest( this );
}
bool RoutingInputWidget::hasInput() const
{
return !d->m_lineEdit->text().isEmpty();
}
void RoutingInputWidget::setMapInputModeEnabled( bool enabled )
{
emit mapInputModeEnabled( this, enabled );
}
void RoutingInputWidget::finishSearch()
{
d->m_lineEdit->setBusy(false);
emit searchFinished( this );
}
void RoutingInputWidget::setInvalid()
{
d->m_route->setPosition( d->m_index, GeoDataCoordinates() );
emit targetValidityChanged( false );
}
void RoutingInputWidget::abortMapInputRequest()
{
if ( d->m_mapInput ) {
d->m_mapInput->setChecked( false );
}
}
void RoutingInputWidget::setIndex( int index )
{
d->m_index = index;
d->m_lineEdit->setBusy(false);
d->m_lineEdit->setDecorator( d->addDropDownIndicator( d->m_route->pixmap( index ) ) );
}
void RoutingInputWidget::updatePosition( int index, const GeoDataCoordinates & )
{
if ( index == d->m_index ) {
d->m_lineEdit->setBusy(false);
emit targetValidityChanged( hasTargetPosition() );
d->adjustText();
}
}
void RoutingInputWidget::clear()
{
d->m_nominatimTimer.stop();
d->m_lineEdit->setBusy(false);
d->m_route->setPosition( d->m_index, GeoDataCoordinates() );
d->m_lineEdit->clear();
emit targetValidityChanged( false );
}
void RoutingInputWidget::retrieveReverseGeocodingResult( const GeoDataCoordinates &, const GeoDataPlacemark &placemark )
{
(*d->m_route)[d->m_index] = placemark;
d->updateDescription();
}
void RoutingInputWidget::reloadBookmarks()
{
if ( d->m_bookmarkAction ) {
d->m_bookmarkAction->setMenu( d->createBookmarkMenu( this ) );
}
}
void RoutingInputWidget::setHomePosition()
{
qreal lon( 0.0 ), lat( 0.0 );
int zoom( 0 );
d->m_marbleModel->home( lon, lat, zoom );
GeoDataCoordinates home( lon, lat, 0.0, GeoDataCoordinates::Degree );
setTargetPosition( home );
requestActivity();
}
void RoutingInputWidget::updateCurrentLocationButton( PositionProviderStatus status )
{
if ( d->m_currentLocationAction ) {
d->m_currentLocationAction->setEnabled( status == PositionProviderStatusAvailable );
}
}
void RoutingInputWidget::setCurrentLocation()
{
setTargetPosition( d->m_marbleModel->positionTracking()->currentLocation() );
requestActivity();
}
void RoutingInputWidget::updateCenterButton( bool hasPosition )
{
if ( d->m_centerAction ) {
d->m_centerAction->setEnabled( hasPosition );
}
}
void RoutingInputWidget::setBookmarkPosition( QAction* bookmark )
{
if ( !bookmark->data().isNull() ) {
setTargetPosition( bookmark->data().value<GeoDataCoordinates>() );
requestActivity();
}
}
void RoutingInputWidget::openTargetSelectionDialog()
{
QPointer<GoToDialog> dialog = new GoToDialog( d->m_marbleModel, this );
dialog->setWindowTitle( tr( "Choose Placemark" ) );
dialog->setShowRoutingItems( false );
dialog->setSearchEnabled( false );
if ( dialog->exec() == QDialog::Accepted ) {
const GeoDataCoordinates coordinates = dialog->coordinates();
setTargetPosition( coordinates );
}
delete dialog;
}
void RoutingInputWidget::showMenu()
{
d->m_menu->exec( mapToGlobal( QPoint( 0, size().height() ) ) );
}
} // namespace Marble
#include "moc_RoutingInputWidget.cpp"
diff --git a/src/lib/marble/routing/RoutingInputWidget.h b/src/lib/marble/routing/RoutingInputWidget.h
index 8924398fa..4d606e16e 100644
--- a/src/lib/marble/routing/RoutingInputWidget.h
+++ b/src/lib/marble/routing/RoutingInputWidget.h
@@ -1,161 +1,161 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTINGINPUTWIDGET_H
#define MARBLE_ROUTINGINPUTWIDGET_H
#include "PositionProviderPluginInterface.h"
#include <QWidget>
class QAbstractItemModel;
namespace Marble
{
class RoutingInputWidgetPrivate;
class GeoDataCoordinates;
class GeoDataPlacemark;
class MarbleModel;
class MarblePlacemarkModel;
/**
* Combines a line edit for input and a couple of buttons to let
* the user type in a search term, find according placemarks using
* the marble runner manager and store one of them as the current
* selection (target position)
*/
class RoutingInputWidget : public QWidget
{
Q_OBJECT
public:
/** Constructor */
- explicit RoutingInputWidget( MarbleModel* model, int index, QWidget *parent = 0 );
+ explicit RoutingInputWidget( MarbleModel* model, int index, QWidget *parent = nullptr );
/** Destructor */
~RoutingInputWidget() override;
/**
* Returns true if the user has selected a valid geo position
* @see targetPosition
*/
bool hasTargetPosition() const;
/**
* Returns the geoposition selected by the user, or a default
* constructed geoposition if hasTargetPosition returns false
* @see hasTargetPosition selectPlacemark
*/
GeoDataCoordinates targetPosition() const;
/**
* Returns the placemark model that contains search results
*/
MarblePlacemarkModel *searchResultModel();
/**
* Returns false iff the input text is empty
*/
bool hasInput() const;
/**
* Change the data index in the route request model
*/
void setIndex( int index );
/**
* Remove target position and user input, if any
*/
void clear();
public Q_SLOTS:
/**
* Search for placemarks matching the current input text. Does nothing
* if input is empty
*/
void findPlacemarks();
/** Set the target position to the given coordinates,
* eliminating any previously set positions
* @see selectPlacemark hasTargetPosition
*/
void setTargetPosition( const GeoDataCoordinates &position, const QString &name = QString() );
/** Cancel a started input request from the map */
void abortMapInputRequest();
/** Reload the bookmarks menu */
void reloadBookmarks();
Q_SIGNALS:
/** All runners are finished */
void searchFinished( RoutingInputWidget * );
/** User requests to remove this widget */
void removalRequest( RoutingInputWidget * );
/** User requests to activate this widget */
void activityRequest( RoutingInputWidget * );
/** User requests position input from the map */
void mapInputModeEnabled( RoutingInputWidget *, bool enabled );
/** hasTargetPosition changed because of selecting a placemark or changing the search term */
void targetValidityChanged( bool targetValid );
private Q_SLOTS:
/** Runner progress */
void setPlacemarkModel( QAbstractItemModel * );
/** Handle click on the goto target button */
void requestActivity();
/** Handle click on the remove widget button */
void requestRemoval();
/** Handle click on the map input button */
void setMapInputModeEnabled( bool enabled );
/** All runners have completed */
void finishSearch();
/** Mark ourself dirty (no target) */
void setInvalid();
/** Set the target position (dragging) */
void updatePosition( int index, const GeoDataCoordinates &position );
void reverseGeocoding();
void retrieveReverseGeocodingResult( const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark );
void setHomePosition();
void setCurrentLocation();
void updateCurrentLocationButton( PositionProviderStatus status );
void updateCenterButton( bool hasPosition );
void setBookmarkPosition( QAction* bookmark );
void openTargetSelectionDialog();
void showMenu();
private:
RoutingInputWidgetPrivate *const d;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/routing/RoutingLayer.cpp b/src/lib/marble/routing/RoutingLayer.cpp
index 8d2897fac..70f3510e7 100644
--- a/src/lib/marble/routing/RoutingLayer.cpp
+++ b/src/lib/marble/routing/RoutingLayer.cpp
@@ -1,817 +1,817 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "RoutingLayer.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLineString.h"
#include "GeoPainter.h"
#include "MarblePlacemarkModel.h"
#include "MarbleWidget.h"
#include "MarbleWidgetPopupMenu.h"
#include "RoutingModel.h"
#include "Route.h"
#include "RouteRequest.h"
#include "MarbleModel.h"
#include "AlternativeRoutesModel.h"
#include "RoutingManager.h"
#include "Maneuver.h"
#include "RenderState.h"
#include <QAbstractItemModel>
#include <QIcon>
#include <QItemSelectionModel>
#include <QAction>
#include <QMouseEvent>
#include <QPixmap>
#include <QFileDialog>
namespace Marble
{
class RoutingLayerPrivate
{
template<class T>
struct PaintRegion {
T index;
QRegion region;
PaintRegion( const T &index_, const QRegion &region_ ) :
index( index_ ), region( region_ )
{
// nothing to do
}
};
typedef PaintRegion<QModelIndex> ModelRegion;
typedef PaintRegion<int> RequestRegion;
public:
RoutingLayer *const q;
QList<ModelRegion> m_instructionRegions;
QList<RequestRegion> m_regions;
QList<RequestRegion> m_alternativeRouteRegions;
QList<ModelRegion> m_placemarks;
QRegion m_routeRegion;
int m_movingIndex;
MarbleWidget *const m_marbleWidget;
QPixmap m_targetPixmap;
QPixmap m_standardRoutePoint;
QPixmap m_activeRoutePoint;
QRect m_dirtyRect;
QPoint m_dropStopOver;
QPoint m_dragStopOver;
int m_dragStopOverRightIndex;
RoutingModel *const m_routingModel;
MarblePlacemarkModel *m_placemarkModel;
QItemSelectionModel *m_selectionModel;
QSize m_pixmapSize;
RouteRequest *const m_routeRequest;
MarbleWidgetPopupMenu *m_contextMenu;
QAction *m_removeViaPointAction;
int m_activeMenuIndex;
AlternativeRoutesModel *const m_alternativeRoutesModel;
ViewContext m_viewContext;
bool m_viewportChanged;
bool m_isInteractive;
/** Constructor */
explicit RoutingLayerPrivate( RoutingLayer *parent, MarbleWidget *widget );
/** Update the cached drag position. Use an empty point to clear it. */
void storeDragPosition( const QPoint &position );
// The following methods are mostly only called at one place in the code, but often
// Inlined to avoid the function call overhead. Having functions here is just to
// keep the code clean
/** Returns the same color as the given one with its alpha channel adjusted to the given value */
static inline QColor alphaAdjusted( const QColor &color, int alpha );
static QPixmap createRoutePoint(const QColor &penColor, const QColor &brushColor);
/**
* Returns the start or destination position if Ctrl key is among the
* provided modifiers, the cached insert position otherwise
*/
inline int viaInsertPosition( Qt::KeyboardModifiers modifiers ) const;
/** Paint icons for each placemark in the placemark model */
inline void renderPlacemarks( GeoPainter *painter );
/** Paint waypoint polygon */
inline void renderRoute( GeoPainter *painter );
/** Paint turn instruction for selected items */
inline void renderAnnotations( GeoPainter *painter ) const;
/** Paint alternative routes in gray */
inline void renderAlternativeRoutes( GeoPainter *painter );
/** Paint icons for trip points etc */
inline void renderRequest( GeoPainter *painter );
/** Insert via points or emit position signal, if appropriate */
inline bool handleMouseButtonRelease( QMouseEvent *e );
/** Select route instructions points, start dragging trip points */
inline bool handleMouseButtonPress( QMouseEvent *e );
/** Dragging trip points, route polygon hovering */
inline bool handleMouseMove( QMouseEvent *e );
/** True if the given point (screen coordinates) is among the route instruction points */
inline bool isInfoPoint( const QPoint &point );
/** True if the given point (screen coordinates) is above an alternative route */
inline bool isAlternativeRoutePoint( const QPoint &point );
/** Paint the stopover indicator pixmap at the given position. Also repaints the old position */
inline void paintStopOver( QRect position );
/** Removes the stopover indicator pixmap. Also repaints its old position */
inline void clearStopOver();
};
RoutingLayerPrivate::RoutingLayerPrivate( RoutingLayer *parent, MarbleWidget *widget ) :
q( parent ), m_movingIndex( -1 ), m_marbleWidget( widget ),
m_targetPixmap(QStringLiteral(":/data/bitmaps/routing_pick.png")),
m_standardRoutePoint(createRoutePoint(widget->model()->routingManager()->routeColorStandard(),
widget->model()->routingManager()->routeColorAlternative())),
m_activeRoutePoint(createRoutePoint(widget->model()->routingManager()->routeColorHighlighted(),
alphaAdjusted(Oxygen::hotOrange4, 200))),
m_dragStopOverRightIndex(-1),
m_routingModel( widget->model()->routingManager()->routingModel() ),
- m_placemarkModel( 0 ),
- m_selectionModel( 0 ),
+ m_placemarkModel( nullptr ),
+ m_selectionModel( nullptr ),
m_pixmapSize( 22, 22 ),
m_routeRequest( widget->model()->routingManager()->routeRequest() ),
m_activeMenuIndex( -1 ),
m_alternativeRoutesModel( widget->model()->routingManager()->alternativeRoutesModel() ),
m_viewContext( Still ),
m_viewportChanged( true ),
m_isInteractive( true )
{
m_contextMenu = new MarbleWidgetPopupMenu( m_marbleWidget, m_marbleWidget->model() );
m_removeViaPointAction = new QAction( QObject::tr( "&Remove this destination" ), q );
QObject::connect( m_removeViaPointAction, SIGNAL(triggered()), q, SLOT(removeViaPoint()) );
m_contextMenu->addAction( Qt::RightButton, m_removeViaPointAction );
QAction *exportAction = new QAction( QObject::tr( "&Export route..." ), q );
QObject::connect( exportAction, SIGNAL(triggered()), q, SLOT(exportRoute()) );
m_contextMenu->addAction( Qt::RightButton, exportAction );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
m_pixmapSize = QSize( 38, 38 );
}
}
int RoutingLayerPrivate::viaInsertPosition( Qt::KeyboardModifiers modifiers ) const
{
if ( modifiers & Qt::ControlModifier ) {
bool leftHand = m_routeRequest->size() / 2 >= m_dragStopOverRightIndex;
if ( leftHand && m_routeRequest->size() > 2 ) {
return 0;
} else {
return m_routeRequest->size();
}
} else {
return m_dragStopOverRightIndex;
}
}
void RoutingLayerPrivate::renderPlacemarks( GeoPainter *painter )
{
m_placemarks.clear();
painter->setPen( QColor( Qt::black ) );
for ( int i = 0; i < m_placemarkModel->rowCount(); ++i ) {
QModelIndex index = m_placemarkModel->index( i, 0 );
QVariant data = index.data( MarblePlacemarkModel::CoordinateRole );
if ( index.isValid() && !data.isNull() ) {
GeoDataCoordinates pos = data.value<GeoDataCoordinates>();
QPixmap pixmap = index.data( Qt::DecorationRole ).value<QPixmap>();
if ( !pixmap.isNull() && m_selectionModel->isSelected( index ) ) {
QIcon selected = QIcon( pixmap );
QPixmap result = selected.pixmap( m_pixmapSize, QIcon::Selected, QIcon::On );
painter->drawPixmap( pos, result );
} else {
painter->drawPixmap( pos, pixmap );
}
const QRegion region = painter->regionFromPixmapRect(pos, m_targetPixmap.width(), m_targetPixmap.height());
m_placemarks.push_back( ModelRegion( index, region ) );
}
}
}
void RoutingLayerPrivate::renderAlternativeRoutes( GeoPainter *painter )
{
QPen alternativeRoutePen( m_marbleWidget->model()->routingManager()->routeColorAlternative() );
alternativeRoutePen.setWidth( 5 );
painter->setPen( alternativeRoutePen );
for ( int i=0; i<m_alternativeRoutesModel->rowCount(); ++i ) {
const GeoDataDocument *route = m_alternativeRoutesModel->route(i);
if ( route && route != m_alternativeRoutesModel->currentRoute() ) {
const GeoDataLineString* points = AlternativeRoutesModel::waypoints( route );
if ( points ) {
painter->drawPolyline( *points );
if ( m_viewportChanged && m_isInteractive && m_viewContext == Still ) {
QRegion region = painter->regionFromPolyline( *points, 8 );
m_alternativeRouteRegions.push_back( RequestRegion( i, region ) );
}
}
}
}
}
void RoutingLayerPrivate::renderRoute( GeoPainter *painter )
{
GeoDataLineString waypoints = m_routingModel->route().path();
QPen standardRoutePen( m_marbleWidget->model()->routingManager()->routeColorStandard() );
standardRoutePen.setWidth( 5 );
if ( m_marbleWidget->model()->routingManager()->state() == RoutingManager::Downloading ) {
standardRoutePen.setStyle( Qt::DotLine );
}
painter->setPen( standardRoutePen );
painter->drawPolyline( waypoints );
if ( m_viewportChanged && m_viewContext == Still ) {
int const offset = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ? 24 : 8;
if ( m_isInteractive ) {
m_routeRegion = painter->regionFromPolyline( waypoints, offset );
}
}
standardRoutePen.setWidth( 2 );
painter->setPen( standardRoutePen );
// Map matched position
//painter->setBrush( QBrush( Oxygen::brickRed4) );
//painter->drawEllipse( m_routingModel->route().positionOnRoute(), 8, 8 );
painter->setBrush( QBrush( m_marbleWidget->model()->routingManager()->routeColorAlternative() ) );
if ( !m_dropStopOver.isNull() ) {
int dx = 1 + m_pixmapSize.width() / 2;
int dy = 1 + m_pixmapSize.height() / 2;
QPoint center = m_dropStopOver - QPoint( dx, dy );
painter->drawPixmap( center, m_targetPixmap );
if ( !m_dragStopOver.isNull() && m_dragStopOverRightIndex >= 0 && m_dragStopOverRightIndex <= m_routeRequest->size() ) {
QPoint moved = m_dropStopOver - m_dragStopOver;
if ( moved.manhattanLength() > 10 ) {
qreal lon( 0.0 ), lat( 0.0 );
if ( m_marbleWidget->geoCoordinates( m_dropStopOver.x(), m_dropStopOver.y(),
lon, lat, GeoDataCoordinates::Radian ) ) {
GeoDataCoordinates drag( lon, lat );
standardRoutePen.setStyle( Qt::DotLine );
painter->setPen( standardRoutePen );
GeoDataLineString lineString;
if ( m_dragStopOverRightIndex > 0 ) {
lineString << m_routeRequest->at( m_dragStopOverRightIndex-1 );
}
lineString << drag;
if ( m_dragStopOverRightIndex < m_routeRequest->size() ) {
lineString << m_routeRequest->at( m_dragStopOverRightIndex );
}
painter->drawPolyline( lineString );
standardRoutePen.setStyle( Qt::SolidLine );
painter->setPen( standardRoutePen );
}
}
}
}
if ( m_viewContext == Animation ) {
return;
}
if( m_routingModel->rowCount() == m_routingModel->route().size() ) {
m_instructionRegions.clear();
QPen activeRouteSegmentPen(m_marbleWidget->model()->routingManager()->routeColorHighlighted());
activeRouteSegmentPen.setWidth(6);
if (m_marbleWidget->model()->routingManager()->state() == RoutingManager::Downloading) {
activeRouteSegmentPen.setStyle(Qt::DotLine);
}
painter->setPen(activeRouteSegmentPen);
for ( int i = 0; i < m_routingModel->rowCount(); ++i ) {
QModelIndex index = m_routingModel->index( i, 0 );
GeoDataCoordinates pos = index.data( MarblePlacemarkModel::CoordinateRole ).value<GeoDataCoordinates>();
if ( m_selectionModel && m_selectionModel->selection().contains( index ) ) {
const RouteSegment &segment = m_routingModel->route().at( i );
const GeoDataLineString currentRoutePoints = segment.path();
painter->drawPolyline( currentRoutePoints );
painter->drawPixmap(pos, m_activeRoutePoint);
}
else {
painter->drawPixmap(pos, m_standardRoutePoint);
}
if ( m_isInteractive ) {
QRegion region = painter->regionFromEllipse( pos, 12, 12 );
m_instructionRegions.push_front( ModelRegion( index, region ) );
}
}
}
if( !m_routingModel->deviatedFromRoute() ) {
GeoDataCoordinates location = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().position();
QString nextInstruction = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().instructionText();
if( !nextInstruction.isEmpty() ) {
painter->drawPixmap(location, m_activeRoutePoint);
}
}
}
void RoutingLayerPrivate::renderAnnotations( GeoPainter *painter ) const
{
if ( !m_selectionModel || m_selectionModel->selection().isEmpty() ) {
// nothing to do
return;
}
for ( int i = 0; i < m_routingModel->rowCount(); ++i ) {
QModelIndex index = m_routingModel->index( i, 0 );
if ( m_selectionModel->selection().contains( index ) ) {
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
GeoDataCoordinates pos = index.data( MarblePlacemarkModel::CoordinateRole ).value<GeoDataCoordinates>();
painter->setPen( QColor( Qt::black ) );
painter->setBrush( QBrush( Oxygen::sunYellow6 ) );
painter->drawAnnotation( pos, index.data().toString(), QSize( smallScreen ? 240 : 120, 0 ), 10, 30, 5, 5 );
}
}
}
void RoutingLayerPrivate::renderRequest( GeoPainter *painter )
{
m_regions.clear();
for ( int i = 0; i < m_routeRequest->size(); ++i ) {
const GeoDataCoordinates pos = m_routeRequest->at( i );
if ( pos.isValid() ) {
QPixmap pixmap = m_routeRequest->pixmap( i );
painter->drawPixmap( pos, pixmap );
const QRegion region = painter->regionFromPixmapRect(pos, pixmap.width(), pixmap.height());
m_regions.push_front( RequestRegion( i, region ) );
}
}
}
void RoutingLayerPrivate::storeDragPosition( const QPoint &pos )
{
m_dragStopOver = pos;
m_dragStopOverRightIndex = -1;
qreal lon( 0.0 ), lat( 0.0 );
if ( m_routeRequest && !pos.isNull()
&& m_marbleWidget->geoCoordinates( pos.x(), pos.y(), lon, lat, GeoDataCoordinates::Radian ) ) {
GeoDataCoordinates waypoint( lon, lat );
m_dragStopOverRightIndex = m_routingModel->rightNeighbor( waypoint, m_routeRequest );
}
}
QColor RoutingLayerPrivate::alphaAdjusted( const QColor &color, int alpha )
{
QColor result( color );
result.setAlpha( alpha );
return result;
}
QPixmap RoutingLayerPrivate::createRoutePoint(const QColor &penColor, const QColor &brushColor)
{
QPen pen(penColor);
pen.setWidth(2);
const QBrush brush(brushColor);
QPixmap routePoint(QSize(8, 8));
routePoint.fill(Qt::transparent);
QPainter painter(&routePoint);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(pen);
painter.setBrush(brush);
painter.drawEllipse(1, 1, 6, 6);
return routePoint;
}
bool RoutingLayerPrivate::handleMouseButtonPress( QMouseEvent *e )
{
for( const RequestRegion &region: m_regions ) {
if ( region.region.contains( e->pos() ) ) {
if ( e->button() == Qt::LeftButton ) {
m_movingIndex = region.index;
m_dropStopOver = QPoint();
m_dragStopOver = QPoint();
return true;
} else if ( e->button() == Qt::RightButton ) {
m_removeViaPointAction->setEnabled( true );
m_activeMenuIndex = region.index;
m_contextMenu->showRmbMenu( e->x(), e->y() );
return true;
} else
return false;
}
}
for( const ModelRegion &region: m_instructionRegions ) {
if ( region.region.contains( e->pos() ) && m_selectionModel ) {
if ( e->button() == Qt::LeftButton ) {
QItemSelectionModel::SelectionFlag command = QItemSelectionModel::ClearAndSelect;
if ( m_selectionModel->isSelected( region.index ) ) {
command = QItemSelectionModel::Clear;
}
m_selectionModel->select( region.index, command );
m_dropStopOver = e->pos();
storeDragPosition( e->pos() );
// annotation and old annotation are dirty, large region
emit q->repaintNeeded();
return true;
} else if ( e->button() == Qt::RightButton ) {
m_removeViaPointAction->setEnabled( false );
m_contextMenu->showRmbMenu( e->x(), e->y() );
return true;
} else
return false;
}
}
if ( m_routeRegion.contains( e->pos() ) ) {
if ( e->button() == Qt::LeftButton ) {
/** @todo: Determine the neighbored via points and insert in order */
m_dropStopOver = e->pos();
storeDragPosition( e->pos() );
return true;
} else if ( e->button() == Qt::RightButton ) {
m_removeViaPointAction->setEnabled( false );
m_contextMenu->showRmbMenu( e->x(), e->y() );
return true;
} else
return false;
}
if ( e->button() != Qt::LeftButton ) {
return false;
}
for( const RequestRegion &region: m_alternativeRouteRegions ) {
if ( region.region.contains( e->pos() ) ) {
m_alternativeRoutesModel->setCurrentRoute( region.index );
return true;
}
}
for( const ModelRegion &region: m_placemarks ) {
if ( region.region.contains( e->pos() ) ) {
emit q->placemarkSelected( region.index );
return true;
}
}
return false;
}
bool RoutingLayerPrivate::handleMouseButtonRelease( QMouseEvent *e )
{
if ( e->button() != Qt::LeftButton ) {
return false;
}
if ( m_movingIndex >= 0 ) {
m_movingIndex = -1;
clearStopOver();
m_marbleWidget->model()->routingManager()->retrieveRoute();
return true;
}
if ( !m_dropStopOver.isNull() && !m_dragStopOver.isNull() ) {
QPoint moved = e->pos() - m_dragStopOver;
if ( moved.manhattanLength() < 10 ) {
return false;
}
qreal lon( 0.0 ), lat( 0.0 );
if ( m_dragStopOverRightIndex >= 0 && m_dragStopOverRightIndex <= m_routeRequest->size()
&& m_marbleWidget->geoCoordinates( m_dropStopOver.x(), m_dropStopOver.y(), lon, lat, GeoDataCoordinates::Radian ) ) {
GeoDataCoordinates position( lon, lat );
m_dragStopOverRightIndex = viaInsertPosition( e->modifiers() );
m_routeRequest->insert( m_dragStopOverRightIndex, position );
clearStopOver();
m_marbleWidget->model()->routingManager()->retrieveRoute();
return true;
}
}
return false;
}
bool RoutingLayerPrivate::handleMouseMove( QMouseEvent *e )
{
qreal lon( 0.0 ), lat( 0.0 );
if ( m_marbleWidget->geoCoordinates( e->pos().x(), e->pos().y(),
lon, lat, GeoDataCoordinates::Radian ) ) {
if ( m_movingIndex >= 0 ) {
GeoDataCoordinates moved( lon, lat );
m_routeRequest->setPosition( m_movingIndex, moved );
m_marbleWidget->setCursor( Qt::ArrowCursor );
} else if ( !m_dragStopOver.isNull() ) {
// Repaint only that region of the map that is affected by the change
m_dragStopOverRightIndex = viaInsertPosition( e->modifiers() );
QRect dirty = m_routeRegion.boundingRect();
dirty |= QRect( m_dropStopOver, m_pixmapSize );
dirty |= QRect( e->pos(), m_pixmapSize );
if ( e->buttons() & Qt::LeftButton ) {
m_dropStopOver = e->pos();
} else {
m_dragStopOver = QPoint();
m_dropStopOver = QPoint();
}
emit q->repaintNeeded( dirty );
m_marbleWidget->setCursor( Qt::ArrowCursor );
} else if ( isInfoPoint( e->pos() ) ) {
clearStopOver();
m_marbleWidget->setCursor( Qt::ArrowCursor );
} else if ( m_routeRegion.contains( e->pos() ) ) {
m_dropStopOver = e->pos();
m_marbleWidget->setCursor( Qt::ArrowCursor );
} else if ( !m_dropStopOver.isNull() ) {
clearStopOver();
} else if ( isAlternativeRoutePoint( e->pos() ) ) {
m_marbleWidget->setCursor( Qt::ArrowCursor );
}
else {
return false;
}
// Update pixmap in the map (old and new position needs repaint)
paintStopOver( QRect( e->pos(), m_pixmapSize ) );
return true;
}
return false;
}
bool RoutingLayerPrivate::isInfoPoint( const QPoint &point )
{
for( const RequestRegion &region: m_regions ) {
if ( region.region.contains( point ) ) {
return true;
}
}
for( const ModelRegion &region: m_instructionRegions ) {
if ( region.region.contains( point ) ) {
return true;
}
}
return false;
}
bool RoutingLayerPrivate::isAlternativeRoutePoint( const QPoint &point )
{
for( const RequestRegion &region: m_alternativeRouteRegions ) {
if ( region.region.contains( point ) ) {
return true;
}
}
return false;
}
void RoutingLayerPrivate::paintStopOver( QRect dirty )
{
emit q->repaintNeeded( m_dirtyRect );
int dx = 1 + m_pixmapSize.width() / 2;
int dy = 1 + m_pixmapSize.height() / 2;
dirty.adjust( -dx, -dy, -dx, -dy );
emit q->repaintNeeded( dirty );
m_dirtyRect = dirty;
}
void RoutingLayerPrivate::clearStopOver()
{
m_dropStopOver = QPoint();
m_dragStopOver = QPoint();
emit q->repaintNeeded( m_dirtyRect );
}
RoutingLayer::RoutingLayer( MarbleWidget *widget, QWidget *parent ) :
QObject( parent ), d( new RoutingLayerPrivate( this, widget ) )
{
connect( widget->model()->routingManager(), SIGNAL(stateChanged(RoutingManager::State)),
this, SLOT(updateRouteState()) );
connect( widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this, SLOT(setViewportChanged()) );
connect(widget->model()->routingManager()->alternativeRoutesModel(), SIGNAL(currentRouteChanged(const GeoDataDocument*)),
this, SLOT(setViewportChanged()) );
connect(widget->model()->routingManager()->alternativeRoutesModel(), SIGNAL(currentRouteChanged(const GeoDataDocument*)),
this, SIGNAL(repaintNeeded()) );
connect( widget->model()->routingManager()->alternativeRoutesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(showAlternativeRoutes()) );
}
RoutingLayer::~RoutingLayer()
{
delete d;
}
QStringList RoutingLayer::renderPosition() const
{
return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE"));
}
qreal RoutingLayer::zValue() const
{
return 1.0;
}
bool RoutingLayer::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos, GeoSceneLayer *layer )
{
Q_UNUSED( viewport )
Q_UNUSED( renderPos )
Q_UNUSED( layer )
painter->save();
if ( d->m_placemarkModel) {
d->renderPlacemarks( painter );
}
if ( d->m_alternativeRoutesModel ) {
d->renderAlternativeRoutes( painter );
}
d->renderRoute( painter );
if ( d->m_routeRequest) {
d->renderRequest( painter );
}
d->renderAnnotations( painter );
painter->restore();
if ( d->m_viewportChanged && d->m_viewContext == Still ) {
d->m_viewportChanged = false;
}
return true;
}
RenderState RoutingLayer::renderState() const
{
return RenderState(QStringLiteral("Routing"), d->m_marbleWidget->model()->routingManager()->state() == RoutingManager::Downloading ? WaitingForUpdate : Complete);
}
bool RoutingLayer::eventFilter( QObject *obj, QEvent *event )
{
Q_UNUSED( obj )
if ( !d->m_isInteractive ) {
return false;
}
if ( event->type() == QEvent::MouseButtonPress ) {
QMouseEvent *e = static_cast<QMouseEvent*>( event );
return d->handleMouseButtonPress( e );
}
if ( event->type() == QEvent::MouseButtonRelease ) {
QMouseEvent *e = static_cast<QMouseEvent*>( event );
return d->handleMouseButtonRelease( e );
}
if ( event->type() == QEvent::MouseMove ) {
QMouseEvent *e = static_cast<QMouseEvent*>( event );
return d->handleMouseMove( e );
}
return false;
}
void RoutingLayer::setPlacemarkModel ( MarblePlacemarkModel *model )
{
d->m_placemarkModel = model;
setViewportChanged();
}
void RoutingLayer::synchronizeWith( QItemSelectionModel *selection )
{
d->m_selectionModel = selection;
}
void RoutingLayer::removeViaPoint()
{
if ( d->m_activeMenuIndex >= 0 ) {
d->m_routeRequest->remove( d->m_activeMenuIndex );
d->m_activeMenuIndex = -1;
emit repaintNeeded();
d->m_marbleWidget->model()->routingManager()->retrieveRoute();
}
}
void RoutingLayer::showAlternativeRoutes()
{
setViewportChanged();
emit repaintNeeded();
}
void RoutingLayer::exportRoute()
{
QString fileName = QFileDialog::getSaveFileName( d->m_marbleWidget,
tr( "Export Route" ), // krazy:exclude=qclasses
QDir::homePath(),
tr( "GPX and KML files (*.gpx *.kml)" ) );
if ( !fileName.isEmpty() ) {
if ( fileName.endsWith( QLatin1String( ".gpx" ), Qt::CaseInsensitive ) ) {
QFile gpx( fileName );
if ( gpx.open( QFile::WriteOnly) ) {
d->m_routingModel->exportGpx( &gpx );
gpx.close();
}
} else {
d->m_marbleWidget->model()->routingManager()->saveRoute( fileName );
}
}
}
void RoutingLayer::updateRouteState()
{
setViewportChanged();
emit repaintNeeded();
}
void RoutingLayer::setViewportChanged()
{
d->m_viewportChanged = true;
d->m_routeRegion = QRegion();
d->m_instructionRegions.clear();
d->m_alternativeRouteRegions.clear();
}
void RoutingLayer::setViewContext( ViewContext viewContext )
{
d->m_viewContext = viewContext;
}
void RoutingLayer::setInteractive( bool interactive )
{
d->m_isInteractive = interactive;
}
bool RoutingLayer::isInteractive() const
{
return d->m_isInteractive;
}
QString RoutingLayer::runtimeTrace() const
{
return QStringLiteral("Routing Layer");
}
} // namespace Marble
#include "moc_RoutingLayer.cpp"
diff --git a/src/lib/marble/routing/RoutingLayer.h b/src/lib/marble/routing/RoutingLayer.h
index 0f6794f67..75188750c 100644
--- a/src/lib/marble/routing/RoutingLayer.h
+++ b/src/lib/marble/routing/RoutingLayer.h
@@ -1,132 +1,132 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTINGLAYER_H
#define MARBLE_ROUTINGLAYER_H
#include "LayerInterface.h"
#include "MarbleGlobal.h"
#include <QObject>
#include <QRect>
class QItemSelectionModel;
class QModelIndex;
namespace Marble
{
class MarbleWidget;
class MarblePlacemarkModel;
class RoutingLayerPrivate;
/**
* @brief A paint layer that serves as a view on a route model
*/
class RoutingLayer: public QObject, public LayerInterface
{
Q_OBJECT
public:
/**
* @brief Constructor
* @param widget The marble widget used for geopos <-> screenpos transformations
* and repainting of (small) areas. Must not be null
* @param parent Optional parent widget
*/
- explicit RoutingLayer( MarbleWidget *widget, QWidget *parent = 0 );
+ explicit RoutingLayer( MarbleWidget *widget, QWidget *parent = nullptr );
/** Destructor */
~RoutingLayer() override;
/** Reimplemented from LayerInterface. We'll hover above the surface */
QStringList renderPosition() const override;
/** Reimplemented from LayerInterface. */
qreal zValue() const override;
/** Reimplemented from LayerInterface. Paints route items and placemarks */
bool render( GeoPainter *painter, ViewportParams *viewport,
- const QString &renderPos = "NONE", GeoSceneLayer *layer = 0 ) override;
+ const QString &renderPos = "NONE", GeoSceneLayer *layer = nullptr ) override;
RenderState renderState() const override;
/**
* Set the proxy model another QAbstractItemView uses that should share
* its selection model with us. Needed because this class uses an unfiltered
* model which has different indices than a filtered one.
*/
void synchronizeWith( QItemSelectionModel *selection );
/**
* Set the placemark model to use. Implicitly removes the routing model.
*/
void setPlacemarkModel ( MarblePlacemarkModel *model );
/**
* Set the view context to determine whether the map is used interactively
*/
void setViewContext( ViewContext viewContext );
/**
* Determine whether the route can be edited by the user (via points added,
* route cleared)
*/
void setInteractive( bool interactive );
/**
* Returns whether the route is interactive (true by default if not changed
* by setInteractive)
*/
bool isInteractive() const;
QString runtimeTrace() const override;
Q_SIGNALS:
/**
* A placemark was selected (clicked) by the user. The index belongs to
* the model set via setModel
*/
void placemarkSelected( const QModelIndex &index );
void repaintNeeded( const QRect &rect = QRect() );
public:
/** Overriding QWidget, used to make the layer interactive */
bool eventFilter( QObject *obj, QEvent *event ) override;
private Q_SLOTS:
void removeViaPoint();
void showAlternativeRoutes();
/** Export route to a file */
void exportRoute();
/**
* Paint a dashed route when downloading a new route, a solid one otherwise.
*/
void updateRouteState();
/**
* The viewport has changed, recalculate positions accordingly
*/
void setViewportChanged();
private:
RoutingLayerPrivate *const d;
friend class RoutingLayerPrivate;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/routing/RoutingManager.cpp b/src/lib/marble/routing/RoutingManager.cpp
index 192c2153d..03d0146c9 100644
--- a/src/lib/marble/routing/RoutingManager.cpp
+++ b/src/lib/marble/routing/RoutingManager.cpp
@@ -1,652 +1,652 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "RoutingManager.h"
#include "AlternativeRoutesModel.h"
#include "MarbleModel.h"
#include "RouteRequest.h"
#include "RoutingModel.h"
#include "RoutingProfilesModel.h"
#include "RoutingRunnerPlugin.h"
#include "GeoWriter.h"
#include "GeoDataDocument.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "GeoDataFolder.h"
#include "GeoDataParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTreeModel.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "PositionTracking.h"
#include "PluginManager.h"
#include "PositionProviderPlugin.h"
#include "Route.h"
#include "RoutingRunnerManager.h"
#include <KmlElementDictionary.h>
#include <QFile>
#include <QMessageBox>
#include <QCheckBox>
#include <QMutexLocker>
namespace Marble
{
class RoutingManagerPrivate
{
public:
RoutingManager* q;
RouteRequest m_routeRequest;
RoutingModel m_routingModel;
RoutingProfilesModel m_profilesModel;
RoutingManager::State m_state;
const PluginManager *const m_pluginManager;
GeoDataTreeModel *const m_treeModel;
PositionTracking *const m_positionTracking;
AlternativeRoutesModel m_alternativeRoutesModel;
RoutingRunnerManager m_runnerManager;
bool m_haveRoute;
bool m_guidanceModeEnabled;
QMutex m_fileMutex;
bool m_shutdownPositionTracking;
bool m_guidanceModeWarning;
QString m_lastOpenPath;
QString m_lastSavePath;
QColor m_routeColorStandard;
QColor m_routeColorHighlighted;
QColor m_routeColorAlternative;
RoutingManagerPrivate(MarbleModel *marbleModel, RoutingManager *manager);
static GeoDataFolder *createFolderFromRequest(const RouteRequest &request);
static QString stateFile( const QString &name = QString( "route.kml" ) );
void saveRoute( const QString &filename );
void loadRoute( const QString &filename );
void addRoute( GeoDataDocument* route );
void routingFinished();
void setCurrentRoute(const GeoDataDocument *route);
void recalculateRoute( bool deviated );
static void importPlacemark( RouteSegment &outline, QVector<RouteSegment> &segments, const GeoDataPlacemark *placemark );
};
RoutingManagerPrivate::RoutingManagerPrivate(MarbleModel *model, RoutingManager *manager) :
q( manager ),
m_routeRequest( manager ),
m_routingModel(&m_routeRequest, model->positionTracking(), manager),
m_profilesModel( model->pluginManager() ),
m_state( RoutingManager::Retrieved ),
m_pluginManager( model->pluginManager() ),
m_treeModel( model->treeModel() ),
m_positionTracking( model->positionTracking() ),
m_alternativeRoutesModel(manager),
m_runnerManager(model, manager),
m_haveRoute( false ),
m_guidanceModeEnabled( false ),
m_shutdownPositionTracking( false ),
m_guidanceModeWarning( true ),
m_routeColorStandard( Oxygen::skyBlue4 ),
m_routeColorHighlighted( Oxygen::skyBlue1 ),
m_routeColorAlternative( Oxygen::aluminumGray4 )
{
m_routeColorStandard.setAlpha( 200 );
m_routeColorHighlighted.setAlpha( 200 );
m_routeColorAlternative.setAlpha( 200 );
}
GeoDataFolder *RoutingManagerPrivate::createFolderFromRequest(const RouteRequest &request)
{
GeoDataFolder* result = new GeoDataFolder;
result->setName(QStringLiteral("Route Request"));
for (int i = 0; i < request.size(); ++i) {
GeoDataPlacemark *placemark = new GeoDataPlacemark(request[i]);
result->append( placemark );
}
return result;
}
QString RoutingManagerPrivate::stateFile( const QString &name)
{
QString const subdir = "routing";
QDir dir( MarbleDirs::localPath() );
if ( !dir.exists( subdir ) ) {
if ( !dir.mkdir( subdir ) ) {
mDebug() << "Unable to create dir " << dir.absoluteFilePath( subdir );
return dir.absolutePath();
}
}
if ( !dir.cd( subdir ) ) {
mDebug() << "Cannot change into " << dir.absoluteFilePath( subdir );
}
return dir.absoluteFilePath( name );
}
void RoutingManagerPrivate::saveRoute(const QString &filename)
{
GeoWriter writer;
writer.setDocumentType( kml::kmlTag_nameSpaceOgc22 );
QMutexLocker locker( &m_fileMutex );
QFile file( filename );
if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
{
mDebug() << "Cannot write to " << file.fileName();
return;
}
GeoDataDocument container;
container.setName(QStringLiteral("Route"));
GeoDataFolder *request = createFolderFromRequest(m_routeRequest);
if ( request ) {
container.append( request );
}
const GeoDataDocument *route = m_alternativeRoutesModel.currentRoute();
if ( route ) {
container.append( new GeoDataDocument( *route ) );
}
if ( !writer.write( &file, &container ) ) {
mDebug() << "Can not write route state to " << file.fileName();
}
file.close();
}
void RoutingManagerPrivate::loadRoute(const QString &filename)
{
QFile file( filename );
if ( !file.open( QIODevice::ReadOnly ) ) {
mDebug() << "Can not read route from " << file.fileName();
return;
}
GeoDataParser parser( GeoData_KML );
if ( !parser.read( &file ) ) {
mDebug() << "Could not parse file: " << parser.errorString();
return;
}
GeoDocument *doc = parser.releaseDocument();
file.close();
bool loaded = false;
GeoDataDocument* container = dynamic_cast<GeoDataDocument*>( doc );
if (container && !container->isEmpty()) {
GeoDataFolder* viaPoints = dynamic_cast<GeoDataFolder*>( &container->first() );
if ( viaPoints ) {
loaded = true;
QVector<GeoDataPlacemark*> placemarks = viaPoints->placemarkList();
for( int i=0; i<placemarks.size(); ++i ) {
if ( i < m_routeRequest.size() ) {
m_routeRequest[i] = *placemarks[i];
} else {
m_routeRequest.append( *placemarks[i] );
}
}
// clear unneeded via points
const int viaPoints_needed = placemarks.size();
for ( int i = m_routeRequest.size(); i > viaPoints_needed; --i ) {
m_routeRequest.remove( viaPoints_needed );
}
} else {
mDebug() << "Expected a GeoDataDocument with at least one child, didn't get one though";
}
}
if ( container && container->size() == 2 ) {
GeoDataDocument* route = dynamic_cast<GeoDataDocument*>(&container->last());
if ( route ) {
loaded = true;
m_alternativeRoutesModel.clear();
m_alternativeRoutesModel.addRoute( new GeoDataDocument(*route), AlternativeRoutesModel::Instant );
m_alternativeRoutesModel.setCurrentRoute( 0 );
m_state = RoutingManager::Retrieved;
emit q->stateChanged( m_state );
emit q->routeRetrieved( route );
} else {
mDebug() << "Expected a GeoDataDocument child, didn't get one though";
}
}
if (loaded) {
delete doc; // == container
} else {
mDebug() << "File " << filename << " is not a valid Marble route .kml file";
if ( container ) {
m_treeModel->addDocument( container );
}
}
}
RoutingManager::RoutingManager(MarbleModel *marbleModel, QObject *parent) :
QObject(parent),
d(new RoutingManagerPrivate(marbleModel, this))
{
connect( &d->m_runnerManager, SIGNAL(routeRetrieved(GeoDataDocument*)),
this, SLOT(addRoute(GeoDataDocument*)) );
connect( &d->m_runnerManager, SIGNAL(routingFinished()),
this, SLOT(routingFinished()) );
connect(&d->m_alternativeRoutesModel, SIGNAL(currentRouteChanged(const GeoDataDocument*)),
this, SLOT(setCurrentRoute(const GeoDataDocument*)));
connect( &d->m_routingModel, SIGNAL(deviatedFromRoute(bool)),
this, SLOT(recalculateRoute(bool)) );
}
RoutingManager::~RoutingManager()
{
delete d;
}
RoutingProfilesModel *RoutingManager::profilesModel()
{
return &d->m_profilesModel;
}
RoutingModel *RoutingManager::routingModel()
{
return &d->m_routingModel;
}
const RoutingModel *RoutingManager::routingModel() const
{
return &d->m_routingModel;
}
RouteRequest* RoutingManager::routeRequest()
{
return &d->m_routeRequest;
}
RoutingManager::State RoutingManager::state() const
{
return d->m_state;
}
void RoutingManager::retrieveRoute()
{
d->m_haveRoute = false;
int realSize = 0;
for ( int i = 0; i < d->m_routeRequest.size(); ++i ) {
// Sort out dummy targets
if ( d->m_routeRequest.at( i ).isValid() ) {
++realSize;
}
}
d->m_alternativeRoutesModel.newRequest( &d->m_routeRequest );
if ( realSize > 1 ) {
d->m_state = RoutingManager::Downloading;
d->m_runnerManager.retrieveRoute( &d->m_routeRequest );
} else {
d->m_routingModel.clear();
d->m_state = RoutingManager::Retrieved;
}
emit stateChanged( d->m_state );
}
void RoutingManagerPrivate::addRoute( GeoDataDocument* route )
{
if ( route ) {
m_alternativeRoutesModel.addRoute( route );
}
if ( !m_haveRoute ) {
- m_haveRoute = route != 0;
+ m_haveRoute = route != nullptr;
}
emit q->routeRetrieved( route );
}
void RoutingManagerPrivate::routingFinished()
{
m_state = RoutingManager::Retrieved;
emit q->stateChanged( m_state );
}
void RoutingManagerPrivate::setCurrentRoute(const GeoDataDocument *document)
{
QVector<RouteSegment> segments;
RouteSegment outline;
if (document != nullptr) {
const auto folders = document->folderList();
for (const auto folder : folders) {
for (const auto placemark : folder->placemarkList()) {
importPlacemark(outline, segments, placemark);
}
}
for (const auto placemark : document->placemarkList()) {
importPlacemark(outline, segments, placemark);
}
}
if ( segments.isEmpty() ) {
segments << outline;
}
// Map via points onto segments
if ( m_routeRequest.size() > 1 && segments.size() > 1 ) {
int index = 0;
for ( int j = 0; j < m_routeRequest.size(); ++j ) {
QPair<int, qreal> minimum( -1, -1.0 );
int viaIndex = -1;
for ( int i = index; i < segments.size(); ++i ) {
const RouteSegment &segment = segments[i];
GeoDataCoordinates closest;
const qreal distance = segment.distanceTo( m_routeRequest.at( j ), closest, closest );
if ( minimum.first < 0 || distance < minimum.second ) {
minimum.first = i;
minimum.second = distance;
viaIndex = j;
}
}
if ( minimum.first >= 0 ) {
index = minimum.first;
Maneuver viaPoint = segments[ minimum.first ].maneuver();
viaPoint.setWaypoint( m_routeRequest.at( viaIndex ), viaIndex );
segments[ minimum.first ].setManeuver( viaPoint );
}
}
}
Route route;
if ( segments.size() > 0 ) {
for( const RouteSegment &segment: segments ) {
route.addRouteSegment( segment );
}
}
m_routingModel.setRoute( route );
}
void RoutingManagerPrivate::importPlacemark( RouteSegment &outline, QVector<RouteSegment> &segments, const GeoDataPlacemark *placemark )
{
const GeoDataGeometry* geometry = placemark->geometry();
const GeoDataLineString* lineString = dynamic_cast<const GeoDataLineString*>( geometry );
QStringList blacklist = QStringList() << "" << "Route" << "Tessellated";
RouteSegment segment;
bool isOutline = true;
if ( !blacklist.contains( placemark->name() ) ) {
if( lineString ) {
Maneuver maneuver;
maneuver.setInstructionText( placemark->name() );
maneuver.setPosition( lineString->at( 0 ) );
if (placemark->extendedData().contains(QStringLiteral("turnType"))) {
QVariant turnType = placemark->extendedData().value(QStringLiteral("turnType")).value();
// The enum value is converted to/from an int in the QVariant
// because only a limited set of data types can be serialized with QVariant's
// toString() method (which is used to serialize <ExtendedData>/<Data> values)
maneuver.setDirection( Maneuver::Direction( turnType.toInt() ) );
}
if (placemark->extendedData().contains(QStringLiteral("roadName"))) {
QVariant roadName = placemark->extendedData().value(QStringLiteral("roadName")).value();
maneuver.setRoadName( roadName.toString() );
}
segment.setManeuver( maneuver );
isOutline = false;
}
}
if ( lineString ) {
segment.setPath( *lineString );
if ( isOutline ) {
outline = segment;
} else {
segments.push_back( segment );
}
}
}
AlternativeRoutesModel* RoutingManager::alternativeRoutesModel()
{
return &d->m_alternativeRoutesModel;
}
void RoutingManager::writeSettings() const
{
d->saveRoute( d->stateFile() );
}
void RoutingManager::saveRoute( const QString &filename ) const
{
d->saveRoute( filename );
}
void RoutingManager::loadRoute( const QString &filename )
{
d->loadRoute( filename );
}
RoutingProfile RoutingManager::defaultProfile( RoutingProfile::TransportType transportType ) const
{
RoutingProfile profile;
RoutingProfilesModel::ProfileTemplate tpl = RoutingProfilesModel::CarFastestTemplate;
switch ( transportType ) {
case RoutingProfile::Motorcar:
tpl = RoutingProfilesModel::CarFastestTemplate;
profile.setName(QStringLiteral("Motorcar"));
profile.setTransportType( RoutingProfile::Motorcar );
break;
case RoutingProfile::Bicycle:
tpl = RoutingProfilesModel::BicycleTemplate;
profile.setName(QStringLiteral("Bicycle"));
profile.setTransportType( RoutingProfile::Bicycle );
break;
case RoutingProfile::Pedestrian:
tpl = RoutingProfilesModel::PedestrianTemplate;
profile.setName(QStringLiteral("Pedestrian"));
profile.setTransportType( RoutingProfile::Pedestrian );
break;
}
for( RoutingRunnerPlugin* plugin: d->m_pluginManager->routingRunnerPlugins() ) {
if ( plugin->supportsTemplate( tpl ) ) {
profile.pluginSettings()[plugin->nameId()] = plugin->templateSettings( tpl );
}
}
return profile;
}
void RoutingManager::readSettings()
{
d->loadRoute( d->stateFile() );
}
void RoutingManager::setGuidanceModeEnabled( bool enabled )
{
if ( d->m_guidanceModeEnabled == enabled ) {
return;
}
d->m_guidanceModeEnabled = enabled;
if ( enabled ) {
d->saveRoute( d->stateFile( "guidance.kml" ) );
if ( d->m_guidanceModeWarning ) {
QString text = QLatin1String("<p>") + tr("Caution: Driving instructions may be incomplete or wrong.") +
QLatin1Char(' ') + tr("Road construction, weather and other unforeseen variables can result in the suggested route not to be the most expedient or safest route to your destination.") +
QLatin1Char(' ') + tr("Please use common sense while navigating.") + QLatin1String("</p>") +
QLatin1String("<p>") + tr("The Marble development team wishes you a pleasant and safe journey.") + QLatin1String("</p>");
QPointer<QMessageBox> messageBox = new QMessageBox(QMessageBox::Information, tr("Guidance Mode"), text, QMessageBox::Ok);
QCheckBox *showAgain = new QCheckBox( tr( "Show again" ) );
showAgain->setChecked( true );
showAgain->blockSignals( true ); // otherwise it'd close the dialog
messageBox->addButton( showAgain, QMessageBox::ActionRole );
const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
messageBox->resize( 380, smallScreen ? 400 : 240 );
messageBox->exec();
if ( !messageBox.isNull() ) {
d->m_guidanceModeWarning = showAgain->isChecked();
}
delete messageBox;
}
} else {
d->loadRoute( d->stateFile( "guidance.kml" ) );
}
PositionProviderPlugin* positionProvider = d->m_positionTracking->positionProviderPlugin();
if ( !positionProvider && enabled ) {
QList<const PositionProviderPlugin*> plugins = d->m_pluginManager->positionProviderPlugins();
if ( plugins.size() > 0 ) {
positionProvider = plugins.first()->newInstance();
}
d->m_positionTracking->setPositionProviderPlugin( positionProvider );
d->m_shutdownPositionTracking = true;
} else if ( positionProvider && !enabled && d->m_shutdownPositionTracking ) {
d->m_shutdownPositionTracking = false;
- d->m_positionTracking->setPositionProviderPlugin( 0 );
+ d->m_positionTracking->setPositionProviderPlugin( nullptr );
}
emit guidanceModeEnabledChanged( d->m_guidanceModeEnabled );
}
void RoutingManagerPrivate::recalculateRoute( bool deviated )
{
if ( m_guidanceModeEnabled && deviated ) {
for ( int i=m_routeRequest.size()-3; i>=0; --i ) {
if ( m_routeRequest.visited( i ) ) {
m_routeRequest.remove( i );
}
}
if ( m_routeRequest.size() == 2 && m_routeRequest.visited( 0 ) && !m_routeRequest.visited( 1 ) ) {
m_routeRequest.setPosition( 0, m_positionTracking->currentLocation(), QObject::tr( "Current Location" ) );
q->retrieveRoute();
} else if ( m_routeRequest.size() != 0 && !m_routeRequest.visited( m_routeRequest.size()-1 ) ) {
m_routeRequest.insert( 0, m_positionTracking->currentLocation(), QObject::tr( "Current Location" ) );
q->retrieveRoute();
}
}
}
void RoutingManager::reverseRoute()
{
d->m_routeRequest.reverse();
retrieveRoute();
}
void RoutingManager::clearRoute()
{
d->m_routeRequest.clear();
retrieveRoute();
}
void RoutingManager::setShowGuidanceModeStartupWarning( bool show )
{
d->m_guidanceModeWarning = show;
}
bool RoutingManager::showGuidanceModeStartupWarning() const
{
return d->m_guidanceModeWarning;
}
void RoutingManager::setLastOpenPath( const QString &path )
{
d->m_lastOpenPath = path;
}
QString RoutingManager::lastOpenPath() const
{
return d->m_lastOpenPath;
}
void RoutingManager::setLastSavePath( const QString &path )
{
d->m_lastSavePath = path;
}
QString RoutingManager::lastSavePath() const
{
return d->m_lastSavePath;
}
void RoutingManager::setRouteColorStandard( const QColor& color )
{
d->m_routeColorStandard = color;
}
QColor RoutingManager::routeColorStandard() const
{
return d->m_routeColorStandard;
}
void RoutingManager::setRouteColorHighlighted( const QColor& color )
{
d->m_routeColorHighlighted = color;
}
QColor RoutingManager::routeColorHighlighted() const
{
return d->m_routeColorHighlighted;
}
void RoutingManager::setRouteColorAlternative( const QColor& color )
{
d->m_routeColorAlternative = color;
}
QColor RoutingManager::routeColorAlternative() const
{
return d->m_routeColorAlternative;
}
bool RoutingManager::guidanceModeEnabled() const
{
return d->m_guidanceModeEnabled;
}
} // namespace Marble
#include "moc_RoutingManager.cpp"
diff --git a/src/lib/marble/routing/RoutingManager.h b/src/lib/marble/routing/RoutingManager.h
index ae2fd6233..4871b5449 100644
--- a/src/lib/marble/routing/RoutingManager.h
+++ b/src/lib/marble/routing/RoutingManager.h
@@ -1,212 +1,212 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTINGMANAGER_H
#define MARBLE_ROUTINGMANAGER_H
#include "marble_export.h"
#include "RoutingProfile.h"
namespace Marble
{
class RoutingManagerPrivate;
class RoutingModel;
class RouteRequest;
class MarbleModel;
class GeoDataDocument;
class AlternativeRoutesModel;
class RoutingProfilesModel;
/**
* Delegates data retrieval and model updates to the appropriate
* routing provider.
*/
class MARBLE_EXPORT RoutingManager : public QObject
{
Q_OBJECT
Q_PROPERTY( State state READ state NOTIFY stateChanged )
Q_PROPERTY( bool guidanceModeEnabled READ guidanceModeEnabled WRITE setGuidanceModeEnabled NOTIFY guidanceModeEnabledChanged )
public:
enum State {
Downloading, // A new route is downloaded in the background
Retrieved // No download in progress
};
/** Constructor */
- explicit RoutingManager( MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit RoutingManager( MarbleModel *marbleModel, QObject *parent = nullptr );
/** Destructor */
~RoutingManager() override;
/**
* Provides access to the model which contains all possible routing profiles
*/
RoutingProfilesModel *profilesModel();
/**
* Provides access to the routing model which contains a list
* of routing instructions describing steps to get from the
* source to the destination.
* @see retrieveDirections
*/
RoutingModel *routingModel();
const RoutingModel *routingModel() const;
/**
* Provides access to the model which contains a list of
* alternative routes
*/
AlternativeRoutesModel* alternativeRoutesModel();
/**
* Returns the current route request
*/
RouteRequest* routeRequest();
/**
* @brief Returns whether a route is being downloaded
* @return
*/
State state() const;
/**
* Saves the current route request and the current route to disk
*/
void writeSettings() const;
/**
* Restores a previously saved route request and route from disk, if any
*/
void readSettings();
/**
* Saves the current route to the file with the given filename. Existing files
* will be overwritten. The route is saved in kml format.
*/
void saveRoute( const QString &filename ) const;
/**
* Opens the given filename (kml format) and loads the route contained in it
*/
void loadRoute( const QString &filename );
/**
* Generates a routing profile with default settings for the given transport type
*/
RoutingProfile defaultProfile( RoutingProfile::TransportType transportType ) const;
/**
* Set whether a warning message should be shown to the user before
* starting guidance mode.
*/
void setShowGuidanceModeStartupWarning( bool show );
/**
* Returns true (default) if a warning is shown to the user when starting guidance
* mode.
*/
bool showGuidanceModeStartupWarning() const;
/**
* Set last directory the user opened a route from.
*/
void setLastOpenPath( const QString &path );
/**
* Return last directory the user opened a route from.
*/
QString lastOpenPath() const;
/**
* Set last directory the user saved a route to.
*/
void setLastSavePath( const QString &path );
/**
* Return last directory the user saved a route to.
*/
QString lastSavePath() const;
/**
* Set color for standard route rendering
*/
void setRouteColorStandard( const QColor& color );
/**
* Get color for standard route rendering
*/
QColor routeColorStandard() const;
/**
* Set color for highlighted route rendering
*/
void setRouteColorHighlighted( const QColor& color );
/**
* Get color for highlighted route rendering
*/
QColor routeColorHighlighted() const;
/**
* Set color for alternative route rendering
*/
void setRouteColorAlternative( const QColor& color );
/**
* Get color for alternative route rendering
*/
QColor routeColorAlternative() const;
bool guidanceModeEnabled() const;
public Q_SLOTS:
/** Reverse the previously requested route, i.e. swap start and destination (and via points, if any) */
void reverseRoute();
/** Retrieve a route suiting the routeRequest */
void retrieveRoute();
/** Clear all via points */
void clearRoute();
/** Toggle turn by turn navigation mode */
void setGuidanceModeEnabled( bool enabled );
Q_SIGNALS:
/**
* Directions and waypoints for the given route are being downloaded or have
* been retrieved -- newState tells which of both
*/
void stateChanged( RoutingManager::State newState );
void routeRetrieved( GeoDataDocument* route );
void guidanceModeEnabledChanged( bool enabled );
private:
Q_PRIVATE_SLOT( d, void addRoute( GeoDataDocument* route ) )
Q_PRIVATE_SLOT( d, void routingFinished() )
Q_PRIVATE_SLOT(d, void setCurrentRoute(const GeoDataDocument *route))
Q_PRIVATE_SLOT( d, void recalculateRoute( bool deviated ) )
private:
friend class RoutingManagerPrivate;
RoutingManagerPrivate *const d;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/routing/RoutingModel.h b/src/lib/marble/routing/RoutingModel.h
index f881cd8c6..995e99bd9 100644
--- a/src/lib/marble/routing/RoutingModel.h
+++ b/src/lib/marble/routing/RoutingModel.h
@@ -1,123 +1,123 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTINGMODEL_H
#define MARBLE_ROUTINGMODEL_H
#include "marble_export.h"
#include <QAbstractListModel>
class QIODevice;
/**
* A QAbstractItemModel that contains a list of routing instructions.
* Each item represents a routing step in the way from source to
* destination. Steps near the source come first, steps near the target
* last.
*/
namespace Marble
{
class RoutingModelPrivate;
class Route;
class RouteRequest;
class GeoDataCoordinates;
class PositionTracking;
class MARBLE_EXPORT RoutingModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY( bool deviatedFromRoute READ deviatedFromRoute NOTIFY deviatedFromRoute )
public:
enum RoutingModelRoles {
CoordinateRole = Qt::UserRole + 3,
TurnTypeIconRole,
LongitudeRole,
LatitudeRole
};
/** Constructor */
- explicit RoutingModel(RouteRequest *request, PositionTracking *positionTracking, QObject *parent = 0);
+ explicit RoutingModel(RouteRequest *request, PositionTracking *positionTracking, QObject *parent = nullptr);
/** Destructor */
~RoutingModel() override;
// Model querying
/** Overload of QAbstractListModel */
int rowCount ( const QModelIndex &parent = QModelIndex() ) const override;
/** Overload of QAbstractListModel */
QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
/** Overload of QAbstractListModel */
QVariant data ( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
/** Overload of QAbstractListModel */
QHash<int, QByteArray> roleNames() const override;
// Model data filling
/**
* Export waypoints and instructions in gpx format
*/
void exportGpx( QIODevice *device ) const;
/**
* Clear any data held in the model
*/
void clear();
/**
* Maps points from the provided route request to waypoints in the model
* according to their global minimal distance. Returns the right neighbor
* (next route request item along the waypoints) of the provided position.
* Provided route must not be null.
* @return -1 If the provided route is empty, the index of the right
* neighbor along the waypoints otherwise (result is a valid RouteRequest
* index in that case)
*/
int rightNeighbor( const GeoDataCoordinates &position, RouteRequest const *const route ) const;
/**
* returns whether the gps location is on route
*/
bool deviatedFromRoute() const;
const Route & route() const;
public Q_SLOTS:
/**
* Old data in the model is discarded and a model reset is done
*/
void setRoute( const Route &route );
void updatePosition( const GeoDataCoordinates&, qreal );
Q_SIGNALS:
/**
* emits a signal regarding information about total time( seconds ) and distance( metres ) remaining to reach destination
*/
void positionChanged();
void deviatedFromRoute( bool deviated );
/** A different route was loaded */
void currentRouteChanged();
private:
RoutingModelPrivate *const d;
};
} // namespace Marble
#endif
diff --git a/src/lib/marble/routing/RoutingProfileSettingsDialog.cpp b/src/lib/marble/routing/RoutingProfileSettingsDialog.cpp
index 378961286..bea6bba79 100644
--- a/src/lib/marble/routing/RoutingProfileSettingsDialog.cpp
+++ b/src/lib/marble/routing/RoutingProfileSettingsDialog.cpp
@@ -1,168 +1,168 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Niko Sams <niko.sams@gmail.com>
//
#include "RoutingProfileSettingsDialog.h"
#include <QStandardItemModel>
#include "MarbleGlobal.h"
#include "RoutingRunnerPlugin.h"
#include "MarbleDebug.h"
#include "RoutingProfilesModel.h"
#include "PluginManager.h"
#include "ui_RoutingProfileSettingsDialog.h"
namespace Marble {
RoutingProfileSettingsDialog::RoutingProfileSettingsDialog( const PluginManager *pluginManager, RoutingProfilesModel *profilesModel, QWidget* parent )
: QDialog( parent ),
- m_profilesModel ( profilesModel ), m_dialog( 0 ), m_dialogLayout( 0 )
+ m_profilesModel ( profilesModel ), m_dialog( nullptr ), m_dialogLayout( nullptr )
{
m_ui = new Ui_RoutingProfileSettingsDialog();
m_ui->setupUi( this );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( smallScreen ) {
setMinimumHeight( 480 );
m_ui->services->setMinimumWidth( 280 );
m_ui->buttonBox->hide();
}
QList<RoutingRunnerPlugin*> allPlugins = pluginManager->routingRunnerPlugins();
for( RoutingRunnerPlugin* plugin: allPlugins ) {
m_plugins << plugin;
RoutingRunnerPlugin::ConfigWidget* configWidget = plugin->configWidget();
if ( configWidget ) {
m_configWidgets.insert( plugin, configWidget );
m_ui->settingsStack->addWidget( configWidget );
}
}
m_servicesModel = new QStandardItemModel;
m_ui->services->setModel( m_servicesModel );
connect ( m_ui->services->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), SLOT(updateConfigWidget()), Qt::QueuedConnection );
connect ( m_servicesModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateConfigWidget()) );
connect ( m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()) );
connect ( m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()) );
connect( m_ui->configureButton, SIGNAL(clicked()), this, SLOT(openConfigDialog()) );
}
RoutingProfileSettingsDialog::~RoutingProfileSettingsDialog()
{
qDeleteAll( m_configWidgets );
delete m_ui;
}
void RoutingProfileSettingsDialog::updateConfigWidget( )
{
QModelIndex current = m_ui->services->selectionModel()->currentIndex();
if ( !current.isValid() ) {
m_ui->settingsStack->setEnabled( false );
return;
}
RoutingRunnerPlugin *plugin = m_plugins.at( current.row() );
QWidget* configWidget = m_configWidgets[plugin];
if ( configWidget ) {
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
m_ui->settingsStack->setCurrentWidget( smallScreen ? m_ui->configurePage : configWidget );
m_ui->descriptionLabel->setText( plugin->description() );
m_ui->statusLabel->setText( plugin->statusMessage() );
QStandardItem *item = m_servicesModel->invisibleRootItem()->child( current.row() );
m_ui->settingsStack->setEnabled( item->checkState() == Qt::Checked );
} else {
m_ui->settingsStack->setEnabled( false );
m_ui->noConfigDescriptionLabel->setText( plugin->description() );
m_ui->noConfigStatusLabel->setText( plugin->statusMessage() );
m_ui->settingsStack->setCurrentWidget( m_ui->noConfigAvailablePage );
}
}
void RoutingProfileSettingsDialog::editProfile( int profileIndex )
{
QList<RoutingProfile> profiles = m_profilesModel->profiles();
m_ui->name->setText( profiles.at( profileIndex ).name() );
m_servicesModel->clear();
for( RoutingRunnerPlugin *plugin: m_plugins ) {
QStandardItem *item = new QStandardItem( plugin->guiString() );
item->setCheckable( true );
if ( profiles[ profileIndex ].pluginSettings().contains( plugin->nameId() ) ) {
item->setCheckState( Qt::Checked );
QHash<QString, QVariant> settings = profiles[ profileIndex ].pluginSettings()[ plugin->nameId() ];
mDebug() << settings;
if ( m_configWidgets[plugin] ) {
m_configWidgets[plugin]->loadSettings( settings );
}
}
m_servicesModel->invisibleRootItem()->appendRow( item );
}
m_ui->settingsStack->setCurrentWidget( m_ui->selectServicePage );
m_ui->settingsStack->setEnabled( false );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
// Small screen profile (like maemo 5) does not have the "buttonBox"
if ( exec() != QDialog::Accepted && !smallScreen ) {
return;
}
m_profilesModel->setProfileName( profileIndex, m_ui->name->text() );
QHash< QString, QHash< QString, QVariant > > pluginSettings;
for ( int i=0; i < m_servicesModel->invisibleRootItem()->rowCount(); ++i) {
QStandardItem *item = m_servicesModel->invisibleRootItem()->child( i );
if ( item->checkState() == Qt::Checked ) {
QHash<QString, QVariant> settings;
if ( m_configWidgets[m_plugins[ i ]] ) {
settings = m_configWidgets[m_plugins[ i ]]->settings();
}
mDebug() << i << m_plugins[ i ]->nameId() << settings;
pluginSettings.insert( m_plugins[ i ]->nameId(), settings );
} else {
pluginSettings.remove( m_plugins[ i ]->nameId() );
}
}
m_profilesModel->setProfilePluginSettings( profileIndex, pluginSettings );
}
void RoutingProfileSettingsDialog::openConfigDialog()
{
QModelIndex current = m_ui->services->selectionModel()->currentIndex();
if ( current.isValid() ) {
RoutingRunnerPlugin *plugin = m_plugins.at( current.row() );
if ( !m_dialog ) {
m_dialog = new QDialog( this );
m_dialogLayout = new QHBoxLayout();
m_dialogLayout->addWidget( m_configWidgets[plugin] );
m_dialog->setLayout( m_dialogLayout );
m_dialog->setMinimumHeight( 480 );
} else {
m_dialogLayout->insertWidget( 0, m_configWidgets[plugin] );
}
m_configWidgets[plugin]->show();
m_dialog->setWindowTitle( plugin->guiString() );
m_dialog->exec();
m_configWidgets[plugin]->hide();
m_dialogLayout->removeWidget( m_configWidgets[plugin] );
}
}
}
#include "moc_RoutingProfileSettingsDialog.cpp"
diff --git a/src/lib/marble/routing/RoutingProfileSettingsDialog.h b/src/lib/marble/routing/RoutingProfileSettingsDialog.h
index 4a3bd2591..a160c5e3a 100644
--- a/src/lib/marble/routing/RoutingProfileSettingsDialog.h
+++ b/src/lib/marble/routing/RoutingProfileSettingsDialog.h
@@ -1,57 +1,57 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Niko Sams <niko.sams@gmail.com>
//
#ifndef MARBLE_ROUTINGPROFILESETTINGSDIALOG_H
#define MARBLE_ROUTINGPROFILESETTINGSDIALOG_H
#include <QDialog>
#include "RoutingRunnerPlugin.h"
class QStandardItemModel;
class QHBoxLayout;
class Ui_RoutingProfileSettingsDialog;
namespace Marble {
class PluginManager;
class RoutingProfilesModel;
class RoutingProfileSettingsDialog : public QDialog
{
Q_OBJECT
public:
- RoutingProfileSettingsDialog( const PluginManager *pluginManager, RoutingProfilesModel *profilesModel, QWidget *parent = 0 );
+ RoutingProfileSettingsDialog( const PluginManager *pluginManager, RoutingProfilesModel *profilesModel, QWidget *parent = nullptr );
~RoutingProfileSettingsDialog() override;
void editProfile( int profileIndex );
private Q_SLOTS:
void updateConfigWidget();
void openConfigDialog();
private:
RoutingProfilesModel *m_profilesModel;
QList<RoutingRunnerPlugin*> m_plugins;
QHash<RoutingRunnerPlugin*, RoutingRunnerPlugin::ConfigWidget*> m_configWidgets;
Ui_RoutingProfileSettingsDialog *m_ui;
QStandardItemModel *m_servicesModel;
QDialog* m_dialog;
QHBoxLayout* m_dialogLayout;
};
}
#endif
diff --git a/src/lib/marble/routing/RoutingProfilesModel.h b/src/lib/marble/routing/RoutingProfilesModel.h
index 6f98fd244..850ad343f 100644
--- a/src/lib/marble/routing/RoutingProfilesModel.h
+++ b/src/lib/marble/routing/RoutingProfilesModel.h
@@ -1,64 +1,64 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Niko Sams <niko.sams@gmail.com>
//
#ifndef MARBLE_ROUTINGPROFILESMODEL_H
#define MARBLE_ROUTINGPROFILESMODEL_H
#include "marble_export.h"
#include "RoutingProfile.h"
#include <QAbstractListModel>
namespace Marble {
class PluginManager;
class MARBLE_EXPORT RoutingProfilesModel : public QAbstractListModel
{
Q_OBJECT
public:
- explicit RoutingProfilesModel( const PluginManager *pluginManager, QObject *parent = 0 );
+ explicit RoutingProfilesModel( const PluginManager *pluginManager, QObject *parent = nullptr );
QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override;
int rowCount( const QModelIndex& parent = QModelIndex() ) const override;
bool removeRows( int row, int count, const QModelIndex& parent = QModelIndex() ) override;
enum ProfileTemplate {
CarFastestTemplate,
CarShortestTemplate,
CarEcologicalTemplate,
BicycleTemplate,
PedestrianTemplate,
LastTemplate
};
void setProfiles( const QList<RoutingProfile> &profiles );
QList<RoutingProfile> profiles() const;
void loadDefaultProfiles();
void addProfile( const QString &name );
bool moveUp( int row );
bool moveDown( int row );
bool setProfileName( int row, const QString &name );
bool setProfilePluginSettings( int row, const QHash<QString, QHash<QString, QVariant> > &pluginSettings );
private:
QList<RoutingProfile> m_profiles;
const PluginManager* m_pluginManager;
};
}
#endif // MARBLE_ROUTINGPROFILESMODEL_H
diff --git a/src/lib/marble/routing/RoutingProfilesWidget.cpp b/src/lib/marble/routing/RoutingProfilesWidget.cpp
index f70417055..fd551a59a 100644
--- a/src/lib/marble/routing/RoutingProfilesWidget.cpp
+++ b/src/lib/marble/routing/RoutingProfilesWidget.cpp
@@ -1,137 +1,137 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Niko Sams <niko.sams@gmail.com>
// Copyright 2011-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "RoutingProfilesWidget.h"
#include "ui_RoutingSettingsWidget.h"
#include "MarbleWidget.h"
#include <QStandardItemModel>
#include "MarbleModel.h"
#include "PluginManager.h"
#include "RoutingRunnerPlugin.h"
#include "MarbleDebug.h"
#include "RoutingProfilesModel.h"
#include "RoutingManager.h"
#include "RoutingProfileSettingsDialog.h"
namespace Marble
{
class Q_DECL_HIDDEN RoutingProfilesWidget::Private
{
public:
Private( MarbleModel *marbleModel, RoutingProfilesWidget *parent );
void add();
void configure();
void remove();
void moveUp();
void moveDown();
void updateButtons();
RoutingProfilesWidget *const q;
const PluginManager *const m_pluginManager;
RoutingProfilesModel *const m_profilesModel;
Ui_RoutingSettingsWidget m_ui;
};
RoutingProfilesWidget::Private::Private( MarbleModel *marbleModel, RoutingProfilesWidget *parent ) :
q( parent ),
m_pluginManager( marbleModel->pluginManager() ),
m_profilesModel( marbleModel->routingManager()->profilesModel() )
{
}
RoutingProfilesWidget::RoutingProfilesWidget( MarbleModel *marbleModel )
- : QWidget( 0 ),
+ : QWidget( nullptr ),
d( new Private( marbleModel, this ) )
{
d->m_ui.setupUi( this );
d->m_ui.profilesList->setModel( d->m_profilesModel );
connect( d->m_ui.addButton, SIGNAL(clicked(bool)), SLOT(add()) );
connect( d->m_ui.removeButton, SIGNAL(clicked(bool)), SLOT(remove()) );
connect( d->m_ui.configureButton, SIGNAL(clicked(bool)), SLOT(configure()) );
connect( d->m_ui.moveUpButton, SIGNAL(clicked(bool)), SLOT(moveUp()) );
connect( d->m_ui.moveDownButton, SIGNAL(clicked(bool)), SLOT(moveDown()) );
connect( d->m_ui.profilesList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), SLOT(updateButtons()), Qt::QueuedConnection );
connect( d->m_ui.profilesList, SIGNAL(doubleClicked(QModelIndex)), SLOT(configure()) );
connect( d->m_profilesModel, SIGNAL(layoutChanged()), SLOT(updateButtons()) );
}
RoutingProfilesWidget::~RoutingProfilesWidget()
{
delete d;
}
void RoutingProfilesWidget::Private::add()
{
m_profilesModel->addProfile( tr( "New Profile" ) );
int profileIndex = m_profilesModel->rowCount() - 1;
m_ui.profilesList->selectionModel()->select( m_profilesModel->index( profileIndex, 0 ), QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent );
RoutingProfileSettingsDialog dialog( m_pluginManager, m_profilesModel, q );
dialog.editProfile( profileIndex );
}
void RoutingProfilesWidget::Private::remove()
{
if ( m_ui.profilesList->selectionModel()->selectedRows().isEmpty() ) {
return;
}
m_profilesModel->removeRows( m_ui.profilesList->selectionModel()->selectedRows().first().row(), 1 );
}
void RoutingProfilesWidget::Private::configure()
{
if ( m_ui.profilesList->selectionModel()->selectedRows().isEmpty() ) {
return;
}
int profileIndex = m_ui.profilesList->selectionModel()->selectedRows().first().row();
RoutingProfileSettingsDialog dialog( m_pluginManager, m_profilesModel, q );
dialog.editProfile( profileIndex );
}
void RoutingProfilesWidget::Private::moveUp()
{
if ( m_ui.profilesList->selectionModel()->selectedRows().isEmpty() ) {
return;
}
m_profilesModel->moveUp( m_ui.profilesList->selectionModel()->selectedRows().first().row() );
}
void RoutingProfilesWidget::Private::moveDown()
{
if ( m_ui.profilesList->selectionModel()->selectedRows().isEmpty() ) {
return;
}
m_profilesModel->moveDown( m_ui.profilesList->selectionModel()->selectedRows().first().row() );
}
void RoutingProfilesWidget::Private::updateButtons()
{
QModelIndex current;
if ( !m_ui.profilesList->selectionModel()->selectedRows().isEmpty() ) {
current = m_ui.profilesList->selectionModel()->selectedRows().first();
}
m_ui.configureButton->setEnabled( current.isValid() );
m_ui.removeButton->setEnabled( current.isValid() );
m_ui.moveUpButton->setEnabled( current.isValid() && current.row() > 0 );
m_ui.moveDownButton->setEnabled( current.isValid() && current.row()+1 < m_profilesModel->rowCount() );
}
}
#include "moc_RoutingProfilesWidget.cpp"
diff --git a/src/lib/marble/routing/RoutingWidget.cpp b/src/lib/marble/routing/RoutingWidget.cpp
index c79f2816a..31546de8f 100644
--- a/src/lib/marble/routing/RoutingWidget.cpp
+++ b/src/lib/marble/routing/RoutingWidget.cpp
@@ -1,1031 +1,1031 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "RoutingWidget.h"
#include "GeoDataLineString.h"
#include "GeoDataLookAt.h"
#include "GeoDataPlaylist.h"
#include "GeoDataTour.h"
#include "GeoDataFlyTo.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataPlacemark.h"
#include "TourPlayback.h"
#include "Maneuver.h"
#include "MarbleModel.h"
#include "MarblePlacemarkModel.h"
#include "MarbleWidget.h"
#include "MarbleWidgetInputHandler.h"
#include "Route.h"
#include "RouteRequest.h"
#include "RoutingInputWidget.h"
#include "RoutingLayer.h"
#include "RoutingManager.h"
#include "RoutingModel.h"
#include "RoutingProfilesModel.h"
#include "RoutingProfileSettingsDialog.h"
#include "GeoDataDocument.h"
#include "GeoDataTreeModel.h"
#include "GeoDataCreate.h"
#include "GeoDataUpdate.h"
#include "GeoDataDelete.h"
#include "AlternativeRoutesModel.h"
#include "RouteSyncManager.h"
#include "CloudRoutesDialog.h"
#include "CloudSyncManager.h"
#include "PlaybackAnimatedUpdateItem.h"
#include "GeoDataAnimatedUpdate.h"
#include "Planet.h"
#include <QTimer>
#include <QPainter>
#include <QFileDialog>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QToolBar>
#include <QToolButton>
#include <QProgressDialog>
#include "ui_RoutingWidget.h"
namespace Marble
{
struct WaypointInfo
{
int index;
double distance; // distance to route start
GeoDataCoordinates coordinates;
Maneuver maneuver;
QString info;
WaypointInfo( int index_, double distance_, const GeoDataCoordinates &coordinates_, Maneuver maneuver_, const QString& info_ ) :
index( index_ ),
distance( distance_ ),
coordinates( coordinates_ ),
maneuver( maneuver_ ),
info( info_ )
{
// nothing to do
}
};
class RoutingWidgetPrivate
{
public:
Ui::RoutingWidget m_ui;
MarbleWidget *const m_widget;
RoutingManager *const m_routingManager;
RoutingLayer *const m_routingLayer;
RoutingInputWidget *m_activeInput;
QVector<RoutingInputWidget*> m_inputWidgets;
RoutingInputWidget *m_inputRequest;
QAbstractItemModel *const m_routingModel;
RouteRequest *const m_routeRequest;
RouteSyncManager *m_routeSyncManager;
bool m_zoomRouteAfterDownload;
QTimer m_progressTimer;
QVector<QIcon> m_progressAnimation;
GeoDataDocument *m_document;
GeoDataTour *m_tour;
TourPlayback *m_playback;
int m_currentFrame;
int m_iconSize;
int m_collapse_width;
bool m_playing;
QString m_planetId;
QToolBar *m_toolBar;
QToolButton *m_openRouteButton;
QToolButton *m_saveRouteButton;
QAction *m_cloudSyncSeparator;
QAction *m_uploadToCloudAction;
QAction *m_openCloudRoutesAction;
QToolButton *m_addViaButton;
QToolButton *m_reverseRouteButton;
QToolButton *m_clearRouteButton;
QToolButton *m_configureButton;
QToolButton *m_playButton;
QProgressDialog* m_routeUploadDialog;
/** Constructor */
RoutingWidgetPrivate(RoutingWidget *parent, MarbleWidget *marbleWidget );
/**
* @brief Toggle between simple search view and route view
* If only one input field exists, hide all buttons
*/
void adjustInputWidgets();
void adjustSearchButton();
/**
* @brief Change the active input widget
* The active input widget influences what is shown in the paint layer
* and in the list view: Either a set of placemarks that correspond to
* a runner search result or the current route
*/
void setActiveInput( RoutingInputWidget* widget );
void setupToolBar();
private:
void createProgressAnimation();
RoutingWidget *m_parent;
};
RoutingWidgetPrivate::RoutingWidgetPrivate( RoutingWidget *parent, MarbleWidget *marbleWidget ) :
m_widget( marbleWidget ),
m_routingManager( marbleWidget->model()->routingManager() ),
m_routingLayer( marbleWidget->routingLayer() ),
- m_activeInput( 0 ),
- m_inputRequest( 0 ),
+ m_activeInput( nullptr ),
+ m_inputRequest( nullptr ),
m_routingModel( m_routingManager->routingModel() ),
m_routeRequest( marbleWidget->model()->routingManager()->routeRequest() ),
- m_routeSyncManager( 0 ),
+ m_routeSyncManager( nullptr ),
m_zoomRouteAfterDownload( false ),
- m_document( 0 ),
- m_tour( 0 ),
- m_playback( 0 ),
+ m_document( nullptr ),
+ m_tour( nullptr ),
+ m_playback( nullptr ),
m_currentFrame( 0 ),
m_iconSize( 16 ),
m_collapse_width( 0 ),
m_playing( false ),
m_planetId(marbleWidget->model()->planetId()),
- m_toolBar( 0 ),
- m_openRouteButton( 0 ),
- m_saveRouteButton( 0 ),
- m_cloudSyncSeparator( 0 ),
- m_uploadToCloudAction( 0 ),
- m_openCloudRoutesAction( 0 ),
- m_addViaButton( 0 ),
- m_reverseRouteButton( 0 ),
- m_clearRouteButton( 0 ),
- m_configureButton( 0 ),
- m_routeUploadDialog( 0 ),
+ m_toolBar( nullptr ),
+ m_openRouteButton( nullptr ),
+ m_saveRouteButton( nullptr ),
+ m_cloudSyncSeparator( nullptr ),
+ m_uploadToCloudAction( nullptr ),
+ m_openCloudRoutesAction( nullptr ),
+ m_addViaButton( nullptr ),
+ m_reverseRouteButton( nullptr ),
+ m_clearRouteButton( nullptr ),
+ m_configureButton( nullptr ),
+ m_routeUploadDialog( nullptr ),
m_parent( parent )
{
createProgressAnimation();
m_progressTimer.setInterval( 100 );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
m_iconSize = 32;
}
}
void RoutingWidgetPrivate::adjustInputWidgets()
{
for ( int i = 0; i < m_inputWidgets.size(); ++i ) {
m_inputWidgets[i]->setIndex( i );
}
adjustSearchButton();
}
void RoutingWidgetPrivate::adjustSearchButton()
{
QString text = QObject::tr( "Get Directions" );
QString tooltip = QObject::tr( "Retrieve routing instructions for the selected destinations." );
int validInputs = 0;
for ( int i = 0; i < m_inputWidgets.size(); ++i ) {
if ( m_inputWidgets[i]->hasTargetPosition() ) {
++validInputs;
}
}
if ( validInputs < 2 ) {
text = QObject::tr( "Search" );
tooltip = QObject::tr( "Find places matching the search term" );
}
m_ui.searchButton->setText( text );
m_ui.searchButton->setToolTip( tooltip );
}
void RoutingWidgetPrivate::setActiveInput( RoutingInputWidget *widget )
{
Q_ASSERT( widget && "Must not pass null" );
MarblePlacemarkModel *model = widget->searchResultModel();
m_activeInput = widget;
m_ui.directionsListView->setModel( model );
m_routingLayer->setPlacemarkModel( model );
m_routingLayer->synchronizeWith( m_ui.directionsListView->selectionModel() );
}
void RoutingWidgetPrivate::setupToolBar()
{
m_toolBar = new QToolBar;
m_openRouteButton = new QToolButton;
m_openRouteButton->setToolTip( QObject::tr("Open Route") );
m_openRouteButton->setIcon(QIcon(QStringLiteral(":/icons/16x16/document-open.png")));
m_toolBar->addWidget(m_openRouteButton);
m_saveRouteButton = new QToolButton;
m_saveRouteButton->setToolTip( QObject::tr("Save Route") );
m_saveRouteButton->setIcon(QIcon(QStringLiteral(":/icons/16x16/document-save.png")));
m_toolBar->addWidget(m_saveRouteButton);
m_playButton = new QToolButton;
m_playButton->setToolTip( QObject::tr("Preview Route") );
m_playButton->setIcon(QIcon(QStringLiteral(":/marble/playback-play.png")));
m_toolBar->addWidget(m_playButton);
m_cloudSyncSeparator = m_toolBar->addSeparator();
m_uploadToCloudAction = m_toolBar->addAction( QObject::tr("Upload to Cloud") );
m_uploadToCloudAction->setToolTip( QObject::tr("Upload to Cloud") );
m_uploadToCloudAction->setIcon(QIcon(QStringLiteral(":/icons/cloud-upload.png")));
m_openCloudRoutesAction = m_toolBar->addAction( QObject::tr("Manage Cloud Routes") );
m_openCloudRoutesAction->setToolTip( QObject::tr("Manage Cloud Routes") );
m_openCloudRoutesAction->setIcon(QIcon(QStringLiteral(":/icons/cloud-download.png")));
m_toolBar->addSeparator();
m_addViaButton = new QToolButton;
m_addViaButton->setToolTip( QObject::tr("Add Via") );
m_addViaButton->setIcon(QIcon(QStringLiteral(":/marble/list-add.png")));
m_toolBar->addWidget(m_addViaButton);
m_reverseRouteButton = new QToolButton;
m_reverseRouteButton->setToolTip( QObject::tr("Reverse Route") );
m_reverseRouteButton->setIcon(QIcon(QStringLiteral(":/marble/reverse.png")));
m_toolBar->addWidget(m_reverseRouteButton);
m_clearRouteButton = new QToolButton;
m_clearRouteButton->setToolTip( QObject::tr("Clear Route") );
m_clearRouteButton->setIcon(QIcon(QStringLiteral(":/marble/edit-clear.png")));
m_toolBar->addWidget(m_clearRouteButton);
m_toolBar->addSeparator();
m_configureButton = new QToolButton;
m_configureButton->setToolTip( QObject::tr("Settings") );
m_configureButton->setIcon(QIcon(QStringLiteral(":/icons/16x16/configure.png")));
m_toolBar->addWidget(m_configureButton);
QObject::connect( m_openRouteButton, SIGNAL(clicked()),
m_parent, SLOT(openRoute()) );
QObject::connect( m_saveRouteButton, SIGNAL(clicked()),
m_parent, SLOT(saveRoute()) );
QObject::connect( m_uploadToCloudAction, SIGNAL(triggered()),
m_parent, SLOT(uploadToCloud()) );
QObject::connect( m_openCloudRoutesAction, SIGNAL(triggered()),
m_parent, SLOT(openCloudRoutesDialog()));
QObject::connect( m_addViaButton, SIGNAL(clicked()),
m_parent, SLOT(addInputWidget()) );
QObject::connect( m_reverseRouteButton, SIGNAL(clicked()),
m_routingManager, SLOT(reverseRoute()) );
QObject::connect( m_clearRouteButton, SIGNAL(clicked()),
m_routingManager, SLOT(clearRoute()) );
QObject::connect( m_configureButton, SIGNAL(clicked()),
m_parent, SLOT(configureProfile()) );
QObject::connect( m_playButton, SIGNAL(clicked()),
m_parent, SLOT(toggleRoutePlay()) );
m_toolBar->setIconSize(QSize(16, 16));
m_ui.toolBarLayout->addWidget(m_toolBar, 0, Qt::AlignLeft);
}
void RoutingWidgetPrivate::createProgressAnimation()
{
// Size parameters
qreal const h = m_iconSize / 2.0; // Half of the icon size
qreal const q = h / 2.0; // Quarter of the icon size
qreal const d = 7.5; // Circle diameter
qreal const r = d / 2.0; // Circle radius
// Canvas parameters
QImage canvas( m_iconSize, m_iconSize, QImage::Format_ARGB32 );
QPainter painter( &canvas );
painter.setRenderHint( QPainter::Antialiasing, true );
painter.setPen( QColor ( Qt::gray ) );
painter.setBrush( QColor( Qt::white ) );
// Create all frames
for( double t = 0.0; t < 2 * M_PI; t += M_PI / 8.0 ) {
canvas.fill( Qt::transparent );
QRectF firstCircle( h - r + q * cos( t ), h - r + q * sin( t ), d, d );
QRectF secondCircle( h - r + q * cos( t + M_PI ), h - r + q * sin( t + M_PI ), d, d );
painter.drawEllipse( firstCircle );
painter.drawEllipse( secondCircle );
m_progressAnimation.push_back( QIcon( QPixmap::fromImage( canvas ) ) );
}
}
RoutingWidget::RoutingWidget( MarbleWidget *marbleWidget, QWidget *parent ) :
QWidget( parent ), d( new RoutingWidgetPrivate( this, marbleWidget ) )
{
d->m_ui.setupUi( this );
d->setupToolBar();
d->m_ui.routeComboBox->setVisible( false );
d->m_ui.routeComboBox->setModel( d->m_routingManager->alternativeRoutesModel() );
layout()->setMargin( 0 );
d->m_ui.routingProfileComboBox->setModel( d->m_routingManager->profilesModel() );
connect( d->m_routingManager->profilesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(selectFirstProfile()) );
connect( d->m_routingManager->profilesModel(), SIGNAL(modelReset()),
this, SLOT(selectFirstProfile()) );
connect( d->m_routingLayer, SIGNAL(placemarkSelected(QModelIndex)),
this, SLOT(activatePlacemark(QModelIndex)) );
connect( d->m_routingManager, SIGNAL(stateChanged(RoutingManager::State)),
this, SLOT(updateRouteState(RoutingManager::State)) );
connect( d->m_routeRequest, SIGNAL(positionAdded(int)),
this, SLOT(insertInputWidget(int)) );
connect( d->m_routeRequest, SIGNAL(positionRemoved(int)),
this, SLOT(removeInputWidget(int)) );
connect( d->m_routeRequest, SIGNAL(routingProfileChanged()),
this, SLOT(updateActiveRoutingProfile()) );
connect( &d->m_progressTimer, SIGNAL(timeout()),
this, SLOT(updateProgress()) );
connect( d->m_ui.routeComboBox, SIGNAL(currentIndexChanged(int)),
d->m_routingManager->alternativeRoutesModel(), SLOT(setCurrentRoute(int)) );
connect( d->m_routingManager->alternativeRoutesModel(), SIGNAL(currentRouteChanged(int)),
d->m_ui.routeComboBox, SLOT(setCurrentIndex(int)) );
connect( d->m_ui.routingProfileComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(setRoutingProfile(int)) );
connect( d->m_ui.routingProfileComboBox, SIGNAL(activated(int)),
this, SLOT(retrieveRoute()) );
connect( d->m_routingManager->alternativeRoutesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(updateAlternativeRoutes()) );
d->m_ui.directionsListView->setModel( d->m_routingModel );
QItemSelectionModel *selectionModel = d->m_ui.directionsListView->selectionModel();
d->m_routingLayer->synchronizeWith( selectionModel );
connect( d->m_ui.directionsListView, SIGNAL(activated(QModelIndex)),
this, SLOT(activateItem(QModelIndex)) );
// FIXME: apply for this sector
connect( d->m_ui.searchButton, SIGNAL(clicked()),
this, SLOT(retrieveRoute()) );
connect( d->m_ui.showInstructionsButton, SIGNAL(clicked(bool)),
this, SLOT(showDirections()) );
for( int i=0; i<d->m_routeRequest->size(); ++i ) {
insertInputWidget( i );
}
for ( int i=0; i<2 && d->m_inputWidgets.size()<2; ++i ) {
// Start with source and destination if the route is empty yet
addInputWidget();
}
//d->m_ui.descriptionLabel->setVisible( false );
d->m_ui.resultLabel->setVisible( false );
setShowDirectionsButtonVisible( false );
updateActiveRoutingProfile();
updateCloudSyncButtons();
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
d->m_ui.directionsListView->setVisible( false );
d->m_openRouteButton->setVisible( false );
d->m_saveRouteButton->setVisible( false );
}
connect( marbleWidget->model(), SIGNAL(themeChanged(QString)),
this, SLOT(handlePlanetChange()) );
}
RoutingWidget::~RoutingWidget()
{
delete d->m_playback;
delete d->m_tour;
if( d->m_document ){
d->m_widget->model()->treeModel()->removeDocument( d->m_document );
delete d->m_document;
}
delete d;
}
void RoutingWidget::retrieveRoute()
{
if ( d->m_inputWidgets.size() == 1 ) {
// Search mode
d->m_inputWidgets.first()->findPlacemarks();
return;
}
int index = d->m_ui.routingProfileComboBox->currentIndex();
if ( index == -1 ) {
return;
}
d->m_routeRequest->setRoutingProfile( d->m_routingManager->profilesModel()->profiles().at( index ) );
Q_ASSERT( d->m_routeRequest->size() == d->m_inputWidgets.size() );
for ( int i = 0; i < d->m_inputWidgets.size(); ++i ) {
RoutingInputWidget *widget = d->m_inputWidgets.at( i );
if ( !widget->hasTargetPosition() && widget->hasInput() ) {
widget->findPlacemarks();
return;
}
}
- d->m_activeInput = 0;
+ d->m_activeInput = nullptr;
if ( d->m_routeRequest->size() > 1 ) {
d->m_zoomRouteAfterDownload = true;
- d->m_routingLayer->setPlacemarkModel( 0 );
+ d->m_routingLayer->setPlacemarkModel( nullptr );
d->m_routingManager->retrieveRoute();
d->m_ui.directionsListView->setModel( d->m_routingModel );
d->m_routingLayer->synchronizeWith( d->m_ui.directionsListView->selectionModel() );
}
if( d->m_playback ) {
d->m_playback->stop();
}
}
void RoutingWidget::activateItem ( const QModelIndex &index )
{
QVariant data = index.data( MarblePlacemarkModel::CoordinateRole );
if ( !data.isNull() ) {
GeoDataCoordinates position = qvariant_cast<GeoDataCoordinates>( data );
d->m_widget->centerOn( position, true );
}
if ( d->m_activeInput && index.isValid() ) {
QVariant data = index.data( MarblePlacemarkModel::CoordinateRole );
if ( !data.isNull() ) {
d->m_activeInput->setTargetPosition( data.value<GeoDataCoordinates>(), index.data().toString() );
}
}
}
void RoutingWidget::handleSearchResult( RoutingInputWidget *widget )
{
d->setActiveInput( widget );
MarblePlacemarkModel *model = widget->searchResultModel();
if ( model->rowCount() ) {
QString const results = tr( "placemarks found: %1" ).arg( model->rowCount() );
d->m_ui.resultLabel->setText( results );
d->m_ui.resultLabel->setVisible( true );
// Make sure we have a selection
activatePlacemark( model->index( 0, 0 ) );
} else {
QString const results = tr( "No placemark found" );
d->m_ui.resultLabel->setText(QLatin1String("<font color=\"red\">") + results + QLatin1String("</font>"));
d->m_ui.resultLabel->setVisible( true );
}
GeoDataLineString placemarks;
for ( int i = 0; i < model->rowCount(); ++i ) {
QVariant data = model->index( i, 0 ).data( MarblePlacemarkModel::CoordinateRole );
if ( !data.isNull() ) {
placemarks << data.value<GeoDataCoordinates>();
}
}
if ( placemarks.size() > 1 ) {
d->m_widget->centerOn( GeoDataLatLonBox::fromLineString( placemarks ) );
//d->m_ui.descriptionLabel->setVisible( false );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
d->m_ui.directionsListView->setVisible( true );
}
}
}
void RoutingWidget::centerOnInputWidget( RoutingInputWidget *widget )
{
if ( widget->hasTargetPosition() ) {
d->m_widget->centerOn( widget->targetPosition() );
}
}
void RoutingWidget::activatePlacemark( const QModelIndex &index )
{
if ( d->m_activeInput && index.isValid() ) {
QVariant data = index.data( MarblePlacemarkModel::CoordinateRole );
if ( !data.isNull() ) {
d->m_activeInput->setTargetPosition( data.value<GeoDataCoordinates>() );
}
}
d->m_ui.directionsListView->setCurrentIndex( index );
}
void RoutingWidget::addInputWidget()
{
d->m_routeRequest->append( GeoDataCoordinates() );
}
void RoutingWidget::insertInputWidget( int index )
{
if ( index >= 0 && index <= d->m_inputWidgets.size() ) {
RoutingInputWidget *input = new RoutingInputWidget( d->m_widget->model(), index, this );
d->m_inputWidgets.insert( index, input );
connect( input, SIGNAL(searchFinished(RoutingInputWidget*)),
this, SLOT(handleSearchResult(RoutingInputWidget*)) );
connect( input, SIGNAL(removalRequest(RoutingInputWidget*)),
this, SLOT(removeInputWidget(RoutingInputWidget*)) );
connect( input, SIGNAL(activityRequest(RoutingInputWidget*)),
this, SLOT(centerOnInputWidget(RoutingInputWidget*)) );
connect( input, SIGNAL(mapInputModeEnabled(RoutingInputWidget*,bool)),
this, SLOT(requestMapPosition(RoutingInputWidget*,bool)) );
connect( input, SIGNAL(targetValidityChanged(bool)),
this, SLOT(adjustSearchButton()) );
d->m_ui.inputLayout->insertWidget( index, input );
d->adjustInputWidgets();
}
}
void RoutingWidget::removeInputWidget( RoutingInputWidget *widget )
{
int index = d->m_inputWidgets.indexOf( widget );
if ( index >= 0 ) {
if ( d->m_inputWidgets.size() < 3 ) {
widget->clear();
} else {
d->m_routeRequest->remove( index );
}
d->m_routingManager->retrieveRoute();
}
}
void RoutingWidget::removeInputWidget( int index )
{
if ( index >= 0 && index < d->m_inputWidgets.size() ) {
RoutingInputWidget *widget = d->m_inputWidgets.at( index );
d->m_inputWidgets.remove( index );
d->m_ui.inputLayout->removeWidget( widget );
widget->deleteLater();
if ( widget == d->m_activeInput ) {
- d->m_activeInput = 0;
- d->m_routingLayer->setPlacemarkModel( 0 );
+ d->m_activeInput = nullptr;
+ d->m_routingLayer->setPlacemarkModel( nullptr );
d->m_ui.directionsListView->setModel( d->m_routingModel );
d->m_routingLayer->synchronizeWith( d->m_ui.directionsListView->selectionModel() );
}
d->adjustInputWidgets();
}
if ( d->m_inputWidgets.size() < 2 ) {
addInputWidget();
}
}
void RoutingWidget::updateRouteState( RoutingManager::State state )
{
clearTour();
switch ( state ) {
case RoutingManager::Downloading:
d->m_ui.routeComboBox->setVisible( false );
d->m_ui.routeComboBox->clear();
d->m_progressTimer.start();
d->m_ui.resultLabel->setVisible( false );
break;
case RoutingManager::Retrieved: {
d->m_progressTimer.stop();
d->m_ui.searchButton->setIcon( QIcon() );
if ( d->m_routingManager->routingModel()->rowCount() == 0 ) {
const QString results = tr( "No route found" );
d->m_ui.resultLabel->setText(QLatin1String("<font color=\"red\">") + results + QLatin1String("</font>"));
d->m_ui.resultLabel->setVisible( true );
}
}
break;
}
d->m_saveRouteButton->setEnabled( d->m_routingManager->routingModel()->rowCount() > 0 );
}
void RoutingWidget::requestMapPosition( RoutingInputWidget *widget, bool enabled )
{
pointSelectionCanceled();
if ( enabled ) {
d->m_inputRequest = widget;
d->m_widget->installEventFilter( this );
d->m_widget->setFocus( Qt::OtherFocusReason );
}
}
void RoutingWidget::retrieveSelectedPoint( const GeoDataCoordinates &coordinates )
{
if ( d->m_inputRequest && d->m_inputWidgets.contains( d->m_inputRequest ) ) {
d->m_inputRequest->setTargetPosition( coordinates );
d->m_widget->update();
}
- d->m_inputRequest = 0;
+ d->m_inputRequest = nullptr;
d->m_widget->removeEventFilter( this );
}
void RoutingWidget::adjustSearchButton()
{
d->adjustSearchButton();
}
void RoutingWidget::pointSelectionCanceled()
{
if ( d->m_inputRequest && d->m_inputWidgets.contains( d->m_inputRequest ) ) {
d->m_inputRequest->abortMapInputRequest();
}
- d->m_inputRequest = 0;
+ d->m_inputRequest = nullptr;
d->m_widget->removeEventFilter( this );
}
void RoutingWidget::configureProfile()
{
int index = d->m_ui.routingProfileComboBox->currentIndex();
if ( index != -1 ) {
RoutingProfileSettingsDialog dialog( d->m_widget->model()->pluginManager(), d->m_routingManager->profilesModel(), this );
dialog.editProfile( d->m_ui.routingProfileComboBox->currentIndex() );
d->m_routeRequest->setRoutingProfile( d->m_routingManager->profilesModel()->profiles().at( index ) );
}
}
void RoutingWidget::updateProgress()
{
if ( !d->m_progressAnimation.isEmpty() ) {
d->m_currentFrame = ( d->m_currentFrame + 1 ) % d->m_progressAnimation.size();
QIcon frame = d->m_progressAnimation[d->m_currentFrame];
d->m_ui.searchButton->setIcon( frame );
}
}
void RoutingWidget::updateAlternativeRoutes()
{
if ( d->m_ui.routeComboBox->count() == 1) {
// Parts of the route may lie outside the route trip points
GeoDataLatLonBox const bbox = d->m_routingManager->routingModel()->route().bounds();
if ( d->m_zoomRouteAfterDownload ) {
d->m_zoomRouteAfterDownload = false;
d->m_widget->centerOn( bbox );
}
}
d->m_ui.routeComboBox->setVisible( d->m_ui.routeComboBox->count() > 0 );
if ( d->m_ui.routeComboBox->currentIndex() < 0 && d->m_ui.routeComboBox->count() > 0 ) {
d->m_ui.routeComboBox->setCurrentIndex( 0 );
}
QString const results = tr( "routes found: %1" ).arg( d->m_ui.routeComboBox->count() );
d->m_ui.resultLabel->setText( results );
d->m_ui.resultLabel->setVisible( true );
d->m_saveRouteButton->setEnabled( d->m_routingManager->routingModel()->rowCount() > 0 );
}
void RoutingWidget::setShowDirectionsButtonVisible( bool visible )
{
d->m_ui.showInstructionsButton->setVisible( visible );
}
void RoutingWidget::setRouteSyncManager(RouteSyncManager *manager)
{
d->m_routeSyncManager = manager;
connect( d->m_routeSyncManager, SIGNAL(routeSyncEnabledChanged(bool)),
this, SLOT(updateCloudSyncButtons()) );
updateCloudSyncButtons();
}
void RoutingWidget::openRoute()
{
QString const file = QFileDialog::getOpenFileName( this, tr( "Open Route" ),
d->m_routingManager->lastOpenPath(), tr("KML Files (*.kml)") );
if ( !file.isEmpty() ) {
d->m_routingManager->setLastOpenPath( QFileInfo( file ).absolutePath() );
d->m_zoomRouteAfterDownload = true;
d->m_routingManager->loadRoute( file );
updateAlternativeRoutes();
}
}
void RoutingWidget::selectFirstProfile()
{
int count = d->m_routingManager->profilesModel()->rowCount();
if ( count && d->m_ui.routingProfileComboBox->currentIndex() < 0 ) {
d->m_ui.routingProfileComboBox->setCurrentIndex( 0 );
}
}
void RoutingWidget::setRoutingProfile( int index )
{
if ( index >= 0 && index < d->m_routingManager->profilesModel()->rowCount() ) {
d->m_routeRequest->setRoutingProfile( d->m_routingManager->profilesModel()->profiles().at( index ) );
}
}
void RoutingWidget::showDirections()
{
d->m_ui.directionsListView->setVisible( true );
}
void RoutingWidget::saveRoute()
{
QString fileName = QFileDialog::getSaveFileName( this,
tr( "Save Route" ), // krazy:exclude=qclasses
d->m_routingManager->lastSavePath(),
tr( "KML files (*.kml)" ) );
if ( !fileName.isEmpty() ) {
// maemo 5 file dialog does not append the file extension
if ( !fileName.endsWith(QLatin1String( ".kml" ), Qt::CaseInsensitive) ) {
fileName += QLatin1String(".kml");
}
d->m_routingManager->setLastSavePath( QFileInfo( fileName ).absolutePath() );
d->m_routingManager->saveRoute( fileName );
}
}
void RoutingWidget::uploadToCloud()
{
Q_ASSERT( d->m_routeSyncManager );
if (!d->m_routeUploadDialog) {
d->m_routeUploadDialog = new QProgressDialog( d->m_widget );
d->m_routeUploadDialog->setWindowTitle( tr( "Uploading route..." ) );
d->m_routeUploadDialog->setMinimum( 0 );
d->m_routeUploadDialog->setMaximum( 100 );
d->m_routeUploadDialog->setAutoClose( true );
d->m_routeUploadDialog->setAutoReset( true );
connect( d->m_routeSyncManager, SIGNAL(routeUploadProgress(qint64,qint64)), this, SLOT(updateUploadProgress(qint64,qint64)) );
}
d->m_routeUploadDialog->show();
d->m_routeSyncManager->uploadRoute();
}
void RoutingWidget::openCloudRoutesDialog()
{
Q_ASSERT( d->m_routeSyncManager );
d->m_routeSyncManager->prepareRouteList();
QPointer<CloudRoutesDialog> dialog = new CloudRoutesDialog( d->m_routeSyncManager->model(), d->m_widget );
connect( d->m_routeSyncManager, SIGNAL(routeListDownloadProgress(qint64,qint64)), dialog, SLOT(updateListDownloadProgressbar(qint64,qint64)) );
connect( dialog, SIGNAL(downloadButtonClicked(QString)), d->m_routeSyncManager, SLOT(downloadRoute(QString)) );
connect( dialog, SIGNAL(openButtonClicked(QString)), this, SLOT(openCloudRoute(QString)) );
connect( dialog, SIGNAL(deleteButtonClicked(QString)), d->m_routeSyncManager, SLOT(deleteRoute(QString)) );
connect( dialog, SIGNAL(removeFromCacheButtonClicked(QString)), d->m_routeSyncManager, SLOT(removeRouteFromCache(QString)) );
connect( dialog, SIGNAL(uploadToCloudButtonClicked(QString)), d->m_routeSyncManager, SLOT(uploadRoute(QString)) );
dialog->exec();
delete dialog;
}
void RoutingWidget::updateActiveRoutingProfile()
{
RoutingProfile const profile = d->m_routingManager->routeRequest()->routingProfile();
QList<RoutingProfile> const profiles = d->m_routingManager->profilesModel()->profiles();
d->m_ui.routingProfileComboBox->setCurrentIndex( profiles.indexOf( profile ) );
}
void RoutingWidget::updateCloudSyncButtons()
{
bool const show = d->m_routeSyncManager && d->m_routeSyncManager->isRouteSyncEnabled();
d->m_cloudSyncSeparator->setVisible( show );
d->m_uploadToCloudAction->setVisible( show );
d->m_openCloudRoutesAction->setVisible( show );
}
void RoutingWidget::openCloudRoute(const QString &identifier)
{
Q_ASSERT( d->m_routeSyncManager );
d->m_routeSyncManager->openRoute( identifier );
d->m_widget->centerOn( d->m_routingManager->routingModel()->route().bounds() );
}
void RoutingWidget::updateUploadProgress(qint64 sent, qint64 total)
{
Q_ASSERT( d->m_routeUploadDialog );
d->m_routeUploadDialog->setValue( 100.0 * sent / total );
}
bool RoutingWidget::eventFilter( QObject *o, QEvent *event )
{
if ( o != d->m_widget ) {
return QWidget::eventFilter( o, event );
}
- Q_ASSERT( d->m_inputRequest != 0 );
+ Q_ASSERT( d->m_inputRequest != nullptr );
Q_ASSERT( d->m_inputWidgets.contains( d->m_inputRequest ) );
if ( event->type() == QEvent::MouseButtonPress ) {
QMouseEvent *e = static_cast<QMouseEvent*>( event );
return e->button() == Qt::LeftButton;
}
if ( event->type() == QEvent::MouseButtonRelease ) {
QMouseEvent *e = static_cast<QMouseEvent*>( event );
qreal lon( 0.0 ), lat( 0.0 );
if ( e->button() == Qt::LeftButton && d->m_widget->geoCoordinates( e->pos().x(), e->pos().y(),
lon, lat, GeoDataCoordinates::Radian ) ) {
retrieveSelectedPoint( GeoDataCoordinates( lon, lat ) );
return true;
} else {
return QWidget::eventFilter( o, event );
}
}
if ( event->type() == QEvent::MouseMove ) {
d->m_widget->setCursor( Qt::CrossCursor );
return true;
}
if ( event->type() == QEvent::KeyPress ) {
QKeyEvent *e = static_cast<QKeyEvent*>( event );
if ( e->key() == Qt::Key_Escape ) {
pointSelectionCanceled();
return true;
}
return QWidget::eventFilter( o, event );
}
return QWidget::eventFilter( o, event );
}
void RoutingWidget::resizeEvent(QResizeEvent *e)
{
QWidget::resizeEvent(e);
}
void RoutingWidget::toggleRoutePlay()
{
if( !d->m_playback ){
if( d->m_routingModel->rowCount() != 0 ){
initializeTour();
}
}
if (!d->m_playback)
return;
if( !d->m_playing ){
d->m_playing = true;
d->m_playButton->setIcon(QIcon(QStringLiteral(":/marble/playback-pause.png")));
if( d->m_playback ){
d->m_playback->play();
}
} else {
d->m_playing = false;
d->m_playButton->setIcon(QIcon(QStringLiteral(":/marble/playback-play.png")));
d->m_playback->pause();
}
}
void RoutingWidget::initializeTour()
{
d->m_tour = new GeoDataTour;
if( d->m_document ){
d->m_widget->model()->treeModel()->removeDocument( d->m_document );
delete d->m_document;
}
d->m_document = new GeoDataDocument;
d->m_document->setId(QStringLiteral("tourdoc"));
d->m_document->append( d->m_tour );
d->m_tour->setPlaylist( new GeoDataPlaylist );
Route const route = d->m_widget->model()->routingManager()->routingModel()->route();
GeoDataLineString path = route.path();
if ( path.size() < 1 ){
return;
}
QList<WaypointInfo> waypoints;
double totalDistance = 0.0;
for( int i=0; i<route.size(); ++i ){
// TODO: QString( i )?
waypoints << WaypointInfo(i, totalDistance, route.at(i).path().first(), route.at(i).maneuver(), QLatin1String("start ") + QString(i));
totalDistance += route.at( i ).distance();
}
if( waypoints.size() < 1 ){
return;
}
QList<WaypointInfo> const allWaypoints = waypoints;
totalDistance = 0.0;
GeoDataCoordinates last = path.at( 0 );
int j=0; // next waypoint
qreal planetRadius = d->m_widget->model()->planet()->radius();
for( int i=1; i<path.size(); ++i ){
GeoDataCoordinates coordinates = path.at( i );
totalDistance += planetRadius * path.at(i - 1).sphericalDistanceTo(coordinates); // Distance to route start
while (totalDistance >= allWaypoints[j].distance && j+1<allWaypoints.size()) {
++j;
}
int const lastIndex = qBound( 0, j-1, allWaypoints.size()-1 ); // previous waypoint
double const lastDistance = qAbs( totalDistance - allWaypoints[lastIndex].distance );
double const nextDistance = qAbs( allWaypoints[j].distance - totalDistance );
double const waypointDistance = qMin( lastDistance, nextDistance ); // distance to closest waypoint
double const step = qBound( 100.0, waypointDistance*2, 1000.0 ); // support point distance (higher density close to waypoints)
double const distance = planetRadius * last.sphericalDistanceTo(coordinates);
if( i > 1 && distance < step ){
continue;
}
last = coordinates;
GeoDataLookAt* lookat = new GeoDataLookAt;
// Choose a zoom distance of 400, 600 or 800 meters based on the distance to the closest waypoint
double const range = waypointDistance < 400 ? 400 : ( waypointDistance < 2000 ? 600 : 800 );
coordinates.setAltitude( range );
lookat->setCoordinates( coordinates );
lookat->setRange( range );
GeoDataFlyTo* flyto = new GeoDataFlyTo;
double const duration = 0.75;
flyto->setDuration( duration );
flyto->setView( lookat );
flyto->setFlyToMode( GeoDataFlyTo::Smooth );
d->m_tour->playlist()->addPrimitive( flyto );
if( !waypoints.empty() && totalDistance > waypoints.first().distance-100 ){
WaypointInfo const waypoint = waypoints.first();
waypoints.pop_front();
GeoDataAnimatedUpdate *updateCreate = new GeoDataAnimatedUpdate;
updateCreate->setUpdate( new GeoDataUpdate );
updateCreate->update()->setCreate( new GeoDataCreate );
GeoDataPlacemark *placemarkCreate = new GeoDataPlacemark;
QString const waypointId = QString( "waypoint-%1" ).arg( i, 0, 10 );
placemarkCreate->setId( waypointId );
placemarkCreate->setTargetId( d->m_document->id() );
placemarkCreate->setCoordinate( waypoint.coordinates );
GeoDataStyle::Ptr style(new GeoDataStyle);
style->iconStyle().setIconPath( waypoint.maneuver.directionPixmap() );
placemarkCreate->setStyle( style );
updateCreate->update()->create()->append( placemarkCreate );
d->m_tour->playlist()->addPrimitive( updateCreate );
GeoDataAnimatedUpdate *updateDelete = new GeoDataAnimatedUpdate;
updateDelete->setDelayedStart( 2 );
updateDelete->setUpdate( new GeoDataUpdate );
updateDelete->update()->setDelete( new GeoDataDelete );
GeoDataPlacemark *placemarkDelete = new GeoDataPlacemark;
placemarkDelete->setTargetId( waypointId );
updateDelete->update()->getDelete()->append( placemarkDelete );
d->m_tour->playlist()->addPrimitive( updateDelete );
}
}
d->m_playback = new TourPlayback;
d->m_playback->setMarbleWidget( d->m_widget );
d->m_playback->setTour( d->m_tour );
d->m_widget->model()->treeModel()->addDocument( d->m_document );
QObject::connect( d->m_playback, SIGNAL(finished()),
this, SLOT(seekTourToStart()) );
}
void RoutingWidget::centerOn( const GeoDataCoordinates &coordinates )
{
if ( d->m_widget ) {
GeoDataLookAt lookat;
lookat.setCoordinates( coordinates );
lookat.setRange( coordinates.altitude() );
d->m_widget->flyTo( lookat, Instant );
}
}
void RoutingWidget::clearTour()
{
d->m_playing = false;
d->m_playButton->setIcon(QIcon(QStringLiteral(":/marble/playback-play.png")));
delete d->m_playback;
- d->m_playback = 0;
+ d->m_playback = nullptr;
if( d->m_document ){
d->m_widget->model()->treeModel()->removeDocument( d->m_document );
delete d->m_document;
- d->m_document = 0;
- d->m_tour = 0;
+ d->m_document = nullptr;
+ d->m_tour = nullptr;
}
}
void RoutingWidget::seekTourToStart()
{
Q_ASSERT( d->m_playback );
d->m_playback->stop();
d->m_playback->seek( 0 );
d->m_playButton->setIcon(QIcon(QStringLiteral(":/marble/playback-play.png")));
d->m_playing = false;
}
void RoutingWidget::handlePlanetChange()
{
const QString newPlanetId = d->m_widget->model()->planetId();
if (newPlanetId == d->m_planetId) {
return;
}
d->m_planetId = newPlanetId;
d->m_routingManager->clearRoute();
}
} // namespace Marble
#include "moc_RoutingWidget.cpp"
diff --git a/src/lib/marble/routing/SpeakersModel.h b/src/lib/marble/routing/SpeakersModel.h
index 994a619ce..38f3be675 100644
--- a/src/lib/marble/routing/SpeakersModel.h
+++ b/src/lib/marble/routing/SpeakersModel.h
@@ -1,86 +1,86 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_SPEAKERSMODEL_H
#define MARBLE_SPEAKERSMODEL_H
#include "marble_export.h"
#include <QAbstractListModel>
namespace Marble
{
class SpeakersModelPrivate;
class MARBLE_EXPORT SpeakersModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
enum SpeakersModelRoles {
Name = Qt::UserRole + 1,
Path,
IsLocal,
IsRemote
};
/** Constructor */
- explicit SpeakersModel( QObject *parent = 0 );
+ explicit SpeakersModel( QObject *parent = nullptr );
/** Destructor */
~SpeakersModel() override;
/** Overload of QAbstractListModel */
int rowCount ( const QModelIndex &parent = QModelIndex() ) const override;
/** Overload of QAbstractListModel */
QVariant data ( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
/** Overload of QAbstractListModel */
QHash<int, QByteArray> roleNames() const override;
/** @todo FIXME https://bugreports.qt-project.org/browse/QTCOMPONENTS-1206 */
int count() const;
public Q_SLOTS:
int indexOf( const QString &name );
QString path( int index );
void install( int index );
bool isLocal( int index ) const;
bool isRemote( int index ) const;
Q_SIGNALS:
void countChanged();
void installationProgressed( int newstuffindex, qreal progress );
void installationFinished( int index );
private:
SpeakersModelPrivate* const d;
friend class SpeakersModelPrivate;
Q_PRIVATE_SLOT( d, void fillModel() )
Q_PRIVATE_SLOT( d, void handleInstallationProgress( int row, qreal progress ) )
Q_PRIVATE_SLOT( d, void handleInstallation( int row ) )
};
}
#endif // MARBLE_SPEAKERSMODEL_H
diff --git a/src/lib/marble/routing/VoiceNavigationModel.h b/src/lib/marble/routing/VoiceNavigationModel.h
index 09bf8d07e..d58110ea2 100644
--- a/src/lib/marble/routing/VoiceNavigationModel.h
+++ b/src/lib/marble/routing/VoiceNavigationModel.h
@@ -1,76 +1,76 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_VOICENAVIGATIONMODEL_H
#define MARBLE_VOICENAVIGATIONMODEL_H
#include "marble_export.h"
#include <QObject>
namespace Marble
{
class Route;
class VoiceNavigationModelPrivate;
class MARBLE_EXPORT VoiceNavigationModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QString speaker READ speaker WRITE setSpeaker NOTIFY speakerChanged)
Q_PROPERTY(bool isSpeakerEnabled READ isSpeakerEnabled WRITE setSpeakerEnabled NOTIFY isSpeakerEnabledChanged )
Q_PROPERTY(QString instruction READ instruction NOTIFY instructionChanged)
Q_PROPERTY(QString preview READ preview NOTIFY previewChanged)
public:
/** Constructor */
- explicit VoiceNavigationModel( QObject *parent = 0 );
+ explicit VoiceNavigationModel( QObject *parent = nullptr );
/** Destructor */
~VoiceNavigationModel() override;
// Initialization
QString speaker() const;
void setSpeaker( const QString &speaker );
bool isSpeakerEnabled() const;
void setSpeakerEnabled( bool enabled );
void reset();
public Q_SLOTS:
void update( const Route &route, qreal distanceManuever, qreal distanceTarget, bool deviated );
// Turn instructions
QString preview() const;
QString instruction() const;
Q_SIGNALS:
void speakerChanged();
void isSpeakerEnabledChanged();
void instructionChanged();
void previewChanged();
private:
VoiceNavigationModelPrivate* const d;
friend class VoiceNavigationModelPrivate;
};
}
#endif // MARBLE_VOICENAVIGATIONMODEL_H
diff --git a/src/lib/marble/routing/instructions/InstructionTransformation.cpp b/src/lib/marble/routing/instructions/InstructionTransformation.cpp
index 07dceeb1e..dec2ab979 100644
--- a/src/lib/marble/routing/instructions/InstructionTransformation.cpp
+++ b/src/lib/marble/routing/instructions/InstructionTransformation.cpp
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "InstructionTransformation.h"
#include <cmath>
namespace Marble
{
RoutingInstructions InstructionTransformation::process( const RoutingWaypoints &model )
{
RoutingInstructions result;
int lastAngle = 0;
for( int i = 0; i < model.size(); ++i ) {
const RoutingWaypoint &item = model[i];
int newAngle = 180 + lastAngle;
if ( i < model.size() - 1 ) {
newAngle = qRound( 180.0 / M_PI * item.point().bearing( model[i+1].point() ) );
}
int angle = ( newAngle - lastAngle + 540 ) % 360;
Q_ASSERT( angle >= 0 && angle <= 360 );
if ( result.isEmpty() || !result.last().append( item, angle ) ) {
result.push_back( RoutingInstruction( item ) );
}
lastAngle = newAngle;
}
for ( int i = 0; i < result.size(); ++i ) {
- result[i].setSuccessor( i < result.size() - 1 ? &result[i+1] : 0 );
- result[i].setPredecessor( i ? &result[i-1] : 0 );
+ result[i].setSuccessor( i < result.size() - 1 ? &result[i+1] : nullptr );
+ result[i].setPredecessor( i ? &result[i-1] : nullptr );
}
return result;
}
} // namespace Marble
diff --git a/src/lib/marble/routing/instructions/RoutingInstruction.cpp b/src/lib/marble/routing/instructions/RoutingInstruction.cpp
index c79de2475..913443fbf 100644
--- a/src/lib/marble/routing/instructions/RoutingInstruction.cpp
+++ b/src/lib/marble/routing/instructions/RoutingInstruction.cpp
@@ -1,531 +1,531 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "RoutingInstruction.h"
#include <QCoreApplication>
#include <QStringList>
#include <QTextStream>
#include <cmath>
namespace Marble
{
RoutingInstruction::RoutingInstruction( const RoutingWaypoint &item ) :
m_roadName( item.roadName() ), m_roadType( item.roadType() ),
m_secondsLeft( item.secondsRemaining() ),
m_angleToPredecessor( 0.0 ), m_roundaboutExit( 0 ),
- m_predecessor( 0 ), m_successor( 0 )
+ m_predecessor( nullptr ), m_successor( nullptr )
{
m_points.append( item );
}
bool RoutingInstruction::append( const RoutingWaypoint &item, int angle )
{
if (m_points.size() &&
m_points.last().roadType() != QLatin1String("roundabout") &&
item.roadType() == QLatin1String("roundabout")) {
// Entering a roundabout. Merge with previous segment to avoid 'Enter the roundabout' instructions
m_points.push_back( item );
return true;
}
if (m_points.size() &&
m_points.last().roadType() == QLatin1String("roundabout") &&
item.roadType() != QLatin1String("roundabout")) {
// Exiting a roundabout
m_points.push_back( item );
return false;
}
m_points.push_back( item );
if ( item.junctionType() == RoutingWaypoint::Roundabout ) {
// Passing a roundabout exit
++m_roundaboutExit;
return true;
}
if ( item.roadName().isEmpty() ) {
if ( item.junctionType() == RoutingWaypoint::None ) {
return true;
}
return angle >= 150 && angle <= 210;
} else {
return item.roadType() == QLatin1String("roundabout") || item.roadName() == roadName();
}
}
QString RoutingInstruction::roadName() const
{
return m_roadName;
}
QString RoutingInstruction::roadType() const
{
return m_roadType;
}
int RoutingInstruction::secondsLeft() const
{
return m_secondsLeft;
}
void RoutingInstruction::calculateAngle()
{
if ( !m_predecessor ) {
return;
}
int hisSize = m_predecessor->points().size();
int mySize = m_points.size();
Q_ASSERT( mySize > 0 && hisSize > 0 );
RoutingPoint one = points().first().point();
RoutingPoint two = m_predecessor->points().at( hisSize - 1 ).point();
qreal distance = 0;
for ( int i = 2; i <= qMin<int>( hisSize, 20 ) && distance < 50.0; ++i ) {
two = m_predecessor->points().at( hisSize - i ).point();
m_intersectionPoints.push_front( two );
distance = one.distance( two );
}
qreal before = two.bearing( one );
m_intersectionPoints.push_back( one );
one = points().first().point();
if ( mySize == 1 && !m_successor ) {
return;
} else if ( mySize == 1 ) {
Q_ASSERT( !m_successor->points().isEmpty() );
two = m_successor->points().first().point();
} else {
two = points().at( 1 ).point();
}
distance = 0;
m_intersectionPoints.push_back( one );
for ( int i = 2; i < qMin<int>( mySize, 20 ) && distance < 50.0; ++i ) {
two = points().at( i ).point();
m_intersectionPoints.push_back( two );
distance = one.distance( two );
}
qreal after = one.bearing( two );
m_angleToPredecessor = after - before;
}
void RoutingInstruction::calculateTurnType()
{
if ( predecessor() && predecessor()->roundaboutExitNumber() ) {
int exit = predecessor()->roundaboutExitNumber();
switch( exit ) {
case 1:
m_turnType = RoundaboutFirstExit;
break;
case 2:
m_turnType = RoundaboutSecondExit;
break;
case 3:
m_turnType = RoundaboutThirdExit;
break;
default:
m_turnType = RoundaboutExit;
break;
}
return;
}
int angle = qRound( angleToPredecssor() * 180.0 / M_PI + 540 ) % 360;
Q_ASSERT( angle >= 0 && angle <= 360 );
const int sharp = 30;
if ( angle >= 360 - sharp || angle < sharp ) {
m_turnType = TurnAround;
} else if ( angle >= sharp && angle < 90 - sharp ) {
m_turnType = SharpLeft;
} else if ( angle >= 90 - sharp && angle < 90 + sharp ) {
m_turnType = Left;
} else if ( angle >= 90 + sharp && angle < 180 - sharp ) {
m_turnType = SlightLeft;
} else if ( angle >= 180 - sharp && angle < 180 + sharp ) {
m_turnType = Straight;
} else if ( angle >= 180 + sharp && angle < 270 - sharp ) {
m_turnType = SlightRight;
} else if ( angle >= 270 - sharp && angle < 270 + sharp ) {
m_turnType = Right;
} else if ( angle >= 270 + sharp && angle < 360 - sharp ) {
m_turnType = SharpRight;
} else {
Q_ASSERT( false && "Internal error: not all angles are properly handled" );
}
}
QVector<RoutingWaypoint> RoutingInstruction::points() const
{
return m_points;
}
QVector<RoutingPoint> RoutingInstruction::intersectionPoints() const
{
return m_intersectionPoints;
}
qreal RoutingInstruction::angleToPredecssor() const
{
return m_angleToPredecessor;
}
RoutingInstruction* RoutingInstruction::predecessor()
{
return m_predecessor;
}
const RoutingInstruction* RoutingInstruction::predecessor() const
{
return m_predecessor;
}
void RoutingInstruction::setPredecessor( RoutingInstruction* predecessor )
{
m_predecessor = predecessor;
calculateAngle();
calculateTurnType();
}
RoutingInstruction* RoutingInstruction::successor()
{
return m_successor;
}
const RoutingInstruction* RoutingInstruction::successor() const
{
return m_successor;
}
void RoutingInstruction::setSuccessor( RoutingInstruction* successor )
{
m_successor = successor;
}
qreal RoutingInstruction::distance() const
{
qreal result = 0.0;
for ( int i = 1; i < m_points.size(); ++i ) {
result += m_points[i-1].point().distance( m_points[i].point() );
}
return result;
}
qreal RoutingInstruction::distanceFromStart() const
{
qreal result = 0.0;
const RoutingInstruction* i = predecessor();
while ( i ) {
result += i->distance();
i = i->predecessor();
}
return result;
}
qreal RoutingInstruction::distanceToEnd() const
{
qreal result = distance();
const RoutingInstruction* i = successor();
while ( i ) {
result += i->distance();
i = i->successor();
}
return result;
}
QString RoutingInstruction::nextRoadInstruction() const
{
if (roadType() == QLatin1String("roundabout")) {
return QObject::tr( "Enter the roundabout." );
}
if (roadType() == QLatin1String("motorway_link")) {
QStringList motorways = QStringList() << "motorway" << "motorway_link";
bool const leaving = predecessor() && motorways.contains( predecessor()->roadType() );
if ( leaving ) {
if ( roadName().isEmpty() ) {
return QObject::tr( "Take the exit." );
} else {
return QObject::tr( "Take the exit towards %1." ).arg( roadName() );
}
}
if ( roadName().isEmpty() ) {
return QObject::tr( "Take the ramp." );
} else {
return QObject::tr( "Take the ramp towards %1." ).arg( roadName() );
}
}
TurnType turnType = m_turnType;
if ( predecessor() && predecessor()->roundaboutExitNumber() ) {
switch ( predecessor()->roundaboutExitNumber() ) {
case 1:
turnType = RoundaboutFirstExit;
break;
case 2:
turnType = RoundaboutSecondExit;
break;
case 3:
turnType = RoundaboutThirdExit;
break;
}
}
return generateRoadInstruction( turnType, roadName() );
}
QString RoutingInstruction::nextDistanceInstruction() const
{
QLocale::MeasurementSystem const measurement = QLocale::system().measurementSystem();
int precision = 0;
qreal length = distance();
QString distanceUnit = QLatin1String( "m" );
if ( measurement != QLocale::MetricSystem ) {
precision = 1;
distanceUnit = "mi";
length /= 1000.0;
length /= 1.609344;
if ( length < 0.1 ) {
length = 10 * qRound( length * 528 );
precision = 0;
distanceUnit = "ft";
}
} else {
if ( length >= 1000 ) {
length /= 1000;
distanceUnit = "km";
precision = 1;
} else if ( length >= 200 ) {
length = 50 * qRound( length / 50 );
} else if ( length >= 100 ) {
length = 25 * qRound( length / 25 );
} else {
length = 10 * qRound( length / 10 );
}
}
if ( length == 0 ) {
return QString();
} else {
QString text = QObject::tr( "Follow the road for %1 %2." );
return text.arg( length, 0, 'f', precision ).arg( distanceUnit );
}
}
QString RoutingInstruction::totalDurationRemaining() const
{
qreal duration = secondsLeft();
QString durationUnit = "sec";
int precision = 0;
if ( duration >= 60.0 ) {
duration /= 60.0;
durationUnit = "min";
precision = 0;
}
if ( duration >= 60.0 ) {
duration /= 60.0;
durationUnit = QStringLiteral("h");
precision = 1;
}
QString text = "Arrival in %1 %2.";
return text.arg( duration, 0, 'f', precision ).arg( durationUnit );
}
QString RoutingInstruction::instructionText() const
{
QString text = nextRoadInstruction();
text += QLatin1Char(' ') + nextDistanceInstruction();
if (QCoreApplication::instance()->arguments().contains(QStringLiteral("--remaining-duration"))) {
text += QLatin1Char(' ') + totalDurationRemaining();
}
return text;
}
QString RoutingInstruction::generateRoadInstruction( RoutingInstruction::TurnType turnType, const QString &roadName )
{
int roundaboutExit = 0;
switch ( turnType ) {
case RoundaboutFirstExit:
roundaboutExit = 1;
break;
case RoundaboutSecondExit:
roundaboutExit = 2;
break;
case RoundaboutThirdExit:
roundaboutExit = 3;
break;
default:
break;
}
if ( roundaboutExit > 0 ) {
if ( roadName.isEmpty() ) {
return QObject::tr( "Take the %1. exit in the roundabout." ).arg( roundaboutExit ); // One sentence
} else {
QString text = QObject::tr( "Take the %1. exit in the roundabout into %2." ); // One sentence
return text.arg( roundaboutExit ).arg( roadName );
}
}
if ( roadName.isEmpty() ) {
switch( turnType ) {
case Continue:
return QObject::tr( "Continue." );
case Merge:
return QObject::tr( "Merge." );
case TurnAround:
return QObject::tr( "Turn around." );
case SharpLeft:
return QObject::tr( "Turn sharp left." );
case Left:
return QObject::tr( "Turn left." );
case SlightLeft:
return QObject::tr( "Keep slightly left." );
case Straight:
return QObject::tr( "Go straight ahead." );
case SlightRight:
return QObject::tr( "Keep slightly right." );
case Right:
return QObject::tr( "Turn right." );
case SharpRight:
return QObject::tr( "Turn sharp right." );
case RoundaboutExit:
return QObject::tr( "Exit the roundabout." );
case Unknown:
case RoundaboutFirstExit:
case RoundaboutSecondExit:
case RoundaboutThirdExit:
Q_ASSERT( false && "Internal error: Unknown/Roundabout should have been handled earlier." );
return QString();
break;
case ExitLeft:
return QObject::tr( "Take the exit to the left." );
case ExitRight:
return QObject::tr( "Take the exit to the right." );
}
} else {
switch( turnType ) {
case Continue:
return QObject::tr( "Continue onto %1." ).arg( roadName );
case Merge:
return QObject::tr( "Merge onto %1." ).arg( roadName );
case TurnAround:
return QObject::tr( "Turn around onto %1." ).arg( roadName );
case SharpLeft:
return QObject::tr( "Turn sharp left on %1." ).arg( roadName );
case Left:
return QObject::tr( "Turn left into %1." ).arg( roadName );
case SlightLeft:
return QObject::tr( "Keep slightly left on %1." ).arg( roadName );
case Straight:
return QObject::tr( "Continue on %1." ).arg( roadName );
case SlightRight:
return QObject::tr( "Keep slightly right on %1." ).arg( roadName );
case Right:
return QObject::tr( "Turn right into %1." ).arg( roadName );
case SharpRight:
return QObject::tr( "Turn sharp right into %1." ).arg( roadName );
case RoundaboutExit:
return QObject::tr( "Exit the roundabout into %2." ).arg( roadName );
case Unknown:
case RoundaboutFirstExit:
case RoundaboutSecondExit:
case RoundaboutThirdExit:
Q_ASSERT( false && "Internal error: Unknown/Roundabout should have been handled earlier." );
return QString();
break;
case ExitLeft:
return QObject::tr( "Take the exit to the left onto %1." ).arg( roadName );
case ExitRight:
return QObject::tr( "Take the exit to the right onto %1." ).arg( roadName );
}
}
Q_ASSERT( false && "Internal error: Switch did not handle all cases.");
return QString();
}
QTextStream& operator<<( QTextStream& stream, const RoutingInstruction &i )
{
stream.setRealNumberPrecision( 8 );
if ( i.points().isEmpty() ) {
return stream;
}
if (QCoreApplication::instance()->arguments().contains(QStringLiteral("--dense"))) {
QVector<RoutingWaypoint> points = i.points();
int maxElement = points.size() - ( i.successor() ? 1 : 0 );
for ( int j = 0; j < maxElement; ++j ) {
stream << points[j].point().lat() << ',';
stream << points[j].point().lon() << ',';
stream << points[j].junctionTypeRaw() << ',';
stream << points[j].roadType() << ',';
stream << points[j].secondsRemaining() << ',';
if ( !j ) {
stream << i.instructionText();
}
if ( j < maxElement - 1 ) {
stream << '\n';
}
}
return stream;
}
if (QCoreApplication::instance()->arguments().contains(QStringLiteral("--csv"))) {
stream << i.points().first().point().lat() << ',';
stream << i.points().first().point().lon() << ',';
} else {
QString distanceUnit = "m ";
int precision = 0;
qreal length = i.distanceFromStart();
if ( length >= 1000 ) {
length /= 1000;
distanceUnit = "km";
precision = 1;
}
QString totalDistance = "[%1 %2] ";
stream << totalDistance.arg( length, 3, 'f', precision ).arg( distanceUnit );
}
stream << i.instructionText();
if (QCoreApplication::instance()->arguments().contains(QStringLiteral("--csv")) &&
QCoreApplication::instance()->arguments().contains(QStringLiteral("--intersection-points"))) {
for ( const RoutingPoint &point: i.intersectionPoints() ) {
stream << ',' << point.lat() << ',' << point.lon();
}
}
return stream;
}
int RoutingInstruction::roundaboutExitNumber() const
{
return m_roundaboutExit;
}
RoutingInstruction::TurnType RoutingInstruction::turnType() const
{
return m_turnType;
}
} // namespace Marble
diff --git a/src/plugins/designer/latloneditwidget/LatLonEditPlugin.h b/src/plugins/designer/latloneditwidget/LatLonEditPlugin.h
index 271cf262c..fe63269a6 100644
--- a/src/plugins/designer/latloneditwidget/LatLonEditPlugin.h
+++ b/src/plugins/designer/latloneditwidget/LatLonEditPlugin.h
@@ -1,45 +1,45 @@
/*
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
*/
//Copyright 2008 Henry de Valence <hdevalence@gmail.com>
#ifndef LATLONEDITPLUGIN_H
#define LATLONEDITPLUGIN_H
#include <QDesignerCustomWidgetInterface>
#include <QObject>
#include <marble_export.h>
class QString;
class QWidget;
class QIcon;
class LatLonEditPlugin : public QObject,
public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.LatLonEditPlugin")
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
- explicit LatLonEditPlugin(QObject *parent = 0);
+ explicit LatLonEditPlugin(QObject *parent = nullptr);
bool isContainer() const override;
bool isInitialized() const override;
QIcon icon() const override;
QString domXml() const override;
QString group() const override;
QString includeFile() const override;
QString name() const override;
QString toolTip() const override;
QString whatsThis() const override;
QWidget *createWidget(QWidget *parent) override;
void initialize(QDesignerFormEditorInterface *core) override;
private:
bool m_initialized;
};
#endif
diff --git a/src/plugins/designer/marblewidget/MarbleWidgetPlugin.h b/src/plugins/designer/marblewidget/MarbleWidgetPlugin.h
index bd85ea008..5c844df86 100644
--- a/src/plugins/designer/marblewidget/MarbleWidgetPlugin.h
+++ b/src/plugins/designer/marblewidget/MarbleWidgetPlugin.h
@@ -1,51 +1,51 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
//
// This class is responsible for offering plugin capabilities.
//
#ifndef MARBLEWIDGETPLUGIN_H
#define MARBLEWIDGETPLUGIN_H
#include <marble_export.h>
// Workaround: moc on osx is unable to find this file, when prefix with QtDesigner/
// moc also doesn't respect Q_OS_* macros, otherwise I could ifdef this.
#include <QDesignerCustomWidgetInterface>
class MarbleWidgetPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.MarbleWidgetPlugin")
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
- explicit MarbleWidgetPlugin(QObject *parent = 0);
+ explicit MarbleWidgetPlugin(QObject *parent = nullptr);
bool isContainer() const override;
bool isInitialized() const override;
QIcon icon() const override;
QString domXml() const override;
QString name() const override;
QString group() const override;
QString includeFile() const override;
QString toolTip() const override;
QString whatsThis() const override;
QWidget *createWidget(QWidget *parent) override;
void initialize(QDesignerFormEditorInterface *core) override;
private:
bool m_initialized;
};
#endif
diff --git a/src/plugins/designer/navigator/MarbleNavigatorPlugin.h b/src/plugins/designer/navigator/MarbleNavigatorPlugin.h
index c32f7ac80..85b7f2e84 100644
--- a/src/plugins/designer/navigator/MarbleNavigatorPlugin.h
+++ b/src/plugins/designer/navigator/MarbleNavigatorPlugin.h
@@ -1,51 +1,51 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2005-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
//
//
// This class is responsible for offering plugin capabilities.
//
#ifndef MARBLENAVIGATORPLUGIN_H
#define MARBLENAVIGATORPLUGIN_H
#include <marble_export.h>
// Workaround: moc on osx is unable to find this file, when prefix with QtDesigner/
// moc also doesn't respect Q_OS_* macros, otherwise I could ifdef this.
#include <QDesignerCustomWidgetInterface>
class MarbleNavigatorPlugin : public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.MarbleNavigatorPlugin")
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
- explicit MarbleNavigatorPlugin(QObject *parent = 0);
+ explicit MarbleNavigatorPlugin(QObject *parent = nullptr);
bool isContainer() const override;
bool isInitialized() const override;
QIcon icon() const override;
QString domXml() const override;
QString name() const override;
QString group() const override;
QString includeFile() const override;
QString toolTip() const override;
QString whatsThis() const override;
QWidget *createWidget(QWidget *parent) override;
void initialize(QDesignerFormEditorInterface *core) override;
private:
bool m_initialized;
};
#endif
diff --git a/src/plugins/positionprovider/flightgear/FlightGearPositionProviderPlugin.cpp b/src/plugins/positionprovider/flightgear/FlightGearPositionProviderPlugin.cpp
index 624b4448f..5acc19724 100644
--- a/src/plugins/positionprovider/flightgear/FlightGearPositionProviderPlugin.cpp
+++ b/src/plugins/positionprovider/flightgear/FlightGearPositionProviderPlugin.cpp
@@ -1,231 +1,231 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Ralf Habacker <ralf.habacker@freenet.de>
//
#include "FlightGearPositionProviderPlugin.h"
#include "MarbleDebug.h"
#include <cmath>
#include <QUdpSocket>
#include <QIcon>
using namespace Marble;
/* TRANSLATOR Marble::FlightGearPositionProviderPlugin */
using namespace std;
FlightGearPositionProviderPlugin::FlightGearPositionProviderPlugin()
- : m_socket(0), m_speed( 0.0 ), m_track( 0.0 )
+ : m_socket(nullptr), m_speed( 0.0 ), m_track( 0.0 )
{
}
FlightGearPositionProviderPlugin::~FlightGearPositionProviderPlugin()
{
delete m_socket;
}
QString FlightGearPositionProviderPlugin::name() const
{
return tr( "FlightGear position provider Plugin" );
}
QString FlightGearPositionProviderPlugin::nameId() const
{
return QStringLiteral("flightgear");
}
QString FlightGearPositionProviderPlugin::guiString() const
{
return tr( "FlightGear" );
}
QString FlightGearPositionProviderPlugin::version() const
{
return QStringLiteral("1.0");
}
QString FlightGearPositionProviderPlugin::description() const
{
return tr( "Reports the position of running flightgear application." );
}
QString FlightGearPositionProviderPlugin::copyrightYears() const
{
return QStringLiteral("2012");
}
QVector<PluginAuthor> FlightGearPositionProviderPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Ralf Habacker"), QStringLiteral("ralf.habacker@freenet.de"));
}
QIcon FlightGearPositionProviderPlugin::icon() const
{
return QIcon();
}
void FlightGearPositionProviderPlugin::initialize()
{
m_status = PositionProviderStatusAcquiring;
emit statusChanged( m_status );
m_socket = new QUdpSocket(this);
m_socket->bind(QHostAddress::LocalHost, 5500);
connect(m_socket, SIGNAL(readyRead()),
this, SLOT(readPendingDatagrams()));
}
/**
fixed case where wrong date format is used '2404112' instead of '240412'
*/
bool fixBadGPRMC(QByteArray &line)
{
if (!line.startsWith("$GPRMC"))
return false;
QStringList parts = QString(line).split(QLatin1Char(','));
if (parts[9].size() == 7) {
parts[9].remove(4,1);
line = parts.join(QLatin1Char(',')).toLatin1();
// update crc
int crc = 0;
for(int i=1; i < line.size()-3; i++) {
crc ^= (int) line[i];
}
parts[11] = parts[11][0] + parts[11][1] + QString::number(crc, 16).toUpper();
line = parts.join(QLatin1Char(',')).toLatin1();
return true;
}
return false;
}
void FlightGearPositionProviderPlugin::readPendingDatagrams()
{
while (m_socket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(m_socket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
m_socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
typedef QList<QByteArray>::Iterator Iterator;
QList<QByteArray> split = datagram.split('\n');
for (Iterator i = split.begin(); i != split.end(); i++) {
fixBadGPRMC(*i);
i->append( "\n" );
parseNmeaSentence( *i );
}
}
}
void FlightGearPositionProviderPlugin::parseNmeaSentence( const QString &sentence )
{
PositionProviderStatus oldStatus = m_status;
GeoDataCoordinates oldPosition = m_position;
if ( sentence.startsWith( QLatin1String( "$GPRMC" ) ) ) {
QStringList const values = sentence.split(QLatin1Char(','));
if ( values.size() > 9 ) {
if (values[2] == QLatin1String("A")) {
m_speed = values[7].toDouble() * 0.514444; // knots => m/s
m_track = values[8].toDouble();
QString const date = values[9] + QLatin1Char(' ') + values[1];
m_timestamp = QDateTime::fromString( date, "ddMMyy HHmmss" );
if (m_timestamp.date().year() <= 1930 && m_timestamp.date().year() >= 1900 ) {
m_timestamp = m_timestamp.addYears( 100 ); // Qt range is 1900-1999 for two-digits
}
}
// Flightgear submits geoposition twice in one datagram, once
// in GPRMC and once in GPGGA. Parsing one is sufficient
}
} else if ( sentence.startsWith( QLatin1String( "$GPGGA" ) ) ) {
QStringList const values = sentence.split(QLatin1Char(','));
if ( values.size() > 10 ) {
- if ( values[6] == 0 ) {
+ if ( values[6] == nullptr ) {
m_status = PositionProviderStatusAcquiring; // no fix
} else {
double const lat = parsePosition(values[2], values[3] == QLatin1String("S"));
double const lon = parsePosition(values[4], values[5] == QLatin1String("W"));
double const unitFactor = values[10] == QLatin1String("F") ? FT2M : 1.0;
double const alt = unitFactor * values[9].toDouble();
m_position.set( lon, lat, alt, GeoDataCoordinates::Degree );
m_accuracy.level = GeoDataAccuracy::Detailed;
m_status = PositionProviderStatusAvailable;
}
}
} else {
return;
}
if ( m_status != oldStatus ) {
emit statusChanged( m_status );
}
if ( m_position != oldPosition && m_status == PositionProviderStatusAvailable ) {
emit positionChanged( m_position, m_accuracy );
}
}
double FlightGearPositionProviderPlugin::parsePosition( const QString &value, bool isNegative )
{
double pos = value.toDouble();
pos = int( pos / 100.0 ) + ( pos - 100.0 * int( pos / 100.0 ) ) / 60.0;
return isNegative ? -qAbs( pos ) : pos;
}
bool FlightGearPositionProviderPlugin::isInitialized() const
{
return m_socket;
}
PositionProviderPlugin* FlightGearPositionProviderPlugin::newInstance() const
{
return new FlightGearPositionProviderPlugin;
}
PositionProviderStatus FlightGearPositionProviderPlugin::status() const
{
return m_status;
}
GeoDataCoordinates FlightGearPositionProviderPlugin::position() const
{
return m_position;
}
GeoDataAccuracy FlightGearPositionProviderPlugin::accuracy() const
{
return m_accuracy;
}
qreal FlightGearPositionProviderPlugin::speed() const
{
return m_speed;
}
qreal FlightGearPositionProviderPlugin::direction() const
{
return m_track;
}
QDateTime FlightGearPositionProviderPlugin::timestamp() const
{
return m_timestamp;
}
QString FlightGearPositionProviderPlugin::error() const
{
return QString();
}
#include "moc_FlightGearPositionProviderPlugin.cpp"
diff --git a/src/plugins/positionprovider/gpsd/GpsdConnection.cpp b/src/plugins/positionprovider/gpsd/GpsdConnection.cpp
index ca9d84173..e67c9b8f8 100644
--- a/src/plugins/positionprovider/gpsd/GpsdConnection.cpp
+++ b/src/plugins/positionprovider/gpsd/GpsdConnection.cpp
@@ -1,144 +1,144 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
// Copyright 2011 Bastian Holst <bastianholst@gmx.de>
//
#include "GpsdConnection.h"
#include "MarbleDebug.h"
#include <QTime>
#include <cerrno>
#include <clocale>
using namespace Marble;
/* TRANSLATOR Marble::GpsdConnection */
const int gpsUpdateInterval = 1000; // ms
const int gpsWaitTimeout = 200; // ms
GpsdConnection::GpsdConnection( QObject* parent )
: QObject( parent ),
#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 5 )
m_gpsd( "localhost", DEFAULT_GPSD_PORT ),
#endif
- m_timer( 0 )
+ m_timer( nullptr )
{
- m_oldLocale = setlocale( LC_NUMERIC, NULL );
+ m_oldLocale = setlocale( LC_NUMERIC, nullptr );
setlocale( LC_NUMERIC, "C" );
connect( &m_timer, SIGNAL(timeout()), this, SLOT(update()) );
}
GpsdConnection::~GpsdConnection()
{
setlocale( LC_NUMERIC, m_oldLocale );
}
void GpsdConnection::initialize()
{
m_timer.stop();
bool success = false;
#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 5 )
success = true;
#else
gps_data_t* data = m_gpsd.open();
success = ( data != 0 );
#endif
#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 3 ) && defined( WATCH_ENABLE )
if ( success ) {
- success = (m_gpsd.stream( WATCH_ENABLE ) != NULL);
+ success = (m_gpsd.stream( WATCH_ENABLE ) != nullptr);
}
#endif
if ( success ) {
m_status = PositionProviderStatusAcquiring;
emit statusChanged( m_status );
m_timer.start( gpsUpdateInterval );
}
else {
// There is also gps_errstr() for libgps version >= 2.90,
// but it doesn't return a sensible error description
switch ( errno ) {
case NL_NOSERVICE:
m_error = tr("Internal gpsd error (cannot get service entry)");
break;
case NL_NOHOST:
m_error = tr("Internal gpsd error (cannot get host entry)");
break;
case NL_NOPROTO:
m_error = tr("Internal gpsd error (cannot get protocol entry)");
break;
case NL_NOSOCK:
m_error = tr("Internal gpsd error (unable to create socket)");
break;
case NL_NOSOCKOPT:
m_error = tr("Internal gpsd error (unable to set socket option)");
break;
case NL_NOCONNECT:
m_error = tr("No GPS device found by gpsd.");
break;
default:
m_error = tr("Unknown error when opening gpsd connection");
break;
}
m_status = PositionProviderStatusError;
emit statusChanged( m_status );
mDebug() << "Connection to gpsd failed, no position info available: " << m_error;
}
}
void GpsdConnection::update()
{
#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 4 ) && defined( PACKET_SET )
- gps_data_t *data = 0;
+ gps_data_t *data = nullptr;
QTime watchdog;
watchdog.start();
#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 5 )
while ( m_gpsd.waiting( 0 ) && watchdog.elapsed() < gpsWaitTimeout ) {
gps_data_t *currentData = m_gpsd.read();
#else
while ( m_gpsd.waiting() && watchdog.elapsed() < gpsWaitTimeout ) {
gps_data_t *currentData = m_gpsd.poll();
#endif
if( currentData && currentData->set & PACKET_SET ) {
data = currentData;
}
}
if ( data ) {
emit gpsdInfo( *data );
}
#else
#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION == 3 ) && defined( PACKET_SET )
gps_data_t *data = m_gpsd.poll();
#else
gps_data_t* data = m_gpsd.query( "o" );
#endif
if ( data ) {
emit gpsdInfo( *data );
}
else if ( m_status != PositionProviderStatusAcquiring ) {
mDebug() << "Lost connection to gpsd, trying to re-open.";
initialize();
}
#endif
}
QString GpsdConnection::error() const
{
return m_error;
}
#include "moc_GpsdConnection.cpp"
diff --git a/src/plugins/positionprovider/gpsd/GpsdConnection.h b/src/plugins/positionprovider/gpsd/GpsdConnection.h
index 96af7ef6f..d7641df11 100644
--- a/src/plugins/positionprovider/gpsd/GpsdConnection.h
+++ b/src/plugins/positionprovider/gpsd/GpsdConnection.h
@@ -1,57 +1,57 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
//
#ifndef GPSDCONNECTION_H
#define GPSDCONNECTION_H
#include "PositionProviderPlugin.h"
#include <QObject>
#include <QTimer>
#include <libgpsmm.h>
namespace Marble
{
class GpsdConnection : public QObject
{
Q_OBJECT
public:
- explicit GpsdConnection( QObject* parent = 0 );
+ explicit GpsdConnection( QObject* parent = nullptr );
~GpsdConnection() override;
void initialize();
QString error() const;
Q_SIGNALS:
void gpsdInfo( gps_data_t data );
void statusChanged( PositionProviderStatus status ) const;
private:
void open();
gpsmm m_gpsd;
QTimer m_timer;
PositionProviderStatus m_status;
QString m_error;
const char* m_oldLocale;
private Q_SLOTS:
void update();
};
}
#endif
diff --git a/src/plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.cpp b/src/plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.cpp
index bf8949a97..5d199ceac 100644
--- a/src/plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.cpp
+++ b/src/plugins/positionprovider/gpsd/GpsdPositionProviderPlugin.cpp
@@ -1,194 +1,194 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
//
#include "GpsdPositionProviderPlugin.h"
#include "GpsdThread.h"
#include "MarbleDebug.h"
#include <QIcon>
#include <cmath>
using namespace Marble;
/* TRANSLATOR Marble::GpsdPositionProviderPlugin */
QString GpsdPositionProviderPlugin::name() const
{
return tr( "Gpsd position provider Plugin" );
}
QString GpsdPositionProviderPlugin::nameId() const
{
return QStringLiteral("Gpsd");
}
QString GpsdPositionProviderPlugin::guiString() const
{
return tr( "gpsd" );
}
QString GpsdPositionProviderPlugin::version() const
{
return QStringLiteral("1.0");
}
QString GpsdPositionProviderPlugin::description() const
{
return tr( "Reports the position of a GPS device." );
}
QString GpsdPositionProviderPlugin::copyrightYears() const
{
return QStringLiteral("2009");
}
QVector<PluginAuthor> GpsdPositionProviderPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Eckhart Wörner"), QStringLiteral("ewoerner@kde.org"));
}
QIcon GpsdPositionProviderPlugin::icon() const
{
return QIcon();
}
void GpsdPositionProviderPlugin::initialize()
{
m_status = PositionProviderStatusAcquiring;
emit statusChanged( m_status );
m_thread = new GpsdThread;
connect( m_thread, SIGNAL(gpsdInfo(gps_data_t)),
this, SLOT(update(gps_data_t)) );
connect( m_thread, SIGNAL(statusChanged(PositionProviderStatus)),
this, SIGNAL(statusChanged(PositionProviderStatus)) );
m_thread->start();
}
void GpsdPositionProviderPlugin::update( gps_data_t data )
{
PositionProviderStatus oldStatus = m_status;
GeoDataCoordinates oldPosition = m_position;
if ( data.status == STATUS_NO_FIX || std::isnan( data.fix.longitude ) || std::isnan( data.fix.latitude ) )
m_status = PositionProviderStatusAcquiring;
else {
m_status = PositionProviderStatusAvailable;
m_position.set( data.fix.longitude, data.fix.latitude,
data.fix.altitude, GeoDataCoordinates::Degree );
if (data.fix.mode == MODE_2D) {
m_position.setAltitude(0);
}
m_accuracy.level = GeoDataAccuracy::Detailed;
#if defined( GPSD_API_MAJOR_VERSION ) && ( GPSD_API_MAJOR_VERSION >= 3 )
if ( !std::isnan( data.fix.epx ) && !std::isnan( data.fix.epy ) ) {
m_accuracy.horizontal = qMax( data.fix.epx, data.fix.epy );
}
#else
if ( !std::isnan( data.fix.eph ) ) {
m_accuracy.horizontal = data.fix.eph;
}
#endif
if ( !std::isnan( data.fix.epv ) ) {
m_accuracy.vertical = data.fix.epv;
}
if( !std::isnan(data.fix.speed ) )
{
m_speed = data.fix.speed;
}
if( !std::isnan( data.fix.track ) )
{
m_track = data.fix.track;
}
if ( !std::isnan( data.fix.time ) )
{
m_timestamp = QDateTime::fromMSecsSinceEpoch( data.fix.time * 1000 );
}
}
if (m_status != oldStatus)
emit statusChanged( m_status );
if (!(oldPosition == m_position)) {
emit positionChanged( m_position, m_accuracy );
}
}
bool GpsdPositionProviderPlugin::isInitialized() const
{
return m_thread;
}
PositionProviderPlugin* GpsdPositionProviderPlugin::newInstance() const
{
return new GpsdPositionProviderPlugin;
}
PositionProviderStatus GpsdPositionProviderPlugin::status() const
{
return m_status;
}
GeoDataCoordinates GpsdPositionProviderPlugin::position() const
{
return m_position;
}
GeoDataAccuracy GpsdPositionProviderPlugin::accuracy() const
{
return m_accuracy;
}
-GpsdPositionProviderPlugin::GpsdPositionProviderPlugin() : m_thread( 0 ),
+GpsdPositionProviderPlugin::GpsdPositionProviderPlugin() : m_thread( nullptr ),
m_speed( 0.0 ),
m_track( 0.0 )
{
}
GpsdPositionProviderPlugin::~GpsdPositionProviderPlugin()
{
if ( m_thread ) {
m_thread->exit();
if ( !m_thread->wait( 5000 ) ) {
mDebug() << "Failed to stop GpsdThread";
}
else {
delete m_thread;
}
}
}
qreal GpsdPositionProviderPlugin::speed() const
{
return m_speed;
}
qreal GpsdPositionProviderPlugin::direction() const
{
return m_track;
}
QDateTime GpsdPositionProviderPlugin::timestamp() const
{
return m_timestamp;
}
QString GpsdPositionProviderPlugin::error() const
{
return m_thread->error();
}
#include "moc_GpsdPositionProviderPlugin.cpp"
diff --git a/src/plugins/positionprovider/gpsd/GpsdThread.cpp b/src/plugins/positionprovider/gpsd/GpsdThread.cpp
index ec833a239..3d9954c0e 100644
--- a/src/plugins/positionprovider/gpsd/GpsdThread.cpp
+++ b/src/plugins/positionprovider/gpsd/GpsdThread.cpp
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
//
#include "GpsdThread.h"
#include <QMetaType>
#include "GpsdConnection.h"
namespace Marble
{
-GpsdThread::GpsdThread() : m_connection( 0 )
+GpsdThread::GpsdThread() : m_connection( nullptr )
{
// nothing to do
}
GpsdThread::~GpsdThread()
{
delete m_connection;
}
void GpsdThread::run()
{
qRegisterMetaType<gps_data_t>( "gps_data_t" );
qRegisterMetaType<PositionProviderStatus>("PositionProviderStatus");
m_connection = new GpsdConnection;
connect( m_connection, SIGNAL(statusChanged(PositionProviderStatus)),
this, SIGNAL(statusChanged(PositionProviderStatus)) );
connect( m_connection, SIGNAL(gpsdInfo(gps_data_t)),
this, SIGNAL(gpsdInfo(gps_data_t)) );
m_connection->initialize();
exec();
}
QString GpsdThread::error() const
{
return m_connection->error();
}
} // namespace Marble
#include "moc_GpsdThread.cpp"
diff --git a/src/plugins/positionprovider/qtpositioning/QtPositioningPositionProviderPlugin.cpp b/src/plugins/positionprovider/qtpositioning/QtPositioningPositionProviderPlugin.cpp
index 698461f19..31c60b4aa 100644
--- a/src/plugins/positionprovider/qtpositioning/QtPositioningPositionProviderPlugin.cpp
+++ b/src/plugins/positionprovider/qtpositioning/QtPositioningPositionProviderPlugin.cpp
@@ -1,221 +1,221 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Daniel Marth <danielmarth@gmx.at>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "QtPositioningPositionProviderPlugin.h"
#include "GeoDataAccuracy.h"
#include "GeoDataCoordinates.h"
#include <QGeoPositionInfoSource>
#include <QGeoCoordinate>
#include <QTimer>
#include <QIcon>
namespace Marble {
class QtPositioningPositionProviderPluginPrivate
{
public:
QtPositioningPositionProviderPluginPrivate();
~QtPositioningPositionProviderPluginPrivate();
QGeoPositionInfoSource* m_source;
PositionProviderStatus m_status;
QTimer * m_updateChecker;
QGeoPositionInfo m_lastKnownPosition;
};
QtPositioningPositionProviderPluginPrivate::QtPositioningPositionProviderPluginPrivate() :
m_source( nullptr ),
m_status( PositionProviderStatusUnavailable ),
m_updateChecker( new QTimer )
{
}
QtPositioningPositionProviderPluginPrivate::~QtPositioningPositionProviderPluginPrivate()
{
delete m_source;
}
QString QtPositioningPositionProviderPlugin::name() const
{
return tr( "Qt Positioning Position Provider Plugin" );
}
QString QtPositioningPositionProviderPlugin::nameId() const
{
return QStringLiteral("QtPositioning");
}
QString QtPositioningPositionProviderPlugin::guiString() const
{
return tr( "Qt Positioning Location" );
}
QString QtPositioningPositionProviderPlugin::version() const
{
return QStringLiteral("1.0");
}
QString QtPositioningPositionProviderPlugin::description() const
{
return tr( "Reports the GPS position of a QtPositioning compatible device." );
}
QString QtPositioningPositionProviderPlugin::copyrightYears() const
{
return QStringLiteral("2011-2016");
}
QVector<PluginAuthor> QtPositioningPositionProviderPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Daniel Marth"), QStringLiteral("danielmarth@gmx.at"));
}
QIcon QtPositioningPositionProviderPlugin::icon() const
{
return QIcon();
}
PositionProviderPlugin* QtPositioningPositionProviderPlugin::newInstance() const
{
return new QtPositioningPositionProviderPlugin;
}
PositionProviderStatus QtPositioningPositionProviderPlugin::status() const
{
return d->m_status;
}
GeoDataCoordinates QtPositioningPositionProviderPlugin::position() const
{
- if ( d->m_source == 0 ) {
+ if ( d->m_source == nullptr ) {
return GeoDataCoordinates();
}
const QGeoCoordinate p = d->m_lastKnownPosition.coordinate();
if( !p.isValid() ) {
return GeoDataCoordinates();
}
return GeoDataCoordinates( p.longitude(), p.latitude(),
p.altitude(), GeoDataCoordinates::Degree );
}
GeoDataAccuracy QtPositioningPositionProviderPlugin::accuracy() const
{
- if ( d->m_source == 0 ) {
+ if ( d->m_source == nullptr ) {
return GeoDataAccuracy();
}
const QGeoPositionInfo info = d->m_lastKnownPosition;
const qreal horizontal = info.attribute( QGeoPositionInfo::HorizontalAccuracy );
const qreal vertical = info.attribute( QGeoPositionInfo::VerticalAccuracy );
GeoDataAccuracy::Level const level = horizontal > 0 ? GeoDataAccuracy::Detailed : GeoDataAccuracy::none;
return GeoDataAccuracy( level, horizontal, vertical );
}
QtPositioningPositionProviderPlugin::QtPositioningPositionProviderPlugin() :
d( new QtPositioningPositionProviderPluginPrivate )
{
}
QtPositioningPositionProviderPlugin::~QtPositioningPositionProviderPlugin()
{
delete d->m_updateChecker;
delete d;
}
void QtPositioningPositionProviderPlugin::initialize()
{
d->m_source = QGeoPositionInfoSource::createDefaultSource( this );
if( d->m_source ) {
d->m_status = PositionProviderStatusAcquiring;
emit statusChanged(d->m_status);
connect( d->m_updateChecker, SIGNAL(timeout()), this, SLOT(update()) );
connect( d->m_source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(update(QGeoPositionInfo)) );
d->m_source->setUpdateInterval( 1000 );
d->m_source->startUpdates();
d->m_updateChecker->start( 5000 );
}
}
bool QtPositioningPositionProviderPlugin::isInitialized() const
{
- return d->m_source != 0;
+ return d->m_source != nullptr;
}
qreal QtPositioningPositionProviderPlugin::speed() const
{
- if ( d->m_source == 0 ) {
+ if ( d->m_source == nullptr ) {
return 0.0;
}
if( !d->m_lastKnownPosition.hasAttribute( QGeoPositionInfo::GroundSpeed ) ) {
return 0.0;
}
return d->m_lastKnownPosition.attribute( QGeoPositionInfo::GroundSpeed );
}
qreal QtPositioningPositionProviderPlugin::direction() const
{
- if ( d->m_source == 0 ) {
+ if ( d->m_source == nullptr ) {
return 0.0;
}
if( !d->m_lastKnownPosition.hasAttribute( QGeoPositionInfo::Direction ) ) {
return 0.0;
}
return d->m_lastKnownPosition.attribute( QGeoPositionInfo::Direction );
}
QDateTime QtPositioningPositionProviderPlugin::timestamp() const
{
- if ( d->m_source == 0 ) {
+ if ( d->m_source == nullptr ) {
return QDateTime();
}
return d->m_lastKnownPosition.timestamp();
}
void QtPositioningPositionProviderPlugin::update()
{
if ( d->m_source ) {
update(d->m_source->lastKnownPosition());
}
}
void QtPositioningPositionProviderPlugin::update(const QGeoPositionInfo& geoPositionInfo)
{
PositionProviderStatus newStatus = geoPositionInfo.isValid() ?
PositionProviderStatusAvailable :
PositionProviderStatusError;
if (geoPositionInfo.isValid()) {
d->m_lastKnownPosition = geoPositionInfo;
}
if (newStatus != d->m_status) {
d->m_status = newStatus;
emit statusChanged(d->m_status);
}
if (newStatus == PositionProviderStatusAvailable) {
emit positionChanged(position(), accuracy());
}
}
} // namespace Marble
#include "moc_QtPositioningPositionProviderPlugin.cpp"
diff --git a/src/plugins/positionprovider/wlocate/WlocatePositionProviderPlugin.cpp b/src/plugins/positionprovider/wlocate/WlocatePositionProviderPlugin.cpp
index 30d7425bb..18ced677e 100644
--- a/src/plugins/positionprovider/wlocate/WlocatePositionProviderPlugin.cpp
+++ b/src/plugins/positionprovider/wlocate/WlocatePositionProviderPlugin.cpp
@@ -1,203 +1,203 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "WlocatePositionProviderPlugin.h"
#include <GeoDataCoordinates.h>
#include <GeoDataAccuracy.h>
#include <QFutureWatcher>
#include <QtConcurrentRun>
#include <QDateTime>
#include <QIcon>
#ifndef ENV_LINUX
#define ENV_LINUX
#define MARBLE_NEEDS_TO_CLEANUP_FOREIGN_WLOCATE_DEFINE
#include <libwlocate.h>
#endif
#ifdef MARBLE_NEEDS_TO_CLEANUP_FOREIGN_WLOCATE_DEFINE
#undef MARBLE_NEEDS_TO_CLEANUP_FOREIGN_WLOCATE_DEFINE
#undef ENV_LINUX
#endif
namespace Marble {
class WlocatePositionProviderPluginPrivate
{
public:
PositionProviderStatus m_status;
qreal m_speed;
qreal m_direction;
QDateTime m_timestamp;
double m_longitude;
double m_latitude;
bool m_initialized;
char m_quality;
short m_ccode;
QFutureWatcher<int>* m_futureWatcher;
WlocatePositionProviderPluginPrivate();
~WlocatePositionProviderPluginPrivate();
};
WlocatePositionProviderPluginPrivate::WlocatePositionProviderPluginPrivate() :
m_status( PositionProviderStatusAcquiring ), m_speed( 0 ), m_direction( 0 ),
m_longitude( 0.0 ), m_latitude( 0.0 ), m_initialized( false ),
- m_quality( 0 ), m_ccode( 0 ), m_futureWatcher( 0 )
+ m_quality( 0 ), m_ccode( 0 ), m_futureWatcher( nullptr )
{
// nothing to do
}
WlocatePositionProviderPluginPrivate::~WlocatePositionProviderPluginPrivate()
{
// nothing to do
}
QString WlocatePositionProviderPlugin::name() const
{
return tr( "Wlocate Position Provider Plugin" );
}
QString WlocatePositionProviderPlugin::nameId() const
{
return QStringLiteral("WlocatePositionProvider");
}
QString WlocatePositionProviderPlugin::guiString() const
{
return tr( "WLAN (Open WLAN Map)" );
}
QString WlocatePositionProviderPlugin::version() const
{
return QStringLiteral("1.0");
}
QString WlocatePositionProviderPlugin::description() const
{
return tr( "Reports the current position based on nearby WLAN access points" );
}
QString WlocatePositionProviderPlugin::copyrightYears() const
{
return QStringLiteral("2012");
}
QVector<PluginAuthor> WlocatePositionProviderPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"));
}
QIcon WlocatePositionProviderPlugin::icon() const
{
return QIcon();
}
PositionProviderPlugin* WlocatePositionProviderPlugin::newInstance() const
{
return new WlocatePositionProviderPlugin;
}
PositionProviderStatus WlocatePositionProviderPlugin::status() const
{
return d->m_status;
}
GeoDataCoordinates WlocatePositionProviderPlugin::position() const
{
return GeoDataCoordinates( d->m_longitude, d->m_latitude, 0.0, GeoDataCoordinates::Degree );
}
qreal WlocatePositionProviderPlugin::speed() const
{
return d->m_speed;
}
qreal WlocatePositionProviderPlugin::direction() const
{
return d->m_direction;
}
GeoDataAccuracy WlocatePositionProviderPlugin::accuracy() const
{
GeoDataAccuracy result;
if ( status() == PositionProviderStatusAvailable ) {
result.level = GeoDataAccuracy::Detailed;
/** @todo: Try mapping the accuracy percentage returned by libwlocate to something useful */
result.horizontal = 0;
result.vertical = 0;
}
else {
result.level = GeoDataAccuracy::none;
result.horizontal = 0;
result.vertical = 0;
}
return result;
}
QDateTime WlocatePositionProviderPlugin::timestamp() const
{
return d->m_timestamp;
}
WlocatePositionProviderPlugin::WlocatePositionProviderPlugin() :
d( new WlocatePositionProviderPluginPrivate )
{
// nothing to do
}
WlocatePositionProviderPlugin::~WlocatePositionProviderPlugin()
{
delete d;
}
void WlocatePositionProviderPlugin::initialize()
{
d->m_initialized = true;
update();
}
bool WlocatePositionProviderPlugin::isInitialized() const
{
return d->m_initialized;
}
void WlocatePositionProviderPlugin::update()
{
if ( !d->m_futureWatcher ) {
d->m_futureWatcher = new QFutureWatcher<int>( this );
connect( d->m_futureWatcher, SIGNAL(finished()), this, SLOT(handleWlocateResult()) );
}
QFuture<int> future = QtConcurrent::run( &wloc_get_location, &d->m_latitude, &d->m_longitude, &d->m_quality, &d->m_ccode );
d->m_futureWatcher->setFuture( future );
}
void WlocatePositionProviderPlugin::handleWlocateResult()
{
if ( d->m_futureWatcher->isFinished() ) {
int const returnCode = d->m_futureWatcher->result();
d->m_status = returnCode == WLOC_OK ? PositionProviderStatusAvailable : PositionProviderStatusError;
if ( d->m_status == PositionProviderStatusAvailable ) {
d->m_timestamp = QDateTime::currentDateTimeUtc();
emit positionChanged( position(), accuracy() );
}
}
}
} // namespace Marble
#include "moc_WlocatePositionProviderPlugin.cpp"
diff --git a/src/plugins/render/annotate/AnnotatePlugin.cpp b/src/plugins/render/annotate/AnnotatePlugin.cpp
index 8cf73926f..f4a485b51 100644
--- a/src/plugins/render/annotate/AnnotatePlugin.cpp
+++ b/src/plugins/render/annotate/AnnotatePlugin.cpp
@@ -1,1792 +1,1792 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Andrew Manson <g.real.ate@gmail.com>
// Copyright 2013 Thibaut Gridel <tgridel@free.fr>
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
// Self
#include "AnnotatePlugin.h"
// Qt
#include <QFileDialog>
#include <QAction>
#include <QMessageBox>
#include <QtAlgorithms>
#include <QColor>
#include <QApplication>
// Marble
#include "MarbleDebug.h"
#include "EditGroundOverlayDialog.h"
#include "EditPlacemarkDialog.h"
#include "EditPolygonDialog.h"
#include "GeoDataDocument.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataLatLonBox.h"
#include "GeoDataParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataStyle.h"
#include "GeoDataLabelStyle.h"
#include "GeoDataLineStyle.h"
#include "GeoDataPoint.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataTreeModel.h"
#include "GeoPainter.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoWriter.h"
#include "KmlElementDictionary.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "MarblePlacemarkModel.h"
#include "MarbleWidget.h"
#include "AreaAnnotation.h"
#include "PlacemarkTextAnnotation.h"
#include "TextureLayer.h"
#include "SceneGraphicsTypes.h"
#include "MergingPolygonNodesAnimation.h"
#include "MergingPolylineNodesAnimation.h"
#include "MarbleWidgetPopupMenu.h"
#include "PolylineAnnotation.h"
#include "EditPolylineDialog.h"
#include "ParsingRunnerManager.h"
#include "ViewportParams.h"
#include "osm/OsmPlacemarkData.h"
#include "DownloadOsmDialog.h"
namespace Marble
{
AnnotatePlugin::AnnotatePlugin( const MarbleModel *model )
: RenderPlugin( model ),
m_isInitialized( false ),
m_widgetInitialized( false ),
- m_marbleWidget( 0 ),
+ m_marbleWidget( nullptr ),
m_overlayRmbMenu(nullptr),
m_polygonRmbMenu(nullptr),
m_nodeRmbMenu(nullptr),
m_textAnnotationRmbMenu(nullptr),
m_polylineRmbMenu(nullptr),
m_annotationDocument(nullptr),
- m_movedItem( 0 ),
- m_focusItem( 0 ),
- m_polylinePlacemark( 0 ),
- m_polygonPlacemark( 0 ),
- m_clipboardItem( 0 ),
+ m_movedItem( nullptr ),
+ m_focusItem( nullptr ),
+ m_polylinePlacemark( nullptr ),
+ m_polygonPlacemark( nullptr ),
+ m_clipboardItem( nullptr ),
m_drawingPolygon( false ),
m_drawingPolyline( false ),
m_addingPlacemark( false ),
m_editingDialogIsShown( false )
{
setEnabled( true );
setVisible( true );
connect( this, SIGNAL(visibilityChanged(bool,QString)), SLOT(enableModel(bool)) );
}
AnnotatePlugin::~AnnotatePlugin()
{
qDeleteAll( m_graphicsItems );
if ( m_marbleWidget ) {
m_marbleWidget->model()->treeModel()->removeDocument( m_annotationDocument );
}
delete m_overlayRmbMenu;
delete m_polygonRmbMenu;
delete m_nodeRmbMenu;
delete m_textAnnotationRmbMenu;
delete m_polylineRmbMenu;
delete m_annotationDocument;
// delete m_networkAccessManager;
delete m_clipboardItem;
qDeleteAll(m_actions);
disconnect( this, SIGNAL(mouseMoveGeoPosition(QString)), m_marbleWidget, SIGNAL(mouseMoveGeoPosition(QString)) );
}
QStringList AnnotatePlugin::backendTypes() const
{
return QStringList(QStringLiteral("annotation"));
}
QString AnnotatePlugin::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList AnnotatePlugin::renderPosition() const
{
return QStringList(QStringLiteral("ALWAYS_ON_TOP"));
}
QString AnnotatePlugin::name() const
{
return tr( "Annotation" );
}
QString AnnotatePlugin::guiString() const
{
return tr( "&Annotation" );
}
QString AnnotatePlugin::nameId() const
{
return QStringLiteral("annotation");
}
QString AnnotatePlugin::description() const
{
return tr( "Draws annotations on maps with placemarks or polygons." );
}
QString AnnotatePlugin::version() const
{
return QStringLiteral("1.0");
}
QString AnnotatePlugin::copyrightYears() const
{
return QStringLiteral("2009, 2013");
}
QVector<PluginAuthor> AnnotatePlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Andrew Manson"), QStringLiteral("g.real.ate@gmail.com"))
<< PluginAuthor(QStringLiteral("Thibaut Gridel"), QStringLiteral("tgridel@free.fr"))
<< PluginAuthor(QStringLiteral("Calin Cruceru"), QStringLiteral("crucerucalincristian@gmail.com"));
}
QIcon AnnotatePlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/draw-placemark.png"));
}
void AnnotatePlugin::initialize()
{
if ( !m_isInitialized ) {
m_widgetInitialized = false;
delete m_polygonPlacemark;
- m_polygonPlacemark = 0;
+ m_polygonPlacemark = nullptr;
delete m_movedItem;
- m_movedItem = 0;
+ m_movedItem = nullptr;
m_drawingPolygon = false;
m_drawingPolyline = false;
m_addingPlacemark = false;
delete m_annotationDocument;
m_annotationDocument = new GeoDataDocument;
m_annotationDocument->setName( tr("Annotations") );
m_annotationDocument->setDocumentRole( UserDocument );
// Default polygon style
GeoDataStyle::Ptr defaultPolygonStyle(new GeoDataStyle);
GeoDataPolyStyle polyStyle;
GeoDataLineStyle edgeStyle;
GeoDataLabelStyle labelStyle;
QColor polygonColor = QApplication::palette().highlight().color();
QColor edgeColor = QApplication::palette().light().color();
QColor labelColor = QApplication::palette().brightText().color();
polygonColor.setAlpha( 80 );
polyStyle.setColor( polygonColor );
edgeStyle.setColor( edgeColor );
labelStyle.setColor( labelColor );
defaultPolygonStyle->setId(QStringLiteral("polygon"));
defaultPolygonStyle->setPolyStyle( polyStyle );
defaultPolygonStyle->setLineStyle( edgeStyle );
defaultPolygonStyle->setLabelStyle( labelStyle );
m_annotationDocument->addStyle( defaultPolygonStyle );
// Default polyline style
GeoDataStyle::Ptr defaultPolylineStyle(new GeoDataStyle);
GeoDataLineStyle lineStyle;
QColor polylineColor = Qt::white;
lineStyle.setColor( polylineColor );
lineStyle.setWidth( 1 );
defaultPolylineStyle->setId(QStringLiteral("polyline"));
defaultPolylineStyle->setLineStyle( lineStyle );
defaultPolylineStyle->setLabelStyle( labelStyle );
m_annotationDocument->addStyle( defaultPolylineStyle );
m_isInitialized = true;
}
}
bool AnnotatePlugin::isInitialized() const
{
return m_isInitialized;
}
QString AnnotatePlugin::runtimeTrace() const
{
return QStringLiteral("Annotate Items: %1").arg(m_annotationDocument->size());
}
const QList<QActionGroup*> *AnnotatePlugin::actionGroups() const
{
return &m_actions;
}
bool AnnotatePlugin::render(GeoPainter *painter, ViewportParams *viewport, const QString &renderPos, GeoSceneLayer *layer)
{
Q_UNUSED( renderPos );
Q_UNUSED( layer );
QListIterator<SceneGraphicsItem*> iter( m_graphicsItems );
while ( iter.hasNext() ) {
iter.next()->paint( painter, viewport, "Annotation", -1 );
}
return true;
}
void AnnotatePlugin::enableModel( bool enabled )
{
if ( enabled ) {
if ( m_marbleWidget ) {
setupActions( m_marbleWidget );
m_marbleWidget->model()->treeModel()->addDocument( m_annotationDocument );
}
} else {
- setupActions( 0 );
+ setupActions( nullptr );
if ( m_marbleWidget ) {
m_marbleWidget->model()->treeModel()->removeDocument( m_annotationDocument );
}
}
}
void AnnotatePlugin::setAddingPolygonHole( bool enabled )
{
if ( enabled ) {
announceStateChanged( SceneGraphicsItem::AddingPolygonHole );
} else {
announceStateChanged( SceneGraphicsItem::Editing );
}
}
void AnnotatePlugin::setAddingNodes( bool enabled )
{
if ( enabled ) {
announceStateChanged( SceneGraphicsItem::AddingNodes );
} else {
announceStateChanged( SceneGraphicsItem::Editing );
}
}
void AnnotatePlugin::setAreaAvailable()
{
static_cast<AreaAnnotation*>( m_focusItem )->setBusy( false );
announceStateChanged( SceneGraphicsItem::Editing );
enableAllActions( m_actions.first() );
disableFocusActions();
enableActionsOnItemType( SceneGraphicsTypes::SceneGraphicAreaAnnotation );
emit repaintNeeded();
}
void AnnotatePlugin::setPolylineAvailable()
{
static_cast<PolylineAnnotation*>( m_focusItem )->setBusy( false );
announceStateChanged( SceneGraphicsItem::Editing );
enableAllActions( m_actions.first() );
disableFocusActions();
enableActionsOnItemType( SceneGraphicsTypes::SceneGraphicPolylineAnnotation );
emit repaintNeeded();
}
void AnnotatePlugin::askToRemoveFocusItem()
{
const int result = QMessageBox::question( m_marbleWidget,
QObject::tr( "Remove current item" ),
QObject::tr( "Are you sure you want to remove the current item?" ),
QMessageBox::Yes | QMessageBox::No );
if ( result == QMessageBox::Yes ) {
removeFocusItem();
}
}
void AnnotatePlugin::removeFocusItem()
{
// Ground Overlays will always be a special case..
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicGroundOverlay ) {
for ( int i = 0; i < m_groundOverlayModel.rowCount(); ++i ) {
const QModelIndex index = m_groundOverlayModel.index( i, 0 );
GeoDataGroundOverlay *overlay = dynamic_cast<GeoDataGroundOverlay*>(
qvariant_cast<GeoDataObject*>( index.data( MarblePlacemarkModel::ObjectPointerRole ) ) );
m_marbleWidget->model()->treeModel()->removeFeature( overlay );
}
clearOverlayFrames();
} else {
disableFocusActions();
m_graphicsItems.removeAll( m_focusItem );
m_marbleWidget->model()->treeModel()->removeFeature( m_focusItem->placemark() );
delete m_focusItem->placemark();
delete m_focusItem;
- m_movedItem = 0;
- m_focusItem = 0;
+ m_movedItem = nullptr;
+ m_focusItem = nullptr;
}
}
void AnnotatePlugin::clearAnnotations()
{
const int result = QMessageBox::question( m_marbleWidget,
QObject::tr( "Clear all annotations" ),
QObject::tr( "Are you sure you want to clear all annotations?" ),
QMessageBox::Yes | QMessageBox::Cancel );
if ( result == QMessageBox::Yes ) {
disableFocusActions();
qDeleteAll( m_graphicsItems );
m_graphicsItems.clear();
m_marbleWidget->model()->treeModel()->removeDocument( m_annotationDocument );
m_annotationDocument->clear();
m_marbleWidget->model()->treeModel()->addDocument( m_annotationDocument );
- m_movedItem = 0;
- m_focusItem = 0;
+ m_movedItem = nullptr;
+ m_focusItem = nullptr;
}
}
void AnnotatePlugin::saveAnnotationFile()
{
- const QString filename = QFileDialog::getSaveFileName( 0,
+ const QString filename = QFileDialog::getSaveFileName( nullptr,
tr("Save Annotation File"),
QString(),
tr("All Supported Files (*.kml *.osm);;"
"KML file (*.kml);;"
"Open Street Map file (*.osm)") );
if ( !filename.isNull() ) {
GeoWriter writer;
// FIXME: This should be consistent with the way the loading is done.
if (filename.endsWith(QLatin1String(".kml"), Qt::CaseInsensitive)) {
writer.setDocumentType( kml::kmlTag_nameSpaceOgc22 );
}
else if (filename.endsWith(QLatin1String(".osm"), Qt::CaseInsensitive)) {
// "0.6" is the current version of osm, it is used to identify the osm writer
// The reference value is kept in plugins/runner/osm/OsmElementDictionary.hz
writer.setDocumentType( "0.6" );
}
QFile file( filename );
file.open( QIODevice::WriteOnly );
if ( !writer.write( &file, m_annotationDocument ) ) {
mDebug() << "Could not write the file " << filename;
}
file.close();
}
}
void AnnotatePlugin::loadAnnotationFile()
{
- const QString filename = QFileDialog::getOpenFileName( 0,
+ const QString filename = QFileDialog::getOpenFileName( nullptr,
tr("Open Annotation File"),
QString(),
tr("All Supported Files (*.kml *.osm);;"
"Kml Annotation file (*.kml);;"
"Open Street Map file (*.osm)") );
if ( filename.isNull() ) {
return;
}
else{
openAnnotationFile(filename);
}
}
void AnnotatePlugin::downloadOsm()
{
QPointer<DownloadOsmDialog> dialog=new DownloadOsmDialog(m_marbleWidget,this);
dialog->show();
}
void AnnotatePlugin::openAnnotationFile(const QString& filename)
{
if ( filename.isNull() ) {
return;
}
ParsingRunnerManager manager( m_marbleWidget->model()->pluginManager(),this );
GeoDataDocument *document = manager.openFile( filename);
Q_ASSERT( document );
// FIXME: The same problem as in the case of copying/cutting graphic items applies here:
// the files do not load properly because the geometry copy is not a deep copy.
foreach ( GeoDataFeature *feature, document->featureList() ) {
if (const GeoDataPlacemark *placemark = geodata_cast<GeoDataPlacemark>(feature)) {
GeoDataPlacemark *newPlacemark = new GeoDataPlacemark( *placemark );
if (geodata_cast<GeoDataPoint>(placemark->geometry())) {
PlacemarkTextAnnotation *placemark = new PlacemarkTextAnnotation( newPlacemark );
m_graphicsItems.append( placemark );
} else if (geodata_cast<GeoDataPolygon>(placemark->geometry())) {
newPlacemark->setParent( m_annotationDocument );
if ( !placemark->styleUrl().isEmpty() ) {
newPlacemark->setStyleUrl( placemark->styleUrl() );
}
AreaAnnotation *polygonAnnotation = new AreaAnnotation( newPlacemark );
m_graphicsItems.append( polygonAnnotation );
} else if (geodata_cast<GeoDataLineString>(placemark->geometry())) {
newPlacemark->setParent( m_annotationDocument );
if ( !placemark->styleUrl().isEmpty() ) {
newPlacemark->setStyleUrl( placemark->styleUrl() );
}
PolylineAnnotation *polylineAnnotation = new PolylineAnnotation( newPlacemark );
m_graphicsItems.append( polylineAnnotation );
}
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, newPlacemark );
} else if (const GeoDataGroundOverlay *overlay = geodata_cast<GeoDataGroundOverlay>(feature)) {
GeoDataGroundOverlay *newOverlay = new GeoDataGroundOverlay( *overlay );
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, newOverlay );
displayOverlayFrame( newOverlay );
}
}
m_marbleWidget->centerOn( document->latLonAltBox() );
delete document;
emit repaintNeeded( QRegion() );
}
bool AnnotatePlugin::eventFilter( QObject *watched, QEvent *event )
{
if ( !m_widgetInitialized ) {
MarbleWidget *marbleWidget = qobject_cast<MarbleWidget*>( watched );
if ( marbleWidget ) {
m_marbleWidget = marbleWidget;
addContextItems();
setupGroundOverlayModel();
setupOverlayRmbMenu();
setupPolygonRmbMenu();
setupPolylineRmbMenu();
setupNodeRmbMenu();
setupTextAnnotationRmbMenu();
setupActions( marbleWidget );
m_marbleWidget->model()->treeModel()->addDocument( m_annotationDocument );
m_widgetInitialized = true;
connect( this, SIGNAL(mouseMoveGeoPosition(QString)), m_marbleWidget, SIGNAL(mouseMoveGeoPosition(QString)) );
return true;
}
return false;
}
// Accept mouse and key press events.
if ( event->type() != QEvent::MouseButtonPress &&
event->type() != QEvent::MouseButtonRelease &&
event->type() != QEvent::MouseMove &&
event->type() != QEvent::KeyPress &&
event->type() != QEvent::KeyRelease ) {
return false;
}
// Handle key press events.
if ( event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease ) {
QKeyEvent * const keyEvent = static_cast<QKeyEvent*>( event );
Q_ASSERT( keyEvent );
if ( m_focusItem &&
( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation ||
m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) ) {
if ( keyEvent->type() == QEvent::KeyPress && keyEvent->key() == Qt::Key_Control ) {
announceStateChanged( SceneGraphicsItem::MergingNodes );
}
if ( keyEvent->type() == QEvent::KeyRelease && keyEvent->key() == Qt::Key_Control ) {
if ( ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation &&
static_cast<AreaAnnotation*>( m_focusItem )->isBusy() ) ||
( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation &&
static_cast<PolylineAnnotation*>( m_focusItem )->isBusy() ) ) {
return true;
}
announceStateChanged( SceneGraphicsItem::Editing );
}
}
// If we have an item which has the focus and the Escape key is pressed, set item's focus
// to false.
if ( m_focusItem &&
keyEvent->type() == QEvent::KeyPress && keyEvent->key() == Qt::Key_Escape &&
!m_editingDialogIsShown ) {
disableFocusActions();
m_focusItem->setFocus( false );
m_marbleWidget->model()->treeModel()->updateFeature( m_focusItem->placemark() );
- m_focusItem = 0;
+ m_focusItem = nullptr;
return true;
}
// If we have an item which has the focus and the Delete key is pressed, delete the item
if ( m_focusItem && keyEvent->type() == QEvent::KeyPress && keyEvent->key() == Qt::Key_Delete &&
!m_editingDialogIsShown ) {
askToRemoveFocusItem();
return true;
}
return false;
}
// Handle mouse events.
QMouseEvent * const mouseEvent = dynamic_cast<QMouseEvent*>( event );
Q_ASSERT( mouseEvent );
// Get the geocoordinates from mouse pos screen coordinates.
qreal lon, lat;
const bool isOnGlobe = m_marbleWidget->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
if ( !isOnGlobe ) {
return false;
}
// Deal with adding polygons and polylines.
if ( ( m_drawingPolygon && handleDrawingPolygon( mouseEvent ) ) ||
( m_drawingPolyline && handleDrawingPolyline( mouseEvent ) ) ) {
return true;
}
// It is important to deal with Ground Overlay mouse release event here because it uses the
// texture layer in order to make the rendering more efficient.
if ( mouseEvent->type() == QEvent::MouseButtonRelease && m_groundOverlayModel.rowCount() ) {
handleReleaseOverlay( mouseEvent );
}
// It is important to deal with the MouseMove event here because it changes the state of the
// selected item irrespective of the longitude/latitude the cursor moved to (excepting when
// it is outside the globe, which is treated above).
if ( mouseEvent->type() == QEvent::MouseMove && m_movedItem &&
handleMovingSelectedItem( mouseEvent ) ) {
setupCursor( m_movedItem );
return true;
}
// Pass the event to Graphic Items.
for ( SceneGraphicsItem *item: m_graphicsItems ) {
if ( !item->containsPoint( mouseEvent->pos() ) ) {
continue;
}
// If an edit dialog is visible, do not permit right clicking on items.
if ( m_editingDialogIsShown && mouseEvent->type() == QEvent::MouseButtonPress &&
mouseEvent->button() == Qt::RightButton) {
return true;
}
if ( !item->hasFocus() &&
item->graphicType() != SceneGraphicsTypes::SceneGraphicGroundOverlay ) {
if ( mouseEvent->type() == QEvent::MouseButtonPress &&
mouseEvent->button() == Qt::LeftButton ) {
item->setFocus( true );
disableFocusActions();
enableActionsOnItemType( item->graphicType() );
if ( m_focusItem && m_focusItem != item ) {
m_focusItem->setFocus( false );
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicGroundOverlay ) {
clearOverlayFrames();
}
}
m_focusItem = item;
m_marbleWidget->model()->treeModel()->updateFeature( item->placemark() );
return true;
}
return false;
}
if ( item->sceneEvent( event ) ) {
setupCursor( item );
if ( mouseEvent->type() == QEvent::MouseButtonPress ) {
handleSuccessfulPressEvent( mouseEvent, item );
} else if ( mouseEvent->type() == QEvent::MouseMove ) {
handleSuccessfulHoverEvent( mouseEvent, item );
} else if ( mouseEvent->type() == QEvent::MouseButtonRelease ) {
handleSuccessfulReleaseEvent( mouseEvent, item );
}
handleRequests( mouseEvent, item );
return true;
}
}
// If the event gets here, it most probably means it is a map interaction event, or something
// that has nothing to do with the annotate plugin items. We "deal" with this situation because,
// for example, we may need to deselect some selected items.
handleUncaughtEvents( mouseEvent );
return false;
}
bool AnnotatePlugin::handleDrawingPolygon( QMouseEvent *mouseEvent )
{
const GeoDataCoordinates coords = mouseGeoDataCoordinates( mouseEvent );
if ( mouseEvent->type() == QEvent::MouseMove ) {
- setupCursor( 0 );
+ setupCursor( nullptr );
emit mouseMoveGeoPosition( coords.toString() );
return true;
} else if ( mouseEvent->button() == Qt::LeftButton &&
mouseEvent->type() == QEvent::MouseButtonPress ) {
m_marbleWidget->model()->treeModel()->removeFeature( m_polygonPlacemark );
GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>( m_polygonPlacemark->geometry() );
poly->outerBoundary().append( coords );
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, m_polygonPlacemark );
emit nodeAdded( coords );
return true;
}
return false;
}
bool AnnotatePlugin::handleDrawingPolyline( QMouseEvent *mouseEvent )
{
const GeoDataCoordinates coords = mouseGeoDataCoordinates( mouseEvent );
if ( mouseEvent->type() == QEvent::MouseMove ) {
- setupCursor( 0 );
+ setupCursor( nullptr );
emit mouseMoveGeoPosition( coords.toString() );
return true;
} else if ( mouseEvent->button() == Qt::LeftButton &&
mouseEvent->type() == QEvent::MouseButtonPress ) {
m_marbleWidget->model()->treeModel()->removeFeature( m_polylinePlacemark );
GeoDataLineString *line = dynamic_cast<GeoDataLineString*>( m_polylinePlacemark->geometry() );
line->append( coords );
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, m_polylinePlacemark );
emit nodeAdded( coords );
return true;
}
return false;
}
void AnnotatePlugin::handleReleaseOverlay( QMouseEvent *mouseEvent )
{
const GeoDataCoordinates coords = mouseGeoDataCoordinates( mouseEvent );
for ( int i = 0; i < m_groundOverlayModel.rowCount(); ++i ) {
const QModelIndex index = m_groundOverlayModel.index( i, 0 );
GeoDataGroundOverlay *overlay = dynamic_cast<GeoDataGroundOverlay*>(
qvariant_cast<GeoDataObject*>( index.data( MarblePlacemarkModel::ObjectPointerRole ) ) );
if ( overlay->latLonBox().contains( coords ) ) {
if ( mouseEvent->button() == Qt::LeftButton ) {
displayOverlayFrame( overlay );
} else if ( mouseEvent->button() == Qt::RightButton ) {
showOverlayRmbMenu( overlay, mouseEvent->x(), mouseEvent->y() );
}
}
}
}
bool AnnotatePlugin::handleMovingSelectedItem( QMouseEvent *mouseEvent )
{
// Handling easily the mouse move by calling for each scene graphic item their own mouseMoveEvent
// handler and updating their feature.
if ( m_movedItem->sceneEvent( mouseEvent ) ) {
m_marbleWidget->model()->treeModel()->updateFeature( m_movedItem->placemark() );
emit itemMoved( m_movedItem->placemark() );
if ( m_movedItem->graphicType() == SceneGraphicsTypes::SceneGraphicTextAnnotation ) {
emit placemarkMoved();
}
const GeoDataCoordinates coords = mouseGeoDataCoordinates( mouseEvent );
emit mouseMoveGeoPosition( coords.toString() );
return true;
}
return false;
}
void AnnotatePlugin::handleSuccessfulPressEvent( QMouseEvent *mouseEvent, SceneGraphicsItem *item )
{
Q_UNUSED( mouseEvent );
// Update the item's placemark.
m_marbleWidget->model()->treeModel()->updateFeature( item->placemark() );
// Store a pointer to the item for possible following move events only if its state is
// either 'Editing' or 'AddingNodes' and the mouse left button has been used.
if ( ( item->state() == SceneGraphicsItem::Editing ||
item->state() == SceneGraphicsItem::AddingNodes ) &&
mouseEvent->button() == Qt::LeftButton ) {
m_movedItem = item;
}
}
void AnnotatePlugin::handleSuccessfulHoverEvent( QMouseEvent *mouseEvent, SceneGraphicsItem *item )
{
Q_UNUSED( mouseEvent );
m_marbleWidget->model()->treeModel()->updateFeature( item->placemark() );
}
void AnnotatePlugin::handleSuccessfulReleaseEvent( QMouseEvent *mouseEvent, SceneGraphicsItem *item )
{
Q_UNUSED( mouseEvent );
// The item gets 'deselected' (from moving) at mouse release.
- m_movedItem = 0;
+ m_movedItem = nullptr;
// Update the item's placemark.
m_marbleWidget->model()->treeModel()->updateFeature( item->placemark() );
}
void AnnotatePlugin::handleRequests( QMouseEvent *mouseEvent, SceneGraphicsItem *item )
{
if ( item->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation ) {
AreaAnnotation * const area = static_cast<AreaAnnotation*>( item );
if ( area->request() == SceneGraphicsItem::ShowPolygonRmbMenu ) {
showPolygonRmbMenu( mouseEvent->pos().x(), mouseEvent->pos().y() );
} else if ( area->request() == SceneGraphicsItem::ShowNodeRmbMenu ) {
showNodeRmbMenu( mouseEvent->pos().x(), mouseEvent->pos().y() );
} else if ( area->request() == SceneGraphicsItem::StartPolygonAnimation ) {
QPointer<MergingPolygonNodesAnimation> animation = area->animation();
connect( animation, SIGNAL(nodesMoved()), this, SIGNAL(repaintNeeded()) );
connect( animation, SIGNAL(animationFinished()),
this, SLOT(setAreaAvailable()) );
area->setBusy( true );
disableActions( m_actions.first() );
animation->startAnimation();
} else if ( area->request() == SceneGraphicsItem::OuterInnerMergingWarning ) {
QMessageBox::warning( m_marbleWidget,
tr( "Operation not permitted" ),
tr( "Cannot merge a node from polygon's outer boundary "
"with a node from one of its inner boundaries." ) );
} else if ( area->request() == SceneGraphicsItem::InnerInnerMergingWarning ) {
QMessageBox::warning( m_marbleWidget,
tr( "Operation not permitted" ),
tr( "Cannot merge two nodes from two different inner "
"boundaries." ) );
} else if ( area->request() == SceneGraphicsItem::InvalidShapeWarning ) {
QMessageBox::warning( m_marbleWidget,
tr( "Operation not permitted" ),
tr( "Cannot merge the selected nodes. Most probably "
"this would make the polygon's outer boundary not "
"contain all its inner boundary nodes." ) );
} else if ( area->request() == SceneGraphicsItem::RemovePolygonRequest ) {
removeFocusItem();
} else if ( area->request() == SceneGraphicsItem::ChangeCursorPolygonNodeHover ) {
m_marbleWidget->setCursor( Qt::PointingHandCursor );
} else if ( area->request() == SceneGraphicsItem::ChangeCursorPolygonBodyHover ) {
m_marbleWidget->setCursor( Qt::SizeAllCursor );
}
} else if ( item->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) {
PolylineAnnotation * const polyline = static_cast<PolylineAnnotation*>( item );
if ( polyline->request() == SceneGraphicsItem::ShowPolylineRmbMenu ) {
showPolylineRmbMenu( mouseEvent->x(), mouseEvent->y() );
} else if ( polyline->request() == SceneGraphicsItem::ShowNodeRmbMenu ) {
showNodeRmbMenu( mouseEvent->x(), mouseEvent->y() );
} else if ( polyline->request() == SceneGraphicsItem::StartPolylineAnimation ) {
QPointer<MergingPolylineNodesAnimation> animation = polyline->animation();
connect( animation, SIGNAL(nodesMoved()), this, SIGNAL(repaintNeeded()) );
connect( animation, SIGNAL(animationFinished()),
this, SLOT(setPolylineAvailable()) );
polyline->setBusy( true );
disableActions( m_actions.first() );
animation->startAnimation();
} else if ( polyline->request() == SceneGraphicsItem::RemovePolylineRequest ) {
removeFocusItem();
} else if ( polyline->request() == SceneGraphicsItem::ChangeCursorPolylineNodeHover ) {
m_marbleWidget->setCursor( Qt::PointingHandCursor );
} else if ( polyline->request() == SceneGraphicsItem::ChangeCursorPolylineLineHover ) {
m_marbleWidget->setCursor( Qt::SizeAllCursor );
}
} else if ( item->graphicType() == SceneGraphicsTypes::SceneGraphicTextAnnotation ) {
PlacemarkTextAnnotation * const textAnnotation = static_cast<PlacemarkTextAnnotation*>( item );
if ( textAnnotation->request() == SceneGraphicsItem::ShowPlacemarkRmbMenu ) {
showTextAnnotationRmbMenu( mouseEvent->x(), mouseEvent->y() );
} else if ( textAnnotation->request() == SceneGraphicsItem::ChangeCursorPlacemarkHover ) {
m_marbleWidget->setCursor( Qt::SizeAllCursor );
}
} else if ( item->graphicType() == SceneGraphicsTypes::SceneGraphicGroundOverlay ){
GroundOverlayFrame * const groundOverlay = static_cast<GroundOverlayFrame*>( item );
if ( groundOverlay->request() == SceneGraphicsItem::ChangeCursorOverlayVerticalHover ) {
m_marbleWidget->setCursor( Qt::SizeVerCursor );
} else if ( groundOverlay->request() == SceneGraphicsItem::ChangeCursorOverlayHorizontalHover ) {
m_marbleWidget->setCursor( Qt::SizeHorCursor );
} else if ( groundOverlay->request() == SceneGraphicsItem::ChangeCursorOverlayBDiagHover ) {
m_marbleWidget->setCursor( Qt::SizeBDiagCursor );
} else if ( groundOverlay->request() == SceneGraphicsItem::ChangeCursorOverlayFDiagHover ) {
m_marbleWidget->setCursor( Qt::SizeFDiagCursor );
} else if ( groundOverlay->request() == SceneGraphicsItem::ChangeCursorOverlayBodyHover ) {
m_marbleWidget->setCursor( Qt::SizeAllCursor );
} else if ( groundOverlay->request() == SceneGraphicsItem::ChangeCursorOverlayRotateHover ) {
m_marbleWidget->setCursor( Qt::CrossCursor );
}
}
}
void AnnotatePlugin::handleUncaughtEvents( QMouseEvent *mouseEvent )
{
Q_UNUSED( mouseEvent );
// If the event is not caught by any of the annotate plugin specific items, clear the frames
// (which have the meaning of deselecting the overlay).
if ( !m_groundOverlayFrames.isEmpty() &&
mouseEvent->type() != QEvent::MouseMove && mouseEvent->type() != QEvent::MouseButtonRelease ) {
clearOverlayFrames();
}
if ( m_focusItem && m_focusItem->graphicType() != SceneGraphicsTypes::SceneGraphicGroundOverlay ) {
if ( ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation &&
static_cast<AreaAnnotation*>( m_focusItem )->isBusy() ) ||
( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation &&
static_cast<PolylineAnnotation*>( m_focusItem )->isBusy() ) ) {
return;
}
- m_focusItem->dealWithItemChange( 0 );
+ m_focusItem->dealWithItemChange( nullptr );
m_marbleWidget->model()->treeModel()->updateFeature( m_focusItem->placemark() );
if ( mouseEvent->type() == QEvent::MouseButtonPress ) {
m_focusItem->setFocus( false );
disableFocusActions();
announceStateChanged( SceneGraphicsItem::Editing );
m_marbleWidget->model()->treeModel()->updateFeature( m_focusItem->placemark() );
- m_focusItem = 0;
+ m_focusItem = nullptr;
}
}
}
void AnnotatePlugin::setupActions( MarbleWidget *widget )
{
qDeleteAll( m_actions );
m_actions.clear();
if ( !widget ) {
return;
}
- QActionGroup *group = new QActionGroup( 0 );
+ QActionGroup *group = new QActionGroup( nullptr );
group->setExclusive( true );
QAction *selectItem = new QAction( QIcon(QStringLiteral(":/icons/edit-select.png")),
tr("Select Item"),
this );
selectItem->setCheckable( true );
selectItem->setChecked( true );
QAction *drawPolygon = new QAction( QIcon(QStringLiteral(":/icons/draw-polygon.png")),
tr("Add Polygon"),
this );
connect( drawPolygon, SIGNAL(triggered()), this, SLOT(addPolygon()) );
QAction *addHole = new QAction( QIcon(QStringLiteral(":/icons/polygon-draw-hole.png")),
tr("Add Polygon Hole"),
this );
addHole->setCheckable( true );
addHole->setEnabled( false );
connect( addHole, SIGNAL(toggled(bool)), this, SLOT(setAddingPolygonHole(bool)) );
QAction *addNodes = new QAction( QIcon(QStringLiteral(":/icons/polygon-add-nodes.png")),
tr("Add Nodes"),
this );
addNodes->setCheckable( true );
addNodes->setEnabled( false );
connect( addNodes, SIGNAL(toggled(bool)), this, SLOT(setAddingNodes(bool)) );
QAction *addTextAnnotation = new QAction( QIcon(QStringLiteral(":/icons/add-placemark.png")),
tr("Add Placemark"),
this );
connect( addTextAnnotation, SIGNAL(triggered()), this, SLOT(addTextAnnotation()) );
QAction *addPath = new QAction( QIcon(QStringLiteral(":/icons/draw-path.png")),
tr("Add Path"),
this );
connect( addPath, SIGNAL(triggered()), this, SLOT(addPolyline()) );
QAction *addOverlay = new QAction( QIcon(QStringLiteral(":/icons/draw-overlay.png")),
tr("Add Ground Overlay"),
this );
connect( addOverlay, SIGNAL(triggered()), this, SLOT(addOverlay()) );
QAction *removeItem = new QAction( QIcon(QStringLiteral(":/icons/edit-delete-shred.png")),
tr("Remove Item"),
this );
removeItem->setEnabled( false );
connect( removeItem, SIGNAL(triggered()), this, SLOT(askToRemoveFocusItem()) );
QAction *loadAnnotationFile = new QAction( QIcon(QStringLiteral(":/icons/open-for-editing.png")),
tr("Load Annotation File" ),
this );
connect( loadAnnotationFile, SIGNAL(triggered()), this, SLOT(loadAnnotationFile()) );
QAction *saveAnnotationFile = new QAction( QIcon(QStringLiteral(":/icons/document-save-as.png")),
tr("Save Annotation File"),
this );
connect( saveAnnotationFile, SIGNAL(triggered()), this, SLOT(saveAnnotationFile()) );
QAction *clearAnnotations = new QAction( QIcon(QStringLiteral(":/icons/remove.png")),
tr("Clear all Annotations"),
this );
QAction *downloadOsm = new QAction( QIcon(":/icons/download.png"),
tr("Download OpenStreetMap Data"),
this );
connect( downloadOsm, SIGNAL(triggered(bool)), this, SLOT(downloadOsm()) );
downloadOsm->setToolTip(tr("Download OpenStreetMap data of the visible region"));
connect( drawPolygon, SIGNAL(toggled(bool)), clearAnnotations, SLOT(setDisabled(bool)) );
connect( clearAnnotations, SIGNAL(triggered()), this, SLOT(clearAnnotations()) );
QAction *sep1 = new QAction( this );
sep1->setSeparator( true );
QAction *sep2 = new QAction( this );
sep2->setSeparator( true );
sep2->setObjectName( "toolbarSeparator" );
QAction *sep3 = new QAction( this );
sep3->setSeparator( true );
QAction *sep4 = new QAction( this );
sep4->setSeparator( true );
group->addAction( loadAnnotationFile );
group->addAction( saveAnnotationFile );
group->addAction( sep1 );
group->addAction( addTextAnnotation );
group->addAction( drawPolygon );
group->addAction( addPath );
group->addAction( addOverlay );
group->addAction( sep2 );
group->addAction( selectItem );
group->addAction( addHole );
group->addAction( addNodes );
group->addAction( removeItem );
group->addAction( sep3 );
group->addAction( clearAnnotations );
group->addAction(downloadOsm);
group->addAction( sep4 );
m_actions.append( group );
emit actionGroupsChanged();
}
void AnnotatePlugin::disableActions( QActionGroup *group )
{
for ( int i = 0; i < group->actions().size(); ++i ) {
if ( group->actions().at(i)->text() != tr("Select Item") ) {
group->actions().at(i)->setEnabled( false );
} else {
group->actions().at(i)->setEnabled( true );
}
}
}
void AnnotatePlugin::enableAllActions( QActionGroup *group )
{
for ( int i = 0; i < group->actions().size(); ++i ) {
group->actions().at(i)->setEnabled( true );
}
}
void AnnotatePlugin::enableActionsOnItemType( const QString &type )
{
if ( type == SceneGraphicsTypes::SceneGraphicAreaAnnotation ) {
m_actions.first()->actions().at(9)->setEnabled( true );
m_actions.first()->actions().at(10)->setEnabled( true );
} else if ( type == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) {
m_actions.first()->actions().at(10)->setEnabled( true );
}
m_actions.first()->actions().at(11)->setEnabled( true );
}
void AnnotatePlugin::disableFocusActions()
{
m_actions.first()->actions().at(8)->setChecked( true );
m_actions.first()->actions().at(9)->setEnabled( false );
m_actions.first()->actions().at(10)->setEnabled( false );
m_actions.first()->actions().at(11)->setEnabled( false );
}
void AnnotatePlugin::addContextItems()
{
MarbleWidgetPopupMenu * const menu = m_marbleWidget->popupMenu();
m_pasteGraphicItem = new QAction( tr( "Paste" ), this );
m_pasteGraphicItem->setVisible( false );
connect( m_pasteGraphicItem, SIGNAL(triggered()), SLOT(pasteItem()) );
QAction *separator = new QAction( this );
separator->setSeparator( true );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( !smallScreen ) {
menu->addAction( Qt::RightButton, m_pasteGraphicItem );
menu->addAction( Qt::RightButton, separator );
}
}
void AnnotatePlugin::setupTextAnnotationRmbMenu()
{
delete m_textAnnotationRmbMenu;
m_textAnnotationRmbMenu = new QMenu;
QAction *cutItem = new QAction( tr( "Cut"), m_textAnnotationRmbMenu );
m_textAnnotationRmbMenu->addAction( cutItem );
connect( cutItem, SIGNAL(triggered()), this, SLOT(cutItem()) );
QAction *copyItem = new QAction( tr( "Copy"), m_textAnnotationRmbMenu );
m_textAnnotationRmbMenu->addAction( copyItem );
connect( copyItem, SIGNAL(triggered()), this, SLOT(copyItem()) );
QAction *removeItem = new QAction( tr( "Remove" ), m_textAnnotationRmbMenu );
m_textAnnotationRmbMenu->addAction( removeItem );
connect( removeItem, SIGNAL(triggered()), this, SLOT(askToRemoveFocusItem()) );
m_textAnnotationRmbMenu->addSeparator();
QAction *properties = new QAction( tr( "Properties" ), m_textAnnotationRmbMenu );
m_textAnnotationRmbMenu->addAction( properties );
connect( properties, SIGNAL(triggered()), this, SLOT(editTextAnnotation()) );
}
void AnnotatePlugin::showTextAnnotationRmbMenu( qreal x, qreal y )
{
m_textAnnotationRmbMenu->popup( m_marbleWidget->mapToGlobal( QPoint( x, y ) ) );
}
void AnnotatePlugin::editTextAnnotation()
{
QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog( m_focusItem->placemark(),
&m_osmRelations,
m_marbleWidget );
connect( dialog, SIGNAL(textAnnotationUpdated(GeoDataFeature*)),
m_marbleWidget->model()->treeModel(), SLOT(updateFeature(GeoDataFeature*)) );
connect( this, SIGNAL(placemarkMoved()),
dialog, SLOT(updateDialogFields()) );
connect( dialog, SIGNAL(finished(int)),
this, SLOT(stopEditingTextAnnotation(int)) );
connect( dialog, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SLOT( addRelation( const OsmPlacemarkData& ) ) );
dialog->setLabelColor(dynamic_cast<PlacemarkTextAnnotation*>(m_focusItem)->labelColor());
disableActions( m_actions.first() );
dialog->show();
m_editingDialogIsShown = true;
m_editedItem = m_focusItem;
}
void AnnotatePlugin::addTextAnnotation()
{
m_addingPlacemark = true;
// Get the normalized coordinates of the focus point. There will be automatically added a new
// placemark.
qreal lat = m_marbleWidget->focusPoint().latitude();
qreal lon = m_marbleWidget->focusPoint().longitude();
GeoDataCoordinates::normalizeLonLat( lon, lat );
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setCoordinate( lon, lat );
placemark->setVisible( true );
placemark->setBalloonVisible( false );
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, placemark );
PlacemarkTextAnnotation *textAnnotation = new PlacemarkTextAnnotation( placemark );
textAnnotation->setFocus( true );
m_graphicsItems.append( textAnnotation );
QPointer<EditPlacemarkDialog> dialog = new EditPlacemarkDialog( placemark, &m_osmRelations, m_marbleWidget );
connect( dialog, SIGNAL(textAnnotationUpdated(GeoDataFeature*)),
m_marbleWidget->model()->treeModel(), SLOT(updateFeature(GeoDataFeature*)) );
connect( this, SIGNAL(placemarkMoved()),
dialog, SLOT(updateDialogFields()) );
connect( dialog, SIGNAL(finished(int)),
this, SLOT(stopEditingTextAnnotation(int)) );
connect( dialog, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SLOT( addRelation( const OsmPlacemarkData& ) ) );
if ( m_focusItem ) {
m_focusItem->setFocus( false );
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicGroundOverlay ) {
clearOverlayFrames();
}
}
m_focusItem = textAnnotation;
m_editedItem = textAnnotation;
disableActions( m_actions.first() );
dialog->move( m_marbleWidget->mapToGlobal( QPoint( 0, 0 ) ) );
dialog->show();
m_editingDialogIsShown = true;
}
void AnnotatePlugin::stopEditingTextAnnotation( int result )
{
m_focusItem = m_editedItem;
- m_editedItem = 0;
+ m_editedItem = nullptr;
announceStateChanged( SceneGraphicsItem::Editing );
enableAllActions( m_actions.first() );
disableFocusActions();
if ( !result && m_addingPlacemark ) {
removeFocusItem();
} else {
enableActionsOnItemType( SceneGraphicsTypes::SceneGraphicTextAnnotation );
}
m_addingPlacemark = false;
m_editingDialogIsShown = false;
}
void AnnotatePlugin::setupGroundOverlayModel()
{
m_editingDialogIsShown = false;
m_groundOverlayModel.setSourceModel( m_marbleWidget->model()->groundOverlayModel() );
m_groundOverlayModel.setDynamicSortFilter( true );
m_groundOverlayModel.setSortRole( MarblePlacemarkModel::PopularityIndexRole );
m_groundOverlayModel.sort( 0, Qt::AscendingOrder );
}
void AnnotatePlugin::setupOverlayRmbMenu()
{
delete m_overlayRmbMenu;
m_overlayRmbMenu = new QMenu;
QAction *editOverlay = new QAction( tr( "Properties" ), m_overlayRmbMenu );
m_overlayRmbMenu->addAction( editOverlay );
connect( editOverlay, SIGNAL(triggered()), this, SLOT(editOverlay()) );
m_overlayRmbMenu->addSeparator();
QAction *removeOverlay = new QAction( tr( "Remove" ), m_overlayRmbMenu );
m_overlayRmbMenu->addAction( removeOverlay );
connect( removeOverlay, SIGNAL(triggered()), this, SLOT(removeOverlay()) );
}
void AnnotatePlugin::addOverlay()
{
GeoDataGroundOverlay *overlay = new GeoDataGroundOverlay();
qreal centerLongitude = m_marbleWidget->viewport()->centerLongitude()*RAD2DEG;
qreal centerLatitude = m_marbleWidget->viewport()->centerLatitude()*RAD2DEG;
GeoDataLatLonAltBox box = m_marbleWidget->viewport()->viewLatLonAltBox();
qreal maxDelta = 20;
qreal deltaLongitude = qMin(box.width(GeoDataCoordinates::Degree), maxDelta);
qreal deltaLatitude = qMin(box.height(GeoDataCoordinates::Degree), maxDelta);
qreal north = centerLatitude + deltaLatitude/4;
qreal south = centerLatitude - deltaLatitude/4;
qreal west = centerLongitude - deltaLongitude/4;
qreal east = centerLongitude + deltaLongitude/4;
overlay->latLonBox().setBoundaries( north, south, east, west, GeoDataCoordinates::Degree );
overlay->setName( tr( "Untitled Ground Overlay" ) );
QPointer<EditGroundOverlayDialog> dialog = new EditGroundOverlayDialog(
overlay,
m_marbleWidget->textureLayer(),
m_marbleWidget );
dialog->exec();
if( dialog->result() ) {
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, overlay );
displayOverlayFrame( overlay );
}
else {
delete overlay;
}
delete dialog;
}
void AnnotatePlugin::showOverlayRmbMenu( GeoDataGroundOverlay *overlay, qreal x, qreal y )
{
m_rmbOverlay = overlay;
m_overlayRmbMenu->popup( m_marbleWidget->mapToGlobal( QPoint( x, y ) ) );
}
void AnnotatePlugin::editOverlay()
{
displayOverlayFrame( m_rmbOverlay );
QPointer<EditGroundOverlayDialog> dialog = new EditGroundOverlayDialog(
m_rmbOverlay,
m_marbleWidget->textureLayer(),
m_marbleWidget );
connect( dialog, SIGNAL(groundOverlayUpdated(GeoDataGroundOverlay*)),
this, SLOT(updateOverlayFrame(GeoDataGroundOverlay*)) );
dialog->exec();
delete dialog;
}
void AnnotatePlugin::removeOverlay()
{
m_marbleWidget->model()->treeModel()->removeFeature( m_rmbOverlay );
clearOverlayFrames();
}
void AnnotatePlugin::displayOverlayFrame( GeoDataGroundOverlay *overlay )
{
if ( m_groundOverlayFrames.keys().contains( overlay ) ) {
return;
}
GeoDataPolygon *polygon = new GeoDataPolygon( Tessellate );
polygon->outerBoundary().setTessellate( true );
GeoDataPlacemark *rectangle_placemark = new GeoDataPlacemark;
rectangle_placemark->setGeometry( polygon );
rectangle_placemark->setParent( m_annotationDocument );
rectangle_placemark->setStyleUrl(QStringLiteral("#polygon"));
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, rectangle_placemark );
GroundOverlayFrame *frame = new GroundOverlayFrame( rectangle_placemark,
overlay,
m_marbleWidget->textureLayer() );
m_graphicsItems.append( frame );
m_groundOverlayFrames.insert( overlay, frame );
if ( m_focusItem ) {
m_focusItem->setFocus( false );
}
m_focusItem = frame;
enableActionsOnItemType( SceneGraphicsTypes::SceneGraphicGroundOverlay );
}
void AnnotatePlugin::updateOverlayFrame( GeoDataGroundOverlay *overlay )
{
GroundOverlayFrame *frame = static_cast<GroundOverlayFrame *>( m_groundOverlayFrames.value( overlay ) );
if ( frame ) {
frame->update();
}
}
void AnnotatePlugin::clearOverlayFrames()
{
for ( GeoDataGroundOverlay *overlay: m_groundOverlayFrames.keys() ) {
GroundOverlayFrame *frame = static_cast<GroundOverlayFrame *>( m_groundOverlayFrames.value( overlay ) );
m_graphicsItems.removeAll( m_groundOverlayFrames.value( overlay ) );
m_marbleWidget->model()->treeModel()->removeFeature( frame->placemark() );
delete frame->placemark();
delete frame;
}
m_groundOverlayFrames.clear();
- m_focusItem = 0;
+ m_focusItem = nullptr;
disableFocusActions();
}
void AnnotatePlugin::setupPolygonRmbMenu()
{
delete m_polygonRmbMenu;
m_polygonRmbMenu = new QMenu;
QAction *deselectNodes = new QAction( tr( "Deselect All Nodes" ), m_polygonRmbMenu );
m_polygonRmbMenu->addAction( deselectNodes );
connect( deselectNodes, SIGNAL(triggered()), this, SLOT(deselectNodes()) );
QAction *deleteAllSelected = new QAction( tr( "Delete All Selected Nodes" ), m_polygonRmbMenu );
m_polygonRmbMenu->addAction( deleteAllSelected );
connect( deleteAllSelected, SIGNAL(triggered()), this, SLOT(deleteSelectedNodes()) );
m_polygonRmbMenu->addSeparator();
QAction *cutPolygon = new QAction( tr( "Cut"), m_polygonRmbMenu );
m_polygonRmbMenu->addAction( cutPolygon );
connect( cutPolygon, SIGNAL(triggered()), this, SLOT(cutItem()) );
QAction *copyPolygon = new QAction( tr( "Copy"), m_polygonRmbMenu );
m_polygonRmbMenu->addAction( copyPolygon );
connect( copyPolygon, SIGNAL(triggered()), this, SLOT(copyItem()) );
QAction *removePolygon = new QAction( tr( "Remove" ), m_polygonRmbMenu );
m_polygonRmbMenu->addAction( removePolygon );
connect( removePolygon, SIGNAL(triggered()), this, SLOT(askToRemoveFocusItem()) );
m_polygonRmbMenu->addSeparator();
QAction *showEditDialog = new QAction( tr( "Properties" ), m_polygonRmbMenu );
m_polygonRmbMenu->addAction( showEditDialog );
connect( showEditDialog, SIGNAL(triggered()), this, SLOT(editPolygon()) );
}
void AnnotatePlugin::showPolygonRmbMenu( qreal x, qreal y )
{
// We need to store the coordinates from where the rmb menu is shown so that in case of
// selecting Copy/Cut, we can move the polygon.
qreal lon, lat;
m_marbleWidget->geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian );
m_fromWhereToCopy = GeoDataCoordinates( lon, lat );
if ( !static_cast<AreaAnnotation*>( m_focusItem )->hasNodesSelected() ) {
m_polygonRmbMenu->actions().at(1)->setEnabled( false );
m_polygonRmbMenu->actions().at(0)->setEnabled( false );
} else {
m_polygonRmbMenu->actions().at(1)->setEnabled( true );
m_polygonRmbMenu->actions().at(0)->setEnabled( true );
}
m_polygonRmbMenu->popup( m_marbleWidget->mapToGlobal( QPoint( x, y ) ) );
}
void AnnotatePlugin::addPolygon()
{
m_drawingPolygon = true;
GeoDataPolygon *poly = new GeoDataPolygon( Tessellate );
poly->outerBoundary().setTessellate( true );
m_polygonPlacemark = new GeoDataPlacemark;
m_polygonPlacemark->setGeometry( poly );
m_polygonPlacemark->setParent( m_annotationDocument );
m_polygonPlacemark->setStyleUrl(QStringLiteral("#polygon"));
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, m_polygonPlacemark );
AreaAnnotation *polygon = new AreaAnnotation( m_polygonPlacemark );
polygon->setState( SceneGraphicsItem::DrawingPolygon );
polygon->setFocus( true );
m_graphicsItems.append( polygon );
m_marbleWidget->update();
QPointer<EditPolygonDialog> dialog = new EditPolygonDialog( m_polygonPlacemark, &m_osmRelations, m_marbleWidget );
connect( dialog, SIGNAL(polygonUpdated(GeoDataFeature*)),
m_marbleWidget->model()->treeModel(), SLOT(updateFeature(GeoDataFeature*)) );
connect( dialog, SIGNAL(finished(int)),
this, SLOT(stopEditingPolygon(int)) );
connect( this, SIGNAL(nodeAdded(GeoDataCoordinates)), dialog, SLOT(handleAddingNode(GeoDataCoordinates)) );
connect( dialog, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SLOT( addRelation( const OsmPlacemarkData& ) ) );
// If there is another graphic item marked as 'selected' when pressing 'Add Polygon', change the focus of
// that item.
if ( m_focusItem ) {
m_focusItem->setFocus( false );
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicGroundOverlay ) {
clearOverlayFrames();
}
}
m_focusItem = polygon;
m_editedItem = polygon;
disableActions( m_actions.first() );
dialog->move( m_marbleWidget->mapToGlobal( QPoint( 0, 0 ) ) );
dialog->show();
m_editingDialogIsShown = true;
}
void AnnotatePlugin::stopEditingPolygon( int result )
{
m_focusItem = m_editedItem;
- m_editedItem = 0;
+ m_editedItem = nullptr;
announceStateChanged( SceneGraphicsItem::Editing );
enableAllActions( m_actions.first() );
disableFocusActions();
if ( !result && m_drawingPolygon ) {
removeFocusItem();
} else {
enableActionsOnItemType( SceneGraphicsTypes::SceneGraphicAreaAnnotation );
}
m_editingDialogIsShown = false;
m_drawingPolygon = false;
- m_polygonPlacemark = 0;
+ m_polygonPlacemark = nullptr;
}
void AnnotatePlugin::deselectNodes()
{
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation ) {
AreaAnnotation * const area = static_cast<AreaAnnotation*>( m_focusItem );
area->deselectAllNodes();
if ( area->request() == SceneGraphicsItem::NoRequest ) {
m_marbleWidget->model()->treeModel()->updateFeature( area->placemark() );
}
} else if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) {
PolylineAnnotation * const polyline = static_cast<PolylineAnnotation*>( m_focusItem );
polyline->deselectAllNodes();
if ( polyline->request() == SceneGraphicsItem::NoRequest ) {
m_marbleWidget->model()->treeModel()->updateFeature( polyline->placemark() );
}
}
}
void AnnotatePlugin::deleteSelectedNodes()
{
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation ) {
AreaAnnotation * const area = static_cast<AreaAnnotation*>( m_focusItem );
area->deleteAllSelectedNodes();
} else if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) {
PolylineAnnotation * const polyline = static_cast<PolylineAnnotation*>( m_focusItem );
polyline->deleteAllSelectedNodes();
}
if ( m_focusItem->request() == SceneGraphicsItem::NoRequest ) {
m_marbleWidget->model()->treeModel()->updateFeature( m_focusItem->placemark() );
} else if ( m_focusItem->request() == SceneGraphicsItem::RemovePolygonRequest ||
m_focusItem->request() == SceneGraphicsItem::RemovePolylineRequest ) {
removeFocusItem();
} else if ( m_focusItem->request() == SceneGraphicsItem::InvalidShapeWarning ) {
QMessageBox::warning( m_marbleWidget,
tr( "Operation not permitted" ),
tr( "Cannot delete one of the selected nodes. Most probably "
"this would make the polygon's outer boundary not "
"contain all its inner boundary nodes." ) );
}
}
void AnnotatePlugin::editPolygon()
{
EditPolygonDialog *dialog = new EditPolygonDialog( m_focusItem->placemark(), &m_osmRelations, m_marbleWidget );
connect( dialog, SIGNAL(polygonUpdated(GeoDataFeature*)),
m_marbleWidget->model()->treeModel(), SLOT(updateFeature(GeoDataFeature*)) );
connect( dialog, SIGNAL(finished(int)),
this, SLOT(stopEditingPolygon(int)) );
connect( this, SIGNAL(itemMoved(GeoDataPlacemark*)), dialog, SLOT(handleItemMoving(GeoDataPlacemark*)) );
connect( dialog, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SLOT( addRelation( const OsmPlacemarkData& ) ) );
disableActions( m_actions.first() );
dialog->move( m_marbleWidget->mapToGlobal( QPoint( 0, 0 ) ) );
dialog->show();
m_editingDialogIsShown = true;
m_editedItem = m_focusItem;
}
void AnnotatePlugin::setupNodeRmbMenu()
{
delete m_nodeRmbMenu;
m_nodeRmbMenu = new QMenu;
QAction *selectNode = new QAction( tr( "Select Node" ), m_nodeRmbMenu );
m_nodeRmbMenu->addAction( selectNode );
connect( selectNode, SIGNAL(triggered()), this, SLOT(selectNode()) );
QAction *deleteNode = new QAction( tr( "Delete Node" ), m_nodeRmbMenu );
m_nodeRmbMenu->addAction( deleteNode );
connect( deleteNode, SIGNAL(triggered()), this, SLOT(deleteNode()) );
}
void AnnotatePlugin::showNodeRmbMenu( qreal x, qreal y )
{
// Check whether the node is already selected; we change the text of the action
// accordingly.
bool isSelected = false;
if ( ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation &&
static_cast<AreaAnnotation*>( m_focusItem )->clickedNodeIsSelected() ) ||
( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation &&
static_cast<PolylineAnnotation*>( m_focusItem )->clickedNodeIsSelected() ) ) {
isSelected = true;
}
m_nodeRmbMenu->actions().first()->setText( isSelected ? tr("Deselect Node") : tr("Select Node") );
m_nodeRmbMenu->popup( m_marbleWidget->mapToGlobal( QPoint( x, y ) ) );
}
void AnnotatePlugin::selectNode()
{
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation ) {
AreaAnnotation * const area = static_cast<AreaAnnotation*>( m_focusItem );
area->changeClickedNodeSelection();
} else if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) {
PolylineAnnotation *const polyline = static_cast<PolylineAnnotation*>( m_focusItem );
polyline->changeClickedNodeSelection();
}
if ( m_focusItem->request() == SceneGraphicsItem::NoRequest ) {
m_marbleWidget->model()->treeModel()->updateFeature( m_focusItem->placemark() );
}
}
void AnnotatePlugin::deleteNode()
{
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation ) {
AreaAnnotation *area = static_cast<AreaAnnotation*>( m_focusItem );
area->deleteClickedNode();
} else if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) {
PolylineAnnotation *polyline = static_cast<PolylineAnnotation*>( m_focusItem );
polyline->deleteClickedNode();
}
if ( m_focusItem->request() == SceneGraphicsItem::NoRequest ) {
m_marbleWidget->model()->treeModel()->updateFeature( m_focusItem->placemark() );
} else if ( m_focusItem->request() == SceneGraphicsItem::RemovePolygonRequest ||
m_focusItem->request() == SceneGraphicsItem::RemovePolylineRequest ) {
removeFocusItem();
} else if ( m_focusItem->request() == SceneGraphicsItem::InvalidShapeWarning ) {
QMessageBox::warning( m_marbleWidget,
tr( "Operation not permitted" ),
tr( "Cannot delete one of the selected nodes. Most probably "
"this would make the polygon's outer boundary not "
"contain all its inner boundary nodes." ) );
}
}
void AnnotatePlugin::setupPolylineRmbMenu()
{
delete m_polylineRmbMenu;
m_polylineRmbMenu = new QMenu;
QAction *deselectNodes = new QAction( tr( "Deselect All Nodes" ), m_polylineRmbMenu );
m_polylineRmbMenu->addAction( deselectNodes );
connect( deselectNodes, SIGNAL(triggered()), this, SLOT(deselectNodes()) );
QAction *deleteAllSelected = new QAction( tr( "Delete All Selected Nodes" ), m_polylineRmbMenu );
m_polylineRmbMenu->addAction( deleteAllSelected );
connect( deleteAllSelected, SIGNAL(triggered()), this, SLOT(deleteSelectedNodes()) );
m_polylineRmbMenu->addSeparator();
QAction *cutItem = new QAction( tr( "Cut"), m_polylineRmbMenu );
m_polylineRmbMenu->addAction( cutItem );
connect( cutItem, SIGNAL(triggered()), this, SLOT(cutItem()) );
QAction *copyItem = new QAction( tr( "Copy"), m_polylineRmbMenu );
m_polylineRmbMenu->addAction( copyItem );
connect( copyItem, SIGNAL(triggered()), this, SLOT(copyItem()) );
QAction *removeItem = new QAction( tr( "Remove" ), m_polylineRmbMenu );
m_polylineRmbMenu->addAction( removeItem );
connect( removeItem, SIGNAL(triggered()), this, SLOT(askToRemoveFocusItem()) );
m_polylineRmbMenu->addSeparator();
QAction *properties = new QAction( tr( "Properties" ), m_polylineRmbMenu );
m_polylineRmbMenu->addAction( properties );
connect( properties, SIGNAL(triggered()), this, SLOT(editPolyline()) );
}
void AnnotatePlugin::showPolylineRmbMenu( qreal x, qreal y )
{
qreal lon, lat;
m_marbleWidget->geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian );
m_fromWhereToCopy = GeoDataCoordinates( lon, lat );
if ( !static_cast<PolylineAnnotation*>( m_focusItem )->hasNodesSelected() ) {
m_polylineRmbMenu->actions().at(1)->setEnabled( false );
m_polylineRmbMenu->actions().at(0)->setEnabled( false );
} else {
m_polylineRmbMenu->actions().at(1)->setEnabled( true );
m_polylineRmbMenu->actions().at(0)->setEnabled( true );
}
m_polylineRmbMenu->popup( m_marbleWidget->mapToGlobal( QPoint( x, y ) ) );
}
void AnnotatePlugin::editPolyline()
{
QPointer<EditPolylineDialog> dialog = new EditPolylineDialog( m_focusItem->placemark(),
&m_osmRelations,
m_marbleWidget );
connect( dialog, SIGNAL(polylineUpdated(GeoDataFeature*)),
m_marbleWidget->model()->treeModel(), SLOT(updateFeature(GeoDataFeature*)) );
connect( dialog, SIGNAL(finished(int)),
this, SLOT(stopEditingPolyline(int)) );
connect( this, SIGNAL(itemMoved(GeoDataPlacemark*)), dialog, SLOT(handleItemMoving(GeoDataPlacemark*)) );
connect( dialog, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SLOT( addRelation( const OsmPlacemarkData& ) ) );
disableActions( m_actions.first() );
dialog->show();
m_editingDialogIsShown = true;
m_editedItem = m_focusItem;
}
void AnnotatePlugin::addPolyline()
{
m_drawingPolyline = true;
m_polylinePlacemark = new GeoDataPlacemark;
m_polylinePlacemark->setGeometry( new GeoDataLineString( Tessellate ) );
m_polylinePlacemark->setParent( m_annotationDocument );
m_polylinePlacemark->setStyleUrl(QStringLiteral("#polyline"));
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, m_polylinePlacemark );
PolylineAnnotation *polyline = new PolylineAnnotation( m_polylinePlacemark );
polyline->setState( SceneGraphicsItem::DrawingPolyline );
polyline->setFocus( true );
m_graphicsItems.append( polyline );
m_marbleWidget->update();
QPointer<EditPolylineDialog> dialog = new EditPolylineDialog( m_polylinePlacemark, &m_osmRelations, m_marbleWidget );
connect( dialog, SIGNAL(polylineUpdated(GeoDataFeature*)),
m_marbleWidget->model()->treeModel(), SLOT(updateFeature(GeoDataFeature*)) );
connect( dialog, SIGNAL(finished(int)),
this, SLOT(stopEditingPolyline(int)) );
connect( this, SIGNAL(nodeAdded(GeoDataCoordinates)), dialog, SLOT(handleAddingNode(GeoDataCoordinates)) );
connect( dialog, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SLOT( addRelation( const OsmPlacemarkData& ) ) );
if ( m_focusItem ) {
m_focusItem->setFocus( false );
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicGroundOverlay ) {
clearOverlayFrames();
}
}
m_focusItem = polyline;
m_editedItem = m_focusItem;
disableActions( m_actions.first() );
dialog->move( m_marbleWidget->mapToGlobal( QPoint( 0, 0 ) ) );
dialog->show();
m_editingDialogIsShown = true;
}
void AnnotatePlugin::stopEditingPolyline( int result )
{
m_focusItem = m_editedItem;
- m_editedItem = 0;
+ m_editedItem = nullptr;
announceStateChanged( SceneGraphicsItem::Editing );
enableAllActions( m_actions.first() );
disableFocusActions();
if ( !result && m_drawingPolyline ) {
removeFocusItem();
} else {
enableActionsOnItemType( SceneGraphicsTypes::SceneGraphicPolylineAnnotation );
}
m_editingDialogIsShown = false;
m_drawingPolyline = false;
- m_polylinePlacemark = 0;
+ m_polylinePlacemark = nullptr;
}
void AnnotatePlugin::addRelation( const OsmPlacemarkData &relationData )
{
m_osmRelations.insert( relationData.id(), relationData );
}
void AnnotatePlugin::announceStateChanged( SceneGraphicsItem::ActionState newState )
{
for ( SceneGraphicsItem *item: m_graphicsItems ) {
item->setState( newState );
m_marbleWidget->model()->treeModel()->updateFeature( item->placemark() );
}
}
void AnnotatePlugin::setupCursor( SceneGraphicsItem *item )
{
if ( !item || item->state() == SceneGraphicsItem::AddingNodes ) {
m_marbleWidget->setCursor( Qt::DragCopyCursor );
} else {
// Nothing to do. The other cursor changes were moved to the handleRequests() section.
}
}
void AnnotatePlugin::cutItem()
{
disableFocusActions();
// If there is already an item copied/cut, free its memory and replace it with this one.
// The same applies when copying.
if ( m_clipboardItem ) {
delete m_clipboardItem->placemark();
delete m_clipboardItem;
- m_clipboardItem = 0;
+ m_clipboardItem = nullptr;
}
m_clipboardItem = m_focusItem;
m_pasteGraphicItem->setVisible( true );
m_graphicsItems.removeAll( m_focusItem );
m_marbleWidget->model()->treeModel()->removeFeature( m_focusItem->placemark() );
- m_focusItem = 0;
+ m_focusItem = nullptr;
}
void AnnotatePlugin::copyItem()
{
if ( m_clipboardItem ) {
delete m_clipboardItem->placemark();
delete m_clipboardItem;
- m_clipboardItem = 0;
+ m_clipboardItem = nullptr;
}
// Just copy the placemark and instantiate a new object based on its graphic type.
// FIXME: Here is obvious a problem in the case of AreaAnnotation (when copying a
// placemark which has a GeoDataPolygon geometry?). Later Edit: The same applies for
// polylines (GeoDataLineString geometries).
GeoDataPlacemark *placemark = new GeoDataPlacemark( *m_focusItem->placemark() );
if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicAreaAnnotation ) {
m_clipboardItem = new AreaAnnotation( placemark );
} else if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicTextAnnotation ) {
m_clipboardItem = new PlacemarkTextAnnotation( placemark );
} else if ( m_focusItem->graphicType() == SceneGraphicsTypes::SceneGraphicPolylineAnnotation ) {
m_clipboardItem = new PolylineAnnotation( placemark );
}
m_pasteGraphicItem->setVisible( true );
}
void AnnotatePlugin::pasteItem()
{
const QPoint eventPoint = m_marbleWidget->popupMenu()->mousePosition();
qreal lon, lat;
m_marbleWidget->geoCoordinates( eventPoint.x(), eventPoint.y(), lon, lat, GeoDataCoordinates::Radian );
const GeoDataCoordinates newCoords( lon, lat );
m_clipboardItem->move( m_fromWhereToCopy, newCoords );
m_marbleWidget->model()->treeModel()->addFeature( m_annotationDocument, m_clipboardItem->placemark() );
m_graphicsItems.append( m_clipboardItem );
m_clipboardItem->setFocus( true );
enableActionsOnItemType( m_clipboardItem->graphicType() );
m_focusItem = m_clipboardItem;
- m_clipboardItem = 0;
+ m_clipboardItem = nullptr;
m_pasteGraphicItem->setVisible( false );
}
const GeoDataCoordinates AnnotatePlugin::mouseGeoDataCoordinates(QMouseEvent *mouseEvent) const
{
qreal lon, lat;
m_marbleWidget->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
return GeoDataCoordinates( lon, lat );
}
}
#include "moc_AnnotatePlugin.cpp"
diff --git a/src/plugins/render/annotate/AnnotatePlugin.h b/src/plugins/render/annotate/AnnotatePlugin.h
index cd4d39fb6..27d2433a6 100644
--- a/src/plugins/render/annotate/AnnotatePlugin.h
+++ b/src/plugins/render/annotate/AnnotatePlugin.h
@@ -1,217 +1,217 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Andrew Manson <g.real.ate@gmail.com>
// Copyright 2013 Thibaut Gridel <tgridel@free.fr>
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
#ifndef MARBLE_ANNOTATEPLUGIN_H
#define MARBLE_ANNOTATEPLUGIN_H
#include "RenderPlugin.h"
#include "SceneGraphicsItem.h"
#include "GeoDataGroundOverlay.h"
#include "GroundOverlayFrame.h"
#include <QMenu>
#include <QSortFilterProxyModel>
namespace Marble
{
class MarbleWidget;
class GeoDataDocument;
class GeoDataLinearRing;
class AreaAnnotation;
class PolylineAnnotation;
class PlacemarkTextAnnotation;
class OsmPlacemarkData;
/**
* @brief This class specifies the Marble layer interface of a plugin which
* annotates maps with polygons and placemarks.
*/
class AnnotatePlugin : public RenderPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.AnnotatePlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
MARBLE_PLUGIN( AnnotatePlugin )
public:
- explicit AnnotatePlugin(const MarbleModel *model = 0);
+ explicit AnnotatePlugin(const MarbleModel *model = nullptr);
~AnnotatePlugin() override;
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QIcon icon () const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
void initialize () override;
bool isInitialized () const override;
QString runtimeTrace() const override;
const QList<QActionGroup*> *actionGroups() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
- const QString &renderPos, GeoSceneLayer *layer = 0 ) override;
+ const QString &renderPos, GeoSceneLayer *layer = nullptr ) override;
Q_SIGNALS:
void placemarkMoved();
void nodeAdded( const GeoDataCoordinates &coordinates );
void itemMoved( GeoDataPlacemark *placemark );
void mouseMoveGeoPosition( const QString& );
private Q_SLOTS:
void enableModel( bool enabled );
void askToRemoveFocusItem();
void removeFocusItem();
void clearAnnotations();
void saveAnnotationFile();
void loadAnnotationFile();
void openAnnotationFile(const QString&);
void copyItem();
void cutItem();
void pasteItem();
void addTextAnnotation();
void editTextAnnotation();
void stopEditingTextAnnotation( int result );
void addOverlay();
void editOverlay();
void removeOverlay();
void updateOverlayFrame( GeoDataGroundOverlay *overlay );
void addPolygon();
void stopEditingPolygon( int result );
void setAddingPolygonHole( bool enabled );
void setAddingNodes( bool enabled );
void editPolygon();
void selectNode();
void deleteNode();
void deselectNodes();
void deleteSelectedNodes();
void setAreaAvailable();
void addPolyline();
void editPolyline();
void stopEditingPolyline( int result );
void setPolylineAvailable();
void addRelation( const OsmPlacemarkData &relationOsmData );
void downloadOsm();
protected:
bool eventFilter( QObject *watched, QEvent *event ) override;
private:
void addContextItems();
void setupActions( MarbleWidget *marbleWidget );
static void disableActions(QActionGroup *group);
static void enableAllActions(QActionGroup *group);
void enableActionsOnItemType( const QString &type );
void disableFocusActions();
void setupTextAnnotationRmbMenu();
void showTextAnnotationRmbMenu( qreal x, qreal y );
void setupGroundOverlayModel();
void setupOverlayRmbMenu();
void showOverlayRmbMenu( GeoDataGroundOverlay *overlay, qreal x, qreal y );
void displayOverlayFrame( GeoDataGroundOverlay *overlay );
void clearOverlayFrames();
void setupPolygonRmbMenu();
void setupNodeRmbMenu();
void showPolygonRmbMenu( qreal x, qreal y );
void showNodeRmbMenu( qreal x, qreal y );
void setupPolylineRmbMenu();
void showPolylineRmbMenu( qreal x, qreal y );
void handleUncaughtEvents( QMouseEvent *mouseEvent );
void handleReleaseOverlay( QMouseEvent *mouseEvent );
bool handleDrawingPolyline( QMouseEvent *mouseEvent );
bool handleDrawingPolygon( QMouseEvent *mouseEvent );
bool handleMovingSelectedItem( QMouseEvent *mouseEvent );
void handleRequests( QMouseEvent *mouseEvent, SceneGraphicsItem *item );
void handleSuccessfulPressEvent( QMouseEvent *mouseEvent, SceneGraphicsItem *item );
void handleSuccessfulHoverEvent( QMouseEvent *mouseEvent, SceneGraphicsItem *item );
void handleSuccessfulReleaseEvent( QMouseEvent *mouseEvent, SceneGraphicsItem *item );
void announceStateChanged( SceneGraphicsItem::ActionState newState );
void setupCursor( SceneGraphicsItem *item );
const GeoDataCoordinates mouseGeoDataCoordinates(QMouseEvent *mouseEvent) const;
bool m_isInitialized;
bool m_widgetInitialized;
MarbleWidget *m_marbleWidget;
QMenu *m_overlayRmbMenu;
QMenu *m_polygonRmbMenu;
QMenu *m_nodeRmbMenu;
QMenu *m_textAnnotationRmbMenu;
QMenu *m_polylineRmbMenu;
QList<QActionGroup*> m_actions;
QSortFilterProxyModel m_groundOverlayModel;
QMap<GeoDataGroundOverlay*, SceneGraphicsItem*> m_groundOverlayFrames;
// A list of all osm relations
QHash<qint64, OsmPlacemarkData> m_osmRelations;
GeoDataDocument* m_annotationDocument;
QList<SceneGraphicsItem*> m_graphicsItems;
SceneGraphicsItem *m_movedItem;
SceneGraphicsItem *m_focusItem;
SceneGraphicsItem *m_editedItem;
GeoDataGroundOverlay *m_rmbOverlay;
GeoDataPlacemark *m_polylinePlacemark;
GeoDataPlacemark *m_polygonPlacemark;
GeoDataCoordinates m_fromWhereToCopy;
SceneGraphicsItem *m_clipboardItem;
QAction *m_pasteGraphicItem;
bool m_drawingPolygon;
bool m_drawingPolyline;
bool m_addingPlacemark;
bool m_editingDialogIsShown;
};
}
#endif // MARBLE_ANNOTATEPLUGIN_H
diff --git a/src/plugins/render/annotate/AreaAnnotation.cpp b/src/plugins/render/annotate/AreaAnnotation.cpp
index ea43b15bc..97a433eca 100644
--- a/src/plugins/render/annotate/AreaAnnotation.cpp
+++ b/src/plugins/render/annotate/AreaAnnotation.cpp
@@ -1,1525 +1,1525 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Andrew Manson <g.real.ate@gmail.com>
// Copyright 2013 Thibaut Gridel <tgridel@free.fr>
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
// Self
#include "AreaAnnotation.h"
// Qt
#include <qmath.h>
#include <QPair>
#include <QApplication>
#include <QPalette>
// Marble
#include "GeoDataPlacemark.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "SceneGraphicsTypes.h"
#include "MergingPolygonNodesAnimation.h"
#include "PolylineNode.h"
#include "osm/OsmPlacemarkData.h"
namespace Marble {
const int AreaAnnotation::regularDim = 15;
const int AreaAnnotation::selectedDim = 15;
const int AreaAnnotation::mergedDim = 20;
const int AreaAnnotation::hoveredDim = 20;
const QColor AreaAnnotation::regularColor = Oxygen::aluminumGray3;
const QColor AreaAnnotation::mergedColor = Oxygen::emeraldGreen6;
AreaAnnotation::AreaAnnotation( GeoDataPlacemark *placemark ) :
SceneGraphicsItem( placemark ),
- m_viewport( 0 ),
+ m_viewport( nullptr ),
m_regionsInitialized( false ),
m_busy( false ),
m_hoveredNode( -1, -1 ),
m_interactingObj( InteractingNothing ),
m_virtualHovered( -1, -1 )
{
setPaintLayers(QStringList() << "AreaAnnotation");
}
AreaAnnotation::~AreaAnnotation()
{
delete m_animation;
}
void AreaAnnotation::paint(GeoPainter *painter, const ViewportParams *viewport , const QString &layer, int tileZoomLevel)
{
Q_UNUSED(layer);
Q_UNUSED(tileZoomLevel);
m_viewport = viewport;
Q_ASSERT(geodata_cast<GeoDataPolygon>(placemark()->geometry()));
painter->save();
if ( state() == SceneGraphicsItem::DrawingPolygon || !m_regionsInitialized ) {
setupRegionsLists( painter );
m_regionsInitialized = true;
} else {
updateRegions( painter );
}
if ( hasFocus() ) {
drawNodes( painter );
}
painter->restore();
}
bool AreaAnnotation::containsPoint( const QPoint &point ) const
{
if ( m_busy ) {
return false;
}
if ( state() == SceneGraphicsItem::Editing ) {
return ( polygonContains( point ) && innerBoundsContain( point ) == -1 ) ||
outerNodeContains( point ) != -1 ||
innerNodeContains( point ) != QPair<int, int>( -1, -1 );
} else if ( state() == SceneGraphicsItem::AddingPolygonHole ) {
return polygonContains( point ) && outerNodeContains( point ) == -1 &&
innerNodeContains( point ) == QPair<int, int>( -1, -1 );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return outerNodeContains( point ) != -1 ||
innerNodeContains( point ) != QPair<int, int>( -1, -1 );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return ( polygonContains( point ) && innerBoundsContain( point ) == -1 ) ||
virtualNodeContains( point ) != QPair<int, int>( -1, -1 ) ||
innerNodeContains( point ) != QPair<int, int>( -1, -1 ) ||
outerNodeContains( point ) != -1;
}
return false;
}
void AreaAnnotation::dealWithItemChange( const SceneGraphicsItem *other )
{
Q_UNUSED( other );
// So far we only deal with item changes when hovering nodes, so that
// they do not remain hovered when changing the item we interact with.
if ( state() == SceneGraphicsItem::Editing ) {
if ( m_hoveredNode != QPair<int, int>( -1, -1 ) ) {
const int i = m_hoveredNode.first;
const int j = m_hoveredNode.second;
if ( j == -1 ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsEditingHighlighted, false );
} else {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsEditingHighlighted, false );
}
}
m_hoveredNode = QPair<int, int>( -1, -1 );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
if ( m_hoveredNode != QPair<int, int>( -1, -1 ) ) {
const int i = m_hoveredNode.first;
const int j = m_hoveredNode.second;
if ( j == -1 ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
} else {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
}
}
m_hoveredNode = QPair<int, int>( -1, -1 );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
m_virtualHovered = QPair<int, int>( -1, -1 );
}
}
void AreaAnnotation::move( const GeoDataCoordinates &source, const GeoDataCoordinates &destination )
{
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
GeoDataLinearRing outerRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> innerRings = polygon->innerBoundaries();
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
polygon->outerBoundary().clear();
polygon->innerBoundaries().clear();
const qreal deltaLat = destination.latitude() - source.latitude();
const qreal deltaLon = destination.longitude() - source.longitude();
Quaternion latRectAxis = Quaternion::fromEuler( 0, destination.longitude(), 0);
Quaternion latAxis = Quaternion::fromEuler( -deltaLat, 0, 0);
Quaternion lonAxis = Quaternion::fromEuler(0, deltaLon, 0);
Quaternion rotAxis = latRectAxis * latAxis * latRectAxis.inverse() * lonAxis;
qreal lonRotated, latRotated;
for ( int i = 0; i < outerRing.size(); ++i ) {
Quaternion qpos = outerRing.at(i).quaternion();
qpos.rotateAroundAxis(rotAxis);
qpos.getSpherical( lonRotated, latRotated );
GeoDataCoordinates movedPoint( lonRotated, latRotated, 0 );
// Keeping the OsmPlacemarkData synchronized with the geometry
if ( osmData ) {
osmData->memberReference( -1 ).changeNodeReference( outerRing.at( i ), movedPoint );
}
polygon->outerBoundary().append( movedPoint );
}
for ( int i = 0; i < innerRings.size(); ++i ) {
GeoDataLinearRing newRing( Tessellate );
for ( int j = 0; j < innerRings.at(i).size(); ++j ) {
Quaternion qpos = innerRings.at(i).at(j).quaternion();
qpos.rotateAroundAxis(rotAxis);
qpos.getSpherical( lonRotated, latRotated );
GeoDataCoordinates movedPoint( lonRotated, latRotated, 0 );
if ( osmData ) {
osmData->memberReference( i ).changeNodeReference( innerRings.at( i ).at( j ), movedPoint );
}
newRing.append( movedPoint );
}
polygon->innerBoundaries().append( newRing );
}
}
void AreaAnnotation::setBusy( bool enabled )
{
m_busy = enabled;
if ( !enabled && m_animation && state() == SceneGraphicsItem::MergingNodes ) {
// Update the PolylineNodes lists after the animation has finished its execution.
const int ff = m_firstMergedNode.first;
const int fs = m_firstMergedNode.second;
const int sf = m_secondMergedNode.first;
const int ss = m_secondMergedNode.second;
if ( ff != -1 && fs == -1 && sf != -1 && ss == -1 ) {
m_outerNodesList[sf].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
m_hoveredNode = QPair<int, int>( -1, -1 );
// Remove the merging node flag and add the NodeIsSelected flag if either one of the
// merged nodes had been selected before merging them.
m_outerNodesList[sf].setFlag( PolylineNode::NodeIsMerged, false );
if ( m_outerNodesList.at(ff).isSelected() ) {
m_outerNodesList[sf].setFlag( PolylineNode::NodeIsSelected );
}
m_outerNodesList.removeAt( ff );
m_firstMergedNode = QPair<int, int>( -1, -1 );
m_secondMergedNode = QPair<int, int>( -1, -1 );
} else if ( ff != -1 && fs != -1 && sf != -1 && ss != -1 ) {
m_innerNodesList[sf][ss].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
m_hoveredNode = QPair<int, int>( -1, -1 );
m_innerNodesList[sf][ss].setFlag( PolylineNode::NodeIsMerged, false );
if ( m_innerNodesList.at(ff).at(fs).isSelected() ) {
m_innerNodesList[sf][ss].setFlag( PolylineNode::NodeIsSelected );
}
m_innerNodesList[sf].removeAt( fs );
m_firstMergedNode = QPair<int, int>( -1, -1 );
m_secondMergedNode = QPair<int, int>( -1, -1 );
}
delete m_animation;
}
}
bool AreaAnnotation::isBusy() const
{
return m_busy;
}
void AreaAnnotation::deselectAllNodes()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
for ( int i = 0 ; i < m_outerNodesList.size(); ++i ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsSelected, false );
}
for ( int i = 0; i < m_innerNodesList.size(); ++i ) {
for ( int j = 0; j < m_innerNodesList.at(i).size(); ++j ) {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsSelected, false );
}
}
}
void AreaAnnotation::deleteAllSelectedNodes()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
GeoDataLinearRing &outerRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
OsmPlacemarkData initialOsmData;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
initialOsmData = placemark()->osmData();
}
// If it proves inefficient, try something different.
GeoDataLinearRing initialOuterRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> initialInnerRings = polygon->innerBoundaries();
const QVector<PolylineNode> initialOuterNodes = m_outerNodesList;
const QVector< QVector<PolylineNode> > initialInnerNodes = m_innerNodesList;
for ( int i = 0; i < outerRing.size(); ++i ) {
if ( m_outerNodesList.at(i).isSelected() ) {
if ( m_outerNodesList.size() <= 3 ) {
setRequest( SceneGraphicsItem::RemovePolygonRequest );
return;
}
if ( osmData ) {
osmData->memberReference( -1 ).removeNodeReference( initialOuterRing.at( i ) );
}
m_outerNodesList.removeAt( i );
outerRing.remove( i );
--i;
}
}
for ( int i = 0; i < innerRings.size(); ++i ) {
for ( int j = 0; j < innerRings.at(i).size(); ++j ) {
if ( m_innerNodesList.at(i).at(j).isSelected() ) {
if ( m_innerNodesList.at(i).size() <= 3 ) {
if ( osmData ) {
osmData->removeMemberReference( i );
}
innerRings.remove( i );
m_innerNodesList.removeAt( i );
--i;
break;
}
if ( osmData ) {
osmData->memberReference( i ).removeNodeReference( initialInnerRings.at( i ).at( j ) );
}
innerRings[i].remove( j );
m_innerNodesList[i].removeAt( j );
--j;
}
}
}
if ( !isValidPolygon() ) {
if ( osmData ) {
placemark()->setOsmData( initialOsmData );
}
polygon->outerBoundary() = initialOuterRing;
polygon->innerBoundaries() = initialInnerRings;
m_outerNodesList = initialOuterNodes;
m_innerNodesList = initialInnerNodes;
setRequest( SceneGraphicsItem::InvalidShapeWarning );
}
}
void AreaAnnotation::deleteClickedNode()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
GeoDataLinearRing &outerRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
OsmPlacemarkData initialOsmData;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
initialOsmData = placemark()->osmData();
}
// If it proves inefficient, try something different.
GeoDataLinearRing initialOuterRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> initialInnerRings = polygon->innerBoundaries();
const QVector<PolylineNode> initialOuterNodes = m_outerNodesList;
const QVector< QVector<PolylineNode> > initialInnerNodes = m_innerNodesList;
int i = m_clickedNodeIndexes.first;
int j = m_clickedNodeIndexes.second;
m_hoveredNode = QPair<int, int>( -1, -1 );
if ( i != -1 && j == -1 ) {
if ( m_outerNodesList.size() <= 3 ) {
setRequest( SceneGraphicsItem::RemovePolygonRequest );
return;
}
// Keep the OsmPlacemarkData synchronized with the geometrys
if ( osmData ) {
osmData->removeNodeReference( outerRing.at( i ) );
}
outerRing.remove( i );
m_outerNodesList.removeAt( i );
} else if ( i != -1 && j != -1 ) {
if ( m_innerNodesList.at(i).size() <= 3 ) {
if ( osmData ) {
osmData->removeMemberReference( i );
}
innerRings.remove( i );
m_innerNodesList.removeAt( i );
return;
}
if ( osmData ) {
osmData->memberReference( i ).removeNodeReference( innerRings.at( i ).at( j ) );
}
innerRings[i].remove( j );
m_innerNodesList[i].removeAt( j );
}
if ( !isValidPolygon() ) {
if ( osmData ) {
placemark()->setOsmData( initialOsmData );
}
polygon->outerBoundary() = initialOuterRing;
polygon->innerBoundaries() = initialInnerRings;
m_outerNodesList = initialOuterNodes;
m_innerNodesList = initialInnerNodes;
setRequest( SceneGraphicsItem::InvalidShapeWarning );
}
}
void AreaAnnotation::changeClickedNodeSelection()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
const int i = m_clickedNodeIndexes.first;
const int j = m_clickedNodeIndexes.second;
if ( i != -1 && j == -1 ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsSelected,
!m_outerNodesList.at(i).isSelected() );
} else if ( i != -1 && j != -1 ) {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsSelected,
!m_innerNodesList.at(i).at(j).isSelected() );
}
}
bool AreaAnnotation::hasNodesSelected() const
{
for ( int i = 0; i < m_outerNodesList.size(); ++i ) {
if ( m_outerNodesList.at(i).isSelected() ) {
return true;
}
}
for ( int i = 0; i < m_innerNodesList.size(); ++i ) {
for ( int j = 0; j < m_innerNodesList.at(i).size(); ++j ) {
if ( m_innerNodesList.at(i).at(j).isSelected() ) {
return true;
}
}
}
return false;
}
bool AreaAnnotation::clickedNodeIsSelected() const
{
const int i = m_clickedNodeIndexes.first;
const int j = m_clickedNodeIndexes.second;
return ( i != -1 && j == -1 && m_outerNodesList.at(i).isSelected() ) ||
( i != -1 && j != -1 && m_innerNodesList.at(i).at(j).isSelected() );
}
QPointer<MergingPolygonNodesAnimation> AreaAnnotation::animation()
{
return m_animation;
}
bool AreaAnnotation::mousePressEvent( QMouseEvent *event )
{
if ( !m_viewport || m_busy ) {
return false;
}
setRequest( SceneGraphicsItem::NoRequest );
if ( state() == SceneGraphicsItem::Editing ) {
return processEditingOnPress( event );
} else if ( state() == SceneGraphicsItem::AddingPolygonHole ) {
return processAddingHoleOnPress( event );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return processMergingOnPress( event );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return processAddingNodesOnPress( event );
}
return false;
}
bool AreaAnnotation::mouseMoveEvent( QMouseEvent *event )
{
if ( !m_viewport || m_busy ) {
return false;
}
setRequest( SceneGraphicsItem::NoRequest );
if ( state() == SceneGraphicsItem::Editing ) {
return processEditingOnMove( event );
} else if ( state() == SceneGraphicsItem::AddingPolygonHole ) {
return processAddingHoleOnMove( event );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return processMergingOnMove( event );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return processAddingNodesOnMove( event );
}
return false;
}
bool AreaAnnotation::mouseReleaseEvent( QMouseEvent *event )
{
if ( !m_viewport || m_busy ) {
return false;
}
setRequest( SceneGraphicsItem::NoRequest );
if ( state() == SceneGraphicsItem::Editing ) {
return processEditingOnRelease( event );
} else if ( state() == SceneGraphicsItem::AddingPolygonHole ) {
return processAddingHoleOnRelease( event );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return processMergingOnRelease( event );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return processAddingNodesOnRelease( event );
}
return false;
}
void AreaAnnotation::dealWithStateChange( SceneGraphicsItem::ActionState previousState )
{
// Dealing with cases when exiting a state has an effect on this item.
if ( previousState == SceneGraphicsItem::Editing ) {
// Make sure that when changing the state, there is no highlighted node.
if ( m_hoveredNode != QPair<int, int>( -1, -1 ) ) {
const int i = m_hoveredNode.first;
const int j = m_hoveredNode.second;
if ( j == -1 ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsEditingHighlighted, false );
} else {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsEditingHighlighted, false );
}
}
m_clickedNodeIndexes = QPair<int, int>( -1, -1 );
m_hoveredNode = QPair<int, int>( -1, -1 );
} else if ( previousState == SceneGraphicsItem::AddingPolygonHole ) {
// Check if a polygon hole was being drawn before changing state.
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
QVector<GeoDataLinearRing> &innerBounds = polygon->innerBoundaries();
if ( innerBounds.size() && innerBounds.last().size() <= 2 ) {
// If only two nodes were added, remove this inner boundary entirely.
innerBounds.remove( innerBounds.size() - 1 );
m_innerNodesList.removeLast();
return;
}
} else if ( previousState == SceneGraphicsItem::MergingNodes ) {
// If there was only a node selected for being merged and the state changed,
// deselect it.
const int i = m_firstMergedNode.first;
const int j = m_firstMergedNode.second;
if ( i != -1 && j != -1 ) {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsMerged, false );
} else if ( i != -1 && j == -1 ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsMerged, false );
}
// Make sure that when changing the state, there is no highlighted node.
if ( m_hoveredNode != QPair<int, int>( -1, -1 ) ) {
int i = m_hoveredNode.first;
int j = m_hoveredNode.second;
if ( j == -1 ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
} else {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
}
}
m_firstMergedNode = QPair<int, int>( -1, -1 );
m_hoveredNode = QPair<int, int>( -1, -1 );
delete m_animation;
} else if ( previousState == SceneGraphicsItem::AddingNodes ) {
m_outerVirtualNodes.clear();
m_innerVirtualNodes.clear();
m_virtualHovered = QPair<int, int>( -1, -1 );
m_adjustedNode = -2;
}
// Dealing with cases when entering a state has an effect on this item, or
// initializations are needed.
if ( state() == SceneGraphicsItem::Editing ) {
m_interactingObj = InteractingNothing;
m_clickedNodeIndexes = QPair<int, int>( -1, -1 );
m_hoveredNode = QPair<int, int>( -1, -1 );
} else if ( state() == SceneGraphicsItem::AddingPolygonHole ) {
// Nothing to do so far when entering this state.
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
QVector<GeoDataLinearRing> &innerBounds = polygon->innerBoundaries();
m_innerNodesList.append(QVector<PolylineNode>());
innerBounds.append( GeoDataLinearRing( Tessellate ) );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
m_firstMergedNode = QPair<int, int>( -1, -1 );
m_secondMergedNode = QPair<int, int>( -1, -1 );
m_hoveredNode = QPair<int, int>( -1, -1 );
- m_animation = 0;
+ m_animation = nullptr;
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
m_virtualHovered = QPair<int, int>( -1, -1 );
m_adjustedNode = -2;
}
}
const char *AreaAnnotation::graphicType() const
{
return SceneGraphicsTypes::SceneGraphicAreaAnnotation;
}
bool AreaAnnotation::isValidPolygon() const
{
const GeoDataPolygon *poly = static_cast<const GeoDataPolygon*>( placemark()->geometry() );
const QVector<GeoDataLinearRing> &innerRings = poly->innerBoundaries();
for ( const GeoDataLinearRing &innerRing: innerRings ) {
for ( int i = 0; i < innerRing.size(); ++i ) {
if ( !poly->outerBoundary().contains( innerRing.at(i) ) ) {
return false;
}
}
}
return true;
}
void AreaAnnotation::setupRegionsLists( GeoPainter *painter )
{
const GeoDataPolygon *polygon = static_cast<const GeoDataPolygon*>( placemark()->geometry() );
const GeoDataLinearRing &outerRing = polygon->outerBoundary();
const QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
// Add the outer boundary nodes.
QVector<GeoDataCoordinates>::ConstIterator itBegin = outerRing.constBegin();
QVector<GeoDataCoordinates>::ConstIterator itEnd = outerRing.constEnd();
m_outerNodesList.clear();
m_innerNodesList.clear();
m_boundariesList.clear();
for ( ; itBegin != itEnd; ++itBegin ) {
const PolylineNode newNode = PolylineNode( painter->regionFromEllipse( *itBegin, regularDim, regularDim ) );
m_outerNodesList.append( newNode );
}
for ( const GeoDataLinearRing &innerRing: innerRings ) {
QVector<GeoDataCoordinates>::ConstIterator itBegin = innerRing.constBegin();
QVector<GeoDataCoordinates>::ConstIterator itEnd = innerRing.constEnd();
QVector<PolylineNode> innerNodes;
innerNodes.reserve(innerRing.size());
for ( ; itBegin != itEnd; ++itBegin ) {
const PolylineNode newNode = PolylineNode( painter->regionFromEllipse( *itBegin, regularDim, regularDim ) );
innerNodes.append( newNode );
}
m_innerNodesList.append( innerNodes );
}
// Add the outer boundary to the boundaries list.
m_boundariesList.append( painter->regionFromPolygon( outerRing, Qt::OddEvenFill ) );
}
void AreaAnnotation::updateRegions( GeoPainter *painter )
{
if ( m_busy ) {
return;
}
const GeoDataPolygon *polygon = static_cast<const GeoDataPolygon*>( placemark()->geometry() );
const GeoDataLinearRing &outerRing = polygon->outerBoundary();
const QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
if ( state() == SceneGraphicsItem::AddingNodes ) {
// Create and update virtual nodes lists when being in the AddingPolgonNodes state, to
// avoid overhead in other states.
m_outerVirtualNodes.clear();
const QRegion firstRegion( painter->regionFromEllipse( outerRing.first().interpolate(
outerRing.last(), 0.5 ), hoveredDim, hoveredDim ) );
m_outerVirtualNodes.append( PolylineNode( firstRegion ) );
for ( int i = 0; i < outerRing.size() - 1; ++i ) {
const QRegion newRegion( painter->regionFromEllipse( outerRing.at(i).interpolate(
outerRing.at(i+1), 0.5 ), hoveredDim, hoveredDim ) );
m_outerVirtualNodes.append( PolylineNode( newRegion ) );
}
m_innerVirtualNodes.clear();
m_innerVirtualNodes.reserve(innerRings.size());
for ( int i = 0; i < innerRings.size(); ++i ) {
m_innerVirtualNodes.append(QVector<PolylineNode>());
const QRegion firstRegion( painter->regionFromEllipse( innerRings.at(i).first().interpolate(
innerRings.at(i).last(), 0.5 ), hoveredDim, hoveredDim ) );
m_innerVirtualNodes[i].append( PolylineNode( firstRegion ) );
for ( int j = 0; j < innerRings.at(i).size() - 1; ++j ) {
const QRegion newRegion( painter->regionFromEllipse( innerRings.at(i).at(j).interpolate(
innerRings.at(i).at(j+1), 0.5 ), hoveredDim, hoveredDim ) );
m_innerVirtualNodes[i].append( PolylineNode( newRegion ) );
}
}
}
// Update the boundaries list.
m_boundariesList.clear();
m_boundariesList.reserve(1 + innerRings.size());
m_boundariesList.append( painter->regionFromPolygon( outerRing, Qt::OddEvenFill ) );
for ( const GeoDataLinearRing &ring: innerRings ) {
m_boundariesList.append( painter->regionFromPolygon( ring, Qt::OddEvenFill ) );
}
// Update the outer and inner nodes lists.
Q_ASSERT( m_outerNodesList.size() == outerRing.size() );
for ( int i = 0; i < m_outerNodesList.size(); ++i ) {
const QRegion newRegion = m_outerNodesList.at(i).isSelected() ?
painter->regionFromEllipse( outerRing.at(i), selectedDim, selectedDim ) :
painter->regionFromEllipse( outerRing.at(i), regularDim, regularDim );
m_outerNodesList[i].setRegion( newRegion );
}
Q_ASSERT( m_innerNodesList.size() == innerRings.size() );
for ( int i = 0; i < m_innerNodesList.size(); ++i ) {
Q_ASSERT( m_innerNodesList.at(i).size() == innerRings.at(i).size() );
for ( int j = 0; j < m_innerNodesList.at(i).size(); ++j ) {
const QRegion newRegion = m_innerNodesList.at(i).at(j).isSelected() ?
painter->regionFromEllipse( innerRings.at(i).at(j), selectedDim, selectedDim ) :
painter->regionFromEllipse( innerRings.at(i).at(j), regularDim, regularDim );
m_innerNodesList[i][j].setRegion( newRegion );
}
}
}
void AreaAnnotation::drawNodes( GeoPainter *painter )
{
// These are the 'real' dimensions of the drawn nodes. The ones which have class scope are used
// to generate the regions and they are a little bit larger, because, for example, it would be
// a little bit too hard to select nodes.
static const int d_regularDim = 10;
static const int d_selectedDim = 10;
static const int d_mergedDim = 20;
static const int d_hoveredDim = 20;
const GeoDataPolygon *polygon = static_cast<const GeoDataPolygon*>( placemark()->geometry() );
const GeoDataLinearRing &outerRing = polygon->outerBoundary();
const QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
QColor glowColor = QApplication::palette().highlightedText().color();
glowColor.setAlpha(120);
auto const selectedColor = QApplication::palette().highlight().color();
auto const hoveredColor = selectedColor;
for ( int i = 0; i < outerRing.size(); ++i ) {
// The order here is important, because a merged node can be at the same time selected.
if ( m_outerNodesList.at(i).isBeingMerged() ) {
painter->setBrush( mergedColor );
painter->drawEllipse( outerRing.at(i), d_mergedDim, d_mergedDim );
} else if ( m_outerNodesList.at(i).isSelected() ) {
painter->setBrush( selectedColor );
painter->drawEllipse( outerRing.at(i), d_selectedDim, d_selectedDim );
if ( m_outerNodesList.at(i).isEditingHighlighted() ||
m_outerNodesList.at(i).isMergingHighlighted() ) {
QPen defaultPen = painter->pen();
QPen newPen;
newPen.setWidth( defaultPen.width() + 3 );
newPen.setColor( glowColor );
painter->setBrush( Qt::NoBrush );
painter->setPen( newPen );
painter->drawEllipse( outerRing.at(i), d_selectedDim + 2, d_selectedDim + 2 );
painter->setPen( defaultPen );
}
} else {
painter->setBrush( regularColor );
painter->drawEllipse( outerRing.at(i), d_regularDim, d_regularDim );
if ( m_outerNodesList.at(i).isEditingHighlighted() ||
m_outerNodesList.at(i).isMergingHighlighted() ) {
QPen defaultPen = painter->pen();
QPen newPen;
newPen.setWidth( defaultPen.width() + 3 );
newPen.setColor( glowColor );
painter->setPen( newPen );
painter->setBrush( Qt::NoBrush );
painter->drawEllipse( outerRing.at(i), d_regularDim + 2, d_regularDim + 2 );
painter->setPen( defaultPen );
}
}
}
for ( int i = 0; i < innerRings.size(); ++i ) {
for ( int j = 0; j < innerRings.at(i).size(); ++j ) {
if ( m_innerNodesList.at(i).at(j).isBeingMerged() ) {
painter->setBrush( mergedColor );
painter->drawEllipse( innerRings.at(i).at(j), d_mergedDim, d_mergedDim );
} else if ( m_innerNodesList.at(i).at(j).isSelected() ) {
painter->setBrush( selectedColor );
painter->drawEllipse( innerRings.at(i).at(j), d_selectedDim, d_selectedDim );
if ( m_innerNodesList.at(i).at(j).isEditingHighlighted() ||
m_innerNodesList.at(i).at(j).isMergingHighlighted() ) {
QPen defaultPen = painter->pen();
QPen newPen;
newPen.setWidth( defaultPen.width() + 3 );
newPen.setColor( glowColor );
painter->setBrush( Qt::NoBrush );
painter->setPen( newPen );
painter->drawEllipse( innerRings.at(i).at(j), d_selectedDim + 2, d_selectedDim + 2 );
painter->setPen( defaultPen );
}
} else {
painter->setBrush( regularColor );
painter->drawEllipse( innerRings.at(i).at(j), d_regularDim, d_regularDim );
if ( m_innerNodesList.at(i).at(j).isEditingHighlighted() ||
m_innerNodesList.at(i).at(j).isMergingHighlighted() ) {
QPen defaultPen = painter->pen();
QPen newPen;
newPen.setWidth( defaultPen.width() + 3 );
newPen.setColor( glowColor );
painter->setBrush( Qt::NoBrush );
painter->setPen( newPen );
painter->drawEllipse( innerRings.at(i).at(j), d_regularDim + 2, d_regularDim + 2 );
painter->setPen( defaultPen );
}
}
}
}
if ( m_virtualHovered != QPair<int, int>( -1, -1 ) ) {
const int i = m_virtualHovered.first;
const int j = m_virtualHovered.second;
painter->setBrush( hoveredColor );
if ( i != -1 && j == -1 ) {
const GeoDataCoordinates coords = i ?
outerRing.at(i).interpolate( outerRing.at(i - 1), 0.5 ) :
outerRing.first().interpolate( outerRing.last(), 0.5 );
painter->drawEllipse( coords, d_hoveredDim, d_hoveredDim );
} else {
Q_ASSERT( i != -1 && j != -1 );
const GeoDataCoordinates coords = j ?
innerRings.at(i).at(j).interpolate( innerRings.at(i).at(j - 1), 0.5 ) :
innerRings.at(i).first().interpolate( innerRings.at(i).last(), 0.5 );
painter->drawEllipse( coords, d_hoveredDim, d_hoveredDim );
}
}
}
int AreaAnnotation::outerNodeContains( const QPoint &point ) const
{
if ( !hasFocus() ) {
return -1;
}
for ( int i = 0; i < m_outerNodesList.size(); ++i ) {
if ( m_outerNodesList.at(i).containsPoint( point ) ) {
return i;
}
}
return -1;
}
QPair<int, int> AreaAnnotation::innerNodeContains( const QPoint &point ) const
{
if ( !hasFocus() ) {
return QPair<int, int>( -1, -1 );
}
for ( int i = 0; i < m_innerNodesList.size(); ++i ) {
for ( int j = 0; j < m_innerNodesList.at(i).size(); ++j ) {
if ( m_innerNodesList.at(i).at(j).containsPoint( point ) ) {
return QPair<int, int>( i, j );
}
}
}
return QPair<int, int>( -1, -1 );
}
QPair<int, int> AreaAnnotation::virtualNodeContains( const QPoint &point ) const
{
if ( !hasFocus() ) {
return QPair<int, int>( -1, -1 );
}
for ( int i = 0; i < m_outerVirtualNodes.size(); ++i ) {
if ( m_outerVirtualNodes.at(i).containsPoint( point ) ) {
return QPair<int, int>( i, -1 );
}
}
for ( int i = 0; i < m_innerVirtualNodes.size(); ++i ) {
for ( int j = 0; j < m_innerVirtualNodes.at(i).size(); ++j ) {
if ( m_innerVirtualNodes.at(i).at(j).containsPoint( point ) ) {
return QPair<int, int>( i, j );
}
}
}
return QPair<int, int>( -1, -1 );
}
int AreaAnnotation::innerBoundsContain( const QPoint &point ) const
{
// There are no inner boundaries.
if ( m_boundariesList.size() == 1 ) {
return -1;
}
// Starting from 1 because on index 0 is stored the region representing the whole polygon.
for ( int i = 1; i < m_boundariesList.size(); ++i ) {
if ( m_boundariesList.at(i).contains( point ) ) {
return i;
}
}
return -1;
}
bool AreaAnnotation::polygonContains( const QPoint &point ) const
{
return m_boundariesList.first().contains( point );
}
bool AreaAnnotation::processEditingOnPress( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() != Qt::LeftButton && mouseEvent->button() != Qt::RightButton ) {
return false;
}
qreal lat, lon;
m_viewport->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
m_movedPointCoords.set( lon, lat );
// First check if one of the nodes from outer boundary has been clicked.
const int outerIndex = outerNodeContains( mouseEvent->pos() );
if ( outerIndex != -1 ) {
m_clickedNodeIndexes = QPair<int, int>( outerIndex, -1 );
if ( mouseEvent->button() == Qt::RightButton ) {
setRequest( SceneGraphicsItem::ShowNodeRmbMenu );
} else {
m_interactingObj = InteractingNode;
}
return true;
}
// Then check if one of the nodes which form an inner boundary has been clicked.
const QPair<int, int> innerIndexes = innerNodeContains( mouseEvent->pos() );
if ( innerIndexes.first != -1 && innerIndexes.second != -1 ) {
m_clickedNodeIndexes = innerIndexes;
if ( mouseEvent->button() == Qt::RightButton ) {
setRequest( SceneGraphicsItem::ShowNodeRmbMenu );
} else {
m_interactingObj = InteractingNode;
}
return true;
}
// If neither outer boundary nodes nor inner boundary nodes contain the event position,
// then check if the interior of the polygon (excepting its 'holes') contains this point.
if ( polygonContains( mouseEvent->pos() ) &&
innerBoundsContain( mouseEvent->pos() ) == -1 ) {
if ( mouseEvent->button() == Qt::RightButton ) {
setRequest( SceneGraphicsItem::ShowPolygonRmbMenu );
} else {
m_interactingObj = InteractingPolygon;
}
return true;
}
return false;
}
bool AreaAnnotation::processEditingOnMove( QMouseEvent *mouseEvent )
{
if ( !m_viewport ) {
return false;
}
qreal lon, lat;
m_viewport->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
const GeoDataCoordinates newCoords( lon, lat );
const qreal deltaLat = lat - m_movedPointCoords.latitude();
const qreal deltaLon = lon - m_movedPointCoords.longitude();
if ( m_interactingObj == InteractingNode ) {
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
GeoDataLinearRing &outerRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
const int i = m_clickedNodeIndexes.first;
const int j = m_clickedNodeIndexes.second;
if ( j == -1 ) {
// Keeping the osmPlacemarkData synchronized with the geometry
if ( osmData ) {
osmData->memberReference( -1 ).changeNodeReference( outerRing.at( i ), newCoords );
}
outerRing[i] = newCoords;
} else {
Q_ASSERT( i != -1 && j != -1 );
if ( osmData ) {
osmData->memberReference( i ).changeNodeReference( innerRings.at( i ).at( j ), newCoords );
}
innerRings[i].at(j) = newCoords;
}
return true;
} else if ( m_interactingObj == InteractingPolygon ) {
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
GeoDataLinearRing outerRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> innerRings = polygon->innerBoundaries();
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
Quaternion latRectAxis = Quaternion::fromEuler( 0, lon, 0);
Quaternion latAxis = Quaternion::fromEuler( -deltaLat, 0, 0);
Quaternion lonAxis = Quaternion::fromEuler(0, deltaLon, 0);
Quaternion rotAxis = latRectAxis * latAxis * latRectAxis.inverse() * lonAxis;
polygon->outerBoundary().clear();
polygon->innerBoundaries().clear();
qreal lonRotated, latRotated;
for ( int i = 0; i < outerRing.size(); ++i ) {
Quaternion qpos = outerRing.at(i).quaternion();
qpos.rotateAroundAxis(rotAxis);
qpos.getSpherical( lonRotated, latRotated );
GeoDataCoordinates movedPoint( lonRotated, latRotated, 0 );
if ( osmData ) {
osmData->memberReference( -1 ).changeNodeReference( outerRing.at( i ), movedPoint );
}
polygon->outerBoundary().append( movedPoint );
}
for ( int i = 0; i < innerRings.size(); ++i ) {
GeoDataLinearRing newRing( Tessellate );
for ( int j = 0; j < innerRings.at(i).size(); ++j ) {
Quaternion qpos = innerRings.at(i).at(j).quaternion();
qpos.rotateAroundAxis(rotAxis);
qpos.getSpherical( lonRotated, latRotated );
GeoDataCoordinates movedPoint( lonRotated, latRotated, 0 );
if ( osmData ) {
osmData->memberReference( i ).changeNodeReference( innerRings.at( i ).at( j ) , movedPoint );
}
newRing.append( movedPoint );
}
polygon->innerBoundaries().append( newRing );
}
m_movedPointCoords = newCoords;
return true;
} else if ( m_interactingObj == InteractingNothing ) {
return dealWithHovering( mouseEvent );
}
return false;
}
bool AreaAnnotation::processEditingOnRelease( QMouseEvent *mouseEvent )
{
static const int mouseMoveOffset = 1;
if ( mouseEvent->button() != Qt::LeftButton ) {
return false;
}
if ( m_interactingObj == InteractingNode ) {
qreal x, y;
m_viewport->screenCoordinates( m_movedPointCoords.longitude(),
m_movedPointCoords.latitude(),
x, y );
// The node gets selected only if it is clicked and not moved.
if ( qFabs(mouseEvent->pos().x() - x) > mouseMoveOffset ||
qFabs(mouseEvent->pos().y() - y) > mouseMoveOffset ) {
m_interactingObj = InteractingNothing;
return true;
}
const int i = m_clickedNodeIndexes.first;
const int j = m_clickedNodeIndexes.second;
if ( j == -1 ) {
m_outerNodesList[i].setFlag( PolylineNode::NodeIsSelected,
!m_outerNodesList[i].isSelected() );
} else {
m_innerNodesList[i][j].setFlag ( PolylineNode::NodeIsSelected,
!m_innerNodesList.at(i).at(j).isSelected() );
}
m_interactingObj = InteractingNothing;
return true;
} else if ( m_interactingObj == InteractingPolygon ) {
// Nothing special happens at polygon release.
m_interactingObj = InteractingNothing;
return true;
}
return false;
}
bool AreaAnnotation::processAddingHoleOnPress( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() != Qt::LeftButton ) {
return false;
}
qreal lon, lat;
m_viewport->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
const GeoDataCoordinates newCoords( lon, lat );
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
QVector<GeoDataLinearRing> &innerBounds = polygon->innerBoundaries();
innerBounds.last().append( newCoords );
m_innerNodesList.last().append( PolylineNode() );
return true;
}
bool AreaAnnotation::processAddingHoleOnMove( QMouseEvent *mouseEvent )
{
Q_UNUSED( mouseEvent );
return true;
}
bool AreaAnnotation::processAddingHoleOnRelease( QMouseEvent *mouseEvent )
{
Q_UNUSED( mouseEvent );
return true;
}
bool AreaAnnotation::processMergingOnPress( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() != Qt::LeftButton ) {
return false;
}
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
GeoDataLinearRing initialOuterRing = polygon->outerBoundary();
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
OsmPlacemarkData initialOsmData;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
GeoDataLinearRing &outerRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
const int outerIndex = outerNodeContains( mouseEvent->pos() );
// If the selected node is an outer boundary node.
if ( outerIndex != -1 ) {
// If this is the first node selected to be merged.
if ( m_firstMergedNode.first == -1 && m_firstMergedNode.second == -1 ) {
m_firstMergedNode = QPair<int, int>( outerIndex, -1 );
m_outerNodesList[outerIndex].setFlag( PolylineNode::NodeIsMerged );
// If the first selected node was an inner boundary node, raise the request for showing
// warning.
} else if ( m_firstMergedNode.first != -1 && m_firstMergedNode.second != -1 ) {
setRequest( SceneGraphicsItem::OuterInnerMergingWarning );
m_innerNodesList[m_firstMergedNode.first][m_firstMergedNode.second].setFlag(
PolylineNode::NodeIsMerged, false );
if ( m_hoveredNode.first != -1 ) {
// We can be sure that the hovered node is an outer node.
Q_ASSERT( m_hoveredNode.second == -1 );
m_outerNodesList[m_hoveredNode.first].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
}
m_hoveredNode = m_firstMergedNode = QPair<int, int>( -1, -1 );
} else {
Q_ASSERT( m_firstMergedNode.first != -1 && m_firstMergedNode.second == -1 );
// Clicking two times the same node results in unmarking it for merging.
if ( m_firstMergedNode.first == outerIndex ) {
m_outerNodesList[outerIndex].setFlag( PolylineNode::NodeIsMerged, false );
m_firstMergedNode = QPair<int, int>( -1, -1 );
return true;
}
// If two nodes which form a triangle are merged, the whole triangle should be
// destroyed.
if ( outerRing.size() <= 3 ) {
setRequest( SceneGraphicsItem::RemovePolygonRequest );
return true;
}
GeoDataCoordinates mergedNode = outerRing.at(m_firstMergedNode.first).interpolate( outerRing.at(outerIndex),
0.5 );
// Keeping the osm data synchronized with the geometry
if ( osmData ) {
osmData->memberReference( -1 ).changeNodeReference( outerRing.at( outerIndex ), mergedNode );
osmData->memberReference( -1 ).removeNodeReference( outerRing.at( m_firstMergedNode.first ) );
}
outerRing[outerIndex] = mergedNode;
outerRing.remove( m_firstMergedNode.first );
if ( !isValidPolygon() ) {
if ( osmData ) {
placemark()->setOsmData( initialOsmData );
}
polygon->outerBoundary() = initialOuterRing;
m_outerNodesList[m_firstMergedNode.first].setFlag( PolylineNode::NodeIsMerged, false );
// Remove highlight effect before showing warning
if ( m_hoveredNode.first != -1 ) {
m_outerNodesList[m_hoveredNode.first].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
}
m_hoveredNode = m_firstMergedNode = QPair<int, int>( -1, -1 );
setRequest( SceneGraphicsItem::InvalidShapeWarning );
return true;
}
// Do not modify it here. The animation has access to the object. It will modify the polygon.
polygon->outerBoundary() = initialOuterRing;
m_outerNodesList[outerIndex].setFlag( PolylineNode::NodeIsMerged );
m_secondMergedNode = QPair<int, int>( outerIndex, -1 );
delete m_animation;
m_animation = new MergingPolygonNodesAnimation( this );
setRequest( SceneGraphicsItem::StartPolygonAnimation );
}
return true;
}
// If the selected node is an inner boundary node.
const QPair<int, int> innerIndexes = innerNodeContains( mouseEvent->pos() );
if ( innerIndexes.first != -1 && innerIndexes.second != -1 ) {
const int i = m_firstMergedNode.first;
const int j = m_firstMergedNode.second;
// If this is the first selected node.
if ( i == -1 && j == -1 ) {
m_firstMergedNode = innerIndexes;
m_innerNodesList[innerIndexes.first][innerIndexes.second].setFlag( PolylineNode::NodeIsMerged );
// If the first selected node has been an outer boundary one, raise the request for showing warning.
} else if ( i != -1 && j == -1 ) {
setRequest( SceneGraphicsItem::OuterInnerMergingWarning );
m_outerNodesList[i].setFlag( PolylineNode::NodeIsMerged, false );
if ( m_hoveredNode.first != -1 ) {
// We can now be sure that the highlighted node is a node from polygon's outer boundary
Q_ASSERT( m_hoveredNode.second != -1 );
m_outerNodesList[m_hoveredNode.first].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
}
m_firstMergedNode = QPair<int, int>( -1, -1 );
} else {
Q_ASSERT( i != -1 && j != -1 );
if ( i != innerIndexes.first ) {
setRequest( SceneGraphicsItem::InnerInnerMergingWarning );
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsMerged, false );
if ( m_hoveredNode.first != -1 && m_hoveredNode.second != -1 ) {
m_innerNodesList[m_hoveredNode.first][m_hoveredNode.second].setFlag(
PolylineNode::NodeIsMergingHighlighted, false );
}
m_hoveredNode = m_firstMergedNode = QPair<int, int>( -1, -1 );
return true;
}
// Clicking two times the same node results in unmarking it for merging.
if ( m_firstMergedNode == innerIndexes ) {
m_innerNodesList[i][j].setFlag( PolylineNode::NodeIsMerged, false );
m_firstMergedNode = QPair<int, int>( -1, -1 );
return true;
}
// If two nodes which form an inner boundary of a polygon with a size smaller than
// 3 are merged, remove the whole inner boundary.
if ( innerRings.at(i).size() <= 3 ) {
innerRings.remove( i );
m_innerNodesList.removeAt( i );
m_firstMergedNode = m_secondMergedNode = m_hoveredNode = QPair<int, int>( -1, -1 );
return true;
}
m_innerNodesList[innerIndexes.first][innerIndexes.second].setFlag( PolylineNode::NodeIsMerged );
m_secondMergedNode = innerIndexes;
m_animation = new MergingPolygonNodesAnimation( this );
setRequest( SceneGraphicsItem::StartPolygonAnimation );
}
return true;
}
return false;
}
bool AreaAnnotation::processMergingOnMove( QMouseEvent *mouseEvent )
{
return dealWithHovering( mouseEvent );
}
bool AreaAnnotation::processMergingOnRelease( QMouseEvent *mouseEvent )
{
Q_UNUSED( mouseEvent );
return true;
}
bool AreaAnnotation::processAddingNodesOnPress( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() != Qt::LeftButton ) {
return false;
}
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
GeoDataLinearRing &outerRing = polygon->outerBoundary();
QVector<GeoDataLinearRing> &innerRings = polygon->innerBoundaries();
// If a virtual node has just been clicked, add it to the polygon's outer boundary
// and start 'adjusting' its position.
const QPair<int, int> index = virtualNodeContains( mouseEvent->pos() );
if ( index != QPair<int, int>( -1, -1 ) && m_adjustedNode == -2 ) {
Q_ASSERT( m_virtualHovered == index );
const int i = index.first;
const int j = index.second;
if ( i != -1 && j == -1 ) {
GeoDataLinearRing newRing( Tessellate );
QVector<PolylineNode> newList;
newList.reserve(outerRing.size());
for ( int k = i; k < i + outerRing.size(); ++k ) {
newRing.append( outerRing.at(k % outerRing.size()) );
PolylineNode newNode;
newNode.setFlags( m_outerNodesList.at(k % outerRing.size()).flags() );
newList.append( newNode );
}
GeoDataCoordinates newCoords = newRing.first().interpolate( newRing.last(), 0.5 );
newRing.append( newCoords );
m_outerNodesList = newList;
m_outerNodesList.append( PolylineNode( QRegion() ) );
polygon->outerBoundary() = newRing;
m_adjustedNode = -1;
} else {
Q_ASSERT( i != -1 && j != -1 );
GeoDataLinearRing newRing( Tessellate );
QVector<PolylineNode> newList;
newList.reserve(innerRings.at(i).size());
for ( int k = j; k < j + innerRings.at(i).size(); ++k ) {
newRing.append( innerRings.at(i).at(k % innerRings.at(i).size()) );
PolylineNode newNode;
newNode.setFlags( m_innerNodesList.at(i).at(k % innerRings.at(i).size()).flags() );
newList.append( newNode );
}
GeoDataCoordinates newCoords = newRing.first().interpolate( newRing.last(), 0.5 );
newRing.append( newCoords );
m_innerNodesList[i] = newList;
m_innerNodesList[i].append( PolylineNode( QRegion() ) );
polygon->innerBoundaries()[i] = newRing;
m_adjustedNode = i;
}
m_virtualHovered = QPair<int, int>( -1, -1 );
return true;
}
// If a virtual node which has been previously clicked and selected to become a
// 'real node' is clicked one more time, it stops from being 'adjusted'.
const int outerIndex = outerNodeContains( mouseEvent->pos() );
if ( outerIndex != -1 && m_adjustedNode != -2 ) {
m_adjustedNode = -2;
return true;
}
const QPair<int,int> innerIndex = innerNodeContains( mouseEvent->pos() );
if ( innerIndex != QPair<int, int>( -1, -1 ) && m_adjustedNode != -2 ) {
m_adjustedNode = -2;
return true;
}
return false;
}
bool AreaAnnotation::processAddingNodesOnMove( QMouseEvent *mouseEvent )
{
Q_ASSERT( mouseEvent->button() == Qt::NoButton );
const QPair<int, int> index = virtualNodeContains( mouseEvent->pos() );
// If we are adjusting a virtual node which has just been clicked and became real, just
// change its coordinates when moving it, as we do with nodes in Editing state on move.
if ( m_adjustedNode != -2 ) {
// The virtual node which has just been added is always the last within
// GeoDataLinearRing's container.qreal lon, lat;
qreal lon, lat;
m_viewport->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
const GeoDataCoordinates newCoords( lon, lat );
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( placemark()->geometry() );
if ( m_adjustedNode == -1 ) {
polygon->outerBoundary().last() = newCoords;
} else {
Q_ASSERT( m_adjustedNode >= 0 );
polygon->innerBoundaries()[m_adjustedNode].last() = newCoords;
}
return true;
// If we are hovering a virtual node, store its index in order to be painted in drawNodes
// method.
} else if ( index != QPair<int, int>( -1, -1 ) ) {
m_virtualHovered = index;
return true;
}
// This means that the interior of the polygon has been hovered. Let the event propagate
// since there may be overlapping polygons.
return false;
}
bool AreaAnnotation::processAddingNodesOnRelease( QMouseEvent *mouseEvent )
{
Q_UNUSED( mouseEvent );
return m_adjustedNode == -2;
}
bool AreaAnnotation::dealWithHovering( QMouseEvent *mouseEvent )
{
const PolylineNode::PolyNodeFlag flag = state() == SceneGraphicsItem::Editing ?
PolylineNode::NodeIsEditingHighlighted :
PolylineNode::NodeIsMergingHighlighted;
const int outerIndex = outerNodeContains( mouseEvent->pos() );
if ( outerIndex != -1 ) {
if ( !m_outerNodesList.at(outerIndex).isEditingHighlighted() &&
!m_outerNodesList.at(outerIndex).isMergingHighlighted() ) {
// Deal with the case when two nodes are very close to each other.
if ( m_hoveredNode != QPair<int, int>( -1, -1 ) ) {
const int i = m_hoveredNode.first;
const int j = m_hoveredNode.second;
if ( j == -1 ) {
m_outerNodesList[i].setFlag( flag, false );
} else {
m_innerNodesList[i][j].setFlag( flag, false );
}
}
m_hoveredNode = QPair<int, int>( outerIndex, -1 );
m_outerNodesList[outerIndex].setFlag( flag );
setRequest( ChangeCursorPolygonNodeHover );
}
return true;
} else if ( m_hoveredNode != QPair<int, int>( -1, -1 ) && m_hoveredNode.second == -1 ) {
m_outerNodesList[m_hoveredNode.first].setFlag( flag, false );
m_hoveredNode = QPair<int, int>( -1, -1 );
return true;
}
const QPair<int, int> innerIndex = innerNodeContains( mouseEvent->pos() );
if ( innerIndex != QPair<int, int>( -1, -1 ) ) {
if ( !m_innerNodesList.at(innerIndex.first).at(innerIndex.second).isEditingHighlighted() &&
!m_innerNodesList.at(innerIndex.first).at(innerIndex.second).isMergingHighlighted()) {
// Deal with the case when two nodes are very close to each other.
if ( m_hoveredNode != QPair<int, int>( -1, -1 ) ) {
const int i = m_hoveredNode.first;
const int j = m_hoveredNode.second;
if ( j == -1 ) {
m_outerNodesList[i].setFlag( flag, false );
} else {
m_innerNodesList[i][j].setFlag( flag, false );
}
}
m_hoveredNode = innerIndex;
m_innerNodesList[innerIndex.first][innerIndex.second].setFlag( flag );
setRequest( ChangeCursorPolygonNodeHover );
}
return true;
} else if ( m_hoveredNode != QPair<int, int>( -1, -1 ) && m_hoveredNode.second != -1 ) {
m_innerNodesList[m_hoveredNode.first][m_hoveredNode.second].setFlag( flag, false );
m_hoveredNode = QPair<int, int>( -1, -1 );
return true;
}
// This means that the interior of the polygon has been covered so we catch this event too.
setRequest( ChangeCursorPolygonBodyHover );
return true;
}
}
diff --git a/src/plugins/render/annotate/DownloadOsmDialog.cpp b/src/plugins/render/annotate/DownloadOsmDialog.cpp
index 853e172e4..c5606c814 100644
--- a/src/plugins/render/annotate/DownloadOsmDialog.cpp
+++ b/src/plugins/render/annotate/DownloadOsmDialog.cpp
@@ -1,173 +1,173 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2017 Sutirtha Ghosh <ghsutirtha@gmail.com>
//
//Self
#include "DownloadOsmDialog.h"
//Qt
#include <QMessageBox>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QTemporaryFile>
#include <QTemporaryFile>
#include <QDir>
//Marble
#include "ui_DownloadOsmDialog.h"
#include "MarbleWidget.h"
#include "ViewParams.h"
#include "ViewportParams.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataLatLonBox.h"
#include "MarbleGlobal.h"
#include "AnnotatePlugin.h"
#include "LatLonBoxWidget.h"
namespace Marble
{
DownloadOsmDialog::DownloadOsmDialog(MarbleWidget *parent,AnnotatePlugin *annotatePlugin) :
QDialog(parent),
m_marbleWidget(parent),
m_latLonBoxWidget(new LatLonBoxWidget)
{
setupUi(this);
horizontalLayout->addWidget(m_latLonBoxWidget);
this->setWindowTitle("Download");
connect(m_marbleWidget,
SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this,
SLOT(updateCoordinates(GeoDataLatLonAltBox) )
);
m_downloadButton = new QPushButton(tr("Download"));
m_downloadButton->setDefault(true);
buttonBox->addButton(m_downloadButton,QDialogButtonBox::ActionRole);
connect( m_downloadButton, SIGNAL(clicked(bool)), this, SLOT(downloadFile()) );
connect( buttonBox, SIGNAL(reject()), this, SLOT(close()) );
connect( this, SIGNAL(openFile(QString)), annotatePlugin, SLOT(openAnnotationFile(QString)) );
progressBar->hide();
updateCoordinates();
}
DownloadOsmDialog::~DownloadOsmDialog()
{
}
void DownloadOsmDialog::updateCoordinates()
{
m_latLonBoxWidget->setLatLonBox( m_marbleWidget->viewport()->viewLatLonAltBox() );
}
void DownloadOsmDialog::updateCoordinates( const GeoDataLatLonAltBox& boundingBox )
{
m_latLonBoxWidget->setLatLonBox( boundingBox );
}
void DownloadOsmDialog::downloadFile()
{
QString m_west;
QString m_south;
QString m_east;
QString m_north;
QString url;
m_isDownloadSuccess=false;
m_file = new QTemporaryFile(QDir::tempPath()+"/"+"XXXXXXosmdata.osm");
if(!m_file->open())
{
QMessageBox::information(this, tr("ERROR"),
"Unable to create temporary file to download OSM data to.");
this->close();
}
m_downloadButton->setEnabled(false);
m_west=QString::number( m_latLonBoxWidget->latLonBox().west()*RAD2DEG );
m_south=QString::number( m_latLonBoxWidget->latLonBox().south()*RAD2DEG );
m_east=QString::number( m_latLonBoxWidget->latLonBox().east()*RAD2DEG );
m_north=QString::number( m_latLonBoxWidget->latLonBox().north()*RAD2DEG );
url="http://api.openstreetmap.org/api/0.6/map?bbox=";
url+=m_west+",";
url+=m_south+",";
url+=m_east+",";
url+=m_north;
m_reply = m_qnam.get(QNetworkRequest(QUrl(url)));
connect( m_reply, SIGNAL(finished()), this, SLOT(httpFinished()) );
connect( m_reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()) );
progressBar->show();
progressBar->setMinimum(0);
progressBar->setMaximum(0);
}
void DownloadOsmDialog::httpReadyRead()
{
//Reads all the data present and writes it to the file whenever data is
//available
if ( m_file ){
m_file->write(m_reply->readAll());
}
}
void DownloadOsmDialog::httpFinished()
{
QVariant statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
int status = statusCode.toInt();
//in case download fails due to network error or server not available
if ( m_reply->error()==QNetworkReply::NoError ){
m_isDownloadSuccess=true;
}
else {
switch(status)
{
case 400:
QMessageBox::information(this, tr("ERROR"),
"The selected region contains too much data.Please select a smaller region and try again.");
m_downloadButton->setEnabled(true);
m_isDownloadSuccess=false;
break;
case 509:
QMessageBox::information(this, tr("ERROR"),
"The bandwidth limit exceeded.Please try again later.");
m_downloadButton->setEnabled(true);
m_isDownloadSuccess=false;
break;
default:
QMessageBox::information(this, tr("ERROR"),"Sorry, a network error occured.Please check your internet connection"
" or try again later.");
m_downloadButton->setEnabled(true);
m_isDownloadSuccess=false;
break;
}
}
progressBar->hide();
m_file->flush();
m_file->close();
if( m_isDownloadSuccess ) {
emit openFile(m_file->fileName());
}
m_reply->deleteLater();
- m_reply=0;
+ m_reply=nullptr;
delete m_file;
- m_file=0;
+ m_file=nullptr;
if( m_isDownloadSuccess ) {
this->close();
}
}
}
#include "moc_DownloadOsmDialog.cpp"
diff --git a/src/plugins/render/annotate/DownloadOsmDialog.h b/src/plugins/render/annotate/DownloadOsmDialog.h
index c4614a749..f0332867e 100644
--- a/src/plugins/render/annotate/DownloadOsmDialog.h
+++ b/src/plugins/render/annotate/DownloadOsmDialog.h
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2017 Sutirtha Ghosh <ghsutirtha@gmail.com>
//
#ifndef DOWNLOADOSMDIALOG_H
#define DOWNLOADOSMDIALOG_H
#include <QDialog>
#include <QPushButton>
#include <GeoDataLatLonAltBox.h>
#include <QtNetwork>
#include <QProgressDialog>
#include <QTemporaryFile>
#include "LatLonBoxWidget.h"
#include "ui_DownloadOsmDialog.h"
namespace Marble
{
class MarbleWidget;
class AnnotatePlugin;
class DownloadOsmDialog : public QDialog,private Ui::DownloadOsmDialog
{
Q_OBJECT
public:
- explicit DownloadOsmDialog(MarbleWidget *parent = 0,AnnotatePlugin *annotatePlugin = 0);
+ explicit DownloadOsmDialog(MarbleWidget *parent = nullptr,AnnotatePlugin *annotatePlugin = nullptr);
~DownloadOsmDialog();
Q_SIGNALS:
void openFile(const QString &filename);
private:
void updateCoordinates();
MarbleWidget *m_marbleWidget;
QPushButton *m_downloadButton;
QNetworkAccessManager m_qnam;
QNetworkReply *m_reply;
QTemporaryFile *m_file;
LatLonBoxWidget *m_latLonBoxWidget;
bool m_isDownloadSuccess;
private Q_SLOTS:
void downloadFile();
void updateCoordinates(const GeoDataLatLonAltBox&);
void httpReadyRead();
void httpFinished();
};
}
#endif // DOWNLOADOSMDIALOG_H
diff --git a/src/plugins/render/annotate/EditGroundOverlayDialog.h b/src/plugins/render/annotate/EditGroundOverlayDialog.h
index 05817caf6..07220e192 100644
--- a/src/plugins/render/annotate/EditGroundOverlayDialog.h
+++ b/src/plugins/render/annotate/EditGroundOverlayDialog.h
@@ -1,45 +1,45 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Adrian Draghici <draghici.adrian.b@gmail.com>
//
#ifndef MARBLE_EDITGROUNDOVERLAYDIALOG_H
#define MARBLE_EDITGROUNDOVERLAYDIALOG_H
#include <QDialog>
namespace Marble
{
class TextureLayer;
class GeoDataGroundOverlay;
class EditGroundOverlayDialog : public QDialog
{
Q_OBJECT
public:
- EditGroundOverlayDialog( GeoDataGroundOverlay *overlay, TextureLayer *textureLayer, QWidget *parent = 0 );
+ EditGroundOverlayDialog( GeoDataGroundOverlay *overlay, TextureLayer *textureLayer, QWidget *parent = nullptr );
~EditGroundOverlayDialog() override;
private Q_SLOTS:
void updateGroundOverlay();
void setGroundOverlayUpdated();
void checkFields();
Q_SIGNALS:
void groundOverlayUpdated( GeoDataGroundOverlay* );
private:
class Private;
Private * const d;
};
}
#endif
diff --git a/src/plugins/render/annotate/EditPolygonDialog.cpp b/src/plugins/render/annotate/EditPolygonDialog.cpp
index 317637bc6..b7054534b 100644
--- a/src/plugins/render/annotate/EditPolygonDialog.cpp
+++ b/src/plugins/render/annotate/EditPolygonDialog.cpp
@@ -1,342 +1,342 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
// Self
#include "EditPolygonDialog.h"
#include "ui_EditPolygonDialog.h"
// Qt
#include <QColorDialog>
#include <QMessageBox>
// Marble
#include "GeoDataPlacemark.h"
#include "GeoDataStyle.h"
#include "GeoDataLineStyle.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "NodeModel.h"
#include "NodeItemDelegate.h"
#include "FormattedTextWidget.h"
#include "StyleBuilder.h"
#include "osm/OsmTagEditorWidget.h"
#include "osm/OsmPlacemarkData.h"
#include "osm/OsmRelationManagerWidget.h"
namespace Marble {
class Q_DECL_HIDDEN EditPolygonDialog::Private : public Ui::UiEditPolygonDialog
{
public:
Private( GeoDataPlacemark *placemark );
~Private();
GeoDataPlacemark *m_placemark;
QColorDialog *m_linesDialog;
QColorDialog *m_polyDialog;
QString m_initialDescription;
QString m_initialName;
GeoDataStyle m_initialStyle;
GeoDataLinearRing m_initialOuterBoundary;
OsmPlacemarkData m_initialOsmData;
bool m_hadInitialOsmData;
NodeModel *m_nodeModel;
NodeItemDelegate *m_delegate;
OsmTagEditorWidget *m_osmTagEditorWidget;
OsmRelationManagerWidget *m_osmRelationManagerWidget;
};
EditPolygonDialog::Private::Private( GeoDataPlacemark *placemark ) :
Ui::UiEditPolygonDialog(),
m_placemark( placemark ),
- m_linesDialog( 0 ),
- m_polyDialog( 0 ),
+ m_linesDialog( nullptr ),
+ m_polyDialog( nullptr ),
m_nodeModel( new NodeModel ),
- m_osmTagEditorWidget( 0 ),
- m_osmRelationManagerWidget( 0 )
+ m_osmTagEditorWidget( nullptr ),
+ m_osmRelationManagerWidget( nullptr )
{
// nothing to do
}
EditPolygonDialog::Private::~Private()
{
delete m_linesDialog;
delete m_polyDialog;
delete m_nodeModel;
delete m_delegate;
}
EditPolygonDialog::EditPolygonDialog( GeoDataPlacemark *placemark,
const QHash<qint64, OsmPlacemarkData> *relations,
QWidget *parent ) :
QDialog( parent ),
d( new Private( placemark ) )
{
d->setupUi( this );
// There's no point showing Relations and Tags tabs if the editor was not
// loaded from the annotate plugin ( loaded from tourWidget.. )
if ( relations ) {
// Adding the osm tag editor widget tab
d->m_osmTagEditorWidget = new OsmTagEditorWidget( placemark, this );
d->tabWidget->addTab( d->m_osmTagEditorWidget, tr( "Tags" ) );
QObject::connect( d->m_osmTagEditorWidget, SIGNAL( placemarkChanged( GeoDataFeature* ) ),
this, SLOT( updatePolygon() ) );
// Adding the osm relation editor widget tab
d->m_osmRelationManagerWidget = new OsmRelationManagerWidget( placemark, relations, this );
d->tabWidget->addTab( d->m_osmRelationManagerWidget, tr( "Relations" ) );
QObject::connect( d->m_osmRelationManagerWidget, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SIGNAL( relationCreated( const OsmPlacemarkData& ) ) );
adjustSize();
}
d->m_hadInitialOsmData = placemark->hasOsmData();
if ( d->m_hadInitialOsmData ) {
d->m_initialOsmData = placemark->osmData();
}
d->m_initialStyle = *placemark->style();
// If the polygon has just been drawn, assign it a default name.
if ( d->m_placemark->name().isNull() ) {
d->m_placemark->setName( tr("Untitled Polygon") );
}
d->m_name->setText( placemark->name() );
d->m_initialName = placemark->name();
connect( d->m_name, SIGNAL(editingFinished()), this, SLOT(updatePolygon()) );
d->m_formattedTextWidget->setText( placemark->description() );
d->m_initialDescription = placemark->description();
// Get the current style properties.
const GeoDataLineStyle lineStyle = placemark->style()->lineStyle();
const GeoDataPolyStyle polyStyle = placemark->style()->polyStyle();
d->m_linesWidth->setRange( 0.1, 5.0 );
d->m_linesWidth->setValue( lineStyle.width() );
connect( d->m_linesWidth, SIGNAL(valueChanged(double)), this, SLOT( handleChangingStyle() ) );
// Adjust the "Filled"/"Not Filled" option according to its current fill.
if ( polyStyle.fill() ) {
d->m_filledColor->setCurrentIndex( 0 );
} else {
d->m_filledColor->setCurrentIndex( 1 );
}
connect( d->m_filledColor, SIGNAL(currentIndexChanged(int)), this, SLOT( handleChangingStyle() ) );
// Adjust the color buttons' icons to the current lines and polygon colors.
QPixmap linesPixmap( d->m_linesColorButton->iconSize().width(),
d->m_linesColorButton->iconSize().height() );
linesPixmap.fill( lineStyle.color() );
d->m_linesColorButton->setIcon( QIcon( linesPixmap ) );
QPixmap polyPixmap( d->m_polyColorButton->iconSize().width(),
d->m_polyColorButton->iconSize().height() );
polyPixmap.fill( polyStyle.color() );
d->m_polyColorButton->setIcon( QIcon( polyPixmap ) );
// Setup the color dialogs.
d->m_linesDialog = new QColorDialog( this );
d->m_linesDialog->setOption( QColorDialog::ShowAlphaChannel );
d->m_linesDialog->setCurrentColor( lineStyle.color() );
connect( d->m_linesColorButton, SIGNAL(clicked()), d->m_linesDialog, SLOT(exec()) );
connect( d->m_linesDialog, SIGNAL(colorSelected(QColor)), this, SLOT(updateLinesDialog(QColor)) );
connect( d->m_linesDialog, SIGNAL(colorSelected(QColor)), this, SLOT( handleChangingStyle() ) );
d->m_polyDialog = new QColorDialog( this );
d->m_polyDialog->setOption( QColorDialog::ShowAlphaChannel );
d->m_polyDialog->setCurrentColor( polyStyle.color() );
connect( d->m_polyColorButton, SIGNAL(clicked()), d->m_polyDialog, SLOT(exec()) );
connect( d->m_polyDialog, SIGNAL(colorSelected(QColor)), this, SLOT(updatePolyDialog(QColor)) );
connect( d->m_polyDialog, SIGNAL(colorSelected(QColor)), this, SLOT( handleChangingStyle() ) );
// Setting the NodeView's delegate: mainly used for the editing the polygon's nodes
d->m_delegate = new NodeItemDelegate( d->m_placemark, d->m_nodeView );
connect( d->m_delegate, SIGNAL(modelChanged(GeoDataPlacemark*)),
this, SLOT(handleItemMoving(GeoDataPlacemark*)) );
connect( d->m_delegate, SIGNAL(geometryChanged()),
this, SLOT(updatePolygon()) );
d->m_nodeView->setItemDelegate( d->m_delegate );
d->m_nodeView->setEditTriggers( QAbstractItemView::AllEditTriggers );
// Populating the model
if (const GeoDataPolygon *polygon = geodata_cast<GeoDataPolygon>(placemark->geometry())) {
GeoDataLinearRing outerBoundary = polygon->outerBoundary();
for( int i = 0; i < outerBoundary.size(); ++i ) {
d->m_nodeModel->addNode( outerBoundary.at( i ) );
}
d->m_initialOuterBoundary = outerBoundary;
}
d->m_nodeView->setModel( d->m_nodeModel );
// Resize column to contents size for better UI.
d->m_nodeView->resizeColumnToContents( 0 );
// Promote "Ok" button to default button.
d->buttonBox->button( QDialogButtonBox::Ok )->setDefault( true );
connect( d->buttonBox->button( QDialogButtonBox::Ok ), SIGNAL(pressed()), this, SLOT(checkFields()) );
connect( this, SIGNAL(accepted()), SLOT(updatePolygon()) );
connect( this, SIGNAL(finished(int)), SLOT(restoreInitial(int)) );
// Ensure that the dialog gets deleted when closing it (either when clicking OK or
// Close).
connect( this, SIGNAL(finished(int)), SLOT(deleteLater()) );
}
EditPolygonDialog::~EditPolygonDialog()
{
delete d;
}
void EditPolygonDialog::handleAddingNode( const GeoDataCoordinates &node )
{
d->m_nodeModel->addNode( node );
}
void EditPolygonDialog::handleItemMoving( GeoDataPlacemark *item )
{
if( item == d->m_placemark ) {
d->m_nodeModel->clear();
if (const auto polygon = geodata_cast<GeoDataPolygon>(d->m_placemark->geometry())) {
GeoDataLinearRing outerBoundary = polygon->outerBoundary();
for( int i = 0; i < outerBoundary.size(); ++i ) {
d->m_nodeModel->addNode( outerBoundary.at( i ) );
}
}
}
}
void EditPolygonDialog::handleChangingStyle()
{
// The default style of the polygon has been changed, thus the old style URL is no longer valid
d->m_placemark->setStyleUrl(QString());
GeoDataStyle::Ptr style(new GeoDataStyle( *d->m_placemark->style() ));
style->lineStyle().setWidth( d->m_linesWidth->value() );
// 0 corresponds to "Filled" and 1 corresponds to "Not Filled".
style->polyStyle().setFill( !d->m_filledColor->currentIndex() );
style->setId(d->m_placemark->id() + QLatin1String("Style"));
// Adjust the lines/polygon colors.
// QColorDialog::currentColor() also works even if the color dialog
// has not been exec'ed, while QColorDialog::selectedColor() does not.
style->lineStyle().setColor( d->m_linesDialog->currentColor() );
style->polyStyle().setColor( d->m_polyDialog->currentColor() );
d->m_placemark->setStyle( style );
updatePolygon();
}
void EditPolygonDialog::updatePolygon()
{
d->m_placemark->setName( d->m_name->text() );
d->m_placemark->setDescription( d->m_formattedTextWidget->text() );
// If there is not custom style initialized( default #polyline url is used ) and there is a osmTag-based style
// available, set it
const OsmPlacemarkData osmData = d->m_osmTagEditorWidget->placemarkData();
const GeoDataPlacemark::GeoDataVisualCategory category = StyleBuilder::determineVisualCategory(osmData);
if (d->m_placemark->styleUrl() == QLatin1String("#polygon") && category != GeoDataPlacemark::None) {
d->m_placemark->setStyle( GeoDataStyle::Ptr() ); // first clear style so style gets set by setVisualCategory()
d->m_placemark->setVisualCategory( category );
}
emit polygonUpdated( d->m_placemark );
}
void EditPolygonDialog::updateLinesDialog( const QColor &color )
{
QPixmap linesPixmap( d->m_linesColorButton->iconSize().width(),
d->m_linesColorButton->iconSize().height() );
linesPixmap.fill( color );
d->m_linesColorButton->setIcon( QIcon( linesPixmap ) );
}
void EditPolygonDialog::updatePolyDialog( const QColor &color )
{
QPixmap polyPixmap( d->m_polyColorButton->iconSize().width(),
d->m_polyColorButton->iconSize().height() );
polyPixmap.fill( color );
d->m_polyColorButton->setIcon( QIcon( polyPixmap ) );
}
void EditPolygonDialog::checkFields()
{
bool ok = true;
if ( d->m_name->text().isEmpty() ) {
QMessageBox::warning( this,
tr( "No name specified" ),
tr( "Please specify a name for this polygon." ) );
ok = false;
} else {
if (const auto polygon = geodata_cast<GeoDataPolygon>(d->m_placemark->geometry())) {
if( polygon->outerBoundary().size() < 3 ) {
QMessageBox::warning( this,
tr( "Not enough nodes specified." ),
tr( "Please specify at least 3 nodes for the polygon by clicking on the map." ) );
ok = false;
}
}
}
if( ok ) {
accept();
}
}
void EditPolygonDialog::restoreInitial( int result )
{
if ( result ) {
return;
}
GeoDataPolygon *polygon = static_cast<GeoDataPolygon*>( d->m_placemark->geometry() );
GeoDataLinearRing outerBoundary = polygon->outerBoundary();
if ( outerBoundary != d->m_initialOuterBoundary ) {
polygon->setOuterBoundary( d->m_initialOuterBoundary );
}
if ( d->m_placemark->name() != d->m_initialName ) {
d->m_placemark->setName( d->m_initialName );
}
if ( d->m_placemark->description() != d->m_initialDescription ) {
d->m_placemark->setDescription( d->m_initialDescription );
}
if ( *d->m_placemark->style() != d->m_initialStyle ) {
d->m_placemark->setStyle( GeoDataStyle::Ptr(new GeoDataStyle( d->m_initialStyle )) );
}
if( d->m_hadInitialOsmData ) {
d->m_placemark->setOsmData( d->m_initialOsmData );
}
emit polygonUpdated( d->m_placemark );
}
}
#include "moc_EditPolygonDialog.cpp"
diff --git a/src/plugins/render/annotate/EditPolygonDialog.h b/src/plugins/render/annotate/EditPolygonDialog.h
index d4acd52c9..c52d43f0e 100644
--- a/src/plugins/render/annotate/EditPolygonDialog.h
+++ b/src/plugins/render/annotate/EditPolygonDialog.h
@@ -1,71 +1,71 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
#ifndef MARBLE_EDITPOLYGONDIALOG_H
#define MARBLE_EDITPOLYGONDIALOG_H
#include <QDialog>
#include <QColor>
#include "MarbleGlobal.h"
namespace Marble {
class GeoDataPlacemark;
class GeoDataCoordinates;
class GeoDataFeature;
class OsmPlacemarkData;
/**
* @brief As it name says by itself, this class is used to show a couple of
* editing options for a polygon. So far there are only a few customization
* options, such as lines width, lines/area color, lines/area opacity.
*/
class EditPolygonDialog : public QDialog
{
Q_OBJECT
public:
EditPolygonDialog( GeoDataPlacemark *placemark,
- const QHash<qint64, OsmPlacemarkData> *relations = 0,
- QWidget *parent = 0 );
+ const QHash<qint64, OsmPlacemarkData> *relations = nullptr,
+ QWidget *parent = nullptr );
~EditPolygonDialog() override;
public Q_SLOTS:
void handleAddingNode( const GeoDataCoordinates &node );
void handleItemMoving( GeoDataPlacemark *item );
void handleChangingStyle();
void updatePolygon();
Q_SIGNALS:
void polygonUpdated( GeoDataFeature *feature );
/**
* @brief relationCreated signals the annotate plugin that a new relation has been
* created( or modified ) within the relation editor
* @param relation the relation's osmData
*/
void relationCreated( const OsmPlacemarkData &relation );
private Q_SLOTS:
void updateLinesDialog( const QColor &color );
void updatePolyDialog( const QColor &color );
void checkFields();
void restoreInitial( int result );
private:
class Private;
Private * const d;
};
}
#endif
diff --git a/src/plugins/render/annotate/EditPolylineDialog.cpp b/src/plugins/render/annotate/EditPolylineDialog.cpp
index 79af4dd91..35db0e093 100644
--- a/src/plugins/render/annotate/EditPolylineDialog.cpp
+++ b/src/plugins/render/annotate/EditPolylineDialog.cpp
@@ -1,298 +1,298 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
// Self
#include "EditPolylineDialog.h"
#include "ui_EditPolylineDialog.h"
// Qt
#include <QColorDialog>
#include <QMessageBox>
// Marble
#include "GeoDataPlacemark.h"
#include "GeoDataLineString.h"
#include "GeoDataStyle.h"
#include "GeoDataLineStyle.h"
#include "NodeModel.h"
#include "FormattedTextWidget.h"
#include "NodeItemDelegate.h"
#include "StyleBuilder.h"
#include "osm/OsmTagEditorWidget.h"
#include "osm/OsmPlacemarkData.h"
#include "osm/OsmRelationManagerWidget.h"
namespace Marble
{
class Q_DECL_HIDDEN EditPolylineDialog::Private : public Ui::UiEditPolylineDialog
{
public:
Private( GeoDataPlacemark *placemark);
~Private();
QColorDialog *m_linesDialog;
OsmTagEditorWidget *m_osmTagEditorWidget;
OsmRelationManagerWidget *m_osmRelationManagerWidget;
GeoDataPlacemark *m_placemark;
// Used to restore if the Cancel button is pressed.
QString m_initialName;
QString m_initialDescription;
GeoDataLineStyle m_initialLineStyle;
GeoDataLineString m_initialLineString;
OsmPlacemarkData m_initialOsmData;
bool m_hadInitialOsmData;
NodeItemDelegate *m_delegate;
NodeModel *m_nodeModel;
};
EditPolylineDialog::Private::Private( GeoDataPlacemark *placemark ) :
Ui::UiEditPolylineDialog(),
- m_linesDialog( 0 ),
- m_osmTagEditorWidget( 0 ),
- m_osmRelationManagerWidget( 0 ),
+ m_linesDialog( nullptr ),
+ m_osmTagEditorWidget( nullptr ),
+ m_osmRelationManagerWidget( nullptr ),
m_placemark( placemark ),
m_nodeModel( new NodeModel )
{
// nothing to do
}
EditPolylineDialog::Private::~Private()
{
delete m_linesDialog;
delete m_nodeModel;
delete m_delegate;
}
EditPolylineDialog::EditPolylineDialog( GeoDataPlacemark *placemark,
const QHash<qint64, OsmPlacemarkData> *relations,
QWidget *parent ) :
QDialog( parent ) ,
d ( new Private( placemark ) )
{
d->setupUi( this );
// There's no point showing Relations and Tags tabs if the editor was not
// loaded from the annotate plugin ( loaded from tourWidget.. )
if ( relations ) {
// Adding the osm tag editor widget tab
d->m_osmTagEditorWidget = new OsmTagEditorWidget( placemark, this );
d->tabWidget->addTab( d->m_osmTagEditorWidget, tr( "Tags" ) );
QObject::connect( d->m_osmTagEditorWidget, SIGNAL( placemarkChanged( GeoDataFeature* ) ),
this, SLOT( updatePolyline() ) );
// Adding the osm relation editor widget tab
d->m_osmRelationManagerWidget = new OsmRelationManagerWidget( placemark, relations, this );
d->tabWidget->addTab( d->m_osmRelationManagerWidget, tr( "Relations" ) );
QObject::connect( d->m_osmRelationManagerWidget, SIGNAL( relationCreated( const OsmPlacemarkData& ) ),
this, SIGNAL( relationCreated( const OsmPlacemarkData& ) ) );
adjustSize();
}
d->m_hadInitialOsmData = placemark->hasOsmData();
if ( d->m_hadInitialOsmData ) {
d->m_initialOsmData = placemark->osmData();
}
// If the polygon has just been drawn, assign it a default name.
if ( d->m_placemark->name().isNull() ) {
d->m_placemark->setName( tr("Untitled Path") );
}
d->m_initialLineString = *(static_cast<GeoDataLineString*>( placemark->geometry() ) );
d->m_name->setText( placemark->name() );
d->m_initialName = d->m_name->text();
connect( d->m_name, SIGNAL(editingFinished()), this, SLOT(updatePolyline()) );
d->m_formattedTextWidget->setText( placemark->description() );
d->m_initialDescription = d->m_formattedTextWidget->text();
d->m_linesWidth->setRange( 0.1, 5.0 );
// Get the current style properties.
const GeoDataLineStyle lineStyle = placemark->style()->lineStyle();
d->m_initialLineStyle = lineStyle;
d->m_linesWidth->setValue( lineStyle.width() );
connect( d->m_linesWidth, SIGNAL(valueChanged(double)), this, SLOT(handleChangingStyle()) );
// Adjust the color button's icon to the current lines color.
QPixmap linesPixmap( d->m_linesColorButton->iconSize() );
linesPixmap.fill( lineStyle.color() );
d->m_linesColorButton->setIcon( QIcon( linesPixmap ) );
// Setting the NodeView's delegate: mainly used for the editing the polyline's nodes
d->m_delegate = new NodeItemDelegate( d->m_placemark, d->m_nodeView );
connect( d->m_delegate, SIGNAL(modelChanged(GeoDataPlacemark*)),
this, SLOT(handleItemMoving(GeoDataPlacemark*)) );
connect( d->m_delegate, SIGNAL(geometryChanged()),
this, SLOT(updatePolyline()) );
d->m_nodeView->setItemDelegate( d->m_delegate );
d->m_nodeView->setEditTriggers( QAbstractItemView::AllEditTriggers );
// Setup the color dialogs.
d->m_linesDialog = new QColorDialog( this );
d->m_linesDialog->setOption( QColorDialog::ShowAlphaChannel );
d->m_linesDialog->setCurrentColor( lineStyle.color() );
connect( d->m_linesColorButton, SIGNAL(clicked()), d->m_linesDialog, SLOT(exec()) );
connect( d->m_linesDialog, SIGNAL(colorSelected(QColor)), this, SLOT(updateLinesDialog(QColor)) );
connect( d->m_linesDialog, SIGNAL(colorSelected(QColor)), this, SLOT(handleChangingStyle()) );
if (const auto lineString = geodata_cast<GeoDataLineString>(placemark->geometry())) {
for( int i = 0; i < lineString->size(); ++i ) {
d->m_nodeModel->addNode( lineString->at( i ) );
}
}
d->m_nodeView->setModel( d->m_nodeModel );
// Resize column to contents size for better UI.
d->m_nodeView->resizeColumnToContents( 0 );
// Promote "Ok" button to default button.
d->buttonBox->button( QDialogButtonBox::Ok )->setDefault( true );
connect( d->buttonBox->button( QDialogButtonBox::Ok ), SIGNAL(pressed()), this, SLOT(checkFields()) );
connect( this, SIGNAL(accepted()), SLOT(updatePolyline()) );
connect( this, SIGNAL(finished(int)), SLOT(restoreInitial(int)) );
// Ensure that the dialog gets deleted when closing it (either when clicking OK or
// Close).
connect( this, SIGNAL(finished(int)), SLOT(deleteLater()) );
}
EditPolylineDialog::~EditPolylineDialog()
{
delete d;
}
void EditPolylineDialog::handleAddingNode( const GeoDataCoordinates &node )
{
d->m_nodeModel->addNode( node );
}
void EditPolylineDialog::handleItemMoving( GeoDataPlacemark *item )
{
if( item == d->m_placemark ) {
d->m_nodeModel->clear();
if (const auto lineString = geodata_cast<GeoDataLineString>(d->m_placemark->geometry())) {
for( int i = 0; i < lineString->size(); ++i ) {
d->m_nodeModel->addNode( lineString->at( i ) );
}
}
}
}
void EditPolylineDialog::handleChangingStyle()
{
// The default style has been changed, thus the old style URL is no longer valid
// The polyline is now considered to have a customStyle
d->m_placemark->setStyleUrl(QString());
GeoDataStyle::Ptr newStyle(new GeoDataStyle( *d->m_placemark->style() ));
newStyle->lineStyle().setColor( d->m_linesDialog->currentColor() );
newStyle->lineStyle().setWidth( d->m_linesWidth->value() );
newStyle->setId(d->m_placemark->id() + QLatin1String("Style"));
d->m_placemark->setStyle( newStyle );
updatePolyline();
}
void EditPolylineDialog::updatePolyline()
{
d->m_placemark->setDescription( d->m_formattedTextWidget->text() );
d->m_placemark->setName( d->m_name->text() );
// If there is no custom style initialized( default #polyline url is used ) and there is a osmTag-based style
// available, set it
const OsmPlacemarkData osmData = d->m_osmTagEditorWidget->placemarkData();
const GeoDataPlacemark::GeoDataVisualCategory category = StyleBuilder::determineVisualCategory(osmData);
if (d->m_placemark->styleUrl() == QLatin1String("#polyline") && category != GeoDataPlacemark::None) {
d->m_placemark->setStyle( GeoDataStyle::Ptr() ); // first clear style so style gets set by setVisualCategory()
d->m_placemark->setVisualCategory( category );
}
emit polylineUpdated( d->m_placemark );
}
void EditPolylineDialog::updateLinesDialog( const QColor &color )
{
QPixmap linesPixmap( d->m_linesColorButton->iconSize().width(),
d->m_linesColorButton->iconSize().height() );
linesPixmap.fill( color );
d->m_linesColorButton->setIcon( QIcon( linesPixmap ) );
}
void EditPolylineDialog::restoreInitial( int result )
{
if ( result ) {
return;
}
GeoDataLineString* currentLineString = static_cast<GeoDataLineString*>( d->m_placemark->geometry() );
if( *currentLineString != d->m_initialLineString ) {
d->m_placemark->setGeometry( new GeoDataLineString( d->m_initialLineString ) );
}
if ( d->m_placemark->name() != d->m_initialName ) {
d->m_placemark->setName( d->m_initialName );
}
if ( d->m_placemark->description() != d->m_initialDescription ) {
d->m_placemark->setDescription( d->m_initialDescription );
}
if ( d->m_placemark->style()->lineStyle() != d->m_initialLineStyle ) {
GeoDataStyle::Ptr newStyle(new GeoDataStyle( *d->m_placemark->style() ));
newStyle->setLineStyle( d->m_initialLineStyle );
d->m_placemark->setStyle( newStyle );
}
if( d->m_hadInitialOsmData ) {
d->m_placemark->setOsmData( d->m_initialOsmData );
}
emit polylineUpdated( d->m_placemark );
}
void EditPolylineDialog::checkFields()
{
bool ok = true;
if ( d->m_name->text().isEmpty() ) {
QMessageBox::warning( this,
tr( "No name specified" ),
tr( "Please specify a name for this polyline." ) );
ok = false;
} else {
if (const auto lineString = geodata_cast<GeoDataLineString>(d->m_placemark->geometry())) {
if( lineString->size() < 2 ) {
QMessageBox::warning( this,
tr( "Not enough nodes specified." ),
tr( "Please specify at least 2 nodes for the path by clicking on the map." ) );
ok = false;
}
}
}
if( ok ) {
accept();
}
}
}
#include "moc_EditPolylineDialog.cpp"
diff --git a/src/plugins/render/annotate/EditPolylineDialog.h b/src/plugins/render/annotate/EditPolylineDialog.h
index 27bbcd5cb..bcd9c0841 100644
--- a/src/plugins/render/annotate/EditPolylineDialog.h
+++ b/src/plugins/render/annotate/EditPolylineDialog.h
@@ -1,61 +1,61 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
#ifndef MARBLE_EDITPOLYLINEDIALOG_H
#define MARBLE_EDITPOLYLINEDIALOG_H
#include <QDialog>
namespace Marble {
class GeoDataPlacemark;
class GeoDataFeature;
class GeoDataCoordinates;
class OsmPlacemarkData;
class EditPolylineDialog : public QDialog
{
Q_OBJECT
public:
EditPolylineDialog( GeoDataPlacemark *placemark,
- const QHash<qint64, OsmPlacemarkData> *relations = 0,
- QWidget *parent = 0 );
+ const QHash<qint64, OsmPlacemarkData> *relations = nullptr,
+ QWidget *parent = nullptr );
~EditPolylineDialog() override;
public Q_SLOTS:
void handleAddingNode( const GeoDataCoordinates &node );
void handleItemMoving( GeoDataPlacemark *item );
void handleChangingStyle();
Q_SIGNALS:
void polylineUpdated( GeoDataFeature *feature );
/**
* @brief relationCreated signals the annotate plugin that a new relation has been
* created( or modified ) within the relation editor
* @param relation the relation's osmData
*/
void relationCreated( const OsmPlacemarkData &relation );
private Q_SLOTS:
void updatePolyline();
void updateLinesDialog( const QColor &color );
void restoreInitial( int result );
void checkFields();
private:
class Private;
Private * const d;
};
}
#endif
diff --git a/src/plugins/render/annotate/GroundOverlayFrame.cpp b/src/plugins/render/annotate/GroundOverlayFrame.cpp
index 67f76f02d..6ad0aa323 100644
--- a/src/plugins/render/annotate/GroundOverlayFrame.cpp
+++ b/src/plugins/render/annotate/GroundOverlayFrame.cpp
@@ -1,398 +1,398 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Adrian Draghici <draghici.adrian.b@gmail.com>
//
// Self
#include "GroundOverlayFrame.h"
// Marble
#include "GeoDataPlacemark.h"
#include "GeoDataGroundOverlay.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "SceneGraphicsTypes.h"
#include "TextureLayer.h"
#include "MarbleDirs.h"
// Qt
#include <qmath.h>
namespace Marble
{
GroundOverlayFrame::GroundOverlayFrame( GeoDataPlacemark *placemark,
GeoDataGroundOverlay *overlay,
TextureLayer *textureLayer ) :
SceneGraphicsItem( placemark ),
m_overlay( overlay ),
m_textureLayer( textureLayer ),
m_movedHandle( NoRegion ),
m_hoveredHandle( NoRegion ),
m_editStatus( Resize ),
m_editStatusChangeNeeded( false ),
m_previousRotation( 0.0 ),
- m_viewport( 0 )
+ m_viewport( nullptr )
{
m_resizeIcons.reserve(16);
// NorthWest
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topleft.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topleft-active.png")));
// SouthWest
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topright.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topright-active.png")));
// SouthEast
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topleft.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topleft-active.png")));
// NorthEast
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topright.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-diagonal-topright-active.png")));
// North
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical-active.png")));
// South
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical-active.png")));
// East
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal-active.png")));
// West
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal.png")));
m_resizeIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal-active.png")));
m_rotateIcons.reserve(16);
// NorthWest
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-topleft.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-topleft-active.png")));
// SouthWest
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-bottomleft.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-bottomleft-active.png")));
// SouthEast
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-bottomright.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-bottomright-active.png")));
// NorthEast
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-topright.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-rotation-topright-active.png")));
// North
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal-active.png")));
// South
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-horizontal-active.png")));
// East
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical-active.png")));
// West
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical.png")));
m_rotateIcons.append(QImage(MarbleDirs::systemPath() + QLatin1String("/bitmaps/editarrows/arrow-vertical-active.png")));
update();
setPaintLayers(QStringList() << "GroundOverlayFrame");
}
void GroundOverlayFrame::paint(GeoPainter *painter, const ViewportParams *viewport , const QString &layer, int tileZoomLevel)
{
Q_UNUSED(layer);
Q_UNUSED(tileZoomLevel);
m_viewport = viewport;
m_regionList.clear();
painter->save();
if (const auto polygon = geodata_cast<GeoDataPolygon>(placemark()->geometry())) {
const GeoDataLinearRing &ring = polygon->outerBoundary();
QVector<GeoDataCoordinates> coordinateList;
coordinateList.reserve(8);
coordinateList.append( ring.at( NorthWest ) );
coordinateList.append( ring.at( SouthWest ) );
coordinateList.append( ring.at( SouthEast ) );
coordinateList.append( ring.at( NorthEast ) );
GeoDataCoordinates northernHandle = ring.at( NorthEast ).interpolate( ring.at( NorthWest ), 0.5 );
GeoDataCoordinates southernHandle = ring.at( SouthEast ).interpolate( ring.at( SouthWest ), 0.5 );
// Special case handle position to take tessellation
// along latitude circles into account
if (m_overlay->latLonBox().rotation() == 0) {
northernHandle.setLatitude(ring.at( NorthEast ).latitude());
southernHandle.setLatitude(ring.at( SouthEast ).latitude());
}
coordinateList.append( northernHandle );
coordinateList.append( southernHandle );
coordinateList.append( ring.at( NorthEast ).interpolate( ring.at( SouthEast ), 0.5 ) );
coordinateList.append( ring.at( NorthWest ).interpolate( ring.at( SouthWest ), 0.5 ) );
m_regionList.reserve(9);
m_regionList.append( painter->regionFromEllipse( coordinateList.at( NorthWest ), 16, 16 ) );
m_regionList.append( painter->regionFromEllipse( coordinateList.at( SouthWest ), 16, 16 ) );
m_regionList.append( painter->regionFromEllipse( coordinateList.at( SouthEast ), 16, 16 ) );
m_regionList.append( painter->regionFromEllipse( coordinateList.at( NorthEast ), 16, 16 ) );
m_regionList.append( painter->regionFromEllipse( coordinateList.at( North ), 16, 16 ) );
m_regionList.append( painter->regionFromEllipse( coordinateList.at( South ), 16, 16 ) );
m_regionList.append( painter->regionFromEllipse( coordinateList.at( East ), 16, 16 ) );
m_regionList.append( painter->regionFromEllipse( coordinateList.at( West ), 16, 16 ) );
m_regionList.append( painter->regionFromPolygon( ring, Qt::OddEvenFill ) );
// Calculate handle icon orientation due to the projection
qreal xNW, yNW, xSW, ySW;
viewport->screenCoordinates(ring.at( NorthWest ), xNW, yNW);
viewport->screenCoordinates(ring.at( SouthWest ), xSW, ySW);
qreal westernAngle = qAtan2(ySW - yNW, xSW - xNW) - M_PI/2;
qreal xNE, yNE, xSE, ySE;
viewport->screenCoordinates(ring.at( NorthEast ), xNE, yNE);
viewport->screenCoordinates(ring.at( SouthEast ), xSE, ySE);
qreal easternAngle = qAtan2(ySE - yNE, xSE - xNE) - M_PI/2;
painter->setPen( Qt::DashLine );
painter->setBrush( Qt::NoBrush );
painter->drawPolygon( ring );
qreal projectedAngle = 0;
for( int i = NorthWest; i != Polygon; ++i ) {
// Assign handle icon orientation due to the projection
if (i == NorthWest || i == West || i == SouthWest) {
projectedAngle = westernAngle;
}
else if (i == NorthEast || i == East || i == SouthEast) {
projectedAngle = easternAngle;
}
else if (i == North || i == South) {
projectedAngle = (westernAngle + easternAngle) / 2;
}
QTransform trans;
trans.rotateRadians( projectedAngle );
if ( m_editStatus == Resize ){
if( m_hoveredHandle != i ) {
painter->drawImage( coordinateList.at( i ),
m_resizeIcons.at( 2*i ).transformed( trans, Qt::SmoothTransformation ) );
} else {
painter->drawImage( coordinateList.at( i ),
m_resizeIcons.at( 2*i + 1 ).transformed( trans, Qt::SmoothTransformation ) );
}
} else if ( m_editStatus == Rotate ) {
if( m_hoveredHandle != i ) {
painter->drawImage( coordinateList.at( i ),
m_rotateIcons.at( 2*i ).transformed( trans, Qt::SmoothTransformation ) );
} else {
painter->drawImage( coordinateList.at( i ),
m_rotateIcons.at( 2*i + 1 ).transformed( trans, Qt::SmoothTransformation ) );
}
}
}
}
painter->restore();
}
bool GroundOverlayFrame::containsPoint( const QPoint &eventPos ) const
{
for ( const QRegion &region: m_regionList ) {
if ( region.contains( eventPos ) ) {
return true;
}
}
// This is a bugfix to handle the events even if they occur outside of this object,
// so when rotating or resizing the mouseReleaseEvent is handled successfully
// TODO: maybe find a better way?
return m_movedHandle != NoRegion ||
m_hoveredHandle != NoRegion;
}
void GroundOverlayFrame::dealWithItemChange( const SceneGraphicsItem *other )
{
Q_UNUSED( other );
}
void GroundOverlayFrame::move( const GeoDataCoordinates &source, const GeoDataCoordinates &destination )
{
// not implemented yet
Q_UNUSED( source );
Q_UNUSED( destination );
}
bool GroundOverlayFrame::mousePressEvent( QMouseEvent *event )
{
// React to all ellipse as well as to the polygon.
for ( int i = 0; i < m_regionList.size(); ++i ) {
if ( m_regionList.at(i).contains( event->pos() ) ) {
m_movedHandle = i;
qreal lon, lat;
m_viewport->geoCoordinates( event->pos().x(),
event->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
m_movedHandleGeoCoordinates.set( lon, lat );
m_movedHandleScreenCoordinates = event->pos();
m_previousRotation = m_overlay->latLonBox().rotation();
if ( m_movedHandle == Polygon ) {
m_editStatusChangeNeeded = true;
}
return true;
}
}
return false;
}
bool GroundOverlayFrame::mouseMoveEvent( QMouseEvent *event )
{
if ( !m_viewport ) {
return false;
}
// Catch hover events.
if ( m_movedHandle == NoRegion ) {
for ( int i = 0; i < m_regionList.size(); ++i ) {
if ( m_regionList.at(i).contains( event->pos() ) ) {
if ( i == Polygon ) {
setRequest( ChangeCursorOverlayBodyHover );
} else {
setRequest( ChangeCursorOverlayRotateHover );
}
m_hoveredHandle = i;
return true;
}
}
m_hoveredHandle = NoRegion;
return true;
} else {
m_editStatusChangeNeeded = false;
}
if (geodata_cast<GeoDataPolygon>(placemark()->geometry())) {
qreal lon, lat;
m_viewport->geoCoordinates( event->pos().x(),
event->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
if ( m_editStatus == Resize ) {
GeoDataCoordinates coord(lon, lat);
GeoDataCoordinates rotatedCoord(coord);
if (m_overlay->latLonBox().rotation() != 0) {
rotatedCoord = coord.rotateAround(m_overlay->latLonBox().center(),
-m_overlay->latLonBox().rotation());
}
if ( m_movedHandle == NorthWest ) {
m_overlay->latLonBox().setNorth( rotatedCoord.latitude() );
m_overlay->latLonBox().setWest( rotatedCoord.longitude() );
} else if ( m_movedHandle == SouthWest ) {
m_overlay->latLonBox().setSouth( rotatedCoord.latitude() );
m_overlay->latLonBox().setWest( rotatedCoord.longitude() );
} else if ( m_movedHandle == SouthEast ) {
m_overlay->latLonBox().setSouth( rotatedCoord.latitude() );
m_overlay->latLonBox().setEast( rotatedCoord.longitude() );
} else if ( m_movedHandle == NorthEast ) {
m_overlay->latLonBox().setNorth( rotatedCoord.latitude() );
m_overlay->latLonBox().setEast( rotatedCoord.longitude() );
} else if ( m_movedHandle == North ) {
m_overlay->latLonBox().setNorth( rotatedCoord.latitude() );
} else if ( m_movedHandle == South ) {
m_overlay->latLonBox().setSouth( rotatedCoord.latitude() );
} else if ( m_movedHandle == East ) {
m_overlay->latLonBox().setEast( rotatedCoord.longitude() );
} else if ( m_movedHandle == West ) {
m_overlay->latLonBox().setWest( rotatedCoord.longitude() );
}
} else if ( m_editStatus == Rotate ) {
if ( m_movedHandle != Polygon ) {
QPoint center = m_regionList.at( Polygon ).boundingRect().center();
qreal angle1 = qAtan2( event->pos().y() - center.y(),
event->pos().x() - center.x() );
qreal angle2 = qAtan2( m_movedHandleScreenCoordinates.y() - center.y(),
m_movedHandleScreenCoordinates.x() - center.x() );
m_overlay->latLonBox().setRotation( angle2 - angle1 + m_previousRotation );
}
}
if ( m_movedHandle == Polygon ) {
const qreal centerLonDiff = lon - m_movedHandleGeoCoordinates.longitude();
const qreal centerLatDiff = lat - m_movedHandleGeoCoordinates.latitude();
m_overlay->latLonBox().setBoundaries( m_overlay->latLonBox().north() + centerLatDiff,
m_overlay->latLonBox().south() + centerLatDiff,
m_overlay->latLonBox().east() + centerLonDiff,
m_overlay->latLonBox().west() + centerLonDiff );
m_movedHandleGeoCoordinates.set( lon, lat );
}
update();
return true;
}
return false;
}
bool GroundOverlayFrame::mouseReleaseEvent( QMouseEvent *event )
{
Q_UNUSED( event );
m_movedHandle = NoRegion;
m_textureLayer->reset();
if( m_editStatusChangeNeeded ) {
if( m_editStatus == Resize ) {
m_editStatus = Rotate;
} else {
m_editStatus = Resize;
}
}
return true;
}
void GroundOverlayFrame::update()
{
GeoDataLatLonBox overlayLatLonBox = m_overlay->latLonBox();
GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>( placemark()->geometry() );
poly->outerBoundary().clear();
GeoDataCoordinates rotatedCoord;
GeoDataCoordinates northWest(overlayLatLonBox.west(), overlayLatLonBox.north());
rotatedCoord = northWest.rotateAround(overlayLatLonBox.center(), overlayLatLonBox.rotation());
poly->outerBoundary().append( rotatedCoord );
GeoDataCoordinates southWest(overlayLatLonBox.west(), overlayLatLonBox.south());
rotatedCoord = southWest.rotateAround(overlayLatLonBox.center(), overlayLatLonBox.rotation());
poly->outerBoundary().append( rotatedCoord );
GeoDataCoordinates southEast(overlayLatLonBox.east(), overlayLatLonBox.south());
rotatedCoord = southEast.rotateAround(overlayLatLonBox.center(), overlayLatLonBox.rotation());
poly->outerBoundary().append( rotatedCoord );
GeoDataCoordinates northEast(overlayLatLonBox.east(), overlayLatLonBox.north());
rotatedCoord = northEast.rotateAround(overlayLatLonBox.center(), overlayLatLonBox.rotation());
poly->outerBoundary().append( rotatedCoord );
}
void GroundOverlayFrame::dealWithStateChange( SceneGraphicsItem::ActionState previousState )
{
Q_UNUSED( previousState );
}
const char *GroundOverlayFrame::graphicType() const
{
return SceneGraphicsTypes::SceneGraphicGroundOverlay;
}
}
diff --git a/src/plugins/render/annotate/NodeModel.h b/src/plugins/render/annotate/NodeModel.h
index f99bad946..ad4d53017 100644
--- a/src/plugins/render/annotate/NodeModel.h
+++ b/src/plugins/render/annotate/NodeModel.h
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Mikhail Ivchenko <ematirov@gmail.com>
//
#ifndef NODEMODEL_H
#define NODEMODEL_H
#include "GeoDataCoordinates.h"
#include <QAbstractListModel>
namespace Marble
{
class NodeModel : public QAbstractListModel
{
Q_OBJECT
public:
- explicit NodeModel( QObject *parent = 0 );
+ explicit NodeModel( QObject *parent = nullptr );
int rowCount( const QModelIndex &parent ) const override;
int columnCount( const QModelIndex &parent ) const override;
QVariant data( const QModelIndex &index, int role ) const override;
QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
void clear();
Qt::ItemFlags flags(const QModelIndex & index) const override ;
public Q_SLOTS:
int addNode( const GeoDataCoordinates &node );
private:
QVector<GeoDataCoordinates> m_nodes;
};
}
#endif
diff --git a/src/plugins/render/annotate/PolylineAnnotation.cpp b/src/plugins/render/annotate/PolylineAnnotation.cpp
index 6b5d47cb3..f9001b13e 100644
--- a/src/plugins/render/annotate/PolylineAnnotation.cpp
+++ b/src/plugins/render/annotate/PolylineAnnotation.cpp
@@ -1,841 +1,841 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
// Self
#include "PolylineAnnotation.h"
// Qt
#include <QApplication>
#include <QPalette>
#include <qmath.h>
// Marble
#include "SceneGraphicsTypes.h"
#include "GeoPainter.h"
#include "PolylineNode.h"
#include "GeoDataLineString.h"
#include "GeoDataPlacemark.h"
#include "ViewportParams.h"
#include "MergingPolylineNodesAnimation.h"
#include "osm/OsmPlacemarkData.h"
namespace Marble
{
const int PolylineAnnotation::regularDim = 15;
const int PolylineAnnotation::selectedDim = 15;
const int PolylineAnnotation::mergedDim = 20;
const int PolylineAnnotation::hoveredDim = 20;
const QColor PolylineAnnotation::regularColor = Oxygen::aluminumGray3;
const QColor PolylineAnnotation::mergedColor = Oxygen::emeraldGreen6;
PolylineAnnotation::PolylineAnnotation( GeoDataPlacemark *placemark ) :
SceneGraphicsItem( placemark ),
- m_viewport( 0 ),
+ m_viewport( nullptr ),
m_regionsInitialized( false ),
m_busy( false ),
m_interactingObj( InteractingNothing ),
m_clickedNodeIndex( -1 ),
m_hoveredNodeIndex( -1 ),
m_virtualHoveredNode( -1 )
{
setPaintLayers(QStringList() << "PolylineAnnotation");
}
PolylineAnnotation::~PolylineAnnotation()
{
delete m_animation;
}
void PolylineAnnotation::paint(GeoPainter *painter, const ViewportParams *viewport , const QString &layer, int tileZoomLevel)
{
Q_UNUSED(layer);
Q_UNUSED(tileZoomLevel);
m_viewport = viewport;
Q_ASSERT(geodata_cast<GeoDataLineString>(placemark()->geometry()));
painter->save();
if ( state() == SceneGraphicsItem::DrawingPolyline || !m_regionsInitialized ) {
setupRegionsLists( painter );
m_regionsInitialized = true;
} else {
updateRegions( painter );
}
if ( hasFocus() ) {
drawNodes( painter );
}
painter->restore();
}
void PolylineAnnotation::setupRegionsLists( GeoPainter *painter )
{
Q_ASSERT( state() == SceneGraphicsItem::DrawingPolyline || !m_regionsInitialized );
const GeoDataLineString line = static_cast<const GeoDataLineString>( *placemark()->geometry() );
// Add poyline nodes.
QVector<GeoDataCoordinates>::ConstIterator itBegin = line.constBegin();
QVector<GeoDataCoordinates>::ConstIterator itEnd = line.constEnd();
m_nodesList.clear();
m_nodesList.reserve(line.size());
for ( ; itBegin != itEnd; ++itBegin ) {
const PolylineNode newNode = PolylineNode( painter->regionFromEllipse( *itBegin, regularDim, regularDim ) );
m_nodesList.append( newNode );
}
// Add region from polyline so that events on polyline's 'lines' could be caught.
m_polylineRegion = painter->regionFromPolyline( line, 15 );
}
void PolylineAnnotation::updateRegions( GeoPainter *painter )
{
if ( m_busy ) {
return;
}
const GeoDataLineString line = static_cast<const GeoDataLineString>( *placemark()->geometry() );
if ( state() == SceneGraphicsItem::AddingNodes ) {
// Create and update virtual nodes lists when being in the AddingPolgonNodes state, to
// avoid overhead in other states.
m_virtualNodesList.clear();
for ( int i = 0; i < line.size() - 1; ++i ) {
const QRegion newRegion( painter->regionFromEllipse( line.at(i).interpolate( line.at(i+1), 0.5 ),
hoveredDim, hoveredDim ) );
m_virtualNodesList.append( PolylineNode( newRegion ) );
}
}
// Update the polyline region;
m_polylineRegion = painter->regionFromPolyline( line, 15 );
// Update the node lists.
for ( int i = 0; i < m_nodesList.size(); ++i ) {
const QRegion newRegion = m_nodesList.at(i).isSelected() ?
painter->regionFromEllipse( line.at(i), selectedDim, selectedDim ) :
painter->regionFromEllipse( line.at(i), regularDim, regularDim );
m_nodesList[i].setRegion( newRegion );
}
}
void PolylineAnnotation::drawNodes( GeoPainter *painter )
{
// These are the 'real' dimensions of the drawn nodes. The ones which have class scope are used
// to generate the regions and they are a little bit larger, because, for example, it would be
// a little bit too hard to select nodes.
static const int d_regularDim = 10;
static const int d_selectedDim = 10;
static const int d_mergedDim = 20;
static const int d_hoveredDim = 20;
const GeoDataLineString line = static_cast<const GeoDataLineString>( *placemark()->geometry() );
QColor glowColor = QApplication::palette().highlightedText().color();
glowColor.setAlpha(120);
auto const selectedColor = QApplication::palette().highlight().color();
auto const hoveredColor = selectedColor;
for ( int i = 0; i < line.size(); ++i ) {
// The order here is important, because a merged node can be at the same time selected.
if ( m_nodesList.at(i).isBeingMerged() ) {
painter->setBrush( mergedColor );
painter->drawEllipse( line.at(i), d_mergedDim, d_mergedDim );
} else if ( m_nodesList.at(i).isSelected() ) {
painter->setBrush( selectedColor );
painter->drawEllipse( line.at(i), d_selectedDim, d_selectedDim );
if ( m_nodesList.at(i).isEditingHighlighted() ||
m_nodesList.at(i).isMergingHighlighted() ) {
QPen defaultPen = painter->pen();
QPen newPen;
newPen.setWidth( defaultPen.width() + 3 );
newPen.setColor( glowColor );
painter->setBrush( Qt::NoBrush );
painter->setPen( newPen );
painter->drawEllipse( line.at(i), d_selectedDim + 2, d_selectedDim + 2 );
painter->setPen( defaultPen );
}
} else {
painter->setBrush( regularColor );
painter->drawEllipse( line.at(i), d_regularDim, d_regularDim );
if ( m_nodesList.at(i).isEditingHighlighted() ||
m_nodesList.at(i).isMergingHighlighted() ) {
QPen defaultPen = painter->pen();
QPen newPen;
newPen.setWidth( defaultPen.width() + 3 );
newPen.setColor( glowColor );
painter->setPen( newPen );
painter->setBrush( Qt::NoBrush );
painter->drawEllipse( line.at(i), d_regularDim + 2, d_regularDim + 2 );
painter->setPen( defaultPen );
}
}
}
if ( m_virtualHoveredNode != -1 ) {
painter->setBrush( hoveredColor );
GeoDataCoordinates newCoords;
if ( m_virtualHoveredNode + 1 ) {
newCoords = line.at( m_virtualHoveredNode + 1 ).interpolate( line.at( m_virtualHoveredNode ), 0.5 );
} else {
newCoords = line.first().interpolate( line.last(), 0.5 );
}
painter->drawEllipse( newCoords, d_hoveredDim, d_hoveredDim );
}
}
bool PolylineAnnotation::containsPoint( const QPoint &point ) const
{
if ( state() == SceneGraphicsItem::Editing ) {
return nodeContains( point ) != -1 || polylineContains( point );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return nodeContains( point ) != -1;
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return virtualNodeContains( point ) != -1 ||
nodeContains( point ) != -1 ||
polylineContains( point );
}
return false;
}
int PolylineAnnotation::nodeContains( const QPoint &point ) const
{
if ( !hasFocus() ) {
return -1;
}
for ( int i = 0; i < m_nodesList.size(); ++i ) {
if ( m_nodesList.at(i).containsPoint( point ) ) {
return i;
}
}
return -1;
}
int PolylineAnnotation::virtualNodeContains( const QPoint &point ) const
{
if ( !hasFocus() ) {
return -1;
}
for ( int i = 0; i < m_virtualNodesList.size(); ++i ) {
if ( m_virtualNodesList.at(i).containsPoint( point ) )
return i;
}
return -1;
}
bool PolylineAnnotation::polylineContains( const QPoint &point ) const
{
return m_polylineRegion.contains( point );
}
void PolylineAnnotation::dealWithItemChange( const SceneGraphicsItem *other )
{
Q_UNUSED( other );
// So far we only deal with item changes when hovering nodes, so that
// they do not remain hovered when changing the item we interact with.
if ( state() == SceneGraphicsItem::Editing ) {
if ( m_hoveredNodeIndex != -1 &&
m_hoveredNodeIndex < static_cast<GeoDataLineString*>( placemark()->geometry() )->size() ) {
m_nodesList[m_hoveredNodeIndex].setFlag( PolylineNode::NodeIsEditingHighlighted, false );
}
m_hoveredNodeIndex = -1;
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
if ( m_hoveredNodeIndex != -1 ) {
m_nodesList[m_hoveredNodeIndex].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
}
m_hoveredNodeIndex = -1;
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
m_virtualHoveredNode = -1;
}
}
void PolylineAnnotation::move( const GeoDataCoordinates &source, const GeoDataCoordinates &destination )
{
GeoDataLineString *lineString = static_cast<GeoDataLineString*>( placemark()->geometry() );
GeoDataLineString oldLineString = *lineString;
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
lineString->clear();
const qreal deltaLat = destination.latitude() - source.latitude();
const qreal deltaLon = destination.longitude() - source.longitude();
Quaternion latRectAxis = Quaternion::fromEuler( 0, destination.longitude(), 0);
Quaternion latAxis = Quaternion::fromEuler( -deltaLat, 0, 0);
Quaternion lonAxis = Quaternion::fromEuler(0, deltaLon, 0);
Quaternion rotAxis = latRectAxis * latAxis * latRectAxis.inverse() * lonAxis;
qreal lonRotated, latRotated;
for ( int i = 0; i < oldLineString.size(); ++i ) {
Quaternion qpos = oldLineString.at(i).quaternion();
qpos.rotateAroundAxis(rotAxis);
qpos.getSpherical( lonRotated, latRotated );
GeoDataCoordinates movedPoint( lonRotated, latRotated, 0 );
if ( osmData ) {
osmData->changeNodeReference( oldLineString.at( i ), movedPoint );
}
lineString->append( movedPoint );
}
}
void PolylineAnnotation::setBusy( bool enabled )
{
m_busy = enabled;
if ( !enabled && m_animation && state() == SceneGraphicsItem::MergingNodes ) {
if ( m_firstMergedNode != -1 && m_secondMergedNode != -1 ) {
// Update the PolylineNodes lists after the animation has finished its execution.
m_nodesList[m_secondMergedNode].setFlag( PolylineNode::NodeIsMergingHighlighted, false );
m_hoveredNodeIndex = -1;
// Remove the merging node flag and add the NodeIsSelected flag if either one of the
// merged nodes had been selected before merging them.
m_nodesList[m_secondMergedNode].setFlag( PolylineNode::NodeIsMerged, false );
if ( m_nodesList[m_firstMergedNode].isSelected() ) {
m_nodesList[m_secondMergedNode].setFlag( PolylineNode::NodeIsSelected );
}
m_nodesList.removeAt( m_firstMergedNode );
m_firstMergedNode = -1;
m_secondMergedNode = -1;
}
delete m_animation;
}
}
bool PolylineAnnotation::isBusy() const
{
return m_busy;
}
void PolylineAnnotation::deselectAllNodes()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
for ( int i = 0 ; i < m_nodesList.size(); ++i ) {
m_nodesList[i].setFlag( PolylineNode::NodeIsSelected, false );
}
}
void PolylineAnnotation::deleteAllSelectedNodes()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
for ( int i = 0; i < line->size(); ++i ) {
if ( m_nodesList.at(i).isSelected() ) {
if ( m_nodesList.size() <= 2 ) {
setRequest( SceneGraphicsItem::RemovePolylineRequest );
return;
}
if ( osmData ) {
osmData->removeNodeReference( line->at( i ) );
}
m_nodesList.removeAt( i );
line->remove( i );
--i;
}
}
}
void PolylineAnnotation::deleteClickedNode()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
if ( m_nodesList.size() <= 2 ) {
setRequest( SceneGraphicsItem::RemovePolylineRequest );
return;
}
if ( osmData ) {
osmData->removeMemberReference( m_clickedNodeIndex );
}
m_nodesList.removeAt( m_clickedNodeIndex );
line->remove( m_clickedNodeIndex );
}
void PolylineAnnotation::changeClickedNodeSelection()
{
if ( state() != SceneGraphicsItem::Editing ) {
return;
}
m_nodesList[m_clickedNodeIndex].setFlag( PolylineNode::NodeIsSelected,
!m_nodesList[m_clickedNodeIndex].isSelected() );
}
bool PolylineAnnotation::hasNodesSelected() const
{
for ( int i = 0; i < m_nodesList.size(); ++i ) {
if ( m_nodesList.at(i).isSelected() ) {
return true;
}
}
return false;
}
bool PolylineAnnotation::clickedNodeIsSelected() const
{
return m_nodesList[m_clickedNodeIndex].isSelected();
}
QPointer<MergingPolylineNodesAnimation> PolylineAnnotation::animation()
{
return m_animation;
}
bool PolylineAnnotation::mousePressEvent( QMouseEvent *event )
{
if ( !m_viewport || m_busy ) {
return false;
}
setRequest( SceneGraphicsItem::NoRequest );
if ( state() == SceneGraphicsItem::Editing ) {
return processEditingOnPress( event );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return processMergingOnPress( event );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return processAddingNodesOnPress( event );
}
return false;
}
bool PolylineAnnotation::mouseMoveEvent( QMouseEvent *event )
{
if ( !m_viewport || m_busy ) {
return false;
}
setRequest( SceneGraphicsItem::NoRequest );
if ( state() == SceneGraphicsItem::Editing ) {
return processEditingOnMove( event );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return processMergingOnMove( event );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return processAddingNodesOnMove( event );
}
return false;
}
bool PolylineAnnotation::mouseReleaseEvent( QMouseEvent *event )
{
if ( !m_viewport || m_busy ) {
return false;
}
setRequest( SceneGraphicsItem::NoRequest );
if ( state() == SceneGraphicsItem::Editing ) {
return processEditingOnRelease( event );
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
return processMergingOnRelease( event );
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
return processAddingNodesOnRelease( event );
}
return false;
}
void PolylineAnnotation::dealWithStateChange( SceneGraphicsItem::ActionState previousState )
{
// Dealing with cases when exiting a state has an effect on this item.
if ( previousState == SceneGraphicsItem::DrawingPolyline ) {
// nothing so far
} else if ( previousState == SceneGraphicsItem::Editing ) {
// Make sure that when changing the state, there is no highlighted node.
if ( m_hoveredNodeIndex != -1 ) {
m_nodesList[m_hoveredNodeIndex].setFlag( PolylineNode::NodeIsEditingHighlighted, false );
}
m_clickedNodeIndex = -1;
m_hoveredNodeIndex = -1;
} else if ( previousState == SceneGraphicsItem::MergingNodes ) {
// If there was only a node selected for being merged and the state changed,
// deselect it.
if ( m_firstMergedNode != -1 ) {
m_nodesList[m_firstMergedNode].setFlag( PolylineNode::NodeIsMerged, false );
}
// Make sure that when changing the state, there is no highlighted node.
if ( m_hoveredNodeIndex != -1 ) {
if ( m_hoveredNodeIndex != -1 ) {
m_nodesList[m_hoveredNodeIndex].setFlag( PolylineNode::NodeIsEditingHighlighted, false );
}
}
m_hoveredNodeIndex = -1;
delete m_animation;
} else if ( previousState == SceneGraphicsItem::AddingNodes ) {
m_virtualNodesList.clear();
m_virtualHoveredNode = -1;
m_adjustedNode = -1;
}
// Dealing with cases when entering a state has an effect on this item, or
// initializations are needed.
if ( state() == SceneGraphicsItem::Editing ) {
m_interactingObj = InteractingNothing;
m_clickedNodeIndex = -1;
m_hoveredNodeIndex = -1;
} else if ( state() == SceneGraphicsItem::MergingNodes ) {
m_firstMergedNode = -1;
m_secondMergedNode = -1;
m_hoveredNodeIndex = -1;
- m_animation = 0;
+ m_animation = nullptr;
} else if ( state() == SceneGraphicsItem::AddingNodes ) {
m_virtualHoveredNode = -1;
m_adjustedNode = -1;
}
}
bool PolylineAnnotation::processEditingOnPress( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() != Qt::LeftButton && mouseEvent->button() != Qt::RightButton ) {
return false;
}
qreal lat, lon;
m_viewport->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
m_movedPointCoords.set( lon, lat );
// First check if one of the nodes has been clicked.
m_clickedNodeIndex = nodeContains( mouseEvent->pos() );
if ( m_clickedNodeIndex != -1 ) {
if ( mouseEvent->button() == Qt::RightButton ) {
setRequest( SceneGraphicsItem::ShowNodeRmbMenu );
} else {
Q_ASSERT( mouseEvent->button() == Qt::LeftButton );
m_interactingObj = InteractingNode;
}
return true;
}
// Then check if the 'interior' of the polyline has been clicked (by interior
// I mean its lines excepting its nodes).
if ( polylineContains( mouseEvent->pos() ) ) {
if ( mouseEvent->button() == Qt::RightButton ) {
setRequest( SceneGraphicsItem::ShowPolylineRmbMenu );
} else {
Q_ASSERT( mouseEvent->button() == Qt::LeftButton );
m_interactingObj = InteractingPolyline;
}
return true;
}
return false;
}
bool PolylineAnnotation::processEditingOnMove( QMouseEvent *mouseEvent )
{
if ( !m_viewport ) {
return false;
}
qreal lon, lat;
m_viewport->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
const GeoDataCoordinates newCoords( lon, lat );
if ( m_interactingObj == InteractingNode ) {
GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
// Keeping the OsmPlacemarkData synchronized with the geometry
if ( osmData ) {
osmData->changeNodeReference( line->at( m_clickedNodeIndex ), newCoords );
}
line->at(m_clickedNodeIndex) = newCoords;
return true;
} else if ( m_interactingObj == InteractingPolyline ) {
GeoDataLineString *lineString = static_cast<GeoDataLineString*>( placemark()->geometry() );
- OsmPlacemarkData *osmData = 0;
+ OsmPlacemarkData *osmData = nullptr;
if ( placemark()->hasOsmData() ) {
osmData = &placemark()->osmData();
}
const GeoDataLineString oldLineString = *lineString;
lineString->clear();
const qreal deltaLat = lat - m_movedPointCoords.latitude();
const qreal deltaLon = lon - m_movedPointCoords.longitude();
Quaternion latRectAxis = Quaternion::fromEuler( 0, lon, 0);
Quaternion latAxis = Quaternion::fromEuler( -deltaLat, 0, 0);
Quaternion lonAxis = Quaternion::fromEuler(0, deltaLon, 0);
Quaternion rotAxis = latRectAxis * latAxis * latRectAxis.inverse() * lonAxis;
qreal lonRotated, latRotated;
for ( int i = 0; i < oldLineString.size(); ++i ) {
Quaternion qpos = oldLineString.at(i).quaternion();
qpos.rotateAroundAxis(rotAxis);
qpos.getSpherical( lonRotated, latRotated );
GeoDataCoordinates movedPoint( lonRotated, latRotated, 0 );
if ( osmData ) {
osmData->changeNodeReference( oldLineString.at( i ), movedPoint );
}
lineString->append( movedPoint );
}
m_movedPointCoords = newCoords;
return true;
}
return dealWithHovering( mouseEvent );
}
bool PolylineAnnotation::processEditingOnRelease( QMouseEvent *mouseEvent )
{
static const int mouseMoveOffset = 1;
if ( mouseEvent->button() != Qt::LeftButton ) {
return false;
}
if ( m_interactingObj == InteractingNode ) {
qreal x, y;
m_viewport->screenCoordinates( m_movedPointCoords.longitude(),
m_movedPointCoords.latitude(),
x, y );
// The node gets selected only if it is clicked and not moved.
if ( qFabs(mouseEvent->pos().x() - x) > mouseMoveOffset ||
qFabs(mouseEvent->pos().y() - y) > mouseMoveOffset ) {
m_interactingObj = InteractingNothing;
return true;
}
m_nodesList[m_clickedNodeIndex].setFlag( PolylineNode::NodeIsSelected,
!m_nodesList.at(m_clickedNodeIndex).isSelected() );
m_interactingObj = InteractingNothing;
return true;
} else if ( m_interactingObj == InteractingPolyline ) {
// Nothing special happens at polyline release.
m_interactingObj = InteractingNothing;
return true;
}
return false;
}
bool PolylineAnnotation::processMergingOnPress( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() != Qt::LeftButton ) {
return false;
}
GeoDataLineString line = static_cast<GeoDataLineString>( *placemark()->geometry() );
const int index = nodeContains( mouseEvent->pos() );
if ( index == -1 ) {
return false;
}
// If this is the first node selected to be merged.
if ( m_firstMergedNode == -1 ) {
m_firstMergedNode = index;
m_nodesList[index].setFlag( PolylineNode::NodeIsMerged );
} else {
Q_ASSERT( m_firstMergedNode != -1 );
// Clicking two times the same node results in unmarking it for merging.
if ( m_firstMergedNode == index ) {
m_nodesList[index].setFlag( PolylineNode::NodeIsMerged, false );
m_firstMergedNode = -1;
return true;
}
// If these two nodes are the last ones remained as part of the polyline, remove
// the whole polyline.
if ( line.size() <= 2 ) {
setRequest( SceneGraphicsItem::RemovePolylineRequest );
return true;
}
m_nodesList[index].setFlag( PolylineNode::NodeIsMerged );
m_secondMergedNode = index;
delete m_animation;
m_animation = new MergingPolylineNodesAnimation( this );
setRequest( SceneGraphicsItem::StartPolylineAnimation );
}
return true;
}
bool PolylineAnnotation::processMergingOnMove( QMouseEvent *mouseEvent )
{
return dealWithHovering( mouseEvent );
}
bool PolylineAnnotation::processMergingOnRelease( QMouseEvent *mouseEvent )
{
Q_UNUSED( mouseEvent );
return true;
}
bool PolylineAnnotation::processAddingNodesOnPress( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() != Qt::LeftButton ) {
return false;
}
GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );
// If a virtual node has just been clicked, add it to the polyline and start 'adjusting'
// its position.
const int virtualIndex = virtualNodeContains( mouseEvent->pos() );
if ( virtualIndex != -1 && m_adjustedNode == -1 ) {
Q_ASSERT( m_virtualHoveredNode == virtualIndex );
line->insert( virtualIndex + 1, line->at( virtualIndex ).interpolate( line->at( virtualIndex + 1 ), 0.5 ) );
m_nodesList.insert( virtualIndex + 1, PolylineNode() );
m_adjustedNode = virtualIndex + 1;
m_virtualHoveredNode = -1;
return true;
}
// If a virtual node which has been previously clicked and selected to become a
// 'real node' is clicked one more time, it stops from being 'adjusted'.
const int realIndex = nodeContains( mouseEvent->pos() );
if ( realIndex != -1 && m_adjustedNode != -1 ) {
m_adjustedNode = -1;
return true;
}
return false;
}
bool PolylineAnnotation::processAddingNodesOnMove( QMouseEvent *mouseEvent )
{
Q_ASSERT( mouseEvent->button() == Qt::NoButton );
const int index = virtualNodeContains( mouseEvent->pos() );
// If we are adjusting a virtual node which has just been clicked and became real, just
// change its coordinates when moving it, as we do with nodes in Editing state on move.
if ( m_adjustedNode != -1 ) {
// The virtual node which has just been added is always the last within
// GeoDataLinearRing's container.qreal lon, lat;
qreal lon, lat;
m_viewport->geoCoordinates( mouseEvent->pos().x(),
mouseEvent->pos().y(),
lon, lat,
GeoDataCoordinates::Radian );
const GeoDataCoordinates newCoords( lon, lat );
GeoDataLineString *line = static_cast<GeoDataLineString*>( placemark()->geometry() );
line->at(m_adjustedNode) = newCoords;
return true;
// If we are hovering a virtual node, store its index in order to be painted in drawNodes
// method.
} else if ( index != -1 ) {
m_virtualHoveredNode = index;
return true;
}
return false;
}
bool PolylineAnnotation::processAddingNodesOnRelease( QMouseEvent *mouseEvent )
{
Q_UNUSED( mouseEvent );
return m_adjustedNode == -1;
}
bool PolylineAnnotation::dealWithHovering( QMouseEvent *mouseEvent )
{
const PolylineNode::PolyNodeFlag flag = state() == SceneGraphicsItem::Editing ?
PolylineNode::NodeIsEditingHighlighted :
PolylineNode::NodeIsMergingHighlighted;
const int index = nodeContains( mouseEvent->pos() );
if ( index != -1 ) {
if ( !m_nodesList.at(index).isEditingHighlighted() &&
!m_nodesList.at(index).isMergingHighlighted() ) {
// Deal with the case when two nodes are very close to each other.
if ( m_hoveredNodeIndex != -1 ) {
m_nodesList[m_hoveredNodeIndex].setFlag( flag, false );
}
m_hoveredNodeIndex = index;
m_nodesList[index].setFlag( flag );
setRequest( ChangeCursorPolylineNodeHover );
}
return true;
} else if ( m_hoveredNodeIndex != -1 ) {
m_nodesList[m_hoveredNodeIndex].setFlag( flag, false );
m_hoveredNodeIndex = -1;
return true;
}
// This means that the interior of the polyline has been hovered so we catch this event too.
setRequest( ChangeCursorPolylineLineHover );
return true;
}
const char *PolylineAnnotation::graphicType() const
{
return SceneGraphicsTypes::SceneGraphicPolylineAnnotation;
}
}
diff --git a/src/plugins/render/annotate/PolylineNode.cpp b/src/plugins/render/annotate/PolylineNode.cpp
index 873f69be5..c01a00f3f 100644
--- a/src/plugins/render/annotate/PolylineNode.cpp
+++ b/src/plugins/render/annotate/PolylineNode.cpp
@@ -1,77 +1,77 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
//
#include "PolylineNode.h"
namespace Marble
{
PolylineNode::PolylineNode( const QRegion& region ) :
m_region( region ),
- m_flags( 0 )
+ m_flags( nullptr )
{
// nothing to do
}
PolylineNode::~PolylineNode()
{
// nothing to do
}
bool PolylineNode::isSelected() const
{
return m_flags & NodeIsSelected;
}
bool PolylineNode::isBeingMerged() const
{
return m_flags & NodeIsMerged;
}
bool PolylineNode::isEditingHighlighted() const
{
return m_flags & NodeIsEditingHighlighted;
}
bool PolylineNode::isMergingHighlighted() const
{
return m_flags & NodeIsMergingHighlighted;
}
void PolylineNode::setRegion( const QRegion& newRegion )
{
m_region = newRegion;
}
PolylineNode::PolyNodeFlags PolylineNode::flags() const
{
return m_flags;
}
void PolylineNode::setFlag( PolyNodeFlag flag, bool enabled )
{
if ( enabled ) {
m_flags |= flag;
} else {
m_flags &= ~flag;
}
}
void PolylineNode::setFlags( PolyNodeFlags flags )
{
m_flags = flags;
}
bool PolylineNode::containsPoint( const QPoint &eventPos ) const
{
return m_region.contains( eventPos );
}
}
diff --git a/src/plugins/render/aprs/AprsFile.cpp b/src/plugins/render/aprs/AprsFile.cpp
index 4963b2039..20826802e 100644
--- a/src/plugins/render/aprs/AprsFile.cpp
+++ b/src/plugins/render/aprs/AprsFile.cpp
@@ -1,72 +1,72 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Wes Hardaker <hardaker@users.sourceforge.net>
//
#include "AprsFile.h"
#include <QFile>
#include "MarbleDebug.h"
#include "AprsGatherer.h"
using namespace Marble;
AprsFile::AprsFile( const QString &fileName )
: m_fileName( fileName ),
m_errorCount( 0 )
{
}
AprsFile::~AprsFile()
{
}
QString
AprsFile::sourceName() const
{
return QString( "File" );
}
bool
AprsFile::canDoDirect() const
{
return true;
}
QIODevice *
AprsFile::openSocket()
{
QFile *file = new QFile( m_fileName );
mDebug() << "opening File socket";
if ( !file->open( QFile::ReadOnly ) ) {
mDebug() << "opening File failed";
delete file;
- return 0;
+ return nullptr;
}
mDebug() << "Opened " << m_fileName.toLocal8Bit().data();
return file;
}
void
AprsFile::checkReadReturn( int length, QIODevice **socket,
AprsGatherer *gatherer )
{
Q_UNUSED( socket );
if ( length < 0 || ( length == 0 && m_errorCount > 5 ) ) {
gatherer->sleepFor( 1 ); // just wait for more
return;
}
if ( length == 0 ) {
++m_errorCount;
mDebug() << "**** Odd: read zero bytes from File socket";
}
return;
}
diff --git a/src/plugins/render/aprs/AprsGatherer.cpp b/src/plugins/render/aprs/AprsGatherer.cpp
index 22fb2c9cf..771aed18f 100644
--- a/src/plugins/render/aprs/AprsGatherer.cpp
+++ b/src/plugins/render/aprs/AprsGatherer.cpp
@@ -1,289 +1,289 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Wes Hardaker <hardaker@users.sourceforge.net>
//
#include "AprsGatherer.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include <QMutex>
using namespace Marble;
AprsGatherer::AprsGatherer( AprsSource *from,
QMap<QString, AprsObject *> *objects,
QMutex *mutex,
QString *filter )
: m_source( from ),
- m_socket( 0 ),
+ m_socket( nullptr ),
m_filter( filter ),
m_running( true ),
m_dumpOutput( false ),
m_seenFrom( GeoAprsCoordinates::FromNowhere ),
m_sourceName( ),
m_mutex( mutex ),
m_objects( objects )
{
m_sourceName = from->sourceName();
initMicETables();
}
AprsGatherer::AprsGatherer( QIODevice *from,
QMap<QString, AprsObject *> *objects,
QMutex *mutex,
QString *filter )
- : m_source( 0 ),
+ : m_source( nullptr ),
m_socket( from ),
m_filter( filter ),
m_running( true ),
m_dumpOutput( false ),
m_seenFrom( GeoAprsCoordinates::FromNowhere ),
m_sourceName( "unknown" ),
m_mutex( mutex ),
m_objects( objects )
{
initMicETables();
}
void
AprsGatherer::run()
{
char buf[4096];
qint64 linelength;
// one particular APRS packet sender can add data after the : ( sigh )
QRegExp matcher( "^([0-9A-Z]+-*[0-9A-Z]*)>([^:]*):([!=@\\/])([0-9][0-9][0-9][0-9][0-9][0-9]|)([hz\\/]|)([0-9][0-9])([0-9][0-9]\\.[0-9][0-9])([NS])(.)([0-9][0-9][0-9])([0-9][0-9]\\.[0-9][0-9])([EW])(.)" );
// mic-e formatted
// 1: src
// 2: dst
// 3: routes
// 4: longitude x 3
// 5: speed and course x3
// 6: symbol and symbol ID
// 7: status text
QRegExp mic_e_matcher( "^([0-9A-Z]+-*[0-9A-Z]*)>([^,:]*),*([^:]*):['`](...)(...)(..)(.*)" );
// If a source can directly receive a signal (as opposed to
// through a relay like the internet) will return true. This
// prevents accidentially coloring signals heard over some sources
// as heard directly where it's never possible (such as over the
// internet).
Q_ASSERT(m_source);
if (!m_source) {
return;
}
bool canDoDirect = m_source->canDoDirect();
while( m_running ) {
if ( m_socket && !m_socket->isOpen() ) {
// connection closed; attempt to reopen
mDebug() << "aprs: socket closed; attempting to reopen";
delete m_socket;
- m_socket = 0;
+ m_socket = nullptr;
}
if ( !m_socket )
m_socket = m_source->openSocket();
if ( !m_socket ) {
mDebug() << "aprs: failed to open socket from "
<< m_sourceName.toLocal8Bit().data();
sleep( 5 );
continue;
}
// wait for data to read in
if ( m_socket->bytesAvailable() <= 0 )
// wait no longer than 1s
if ( ! m_socket->waitForReadyRead( 1000 ) )
continue; // continue to loop again on "not ready"
// Read the line to parse
linelength = m_socket->readLine( buf, sizeof( buf ) );
// if we got 0 or less bytes this is probably an odd case; ask
// the source what to do.
m_source->checkReadReturn( linelength, &m_socket, this );
if ( linelength <= 0 ) {
// don't go into an infinite untimed loop of failed sockets
sleep( 2 );
continue;
}
- if ( m_socket && m_filter != NULL ) {
+ if ( m_socket && m_filter != nullptr ) {
QMutexLocker locker( m_mutex );
if ( m_filter->length() > 0 ) {
m_socket->write( m_filter->toLocal8Bit().data(),
m_filter->length() );
}
}
// Parse the results
QString line( buf );
// Dump it out if we wanted it dumped
if ( m_dumpOutput )
mDebug() << "aprs: " << m_sourceName.toLocal8Bit().data()
<< ": " << line;
if ( matcher.indexIn( line ) != -1 ) {
QString callSign = matcher.cap( 1 );
qreal latitude = matcher.cap( 6 ).toFloat() +
( matcher.cap( 7 ).toFloat()/60 );
if (matcher.cap(8) == QLatin1String("S"))
latitude = - latitude;
qreal longitude = matcher.cap( 10 ).toFloat() +
( matcher.cap( 11 ).toFloat()/60 );
if (matcher.cap(12) == QLatin1String("W"))
longitude = - longitude;
addObject( callSign, latitude, longitude, canDoDirect,
QString( matcher.cap( 2 ) ),
QChar( matcher.cap( 9 )[0] ),
QChar( matcher.cap( 13 )[0] ) );
}
else if ( mic_e_matcher.indexIn( line ) != -1 ) {
// MIC-E formatted compressed packet
QString myCall = mic_e_matcher.cap( 1 );
QString dstCall = mic_e_matcher.cap( 2 );
qreal latitude =
// hours
m_dstCallDigits[dstCall[0]] * 10 +
m_dstCallDigits[dstCall[1]] +
// minutes
( qreal( m_dstCallDigits[dstCall[2]] * 10 +
m_dstCallDigits[dstCall[3]] ) +
qreal( m_dstCallDigits[dstCall[4]] ) / 10.0 +
qreal( m_dstCallDigits[dstCall[5]] ) / 100 ) / 60.0;
if ( m_dstCallSouthEast[dstCall[4]] )
latitude = - latitude;
qreal longitude =
calculateLongitude( QString ( mic_e_matcher.cap( 4 ) ),
m_dstCallLongitudeOffset[dstCall[4]],
m_dstCallSouthEast[dstCall[5]] );
// mDebug() << " MIC-E: " << line.toLocal8Bit().data();
// mDebug() << " lat: " << latitude;
// mDebug() << " lon: " << longitude;
addObject( myCall, latitude, longitude, canDoDirect,
QString( mic_e_matcher.cap( 3 ) ),
QChar( mic_e_matcher.cap( 6 )[1] ),
QChar( mic_e_matcher.cap( 6 )[0] ) );
}
else {
mDebug() << "aprs: UNPARSED: " << line;
}
// If the filter should be changed, send it out the socket
- if ( m_filter != NULL ) {
+ if ( m_filter != nullptr ) {
QMutexLocker locker( m_mutex );
if ( m_filter->length() > 0 ) {
m_socket->write( m_filter->toLocal8Bit().data(),
m_filter->length() );
}
}
}
}
void
AprsGatherer::shutDown()
{
m_running = false;
}
void
AprsGatherer::addObject( const QString &callSign,
qreal latitude, qreal longitude, bool canDoDirect,
const QString &routePath,
const QChar &symbolTable,
const QChar &symbolCode )
{
QMutexLocker locker( m_mutex );
GeoAprsCoordinates location( longitude, latitude, m_seenFrom );
if ( canDoDirect ) {
if (!routePath.contains(QLatin1Char('*'))) {
location.addSeenFrom( GeoAprsCoordinates::Directly );
}
}
if ( m_objects->contains( callSign ) ) {
// we already have one for this callSign; just add the new
// history item.
( *m_objects )[callSign]->setLocation( location );
}
else {
AprsObject *foundObject = new AprsObject( location, callSign );
foundObject->setPixmapId( m_pixmaps[QPair<QChar, QChar>( symbolTable,symbolCode )] );
( *m_objects )[callSign] = foundObject;
mDebug() << "aprs: new: " << callSign.toLocal8Bit().data();
}
}
qreal AprsGatherer::calculateLongitude( const QString &threeBytes, int offset,
bool isEast )
{
// otherwise known as "fun with funky encoding"
qreal hours = threeBytes[0].toLatin1() - 28 + offset;
if ( 180 <= hours && hours <= 189 )
hours -= 80;
if ( 190 <= hours && hours <= 199 )
hours -= 190;
hours +=
( qreal( (threeBytes[1].toLatin1() - 28 ) % 60 ) +
( qreal( threeBytes[2].toLatin1() - 28 ) ) / 100 ) / 60.0;
if ( ! isEast )
hours = -hours;
return hours;
}
void
AprsGatherer::setDumpOutput( bool to )
{
m_dumpOutput = to;
}
bool
AprsGatherer::dumpOutput() const
{
return m_dumpOutput;
}
void
AprsGatherer::setSeenFrom( GeoAprsCoordinates::SeenFrom to )
{
m_seenFrom = to;
}
GeoAprsCoordinates::SeenFrom
AprsGatherer::seenFrom()
{
return m_seenFrom;
}
// gets around parent QThread protected sleep as our objects need a sleep
void
AprsGatherer::sleepFor(int seconds)
{
sleep(seconds);
}
#include "moc_AprsGatherer.cpp"
diff --git a/src/plugins/render/aprs/AprsObject.cpp b/src/plugins/render/aprs/AprsObject.cpp
index 0925a8691..64bc0b077 100644
--- a/src/plugins/render/aprs/AprsObject.cpp
+++ b/src/plugins/render/aprs/AprsObject.cpp
@@ -1,160 +1,160 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Wes Hardaker <marble@ws6z.com>
//
#include "AprsObject.h"
#include <QPixmap>
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "GeoDataLineString.h"
#include "GeoPainter.h"
#include "GeoAprsCoordinates.h"
using namespace Marble;
AprsObject::AprsObject( const GeoAprsCoordinates &at, const QString &name )
: m_myName( name ),
m_seenFrom( at.seenFrom() ),
m_havePixmap ( false ),
m_pixmapFilename( ),
- m_pixmap( 0 )
+ m_pixmap( nullptr )
{
m_history.push_back( at );
}
AprsObject::~AprsObject()
{
delete m_pixmap;
}
GeoAprsCoordinates
AprsObject::location() const
{
return m_history.last();
}
void
AprsObject::setLocation( const GeoAprsCoordinates &location )
{
// Not ideal but it's unlikely they'll jump to the *exact* same spot again
if ( !m_history.contains( location ) ) {
m_history.push_back( location );
mDebug() << " moved: " << m_myName.toLocal8Bit().data();
} else {
int index = m_history.indexOf( location );
QTime now;
m_history[index].setTimestamp( now );
m_history[index].addSeenFrom( location.seenFrom() );
}
m_seenFrom = ( m_seenFrom | location.seenFrom() );
}
void
AprsObject::setPixmapId( QString &pixmap )
{
QString pixmapFilename = MarbleDirs::path( pixmap );
if ( QFile( pixmapFilename ).exists() ) {
m_havePixmap = true;
m_pixmapFilename = pixmapFilename;
// We can't load the pixmap here since it's used in a different thread
}
else {
m_havePixmap = false;
}
}
QColor
AprsObject::calculatePaintColor( int from, const QTime &time, int fadeTime )
{
QColor color;
if ( from & GeoAprsCoordinates::Directly ) {
color = Oxygen::emeraldGreen4; // oxygen green if direct
} else if ( (from & ( GeoAprsCoordinates::FromTCPIP | GeoAprsCoordinates::FromTTY ) ) == ( GeoAprsCoordinates::FromTCPIP | GeoAprsCoordinates::FromTTY ) ) {
color = Oxygen::burgundyPurple4; // oxygen purple if both
} else if ( from & GeoAprsCoordinates::FromTCPIP ) {
color = Oxygen::brickRed4; // oxygen red if net
} else if ( from & GeoAprsCoordinates::FromTTY ) {
color = Oxygen::seaBlue4; // oxygen blue if TNC TTY relay
} else if ( from & ( GeoAprsCoordinates::FromFile ) ) {
color = Oxygen::sunYellow3; // oxygen yellow if file only
} else {
mDebug() << "**************************************** unknown from: "
<< from;
color = Oxygen::aluminumGray5; // shouldn't happen but a user
// could mess up I suppose we
// should at least draw it in
// something.
}
if ( fadeTime > 0 && time.elapsed() > fadeTime ) { // 5 min ( 600000 ms )
color.setAlpha( 160 );
}
return color;
}
void
AprsObject::render( GeoPainter *painter, ViewportParams *viewport,
int fadeTime, int hideTime )
{
Q_UNUSED( viewport );
if ( hideTime > 0 && m_history.last().timestamp().elapsed() > hideTime )
return;
QColor baseColor = calculatePaintColor( m_seenFrom,
m_history.last().timestamp(),
fadeTime );
if ( m_history.count() > 1 ) {
QList<GeoAprsCoordinates>::iterator spot = m_history.begin();
QList<GeoAprsCoordinates>::iterator endSpot = m_history.end();
GeoDataLineString lineString;
lineString.setTessellate( true );
lineString << *spot; // *spot exists because m_history.count() > 1
for( ++spot; spot != endSpot; ++spot ) {
if ( hideTime > 0 && ( *spot ).timestamp().elapsed() > hideTime )
break;
lineString << *spot;
// draw the new circle in whatever is appropriate for that point
const QColor penColor = calculatePaintColor( spot->seenFrom(), spot->timestamp(), fadeTime );
painter->setPen( penColor );
painter->drawRect( *spot, 5, 5 );
}
// draw the line in the base color
painter->setPen( baseColor );
painter->drawPolyline( lineString );
}
// Always draw the symbol then the text last so it's on top
if ( m_havePixmap ) {
if ( ! m_pixmap )
m_pixmap = new QPixmap ( m_pixmapFilename );
if ( m_pixmap && ! m_pixmap->isNull() )
painter->drawPixmap( m_history.last(), *m_pixmap );
else
painter->drawRect( m_history.last(), 6, 6 );
}
else
painter->drawRect( m_history.last(), 6, 6 );
painter->setPen( baseColor );
painter->drawText( m_history.last(), m_myName );
}
diff --git a/src/plugins/render/aprs/AprsPlugin.cpp b/src/plugins/render/aprs/AprsPlugin.cpp
index 861c7e746..a13ab02a5 100644
--- a/src/plugins/render/aprs/AprsPlugin.cpp
+++ b/src/plugins/render/aprs/AprsPlugin.cpp
@@ -1,449 +1,449 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Wes Hardaker <hardaker@users.sourceforge.net>
//
#include "AprsPlugin.h"
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include <QColor>
#include <QAction>
#include <QMutexLocker>
#include <QTcpSocket>
#include "MarbleDirs.h"
#include "MarbleWidget.h"
#include "GeoPainter.h"
#include "GeoDataCoordinates.h"
#include "MarbleModel.h"
#include "GeoDataLatLonAltBox.h"
#include "ViewportParams.h"
#include "AprsGatherer.h"
#include "AprsTCPIP.h"
#include "AprsFile.h"
#include <aprsconfig.h>
#ifdef HAVE_QTSERIALPORT
#include "AprsTTY.h"
#endif
using namespace Marble;
/* TRANSLATOR Marble::AprsPlugin */
AprsPlugin::AprsPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
m_mutex( new QMutex ),
m_initialized( false ),
- m_tcpipGatherer( 0 ),
- m_ttyGatherer( 0 ),
- m_fileGatherer( 0 ),
- m_action( 0 ),
+ m_tcpipGatherer( nullptr ),
+ m_ttyGatherer( nullptr ),
+ m_fileGatherer( nullptr ),
+ m_action( nullptr ),
m_useInternet( true ),
m_useTty( false ),
m_useFile( false ),
m_aprsHost( "rotate.aprs.net" ),
m_aprsPort( 10253 ),
m_tncTty( "/dev/ttyUSB0" ),
m_aprsFile(),
m_dumpTcpIp( false ),
m_dumpTty( false ),
m_dumpFile( false ),
m_fadeTime( 10 ),
m_hideTime( 45 ),
- m_configDialog( 0 ),
- ui_configWidget( 0 )
+ m_configDialog( nullptr ),
+ ui_configWidget( nullptr )
{
setEnabled( true );
setVisible( false );
setSettings( QHash<QString,QVariant>() );
connect( this, SIGNAL(visibilityChanged(bool,QString)),
this, SLOT(updateVisibility(bool)) );
m_action = new QAction( this );
connect( m_action, SIGNAL(toggled(bool)),
this, SLOT(setVisible(bool)) );
}
AprsPlugin::~AprsPlugin()
{
stopGatherers();
delete m_configDialog;
delete ui_configWidget;
QMap<QString, AprsObject *>::Iterator obj;
QMap<QString, AprsObject *>::Iterator end = m_objects.end();
for( obj = m_objects.begin(); obj != end; ++obj ) {
delete *obj;
}
m_objects.clear();
delete m_mutex;
}
void AprsPlugin::updateVisibility( bool visible )
{
if ( visible )
restartGatherers();
else
stopGatherers();
}
RenderPlugin::RenderType AprsPlugin::renderType() const
{
return OnlineRenderType;
}
QStringList AprsPlugin::backendTypes() const
{
return QStringList(QStringLiteral("aprs"));
}
QString AprsPlugin::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList AprsPlugin::renderPosition() const
{
return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE"));
}
QString AprsPlugin::name() const
{
return tr( "Amateur Radio Aprs Plugin" );
}
QString AprsPlugin::guiString() const
{
return tr( "Amateur Radio &Aprs Plugin" );
}
QString AprsPlugin::nameId() const
{
return QStringLiteral("aprs-plugin");
}
QString AprsPlugin::version() const
{
return QStringLiteral("1.0");
}
QString AprsPlugin::description() const
{
return tr( "This plugin displays APRS data gleaned from the Internet. APRS is an Amateur Radio protocol for broadcasting location and other information." );
}
QString AprsPlugin::copyrightYears() const
{
return QStringLiteral("2009, 2010");
}
QVector<PluginAuthor> AprsPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Wes Hardaker"), QStringLiteral("hardaker@users.sourceforge.net"));
}
QIcon AprsPlugin::icon () const
{
return QIcon(QStringLiteral(":/icons/aprs.png"));
}
void AprsPlugin::stopGatherers()
{
// tell them all to stop
if ( m_tcpipGatherer )
m_tcpipGatherer->shutDown();
#ifdef HAVE_QTSERIALPORT
if ( m_ttyGatherer )
m_ttyGatherer->shutDown();
#endif
if ( m_fileGatherer )
m_fileGatherer->shutDown();
// now wait for them for at least 2 seconds (it shouldn't take that long)
if ( m_tcpipGatherer )
if ( m_tcpipGatherer->wait(2000) )
delete m_tcpipGatherer;
#ifdef HAVE_QTSERIALPORT
if ( m_ttyGatherer )
if ( m_ttyGatherer->wait(2000) )
delete m_ttyGatherer;
#endif
if ( m_fileGatherer )
if ( m_fileGatherer->wait(2000) )
delete m_fileGatherer;
- m_tcpipGatherer = 0;
- m_ttyGatherer = 0;
- m_fileGatherer = 0;
+ m_tcpipGatherer = nullptr;
+ m_ttyGatherer = nullptr;
+ m_fileGatherer = nullptr;
}
void AprsPlugin::restartGatherers()
{
stopGatherers();
if ( m_useInternet ) {
m_tcpipGatherer =
new AprsGatherer( new AprsTCPIP( m_aprsHost, m_aprsPort ),
&m_objects, m_mutex, &m_filter);
m_tcpipGatherer->setSeenFrom( GeoAprsCoordinates::FromTCPIP );
m_tcpipGatherer->setDumpOutput( m_dumpTcpIp );
m_tcpipGatherer->start();
mDebug() << "started TCPIP gatherer";
}
#ifdef HAVE_QTSERIALPORT
if ( m_useTty ) {
m_ttyGatherer =
new AprsGatherer( new AprsTTY( m_tncTty ),
- &m_objects, m_mutex, NULL);
+ &m_objects, m_mutex, nullptr);
m_ttyGatherer->setSeenFrom( GeoAprsCoordinates::FromTTY );
m_ttyGatherer->setDumpOutput( m_dumpTty );
m_ttyGatherer->start();
mDebug() << "started TTY gatherer";
}
#endif
if ( m_useFile ) {
m_fileGatherer =
new AprsGatherer( new AprsFile( m_aprsFile ),
- &m_objects, m_mutex, NULL);
+ &m_objects, m_mutex, nullptr);
m_fileGatherer->setSeenFrom( GeoAprsCoordinates::FromFile );
m_fileGatherer->setDumpOutput( m_dumpFile );
m_fileGatherer->start();
mDebug() << "started File gatherer";
}
}
void AprsPlugin::initialize ()
{
m_initialized = true;
mDebug() << "APRS initialized";
restartGatherers();
}
QDialog *AprsPlugin::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::AprsConfigWidget;
ui_configWidget->setupUi( m_configDialog );
readSettings();
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
// QPushButton *applyButton =
// ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
// connect( applyButton, SIGNAL(clicked()),
// this, SLOT(writeSettings()) );
}
return m_configDialog;
}
void AprsPlugin::readSettings()
{
if ( !m_configDialog ) {
return;
}
#ifndef HAVE_QTSERIALPORT
ui_configWidget->tabWidget->setTabEnabled( ui_configWidget->tabWidget->indexOf(
ui_configWidget->Device ), false );
#endif
// Connect to the net?
if ( m_useInternet )
ui_configWidget->m_internetBox->setCheckState( Qt::Checked );
else
ui_configWidget->m_internetBox->setCheckState( Qt::Unchecked );
// Connection Information
ui_configWidget->m_serverName->setText( m_aprsHost );
ui_configWidget->m_serverPort->setText( QString::number( m_aprsPort ) );
// Read from a TTY serial port?
if ( m_useTty )
ui_configWidget->m_serialBox->setCheckState( Qt::Checked );
else
ui_configWidget->m_serialBox->setCheckState( Qt::Unchecked );
// Serial port to use
ui_configWidget->m_ttyName->setText( m_tncTty );
// Read from a File?
if ( m_useFile )
ui_configWidget->m_useFile->setCheckState( Qt::Checked );
else
ui_configWidget->m_useFile->setCheckState( Qt::Unchecked );
// Serial port to use
ui_configWidget->m_fileName->setText( m_aprsFile );
// Dumping settings
if ( m_dumpTcpIp )
ui_configWidget->m_tcpipdump->setCheckState( Qt::Checked );
else
ui_configWidget->m_tcpipdump->setCheckState( Qt::Unchecked );
if ( m_dumpTty )
ui_configWidget->m_ttydump->setCheckState( Qt::Checked );
else
ui_configWidget->m_ttydump->setCheckState( Qt::Unchecked );
if ( m_dumpFile )
ui_configWidget->m_filedump->setCheckState( Qt::Checked );
else
ui_configWidget->m_filedump->setCheckState( Qt::Unchecked );
// display settings
ui_configWidget->m_fadetime->setText( QString::number( m_fadeTime ) );
ui_configWidget->m_hidetime->setText( QString::number( m_hideTime ) );
}
void AprsPlugin::writeSettings()
{
m_useInternet = ui_configWidget->m_internetBox->checkState() == Qt::Checked;
m_useTty = ui_configWidget->m_serialBox->checkState() == Qt::Checked;
m_useFile = ui_configWidget->m_useFile->checkState() == Qt::Checked;
m_aprsHost = ui_configWidget->m_serverName->text();
m_aprsPort = ui_configWidget->m_serverPort->text().toInt();
m_tncTty = ui_configWidget->m_ttyName->text();
m_dumpTcpIp = ui_configWidget->m_tcpipdump->checkState() == Qt::Checked;
m_dumpTty = ui_configWidget->m_ttydump->checkState() == Qt::Checked;
m_dumpFile = ui_configWidget->m_filedump->checkState() == Qt::Checked;
m_fadeTime = ui_configWidget->m_fadetime->text().toInt();
m_hideTime = ui_configWidget->m_hidetime->text().toInt();
restartGatherers();
emit settingsChanged( nameId() );
}
QHash<QString,QVariant> AprsPlugin::settings() const
{
QHash<QString, QVariant> result = RenderPlugin::settings();
result.insert(QStringLiteral("useInternet"), m_useInternet);
result.insert(QStringLiteral("useTTY"), m_useTty);
result.insert(QStringLiteral("useFile"), m_useFile);
result.insert(QStringLiteral("APRSHost"), m_aprsHost);
result.insert(QStringLiteral("APRSPort"), m_aprsPort);
result.insert(QStringLiteral("TNCTTY"), m_tncTty);
result.insert(QStringLiteral("FileName"), m_aprsFile);
result.insert(QStringLiteral("TCPIPDump"), m_dumpTcpIp);
result.insert(QStringLiteral("TTYDump"), m_dumpTty);
result.insert(QStringLiteral("FileDump"), m_dumpFile);
result.insert(QStringLiteral("fadeTime"), m_fadeTime);
result.insert(QStringLiteral("hideTime"), m_hideTime);
return result;
}
void AprsPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
RenderPlugin::setSettings( settings );
m_useInternet = settings.value(QStringLiteral("useInternet"), true).toBool();
m_useTty = settings.value(QStringLiteral("useTTY"), false).toBool();
m_useFile = settings.value(QStringLiteral("useFile"), false).toBool();
m_aprsHost = settings.value(QStringLiteral("APRSHost"), QStringLiteral("rotate.aprs.net")).toString();
m_aprsPort = settings.value(QStringLiteral("APRSPort"), 10253).toInt();
m_tncTty = settings.value(QStringLiteral("TNCTTY"), QStringLiteral("/dev/ttyUSB0")).toString();
m_aprsFile = settings.value(QStringLiteral("FileName"), QString()).toString();
m_dumpTcpIp = settings.value(QStringLiteral("TCPIPDump"), false).toBool();
m_dumpTty = settings.value(QStringLiteral("TTYDump"), false).toBool();
m_dumpFile = settings.value(QStringLiteral("FileDump"), false).toBool();
m_fadeTime = settings.value(QStringLiteral("fadeTime"), 10).toInt();
m_hideTime = settings.value(QStringLiteral("hideTime"), 45).toInt();
readSettings();
emit settingsChanged( nameId() );
}
bool AprsPlugin::isInitialized () const
{
return m_initialized;
}
bool AprsPlugin::render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer )
{
Q_UNUSED( renderPos )
Q_UNUSED( layer )
int fadetime = m_fadeTime * 60000;
int hidetime = m_hideTime * 60000;
painter->save();
if ( !( viewport->viewLatLonAltBox() == m_lastBox ) ) {
m_lastBox = viewport->viewLatLonAltBox();
QString towrite = QLatin1String("#filter a/") +
QString::number(m_lastBox.north(GeoDataCoordinates::Degree)) + QLatin1Char('/') +
QString::number(m_lastBox.west(GeoDataCoordinates::Degree)) + QLatin1Char('/') +
QString::number(m_lastBox.south(GeoDataCoordinates::Degree)) + QLatin1Char('/') +
QString::number(m_lastBox.east(GeoDataCoordinates::Degree)) + QLatin1Char('\n');
mDebug() << "upating filter: " << towrite.toLocal8Bit().data();
QMutexLocker locker( m_mutex );
m_filter = towrite;
}
QMutexLocker locker( m_mutex );
QMap<QString, AprsObject *>::ConstIterator obj;
for( obj = m_objects.constBegin(); obj != m_objects.constEnd(); ++obj ) {
( *obj )->render( painter, viewport, fadetime, hidetime );
}
painter->restore();
return true;
}
QAction* AprsPlugin::action() const
{
m_action->setCheckable( true );
m_action->setChecked( visible() );
m_action->setIcon( icon() );
m_action->setText( guiString() );
m_action->setToolTip( description() );
return m_action;
}
#include "moc_AprsPlugin.cpp"
diff --git a/src/plugins/render/aprs/AprsPlugin.h b/src/plugins/render/aprs/AprsPlugin.h
index 3feec2262..79ac0328f 100644
--- a/src/plugins/render/aprs/AprsPlugin.h
+++ b/src/plugins/render/aprs/AprsPlugin.h
@@ -1,118 +1,118 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Wes Hardaker <hardaker@users.sourceforge.net>
//
#ifndef APRSPLUGIN_H
#define APRSPLUGIN_H
#include <QDialog>
#include "RenderPlugin.h"
#include "DialogConfigurationInterface.h"
#include "AprsObject.h"
#include "AprsGatherer.h"
#include "GeoDataLatLonAltBox.h"
#include "ui_AprsConfigWidget.h"
class QMutex;
namespace Ui
{
class AprsConfigWidget;
}
namespace Marble
{
/**
* \brief This class displays a layer of aprs (which aprs TBD).
*
*/
class AprsPlugin : public RenderPlugin, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.AprsPlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN( AprsPlugin )
public:
- explicit AprsPlugin( const MarbleModel *marbleModel=0 );
+ explicit AprsPlugin( const MarbleModel *marbleModel=nullptr );
~AprsPlugin() override;
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
- bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
QDialog *configDialog() override;
QAction *action() const;
QHash<QString,QVariant> settings() const override;
void setSettings( const QHash<QString,QVariant> &settings ) override;
void stopGatherers();
void restartGatherers();
private Q_SLOTS:
void readSettings();
void writeSettings();
void updateVisibility( bool visible );
RenderType renderType() const override;
private:
QMutex *m_mutex;
QMap<QString, AprsObject *> m_objects;
bool m_initialized;
GeoDataLatLonAltBox m_lastBox;
AprsGatherer *m_tcpipGatherer,
*m_ttyGatherer,
*m_fileGatherer;
QString m_filter;
QAction *m_action;
bool m_useInternet;
bool m_useTty;
bool m_useFile;
QString m_aprsHost;
int m_aprsPort;
QString m_tncTty;
QString m_aprsFile;
bool m_dumpTcpIp;
bool m_dumpTty;
bool m_dumpFile;
int m_fadeTime;
int m_hideTime;
QDialog *m_configDialog;
Ui::AprsConfigWidget *ui_configWidget;
};
}
#endif
diff --git a/src/plugins/render/aprs/AprsTTY.cpp b/src/plugins/render/aprs/AprsTTY.cpp
index 6a5f8783d..9c6effdd5 100644
--- a/src/plugins/render/aprs/AprsTTY.cpp
+++ b/src/plugins/render/aprs/AprsTTY.cpp
@@ -1,83 +1,83 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Wes Hardaker <hardaker@users.sourceforge.net>
//
#include "AprsTTY.h"
#include <QSerialPort>
#include "MarbleDebug.h"
#include "AprsGatherer.h"
using namespace Marble;
AprsTTY::AprsTTY( const QString &ttyName )
: m_ttyName( ttyName ),
m_numErrors( 0 )
{
}
AprsTTY::~AprsTTY()
{
}
QString
AprsTTY::sourceName() const
{
return QString( "TTY" );
}
bool
AprsTTY::canDoDirect() const
{
return true;
}
QIODevice *
AprsTTY::openSocket()
{
QSerialPort *m_port = new QSerialPort( m_ttyName );
m_port->setBaudRate( QSerialPort::Baud9600, QSerialPort::Input );
m_port->setParity( QSerialPort::NoParity );
m_port->setDataBits( QSerialPort::Data8 );
m_port->setStopBits( QSerialPort::OneStop );
// m_port->setTimeout( 60000 ); // ms
m_port->open( QIODevice::ReadOnly );
mDebug() << "opened TTY socket";
if ( m_port->isOpen() ) {
mDebug() << "connected to " << m_ttyName.toLocal8Bit().data();
} else {
delete m_port;
- m_port = 0;
+ m_port = nullptr;
mDebug() << "**** failed to open terminal " << m_ttyName.toLocal8Bit().data() << " ****";
}
return m_port;
}
void
AprsTTY::checkReadReturn( int length, QIODevice **socket,
AprsGatherer *gatherer )
{
if ( length < 0 || ( length == 0 && m_numErrors > 5 ) ) {
// hard error. try reopening
mDebug() << "**** restarting TTY socket";
delete *socket;
gatherer->sleepFor( 1 );
*socket = openSocket();
return;
}
if ( length == 0 ) {
++m_numErrors;
mDebug() << "**** Odd: read zero bytes from TTY socket";
return;
}
return;
}
diff --git a/src/plugins/render/atmosphere/AtmospherePlugin.cpp b/src/plugins/render/atmosphere/AtmospherePlugin.cpp
index 7e2bf7350..297d7edd1 100644
--- a/src/plugins/render/atmosphere/AtmospherePlugin.cpp
+++ b/src/plugins/render/atmosphere/AtmospherePlugin.cpp
@@ -1,194 +1,194 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2008-2010 Jens-Michael Hoffmann <jmho@c-xx.com>
// Copyright 2008-2009 Patrick Spendrin <ps_ml@gmx.de>
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
// Copyright 2012 Kovalevskyy Illya <illya.kovalevskyy@gmail.com>
//
#include "AtmospherePlugin.h"
#include "Planet.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "MarbleModel.h"
#include <QIcon>
namespace Marble
{
AtmospherePlugin::AtmospherePlugin() :
- RenderPlugin( 0 ),
+ RenderPlugin( nullptr ),
m_renderRadius(-1)
{
}
AtmospherePlugin::AtmospherePlugin( const MarbleModel *marbleModel ) :
RenderPlugin( marbleModel ),
m_renderRadius(-1)
{
connect( marbleModel, SIGNAL(themeChanged(QString)),
this, SLOT(updateTheme()) );
}
QStringList AtmospherePlugin::backendTypes() const
{
return QStringList(QStringLiteral("atmosphere"));
}
QString AtmospherePlugin::renderPolicy() const
{
return QStringLiteral("SPECIFIED_ALWAYS");
}
QStringList AtmospherePlugin::renderPosition() const
{
return QStringList(QStringLiteral("SURFACE"));
}
RenderPlugin::RenderType AtmospherePlugin::renderType() const
{
return RenderPlugin::ThemeRenderType;
}
QString AtmospherePlugin::name() const
{
return tr( "Atmosphere" );
}
QString AtmospherePlugin::guiString() const
{
return tr( "&Atmosphere" );
}
QString AtmospherePlugin::nameId() const
{
return QStringLiteral("atmosphere");
}
QString AtmospherePlugin::version() const
{
return QStringLiteral("1.0");
}
QString AtmospherePlugin::description() const
{
return tr( "Shows the atmosphere around the earth." );
}
QIcon AtmospherePlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/atmosphere.png"));
}
QString AtmospherePlugin::copyrightYears() const
{
return QStringLiteral("2006-2012");
}
QVector<PluginAuthor> AtmospherePlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"))
<< PluginAuthor(QStringLiteral("Inge Wallin"), QStringLiteral("ingwa@kde.org"))
<< PluginAuthor(QStringLiteral("Jens-Michael Hoffmann"), QStringLiteral("jmho@c-xx.com"))
<< PluginAuthor(QStringLiteral("Patrick Spendrin"), QStringLiteral("ps_ml@gmx.de"))
<< PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"))
<< PluginAuthor(QStringLiteral("Mohammed Nafees"), QStringLiteral("nafees.technocool@gmail.com"));
}
qreal AtmospherePlugin::zValue() const
{
return -100.0;
}
void AtmospherePlugin::initialize()
{
/* nothing to do */
}
bool AtmospherePlugin::isInitialized() const
{
return true;
}
void AtmospherePlugin::updateTheme()
{
bool hasAtmosphere = marbleModel()->planet()->hasAtmosphere();
setEnabled( hasAtmosphere );
setVisible( hasAtmosphere );
}
bool AtmospherePlugin::render( GeoPainter *painter,
ViewportParams *viewParams,
const QString &renderPos,
GeoSceneLayer *layer )
{
Q_UNUSED(renderPos)
Q_UNUSED(layer)
if ( !visible() || !marbleModel()->planet()->hasAtmosphere() )
return true;
// Only draw an atmosphere if projection is spherical
if ( viewParams->projection() != Spherical && viewParams->projection() != VerticalPerspective )
return true;
// No use to draw atmosphere if it's not visible in the area.
if ( viewParams->mapCoversViewport() )
return true;
// Gradient should be recalculated only if planet color or size changed
if(viewParams->radius() != m_renderRadius || marbleModel()->planet()->atmosphereColor() != m_renderColor) {
m_renderRadius = viewParams->radius();
m_renderColor = marbleModel()->planet()->atmosphereColor();
repaintPixmap(viewParams);
}
int imageHalfWidth = viewParams->width() / 2;
int imageHalfHeight = viewParams->height() / 2;
painter->drawPixmap(imageHalfWidth - (int) ( (qreal) ( viewParams->radius() ) * 1.05 ),
imageHalfHeight - (int) ( (qreal) ( viewParams->radius() ) * 1.05 ),
m_renderPixmap);
return true;
}
void AtmospherePlugin::repaintPixmap(const ViewportParams *viewParams)
{
int imageHalfWidth = 1.05 * viewParams->radius();
int imageHalfHeight = 1.05 * viewParams->radius();
int diameter = (int) ( 2.1 * (qreal) ( viewParams->radius()));
m_renderPixmap = QPixmap(diameter, diameter);
m_renderPixmap.fill(QColor(Qt::transparent));
QPainter renderPainter(&m_renderPixmap);
QColor color = marbleModel()->planet()->atmosphereColor();
// Recalculate the atmosphere effect and paint it to canvasImage.
QRadialGradient grad( QPointF( imageHalfWidth, imageHalfHeight ),
1.05 * viewParams->radius() );
grad.setColorAt( 0.91, color );
grad.setColorAt( 1.00, QColor(color.red(), color.green(), color.blue(), 0) );
QBrush brush(grad);
renderPainter.setBrush(brush);
renderPainter.setPen(Qt::NoPen);
renderPainter.setRenderHint(QPainter::Antialiasing, false);
// Let's paint elipse we want in this::render(..) on pixmap from point (0;0)
renderPainter.drawEllipse(0, 0, diameter, diameter);
}
}
#include "moc_AtmospherePlugin.cpp"
diff --git a/src/plugins/render/atmosphere/AtmospherePlugin.h b/src/plugins/render/atmosphere/AtmospherePlugin.h
index 30bd445f5..f39947b08 100644
--- a/src/plugins/render/atmosphere/AtmospherePlugin.h
+++ b/src/plugins/render/atmosphere/AtmospherePlugin.h
@@ -1,78 +1,78 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011 Jens-Michael Hoffmann <jmho@c-xx.com>
//
#ifndef MARBLE_ATMOSPHEREPLUGIN_H
#define MARBLE_ATMOSPHEREPLUGIN_H
#include "RenderPlugin.h"
#include <QPixmap>
namespace Marble
{
class AtmospherePlugin : public RenderPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.AtmospherePlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
MARBLE_PLUGIN( AtmospherePlugin )
public:
AtmospherePlugin();
explicit AtmospherePlugin( const MarbleModel *marbleModel );
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
RenderType renderType() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QIcon icon() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
qreal zValue() const override;
void initialize() override;
bool isInitialized() const override;
- bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
void repaintPixmap(const ViewportParams *viewParams);
public Q_SLOTS:
void updateTheme();
private:
QPixmap m_renderPixmap;
QColor m_renderColor;
int m_renderRadius;
};
}
#endif // MARBLE_ATMOSPHEREPLUGIN_H
diff --git a/src/plugins/render/compass/CompassFloatItem.cpp b/src/plugins/render/compass/CompassFloatItem.cpp
index d8dc02136..09e4c7655 100644
--- a/src/plugins/render/compass/CompassFloatItem.cpp
+++ b/src/plugins/render/compass/CompassFloatItem.cpp
@@ -1,258 +1,258 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "CompassFloatItem.h"
#include "ui_CompassConfigWidget.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "ViewportParams.h"
#include <QRect>
#include <QColor>
#include <QPainter>
#include <QPushButton>
#include <QSvgRenderer>
namespace Marble
{
CompassFloatItem::CompassFloatItem()
- : AbstractFloatItem( 0 ),
- m_svgobj( 0 ),
+ : AbstractFloatItem( nullptr ),
+ m_svgobj( nullptr ),
m_polarity( 0 ),
m_themeIndex( 0 ),
- m_configDialog( 0 ),
- m_uiConfigWidget( 0 )
+ m_configDialog( nullptr ),
+ m_uiConfigWidget( nullptr )
{
}
CompassFloatItem::CompassFloatItem( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( -1.0, 10.0 ), QSizeF( 75.0, 75.0 ) ),
m_isInitialized( false ),
- m_svgobj( 0 ),
+ m_svgobj( nullptr ),
m_compass(),
m_polarity( 0 ),
m_themeIndex( 0 ),
- m_configDialog( 0 ),
- m_uiConfigWidget( 0 )
+ m_configDialog( nullptr ),
+ m_uiConfigWidget( nullptr )
{
}
CompassFloatItem::~CompassFloatItem ()
{
delete m_svgobj;
}
QStringList CompassFloatItem::backendTypes() const
{
return QStringList(QStringLiteral("compass"));
}
QString CompassFloatItem::name() const
{
return tr( "Compass" );
}
QString CompassFloatItem::guiString() const
{
return tr( "&Compass" );
}
QString CompassFloatItem::nameId() const
{
return QStringLiteral("compass");
}
QString CompassFloatItem::version() const
{
return QStringLiteral("1.0");
}
QString CompassFloatItem::description() const
{
return tr( "This is a float item that provides a compass." );
}
QString CompassFloatItem::copyrightYears() const
{
return QStringLiteral("2009, 2010");
}
QVector<PluginAuthor> CompassFloatItem::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"));
}
QIcon CompassFloatItem::icon() const
{
return QIcon(QStringLiteral(":/icons/compass.png"));
}
void CompassFloatItem::initialize()
{
readSettings();
m_isInitialized = true;
}
bool CompassFloatItem::isInitialized() const
{
return m_isInitialized;
}
QPainterPath CompassFloatItem::backgroundShape() const
{
QRectF contentRect = this->contentRect();
QPainterPath path;
int fontheight = QFontMetrics( font() ).ascent();
int compassLength = static_cast<int>( contentRect.height() ) - 5 - fontheight;
path.addEllipse( QRectF( QPointF( marginLeft() + padding() + ( contentRect.width() - compassLength ) / 2,
marginTop() + padding() + 5 + fontheight ),
QSize( compassLength, compassLength ) ).toRect() );
return path;
}
void CompassFloatItem::setProjection( const ViewportParams *viewport )
{
// figure out the polarity ...
if ( m_polarity != viewport->polarity() ) {
m_polarity = viewport->polarity();
update();
}
AbstractFloatItem::setProjection( viewport );
}
void CompassFloatItem::paintContent( QPainter *painter )
{
painter->save();
QRectF compassRect( contentRect() );
const QString dirstr =
(m_polarity == +1) ? tr("N") :
(m_polarity == -1) ? tr("S") :
/*else*/ QString();
int fontheight = QFontMetrics( font() ).ascent();
int fontwidth = QFontMetrics( font() ).boundingRect( dirstr ).width();
QPen outlinepen( background().color() );
outlinepen.setWidth( 2 );
QBrush outlinebrush( pen().color() );
QPainterPath outlinepath;
const QPointF baseline( 0.5 * (qreal)( compassRect.width() - fontwidth ),
(qreal)(fontheight) + 2.0 );
outlinepath.addText( baseline, font(), dirstr );
painter->setPen( outlinepen );
painter->setBrush( outlinebrush );
painter->drawPath( outlinepath );
painter->setPen( Qt::NoPen );
painter->drawPath( outlinepath );
int compassLength = static_cast<int>( compassRect.height() ) - 5 - fontheight;
QSize compassSize( compassLength, compassLength );
// Rerender compass pixmap if the size has changed
if ( m_compass.isNull() || m_compass.size() != compassSize ) {
m_compass = QPixmap( compassSize );
m_compass.fill( Qt::transparent );
QPainter mapPainter( &m_compass );
mapPainter.setViewport( m_compass.rect() );
m_svgobj->render( &mapPainter );
}
painter->drawPixmap( QPoint( static_cast<int>( compassRect.width() - compassLength ) / 2, fontheight + 5 ), m_compass );
painter->restore();
}
QDialog *CompassFloatItem::configDialog()
{
if ( !m_configDialog ) {
m_configDialog = new QDialog();
m_uiConfigWidget = new Ui::CompassConfigWidget;
m_uiConfigWidget->setupUi( m_configDialog );
readSettings();
connect( m_uiConfigWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( m_uiConfigWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
QPushButton *applyButton = m_uiConfigWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
this, SLOT(writeSettings()) );
}
return m_configDialog;
}
QHash<QString,QVariant> CompassFloatItem::settings() const
{
QHash<QString, QVariant> result = AbstractFloatItem::settings();
result.insert(QStringLiteral("theme"), m_themeIndex);
return result;
}
void CompassFloatItem::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractFloatItem::setSettings( settings );
m_themeIndex = settings.value(QStringLiteral("theme"), 0).toInt();
readSettings();
}
void CompassFloatItem::readSettings()
{
if ( m_uiConfigWidget && m_themeIndex >= 0 && m_themeIndex < m_uiConfigWidget->m_themeList->count() ) {
m_uiConfigWidget->m_themeList->setCurrentRow( m_themeIndex );
}
QString theme = QStringLiteral(":/compass.svg");
switch( m_themeIndex ) {
case 1:
theme = QStringLiteral(":/compass-arrows.svg");
break;
case 2:
theme = QStringLiteral(":/compass-atom.svg");
break;
case 3:
theme = QStringLiteral(":/compass-magnet.svg");
break;
}
delete m_svgobj;
m_svgobj = new QSvgRenderer( theme, this );
m_compass = QPixmap();
}
void CompassFloatItem::writeSettings()
{
if ( m_uiConfigWidget ) {
m_themeIndex = m_uiConfigWidget->m_themeList->currentRow();
}
readSettings();
update();
emit settingsChanged( nameId() );
}
}
#include "moc_CompassFloatItem.cpp"
diff --git a/src/plugins/render/crosshairs/CrosshairsPlugin.cpp b/src/plugins/render/crosshairs/CrosshairsPlugin.cpp
index 2fdac1794..5ee006f64 100644
--- a/src/plugins/render/crosshairs/CrosshairsPlugin.cpp
+++ b/src/plugins/render/crosshairs/CrosshairsPlugin.cpp
@@ -1,252 +1,252 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2010 Cezar Mocan <mocancezar@gmail.com>
//
#include "CrosshairsPlugin.h"
#include "ui_CrosshairsConfigWidget.h"
#include "GeoPainter.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "ViewportParams.h"
#include <QRect>
#include <QColor>
#include <QPushButton>
#include <QSvgRenderer>
#include <QImageReader>
namespace Marble
{
CrosshairsPlugin::CrosshairsPlugin()
- : RenderPlugin( 0 ),
- m_svgobj( 0 ),
+ : RenderPlugin( nullptr ),
+ m_svgobj( nullptr ),
m_themeIndex( 0 ),
- m_configDialog( 0 ),
- m_uiConfigWidget( 0 )
+ m_configDialog( nullptr ),
+ m_uiConfigWidget( nullptr )
{
}
CrosshairsPlugin::CrosshairsPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
m_isInitialized( false ),
- m_svgobj( 0 ),
+ m_svgobj( nullptr ),
m_themeIndex( 0 ),
- m_configDialog( 0 ),
- m_uiConfigWidget( 0 )
+ m_configDialog( nullptr ),
+ m_uiConfigWidget( nullptr )
{
}
CrosshairsPlugin::~CrosshairsPlugin ()
{
delete m_svgobj;
}
QStringList CrosshairsPlugin::backendTypes() const
{
return QStringList(QStringLiteral("crosshairs"));
}
QString CrosshairsPlugin::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList CrosshairsPlugin::renderPosition() const
{
return QStringList(QStringLiteral("FLOAT_ITEM")); // although this is not a float item we choose the position of one
}
RenderPlugin::RenderType CrosshairsPlugin::renderType() const
{
return RenderPlugin::TopLevelRenderType;
}
QString CrosshairsPlugin::name() const
{
return tr( "Crosshairs" );
}
QString CrosshairsPlugin::guiString() const
{
return tr( "Cross&hairs" );
}
QString CrosshairsPlugin::nameId() const
{
return QStringLiteral("crosshairs");
}
QString CrosshairsPlugin::version() const
{
return QStringLiteral("1.0");
}
QString CrosshairsPlugin::description() const
{
return tr( "A plugin that shows crosshairs." );
}
QString CrosshairsPlugin::copyrightYears() const
{
return QStringLiteral("2009, 2010");
}
QVector<PluginAuthor> CrosshairsPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Cezar Mocan"), QStringLiteral("cezarmocan@gmail.com"))
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"));
}
QIcon CrosshairsPlugin::icon () const
{
return QIcon(QStringLiteral(":/icons/crosshairs.png"));
}
void CrosshairsPlugin::initialize ()
{
readSettings();
m_isInitialized = true;
}
bool CrosshairsPlugin::isInitialized () const
{
return m_isInitialized;
}
QDialog *CrosshairsPlugin::configDialog()
{
if ( !m_configDialog ) {
m_configDialog = new QDialog();
m_uiConfigWidget = new Ui::CrosshairsConfigWidget;
m_uiConfigWidget->setupUi( m_configDialog );
readSettings();
connect( m_uiConfigWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( m_uiConfigWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
QPushButton *applyButton = m_uiConfigWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
this, SLOT(writeSettings()) );
}
return m_configDialog;
}
QHash<QString,QVariant> CrosshairsPlugin::settings() const
{
QHash<QString, QVariant> result = RenderPlugin::settings();
result.insert(QStringLiteral("theme"), m_themeIndex);
return result;
}
void CrosshairsPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
RenderPlugin::setSettings( settings );
m_themeIndex = settings.value(QStringLiteral("theme"), 0).toInt();
readSettings();
}
void CrosshairsPlugin::readSettings()
{
if ( m_uiConfigWidget && m_themeIndex >= 0 && m_themeIndex < m_uiConfigWidget->m_themeList->count() ) {
m_uiConfigWidget->m_themeList->setCurrentRow( m_themeIndex );
}
m_theme = QStringLiteral(":/crosshairs-darkened.png");
switch( m_themeIndex ) {
case 1:
m_theme = QStringLiteral(":/crosshairs-gun1.svg");
break;
case 2:
m_theme = QStringLiteral(":/crosshairs-gun2.svg");
break;
case 3:
m_theme = QStringLiteral(":/crosshairs-circled.svg");
break;
case 4:
m_theme = QStringLiteral(":/crosshairs-german.svg");
break;
}
if (QImageReader::imageFormat(m_theme) == QLatin1String("svg")) {
delete m_svgobj;
m_svgobj = new QSvgRenderer( m_theme, this );
}
m_crosshairs = QPixmap();
}
void CrosshairsPlugin::writeSettings()
{
if ( m_uiConfigWidget ) {
m_themeIndex = m_uiConfigWidget->m_themeList->currentRow();
}
readSettings();
emit settingsChanged( nameId() );
}
bool CrosshairsPlugin::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos,
GeoSceneLayer * layer )
{
Q_UNUSED( renderPos )
Q_UNUSED( layer )
if ( m_crosshairs.isNull() ) {
if (QImageReader::imageFormat(m_theme) == QLatin1String("svg")) {
painter->setRenderHint( QPainter::Antialiasing, true );
m_crosshairs = QPixmap( QSize( 21, 21 ) );
m_crosshairs.fill( Qt::transparent );
QPainter mapPainter( &m_crosshairs );
m_svgobj->render( &mapPainter );
}
else {
m_crosshairs.load( m_theme );
}
}
const int width = m_crosshairs.width();
const int height = m_crosshairs.height();
int posX;
int posY;
GeoDataCoordinates const focusPoint = viewport->focusPoint();
GeoDataCoordinates const centerPoint = GeoDataCoordinates( viewport->centerLongitude(), viewport->centerLatitude() );
if ( focusPoint == centerPoint ) {
// Focus point is in the middle of the screen. Special casing this avoids jittering.
const QSize viewPortSize = viewport->size();
posX = (viewPortSize.width() - width) / 2;
posY = (viewPortSize.height() - height) / 2;
} else {
qreal centerX = 0.0;
qreal centerY = 0.0;
viewport->screenCoordinates( focusPoint, centerX, centerY );
posX = qRound(centerX - width / 2.0);
posY = qRound(centerY - height / 2.0);
}
painter->drawPixmap(posX, posY, m_crosshairs );
return true;
}
}
#include "moc_CrosshairsPlugin.cpp"
diff --git a/src/plugins/render/crosshairs/CrosshairsPlugin.h b/src/plugins/render/crosshairs/CrosshairsPlugin.h
index f6bde45af..38f6aa0eb 100644
--- a/src/plugins/render/crosshairs/CrosshairsPlugin.h
+++ b/src/plugins/render/crosshairs/CrosshairsPlugin.h
@@ -1,113 +1,113 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2010 Cezar Mocan <mocancezar@gmail.com>
//
//
// This class is a crosshairs plugin.
//
#ifndef MARBLE_CROSSHAIRSPLUGIN_H
#define MARBLE_CROSSHAIRSPLUGIN_H
#include <QPixmap>
#include "RenderPlugin.h"
#include "DialogConfigurationInterface.h"
class QSvgRenderer;
namespace Ui {
class CrosshairsConfigWidget;
}
namespace Marble
{
/**
* @short The class that specifies the Marble layer interface of a plugin.
*
*/
class CrosshairsPlugin : public RenderPlugin, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.CrosshairsPlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN(CrosshairsPlugin)
public:
CrosshairsPlugin();
explicit CrosshairsPlugin( const MarbleModel *marbleModel );
~CrosshairsPlugin() override;
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
RenderType renderType() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
- bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
QDialog *configDialog() override;
QHash<QString,QVariant> settings() const override;
void setSettings( const QHash<QString,QVariant> &settings ) override;
private Q_SLOTS:
void readSettings();
void writeSettings();
private:
Q_DISABLE_COPY( CrosshairsPlugin )
bool m_isInitialized;
QSvgRenderer *m_svgobj;
QPixmap m_crosshairs;
int m_themeIndex;
QString m_theme;
QDialog * m_configDialog;
Ui::CrosshairsConfigWidget * m_uiConfigWidget;
};
}
#endif // MARBLE_CROSSHAIRSPLUGIN_H
diff --git a/src/plugins/render/earthquake/EarthquakeModel.h b/src/plugins/render/earthquake/EarthquakeModel.h
index 035ea9f0c..cd1733159 100644
--- a/src/plugins/render/earthquake/EarthquakeModel.h
+++ b/src/plugins/render/earthquake/EarthquakeModel.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Utku Aydin <utkuaydin34@gmail.com>
//
#ifndef EARTHQUAKEMODEL_H
#define EARTHQUAKEMODEL_H
#include "AbstractDataPluginModel.h"
#include <QDateTime>
namespace Marble
{
class EarthquakeModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- explicit EarthquakeModel( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit EarthquakeModel( const MarbleModel *marbleModel, QObject *parent = nullptr );
~EarthquakeModel() override;
void setMinMagnitude( double minMagnitude );
void setStartDate( const QDateTime& startDate );
void setEndDate( const QDateTime& endDate );
protected:
/**
* Generates the download url for the description file from the web service depending on
* the @p box surrounding the view and the @p number of files to show.
**/
void getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number = 10 ) override;
/**
* Parses the @p file which getAdditionalItems downloads and
* prepares the data for usage.
**/
void parseFile( const QByteArray& file ) override;
private:
double m_minMagnitude;
QDateTime m_startDate;
QDateTime m_endDate;
};
}
#endif // EARTHQUAKEMODEL_H
diff --git a/src/plugins/render/earthquake/EarthquakePlugin.cpp b/src/plugins/render/earthquake/EarthquakePlugin.cpp
index f02e8fd69..79c08b30b 100644
--- a/src/plugins/render/earthquake/EarthquakePlugin.cpp
+++ b/src/plugins/render/earthquake/EarthquakePlugin.cpp
@@ -1,221 +1,221 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Utku Aydın <utkuaydin34@gmail.com>
//
#include "EarthquakePlugin.h"
#include "EarthquakeModel.h"
#include "ui_EarthquakeConfigWidget.h"
#include <QPushButton>
#include <QSlider>
#include "MarbleModel.h"
namespace Marble {
EarthquakePlugin::EarthquakePlugin()
- : AbstractDataPlugin( 0 ),
- m_ui( 0 ),
- m_configDialog( 0 ),
+ : AbstractDataPlugin( nullptr ),
+ m_ui( nullptr ),
+ m_configDialog( nullptr ),
m_maximumNumberOfItems( 100 )
{
}
EarthquakePlugin::EarthquakePlugin( const MarbleModel *marbleModel )
: AbstractDataPlugin( marbleModel ),
- m_ui( 0 ),
- m_configDialog( 0 ),
+ m_ui( nullptr ),
+ m_configDialog( nullptr ),
m_minMagnitude( 0.0 ),
m_startDate( QDateTime::fromString( "2006-02-04", "yyyy-MM-dd" ) ),
m_endDate( marbleModel->clockDateTime() ),
m_pastDays( 30 ),
m_timeRangeNPastDays( true ),
m_numResults( 20 ),
m_maximumNumberOfItems( 100 )
{
setEnabled( true ); // Plugin is enabled by default
setVisible( false ); // Plugin is invisible by default
connect( this, SIGNAL(settingsChanged(QString)),
this, SLOT(updateModel()) );
}
void EarthquakePlugin::initialize()
{
EarthquakeModel *model = new EarthquakeModel( marbleModel(), this );
setModel( model );
setNumberOfItems( m_numResults );
updateModel();
}
QString EarthquakePlugin::name() const
{
return tr( "Earthquakes" );
}
QString EarthquakePlugin::guiString() const
{
return tr( "&Earthquakes" );
}
QString EarthquakePlugin::nameId() const
{
return QStringLiteral("earthquake");
}
QString EarthquakePlugin::version() const
{
return QStringLiteral("1.0");
}
QString EarthquakePlugin::description() const
{
return tr( "Shows earthquakes on the map." );
}
QString EarthquakePlugin::copyrightYears() const
{
return QStringLiteral("2010, 2011");
}
QVector<PluginAuthor> EarthquakePlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Utku Aydın"), QStringLiteral("utkuaydin34@gmail.com"))
<< PluginAuthor(QStringLiteral("Daniel Marth"), QStringLiteral("danielmarth@gmx.at"));
}
QIcon EarthquakePlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/earthquake.png"));
}
QDialog *EarthquakePlugin::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
m_ui = new Ui::EarthquakeConfigWidget;
m_ui->setupUi( m_configDialog );
m_ui->m_numResults->setRange( 1, m_maximumNumberOfItems );
readSettings();
connect( m_ui->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( m_ui->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
connect( m_ui->m_buttonBox->button( QDialogButtonBox::Reset ), SIGNAL(clicked()),
SLOT(restoreDefaultSettings()) );
QPushButton *applyButton = m_ui->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
SLOT(writeSettings()) );
connect( m_ui->m_startDate, SIGNAL(dateTimeChanged(QDateTime)),
SLOT(validateDateRange()) );
connect( m_ui->m_endDate, SIGNAL(dateTimeChanged(QDateTime)),
SLOT(validateDateRange()) );
connect( this, SIGNAL(settingsChanged(QString)),
this, SLOT(readSettings()) );
}
return m_configDialog;
}
QHash<QString,QVariant> EarthquakePlugin::settings() const
{
QHash<QString, QVariant> settings = AbstractDataPlugin::settings();
settings.insert(QStringLiteral("numResults"), m_numResults);
settings.insert(QStringLiteral("minMagnitude"), m_minMagnitude);
settings.insert(QStringLiteral("startDate"), m_startDate);
settings.insert(QStringLiteral("endDate"), m_endDate);
settings.insert(QStringLiteral("pastDays"), m_pastDays);
settings.insert(QStringLiteral("timeRangeNPastDays"), m_timeRangeNPastDays);
settings.insert(QStringLiteral("maximumNumberOfItems"), m_maximumNumberOfItems);
return settings;
}
void EarthquakePlugin::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractDataPlugin::setSettings( settings );
m_numResults = settings.value(QStringLiteral("numResults"), 20).toInt();
m_minMagnitude = settings.value(QStringLiteral("minMagnitude"), 0.0).toReal();
m_startDate = settings.value(QStringLiteral("startDate"), QDateTime::fromString(QStringLiteral("2006-02-04"), QStringLiteral("yyyy-MM-dd"))).toDateTime();
m_endDate = settings.value(QStringLiteral("endDate"), marbleModel()->clockDateTime()).toDateTime();
m_pastDays = settings.value(QStringLiteral("pastDays"), 30).toInt();
m_timeRangeNPastDays = settings.value(QStringLiteral("timeRangeNPastDays"), true).toBool();
m_maximumNumberOfItems = settings.value(QStringLiteral("maximumNumberOfItems"), m_maximumNumberOfItems).toInt();
emit settingsChanged( nameId() );
}
void EarthquakePlugin::readSettings()
{
Q_ASSERT( m_configDialog );
m_ui->m_numResults->setValue( m_numResults );
m_ui->m_minMagnitude->setValue( m_minMagnitude );
m_ui->m_startDate->setDateTime( m_startDate );
m_ui->m_endDate->setDateTime( m_endDate );
m_ui->m_startDate->setMaximumDateTime( m_ui->m_endDate->dateTime() );
m_ui->m_pastDays->setValue(m_pastDays);
if ( m_timeRangeNPastDays ) {
m_ui->m_timeRangeNPastDaysRadioButton->setChecked(true);
} else {
m_ui->m_timeRangeFromToRadioButton->setChecked(true);
}
}
void EarthquakePlugin::writeSettings()
{
Q_ASSERT( m_configDialog );
m_numResults = m_ui->m_numResults->value();
setNumberOfItems( m_numResults );
m_minMagnitude = m_ui->m_minMagnitude->value();
m_startDate = m_ui->m_startDate->dateTime();
m_endDate = m_ui->m_endDate->dateTime();
m_pastDays = m_ui->m_pastDays->value();
m_timeRangeNPastDays = m_ui->m_timeRangeNPastDaysRadioButton->isChecked();
emit settingsChanged( nameId() );
}
void EarthquakePlugin::updateModel()
{
if( model() ) {
EarthquakeModel *const earthquakeModel = static_cast<EarthquakeModel *>( model() );
earthquakeModel->setMinMagnitude( m_minMagnitude );
if ( m_timeRangeNPastDays ) {
QDateTime startdate, enddate;
enddate = marbleModel()->clockDateTime();
startdate = enddate.addDays(-m_pastDays + 1);
earthquakeModel->setStartDate( startdate );
earthquakeModel->setEndDate( enddate );
} else {
earthquakeModel->setStartDate( m_startDate );
earthquakeModel->setEndDate( m_endDate );
}
earthquakeModel->clear();
}
}
void EarthquakePlugin::validateDateRange()
{
Q_ASSERT( m_configDialog );
if( m_ui->m_startDate->dateTime() >= m_ui->m_endDate->dateTime() ) {
m_ui->m_startDate->setDateTime( m_ui->m_endDate->dateTime().addDays(-1) );
}
m_ui->m_startDate->setMaximumDateTime( m_ui->m_endDate->dateTime().addDays(-1) );
}
}
#include "moc_EarthquakePlugin.cpp"
diff --git a/src/plugins/render/eclipses/EclipsesBrowserDialog.h b/src/plugins/render/eclipses/EclipsesBrowserDialog.h
index ed0c67eb6..cd0a2b071 100644
--- a/src/plugins/render/eclipses/EclipsesBrowserDialog.h
+++ b/src/plugins/render/eclipses/EclipsesBrowserDialog.h
@@ -1,124 +1,124 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#ifndef MARBLE_ECLIPSESBROWSERDIALOG_H
#define MARBLE_ECLIPSESBROWSERDIALOG_H
#include <QDialog>
namespace Ui {
class EclipsesBrowserDialog;
}
namespace Marble {
class EclipsesModel;
class MarbleModel;
/**
* @brief The eclipse browser dialog
*
* This implements the logic for the eclipse browser dialog.
*/
class EclipsesBrowserDialog : public QDialog
{
Q_OBJECT
public:
explicit EclipsesBrowserDialog( const MarbleModel *model,
- QWidget *parent = 0 );
+ QWidget *parent = nullptr );
~EclipsesBrowserDialog() override;
/**
* @brief Set the year
*
* This sets the year the browser currently shows eclipses for.
*
* @see year
*/
void setYear( int year );
/**
* @brief Return the year the browser is set to
*
* @return The year the browser shows eclipses for at the moment
* @see setYear
*/
int year() const;
/**
* @brief Set whether or not to list lunar eclipses
* @param enable whether or not to list lunar eclipses
*
* @see withLunarEclipses
*/
void setWithLunarEclipses( const bool enable );
/**
* @brief Returns whether or not lunar eclipses are listed
*
* @return Whether or not lunar eclipses are listed
* @see setWithLunarEclipses
*/
bool withLunarEclipses() const;
Q_SIGNALS:
/**
* @brief This signal is emitted when the use clicks the "show" button
* @param year the year of the selected eclipse event
* @param index the index of the selected eclipse item
*/
void buttonShowClicked( int year, int index );
/**
* @brief This signal is emitted when the 'Settings' button is clicked
*/
void buttonSettingsClicked();
protected Q_SLOTS:
/**
* @brief Accept the dialog
*
* This emits the buttonShowClicked signal
*
* @see buttonShowClicked
*/
void accept() override;
/**
* @brief Update the list of eclipses for the given year
* @param year The year to list eclipses for
*/
void updateEclipsesForYear( int year );
/**
* @brief Update the dialog's button states
*
* Disable/enable the show button according to the current selection.
*/
void updateButtonStates();
protected:
/**
* @brief Initialize the object
*/
void initialize();
private:
const MarbleModel *m_marbleModel;
Ui::EclipsesBrowserDialog *m_browserWidget;
EclipsesModel *m_eclModel;
};
} // namespace Marble
#endif // MARBLE_ECLIPSESBROWSERDIALOG_H
diff --git a/src/plugins/render/eclipses/EclipsesItem.h b/src/plugins/render/eclipses/EclipsesItem.h
index 73f571f25..a8639c463 100644
--- a/src/plugins/render/eclipses/EclipsesItem.h
+++ b/src/plugins/render/eclipses/EclipsesItem.h
@@ -1,267 +1,267 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#ifndef MARBLE_ECLIPSESITEM_H
#define MARBLE_ECLIPSESITEM_H
#include <QObject>
#include <QDateTime>
#include "GeoDataLineString.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLinearRing.h"
#include <eclsolar.h>
namespace Marble
{
/**
* @brief The representation of an eclipse event
*
* This class represents an eclipse event on earth. It calculates all
* basic information like date and visibility upon initialization.
* Expensive calculations like boundary polygons are done the first time
* they are requested.
*
* The calculations are done using the eclsolar backend that has to be
* passed to the constructor.
*/
class EclipsesItem : public QObject
{
Q_OBJECT
public:
/**
* @brief A type of an eclipse event
*/
enum EclipsePhase {
TotalMoon = -4,
PartialMoon = -3,
PenumbralMoon = -1,
PartialSun = 1,
NonCentralAnnularSun = 2,
NonCentralTotalSun = 3,
AnnularSun = 4,
TotalSun = 5,
AnnularTotalSun = 6
};
/**
* @brief Construct the EclipseItem object and trigger basic calculations
* @param ecl The EclSolar backend
* @param parent The parent object
*/
- explicit EclipsesItem( EclSolar *ecl, int index, QObject *parent = 0 );
+ explicit EclipsesItem( EclSolar *ecl, int index, QObject *parent = nullptr );
~EclipsesItem() override;
/**
* @brief The index of the eclipse event
*
* Returns the index of the eclipse event.
*
* @return The eclipse events index.
*/
int index() const;
/**
* @brief Check if the event takes place at a given datetime
* @param dateTime The date time to check
*
* Checks whether or not this eclipse event takes place at the given
* @p dateTime. This is true if @p dateTime is between the global
* start and end dates of the event.
*
* @return True if the event takes place at @p dateTime or false otherwise.
*/
bool takesPlaceAt( const QDateTime &dateTime ) const;
/**
* @brief Returns the phase of this eclipse event
* @return the phase or type of this eclipse event
* @see phaseText
*/
EclipsesItem::EclipsePhase phase() const;
/**
* @brief Returns an icon of the eclipse type
* @return an icon representing the eclipse's type
*/
QIcon icon() const;
/**
* @brief Returns a human readable representation of the eclipse type
* @return A string representing the eclipse's type
* @see phase
*/
QString phaseText() const;
/**
* @brief Returns the date of the eclipse event's maximum
* @return The DateTime of the eclipse's maximum
* @see maxLocation
*/
const QDateTime& dateMaximum() const;
/**
* @brief Returns the start date of the eclipse's partial phase
* @return The start date of the partial phase
* @see endDatePartial
*/
const QDateTime& startDatePartial() const;
/**
* @brief Returns the end date of the eclipse's partial phase
* @return The end date of the partial phase
* @see startDatePartial
*/
const QDateTime& endDatePartial() const;
/**
* @brief Returns the number of hours the partial phase takes place
* @return The number of hours of the partial phase
* @see startDatePartial, endDatePartial
*/
int partialDurationHours() const;
/**
* @brief Returns the start date of the eclipse's total phase
*
* If the eclipse has a total phase, the date and time of its beginning
* is returned. If this is no total eclipse, an invalid datetime object
* will be returned.
*
* @return The start date of the total phase or an invalid date
* @see endDateTotal
*/
const QDateTime& startDateTotal() const;
/**
* @brief Returns the end date of the eclipse's total phase
*
* If the eclipse has a total phase, the date and time of its ending
* is returned. If this is no total eclipse, an invalid datetime object
* will be returned.
*
* @return The end date of the total phase or an invalid date
* @see startDateTotal
*/
const QDateTime& endDateTotal() const;
/**
* @brief Return the eclipse's magnitude
* @return The magnitude of the eclipse
*/
double magnitude() const;
/**
* @brief Return the coordinates of the eclipse's maximum
* @return GeoDataCoordinates of the eclipse's maximum
* @see dateMaximum
*/
const GeoDataCoordinates& maxLocation();
/**
* @brief The eclipse's central line
* @return The central line of the eclipse
*/
const GeoDataLineString& centralLine();
/**
* @brief Return the eclipse's umbra
* @return The eclipse's umbra
*/
const GeoDataLinearRing& umbra();
/**
* @brief Return the eclipse's southern penumbra
* @return The eclipse's southern penumbra
*/
const GeoDataLineString& southernPenumbra();
/**
* @brief Return the eclipse's northern penumbra
* @return The eclipse's northern umbra
*/
const GeoDataLineString& northernPenumbra();
/**
* @brief Return the eclipse's sun boundaries
* @return The eclipse's sun boundaries
*/
const QList<GeoDataLinearRing>& sunBoundaries();
/**
* @brief Return the shadow cone of the umbra
* @return The shadow cone of the umbra
*/
GeoDataLinearRing shadowConeUmbra();
/**
* @brief Return the shadow cone of the penumbra
* @return The shadow cone of the penumbra
*/
GeoDataLinearRing shadowConePenumbra();
/**
* @brief Return the shadow cone of the penumbra at 60 percent magnitude
* @return The shadow cone of the penumbra at 60 percent magnitude
*/
GeoDataLinearRing shadowCone60MagPenumbra();
private:
/**
* @brief Initialize the eclipse item
*
* Initializes all properties of the eclipse item and does basic
* calculations. Expensive calculations are done as required.
*
* @see calculate
*/
void initialize();
/**
* @brief Do detailed calculations
*
* Do the expensive calculations (like shadow cones) for this eclipse
* event. This is normally called on the first request of such data.
*/
void calculate();
EclSolar *m_ecl;
int m_index;
bool m_calculationsNeedUpdate;
bool m_isTotal;
QDateTime m_dateMaximum;
QDateTime m_startDatePartial;
QDateTime m_endDatePartial;
QDateTime m_startDateTotal;
QDateTime m_endDateTotal;
EclipsesItem::EclipsePhase m_phase;
double m_magnitude;
GeoDataCoordinates m_maxLocation;
GeoDataLineString m_centralLine;
GeoDataLinearRing m_umbra;
GeoDataLineString m_southernPenumbra;
GeoDataLineString m_northernPenumbra;
GeoDataLinearRing m_shadowConeUmbra;
GeoDataLinearRing m_shadowConePenumbra;
GeoDataLinearRing m_shadowCone60MagPenumbra;
QList<GeoDataLinearRing> m_sunBoundaries;
};
}
#endif // MARBLE_ECLIPSESITEM_H
diff --git a/src/plugins/render/eclipses/EclipsesModel.cpp b/src/plugins/render/eclipses/EclipsesModel.cpp
index ff434fc36..093d7cb89 100644
--- a/src/plugins/render/eclipses/EclipsesModel.cpp
+++ b/src/plugins/render/eclipses/EclipsesModel.cpp
@@ -1,212 +1,212 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#include "EclipsesModel.h"
#include "EclipsesItem.h"
#include "MarbleDebug.h"
#include "MarbleClock.h"
#include <eclsolar.h>
#include <QIcon>
namespace Marble
{
EclipsesModel::EclipsesModel( const MarbleModel *model, QObject *parent )
: QAbstractItemModel( parent ),
m_marbleModel( model ),
m_currentYear( 0 ),
m_withLunarEclipses( false )
{
m_ecl = new EclSolar();
m_ecl->setTimezone( model->clock()->timezone() / 3600. );
m_ecl->setLunarEcl( m_withLunarEclipses );
// oberservation point defaults to home location
qreal lon, lat;
int zoom;
m_marbleModel->home( lon, lat, zoom );
GeoDataCoordinates homeLocation( lon, lat, 0, GeoDataCoordinates::Degree );
setObservationPoint( homeLocation );
}
EclipsesModel::~EclipsesModel()
{
clear();
delete m_ecl;
}
const GeoDataCoordinates& EclipsesModel::observationPoint() const
{
return m_observationPoint;
}
void EclipsesModel::setObservationPoint( const GeoDataCoordinates &coords )
{
m_observationPoint = coords;
m_ecl->setLocalPos( coords.latitude(), coords.altitude(), 6000. );
}
void EclipsesModel::setYear( int year )
{
if( m_currentYear != year ) {
mDebug() << "Year changed - Calculating eclipses...";
m_currentYear = year;
m_ecl->putYear( year );
update();
}
}
int EclipsesModel::year() const
{
return m_currentYear;
}
void EclipsesModel::setWithLunarEclipses( const bool enable )
{
if( m_withLunarEclipses != enable ) {
m_withLunarEclipses = enable;
m_ecl->setLunarEcl( m_withLunarEclipses );
update();
}
}
bool EclipsesModel::withLunarEclipses() const
{
return m_withLunarEclipses;
}
EclipsesItem* EclipsesModel::eclipseWithIndex( int index )
{
for( EclipsesItem *item: m_items ) {
if( item->index() == index ) {
return item;
}
}
- return NULL;
+ return nullptr;
}
QList<EclipsesItem*> EclipsesModel::items() const
{
return m_items;
}
QModelIndex EclipsesModel::index( int row, int column, const QModelIndex &parent ) const
{
if( !hasIndex( row, column, parent ) ) {
return QModelIndex();
}
if( row >= m_items.count() ) {
return QModelIndex();
}
return createIndex( row, column, m_items.at( row ) );
}
QModelIndex EclipsesModel::parent( const QModelIndex &index ) const
{
Q_UNUSED( index );
return QModelIndex(); // no parents
}
int EclipsesModel::rowCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent );
return m_items.count();
}
int EclipsesModel::columnCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent );
return 4; // start, end, type magnitude
}
QVariant EclipsesModel::data( const QModelIndex &index, int role ) const
{
if( !index.isValid() ) {
return QVariant();
}
Q_ASSERT( index.column() < 4 );
EclipsesItem *item = static_cast<EclipsesItem*>( index.internalPointer() );
if( role == Qt::DisplayRole ) {
switch( index.column() ) {
case 0: return QVariant( item->startDatePartial() );
case 1: return QVariant( item->endDatePartial() );
case 2: return QVariant( item->phaseText() );
case 3: return QVariant( item->magnitude() );
default: break; // should never happen
}
}
if( role == Qt::DecorationRole ) {
if ( index.column() == 2 ) return QVariant( item->icon() );
}
return QVariant();
}
QVariant EclipsesModel::headerData( int section, Qt::Orientation orientation,
int role ) const
{
if( orientation != Qt::Horizontal || role != Qt::DisplayRole ) {
return QVariant();
}
switch( section ) {
case 0: return QVariant( tr( "Start" ) );
case 1: return QVariant( tr( "End" ) );
case 2: return QVariant( tr( "Type" ) );
case 3: return QVariant( tr( "Magnitude" ) );
default: break;
}
return QVariant();
}
void EclipsesModel::addItem( EclipsesItem *item )
{
m_items.append( item );
}
void EclipsesModel::clear()
{
beginResetModel();
qDeleteAll( m_items );
m_items.clear();
endResetModel();
}
void EclipsesModel::update()
{
clear();
beginInsertRows( QModelIndex(), 0, rowCount() );
int num = m_ecl->getNumberEclYear();
for( int i = 1; i <= num; ++i ) {
EclipsesItem *item = new EclipsesItem( m_ecl, i );
addItem( item );
}
endInsertRows();
}
} // namespace Marble
#include "moc_EclipsesModel.cpp"
diff --git a/src/plugins/render/eclipses/EclipsesModel.h b/src/plugins/render/eclipses/EclipsesModel.h
index 283aec97e..f45e1f945 100644
--- a/src/plugins/render/eclipses/EclipsesModel.h
+++ b/src/plugins/render/eclipses/EclipsesModel.h
@@ -1,187 +1,187 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#ifndef MARBLE_ECLIPSESMODEL_H
#define MARBLE_ECLIPSESMODEL_H
#include <QAbstractItemModel>
#include "GeoDataCoordinates.h"
#include "MarbleModel.h"
class EclSolar;
namespace Marble
{
class EclipsesItem;
/**
* @brief The model for eclipses
*
* EclipsesModel provides an interface to the eclsolar backend. Instances
* of this class hold EclipseItem objects for every eclipse event of a given
* year. Furthermore, it implements QTs AbstractItemModel interface and can
* be used with QTs view classes.
*/
class EclipsesModel : public QAbstractItemModel
{
Q_OBJECT
public:
- explicit EclipsesModel( const MarbleModel *model, QObject *parent = 0 );
+ explicit EclipsesModel( const MarbleModel *model, QObject *parent = nullptr );
~EclipsesModel() override;
/**
* @brief Return the current observation point
*
* Returns the current observation point on which location specific
* eclipse calculations are based.
*
* @return GeoDataCoordinates of the current observation point
* @see setObservationPoint
*/
const GeoDataCoordinates& observationPoint() const;
/**
* @brief Set the current observation point
*
* @param coords
*
* Set the current observation point to @p coords. This will mark all
* items for recalculation of eclipses details according to the new
* observation point.
*
* @see observationPoint
*/
void setObservationPoint( const GeoDataCoordinates &coords );
/**
* @brief Set the year
*
* @param year The year
*
* Sets the year to @p year. This clears all items in the model and
* fills it with all eclipse items for the given year.
*
* @see year
*/
void setYear( int year );
/**
* @brief Return the year
*
* Returns the year of all eclipse items in this model.
*
* @return the year of eclipse items in this model
* @see setYear
*/
int year() const;
/**
* @brief Set if lunar eclipses are enbled
* @param enable Indicates whether or not to allow lunar eclipses
*
* Allows to enable or disable inclusion of lunar eclipses.
*
* @see withLunarEclipses
*/
void setWithLunarEclipses( const bool enable );
/**
* @brief Return whether or not lunar eclipses are enabled
*
* Returns whether or not lunar eclipses are included in the eclipse
* calculation.
*
* @return True if lunar eclipses are enabled or false otherwise
* @see setWithLunarEclipses
*/
bool withLunarEclipses() const;
/**
* @brief Get eclipse item of a given year
*
* @param index
*
* This returns the eclipse item with @p index for the year set. If
* there is no eclipse with @p index in the set year, NULL will be
* returned.
*
* @return the requested eclipse item or NULL if there is no eclipse
* @see setYear
*/
EclipsesItem* eclipseWithIndex( int index );
/**
* @brief Return the items in this model
*
* Returns a list of items currently in the model.
*
* @return list of items in the model
*/
QList<EclipsesItem*> items() const;
// QT abstract item model interface
QModelIndex index( int row, int column,
const QModelIndex &parent = QModelIndex() ) const override;
QModelIndex parent( const QModelIndex &index ) const override;
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
QVariant data( const QModelIndex &index,
int role = Qt::DisplayRole ) const override;
QVariant headerData( int section, Qt::Orientation orientation,
int role = Qt::DisplayRole ) const override;
public Q_SLOTS:
/**
* @brief Update the list of eclipse items
*
* This forces an update of the current list of eclipse items by
* calculating all eclipse events for the currently set year and
* adding them to the model. All previously added items are
* cleared before.
*
* @see clear
*/
void update();
private:
/**
* @brief Add an item to the model
* @param item the item to add
*
* Adds @p item to the model.
*
* @see clear
*/
void addItem( EclipsesItem *item );
/**
* @brief Clears all items
*
* Clear the model by removing all items.
*
* @see addItem
*/
void clear();
const MarbleModel *m_marbleModel;
EclSolar *m_ecl;
QList<EclipsesItem*> m_items;
int m_currentYear;
bool m_withLunarEclipses;
GeoDataCoordinates m_observationPoint;
};
}
#endif // MARBLE_ECLIPSESMODEL_H
diff --git a/src/plugins/render/eclipses/EclipsesPlugin.cpp b/src/plugins/render/eclipses/EclipsesPlugin.cpp
index 9613ea237..0b9e0bd15 100644
--- a/src/plugins/render/eclipses/EclipsesPlugin.cpp
+++ b/src/plugins/render/eclipses/EclipsesPlugin.cpp
@@ -1,510 +1,510 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#include "EclipsesPlugin.h"
#include "MarbleWidget.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "MarbleClock.h"
#include "ViewportParams.h"
#include "GeoPainter.h"
#include "EclipsesModel.h"
#include "EclipsesItem.h"
#include "EclipsesBrowserDialog.h"
#include "ui_EclipsesConfigDialog.h"
#include "ui_EclipsesReminderDialog.h"
#include <QMenu>
#include <QPushButton>
namespace Marble
{
EclipsesPlugin::EclipsesPlugin()
- : RenderPlugin( 0 ),
+ : RenderPlugin( nullptr ),
m_isInitialized( false ),
- m_marbleWidget( 0 ),
- m_model( 0 ),
- m_eclipsesActionGroup( 0 ),
- m_eclipsesMenuAction( 0 ),
- m_eclipsesListMenu( 0 ),
+ m_marbleWidget( nullptr ),
+ m_model( nullptr ),
+ m_eclipsesActionGroup( nullptr ),
+ m_eclipsesMenuAction( nullptr ),
+ m_eclipsesListMenu( nullptr ),
m_menuYear( 0 ),
- m_configDialog( 0 ),
- m_configWidget( 0 ),
- m_browserDialog( 0 ),
- m_reminderDialog( 0 ),
- m_reminderWidget( 0 )
+ m_configDialog( nullptr ),
+ m_configWidget( nullptr ),
+ m_browserDialog( nullptr ),
+ m_reminderDialog( nullptr ),
+ m_reminderWidget( nullptr )
{
}
EclipsesPlugin::EclipsesPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
m_isInitialized( false ),
- m_marbleWidget( 0 ),
- m_model( 0 ),
- m_eclipsesActionGroup( 0 ),
- m_eclipsesMenuAction( 0 ),
- m_eclipsesListMenu( 0 ),
+ m_marbleWidget( nullptr ),
+ m_model( nullptr ),
+ m_eclipsesActionGroup( nullptr ),
+ m_eclipsesMenuAction( nullptr ),
+ m_eclipsesListMenu( nullptr ),
m_menuYear( 0 ),
- m_configDialog( 0 ),
- m_configWidget( 0 ),
- m_browserDialog( 0 ),
- m_reminderDialog( 0 ),
- m_reminderWidget( 0 )
+ m_configDialog( nullptr ),
+ m_configWidget( nullptr ),
+ m_browserDialog( nullptr ),
+ m_reminderDialog( nullptr ),
+ m_reminderWidget( nullptr )
{
connect( this, SIGNAL(settingsChanged(QString)),
SLOT(updateSettings()) );
}
EclipsesPlugin::~EclipsesPlugin()
{
if( m_isInitialized ) {
delete m_model;
delete m_eclipsesActionGroup;
delete m_eclipsesListMenu;
delete m_configDialog;
delete m_configWidget;
delete m_browserDialog;
delete m_reminderDialog;
delete m_reminderWidget;
}
}
QStringList EclipsesPlugin::backendTypes() const
{
return QStringList(QStringLiteral("eclipses"));
}
QString EclipsesPlugin::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList EclipsesPlugin::renderPosition() const
{
return QStringList(QStringLiteral("ORBIT"));
}
QString EclipsesPlugin::name() const
{
return tr( "Eclipses" );
}
QString EclipsesPlugin::nameId() const
{
return QStringLiteral("eclipses");
}
QString EclipsesPlugin::guiString() const
{
return tr( "E&clipses" );
}
QString EclipsesPlugin::version() const
{
return QStringLiteral("1.0");
}
QString EclipsesPlugin::description() const
{
return tr( "This plugin visualizes solar eclipses." );
}
QString EclipsesPlugin::copyrightYears() const
{
return QStringLiteral("2013");
}
QVector<PluginAuthor> EclipsesPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Rene Kuettner"), QStringLiteral("rene@bitkanal.net"))
<< PluginAuthor(QStringLiteral("Gerhard Holtkamp"), QString());
}
QIcon EclipsesPlugin::icon() const
{
return QIcon(QStringLiteral(":res/eclipses.png"));
}
RenderPlugin::RenderType EclipsesPlugin::renderType() const
{
return RenderPlugin::ThemeRenderType;
//return UnknownRenderType;
}
QList<QActionGroup*>* EclipsesPlugin::actionGroups() const
{
return const_cast<QList<QActionGroup*>*>( &m_actionGroups );
}
QDialog* EclipsesPlugin::configDialog()
{
Q_ASSERT( m_isInitialized );
return m_configDialog;
}
void EclipsesPlugin::initialize()
{
if( isInitialized() ) {
return;
}
// initialize dialogs
delete m_configDialog;
m_configDialog = new QDialog();
delete m_configWidget;
m_configWidget = new Ui::EclipsesConfigDialog();
m_configWidget->setupUi( m_configDialog );
connect( m_configDialog, SIGNAL(accepted()),
this, SLOT(writeSettings()) );
connect( m_configDialog, SIGNAL(rejected()),
this, SLOT(readSettings()) );
connect( m_configWidget->buttonBox->button( QDialogButtonBox::Reset ),
SIGNAL(clicked()), this, SLOT(readSettings()) );
connect( m_configWidget->buttonBox->button( QDialogButtonBox::Apply ),
SIGNAL(clicked()), this, SLOT(writeSettings()) );
connect( m_configWidget->buttonBox->button( QDialogButtonBox::Apply ),
SIGNAL(clicked()), this, SLOT(updateEclipses()) );
m_browserDialog = new EclipsesBrowserDialog( marbleModel() );
connect( m_browserDialog, SIGNAL(buttonShowClicked(int,int)),
this, SLOT(showEclipse(int,int)) );
connect( m_browserDialog, SIGNAL(buttonSettingsClicked()),
m_configDialog, SLOT(show()) );
delete m_reminderDialog;
m_reminderDialog = new QDialog();
delete m_reminderWidget;
m_reminderWidget = new Ui::EclipsesReminderDialog();
m_reminderWidget->setupUi( m_reminderDialog );
// initialize menu entries
m_eclipsesActionGroup = new QActionGroup( this );
m_actionGroups.append( m_eclipsesActionGroup );
m_eclipsesListMenu = new QMenu();
m_eclipsesActionGroup->addAction( m_eclipsesListMenu->menuAction() );
connect( m_eclipsesListMenu, SIGNAL(triggered(QAction*)),
this, SLOT(showEclipseFromMenu(QAction*)) );
m_eclipsesMenuAction = new QAction(
tr("Browse Ecli&pses..."), m_eclipsesActionGroup );
m_eclipsesMenuAction->setIcon(QIcon(QStringLiteral(":res/eclipses.png")));
m_eclipsesActionGroup->addAction( m_eclipsesMenuAction );
connect( m_eclipsesMenuAction, SIGNAL(triggered()),
m_browserDialog, SLOT(show()) );
// initialize eclipses model
m_model = new EclipsesModel( marbleModel() );
connect( marbleModel()->clock(), SIGNAL(timeChanged()),
this, SLOT(updateEclipses()) );
m_isInitialized = true;
readSettings();
updateEclipses();
updateMenuItemState();
updateSettings();
}
bool EclipsesPlugin::isInitialized() const
{
return m_isInitialized;
}
bool EclipsesPlugin::eventFilter( QObject *object, QEvent *e )
{
// delayed initialization of pointer to marble widget
MarbleWidget *widget = dynamic_cast<MarbleWidget*> (object);
if ( widget && m_marbleWidget != widget ) {
connect( widget, SIGNAL(themeChanged(QString)),
this, SLOT(updateMenuItemState()) );
m_marbleWidget = widget;
}
return RenderPlugin::eventFilter(object, e);
}
bool EclipsesPlugin::render( GeoPainter *painter,
ViewportParams *viewport,
const QString &renderPos,
GeoSceneLayer *layer )
{
Q_UNUSED( viewport );
Q_UNUSED( renderPos );
Q_UNUSED( layer );
if (marbleModel()->planetId() == QLatin1String("earth")) {
for( EclipsesItem *item: m_model->items() ) {
if( item->takesPlaceAt( marbleModel()->clock()->dateTime() ) ) {
return renderItem( painter, item );
}
}
}
return true;
}
bool EclipsesPlugin::renderItem( GeoPainter *painter, EclipsesItem *item ) const
{
int phase = item->phase();
// Draw full penumbra shadow cone
if( m_configWidget->checkBoxShowFullPenumbra->isChecked() ) {
painter->setPen( Oxygen::aluminumGray1 );
QColor sunBoundingBrush ( Oxygen::aluminumGray6 );
sunBoundingBrush.setAlpha( 48 );
painter->setBrush( sunBoundingBrush );
painter->drawPolygon( item->shadowConePenumbra() );
}
// Draw 60% penumbra shadow cone
if( m_configWidget->checkBoxShow60MagPenumbra->isChecked() ) {
painter->setPen( Oxygen::aluminumGray2 );
QColor penumbraBrush ( Oxygen::aluminumGray6 );
penumbraBrush.setAlpha( 96 );
painter->setBrush( penumbraBrush );
painter->drawPolygon( item->shadowCone60MagPenumbra() );
}
// Draw southern boundary of the penumbra
if( m_configWidget->checkBoxShowSouthernPenumbra->isChecked() ) {
QColor southernBoundaryColor(Oxygen::brickRed1);
southernBoundaryColor.setAlpha(128);
QPen southernBoundary(southernBoundaryColor);
southernBoundary.setWidth(3);
painter->setPen( southernBoundary );
painter->drawPolyline( item->southernPenumbra() );
painter->setPen( Oxygen::brickRed5 );
painter->drawPolyline( item->southernPenumbra() );
}
// Draw northern boundary of the penumbra
if( m_configWidget->checkBoxShowNorthernPenumbra->isChecked() ) {
QColor northernBoundaryColor(Oxygen::brickRed1);
northernBoundaryColor.setAlpha(128);
QPen northernBoundary(northernBoundaryColor);
northernBoundary.setWidth(3);
painter->setPen( northernBoundary );
painter->drawPolyline( item->northernPenumbra() );
painter->setPen( Oxygen::brickRed5 );
painter->drawPolyline( item->northernPenumbra() );
}
// Draw Sunrise / Sunset Boundaries
if( m_configWidget->checkBoxShowSunBoundaries->isChecked() ) {
painter->setPen( Oxygen::hotOrange6 );
const QList<GeoDataLinearRing> boundaries = item->sunBoundaries();
QList<GeoDataLinearRing>::const_iterator i = boundaries.constBegin();
QColor sunBoundingBrush ( Oxygen::hotOrange5 );
sunBoundingBrush.setAlpha( 64 );
painter->setBrush( sunBoundingBrush );
for( ; i != boundaries.constEnd(); ++i ) {
painter->drawPolygon( *i );
}
}
// total or annular eclipse
if( m_configWidget->checkBoxShowUmbra->isChecked() && phase > 3 )
{
painter->setPen( Oxygen::aluminumGray4 );
QColor sunBoundingBrush ( Oxygen::aluminumGray6 );
sunBoundingBrush.setAlpha( 128 );
painter->setBrush( sunBoundingBrush );
painter->drawPolygon( item->umbra() );
// draw shadow cone
painter->setPen( Qt::black );
QColor shadowConeBrush ( Oxygen::aluminumGray6 );
shadowConeBrush.setAlpha( 128 );
painter->setBrush( shadowConeBrush );
painter->drawPolygon( item->shadowConeUmbra() );
}
// plot central line
if( m_configWidget->checkBoxShowCentralLine->isChecked() && phase > 3 ) {
painter->setPen( Qt::black );
painter->drawPolyline( item->centralLine() );
}
// mark point of maximum eclipse
if( m_configWidget->checkBoxShowMaximum->isChecked() ) {
painter->setPen( Qt::white );
QColor sunBoundingBrush ( Qt::white );
sunBoundingBrush.setAlpha( 128 );
painter->setBrush( sunBoundingBrush );
painter->drawEllipse( item->maxLocation(), 15, 15 );
painter->setPen( Oxygen::brickRed4 );
painter->drawText( item->maxLocation(), tr( "Maximum of Eclipse" ) );
}
return true;
}
QHash<QString, QVariant> EclipsesPlugin::settings() const
{
return RenderPlugin::settings();
}
void EclipsesPlugin::setSettings( const QHash<QString, QVariant> &settings )
{
RenderPlugin::setSettings( settings );
m_settings = settings;
emit settingsChanged( nameId() );
}
void EclipsesPlugin::readSettings()
{
m_configWidget->checkBoxEnableLunarEclipses->setChecked(
m_settings.value(QStringLiteral("enableLunarEclipses"), false).toBool());
m_configWidget->checkBoxShowMaximum->setChecked(
m_settings.value(QStringLiteral("showMaximum"), true).toBool());
m_configWidget->checkBoxShowUmbra->setChecked(
m_settings.value(QStringLiteral("showUmbra"), true).toBool());
m_configWidget->checkBoxShowSouthernPenumbra->setChecked(
m_settings.value(QStringLiteral("showSouthernPenumbra"), true).toBool());
m_configWidget->checkBoxShowNorthernPenumbra->setChecked(
m_settings.value(QStringLiteral("showNorthernPenumbra"), true).toBool());
m_configWidget->checkBoxShowCentralLine->setChecked(
m_settings.value(QStringLiteral("showCentralLine"), true).toBool());
m_configWidget->checkBoxShowFullPenumbra->setChecked(
m_settings.value(QStringLiteral("showFullPenumbra"), true).toBool());
m_configWidget->checkBoxShow60MagPenumbra->setChecked(
m_settings.value(QStringLiteral("show60MagPenumbra"), false).toBool());
m_configWidget->checkBoxShowSunBoundaries->setChecked(
m_settings.value(QStringLiteral("showSunBoundaries"), true).toBool());
}
void EclipsesPlugin::writeSettings()
{
m_settings.insert(QStringLiteral("enableLunarEclipses"),
m_configWidget->checkBoxEnableLunarEclipses->isChecked() );
m_settings.insert(QStringLiteral("showMaximum"),
m_configWidget->checkBoxShowMaximum->isChecked() );
m_settings.insert(QStringLiteral("showUmbra"),
m_configWidget->checkBoxShowUmbra->isChecked() );
m_settings.insert(QStringLiteral("showSouthernPenumbra"),
m_configWidget->checkBoxShowSouthernPenumbra->isChecked() );
m_settings.insert(QStringLiteral("showNorthernPenumbra"),
m_configWidget->checkBoxShowNorthernPenumbra->isChecked() );
m_settings.insert(QStringLiteral("showCentralLine"),
m_configWidget->checkBoxShowCentralLine->isChecked() );
m_settings.insert(QStringLiteral("showFullPenumbra"),
m_configWidget->checkBoxShowFullPenumbra->isChecked() );
m_settings.insert(QStringLiteral("show60MagPenumbra"),
m_configWidget->checkBoxShow60MagPenumbra->isChecked() );
m_settings.insert(QStringLiteral("showSunBoundaries"),
m_configWidget->checkBoxShowSunBoundaries->isChecked() );
emit settingsChanged( nameId() );
}
void EclipsesPlugin::updateSettings()
{
if (!isInitialized()) {
return;
}
m_browserDialog->setWithLunarEclipses(
m_settings.value(QStringLiteral("enableLunarEclipses")).toBool());
if( m_model->withLunarEclipses() !=
m_settings.value(QStringLiteral("enableLunarEclipses")).toBool()) {
updateEclipses();
}
}
void EclipsesPlugin::updateEclipses()
{
// mDebug() << "Updating eclipses....";
const int year = marbleModel()->clock()->dateTime().date().year();
const bool lun = m_settings.value(QStringLiteral("enableLunarEclipses")).toBool();
if( ( m_menuYear != year ) || ( m_model->withLunarEclipses() != lun ) ) {
// remove old menus
for( QAction *action: m_eclipsesListMenu->actions() ) {
m_eclipsesListMenu->removeAction( action );
delete action;
}
// update year and create menus for this year's eclipse events
if( m_model->year() != year ) {
m_model->setYear( year );
}
m_menuYear = year;
// enable/disable lunar eclipses if necessary
if( m_model->withLunarEclipses() != lun ) {
m_model->setWithLunarEclipses( lun );
}
m_eclipsesListMenu->setTitle( tr("Eclipses in %1").arg( year ) );
for( EclipsesItem *item: m_model->items() ) {
QAction *action = m_eclipsesListMenu->addAction(
item->dateMaximum().date().toString() );
action->setData( QVariant( 1000 * item->dateMaximum().date().year() + item->index() ) );
action->setIcon( item->icon() );
}
emit actionGroupsChanged();
}
}
void EclipsesPlugin::updateMenuItemState()
{
if( !isInitialized() ) {
return;
}
// eclipses are only supported for earth based obervers at the moment
// so we disable the menu items for other celestial bodies
const bool active = (marbleModel()->planetId() == QLatin1String("earth"));
m_eclipsesListMenu->setEnabled( active );
m_eclipsesMenuAction->setEnabled( active );
}
void EclipsesPlugin::showEclipse( int year, int index )
{
if( m_model->year() != year ) {
m_model->setYear( year );
}
EclipsesItem *item = m_model->eclipseWithIndex( index );
Q_ASSERT( item );
if( item ) {
m_marbleWidget->model()->clock()->setDateTime( item->dateMaximum() );
m_marbleWidget->centerOn( item->maxLocation() );
}
}
void EclipsesPlugin::showEclipseFromMenu( QAction *action )
{
Q_ASSERT( action->data().isValid() );
int year = action->data().toInt() / 1000;
int index = action->data().toInt() - 1000 * year;
showEclipse( year, index );
}
} // namespace Marble
#include "moc_EclipsesPlugin.cpp"
diff --git a/src/plugins/render/elevationprofilefloatitem/ElevationProfileContextMenu.cpp b/src/plugins/render/elevationprofilefloatitem/ElevationProfileContextMenu.cpp
index 2440c5d4f..005e9ce37 100644
--- a/src/plugins/render/elevationprofilefloatitem/ElevationProfileContextMenu.cpp
+++ b/src/plugins/render/elevationprofilefloatitem/ElevationProfileContextMenu.cpp
@@ -1,109 +1,109 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011-2012 Florian Eßer <f.esser@rwth-aachen.de>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2013 Roman Karlstetter <roman.karlstetter@googlemail.com>
//
#include "ElevationProfileContextMenu.h"
#include "ElevationProfileDataSource.h"
#include "ElevationProfileFloatItem.h"
#include "MarbleDebug.h"
namespace Marble {
ElevationProfileContextMenu::ElevationProfileContextMenu(ElevationProfileFloatItem *floatItem):
QObject(floatItem),
m_floatItem(floatItem),
- m_sourceGrp(0),
- m_contextMenu(0),
- m_trackMapper(0)
+ m_sourceGrp(nullptr),
+ m_contextMenu(nullptr),
+ m_trackMapper(nullptr)
{
}
QMenu *ElevationProfileContextMenu::getMenu()
{
if (!m_contextMenu) {
m_contextMenu = m_floatItem->contextMenu();
for ( QAction *action: m_contextMenu->actions() ) {
if ( action->text() == tr( "&Configure..." ) ) {
m_contextMenu->removeAction( action );
break;
}
}
QAction *zoomToViewportAction = m_contextMenu->addAction( tr("&Zoom to viewport"), m_floatItem,
SLOT(toggleZoomToViewport()) );
zoomToViewportAction->setCheckable( true );
zoomToViewportAction->setChecked( m_floatItem->m_zoomToViewport );
m_contextMenu->addSeparator();
m_sourceGrp = new QActionGroup(this);
m_trackMapper = new QSignalMapper(this);
updateContextMenuEntries();
}
return m_contextMenu;
}
void ElevationProfileContextMenu::updateContextMenuEntries()
{
// context menu has not yet been initialized, this functions is called as last step of initialization
if (!m_contextMenu) {
return;
}
// completely rebuild selection, TODO could be possibly improved to only add/remove items incrementally
for (QAction* action: m_selectionActions) {
m_contextMenu->removeAction( action );
}
// clear state
qDeleteAll(m_selectionActions);
m_selectionActions.clear();
// add route data source (if available)
if ( m_floatItem->m_routeDataSource.isDataAvailable()) {
QAction *route = new QAction( tr( "Route" ), m_contextMenu );
route->setActionGroup(m_sourceGrp);
route->setCheckable(true);
route->setChecked(m_floatItem->m_activeDataSource == &m_floatItem->m_routeDataSource);
connect( route, SIGNAL(triggered()), m_floatItem, SLOT(switchToRouteDataSource()) );
m_selectionActions.append(route);
}
// add tracks (if available)
if ( m_floatItem->m_trackDataSource.isDataAvailable()) {
QStringList sources = m_floatItem->m_trackDataSource.sourceDescriptions();
for (int i = 0; i<sources.size(); ++i) {
QAction *track = new QAction( tr("Track: ") + sources[i], m_contextMenu);
connect(track, SIGNAL(triggered()), m_trackMapper, SLOT(map()));
track->setCheckable(true);
track->setChecked(m_floatItem->m_activeDataSource == &m_floatItem->m_trackDataSource && m_floatItem->m_trackDataSource.currentSourceIndex() == i);
track->setActionGroup(m_sourceGrp);
m_selectionActions.append(track);
m_trackMapper->setMapping(track, i);
}
connect(m_trackMapper, SIGNAL(mapped(int)), m_floatItem, SLOT(switchToTrackDataSource(int)));
}
// no route or track available, add disabled action to inform user about it
if ( m_selectionActions.isEmpty() ) {
QAction *disabledInformationAction = new QAction( tr( "Create a route or load a track from file to view its elevation profile." ), m_contextMenu);
disabledInformationAction->setEnabled(false);
m_selectionActions.append(disabledInformationAction);
}
for (QAction *action: m_selectionActions) {
m_contextMenu->addAction(action);
}
}
}
#include "moc_ElevationProfileContextMenu.cpp"
diff --git a/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.cpp b/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.cpp
index 7615aefda..3346420da 100644
--- a/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.cpp
+++ b/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.cpp
@@ -1,250 +1,250 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011-2012 Florian Eßer <f.esser@rwth-aachen.de>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2013 Roman Karlstetter <roman.karlstetter@googlemail.com>
//
#include "ElevationProfileDataSource.h"
#include "ElevationModel.h"
#include "GeoDataDocument.h"
#include "GeoDataLineString.h"
#include "GeoDataObject.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTrack.h"
#include "GeoDataTreeModel.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "routing/Route.h"
#include "routing/RoutingModel.h"
#include <QFileInfo>
namespace Marble
{
ElevationProfileDataSource::ElevationProfileDataSource( QObject *parent ) :
QObject( parent )
{
// nothing to do
}
QVector<QPointF> ElevationProfileDataSource::calculateElevationData(const GeoDataLineString &lineString) const
{
// TODO: Don't re-calculate the whole route if only a small part of it was changed
QVector<QPointF> result;
qreal distance = 0;
//GeoDataLineString path;
for ( int i = 0; i < lineString.size(); i++ ) {
const qreal ele = getElevation( lineString[i] );
if ( i ) {
distance += EARTH_RADIUS * lineString[i-1].sphericalDistanceTo(lineString[i]);
}
if ( ele != invalidElevationData ) { // skip no data
result.append( QPointF( distance, ele ) );
}
}
return result;
}
// end of impl of ElevationProfileDataSource
ElevationProfileTrackDataSource::ElevationProfileTrackDataSource( const GeoDataTreeModel *treeModel, QObject *parent ) :
ElevationProfileDataSource( parent ),
m_currentSourceIndex( -1 )
{
if ( treeModel ) {
connect( treeModel, SIGNAL(added(GeoDataObject*)), SLOT(handleObjectAdded(GeoDataObject*)) );
connect( treeModel, SIGNAL(removed(GeoDataObject*)), SLOT(handleObjectRemoved(GeoDataObject*)) );
}
}
QStringList ElevationProfileTrackDataSource::sourceDescriptions() const
{
return m_trackChooserList;
}
void ElevationProfileTrackDataSource::setSourceIndex(int index)
{
if (m_currentSourceIndex != index) {
m_currentSourceIndex = index;
requestUpdate();
}
}
int ElevationProfileTrackDataSource::currentSourceIndex() const
{
return m_currentSourceIndex;
}
void ElevationProfileTrackDataSource::requestUpdate()
{
if ( m_currentSourceIndex < 0 ) {
return;
}
if ( m_currentSourceIndex >= m_trackList.size() ) {
return;
}
const GeoDataLineString *routePoints = m_trackList[m_currentSourceIndex]->lineString();
emit dataUpdated(*routePoints, calculateElevationData(*routePoints));
}
bool ElevationProfileTrackDataSource::isDataAvailable() const
{
return !m_trackHash.isEmpty();
}
qreal ElevationProfileTrackDataSource::getElevation(const GeoDataCoordinates &coordinates) const
{
return coordinates.altitude();
}
void ElevationProfileTrackDataSource::handleObjectAdded(GeoDataObject *object)
{
const GeoDataDocument *document = dynamic_cast<const GeoDataDocument *>(object);
if (!document) {
return;// don't know what to do if not a document
}
QList<const GeoDataTrack *> trackList;
for (int i = 0; i<document->size(); ++i) {
const GeoDataFeature *feature = document->child(i);
const GeoDataPlacemark *placemark = dynamic_cast<const GeoDataPlacemark*>(feature);
if (!placemark) {
continue;
}
const GeoDataMultiGeometry *multiGeometry = dynamic_cast<const GeoDataMultiGeometry *>(placemark->geometry());
if (!multiGeometry) {
continue;
}
for (int i = 0; i<multiGeometry->size(); i++) {
const GeoDataTrack *track = dynamic_cast<const GeoDataTrack *>(multiGeometry->child(i));
if (track && track->size() > 1) {
mDebug() << "new GeoDataTrack for ElevationProfile detected";
trackList.append(track);
}
}
}
if (trackList.isEmpty()) {
return;
}
// update internal datastructures
m_trackHash.insert(document->fileName(), trackList);
- const GeoDataTrack *selectedTrack = 0;
+ const GeoDataTrack *selectedTrack = nullptr;
if ( 0 <= m_currentSourceIndex && m_currentSourceIndex < m_trackList.size() ) {
selectedTrack = m_trackList[m_currentSourceIndex];
}
m_trackChooserList.clear();
m_trackList.clear();
QHashIterator<QString, QList<const GeoDataTrack *> > i(m_trackHash);
while (i.hasNext()) {
i.next();
mDebug() << i.key() << ": " << i.value() << endl;
QFileInfo info(i.key());
QString filename = info.fileName();
QList<const GeoDataTrack *> list = i.value();
for (int i = 0; i<list.size(); ++i) {
m_trackList << list[i];
m_trackChooserList << QString(filename + QLatin1String(": ") + QString::number(i));
}
}
if (selectedTrack) {
m_currentSourceIndex = m_trackList.indexOf(selectedTrack);
}
emit sourceCountChanged();
}
void ElevationProfileTrackDataSource::handleObjectRemoved(GeoDataObject *object)
{
if (m_trackList.size() == 0) {
// no track loaded, nothing to remove
return;
}
const GeoDataDocument *topLevelDoc = dynamic_cast<const GeoDataDocument*>(object);
if (!topLevelDoc) {
return;// don't know what to do if not a document
}
const QString key = topLevelDoc->fileName();
if ( !m_trackHash.contains( key ) ) {
return;
}
const QList<const GeoDataTrack *> list = m_trackHash.value(key);
const GeoDataTrack *const selectedTrack = m_currentSourceIndex == -1 ? 0 : m_trackList[m_currentSourceIndex];
for (int i = 0; i<list.size(); i++) {
int idx = m_trackList.indexOf(list[i]);
m_trackList.removeAt(idx);
m_trackChooserList.removeAt(idx);
}
m_trackHash.remove(key);
m_currentSourceIndex = m_trackList.indexOf(selectedTrack);
if (m_currentSourceIndex == -1) {
m_currentSourceIndex = 0;
}
emit sourceCountChanged();
requestUpdate();
}
// end of impl of ElevationProfileTrackDataSource
ElevationProfileRouteDataSource::ElevationProfileRouteDataSource( const RoutingModel *routingModel, const ElevationModel *elevationModel, QObject *parent ) :
ElevationProfileDataSource( parent ),
m_routingModel( routingModel ),
m_elevationModel( elevationModel ),
m_routeAvailable( false )
{
}
void ElevationProfileRouteDataSource::requestUpdate()
{
if (m_routeAvailable != isDataAvailable()) {
// availability of route changed
emit sourceCountChanged();
m_routeAvailable = isDataAvailable();
}
const GeoDataLineString routePoints = m_routingModel->route().path();
const QVector<QPointF> elevationData = calculateElevationData(routePoints);
emit dataUpdated( routePoints, elevationData );
}
bool ElevationProfileRouteDataSource::isDataAvailable() const
{
return m_routingModel && m_routingModel->rowCount() > 0;
}
qreal ElevationProfileRouteDataSource::getElevation(const GeoDataCoordinates &coordinates) const
{
const qreal lat = coordinates.latitude ( GeoDataCoordinates::Degree );
const qreal lon = coordinates.longitude( GeoDataCoordinates::Degree );
qreal ele = m_elevationModel->height( lon, lat );
return ele;
}
// end of impl of ElevationProfileRouteDataSource
}
#include "moc_ElevationProfileDataSource.cpp"
diff --git a/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.h b/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.h
index 07ed372a0..9ca7db334 100644
--- a/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.h
+++ b/src/plugins/render/elevationprofilefloatitem/ElevationProfileDataSource.h
@@ -1,120 +1,120 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011-2012 Florian Eßer <f.esser@rwth-aachen.de>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2013 Roman Karlstetter <roman.karlstetter@googlemail.com>
//
#ifndef ELEVATIONPROFILEDATASOURCE_H
#define ELEVATIONPROFILEDATASOURCE_H
#include <QObject>
#include <QHash>
#include <QList>
#include <QPointF>
#include <QStringList>
namespace Marble
{
class ElevationModel;
class GeoDataCoordinates;
class GeoDataLineString;
class GeoDataObject;
class GeoDataTrack;
class GeoDataTreeModel;
class RoutingModel;
class ElevationProfileDataSource : public QObject
{
Q_OBJECT
public:
- explicit ElevationProfileDataSource( QObject *parent = 0 );
+ explicit ElevationProfileDataSource( QObject *parent = nullptr );
/**
* @brief isDataAvailable
* @return true if data is available to display
*/
virtual bool isDataAvailable() const = 0;
public Q_SLOTS:
virtual void requestUpdate() = 0;
Q_SIGNALS:
void sourceCountChanged();
void dataUpdated(const GeoDataLineString &points, const QVector<QPointF> &elevationData);
protected:
QVector<QPointF> calculateElevationData(const GeoDataLineString &lineString) const;
virtual qreal getElevation(const GeoDataCoordinates &coordinates) const = 0;
};
/**
* @brief The ElevationProfileTrackDataSource provides elevation profile of GeoDataTrack Objects in the marblemodel
*/
class ElevationProfileTrackDataSource : public ElevationProfileDataSource
{
Q_OBJECT
public:
- explicit ElevationProfileTrackDataSource( const GeoDataTreeModel *treeModel, QObject *parent = 0 );
+ explicit ElevationProfileTrackDataSource( const GeoDataTreeModel *treeModel, QObject *parent = nullptr );
bool isDataAvailable() const override;
QStringList sourceDescriptions() const;
void setSourceIndex(int index);
int currentSourceIndex() const;
public Q_SLOTS:
void requestUpdate() override;
protected:
qreal getElevation(const GeoDataCoordinates &coordinates) const override;
private Q_SLOTS:
void handleObjectAdded( GeoDataObject *object );
void handleObjectRemoved( GeoDataObject *object );
private:
QHash<QString, QList<const GeoDataTrack *> > m_trackHash;
QStringList m_trackChooserList;
QList<const GeoDataTrack *> m_trackList;
int m_currentSourceIndex;
};
/**
* @brief The ElevationProfileRouteDataSource provides elevation profile of the current route
*/
class ElevationProfileRouteDataSource : public ElevationProfileDataSource
{
Q_OBJECT
public:
- ElevationProfileRouteDataSource( const RoutingModel *routingModel, const ElevationModel *elevationModel, QObject *parent = 0 );
+ ElevationProfileRouteDataSource( const RoutingModel *routingModel, const ElevationModel *elevationModel, QObject *parent = nullptr );
bool isDataAvailable() const override;
public Q_SLOTS:
void requestUpdate() override;
protected:
qreal getElevation(const GeoDataCoordinates &coordinates) const override;
private:
const RoutingModel *const m_routingModel;
const ElevationModel *const m_elevationModel;
bool m_routeAvailable; // save state if route is available to notify FloatItem when this changes
};
}
#endif // ELEVATIONPROFILEDATASOURCE_H
diff --git a/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.cpp b/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.cpp
index af59c3546..44191c229 100644
--- a/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.cpp
+++ b/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.cpp
@@ -1,728 +1,728 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011-2012 Florian Eßer <f.esser@rwth-aachen.de>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2013 Roman Karlstetter <roman.karlstetter@googlemail.com>
//
#include "ElevationProfileFloatItem.h"
#include "ElevationProfileContextMenu.h"
#include "ui_ElevationProfileConfigWidget.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTreeModel.h"
#include "ViewportParams.h"
#include "MarbleDirs.h"
#include "ElevationModel.h"
#include "MarbleGraphicsGridLayout.h"
#include "MarbleDebug.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingModel.h"
#include <QContextMenuEvent>
#include <QRect>
#include <QPainter>
#include <QPushButton>
#include <QMenu>
#include <QMouseEvent>
namespace Marble
{
ElevationProfileFloatItem::ElevationProfileFloatItem( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( 220, 10.5 ), QSizeF( 0.0, 50.0 ) ),
- m_activeDataSource(0),
- m_routeDataSource( marbleModel ? marbleModel->routingManager()->routingModel() : 0, marbleModel ? marbleModel->elevationModel() : 0, this ),
- m_trackDataSource( marbleModel ? marbleModel->treeModel() : 0, this ),
- m_configDialog( 0 ),
- ui_configWidget( 0 ),
+ m_activeDataSource(nullptr),
+ m_routeDataSource( marbleModel ? marbleModel->routingManager()->routingModel() : nullptr, marbleModel ? marbleModel->elevationModel() : nullptr, this ),
+ m_trackDataSource( marbleModel ? marbleModel->treeModel() : nullptr, this ),
+ m_configDialog( nullptr ),
+ ui_configWidget( nullptr ),
m_leftGraphMargin( 0 ),
m_eleGraphWidth( 0 ),
m_viewportWidth( 0 ),
m_shrinkFactorY( 1.2 ),
m_fontHeight( 10 ),
m_markerPlacemark( new GeoDataPlacemark ),
m_documentIndex( -1 ),
m_cursorPositionX( 0 ),
m_isInitialized( false ),
- m_contextMenu( 0 ),
- m_marbleWidget( 0 ),
+ m_contextMenu( nullptr ),
+ m_marbleWidget( nullptr ),
m_firstVisiblePoint( 0 ),
m_lastVisiblePoint( 0 ),
m_zoomToViewport( false )
{
setVisible( false );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( smallScreen ) {
setPosition( QPointF( 10.5, 10.5 ) );
}
bool const highRes = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::HighResolution;
m_eleGraphHeight = highRes ? 100 : 50; /// TODO make configurable
setPadding( 1 );
m_markerDocument.setDocumentRole( UnknownDocument );
m_markerDocument.setName(QStringLiteral("Elevation Profile"));
m_markerPlacemark->setName(QStringLiteral("Elevation Marker"));
m_markerPlacemark->setVisible( false );
m_markerDocument.append( m_markerPlacemark );
m_contextMenu = new ElevationProfileContextMenu(this);
connect( &m_trackDataSource, SIGNAL(sourceCountChanged()), m_contextMenu, SLOT(updateContextMenuEntries()) );
connect( &m_routeDataSource, SIGNAL(sourceCountChanged()), m_contextMenu, SLOT(updateContextMenuEntries()) );
}
ElevationProfileFloatItem::~ElevationProfileFloatItem()
{
}
QStringList ElevationProfileFloatItem::backendTypes() const
{
return QStringList(QStringLiteral("elevationprofile"));
}
qreal ElevationProfileFloatItem::zValue() const
{
return 3.0;
}
QString ElevationProfileFloatItem::name() const
{
return tr("Elevation Profile");
}
QString ElevationProfileFloatItem::guiString() const
{
return tr("&Elevation Profile");
}
QString ElevationProfileFloatItem::nameId() const
{
return QStringLiteral("elevationprofile");
}
QString ElevationProfileFloatItem::version() const
{
return QStringLiteral("1.2"); // TODO: increase to 1.3 ?
}
QString ElevationProfileFloatItem::description() const
{
return tr( "A float item that shows the elevation profile of the current route." );
}
QString ElevationProfileFloatItem::copyrightYears() const
{
return QStringLiteral("2011, 2012, 2013");
}
QVector<PluginAuthor> ElevationProfileFloatItem::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Florian Eßer"),QStringLiteral("f.esser@rwth-aachen.de"))
<< PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"))
<< PluginAuthor(QStringLiteral("Roman Karlstetter"), QStringLiteral("roman.karlstetter@googlemail.com"));
}
QIcon ElevationProfileFloatItem::icon () const
{
return QIcon(QStringLiteral(":/icons/elevationprofile.png"));
}
void ElevationProfileFloatItem::initialize ()
{
connect( marbleModel()->elevationModel(), SIGNAL(updateAvailable()), &m_routeDataSource, SLOT(requestUpdate()) );
connect( marbleModel()->routingManager()->routingModel(), SIGNAL(currentRouteChanged()), &m_routeDataSource, SLOT(requestUpdate()) );
connect( this, SIGNAL(dataUpdated()), SLOT(forceRepaint()) );
switchDataSource(&m_routeDataSource);
m_fontHeight = QFontMetricsF( font() ).ascent() + 1;
m_leftGraphMargin = QFontMetricsF( font() ).width( "0000 m" ); /// TODO make this dynamic according to actual need
m_isInitialized = true;
}
bool ElevationProfileFloatItem::isInitialized () const
{
return m_isInitialized;
}
void ElevationProfileFloatItem::setProjection( const ViewportParams *viewport )
{
if ( !( viewport->width() == m_viewportWidth && m_isInitialized ) ) {
bool const highRes = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::HighResolution;
int const widthRatio = highRes ? 2 : 3;
setContentSize( QSizeF( viewport->width() / widthRatio,
m_eleGraphHeight + m_fontHeight * 2.5 ) );
m_eleGraphWidth = contentSize().width() - m_leftGraphMargin;
m_axisX.setLength( m_eleGraphWidth );
m_axisY.setLength( m_eleGraphHeight );
m_axisX.setTickCount( 3, m_eleGraphWidth / ( m_leftGraphMargin * 1.5 ) );
m_axisY.setTickCount( 2, m_eleGraphHeight / m_fontHeight );
m_viewportWidth = viewport->width();
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( !m_isInitialized && !smallScreen ) {
setPosition( QPointF( (viewport->width() - contentSize().width()) / 2 , 10.5 ) );
}
}
update();
AbstractFloatItem::setProjection( viewport );
}
void ElevationProfileFloatItem::paintContent( QPainter *painter )
{
// do not try to draw if not initialized
if(!isInitialized()) {
return;
}
painter->save();
painter->setRenderHint( QPainter::Antialiasing, true );
painter->setFont( font() );
if ( ! ( m_activeDataSource->isDataAvailable() && m_eleData.size() > 0 ) ) {
painter->setPen( QColor( Qt::black ) );
QString text = tr( "Create a route or load a track from file to view its elevation profile." );
painter->drawText( contentRect().toRect(), Qt::TextWordWrap | Qt::AlignCenter, text );
painter->restore();
return;
}
if ( m_zoomToViewport && ( m_lastVisiblePoint - m_firstVisiblePoint < 5 ) ) {
painter->setPen( QColor( Qt::black ) );
QString text = tr( "Not enough points in the current viewport.\nTry to disable 'Zoom to viewport'." );
painter->drawText( contentRect().toRect(), Qt::TextWordWrap | Qt::AlignCenter, text );
painter->restore();
return;
}
QString intervalStr;
int lastStringEnds;
// draw viewport bounds
if ( ! m_zoomToViewport && ( m_firstVisiblePoint > 0 || m_lastVisiblePoint < m_eleData.size() - 1 ) ) {
QColor color( Qt::black );
color.setAlpha( 64 );
QRect rect;
rect.setLeft( m_leftGraphMargin + m_eleData.value( m_firstVisiblePoint ).x() * m_eleGraphWidth / m_axisX.range() );
rect.setTop( 0 );
rect.setWidth( ( m_eleData.value( m_lastVisiblePoint ).x() - m_eleData.value( m_firstVisiblePoint ).x() ) * m_eleGraphWidth / m_axisX.range() );
rect.setHeight( m_eleGraphHeight );
painter->fillRect( rect, color );
}
// draw X and Y axis
painter->setPen( Oxygen::aluminumGray4 );
painter->drawLine( m_leftGraphMargin, m_eleGraphHeight, contentSize().width(), m_eleGraphHeight );
painter->drawLine( m_leftGraphMargin, m_eleGraphHeight, m_leftGraphMargin, 0 );
// draw Y grid and labels
painter->setPen( QColor( Qt::black ) );
QPen dashedPen( Qt::DashLine );
dashedPen.setColor( Oxygen::aluminumGray4 );
QRect labelRect( 0, 0, m_leftGraphMargin - 1, m_fontHeight + 2 );
lastStringEnds = m_eleGraphHeight + m_fontHeight;
// painter->drawText(m_leftGraphMargin + 1, m_fontHeight, QLatin1Char('[') + m_axisY.unit() + QLatin1Char(']'));
for ( const AxisTick &tick: m_axisY.ticks() ) {
const int posY = m_eleGraphHeight - tick.position;
painter->setPen( dashedPen );
painter->drawLine( m_leftGraphMargin, posY, contentSize().width(), posY );
labelRect.moveCenter( QPoint( labelRect.center().x(), posY ) );
if ( labelRect.top() < 0 ) {
// don't cut off uppermost label
labelRect.moveTop( 0 );
}
if ( labelRect.bottom() >= lastStringEnds ) {
// Don't print overlapping labels
continue;
}
lastStringEnds = labelRect.top();
painter->setPen( QColor( Qt::black ) );
intervalStr.setNum( tick.value * m_axisY.scale() );
painter->drawText( labelRect, Qt::AlignRight, intervalStr );
}
// draw X grid and labels
painter->setPen( QColor( Qt::black ) );
labelRect.moveTop( m_eleGraphHeight + 1 );
lastStringEnds = 0;
for ( const AxisTick &tick: m_axisX.ticks() ) {
const int posX = m_leftGraphMargin + tick.position;
painter->setPen( dashedPen );
painter->drawLine( posX, 0, posX, m_eleGraphHeight );
intervalStr.setNum( tick.value * m_axisX.scale() );
if ( tick.position == m_axisX.ticks().last().position ) {
intervalStr += QLatin1Char(' ') + m_axisX.unit();
}
labelRect.setWidth( QFontMetricsF( font() ).width( intervalStr ) * 1.5 );
labelRect.moveCenter( QPoint( posX, labelRect.center().y() ) );
if ( labelRect.right() > m_leftGraphMargin + m_eleGraphWidth ) {
// don't cut off rightmost label
labelRect.moveRight( m_leftGraphMargin + m_eleGraphWidth );
}
if ( labelRect.left() <= lastStringEnds ) {
// Don't print overlapping labels
continue;
}
lastStringEnds = labelRect.right();
painter->setPen( QColor( Qt::black ) );
painter->drawText( labelRect, Qt::AlignCenter, intervalStr );
}
// display elevation gain/loss data
painter->setPen( QColor( Qt::black ) );
intervalStr = tr( "Difference: %1 %2" )
.arg( QString::number( m_gain - m_loss, 'f', 0 ) )
.arg( m_axisY.unit() );
intervalStr += QString::fromUtf8( " (↗ %1 %3 ↘ %2 %3)" )
.arg( QString::number( m_gain, 'f', 0 ) )
.arg( QString::number( m_loss, 'f', 0 ) )
.arg( m_axisY.unit() );
painter->drawText( contentRect().toRect(), Qt::AlignBottom | Qt::AlignCenter, intervalStr );
// draw elevation profile
painter->setPen( QColor( Qt::black ) );
bool const highRes = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::HighResolution;
QPen pen = painter->pen();
pen.setWidth( highRes ? 2 : 1 );
painter->setPen( pen );
QLinearGradient fillGradient( 0, 0, 0, m_eleGraphHeight );
QColor startColor = Oxygen::forestGreen4;
QColor endColor = Oxygen::hotOrange4;
startColor.setAlpha( 200 );
endColor.setAlpha( 32 );
fillGradient.setColorAt( 0.0, startColor );
fillGradient.setColorAt( 1.0, endColor );
QBrush brush = QBrush( fillGradient );
painter->setBrush( brush );
QPoint oldPos;
oldPos.setX( m_leftGraphMargin );
oldPos.setY( ( m_axisY.minValue() - m_axisY.minValue() )
* m_eleGraphHeight / ( m_axisY.range() / m_shrinkFactorY ) );
oldPos.setY( m_eleGraphHeight - oldPos.y() );
QPainterPath path;
path.moveTo( oldPos.x(), m_eleGraphHeight );
path.lineTo( oldPos.x(), oldPos.y() );
const int start = m_zoomToViewport ? m_firstVisiblePoint : 0;
const int end = m_zoomToViewport ? m_lastVisiblePoint : m_eleData.size() - 1;
for ( int i = start; i <= end; ++i ) {
QPoint newPos;
if ( i == start ) {
// make sure the plot always starts at the y-axis
newPos.setX( 0 );
} else {
newPos.setX( ( m_eleData.value(i).x() - m_axisX.minValue() ) * m_eleGraphWidth / m_axisX.range() );
}
newPos.rx() += m_leftGraphMargin;
if ( newPos.x() != oldPos.x() || newPos.y() != oldPos.y() ) {
newPos.setY( ( m_eleData.value(i).y() - m_axisY.minValue() )
* m_eleGraphHeight / ( m_axisY.range() * m_shrinkFactorY ) );
newPos.setY( m_eleGraphHeight - newPos.y() );
path.lineTo( newPos.x(), newPos.y() );
oldPos = newPos;
}
}
path.lineTo( oldPos.x(), m_eleGraphHeight );
// fill
painter->setPen( QPen( Qt::NoPen ) );
painter->drawPath( path );
// contour
// "remove" the first and last path element first, they are only used to fill down to the bottom
painter->setBrush( QBrush( Qt::NoBrush ) );
path.setElementPositionAt( 0, path.elementAt( 1 ).x, path.elementAt( 1 ).y );
path.setElementPositionAt( path.elementCount()-1,
path.elementAt( path.elementCount()-2 ).x,
path.elementAt( path.elementCount()-2 ).y );
painter->setPen( pen );
painter->drawPath( path );
pen.setWidth( 1 );
painter->setPen( pen );
// draw interactive cursor
const GeoDataCoordinates currentPoint = m_markerPlacemark->coordinate();
if ( currentPoint.isValid() ) {
painter->setPen( QColor( Qt::white ) );
painter->drawLine( m_leftGraphMargin + m_cursorPositionX, 0,
m_leftGraphMargin + m_cursorPositionX, m_eleGraphHeight );
qreal xpos = m_axisX.minValue() + ( m_cursorPositionX / m_eleGraphWidth ) * m_axisX.range();
qreal ypos = m_eleGraphHeight - ( ( currentPoint.altitude() - m_axisY.minValue() ) / ( qMax<qreal>( 1.0, m_axisY.range() ) * m_shrinkFactorY ) ) * m_eleGraphHeight;
painter->drawLine( m_leftGraphMargin + m_cursorPositionX - 5, ypos,
m_leftGraphMargin + m_cursorPositionX + 5, ypos );
intervalStr.setNum( xpos * m_axisX.scale(), 'f', 2 );
intervalStr += QLatin1Char(' ') + m_axisX.unit();
int currentStringBegin = m_leftGraphMargin + m_cursorPositionX
- QFontMetricsF( font() ).width( intervalStr ) / 2;
painter->drawText( currentStringBegin, contentSize().height() - 1.5 * m_fontHeight, intervalStr );
intervalStr.setNum( currentPoint.altitude(), 'f', 1 );
intervalStr += QLatin1Char(' ') + m_axisY.unit();
if ( m_cursorPositionX + QFontMetricsF( font() ).width( intervalStr ) + m_leftGraphMargin
< m_eleGraphWidth ) {
currentStringBegin = ( m_leftGraphMargin + m_cursorPositionX + 5 + 2 );
} else {
currentStringBegin = m_leftGraphMargin + m_cursorPositionX - 5
- QFontMetricsF( font() ).width( intervalStr ) * 1.5;
}
// Make sure the text still fits into the window
while ( ypos < m_fontHeight ) {
ypos++;
}
painter->drawText( currentStringBegin, ypos + m_fontHeight / 2, intervalStr );
}
painter->restore();
}
QDialog *ElevationProfileFloatItem::configDialog() //FIXME TODO Make a config dialog? /// TODO what is this comment?
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::ElevationProfileConfigWidget;
ui_configWidget->setupUi( m_configDialog );
readSettings();
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()), SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()), SLOT(readSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()), this, SLOT(writeSettings()) );
}
return m_configDialog;
}
void ElevationProfileFloatItem::contextMenuEvent( QWidget *w, QContextMenuEvent *e )
{
Q_ASSERT( m_contextMenu );
m_contextMenu->getMenu()->exec( w->mapToGlobal( e->pos() ) );
}
bool ElevationProfileFloatItem::eventFilter( QObject *object, QEvent *e )
{
if ( !enabled() || !visible() ) {
return false;
}
MarbleWidget *widget = dynamic_cast<MarbleWidget*>( object );
if ( !widget ) {
return AbstractFloatItem::eventFilter(object,e);
}
if ( widget && !m_marbleWidget ) {
m_marbleWidget = widget;
connect( this, SIGNAL(dataUpdated()), this, SLOT(updateVisiblePoints()) );
connect( m_marbleWidget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this, SLOT(updateVisiblePoints()) );
connect( this, SIGNAL(settingsChanged(QString)), this, SLOT(updateVisiblePoints()) );
}
if ( e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove ) {
GeoDataTreeModel *const treeModel = const_cast<MarbleModel *>( marbleModel() )->treeModel();
QMouseEvent *event = static_cast<QMouseEvent*>( e );
QRectF plotRect = QRectF ( m_leftGraphMargin, 0, m_eleGraphWidth, contentSize().height() );
plotRect.translate( positivePosition() );
plotRect.translate( padding(), padding() );
// for antialiasing: increase size by 1 px to each side
plotRect.translate(-1, -1);
plotRect.setSize(plotRect.size() + QSize(2, 2) );
const bool cursorAboveFloatItem = plotRect.contains(event->pos());
if ( cursorAboveFloatItem ) {
const int start = m_zoomToViewport ? m_firstVisiblePoint : 0;
const int end = m_zoomToViewport ? m_lastVisiblePoint : m_eleData.size();
// Double click triggers recentering the map at the specified position
if ( e->type() == QEvent::MouseButtonDblClick ) {
const QPointF mousePosition = event->pos() - plotRect.topLeft();
const int xPos = mousePosition.x();
for ( int i = start; i < end; ++i) {
const int plotPos = ( m_eleData.value(i).x() - m_axisX.minValue() ) * m_eleGraphWidth / m_axisX.range();
if ( plotPos >= xPos ) {
widget->centerOn( m_points[i], true );
break;
}
}
return true;
}
if ( e->type() == QEvent::MouseMove && !(event->buttons() & Qt::LeftButton) ) {
// Cross hair cursor when moving above the float item
// and mark the position on the graph
widget->setCursor(QCursor(Qt::CrossCursor));
if ( m_cursorPositionX != event->pos().x() - plotRect.left() ) {
m_cursorPositionX = event->pos().x() - plotRect.left();
const qreal xpos = m_axisX.minValue() + ( m_cursorPositionX / m_eleGraphWidth ) * m_axisX.range();
GeoDataCoordinates currentPoint; // invalid coordinates
for ( int i = start; i < end; ++i) {
if ( m_eleData.value(i).x() >= xpos ) {
currentPoint = m_points[i];
currentPoint.setAltitude( m_eleData.value(i).y() );
break;
}
}
m_markerPlacemark->setCoordinate( currentPoint );
if ( m_documentIndex < 0 ) {
m_documentIndex = treeModel->addDocument( &m_markerDocument );
}
emit repaintNeeded();
}
return true;
}
}
else {
if ( m_documentIndex >= 0 ) {
m_markerPlacemark->setCoordinate( GeoDataCoordinates() ); // set to invalid
treeModel->removeDocument( &m_markerDocument );
m_documentIndex = -1;
emit repaintNeeded();
}
}
}
return AbstractFloatItem::eventFilter(object,e);
}
void ElevationProfileFloatItem::handleDataUpdate(const GeoDataLineString &points, const QVector<QPointF> &eleData)
{
m_eleData = eleData;
m_points = points;
calculateStatistics( m_eleData );
if ( m_eleData.length() >= 2 ) {
m_axisX.setRange( m_eleData.first().x(), m_eleData.last().x() );
m_axisY.setRange( qMin( m_minElevation, qreal( 0.0 ) ), m_maxElevation );
}
emit dataUpdated();
}
void ElevationProfileFloatItem::updateVisiblePoints()
{
if ( ! m_activeDataSource->isDataAvailable() || m_points.size() < 2 ) {
return;
}
// find the longest visible route section on screen
QList<QList<int> > routeSegments;
QList<int> currentRouteSegment;
for ( int i = 0; i < m_eleData.count(); i++ ) {
qreal lon = m_points[i].longitude(GeoDataCoordinates::Degree);
qreal lat = m_points[i].latitude (GeoDataCoordinates::Degree);
qreal x = 0;
qreal y = 0;
if ( m_marbleWidget->screenCoordinates(lon, lat, x, y) ) {
// on screen --> add point to list
currentRouteSegment.append(i);
} else {
// off screen --> start new list
if ( !currentRouteSegment.isEmpty() ) {
routeSegments.append( currentRouteSegment );
currentRouteSegment.clear();
}
}
}
routeSegments.append( currentRouteSegment ); // in case the route ends on screen
int maxLenght = 0;
for ( const QList<int> &currentRouteSegment: routeSegments ) {
if ( currentRouteSegment.size() > maxLenght ) {
maxLenght = currentRouteSegment.size() ;
m_firstVisiblePoint = currentRouteSegment.first();
m_lastVisiblePoint = currentRouteSegment.last();
}
}
if ( m_firstVisiblePoint < 0 ) {
m_firstVisiblePoint = 0;
}
if ( m_lastVisiblePoint < 0 || m_lastVisiblePoint >= m_eleData.count() ) {
m_lastVisiblePoint = m_eleData.count() - 1;
}
// include setting range to statistics and test for m_zoomToViewport in calculateStatistics();
if ( m_zoomToViewport ) {
calculateStatistics( m_eleData );
m_axisX.setRange( m_eleData.value( m_firstVisiblePoint ).x(),
m_eleData.value( m_lastVisiblePoint ).x() );
m_axisY.setRange( m_minElevation, m_maxElevation );
}
return;
}
void ElevationProfileFloatItem::calculateStatistics(const QVector<QPointF> &eleData)
{
// This basically calculates the important peaks of the moving average filtered elevation and
// calculates the elevation data based on this points.
// This is done by always placing the averaging window in a way that it starts or ends at an
// original data point. This should ensure that all minima/maxima of the moving average
// filtered data are covered.
const qreal averageDistance = 200.0;
m_maxElevation = 0.0;
m_minElevation = invalidElevationData;
m_gain = 0.0;
m_loss = 0.0;
const int start = m_zoomToViewport ? m_firstVisiblePoint : 0;
const int end = m_zoomToViewport ? m_lastVisiblePoint + 1 : eleData.size();
if( start < end ) {
qreal lastX = eleData.value( start ).x();
qreal lastY = eleData.value( start ).y();
qreal nextX = eleData.value( start + 1 ).x();
qreal nextY = eleData.value( start + 1 ).y();
m_maxElevation = qMax( lastY, nextY );
m_minElevation = qMin( lastY, nextY );
int averageStart = start;
if(lastX + averageDistance < eleData.value( start + 2 ).x())
++averageStart;
for ( int index = start + 2; index <= end; ++index ) {
qreal indexX = index < end ? eleData.value( index ).x() : eleData.value( end - 1 ).x() + averageDistance;
qreal indexY = eleData.value( qMin( index, end - 1 ) ).y();
m_maxElevation = qMax( m_maxElevation, indexY );
m_minElevation = qMin( m_minElevation, indexY );
// Low-pass filtering (moving average) of the elevation profile to calculate gain and loss values
// not always the best method, see for example
// http://www.ikg.uni-hannover.de/fileadmin/ikg/staff/thesis/finished/documents/StudArb_Schulze.pdf
// (German), chapter 4.2
// Average over the part ending with the previous point.
// Do complete recalculation to avoid accumulation of floating point artifacts.
nextY = 0;
qreal averageX = nextX - averageDistance;
for( int averageIndex = averageStart; averageIndex < index; ++averageIndex ) {
qreal nextAverageX = eleData.value( averageIndex ).x();
qreal ratio = ( nextAverageX - averageX ) / averageDistance; // Weighting of original data based on covered distance
nextY += eleData.value( qMax( averageIndex - 1, 0 ) ).y() * ratio;
averageX = nextAverageX;
}
while( averageStart < index ) {
// This handles the part ending with the previous point on the first iteration and the parts starting with averageStart afterwards
if ( nextY > lastY ) {
m_gain += nextY - lastY;
} else {
m_loss += lastY - nextY;
}
// Here we split the data into parts that average over the same data points
// As soon as the end of the averaging window reaches the current point we reached the end of the current part
lastX = nextX;
lastY = nextY;
nextX = eleData.value( averageStart ).x() + averageDistance;
if( nextX >= indexX ) {
break;
}
// We don't need to recalculate the average completely, just remove the reached point
qreal ratio = (nextX - lastX) / averageDistance;
nextY += ( eleData.value( index - 1 ).y() - eleData.value( qMax( averageStart - 1, 0 ) ).y() ) * ratio;
++averageStart;
}
// This is for the next part already, the end of the averaging window is at the following point
nextX = indexX;
}
// Also include the last point
nextY = eleData.value( end - 1 ).y();
if ( nextY > lastY ) {
m_gain += nextY - lastY;
} else {
m_loss += lastY - nextY;
}
}
}
void ElevationProfileFloatItem::forceRepaint()
{
// We add one pixel as antialiasing could result into painting on these pixels to.
QRectF floatItemRect = QRectF( positivePosition() - QPoint( 1, 1 ),
size() + QSize( 2, 2 ) );
update();
emit repaintNeeded( floatItemRect.toRect() );
}
void ElevationProfileFloatItem::readSettings()
{
if ( !m_configDialog )
return;
if ( m_zoomToViewport ) {
ui_configWidget->m_zoomToViewportCheckBox->setCheckState( Qt::Checked );
}
else {
ui_configWidget->m_zoomToViewportCheckBox->setCheckState( Qt::Unchecked );
}
}
void ElevationProfileFloatItem::writeSettings()
{
if ( ui_configWidget->m_zoomToViewportCheckBox->checkState() == Qt::Checked ) {
m_zoomToViewport = true;
} else {
m_zoomToViewport = false;
}
emit settingsChanged( nameId() );
}
void ElevationProfileFloatItem::toggleZoomToViewport()
{
m_zoomToViewport = ! m_zoomToViewport;
calculateStatistics( m_eleData );
if ( ! m_zoomToViewport ) {
m_axisX.setRange( m_eleData.first().x(), m_eleData.last().x() );
m_axisY.setRange( qMin( m_minElevation, qreal( 0.0 ) ), m_maxElevation );
}
readSettings();
emit settingsChanged( nameId() );
}
void ElevationProfileFloatItem::switchToRouteDataSource()
{
switchDataSource(&m_routeDataSource);
}
void ElevationProfileFloatItem::switchToTrackDataSource(int index)
{
m_trackDataSource.setSourceIndex(index);
switchDataSource(&m_trackDataSource);
}
void ElevationProfileFloatItem::switchDataSource(ElevationProfileDataSource* source)
{
if (m_activeDataSource) {
- disconnect(m_activeDataSource, SIGNAL(dataUpdated(GeoDataLineString,QVector<QPointF>)),0,0);
+ disconnect(m_activeDataSource, SIGNAL(dataUpdated(GeoDataLineString,QVector<QPointF>)),nullptr,nullptr);
}
m_activeDataSource = source;
connect(m_activeDataSource, SIGNAL(dataUpdated(GeoDataLineString,QVector<QPointF>)), this, SLOT(handleDataUpdate(GeoDataLineString,QVector<QPointF>)));
m_activeDataSource->requestUpdate();
}
}
#include "moc_ElevationProfileFloatItem.cpp"
diff --git a/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.h b/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.h
index 84b007531..6b570cd44 100644
--- a/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.h
+++ b/src/plugins/render/elevationprofilefloatitem/ElevationProfileFloatItem.h
@@ -1,157 +1,157 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011-2012 Florian Eßer <f.esser@rwth-aachen.de>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2013 Roman Karlstetter <roman.karlstetter@googlemail.com>
//
#ifndef ELEVATIONPROFILEFLOATITEM_H
#define ELEVATIONPROFILEFLOATITEM_H
#include "AbstractFloatItem.h"
#include "DialogConfigurationInterface.h"
#include "ElevationProfileDataSource.h"
#include "ElevationProfilePlotAxis.h"
#include "GeoDataDocument.h"
#include "GeoDataLineString.h"
namespace Ui
{
class ElevationProfileConfigWidget;
}
namespace Marble
{
class ElevationProfileContextMenu;
class ElevationProfileDataSource;
class ElevationProfileTrackDataSource;
class ElevationProfileRouteDataSource;
class GeoDataPlacemark;
class MarbleWidget;
/**
* @short The class that creates an interactive elvation profile.
*
*/
class ElevationProfileFloatItem : public AbstractFloatItem, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.ElevationProfileFloatItem")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN( ElevationProfileFloatItem )
public:
- explicit ElevationProfileFloatItem( const MarbleModel *marbleModel = 0 );
+ explicit ElevationProfileFloatItem( const MarbleModel *marbleModel = nullptr );
~ElevationProfileFloatItem() override;
QStringList backendTypes() const override;
qreal zValue() const override; // Overriding LayerInterface to paint on top of the route
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon() const override;
void initialize() override;
bool isInitialized() const override;
void setProjection( const ViewportParams *viewport ) override;
void paintContent( QPainter *painter ) override;
QDialog *configDialog() override;
protected:
bool eventFilter( QObject *object, QEvent *e ) override;
void contextMenuEvent( QWidget *w, QContextMenuEvent *e ) override;
private Q_SLOTS:
void handleDataUpdate(const GeoDataLineString &points, const QVector<QPointF> &eleData);
void updateVisiblePoints();
void forceRepaint();
void readSettings();
void writeSettings();
void toggleZoomToViewport();
void switchToRouteDataSource();
void switchToTrackDataSource(int index);
void switchDataSource(ElevationProfileDataSource *source);
Q_SIGNALS:
void dataUpdated();
private:
ElevationProfileDataSource* m_activeDataSource;
ElevationProfileRouteDataSource m_routeDataSource;
ElevationProfileTrackDataSource m_trackDataSource;
QDialog *m_configDialog;
Ui::ElevationProfileConfigWidget *ui_configWidget;
int m_leftGraphMargin;
int m_eleGraphWidth;
qreal m_viewportWidth;
qreal m_eleGraphHeight;
qreal m_shrinkFactorY;
int m_fontHeight;
ElevationProfilePlotAxis m_axisX;
ElevationProfilePlotAxis m_axisY;
GeoDataDocument m_markerDocument;
GeoDataPlacemark *const m_markerPlacemark;
int m_documentIndex;
qreal m_cursorPositionX;
bool m_isInitialized;
friend class ElevationProfileContextMenu;
ElevationProfileContextMenu* m_contextMenu;
MarbleWidget* m_marbleWidget;
int m_firstVisiblePoint;
int m_lastVisiblePoint;
bool m_zoomToViewport;
QVector<QPointF> m_eleData;
GeoDataLineString m_points;
qreal m_minElevation;
qreal m_maxElevation;
qreal m_gain;
qreal m_loss;
QVector<QPointF> calculateElevationData(const GeoDataLineString &lineString) const;
void calculateStatistics(const QVector<QPointF> &eleData);
};
}
#endif // ELEVATIONPROFILEFLOATITEM_H
diff --git a/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.cpp b/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.cpp
index 160449803..2a2778430 100644
--- a/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.cpp
+++ b/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.cpp
@@ -1,230 +1,230 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2011-2012 Florian Eßer <f.esser@rwth-aachen.de>
//
#include "ElevationProfileMarker.h"
#include "MarbleLocale.h"
#include "MarbleModel.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoPainter.h"
#include "GeoDataTreeModel.h"
#include "ViewportParams.h"
#include "MarbleGraphicsGridLayout.h"
#include <QRect>
#include <QIcon>
namespace Marble
{
ElevationProfileMarker::ElevationProfileMarker( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
- m_markerPlacemark( 0 ),
+ m_markerPlacemark( nullptr ),
m_markerItem(),
m_markerIcon( &m_markerItem ),
m_markerText( &m_markerItem )
{
if ( !marbleModel ) {
return;
}
setVisible( false );
m_markerItem.setCacheMode( MarbleGraphicsItem::ItemCoordinateCache );
connect( const_cast<MarbleModel *>( marbleModel )->treeModel(), SIGNAL(added(GeoDataObject*)),
this, SLOT(onGeoObjectAdded(GeoDataObject*)) );
connect( const_cast<MarbleModel *>( marbleModel )->treeModel(), SIGNAL(removed(GeoDataObject*)),
this, SLOT(onGeoObjectRemoved(GeoDataObject*)) );
}
ElevationProfileMarker::~ElevationProfileMarker()
{
}
QStringList ElevationProfileMarker::backendTypes() const
{
return QStringList(QStringLiteral("elevationprofilemarker"));
}
QString ElevationProfileMarker::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList ElevationProfileMarker::renderPosition() const
{
return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE"));
}
qreal ElevationProfileMarker::zValue() const
{
return 3.0;
}
QString ElevationProfileMarker::name() const
{
return tr( "Elevation Profile Marker" );
}
QString ElevationProfileMarker::guiString() const
{
return tr( "&Elevation Profile Marker" );
}
QString ElevationProfileMarker::nameId() const
{
return QStringLiteral("elevationprofilemarker");
}
QString ElevationProfileMarker::version() const
{
return QStringLiteral("1.0");
}
QString ElevationProfileMarker::description() const
{
return tr( "Marks the current elevation of the elevation profile on the map." );
}
QString ElevationProfileMarker::copyrightYears() const
{
return QStringLiteral("2011, 2012");
}
QVector<PluginAuthor> ElevationProfileMarker::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"))
<< PluginAuthor(QStringLiteral("Florian Eßer"), QStringLiteral("f.esser@rwth-aachen.de"));
}
QIcon ElevationProfileMarker::icon() const
{
return QIcon(QStringLiteral(":/icons/elevationprofile.png"));
}
void ElevationProfileMarker::initialize()
{
m_markerIcon.setImage(QImage(QStringLiteral(":/flag-red-mirrored.png")));
MarbleGraphicsGridLayout *topLayout = new MarbleGraphicsGridLayout( 1, 2 );
m_markerItem.setLayout( topLayout );
topLayout->addItem( &m_markerIcon, 0, 0 );
m_markerText.setFrame( LabelGraphicsItem::RoundedRectFrame );
m_markerText.setPadding( 1 );
topLayout->addItem( &m_markerText, 0, 1 );
}
bool ElevationProfileMarker::isInitialized() const
{
return !m_markerIcon.image().isNull();
}
bool ElevationProfileMarker::render( GeoPainter* painter, ViewportParams* viewport, const QString& renderPos, GeoSceneLayer* layer )
{
Q_UNUSED( renderPos )
Q_UNUSED( layer )
if ( !m_markerPlacemark )
return true;
if ( m_currentPosition != m_markerPlacemark->coordinate() ) {
m_currentPosition = m_markerPlacemark->coordinate();
if ( m_currentPosition.isValid() ) {
QString unitString = tr( "m" );
int displayScale = 1.0;
const MarbleLocale::MeasurementSystem measurementSystem =
MarbleGlobal::getInstance()->locale()->measurementSystem();
switch ( measurementSystem ) {
case MarbleLocale::MetricSystem:
/* nothing to do */
break;
case MarbleLocale::ImperialSystem:
unitString = tr( "ft" );
displayScale = M2FT;
break;
case MarbleLocale::NauticalSystem:
unitString = tr("ft");
displayScale = 0.001 * KM2NM * NM2FT;
}
QString intervalStr;
intervalStr.setNum( m_currentPosition.altitude() * displayScale, 'f', 1 );
intervalStr += QLatin1Char(' ') + unitString;
m_markerText.setText( intervalStr );
}
}
if ( m_currentPosition.isValid() ) {
qreal x;
qreal y;
qreal lon;
qreal lat;
// move the icon by some pixels, so that the pole of the flag sits at the exact point
int dx = +3 + m_markerItem.size().width() / 2 - m_markerIcon.contentRect().right();//-4;
int dy = -6;
viewport->screenCoordinates( m_currentPosition.longitude( GeoDataCoordinates::Radian ),
m_currentPosition.latitude ( GeoDataCoordinates::Radian ),
x, y );
viewport->geoCoordinates( x + dx, y + dy, lon, lat, GeoDataCoordinates::Radian );
m_markerItem.setCoordinate( GeoDataCoordinates( lon, lat, m_currentPosition.altitude(),
GeoDataCoordinates::Radian ) );
painter->save();
m_markerItem.paintEvent( painter, viewport );
painter->restore();
}
return true;
}
void ElevationProfileMarker::onGeoObjectAdded( GeoDataObject *object )
{
if ( m_markerPlacemark )
return;
GeoDataDocument *document = dynamic_cast<GeoDataDocument *>( object );
if ( !document )
return;
if (document->name() != QLatin1String("Elevation Profile"))
return;
if (document->isEmpty())
return;
m_markerPlacemark = dynamic_cast<GeoDataPlacemark *>( document->child( 0 ) );
- setVisible( m_markerPlacemark != 0 );
+ setVisible( m_markerPlacemark != nullptr );
}
void ElevationProfileMarker::onGeoObjectRemoved( GeoDataObject *object )
{
GeoDataDocument *const document = dynamic_cast<GeoDataDocument *>( object );
if ( !document )
return;
if (document->name() != QLatin1String("Elevation Profile"))
return;
- m_markerPlacemark = 0;
+ m_markerPlacemark = nullptr;
emit repaintNeeded();
}
}
#include "moc_ElevationProfileMarker.cpp"
diff --git a/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.h b/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.h
index 22cb5d1cc..d8917af10 100644
--- a/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.h
+++ b/src/plugins/render/elevationprofilemarker/ElevationProfileMarker.h
@@ -1,87 +1,87 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef ELEVATIONPROFILEMARKER_H
#define ELEVATIONPROFILEMARKER_H
#include "RenderPlugin.h"
#include "BillboardGraphicsItem.h"
#include "GeoDataCoordinates.h"
#include "LabelGraphicsItem.h"
namespace Marble
{
class GeoDataObject;
class GeoDataPlacemark;
class ElevationProfileMarker : public RenderPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.ElevationProfileMarker")
Q_INTERFACES( Marble::RenderPluginInterface )
MARBLE_PLUGIN( ElevationProfileMarker )
public:
- explicit ElevationProfileMarker( const MarbleModel *marbleModel = 0 );
+ explicit ElevationProfileMarker( const MarbleModel *marbleModel = nullptr );
~ElevationProfileMarker() override;
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
qreal zValue() const override; // Overriding LayerInterface to paint on top of the route
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon() const override;
void initialize() override;
bool isInitialized() const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
- const QString &renderPos, GeoSceneLayer *layer = 0 ) override;
+ const QString &renderPos, GeoSceneLayer *layer = nullptr ) override;
private Q_SLOTS:
void onGeoObjectAdded( GeoDataObject *object );
void onGeoObjectRemoved( GeoDataObject *object );
private:
GeoDataPlacemark *m_markerPlacemark;
GeoDataCoordinates m_currentPosition;
BillboardGraphicsItem m_markerItem;
LabelGraphicsItem m_markerIcon;
LabelGraphicsItem m_markerText;
};
}
#endif // ELEVATIONPROFILEMARKER_H
diff --git a/src/plugins/render/foursquare/FoursquareItem.h b/src/plugins/render/foursquare/FoursquareItem.h
index c2c6028a0..9a9d3e05e 100644
--- a/src/plugins/render/foursquare/FoursquareItem.h
+++ b/src/plugins/render/foursquare/FoursquareItem.h
@@ -1,114 +1,114 @@
#ifndef FOURSQUAREITEM_H
#define FOURSQUAREITEM_H
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Utku Aydın <utkuaydin34@gmail.com>
//
#include "AbstractDataPluginItem.h"
class QFont;
namespace Marble
{
class FoursquareItem : public AbstractDataPluginItem
{
Q_OBJECT
Q_PROPERTY( QString name READ name NOTIFY nameChanged )
Q_PROPERTY( QString category READ category NOTIFY categoryChanged )
Q_PROPERTY( QString address READ address NOTIFY addressChanged )
Q_PROPERTY( QString city READ city NOTIFY cityChanged )
Q_PROPERTY( QString country READ country NOTIFY countryChanged )
Q_PROPERTY( QString usersCount READ usersCount NOTIFY usersCountChanged )
Q_PROPERTY( QString categoryIconUrl READ categoryIconUrl NOTIFY categoryIconUrlChanged )
Q_PROPERTY( QString categoryLargeIconUrl READ categoryLargeIconUrl NOTIFY categoryLargeIconUrlChanged )
public:
- explicit FoursquareItem( QObject *parent=0 );
+ explicit FoursquareItem( QObject *parent=nullptr );
~FoursquareItem() override;
bool initialized() const override;
void paint( QPainter* painter ) override;
bool operator<( const AbstractDataPluginItem *other ) const override;
QString name() const;
void setName( const QString& name );
QString category() const;
void setCategory( const QString& category );
QString address() const;
void setAddress( const QString& address );
QString city() const;
void setCity( const QString& city );
QString country() const;
void setCountry( const QString& country );
int usersCount() const;
void setUsersCount( const int count );
QString categoryIconUrl() const;
void setCategoryIconUrl( const QString& url );
QString categoryLargeIconUrl() const;
void setCategoryLargeIconUrl( const QString& url );
private:
QString m_name;
QString m_category;
QString m_address;
QString m_city;
QString m_country;
int m_usersCount;
QString m_categoryIconUrl;
QString m_categoryLargeIconUrl;
static QFont s_font;
Q_SIGNALS:
void nameChanged();
void categoryChanged();
void addressChanged();
void cityChanged();
void countryChanged();
void usersCountChanged();
void categoryIconUrlChanged();
void categoryLargeIconUrlChanged();
};
}
#endif // FOURSQUAREITEM_H
diff --git a/src/plugins/render/foursquare/FoursquareModel.h b/src/plugins/render/foursquare/FoursquareModel.h
index 285d87a9b..7b684f73f 100644
--- a/src/plugins/render/foursquare/FoursquareModel.h
+++ b/src/plugins/render/foursquare/FoursquareModel.h
@@ -1,43 +1,43 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Utku Aydın <utkuaydin34@gmail.com>
//
#ifndef FOURSQUAREMODEL_H
#define FOURSQUAREMODEL_H
#include <AbstractDataPluginModel.h>
namespace Marble
{
class FoursquareModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- explicit FoursquareModel( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit FoursquareModel( const MarbleModel *marbleModel, QObject *parent = nullptr );
~FoursquareModel() override;
protected:
/**
* Generates the download url for the description file from the web service depending on
* the @p box surrounding the view and the @p number of files to show.
**/
void getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number = 10 ) override;
/**
* Parses the @p file which getAdditionalItems downloads and
* prepares the data for usage.
**/
void parseFile( const QByteArray& file ) override;
};
}
#endif // FOURSQUAREMODEL_H
diff --git a/src/plugins/render/foursquare/FoursquarePlugin.cpp b/src/plugins/render/foursquare/FoursquarePlugin.cpp
index 981691bf0..ca2a09353 100644
--- a/src/plugins/render/foursquare/FoursquarePlugin.cpp
+++ b/src/plugins/render/foursquare/FoursquarePlugin.cpp
@@ -1,103 +1,103 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Utku Aydın <utkuaydin34@gmail.com>
//
#include "FoursquarePlugin.h"
#include "FoursquareModel.h"
#include <QSettings>
#include <QIcon>
namespace Marble {
FoursquarePlugin::FoursquarePlugin()
- : AbstractDataPlugin( 0 )
+ : AbstractDataPlugin( nullptr )
{
}
FoursquarePlugin::FoursquarePlugin(const MarbleModel* marbleModel)
: AbstractDataPlugin(marbleModel)
{
setEnabled( true ); // Plugin is enabled by default
setVisible( false ); // Plugin is invisible by default
}
void FoursquarePlugin::initialize()
{
FoursquareModel *model = new FoursquareModel( marbleModel(), this );
setModel( model );
setNumberOfItems( 20 ); // Do we hardcode that?
}
QString FoursquarePlugin::name() const
{
return tr( "Places" );
}
QString FoursquarePlugin::guiString() const
{
return tr( "&Places" ); // TODO: Check if that ampersand conflicts with another
}
QString FoursquarePlugin::nameId() const
{
return QStringLiteral("foursquare");
}
QString FoursquarePlugin::version() const
{
return QStringLiteral("1.0");
}
QString FoursquarePlugin::description() const
{
return tr( "Displays trending Foursquare places" );
}
QString FoursquarePlugin::copyrightYears() const
{
return QStringLiteral("2012");
}
QVector<PluginAuthor> FoursquarePlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
<< PluginAuthor(QStringLiteral("Utku Aydın"), QStringLiteral("utkuaydin34@gmail.com"));
}
QIcon FoursquarePlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/places.png"));
}
bool FoursquarePlugin::isAuthenticated()
{
QSettings settings;
return !settings.value(QStringLiteral("access_token")).isNull();
}
bool FoursquarePlugin::storeAccessToken(const QString& tokenUrl)
{
QString expected = "http://edu.kde.org/marble/dummy#access_token=";
if( tokenUrl.startsWith( expected ) ) {
QSettings settings;
QString url = tokenUrl;
settings.setValue(QStringLiteral("access_token"), url.remove(expected));
return true;
} else {
return false;
}
}
}
#include "moc_FoursquarePlugin.cpp"
diff --git a/src/plugins/render/gpsinfo/GpsInfo.cpp b/src/plugins/render/gpsinfo/GpsInfo.cpp
index 288f1bf0f..ba9e7714a 100644
--- a/src/plugins/render/gpsinfo/GpsInfo.cpp
+++ b/src/plugins/render/gpsinfo/GpsInfo.cpp
@@ -1,178 +1,178 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
//
#include "GpsInfo.h"
#include "ui_GpsInfoPlugin.h"
#include <QIcon>
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "MarbleModel.h"
#include "PositionTracking.h"
#include "WidgetGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "ViewportParams.h"
#include "GeoDataAccuracy.h"
namespace Marble
{
GpsInfo::GpsInfo()
- : AbstractFloatItem( 0 ),
- m_locale( 0 ),
- m_widgetItem( 0 )
+ : AbstractFloatItem( nullptr ),
+ m_locale( nullptr ),
+ m_widgetItem( nullptr )
{
}
GpsInfo::GpsInfo( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( 10.5, 110 ), QSizeF( 135.0, 80.0 ) ),
- m_locale( 0 ),
- m_widgetItem( 0 )
+ m_locale( nullptr ),
+ m_widgetItem( nullptr )
{
setVisible( false );
}
GpsInfo::~GpsInfo()
{
}
QStringList GpsInfo::backendTypes() const
{
return QStringList(QStringLiteral("GpsInfo"));
}
QString GpsInfo::name() const
{
return tr("GpsInfo");
}
QString GpsInfo::guiString() const
{
return tr("&GpsInfo");
}
QString GpsInfo::nameId() const
{
return QStringLiteral("GpsInfo");
}
QString GpsInfo::version() const
{
return QStringLiteral("1.0");
}
QString GpsInfo::description() const
{
return tr("This is a float item that provides Gps Information.");
}
QString GpsInfo::copyrightYears() const
{
return QStringLiteral("2011");
}
QVector<PluginAuthor> GpsInfo::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Thibaut Gridel"), QStringLiteral("tgridel@free.fr"));
}
QIcon GpsInfo::icon () const
{
return QIcon(QStringLiteral(":/icons/gps.png"));
}
void GpsInfo::initialize ()
{
if ( !m_widgetItem )
{
QWidget *widget = new QWidget;
m_widget.setupUi( widget );
m_widgetItem = new WidgetGraphicsItem( this );
m_widgetItem->setWidget( widget );
MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
layout->addItem( m_widgetItem, 0, 0 );
setLayout( layout );
setPadding( 0 );
m_locale = MarbleGlobal::getInstance()->locale();
connect( marbleModel()->positionTracking(), SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
this, SLOT(updateLocation(GeoDataCoordinates,qreal)) );
}
}
bool GpsInfo::isInitialized () const
{
return m_widgetItem;
}
void GpsInfo::updateLocation( const GeoDataCoordinates& coordinates, qreal)
{
PositionTracking *tracking = marbleModel()->positionTracking();
qreal speed = tracking->speed();
qreal direction = tracking->direction();
qreal altitude = coordinates.altitude();
qreal precision = tracking->accuracy().horizontal;
QString speedString;
QString distanceString;
switch ( m_locale->measurementSystem() ) {
case MarbleLocale::ImperialSystem:
//miles per hour
speedString = tr("mph");
speed *= HOUR2SEC * METER2KM * KM2MI;
distanceString = tr("ft");
altitude *= M2FT;
precision *= M2FT;
break;
case MarbleLocale::MetricSystem:
//kilometers per hour
speedString = tr("km/h");
speed *= HOUR2SEC * METER2KM;
distanceString = tr("m");
break;
case MarbleLocale::NauticalSystem:
// nm per hour (knots)
speedString = tr("kt");
speed *= HOUR2SEC * METER2KM * KM2NM;
distanceString = tr("nm");
break;
}
m_widget.SpeedValue->setText( QString( " %1 %2" )
.arg( QLocale().toString(speed, 'f', 1 ) )
.arg( speedString ) );
m_widget.AltitudeValue->setText( QString( " %1 %2" )
.arg( QLocale().toString(altitude, 'f', 1 ) )
.arg( distanceString ) );
m_widget.DirectionValue->setText( QString( " %1 %2" )
.arg( QLocale().toString(direction, 'f', 1 ) )
.arg( "d" ) );
m_widget.PrecisionValue->setText( QString( " %1 %2" )
.arg( QLocale().toString(precision, 'f', 1 ) )
.arg( distanceString ) );
int const minimumWidth = m_widgetItem->widget()->sizeHint().width();
if ( size().width() < minimumWidth ) {
m_widgetItem->setSize( QSizeF( minimumWidth, size().height() ) );
}
update();
emit repaintNeeded();
}
}
#include "moc_GpsInfo.cpp"
diff --git a/src/plugins/render/graticule/GraticulePlugin.cpp b/src/plugins/render/graticule/GraticulePlugin.cpp
index 60ea27856..923814c79 100644
--- a/src/plugins/render/graticule/GraticulePlugin.cpp
+++ b/src/plugins/render/graticule/GraticulePlugin.cpp
@@ -1,793 +1,793 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Torsten Rahn <tackat@kde.org>
//
#include "GraticulePlugin.h"
#include "ui_GraticuleConfigWidget.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "GeoPainter.h"
#include "GeoDataLineString.h"
#include "Planet.h"
#include "MarbleModel.h"
#include "PluginAboutDialog.h"
#include "ViewportParams.h"
#include "GeoDataLatLonAltBox.h"
// Qt
#include <QPushButton>
#include <QRect>
#include <QColor>
#include <QBrush>
#include <QColorDialog>
#include <QDebug>
namespace Marble
{
GraticulePlugin::GraticulePlugin()
- : RenderPlugin( 0 ),
+ : RenderPlugin( nullptr ),
m_showPrimaryLabels( true ),
m_showSecondaryLabels( true ),
m_isInitialized( false ),
- ui_configWidget( 0 ),
- m_configDialog( 0 )
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr )
{
}
GraticulePlugin::GraticulePlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
m_equatorCirclePen( Qt::yellow ),
m_tropicsCirclePen( Qt::yellow ),
m_gridCirclePen( Qt::white ),
m_showPrimaryLabels( true ),
m_showSecondaryLabels( true ),
m_isInitialized( false ),
- ui_configWidget( 0 ),
- m_configDialog( 0 )
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr )
{
}
QStringList GraticulePlugin::backendTypes() const
{
return QStringList(QStringLiteral("graticule"));
}
QString GraticulePlugin::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList GraticulePlugin::renderPosition() const
{
return QStringList(QStringLiteral("GRATICULE"));
}
QString GraticulePlugin::name() const
{
return tr( "Coordinate Grid" );
}
QString GraticulePlugin::guiString() const
{
return tr( "Coordinate &Grid" );
}
QString GraticulePlugin::nameId() const
{
return QStringLiteral("coordinate-grid");
}
QString GraticulePlugin::version() const
{
return QStringLiteral("1.0");
}
QString GraticulePlugin::description() const
{
return tr( "A plugin that shows a coordinate grid." );
}
QString GraticulePlugin::copyrightYears() const
{
return QStringLiteral("2009");
}
QVector<PluginAuthor> GraticulePlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"));
}
QIcon GraticulePlugin::icon () const
{
return QIcon(QStringLiteral(":/icons/coordinate.png"));
}
void GraticulePlugin::initialize ()
{
// Initialize range maps that map the zoom to the number of coordinate grid lines.
initLineMaps( GeoDataCoordinates::defaultNotation() );
m_isInitialized = true;
}
bool GraticulePlugin::isInitialized () const
{
return m_isInitialized;
}
QDialog *GraticulePlugin::configDialog()
{
if ( !m_configDialog ) {
m_configDialog = new QDialog();
ui_configWidget = new Ui::GraticuleConfigWidget;
ui_configWidget->setupUi( m_configDialog );
connect( ui_configWidget->gridPushButton, SIGNAL(clicked()), this,
SLOT(gridGetColor()) );
connect( ui_configWidget->tropicsPushButton, SIGNAL(clicked()), this,
SLOT(tropicsGetColor()) );
connect( ui_configWidget->equatorPushButton, SIGNAL(clicked()), this,
SLOT(equatorGetColor()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()), this,
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox->button( QDialogButtonBox::Reset ), SIGNAL(clicked()),
SLOT(restoreDefaultSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
this, SLOT(writeSettings()) );
}
readSettings();
return m_configDialog;
}
QHash<QString,QVariant> GraticulePlugin::settings() const
{
QHash<QString, QVariant> settings = RenderPlugin::settings();
settings.insert(QStringLiteral("gridColor"), m_gridCirclePen.color().name());
settings.insert(QStringLiteral("tropicsColor"), m_tropicsCirclePen.color().name());
settings.insert(QStringLiteral("equatorColor"), m_equatorCirclePen.color().name());
settings.insert(QStringLiteral("primaryLabels"), m_showPrimaryLabels);
settings.insert(QStringLiteral("secondaryLabels"), m_showSecondaryLabels);
return settings;
}
void GraticulePlugin::setSettings( const QHash<QString,QVariant> &settings )
{
RenderPlugin::setSettings( settings );
const QColor gridColor = settings.value(QStringLiteral("gridColor"), QColor(Qt::white)).value<QColor>();
const QColor tropicsColor = settings.value(QStringLiteral("tropicsColor"), QColor(Qt::yellow)).value<QColor>();
const QColor equatorColor = settings.value(QStringLiteral("equatorColor"), QColor(Qt::yellow)).value<QColor>();
bool primaryLabels = settings.value(QStringLiteral("primaryLabels"), true).toBool();
bool secondaryLabels = settings.value(QStringLiteral("secondaryLabels"), true).toBool();
m_gridCirclePen.setColor( gridColor );
m_tropicsCirclePen.setColor( tropicsColor );
m_equatorCirclePen.setColor( equatorColor );
m_showPrimaryLabels = primaryLabels;
m_showSecondaryLabels = secondaryLabels;
readSettings();
}
void GraticulePlugin::readSettings()
{
if ( !m_configDialog )
return;
QPalette gridPalette;
gridPalette.setColor( QPalette::Button, m_gridCirclePen.color() );
ui_configWidget->gridPushButton->setPalette( gridPalette );
QPalette tropicsPalette;
tropicsPalette.setColor( QPalette::Button, m_tropicsCirclePen.color() );
ui_configWidget->tropicsPushButton->setPalette( tropicsPalette );
QPalette equatorPalette;
equatorPalette.setColor( QPalette::Button, m_equatorCirclePen.color() );
ui_configWidget->equatorPushButton->setPalette( equatorPalette );
ui_configWidget->primaryCheckBox->setChecked( m_showPrimaryLabels );
ui_configWidget->secondaryCheckBox->setChecked( m_showSecondaryLabels );
}
void GraticulePlugin::gridGetColor()
{
- const QColor c = QColorDialog::getColor( m_gridCirclePen.color(), 0, tr("Please choose the color for the coordinate grid.") );
+ const QColor c = QColorDialog::getColor( m_gridCirclePen.color(), nullptr, tr("Please choose the color for the coordinate grid.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->gridPushButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->gridPushButton->setPalette( palette );
}
}
void GraticulePlugin::tropicsGetColor()
{
- const QColor c = QColorDialog::getColor( m_tropicsCirclePen.color(), 0, tr("Please choose the color for the tropic circles.") );
+ const QColor c = QColorDialog::getColor( m_tropicsCirclePen.color(), nullptr, tr("Please choose the color for the tropic circles.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->tropicsPushButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->tropicsPushButton->setPalette( palette );
}
}
void GraticulePlugin::equatorGetColor()
{
- const QColor c = QColorDialog::getColor( m_equatorCirclePen.color(), 0, tr("Please choose the color for the equator.") );
+ const QColor c = QColorDialog::getColor( m_equatorCirclePen.color(), nullptr, tr("Please choose the color for the equator.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->equatorPushButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->equatorPushButton->setPalette( palette );
}
}
void GraticulePlugin::writeSettings()
{
m_equatorCirclePen.setColor( ui_configWidget->equatorPushButton->palette().color( QPalette::Button ) );
m_tropicsCirclePen.setColor( ui_configWidget->tropicsPushButton->palette().color( QPalette::Button ) );
m_gridCirclePen.setColor( ui_configWidget->gridPushButton->palette().color( QPalette::Button) );
m_showPrimaryLabels = ui_configWidget->primaryCheckBox->isChecked();
m_showSecondaryLabels = ui_configWidget->secondaryCheckBox->isChecked();
emit settingsChanged( nameId() );
}
bool GraticulePlugin::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos,
GeoSceneLayer * layer )
{
Q_UNUSED( layer )
Q_UNUSED( renderPos )
if ( m_currentNotation != GeoDataCoordinates::defaultNotation() ) {
initLineMaps( GeoDataCoordinates::defaultNotation() );
}
// Setting the label font for the coordinate lines.
#ifdef Q_OS_MACX
int defaultFontSize = 10;
#else
int defaultFontSize = 8;
#endif
QFont gridFont("Sans Serif");
gridFont.setPointSize( defaultFontSize );
gridFont.setBold( true );
painter->save();
painter->setFont( gridFont );
renderGrid( painter, viewport, m_equatorCirclePen, m_tropicsCirclePen, m_gridCirclePen );
painter->restore();
return true;
}
qreal GraticulePlugin::zValue() const
{
return 1.0;
}
void GraticulePlugin::renderGrid( GeoPainter *painter, ViewportParams *viewport,
const QPen& equatorCirclePen,
const QPen& tropicsCirclePen,
const QPen& gridCirclePen )
{
GeoDataLatLonAltBox viewLatLonAltBox = viewport->viewLatLonAltBox();
painter->setPen( equatorCirclePen );
LabelPositionFlags mainPosition(NoLabel);
if ( m_showPrimaryLabels ) {
mainPosition = LineCenter;
}
// Render the equator
renderLatitudeLine( painter, 0.0, viewLatLonAltBox, tr( "Equator" ), mainPosition );
// Render the Prime Meridian and Antimeridian
GeoDataCoordinates::Notation notation = GeoDataCoordinates::defaultNotation();
if (marbleModel()->planet()->id() != QLatin1String("sky") && notation != GeoDataCoordinates::Astro) {
renderLongitudeLine( painter, 0.0, viewLatLonAltBox, 0.0, 0.0, tr( "Prime Meridian" ), mainPosition );
renderLongitudeLine( painter, 180.0, viewLatLonAltBox, 0.0, 0.0, tr( "Antimeridian" ), mainPosition );
}
painter->setPen( gridCirclePen );
// painter->setPen( QPen( QBrush( Qt::white ), 0.75 ) );
// Render UTM grid zones
if ( m_currentNotation == GeoDataCoordinates::UTM ) {
renderLatitudeLine( painter, 84.0, viewLatLonAltBox );
renderLongitudeLines( painter, viewLatLonAltBox,
6.0, 0.0,
18.0, 154.0, LineEnd | IgnoreXMargin );
renderLongitudeLines( painter, viewLatLonAltBox,
6.0, 0.0,
34.0, 10.0, LineStart | IgnoreXMargin );
// Paint longitudes with exceptions
renderLongitudeLines( painter, viewLatLonAltBox,
6.0, 0.0,
6.0, 162.0, LineEnd | IgnoreXMargin );
renderLongitudeLines( painter, viewLatLonAltBox,
6.0, 0.0,
26.0, 146.0, LineEnd | IgnoreXMargin );
renderLatitudeLines( painter, viewLatLonAltBox, 8.0, 0.0 /*,
LineStart | IgnoreYMargin */ );
return;
}
// Render the normal grid
// calculate the angular distance between coordinate lines of the normal grid
qreal normalDegreeStep = 360.0 / m_normalLineMap.lowerBound(viewport->radius()).value();
LabelPositionFlags labelXPosition(NoLabel), labelYPosition(NoLabel);
if ( m_showSecondaryLabels ) {
labelXPosition = LineStart | IgnoreXMargin;
labelYPosition = LineStart | IgnoreYMargin;
}
qreal boldDegreeStep = 360.0 / m_boldLineMap.lowerBound(viewport->radius()).value();
renderLongitudeLines( painter, viewLatLonAltBox,
normalDegreeStep, boldDegreeStep,
normalDegreeStep, normalDegreeStep,
labelXPosition );
renderLatitudeLines( painter, viewLatLonAltBox, normalDegreeStep, boldDegreeStep,
labelYPosition );
// Render some non-cut off longitude lines ..
renderLongitudeLine( painter, +90.0, viewLatLonAltBox );
renderLongitudeLine( painter, -90.0, viewLatLonAltBox );
// Render the bold grid
if ( painter->mapQuality() == HighQuality
|| painter->mapQuality() == PrintQuality ) {
QPen boldPen = gridCirclePen;
boldPen.setWidthF( 2.0 );
painter->setPen( boldPen );
}
// calculate the angular distance between coordinate lines of the bold grid
renderLongitudeLines( painter, viewLatLonAltBox,
boldDegreeStep, 0.0,
normalDegreeStep, normalDegreeStep,
NoLabel
);
renderLatitudeLines( painter, viewLatLonAltBox, boldDegreeStep, 0.0,
NoLabel );
QPen tropicsPen = tropicsCirclePen;
if ( painter->mapQuality() != OutlineQuality
&& painter->mapQuality() != LowQuality ) {
tropicsPen.setStyle( Qt::DotLine );
}
painter->setPen( tropicsPen );
// Determine the planet's axial tilt
qreal axialTilt = RAD2DEG * marbleModel()->planet()->epsilon();
if ( axialTilt > 0 ) {
// Render the tropics
renderLatitudeLine( painter, +axialTilt, viewLatLonAltBox, tr( "Tropic of Cancer" ), mainPosition );
renderLatitudeLine( painter, -axialTilt, viewLatLonAltBox, tr( "Tropic of Capricorn" ), mainPosition );
// Render the arctics
renderLatitudeLine( painter, +90.0 - axialTilt, viewLatLonAltBox, tr( "Arctic Circle" ), mainPosition );
renderLatitudeLine( painter, -90.0 + axialTilt, viewLatLonAltBox, tr( "Antarctic Circle" ), mainPosition );
}
}
void GraticulePlugin::renderLatitudeLine( GeoPainter *painter, qreal latitude,
const GeoDataLatLonAltBox& viewLatLonAltBox,
const QString& lineLabel,
LabelPositionFlags labelPositionFlags )
{
qreal fromSouthLat = viewLatLonAltBox.south( GeoDataCoordinates::Degree );
qreal toNorthLat = viewLatLonAltBox.north( GeoDataCoordinates::Degree );
// Coordinate line is not displayed inside the viewport
if ( latitude < fromSouthLat || toNorthLat < latitude ) {
// mDebug() << "Lat: Out of View";
return;
}
GeoDataLineString line( Tessellate | RespectLatitudeCircle ) ;
qreal fromWestLon = viewLatLonAltBox.west( GeoDataCoordinates::Degree );
qreal toEastLon = viewLatLonAltBox.east( GeoDataCoordinates::Degree );
if ( fromWestLon < toEastLon ) {
qreal step = ( toEastLon - fromWestLon ) * 0.25;
for ( int i = 0; i < 5; ++i ) {
line << GeoDataCoordinates( fromWestLon + i * step, latitude, 0.0, GeoDataCoordinates::Degree );
}
}
else {
qreal step = ( +180.0 - toEastLon ) * 0.25;
for ( int i = 0; i < 5; ++i ) {
line << GeoDataCoordinates( toEastLon + i * step, latitude, 0.0, GeoDataCoordinates::Degree );
}
step = ( +180 + fromWestLon ) * 0.25;
for ( int i = 0; i < 5; ++i ) {
line << GeoDataCoordinates( -180 + i * step, latitude, 0.0, GeoDataCoordinates::Degree );
}
}
painter->drawPolyline( line, lineLabel, labelPositionFlags, painter->pen().color() );
}
void GraticulePlugin::renderLongitudeLine( GeoPainter *painter, qreal longitude,
const GeoDataLatLonAltBox& viewLatLonAltBox,
qreal northPolarGap, qreal southPolarGap,
const QString& lineLabel,
LabelPositionFlags labelPositionFlags )
{
const qreal fromWestLon = viewLatLonAltBox.west();
const qreal toEastLon = viewLatLonAltBox.east();
// Coordinate line is not displayed inside the viewport
if ( ( !viewLatLonAltBox.crossesDateLine()
&& ( longitude * DEG2RAD < fromWestLon || toEastLon < longitude * DEG2RAD ) ) ||
( viewLatLonAltBox.crossesDateLine() &&
longitude * DEG2RAD < toEastLon && fromWestLon < longitude * DEG2RAD &&
fromWestLon != -M_PI && toEastLon != +M_PI )
) {
// mDebug() << "Lon: Out of View:" << viewLatLonAltBox.toString() << " Crossing: "<< viewLatLonAltBox.crossesDateLine() << "Longitude: " << longitude;
return;
}
qreal fromSouthLat = viewLatLonAltBox.south( GeoDataCoordinates::Degree );
qreal toNorthLat = viewLatLonAltBox.north( GeoDataCoordinates::Degree );
qreal southLat = ( fromSouthLat < -90.0 + southPolarGap ) ? -90.0 + southPolarGap : fromSouthLat;
qreal northLat = ( toNorthLat > +90.0 - northPolarGap ) ? +90.0 - northPolarGap : toNorthLat;
GeoDataCoordinates n1( longitude, southLat, 0.0, GeoDataCoordinates::Degree );
GeoDataCoordinates n3( longitude, northLat, 0.0, GeoDataCoordinates::Degree );
GeoDataLineString line( Tessellate );
if ( northLat > 0 && southLat < 0 )
{
GeoDataCoordinates n2( longitude, 0.0, 0.0, GeoDataCoordinates::Degree );
line << n1 << n2 << n3;
}
else {
line << n1 << n3;
}
painter->drawPolyline( line, lineLabel, labelPositionFlags, painter->pen().color() );
}
void GraticulePlugin::renderLatitudeLines( GeoPainter *painter,
const GeoDataLatLonAltBox& viewLatLonAltBox,
qreal step, qreal skipStep,
LabelPositionFlags labelPositionFlags
)
{
if ( step <= 0 ) {
return;
}
// Latitude
qreal southLat = viewLatLonAltBox.south( GeoDataCoordinates::Degree );
qreal northLat = viewLatLonAltBox.north( GeoDataCoordinates::Degree );
qreal southLineLat = step * static_cast<int>( southLat / step );
qreal northLineLat = step * ( static_cast<int>( northLat / step ) + 1 );
if ( m_currentNotation == GeoDataCoordinates::UTM ) {
if ( northLineLat > 84.0 ) {
northLineLat = 76.0;
}
if ( southLineLat < -80.0 ) {
southLineLat = -80.0;
}
}
qreal itStep = southLineLat;
GeoDataCoordinates::Notation notation = GeoDataCoordinates::defaultNotation();
while ( itStep < northLineLat ) {
// Create a matching label
QString label = GeoDataCoordinates::latToString( itStep, notation,
GeoDataCoordinates::Degree, -1, 'g' );
// No additional labels for the equator
if ( labelPositionFlags.testFlag( LineCenter ) && itStep == 0.0 ) {
label.clear();
}
// Paint all latitude coordinate lines except for the equator
if ( itStep != 0.0 && fmod(itStep, skipStep) != 0 ) {
renderLatitudeLine( painter, itStep, viewLatLonAltBox, label, labelPositionFlags );
}
itStep += step;
}
}
void GraticulePlugin::renderUtmExceptions( GeoPainter *painter,
const GeoDataLatLonAltBox& viewLatLonAltBox,
qreal itStep, qreal northPolarGap, qreal southPolarGap,
const QString & label,
LabelPositionFlags labelPositionFlags )
{
// This code renders the so called "exceptions" in the UTM coordinate grid
// See: http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system#Exceptions
if ( northPolarGap == 6.0 && southPolarGap == 162.0) {
if (label == QLatin1String("33")) {
renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
} else if (label == QLatin1String("35")) {
renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
} else if (label == QLatin1String("37")) {
renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
} else if (label == QLatin1String("32") || label == QLatin1String("34") || label == QLatin1String("36")) {
// paint nothing
} else {
renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
}
}
else if ( northPolarGap == 26.0 && southPolarGap == 146.0 ) {
if (label == QLatin1String("32")) {
renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
} else {
renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
}
}
else {
renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
}
}
void GraticulePlugin::renderLongitudeLines( GeoPainter *painter,
const GeoDataLatLonAltBox& viewLatLonAltBox,
qreal step, qreal skipStep,
qreal northPolarGap, qreal southPolarGap,
LabelPositionFlags labelPositionFlags) const
{
if ( step <= 0 ) {
return;
}
const bool isSky = (marbleModel()->planet()->id() == QLatin1String("sky"));
const GeoDataCoordinates::Notation notation = isSky ? GeoDataCoordinates::Astro : GeoDataCoordinates::defaultNotation();
// Set precision to 0 in UTM in order to show only zone number.
int precision = (notation == GeoDataCoordinates::UTM) ? 0 : -1;
// Longitude
qreal westLon = viewLatLonAltBox.west( GeoDataCoordinates::Degree );
qreal eastLon = viewLatLonAltBox.east( GeoDataCoordinates::Degree );
qreal westLineLon = step * static_cast<int>( westLon / step );
qreal eastLineLon = step * ( static_cast<int>( eastLon / step ) + 1 );
if ( !viewLatLonAltBox.crossesDateLine() ||
( westLon == -180.0 && eastLon == +180.0 ) ) {
qreal itStep = westLineLon;
while ( itStep < eastLineLon ) {
// Create a matching label
QString label = GeoDataCoordinates::lonToString( itStep,
notation, GeoDataCoordinates::Degree,
precision, 'g' );
// No additional labels for the prime meridian and the antimeridian
if ( labelPositionFlags.testFlag( LineCenter ) && ( itStep == 0.0 || itStep == 180.0 || itStep == -180.0 ) )
{
label.clear();
}
// Paint all longitude coordinate lines (except for the meridians in non-UTM mode)
if (notation == GeoDataCoordinates::UTM ) {
renderUtmExceptions( painter, viewLatLonAltBox, itStep, northPolarGap,
southPolarGap, label, labelPositionFlags );
} else if ( itStep != 0.0 && itStep != 180.0 && itStep != -180.0 ) {
if (fmod(itStep, skipStep) != 0 || skipStep == 0.0) {
renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
}
}
itStep += step;
}
}
else {
qreal itStep = eastLineLon;
while ( itStep < 180.0 ) {
// Create a matching label
QString label = GeoDataCoordinates::lonToString( itStep,
notation, GeoDataCoordinates::Degree,
precision, 'g' );
// No additional labels for the prime meridian and the antimeridian
if ( labelPositionFlags.testFlag( LineCenter ) && ( itStep == 0.0 || itStep == 180.0 || itStep == -180.0 ) )
{
label.clear();
}
// Paint all longitude coordinate lines (except for the meridians in non-UTM mode)
if (notation == GeoDataCoordinates::UTM ) {
renderUtmExceptions( painter, viewLatLonAltBox, itStep, northPolarGap,
southPolarGap, label, labelPositionFlags );
} else if ( itStep != 0.0 && itStep != 180.0 && itStep != -180.0 ) {
if (fmod((itStep), skipStep) != 0 || skipStep == 0.0) {
renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
}
}
itStep += step;
}
itStep = -180.0;
while ( itStep < westLineLon ) {
// Create a matching label
QString label = GeoDataCoordinates::lonToString( itStep,
notation, GeoDataCoordinates::Degree,
precision, 'g' );
// No additional labels for the prime meridian and the antimeridian
if ( labelPositionFlags.testFlag( LineCenter ) && ( itStep == 0.0 || itStep == 180.0 || itStep == -180.0 ) )
{
label.clear();
}
// Paint all longitude coordinate lines (except for the meridians in non-UTM mode)
if (notation == GeoDataCoordinates::UTM ) {
renderUtmExceptions( painter, viewLatLonAltBox, itStep, northPolarGap,
southPolarGap, label, labelPositionFlags );
} else if ( itStep != 0.0 && itStep != 180.0 && itStep != -180.0 ) {
if (fmod((itStep+180), skipStep) != 0 || skipStep == 0.0) {
renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap,
southPolarGap, label, labelPositionFlags );
}
}
itStep += step;
}
}
}
void GraticulePlugin::initLineMaps( GeoDataCoordinates::Notation notation)
{
/* Define Upper Bound keys and associated values:
The key number is the globe radius in pixel.
The value number is the amount of grid lines for the full range.
Example: up to a 100 pixel radius the globe is covered
with 4 longitude lines (4 half-circles).
*/
if (marbleModel()->planet()->id() == QLatin1String("sky") ||
notation == GeoDataCoordinates::Astro) {
m_normalLineMap[100] = 4; // 6h
m_normalLineMap[1000] = 12; // 2h
m_normalLineMap[2000] = 24; // 1h
m_normalLineMap[4000] = 48; // 30 min
m_normalLineMap[8000] = 96; // 15 min
m_normalLineMap[16000] = 288; // 5 min
m_normalLineMap[100000] = 24 * 60; // 1 min
m_normalLineMap[200000] = 24 * 60 * 2; // 30 sec
m_normalLineMap[400000] = 24 * 60 * 4; // 15 sec
m_normalLineMap[1200000] = 24 * 60 * 12; // 5 sec
m_normalLineMap[6000000] = 24 * 60 * 60; // 1 sec
m_normalLineMap[12000000] = 24 * 60 * 60 * 2; // 0.5 sec
m_normalLineMap[24000000] = 24 * 60 * 60 * 4; // 0.25 sec
m_boldLineMap[1000] = 0; // 0h
m_boldLineMap[2000] = 4; // 6h
m_boldLineMap[16000] = 24; // 30 deg
return;
}
m_normalLineMap[100] = 4; // 90 deg
m_normalLineMap[1000] = 12; // 30 deg
m_normalLineMap[4000] = 36; // 10 deg
m_normalLineMap[16000] = 72; // 5 deg
m_normalLineMap[64000] = 360; // 1 deg
m_normalLineMap[128000] = 720; // 0.5 deg
m_boldLineMap[1000] = 0; // 0 deg
m_boldLineMap[4000] = 12; // 30 deg
m_boldLineMap[16000] = 36; // 10 deg
switch ( notation )
{
case GeoDataCoordinates::Decimal :
m_normalLineMap[512000] = 360 * 10; // 0.1 deg
m_normalLineMap[2048000] = 360 * 20; // 0.05 deg
m_normalLineMap[8192000] = 360 * 100; // 0.01 deg
m_normalLineMap[16384000] = 360 * 200; // 0.005 deg
m_normalLineMap[32768000] = 360 * 1000; // 0.001 deg
m_normalLineMap[131072000] = 360 * 2000; // 0.0005 deg
m_normalLineMap[524288000] = 360 * 10000; // 0.00001 deg
m_boldLineMap[512000] = 360; // 0.1 deg
m_boldLineMap[2048000] = 720; // 0.05 deg
m_boldLineMap[8192000] = 360 * 10; // 0.01 deg
m_boldLineMap[1638400] = 360 * 20; // 0.005 deg
m_boldLineMap[32768000] = 360 * 100; // 0.001 deg
m_boldLineMap[131072000] = 360 * 200; // 0.0005 deg
m_boldLineMap[524288000] = 360 * 1000; // 0.00001 deg
break;
default:
case GeoDataCoordinates::DMS :
m_normalLineMap[512000] = 360 * 6; // 10'
m_normalLineMap[1024000] = 360 * 12; // 5'
m_normalLineMap[4096000] = 360 * 60; // 1'
m_normalLineMap[8192000] = 360 * 60 * 2; // 30"
m_normalLineMap[16384000] = 360 * 60 * 6; // 10"
m_normalLineMap[65535000] = 360 * 60 * 12; // 5"
m_normalLineMap[524288000] = 360 * 60 * 60; // 1"
m_boldLineMap[512000] = 360; // 10'
m_boldLineMap[1024000] = 720; // 5'
m_boldLineMap[4096000] = 360 * 6; // 1'
m_boldLineMap[8192000] = 360 * 12; // 30"
m_boldLineMap[16384000] = 360 * 60; // 10"
m_boldLineMap[65535000] = 360 * 60 * 2; // 5"
m_boldLineMap[524288000] = 360 * 60 * 6; // 1"
break;
}
m_normalLineMap[999999999] = m_normalLineMap.value(262144000); // last
m_boldLineMap[999999999] = m_boldLineMap.value(262144000); // last
m_currentNotation = notation;
}
}
#include "moc_GraticulePlugin.cpp"
diff --git a/src/plugins/render/graticule/GraticulePlugin.h b/src/plugins/render/graticule/GraticulePlugin.h
index a02a10b7f..132fb3060 100644
--- a/src/plugins/render/graticule/GraticulePlugin.h
+++ b/src/plugins/render/graticule/GraticulePlugin.h
@@ -1,230 +1,230 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Torsten Rahn <tackat@kde.org>
//
//
// This class is a graticule plugin.
//
#ifndef MARBLEGRATICULEPLUGIN_H
#define MARBLEGRATICULEPLUGIN_H
#include <QMap>
#include <QHash>
#include <QPen>
#include <QIcon>
#include <QColorDialog>
#include "DialogConfigurationInterface.h"
#include "RenderPlugin.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLatLonAltBox.h"
namespace Ui
{
class GraticuleConfigWidget;
}
namespace Marble
{
class GeoDataLatLonAltBox;
/**
* @brief A plugin that creates a coordinate grid on top of the map.
* Unlike in all other classes we are using degree by default in this class.
* This choice was made due to the fact that all common coordinate grids focus fully
* on the degree system.
*/
class GraticulePlugin : public RenderPlugin, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.GraticulePlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN( GraticulePlugin )
public:
GraticulePlugin();
explicit GraticulePlugin( const MarbleModel *marbleModel );
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
QDialog *configDialog() override;
void initialize () override;
bool isInitialized () const override;
- bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
qreal zValue() const override;
QHash<QString,QVariant> settings() const override;
void setSettings( const QHash<QString,QVariant> &settings ) override;
public Q_SLOTS:
void readSettings();
void writeSettings();
void gridGetColor();
void tropicsGetColor();
void equatorGetColor();
private:
/**
* @brief Renders the coordinate grid within the defined view bounding box.
* @param painter the painter used to draw the grid
* @param viewport the viewport
*/
void renderGrid( GeoPainter *painter, ViewportParams *viewport,
const QPen& equatorCirclePen,
const QPen& tropicsCirclePen,
const QPen& gridCirclePen );
/**
* @brief Renders a latitude line within the defined view bounding box.
* @param painter the painter used to draw the latitude line
* @param latitude the latitude of the coordinate line measured in degree .
* @param viewLatLonAltBox the latitude longitude bounding box that is covered by the view.
*/
static void renderLatitudeLine( GeoPainter *painter, qreal latitude,
const GeoDataLatLonAltBox& viewLatLonAltBox = GeoDataLatLonAltBox(),
const QString& lineLabel = QString(),
LabelPositionFlags labelPositionFlags = LineCenter );
/**
* @brief Renders a longitude line within the defined view bounding box.
* @param painter the painter used to draw the latitude line
* @param longitude the longitude of the coordinate line measured in degree .
* @param viewLatLonAltBox the latitude longitude bounding box that is covered by the view.
* @param polarGap the area around the poles in which most longitude lines are not drawn
* for reasons of aesthetics and clarity of the map. The polarGap avoids narrow
* concurring lines around the poles which obstruct the view onto the surface.
* The radius of the polarGap area is measured in degrees.
* @param lineLabel draws a label using the font and color properties set for the painter.
*/
static void renderLongitudeLine( GeoPainter *painter, qreal longitude,
const GeoDataLatLonAltBox& viewLatLonAltBox = GeoDataLatLonAltBox(),
qreal northPolarGap = 0.0, qreal southPolarGap = 0.0,
const QString& lineLabel = QString(),
LabelPositionFlags labelPositionFlags = LineCenter );
/**
* @brief Renders the latitude lines that are visible within the defined view bounding box.
* @param painter the painter used to draw the latitude lines
* @param viewLatLonAltBox the latitude longitude bounding box that is covered by the view.
* @param step the angular distance between the lines measured in degrees .
*/
void renderLatitudeLines( GeoPainter *painter,
const GeoDataLatLonAltBox& viewLatLonAltBox,
qreal step, qreal skipStep,
LabelPositionFlags labelPositionFlags = LineCenter
);
/**
* @brief Renders the longitude lines that are visible within the defined view bounding box.
* @param painter the painter used to draw the latitude lines
* @param viewLatLonAltBox the latitude longitude bounding box that is covered by the view.
* @param step the angular distance between the lines measured in degrees .
* @param northPolarGap the area around the north pole in which most longitude lines are not drawn
* for reasons of aesthetics and clarity of the map. The polarGap avoids narrow
* concurring lines around the poles which obstruct the view onto the surface.
* The radius of the polarGap area is measured in degrees.
* @param southPolarGap the area around the south pole in which most longitude lines are not drawn
* for reasons of aesthetics and clarity of the map. The polarGap avoids narrow
* concurring lines around the poles which obstruct the view onto the surface.
* The radius of the polarGap area is measured in degrees.
*/
void renderLongitudeLines( GeoPainter *painter,
const GeoDataLatLonAltBox& viewLatLonAltBox,
qreal step, qreal skipStep,
qreal northPolarGap = 0.0, qreal southPolarGap = 0.0,
LabelPositionFlags labelPositionFlags = LineCenter
) const;
/**
* @brief Renders UTM exceptions that are visible within the defined view bounding box.
* @param painter the painter used to draw the latitude lines
* @param viewLatLonAltBox the latitude longitude bounding box that is covered by the view.
* @param step the angular distance between the lines measured in degrees .
* @param northPolarGap the area around the north pole in which most longitude lines are not drawn
* for reasons of aesthetics and clarity of the map. The polarGap avoids narrow
* concurring lines around the poles which obstruct the view onto the surface.
* The radius of the polarGap area is measured in degrees.
* @param southPolarGap the area around the south pole in which most longitude lines are not drawn
* for reasons of aesthetics and clarity of the map. The polarGap avoids narrow
* concurring lines around the poles which obstruct the view onto the surface.
* The radius of the polarGap area is measured in degrees.
*/
static void renderUtmExceptions( GeoPainter *painter,
const GeoDataLatLonAltBox& viewLatLonAltBox,
qreal step,
qreal northPolarGap, qreal southPolarGap,
const QString & label,
LabelPositionFlags labelPositionFlags );
/**
* @brief Maps the number of coordinate lines per 360 deg against the globe radius on the screen.
* @param notation Determines whether the graticule is according to the DMS or Decimal system.
*/
void initLineMaps( GeoDataCoordinates::Notation notation );
GeoDataCoordinates::Notation m_currentNotation;
// Maps the zoom factor to the amount of lines per 360 deg
QMap<qreal,qreal> m_boldLineMap;
QMap<qreal,qreal> m_normalLineMap;
QPen m_equatorCirclePen;
QPen m_tropicsCirclePen;
QPen m_gridCirclePen;
bool m_showPrimaryLabels;
bool m_showSecondaryLabels;
bool m_isInitialized;
QIcon m_icon;
Ui::GraticuleConfigWidget *ui_configWidget;
QDialog *m_configDialog;
};
}
#endif // MARBLEGRATICULEPLUGIN_H
diff --git a/src/plugins/render/license/License.cpp b/src/plugins/render/license/License.cpp
index 511dfc064..6faaa3e08 100644
--- a/src/plugins/render/license/License.cpp
+++ b/src/plugins/render/license/License.cpp
@@ -1,246 +1,246 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "License.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarbleAboutDialog.h"
#include "WidgetGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "ViewportParams.h"
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "GeoSceneLicense.h"
#include <QCommonStyle>
#include <QContextMenuEvent>
#include <QPainter>
#include <QLabel>
#include <QMenu>
#include <QMouseEvent>
namespace Marble
{
class OutlinedStyle : public QCommonStyle {
public:
void drawItemText( QPainter *painter, const QRect &rect, int alignment, const QPalette &palette,
bool enabled, const QString& text, QPalette::ColorRole textRole ) const override {
Q_UNUSED( alignment );
Q_UNUSED( enabled );
if ( text.isEmpty() ) {
return;
}
QPen savedPen;
if ( textRole != QPalette::NoRole ) {
savedPen = painter->pen();
painter->setPen( QPen( palette.brush( textRole ), savedPen.widthF() ) );
}
QPainterPath path;
QFontMetricsF metrics( painter->font() );
QPointF point( rect.x() + 7.0, rect.y() + metrics.ascent() );
path.addText( point, painter->font(), text );
QPen pen( Qt::white );
pen.setWidth( 3 );
painter->setPen( pen );
painter->setBrush( QBrush( Qt::black ) );
painter->setRenderHint( QPainter::Antialiasing, true );
painter->drawPath( path );
painter->setPen( Qt::NoPen );
painter->drawPath( path );
if ( textRole != QPalette::NoRole ) {
painter->setPen( savedPen );
}
}
};
License::License( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( -10.0, -5.0 ), QSizeF( 150.0, 20.0 ) ),
- m_widgetItem( 0 ),
- m_label( 0 ),
+ m_widgetItem( nullptr ),
+ m_label( nullptr ),
m_showFullLicense( false ),
- m_contextMenu( 0 )
+ m_contextMenu( nullptr )
{
setEnabled( true );
setVisible( true );
setBackground( QBrush( QColor( Qt::transparent ) ) );
setFrame( NoFrame );
}
License::~License()
{
}
QStringList License::backendTypes() const
{
return QStringList(QStringLiteral("License"));
}
QString License::name() const
{
return tr( "License" );
}
QString License::guiString() const
{
return tr( "&License" );
}
QString License::nameId() const
{
return QStringLiteral("license");
}
QString License::version() const
{
return QStringLiteral("1.0");
}
QString License::description() const
{
return tr( "This is a float item that provides copyright information." );
}
QString License::copyrightYears() const
{
return QStringLiteral("2012");
}
QVector<PluginAuthor> License::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
<< PluginAuthor(QStringLiteral("Illya Kovalevskyy"), QStringLiteral("illya.kovalevskyy@gmail.com"));
}
QIcon License::icon () const
{
return QIcon(QStringLiteral(":/icons/license.png"));
}
void License::initialize ()
{
delete m_widgetItem;
m_widgetItem = new WidgetGraphicsItem( this );
m_label = new QLabel;
auto style = new OutlinedStyle;
style->setParent(this);
m_label->setStyle( style );
m_label->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
m_widgetItem->setWidget( m_label );
MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
layout->addItem( m_widgetItem, 0, 0 );
setLayout( layout );
setPadding( 0 );
updateLicenseText();
connect( marbleModel(), SIGNAL(themeChanged(QString)), this, SLOT(updateLicenseText()) );
}
void License::updateLicenseText()
{
const GeoSceneDocument *const mapTheme = marbleModel()->mapTheme();
if ( !mapTheme )
return;
const GeoSceneHead *const head = mapTheme->head();
if ( !head )
return;
const GeoSceneLicense *license = marbleModel()->mapTheme()->head()->license();
m_label->setText( m_showFullLicense ? license->license() : license->shortLicense() );
m_label->setToolTip( license->license() );
if( license->attribution() == GeoSceneLicense::Always ) {
setUserCheckable( false );
} else if( license->attribution() == GeoSceneLicense::Never ) {
setVisible( false );
setUserCheckable( false );
} else if( license->attribution() == GeoSceneLicense::OptIn ) {
setUserCheckable( true );
setVisible( false );
} else {
setUserCheckable( true );
setVisible( true );
}
QSizeF const magic( 6,0 );
m_widgetItem->setSize( m_label->sizeHint()+magic );
setSize( m_label->sizeHint()+magic );
update();
emit repaintNeeded();
}
void License::toggleLicenseSize()
{
m_showFullLicense = !m_showFullLicense;
updateLicenseText();
}
void License::showAboutDialog()
{
QPointer<MarbleAboutDialog> aboutDialog = new MarbleAboutDialog;
aboutDialog->setInitialTab( MarbleAboutDialog::Data );
aboutDialog->exec();
delete aboutDialog;
}
bool License::isInitialized () const
{
return m_widgetItem;
}
bool License::eventFilter( QObject *object, QEvent *event )
{
if ( !enabled() || !visible() )
return false;
MarbleWidget *widget = dynamic_cast<MarbleWidget*>( object );
if ( !widget ) {
return AbstractFloatItem::eventFilter( object,event );
}
if( event->type() == QEvent::MouseMove ) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
QRectF floatItemRect = QRectF( positivePosition(), size() );
if ( floatItemRect.contains( mouseEvent->pos() ) ) {
widget->setCursor( QCursor( Qt::ArrowCursor ) );
return true;
}
}
return AbstractFloatItem::eventFilter( object, event );
}
void License::contextMenuEvent( QWidget *w, QContextMenuEvent *e )
{
if ( !m_contextMenu ) {
m_contextMenu = contextMenu();
QAction *toggleAction = m_contextMenu->addAction( tr("&Full License"), this,
SLOT(toggleLicenseSize()) );
toggleAction->setCheckable( true );
toggleAction->setChecked( m_showFullLicense );
m_contextMenu->addAction( tr("&Show Details"), this, SLOT(showAboutDialog()) );
}
Q_ASSERT( m_contextMenu );
m_contextMenu->exec( w->mapToGlobal( e->pos() ) );
}
}
#include "moc_License.cpp"
diff --git a/src/plugins/render/license/License.h b/src/plugins/render/license/License.h
index b663922ce..f48cabdaa 100644
--- a/src/plugins/render/license/License.h
+++ b/src/plugins/render/license/License.h
@@ -1,69 +1,69 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef MARBLELICENSE_H
#define MARBLELICENSE_H
#include "AbstractFloatItem.h"
class QLabel;
namespace Marble
{
class WidgetGraphicsItem;
/**
* @short The class that displays copyright info
*
*/
class License : public AbstractFloatItem
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.License")
Q_INTERFACES( Marble::RenderPluginInterface )
MARBLE_PLUGIN( License )
public:
- explicit License( const MarbleModel *marbleModel=0 );
+ explicit License( const MarbleModel *marbleModel=nullptr );
~License() override;
QStringList backendTypes() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
private Q_SLOTS:
void updateLicenseText();
void toggleLicenseSize();
void showAboutDialog();
protected:
bool eventFilter(QObject *, QEvent *e) override;
void contextMenuEvent( QWidget *w, QContextMenuEvent *e ) override;
private:
WidgetGraphicsItem* m_widgetItem;
QLabel* m_label;
bool m_showFullLicense;
QMenu* m_contextMenu;
};
}
#endif
diff --git a/src/plugins/render/mapscale/MapScaleFloatItem.cpp b/src/plugins/render/mapscale/MapScaleFloatItem.cpp
index d8f784a03..ab8b390a7 100644
--- a/src/plugins/render/mapscale/MapScaleFloatItem.cpp
+++ b/src/plugins/render/mapscale/MapScaleFloatItem.cpp
@@ -1,457 +1,457 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "MapScaleFloatItem.h"
#include <QContextMenuEvent>
#include <QDebug>
#include <QHelpEvent>
#include <QRect>
#include <QPainter>
#include <QPushButton>
#include <QMenu>
#include <QToolTip>
#include "ui_MapScaleConfigWidget.h"
#include "MarbleDebug.h"
#include "MarbleGlobal.h"
#include "projections/AbstractProjection.h"
#include "MarbleLocale.h"
#include "MarbleModel.h"
#include "ViewportParams.h"
#include "GeoDataLatLonAltBox.h"
namespace Marble
{
MapScaleFloatItem::MapScaleFloatItem( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( 10.5, -10.5 ), QSizeF( 0.0, 40.0 ) ),
- m_configDialog(0),
+ m_configDialog(nullptr),
m_radius(0),
m_target(QString()),
m_leftBarMargin(0),
m_rightBarMargin(0),
m_scaleBarWidth(0),
m_viewportWidth(0),
m_scaleBarHeight(5),
m_scaleBarDistance(0.0),
m_bestDivisor(0),
m_pixelInterval(0),
m_valueInterval(0),
m_scaleInitDone( false ),
m_showRatioScale( false ),
- m_contextMenu( 0 ),
+ m_contextMenu( nullptr ),
m_minimized(false),
m_widthScaleFactor(2)
{
m_minimizeAction = new QAction(tr("Minimize"), this);
m_minimizeAction->setCheckable(true);
m_minimizeAction->setChecked(m_minimized);
connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(toggleMinimized()));
}
MapScaleFloatItem::~MapScaleFloatItem()
{
}
QStringList MapScaleFloatItem::backendTypes() const
{
return QStringList(QStringLiteral("mapscale"));
}
QString MapScaleFloatItem::name() const
{
return tr("Scale Bar");
}
QString MapScaleFloatItem::guiString() const
{
return tr("&Scale Bar");
}
QString MapScaleFloatItem::nameId() const
{
return QStringLiteral("scalebar");
}
QString MapScaleFloatItem::version() const
{
return QStringLiteral("1.1");
}
QString MapScaleFloatItem::description() const
{
return tr("This is a float item that provides a map scale.");
}
QString MapScaleFloatItem::copyrightYears() const
{
return QStringLiteral("2008, 2010, 2012");
}
QVector<PluginAuthor> MapScaleFloatItem::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"), tr("Original Developer"))
<< PluginAuthor(QStringLiteral("Khanh-Nhan Nguyen"), QStringLiteral("khanh.nhan@wpi.edu"))
<< PluginAuthor(QStringLiteral("Illya Kovalevskyy"), QStringLiteral("illya.kovalevskyy@gmail.com"));
}
QIcon MapScaleFloatItem::icon () const
{
return QIcon(QStringLiteral(":/icons/scalebar.png"));
}
void MapScaleFloatItem::initialize ()
{
}
bool MapScaleFloatItem::isInitialized () const
{
return true;
}
void MapScaleFloatItem::setProjection( const ViewportParams *viewport )
{
int viewportWidth = viewport->width();
QString target = marbleModel()->planetId();
if ( !( m_radius == viewport->radius()
&& viewportWidth == m_viewportWidth
&& m_target == target
&& m_scaleInitDone ) )
{
int fontHeight = QFontMetrics( font() ).ascent();
if (m_showRatioScale) {
setContentSize( QSizeF( viewport->width() / m_widthScaleFactor,
fontHeight + 3 + m_scaleBarHeight + fontHeight + 7 ) );
} else {
setContentSize( QSizeF( viewport->width() / m_widthScaleFactor,
fontHeight + 3 + m_scaleBarHeight ) );
}
m_leftBarMargin = QFontMetrics( font() ).boundingRect( "0" ).width() / 2;
m_rightBarMargin = QFontMetrics( font() ).boundingRect( "0000" ).width() / 2;
m_scaleBarWidth = contentSize().width() - m_leftBarMargin - m_rightBarMargin;
m_viewportWidth = viewport->width();
m_radius = viewport->radius();
m_scaleInitDone = true;
m_pixel2Length = marbleModel()->planetRadius() /
(qreal)(viewport->radius());
if ( viewport->currentProjection()->surfaceType() == AbstractProjection::Cylindrical )
{
qreal centerLatitude = viewport->viewLatLonAltBox().center().latitude();
// For flat maps we calculate the length of the 90 deg section of the
// central latitude circle. For flat maps this distance matches
// the pixel based radius propertyy.
m_pixel2Length *= M_PI / 2 * cos( centerLatitude );
}
m_scaleBarDistance = (qreal)(m_scaleBarWidth) * m_pixel2Length;
const MarbleLocale::MeasurementSystem measurementSystem =
MarbleGlobal::getInstance()->locale()->measurementSystem();
if ( measurementSystem != MarbleLocale::MetricSystem ) {
m_scaleBarDistance *= KM2MI;
} else if (measurementSystem == MarbleLocale::NauticalSystem) {
m_scaleBarDistance *= KM2NM;
}
calcScaleBar();
update();
}
AbstractFloatItem::setProjection( viewport );
}
void MapScaleFloatItem::paintContent( QPainter *painter )
{
painter->save();
painter->setRenderHint( QPainter::Antialiasing, true );
int fontHeight = QFontMetrics( font() ).ascent();
//calculate scale ratio
qreal displayMMPerPixel = 1.0 * painter->device()->widthMM() / painter->device()->width();
qreal ratio = m_pixel2Length / (displayMMPerPixel * MM2M);
//round ratio to 3 most significant digits, assume that ratio >= 1, otherwise it may display "1 : 0"
//i made this assumption because as the primary use case we do not need to zoom in that much
qreal power = 1;
int iRatio = (int)(ratio + 0.5); //round ratio to the nearest integer
while (iRatio >= 1000) {
iRatio /= 10;
power *= 10;
}
iRatio *= power;
m_ratioString.setNum(iRatio);
m_ratioString = QLatin1String("1 : ") + m_ratioString;
painter->setPen( QColor( Qt::darkGray ) );
painter->setBrush( QColor( Qt::darkGray ) );
painter->drawRect( m_leftBarMargin, fontHeight + 3,
m_scaleBarWidth,
m_scaleBarHeight );
painter->setPen( QColor( Qt::black ) );
painter->setBrush( QColor( Qt::white ) );
painter->drawRect( m_leftBarMargin, fontHeight + 3,
m_bestDivisor * m_pixelInterval, m_scaleBarHeight );
painter->setPen( QColor( Oxygen::aluminumGray4 ) );
painter->drawLine( m_leftBarMargin + 1, fontHeight + 2 + m_scaleBarHeight,
m_leftBarMargin + m_bestDivisor * m_pixelInterval - 1, fontHeight + 2 + m_scaleBarHeight );
painter->setPen( QColor( Qt::black ) );
painter->setBrush( QColor( Qt::black ) );
QString intervalStr;
int lastStringEnds = 0;
int currentStringBegin = 0;
for ( int j = 0; j <= m_bestDivisor; j += 2 ) {
if ( j < m_bestDivisor ) {
painter->drawRect( m_leftBarMargin + j * m_pixelInterval,
fontHeight + 3, m_pixelInterval - 1,
m_scaleBarHeight );
painter->setPen( QColor( Oxygen::aluminumGray5 ) );
painter->drawLine( m_leftBarMargin + j * m_pixelInterval + 1, fontHeight + 4,
m_leftBarMargin + (j + 1) * m_pixelInterval - 1, fontHeight + 4 );
painter->setPen( QColor( Qt::black ) );
}
MarbleLocale::MeasurementSystem distanceUnit;
distanceUnit = MarbleGlobal::getInstance()->locale()->measurementSystem();
QString unit = tr("km");
switch ( distanceUnit ) {
case MarbleLocale::MetricSystem:
if ( m_bestDivisor * m_valueInterval > 10000 ) {
unit = tr("km");
intervalStr.setNum( j * m_valueInterval / 1000 );
}
else {
unit = tr("m");
intervalStr.setNum( j * m_valueInterval );
}
break;
case MarbleLocale::ImperialSystem:
unit = tr("mi");
intervalStr.setNum( j * m_valueInterval / 1000 );
if ( m_bestDivisor * m_valueInterval > 3800 ) {
intervalStr.setNum( j * m_valueInterval / 1000 );
}
else {
intervalStr.setNum( qreal(j * m_valueInterval ) / 1000.0, 'f', 2 );
}
break;
case MarbleLocale::NauticalSystem:
unit = tr("nm");
intervalStr.setNum( j * m_valueInterval / 1000 );
if ( m_bestDivisor * m_valueInterval > 3800 ) {
intervalStr.setNum( j * m_valueInterval / 1000 );
}
else {
intervalStr.setNum( qreal(j * m_valueInterval ) / 1000.0, 'f', 2 );
}
break;
}
painter->setFont( font() );
if ( j == 0 ) {
const QString text = QLatin1String("0 ") + unit;
painter->drawText(0, fontHeight, text);
lastStringEnds = QFontMetrics(font()).width(text);
continue;
}
if( j == m_bestDivisor ) {
currentStringBegin = ( j * m_pixelInterval
- QFontMetrics( font() ).boundingRect( intervalStr ).width() );
}
else {
currentStringBegin = ( j * m_pixelInterval
- QFontMetrics( font() ).width( intervalStr ) / 2 );
}
if ( lastStringEnds < currentStringBegin ) {
painter->drawText( currentStringBegin, fontHeight, intervalStr );
lastStringEnds = currentStringBegin + QFontMetrics( font() ).width( intervalStr );
}
}
int leftRatioIndent = m_leftBarMargin + (m_scaleBarWidth - QFontMetrics( font() ).width(m_ratioString) ) / 2;
painter->drawText( leftRatioIndent, fontHeight + 3 + m_scaleBarHeight + fontHeight + 5, m_ratioString );
painter->restore();
}
void MapScaleFloatItem::calcScaleBar()
{
qreal magnitude = 1;
// First we calculate the exact length of the whole area that is possibly
// available to the scalebar in kilometers
int magValue = (int)( m_scaleBarDistance );
// We calculate the two most significant digits of the km-scalebar-length
// and store them in magValue.
while ( magValue >= 100 ) {
magValue /= 10;
magnitude *= 10;
}
m_bestDivisor = 4;
int bestMagValue = 1;
for ( int i = 0; i < magValue; i++ ) {
// We try to find the lowest divisor between 4 and 8 that
// divides magValue without remainder.
for ( int j = 4; j < 9; j++ ) {
if ( ( magValue - i ) % j == 0 ) {
// We store the very first result we find and store
// m_bestDivisor and bestMagValue as a final result.
m_bestDivisor = j;
bestMagValue = magValue - i;
// Stop all for loops and end search
i = magValue;
j = 9;
}
}
// If magValue doesn't divide through values between 4 and 8
// (e.g. because it's a prime number) try again with magValue
// decreased by i.
}
m_pixelInterval = (int)( m_scaleBarWidth * (qreal)( bestMagValue )
/ (qreal)( magValue ) / m_bestDivisor );
m_valueInterval = (int)( bestMagValue * magnitude / m_bestDivisor );
}
QDialog *MapScaleFloatItem::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::MapScaleConfigWidget;
ui_configWidget->setupUi( m_configDialog );
readSettings();
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()) ,
this, SLOT(writeSettings()) );
}
return m_configDialog;
}
void MapScaleFloatItem::contextMenuEvent( QWidget *w, QContextMenuEvent *e )
{
if ( !m_contextMenu ) {
m_contextMenu = contextMenu();
for( QAction *action: m_contextMenu->actions() ) {
if ( action->text() == tr( "&Configure..." ) ) {
m_contextMenu->removeAction( action );
break;
}
}
QAction *toggleAction = m_contextMenu->addAction( tr("&Ratio Scale"), this,
SLOT(toggleRatioScaleVisibility()) );
toggleAction->setCheckable( true );
toggleAction->setChecked( m_showRatioScale );
m_contextMenu->addAction(m_minimizeAction);
}
Q_ASSERT( m_contextMenu );
m_contextMenu->exec( w->mapToGlobal( e->pos() ) );
}
void MapScaleFloatItem::toolTipEvent( QHelpEvent *e )
{
QToolTip::showText( e->globalPos(), m_ratioString );
}
void MapScaleFloatItem::readSettings()
{
if ( !m_configDialog )
return;
if ( m_showRatioScale ) {
ui_configWidget->m_showRatioScaleCheckBox->setCheckState( Qt::Checked );
} else {
ui_configWidget->m_showRatioScaleCheckBox->setCheckState( Qt::Unchecked );
}
ui_configWidget->m_minimizeCheckBox->setChecked(m_minimized);
}
void MapScaleFloatItem::writeSettings()
{
if ( ui_configWidget->m_showRatioScaleCheckBox->checkState() == Qt::Checked ) {
m_showRatioScale = true;
} else {
m_showRatioScale = false;
}
if (m_minimized != ui_configWidget->m_minimizeCheckBox->isChecked()) {
toggleMinimized();
}
emit settingsChanged( nameId() );
}
void MapScaleFloatItem::toggleRatioScaleVisibility()
{
m_showRatioScale = !m_showRatioScale;
readSettings();
emit settingsChanged( nameId() );
}
void MapScaleFloatItem::toggleMinimized()
{
m_minimized = !m_minimized;
ui_configWidget->m_minimizeCheckBox->setChecked(m_minimized);
m_minimizeAction->setChecked(m_minimized);
readSettings();
emit settingsChanged( nameId() );
if (m_minimized == true) {
m_widthScaleFactor = 4;
} else {
m_widthScaleFactor = 2;
}
}
}
#include "moc_MapScaleFloatItem.cpp"
diff --git a/src/plugins/render/mapscale/MapScaleFloatItem.h b/src/plugins/render/mapscale/MapScaleFloatItem.h
index 47e50cf74..4f9892fb3 100644
--- a/src/plugins/render/mapscale/MapScaleFloatItem.h
+++ b/src/plugins/render/mapscale/MapScaleFloatItem.h
@@ -1,118 +1,118 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
//
#ifndef MAPSCALEFLOATITEM_H
#define MAPSCALEFLOATITEM_H
#include "AbstractFloatItem.h"
#include "DialogConfigurationInterface.h"
namespace Ui
{
class MapScaleConfigWidget;
}
namespace Marble
{
/**
* @short The class that creates a map scale.
*
*/
class MapScaleFloatItem : public AbstractFloatItem, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.MapScaleFloatItem")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN( MapScaleFloatItem )
public:
- explicit MapScaleFloatItem( const MarbleModel *marbleModel = 0 );
+ explicit MapScaleFloatItem( const MarbleModel *marbleModel = nullptr );
~MapScaleFloatItem() override;
QStringList backendTypes() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
void setProjection( const ViewportParams *viewport ) override;
void paintContent( QPainter *painter ) override;
QDialog *configDialog() override;
protected:
void contextMenuEvent( QWidget *w, QContextMenuEvent *e ) override;
void toolTipEvent( QHelpEvent *e ) override;
private Q_SLOTS:
void readSettings();
void writeSettings();
void toggleRatioScaleVisibility();
void toggleMinimized();
private:
void calcScaleBar();
private:
QDialog *m_configDialog;
Ui::MapScaleConfigWidget *ui_configWidget;
int m_radius;
QString m_target;
int m_leftBarMargin;
int m_rightBarMargin;
int m_scaleBarWidth;
int m_viewportWidth;
int m_scaleBarHeight;
qreal m_scaleBarDistance;
qreal m_pixel2Length;
int m_bestDivisor;
int m_pixelInterval;
int m_valueInterval;
QString m_ratioString;
bool m_scaleInitDone;
bool m_showRatioScale;
QMenu* m_contextMenu;
QAction *m_minimizeAction;
bool m_minimized;
int m_widthScaleFactor;
};
}
#endif // MAPSCALEFLOATITEM_H
diff --git a/src/plugins/render/measure/MeasureConfigDialog.h b/src/plugins/render/measure/MeasureConfigDialog.h
index f61314967..6f017c8bf 100644
--- a/src/plugins/render/measure/MeasureConfigDialog.h
+++ b/src/plugins/render/measure/MeasureConfigDialog.h
@@ -1,59 +1,59 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
#ifndef MEASURECONFIGDIALOG_H
#define MEASURECONFIGDIALOG_H
#include <QDialog>
#include "ui_MeasureConfigDialog.h"
#include "MeasureToolPlugin.h"
namespace Marble {
class MeasureConfigDialog : public QDialog
{
Q_OBJECT
public:
- explicit MeasureConfigDialog(QDialog *parent = 0);
+ explicit MeasureConfigDialog(QDialog *parent = nullptr);
~MeasureConfigDialog() override;
bool showBearingLabel() const;
bool showBearingLabelChange() const;
bool showDistanceLabels() const;
bool showRadius() const;
bool showPerimeter() const;
bool showCircumference() const;
bool showPolygonArea() const;
bool showCircularArea() const;
MeasureToolPlugin::PaintMode paintMode() const;
void setShowBearingLabel(bool);
void setShowBearingLabelChange(bool);
void setShowDistanceLabels(bool);
void setShowRadius(bool);
void setShowPerimeter(bool);
void setShowCircumference(bool);
void setShowPolygonArea(bool);
void setShowCircularArea(bool);
void setPaintMode(MeasureToolPlugin::PaintMode);
private Q_SLOTS:
void updateTabs();
Q_SIGNALS:
void applied();
private:
Ui::MeasureConfigDialog *ui;
};
} // namespace Marble
#endif // MEASURECONFIGDIALOG_H
diff --git a/src/plugins/render/measure/MeasureToolPlugin.cpp b/src/plugins/render/measure/MeasureToolPlugin.cpp
index 93e9f2096..a7ebcc4d1 100644
--- a/src/plugins/render/measure/MeasureToolPlugin.cpp
+++ b/src/plugins/render/measure/MeasureToolPlugin.cpp
@@ -1,705 +1,705 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007-2008 Inge Wallin <ingwa@kde.org>
// Copyright 2007-2008 Carlos Licea <carlos.licea@kdemail.net>
// Copyright 2011 Michael Henning <mikehenning@eclipse.net>
// Copyright 2011 Valery Kharitonov <kharvd@gmail.com>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "MeasureToolPlugin.h"
#include "MeasureConfigDialog.h"
#include "GeoPainter.h"
#include "GeoDataLinearRing.h"
#include "MarbleDebug.h"
#include "MarbleWidgetPopupMenu.h"
#include "MarbleModel.h"
#include "MarbleLocale.h"
#include "ViewportParams.h"
#include "Planet.h"
#include <QDialog>
#include <QColor>
#include <QTextDocument>
#include <qmath.h>
namespace Marble
{
MeasureToolPlugin::MeasureToolPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
m_measureLineString( GeoDataLineString( Tessellate ) ),
#ifdef Q_OS_MACX
m_font_regular( QFont( QStringLiteral( "Sans Serif" ), 10, 50, false ) ),
#else
m_font_regular( QFont( QStringLiteral( "Sans Serif" ), 8, 50, false ) ),
#endif
m_fontascent(-1),
m_pen( Qt::red ),
- m_addMeasurePointAction( 0 ),
- m_removeLastMeasurePointAction( 0 ),
- m_removeMeasurePointsAction( 0 ),
- m_separator( 0 ),
- m_marbleWidget( 0 ),
- m_configDialog( 0 ),
+ m_addMeasurePointAction( nullptr ),
+ m_removeLastMeasurePointAction( nullptr ),
+ m_removeMeasurePointsAction( nullptr ),
+ m_separator( nullptr ),
+ m_marbleWidget( nullptr ),
+ m_configDialog( nullptr ),
m_showDistanceLabel( true ),
m_showBearingLabel( true ),
m_showBearingChangeLabel( true ),
m_showPolygonArea(false),
m_showCircularArea(true),
m_showRadius(true),
m_showPerimeter(true),
m_showCircumference(true),
m_totalDistance(0.0),
m_polygonArea(0.0),
m_circularArea(0.0),
m_radius(0.0),
m_perimeter(0.0),
m_circumference(0.0),
m_paintMode(Polygon)
{
m_pen.setWidthF( 2.0 );
}
QStringList MeasureToolPlugin::backendTypes() const
{
return QStringList(QStringLiteral("measuretool"));
}
QString MeasureToolPlugin::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList MeasureToolPlugin::renderPosition() const
{
return QStringList(QStringLiteral("ATMOSPHERE"));
}
QString MeasureToolPlugin::name() const
{
return tr( "Measure Tool" );
}
QString MeasureToolPlugin::guiString() const
{
return tr( "&Measure Tool" );
}
QString MeasureToolPlugin::nameId() const
{
return QStringLiteral("measure-tool");
}
QString MeasureToolPlugin::version() const
{
return QStringLiteral("1.0");
}
QString MeasureToolPlugin::description() const
{
return tr( "Measure distances between two or more points." );
}
QString MeasureToolPlugin::copyrightYears() const
{
return QStringLiteral("2006-2008, 2011");
}
QVector<PluginAuthor> MeasureToolPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"))
<< PluginAuthor(QStringLiteral("Inge Wallin"), QStringLiteral("ingwa@kde.org"))
<< PluginAuthor(QStringLiteral("Carlos Licea"), QStringLiteral("carlos.licea@kdemail.net"))
<< PluginAuthor(QStringLiteral("Michael Henning"), QStringLiteral("mikehenning@eclipse.net"))
<< PluginAuthor(QStringLiteral("Valery Kharitonov"), QStringLiteral("kharvd@gmail.com"))
<< PluginAuthor(QStringLiteral("Mohammed Nafees"), QStringLiteral("nafees.technocool@gmail.com"))
<< PluginAuthor(QStringLiteral("Illya Kovalevskyy"), QStringLiteral("illya.kovalevskyy@gmail.com"));
}
QIcon MeasureToolPlugin::icon () const
{
return QIcon(QStringLiteral(":/icons/measure.png"));
}
void MeasureToolPlugin::initialize ()
{
m_fontascent = QFontMetrics( m_font_regular ).ascent();
}
bool MeasureToolPlugin::isInitialized () const
{
return m_fontascent >= 0;
}
QDialog *MeasureToolPlugin::configDialog()
{
if ( !m_configDialog ) {
m_configDialog = new MeasureConfigDialog(m_configDialog);
connect( m_configDialog, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( m_configDialog, SIGNAL(applied()),
this, SLOT(writeSettings()) );
}
m_configDialog->setShowDistanceLabels( m_showDistanceLabel );
m_configDialog->setShowBearingLabel( m_showBearingLabel );
m_configDialog->setShowBearingLabelChange( m_showBearingChangeLabel );
m_configDialog->setShowPolygonArea( m_showPolygonArea );
m_configDialog->setShowCircularArea( m_showCircularArea );
m_configDialog->setShowRadius( m_showRadius );
m_configDialog->setShowPerimeter( m_showPerimeter );
m_configDialog->setShowCircumference( m_showCircumference );
m_configDialog->setPaintMode( m_paintMode );
return m_configDialog;
}
QHash<QString,QVariant> MeasureToolPlugin::settings() const
{
QHash<QString, QVariant> settings = RenderPlugin::settings();
settings.insert(QStringLiteral("showDistanceLabel"), m_showDistanceLabel);
settings.insert(QStringLiteral("showBearingLabel"), m_showBearingLabel);
settings.insert(QStringLiteral("showBearingChangeLabel"), m_showBearingChangeLabel);
settings.insert(QStringLiteral("showPolygonArea"), m_showPolygonArea);
settings.insert(QStringLiteral("showCircularArea"), m_showCircularArea);
settings.insert(QStringLiteral("showRadius"), m_showRadius);
settings.insert(QStringLiteral("showPerimeter"), m_showPerimeter);
settings.insert(QStringLiteral("showCircumference"), m_showCircumference);
settings.insert(QStringLiteral("paintMode"), (int)m_paintMode);
return settings;
}
void MeasureToolPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
RenderPlugin::setSettings( settings );
m_showDistanceLabel = settings.value(QStringLiteral("showDistanceLabel"), true).toBool();
m_showBearingLabel = settings.value(QStringLiteral("showBearingLabel"), true).toBool();
m_showBearingChangeLabel = settings.value(QStringLiteral("showBearingChangeLabel"), true).toBool();
m_showPolygonArea = settings.value(QStringLiteral("showPolygonArea"), false).toBool();
m_showCircularArea = settings.value(QStringLiteral("showCircularArea"), true).toBool();
m_showRadius = settings.value(QStringLiteral("showRadius"), true).toBool();
m_showPerimeter = settings.value(QStringLiteral("showPerimeter"), true).toBool();
m_showCircumference = settings.value(QStringLiteral("showCircumference"), true).toBool();
m_paintMode = (PaintMode)settings.value(QStringLiteral("paintMode"), 0).toInt();
}
void MeasureToolPlugin::writeSettings()
{
m_showDistanceLabel = m_configDialog->showDistanceLabels();
m_showBearingLabel = m_configDialog->showBearingLabel();
m_showBearingChangeLabel = m_configDialog->showBearingLabelChange();
m_showPolygonArea = m_configDialog->showPolygonArea();
m_showCircularArea = m_configDialog->showCircularArea();
m_showRadius = m_configDialog->showRadius();
m_showPerimeter = m_configDialog->showPerimeter();
m_showCircumference = m_configDialog->showCircumference();
m_paintMode = (PaintMode)m_configDialog->paintMode();
if (m_paintMode == Circular) {
if (m_measureLineString.size() < 2) {
m_addMeasurePointAction->setEnabled(true);
} else {
m_addMeasurePointAction->setEnabled(false);
while (m_measureLineString.size() > 2)
m_measureLineString.remove(m_measureLineString.size()-1);
}
} else {
m_addMeasurePointAction->setEnabled(true);
}
emit settingsChanged( nameId() );
emit repaintNeeded();
}
bool MeasureToolPlugin::render( GeoPainter *painter,
ViewportParams *viewport,
const QString& renderPos,
GeoSceneLayer * layer )
{
Q_UNUSED(renderPos)
Q_UNUSED(layer)
m_latLonAltBox = viewport->viewLatLonAltBox();
// No way to paint anything if the list is empty.
if ( m_measureLineString.isEmpty() )
return true;
painter->save();
// Prepare for painting the measure line string and paint it.
painter->setPen( m_pen );
if ( m_showDistanceLabel || m_showBearingLabel || m_showBearingChangeLabel ) {
drawSegments( painter );
} else {
painter->drawPolyline( m_measureLineString );
}
// Paint the nodes of the paths.
drawMeasurePoints( painter );
m_totalDistance = m_measureLineString.length( marbleModel()->planet()->radius() );
if ( m_measureLineString.size() > 1 )
drawInfobox(painter);
painter->restore();
return true;
}
void MeasureToolPlugin::drawSegments( GeoPainter* painter )
{
for ( int segmentIndex = 0; segmentIndex < m_measureLineString.size() - 1; ++segmentIndex ) {
GeoDataLineString segment( Tessellate );
segment << m_measureLineString[segmentIndex] ;
segment << m_measureLineString[segmentIndex + 1];
QPen shadowPen( Oxygen::aluminumGray5 );
shadowPen.setWidthF(4.0);
painter->setPen( shadowPen );
painter->drawPolyline( segment );
QString infoString;
if ( (m_paintMode == Polygon && m_showDistanceLabel)
|| (m_paintMode == Circular && m_showRadius) ) {
const qreal segmentLength = segment.length( marbleModel()->planet()->radius() );
m_radius = segmentLength;
infoString = meterToPreferredUnit(segmentLength);
}
if ( m_showBearingLabel && m_paintMode != Circular ) {
GeoDataCoordinates coordinates = segment.first();
qreal bearing = coordinates.bearing( segment.last(), GeoDataCoordinates::Degree );
if ( bearing < 0 ) {
bearing += 360;
}
QString bearingString = QString::fromUtf8( "%1°" ).arg( bearing, 0, 'f', 2 );
if ( !infoString.isEmpty() ) {
infoString += QLatin1Char('\n');
}
infoString.append( bearingString );
}
if ( m_showBearingChangeLabel && segmentIndex != 0 ) {
GeoDataCoordinates currentCoordinates = m_measureLineString[segmentIndex];
qreal currentBearing = currentCoordinates.bearing(m_measureLineString[segmentIndex+1]);
qreal previousBearing = currentCoordinates.bearing( m_measureLineString[segmentIndex-1]);
GeoDataLinearRing ring;
painter->setPen( Qt::NoPen );
painter->setBrush( QBrush ( QColor ( 127, 127, 127, 127 ) ) );
if (currentBearing < previousBearing) currentBearing += 2 * M_PI;
ring << currentCoordinates;
qreal angleLength = qAbs(m_latLonAltBox.north() - m_latLonAltBox.south()) / 20;
qreal iterBearing = previousBearing;
while ( iterBearing < currentBearing ) {
ring << currentCoordinates.moveByBearing( iterBearing, angleLength );;
iterBearing += 0.1;
}
ring << currentCoordinates.moveByBearing( currentBearing, angleLength );;
painter->drawPolygon( ring );
qreal currentBearingChange = (currentBearing - previousBearing) * RAD2DEG;
if (currentBearingChange < 0) currentBearingChange += 360;
QString bearingChangedString = QString::fromUtf8( "%1°" ).arg( currentBearingChange, 0, 'f', 2 );
painter->setPen( Qt::black );
GeoDataCoordinates textPosition = ring.latLonAltBox().center();
qreal deltaEast = ring.latLonAltBox().east() - currentCoordinates.longitude();
qreal deltaWest = currentCoordinates.longitude() - ring.latLonAltBox().west();
if (deltaEast > deltaWest) {
textPosition.setLongitude(currentCoordinates.longitude() + deltaEast / 2);
}
else {
textPosition.setLongitude(currentCoordinates.longitude() - deltaWest);
}
painter->drawText(textPosition, bearingChangedString );
}
// Drawing ellipse around 1st point towards the 2nd
if ( m_paintMode == Circular ) {
GeoDataCoordinates currentCoordinates = m_measureLineString[segmentIndex];
GeoDataLinearRing ring;
// planetRadius - planet radius
// d - distance between points
// S - area of the painted circle
qreal planetRadius = marbleModel()->planet()->radius();
qreal d = m_measureLineString.length(1);
m_circularArea = 2 * M_PI * planetRadius * planetRadius * (1 - qCos(d));
qreal iterBearing = 0;
while ( iterBearing < 2 * M_PI ) {
ring << currentCoordinates.moveByBearing(iterBearing, d);
iterBearing += 0.1;
}
painter->setPen( Qt::NoPen );
painter->setBrush( QBrush ( QColor ( 127, 127, 127, 127 ) ) );
painter->drawPolygon(ring);
if ( m_showCircularArea ) {
painter->setPen(Qt::white);
GeoDataCoordinates textPosition = ring.latLonAltBox().center();
QString areaText = tr("Area:\n%1").arg(meterToPreferredUnit(m_circularArea, true));
QFontMetrics fontMetrics = painter->fontMetrics();
QRect boundingRect = fontMetrics.boundingRect(QRect(), Qt::AlignCenter, areaText);
painter->drawText(textPosition,
areaText,
-boundingRect.width()/2, -boundingRect.height()*1.5,
boundingRect.width(), boundingRect.height(),
QTextOption(Qt::AlignCenter));
}
if ( m_showCircumference ) {
painter->setPen(Qt::white);
GeoDataCoordinates textPosition = ring.latLonAltBox().center();
m_circumference = 2 * M_PI * planetRadius * qSin(d);
QString circumferenceText = tr("Circumference:\n%1").arg(meterToPreferredUnit(m_circumference));
QFontMetrics fontMetrics = painter->fontMetrics();
QRect boundingRect = fontMetrics.boundingRect(QRect(),Qt::AlignCenter,
circumferenceText);
painter->drawText(textPosition,
circumferenceText,
-boundingRect.width()/2, boundingRect.height(),
boundingRect.width(), boundingRect.height(),
QTextOption(Qt::AlignCenter));
}
}
if ( !infoString.isEmpty() ) {
QPen linePen;
// have three alternating colors for the segments
switch ( segmentIndex % 3 ) {
case 0:
linePen.setColor( Oxygen::brickRed4 );
break;
case 1:
linePen.setColor( Oxygen::forestGreen4 );
break;
case 2:
linePen.setColor( Oxygen::skyBlue4 );
break;
}
linePen.setWidthF(2.0);
painter->setPen( linePen );
painter->drawPolyline( segment, infoString, LineCenter );
}
}
if (m_paintMode == Polygon && m_measureLineString.size() > 2) {
GeoDataLinearRing measureRing(m_measureLineString);
if (m_showPolygonArea || m_showPerimeter) {
painter->setPen( Qt::NoPen );
painter->setBrush( QBrush ( QColor ( 127, 127, 127, 127 ) ) );
painter->drawPolygon(measureRing);
QPen shadowPen( Oxygen::aluminumGray5 );
shadowPen.setStyle(Qt::DashLine);
shadowPen.setWidthF(3.0);
painter->setPen( shadowPen );
painter->drawPolyline(GeoDataLineString( Tessellate ) << m_measureLineString.first()
<< m_measureLineString.last());
}
if (m_showPolygonArea) {
qreal theta1 = 0.0;
qreal n = m_measureLineString.size();
for (int segmentIndex = 1; segmentIndex < m_measureLineString.size()-1; segmentIndex++) {
GeoDataCoordinates current = m_measureLineString[segmentIndex];
qreal prevBearing = current.bearing(m_measureLineString[segmentIndex-1]);
qreal nextBearing = current.bearing(m_measureLineString[segmentIndex+1]);
if (nextBearing < prevBearing)
nextBearing += 2 * M_PI;
qreal angle = nextBearing - prevBearing;
theta1 += angle;
}
// Traversing first vertex
GeoDataCoordinates current = m_measureLineString[0];
qreal prevBearing = current.bearing(m_measureLineString[n-1]);
qreal nextBearing = current.bearing(m_measureLineString[1]);
if (nextBearing < prevBearing)
nextBearing += 2 * M_PI;
qreal angle = nextBearing - prevBearing;
theta1 += angle;
// And the last one
current = m_measureLineString[n-1];
prevBearing = current.bearing(m_measureLineString[n-2]);
nextBearing = current.bearing(m_measureLineString[0]);
if (nextBearing < prevBearing)
nextBearing += 2 * M_PI;
angle = nextBearing - prevBearing;
theta1 += angle;
qreal theta2 = 2 * M_PI * n - theta1;
// theta = smaller of theta1 and theta2
qreal theta = (theta1 < theta2) ? theta1 : theta2;
qreal planetRadius = marbleModel()->planet()->radius();
qreal S = qAbs((theta - (n-2) * M_PI) * planetRadius * planetRadius);
m_polygonArea = S;
painter->setPen(Qt::white);
GeoDataCoordinates textPosition = measureRing.latLonAltBox().center();
QString areaText = tr("Area:\n%1").arg(meterToPreferredUnit(S, true));
QFontMetrics fontMetrics = painter->fontMetrics();
QRect boundingRect = fontMetrics.boundingRect(QRect(), Qt::AlignCenter, areaText);
painter->drawText(textPosition,
areaText,
-boundingRect.width()/2, -(boundingRect.height()+fontMetrics.height()*0.25),
boundingRect.width(), boundingRect.height(),
QTextOption(Qt::AlignCenter));
}
if (m_showPerimeter) {
painter->setPen(Qt::white);
GeoDataCoordinates textPosition = measureRing.latLonAltBox().center();
qreal P = measureRing.length(marbleModel()->planet()->radius());
m_perimeter = P;
QString perimeterText = tr("Perimeter:\n%1").arg(meterToPreferredUnit(P));
QFontMetrics fontMetrics = painter->fontMetrics();
QRect boundingRect = fontMetrics.boundingRect(QRect(),Qt::AlignCenter,
perimeterText);
painter->drawText(textPosition,
perimeterText,
-boundingRect.width()/2, 0,
boundingRect.width(), boundingRect.height(),
QTextOption(Qt::AlignCenter));
}
}
}
QString MeasureToolPlugin::meterToPreferredUnit(qreal meters, bool isSquare)
{
MarbleLocale *locale = MarbleGlobal::getInstance()->locale();
const MarbleLocale::MeasurementSystem measurementSystem = locale->measurementSystem();
MarbleLocale::MeasureUnit unit;
qreal convertedMeters;
if (isSquare)
meters = qSqrt(meters);
locale->meterToTargetUnit(meters, measurementSystem, convertedMeters, unit);
QString unitString = locale->unitAbbreviation(unit);
if (isSquare) {
qreal k = convertedMeters/meters;
convertedMeters *= k;
convertedMeters *= meters;
unitString.append(QChar(0xB2));
}
return QString("%L1 %2").arg(convertedMeters, 8, 'f', 1, QLatin1Char(' '))
.arg(unitString);
}
void MeasureToolPlugin::drawMeasurePoints( GeoPainter *painter )
{
// Paint the marks.
GeoDataLineString::const_iterator itpoint = m_measureLineString.constBegin();
GeoDataLineString::const_iterator const endpoint = m_measureLineString.constEnd();
if (m_mark.isNull()) {
m_mark = QPixmap(QStringLiteral(":/mark.png"));
}
for (; itpoint != endpoint; ++itpoint )
{
painter->drawPixmap( *itpoint, m_mark );
}
}
void MeasureToolPlugin::drawInfobox( GeoPainter *painter ) const
{
QString boxContent;
if (m_paintMode == Polygon) {
boxContent += QLatin1String("<strong>") + tr("Polygon Ruler") + QLatin1String(":</strong><br/>\n");
} else /* Circular */ {
boxContent += QLatin1String("<strong>") + tr("Circle Ruler") + QLatin1String(":</strong><br/>\n");
}
if (m_paintMode == Polygon) {
boxContent += tr("Total Distance: %1<br/>\n").arg( meterToPreferredUnit(m_totalDistance) );
if (m_showPolygonArea)
boxContent += tr("Area: %1<br/>\n").arg( meterToPreferredUnit(m_polygonArea, true) );
if (m_showPerimeter)
boxContent += tr("Perimeter: %1<br/>\n").arg( meterToPreferredUnit(m_perimeter) );
} else /* Circular */ {
if (m_showRadius)
boxContent += tr("Radius: %1<br/>\n").arg( meterToPreferredUnit(m_radius) );
if (m_showCircumference)
boxContent += tr("Circumference: %1<br/>\n").arg( meterToPreferredUnit(m_circumference) );
if (m_showCircularArea)
boxContent += tr("Area: %1<br/>\n").arg( meterToPreferredUnit(m_circularArea, true) );
}
painter->setPen( QColor( Qt::black ) );
painter->setBrush( QColor( 192, 192, 192, 192 ) );
QTextDocument doc;
doc.setHtml(boxContent);
doc.setDefaultFont(m_font_regular);
doc.adjustSize();
QSizeF pageSize = doc.size();
painter->drawRect( 10, 105, 10 + pageSize.width(), pageSize.height() );
QTransform transform;
transform.translate(15, 110);
painter->setTransform(transform);
doc.drawContents(painter);
painter->setTransform(QTransform());
}
void MeasureToolPlugin::addMeasurePoint( qreal lon, qreal lat )
{
m_measureLineString << GeoDataCoordinates( lon, lat );
emit numberOfMeasurePointsChanged( m_measureLineString.size() );
}
void MeasureToolPlugin::removeLastMeasurePoint()
{
if (!m_measureLineString.isEmpty())
m_measureLineString.remove( m_measureLineString.size() - 1 );
emit numberOfMeasurePointsChanged( m_measureLineString.size() );
}
void MeasureToolPlugin::removeMeasurePoints()
{
m_measureLineString.clear();
emit numberOfMeasurePointsChanged( m_measureLineString.size() );
}
void MeasureToolPlugin::addContextItems()
{
MarbleWidgetPopupMenu *menu = m_marbleWidget->popupMenu();
// Connect the inputHandler and the measure tool to the popup menu
m_addMeasurePointAction = new QAction(QIcon(QStringLiteral(":/icons/measure.png")), tr("Add &Measure Point"), this);
m_removeLastMeasurePointAction = new QAction( tr( "Remove &Last Measure Point" ), this );
m_removeLastMeasurePointAction->setEnabled( false );
m_removeMeasurePointsAction = new QAction( tr( "&Remove Measure Points" ), this );
m_removeMeasurePointsAction->setEnabled( false );
m_separator = new QAction( this );
m_separator->setSeparator( true );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( !smallScreen ) {
menu->addAction( Qt::RightButton, m_addMeasurePointAction );
menu->addAction( Qt::RightButton, m_removeLastMeasurePointAction );
menu->addAction( Qt::RightButton, m_removeMeasurePointsAction );
menu->addAction( Qt::RightButton, m_separator );
}
connect( m_addMeasurePointAction, SIGNAL(triggered()), SLOT(addMeasurePointEvent()) );
connect( m_removeLastMeasurePointAction, SIGNAL(triggered()), SLOT(removeLastMeasurePoint()) );
connect( m_removeMeasurePointsAction, SIGNAL(triggered()), SLOT(removeMeasurePoints()) );
connect( this, SIGNAL(numberOfMeasurePointsChanged(int)), SLOT(setNumberOfMeasurePoints(int)) );
}
void MeasureToolPlugin::removeContextItems()
{
delete m_addMeasurePointAction;
delete m_removeLastMeasurePointAction;
delete m_removeMeasurePointsAction;
delete m_separator;
}
void MeasureToolPlugin::addMeasurePointEvent()
{
QPoint p = m_marbleWidget->popupMenu()->mousePosition();
qreal lat;
qreal lon;
m_marbleWidget->geoCoordinates( p.x(), p.y(), lon, lat, GeoDataCoordinates::Radian );
addMeasurePoint( lon, lat );
}
void MeasureToolPlugin::setNumberOfMeasurePoints( int newNumber )
{
const bool enableMeasureActions = ( newNumber > 0 );
m_removeMeasurePointsAction->setEnabled(enableMeasureActions);
m_removeLastMeasurePointAction->setEnabled(enableMeasureActions);
if (m_paintMode == Circular) {
if (newNumber >= 2) {
m_addMeasurePointAction->setEnabled(false);
} else {
m_addMeasurePointAction->setEnabled(true);
}
}
}
bool MeasureToolPlugin::eventFilter( QObject *object, QEvent *e )
{
if ( m_marbleWidget && !enabled() ) {
- m_marbleWidget = 0;
+ m_marbleWidget = nullptr;
removeContextItems();
m_measureLineString.clear();
}
if ( m_marbleWidget || !enabled() || !visible() ) {
return RenderPlugin::eventFilter( object, e );
}
MarbleWidget *widget = qobject_cast<MarbleWidget*>( object );
if ( widget ) {
m_marbleWidget = widget;
addContextItems();
}
return RenderPlugin::eventFilter( object, e );
}
}
#include "moc_MeasureToolPlugin.cpp"
diff --git a/src/plugins/render/measure/MeasureToolPlugin.h b/src/plugins/render/measure/MeasureToolPlugin.h
index 7ae60f4f8..92aba7a15 100644
--- a/src/plugins/render/measure/MeasureToolPlugin.h
+++ b/src/plugins/render/measure/MeasureToolPlugin.h
@@ -1,147 +1,147 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007 Inge Wallin <ingwa@kde.org>
// Copyright 2011 Michael Henning <mikehenning@eclipse.net>
//
//
// MeasureToolPlugin enables Marble to set and display measure points
//
#ifndef MARBLE_MEASURETOOLPLUGIN_H
#define MARBLE_MEASURETOOLPLUGIN_H
#include "DialogConfigurationInterface.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataLineString.h"
#include "RenderPlugin.h"
#include "MarbleWidget.h"
#include <QFont>
#include <QPen>
#include <QAction>
#include <QPixmap>
namespace Marble
{
class MeasureConfigDialog;
class MeasureToolPlugin : public RenderPlugin, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.MeasureToolPlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN( MeasureToolPlugin )
public:
- explicit MeasureToolPlugin( const MarbleModel *marbleModel = 0 );
+ explicit MeasureToolPlugin( const MarbleModel *marbleModel = nullptr );
enum PaintMode {
Polygon = 0,
Circular
};
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
- bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
QDialog *configDialog() override;
QHash<QString,QVariant> settings() const override;
void setSettings( const QHash<QString,QVariant> &settings ) override;
Q_SIGNALS:
void numberOfMeasurePointsChanged( int newNumber );
public Q_SLOTS:
bool eventFilter( QObject *object, QEvent *event ) override;
private:
void drawMeasurePoints( GeoPainter *painter );
void drawInfobox( GeoPainter *painter ) const;
void drawSegments( GeoPainter *painter );
void addContextItems();
void removeContextItems();
private Q_SLOTS:
void setNumberOfMeasurePoints( int number );
void addMeasurePointEvent();
void addMeasurePoint( qreal lon, qreal lat );
void removeLastMeasurePoint();
void removeMeasurePoints();
void writeSettings();
private:
Q_DISABLE_COPY( MeasureToolPlugin )
static QString meterToPreferredUnit(qreal meters, bool isSquare = false);
// The line strings in the distance path.
GeoDataLineString m_measureLineString;
GeoDataLatLonAltBox m_latLonAltBox;
QPixmap m_mark;
QFont m_font_regular;
int m_fontascent;
QPen m_pen;
QAction *m_addMeasurePointAction;
QAction *m_removeLastMeasurePointAction;
QAction *m_removeMeasurePointsAction;
QAction *m_separator;
MarbleWidget* m_marbleWidget;
MeasureConfigDialog *m_configDialog;
bool m_showDistanceLabel;
bool m_showBearingLabel;
bool m_showBearingChangeLabel;
bool m_showPolygonArea;
bool m_showCircularArea;
bool m_showRadius;
bool m_showPerimeter;
bool m_showCircumference;
qreal m_totalDistance;
qreal m_polygonArea;
qreal m_circularArea;
qreal m_radius;
qreal m_perimeter;
qreal m_circumference;
PaintMode m_paintMode;
};
}
#endif // MARBLE_MEASURETOOLPLUGIN_H
diff --git a/src/plugins/render/navigation/ArrowDiscWidget.cpp b/src/plugins/render/navigation/ArrowDiscWidget.cpp
index 476ff73d9..714a14b34 100644
--- a/src/plugins/render/navigation/ArrowDiscWidget.cpp
+++ b/src/plugins/render/navigation/ArrowDiscWidget.cpp
@@ -1,234 +1,234 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "ArrowDiscWidget.h"
#include "MarbleWidget.h"
#include <qmath.h>
#include <QPainter>
#include <QMouseEvent>
#include <QPixmapCache>
namespace Marble
{
ArrowDiscWidget::ArrowDiscWidget( QWidget *parent ) :
QWidget( parent ),
m_arrowPressed( Qt::NoArrow ),
m_repetitions( 0 ),
- m_marbleWidget( 0 ),
+ m_marbleWidget( nullptr ),
m_imagePath( "marble/navigation/navigational_arrows" )
{
setMouseTracking( true );
m_initialPressTimer.setSingleShot( true );
connect( &m_initialPressTimer, SIGNAL(timeout()), SLOT(startPressRepeat()) );
connect( &m_repeatPressTimer, SIGNAL(timeout()), SLOT(repeatPress()) );
}
ArrowDiscWidget::~ArrowDiscWidget()
{
QPixmapCache::remove( "marble/navigation/navigational_arrows" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_hover_bottom" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_hover_left" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_hover_right" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_hover_top" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_press_bottom" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_press_left" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_press_right" );
QPixmapCache::remove( "marble/navigation/navigational_arrows_press_top" );
}
void ArrowDiscWidget::setMarbleWidget( MarbleWidget *marbleWidget )
{
m_marbleWidget = marbleWidget;
}
QPixmap ArrowDiscWidget::pixmap( const QString &id )
{
QPixmap result;
if ( !QPixmapCache::find( id, result ) ) {
result = QPixmap(QLatin1String(":/") + id + QLatin1String(".png"));
QPixmapCache::insert( id, result );
}
return result;
}
void ArrowDiscWidget::mousePressEvent( QMouseEvent *mouseEvent )
{
if ( mouseEvent->button() == Qt::LeftButton ) {
if ( !m_initialPressTimer.isActive() && !m_repeatPressTimer.isActive() ) {
m_repetitions = 0;
m_initialPressTimer.start( 300 );
}
m_arrowPressed = arrowUnderMouse( mouseEvent->pos() );
switch ( m_arrowPressed ) {
case Qt::NoArrow:
m_imagePath = "marble/navigation/navigational_arrows";
break;
case Qt::UpArrow:
m_imagePath = "marble/navigation/navigational_arrows_press_top";
m_marbleWidget->moveUp();
break;
case Qt::DownArrow:
m_imagePath = "marble/navigation/navigational_arrows_press_bottom";
m_marbleWidget->moveDown();
break;
case Qt::LeftArrow:
m_imagePath = "marble/navigation/navigational_arrows_press_left";
m_marbleWidget->moveLeft();
break;
case Qt::RightArrow:
m_imagePath = "marble/navigation/navigational_arrows_press_right";
m_marbleWidget->moveRight();
break;
}
}
repaint();
}
void ArrowDiscWidget::mouseReleaseEvent( QMouseEvent *mouseEvent )
{
m_initialPressTimer.stop();
m_repeatPressTimer.stop();
mouseMoveEvent( mouseEvent );
}
void ArrowDiscWidget::leaveEvent( QEvent* )
{
if (m_imagePath != QLatin1String("marble/navigation/navigational_arrows")) {
m_imagePath = "marble/navigation/navigational_arrows";
repaint();
}
m_initialPressTimer.stop();
m_repeatPressTimer.stop();
}
void ArrowDiscWidget::startPressRepeat()
{
repeatPress();
if ( m_arrowPressed != Qt::NoArrow ) {
m_repeatPressTimer.start( 100 );
}
}
void ArrowDiscWidget::repeatPress()
{
if ( m_repetitions <= 200 ) {
++m_repetitions;
switch ( m_arrowPressed ) {
case Qt::NoArrow:
break;
case Qt::UpArrow:
m_marbleWidget->moveUp();
break;
case Qt::DownArrow:
m_marbleWidget->moveDown();
break;
case Qt::LeftArrow:
m_marbleWidget->moveLeft();
break;
case Qt::RightArrow:
m_marbleWidget->moveRight();
break;
}
} else {
m_repeatPressTimer.stop();
}
}
void ArrowDiscWidget::mouseMoveEvent( QMouseEvent *mouseEvent )
{
QString const oldPath = m_imagePath;
switch ( arrowUnderMouse( mouseEvent->pos() ) ) {
case Qt::NoArrow:
m_imagePath = "marble/navigation/navigational_arrows";
break;
case Qt::UpArrow:
m_imagePath = "marble/navigation/navigational_arrows_hover_top";
m_arrowPressed = Qt::UpArrow;
break;
case Qt::DownArrow:
m_imagePath = "marble/navigation/navigational_arrows_hover_bottom";
m_arrowPressed = Qt::DownArrow;
break;
case Qt::LeftArrow:
m_imagePath = "marble/navigation/navigational_arrows_hover_left";
m_arrowPressed = Qt::LeftArrow;
break;
case Qt::RightArrow:
m_imagePath = "marble/navigation/navigational_arrows_hover_right";
m_arrowPressed = Qt::RightArrow;
break;
}
if ( m_imagePath != oldPath ) {
repaint();
}
}
void ArrowDiscWidget::repaint()
{
emit repaintNeeded();
}
Qt::ArrowType ArrowDiscWidget::arrowUnderMouse(const QPoint &position) const
{
const int min_radius_pow2 = 5*5;
const int max_radius_pow2 = 28*28;
// mouse coordinates relative to widget topleft
int mx = position.x();
int my = position.y();
// center coordinates relative to widget topleft
int cx = width()/2;
int cy = height()/2;
int px = mx - cx;
int py = my - cy;
int const distance_pow2 = px*px + py*py;
if ( distance_pow2 >= min_radius_pow2 && distance_pow2 <= max_radius_pow2 ) {
int const angle = int( qAtan2( py, px ) * RAD2DEG );
Q_ASSERT( -180 <= angle && angle <= 180 );
if ( angle >= 135 || angle < -135 ) {
return Qt::LeftArrow;
} else if ( angle < -45 ) {
return Qt::UpArrow;
} else if ( angle < 45 ) {
return Qt::RightArrow;
} else {
return Qt::DownArrow;
}
}
return Qt::NoArrow;
}
void ArrowDiscWidget::paintEvent( QPaintEvent * )
{
Q_ASSERT( !pixmap( m_imagePath ).isNull() );
QPainter painter( this );
painter.drawPixmap( 0, 0, pixmap( m_imagePath ) );
painter.end();
}
}
#include "moc_ArrowDiscWidget.cpp"
diff --git a/src/plugins/render/navigation/ArrowDiscWidget.h b/src/plugins/render/navigation/ArrowDiscWidget.h
index 71752a611..630293857 100644
--- a/src/plugins/render/navigation/ArrowDiscWidget.h
+++ b/src/plugins/render/navigation/ArrowDiscWidget.h
@@ -1,61 +1,61 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#ifndef ARROWDISCWIDGET_H
#define ARROWDISCWIDGET_H
#include <QWidget>
#include <QPixmap>
#include <QTimer>
namespace Marble
{
class MarbleWidget;
class ArrowDiscWidget : public QWidget
{
Q_OBJECT
public:
- explicit ArrowDiscWidget( QWidget *parent = 0 );
+ explicit ArrowDiscWidget( QWidget *parent = nullptr );
~ArrowDiscWidget() override;
void setMarbleWidget( MarbleWidget *marbleWidget );
Q_SIGNALS:
void repaintNeeded();
protected:
void paintEvent( QPaintEvent * ) override;
void mouseMoveEvent( QMouseEvent *mouseEvent ) override;
void mousePressEvent( QMouseEvent *mouseEvent ) override;
void mouseReleaseEvent( QMouseEvent *mouseEvent ) override;
void leaveEvent( QEvent *event ) override;
void repaint();
private Q_SLOTS:
void startPressRepeat();
void repeatPress();
private:
static QPixmap pixmap(const QString &id );
Qt::ArrowType arrowUnderMouse( const QPoint &position ) const;
QTimer m_initialPressTimer;
QTimer m_repeatPressTimer;
Qt::ArrowType m_arrowPressed;
int m_repetitions;
MarbleWidget *m_marbleWidget;
QString m_imagePath;
};
}
#endif
diff --git a/src/plugins/render/navigation/NavigationButton.h b/src/plugins/render/navigation/NavigationButton.h
index 37039faa2..18f4f1a5b 100644
--- a/src/plugins/render/navigation/NavigationButton.h
+++ b/src/plugins/render/navigation/NavigationButton.h
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#ifndef NAVIGATIONBUTTON_H
#define NAVIGATIONBUTTON_H
#include <QAbstractButton>
namespace Marble
{
class NavigationButton : public QAbstractButton
{
Q_OBJECT
public:
- explicit NavigationButton( QWidget *parent = 0 );
+ explicit NavigationButton( QWidget *parent = nullptr );
Q_SIGNALS:
void repaintNeeded();
protected:
void mousePressEvent ( QMouseEvent *mouseEvent ) override;
void mouseReleaseEvent ( QMouseEvent *mouseEvent ) override;
void enterEvent( QEvent * e) override;
void leaveEvent( QEvent * e) override;
void changeEvent( QEvent *e ) override;
void paintEvent( QPaintEvent * ) override;
private:
QIcon::Mode m_iconMode;
};
}
#endif
diff --git a/src/plugins/render/navigation/NavigationFloatItem.cpp b/src/plugins/render/navigation/NavigationFloatItem.cpp
index bcbc23b7e..15ee5df07 100644
--- a/src/plugins/render/navigation/NavigationFloatItem.cpp
+++ b/src/plugins/render/navigation/NavigationFloatItem.cpp
@@ -1,341 +1,341 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010 Bastian Holst <bastianholst@gmx.de>
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include "NavigationFloatItem.h"
#include <qmath.h>
#include <QContextMenuEvent>
#include <QRect>
#include <QSlider>
#include <QWidget>
#include <QPainter>
#include <QPixmapCache>
#include "ui_navigation.h"
#include "ViewportParams.h"
#include "MarbleDebug.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "PositionTracking.h"
#include "WidgetGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
using namespace Marble;
/* TRANSLATOR Marble::NavigationFloatItem */
NavigationFloatItem::NavigationFloatItem( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( -10, -30 ) ),
- m_marbleWidget( 0 ),
- m_widgetItem( 0 ),
- m_navigationWidget( 0 ),
+ m_marbleWidget( nullptr ),
+ m_widgetItem( nullptr ),
+ m_navigationWidget( nullptr ),
m_oldViewportRadius( 0 ),
- m_contextMenu( 0 ),
+ m_contextMenu( nullptr ),
m_showHomeButton( true )
{
// Plugin is visible by default on desktop systems
const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
setEnabled( !smallScreen );
setVisible( true );
setCacheMode( NoCache );
setBackground( QBrush( QColor( Qt::transparent ) ) );
setFrame( NoFrame );
}
NavigationFloatItem::~NavigationFloatItem()
{
delete m_navigationWidget;
}
QStringList NavigationFloatItem::backendTypes() const
{
return QStringList(QStringLiteral("navigation"));
}
QString NavigationFloatItem::name() const
{
return tr("Navigation");
}
QString NavigationFloatItem::guiString() const
{
return tr("&Navigation");
}
QString NavigationFloatItem::nameId() const
{
return QStringLiteral("navigation");
}
QString NavigationFloatItem::version() const
{
return QStringLiteral("1.0");
}
QString NavigationFloatItem::description() const
{
return tr("A mouse control to zoom and move the map");
}
QString NavigationFloatItem::copyrightYears() const
{
return QStringLiteral("2008, 2010, 2013");
}
QVector<PluginAuthor> NavigationFloatItem::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
<< PluginAuthor(QStringLiteral("Bastian Holst"), QStringLiteral("bastianholst@gmx.de"))
<< PluginAuthor(QStringLiteral("Mohammed Nafees"), QStringLiteral("nafees.technocool@gmail.com"));
}
QIcon NavigationFloatItem::icon() const
{
return QIcon(QStringLiteral(":/icons/navigation.png"));
}
void NavigationFloatItem::initialize()
{
- QWidget *navigationParent = new QWidget( 0 );
+ QWidget *navigationParent = new QWidget( nullptr );
navigationParent->setAttribute( Qt::WA_NoSystemBackground, true );
m_navigationWidget = new Ui::Navigation;
m_navigationWidget->setupUi( navigationParent );
m_widgetItem = new WidgetGraphicsItem( this );
m_widgetItem->setWidget( navigationParent );
MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
layout->addItem( m_widgetItem, 0, 0 );
setLayout( layout );
if ( m_showHomeButton ) {
activateHomeButton();
} else {
activateCurrentPositionButton();
}
}
bool NavigationFloatItem::isInitialized() const
{
return m_widgetItem;
}
void NavigationFloatItem::setProjection( const ViewportParams *viewport )
{
if ( viewport->radius() != m_oldViewportRadius ) {
m_oldViewportRadius = viewport->radius();
// The slider depends on the map state (zoom factor)
update();
}
AbstractFloatItem::setProjection( viewport );
}
bool NavigationFloatItem::eventFilter( QObject *object, QEvent *e )
{
if ( !enabled() || !visible() ) {
return false;
}
MarbleWidget *widget = dynamic_cast<MarbleWidget*> (object);
if ( !widget ) {
return AbstractFloatItem::eventFilter( object, e );
}
if ( m_marbleWidget != widget ) {
// Delayed initialization
m_marbleWidget = widget;
m_maxZoom = m_marbleWidget->maximumZoom();
m_minZoom = m_marbleWidget->minimumZoom();
m_navigationWidget->arrowDisc->setMarbleWidget( m_marbleWidget );
connect( m_navigationWidget->arrowDisc, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) );
connect( m_navigationWidget->homeButton, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) );
if ( m_showHomeButton ) {
activateHomeButton();
} else {
activateCurrentPositionButton();
}
connect( m_navigationWidget->zoomInButton, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) );
connect( m_navigationWidget->zoomInButton, SIGNAL(clicked()),
m_marbleWidget, SLOT(zoomIn()) );
m_navigationWidget->zoomSlider->setMaximum( m_maxZoom );
m_navigationWidget->zoomSlider->setMinimum( m_minZoom );
connect( m_navigationWidget->zoomSlider, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) );
connect( m_navigationWidget->zoomSlider, SIGNAL(valueChanged(int)),
m_marbleWidget, SLOT(setZoom(int)) );
connect( m_navigationWidget->zoomOutButton, SIGNAL(repaintNeeded()), SIGNAL(repaintNeeded()) );
connect( m_navigationWidget->zoomOutButton, SIGNAL(clicked()),
m_marbleWidget, SLOT(zoomOut()) );
connect( m_marbleWidget, SIGNAL(zoomChanged(int)), SLOT(updateButtons(int)) );
updateButtons( m_marbleWidget->zoom() );
connect( m_marbleWidget, SIGNAL(themeChanged(QString)), this, SLOT(selectTheme(QString)) );
}
return AbstractFloatItem::eventFilter(object, e);
}
void NavigationFloatItem::selectTheme( const QString& )
{
if ( m_marbleWidget ) {
m_maxZoom = m_marbleWidget->maximumZoom();
m_minZoom = m_marbleWidget->minimumZoom();
m_navigationWidget->zoomSlider->setMaximum( m_maxZoom );
m_navigationWidget->zoomSlider->setMinimum( m_minZoom );
updateButtons( m_marbleWidget->zoom() );
}
}
void NavigationFloatItem::updateButtons( int zoomValue )
{
bool const zoomInEnabled = m_navigationWidget->zoomInButton->isEnabled();
bool const zoomOutEnabled = m_navigationWidget->zoomOutButton->isEnabled();
int const oldZoomValue = m_navigationWidget->zoomSlider->value();
m_navigationWidget->zoomInButton->setEnabled( zoomValue < m_maxZoom );
m_navigationWidget->zoomOutButton->setEnabled( zoomValue > m_minZoom );
m_navigationWidget->zoomSlider->setValue( zoomValue );
if ( zoomInEnabled != m_navigationWidget->zoomInButton->isEnabled() ||
zoomOutEnabled != m_navigationWidget->zoomOutButton->isEnabled() ||
oldZoomValue != zoomValue ) {
update();
}
}
QPixmap NavigationFloatItem::pixmap( const QString &id )
{
QPixmap result;
if ( !QPixmapCache::find( id, result ) ) {
result = QPixmap(QLatin1String(":/") + id + QLatin1String(".png"));
QPixmapCache::insert( id, result );
}
return result;
}
void NavigationFloatItem::paintContent( QPainter *painter )
{
painter->drawPixmap( 0, 0, pixmap( "marble/navigation/navigational_backdrop_top" ) );
painter->drawPixmap( 0, 70, pixmap( "marble/navigation/navigational_backdrop_center" ) );
painter->drawPixmap( 0, 311, pixmap( "marble/navigation/navigational_backdrop_bottom" ) );
}
void NavigationFloatItem::contextMenuEvent( QWidget *w, QContextMenuEvent *e )
{
if ( !m_contextMenu ) {
m_contextMenu = contextMenu();
m_activateCurrentPositionButtonAction = new QAction( QIcon(),
tr( "Current Location Button" ),
m_contextMenu );
m_activateHomeButtonAction = new QAction(QIcon(QStringLiteral(":/icons/go-home.png")),
tr( "Home Button" ),
m_contextMenu );
m_activateHomeButtonAction->setVisible( !m_showHomeButton );
m_activateCurrentPositionButtonAction->setVisible( m_showHomeButton );
m_contextMenu->addSeparator();
m_contextMenu->addAction( m_activateCurrentPositionButtonAction );
m_contextMenu->addAction( m_activateHomeButtonAction );
connect( m_activateCurrentPositionButtonAction, SIGNAL(triggered()), SLOT(activateCurrentPositionButton()) );
connect( m_activateHomeButtonAction, SIGNAL(triggered()), SLOT(activateHomeButton()) );
}
Q_ASSERT( m_contextMenu );
m_contextMenu->exec( w->mapToGlobal( e->pos() ) );
}
void NavigationFloatItem::activateCurrentPositionButton()
{
if ( !isInitialized() ) {
return;
}
QIcon icon;
icon.addPixmap( pixmap("marble/navigation/navigational_currentlocation"), QIcon::Normal );
icon.addPixmap( pixmap("marble/navigation/navigational_currentlocation_hover"), QIcon::Active );
icon.addPixmap( pixmap("marble/navigation/navigational_currentlocation_pressed"), QIcon::Selected );
m_navigationWidget->homeButton->setProperty("icon", QVariant(icon));
if ( m_contextMenu ) {
m_activateCurrentPositionButtonAction->setVisible( false );
m_activateHomeButtonAction->setVisible( true );
}
if (m_marbleWidget) {
disconnect( m_navigationWidget->homeButton, SIGNAL(clicked()), m_marbleWidget, SLOT(goHome()) );
}
connect( m_navigationWidget->homeButton, SIGNAL(clicked()), SLOT(centerOnCurrentLocation()) );
emit repaintNeeded();
m_showHomeButton = false;
emit settingsChanged( nameId() );
}
void NavigationFloatItem::activateHomeButton()
{
if ( !isInitialized() ) {
return;
}
QIcon icon;
icon.addPixmap( pixmap("marble/navigation/navigational_homebutton"), QIcon::Normal );
icon.addPixmap( pixmap("marble/navigation/navigational_homebutton_hover"), QIcon::Active );
icon.addPixmap( pixmap("marble/navigation/navigational_homebutton_press"), QIcon::Selected );
m_navigationWidget->homeButton->setProperty("icon", QVariant(icon));
if ( m_contextMenu ) {
m_activateCurrentPositionButtonAction->setVisible( true );
m_activateHomeButtonAction->setVisible( false );
}
disconnect( m_navigationWidget->homeButton, SIGNAL(clicked()), this, SLOT(centerOnCurrentLocation()) );
if (m_marbleWidget) {
connect( m_navigationWidget->homeButton, SIGNAL(clicked()), m_marbleWidget, SLOT(goHome()) );
}
emit repaintNeeded();
m_showHomeButton = true;
emit settingsChanged( nameId() );
}
void NavigationFloatItem::centerOnCurrentLocation()
{
if ( m_marbleWidget->model()->positionTracking()->currentLocation().isValid() ) {
m_marbleWidget->centerOn( m_marbleWidget->model()->positionTracking()->currentLocation(), true );
}
}
QHash<QString,QVariant> NavigationFloatItem::settings() const
{
QHash<QString, QVariant> settings = AbstractFloatItem::settings();
settings.insert(QStringLiteral("showHomeButton"), m_showHomeButton);
return settings;
}
void NavigationFloatItem::setSettings( const QHash<QString, QVariant> &settings )
{
AbstractFloatItem::setSettings( settings );
m_showHomeButton = settings.value(QStringLiteral("showHomeButton"), true).toBool();
if ( m_showHomeButton ) {
activateHomeButton();
} else {
activateCurrentPositionButton();
}
}
#include "moc_NavigationFloatItem.cpp"
diff --git a/src/plugins/render/navigation/NavigationFloatItem.h b/src/plugins/render/navigation/NavigationFloatItem.h
index 836b251a2..942995484 100644
--- a/src/plugins/render/navigation/NavigationFloatItem.h
+++ b/src/plugins/render/navigation/NavigationFloatItem.h
@@ -1,124 +1,124 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#ifndef NAVIGATION_FLOAT_ITEM_H
#define NAVIGATION_FLOAT_ITEM_H
#include <QMenu>
#include "MarbleGlobal.h"
#include "AbstractFloatItem.h"
namespace Ui
{
class Navigation;
}
namespace Marble
{
class MarbleWidget;
class WidgetGraphicsItem;
/**
* @short Provides a float item with zoom and move controls
*
*/
class NavigationFloatItem: public AbstractFloatItem
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.NavigationFloatItem")
Q_INTERFACES( Marble::RenderPluginInterface )
MARBLE_PLUGIN( NavigationFloatItem )
public:
- explicit NavigationFloatItem( const MarbleModel *marbleModel = 0 );
+ explicit NavigationFloatItem( const MarbleModel *marbleModel = nullptr );
~NavigationFloatItem() override;
QStringList backendTypes() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
void setProjection( const ViewportParams *viewport ) override;
static QPixmap pixmap( const QString &Id );
QHash<QString,QVariant> settings() const override;
void setSettings( const QHash<QString, QVariant> &settings ) override;
protected:
bool eventFilter( QObject *object, QEvent *e ) override;
void paintContent( QPainter *painter ) override;
void contextMenuEvent( QWidget *w, QContextMenuEvent *e ) override;
private Q_SLOTS:
/** Map theme was changed, adjust controls */
void selectTheme( const QString& theme );
/** Enable/disable zoom in/out buttons */
void updateButtons( int zoomValue );
void activateCurrentPositionButton();
void activateHomeButton();
void centerOnCurrentLocation();
private:
/** MarbleWidget this float item is installed as event filter for */
MarbleWidget *m_marbleWidget;
/** The GraphicsItem presenting the widgets. NavigationFloatItem doesn't take direct ownership
of this */
WidgetGraphicsItem *m_widgetItem;
/** Navigation controls */
Ui::Navigation *m_navigationWidget;
/** Used Profile */
MarbleGlobal::Profiles m_profiles;
/** Radius of the viewport last time */
int m_oldViewportRadius;
int m_maxZoom;
int m_minZoom;
QMenu *m_contextMenu;
QAction *m_activateCurrentPositionButtonAction;
QAction *m_activateHomeButtonAction;
bool m_showHomeButton;
};
}
#endif // NAVIGATION_FLOAT_ITEM_H
diff --git a/src/plugins/render/navigation/NavigationSlider.h b/src/plugins/render/navigation/NavigationSlider.h
index 97b7996bd..299325d89 100644
--- a/src/plugins/render/navigation/NavigationSlider.h
+++ b/src/plugins/render/navigation/NavigationSlider.h
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
//
#ifndef NAVIGATIONSLIDER_H
#define NAVIGATIONSLIDER_H
#include <QAbstractSlider>
#include <QPixmap>
namespace Marble
{
class NavigationSlider : public QAbstractSlider
{
Q_OBJECT
public:
- explicit NavigationSlider( QWidget *parent = 0 );
+ explicit NavigationSlider( QWidget *parent = nullptr );
~NavigationSlider() override;
Q_SIGNALS:
void repaintNeeded();
protected:
void enterEvent( QEvent * ) override;
void mouseMoveEvent( QMouseEvent * mouseEvent) override;
void mousePressEvent( QMouseEvent * ) override;
void mouseReleaseEvent( QMouseEvent * ) override;
void leaveEvent( QEvent * ) override;
void paintEvent( QPaintEvent * ) override;
void repaint();
private:
static QPixmap pixmap(const QString &id );
QString m_handleImagePath;
};
}
#endif
diff --git a/src/plugins/render/notes/NotesModel.h b/src/plugins/render/notes/NotesModel.h
index 460b7a81e..9ad341e2b 100644
--- a/src/plugins/render/notes/NotesModel.h
+++ b/src/plugins/render/notes/NotesModel.h
@@ -1,32 +1,32 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2017 Spencer Brown <spencerbrown991@gmail.com>
//
#ifndef NOTESMODEL_H
#define NOTESMODEL_H
#include "AbstractDataPluginModel.h"
namespace Marble
{
class NotesModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- explicit NotesModel(const MarbleModel *marbleModel, QObject *parent = 0);
+ explicit NotesModel(const MarbleModel *marbleModel, QObject *parent = nullptr);
protected:
void getAdditionalItems(const GeoDataLatLonAltBox& box, qint32 number = 10) override;
void parseFile(const QByteArray& file) override;
};
}
#endif
diff --git a/src/plugins/render/notes/NotesPlugin.cpp b/src/plugins/render/notes/NotesPlugin.cpp
index 613820064..91530a430 100644
--- a/src/plugins/render/notes/NotesPlugin.cpp
+++ b/src/plugins/render/notes/NotesPlugin.cpp
@@ -1,78 +1,78 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2017 Spencer Brown <spencerbrown991@gmail.com>
//
#include "NotesPlugin.h"
#include "NotesModel.h"
#include "MarbleDirs.h"
#include <QIcon>
using namespace Marble;
NotesPlugin::NotesPlugin()
- : AbstractDataPlugin(0)
+ : AbstractDataPlugin(nullptr)
{
}
NotesPlugin::NotesPlugin(const MarbleModel *marbleModel)
: AbstractDataPlugin(marbleModel)
{
setEnabled(true);
setVisible(false);
}
void NotesPlugin::initialize()
{
setModel(new NotesModel(marbleModel(), this));
setNumberOfItems(20);
}
QString NotesPlugin::name() const
{
return tr("OSM Mapper Notes");
}
QString NotesPlugin::guiString() const
{
return name();
}
QString NotesPlugin::nameId() const
{
return QStringLiteral("notes");
}
QString NotesPlugin::version() const
{
return QStringLiteral("1.0");
}
QString NotesPlugin::copyrightYears() const
{
return QStringLiteral("2017");
}
QVector<PluginAuthor> NotesPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Spencer Brown"), QStringLiteral("spencerbrown991@gmail.com"));
}
QString NotesPlugin::description() const
{
return tr("Display OpenStreetMap Mapper Notes.");
}
QIcon NotesPlugin::icon() const
{
return QIcon(MarbleDirs::path("bitmaps/notes_open.png"));
}
#include "moc_NotesPlugin.cpp"
diff --git a/src/plugins/render/opendesktop/OpenDesktopModel.h b/src/plugins/render/opendesktop/OpenDesktopModel.h
index 22f57c522..db33f9b59 100644
--- a/src/plugins/render/opendesktop/OpenDesktopModel.h
+++ b/src/plugins/render/opendesktop/OpenDesktopModel.h
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Utku Aydın <utkuaydin34@gmail.com>
//
#ifndef OPENDESKTOPMODEL_H
#define OPENDESKTOPMODEL_H
#include "AbstractDataPluginModel.h"
namespace Marble {
class MarbleWidget;
class MarbleModel;
class OpenDesktopModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- explicit OpenDesktopModel( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit OpenDesktopModel( const MarbleModel *marbleModel, QObject *parent = nullptr );
~OpenDesktopModel() override;
void setMarbleWidget(MarbleWidget *widget);
protected:
/**
* Generates the download url for the description file from the web service depending on
* the @p box surrounding the view and the @p number of files to show.
**/
void getAdditionalItems(const Marble::GeoDataLatLonAltBox& box, qint32 number = 10) override;
/**
* Parses the @p file which getAdditionalItems downloads and
* prepares the data for usage.
**/
void parseFile(const QByteArray& file) override;
private:
MarbleWidget *m_marbleWidget;
};
}
#endif // OPENDESKTOPMODEL_H
diff --git a/src/plugins/render/opendesktop/OpenDesktopPlugin.cpp b/src/plugins/render/opendesktop/OpenDesktopPlugin.cpp
index e24cf9404..7b6230ecc 100644
--- a/src/plugins/render/opendesktop/OpenDesktopPlugin.cpp
+++ b/src/plugins/render/opendesktop/OpenDesktopPlugin.cpp
@@ -1,154 +1,154 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Utku Aydın <utkuaydin34@gmail.com>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include "OpenDesktopPlugin.h"
#include "OpenDesktopModel.h"
#include "MarbleWidget.h"
#include "ui_OpenDesktopConfigWidget.h"
#include <QPushButton>
using namespace Marble;
OpenDesktopPlugin::OpenDesktopPlugin()
- : AbstractDataPlugin( 0 ),
- m_configDialog( 0 ),
- m_uiConfigWidget( 0 )
+ : AbstractDataPlugin( nullptr ),
+ m_configDialog( nullptr ),
+ m_uiConfigWidget( nullptr )
{
}
OpenDesktopPlugin::OpenDesktopPlugin( const MarbleModel *marbleModel )
: AbstractDataPlugin( marbleModel ),
- m_configDialog( 0 ),
- m_uiConfigWidget( 0 )
+ m_configDialog( nullptr ),
+ m_uiConfigWidget( nullptr )
{
setEnabled( true ); // Plugin is enabled by default
setVisible( false ); // Plugin is invisible by default
}
void OpenDesktopPlugin::initialize()
{
setModel( new OpenDesktopModel( marbleModel(), this ) );
setNumberOfItems( defaultItemsOnScreen ); // Setting the number of items on the screen.
}
QString OpenDesktopPlugin::name() const
{
return tr( "OpenDesktop Items" );
}
QString OpenDesktopPlugin::guiString() const
{
return tr( "&OpenDesktop Community" );
}
QString OpenDesktopPlugin::nameId() const
{
return QStringLiteral("opendesktop");
}
QString OpenDesktopPlugin::version() const
{
return QStringLiteral("1.0");
}
QString OpenDesktopPlugin::description() const
{
return tr( "Shows OpenDesktop users' avatars and some extra information about them on the map." );
}
QString OpenDesktopPlugin::copyrightYears() const
{
return QStringLiteral("2010");
}
QVector<PluginAuthor> OpenDesktopPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Utku Aydin"), QStringLiteral("utkuaydin34@gmail.com"));
}
QIcon OpenDesktopPlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/social.png"));
}
QDialog *OpenDesktopPlugin::configDialog()
{
if ( !m_configDialog ) {
m_configDialog = new QDialog();
m_uiConfigWidget = new Ui::OpenDesktopConfigWidget;
m_uiConfigWidget->setupUi( m_configDialog );
readSettings();
connect( m_uiConfigWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( m_uiConfigWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
QPushButton *applyButton = m_uiConfigWidget->m_buttonBox->button(
QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
this, SLOT(writeSettings()) );
}
return m_configDialog;
}
QHash<QString,QVariant> OpenDesktopPlugin::settings() const
{
QHash<QString, QVariant> settings = AbstractDataPlugin::settings();
settings.insert(QStringLiteral("itemsOnScreen"), numberOfItems());
return settings;
}
bool OpenDesktopPlugin::eventFilter(QObject *object, QEvent *event)
{
if ( isInitialized() ) {
OpenDesktopModel *odModel = qobject_cast<OpenDesktopModel*>( model() );
Q_ASSERT(odModel);
MarbleWidget* widget = qobject_cast<MarbleWidget*>( object );
if ( widget ) {
odModel->setMarbleWidget(widget);
}
}
return AbstractDataPlugin::eventFilter( object, event );
}
void OpenDesktopPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractDataPlugin::setSettings( settings );
setNumberOfItems(settings.value(QStringLiteral("itemsOnScreen"), defaultItemsOnScreen).toInt());
emit settingsChanged( nameId() );
}
void OpenDesktopPlugin::readSettings()
{
if ( m_uiConfigWidget ) {
m_uiConfigWidget->m_itemsOnScreenSpin->setValue( numberOfItems() );
}
}
void OpenDesktopPlugin::writeSettings()
{
if ( m_uiConfigWidget ) {
setNumberOfItems( m_uiConfigWidget->m_itemsOnScreenSpin->value() );
}
emit settingsChanged( nameId() );
}
#include "moc_OpenDesktopPlugin.cpp"
diff --git a/src/plugins/render/overviewmap/OverviewMap.cpp b/src/plugins/render/overviewmap/OverviewMap.cpp
index eec7da392..85eaffb04 100644
--- a/src/plugins/render/overviewmap/OverviewMap.cpp
+++ b/src/plugins/render/overviewmap/OverviewMap.cpp
@@ -1,540 +1,540 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
//
#include "OverviewMap.h"
#include <QRect>
#include <QStringList>
#include <QCursor>
#include <QMouseEvent>
#include <QPainter>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QColorDialog>
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "ui_OverviewMapConfigWidget.h"
#include "GeoDataPoint.h"
#include "ViewportParams.h"
#include "MarbleWidget.h"
#include "Planet.h"
#include "PlanetFactory.h"
namespace Marble
{
OverviewMap::OverviewMap()
- : AbstractFloatItem( 0 ),
- ui_configWidget( 0 ),
- m_configDialog( 0 ),
+ : AbstractFloatItem( nullptr ),
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr ),
m_mapChanged( false )
{
}
OverviewMap::OverviewMap( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( 10.5, 10.5 ), QSizeF( 166.0, 86.0 ) ),
m_target(),
m_planetID( PlanetFactory::planetList() ),
m_defaultSize( AbstractFloatItem::size() ),
- ui_configWidget( 0 ),
- m_configDialog( 0 ),
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr ),
m_mapChanged( false )
{
// cache is no needed because:
// (1) the SVG overview map is already rendered and stored in m_worldmap pixmap
// (2) bounding box and location dot keep changing during navigation
setCacheMode( NoCache );
connect( this, SIGNAL(settingsChanged(QString)),
this, SLOT(updateSettings()) );
restoreDefaultSettings();
}
OverviewMap::~OverviewMap()
{
QHash<QString, QSvgWidget *>::const_iterator pos = m_svgWidgets.constBegin();
QHash<QString, QSvgWidget *>::const_iterator const end = m_svgWidgets.constEnd();
for (; pos != end; ++pos ) {
delete pos.value();
}
}
QStringList OverviewMap::backendTypes() const
{
return QStringList(QStringLiteral("overviewmap"));
}
QString OverviewMap::name() const
{
return tr("Overview Map");
}
QString OverviewMap::guiString() const
{
return tr("&Overview Map");
}
QString OverviewMap::nameId() const
{
return QStringLiteral("overviewmap");
}
QString OverviewMap::version() const
{
return QStringLiteral("1.0");
}
QString OverviewMap::description() const
{
return tr("This is a float item that provides an overview map.");
}
QString OverviewMap::copyrightYears() const
{
return QStringLiteral("2008");
}
QVector<PluginAuthor> OverviewMap::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"));
}
QIcon OverviewMap::icon () const
{
return QIcon(QStringLiteral(":/icons/worldmap.png"));
}
QDialog *OverviewMap::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::OverviewMapConfigWidget;
ui_configWidget->setupUi( m_configDialog );
for( int i = 0; i < m_planetID.size(); ++i ) {
ui_configWidget->m_planetComboBox->addItem( PlanetFactory::localizedName(m_planetID.value( i ) ) );
}
ui_configWidget->m_planetComboBox->setCurrentIndex( 2 );
readSettings();
loadMapSuggestions();
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
connect( ui_configWidget->m_buttonBox->button( QDialogButtonBox::Reset ), SIGNAL(clicked()),
SLOT(restoreDefaultSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_fileChooserButton, SIGNAL(clicked()),
SLOT(chooseCustomMap()) );
connect( ui_configWidget->m_widthBox, SIGNAL(valueChanged(int)),
SLOT(synchronizeSpinboxes()) );
connect( ui_configWidget->m_heightBox, SIGNAL(valueChanged(int)),
SLOT(synchronizeSpinboxes()) );
connect( ui_configWidget->m_planetComboBox, SIGNAL(currentIndexChanged(int)),
SLOT(showCurrentPlanetPreview()) );
connect( ui_configWidget->m_colorChooserButton, SIGNAL(clicked()),
SLOT(choosePositionIndicatorColor()) );
connect( ui_configWidget->m_tableWidget, SIGNAL(cellClicked(int,int)),
SLOT(useMapSuggestion(int)) );
}
return m_configDialog;
}
void OverviewMap::initialize ()
{
}
bool OverviewMap::isInitialized () const
{
return true;
}
void OverviewMap::setProjection( const ViewportParams *viewport )
{
GeoDataLatLonAltBox latLonAltBox = viewport->latLonAltBox( QRect( QPoint( 0, 0 ), viewport->size() ) );
const qreal centerLon = viewport->centerLongitude();
const qreal centerLat = viewport->centerLatitude();
QString target = marbleModel()->planetId();
if ( target != m_target ) {
changeBackground( target );
m_target = target;
update();
}
if ( !( m_latLonAltBox == latLonAltBox
&& m_centerLon == centerLon
&& m_centerLat == centerLat ) )
{
m_latLonAltBox = latLonAltBox;
m_centerLon = centerLon;
m_centerLat = centerLat;
update();
}
AbstractFloatItem::setProjection( viewport );
}
void OverviewMap::paintContent( QPainter *painter )
{
painter->save();
QRectF mapRect( contentRect() );
if ( m_svgobj.isValid() ) {
// Rerender worldmap pixmap if the size or map has changed
if ( m_worldmap.size() != mapRect.size().toSize() || m_mapChanged ) {
m_mapChanged = false;
m_worldmap = QPixmap( mapRect.size().toSize() );
m_worldmap.fill( Qt::transparent );
QPainter mapPainter;
mapPainter.begin( &m_worldmap );
mapPainter.setViewport( m_worldmap.rect() );
m_svgobj.render( &mapPainter );
mapPainter.end();
}
painter->drawPixmap( QPoint( 0, 0 ), m_worldmap );
}
else {
painter->setPen( QPen( Qt::DashLine ) );
painter->drawRect( QRectF( QPoint( 0, 0 ), mapRect.size().toSize() ) );
for ( int y = 1; y < 4; ++y ) {
if ( y == 2 ) {
painter->setPen( QPen( Qt::DashLine ) );
}
else {
painter->setPen( QPen( Qt::DotLine ) );
}
painter->drawLine( 0.0, 0.25 * y * mapRect.height(),
mapRect.width(), 0.25 * y * mapRect.height() );
}
for ( int x = 1; x < 8; ++x ) {
if ( x == 4 ) {
painter->setPen( QPen( Qt::DashLine ) );
}
else {
painter->setPen( QPen( Qt::DotLine ) );
}
painter->drawLine( 0.125 * x * mapRect.width(), 0,
0.125 * x * mapRect.width(), mapRect.height() );
}
}
// Now draw the latitude longitude bounding box
qreal xWest = mapRect.width() / 2.0
+ mapRect.width() / ( 2.0 * M_PI ) * m_latLonAltBox.west();
qreal xEast = mapRect.width() / 2.0
+ mapRect.width() / ( 2.0 * M_PI ) * m_latLonAltBox.east();
qreal xNorth = mapRect.height() / 2.0
- mapRect.height() / M_PI * m_latLonAltBox.north();
qreal xSouth = mapRect.height() / 2.0
- mapRect.height() / M_PI * m_latLonAltBox.south();
qreal lon = m_centerLon;
qreal lat = m_centerLat;
GeoDataCoordinates::normalizeLonLat( lon, lat );
qreal x = mapRect.width() / 2.0 + mapRect.width() / ( 2.0 * M_PI ) * lon;
qreal y = mapRect.height() / 2.0 - mapRect.height() / M_PI * lat;
painter->setPen( QPen( Qt::white ) );
painter->setBrush( QBrush( Qt::transparent ) );
painter->setRenderHint( QPainter::Antialiasing, false );
qreal boxWidth = xEast - xWest;
qreal boxHeight = xSouth - xNorth;
qreal minBoxSize = 2.0;
if ( boxHeight < minBoxSize ) boxHeight = minBoxSize;
if ( m_latLonAltBox.west() <= m_latLonAltBox.east() ) {
// Make sure the latLonBox is still visible
if ( boxWidth < minBoxSize ) boxWidth = minBoxSize;
painter->drawRect( QRectF( xWest, xNorth, boxWidth, boxHeight ) );
}
else {
// If the dateline is shown in the viewport and if the poles are not
// then there are two boxes that represent the latLonBox of the view.
boxWidth = xEast;
// Make sure the latLonBox is still visible
if ( boxWidth < minBoxSize ) boxWidth = minBoxSize;
painter->drawRect( QRectF( 0, xNorth, boxWidth, boxHeight ) );
boxWidth = mapRect.width() - xWest;
// Make sure the latLonBox is still visible
if ( boxWidth < minBoxSize ) boxWidth = minBoxSize;
painter->drawRect( QRectF( xWest, xNorth, boxWidth, boxHeight ) );
}
painter->setPen( QPen( m_posColor ) );
painter->setBrush( QBrush( m_posColor ) );
qreal circleRadius = 2.5;
painter->setRenderHint( QPainter::Antialiasing, true );
painter->drawEllipse( QRectF( x - circleRadius, y - circleRadius , 2 * circleRadius, 2 * circleRadius ) );
painter->restore();
}
QHash<QString,QVariant> OverviewMap::settings() const
{
QHash<QString, QVariant> result = AbstractFloatItem::settings();
typedef QHash<QString, QVariant>::ConstIterator Iterator;
Iterator end = m_settings.constEnd();
for ( Iterator iter = m_settings.constBegin(); iter != end; ++iter ) {
result.insert( iter.key(), iter.value() );
}
return result;
}
void OverviewMap::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractFloatItem::setSettings( settings );
m_settings.insert(QStringLiteral("width"), settings.value(QStringLiteral("width"), m_defaultSize.toSize().width()));
m_settings.insert(QStringLiteral("height"), settings.value(QStringLiteral("height"), m_defaultSize.toSize().height()));
for ( const QString& planet: PlanetFactory::planetList() ) {
QString mapFile = MarbleDirs::path(QLatin1String("svg/") + planet + QLatin1String("map.svg"));
if (planet == QLatin1String("moon")) {
mapFile = MarbleDirs::path(QStringLiteral("svg/lunarmap.svg"));
}
else if (planet == QLatin1String("earth") || mapFile.isEmpty()) {
mapFile = MarbleDirs::path(QStringLiteral("svg/worldmap.svg"));
}
const QString id = QLatin1String("path_") + planet;
m_settings.insert(id, settings.value(id, mapFile));
}
m_settings.insert(QStringLiteral("posColor"), settings.value(QStringLiteral("posColor"), QColor(Qt::white).name()));
m_target.clear(); // FIXME: forces execution of changeBackground() in changeViewport()
readSettings();
emit settingsChanged( nameId() );
}
void OverviewMap::readSettings()
{
if ( !m_configDialog ) {
return;
}
ui_configWidget->m_widthBox->setValue( m_settings.value(QStringLiteral("width")).toInt() );
ui_configWidget->m_heightBox->setValue( m_settings.value(QStringLiteral("height")).toInt() );
QPalette palette = ui_configWidget->m_colorChooserButton->palette();
palette.setColor(QPalette::Button, QColor(m_settings.value(QStringLiteral("posColor")).toString()));
ui_configWidget->m_colorChooserButton->setPalette( palette );
}
void OverviewMap::writeSettings()
{
if ( !m_configDialog ) {
return;
}
m_settings.insert(QStringLiteral("width"), contentRect().width());
m_settings.insert(QStringLiteral("height"), contentRect().height());
QStringList const planets = PlanetFactory::planetList();
for( const QString &planet: planets ) {
m_settings.insert(QLatin1String("path_") + planet, m_svgPaths[planet]);
}
m_settings.insert(QStringLiteral("posColor"), m_posColor.name());
emit settingsChanged( nameId() );
}
void OverviewMap::updateSettings()
{
QStringList const planets = PlanetFactory::planetList();
for( const QString &planet: planets ) {
m_svgPaths.insert(planet, m_settings.value(QLatin1String("path_") + planet, QString()).toString());
}
m_posColor = QColor(m_settings.value(QStringLiteral("posColor")).toString());
loadPlanetMaps();
if ( !m_configDialog ) {
return;
}
setCurrentWidget( m_svgWidgets[m_planetID[2]] );
showCurrentPlanetPreview();
setContentSize( QSizeF( ui_configWidget->m_widthBox->value(), ui_configWidget->m_heightBox->value() ) );
}
bool OverviewMap::eventFilter( QObject *object, QEvent *e )
{
if ( !enabled() || !visible() ) {
return false;
}
MarbleWidget *widget = dynamic_cast<MarbleWidget*>(object);
if ( !widget ) {
return AbstractFloatItem::eventFilter(object,e);
}
if ( e->type() == QEvent::MouseButtonDblClick || e->type() == QEvent::MouseMove ) {
QMouseEvent *event = static_cast<QMouseEvent*>(e);
QRectF floatItemRect = QRectF( positivePosition(), size() );
bool cursorAboveFloatItem(false);
if ( floatItemRect.contains(event->pos()) ) {
cursorAboveFloatItem = true;
// Double click triggers recentering the map at the specified position
if ( e->type() == QEvent::MouseButtonDblClick ) {
QRectF mapRect( contentRect() );
QPointF pos = event->pos() - floatItemRect.topLeft()
- QPointF(padding(),padding());
qreal lon = ( pos.x() - mapRect.width() / 2.0 ) / mapRect.width() * 360.0 ;
qreal lat = ( mapRect.height() / 2.0 - pos.y() ) / mapRect.height() * 180.0;
widget->centerOn(lon,lat,true);
return true;
}
}
if ( cursorAboveFloatItem && e->type() == QEvent::MouseMove
&& !(event->buttons() & Qt::LeftButton) )
{
// Cross hair cursor when moving above the float item without pressing a button
widget->setCursor(QCursor(Qt::CrossCursor));
return true;
}
}
return AbstractFloatItem::eventFilter(object,e);
}
void OverviewMap::changeBackground( const QString& target )
{
m_svgobj.load( m_svgPaths[target] );
m_mapChanged = true;
}
QSvgWidget *OverviewMap::currentWidget() const
{
return m_svgWidgets[m_planetID[ui_configWidget->m_planetComboBox->currentIndex()]];
}
void OverviewMap::setCurrentWidget( QSvgWidget *widget )
{
m_svgWidgets[m_planetID[ui_configWidget->m_planetComboBox->currentIndex()]] = widget;
if( m_target == m_planetID[ui_configWidget->m_planetComboBox->currentIndex()] ) {
changeBackground( m_target );
}
}
void OverviewMap::loadPlanetMaps()
{
for( const QString& planet: m_planetID ) {
if ( m_svgWidgets.contains( planet) ) {
m_svgWidgets[planet]->load( m_svgPaths[planet] );
} else {
m_svgWidgets[planet] = new QSvgWidget( m_svgPaths[planet] );
}
}
}
void OverviewMap::loadMapSuggestions()
{
QStringList paths = QDir(MarbleDirs::pluginPath(QString())).entryList(QStringList("*.svg"), QDir::Files | QDir::NoDotAndDotDot);
for( int i = 0; i < paths.size(); ++i ) {
paths[i] = MarbleDirs::pluginPath(QString()) + QLatin1Char('/') + paths[i];
}
paths << MarbleDirs::path(QStringLiteral("svg/worldmap.svg")) << MarbleDirs::path(QStringLiteral("svg/lunarmap.svg"));
ui_configWidget->m_tableWidget->setRowCount( paths.size() );
for( int i = 0; i < paths.size(); ++i ) {
ui_configWidget->m_tableWidget->setCellWidget( i, 0, new QSvgWidget( paths[i] ) );
ui_configWidget->m_tableWidget->setItem( i, 1, new QTableWidgetItem( paths[i] ) );
}
}
void OverviewMap::chooseCustomMap()
{
QString path = QFileDialog::getOpenFileName ( m_configDialog, tr( "Choose Overview Map" ), "", "SVG (*.svg)" );
if( !path.isNull() )
{
ui_configWidget->m_fileChooserButton->layout()->removeWidget( currentWidget() );
delete currentWidget();
QSvgWidget *widget = new QSvgWidget( path );
setCurrentWidget( widget );
ui_configWidget->m_fileChooserButton->layout()->addWidget( widget );
m_svgPaths[m_planetID[ui_configWidget->m_planetComboBox->currentIndex()]] = path;
}
}
void OverviewMap::synchronizeSpinboxes()
{
if( sender() == ui_configWidget->m_widthBox ) {
ui_configWidget->m_heightBox->setValue( ui_configWidget->m_widthBox->value() / 2 );
}
else if( sender() == ui_configWidget->m_heightBox ) {
ui_configWidget->m_widthBox->setValue( ui_configWidget->m_heightBox->value() * 2 );
}
}
void OverviewMap::showCurrentPlanetPreview() const
{
delete ui_configWidget->m_fileChooserButton->layout();
ui_configWidget->m_fileChooserButton->setLayout( new QHBoxLayout() );
ui_configWidget->m_fileChooserButton->layout()->addWidget( currentWidget() );
}
void OverviewMap::choosePositionIndicatorColor()
{
- QColor c = QColorDialog::getColor( m_posColor, 0,
+ QColor c = QColorDialog::getColor( m_posColor, nullptr,
tr( "Please choose the color for the position indicator" ),
QColorDialog::ShowAlphaChannel );
if( c.isValid() )
{
m_posColor = c;
QPalette palette = ui_configWidget->m_colorChooserButton->palette();
palette.setColor( QPalette::Button, m_posColor );
ui_configWidget->m_colorChooserButton->setPalette( palette );
}
}
void OverviewMap::useMapSuggestion( int index )
{
QString path = ui_configWidget->m_tableWidget->item( index, 1 )->text();
m_svgPaths[m_planetID[ui_configWidget->m_planetComboBox->currentIndex()]] = path;
delete currentWidget();
QSvgWidget *widget = new QSvgWidget( path );
setCurrentWidget( widget );
showCurrentPlanetPreview();
}
}
#include "moc_OverviewMap.cpp"
diff --git a/src/plugins/render/photo/PhotoPlugin.cpp b/src/plugins/render/photo/PhotoPlugin.cpp
index 8fc70a4b8..1f0b59412 100644
--- a/src/plugins/render/photo/PhotoPlugin.cpp
+++ b/src/plugins/render/photo/PhotoPlugin.cpp
@@ -1,268 +1,268 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
// Self
#include "PhotoPlugin.h"
#include "PhotoPluginModel.h"
// Marble
#include "ui_PhotoConfigWidget.h"
#include "MarbleDebug.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
// Qt
#include <QPushButton>
#include <QStringList>
using namespace Marble;
/* TRANSLATOR Marble::PhotoPlugin */
const quint32 maximumNumberOfItems = 99;
PhotoPlugin::PhotoPlugin()
- : AbstractDataPlugin( 0 ),
- ui_configWidget( 0 ),
- m_configDialog( 0 )
+ : AbstractDataPlugin( nullptr ),
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr )
{
}
PhotoPlugin::PhotoPlugin( const MarbleModel *marbleModel )
: AbstractDataPlugin( marbleModel ),
- ui_configWidget( 0 ),
- m_configDialog( 0 )
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr )
{
// Plugin is enabled by default
setEnabled( true );
// Plugin is not visible by default
setVisible( false );
connect( this, SIGNAL(settingsChanged(QString)),
this, SLOT(updateSettings()) );
connect( this, SIGNAL(changedNumberOfItems(quint32)),
this, SLOT(checkNumberOfItems(quint32)) );
setSettings( QHash<QString,QVariant>() );
}
PhotoPlugin::~PhotoPlugin()
{
delete ui_configWidget;
delete m_configDialog;
}
void PhotoPlugin::initialize()
{
mDebug() << "PhotoPlugin: Initialize";
PhotoPluginModel *model = new PhotoPluginModel( marbleModel(), this );
setModel( model );
updateSettings();
}
QString PhotoPlugin::name() const
{
return tr( "Photos" );
}
QString PhotoPlugin::guiString() const
{
return tr( "&Photos" );
}
QString PhotoPlugin::nameId() const
{
return QStringLiteral("photo");
}
QString PhotoPlugin::version() const
{
return QStringLiteral("1.0");
}
QString PhotoPlugin::description() const
{
return tr( "Automatically downloads images from around the world in preference to their popularity" );
}
QString PhotoPlugin::copyrightYears() const
{
return QStringLiteral("2009, 2012");
}
QVector<PluginAuthor> PhotoPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Bastian Holst"), QStringLiteral("bastianholst@gmx.de"))
<< PluginAuthor(QStringLiteral("Mohammed Nafees"), QStringLiteral("nafees.technocool@gmail.com"));
}
QIcon PhotoPlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/photo.png"));
}
QDialog *PhotoPlugin::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::PhotoConfigWidget;
ui_configWidget->setupUi( m_configDialog );
// add licenses to the list widget
QListWidgetItem *ccByNcSa2 = new QListWidgetItem( ui_configWidget->m_licenseListWidget );
ccByNcSa2->setText( tr("Attribution-NonCommercial-ShareAlike License") );
ccByNcSa2->setIcon( QIcon() );
ccByNcSa2->setCheckState( Qt::Checked );
ccByNcSa2->setData( Qt::UserRole+1, 1 );
ccByNcSa2->setData( Qt::UserRole+2, "http://creativecommons.org/licenses/by-nc-sa/2.0/" );
ui_configWidget->m_licenseListWidget->addItem( ccByNcSa2 );
QListWidgetItem *ccByNc2 = new QListWidgetItem( ui_configWidget->m_licenseListWidget );
ccByNc2->setText( tr("Attribution-NonCommercial License") );
ccByNc2->setIcon( QIcon() );
ccByNc2->setCheckState( Qt::Checked );
ccByNc2->setData( Qt::UserRole+1, 2 );
ccByNc2->setData( Qt::UserRole+2, "http://creativecommons.org/licenses/by-nc/2.0/" );
ui_configWidget->m_licenseListWidget->addItem( ccByNc2 );
QListWidgetItem *ccByNcNd2 = new QListWidgetItem( ui_configWidget->m_licenseListWidget );
ccByNcNd2->setText( tr("Attribution-NonCommercial-NoDerivs License") );
ccByNcNd2->setIcon( QIcon() );
ccByNcNd2->setCheckState( Qt::Checked );
ccByNcNd2->setData( Qt::UserRole+1, 3 );
ccByNcNd2->setData( Qt::UserRole+2, "http://creativecommons.org/licenses/by-nc-nd/2.0/" );
ui_configWidget->m_licenseListWidget->addItem( ccByNcNd2 );
QListWidgetItem *ccBy2 = new QListWidgetItem( ui_configWidget->m_licenseListWidget );
ccBy2->setText( tr("Attribution License") );
ccBy2->setIcon( QIcon() );
ccBy2->setCheckState( Qt::Checked );
ccBy2->setData( Qt::UserRole+1, 4 );
ccBy2->setData( Qt::UserRole+2, "http://creativecommons.org/licenses/by/2.0/" );
ui_configWidget->m_licenseListWidget->addItem( ccBy2 );
QListWidgetItem *ccBySa2 = new QListWidgetItem( ui_configWidget->m_licenseListWidget );
ccBySa2->setText( tr("Attribution-ShareAlike License") );
ccBySa2->setIcon( QIcon() );
ccBySa2->setCheckState( Qt::Checked );
ccBySa2->setData( Qt::UserRole+1, 5 );
ccBySa2->setData( Qt::UserRole+2, "http://creativecommons.org/licenses/by-sa/2.0/" );
ui_configWidget->m_licenseListWidget->addItem( ccBySa2 );
QListWidgetItem *ccByNd2 = new QListWidgetItem( ui_configWidget->m_licenseListWidget );
ccByNd2->setText( tr("Attribution-NoDerivs License") );
ccByNd2->setIcon( QIcon() );
ccByNd2->setCheckState( Qt::Checked );
ccByNd2->setData( Qt::UserRole+1, 6 );
ccByNd2->setData( Qt::UserRole+2, "http://creativecommons.org/licenses/by-nd/2.0/" );
ui_configWidget->m_licenseListWidget->addItem( ccByNd2 );
QListWidgetItem *noLicense = new QListWidgetItem( ui_configWidget->m_licenseListWidget );
noLicense->setText( tr("No known copyright restrictions") );
noLicense->setIcon( QIcon() );
noLicense->setCheckState( Qt::Checked );
noLicense->setData( Qt::UserRole+1, 7 );
noLicense->setData( Qt::UserRole+2, "http://flickr.com/commons/usage/" );
ui_configWidget->m_licenseListWidget->addItem( noLicense );
readSettings();
ui_configWidget->m_itemNumberSpinBox->setRange( 0, maximumNumberOfItems );
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
this, SLOT(writeSettings()) );
}
return m_configDialog;
}
QHash<QString,QVariant> PhotoPlugin::settings() const
{
QHash<QString, QVariant> settings = AbstractDataPlugin::settings();
settings.insert(QStringLiteral("numberOfItems"), numberOfItems());
settings.insert(QStringLiteral("checkState"), m_checkStateList.join(QLatin1Char(',')));
return settings;
}
void PhotoPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractDataPlugin::setSettings( settings );
setNumberOfItems(qMin<int>(maximumNumberOfItems, settings.value(QStringLiteral("numberOfItems"), 15).toInt()));
m_checkStateList = settings.value(QStringLiteral("checkState"), QStringLiteral("1,2,3,4,5,6,7")).toString().split(QLatin1Char(','), QString::SkipEmptyParts);
updateSettings();
readSettings();
}
bool PhotoPlugin::eventFilter(QObject *object, QEvent *event)
{
if ( isInitialized() ) {
PhotoPluginModel *photoPluginModel = dynamic_cast<PhotoPluginModel*>( model() );
Q_ASSERT( photoPluginModel );
MarbleWidget* widget = dynamic_cast<MarbleWidget*>( object );
if ( widget ) {
photoPluginModel->setMarbleWidget( widget );
}
}
return AbstractDataPlugin::eventFilter( object, event );
}
void PhotoPlugin::readSettings()
{
if ( !m_configDialog )
return;
ui_configWidget->m_itemNumberSpinBox->setValue( numberOfItems() );
for ( int i = 0; i < ui_configWidget->m_licenseListWidget->count(); ++i ) {
const QString licenseId = QString::number( ui_configWidget->m_licenseListWidget->item(i)->data( Qt::UserRole+1 ).toInt() );
ui_configWidget->m_licenseListWidget->item(i)->setCheckState( m_checkStateList.contains( licenseId ) ? Qt::Checked : Qt::Unchecked );
}
}
void PhotoPlugin::writeSettings()
{
setNumberOfItems( ui_configWidget->m_itemNumberSpinBox->value() );
QStringList licenseCheckStateList;
for ( int i = 0; i < ui_configWidget->m_licenseListWidget->count(); ++i ) {
if ( ui_configWidget->m_licenseListWidget->item(i)->checkState() == Qt::Checked )
{
licenseCheckStateList << ui_configWidget->m_licenseListWidget->item(i)->data( Qt::UserRole+1 ).toString();
}
}
m_checkStateList = licenseCheckStateList;
emit settingsChanged( nameId() );
}
void PhotoPlugin::updateSettings()
{
AbstractDataPluginModel *abstractModel = model();
- if ( abstractModel != 0 ) {
+ if ( abstractModel != nullptr ) {
abstractModel->setItemSettings( settings() );
}
if ( model() ) {
qobject_cast<PhotoPluginModel*>(model())->setLicenseValues(m_checkStateList.join(QLatin1Char(',')));
}
}
void PhotoPlugin::checkNumberOfItems( quint32 number ) {
if ( number > maximumNumberOfItems ) {
setNumberOfItems( maximumNumberOfItems );
}
readSettings();
}
#include "moc_PhotoPlugin.cpp"
diff --git a/src/plugins/render/photo/PhotoPluginItem.cpp b/src/plugins/render/photo/PhotoPluginItem.cpp
index e6bef50ed..aea20aab1 100644
--- a/src/plugins/render/photo/PhotoPluginItem.cpp
+++ b/src/plugins/render/photo/PhotoPluginItem.cpp
@@ -1,203 +1,203 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
// Self
#include "PhotoPluginItem.h"
// Plugin
#include "CoordinatesParser.h"
#include "PhotoPluginModel.h"
// Marble
#include "AbstractDataPluginItem.h"
#include "GeoDataCoordinates.h"
#include "GeoPainter.h"
#include "LabelGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "TinyWebBrowser.h"
#include "ViewportParams.h"
#include "MarbleDebug.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "RenderPlugin.h"
#include "PluginManager.h"
#include "layers/PopupLayer.h"
// Qt
#include <QAction>
#include <QIcon>
#include <QFile>
#include <QHash>
#include <QUrl>
#include <QPixmap>
using namespace Marble;
PhotoPluginItem::PhotoPluginItem( MarbleWidget *widget, QObject *parent )
: AbstractDataPluginItem( parent ),
m_marbleWidget( widget ),
m_image( this ),
- m_browser( 0 )
+ m_browser( nullptr )
{
m_action = new QAction( this );
connect( m_action, SIGNAL(triggered()), this, SLOT(openBrowser()) );
setCacheMode( ItemCoordinateCache );
m_image.setFrame( FrameGraphicsItem::ShadowFrame );
m_image.setBorderBrush( QBrush( QColor( Qt::white ) ) );
m_image.setBorderWidth( 2.0 );
m_image.setMargin( 5 );
MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
layout->addItem( &m_image, 0, 0 );
setLayout( layout );
}
PhotoPluginItem::~PhotoPluginItem()
{
delete m_browser;
}
QString PhotoPluginItem::name() const
{
return title();
}
bool PhotoPluginItem::initialized() const
{
return !m_smallImage.isNull() && coordinate().isValid();
}
void PhotoPluginItem::addDownloadedFile( const QString& url, const QString& type )
{
if (type == QLatin1String("thumbnail")) {
m_smallImage.load( url );
m_image.setImage( m_smallImage.scaled( QSize( 50, 50 ) ) );
}
else if (type == QLatin1String("info")) {
QFile file( url );
if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
return;
}
GeoDataCoordinates coordinates;
CoordinatesParser parser( &coordinates );
if( parser.read( &file ) ) {
setCoordinate( coordinates );
}
}
if ( initialized() ) {
emit updated();
}
}
bool PhotoPluginItem::operator<( const AbstractDataPluginItem *other ) const
{
return this->id() < other->id();
}
QUrl PhotoPluginItem::photoUrl() const
{
QString url = "https://farm%1.static.flickr.com/%2/%3_%4_s.jpg";
return QUrl( url.arg( farm() ).arg( server() ).arg( id() ).arg( secret() ) );
}
QUrl PhotoPluginItem::infoUrl() const
{
QHash<QString,QString> options;
options.insert( "photo_id", id() );
return PhotoPluginModel::generateUrl( "flickr", "flickr.photos.geo.getLocation", options );
}
QString PhotoPluginItem::server() const
{
return m_server;
}
void PhotoPluginItem::setServer( const QString& server )
{
m_server = server;
}
QString PhotoPluginItem::farm() const
{
return m_farm;
}
void PhotoPluginItem::setFarm( const QString& farm )
{
m_farm = farm;
}
QString PhotoPluginItem::secret() const
{
return m_secret;
}
void PhotoPluginItem::setSecret( const QString& secret )
{
m_secret = secret;
}
QString PhotoPluginItem::owner() const
{
return m_owner;
}
void PhotoPluginItem::setOwner( const QString& owner )
{
m_owner = owner;
}
QString PhotoPluginItem::title() const
{
return m_title;
}
void PhotoPluginItem::setTitle( const QString& title )
{
m_title = title;
m_action->setText( title );
}
QAction *PhotoPluginItem::action()
{
if( m_action->icon().isNull() ) {
m_action->setIcon( QIcon( QPixmap::fromImage( m_smallImage ) ) );
}
return m_action;
}
void PhotoPluginItem::openBrowser()
{
if ( m_marbleWidget ) {
PopupLayer* popup = m_marbleWidget->popupLayer();
popup->setCoordinates( coordinate(), Qt::AlignRight | Qt::AlignVCenter );
popup->setSize(QSizeF(720, 470));
popup->setUrl(QUrl(QLatin1String("http://m.flickr.com/photos/") + owner() + QLatin1Char('/') + id() + QLatin1Char('/')));
popup->popup();
} else {
if( !m_browser ) {
m_browser = new TinyWebBrowser();
}
QString url = "http://www.flickr.com/photos/%1/%2/";
m_browser->load( QUrl( url.arg( owner() ).arg( id() ) ) );
m_browser->show();
}
}
#include "moc_PhotoPluginItem.cpp"
diff --git a/src/plugins/render/photo/PhotoPluginModel.cpp b/src/plugins/render/photo/PhotoPluginModel.cpp
index ad4ae356c..54ed4cc7d 100644
--- a/src/plugins/render/photo/PhotoPluginModel.cpp
+++ b/src/plugins/render/photo/PhotoPluginModel.cpp
@@ -1,155 +1,155 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
// Self
#include "PhotoPluginModel.h"
// Photo Plugin
#include "FlickrParser.h"
#include "PhotoPluginItem.h"
#include "PhotoPlugin.h"
// Marble
#include "AbstractDataPluginItem.h"
#include "GeoDataLatLonAltBox.h"
#include "MarbleModel.h"
#include "MarbleDebug.h"
#include "MarbleWidget.h"
// Qt
#include <QHash>
#include <QString>
#include <QUrl>
using namespace Marble;
const QString flickrApiKey( "620131a1b82b000c9582b94effcdc636" );
PhotoPluginModel::PhotoPluginModel( const MarbleModel *marbleModel, QObject *parent )
: AbstractDataPluginModel( "photo", marbleModel, parent ),
- m_marbleWidget( 0 )
+ m_marbleWidget( nullptr )
{
}
QUrl PhotoPluginModel::generateUrl( const QString& service,
const QString& method,
const QHash<QString,QString>& options )
{
QString url;
if (service == QLatin1String("flickr"))
url += QLatin1String("https://www.flickr.com/services/rest/");
else
return QUrl();
url += QLatin1String("?method=") + method +
QLatin1String("&format=rest") +
QLatin1String("&api_key=") + flickrApiKey;
QHash<QString,QString>::const_iterator it = options.constBegin();
QHash<QString,QString>::const_iterator const end = options.constEnd();
for (; it != end; ++it ) {
url += QLatin1Char('&') + it.key() + QLatin1Char('=') + it.value();
}
return QUrl( url );
}
void PhotoPluginModel::getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number )
{
// Flickr only supports images for earth
if (marbleModel()->planetId() != QLatin1String("earth")) {
return;
}
if( box.west() <= box.east() ) {
const QString bbox =
QString::number(box.west() * RAD2DEG) + QLatin1Char(',') +
QString::number(box.south() * RAD2DEG) + QLatin1Char(',') +
QString::number(box.east() * RAD2DEG) + QLatin1Char(',') +
QString::number(box.north() * RAD2DEG);
QHash<QString,QString> options;
options.insert( "per_page", QString::number( number ) );
options.insert( "bbox", bbox );
options.insert( "sort", "interestingness-desc" );
options.insert( "license", m_licenses );
downloadDescriptionFile( generateUrl( "flickr", "flickr.photos.search", options ) );
}
else {
// Flickr api doesn't support bboxes with west > east so we have to split in two boxes
const QString bboxWest =
QString::number(box.west() * RAD2DEG) + QLatin1Char(',') +
QString::number(box.south() * RAD2DEG) + QLatin1Char(',') +
QString::number(180 ) + QLatin1Char(',') +
QString::number(box.north() * RAD2DEG);
QHash<QString,QString> optionsWest;
optionsWest.insert( "per_page", QString::number( number/2 ) );
optionsWest.insert( "bbox", bboxWest );
optionsWest.insert( "sort", "interestingness-desc" );
optionsWest.insert( "license", m_licenses );
downloadDescriptionFile( generateUrl( "flickr", "flickr.photos.search", optionsWest ) );
const QString bboxEast =
QString::number(-180) +QLatin1Char( ',') +
QString::number(box.south() * RAD2DEG) + QLatin1Char(',') +
QString::number(box.east() * RAD2DEG) + QLatin1Char(',') +
QString::number(box.north() * RAD2DEG);
QHash<QString,QString> optionsEast;
optionsEast.insert( "per_page", QString::number( number/2 ) );
optionsEast.insert( "bbox", bboxEast );
optionsEast.insert( "sort", "interestingness-desc" );
optionsEast.insert( "license", m_licenses );
downloadDescriptionFile( generateUrl( "flickr", "flickr.photos.search", optionsEast ) );
}
}
void PhotoPluginModel::parseFile( const QByteArray& file )
{
QList<PhotoPluginItem*> list;
FlickrParser parser( m_marbleWidget, &list, this );
parser.read( file );
QList<PhotoPluginItem*>::iterator it;
QList<AbstractDataPluginItem*> items;
for( it = list.begin(); it != list.end(); ++it ) {
if( itemExists( (*it)->id() ) ) {
delete (*it);
continue;
}
downloadItem( (*it)->photoUrl(), "thumbnail", (*it) );
downloadItem( (*it)->infoUrl(), "info", (*it) );
items << *it;
}
addItemsToList( items );
}
void PhotoPluginModel::setMarbleWidget( MarbleWidget *widget )
{
m_marbleWidget = widget;
}
void PhotoPluginModel::setLicenseValues( const QString &licenses )
{
m_licenses = licenses;
}
#include "moc_PhotoPluginModel.cpp"
diff --git a/src/plugins/render/photo/PhotoPluginModel.h b/src/plugins/render/photo/PhotoPluginModel.h
index 29d7ad34e..d653731ad 100644
--- a/src/plugins/render/photo/PhotoPluginModel.h
+++ b/src/plugins/render/photo/PhotoPluginModel.h
@@ -1,62 +1,62 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#ifndef PHOTOPLUGINMODEL_H
#define PHOTOPLUGINMODEL_H
#include "AbstractDataPluginModel.h"
namespace Marble
{
class MarbleWidget;
const quint32 numberOfImagesPerFetch = 15;
class PhotoPluginModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- explicit PhotoPluginModel( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit PhotoPluginModel( const MarbleModel *marbleModel, QObject *parent = nullptr );
static QUrl generateUrl( const QString& service,
const QString& method,
const QHash<QString,QString>& options );
void setMarbleWidget( MarbleWidget* widget );
void setLicenseValues( const QString &licenses );
protected:
/**
* Generates the download url for the description file from the web service depending on
* the @p box surrounding the view and the @p number of files to show.
**/
void getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number = 10 ) override;
/**
* The reimplementation has to parse the @p file and should generate items. This items
* have to be scheduled to downloadItemData or could be directly added to the list,
* depending on if they have to download information to be shown.
**/
void parseFile( const QByteArray& file ) override;
private:
MarbleWidget *m_marbleWidget;
QString m_licenses;
};
}
#endif //PHOTOPLUGINMODEL_H
diff --git a/src/plugins/render/positionmarker/PositionMarker.cpp b/src/plugins/render/positionmarker/PositionMarker.cpp
index d1750f0d1..cd8251955 100644
--- a/src/plugins/render/positionmarker/PositionMarker.cpp
+++ b/src/plugins/render/positionmarker/PositionMarker.cpp
@@ -1,480 +1,480 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Andrew Manson <g.real.ate@gmail.com>
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
// Copyright 2010 Thibaut Gridel <tgridel@free.fr>
// Copyright 2010 Daniel Marth <danielmarth@gmx.at>
//
#include "PositionMarker.h"
#include "MarbleDebug.h"
#include <QRect>
#include <qmath.h>
#include <QFileDialog>
#include <QPushButton>
#include <QColorDialog>
#include <QTransform>
#include <cmath>
#include "ui_PositionMarkerConfigWidget.h"
#include "MarbleModel.h"
#include "MarbleDirs.h"
#include "GeoPainter.h"
#include "PositionTracking.h"
#include "ViewportParams.h"
#include "Planet.h"
#include "GeoDataAccuracy.h"
namespace Marble
{
const int PositionMarker::sm_defaultSizeStep = 2;
const float PositionMarker::sm_resizeSteps[] = { 0.25, 0.5, 1.0, 2.0, 4.0 };
const int PositionMarker::sm_numResizeSteps = sizeof( sm_resizeSteps ) / sizeof( sm_resizeSteps[0] );
PositionMarker::PositionMarker( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
m_marbleModel( marbleModel ),
m_isInitialized( false ),
m_useCustomCursor( false ),
m_defaultCursorPath(MarbleDirs::path(QStringLiteral("svg/track_turtle.svg"))),
m_lastBoundingBox(),
- ui_configWidget( 0 ),
- m_configDialog( 0 ),
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr ),
m_cursorPath( m_defaultCursorPath ),
m_cursorSize( 1.0 ),
m_accuracyColor( Oxygen::brickRed4 ),
m_trailColor( 0, 0, 255 ),
m_heading( 0.0 ),
m_showTrail ( false )
{
const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
m_accuracyColor.setAlpha( smallScreen ? 80 : 40 );
}
PositionMarker::~PositionMarker ()
{
delete ui_configWidget;
delete m_configDialog;
}
QStringList PositionMarker::renderPosition() const
{
return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE"));
}
QString PositionMarker::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList PositionMarker::backendTypes() const
{
return QStringList(QStringLiteral("positionmarker"));
}
QString PositionMarker::name() const
{
return tr( "Position Marker" );
}
QString PositionMarker::guiString() const
{
return tr( "&Position Marker" );
}
QString PositionMarker::nameId() const
{
return QStringLiteral("positionMarker");
}
QString PositionMarker::version() const
{
return QStringLiteral("1.0");
}
QString PositionMarker::description() const
{
return tr( "draws a marker at the current position" );
}
QString PositionMarker::copyrightYears() const
{
return QStringLiteral("2009, 2010");
}
QVector<PluginAuthor> PositionMarker::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Andrew Manson"), QStringLiteral("g.real.ate@gmail.com"))
<< PluginAuthor(QStringLiteral("Eckhart Woerner"), QStringLiteral("ewoerner@kde.org"))
<< PluginAuthor(QStringLiteral("Thibaut Gridel"), QStringLiteral("tgridel@free.fr"))
<< PluginAuthor(QStringLiteral("Daniel Marth"), QStringLiteral("danielmarth@gmx.at"));
}
QIcon PositionMarker::icon() const
{
return QIcon(QStringLiteral(":/icons/positionmarker.png"));
}
QDialog *PositionMarker::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::PositionMarkerConfigWidget;
ui_configWidget->setupUi( m_configDialog );
ui_configWidget->m_resizeSlider->setMaximum( sm_numResizeSteps - 1 );
readSettings();
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
connect( ui_configWidget->m_buttonBox->button( QDialogButtonBox::RestoreDefaults ), SIGNAL(clicked()),
SLOT(restoreDefaultSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_fileChooserButton, SIGNAL(clicked()),
SLOT(chooseCustomCursor()) );
connect( ui_configWidget->m_resizeSlider, SIGNAL(valueChanged(int)),
SLOT(resizeCursor(int)) );
connect( ui_configWidget->m_acColorChooserButton, SIGNAL(clicked()),
SLOT(chooseColor()) );
connect( ui_configWidget->m_trailColorChooserButton, SIGNAL(clicked()),
SLOT(chooseColor()) );
}
return m_configDialog;
}
void PositionMarker::initialize()
{
if ( marbleModel() ) {
connect( marbleModel()->positionTracking(), SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
this, SLOT(setPosition(GeoDataCoordinates)) );
connect( marbleModel()->positionTracking(), SIGNAL(statusChanged(PositionProviderStatus)),
this, SIGNAL(repaintNeeded()) );
m_isInitialized = true;
}
loadDefaultCursor();
}
bool PositionMarker::isInitialized() const
{
return m_isInitialized;
}
bool PositionMarker::render( GeoPainter *painter,
ViewportParams *viewport,
const QString& renderPos,
GeoSceneLayer * layer )
{
Q_UNUSED( renderPos )
Q_UNUSED( layer )
- bool const gpsActive = marbleModel()->positionTracking()->positionProviderPlugin() != 0;
+ bool const gpsActive = marbleModel()->positionTracking()->positionProviderPlugin() != nullptr;
bool const positionAvailable = marbleModel()->positionTracking()->status() == PositionProviderStatusAvailable;
bool const positionValid = m_currentPosition.isValid();
if ( gpsActive && positionAvailable && positionValid ) {
m_lastBoundingBox = viewport->viewLatLonAltBox();
qreal screenPositionX, screenPositionY;
if (!viewport->screenCoordinates( m_currentPosition, screenPositionX, screenPositionY )){
return true;
}
const GeoDataCoordinates top( m_currentPosition.longitude(), m_currentPosition.latitude()+0.1 );
qreal screenTopX, screenTopY;
if (!viewport->screenCoordinates( top, screenTopX, screenTopY )){
return true;
}
qreal const correction = -90.0 + RAD2DEG * atan2( screenPositionY -screenTopY, screenPositionX - screenTopX );
const qreal rotation = m_heading + correction;
if ( m_useCustomCursor ) {
QTransform transform;
transform.rotate( rotation );
bool const highQuality = painter->mapQuality() == HighQuality || painter->mapQuality() == PrintQuality;
Qt::TransformationMode const mode = highQuality ? Qt::SmoothTransformation : Qt::FastTransformation;
m_customCursorTransformed = m_customCursor.transformed( transform, mode );
} else {
// Calculate the scaled arrow shape
const QPointF baseX( m_cursorSize, 0.0 );
const QPointF baseY( 0.0, m_cursorSize );
const QPointF relativeLeft = - ( baseX * 9 ) + ( baseY * 9 );
const QPointF relativeRight = ( baseX * 9 ) + ( baseY * 9 );
const QPointF relativeTip = - ( baseY * 19.0 );
m_arrow = QPolygonF() << QPointF( 0.0, 0.0 ) << relativeLeft << relativeTip << relativeRight;
// Rotate the shape according to the current direction and move it to the screen center
QMatrix transformation;
transformation.translate( screenPositionX, screenPositionY );
transformation.rotate( rotation );
m_arrow = m_arrow * transformation;
m_dirtyRegion = QRegion();
m_dirtyRegion += ( m_arrow.boundingRect().toRect() );
m_dirtyRegion += ( m_previousArrow.boundingRect().toRect() );
}
painter->save();
GeoDataAccuracy accuracy = marbleModel()->positionTracking()->accuracy();
if ( accuracy.horizontal > 0 && accuracy.horizontal < 1000 ) {
// Paint a circle indicating the position accuracy
painter->setPen( Qt::transparent );
qreal planetRadius = m_marbleModel->planet()->radius();
int width = qRound( accuracy.horizontal * viewport->radius() / planetRadius );
if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) {
int arrowSize = qMax<int>( m_arrow.boundingRect().width(), m_arrow.boundingRect().height() );
width = qMax<int>( width, arrowSize + 10 );
}
painter->setBrush( m_accuracyColor );
painter->drawEllipse( m_currentPosition, width, width );
}
// Draw trail if requested.
if( m_showTrail ) {
painter->save();
// Use selected color to draw trail.
painter->setBrush( m_trailColor );
painter->setPen( m_trailColor );
// we don't draw m_trail[0] which is current position
for( int i = 1; i < m_trail.size(); ++i ) {
// Get screen coordinates from coordinates on the map.
qreal trailPointX, trailPointY;
viewport->screenCoordinates( m_trail[i], trailPointX, trailPointY );
const int size = ( sm_numTrailPoints - i ) * 3;
QRectF trailRect;
trailRect.setX( trailPointX - size / 2.0 );
trailRect.setY( trailPointY - size / 2.0 );
trailRect.setWidth( size );
trailRect.setHeight( size );
const qreal opacity = 1.0 - 0.15 * ( i - 1 );
painter->setOpacity( opacity );
painter->drawEllipse( trailRect );
}
painter->restore();
}
if( m_useCustomCursor)
{
painter->drawPixmap( m_currentPosition, m_customCursorTransformed );
}
else
{
painter->setPen( Qt::black );
painter->setBrush( Qt::white );
painter->drawPolygon( m_arrow );
}
painter->restore();
m_previousArrow = m_arrow;
}
return true;
}
QHash<QString,QVariant> PositionMarker::settings() const
{
QHash<QString, QVariant> settings = RenderPlugin::settings();
settings.insert(QStringLiteral("useCustomCursor"), m_useCustomCursor);
settings.insert(QStringLiteral("cursorPath"), m_cursorPath);
settings.insert(QStringLiteral("cursorSize"), m_cursorSize);
settings.insert(QStringLiteral("acColor"), m_accuracyColor);
settings.insert(QStringLiteral("trailColor"), m_trailColor);
settings.insert(QStringLiteral("showTrail"), m_showTrail);
return settings;
}
void PositionMarker::setSettings( const QHash<QString, QVariant> &settings )
{
RenderPlugin::setSettings( settings );
const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
QColor defaultColor = Oxygen::brickRed4;
defaultColor.setAlpha( smallScreen ? 80 : 40 );
m_useCustomCursor = settings.value(QStringLiteral("useCustomCursor"), false).toBool();
m_cursorPath = settings.value(QStringLiteral("cursorPath"), m_defaultCursorPath).toString();
m_cursorSize = settings.value(QStringLiteral("cursorSize"), 1.0).toFloat();
loadCustomCursor( m_cursorPath, m_useCustomCursor );
m_accuracyColor = settings.value(QStringLiteral("acColor"), defaultColor).value<QColor>();
m_trailColor = settings.value(QStringLiteral("trailColor"), QColor(0, 0, 255)).value<QColor>();
m_showTrail = settings.value(QStringLiteral("showTrail"), false).toBool();
readSettings();
}
void PositionMarker::readSettings()
{
if ( !m_configDialog ) {
return;
}
if( m_useCustomCursor )
ui_configWidget->m_customCursor->click();
else
ui_configWidget->m_originalCursor->click();
bool found = false;
float cursorSize = m_cursorSize;
for( int i = 0; i < sm_numResizeSteps && !found; i++ )
{
if( sm_resizeSteps[i] == cursorSize )
{
ui_configWidget->m_resizeSlider->setValue( i );
found = true;
}
}
if( !found )
{
ui_configWidget->m_resizeSlider->setValue( sm_defaultSizeStep );
cursorSize = sm_resizeSteps[sm_defaultSizeStep];
}
ui_configWidget->m_sizeLabel->setText( tr( "Cursor Size: %1" ).arg( cursorSize ) );
QPalette palette = ui_configWidget->m_acColorChooserButton->palette();
palette.setColor( QPalette::Button, m_accuracyColor );
ui_configWidget->m_acColorChooserButton->setPalette( palette );
palette = ui_configWidget->m_trailColorChooserButton->palette();
palette.setColor( QPalette::Button, m_trailColor );
ui_configWidget->m_trailColorChooserButton->setPalette( palette );
ui_configWidget->m_trailCheckBox->setChecked( m_showTrail );
}
void PositionMarker::writeSettings()
{
if ( !m_configDialog ) {
return;
}
m_useCustomCursor = ui_configWidget->m_customCursor->isChecked();
m_cursorPath = m_cursorPath;
m_cursorSize = sm_resizeSteps[ui_configWidget->m_resizeSlider->value()];
m_accuracyColor = m_accuracyColor;
m_trailColor = m_trailColor;
m_showTrail = ui_configWidget->m_trailCheckBox->isChecked();
emit settingsChanged( nameId() );
}
void PositionMarker::setPosition( const GeoDataCoordinates &position )
{
m_previousPosition = m_currentPosition;
m_currentPosition = position;
m_heading = marbleModel()->positionTracking()->direction();
// Update the trail
m_trail.push_front( m_currentPosition );
for( int i = sm_numTrailPoints + 1; i< m_trail.size(); ++i ) {
m_trail.pop_back();
}
if ( m_lastBoundingBox.contains( m_currentPosition ) )
{
emit repaintNeeded( m_dirtyRegion );
}
}
void PositionMarker::chooseCustomCursor()
{
- QString filename = QFileDialog::getOpenFileName( NULL, tr( "Choose Custom Cursor" ) );
+ QString filename = QFileDialog::getOpenFileName( nullptr, tr( "Choose Custom Cursor" ) );
if( !filename.isEmpty() )
loadCustomCursor( filename, true );
}
void PositionMarker::loadCustomCursor( const QString& filename, bool useCursor )
{
m_customCursor = QPixmap( filename ).scaled( 22 * m_cursorSize, 22 * m_cursorSize, Qt::KeepAspectRatio, Qt::SmoothTransformation );
if( !m_customCursor.isNull() )
{
if( m_configDialog )
{
if( useCursor )
ui_configWidget->m_customCursor->click();
ui_configWidget->m_fileChooserButton->setIconSize( QSize( m_customCursor.width(), m_customCursor.height() ) );
ui_configWidget->m_fileChooserButton->setIcon( QIcon( m_customCursor ) );
}
m_cursorPath = filename;
}
else
{
mDebug() << "Unable to load custom cursor from " << filename << ". "
<< "The default cursor will be used instead";
if ( m_configDialog )
ui_configWidget->m_fileChooserButton->setIcon( QIcon( m_defaultCursor ) );
m_customCursor = m_defaultCursor;
m_cursorPath = m_defaultCursorPath;
}
}
void PositionMarker::loadDefaultCursor()
{
m_defaultCursor = QPixmap( m_defaultCursorPath ).scaled( 22 * m_cursorSize, 22 * m_cursorSize, Qt::KeepAspectRatio, Qt::SmoothTransformation );
}
void PositionMarker::chooseColor()
{
QColor initialColor;
if( sender() == ui_configWidget->m_acColorChooserButton ) {
initialColor = m_accuracyColor;
}
else if( sender() == ui_configWidget->m_trailColorChooserButton ) {
initialColor = m_trailColor;
}
- QColor color = QColorDialog::getColor( initialColor, NULL,
+ QColor color = QColorDialog::getColor( initialColor, nullptr,
tr( "Please choose a color" ),
QColorDialog::ShowAlphaChannel );
if( color.isValid() )
{
QPalette palette;
if( sender() == ui_configWidget->m_acColorChooserButton ) {
m_accuracyColor = color;
palette = ui_configWidget->m_acColorChooserButton->palette();
palette.setColor( QPalette::Button, m_accuracyColor );
ui_configWidget->m_acColorChooserButton->setPalette( palette );
}
else if( sender() == ui_configWidget->m_trailColorChooserButton ) {
m_trailColor = color;
palette = ui_configWidget->m_trailColorChooserButton->palette();
palette.setColor( QPalette::Button, m_trailColor );
ui_configWidget->m_trailColorChooserButton->setPalette( palette );
}
}
}
void PositionMarker::resizeCursor( int step )
{
m_cursorSize = sm_resizeSteps[step];
float newSize = 22 * m_cursorSize;
m_customCursor = QPixmap( m_cursorPath ).scaled( newSize, newSize, Qt::KeepAspectRatio, Qt::SmoothTransformation );
ui_configWidget->m_sizeLabel->setText( tr( "Cursor Size: %1" ).arg( m_cursorSize ) );
if( !m_customCursor.isNull() )
{
ui_configWidget->m_fileChooserButton->setIconSize( QSize( m_customCursor.width(), m_customCursor.height() ) );
ui_configWidget->m_fileChooserButton->setIcon( QIcon( m_customCursor ) );
}
loadDefaultCursor();
}
qreal PositionMarker::zValue() const
{
return 1.0;
}
}
#include "moc_PositionMarker.cpp"
diff --git a/src/plugins/render/positionmarker/PositionMarker.h b/src/plugins/render/positionmarker/PositionMarker.h
index 36658e6fa..98b1ccefa 100644
--- a/src/plugins/render/positionmarker/PositionMarker.h
+++ b/src/plugins/render/positionmarker/PositionMarker.h
@@ -1,141 +1,141 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2007 Andrew Manson <g.real.ate@gmail.com>
// Copyright 2009 Eckhart Wörner <ewoerner@kde.org>
// Copyright 2010 Thibaut Gridel <tgridel@free.fr>
//
#ifndef POSITION_MARKER_H
#define POSITION_MARKER_H
#include <QHash>
#include <QVector>
#include <QColor>
#include <QPolygon>
#include <QPixmap>
#include "DialogConfigurationInterface.h"
#include "RenderPlugin.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLatLonAltBox.h"
namespace Ui
{
class PositionMarkerConfigWidget;
}
namespace Marble
{
class PositionMarker : public RenderPlugin, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.PositionMarker")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN( PositionMarker )
public:
- explicit PositionMarker(const MarbleModel *marbleModel = 0 );
+ explicit PositionMarker(const MarbleModel *marbleModel = nullptr );
~PositionMarker () override;
QStringList renderPosition() const override;
QString renderPolicy() const override;
QStringList backendTypes() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
QDialog *configDialog() override;
void initialize () override;
bool isInitialized () const override;
bool render( GeoPainter *painter, ViewportParams *viewport,
- const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
// Overriding LayerInterface to paint on top of the route
qreal zValue() const override;
/**
* @return: The settings of the item.
*/
QHash<QString,QVariant> settings() const override;
/**
* Set the settings of the item.
*/
void setSettings( const QHash<QString,QVariant> &settings ) override;
public Q_SLOTS:
void readSettings();
void writeSettings();
void setPosition( const GeoDataCoordinates &position );
void chooseCustomCursor();
void chooseColor();
void resizeCursor( int step );
private:
Q_DISABLE_COPY( PositionMarker )
void loadCustomCursor( const QString& filename, bool useCursor );
void loadDefaultCursor();
const MarbleModel *m_marbleModel;
bool m_isInitialized;
bool m_useCustomCursor;
const QString m_defaultCursorPath;
GeoDataLatLonAltBox m_lastBoundingBox;
GeoDataCoordinates m_currentPosition;
GeoDataCoordinates m_previousPosition;
Ui::PositionMarkerConfigWidget *ui_configWidget;
QDialog *m_configDialog;
QString m_cursorPath;
QPolygonF m_arrow;
QPolygonF m_previousArrow;
QRegion m_dirtyRegion;
QPixmap m_customCursor;
QPixmap m_customCursorTransformed;
QPixmap m_defaultCursor;
float m_cursorSize;
QColor m_accuracyColor;
QColor m_trailColor;
qreal m_heading;
QVector<GeoDataCoordinates> m_trail;
static const int sm_numTrailPoints = 6;
bool m_showTrail;
static const int sm_defaultSizeStep;
static const int sm_numResizeSteps;
static const float sm_resizeSteps[];
};
}
#endif
diff --git a/src/plugins/render/postalcode/PostalCodeModel.h b/src/plugins/render/postalcode/PostalCodeModel.h
index e43e16cb1..f5c215b8c 100644
--- a/src/plugins/render/postalcode/PostalCodeModel.h
+++ b/src/plugins/render/postalcode/PostalCodeModel.h
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Valery Kharitonov <kharvd@gmail.com>
//
#ifndef POSTALCODEMODEL_H
#define POSTALCODEMODEL_H
#include "AbstractDataPluginModel.h"
namespace Marble {
class PostalCodeModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- explicit PostalCodeModel( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit PostalCodeModel( const MarbleModel *marbleModel, QObject *parent = nullptr );
~PostalCodeModel() override;
protected:
/**
* Generates the download url for the description file from the web service depending on
* the @p box surrounding the view and the @p number of files to show.
**/
void getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number = 10 ) override;
/**
* Parses the @p file which getAdditionalItems downloads and
* prepares the data for usage.
**/
void parseFile( const QByteArray& file ) override;
private:
static void addLine( QString* string, const QString &line );
};
}
#endif // POSTALCODEMODEL_H
diff --git a/src/plugins/render/postalcode/PostalCodePlugin.cpp b/src/plugins/render/postalcode/PostalCodePlugin.cpp
index cfc3cef48..a3d743120 100644
--- a/src/plugins/render/postalcode/PostalCodePlugin.cpp
+++ b/src/plugins/render/postalcode/PostalCodePlugin.cpp
@@ -1,77 +1,77 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Valery Kharitonov <kharvd@gmail.com>
//
#include "PostalCodePlugin.h"
#include "PostalCodeModel.h"
#include <QIcon>
using namespace Marble;
PostalCodePlugin::PostalCodePlugin()
- : AbstractDataPlugin( 0 )
+ : AbstractDataPlugin( nullptr )
{
}
PostalCodePlugin::PostalCodePlugin( const MarbleModel *marbleModel )
: AbstractDataPlugin( marbleModel )
{
setEnabled( true );
setVisible( false );
}
void PostalCodePlugin::initialize()
{
setModel( new PostalCodeModel( marbleModel(), this ) );
setNumberOfItems( 20 );
}
QString PostalCodePlugin::name() const
{
return tr( "Postal Codes" );
}
QString PostalCodePlugin::guiString() const
{
return tr( "Postal Codes" );
}
QString PostalCodePlugin::nameId() const
{
return QStringLiteral("postalCode");
}
QString PostalCodePlugin::version() const
{
return QStringLiteral("1.0");
}
QString PostalCodePlugin::copyrightYears() const
{
return QStringLiteral("2011");
}
QVector<PluginAuthor> PostalCodePlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Valery Kharitonov"), QStringLiteral("kharvd@gmail.com"));
}
QString PostalCodePlugin::description() const
{
return tr( "Shows postal codes of the area on the map." );
}
QIcon PostalCodePlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/postalcode.png"));
}
#include "moc_PostalCodePlugin.cpp"
diff --git a/src/plugins/render/progress/ProgressFloatItem.h b/src/plugins/render/progress/ProgressFloatItem.h
index 4053a87dd..d95760135 100644
--- a/src/plugins/render/progress/ProgressFloatItem.h
+++ b/src/plugins/render/progress/ProgressFloatItem.h
@@ -1,110 +1,110 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef PROGRESS_FLOAT_ITEM_H
#define PROGRESS_FLOAT_ITEM_H
#include "AbstractFloatItem.h"
#include <QMutex>
#include <QTimer>
#include <QIcon>
namespace Marble
{
/**
* @brief A float item that shows a pie-chart progress
* indicator when downloads are active
*/
class ProgressFloatItem : public AbstractFloatItem
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.ProgressFloatItem")
Q_INTERFACES( Marble::RenderPluginInterface )
MARBLE_PLUGIN( ProgressFloatItem )
public:
- explicit ProgressFloatItem( const MarbleModel *marbleModel = 0 );
+ explicit ProgressFloatItem( const MarbleModel *marbleModel = nullptr );
~ProgressFloatItem () override;
QStringList backendTypes() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
QPainterPath backgroundShape() const override;
void paintContent( QPainter *painter ) override;
private Q_SLOTS:
void removeProgressItem();
void handleProgress( int active, int queued );
void hideProgress();
void show();
void scheduleRepaint();
private:
Q_DISABLE_COPY( ProgressFloatItem )
bool active() const;
void setActive( bool active );
bool m_isInitialized;
int m_totalJobs;
int m_completedJobs;
qreal m_completed;
QTimer m_progressHideTimer;
QTimer m_progressShowTimer;
QMutex m_jobMutex;
bool m_active;
QIcon m_icon;
int m_fontSize;
QTimer m_repaintTimer;
};
}
#endif
diff --git a/src/plugins/render/routing/AudioOutput.cpp b/src/plugins/render/routing/AudioOutput.cpp
index a7179cb1b..df3a69c1f 100644
--- a/src/plugins/render/routing/AudioOutput.cpp
+++ b/src/plugins/render/routing/AudioOutput.cpp
@@ -1,140 +1,140 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "AudioOutput.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "routing/VoiceNavigationModel.h"
#include "routing/Route.h"
#include <QUrl>
#include <phonon/MediaObject>
#include <phonon/MediaSource>
#include <phonon/AudioOutput>
namespace Marble
{
class AudioOutputPrivate
{
public:
AudioOutput *q;
Phonon::MediaObject *m_output;
bool m_muted;
VoiceNavigationModel m_voiceNavigation;
AudioOutputPrivate( AudioOutput* parent );
void audioOutputFinished();
void setupAudio();
void reset();
void playInstructions();
};
AudioOutputPrivate::AudioOutputPrivate( AudioOutput* parent ) :
- q( parent ), m_output( 0 ), m_muted( false )
+ q( parent ), m_output( nullptr ), m_muted( false )
{
QObject::connect( &m_voiceNavigation, SIGNAL(instructionChanged()),
q, SLOT(playInstructions()) );
}
void AudioOutputPrivate::audioOutputFinished()
{
m_output->setCurrentSource( Phonon::MediaSource() );
m_output->clearQueue();
}
void AudioOutputPrivate::setupAudio()
{
if ( !m_output ) {
m_output = new Phonon::MediaObject( q );
Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput( Phonon::VideoCategory, q );
Phonon::createPath( m_output, audioOutput );
q->connect( m_output, SIGNAL(finished()), q, SLOT(audioOutputFinished()) );
}
}
void AudioOutputPrivate::reset()
{
if ( m_output ) {
m_output->stop();
m_output->setCurrentSource( Phonon::MediaSource() );
m_output->clearQueue();
}
m_voiceNavigation.reset();
}
void AudioOutputPrivate::playInstructions()
{
setupAudio();
if ( m_output ) {
m_output->enqueue( QUrl::fromLocalFile( m_voiceNavigation.instruction() ) );
m_output->play();
}
}
AudioOutput::AudioOutput( QObject* parent ) : QObject( parent ),
d( new AudioOutputPrivate( this ) )
{
setSoundEnabled( false );
}
AudioOutput::~AudioOutput()
{
delete d;
}
void AudioOutput::update(const Route &route, qreal distanceManeuver, qreal distanceTarget, bool deviated )
{
d->m_voiceNavigation.update( route, distanceManeuver, distanceTarget, deviated );
}
void AudioOutput::setMuted( bool muted )
{
d->m_muted = muted;
}
bool AudioOutput::isMuted() const
{
return d->m_muted;
}
void AudioOutput::setSpeaker( const QString &speaker )
{
d->m_voiceNavigation.setSpeaker( speaker );
}
QString AudioOutput::speaker() const
{
return d->m_voiceNavigation.speaker();
}
void AudioOutput::setSoundEnabled( bool enabled )
{
d->m_voiceNavigation.setSpeakerEnabled( !enabled );
}
bool AudioOutput::isSoundEnabled() const
{
return !d->m_voiceNavigation.isSpeakerEnabled();
}
}
#include "moc_AudioOutput.cpp"
diff --git a/src/plugins/render/routing/AudioOutput.h b/src/plugins/render/routing/AudioOutput.h
index 3f19df260..d7d6c19c1 100644
--- a/src/plugins/render/routing/AudioOutput.h
+++ b/src/plugins/render/routing/AudioOutput.h
@@ -1,82 +1,82 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_AUDIOOUTPUT_H
#define MARBLE_AUDIOOUTPUT_H
#include <QObject>
namespace Marble
{
class Route;
class AudioOutputPrivate;
/**
* Audio (mainly voice) output of driving instructions
*/
class AudioOutput : public QObject
{
Q_OBJECT
public:
/** Constructor */
- explicit AudioOutput( QObject* parent = 0 );
+ explicit AudioOutput( QObject* parent = nullptr );
/** Destructor */
~AudioOutput() override;
/**
* Generate an audible notification (if needed) after the position on the route has changed.
* No notification will be generated if the turn point with the given index is too far away,
* has been announced previously, if the output is @see setMuted or the needed sounds cannot
* be found in the Marble data path.
* @param index The index of the next turn point
* @param distance The distance in meters to the next turn point
* @param turnType The turn type to execute at the next turn point
*/
void update( const Route &route, qreal distanceManeuver, qreal distanceTarget, bool deviated );
/** Toggle muting (neither sound nor voice output) */
void setMuted( bool muted );
bool isMuted() const;
/**
* Change the speaker to use.
* @param speaker A directory name in audio/speakers in Marble's data path. This directory
* is expected to contain ogg files containing the instructions: TurnLeft.ogg, RbExit3.ogg etc.
* Disabled by setSoundEnabled(true) and overridden by setMuted(true).
* @see setSoundEnabled
* @see setMuted
*/
void setSpeaker( const QString &speaker );
QString speaker() const;
/**
* Toggle whether sound output is used instead of a speaker. Overridden by setMuted(true).
* @see setMuted
*/
void setSoundEnabled( bool enabled );
bool isSoundEnabled() const;
private:
Q_PRIVATE_SLOT( d, void audioOutputFinished() )
Q_PRIVATE_SLOT( d, void playInstructions() )
AudioOutputPrivate * const d;
};
}
#endif // MARBLE_AUDIOOUTPUT_H
diff --git a/src/plugins/render/routing/RoutingPlugin.cpp b/src/plugins/render/routing/RoutingPlugin.cpp
index 60ba59432..58d7bffcd 100644
--- a/src/plugins/render/routing/RoutingPlugin.cpp
+++ b/src/plugins/render/routing/RoutingPlugin.cpp
@@ -1,590 +1,590 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Siddharth Srivastava <akssps011@gmail.com>
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "RoutingPlugin.h"
#include "ui_RoutingPlugin.h"
#include "ui_RoutingConfigDialog.h"
#include "Planet.h"
#include "AudioOutput.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLookAt.h"
#include "GeoPainter.h"
#include "MarbleGraphicsGridLayout.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "MarbleLocale.h"
#include "MarbleDirs.h"
#include "PluginManager.h"
#include "PositionTracking.h"
#include "PositionProviderPlugin.h"
#include "routing/Route.h"
#include "routing/RoutingManager.h"
#include "routing/RoutingModel.h"
#include "routing/RouteRequest.h"
#include "routing/SpeakersModel.h"
#include "ViewportParams.h"
#include "WidgetGraphicsItem.h"
#include <QDialog>
#include <QPushButton>
namespace Marble
{
namespace
{
int const thresholdDistance = 1000; // in meter
}
class RoutingPluginPrivate
{
public:
MarbleWidget* m_marbleWidget;
WidgetGraphicsItem* m_widgetItem;
RoutingModel* m_routingModel;
Ui::RoutingPlugin m_widget;
bool m_nearNextInstruction;
bool m_guidanceModeEnabled;
AudioOutput* m_audio;
QDialog *m_configDialog;
Ui::RoutingConfigDialog m_configUi;
bool m_routeCompleted;
SpeakersModel* m_speakersModel;
RoutingPluginPrivate( RoutingPlugin* parent );
void updateZoomButtons( int zoomValue );
void updateZoomButtons();
void updateGuidanceModeButton();
void forceRepaint();
void updateButtonVisibility();
void reverseRoute();
void toggleGuidanceMode( bool enabled );
void updateDestinationInformation();
void updateGpsButton( PositionProviderPlugin *activePlugin );
void togglePositionTracking( bool enabled );
static QString richText( const QString &source );
static QString fuzzyDistance( qreal distanceMeter );
void readSettings();
qreal nextInstructionDistance() const;
qreal remainingDistance() const;
private:
RoutingPlugin* m_parent;
};
RoutingPluginPrivate::RoutingPluginPrivate( RoutingPlugin *parent ) :
- m_marbleWidget( 0 ),
- m_widgetItem( 0 ),
- m_routingModel( 0 ),
+ m_marbleWidget( nullptr ),
+ m_widgetItem( nullptr ),
+ m_routingModel( nullptr ),
m_nearNextInstruction( false ),
m_guidanceModeEnabled( false ),
m_audio( new AudioOutput( parent ) ),
- m_configDialog( 0 ),
+ m_configDialog( nullptr ),
m_routeCompleted( false ),
- m_speakersModel( 0 ),
+ m_speakersModel( nullptr ),
m_parent( parent )
{
m_audio->setMuted( false );
m_audio->setSoundEnabled( true );
}
QString RoutingPluginPrivate::richText( const QString &source )
{
return QLatin1String("<font size=\"+1\" color=\"black\">") + source + QLatin1String("</font>");
}
QString RoutingPluginPrivate::fuzzyDistance( qreal length )
{
int precision = 0;
QString distanceUnit = QLatin1String( "m" );
if ( MarbleGlobal::getInstance()->locale()->measurementSystem() != MarbleLocale::MetricSystem ) {
precision = 1;
distanceUnit = "mi";
length *= METER2KM;
length *= KM2MI;
} else if (MarbleGlobal::getInstance()->locale()->measurementSystem() ==
MarbleLocale::MetricSystem) {
if ( length >= 1000 ) {
length /= 1000;
distanceUnit = "km";
precision = 1;
} else if ( length >= 200 ) {
length = 50 * qRound( length / 50 );
} else if ( length >= 100 ) {
length = 25 * qRound( length / 25 );
} else {
length = 10 * qRound( length / 10 );
}
} else if (MarbleGlobal::getInstance()->locale()->measurementSystem() ==
MarbleLocale::NauticalSystem) {
precision = 2;
distanceUnit = "nm";
length *= METER2KM;
length *= KM2NM;
}
return QString( "%1 %2" ).arg( length, 0, 'f', precision ).arg( distanceUnit );
}
void RoutingPluginPrivate::updateZoomButtons( int zoomValue )
{
int const minZoom = m_marbleWidget ? m_marbleWidget->minimumZoom() : 900;
int const maxZoom = m_marbleWidget ? m_marbleWidget->maximumZoom() : 2400;
bool const zoomInEnabled = zoomValue < maxZoom;
bool const zoomOutEnabled = zoomValue > minZoom;
if ( ( zoomInEnabled != m_widget.zoomInButton->isEnabled() ) ||
( zoomOutEnabled != m_widget.zoomOutButton->isEnabled() ) ) {
m_widget.zoomInButton->setEnabled( zoomInEnabled );
m_widget.zoomOutButton->setEnabled( zoomOutEnabled );
forceRepaint();
}
}
void RoutingPluginPrivate::updateGuidanceModeButton()
{
bool const hasRoute = m_routingModel->rowCount() > 0;
m_widget.routingButton->setEnabled( hasRoute );
forceRepaint();
}
void RoutingPluginPrivate::forceRepaint()
{
m_parent->update();
emit m_parent->repaintNeeded();
}
void RoutingPluginPrivate::updateButtonVisibility()
{
bool const show = m_guidanceModeEnabled;
bool const near = show && m_nearNextInstruction;
m_widget.progressBar->setVisible( near );
m_widget.instructionIconLabel->setVisible( show );
m_widget.spacer->changeSize( show ? 10 : 0, 20 );
m_widget.instructionLabel->setVisible( show );
// m_widget.followingInstructionIconLabel->setVisible( show );
// Disabling the next instruction turn icon for now, it seems to confuse first time users.
m_widget.followingInstructionIconLabel->setVisible( false );
m_widget.destinationDistanceLabel->setVisible( show );
m_widget.gpsButton->setVisible( !show );
m_widget.zoomOutButton->setVisible( !show );
m_widget.zoomInButton->setVisible( !show );
m_widgetItem->widget()->updateGeometry();
QSize const size = m_widgetItem->widget()->sizeHint();
m_widgetItem->widget()->resize( size );
m_widgetItem->setContentSize( size );
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( smallScreen ) {
qreal const pluginWidth = size.width();
int x = -10;
if ( m_guidanceModeEnabled ) {
int const parentWidth = m_marbleWidget->width();
x = qRound( ( parentWidth - pluginWidth ) / 2.0 );
}
m_parent->setPosition( QPointF( x, m_parent->position().y() ) );
}
}
void RoutingPluginPrivate::updateZoomButtons()
{
if ( m_marbleWidget ) {
updateZoomButtons( m_marbleWidget->zoom() );
}
}
void RoutingPluginPrivate::toggleGuidanceMode( bool enabled )
{
if( !m_marbleWidget || m_guidanceModeEnabled == enabled ) {
return;
}
m_guidanceModeEnabled = enabled;
updateButtonVisibility();
if( enabled ) {
QObject::connect( m_routingModel, SIGNAL(positionChanged()),
m_parent, SLOT(updateDestinationInformation()) );
} else {
QObject::disconnect( m_routingModel, SIGNAL(positionChanged()),
m_parent, SLOT(updateDestinationInformation()) );
}
if ( enabled ) {
QString const text = QObject::tr( "Starting guidance mode, please wait..." );
m_widget.instructionLabel->setText( richText( "%1" ).arg( text ) );
}
if ( enabled ) {
RouteRequest* request = m_marbleWidget->model()->routingManager()->routeRequest();
if ( request && request->size() > 0 ) {
GeoDataCoordinates source = request->source();
if ( source.isValid() ) {
GeoDataLookAt view;
view.setCoordinates( source );
// By happy coincidence this equals OpenStreetMap tile level 15
view.setRange( 851.807 );
m_marbleWidget->flyTo( view );
}
}
}
m_marbleWidget->model()->routingManager()->setGuidanceModeEnabled( enabled );
if ( enabled ) {
m_routeCompleted = false;
}
forceRepaint();
}
void RoutingPluginPrivate::updateDestinationInformation()
{
if ( m_routingModel->route().currentSegment().isValid() ) {
qreal remaining = remainingDistance();
qreal distanceLeft = nextInstructionDistance();
m_audio->update( m_routingModel->route(), distanceLeft, remaining, m_routingModel->deviatedFromRoute() );
m_nearNextInstruction = distanceLeft < thresholdDistance;
QString pixmapHtml = "<img src=\":/flag.png\" /><br />";
m_widget.destinationDistanceLabel->setText( pixmapHtml + richText( fuzzyDistance( remaining ) ) );
m_widget.instructionIconLabel->setEnabled( m_nearNextInstruction );
m_widget.progressBar->setMaximum( thresholdDistance );
m_widget.progressBar->setValue( qRound( distanceLeft ) );
updateButtonVisibility();
QString pixmap = MarbleDirs::path(QStringLiteral("bitmaps/routing_step.png"));
pixmapHtml = QString( "<img src=\"%1\" />" ).arg( pixmap );
qreal planetRadius = m_marbleWidget->model()->planet()->radius();
GeoDataCoordinates const onRoute = m_routingModel->route().positionOnRoute();
GeoDataCoordinates const ego = m_routingModel->route().position();
qreal const distanceToRoute = planetRadius * ego.sphericalDistanceTo(onRoute);
if ( !m_routingModel->route().currentSegment().isValid() ) {
m_widget.instructionLabel->setText( richText( QObject::tr( "Calculate a route to get directions." ) ) );
m_widget.instructionIconLabel->setText( pixmapHtml );
} else if ( distanceToRoute > 300.0 ) {
m_widget.instructionLabel->setText( richText( QObject::tr( "Route left." ) ) );
m_widget.instructionIconLabel->setText( pixmapHtml );
} else if ( !m_routingModel->route().currentSegment().nextRouteSegment().isValid() ) {
m_widget.instructionLabel->setText( richText( QObject::tr( "Destination ahead." ) ) );
m_widget.instructionIconLabel->setText( pixmapHtml );
} else {
pixmap = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().directionPixmap();
QString const instructionText = m_routingModel->route().currentSegment().nextRouteSegment().maneuver().instructionText();
m_widget.instructionLabel->setText( richText( "%1" ).arg( instructionText ) );
pixmapHtml = QString( "<p align=\"center\"><img src=\"%1\" /><br />%2</p>" ).arg( pixmap );
m_widget.instructionIconLabel->setText( pixmapHtml.arg( richText( fuzzyDistance( distanceLeft ) ) ) );
if( remaining > 50 ) {
m_routeCompleted = false;
} else {
if ( !m_routeCompleted ) {
QString content = QObject::tr( "Arrived at destination. <a href=\"#reverse\">Calculate the way back.</a>" );
m_widget.instructionLabel->setText( richText( "%1" ).arg( content ) );
}
m_routeCompleted = true;
}
}
forceRepaint();
}
}
void RoutingPluginPrivate::updateGpsButton( PositionProviderPlugin *activePlugin )
{
- m_widget.gpsButton->setChecked( activePlugin != 0 );
+ m_widget.gpsButton->setChecked( activePlugin != nullptr );
forceRepaint();
}
void RoutingPluginPrivate::togglePositionTracking( bool enabled )
{
- PositionProviderPlugin* plugin = 0;
+ PositionProviderPlugin* plugin = nullptr;
if ( enabled ) {
const PluginManager* pluginManager = m_marbleWidget->model()->pluginManager();
QList<const PositionProviderPlugin*> plugins = pluginManager->positionProviderPlugins();
if ( plugins.size() > 0 ) {
plugin = plugins.first()->newInstance();
}
}
m_parent->marbleModel()->positionTracking()->setPositionProviderPlugin( plugin );
}
void RoutingPluginPrivate::reverseRoute()
{
if ( m_marbleWidget ) {
m_marbleWidget->model()->routingManager()->reverseRoute();
}
}
void RoutingPluginPrivate::readSettings()
{
if ( m_configDialog ) {
if ( !m_speakersModel ) {
m_speakersModel = new SpeakersModel( m_parent );
}
int const index = m_speakersModel->indexOf( m_audio->speaker() );
m_configUi.speakerComboBox->setModel( m_speakersModel );
m_configUi.speakerComboBox->setCurrentIndex( index );
m_configUi.voiceNavigationCheckBox->setChecked( !m_audio->isMuted() );
m_configUi.soundRadioButton->setChecked( m_audio->isSoundEnabled() );
m_configUi.speakerRadioButton->setChecked( !m_audio->isSoundEnabled() );
}
}
qreal RoutingPluginPrivate::nextInstructionDistance() const
{
GeoDataCoordinates position = m_routingModel->route().position();
GeoDataCoordinates interpolated = m_routingModel->route().positionOnRoute();
GeoDataCoordinates onRoute = m_routingModel->route().currentWaypoint();
qreal planetRadius = m_marbleWidget->model()->planet()->radius();
const qreal distance = planetRadius * (position.sphericalDistanceTo(interpolated) + interpolated.sphericalDistanceTo(onRoute));
const RouteSegment &segment = m_routingModel->route().currentSegment();
for (int i=0; i<segment.path().size(); ++i) {
if (segment.path()[i] == onRoute) {
return distance + segment.path().length( planetRadius, i );
}
}
return distance;
}
qreal RoutingPluginPrivate::remainingDistance() const
{
GeoDataCoordinates position = m_routingModel->route().currentSegment().maneuver().position();
bool foundSegment = false;
qreal distance = nextInstructionDistance();
for ( int i=0; i<m_routingModel->route().size(); ++i ) {
if ( foundSegment ) {
distance += m_routingModel->route().at( i ).distance();
} else {
foundSegment = m_routingModel->route().at( i ).maneuver().position() == position;
}
}
return distance;
}
void RoutingPlugin::writeSettings()
{
Q_ASSERT( d->m_configDialog );
int const index = d->m_configUi.speakerComboBox->currentIndex();
if ( index >= 0 ) {
QModelIndex const idx = d->m_speakersModel->index( index );
d->m_audio->setSpeaker( d->m_speakersModel->data( idx, SpeakersModel::Path ).toString() );
if ( !d->m_speakersModel->data( idx, SpeakersModel::IsLocal ).toBool() ) {
d->m_speakersModel->install( index );
}
}
d->m_audio->setMuted( !d->m_configUi.voiceNavigationCheckBox->isChecked() );
d->m_audio->setSoundEnabled( d->m_configUi.soundRadioButton->isChecked() );
d->readSettings();
emit settingsChanged( nameId() );
}
RoutingPlugin::RoutingPlugin() :
- AbstractFloatItem( 0 ),
- d( 0 )
+ AbstractFloatItem( nullptr ),
+ d( nullptr )
{
}
RoutingPlugin::RoutingPlugin( const MarbleModel *marbleModel ) :
AbstractFloatItem( marbleModel, QPointF( -10, -10 ) ),
d( new RoutingPluginPrivate( this ) )
{
setEnabled( true );
//plugin is visible by default on small screen devices
setVisible( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen );
setPadding( 0.5 );
setBorderWidth( 1 );
setBackground( QBrush( QColor( "white" ) ) );
}
RoutingPlugin::~RoutingPlugin()
{
delete d;
}
QStringList RoutingPlugin::backendTypes() const
{
return QStringList(QStringLiteral("routing"));
}
QString RoutingPlugin::name() const
{
return tr( "Routing" );
}
QString RoutingPlugin::guiString() const
{
return tr( "&Routing" );
}
QString RoutingPlugin::nameId() const
{
return QStringLiteral("routing");
}
QString RoutingPlugin::version() const
{
return QStringLiteral("1.0");
}
QString RoutingPlugin::description() const
{
return tr( "Routing information and navigation controls" );
}
QString RoutingPlugin::copyrightYears() const
{
return QStringLiteral("2010");
}
QVector<PluginAuthor> RoutingPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Siddharth Srivastava"), QStringLiteral("akssps011@gmail.com"))
<< PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"));
}
QIcon RoutingPlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/routeplanning.png"));
}
void RoutingPlugin::initialize()
{
QWidget *widget = new QWidget;
d->m_widget.setupUi( widget );
d->m_widgetItem = new WidgetGraphicsItem( this );
d->m_widgetItem->setWidget( widget );
PositionProviderPlugin* activePlugin = marbleModel()->positionTracking()->positionProviderPlugin();
d->updateGpsButton( activePlugin );
connect( marbleModel()->positionTracking(),
SIGNAL(positionProviderPluginChanged(PositionProviderPlugin*)),
this, SLOT(updateGpsButton(PositionProviderPlugin*)) );
d->m_widget.routingButton->setEnabled( false );
connect( d->m_widget.instructionLabel, SIGNAL(linkActivated(QString)),
this, SLOT(reverseRoute()) );
MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
layout->addItem( d->m_widgetItem, 0, 0 );
setLayout( layout );
d->updateButtonVisibility();
}
bool RoutingPlugin::isInitialized() const
{
return d->m_widgetItem;
}
bool RoutingPlugin::eventFilter( QObject *object, QEvent *e )
{
if ( d->m_marbleWidget || !enabled() || !visible() ) {
return AbstractFloatItem::eventFilter( object, e );
}
MarbleWidget *widget = dynamic_cast<MarbleWidget*> ( object );
if ( widget && !d->m_marbleWidget ) {
d->m_marbleWidget = widget;
d->m_routingModel = d->m_marbleWidget->model()->routingManager()->routingModel();
connect( d->m_widget.routingButton, SIGNAL(clicked(bool)),
this, SLOT(toggleGuidanceMode(bool)) );
connect( d->m_widget.gpsButton, SIGNAL(clicked(bool)),
this, SLOT(togglePositionTracking(bool)) );
connect( d->m_widget.zoomInButton, SIGNAL(clicked()),
d->m_marbleWidget, SLOT(zoomIn()) );
connect( d->m_widget.zoomOutButton, SIGNAL(clicked()),
d->m_marbleWidget, SLOT(zoomOut()) );
connect( d->m_marbleWidget, SIGNAL(themeChanged(QString)),
this, SLOT(updateZoomButtons()) );
connect( d->m_marbleWidget, SIGNAL(zoomChanged(int)),
this, SLOT(updateZoomButtons(int)) );
connect( d->m_routingModel, SIGNAL(currentRouteChanged()),
this, SLOT(updateGuidanceModeButton()) );
d->updateGuidanceModeButton();
}
return AbstractFloatItem::eventFilter( object, e );
}
QHash<QString,QVariant> RoutingPlugin::settings() const
{
QHash<QString, QVariant> result = AbstractFloatItem::settings();
result.insert(QStringLiteral("muted"), d->m_audio->isMuted());
result.insert(QStringLiteral("sound"), d->m_audio->isSoundEnabled());
result.insert(QStringLiteral("speaker"), d->m_audio->speaker());
return result;
}
void RoutingPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractFloatItem::setSettings( settings );
d->m_audio->setMuted(settings.value(QStringLiteral("muted"), false).toBool());
d->m_audio->setSoundEnabled(settings.value(QStringLiteral("sound"), true).toBool());
d->m_audio->setSpeaker(settings.value(QStringLiteral("speaker")).toString());
d->readSettings();
}
QDialog *RoutingPlugin::configDialog()
{
if ( !d->m_configDialog ) {
d->m_configDialog = new QDialog;
d->m_configUi.setupUi( d->m_configDialog );
d->readSettings();
connect( d->m_configDialog, SIGNAL(accepted()), this, SLOT(writeSettings()) );
connect( d->m_configDialog, SIGNAL(rejected()), this, SLOT(readSettings()) );
connect( d->m_configUi.buttonBox->button( QDialogButtonBox::Reset ), SIGNAL(clicked()),
SLOT(restoreDefaultSettings()) );
}
return d->m_configDialog;
}
}
#include "moc_RoutingPlugin.cpp"
diff --git a/src/plugins/render/satellites/SatellitesConfigAbstractItem.cpp b/src/plugins/render/satellites/SatellitesConfigAbstractItem.cpp
index b99ff3e23..ced854373 100644
--- a/src/plugins/render/satellites/SatellitesConfigAbstractItem.cpp
+++ b/src/plugins/render/satellites/SatellitesConfigAbstractItem.cpp
@@ -1,96 +1,96 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
//
#include "SatellitesConfigAbstractItem.h"
#include "MarbleDebug.h"
#include <QVariant>
namespace Marble {
SatellitesConfigAbstractItem::SatellitesConfigAbstractItem( const QString &name )
: m_name( name ),
- m_parent( 0 ),
+ m_parent( nullptr ),
m_flags( Qt::ItemIsEnabled | Qt::ItemIsUserCheckable )
{
}
SatellitesConfigAbstractItem::~SatellitesConfigAbstractItem()
{
}
QString SatellitesConfigAbstractItem::name() const
{
return m_name;
}
int SatellitesConfigAbstractItem::row() const
{
- if ( m_parent != 0 ) {
+ if ( m_parent != nullptr ) {
return m_parent->indexOf( this );
}
return 0;
}
SatellitesConfigAbstractItem *SatellitesConfigAbstractItem::parent() const
{
return m_parent;
}
void SatellitesConfigAbstractItem::setParent( SatellitesConfigAbstractItem *parent )
{
m_parent = parent;
}
void SatellitesConfigAbstractItem::loadSettings(const QHash<QString, QVariant> &settings)
{
Q_UNUSED( settings );
}
QVariant SatellitesConfigAbstractItem::data( int column, int role ) const
{
if ( column != 0 ) {
return QVariant();
}
switch ( role ) {
case Qt::DisplayRole:
return QVariant( name() );
default:
return QVariant();
}
}
bool SatellitesConfigAbstractItem::setData( int column, int role, const QVariant &data )
{
Q_UNUSED( column );
Q_UNUSED( role );
Q_UNUSED( data );
return false;
}
Qt::ItemFlags SatellitesConfigAbstractItem::flags() const
{
return m_flags;
}
void SatellitesConfigAbstractItem::setFlags( Qt::ItemFlags flags )
{
m_flags = flags;
}
void SatellitesConfigAbstractItem::clear()
{
}
} // namespace Marble
diff --git a/src/plugins/render/satellites/SatellitesConfigDialog.cpp b/src/plugins/render/satellites/SatellitesConfigDialog.cpp
index 313fcf261..0d59cba9c 100644
--- a/src/plugins/render/satellites/SatellitesConfigDialog.cpp
+++ b/src/plugins/render/satellites/SatellitesConfigDialog.cpp
@@ -1,383 +1,383 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#include "SatellitesConfigDialog.h"
#include <QMessageBox>
#include <QInputDialog>
#include <QFileDialog>
#include <QDateTime>
#include <QUrl>
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "SatellitesConfigNodeItem.h"
#include "SatellitesConfigLeafItem.h"
#include "SatellitesConfigModel.h"
#include "ui_SatellitesConfigDialog.h"
namespace Marble {
SatellitesConfigDialog::SatellitesConfigDialog( QWidget *parent )
: QDialog( parent )
{
initialize();
// allow translation for catalog items
// + categories
m_translations["Comets"] = tr( "Comets" );
m_translations["Moons"] = tr( "Moons" );
m_translations["Other"] = tr( "Other" );
m_translations["Spacecrafts"] = tr( "Spacecrafts" );
m_translations["Spaceprobes"] = tr( "Spaceprobes" );
// + bodies
m_translations["Moon"] = tr( "Moon" );
m_translations["Sun"] = tr( "Sun" );
m_translations["Mercury"] = tr( "Mercury" );
m_translations["Venus"] = tr( "Venus" );
m_translations["Earth"] = tr( "Earth" );
m_translations["Mars"] = tr( "Mars" );
m_translations["Jupiter"] = tr( "Jupiter" );
m_translations["Saturn"] = tr( "Saturn" );
m_translations["Uranus"] = tr( "Uranus" );
m_translations["Neptune"] = tr( "Neptune" );
}
SatellitesConfigDialog::~SatellitesConfigDialog()
{
}
void SatellitesConfigDialog::setUserDataSources( const QStringList &sources )
{
m_userDataSources = sources;
// keep the first item
for( int i = m_configWidget->listDataSources->count(); i > 1; --i ) {
delete m_configWidget->listDataSources->takeItem( i-1 );
}
m_configWidget->listDataSources->addItems( m_userDataSources );
}
QStringList SatellitesConfigDialog::userDataSources() const
{
return m_userDataSources;
}
void SatellitesConfigDialog::setUserDataSourceLoaded( const QString &source,
bool loaded )
{
QList<QListWidgetItem*> list;
list = m_configWidget->listDataSources->findItems( source,
Qt::MatchFixedString );
if( list.count() > 0 ) {
list[0]->setData( IsLoadedRole, QVariant( loaded ) );
}
QString date( QDateTime::currentDateTime().toString() );
m_configWidget->labelLastUpdated->setText( date );
}
void SatellitesConfigDialog::update()
{
expandTreeView();
QDialog::update();
}
SatellitesConfigAbstractItem*
SatellitesConfigDialog::addSatelliteItem( const QString &body,
const QString &category,
const QString &title,
const QString &id,
const QString &url )
{
QString theTitle = translation( title );
SatellitesConfigNodeItem *categoryItem;
categoryItem = getSatellitesCategoryItem( body, category, true );
// exists?
for( int i = 0; i < categoryItem->childrenCount(); ++i ) {
SatellitesConfigAbstractItem *absItem = categoryItem->childAt( i );
if( ( absItem->data( 0, SatellitesConfigAbstractItem::IdListRole ) == id ) ) {
return absItem;
}
}
// add it
SatellitesConfigLeafItem *newItem;
newItem = new SatellitesConfigLeafItem( theTitle, id );
if( !url.isNull() && !url.isEmpty() ) {
newItem->setData( 0, SatellitesConfigAbstractItem::UrlListRole, url );
}
categoryItem->appendChild( newItem );
return newItem;
}
SatellitesConfigAbstractItem*
SatellitesConfigDialog::addTLESatelliteItem( const QString &category,
const QString &title,
const QString &url )
{
// TLE items always have their id set to their url and
// are always related to the earth
return addSatelliteItem( "Earth", category, title, url, url );
}
void SatellitesConfigDialog::setDialogActive( bool active )
{
m_configWidget->tabWidget->clear();
if( active ) {
m_configWidget->tabWidget->addTab( m_configWidget->tabSatellites,
tr( "&Satellites" ) );
m_configWidget->tabWidget->addTab( m_configWidget->tabDataSources,
tr( "&Data Sources" ) );
} else {
m_configWidget->tabWidget->addTab( m_configWidget->tabDisabled,
tr( "&Activate Plugin" ) );
}
QDialogButtonBox *bBox = m_configWidget->buttonBox;
bBox->button( QDialogButtonBox::Ok )->setEnabled( active );
bBox->button( QDialogButtonBox::Reset )->setEnabled( active );
}
Ui::SatellitesConfigDialog* SatellitesConfigDialog::configWidget()
{
return m_configWidget;
}
void SatellitesConfigDialog::initialize()
{
m_configWidget = new Ui::SatellitesConfigDialog();
m_configWidget->setupUi( this );
setupDataSourcesTab();
setDialogActive( false );
connect( m_configWidget->buttonDisabled, SIGNAL(clicked()),
this, SIGNAL(activatePluginClicked()) );
update();
}
void SatellitesConfigDialog::setupDataSourcesTab()
{
connect( m_configWidget->buttonAddDataSource,
SIGNAL(clicked()), SLOT(addDataSource()) );
connect( m_configWidget->buttonOpenDataSource,
SIGNAL(clicked()), SLOT(openDataSource()) );
connect( m_configWidget->buttonRemoveDataSource,
SIGNAL(clicked()), SLOT(removeSelectedDataSource()) );
connect( m_configWidget->buttonReloadDataSources,
SIGNAL(clicked()), SLOT(reloadDataSources()) );
connect( m_configWidget->listDataSources,
SIGNAL(itemSelectionChanged()), SLOT(updateButtonState()) );
}
SatellitesConfigNodeItem* SatellitesConfigDialog::getSatellitesCategoryItem(
const QString &body,
const QString &category,
bool create )
{
QString theCategory = translation( category );
SatellitesConfigNodeItem *catalogItem;
catalogItem = getSatellitesBodyItem( body, create );
- if( catalogItem == NULL ) {
- return NULL;
+ if( catalogItem == nullptr ) {
+ return nullptr;
}
// find category
for( int i = 0; i < catalogItem->childrenCount(); ++i ) {
if( catalogItem->childAt( i )->name() == theCategory ) {
return dynamic_cast<SatellitesConfigNodeItem*>(catalogItem->childAt( i ) );
}
}
// not found, create?
if( create ) {
SatellitesConfigNodeItem *newItem;
newItem = new SatellitesConfigNodeItem( theCategory );
catalogItem->appendChild( newItem );
return newItem;
}
- return NULL; // not found, not created
+ return nullptr; // not found, not created
}
SatellitesConfigNodeItem* SatellitesConfigDialog::getSatellitesBodyItem(
const QString &body,
bool create )
{
QString theBody = translation( body );
SatellitesConfigModel *model = dynamic_cast<SatellitesConfigModel*>( m_configWidget->treeView->model() );
SatellitesConfigNodeItem *rootItem = model->rootItem();
// try to find it
for( int i = 0; i < rootItem->childrenCount(); ++i ) {
if( rootItem->childAt( i )->name() == theBody ) {
return dynamic_cast<SatellitesConfigNodeItem*>(rootItem->childAt( i ) );
}
}
// not found, create?
if( create ) {
SatellitesConfigNodeItem *newItem;
newItem = new SatellitesConfigNodeItem( theBody );
rootItem->appendChild( newItem );
return newItem;
}
- return NULL; // not found, not created
+ return nullptr; // not found, not created
}
void SatellitesConfigDialog::reloadDataSources()
{
emit dataSourcesReloadRequested();
}
void SatellitesConfigDialog::addDataSource()
{
QListWidget *list = m_configWidget->listDataSources;
bool ok;
QString text = QInputDialog::getText( this,
tr("Add Data Source"),
tr("URL or File path:"),
QLineEdit::Normal,
"", &ok);
if( ok && !text.isEmpty() ) {
QUrl url = QUrl::fromUserInput( text );
if( !url.isValid() ) {
mDebug() << "Invalid data source input:" << text;
QMessageBox::critical( this,
tr( "Invalid data source input" ),
tr( "Please enter a valid URL or file path!" ),
QMessageBox::Cancel );
return;
}
// add item
QListWidgetItem *item = new QListWidgetItem( url.toString(), list );
item->setFlags( Qt::ItemIsSelectable |
Qt::ItemIsEnabled );
item->setData( IsLoadedRole, QVariant( false ) );
mDebug() << "Added satellite data source:" << item->text();
m_userDataSources << item->text();
emit userDataSourceAdded( item->text() );
emit userDataSourcesChanged();
}
}
void SatellitesConfigDialog::openDataSource()
{
QListWidget *list = m_configWidget->listDataSources;
const QString filter = QString("%1;;%2;;%3").arg(
tr( "All Supported Files (*.txt *.msc)" ),
tr( "Marble Satellite Catalog (*.msc)" ),
tr( "Two Line Element Set (*.txt)" ),
tr( "All Files (*.*)" ) );
QString filename = QFileDialog::getOpenFileName( this,
tr( "Open Satellite Data File" ), "", filter );
if( !filename.isNull() ) {
QString url = QUrl::fromLocalFile( filename ).toString();
if( m_configWidget->listDataSources->findItems(
url, Qt::MatchFixedString ).size() > 0 ) {
mDebug() << "Satellite data source exists:" << url;
return; // already in list
}
QListWidgetItem *item = new QListWidgetItem( url, list );
item->setFlags( Qt::ItemIsSelectable |
Qt::ItemIsEnabled );
item->setData( IsLoadedRole, QVariant( false ) );
mDebug() << "Added satellite data source:" << url;
m_userDataSources << url;
emit userDataSourceAdded( url );
emit userDataSourcesChanged();
}
}
void SatellitesConfigDialog::removeSelectedDataSource()
{
int row = m_configWidget->listDataSources->currentRow();
if( row >= 0 &&
QMessageBox::question( this,
tr( "Delete selected data source" ),
tr( "Do you really want to delete the selected data source?" ),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No ) == QMessageBox::Yes ) {
QListWidgetItem *item;
item = m_configWidget->listDataSources->takeItem( row );
QString source = item->text();
mDebug() << "Removing satellite data source:" << source;
m_userDataSources.removeAll( source );
emit userDataSourceRemoved( source );
delete item;
emit userDataSourcesChanged();
}
}
void SatellitesConfigDialog::updateButtonState()
{
m_configWidget->buttonRemoveDataSource->setEnabled(
( m_configWidget->listDataSources->currentIndex().row() >= 0 ) );
}
void SatellitesConfigDialog::expandTreeView()
{
QTreeView *treeView = m_configWidget->treeView;
if( !treeView->model() ) {
return;
}
// expand only branches with selected items
treeView->expandAll();
for ( int i = 0; i < treeView->model()->columnCount(); ++i ) {
treeView->resizeColumnToContents( i );
}
}
QString SatellitesConfigDialog::translation( const QString &from ) const
{
if( m_translations.contains( from ) ) {
return m_translations.value( from );
}
return from;
}
} // namespace Marble
#include "moc_SatellitesConfigDialog.cpp"
diff --git a/src/plugins/render/satellites/SatellitesConfigDialog.h b/src/plugins/render/satellites/SatellitesConfigDialog.h
index 5b64235e3..a165efddc 100644
--- a/src/plugins/render/satellites/SatellitesConfigDialog.h
+++ b/src/plugins/render/satellites/SatellitesConfigDialog.h
@@ -1,95 +1,95 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#ifndef MARBLE_SATELLITESCONFIGDIALOG_H
#define MARBLE_SATELLITESCONFIGDIALOG_H
#include <QDialog>
#include <QMap>
namespace Ui {
class SatellitesConfigDialog;
}
namespace Marble {
class SatellitesConfigAbstractItem;
class SatellitesConfigNodeItem;
class SatellitesConfigDialog : public QDialog
{
Q_OBJECT
public:
enum {
IsLoadedRole = Qt::UserRole + 1
};
- explicit SatellitesConfigDialog( QWidget *parent = 0 );
+ explicit SatellitesConfigDialog( QWidget *parent = nullptr );
~SatellitesConfigDialog() override;
void update();
void setUserDataSources( const QStringList &sources );
QStringList userDataSources() const;
void setUserDataSourceLoaded( const QString& source, bool loaded );
SatellitesConfigAbstractItem* addSatelliteItem( const QString &body,
const QString &category,
const QString &title,
const QString &id,
const QString &url = QString() );
SatellitesConfigAbstractItem* addTLESatelliteItem( const QString &category,
const QString &title,
const QString &url );
Ui::SatellitesConfigDialog* configWidget();
Q_SIGNALS:
void dataSourcesReloadRequested();
void userDataSourceAdded( const QString &source );
void userDataSourceRemoved( const QString &source );
void userDataSourcesChanged();
void activatePluginClicked();
public Q_SLOTS:
void setDialogActive( bool active );
protected:
void initialize();
void setupDataSourcesTab();
SatellitesConfigNodeItem* getSatellitesCategoryItem(
const QString &body,
const QString &category,
bool create = false );
SatellitesConfigNodeItem* getSatellitesBodyItem(
const QString &body,
bool create = false );
void expandTreeView();
protected Q_SLOTS:
void reloadDataSources();
void addDataSource();
void openDataSource();
void removeSelectedDataSource();
void updateButtonState();
private:
QString translation( const QString &from ) const;
QStringList m_userDataSources;
Ui::SatellitesConfigDialog *m_configWidget;
QMap<QString, QString> m_translations;
};
} // namespace Marble
#endif // MARBLE_SATELLITESCONFIGDIALOG_H
diff --git a/src/plugins/render/satellites/SatellitesConfigLeafItem.cpp b/src/plugins/render/satellites/SatellitesConfigLeafItem.cpp
index 1fd7680d1..5ecec143e 100644
--- a/src/plugins/render/satellites/SatellitesConfigLeafItem.cpp
+++ b/src/plugins/render/satellites/SatellitesConfigLeafItem.cpp
@@ -1,117 +1,117 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
//
#include "SatellitesConfigLeafItem.h"
#include <QVariant>
namespace Marble {
SatellitesConfigLeafItem::SatellitesConfigLeafItem( const QString &name, const QString &id )
: SatellitesConfigAbstractItem( name ),
m_id( id ),
m_url( QString() ),
m_isChecked( false ),
m_isOrbitDisplayed( false )
{
}
SatellitesConfigLeafItem::~SatellitesConfigLeafItem()
{
}
void SatellitesConfigLeafItem::loadSettings(const QHash<QString, QVariant> &settings)
{
const QStringList idList = settings.value(QStringLiteral("idList")).toStringList();
m_isChecked = idList.contains( m_id );
}
QVariant SatellitesConfigLeafItem::data( int column, int role ) const
{
QVariant base = SatellitesConfigAbstractItem::data( column, role );
if ( base.isValid() ) {
return base;
}
switch ( role ) {
case UrlListRole:
if( !m_url.isNull() && !m_url.isEmpty() ) {
return QVariant( QStringList() << m_url );
}
break;
case IdListRole:
case FullIdListRole:
return QVariant( QStringList() << m_id );
case Qt::CheckStateRole:
switch ( column ) {
case 0:
return QVariant( m_isChecked ? Qt::Checked : Qt::Unchecked );
case 1:
return QVariant( m_isOrbitDisplayed ? Qt::Checked : Qt::Unchecked );
}
}
return QVariant();
}
bool SatellitesConfigLeafItem::setData( int column, int role, const QVariant& data )
{
switch( role ) {
case UrlListRole:
m_url = data.toString();
return true;
case Qt::CheckStateRole:
switch ( column ) {
case 0:
m_isChecked = data.toBool();
return true;
case 1:
m_isOrbitDisplayed = data.toBool();
return true;
}
}
return false;
}
bool SatellitesConfigLeafItem::isLeaf() const
{
return true;
}
SatellitesConfigAbstractItem *SatellitesConfigLeafItem::childAt( int row ) const
{
Q_UNUSED( row )
- return 0;
+ return nullptr;
}
int SatellitesConfigLeafItem::indexOf( const SatellitesConfigAbstractItem *child ) const
{
Q_UNUSED( child )
return -1;
}
int SatellitesConfigLeafItem::childrenCount() const
{
return 0;
}
QString SatellitesConfigLeafItem::id() const
{
return m_id;
}
QString SatellitesConfigLeafItem::url() const
{
return m_url;
}
} // namespace Marble
diff --git a/src/plugins/render/satellites/SatellitesConfigModel.cpp b/src/plugins/render/satellites/SatellitesConfigModel.cpp
index a182738a0..51c20ce4f 100644
--- a/src/plugins/render/satellites/SatellitesConfigModel.cpp
+++ b/src/plugins/render/satellites/SatellitesConfigModel.cpp
@@ -1,195 +1,195 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
//
#include "SatellitesConfigModel.h"
#include "SatellitesConfigNodeItem.h"
#include "SatellitesConfigLeafItem.h"
#include "MarbleDebug.h"
namespace Marble {
SatellitesConfigModel::SatellitesConfigModel( QObject *parent )
: QAbstractItemModel( parent ),
m_rootItem(new SatellitesConfigNodeItem(QString()))
{
}
SatellitesConfigModel::~SatellitesConfigModel()
{
delete m_rootItem;
}
QStringList SatellitesConfigModel::idList() const
{
return m_rootItem->data( 0, SatellitesConfigAbstractItem::IdListRole )
.toStringList();
}
QStringList SatellitesConfigModel::fullIdList() const
{
return m_rootItem->data( 0, SatellitesConfigAbstractItem::FullIdListRole )
.toStringList();
}
QStringList SatellitesConfigModel::urlList() const
{
return m_rootItem->data( 0, SatellitesConfigAbstractItem::UrlListRole )
.toStringList();
}
void SatellitesConfigModel::loadSettings(const QHash<QString, QVariant> &settings)
{
m_rootItem->loadSettings( settings );
}
void SatellitesConfigModel::appendChild( SatellitesConfigAbstractItem *child )
{
m_rootItem->appendChild( child );
}
void SatellitesConfigModel::clear()
{
m_rootItem->clear();
}
QVariant SatellitesConfigModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() ) {
return QVariant();
}
SatellitesConfigAbstractItem *item =
static_cast<SatellitesConfigAbstractItem *>( index.internalPointer() );
return item->data( index.column(), role );
}
bool SatellitesConfigModel::setData( const QModelIndex &index,
const QVariant &value,
int role )
{
SatellitesConfigAbstractItem *item =
static_cast<SatellitesConfigAbstractItem *>( index.internalPointer() );
bool success = item->setData( index.column(), role, value );
if ( success ) {
QModelIndex parentCellIndex = this->index( index.parent().row(),
index.column(),
index.parent().parent() );
emit dataChanged( parentCellIndex, parentCellIndex );
}
return success;
}
int SatellitesConfigModel::columnCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent )
//TODO: enable second column
return 1;
}
int SatellitesConfigModel::rowCount( const QModelIndex &parent ) const
{
if ( parent.column() > 0 ) {
return 0;
}
- SatellitesConfigAbstractItem *parentItem = 0;
+ SatellitesConfigAbstractItem *parentItem = nullptr;
if ( !parent.isValid() ) {
parentItem = m_rootItem;
} else {
parentItem = static_cast<SatellitesConfigAbstractItem *>(
parent.internalPointer() );
}
return parentItem->childrenCount();
}
QModelIndex SatellitesConfigModel::parent( const QModelIndex &child ) const
{
if ( !child.isValid() ) {
return QModelIndex();
}
SatellitesConfigAbstractItem *childItem =
static_cast<SatellitesConfigAbstractItem *>( child.internalPointer() );
SatellitesConfigAbstractItem *parentItem = childItem->parent();
if ( parentItem == m_rootItem ) {
return QModelIndex();
}
return createIndex( parentItem->row(), 0, parentItem );
}
QModelIndex SatellitesConfigModel::index( int row, int column,
const QModelIndex &parent ) const
{
if ( !hasIndex( row, column, parent ) ) {
return QModelIndex();
}
- SatellitesConfigAbstractItem *parentItem = 0;
+ SatellitesConfigAbstractItem *parentItem = nullptr;
if ( !parent.isValid() ) {
parentItem = m_rootItem;
} else {
parentItem = static_cast<SatellitesConfigAbstractItem *>(
parent.internalPointer() );
}
SatellitesConfigAbstractItem *childItem = parentItem->childAt( row );
if ( !childItem ) {
return QModelIndex();
}
return createIndex( row, column, childItem );
}
QVariant SatellitesConfigModel::headerData( int section,
Qt::Orientation orientation,
int role ) const
{
if ( orientation != Qt::Horizontal || role != Qt::DisplayRole ) {
return QVariant();
}
switch (section) {
case 0: {
return QVariant( tr( "Catalogs" ) );
}
default: {
return QVariant();
}
}
}
Qt::ItemFlags SatellitesConfigModel::flags( const QModelIndex &index ) const
{
if ( !index.isValid() ) {
- return 0;
+ return nullptr;
}
SatellitesConfigAbstractItem *item =
static_cast<SatellitesConfigAbstractItem *>( index.internalPointer() );
return item->flags();
}
SatellitesConfigNodeItem* SatellitesConfigModel::rootItem() const
{
return m_rootItem;
}
} // namespace Marble
#include "moc_SatellitesConfigModel.cpp"
diff --git a/src/plugins/render/satellites/SatellitesConfigModel.h b/src/plugins/render/satellites/SatellitesConfigModel.h
index 21da28bdf..d08d85852 100644
--- a/src/plugins/render/satellites/SatellitesConfigModel.h
+++ b/src/plugins/render/satellites/SatellitesConfigModel.h
@@ -1,59 +1,59 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
//
#ifndef MARBLE_SATELLITESCONFIGMODEL_H
#define MARBLE_SATELLITESCONFIGMODEL_H
#include <QModelIndex>
#include "SatellitesConfigNodeItem.h"
namespace Marble {
class SatellitesConfigModel : public QAbstractItemModel
{
Q_OBJECT
public:
- explicit SatellitesConfigModel( QObject *parent = 0 );
+ explicit SatellitesConfigModel( QObject *parent = nullptr );
~SatellitesConfigModel() override;
void loadSettings(const QHash<QString, QVariant> &settings);
void appendChild( SatellitesConfigAbstractItem *child );
void clear();
QStringList idList() const;
QStringList fullIdList() const;
QStringList urlList() const;
QVariant data( const QModelIndex &index,
int role = Qt::DisplayRole ) const override;
bool setData( const QModelIndex &index,
const QVariant &value,
int role = Qt::EditRole ) override;
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
QModelIndex parent( const QModelIndex &child ) const override;
QModelIndex index( int row,
int column,
const QModelIndex &parent = QModelIndex() ) const override;
QVariant headerData( int section, Qt::Orientation orientation,
int role = Qt::DisplayRole ) const override;
Qt::ItemFlags flags( const QModelIndex &index ) const override;
SatellitesConfigNodeItem* rootItem() const;
protected:
SatellitesConfigNodeItem *m_rootItem;
};
} // namespace Marble
#endif // MARBLE_SATELLITESCONFIGMODEL_H
diff --git a/src/plugins/render/satellites/SatellitesConfigNodeItem.cpp b/src/plugins/render/satellites/SatellitesConfigNodeItem.cpp
index 6ac7a1ae8..391b595bd 100644
--- a/src/plugins/render/satellites/SatellitesConfigNodeItem.cpp
+++ b/src/plugins/render/satellites/SatellitesConfigNodeItem.cpp
@@ -1,149 +1,149 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#include "SatellitesConfigNodeItem.h"
#include <QStringList>
#include <QVariant>
#include "MarbleDebug.h"
namespace Marble {
SatellitesConfigNodeItem::SatellitesConfigNodeItem( const QString &name )
: SatellitesConfigAbstractItem( name )
{
}
SatellitesConfigNodeItem::~SatellitesConfigNodeItem()
{
}
void SatellitesConfigNodeItem::loadSettings(const QHash<QString, QVariant> &settings)
{
for( SatellitesConfigAbstractItem *item: m_children ) {
item->loadSettings( settings );
}
}
QVariant SatellitesConfigNodeItem::data( int column, int role ) const
{
QVariant base = SatellitesConfigAbstractItem::data( column, role );
if ( base.isValid() ) {
return base;
}
switch ( role ) {
case IdListRole:
case UrlListRole: {
QStringList list;
for( SatellitesConfigAbstractItem *item: m_children ) {
if ( item->data( column, Qt::CheckStateRole ).toInt() != Qt::Unchecked ) {
list.append( item->data( column, role).toStringList() );
}
}
return list;
}
case FullIdListRole: {
QStringList fullIdList;
for( SatellitesConfigAbstractItem *item: m_children ) {
fullIdList.append( item->data( column, role ).toStringList() );
}
return fullIdList;
}
case Qt::CheckStateRole: {
bool oneChecked = false;
bool oneUnchecked = false;
for( SatellitesConfigAbstractItem *item: m_children ) {
switch ( item->data( column, Qt::CheckStateRole ).toInt() ) {
case Qt::Checked:
oneChecked = true;
if ( oneUnchecked ) {
return Qt::PartiallyChecked;
}
break;
case Qt::PartiallyChecked:
return Qt::PartiallyChecked;
case Qt::Unchecked:
oneUnchecked = true;
if ( oneChecked ) {
return Qt::PartiallyChecked;
}
}
}
return QVariant( oneChecked ? Qt::Checked : Qt::Unchecked );
}
}
return QVariant();
}
bool SatellitesConfigNodeItem::setData( int column, int role, const QVariant &data )
{
if ( role == Qt::CheckStateRole ) {
switch ( column ) {
case 0:
// fall through
case 1:
for( SatellitesConfigAbstractItem *item: m_children ) {
item->setData( column, role, data );
}
return true;
}
}
return false;
}
bool SatellitesConfigNodeItem::isLeaf() const
{
return false;
}
SatellitesConfigAbstractItem *SatellitesConfigNodeItem::childAt( int row ) const
{
if ( m_children.size() <= row ) {
- return 0;
+ return nullptr;
}
return m_children.at( row );
}
int SatellitesConfigNodeItem::indexOf( const SatellitesConfigAbstractItem *child ) const
{
//TODO: find out if we can avoid the const_cast
return m_children.indexOf( const_cast<SatellitesConfigAbstractItem *>( child ) );
}
int SatellitesConfigNodeItem::childrenCount() const
{
return m_children.size();
}
void SatellitesConfigNodeItem::appendChild( SatellitesConfigAbstractItem *item )
{
item->setParent( this );
m_children.append( item );
}
void SatellitesConfigNodeItem::clear()
{
for( int i = childrenCount(); i > 0; --i ) {
SatellitesConfigAbstractItem *item = m_children.at( i - 1 );
item->clear();
m_children.remove( i - 1 );
delete item;
}
}
} // namespace Marble
diff --git a/src/plugins/render/satellites/SatellitesModel.cpp b/src/plugins/render/satellites/SatellitesModel.cpp
index d5c6bdf72..68f4b1e59 100644
--- a/src/plugins/render/satellites/SatellitesModel.cpp
+++ b/src/plugins/render/satellites/SatellitesModel.cpp
@@ -1,272 +1,272 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
//
#include "SatellitesModel.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "SatellitesMSCItem.h"
#include "SatellitesTLEItem.h"
#include "MarbleClock.h"
#include "GeoDataPlacemark.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataLabelStyle.h"
#include "GeoDataLineStyle.h"
#include <planetarySats.h>
#include <sgp4io.h>
#include <clocale>
namespace Marble {
SatellitesModel::SatellitesModel( GeoDataTreeModel *treeModel,
const MarbleClock *clock )
: TrackerPluginModel( treeModel ),
m_clock( clock ),
m_currentColorIndex( 0 )
{
setupColors();
connect(m_clock, SIGNAL(timeChanged()), this, SLOT(update()));
}
void SatellitesModel::setupColors()
{
m_colorList.push_back( Oxygen::brickRed4 );
m_colorList.push_back( Oxygen::raspberryPink4 );
m_colorList.push_back( Oxygen::burgundyPurple4 );
m_colorList.push_back( Oxygen::grapeViolet4 );
m_colorList.push_back( Oxygen::skyBlue4 );
m_colorList.push_back( Oxygen::seaBlue4 );
m_colorList.push_back( Oxygen::emeraldGreen4 );
m_colorList.push_back( Oxygen::forestGreen4 );
m_colorList.push_back( Oxygen::sunYellow4 );
m_colorList.push_back( Oxygen::hotOrange4 );
m_colorList.push_back( Oxygen::aluminumGray4 );
m_colorList.push_back( Oxygen::woodBrown4 );
}
QColor SatellitesModel::nextColor()
{
if (m_colorList.isEmpty()) {
return Oxygen::brickRed4;
}
if (m_currentColorIndex < m_colorList.size()) {
m_currentColorIndex++;
return m_colorList[m_currentColorIndex-1];
} else {
m_currentColorIndex = 1;
return m_colorList[0];
}
return Oxygen::brickRed4;
}
void SatellitesModel::loadSettings( const QHash<QString, QVariant> &settings )
{
QStringList idList = settings[QStringLiteral("idList")].toStringList();
m_enabledIds = idList;
updateVisibility();
}
void SatellitesModel::setPlanet( const QString &planetId )
{
if( m_lcPlanet != planetId ) {
mDebug() << "Planet changed from" << m_lcPlanet << "to" << planetId;
m_lcPlanet = planetId;
updateVisibility();
}
}
void SatellitesModel::updateVisibility()
{
beginUpdateItems();
for( TrackerPluginItem *obj: items() ) {
SatellitesMSCItem *oItem = dynamic_cast<SatellitesMSCItem*>(obj);
- if( oItem != NULL ) {
+ if( oItem != nullptr ) {
bool enabled = ( ( oItem->relatedBody().toLower() == m_lcPlanet ) &&
( m_enabledIds.contains( oItem->id() ) ) );
oItem->setEnabled( enabled );
if( enabled ) {
oItem->update();
}
}
SatellitesTLEItem *eItem = dynamic_cast<SatellitesTLEItem*>(obj);
- if( eItem != NULL ) {
+ if( eItem != nullptr ) {
// TLE satellites are always earth satellites
bool enabled = (m_lcPlanet == QLatin1String("earth"));
eItem->setEnabled( enabled );
if( enabled ) {
eItem->update();
}
}
}
endUpdateItems();
}
void SatellitesModel::parseFile( const QString &id,
const QByteArray &data )
{
// catalog files are comma serparated while tle files
// are not allowed to contain commas, so we use this
// to distinguish between those two
if( data.contains( ',' ) ) {
parseCatalog( id, data );
} else {
parseTLE( id, data );
}
emit fileParsed( id );
}
void SatellitesModel::parseCatalog( const QString &id,
const QByteArray &data )
{
// For details see:
// http://techbase.kde.org/Projects/Marble/SatelliteCatalogFormat
mDebug() << "Reading satellite catalog from:" << id;
QTextStream ts(data);
int index = 1;
beginUpdateItems();
QString line = ts.readLine();
for( ; !line.isNull(); line = ts.readLine() ) {
if (line.trimmed().startsWith(QLatin1Char('#'))) {
continue;
}
QStringList elms = line.split(", ");
// check for '<' instead of '==' in order to allow fields to be added
// to catalogs later without breaking the code
if( elms.size() < 14 ) {
mDebug() << "Skipping line:" << elms << "(" << line << ")";
continue;
}
QString name( elms[0] );
QString category( elms[1] );
QString body( elms[2] );
QByteArray body8Bit = body.toLocal8Bit();
char *cbody = const_cast<char*>( body8Bit.constData() );
mDebug() << "Loading" << category << name;
PlanetarySats *planSat = new PlanetarySats();
planSat->setPlanet( cbody );
planSat->setStateVector(
elms[7].toFloat() - 2400000.5,
elms[8].toFloat(), elms[9].toFloat(), elms[10].toFloat(),
elms[11].toFloat(), elms[12].toFloat(), elms[13].toFloat() );
planSat->stateToKepler();
QDateTime missionStart, missionEnd;
if( elms[3].toUInt() > 0 ) {
missionStart = QDateTime::fromTime_t( elms[3].toUInt() );
}
if( elms[4].toUInt() > 0 ) {
missionEnd = QDateTime::fromTime_t( elms[4].toUInt() );
}
SatellitesMSCItem *item = new SatellitesMSCItem( name, category, body, id,
missionStart, missionEnd,
index++, planSat, m_clock );
GeoDataStyle::Ptr style(new GeoDataStyle( *item->placemark()->style() ));
style->lineStyle().setPenStyle( Qt::SolidLine );
style->lineStyle().setColor( nextColor() );
style->labelStyle().setGlow( true );
// use special icon for moons
if (category == QLatin1String("Moons")) {
style->iconStyle().setIconPath(QStringLiteral(":/icons/moon.png"));
} else {
style->iconStyle().setIconPath(MarbleDirs::path(QStringLiteral("bitmaps/satellite.png")));
}
item->placemark()->setStyle( style );
item->placemark()->setVisible( ( body.toLower() == m_lcPlanet ) );
addItem( item );
}
endUpdateItems();
}
void SatellitesModel::parseTLE( const QString &id,
const QByteArray &data )
{
mDebug() << "Reading satellite TLE data from:" << id;
QList<QByteArray> tleLines = data.split( '\n' );
// File format: One line of description, two lines of TLE, last line is empty
if ( tleLines.size() % 3 != 1 ) {
mDebug() << "Malformated satellite data file";
}
beginUpdateItems();
//FIXME: terrible hack because twoline2rv uses sscanf
setlocale( LC_NUMERIC, "C" );
double startmfe, stopmfe, deltamin;
elsetrec satrec;
int i = 0;
while ( i < tleLines.size() - 1 ) {
QString satelliteName = QString( tleLines.at( i++ ) ).trimmed();
char line1[130];
char line2[130];
if( tleLines.at( i ).size() >= 79 ||
tleLines.at( i+1 ).size() >= 79 ) {
mDebug() << "Invalid TLE data!";
return;
}
qstrcpy( line1, tleLines.at( i++ ).constData() );
qstrcpy( line2, tleLines.at( i++ ).constData() );
twoline2rv( line1, line2, 'c', 'd', 'i', wgs84,
startmfe, stopmfe, deltamin, satrec );
if ( satrec.error != 0 ) {
mDebug() << "Error: " << satrec.error;
return;
}
SatellitesTLEItem *item = new SatellitesTLEItem( satelliteName, satrec, m_clock );
GeoDataStyle::Ptr style(new GeoDataStyle( *item->placemark()->style() ));
style->lineStyle().setPenStyle( Qt::SolidLine );
style->lineStyle().setColor( nextColor() );
style->labelStyle().setGlow( true );
style->iconStyle().setIconPath(MarbleDirs::path(QStringLiteral("bitmaps/satellite.png")));
item->placemark()->setStyle( style );
addItem( item );
}
//Reset to environment
setlocale( LC_NUMERIC, "" );
endUpdateItems();
}
} // namespace Marble
#include "moc_SatellitesModel.cpp"
diff --git a/src/plugins/render/satellites/SatellitesPlugin.cpp b/src/plugins/render/satellites/SatellitesPlugin.cpp
index 0a43d2440..0bacb247c 100644
--- a/src/plugins/render/satellites/SatellitesPlugin.cpp
+++ b/src/plugins/render/satellites/SatellitesPlugin.cpp
@@ -1,506 +1,506 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#include "SatellitesPlugin.h"
#include "MarbleDebug.h"
#include "MarbleWidget.h"
#include "MarbleWidgetPopupMenu.h"
#include "MarbleModel.h"
#include "GeoDataPlacemark.h"
#include "SatellitesMSCItem.h"
#include "SatellitesTLEItem.h"
#include "SatellitesConfigLeafItem.h"
#include "SatellitesConfigNodeItem.h"
#include "SatellitesConfigModel.h"
#include "ViewportParams.h"
#include "ui_SatellitesConfigDialog.h"
#include <QAction>
#include <QUrl>
#include <QMouseEvent>
namespace Marble
{
SatellitesPlugin::SatellitesPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
- m_satModel( 0 ),
+ m_satModel( nullptr ),
m_isInitialized( false ),
m_configDialog(nullptr)
{
connect( this, SIGNAL(settingsChanged(QString)), SLOT(updateSettings()) );
connect( this, SIGNAL(enabledChanged(bool)), SLOT(enableModel(bool)) );
connect( this, SIGNAL(visibilityChanged(bool,QString)), SLOT(visibleModel(bool)) );
setVisible( false );
setSettings(QHash<QString, QVariant>());
m_showOrbitAction = new QAction( tr( "Display orbit" ), this );
m_showOrbitAction->setCheckable( true );
m_showOrbitAction->setData( 0 );
m_trackPlacemarkAction = new QAction( tr( "Keep centered" ), this );
m_trackPlacemarkAction->setData( 0 );
connect( m_showOrbitAction, SIGNAL(triggered(bool)), SLOT(showOrbit(bool)) );
connect( m_trackPlacemarkAction, SIGNAL(triggered(bool)), SLOT(trackPlacemark()) );
}
SatellitesPlugin::~SatellitesPlugin()
{
delete m_satModel;
delete m_configDialog;
delete m_showOrbitAction;
delete m_trackPlacemarkAction;
}
QStringList SatellitesPlugin::backendTypes() const
{
return QStringList(QStringLiteral("satellites"));
}
QString SatellitesPlugin::renderPolicy() const
{
return QStringLiteral("ALWAYS");
}
QStringList SatellitesPlugin::renderPosition() const
{
return QStringList(QStringLiteral("ORBIT"));
}
QString SatellitesPlugin::name() const
{
return tr( "Satellites" );
}
QString SatellitesPlugin::nameId() const
{
return QStringLiteral("satellites");
}
QString SatellitesPlugin::guiString() const
{
return tr( "&Satellites" );
}
QString SatellitesPlugin::version() const
{
return QStringLiteral("2.0");
}
QString SatellitesPlugin::description() const
{
return tr( "This plugin displays satellites and their orbits." );
}
QString SatellitesPlugin::copyrightYears() const
{
return QStringLiteral("2012");
}
QVector<PluginAuthor> SatellitesPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Guillaume Martres"), QStringLiteral("smarter@ubuntu.com"))
<< PluginAuthor(QStringLiteral("Rene Kuettner"), QStringLiteral("rene@bitkanal.net"))
<< PluginAuthor(QStringLiteral("Gerhard Holtkamp"), QString());
}
QString SatellitesPlugin::aboutDataText() const
{
return tr(
"Earth-Satellites orbital elements from <ul><li>"
"<a href=\"http://www.celestrak.com\">http://www.celestrak.com</a>"
"</li></ul>"
"Planetary-Satellites orbital elements from <ul><li>"
"<a href=\"http://tasc.esa.int/\">ESA TASC service</a></li><li>"
"<a href=\"http://ssd.jpl.nasa.gov/?horizons\">"
"JPL Horizons</a></li></ul>" );
}
QIcon SatellitesPlugin::icon() const
{
return QIcon(QStringLiteral(":/data/bitmaps/satellite.png"));
}
RenderPlugin::RenderType SatellitesPlugin::renderType() const
{
return OnlineRenderType;
}
void SatellitesPlugin::initialize()
{
// FIXME: remove the const_cast, it may be best to create a new type of
// plugins where marbleModel() is not const, since traditional
// RenderPlugins do not require that
m_satModel = new SatellitesModel(
const_cast<MarbleModel *>( marbleModel() )->treeModel(),
marbleModel()->clock() );
m_configModel = new SatellitesConfigModel( this );
delete m_configDialog;
m_configDialog = new SatellitesConfigDialog();
connect( m_configDialog, SIGNAL(activatePluginClicked()), this, SLOT(activate()) );
connect( this, SIGNAL(visibilityChanged(bool,QString)),
m_configDialog, SLOT(setDialogActive(bool)) );
m_configDialog->configWidget()->treeView->setModel( m_configModel );
connect( m_satModel, SIGNAL(fileParsed(QString)),
SLOT(dataSourceParsed(QString)) );
connect( m_satModel, SIGNAL(fileParsed(QString)),
SLOT(updateDataSourceConfig(QString)) );
connect( m_configDialog, SIGNAL(dataSourcesReloadRequested()),
SLOT(updateSettings()) );
connect( m_configDialog, SIGNAL(accepted()), SLOT(writeSettings()) );
connect( m_configDialog, SIGNAL(rejected()), SLOT(readSettings()) );
connect( m_configDialog->configWidget()->buttonBox->button(
QDialogButtonBox::Reset ),
SIGNAL(clicked()), SLOT(restoreDefaultSettings()) );
connect( m_configDialog, SIGNAL(userDataSourcesChanged()),
SLOT(writeSettings()) );
connect( m_configDialog, SIGNAL(userDataSourceAdded(QString)),
SLOT(userDataSourceAdded(QString)) );
m_isInitialized = true;
readSettings();
updateSettings();
enableModel( enabled() );
}
bool SatellitesPlugin::isInitialized() const
{
return m_isInitialized;
}
bool SatellitesPlugin::render( GeoPainter *painter, ViewportParams *viewport,
const QString &renderPos, GeoSceneLayer *layer )
{
Q_UNUSED( painter );
Q_UNUSED( viewport );
Q_UNUSED( renderPos );
Q_UNUSED( layer );
enableModel( enabled() );
return true;
}
bool SatellitesPlugin::eventFilter( QObject *object, QEvent *event )
{
// only if active plugin
if( !enabled() || !visible() ) {
return false;
}
if( event->type() != QEvent::MouseButtonPress )
{
return false;
}
MarbleWidget *widget = qobject_cast<MarbleWidget*> ( object );
Q_ASSERT ( widget );
QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
Q_ASSERT( mouseEvent );
if( mouseEvent->button() == Qt::LeftButton ) {
m_trackerList.clear();
QVector<const GeoDataFeature*> vector = widget->whichFeatureAt( mouseEvent->pos() );
for (const GeoDataFeature *feature: vector) {
const GeoDataPlacemark* placemark = dynamic_cast<const GeoDataPlacemark*>(feature);
if ( placemark ) {
for (TrackerPluginItem *obj: m_satModel->items() ) {
if( obj->placemark() == placemark ) {
m_showOrbitAction->data() = m_trackerList.size();
m_showOrbitAction->setChecked( obj->isTrackVisible() );
widget->popupMenu()->addAction( Qt::LeftButton, m_showOrbitAction );
m_trackPlacemarkAction->data() = m_trackerList.size();
widget->popupMenu()->addAction( Qt::LeftButton, m_trackPlacemarkAction );
m_trackerList.append( obj );
}
}
}
}
}
return false;
}
void SatellitesPlugin::showOrbit(bool show)
{
QAction *action = qobject_cast<QAction *>( sender() );
Q_ASSERT( action );
int actionIndex = action->data().toInt();
TrackerPluginItem *item = m_trackerList.at( actionIndex );
item->setTrackVisible( show );
m_satModel->updateVisibility();
}
void SatellitesPlugin::trackPlacemark()
{
QAction *action = qobject_cast<QAction *>( sender() );
Q_ASSERT( action );
int actionIndex = action->data().toInt();
TrackerPluginItem *item = m_trackerList.at( actionIndex );
const_cast<MarbleModel *>( marbleModel() )->setTrackedPlacemark( item->placemark() );
}
QHash<QString, QVariant> SatellitesPlugin::settings() const
{
QHash<QString, QVariant> result = RenderPlugin::settings();
typedef QHash<QString, QVariant>::ConstIterator Iterator;
Iterator end = m_settings.constEnd();
for ( Iterator iter = m_settings.constBegin(); iter != end; ++iter ) {
result.insert( iter.key(), iter.value() );
}
return result;
}
void SatellitesPlugin::setSettings( const QHash<QString, QVariant> &settings )
{
RenderPlugin::setSettings( settings );
// reset
m_newDataSources.clear();
// TODO: cancel also all on-going downloads
// add default data sources
if (!settings.contains(QStringLiteral("dataSources"))) {
QStringList dsList;
dsList << QStringLiteral("http://www.celestrak.com/NORAD/elements/visual.txt");
m_settings.insert(QStringLiteral("dataSources"), dsList);
m_settings.insert(QStringLiteral("idList"), dsList);
}
else {
// HACK: KConfig can't guess the type of the settings, when we use
// KConfigGroup::readEntry() in marble_part it returns a QString which
// is then wrapped into a QVariant when added to the settings hash.
// QVariant can handle the conversion for some types, like toDateTime()
// but when calling toStringList() on a QVariant::String, it will
// return a one element list
if (settings.value(QStringLiteral("dataSources")).type() == QVariant::String) {
m_settings.insert(QStringLiteral("dataSources"),
settings.value(QStringLiteral("dataSources")).toString().split(QLatin1Char(',')));
}
if (settings.value(QStringLiteral("idList")).type() == QVariant::String) {
m_settings.insert(QStringLiteral("idList"),
settings.value(QStringLiteral("idList")).toString().split(QLatin1Char(',')));
}
}
// add default user data source
if (!settings.contains(QStringLiteral("userDataSources"))) {
QStringList udsList;
udsList << QStringLiteral("http://files.kde.org/marble/satellites/PlanetarySatellites.msc");
m_settings.insert(QStringLiteral("userDataSources"), udsList);
userDataSourceAdded( udsList[0] );
}
else if (settings.value(QStringLiteral("userDataSources")).type() == QVariant::String) {
// same HACK as above
m_settings.insert(QStringLiteral("userDataSources"),
settings.value(QStringLiteral("userDataSources")).toString().split(QLatin1Char(',')));
}
emit settingsChanged( nameId() );
}
void SatellitesPlugin::readSettings()
{
m_configDialog->setUserDataSources(
m_settings.value(QStringLiteral("userDataSources")).toStringList());
m_configModel->loadSettings( m_settings );
m_satModel->loadSettings( m_settings );
}
void SatellitesPlugin::writeSettings()
{
m_settings.insert(QStringLiteral("userDataSources"), m_configDialog->userDataSources());
m_settings.insert(QStringLiteral("dataSources"), m_configModel->urlList());
m_settings.insert(QStringLiteral("idList"), m_configModel->idList());
emit settingsChanged( nameId() );
}
void SatellitesPlugin::updateSettings()
{
if (!isInitialized()) {
return;
}
// TODO: cancel also all on-going downloads
m_satModel->clear();
m_configModel->clear();
addBuiltInDataSources();
// (re)load data sources
QStringList dsList = m_settings[QStringLiteral("dataSources")].toStringList();
dsList << m_settings[QStringLiteral("userDataSources")].toStringList();
dsList.removeDuplicates();
for( const QString &ds: dsList ) {
mDebug() << "Loading satellite data from:" << ds;
m_satModel->downloadFile( QUrl( ds ), ds );
}
}
void SatellitesPlugin::dataSourceParsed( const QString &source )
{
m_configDialog->setUserDataSourceLoaded( source, true );
}
void SatellitesPlugin::userDataSourceAdded( const QString &source )
{
// items contained in catalog data sources are not known before
// the catalog has been parsed. so we store new data sources in
// order to activate them later (new datasources are enabled by
// default)
if( !m_newDataSources.contains( source ) ) {
m_newDataSources.append( source );
}
}
SatellitesConfigDialog *SatellitesPlugin::configDialog()
{
return m_configDialog;
}
void SatellitesPlugin::activate()
{
action()->trigger();
}
void SatellitesPlugin::enableModel( bool enabled )
{
if ( !m_isInitialized ) {
return;
}
m_satModel->setPlanet( marbleModel()->planetId() );
m_satModel->enable( enabled && visible() );
}
void SatellitesPlugin::visibleModel( bool visible )
{
if ( !m_isInitialized ) {
return;
}
m_satModel->setPlanet( marbleModel()->planetId() );
m_satModel->enable( enabled() && visible );
}
void SatellitesPlugin::updateDataSourceConfig( const QString &source )
{
mDebug() << "Updating orbiter configuration";
for( TrackerPluginItem *obj: m_satModel->items() ) {
// catalog items
SatellitesMSCItem *item = dynamic_cast<SatellitesMSCItem*>( obj );
- if( ( item != NULL ) && ( item->catalog() == source ) ) {
+ if( ( item != nullptr ) && ( item->catalog() == source ) ) {
m_configDialog->addSatelliteItem(
item->relatedBody(),
item->category(),
item->name(),
item->id() );
}
}
// activate new datasources by default
if( m_newDataSources.contains( source ) ) {
m_newDataSources.removeAll( source );
activateDataSource( source );
}
readSettings();
m_configDialog->update();
}
void SatellitesPlugin::activateDataSource( const QString &source )
{
// activate the given data source (select it)
mDebug() << "Activating Data Source:" << source;
QStringList list = m_configModel->fullIdList().filter( source );
QStringList idList = m_settings[QStringLiteral("idList")].toStringList();
idList << list;
m_settings.insert(QStringLiteral("idList"), idList);
}
void SatellitesPlugin::addBuiltInDataSources()
{
QString currentCategory;
currentCategory = tr("Special-Interest Satellites" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Last 30 Days' Launches", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/tle-new.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Space Stations", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/stations.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "100 (or so) Brightest", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/visual.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "FENGYUN 1C Debris", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/1999-025.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "IRIDIUM 33 Debris", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/iridium-33-debris.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "COSMOS 2251 Debris", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/cosmos-2251-debris.txt" );
currentCategory = tr( "Weather & Earth Resources Satellites" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Weather", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/weather.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "NOAA", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/noaa.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "GOES", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/goes.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Earth Resources", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/resource.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Search & Rescue (SARSAT)", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/sarsat.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Disaster Monitoring", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/dmc.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Tracking and Data Relay Satellite System (TDRSS)", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/tdrss.txt" );
currentCategory = tr( "Communications Satellites" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Geostationary", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/geo.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Intelsat", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/intelsat.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Gorizont", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/gorizont.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Raduga", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/raduga.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Molniya", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/molniya.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Iridium", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/iridium.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Orbcomm", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/orbcomm.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Globalstar", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/globalstar.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Amateur radio", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/amateur.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Experimental", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/x-comm.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Other", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/other-comm.txt" );
currentCategory = tr( "Navigation Satellites" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "GPS Operational", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/gps-ops.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Glonass Operational", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/glo-ops.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Galileo", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/galileo.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Satellite-Based Augmentation System (WAAS/EGNOS/MSAS)", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/sbas.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Navy Navigation Satellite System (NNSS)", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/nnss.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Russian LEO Navigation", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/musson.txt" );
currentCategory = tr( "Scientific Satellites" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Space & Earth Science", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/science.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Geodetic", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/geodetic.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Engineering", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/engineering.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Education", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/education.txt" );
currentCategory = tr( "Miscellaneous Satellites" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Miscellaneous Military", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/military.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Radar Calibration", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/radar.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "CubeSats", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/cubesat.txt" );
m_configDialog->addTLESatelliteItem( currentCategory, tr( "Other", "Name of a satellite group" ), "http://www.celestrak.com/NORAD/elements/other.txt" );
readSettings();
m_configDialog->update();
}
} // namespace Marble
#include "moc_SatellitesPlugin.cpp"
diff --git a/src/plugins/render/satellites/SatellitesPlugin.h b/src/plugins/render/satellites/SatellitesPlugin.h
index 160c1aca8..47568ff30 100644
--- a/src/plugins/render/satellites/SatellitesPlugin.h
+++ b/src/plugins/render/satellites/SatellitesPlugin.h
@@ -1,107 +1,107 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
// Copyright 2012 Rene Kuettner <rene@bitkanal.net>
//
#ifndef MARBLE_SATELLITESPLUGIN_H
#define MARBLE_SATELLITESPLUGIN_H
#include "RenderPlugin.h"
#include "SatellitesConfigDialog.h"
#include "DialogConfigurationInterface.h"
#include "SatellitesModel.h"
#include <QHash>
namespace Marble
{
class SatellitesConfigModel;
/**
* @brief This plugin displays satellites and their orbits.
*
*/
class SatellitesPlugin : public RenderPlugin,
public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.SatellitesPlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN( SatellitesPlugin )
public:
- explicit SatellitesPlugin( const MarbleModel *marbleModel = 0 );
+ explicit SatellitesPlugin( const MarbleModel *marbleModel = nullptr );
~SatellitesPlugin() override;
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
QString name() const override;
QString nameId() const override;
QString guiString() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString aboutDataText() const override;
QIcon icon() const override;
RenderType renderType() const override;
void initialize() override;
bool isInitialized() const override;
bool render( GeoPainter *painter,
ViewportParams *viewport,
const QString &renderPos,
GeoSceneLayer *layer ) override;
bool eventFilter( QObject *object, QEvent *event ) override;
QHash<QString, QVariant> settings() const override;
void setSettings( const QHash<QString, QVariant> &settings ) override;
SatellitesConfigDialog *configDialog() override;
private Q_SLOTS:
void activate();
void enableModel( bool enabled );
void visibleModel( bool visible );
void readSettings();
void writeSettings();
void updateSettings();
void updateDataSourceConfig( const QString &source );
void dataSourceParsed( const QString &source );
void userDataSourceAdded( const QString &source );
void showOrbit( bool show );
void trackPlacemark();
protected:
void activateDataSource( const QString &source );
void addBuiltInDataSources();
private:
SatellitesModel *m_satModel;
SatellitesConfigModel *m_configModel;
bool m_isInitialized;
QHash<QString, QVariant> m_settings;
QStringList m_newDataSources;
SatellitesConfigDialog *m_configDialog;
QAction *m_showOrbitAction;
QAction *m_trackPlacemarkAction;
QVector<TrackerPluginItem*> m_trackerList;
};
} // namespace Marble
#endif // MARBLE_SATELLITESPLUGIN_H
diff --git a/src/plugins/render/satellites/TrackerPluginModel.cpp b/src/plugins/render/satellites/TrackerPluginModel.cpp
index ef7c13c5b..c3e982f2f 100644
--- a/src/plugins/render/satellites/TrackerPluginModel.cpp
+++ b/src/plugins/render/satellites/TrackerPluginModel.cpp
@@ -1,172 +1,172 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Guillaume Martres <smarter@ubuntu.com>
//
#include "TrackerPluginModel.h"
#include "CacheStoragePolicy.h"
#include "HttpDownloadManager.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataTreeModel.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "TrackerPluginItem.h"
namespace Marble
{
class TrackerPluginModelPrivate
{
public:
TrackerPluginModelPrivate( TrackerPluginModel *parent, GeoDataTreeModel *treeModel )
: m_parent( parent ),
m_enabled( false ),
m_treeModel( treeModel ),
m_document( new GeoDataDocument() ),
m_storagePolicy(MarbleDirs::localPath() + QLatin1String("/cache/")),
- m_downloadManager( 0 )
+ m_downloadManager( nullptr )
{
}
~TrackerPluginModelPrivate()
{
delete m_document;
qDeleteAll( m_itemVector );
delete m_downloadManager;
}
void downloaded(const QString &relativeUrlString, const QString &id)
{
Q_UNUSED( relativeUrlString );
m_parent->parseFile( id, m_storagePolicy.data( id ) );
}
void update()
{
for( TrackerPluginItem *item: m_itemVector ) {
item->update();
}
}
void updateDocument()
{
// we cannot use ->clear() since its implementation
// will delete all items
for( TrackerPluginItem *item: m_itemVector ) {
int idx = m_document->childPosition( item->placemark() );
if( item->isEnabled() && idx == -1 ) {
m_document->append( item->placemark() );
}
if( !item->isEnabled() && idx > -1 ) {
m_document->remove( idx );
}
}
}
TrackerPluginModel *m_parent;
bool m_enabled;
GeoDataTreeModel *m_treeModel;
GeoDataDocument *m_document;
CacheStoragePolicy m_storagePolicy;
HttpDownloadManager *m_downloadManager;
QVector<TrackerPluginItem *> m_itemVector;
};
TrackerPluginModel::TrackerPluginModel( GeoDataTreeModel *treeModel )
: d( new TrackerPluginModelPrivate( this, treeModel ) )
{
d->m_document->setDocumentRole( TrackingDocument );
d->m_document->setName(QStringLiteral("Satellites"));
if( d->m_enabled ) {
d->m_treeModel->addDocument( d->m_document );
}
d->m_downloadManager = new HttpDownloadManager( &d->m_storagePolicy );
connect( d->m_downloadManager, SIGNAL(downloadComplete(QString,QString)),
this, SLOT(downloaded(QString,QString)) );
}
TrackerPluginModel::~TrackerPluginModel()
{
if( d->m_enabled ) {
d->m_treeModel->removeDocument( d->m_document );
}
delete d;
}
void TrackerPluginModel::enable( bool enabled )
{
if( enabled == d->m_enabled ) {
return;
}
if( enabled ) {
d->m_treeModel->addDocument( d->m_document );
} else {
d->m_treeModel->removeDocument( d->m_document );
}
d->m_enabled = enabled;
}
void TrackerPluginModel::addItem( TrackerPluginItem *mark )
{
d->m_document->append( mark->placemark() );
d->m_itemVector.append( mark );
}
QVector<TrackerPluginItem*> TrackerPluginModel::items() const
{
return d->m_itemVector;
}
void TrackerPluginModel::clear()
{
beginUpdateItems();
qDeleteAll( d->m_itemVector );
d->m_itemVector.clear();
d->m_itemVector.squeeze();
d->m_document->clear();
endUpdateItems();
}
void TrackerPluginModel::beginUpdateItems()
{
if( d->m_enabled ) {
d->m_treeModel->removeDocument( d->m_document );
}
emit itemUpdateStarted();
}
void TrackerPluginModel::endUpdateItems()
{
if( d->m_enabled ) {
d->updateDocument();
d->m_treeModel->addDocument( d->m_document );
}
emit itemUpdateEnded();
}
void TrackerPluginModel::downloadFile(const QUrl &url, const QString &id)
{
d->m_downloadManager->addJob( url, id, id, DownloadBrowse );
}
void TrackerPluginModel::parseFile( const QString &id, const QByteArray &file )
{
Q_UNUSED( id );
Q_UNUSED( file );
}
} // namespace Marble
#include "moc_TrackerPluginModel.cpp"
diff --git a/src/plugins/render/speedometer/Speedometer.cpp b/src/plugins/render/speedometer/Speedometer.cpp
index 9671e5fe0..353fa9e7f 100644
--- a/src/plugins/render/speedometer/Speedometer.cpp
+++ b/src/plugins/render/speedometer/Speedometer.cpp
@@ -1,156 +1,156 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "Speedometer.h"
#include <QIcon>
#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "MarbleModel.h"
#include "PositionTracking.h"
#include "WidgetGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "ViewportParams.h"
namespace Marble
{
Speedometer::Speedometer()
- : AbstractFloatItem( 0 ),
- m_locale( 0 ),
- m_widgetItem( 0 )
+ : AbstractFloatItem( nullptr ),
+ m_locale( nullptr ),
+ m_widgetItem( nullptr )
{
}
Speedometer::Speedometer( const MarbleModel *marbleModel )
: AbstractFloatItem( marbleModel, QPointF( 10.5, 110 ), QSizeF( 135.0, 80.0 ) ),
- m_locale( 0 ),
- m_widgetItem( 0 )
+ m_locale( nullptr ),
+ m_widgetItem( nullptr )
{
setVisible( false );
const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if ( smallScreen ) {
setPosition( QPointF( 10.5, 10.5 ) );
}
}
Speedometer::~Speedometer()
{
}
QStringList Speedometer::backendTypes() const
{
return QStringList(QStringLiteral("speedometer"));
}
QString Speedometer::name() const
{
return tr( "Speedometer" );
}
QString Speedometer::guiString() const
{
return tr( "&Speedometer" );
}
QString Speedometer::nameId() const
{
return QStringLiteral("speedometer");
}
QString Speedometer::version() const
{
return QStringLiteral("1.0");
}
QString Speedometer::description() const
{
return tr( "Display the current cruising speed." );
}
QString Speedometer::copyrightYears() const
{
return QStringLiteral("2011");
}
QVector<PluginAuthor> Speedometer::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"));
}
QIcon Speedometer::icon () const
{
return QIcon(QStringLiteral(":/icons/speedometer.png"));
}
void Speedometer::initialize ()
{
if ( !m_widgetItem ) {
QWidget *widget = new QWidget;
m_widget.setupUi( widget );
m_widgetItem = new WidgetGraphicsItem( this );
m_widgetItem->setWidget( widget );
MarbleGraphicsGridLayout *layout = new MarbleGraphicsGridLayout( 1, 1 );
layout->addItem( m_widgetItem, 0, 0 );
setLayout( layout );
setPadding( 0 );
m_locale = MarbleGlobal::getInstance()->locale();
connect( marbleModel()->positionTracking(), SIGNAL(gpsLocation(GeoDataCoordinates,qreal)),
this, SLOT(updateLocation(GeoDataCoordinates,qreal)) );
}
}
bool Speedometer::isInitialized () const
{
return m_widgetItem;
}
void Speedometer::updateLocation( const GeoDataCoordinates& coordinates, qreal speed )
{
Q_UNUSED( coordinates );
speed *= METER2KM / SEC2HOUR;
QString speedUnit;
switch ( m_locale->measurementSystem() ) {
case MarbleLocale::ImperialSystem:
//miles per hour
speedUnit = tr("mph");
speed *= KM2MI;
break;
case MarbleLocale::MetricSystem:
//kilometers per hour
speedUnit = tr("km/h");
break;
case MarbleLocale::NauticalSystem:
// nm per hour (kt)
speedUnit = tr("kt");
speed *= KM2NM;
break;
}
m_widget.speed->display( speed );
m_widget.speedUnit->setText( speedUnit );
update();
emit repaintNeeded();
}
}
#include "moc_Speedometer.cpp"
diff --git a/src/plugins/render/stars/StarsPlugin.cpp b/src/plugins/render/stars/StarsPlugin.cpp
index 6599545e9..c842f0991 100644
--- a/src/plugins/render/stars/StarsPlugin.cpp
+++ b/src/plugins/render/stars/StarsPlugin.cpp
@@ -1,1488 +1,1488 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2011-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "StarsPlugin.h"
#include "ui_StarsConfigWidget.h"
#include <QRectF>
#include <QSize>
#include <QDateTime>
#include <QRegion>
#include <QContextMenuEvent>
#include <QMenu>
#include <QColorDialog>
#include <qmath.h>
#include "MarbleClock.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "MarbleWidget.h"
#include "AbstractFloatItem.h"
#include "GeoPainter.h"
#include "Planet.h"
#include "PlanetFactory.h"
#include "SunLocator.h"
#include "ViewportParams.h"
#include "src/lib/astro/solarsystem.h"
namespace Marble
{
StarsPlugin::StarsPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel ),
m_nameIndex( 0 ),
- m_configDialog( 0 ),
- ui_configWidget( 0 ),
+ m_configDialog( nullptr ),
+ ui_configWidget( nullptr ),
m_renderStars( true ),
m_renderConstellationLines( true ),
m_renderConstellationLabels( true ),
m_renderDsos( true ),
m_renderDsoLabels( true ),
m_renderSun( true ),
m_renderMoon( true ),
m_renderEcliptic( true ),
m_renderCelestialEquator( true ),
m_renderCelestialPole( true ),
m_starsLoaded( false ),
m_starPixmapsCreated( false ),
m_constellationsLoaded( false ),
m_dsosLoaded( false ),
m_zoomSunMoon( true ),
m_viewSolarSystemLabel( true ),
m_magnitudeLimit( 100 ),
m_zoomCoefficient( 4 ),
m_constellationBrush( Marble::Oxygen::aluminumGray5 ),
m_constellationLabelBrush( Marble::Oxygen::aluminumGray5 ),
m_dsoLabelBrush( Marble::Oxygen::aluminumGray5 ),
m_eclipticBrush( Marble::Oxygen::aluminumGray5 ),
m_celestialEquatorBrush( Marble::Oxygen::aluminumGray5 ),
m_celestialPoleBrush( Marble::Oxygen::aluminumGray5 ),
- m_contextMenu(0),
- m_constellationsAction(0),
- m_sunMoonAction(0),
- m_planetsAction(0),
- m_dsoAction(0),
+ m_contextMenu(nullptr),
+ m_constellationsAction(nullptr),
+ m_sunMoonAction(nullptr),
+ m_planetsAction(nullptr),
+ m_dsoAction(nullptr),
m_doRender( false )
{
bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
if (smallScreen) m_magnitudeLimit = 5;
prepareNames();
}
StarsPlugin::~StarsPlugin()
{
delete m_contextMenu;
}
QStringList StarsPlugin::backendTypes() const
{
return QStringList(QStringLiteral("stars"));
}
QString StarsPlugin::renderPolicy() const
{
return QStringLiteral("SPECIFIED_ALWAYS");
}
QStringList StarsPlugin::renderPosition() const
{
return QStringList(QStringLiteral("STARS"));
}
RenderPlugin::RenderType StarsPlugin::renderType() const
{
return RenderPlugin::ThemeRenderType;
}
QString StarsPlugin::name() const
{
return tr( "Stars" );
}
QString StarsPlugin::guiString() const
{
return tr( "&Stars" );
}
QString StarsPlugin::nameId() const
{
return QStringLiteral("stars");
}
QString StarsPlugin::version() const
{
return QStringLiteral("1.2");
}
QString StarsPlugin::description() const
{
return tr( "A plugin that shows the Starry Sky and the Sun." );
}
QString StarsPlugin::copyrightYears() const
{
return QStringLiteral("2008-2012");
}
QVector<PluginAuthor> StarsPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"))
<< PluginAuthor(QStringLiteral("Rene Kuettner"), QStringLiteral("rene@bitkanal.net"))
<< PluginAuthor(QStringLiteral("Timothy Lanzi"), QStringLiteral("trlanzi@gmail.com"));
}
QIcon StarsPlugin::icon() const
{
return QIcon(QStringLiteral(":/icons/stars.png"));
}
void StarsPlugin::initialize()
{
}
bool StarsPlugin::isInitialized() const
{
return true;
}
QDialog *StarsPlugin::configDialog()
{
if (!m_configDialog) {
// Initializing configuration dialog
m_configDialog = new QDialog;
ui_configWidget = new Ui::StarsConfigWidget;
ui_configWidget->setupUi( m_configDialog );
readSettings();
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()), SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()), SLOT(readSettings()) );
connect( ui_configWidget->m_constellationColorButton, SIGNAL(clicked()), this,
SLOT(constellationGetColor()) );
connect( ui_configWidget->m_constellationLabelColorButton, SIGNAL(clicked()), this,
SLOT(constellationLabelGetColor()) );
connect( ui_configWidget->m_dsoLabelColorButton, SIGNAL(clicked()), this,
SLOT(dsoLabelGetColor()) );
connect( ui_configWidget->m_eclipticColorButton, SIGNAL(clicked()), this,
SLOT(eclipticGetColor()) );
connect( ui_configWidget->m_celestialEquatorColorButton, SIGNAL(clicked()), this,
SLOT(celestialEquatorGetColor()) );
connect( ui_configWidget->m_celestialPoleColorButton, SIGNAL(clicked()), this,
SLOT(celestialPoleGetColor()) );
}
return m_configDialog;
}
QHash<QString, QVariant> StarsPlugin::settings() const
{
QHash<QString, QVariant> settings = RenderPlugin::settings();
settings.insert(QStringLiteral("nameIndex"), m_nameIndex);
settings.insert(QStringLiteral("renderStars"), m_renderStars);
settings.insert(QStringLiteral("renderConstellationLines"), m_renderConstellationLines);
settings.insert(QStringLiteral("renderConstellationLabels"), m_renderConstellationLabels);
settings.insert(QStringLiteral("renderDsos"), m_renderDsos);
settings.insert(QStringLiteral("renderDsoLabels"), m_renderDsoLabels);
settings.insert(QStringLiteral("renderSun"), m_renderSun);
settings.insert(QStringLiteral("renderMoon"), m_renderMoon);
QStringList planetState;
for (const QString &key: m_renderPlanet.keys())
planetState += key + QLatin1Char(':') + QString::number((int)m_renderPlanet[key]);
settings.insert(QStringLiteral("renderPlanet"), planetState.join(QLatin1Char('|')));
settings.insert(QStringLiteral("renderEcliptic"), m_renderEcliptic);
settings.insert(QStringLiteral("renderCelestialEquator"), m_renderCelestialEquator);
settings.insert(QStringLiteral("renderCelestialPole"), m_renderCelestialPole);
settings.insert(QStringLiteral("zoomSunMoon"), m_zoomSunMoon);
settings.insert(QStringLiteral("viewSolarSystemLabel"), m_viewSolarSystemLabel);
settings.insert(QStringLiteral("magnitudeLimit"), m_magnitudeLimit);
settings.insert(QStringLiteral("constellationBrush"), m_constellationBrush.color().rgb());
settings.insert(QStringLiteral("constellationLabelBrush"), m_constellationLabelBrush.color().rgb());
settings.insert(QStringLiteral("dsoLabelBrush"), m_dsoLabelBrush.color().rgb());
settings.insert(QStringLiteral("eclipticBrush"), m_eclipticBrush.color().rgb());
settings.insert(QStringLiteral("celestialEaquatorBrush"), m_celestialEquatorBrush.color().rgb());
settings.insert(QStringLiteral("celestialPoleBrush"), m_celestialPoleBrush.color().rgb());
return settings;
}
void StarsPlugin::setSettings( const QHash<QString, QVariant> &settings )
{
RenderPlugin::setSettings( settings );
m_nameIndex = readSetting<int>(settings, QStringLiteral("nameIndex"), 0);
m_renderStars = readSetting<bool>(settings, QStringLiteral("renderStars"), true);
m_renderConstellationLines = readSetting<bool>(settings, QStringLiteral("renderConstellationLines"), true);
m_renderConstellationLabels = readSetting<bool>(settings, QStringLiteral("renderConstellationLabels"), true);
m_renderDsos = readSetting<bool>(settings, QStringLiteral("renderDsos"), true);
m_renderDsoLabels = readSetting<bool>(settings, QStringLiteral("renderDsoLabels"), true);
m_renderSun = readSetting<bool>(settings, QStringLiteral("renderSun"), true);
m_renderMoon = readSetting<bool>(settings, QStringLiteral("renderMoon"), true);
m_renderPlanet.clear();
const QString renderPlanet = readSetting<QString>(settings, QStringLiteral("renderPlanet"), QString());
const QStringList renderStates = renderPlanet.split(QLatin1Char('|'));
for(const QString &state: renderStates) {
const QStringList stateList = state.split(QLatin1Char(':'));
if (stateList.size() == 2)
m_renderPlanet[stateList[0]] = (bool)stateList[1].toInt();
}
m_renderEcliptic = readSetting<bool>(settings, QStringLiteral("renderEcliptic"), true);
m_renderCelestialEquator = readSetting<bool>(settings, QStringLiteral("renderCelestialEquator"), true);
m_renderCelestialPole = readSetting<bool>(settings, QStringLiteral("renderCelestialPole"), true);
m_zoomSunMoon = readSetting<bool>(settings, QStringLiteral("zoomSunMoon"), true);
m_viewSolarSystemLabel = readSetting<bool>(settings, QStringLiteral("viewSolarSystemLabel"), true);
m_magnitudeLimit = readSetting<int>(settings, QStringLiteral("magnitudeLimit"), 100);
QColor const defaultColor = Marble::Oxygen::aluminumGray5;
m_constellationBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("constellationBrush"), defaultColor.rgb()));
m_constellationLabelBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("constellationLabelBrush"), defaultColor.rgb()));
m_dsoLabelBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("dsoLabelBrush"), defaultColor.rgb()));
m_eclipticBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("eclipticBrush"), defaultColor.rgb()));
m_celestialEquatorBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("celestialEquatorBrush"), defaultColor.rgb()));
m_celestialPoleBrush = QColor(readSetting<QRgb>(settings, QStringLiteral("celestialPoleBrush"), defaultColor.rgb()));
}
QPixmap StarsPlugin::starPixmap(qreal mag, int colorId) const
{
if ( mag < -1 ) {
return m_pixN1Stars.at(colorId);
} else if ( mag < 0 ) {
return m_pixP0Stars.at(colorId);
} else if ( mag < 1 ) {
return m_pixP1Stars.at(colorId);
} else if ( mag < 2 ) {
return m_pixP2Stars.at(colorId);
} else if ( mag < 3 ) {
return m_pixP3Stars.at(colorId);
} else if ( mag < 4 ) {
return m_pixP4Stars.at(colorId);
} else if ( mag < 5 ) {
return m_pixP5Stars.at(colorId);
} else if ( mag < 6 ) {
return m_pixP6Stars.at(colorId);
} else {
return m_pixP7Stars.at(colorId);
}
return QPixmap();
}
void StarsPlugin::prepareNames()
{
QFile names(MarbleDirs::path(QStringLiteral("stars/names.csv")));
if ( !names.open( QIODevice::ReadOnly ) ) {
return;
}
QTextStream in( &names );
while ( !in.atEnd() ) {
QString line = in.readLine();
const QStringList list = line.split(QLatin1Char(';'));
if ( list.size() == 3 ) {
m_nativeHash[ list.at( 0 ) ] = QCoreApplication::translate( "StarNames", list.at( 1 ).toUtf8().constData() );
m_abbrHash[ list.at( 0 ) ] = list.at( 2 );
}
}
names.close();
}
QString StarsPlugin::assembledConstellation(const QString &name)
{
switch (m_nameIndex) {
case 0:
return name;
case 1:
return m_nativeHash[name];
case 2:
return m_abbrHash[name];
default:
return name;
}
}
void StarsPlugin::readSettings()
{
if ( !m_configDialog ) {
return;
}
ui_configWidget->constellationNamesComboBox->setCurrentIndex(m_nameIndex);
Qt::CheckState const constellationLineState = m_renderConstellationLines ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewConstellationLinesCheckbox->setCheckState( constellationLineState );
Qt::CheckState const constellationLabelState = m_renderConstellationLabels ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewConstellationLabelsCheckbox->setCheckState( constellationLabelState );
Qt::CheckState const dsoState = m_renderDsos ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewDsosCheckbox->setCheckState( dsoState );
Qt::CheckState const dsoLabelState = m_renderDsoLabels ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewDsoLabelCheckbox->setCheckState( dsoLabelState );
Qt::CheckState const sunState = m_renderSun ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 0 )->setCheckState( sunState );
Qt::CheckState const moonState = m_renderMoon ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 1 )->setCheckState( moonState );
Qt::CheckState const mercuryState = m_renderPlanet["mercury"] ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 2 )->setCheckState(mercuryState);
Qt::CheckState const venusState = m_renderPlanet["venus"] ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 3 )->setCheckState(venusState);
Qt::CheckState const marsState = m_renderPlanet["mars"] ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 5 )->setCheckState(marsState);
Qt::CheckState const jupiterState = m_renderPlanet["jupiter"] ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 6 )->setCheckState(jupiterState);
Qt::CheckState const saturnState = m_renderPlanet["saturn"] ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 7 )->setCheckState(saturnState);
Qt::CheckState const uranusState = m_renderPlanet["uranus"] ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 8 )->setCheckState(uranusState);
Qt::CheckState const neptuneState = m_renderPlanet["neptune"] ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_solarSystemListWidget->item( 9 )->setCheckState(neptuneState);
Qt::CheckState const eclipticState = m_renderEcliptic ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewEclipticCheckbox->setCheckState( eclipticState );
Qt::CheckState const celestialEquatorState = m_renderCelestialEquator ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewCelestialEquatorCheckbox->setCheckState( celestialEquatorState );
Qt::CheckState const celestialPoleState = m_renderCelestialPole ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewCelestialPoleCheckbox->setCheckState( celestialPoleState );
Qt::CheckState const zoomSunMoonState = m_zoomSunMoon ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_zoomSunMoonCheckbox->setCheckState( zoomSunMoonState );
Qt::CheckState const viewSolarSystemLabelState = m_viewSolarSystemLabel ? Qt::Checked : Qt::Unchecked;
ui_configWidget->m_viewSolarSystemLabelCheckbox->setCheckState( viewSolarSystemLabelState );
int magState = m_magnitudeLimit;
if ( magState < ui_configWidget->m_magnitudeSlider->minimum() ) {
magState = ui_configWidget->m_magnitudeSlider->minimum();
}
else if ( magState > ui_configWidget->m_magnitudeSlider->maximum() ) {
magState = ui_configWidget->m_magnitudeSlider->maximum();
}
ui_configWidget->m_magnitudeSlider->setValue(magState);
QPalette constellationPalette;
constellationPalette.setColor( QPalette::Button, m_constellationBrush.color() );
ui_configWidget->m_constellationColorButton->setPalette( constellationPalette );
QPalette constellationLabelPalette;
constellationLabelPalette.setColor( QPalette::Button, m_constellationLabelBrush.color() );
ui_configWidget->m_constellationLabelColorButton->setPalette( constellationLabelPalette );
QPalette dsoLabelPalette;
dsoLabelPalette.setColor( QPalette::Button, m_dsoLabelBrush.color() );
ui_configWidget->m_dsoLabelColorButton->setPalette( dsoLabelPalette );
QPalette eclipticPalette;
eclipticPalette.setColor( QPalette::Button, m_eclipticBrush.color() );
ui_configWidget->m_eclipticColorButton->setPalette( eclipticPalette );
QPalette celestialEquatorPalette;
celestialEquatorPalette.setColor( QPalette::Button, m_celestialEquatorBrush.color() );
ui_configWidget->m_celestialEquatorColorButton->setPalette( celestialEquatorPalette );
QPalette celestialPolePalette;
celestialPolePalette.setColor( QPalette::Button, m_celestialPoleBrush.color() );
ui_configWidget->m_celestialPoleColorButton->setPalette( celestialPolePalette );
}
void StarsPlugin::writeSettings()
{
m_nameIndex = ui_configWidget->constellationNamesComboBox->currentIndex();
m_renderConstellationLines = ui_configWidget->m_viewConstellationLinesCheckbox->checkState() == Qt::Checked;
m_renderConstellationLabels = ui_configWidget->m_viewConstellationLabelsCheckbox->checkState() == Qt::Checked;
m_renderDsos = ui_configWidget->m_viewDsosCheckbox->checkState() == Qt::Checked;
m_renderDsoLabels = ui_configWidget->m_viewDsoLabelCheckbox->checkState() == Qt::Checked;
m_renderSun = ui_configWidget->m_solarSystemListWidget->item( 0 )->checkState() == Qt::Checked;
m_renderMoon = ui_configWidget->m_solarSystemListWidget->item( 1 )->checkState() == Qt::Checked;
m_renderPlanet["mercury"] = ui_configWidget->m_solarSystemListWidget->item( 2 )->checkState()
== Qt::Checked;
m_renderPlanet["venus"] = ui_configWidget->m_solarSystemListWidget->item( 3 )->checkState()
== Qt::Checked;
m_renderPlanet["mars"] = ui_configWidget->m_solarSystemListWidget->item( 5 )->checkState()
== Qt::Checked;
m_renderPlanet["jupiter"] = ui_configWidget->m_solarSystemListWidget->item( 6 )->checkState()
== Qt::Checked;
m_renderPlanet["saturn"] = ui_configWidget->m_solarSystemListWidget->item( 7 )->checkState()
== Qt::Checked;
m_renderPlanet["uranus"] = ui_configWidget->m_solarSystemListWidget->item( 8 )->checkState()
== Qt::Checked;
m_renderPlanet["neptune"] = ui_configWidget->m_solarSystemListWidget->item( 9 )->checkState()
== Qt::Checked;
m_renderEcliptic = ui_configWidget->m_viewEclipticCheckbox->checkState() == Qt::Checked;
m_renderCelestialEquator = ui_configWidget->m_viewCelestialEquatorCheckbox->checkState() == Qt::Checked;
m_renderCelestialPole = ui_configWidget->m_viewCelestialPoleCheckbox->checkState() == Qt::Checked;
m_zoomSunMoon = ui_configWidget->m_zoomSunMoonCheckbox->checkState() == Qt::Checked;
m_viewSolarSystemLabel = ui_configWidget->m_viewSolarSystemLabelCheckbox->checkState() == Qt::Checked;
m_magnitudeLimit = ui_configWidget->m_magnitudeSlider->value();
m_constellationBrush = QBrush( ui_configWidget->m_constellationColorButton->palette().color( QPalette::Button) );
m_constellationLabelBrush = QBrush( ui_configWidget->m_constellationLabelColorButton->palette().color( QPalette::Button) );
m_dsoLabelBrush = QBrush( ui_configWidget->m_dsoLabelColorButton->palette().color( QPalette::Button) );
m_eclipticBrush = QBrush( ui_configWidget->m_eclipticColorButton->palette().color( QPalette::Button) );
m_celestialEquatorBrush = QBrush( ui_configWidget->m_celestialEquatorColorButton->palette().color( QPalette::Button) );
m_celestialPoleBrush = QBrush( ui_configWidget->m_celestialPoleColorButton->palette().color( QPalette::Button) );
emit settingsChanged( nameId() );
}
void StarsPlugin::constellationGetColor()
{
- const QColor c = QColorDialog::getColor( m_constellationBrush.color(), 0, tr("Please choose the color for the constellation lines.") );
+ const QColor c = QColorDialog::getColor( m_constellationBrush.color(), nullptr, tr("Please choose the color for the constellation lines.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->m_constellationColorButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->m_constellationColorButton->setPalette( palette );
}
}
void StarsPlugin::constellationLabelGetColor()
{
- const QColor c = QColorDialog::getColor( m_constellationLabelBrush.color(), 0, tr("Please choose the color for the constellation labels.") );
+ const QColor c = QColorDialog::getColor( m_constellationLabelBrush.color(), nullptr, tr("Please choose the color for the constellation labels.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->m_constellationLabelColorButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->m_constellationLabelColorButton->setPalette( palette );
}
}
void StarsPlugin::dsoLabelGetColor()
{
- const QColor c = QColorDialog::getColor( m_dsoLabelBrush.color(), 0, tr("Please choose the color for the dso labels.") );
+ const QColor c = QColorDialog::getColor( m_dsoLabelBrush.color(), nullptr, tr("Please choose the color for the dso labels.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->m_dsoLabelColorButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->m_dsoLabelColorButton->setPalette( palette );
}
}
void StarsPlugin::eclipticGetColor()
{
- const QColor c = QColorDialog::getColor( m_eclipticBrush.color(), 0, tr("Please choose the color for the ecliptic.") );
+ const QColor c = QColorDialog::getColor( m_eclipticBrush.color(), nullptr, tr("Please choose the color for the ecliptic.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->m_eclipticColorButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->m_eclipticColorButton->setPalette( palette );
}
}
void StarsPlugin::celestialEquatorGetColor()
{
- const QColor c = QColorDialog::getColor( m_celestialEquatorBrush.color(), 0, tr("Please choose the color for the celestial equator.") );
+ const QColor c = QColorDialog::getColor( m_celestialEquatorBrush.color(), nullptr, tr("Please choose the color for the celestial equator.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->m_celestialEquatorColorButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->m_celestialEquatorColorButton->setPalette( palette );
}
}
void StarsPlugin::celestialPoleGetColor()
{
- const QColor c = QColorDialog::getColor( m_celestialPoleBrush.color(), 0, tr("Please choose the color for the celestial equator.") );
+ const QColor c = QColorDialog::getColor( m_celestialPoleBrush.color(), nullptr, tr("Please choose the color for the celestial equator.") );
if ( c.isValid() ) {
QPalette palette = ui_configWidget->m_celestialPoleColorButton->palette();
palette.setColor( QPalette::Button, c );
ui_configWidget->m_celestialPoleColorButton->setPalette( palette );
}
}
void StarsPlugin::loadStars()
{
//mDebug() << Q_FUNC_INFO;
// Load star data
m_stars.clear();
QFile starFile(MarbleDirs::path(QStringLiteral("stars/stars.dat")));
starFile.open( QIODevice::ReadOnly );
QDataStream in( &starFile );
// Read and check the header
quint32 magic;
in >> magic;
if ( magic != 0x73746172 ) {
return;
}
// Read the version
qint32 version;
in >> version;
if ( version > 004 ) {
mDebug() << "stars.dat: file too new.";
return;
}
if ( version == 003 ) {
mDebug() << "stars.dat: file version no longer supported.";
return;
}
int maxid = 0;
int id = 0;
int starIndex = 0;
double ra;
double de;
double mag;
int colorId = 2;
mDebug() << "Star Catalog Version " << version;
while ( !in.atEnd() ) {
if ( version >= 2 ) {
in >> id;
}
if ( id > maxid ) {
maxid = id;
}
in >> ra;
in >> de;
in >> mag;
if ( version >= 4 ) {
in >> colorId;
}
StarPoint star( id, ( qreal )( ra ), ( qreal )( de ), ( qreal )( mag ), colorId );
// Create entry in stars database
m_stars << star;
// Create key,value pair in idHash table to map from star id to
// index in star database vector
m_idHash[id] = starIndex;
// Increment Index for use in hash
++starIndex;
}
// load the Sun pixmap
// TODO: adjust pixmap size according to distance
m_pixmapSun.load(MarbleDirs::path(QStringLiteral("svg/sun.png")));
m_pixmapMoon.load(MarbleDirs::path(QStringLiteral("svg/moon.png")));
m_starsLoaded = true;
}
void StarsPlugin::createStarPixmaps()
{
// Load star pixmaps
QVector<QPixmap> pixBigStars;
pixBigStars.clear();
pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_blue.png"))));
pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_bluewhite.png"))));
pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_white.png"))));
pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_yellow.png"))));
pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_orange.png"))));
pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_red.png"))));
pixBigStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_0_garnetred.png"))));
QVector<QPixmap> pixSmallStars;
pixSmallStars.clear();
pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_blue.png"))));
pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_bluewhite.png"))));
pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_white.png"))));
pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_yellow.png"))));
pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_orange.png"))));
pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_red.png"))));
pixSmallStars.append(QPixmap(MarbleDirs::path(QStringLiteral("bitmaps/stars/star_3_garnetred.png"))));
// Pre-Scale Star Pixmaps
m_pixN1Stars.clear();
for ( int p=0; p < pixBigStars.size(); ++p) {
int width = 1.0*pixBigStars.at(p).width();
m_pixN1Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP0Stars.clear();
for ( int p=0; p < pixBigStars.size(); ++p) {
int width = 0.90*pixBigStars.at(p).width();
m_pixP0Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP1Stars.clear();
for ( int p=0; p < pixBigStars.size(); ++p) {
int width = 0.80*pixBigStars.at(p).width();
m_pixP1Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP2Stars.clear();
for ( int p=0; p < pixBigStars.size(); ++p) {
int width = 0.70*pixBigStars.at(p).width();
m_pixP2Stars.append(pixBigStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP3Stars.clear();
for ( int p=0; p < pixSmallStars.size(); ++p) {
int width = 14;
m_pixP3Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP4Stars.clear();
for ( int p=0; p < pixSmallStars.size(); ++p) {
int width = 10;
m_pixP4Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP5Stars.clear();
for ( int p=0; p < pixSmallStars.size(); ++p) {
int width = 6;
m_pixP5Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP6Stars.clear();
for ( int p=0; p < pixSmallStars.size(); ++p) {
int width = 4;
m_pixP6Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_pixP7Stars.clear();
for ( int p=0; p < pixSmallStars.size(); ++p) {
int width = 1;
m_pixP7Stars.append(pixSmallStars.at(p).scaledToWidth(width,Qt::SmoothTransformation));
}
m_starPixmapsCreated = true;
}
void StarsPlugin::loadConstellations()
{
// Load star data
m_constellations.clear();
QFile constellationFile(MarbleDirs::path(QStringLiteral("stars/constellations.dat")));
constellationFile.open( QIODevice::ReadOnly );
QTextStream in( &constellationFile );
QString line;
QString indexList;
while ( !in.atEnd() ) {
line = in.readLine();
// Check for null line at end of file
if ( line.isNull() ) {
continue;
}
// Ignore Comment lines in header and
// between constellation entries
if (line.startsWith(QLatin1Char('#'))) {
continue;
}
indexList = in.readLine();
// Make sure we have a valid label and indexList
if ( indexList.isNull() ) {
break;
}
Constellation constellation( this, line, indexList );
m_constellations << constellation;
}
m_constellationsLoaded = true;
}
void StarsPlugin::loadDsos()
{
// Load star data
m_dsos.clear();
QFile dsoFile(MarbleDirs::path(QStringLiteral("stars/dso.dat")));
dsoFile.open( QIODevice::ReadOnly );
QTextStream in( &dsoFile );
QString line;
while ( !in.atEnd() ) {
line = in.readLine();
// Check for null line at end of file
if ( line.isNull() ) {
continue;
}
// Ignore Comment lines in header and
// between dso entries
if (line.startsWith(QLatin1Char('#'))) {
continue;
}
QStringList entries = line.split( QLatin1Char( ',' ) );
QString id = entries.at( 0 );
double raH = entries.at( 1 ).toDouble();
double raM = entries.at( 2 ).toDouble();
double raS = entries.at( 3 ).toDouble();
double decD = entries.at( 4 ).toDouble();
double decM = entries.at( 5 ).toDouble();
double decS = entries.at( 6 ).toDouble();
double raRad = ( raH+raM/60.0+raS/3600.0 )*15.0*M_PI/180.0;
double decRad;
if ( decD >= 0.0 ) {
decRad = ( decD+decM/60.0+decS/3600.0 )*M_PI/180.0;
}
else {
decRad = ( decD-decM/60.0-decS/3600.0 )*M_PI/180.0;
}
DsoPoint dso( id, ( qreal )( raRad ), ( qreal )( decRad ) );
// Create entry in stars database
m_dsos << dso;
}
m_dsoImage.load(MarbleDirs::path(QStringLiteral("stars/deepsky.png")));
m_dsosLoaded = true;
}
bool StarsPlugin::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos, GeoSceneLayer * layer )
{
Q_UNUSED( renderPos )
Q_UNUSED( layer )
QString planetId = marbleModel()->planetId();
const bool doRender = !viewport->mapCoversViewport() &&
( (viewport->projection() == Spherical || viewport->projection() == VerticalPerspective) &&
planetId == QLatin1String("earth")); // So far displaying stars is only supported on earth.
if ( doRender != m_doRender ) {
if ( doRender ) {
connect( marbleModel()->clock(), SIGNAL(timeChanged()),
this, SLOT(requestRepaint()) );
} else {
disconnect( marbleModel()->clock(), SIGNAL(timeChanged()),
this, SLOT(requestRepaint()) );
}
m_doRender = doRender;
}
painter->save();
SolarSystem sys;
QDateTime dateTime = marbleModel()->clock()->dateTime();
sys.setCurrentMJD(
dateTime.date().year(), dateTime.date().month(), dateTime.date().day(),
dateTime.time().hour(), dateTime.time().minute(),
(double)dateTime.time().second());
QString const pname = planetId.at(0).toUpper() + planetId.right(planetId.size() - 1);
QByteArray name = pname.toLatin1();
sys.setCentralBody( name.data() );
Vec3 skyVector = sys.getPlanetocentric (0.0, 0.0);
qreal skyRotationAngle = -atan2(skyVector[1], skyVector[0]);
const qreal centerLon = viewport->centerLongitude();
const qreal centerLat = viewport->centerLatitude();
const qreal skyRadius = 0.6 * sqrt( ( qreal )viewport->width() * viewport->width() + viewport->height() * viewport->height() );
if ( doRender ) {
if (!m_starPixmapsCreated) {
createStarPixmaps();
m_starPixmapsCreated = true;
}
// Delayed initialization:
// Load the star database only if the sky is actually being painted...
if ( !m_starsLoaded ) {
loadStars();
m_starsLoaded = true;
}
if ( !m_constellationsLoaded ) {
loadConstellations();
m_constellationsLoaded = true;
}
if ( !m_dsosLoaded ) {
loadDsos();
m_dsosLoaded = true;
}
const qreal earthRadius = viewport->radius();
// List of Pens used to draw the sky
QPen polesPen( m_celestialPoleBrush, 2, Qt::SolidLine );
QPen constellationPenSolid( m_constellationBrush, 1, Qt::SolidLine );
QPen constellationPenDash( m_constellationBrush, 1, Qt::DashLine );
QPen constellationLabelPen( m_constellationLabelBrush, 1, Qt::SolidLine );
QPen eclipticPen( m_eclipticBrush, 1, Qt::DotLine );
QPen equatorPen( m_celestialEquatorBrush, 1, Qt::DotLine );
QPen dsoLabelPen (m_dsoLabelBrush, 1, Qt::SolidLine);
const Quaternion skyAxis = Quaternion::fromEuler( -centerLat , centerLon + skyRotationAngle, 0.0 );
matrix skyAxisMatrix;
skyAxis.inverse().toMatrix( skyAxisMatrix );
if ( m_renderCelestialPole ) {
polesPen.setWidth( 2 );
painter->setPen( polesPen );
Quaternion qpos1;
qpos1 = Quaternion::fromSpherical( 0, 90 * DEG2RAD );
qpos1.rotateAroundAxis( skyAxisMatrix );
if ( qpos1.v[Q_Z] < 0 ) {
const int x1 = ( int )( viewport->width() / 2 + skyRadius * qpos1.v[Q_X] );
const int y1 = ( int )( viewport->height() / 2 - skyRadius * qpos1.v[Q_Y] );
painter->drawLine( x1, y1, x1+10, y1 );
painter->drawLine( x1+5, y1-5, x1+5, y1+5 );
painter->drawText( x1+8, y1+12, "NP" );
}
Quaternion qpos2;
qpos2 = Quaternion::fromSpherical( 0, -90 * DEG2RAD );
qpos2.rotateAroundAxis( skyAxisMatrix );
if ( qpos2.v[Q_Z] < 0 ) {
const int x1 = ( int )( viewport->width() / 2 + skyRadius * qpos2.v[Q_X] );
const int y1 = ( int )( viewport->height() / 2 - skyRadius * qpos2.v[Q_Y] );
painter->drawLine( x1, y1, x1+10, y1 );
painter->drawLine( x1+5, y1-5, x1+5, y1+5 );
painter->drawText( x1+8, y1+12, "SP" );
}
}
if( m_renderEcliptic ) {
const Quaternion eclipticAxis = Quaternion::fromEuler( 0.0, 0.0, -marbleModel()->planet()->epsilon() );
matrix eclipticAxisMatrix;
(eclipticAxis * skyAxis).inverse().toMatrix( eclipticAxisMatrix );
painter->setPen(eclipticPen);
int previousX = -1;
int previousY = -1;
for ( int i = 0; i <= 36; ++i) {
Quaternion qpos;
qpos = Quaternion::fromSpherical( i * 10 * DEG2RAD, 0 );
qpos.rotateAroundAxis( eclipticAxisMatrix );
int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] );
int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] );
if ( qpos.v[Q_Z] < 0 && previousX >= 0 ) painter->drawLine(previousX, previousY, x, y);
previousX = x;
previousY = y;
}
}
if( m_renderCelestialEquator ) {
painter->setPen(equatorPen);
int previousX = -1;
int previousY = -1;
for ( int i = 0; i <= 36; ++i) {
Quaternion qpos;
qpos = Quaternion::fromSpherical( i * 10 * DEG2RAD, 0 );
qpos.rotateAroundAxis( skyAxisMatrix );
int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] );
int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] );
if ( qpos.v[Q_Z] < 0 && previousX > 0 ) painter->drawLine(previousX, previousY, x, y);
previousX = x;
previousY = y;
}
}
if ( m_renderDsos ) {
painter->setPen(dsoLabelPen);
// Render Deep Space Objects
for ( int d = 0; d < m_dsos.size(); ++d ) {
Quaternion qpos = m_dsos.at( d ).quaternion();
qpos.rotateAroundAxis( skyAxisMatrix );
if ( qpos.v[Q_Z] > 0 ) {
continue;
}
qreal earthCenteredX = qpos.v[Q_X] * skyRadius;
qreal earthCenteredY = qpos.v[Q_Y] * skyRadius;
// Don't draw high placemarks (e.g. satellites) that aren't visible.
if ( qpos.v[Q_Z] < 0
&& ( ( earthCenteredX * earthCenteredX
+ earthCenteredY * earthCenteredY )
< earthRadius * earthRadius ) ) {
continue;
}
// Let (x, y) be the position on the screen of the placemark..
const int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] );
const int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] );
// Skip placemarks that are outside the screen area
if ( x < 0 || x >= viewport->width() ||
y < 0 || y >= viewport->height() ) {
continue;
}
// Hard Code DSO Size for now
qreal size = 20;
// Center Image on x,y location
painter->drawImage( QRectF( x-size/2, y-size/2, size, size ),m_dsoImage );
if (m_renderDsoLabels) {
painter->drawText( x+8, y+12, m_dsos.at( d ).id() );
}
}
}
if ( m_renderConstellationLines || m_renderConstellationLabels )
{
// Render Constellations
for ( int c = 0; c < m_constellations.size(); ++c ) {
int xMean = 0;
int yMean = 0;
int endptCount = 0;
painter->setPen( constellationPenSolid );
for ( int s = 0; s < ( m_constellations.at( c ).size() - 1 ); ++s ) {
int starId1 = m_constellations.at( c ).at( s );
int starId2 = m_constellations.at( c ).at( s + 1 );
if ( starId1 == -1 || starId2 == -1 ) {
// starId == -1 means we don't draw this segment
continue;
} else if ( starId1 == -2 || starId2 == -2 ) {
painter->setPen( constellationPenDash );
} else if ( starId1 == -3 || starId2 == -3 ) {
painter->setPen( constellationPenSolid );
}
int idx1 = m_idHash.value( starId1,-1 );
int idx2 = m_idHash.value( starId2,-1 );
if ( idx1 < 0 ) {
mDebug() << "unknown star, "
<< starId1 << ", in constellation "
<< m_constellations.at( c ).name();
continue;
}
if ( idx2 < 0 ) {
mDebug() << "unknown star, "
<< starId1 << ", in constellation "
<< m_constellations.at( c ).name();
continue;
}
// Fetch quaternion from star s in constellation c
Quaternion q1 = m_stars.at( idx1 ).quaternion();
// Fetch quaternion from star s+1 in constellation c
Quaternion q2 = m_stars.at( idx2 ).quaternion();
q1.rotateAroundAxis( skyAxisMatrix );
q2.rotateAroundAxis( skyAxisMatrix );
if ( q1.v[Q_Z] > 0 || q2.v[Q_Z] > 0 ) {
continue;
}
// Let (x, y) be the position on the screen of the placemark..
int x1 = ( int )( viewport->width() / 2 + skyRadius * q1.v[Q_X] );
int y1 = ( int )( viewport->height() / 2 - skyRadius * q1.v[Q_Y] );
int x2 = ( int )( viewport->width() / 2 + skyRadius * q2.v[Q_X] );
int y2 = ( int )( viewport->height() / 2 - skyRadius * q2.v[Q_Y] );
xMean = xMean + x1 + x2;
yMean = yMean + y1 + y2;
endptCount = endptCount + 2;
if ( m_renderConstellationLines ) {
painter->drawLine( x1, y1, x2, y2 );
}
}
// Skip constellation labels that are outside the screen area
if ( endptCount > 0 ) {
xMean = xMean / endptCount;
yMean = yMean / endptCount;
}
if ( endptCount < 1 || xMean < 0 || xMean >= viewport->width()
|| yMean < 0 || yMean >= viewport->height() )
continue;
painter->setPen( constellationLabelPen );
if ( m_renderConstellationLabels ) {
painter->drawText( xMean, yMean, m_constellations.at( c ).name() );
}
}
}
// Render Stars
for ( int s = 0; s < m_stars.size(); ++s ) {
Quaternion qpos = m_stars.at(s).quaternion();
qpos.rotateAroundAxis( skyAxisMatrix );
if ( qpos.v[Q_Z] > 0 ) {
continue;
}
qreal earthCenteredX = qpos.v[Q_X] * skyRadius;
qreal earthCenteredY = qpos.v[Q_Y] * skyRadius;
// Don't draw high placemarks (e.g. satellites) that aren't visible.
if ( qpos.v[Q_Z] < 0
&& ( ( earthCenteredX * earthCenteredX
+ earthCenteredY * earthCenteredY )
< earthRadius * earthRadius ) ) {
continue;
}
// Let (x, y) be the position on the screen of the placemark..
const int x = ( int )( viewport->width() / 2 + skyRadius * qpos.v[Q_X] );
const int y = ( int )( viewport->height() / 2 - skyRadius * qpos.v[Q_Y] );
// Skip placemarks that are outside the screen area
if ( x < 0 || x >= viewport->width()
|| y < 0 || y >= viewport->height() )
continue;
// Show star if it is brighter than magnitude threshold
if ( m_stars.at(s).magnitude() < m_magnitudeLimit ) {
// colorId is used to select which pixmap in vector to display
int colorId = m_stars.at(s).colorId();
QPixmap s_pixmap = starPixmap(m_stars.at(s).magnitude(), colorId);
int sizeX = s_pixmap.width();
int sizeY = s_pixmap.height();
painter->drawPixmap( x-sizeX/2, y-sizeY/2 ,s_pixmap );
}
}
if ( m_renderSun ) {
// sun
double ra = 0.0;
double decl = 0.0;
sys.getSun( ra, decl );
ra = 15.0 * sys.DmsDegF( ra );
decl = sys.DmsDegF( decl );
Quaternion qpos = Quaternion::fromSpherical( ra * DEG2RAD, decl * DEG2RAD );
qpos.rotateAroundAxis( skyAxisMatrix );
if ( qpos.v[Q_Z] <= 0 ) {
QPixmap glow(MarbleDirs::path(QStringLiteral("svg/glow.png")));
qreal deltaX = glow.width() / 2.;
qreal deltaY = glow.height() / 2.;
int x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]);
int y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]);
bool glowDrawn = false;
if (!(x < -glow.width() || x >= viewport->width() ||
y < -glow.height() || y >= viewport->height())) {
painter->drawPixmap( x - deltaX, y - deltaY, glow );
glowDrawn = true;
}
if (glowDrawn) {
double diameter = 0.0, mag = 0.0;
sys.getPhysSun(diameter, mag);
const int coefficient = m_zoomSunMoon ? m_zoomCoefficient : 1;
const qreal size = skyRadius * qSin(diameter) * coefficient;
const qreal factor = size/m_pixmapSun.width();
QPixmap sun = m_pixmapSun.transformed(QTransform().scale(factor, factor),
Qt::SmoothTransformation);
deltaX = sun.width() / 2.;
deltaY = sun.height() / 2.;
x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]);
y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]);
painter->drawPixmap( x - deltaX, y - deltaY, sun );
}
// It's labels' time!
if (m_viewSolarSystemLabel)
painter->drawText(x+deltaX*1.5, y+deltaY*1.5, tr("Sun"));
}
}
if ( m_renderMoon && marbleModel()->planetId() == QLatin1String("earth")) {
// moon
double ra=0.0;
double decl=0.0;
sys.getMoon(ra, decl);
ra = 15.0 * sys.DmsDegF(ra);
decl = sys.DmsDegF(decl);
Quaternion qpos = Quaternion::fromSpherical( ra * DEG2RAD,
decl * DEG2RAD );
qpos.rotateAroundAxis( skyAxisMatrix );
if ( qpos.v[Q_Z] <= 0 ) {
// If zoom Sun and Moon is enabled size is multiplied by zoomCoefficient.
const int coefficient = m_zoomSunMoon ? m_zoomCoefficient : 1;
QPixmap moon = m_pixmapMoon.copy();
const qreal size = skyRadius * qSin(sys.getDiamMoon()) * coefficient;
qreal deltaX = size / 2.;
qreal deltaY = size / 2.;
const int x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]);
const int y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]);
if (!(x < -size || x >= viewport->width() ||
y < -size || y >= viewport->height())) {
// Moon phases
double phase = 0.0, ildisk = 0.0, amag = 0.0;
sys.getLunarPhase(phase, ildisk, amag);
QPainterPath path;
QRectF fullMoonRect = moon.rect();
if (ildisk < 0.05) {
// small enough, so it's not visible
path.addEllipse(fullMoonRect);
} else if (ildisk < 0.95) { // makes sense to do smth
QRectF halfEllipseRect;
qreal ellipseWidth = 2 * qAbs(ildisk-0.5) * moon.width();
halfEllipseRect.setX((fullMoonRect.width() - ellipseWidth) * 0.5);
halfEllipseRect.setWidth(ellipseWidth);
halfEllipseRect.setHeight(moon.height());
if (phase < 0.5) {
if (ildisk < 0.5) {
path.moveTo(fullMoonRect.width()/2, moon.height());
path.arcTo(fullMoonRect, -90, -180);
path.arcTo(halfEllipseRect, 90, -180);
} else {
path.moveTo(fullMoonRect.width()/2, 0);
path.arcTo(fullMoonRect, 90, 180);
path.arcTo(halfEllipseRect, -90, -180);
}
} else {
if (ildisk < 0.5) {
path.moveTo(fullMoonRect.width()/2, moon.height());
path.arcTo(fullMoonRect, -90, 180);
path.arcTo(halfEllipseRect, 90, 180);
} else {
path.moveTo(fullMoonRect.width()/2, 0);
path.arcTo(fullMoonRect, 90, -180);
path.arcTo(halfEllipseRect, -90, 180);
}
}
path.closeSubpath();
}
QPainter overlay;
overlay.begin(&moon);
overlay.setPen(Qt::NoPen);
overlay.setBrush(QBrush(QColor(0, 0, 0, 180)));
overlay.setRenderHint(QPainter::Antialiasing, true);
overlay.drawPath(path);
overlay.end();
qreal angle = marbleModel()->planet()->epsilon() * qCos(ra * DEG2RAD) * RAD2DEG;
if (viewport->polarity() < 0) angle += 180;
QTransform form;
const qreal factor = size / moon.size().width();
moon = moon.transformed(form.rotate(angle).scale(factor, factor),
Qt::SmoothTransformation);
painter->drawPixmap( x - deltaX, y - deltaY, moon );
// It's labels' time!
if (m_viewSolarSystemLabel)
painter->drawText(x+deltaX, y+deltaY, PlanetFactory::localizedName("moon"));
}
}
}
for(const QString &planet: m_renderPlanet.keys()) {
if (m_renderPlanet[planet])
renderPlanet(planet, painter, sys, viewport, skyRadius, skyAxisMatrix);
}
}
painter->restore();
return true;
}
void StarsPlugin::renderPlanet(const QString &planetId,
GeoPainter *painter,
SolarSystem &sys,
ViewportParams *viewport,
qreal skyRadius,
matrix &skyAxisMatrix) const
{
double ra(.0), decl(.0), diam(.0), mag(.0), phase(.0);
int color=0;
// venus, mars, jupiter, uranus, neptune, saturn
if (planetId == QLatin1String("venus")) {
sys.getVenus(ra, decl);
sys.getPhysVenus(diam, mag, phase);
color = 2;
} else if (planetId == QLatin1String("mars")) {
sys.getMars(ra, decl);
sys.getPhysMars(diam, mag, phase);
color = 5;
} else if (planetId == QLatin1String("jupiter")) {
sys.getJupiter(ra, decl);
sys.getPhysJupiter(diam, mag, phase);
color = 2;
} else if (planetId == QLatin1String("mercury")) {
sys.getMercury(ra, decl);
sys.getPhysMercury(diam, mag, phase);
color = 3;
} else if (planetId == QLatin1String("saturn")) {
sys.getSaturn(ra, decl);
sys.getPhysSaturn(diam, mag, phase);
color = 3;
} else if (planetId == QLatin1String("uranus")) {
sys.getUranus(ra, decl);
sys.getPhysUranus(diam, mag, phase);
color = 0;
} else if (planetId == QLatin1String("neptune")) {
sys.getNeptune(ra, decl);
sys.getPhysNeptune(diam, mag, phase);
color = 0;
} else {
return;
}
ra = 15.0 * sys.DmsDegF(ra);
decl = sys.DmsDegF(decl);
Quaternion qpos = Quaternion::fromSpherical( ra * DEG2RAD,
decl * DEG2RAD );
qpos.rotateAroundAxis( skyAxisMatrix );
if ( qpos.v[Q_Z] <= 0 ) {
QPixmap planetPixmap = starPixmap(mag, color);
qreal deltaX = planetPixmap.width() / 2.;
qreal deltaY = planetPixmap.height() / 2.;
const int x = (int)(viewport->width() / 2 + skyRadius * qpos.v[Q_X]);
const int y = (int)(viewport->height() / 2 - skyRadius * qpos.v[Q_Y]);
if (!(x < 0 || x >= viewport->width() ||
y < 0 || y >= viewport->height())) {
painter->drawPixmap( x - deltaX, y - deltaY, planetPixmap );
}
// It's labels' time!
if (m_viewSolarSystemLabel)
painter->drawText(x+deltaX, y+deltaY, PlanetFactory::localizedName(planetId));
}
}
void StarsPlugin::requestRepaint()
{
emit repaintNeeded( QRegion() );
}
void StarsPlugin::toggleSunMoon(bool on)
{
m_renderSun = on;
m_renderMoon = on;
if (on) {
m_viewSolarSystemLabel = true;
}
const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked;
if ( m_configDialog ) {
ui_configWidget->m_solarSystemListWidget->item( 0 )->setCheckState( state );
ui_configWidget->m_solarSystemListWidget->item( 1 )->setCheckState( state );
ui_configWidget->m_viewSolarSystemLabelCheckbox->setChecked(m_viewSolarSystemLabel);
}
emit settingsChanged( nameId() );
requestRepaint();
}
void StarsPlugin::toggleDsos(bool on)
{
m_renderDsos = on;
// only enable lables if set to true
if (on) {
m_renderDsoLabels = true;
}
const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked;
if ( m_configDialog ) {
ui_configWidget->m_viewDsosCheckbox->setChecked(state);
ui_configWidget->m_viewDsoLabelCheckbox->setChecked(state);
}
emit settingsChanged( nameId() );
requestRepaint();
}
void StarsPlugin::toggleConstellations(bool on)
{
m_renderConstellationLines = on;
m_renderConstellationLabels = on;
const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked;
if ( m_configDialog ) {
ui_configWidget->m_viewConstellationLinesCheckbox->setChecked( state );
ui_configWidget->m_viewConstellationLabelsCheckbox->setChecked( state );
}
emit settingsChanged( nameId() );
requestRepaint();
}
void StarsPlugin::togglePlanets(bool on)
{
m_renderPlanet["venus"] = on;
m_renderPlanet["mars"] = on;
m_renderPlanet["jupiter"] = on;
m_renderPlanet["mercury"] = on;
m_renderPlanet["saturn"] = on;
m_renderPlanet["uranus"] = on;
m_renderPlanet["neptune"] = on;
const Qt::CheckState state = on ? Qt::Checked : Qt::Unchecked;
if ( m_configDialog ) {
// Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune
ui_configWidget->m_solarSystemListWidget->item(2)->setCheckState(state);
ui_configWidget->m_solarSystemListWidget->item(3)->setCheckState(state);
ui_configWidget->m_solarSystemListWidget->item(5)->setCheckState(state);
ui_configWidget->m_solarSystemListWidget->item(6)->setCheckState(state);
ui_configWidget->m_solarSystemListWidget->item(7)->setCheckState(state);
ui_configWidget->m_solarSystemListWidget->item(8)->setCheckState(state);
ui_configWidget->m_solarSystemListWidget->item(9)->setCheckState(state);
}
emit settingsChanged( nameId() );
requestRepaint();
}
void StarsPlugin::executeConfigDialog()
{
QDialog *dialog = configDialog();
Q_ASSERT( dialog );
dialog->exec();
}
bool StarsPlugin::eventFilter( QObject *object, QEvent *e )
{
if ( !enabled() || !visible() ) {
return false;
}
if( e->type() == QEvent::ContextMenu )
{
MarbleWidget *widget = dynamic_cast<MarbleWidget *>( object );
QContextMenuEvent *menuEvent = dynamic_cast<QContextMenuEvent *> ( e );
if( widget && menuEvent )
{
qreal mouseLon, mouseLat;
const bool aboveMap = widget->geoCoordinates( menuEvent->x(), menuEvent->y(),
mouseLon, mouseLat, GeoDataCoordinates::Radian );
if ( aboveMap ) {
return false;
}
for ( AbstractFloatItem *floatItem: widget->floatItems() ) {
if ( floatItem->enabled() && floatItem->visible()
&& floatItem->contains( menuEvent->pos() ) )
{
return false;
}
}
if (!m_contextMenu) {
m_contextMenu = new QMenu;
m_constellationsAction = m_contextMenu->addAction(tr("Show &Constellations"),
this, SLOT(toggleConstellations(bool)));
m_constellationsAction->setCheckable(true);
m_sunMoonAction = m_contextMenu->addAction(tr("Show &Sun and Moon"),
this, SLOT(toggleSunMoon(bool)));
m_sunMoonAction->setCheckable(true);
m_planetsAction = m_contextMenu->addAction(tr("Show &Planets"),
this, SLOT(togglePlanets(bool)));
m_planetsAction->setCheckable(true);
m_dsoAction = m_contextMenu->addAction(tr("Show &Deep Sky Objects"),
this, SLOT(toggleDsos(bool)) );
m_dsoAction->setCheckable(true);
m_contextMenu->addSeparator();
m_contextMenu->addAction(tr("&Configure..."),
this, SLOT(executeConfigDialog()));
}
// update action states
m_constellationsAction->setChecked(m_renderConstellationLines || m_renderConstellationLabels);
m_sunMoonAction->setChecked(m_renderSun || m_renderMoon);
m_dsoAction->setChecked(m_renderDsos);
const bool isAnyPlanetRendered =
m_renderPlanet["venus"] || m_renderPlanet["mars"] ||
m_renderPlanet["jupiter"] || m_renderPlanet["mercury"] ||
m_renderPlanet["saturn"] || m_renderPlanet["uranus"] ||
m_renderPlanet["neptune"];
m_planetsAction->setChecked(isAnyPlanetRendered);
m_contextMenu->exec(widget->mapToGlobal(menuEvent->pos()));
return true;
}
return false;
} else {
return RenderPlugin::eventFilter( object, e );
}
}
}
#include "moc_StarsPlugin.cpp"
diff --git a/src/plugins/render/stars/StarsPlugin.h b/src/plugins/render/stars/StarsPlugin.h
index b2ea6c5db..e2fe0bc75 100644
--- a/src/plugins/render/stars/StarsPlugin.h
+++ b/src/plugins/render/stars/StarsPlugin.h
@@ -1,324 +1,324 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
//
//
// This class is a stars plugin.
//
#ifndef MARBLESTARSPLUGIN_H
#define MARBLESTARSPLUGIN_H
#include <QVector>
#include <QHash>
#include <QMap>
#include <QVariant>
#include <QBrush>
#include "RenderPlugin.h"
#include "Quaternion.h"
#include "DialogConfigurationInterface.h"
class QMenu;
class QVariant;
class SolarSystem;
namespace Ui
{
class StarsConfigWidget;
}
namespace Marble
{
class StarPoint
{
public:
StarPoint() {}
/**
* @brief create a starpoint from rectaszension and declination
* @param rect rectaszension
* @param lat declination
* @param mag magnitude
* (default for Radian: north pole at pi/2, southpole at -pi/2)
*/
StarPoint(int id, qreal rect, qreal decl, qreal mag, int colorId) :
m_id( id ),
m_magnitude( mag ),
m_colorId( colorId )
{
m_q = Quaternion::fromSpherical( rect, decl );
}
~StarPoint() {}
qreal magnitude() const
{
return m_magnitude;
}
const Quaternion &quaternion() const
{
return m_q;
}
int id() const
{
return m_id;
}
int colorId() const
{
return m_colorId;
}
private:
int m_id;
qreal m_magnitude;
Quaternion m_q;
int m_colorId;
};
class DsoPoint
{
public:
DsoPoint() {}
/**
* @brief create a dsopoint from rectaszension and declination
* @param rect rectaszension
* @param lat declination
* @param mag
* (default for Radian: north pole at pi/2, southpole at -pi/2)
*/
DsoPoint(const QString& id, qreal rect, qreal decl) {
m_id = id;
m_q = Quaternion::fromSpherical( rect, decl );
}
QString id() const
{
return m_id;
}
const Quaternion &quaternion() const
{
return m_q;
}
private:
QString m_id;
Quaternion m_q;
};
/**
* @short The class that specifies the Marble layer interface of a plugin.
*
*/
class Constellation;
class StarsPlugin : public RenderPlugin, public DialogConfigurationInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.StarsPlugin")
Q_INTERFACES(Marble::RenderPluginInterface)
Q_INTERFACES( Marble::DialogConfigurationInterface )
MARBLE_PLUGIN(StarsPlugin)
public:
- explicit StarsPlugin( const MarbleModel *marbleModel=0 );
+ explicit StarsPlugin( const MarbleModel *marbleModel=nullptr );
~StarsPlugin() override;
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
RenderType renderType() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon() const override;
void initialize() override;
bool isInitialized() const override;
- bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
QDialog *configDialog() override;
QHash<QString,QVariant> settings() const override;
void setSettings( const QHash<QString,QVariant> &settings ) override;
QString assembledConstellation(const QString &name);
protected:
bool eventFilter( QObject *object, QEvent *e ) override;
private Q_SLOTS:
void requestRepaint();
void toggleSunMoon(bool on);
void togglePlanets(bool on);
void toggleDsos(bool on);
void toggleConstellations(bool on);
void executeConfigDialog();
public Q_SLOTS:
void readSettings();
void writeSettings();
void constellationGetColor();
void constellationLabelGetColor();
void dsoLabelGetColor();
void eclipticGetColor();
void celestialEquatorGetColor();
void celestialPoleGetColor();
private:
template<class T>
T readSetting( const QHash<QString, QVariant> &settings, const QString &key, const T &defaultValue )
{
if ( !settings.contains( key ) ) {
return defaultValue;
}
return settings[key].value<T>();
}
QPixmap starPixmap(qreal mag, int colorId) const;
void prepareNames();
QHash<QString, QString> m_abbrHash;
QHash<QString, QString> m_nativeHash;
int m_nameIndex;
void renderPlanet(const QString &planetId,
GeoPainter *painter,
SolarSystem &sys,
ViewportParams *viewport,
qreal skyRadius,
matrix &skyAxisMatrix) const;
void createStarPixmaps();
void loadStars();
void loadConstellations();
void loadDsos();
QPointer<QDialog> m_configDialog;
Ui::StarsConfigWidget *ui_configWidget;
bool m_renderStars;
bool m_renderConstellationLines;
bool m_renderConstellationLabels;
bool m_renderDsos;
bool m_renderDsoLabels;
bool m_renderSun;
bool m_renderMoon;
QMap<QString, bool> m_renderPlanet;
bool m_renderEcliptic;
bool m_renderCelestialEquator;
bool m_renderCelestialPole;
bool m_starsLoaded;
bool m_starPixmapsCreated;
bool m_constellationsLoaded;
bool m_dsosLoaded;
bool m_zoomSunMoon;
bool m_viewSolarSystemLabel;
QVector<StarPoint> m_stars;
QPixmap m_pixmapSun;
QPixmap m_pixmapMoon;
QVector<Constellation> m_constellations;
QVector<DsoPoint> m_dsos;
QHash<int,int> m_idHash;
QImage m_dsoImage;
int m_magnitudeLimit;
int m_zoomCoefficient;
QBrush m_constellationBrush;
QBrush m_constellationLabelBrush;
QBrush m_dsoLabelBrush;
QBrush m_eclipticBrush;
QBrush m_celestialEquatorBrush;
QBrush m_celestialPoleBrush;
QVector<QPixmap> m_pixN1Stars;
QVector<QPixmap> m_pixP0Stars;
QVector<QPixmap> m_pixP1Stars;
QVector<QPixmap> m_pixP2Stars;
QVector<QPixmap> m_pixP3Stars;
QVector<QPixmap> m_pixP4Stars;
QVector<QPixmap> m_pixP5Stars;
QVector<QPixmap> m_pixP6Stars;
QVector<QPixmap> m_pixP7Stars;
/* Context menu */
QPointer<QMenu> m_contextMenu;
QAction* m_constellationsAction;
QAction* m_sunMoonAction;
QAction* m_planetsAction;
QAction* m_dsoAction;
bool m_doRender;
};
class Constellation
{
public:
Constellation() {}
Constellation(StarsPlugin *plugin, const QString &name, const QString &stars) :
m_plugin( plugin ),
m_name( name )
{
const QStringList starlist = stars.split(QLatin1Char(' '));
for (int i = 0; i < starlist.size(); ++i) {
m_stars << starlist.at(i).toInt();
}
}
int size() const
{
return m_stars.size();
}
int at(const int index) const
{
if (index < 0) {
return -1;
}
if (index >= m_stars.size()) {
return -1;
}
return m_stars.at(index);
}
QString name() const
{
return m_plugin->assembledConstellation(m_name);
}
private:
StarsPlugin *m_plugin;
QString m_name;
QVector<int> m_stars;
};
}
#endif // MARBLESTARSPLUGIN_H
diff --git a/src/plugins/render/sun/SunPlugin.cpp b/src/plugins/render/sun/SunPlugin.cpp
index 8f103250d..199f6490c 100644
--- a/src/plugins/render/sun/SunPlugin.cpp
+++ b/src/plugins/render/sun/SunPlugin.cpp
@@ -1,125 +1,125 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "SunPlugin.h"
#include "GeoDataCoordinates.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "GeoPainter.h"
#include "SunLocator.h"
#include <QIcon>
namespace Marble
{
SunPlugin::SunPlugin()
- : RenderPlugin( 0 )
+ : RenderPlugin( nullptr )
{
}
SunPlugin::SunPlugin( const MarbleModel *marbleModel )
: RenderPlugin( marbleModel )
{
setVisible( false );
}
QStringList SunPlugin::backendTypes() const
{
return QStringList(QStringLiteral("stars"));
}
QString SunPlugin::renderPolicy() const
{
return QStringLiteral("SPECIFIED_ALWAYS");
}
QStringList SunPlugin::renderPosition() const
{
return QStringList(QStringLiteral("ALWAYS_ON_TOP"));
}
QString SunPlugin::name() const
{
return tr( "Sun" );
}
QString SunPlugin::guiString() const
{
return tr( "Sun" );
}
QString SunPlugin::nameId() const
{
return QStringLiteral("sun");
}
QString SunPlugin::version() const
{
return QStringLiteral("1.0");
}
QString SunPlugin::description() const
{
return tr( "A plugin that shows the Sun." );
}
QString SunPlugin::copyrightYears() const
{
return QStringLiteral("2011");
}
QVector<PluginAuthor> SunPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"))
<< PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"))
<< PluginAuthor(QStringLiteral("Harshit Jain"), QStringLiteral("hjain.itbhu@gmail.com"));
}
QIcon SunPlugin::icon () const
{
return QIcon(MarbleDirs::path(QStringLiteral("svg/sunshine.png")));
}
void SunPlugin::initialize ()
{
m_pixmap = QPixmap(MarbleDirs::path(QStringLiteral("svg/sunshine.png"))).scaled(QSize(22,22));
}
bool SunPlugin::isInitialized () const
{
return !m_pixmap.isNull();
}
bool SunPlugin::render( GeoPainter *painter, ViewportParams *viewport,
const QString& renderPos, GeoSceneLayer * layer )
{
Q_UNUSED( viewport )
Q_UNUSED( renderPos )
Q_UNUSED( layer )
if( visible() )
{
const qreal lon = marbleModel()->sunLocator()->getLon();
const qreal lat = marbleModel()->sunLocator()->getLat();
const GeoDataCoordinates coordinates( lon, lat, 0, GeoDataCoordinates::Degree );
painter->drawPixmap( coordinates, m_pixmap );
}
return true;
}
}
#include "moc_SunPlugin.cpp"
diff --git a/src/plugins/render/sun/SunPlugin.h b/src/plugins/render/sun/SunPlugin.h
index 5eaef45ca..fd8409be1 100644
--- a/src/plugins/render/sun/SunPlugin.h
+++ b/src/plugins/render/sun/SunPlugin.h
@@ -1,72 +1,72 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Torsten Rahn <tackat@kde.org>
// Copyright 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLESUNPLUGIN_H
#define MARBLESUNPLUGIN_H
#include "RenderPlugin.h"
#include <QPixmap>
namespace Marble
{
/**
* @short The class that specifies the Marble layer interface of a plugin.
*
*/
class SunPlugin : public RenderPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.SunPlugin")
Q_INTERFACES( Marble::RenderPluginInterface )
MARBLE_PLUGIN( SunPlugin )
public:
SunPlugin();
explicit SunPlugin( const MarbleModel *marbleModel );
QStringList backendTypes() const override;
QString renderPolicy() const override;
QStringList renderPosition() const override;
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QIcon icon () const override;
void initialize () override;
bool isInitialized () const override;
- bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = 0 ) override;
+ bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer = nullptr ) override;
private:
QPixmap m_pixmap;
};
}
#endif // MARBLESUNPLUGIN_H
diff --git a/src/plugins/render/weather/AbstractWeatherService.cpp b/src/plugins/render/weather/AbstractWeatherService.cpp
index 01bac1324..b78872205 100644
--- a/src/plugins/render/weather/AbstractWeatherService.cpp
+++ b/src/plugins/render/weather/AbstractWeatherService.cpp
@@ -1,63 +1,63 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "AbstractWeatherService.h"
namespace Marble
{
AbstractWeatherService::AbstractWeatherService( const MarbleModel *model, QObject *parent )
: QObject( parent ),
m_marbleModel( model ),
- m_marbleWidget( 0 )
+ m_marbleWidget( nullptr )
{
- Q_ASSERT( m_marbleModel != 0 );
+ Q_ASSERT( m_marbleModel != nullptr );
}
AbstractWeatherService::~AbstractWeatherService()
{
}
void AbstractWeatherService::setMarbleWidget( MarbleWidget *widget )
{
m_marbleWidget = widget;
}
const MarbleModel* AbstractWeatherService::marbleModel() const
{
return m_marbleModel;
}
MarbleWidget* AbstractWeatherService::marbleWidget()
{
return m_marbleWidget;
}
void AbstractWeatherService::setFavoriteItems( const QStringList& favorite )
{
if ( m_favoriteItems != favorite) {
m_favoriteItems = favorite;
}
}
QStringList AbstractWeatherService::favoriteItems() const
{
return m_favoriteItems;
}
void AbstractWeatherService::parseFile( const QByteArray& file )
{
Q_UNUSED( file );
}
} // namespace Marble
#include "moc_AbstractWeatherService.cpp"
diff --git a/src/plugins/render/weather/BBCItemGetter.h b/src/plugins/render/weather/BBCItemGetter.h
index d2a0054b4..1624b8e17 100644
--- a/src/plugins/render/weather/BBCItemGetter.h
+++ b/src/plugins/render/weather/BBCItemGetter.h
@@ -1,59 +1,59 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef BBCITEMGETTER_H
#define BBCITEMGETTER_H
// Marble
#include "AbstractWorkerThread.h"
#include "GeoDataLatLonBox.h"
// Qt
#include <QList>
#include <QMutex>
#include <QThread>
namespace Marble
{
class BBCStation;
class BBCItemGetter : public AbstractWorkerThread
{
Q_OBJECT
public:
- explicit BBCItemGetter( QObject *parent = 0 );
+ explicit BBCItemGetter( QObject *parent = nullptr );
~BBCItemGetter() override;
void setSchedule( const GeoDataLatLonBox& box,
qint32 number );
void setStationList( const QList<BBCStation>& items );
BBCStation station( const QString &id );
protected:
bool workAvailable() override;
void work() override;
Q_SIGNALS:
void foundStation( const BBCStation& );
public:
QList<BBCStation> m_items;
QMutex m_scheduleMutex;
GeoDataLatLonBox m_scheduledBox;
qint32 m_scheduledNumber;
};
} // namespace Marble
#endif // BBCITEMGETTER_H
diff --git a/src/plugins/render/weather/BBCParser.h b/src/plugins/render/weather/BBCParser.h
index 212618e8f..f1fe5f477 100644
--- a/src/plugins/render/weather/BBCParser.h
+++ b/src/plugins/render/weather/BBCParser.h
@@ -1,82 +1,82 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef BBCPARSER_H
#define BBCPARSER_H
// Marble
#include "AbstractWorkerThread.h"
#include "WeatherData.h"
// Qt
#include <QHash>
#include <QList>
#include <QMutex>
#include <QPointer>
#include <QStack>
#include <QXmlStreamReader>
class QObject;
namespace Marble
{
class BBCWeatherItem;
struct ScheduleEntry
{
QString path;
QPointer<BBCWeatherItem> item;
QString type;
};
class BBCParser : public AbstractWorkerThread, public QXmlStreamReader
{
Q_OBJECT
public:
~BBCParser() override;
static BBCParser *instance();
void scheduleRead( const QString& path, BBCWeatherItem *item, const QString& type );
protected:
bool workAvailable() override;
void work() override;
Q_SIGNALS:
void parsedFile();
private:
- explicit BBCParser( QObject *parent = 0 );
+ explicit BBCParser( QObject *parent = nullptr );
QList<WeatherData> read( QIODevice *device );
void readUnknownElement();
void readBBC();
void readChannel();
void readItem();
void readDescription( WeatherData *data );
void readTitle( WeatherData *data );
void readPubDate( WeatherData *data );
QList<WeatherData> m_list;
QStack<ScheduleEntry> m_schedule;
QMutex m_scheduleMutex;
QHash<QString, WeatherData::WeatherCondition> m_dayConditions;
QHash<QString, WeatherData::WeatherCondition> m_nightConditions;
QHash<QString, WeatherData::WindDirection> m_windDirections;
QHash<QString, WeatherData::PressureDevelopment> m_pressureDevelopments;
QHash<QString, WeatherData::Visibility> m_visibilityStates;
QHash<QString, int> m_monthNames;
};
} // Marble namespace
#endif // BBCPARSER_H
diff --git a/src/plugins/render/weather/BBCWeatherItem.h b/src/plugins/render/weather/BBCWeatherItem.h
index f8c970fd2..49974b339 100644
--- a/src/plugins/render/weather/BBCWeatherItem.h
+++ b/src/plugins/render/weather/BBCWeatherItem.h
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef BBCWEATHERITEM_H
#define BBCWEATHERITEM_H
#include "WeatherItem.h"
class QString;
class QUrl;
namespace Marble
{
class BBCWeatherItem : public WeatherItem
{
Q_OBJECT
public:
- explicit BBCWeatherItem( QObject *parent = 0 );
+ explicit BBCWeatherItem( QObject *parent = nullptr );
~BBCWeatherItem() override;
bool request( const QString& type ) override;
QString service() const override;
void addDownloadedFile( const QString& url, const QString& type ) override;
QUrl observationUrl() const;
QUrl forecastUrl() const;
quint32 bbcId() const;
void setBbcId( quint32 id );
QString creditHtml() const;
private:
quint32 m_bbcId;
bool m_observationRequested;
bool m_forecastRequested;
};
} // namespace Marble
#endif // BBCWEATHERITEM_H
diff --git a/src/plugins/render/weather/BBCWeatherService.cpp b/src/plugins/render/weather/BBCWeatherService.cpp
index 4b06bdfa5..d9401da3b 100644
--- a/src/plugins/render/weather/BBCWeatherService.cpp
+++ b/src/plugins/render/weather/BBCWeatherService.cpp
@@ -1,116 +1,116 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "BBCWeatherService.h"
// Marble
#include "BBCItemGetter.h"
#include "BBCStation.h"
#include "BBCWeatherItem.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLatLonAltBox.h"
#include "MarbleDirs.h"
#include "StationListParser.h"
#include "WeatherData.h"
#include "WeatherModel.h"
#include "MarbleDebug.h"
#include "MarbleGlobal.h"
// Qt
#include <QUrl>
using namespace Marble;
BBCWeatherService::BBCWeatherService( const MarbleModel *model, QObject *parent )
: AbstractWeatherService( model, parent ),
m_parsingStarted( false ),
- m_parser( 0 ),
+ m_parser( nullptr ),
m_itemGetter( new BBCItemGetter( this ) )
{
qRegisterMetaType<BBCStation>("BBCStation");
}
BBCWeatherService::~BBCWeatherService()
{
}
void BBCWeatherService::setFavoriteItems( const QStringList& favorite )
{
if ( favoriteItems() != favorite ) {
m_parsingStarted = false;
delete m_itemGetter;
m_itemGetter = new BBCItemGetter( this );
AbstractWeatherService::setFavoriteItems( favorite );
}
}
void BBCWeatherService::getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number )
{
if ( !m_parsingStarted ) {
m_parsingStarted = true;
m_parser = new StationListParser( this );
m_parser->setPath(MarbleDirs::path(QStringLiteral("weather/bbc-stations.xml")));
connect( m_parser, SIGNAL(finished()),
this, SLOT(fetchStationList()) );
if ( m_parser->wait( 100 ) ) {
m_parser->start( QThread::IdlePriority );
}
}
m_itemGetter->setSchedule( box, number );
}
void BBCWeatherService::getItem( const QString &id )
{
if ( id.startsWith( QLatin1String( "bbc" ) ) ) {
BBCStation const station = m_itemGetter->station( id );
if ( station.bbcId() > 0 ) {
createItem( station );
}
}
}
void BBCWeatherService::fetchStationList()
{
if ( !m_parser ) {
return;
}
connect( m_itemGetter,
SIGNAL(foundStation(BBCStation)),
this,
SLOT(createItem(BBCStation)) );
m_stationList = m_parser->stationList();
m_itemGetter->setStationList( m_stationList );
delete m_parser;
- m_parser = 0;
+ m_parser = nullptr;
}
void BBCWeatherService::createItem( const BBCStation& station )
{
BBCWeatherItem *item = new BBCWeatherItem( this );
item->setMarbleWidget( marbleWidget() );
item->setBbcId( station.bbcId() );
item->setCoordinate( station.coordinate() );
item->setPriority( station.priority() );
item->setStationName( station.name() );
emit requestedDownload( item->observationUrl(), "bbcobservation", item );
emit requestedDownload( item->forecastUrl(), "bbcforecast", item );
}
#include "moc_BBCWeatherService.cpp"
diff --git a/src/plugins/render/weather/FakeWeatherItem.h b/src/plugins/render/weather/FakeWeatherItem.h
index 92b9b4f8c..0651c2815 100644
--- a/src/plugins/render/weather/FakeWeatherItem.h
+++ b/src/plugins/render/weather/FakeWeatherItem.h
@@ -1,33 +1,33 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef FAKEWEATHERITEM_H
#define FAKEWEATHERITEM_H
#include "WeatherItem.h"
class QString;
namespace Marble
{
class FakeWeatherItem : public WeatherItem
{
public:
- explicit FakeWeatherItem( QObject *parent = 0 );
+ explicit FakeWeatherItem( QObject *parent = nullptr );
~FakeWeatherItem() override;
QString service() const override;
void addDownloadedFile( const QString& url, const QString& type ) override;
};
} // namespace Marble
#endif // FAKEWEATHERITEM_H
diff --git a/src/plugins/render/weather/GeoNamesWeatherItem.h b/src/plugins/render/weather/GeoNamesWeatherItem.h
index bd088ba26..9872664f6 100644
--- a/src/plugins/render/weather/GeoNamesWeatherItem.h
+++ b/src/plugins/render/weather/GeoNamesWeatherItem.h
@@ -1,35 +1,35 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Valery Kharitonov <kharvd@gmail.com>
//
#ifndef GEONAMESWEATHERITEM_H
#define GEONAMESWEATHERITEM_H
#include "WeatherItem.h"
namespace Marble
{
class GeoNamesWeatherItem : public WeatherItem
{
Q_OBJECT
public:
- explicit GeoNamesWeatherItem( QObject *parent = 0 );
+ explicit GeoNamesWeatherItem( QObject *parent = nullptr );
~GeoNamesWeatherItem() override;
void addDownloadedFile( const QString& url, const QString& type ) override;
QString service() const override;
QString creditHtml() const;
};
} // namespace Marble
#endif // GEONAMESWEATHERITEM_H
diff --git a/src/plugins/render/weather/GeoNamesWeatherService.cpp b/src/plugins/render/weather/GeoNamesWeatherService.cpp
index e806473ec..7365dc5a3 100644
--- a/src/plugins/render/weather/GeoNamesWeatherService.cpp
+++ b/src/plugins/render/weather/GeoNamesWeatherService.cpp
@@ -1,270 +1,270 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Valery Kharitonov <kharvd@gmail.com>
//
#include "GeoNamesWeatherService.h"
#include "WeatherData.h"
#include "GeoNamesWeatherItem.h"
#include "GeoDataLatLonAltBox.h"
#include "MarbleModel.h"
#include "MarbleDebug.h"
#include <QUrl>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QUrlQuery>
using namespace Marble;
QHash<QString, WeatherData::WeatherCondition> GeoNamesWeatherService::dayConditions
= QHash<QString, WeatherData::WeatherCondition>();
QVector<WeatherData::WindDirection> GeoNamesWeatherService::windDirections
= QVector<WeatherData::WindDirection>(16);
GeoNamesWeatherService::GeoNamesWeatherService( const MarbleModel *model, QObject *parent ) :
AbstractWeatherService( model, parent )
{
GeoNamesWeatherService::setupHashes();
}
GeoNamesWeatherService::~GeoNamesWeatherService()
{
}
void GeoNamesWeatherService::getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number )
{
if (marbleModel()->planetId() != QLatin1String("earth")) {
return;
}
QUrl geonamesUrl( "http://ws.geonames.org/weatherJSON" );
QUrlQuery urlQuery;
urlQuery.addQueryItem( "north", QString::number( box.north( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "south", QString::number( box.south( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "east", QString::number( box.east( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "west", QString::number( box.west( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "maxRows", QString::number( number ) );
urlQuery.addQueryItem( "username", "marble" );
geonamesUrl.setQuery( urlQuery );
emit downloadDescriptionFileRequested( geonamesUrl );
}
void GeoNamesWeatherService::getItem( const QString &id )
{
if (marbleModel()->planetId() != QLatin1String("earth")) {
return;
}
if ( id.startsWith(QLatin1String("geonames_") ) ) {
QUrl geonamesUrl( "http://ws.geonames.org/weatherIcaoJSON" );
QUrlQuery urlQuery;
urlQuery.addQueryItem( "ICAO", id.mid( 9 ) );
urlQuery.addQueryItem( "username", "marble" );
geonamesUrl.setQuery( urlQuery );
emit downloadDescriptionFileRequested( geonamesUrl );
}
}
void GeoNamesWeatherService::parseFile( const QByteArray& file )
{
QJsonDocument jsonDoc = QJsonDocument::fromJson(file);
QJsonValue weatherObservationsValue = jsonDoc.object().value(QStringLiteral("weatherObservations"));
// Parse if any result exists
QList<AbstractDataPluginItem*> items;
if (weatherObservationsValue.isArray()) {
// Add items to the list
QJsonArray weatherObservationsArray = weatherObservationsValue.toArray();
for (int index = 0; index < weatherObservationsArray.size(); ++index) {
QJsonObject weatherObservationObject = weatherObservationsArray[index].toObject();
AbstractDataPluginItem* item = parse(weatherObservationObject);
if ( item ) {
items << item;
}
}
} else {
QJsonValue weatherObservationValue = jsonDoc.object().value(QStringLiteral("weatherObservation"));
QJsonObject weatherObservationObject = weatherObservationValue.toObject();
AbstractDataPluginItem* item = parse(weatherObservationObject);
if ( item ) {
items << item;
}
}
emit createdItems( items );
}
AbstractDataPluginItem *GeoNamesWeatherService::parse(const QJsonObject &weatherObservationObject)
{
const QString condition = weatherObservationObject.value(QStringLiteral("weatherCondition")).toString();
const QString clouds = weatherObservationObject.value(QStringLiteral("clouds")).toString();
const int windDirection = weatherObservationObject.value(QStringLiteral("windDirection")).toInt();
QString id = weatherObservationObject.value(QStringLiteral("ICAO")).toString();
const double temperature = weatherObservationObject.value(QStringLiteral("temperature")).toString().toDouble(); //delivered as string
const int windSpeed = weatherObservationObject.value(QStringLiteral("windSpeed")).toString().toInt(); //delivered as string
const int humidity = weatherObservationObject.value(QStringLiteral("humidity")).toInt();
const double pressure = weatherObservationObject.value(QStringLiteral("seaLevelPressure")).toDouble();
const QString name = weatherObservationObject.value(QStringLiteral("stationName")).toString();
const QDateTime date = QDateTime::fromString(
weatherObservationObject.value(QStringLiteral("datetime")).toString(), "yyyy-MM-dd hh:mm:ss" );
const double longitude = weatherObservationObject.value(QStringLiteral("lng")).toDouble();
const double latitude = weatherObservationObject.value(QStringLiteral("lat")).toDouble();
if ( !id.isEmpty() ) {
WeatherData data;
// Weather condition
if (clouds != QLatin1String("n/a") && condition != QLatin1String("n/a")) {
if ( dayConditions.contains( condition ) ) {
data.setCondition( dayConditions[condition] );
} else {
mDebug() << "UNHANDLED GEONAMES WEATHER CONDITION, PLEASE REPORT: " << condition;
}
} else {
if ( dayConditions.contains( clouds ) ) {
data.setCondition( dayConditions[clouds] );
} else {
mDebug() << "UNHANDLED GEONAMES CLOUDS CONDITION, PLEASE REPORT: " << clouds;
}
}
// Wind direction. Finds the closest direction from windDirections array.
if ( windDirection >= 0 ) {
double tickSpacing = 360.0 / windDirections.size();
data.setWindDirection( windDirections[int(( windDirection / tickSpacing ) + 0.5)
% windDirections.size()] );
}
// Wind speed
if ( windSpeed != 0 ) {
data.setWindSpeed( windSpeed, WeatherData::knots );
}
// Temperature
data.setTemperature( temperature, WeatherData::Celsius );
// Humidity
data.setHumidity( humidity );
// Pressure
if ( pressure != 0.0 ) {
data.setPressure( pressure, WeatherData::HectoPascal );
}
// Date
data.setDataDate( date.date() );
data.setPublishingTime( date );
// ID
id = QLatin1String("geonames_") + id;
GeoDataCoordinates coordinates( longitude, latitude, 0.0, GeoDataCoordinates::Degree );
GeoNamesWeatherItem *item = new GeoNamesWeatherItem( this );
item->setMarbleWidget( marbleWidget() );
item->setId( id );
item->setCoordinate( coordinates );
item->setPriority( 0 );
item->setStationName( name );
item->setCurrentWeather( data );
return item;
} else {
- return 0;
+ return nullptr;
}
}
void GeoNamesWeatherService::setupHashes()
{
if( !( ( dayConditions.isEmpty() )
|| ( windDirections.isEmpty() ) ) )
{
return;
}
dayConditions["sunny"] = WeatherData::ClearDay;
dayConditions["clear"] = WeatherData::ClearDay;
dayConditions["clear sky"] = WeatherData::ClearDay;
dayConditions["sunny intervals"] = WeatherData::FewCloudsDay;
dayConditions["few clouds"] = WeatherData::FewCloudsDay;
dayConditions["scattered clouds"] = WeatherData::FewCloudsDay;
dayConditions["partly cloudy"] = WeatherData::PartlyCloudyDay;
dayConditions["broken clouds"] = WeatherData::PartlyCloudyDay;
dayConditions["white cloud"] = WeatherData::Overcast;
dayConditions["overcast"] = WeatherData::Overcast;
dayConditions["grey cloud"] = WeatherData::Overcast;
dayConditions["cloudy"] = WeatherData::Overcast;
dayConditions["drizzle"] = WeatherData::LightRain;
dayConditions["light drizzle"] = WeatherData::LightRain;
dayConditions["misty"] = WeatherData::Mist;
dayConditions["mist"] = WeatherData::Mist;
dayConditions["fog"] = WeatherData::Mist;
dayConditions["foggy"] = WeatherData::Mist;
dayConditions["dense fog"] = WeatherData::Mist;
dayConditions["Thick Fog"] = WeatherData::Mist;
dayConditions["tropical storm"] = WeatherData::Thunderstorm;
dayConditions["thunderstorm"] = WeatherData::Thunderstorm;
dayConditions["hazy"] = WeatherData::Mist;
dayConditions["haze"] = WeatherData::Mist;
dayConditions["in vicinity: showers "] = WeatherData::ShowersDay;
dayConditions["light shower"] = WeatherData::LightShowersDay;
dayConditions["light rain shower"] = WeatherData::LightShowersDay;
dayConditions["light showers"] = WeatherData::LightShowersDay;
dayConditions["light rain"] = WeatherData::ShowersDay;
dayConditions["heavy rain"] = WeatherData::Rain;
dayConditions["heavy showers"] = WeatherData::Rain;
dayConditions["heavy shower"] = WeatherData::Rain;
dayConditions["heavy rain shower"] = WeatherData::Rain;
dayConditions["thundery shower"] = WeatherData::Thunderstorm;
dayConditions["thunderstorm"] = WeatherData::Thunderstorm;
dayConditions["thunder storm"] = WeatherData::Thunderstorm;
dayConditions["cloudy with sleet"] = WeatherData::RainSnow;
dayConditions["sleet shower"] = WeatherData::RainSnow;
dayConditions["sleet showers"] = WeatherData::RainSnow;
dayConditions["sleet"] = WeatherData::RainSnow;
dayConditions["cloudy with hail"] = WeatherData::Hail;
dayConditions["hail shower"] = WeatherData::Hail;
dayConditions["hail showers"] = WeatherData::Hail;
dayConditions["hail"] = WeatherData::Hail;
dayConditions["light snow"] = WeatherData::LightSnow;
dayConditions["light snow shower"] = WeatherData::ChanceSnowDay;
dayConditions["light snow showers"] = WeatherData::ChanceSnowDay;
dayConditions["cloudy with light snow"] = WeatherData::LightSnow;
dayConditions["heavy snow"] = WeatherData::Snow;
dayConditions["heavy snow shower"] = WeatherData::Snow;
dayConditions["heavy snow showers"] = WeatherData::Snow;
dayConditions["cloudy with heavy snow"] = WeatherData::Snow;
dayConditions["sandstorm"] = WeatherData::SandStorm;
dayConditions["na"] = WeatherData::ConditionNotAvailable;
dayConditions["n/a"] = WeatherData::ConditionNotAvailable;
windDirections[0] = WeatherData::N;
windDirections[1] = WeatherData::NNE;
windDirections[2] = WeatherData::NE;
windDirections[3] = WeatherData::ENE;
windDirections[4] = WeatherData::E;
windDirections[5] = WeatherData::ESE;
windDirections[6] = WeatherData::SE;
windDirections[7] = WeatherData::SSE;
windDirections[8] = WeatherData::S;
windDirections[9] = WeatherData::SSW;
windDirections[10] = WeatherData::SW;
windDirections[11] = WeatherData::WSW;
windDirections[12] = WeatherData::W;
windDirections[13] = WeatherData::WNW;
windDirections[14] = WeatherData::NW;
windDirections[15] = WeatherData::NNW;
}
#include "moc_GeoNamesWeatherService.cpp"
diff --git a/src/plugins/render/weather/WeatherItem.cpp b/src/plugins/render/weather/WeatherItem.cpp
index 0fa42eb10..fcc42915a 100644
--- a/src/plugins/render/weather/WeatherItem.cpp
+++ b/src/plugins/render/weather/WeatherItem.cpp
@@ -1,580 +1,580 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
// Self
#include "WeatherItem.h"
// Marble
#include "GeoPainter.h"
#include "MarbleDirs.h"
#include "WeatherData.h"
#include "weatherGlobal.h"
#include "FrameGraphicsItem.h"
#include "LabelGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "WidgetGraphicsItem.h"
#include "TinyWebBrowser.h"
#include "MarbleDebug.h"
#include "MarbleWidget.h"
#include "layers/PopupLayer.h"
// Qt
#include <QDate>
#include <QHash>
#include <QString>
#include <QAction>
#include <QIcon>
#include <QFont>
#include <QPushButton>
#include <QSvgRenderer>
namespace Marble
{
const QSize borderSpacing( 4, 4 );
const QSize imageSize( 28, 28 );
const double imageSizeRatio = ( (double) imageSize.width()) / ( (double) imageSize.height() );
class WeatherItemPrivate
{
Q_DECLARE_TR_FUNCTIONS(WeatherItemPrivate)
public:
WeatherItemPrivate( WeatherItem *parent )
- : m_marbleWidget( 0 ),
+ : m_marbleWidget( nullptr ),
m_priority( 0 ),
m_browserAction( tr( "Weather" ), parent ),
m_favoriteAction( parent ),
m_parent( parent ),
m_frameItem( m_parent ),
m_conditionLabel( &m_frameItem ),
m_temperatureLabel( &m_frameItem ),
m_windDirectionLabel( &m_frameItem ),
m_windSpeedLabel( &m_frameItem ),
m_favoriteButton( &m_frameItem )
{
// Setting minimum sizes
m_temperatureLabel.setMinimumSize( QSizeF( 0, imageSize.height() ) );
m_windSpeedLabel.setMinimumSize( QSizeF( 0, imageSize.height() ) );
QPushButton *button = new QPushButton();
button->setStyleSheet( "border-style: outset;" );
button->setIcon(QIcon(QStringLiteral(":/icons/bookmarks.png")));
button->setFixedSize( 22, 22 );
button->setFlat( true );
button->setCheckable( true );
m_favoriteButton.setWidget( button );
// Layouting the item
MarbleGraphicsGridLayout *topLayout = new MarbleGraphicsGridLayout( 1, 1 );
parent->setLayout( topLayout );
topLayout->addItem( &m_frameItem, 0, 0 );
MarbleGraphicsGridLayout *gridLayout = new MarbleGraphicsGridLayout( 2, 3 );
gridLayout->setAlignment( Qt::AlignCenter );
gridLayout->setSpacing( 4 );
m_frameItem.setLayout( gridLayout );
m_frameItem.setFrame( FrameGraphicsItem::RoundedRectFrame );
gridLayout->addItem( &m_conditionLabel, 0, 0 );
gridLayout->addItem( &m_temperatureLabel, 0, 1 );
gridLayout->setAlignment( &m_temperatureLabel, Qt::AlignRight | Qt::AlignVCenter );
gridLayout->addItem( &m_windDirectionLabel, 1, 0 );
gridLayout->addItem( &m_windSpeedLabel, 1, 1 );
gridLayout->setAlignment( &m_windSpeedLabel, Qt::AlignRight | Qt::AlignVCenter );
gridLayout->addItem( &m_favoriteButton, 0, 2 );
updateLabels();
}
~WeatherItemPrivate()
{
}
void updateToolTip()
{
QLocale locale = QLocale::system();
QString toolTip;
toolTip += tr( "Station: %1\n" ).arg( m_parent->stationName() );
if ( m_currentWeather.hasValidCondition() && m_currentWeather.hasValidTemperature() )
toolTip += QString( "%2, %3\n" ).arg( m_currentWeather.conditionString() )
.arg( temperatureString() );
else if ( m_currentWeather.hasValidCondition() )
toolTip += QString( "%2\n" ).arg( m_currentWeather.conditionString() );
else if ( m_currentWeather.hasValidTemperature() )
toolTip += QString( "%2\n" ).arg( temperatureString() );
if ( m_currentWeather.hasValidWindSpeed() && m_currentWeather.hasValidWindDirection() )
toolTip += tr( "Wind: %4, %5\n", "Wind: WindSpeed, WindDirection" )
.arg( windSpeedString( ) )
.arg( m_currentWeather.windDirectionString() );
else if ( m_currentWeather.hasValidWindSpeed() )
toolTip += tr( "Wind: %4\n", "Wind: WindSpeed" )
.arg( m_currentWeather.windSpeedString() );
else if ( m_currentWeather.hasValidWindDirection() )
toolTip += tr( "Wind: %4\n", "Wind: WindDirection" )
.arg( m_currentWeather.windDirectionString() );
if ( m_currentWeather.hasValidPressure() && m_currentWeather.hasValidPressureDevelopment() )
toolTip += tr( "Pressure: %6, %7", "Pressure: Pressure, Development" )
.arg( pressureString() )
.arg( m_currentWeather.pressureDevelopmentString() );
else if ( m_currentWeather.hasValidPressure() )
toolTip += tr( "Pressure: %6", "Pressure: Pressure" )
.arg( pressureString() );
else if ( m_currentWeather.hasValidPressureDevelopment() )
toolTip += tr( "Pressure %7", "Pressure Development" )
.arg( m_currentWeather.pressureDevelopmentString() );
if ( !m_forecastWeather.isEmpty() ) {
toolTip += QLatin1Char('\n');
QDate const minDate = QDate::currentDate();
for( const WeatherData& data: m_forecastWeather ) {
QDate date = data.dataDate();
if( date >= minDate
&& data.hasValidCondition()
&& data.hasValidMinTemperature()
&& data.hasValidMaxTemperature() )
{
toolTip += QLatin1Char('\n') +
tr( "%1: %2, %3 to %4", "DayOfWeek: Condition, MinTemp to MaxTemp" )
.arg( locale.standaloneDayName( date.dayOfWeek() ) )
.arg( data.conditionString() )
.arg( data.minTemperatureString( temperatureUnit() ) )
.arg( data.maxTemperatureString( temperatureUnit() ) );
}
}
}
m_parent->setToolTip( toolTip );
}
void updateLabels()
{
if ( isConditionShown() ) {
m_conditionLabel.setImage( m_currentWeather.icon(), imageSize );
}
else {
m_conditionLabel.clear();
}
if ( isTemperatureShown() ) {
m_temperatureLabel.setText( temperatureString() );
}
else {
m_temperatureLabel.clear();
}
if ( isWindDirectionShown() ) {
QString windDirectionString = m_currentWeather.windDirectionString();
QSizeF windDirectionImageSize;
QSvgRenderer s_windIcons(MarbleDirs::path(QStringLiteral("weather/wind-arrows.svgz")));
QSizeF windDirectionSizeF = s_windIcons.boundsOnElement( windDirectionString ).size();
double windDirectionRatio = windDirectionSizeF.width() / windDirectionSizeF.height();
if ( windDirectionRatio >= imageSizeRatio ) {
windDirectionImageSize.setWidth( imageSize.width() );
windDirectionImageSize.setHeight( imageSize.width() / windDirectionRatio );
}
else {
windDirectionImageSize.setHeight( imageSize.height() );
windDirectionImageSize.setWidth( imageSize.height() * windDirectionRatio );
}
QImage windArrow( windDirectionImageSize.toSize(), QImage::Format_ARGB32 );
windArrow.fill( Qt::transparent );
QPainter painter( &windArrow );
s_windIcons.render( &painter, windDirectionString );
m_windDirectionLabel.setImage( windArrow );
}
else {
m_windDirectionLabel.clear();
}
if ( isWindSpeedShown() ) {
m_windSpeedLabel.setText( windSpeedString() );
}
else {
m_windSpeedLabel.clear();
}
m_parent->update();
}
void updateFavorite()
{
QStringList items = m_settings.value(QStringLiteral("favoriteItems")).toString()
.split(QLatin1Char(','), QString::SkipEmptyParts);
bool favorite = items.contains( m_parent->id() );
m_favoriteButton.setVisible( favorite );
m_favoriteAction.setText( favorite ? tr( "Remove from Favorites" )
: tr( "Add to Favorites" ) );
if ( m_parent->isFavorite() != favorite ) {
m_parent->setFavorite( favorite );
}
m_parent->update();
}
bool isConditionShown() const
{
return m_currentWeather.hasValidCondition()
&& m_settings.value(QStringLiteral("showCondition"), showConditionDefault).toBool();
}
bool isTemperatureShown() const
{
return m_currentWeather.hasValidTemperature()
&& m_settings.value(QStringLiteral("showTemperature"), showTemperatureDefault).toBool();
}
bool isWindDirectionShown() const
{
return m_currentWeather.hasValidWindDirection()
&& m_settings.value(QStringLiteral("showWindDirection"), showWindDirectionDefault).toBool();
}
bool isWindSpeedShown() const
{
return m_currentWeather.hasValidWindSpeed()
&& m_settings.value(QStringLiteral("showWindSpeed"), showWindSpeedDefault).toBool();
}
QString temperatureString() const
{
WeatherData::TemperatureUnit tUnit = temperatureUnit();
return m_currentWeather.temperatureString( tUnit );
}
WeatherData::TemperatureUnit temperatureUnit() const
{
WeatherData::TemperatureUnit tUnit
= (WeatherData::TemperatureUnit) m_settings.value(QStringLiteral("temperatureUnit"),
WeatherData::Celsius ).toInt();
return tUnit;
}
QString windSpeedString() const
{
return m_currentWeather.windSpeedString( speedUnit() );
}
WeatherData::SpeedUnit speedUnit() const
{
return (WeatherData::SpeedUnit) m_settings.value(QStringLiteral("windSpeedUnit"),
WeatherData::kph ).toInt();
}
QString pressureString() const
{
return m_currentWeather.pressureString( pressureUnit() );
}
WeatherData::PressureUnit pressureUnit() const
{
return (WeatherData::PressureUnit) m_settings.value(QStringLiteral("pressureUnit"),
WeatherData::HectoPascal ).toInt();
}
MarbleWidget *m_marbleWidget;
WeatherData m_currentWeather;
QMap<QDate, WeatherData> m_forecastWeather;
quint8 m_priority;
QAction m_browserAction;
QAction m_favoriteAction;
WeatherItem *m_parent;
QString m_stationName;
QHash<QString,QVariant> m_settings;
static QFont s_font;
// Labels and Layout
// We are not the owner of these items.
FrameGraphicsItem m_frameItem;
LabelGraphicsItem m_conditionLabel;
LabelGraphicsItem m_temperatureLabel;
LabelGraphicsItem m_windDirectionLabel;
LabelGraphicsItem m_windSpeedLabel;
WidgetGraphicsItem m_favoriteButton;
};
// FIXME: Fonts to be defined globally
#ifdef Q_OS_MACX
QFont WeatherItemPrivate::s_font = QFont( QStringLiteral( "Sans Serif" ), 10 );
#else
QFont WeatherItemPrivate::s_font = QFont( QStringLiteral( "Sans Serif" ), 8 );
#endif
WeatherItem::WeatherItem(QObject *parent )
: AbstractDataPluginItem( parent ),
d( new WeatherItemPrivate( this ) )
{
setCacheMode( ItemCoordinateCache );
}
WeatherItem::WeatherItem(MarbleWidget* widget, QObject *parent )
: AbstractDataPluginItem( parent ),
d( new WeatherItemPrivate( this ) )
{
setCacheMode( ItemCoordinateCache );
d->m_marbleWidget = widget;
}
WeatherItem::~WeatherItem()
{
delete d;
}
QAction *WeatherItem::action()
{
disconnect( &d->m_browserAction, SIGNAL(triggered()),
this, SLOT(openBrowser()) );
connect( &d->m_browserAction, SIGNAL(triggered()),
this, SLOT(openBrowser()) );
return &d->m_browserAction;
}
bool WeatherItem::request( const QString& type )
{
Q_UNUSED( type )
return true;
}
bool WeatherItem::initialized() const
{
return d->isConditionShown()
|| d->isTemperatureShown()
|| d->isWindDirectionShown()
|| d->isWindSpeedShown();
}
bool WeatherItem::operator<( const AbstractDataPluginItem *other ) const
{
const WeatherItem *weatherItem = qobject_cast<const WeatherItem *>(other);
if( weatherItem ) {
return ( priority() > weatherItem->priority() );
}
else {
return false;
}
}
QString WeatherItem::stationName() const
{
return d->m_stationName;
}
void WeatherItem::setStationName( const QString& name )
{
if ( name != d->m_stationName ) {
d->m_browserAction.setText( name );
d->m_stationName = name;
d->updateToolTip();
d->updateLabels();
emit stationNameChanged();
}
}
WeatherData WeatherItem::currentWeather() const
{
return d->m_currentWeather;
}
void WeatherItem::setCurrentWeather( const WeatherData &weather )
{
d->m_currentWeather = weather;
d->updateToolTip();
d->updateLabels();
emit updated();
emit descriptionChanged();
emit imageChanged();
emit temperatureChanged();
}
QMap<QDate, WeatherData> WeatherItem::forecastWeather() const
{
return d->m_forecastWeather;
}
void WeatherItem::setForecastWeather( const QMap<QDate, WeatherData>& forecasts )
{
d->m_forecastWeather = forecasts;
d->updateToolTip();
emit updated();
}
void WeatherItem::addForecastWeather( const QList<WeatherData>& forecasts )
{
for( const WeatherData& data: forecasts ) {
QDate date = data.dataDate();
WeatherData other = d->m_forecastWeather.value( date );
if ( !other.isValid() ) {
d->m_forecastWeather.insert( date, data );
}
else if ( other.publishingTime() < data.publishingTime() ) {
d->m_forecastWeather.remove( date );
d->m_forecastWeather.insert( date, data );
}
}
// Remove old items
QDate const minDate = QDate::currentDate();
QMap<QDate, WeatherData>::iterator it = d->m_forecastWeather.begin();
while( it != d->m_forecastWeather.end() ) {
if ( it.key() < minDate ) {
it = d->m_forecastWeather.erase( it );
} else {
++it;
}
}
d->updateToolTip();
emit updated();
}
quint8 WeatherItem::priority() const
{
return d->m_priority;
}
void WeatherItem::setPriority( quint8 priority )
{
d->m_priority = priority;
}
void WeatherItem::setSettings( const QHash<QString, QVariant>& settings )
{
if ( d->m_settings == settings ) {
return;
}
d->m_settings = settings;
d->updateToolTip();
d->updateLabels();
d->updateFavorite();
}
void WeatherItem::setMarbleWidget(MarbleWidget *widget)
{
d->m_marbleWidget = widget;
}
void WeatherItem::openBrowser()
{
if (d->m_marbleWidget) {
PopupLayer *popup = d->m_marbleWidget->popupLayer();
popup->setCoordinates( coordinate(), Qt::AlignRight | Qt::AlignVCenter );
popup->setSize(QSizeF(630, 580)); // +10 pixels for the width
popup->popup();
QFile weatherHtmlFile(QStringLiteral(":/marble/weather/weather.html"));
if ( !weatherHtmlFile.open(QIODevice::ReadOnly) ) {
return;
}
QString templateHtml = weatherHtmlFile.readAll();
popup->setContent( createFromTemplate(templateHtml) );
}
}
QString WeatherItem::createFromTemplate(const QString &templateHtml)
{
QString html = templateHtml;
QLocale locale = QLocale::system();
html.replace("%city_name%", stationName());
if (!d->m_currentWeather.iconSource().isEmpty()) {
html.replace("%weather_situation%",
QLatin1String("<img src=\"file://") + d->m_currentWeather.iconSource() + QLatin1String("\" />"));
} else {
html.remove("%weather_situation%");
}
html.replace("%current_temp%", d->temperatureString());
html.replace("%current_condition%", d->m_currentWeather.conditionString());
html.replace("%wind_direction%", d->m_currentWeather.windDirectionString());
html.replace("%wind_speed%", d->m_currentWeather.windSpeedString());
html.replace("%humidity_level%", d->m_currentWeather.humidityString());
html.replace("%publish_time%", d->m_currentWeather.publishingTime().toString());
if(d->m_forecastWeather.size() < 1) {
html.replace("%forecast_available%", "none");
} else {
html.replace("%forecast_available%", "block");
}
int forecastNumber = 0;
for ( const WeatherData &forecast: d->m_forecastWeather ) {
forecastNumber++;
const QString suffix = QString::number(forecastNumber);
QDate date = forecast.dataDate();
html.replace(QLatin1String("%day_f") + suffix + QLatin1Char('%'),
locale.standaloneDayName(date.dayOfWeek()));
html.replace(QLatin1String("%weather_situation_f") + suffix + QLatin1Char('%'),
QLatin1String("file://")+forecast.iconSource());
html.replace(QLatin1String("%max_temp_f") + suffix + QLatin1Char('%'),
forecast.maxTemperatureString(WeatherData::Celsius));
html.replace(QLatin1String("%min_temp_f") + suffix + QLatin1Char('%'),
forecast.minTemperatureString(WeatherData::Celsius));
html.replace(QLatin1String("%condition_f") + suffix + QLatin1Char('%'), forecast.conditionString());
html.replace(QLatin1String("%wind_direction_f") + suffix + QLatin1Char('%'), forecast.windDirectionString());
html.replace(QLatin1String("%wind_speed_f") + suffix + QLatin1Char('%'), forecast.windSpeedString());
html.replace(QLatin1String("%publish_time_f") + suffix + QLatin1Char('%'), forecast.publishingTime().toString());
}
return html;
}
QList<QAction*> WeatherItem::actions()
{
QList<QAction*> result;
result << &d->m_browserAction;
disconnect( &d->m_favoriteAction, SIGNAL(triggered()),
this, SLOT(toggleFavorite()) );
connect( &d->m_favoriteAction, SIGNAL(triggered()),
this, SLOT(toggleFavorite()) );
result << &d->m_favoriteAction;
return result;
}
QString WeatherItem::description() const
{
return d->m_currentWeather.toHtml( WeatherData::Celsius, WeatherData::kph, WeatherData::Bar );
}
QString WeatherItem::image() const
{
return d->m_currentWeather.iconSource();
}
double WeatherItem::temperature() const
{
return d->m_currentWeather.hasValidTemperature()
? d->m_currentWeather.temperature( WeatherData::Celsius )
: 0.0;
}
} // namespace Marble
#include "moc_WeatherItem.cpp"
diff --git a/src/plugins/render/weather/WeatherItem.h b/src/plugins/render/weather/WeatherItem.h
index d796efcbe..c94ae9ea1 100644
--- a/src/plugins/render/weather/WeatherItem.h
+++ b/src/plugins/render/weather/WeatherItem.h
@@ -1,120 +1,120 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
// Copyright 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#ifndef WEATHERITEM_H
#define WEATHERITEM_H
// Marble
#include "AbstractDataPluginItem.h"
// Qt
#include <QMap>
class QString;
class QAction;
class QDate;
namespace Marble
{
class MarbleWidget;
class WeatherData;
class WeatherItemPrivate;
/**
* This is the class painting a weather item on the screen. So it is a subclass of
* AbstractDataItem.
*/
class WeatherItem : public AbstractDataPluginItem
{
Q_OBJECT
Q_PROPERTY( QString station READ stationName WRITE setStationName NOTIFY stationNameChanged )
Q_PROPERTY( QString description READ description NOTIFY descriptionChanged )
Q_PROPERTY( QString image READ image NOTIFY imageChanged )
Q_PROPERTY( double temperature READ temperature NOTIFY temperatureChanged )
public:
- explicit WeatherItem( QObject *parent = 0 );
- explicit WeatherItem( MarbleWidget* widget, QObject *parent = 0 );
+ explicit WeatherItem( QObject *parent = nullptr );
+ explicit WeatherItem( MarbleWidget* widget, QObject *parent = nullptr );
~WeatherItem() override;
QAction *action() override;
/**
* Test if the item wants to request @p type again.
*/
virtual bool request( const QString& type );
/**
* Returns the provider of the weather information.
*/
virtual QString service() const = 0;
bool initialized() const override;
void addDownloadedFile( const QString& url, const QString& type ) override = 0;
bool operator<( const AbstractDataPluginItem *other ) const override;
QString stationName() const;
void setStationName( const QString& name );
WeatherData currentWeather() const;
void setCurrentWeather( const WeatherData& weather );
QMap<QDate, WeatherData> forecastWeather() const;
void setForecastWeather( const QMap<QDate, WeatherData>& forecasts );
/**
* Adds additional forecasts to the list. If there are multiple forecasts for one day,
* it will choose the most recent (as of pubDate).
*/
void addForecastWeather( const QList<WeatherData>& forecasts );
quint8 priority() const;
void setPriority( quint8 priority );
void setSettings( const QHash<QString, QVariant>& settings ) override;
void setMarbleWidget( MarbleWidget *widget );
QList<QAction*> actions() override;
QString description() const;
QString image() const;
double temperature() const;
public Q_SLOTS:
void openBrowser();
Q_SIGNALS:
void stationNameChanged();
void descriptionChanged();
void imageChanged();
void temperatureChanged();
private:
Q_DISABLE_COPY(WeatherItem)
WeatherItemPrivate * const d;
friend class WeatherItemPrivate;
QString createFromTemplate(const QString &templateHtml);
};
} // namespace Marble
#endif // WEATHERITEM_H
diff --git a/src/plugins/render/weather/WeatherPlugin.cpp b/src/plugins/render/weather/WeatherPlugin.cpp
index cdfba49f3..91884af3a 100644
--- a/src/plugins/render/weather/WeatherPlugin.cpp
+++ b/src/plugins/render/weather/WeatherPlugin.cpp
@@ -1,320 +1,320 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "WeatherPlugin.h"
// Marble
#include "ui_WeatherConfigWidget.h"
#include "WeatherData.h"
#include "WeatherModel.h"
#include "MarbleWidget.h"
#include "MarbleDirs.h"
#include "MarbleLocale.h"
#include "MarbleGlobal.h"
#include "weatherGlobal.h"
#include "MarbleDebug.h"
// Qt
#include <QDialog>
#include <QIcon>
#include <QPushButton>
using namespace Marble;
/* TRANSLATOR Marble::WeatherPlugin */
const quint32 numberOfStationsPerFetch = 20;
WeatherPlugin::WeatherPlugin()
- : AbstractDataPlugin( 0 ),
- m_configDialog( 0 ),
- ui_configWidget( 0 )
+ : AbstractDataPlugin( nullptr ),
+ m_configDialog( nullptr ),
+ ui_configWidget( nullptr )
{
}
WeatherPlugin::WeatherPlugin( const MarbleModel *marbleModel )
: AbstractDataPlugin( marbleModel ),
m_updateInterval( 0 ),
m_icon(MarbleDirs::path(QStringLiteral("weather/weather-clear.png"))),
- m_configDialog( 0 ),
- ui_configWidget( 0 ),
+ m_configDialog( nullptr ),
+ ui_configWidget( nullptr ),
m_settings()
{
// Plugin is enabled by default
setEnabled( true );
// Plugin is not visible by default
setVisible( false );
connect( this, SIGNAL(settingsChanged(QString)),
this, SLOT(updateItemSettings()) );
setSettings( QHash<QString,QVariant>() );
}
WeatherPlugin::~WeatherPlugin()
{
delete m_configDialog;
delete ui_configWidget;
}
void WeatherPlugin::initialize()
{
readSettings();
WeatherModel *model = new WeatherModel( marbleModel(), this );
setModel( model );
updateSettings();
updateItemSettings();
}
QString WeatherPlugin::name() const
{
return tr( "Weather" );
}
QString WeatherPlugin::guiString() const
{
return tr( "&Weather" );
}
QString WeatherPlugin::nameId() const
{
return QStringLiteral("weather");
}
QString WeatherPlugin::version() const
{
return QStringLiteral("1.1");
}
QString WeatherPlugin::description() const
{
return tr( "Download weather information from many weather stations all around the world" );
}
QString WeatherPlugin::copyrightYears() const
{
return QStringLiteral("2009, 2011");
}
QVector<PluginAuthor> WeatherPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Bastian Holst"), QStringLiteral("bastianholst@gmx.de"))
<< PluginAuthor(QStringLiteral("Valery Kharitonov"), QStringLiteral("kharvd@gmail.com"));
}
QString WeatherPlugin::aboutDataText() const
{
return tr( "Supported by backstage.bbc.co.uk.\nWeather data from UK MET Office" );
}
QIcon WeatherPlugin::icon() const
{
return m_icon;
}
QDialog *WeatherPlugin::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::WeatherConfigWidget;
ui_configWidget->setupUi( m_configDialog );
readSettings();
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
this, SLOT(writeSettings()) );
}
return m_configDialog;
}
QHash<QString,QVariant> WeatherPlugin::settings() const
{
QHash<QString, QVariant> result = AbstractDataPlugin::settings();
typedef QHash<QString, QVariant>::ConstIterator Iterator;
Iterator end = m_settings.constEnd();
for ( Iterator iter = m_settings.constBegin(); iter != end; ++iter ) {
result.insert( iter.key(), iter.value() );
}
return result;
}
void WeatherPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractDataPlugin::setSettings( settings );
m_settings.insert(QStringLiteral("showCondition"), settings.value(QStringLiteral("showCondition"), showConditionDefault));
m_settings.insert(QStringLiteral("showTemperature"), settings.value(QStringLiteral("showTemperature"), showTemperatureDefault));
m_settings.insert(QStringLiteral("showWindDirection"), settings.value(QStringLiteral("showWindDirection"), showWindDirectionDefault));
m_settings.insert(QStringLiteral("showWindSpeed"), settings.value(QStringLiteral("showWindSpeed"), showWindSpeedDefault));
// Units
// The default units depend on the global measure system.
const MarbleLocale *locale = MarbleGlobal::getInstance()->locale();
int temperatureUnit;
if ( locale->measurementSystem() == MarbleLocale::MetricSystem ) {
temperatureUnit = WeatherData::Celsius;
}
else {
temperatureUnit = WeatherData::Fahrenheit;
}
m_settings.insert(QStringLiteral("temperatureUnit"), settings.value(QStringLiteral("temperatureUnit"), temperatureUnit));
int windSpeedUnit;
if ( locale->measurementSystem() == MarbleLocale::MetricSystem ) {
windSpeedUnit = WeatherData::kph;
}
else {
windSpeedUnit = WeatherData::mph;
}
m_settings.insert(QStringLiteral("windSpeedUnit"), settings.value(QStringLiteral("windSpeedUnit"), windSpeedUnit));
int pressureUnit;
if ( locale->measurementSystem() == MarbleLocale::MetricSystem ) {
pressureUnit = WeatherData::HectoPascal;
}
else {
pressureUnit = WeatherData::inchHg;
}
m_settings.insert(QStringLiteral("pressureUnit"), settings.value(QStringLiteral("pressureUnit"), pressureUnit));
readSettings();
emit settingsChanged( nameId() );
updateSettings();
}
bool WeatherPlugin::eventFilter(QObject *object, QEvent *event)
{
if ( isInitialized() ) {
WeatherModel *weatherModel = qobject_cast<WeatherModel*>( model() );
Q_ASSERT(weatherModel);
MarbleWidget* widget = qobject_cast<MarbleWidget*>( object );
if ( widget ) {
weatherModel->setMarbleWidget(widget);
}
}
return AbstractDataPlugin::eventFilter( object, event );
}
void WeatherPlugin::readSettings()
{
if ( !m_configDialog ) {
return;
}
// Information
if (m_settings.value(QStringLiteral("showCondition")).toBool())
ui_configWidget->m_weatherConditionBox->setCheckState( Qt::Checked );
else
ui_configWidget->m_weatherConditionBox->setCheckState( Qt::Unchecked );
if (m_settings.value(QStringLiteral("showTemperature")).toBool())
ui_configWidget->m_temperatureBox->setCheckState( Qt::Checked );
else
ui_configWidget->m_temperatureBox->setCheckState( Qt::Unchecked );
if (m_settings.value(QStringLiteral("showWindDirection")).toBool())
ui_configWidget->m_windDirectionBox->setCheckState( Qt::Checked );
else
ui_configWidget->m_windDirectionBox->setCheckState( Qt::Unchecked );
if (m_settings.value(QStringLiteral("showWindSpeed")).toBool())
ui_configWidget->m_windSpeedBox->setCheckState( Qt::Checked );
else
ui_configWidget->m_windSpeedBox->setCheckState( Qt::Unchecked );
if (m_settings.value(QStringLiteral("onlyFavorites")).toBool())
ui_configWidget->m_onlyFavoritesBox->setCheckState( Qt::Checked );
else
ui_configWidget->m_onlyFavoritesBox->setCheckState( Qt::Unchecked );
// Units
ui_configWidget->m_temperatureComboBox
->setCurrentIndex(m_settings.value(QStringLiteral("temperatureUnit")).toInt());
ui_configWidget->m_windSpeedComboBox
->setCurrentIndex(m_settings.value(QStringLiteral("windSpeedUnit")).toInt());
ui_configWidget->m_pressureComboBox
->setCurrentIndex(m_settings.value(QStringLiteral("pressureUnit")).toInt());
// Misc
ui_configWidget->m_updateIntervalBox
->setValue(m_settings.value(QStringLiteral("updateInterval"), 3).toInt());
}
void WeatherPlugin::writeSettings()
{
// Information
m_settings.insert(QStringLiteral("showCondition"),
ui_configWidget->m_weatherConditionBox->checkState() == Qt::Checked );
m_settings.insert(QStringLiteral("showTemperature"),
ui_configWidget->m_temperatureBox->checkState() == Qt::Checked );
m_settings.insert(QStringLiteral("showWindDirection"),
ui_configWidget->m_windDirectionBox->checkState() == Qt::Checked );
m_settings.insert(QStringLiteral("showWindSpeed"),
ui_configWidget->m_windSpeedBox->checkState() == Qt::Checked );
// Units
m_settings.insert(QStringLiteral("temperatureUnit"), ui_configWidget->m_temperatureComboBox->currentIndex());
m_settings.insert(QStringLiteral("windSpeedUnit"), ui_configWidget->m_windSpeedComboBox->currentIndex());
m_settings.insert(QStringLiteral("pressureUnit"), ui_configWidget->m_pressureComboBox->currentIndex());
// Misc
bool onlyFavorites = ( ui_configWidget->m_onlyFavoritesBox->checkState() == Qt::Checked );
m_settings.insert(QStringLiteral("onlyFavorites"), onlyFavorites);
m_updateInterval = ui_configWidget->m_updateIntervalBox->value();
m_settings.insert(QStringLiteral("updateInterval"), m_updateInterval);
emit settingsChanged( nameId() );
updateSettings();
}
void WeatherPlugin::updateSettings()
{
if ( model() ) {
bool favoritesOnly = m_settings.value(QStringLiteral("onlyFavorites"), false).toBool();
QList<QString> favoriteItems = m_settings.value(QStringLiteral("favoriteItems")).toString()
.split(QLatin1Char(','), QString::SkipEmptyParts);
model()->setFavoriteItems( favoriteItems );
setNumberOfItems( favoritesOnly ? favoriteItems.size() : numberOfStationsPerFetch );
model()->setFavoriteItemsOnly( favoritesOnly );
}
}
void WeatherPlugin::updateItemSettings()
{
AbstractDataPluginModel *abstractModel = model();
- if( abstractModel != 0 ) {
+ if( abstractModel != nullptr ) {
abstractModel->setItemSettings( m_settings );
}
}
void WeatherPlugin::favoriteItemsChanged( const QStringList& favoriteItems )
{
m_settings[QStringLiteral("favoriteItems")] = favoriteItems.join(QLatin1Char(','));
emit settingsChanged( nameId() );
updateSettings();
}
#include "moc_WeatherPlugin.cpp"
diff --git a/src/plugins/render/wikipedia/WikipediaItem.cpp b/src/plugins/render/wikipedia/WikipediaItem.cpp
index f86ae3b4c..9127944d5 100644
--- a/src/plugins/render/wikipedia/WikipediaItem.cpp
+++ b/src/plugins/render/wikipedia/WikipediaItem.cpp
@@ -1,248 +1,248 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "WikipediaItem.h"
// Qt
#include <QAction>
#include <QPainter>
// Marble
#include "MarbleDebug.h"
#include "ViewportParams.h"
#include "TinyWebBrowser.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "RenderPlugin.h"
#include "PluginManager.h"
#include "layers/PopupLayer.h"
using namespace Marble;
/* TRANSLATOR Marble::WikipediaItem */
// The Wikipedia icon is not a square
const QRect wikiIconRect( 0, 0, 22, 19 );
const QSize miniWikiIconSize( 22, 19 );
const int miniWikiIconBorder = 3;
WikipediaItem::WikipediaItem( MarbleWidget* widget, QObject *parent )
: AbstractDataPluginItem( parent ),
m_marbleWidget( widget ),
m_rank( 0.0 ),
- m_browser( 0 ),
+ m_browser( nullptr ),
m_wikiIcon(),
m_showThumbnail( false )
{
m_action = new QAction( this );
connect( m_action, SIGNAL(triggered()), this, SLOT(openBrowser()) );
setCacheMode( ItemCoordinateCache );
}
WikipediaItem::~WikipediaItem()
{
delete m_browser;
}
QString WikipediaItem::name() const
{
return id();
}
void WikipediaItem::setName( const QString& name )
{
setId( name );
updateToolTip();
}
bool WikipediaItem::initialized() const
{
return true;
}
void WikipediaItem::addDownloadedFile( const QString& url, const QString& type )
{
if (type == QLatin1String("thumbnail")) {
m_thumbnail.load( url );
updateSize();
emit updated();
}
}
bool WikipediaItem::operator<( const AbstractDataPluginItem *other ) const
{
WikipediaItem const * otherItem = dynamic_cast<WikipediaItem const *>( other );
return otherItem ? m_rank > otherItem->m_rank : id() < other->id();
}
void WikipediaItem::paint( QPainter *painter )
{
if ( !showThumbnail() ) {
m_wikiIcon.paint( painter, wikiIconRect );
}
else {
painter->drawPixmap( 0, 0, m_thumbnail );
QSize minSize = miniWikiIconSize;
minSize *= 2;
QSize thumbnailSize = m_thumbnail.size();
if ( thumbnailSize.width() >= minSize.width()
&& thumbnailSize.height() >= minSize.height() )
{
QRect wikiRect( QPoint( 0, 0 ), miniWikiIconSize );
wikiRect.moveBottomRight( QPoint( m_thumbnail.width() - miniWikiIconBorder,
m_thumbnail.height() - miniWikiIconBorder ) );
m_wikiIcon.paint( painter, wikiRect );
}
}
}
qreal WikipediaItem::longitude() const
{
return coordinate().longitude();
}
void WikipediaItem::setLongitude( qreal longitude )
{
GeoDataCoordinates updatedCoordinates = coordinate();
updatedCoordinates.setLongitude( longitude );
setCoordinate( updatedCoordinates );
}
qreal WikipediaItem::latitude() const
{
return coordinate().latitude();
}
void WikipediaItem::setLatitude( qreal latitude )
{
GeoDataCoordinates updatedCoordinates = coordinate();
updatedCoordinates.setLatitude( latitude );
setCoordinate( updatedCoordinates );
}
QUrl WikipediaItem::url() const
{
return m_url;
}
void WikipediaItem::setUrl( const QUrl& url )
{
m_url = url;
}
QUrl WikipediaItem::thumbnailImageUrl() const
{
return m_thumbnailImageUrl;
}
void WikipediaItem::setThumbnailImageUrl( const QUrl& thumbnailImageUrl )
{
m_thumbnailImageUrl = thumbnailImageUrl;
}
QString WikipediaItem::summary() const
{
return m_summary;
}
void WikipediaItem::setSummary( const QString& summary )
{
m_summary = summary;
updateToolTip();
}
QAction *WikipediaItem::action()
{
m_action->setText( id() );
return m_action;
}
void WikipediaItem::openBrowser( )
{
if ( m_marbleWidget ) {
PopupLayer* popup = m_marbleWidget->popupLayer();
popup->setCoordinates( coordinate(), Qt::AlignRight | Qt::AlignVCenter );
popup->setSize(QSizeF(520, 570));
popup->setUrl( url() );
popup->popup();
} else {
if ( !m_browser ) {
m_browser = new TinyWebBrowser();
}
m_browser->load( url() );
m_browser->show();
}
}
void WikipediaItem::setIcon( const QIcon& icon )
{
m_action->setIcon( icon );
m_wikiIcon = icon;
updateSize();
}
void WikipediaItem::setSettings( const QHash<QString, QVariant>& settings )
{
const bool showThumbnail = settings.value(QStringLiteral("showThumbnails"), false).toBool();
if ( showThumbnail != m_showThumbnail ) {
m_showThumbnail = showThumbnail;
updateSize();
updateToolTip();
update();
}
}
void WikipediaItem::setRank( double rank )
{
m_rank = rank;
}
double WikipediaItem::rank() const
{
return m_rank;
}
void WikipediaItem::updateSize()
{
if ( showThumbnail() ) {
setSize( m_thumbnail.size() );
}
else {
setSize( wikiIconRect.size() );
}
}
void WikipediaItem::updateToolTip()
{
QString toolTip = QLatin1String(
"<html><head><meta name=\"qrichtext\" content=\"1\" />"
"<style type=\"text/css\">\\np, li { white-space: pre-wrap; }\\n</style></head>"
"<body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; "
"font-style:normal;\"><p style=\" margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">");
if ( summary().isEmpty() ) {
toolTip += name() + QLatin1String("</p></body></html>\n");
setToolTip(toolTip);
}
else {
toolTip += tr("<b>%1</b><br>%2", "Title:\nSummary") + QLatin1String("</p></body></html>\n");
setToolTip( toolTip.arg( name() ).arg( summary() ) );
}
}
bool WikipediaItem::showThumbnail() const
{
return m_showThumbnail && !m_thumbnail.isNull();
}
#include "moc_WikipediaItem.cpp"
diff --git a/src/plugins/render/wikipedia/WikipediaModel.cpp b/src/plugins/render/wikipedia/WikipediaModel.cpp
index 328bd6d04..ad03c2f6a 100644
--- a/src/plugins/render/wikipedia/WikipediaModel.cpp
+++ b/src/plugins/render/wikipedia/WikipediaModel.cpp
@@ -1,110 +1,110 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "WikipediaModel.h"
// Plugin
#include "GeonamesParser.h"
// Marble
#include "GeoDataLatLonAltBox.h"
#include "MarbleGlobal.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MarbleDirs.h"
#include "WikipediaItem.h"
#include "MarbleLocale.h"
#include "MarbleDebug.h"
// Qt
#include <QUrl>
#include <QString>
#include <QPainter>
#include <QUrlQuery>
using namespace Marble;
WikipediaModel::WikipediaModel( const MarbleModel *marbleModel, QObject *parent )
: AbstractDataPluginModel( "wikipedia", marbleModel, parent ),
- m_marbleWidget( 0 ),
+ m_marbleWidget( nullptr ),
m_wikipediaIcon(MarbleDirs::path(QStringLiteral("svg/wikipedia_shadow.svg"))),
m_showThumbnail( true )
{
m_languageCode = MarbleLocale::languageCode();
}
WikipediaModel::~WikipediaModel()
{
}
void WikipediaModel::setShowThumbnail( bool show )
{
m_showThumbnail = show;
}
void WikipediaModel::getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number )
{
// Geonames only supports wikipedia articles for earth
if (marbleModel()->planetId() != QLatin1String("earth")) {
return;
}
QUrl geonamesUrl( "http://ws.geonames.org/wikipediaBoundingBox" );
QUrlQuery urlQuery;
urlQuery.addQueryItem( "north", QString::number( box.north( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "south", QString::number( box.south( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "east", QString::number( box.east( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "west", QString::number( box.west( GeoDataCoordinates::Degree ) ) );
urlQuery.addQueryItem( "maxRows", QString::number( number ) );
urlQuery.addQueryItem( "lang", m_languageCode );
urlQuery.addQueryItem( "username", "marble" );
geonamesUrl.setQuery( urlQuery );
downloadDescriptionFile( geonamesUrl );
}
void WikipediaModel::parseFile( const QByteArray& file )
{
QList<WikipediaItem*> list;
GeonamesParser parser( m_marbleWidget, &list, this );
parser.read( file );
QList<AbstractDataPluginItem*> items;
QList<WikipediaItem*>::const_iterator it;
for ( it = list.constBegin(); it != list.constEnd(); ++it ) {
if ( itemExists( (*it)->id() ) ) {
delete *it;
continue;
}
(*it)->setIcon( m_wikipediaIcon );
QUrl thumbnailImageUrl = (*it)->thumbnailImageUrl();
if ( m_showThumbnail && !thumbnailImageUrl.isEmpty() ) {
downloadItem( thumbnailImageUrl, "thumbnail", *it );
}
else {
items << *it;
}
}
addItemsToList( items );
}
void WikipediaModel::setMarbleWidget(MarbleWidget *widget)
{
m_marbleWidget = widget;
}
#include "moc_WikipediaModel.cpp"
diff --git a/src/plugins/render/wikipedia/WikipediaModel.h b/src/plugins/render/wikipedia/WikipediaModel.h
index dee8b6374..ec70cf6c5 100644
--- a/src/plugins/render/wikipedia/WikipediaModel.h
+++ b/src/plugins/render/wikipedia/WikipediaModel.h
@@ -1,62 +1,62 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#ifndef WIKIPEDIAMODEL_H
#define WIKIPEDIAMODEL_H
#include "AbstractDataPluginModel.h"
#include <QIcon>
namespace Marble
{
class MarbleWidget;
const quint32 numberOfArticlesPerFetch = 7;
class WikipediaModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- explicit WikipediaModel( const MarbleModel *marbleModel, QObject *parent = 0 );
+ explicit WikipediaModel( const MarbleModel *marbleModel, QObject *parent = nullptr );
~WikipediaModel() override;
void setShowThumbnail( bool show );
void setMarbleWidget( MarbleWidget* widget );
protected:
/**
* Generates the download url for the description file from the web service depending on
* the @p box surrounding the view and the @p number of files to show.
**/
void getAdditionalItems( const GeoDataLatLonAltBox& box,
qint32 number = 10 ) override;
/**
* The reimplementation has to parse the @p file and should generate widgets. This widgets
* have to be scheduled to downloadItemData or could be directly added to the list,
* depending on if they have to download information to be shown.
**/
void parseFile( const QByteArray& file ) override;
private:
MarbleWidget* m_marbleWidget;
QIcon m_wikipediaIcon;
QString m_languageCode;
bool m_showThumbnail;
};
}
#endif // WIKIPEDIAMODEL_H
diff --git a/src/plugins/render/wikipedia/WikipediaPlugin.cpp b/src/plugins/render/wikipedia/WikipediaPlugin.cpp
index 30d8d60cb..571de3dda 100644
--- a/src/plugins/render/wikipedia/WikipediaPlugin.cpp
+++ b/src/plugins/render/wikipedia/WikipediaPlugin.cpp
@@ -1,209 +1,209 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
// Self
#include "WikipediaPlugin.h"
// Marble
#include "ui_WikipediaConfigWidget.h"
#include "WikipediaModel.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include "MarbleWidget.h"
// Qt
#include <QPushButton>
using namespace Marble;
/* TRANSLATOR Marble::WikipediaPlugin */
const quint32 maximumNumberOfItems = 99;
WikipediaPlugin::WikipediaPlugin()
- : AbstractDataPlugin( 0 ),
- ui_configWidget( 0 ),
- m_configDialog( 0 )
+ : AbstractDataPlugin( nullptr ),
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr )
{
}
WikipediaPlugin::WikipediaPlugin( const MarbleModel *marbleModel )
: AbstractDataPlugin( marbleModel ),
m_icon(MarbleDirs::path(QStringLiteral("svg/wikipedia_shadow.svg"))),
- ui_configWidget( 0 ),
- m_configDialog( 0 ),
+ ui_configWidget( nullptr ),
+ m_configDialog( nullptr ),
m_showThumbnails( true )
{
// Plugin is enabled by default
setEnabled( true );
// Plugin is not visible by default
setVisible( false );
connect( this, SIGNAL(settingsChanged(QString)),
this, SLOT(updateSettings()) );
connect( this, SIGNAL(changedNumberOfItems(quint32)),
this, SLOT(checkNumberOfItems(quint32)) );
setSettings( QHash<QString,QVariant>() );
}
WikipediaPlugin::~WikipediaPlugin()
{
delete ui_configWidget;
delete m_configDialog;
}
void WikipediaPlugin::initialize()
{
WikipediaModel *model = new WikipediaModel( marbleModel(), this );
// Ensure that all settings get forwarded to the model.
setModel( model );
updateSettings();
}
QString WikipediaPlugin::name() const
{
return tr( "Wikipedia Articles" );
}
QString WikipediaPlugin::guiString() const
{
return tr( "&Wikipedia" );
}
QString WikipediaPlugin::nameId() const
{
return QStringLiteral("wikipedia");
}
QString WikipediaPlugin::version() const
{
return QStringLiteral("1.0");
}
QString WikipediaPlugin::description() const
{
return tr( "Automatically downloads Wikipedia articles and shows them on the right position on the map" );
}
QString WikipediaPlugin::copyrightYears() const
{
return QStringLiteral("2009");
}
QVector<PluginAuthor> WikipediaPlugin::pluginAuthors() const
{
return QVector<PluginAuthor>()
<< PluginAuthor(QStringLiteral("Bastian Holst"), QStringLiteral("bastianholst@gmx.de"));
}
QString WikipediaPlugin::aboutDataText() const
{
return tr( "Geo positions by geonames.org\nTexts by wikipedia.org" );
}
QIcon WikipediaPlugin::icon() const
{
return m_icon;
}
QDialog *WikipediaPlugin::configDialog()
{
if ( !m_configDialog ) {
// Initializing configuration dialog
m_configDialog = new QDialog();
ui_configWidget = new Ui::WikipediaConfigWidget;
ui_configWidget->setupUi( m_configDialog );
readSettings();
ui_configWidget->m_itemNumberSpinBox->setRange( 0, maximumNumberOfItems );
connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()),
SLOT(writeSettings()) );
connect( ui_configWidget->m_buttonBox, SIGNAL(rejected()),
SLOT(readSettings()) );
QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply );
connect( applyButton, SIGNAL(clicked()),
this, SLOT(writeSettings()) );
}
return m_configDialog;
}
QHash<QString,QVariant> WikipediaPlugin::settings() const
{
QHash<QString, QVariant> settings = AbstractDataPlugin::settings();
settings.insert(QStringLiteral("numberOfItems"), numberOfItems());
settings.insert(QStringLiteral("showThumbnails"), m_showThumbnails);
return settings;
}
void WikipediaPlugin::setSettings( const QHash<QString,QVariant> &settings )
{
AbstractDataPlugin::setSettings( settings );
setNumberOfItems(qMin<int>(maximumNumberOfItems, settings.value(QStringLiteral("numberOfItems"), 15).toInt()));
m_showThumbnails = settings.value(QStringLiteral("showThumbnails"), true).toBool();
readSettings();
emit settingsChanged( nameId() );
}
bool WikipediaPlugin::eventFilter(QObject *object, QEvent *event)
{
if ( isInitialized() ) {
WikipediaModel *wikipediaModel = dynamic_cast<WikipediaModel*>( model() );
Q_ASSERT( wikipediaModel );
MarbleWidget* widget = dynamic_cast<MarbleWidget*>( object );
if ( widget ) {
wikipediaModel->setMarbleWidget( widget );
}
}
return AbstractDataPlugin::eventFilter( object, event );
}
void WikipediaPlugin::readSettings()
{
if ( !m_configDialog )
return;
ui_configWidget->m_itemNumberSpinBox->setValue( numberOfItems() );
ui_configWidget->m_showThumbnailCheckBox->setChecked( m_showThumbnails );
}
void WikipediaPlugin::writeSettings()
{
setNumberOfItems( ui_configWidget->m_itemNumberSpinBox->value() );
m_showThumbnails = ui_configWidget->m_showThumbnailCheckBox->isChecked();
emit settingsChanged( nameId() );
}
void WikipediaPlugin::updateSettings()
{
AbstractDataPluginModel *abstractModel = model();
- if ( abstractModel != 0 ) {
+ if ( abstractModel != nullptr ) {
abstractModel->setItemSettings( settings() );
}
WikipediaModel *wikipediaModel = qobject_cast<WikipediaModel*>( model() );
if ( wikipediaModel ) {
wikipediaModel->setShowThumbnail( m_showThumbnails );
}
}
void WikipediaPlugin::checkNumberOfItems( quint32 number ) {
if ( number > maximumNumberOfItems ) {
setNumberOfItems( maximumNumberOfItems );
}
readSettings();
}
#include "moc_WikipediaPlugin.cpp"
diff --git a/src/plugins/runner/cache/CachePlugin.h b/src/plugins/runner/cache/CachePlugin.h
index ea04fe3fe..b16acb1de 100644
--- a/src/plugins/runner/cache/CachePlugin.h
+++ b/src/plugins/runner/cache/CachePlugin.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLECACHEPLUGIN_H
#define MARBLECACHEPLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class CachePlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.CachePlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit CachePlugin( QObject *parent = 0 );
+ explicit CachePlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLECACHEPLUGIN_H
diff --git a/src/plugins/runner/cache/CacheRunner.h b/src/plugins/runner/cache/CacheRunner.h
index 37fb88372..8764c5cb4 100644
--- a/src/plugins/runner/cache/CacheRunner.h
+++ b/src/plugins/runner/cache/CacheRunner.h
@@ -1,29 +1,29 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLECACHERUNNER_H
#define MARBLECACHERUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class CacheRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit CacheRunner(QObject *parent = 0);
+ explicit CacheRunner(QObject *parent = nullptr);
~CacheRunner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLECACHERUNNER_H
diff --git a/src/plugins/runner/cyclestreets/CycleStreetsPlugin.h b/src/plugins/runner/cyclestreets/CycleStreetsPlugin.h
index 93752160f..c5333822b 100644
--- a/src/plugins/runner/cyclestreets/CycleStreetsPlugin.h
+++ b/src/plugins/runner/cyclestreets/CycleStreetsPlugin.h
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
//
#ifndef MARBLE_CYCLESTREETSPLUGIN_H
#define MARBLE_CYCLESTREETSPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class CycleStreetsPlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.CycleStreetsPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
- explicit CycleStreetsPlugin( QObject *parent = 0 );
+ explicit CycleStreetsPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
RoutingRunner *newRunner() const override;
ConfigWidget* configWidget() override;
bool supportsTemplate( RoutingProfilesModel::ProfileTemplate profileTemplate ) const override;
};
}
#endif
diff --git a/src/plugins/runner/cyclestreets/CycleStreetsRunner.h b/src/plugins/runner/cyclestreets/CycleStreetsRunner.h
index 6fc70bc36..0a49ad3b9 100644
--- a/src/plugins/runner/cyclestreets/CycleStreetsRunner.h
+++ b/src/plugins/runner/cyclestreets/CycleStreetsRunner.h
@@ -1,59 +1,59 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mihail Ivchenko <ematirov@gmail.com>
//
#ifndef MARBLE_CYCLESTREETSRUNNER_H
#define MARBLE_CYCLESTREETSRUNNER_H
#include "RoutingRunner.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
namespace Marble
{
class CycleStreetsRunner : public RoutingRunner
{
Q_OBJECT
public:
- explicit CycleStreetsRunner(QObject *parent = 0);
+ explicit CycleStreetsRunner(QObject *parent = nullptr);
~CycleStreetsRunner() override;
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
private Q_SLOTS:
void get();
/** Route data was retrieved via http */
void retrieveData( QNetworkReply *reply );
/** A network error occurred */
void handleError( QNetworkReply::NetworkError );
private:
GeoDataDocument *parse( const QByteArray &content ) const;
int maneuverType( QString& cycleStreetsName ) const;
QNetworkAccessManager m_networkAccessManager;
QNetworkRequest m_request;
QMap<QString,int> turns;
};
}
#endif
diff --git a/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingPlugin.h b/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingPlugin.h
index 37e6f218e..8fe62afb6 100644
--- a/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingPlugin.h
+++ b/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingPlugin.h
@@ -1,51 +1,51 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_GOSMOREREVERSEGEOCODINGPLUGIN_H
#define MARBLE_GOSMOREREVERSEGEOCODINGPLUGIN_H
#include "ReverseGeocodingRunnerPlugin.h"
namespace Marble
{
class GosmorePlugin : public ReverseGeocodingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.GosmoreReverseGeocodingPlugin")
Q_INTERFACES( Marble::ReverseGeocodingRunnerPlugin )
public:
- explicit GosmorePlugin( QObject *parent = 0 );
+ explicit GosmorePlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
ReverseGeocodingRunner* newRunner() const override;
bool canWork() const override;
};
}
#endif
diff --git a/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingRunner.h b/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingRunner.h
index fe2362d4a..59c2956d5 100644
--- a/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingRunner.h
+++ b/src/plugins/runner/gosmore-reversegeocoding/GosmoreReverseGeocodingRunner.h
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_GOSMOREREVERSEGEOCODINGRUNNER_H
#define MARBLE_GOSMOREREVERSEGEOCODINGRUNNER_H
#include "ReverseGeocodingRunner.h"
namespace Marble
{
class GosmoreRunnerPrivate;
class GosmoreRunner : public ReverseGeocodingRunner
{
public:
- explicit GosmoreRunner(QObject *parent = 0);
+ explicit GosmoreRunner(QObject *parent = nullptr);
~GosmoreRunner() override;
// Overriding MarbleAbstractRunner
void reverseGeocoding( const GeoDataCoordinates &coordinates ) override;
private:
GosmoreRunnerPrivate* const d;
};
}
#endif
diff --git a/src/plugins/runner/gosmore-routing/GosmoreRoutingPlugin.h b/src/plugins/runner/gosmore-routing/GosmoreRoutingPlugin.h
index b0f9c28b0..b3d5d8db4 100644
--- a/src/plugins/runner/gosmore-routing/GosmoreRoutingPlugin.h
+++ b/src/plugins/runner/gosmore-routing/GosmoreRoutingPlugin.h
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_GOSMOREROUTINGPLUGIN_H
#define MARBLE_GOSMOREROUTINGPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class GosmorePlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.GosmoreRoutingPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
- explicit GosmorePlugin( QObject *parent = 0 );
+ explicit GosmorePlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
RoutingRunner *newRunner() const override;
bool supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const override;
bool canWork() const override;
};
}
#endif
diff --git a/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.cpp b/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.cpp
index 25538d9c7..4e1f8e80c 100644
--- a/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.cpp
+++ b/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.cpp
@@ -1,249 +1,249 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "GosmoreRoutingRunner.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "routing/RouteRequest.h"
#include "routing/instructions/WaypointParser.h"
#include "routing/instructions/InstructionTransformation.h"
#include "GeoDataDocument.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLineString.h"
#include <QProcess>
#include <QMap>
namespace Marble
{
class GosmoreRunnerPrivate
{
public:
QFileInfo m_gosmoreMapFile;
WaypointParser m_parser;
/** Static to share the cache among all instances */
static QMap<QString, QByteArray> m_partialRoutes;
QByteArray retrieveWaypoints( const QString &query ) const;
static GeoDataDocument* createDocument( GeoDataLineString* routeWaypoints, const QVector<GeoDataPlacemark*> instructions );
static GeoDataLineString parseGosmoreOutput( const QByteArray &content );
static void merge( GeoDataLineString* one, const GeoDataLineString& two );
QVector<GeoDataPlacemark*> parseGosmoreInstructions( const QByteArray &content );
GosmoreRunnerPrivate();
};
GosmoreRunnerPrivate::GosmoreRunnerPrivate()
{
m_parser.setLineSeparator("\r");
m_parser.setFieldSeparator(QLatin1Char(','));
m_parser.setFieldIndex( WaypointParser::RoadName, 4 );
m_parser.addJunctionTypeMapping( "Jr", RoutingWaypoint::Roundabout );
}
QMap<QString, QByteArray> GosmoreRunnerPrivate::m_partialRoutes;
void GosmoreRunnerPrivate::merge( GeoDataLineString* one, const GeoDataLineString& two )
{
Q_ASSERT( one );
QVector<GeoDataCoordinates>::const_iterator iter = two.constBegin();
for( ; iter != two.constEnd(); ++iter ) {
/** @todo: It might be needed to cut off some points at the start or end */
one->append( *iter );
}
}
QByteArray GosmoreRunnerPrivate::retrieveWaypoints( const QString &query ) const
{
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("QUERY_STRING", query);
env.insert("LC_ALL", "C");
QProcess gosmore;
gosmore.setProcessEnvironment(env);
gosmore.start("gosmore", QStringList() << m_gosmoreMapFile.absoluteFilePath() );
if (!gosmore.waitForStarted(5000)) {
mDebug() << "Couldn't start gosmore from the current PATH. Install it to retrieve routing results from gosmore.";
return QByteArray();
}
if ( gosmore.waitForFinished(15000) ) {
return gosmore.readAllStandardOutput();
}
else {
mDebug() << "Couldn't stop gosmore";
}
return QByteArray();
}
GeoDataLineString GosmoreRunnerPrivate::parseGosmoreOutput( const QByteArray &content )
{
GeoDataLineString routeWaypoints;
QStringList lines = QString::fromLocal8Bit( content ).split(QLatin1Char('\r'));
for( const QString &line: lines ) {
const QStringList fields = line.split(QLatin1Char(','));
if (fields.size() >= 5) {
qreal lon = fields.at(1).toDouble();
qreal lat = fields.at(0).toDouble();
GeoDataCoordinates coordinates( lon, lat, 0.0, GeoDataCoordinates::Degree );
routeWaypoints.append( coordinates );
}
}
return routeWaypoints;
}
QVector<GeoDataPlacemark*> GosmoreRunnerPrivate::parseGosmoreInstructions( const QByteArray &content )
{
// Determine gosmore version
QStringList lines = QString::fromUtf8(content).split(QLatin1Char('\r'));
if ( lines.size() > 2 ) {
const QStringList fields = lines.at(lines.size()-2).split(QLatin1Char(','));
m_parser.setFieldIndex( WaypointParser::RoadName, fields.size()-1 );
if ( fields.size() < 5 || fields.size() > 6 ) {
// Can happen when gosmore changes the output format, returns garbage
// or the last street name contains a comma. We may still parse it correctly, just try.
mDebug() << "Unexpected number of fields. This gosmore version may be unsupported.";
}
}
QVector<GeoDataPlacemark*> result;
QTextStream stream( content );
stream.setCodec("UTF8");
stream.setAutoDetectUnicode( true );
RoutingInstructions directions = InstructionTransformation::process( m_parser.parse( stream ) );
for( int i=0; i<directions.size(); ++i ) {
GeoDataPlacemark* placemark = new GeoDataPlacemark( directions[i].instructionText() );
GeoDataExtendedData extendedData;
GeoDataData turnType;
turnType.setName(QStringLiteral("turnType"));
turnType.setValue( qVariantFromValue<int>( int( directions[i].turnType() ) ) );
extendedData.addValue( turnType );
GeoDataData roadName;
roadName.setName(QStringLiteral("roadName"));
roadName.setValue( directions[i].roadName() );
extendedData.addValue( roadName );
placemark->setExtendedData( extendedData );
Q_ASSERT( !directions[i].points().isEmpty() );
GeoDataLineString* geometry = new GeoDataLineString;
QVector<RoutingWaypoint> items = directions[i].points();
for (int j=0; j<items.size(); ++j ) {
RoutingPoint point = items[j].point();
GeoDataCoordinates coordinates( point.lon(), point.lat(), 0.0, GeoDataCoordinates::Degree );
geometry->append( coordinates );
}
placemark->setGeometry( geometry );
result.push_back( placemark );
}
return result;
}
GeoDataDocument* GosmoreRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints, const QVector<GeoDataPlacemark*> instructions )
{
if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
- return 0;
+ return nullptr;
}
GeoDataDocument* result = new GeoDataDocument();
GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
routePlacemark->setName(QStringLiteral("Route"));
routePlacemark->setGeometry( routeWaypoints );
result->append( routePlacemark );
QString name = QStringLiteral("%1 %2 (Gosmore)");
QString unit = QLatin1String( "m" );
qreal length = routeWaypoints->length( EARTH_RADIUS );
if (length >= 1000) {
length /= 1000.0;
unit = "km";
}
result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );
for( GeoDataPlacemark* placemark: instructions )
{
result->append( placemark );
}
return result;
}
GosmoreRunner::GosmoreRunner( QObject *parent ) :
RoutingRunner( parent ),
d( new GosmoreRunnerPrivate )
{
// Check installation
QDir mapDir(MarbleDirs::localPath() + QLatin1String("/maps/earth/gosmore/"));
d->m_gosmoreMapFile = QFileInfo ( mapDir, "gosmore.pak" );
}
GosmoreRunner::~GosmoreRunner()
{
delete d;
}
void GosmoreRunner::retrieveRoute( const RouteRequest *route )
{
if ( !d->m_gosmoreMapFile.exists() )
{
- emit routeCalculated( 0 );
+ emit routeCalculated( nullptr );
return;
}
GeoDataLineString* wayPoints = new GeoDataLineString;
QByteArray completeOutput;
for( int i=0; i<route->size()-1; ++i )
{
QString queryString = "flat=%1&flon=%2&tlat=%3&tlon=%4&fastest=1&v=motorcar";
GeoDataCoordinates source = route->at(i);
double fLon = source.longitude( GeoDataCoordinates::Degree );
double fLat = source.latitude( GeoDataCoordinates::Degree );
queryString = queryString.arg(fLat, 0, 'f', 8).arg(fLon, 0, 'f', 8);
GeoDataCoordinates destination = route->at(i+1);
double tLon = destination.longitude( GeoDataCoordinates::Degree );
double tLat = destination.latitude( GeoDataCoordinates::Degree );
queryString = queryString.arg(tLat, 0, 'f', 8).arg(tLon, 0, 'f', 8);
QByteArray output;
if ( d->m_partialRoutes.contains( queryString ) ) {
output = d->m_partialRoutes[queryString];
}
else {
output = d->retrieveWaypoints( queryString );
}
GeoDataLineString points = d->parseGosmoreOutput( output );
d->merge( wayPoints, points );
completeOutput.append( output );
}
QVector<GeoDataPlacemark*> instructions = d->parseGosmoreInstructions( completeOutput );
GeoDataDocument* result = d->createDocument( wayPoints, instructions );
emit routeCalculated( result );
}
} // namespace Marble
diff --git a/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.h b/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.h
index 0c71df865..8d5254c1f 100644
--- a/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.h
+++ b/src/plugins/runner/gosmore-routing/GosmoreRoutingRunner.h
@@ -1,40 +1,40 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_GOSMOREROUTINGRUNNER_H
#define MARBLE_GOSMOREROUTINGRUNNER_H
#include "RoutingRunner.h"
namespace Marble
{
class GosmoreRunnerPrivate;
class RouteRequest;
class GosmoreRunner : public RoutingRunner
{
public:
- explicit GosmoreRunner(QObject *parent = 0);
+ explicit GosmoreRunner(QObject *parent = nullptr);
~GosmoreRunner() override;
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
private:
GosmoreRunnerPrivate* const d;
};
}
#endif
diff --git a/src/plugins/runner/gpsbabel/GpsbabelPlugin.h b/src/plugins/runner/gpsbabel/GpsbabelPlugin.h
index 7cff05aa5..a244f8349 100644
--- a/src/plugins/runner/gpsbabel/GpsbabelPlugin.h
+++ b/src/plugins/runner/gpsbabel/GpsbabelPlugin.h
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
#ifndef MARBLE_GPSBABEL_PLUGIN_H
#define MARBLE_GPSBABEL_PLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class GpsbabelPlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.GpsbabelPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit GpsbabelPlugin( QObject *parent = 0 );
+ explicit GpsbabelPlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLE_GPSBABEL_PLUGIN_H
diff --git a/src/plugins/runner/gpsbabel/GpsbabelRunner.h b/src/plugins/runner/gpsbabel/GpsbabelRunner.h
index 7d900efc5..2acd93a5c 100644
--- a/src/plugins/runner/gpsbabel/GpsbabelRunner.h
+++ b/src/plugins/runner/gpsbabel/GpsbabelRunner.h
@@ -1,31 +1,31 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mohammed Nafees <nafees.technocool@gmail.com>
#ifndef MARBLE_GPSBABEL_RUNNER_H
#define MARBLE_GPSBABEL_RUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class GpsbabelRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit GpsbabelRunner( QObject *parent = 0 );
+ explicit GpsbabelRunner( QObject *parent = nullptr );
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLE_GPSBABEL_RUNNER_H
diff --git a/src/plugins/runner/gpx/GpxPlugin.h b/src/plugins/runner/gpx/GpxPlugin.h
index afc8eb4f1..404926200 100644
--- a/src/plugins/runner/gpx/GpxPlugin.h
+++ b/src/plugins/runner/gpx/GpxPlugin.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEGPXPLUGIN_H
#define MARBLEGPXPLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class GpxPlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.GpxPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit GpxPlugin( QObject *parent = 0 );
+ explicit GpxPlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLEGPXPLUGIN_H
diff --git a/src/plugins/runner/gpx/GpxRunner.h b/src/plugins/runner/gpx/GpxRunner.h
index 3f8c65bef..dd922019e 100644
--- a/src/plugins/runner/gpx/GpxRunner.h
+++ b/src/plugins/runner/gpx/GpxRunner.h
@@ -1,29 +1,29 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEGPXRUNNER_H
#define MARBLEGPXRUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class GpxRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit GpxRunner(QObject *parent = 0);
+ explicit GpxRunner(QObject *parent = nullptr);
~GpxRunner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLEGPXRUNNER_H
diff --git a/src/plugins/runner/gpx/handlers/GPXTrackPointExtensionTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXTrackPointExtensionTagHandler.cpp
index 5ff6a6c0b..3a71533a3 100644
--- a/src/plugins/runner/gpx/handlers/GPXTrackPointExtensionTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXTrackPointExtensionTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "GPXTrackPointExtensionTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPoint.h"
#include "GeoDataTrack.h"
#include "GeoDataExtendedData.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER_GARMIN_TRACKPOINTEXT1(TrackPointExtension)
GeoNode* GPXTrackPointExtensionTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_TrackPointExtension)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataTrack>() )
{
GeoDataTrack* track = parentItem.nodeAs<GeoDataTrack>();
return track;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXcmtTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXcmtTagHandler.cpp
index 685864499..8fc95dff4 100644
--- a/src/plugins/runner/gpx/handlers/GPXcmtTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXcmtTagHandler.cpp
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Anders Lund <anders@alweb.dk>
//
#include "GPXcmtTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
// type is used in wpt, rte and trk to provide some sort of keyword, like "Geocache/traditional cache",
// and in link to provide a mimetype
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(cmt)
GeoNode* GPXcmtTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_cmt)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_wpt))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
QString cmt = parser.readElementText().trimmed();
if (!cmt.isEmpty())
{
QString desc = placemark->description();
if (!desc.isEmpty())
{
desc += QLatin1String("<br/>");
}
placemark->setDescription(desc.append(cmt.replace(QLatin1Char('\n'),QLatin1String("\n<br/>"))));
placemark->setDescriptionCDATA(true);
}
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXdescTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXdescTagHandler.cpp
index 2156625c5..cb7eb4e59 100644
--- a/src/plugins/runner/gpx/handlers/GPXdescTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXdescTagHandler.cpp
@@ -1,63 +1,63 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Anders Lund <anders@alweb.dk>
// Copyright 2009 Thibaut GRIDEL <tgridel@free.fr>
//
#include "GPXdescTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(desc)
GeoNode* GPXdescTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_desc)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_wpt)
|| parentItem.represents(gpxTag_trk)
|| parentItem.represents(gpxTag_rtept))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
QString desc = placemark->description();
if (!desc.isEmpty())
{
desc += QLatin1String("<br/>");
}
placemark->setDescription(desc.append(parser.readElementText().trimmed().replace(QLatin1Char('\n'),QLatin1String("\n<br/>"))));
placemark->setDescriptionCDATA(true);
}
else if (parentItem.represents(gpxTag_rte))
{
GeoDataFeature* route = parentItem.nodeAs<GeoDataFeature>();
QString desc = route->description();
if (!desc.isEmpty())
{
desc += QLatin1String("<br/>");
}
route->setDescription(desc.append(parser.readElementText().trimmed().replace(QLatin1Char('\n'),QLatin1String("\n<br/>"))));
route->setDescriptionCDATA(true);
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXeleTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXeleTagHandler.cpp
index cfe3e0aeb..483f9c9e0 100644
--- a/src/plugins/runner/gpx/handlers/GPXeleTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXeleTagHandler.cpp
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "GPXeleTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPoint.h"
#include "GeoDataTrack.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(ele)
GeoNode* GPXeleTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_ele)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_trkpt))
{
GeoDataTrack* track = parentItem.nodeAs<GeoDataTrack>();
track->appendAltitude( parser.readElementText().trimmed().toDouble() );
return track;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXextensionsTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXextensionsTagHandler.cpp
index dc6bb52bf..edcdd2685 100644
--- a/src/plugins/runner/gpx/handlers/GPXextensionsTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXextensionsTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "GPXextensionsTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPoint.h"
#include "GeoDataTrack.h"
#include "GeoDataExtendedData.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(extensions)
GeoNode* GPXextensionsTagHandler::parse( GeoParser& parser ) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_extensions)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.represents( gpxTag_trkpt ) )
{
GeoDataTrack* track = parentItem.nodeAs<GeoDataTrack>();
return track;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXhrTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXhrTagHandler.cpp
index b94cd01d5..fd39c5b65 100644
--- a/src/plugins/runner/gpx/handlers/GPXhrTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXhrTagHandler.cpp
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "GPXhrTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataExtendedData.h"
#include "GeoDataTrack.h"
#include "GeoDataSimpleArrayData.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER_GARMIN_TRACKPOINTEXT1(hr)
GeoNode* GPXhrTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_hr)));
GeoStackItem parentItem = parser.parentElement();
if ( parentItem.is<GeoDataTrack>() )
{
GeoDataSimpleArrayData* arrayData = parentItem.nodeAs<GeoDataTrack>()
->extendedData().simpleArrayData(QStringLiteral("heartrate"));
if (!arrayData) {
arrayData = new GeoDataSimpleArrayData();
QString name = parser.attribute( "name" ).trimmed();
parentItem.nodeAs<GeoDataTrack>()->extendedData().setSimpleArrayData(QStringLiteral("heartrate"), arrayData);
}
QVariant value( parser.readElementText().toInt() );
arrayData->append( value );
- return 0;
+ return nullptr;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXlinkTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXlinkTagHandler.cpp
index ea8697642..ec8b23d60 100644
--- a/src/plugins/runner/gpx/handlers/GPXlinkTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXlinkTagHandler.cpp
@@ -1,67 +1,67 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Anders Lund <anders@alweb.dk>
//
#include "GPXlinkTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataData.h"
#include "GeoDataExtendedData.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER_11(link)
// Gpx link provides a linke related to the object, and is inserted into the
// waypoint description as this seems to be the simplest means to make it
// available to the user.
// In addition, link properties are saved to extendedData.
// there are text and type properties, type being ignored for now.
GeoNode* GPXlinkTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_link)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_wpt))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
QXmlStreamAttributes attributes = parser.attributes();
QString href = attributes.value(QLatin1String("href")).toString();
QString text = href;
if (parser.readNextStartElement())
{
text = parser.readElementText();
}
const QString link = QStringLiteral("Link: <a href=\"%1\">%2</a>")
.arg(href).arg(text);
QString desc = placemark->description();
if (!desc.isEmpty())
{
desc += QLatin1String("<br/>");
}
placemark->setDescription(desc.append(link));
placemark->setDescriptionCDATA(true);
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXnameTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXnameTagHandler.cpp
index 1e6b89a82..3a6fe8b4d 100644
--- a/src/plugins/runner/gpx/handlers/GPXnameTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXnameTagHandler.cpp
@@ -1,58 +1,58 @@
/*
This file is part of the Marble Virtual Globe.
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.1 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. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009 Thibaut GRIDEL <tgridel@free.fr>
*/
#include "GPXnameTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(name)
GeoNode* GPXnameTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_name)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_wpt)
|| parentItem.represents(gpxTag_trk)
|| parentItem.represents(gpxTag_rtept))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
placemark->setName(parser.readElementText().trimmed());
}
else if (parentItem.represents(gpxTag_rte))
{
GeoDataFeature* route = parentItem.nodeAs<GeoDataFeature>();
route->setName(parser.readElementText().trimmed());
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXrteTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXrteTagHandler.cpp
index fed9aa12c..abdd44d73 100644
--- a/src/plugins/runner/gpx/handlers/GPXrteTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXrteTagHandler.cpp
@@ -1,60 +1,60 @@
/*
This file is part of the Marble Virtual Globe.
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.1 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. If not, see <http://www.gnu.org/licenses/>.
Copyright 2011 Anders Lund <anders@alweb.dk>
*/
#include "GPXrteTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataLineString.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(rte)
GeoNode* GPXrteTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_rte)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_gpx))
{
GeoDataDocument* doc = parentItem.nodeAs<GeoDataDocument>();
// placemark for the linestring
GeoDataPlacemark *placemark = new GeoDataPlacemark;
doc->append(placemark);
GeoDataLineString *linestring = new GeoDataLineString;
placemark->setGeometry(linestring);
placemark->setStyleUrl(QStringLiteral("#map-route"));
return placemark;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXrteptTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXrteptTagHandler.cpp
index 44bc4cc59..5c9d23637 100644
--- a/src/plugins/runner/gpx/handlers/GPXrteptTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXrteptTagHandler.cpp
@@ -1,71 +1,71 @@
/*
This file is part of the Marble Virtual Globe.
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.1 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. If not, see <http://www.gnu.org/licenses/>.
Copyright 2011 Anders Lund <anders@alweb.dk>
*/
#include "GPXrteptTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataLineString.h"
#include "GeoDataCoordinates.h"
#include "GeoDataPlacemark.h"
#include "GeoDataStyle.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(rtept)
GeoNode* GPXrteptTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_rtept)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_rte))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
GeoDataLineString* linestring = static_cast<GeoDataLineString*>(placemark->geometry());
GeoDataCoordinates coord;
QXmlStreamAttributes attributes = parser.attributes();
QStringRef tmp;
qreal lat = 0;
qreal lon = 0;
tmp = attributes.value(QLatin1String(gpxTag_lat));
if ( !tmp.isEmpty() )
{
lat = tmp.toString().toFloat();
}
tmp = attributes.value(QLatin1String(gpxTag_lon));
if ( !tmp.isEmpty() )
{
lon = tmp.toString().toFloat();
}
coord.set(lon, lat, 0, GeoDataCoordinates::Degree);
linestring->append(coord);
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXtimeTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXtimeTagHandler.cpp
index e7326caba..a01a1b751 100644
--- a/src/plugins/runner/gpx/handlers/GPXtimeTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXtimeTagHandler.cpp
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Niko Sams <niko.sams@gmail.com>
//
#include "GPXtimeTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPoint.h"
#include "GeoDataTrack.h"
#include <QDateTime>
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(time)
GeoNode* GPXtimeTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_time)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_trkpt))
{
GeoDataTrack* track = parentItem.nodeAs<GeoDataTrack>();
QDateTime dateTime = QDateTime::fromString( parser.readElementText().trimmed(), Qt::ISODate );
track->appendWhen( dateTime );
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXtrkTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXtrkTagHandler.cpp
index 33497e3d5..c75302b98 100644
--- a/src/plugins/runner/gpx/handlers/GPXtrkTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXtrkTagHandler.cpp
@@ -1,58 +1,58 @@
/*
This file is part of the Marble Virtual Globe.
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.1 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. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 Thibaut GRIDEL <tgridel@free.fr>
*/
#include "GPXtrkTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataMultiGeometry.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(trk)
GeoNode* GPXtrkTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_trk)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_gpx))
{
GeoDataDocument* doc = parentItem.nodeAs<GeoDataDocument>();
GeoDataPlacemark *placemark = new GeoDataPlacemark;
doc->append(placemark);
GeoDataMultiGeometry *multigeometry = new GeoDataMultiGeometry;
placemark->setGeometry(multigeometry);
placemark->setStyleUrl(QStringLiteral("#map-track"));
return placemark;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXtrkptTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXtrkptTagHandler.cpp
index fc86305a7..b19809d48 100644
--- a/src/plugins/runner/gpx/handlers/GPXtrkptTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXtrkptTagHandler.cpp
@@ -1,70 +1,70 @@
/*
This file is part of the Marble Virtual Globe.
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.1 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. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009 Thibaut GRIDEL <tgridel@free.fr>
*/
#include "GPXtrkptTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataLineString.h"
#include "GeoDataCoordinates.h"
#include "GeoDataTrack.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(trkpt)
GeoNode* GPXtrkptTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_trkpt)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_trkseg))
{
GeoDataTrack* track = parentItem.nodeAs<GeoDataTrack>();
GeoDataCoordinates coord;
QXmlStreamAttributes attributes = parser.attributes();
QStringRef tmp;
qreal lat = 0;
qreal lon = 0;
tmp = attributes.value(QLatin1String(gpxTag_lat));
if ( !tmp.isEmpty() )
{
lat = tmp.toString().toDouble();
}
tmp = attributes.value(QLatin1String(gpxTag_lon));
if ( !tmp.isEmpty() )
{
lon = tmp.toString().toDouble();
}
coord.set(lon, lat, 0, GeoDataCoordinates::Degree);
track->appendCoordinates( coord );
return track;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXtrksegTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXtrksegTagHandler.cpp
index c9acf04db..4e7f48eba 100644
--- a/src/plugins/runner/gpx/handlers/GPXtrksegTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXtrksegTagHandler.cpp
@@ -1,56 +1,56 @@
/*
This file is part of the Marble Virtual Globe.
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.1 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. If not, see <http://www.gnu.org/licenses/>.
Copyright 2010 Thibaut GRIDEL <tgridel@free.fr>
*/
#include "GPXtrksegTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataTrack.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(trkseg)
GeoNode* GPXtrksegTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_trkseg)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_trk))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
GeoDataMultiGeometry *multigeometry = static_cast<GeoDataMultiGeometry*>(placemark->geometry());
GeoDataTrack *track = new GeoDataTrack;
multigeometry->append( track );
return track;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXtypeTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXtypeTagHandler.cpp
index 942996ca1..8e20744ad 100644
--- a/src/plugins/runner/gpx/handlers/GPXtypeTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXtypeTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Anders Lund <anders@alweb.dk>
//
#include "GPXtypeTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(type)
// type is used in wpt, rte and trk to provide some sort of keyword, like "Geocache/traditional cache",
// and in link to provide a mimetype
GeoNode* GPXtypeTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_type)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_wpt)
|| parentItem.represents(gpxTag_trk)
|| parentItem.represents(gpxTag_rtept))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
placemark->setRole(parser.readElementText().trimmed());
}
else if (parentItem.represents(gpxTag_rte))
{
GeoDataFeature* route = parentItem.nodeAs<GeoDataFeature>();
route->setRole(parser.readElementText().trimmed());
}
// TODO: tracks, link
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXurlTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXurlTagHandler.cpp
index be8219c2a..6bc120f72 100644
--- a/src/plugins/runner/gpx/handlers/GPXurlTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXurlTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Anders Lund <anders@alweb.dk>
//
#include "GPXurlTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataData.h"
#include "GeoDataExtendedData.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER_10(url)
// Gpx 1.0 url element provides a link related to a waypoint, and is
// inserted into the waypoint description as this seems to be the
// simplest means to make it available to the user.
// In addition, url properties are saved to extendedData.
// The insertion is done in the urlname element, which is the link text.
GeoNode* GPXurlTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_url)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_wpt))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
QString url = parser.readElementText().trimmed();
GeoDataExtendedData extendedData = placemark->extendedData();
extendedData.addValue(GeoDataData(QStringLiteral("url"), url));
placemark->setExtendedData(extendedData);
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXurlnameTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXurlnameTagHandler.cpp
index 96737d88f..fea359e95 100644
--- a/src/plugins/runner/gpx/handlers/GPXurlnameTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXurlnameTagHandler.cpp
@@ -1,53 +1,53 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Anders Lund <anders@alweb.dk>
//
#include "GPXurlnameTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataPlacemark.h"
#include "GeoDataData.h"
#include "GeoDataExtendedData.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER_10(urlname)
// completes gpx 1.0 url element
GeoNode* GPXurlnameTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_urlname)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_wpt))
{
GeoDataPlacemark* placemark = parentItem.nodeAs<GeoDataPlacemark>();
QString text = parser.readElementText().trimmed();
// no reason to save for now!
// GeoDataExtendedData extendedData = placemark->extendedData();
// extendedData.addValue(GeoDataData("urlname", text));
// placemark->setExtendedData(extendedData);
const QString link = QStringLiteral("<br/>Link: <a href=\"%1\">%2</a>")
.arg(placemark->extendedData().value(QStringLiteral("url")).value().toString())
.arg(text);
placemark->setDescription(placemark->description().append(link));
placemark->setDescriptionCDATA(true);
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/gpx/handlers/GPXwptTagHandler.cpp b/src/plugins/runner/gpx/handlers/GPXwptTagHandler.cpp
index e04cadaba..67c4b1fa9 100644
--- a/src/plugins/runner/gpx/handlers/GPXwptTagHandler.cpp
+++ b/src/plugins/runner/gpx/handlers/GPXwptTagHandler.cpp
@@ -1,73 +1,73 @@
/*
This file is part of the Marble Virtual Globe.
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.1 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. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009 Thibaut GRIDEL <tgridel@free.fr>
*/
#include "GPXwptTagHandler.h"
#include "MarbleDebug.h"
#include "GPXElementDictionary.h"
#include "GeoParser.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
namespace Marble
{
namespace gpx
{
GPX_DEFINE_TAG_HANDLER(wpt)
GeoNode* GPXwptTagHandler::parse(GeoParser& parser) const
{
Q_ASSERT(parser.isStartElement() && parser.isValidElement(QLatin1String(gpxTag_wpt)));
GeoStackItem parentItem = parser.parentElement();
if (parentItem.represents(gpxTag_gpx))
{
GeoDataDocument* doc = parentItem.nodeAs<GeoDataDocument>();
GeoDataPlacemark *placemark = new GeoDataPlacemark;
QXmlStreamAttributes attributes = parser.attributes();
QStringRef tmp;
qreal lat = 0;
qreal lon = 0;
tmp = attributes.value(QLatin1String(gpxTag_lat));
if ( !tmp.isEmpty() )
{
lat = tmp.toString().toFloat();
}
tmp = attributes.value(QLatin1String(gpxTag_lon));
if ( !tmp.isEmpty() )
{
lon = tmp.toString().toFloat();
}
placemark->setCoordinate( lon, lat, 0, GeoDataCoordinates::Degree );
placemark->setRole(QStringLiteral("Waypoint"));
placemark->setStyle(doc->style(QStringLiteral("waypoint")));
doc->append(placemark);
return placemark;
}
- return 0;
+ return nullptr;
}
} // namespace gpx
} // namespace Marble
diff --git a/src/plugins/runner/hostip/HostipPlugin.h b/src/plugins/runner/hostip/HostipPlugin.h
index cc2589785..e3f24d03e 100644
--- a/src/plugins/runner/hostip/HostipPlugin.h
+++ b/src/plugins/runner/hostip/HostipPlugin.h
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_HOSTIPPLUGIN_H
#define MARBLE_HOSTIPPLUGIN_H
#include "SearchRunnerPlugin.h"
namespace Marble
{
class HostipPlugin : public SearchRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.HostipPlugin")
Q_INTERFACES( Marble::SearchRunnerPlugin )
public:
- explicit HostipPlugin( QObject *parent = 0 );
+ explicit HostipPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
SearchRunner* newRunner() const override;
bool canWork() const override;
};
}
#endif
diff --git a/src/plugins/runner/hostip/HostipRunner.h b/src/plugins/runner/hostip/HostipRunner.h
index 497c3c884..957851446 100644
--- a/src/plugins/runner/hostip/HostipRunner.h
+++ b/src/plugins/runner/hostip/HostipRunner.h
@@ -1,57 +1,57 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
#ifndef MARBLE_HOSTIPRUNNER_H
#define MARBLE_HOSTIPRUNNER_H
#include "SearchRunner.h"
#include <QString>
#include <QHostInfo>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
class QNetworkReply;
namespace Marble
{
class HostipRunner : public SearchRunner
{
Q_OBJECT
public:
- explicit HostipRunner(QObject *parent = 0);
+ explicit HostipRunner(QObject *parent = nullptr);
~HostipRunner() override;
private Q_SLOTS:
void get();
// Http request with hostip.info done
void slotRequestFinished( QNetworkReply* );
// IP address lookup finished
void slotLookupFinished(const QHostInfo &host);
// No results (or an error)
void slotNoResults();
void search( const QString &searchTerm, const GeoDataLatLonBox &preferred ) override;
private:
QHostInfo m_hostInfo;
QNetworkAccessManager m_networkAccessManager;
QNetworkRequest m_request;
};
}
#endif
diff --git a/src/plugins/runner/json/JsonParser.cpp b/src/plugins/runner/json/JsonParser.cpp
index aff1ac1df..3fcc5bed5 100644
--- a/src/plugins/runner/json/JsonParser.cpp
+++ b/src/plugins/runner/json/JsonParser.cpp
@@ -1,317 +1,317 @@
/*
This file is part of the Marble Virtual Globe.
This program is free software licensed under the GNU LGPL. You can
find a copy of this license in LICENSE.txt in the top directory of
the source code.
Copyright 2013 Ander Pijoan <ander.pijoan@deusto.es>
*/
#include "JsonParser.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPolygon.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPoint.h"
#include "MarbleDebug.h"
#include "StyleBuilder.h"
#include "osm/OsmPlacemarkData.h"
#include <QIODevice>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
namespace Marble {
-JsonParser::JsonParser() : m_document( 0 )
+JsonParser::JsonParser() : m_document( nullptr )
{
}
JsonParser::~JsonParser()
{
delete m_document;
}
GeoDataDocument *JsonParser::releaseDocument()
{
GeoDataDocument* document = m_document;
- m_document = 0;
+ m_document = nullptr;
return document;
}
bool JsonParser::read( QIODevice* device )
{
// Assert previous document got released.
delete m_document;
m_document = new GeoDataDocument;
Q_ASSERT( m_document );
// Read file data
QJsonParseError error;
const QJsonDocument jsonDoc = QJsonDocument::fromJson(device->readAll(), &error);
if (jsonDoc.isNull()) {
qDebug() << "Error parsing GeoJSON : " << error.errorString();
return false;
}
// Start parsing
const QJsonValue featuresValue = jsonDoc.object().value(QStringLiteral("features"));
// In GeoJSON format, geometries are stored in features, so we iterate on features
if (featuresValue.isArray()) {
const QJsonArray featureArray = featuresValue.toArray();
// Parse each feature
for (int featureIndex = 0; featureIndex < featureArray.size(); ++featureIndex) {
const QJsonObject featureObject = featureArray[featureIndex].toObject();
// Check if the feature contains a geometry
const QJsonValue geometryValue = featureObject.value(QStringLiteral("geometry"));
if (geometryValue.isObject()) {
const QJsonObject geometryObject = geometryValue.toObject();
// Variables for creating the geometry
QList<GeoDataGeometry*> geometryList;
QList<GeoDataPlacemark*> placemarkList;
// Create the different geometry types
const QString geometryType = geometryObject.value(QStringLiteral("type")).toString().toUpper();
if (geometryType == QLatin1String("POLYGON")) {
// Check first that there are coordinates
const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
if (coordinatesValue.isArray()) {
const QJsonArray coordinateArray = coordinatesValue.toArray();
GeoDataPolygon * geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );
// Coordinates first array will be the outer boundary, if there are more
// positions those will be inner holes
for (int ringIndex = 0 ; ringIndex < coordinateArray.size(); ++ringIndex) {
const QJsonArray ringArray = coordinateArray[ringIndex].toArray();
GeoDataLinearRing linearRing;
for (int coordinatePairIndex = 0; coordinatePairIndex < ringArray.size(); ++coordinatePairIndex) {
const QJsonArray coordinatePairArray = ringArray[coordinatePairIndex].toArray();
const qreal longitude = coordinatePairArray.at(0).toDouble();
const qreal latitude = coordinatePairArray.at(1).toDouble();
linearRing.append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
}
// Outer ring
if (ringIndex == 0) {
geom->setOuterBoundary( linearRing );
}
// Inner holes
else {
geom->appendInnerBoundary( linearRing );
}
}
geometryList.append( geom );
}
} else if (geometryType == QLatin1String("MULTIPOLYGON")) {
// Check first that there are coordinates
const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
if (coordinatesValue.isArray()) {
const QJsonArray coordinateArray = coordinatesValue.toArray();
for (int polygonIndex = 0; polygonIndex < coordinateArray.size(); ++polygonIndex) {
const QJsonArray polygonArray = coordinateArray[polygonIndex].toArray();
GeoDataPolygon * geom = new GeoDataPolygon( RespectLatitudeCircle | Tessellate );
// Coordinates first array will be the outer boundary, if there are more
// positions those will be inner holes
for (int ringIndex = 0 ; ringIndex < polygonArray.size(); ++ringIndex) {
const QJsonArray ringArray = polygonArray[ringIndex].toArray();
GeoDataLinearRing linearRing;
for (int coordinatePairIndex = 0; coordinatePairIndex < ringArray.size(); ++coordinatePairIndex) {
const QJsonArray coordinatePairArray = ringArray[coordinatePairIndex].toArray();
const qreal longitude = coordinatePairArray.at(0).toDouble();
const qreal latitude = coordinatePairArray.at(1).toDouble();
linearRing.append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
}
// Outer ring
if (ringIndex == 0) {
geom->setOuterBoundary( linearRing );
}
// Inner holes
else {
geom->appendInnerBoundary( linearRing );
}
}
geometryList.append( geom );
}
}
} else if (geometryType == QLatin1String("LINESTRING")) {
// Check first that there are coordinates
const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
if (coordinatesValue.isArray()) {
const QJsonArray coordinateArray = coordinatesValue.toArray();
GeoDataLineString * geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );
for (int coordinatePairIndex = 0; coordinatePairIndex < coordinateArray.size(); ++coordinatePairIndex) {
const QJsonArray coordinatePairArray = coordinateArray[coordinatePairIndex].toArray();
const qreal longitude = coordinatePairArray.at(0).toDouble();
const qreal latitude = coordinatePairArray.at(1).toDouble();
geom->append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
}
geometryList.append( geom );
}
} else if (geometryType == QLatin1String("MULTILINESTRING")) {
// Check first that there are coordinates
const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
if (coordinatesValue.isArray()) {
const QJsonArray coordinateArray = coordinatesValue.toArray();
for (int lineStringIndex = 0; lineStringIndex < coordinateArray.size(); ++lineStringIndex) {
const QJsonArray lineStringArray = coordinateArray[lineStringIndex].toArray();
GeoDataLineString * geom = new GeoDataLineString( RespectLatitudeCircle | Tessellate );
for (int coordinatePairIndex = 0; coordinatePairIndex < lineStringArray.size(); ++coordinatePairIndex) {
const QJsonArray coordinatePairArray = lineStringArray[coordinatePairIndex].toArray();
const qreal longitude = coordinatePairArray.at(0).toDouble();
const qreal latitude = coordinatePairArray.at(1).toDouble();
geom->append( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
}
geometryList.append( geom );
}
}
} else if (geometryType == QLatin1String("POINT")) {
// Check first that there are coordinates
const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
if (coordinatesValue.isArray()) {
const QJsonArray coordinatePairArray = coordinatesValue.toArray();
GeoDataPoint * geom = new GeoDataPoint();
const qreal longitude = coordinatePairArray.at(0).toDouble();
const qreal latitude = coordinatePairArray.at(1).toDouble();
geom->setCoordinates( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
geometryList.append( geom );
}
} else if (geometryType == QLatin1String("MULTIPOINT")) {
// Check first that there are coordinates
const QJsonValue coordinatesValue = geometryObject.value(QStringLiteral("coordinates"));
if (coordinatesValue.isArray()) {
const QJsonArray coordinateArray = coordinatesValue.toArray();
for (int pointIndex = 0; pointIndex < coordinateArray.size(); ++pointIndex) {
const QJsonArray coordinatePairArray = coordinateArray[pointIndex].toArray();
GeoDataPoint * geom = new GeoDataPoint();
const qreal longitude = coordinatePairArray.at(0).toDouble();
const qreal latitude = coordinatePairArray.at(1).toDouble();
geom->setCoordinates( GeoDataCoordinates( longitude , latitude , 0 , GeoDataCoordinates::Degree ) );
geometryList.append( geom );
}
}
}
// Parse the features properties
const QJsonValue propertiesValue = featureObject.value(QStringLiteral("properties"));
if (!geometryList.isEmpty() && propertiesValue.isObject()) {
const QJsonObject propertiesObject = propertiesValue.toObject();
// First create a placemark for each geometry, there could be multi geometries
// that are translated into more than one geometry/placemark
for ( int numberGeometries = 0 ; numberGeometries < geometryList.length() ; numberGeometries++ ) {
GeoDataPlacemark * placemark = new GeoDataPlacemark();
placemarkList.append( placemark );
}
OsmPlacemarkData osmData;
QJsonObject::ConstIterator it = propertiesObject.begin();
const QJsonObject::ConstIterator end = propertiesObject.end();
for ( ; it != end; ++it) {
if (it.value().isObject() || it.value().isArray()) {
qDebug() << "Skipping property, values of type arrays and objects not supported:" << it.key();
continue;
}
// pass value through QVariant to also get bool & numbers
osmData.addTag(it.key(), it.value().toVariant().toString());
}
// If the property read, is the features name
const auto tagIter = osmData.findTag(QStringLiteral("name"));
if (tagIter != osmData.tagsEnd()) {
const QString& name = tagIter.value();
for (int pl = 0 ; pl < placemarkList.length(); ++pl) {
placemarkList.at(pl)->setName(name);
}
}
const GeoDataPlacemark::GeoDataVisualCategory category = StyleBuilder::determineVisualCategory(osmData);
if (category != GeoDataPlacemark::None) {
// Add the visual category to all the placemarks
for (int pl = 0 ; pl < placemarkList.length(); ++pl) {
placemarkList.at(pl)->setVisualCategory(category);
placemarkList.at(pl)->setOsmData(osmData);
}
}
}
// Add the geometry to the document
if ( geometryList.length() == placemarkList.length() ) {
while( placemarkList.length() > 0 ) {
GeoDataPlacemark * placemark = placemarkList.last();
placemarkList.pop_back();
GeoDataGeometry * geom = geometryList.last();
geometryList.pop_back();
placemark->setGeometry( geom );
placemark->setVisible( true );
m_document->append( placemark );
}
}
// If geometries or placemarks missing inside the lists, delete them
qDeleteAll( geometryList.begin(), geometryList.end() );
geometryList.clear();
qDeleteAll( placemarkList.begin(), placemarkList.end() );
placemarkList.clear();
}
}
}
return true;
}
}
diff --git a/src/plugins/runner/json/JsonPlugin.h b/src/plugins/runner/json/JsonPlugin.h
index a4c1b4bdf..3241f81f7 100644
--- a/src/plugins/runner/json/JsonPlugin.h
+++ b/src/plugins/runner/json/JsonPlugin.h
@@ -1,49 +1,49 @@
/*
This file is part of the Marble Virtual Globe.
This program is free software licensed under the GNU LGPL. You can
find a copy of this license in LICENSE.txt in the top directory of
the source code.
Copyright 2013 Ander Pijoan <ander.pijoan@deusto.es>
*/
#ifndef MARBLE_JSONPLUGIN_H
#define MARBLE_JSONPLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class JsonPlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.JsonPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit JsonPlugin( QObject *parent = 0 );
+ explicit JsonPlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif
diff --git a/src/plugins/runner/json/JsonRunner.h b/src/plugins/runner/json/JsonRunner.h
index 224cbce09..dfcf35753 100644
--- a/src/plugins/runner/json/JsonRunner.h
+++ b/src/plugins/runner/json/JsonRunner.h
@@ -1,29 +1,29 @@
/*
This file is part of the Marble Virtual Globe.
This program is free software licensed under the GNU LGPL. You can
find a copy of this license in LICENSE.txt in the top directory of
the source code.
Copyright 2013 Ander Pijoan <ander.pijoan@deusto.es>
*/
#ifndef MARBLE_JSONRUNNER_H
#define MARBLE_JSONRUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class JsonRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit JsonRunner(QObject *parent = 0);
+ explicit JsonRunner(QObject *parent = nullptr);
~JsonRunner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLE_JSONRUNNER_H
diff --git a/src/plugins/runner/kml/KmlPlugin.h b/src/plugins/runner/kml/KmlPlugin.h
index d2f51f7cd..4010316f3 100644
--- a/src/plugins/runner/kml/KmlPlugin.h
+++ b/src/plugins/runner/kml/KmlPlugin.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEKMLPLUGIN_H
#define MARBLEKMLPLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class KmlPlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.KmlPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit KmlPlugin( QObject *parent = 0 );
+ explicit KmlPlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLEKMLPLUGIN_H
diff --git a/src/plugins/runner/kml/KmlRunner.h b/src/plugins/runner/kml/KmlRunner.h
index 305686fd0..727599665 100644
--- a/src/plugins/runner/kml/KmlRunner.h
+++ b/src/plugins/runner/kml/KmlRunner.h
@@ -1,28 +1,28 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEKMLRUNNER_H
#define MARBLEKMLRUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class KmlRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit KmlRunner(QObject *parent = 0);
+ explicit KmlRunner(QObject *parent = nullptr);
~KmlRunner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLEKMLRUNNER_H
diff --git a/src/plugins/runner/latlon/LatLonPlugin.h b/src/plugins/runner/latlon/LatLonPlugin.h
index bfe452fde..1caffdef4 100644
--- a/src/plugins/runner/latlon/LatLonPlugin.h
+++ b/src/plugins/runner/latlon/LatLonPlugin.h
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_LATLONPLUGIN_H
#define MARBLE_LATLONPLUGIN_H
#include "SearchRunnerPlugin.h"
namespace Marble
{
class LatLonPlugin : public SearchRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.LatLonPlugin")
Q_INTERFACES( Marble::SearchRunnerPlugin )
public:
- explicit LatLonPlugin( QObject *parent = 0 );
+ explicit LatLonPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
SearchRunner* newRunner() const override;
};
}
#endif
diff --git a/src/plugins/runner/latlon/LatLonRunner.h b/src/plugins/runner/latlon/LatLonRunner.h
index c6b7780fd..8e90a1387 100644
--- a/src/plugins/runner/latlon/LatLonRunner.h
+++ b/src/plugins/runner/latlon/LatLonRunner.h
@@ -1,32 +1,32 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008 Henry de Valence <hdevalence@gmail.com>
#ifndef MARBLE_LATLONRUNNER_H
#define MARBLE_LATLONRUNNER_H
#include "SearchRunner.h"
#include <QString>
namespace Marble
{
class LatLonRunner : public SearchRunner
{
Q_OBJECT
public:
- explicit LatLonRunner(QObject *parent = 0);
+ explicit LatLonRunner(QObject *parent = nullptr);
~LatLonRunner() override;
void search( const QString &searchTerm, const GeoDataLatLonBox &preferred ) override;
};
}
#endif
diff --git a/src/plugins/runner/local-osm-search/LocalOsmSearchPlugin.h b/src/plugins/runner/local-osm-search/LocalOsmSearchPlugin.h
index 4798ebef5..109dd955d 100644
--- a/src/plugins/runner/local-osm-search/LocalOsmSearchPlugin.h
+++ b/src/plugins/runner/local-osm-search/LocalOsmSearchPlugin.h
@@ -1,65 +1,65 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_LOCALOSMSEARCHPLUGIN_H
#define MARBLE_LOCALOSMSEARCHPLUGIN_H
#include "SearchRunnerPlugin.h"
#include "OsmDatabase.h"
#include <QFileSystemWatcher>
namespace Marble
{
class LocalOsmSearchPlugin : public SearchRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.LocalOsmSearchPlugin")
Q_INTERFACES( Marble::SearchRunnerPlugin )
public:
- explicit LocalOsmSearchPlugin( QObject *parent = 0 );
+ explicit LocalOsmSearchPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
SearchRunner* newRunner() const override;
private Q_SLOTS:
void updateDirectory( const QString &directory );
void updateFile( const QString &directory );
private:
void addDatabaseDirectory( const QString &path );
void updateDatabase();
QStringList m_databaseFiles;
QFileSystemWatcher m_watcher;
};
}
#endif
diff --git a/src/plugins/runner/local-osm-search/LocalOsmSearchRunner.h b/src/plugins/runner/local-osm-search/LocalOsmSearchRunner.h
index fc724660f..7ddc00455 100644
--- a/src/plugins/runner/local-osm-search/LocalOsmSearchRunner.h
+++ b/src/plugins/runner/local-osm-search/LocalOsmSearchRunner.h
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_LOCALOSMSEARCHRUNNER_H
#define MARBLE_LOCALOSMSEARCHRUNNER_H
#include "SearchRunner.h"
#include "OsmDatabase.h"
#include "OsmPlacemark.h"
#include "GeoDataPlacemark.h"
#include <QMap>
namespace Marble
{
class LocalOsmSearchRunner : public SearchRunner
{
Q_OBJECT
public:
- explicit LocalOsmSearchRunner( const QStringList &databaseFiles, QObject *parent = 0 );
+ explicit LocalOsmSearchRunner( const QStringList &databaseFiles, QObject *parent = nullptr );
~LocalOsmSearchRunner() override;
void search( const QString &searchTerm, const GeoDataLatLonBox &preferred ) override;
private:
OsmDatabase m_database;
static QMap<OsmPlacemark::OsmCategory, GeoDataPlacemark::GeoDataVisualCategory> m_categoryMap;
};
}
#endif
diff --git a/src/plugins/runner/localdatabase/LocalDatabasePlugin.h b/src/plugins/runner/localdatabase/LocalDatabasePlugin.h
index d3f8805e6..fb6a0745b 100644
--- a/src/plugins/runner/localdatabase/LocalDatabasePlugin.h
+++ b/src/plugins/runner/localdatabase/LocalDatabasePlugin.h
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_LOCALDATABASEPLUGIN_H
#define MARBLE_LOCALDATABASEPLUGIN_H
#include "SearchRunnerPlugin.h"
namespace Marble
{
class LocalDatabasePlugin : public SearchRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.LocalDatabasePlugin")
Q_INTERFACES( Marble::SearchRunnerPlugin )
public:
- explicit LocalDatabasePlugin(QObject *parent = 0);
+ explicit LocalDatabasePlugin(QObject *parent = nullptr);
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
SearchRunner* newRunner() const override;
};
}
#endif
diff --git a/src/plugins/runner/localdatabase/LocalDatabaseRunner.h b/src/plugins/runner/localdatabase/LocalDatabaseRunner.h
index c67d93001..8b2dc7e43 100644
--- a/src/plugins/runner/localdatabase/LocalDatabaseRunner.h
+++ b/src/plugins/runner/localdatabase/LocalDatabaseRunner.h
@@ -1,31 +1,31 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Torsten Rahn <rahn@kde.org>
//
#ifndef MARBLE_LOCALDATABASERUNNER_H
#define MARBLE_LOCALDATABASERUNNER_H
#include "SearchRunner.h"
namespace Marble
{
class LocalDatabaseRunner : public SearchRunner
{
Q_OBJECT
public:
- explicit LocalDatabaseRunner(QObject *parent = 0);
+ explicit LocalDatabaseRunner(QObject *parent = nullptr);
~LocalDatabaseRunner() override;
void search( const QString &searchTerm, const GeoDataLatLonBox &preferred ) override;
};
}
#endif
diff --git a/src/plugins/runner/log/LogPlugin.h b/src/plugins/runner/log/LogPlugin.h
index dd46454f6..dbece5a04 100644
--- a/src/plugins/runner/log/LogPlugin.h
+++ b/src/plugins/runner/log/LogPlugin.h
@@ -1,48 +1,48 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
#ifndef MARBLE_LOGFILE_PLUGIN_H
#define MARBLE_LOGFILE_PLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class LogfilePlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.LogPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit LogfilePlugin( QObject *parent = 0 );
+ explicit LogfilePlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLE_LOGFILE_PLUGIN_H
diff --git a/src/plugins/runner/log/LogRunner.cpp b/src/plugins/runner/log/LogRunner.cpp
index 56b85183a..6766c02d6 100644
--- a/src/plugins/runner/log/LogRunner.cpp
+++ b/src/plugins/runner/log/LogRunner.cpp
@@ -1,102 +1,102 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
#include "LogRunner.h"
#include "GeoDataDocument.h"
#include "GeoDataLineString.h"
#include "GeoDataPlacemark.h"
#include "MarbleDebug.h"
#include <QFile>
namespace Marble
{
LogRunner::LogRunner( QObject *parent ) :
ParsingRunner( parent )
{
}
LogRunner::~LogRunner()
{
}
GeoDataDocument *LogRunner::parseFile(const QString &fileName, DocumentRole role, QString &errorString)
{
QFile file( fileName );
if ( !file.exists() ) {
errorString = QStringLiteral("File %1 does not exist").arg(fileName);
mDebug() << errorString;
return nullptr;
}
file.open( QIODevice::ReadOnly );
QTextStream stream( &file );
GeoDataLineString *const track = new GeoDataLineString;
GeoDataPlacemark *const placemark = new GeoDataPlacemark;
placemark->setGeometry( track );
GeoDataDocument *document = new GeoDataDocument();
document->setDocumentRole( role );
document->append( placemark );
int count = 0;
bool error = false;
while( !stream.atEnd() || error ){
const QString line = stream.readLine();
const QStringList list = line.split(QLatin1Char(','));
if ( list.size() != 7 ) {
mDebug() << Q_FUNC_INFO << "Aborting due to error in line" << count << ". Line was:" << line;
error = true;
break;
}
const QString strLat = list[0];
const QString strLon = list[1];
const QString strElevation = list[2];
const QString strSpeed = list[3];
const QString strCourse = list[4];
const QString strHdop = list[5];
const QString strTime = list[6];
if ( strLat.isEmpty() || strLon.isEmpty() || strElevation.isEmpty() ) {
continue;
}
bool okLat, okLon, okAlt = false;
const qreal lat = strLat.toDouble( &okLat );
const qreal lon = strLon.toDouble( &okLon );
const qreal alt = strElevation.toDouble( &okAlt );
if ( !okLat || !okLon || !okAlt ) {
continue;
}
GeoDataCoordinates coord( lon, lat, alt, GeoDataCoordinates::Degree );
track->append( coord );
}
file.close();
if ( track->size() == 0 || error ) {
delete document;
- document = 0;
+ document = nullptr;
return nullptr;
}
document->setFileName( fileName );
return document;
}
}
#include "moc_LogRunner.cpp"
diff --git a/src/plugins/runner/log/LogRunner.h b/src/plugins/runner/log/LogRunner.h
index 9c8a3c8af..594b09e83 100644
--- a/src/plugins/runner/log/LogRunner.h
+++ b/src/plugins/runner/log/LogRunner.h
@@ -1,31 +1,31 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
#ifndef MARBLE_LOGFILE_RUNNER_H
#define MARBLE_LOGFILE_RUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class LogRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit LogRunner( QObject *parent = 0 );
+ explicit LogRunner( QObject *parent = nullptr );
~LogRunner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLE_LOGFILE_RUNNER_H
diff --git a/src/plugins/runner/mapquest/MapQuestPlugin.h b/src/plugins/runner/mapquest/MapQuestPlugin.h
index b097251ae..5ba463e7f 100644
--- a/src/plugins/runner/mapquest/MapQuestPlugin.h
+++ b/src/plugins/runner/mapquest/MapQuestPlugin.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_MAPQUESTPLUGIN_H
#define MARBLE_MAPQUESTPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class MapQuestPlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.MapQuestPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
- explicit MapQuestPlugin( QObject *parent = 0 );
+ explicit MapQuestPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
RoutingRunner *newRunner() const override;
ConfigWidget* configWidget() override;
bool supportsTemplate( RoutingProfilesModel::ProfileTemplate profileTemplate ) const override;
QHash<QString, QVariant> templateSettings( RoutingProfilesModel::ProfileTemplate profileTemplate ) const override;
};
}
#endif
diff --git a/src/plugins/runner/mapquest/MapQuestRunner.cpp b/src/plugins/runner/mapquest/MapQuestRunner.cpp
index 99e2a44b3..c9058aa6b 100644
--- a/src/plugins/runner/mapquest/MapQuestRunner.cpp
+++ b/src/plugins/runner/mapquest/MapQuestRunner.cpp
@@ -1,308 +1,308 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "MapQuestRunner.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "GeoDataLineString.h"
#include "HttpDownloadManager.h"
#include "routing/Maneuver.h"
#include "routing/RouteRequest.h"
#include <QString>
#include <QUrl>
#include <QTime>
#include <QTimer>
#include <QNetworkReply>
#include <QDomDocument>
#include <QUrlQuery>
namespace Marble
{
MapQuestRunner::MapQuestRunner( QObject *parent ) :
RoutingRunner( parent ),
m_networkAccessManager(),
m_request()
{
connect( &m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(retrieveData(QNetworkReply*)) );
}
MapQuestRunner::~MapQuestRunner()
{
// nothing to do
}
void MapQuestRunner::retrieveRoute( const RouteRequest *route )
{
if ( route->size() < 2 ) {
return;
}
QHash<QString, QVariant> settings = route->routingProfile().pluginSettings()["mapquest"];
if (settings.value(QStringLiteral("appKey")).toString().isEmpty()) {
return;
}
QString url = "http://open.mapquestapi.com/directions/v1/route?callback=renderAdvancedNarrative&outFormat=xml&narrativeType=text&shapeFormat=raw&generalize=0";
GeoDataCoordinates::Unit const degree = GeoDataCoordinates::Degree;
append(&url, "from", QString::number(route->source().latitude(degree), 'f', 6) + QLatin1Char(',') + QString::number(route->source().longitude(degree), 'f', 6));
for ( int i=1; i<route->size(); ++i ) {
append(&url, "to", QString::number(route->at(i).latitude(degree), 'f', 6) + QLatin1Char(',') + QString::number(route->at(i).longitude(degree), 'f', 6));
}
QString const unit = MarbleGlobal::getInstance()->locale()->measurementSystem() == MarbleLocale::MetricSystem ? "k" : "m";
append( &url, "units", unit );
if (settings[QStringLiteral("noMotorways")].toInt()) {
append( &url, "avoids", "Limited Access" );
}
if (settings[QStringLiteral("noTollroads")].toInt()) {
append( &url, "avoids", "Toll road" );
}
if (settings[QStringLiteral("noFerries")].toInt()) {
append( &url, "avoids", "Ferry" );
}
if (!settings[QStringLiteral("preference")].toString().isEmpty()) {
append(&url, QStringLiteral("routeType"), settings[QStringLiteral("preference")].toString());
}
const QString ascendingSetting = settings[QStringLiteral("ascending")].toString();
const QString descendingSetting = settings[QStringLiteral("descending")].toString();
if (!ascendingSetting.isEmpty() && !descendingSetting.isEmpty()) {
if (ascendingSetting == QLatin1String("AVOID_UP_HILL") &&
descendingSetting == QLatin1String("AVOID_DOWN_HILL")) {
append(&url, QStringLiteral("roadGradeStrategy"), QStringLiteral("AVOID_ALL_HILLS"));
}
else if (ascendingSetting == QLatin1String("FAVOR_UP_HILL") &&
descendingSetting == QLatin1String("FAVOR_DOWN_HILL")) {
append(&url, QStringLiteral("roadGradeStrategy"), QStringLiteral("FAVOR_ALL_HILLS"));
}
else if (ascendingSetting == QLatin1String("DEFAULT_STRATEGY") &&
descendingSetting == QLatin1String("DEFAULT_STRATEGY")) {
append(&url, QStringLiteral("roadGradeStrategy"), QStringLiteral("DEFAULT_STRATEGY"));
}
else if (ascendingSetting == QLatin1String("DEFAULT_STRATEGY")) {
append(&url, QStringLiteral("roadGradeStrategy"), descendingSetting);
}
else if (descendingSetting == QLatin1String("DEFAULT_STRATEGY")) {
append(&url, QStringLiteral("roadGradeStrategy"), ascendingSetting);
}
else if (descendingSetting == QLatin1String("AVOID_DOWN_HILL")) {
append(&url, QStringLiteral("roadGradeStrategy"), descendingSetting);
}
else if (ascendingSetting == QLatin1String("AVOID_UP_HILL")) {
append(&url, QStringLiteral("roadGradeStrategy"), ascendingSetting);
}
}
QUrl qurl(url);
// FIXME: verify that this works with special characters.
QUrlQuery urlQuery;
urlQuery.addQueryItem(QStringLiteral("key"), settings.value(QStringLiteral("appKey")).toByteArray());
qurl.setQuery(urlQuery);
m_request.setUrl( qurl );
m_request.setRawHeader( "User-Agent", HttpDownloadManager::userAgent( "Browser", "MapQuestRunner" ) );
QEventLoop eventLoop;
QTimer timer;
timer.setSingleShot( true );
timer.setInterval( 15000 );
connect( &timer, SIGNAL(timeout()),
&eventLoop, SLOT(quit()));
connect( this, SIGNAL(routeCalculated(GeoDataDocument*)),
&eventLoop, SLOT(quit()) );
// @todo FIXME Must currently be done in the main thread, see bug 257376
QTimer::singleShot( 0, this, SLOT(get()) );
timer.start();
eventLoop.exec();
}
void MapQuestRunner::get()
{
QNetworkReply *reply = m_networkAccessManager.get( m_request );
connect( reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)), Qt::DirectConnection );
}
void MapQuestRunner::retrieveData( QNetworkReply *reply )
{
if ( reply->isFinished() ) {
QByteArray data = reply->readAll();
reply->deleteLater();
//mDebug() << "Download completed: " << data;
GeoDataDocument* document = parse( data );
if ( !document ) {
mDebug() << "Failed to parse the downloaded route data" << data;
}
emit routeCalculated( document );
}
}
void MapQuestRunner::handleError( QNetworkReply::NetworkError error )
{
mDebug() << " Error when retrieving mapquest.org route: " << error;
}
void MapQuestRunner::append(QString *input, const QString &key, const QString &value)
{
*input += QLatin1Char('&') + key + QLatin1Char('=') + value;
}
int MapQuestRunner::maneuverType( int mapQuestId )
{
/** @todo FIXME: review 10, 11 */
switch( mapQuestId ) {
case 0: return Maneuver::Straight ; // straight
case 1: return Maneuver::SlightRight ; // slight right
case 2: return Maneuver::Right ; // right
case 3: return Maneuver::SharpRight ; // sharp right
case 4: return Maneuver::TurnAround ; // reverse
case 5: return Maneuver::SharpLeft ; // sharp left
case 6: return Maneuver::Left ; // left
case 7: return Maneuver::SlightLeft ; // slight left
case 8: return Maneuver::TurnAround ; // right u-turn
case 9: return Maneuver::TurnAround ; // left u-turn
case 10: return Maneuver::Merge ; // right merge
case 11: return Maneuver::Merge ; // left merge
case 12: return Maneuver::Merge ; // right on ramp
case 13: return Maneuver::Merge ; // left on ramp
case 14: return Maneuver::ExitRight ; // right off ramp
case 15: return Maneuver::ExitLeft ; // left off ramp
case 16: return Maneuver::Right ; // right fork
case 17: return Maneuver::Left ; // left fork
case 18: return Maneuver::Continue ; // straight fork
}
return Maneuver::Unknown;
}
GeoDataDocument* MapQuestRunner::parse( const QByteArray &content ) const
{
QDomDocument xml;
if ( !xml.setContent( content ) ) {
mDebug() << "Cannot parse xml file with routing instructions.";
- return 0;
+ return nullptr;
}
// mDebug() << xml.toString(2);
QDomElement root = xml.documentElement();
GeoDataDocument* result = new GeoDataDocument();
result->setName(QStringLiteral("MapQuest"));
GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
routePlacemark->setName(QStringLiteral("Route"));
GeoDataLineString* routeWaypoints = new GeoDataLineString;
QDomNodeList shapePoints = root.elementsByTagName(QStringLiteral("shapePoints"));
if ( shapePoints.size() == 1 ) {
QDomNodeList geometry = shapePoints.at(0).toElement().elementsByTagName(QStringLiteral("latLng"));
for ( int i=0; i<geometry.size(); ++i ) {
double const lat = geometry.item(i).namedItem(QStringLiteral("lat")).toElement().text().toDouble();
double const lon = geometry.item(i).namedItem(QStringLiteral("lng")).toElement().text().toDouble();
GeoDataCoordinates const position( lon, lat, 0.0, GeoDataCoordinates::Degree );
routeWaypoints->append( position );
}
}
routePlacemark->setGeometry( routeWaypoints );
QTime time;
time = time.addSecs(root.elementsByTagName(QStringLiteral("time")).at(0).toElement().text().toInt());
qreal length = routeWaypoints->length( EARTH_RADIUS );
const QString name = nameString( "MQ", length, time );
const GeoDataExtendedData data = routeData( length, time );
routePlacemark->setExtendedData( data );
result->setName( name );
result->append( routePlacemark );
QMap<int,int> mapping;
QDomNodeList maneuvers = root.elementsByTagName(QStringLiteral("maneuverIndexes"));
if ( maneuvers.size() == 1 ) {
maneuvers = maneuvers.at( 0 ).childNodes();
for ( int i=0; i<maneuvers.size(); ++i ) {
mapping[i] = maneuvers.at( i ).toElement().text().toInt();
if ( mapping[i] == routeWaypoints->size() ) {
--mapping[i];
}
}
}
QDomNodeList instructions = root.elementsByTagName(QStringLiteral("maneuver"));
unsigned int const lastInstruction = qMax<int>( 0, instructions.length()-1 ); // ignore the last 'Welcome to xy' instruction
for ( unsigned int i = 0; i < lastInstruction; ++i ) {
QDomElement node = instructions.item( i ).toElement();
QDomNodeList maneuver = node.elementsByTagName(QStringLiteral("turnType"));
QDomNodeList textNodes = node.elementsByTagName(QStringLiteral("narrative"));
QDomNodeList points = node.elementsByTagName(QStringLiteral("startPoint"));
QDomNodeList streets = node.elementsByTagName(QStringLiteral("streets"));
Q_ASSERT( mapping.contains( i ) );
if ( textNodes.size() == 1 && maneuver.size() == 1 && points.size() == 1 && mapping.contains( i ) ) {
GeoDataPlacemark* instruction = new GeoDataPlacemark;
instruction->setName( textNodes.at( 0 ).toElement().text() );
GeoDataExtendedData extendedData;
GeoDataData turnType;
turnType.setName(QStringLiteral("turnType"));
turnType.setValue( maneuverType( maneuver.at( 0 ).toElement().text().toInt() ) );
extendedData.addValue( turnType );
if ( streets.size() == 1 ) {
GeoDataData roadName;
roadName.setName(QStringLiteral("roadName"));
roadName.setValue( streets.at( 0 ).toElement().text() );
extendedData.addValue( roadName );
}
instruction->setExtendedData( extendedData );
int const start = mapping[i];
int const end = mapping.contains(i+1) ? mapping[i+1] : routeWaypoints->size()-1;
if ( start >= 0 && start < routeWaypoints->size() && end < routeWaypoints->size() ) {
instruction->setName( textNodes.item( 0 ).toElement().text() );
GeoDataLineString *lineString = new GeoDataLineString;
for ( int j=start; j<=end; ++j ) {
*lineString << GeoDataCoordinates( routeWaypoints->at( j ).longitude(), routeWaypoints->at( j ).latitude() );
}
if ( !lineString->isEmpty() ) {
instruction->setGeometry( lineString );
result->append( instruction );
}
}
}
}
if ( routeWaypoints->size() < 1 ) {
delete result;
- result = 0;
+ result = nullptr;
}
return result;
}
} // namespace Marble
#include "moc_MapQuestRunner.cpp"
diff --git a/src/plugins/runner/mapquest/MapQuestRunner.h b/src/plugins/runner/mapquest/MapQuestRunner.h
index 4e18bb02a..81f9db51d 100644
--- a/src/plugins/runner/mapquest/MapQuestRunner.h
+++ b/src/plugins/runner/mapquest/MapQuestRunner.h
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OSMMAPQUESTRUNNER_H
#define MARBLE_OSMMAPQUESTRUNNER_H
#include "RoutingRunner.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
namespace Marble
{
class MapQuestRunner : public RoutingRunner
{
Q_OBJECT
public:
- explicit MapQuestRunner(QObject *parent = 0);
+ explicit MapQuestRunner(QObject *parent = nullptr);
~MapQuestRunner() override;
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
private Q_SLOTS:
void get();
/** Route data was retrieved via http */
void retrieveData( QNetworkReply *reply );
/** A network error occurred */
void handleError( QNetworkReply::NetworkError );
private:
static void append( QString* input, const QString &key, const QString &value );
static int maneuverType( int mapQuestId );
GeoDataDocument* parse( const QByteArray &input ) const;
QNetworkAccessManager m_networkAccessManager;
QNetworkRequest m_request;
};
}
#endif
diff --git a/src/plugins/runner/monav/MonavConfigWidget.cpp b/src/plugins/runner/monav/MonavConfigWidget.cpp
index 305cc6478..c0a03c216 100644
--- a/src/plugins/runner/monav/MonavConfigWidget.cpp
+++ b/src/plugins/runner/monav/MonavConfigWidget.cpp
@@ -1,690 +1,690 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "MonavConfigWidget.h"
#include "MonavMapsModel.h"
#include "MonavPlugin.h"
#include "MarbleDirs.h"
#include "MarbleDebug.h"
#include <QFile>
#include <QProcess>
#include <QSignalMapper>
#include <QPushButton>
#include <QShowEvent>
#include <QSortFilterProxyModel>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDomDocument>
namespace Marble
{
class MonavStuffEntry
{
public:
void setPayload( const QString &payload );
QString payload() const;
void setName( const QString &name );
QString name() const;
bool isValid() const;
QString continent() const;
QString state() const;
QString region() const;
QString transport() const;
private:
QString m_payload;
QString m_name;
QString m_continent;
QString m_state;
QString m_region;
QString m_transport;
};
class MonavConfigWidgetPrivate
{
public:
MonavConfigWidget* m_parent;
MonavPlugin* m_plugin;
QNetworkAccessManager m_networkAccessManager;
QNetworkReply* m_currentReply;
QProcess* m_unpackProcess;
QSortFilterProxyModel* m_filteredModel;
MonavMapsModel* m_mapsModel;
bool m_initialized;
QSignalMapper m_removeMapSignalMapper;
QSignalMapper m_upgradeMapSignalMapper;
QVector<MonavStuffEntry> m_remoteMaps;
QMap<QString, QString> m_remoteVersions;
QString m_currentDownload;
QFile m_currentFile;
QString m_transport;
MonavConfigWidgetPrivate( MonavConfigWidget* parent, MonavPlugin* plugin );
void parseNewStuff( const QByteArray &data );
bool updateContinents( QComboBox* comboBox );
bool updateStates( const QString &continent, QComboBox* comboBox );
bool updateRegions( const QString &continent, const QString &state, QComboBox* comboBox );
MonavStuffEntry map( const QString &continent, const QString &state, const QString &region ) const;
void install();
void installMap();
void updateInstalledMapsView();
void updateInstalledMapsViewButtons();
void updateTransportPreference();
static bool canExecute( const QString &executable );
void setBusy( bool busy, const QString &message = QString() ) const;
private:
static bool fillComboBox( QStringList items, QComboBox* comboBox );
};
void MonavStuffEntry::setPayload( const QString &payload )
{
m_payload = payload;
}
QString MonavStuffEntry::payload() const
{
return m_payload;
}
void MonavStuffEntry::setName( const QString &name )
{
m_name = name;
QStringList parsed = name.split( QLatin1Char( '/' ) );
int size = parsed.size();
m_continent = size > 0 ? parsed.at( 0 ).trimmed() : QString();
m_state = size > 1 ? parsed.at( 1 ).trimmed() : QString();
m_region = size > 2 ? parsed.at( 2 ).trimmed() : QString();
m_transport = "Motorcar"; // No i18n
if ( size > 1 ) {
QString last = parsed.last().trimmed();
QRegExp regexp("([^(]+)\\(([^)]+)\\)");
if ( regexp.indexIn( last ) >= 0 ) {
QStringList matches = regexp.capturedTexts();
if ( matches.size() == 3 ) {
m_transport = matches.at( 2 ).trimmed();
if ( size > 2 ) {
m_region = matches.at( 1 ).trimmed();
} else {
m_state = matches.at( 1 ).trimmed();
}
}
}
}
}
QString MonavStuffEntry::name() const
{
return m_name;
}
QString MonavStuffEntry::continent() const
{
return m_continent;
}
QString MonavStuffEntry::state() const
{
return m_state;
}
QString MonavStuffEntry::region() const
{
return m_region;
}
QString MonavStuffEntry::transport() const
{
return m_transport;
}
bool MonavStuffEntry::isValid() const
{
return !m_continent.isEmpty() && !m_state.isEmpty() && m_payload.startsWith( QLatin1String( "http://" ) );
}
MonavConfigWidgetPrivate::MonavConfigWidgetPrivate( MonavConfigWidget* parent, MonavPlugin* plugin ) :
- m_parent( parent ), m_plugin( plugin ), m_networkAccessManager( 0 ),
- m_currentReply( 0 ), m_unpackProcess( 0 ), m_filteredModel( new QSortFilterProxyModel( parent) ),
- m_mapsModel( 0 ), m_initialized( false )
+ m_parent( parent ), m_plugin( plugin ), m_networkAccessManager( nullptr ),
+ m_currentReply( nullptr ), m_unpackProcess( nullptr ), m_filteredModel( new QSortFilterProxyModel( parent) ),
+ m_mapsModel( nullptr ), m_initialized( false )
{
m_filteredModel->setFilterKeyColumn( 1 );
}
void MonavConfigWidgetPrivate::parseNewStuff( const QByteArray &data )
{
QDomDocument xml;
if ( !xml.setContent( data ) ) {
mDebug() << "Cannot parse xml file " << data;
return;
}
QDomElement root = xml.documentElement();
QDomNodeList items = root.elementsByTagName(QStringLiteral("stuff"));
for (int i=0 ; i < items.length(); ++i ) {
MonavStuffEntry item;
QDomNode node = items.item( i );
QDomNodeList names = node.toElement().elementsByTagName(QStringLiteral("name"));
if ( names.size() == 1 ) {
item.setName( names.at( 0 ).toElement().text() );
}
QString releaseDate;
QDomNodeList dates = node.toElement().elementsByTagName(QStringLiteral("releasedate"));
if ( dates.size() == 1 ) {
releaseDate = dates.at( 0 ).toElement().text();
}
QString filename;
QDomNodeList payloads = node.toElement().elementsByTagName(QStringLiteral("payload"));
if ( payloads.size() == 1 ) {
QString payload = payloads.at( 0 ).toElement().text();
filename = payload.mid(1 + payload.lastIndexOf(QLatin1Char('/')));
item.setPayload( payload );
}
if ( item.isValid() ) {
m_remoteMaps.push_back( item );
if ( !filename.isEmpty() && !releaseDate.isEmpty() ) {
m_remoteVersions[filename] = releaseDate;
}
}
}
m_mapsModel->setInstallableVersions( m_remoteVersions );
updateInstalledMapsViewButtons();
}
bool MonavConfigWidgetPrivate::fillComboBox( QStringList items, QComboBox* comboBox )
{
comboBox->clear();
std::sort( items.begin(), items.end() );
comboBox->addItems( items );
return !items.isEmpty();
}
bool MonavConfigWidgetPrivate::updateContinents( QComboBox* comboBox )
{
QSet<QString> continents;
for( const MonavStuffEntry &map: m_remoteMaps ) {
Q_ASSERT( map.isValid() );
continents << map.continent();
}
return fillComboBox( continents.toList(), comboBox );
}
bool MonavConfigWidgetPrivate::updateStates( const QString &continent, QComboBox* comboBox )
{
QSet<QString> states;
for( const MonavStuffEntry &map: m_remoteMaps ) {
Q_ASSERT( map.isValid() );
if ( map.continent() == continent ) {
states << map.state();
}
}
return fillComboBox( states.toList(), comboBox );
}
bool MonavConfigWidgetPrivate::updateRegions( const QString &continent, const QString &state, QComboBox* comboBox )
{
comboBox->clear();
QMap<QString,QString> regions;
for( const MonavStuffEntry &map: m_remoteMaps ) {
Q_ASSERT( map.isValid() );
if ( map.continent() == continent && map.state() == state ) {
QString item = "%1 - %2";
if ( map.region().isEmpty() ) {
item = item.arg( map.state() );
comboBox->addItem( item.arg( map.transport() ), map.payload() );
} else {
item = item.arg( map.region(), map.transport() );
regions.insert( item, map.payload() );
}
}
}
QMapIterator<QString, QString> iter( regions );
while ( iter.hasNext() ) {
iter.next();
comboBox->addItem( iter.key(), iter.value() );
}
return true;
}
MonavStuffEntry MonavConfigWidgetPrivate::map( const QString &continent, const QString &state, const QString &region ) const
{
for( const MonavStuffEntry &entry: m_remoteMaps ) {
if ( continent == entry.continent() && state == entry.state() && region == entry.region() ) {
return entry;
}
}
return MonavStuffEntry();
}
MonavConfigWidget::MonavConfigWidget( MonavPlugin* plugin ) :
d( new MonavConfigWidgetPrivate( this, plugin ) )
{
setupUi( this );
m_statusLabel->setText( plugin->statusMessage() );
m_statusLabel->setHidden( m_statusLabel->text().isEmpty() );
d->setBusy( false );
m_installedMapsListView->setModel( d->m_mapsModel );
m_configureMapsListView->setModel( d->m_filteredModel );
m_configureMapsListView->resizeColumnsToContents();
updateComboBoxes();
connect( m_continentComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(updateStates()) );
connect( m_transportTypeComboBox, SIGNAL(currentIndexChanged(QString)),
this, SLOT(updateTransportTypeFilter(QString)) );
connect( m_stateComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(updateRegions()) );
connect( m_installButton, SIGNAL(clicked()), this, SLOT(downloadMap()) );
connect( m_cancelButton, SIGNAL(clicked()), this, SLOT(cancelOperation()) );
connect( &d->m_removeMapSignalMapper, SIGNAL(mapped(int)),
this, SLOT(removeMap(int)) );
connect( &d->m_upgradeMapSignalMapper, SIGNAL(mapped(int)),
this, SLOT(upgradeMap(int)) );
connect( &d->m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(retrieveMapList(QNetworkReply*)) );
}
MonavConfigWidget::~MonavConfigWidget()
{
delete d;
}
void MonavConfigWidget::loadSettings( const QHash<QString, QVariant> &settings )
{
d->m_transport = settings[QStringLiteral("transport")].toString();
d->updateTransportPreference();
}
void MonavConfigWidgetPrivate::updateTransportPreference()
{
if ( m_parent->m_transportTypeComboBox && m_mapsModel ) {
m_parent->m_transportTypeComboBox->blockSignals( true );
m_parent->m_transportTypeComboBox->clear();
QSet<QString> transportTypes;
for( int i=0; i<m_mapsModel->rowCount(); ++i ) {
QModelIndex index = m_mapsModel->index( i, 1 );
transportTypes << m_mapsModel->data( index ).toString();
}
m_parent->m_transportTypeComboBox->addItems( transportTypes.toList() );
m_parent->m_transportTypeComboBox->blockSignals( false );
if ( !m_transport.isEmpty() && m_parent->m_transportTypeComboBox ) {
for ( int i=1; i<m_parent->m_transportTypeComboBox->count(); ++i ) {
if ( m_parent->m_transportTypeComboBox->itemText( i ) == m_transport ) {
m_parent->m_transportTypeComboBox->setCurrentIndex( i );
return;
}
}
}
}
}
QHash<QString, QVariant> MonavConfigWidget::settings() const
{
QHash<QString, QVariant> settings;
settings.insert(QStringLiteral("transport"), d->m_transport);
return settings;
}
void MonavConfigWidget::retrieveMapList( QNetworkReply *reply )
{
if ( reply->isReadable() && d->m_currentDownload.isEmpty() ) {
// check if we are redirected
QVariant const redirectionAttribute = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirectionAttribute.isNull() ) {
d->m_networkAccessManager.get( QNetworkRequest( redirectionAttribute.toUrl() ) );
} else {
disconnect( &d->m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(retrieveMapList(QNetworkReply*)) );
d->parseNewStuff( reply->readAll() );
updateComboBoxes();
}
}
}
void MonavConfigWidget::retrieveData()
{
if ( d->m_currentReply && d->m_currentReply->isReadable() && !d->m_currentDownload.isEmpty() ) {
// check if we are redirected
QVariant const redirectionAttribute = d->m_currentReply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( !redirectionAttribute.isNull() ) {
d->m_currentReply = d->m_networkAccessManager.get( QNetworkRequest( redirectionAttribute.toUrl() ) );
connect( d->m_currentReply, SIGNAL(readyRead()),
this, SLOT(retrieveData()) );
connect( d->m_currentReply, SIGNAL(readChannelFinished()),
this, SLOT(retrieveData()) );
connect( d->m_currentReply, SIGNAL(downloadProgress(qint64,qint64)),
this, SLOT(updateProgressBar(qint64,qint64)) );
} else {
d->m_currentFile.write( d->m_currentReply->readAll() );
if ( d->m_currentReply->isFinished() ) {
d->m_currentReply->deleteLater();
- d->m_currentReply = 0;
+ d->m_currentReply = nullptr;
d->m_currentFile.close();
d->installMap();
d->m_currentDownload.clear();
}
}
}
}
void MonavConfigWidget::updateComboBoxes()
{
d->updateContinents( m_continentComboBox );
updateStates();
updateRegions();
}
void MonavConfigWidget::updateStates()
{
bool const haveContinents = m_continentComboBox->currentIndex() >= 0;
if ( haveContinents ) {
QString const continent = m_continentComboBox->currentText();
if ( d->updateStates( continent, m_stateComboBox ) ) {
updateRegions();
}
}
}
void MonavConfigWidget::updateRegions()
{
bool haveRegions = false;
if ( m_continentComboBox->currentIndex() >= 0 ) {
if ( m_stateComboBox->currentIndex() >= 0 ) {
QString const continent = m_continentComboBox->currentText();
QString const state = m_stateComboBox->currentText();
haveRegions = d->updateRegions( continent, state, m_regionComboBox );
}
}
m_regionLabel->setVisible( haveRegions );
m_regionComboBox->setVisible( haveRegions );
}
void MonavConfigWidget::downloadMap()
{
if ( d->m_currentDownload.isEmpty() && !d->m_currentFile.isOpen() ) {
d->m_currentDownload = m_regionComboBox->itemData( m_regionComboBox->currentIndex() ).toString();
d->install();
}
}
void MonavConfigWidget::cancelOperation()
{
if ( !d->m_currentDownload.isEmpty() || d->m_currentFile.isOpen() ) {
d->m_currentReply->abort();
d->m_currentReply->deleteLater();
- d->m_currentReply = 0;
+ d->m_currentReply = nullptr;
d->m_currentDownload.clear();
d->setBusy( false );
d->m_currentFile.close();
}
}
void MonavConfigWidgetPrivate::install()
{
if ( !m_currentDownload.isEmpty() ) {
int const index = m_currentDownload.lastIndexOf(QLatin1Char('/'));
const QString localFile = MarbleDirs::localPath() + QLatin1String("/maps") + m_currentDownload.mid(index);
m_currentFile.setFileName( localFile );
if ( m_currentFile.open( QFile::WriteOnly ) ) {
QFileInfo file( m_currentFile );
QString message = QObject::tr( "Downloading %1" ).arg( file.fileName() );
setBusy( true, message );
m_currentReply = m_networkAccessManager.get( QNetworkRequest( QUrl ( m_currentDownload ) ) );
QObject::connect( m_currentReply, SIGNAL(readyRead()),
m_parent, SLOT(retrieveData()) );
QObject::connect( m_currentReply, SIGNAL(readChannelFinished()),
m_parent, SLOT(retrieveData()) );
QObject::connect( m_currentReply, SIGNAL(downloadProgress(qint64,qint64)),
m_parent, SLOT(updateProgressBar(qint64,qint64)) );
} else {
mDebug() << "Failed to write to " << localFile;
}
}
}
void MonavConfigWidgetPrivate::installMap()
{
if ( m_unpackProcess ) {
m_unpackProcess->close();
delete m_unpackProcess;
- m_unpackProcess = 0;
+ m_unpackProcess = nullptr;
m_parent->m_installButton->setEnabled( true );
} else if ( m_currentFile.fileName().endsWith( QLatin1String( "tar.gz" ) ) && canExecute( "tar" ) ) {
QFileInfo file( m_currentFile );
QString message = QObject::tr( "Installing %1" ).arg( file.fileName() );
setBusy( true, message );
m_parent->m_progressBar->setMaximum( 0 );
if ( file.exists() && file.isReadable() ) {
m_unpackProcess = new QProcess;
QObject::connect( m_unpackProcess, SIGNAL(finished(int)),
m_parent, SLOT(mapInstalled(int)) );
QStringList arguments = QStringList() << "-x" << "-z" << "-f" << file.fileName();
m_unpackProcess->setWorkingDirectory( file.dir().absolutePath() );
m_unpackProcess->start( "tar", arguments );
}
} else {
if ( !m_currentFile.fileName().endsWith( QLatin1String( "tar.gz" ) ) ) {
mDebug() << "Can only handle tar.gz files";
} else {
mDebug() << "Cannot extract archive: tar executable not found in PATH.";
}
}
}
void MonavConfigWidget::updateProgressBar( qint64 bytesReceived, qint64 bytesTotal )
{
// Coarse MB resolution for the text to get it short,
// finer Kb resolution for the progress values to see changes easily
m_progressBar->setMaximum( bytesTotal / 1024 );
m_progressBar->setValue( bytesReceived / 1024 );
QString progress = "%1/%2 MB";
m_progressBar->setFormat( progress.arg( bytesReceived / 1024 / 1024 ).arg( bytesTotal / 1024 / 1024 ) );
}
bool MonavConfigWidgetPrivate::canExecute( const QString &executable )
{
QString path = QProcessEnvironment::systemEnvironment().value(QStringLiteral("PATH"), QStringLiteral("/usr/local/bin:/usr/bin:/bin"));
for( const QString &dir: path.split( QLatin1Char( ':' ) ) ) {
QFileInfo application( QDir( dir ), executable );
if ( application.exists() ) {
return true;
}
}
return false;
}
void MonavConfigWidget::mapInstalled( int exitStatus )
{
- d->m_unpackProcess = 0;
+ d->m_unpackProcess = nullptr;
d->m_currentFile.remove();
d->setBusy( false );
if ( exitStatus == 0 ) {
d->m_plugin->reloadMaps();
d->updateInstalledMapsView();
monavTabWidget->setCurrentIndex( 0 );
} else {
mDebug() << "Error when unpacking archive, process exited with status code " << exitStatus;
}
}
void MonavConfigWidget::showEvent ( QShowEvent * event )
{
// Lazy initialization
RoutingRunnerPlugin::ConfigWidget::showEvent( event );
if ( !event->spontaneous() && !d->m_initialized ) {
d->m_initialized = true;
d->updateInstalledMapsView();
QUrl url = QUrl( "http://files.kde.org/marble/newstuff/maps-monav.xml" );
d->m_networkAccessManager.get( QNetworkRequest( url ) );
}
}
void MonavConfigWidgetPrivate::updateInstalledMapsView()
{
m_mapsModel = m_plugin->installedMapsModel();
m_mapsModel->setInstallableVersions( m_remoteVersions );
m_filteredModel->setSourceModel( m_mapsModel );
m_parent->m_installedMapsListView->setModel( m_mapsModel );
m_parent->m_configureMapsListView->setColumnHidden( 1, true );
m_parent->m_installedMapsListView->setColumnHidden( 2, true );
m_parent->m_configureMapsListView->setColumnHidden( 3, true );
m_parent->m_configureMapsListView->setColumnHidden( 4, true );
m_parent->m_installedMapsListView->setColumnHidden( 5, true );
m_parent->m_configureMapsListView->horizontalHeader()->setVisible( true );
m_parent->m_installedMapsListView->horizontalHeader()->setVisible( true );
m_parent->m_configureMapsListView->resizeColumnsToContents();
m_parent->m_installedMapsListView->resizeColumnsToContents();
updateTransportPreference();
updateInstalledMapsViewButtons();
}
void MonavConfigWidgetPrivate::updateInstalledMapsViewButtons()
{
m_removeMapSignalMapper.removeMappings( m_parent );
m_upgradeMapSignalMapper.removeMappings( m_parent );
for( int i=0; i<m_mapsModel->rowCount(); ++i ) {
{
QPushButton* button = new QPushButton(QIcon(QStringLiteral(":/system-software-update.png")), QString());
button->setAutoFillBackground( true );
QModelIndex index = m_mapsModel->index( i, 3 );
m_parent->m_installedMapsListView->setIndexWidget( index, button );
m_upgradeMapSignalMapper.setMapping( button, index.row() );
QObject::connect( button, SIGNAL(clicked()), &m_upgradeMapSignalMapper, SLOT(map()) );
bool upgradable = m_mapsModel->data( index ).toBool();
QString canUpgradeText = QObject::tr( "An update is available. Click to install it." );
QString isLatestText = QObject::tr( "No update available. You are running the latest version." );
button->setToolTip( upgradable ? canUpgradeText : isLatestText );
button->setEnabled( upgradable );
}
{
QPushButton* button = new QPushButton(QIcon(QStringLiteral(":/edit-delete.png")), QString());
button->setAutoFillBackground( true );
QModelIndex index = m_mapsModel->index( i, 4 );
m_parent->m_installedMapsListView->setIndexWidget( index, button );
m_removeMapSignalMapper.setMapping( button, index.row() );
QObject::connect( button, SIGNAL(clicked()), &m_removeMapSignalMapper, SLOT(map()) );
bool const writable = m_mapsModel->data( index ).toBool();
button->setEnabled( writable );
}
}
m_parent->m_installedMapsListView->resizeColumnsToContents();
}
void MonavConfigWidget::updateTransportTypeFilter( const QString &filter )
{
d->m_filteredModel->setFilterFixedString( filter );
d->m_transport = filter;
m_configureMapsListView->resizeColumnsToContents();
}
void MonavConfigWidget::removeMap( int index )
{
QMessageBox::StandardButtons buttons = QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel;
QString text = tr( "Are you sure you want to delete this map from the system?" );
if ( QMessageBox::question( this, tr( "Remove Map" ), text, buttons, QMessageBox::No ) == QMessageBox::Yes ) {
d->m_mapsModel->deleteMapFiles( index );
d->m_plugin->reloadMaps();
d->updateInstalledMapsView();
}
}
void MonavConfigWidget::upgradeMap( int index )
{
QString payload = d->m_mapsModel->payload( index );
if ( !payload.isEmpty() ) {
for( const MonavStuffEntry &entry: d->m_remoteMaps ) {
if (entry.payload().endsWith(QLatin1Char('/') + payload)) {
d->m_currentDownload = entry.payload();
d->install();
return;
}
}
}
}
void MonavConfigWidgetPrivate::setBusy( bool busy, const QString &message ) const
{
if ( busy ) {
m_parent->m_stackedWidget->removeWidget( m_parent->m_settingsPage );
m_parent->m_stackedWidget->addWidget( m_parent->m_progressPage );
} else {
m_parent->m_stackedWidget->removeWidget( m_parent->m_progressPage );
m_parent->m_stackedWidget->addWidget( m_parent->m_settingsPage );
}
QString const defaultMessage = QObject::tr( "Nothing to do." );
m_parent->m_progressLabel->setText( message.isEmpty() ? defaultMessage : message );
}
}
#include "moc_MonavConfigWidget.cpp"
diff --git a/src/plugins/runner/monav/MonavMapsModel.h b/src/plugins/runner/monav/MonavMapsModel.h
index 2c8b00c65..aae441b41 100644
--- a/src/plugins/runner/monav/MonavMapsModel.h
+++ b/src/plugins/runner/monav/MonavMapsModel.h
@@ -1,52 +1,52 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_MONAVMAPSMODEL_H
#define MARBLE_MONAVMAPSMODEL_H
#include "MonavMap.h"
#include <QAbstractTableModel>
namespace Marble
{
class MonavMapsModel : public QAbstractTableModel
{
Q_OBJECT
public:
- explicit MonavMapsModel( const QVector<MonavMap> &data, QObject * parent = 0 );
+ explicit MonavMapsModel( const QVector<MonavMap> &data, QObject * parent = nullptr );
QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const override;
int rowCount ( const QModelIndex & parent = QModelIndex() ) const override;
int columnCount ( const QModelIndex & parent = QModelIndex() ) const override;
static bool sortByName( const MonavMap &first, const MonavMap &second );
void deleteMapFiles( int index );
QString payload( int index ) const;
void setInstallableVersions( const QMap<QString, QString> &remoteMaps );
private:
QVector<MonavMap> m_data;
QMap<QString, QString> m_remoteMaps;
};
}
#endif // MARBLE_MONAVMAPSMODEL_H
diff --git a/src/plugins/runner/monav/MonavPlugin.h b/src/plugins/runner/monav/MonavPlugin.h
index d6f3c0e94..913916420 100644
--- a/src/plugins/runner/monav/MonavPlugin.h
+++ b/src/plugins/runner/monav/MonavPlugin.h
@@ -1,82 +1,82 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_MONAVPLUGIN_H
#define MARBLE_MONAVPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class MonavMapsModel;
class MonavPluginPrivate;
class RouteRequest;
class MonavPlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.MonavPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
enum MonavRoutingDaemonVersion
{
Monav_0_2,
Monav_0_3
};
- explicit MonavPlugin( QObject *parent = 0 );
+ explicit MonavPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
~MonavPlugin() override;
RoutingRunner *newRunner() const override;
bool supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const override;
QHash< QString, QVariant > templateSettings( RoutingProfilesModel::ProfileTemplate profileTemplate ) const override;
ConfigWidget *configWidget() override;
bool canWork() const override;
QString mapDirectoryForRequest( const RouteRequest* request ) const;
QStringList mapDirectoriesForRequest( const RouteRequest* request ) const;
MonavMapsModel* installedMapsModel();
void reloadMaps();
MonavRoutingDaemonVersion monavVersion() const;
private:
MonavPluginPrivate* const d;
Q_PRIVATE_SLOT( d, void stopDaemon() )
};
}
#endif
diff --git a/src/plugins/runner/monav/MonavRunner.cpp b/src/plugins/runner/monav/MonavRunner.cpp
index 49a3430dc..529ff5c48 100644
--- a/src/plugins/runner/monav/MonavRunner.cpp
+++ b/src/plugins/runner/monav/MonavRunner.cpp
@@ -1,274 +1,274 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "MonavRunner.h"
#include "MonavPlugin.h"
#include "signals.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "routing/RouteRequest.h"
#include "routing/instructions/InstructionTransformation.h"
#include "GeoDataDocument.h"
#include "GeoDataData.h"
#include "GeoDataExtendedData.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLineString.h"
#include <QTime>
#include <QLocalSocket>
using namespace MoNav;
namespace Marble
{
class MonavRunnerPrivate
{
public:
const MonavPlugin* m_plugin;
MonavRunnerPrivate( const MonavPlugin* plugin );
bool retrieveData( const RouteRequest *route, RoutingResult* result ) const;
bool retrieveData( const RouteRequest *route, const QString &mapDir, RoutingResult* result ) const;
int retrieveRoute( const RouteRequest *route, QVector<GeoDataPlacemark*> *instructions, GeoDataLineString* geometry ) const;
static GeoDataDocument* createDocument( GeoDataLineString *geometry, const QVector<GeoDataPlacemark*> &instructions, const QString &name, const GeoDataExtendedData &data );
};
MonavRunnerPrivate::MonavRunnerPrivate( const MonavPlugin* plugin ) :
m_plugin( plugin )
{
// nothing to do
}
bool MonavRunnerPrivate::retrieveData( const RouteRequest *route, RoutingResult* reply ) const
{
QString mapDir = m_plugin->mapDirectoryForRequest( route );
if ( mapDir.isEmpty() ) {
return false;
}
if ( retrieveData( route, mapDir, reply ) ) {
return true;
}
// The separation into two different methods to determine a first country candidate
// and a list of alternative ones if the first candidate fails is intentional
// for performance reasons. Do not merge both.
QStringList alternatives = m_plugin->mapDirectoriesForRequest( route );
alternatives.removeOne( mapDir );
for( const QString &mapDir: alternatives ) {
if ( retrieveData( route, mapDir, reply ) ) {
return true;
}
}
return false;
}
bool MonavRunnerPrivate::retrieveData( const RouteRequest *route, const QString &mapDir, RoutingResult* reply ) const
{
QLocalSocket socket;
socket.connectToServer( "MoNavD" );
if ( socket.waitForConnected() ) {
if ( m_plugin->monavVersion() == MonavPlugin::Monav_0_3 ) {
CommandType commandType;
commandType.value = CommandType::RoutingCommand;
commandType.post( &socket );
}
RoutingCommand command;
QVector<Node> waypoints;
for ( int i = 0; i < route->size(); ++i ) {
Node coordinate;
coordinate.longitude = route->at( i ).longitude( GeoDataCoordinates::Degree );
coordinate.latitude = route->at( i ).latitude( GeoDataCoordinates::Degree );
waypoints << coordinate;
}
command.dataDirectory = mapDir;
command.lookupRadius = 1500;
command.waypoints = waypoints;
command.lookupStrings = true;
command.post( &socket );
socket.flush();
if ( reply->read( &socket ) ) {
switch ( reply->type ) {
case RoutingResult::LoadFailed:
mDebug() << "failed to load monav map from " << mapDir;
return false;
break;
case RoutingResult::RouteFailed:
mDebug() << "failed to retrieve route from monav daemon";
return false;
break;
case RoutingResult::TypeLookupFailed:
mDebug() << "failed to lookup type from monav daemon";
return false;
break;
case RoutingResult::NameLookupFailed:
mDebug() << "failed to lookup name from monav daemon";
return false;
break;
case RoutingResult::Success:
return true;
}
} else {
mDebug() << "Failed to read reply";
}
} else {
mDebug() << "No connection to MoNavD";
}
return false;
}
int MonavRunnerPrivate::retrieveRoute( const Marble::RouteRequest* route, QVector< Marble::GeoDataPlacemark* >* instructions, Marble::GeoDataLineString* geometry ) const
{
RoutingResult reply;
if ( retrieveData( route, &reply ) ) {
/** @todo: make use of reply.seconds, the estimated travel time */
for ( int i = 0; i < reply.pathNodes.size(); ++i ) {
qreal lon = reply.pathNodes[i].longitude;
qreal lat = reply.pathNodes[i].latitude;
GeoDataCoordinates coordinates( lon, lat, 0, GeoDataCoordinates::Degree );
geometry->append( coordinates );
}
RoutingWaypoints waypoints;
int k = 0;
for ( int i = 0; i < reply.pathEdges.size(); ++i ) {
QString road = reply.nameStrings[reply.pathEdges[i].name];
QString type = reply.typeStrings[reply.pathEdges[i].type];
RoutingWaypoint::JunctionType junction = RoutingWaypoint::Other;
if (type == QLatin1String("roundabout") && reply.pathEdges[i].branchingPossible) {
junction = RoutingWaypoint::Roundabout;
}
for ( unsigned int l = 0; l < reply.pathEdges[i].length; ++k, ++l ) {
qreal lon = reply.pathNodes[k].longitude;
qreal lat = reply.pathNodes[k].latitude;
RoutingPoint point( lon, lat );
bool const last = l == reply.pathEdges[i].length - 1;
RoutingWaypoint::JunctionType finalJunction = last ? junction : ( reply.pathEdges[i].branchingPossible ? RoutingWaypoint::Other : RoutingWaypoint::None );
RoutingWaypoint waypoint( point, finalJunction, "", type, -1, road );
waypoints.push_back( waypoint );
}
}
RoutingInstructions directions = InstructionTransformation::process( waypoints );
for ( int i = 0; i < directions.size(); ++i ) {
GeoDataPlacemark* placemark = new GeoDataPlacemark( directions[i].instructionText() );
GeoDataExtendedData extendedData;
GeoDataData turnType;
turnType.setName(QStringLiteral("turnType"));
turnType.setValue( qVariantFromValue<int>( int( directions[i].turnType() ) ) );
extendedData.addValue( turnType );
GeoDataData roadName;
roadName.setName(QStringLiteral("roadName"));
roadName.setValue( directions[i].roadName() );
extendedData.addValue( roadName );
placemark->setExtendedData( extendedData );
Q_ASSERT( !directions[i].points().isEmpty() );
GeoDataLineString* geometry = new GeoDataLineString;
QVector<RoutingWaypoint> items = directions[i].points();
for ( int j = 0; j < items.size(); ++j ) {
RoutingPoint point = items[j].point();
GeoDataCoordinates coordinates( point.lon(), point.lat(), 0.0, GeoDataCoordinates::Degree );
geometry->append( coordinates );
}
placemark->setGeometry( geometry );
instructions->push_back( placemark );
}
int duration = (int) reply.seconds;
return duration;
}
return 0;
}
GeoDataDocument* MonavRunnerPrivate::createDocument( Marble::GeoDataLineString* geometry, const QVector< Marble::GeoDataPlacemark* >& instructions, const QString& name, const Marble::GeoDataExtendedData& data )
{
if ( !geometry || geometry->isEmpty() ) {
- return 0;
+ return nullptr;
}
GeoDataDocument* result = new GeoDataDocument;
GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
routePlacemark->setName(QStringLiteral("Route"));
routePlacemark->setGeometry( geometry );
routePlacemark->setExtendedData( data );
result->append( routePlacemark );
for( GeoDataPlacemark* placemark: instructions ) {
result->append( placemark );
}
result->setName( name );
return result;
}
MonavRunner::MonavRunner( const MonavPlugin* plugin, QObject *parent ) :
RoutingRunner( parent ),
d( new MonavRunnerPrivate( plugin ) )
{
// nothing to do
}
MonavRunner::~MonavRunner()
{
delete d;
}
void MonavRunner::retrieveRoute( const RouteRequest *route )
{
QVector<GeoDataPlacemark*> instructions;
QTime time;
GeoDataLineString* waypoints = new GeoDataLineString();
int duration = d->retrieveRoute( route, &instructions, waypoints );
time = time.addSecs( duration );
qreal length = waypoints->length( EARTH_RADIUS );
const QString name = nameString( "Monav", length, time );
const GeoDataExtendedData data = routeData( length, time );
GeoDataDocument *result = d->createDocument( waypoints, instructions, name, data );
emit routeCalculated( result );
}
#if 0
void MonavRunner::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
GeoDataPlacemark placemark;
placemark.setCoordinate( GeoDataPoint( coordinates ) );
RouteRequest route;
route.append( coordinates );
route.append( coordinates );
RoutingResult reply;
if ( d->retrieveData( &route, &reply ) && !reply.pathEdges.isEmpty() ) {
QString road = reply.nameStrings[reply.pathEdges[0].name];
placemark.setAddress( road );
GeoDataExtendedData extendedData;
extendedData.addValue( GeoDataData( "road", road ) );
placemark.setExtendedData( extendedData );
}
emit reverseGeocodingFinished( coordinates, placemark );
}
#endif
} // namespace Marble
#include "moc_MonavRunner.cpp"
diff --git a/src/plugins/runner/monav/MonavRunner.h b/src/plugins/runner/monav/MonavRunner.h
index ac227e937..7437e7ab5 100644
--- a/src/plugins/runner/monav/MonavRunner.h
+++ b/src/plugins/runner/monav/MonavRunner.h
@@ -1,44 +1,44 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_MONAVRUNNER_H
#define MARBLE_MONAVRUNNER_H
#include "RoutingRunner.h"
namespace Marble
{
class MonavRunnerPrivate;
class MonavPlugin;
class MonavRunner : public RoutingRunner
{
Q_OBJECT
public:
- explicit MonavRunner( const MonavPlugin* plugin, QObject *parent = 0 );
+ explicit MonavRunner( const MonavPlugin* plugin, QObject *parent = nullptr );
~MonavRunner() override;
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
#if 0
// Overriding MarbleAbstractRunner
void reverseGeocoding( const GeoDataCoordinates &coordinates );
#endif
private:
MonavRunnerPrivate* const d;
};
}
#endif
diff --git a/src/plugins/runner/nominatim-reversegeocoding/NominatimReverseGeocodingPlugin.h b/src/plugins/runner/nominatim-reversegeocoding/NominatimReverseGeocodingPlugin.h
index 073d62e07..d75c3f0bd 100644
--- a/src/plugins/runner/nominatim-reversegeocoding/NominatimReverseGeocodingPlugin.h
+++ b/src/plugins/runner/nominatim-reversegeocoding/NominatimReverseGeocodingPlugin.h
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_NOMINATIMREVERSEGEOCODINGPLUGIN_H
#define MARBLE_NOMINATIMREVERSEGEOCODINGPLUGIN_H
#include "ReverseGeocodingRunnerPlugin.h"
namespace Marble
{
class NominatimPlugin : public ReverseGeocodingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.NominatimReverseGeocodingPlugin")
Q_INTERFACES( Marble::ReverseGeocodingRunnerPlugin )
public:
- explicit NominatimPlugin( QObject *parent = 0 );
+ explicit NominatimPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
ReverseGeocodingRunner* newRunner() const override;
};
}
#endif
diff --git a/src/plugins/runner/nominatim-reversegeocoding/OsmNominatimReverseGeocodingRunner.h b/src/plugins/runner/nominatim-reversegeocoding/OsmNominatimReverseGeocodingRunner.h
index 2b6ad5378..7835cfb85 100644
--- a/src/plugins/runner/nominatim-reversegeocoding/OsmNominatimReverseGeocodingRunner.h
+++ b/src/plugins/runner/nominatim-reversegeocoding/OsmNominatimReverseGeocodingRunner.h
@@ -1,61 +1,61 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OSMNOMINATIMRUNNER_H
#define MARBLE_OSMNOMINATIMRUNNER_H
#include "ReverseGeocodingRunner.h"
#include "GeoDataCoordinates.h"
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
class QNetworkReply;
class QDomNode;
namespace Marble
{
class GeoDataExtendedData;
class OsmNominatimRunner : public ReverseGeocodingRunner
{
Q_OBJECT
public:
- explicit OsmNominatimRunner(QObject *parent = 0);
+ explicit OsmNominatimRunner(QObject *parent = nullptr);
~OsmNominatimRunner() override;
// Overriding MarbleAbstractRunner
void reverseGeocoding( const GeoDataCoordinates &coordinates ) override;
private Q_SLOTS:
// Forward a result to the search or reverse geocoding handler
void handleResult( QNetworkReply* );
void returnNoReverseGeocodingResult();
void startReverseGeocoding();
private:
static void extractChildren(const QDomNode &node, GeoDataPlacemark &placemark);
QNetworkAccessManager m_manager;
QNetworkRequest m_request;
GeoDataCoordinates m_coordinates;
};
}
#endif
diff --git a/src/plugins/runner/nominatim-search/NominatimSearchPlugin.h b/src/plugins/runner/nominatim-search/NominatimSearchPlugin.h
index b62af682d..b4833bbfe 100644
--- a/src/plugins/runner/nominatim-search/NominatimSearchPlugin.h
+++ b/src/plugins/runner/nominatim-search/NominatimSearchPlugin.h
@@ -1,49 +1,49 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#ifndef MARBLE_NOMINATIMSEARCHPLUGIN_H
#define MARBLE_NOMINATIMSEARCHPLUGIN_H
#include "SearchRunnerPlugin.h"
namespace Marble
{
class NominatimPlugin : public SearchRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.NominatimSearchPlugin")
Q_INTERFACES( Marble::SearchRunnerPlugin )
public:
- explicit NominatimPlugin( QObject *parent = 0 );
+ explicit NominatimPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
SearchRunner* newRunner() const override;
};
}
#endif
diff --git a/src/plugins/runner/nominatim-search/OsmNominatimSearchRunner.h b/src/plugins/runner/nominatim-search/OsmNominatimSearchRunner.h
index 916ac56d4..933a04c2d 100644
--- a/src/plugins/runner/nominatim-search/OsmNominatimSearchRunner.h
+++ b/src/plugins/runner/nominatim-search/OsmNominatimSearchRunner.h
@@ -1,56 +1,56 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OSMNOMINATIMRUNNER_H
#define MARBLE_OSMNOMINATIMRUNNER_H
#include "SearchRunner.h"
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
class QNetworkReply;
class QDomNode;
namespace Marble
{
class GeoDataExtendedData;
class OsmNominatimRunner : public SearchRunner
{
Q_OBJECT
public:
- explicit OsmNominatimRunner(QObject *parent = 0);
+ explicit OsmNominatimRunner(QObject *parent = nullptr);
~OsmNominatimRunner() override;
void search( const QString &searchTerm, const GeoDataLatLonBox &preferred ) override;
private Q_SLOTS:
// Forward a result to the search or reverse geocoding handler
void handleResult( QNetworkReply* );
// No results (or an error)
void returnNoResults();
void startSearch();
private:
static GeoDataExtendedData extractChildren(const QDomNode &node);
QNetworkAccessManager m_manager;
QNetworkRequest m_request;
};
}
#endif
diff --git a/src/plugins/runner/open-source-routing-machine/OSRMPlugin.h b/src/plugins/runner/open-source-routing-machine/OSRMPlugin.h
index de712d30d..d241bd30e 100644
--- a/src/plugins/runner/open-source-routing-machine/OSRMPlugin.h
+++ b/src/plugins/runner/open-source-routing-machine/OSRMPlugin.h
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OSRMPLUGIN_H
#define MARBLE_OSRMPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class OSRMPlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.OSRMPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
- explicit OSRMPlugin( QObject *parent = 0 );
+ explicit OSRMPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
RoutingRunner *newRunner() const override;
bool supportsTemplate( RoutingProfilesModel::ProfileTemplate profileTemplate ) const override;
};
}
#endif
diff --git a/src/plugins/runner/open-source-routing-machine/OSRMRunner.cpp b/src/plugins/runner/open-source-routing-machine/OSRMRunner.cpp
index 8b64cc8e8..5937895e6 100644
--- a/src/plugins/runner/open-source-routing-machine/OSRMRunner.cpp
+++ b/src/plugins/runner/open-source-routing-machine/OSRMRunner.cpp
@@ -1,289 +1,289 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include "OSRMRunner.h"
#include "MarbleDebug.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "GeoDataLineString.h"
#include "routing/Maneuver.h"
#include "routing/RouteRequest.h"
#include "HttpDownloadManager.h"
#include <QString>
#include <QVector>
#include <QUrl>
#include <QTime>
#include <QTimer>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
namespace Marble
{
OSRMRunner::OSRMRunner( QObject *parent ) :
RoutingRunner( parent ),
m_networkAccessManager()
{
connect( &m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(retrieveData(QNetworkReply*)) );
}
OSRMRunner::~OSRMRunner()
{
// nothing to do
}
void OSRMRunner::retrieveRoute( const RouteRequest *route )
{
if ( route->size() < 2 ) {
return;
}
QString url = "http://router.project-osrm.org/route/v1/driving/";
GeoDataCoordinates::Unit const degree = GeoDataCoordinates::Degree;
for ( int i=0; i<route->size(); ++i ) {
GeoDataCoordinates const coordinates = route->at( i );
url += QString::number(coordinates.longitude(degree), 'f', 6);
url += ',';
url += QString::number(coordinates.latitude(degree), 'f', 6);
if (i+1<route->size()) {
url += ';';
}
}
url += QStringLiteral("?alternatives=false&overview=full&geometries=polyline6");
m_request = QNetworkRequest( QUrl( url ) );
m_request.setRawHeader( "User-Agent", HttpDownloadManager::userAgent( "Browser", "OSRMRunner" ) );
QEventLoop eventLoop;
QTimer timer;
timer.setSingleShot( true );
timer.setInterval( 15000 );
connect( &timer, SIGNAL(timeout()),
&eventLoop, SLOT(quit()));
connect( this, SIGNAL(routeCalculated(GeoDataDocument*)),
&eventLoop, SLOT(quit()) );
// @todo FIXME Must currently be done in the main thread, see bug 257376
QTimer::singleShot( 0, this, SLOT(get()) );
timer.start();
eventLoop.exec();
}
void OSRMRunner::retrieveData( QNetworkReply *reply )
{
if ( reply->isFinished() ) {
QByteArray data = reply->readAll();
reply->deleteLater();
GeoDataDocument* document = parse( data );
if ( !document ) {
mDebug() << "Failed to parse the downloaded route data" << data;
}
emit routeCalculated( document );
}
}
void OSRMRunner::handleError( QNetworkReply::NetworkError error )
{
mDebug() << " Error when retrieving OSRM route: " << error;
}
void OSRMRunner::get()
{
QNetworkReply *reply = m_networkAccessManager.get( m_request );
connect( reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)), Qt::DirectConnection );
}
void OSRMRunner::append(QString *input, const QString &key, const QString &value)
{
*input += QLatin1Char('&') + key + QLatin1Char('=') + value;
}
GeoDataLineString *OSRMRunner::decodePolyline( const QString &geometry )
{
// See https://developers.google.com/maps/documentation/utilities/polylinealgorithm
GeoDataLineString* lineString = new GeoDataLineString;
int coordinates[2] = { 0, 0 };
int const length = geometry.length();
for( int i=0; i<length; /* increment happens below */ ) {
for ( int j=0; j<2; ++j ) { // lat and lon
int block( 0 ), shift( 0 ), result( 0 );
do {
block = geometry.at( i++ /* increment for outer loop */ ).toLatin1() - 63;
result |= ( block & 0x1F ) << shift;
shift += 5;
} while ( block >= 0x20 );
coordinates[j] += ( ( result & 1 ) != 0 ? ~( result >> 1 ) : ( result >> 1 ) );
}
lineString->append( GeoDataCoordinates( double( coordinates[1] ) / 1E6,
double( coordinates[0] ) / 1E6,
0.0, GeoDataCoordinates::Degree ) );
}
return lineString;
}
RoutingInstruction::TurnType OSRMRunner::parseTurnType( const QString &instruction )
{
if (instruction == QLatin1String("1")) {
return RoutingInstruction::Straight;
} else if (instruction == QLatin1String("2")) {
return RoutingInstruction::SlightRight;
} else if (instruction == QLatin1String("3")) {
return RoutingInstruction::Right;
} else if (instruction == QLatin1String("4")) {
return RoutingInstruction::SharpRight;
} else if (instruction == QLatin1String("5")) {
return RoutingInstruction::TurnAround;
} else if (instruction == QLatin1String("6")) {
return RoutingInstruction::SharpLeft;
} else if (instruction == QLatin1String("7")) {
return RoutingInstruction::Left;
} else if (instruction == QLatin1String("8")) {
return RoutingInstruction::SlightLeft;
} else if (instruction == QLatin1String("10")) {
return RoutingInstruction::Continue;
} else if (instruction.startsWith(QLatin1String("11-"))) {
int const exit = instruction.mid( 3 ).toInt();
switch ( exit ) {
case 1: return RoutingInstruction::RoundaboutFirstExit; break;
case 2: return RoutingInstruction::RoundaboutSecondExit; break;
case 3: return RoutingInstruction::RoundaboutThirdExit; break;
default: return RoutingInstruction::RoundaboutExit;
}
} else if (instruction == QLatin1String("12")) {
return RoutingInstruction::RoundaboutExit;
}
// ignoring ReachViaPoint = 9;
// ignoring StayOnRoundAbout = 13;
// ignoring StartAtEndOfStreet = 14;
// ignoring ReachedYourDestination = 15;
return RoutingInstruction::Unknown;
}
GeoDataDocument *OSRMRunner::parse( const QByteArray &input ) const
{
QJsonDocument jsonDoc = QJsonDocument::fromJson(input);
QJsonObject data = jsonDoc.object();
- GeoDataDocument* result = 0;
- GeoDataLineString* routeWaypoints = 0;
+ GeoDataDocument* result = nullptr;
+ GeoDataLineString* routeWaypoints = nullptr;
QJsonValue routeGeometryValue = data.value(QStringLiteral("routes"));
if (routeGeometryValue.isArray()) {
auto routes = routeGeometryValue.toArray();
if (!routes.isEmpty()) {
auto route = routes[0].toObject();
auto routeGeometryValue = route.value(QStringLiteral("geometry"));
if (routeGeometryValue.isString()) {
result = new GeoDataDocument();
result->setName(QStringLiteral("Open Source Routing Machine"));
GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
routePlacemark->setName(QStringLiteral("Route"));
routeWaypoints = decodePolyline(routeGeometryValue.toString());
routePlacemark->setGeometry( routeWaypoints );
auto time = QTime(0, 0, 0);
time = time.addSecs(qRound(route.value(QStringLiteral("duration")).toDouble()));
qreal length = routeWaypoints->length( EARTH_RADIUS );
const QString name = nameString( "OSRM", length, time );
const GeoDataExtendedData extendedData = routeData( length, time );
routePlacemark->setExtendedData( extendedData );
result->setName( name );
result->append( routePlacemark );
}
}
}
/*
QJsonValue routeInstructionsValue = data.value(QStringLiteral("route_instructions"));
if (result && routeWaypoints && routeInstructionsValue.isArray()) {
bool first = true;
GeoDataPlacemark* instruction = new GeoDataPlacemark;
int lastWaypointIndex = 0;
const QJsonArray routeInstructionsArray = routeInstructionsValue.toArray();
for (int index = 0; index < routeInstructionsArray.size(); ++index) {
QVariantList details = routeInstructionsArray[index].toVariant().toList();
if ( details.size() > 7 ) {
QString const text = details.at( 0 ).toString();
QString const road = details.at( 1 ).toString();
int const waypointIndex = details.at( 3 ).toInt();
if ( waypointIndex < routeWaypoints->size() ) {
const bool isLastInstruction = (index+1 >= routeInstructionsArray.size());
if (!isLastInstruction) {
GeoDataLineString *lineString = new GeoDataLineString;
for ( int i=lastWaypointIndex; i<=waypointIndex; ++i ) {
lineString->append(routeWaypoints->at( i ) );
}
instruction->setGeometry( lineString );
result->append( instruction );
instruction = new GeoDataPlacemark;
}
lastWaypointIndex = waypointIndex;
GeoDataExtendedData extendedData;
GeoDataData turnTypeData;
turnTypeData.setName(QStringLiteral("turnType"));
RoutingInstruction::TurnType turnType = parseTurnType( text );
turnTypeData.setValue( turnType );
extendedData.addValue( turnTypeData );
if (!road.isEmpty()) {
GeoDataData roadName;
roadName.setName(QStringLiteral("roadName"));
roadName.setValue( road );
extendedData.addValue( roadName );
}
if ( first ) {
turnType = RoutingInstruction::Continue;
first = false;
}
if ( turnType == RoutingInstruction::Unknown ) {
instruction->setName( text );
} else {
instruction->setName( RoutingInstruction::generateRoadInstruction( turnType, road ) );
}
instruction->setExtendedData( extendedData );
if (isLastInstruction && lastWaypointIndex > 0 ) {
GeoDataLineString *lineString = new GeoDataLineString;
for ( int i=lastWaypointIndex; i<waypointIndex; ++i ) {
lineString->append(routeWaypoints->at( i ) );
}
instruction->setGeometry( lineString );
result->append( instruction );
}
}
}
}
}
*/
return result;
}
} // namespace Marble
#include "moc_OSRMRunner.cpp"
diff --git a/src/plugins/runner/open-source-routing-machine/OSRMRunner.h b/src/plugins/runner/open-source-routing-machine/OSRMRunner.h
index 843056dfa..fff492e04 100644
--- a/src/plugins/runner/open-source-routing-machine/OSRMRunner.h
+++ b/src/plugins/runner/open-source-routing-machine/OSRMRunner.h
@@ -1,65 +1,65 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OSMOSRMRUNNER_H
#define MARBLE_OSMOSRMRUNNER_H
#include "RoutingRunner.h"
#include "GeoDataCoordinates.h"
#include "routing/instructions/RoutingInstruction.h"
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkReply>
namespace Marble
{
class GeoDataLineString;
class OSRMRunner : public RoutingRunner
{
Q_OBJECT
public:
- explicit OSRMRunner(QObject *parent = 0);
+ explicit OSRMRunner(QObject *parent = nullptr);
~OSRMRunner() override;
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
private Q_SLOTS:
/** Route data was retrieved via http */
void retrieveData( QNetworkReply *reply );
/** A network error occurred */
void handleError( QNetworkReply::NetworkError );
void get();
private:
static void append( QString* input, const QString &key, const QString &value );
static GeoDataLineString* decodePolyline( const QString &geometry );
static RoutingInstruction::TurnType parseTurnType( const QString &instruction );
GeoDataDocument* parse( const QByteArray &input ) const;
QNetworkAccessManager m_networkAccessManager;
QNetworkRequest m_request;
};
}
#endif
diff --git a/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchPlugin.h b/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchPlugin.h
index 1d3498da9..c34c6b424 100644
--- a/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchPlugin.h
+++ b/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchPlugin.h
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Constantin Mihalache <mihalache.c94@gmail.com>
//
#ifndef OPENLOCATIONCODESEARCHPLUGIN_H
#define OPENLOCATIONCODESEARCHPLUGIN_H
#include "SearchRunnerPlugin.h"
namespace Marble {
class OpenLocationCodeSearchPlugin : public SearchRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.OpenLocationCodeSearchPlugin")
Q_INTERFACES( Marble::SearchRunnerPlugin )
public:
- explicit OpenLocationCodeSearchPlugin(QObject *parent = 0);
+ explicit OpenLocationCodeSearchPlugin(QObject *parent = nullptr);
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
SearchRunner* newRunner() const override;
};
}
#endif // OPENLOCATIONCODESEARCHPLUGIN_H
diff --git a/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchRunner.h b/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchRunner.h
index f37dbf2bd..05a4ddb7c 100644
--- a/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchRunner.h
+++ b/src/plugins/runner/openlocation-code-search/OpenLocationCodeSearchRunner.h
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Constantin Mihalache <mihalache.c94@gmail.com>
//
#ifndef OPENLOCATIONCODESEARCHRUNNER_H
#define OPENLOCATIONCODESEARCHRUNNER_H
#include "SearchRunner.h"
#include "GeoDataLatLonBox.h"
#include "MarbleDebug.h"
namespace Marble
{
class GeoDataPolygon;
class OpenLocationCodeSearchRunner : public SearchRunner
{
Q_OBJECT
public:
- explicit OpenLocationCodeSearchRunner( QObject *parent = 0 );
+ explicit OpenLocationCodeSearchRunner( QObject *parent = nullptr );
void search( const QString &searchTerm, const GeoDataLatLonBox &preferred ) override;
private:
/**
* Makes a GeoDataPolygon which contains the boundary points of the
* boundingBox parameter.
*/
GeoDataPolygon polygonFromLatLonBox( const GeoDataLatLonBox& boundingBox ) const;
/**
* Decode a valid open location code string into a GeoDataLatLonBox.
*/
GeoDataLatLonBox decodeOLC( const QString &ocl ) const;
/**
* Decide if the string is a valid & full open location code.
*/
bool isValidOLC( const QString &ocl ) const;
/**
* Maps each character from the accepted chars to its corresponding index
* inside the string.
*/
QHash<QChar, int> charIndex;
};
}
#endif // OPENLOCATIONCODESEARCHRUNNER_H
diff --git a/src/plugins/runner/openrouteservice/OpenRouteServicePlugin.h b/src/plugins/runner/openrouteservice/OpenRouteServicePlugin.h
index bd20ec9a1..f54a1f44c 100644
--- a/src/plugins/runner/openrouteservice/OpenRouteServicePlugin.h
+++ b/src/plugins/runner/openrouteservice/OpenRouteServicePlugin.h
@@ -1,54 +1,54 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OPENROUTESERVICEPLUGIN_H
#define MARBLE_OPENROUTESERVICEPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class OpenRouteServicePlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.OpenRouteServicePlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
- explicit OpenRouteServicePlugin( QObject *parent = 0 );
+ explicit OpenRouteServicePlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
RoutingRunner *newRunner() const override;
ConfigWidget* configWidget() override;
bool supportsTemplate( RoutingProfilesModel::ProfileTemplate profileTemplate ) const override;
QHash<QString, QVariant> templateSettings( RoutingProfilesModel::ProfileTemplate profileTemplate ) const override;
};
}
#endif
diff --git a/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.cpp b/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.cpp
index 68205a253..655a892bf 100644
--- a/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.cpp
+++ b/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.cpp
@@ -1,343 +1,343 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#include "OpenRouteServiceRunner.h"
#include "MarbleDebug.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataData.h"
#include "GeoDataExtendedData.h"
#include "GeoDataLineString.h"
#include "routing/RouteRequest.h"
#include <QString>
#include <QUrl>
#include <QUrlQuery>
#include <QTime>
#include <QTimer>
#include <QNetworkReply>
#include <QDomDocument>
namespace Marble
{
OpenRouteServiceRunner::OpenRouteServiceRunner( QObject *parent ) :
RoutingRunner( parent ),
m_networkAccessManager()
{
connect( &m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(retrieveData(QNetworkReply*)));
}
void OpenRouteServiceRunner::retrieveRoute( const RouteRequest *route )
{
if ( route->size() < 2 ) {
return;
}
GeoDataCoordinates source = route->source();
GeoDataCoordinates destination = route->destination();
QHash<QString, QVariant> settings = route->routingProfile().pluginSettings()["openrouteservice"];
QUrlQuery queries;
queries.addQueryItem("api_key", "ee0b8233adff52ce9fd6afc2a2859a28");
QString unit = "KM";
QString preference = "Fastest";
if (settings.contains(QStringLiteral("preference"))) {
preference = settings[QStringLiteral("preference")].toString();
}
if (preference == QLatin1String("Pedestrian")) {
unit = QStringLiteral("M");
}
queries.addQueryItem("start", formatCoordinates(source));
QStringList via;
for (int i = 1; i < route->size()-1; ++i) {
via << formatCoordinates(route->at(i));
}
queries.addQueryItem("via", via.join(' '));
queries.addQueryItem("end", formatCoordinates(destination));
queries.addQueryItem("distunit", unit);
if (preference == "Fastest" || preference == "Shortest" || preference == "Recommended") {
queries.addQueryItem("routepref", "Car");
queries.addQueryItem("weighting", preference);
} else {
queries.addQueryItem("routepref", preference);
queries.addQueryItem("weighting", "Recommended");
}
QString const motorways = settings.value("noMotorways").toInt() == 0 ? "false" : "true";
queries.addQueryItem("noMotorways", motorways);
QString const tollways = settings.value("noTollways").toInt() == 0 ? "false" : "true";
queries.addQueryItem("noTollways", tollways);
queries.addQueryItem("noUnpavedroads", "false");
queries.addQueryItem("noSteps", "false");
QString const ferries = settings.value("noFerries").toInt() == 0 ? "false" : "true";
queries.addQueryItem("noFerries", ferries);
queries.addQueryItem("instructions", "true");
queries.addQueryItem("lang", "en");
QUrl url = QUrl( "http://openls.geog.uni-heidelberg.de/route" );
// QUrlQuery strips empty value pairs, but OpenRouteService does not work without
QString const trailer = route->size() == 2 ? "&via=" : QString();
url.setQuery(queries.toString() + trailer);
m_request = QNetworkRequest( url );
QEventLoop eventLoop;
QTimer timer;
timer.setSingleShot( true );
timer.setInterval( 15000 );
connect( &timer, SIGNAL(timeout()),
&eventLoop, SLOT(quit()));
connect( this, SIGNAL(routeCalculated(GeoDataDocument*)),
&eventLoop, SLOT(quit()));
// @todo FIXME Must currently be done in the main thread, see bug 257376
QTimer::singleShot( 0, this, SLOT(get()));
timer.start();
eventLoop.exec();
}
void OpenRouteServiceRunner::get()
{
QNetworkReply *reply = m_networkAccessManager.get(m_request);
connect( reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)), Qt::DirectConnection);
}
QString OpenRouteServiceRunner::formatCoordinates(const GeoDataCoordinates &coordinates)
{
return QStringLiteral("%1,%2")
.arg(coordinates.longitude(GeoDataCoordinates::Degree ), 0, 'f', 8)
.arg(coordinates.latitude(GeoDataCoordinates::Degree ), 0, 'f', 8);
}
void OpenRouteServiceRunner::retrieveData( QNetworkReply *reply )
{
if ( reply->isFinished() ) {
QByteArray data = reply->readAll();
reply->deleteLater();
//mDebug() << "Download completed: " << data;
GeoDataDocument* document = parse( data );
if ( !document ) {
mDebug() << "Failed to parse the downloaded route data" << data;
}
emit routeCalculated( document );
}
}
void OpenRouteServiceRunner::handleError( QNetworkReply::NetworkError error )
{
mDebug() << " Error when retrieving openrouteservice.org route: " << error;
}
GeoDataDocument* OpenRouteServiceRunner::parse( const QByteArray &content ) const
{
QDomDocument xml;
if ( !xml.setContent( content ) ) {
mDebug() << "Cannot parse xml file with routing instructions.";
- return 0;
+ return nullptr;
}
QDomElement root = xml.documentElement();
GeoDataDocument* result = new GeoDataDocument();
result->setName(QStringLiteral("OpenRouteService"));
QDomNodeList errors = root.elementsByTagName(QStringLiteral("xls:Error"));
if ( errors.size() > 0 ) {
- return 0;
+ return nullptr;
// Returning early because fallback routing providers are used now
// The code below can be used to parse OpenGis errors reported by ORS
// and may be useful in the future
for (int i=0 ; i < errors.length(); ++i ) {
QDomNode node = errors.item( i );
QString errorMessage = node.attributes().namedItem(QStringLiteral("message")).nodeValue();
QRegExp regexp = QRegExp( "^(.*) Please Check your Position: (-?[0-9]+.[0-9]+) (-?[0-9]+.[0-9]+) !" );
if ( regexp.indexIn( errorMessage ) == 0 ) {
if ( regexp.capturedTexts().size() == 4 ) {
GeoDataPlacemark* placemark = new GeoDataPlacemark;
placemark->setName( regexp.capturedTexts().at( 1 ) );
GeoDataCoordinates position;
position.setLongitude( regexp.capturedTexts().at( 2 ).toDouble(), GeoDataCoordinates::Degree );
position.setLatitude( regexp.capturedTexts().at( 3 ).toDouble(), GeoDataCoordinates::Degree );
placemark->setCoordinate( position );
result->append( placemark );
}
} else {
mDebug() << "Error message " << errorMessage << " not parsable.";
/** @todo: How to handle this now with plugins? */
// QString message = tr( "Sorry, a problem occurred when calculating the route. Try adjusting start and destination points." );
// QPointer<QMessageBox> messageBox = new QMessageBox( QMessageBox::Warning, "Route Error", message );
// messageBox->setDetailedText( errorMessage );
// messageBox->exec();
// delete messageBox;
}
}
}
GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
routePlacemark->setName(QStringLiteral("Route"));
QTime time;
QDomNodeList summary = root.elementsByTagName(QStringLiteral("xls:RouteSummary"));
if ( summary.size() > 0 ) {
QDomNodeList timeNodeList = summary.item(0).toElement().elementsByTagName(QStringLiteral("xls:TotalTime"));
if ( timeNodeList.size() == 1 ) {
QRegExp regexp = QRegExp( "^P(?:(\\d+)D)?T(?:(\\d+)H)?(?:(\\d+)M)?(\\d+)S" );
if ( regexp.indexIn( timeNodeList.item( 0 ).toElement().text() ) == 0 ) {
QStringList matches = regexp.capturedTexts();
unsigned int hours( 0 ), minutes( 0 ), seconds( 0 );
switch ( matches.size() ) {
case 5:
// days = regexp.cap( matches.size() - 4 ).toInt();
// Intentionally no break
case 4:
hours = regexp.cap( matches.size() - 3 ).toInt();
// Intentionally no break
case 3:
minutes = regexp.cap( matches.size() - 2 ).toInt();
// Intentionally no break
case 2:
seconds = regexp.cap( matches.size() - 1 ).toInt();
break;
default:
mDebug() << "Unable to parse time string " << timeNodeList.item( 0 ).toElement().text();
}
time = QTime( hours, minutes, seconds, 0 );
}
}
}
GeoDataLineString* routeWaypoints = new GeoDataLineString;
QDomNodeList geometry = root.elementsByTagName(QStringLiteral("xls:RouteGeometry"));
if ( geometry.size() > 0 ) {
QDomNodeList waypoints = geometry.item( 0 ).toElement().elementsByTagName( "gml:pos" );
for (int i=0 ; i < waypoints.length(); ++i ) {
QDomNode node = waypoints.item( i );
const QStringList content = node.toElement().text().split(QLatin1Char(' '));
if ( content.length() == 2 ) {
GeoDataCoordinates position;
position.setLongitude( content.at( 0 ).toDouble(), GeoDataCoordinates::Degree );
position.setLatitude( content.at( 1 ).toDouble(), GeoDataCoordinates::Degree );
routeWaypoints->append( position );
}
}
}
routePlacemark->setGeometry( routeWaypoints );
qreal length = routeWaypoints->length( EARTH_RADIUS );
const QString name = nameString( "ORS", length, time );
const GeoDataExtendedData data = routeData( length, time );
routePlacemark->setExtendedData( data );
result->setName( name );
result->append( routePlacemark );
QDomNodeList instructionList = root.elementsByTagName(QStringLiteral("xls:RouteInstructionsList"));
if ( instructionList.size() > 0 ) {
QDomNodeList instructions = instructionList.item(0).toElement().elementsByTagName(QStringLiteral("xls:RouteInstruction"));
for (int i=0 ; i < instructions.length(); ++i ) {
QDomElement node = instructions.item( i ).toElement();
QDomNodeList textNodes = node.elementsByTagName(QStringLiteral("xls:Instruction"));
QDomNodeList positions = node.elementsByTagName(QStringLiteral("gml:pos"));
if ( textNodes.size() > 0 && positions.size() > 0 ) {
const QStringList content = positions.at(0).toElement().text().split(QLatin1Char(' '));
if ( content.length() == 2 ) {
GeoDataLineString *lineString = new GeoDataLineString;
for( int i = 0; i < positions.count(); ++i ) {
const QStringList pointList = positions.at(i).toElement().text().split(QLatin1Char(' '));
GeoDataCoordinates position;
position.setLongitude( pointList.at( 0 ).toDouble(), GeoDataCoordinates::Degree );
position.setLatitude( pointList.at( 1 ).toDouble(), GeoDataCoordinates::Degree );
lineString->append( position );
}
GeoDataPlacemark* instruction = new GeoDataPlacemark;
QString const text = textNodes.item( 0 ).toElement().text().remove(QRegExp("<[^>]*>"));
GeoDataExtendedData extendedData;
GeoDataData turnTypeData;
turnTypeData.setName(QStringLiteral("turnType"));
QString road;
RoutingInstruction::TurnType turnType = parseTurnType( text, &road );
turnTypeData.setValue( turnType );
extendedData.addValue( turnTypeData );
if ( !road.isEmpty() ) {
GeoDataData roadName;
roadName.setName(QStringLiteral("roadName"));
roadName.setValue( road );
extendedData.addValue( roadName );
}
QString const instructionText = turnType == RoutingInstruction::Unknown ? text : RoutingInstruction::generateRoadInstruction( turnType, road );
instruction->setName( instructionText );
instruction->setExtendedData( extendedData );
instruction->setGeometry( lineString );
result->append( instruction );
}
}
}
}
return result;
}
RoutingInstruction::TurnType OpenRouteServiceRunner::parseTurnType( const QString &text, QString *road )
{
QRegExp syntax( "^(Go|Drive|Turn) (half left|left|sharp left|straight forward|half right|right|sharp right)( on )?(.*)?$", Qt::CaseSensitive, QRegExp::RegExp2 );
QString instruction;
if ( syntax.indexIn( text ) == 0 ) {
if ( syntax.captureCount() > 1 ) {
instruction = syntax.cap( 2 );
if ( syntax.captureCount() == 4 ) {
*road = syntax.cap( 4 ).remove(QLatin1String( " - Arrived at destination!"));
}
}
}
if (instruction == QLatin1String("Continue")) {
return RoutingInstruction::Straight;
} else if (instruction == QLatin1String("half right")) {
return RoutingInstruction::SlightRight;
} else if (instruction == QLatin1String("right")) {
return RoutingInstruction::Right;
} else if (instruction == QLatin1String("sharp right")) {
return RoutingInstruction::SharpRight;
} else if (instruction == QLatin1String("straight forward")) {
return RoutingInstruction::Straight;
} else if (instruction == QLatin1String("turn")) {
return RoutingInstruction::TurnAround;
} else if (instruction == QLatin1String("sharp left")) {
return RoutingInstruction::SharpLeft;
} else if (instruction == QLatin1String("left")) {
return RoutingInstruction::Left;
} else if (instruction == QLatin1String("half left")) {
return RoutingInstruction::SlightLeft;
}
return RoutingInstruction::Unknown;
}
} // namespace Marble
#include "moc_OpenRouteServiceRunner.cpp"
diff --git a/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.h b/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.h
index 77442b102..ee00a93c3 100644
--- a/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.h
+++ b/src/plugins/runner/openrouteservice/OpenRouteServiceRunner.h
@@ -1,66 +1,66 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OSMOPENROUTESERVICERUNNER_H
#define MARBLE_OSMOPENROUTESERVICERUNNER_H
#include "RoutingRunner.h"
#include "routing/instructions/RoutingInstruction.h"
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkReply>
namespace Marble
{
class GeoDataCoordinates;
class OpenRouteServiceRunner : public RoutingRunner
{
Q_OBJECT
enum PointType {
StartPoint,
ViaPoint,
EndPoint
};
public:
- explicit OpenRouteServiceRunner(QObject *parent = 0);
+ explicit OpenRouteServiceRunner(QObject *parent = nullptr);
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
private Q_SLOTS:
/** Route data was retrieved via http */
void retrieveData( QNetworkReply *reply );
/** A network error occurred */
void handleError( QNetworkReply::NetworkError );
void get();
private:
static QString formatCoordinates(const GeoDataCoordinates &coordinates);
GeoDataDocument* parse( const QByteArray &input ) const;
static RoutingInstruction::TurnType parseTurnType( const QString &text, QString* road );
QNetworkAccessManager m_networkAccessManager;
QNetworkRequest m_request;
};
}
#endif
diff --git a/src/plugins/runner/osm/OsmParser.cpp b/src/plugins/runner/osm/OsmParser.cpp
index a1e3fdd9f..3a8f427a1 100644
--- a/src/plugins/runner/osm/OsmParser.cpp
+++ b/src/plugins/runner/osm/OsmParser.cpp
@@ -1,253 +1,253 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2011 Konstantin Oblaukhov <oblaukhov.konstantin@gmail.com>
// Copyright 2014 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
// Copyright 2015 Dennis Nienhüser <nienhueser@kde.org>
//
#include "OsmParser.h"
#include "OsmElementDictionary.h"
#include "osm/OsmObjectManager.h"
#include "GeoDataDocument.h"
#include "GeoDataPoint.h"
#include "GeoDataTypes.h"
#include "GeoDataStyle.h"
#include "GeoDataPolyStyle.h"
#include <MarbleZipReader.h>
#include "o5mreader.h"
#include <QFile>
#include <QFileInfo>
#include <QBuffer>
#include <QSet>
namespace Marble {
GeoDataDocument *OsmParser::parse(const QString &filename, QString &error)
{
QFileInfo const fileInfo(filename);
if (!fileInfo.exists() || !fileInfo.isReadable()) {
error = QString("Cannot read file %1").arg(filename);
- return 0;
+ return nullptr;
}
if (fileInfo.completeSuffix() == QLatin1String("o5m")) {
return parseO5m(filename, error);
} else {
return parseXml(filename, error);
}
}
GeoDataDocument* OsmParser::parseO5m(const QString &filename, QString &error)
{
O5mreader* reader;
O5mreaderDataset data;
O5mreaderIterateRet outerState, innerState;
char *key, *value;
// share string data on the heap at least for this file
QSet<QString> stringPool;
OsmNodes nodes;
OsmWays ways;
OsmRelations relations;
QHash<uint8_t, QString> relationTypes;
relationTypes[O5MREADER_DS_NODE] = QStringLiteral("node");
relationTypes[O5MREADER_DS_WAY] = QStringLiteral("way");
relationTypes[O5MREADER_DS_REL] = QStringLiteral("relation");
auto file = fopen(filename.toStdString().c_str(), "rb");
o5mreader_open(&reader, file);
while( (outerState = o5mreader_iterateDataSet(reader, &data)) == O5MREADER_ITERATE_RET_NEXT) {
switch (data.type) {
case O5MREADER_DS_NODE:
{
OsmNode& node = nodes[data.id];
node.osmData().setId(data.id);
node.setCoordinates(GeoDataCoordinates(data.lon*1.0e-7, data.lat*1.0e-7,
0.0, GeoDataCoordinates::Degree));
while ((innerState = o5mreader_iterateTags(reader, &key, &value)) == O5MREADER_ITERATE_RET_NEXT) {
const QString keyString = *stringPool.insert(QString::fromUtf8(key));
const QString valueString = *stringPool.insert(QString::fromUtf8(value));
node.osmData().addTag(keyString, valueString);
}
}
break;
case O5MREADER_DS_WAY:
{
OsmWay &way = ways[data.id];
way.osmData().setId(data.id);
uint64_t nodeId;
while ((innerState = o5mreader_iterateNds(reader, &nodeId)) == O5MREADER_ITERATE_RET_NEXT) {
way.addReference(nodeId);
}
while ((innerState = o5mreader_iterateTags(reader, &key, &value)) == O5MREADER_ITERATE_RET_NEXT) {
const QString keyString = *stringPool.insert(QString::fromUtf8(key));
const QString valueString = *stringPool.insert(QString::fromUtf8(value));
way.osmData().addTag(keyString, valueString);
}
}
break;
case O5MREADER_DS_REL:
{
OsmRelation &relation = relations[data.id];
relation.osmData().setId(data.id);
char *role;
uint8_t type;
uint64_t refId;
while ((innerState = o5mreader_iterateRefs(reader, &refId, &type, &role)) == O5MREADER_ITERATE_RET_NEXT) {
const QString roleString = *stringPool.insert(QString::fromUtf8(role));
relation.addMember(refId, roleString, relationTypes[type]);
}
while ((innerState = o5mreader_iterateTags(reader, &key, &value)) == O5MREADER_ITERATE_RET_NEXT) {
const QString keyString = *stringPool.insert(QString::fromUtf8(key));
const QString valueString = *stringPool.insert(QString::fromUtf8(value));
relation.osmData().addTag(keyString, valueString);
}
}
break;
}
}
fclose(file);
error = reader->errMsg;
o5mreader_close(reader);
return createDocument(nodes, ways, relations);
}
GeoDataDocument* OsmParser::parseXml(const QString &filename, QString &error)
{
QXmlStreamReader parser;
QFile file;
QBuffer buffer;
QFileInfo fileInfo(filename);
if (fileInfo.completeSuffix() == QLatin1String("osm.zip")) {
MarbleZipReader zipReader(filename);
if (zipReader.fileInfoList().size() != 1) {
int const fileNumber = zipReader.fileInfoList().size();
error = QStringLiteral("Unexpected number of files (%1) in %2").arg(fileNumber).arg(filename);
return nullptr;
}
QByteArray const data = zipReader.fileData(zipReader.fileInfoList().first().filePath);
buffer.setData(data);
buffer.open(QBuffer::ReadOnly);
parser.setDevice(&buffer);
} else {
file.setFileName(filename);
if (!file.open(QFile::ReadOnly)) {
error = QStringLiteral("Cannot open file %1").arg(filename);
return nullptr;
}
parser.setDevice(&file);
}
- OsmPlacemarkData* osmData(0);
+ OsmPlacemarkData* osmData(nullptr);
QString parentTag;
qint64 parentId(0);
// share string data on the heap at least for this file
QSet<QString> stringPool;
OsmNodes m_nodes;
OsmWays m_ways;
OsmRelations m_relations;
while (!parser.atEnd()) {
parser.readNext();
if (!parser.isStartElement()) {
continue;
}
QStringRef const tagName = parser.name();
if (tagName == osm::osmTag_node || tagName == osm::osmTag_way || tagName == osm::osmTag_relation) {
parentTag = parser.name().toString();
parentId = parser.attributes().value(QLatin1String("id")).toLongLong();
if (tagName == osm::osmTag_node) {
m_nodes[parentId].osmData() = OsmPlacemarkData::fromParserAttributes(parser.attributes());
m_nodes[parentId].parseCoordinates(parser.attributes());
osmData = &m_nodes[parentId].osmData();
} else if (tagName == osm::osmTag_way) {
m_ways[parentId].osmData() = OsmPlacemarkData::fromParserAttributes(parser.attributes());
osmData = &m_ways[parentId].osmData();
} else {
Q_ASSERT(tagName == osm::osmTag_relation);
m_relations[parentId].osmData() = OsmPlacemarkData::fromParserAttributes(parser.attributes());
osmData = &m_relations[parentId].osmData();
}
} else if (osmData && tagName == osm::osmTag_tag) {
const QXmlStreamAttributes &attributes = parser.attributes();
const QString keyString = *stringPool.insert(attributes.value(QLatin1String("k")).toString());
const QString valueString = *stringPool.insert(attributes.value(QLatin1String("v")).toString());
osmData->addTag(keyString, valueString);
} else if (tagName == osm::osmTag_nd && parentTag == osm::osmTag_way) {
m_ways[parentId].addReference(parser.attributes().value(QLatin1String("ref")).toLongLong());
} else if (tagName == osm::osmTag_member && parentTag == osm::osmTag_relation) {
m_relations[parentId].parseMember(parser.attributes());
} // other tags like osm, bounds ignored
}
if (parser.hasError()) {
error = parser.errorString();
return nullptr;
}
return createDocument(m_nodes, m_ways, m_relations);
}
GeoDataDocument *OsmParser::createDocument(OsmNodes &nodes, OsmWays &ways, OsmRelations &relations)
{
GeoDataDocument* document = new GeoDataDocument;
GeoDataPolyStyle backgroundPolyStyle;
backgroundPolyStyle.setFill( true );
backgroundPolyStyle.setOutline( false );
backgroundPolyStyle.setColor(QStringLiteral("#f1eee8"));
GeoDataStyle::Ptr backgroundStyle(new GeoDataStyle);
backgroundStyle->setPolyStyle( backgroundPolyStyle );
backgroundStyle->setId(QStringLiteral("background"));
document->addStyle( backgroundStyle );
QSet<qint64> usedNodes, usedWays;
for(auto const &relation: relations) {
relation.createMultipolygon(document, ways, nodes, usedNodes, usedWays);
}
for(auto id: usedWays) {
ways.remove(id);
}
QHash<qint64, GeoDataPlacemark*> placemarks;
for (auto iter=ways.constBegin(), end=ways.constEnd(); iter != end; ++iter) {
auto placemark = iter.value().create(nodes, usedNodes);
if (placemark) {
document->append(placemark);
placemarks[placemark->osmData().oid()] = placemark;
}
}
for(auto id: usedNodes) {
if (nodes[id].osmData().isEmpty()) {
nodes.remove(id);
}
}
for(auto const &node: nodes) {
auto placemark = node.create();
if (placemark) {
document->append(placemark);
placemarks[placemark->osmData().oid()] = placemark;
}
}
for(auto const &relation: relations) {
relation.createRelation(document, placemarks);
}
return document;
}
}
diff --git a/src/plugins/runner/osm/OsmPlugin.h b/src/plugins/runner/osm/OsmPlugin.h
index 36f5b72a7..6d8384e93 100644
--- a/src/plugins/runner/osm/OsmPlugin.h
+++ b/src/plugins/runner/osm/OsmPlugin.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEOSMPLUGIN_H
#define MARBLEOSMPLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class OsmPlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.OsmPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit OsmPlugin( QObject *parent = 0 );
+ explicit OsmPlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLEOSMPLUGIN_H
diff --git a/src/plugins/runner/osm/OsmRunner.h b/src/plugins/runner/osm/OsmRunner.h
index a9b3aab14..d2bc1a73d 100644
--- a/src/plugins/runner/osm/OsmRunner.h
+++ b/src/plugins/runner/osm/OsmRunner.h
@@ -1,27 +1,27 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEOSMRUNNER_H
#define MARBLEOSMRUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class OsmRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit OsmRunner(QObject *parent = 0);
+ explicit OsmRunner(QObject *parent = nullptr);
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLEOSMRUNNER_H
diff --git a/src/plugins/runner/osm/OsmWay.cpp b/src/plugins/runner/osm/OsmWay.cpp
index 41d927b44..486226c33 100644
--- a/src/plugins/runner/osm/OsmWay.cpp
+++ b/src/plugins/runner/osm/OsmWay.cpp
@@ -1,277 +1,277 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Dennis Nienhüser <nienhueser@kde.org>
//
#include <OsmRelation.h>
#include <MarbleDebug.h>
#include <GeoDataPlacemark.h>
#include <GeoDataLineStyle.h>
#include <GeoDataPolyStyle.h>
#include <GeoDataStyle.h>
#include <GeoDataDocument.h>
#include <osm/OsmObjectManager.h>
#include <MarbleDirs.h>
#include <StyleBuilder.h>
#include <GeoDataMultiGeometry.h>
namespace Marble {
QSet<StyleBuilder::OsmTag> OsmWay::s_areaTags;
QSet<StyleBuilder::OsmTag> OsmWay::s_buildingTags;
GeoDataPlacemark *OsmWay::create(const OsmNodes &nodes, QSet<qint64> &usedNodes) const
{
OsmPlacemarkData osmData = m_osmData;
- GeoDataGeometry *geometry = 0;
+ GeoDataGeometry *geometry = nullptr;
if (isArea()) {
GeoDataLinearRing linearRing;
linearRing.reserve(m_references.size());
bool const stripLastNode = m_references.first() == m_references.last();
for (int i=0, n=m_references.size() - (stripLastNode ? 1 : 0); i<n; ++i) {
qint64 nodeId = m_references[i];
auto const nodeIter = nodes.constFind(nodeId);
if (nodeIter == nodes.constEnd()) {
return nullptr;
}
OsmNode const & node = nodeIter.value();
osmData.addNodeReference(node.coordinates(), node.osmData());
linearRing.append(node.coordinates());
usedNodes << nodeId;
}
if (isBuilding()) {
GeoDataBuilding building;
building.setName(extractBuildingName());
building.setHeight(extractBuildingHeight());
building.setEntries(extractNamedEntries());
building.multiGeometry()->append(new GeoDataLinearRing(linearRing.optimized()));
geometry = new GeoDataBuilding(building);
} else {
geometry = new GeoDataLinearRing(linearRing.optimized());
}
} else {
GeoDataLineString lineString;
lineString.reserve(m_references.size());
for(auto nodeId: m_references) {
auto const nodeIter = nodes.constFind(nodeId);
if (nodeIter == nodes.constEnd()) {
return nullptr;
}
OsmNode const & node = nodeIter.value();
osmData.addNodeReference(node.coordinates(), node.osmData());
lineString.append(node.coordinates());
usedNodes << nodeId;
}
geometry = new GeoDataLineString(lineString.optimized());
}
Q_ASSERT(geometry != nullptr);
OsmObjectManager::registerId(m_osmData.id());
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setGeometry(geometry);
placemark->setVisualCategory(StyleBuilder::determineVisualCategory(m_osmData));
placemark->setName(m_osmData.tagValue(QStringLiteral("name")));
if (placemark->name().isEmpty()) {
placemark->setName(m_osmData.tagValue(QStringLiteral("ref")));
}
placemark->setOsmData(osmData);
placemark->setZoomLevel(StyleBuilder::minimumZoomLevel(placemark->visualCategory()));
placemark->setPopularity(StyleBuilder::popularity(placemark));
placemark->setVisible(placemark->visualCategory() != GeoDataPlacemark::None);
return placemark;
}
const QVector<qint64> &OsmWay::references() const
{
return m_references;
}
OsmPlacemarkData &OsmWay::osmData()
{
return m_osmData;
}
const OsmPlacemarkData &OsmWay::osmData() const
{
return m_osmData;
}
void OsmWay::addReference(qint64 id)
{
m_references << id;
}
bool OsmWay::isArea() const
{
// @TODO A single OSM way can be both closed and non-closed, e.g. landuse=grass with barrier=fence.
// We need to create two separate ways in cases like that to support this.
// See also https://wiki.openstreetmap.org/wiki/Key:area
if (m_osmData.containsTag(QStringLiteral("area"), QStringLiteral("yes"))) {
return true;
}
bool const isLinearFeature =
m_osmData.containsTag(QStringLiteral("area"), QStringLiteral("no")) ||
m_osmData.containsTagKey(QStringLiteral("highway")) ||
m_osmData.containsTagKey(QStringLiteral("barrier"));
if (isLinearFeature) {
return false;
}
bool const isAreaFeature = m_osmData.containsTagKey(QStringLiteral("landuse"));
if (isAreaFeature) {
return true;
}
for (auto iter = m_osmData.tagsBegin(), end=m_osmData.tagsEnd(); iter != end; ++iter) {
const auto tag = StyleBuilder::OsmTag(iter.key(), iter.value());
if (isAreaTag(tag)) {
return true;
}
}
bool const isImplicitlyClosed = m_references.size() > 1 && m_references.front() == m_references.last();
return isImplicitlyClosed;
}
bool OsmWay::isAreaTag(const StyleBuilder::OsmTag &keyValue)
{
if (s_areaTags.isEmpty()) {
// All these tags can be found updated at
// http://wiki.openstreetmap.org/wiki/Map_Features#Landuse
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("natural"), QStringLiteral("water")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("natural"), QStringLiteral("wood")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("natural"), QStringLiteral("beach")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("natural"), QStringLiteral("wetland")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("natural"), QStringLiteral("glacier")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("natural"), QStringLiteral("scrub")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("natural"), QStringLiteral("cliff")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("area"), QStringLiteral("yes")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("waterway"), QStringLiteral("riverbank")));
for (auto const & tag: StyleBuilder::buildingTags()) {
s_areaTags.insert(tag);
}
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("man_made"), QStringLiteral("bridge")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("graveyard")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("parking")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("parking_space")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("bicycle_parking")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("college")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("hospital")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("kindergarten")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("school")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("amenity"), QStringLiteral("university")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("common")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("garden")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("golf_course")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("marina")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("playground")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("pitch")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("park")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("sports_centre")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("stadium")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("swimming_pool")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("leisure"), QStringLiteral("track")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("military"), QStringLiteral("danger_area")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("marble_land"), QStringLiteral("landmass")));
s_areaTags.insert(StyleBuilder::OsmTag(QStringLiteral("settlement"), QStringLiteral("yes")));
}
return s_areaTags.contains(keyValue);
}
bool OsmWay::isBuilding() const
{
for (auto iter = m_osmData.tagsBegin(), end=m_osmData.tagsEnd(); iter != end; ++iter) {
const auto tag = StyleBuilder::OsmTag(iter.key(), iter.value());
if (isBuildingTag(tag)) {
return true;
}
}
return false;
}
bool OsmWay::isBuildingTag(const StyleBuilder::OsmTag &keyValue)
{
if (s_buildingTags.isEmpty()) {
for (auto const & tag: StyleBuilder::buildingTags()) {
s_buildingTags.insert(tag);
}
}
return s_buildingTags.contains(keyValue);
}
QString OsmWay::extractBuildingName() const
{
auto tagIter = m_osmData.findTag(QStringLiteral("addr:housename"));
if (tagIter != m_osmData.tagsEnd()) {
return tagIter.value();
}
tagIter = m_osmData.findTag(QStringLiteral("addr:housenumber"));
if (tagIter != m_osmData.tagsEnd()) {
return tagIter.value();
}
return QString();
}
double OsmWay::extractBuildingHeight() const
{
double height = 8.0;
QHash<QString, QString>::const_iterator tagIter;
if ((tagIter = m_osmData.findTag(QStringLiteral("height"))) != m_osmData.tagsEnd()) {
height = GeoDataBuilding::parseBuildingHeight(tagIter.value());
} else if ((tagIter = m_osmData.findTag(QStringLiteral("building:levels"))) != m_osmData.tagsEnd()) {
int const levels = tagIter.value().toInt();
int const skipLevels = m_osmData.tagValue(QStringLiteral("building:min_level")).toInt();
/** @todo Is 35 as an upper bound for the number of levels sane? */
height = 3.0 * qBound(1, 1+levels-skipLevels, 35);
}
return qBound(1.0, height, 1000.0);
}
QVector<GeoDataBuilding::NamedEntry> OsmWay::extractNamedEntries() const
{
QVector<GeoDataBuilding::NamedEntry> entries;
const auto end = m_osmData.nodeReferencesEnd();
for (auto iter = m_osmData.nodeReferencesBegin(); iter != end; ++iter) {
const auto tagIter = iter.value().findTag(QStringLiteral("addr:housenumber"));
if (tagIter != iter.value().tagsEnd()) {
GeoDataBuilding::NamedEntry entry;
entry.point = iter.key();
entry.label = tagIter.value();
entries.push_back(entry);
}
}
return entries;
}
}
diff --git a/src/plugins/runner/pn2/Pn2Plugin.h b/src/plugins/runner/pn2/Pn2Plugin.h
index d290fed78..e58431cb8 100644
--- a/src/plugins/runner/pn2/Pn2Plugin.h
+++ b/src/plugins/runner/pn2/Pn2Plugin.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Cezar Mocan <mocancezar@gmail.com>
#ifndef MARBLEPN2PLUGIN_H
#define MARBLEPN2PLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class Pn2Plugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.Pn2Plugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit Pn2Plugin( QObject *parent = 0 );
+ explicit Pn2Plugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLEPN2PLUGIN_H
diff --git a/src/plugins/runner/pn2/Pn2Runner.cpp b/src/plugins/runner/pn2/Pn2Runner.cpp
index 32a8f8afe..51498d0df 100644
--- a/src/plugins/runner/pn2/Pn2Runner.cpp
+++ b/src/plugins/runner/pn2/Pn2Runner.cpp
@@ -1,408 +1,408 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
//
// For the Natural Earth Layer providing the Default data set at 0.5 arcminute resolution should be enough.
// This fileformat allows for even better packed data than the PNT format. For detailed polygons at arcminute
// scale on average it should use only 33% of the amount used by PNT.
//
// Description of the file format
//
// In the fileformat initially a file header is provided that provides the file format version and the number
// of polygons stored inside the file. A Polygon starts with the Polygon Header which provides the feature id
// and the number of so called "absolute nodes" that are about to follow. Absolute nodes always contain
// absolute geodetic coordinates. The Polygon Header also provides a flag that allows to specify whether the
// polygon is supposed to represent a line string ("0") or a linear ring ("1"). Each absolute node can be followed
// by relative nodes: These relative nodes are always nodes that follow in correct order inside the polygon after
// "their" absolute node. Each absolute node specifies the number of relative nodes which contain relative
// coordinates in reference to their absolute node. So an absolute node provides the absolute reference for
// relative nodes across a theoretical area of 2x2 squaredegree-area (which in practice frequently might rather
// amount to 1x1 square degrees).
//
// So much of the compression works by just referencing lat/lon diffs to special "absolute nodes". Hence the
// compression will especially work well for polygons with many nodes with a high node density.
//
// The parser has to convert these relative coordinates to absolute coordinates.
//
// Copyright 2012 Torsten Rahn <rahn@kde.org>
// Copyright 2012 Cezar Mocan <mocancezar@gmail.com>
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
#include "Pn2Runner.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataStyle.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPolygon.h"
#include "GeoDataMultiGeometry.h"
#include "MarbleDebug.h"
#include <QFile>
#include <QFileInfo>
namespace Marble
{
// Polygon header flags, representing the type of polygon
enum polygonFlagType { LINESTRING = 0, LINEARRING = 1, OUTERBOUNDARY = 2, INNERBOUNDARY = 3, MULTIGEOMETRY = 4 };
Pn2Runner::Pn2Runner(QObject *parent) :
ParsingRunner(parent)
{
}
Pn2Runner::~Pn2Runner()
{
}
bool Pn2Runner::errorCheckLat( qint16 lat )
{
return !(lat >= -10800 && lat <= +10800);
}
bool Pn2Runner::errorCheckLon( qint16 lon )
{
return !(lon >= -21600 && lon <= +21600);
}
bool Pn2Runner::importPolygon( QDataStream &stream, GeoDataLineString* linestring, quint32 nrAbsoluteNodes )
{
qint16 lat, lon, nrRelativeNodes;
qint8 relativeLat, relativeLon;
bool error = false;
for ( quint32 absoluteNode = 1; absoluteNode <= nrAbsoluteNodes; absoluteNode++ ) {
stream >> lat >> lon >> nrRelativeNodes;
error = error | errorCheckLat( lat ) | errorCheckLon( lon );
qreal degLat = ( 1.0 * lat / 120.0 );
qreal degLon = ( 1.0 * lon / 120.0 );
GeoDataCoordinates coord( degLon / 180 * M_PI, degLat / 180 * M_PI );
linestring->append( coord );
for ( qint16 relativeNode = 1; relativeNode <= nrRelativeNodes; ++relativeNode ) {
stream >> relativeLat >> relativeLon;
qint16 currLat = relativeLat + lat;
qint16 currLon = relativeLon + lon;
error = error | errorCheckLat( currLat ) | errorCheckLon( currLon );
qreal currDegLat = ( 1.0 * currLat / 120.0 );
qreal currDegLon = ( 1.0 * currLon / 120.0 );
GeoDataCoordinates currCoord( currDegLon / 180 * M_PI, currDegLat / 180 * M_PI );
linestring->append( currCoord );
}
}
*linestring = linestring->optimized();
return error;
}
GeoDataDocument *Pn2Runner::parseFile(const QString &fileName, DocumentRole role, QString &error)
{
QFileInfo fileinfo( fileName );
if (fileinfo.suffix().compare(QLatin1String("pn2"), Qt::CaseInsensitive) != 0) {
error = QStringLiteral("File %1 does not have a pn2 suffix").arg(fileName);
mDebug() << error;
return nullptr;
}
QFile file( fileName );
if ( !file.exists() ) {
error = QStringLiteral("File %1 does not exist").arg(fileName);
mDebug() << error;
return nullptr;
}
file.open( QIODevice::ReadOnly );
m_stream.setDevice( &file ); // read the data serialized from the file
m_stream >> m_fileHeaderVersion >> m_fileHeaderPolygons >> m_isMapColorField;
switch( m_fileHeaderVersion ) {
case 1: return parseForVersion1( fileName, role );
break;
case 2: return parseForVersion2( fileName, role );
break;
default: qDebug() << "File can't be parsed. We don't have parser for file header version:" << m_fileHeaderVersion;
break;
}
return nullptr;
}
GeoDataDocument* Pn2Runner::parseForVersion1(const QString& fileName, DocumentRole role)
{
GeoDataDocument *document = new GeoDataDocument();
document->setDocumentRole( role );
bool error = false;
quint32 ID, nrAbsoluteNodes;
quint8 flag, prevFlag = -1;
GeoDataStyle::Ptr style;
GeoDataPolygon *polygon = new GeoDataPolygon;
for ( quint32 currentPoly = 1; ( currentPoly <= m_fileHeaderPolygons ) && ( !error ) && ( !m_stream.atEnd() ); currentPoly++ ) {
m_stream >> ID >> nrAbsoluteNodes >> flag;
if ( flag != INNERBOUNDARY && ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) ) {
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setGeometry( polygon );
if ( m_isMapColorField ) {
if ( style ) {
placemark->setStyle( style );
}
}
document->append( placemark );
}
if ( flag == LINESTRING ) {
GeoDataLineString *linestring = new GeoDataLineString;
error = error | importPolygon( m_stream, linestring, nrAbsoluteNodes );
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setGeometry( linestring );
document->append( placemark );
}
if ( ( flag == LINEARRING ) || ( flag == OUTERBOUNDARY ) || ( flag == INNERBOUNDARY ) ) {
if ( flag == OUTERBOUNDARY && m_isMapColorField ) {
quint8 colorIndex;
m_stream >> colorIndex;
style = GeoDataStyle::Ptr(new GeoDataStyle);
GeoDataPolyStyle polyStyle;
polyStyle.setColorIndex( colorIndex );
style->setPolyStyle( polyStyle );
}
GeoDataLinearRing* linearring = new GeoDataLinearRing;
error = error | importPolygon( m_stream, linearring, nrAbsoluteNodes );
if ( flag == LINEARRING ) {
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setGeometry( linearring );
document->append( placemark );
}
if ( flag == OUTERBOUNDARY ) {
polygon = new GeoDataPolygon;
polygon->setOuterBoundary( *linearring );
}
if ( flag == INNERBOUNDARY ) {
polygon->appendInnerBoundary( *linearring );
}
}
if ( flag == MULTIGEOMETRY ) {
// not implemented yet, for now elements inside a multigeometry are separated as individual geometries
}
prevFlag = flag;
}
if ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) {
GeoDataPlacemark *placemark = new GeoDataPlacemark;
if ( m_isMapColorField ) {
if ( style ) {
placemark->setStyle( style );
}
}
placemark->setGeometry( polygon );
document->append( placemark );
}
if ( error ) {
delete document;
- document = 0;
+ document = nullptr;
return nullptr;
}
document->setFileName( fileName );
return document;
}
GeoDataDocument* Pn2Runner::parseForVersion2( const QString &fileName, DocumentRole role )
{
GeoDataDocument *document = new GeoDataDocument();
document->setDocumentRole( role );
bool error = false;
quint32 nrAbsoluteNodes;
quint32 placemarkCurrentID = 1;
quint32 placemarkPrevID = 0;
quint8 flag, prevFlag = -1;
GeoDataPolygon *polygon = new GeoDataPolygon;
GeoDataStyle::Ptr style;
- GeoDataPlacemark *placemark =0; // new GeoDataPlacemark;
+ GeoDataPlacemark *placemark =nullptr; // new GeoDataPlacemark;
quint32 currentPoly;
for ( currentPoly = 1; ( currentPoly <= m_fileHeaderPolygons ) && ( !error ) && ( !m_stream.atEnd() ); currentPoly++ ) {
m_stream >> flag >> placemarkCurrentID;
if ( flag == MULTIGEOMETRY && ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) ) {
if ( placemark ) {
placemark->setGeometry( polygon );
}
}
if ( flag != MULTIGEOMETRY && flag != INNERBOUNDARY && ( prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY ) ) {
if ( placemark ) {
placemark->setGeometry( polygon );
}
}
/**
* If the parsed placemark id @p placemarkCurrentID is different
* from the id of previous placemark @p placemarkPrevID, it means
* we have encountered a new placemark. So, prepare a style @p style
* if file has color indices
*/
if ( placemarkCurrentID != placemarkPrevID ) {
placemark = new GeoDataPlacemark;
// Handle the color index
if( m_isMapColorField ) {
quint8 colorIndex;
m_stream >> colorIndex;
style = GeoDataStyle::Ptr(new GeoDataStyle);
GeoDataPolyStyle polyStyle;
polyStyle.setColorIndex( colorIndex );
polyStyle.setFill( true );
style->setPolyStyle( polyStyle );
placemark->setStyle( style );
}
document->append( placemark );
}
placemarkPrevID = placemarkCurrentID;
if ( flag != MULTIGEOMETRY ) {
m_stream >> nrAbsoluteNodes;
if ( flag == LINESTRING ) {
GeoDataLineString *linestring = new GeoDataLineString;
error = error | importPolygon( m_stream, linestring, nrAbsoluteNodes );
if ( placemark ) {
placemark->setGeometry( linestring );
}
}
if ( ( flag == LINEARRING ) || ( flag == OUTERBOUNDARY ) || ( flag == INNERBOUNDARY ) ) {
GeoDataLinearRing* linearring = new GeoDataLinearRing;
error = error || importPolygon( m_stream, linearring, nrAbsoluteNodes );
if ( flag == LINEARRING ) {
if ( placemark ) {
placemark->setGeometry( linearring );
}
} else {
if ( flag == OUTERBOUNDARY ) {
polygon = new GeoDataPolygon;
polygon->setOuterBoundary( *linearring );
}
if ( flag == INNERBOUNDARY ) {
polygon->appendInnerBoundary( *linearring );
}
delete linearring;
}
}
prevFlag = flag;
}
else {
quint32 placemarkCurrentIDInMulti;
quint8 flagInMulti;
quint8 prevFlagInMulti = -1;
quint8 multiSize = 0;
m_stream >> multiSize;
GeoDataMultiGeometry *multigeom = new GeoDataMultiGeometry;
/**
* Read @p multiSize GeoDataGeometry objects
*/
for ( int iter = 0; iter < multiSize; ++iter ) {
m_stream >> flagInMulti >> placemarkCurrentIDInMulti >> nrAbsoluteNodes;
if ( flagInMulti != INNERBOUNDARY && ( prevFlagInMulti == INNERBOUNDARY || prevFlagInMulti == OUTERBOUNDARY ) ) {
multigeom->append( polygon );
}
if ( flagInMulti == LINESTRING ) {
GeoDataLineString *linestring = new GeoDataLineString;
error = error || importPolygon( m_stream, linestring, nrAbsoluteNodes );
multigeom->append( linestring );
}
if ( ( flagInMulti == LINEARRING ) || ( flagInMulti == OUTERBOUNDARY ) || ( flagInMulti == INNERBOUNDARY ) ) {
GeoDataLinearRing* linearring = new GeoDataLinearRing;
error = error | importPolygon( m_stream, linearring, nrAbsoluteNodes );
if ( flagInMulti == LINEARRING ) {
multigeom->append( linearring );
} else {
if ( flagInMulti == OUTERBOUNDARY ) {
polygon = new GeoDataPolygon;
polygon->setOuterBoundary( *linearring );
}
if ( flagInMulti == INNERBOUNDARY ) {
polygon->appendInnerBoundary( *linearring );
}
delete linearring;
}
}
prevFlagInMulti = flagInMulti;
}
if ( prevFlagInMulti == INNERBOUNDARY || prevFlagInMulti == OUTERBOUNDARY ) {
multigeom->append( polygon );
}
if ( placemark ) {
placemark->setGeometry( multigeom );
}
prevFlag = MULTIGEOMETRY;
}
}
if ( (prevFlag == INNERBOUNDARY || prevFlag == OUTERBOUNDARY) && prevFlag != MULTIGEOMETRY ) {
placemark->setGeometry( polygon );
}
if ( error ) {
delete document;
- document = 0;
+ document = nullptr;
return nullptr;
}
document->setFileName( fileName );
return document;
}
}
#include "moc_Pn2Runner.cpp"
diff --git a/src/plugins/runner/pn2/Pn2Runner.h b/src/plugins/runner/pn2/Pn2Runner.h
index a4ee64f2e..2ace80f71 100644
--- a/src/plugins/runner/pn2/Pn2Runner.h
+++ b/src/plugins/runner/pn2/Pn2Runner.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Cezar Mocan <mocancezar@gmail.com>
#ifndef MARBLEPN2RUNNER_H
#define MARBLEPN2RUNNER_H
#include "ParsingRunner.h"
#include <QDataStream>
class QDataStream;
namespace Marble
{
class GeoDataLineString;
class Pn2Runner : public ParsingRunner
{
Q_OBJECT
public:
- explicit Pn2Runner(QObject *parent = 0);
+ explicit Pn2Runner(QObject *parent = nullptr);
~Pn2Runner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
private:
static bool errorCheckLat( qint16 lat );
static bool errorCheckLon( qint16 lon );
static bool importPolygon( QDataStream &stream, GeoDataLineString* linestring, quint32 nrAbsoluteNodes );
GeoDataDocument* parseForVersion1( const QString &fileName, DocumentRole role );
GeoDataDocument* parseForVersion2( const QString &fileName, DocumentRole role );
QDataStream m_stream;
quint8 m_fileHeaderVersion;
quint32 m_fileHeaderPolygons;
bool m_isMapColorField; // Whether the file contains color indexes
};
}
#endif // MARBLEPN2RUNNER_H
diff --git a/src/plugins/runner/pnt/PntPlugin.h b/src/plugins/runner/pnt/PntPlugin.h
index 8bdefb9be..8a4a67b12 100644
--- a/src/plugins/runner/pnt/PntPlugin.h
+++ b/src/plugins/runner/pnt/PntPlugin.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEPNTPLUGIN_H
#define MARBLEPNTPLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class PntPlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.PntPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit PntPlugin( QObject *parent = 0 );
+ explicit PntPlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLEPNTPLUGIN_H
diff --git a/src/plugins/runner/pnt/PntRunner.cpp b/src/plugins/runner/pnt/PntRunner.cpp
index 5b489d4ac..af5dc5c3b 100644
--- a/src/plugins/runner/pnt/PntRunner.cpp
+++ b/src/plugins/runner/pnt/PntRunner.cpp
@@ -1,212 +1,212 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
#include "PntRunner.h"
#include "GeoDataDocument.h"
#include "GeoDataLineString.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPlacemark.h"
#include "MarbleDebug.h"
#include "MarbleGlobal.h"
#include <qmath.h>
#include <QFile>
#include <QFileInfo>
#include <QDataStream>
namespace Marble
{
// distance of 180deg in arcminutes
const qreal INT2RAD = M_PI / 10800.0;
PntRunner::PntRunner(QObject *parent) :
ParsingRunner(parent)
{
}
PntRunner::~PntRunner()
{
}
GeoDataDocument *PntRunner::parseFile(const QString &fileName, DocumentRole role, QString &errorString)
{
QFileInfo fileinfo( fileName );
if (fileinfo.suffix().compare(QLatin1String("pnt"), Qt::CaseInsensitive) != 0) {
errorString = QStringLiteral("File %1 does not have a pnt suffix").arg(fileName);
mDebug() << errorString;
return nullptr;
}
QFile file( fileName );
if ( !file.exists() ) {
errorString = QStringLiteral("File %1 does not exist").arg(fileName);
mDebug() << errorString;
return nullptr;
}
file.open( QIODevice::ReadOnly );
QDataStream stream( &file ); // read the data serialized from the file
stream.setByteOrder( QDataStream::LittleEndian );
GeoDataDocument *document = new GeoDataDocument();
document->setDocumentRole( role );
- GeoDataPlacemark *placemark = 0;
+ GeoDataPlacemark *placemark = nullptr;
int count = 0;
bool error = false;
while( !stream.atEnd() || error ){
short header = -1;
short iLat = -5400 - 1;
short iLon = -10800 - 1;
stream >> header >> iLat >> iLon;
// make sure iLat is within valid range
if ( !( -5400 <= iLat && iLat <= 5400 ) ) {
mDebug() << Q_FUNC_INFO << "invalid iLat =" << iLat << "(" << ( iLat * INT2RAD ) * RAD2DEG << ") in dataset" << count << "of file" << fileName;
error = true;
}
// make sure iLon is within valid range
if ( !( -10800 <= iLon && iLon <= 10800 ) ) {
mDebug() << Q_FUNC_INFO << "invalid iLon =" << iLon << "(" << ( iLon * INT2RAD ) * RAD2DEG << ") in dataset" << count << "of file" << fileName;
error = true;
}
if (header >= 1000 && !document->isEmpty()) {
GeoDataLineString *const polyline = static_cast<GeoDataLineString*>( placemark->geometry() );
if ( polyline->size() == 1 ) {
mDebug() << Q_FUNC_INFO << fileName << "contains single-point polygon at" << count << ". Aborting.";
error = true;
break;
}
}
if ( header < 1 ) {
/* invalid header */
mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
error = true;
break;
}
else if ( header <= 5 ) {
/* header represents level of detail */
/* nothing to do */
}
else if ( header < 1000 ) {
/* invalid header */
mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
error = true;
break;
}
else if ( header < 2000 ) {
/* header represents start of coastline */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLinearRing );
}
else if ( header < 4000 ) {
/* header represents start of country border */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLineString );
}
else if ( header < 5000 ) {
/* header represents start of internal political border */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLineString );
}
else if ( header < 6000 ) {
/* header represents start of island */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLinearRing );
}
else if ( header < 7000 ) {
/* header represents start of lake */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLinearRing );
}
else if ( header < 8000 ) {
/* header represents start of river */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLineString );
}
else if ( header < 9000 ) {
/* custom header represents start of glaciers, lakes or islands */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLinearRing );
}
else if ( header < 10000 ) {
/* custom header represents start of political borders */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLineString );
}
else if ( header < 14000 ) {
/* invalid header */
mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
error = true;
break;
}
else if ( header < 15000 ) {
/* custom header represents start of political borders */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLineString );
}
else if ( header < 19000 ) {
/* invalid header */
mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
error = true;
break;
}
else if ( header < 20000 ) {
/* custom header represents start of dateline */
placemark = new GeoDataPlacemark;
document->append( placemark );
placemark->setGeometry( new GeoDataLineString );
}
else {
/* invalid header */
mDebug() << Q_FUNC_INFO << "invalid header:" << header << "in" << fileName << "at" << count;
error = true;
break;
}
GeoDataLineString *polyline = static_cast<GeoDataLineString*>( placemark->geometry() );
// Transforming Range of Coordinates to iLat [0,ARCMINUTE] , iLon [0,2 * ARCMINUTE]
polyline->append( GeoDataCoordinates( (qreal)(iLon) * INT2RAD, (qreal)(iLat) * INT2RAD,
0.0, GeoDataCoordinates::Radian,
5 - qMin( 5, (int)header ) ) ); // if 1 <= header <= 5, header contains level of detail
// else pick most sparse level of detail, which equals 0
++count;
}
file.close();
if (document->isEmpty() || error) {
delete document;
- document = 0;
+ document = nullptr;
return nullptr;
}
document->setFileName( fileName );
return document;
}
}
#include "moc_PntRunner.cpp"
diff --git a/src/plugins/runner/pnt/PntRunner.h b/src/plugins/runner/pnt/PntRunner.h
index a44385c99..dbe73d142 100644
--- a/src/plugins/runner/pnt/PntRunner.h
+++ b/src/plugins/runner/pnt/PntRunner.h
@@ -1,28 +1,28 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLEPNTRUNNER_H
#define MARBLEPNTRUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class PntRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit PntRunner(QObject *parent = 0);
+ explicit PntRunner(QObject *parent = nullptr);
~PntRunner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLEPNTRUNNER_H
diff --git a/src/plugins/runner/routino/RoutinoPlugin.h b/src/plugins/runner/routino/RoutinoPlugin.h
index 0ec7112d0..3afdb39ba 100644
--- a/src/plugins/runner/routino/RoutinoPlugin.h
+++ b/src/plugins/runner/routino/RoutinoPlugin.h
@@ -1,56 +1,56 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTINOPLUGIN_H
#define MARBLE_ROUTINOPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class RoutinoPlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.RoutinoPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
- explicit RoutinoPlugin( QObject *parent = 0 );
+ explicit RoutinoPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
RoutingRunner *newRunner() const override;
ConfigWidget* configWidget() override;
bool supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const override;
QHash< QString, QVariant > templateSettings(RoutingProfilesModel::ProfileTemplate profileTemplate) const override;
bool canWork() const override;
};
}
#endif
diff --git a/src/plugins/runner/routino/RoutinoRunner.cpp b/src/plugins/runner/routino/RoutinoRunner.cpp
index 2a9d6c3ae..e6e1cd3fb 100644
--- a/src/plugins/runner/routino/RoutinoRunner.cpp
+++ b/src/plugins/runner/routino/RoutinoRunner.cpp
@@ -1,272 +1,272 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2010 Niko Sams <niko.sams@gmail.com>
//
#include "RoutinoRunner.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "routing/RouteRequest.h"
#include "routing/instructions/WaypointParser.h"
#include "routing/instructions/InstructionTransformation.h"
#include "GeoDataDocument.h"
#include "GeoDataExtendedData.h"
#include "GeoDataData.h"
#include "GeoDataPlacemark.h"
#include "GeoDataLineString.h"
#include <QProcess>
#include <QTemporaryFile>
#include <MarbleMap.h>
#include <MarbleModel.h>
#include <routing/RoutingManager.h>
#include <routing/RoutingProfilesModel.h>
namespace Marble
{
class RoutinoRunnerPrivate
{
public:
QDir m_mapDir;
WaypointParser m_parser;
QByteArray retrieveWaypoints( const QStringList &params ) const;
static GeoDataDocument* createDocument( GeoDataLineString* routeWaypoints, const QVector<GeoDataPlacemark*> instructions );
static GeoDataLineString* parseRoutinoOutput( const QByteArray &content );
QVector<GeoDataPlacemark*> parseRoutinoInstructions( const QByteArray &content ) const;
RoutinoRunnerPrivate();
};
RoutinoRunnerPrivate::RoutinoRunnerPrivate()
{
m_parser.setLineSeparator("\n");
m_parser.setFieldSeparator(QLatin1Char('\t'));
m_parser.setFieldIndex( WaypointParser::RoadName, 10 );
}
class TemporaryDir
{
public:
TemporaryDir() {
QTemporaryFile f;
f.setAutoRemove( false );
f.open();
m_dirName = f.fileName();
f.close();
f.remove();
QFileInfo( m_dirName ).dir().mkdir( m_dirName );
}
~TemporaryDir() {
QDir dir( m_dirName );
QFileInfoList entries = dir.entryInfoList( QDir::Files );
for ( const QFileInfo &file: entries ) {
QFile( file.absoluteFilePath() ).remove();
}
dir.rmdir( dir.absolutePath() );
}
QString dirName() const
{
return m_dirName;
}
private:
QString m_dirName;
};
QByteArray RoutinoRunnerPrivate::retrieveWaypoints( const QStringList &params ) const
{
TemporaryDir dir;
QProcess routinoProcess;
routinoProcess.setWorkingDirectory( dir.dirName() );
QStringList routinoParams;
routinoParams << params;
routinoParams << QLatin1String("--dir=") + m_mapDir.absolutePath();
routinoParams << "--output-text-all";
mDebug() << routinoParams;
routinoProcess.start( "routino-router", routinoParams );
if ( !routinoProcess.waitForStarted( 5000 ) ) {
mDebug() << "Couldn't start routino-router from the current PATH. Install it to retrieve routing results from routino.";
- return 0;
+ return nullptr;
}
if ( routinoProcess.waitForFinished(60 * 1000) ) {
mDebug() << routinoProcess.readAll();
mDebug() << "routino finished";
QFile file(routinoProcess.workingDirectory() + QLatin1String("/shortest-all.txt"));
if ( !file.exists() ) {
file.setFileName(routinoProcess.workingDirectory() + QLatin1String("/quickest-all.txt"));
}
if ( !file.exists() ) {
mDebug() << "Can't get results";
} else {
file.open( QIODevice::ReadOnly );
return file.readAll();
}
}
else {
mDebug() << "Couldn't stop routino";
}
- return 0;
+ return nullptr;
}
GeoDataLineString* RoutinoRunnerPrivate::parseRoutinoOutput( const QByteArray &content )
{
GeoDataLineString* routeWaypoints = new GeoDataLineString;
const QStringList lines = QString::fromUtf8(content).split(QLatin1Char('\n'));
mDebug() << lines.count() << "lines";
for( const QString &line: lines ) {
if (line.startsWith(QLatin1Char('#'))) {
//skip comment
continue;
}
const QStringList fields = line.split(QLatin1Char('\t'));
if ( fields.size() >= 10 ) {
qreal lon = fields.at(1).trimmed().toDouble();
qreal lat = fields.at(0).trimmed().toDouble();
GeoDataCoordinates coordinates( lon, lat, 0.0, GeoDataCoordinates::Degree );
routeWaypoints->append( coordinates );
}
}
return routeWaypoints;
}
QVector<GeoDataPlacemark*> RoutinoRunnerPrivate::parseRoutinoInstructions( const QByteArray &content ) const
{
QVector<GeoDataPlacemark*> result;
QTextStream stream( content );
stream.setCodec("UTF8");
stream.setAutoDetectUnicode( true );
RoutingInstructions directions = InstructionTransformation::process( m_parser.parse( stream ) );
for( int i=0; i<directions.size(); ++i ) {
GeoDataPlacemark* placemark = new GeoDataPlacemark( directions[i].instructionText() );
GeoDataExtendedData extendedData;
GeoDataData turnType;
turnType.setName(QStringLiteral("turnType"));
turnType.setValue( qVariantFromValue<int>( int( directions[i].turnType() ) ) );
extendedData.addValue( turnType );
GeoDataData roadName;
roadName.setName(QStringLiteral("roadName"));
roadName.setValue( directions[i].roadName() );
extendedData.addValue( roadName );
placemark->setExtendedData( extendedData );
Q_ASSERT( !directions[i].points().isEmpty() );
GeoDataLineString* geometry = new GeoDataLineString;
QVector<RoutingWaypoint> items = directions[i].points();
for (int j=0; j<items.size(); ++j ) {
RoutingPoint point = items[j].point();
GeoDataCoordinates coordinates( point.lon(), point.lat(), 0.0, GeoDataCoordinates::Degree );
geometry->append( coordinates );
}
placemark->setGeometry( geometry );
result.push_back( placemark );
}
return result;
}
GeoDataDocument* RoutinoRunnerPrivate::createDocument( GeoDataLineString* routeWaypoints, const QVector<GeoDataPlacemark*> instructions )
{
if ( !routeWaypoints || routeWaypoints->isEmpty() ) {
- return 0;
+ return nullptr;
}
GeoDataDocument* result = new GeoDataDocument();
GeoDataPlacemark* routePlacemark = new GeoDataPlacemark;
routePlacemark->setName( "Route" );
routePlacemark->setGeometry( routeWaypoints );
result->append( routePlacemark );
QString name = "%1 %2 (Routino)";
QString unit = QLatin1String( "m" );
qreal length = routeWaypoints->length( EARTH_RADIUS );
if (length >= 1000) {
length /= 1000.0;
unit = "km";
}
result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );
for( GeoDataPlacemark* placemark: instructions )
{
result->append( placemark );
}
return result;
}
RoutinoRunner::RoutinoRunner( QObject *parent ) :
RoutingRunner( parent ),
d( new RoutinoRunnerPrivate )
{
// Check installation
d->m_mapDir = QDir(MarbleDirs::localPath() + QLatin1String("/maps/earth/routino/"));
}
RoutinoRunner::~RoutinoRunner()
{
delete d;
}
void RoutinoRunner::retrieveRoute( const RouteRequest *route )
{
mDebug();
if ( ! QFileInfo( d->m_mapDir, "nodes.mem" ).exists() )
{
- emit routeCalculated( 0 );
+ emit routeCalculated( nullptr );
return;
}
QStringList params;
for( int i=0; i<route->size(); ++i )
{
double fLon = route->at(i).longitude( GeoDataCoordinates::Degree );
double fLat = route->at(i).latitude( GeoDataCoordinates::Degree );
params << QString("--lat%1=%2").arg(i+1).arg(fLat, 0, 'f', 8);
params << QString("--lon%1=%2").arg(i+1).arg(fLon, 0, 'f', 8);
}
QHash<QString, QVariant> settings = route->routingProfile().pluginSettings()[QStringLiteral("routino")];
QString transport = settings[QStringLiteral("transport")].toString();
params << QString( "--transport=%0" ).arg( transport );
if (settings[QStringLiteral("method")] == QLatin1String("shortest")) {
params << "--shortest";
} else {
params << "--quickest";
}
/*
if ( route->avoidFeatures() & RouteRequest::AvoidHighway ) {
params << "--highway-motorway=0";
}
*/
QByteArray output = d->retrieveWaypoints( params );
GeoDataLineString* wayPoints = d->parseRoutinoOutput( output );
QVector<GeoDataPlacemark*> instructions = d->parseRoutinoInstructions( output );
GeoDataDocument* result = d->createDocument( wayPoints, instructions );
mDebug() << this << "routeCalculated";
emit routeCalculated( result );
}
} // namespace Marble
#include "moc_RoutinoRunner.cpp"
diff --git a/src/plugins/runner/routino/RoutinoRunner.h b/src/plugins/runner/routino/RoutinoRunner.h
index f7b7e8bc8..4ea5ac691 100644
--- a/src/plugins/runner/routino/RoutinoRunner.h
+++ b/src/plugins/runner/routino/RoutinoRunner.h
@@ -1,39 +1,39 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_ROUTINORUNNER_H
#define MARBLE_ROUTINORUNNER_H
#include "RoutingRunner.h"
namespace Marble
{
class RoutinoRunnerPrivate;
class RoutinoRunner : public RoutingRunner
{
Q_OBJECT
public:
- explicit RoutinoRunner(QObject *parent = 0);
+ explicit RoutinoRunner(QObject *parent = nullptr);
~RoutinoRunner() override;
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
private:
RoutinoRunnerPrivate* const d;
};
}
#endif
diff --git a/src/plugins/runner/shp/ShpPlugin.h b/src/plugins/runner/shp/ShpPlugin.h
index 70e630c68..60f71bfed 100644
--- a/src/plugins/runner/shp/ShpPlugin.h
+++ b/src/plugins/runner/shp/ShpPlugin.h
@@ -1,47 +1,47 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLESHPPLUGIN_H
#define MARBLESHPPLUGIN_H
#include "ParseRunnerPlugin.h"
namespace Marble
{
class ShpPlugin : public ParseRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.ShpPlugin")
Q_INTERFACES( Marble::ParseRunnerPlugin )
public:
- explicit ShpPlugin( QObject *parent = 0 );
+ explicit ShpPlugin( QObject *parent = nullptr );
QString name() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
QString fileFormatDescription() const override;
QStringList fileExtensions() const override;
ParsingRunner* newRunner() const override;
};
}
#endif // MARBLESHPPLUGIN_H
diff --git a/src/plugins/runner/shp/ShpRunner.cpp b/src/plugins/runner/shp/ShpRunner.cpp
index e24720633..de605f48c 100644
--- a/src/plugins/runner/shp/ShpRunner.cpp
+++ b/src/plugins/runner/shp/ShpRunner.cpp
@@ -1,232 +1,232 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#include "ShpRunner.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPolygon.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPoint.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataSchema.h"
#include "GeoDataSimpleField.h"
#include "GeoDataStyle.h"
#include "GeoDataPolyStyle.h"
#include "MarbleDebug.h"
#include <QFileInfo>
#include <shapefil.h>
namespace Marble
{
ShpRunner::ShpRunner(QObject *parent) :
ParsingRunner(parent)
{
}
ShpRunner::~ShpRunner()
{
}
GeoDataDocument *ShpRunner::parseFile(const QString &fileName, DocumentRole role, QString &error)
{
QFileInfo fileinfo( fileName );
if (fileinfo.suffix().compare(QLatin1String("shp"), Qt::CaseInsensitive) != 0) {
error = QStringLiteral("File %1 does not have a shp suffix").arg(fileName);
mDebug() << error;
return nullptr;
}
SHPHandle handle = SHPOpen( fileName.toStdString().c_str(), "rb" );
if ( !handle ) {
error = QStringLiteral("Failed to read %1").arg(fileName);
mDebug() << error;
return nullptr;
}
int entities;
int shapeType;
- SHPGetInfo( handle, &entities, &shapeType, NULL, NULL );
+ SHPGetInfo( handle, &entities, &shapeType, nullptr, nullptr );
mDebug() << " SHP info " << entities << " Entities "
<< shapeType << " Shape Type ";
DBFHandle dbfhandle;
dbfhandle = DBFOpen( fileName.toStdString().c_str(), "rb");
int nameField = DBFGetFieldIndex( dbfhandle, "Name" );
int noteField = DBFGetFieldIndex( dbfhandle, "Note" );
int mapColorField = DBFGetFieldIndex( dbfhandle, "mapcolor13" );
GeoDataDocument *document = new GeoDataDocument;
document->setDocumentRole( role );
if ( mapColorField != -1 ) {
GeoDataSchema schema;
schema.setId(QStringLiteral("default"));
GeoDataSimpleField simpleField;
simpleField.setName(QStringLiteral("mapcolor13"));
simpleField.setType( GeoDataSimpleField::Double );
schema.addSimpleField( simpleField );
document->addSchema( schema );
}
for ( int i=0; i< entities; ++i ) {
- GeoDataPlacemark *placemark = 0;
+ GeoDataPlacemark *placemark = nullptr;
placemark = new GeoDataPlacemark;
document->append( placemark );
SHPObject *shape = SHPReadObject( handle, i );
if (nameField != -1) {
const char* info = DBFReadStringAttribute( dbfhandle, i, nameField );
// TODO: defaults to utf-8 encoding, but could be also something else, optionally noted in a .cpg file
placemark->setName( info );
mDebug() << "name " << placemark->name();
}
if (noteField != -1) {
const char* note = DBFReadStringAttribute( dbfhandle, i, noteField );
// TODO: defaults to utf-8 encoding, see comment for name
placemark->setDescription( note );
mDebug() << "desc " << placemark->description();
}
double mapColor = DBFReadDoubleAttribute( dbfhandle, i, mapColorField );
if ( mapColor ) {
GeoDataStyle::Ptr style(new GeoDataStyle);
if ( mapColor >= 0 && mapColor <=255 ) {
quint8 colorIndex = quint8( mapColor );
style->polyStyle().setColorIndex( colorIndex );
}
else {
quint8 colorIndex = 0; // mapColor is undefined in this case
style->polyStyle().setColorIndex( colorIndex );
}
placemark->setStyle( style );
}
switch ( shapeType ) {
case SHPT_POINT: {
GeoDataPoint *point = new GeoDataPoint( *shape->padfX, *shape->padfY, 0, GeoDataCoordinates::Degree );
placemark->setGeometry( point );
mDebug() << "point " << placemark->name();
break;
}
case SHPT_MULTIPOINT: {
GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
for( int j=0; j<shape->nVertices; ++j ) {
geom->append( new GeoDataPoint( GeoDataCoordinates(
shape->padfX[j], shape->padfY[j],
0, GeoDataCoordinates::Degree ) ) );
}
placemark->setGeometry( geom );
mDebug() << "multipoint " << placemark->name();
break;
}
case SHPT_ARC: {
if ( shape->nParts != 1 ) {
GeoDataMultiGeometry *geom = new GeoDataMultiGeometry;
for( int j=0; j<shape->nParts; ++j ) {
GeoDataLineString *line = new GeoDataLineString;
int itEnd = (j + 1 < shape->nParts) ? shape->panPartStart[j+1] : shape->nVertices;
for( int k=shape->panPartStart[j]; k<itEnd; ++k ) {
line->append( GeoDataCoordinates(
shape->padfX[k], shape->padfY[k],
0, GeoDataCoordinates::Degree ) );
}
geom->append( line );
}
placemark->setGeometry( geom );
mDebug() << "arc " << placemark->name() << " " << shape->nParts;
} else {
GeoDataLineString *line = new GeoDataLineString;
for( int j=0; j<shape->nVertices; ++j ) {
line->append( GeoDataCoordinates(
shape->padfX[j], shape->padfY[j],
0, GeoDataCoordinates::Degree ) );
}
placemark->setGeometry( line );
mDebug() << "arc " << placemark->name() << " " << shape->nParts;
}
break;
}
case SHPT_POLYGON: {
if ( shape->nParts != 1 ) {
bool isRingClockwise = false;
GeoDataMultiGeometry *multigeom = new GeoDataMultiGeometry;
- GeoDataPolygon *poly = 0;
+ GeoDataPolygon *poly = nullptr;
int polygonCount = 0;
for( int j=0; j<shape->nParts; ++j ) {
GeoDataLinearRing ring;
int itStart = shape->panPartStart[j];
int itEnd = (j + 1 < shape->nParts) ? shape->panPartStart[j+1] : shape->nVertices;
for( int k = itStart; k<itEnd; ++k ) {
ring.append( GeoDataCoordinates(
shape->padfX[k], shape->padfY[k],
0, GeoDataCoordinates::Degree ) );
}
isRingClockwise = ring.isClockwise();
if ( j == 0 || isRingClockwise ) {
poly = new GeoDataPolygon;
++polygonCount;
poly->setOuterBoundary( ring );
if ( polygonCount > 1 ) {
multigeom->append( poly );
}
}
else {
poly->appendInnerBoundary( ring );
}
}
if ( polygonCount > 1 ) {
placemark->setGeometry( multigeom );
}
else {
placemark->setGeometry( poly );
delete multigeom;
- multigeom = 0;
+ multigeom = nullptr;
}
mDebug() << "donut " << placemark->name() << " " << shape->nParts;
} else {
GeoDataPolygon *poly = new GeoDataPolygon;
GeoDataLinearRing ring;
for( int j=0; j<shape->nVertices; ++j ) {
ring.append( GeoDataCoordinates(
shape->padfX[j], shape->padfY[j],
0, GeoDataCoordinates::Degree ) );
}
poly->setOuterBoundary( ring );
placemark->setGeometry( poly );
mDebug() << "poly " << placemark->name() << " " << shape->nParts;
}
break;
}
}
}
SHPClose( handle );
DBFClose( dbfhandle );
if (!document->isEmpty()) {
document->setFileName( fileName );
return document;
} else {
delete document;
return nullptr;
}
}
}
#include "moc_ShpRunner.cpp"
diff --git a/src/plugins/runner/shp/ShpRunner.h b/src/plugins/runner/shp/ShpRunner.h
index 61ffa4ff4..d1d0b51d9 100644
--- a/src/plugins/runner/shp/ShpRunner.h
+++ b/src/plugins/runner/shp/ShpRunner.h
@@ -1,28 +1,28 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
#ifndef MARBLESHPRUNNER_H
#define MARBLESHPRUNNER_H
#include "ParsingRunner.h"
namespace Marble
{
class ShpRunner : public ParsingRunner
{
Q_OBJECT
public:
- explicit ShpRunner(QObject *parent = 0);
+ explicit ShpRunner(QObject *parent = nullptr);
~ShpRunner() override;
GeoDataDocument* parseFile( const QString &fileName, DocumentRole role, QString& error ) override;
};
}
#endif // MARBLESHPRUNNER_H
diff --git a/src/plugins/runner/yours/YoursPlugin.h b/src/plugins/runner/yours/YoursPlugin.h
index 84fd56944..4a223a039 100644
--- a/src/plugins/runner/yours/YoursPlugin.h
+++ b/src/plugins/runner/yours/YoursPlugin.h
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2016 Piotr Wójcik <chocimier@tlen.pl>
//
#ifndef MARBLE_YOURSPLUGIN_H
#define MARBLE_YOURSPLUGIN_H
#include "RoutingRunnerPlugin.h"
namespace Marble
{
class YoursPlugin : public RoutingRunnerPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.kde.marble.YoursPlugin")
Q_INTERFACES( Marble::RoutingRunnerPlugin )
public:
- explicit YoursPlugin( QObject *parent = 0 );
+ explicit YoursPlugin( QObject *parent = nullptr );
QString name() const override;
QString guiString() const override;
QString nameId() const override;
QString version() const override;
QString description() const override;
QString copyrightYears() const override;
QVector<PluginAuthor> pluginAuthors() const override;
RoutingRunner *newRunner() const override;
ConfigWidget* configWidget() override;
bool supportsTemplate(RoutingProfilesModel::ProfileTemplate profileTemplate) const override;
QHash< QString, QVariant > templateSettings(RoutingProfilesModel::ProfileTemplate profileTemplate) const override;
};
}
#endif
diff --git a/src/plugins/runner/yours/YoursRunner.cpp b/src/plugins/runner/yours/YoursRunner.cpp
index 12ab54978..a112fa4bf 100644
--- a/src/plugins/runner/yours/YoursRunner.cpp
+++ b/src/plugins/runner/yours/YoursRunner.cpp
@@ -1,176 +1,176 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2016 Piotr Wójcik <chocimier@tlen.pl>
//
#include "YoursRunner.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataParser.h"
#include "GeoDataFolder.h"
#include "GeoDataLineString.h"
#include "routing/RouteRequest.h"
#include <QString>
#include <QVector>
#include <QUrl>
#include <QNetworkReply>
#include <QBuffer>
#include <QTimer>
namespace Marble
{
YoursRunner::YoursRunner( QObject *parent ) :
RoutingRunner( parent ),
m_networkAccessManager()
{
connect( &m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(retrieveData(QNetworkReply*)) );
}
YoursRunner::~YoursRunner()
{
// nothing to do
}
void YoursRunner::retrieveRoute( const RouteRequest *route )
{
if ( route->size() != 2 ) {
return;
}
GeoDataCoordinates source = route->source();
GeoDataCoordinates destination = route->destination();
double fLon = source.longitude( GeoDataCoordinates::Degree );
double fLat = source.latitude( GeoDataCoordinates::Degree );
double tLon = destination.longitude( GeoDataCoordinates::Degree );
double tLat = destination.latitude( GeoDataCoordinates::Degree );
QString base = "http://www.yournavigation.org/api/1.0/gosmore.php";
//QString base = "http://nroets.dev.openstreetmap.org/demo/gosmore.php";
QString args = "?flat=%1&flon=%2&tlat=%3&tlon=%4";
args = args.arg( fLat, 0, 'f', 6 ).arg( fLon, 0, 'f', 6 ).arg( tLat, 0, 'f', 6 ).arg( tLon, 0, 'f', 6 );
QHash<QString, QVariant> settings = route->routingProfile().pluginSettings()[QStringLiteral("yours")];
QString transport = settings[QStringLiteral("transport")].toString();
QString fast;
if (settings[QStringLiteral("method")] == QLatin1String("shortest")) {
fast = "0";
} else {
fast = "1";
}
QString preferences = "&v=%1&fast=%2&layer=mapnik;";
preferences = preferences.arg(transport).arg(fast);
QString request = base + args + preferences;
// mDebug() << "GET: " << request;
m_request = QNetworkRequest( QUrl( request ) );
m_request.setRawHeader( "X-Yours-client", "Marble" );
QEventLoop eventLoop;
QTimer timer;
timer.setSingleShot( true );
timer.setInterval( 15000 );
connect( &timer, SIGNAL(timeout()),
&eventLoop, SLOT(quit()));
connect( this, SIGNAL(routeCalculated(GeoDataDocument*)),
&eventLoop, SLOT(quit()) );
// @todo FIXME Must currently be done in the main thread, see bug 257376
QTimer::singleShot( 0, this, SLOT(get()) );
timer.start();
eventLoop.exec();
}
void YoursRunner::get()
{
QNetworkReply *reply = m_networkAccessManager.get( m_request );
connect( reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)) );
}
void YoursRunner::retrieveData( QNetworkReply *reply )
{
if ( reply->isFinished() ) {
QByteArray data = reply->readAll();
reply->deleteLater();
//mDebug() << "Download completed: " << data;
GeoDataDocument* result = parse( data );
if ( result ) {
QString name = "%1 %2 (Yours)";
QString unit = QLatin1String( "m" );
qreal length = distance( result );
if ( length == 0.0 ) {
delete result;
- emit routeCalculated( 0 );
+ emit routeCalculated( nullptr );
return;
} else if ( length >= 1000 ) {
length /= 1000.0;
unit = "km";
}
result->setName( name.arg( length, 0, 'f', 1 ).arg( unit ) );
}
emit routeCalculated( result );
}
}
void YoursRunner::handleError( QNetworkReply::NetworkError error )
{
mDebug() << " Error when retrieving yournavigation.org route: " << error;
- emit routeCalculated( 0 );
+ emit routeCalculated( nullptr );
}
GeoDataDocument* YoursRunner::parse( const QByteArray &content )
{
GeoDataParser parser( GeoData_UNKNOWN );
// Open file in right mode
QBuffer buffer;
buffer.setData( content );
buffer.open( QIODevice::ReadOnly );
if ( !parser.read( &buffer ) ) {
mDebug() << "Cannot parse kml data! Input is " << content ;
- return 0;
+ return nullptr;
}
GeoDataDocument* document = static_cast<GeoDataDocument*>( parser.releaseDocument() );
return document;
}
qreal YoursRunner::distance( const GeoDataDocument* document )
{
QVector<GeoDataFolder*> folders = document->folderList();
for( const GeoDataFolder *folder: folders ) {
for( const GeoDataPlacemark *placemark: folder->placemarkList() ) {
const GeoDataGeometry* geometry = placemark->geometry();
if ( geometry->geometryId() == GeoDataLineStringId ) {
const GeoDataLineString* lineString = dynamic_cast<const GeoDataLineString*>( geometry );
Q_ASSERT( lineString && "Internal error: geometry ID does not match class type" );
return lineString->length( EARTH_RADIUS );
}
}
}
return 0.0;
}
} // namespace Marble
#include "moc_YoursRunner.cpp"
diff --git a/src/plugins/runner/yours/YoursRunner.h b/src/plugins/runner/yours/YoursRunner.h
index 31da7148a..e2d67a449 100644
--- a/src/plugins/runner/yours/YoursRunner.h
+++ b/src/plugins/runner/yours/YoursRunner.h
@@ -1,57 +1,57 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010 Dennis Nienhüser <nienhueser@kde.org>
// Copyright 2016 Piotr Wójcik <chocimier@tlen.pl>
//
#ifndef MARBLE_YOURSRUNNER_H
#define MARBLE_YOURSRUNNER_H
#include "RoutingRunner.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
namespace Marble
{
class YoursRunner : public RoutingRunner
{
Q_OBJECT
public:
- explicit YoursRunner( QObject *parent = 0 );
+ explicit YoursRunner( QObject *parent = nullptr );
~YoursRunner() override;
// Overriding MarbleAbstractRunner
void retrieveRoute( const RouteRequest *request ) override;
private Q_SLOTS:
/** Route data was retrieved via http */
void retrieveData( QNetworkReply *reply );
/** A network error occurred */
void handleError( QNetworkReply::NetworkError );
void get();
private:
static GeoDataDocument* parse( const QByteArray &input );
static qreal distance( const GeoDataDocument* document );
QNetworkAccessManager m_networkAccessManager;
QNetworkRequest m_request;
};
}
#endif
diff --git a/tests/AbstractDataPluginModelTest.cpp b/tests/AbstractDataPluginModelTest.cpp
index ab563fd31..8c7f81442 100644
--- a/tests/AbstractDataPluginModelTest.cpp
+++ b/tests/AbstractDataPluginModelTest.cpp
@@ -1,346 +1,346 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "TestUtils.h"
#include "AbstractDataPluginModel.h"
#include "AbstractDataPluginItem.h"
#include "MarbleModel.h"
#include "ViewportParams.h"
#include <QTimer>
#include <QSignalSpy>
using namespace Marble;
class TestDataPluginItem : public AbstractDataPluginItem
{
Q_OBJECT
public:
- TestDataPluginItem( QObject *parent = 0 ) :
+ TestDataPluginItem( QObject *parent = nullptr ) :
AbstractDataPluginItem( parent ),
m_initialized( false )
{}
void setInitialized( bool initialized ) { m_initialized = initialized; }
bool initialized() const override { return m_initialized; }
bool operator<( const AbstractDataPluginItem *other ) const override { return this < other; }
private:
bool m_initialized;
};
class TestDataPluginModel : public AbstractDataPluginModel
{
Q_OBJECT
public:
- TestDataPluginModel( const MarbleModel *marbleModel, QObject *parent = 0 ) :
+ TestDataPluginModel( const MarbleModel *marbleModel, QObject *parent = nullptr ) :
AbstractDataPluginModel( "test", marbleModel, parent )
{}
protected:
void getAdditionalItems(const GeoDataLatLonAltBox &box, qint32 number) override
{
Q_UNUSED( box )
Q_UNUSED( number )
}
};
class AbstractDataPluginModelTest : public QObject
{
Q_OBJECT
public:
- AbstractDataPluginModelTest( QObject *parent = 0 ) :
+ AbstractDataPluginModelTest( QObject *parent = nullptr ) :
QObject( parent )
{}
private Q_SLOTS:
void init_testcase();
void defaultConstructor();
void destructor();
void addItemToList_data();
void addItemToList();
void addItemToList_keepExisting_data();
void addItemToList_keepExisting();
void switchMapTheme_data();
void switchMapTheme();
void setFavoriteItemsOnly_data();
void setFavoriteItemsOnly();
void itemsVersusInitialized_data();
void itemsVersusInitialized();
void itemsVersusAddedAngularResolution();
void itemsVersusSetSticky();
private:
const MarbleModel m_marbleModel;
static const ViewportParams fullViewport;
};
const ViewportParams AbstractDataPluginModelTest::fullViewport( Equirectangular, 0, 0, 100, QSize( 230, 230 ) );
void AbstractDataPluginModelTest::init_testcase()
{
QCOMPARE( GeoDataLatLonBox( fullViewport.viewLatLonAltBox() ), GeoDataLatLonBox( 90, -90, 180, -180, GeoDataCoordinates::Degree ) );
}
void AbstractDataPluginModelTest::defaultConstructor()
{
const TestDataPluginModel model( &m_marbleModel );
QCOMPARE( model.isFavoriteItemsOnly(), false );
}
void AbstractDataPluginModelTest::destructor()
{
QPointer<AbstractDataPluginItem> item( new TestDataPluginItem );
item->setId( "foo" );
QEventLoop loop;
connect( item, SIGNAL(destroyed()), &loop, SLOT(quit()) );
{
TestDataPluginModel model( &m_marbleModel );
model.addItemToList( item );
QVERIFY( model.itemExists( "foo" ) );
}
QTimer::singleShot( 5000, &loop, SLOT(quit()) ); // watchdog timer
loop.exec();
QVERIFY( item.isNull() );
}
void AbstractDataPluginModelTest::addItemToList_data()
{
QTest::addColumn<bool>( "initialized" );
const bool isInitialized = true;
addRow() << isInitialized;
addRow() << !isInitialized;
}
void AbstractDataPluginModelTest::addItemToList()
{
QFETCH( bool, initialized );
TestDataPluginModel model( &m_marbleModel );
QVERIFY( model.isFavoriteItemsOnly() == false );
QVERIFY( !model.itemExists( "foo" ) );
- QVERIFY( model.findItem( "foo" ) == 0 );
+ QVERIFY( model.findItem( "foo" ) == nullptr );
TestDataPluginItem *item = new TestDataPluginItem();
item->setInitialized( initialized );
item->setId( "foo" );
QSignalSpy itemsUpdatedSpy( &model, SIGNAL(itemsUpdated()) );
model.addItemToList( item );
QVERIFY( model.itemExists( "foo" ) );
QCOMPARE( model.findItem( "foo" ), item );
QCOMPARE( itemsUpdatedSpy.count() == 1, initialized );
QCOMPARE( static_cast<bool>( model.items( &fullViewport, 1 ).contains( item ) ), initialized );
}
void AbstractDataPluginModelTest::addItemToList_keepExisting_data()
{
QTest::addColumn<bool>( "itemInitialized" );
QTest::addColumn<bool>( "rejectedInitialized" );
const bool isInitialized = true;
addRow() << isInitialized << isInitialized;
addRow() << isInitialized << !isInitialized;
addRow() << !isInitialized << isInitialized;
addRow() << !isInitialized << !isInitialized;
}
void AbstractDataPluginModelTest::addItemToList_keepExisting()
{
QFETCH( bool, itemInitialized );
QFETCH( bool, rejectedInitialized );
TestDataPluginModel model( &m_marbleModel );
QPointer<TestDataPluginItem> item( new TestDataPluginItem() );
item->setId( "foo" );
item->setInitialized( itemInitialized );
model.addItemToList( item );
QPointer<TestDataPluginItem> rejectedItem( new TestDataPluginItem() );
rejectedItem->setId( "foo" );
rejectedItem->setInitialized( rejectedInitialized );
QEventLoop loop;
connect( rejectedItem.data(), SIGNAL(destroyed()), &loop, SLOT(quit()) );
QSignalSpy itemsUpdatedSpy( &model, SIGNAL(itemsUpdated()) );
model.addItemToList( rejectedItem );
QTimer::singleShot( 5000, &loop, SLOT(quit()) ); // watchdog timer
loop.exec();
QVERIFY( !item.isNull() );
QVERIFY( rejectedItem.isNull() );
QCOMPARE( model.findItem( item->id() ), item.data() );
QCOMPARE( itemsUpdatedSpy.count(), 0 );
}
void AbstractDataPluginModelTest::switchMapTheme_data()
{
QTest::addColumn<QString>( "mapThemeId" );
QTest::addColumn<bool>( "planetChanged" );
addRow() << "earth/bluemarble/bluemarble.dgml" << false;
addRow() << "moon/clementine/clementine.dgml" << true;
}
void AbstractDataPluginModelTest::switchMapTheme()
{
QFETCH( QString, mapThemeId );
QFETCH( bool, planetChanged );
MarbleModel marbleModel;
marbleModel.setMapThemeId( "earth/openstreetmap/openstreetmap.dgml" );
QCOMPARE( marbleModel.mapThemeId(), QString( "earth/openstreetmap/openstreetmap.dgml" ) );
TestDataPluginModel model( &marbleModel );
TestDataPluginItem *const item = new TestDataPluginItem();
item->setId( "foo" );
model.addItemToList( item );
QCOMPARE( model.findItem( "foo" ), item );
marbleModel.setMapThemeId( mapThemeId );
QCOMPARE( marbleModel.mapThemeId(), mapThemeId );
if ( planetChanged ) {
- QCOMPARE( model.findItem( "foo" ), static_cast<AbstractDataPluginItem *>( 0 ) );
+ QCOMPARE( model.findItem( "foo" ), static_cast<AbstractDataPluginItem *>( nullptr ) );
}
else {
QCOMPARE( model.findItem( "foo" ), item );
}
}
void AbstractDataPluginModelTest::setFavoriteItemsOnly_data()
{
QTest::addColumn<bool>( "itemIsFavorite" );
QTest::addColumn<bool>( "favoriteItemsOnly" );
addRow() << true << true;
addRow() << true << false;
addRow() << false << true;
addRow() << false << false;
}
void AbstractDataPluginModelTest::setFavoriteItemsOnly()
{
QFETCH( bool, itemIsFavorite );
QFETCH( bool, favoriteItemsOnly );
TestDataPluginItem *item = new TestDataPluginItem;
item->setId( "foo" );
item->setInitialized( true );
item->setFavorite( itemIsFavorite );
TestDataPluginModel model( &m_marbleModel );
model.setFavoriteItemsOnly( favoriteItemsOnly );
model.addItemToList( item );
QVERIFY( model.findItem( item->id() ) == item );
const bool visible = !favoriteItemsOnly || itemIsFavorite;
QCOMPARE( static_cast<bool>( model.items( &fullViewport, 1 ).contains( item ) ), visible );
}
void AbstractDataPluginModelTest::itemsVersusInitialized_data()
{
QTest::addColumn<bool>( "initialized" );
addRow() << true;
addRow() << false;
}
void AbstractDataPluginModelTest::itemsVersusInitialized()
{
QFETCH( bool, initialized );
TestDataPluginItem *item = new TestDataPluginItem;
item->setInitialized( initialized );
TestDataPluginModel model( &m_marbleModel );
model.addItemToList( item );
QCOMPARE( static_cast<bool>( model.items( &fullViewport, 1 ).contains( item ) ), initialized );
}
void AbstractDataPluginModelTest::itemsVersusAddedAngularResolution()
{
const ViewportParams zoomedViewport( Equirectangular, 0, 0, 10000, QSize( 230, 230 ) );
TestDataPluginItem *item = new TestDataPluginItem;
item->setInitialized( true );
TestDataPluginModel model( &m_marbleModel );
model.addItemToList( item );
QVERIFY( model.items( &zoomedViewport, 1 ).contains( item ) ); // calls setAddedAngularResolution()
QVERIFY( !model.items( &fullViewport, 1 ).contains( item ) ); // addedAngularResolution() is too low
}
void AbstractDataPluginModelTest::itemsVersusSetSticky()
{
const ViewportParams zoomedViewport( Equirectangular, 0, 0, 10000, QSize( 230, 230 ) );
TestDataPluginItem *item = new TestDataPluginItem;
item->setInitialized( true );
item->setSticky( false );
TestDataPluginModel model( &m_marbleModel );
model.addItemToList( item );
QVERIFY( model.items( &zoomedViewport, 1 ).contains( item ) );
QVERIFY( !model.items( &fullViewport, 1 ).contains( item ) );
item->setSticky( true );
QVERIFY( model.items( &zoomedViewport, 1 ).contains( item ) );
QVERIFY( model.items( &fullViewport, 1 ).contains( item ) );
item->setSticky( false );
QVERIFY( model.items( &zoomedViewport, 1 ).contains( item ) );
QVERIFY( !model.items( &fullViewport, 1 ).contains( item ) );
}
QTEST_MAIN( AbstractDataPluginModelTest )
#include "AbstractDataPluginModelTest.moc"
diff --git a/tests/AbstractDataPluginTest.cpp b/tests/AbstractDataPluginTest.cpp
index f1c90e3be..904d9f5ac 100644
--- a/tests/AbstractDataPluginTest.cpp
+++ b/tests/AbstractDataPluginTest.cpp
@@ -1,68 +1,68 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "MarbleModel.h"
#include "PluginManager.h"
#include "AbstractDataPlugin.h"
#include <QMetaType>
#include <QTest>
Q_DECLARE_METATYPE( const Marble::AbstractDataPlugin * )
namespace Marble
{
class AbstractDataPluginTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initialize_data();
void initialize();
private:
MarbleModel m_model;
};
void AbstractDataPluginTest::initialize_data()
{
QTest::addColumn<const AbstractDataPlugin *>( "factory" );
foreach ( const RenderPlugin *plugin, m_model.pluginManager()->renderPlugins() ) {
const AbstractDataPlugin *const dataPlugin = qobject_cast<const AbstractDataPlugin *>( plugin );
if ( !dataPlugin )
continue;
QTest::newRow(plugin->nameId().toLatin1().constData()) << dataPlugin;
}
}
void AbstractDataPluginTest::initialize()
{
QFETCH( const AbstractDataPlugin *, factory );
RenderPlugin *const instance = factory->newInstance( &m_model );
AbstractDataPlugin *const dataInstance = qobject_cast<AbstractDataPlugin *>( instance );
- QVERIFY( dataInstance != 0 );
- QVERIFY( dataInstance->model() == 0 );
+ QVERIFY( dataInstance != nullptr );
+ QVERIFY( dataInstance->model() == nullptr );
dataInstance->initialize();
- QVERIFY( dataInstance->model() != 0 );
+ QVERIFY( dataInstance->model() != nullptr );
}
}
QTEST_MAIN( Marble::AbstractDataPluginTest )
#include "AbstractDataPluginTest.moc"
diff --git a/tests/AbstractFloatItemTest.cpp b/tests/AbstractFloatItemTest.cpp
index 692686909..9bce06f4c 100644
--- a/tests/AbstractFloatItemTest.cpp
+++ b/tests/AbstractFloatItemTest.cpp
@@ -1,196 +1,196 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "MarbleModel.h"
#include "PluginManager.h"
#include "AbstractFloatItem.h"
#include <QMetaType>
#include <QTest>
Q_DECLARE_METATYPE( const Marble::AbstractFloatItem * )
using namespace Marble;
class NullFloatItem : public AbstractFloatItem
{
public:
NullFloatItem() :
- AbstractFloatItem( 0 )
+ AbstractFloatItem( nullptr )
{}
NullFloatItem( const MarbleModel *model ) :
AbstractFloatItem( model )
{}
QString name() const override { return QStringLiteral("Null Float Item"); }
QString nameId() const override { return QStringLiteral("null"); }
QString version() const override { return QStringLiteral("0.0"); }
QString description() const override { return QStringLiteral("A null float item just for testing."); }
QIcon icon() const override { return QIcon(); }
QString copyrightYears() const override { return QStringLiteral("2013"); }
QVector<PluginAuthor> pluginAuthors() const override
{
return QVector<PluginAuthor>() << PluginAuthor(QStringLiteral("Bernhard Beschow"), QStringLiteral("bbeschow@cs.tu-berlin.de"));
}
void initialize() override {}
bool isInitialized() const override { return true; }
QStringList backendTypes() const override { return QStringList(QStringLiteral("null")); }
QString guiString() const override { return QStringLiteral("Null"); }
- RenderPlugin *newInstance( const MarbleModel * ) const override { return 0; }
+ RenderPlugin *newInstance( const MarbleModel * ) const override { return nullptr; }
};
class AbstractFloatItemTest : public QObject
{
Q_OBJECT
public:
AbstractFloatItemTest();
private Q_SLOTS:
void defaultConstructor();
void newInstance_data();
void newInstance();
void setSettings_data();
void setSettings();
void setPosition_data();
void setPosition();
private:
MarbleModel m_model;
QList<const AbstractFloatItem *> m_factories;
};
AbstractFloatItemTest::AbstractFloatItemTest()
{
foreach ( const RenderPlugin *plugin, m_model.pluginManager()->renderPlugins() ) {
const AbstractFloatItem *const factory = qobject_cast<const AbstractFloatItem *>( plugin );
if ( !factory )
continue;
m_factories << factory;
}
}
void AbstractFloatItemTest::defaultConstructor()
{
const NullFloatItem item;
QCOMPARE( item.renderPolicy(), QString( "ALWAYS") );
QCOMPARE( item.renderPosition(), QStringList( "FLOAT_ITEM" ) );
QCOMPARE( item.cacheMode(), AbstractFloatItem::ItemCoordinateCache );
QCOMPARE( item.frame(), AbstractFloatItem::RectFrame );
QCOMPARE( item.padding(), 4. );
QCOMPARE( item.contentSize(), QSizeF( 150, 50 ) );
QCOMPARE( item.position(), QPointF( 10, 10 ) );
QCOMPARE( item.visible(), true );
QCOMPARE( item.positionLocked(), true );
QVERIFY( item.settings().contains( "position" ) );
}
void AbstractFloatItemTest::newInstance_data()
{
QTest::addColumn<const AbstractFloatItem *>( "factory" );
foreach ( const AbstractFloatItem *factory, m_factories ) {
QTest::newRow(factory->nameId().toLatin1().constData())
<< factory;
}
}
void AbstractFloatItemTest::newInstance()
{
QFETCH( const AbstractFloatItem *, factory );
RenderPlugin *const instance = factory->newInstance( &m_model );
QVERIFY( qobject_cast<AbstractFloatItem *>( instance ) != 0 );
QVERIFY( instance->settings().contains( "position" ) );
delete instance;
}
void AbstractFloatItemTest::setSettings_data()
{
QTest::addColumn<const AbstractFloatItem *>( "factory" );
foreach ( const AbstractFloatItem *factory, m_factories ) {
QTest::newRow(factory->nameId().toLatin1().constData())
<< factory;
}
}
void AbstractFloatItemTest::setSettings()
{
QFETCH( const AbstractFloatItem *, factory );
AbstractFloatItem *const instance = qobject_cast<AbstractFloatItem *>( factory->newInstance( &m_model ) );
- QVERIFY( instance != 0 );
+ QVERIFY( instance != nullptr );
const QPointF position( 1.318, 4.005 );
instance->restoreDefaultSettings();
QVERIFY( instance->settings().value( "position", position ).toPointF() != position );
QVERIFY( instance->position() != position );
QHash<QString, QVariant> settings;
settings.insert( "position", position );
instance->setSettings( settings );
QCOMPARE( instance->settings().value( "position", QPointF( 0, 0 ) ).toPointF(), position );
QCOMPARE( instance->position(), position );
delete instance;
}
void AbstractFloatItemTest::setPosition_data()
{
QTest::addColumn<const AbstractFloatItem *>( "factory" );
foreach ( const AbstractFloatItem *factory, m_factories ) {
QTest::newRow(factory->nameId().toLatin1().constData())
<< factory;
}
}
void AbstractFloatItemTest::setPosition()
{
QFETCH( const AbstractFloatItem *, factory );
AbstractFloatItem *const instance = qobject_cast<AbstractFloatItem *>( factory->newInstance( &m_model ) );
- QVERIFY( instance != 0 );
+ QVERIFY( instance != nullptr );
const QPointF position( 1.318, 4.005 );
QVERIFY( instance->position() != position );
QVERIFY( instance->settings().value( "position", position ).toPointF() != position );
QHash<QString, QVariant> settings;
settings.insert( "position", QPointF( 0, 0 ) );
instance->setSettings( settings );
instance->setPosition( position ); // position of settings should be overwritten
QCOMPARE( instance->position(), position );
QCOMPARE( instance->settings().value( "position", QPointF( 1, 0 ) ).toPointF(), position );
delete instance;
}
QTEST_MAIN( AbstractFloatItemTest )
#include "AbstractFloatItemTest.moc"
diff --git a/tests/BillboardGraphicsItemTest.cpp b/tests/BillboardGraphicsItemTest.cpp
index cec8ac905..3c2b35bc3 100644
--- a/tests/BillboardGraphicsItemTest.cpp
+++ b/tests/BillboardGraphicsItemTest.cpp
@@ -1,84 +1,84 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "BillboardGraphicsItem.h"
#include "FrameGraphicsItem.h"
#include "MarbleGraphicsGridLayout.h"
#include "ViewportParams.h"
#include <QImage>
#include <QPainter>
#include <QTest>
namespace Marble
{
class BillboardGraphicsItemTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void defaultConstructorValues();
void paintEvent();
};
void BillboardGraphicsItemTest::defaultConstructorValues()
{
const BillboardGraphicsItem item;
// MarbleGraphicsItem
- QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( 0 ) );
+ QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( nullptr ) );
QCOMPARE( item.cacheMode(), BillboardGraphicsItem::NoCache );
QCOMPARE( item.visible(), true );
QCOMPARE( item.size(), QSizeF() );
QCOMPARE( item.contentSize(), QSizeF() );
// BillboardGraphicsItem
QCOMPARE( item.coordinate(), GeoDataCoordinates() );
QCOMPARE( item.alignment(), Qt::AlignHCenter | Qt::AlignVCenter );
QCOMPARE( item.positions(), QVector<QPointF>() );
QCOMPARE( item.boundingRects(), QVector<QRectF>() );
}
void BillboardGraphicsItemTest::paintEvent()
{
BillboardGraphicsItem item;
item.setCoordinate( GeoDataCoordinates( 0, 0 ) );
MarbleGraphicsGridLayout *topLayout = new MarbleGraphicsGridLayout( 1, 1 );
item.setLayout( topLayout );
FrameGraphicsItem frameItem( &item );
frameItem.setSize( QSizeF( 11.2, 11.3 ) );
topLayout->addItem( &frameItem, 0, 0 );
QCOMPARE( item.positions(), QVector<QPointF>() );
QCOMPARE( item.size(), QSizeF() );
QImage paintDevice( 100, 100, QImage::Format_ARGB32_Premultiplied );
QPainter painter( &paintDevice );
const ViewportParams viewport( Mercator, 0, 0, 20, paintDevice.size() );
item.paintEvent( &painter, &viewport );
QCOMPARE( item.size(), frameItem.size() );
QCOMPARE( item.positions().size(), 1 );
QCOMPARE( item.positions()[0], QPointF( 44, 44 ) );
}
}
QTEST_MAIN( Marble::BillboardGraphicsItemTest )
#include "BillboardGraphicsItemTest.moc"
diff --git a/tests/BookmarkManagerTest.cpp b/tests/BookmarkManagerTest.cpp
index 9a614da5e..8e656cc7e 100644
--- a/tests/BookmarkManagerTest.cpp
+++ b/tests/BookmarkManagerTest.cpp
@@ -1,91 +1,91 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include <QSignalSpy>
#include "BookmarkManager.h"
#include "GeoDataFolder.h"
#include "GeoDataTreeModel.h"
#include "TestUtils.h"
namespace Marble
{
class BookmarkManagerTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void construct();
void loadFile_data();
void loadFile();
};
void BookmarkManagerTest::construct()
{
GeoDataTreeModel model;
QCOMPARE( model.rowCount(), 0 );
{
const BookmarkManager manager( &model );
QCOMPARE( model.rowCount(), 1 );
- QVERIFY( manager.document() != 0 );
+ QVERIFY( manager.document() != nullptr );
QCOMPARE( manager.folders().count(), 1 );
QCOMPARE( manager.folders().first()->size(), 0 );
QCOMPARE( manager.showBookmarks(), true );
// FIXME this method returns random results (depending on the username and the existence of the bookmarks file)
// QCOMPARE( manager.bookmarkFile(), QString() );
QCOMPARE( model.rowCount(), 1 );
}
QCOMPARE( model.rowCount(), 0 );
}
void BookmarkManagerTest::loadFile_data()
{
QTest::addColumn<QString>( "relativePath" );
QTest::addColumn<bool>( "expected" );
addRow() << QString() << false;
addRow() << QString( "lsdkrfuweqofn.kml" ) << false; // non-existing file
// FIXME This will create an empty KML file called "LICENSE.txt" under MarbleDirs::localPath().
// addRow() << QString( "LICENSE.txt" ) << true; // file exists in MarbleDirs::systemPath()
}
void BookmarkManagerTest::loadFile()
{
QFETCH( QString, relativePath );
QFETCH( bool, expected );
GeoDataTreeModel model;
BookmarkManager manager( &model );
QVERIFY( model.rowCount() == 1 );
const bool fileLoaded = manager.loadFile( relativePath );
QCOMPARE( fileLoaded, expected );
- QVERIFY( manager.document() != 0 );
+ QVERIFY( manager.document() != nullptr );
QCOMPARE( model.rowCount(), 1 );
}
}
QTEST_MAIN( Marble::BookmarkManagerTest )
#include "BookmarkManagerTest.moc"
diff --git a/tests/GeoDataTreeModelTest.cpp b/tests/GeoDataTreeModelTest.cpp
index a7427b0b1..9c7fce8c9 100644
--- a/tests/GeoDataTreeModelTest.cpp
+++ b/tests/GeoDataTreeModelTest.cpp
@@ -1,80 +1,80 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include <QTest>
#include "GeoDataTreeModel.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
namespace Marble
{
class GeoDataTreeModelTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void defaultConstructor();
void setRootDocument();
void addDocument();
};
void GeoDataTreeModelTest::defaultConstructor()
{
const GeoDataTreeModel model;
QCOMPARE( model.rowCount(), 0 );
QCOMPARE( model.columnCount(), 4 );
QCOMPARE( model.headerData( 0, Qt::Horizontal, Qt::DisplayRole ), QVariant( tr( "Name" ) ) );
QCOMPARE( model.headerData( 1, Qt::Horizontal, Qt::DisplayRole ), QVariant( tr( "Type" ) ) );
QCOMPARE( model.headerData( 2, Qt::Horizontal, Qt::DisplayRole ), QVariant( tr( "Popularity" ) ) );
QCOMPARE( model.headerData( 3, Qt::Horizontal, Qt::DisplayRole ), QVariant( tr( "PopIndex", "Popularity index" ) ) );
QCOMPARE( model.index( 0, 0 ), QModelIndex() );
- QCOMPARE( model.index( 0 ), QModelIndex() );
+ QCOMPARE( model.index( nullptr ), QModelIndex() );
QCOMPARE( model.parent( QModelIndex() ), QModelIndex() );
QCOMPARE( model.data( QModelIndex(), Qt::DisplayRole ), QVariant() );
QCOMPARE( model.flags( QModelIndex() ), Qt::NoItemFlags );
- QVERIFY( const_cast<GeoDataTreeModel *>( &model )->rootDocument() != 0 );
+ QVERIFY( const_cast<GeoDataTreeModel *>( &model )->rootDocument() != nullptr );
}
void GeoDataTreeModelTest::setRootDocument()
{
GeoDataDocument document;
{
GeoDataTreeModel model;
model.setRootDocument( &document );
// ~GeoDataTreeModel() shouldn't delete document
}
}
void GeoDataTreeModelTest::addDocument()
{
{
GeoDataDocument *document = new GeoDataDocument;
GeoDataTreeModel model;
model.addDocument( document );
QCOMPARE( model.rowCount(), 1 );
}
}
}
QTEST_MAIN( Marble::GeoDataTreeModelTest )
#include "GeoDataTreeModelTest.moc"
diff --git a/tests/MarbleRunnerManagerTest.cpp b/tests/MarbleRunnerManagerTest.cpp
index 063d5e065..390b51b44 100644
--- a/tests/MarbleRunnerManagerTest.cpp
+++ b/tests/MarbleRunnerManagerTest.cpp
@@ -1,375 +1,375 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Thibaut Gridel <tgridel@free.fr>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "MarbleDebug.h"
#include "MarbleDirs.h"
#include "MarbleModel.h"
#include "ParsingRunnerManager.h"
#include "PluginManager.h"
#include "ReverseGeocodingRunnerManager.h"
#include "RoutingRunnerManager.h"
#include "SearchRunnerManager.h"
#include "GeoDataPlacemark.h"
#include "routing/RouteRequest.h"
#include "TestUtils.h"
#include <QSignalSpy>
#include <QMetaType>
#include <QThreadPool>
Q_DECLARE_METATYPE( QList<Marble::GeoDataCoordinates> )
namespace Marble
{
class MarbleRunnerManagerTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init(){ qDebug() << "start: " << t.elapsed();}// will be called before each testfunction is executed.
void cleanup(){ qDebug() << "end: " << t.elapsed();}// will be called after every testfunction.
void testSyncPlacemarks();
void testAsyncPlacemarks_data();
void testAsyncPlacemarks();
void testSyncReverse();
void testAsyncReverse_data();
void testAsyncReverse();
void testSyncRouting();
void testAsyncRouting_data();
void testAsyncRouting();
void testSyncParsing_data();
void testSyncParsing();
void testAsyncParsing_data();
void testAsyncParsing();
public:
PluginManager m_pluginManager;
int m_time;
QString m_name;
GeoDataCoordinates m_coords;
GeoDataCoordinates m_coords2;
RouteRequest m_request;
QTime t;
};
void MarbleRunnerManagerTest::initTestCase()
{
MarbleDebug::setEnabled( true );
MarbleDirs::setMarbleDataPath( DATA_PATH );
MarbleDirs::setMarblePluginPath( PLUGIN_PATH );
m_time = 30000;
m_name = "Berlin";
qRegisterMetaType<QVector<GeoDataCoordinates> >( "QVector<GeoDataCoordinates>" );
m_coords.setLatitude(52.50160, GeoDataCoordinates::Degree );
m_coords.setLongitude(13.40233, GeoDataCoordinates::Degree );
m_coords2.setLatitude(52.52665, GeoDataCoordinates::Degree );
m_coords2.setLongitude(13.39032, GeoDataCoordinates::Degree );
m_request.append( m_coords );
m_request.append( m_coords2 );
t.start();
}
void MarbleRunnerManagerTest::cleanupTestCase()
{
}
void MarbleRunnerManagerTest::testSyncPlacemarks()
{
MarbleModel model;
SearchRunnerManager m_runnerManager(&model, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(placemarkSearchFinished()) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(searchResultChanged(QVector<GeoDataPlacemark*>)) );
QCOMPARE( finishSpy.count(), 0 );
QCOMPARE( resultSpy.count(), 0 );
QTime timer;
timer.start();
QVector<GeoDataPlacemark*> placemarks = m_runnerManager.searchPlacemarks(m_name);
QVERIFY( timer.elapsed() < m_time );
QCOMPARE( resultSpy.count(), 1 );
QVERIFY( placemarks.size() > 0 );
QCOMPARE( finishSpy.count(), 1 );
// second search is optimised
placemarks.clear();
finishSpy.clear();
resultSpy.clear();
timer.start();
placemarks = m_runnerManager.searchPlacemarks(m_name);
QVERIFY( timer.elapsed() < m_time );
QCOMPARE( resultSpy.count(), 1 );
QVERIFY( placemarks.size() > 0 );
QCOMPARE( finishSpy.count(), 1 );
}
void MarbleRunnerManagerTest::testAsyncPlacemarks_data()
{
QTest::addColumn<QString>( "name" );
addRow() << QString( "Berlin" );
addRow() << QString( "www.heise.de" );
}
void MarbleRunnerManagerTest::testAsyncPlacemarks()
{
MarbleModel model;
SearchRunnerManager m_runnerManager(&model, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(searchFinished(QString)) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(searchResultChanged(QVector<GeoDataPlacemark*>)) );
QEventLoop loop;
connect( &m_runnerManager, SIGNAL(searchFinished(QString)),
&loop, SLOT(quit()), Qt::QueuedConnection );
QFETCH( QString, name );
m_runnerManager.findPlacemarks( name );
loop.exec();
QCOMPARE( resultSpy.count(), 1 );
QCOMPARE( finishSpy.count(), 1 );
QThreadPool::globalInstance()->waitForDone();
}
void MarbleRunnerManagerTest::testSyncReverse()
{
MarbleModel model;
ReverseGeocodingRunnerManager m_runnerManager(&model, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(reverseGeocodingFinished()) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)) );
QCOMPARE( finishSpy.count(), 0 );
QCOMPARE( resultSpy.count(), 0 );
QTime timer;
timer.start();
QString placemark = m_runnerManager.searchReverseGeocoding( m_coords );
QVERIFY( timer.elapsed() < m_time );
QCOMPARE( resultSpy.count(), 1 );
QVERIFY( !placemark.isEmpty() );
QCOMPARE( finishSpy.count(), 1 );
// second search is optimised
finishSpy.clear();
resultSpy.clear();
timer.start();
placemark = m_runnerManager.searchReverseGeocoding( m_coords );
QVERIFY( timer.elapsed() < m_time );
QCOMPARE( resultSpy.count(), 1 );
QVERIFY( !placemark.isEmpty() );
QCOMPARE( finishSpy.count(), 1 );
}
void MarbleRunnerManagerTest::testAsyncReverse_data()
{
QTest::addColumn<GeoDataCoordinates>( "coordinates" );
addRow() << m_coords;
}
void MarbleRunnerManagerTest::testAsyncReverse()
{
MarbleModel model;
ReverseGeocodingRunnerManager m_runnerManager(&model, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(reverseGeocodingFinished()) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)) );
QEventLoop loop;
connect( &m_runnerManager, SIGNAL(reverseGeocodingFinished()),
&loop, SLOT(quit()), Qt::QueuedConnection );
QFETCH( GeoDataCoordinates, coordinates );
m_runnerManager.reverseGeocoding( coordinates );
loop.exec();
QCOMPARE( resultSpy.count(), 1 );
QCOMPARE( finishSpy.count(), 1 );
QThreadPool::globalInstance()->waitForDone();
}
void MarbleRunnerManagerTest::testSyncRouting()
{
MarbleModel model;
RoutingRunnerManager m_runnerManager(&model, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(routingFinished()) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(routeRetrieved(GeoDataDocument*)) );
QCOMPARE( finishSpy.count(), 0 );
QCOMPARE( resultSpy.count(), 0 );
QTime timer;
timer.start();
QVector<GeoDataDocument*> routes = m_runnerManager.searchRoute( &m_request );
QVERIFY( timer.elapsed() < m_time );
QVERIFY( resultSpy.count() > 0 );
QVERIFY( !routes.isEmpty() );
QCOMPARE( finishSpy.count(), 1 );
}
void MarbleRunnerManagerTest::testAsyncRouting_data()
{
QTest::addColumn<QVector<GeoDataCoordinates> >( "coordinatesList" );
addRow() << ( QVector<GeoDataCoordinates>() << m_coords << m_coords2 );
}
void MarbleRunnerManagerTest::testAsyncRouting()
{
MarbleModel model;
RoutingRunnerManager m_runnerManager(&model, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(routingFinished()) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(routeRetrieved(GeoDataDocument*)) );
QEventLoop loop;
connect( &m_runnerManager, SIGNAL(routingFinished()),
&loop, SLOT(quit()), Qt::QueuedConnection );
QFETCH( QVector<GeoDataCoordinates>, coordinatesList );
RouteRequest request;
foreach( const GeoDataCoordinates &coordinates, coordinatesList ) {
request.append( coordinates );
}
m_runnerManager.retrieveRoute( &request );
loop.exec();
QVERIFY( resultSpy.count() > 0 );
QCOMPARE( finishSpy.count(), 1 );
QThreadPool::globalInstance()->waitForDone();
}
void MarbleRunnerManagerTest::testSyncParsing_data()
{
QTest::addColumn<QString>( "fileName" );
QTest::addColumn<int>( "resultCount" );
addRow() << MarbleDirs::path( "mwdbii/DATELINE.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PCOAST.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PLAKEISLAND.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PDIFFBORDER.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PISLAND.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PLAKE.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PUSA48.DIFF.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/RIVER.PNT" ) << 1;
addNamedRow("cache") << QString( MARBLE_SRC_DIR ).append( "/data/placemarks/otherplacemarks.cache" ) << 1;
addNamedRow("gpx") << QString( MARBLE_SRC_DIR ).append( "/examples/gpx/mjolby.gpx") << 1;
//json
addNamedRow("kml") << QString( MARBLE_SRC_DIR ).append( "/examples/kml/NewYork.kml") << 1;
//log
addNamedRow("osm") << QString( MARBLE_SRC_DIR ).append( "/examples/osm/map.osm") << 1;
addNamedRow("pn2") << QString( MARBLE_SRC_DIR ).append( "/data/naturalearth/ne_50m_lakes.pn2") << 1;
addNamedRow("pnt") << QString( MARBLE_SRC_DIR ).append( "/data/mwdbii/PGLACIER.PNT" ) << 1;
//shp
addNamedRow("svg") << MarbleDirs::path( "flags/flag_tv.svg" ) << 0;
}
void MarbleRunnerManagerTest::testSyncParsing()
{
ParsingRunnerManager m_runnerManager(&m_pluginManager, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(parsingFinished()) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(parsingFinished(GeoDataDocument*,QString)) );
QFETCH( QString, fileName );
QFETCH( int, resultCount );
GeoDataDocument* file = m_runnerManager.openFile( fileName );
QCOMPARE( resultSpy.count(), resultCount );
- QCOMPARE( file != 0, resultCount > 0 );
+ QCOMPARE( file != nullptr, resultCount > 0 );
QCOMPARE( finishSpy.count(), 1 );
}
void MarbleRunnerManagerTest::testAsyncParsing_data()
{
QTest::addColumn<QString>( "fileName" );
QTest::addColumn<int>( "resultCount" );
addRow() << MarbleDirs::path( "placemarks/otherplacemarks.cache" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/DATELINE.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PCOAST.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PGLACIER.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PLAKEISLAND.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PDIFFBORDER.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PISLAND.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PLAKE.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/PUSA48.DIFF.PNT" ) << 1;
addRow() << MarbleDirs::path( "mwdbii/RIVER.PNT" ) << 1;
addRow() << MarbleDirs::path( "flags/flag_tv.svg" ) << 0;
}
void MarbleRunnerManagerTest::testAsyncParsing()
{
ParsingRunnerManager m_runnerManager(&m_pluginManager, this);
QSignalSpy finishSpy( &m_runnerManager, SIGNAL(parsingFinished()) );
QSignalSpy resultSpy( &m_runnerManager, SIGNAL(parsingFinished(GeoDataDocument*,QString)) );
QEventLoop loop;
connect( &m_runnerManager, SIGNAL(parsingFinished()),
&loop, SLOT(quit()), Qt::QueuedConnection );
QFETCH( QString, fileName );
QFETCH( int, resultCount );
m_runnerManager.parseFile( fileName );
loop.exec();
QCOMPARE( resultSpy.count(), resultCount );
QCOMPARE( finishSpy.count(), 1 );
QThreadPool::globalInstance()->waitForDone();
}
}
QTEST_MAIN( Marble::MarbleRunnerManagerTest )
#include "MarbleRunnerManagerTest.moc"
diff --git a/tests/PlacemarkPositionProviderPluginTest.cpp b/tests/PlacemarkPositionProviderPluginTest.cpp
index 229f23504..1f3102863 100644
--- a/tests/PlacemarkPositionProviderPluginTest.cpp
+++ b/tests/PlacemarkPositionProviderPluginTest.cpp
@@ -1,205 +1,205 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "GeoDataTrack.h"
#include "GeoDataPlacemark.h"
#include "GeoDataAccuracy.h"
#include "PositionProviderPlugin.h"
#include "PluginManager.h"
#include "MarbleModel.h"
#include "TestUtils.h"
#include <QSignalSpy>
Q_DECLARE_METATYPE( Marble::GeoDataPlacemark * )
namespace Marble
{
class PlacemarkPositionProviderPluginTest : public QObject
{
Q_OBJECT
public:
PlacemarkPositionProviderPluginTest();
static PositionProviderPlugin *createUninitializedPlugin( const PluginManager *pluginManager );
static PositionProviderPlugin *createInitializedPlugin( const MarbleModel *model );
private Q_SLOTS:
void initialize_data();
void initialize();
void setTrackedPlacemark_afterInitialize_data();
void setTrackedPlacemark_afterInitialize();
void setClockDateTime();
private:
const QDateTime m_minTime;
const QDateTime m_maxTime;
GeoDataPlacemark m_placemark1;
GeoDataPlacemark m_placemark2;
};
PlacemarkPositionProviderPluginTest::PlacemarkPositionProviderPluginTest() :
m_minTime( QDate( 2000, 1, 1 ), QTime( 0, 0 ) ),
m_maxTime( QDate( 2000, 1, 2 ), QTime( 23, 59 ) )
{
qRegisterMetaType<GeoDataCoordinates>( "GeoDataCoordinates" );
qRegisterMetaType<GeoDataAccuracy>( "GeoDataAccuracy" );
qRegisterMetaType<PositionProviderStatus>( "PositionProviderStatus" );
GeoDataTrack *track = new GeoDataTrack;
track->setInterpolate( true );
track->addPoint( m_minTime, GeoDataCoordinates() );
track->addPoint( m_maxTime, GeoDataCoordinates() );
m_placemark1.setGeometry( track );
m_placemark2 = m_placemark1;
}
PositionProviderPlugin *PlacemarkPositionProviderPluginTest::createUninitializedPlugin( const PluginManager *pluginManager )
{
foreach ( const PositionProviderPlugin *plugin, pluginManager->positionProviderPlugins() ) {
if (plugin->nameId() == QLatin1String("Placemark")) {
PositionProviderPlugin *instance = plugin->newInstance();
return instance;
}
}
- return 0;
+ return nullptr;
}
PositionProviderPlugin *PlacemarkPositionProviderPluginTest::createInitializedPlugin( const MarbleModel *model )
{
PositionProviderPlugin *const plugin = createUninitializedPlugin( model->pluginManager() );
- if ( plugin == 0 ) {
- return 0;
+ if ( plugin == nullptr ) {
+ return nullptr;
}
plugin->initialize();
return plugin;
}
void PlacemarkPositionProviderPluginTest::initialize_data()
{
QTest::addColumn<GeoDataPlacemark *>( "placemark" );
- GeoDataPlacemark *const nullPlacemark = 0;
+ GeoDataPlacemark *const nullPlacemark = nullptr;
addRow() << nullPlacemark;
addRow() << &m_placemark1;
}
void PlacemarkPositionProviderPluginTest::initialize()
{
QFETCH( GeoDataPlacemark *, placemark );
const PositionProviderStatus expectedStatus = placemark ? PositionProviderStatusAvailable : PositionProviderStatusUnavailable;
const int expectedStatusCount = placemark ? 1 : 0;
const int expectedPositionCount = placemark ? 1 : 0;
MarbleModel model;
model.setClockDateTime( m_minTime ); // FIXME crashes when this line is removed
model.setTrackedPlacemark( placemark );
QVERIFY( model.trackedPlacemark() == placemark );
PositionProviderPlugin *const plugin = createUninitializedPlugin( model.pluginManager() );
- QVERIFY2( plugin != 0, "Need a PlacemarkPositionProviderPlugin!" );
+ QVERIFY2( plugin != nullptr, "Need a PlacemarkPositionProviderPlugin!" );
QCOMPARE( plugin->status(), PositionProviderStatusUnavailable );
QSignalSpy statusChangedSpy( plugin, SIGNAL(statusChanged(PositionProviderStatus)) );
QSignalSpy positionChangedSpy( plugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)) );
plugin->initialize();
QCOMPARE( plugin->status(), expectedStatus );
QCOMPARE( statusChangedSpy.count(), expectedStatusCount );
QCOMPARE( positionChangedSpy.count(), expectedPositionCount );
delete plugin;
}
void PlacemarkPositionProviderPluginTest::setTrackedPlacemark_afterInitialize_data()
{
QTest::addColumn<GeoDataPlacemark *>( "initialPlacemark" );
QTest::addColumn<GeoDataPlacemark *>( "newPlacemark" );
QTest::addColumn<int>( "expectedStatusCount" );
- GeoDataPlacemark *const nullPlacemark = 0;
+ GeoDataPlacemark *const nullPlacemark = nullptr;
addRow() << nullPlacemark << nullPlacemark << 0;
addRow() << nullPlacemark << &m_placemark1 << 1;
addRow() << &m_placemark1 << nullPlacemark << 1;
addRow() << &m_placemark1 << &m_placemark2 << 2;
}
void PlacemarkPositionProviderPluginTest::setTrackedPlacemark_afterInitialize()
{
QFETCH( GeoDataPlacemark *, initialPlacemark );
QFETCH( GeoDataPlacemark *, newPlacemark );
QFETCH( int, expectedStatusCount );
const PositionProviderStatus expectedStatus = newPlacemark ? PositionProviderStatusAvailable : PositionProviderStatusUnavailable;
const int expectedPositionCount = newPlacemark ? 1 : 0;
MarbleModel model;
model.setClockDateTime( m_minTime ); // FIXME crashes when this line is removed
model.setTrackedPlacemark( initialPlacemark );
QVERIFY( model.trackedPlacemark() == initialPlacemark );
PositionProviderPlugin *const plugin = createInitializedPlugin( &model );
- QVERIFY2( plugin != 0, "Need a PlacemarkPositionProviderPlugin!" );
+ QVERIFY2( plugin != nullptr, "Need a PlacemarkPositionProviderPlugin!" );
QSignalSpy statusChangedSpy( plugin, SIGNAL(statusChanged(PositionProviderStatus)) );
QSignalSpy positionChangedSpy( plugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)) );
model.setTrackedPlacemark( newPlacemark );
QCOMPARE( plugin->status(), expectedStatus );
QCOMPARE( statusChangedSpy.count(), expectedStatusCount );
QCOMPARE( positionChangedSpy.count(), expectedPositionCount );
delete plugin;
}
void PlacemarkPositionProviderPluginTest::setClockDateTime()
{
MarbleModel model;
model.setClockDateTime( m_minTime ); // FIXME crashes when this line is removed
model.setTrackedPlacemark( &m_placemark1 );
PositionProviderPlugin *const plugin = createInitializedPlugin( &model );
- QVERIFY2( plugin != 0, "Need a PlacemarkPositionProviderPlugin!" );
+ QVERIFY2( plugin != nullptr, "Need a PlacemarkPositionProviderPlugin!" );
QSignalSpy positionChangedSpy( plugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)) );
model.setClockDateTime( m_minTime );
QCOMPARE( positionChangedSpy.count(), 1 );
model.setClockDateTime( m_minTime ); // FIXME crashes when using m_maxTime
QCOMPARE( positionChangedSpy.count(), 2 );
delete plugin;
}
}
QTEST_MAIN( Marble::PlacemarkPositionProviderPluginTest )
#include "PlacemarkPositionProviderPluginTest.moc"
diff --git a/tests/PositionTrackingTest.cpp b/tests/PositionTrackingTest.cpp
index 9ca812ecf..2cf515e30 100644
--- a/tests/PositionTrackingTest.cpp
+++ b/tests/PositionTrackingTest.cpp
@@ -1,239 +1,239 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "GeoDataTreeModel.h"
#include "GeoDataAccuracy.h"
#include "PositionProviderPlugin.h"
#include "PositionTracking.h"
#include "TestUtils.h"
#include <QSignalSpy>
class FakeProvider : public Marble::PositionProviderPlugin
{
public:
FakeProvider() :
m_status( Marble::PositionProviderStatusUnavailable ),
m_position(),
m_accuracy(),
m_speed( 0.0 ),
m_direction( 0.0 ),
m_timestamp()
{}
QString name() const override { return "fake plugin"; }
QString guiString() const override { return "fake"; }
QString nameId() const override { return "fakeplugin"; }
QString version() const override { return "1.0"; }
QString description() const override { return "plugin for testing"; }
QIcon icon() const override { return QIcon(); }
QString copyrightYears() const override { return "2012"; }
QVector<Marble::PluginAuthor> pluginAuthors() const override { return QVector<Marble::PluginAuthor>(); }
void initialize() override {}
bool isInitialized() const override { return true; }
Marble::PositionProviderStatus status() const override { return m_status; }
Marble::GeoDataCoordinates position() const override { return m_position; }
Marble::GeoDataAccuracy accuracy() const override { return m_accuracy; }
qreal speed() const override { return m_speed; }
qreal direction() const override { return m_direction; }
QDateTime timestamp() const override { return m_timestamp; }
- Marble::PositionProviderPlugin *newInstance() const override { return 0; }
+ Marble::PositionProviderPlugin *newInstance() const override { return nullptr; }
void setStatus( Marble::PositionProviderStatus status );
void setPosition( const Marble::GeoDataCoordinates &position,
const Marble::GeoDataAccuracy &accuracy,
qreal speed,
qreal direction,
const QDateTime &timestamp );
private:
Marble::PositionProviderStatus m_status;
Marble::GeoDataCoordinates m_position;
Marble::GeoDataAccuracy m_accuracy;
qreal m_speed;
qreal m_direction;
QDateTime m_timestamp;
};
void FakeProvider::setStatus( Marble::PositionProviderStatus status )
{
const Marble::PositionProviderStatus oldStatus = m_status;
m_status = status;
if ( oldStatus != m_status ) {
emit statusChanged( m_status );
}
}
void FakeProvider::setPosition( const Marble::GeoDataCoordinates &position,
const Marble::GeoDataAccuracy &accuracy,
qreal speed,
qreal direction,
const QDateTime &timestamp )
{
m_position = position;
m_accuracy = accuracy;
m_speed = speed;
m_direction = direction;
m_timestamp = timestamp;
emit positionChanged( m_position, m_accuracy );
}
namespace Marble
{
class PositionTrackingTest : public QObject
{
Q_OBJECT
public:
PositionTrackingTest();
private Q_SLOTS:
void construct();
void statusChanged_data();
void statusChanged();
void setPositionProviderPlugin();
void clearTrack();
};
PositionTrackingTest::PositionTrackingTest()
{
qRegisterMetaType<GeoDataCoordinates>( "GeoDataCoordinates" );
qRegisterMetaType<PositionProviderStatus>( "PositionProviderStatus" );
}
void PositionTrackingTest::construct()
{
GeoDataTreeModel treeModel;
const PositionTracking tracking( &treeModel );
- QCOMPARE( const_cast<PositionTracking &>( tracking ).positionProviderPlugin(), static_cast<PositionProviderPlugin *>( 0 ) );
+ QCOMPARE( const_cast<PositionTracking &>( tracking ).positionProviderPlugin(), static_cast<PositionProviderPlugin *>( nullptr ) );
QCOMPARE( tracking.speed(), qreal( 0 ) );
QCOMPARE( tracking.direction(), qreal( 0 ) );
QCOMPARE( tracking.timestamp(), QDateTime() );
QCOMPARE( tracking.accuracy(), GeoDataAccuracy() );
QCOMPARE( tracking.trackVisible(), true );
QCOMPARE( tracking.currentLocation(), GeoDataCoordinates() );
QCOMPARE( tracking.status(), PositionProviderStatusUnavailable );
QCOMPARE( tracking.isTrackEmpty(), true );
QCOMPARE( treeModel.rowCount(), 1 );
const QModelIndex indexPositionTracking = treeModel.index( 0, 0 );
QCOMPARE( treeModel.data( indexPositionTracking, Qt::DisplayRole ).toString(), QString( "Position Tracking" ) );
QCOMPARE( treeModel.rowCount( indexPositionTracking ), 2 );
const QModelIndex indexCurrentPosition = treeModel.index( 0, 0, indexPositionTracking );
QCOMPARE( treeModel.data( indexCurrentPosition, Qt::DisplayRole ).toString(), QString( "Current Position" ) );
const QModelIndex indexCurrentTrack = treeModel.index( 1, 0, indexPositionTracking );
QCOMPARE( treeModel.data( indexCurrentTrack, Qt::DisplayRole ).toString(), QString( "Current Track" ) );
}
void PositionTrackingTest::statusChanged_data()
{
QTest::addColumn<PositionProviderStatus>( "finalStatus" );
addRow() << PositionProviderStatusError;
addRow() << PositionProviderStatusUnavailable;
addRow() << PositionProviderStatusAcquiring;
addRow() << PositionProviderStatusAvailable;
}
void PositionTrackingTest::statusChanged()
{
QFETCH( PositionProviderStatus, finalStatus );
const int expectedStatusChangedCount = ( finalStatus == PositionProviderStatusUnavailable ) ? 0 : 1;
GeoDataTreeModel treeModel;
PositionTracking tracking( &treeModel );
QSignalSpy statusChangedSpy( &tracking, SIGNAL(statusChanged(PositionProviderStatus)) );
FakeProvider provider;
provider.setStatus( finalStatus );
tracking.setPositionProviderPlugin( &provider );
QCOMPARE( tracking.status(), finalStatus );
QCOMPARE( statusChangedSpy.count(), expectedStatusChangedCount );
}
void PositionTrackingTest::setPositionProviderPlugin()
{
const GeoDataCoordinates coordinates( 1.2, 0.9 );
const GeoDataAccuracy accuracy( GeoDataAccuracy::Detailed, 10.0, 22.0 );
const qreal speed = 32.8;
const qreal direction = 49.7;
const QDateTime timestamp( QDate( 1, 3, 1994 ) );
GeoDataTreeModel treeModel;
PositionTracking tracking( &treeModel );
QSignalSpy gpsLocationSpy( &tracking, SIGNAL(gpsLocation(GeoDataCoordinates,qreal)) );
QPointer<FakeProvider> provider( new FakeProvider );
provider->setStatus( PositionProviderStatusAvailable );
provider->setPosition( coordinates, accuracy, speed, direction, timestamp );
tracking.setPositionProviderPlugin( provider );
QCOMPARE( tracking.currentLocation(), coordinates );
QCOMPARE( tracking.accuracy(), accuracy );
QCOMPARE( tracking.speed(), speed );
QCOMPARE( tracking.direction(), direction );
QCOMPARE( tracking.timestamp(), timestamp );
QCOMPARE( gpsLocationSpy.count(), 1 );
- tracking.setPositionProviderPlugin( 0 );
+ tracking.setPositionProviderPlugin( nullptr );
QVERIFY( provider.isNull() );
}
void PositionTrackingTest::clearTrack()
{
const GeoDataCoordinates position( 2.1, 0.8 );
const GeoDataAccuracy accuracy( GeoDataAccuracy::Detailed, 10.0, 22.0 );
const qreal speed = 32.8;
const qreal direction = 49.7;
const QDateTime timestamp( QDate( 1, 3, 1994 ) );
GeoDataTreeModel treeModel;
PositionTracking tracking( &treeModel );
FakeProvider provider;
tracking.setPositionProviderPlugin( &provider );
tracking.clearTrack();
QVERIFY( tracking.isTrackEmpty() );
provider.setStatus( PositionProviderStatusAvailable );
provider.setPosition( position, accuracy, speed, direction, timestamp );
QVERIFY( !tracking.isTrackEmpty() );
tracking.clearTrack();
QVERIFY( tracking.isTrackEmpty() );
}
}
QTEST_MAIN( Marble::PositionTrackingTest )
#include "PositionTrackingTest.moc"
diff --git a/tests/RenderPluginModelTest.cpp b/tests/RenderPluginModelTest.cpp
index 208339557..75cf7f49f 100644
--- a/tests/RenderPluginModelTest.cpp
+++ b/tests/RenderPluginModelTest.cpp
@@ -1,58 +1,58 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "RenderPluginModel.h"
#include "MarbleMap.h"
#include "TestUtils.h"
namespace Marble
{
class RenderPluginModelTest : public QObject
{
Q_OBJECT
public:
RenderPluginModelTest() :
- m_map( 0 )
+ m_map( nullptr )
{}
private Q_SLOTS:
void initTestCase() { m_map = new MarbleMap(); }
void cleanupTestCase() { delete m_map; }
void construct();
void setRenderPlugins();
private:
MarbleMap *m_map;
};
void RenderPluginModelTest::construct()
{
const RenderPluginModel model;
QCOMPARE( model.rowCount(), 0 );
}
void RenderPluginModelTest::setRenderPlugins()
{
RenderPluginModel model;
model.setRenderPlugins( m_map->renderPlugins() );
QCOMPARE( model.rowCount(), m_map->renderPlugins().count() );
}
}
QTEST_MAIN( Marble::RenderPluginModelTest )
#include "RenderPluginModelTest.moc"
diff --git a/tests/ScreenGraphicsItemTest.cpp b/tests/ScreenGraphicsItemTest.cpp
index eb9e6a723..3fdcc92f9 100644
--- a/tests/ScreenGraphicsItemTest.cpp
+++ b/tests/ScreenGraphicsItemTest.cpp
@@ -1,105 +1,105 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
//
#include "ScreenGraphicsItem.h"
#include "GeoGraphicsItem.h"
#include <QTest>
namespace Marble
{
class ScreenGraphicsItemTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void defaultConstructorValues();
void constructorValuesScreenParent();
void setLayout();
};
void ScreenGraphicsItemTest::defaultConstructorValues()
{
const ScreenGraphicsItem item;
- QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( 0 ) );
+ QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( nullptr ) );
QCOMPARE( item.cacheMode(), ScreenGraphicsItem::NoCache );
QCOMPARE( item.visible(), true );
QCOMPARE( item.size(), QSizeF() );
QCOMPARE( item.contentSize(), QSizeF() );
QCOMPARE( item.position(), QPointF( 0, 0 ) );
QCOMPARE( item.positivePosition(), QPointF( 0, 0 ) );
QCOMPARE( item.absolutePositions().size(), 1 );
QCOMPARE( item.absolutePositions()[0], QPointF( 0, 0 ) );
// invariants
QCOMPARE( item.contentRect(), QRectF( item.position(), item.contentSize() ) );
}
void ScreenGraphicsItemTest::constructorValuesScreenParent()
{
ScreenGraphicsItem screenParent;
QVERIFY( screenParent.absolutePositions().size() == 1 );
QVERIFY( screenParent.absolutePositions()[0] == QPointF( 0, 0 ) );
const ScreenGraphicsItem item( &screenParent );
- QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( 0 ) );
+ QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( nullptr ) );
QCOMPARE( item.cacheMode(), ScreenGraphicsItem::NoCache );
QCOMPARE( item.visible(), true );
QCOMPARE( item.size(), QSizeF() );
QCOMPARE( item.contentSize(), QSizeF() );
QCOMPARE( item.position(), QPointF( 0, 0 ) );
QCOMPARE( item.positivePosition(), QPointF( 0, 0 ) );
// invariants
QCOMPARE( item.contentRect(), QRectF( item.position(), item.contentSize() ) );
QCOMPARE( item.absolutePositions().size(), screenParent.absolutePositions().size() );
QCOMPARE( item.absolutePositions(), screenParent.absolutePositions() );
}
void ScreenGraphicsItemTest::setLayout()
{
ScreenGraphicsItem screenParent;
QVERIFY( screenParent.absolutePositions().size() == 1 );
QVERIFY( screenParent.absolutePositions()[0] == QPointF( 0, 0 ) );
const ScreenGraphicsItem item( &screenParent );
- QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( 0 ) );
+ QCOMPARE( item.layout(), static_cast<AbstractMarbleGraphicsLayout *>( nullptr ) );
QCOMPARE( item.cacheMode(), ScreenGraphicsItem::NoCache );
QCOMPARE( item.visible(), true );
QCOMPARE( item.size(), QSizeF() );
QCOMPARE( item.contentSize(), QSizeF() );
QCOMPARE( item.position(), QPointF( 0, 0 ) );
QCOMPARE( item.positivePosition(), QPointF( 0, 0 ) );
// invariants
QCOMPARE( item.contentRect(), QRectF( item.position(), item.contentSize() ) );
QCOMPARE( item.absolutePositions().size(), screenParent.absolutePositions().size() );
QCOMPARE( item.absolutePositions(), screenParent.absolutePositions() );
}
}
QTEST_MAIN( Marble::ScreenGraphicsItemTest )
#include "ScreenGraphicsItemTest.moc"
diff --git a/tests/TestBalloonStyle.cpp b/tests/TestBalloonStyle.cpp
index 428f3e12a..5254616f7 100644
--- a/tests/TestBalloonStyle.cpp
+++ b/tests/TestBalloonStyle.cpp
@@ -1,82 +1,82 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Dennis Nienhüser <nienhueser@kde.org>
//
#include <QObject>
#include <GeoDataDocument.h>
#include <MarbleDebug.h>
#include <GeoDataFolder.h>
#include <GeoDataPlacemark.h>
#include <GeoDataStyle.h>
#include <GeoDataBalloonStyle.h>
#include "TestUtils.h"
using namespace Marble;
class TestBalloonStyle : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestBalloonStyle::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestBalloonStyle::simpleParseTest()
{
QString const content (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Document>"
" <name>The one and only BalloonStyle test case</name>"
" <Style id=\"my-balloon-style\">"
" <BalloonStyle>"
" <bgColor>aa112233</bgColor>"
" <textColor>bb445566</textColor>"
" <text>This is my balloon style. There are many like it, but this is mine.</text>"
" <displayMode>hide</displayMode>"
" </BalloonStyle>"
" </Style>"
" <Folder>"
" <Placemark>"
" <name>The first placemark</name>"
" <styleUrl>#my-balloon-style</styleUrl>"
" <Point><coordinates>80.0,30.0</coordinates></Point>"
" </Placemark>"
" </Folder>"
"</Document>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( content );
QCOMPARE( dataDocument->folderList().size(), 1 );
GeoDataFolder *folder = dataDocument->folderList().at( 0 );
QCOMPARE( folder->size(), 1 );
GeoDataPlacemark *placemark1 = dynamic_cast<GeoDataPlacemark*>( folder->child( 0 ) );
- QVERIFY( placemark1 != 0 );
+ QVERIFY( placemark1 != nullptr );
QCOMPARE( placemark1->name(), QString( "The first placemark" ) );
QCOMPARE( placemark1->style()->balloonStyle().backgroundColor().red(), 51 );
QCOMPARE( placemark1->style()->balloonStyle().textColor().blue(), 68 );
QCOMPARE( placemark1->style()->balloonStyle().displayMode(), GeoDataBalloonStyle::Hide );
QString const text = "This is my balloon style. There are many like it, but this is mine.";
QCOMPARE( placemark1->style()->balloonStyle().text(), text );
delete dataDocument;
}
QTEST_MAIN( TestBalloonStyle )
#include "TestBalloonStyle.moc"
diff --git a/tests/TestCamera.cpp b/tests/TestCamera.cpp
index ab4a87661..79a9a0777 100644
--- a/tests/TestCamera.cpp
+++ b/tests/TestCamera.cpp
@@ -1,72 +1,72 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Dennis Nienhüser <nienhueser@kde.org>
//
#include <QObject>
#include <GeoDataDocument.h>
#include <MarbleDebug.h>
#include <GeoDataCamera.h>
#include "TestUtils.h"
using namespace Marble;
class TestCamera : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestCamera::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestCamera::simpleParseTest()
{
QString const kmlContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Document>"
" <Camera id=\"myCam\">"
" <longitude>1</longitude>"
" <latitude>2</latitude>"
" <altitude>3</altitude>"
" <heading>4</heading>"
" <tilt>5</tilt>"
" <roll>6</roll>"
" <altitudeMode>relativeToGround</altitudeMode>"
" </Camera>"
"</Document>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( kmlContent );
GeoDataCamera *camera = dynamic_cast<GeoDataCamera*>( dataDocument->abstractView() );
- QVERIFY( camera != 0);
+ QVERIFY( camera != nullptr);
GeoDataCoordinates::Unit const degree = GeoDataCoordinates::Degree;
QCOMPARE( camera->longitude( degree ), 1.0 );
QCOMPARE( camera->latitude( degree ), 2.0 );
QCOMPARE( camera->altitude(), 3.0 );
QCOMPARE( camera->heading(), 4.0 );
QCOMPARE( camera->tilt(), 5.0 );
QCOMPARE( camera->roll(), 6.0 );
QCOMPARE( camera->altitudeMode(), RelativeToGround );
delete dataDocument;
}
QTEST_MAIN( TestCamera )
#include "TestCamera.moc"
diff --git a/tests/TestEquality.cpp b/tests/TestEquality.cpp
index 3c93cab18..517b8a951 100644
--- a/tests/TestEquality.cpp
+++ b/tests/TestEquality.cpp
@@ -1,2376 +1,2376 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2014 Calin Cruceru <crucerucalincristian@gmail.com>
// Copyright 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
// Copyright 2014 Abhinav Gangwar <abhgang@gmail.com>
//
#include <QObject>
#include <MarbleDebug.h>
#include <GeoDataAlias.h>
#include <GeoDataAccuracy.h>
#include <GeoDataSimpleArrayData.h>
#include <GeoDataData.h>
#include <GeoDataExtendedData.h>
#include <GeoDataBalloonStyle.h>
#include <GeoDataCamera.h>
#include <GeoDataColorStyle.h>
#include <GeoDataFlyTo.h>
#include <GeoDataHotSpot.h>
#include <GeoDataImagePyramid.h>
#include <GeoDataItemIcon.h>
#include <GeoDataLink.h>
#include <GeoDataAnimatedUpdate.h>
#include <GeoDataSoundCue.h>
#include "GeoDataPlaylist.h"
#include <GeoDataTourControl.h>
#include <GeoDataWait.h>
#include <GeoDataTour.h>
#include <GeoDataPoint.h>
#include <GeoDataLinearRing.h>
#include <GeoDataLineString.h>
#include <GeoDataPolygon.h>
#include <GeoDataLatLonQuad.h>
#include <GeoDataLatLonAltBox.h>
#include <GeoDataLatLonBox.h>
#include <GeoDataLod.h>
#include <GeoDataRegion.h>
#include <GeoDataIconStyle.h>
#include <GeoDataLabelStyle.h>
#include <GeoDataLineStyle.h>
#include <GeoDataListStyle.h>
#include <GeoDataPolyStyle.h>
#include <GeoDataStyle.h>
#include <GeoDataStyleMap.h>
#include <GeoDataTimeSpan.h>
#include <GeoDataTimeStamp.h>
#include <GeoDataViewVolume.h>
#include <GeoDataVec2.h>
#include <GeoDataScreenOverlay.h>
#include <GeoDataPhotoOverlay.h>
#include <GeoDataGroundOverlay.h>
#include <GeoDataSchema.h>
#include <GeoDataSimpleField.h>
#include <GeoDataScale.h>
#include <GeoDataOrientation.h>
#include <GeoDataLocation.h>
#include <GeoDataResourceMap.h>
#include <GeoDataModel.h>
#include <GeoDataTrack.h>
#include <GeoDataMultiTrack.h>
#include <GeoDataSnippet.h>
#include <GeoDataLookAt.h>
#include <GeoDataNetworkLink.h>
#include <GeoDataNetworkLinkControl.h>
#include <GeoDataFolder.h>
#include <GeoDataSchemaData.h>
#include <GeoDataSimpleData.h>
#include <GeoDataUpdate.h>
#include "TestUtils.h"
using namespace Marble;
class TestEquality : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void aliasTest();
void accuracyTest();
void simpleArrayDataTest();
void dataTest();
void extendedDataTest();
void balloonTest();
void colorTest();
void cameraTest();
void flyToTest();
void hotSpotTest();
void imagePyramidTest();
void itemIconTest();
void linkTest();
void tourTest();
void pointTest();
void linearRingTest();
void lineStringTest();
void polygonTest();
void latLonQuadTest();
void latLonBoxTest();
void latLonAltBoxTest();
void lodTest();
void regionTest();
void iconStyleTest();
void lineStyleTest();
void listStyleTest();
void polyStyleTest();
void labelStyleTest();
void styleTest();
void styleMapTest();
void timeSpanTest();
void timeStampTest();
void viewVolumeTest();
void vecTest();
void screenOverlayTest();
void photoOverlayTest();
void groundOverlayTest();
void simpleFieldTest();
void schemaTest();
void scaleTest();
void orientationTest();
void locationTest();
void resourceMapTest();
void modelTest();
void trackTest();
void multiTrackTest();
void snippetTest();
void lookAtTest();
void networkLinkTest();
void networkLinkControlTest();
void folderTest();
void simpleDataTest();
void schemaDataTest();
};
void TestEquality::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestEquality::aliasTest()
{
GeoDataAlias alias;
alias.setSourceHref("test1");
alias.setTargetHref("test1");
GeoDataAlias alias2;
alias2.setSourceHref("test1");
alias2.setTargetHref("test1");
QCOMPARE( alias, alias );
QCOMPARE( alias2, alias2 );
QCOMPARE( alias, alias2 );
alias.setSourceHref("test2");
alias2.setSourceHref("Test2");
QCOMPARE( alias == alias2, false );
QVERIFY( alias != alias2 );
alias.setSourceHref("test3");
alias.setTargetHref("test3");
alias2.setSourceHref("test3");
alias2.setTargetHref("test2");
QCOMPARE( alias == alias2, false );
alias2.setSourceHref("Test3");
QVERIFY( alias != alias2 );
alias.setSourceHref("Test3");
alias.setTargetHref("test2");
QCOMPARE( alias, alias2 );
}
void TestEquality::accuracyTest()
{
GeoDataAccuracy accuracy1, accuracy2;
accuracy1.level = GeoDataAccuracy::Country;
accuracy1.vertical = 2;
accuracy1.horizontal = 3;
accuracy2.level = GeoDataAccuracy::Country;
accuracy2.vertical = 2;
accuracy2.horizontal = 3;
QCOMPARE( accuracy1, accuracy1 );
QCOMPARE( accuracy2, accuracy2 );
QCOMPARE( accuracy1, accuracy2 );
accuracy1.vertical = 1;
QVERIFY( accuracy1 != accuracy2 );
accuracy1.horizontal = 1;
accuracy2.horizontal = 1;
QCOMPARE( accuracy1 == accuracy2, false );
}
void TestEquality::simpleArrayDataTest()
{
GeoDataSimpleArrayData simpleArray1, simpleArray2;
simpleArray1.append("Marble");
simpleArray1.append(2014);
simpleArray1.append("Globe");
simpleArray2.append("Globe");
simpleArray2.append(2014);
simpleArray2.append("Marble");
QCOMPARE( simpleArray1, simpleArray1 );
QCOMPARE( simpleArray2, simpleArray2 );
QCOMPARE( simpleArray1 == simpleArray2, false );
QVERIFY( simpleArray1 != simpleArray2 );
}
void TestEquality::dataTest()
{
GeoDataData data1, data2;
data1.setName("Something");
data1.setValue(QVariant(23.56));
data1.setDisplayName("Marble");
data2.setName("Something");
data2.setValue(QVariant(23.56));
data2.setDisplayName("Marble");
QCOMPARE( data1, data1 );
QCOMPARE( data2, data2 );
QCOMPARE( data1, data2 );
QCOMPARE( data1 != data2, false );
data1.setName("Marble");
data1.setDisplayName("Something");
QCOMPARE( data1 == data2, false );
QVERIFY( data1 != data2 );
}
void TestEquality::extendedDataTest()
{
GeoDataExtendedData extendedData1, extendedData2;
GeoDataData data1, data2;
data1.setName("Something");
data1.setValue(QVariant(23.56));
data1.setDisplayName("Marble");
data2.setName("Marble");
data2.setValue(QVariant(23.56));
data2.setDisplayName("Globe");
extendedData1.addValue(data1);
extendedData2.addValue(data2);
QCOMPARE( extendedData1, extendedData1 );
QCOMPARE( extendedData2, extendedData2 );
QCOMPARE( extendedData1 == extendedData2, false );
QVERIFY( extendedData1 != extendedData2 );
}
void TestEquality::balloonTest()
{
GeoDataBalloonStyle balloon1, balloon2;
balloon1.setBackgroundColor(Qt::white);
balloon1.setTextColor(Qt::black);
balloon1.setText("Text1");
balloon1.setDisplayMode(GeoDataBalloonStyle::Hide);
balloon2.setBackgroundColor(Qt::white);
balloon2.setTextColor(Qt::black);
balloon2.setText("Text1");
balloon2.setDisplayMode(GeoDataBalloonStyle::Hide);
QCOMPARE( balloon1, balloon1 );
QCOMPARE( balloon2, balloon2 );
QCOMPARE( balloon1, balloon2 );
balloon2.setDisplayMode(GeoDataBalloonStyle::Default);
QCOMPARE( balloon1 != balloon2, true );
balloon1.setDisplayMode(GeoDataBalloonStyle::Default);
balloon1.setText("Text2");
QCOMPARE( balloon1 == balloon2, false);
QVERIFY( balloon1 != balloon2 );
}
void TestEquality::colorTest()
{
GeoDataColorStyle color1, color2;
color1.setColor(Qt::white);
color2.setColor(Qt::white);
QCOMPARE( color1, color1 );
QCOMPARE( color2, color2 );
QCOMPARE( color1, color2 );
color1.setId("foo");
QVERIFY( color1 != color2 );
color2.setId("foo");
QCOMPARE( color1, color2 );
color1.setColorMode(GeoDataColorStyle::Random);
QCOMPARE( color1, color1 );
QCOMPARE( color2, color2 );
// Different color mode, so not equal
QVERIFY( color1 != color2 );
color2.setColorMode(GeoDataColorStyle::Random);
QCOMPARE( color1, color1 );
QCOMPARE( color2, color2 );
// Paint colors are now likely different, but we still consider them equal
QCOMPARE( color1, color2 );
color2.setColor( Qt::yellow );
QCOMPARE( color1, color1 );
QCOMPARE( color2, color2 );
QVERIFY( color1 != color2 );
}
void TestEquality::cameraTest()
{
GeoDataCamera camera1, camera2;
camera1.setAltitudeMode(Marble::Absolute);
camera1.setAltitude(100);
camera1.setLatitude(100);
camera1.setLongitude(100);
camera1.setHeading(200);
camera1.setRoll(300);
camera1.setTilt(400);
camera2.setAltitudeMode(Marble::ClampToGround);
camera2.setAltitude(100);
camera2.setLatitude(100);
camera2.setLongitude(100);
camera2.setHeading(200);
camera2.setRoll(300);
camera2.setTilt(400);
QCOMPARE( camera1, camera1 );
QCOMPARE( camera2, camera2 );
QCOMPARE( camera1 == camera2, false );
QVERIFY( camera1 != camera2 );
GeoDataTimeStamp timeStampBegin, timeStampEnd;
QDateTime date1( QDate(2014, 4, 7) );
timeStampBegin.setWhen( date1 );
timeStampEnd.setWhen( date1 );
timeStampBegin.setResolution( GeoDataTimeStamp::YearResolution );
timeStampEnd.setResolution( GeoDataTimeStamp::YearResolution );
GeoDataTimeSpan timeSpan1, timeSpan2;
timeSpan1.setBegin( timeStampBegin );
timeSpan1.setEnd( timeStampEnd );
timeSpan2.setBegin( timeStampBegin );
timeSpan2.setEnd( timeStampEnd );
GeoDataTimeStamp timeStamp1, timeStamp2;
QDateTime date2( QDate(2014, 4, 8) );
timeStamp1.setWhen( date2 );
timeStamp2.setWhen( date2 );
timeStamp1.setResolution( GeoDataTimeStamp::SecondResolution );
timeStamp2.setResolution( GeoDataTimeStamp::SecondResolution );
camera1.setTimeSpan( timeSpan1 );
camera2.setTimeSpan( timeSpan2 );
camera1.setTimeStamp( timeStamp1 );
camera2.setTimeStamp( timeStamp2 );
camera2.setAltitudeMode( Marble::Absolute );
QCOMPARE( camera1, camera2 );
QCOMPARE( camera2, camera2 );
QVERIFY( camera1 == camera2 );
camera1.setId("camera1");
camera2.setId("camera2");
QVERIFY( camera1 != camera2 );
camera1.setId("camera2");
QVERIFY( camera1 == camera2 );
timeStamp1.setResolution( GeoDataTimeStamp::YearResolution );
camera2.setTimeStamp( timeStamp1 );
QVERIFY( camera1 != camera2 );
}
void TestEquality::flyToTest()
{
GeoDataFlyTo flyTo1, flyTo2;
flyTo1.setDuration(7.6);
flyTo1.setFlyToMode(GeoDataFlyTo::Bounce);
flyTo2.setDuration( 5.8 );
flyTo1.setFlyToMode( GeoDataFlyTo::Smooth );
QCOMPARE( flyTo1, flyTo1 );
QCOMPARE( flyTo2, flyTo2 );
QCOMPARE( flyTo1 == flyTo2, false );
QVERIFY( flyTo1 != flyTo2 );
}
void TestEquality::hotSpotTest()
{
QPointF point1, point2;
point1.setX( 5 );
point1.setY( 4 );
point2.setX( 6 );
point2.setY( 2 );
GeoDataHotSpot hotSpot1, hotSpot2;
hotSpot1.setHotSpot( point1, GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction );
hotSpot2.setHotSpot( point2, GeoDataHotSpot::Pixels, GeoDataHotSpot::Pixels );
QCOMPARE( &hotSpot1, &hotSpot1 );
QCOMPARE( &hotSpot2, &hotSpot2 );
QCOMPARE( hotSpot1 == hotSpot2, false );
QVERIFY( hotSpot1 != hotSpot2 );
}
void TestEquality::imagePyramidTest()
{
GeoDataImagePyramid pyramid1, pyramid2;
pyramid1.setGridOrigin( GeoDataImagePyramid::LowerLeft );
pyramid1.setMaxHeight( 40 );
pyramid1.setMaxWidth( 30 );
pyramid1.setTileSize( 20 );
pyramid2.setGridOrigin( GeoDataImagePyramid::UpperLeft );
pyramid2.setMaxHeight( 50 );
pyramid2.setMaxWidth( 80 );
pyramid2.setTileSize( 30 );
QCOMPARE( &pyramid1, &pyramid1 );
QCOMPARE( &pyramid2, &pyramid2 );
QCOMPARE( pyramid1 == pyramid2, false );
QVERIFY( pyramid1 != pyramid2 );
}
void TestEquality::itemIconTest()
{
GeoDataItemIcon icon1, icon2;
QImage img1( 10, 20, QImage::Format_Mono );
QImage img2( 30, 50, QImage::Format_Mono );
img1.fill( Qt::green );
img2.fill( Qt::green );
icon1.setIcon( img1 );
icon1.setIconPath( "some/path" );
icon1.setState( GeoDataItemIcon::Open );
icon2.setIcon( img2 );
icon2.setIconPath( "some/other/path" );
icon2.setState( GeoDataItemIcon::Closed );
QCOMPARE( &icon1, &icon1 );
QCOMPARE( &icon2, &icon2 );
QCOMPARE( &icon1 == &icon2, false );
QVERIFY( &icon1 != &icon2 );
}
void TestEquality::linkTest()
{
GeoDataLink link1, link2;
link1.setHref("some/example/href.something");
link1.setRefreshInterval( 23 );
link1.setRefreshMode( GeoDataLink::OnChange );
link1.setViewBoundScale( 50 );
link1.setViewRefreshTime( 30 );
link2.setHref("some/other/example/href.something");
link1.setRefreshInterval( 32 );
link1.setRefreshMode(GeoDataLink::OnChange);
link1.setViewBoundScale( 60 );
link1.setViewRefreshTime( 40 );
QCOMPARE( &link1, &link1 );
QCOMPARE( &link2, &link2 );
QCOMPARE( &link1 == &link2, false );
QVERIFY( &link1 != &link2 );
}
void TestEquality::tourTest()
{
GeoDataTour tour1;
GeoDataTour tour2;
GeoDataPlaylist* playlist1 = new GeoDataPlaylist;
GeoDataPlaylist* playlist2 = new GeoDataPlaylist;
GeoDataAnimatedUpdate* animatedUpdate1 = new GeoDataAnimatedUpdate;
GeoDataAnimatedUpdate* animatedUpdate2 = new GeoDataAnimatedUpdate;
GeoDataSoundCue* cue1 = new GeoDataSoundCue;
GeoDataSoundCue* cue2 = new GeoDataSoundCue;
GeoDataTourControl* control1 = new GeoDataTourControl;
GeoDataTourControl* control2 = new GeoDataTourControl;
GeoDataWait* wait1 = new GeoDataWait;
GeoDataWait* wait2 = new GeoDataWait;
GeoDataFlyTo* flyTo1 = new GeoDataFlyTo;
GeoDataFlyTo* flyTo2 = new GeoDataFlyTo;
playlist1->addPrimitive( animatedUpdate1 );
playlist1->addPrimitive( cue1 );
playlist1->addPrimitive( control1 );
playlist1->addPrimitive( wait1 );
playlist1->addPrimitive( flyTo1 );
playlist2->addPrimitive( animatedUpdate2 );
playlist2->addPrimitive( cue2 );
playlist2->addPrimitive( control2 );
playlist2->addPrimitive( wait2 );
playlist2->addPrimitive( flyTo2 );
tour1.setPlaylist( playlist1 );
tour2.setPlaylist( playlist2 );
QCOMPARE( tour1, tour1 );
QCOMPARE( tour2, tour2 );
QCOMPARE( tour1 != tour2, false );
QVERIFY( tour1 == tour2 );
tour1.playlist()->swapPrimitives( 1, 3 );
QCOMPARE( tour1, tour1 );
QCOMPARE( tour2, tour2 );
QCOMPARE( tour1 == tour2, false );
QVERIFY( tour1 != tour2 );
tour1.playlist()->swapPrimitives( 1, 3 );
QVERIFY( tour1 == tour2 );
GeoDataSoundCue* cue3 = new GeoDataSoundCue;
tour1.playlist()->addPrimitive( cue3 );
QCOMPARE( tour1, tour1 );
QCOMPARE( tour2, tour2 );
QCOMPARE( tour1 == tour2, false );
QVERIFY( tour1 != tour2 );
// Test GeoDataFeature properties
tour1.setName( QString("Tour1") );
tour1.setSnippet( GeoDataSnippet("Text1", 10) );
tour1.setDescription( QString("Description1") );
tour1.setDescriptionCDATA( true );
tour1.setAddress( QString("Address1") );
tour1.setPhoneNumber( QString("+40768652156") );
tour1.setStyleUrl( QString("/link/to/style1") );
tour1.setPopularity( 66666 );
tour1.setZoomLevel( 10 );
tour1.setVisible( true );
tour1.setRole( QString("Role1") );
GeoDataStyle::Ptr style1(new GeoDataStyle), style2(new GeoDataStyle);
GeoDataIconStyle iconStyle;
QImage icon( 50, 50, QImage::Format_Mono );
icon.fill( Qt::black );
QPointF hotSpot = QPointF( 7.6, 6.4 );
iconStyle.setScale( 1.0 );
iconStyle.setIconPath( "path/to/icon" );
iconStyle.setIcon( icon );
iconStyle.setHotSpot( hotSpot, GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction );
iconStyle.setHeading( 0 );
GeoDataLabelStyle labelStyle;
labelStyle.setColor( Qt::blue );
labelStyle.setScale( 1.0 );
labelStyle.setAlignment( GeoDataLabelStyle::Center );
labelStyle.setFont( QFont( QStringLiteral( "Helvetica" ), 10 ) );
GeoDataLineStyle lineStyle;
QVector< qreal > pattern( 5, 6.2 );
lineStyle.setWidth( 1.2 );
lineStyle.setPhysicalWidth( 1.0 );
lineStyle.setCapStyle( Qt::RoundCap );
lineStyle.setPenStyle( Qt::SolidLine );
lineStyle.setBackground( false );
lineStyle.setDashPattern( pattern );
GeoDataPolyStyle polyStyle;
polyStyle.setColor( Qt::red );
polyStyle.setFill( false );
polyStyle.setOutline( false );
polyStyle.setBrushStyle( Qt::SolidPattern );
GeoDataBalloonStyle balloon;
balloon.setBackgroundColor(Qt::white);
balloon.setTextColor(Qt::black);
balloon.setText("SomeText");
balloon.setDisplayMode(GeoDataBalloonStyle::Hide);
GeoDataListStyle listStyle;
listStyle.setListItemType( GeoDataListStyle::Check );
listStyle.setBackgroundColor( Qt::gray );
for( int i = 0; i < 5; ++i ) {
GeoDataItemIcon *icon = new GeoDataItemIcon;
QImage img( 20 * ( i + 1 ), 20 * ( i + 1 ), QImage::Format_Mono );
img.fill( Qt::black );
icon->setIcon( img );
icon->setIconPath( QString("path/to/icon") );
icon->setState( GeoDataItemIcon::Open );
listStyle.append( icon );
}
style1->setIconStyle( iconStyle );
style1->setLineStyle( lineStyle );
style1->setLabelStyle( labelStyle );
style1->setPolyStyle( polyStyle );
style1->setBalloonStyle( balloon );
style1->setListStyle( listStyle );
style2 = style1;
GeoDataStyleMap styleMap1, styleMap2;
styleMap1["germany"] = "gst1";
styleMap1["germany"] = "gst2";
styleMap1["germany"] = "gst3";
styleMap1["poland"] = "pst1";
styleMap1["poland"] = "pst2";
styleMap1["poland"] = "pst3";
styleMap1.setLastKey("poland");
styleMap2 = styleMap1;
GeoDataRegion region1;
GeoDataRegion region2;
GeoDataLatLonAltBox latLonAltBox1;
GeoDataLod lod1;
latLonAltBox1.setEast( 40 );
latLonAltBox1.setWest( 50 );
latLonAltBox1.setNorth( 60 );
latLonAltBox1.setSouth( 70 );
latLonAltBox1.setRotation( 20 );
latLonAltBox1.setBoundaries( 70, 80, 50, 60 );
latLonAltBox1.setMaxAltitude( 100 );
latLonAltBox1.setMinAltitude( 20 );
latLonAltBox1.setAltitudeMode( Marble::Absolute );
region1.setLatLonAltBox( latLonAltBox1 );
region2.setLatLonAltBox( latLonAltBox1 );
lod1.setMaxFadeExtent( 20 );
lod1.setMinFadeExtent( 10 );
lod1.setMaxLodPixels( 30 );
lod1.setMinLodPixels( 5 );
region1.setLod( lod1 );
region2.setLod( lod1 );
GeoDataExtendedData extendedData1, extendedData2;
GeoDataData data1;
data1.setName( "Something" );
data1.setValue( QVariant(23.56) );
data1.setDisplayName( "Marble" );
extendedData1.addValue(data1);
extendedData2.addValue(data1);
GeoDataTimeStamp timeStamp1, timeStamp2;
QDateTime date1( QDate(1994, 10, 4) );
timeStamp1.setWhen( date1 );
timeStamp1.setResolution( GeoDataTimeStamp::YearResolution );
timeStamp2 = timeStamp1;
GeoDataCamera camera1, camera2;
camera1.setAltitudeMode(Marble::Absolute);
camera1.setAltitude(100);
camera1.setLatitude(100);
camera1.setLongitude(100);
camera1.setHeading(200);
camera1.setRoll(300);
camera1.setTilt(400);
camera2 = camera1;
tour1.setAbstractView( &camera1 );
tour1.setTimeStamp( timeStamp1 );
tour1.setExtendedData( extendedData1 );
tour1.setRegion( region1 );
tour1.setStyle( style1 );
tour1.setStyleMap( &styleMap1 );
tour2 = tour1;
QCOMPARE( tour1, tour1 );
QCOMPARE( tour2, tour2 );
QCOMPARE( tour1 != tour2, false );
QVERIFY( tour1 == tour2 );
GeoDataLookAt lookAt;
lookAt.setLatitude( 1.1113 );
lookAt.setLongitude( 2.33 );
lookAt.setAltitude( 1500 );
lookAt.setRange( 500 );
tour2.setAbstractView( &lookAt );
QVERIFY( tour1 != tour2 );
tour1.setAbstractView( &lookAt );
- tour1.setStyleMap( 0 );
+ tour1.setStyleMap( nullptr );
QVERIFY(tour1 != tour2 );
tour1.setStyleMap( &styleMap1 );
QVERIFY( tour1 == tour2 );
camera2.setRoll(400);
tour1.setAbstractView( &camera2 );
QVERIFY( tour1 != tour2 );
}
void TestEquality::pointTest()
{
GeoDataPoint point1, point2;
GeoDataCoordinates coord1, coord2;
coord1.set(100,100,100);
coord2.set(200,200,200);
point1.setCoordinates(coord1);
point2.setCoordinates(coord2);
QVERIFY( point1 != point2 );
QCOMPARE( point1 != point2, true );
coord1.set(100,150);
coord2.set(100,150);
point1.setCoordinates(coord1);
point2.setCoordinates(coord2);
QVERIFY( point1 == point2 );
QCOMPARE( point1, point2 );
QCOMPARE( point1 == point2, true );
QVERIFY( point1 == point1 );
QCOMPARE( point1, point2 );
}
void TestEquality::linearRingTest()
{
GeoDataLinearRing linearRing1, linearRing2;
GeoDataCoordinates coord1, coord2, coord3, coord4, coord5, coord6;
coord1.set(123,100);
coord2.set(124,101);
coord3.set(123,100);
coord4.set(123,100);
coord5.set(124,101);
coord6.set(123,100);
linearRing1.append(coord1);
linearRing1.append(coord2);
linearRing1.append(coord3);
linearRing2.append(coord4);
linearRing2.append(coord5);
linearRing2.append(coord6);
linearRing1.setTessellate(false);
linearRing2.setTessellate(false);
QVERIFY( linearRing1 == linearRing2 );
QCOMPARE( linearRing1 != linearRing2, false );
linearRing2.clear();
linearRing2.append(coord1);
linearRing2.append(coord3);
linearRing2.append(coord4);
QVERIFY( linearRing1 != linearRing2 );
QCOMPARE( linearRing1 == linearRing2, false );
}
void TestEquality::lineStringTest()
{
GeoDataLineString lineString1, lineString2;
GeoDataCoordinates coord1, coord2, coord3, coord4, coord5, coord6;
coord1.set(100,100,100);
coord2.set(-100,-100,-100);
coord3.set(50,50,50);
coord4.set(150,150,150);
coord5.set(-150,-150,-150);
coord6.set(-50,-50,-50);
lineString1.append(coord1);
lineString1.append(coord3);
lineString1.append(coord4);
lineString2.append(coord2);
lineString2.append(coord5);
lineString2.append(coord6);
lineString1.setTessellate(false);
lineString2.setTessellate(false);
QVERIFY( lineString1 != lineString2 );
QCOMPARE( lineString1 == lineString2, false );
lineString2.clear();
lineString2.append(coord1);
lineString2.append(coord3);
lineString2.append(coord4);
QVERIFY( lineString1 == lineString2 );
QCOMPARE( lineString1 != lineString2, false );
}
void TestEquality::polygonTest()
{
GeoDataPolygon polygon1, polygon2;
GeoDataLinearRing outerBoundary1, outerBoundary2;
GeoDataCoordinates coord1, coord2, coord3, coord4, coord5, coord6;
coord1.set(623,600);
coord2.set(624,601);
coord3.set(623,600);
coord4.set(623,600);
coord5.set(624,601);
coord6.set(623,600);
outerBoundary1.append(coord1);
outerBoundary1.append(coord2);
outerBoundary1.append(coord3);
outerBoundary2.append(coord4);
outerBoundary2.append(coord5);
outerBoundary2.append(coord6);
outerBoundary1.setTessellate(true);
outerBoundary2.setTessellate(true);
polygon1.setOuterBoundary(outerBoundary1);
polygon2.setOuterBoundary(outerBoundary2);
GeoDataLinearRing innerBoundary11, innerBoundary12, innerBoundary21, innerBoundary22;
GeoDataCoordinates coord111, coord112, coord113, coord121, coord122, coord123;
GeoDataCoordinates coord211, coord212, coord213, coord221, coord222, coord223;
coord111.set(100,100);
coord112.set(200,200);
coord113.set(100,100);
coord121.set(400,400);
coord122.set(500,500);
coord123.set(400,400);
coord211.set(100,100);
coord212.set(200,200);
coord213.set(100,100);
coord221.set(400,400);
coord222.set(500,500);
coord223.set(400,400);
innerBoundary11.append(coord111);
innerBoundary11.append(coord112);
innerBoundary11.append(coord113);
innerBoundary12.append(coord121);
innerBoundary12.append(coord122);
innerBoundary12.append(coord123);
innerBoundary21.append(coord211);
innerBoundary21.append(coord212);
innerBoundary21.append(coord213);
innerBoundary22.append(coord221);
innerBoundary22.append(coord222);
innerBoundary22.append(coord223);
innerBoundary11.setTessellate(true);
innerBoundary12.setTessellate(true);
innerBoundary21.setTessellate(true);
innerBoundary22.setTessellate(true);
polygon1.appendInnerBoundary(innerBoundary11);
polygon1.appendInnerBoundary(innerBoundary12);
polygon2.appendInnerBoundary(innerBoundary21);
polygon2.appendInnerBoundary(innerBoundary22);
polygon1.setTessellate(true);
polygon2.setTessellate(true);
QVERIFY( polygon1 == polygon2 );
QCOMPARE( polygon1 != polygon2, false );
polygon1.setTessellate(false);
QVERIFY( polygon1 != polygon2 );
polygon1.setTessellate(true);
polygon1.appendInnerBoundary(innerBoundary11);
QVERIFY( polygon1 != polygon2 );
QCOMPARE( polygon1 == polygon2, false );
/* Prepare for unequality test */
polygon2.appendInnerBoundary(innerBoundary11);
QVERIFY( polygon1 == polygon2 );
/* Test for unequality: make sure polygon's coordinates are not equal */
polygon2.appendInnerBoundary(innerBoundary11);
coord111.set(100,1);
innerBoundary11.clear();
innerBoundary11.append(coord111);
innerBoundary11.append(coord112);
innerBoundary11.append(coord113);
innerBoundary11.setTessellate(true);
polygon1.appendInnerBoundary(innerBoundary11);
QVERIFY( polygon1 != polygon2 );
QCOMPARE( polygon1 == polygon2, false );
}
void TestEquality::latLonQuadTest()
{
GeoDataLatLonQuad quad1, quad2;
quad1.setBottomLeftLatitude( 55, GeoDataCoordinates::Degree );
quad1.setBottomLeftLongitude( 60, GeoDataCoordinates::Degree );
quad1.setBottomRightLatitude( 45, GeoDataCoordinates::Degree );
quad1.setBottomRightLongitude( 50, GeoDataCoordinates::Degree );
quad1.setTopLeftLatitude( 55, GeoDataCoordinates::Degree );
quad1.setTopLeftLongitude( 60, GeoDataCoordinates::Degree );
quad1.setTopRightLatitude( 45, GeoDataCoordinates::Degree );
quad1.setTopRightLongitude( 50, GeoDataCoordinates::Degree );
quad2.setBottomLeftLatitude( 55, GeoDataCoordinates::Degree );
quad2.setBottomLeftLongitude( 60, GeoDataCoordinates::Degree );
quad2.setBottomRightLatitude( 45, GeoDataCoordinates::Degree );
quad2.setBottomRightLongitude( 50, GeoDataCoordinates::Degree );
quad2.setTopLeftLatitude( 55, GeoDataCoordinates::Degree );
quad2.setTopLeftLongitude( 60, GeoDataCoordinates::Degree );
quad2.setTopRightLatitude( 45, GeoDataCoordinates::Degree );
quad2.setTopRightLongitude( 50, GeoDataCoordinates::Degree );
QCOMPARE( quad1, quad1 );
QCOMPARE( quad2, quad2 );
QCOMPARE( quad1 != quad2, false );
QVERIFY( quad1 == quad2 );
quad1.setTopLeftLatitude( 65, GeoDataCoordinates::Degree );
QCOMPARE( quad1, quad1 );
QCOMPARE( quad2, quad2 );
QCOMPARE( quad1 == quad2, false );
QVERIFY( quad1 != quad2 );
}
void TestEquality::latLonBoxTest()
{
GeoDataLatLonBox latLonBox1, latLonBox2;
latLonBox1.setEast( 40 );
latLonBox1.setWest( 50 );
latLonBox1.setNorth( 60 );
latLonBox1.setSouth( 70 );
latLonBox1.setRotation( 20 );
latLonBox1.setBoundaries( 70, 80, 50, 60 );
latLonBox2.setEast( 40 );
latLonBox2.setWest( 50 );
latLonBox2.setNorth( 60 );
latLonBox2.setSouth( 70 );
latLonBox2.setRotation( 20 );
latLonBox2.setBoundaries( 70, 80, 50, 60 );
QCOMPARE( latLonBox1, latLonBox1 );
QCOMPARE( latLonBox2, latLonBox2 );
QCOMPARE( latLonBox1 != latLonBox2, false );
QVERIFY( latLonBox1 == latLonBox2 );
latLonBox2.setWest( 55 );
QCOMPARE( latLonBox1, latLonBox1 );
QCOMPARE( latLonBox2, latLonBox2 );
QCOMPARE( latLonBox1 == latLonBox2, false );
QVERIFY( latLonBox1 != latLonBox2 );
}
void TestEquality::latLonAltBoxTest()
{
GeoDataLatLonAltBox latLonAltBox1, latLonAltBox2;
latLonAltBox1.setEast( 40 );
latLonAltBox1.setWest( 50 );
latLonAltBox1.setNorth( 60 );
latLonAltBox1.setSouth( 70 );
latLonAltBox1.setRotation( 20 );
latLonAltBox1.setBoundaries( 70, 80, 50, 60 );
latLonAltBox1.setMaxAltitude( 100 );
latLonAltBox1.setMinAltitude( 20 );
latLonAltBox1.setAltitudeMode( Marble::Absolute );
latLonAltBox2.setEast( 40 );
latLonAltBox2.setWest( 50 );
latLonAltBox2.setNorth( 60 );
latLonAltBox2.setSouth( 70 );
latLonAltBox2.setRotation( 20 );
latLonAltBox2.setBoundaries( 70, 80, 50, 60 );
latLonAltBox2.setMaxAltitude( 100 );
latLonAltBox2.setMinAltitude( 20 );
latLonAltBox2.setAltitudeMode( Marble::Absolute );
QCOMPARE( latLonAltBox1, latLonAltBox1 );
QCOMPARE( latLonAltBox2, latLonAltBox2 );
QCOMPARE( latLonAltBox1 != latLonAltBox2, false );
QVERIFY( latLonAltBox1 == latLonAltBox2 );
latLonAltBox2.setEast( 30 );
QCOMPARE( latLonAltBox1, latLonAltBox1 );
QCOMPARE( latLonAltBox2, latLonAltBox2 );
QCOMPARE( latLonAltBox1 == latLonAltBox2, false );
QVERIFY( latLonAltBox1 != latLonAltBox2 );
}
void TestEquality::lodTest()
{
GeoDataLod lod1, lod2;
lod1.setMaxFadeExtent( 20 );
lod1.setMinFadeExtent( 10 );
lod1.setMaxLodPixels( 30 );
lod1.setMinLodPixels( 5 );
lod2.setMaxFadeExtent( 20 );
lod2.setMinFadeExtent( 10 );
lod2.setMaxLodPixels( 30 );
lod2.setMinLodPixels( 5 );
QCOMPARE( lod1, lod1 );
QCOMPARE( lod2, lod2 );
QCOMPARE( lod1 != lod2, false );
QVERIFY( lod1 == lod2 );
lod2.setMaxFadeExtent( 30 );
QCOMPARE( lod1, lod1 );
QCOMPARE( lod2, lod2 );
QCOMPARE( lod1 == lod2, false );
QVERIFY( lod1 != lod2 );
}
void TestEquality::regionTest()
{
GeoDataRegion region1;
GeoDataRegion region2;
GeoDataLatLonAltBox latLonAltBox1;
GeoDataLatLonAltBox latLonAltBox2;
latLonAltBox1.setEast( 40 );
latLonAltBox1.setWest( 50 );
latLonAltBox1.setNorth( 60 );
latLonAltBox1.setSouth( 70 );
latLonAltBox1.setRotation( 20 );
latLonAltBox1.setBoundaries( 70, 80, 50, 60 );
latLonAltBox1.setMaxAltitude( 100 );
latLonAltBox1.setMinAltitude( 20 );
latLonAltBox1.setAltitudeMode( Marble::Absolute );
latLonAltBox2.setEast( 40 );
latLonAltBox2.setWest( 50 );
latLonAltBox2.setNorth( 60 );
latLonAltBox2.setSouth( 70 );
latLonAltBox2.setRotation( 20 );
latLonAltBox2.setBoundaries( 70, 80, 50, 60 );
latLonAltBox2.setMaxAltitude( 100 );
latLonAltBox2.setMinAltitude( 20 );
latLonAltBox2.setAltitudeMode( Marble::Absolute );
region1.setLatLonAltBox( latLonAltBox1 );
region2.setLatLonAltBox( latLonAltBox2 );
GeoDataLod lod1;
GeoDataLod lod2;
lod1.setMaxFadeExtent( 20 );
lod1.setMinFadeExtent( 10 );
lod1.setMaxLodPixels( 30 );
lod1.setMinLodPixels( 5 );
lod2.setMaxFadeExtent( 20 );
lod2.setMinFadeExtent( 10 );
lod2.setMaxLodPixels( 30 );
lod2.setMinLodPixels( 5 );
region1.setLod( lod1 );
region2.setLod( lod2 );
QCOMPARE( region1, region1 );
QCOMPARE( region2, region2 );
QCOMPARE( region1 != region2, false );
QVERIFY( region1 == region2 );
region2.lod().setMaxFadeExtent( 30 );
QCOMPARE( region1, region1 );
QCOMPARE( region2, region2 );
QCOMPARE( region1 == region2, false );
QVERIFY( region1 != region2 );
}
void TestEquality::timeSpanTest()
{
GeoDataTimeSpan timeSpan1, timeSpan2;
GeoDataTimeStamp timeStampBegin, timeStampEnd;
QDateTime date1( QDate(2014, 1, 10) ), date2( QDate(2014, 4, 21) );
timeStampBegin.setWhen( date1 );
timeStampEnd.setWhen( date2 );
timeStampBegin.setResolution( GeoDataTimeStamp::DayResolution );
timeStampEnd.setResolution( GeoDataTimeStamp::DayResolution );
timeSpan1.setBegin( timeStampBegin );
timeSpan1.setEnd( timeStampEnd );
timeSpan2.setBegin( timeStampBegin );
timeSpan2.setEnd( timeStampBegin );
QCOMPARE( timeSpan1, timeSpan1 );
QCOMPARE( timeSpan2, timeSpan2 );
QCOMPARE( timeSpan1 == timeSpan2, false );
QVERIFY( timeSpan1 != timeSpan2 );
timeSpan2.setEnd( timeStampEnd );
timeSpan1.setTargetId("timeSpan2");
timeSpan2.setTargetId("timeSpan1");
QVERIFY( timeSpan1 != timeSpan2 );
timeSpan1.setTargetId("timeSpan1");
QVERIFY( timeSpan1 == timeSpan2 );
}
void TestEquality::timeStampTest()
{
GeoDataTimeStamp timeStamp1, timeStamp2;
QDateTime date1( QDate(1994, 10, 4) ), date2( QDate(2070, 10, 4) );
timeStamp1.setWhen( date1 );
timeStamp2.setWhen( date2 );
timeStamp1.setResolution( GeoDataTimeStamp::YearResolution );
timeStamp2.setResolution( GeoDataTimeStamp::DayResolution );
QCOMPARE( timeStamp1, timeStamp1 );
QCOMPARE( timeStamp2, timeStamp2 );
QCOMPARE( timeStamp1 == timeStamp2, false );
QVERIFY( timeStamp1 != timeStamp2 );
timeStamp2.setWhen( date1 );
timeStamp1.setResolution( GeoDataTimeStamp::DayResolution );
timeStamp1.setId("timeStamp1");
timeStamp2.setId("timeStamp2");
QVERIFY( timeStamp1 != timeStamp2 );
timeStamp1.setId("timeStamp2");
QVERIFY( timeStamp1 == timeStamp2 );
}
void TestEquality::iconStyleTest()
{
GeoDataIconStyle iconStyle1, iconStyle2;
QImage icon( 50, 50, QImage::Format_Mono );
icon.fill( Qt::black );
QPointF hotSpot = QPointF( 6.7, 4.6 );
iconStyle1.setScale( 1.0 );
iconStyle1.setIconPath( "path/to/icon" );
iconStyle1.setIcon( icon );
iconStyle1.setHotSpot( hotSpot, GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction );
iconStyle1.setHeading( 0 );
iconStyle2.setScale( 1.0 );
iconStyle2.setIconPath( "path/to/icon" );
iconStyle2.setIcon( icon );
iconStyle2.setHotSpot( hotSpot, GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction );
iconStyle2.setHeading( 0 );
QCOMPARE( iconStyle1, iconStyle1 );
QCOMPARE( iconStyle2, iconStyle2 );
QCOMPARE( iconStyle1 != iconStyle2, false );
QVERIFY( iconStyle1 == iconStyle2 );
iconStyle2.setHeading( 1 );
iconStyle2.setScale( 2.0 );
QCOMPARE( iconStyle1, iconStyle1 );
QCOMPARE( iconStyle2, iconStyle2 );
QCOMPARE( iconStyle1 == iconStyle2, false );
QVERIFY( iconStyle1 != iconStyle2 );
}
void TestEquality::lineStyleTest()
{
GeoDataLineStyle lineStyle1, lineStyle2;
QVector< qreal > pattern( 7, 7.8 );
lineStyle1.setWidth( 1.3 );
lineStyle1.setPhysicalWidth( 1.0 );
lineStyle1.setCapStyle( Qt::RoundCap );
lineStyle1.setPenStyle( Qt::SolidLine );
lineStyle1.setBackground( false );
lineStyle1.setDashPattern( pattern );
lineStyle2.setWidth( 1.3 );
lineStyle2.setPhysicalWidth( 1.0 );
lineStyle2.setCapStyle( Qt::RoundCap );
lineStyle2.setPenStyle( Qt::SolidLine );
lineStyle2.setBackground( false );
lineStyle2.setDashPattern( pattern );
QCOMPARE( lineStyle1, lineStyle2 );
QCOMPARE( lineStyle2, lineStyle2 );
QCOMPARE( lineStyle1 != lineStyle2, false );
QVERIFY( lineStyle1 == lineStyle2 );
lineStyle2.setCapStyle( Qt::FlatCap );
lineStyle2.setBackground( true );
QCOMPARE( lineStyle1, lineStyle1 );
QCOMPARE( lineStyle2, lineStyle2 );
QCOMPARE( lineStyle1 == lineStyle2, false );
QVERIFY( lineStyle1 != lineStyle2 );
}
void TestEquality::listStyleTest()
{
GeoDataListStyle listStyle1, listStyle2;
listStyle1.setListItemType( GeoDataListStyle::Check );
listStyle1.setBackgroundColor( Qt::gray );
for( int i = 0; i < 5; ++i ) {
GeoDataItemIcon *icon = new GeoDataItemIcon;
QImage img( 10 * ( i + 1 ), 10 * ( i + 1 ), QImage::Format_Mono );
img.fill( Qt::black );
icon->setIcon( img );
icon->setIconPath( QString("path/to/icon") );
icon->setState( GeoDataItemIcon::Open );
listStyle1.append( icon );
}
listStyle2.setListItemType( GeoDataListStyle::Check );
listStyle2.setBackgroundColor( Qt::gray );
for( int i = 0; i < 5; ++i ) {
GeoDataItemIcon *icon = new GeoDataItemIcon;
QImage img( 10 * ( i + 1 ), 10 * ( i + 1 ), QImage::Format_Mono );
img.fill( Qt::black );
icon->setIcon( img );
icon->setIconPath( QString("path/to/icon") );
icon->setState( GeoDataItemIcon::Open );
listStyle2.append( icon );
}
QCOMPARE( listStyle1, listStyle1 );
QCOMPARE( listStyle2, listStyle2 );
QCOMPARE( listStyle1 != listStyle2, false );
QVERIFY( listStyle1 == listStyle2 );
listStyle2.setBackgroundColor( Qt::green );
listStyle2.setListItemType( GeoDataListStyle::RadioFolder );
QCOMPARE( listStyle1, listStyle1 );
QCOMPARE( listStyle2, listStyle2 );
QCOMPARE( listStyle1 == listStyle2, false );
QVERIFY( listStyle1 != listStyle2 );
}
void TestEquality::polyStyleTest()
{
GeoDataPolyStyle polyStyle1, polyStyle2;
polyStyle1.setColor( Qt::red );
polyStyle1.setFill( false );
polyStyle1.setOutline( false );
polyStyle1.setBrushStyle( Qt::SolidPattern );
polyStyle2.setColor( Qt::red );
polyStyle2.setFill( false );
polyStyle2.setOutline( false );
polyStyle2.setBrushStyle( Qt::SolidPattern );
QCOMPARE( polyStyle1, polyStyle1 );
QCOMPARE( polyStyle2, polyStyle2 );
QCOMPARE( polyStyle1 != polyStyle2, false );
QVERIFY( polyStyle1 == polyStyle2 );
polyStyle2.setOutline( true );
polyStyle2.setBrushStyle( Qt::CrossPattern );
QCOMPARE( polyStyle1, polyStyle1 );
QCOMPARE( polyStyle2, polyStyle2 );
QCOMPARE( polyStyle1 == polyStyle2, false );
QVERIFY( polyStyle1 != polyStyle2 );
}
void TestEquality::labelStyleTest()
{
GeoDataLabelStyle labelStyle1, labelStyle2;
labelStyle1.setColor( Qt::blue );
labelStyle1.setScale( 1.0 );
labelStyle1.setAlignment( GeoDataLabelStyle::Center );
labelStyle1.setFont( QFont( QStringLiteral( "Helvetica" ), 10 ) );
labelStyle2.setColor( Qt::blue );
labelStyle2.setScale( 1.0 );
labelStyle2.setAlignment( GeoDataLabelStyle::Center );
labelStyle2.setFont( QFont( QStringLiteral( "Helvetica" ), 10 ) );
QCOMPARE( labelStyle1, labelStyle1 );
QCOMPARE( labelStyle2, labelStyle2 );
QCOMPARE( labelStyle1 != labelStyle2, false );
QVERIFY( labelStyle1 == labelStyle2);
labelStyle2.setAlignment( GeoDataLabelStyle::Corner );
labelStyle2.setFont( QFont( QStringLiteral( "Helvetica [Cronyx]" ), 12 ) );
QCOMPARE( labelStyle1, labelStyle1 );
QCOMPARE( labelStyle2, labelStyle2 );
QCOMPARE( labelStyle1 == labelStyle2, false);
QVERIFY( labelStyle1 != labelStyle2 );
}
void TestEquality::styleTest()
{
GeoDataStyle style1, style2;
GeoDataIconStyle iconStyle;
QImage icon( 50, 50, QImage::Format_Mono );
icon.fill( Qt::black );
QPointF hotSpot = QPointF( 7.6, 6.4 );
iconStyle.setScale( 1.0 );
iconStyle.setIconPath( "path/to/icon" );
iconStyle.setIcon( icon );
iconStyle.setHotSpot( hotSpot, GeoDataHotSpot::Fraction, GeoDataHotSpot::Fraction );
iconStyle.setHeading( 0 );
GeoDataLabelStyle labelStyle;
labelStyle.setColor( Qt::blue );
labelStyle.setScale( 1.0 );
labelStyle.setAlignment( GeoDataLabelStyle::Center );
labelStyle.setFont( QFont( QStringLiteral( "Helvetica" ), 10 ) );
GeoDataLineStyle lineStyle;
QVector< qreal > pattern( 5, 6.2 );
lineStyle.setWidth( 1.2 );
lineStyle.setPhysicalWidth( 1.0 );
lineStyle.setCapStyle( Qt::RoundCap );
lineStyle.setPenStyle( Qt::SolidLine );
lineStyle.setBackground( false );
lineStyle.setDashPattern( pattern );
GeoDataPolyStyle polyStyle;
polyStyle.setColor( Qt::red );
polyStyle.setFill( false );
polyStyle.setOutline( false );
polyStyle.setBrushStyle( Qt::SolidPattern );
GeoDataBalloonStyle balloon;
balloon.setBackgroundColor(Qt::white);
balloon.setTextColor(Qt::black);
balloon.setText("SomeText");
balloon.setDisplayMode(GeoDataBalloonStyle::Hide);
GeoDataListStyle listStyle;
listStyle.setListItemType( GeoDataListStyle::Check );
listStyle.setBackgroundColor( Qt::gray );
for( int i = 0; i < 5; ++i ) {
GeoDataItemIcon *icon = new GeoDataItemIcon;
QImage img( 20 * ( i + 1 ), 20 * ( i + 1 ), QImage::Format_Mono );
img.fill( Qt::black );
icon->setIcon( img );
icon->setIconPath( QString("path/to/icon") );
icon->setState( GeoDataItemIcon::Open );
listStyle.append( icon );
}
style1.setIconStyle( iconStyle );
style1.setLineStyle( lineStyle );
style1.setLabelStyle( labelStyle );
style1.setPolyStyle( polyStyle );
style1.setBalloonStyle( balloon );
style1.setListStyle( listStyle );
style2.setIconStyle( iconStyle );
style2.setLineStyle( lineStyle );
style2.setLabelStyle( labelStyle );
style2.setPolyStyle( polyStyle );
style2.setBalloonStyle( balloon );
style2.setListStyle( listStyle );
QCOMPARE( style1, style1 );
QCOMPARE( style2, style2 );
QCOMPARE( style1 != style2, false );
QVERIFY( style1 == style2 );
iconStyle.setScale( 2.0 );
labelStyle.setAlignment( GeoDataLabelStyle::Corner );
lineStyle.setBackground( true );
polyStyle.setOutline( true );
style2.setIconStyle( iconStyle );
style2.setLabelStyle( labelStyle );
style2.setLineStyle( lineStyle );
style2.setPolyStyle( polyStyle );
QCOMPARE( style1, style1 );
QCOMPARE( style2, style2 );
QCOMPARE( style1 == style2, false );
QVERIFY( style1 != style2 );
}
void TestEquality::styleMapTest()
{
GeoDataStyleMap styleMap1, styleMap2;
styleMap1["germany"] = "gst1";
styleMap1["germany"] = "gst2";
styleMap1["germany"] = "gst3";
styleMap1["poland"] = "pst1";
styleMap1["poland"] = "pst2";
styleMap1["poland"] = "pst3";
styleMap1.setLastKey("poland");
styleMap2["germany"] = "gst1";
styleMap2["germany"] = "gst2";
styleMap2["germany"] = "gst3";
styleMap2["poland"] = "pst1";
styleMap2["poland"] = "pst2";
styleMap2["poland"] = "pst3";
styleMap2.setLastKey("poland");
QCOMPARE( styleMap1, styleMap1 );
QCOMPARE( styleMap2, styleMap2 );
QCOMPARE( styleMap1 != styleMap2, false );
styleMap2.insert("Romania", "rst1");
styleMap2.insert("Romania", "rst2");
styleMap2.insert("Romania", "rst3");
styleMap2.setLastKey("Romania");
QCOMPARE( styleMap1, styleMap1 );
QCOMPARE( styleMap2, styleMap2 );
QCOMPARE( styleMap1 == styleMap2, false );
QVERIFY( styleMap1 != styleMap2 );
}
void TestEquality::viewVolumeTest()
{
GeoDataViewVolume volume1, volume2;
volume1.setLeftFov( 5.6 );
volume1.setRightFov( 6.5 );
volume1.setTopFov( 2.3 );
volume1.setBottomFov( 9.2 );
volume1.setNear( 8.6 );
volume2.setLeftFov( 5.6 );
volume2.setRightFov( 6.5 );
volume2.setTopFov( 2.3 );
volume2.setBottomFov( 9.2 );
volume2.setNear( 8.6 );
QCOMPARE( volume1, volume1 );
QCOMPARE( volume2, volume2 );
QCOMPARE( volume1 != volume2, false );
QVERIFY( volume1 == volume2 );
volume2.setRightFov( 7.3 );
QCOMPARE( volume1, volume1 );
QCOMPARE( volume2, volume2 );
QCOMPARE( volume1 == volume2, false );
QVERIFY( volume1 != volume2 );
}
void TestEquality::vecTest()
{
GeoDataVec2 vec1, vec2;
vec1.setXunits( GeoDataVec2::Fraction );
vec1.setYunits( GeoDataVec2::Pixels );
vec2.setXunits( GeoDataVec2::Fraction );
vec2.setYunits( GeoDataVec2::Pixels );
QCOMPARE( vec1, vec1 );
QCOMPARE( vec2, vec2 );
QCOMPARE( vec1 != vec2, false );
QVERIFY( vec1 == vec2 );
vec2.setYunits( GeoDataVec2::Fraction );
QCOMPARE( vec1, vec1 );
QCOMPARE( vec2, vec2 );
QCOMPARE( vec1 == vec2, false );
QVERIFY( vec1 != vec2 );
}
void TestEquality::screenOverlayTest()
{
GeoDataVec2 vec1, vec2, vec3, vec4;
vec1.setXunits( GeoDataVec2::Fraction );
vec1.setYunits( GeoDataVec2::Pixels );
vec2.setXunits( GeoDataVec2::Fraction );
vec2.setYunits( GeoDataVec2::InsetPixels );
vec3.setXunits( GeoDataVec2::Pixels );
vec3.setYunits( GeoDataVec2::Pixels );
vec4.setXunits( GeoDataVec2::Fraction );
vec4.setYunits( GeoDataVec2::Fraction );
GeoDataScreenOverlay overlay1, overlay2;
overlay1.setOverlayXY( vec1 );
overlay1.setRotationXY( vec2 );
overlay1.setScreenXY( vec3 );
overlay1.setSize( vec4 );
overlay1.setRotation( 3.4 );
overlay2.setOverlayXY( vec1 );
overlay2.setRotationXY( vec2 );
overlay2.setScreenXY( vec3 );
overlay2.setSize( vec4 );
overlay2.setRotation( 3.4 );
QCOMPARE( overlay1, overlay1 );
QCOMPARE( overlay2, overlay2 );
QCOMPARE( overlay1 != overlay2, false );
QVERIFY( overlay1 == overlay2 );
overlay2.setRotation( 7.3 );
QCOMPARE( overlay1, overlay1 );
QCOMPARE( overlay2, overlay2 );
QCOMPARE( overlay1 == overlay2, false );
QVERIFY( overlay1 != overlay2 );
}
void TestEquality::photoOverlayTest()
{
GeoDataPhotoOverlay overlay1, overlay2;
GeoDataViewVolume volume1, volume2;
volume1.setLeftFov( 5.6 );
volume1.setRightFov( 6.5 );
volume1.setTopFov( 2.3 );
volume1.setBottomFov( 9.2 );
volume1.setNear( 8.6 );
volume2.setLeftFov( 5.6 );
volume2.setRightFov( 6.5 );
volume2.setTopFov( 2.3 );
volume2.setBottomFov( 9.2 );
volume2.setNear( 8.6 );
overlay1.setViewVolume( volume1 );
overlay2.setViewVolume( volume2 );
GeoDataImagePyramid pyramid1, pyramid2;
pyramid1.setTileSize( 3 );
pyramid1.setMaxWidth( 5 );
pyramid1.setMaxHeight( 8 );
pyramid1.setGridOrigin( GeoDataImagePyramid::UpperLeft );
pyramid2.setTileSize( 3 );
pyramid2.setMaxWidth( 5 );
pyramid2.setMaxHeight( 8 );
pyramid2.setGridOrigin( GeoDataImagePyramid::UpperLeft );
overlay1.setImagePyramid( pyramid1 );
overlay2.setImagePyramid( pyramid2 );
GeoDataPoint point1, point2;
GeoDataCoordinates coord1, coord2;
coord1.set(100,100,100);
coord2.set(100,100,100);
point1.setCoordinates(coord1);
point2.setCoordinates(coord2);
overlay1.setPoint( point1 );
overlay2.setPoint( point2 );
overlay1.setShape( GeoDataPhotoOverlay::Cylinder );
overlay2.setShape( GeoDataPhotoOverlay::Cylinder );
overlay1.setRotation( 2.5 );
overlay2.setRotation( 2.5 );
QCOMPARE( overlay1, overlay1 );
QCOMPARE( overlay2, overlay2 );
QCOMPARE( overlay1 != overlay2, false );
QVERIFY( overlay1 == overlay2 );
overlay2.setRotation( 4.3 );
QCOMPARE( overlay1, overlay1 );
QCOMPARE( overlay2, overlay2 );
QCOMPARE( overlay1 == overlay2, false );
QVERIFY( overlay1 != overlay2 );
}
void TestEquality::groundOverlayTest()
{
GeoDataGroundOverlay overlay1, overlay2;
GeoDataLatLonBox latLonBox1, latLonBox2;
latLonBox1.setEast( 40 );
latLonBox1.setWest( 50 );
latLonBox1.setNorth( 60 );
latLonBox1.setSouth( 70 );
latLonBox1.setRotation( 20 );
latLonBox1.setBoundaries( 70, 80, 50, 60 );
latLonBox2.setEast( 40 );
latLonBox2.setWest( 50 );
latLonBox2.setNorth( 60 );
latLonBox2.setSouth( 70 );
latLonBox2.setRotation( 20 );
latLonBox2.setBoundaries( 70, 80, 50, 60 );
overlay1.setLatLonBox( latLonBox1 );
overlay2.setLatLonBox( latLonBox2 );
GeoDataLatLonQuad quad1, quad2;
quad1.setBottomLeftLatitude( 55, GeoDataCoordinates::Degree );
quad1.setBottomLeftLongitude( 60, GeoDataCoordinates::Degree );
quad1.setBottomRightLatitude( 45, GeoDataCoordinates::Degree );
quad1.setBottomRightLongitude( 50, GeoDataCoordinates::Degree );
quad1.setTopLeftLatitude( 55, GeoDataCoordinates::Degree );
quad1.setTopLeftLongitude( 60, GeoDataCoordinates::Degree );
quad1.setTopRightLatitude( 45, GeoDataCoordinates::Degree );
quad1.setTopRightLongitude( 50, GeoDataCoordinates::Degree );
quad2.setBottomLeftLatitude( 55, GeoDataCoordinates::Degree );
quad2.setBottomLeftLongitude( 60, GeoDataCoordinates::Degree );
quad2.setBottomRightLatitude( 45, GeoDataCoordinates::Degree );
quad2.setBottomRightLongitude( 50, GeoDataCoordinates::Degree );
quad2.setTopLeftLatitude( 55, GeoDataCoordinates::Degree );
quad2.setTopLeftLongitude( 60, GeoDataCoordinates::Degree );
quad2.setTopRightLatitude( 45, GeoDataCoordinates::Degree );
quad2.setTopRightLongitude( 50, GeoDataCoordinates::Degree );
overlay1.setLatLonQuad( quad1 );
overlay2.setLatLonQuad( quad2 );
overlay1.setAltitude( 23.5 );
overlay2.setAltitude( 23.5 );
overlay1.setAltitudeMode( Marble::Absolute );
overlay2.setAltitudeMode( Marble::Absolute );
QCOMPARE( overlay1, overlay1 );
QCOMPARE( overlay2, overlay2 );
QCOMPARE( overlay1 != overlay2, false );
QVERIFY( overlay1 == overlay2 );
overlay2.setAltitude( 42.3 );
QCOMPARE( overlay1, overlay1 );
QCOMPARE( overlay2, overlay2 );
QCOMPARE( overlay1 == overlay2, false );
QVERIFY( overlay1 != overlay2 );
}
void TestEquality::simpleFieldTest()
{
GeoDataSimpleField field1, field2;
field1.setDisplayName("Simple Field");
field1.setName("Field Name");
field1.setType(GeoDataSimpleField::Int);
field2.setDisplayName("Simple Field");
field2.setName("Field Name");
field2.setType(GeoDataSimpleField::Int);
QCOMPARE( field1, field1 );
QCOMPARE( field2, field2 );
QCOMPARE( field1 != field2, false );
QVERIFY( field1 == field2 );
field2.setType( GeoDataSimpleField::Double );
QCOMPARE( field1, field1 );
QCOMPARE( field2, field2 );
QCOMPARE( field1 == field2, false );
QVERIFY( field1 != field2 );
}
void TestEquality::schemaTest()
{
GeoDataSimpleField field1, field2;
field1.setDisplayName("Simple Field 1");
field1.setName("Field Name 1");
field1.setType(GeoDataSimpleField::Int);
field2.setDisplayName("Simple Field 2");
field2.setName("Field Name 2");
field2.setType(GeoDataSimpleField::Double);
GeoDataSchema schema1, schema2;
schema1.setId( "Some ID" );
schema1.setSchemaName( "Some Name" );
schema1.addSimpleField( field1 );
schema1.addSimpleField( field2 );
schema2.setId( "Some ID" );
schema2.setSchemaName( "Some Name" );
schema2.addSimpleField( field1 );
schema2.addSimpleField( field2 );
QCOMPARE( schema1, schema1 );
QCOMPARE( schema2, schema2 );
QCOMPARE( schema1 != schema2, false );
QVERIFY( schema1 == schema2 );
schema2.setSchemaName( "Changed Name" );
QCOMPARE( schema1, schema1 );
QCOMPARE( schema2, schema2 );
QCOMPARE( schema1 == schema2, false );
QVERIFY( schema1 != schema2 );
}
void TestEquality::scaleTest()
{
GeoDataScale scale1, scale2;
scale1.setX( 1.0 );
scale1.setY( 2.0 );
scale1.setZ( 3.0 );
scale2 = scale1;
scale2.setZ( 3.5 );
QCOMPARE( scale1, scale1 );
QCOMPARE( scale2, scale2 );
QCOMPARE( scale1 == scale2, false );
QVERIFY( scale1 != scale2 );
scale2.setZ( 3.0 );
QVERIFY( scale1 == scale2 );
}
void TestEquality::orientationTest()
{
GeoDataOrientation obj1, obj2;
obj1.setHeading( 90 );
obj1.setTilt( 45 );
obj1.setRoll( -90 );
obj2 = obj1;
obj2.setRoll( -45 );
QCOMPARE( obj1, obj1 );
QCOMPARE( obj2, obj2 );
QCOMPARE( obj1 == obj2, false );
QVERIFY( obj1 != obj2 );
obj2.setRoll( - 90 );
QVERIFY( obj1 == obj2 );
}
void TestEquality::locationTest()
{
GeoDataLocation loc1, loc2;
loc1.setLatitude( M_PI_4, GeoDataCoordinates::Degree );
loc1.setLongitude( M_PI_4, GeoDataCoordinates::Degree );
loc1.setAltitude( 2500.0 );
loc2 = loc1;
loc2.setAltitude( 2000.0 );
QCOMPARE( loc1, loc1 );
QCOMPARE( loc2, loc2 );
QCOMPARE( loc1 == loc2, false );
QVERIFY( loc1 != loc2 );
loc2.setAltitude( 2500.0 );
QVERIFY( loc1 == loc2 );
}
void TestEquality::resourceMapTest()
{
GeoDataResourceMap rMap1, rMap2;
rMap1.setSourceHref( "/path/to/source/href" );
rMap1.setTargetHref( "/path/to/target/href" );
rMap2 = rMap1;
rMap2.setTargetHref( "/path/to/target/href2" );
QCOMPARE( rMap1, rMap1 );
QCOMPARE( rMap2, rMap2 );
QCOMPARE( rMap1 == rMap2, false );
QVERIFY( rMap1 != rMap2 );
rMap2.setTargetHref( "/path/to/target/href" );
QVERIFY( rMap1 == rMap2 );
}
void TestEquality::modelTest()
{
GeoDataModel model1, model2;
GeoDataLink link1, link2;
link1.setHref("some/example/href.something");
link1.setRefreshInterval( 23 );
link1.setRefreshMode( GeoDataLink::OnChange );
link1.setViewBoundScale( 50 );
link1.setViewRefreshTime( 30 );
link2 = link1;
link2.setRefreshMode( GeoDataLink::OnExpire );
model1.setLink( link1 );
model1.setLink( link2 );
GeoDataCoordinates coord1, coord2;
coord1.set(100, 200, 300);
coord2.set(100, 200, 200);
model1.setCoordinates( coord1 );
model2.setCoordinates( coord2 );
GeoDataScale scale1, scale2;
scale1.setX( 1.0 );
scale1.setY( 2.0 );
scale1.setZ( 3.0 );
scale2 = scale1;
scale2.setZ( 3.5 );
model1.setScale( scale1 );
model2.setScale( scale2 );
GeoDataOrientation obj1, obj2;
obj1.setHeading( 90 );
obj1.setTilt( 45 );
obj1.setRoll( -90 );
obj2 = obj1;
obj2.setRoll( -45 );
model1.setOrientation( obj1 );
model2.setOrientation( obj2 );
GeoDataLocation loc1, loc2;
loc1.setLatitude( M_PI_4, GeoDataCoordinates::Degree );
loc1.setLongitude( M_PI_4, GeoDataCoordinates::Degree );
loc1.setAltitude( 2500.0 );
loc2 = loc1;
loc2.setAltitude( 2000.0 );
model1.setLocation( loc1 );
model2.setLocation( loc2 );
GeoDataResourceMap rMap1, rMap2;
rMap1.setSourceHref( "/path/to/source/href" );
rMap1.setTargetHref( "/path/to/target/href" );
rMap2 = rMap1;
rMap2.setTargetHref( "/path/to/target/href2" );
model1.setResourceMap( rMap1 );
model2.setResourceMap( rMap2 );
QCOMPARE( model1, model1 );
QCOMPARE( model2, model2 );
QCOMPARE( model1 == model2, false );
QVERIFY( model1 != model2 );
link2.setRefreshMode( GeoDataLink::OnExpire );
model2.setLink( link2 );
coord2.setAltitude( 300 );
model2.setCoordinates( coord2 );
scale2.setZ( 3.0 );
model2.setScale( scale2 );
obj2.setRoll( -90 );
model2.setOrientation( obj2 );
loc2.setAltitude( 2500.0 );
model2.setLocation( loc2 );
rMap2.setTargetHref( "/path/to/target/href" );
model2.setResourceMap( rMap2 );
QVERIFY( model1 == model2 );
}
void TestEquality::trackTest()
{
GeoDataTrack track1, track2;
QDateTime date11( QDate(2000, 10, 4) ), date12( QDate(2001, 10, 4) );
QDateTime date21( QDate(2002, 10, 4) ), date22( QDate(2003, 10, 4) );
GeoDataCoordinates coord1(100, 100), coord2(200, 300), coord3(300, 300), coord4(400, 400);
GeoDataExtendedData extendedData1, extendedData2;
GeoDataData data1, data2;
data1.setName("Something");
data1.setValue(QVariant(23.56));
data1.setDisplayName("Marble");
data2.setName("Marble");
data2.setValue(QVariant(23.56));
data2.setDisplayName("Globe");
extendedData1.addValue(data1);
extendedData2.addValue(data2);
track1.addPoint(date11, coord1);
track1.addPoint(date12, coord2);
track2.addPoint(date21, coord3);
track2.addPoint(date22, coord4);
track1.setExtendedData(extendedData1);
track2.setExtendedData(extendedData2);
track1.setInterpolate( true );
track2.setInterpolate( true );
QCOMPARE(track1, track1);
QCOMPARE(track2, track2);
QCOMPARE(track1 == track2, false);
QVERIFY(track1 != track2);
track1.clear();
track1.addPoint(date21, coord3);
track1.addPoint(date22, coord4);
track1.setExtendedData(extendedData2);
QVERIFY(track1 == track2);
}
void TestEquality::multiTrackTest()
{
GeoDataMultiTrack multiTrack1, multiTrack2;
GeoDataTrack *track1, *track2, *track3, *track4;
QDateTime date11( QDate(2000, 10, 4) ), date12( QDate(2001, 10, 4) );
QDateTime date21( QDate(2002, 10, 4) ), date22( QDate(2003, 10, 4) );
GeoDataCoordinates coord1(100, 100), coord2(200, 300), coord3(300, 300), coord4(400, 400);
GeoDataExtendedData extendedData1, extendedData2;
GeoDataData data1, data2;
data1.setName("Something");
data1.setValue(QVariant(23.56));
data1.setDisplayName("Marble");
data2.setName("Marble");
data2.setValue(QVariant(23.56));
data2.setDisplayName("Globe");
extendedData1.addValue(data1);
extendedData2.addValue(data2);
track1 = new GeoDataTrack();
track2 = new GeoDataTrack();
track1->addPoint(date11, coord1);
track1->addPoint(date12, coord2);
track2->addPoint(date11, coord1);
track2->addPoint(date12, coord2);
track1->setExtendedData(extendedData1);
track2->setExtendedData(extendedData1);
track1->setInterpolate( true );
track2->setInterpolate( true );
track3 = new GeoDataTrack();
track4 = new GeoDataTrack();
track3->addPoint(date21, coord3);
track3->addPoint(date22, coord4);
track4->addPoint(date21, coord3);
track4->addPoint(date22, coord4);
track3->setExtendedData(extendedData2);
track4->setExtendedData(extendedData2);
track3->setInterpolate( false );
track4->setInterpolate( false );
multiTrack1.append(track1);
multiTrack2.append(track2);
multiTrack1.append(track3);
multiTrack2.append(track4);
QCOMPARE(*track1, *track2);
QCOMPARE(*track3, *track4);
QCOMPARE(multiTrack1, multiTrack1);
QCOMPARE(multiTrack2, multiTrack2);
QCOMPARE(multiTrack1 != multiTrack2, false);
QVERIFY(multiTrack1 == multiTrack2);
}
void TestEquality::snippetTest()
{
GeoDataSnippet snipp1, snipp2;
snipp1.setText( QString("Text1") );
snipp2.setText( QString("Text2") );
snipp1.setMaxLines( 10 );
snipp2.setMaxLines( 666013 );
QCOMPARE( snipp1, snipp1 );
QCOMPARE( snipp2, snipp2 );
QCOMPARE( snipp1 == snipp2, false );
QVERIFY( snipp1 != snipp2 );
snipp1.setText( QString("Text2") );
snipp2.setMaxLines( 10 );
QVERIFY( snipp1 == snipp2 );
}
void TestEquality::lookAtTest()
{
GeoDataLookAt lookAt1, lookAt2;
lookAt1.setLatitude(1.112);
lookAt1.setLongitude(2.33);
lookAt1.setAltitude(1500);
lookAt2 = lookAt1;
GeoDataTimeStamp timeStampBegin, timeStampEnd;
QDateTime date1( QDate(2014, 4, 7) );
timeStampBegin.setWhen( date1 );
timeStampEnd.setWhen( date1 );
timeStampBegin.setResolution( GeoDataTimeStamp::YearResolution );
timeStampEnd.setResolution( GeoDataTimeStamp::YearResolution );
GeoDataTimeSpan timeSpan1, timeSpan2;
timeSpan1.setBegin( timeStampBegin );
timeSpan1.setEnd( timeStampEnd );
timeSpan2 = timeSpan1;
GeoDataTimeStamp timeStamp1, timeStamp2;
QDateTime date2( QDate(2014, 4, 8) );
timeStamp1.setWhen( date2 );
timeStamp2.setWhen( date2 );
timeStamp1.setResolution( GeoDataTimeStamp::SecondResolution );
timeStamp2.setResolution( GeoDataTimeStamp::SecondResolution );
lookAt1.setTimeSpan( timeSpan1 );
lookAt2.setTimeSpan( timeSpan2 );
lookAt1.setTimeStamp( timeStamp1 );
lookAt2.setTimeStamp( timeStamp2 );
lookAt1.setRange( 500 );
lookAt2.setRange( 300 );
QCOMPARE( lookAt1, lookAt1 );
QCOMPARE( lookAt2, lookAt2 );
QCOMPARE( lookAt1 == lookAt2, false );
QVERIFY( lookAt1 != lookAt2 );
lookAt2.setRange( 500 );
QVERIFY( lookAt1 == lookAt2 );
timeStamp1.setResolution( GeoDataTimeStamp::YearResolution );
lookAt1.setTimeStamp( timeStamp1 );
QVERIFY( lookAt1 != lookAt2 );
lookAt2.setTimeStamp( timeStamp1 );
QVERIFY( lookAt1 == lookAt2 );
lookAt2.setAltitude( 2000 );
QVERIFY( lookAt1 != lookAt2 );
}
void TestEquality::networkLinkTest()
{
GeoDataNetworkLink netL1, netL2;
netL1.setRefreshVisibility( true );
netL2.setRefreshVisibility( false );
netL1.setFlyToView( true );
netL2.setFlyToView( false );
GeoDataLink link;
link.setHref(QString("/link/to/something"));
link.setRefreshMode( GeoDataLink::OnExpire );
link.setRefreshInterval( 20.22 );
link.setViewRefreshMode( GeoDataLink::OnRequest );
link.setViewRefreshTime( 3.22 );
link.setViewBoundScale( 1.132 );
link.setViewFormat( QString("Format 1") );
link.setHttpQuery( QString("HttpQueryy1") );
netL1.setLink( link );
netL2.setLink( link );
QCOMPARE( netL1, netL1 );
QCOMPARE( netL2, netL2 );
QCOMPARE( netL1 == netL2, false );
QVERIFY( netL1 != netL2 );
netL1.setName( QString("NetL1") );
netL1.setSnippet( GeoDataSnippet("Textttt", 10) );
netL1.setDescription( QString("Descr1") );
netL1.setDescriptionCDATA( false );
netL1.setAddress( QString("Some address") );
netL1.setPhoneNumber( QString("Some phone number") );
netL1.setStyleUrl( QString("/link/to/style1") );
netL1.setPopularity( 66666 );
netL1.setZoomLevel( 10 );
netL1.setVisible( true );
netL1.setRole( QString("Role1") );
netL2.setName( QString("NetL1") );
netL2.setSnippet( GeoDataSnippet("Textttt", 10) );
netL2.setDescription( QString("Descr1") );
netL2.setDescriptionCDATA( false );
netL2.setAddress( QString("Some address") );
netL2.setPhoneNumber( QString("Some phone number") );
netL2.setStyleUrl( QString("/link/to/style1") );
netL2.setPopularity( 66666 );
netL2.setZoomLevel( 10 );
netL2.setVisible( true );
netL2.setRole( QString("Role1") );
GeoDataLookAt lookAt1, lookAt2;
lookAt1.setAltitudeMode( Marble::ClampToGround );
lookAt1.setAltitude( 100 );
lookAt1.setLatitude( 100 );
lookAt1.setLongitude( 100 );
lookAt1.setRange( 500 );
lookAt2 = lookAt1;
netL1.setAbstractView( &lookAt1 );
netL2.setAbstractView( &lookAt2 );
netL1.setFlyToView( false );
netL2.setRefreshVisibility( true );
QVERIFY( netL1 == netL2 );
}
void TestEquality::networkLinkControlTest()
{
GeoDataNetworkLinkControl netLC1, netLC2;
netLC1.setMinRefreshPeriod( 25 );
netLC1.setMaxSessionLength( 100 );
netLC1.setCookie( QString("Coookiiee") );
netLC1.setMessage( QString("Some message here") );
netLC1.setLinkName( QString("Link name") );
netLC1.setLinkDescription( QString("Some link description here") );
netLC1.setLinkSnippet( QString("Link snippet") );
netLC1.setMaxLines( 100 );
netLC1.setExpires( QDateTime(QDate(2014, 5, 4)) );
netLC2.setMinRefreshPeriod( 25 );
netLC2.setMaxSessionLength( 100 );
netLC2.setCookie( QString("Coookiiee") );
netLC2.setMessage( QString("Some message here") );
netLC2.setLinkName( QString("Link name") );
netLC2.setLinkDescription( QString("Some link description here") );
netLC2.setLinkSnippet( QString("Link snippet") );
netLC2.setMaxLines( 100 );
netLC2.setExpires( QDateTime(QDate(2014, 5, 4)) );
GeoDataUpdate update;
update.setTargetHref( QString("Target href") );
netLC1.setUpdate( update );
netLC2.setUpdate( update );
GeoDataCamera *camera1 = new GeoDataCamera;
GeoDataCamera *camera2 = new GeoDataCamera;
camera1->setAltitudeMode( Marble::ClampToGround );
camera1->setAltitude( 2000 );
camera1->setLatitude( 2.555 );
camera1->setLongitude( 1.32 );
camera1->setHeading( 200 );
camera1->setRoll( 300 );
camera1->setTilt( 400 );
*camera2 = *camera1;
netLC1.setAbstractView( camera1 );
netLC2.setAbstractView( camera2 );
QVERIFY( netLC1 == netLC2 );
camera2->setAltitudeMode( Marble::Absolute );
QVERIFY( netLC1 != netLC2 );
camera1->setAltitudeMode( Marble::Absolute );
QVERIFY( netLC1 == netLC2 );
netLC1.setMaxLines( 50 );
QVERIFY( netLC1 != netLC2 );
- netLC1.setStyleMap(0);
- netLC2.setStyleMap(0);
+ netLC1.setStyleMap(nullptr);
+ netLC2.setStyleMap(nullptr);
GeoDataStyleMap styleMap1, styleMap2;
styleMap1["germany"] = "gst1";
styleMap1["germany"] = "gst2";
styleMap1["germany"] = "gst3";
styleMap1["poland"] = "pst1";
styleMap1["poland"] = "pst2";
styleMap1["poland"] = "pst3";
styleMap1.setLastKey("poland");
styleMap2["germany"] = "gst1";
styleMap2["germany"] = "gst2";
styleMap2["germany"] = "gst3";
styleMap2["poland"] = "pst1";
styleMap2["poland"] = "pst2";
styleMap2["poland"] = "pst3";
styleMap2.setLastKey("romania");
netLC2.setMaxLines( 50 );
netLC1.setStyleMap( &styleMap1 );
netLC2.setStyleMap( &styleMap2 );
QVERIFY( netLC1 != netLC2 );
styleMap1.setLastKey("romania");
QVERIFY( netLC1 == netLC2 );
}
void TestEquality::folderTest()
{
GeoDataFolder folder1, folder2;
GeoDataGroundOverlay *overlay11, *overlay12, *overlay21, *overlay22;
GeoDataLatLonBox latLonBox1, latLonBox2;
overlay11 = new GeoDataGroundOverlay;
overlay12 = new GeoDataGroundOverlay;
overlay21 = new GeoDataGroundOverlay;
overlay22 = new GeoDataGroundOverlay;
latLonBox1.setEast( 33 );
latLonBox1.setWest( 52 );
latLonBox1.setNorth( 61 );
latLonBox1.setSouth( 72 );
latLonBox1.setRotation( 51 );
latLonBox1.setBoundaries( 23, 54, 33, 21 );
latLonBox2.setEast( 40 );
latLonBox2.setWest( 50 );
latLonBox2.setNorth( 60 );
latLonBox2.setSouth( 70 );
latLonBox2.setRotation( 20 );
latLonBox2.setBoundaries( 70, 80, 50, 60 );
overlay11->setLatLonBox( latLonBox1 );
overlay12->setLatLonBox( latLonBox2 );
GeoDataLatLonQuad quad1, quad2;
quad1.setBottomLeftLatitude( 1.23, GeoDataCoordinates::Radian );
quad1.setBottomLeftLongitude( 2.60, GeoDataCoordinates::Radian );
quad1.setBottomRightLatitude( 0.45, GeoDataCoordinates::Radian );
quad1.setBottomRightLongitude( 1.260, GeoDataCoordinates::Radian );
quad1.setTopLeftLatitude( 2.55, GeoDataCoordinates::Radian );
quad1.setTopLeftLongitude( 1.65, GeoDataCoordinates::Radian );
quad1.setTopRightLatitude( 1.245, GeoDataCoordinates::Radian );
quad1.setTopRightLongitude( 1.350, GeoDataCoordinates::Radian );
quad2.setBottomLeftLatitude( 55, GeoDataCoordinates::Degree );
quad2.setBottomLeftLongitude( 60, GeoDataCoordinates::Degree );
quad2.setBottomRightLatitude( 45, GeoDataCoordinates::Degree );
quad2.setBottomRightLongitude( 50, GeoDataCoordinates::Degree );
quad2.setTopLeftLatitude( 55, GeoDataCoordinates::Degree );
quad2.setTopLeftLongitude( 60, GeoDataCoordinates::Degree );
quad2.setTopRightLatitude( 45, GeoDataCoordinates::Degree );
quad2.setTopRightLongitude( 50, GeoDataCoordinates::Degree );
overlay11->setLatLonQuad( quad1 );
overlay12->setLatLonQuad( quad2 );
overlay11->setAltitude( 23.5 );
overlay12->setAltitude( 23.5 );
overlay11->setAltitudeMode( Marble::Absolute );
overlay12->setAltitudeMode( Marble::Absolute );
*overlay21 = *overlay11;
*overlay22 = *overlay12;
folder1.append( overlay11 );
folder1.append( overlay12 );
folder2.append( overlay21 );
folder2.append( overlay22 );
QCOMPARE( folder1, folder1 );
QCOMPARE( folder2, folder2 );
QCOMPARE( folder1 != folder2, false );
QVERIFY( folder1 == folder2 );
}
void TestEquality::simpleDataTest()
{
GeoDataSimpleData simpleData1, simpleData2;
simpleData1.setName( "height" );
simpleData1.setData( "4.65" );
simpleData2.setName( "height" );
simpleData2.setData( "4.65" );
QCOMPARE( simpleData1, simpleData1 );
QCOMPARE( simpleData2, simpleData2 );
QCOMPARE( simpleData1 != simpleData2, false );
QVERIFY( simpleData1 == simpleData2 );
simpleData2.setData( "7.45" );
QCOMPARE( simpleData1, simpleData1 );
QCOMPARE( simpleData2, simpleData2 );
QCOMPARE( simpleData1 == simpleData2, false );
QVERIFY( simpleData1 != simpleData2 );
}
void TestEquality::schemaDataTest()
{
GeoDataSimpleData simpleData1, simpleData2;
simpleData1.setName( "width" );
simpleData1.setData( "6.24" );
simpleData2.setName( "width" );
simpleData2.setData( "6.24" );
GeoDataSchemaData schemaData1, schemaData2;
schemaData1.setSchemaUrl( "dimensions" );
schemaData1.addSimpleData( simpleData1 );
schemaData1.addSimpleData( simpleData2 );
schemaData2.setSchemaUrl( "dimensions" );
schemaData2.addSimpleData( simpleData1 );
schemaData2.addSimpleData( simpleData2 );
QCOMPARE( schemaData1, schemaData1 );
QCOMPARE( schemaData2, schemaData2 );
QCOMPARE( schemaData1 != schemaData2, false );
QVERIFY( schemaData1 == schemaData2 );
schemaData2.setSchemaUrl( "some other id" );
QCOMPARE( schemaData1, schemaData1 );
QCOMPARE( schemaData2, schemaData2 );
QCOMPARE( schemaData1 == schemaData2, false );
QVERIFY( schemaData1 != schemaData2 );
}
QTEST_MAIN( TestEquality )
#include "TestEquality.moc"
diff --git a/tests/TestGeoData.cpp b/tests/TestGeoData.cpp
index 4dce689e3..a86ea952e 100644
--- a/tests/TestGeoData.cpp
+++ b/tests/TestGeoData.cpp
@@ -1,137 +1,137 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Bastian Holst <bastianholst@gmx.de>
//
#include <QTest>
#include <QDebug>
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataPlacemark.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataTypes.h"
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataStyleMap.h"
#include "MarbleDebug.h"
namespace Marble
{
class TestGeoData : public QObject
{
Q_OBJECT
private Q_SLOTS:
void nodeTypeTest();
void parentingTest();
};
/// test the nodeType function through various construction tests
void TestGeoData::nodeTypeTest()
{
/// basic testing of nodeType
GeoDataFolder *folder = new GeoDataFolder;
const char* folderType = GeoDataTypes::GeoDataFolderType;
QCOMPARE( folder->nodeType(), folderType );
/// testing the nodeType of an object appended to a container
GeoDataDocument document;
document.append( folder );
GeoDataFeature &featureRef = document.last();
QVERIFY(geodata_cast<GeoDataFolder>(&featureRef));
}
void TestGeoData::parentingTest()
{
GeoDataDocument *document = new GeoDataDocument;
GeoDataFolder *folder = new GeoDataFolder;
/// simple parenting test
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setParent(document);
QCOMPARE(placemark->parent(), document);
/// simple append and child count test
document->append(placemark);
/// appending folder to document before feeding folder
document->append(folder);
QCOMPARE(document->size(), 2);
GeoDataPlacemark *placemark2 = new GeoDataPlacemark;
folder->append(placemark2);
QCOMPARE(folder->size(), 1);
/// retrieve child and check it matches placemark
GeoDataPlacemark *placemarkPtr;
QVERIFY(geodata_cast<GeoDataPlacemark>(document->child(0)));
placemarkPtr = static_cast<GeoDataPlacemark*>(document->child(0));
QCOMPARE(placemarkPtr, placemark);
/// check retrieved placemark matches intented child
int position = document->childPosition(placemarkPtr);
QCOMPARE(position, 0);
/// retrieve child two and check it matches folder
GeoDataFolder *folderPtr;
QVERIFY(geodata_cast<GeoDataFolder>(document->child(1)));
folderPtr = static_cast<GeoDataFolder*>(document->child(1));
QCOMPARE(folderPtr, folder);
/// check retrieved folder matches intended child
position = document->childPosition(folderPtr);
QCOMPARE(position, 1);
/// retrieve child three and check it matches placemark
QCOMPARE(folderPtr->size(), 1);
placemarkPtr = static_cast<GeoDataPlacemark*>(folderPtr->child(0));
QCOMPARE(placemarkPtr->nodeType(), placemark2->nodeType());
QCOMPARE(placemarkPtr, placemark2);
/// check retrieved placemark matches intended child
QCOMPARE(folderPtr->childPosition(placemarkPtr), 0);
/// Set a style
GeoDataIconStyle iconStyle;
iconStyle.setIconPath( "myicon.png" );
GeoDataStyle::Ptr style(new GeoDataStyle);
style->setId( "mystyle" );
style->setIconStyle( iconStyle );
- GeoDataObject* noParent = 0;
+ GeoDataObject* noParent = nullptr;
QCOMPARE( style->parent(), noParent );
QCOMPARE( iconStyle.parent(), noParent );
document->setStyle( style );
QCOMPARE( style->parent(), document ); // Parent should be assigned now
QCOMPARE( style->iconStyle().parent(), style.data() );
QCOMPARE( iconStyle.parent(), noParent ); // setIconStyle copies
QCOMPARE( placemark->style()->parent(), noParent );
placemark->setStyle( style );
QCOMPARE( placemark->style()->parent(), placemark ); // Parent should be assigned now
/// Set a style map
GeoDataStyleMap* styleMap = new GeoDataStyleMap;
styleMap->setId( "mystylemap" );
styleMap->insert( "normal", "#mystyle" );
styleMap->insert( "highlight", "#mystyle" );
document->addStyle( style );
document->setStyleMap( styleMap );
QCOMPARE( placemark2->style()->parent(), noParent );
placemark2->setStyleUrl( "#mystyle" );
QCOMPARE( placemark2->style()->parent(), document ); // Parent is document, not placemark2
QCOMPARE( iconStyle.iconPath(), QString( "myicon.png" ) );
QCOMPARE( placemark2->style()->iconStyle().iconPath(), QString( "myicon.png" ) );
}
}
QTEST_MAIN( Marble::TestGeoData )
#include "TestGeoData.moc"
diff --git a/tests/TestGeoDataCoordinates.cpp b/tests/TestGeoDataCoordinates.cpp
index 22d87f38f..b363c94a2 100644
--- a/tests/TestGeoDataCoordinates.cpp
+++ b/tests/TestGeoDataCoordinates.cpp
@@ -1,1926 +1,1926 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
// Copyright 2010 Matias Kallio <matias.kallio@gmail.com>
// Copyright 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
// Copyright 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
#include "MarbleGlobal.h"
#include "MarbleWidget.h"
#include "GeoDataCoordinates.h"
#include "TestUtils.h"
#include <QLocale>
#include <QDebug>
#include <QTranslator>
#include <QTemporaryFile>
using namespace Marble;
class TestGeoDataCoordinates : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void testConstruction();
void testSet_Degree();
void testSet_Radian();
void testSetLongitude_Degree();
void testSetLongitude_Radian();
void testSetLatitude_Degree();
void testSetLatitude_Radian();
void testAltitude();
void testOperatorAssignment();
void testDetail();
void testIsPole_data();
void testIsPole();
void testNotation();
void testNormalizeLat_data();
void testNormalizeLat();
void testNormalizeLon_data();
void testNormalizeLon();
void testNormalize_data();
void testNormalize();
void testFromStringDMS_data();
void testFromStringDMS();
void testFromStringDM_data();
void testFromStringDM();
void testFromStringD_data();
void testFromStringD();
void testFromLocaleString_data();
void testFromLocaleString();
void testToString_Decimal_data();
void testToString_Decimal();
void testToString_DMS_data();
void testToString_DMS();
void testToString_DM_data();
void testToString_DM();
void testPack_data();
void testPack();
void testUTM_data();
void testUTM();
};
void TestGeoDataCoordinates::initTestCase()
{
QLocale::setDefault( QLocale::c() ); // needed for testing toString* conversions
QTime time = QTime::currentTime();
qsrand((uint)time.msec());
}
/*
* test constructors
*/
void TestGeoDataCoordinates::testConstruction()
{
GeoDataCoordinates invalid1;
QVERIFY(!invalid1.isValid());
GeoDataCoordinates invalid2(invalid1);
QVERIFY(!invalid2.isValid());
QVERIFY(!invalid1.isValid());
QCOMPARE(invalid1, invalid2);
const qreal lon = 164.77;
const qreal lat = 55.9;
const qreal alt = 400.003;
GeoDataCoordinates coordinates3(lon, lat, alt, GeoDataCoordinates::Degree);
QVERIFY(coordinates3.isValid());
QCOMPARE(coordinates3, GeoDataCoordinates(lon, lat, alt, GeoDataCoordinates::Degree));
QVERIFY(coordinates3 != invalid1);
QVERIFY(coordinates3 != invalid2);
QCOMPARE(coordinates3.longitude(GeoDataCoordinates::Degree), lon);
QCOMPARE(coordinates3.longitude(), lon*DEG2RAD);
QCOMPARE(coordinates3.latitude(GeoDataCoordinates::Degree), lat);
QCOMPARE(coordinates3.latitude(), lat*DEG2RAD);
QCOMPARE(coordinates3.altitude(), alt);
qreal myLongitude = 0;
qreal myLatitude = 0;
coordinates3.geoCoordinates(myLongitude, myLatitude, GeoDataCoordinates::Degree);
QCOMPARE(myLongitude, lon);
QCOMPARE(myLatitude, lat);
myLongitude = 0;
myLatitude = 0;
coordinates3.geoCoordinates(myLongitude, myLatitude);
QCOMPARE(myLongitude, lon*DEG2RAD);
QCOMPARE(myLatitude, lat*DEG2RAD);
GeoDataCoordinates coordinates4(lon*DEG2RAD, lat*DEG2RAD, alt);
QVERIFY(coordinates4.isValid());
QCOMPARE(coordinates4, GeoDataCoordinates(lon, lat, alt, GeoDataCoordinates::Degree));
QCOMPARE(coordinates4, coordinates3);
QVERIFY(coordinates4 != invalid1);
QVERIFY(coordinates4 != invalid2);
GeoDataCoordinates coordinates5(coordinates3);
QVERIFY(coordinates5.isValid());
QCOMPARE(coordinates5, GeoDataCoordinates(lon, lat, alt, GeoDataCoordinates::Degree));
QCOMPARE(coordinates5, coordinates3);
QCOMPARE(coordinates5, coordinates4);
QVERIFY(coordinates5 != invalid1);
QVERIFY(coordinates5 != invalid2);
GeoDataCoordinates coordinates6(invalid1.longitude(), invalid1.latitude(), invalid1.altitude(), GeoDataCoordinates::Radian, invalid1.detail());
QVERIFY(coordinates6.isValid()); // it should be valid, even though
QCOMPARE(coordinates6, invalid1); // it is equal to an invalid one
}
/*
* test setting coordinates in degree
*/
void TestGeoDataCoordinates::testSet_Degree()
{
const qreal lon = 345.8;
const qreal lat = 70.3;
const qreal alt = 1000.9;
GeoDataCoordinates coordinates1; // invalid
coordinates1.set(lon, lat, alt, GeoDataCoordinates::Degree);
QVERIFY(coordinates1.isValid());
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.set(0, 0, 0, GeoDataCoordinates::Degree);
QVERIFY(coordinates2.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(lon, lat, alt, GeoDataCoordinates::Degree));
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0, 0, GeoDataCoordinates::Degree));
}
/*
* test setting coordinates in radian
*/
void TestGeoDataCoordinates::testSet_Radian()
{
const qreal lon = 1.3;
const qreal lat = 0.7;
const qreal alt = 6886.44;
GeoDataCoordinates coordinates1; // invalid
coordinates1.set(lon, lat, alt);
QVERIFY(coordinates1.isValid());
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.set(0, 0, 0);
QVERIFY(coordinates2.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(lon, lat, alt));
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0, 0));
}
/*
* test setLongitude() in degree
*/
void TestGeoDataCoordinates::testSetLongitude_Degree()
{
const qreal lon = 143.8;
GeoDataCoordinates coordinates1; // invalid
coordinates1.setLongitude(lon, GeoDataCoordinates::Degree);
QVERIFY(coordinates1.isValid());
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.setLongitude(0, GeoDataCoordinates::Degree);
QVERIFY(coordinates2.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(lon, 0, 0, GeoDataCoordinates::Degree));
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0, 0, GeoDataCoordinates::Degree));
}
/*
* test setLongitude() in radian
*/
void TestGeoDataCoordinates::testSetLongitude_Radian()
{
const qreal lon = 2.5;
GeoDataCoordinates coordinates1; // invalid
coordinates1.setLongitude(lon);
QVERIFY(coordinates1.isValid());
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.setLongitude(0);
QVERIFY(coordinates2.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(lon, 0));
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0));
}
/*
* test setLatitude() and latitude() in degree
*/
void TestGeoDataCoordinates::testSetLatitude_Degree()
{
const qreal lat = 75.0;
GeoDataCoordinates coordinates1; // invalid
coordinates1.setLatitude(lat, GeoDataCoordinates::Degree);
QVERIFY(coordinates1.isValid());
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.setLatitude(0, GeoDataCoordinates::Degree);
QVERIFY(coordinates2.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(0, lat, 0, GeoDataCoordinates::Degree));
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0, 0, GeoDataCoordinates::Degree));
}
/*
* test setLatitude() in radian
*/
void TestGeoDataCoordinates::testSetLatitude_Radian()
{
const qreal lat = 1.2;
GeoDataCoordinates coordinates1; // invalid
coordinates1.setLatitude(lat);
QVERIFY(coordinates1.isValid());
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.setLatitude(0);
QVERIFY(coordinates2.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(0, lat));
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0));
}
/*
* test setAltitude()
*/
void TestGeoDataCoordinates::testAltitude()
{
const qreal alt = 400;
GeoDataCoordinates coordinates1; // invalid
coordinates1.setAltitude(alt);
QVERIFY(coordinates1.isValid());
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.setAltitude(0);
QVERIFY(coordinates2.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(0, 0, alt));
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0, 0));
}
void TestGeoDataCoordinates::testOperatorAssignment()
{
const qreal lon = 123.4;
const qreal lat = 56.7;
const qreal alt = 890.1;
const GeoDataCoordinates coordinates1(lon, lat, alt, GeoDataCoordinates::Degree);
const GeoDataCoordinates coordinates2(0, 0, 0);
GeoDataCoordinates coordinates3; // invalid
coordinates3 = coordinates1;
QVERIFY(coordinates3.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(lon, lat, alt, GeoDataCoordinates::Degree)); // stays unmodified
QCOMPARE(coordinates3, coordinates1);
coordinates3 = GeoDataCoordinates();
QVERIFY(!coordinates3.isValid());
GeoDataCoordinates coordinates4(coordinates1);
coordinates4 = coordinates2;
QVERIFY(coordinates4.isValid());
QCOMPARE(coordinates1, GeoDataCoordinates(lon, lat, alt, GeoDataCoordinates::Degree)); // stays unmodified
QCOMPARE(coordinates2, GeoDataCoordinates(0, 0, 0)); // stays unmodified
QCOMPARE(coordinates4, coordinates2);
}
/*
* test setDetail() and detail()
*/
void TestGeoDataCoordinates::testDetail()
{
const quint8 detailnumber = 15;
GeoDataCoordinates coordinates1;
coordinates1.setDetail(detailnumber);
GeoDataCoordinates coordinates2(coordinates1);
coordinates2.setDetail(0);
QCOMPARE(coordinates1.detail(), detailnumber);
}
/*
* test setDefaultNotation() and defaultNotation
*/
void TestGeoDataCoordinates::testNotation()
{
GeoDataCoordinates::setDefaultNotation(GeoDataCoordinates::Decimal);
QVERIFY(GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::Decimal);
GeoDataCoordinates::setDefaultNotation(GeoDataCoordinates::DMS);
QVERIFY(GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::DMS);
}
/*
* test data for testIsPole()
*/
void TestGeoDataCoordinates::testIsPole_data()
{
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
QTest::addColumn<qreal>("alt");
QTest::addColumn<QString>("pole");
QTest::newRow("false") << qreal(50.0) << qreal(50.0) << qreal(0.0) << "false_pole";
QTest::newRow("south") << qreal(0.0) << qreal(-90.0) << qreal(0.0) << "south_pole";
QTest::newRow("north") << qreal(0.0) << qreal(90.0) << qreal(0.0) << "north_pole";
}
/*
* Test isPole-method
*/
void TestGeoDataCoordinates::testIsPole()
{
QFETCH(qreal, lon);
QFETCH(qreal, lat);
QFETCH(qreal, alt);
QFETCH(QString, pole);
GeoDataCoordinates coordinates1;
if (pole == QLatin1String("false_pole")) {
coordinates1.set(lon, lat, alt, GeoDataCoordinates::Degree);
QVERIFY(coordinates1.isPole() == false);
} else if (pole == QLatin1String("south_pole")) {
coordinates1.set(lon, lat, alt, GeoDataCoordinates::Degree);
QVERIFY(coordinates1.isPole(SouthPole));
} else if (pole == QLatin1String("north_pole")) {
coordinates1.set(lon, lat, alt, GeoDataCoordinates::Degree);
QVERIFY(coordinates1.isPole(NorthPole));
}
}
void TestGeoDataCoordinates::testNormalizeLat_data()
{
QTest::addColumn<qreal>( "latRadian" );
QTest::newRow( "north pole" ) << qreal(M_PI / 2);
QTest::newRow( "south pole" ) << qreal(- M_PI / 2);
QTest::newRow( "somewhere" ) << qreal(1.0);
}
void TestGeoDataCoordinates::testNormalizeLat()
{
QFETCH( qreal, latRadian );
qreal latDegree = RAD2DEG * latRadian;
for ( int i = 1; i < 10; ++i ) {
if ( ( i % 2 ) == 0 ) {
QCOMPARE( GeoDataCoordinates::normalizeLat( latRadian + i * M_PI, GeoDataCoordinates::Radian ), latRadian );
QCOMPARE( GeoDataCoordinates::normalizeLat( latRadian + i * M_PI ), latRadian );
QCOMPARE( GeoDataCoordinates::normalizeLat( latDegree + i * 180, GeoDataCoordinates::Degree ), latDegree );
}
else {
QCOMPARE( GeoDataCoordinates::normalizeLat( latRadian + i * M_PI, GeoDataCoordinates::Radian ), -latRadian );
QCOMPARE( GeoDataCoordinates::normalizeLat( latRadian + i * M_PI ), -latRadian );
QCOMPARE( GeoDataCoordinates::normalizeLat( latDegree + i * 180, GeoDataCoordinates::Degree ), -latDegree );
}
}
}
void TestGeoDataCoordinates::testNormalizeLon_data()
{
QTest::addColumn<qreal>( "lonRadian" );
QTest::newRow( "half east" ) << qreal(M_PI / 2);
QTest::newRow( "half west" ) << qreal(- M_PI / 2);
QTest::newRow( "somewhere" ) << qreal(1.0);
QTest::newRow( "date line east" ) << qreal(M_PI);
QTest::newRow( "date line west" ) << - qreal(M_PI);
}
void TestGeoDataCoordinates::testNormalizeLon()
{
QFETCH( qreal, lonRadian );
qreal lonDegree = RAD2DEG * lonRadian;
for ( int i = 1; i < 10; ++i ) {
if ( lonRadian == qreal(M_PI) || lonRadian == qreal(-M_PI) ) {
int lonRadianLarge = qRound( lonRadian * 1000 );
int lonDegreeLarge = qRound( lonDegree * 1000 );
if ( qRound( GeoDataCoordinates::normalizeLon( lonRadian + i * 2 * M_PI ) * 1000 ) != lonRadianLarge
&& qRound( GeoDataCoordinates::normalizeLon( lonRadian + i * 2 * M_PI ) * 1000 ) != -lonRadianLarge )
{
QFAIL( "Error at M_PI/-M_PI" );
}
if ( qRound( GeoDataCoordinates::normalizeLon( lonRadian + i * 2 * M_PI, GeoDataCoordinates::Radian ) * 1000 ) != lonRadianLarge
&& qRound( GeoDataCoordinates::normalizeLon( lonRadian + i * 2 * M_PI, GeoDataCoordinates::Radian ) * 1000 ) != -lonRadianLarge )
{
QFAIL( "Error at M_PI/-M_PI" );
}
if ( qRound( GeoDataCoordinates::normalizeLon( lonDegree + i * 360, GeoDataCoordinates::Degree ) * 1000 ) != lonDegreeLarge
&& qRound( GeoDataCoordinates::normalizeLon( lonDegree + i * 360, GeoDataCoordinates::Degree ) * 1000 ) != -lonDegreeLarge )
{
QFAIL( "Error at M_PI/-M_PI" );
}
}
else {
QCOMPARE( GeoDataCoordinates::normalizeLon( lonRadian + i * 2 * M_PI, GeoDataCoordinates::Radian ), lonRadian );
QCOMPARE( GeoDataCoordinates::normalizeLon( lonRadian + i * 2 * M_PI ), lonRadian );
QCOMPARE( GeoDataCoordinates::normalizeLon( lonDegree + i * 360, GeoDataCoordinates::Degree ), lonDegree );
}
}
}
/*
* test data for testNormalize()
*/
void TestGeoDataCoordinates::testNormalize_data()
{
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
QTest::addColumn<QString>("unit");
QTest::newRow("deg") << qreal(200.0) << qreal(130.0) << "degree";
QTest::newRow("rad") << qreal(3.6) << qreal(2.7) << "radian";
}
/*
* test normalizeLon(), normalizeLat() and normalizeLonLat()
*/
void TestGeoDataCoordinates::testNormalize()
{
QFETCH(qreal, lon);
QFETCH(qreal, lat);
QFETCH(QString, unit);
if (unit == QLatin1String("degree")) {
QCOMPARE(GeoDataCoordinates::normalizeLon(lon, GeoDataCoordinates::Degree), qreal(-160));
QCOMPARE(GeoDataCoordinates::normalizeLat(lat, GeoDataCoordinates::Degree), qreal(50));
qreal normalized_lon = lon;
qreal normalized_lat = lat;
GeoDataCoordinates::normalizeLonLat( normalized_lon, normalized_lat, GeoDataCoordinates::Degree);
QCOMPARE(normalized_lon, qreal(20));
QCOMPARE(normalized_lat, qreal(50));
} else if (unit == QLatin1String("radian")) {
// Compare up to three decimals
qreal value = GeoDataCoordinates::normalizeLon(lon, GeoDataCoordinates::Radian);
QCOMPARE(ceil(value * 1000) / 1000, qreal(-2.683));
value = GeoDataCoordinates::normalizeLat(lat, GeoDataCoordinates::Radian);
QCOMPARE(ceil(value * 1000) / 1000, qreal(0.442));
qreal normalized_lon = lon;
qreal normalized_lat = lat;
GeoDataCoordinates::normalizeLonLat( normalized_lon, normalized_lat, GeoDataCoordinates::Radian);
QCOMPARE(ceil(normalized_lon * 1000) / 1000, qreal(0.459));
QCOMPARE(ceil(normalized_lat * 1000) / 1000, qreal(0.442));
}
}
enum SignType {NoSign, PositiveSign, NegativeSign};
enum SphereType {PosSphere, NegSphere};
enum UnitsType {NoUnits, WithUnits};
enum SpacesType {NoSpaces, WithSpaces};
enum LocaleType {CLocale, SystemLocale};
static QString
createDegreeString(SignType signType,
int degreeValue, int minutesValue, qreal secondsValue,
LocaleType locale,
UnitsType unitsType, SpacesType spacesType)
{
QString string;
// add degree
if (signType != NoSign) string.append(QLatin1Char(signType==PositiveSign?'+':'-'));
string.append(QString::number(degreeValue));
if (unitsType == WithUnits) string.append(QChar(0xb0));
// add minutes
string.append(QLatin1Char(' ') + QString::number(minutesValue));
if (unitsType == WithUnits) string.append(QLatin1Char('\''));
// add seconds
if (locale == CLocale) {
string.append(QLatin1Char(' ') + QString::number(secondsValue, 'f', 10));
} else {
string.append(QLatin1Char(' ') + QLocale::system().toString(secondsValue, 'f', 10));
}
if (unitsType == WithUnits) string.append(QLatin1Char('"'));
if (spacesType == WithSpaces) string.append(QLatin1Char(' '));
return string;
}
static QString
createDegreeString(SignType signType,
int degreeValue, qreal minutesValue,
LocaleType locale,
UnitsType unitsType, SpacesType spacesType)
{
QString string;
// add degree
if (signType != NoSign) string.append(QLatin1Char(signType==PositiveSign?'+':'-'));
string.append(QString::number(degreeValue));
if (unitsType == WithUnits) string.append(QChar(0xb0));
// add minutes
if (locale == CLocale) {
string.append(QLatin1Char(' ') + QString::number(minutesValue, 'f', 10));
} else {
string.append(QLatin1Char(' ') + QLocale::system().toString(minutesValue, 'f', 10));
}
if (unitsType == WithUnits) string.append(QLatin1Char('\''));
if (spacesType == WithSpaces) string.append(QLatin1Char(' '));
return string;
}
static QString
createDegreeString(SignType signType,
qreal degreeValue,
LocaleType locale,
UnitsType unitsType, SpacesType spacesType)
{
QString string;
// add degree
if (signType != NoSign) string.append(QLatin1Char(signType==PositiveSign?'+':'-'));
if (locale == CLocale) {
string.append(QString::number(degreeValue, 'f', 10));
} else {
string.append(QLocale::system().toString(degreeValue, 'f', 10));
}
if (unitsType == WithUnits) string.append(QChar(0xb0));
if (spacesType == WithSpaces) string.append(QLatin1Char(' '));
return string;
}
/*
* test data for testStringDMS()
*/
void TestGeoDataCoordinates::testFromStringDMS_data()
{
QTest::addColumn<QString>("string");
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
const QVector<SignType> signTypes = QVector<SignType>()
<< NoSign << PositiveSign << NegativeSign;
const QVector<SphereType> sphereTypes = QVector<SphereType>()
<< PosSphere << NegSphere;
const QVector<UnitsType> unitsTypes = QVector<UnitsType>()
<< NoUnits << WithUnits;
const QVector<SpacesType> spacesTypes = QVector<SpacesType>()
<< NoSpaces << WithSpaces;
const QVector<LocaleType> localeTypes = QVector<LocaleType>()
<< CLocale << SystemLocale;
const QVector<uint> degreeSamples = QVector<uint>()
<< 0 << 140 << 180;
const QVector<uint> minutesSamples = QVector<uint>()
<< 0 << 23 << 59;
const QVector<qreal> secondsSamples = QVector<qreal>()
<< 0.0 << 3.14159 << 59.9999999;
foreach(const UnitsType unitsType, unitsTypes) {
foreach(const SpacesType spacesType, spacesTypes) {
// lon
foreach(const SphereType lonSphere, sphereTypes) {
foreach(const SignType lonSignType, signTypes) {
const bool lonIsPositive =
(lonSphere==PosSphere && lonSignType!=NegativeSign) ||
(lonSphere==NegSphere && lonSignType==NegativeSign);
foreach(const uint lonDegree, degreeSamples) {
foreach(const uint lonMinutes, minutesSamples) {
if(lonDegree == 180 && lonMinutes != 0) continue;
foreach(const qreal lonSeconds, secondsSamples) {
if(lonDegree == 180 && lonSeconds != 0.0) continue;
// lat
foreach(const SphereType latSphere, sphereTypes) {
foreach(const SignType latSignType, signTypes) {
const bool latIsPositive =
(latSphere==PosSphere && latSignType!=NegativeSign) ||
(latSphere==NegSphere && latSignType==NegativeSign);
foreach(const uint latDegree, degreeSamples) {
foreach(const uint latMinutes, minutesSamples) {
if(latDegree == 180 && latMinutes != 0) continue;
foreach(const qreal latSeconds, secondsSamples) {
if(latDegree == 180 && latSeconds != 0.0) continue;
// locale
foreach(const LocaleType locale, localeTypes) {
// actual construction
// Create lon & lat values
qreal lon = (qreal)lonDegree + lonMinutes*MIN2HOUR + lonSeconds*SEC2HOUR;
if( ! lonIsPositive )
lon *= -1;
qreal lat = (qreal)latDegree + latMinutes*MIN2HOUR + latSeconds*SEC2HOUR;
if( ! latIsPositive )
lat *= -1;
// Create string
QString string;
string.append(createDegreeString(latSignType,
latDegree, latMinutes, latSeconds,
locale,
unitsType, spacesType));
string.append(QLatin1Char(latSphere==PosSphere?'N':'S'));
string.append(QLatin1Char(' '));
string.append(createDegreeString(lonSignType,
lonDegree, lonMinutes, lonSeconds,
locale,
unitsType, spacesType));
string.append(QLatin1Char(lonSphere==PosSphere?'E':'W'));
// Create row title
QString rowTitle;
rowTitle.append(QLatin1String(spacesType==WithSpaces?"spaced dir":"unspaced dir"))
.append(QLatin1String(unitsType==WithUnits?"|units":"|no units"))
.append(QLatin1String("|lon:"))
.append(QLatin1Char(lonIsPositive?'+':'-'))
.append(QString::number(lonDegree)+QChar(0xb0))
.append(QString::number(lonMinutes)+QLatin1Char('\''))
.append(QString::number(lonSeconds, 'f', 10)+QLatin1Char('"'))
.append(QLatin1Char(lonSphere==PosSphere?'P':'N'))
.append(QLatin1String("|lat:"))
.append(QLatin1Char(latIsPositive?'+':'-'))
.append(QString::number(latDegree)+QChar(0xb0))
.append(QString::number(latMinutes)+QLatin1Char('\''))
.append(QString::number(latSeconds, 'f', 10)+QLatin1Char('"'))
.append(QLatin1Char(latSphere==PosSphere?'P':'N'))
.append(QLatin1Char('|')).append(QLatin1Char(locale==CLocale?'C':'L'))
.append(QLatin1Char('|')).append(string).append(QLatin1Char('|'));
QTest::newRow(rowTitle.toLatin1().constData())
<< string
<< lon
<< lat;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
/*
* test fromString() with DMS notation
*/
void TestGeoDataCoordinates::testFromStringDMS()
{
// only run random 5% of all possible permutations
if ((qreal(qrand()) / RAND_MAX) > 0.05) {
QSKIP("Not picked for this run.");
}
QFETCH(QString, string);
QFETCH(qreal, lon);
QFETCH(qreal, lat);
bool succeeded = false;
const GeoDataCoordinates coords = GeoDataCoordinates::fromString(string, succeeded);
if(! succeeded)
qWarning() << "Could not parse"<<string <<"for"<<lon<<lat;
QVERIFY(succeeded);
QCOMPARE(coords.longitude(GeoDataCoordinates::Degree), lon);
QCOMPARE(coords.latitude(GeoDataCoordinates::Degree), lat);
}
/*
* test data for testStringDM()
*/
void TestGeoDataCoordinates::testFromStringDM_data()
{
QTest::addColumn<QString>("string");
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
const QVector<SignType> signTypes = QVector<SignType>()
<< NoSign << PositiveSign << NegativeSign;
const QVector<SphereType> sphereTypes = QVector<SphereType>()
<< PosSphere << NegSphere;
const QVector<UnitsType> unitsTypes = QVector<UnitsType>()
<< NoUnits << WithUnits;
const QVector<SpacesType> spacesTypes = QVector<SpacesType>()
<< NoSpaces << WithSpaces;
const QVector<LocaleType> localeTypes = QVector<LocaleType>()
<< CLocale << SystemLocale;
const QVector<uint> degreeSamples = QVector<uint>()
<< 0 << 140 << 180;
const QVector<qreal> minutesSamples = QVector<qreal>()
<< 0.0 << 3.14159 << 59.9999999;
foreach(const UnitsType unitsType, unitsTypes) {
foreach(const SpacesType spacesType, spacesTypes) {
// lon
foreach(const SphereType lonSphere, sphereTypes) {
foreach(const SignType lonSignType, signTypes) {
const bool lonIsPositive =
(lonSphere==PosSphere && lonSignType!=NegativeSign) ||
(lonSphere==NegSphere && lonSignType==NegativeSign);
foreach(const uint lonDegree, degreeSamples) {
foreach(const qreal lonMinutes, minutesSamples) {
if(lonDegree == 180 && lonMinutes != 0.0) continue;
// lat
foreach(const SphereType latSphere, sphereTypes) {
foreach(const SignType latSignType, signTypes) {
const bool latIsPositive =
(latSphere==PosSphere && latSignType!=NegativeSign) ||
(latSphere==NegSphere && latSignType==NegativeSign);
foreach(const uint latDegree, degreeSamples) {
foreach(const qreal latMinutes, minutesSamples) {
if(latDegree == 180 && latMinutes != 0.0) continue;
// locale
foreach(const LocaleType locale, localeTypes) {
// actual construction
// Create lon & lat values
qreal lon = (qreal)lonDegree + lonMinutes*MIN2HOUR;
if( ! lonIsPositive )
lon *= -1;
qreal lat = (qreal)latDegree + latMinutes*MIN2HOUR;
if( ! latIsPositive )
lat *= -1;
// Create string
QString string;
string.append(createDegreeString(latSignType,
latDegree, latMinutes,
locale,
unitsType, spacesType));
string.append(QLatin1Char(latSphere==PosSphere?'N':'S'));
string.append(QLatin1Char(' '));
string.append(createDegreeString(lonSignType,
lonDegree, lonMinutes,
locale,
unitsType, spacesType));
string.append(QLatin1Char(lonSphere==PosSphere?'E':'W'));
// Create row title
QString rowTitle;
rowTitle.append(QLatin1String(spacesType==WithSpaces?"spaced dir":"unspaced dir"))
.append(QLatin1String(unitsType==WithUnits?"|units":"|no units"))
.append(QLatin1String("|lon:"))
.append(QLatin1Char(lonIsPositive?'+':'-'))
.append(QString::number(lonDegree)+QChar(0xb0))
.append(QString::number(lonMinutes, 'f', 10)+QLatin1Char('\''))
.append(QLatin1Char(lonSphere==PosSphere?'P':'N'))
.append(QLatin1String("|lat:"))
.append(QLatin1Char(latIsPositive?'+':'-'))
.append(QString::number(latDegree)+QChar(0xb0))
.append(QString::number(latMinutes, 'f', 10)+QLatin1Char('\''))
.append(QLatin1Char(latSphere==PosSphere?'P':'N'))
.append(QLatin1Char('|')).append(QLatin1Char(locale==CLocale?'C':'L'))
.append(QLatin1Char('|')).append(string).append(QLatin1Char('|'));
QTest::newRow(rowTitle.toLatin1().constData())
<< string
<< lon
<< lat;
}
}
}
}
}
}
}
}
}
}
}
}
/*
* test fromString() with DM notation
*/
void TestGeoDataCoordinates::testFromStringDM()
{
// only run random 5% of all possible permutations
if ((qreal(qrand()) / RAND_MAX) > 0.05) {
QSKIP("Not picked for this run.");
}
QFETCH(QString, string);
QFETCH(qreal, lon);
QFETCH(qreal, lat);
bool succeeded = false;
const GeoDataCoordinates coords = GeoDataCoordinates::fromString(string, succeeded);
if(! succeeded)
qWarning() << "Could not parse"<<string <<"for"<<lon<<lat;
QVERIFY(succeeded);
QCOMPARE(coords.longitude(GeoDataCoordinates::Degree), lon);
QCOMPARE(coords.latitude(GeoDataCoordinates::Degree), lat);
}
/*
* test data for testStringDM()
*/
void TestGeoDataCoordinates::testFromStringD_data()
{
QTest::addColumn<QString>("string");
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
const QVector<SignType> signTypes = QVector<SignType>()
<< NoSign << PositiveSign << NegativeSign;
const QVector<SphereType> sphereTypes = QVector<SphereType>()
<< PosSphere << NegSphere;
const QVector<UnitsType> unitsTypes = QVector<UnitsType>()
<< NoUnits << WithUnits;
const QVector<SpacesType> spacesTypes = QVector<SpacesType>()
<< NoSpaces << WithSpaces;
const QVector<LocaleType> localeTypes = QVector<LocaleType>()
<< CLocale << SystemLocale;
const QVector<qreal> degreeSamples = QVector<qreal>()
<< qreal(0.0) << qreal(3.14159) << qreal(180.0);
foreach(const UnitsType unitsType, unitsTypes) {
foreach(const SpacesType spacesType, spacesTypes) {
// lon
foreach(const SphereType lonSphere, sphereTypes) {
foreach(const SignType lonSignType, signTypes) {
const bool lonIsPositive =
(lonSphere==PosSphere && lonSignType!=NegativeSign) ||
(lonSphere==NegSphere && lonSignType==NegativeSign);
foreach(const qreal lonDegree, degreeSamples) {
// lat
foreach(const SphereType latSphere, sphereTypes) {
foreach(const SignType latSignType, signTypes) {
const bool latIsPositive =
(latSphere==PosSphere && latSignType!=NegativeSign) ||
(latSphere==NegSphere && latSignType==NegativeSign);
foreach(const qreal latDegree, degreeSamples) {
// locale
foreach(const LocaleType locale, localeTypes) {
// actual construction
// Create lon & lat values
qreal lon = lonDegree;
if (! lonIsPositive)
lon *= -1;
qreal lat = latDegree;
if (! latIsPositive)
lat *= -1;
// Create string
QString string;
string.append(createDegreeString(latSignType,
latDegree,
locale,
unitsType, spacesType));
string.append(QLatin1Char(latSphere==PosSphere?'N':'S'));
string.append(QLatin1Char(' '));
string.append(createDegreeString(lonSignType,
lonDegree,
locale,
unitsType, spacesType));
string.append(QLatin1Char(lonSphere==PosSphere?'E':'W'));
// Create row title
QString rowTitle;
rowTitle.append(QLatin1String(spacesType==WithSpaces?"spaced dir":"unspaced dir"))
.append(QLatin1String(unitsType==WithUnits?"|units":"|no units"))
.append(QLatin1String("|lon:"))
.append(QLatin1Char(lonIsPositive?'+':'-'))
.append(QString::number(lonDegree, 'f', 10)+QChar(0xb0))
.append(QLatin1Char(lonSphere==PosSphere?'P':'N'))
.append(QLatin1String("|lat:"))
.append(QLatin1Char(latIsPositive?'+':'-'))
.append(QString::number(latDegree, 'f', 10)+QChar(0xb0))
.append(QLatin1Char(latSphere==PosSphere?'P':'N'))
.append(QLatin1Char('|')).append(QLatin1Char(locale==CLocale?'C':'L'))
.append(QLatin1Char('|')).append(string).append(QLatin1Char('|'));
QTest::newRow(rowTitle.toLatin1().constData())
<< string
<< lon
<< lat;
}
}
}
}
}
}
}
}
}
QTest::newRow("scientific notation") << "0.0,1.0e-2" << qreal(1.0e-2) << qreal(0.0);
QTest::newRow("scientific notation") << "-2.4E0 1.0e-18" << qreal(1e-18) << qreal(-2.4e0);
QTest::newRow("scientific notation") << "1.14e-02;1.33e+01" << qreal(1.33e1) << qreal(1.14e-2);
}
/*
* test fromString() with DM notation
*/
void TestGeoDataCoordinates::testFromStringD()
{
QFETCH(QString, string);
QFETCH(qreal, lon);
QFETCH(qreal, lat);
bool succeeded = false;
const GeoDataCoordinates coords = GeoDataCoordinates::fromString(string, succeeded);
if(! succeeded)
qWarning() << "Could not parse"<<string <<"for"<<lon<<lat;
QVERIFY(succeeded);
QCOMPARE(coords.longitude(GeoDataCoordinates::Degree), lon);
QCOMPARE(coords.latitude(GeoDataCoordinates::Degree), lat);
}
class FromStringRegExpTranslator : public QTranslator
{
public:
FromStringRegExpTranslator(const QString& _degree, const QString& _minutes, const QString& _seconds,
const QString& _north, const QString& _south,
const QString& _east, const QString& _west)
- : QTranslator((QObject*)0)
+ : QTranslator((QObject*)nullptr)
, degree( _degree )
, minutes( _minutes )
, seconds( _seconds )
, north( _north )
, south( _south )
, east( _east )
, west( _west )
{}
public: // QTranslator API
bool isEmpty() const override { return false; }
QString translate( const char* context, const char* sourceText,
- const char* disambiguation = 0, int n = -1 ) const override;
+ const char* disambiguation = nullptr, int n = -1 ) const override;
private:
const QString degree;
const QString minutes;
const QString seconds;
const QString north;
const QString south;
const QString east;
const QString west;
};
QString FromStringRegExpTranslator::translate(const char* context, const char* sourceText,
const char* disambiguation , int n) const
{
Q_UNUSED(n);
if (qstrcmp(context, "GeoDataCoordinates") != 0 )
return QString();
if (qstrcmp(sourceText, "*") != 0 )
return QString();
if (qstrcmp(disambiguation, "North direction terms") == 0 )
return north;
if (qstrcmp(disambiguation, "South direction terms") == 0 )
return south;
if (qstrcmp(disambiguation, "East direction terms") == 0 )
return east;
if (qstrcmp(disambiguation, "West direction terms") == 0 )
return west;
if (qstrcmp(disambiguation, "Degree symbol terms") == 0 )
return degree;
if (qstrcmp(disambiguation, "Minutes symbol terms") == 0 )
return minutes;
if (qstrcmp(disambiguation, "Seconds symbol terms") == 0 )
return seconds;
return QString();
}
class Sample
{
public:
Sample() {}
Sample(const char* _name, const char* _string, qreal _lon, qreal _lat)
: name(QString::fromUtf8(_name))
, string(QString::fromUtf8(_string))
, lon(_lon)
, lat(_lat)
{}
QString name;
QString string;
qreal lon;
qreal lat;
};
class Language {
public:
Language() {}
Language(const char* _name,
const char* _degree, const char* _minutes, const char* _seconds,
const char* _north, const char* _south, const char* _east, const char* _west,
const QVector<Sample>& _samples)
: name(QString::fromUtf8(_name))
, degree(QString::fromUtf8(_degree))
, minutes(QString::fromUtf8(_minutes))
, seconds(QString::fromUtf8(_seconds))
, north(QString::fromUtf8(_north))
, south(QString::fromUtf8(_south))
, east(QString::fromUtf8(_east))
, west(QString::fromUtf8(_west))
, samples(_samples)
{}
QString name;
QString degree;
QString minutes;
QString seconds;
QString north;
QString south;
QString east;
QString west;
QVector<Sample> samples;
};
void TestGeoDataCoordinates::testFromLocaleString_data()
{
QTest::addColumn<QString>("degree");
QTest::addColumn<QString>("minutes");
QTest::addColumn<QString>("seconds");
QTest::addColumn<QString>("north");
QTest::addColumn<QString>("south");
QTest::addColumn<QString>("east");
QTest::addColumn<QString>("west");
QTest::addColumn<QString>("string");
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
const QVector<Language> languages = QVector<Language>()
<< Language(
"English",
"*", // degree
"*", // minutes
"*", // seconds
"*", // north
"*", // south
"*", // east
"*", // west
QVector<Sample>()
<< Sample(
"London",
"N051 30.150′ W000 07.234′",
-0.12056666666666666921, 51.50249999999999772626)
<< Sample(
"Ålgård",
"N58.764828 E5.855483",
5.85548300000000043752, 58.76482800000000139562))
<< Language(
"Japanese",
"度", // degree
"分", // minutes
"秒", // seconds
"北緯", // north
"南緯", // south
"東経", // east
"西経", // west
QVector<Sample>()
<< Sample(
"London",
"北緯51度30分28秒 西経0度07分41秒",
-0.12805555555555556135, 51.50777777777777544088)
<< Sample(
"Sydney",
"南緯33度52分06秒 東経151度12分31秒",
151.20861111111111085847, -33.86833333333333229120))
<< Language(
"Korean",
"도", // degree
"분", // minutes
"초", // seconds
"북위", // north
"남위", // south
"동경", // east
"서경", // west
QVector<Sample>()
<< Sample(
"London",
"북위 51도 30분 26초, 서경 0도 7분 39초",
-0.12750000000000000222, 51.50722222222222512755)
<< Sample(
"Sydney",
"남위 33도 31분 56초, 동경 151도 12분 40초",
151.21111111111110858474, -33.53222222222222370647))
// TODO: allow test control for parsing float in given locale
#if 0
<< Language(
"Galician",
"", // degree
"", // minutes
"", // seconds
"N", //north
"S", // south
"L|E", // east
"O|W", // west
QVector<Sample>()
<< Sample(
"Campamento",
"36º10,67´N 5º24,29´W",
-5.40483333333333337833, 36.17783333333333217752))
#endif
<< Language(
"German",
"*", // degree
"*", // minutes
"*", // seconds
"N", //north
"S", // south
"O", // east
"W", // west
QVector<Sample>()
<< Sample(
"London",
"51° 31′ N, 0° 7′ W",
-0.11666666666666666852, 51.51666666666666571928))
<< Language(
"Greek",
"", // degree
"", // minutes
"", // seconds
"Β", // north
"Ν", // south
"Α", // east
"Δ", // west
QVector<Sample>()
<< Sample(
"Χαλκίδα",
"38° 28′ Β 23° 36′ Α",
23.6, 38.46666666666666856))
<< Language(
"Dutch",
"", // degree
"", // minutes
"", // seconds
"N|NB", // north
"Z|ZB", // south
"O|OL", // east
"W|WL", // west
QVector<Sample>()
<< Sample(
"Amersfoort",
"N 52° 8′ 32.14″ , E 5° 24′ 56.09″",
5.41558055555555561966, 52.14226111111111094942)
// TODO: allow test control for parsing float in given locale
#if 0
<< Sample(
"London",
"51°30'00,55\" NB 0°07'34,45\" WL",
-0.12623611111111110450, 51.50015277777777811252)
<< Sample(
"Amsterdam",
"52°22'12,78\" NB 4°53'42,60\" OL",
4.89516666666666644403, 52.37021666666666419587)
<< Sample(
"Capetown",
"33°55'29,52\" ZB 18°25'26,60\" OL",
18.42405555555555451974, -33.92486666666666650372)
#endif
)
<< Language(
"Polish",
"", // degree
"", // minutes
"", // seconds
"Pn.|Pn", // north
"Płd.|Płd", // south
"Wschod.|Wschod|Wsch.|Wsch|Ws.|Ws", // east
"Zach.|Zach|Z", // west
QVector<Sample>()
<< Sample(
"Warsaw",
"52°13′56″Pn. 21°00′30″Ws.",
21.00833333333333285964, 52.23222222222221944321))
// TODO: allow test control for parsing float in given locale
#if 0
<< Language(
"Esperanto",
"", // degree
"", // minutes
"", // seconds
"N", // north
"S", // south
"Or", // east
"Ok", // west
QVector<Sample>()
<< Sample(
"London",
"52° 8′ 32,14″ N; 5° 24′ 56,09″ Or",
5.41558055555555561966, 52.14226111111111094942))
#endif
<< Language(
"Norwegian",
"", // degree
"", // minutes
"", // seconds
"N", // north
"S", // south
"Ø", // east
"V", // west
QVector<Sample>()
<< Sample(
"London",
"51° 30′ 25” N 0° 7′ 39” V",
-0.12750000000000000222, 51.50694444444444286546)
<< Sample(
"Ålgård",
"58° 45′ 53.38″ N 5° 51′ 19.74″ Ø",
5.85548333333333292927, 58.76482777777777499750))
<< Language(
"Swedish",
"", // degree
"", // minutes
"", // seconds
"N", // north
"S", // south
"O", // east
"V", // west
QVector<Sample>()
<< Sample(
"London",
"51°30′29″N 0°7′29″V",
-0.12472222222222222043, 51.50805555555555770297)
<< Sample(
"Sydney",
"33°31′56″S 151°12′40″O",
151.21111111111110858474, -33.53222222222222370647))
<< Language(
"Icelandic",
"", // degree
"", // minutes
"", // seconds
"N", //north
"S", // south
"A", // east
"V", // west
//TODO: "breidd 51°30'26\" N, lengd 0°7'39\" V" // London
QVector<Sample>()
<< Sample(
"Sydney",
"33°31'56\" S, 151°12'40\" A",
151.21111111111110858474, -33.53222222222222370647))
<< Language(
"Turkish",
"", // degree
"", // minutes
"", // seconds
"K", // north
"G", // south
"D", // east
"B", // west
QVector<Sample>()
<< Sample(
"London",
"51° 30′ 28″ K, 0° 7′ 41″ B",
-0.12805555555555556135, 51.50777777777777544088))
<< Language(
"Spanish", // (incl. Latin America)
"", // degree
"", // minutes
"", // seconds
"N", // north
"S", // south
"E", // east
"O|W", // west
QVector<Sample>()
<< Sample(
"London",
"51°30′25″N 00°07′39″O",
-0.12750000000000000222, 51.50694444444444286546)
<< Sample(
"Else",
"52° 8′ 32.14″ N, 5° 24′ 56.09″ W",
-5.41558055555555561966, 52.14226111111111094942)
<< Sample(
"Bogotá",
"4°35’53″N 74°4’33″O",
-74.07583333333333541759, 4.59805555555555667269))
<< Language(
"French",
"", // degree
"", // minutes
"", // seconds
"N", // north
"S", // south
"E", // east
"O", // west
QVector<Sample>()
<< Sample(
"London",
"51° 30′ 18″ N 0° 04′ 43″ O",
-0.07861111111111110383, 51.50500000000000255795))
<< Language(
"Portuguese", // incl. Brazilian Portuguese
"", // degree
"", // minutes
"", // seconds
"N", // north
"S", // south
"E|L", // east
"O", // west
QVector<Sample>()
<< Sample(
"London",
"52° 8′ 32.14″ N, 5° 24′ 56.09″ E",
5.41558055555555561966, 52.14226111111111094942))
<< Language(
"Arabic",
"", // degree
"", // minutes
"", // seconds
"شمال", // north
"جنوب", // south
"شرق", // east
"غرب", // west
QVector<Sample>()
<< Sample(
"Warsaw",
"52°13′56″ شمال 21°00′30″ شرق",
21.00833333333333285964, 52.23222222222221944321))
<< Language(
"Russian",
"", //"град", "градусов" // degree
"", //"мин", "минут" // minutes
"", //"сек", "секунд" // seconds
"с. ш.", // north
"ю. ш.", // south
"в. д.", // east
"з. д.", // west
QVector<Sample>()
<< Sample(
"London",
"51°30′26″ с. ш. 0°07′39″ з. д.",
-0.12750000000000000222, 51.50722222222222512755))
<< Language(
"Ukrainian",
"", // degree
"", // minutes
"", // seconds
"пн. ш.", // north
"пд. ш.", // south
"сх. д.", // east
"зх. д.", // west
QVector<Sample>()
<< Sample(
"London",
"51°30' пн. ш. 0°07' сх. д.",
0.11666666666666666852, 51.50000000000000000000)
<< Sample(
"Sydney",
"33°52'10'' пд. ш. 151°12'30'' сх. д.",
151.20833333333334280724, -33.86944444444444712872)
<< Sample(
"Rio de Janeiro",
"22°54'30'' пд. ш. 43°11'47'' зх. д.",
-43.19638888888889027839, -22.90833333333333499127))
<< Language(
"Bulgarian",
"", // degree
"", // minutes
"", // seconds
"с. ш.", // north
"ю. ш.", // south
"и. д.", // east
"и. д.", // west
QVector<Sample>()
<< Sample(
"London",
"51°30′26″ с. ш. 0°07′39″ и. д.",
0.12750000000000000222, 51.50722222222222512755))
<< Language(
"Czech",
"", // degree
"", // minutes
"", // seconds
"s. š.", // north
"j. š.", // south
"z. d.", // east
"v. d.", // west
QVector<Sample>()
<< Sample(
"London",
"51°30′42″ s. š., 0°02′56″ z. d.",
0.04888888888888889145, 51.51166666666666316132)
<< Sample(
"Sydney",
"33° 52′ j. š., 151° 13′ v. d.",
-151.21666666666669698316, -33.86666666666666714036))
<< Language(
"Hindi",
"", // degree
"", // minutes
"", // seconds
"उ", // north
"द", // south
"पू", // east
"प", // west
QVector<Sample>()
<< Sample(
"London",
"51°30′25″उ 00°07′39″पू",
0.12750000000000000222, 51.50694444444444286546))
<< Language(
"Tamil",
"", // degree
"", // minutes
"", // seconds
"வ", // north
"தெ", // south
"கி", // east
"மே", // west
QVector<Sample>()
<< Sample(
"London",
"51°30′25″ வ 00°07′39″ கி",
0.12750000000000000222, 51.50694444444444286546))
;
foreach( const Language& language, languages ) {
foreach( const Sample& sample, language.samples ) {
const QString rowTitle =
language.name +
QLatin1String("|") + sample.name +
QLatin1String("|lon:") +
QString::number(sample.lon, 'f', 10) +
QLatin1String("|lat:") +
QString::number(sample.lat, 'f', 10);
QTest::newRow(rowTitle.toLatin1().constData())
<< language.degree
<< language.minutes
<< language.seconds
<< language.north
<< language.south
<< language.east
<< language.west
<< sample.string
<< sample.lon
<< sample.lat;
}
}
}
void TestGeoDataCoordinates::testFromLocaleString()
{
QFETCH(QString, degree);
QFETCH(QString, minutes);
QFETCH(QString, seconds);
QFETCH(QString, north);
QFETCH(QString, south);
QFETCH(QString, east);
QFETCH(QString, west);
QFETCH(QString, string);
QFETCH(qreal, lon);
QFETCH(qreal, lat);
FromStringRegExpTranslator translator(degree, minutes, seconds, north, south, east, west);
QCoreApplication::installTranslator(&translator);
bool succeeded = false;
const GeoDataCoordinates coords = GeoDataCoordinates::fromString(string, succeeded);
if(! succeeded)
qWarning() << "Could not parse"<<string <<"for"<<lon<<lat;
QVERIFY(succeeded);
// Uncomment to get the lon and lat values with more precision
// qWarning() << "lon"<<QString::number(coords.longitude(GeoDataCoordinates::Degree), 'f', 20)
// << "lat"<<QString::number(coords.latitude(GeoDataCoordinates::Degree), 'f', 20);
QCOMPARE(coords.longitude(GeoDataCoordinates::Degree), lon);
QCOMPARE(coords.latitude(GeoDataCoordinates::Degree), lat);
QCoreApplication::removeTranslator(&translator);
}
/*
* test data for toString()
*/
void TestGeoDataCoordinates::testToString_Decimal_data()
{
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
QTest::addColumn<int>("precision");
QTest::addColumn<QString>("expected");
addRow() << qreal(150.0) << qreal(80.0) << 0 << QString::fromUtf8( " 150°E, 80°N" );
addRow() << qreal(150.0) << qreal(80.0) << 1 << QString::fromUtf8( "150.0°E, 80.0°N" );
addRow() << qreal(150.0) << qreal(80.0) << 2 << QString::fromUtf8( "150.00°E, 80.00°N" );
addRow() << qreal(150.0) << qreal(80.0) << 3 << QString::fromUtf8( "150.000°E, 80.000°N" );
addRow() << qreal(150.0) << qreal(80.0) << 4 << QString::fromUtf8( "150.0000°E, 80.0000°N" );
addRow() << qreal(150.0) << qreal(80.0) << 5 << QString::fromUtf8( "150.00000°E, 80.00000°N" );
addRow() << qreal(149.6) << qreal(79.6) << 0 << QString::fromUtf8( " 150°E, 80°N" );
addRow() << qreal(149.96) << qreal(79.96) << 0 << QString::fromUtf8( " 150°E, 80°N" );
addRow() << qreal(149.6) << qreal(79.6) << 1 << QString::fromUtf8( "149.6°E, 79.6°N" );
addRow() << qreal(149.96) << qreal(79.96) << 1 << QString::fromUtf8( "150.0°E, 80.0°N" );
addRow() << qreal(149.996) << qreal(79.996) << 1 << QString::fromUtf8( "150.0°E, 80.0°N" );
addRow() << qreal(149.96) << qreal(79.96) << 2 << QString::fromUtf8( "149.96°E, 79.96°N" );
addRow() << qreal(149.996) << qreal(79.996) << 2 << QString::fromUtf8( "150.00°E, 80.00°N" );
addRow() << qreal(149.9996) << qreal(79.9996) << 2 << QString::fromUtf8( "150.00°E, 80.00°N" );
addRow() << qreal(149.996) << qreal(79.996) << 3 << QString::fromUtf8( "149.996°E, 79.996°N" );
addRow() << qreal(149.9996) << qreal(79.9996) << 3 << QString::fromUtf8( "150.000°E, 80.000°N" );
addRow() << qreal(149.99996) << qreal(79.99996) << 3 << QString::fromUtf8( "150.000°E, 80.000°N" );
addRow() << qreal(149.9996) << qreal(79.9996) << 4 << QString::fromUtf8( "149.9996°E, 79.9996°N" );
addRow() << qreal(149.99996) << qreal(79.99996) << 4 << QString::fromUtf8( "150.0000°E, 80.0000°N" );
addRow() << qreal(149.999996) << qreal(79.999996) << 4 << QString::fromUtf8( "150.0000°E, 80.0000°N" );
addRow() << qreal(149.99996) << qreal(79.99996) << 5 << QString::fromUtf8( "149.99996°E, 79.99996°N" );
addRow() << qreal(149.999996) << qreal(79.999996) << 5 << QString::fromUtf8( "150.00000°E, 80.00000°N" );
addRow() << qreal(149.9999996) << qreal(79.9999996) << 5 << QString::fromUtf8( "150.00000°E, 80.00000°N" );
addRow() << qreal(149.999996) << qreal(79.999996) << 6 << QString::fromUtf8( "149.999996°E, 79.999996°N" );
addRow() << qreal(149.9999996) << qreal(79.9999996) << 6 << QString::fromUtf8( "150.000000°E, 80.000000°N" );
addRow() << qreal(150.1) << qreal(80.1) << 0 << QString::fromUtf8( " 150°E, 80°N" );
addRow() << qreal(150.01) << qreal(80.01) << 0 << QString::fromUtf8( " 150°E, 80°N" );
addRow() << qreal(150.1) << qreal(80.1) << 1 << QString::fromUtf8( "150.1°E, 80.1°N" );
addRow() << qreal(150.01) << qreal(80.01) << 1 << QString::fromUtf8( "150.0°E, 80.0°N" );
addRow() << qreal(150.001) << qreal(80.001) << 1 << QString::fromUtf8( "150.0°E, 80.0°N" );
addRow() << qreal(150.01) << qreal(80.01) << 2 << QString::fromUtf8( "150.01°E, 80.01°N" );
addRow() << qreal(150.001) << qreal(80.001) << 2 << QString::fromUtf8( "150.00°E, 80.00°N" );
addRow() << qreal(150.0001) << qreal(80.0001) << 2 << QString::fromUtf8( "150.00°E, 80.00°N" );
addRow() << qreal(150.001) << qreal(80.001) << 3 << QString::fromUtf8( "150.001°E, 80.001°N" );
addRow() << qreal(150.0001) << qreal(80.0001) << 3 << QString::fromUtf8( "150.000°E, 80.000°N" );
addRow() << qreal(150.00001) << qreal(80.00001) << 3 << QString::fromUtf8( "150.000°E, 80.000°N" );
addRow() << qreal(150.0001) << qreal(80.0001) << 4 << QString::fromUtf8( "150.0001°E, 80.0001°N" );
addRow() << qreal(150.00001) << qreal(80.00001) << 4 << QString::fromUtf8( "150.0000°E, 80.0000°N" );
addRow() << qreal(150.000001) << qreal(80.000001) << 4 << QString::fromUtf8( "150.0000°E, 80.0000°N" );
addRow() << qreal(150.00001) << qreal(80.00001) << 5 << QString::fromUtf8( "150.00001°E, 80.00001°N" );
addRow() << qreal(150.000001) << qreal(80.000001) << 5 << QString::fromUtf8( "150.00000°E, 80.00000°N" );
addRow() << qreal(150.0000001) << qreal(80.0000001) << 5 << QString::fromUtf8( "150.00000°E, 80.00000°N" );
addRow() << qreal(150.000001) << qreal(80.000001) << 6 << QString::fromUtf8( "150.000001°E, 80.000001°N" );
addRow() << qreal(150.0000001) << qreal(80.0000001) << 6 << QString::fromUtf8( "150.000000°E, 80.000000°N" );
}
/*
* test toString()
*/
void TestGeoDataCoordinates::testToString_Decimal()
{
QFETCH( qreal, lon );
QFETCH( qreal, lat );
QFETCH( int, precision );
QFETCH( QString, expected );
const GeoDataCoordinates coordinates( lon, lat, 0, GeoDataCoordinates::Degree );
const QString result = coordinates.toString( GeoDataCoordinates::Decimal, precision );
QCOMPARE( result, expected );
}
/*
* test data for toString()
*/
void TestGeoDataCoordinates::testToString_DMS_data()
{
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
QTest::addColumn<int>("precision");
QTest::addColumn<QString>("expected");
addRow() << qreal(0.) << qreal(0.) << 0 << QString::fromUtf8( " 0°E, 0°S" );
addRow() << qreal(150.) << qreal(80.) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(149. + 31./60) << qreal(79. + 31./60) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(149. + 30./60 + 31./3600) << qreal(79. + 30./60 + 31./3600) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(149. + 30./60 + 30.51/3600) << qreal(79. + 30./60 + 30.51/3600) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(150. + 29./60) << qreal(80. + 29./60) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(150. + 29./60 + 29./3600) << qreal(80. + 29./60 + 29./3600) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(150. + 29./60 + 29.49/3600) << qreal(80. + 29./60 + 29.49/3600) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(0.) << qreal(0.) << 1 << QString::fromUtf8( " 0° 00'E, 0° 00'S" );
addRow() << qreal(150.) << qreal(80.) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(149. + 59./60 + 31./3600) << qreal(79. + 59./60 + 31./3600) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(149. + 59./60 + 30.51/3600) << qreal(79. + 59./60 + 30.51/3600) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(150. + 29./3600) << qreal(80. + 29./3600) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(150. + 29.49/3600) << qreal(80. + 29.49/3600) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(0.) << qreal(0.) << 2 << QString::fromUtf8( " 0° 00'E, 0° 00'S" );
addRow() << qreal(150.) << qreal(80.) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(149. + 59./60 + 31./3600) << qreal(79. + 59./60 + 31./3600) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(149. + 59./60 + 30.51/3600) << qreal(79. + 59./60 + 30.51/3600) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(150. + 29./3600) << qreal(80. + 29./3600) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(150. + 29.49/3600) << qreal(80. + 29.49/3600) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(0.) << qreal(0.) << 3 << QString::fromUtf8( " 0° 00' 00\"E, 0° 00' 00\"S" );
addRow() << qreal(150.) << qreal(80.) << 3 << QString::fromUtf8( "150° 00' 00\"E, 80° 00' 00\"N" );
addRow() << qreal(149. + 59./60 + 59.51/3600) << qreal(79. + 59./60 + 59.51/3600) << 3 << QString::fromUtf8( "150° 00' 00\"E, 80° 00' 00\"N" );
addRow() << qreal(150. + 0.49/3600) << qreal(80. + 0.49/3600) << 3 << QString::fromUtf8( "150° 00' 00\"E, 80° 00' 00\"N" );
addRow() << qreal(0.) << qreal(0.) << 4 << QString::fromUtf8( " 0° 00' 00\"E, 0° 00' 00\"S" );
addRow() << qreal(150.) << qreal(80.) << 4 << QString::fromUtf8( "150° 00' 00\"E, 80° 00' 00\"N" );
addRow() << qreal(149. + 59./60 + 59.51/3600) << qreal(79. + 59./60 + 59.51/3600) << 4 << QString::fromUtf8( "150° 00' 00\"E, 80° 00' 00\"N" );
addRow() << qreal(150. + 0.49/3600) << qreal(80. + 0.49/3600) << 4 << QString::fromUtf8( "150° 00' 00\"E, 80° 00' 00\"N" );
addRow() << qreal(0.) << qreal(0.) << 5 << QString::fromUtf8( " 0° 00' 00.0\"E, 0° 00' 00.0\"S" );
addRow() << qreal(150.) << qreal(80.) << 5 << QString::fromUtf8( "150° 00' 00.0\"E, 80° 00' 00.0\"N" );
addRow() << qreal(149. + 59./60 + 59.951/3600) << qreal(79. + 59./60 + 59.951/3600) << 5 << QString::fromUtf8( "150° 00' 00.0\"E, 80° 00' 00.0\"N" );
addRow() << qreal(150. + 0.049/3600) << qreal(80. + 0.049/3600) << 5 << QString::fromUtf8( "150° 00' 00.0\"E, 80° 00' 00.0\"N" );
addRow() << qreal(0.) << qreal(0.) << 6 << QString::fromUtf8( " 0° 00' 00.00\"E, 0° 00' 00.00\"S" );
addRow() << qreal(150.) << qreal(80.) << 6 << QString::fromUtf8( "150° 00' 00.00\"E, 80° 00' 00.00\"N" );
addRow() << qreal(149. + 59./60 + 59.9951/3600) << qreal(79. + 59./60 + 59.9951/3600) << 6 << QString::fromUtf8( "150° 00' 00.00\"E, 80° 00' 00.00\"N" );
addRow() << qreal(150. + 0.0049/3600) << qreal(80. + 0.0049/3600) << 6 << QString::fromUtf8( "150° 00' 00.00\"E, 80° 00' 00.00\"N" );
}
/*
* test toString()
*/
void TestGeoDataCoordinates::testToString_DMS()
{
QFETCH( qreal, lon );
QFETCH( qreal, lat );
QFETCH( int, precision );
QFETCH( QString, expected );
const GeoDataCoordinates coordinates( lon, lat, 0, GeoDataCoordinates::Degree );
const QString result = coordinates.toString( GeoDataCoordinates::DMS, precision );
QCOMPARE( result, expected );
}
/*
* test data for toString()
*/
void TestGeoDataCoordinates::testToString_DM_data()
{
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
QTest::addColumn<int>("precision");
QTest::addColumn<QString>("expected");
addRow() << qreal(0.) << qreal(0.) << 0 << QString::fromUtf8( " 0°E, 0°S" );
addRow() << qreal(150.) << qreal(80.) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(149. + 31./60) << qreal(79. + 31./60) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(149. + 30.51/60) << qreal(79. + 30.51/60) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(150. + 29./60) << qreal(80. + 29./60) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(150. + 29.49/60) << qreal(80. + 29.49/60) << 0 << QString::fromUtf8( "150°E, 80°N" );
addRow() << qreal(0.) << qreal(0.) << 1 << QString::fromUtf8( " 0° 00'E, 0° 00'S" );
addRow() << qreal(150.) << qreal(80.) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(149. + 59.51/60) << qreal(79. + 59.51/60) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(150. + 0.49/60) << qreal(80. + 0.49/60) << 1 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(0.) << qreal(0.) << 2 << QString::fromUtf8( " 0° 00'E, 0° 00'S" );
addRow() << qreal(150.) << qreal(80.) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(149. + 59.51/60) << qreal(79. + 59.51/60) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(150. + 0.49/60) << qreal(80. + 0.49/60) << 2 << QString::fromUtf8( "150° 00'E, 80° 00'N" );
addRow() << qreal(0.) << qreal(0.) << 3 << QString::fromUtf8( " 0° 00.0'E, 0° 00.0'S" );
addRow() << qreal(150.) << qreal(80.) << 3 << QString::fromUtf8( "150° 00.0'E, 80° 00.0'N" );
addRow() << qreal(149. + 59.951/60) << qreal(79. + 59.951/60) << 3 << QString::fromUtf8( "150° 00.0'E, 80° 00.0'N" );
addRow() << qreal(150. + 0.049/60) << qreal(80. + 0.049/60) << 3 << QString::fromUtf8( "150° 00.0'E, 80° 00.0'N" );
addRow() << qreal(0.) << qreal(0.) << 4 << QString::fromUtf8( " 0° 00.00'E, 0° 00.00'S" );
addRow() << qreal(150.) << qreal(80.) << 4 << QString::fromUtf8( "150° 00.00'E, 80° 00.00'N" );
addRow() << qreal(149. + 59.9951/60) << qreal(79. + 59.9951/60) << 4 << QString::fromUtf8( "150° 00.00'E, 80° 00.00'N" );
addRow() << qreal(150. + 0.0049/60) << qreal(80. + 0.0049/60) << 4 << QString::fromUtf8( "150° 00.00'E, 80° 00.00'N" );
}
/*
* test toString()
*/
void TestGeoDataCoordinates::testToString_DM()
{
QFETCH( qreal, lon );
QFETCH( qreal, lat );
QFETCH( int, precision );
QFETCH( QString, expected );
const GeoDataCoordinates coordinates( lon, lat, 0, GeoDataCoordinates::Degree );
const QString result = coordinates.toString( GeoDataCoordinates::DM, precision );
QCOMPARE( result, expected );
}
/*
* test data for testPack()
*/
void TestGeoDataCoordinates::testPack_data()
{
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
QTest::addColumn<qreal>("alt");
QTest::newRow("deg") << qreal(180.0) << qreal(90.0) << qreal(400.0);
}
/*
* test pack() and unPack()
*/
void TestGeoDataCoordinates::testPack()
{
QFETCH(qreal, lon);
QFETCH(qreal, lat);
QFETCH(qreal, alt);
GeoDataCoordinates coordinates1,coordinates2;
coordinates1.set(lon, lat, alt, GeoDataCoordinates::Degree);
QTemporaryFile file;
if(file.open()) {
QDataStream out(&file);
coordinates1.pack(out);
}
file.close();
if(file.open()) {
QDataStream in(&file);
coordinates2.unpack(in);
}
file.close();
QCOMPARE(coordinates1.longitude(GeoDataCoordinates::Degree), coordinates2.longitude(GeoDataCoordinates::Degree));
QCOMPARE(coordinates1.latitude(GeoDataCoordinates::Degree), coordinates2.latitude(GeoDataCoordinates::Degree));
QCOMPARE(coordinates1.altitude(), coordinates2.altitude());
}
/*
* test data for testUTM()
*/
void TestGeoDataCoordinates::testUTM_data()
{
QTest::addColumn<qreal>("lon");
QTest::addColumn<qreal>("lat");
QTest::addColumn<int>("zone");
QTest::addColumn<QString>("latitudeBand");
QTest::addColumn<int>("easting");
QTest::addColumn<int>("northing");
/* Randomly selected locations, converted to UTM with the following
* tools to check their correctness:
* http://home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html
* http://www.earthpoint.us/Convert.aspx
* http://www.synnatschke.de/geo-tools/coordinate-converter.php
* http://www.latlong.net/lat-long-utm.html
* http://leware.net/geo/utmgoogle.htm
* http://geographiclib.sourceforge.net/cgi-bin/GeoConvert
*/
// Equator
addRow() << qreal(-180.0) << qreal(0.0) << 1 << "N" << 16602144 << 0;
addRow() << qreal(0) << qreal(0.0) << 31 << "N" << 16602144 << 0;
addRow() << qreal(150.567) << qreal(0.0) << 56 << "N" << 22918607 << 0;
// Zone borders
int zoneNumber = 1;
for ( int i = -180; i <= 180; i += 6 ){
addRow() << qreal(i) << qreal(0.0) << zoneNumber << "N" << 16602144 << 0;
zoneNumber++;
}
// Northern hemisphere
addRow() << qreal(-180.0) << qreal(15) << 1 << "P" << 17734904 << 166051369;
addRow() << qreal(0) << qreal(60.5) << 31 << "V" << 33523714 << 671085271;
addRow() << qreal(150.567) << qreal(75.123) << 56 << "X" << 43029080 << 833876115;
// Southern hemisphere
addRow() << qreal(-3.5) << qreal(-50) << 30 << "F" << 46416654 << 446124952;
addRow() << qreal(22.56) << qreal(-62.456) << 34 << "E" << 58047905 << 307404780;
// Exceptions
// North pole (no zone associated, so it returns 0)
addRow() << qreal(-100.0) << qreal(85.0) << 0 << "Y" << 49026986 << 943981733;
addRow() << qreal(100.0) << qreal(85.0) << 0 << "Z" << 50973014 << 943981733;
// South pole (no zone associated, so it returns 0)
addRow() << qreal(-100.0) << qreal(-85.0) << 0 << "A" << 49026986 << 56018267;
addRow() << qreal(100.0) << qreal(-85.0) << 0 << "B" << 50973014 << 56018267;
// Stavanger, in southwestern Norway, is in zone 32
addRow() << qreal(5.73) << qreal(58.97) << 32 << "V" << 31201538 << 654131013;
// Same longitude, at the equator, is in zone 31
addRow() << qreal(5.73) << qreal(0.0) << 31 << "N" << 80389643 << 0;
// Svalbard is in zone 33
addRow() << qreal(10.55) << qreal(78.88) << 33 << "X" << 40427848 << 876023047;
// Same longitude, at the equator, is in zone 32
addRow() << qreal(10.55) << qreal(0.0) << 32 << "N" << 67249738 << 0;
}
/*
* test UTM-related functions:
* - utmZone()
* - utmLatitudeBand()
* - utmEasting()
* - utmNorthing()
*/
void TestGeoDataCoordinates::testUTM(){
QFETCH(qreal, lon);
QFETCH(qreal, lat);
QFETCH(int, zone);
QFETCH(QString, latitudeBand);
QFETCH(int, easting);
QFETCH(int, northing);
GeoDataCoordinates coordinates;
coordinates.set(lon, lat, 0, GeoDataCoordinates::Degree);
QCOMPARE(coordinates.utmZone(), zone);
QCOMPARE(coordinates.utmLatitudeBand(), latitudeBand);
/* Comparing integers is safer than comparing qreals. As the expected
* values are expressed in centimeters, the actual values are converted
* to this unit.
*/
int actualEasting = qRound( 100.0 * coordinates.utmEasting() );
int actualNorthing = qRound( 100.0 * coordinates.utmNorthing() );
QCOMPARE( actualEasting, easting );
QCOMPARE( actualNorthing, northing );
}
QTEST_MAIN(TestGeoDataCoordinates)
#include "TestGeoDataCoordinates.moc"
diff --git a/tests/TestGeoDataCopy.cpp b/tests/TestGeoDataCopy.cpp
index 9c51d6f42..3c5703c26 100644
--- a/tests/TestGeoDataCopy.cpp
+++ b/tests/TestGeoDataCopy.cpp
@@ -1,685 +1,685 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2009 Patrick Spendrin <ps_ml@gmx.de>
//
#include "MarbleDebug.h"
#include "MarbleDirs.h"
// Feature:
#include "GeoDataFolder.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
// Geometry:
#include "GeoDataPolygon.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataLineString.h"
#include "GeoDataLinearRing.h"
#include "GeoDataPoint.h"
// StyleSelector:
#include "GeoDataStyle.h"
#include "GeoDataIconStyle.h"
#include "GeoDataLabelStyle.h"
#include "GeoDataLineStyle.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataStyleMap.h"
// misc:
#include "GeoDataHotSpot.h"
#include "GeoDataLatLonBox.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataCoordinates.h"
#include <QPointF>
#include <QString>
#include <QStringList>
#include <QTest>
namespace Marble
{
class TestGeoDataCopy : public QObject
{
Q_OBJECT
public:
TestGeoDataCopy();
private Q_SLOTS:
void initTestCase();
// misc.:
void copyCoordinates();
void copyHotSpot();
void copyLatLonBox();
// GeoDataGeometry:
void copyLineString();
void copyLinearRing();
void copyPoint();
void copyPolygon();
void copyMultiGeometry();
// GeoDataFeature:
void copyDocument();
void copyFolder();
void copyPlacemark();
// StyleSelector:
void copyStyle();
void copyIconStyle();
void copyLabelStyle();
void copyLineStyle();
void copyPolyStyle();
void copyStyleMap();
private:
const GeoDataCoordinates coord1;
const GeoDataCoordinates coord2;
const GeoDataCoordinates coord3;
};
TestGeoDataCopy::TestGeoDataCopy() :
coord1(13.7107, 51.0235, 123.4, GeoDataCoordinates::Degree, 2),
coord2(14.7107, 52.0235, 133.4, GeoDataCoordinates::Degree, 3),
coord3(15.7107, 53.0235, 143.4, GeoDataCoordinates::Degree, 4)
{
}
void TestGeoDataCopy::initTestCase()
{
MarbleDirs::setMarbleDataPath( DATA_PATH );
MarbleDirs::setMarblePluginPath( PLUGIN_PATH );
}
void TestGeoDataCopy::copyCoordinates()
{
GeoDataCoordinates other = coord1;
// make sure that the coordinate contains the right values
QCOMPARE(other, coord1);
QCOMPARE(other.detail(), coord1.detail());
QVERIFY(coord1 == other);
}
void TestGeoDataCopy::copyPoint()
{
GeoDataPoint point;
point.setCoordinates(coord1);
point.setExtrude( true );
// make sure that the coordinate contains the right values
QCOMPARE(point.coordinates(), coord1);
QCOMPARE(point.coordinates().detail(), coord1.detail());
QCOMPARE(point.extrude(), true);
GeoDataPoint other = point;
// make sure that the coordinate contains the right values
QCOMPARE(other.coordinates(), coord1);
QCOMPARE(other.coordinates().detail(), coord1.detail());
QCOMPARE(other.extrude(), true);
QVERIFY(point.coordinates() == other.coordinates());
point = GeoDataPoint( GeoDataCoordinates(13.7107, 51.0235, 123.4, GeoDataCoordinates::Degree, 17) );
point.setExtrude(false);
QCOMPARE(other.coordinates().detail(), quint8(2));
QCOMPARE(point.coordinates().detail(), quint8(17));
QCOMPARE(other.extrude(), true);
QCOMPARE(point.extrude(), false);
}
void TestGeoDataCopy::copyLineString()
{
GeoDataLineString lineString;
lineString.setTessellate(true);
lineString.append(coord1);
lineString.append(coord2);
lineString.append(coord3);
QVERIFY(lineString.size() == 3);
GeoDataLineString other = lineString;
QVERIFY(other.size() == 3);
QCOMPARE(lineString.at(0), coord1);
QCOMPARE(lineString.at(0).detail(), coord1.detail());
QCOMPARE(other.at(2), coord3);
QCOMPARE(other.at(2).detail(), coord3.detail());
QVERIFY(other.at(2) == coord3);
QVERIFY(other.tessellate());
}
void TestGeoDataCopy::copyLinearRing()
{
GeoDataLinearRing linearRing;
linearRing.setTessellate(true);
linearRing.append(coord1);
linearRing.append(coord2);
linearRing.append(coord3);
QVERIFY(linearRing.size() == 3);
GeoDataLinearRing other = linearRing;
QVERIFY(other.size() == 3);
QCOMPARE(linearRing.at(0), coord1);
QCOMPARE(linearRing.at(0).detail(), coord1.detail());
QCOMPARE(other.at(2), coord3);
QCOMPARE(other.at(2).detail(), coord3.detail());
QVERIFY(other.at(2) == coord3);
QVERIFY(other.tessellate());
}
void TestGeoDataCopy::copyPolygon()
{
GeoDataLinearRing linearRing1;
GeoDataLinearRing linearRing2;
GeoDataLinearRing linearRing3;
GeoDataLinearRing linearRing4;
linearRing1.append(coord1); linearRing1.append(coord2); linearRing1.append(coord3);
linearRing2.append(coord3); linearRing2.append(coord2); linearRing2.append(coord1);
linearRing3.append(coord1); linearRing3.append(coord2); linearRing3.append(coord3);
linearRing3.append(coord3); linearRing3.append(coord2); linearRing3.append(coord1);
linearRing4.append(coord3); linearRing4.append(coord2); linearRing4.append(coord1);
linearRing4.append(coord1); linearRing4.append(coord2); linearRing4.append(coord3);
GeoDataPolygon polygon;
polygon.appendInnerBoundary(linearRing1);
polygon.appendInnerBoundary(linearRing2);
polygon.appendInnerBoundary(linearRing3);
polygon.setOuterBoundary(linearRing4);
polygon.setTessellate(true);
QCOMPARE(polygon.innerBoundaries().size(), 3);
GeoDataPolygon other = polygon;
QCOMPARE(other.innerBoundaries().size(), 3);
QVERIFY(other.innerBoundaries()[0][0] == coord1);
QVERIFY(other.innerBoundaries()[0][1] == coord2);
QVERIFY(other.innerBoundaries()[0][2] == coord3);
QVERIFY(other.innerBoundaries()[1][0] == coord3);
QVERIFY(other.innerBoundaries()[1][1] == coord2);
QVERIFY(other.innerBoundaries()[1][2] == coord1);
QVERIFY(other.innerBoundaries()[2][0] == coord1);
QVERIFY(other.innerBoundaries()[2][1] == coord2);
QVERIFY(other.innerBoundaries()[2][2] == coord3);
QVERIFY(other.innerBoundaries()[2][3] == coord3);
QVERIFY(other.innerBoundaries()[2][4] == coord2);
QVERIFY(other.innerBoundaries()[2][5] == coord1);
QCOMPARE(other.outerBoundary().size(), 6);
QVERIFY(other.outerBoundary()[0] == coord3);
QVERIFY(other.outerBoundary()[1] == coord2);
QVERIFY(other.outerBoundary()[2] == coord1);
QVERIFY(other.outerBoundary()[3] == coord1);
QVERIFY(other.outerBoundary()[4] == coord2);
QVERIFY(other.outerBoundary()[5] == coord3);
QVERIFY(other.tessellate());
}
void TestGeoDataCopy::copyMultiGeometry()
{
GeoDataLinearRing linearRing1;
GeoDataLinearRing linearRing2;
GeoDataLinearRing linearRing3;
GeoDataLinearRing linearRing4;
linearRing1.append(coord1); linearRing1.append(coord2); linearRing1.append(coord3);
linearRing2.append(coord3); linearRing2.append(coord2); linearRing2.append(coord1);
linearRing3.append(coord1); linearRing3.append(coord2); linearRing3.append(coord3);
linearRing3.append(coord3); linearRing3.append(coord2); linearRing3.append(coord1);
linearRing4.append(coord3); linearRing4.append(coord2); linearRing4.append(coord1);
linearRing4.append(coord1); linearRing4.append(coord2); linearRing4.append(coord3);
GeoDataPolygon *polygon = new GeoDataPolygon;
polygon->appendInnerBoundary(linearRing1);
polygon->appendInnerBoundary(linearRing2);
polygon->appendInnerBoundary(linearRing3);
polygon->setOuterBoundary(linearRing4);
polygon->setTessellate(true);
GeoDataMultiGeometry multiGeometry;
multiGeometry.append(polygon);
multiGeometry.append(new GeoDataLinearRing(linearRing1));
multiGeometry.append(new GeoDataLinearRing(linearRing2));
multiGeometry.append(new GeoDataLinearRing(linearRing3));
multiGeometry.append(new GeoDataLinearRing(linearRing4));
GeoDataMultiGeometry other = multiGeometry;
QCOMPARE(other.size(), 5);
QCOMPARE(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries().size(), 3);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[0][0] == coord1);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[0][1] == coord2);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[0][2] == coord3);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[1][0] == coord3);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[1][1] == coord2);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[1][2] == coord1);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[2][0] == coord1);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[2][1] == coord2);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[2][2] == coord3);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[2][3] == coord3);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[2][4] == coord2);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->innerBoundaries()[2][5] == coord1);
QCOMPARE(static_cast<GeoDataPolygon*>(other.child(0))->outerBoundary().size(), 6);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->outerBoundary()[0] == coord3);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->outerBoundary()[1] == coord2);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->outerBoundary()[2] == coord1);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->outerBoundary()[3] == coord1);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->outerBoundary()[4] == coord2);
QVERIFY(static_cast<GeoDataPolygon*>(other.child(0))->outerBoundary()[5] == coord3);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(1))->at(0) == coord1);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(1))->at(1) == coord2);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(1))->at(2) == coord3);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(2))->at(0) == coord3);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(2))->at(1) == coord2);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(2))->at(2) == coord1);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(3))->at(0) == coord1);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(3))->at(1) == coord2);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(3))->at(2) == coord3);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(3))->at(3) == coord3);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(3))->at(4) == coord2);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(3))->at(5) == coord1);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(4))->at(0) == coord3);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(4))->at(1) == coord2);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(4))->at(2) == coord1);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(4))->at(3) == coord1);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(4))->at(4) == coord2);
QVERIFY(static_cast<GeoDataLinearRing*>(other.child(4))->at(5) == coord3);
}
void TestGeoDataCopy::copyDocument()
{
QWARN("add more document specific data");
GeoDataPlacemark pl1;
GeoDataPlacemark pl2;
GeoDataPlacemark pl3;
pl1.setCoordinate(coord1);
pl2.setCoordinate(coord2);
pl3.setCoordinate(coord3);
GeoDataFolder *folder = new GeoDataFolder;
folder->append(new GeoDataPlacemark(pl1));
folder->append(new GeoDataPlacemark(pl2));
folder->append(new GeoDataPlacemark(pl3));
GeoDataDocument document;
document.append(new GeoDataPlacemark(pl3));
document.append(folder);
document.append(new GeoDataPlacemark(pl1));
GeoDataDocument other = document;
QCOMPARE(document.size(), 3);
QCOMPARE(other.size(), 3);
QCOMPARE(static_cast<GeoDataPlacemark*>(other.child(0))->coordinate(), coord3);
QCOMPARE(static_cast<GeoDataPlacemark*>(other.child(2))->coordinate(), coord1);
GeoDataFolder *otherFolder = static_cast<GeoDataFolder*>(other.child(1));
QCOMPARE(static_cast<GeoDataPlacemark*>(otherFolder->child(0))->coordinate(), coord1);
QCOMPARE(static_cast<GeoDataPlacemark*>(otherFolder->child(1))->coordinate(), coord2);
QCOMPARE(static_cast<GeoDataPlacemark*>(otherFolder->child(2))->coordinate(), coord3);
other.append(new GeoDataPlacemark(pl1));
QCOMPARE(document.size(), 3);
QCOMPARE(other.size(), 4);
QCOMPARE(static_cast<GeoDataPlacemark*>(other.child(3))->coordinate(), coord1);
}
void TestGeoDataCopy::copyFolder()
{
GeoDataPlacemark pl1, pl2, pl3;
pl1.setCoordinate(coord1);
pl2.setCoordinate(coord2);
pl3.setCoordinate(coord3);
GeoDataFolder folder;
folder.append(new GeoDataPlacemark(pl1));
folder.append(new GeoDataPlacemark(pl2));
folder.append(new GeoDataPlacemark(pl3));
QCOMPARE(folder.size(), 3);
QCOMPARE(folder.child(0)->parent(), &folder);
QCOMPARE(folder.child(1)->parent(), &folder);
QCOMPARE(folder.child(2)->parent(), &folder);
GeoDataFolder other = folder;
QCOMPARE(other.size(), 3);
QCOMPARE(other.child(0)->parent(), &other);
QCOMPARE(other.child(1)->parent(), &other);
QCOMPARE(other.child(2)->parent(), &other);
QCOMPARE(static_cast<GeoDataPlacemark*>(other.child(0))->coordinate(), coord1);
QCOMPARE(static_cast<GeoDataPlacemark*>(other.child(1))->coordinate(), coord2);
QCOMPARE(static_cast<GeoDataPlacemark*>(other.child(2))->coordinate(), coord3);
other.append(new GeoDataPlacemark(pl1));
QCOMPARE(folder.size(), 3);
QCOMPARE(other.size(), 4);
QCOMPARE(static_cast<GeoDataPlacemark*>(other.child(3))->coordinate(), coord1);
}
void TestGeoDataCopy::copyPlacemark()
{
GeoDataPoint *point = new GeoDataPoint(coord1);
point->setExtrude( true );
// make sure that the coordinate contains the right values
QCOMPARE(point->coordinates(), coord1);
QCOMPARE(point->coordinates().detail(), coord1.detail());
QCOMPARE(point->extrude(), true);
GeoDataFolder folder;
GeoDataPlacemark placemark;
placemark.setName("Patrick Spendrin");
placemark.setGeometry(point);
placemark.setArea(12345678.0);
placemark.setPopulation(123456789);
placemark.setId("281012");
placemark.setParent(&folder);
QCOMPARE(placemark.coordinate(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(placemark.geometry())->coordinates(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(placemark.geometry())->coordinates().detail(), coord1.detail());
QCOMPARE(placemark.area(), 12345678.0);
QCOMPARE(placemark.population(), (qint64)123456789);
QCOMPARE(placemark.id(), QString("281012"));
QCOMPARE(placemark.name(), QString::fromLatin1("Patrick Spendrin"));
QCOMPARE(placemark.geometry()->parent(), &placemark);
QCOMPARE(placemark.parent(), &folder);
{
GeoDataPlacemark other(placemark);
QCOMPARE(other.id(), QString());
- QCOMPARE(other.parent(), static_cast<GeoDataObject *>(0));
+ QCOMPARE(other.parent(), static_cast<GeoDataObject *>(nullptr));
QCOMPARE(other.coordinate(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates().detail(), coord1.detail());
QCOMPARE(other.area(), 12345678.0);
QCOMPARE(other.population(), (qint64)123456789);
QCOMPARE(other.name(), QString::fromLatin1("Patrick Spendrin"));
QCOMPARE(other.geometry()->parent(), &other);
other.setPopulation(987654321);
QCOMPARE(other.coordinate(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates().detail(), coord1.detail());
QCOMPARE(other.area(), 12345678.0);
QCOMPARE(other.population(), (qint64)987654321);
QCOMPARE(placemark.population(), (qint64)123456789);
QCOMPARE(placemark.name(), QString::fromLatin1("Patrick Spendrin"));
QCOMPARE(other.name(), QString::fromLatin1("Patrick Spendrin"));
}
{
GeoDataPlacemark other;
- QCOMPARE(other.parent(), static_cast<GeoDataObject *>(0)); // add a check before assignment to avoid compiler optimizing to copy c'tor
+ QCOMPARE(other.parent(), static_cast<GeoDataObject *>(nullptr)); // add a check before assignment to avoid compiler optimizing to copy c'tor
other = placemark;
QCOMPARE(other.id(), QString());
- QCOMPARE(other.parent(), static_cast<GeoDataObject *>(0));
+ QCOMPARE(other.parent(), static_cast<GeoDataObject *>(nullptr));
QCOMPARE(other.coordinate(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates().detail(), coord1.detail());
QCOMPARE(other.area(), 12345678.0);
QCOMPARE(other.population(), (qint64)123456789);
QCOMPARE(other.name(), QString::fromLatin1("Patrick Spendrin"));
QCOMPARE(other.geometry()->parent(), &other);
other.setPopulation(987654321);
QCOMPARE(other.coordinate(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates(), coord1);
QCOMPARE(static_cast<GeoDataPoint*>(other.geometry())->coordinates().detail(), coord1.detail());
QCOMPARE(other.area(), 12345678.0);
QCOMPARE(other.population(), (qint64)987654321);
QCOMPARE(placemark.population(), (qint64)123456789);
QCOMPARE(placemark.name(), QString::fromLatin1("Patrick Spendrin"));
QCOMPARE(other.name(), QString::fromLatin1("Patrick Spendrin"));
}
{
GeoDataFolder otherFolder;
GeoDataPlacemark other;
other.setParent(&otherFolder);
QCOMPARE(other.parent(), &otherFolder);
other = placemark;
QCOMPARE(other.parent(), &otherFolder);
}
{
const GeoDataPlacemark other(placemark);
const GeoDataPlacemark other2(other);
QCOMPARE(placemark.geometry()->parent(), &placemark);
QCOMPARE(other.geometry()->parent(), &other);
QCOMPARE(other2.geometry()->parent(), &other2);
}
{
GeoDataPlacemark other;
GeoDataPlacemark other2;
QCOMPARE(placemark.geometry()->parent(), &placemark);
QCOMPARE(other.geometry()->parent(), &other);
QCOMPARE(other2.geometry()->parent(), &other2);
other = placemark;
other2 = other;
QCOMPARE(placemark.geometry()->parent(), &placemark);
QCOMPARE(other.geometry()->parent(), &other);
QCOMPARE(other2.geometry()->parent(), &other2);
}
}
void TestGeoDataCopy::copyHotSpot()
{
QPointF point(0.25, 0.75);
GeoDataHotSpot first(point);
GeoDataHotSpot::Units xunits;
GeoDataHotSpot::Units yunits;
GeoDataHotSpot second = first;
QVERIFY(first.hotSpot(xunits, yunits) == QPointF(0.25, 0.75));
QVERIFY(second.hotSpot(xunits, yunits) == QPointF(0.25, 0.75));
first.setHotSpot(QPointF(0.3333333, 0.666666));
QVERIFY(first.hotSpot(xunits, yunits) == QPointF(0.3333333, 0.666666));
QVERIFY(second.hotSpot(xunits, yunits) == QPointF(0.25, 0.75));
}
void TestGeoDataCopy::copyLatLonBox()
{
// north south east west
GeoDataLatLonBox llbox(30.1, 12.2, 110.0, 44.9, GeoDataCoordinates::Degree);
QCOMPARE(llbox.north(GeoDataCoordinates::Degree), 30.1);
QCOMPARE(llbox.south(GeoDataCoordinates::Degree), 12.2);
QCOMPARE(llbox.east(GeoDataCoordinates::Degree), 110.0);
QCOMPARE(llbox.west(GeoDataCoordinates::Degree), 44.9);
GeoDataLatLonBox other = llbox;
QCOMPARE(other.north(GeoDataCoordinates::Degree), 30.1);
QCOMPARE(other.south(GeoDataCoordinates::Degree), 12.2);
QCOMPARE(other.east(GeoDataCoordinates::Degree), 110.0);
QCOMPARE(other.west(GeoDataCoordinates::Degree), 44.9);
llbox.setNorth(0.1);
other.setSouth(1.4);
QCOMPARE(llbox.north(), 0.1);
QCOMPARE(llbox.south(GeoDataCoordinates::Degree), 12.2);
QCOMPARE(other.north(GeoDataCoordinates::Degree), 30.1);
QCOMPARE(other.south(), 1.4);
}
void TestGeoDataCopy::copyStyle()
{
GeoDataLineStyle line(Qt::green);
line.setWidth(2.0);
GeoDataStyle style;
style.setLineStyle( line );
QCOMPARE(style.lineStyle().width(), (float)2.0);
QVERIFY(style.lineStyle().color() == Qt::green);
}
void TestGeoDataCopy::copyIconStyle()
{
// hotspottesting is not implemented as I am not sure how it should work
GeoDataIconStyle icon;
icon.setScale(2.0);
QCOMPARE(icon.scale(), (float)2.0);
GeoDataIconStyle other = icon;
QCOMPARE(other.scale(), (float)2.0);
icon.setScale(5.0);
QCOMPARE(icon.scale(), (float)5.0);
QCOMPARE(other.scale(), (float)2.0);
}
void TestGeoDataCopy::copyLabelStyle()
{
QFont testFont(QFont(QStringLiteral("Sans Serif")).family(), 12, 10, false);
GeoDataLabelStyle label(testFont, Qt::red);
label.setScale(2.0);
QCOMPARE(label.scale(), (float)2.0);
QVERIFY(label.color() == Qt::red);
QVERIFY(label.font() == testFont);
GeoDataLabelStyle other = label;
QCOMPARE(other.scale(), (float)2.0);
QVERIFY(other.color() == Qt::red);
QVERIFY(other.font() == testFont);
other.setColor(Qt::darkRed);
label.setScale(5.0);
QCOMPARE(label.scale(), (float)5.0);
QCOMPARE(other.scale(), (float)2.0);
QVERIFY(label.color() == Qt::red);
QVERIFY(other.color() == Qt::darkRed);
}
void TestGeoDataCopy::copyLineStyle()
{
GeoDataLineStyle line(Qt::green);
line.setWidth(2.0);
QCOMPARE(line.width(), (float)2.0);
QVERIFY(line.color() == Qt::green);
GeoDataLineStyle other = line;
QCOMPARE(other.width(), (float)2.0);
QVERIFY(other.color() == Qt::green);
other.setColor(Qt::darkGreen);
line.setWidth(5.0);
QCOMPARE(line.width(), (float)5.0);
QCOMPARE(other.width(), (float)2.0);
QVERIFY(line.color() == Qt::green);
QVERIFY(other.color() == Qt::darkGreen);
}
void TestGeoDataCopy::copyPolyStyle()
{
GeoDataPolyStyle poly(Qt::blue);
poly.setFill(true);
poly.setOutline(false);
QCOMPARE(poly.fill(), true);
QCOMPARE(poly.outline(), false);
QVERIFY(poly.color() == Qt::blue);
GeoDataPolyStyle other = poly;
QCOMPARE(other.fill(), true);
QCOMPARE(other.outline(), false);
QVERIFY(other.color() == Qt::blue);
other.setOutline(true);
poly.setColor( Qt::cyan );
QCOMPARE(poly.outline(), false);
QCOMPARE(other.outline(), true);
QVERIFY(poly.color() == Qt::cyan);
QVERIFY(other.color() == Qt::blue);
}
void TestGeoDataCopy::copyStyleMap()
{
GeoDataStyleMap styleMap;
styleMap["germany"] = "gst1";
styleMap["germany"] = "gst2";
styleMap["germany"] = "gst3";
styleMap["poland"] = "pst1";
styleMap["poland"] = "pst2";
styleMap["poland"] = "pst3";
styleMap.setLastKey("poland");
QCOMPARE(styleMap.lastKey(), QLatin1String("poland"));
GeoDataStyleMap testMap = styleMap;
QVERIFY( styleMap == testMap );
testMap.insert("Romania", "rst1");
testMap.insert("Romania", "rst2");
testMap.insert("Romania", "rst3");
testMap.setLastKey("Romania");
QCOMPARE(testMap.lastKey(), QLatin1String("Romania"));
QCOMPARE(styleMap.lastKey(), QLatin1String("poland"));
}
}
QTEST_MAIN( Marble::TestGeoDataCopy )
#include "TestGeoDataCopy.moc"
diff --git a/tests/TestGroundOverlay.cpp b/tests/TestGroundOverlay.cpp
index 083cd0040..5b7db0426 100644
--- a/tests/TestGroundOverlay.cpp
+++ b/tests/TestGroundOverlay.cpp
@@ -1,102 +1,102 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include <QObject>
#include <GeoDataDocument.h>
#include <MarbleDebug.h>
#include <GeoDataFolder.h>
#include <GeoDataGroundOverlay.h>
#include "TestUtils.h"
using namespace Marble;
class TestGroundOverlay : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestGroundOverlay::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestGroundOverlay::simpleParseTest()
{
QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Folder>"
"<GroundOverlay>"
"<altitude>0</altitude>"
"<altitudeMode>absolute</altitudeMode>"
"<LatLonBox>"
"<north>37.91904192681665</north>"
"<south>37.46543388598137</south>"
"<east>15.35832653742206</east>"
"<west>14.60128369746704</west>"
"<rotation>-0.1556640799496235</rotation>"
"</LatLonBox>"
"</GroundOverlay>"
"<GroundOverlay>"
"<altitude>233</altitude>"
"<drawOrder>2</drawOrder>"
"<LatLonBox>"
"<north>23.3765376</north>"
"<south>1.5743867869</south>"
"<east>33.78365874</east>"
"<west>94.352435642</west>"
"<rotation>6.346364378</rotation>"
"</LatLonBox>"
"</GroundOverlay>"
"</Folder>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( centerContent );
QCOMPARE( dataDocument->folderList().size(), 1 );
GeoDataFolder *folder = dataDocument->folderList().at( 0 );
QCOMPARE( folder->size(), 2 );
GeoDataGroundOverlay *overlayFirst = dynamic_cast<GeoDataGroundOverlay*>( folder->child( 0 ) );
GeoDataGroundOverlay *overlaySecond = dynamic_cast<GeoDataGroundOverlay*>( folder->child( 1 ) );
- QVERIFY( overlayFirst != 0 );
- QVERIFY( overlaySecond != 0 );
+ QVERIFY( overlayFirst != nullptr );
+ QVERIFY( overlaySecond != nullptr );
QFUZZYCOMPARE( overlayFirst->altitude(), 0.0, 0.0001 );
QFUZZYCOMPARE( overlayFirst->altitudeMode(), Absolute, 0.0001 );
QCOMPARE( overlayFirst->drawOrder(), 0 );
QFUZZYCOMPARE( overlayFirst->latLonBox().north(), 37.91904192681665 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlayFirst->latLonBox().south(), 37.46543388598137 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlayFirst->latLonBox().east(), 15.35832653742206 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlayFirst->latLonBox().west(), 14.60128369746704 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlayFirst->latLonBox().rotation(), -0.1556640799496235 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlaySecond->altitude(), 233.0, 0.0001 );
QCOMPARE( overlaySecond->altitudeMode(), ClampToGround );
QCOMPARE( overlaySecond->drawOrder(), 2 );
QFUZZYCOMPARE( overlaySecond->latLonBox().north(), 23.3765376 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlaySecond->latLonBox().south(), 1.5743867869 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlaySecond->latLonBox().east(), 33.78365874 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlaySecond->latLonBox().west(), 94.352435642 * DEG2RAD, 0.0001 );
QFUZZYCOMPARE( overlaySecond->latLonBox().rotation(), 6.346364378 * DEG2RAD, 0.0001 );
delete dataDocument;
}
QTEST_MAIN( TestGroundOverlay )
#include "TestGroundOverlay.moc"
diff --git a/tests/TestGxTimeSpan.cpp b/tests/TestGxTimeSpan.cpp
index c16db8b82..36e76e632 100644
--- a/tests/TestGxTimeSpan.cpp
+++ b/tests/TestGxTimeSpan.cpp
@@ -1,68 +1,68 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include <QObject>
#include <GeoDataDocument.h>
#include <GeoDataTimeSpan.h>
#include <GeoDataTimeStamp.h>
#include <MarbleDebug.h>
#include "TestUtils.h"
#include <GeoDataLookAt.h>
#include <GeoDataCamera.h>
#include <GeoDataPlacemark.h>
using namespace Marble;
class TestGxTimeSpan : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestGxTimeSpan::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestGxTimeSpan::simpleParseTest()
{
QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Document>"
"<Placemark>"
"<LookAt>"
"<gx:TimeSpan>"
"<begin>2010-05-28T02:02:09Z</begin>"
"<end>2010-05-28T02:02:56Z</end>"
"</gx:TimeSpan>"
"</LookAt>"
"</Placemark>"
"</Document>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( centerContent );
QCOMPARE( dataDocument->placemarkList().size(), 1 );
GeoDataPlacemark *placemark = dataDocument->placemarkList().at( 0 );
- QVERIFY( placemark->lookAt() != 0 );
+ QVERIFY( placemark->lookAt() != nullptr );
QCOMPARE( placemark->lookAt()->timeSpan().begin().when(), QDateTime::fromString( "2010-05-28T02:02:09Z", Qt::ISODate) );
QCOMPARE( placemark->lookAt()->timeSpan().end().when(), QDateTime::fromString( "2010-05-28T02:02:56Z", Qt::ISODate) );
delete dataDocument;
}
QTEST_MAIN( TestGxTimeSpan )
#include "TestGxTimeSpan.moc"
diff --git a/tests/TestGxTimeStamp.cpp b/tests/TestGxTimeStamp.cpp
index 0079cab13..443e9fa6e 100644
--- a/tests/TestGxTimeStamp.cpp
+++ b/tests/TestGxTimeStamp.cpp
@@ -1,67 +1,67 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include <QObject>
#include <GeoDataDocument.h>
#include <GeoDataPlacemark.h>
#include <GeoDataTimeStamp.h>
#include <GeoDataCamera.h>
#include <MarbleDebug.h>
#include "TestUtils.h"
using namespace Marble;
class TestGxTimeStamp : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestGxTimeStamp::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestGxTimeStamp::simpleParseTest()
{
QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Document>"
"<Placemark>"
"<Camera>"
"<gx:TimeStamp>"
"<when>1987-06-05T04:03:02-01:00</when>"
"</gx:TimeStamp>"
"</Camera>"
"</Placemark>"
"</Document>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( centerContent );
QCOMPARE( dataDocument->placemarkList().size(), 1 );
GeoDataPlacemark *placemark = dataDocument->placemarkList().at( 0 );
GeoDataAbstractView* view = placemark->abstractView();
- QVERIFY( view != 0 );
+ QVERIFY( view != nullptr );
GeoDataCamera* camera = dynamic_cast<GeoDataCamera*>( view );
- QVERIFY( camera != 0 );
+ QVERIFY( camera != nullptr );
QCOMPARE( camera->timeStamp().when().toUTC(), QDateTime::fromString( "1987-06-05T04:03:02-01:00", Qt::ISODate).toUTC() );
delete dataDocument;
}
QTEST_MAIN( TestGxTimeStamp )
#include "TestGxTimeStamp.moc"
diff --git a/tests/TestLatLonQuad.cpp b/tests/TestLatLonQuad.cpp
index b7dd11bc8..d89a7ae81 100644
--- a/tests/TestLatLonQuad.cpp
+++ b/tests/TestLatLonQuad.cpp
@@ -1,69 +1,69 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Dennis Nienhüser <nienhueser@kde.org>
//
#include <QObject>
#include "TestUtils.h"
#include <GeoDataDocument.h>
#include <MarbleDebug.h>
#include <GeoDataGroundOverlay.h>
#include <GeoDataLatLonQuad.h>
using namespace Marble;
class TestLatLonQuad : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestLatLonQuad::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestLatLonQuad::simpleParseTest()
{
QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Document>"
"<GroundOverlay id=\"overlayID\">"
"<gx:LatLonQuad>"
"<coordinates>1,2 3,4 5,6 7,8</coordinates>"
"</gx:LatLonQuad>"
"</GroundOverlay>"
"</Document>"
"</kml>");
GeoDataDocument* dataDocument = parseKml( centerContent );
QCOMPARE( dataDocument->size(), 1 );
GeoDataGroundOverlay *overlay = dynamic_cast<GeoDataGroundOverlay*>( dataDocument->child( 0 ) );
- QVERIFY( overlay != 0 );
+ QVERIFY( overlay != nullptr );
QVERIFY( overlay->latLonBox().isEmpty() );
QVERIFY( overlay->latLonQuad().isValid() );
QFUZZYCOMPARE( overlay->latLonQuad().bottomLeft().longitude( GeoDataCoordinates::Degree ), 1.0, 0.0001 );
QFUZZYCOMPARE( overlay->latLonQuad().bottomLeft().latitude( GeoDataCoordinates::Degree ), 2.0, 0.0001 );
QFUZZYCOMPARE( overlay->latLonQuad().bottomRight().longitude( GeoDataCoordinates::Degree ), 3.0, 0.0001 );
QFUZZYCOMPARE( overlay->latLonQuad().bottomRight().latitude( GeoDataCoordinates::Degree ), 4.0, 0.0001 );
QFUZZYCOMPARE( overlay->latLonQuad().topRight().longitude( GeoDataCoordinates::Degree ), 5.0, 0.0001 );
QFUZZYCOMPARE( overlay->latLonQuad().topRight().latitude( GeoDataCoordinates::Degree ), 6.0, 0.0001 );
QFUZZYCOMPARE( overlay->latLonQuad().topLeft().longitude( GeoDataCoordinates::Degree ), 7.0, 0.0001 );
QFUZZYCOMPARE( overlay->latLonQuad().topLeft().latitude( GeoDataCoordinates::Degree ), 8.0, 0.0001 );
}
QTEST_MAIN( TestLatLonQuad )
#include "TestLatLonQuad.moc"
diff --git a/tests/TestListStyle.cpp b/tests/TestListStyle.cpp
index 03cd7b9f9..ca4ac6ca8 100644
--- a/tests/TestListStyle.cpp
+++ b/tests/TestListStyle.cpp
@@ -1,91 +1,91 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 Mohammed Nafees <nafees.technocool@gmail.com>
//
#include <QObject>
#include <GeoDataDocument.h>
#include <MarbleDebug.h>
#include <GeoDataFolder.h>
#include <GeoDataPlacemark.h>
#include <GeoDataStyle.h>
#include <GeoDataListStyle.h>
#include <GeoDataItemIcon.h>
#include "TestUtils.h"
using namespace Marble;
class TestListStyle : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestListStyle::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestListStyle::simpleParseTest()
{
QString const content (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Document>"
" <name>The one and only BalloonStyle test case</name>"
" <Style id=\"my-list-style\">"
" <ListStyle>"
" <listItemType>checkOffOnly</listItemType>"
" <bgColor>aa112233</bgColor>"
" <ItemIcon>"
" <state>open error</state>"
" <href>https://developers.google.com/kml/documentation/images/itemicons.jpg</href>"
" </ItemIcon>"
" <ItemIcon>"
" <state>closed</state>"
" <href>https://developers.google.com/kml/documentation/images/itemicons1.jpg</href>"
" </ItemIcon>"
" </ListStyle>"
" </Style>"
" <Folder>"
" <Placemark>"
" <name>The first placemark</name>"
" <styleUrl>#my-list-style</styleUrl>"
" <Point><coordinates>80.0,30.0</coordinates></Point>"
" </Placemark>"
" </Folder>"
"</Document>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( content );
QCOMPARE( dataDocument->folderList().size(), 1 );
GeoDataFolder *folder = dataDocument->folderList().at( 0 );
QCOMPARE( folder->size(), 1 );
GeoDataPlacemark *placemark1 = dynamic_cast<GeoDataPlacemark*>( folder->child( 0 ) );
- QVERIFY( placemark1 != 0 );
+ QVERIFY( placemark1 != nullptr );
QCOMPARE( placemark1->name(), QString( "The first placemark" ) );
QCOMPARE( placemark1->style()->listStyle().listItemType(), GeoDataListStyle::CheckOffOnly );
QCOMPARE( placemark1->style()->listStyle().backgroundColor().red(), 51 );
QCOMPARE( placemark1->style()->listStyle().itemIconList().at(0)->state(), GeoDataItemIcon::Open | GeoDataItemIcon::Error );
QCOMPARE( placemark1->style()->listStyle().itemIconList().at(0)->iconPath(), QString( "https://developers.google.com/kml/documentation/images/itemicons.jpg" ) );
QCOMPARE( placemark1->style()->listStyle().itemIconList().at(1)->state(), GeoDataItemIcon::Closed );
QCOMPARE( placemark1->style()->listStyle().itemIconList().at(1)->iconPath(), QString( "https://developers.google.com/kml/documentation/images/itemicons1.jpg" ) );
delete dataDocument;
}
QTEST_MAIN( TestListStyle )
#include "TestListStyle.moc"
diff --git a/tests/TestModel.cpp b/tests/TestModel.cpp
index 0512ad0d1..77aae6040 100644
--- a/tests/TestModel.cpp
+++ b/tests/TestModel.cpp
@@ -1,105 +1,105 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
// Copyright 2013 Sanjiban Bairagya <sanjiban22393@gmail.com>
//
#include <QObject>
#include <GeoDataDocument.h>
#include <GeoDataPlacemark.h>
#include <GeoDataOrientation.h>
#include <GeoDataScale.h>
#include <MarbleDebug.h>
#include <GeoDataModel.h>
#include <GeoDataLink.h>
#include <GeoDataLocation.h>
#include "TestUtils.h"
using namespace Marble ;
class TestModel : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestModel::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestModel::simpleParseTest()
{
QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">"
"<Placemark>"
"<Model id=\"model_4\">"
"<altitudeMode>relativeToGround</altitudeMode>"
"<Location>"
"<longitude>-105.27</longitude>"
"<latitude>40.00</latitude>"
"<altitude>23.4</altitude>"
"</Location>"
"<Orientation>"
"<heading>1</heading>"
"<tilt>2</tilt>"
"<roll>3</roll>"
"</Orientation>"
"<Scale>"
"<x>3</x>"
"<y>4</y>"
"<z>5</z>"
"</Scale>"
"<Link>"
"<href>MackyBldg.kmz/files/CU Macky.dae</href>"
"<refreshMode>onExpire</refreshMode>"
"</Link>"
"<ResourceMap id=\"resourcemap_for_model_4\">"
"<Alias>"
"<sourceHref>../files/CU-Macky-4sideturretnoCulling.jpg</sourceHref>"
"<targetHref>../files/CU-Macky-4sideturretnoCulling.jpg</targetHref>"
"</Alias>"
"</ResourceMap>"
"</Model>"
"</Placemark>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( centerContent );
QCOMPARE( dataDocument->placemarkList().size(), 1 );
GeoDataPlacemark *placemark = dataDocument->placemarkList().at( 0 );
GeoDataModel *model = dynamic_cast<GeoDataModel*>( placemark->geometry() );
- QVERIFY( model != 0 );
+ QVERIFY( model != nullptr );
QCOMPARE( model->altitudeMode(), RelativeToGround);
QCOMPARE( model->location().altitude(), 23.4);
QCOMPARE( model->location().latitude(GeoDataCoordinates::Degree), 40.00 );
QCOMPARE( model->location().longitude(GeoDataCoordinates::Degree), -105.27 );
QCOMPARE( model->orientation().heading(), 1.0);
QCOMPARE( model->orientation().tilt(), 2.0);
QCOMPARE( model->orientation().roll(), 3.0);
QCOMPARE( model->scale().x(), 3.0);
QCOMPARE( model->scale().y(), 4.0);
QCOMPARE( model->scale().z(), 5.0);
QCOMPARE( model->link().href(), QString("MackyBldg.kmz/files/CU Macky.dae"));
QCOMPARE( model->link().refreshMode(), GeoDataLink::OnExpire );
QCOMPARE( model->targetHref(), QString("../files/CU-Macky-4sideturretnoCulling.jpg"));
QCOMPARE( model->sourceHref(), QString("../files/CU-Macky-4sideturretnoCulling.jpg"));
delete dataDocument;
}
QTEST_MAIN( TestModel )
#include "TestModel.moc"
diff --git a/tests/TestNetworkLink.cpp b/tests/TestNetworkLink.cpp
index 40c472265..cb50e8190 100644
--- a/tests/TestNetworkLink.cpp
+++ b/tests/TestNetworkLink.cpp
@@ -1,83 +1,83 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Mayank Madan <maddiemadan@gmail.com>
//
#include <QObject>
#include "TestUtils.h"
#include <GeoDataDocument.h>
#include <GeoDataFolder.h>
#include <MarbleDebug.h>
#include <GeoDataNetworkLink.h>
#include <GeoDataLink.h>
using namespace Marble;
class TestNetworkLink : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestNetworkLink::initTestCase()
{
MarbleDebug::setEnabled( true );
}
void TestNetworkLink::simpleParseTest()
{
QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Folder>"
" <NetworkLink>"
" <refreshVisibility>1</refreshVisibility> <!-- boolean -->"
" <flyToView>1</flyToView> <!-- boolean -->"
" <Link>"
" <href>http://files.kde.org/marble/examples/kml/</href>"
" <refreshMode>onChange</refreshMode>"
" <refreshInterval>2.1</refreshInterval>"
" <viewRefreshMode>never</viewRefreshMode>"
" <viewRefreshTime>4.2</viewRefreshTime>"
" <viewBoundScale>1.5</viewBoundScale>"
" <viewFormat>BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]</viewFormat>"
" <httpQuery>SiteType=sw,gw,sp&amp;SiteCode=all&amp;Format=ge</httpQuery>"
" </Link>"
" </NetworkLink>"
"</Folder>"
"</kml>");
GeoDataDocument* dataDocument = parseKml( centerContent );
QCOMPARE( dataDocument->folderList().size(), 1 );
GeoDataFolder *folder = dataDocument->folderList().at( 0 );
QCOMPARE( folder->size(), 1 );
GeoDataNetworkLink *networkLink = dynamic_cast<GeoDataNetworkLink*>( folder->child( 0 ) );
- QVERIFY( networkLink != 0 );
+ QVERIFY( networkLink != nullptr );
QCOMPARE( networkLink->refreshVisibility(), true );
QCOMPARE( networkLink->flyToView(), true );
QCOMPARE( networkLink->link().href(), QString("http://files.kde.org/marble/examples/kml/") );
QCOMPARE( networkLink->link().refreshMode(), GeoDataLink::OnChange );
QFUZZYCOMPARE( networkLink->link().refreshInterval(), 2.1, 0.0001 );
QCOMPARE( networkLink->link().viewRefreshMode(), GeoDataLink::Never);
QFUZZYCOMPARE( networkLink->link().viewRefreshTime(), 4.2, 0.0001 );
QFUZZYCOMPARE( networkLink->link().viewBoundScale(), 1.5, 0.0001 );
QCOMPARE( networkLink->link().viewFormat(), QString("BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]") );
QCOMPARE( networkLink->link().httpQuery(), QString("SiteType=sw,gw,sp&SiteCode=all&Format=ge"));
}
QTEST_MAIN( TestNetworkLink )
#include "TestNetworkLink.moc"
diff --git a/tests/TestTour.cpp b/tests/TestTour.cpp
index 3bcda4748..9b3da0bba 100644
--- a/tests/TestTour.cpp
+++ b/tests/TestTour.cpp
@@ -1,137 +1,137 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2013 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
//
#include <GeoDataParser.h>
#include <GeoDataDocument.h>
#include <GeoDataUpdate.h>
#include <GeoDataTour.h>
#include <GeoDataPlaylist.h>
#include <GeoDataTourControl.h>
#include <MarbleDebug.h>
#include <GeoDataFolder.h>
#include <GeoDataAnimatedUpdate.h>
#include <QObject>
#include <QBuffer>
#include <QTest>
using namespace Marble;
class TestTour : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void simpleParseTest();
};
void TestTour::initTestCase()
{
MarbleDebug::setEnabled( true );
}
GeoDataDocument *parseKml(const QString &content)
{
GeoDataParser parser( GeoData_KML );
QByteArray array( content.toUtf8() );
QBuffer buffer( &array );
buffer.open( QIODevice::ReadOnly );
//qDebug() << "Buffer content:" << endl << buffer.buffer();
if ( !parser.read( &buffer ) ) {
qFatal( "Could not parse data!" );
}
GeoDocument* document = parser.releaseDocument();
Q_ASSERT( document );
return static_cast<GeoDataDocument*>( document );
}
void TestTour::simpleParseTest()
{
QString const centerContent (
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://www.opengis.net/kml/2.2\""
" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">"
"<Folder>"
" <gx:Tour>"
" <name>My Tour</name>"
" <description>This is my tour.</description>"
" </gx:Tour>"
" <gx:Tour id=\"tourId\">"
" <gx:Playlist>"
" <gx:TourControl id=\"space\">"
" <gx:playMode>pause</gx:playMode>"
" </gx:TourControl>"
" </gx:Playlist>"
" </gx:Tour>"
" <gx:Tour id=\"animUpd\">"
" <name>TourAnim</name>"
" <description>Tour with AnimatedUpdate</description>"
" <gx:Playlist>"
" <gx:AnimatedUpdate>"
" <gx:duration>5.0</gx:duration>"
" <Update>"
" <targetHref>Whatever.jpg</targetHref>"
" </Update>"
" </gx:AnimatedUpdate>"
" </gx:Playlist>"
" </gx:Tour>"
"</Folder>"
"</kml>" );
GeoDataDocument* dataDocument = parseKml( centerContent );
QCOMPARE( dataDocument->folderList().size(), 1 );
GeoDataFolder *folder = dataDocument->folderList().at( 0 );
GeoDataTour *tour_1 = dynamic_cast<GeoDataTour*>(folder->child(0));
GeoDataTour *tour_2 = dynamic_cast<GeoDataTour*>(folder->child(1));
GeoDataTour *tour_3 = dynamic_cast<GeoDataTour*>(folder->child(2));
- QVERIFY(tour_1 != 0);
- QVERIFY(tour_2 != 0);
- QVERIFY(tour_3 != 0);
+ QVERIFY(tour_1 != nullptr);
+ QVERIFY(tour_2 != nullptr);
+ QVERIFY(tour_3 != nullptr);
QCOMPARE(tour_1->id(), QString(""));
QCOMPARE(tour_1->name(), QString("My Tour"));
QCOMPARE(tour_1->description(), QString("This is my tour."));
QCOMPARE(tour_2->id(), QString("tourId"));
QCOMPARE(tour_2->name(), QString());
QCOMPARE(tour_2->description(), QString());
QCOMPARE(tour_3->id(), QString("animUpd"));
QCOMPARE(tour_3->name(), QString("TourAnim"));
QCOMPARE(tour_3->description(), QString("Tour with AnimatedUpdate"));
GeoDataPlaylist *playlist = tour_2->playlist();
- QVERIFY(playlist != 0);
+ QVERIFY(playlist != nullptr);
GeoDataTourControl *control = dynamic_cast<GeoDataTourControl*>(
playlist->primitive(0));
- QVERIFY(control != 0);
+ QVERIFY(control != nullptr);
QCOMPARE(control->id(), QString("space"));
QCOMPARE(control->playMode(), GeoDataTourControl::Pause);
GeoDataPlaylist *playlist2 = tour_3->playlist();
- QVERIFY(playlist2 != 0);
+ QVERIFY(playlist2 != nullptr);
GeoDataAnimatedUpdate *update = dynamic_cast<GeoDataAnimatedUpdate*>(playlist2->primitive(0));
- QVERIFY(update != 0);
+ QVERIFY(update != nullptr);
QCOMPARE(update->duration(),5.0);
QCOMPARE(update->update()->targetHref(),QString("Whatever.jpg"));
delete dataDocument;
}
QTEST_MAIN( TestTour )
#include "TestTour.moc"
diff --git a/tools/mapreproject/BilinearInterpolation.h b/tools/mapreproject/BilinearInterpolation.h
index ba774e2cb..06359d3d9 100644
--- a/tools/mapreproject/BilinearInterpolation.h
+++ b/tools/mapreproject/BilinearInterpolation.h
@@ -1,16 +1,16 @@
#ifndef BILINEARINTERPOLATION_H
#define BILINEARINTERPOLATION_H
#include "InterpolationMethod.h"
class ReadOnlyMapImage;
class BilinearInterpolation: public InterpolationMethod
{
public:
- explicit BilinearInterpolation( ReadOnlyMapImage * const mapImage = NULL );
+ explicit BilinearInterpolation( ReadOnlyMapImage * const mapImage = nullptr );
QRgb interpolate( double const x, double const y ) override;
};
#endif
diff --git a/tools/mapreproject/IntegerInterpolation.h b/tools/mapreproject/IntegerInterpolation.h
index 8058878af..dc9b853bd 100644
--- a/tools/mapreproject/IntegerInterpolation.h
+++ b/tools/mapreproject/IntegerInterpolation.h
@@ -1,16 +1,16 @@
#ifndef INTEGERINTERPOLATION_H
#define INTEGERINTERPOLATION_H
#include "InterpolationMethod.h"
class ReadOnlyMapImage;
class IntegerInterpolation: public InterpolationMethod
{
public:
- explicit IntegerInterpolation( ReadOnlyMapImage * const mapImage = NULL );
+ explicit IntegerInterpolation( ReadOnlyMapImage * const mapImage = nullptr );
QRgb interpolate( double const x, double const y ) override;
};
#endif
diff --git a/tools/mapreproject/NasaWorldWindToOpenStreetMapConverter.h b/tools/mapreproject/NasaWorldWindToOpenStreetMapConverter.h
index a5af41ac8..1ce1d8a44 100644
--- a/tools/mapreproject/NasaWorldWindToOpenStreetMapConverter.h
+++ b/tools/mapreproject/NasaWorldWindToOpenStreetMapConverter.h
@@ -1,60 +1,60 @@
#ifndef NASAWORLDWINDTOOPENSTREETMAPCONVERTER_H
#define NASAWORLDWINDTOOPENSTREETMAPCONVERTER_H
#include "mapreproject.h"
#include "ReadOnlyMapDefinition.h"
#include <QDir>
#include <QObject>
#include <QPair>
#include <QVector>
class OsmTileClusterRenderer;
class Thread;
// Abbreviations used:
// Nww, nww: NASA WorldWind
// Osm, osm: OpenStreetMap
// Lon, lon: Longitude
// Lat, lat: Latitude
// Rad, rad: Radiant
class NasaWorldWindToOpenStreetMapConverter: public QObject
{
Q_OBJECT
public:
- explicit NasaWorldWindToOpenStreetMapConverter( QObject * const parent = NULL );
+ explicit NasaWorldWindToOpenStreetMapConverter( QObject * const parent = nullptr );
void setMapSources( QVector<ReadOnlyMapDefinition> const & mapSources );
void setOsmBaseDirectory( QDir const & nwwBaseDirectory );
void setOsmTileClusterEdgeLengthTiles( int const clusterEdgeLengthTiles );
void setOsmTileLevel( int const level );
void setThreadCount( int const threadCount );
QVector<QPair<Thread*, OsmTileClusterRenderer*> > start();
void testReprojection();
Q_SIGNALS:
void finished();
public Q_SLOTS:
void assignNextCluster( OsmTileClusterRenderer * );
private:
void checkAndCreateLevelDirectory() const;
void incNextCluster();
int m_threadCount;
QVector<ReadOnlyMapDefinition> m_mapSources;
QDir m_osmBaseDirectory;
int m_osmTileLevel;
int m_osmTileClusterEdgeLengthTiles;
int m_osmMapEdgeLengthClusters;
int m_nextClusterX;
int m_nextClusterY;
};
#endif
diff --git a/tools/mapreproject/NearestNeighborInterpolation.h b/tools/mapreproject/NearestNeighborInterpolation.h
index 5015634f0..fc0b566ac 100644
--- a/tools/mapreproject/NearestNeighborInterpolation.h
+++ b/tools/mapreproject/NearestNeighborInterpolation.h
@@ -1,16 +1,16 @@
#ifndef NEARESTNEIGHBORINTERPOLATION_H
#define NEARESTNEIGHBORINTERPOLATION_H
#include "InterpolationMethod.h"
class ReadOnlyMapImage;
class NearestNeighborInterpolation: public InterpolationMethod
{
public:
- explicit NearestNeighborInterpolation( ReadOnlyMapImage * const mapImage = NULL );
+ explicit NearestNeighborInterpolation( ReadOnlyMapImage * const mapImage = nullptr );
QRgb interpolate( double const x, double const y ) override;
};
#endif
diff --git a/tools/mapreproject/OsmTileClusterRenderer.h b/tools/mapreproject/OsmTileClusterRenderer.h
index 449478bc6..6eeffcdc3 100644
--- a/tools/mapreproject/OsmTileClusterRenderer.h
+++ b/tools/mapreproject/OsmTileClusterRenderer.h
@@ -1,52 +1,52 @@
#ifndef OSMTILECLUSTERRENDERER_H
#define OSMTILECLUSTERRENDERER_H
#include "mapreproject.h"
#include "ReadOnlyMapDefinition.h"
#include <QDir>
#include <QObject>
#include <QVector>
#include <QImage>
class ReadOnlyMapImage;
class OsmTileClusterRenderer: public QObject
{
Q_OBJECT
public:
- explicit OsmTileClusterRenderer( QObject * const parent = NULL );
+ explicit OsmTileClusterRenderer( QObject * const parent = nullptr );
void setClusterEdgeLengthTiles( int const clusterEdgeLengthTiles );
void setMapSources( QVector<ReadOnlyMapDefinition> const & mapSources );
void setOsmBaseDirectory( QDir const & osmBaseDirectory );
void setOsmTileLevel( int const level );
Q_SIGNALS:
void clusterRendered( OsmTileClusterRenderer * );
public Q_SLOTS:
void initMapSources();
void renderOsmTileCluster( int const clusterX, int const clusterY );
private:
QDir checkAndCreateDirectory( int const tileX ) const;
QImage renderOsmTile( int const tileX, int const tileY );
double osmPixelXtoLonRad( int const pixelX ) const;
double osmPixelYtoLatRad( int const pixelY ) const;
int const m_osmTileEdgeLengthPixel;
QRgb const m_emptyPixel;
QDir m_osmBaseDirectory;
int m_osmTileLevel;
int m_osmMapEdgeLengthPixel;
int m_clusterEdgeLengthTiles;
QVector<ReadOnlyMapDefinition> m_mapSourceDefinitions;
QVector<ReadOnlyMapImage*> m_mapSources;
int m_mapSourceCount;
};
#endif
diff --git a/tools/mapreproject/ReadOnlyMapDefinition.cpp b/tools/mapreproject/ReadOnlyMapDefinition.cpp
index e2f3994ce..a3633839f 100644
--- a/tools/mapreproject/ReadOnlyMapDefinition.cpp
+++ b/tools/mapreproject/ReadOnlyMapDefinition.cpp
@@ -1,58 +1,58 @@
#include "ReadOnlyMapDefinition.h"
#include "BilinearInterpolation.h"
#include "IntegerInterpolation.h"
#include "NearestNeighborInterpolation.h"
#include "NwwMapImage.h"
#include "SimpleMapImage.h"
ReadOnlyMapDefinition::ReadOnlyMapDefinition()
: m_mapType( UnknownMapSource ),
m_interpolationMethod( UnknownInterpolationMethod ),
m_baseDirectory(),
m_tileLevel( -1 ),
m_cacheSizeBytes(),
m_filename()
{
}
InterpolationMethod * ReadOnlyMapDefinition::createInterpolationMethod() const
{
switch ( m_interpolationMethod ) {
case IntegerInterpolationMethod:
return new IntegerInterpolation;
case NearestNeighborInterpolationMethod:
return new NearestNeighborInterpolation;
case AverageInterpolationMethod:
- return NULL;
+ return nullptr;
case BilinearInterpolationMethod:
return new BilinearInterpolation;
default:
- return NULL;
+ return nullptr;
}
}
ReadOnlyMapImage * ReadOnlyMapDefinition::createReadOnlyMap() const
{
InterpolationMethod * const interpolationMethod = createInterpolationMethod();
if ( !interpolationMethod )
qFatal( "Unsupported interpolation method: '%i'", m_interpolationMethod );
if ( m_mapType == NasaWorldWindMap ) {
NwwMapImage * const mapImage = new NwwMapImage( m_baseDirectory, m_tileLevel );
interpolationMethod->setMapImage( mapImage );
mapImage->setInterpolationMethod( interpolationMethod );
mapImage->setCacheSizeBytes( m_cacheSizeBytes );
return mapImage;
}
else if ( m_mapType == BathymetryMap ) {
SimpleMapImage * const mapImage = new SimpleMapImage( m_filename );
interpolationMethod->setMapImage( mapImage );
mapImage->setInterpolationMethod( interpolationMethod );
return mapImage;
}
else {
delete interpolationMethod;
- return NULL;
+ return nullptr;
}
}
diff --git a/tools/mapreproject/Thread.h b/tools/mapreproject/Thread.h
index c3b319902..d94438cc0 100644
--- a/tools/mapreproject/Thread.h
+++ b/tools/mapreproject/Thread.h
@@ -1,75 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef THREAD_H
#define THREAD_H
#include <QMutex>
#include <QThread>
#include <QWaitCondition>
class QSignalMapper;
class Thread: public QThread
{
Q_OBJECT
public:
- explicit Thread( QObject * const parent = NULL );
+ explicit Thread( QObject * const parent = nullptr );
~Thread() override;
void launchWorker( QObject * const worker );
void stop();
Q_SIGNALS:
void aboutToStop();
private Q_SLOTS:
void stopExecutor();
void setReadyStatus();
private:
QObject * m_worker;
QSignalMapper * m_shutDownHelper;
QWaitCondition m_waitCondition;
QMutex m_mutex;
};
#endif
diff --git a/tools/mapreproject/main.cpp b/tools/mapreproject/main.cpp
index d063a9b82..5ad3c983b 100644
--- a/tools/mapreproject/main.cpp
+++ b/tools/mapreproject/main.cpp
@@ -1,281 +1,281 @@
#include "BilinearInterpolation.h"
#include "NasaWorldWindToOpenStreetMapConverter.h"
#include "NearestNeighborInterpolation.h"
#include "OsmTileClusterRenderer.h"
#include "ReadOnlyMapDefinition.h"
#include "Thread.h"
#include "mapreproject.h"
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QPair>
#include <QThread>
#include <QVector>
#include <getopt.h>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
/* example usage
mapreproject --simulate --output-directory=/home/jmho --jobs 7 --cluster-size 64 --output-tile-level=10 \
--input=type=NasaWW,base-directory=/home,tile-level=8,interpolation-method=bilinear,cache-size=200000000 \
--input type=Bathymetry,file=BLAH.tiff
*/
void printUsage()
{
std::cout << "Usage: mapreproject [OPTIONS] [INPUT] ...\n"
" --help display this help and exit\n"
" --output-directory output base directory, where the resulting tiles will be stored\n"
" --output-tile-level tile level of resulting map\n"
" --cluster-size edge length of tile clusters in tiles\n"
" --jobs number of threads, use to override default of one thread per cpu core\n"
" --simulate \n"
" --input INPUT_OPTS INPUT_OPTS can be a combination of the following options, separated by comma:\n"
" type \n"
" base-directory \n"
" tile-level \n"
" cache-size \n"
" file \n"
" interpolation-method one of \"integer\", \"nearest-neighbor\" (default), \"average\" or \"bilinear\"\n";
}
MapSourceType parseType( char const * const value )
{
MapSourceType result = UnknownMapSource;
if ( !value )
qFatal("Suboption 'type' does not have a value.");
if ( strcmp( value, "NasaWW") == 0 )
result = NasaWorldWindMap;
else if ( strcmp( value, "Bathymetry" ) == 0 )
result = BathymetryMap;
else
qFatal("Suboption 'type': Unrecognized value '%s'.", value );
return result;
}
QString parseString( char const * const value )
{
QString result;
if ( !value )
qFatal("Suboption does not have a value.");
result = value;
return result;
}
int parseInt( char const * const value )
{
if ( !value )
qFatal("Suboption does not have a value.");
QString str( value );
bool ok;
int const result = str.toInt( &ok );
if ( !ok )
qFatal("Suboption does not have an integer value.");
return result;
}
EInterpolationMethod parseInterpolationMethod( char const * const value )
{
EInterpolationMethod result = UnknownInterpolationMethod;
if ( !value )
qFatal("Suboption 'interpolation-method' does not have a value.");
if ( strcmp( value, "integer") == 0 )
result = IntegerInterpolationMethod;
if ( strcmp( value, "nearest-neighbor") == 0 )
result = NearestNeighborInterpolationMethod;
if ( strcmp( value, "average") == 0 )
result = AverageInterpolationMethod;
else if ( strcmp( value, "bilinear" ) == 0 )
result = BilinearInterpolationMethod;
else
qFatal("Suboption 'interpolation-method': Unrecognized value '%s'.", value );
return result;
}
ReadOnlyMapDefinition parseInput( char * subopts )
{
if ( !subopts )
qFatal("Missing argument for '--input'");
enum
{
TypeOption = 0,
BaseDirectoryOption,
FileOption,
TileLevelOption,
InterpolationOption,
CacheSizeOption,
TheEnd
};
char optionType[] = "type";
char optionBaseDirectory[] = "base-directory";
char optionFile[] = "file";
char optionTileLevel[] = "tile-level";
char optionInterpolationMethod[] = "interpolation-method";
char optionCacheSize[] = "cache-size";
char * const input_opts[] =
{
optionType,
optionBaseDirectory,
optionFile,
optionTileLevel,
optionInterpolationMethod,
optionCacheSize,
- NULL
+ nullptr
};
ReadOnlyMapDefinition mapDefinition;
char * value;
while ( *subopts != '\0' ) {
switch ( getsubopt( &subopts, input_opts, &value )) {
case TypeOption:
mapDefinition.setMapType( parseType( value ));
break;
case BaseDirectoryOption:
mapDefinition.setBaseDirectory( parseString( value ));
break;
case FileOption:
mapDefinition.setFileName( parseString( value ));
break;
case TileLevelOption:
mapDefinition.setTileLevel( parseInt( value ));
break;
case InterpolationOption:
mapDefinition.setInterpolationMethod( parseInterpolationMethod( value ));
break;
case CacheSizeOption:
mapDefinition.setCacheSizeBytes( parseInt( value ));
break;
default:
qFatal("Unrecognized input suboption.");
}
}
return mapDefinition;
}
int main( int argc, char *argv[] )
{
QCoreApplication app( argc, argv );
// --interpolation-method=NearestNeighbor|Bilinear
QString outputDirectory;
int outputTileLevel = -1;
int threadCount = QThread::idealThreadCount();
int clusterSize = 0; // cluster size 0 makes no sense
bool onlySimulate = false;
QVector<ReadOnlyMapDefinition> mapSources;
// input: type, tile-level, base-dir|file
// --input,type=NasaWW,tile-level=8,base-directory=<dir>,interpolation-method=Bilinear
// --input,type=Image,file=<file>
enum { HelpOption = 1,
InputOption,
OutputDirectoryOption,
OutputTileLevelOption,
JobsOption,
ClusterSizeOption,
SimulateOption };
static struct option long_options[] = {
- {"help", no_argument, NULL, HelpOption },
- {"input", required_argument, NULL, InputOption },
- {"output-directory", required_argument, NULL, OutputDirectoryOption },
- {"output-tile-level", required_argument, NULL, OutputTileLevelOption },
- {"jobs", required_argument, NULL, JobsOption },
- {"cluster-size", required_argument, NULL, ClusterSizeOption },
- {"simulate", no_argument, NULL, SimulateOption },
- {0, 0, 0, 0 }
+ {"help", no_argument, nullptr, HelpOption },
+ {"input", required_argument, nullptr, InputOption },
+ {"output-directory", required_argument, nullptr, OutputDirectoryOption },
+ {"output-tile-level", required_argument, nullptr, OutputTileLevelOption },
+ {"jobs", required_argument, nullptr, JobsOption },
+ {"cluster-size", required_argument, nullptr, ClusterSizeOption },
+ {"simulate", no_argument, nullptr, SimulateOption },
+ {nullptr, 0, nullptr, 0 }
};
while ( true ) {
int option_index = 0;
int const opt = getopt_long( argc, argv, "", long_options, &option_index );
if ( opt == -1 )
break;
switch ( opt ) {
case HelpOption:
printUsage();
exit( EXIT_SUCCESS );
case InputOption:
mapSources.push_back( parseInput( optarg ));
break;
case OutputDirectoryOption:
outputDirectory = parseString( optarg );
break;
case OutputTileLevelOption:
outputTileLevel = parseInt( optarg );
break;
case JobsOption:
threadCount = parseInt( optarg );
break;
case ClusterSizeOption:
clusterSize = parseInt( optarg );
break;
case SimulateOption:
onlySimulate = true;
break;
case '?':
break;
}
}
qDebug() << "\noutput directory:" << outputDirectory
<< "\noutput tile level:" << outputTileLevel
<< "\ncluster size:" << clusterSize
<< "\nthreads:" << threadCount
<< "\ninputs:" << mapSources;
if (onlySimulate)
exit( EXIT_SUCCESS );
NasaWorldWindToOpenStreetMapConverter converter;
converter.setMapSources( mapSources );
converter.setOsmBaseDirectory( QDir( outputDirectory ));
converter.setOsmTileLevel( outputTileLevel );
converter.setOsmTileClusterEdgeLengthTiles( clusterSize );
converter.setThreadCount( threadCount );
QObject::connect( &converter, SIGNAL(finished()), &app, SLOT(quit()));
QVector<QPair<Thread*, OsmTileClusterRenderer*> > renderThreads = converter.start();
app.exec();
QVector<QPair<Thread*, OsmTileClusterRenderer*> >::iterator pos = renderThreads.begin();
QVector<QPair<Thread*, OsmTileClusterRenderer*> >::iterator const end = renderThreads.end();
for (; pos != end; ++pos ) {
(*pos).first->stop();
(*pos).first->wait();
delete (*pos).second;
}
return EXIT_SUCCESS;
}
diff --git a/tools/osm-addresses/OsmParser.cpp b/tools/osm-addresses/OsmParser.cpp
index f892285c6..762794f25 100644
--- a/tools/osm-addresses/OsmParser.cpp
+++ b/tools/osm-addresses/OsmParser.cpp
@@ -1,760 +1,760 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "OsmParser.h"
#include "OsmRegionTree.h"
#include "GeoDataLatLonAltBox.h"
#include "GeoDataLinearRing.h"
#include "GeoDataLineString.h"
#include "GeoDataPolygon.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataMultiGeometry.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "GeoDataLineStyle.h"
#include "geodata/writer/GeoDataDocumentWriter.h"
#include <GeoDataExtendedData.h>
#include <GeoDataData.h>
#include <geodata/handlers/kml/KmlElementDictionary.h>
#include <QDebug>
#include <QTime>
namespace Marble
{
using namespace Oxygen;
namespace {
struct GrahamScanHelper {
Coordinate coordinate;
qreal direction;
GrahamScanHelper( const Coordinate &coordinate_=Coordinate(), qreal direction_=0.0 )
: coordinate( coordinate_ ), direction( direction_ )
{
// nothing to do
}
double turnDirection( const GrahamScanHelper &two, const GrahamScanHelper &three )
{
return ( two.coordinate.lat - coordinate.lat ) * ( three.coordinate.lon - coordinate.lon )
- ( two.coordinate.lon - coordinate.lon ) * ( three.coordinate.lat - coordinate.lat );
}
static bool directionLessThan( const GrahamScanHelper &one, const GrahamScanHelper &two )
{
return one.direction < two.direction;
}
};
}
bool moreImportantAdminArea( const OsmRegion &a, const OsmRegion& b )
{
return a.adminLevel() < b.adminLevel();
}
OsmParser::OsmParser( QObject *parent ) :
- QObject( parent ), m_convexHull( 0 )
+ QObject( parent ), m_convexHull( nullptr )
{
m_categoryMap["tourism/camp_site"] = OsmPlacemark::AccomodationCamping;
m_categoryMap["tourism/hostel"] = OsmPlacemark::AccomodationHostel;
m_categoryMap["tourism/hotel"] = OsmPlacemark::AccomodationHotel;
m_categoryMap["tourism/motel"] = OsmPlacemark::AccomodationMotel;
//m_categoryMap["/"] = OsmPlacemark::AccomodationYouthHostel;
m_categoryMap["amenity/library"] = OsmPlacemark::AmenityLibrary;
m_categoryMap["amenity/college"] = OsmPlacemark::EducationCollege;
m_categoryMap["amenity/school"] = OsmPlacemark::EducationSchool;
m_categoryMap["amenity/university"] = OsmPlacemark::EducationUniversity;
m_categoryMap["amenity/bar"] = OsmPlacemark::FoodBar;
m_categoryMap["amenity/biergarten"] = OsmPlacemark::FoodBiergarten;
m_categoryMap["amenity/cafe"] = OsmPlacemark::FoodCafe;
m_categoryMap["amenity/fast_food"] = OsmPlacemark::FoodFastFood;
m_categoryMap["amenity/pub"] = OsmPlacemark::FoodPub;
m_categoryMap["amenity/restaurant"] = OsmPlacemark::FoodRestaurant;
m_categoryMap["amenity/doctor"] = OsmPlacemark::HealthDoctors;
m_categoryMap["amenity/doctors"] = OsmPlacemark::HealthDoctors;
m_categoryMap["amenity/hospital"] = OsmPlacemark::HealthHospital;
m_categoryMap["amenity/pharmacy"] = OsmPlacemark::HealthPharmacy;
m_categoryMap["amenity/atm"] = OsmPlacemark::MoneyAtm;
m_categoryMap["amenity/bank"] = OsmPlacemark::MoneyBank;
m_categoryMap["shop/beverages"] = OsmPlacemark::ShoppingBeverages;
m_categoryMap["shop/hifi"] = OsmPlacemark::ShoppingHifi;
m_categoryMap["shop/supermarket"] = OsmPlacemark::ShoppingSupermarket;
m_categoryMap["tourism/attraction"] = OsmPlacemark::TouristAttraction;
m_categoryMap["tourism/castle"] = OsmPlacemark::TouristCastle;
m_categoryMap["amenity/cinema"] = OsmPlacemark::TouristCinema;
m_categoryMap["tourism/monument"] = OsmPlacemark::TouristMonument;
m_categoryMap["tourism/museum"] = OsmPlacemark::TouristMuseum;
m_categoryMap["historic/ruins"] = OsmPlacemark::TouristRuin;
m_categoryMap["amenity/theatre"] = OsmPlacemark::TouristTheatre;
m_categoryMap["tourism/theme_park"] = OsmPlacemark::TouristThemePark;
m_categoryMap["tourism/viewpoint"] = OsmPlacemark::TouristViewPoint;
m_categoryMap["tourism/zoo"] = OsmPlacemark::TouristZoo;
m_categoryMap["aeroway/aerodrome"] = OsmPlacemark::TransportAirport;
m_categoryMap["aeroway/terminal"] = OsmPlacemark::TransportAirportTerminal;
m_categoryMap["amenity/bus_station"] = OsmPlacemark::TransportBusStation;
m_categoryMap["highway/bus_stop"] = OsmPlacemark::TransportBusStop;
m_categoryMap["highway/speed_camera"] = OsmPlacemark::TransportSpeedCamera;
m_categoryMap["amenity/car_sharing"] = OsmPlacemark::TransportCarShare;
m_categoryMap["amenity/car_rental"] = OsmPlacemark::TransportRentalCar;
m_categoryMap["amenity/bicycle_rental"] = OsmPlacemark::TransportRentalBicycle;
m_categoryMap["amenity/fuel"] = OsmPlacemark::TransportFuel;
m_categoryMap["amenity/parking"] = OsmPlacemark::TransportParking;
m_categoryMap["amenity/taxi"] = OsmPlacemark::TransportTaxiRank;
m_categoryMap["railway/station"] = OsmPlacemark::TransportTrainStation;
m_categoryMap["railway/tram_stop"] = OsmPlacemark::TransportTramStop;
}
void OsmParser::addWriter( Writer* writer )
{
m_writers.push_back( writer );
}
Node::operator OsmPlacemark() const
{
OsmPlacemark placemark;
placemark.setCategory( category );
placemark.setName( name.trimmed() );
placemark.setHouseNumber( houseNumber.trimmed() );
placemark.setLongitude( lon );
placemark.setLatitude( lat );
return placemark;
}
Node::operator Coordinate() const
{
Coordinate coordinate;
coordinate.lon = lon;
coordinate.lat = lat;
return coordinate;
}
Way::operator OsmPlacemark() const
{
OsmPlacemark placemark;
placemark.setCategory( category );
placemark.setName( name.trimmed() );
placemark.setHouseNumber( houseNumber.trimmed() );
return placemark;
}
void Way::setPosition( const QHash<int, Coordinate> &database, OsmPlacemark &placemark ) const
{
if ( !nodes.isEmpty() ) {
if ( nodes.first() == nodes.last() && database.contains( nodes.first() ) ) {
GeoDataLinearRing ring;
for( int id: nodes ) {
if ( database.contains( id ) ) {
const Coordinate &node = database[id];
GeoDataCoordinates coordinates( node.lon, node.lat, 0.0, GeoDataCoordinates::Degree );
ring << coordinates;
} else {
qDebug() << "Missing node " << id << " in database";
}
}
if ( !ring.isEmpty() ) {
GeoDataCoordinates center = ring.latLonAltBox().center();
placemark.setLongitude( center.longitude( GeoDataCoordinates::Degree ) );
placemark.setLatitude( center.latitude( GeoDataCoordinates::Degree ) );
}
} else {
int id = nodes.at( nodes.size() / 2 );
if ( database.contains( id ) ) {
const Coordinate &node = database[id];
placemark.setLongitude( node.lon );
placemark.setLatitude( node.lat );
}
}
}
}
void Way::setRegion( const QHash<int, Node> &database, const OsmRegionTree & tree, QList<OsmOsmRegion> & osmOsmRegions, OsmPlacemark &placemark ) const
{
if ( !city.isEmpty() ) {
for( const OsmOsmRegion & region: osmOsmRegions ) {
if ( region.region.name() == city ) {
placemark.setRegionId( region.region.identifier() );
return;
}
}
for( const Node & node: database ) {
if ( node.category >= OsmPlacemark::PlacesRegion &&
node.category <= OsmPlacemark::PlacesIsland &&
node.name == city ) {
qDebug() << "Creating a new implicit region from " << node.name << " at " << node.lon << "," << node.lat;
OsmOsmRegion region;
region.region.setName( city );
region.region.setLongitude( node.lon );
region.region.setLatitude( node.lat );
placemark.setRegionId( region.region.identifier() );
osmOsmRegions.push_back( region );
return;
}
}
qDebug() << "Unable to locate city " << city << ", setting it up without coordinates";
OsmOsmRegion region;
region.region.setName( city );
placemark.setRegionId( region.region.identifier() );
osmOsmRegions.push_back( region );
return;
}
GeoDataCoordinates position( placemark.longitude(), placemark.latitude(), 0.0, GeoDataCoordinates::Degree );
placemark.setRegionId( tree.smallestRegionId( position ) );
}
void OsmParser::read( const QFileInfo &content, const QString &areaName )
{
QTime timer;
timer.start();
m_nodes.clear();
m_ways.clear();
m_relations.clear();
m_placemarks.clear();
m_osmOsmRegions.clear();
int pass = 0;
bool needAnotherPass = false;
do {
qWarning() << "Step 1." << pass << ": Parsing input file " << content.fileName();
parse( content, pass++, needAnotherPass );
}
while ( needAnotherPass );
qWarning() << "Step 2: " << m_coordinates.size() << "coordinates."
<< "Now extracting regions from" << m_relations.size() << "relations";
QHash<int, Relation>::iterator itpoint = m_relations.begin();
QHash<int, Relation>::iterator const endpoint = m_relations.end();
for(; itpoint != endpoint; ++itpoint ) {
if ( itpoint.value().isAdministrativeBoundary /*&& relation.isMultipolygon*/ ) {
importMultipolygon( itpoint.value() );
if ( !itpoint.value().relations.isEmpty() ) {
qDebug() << "Ignoring relations inside the relation " << itpoint.value().name;
}
}
}
m_relations.clear();
for ( int i = 0; i < m_osmOsmRegions.size(); ++i ) {
OsmOsmRegion &osmOsmRegion = m_osmOsmRegions[i];
GeoDataCoordinates center = osmOsmRegion.region.geometry().latLonAltBox().center();
osmOsmRegion.region.setLongitude( center.longitude( GeoDataCoordinates::Degree ) );
osmOsmRegion.region.setLatitude( center.latitude( GeoDataCoordinates::Degree ) );
}
qWarning() << "Step 3: Creating region hierarchies from" << m_osmOsmRegions.size() << "administrative boundaries";
QMultiMap<int,int> sortedRegions;
for ( int i = 0; i < m_osmOsmRegions.size(); ++i ) {
sortedRegions.insert( m_osmOsmRegions[i].region.adminLevel(), i );
}
for ( int i = 0; i < m_osmOsmRegions.size(); ++i ) {
GeoDataLinearRing const & ring = m_osmOsmRegions[i].region.geometry().outerBoundary();
- OsmOsmRegion* parent = 0;
+ OsmOsmRegion* parent = nullptr;
qDebug() << "Examining admin region " << i << " of " << m_osmOsmRegions.count();
- for ( int level=m_osmOsmRegions[i].region.adminLevel()-1; level >= 0 && parent == 0; --level ) {
+ for ( int level=m_osmOsmRegions[i].region.adminLevel()-1; level >= 0 && parent == nullptr; --level ) {
QList<int> candidates = sortedRegions.values( level );
qDebug() << "Examining " << candidates.count() << "admin regions on level" << level;
for( int j: candidates ) {
GeoDataLinearRing const & outer = m_osmOsmRegions[j].region.geometry().outerBoundary();
if ( contains<GeoDataLinearRing, GeoDataLinearRing>( outer, ring ) ) {
- if ( parent == 0 || contains<GeoDataLinearRing, GeoDataLinearRing>( parent->region.geometry().outerBoundary(), outer ) ) {
+ if ( parent == nullptr || contains<GeoDataLinearRing, GeoDataLinearRing>( parent->region.geometry().outerBoundary(), outer ) ) {
qDebug() << "Parent found: " << m_osmOsmRegions[i].region.name() << ", level " << m_osmOsmRegions[i].region.adminLevel()
<< "is a child of " << m_osmOsmRegions[j].region.name() << ", level " << m_osmOsmRegions[j].region.adminLevel();
parent = &m_osmOsmRegions[j];
break;
}
}
}
}
m_osmOsmRegions[i].parent = parent;
}
for ( int i = 0; i < m_osmOsmRegions.size(); ++i ) {
int const parent = m_osmOsmRegions[i].parent ? m_osmOsmRegions[i].parent->region.identifier() : 0;
m_osmOsmRegions[i].region.setParentIdentifier( parent );
}
OsmRegion mainArea;
mainArea.setIdentifier( 0 );
mainArea.setName( areaName );
mainArea.setAdminLevel( 1 );
QPair<float, float> minLon( -180.0, 180.0 ), minLat( -90.0, 90.0 );
for( const Coordinate & node: m_coordinates ) {
minLon.first = qMin( node.lon, minLon.first );
minLon.second = qMax( node.lon, minLon.second );
minLat.first = qMin( node.lat, minLat.first );
minLat.second = qMax( node.lat, minLat.second );
}
GeoDataLatLonBox center( minLat.second, minLat.first,
minLon.second, minLon.first );
mainArea.setLongitude( center.center().longitude( GeoDataCoordinates::Degree ) );
mainArea.setLatitude( center.center().latitude( GeoDataCoordinates::Degree ) );
QList<OsmRegion> regions;
for( const OsmOsmRegion & region: m_osmOsmRegions ) {
regions << region.region;
}
std::sort( regions.begin(), regions.end(), moreImportantAdminArea );
OsmRegionTree regionTree( mainArea );
regionTree.append( regions );
Q_ASSERT( regions.isEmpty() );
int left = 0;
regionTree.traverse( left );
qWarning() << "Step 4: Creating placemarks from" << m_nodes.size() << "nodes";
for( const Node & node: m_nodes ) {
if ( node.save ) {
OsmPlacemark placemark = node;
GeoDataCoordinates position( node.lon, node.lat, 0.0, GeoDataCoordinates::Degree );
placemark.setRegionId( regionTree.smallestRegionId( position ) );
if ( !node.name.isEmpty() ) {
placemark.setHouseNumber( QString() );
m_placemarks.push_back( placemark );
}
if ( !node.street.isEmpty() && node.name != node.street ) {
placemark.setCategory( OsmPlacemark::Address );
placemark.setName( node.street.trimmed() );
placemark.setHouseNumber( node.houseNumber.trimmed() );
m_placemarks.push_back( placemark );
}
}
}
qWarning() << "Step 5: Creating placemarks from" << m_ways.size() << "ways";
QMultiMap<QString, Way> waysByName;
for ( const Way & way: m_ways ) {
if ( way.save ) {
if ( !way.name.isEmpty() && !way.nodes.isEmpty() ) {
waysByName.insert( way.name, way );
}
if ( !way.street.isEmpty() && way.name != way.street && !way.nodes.isEmpty() ) {
waysByName.insert( way.street, way );
}
} else {
++m_statistic.uselessWays;
}
}
QSet<QString> keys = QSet<QString>::fromList( waysByName.keys() );
for( const QString & key: keys ) {
QList<QList<Way> > merged = merge( waysByName.values( key ) );
for( const QList<Way> & ways: merged ) {
Q_ASSERT( !ways.isEmpty() );
OsmPlacemark placemark = ways.first();
ways.first().setPosition( m_coordinates, placemark );
ways.first().setRegion( m_nodes, regionTree, m_osmOsmRegions, placemark );
if ( placemark.category() != OsmPlacemark::Address && !ways.first().name.isEmpty() ) {
placemark.setHouseNumber( QString() );
m_placemarks.push_back( placemark );
}
if ( !ways.first().isBuilding || !ways.first().houseNumber.isEmpty() ) {
placemark.setCategory( OsmPlacemark::Address );
QString name = ways.first().street.isEmpty() ? ways.first().name : ways.first().street;
if ( !name.isEmpty() ) {
placemark.setName( name.trimmed() );
placemark.setHouseNumber( ways.first().houseNumber.trimmed() );
m_placemarks.push_back( placemark );
}
}
}
}
m_convexHull = convexHull();
m_coordinates.clear();
m_nodes.clear();
m_ways.clear();
Q_ASSERT( regions.isEmpty() );
for( const OsmOsmRegion & region: m_osmOsmRegions ) {
regions << region.region;
}
std::sort( regions.begin(), regions.end(), moreImportantAdminArea );
regionTree = OsmRegionTree( mainArea );
regionTree.append( regions );
Q_ASSERT( regions.isEmpty() );
left = 0;
regionTree.traverse( left );
regions = regionTree;
qWarning() << "Step 6: " << m_statistic.mergedWays << " ways merged," << m_statistic.uselessWays << "useless ways."
<< "Now serializing" << regions.size() << "regions";
for( const OsmRegion & region: regions ) {
for( Writer * writer: m_writers ) {
writer->addOsmRegion( region );
}
}
qWarning() << "Step 7: Serializing" << m_placemarks.size() << "placemarks";
for( const OsmPlacemark & placemark: m_placemarks ) {
for( Writer * writer: m_writers ) {
Q_ASSERT( !placemark.name().isEmpty() );
writer->addOsmPlacemark( placemark );
}
}
qWarning() << "Step 8: There is no step 8. Done after " << timer.elapsed() / 1000 << "s.";
//writeOutlineKml( areaName );
}
QList< QList<Way> > OsmParser::merge( const QList<Way> &ways ) const
{
QList<WayMerger> mergers;
for( const Way & way: ways ) {
mergers << WayMerger( way );
}
bool moved = false;
do {
moved = false;
for( int i = 0; i < mergers.size(); ++i ) {
for ( int j = i + 1; j < mergers.size(); ++j ) {
if ( mergers[i].compatible( mergers[j] ) ) {
mergers[i].merge( mergers[j] );
moved = true;
mergers.removeAt( j );
}
}
}
} while ( moved );
QList< QList<Way> > result;
for( const WayMerger & merger: mergers ) {
result << merger.ways;
}
m_statistic.mergedWays += ( ways.size() - result.size() );
return result;
}
void OsmParser::importMultipolygon( const Relation &relation )
{
/** @todo: import nodes? What are they used for? */
typedef QPair<int, RelationRole> RelationPair;
QVector<GeoDataLineString> outer;
QVector<GeoDataLineString> inner;
for( const RelationPair & pair: relation.ways ) {
if ( pair.second == Outer ) {
importWay( outer, pair.first );
} else if ( pair.second == Inner ) {
importWay( inner, pair.first );
} else {
qDebug() << "Ignoring way " << pair.first << " with unknown relation role.";
}
}
for( const GeoDataLineString & string: outer ) {
if ( string.isEmpty() || !( string.first() == string.last() ) ) {
qDebug() << "Ignoring open polygon in relation " << relation.name << ". Check data.";
continue;
}
GeoDataPolygon polygon;
polygon.setOuterBoundary(GeoDataLinearRing(string));
Q_ASSERT( polygon.outerBoundary().size() > 0 );
for( const GeoDataLineString & hole: inner ) {
if ( contains<GeoDataLinearRing, GeoDataLineString>( polygon.outerBoundary(), hole ) ) {
polygon.appendInnerBoundary(GeoDataLinearRing(hole));
}
}
OsmOsmRegion region;
region.region.setName( relation.name );
region.region.setGeometry( polygon );
region.region.setAdminLevel( relation.adminLevel );
qDebug() << "Adding administrative region " << relation.name;
m_osmOsmRegions.push_back( region );
}
}
void OsmParser::importWay( QVector<GeoDataLineString> &ways, int id )
{
if ( !m_ways.contains( id ) ) {
qDebug() << "Skipping unknown way " << id << ". Check data.";
return;
}
GeoDataLineString way;
for( int node: m_ways[id].nodes ) {
if ( !m_coordinates.contains( node ) ) {
qDebug() << "Skipping unknown node " << node << ". Check data.";
} else {
const Coordinate &nd = m_coordinates[node];
GeoDataCoordinates coordinates( nd.lon, nd.lat, 0.0, GeoDataCoordinates::Degree );
way << coordinates;
}
}
QList<int> remove;
do {
remove.clear();
for ( int i = 0; i < ways.size(); ++i ) {
const GeoDataLineString &existing = ways[i];
if ( existing.first() == way.first() ) {
way = reverse( way ) << existing;
remove.push_front( i );
} else if ( existing.last() == way.first() ) {
GeoDataLineString copy = existing;
way = copy << way;
remove.push_front( i );
} else if ( existing.first() == way.last() ) {
way << existing;
remove.push_front( i );
} else if ( existing.last() == way.last() ) {
way << reverse( existing );
remove.push_front( i );
}
}
for( int key: remove ) {
ways.remove( key );
}
} while ( !remove.isEmpty() );
ways.push_back( way );
}
GeoDataLineString OsmParser::reverse( const GeoDataLineString & string )
{
GeoDataLineString result;
for ( int i = string.size() - 1; i >= 0; --i ) {
result << string[i];
}
return result;
}
bool OsmParser::shouldSave( ElementType /*type*/, const QString &key, const QString &value )
{
typedef QList<QString> Dictionary;
static QHash<QString, Dictionary> interestingTags;
if ( interestingTags.isEmpty() ) {
Dictionary highways;
highways << "primary" << "secondary" << "tertiary";
highways << "residential" << "unclassified" << "road";
highways << "living_street" << "service" << "track";
highways << "bus_stop" << "platform" << "speed_camera";
interestingTags["highway"] = highways;
Dictionary aeroways;
aeroways << "aerodrome" << "terminal";
interestingTags["aeroway"] = aeroways;
interestingTags["aerialway"] = Dictionary() << "station";
Dictionary leisures;
leisures << "sports_centre" << "stadium" << "pitch";
leisures << "park" << "dance";
interestingTags["leisure"] = leisures;
Dictionary amenities;
amenities << "restaurant" << "food_court" << "fast_food";
amenities << "pub" << "bar" << "cafe";
amenities << "biergarten" << "kindergarten" << "school";
amenities << "college" << "university" << "library";
amenities << "ferry_terminal" << "bus_station" << "car_rental";
amenities << "car_sharing" << "fuel" << "parking";
amenities << "bank" << "pharmacy" << "hospital";
amenities << "cinema" << "nightclub" << "theatre";
amenities << "taxi" << "bicycle_rental" << "atm";
interestingTags["amenity"] = amenities;
Dictionary shops;
shops << "beverages" << "supermarket" << "hifi";
interestingTags["shop"] = shops;
Dictionary tourism;
tourism << "attraction" << "camp_site" << "caravan_site";
tourism << "chalet" << "chalet" << "hostel";
tourism << "hotel" << "motel" << "museum";
tourism << "theme_park" << "viewpoint" << "zoo";
interestingTags["tourism"] = tourism;
Dictionary historic;
historic << "castle" << "fort" << "monument";
historic << "ruins";
interestingTags["historic"] = historic;
Dictionary railway;
railway << "station" << "tram_stop";
interestingTags["railway"] = railway;
Dictionary places;
places << "region" << "county" << "city";
places << "town" << "village" << "hamlet";
places << "isolated_dwelling" << "suburb" << "locality";
places << "island";
interestingTags["place"] = places;
}
return interestingTags.contains( key ) &&
interestingTags[key].contains( value );
}
void OsmParser::setCategory( Element &element, const QString &key, const QString &value )
{
QString const term = key + QLatin1Char('/') + value;
if ( m_categoryMap.contains( term ) ) {
if ( element.category != OsmPlacemark::UnknownCategory ) {
qDebug() << "Overwriting category " << element.category << " with " << m_categoryMap[term] << " for " << element.name;
}
element.category = m_categoryMap[term];
}
}
// From http://en.wikipedia.org/wiki/Graham_scan#Pseudocode
GeoDataLinearRing* OsmParser::convexHull() const
{
Q_ASSERT(m_coordinates.size()>2);
QList<Coordinate> coordinates = m_coordinates.values();
QVector<GrahamScanHelper> points;
points.reserve( coordinates.size()+1 );
Coordinate start = coordinates.first();
int startPos = 0;
for ( int i=0; i<coordinates.size(); ++i ) {
if ( coordinates[i].lon < start.lon ) {
start = coordinates[i];
startPos = i;
}
points << coordinates[i];
}
int const n = points.size();
Q_ASSERT( n == coordinates.size() );
Q_ASSERT( n>2 );
qSwap( points[1], points[startPos] );
Q_ASSERT( start.lat != 360.0 );
for ( int i=0; i<points.size(); ++i ) {
points[i].direction = atan2( start.lon - points[i].coordinate.lon,
start.lat - points[i].coordinate.lat );
}
std::sort( points.begin(), points.end(), GrahamScanHelper::directionLessThan );
points << points.first();
int m = 2;
for ( int i=3; i<=n; ++i ) {
while ( points[m-1].turnDirection( points[m], points[i] ) <= 0 ) {
if ( m == 2 ) {
qSwap( points[m], points[i] );
++i;
} else {
--m;
}
Q_ASSERT( n+1 == points.size() );
Q_ASSERT( m > 0 );
Q_ASSERT( m <= n );
Q_ASSERT( i >= 0 );
Q_ASSERT( i <= n );
}
++m;
qSwap( points[m], points[i] );
}
GeoDataLinearRing* ring = new GeoDataLinearRing;
for ( int i=1; i<=m; ++i ) {
ring->append(GeoDataCoordinates(points[i].coordinate.lon, points[i].coordinate.lat, 0.0, GeoDataCoordinates::Degree));
}
return ring;
}
QColor OsmParser::randomColor() const
{
QVector<QColor> colors = QVector<QColor>() << aluminumGray4 << brickRed4;
colors << woodBrown4 << forestGreen4 << hotOrange4;
colors << seaBlue2 << skyBlue4 << sunYellow6;
return colors.at( qrand() % colors.size() );
}
void OsmParser::writeKml( const QString &area, const QString &version, const QString &date, const QString &transport, const QString &payload, const QString &filename ) const
{
GeoDataDocument* document = new GeoDataDocument;
//for( const OsmOsmRegion & region: m_osmOsmRegions ) {
GeoDataPlacemark* placemark = new GeoDataPlacemark;
placemark->setName( area );
if ( !version.isEmpty() ) {
placemark->extendedData().addValue( GeoDataData( "version", version ) );
}
if ( !date.isEmpty() ) {
placemark->extendedData().addValue( GeoDataData( "date", date ) );
}
if ( !transport.isEmpty() ) {
placemark->extendedData().addValue( GeoDataData( "transport", transport ) );
}
if ( !payload.isEmpty() ) {
placemark->extendedData().addValue( GeoDataData( "payload", payload ) );
}
GeoDataStyle::Ptr style(new GeoDataStyle);
GeoDataLineStyle lineStyle;
QColor color = randomColor();
color.setAlpha( 200 );
lineStyle.setColor( color );
lineStyle.setWidth( 4 );
style->setLineStyle( lineStyle );
style->setId(color.name().replace(QLatin1Char('#'), QLatin1Char('f')));
GeoDataStyleMap styleMap;
styleMap.setId(color.name().replace(QLatin1Char('#'), QLatin1Char('f')));
styleMap.insert("normal", QLatin1Char('#') + style->id());
document->addStyle( style );
placemark->setStyleUrl(QLatin1Char('#') + styleMap.id());
//placemark->setGeometry( new GeoDataLinearRing( region.region.geometry().outerBoundary() ) );
GeoDataMultiGeometry *geometry = new GeoDataMultiGeometry;
geometry->append( m_convexHull );
placemark->setGeometry( geometry );
document->append( placemark );
document->addStyleMap( styleMap );
// }
if (!GeoDataDocumentWriter::write(filename, *document)) {
qCritical() << "Can not write to " << filename;
}
}
Coordinate::Coordinate(float lon_, float lat_) : lon(lon_), lat(lat_)
{
// nothing to do
}
}
#include "moc_OsmParser.cpp"
diff --git a/tools/osm-addresses/OsmParser.h b/tools/osm-addresses/OsmParser.h
index 29d0d7cbf..662c664db 100644
--- a/tools/osm-addresses/OsmParser.h
+++ b/tools/osm-addresses/OsmParser.h
@@ -1,221 +1,221 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_OSMPARSER_H
#define MARBLE_OSMPARSER_H
#include "Writer.h"
#include "OsmRegion.h"
#include "OsmPlacemark.h"
#include "OsmRegionTree.h"
#include <QObject>
#include <QFileInfo>
#include <QHash>
#include <QList>
#include <QPair>
namespace Marble
{
class GeoDataLineString;
enum ElementType {
NoType,
NodeType,
WayType,
RelationType
};
enum RelationRole {
None,
Outer,
Inner
};
struct OsmOsmRegion {
OsmOsmRegion* parent;
OsmRegion region;
- OsmOsmRegion() : parent( 0 ) {}
+ OsmOsmRegion() : parent( nullptr ) {}
};
struct Element {
bool save;
QString name;
QString street;
QString houseNumber;
QString city;
OsmPlacemark::OsmCategory category;
Element() : save( false ),
category( OsmPlacemark::UnknownCategory ) {}
};
struct Coordinate {
float lon;
float lat;
Coordinate(float lon=0.0, float lat=0.0);
};
struct Node : public Element {
float lon;
float lat;
operator OsmPlacemark() const;
operator Coordinate() const;
};
struct Way : public Element {
QList<int> nodes;
bool isBuilding;
operator OsmPlacemark() const;
void setPosition( const QHash<int, Coordinate> &database, OsmPlacemark &placemark ) const;
void setRegion( const QHash<int, Node> &database, const OsmRegionTree & tree, QList<OsmOsmRegion> & osmOsmRegions, OsmPlacemark &placemark ) const;
};
struct WayMerger {
public:
QList<Way> ways;
WayMerger( const Way &way ) {
ways << way;
}
bool compatible( const Way &aWay ) const {
for( const Way & way: ways ) {
if ( way.nodes.first() == aWay.nodes.first() ) return true;
if ( way.nodes.last() == aWay.nodes.first() ) return true;
if ( way.nodes.first() == aWay.nodes.last() ) return true;
if ( way.nodes.last() == aWay.nodes.last() ) return true;
}
return false;
}
bool compatible( const WayMerger &other ) const {
for( const Way & way: ways ) {
if ( other.compatible( way ) ) {
return true;
}
}
return false;
}
void merge( const WayMerger &other ) {
ways << other.ways;
}
};
struct Relation : public Element {
QList<int> nodes;
QList< QPair<int, RelationRole> > ways;
QList<int> relations;
QString name;
bool isMultipolygon;
bool isAdministrativeBoundary;
int adminLevel;
Relation() : isMultipolygon( false ),
isAdministrativeBoundary( false ),
adminLevel( 0 )
{
// nothing to do
}
};
struct Statistic {
unsigned int mergedWays;
unsigned int uselessWays;
Statistic() : mergedWays( 0 ),
uselessWays( 0 )
{}
};
class OsmParser : public QObject
{
Q_OBJECT
public:
- explicit OsmParser( QObject *parent = 0 );
+ explicit OsmParser( QObject *parent = nullptr );
void addWriter( Writer* writer );
void read( const QFileInfo &file, const QString &areaName );
void writeKml( const QString &area, const QString &version, const QString &date, const QString &transport, const QString &payload, const QString &outputKml ) const;
protected:
virtual bool parse( const QFileInfo &file, int pass, bool &needAnotherPass ) = 0;
bool shouldSave( ElementType type, const QString &key, const QString &value );
void setCategory( Element &element, const QString &key, const QString &value );
QHash<int, Coordinate> m_coordinates;
QHash<int, Node> m_nodes;
QHash<int, Way> m_ways;
QHash<int, Relation> m_relations;
private:
GeoDataLinearRing *convexHull() const;
void importMultipolygon( const Relation &relation );
void importWay( QVector<Marble::GeoDataLineString> &ways, int id );
QList< QList<Way> > merge( const QList<Way> &ways ) const;
template<class T, class S>
bool contains( const T &outer, const S &inner ) const {
for ( int i = 0; i < inner.size(); ++i ) {
if ( !outer.contains( inner[i] ) ) {
bool onBorder = false;
for ( int k=0; k<outer.size(); ++k ) {
if ( inner[i] == outer[k] ) {
onBorder = true;
break;
}
}
if ( !onBorder ) {
return false;
}
}
}
return true;
}
QColor randomColor() const;
Marble::GeoDataLineString reverse( const Marble::GeoDataLineString & string );
QList<Writer*> m_writers;
QList<OsmOsmRegion> m_osmOsmRegions;
QList<OsmPlacemark> m_placemarks;
QHash<QString, OsmPlacemark::OsmCategory> m_categoryMap;
mutable Statistic m_statistic;
GeoDataLinearRing* m_convexHull;
};
}
#endif // MARBLE_OSMPARSER_H
diff --git a/tools/osm-addresses/SqlWriter.h b/tools/osm-addresses/SqlWriter.h
index 32bd85a4d..194e910b0 100644
--- a/tools/osm-addresses/SqlWriter.h
+++ b/tools/osm-addresses/SqlWriter.h
@@ -1,50 +1,50 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef SQLWRITER_H
#define SQLWRITER_H
#include "Writer.h"
#include <QPair>
#include <QHash>
#include <QSqlQuery>
namespace Marble
{
class SqlWriter : public Writer
{
public:
- explicit SqlWriter( const QString &filename, QObject* parent = 0 );
+ explicit SqlWriter( const QString &filename, QObject* parent = nullptr );
~SqlWriter() override;
void addOsmRegion( const OsmRegion &region ) override;
void addOsmPlacemark( const OsmPlacemark &placemark ) override;
void saveDatabase( const QString &filename ) const;
private:
void execQuery( QSqlQuery &query ) const;
void execQuery( const QString &query ) const;
QHash<QString, int> m_placemarks;
QPair<int, QString> m_lastPlacemark;
int m_placemarkId;
};
}
#endif // SQLWRITER_H
diff --git a/tools/osm-addresses/Writer.h b/tools/osm-addresses/Writer.h
index 0ebadb274..c83519b93 100644
--- a/tools/osm-addresses/Writer.h
+++ b/tools/osm-addresses/Writer.h
@@ -1,36 +1,36 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_WRITER_H
#define MARBLE_WRITER_H
#include "OsmRegion.h"
#include "OsmPlacemark.h"
#include <QObject>
namespace Marble
{
class Writer : public QObject
{
Q_OBJECT
public:
- explicit Writer( QObject* parent = 0 );
+ explicit Writer( QObject* parent = nullptr );
virtual void addOsmRegion( const OsmRegion &region ) = 0;
virtual void addOsmPlacemark( const OsmPlacemark &placemark ) = 0;
};
}
#endif // MARBLE_WRITER_H
diff --git a/tools/osm-addresses/main.cpp b/tools/osm-addresses/main.cpp
index 63ae45c02..7e372c741 100644
--- a/tools/osm-addresses/main.cpp
+++ b/tools/osm-addresses/main.cpp
@@ -1,132 +1,132 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#include "SqlWriter.h"
#include "pbf/PbfParser.h"
#include "xml/XmlParser.h"
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
#include <QMessageLogContext>
using namespace Marble;
enum DebugLevel {
Debug,
Info,
Mute
};
DebugLevel debugLevel = Info;
void debugOutput( QtMsgType type, const QMessageLogContext &context, const QString &msg )
{
switch ( type ) {
case QtDebugMsg:
if ( debugLevel == Debug ) {
qDebug() << "Debug: " << context.file << ":" << context.line << " " << msg;
}
break;
case QtInfoMsg:
case QtWarningMsg:
if ( debugLevel < Mute ) {
qDebug() << "Info: " << context.file << ":" << context.line << " " << msg;
}
break;
case QtCriticalMsg:
if ( debugLevel < Mute ) {
qDebug() << "Warning: " << context.file << ":" << context.line << " " << msg;
}
break;
case QtFatalMsg:
if ( debugLevel < Mute ) {
qDebug() << "Fatal: " << context.file << ":" << context.line << " " << msg;
abort();
}
}
}
void usage()
{
qDebug() << "Usage: [options] osm-addresses [options] input.osm.pbf|input.osm output.sqlite output.kml";
qDebug() << "\tOptions affect verbosity and store additional metadata in output.kml:";
qDebug() << "\t-q quiet";
qDebug() << "\t-v debug output";
qDebug() << "\t--version aVersion";
qDebug() << "\t--name aName";
qDebug() << "\t--date aDate";
qDebug() << "\t--payload aFilename";
}
int main( int argc, char *argv[] )
{
if ( argc < 4 ) {
usage();
return 1;
}
QCoreApplication app( argc, argv );
QString inputFile = argv[argc-3];
QString outputSqlite = argv[argc-2];
QString outputKml = argv[argc-1];
QString name;
QString version;
QString date;
QString transport;
QString payload;
for ( int i=1; i<argc-3; ++i ) {
QString arg( argv[i] );
if (arg == QLatin1String("-v")) {
debugLevel = Debug;
} else if (arg == QLatin1String("-q")) {
debugLevel = Mute;
} else if (arg == QLatin1String("--name")) {
name = argv[++i];
} else if (arg == QLatin1String("--version")) {
version = argv[++i];
} else if (arg == QLatin1String("--date")) {
date = argv[++i];
} else if (arg == QLatin1String("--transport")) {
transport = argv[++i];
} else if (arg == QLatin1String("--payload")) {
payload = argv[++i];
} else {
usage();
return 1;
}
}
qInstallMessageHandler( debugOutput );
QFileInfo file( inputFile );
if ( !file.exists() ) {
qDebug() << "File " << file.absoluteFilePath() << " does not exist. Exiting.";
return 2;
}
- OsmParser* parser = 0;
+ OsmParser* parser = nullptr;
if ( file.fileName().endsWith( QLatin1String( ".osm" ) ) ) {
parser = new XmlParser;
} else if ( file.fileName().endsWith( QLatin1String( ".pbf" ) ) ) {
parser = new PbfParser;
} else {
qDebug() << "Unsupported file format: " << file.fileName();
return 3;
}
Q_ASSERT( parser );
SqlWriter sql( outputSqlite );
parser->addWriter( &sql );
parser->read( file, name );
parser->writeKml( name, version, date, transport, payload, outputKml );
}
diff --git a/tools/osm-addresses/xml/XmlParser.h b/tools/osm-addresses/xml/XmlParser.h
index ba964abee..55d016667 100644
--- a/tools/osm-addresses/xml/XmlParser.h
+++ b/tools/osm-addresses/xml/XmlParser.h
@@ -1,55 +1,55 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef MARBLE_XMLPARSER_H
#define MARBLE_XMLPARSER_H
#include "../OsmParser.h"
#include "Writer.h"
#include "OsmRegion.h"
#include "OsmPlacemark.h"
#include "OsmRegionTree.h"
#include <QFileInfo>
#include <QXmlDefaultHandler>
namespace Marble
{
class XmlParser : public OsmParser, private QXmlDefaultHandler
{
Q_OBJECT
public:
- explicit XmlParser( QObject *parent = 0 );
+ explicit XmlParser( QObject *parent = nullptr );
protected:
bool parse( const QFileInfo &file, int pass, bool &needAnotherPass ) override;
private:
bool startElement ( const QString & namespaceURI, const QString & localName, const QString & qName, const QXmlAttributes & atts ) override;
bool endElement ( const QString & namespaceURI, const QString & localName, const QString & qName ) override;
Node m_node;
Way m_way;
Relation m_relation;
int m_id;
ElementType m_element;
};
}
#endif // MARBLE_XMLPARSER_H
diff --git a/tools/osm-sisyphus/job.h b/tools/osm-sisyphus/job.h
index bd1ddfb00..e0b2a3ca2 100644
--- a/tools/osm-sisyphus/job.h
+++ b/tools/osm-sisyphus/job.h
@@ -1,97 +1,97 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef JOB_H
#define JOB_H
#include "jobparameters.h"
#include "region.h"
#include <QObject>
#include <QRunnable>
#include <QFileInfo>
class Job : public QObject, public QRunnable
{
Q_OBJECT
public:
enum Status {
Waiting,
Downloading,
Routing,
Search,
Packaging,
Uploading,
Finished,
Error
};
- explicit Job(const Region &region, const JobParameters &parameters, QObject *parent = 0);
+ explicit Job(const Region &region, const JobParameters &parameters, QObject *parent = nullptr);
Status status() const;
QString statusMessage() const;
Region region() const;
void setTransport(const QString &transport);
QString transport() const;
void setProfile(const QString &profile);
void setMonavSettings(const QString &filename);
bool operator==(const Job &other) const;
void run() override;
Q_SIGNALS:
void finished(Job* job);
private:
void changeStatus(Status status, const QString &message);
bool download();
bool monav();
bool search();
bool package();
bool upload();
bool cleanup();
QFileInfo osmFile();
QFileInfo monavDir();
QFileInfo targetFile();
QFileInfo searchFile();
Status m_status;
Region m_region;
JobParameters m_parameters;
QString m_statusMessage;
QString m_transport;
QString m_profile;
QString m_monavSettings;
};
#endif // JOB_H
diff --git a/tools/osm-sisyphus/jobmanager.h b/tools/osm-sisyphus/jobmanager.h
index d2424e2b6..8ed14482a 100644
--- a/tools/osm-sisyphus/jobmanager.h
+++ b/tools/osm-sisyphus/jobmanager.h
@@ -1,57 +1,57 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef JOBMANAGER_H
#define JOBMANAGER_H
#include "jobqueue.h"
#include "region.h"
#include <QObject>
#include <QVector>
struct PendingJob {
Region m_region;
QString m_transport;
QString m_profile;
};
class JobManager : public QObject
{
Q_OBJECT
public:
- explicit JobManager(QObject *parent = 0);
+ explicit JobManager(QObject *parent = nullptr);
void run();
void setRegionsFile(const QString &filename);
void setResumeId(const QString &resumeId);
void setJobParameters(const JobParameters &parameters);
private Q_SLOTS:
void update();
private:
void addJob(const PendingJob &region);
JobQueue m_queue;
JobParameters m_jobParameters;
QFileInfo m_monavSettings;
QVector<PendingJob> m_pendingJobs;
QString m_resumeId;
};
#endif // JOBMANAGER_H
diff --git a/tools/osm-sisyphus/jobqueue.h b/tools/osm-sisyphus/jobqueue.h
index eaedfeade..69556bc19 100644
--- a/tools/osm-sisyphus/jobqueue.h
+++ b/tools/osm-sisyphus/jobqueue.h
@@ -1,42 +1,42 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef JOBQUEUE_H
#define JOBQUEUE_H
#include "job.h"
#include <QObject>
#include <QList>
class JobQueue : public QObject
{
Q_OBJECT
public:
- explicit JobQueue(QObject *parent = 0);
+ explicit JobQueue(QObject *parent = nullptr);
void addJob(Job* job);
void setMaxConcurrentJobs(int size);
private Q_SLOTS:
void removeJob(Job* job);
private:
void startJob(Job *job);
QList<Job*> m_jobs;
QList<Job*> m_runningJobs;
int m_maxConcurrentJobs;
};
#endif // JOBQUEUE_H
diff --git a/tools/osm-sisyphus/logger.h b/tools/osm-sisyphus/logger.h
index 6467ca50b..a96f90950 100644
--- a/tools/osm-sisyphus/logger.h
+++ b/tools/osm-sisyphus/logger.h
@@ -1,36 +1,36 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef LOGGER_H
#define LOGGER_H
#include <QObject>
class LoggerPrivate;
class Logger : public QObject
{
Q_OBJECT
public:
static Logger& instance();
void setFilename(const QString &filename);
void setStatus(const QString &id, const QString &name, const QString &status, const QString &message);
private:
- explicit Logger(QObject *parent = 0);
+ explicit Logger(QObject *parent = nullptr);
~Logger() override;
LoggerPrivate* const d;
};
#endif // LOGGER_H
diff --git a/tools/osm-sisyphus/upload.h b/tools/osm-sisyphus/upload.h
index 8db0f59ea..72d011ad8 100644
--- a/tools/osm-sisyphus/upload.h
+++ b/tools/osm-sisyphus/upload.h
@@ -1,74 +1,74 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2011 Dennis Nienhüser <nienhueser@kde.org>
//
#ifndef UPLOAD_H
#define UPLOAD_H
#include "region.h"
#include "jobparameters.h"
#include <QObject>
#include <QList>
#include <QFileInfo>
#include <QDomDocument>
class Upload : public QObject
{
Q_OBJECT
Q_PROPERTY(bool uploadFiles READ uploadFiles WRITE setUploadFiles)
public:
static Upload& instance();
void uploadAndDelete(const Region &region, const QFileInfo &file, const QString &transport);
bool uploadFiles() const;
void setJobParameters(const JobParameters &parameters);
void setUploadFiles(bool arg);
private:
struct Package {
Region region;
QFileInfo file;
QString transport;
bool operator==(const Package &other) const;
};
- explicit Upload(QObject *parent = 0);
+ explicit Upload(QObject *parent = nullptr);
void changeStatus( const Package &package, const QString &status, const QString &message );
void processQueue();
bool upload(const Package &package);
void deleteFile(const QFileInfo &file);
bool adjustNewstuffFile(const Package &package);
bool uploadNewstuff();
bool deleteRemoteFile(const QString &filename);
QString targetDir() const;
QString releaseDate() const;
QList<Package> m_queue;
bool m_uploadFiles;
QDomDocument m_xml;
JobParameters m_jobParameters;
};
#endif // UPLOAD_H
diff --git a/tools/sentineltile/tileprocessor.h b/tools/sentineltile/tileprocessor.h
index 739417fde..4d76eb628 100644
--- a/tools/sentineltile/tileprocessor.h
+++ b/tools/sentineltile/tileprocessor.h
@@ -1,46 +1,46 @@
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2016 Torsten Rahn <tackat@kde.org>
//
#ifndef TILEPROCESSOR_H
#define TILEPROCESSOR_H
#include <QObject>
#include <QColor>
#include <QImage>
class TileProcessor : public QObject
{
Q_OBJECT
public:
- explicit TileProcessor(QObject *parent = 0);
+ explicit TileProcessor(QObject *parent = nullptr);
public:
void parseFileList(const QString& fileListUrl);
void loadReferenceImages(const QString& maskPath, const QString& bathymetryPath);
void process();
private:
void colorForFile(const QString& filePath);
QStringList m_fileList;
QImage m_mask;
QImage m_bathymetry;
int m_tileLevel;
static int progress;
};
#endif // TILEPROCESSOR_H
diff --git a/tools/vectorosm-tilecreator/clipper/clipper.cpp b/tools/vectorosm-tilecreator/clipper/clipper.cpp
index 2df031b13..bf04c22ab 100644
--- a/tools/vectorosm-tilecreator/clipper/clipper.cpp
+++ b/tools/vectorosm-tilecreator/clipper/clipper.cpp
@@ -1,4652 +1,4652 @@
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 6.4.0 *
* Date : 2 July 2015 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2015 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: *
* "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
/*******************************************************************************
* *
* This is a translation of the Delphi Clipper library and the naming style *
* used has retained a Delphi flavour. *
* *
*******************************************************************************/
#include "clipper.hpp"
#include <cmath>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
#include <functional>
#include <MarbleMath.h>
namespace ClipperLib {
static double const pi = 3.141592653589793238;
static double const two_pi = pi *2;
static double const def_arc_tolerance = 0.25;
enum Direction { dRightToLeft, dLeftToRight };
static int const Unassigned = -1; //edge not currently 'owning' a solution
static int const Skip = -2; //edge that would otherwise close a path
#define HORIZONTAL (-1.0E+40)
#define TOLERANCE (1.0e-20)
#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))
struct TEdge {
IntPoint Bot;
IntPoint Curr; //current (updated for every new scanbeam)
IntPoint Top;
double Dx;
PolyType PolyTyp;
EdgeSide Side; //side only refers to current side of solution poly
int WindDelta; //1 or -1 depending on winding direction
int WindCnt;
int WindCnt2; //winding count of the opposite polytype
int OutIdx;
TEdge *Next;
TEdge *Prev;
TEdge *NextInLML;
TEdge *NextInAEL;
TEdge *PrevInAEL;
TEdge *NextInSEL;
TEdge *PrevInSEL;
};
struct IntersectNode {
TEdge *Edge1;
TEdge *Edge2;
IntPoint Pt;
};
struct LocalMinimum {
cInt Y;
TEdge *LeftBound;
TEdge *RightBound;
};
struct OutPt;
//OutRec: contains a path in the clipping solution. Edges in the AEL will
//carry a pointer to an OutRec when they are part of the clipping solution.
struct OutRec {
int Idx;
bool IsHole;
bool IsOpen;
OutRec *FirstLeft; //see comments in clipper.pas
PolyNode *PolyNd;
OutPt *Pts;
OutPt *BottomPt;
};
struct OutPt {
int Idx;
IntPoint Pt;
OutPt *Next;
OutPt *Prev;
};
struct Join {
OutPt *OutPt1;
OutPt *OutPt2;
IntPoint OffPt;
};
struct LocMinSorter
{
inline bool operator()(const LocalMinimum& locMin1, const LocalMinimum& locMin2)
{
return locMin2.Y < locMin1.Y;
}
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
inline cInt Round(double val)
{
if ((val < 0)) return static_cast<cInt>(val - 0.5);
else return static_cast<cInt>(val + 0.5);
}
//------------------------------------------------------------------------------
inline cInt Abs(cInt val)
{
return val < 0 ? -val : val;
}
//------------------------------------------------------------------------------
// PolyTree methods ...
//------------------------------------------------------------------------------
void PolyTree::Clear()
{
for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
delete AllNodes[i];
AllNodes.resize(0);
Childs.resize(0);
}
//------------------------------------------------------------------------------
PolyNode* PolyTree::GetFirst() const
{
if (!Childs.empty())
return Childs[0];
else
- return 0;
+ return nullptr;
}
//------------------------------------------------------------------------------
int PolyTree::Total() const
{
int result = (int)AllNodes.size();
//with negative offsets, ignore the hidden outer polygon ...
if (result > 0 && Childs[0] != AllNodes[0]) result--;
return result;
}
//------------------------------------------------------------------------------
// PolyNode methods ...
//------------------------------------------------------------------------------
-PolyNode::PolyNode(): Childs(), Parent(0), Index(0), m_IsOpen(false)
+PolyNode::PolyNode(): Childs(), Parent(nullptr), Index(0), m_IsOpen(false)
{
}
//------------------------------------------------------------------------------
int PolyNode::ChildCount() const
{
return (int)Childs.size();
}
//------------------------------------------------------------------------------
void PolyNode::AddChild(PolyNode& child)
{
unsigned cnt = (unsigned)Childs.size();
Childs.push_back(&child);
child.Parent = this;
child.Index = cnt;
}
//------------------------------------------------------------------------------
PolyNode* PolyNode::GetNext() const
{
if (!Childs.empty())
return Childs[0];
else
return GetNextSiblingUp();
}
//------------------------------------------------------------------------------
PolyNode* PolyNode::GetNextSiblingUp() const
{
if (!Parent) //protects against PolyTree.GetNextSiblingUp()
- return 0;
+ return nullptr;
else if (Index == Parent->Childs.size() - 1)
return Parent->GetNextSiblingUp();
else
return Parent->Childs[Index + 1];
}
//------------------------------------------------------------------------------
bool PolyNode::IsHole() const
{
bool result = true;
PolyNode* node = Parent;
while (node)
{
result = !result;
node = node->Parent;
}
return result;
}
//------------------------------------------------------------------------------
bool PolyNode::IsOpen() const
{
return m_IsOpen;
}
//------------------------------------------------------------------------------
#ifndef use_int32
//------------------------------------------------------------------------------
// Int128 class (enables safe math on signed 64bit integers)
// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1
// Int128 val2((long64)9223372036854775807);
// Int128 val3 = val1 * val2;
// val3.AsString => "85070591730234615847396907784232501249" (8.5e+37)
//------------------------------------------------------------------------------
class Int128
{
public:
ulong64 lo;
long64 hi;
Int128(long64 _lo = 0)
{
lo = (ulong64)_lo;
if (_lo < 0) hi = -1; else hi = 0;
}
Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
Int128& operator = (const long64 &val)
{
lo = (ulong64)val;
if (val < 0) hi = -1; else hi = 0;
return *this;
}
bool operator == (const Int128 &val) const
{return (hi == val.hi && lo == val.lo);}
bool operator != (const Int128 &val) const
{ return !(*this == val);}
bool operator > (const Int128 &val) const
{
if (hi != val.hi)
return hi > val.hi;
else
return lo > val.lo;
}
bool operator < (const Int128 &val) const
{
if (hi != val.hi)
return hi < val.hi;
else
return lo < val.lo;
}
bool operator >= (const Int128 &val) const
{ return !(*this < val);}
bool operator <= (const Int128 &val) const
{ return !(*this > val);}
Int128& operator += (const Int128 &rhs)
{
hi += rhs.hi;
lo += rhs.lo;
if (lo < rhs.lo) hi++;
return *this;
}
Int128 operator + (const Int128 &rhs) const
{
Int128 result(*this);
result+= rhs;
return result;
}
Int128& operator -= (const Int128 &rhs)
{
*this += -rhs;
return *this;
}
Int128 operator - (const Int128 &rhs) const
{
Int128 result(*this);
result -= rhs;
return result;
}
Int128 operator-() const //unary negation
{
if (lo == 0)
return Int128(-hi, 0);
else
return Int128(~hi, ~lo + 1);
}
operator double() const
{
const double shift64 = 18446744073709551616.0; //2^64
if (hi < 0)
{
if (lo == 0) return (double)hi * shift64;
else return -(double)(~lo + ~hi * shift64);
}
else
return (double)(lo + hi * shift64);
}
};
//------------------------------------------------------------------------------
Int128 Int128Mul (long64 lhs, long64 rhs)
{
bool negate = (lhs < 0) != (rhs < 0);
if (lhs < 0) lhs = -lhs;
ulong64 int1Hi = ulong64(lhs) >> 32;
ulong64 int1Lo = ulong64(lhs & 0xFFFFFFFF);
if (rhs < 0) rhs = -rhs;
ulong64 int2Hi = ulong64(rhs) >> 32;
ulong64 int2Lo = ulong64(rhs & 0xFFFFFFFF);
//nb: see comments in clipper.pas
ulong64 a = int1Hi * int2Hi;
ulong64 b = int1Lo * int2Lo;
ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi;
Int128 tmp;
tmp.hi = long64(a + (c >> 32));
tmp.lo = long64(c << 32);
tmp.lo += long64(b);
if (tmp.lo < b) tmp.hi++;
if (negate) tmp = -tmp;
return tmp;
};
#endif
//------------------------------------------------------------------------------
// Miscellaneous global functions
//------------------------------------------------------------------------------
bool Orientation(const Path &poly)
{
return Area(poly) >= 0;
}
//------------------------------------------------------------------------------
double Area(const Path &poly)
{
int size = (int)poly.size();
if (size < 3) return 0;
double a = 0;
for (int i = 0, j = size -1; i < size; ++i)
{
a += ((double)poly[j].X + poly[i].X) * ((double)poly[j].Y - poly[i].Y);
j = i;
}
return -a * 0.5;
}
//------------------------------------------------------------------------------
double Area(const OutPt *op)
{
const OutPt *startOp = op;
if (!op) return 0;
double a = 0;
do {
a += (double)(op->Prev->Pt.X + op->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y);
op = op->Next;
} while (op != startOp);
return a * 0.5;
}
//------------------------------------------------------------------------------
double Area(const OutRec &outRec)
{
return Area(outRec.Pts);
}
//------------------------------------------------------------------------------
bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
{
OutPt *pp2 = pp;
do
{
if (pp2->Pt == Pt) return true;
pp2 = pp2->Next;
}
while (pp2 != pp);
return false;
}
//------------------------------------------------------------------------------
//See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos
//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
int PointInPolygon(const IntPoint &pt, const Path &path)
{
//returns 0 if false, +1 if true, -1 if pt ON polygon boundary
int result = 0;
size_t cnt = path.size();
if (cnt < 3) return 0;
IntPoint ip = path[0];
for(size_t i = 1; i <= cnt; ++i)
{
IntPoint ipNext = (i == cnt ? path[0] : path[i]);
if (ipNext.Y == pt.Y)
{
if ((ipNext.X == pt.X) || (ip.Y == pt.Y &&
((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1;
}
if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y))
{
if (ip.X >= pt.X)
{
if (ipNext.X > pt.X) result = 1 - result;
else
{
double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
(double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
}
} else
{
if (ipNext.X > pt.X)
{
double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
(double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
}
}
}
ip = ipNext;
}
return result;
}
//------------------------------------------------------------------------------
int PointInPolygon (const IntPoint &pt, OutPt *op)
{
//returns 0 if false, +1 if true, -1 if pt ON polygon boundary
int result = 0;
OutPt* startOp = op;
for(;;)
{
if (op->Next->Pt.Y == pt.Y)
{
if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y &&
((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1;
}
if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y))
{
if (op->Pt.X >= pt.X)
{
if (op->Next->Pt.X > pt.X) result = 1 - result;
else
{
double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
(double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
}
} else
{
if (op->Next->Pt.X > pt.X)
{
double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
(double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
}
}
}
op = op->Next;
if (startOp == op) break;
}
return result;
}
//------------------------------------------------------------------------------
bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
{
OutPt* op = OutPt1;
do
{
//nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon
int res = PointInPolygon(op->Pt, OutPt2);
if (res >= 0) return res > 0;
op = op->Next;
}
while (op != OutPt1);
return true;
}
//----------------------------------------------------------------------
bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
{
#ifndef use_int32
if (UseFullInt64Range)
return Int128Mul(e1.Top.Y - e1.Bot.Y, e2.Top.X - e2.Bot.X) ==
Int128Mul(e1.Top.X - e1.Bot.X, e2.Top.Y - e2.Bot.Y);
else
#endif
return (e1.Top.Y - e1.Bot.Y) * (e2.Top.X - e2.Bot.X) ==
(e1.Top.X - e1.Bot.X) * (e2.Top.Y - e2.Bot.Y);
}
//------------------------------------------------------------------------------
bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2,
const IntPoint &pt3, bool UseFullInt64Range)
{
#ifndef use_int32
if (UseFullInt64Range)
return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y);
else
#endif
return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y);
}
//------------------------------------------------------------------------------
bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2,
const IntPoint &pt3, const IntPoint &pt4, bool UseFullInt64Range)
{
#ifndef use_int32
if (UseFullInt64Range)
return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y);
else
#endif
return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y);
}
//------------------------------------------------------------------------------
inline bool IsHorizontal(TEdge &e)
{
return e.Dx == HORIZONTAL;
}
//------------------------------------------------------------------------------
inline double GetDx(const IntPoint &pt1, const IntPoint &pt2)
{
return (pt1.Y == pt2.Y) ?
HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y);
}
//---------------------------------------------------------------------------
inline void SetDx(TEdge &e)
{
cInt dy = (e.Top.Y - e.Bot.Y);
if (dy == 0) e.Dx = HORIZONTAL;
else e.Dx = (double)(e.Top.X - e.Bot.X) / dy;
}
//---------------------------------------------------------------------------
inline void SwapSides(TEdge &Edge1, TEdge &Edge2)
{
EdgeSide Side = Edge1.Side;
Edge1.Side = Edge2.Side;
Edge2.Side = Side;
}
//------------------------------------------------------------------------------
inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2)
{
int OutIdx = Edge1.OutIdx;
Edge1.OutIdx = Edge2.OutIdx;
Edge2.OutIdx = OutIdx;
}
//------------------------------------------------------------------------------
inline cInt TopX(TEdge &edge, const cInt currentY)
{
return ( currentY == edge.Top.Y ) ?
edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y));
}
//------------------------------------------------------------------------------
void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
{
#ifdef use_xyz
ip.Z = 0;
#endif
double b1, b2;
if (Edge1.Dx == Edge2.Dx)
{
ip.Y = Edge1.Curr.Y;
ip.X = TopX(Edge1, ip.Y);
return;
}
else if (Edge1.Dx == 0)
{
ip.X = Edge1.Bot.X;
if (IsHorizontal(Edge2))
ip.Y = Edge2.Bot.Y;
else
{
b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx);
ip.Y = Round(ip.X / Edge2.Dx + b2);
}
}
else if (Edge2.Dx == 0)
{
ip.X = Edge2.Bot.X;
if (IsHorizontal(Edge1))
ip.Y = Edge1.Bot.Y;
else
{
b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx);
ip.Y = Round(ip.X / Edge1.Dx + b1);
}
}
else
{
b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx;
b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx;
double q = (b2-b1) / (Edge1.Dx - Edge2.Dx);
ip.Y = Round(q);
if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
ip.X = Round(Edge1.Dx * q + b1);
else
ip.X = Round(Edge2.Dx * q + b2);
}
if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y)
{
if (Edge1.Top.Y > Edge2.Top.Y)
ip.Y = Edge1.Top.Y;
else
ip.Y = Edge2.Top.Y;
if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
ip.X = TopX(Edge1, ip.Y);
else
ip.X = TopX(Edge2, ip.Y);
}
//finally, don't allow 'ip' to be BELOW curr.Y (ie bottom of scanbeam) ...
if (ip.Y > Edge1.Curr.Y)
{
ip.Y = Edge1.Curr.Y;
//use the more vertical edge to derive X ...
if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx))
ip.X = TopX(Edge2, ip.Y); else
ip.X = TopX(Edge1, ip.Y);
}
}
//------------------------------------------------------------------------------
void ReversePolyPtLinks(OutPt *pp)
{
if (!pp) return;
OutPt *pp1, *pp2;
pp1 = pp;
do {
pp2 = pp1->Next;
pp1->Next = pp1->Prev;
pp1->Prev = pp2;
pp1 = pp2;
} while( pp1 != pp );
}
//------------------------------------------------------------------------------
void DisposeOutPts(OutPt*& pp)
{
- if (pp == 0) return;
- pp->Prev->Next = 0;
+ if (pp == nullptr) return;
+ pp->Prev->Next = nullptr;
while( pp )
{
OutPt *tmpPp = pp;
pp = pp->Next;
delete tmpPp;
}
}
//------------------------------------------------------------------------------
inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt)
{
std::memset(e, 0, sizeof(TEdge));
e->Next = eNext;
e->Prev = ePrev;
e->Curr = Pt;
e->OutIdx = Unassigned;
}
//------------------------------------------------------------------------------
void InitEdge2(TEdge& e, PolyType Pt)
{
if (e.Curr.Y >= e.Next->Curr.Y)
{
e.Bot = e.Curr;
e.Top = e.Next->Curr;
} else
{
e.Top = e.Curr;
e.Bot = e.Next->Curr;
}
SetDx(e);
e.PolyTyp = Pt;
}
//------------------------------------------------------------------------------
TEdge* RemoveEdge(TEdge* e)
{
//removes e from double_linked_list (but without removing from memory)
e->Prev->Next = e->Next;
e->Next->Prev = e->Prev;
TEdge* result = e->Next;
- e->Prev = 0; //flag as removed (see ClipperBase.Clear)
+ e->Prev = nullptr; //flag as removed (see ClipperBase.Clear)
return result;
}
//------------------------------------------------------------------------------
inline void ReverseHorizontal(TEdge &e)
{
//swap horizontal edges' Top and Bottom x's so they follow the natural
//progression of the bounds - ie so their xbots will align with the
//adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
std::swap(e.Top.X, e.Bot.X);
#ifdef use_xyz
std::swap(e.Top.Z, e.Bot.Z);
#endif
}
//------------------------------------------------------------------------------
void SwapPoints(IntPoint &pt1, IntPoint &pt2)
{
IntPoint tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
//------------------------------------------------------------------------------
bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a,
IntPoint pt2b, IntPoint &pt1, IntPoint &pt2)
{
//precondition: segments are Collinear.
if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y))
{
if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b);
if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b);
if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a;
if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b;
return pt1.X < pt2.X;
} else
{
if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b);
if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b);
if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a;
if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b;
return pt1.Y > pt2.Y;
}
}
//------------------------------------------------------------------------------
bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
{
OutPt *p = btmPt1->Prev;
while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev;
double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt));
p = btmPt1->Next;
while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next;
double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt));
p = btmPt2->Prev;
while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev;
double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt));
p = btmPt2->Next;
while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));
if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
return Area(btmPt1) > 0; //if otherwise identical use orientation
else
return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
}
//------------------------------------------------------------------------------
OutPt* GetBottomPt(OutPt *pp)
{
- OutPt* dups = 0;
+ OutPt* dups = nullptr;
OutPt* p = pp->Next;
while (p != pp)
{
if (p->Pt.Y > pp->Pt.Y)
{
pp = p;
- dups = 0;
+ dups = nullptr;
}
else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X)
{
if (p->Pt.X < pp->Pt.X)
{
- dups = 0;
+ dups = nullptr;
pp = p;
} else
{
if (p->Next != pp && p->Prev != pp) dups = p;
}
}
p = p->Next;
}
if (dups)
{
//there appears to be at least 2 vertices at BottomPt so ...
while (dups != p)
{
if (!FirstIsBottomPt(p, dups)) pp = dups;
dups = dups->Next;
while (dups->Pt != pp->Pt) dups = dups->Next;
}
}
return pp;
}
//------------------------------------------------------------------------------
bool Pt2IsBetweenPt1AndPt3(const IntPoint &pt1,
const IntPoint &pt2, const IntPoint &pt3)
{
if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
return false;
else if (pt1.X != pt3.X)
return (pt2.X > pt1.X) == (pt2.X < pt3.X);
else
return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y);
}
//------------------------------------------------------------------------------
bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
{
if (seg1a > seg1b) std::swap(seg1a, seg1b);
if (seg2a > seg2b) std::swap(seg2a, seg2b);
return (seg1a < seg2b) && (seg2a < seg1b);
}
//------------------------------------------------------------------------------
// ClipperBase class methods ...
//------------------------------------------------------------------------------
ClipperBase::ClipperBase() //constructor
{
m_CurrentLM = m_MinimaList.begin(); //begin() == end() here
m_UseFullRange = false;
}
//------------------------------------------------------------------------------
ClipperBase::~ClipperBase() //destructor
{
Clear();
}
//------------------------------------------------------------------------------
void RangeTest(const IntPoint& Pt, bool& useFullRange)
{
if (useFullRange)
{
if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange)
throw clipperException("Coordinate outside allowed range");
}
else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange)
{
useFullRange = true;
RangeTest(Pt, useFullRange);
}
}
//------------------------------------------------------------------------------
TEdge* FindNextLocMin(TEdge* E)
{
for (;;)
{
while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next;
if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break;
while (IsHorizontal(*E->Prev)) E = E->Prev;
TEdge* E2 = E;
while (IsHorizontal(*E)) E = E->Next;
if (E->Top.Y == E->Prev->Bot.Y) continue; //ie just an intermediate horz.
if (E2->Prev->Bot.X < E->Bot.X) E = E2;
break;
}
return E;
}
//------------------------------------------------------------------------------
TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
{
TEdge *Result = E;
- TEdge *Horz = 0;
+ TEdge *Horz = nullptr;
if (E->OutIdx == Skip)
{
//if edges still remain in the current bound beyond the skip edge then
//create another LocMin and call ProcessBound once more
if (NextIsForward)
{
while (E->Top.Y == E->Next->Bot.Y) E = E->Next;
//don't include top horizontals when parsing a bound a second time,
//they will be contained in the opposite bound ...
while (E != Result && IsHorizontal(*E)) E = E->Prev;
}
else
{
while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev;
while (E != Result && IsHorizontal(*E)) E = E->Next;
}
if (E == Result)
{
if (NextIsForward) Result = E->Next;
else Result = E->Prev;
}
else
{
//there are more edges in the bound beyond result starting with E
if (NextIsForward)
E = Result->Next;
else
E = Result->Prev;
MinimaList::value_type locMin;
locMin.Y = E->Bot.Y;
- locMin.LeftBound = 0;
+ locMin.LeftBound = nullptr;
locMin.RightBound = E;
E->WindDelta = 0;
Result = ProcessBound(E, NextIsForward);
m_MinimaList.push_back(locMin);
}
return Result;
}
TEdge *EStart;
if (IsHorizontal(*E))
{
//We need to be careful with open paths because this may not be a
//true local minima (ie E may be following a skip edge).
//Also, consecutive horz. edges may start heading left before going right.
if (NextIsForward)
EStart = E->Prev;
else
EStart = E->Next;
if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge
{
if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X)
ReverseHorizontal(*E);
}
else if (EStart->Bot.X != E->Bot.X)
ReverseHorizontal(*E);
}
EStart = E;
if (NextIsForward)
{
while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip)
Result = Result->Next;
if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip)
{
//nb: at the top of a bound, horizontals are added to the bound
//only when the preceding edge attaches to the horizontal's left vertex
//unless a Skip edge is encountered when that becomes the top divide
Horz = Result;
while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev;
if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev;
}
while (E != Result)
{
E->NextInLML = E->Next;
if (IsHorizontal(*E) && E != EStart &&
E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
E = E->Next;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X)
ReverseHorizontal(*E);
Result = Result->Next; //move to the edge just beyond current bound
} else
{
while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip)
Result = Result->Prev;
if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip)
{
Horz = Result;
while (IsHorizontal(*Horz->Next)) Horz = Horz->Next;
if (Horz->Next->Top.X == Result->Prev->Top.X ||
Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next;
}
while (E != Result)
{
E->NextInLML = E->Prev;
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
E = E->Prev;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
Result = Result->Prev; //move to the edge just beyond current bound
}
return Result;
}
//------------------------------------------------------------------------------
bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
{
#ifdef use_lines
if (!Closed && PolyTyp == ptClip)
throw clipperException("AddPath: Open paths must be subject.");
#else
if (!Closed)
throw clipperException("AddPath: Open paths have been disabled.");
#endif
int highI = (int)pg.size() -1;
if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI;
while (highI > 0 && (pg[highI] == pg[highI -1])) --highI;
if ((Closed && highI < 2) || (!Closed && highI < 1)) return false;
//create a new edge array ...
TEdge *edges = new TEdge [highI +1];
bool IsFlat = true;
//1. Basic (first) edge initialization ...
try
{
edges[1].Curr = pg[1];
RangeTest(pg[0], m_UseFullRange);
RangeTest(pg[highI], m_UseFullRange);
InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]);
InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]);
for (int i = highI - 1; i >= 1; --i)
{
RangeTest(pg[i], m_UseFullRange);
InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
}
}
catch(...)
{
delete [] edges;
throw; //range test fails
}
TEdge *eStart = &edges[0];
//2. Remove duplicate vertices, and (when closed) collinear edges ...
TEdge *E = eStart, *eLoopStop = eStart;
for (;;)
{
//nb: allows matching start and end points when not Closed ...
if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart))
{
if (E == E->Next) break;
if (E == eStart) eStart = E->Next;
E = RemoveEdge(E);
eLoopStop = E;
continue;
}
if (E->Prev == E->Next)
break; //only two vertices
else if (Closed &&
SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) &&
(!m_PreserveCollinear ||
!Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr)))
{
//Collinear edges are allowed for open paths but in closed paths
//the default is to merge adjacent collinear edges into a single edge.
//However, if the PreserveCollinear property is enabled, only overlapping
//collinear edges (ie spikes) will be removed from closed paths.
if (E == eStart) eStart = E->Next;
E = RemoveEdge(E);
E = E->Prev;
eLoopStop = E;
continue;
}
E = E->Next;
if ((E == eLoopStop) || (!Closed && E->Next == eStart)) break;
}
if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next)))
{
delete [] edges;
return false;
}
if (!Closed)
{
m_HasOpenPaths = true;
eStart->Prev->OutIdx = Skip;
}
//3. Do second stage of edge initialization ...
E = eStart;
do
{
InitEdge2(*E, PolyTyp);
E = E->Next;
if (IsFlat && E->Curr.Y != eStart->Curr.Y) IsFlat = false;
}
while (E != eStart);
//4. Finally, add edge bounds to LocalMinima list ...
//Totally flat paths must be handled differently when adding them
//to LocalMinima list to avoid endless loops etc ...
if (IsFlat)
{
if (Closed)
{
delete [] edges;
return false;
}
E->Prev->OutIdx = Skip;
MinimaList::value_type locMin;
locMin.Y = E->Bot.Y;
- locMin.LeftBound = 0;
+ locMin.LeftBound = nullptr;
locMin.RightBound = E;
locMin.RightBound->Side = esRight;
locMin.RightBound->WindDelta = 0;
for (;;)
{
if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
if (E->Next->OutIdx == Skip) break;
E->NextInLML = E->Next;
E = E->Next;
}
m_MinimaList.push_back(locMin);
m_edges.push_back(edges);
return true;
}
m_edges.push_back(edges);
bool leftBoundIsForward;
- TEdge* EMin = 0;
+ TEdge* EMin = nullptr;
//workaround to avoid an endless loop in the while loop below when
//open paths have matching start and end points ...
if (E->Prev->Bot == E->Prev->Top) E = E->Next;
for (;;)
{
E = FindNextLocMin(E);
if (E == EMin) break;
else if (!EMin) EMin = E;
//E and E.Prev now share a local minima (left aligned if horizontal).
//Compare their slopes to find which starts which bound ...
MinimaList::value_type locMin;
locMin.Y = E->Bot.Y;
if (E->Dx < E->Prev->Dx)
{
locMin.LeftBound = E->Prev;
locMin.RightBound = E;
leftBoundIsForward = false; //Q.nextInLML = Q.prev
} else
{
locMin.LeftBound = E;
locMin.RightBound = E->Prev;
leftBoundIsForward = true; //Q.nextInLML = Q.next
}
if (!Closed) locMin.LeftBound->WindDelta = 0;
else if (locMin.LeftBound->Next == locMin.RightBound)
locMin.LeftBound->WindDelta = -1;
else locMin.LeftBound->WindDelta = 1;
locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta;
E = ProcessBound(locMin.LeftBound, leftBoundIsForward);
if (E->OutIdx == Skip) E = ProcessBound(E, leftBoundIsForward);
TEdge* E2 = ProcessBound(locMin.RightBound, !leftBoundIsForward);
if (E2->OutIdx == Skip) E2 = ProcessBound(E2, !leftBoundIsForward);
if (locMin.LeftBound->OutIdx == Skip)
- locMin.LeftBound = 0;
+ locMin.LeftBound = nullptr;
else if (locMin.RightBound->OutIdx == Skip)
- locMin.RightBound = 0;
+ locMin.RightBound = nullptr;
m_MinimaList.push_back(locMin);
if (!leftBoundIsForward) E = E2;
}
return true;
}
//------------------------------------------------------------------------------
bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed)
{
bool result = false;
for (Paths::size_type i = 0; i < ppg.size(); ++i)
if (AddPath(ppg[i], PolyTyp, Closed)) result = true;
return result;
}
//------------------------------------------------------------------------------
void ClipperBase::Clear()
{
DisposeLocalMinimaList();
for (EdgeList::size_type i = 0; i < m_edges.size(); ++i)
{
TEdge* edges = m_edges[i];
delete [] edges;
}
m_edges.clear();
m_UseFullRange = false;
m_HasOpenPaths = false;
}
//------------------------------------------------------------------------------
void ClipperBase::Reset()
{
m_CurrentLM = m_MinimaList.begin();
if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process
std::sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter());
m_Scanbeam = ScanbeamList(); //clears/resets priority_queue
//reset all edges ...
for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
{
InsertScanbeam(lm->Y);
TEdge* e = lm->LeftBound;
if (e)
{
e->Curr = e->Bot;
e->Side = esLeft;
e->OutIdx = Unassigned;
}
e = lm->RightBound;
if (e)
{
e->Curr = e->Bot;
e->Side = esRight;
e->OutIdx = Unassigned;
}
}
- m_ActiveEdges = 0;
+ m_ActiveEdges = nullptr;
m_CurrentLM = m_MinimaList.begin();
}
//------------------------------------------------------------------------------
void ClipperBase::DisposeLocalMinimaList()
{
m_MinimaList.clear();
m_CurrentLM = m_MinimaList.begin();
}
//------------------------------------------------------------------------------
bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
{
if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).Y != Y) return false;
locMin = &(*m_CurrentLM);
++m_CurrentLM;
return true;
}
//------------------------------------------------------------------------------
IntRect ClipperBase::GetBounds()
{
IntRect result;
MinimaList::iterator lm = m_MinimaList.begin();
if (lm == m_MinimaList.end())
{
result.left = result.top = result.right = result.bottom = 0;
return result;
}
result.left = lm->LeftBound->Bot.X;
result.top = lm->LeftBound->Bot.Y;
result.right = lm->LeftBound->Bot.X;
result.bottom = lm->LeftBound->Bot.Y;
while (lm != m_MinimaList.end())
{
//todo - needs fixing for open paths
result.bottom = std::max(result.bottom, lm->LeftBound->Bot.Y);
TEdge* e = lm->LeftBound;
for (;;) {
TEdge* bottomE = e;
while (e->NextInLML)
{
if (e->Bot.X < result.left) result.left = e->Bot.X;
if (e->Bot.X > result.right) result.right = e->Bot.X;
e = e->NextInLML;
}
result.left = std::min(result.left, e->Bot.X);
result.right = std::max(result.right, e->Bot.X);
result.left = std::min(result.left, e->Top.X);
result.right = std::max(result.right, e->Top.X);
result.top = std::min(result.top, e->Top.Y);
if (bottomE == lm->LeftBound) e = lm->RightBound;
else break;
}
++lm;
}
return result;
}
//------------------------------------------------------------------------------
void ClipperBase::InsertScanbeam(const cInt Y)
{
m_Scanbeam.push(Y);
}
//------------------------------------------------------------------------------
bool ClipperBase::PopScanbeam(cInt &Y)
{
if (m_Scanbeam.empty()) return false;
Y = m_Scanbeam.top();
m_Scanbeam.pop();
while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
return true;
}
//------------------------------------------------------------------------------
void ClipperBase::DisposeAllOutRecs(){
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
DisposeOutRec(i);
m_PolyOuts.clear();
}
//------------------------------------------------------------------------------
void ClipperBase::DisposeOutRec(PolyOutList::size_type index)
{
OutRec *outRec = m_PolyOuts[index];
if (outRec->Pts) DisposeOutPts(outRec->Pts);
delete outRec;
- m_PolyOuts[index] = 0;
+ m_PolyOuts[index] = nullptr;
}
//------------------------------------------------------------------------------
void ClipperBase::DeleteFromAEL(TEdge *e)
{
TEdge* AelPrev = e->PrevInAEL;
TEdge* AelNext = e->NextInAEL;
if (!AelPrev && !AelNext && (e != m_ActiveEdges)) return; //already deleted
if (AelPrev) AelPrev->NextInAEL = AelNext;
else m_ActiveEdges = AelNext;
if (AelNext) AelNext->PrevInAEL = AelPrev;
- e->NextInAEL = 0;
- e->PrevInAEL = 0;
+ e->NextInAEL = nullptr;
+ e->PrevInAEL = nullptr;
}
//------------------------------------------------------------------------------
OutRec* ClipperBase::CreateOutRec()
{
OutRec* result = new OutRec;
result->IsHole = false;
result->IsOpen = false;
- result->FirstLeft = 0;
- result->Pts = 0;
- result->BottomPt = 0;
- result->PolyNd = 0;
+ result->FirstLeft = nullptr;
+ result->Pts = nullptr;
+ result->BottomPt = nullptr;
+ result->PolyNd = nullptr;
m_PolyOuts.push_back(result);
result->Idx = (int)m_PolyOuts.size() - 1;
return result;
}
//------------------------------------------------------------------------------
void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
{
//check that one or other edge hasn't already been removed from AEL ...
if (Edge1->NextInAEL == Edge1->PrevInAEL ||
Edge2->NextInAEL == Edge2->PrevInAEL) return;
if (Edge1->NextInAEL == Edge2)
{
TEdge* Next = Edge2->NextInAEL;
if (Next) Next->PrevInAEL = Edge1;
TEdge* Prev = Edge1->PrevInAEL;
if (Prev) Prev->NextInAEL = Edge2;
Edge2->PrevInAEL = Prev;
Edge2->NextInAEL = Edge1;
Edge1->PrevInAEL = Edge2;
Edge1->NextInAEL = Next;
}
else if (Edge2->NextInAEL == Edge1)
{
TEdge* Next = Edge1->NextInAEL;
if (Next) Next->PrevInAEL = Edge2;
TEdge* Prev = Edge2->PrevInAEL;
if (Prev) Prev->NextInAEL = Edge1;
Edge1->PrevInAEL = Prev;
Edge1->NextInAEL = Edge2;
Edge2->PrevInAEL = Edge1;
Edge2->NextInAEL = Next;
}
else
{
TEdge* Next = Edge1->NextInAEL;
TEdge* Prev = Edge1->PrevInAEL;
Edge1->NextInAEL = Edge2->NextInAEL;
if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1;
Edge1->PrevInAEL = Edge2->PrevInAEL;
if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1;
Edge2->NextInAEL = Next;
if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2;
Edge2->PrevInAEL = Prev;
if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2;
}
if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1;
else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2;
}
//------------------------------------------------------------------------------
void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
{
if (!e->NextInLML)
throw clipperException("UpdateEdgeIntoAEL: invalid call");
e->NextInLML->OutIdx = e->OutIdx;
TEdge* AelPrev = e->PrevInAEL;
TEdge* AelNext = e->NextInAEL;
if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
else m_ActiveEdges = e->NextInLML;
if (AelNext) AelNext->PrevInAEL = e->NextInLML;
e->NextInLML->Side = e->Side;
e->NextInLML->WindDelta = e->WindDelta;
e->NextInLML->WindCnt = e->WindCnt;
e->NextInLML->WindCnt2 = e->WindCnt2;
e = e->NextInLML;
e->Curr = e->Bot;
e->PrevInAEL = AelPrev;
e->NextInAEL = AelNext;
if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y);
}
//------------------------------------------------------------------------------
bool ClipperBase::LocalMinimaPending()
{
return (m_CurrentLM != m_MinimaList.end());
}
//------------------------------------------------------------------------------
// TClipper methods ...
//------------------------------------------------------------------------------
Clipper::Clipper(int initOptions) : ClipperBase() //constructor
{
m_ExecuteLocked = false;
m_UseFullRange = false;
m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
m_HasOpenPaths = false;
#ifdef use_xyz
m_ZFill = 0;
#endif
}
//------------------------------------------------------------------------------
#ifdef use_xyz
void Clipper::ZFillFunction(ZFillCallback zFillFunc)
{
m_ZFill = zFillFunc;
}
//------------------------------------------------------------------------------
#endif
bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType)
{
return Execute(clipType, solution, fillType, fillType);
}
//------------------------------------------------------------------------------
bool Clipper::Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType)
{
return Execute(clipType, polytree, fillType, fillType);
}
//------------------------------------------------------------------------------
bool Clipper::Execute(ClipType clipType, Paths &solution,
PolyFillType subjFillType, PolyFillType clipFillType)
{
if( m_ExecuteLocked ) return false;
if (m_HasOpenPaths)
throw clipperException("Error: PolyTree struct is needed for open path clipping.");
m_ExecuteLocked = true;
solution.resize(0);
m_SubjFillType = subjFillType;
m_ClipFillType = clipFillType;
m_ClipType = clipType;
m_UsingPolyTree = false;
bool succeeded = ExecuteInternal();
if (succeeded) BuildResult(solution);
DisposeAllOutRecs();
m_ExecuteLocked = false;
return succeeded;
}
//------------------------------------------------------------------------------
bool Clipper::Execute(ClipType clipType, PolyTree& polytree,
PolyFillType subjFillType, PolyFillType clipFillType)
{
if( m_ExecuteLocked ) return false;
m_ExecuteLocked = true;
m_SubjFillType = subjFillType;
m_ClipFillType = clipFillType;
m_ClipType = clipType;
m_UsingPolyTree = true;
bool succeeded = ExecuteInternal();
if (succeeded) BuildResult2(polytree);
DisposeAllOutRecs();
m_ExecuteLocked = false;
return succeeded;
}
//------------------------------------------------------------------------------
void Clipper::FixHoleLinkage(OutRec &outrec)
{
//skip OutRecs that (a) contain outermost polygons or
//(b) already have the correct owner/child linkage ...
if (!outrec.FirstLeft ||
(outrec.IsHole != outrec.FirstLeft->IsHole &&
outrec.FirstLeft->Pts)) return;
OutRec* orfl = outrec.FirstLeft;
while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts))
orfl = orfl->FirstLeft;
outrec.FirstLeft = orfl;
}
//------------------------------------------------------------------------------
bool Clipper::ExecuteInternal()
{
bool succeeded = true;
try {
Reset();
m_Maxima = MaximaList();
- m_SortedEdges = 0;
+ m_SortedEdges = nullptr;
succeeded = true;
cInt botY, topY;
if (!PopScanbeam(botY)) return false;
InsertLocalMinimaIntoAEL(botY);
while (PopScanbeam(topY) || LocalMinimaPending())
{
ProcessHorizontals();
ClearGhostJoins();
if (!ProcessIntersections(topY))
{
succeeded = false;
break;
}
ProcessEdgesAtTopOfScanbeam(topY);
botY = topY;
InsertLocalMinimaIntoAEL(botY);
}
}
catch(...)
{
succeeded = false;
}
if (succeeded)
{
//fix orientations ...
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec *outRec = m_PolyOuts[i];
if (!outRec->Pts || outRec->IsOpen) continue;
if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0))
ReversePolyPtLinks(outRec->Pts);
}
if (!m_Joins.empty()) JoinCommonEdges();
//unfortunately FixupOutPolygon() must be done after JoinCommonEdges()
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec *outRec = m_PolyOuts[i];
if (!outRec->Pts) continue;
if (outRec->IsOpen)
FixupOutPolyline(*outRec);
else
FixupOutPolygon(*outRec);
}
if (m_StrictSimple) DoSimplePolygons();
}
ClearJoins();
ClearGhostJoins();
return succeeded;
}
//------------------------------------------------------------------------------
void Clipper::SetWindingCount(TEdge &edge)
{
TEdge *e = edge.PrevInAEL;
//find the edge of the same polytype that immediately preceeds 'edge' in AEL
while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
if (!e)
{
if (edge.WindDelta == 0)
{
PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType);
edge.WindCnt = (pft == pftNegative ? -1 : 1);
}
else
edge.WindCnt = edge.WindDelta;
edge.WindCnt2 = 0;
e = m_ActiveEdges; //ie get ready to calc WindCnt2
}
else if (edge.WindDelta == 0 && m_ClipType != ctUnion)
{
edge.WindCnt = 1;
edge.WindCnt2 = e->WindCnt2;
e = e->NextInAEL; //ie get ready to calc WindCnt2
}
else if (IsEvenOddFillType(edge))
{
//EvenOdd filling ...
if (edge.WindDelta == 0)
{
//are we inside a subj polygon ...
bool Inside = true;
TEdge *e2 = e->PrevInAEL;
while (e2)
{
if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0)
Inside = !Inside;
e2 = e2->PrevInAEL;
}
edge.WindCnt = (Inside ? 0 : 1);
}
else
{
edge.WindCnt = edge.WindDelta;
}
edge.WindCnt2 = e->WindCnt2;
e = e->NextInAEL; //ie get ready to calc WindCnt2
}
else
{
//nonZero, Positive or Negative filling ...
if (e->WindCnt * e->WindDelta < 0)
{
//prev edge is 'decreasing' WindCount (WC) toward zero
//so we're outside the previous polygon ...
if (Abs(e->WindCnt) > 1)
{
//outside prev poly but still inside another.
//when reversing direction of prev poly use the same WC
if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
//otherwise continue to 'decrease' WC ...
else edge.WindCnt = e->WindCnt + edge.WindDelta;
}
else
//now outside all polys of same polytype so set own WC ...
edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
} else
{
//prev edge is 'increasing' WindCount (WC) away from zero
//so we're inside the previous polygon ...
if (edge.WindDelta == 0)
edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1);
//if wind direction is reversing prev then use same WC
else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
//otherwise add to WC ...
else edge.WindCnt = e->WindCnt + edge.WindDelta;
}
edge.WindCnt2 = e->WindCnt2;
e = e->NextInAEL; //ie get ready to calc WindCnt2
}
//update WindCnt2 ...
if (IsEvenOddAltFillType(edge))
{
//EvenOdd filling ...
while (e != &edge)
{
if (e->WindDelta != 0)
edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0);
e = e->NextInAEL;
}
} else
{
//nonZero, Positive or Negative filling ...
while ( e != &edge )
{
edge.WindCnt2 += e->WindDelta;
e = e->NextInAEL;
}
}
}
//------------------------------------------------------------------------------
bool Clipper::IsEvenOddFillType(const TEdge& edge) const
{
if (edge.PolyTyp == ptSubject)
return m_SubjFillType == pftEvenOdd; else
return m_ClipFillType == pftEvenOdd;
}
//------------------------------------------------------------------------------
bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const
{
if (edge.PolyTyp == ptSubject)
return m_ClipFillType == pftEvenOdd; else
return m_SubjFillType == pftEvenOdd;
}
//------------------------------------------------------------------------------
bool Clipper::IsContributing(const TEdge& edge) const
{
PolyFillType pft, pft2;
if (edge.PolyTyp == ptSubject)
{
pft = m_SubjFillType;
pft2 = m_ClipFillType;
} else
{
pft = m_ClipFillType;
pft2 = m_SubjFillType;
}
switch(pft)
{
case pftEvenOdd:
//return false if a subj line has been flagged as inside a subj polygon
if (edge.WindDelta == 0 && edge.WindCnt != 1) return false;
break;
case pftNonZero:
if (Abs(edge.WindCnt) != 1) return false;
break;
case pftPositive:
if (edge.WindCnt != 1) return false;
break;
default: //pftNegative
if (edge.WindCnt != -1) return false;
}
switch(m_ClipType)
{
case ctIntersection:
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 != 0);
case pftPositive:
return (edge.WindCnt2 > 0);
default:
return (edge.WindCnt2 < 0);
}
break;
case ctUnion:
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 == 0);
case pftPositive:
return (edge.WindCnt2 <= 0);
default:
return (edge.WindCnt2 >= 0);
}
break;
case ctDifference:
if (edge.PolyTyp == ptSubject)
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 == 0);
case pftPositive:
return (edge.WindCnt2 <= 0);
default:
return (edge.WindCnt2 >= 0);
}
else
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 != 0);
case pftPositive:
return (edge.WindCnt2 > 0);
default:
return (edge.WindCnt2 < 0);
}
break;
case ctXor:
if (edge.WindDelta == 0) //XOr always contributing unless open
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 == 0);
case pftPositive:
return (edge.WindCnt2 <= 0);
default:
return (edge.WindCnt2 >= 0);
}
else
return true;
break;
default:
return true;
}
}
//------------------------------------------------------------------------------
OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
{
OutPt* result;
TEdge *e, *prevE;
if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx ))
{
result = AddOutPt(e1, Pt);
e2->OutIdx = e1->OutIdx;
e1->Side = esLeft;
e2->Side = esRight;
e = e1;
if (e->PrevInAEL == e2)
prevE = e2->PrevInAEL;
else
prevE = e->PrevInAEL;
} else
{
result = AddOutPt(e2, Pt);
e1->OutIdx = e2->OutIdx;
e1->Side = esRight;
e2->Side = esLeft;
e = e2;
if (e->PrevInAEL == e1)
prevE = e1->PrevInAEL;
else
prevE = e->PrevInAEL;
}
if (prevE && prevE->OutIdx >= 0)
{
cInt xPrev = TopX(*prevE, Pt.Y);
cInt xE = TopX(*e, Pt.Y);
if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
SlopesEqual(IntPoint(xPrev, Pt.Y), prevE->Top, IntPoint(xE, Pt.Y), e->Top, m_UseFullRange))
{
OutPt* outPt = AddOutPt(prevE, Pt);
AddJoin(result, outPt, e->Top);
}
}
return result;
}
//------------------------------------------------------------------------------
void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
{
AddOutPt( e1, Pt );
if (e2->WindDelta == 0) AddOutPt(e2, Pt);
if( e1->OutIdx == e2->OutIdx )
{
e1->OutIdx = Unassigned;
e2->OutIdx = Unassigned;
}
else if (e1->OutIdx < e2->OutIdx)
AppendPolygon(e1, e2);
else
AppendPolygon(e2, e1);
}
//------------------------------------------------------------------------------
void Clipper::AddEdgeToSEL(TEdge *edge)
{
//SEL pointers in PEdge are reused to build a list of horizontal edges.
//However, we don't need to worry about order with horizontal edge processing.
if( !m_SortedEdges )
{
m_SortedEdges = edge;
- edge->PrevInSEL = 0;
- edge->NextInSEL = 0;
+ edge->PrevInSEL = nullptr;
+ edge->NextInSEL = nullptr;
}
else
{
edge->NextInSEL = m_SortedEdges;
- edge->PrevInSEL = 0;
+ edge->PrevInSEL = nullptr;
m_SortedEdges->PrevInSEL = edge;
m_SortedEdges = edge;
}
}
//------------------------------------------------------------------------------
bool Clipper::PopEdgeFromSEL(TEdge *&edge)
{
if (!m_SortedEdges) return false;
edge = m_SortedEdges;
DeleteFromSEL(m_SortedEdges);
return true;
}
//------------------------------------------------------------------------------
void Clipper::CopyAELToSEL()
{
TEdge* e = m_ActiveEdges;
m_SortedEdges = e;
while ( e )
{
e->PrevInSEL = e->PrevInAEL;
e->NextInSEL = e->NextInAEL;
e = e->NextInAEL;
}
}
//------------------------------------------------------------------------------
void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint &OffPt)
{
Join* j = new Join;
j->OutPt1 = op1;
j->OutPt2 = op2;
j->OffPt = OffPt;
m_Joins.push_back(j);
}
//------------------------------------------------------------------------------
void Clipper::ClearJoins()
{
for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
delete m_Joins[i];
m_Joins.resize(0);
}
//------------------------------------------------------------------------------
void Clipper::ClearGhostJoins()
{
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++)
delete m_GhostJoins[i];
m_GhostJoins.resize(0);
}
//------------------------------------------------------------------------------
void Clipper::AddGhostJoin(OutPt *op, const IntPoint &OffPt)
{
Join* j = new Join;
j->OutPt1 = op;
- j->OutPt2 = 0;
+ j->OutPt2 = nullptr;
j->OffPt = OffPt;
m_GhostJoins.push_back(j);
}
//------------------------------------------------------------------------------
void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
{
const LocalMinimum *lm;
while (PopLocalMinima(botY, lm))
{
TEdge* lb = lm->LeftBound;
TEdge* rb = lm->RightBound;
- OutPt *Op1 = 0;
+ OutPt *Op1 = nullptr;
if (!lb)
{
//nb: don't insert LB into either AEL or SEL
- InsertEdgeIntoAEL(rb, 0);
+ InsertEdgeIntoAEL(rb, nullptr);
SetWindingCount(*rb);
if (IsContributing(*rb))
Op1 = AddOutPt(rb, rb->Bot);
}
else if (!rb)
{
- InsertEdgeIntoAEL(lb, 0);
+ InsertEdgeIntoAEL(lb, nullptr);
SetWindingCount(*lb);
if (IsContributing(*lb))
Op1 = AddOutPt(lb, lb->Bot);
InsertScanbeam(lb->Top.Y);
}
else
{
- InsertEdgeIntoAEL(lb, 0);
+ InsertEdgeIntoAEL(lb, nullptr);
InsertEdgeIntoAEL(rb, lb);
SetWindingCount( *lb );
rb->WindCnt = lb->WindCnt;
rb->WindCnt2 = lb->WindCnt2;
if (IsContributing(*lb))
Op1 = AddLocalMinPoly(lb, rb, lb->Bot);
InsertScanbeam(lb->Top.Y);
}
if (rb)
{
if (IsHorizontal(*rb))
{
AddEdgeToSEL(rb);
if (rb->NextInLML)
InsertScanbeam(rb->NextInLML->Top.Y);
}
else InsertScanbeam( rb->Top.Y );
}
if (!lb || !rb) continue;
//if any output polygons share an edge, they'll need joining later ...
if (Op1 && IsHorizontal(*rb) &&
m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
{
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
{
Join* jr = m_GhostJoins[i];
//if the horizontal Rb and a 'ghost' horizontal overlap, then convert
//the 'ghost' join to a real join ready for later ...
if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X))
AddJoin(jr->OutPt1, Op1, jr->OffPt);
}
}
if (lb->OutIdx >= 0 && lb->PrevInAEL &&
lb->PrevInAEL->Curr.X == lb->Bot.X &&
lb->PrevInAEL->OutIdx >= 0 &&
SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) &&
(lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
{
OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
AddJoin(Op1, Op2, lb->Top);
}
if(lb->NextInAEL != rb)
{
if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) &&
(rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
{
OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
AddJoin(Op1, Op2, rb->Top);
}
TEdge* e = lb->NextInAEL;
if (e)
{
while( e != rb )
{
//nb: For calculating winding counts etc, IntersectEdges() assumes
//that param1 will be to the Right of param2 ABOVE the intersection ...
IntersectEdges(rb , e , lb->Curr); //order important here
e = e->NextInAEL;
}
}
}
}
}
//------------------------------------------------------------------------------
void Clipper::DeleteFromSEL(TEdge *e)
{
TEdge* SelPrev = e->PrevInSEL;
TEdge* SelNext = e->NextInSEL;
if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted
if( SelPrev ) SelPrev->NextInSEL = SelNext;
else m_SortedEdges = SelNext;
if( SelNext ) SelNext->PrevInSEL = SelPrev;
- e->NextInSEL = 0;
- e->PrevInSEL = 0;
+ e->NextInSEL = nullptr;
+ e->PrevInSEL = nullptr;
}
//------------------------------------------------------------------------------
#ifdef use_xyz
void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2)
{
if (pt.Z != 0 || !m_ZFill) return;
else if (pt == e1.Bot) pt.Z = e1.Bot.Z;
else if (pt == e1.Top) pt.Z = e1.Top.Z;
else if (pt == e2.Bot) pt.Z = e2.Bot.Z;
else if (pt == e2.Top) pt.Z = e2.Top.Z;
else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt);
}
//------------------------------------------------------------------------------
#endif
void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
{
bool e1Contributing = ( e1->OutIdx >= 0 );
bool e2Contributing = ( e2->OutIdx >= 0 );
#ifdef use_xyz
SetZ(Pt, *e1, *e2);
#endif
#ifdef use_lines
//if either edge is on an OPEN path ...
if (e1->WindDelta == 0 || e2->WindDelta == 0)
{
//ignore subject-subject open path intersections UNLESS they
//are both open paths, AND they are both 'contributing maximas' ...
if (e1->WindDelta == 0 && e2->WindDelta == 0) return;
//if intersecting a subj line with a subj poly ...
else if (e1->PolyTyp == e2->PolyTyp &&
e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion)
{
if (e1->WindDelta == 0)
{
if (e2Contributing)
{
AddOutPt(e1, Pt);
if (e1Contributing) e1->OutIdx = Unassigned;
}
}
else
{
if (e1Contributing)
{
AddOutPt(e2, Pt);
if (e2Contributing) e2->OutIdx = Unassigned;
}
}
}
else if (e1->PolyTyp != e2->PolyTyp)
{
//toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ...
if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 &&
(m_ClipType != ctUnion || e2->WindCnt2 == 0))
{
AddOutPt(e1, Pt);
if (e1Contributing) e1->OutIdx = Unassigned;
}
else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) &&
(m_ClipType != ctUnion || e1->WindCnt2 == 0))
{
AddOutPt(e2, Pt);
if (e2Contributing) e2->OutIdx = Unassigned;
}
}
return;
}
#endif
//update winding counts...
//assumes that e1 will be to the Right of e2 ABOVE the intersection
if ( e1->PolyTyp == e2->PolyTyp )
{
if ( IsEvenOddFillType( *e1) )
{
int oldE1WindCnt = e1->WindCnt;
e1->WindCnt = e2->WindCnt;
e2->WindCnt = oldE1WindCnt;
} else
{
if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt;
else e1->WindCnt += e2->WindDelta;
if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt;
else e2->WindCnt -= e1->WindDelta;
}
} else
{
if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta;
else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0;
if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta;
else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0;
}
PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
if (e1->PolyTyp == ptSubject)
{
e1FillType = m_SubjFillType;
e1FillType2 = m_ClipFillType;
} else
{
e1FillType = m_ClipFillType;
e1FillType2 = m_SubjFillType;
}
if (e2->PolyTyp == ptSubject)
{
e2FillType = m_SubjFillType;
e2FillType2 = m_ClipFillType;
} else
{
e2FillType = m_ClipFillType;
e2FillType2 = m_SubjFillType;
}
cInt e1Wc, e2Wc;
switch (e1FillType)
{
case pftPositive: e1Wc = e1->WindCnt; break;
case pftNegative: e1Wc = -e1->WindCnt; break;
default: e1Wc = Abs(e1->WindCnt);
}
switch(e2FillType)
{
case pftPositive: e2Wc = e2->WindCnt; break;
case pftNegative: e2Wc = -e2->WindCnt; break;
default: e2Wc = Abs(e2->WindCnt);
}
if ( e1Contributing && e2Contributing )
{
if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
(e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) )
{
AddLocalMaxPoly(e1, e2, Pt);
}
else
{
AddOutPt(e1, Pt);
AddOutPt(e2, Pt);
SwapSides( *e1 , *e2 );
SwapPolyIndexes( *e1 , *e2 );
}
}
else if ( e1Contributing )
{
if (e2Wc == 0 || e2Wc == 1)
{
AddOutPt(e1, Pt);
SwapSides(*e1, *e2);
SwapPolyIndexes(*e1, *e2);
}
}
else if ( e2Contributing )
{
if (e1Wc == 0 || e1Wc == 1)
{
AddOutPt(e2, Pt);
SwapSides(*e1, *e2);
SwapPolyIndexes(*e1, *e2);
}
}
else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1))
{
//neither edge is currently contributing ...
cInt e1Wc2, e2Wc2;
switch (e1FillType2)
{
case pftPositive: e1Wc2 = e1->WindCnt2; break;
case pftNegative : e1Wc2 = -e1->WindCnt2; break;
default: e1Wc2 = Abs(e1->WindCnt2);
}
switch (e2FillType2)
{
case pftPositive: e2Wc2 = e2->WindCnt2; break;
case pftNegative: e2Wc2 = -e2->WindCnt2; break;
default: e2Wc2 = Abs(e2->WindCnt2);
}
if (e1->PolyTyp != e2->PolyTyp)
{
AddLocalMinPoly(e1, e2, Pt);
}
else if (e1Wc == 1 && e2Wc == 1)
switch( m_ClipType ) {
case ctIntersection:
if (e1Wc2 > 0 && e2Wc2 > 0)
AddLocalMinPoly(e1, e2, Pt);
break;
case ctUnion:
if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
AddLocalMinPoly(e1, e2, Pt);
break;
case ctDifference:
if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
AddLocalMinPoly(e1, e2, Pt);
break;
case ctXor:
AddLocalMinPoly(e1, e2, Pt);
}
else
SwapSides( *e1, *e2 );
}
}
//------------------------------------------------------------------------------
void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
{
TEdge *e2 = e->PrevInAEL;
- TEdge *eTmp = 0;
+ TEdge *eTmp = nullptr;
while (e2)
{
if (e2->OutIdx >= 0 && e2->WindDelta != 0)
{
if (!eTmp) eTmp = e2;
- else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;
+ else if (eTmp->OutIdx == e2->OutIdx) eTmp = nullptr;
}
e2 = e2->PrevInAEL;
}
if (!eTmp)
{
- outrec->FirstLeft = 0;
+ outrec->FirstLeft = nullptr;
outrec->IsHole = false;
}
else
{
outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx];
outrec->IsHole = !outrec->FirstLeft->IsHole;
}
}
//------------------------------------------------------------------------------
OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
{
//work out which polygon fragment has the correct hole state ...
if (!outRec1->BottomPt)
outRec1->BottomPt = GetBottomPt(outRec1->Pts);
if (!outRec2->BottomPt)
outRec2->BottomPt = GetBottomPt(outRec2->Pts);
OutPt *OutPt1 = outRec1->BottomPt;
OutPt *OutPt2 = outRec2->BottomPt;
if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1;
else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2;
else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1;
else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2;
else if (OutPt1->Next == OutPt1) return outRec2;
else if (OutPt2->Next == OutPt2) return outRec1;
else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1;
else return outRec2;
}
//------------------------------------------------------------------------------
bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
{
do
{
outRec1 = outRec1->FirstLeft;
if (outRec1 == outRec2) return true;
} while (outRec1);
return false;
}
//------------------------------------------------------------------------------
OutRec* Clipper::GetOutRec(int Idx)
{
OutRec* outrec = m_PolyOuts[Idx];
while (outrec != m_PolyOuts[outrec->Idx])
outrec = m_PolyOuts[outrec->Idx];
return outrec;
}
//------------------------------------------------------------------------------
void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
{
//get the start and ends of both output polygons ...
OutRec *outRec1 = m_PolyOuts[e1->OutIdx];
OutRec *outRec2 = m_PolyOuts[e2->OutIdx];
OutRec *holeStateRec;
if (OutRec1RightOfOutRec2(outRec1, outRec2))
holeStateRec = outRec2;
else if (OutRec1RightOfOutRec2(outRec2, outRec1))
holeStateRec = outRec1;
else
holeStateRec = GetLowermostRec(outRec1, outRec2);
//get the start and ends of both output polygons and
//join e2 poly onto e1 poly and delete pointers to e2 ...
OutPt* p1_lft = outRec1->Pts;
OutPt* p1_rt = p1_lft->Prev;
OutPt* p2_lft = outRec2->Pts;
OutPt* p2_rt = p2_lft->Prev;
//join e2 poly onto e1 poly and delete pointers to e2 ...
if( e1->Side == esLeft )
{
if( e2->Side == esLeft )
{
//z y x a b c
ReversePolyPtLinks(p2_lft);
p2_lft->Next = p1_lft;
p1_lft->Prev = p2_lft;
p1_rt->Next = p2_rt;
p2_rt->Prev = p1_rt;
outRec1->Pts = p2_rt;
} else
{
//x y z a b c
p2_rt->Next = p1_lft;
p1_lft->Prev = p2_rt;
p2_lft->Prev = p1_rt;
p1_rt->Next = p2_lft;
outRec1->Pts = p2_lft;
}
} else
{
if( e2->Side == esRight )
{
//a b c z y x
ReversePolyPtLinks(p2_lft);
p1_rt->Next = p2_rt;
p2_rt->Prev = p1_rt;
p2_lft->Next = p1_lft;
p1_lft->Prev = p2_lft;
} else
{
//a b c x y z
p1_rt->Next = p2_lft;
p2_lft->Prev = p1_rt;
p1_lft->Prev = p2_rt;
p2_rt->Next = p1_lft;
}
}
- outRec1->BottomPt = 0;
+ outRec1->BottomPt = nullptr;
if (holeStateRec == outRec2)
{
if (outRec2->FirstLeft != outRec1)
outRec1->FirstLeft = outRec2->FirstLeft;
outRec1->IsHole = outRec2->IsHole;
}
- outRec2->Pts = 0;
- outRec2->BottomPt = 0;
+ outRec2->Pts = nullptr;
+ outRec2->BottomPt = nullptr;
outRec2->FirstLeft = outRec1;
int OKIdx = e1->OutIdx;
int ObsoleteIdx = e2->OutIdx;
e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly
e2->OutIdx = Unassigned;
TEdge* e = m_ActiveEdges;
while( e )
{
if( e->OutIdx == ObsoleteIdx )
{
e->OutIdx = OKIdx;
e->Side = e1->Side;
break;
}
e = e->NextInAEL;
}
outRec2->Idx = outRec1->Idx;
}
//------------------------------------------------------------------------------
OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
{
if( e->OutIdx < 0 )
{
OutRec *outRec = CreateOutRec();
outRec->IsOpen = (e->WindDelta == 0);
OutPt* newOp = new OutPt;
outRec->Pts = newOp;
newOp->Idx = outRec->Idx;
newOp->Pt = pt;
newOp->Next = newOp;
newOp->Prev = newOp;
if (!outRec->IsOpen)
SetHoleState(e, outRec);
e->OutIdx = outRec->Idx;
return newOp;
} else
{
OutRec *outRec = m_PolyOuts[e->OutIdx];
//OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most'
OutPt* op = outRec->Pts;
bool ToFront = (e->Side == esLeft);
if (ToFront && (pt == op->Pt)) return op;
else if (!ToFront && (pt == op->Prev->Pt)) return op->Prev;
OutPt* newOp = new OutPt;
newOp->Idx = outRec->Idx;
newOp->Pt = pt;
newOp->Next = op;
newOp->Prev = op->Prev;
newOp->Prev->Next = newOp;
op->Prev = newOp;
if (ToFront) outRec->Pts = newOp;
return newOp;
}
}
//------------------------------------------------------------------------------
OutPt* Clipper::GetLastOutPt(TEdge *e)
{
OutRec *outRec = m_PolyOuts[e->OutIdx];
if (e->Side == esLeft)
return outRec->Pts;
else
return outRec->Pts->Prev;
}
//------------------------------------------------------------------------------
void Clipper::ProcessHorizontals()
{
TEdge* horzEdge;
while (PopEdgeFromSEL(horzEdge))
ProcessHorizontal(horzEdge);
}
//------------------------------------------------------------------------------
inline bool IsMinima(TEdge *e)
{
return e && (e->Prev->NextInLML != e) && (e->Next->NextInLML != e);
}
//------------------------------------------------------------------------------
inline bool IsMaxima(TEdge *e, const cInt Y)
{
return e && e->Top.Y == Y && !e->NextInLML;
}
//------------------------------------------------------------------------------
inline bool IsIntermediate(TEdge *e, const cInt Y)
{
return e->Top.Y == Y && e->NextInLML;
}
//------------------------------------------------------------------------------
TEdge *GetMaximaPair(TEdge *e)
{
if ((e->Next->Top == e->Top) && !e->Next->NextInLML)
return e->Next;
else if ((e->Prev->Top == e->Top) && !e->Prev->NextInLML)
return e->Prev;
- else return 0;
+ else return nullptr;
}
//------------------------------------------------------------------------------
TEdge *GetMaximaPairEx(TEdge *e)
{
//as GetMaximaPair() but returns 0 if MaxPair isn't in AEL (unless it's horizontal)
TEdge* result = GetMaximaPair(e);
if (result && (result->OutIdx == Skip ||
- (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return 0;
+ (result->NextInAEL == result->PrevInAEL && !IsHorizontal(*result)))) return nullptr;
return result;
}
//------------------------------------------------------------------------------
void Clipper::SwapPositionsInSEL(TEdge *Edge1, TEdge *Edge2)
{
if( !( Edge1->NextInSEL ) && !( Edge1->PrevInSEL ) ) return;
if( !( Edge2->NextInSEL ) && !( Edge2->PrevInSEL ) ) return;
if( Edge1->NextInSEL == Edge2 )
{
TEdge* Next = Edge2->NextInSEL;
if( Next ) Next->PrevInSEL = Edge1;
TEdge* Prev = Edge1->PrevInSEL;
if( Prev ) Prev->NextInSEL = Edge2;
Edge2->PrevInSEL = Prev;
Edge2->NextInSEL = Edge1;
Edge1->PrevInSEL = Edge2;
Edge1->NextInSEL = Next;
}
else if( Edge2->NextInSEL == Edge1 )
{
TEdge* Next = Edge1->NextInSEL;
if( Next ) Next->PrevInSEL = Edge2;
TEdge* Prev = Edge2->PrevInSEL;
if( Prev ) Prev->NextInSEL = Edge1;
Edge1->PrevInSEL = Prev;
Edge1->NextInSEL = Edge2;
Edge2->PrevInSEL = Edge1;
Edge2->NextInSEL = Next;
}
else
{
TEdge* Next = Edge1->NextInSEL;
TEdge* Prev = Edge1->PrevInSEL;
Edge1->NextInSEL = Edge2->NextInSEL;
if( Edge1->NextInSEL ) Edge1->NextInSEL->PrevInSEL = Edge1;
Edge1->PrevInSEL = Edge2->PrevInSEL;
if( Edge1->PrevInSEL ) Edge1->PrevInSEL->NextInSEL = Edge1;
Edge2->NextInSEL = Next;
if( Edge2->NextInSEL ) Edge2->NextInSEL->PrevInSEL = Edge2;
Edge2->PrevInSEL = Prev;
if( Edge2->PrevInSEL ) Edge2->PrevInSEL->NextInSEL = Edge2;
}
if( !Edge1->PrevInSEL ) m_SortedEdges = Edge1;
else if( !Edge2->PrevInSEL ) m_SortedEdges = Edge2;
}
//------------------------------------------------------------------------------
TEdge* GetNextInAEL(TEdge *e, Direction dir)
{
return dir == dLeftToRight ? e->NextInAEL : e->PrevInAEL;
}
//------------------------------------------------------------------------------
void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cInt& Right)
{
if (HorzEdge.Bot.X < HorzEdge.Top.X)
{
Left = HorzEdge.Bot.X;
Right = HorzEdge.Top.X;
Dir = dLeftToRight;
} else
{
Left = HorzEdge.Top.X;
Right = HorzEdge.Bot.X;
Dir = dRightToLeft;
}
}
//------------------------------------------------------------------------
/*******************************************************************************
* Notes: Horizontal edges (HEs) at scanline intersections (ie at the Top or *
* Bottom of a scanbeam) are processed as if layered. The order in which HEs *
* are processed doesn't matter. HEs intersect with other HE Bot.Xs only [#] *
* (or they could intersect with Top.Xs only, ie EITHER Bot.Xs OR Top.Xs), *
* and with other non-horizontal edges [*]. Once these intersections are *
* processed, intermediate HEs then 'promote' the Edge above (NextInLML) into *
* the AEL. These 'promoted' edges may in turn intersect [%] with other HEs. *
*******************************************************************************/
void Clipper::ProcessHorizontal(TEdge *horzEdge)
{
Direction dir;
cInt horzLeft, horzRight;
bool IsOpen = (horzEdge->WindDelta == 0);
GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
- TEdge* eLastHorz = horzEdge, *eMaxPair = 0;
+ TEdge* eLastHorz = horzEdge, *eMaxPair = nullptr;
while (eLastHorz->NextInLML && IsHorizontal(*eLastHorz->NextInLML))
eLastHorz = eLastHorz->NextInLML;
if (!eLastHorz->NextInLML)
eMaxPair = GetMaximaPair(eLastHorz);
MaximaList::const_iterator maxIt;
MaximaList::const_reverse_iterator maxRit;
if (m_Maxima.size() > 0)
{
//get the first maxima in range (X) ...
if (dir == dLeftToRight)
{
maxIt = m_Maxima.begin();
while (maxIt != m_Maxima.end() && *maxIt <= horzEdge->Bot.X) ++maxIt;
if (maxIt != m_Maxima.end() && *maxIt >= eLastHorz->Top.X)
maxIt = m_Maxima.end();
}
else
{
maxRit = m_Maxima.rbegin();
while (maxRit != m_Maxima.rend() && *maxRit > horzEdge->Bot.X) ++maxRit;
if (maxRit != m_Maxima.rend() && *maxRit <= eLastHorz->Top.X)
maxRit = m_Maxima.rend();
}
}
- OutPt* op1 = 0;
+ OutPt* op1 = nullptr;
for (;;) //loop through consec. horizontal edges
{
bool IsLastHorz = (horzEdge == eLastHorz);
TEdge* e = GetNextInAEL(horzEdge, dir);
while(e)
{
//this code block inserts extra coords into horizontal edges (in output
//polygons) whereever maxima touch these horizontal edges. This helps
//'simplifying' polygons (ie if the Simplify property is set).
if (m_Maxima.size() > 0)
{
if (dir == dLeftToRight)
{
while (maxIt != m_Maxima.end() && *maxIt < e->Curr.X)
{
if (horzEdge->OutIdx >= 0 && !IsOpen)
AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y));
++maxIt;
}
}
else
{
while (maxRit != m_Maxima.rend() && *maxRit > e->Curr.X)
{
if (horzEdge->OutIdx >= 0 && !IsOpen)
AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y));
++maxRit;
}
}
};
if ((dir == dLeftToRight && e->Curr.X > horzRight) ||
(dir == dRightToLeft && e->Curr.X < horzLeft)) break;
//Also break if we've got to the end of an intermediate horizontal edge ...
//nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal.
if (e->Curr.X == horzEdge->Top.X && horzEdge->NextInLML &&
e->Dx < horzEdge->NextInLML->Dx) break;
if (horzEdge->OutIdx >= 0 && !IsOpen) //note: may be done multiple times
{
op1 = AddOutPt(horzEdge, e->Curr);
TEdge* eNextHorz = m_SortedEdges;
while (eNextHorz)
{
if (eNextHorz->OutIdx >= 0 &&
HorzSegmentsOverlap(horzEdge->Bot.X,
horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X))
{
OutPt* op2 = GetLastOutPt(eNextHorz);
AddJoin(op2, op1, eNextHorz->Top);
}
eNextHorz = eNextHorz->NextInSEL;
}
AddGhostJoin(op1, horzEdge->Bot);
}
//OK, so far we're still in range of the horizontal Edge but make sure
//we're at the last of consec. horizontals when matching with eMaxPair
if(e == eMaxPair && IsLastHorz)
{
if (horzEdge->OutIdx >= 0)
AddLocalMaxPoly(horzEdge, eMaxPair, horzEdge->Top);
DeleteFromAEL(horzEdge);
DeleteFromAEL(eMaxPair);
return;
}
if(dir == dLeftToRight)
{
IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
IntersectEdges(horzEdge, e, Pt);
}
else
{
IntPoint Pt = IntPoint(e->Curr.X, horzEdge->Curr.Y);
IntersectEdges( e, horzEdge, Pt);
}
TEdge* eNext = GetNextInAEL(e, dir);
SwapPositionsInAEL( horzEdge, e );
e = eNext;
} //end while(e)
//Break out of loop if HorzEdge.NextInLML is not also horizontal ...
if (!horzEdge->NextInLML || !IsHorizontal(*horzEdge->NextInLML)) break;
UpdateEdgeIntoAEL(horzEdge);
if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Bot);
GetHorzDirection(*horzEdge, dir, horzLeft, horzRight);
} //end for (;;)
if (horzEdge->OutIdx >= 0 && !op1)
{
op1 = GetLastOutPt(horzEdge);
TEdge* eNextHorz = m_SortedEdges;
while (eNextHorz)
{
if (eNextHorz->OutIdx >= 0 &&
HorzSegmentsOverlap(horzEdge->Bot.X,
horzEdge->Top.X, eNextHorz->Bot.X, eNextHorz->Top.X))
{
OutPt* op2 = GetLastOutPt(eNextHorz);
AddJoin(op2, op1, eNextHorz->Top);
}
eNextHorz = eNextHorz->NextInSEL;
}
AddGhostJoin(op1, horzEdge->Top);
}
if (horzEdge->NextInLML)
{
if(horzEdge->OutIdx >= 0)
{
op1 = AddOutPt( horzEdge, horzEdge->Top);
UpdateEdgeIntoAEL(horzEdge);
if (horzEdge->WindDelta == 0) return;
//nb: HorzEdge is no longer horizontal here
TEdge* ePrev = horzEdge->PrevInAEL;
TEdge* eNext = horzEdge->NextInAEL;
if (ePrev && ePrev->Curr.X == horzEdge->Bot.X &&
ePrev->Curr.Y == horzEdge->Bot.Y && ePrev->WindDelta != 0 &&
(ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y &&
SlopesEqual(*horzEdge, *ePrev, m_UseFullRange)))
{
OutPt* op2 = AddOutPt(ePrev, horzEdge->Bot);
AddJoin(op1, op2, horzEdge->Top);
}
else if (eNext && eNext->Curr.X == horzEdge->Bot.X &&
eNext->Curr.Y == horzEdge->Bot.Y && eNext->WindDelta != 0 &&
eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y &&
SlopesEqual(*horzEdge, *eNext, m_UseFullRange))
{
OutPt* op2 = AddOutPt(eNext, horzEdge->Bot);
AddJoin(op1, op2, horzEdge->Top);
}
}
else
UpdateEdgeIntoAEL(horzEdge);
}
else
{
if (horzEdge->OutIdx >= 0) AddOutPt(horzEdge, horzEdge->Top);
DeleteFromAEL(horzEdge);
}
}
//------------------------------------------------------------------------------
bool Clipper::ProcessIntersections(const cInt topY)
{
if( !m_ActiveEdges ) return true;
try {
BuildIntersectList(topY);
size_t IlSize = m_IntersectList.size();
if (IlSize == 0) return true;
if (IlSize == 1 || FixupIntersectionOrder()) ProcessIntersectList();
else return false;
}
catch(...)
{
- m_SortedEdges = 0;
+ m_SortedEdges = nullptr;
DisposeIntersectNodes();
throw clipperException("ProcessIntersections error");
}
- m_SortedEdges = 0;
+ m_SortedEdges = nullptr;
return true;
}
//------------------------------------------------------------------------------
void Clipper::DisposeIntersectNodes()
{
for (size_t i = 0; i < m_IntersectList.size(); ++i )
delete m_IntersectList[i];
m_IntersectList.clear();
}
//------------------------------------------------------------------------------
void Clipper::BuildIntersectList(const cInt topY)
{
if ( !m_ActiveEdges ) return;
//prepare for sorting ...
TEdge* e = m_ActiveEdges;
m_SortedEdges = e;
while( e )
{
e->PrevInSEL = e->PrevInAEL;
e->NextInSEL = e->NextInAEL;
e->Curr.X = TopX( *e, topY );
e = e->NextInAEL;
}
//bubblesort ...
bool isModified;
do
{
isModified = false;
e = m_SortedEdges;
while( e->NextInSEL )
{
TEdge *eNext = e->NextInSEL;
IntPoint Pt;
if(e->Curr.X > eNext->Curr.X)
{
IntersectPoint(*e, *eNext, Pt);
if (Pt.Y < topY) Pt = IntPoint(TopX(*e, topY), topY);
IntersectNode * newNode = new IntersectNode;
newNode->Edge1 = e;
newNode->Edge2 = eNext;
newNode->Pt = Pt;
m_IntersectList.push_back(newNode);
SwapPositionsInSEL(e, eNext);
isModified = true;
}
else
e = eNext;
}
- if( e->PrevInSEL ) e->PrevInSEL->NextInSEL = 0;
+ if( e->PrevInSEL ) e->PrevInSEL->NextInSEL = nullptr;
else break;
}
while ( isModified );
- m_SortedEdges = 0; //important
+ m_SortedEdges = nullptr; //important
}
//------------------------------------------------------------------------------
void Clipper::ProcessIntersectList()
{
for (size_t i = 0; i < m_IntersectList.size(); ++i)
{
IntersectNode* iNode = m_IntersectList[i];
{
IntersectEdges( iNode->Edge1, iNode->Edge2, iNode->Pt);
SwapPositionsInAEL( iNode->Edge1 , iNode->Edge2 );
}
delete iNode;
}
m_IntersectList.clear();
}
//------------------------------------------------------------------------------
bool IntersectListSort(IntersectNode* node1, IntersectNode* node2)
{
return node2->Pt.Y < node1->Pt.Y;
}
//------------------------------------------------------------------------------
inline bool EdgesAdjacent(const IntersectNode &inode)
{
return (inode.Edge1->NextInSEL == inode.Edge2) ||
(inode.Edge1->PrevInSEL == inode.Edge2);
}
//------------------------------------------------------------------------------
bool Clipper::FixupIntersectionOrder()
{
//pre-condition: intersections are sorted Bottom-most first.
//Now it's crucial that intersections are made only between adjacent edges,
//so to ensure this the order of intersections may need adjusting ...
CopyAELToSEL();
std::sort(m_IntersectList.begin(), m_IntersectList.end(), IntersectListSort);
size_t cnt = m_IntersectList.size();
for (size_t i = 0; i < cnt; ++i)
{
if (!EdgesAdjacent(*m_IntersectList[i]))
{
size_t j = i + 1;
while (j < cnt && !EdgesAdjacent(*m_IntersectList[j])) j++;
if (j == cnt) return false;
std::swap(m_IntersectList[i], m_IntersectList[j]);
}
SwapPositionsInSEL(m_IntersectList[i]->Edge1, m_IntersectList[i]->Edge2);
}
return true;
}
//------------------------------------------------------------------------------
void Clipper::DoMaxima(TEdge *e)
{
TEdge* eMaxPair = GetMaximaPairEx(e);
if (!eMaxPair)
{
if (e->OutIdx >= 0)
AddOutPt(e, e->Top);
DeleteFromAEL(e);
return;
}
TEdge* eNext = e->NextInAEL;
while(eNext && eNext != eMaxPair)
{
IntersectEdges(e, eNext, e->Top);
SwapPositionsInAEL(e, eNext);
eNext = e->NextInAEL;
}
if(e->OutIdx == Unassigned && eMaxPair->OutIdx == Unassigned)
{
DeleteFromAEL(e);
DeleteFromAEL(eMaxPair);
}
else if( e->OutIdx >= 0 && eMaxPair->OutIdx >= 0 )
{
if (e->OutIdx >= 0) AddLocalMaxPoly(e, eMaxPair, e->Top);
DeleteFromAEL(e);
DeleteFromAEL(eMaxPair);
}
#ifdef use_lines
else if (e->WindDelta == 0)
{
if (e->OutIdx >= 0)
{
AddOutPt(e, e->Top);
e->OutIdx = Unassigned;
}
DeleteFromAEL(e);
if (eMaxPair->OutIdx >= 0)
{
AddOutPt(eMaxPair, e->Top);
eMaxPair->OutIdx = Unassigned;
}
DeleteFromAEL(eMaxPair);
}
#endif
else throw clipperException("DoMaxima error");
}
//------------------------------------------------------------------------------
void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
{
TEdge* e = m_ActiveEdges;
while( e )
{
//1. process maxima, treating them as if they're 'bent' horizontal edges,
// but exclude maxima with horizontal edges. nb: e can't be a horizontal.
bool IsMaximaEdge = IsMaxima(e, topY);
if(IsMaximaEdge)
{
TEdge* eMaxPair = GetMaximaPairEx(e);
IsMaximaEdge = (!eMaxPair || !IsHorizontal(*eMaxPair));
}
if(IsMaximaEdge)
{
if (m_StrictSimple) m_Maxima.push_back(e->Top.X);
TEdge* ePrev = e->PrevInAEL;
DoMaxima(e);
if( !ePrev ) e = m_ActiveEdges;
else e = ePrev->NextInAEL;
}
else
{
//2. promote horizontal edges, otherwise update Curr.X and Curr.Y ...
if (IsIntermediate(e, topY) && IsHorizontal(*e->NextInLML))
{
UpdateEdgeIntoAEL(e);
if (e->OutIdx >= 0)
AddOutPt(e, e->Bot);
AddEdgeToSEL(e);
}
else
{
e->Curr.X = TopX( *e, topY );
e->Curr.Y = topY;
}
//When StrictlySimple and 'e' is being touched by another edge, then
//make sure both edges have a vertex here ...
if (m_StrictSimple)
{
TEdge* ePrev = e->PrevInAEL;
if ((e->OutIdx >= 0) && (e->WindDelta != 0) && ePrev && (ePrev->OutIdx >= 0) &&
(ePrev->Curr.X == e->Curr.X) && (ePrev->WindDelta != 0))
{
IntPoint pt = e->Curr;
#ifdef use_xyz
SetZ(pt, *ePrev, *e);
#endif
OutPt* op = AddOutPt(ePrev, pt);
OutPt* op2 = AddOutPt(e, pt);
AddJoin(op, op2, pt); //StrictlySimple (type-3) join
}
}
e = e->NextInAEL;
}
}
//3. Process horizontals at the Top of the scanbeam ...
m_Maxima.sort();
ProcessHorizontals();
m_Maxima.clear();
//4. Promote intermediate vertices ...
e = m_ActiveEdges;
while(e)
{
if(IsIntermediate(e, topY))
{
- OutPt* op = 0;
+ OutPt* op = nullptr;
if( e->OutIdx >= 0 )
op = AddOutPt(e, e->Top);
UpdateEdgeIntoAEL(e);
//if output polygons share an edge, they'll need joining later ...
TEdge* ePrev = e->PrevInAEL;
TEdge* eNext = e->NextInAEL;
if (ePrev && ePrev->Curr.X == e->Bot.X &&
ePrev->Curr.Y == e->Bot.Y && op &&
ePrev->OutIdx >= 0 && ePrev->Curr.Y > ePrev->Top.Y &&
SlopesEqual(e->Curr, e->Top, ePrev->Curr, ePrev->Top, m_UseFullRange) &&
(e->WindDelta != 0) && (ePrev->WindDelta != 0))
{
OutPt* op2 = AddOutPt(ePrev, e->Bot);
AddJoin(op, op2, e->Top);
}
else if (eNext && eNext->Curr.X == e->Bot.X &&
eNext->Curr.Y == e->Bot.Y && op &&
eNext->OutIdx >= 0 && eNext->Curr.Y > eNext->Top.Y &&
SlopesEqual(e->Curr, e->Top, eNext->Curr, eNext->Top, m_UseFullRange) &&
(e->WindDelta != 0) && (eNext->WindDelta != 0))
{
OutPt* op2 = AddOutPt(eNext, e->Bot);
AddJoin(op, op2, e->Top);
}
}
e = e->NextInAEL;
}
}
//------------------------------------------------------------------------------
void Clipper::FixupOutPolyline(OutRec &outrec)
{
OutPt *pp = outrec.Pts;
OutPt *lastPP = pp->Prev;
while (pp != lastPP)
{
pp = pp->Next;
if (pp->Pt == pp->Prev->Pt)
{
if (pp == lastPP) lastPP = pp->Prev;
OutPt *tmpPP = pp->Prev;
tmpPP->Next = pp->Next;
pp->Next->Prev = tmpPP;
delete pp;
pp = tmpPP;
}
}
if (pp == pp->Prev)
{
DisposeOutPts(pp);
- outrec.Pts = 0;
+ outrec.Pts = nullptr;
return;
}
}
//------------------------------------------------------------------------------
void Clipper::FixupOutPolygon(OutRec &outrec)
{
//FixupOutPolygon() - removes duplicate points and simplifies consecutive
//parallel edges by removing the middle vertex.
- OutPt *lastOK = 0;
- outrec.BottomPt = 0;
+ OutPt *lastOK = nullptr;
+ outrec.BottomPt = nullptr;
OutPt *pp = outrec.Pts;
bool preserveCol = m_PreserveCollinear || m_StrictSimple;
for (;;)
{
if (pp->Prev == pp || pp->Prev == pp->Next)
{
DisposeOutPts(pp);
- outrec.Pts = 0;
+ outrec.Pts = nullptr;
return;
}
//test for duplicate points and collinear edges ...
if ((pp->Pt == pp->Next->Pt) || (pp->Pt == pp->Prev->Pt) ||
(SlopesEqual(pp->Prev->Pt, pp->Pt, pp->Next->Pt, m_UseFullRange) &&
(!preserveCol || !Pt2IsBetweenPt1AndPt3(pp->Prev->Pt, pp->Pt, pp->Next->Pt))))
{
- lastOK = 0;
+ lastOK = nullptr;
OutPt *tmp = pp;
pp->Prev->Next = pp->Next;
pp->Next->Prev = pp->Prev;
pp = pp->Prev;
delete tmp;
}
else if (pp == lastOK) break;
else
{
if (!lastOK) lastOK = pp;
pp = pp->Next;
}
}
outrec.Pts = pp;
}
//------------------------------------------------------------------------------
int PointCount(OutPt *Pts)
{
if (!Pts) return 0;
int result = 0;
OutPt* p = Pts;
do
{
result++;
p = p->Next;
}
while (p != Pts);
return result;
}
//------------------------------------------------------------------------------
void Clipper::BuildResult(Paths &polys)
{
polys.reserve(m_PolyOuts.size());
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
if (!m_PolyOuts[i]->Pts) continue;
Path pg;
OutPt* p = m_PolyOuts[i]->Pts->Prev;
int cnt = PointCount(p);
if (cnt < 2) continue;
pg.reserve(cnt);
for (int i = 0; i < cnt; ++i)
{
pg.push_back(p->Pt);
p = p->Prev;
}
polys.push_back(pg);
}
}
//------------------------------------------------------------------------------
void Clipper::BuildResult2(PolyTree& polytree)
{
polytree.Clear();
polytree.AllNodes.reserve(m_PolyOuts.size());
//add each output polygon/contour to polytree ...
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++)
{
OutRec* outRec = m_PolyOuts[i];
int cnt = PointCount(outRec->Pts);
if ((outRec->IsOpen && cnt < 2) || (!outRec->IsOpen && cnt < 3)) continue;
FixHoleLinkage(*outRec);
PolyNode* pn = new PolyNode();
//nb: polytree takes ownership of all the PolyNodes
polytree.AllNodes.push_back(pn);
outRec->PolyNd = pn;
- pn->Parent = 0;
+ pn->Parent = nullptr;
pn->Index = 0;
pn->Contour.reserve(cnt);
OutPt *op = outRec->Pts->Prev;
for (int j = 0; j < cnt; j++)
{
pn->Contour.push_back(op->Pt);
op = op->Prev;
}
}
//fixup PolyNode links etc ...
polytree.Childs.reserve(m_PolyOuts.size());
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); i++)
{
OutRec* outRec = m_PolyOuts[i];
if (!outRec->PolyNd) continue;
if (outRec->IsOpen)
{
outRec->PolyNd->m_IsOpen = true;
polytree.AddChild(*outRec->PolyNd);
}
else if (outRec->FirstLeft && outRec->FirstLeft->PolyNd)
outRec->FirstLeft->PolyNd->AddChild(*outRec->PolyNd);
else
polytree.AddChild(*outRec->PolyNd);
}
}
//------------------------------------------------------------------------------
void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2)
{
//just swap the contents (because fIntersectNodes is a single-linked-list)
IntersectNode inode = int1; //gets a copy of Int1
int1.Edge1 = int2.Edge1;
int1.Edge2 = int2.Edge2;
int1.Pt = int2.Pt;
int2.Edge1 = inode.Edge1;
int2.Edge2 = inode.Edge2;
int2.Pt = inode.Pt;
}
//------------------------------------------------------------------------------
inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
{
if (e2.Curr.X == e1.Curr.X)
{
if (e2.Top.Y > e1.Top.Y)
return e2.Top.X < TopX(e1, e2.Top.Y);
else return e1.Top.X > TopX(e2, e1.Top.Y);
}
else return e2.Curr.X < e1.Curr.X;
}
//------------------------------------------------------------------------------
bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cInt b2,
cInt& Left, cInt& Right)
{
if (a1 < a2)
{
if (b1 < b2) {Left = std::max(a1,b1); Right = std::min(a2,b2);}
else {Left = std::max(a1,b2); Right = std::min(a2,b1);}
}
else
{
if (b1 < b2) {Left = std::max(a2,b1); Right = std::min(a1,b2);}
else {Left = std::max(a2,b2); Right = std::min(a1,b1);}
}
return Left < Right;
}
//------------------------------------------------------------------------------
inline void UpdateOutPtIdxs(OutRec& outrec)
{
OutPt* op = outrec.Pts;
do
{
op->Idx = outrec.Idx;
op = op->Prev;
}
while(op != outrec.Pts);
}
//------------------------------------------------------------------------------
void Clipper::InsertEdgeIntoAEL(TEdge *edge, TEdge* startEdge)
{
if(!m_ActiveEdges)
{
- edge->PrevInAEL = 0;
- edge->NextInAEL = 0;
+ edge->PrevInAEL = nullptr;
+ edge->NextInAEL = nullptr;
m_ActiveEdges = edge;
}
else if(!startEdge && E2InsertsBeforeE1(*m_ActiveEdges, *edge))
{
- edge->PrevInAEL = 0;
+ edge->PrevInAEL = nullptr;
edge->NextInAEL = m_ActiveEdges;
m_ActiveEdges->PrevInAEL = edge;
m_ActiveEdges = edge;
}
else
{
if(!startEdge) startEdge = m_ActiveEdges;
while(startEdge->NextInAEL &&
!E2InsertsBeforeE1(*startEdge->NextInAEL , *edge))
startEdge = startEdge->NextInAEL;
edge->NextInAEL = startEdge->NextInAEL;
if(startEdge->NextInAEL) startEdge->NextInAEL->PrevInAEL = edge;
edge->PrevInAEL = startEdge;
startEdge->NextInAEL = edge;
}
}
//----------------------------------------------------------------------
OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
{
OutPt* result = new OutPt;
result->Pt = outPt->Pt;
result->Idx = outPt->Idx;
if (InsertAfter)
{
result->Next = outPt->Next;
result->Prev = outPt;
outPt->Next->Prev = result;
outPt->Next = result;
}
else
{
result->Prev = outPt->Prev;
result->Next = outPt;
outPt->Prev->Next = result;
outPt->Prev = result;
}
return result;
}
//------------------------------------------------------------------------------
bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
const IntPoint &Pt, bool DiscardLeft)
{
Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight);
Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight);
if (Dir1 == Dir2) return false;
//When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we
//want Op1b to be on the Right. (And likewise with Op2 and Op2b.)
//So, to facilitate this while inserting Op1b and Op2b ...
//when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b,
//otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.)
if (Dir1 == dLeftToRight)
{
while (op1->Next->Pt.X <= Pt.X &&
op1->Next->Pt.X >= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
op1 = op1->Next;
if (DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
op1b = DupOutPt(op1, !DiscardLeft);
if (op1b->Pt != Pt)
{
op1 = op1b;
op1->Pt = Pt;
op1b = DupOutPt(op1, !DiscardLeft);
}
}
else
{
while (op1->Next->Pt.X >= Pt.X &&
op1->Next->Pt.X <= op1->Pt.X && op1->Next->Pt.Y == Pt.Y)
op1 = op1->Next;
if (!DiscardLeft && (op1->Pt.X != Pt.X)) op1 = op1->Next;
op1b = DupOutPt(op1, DiscardLeft);
if (op1b->Pt != Pt)
{
op1 = op1b;
op1->Pt = Pt;
op1b = DupOutPt(op1, DiscardLeft);
}
}
if (Dir2 == dLeftToRight)
{
while (op2->Next->Pt.X <= Pt.X &&
op2->Next->Pt.X >= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
op2 = op2->Next;
if (DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
op2b = DupOutPt(op2, !DiscardLeft);
if (op2b->Pt != Pt)
{
op2 = op2b;
op2->Pt = Pt;
op2b = DupOutPt(op2, !DiscardLeft);
};
} else
{
while (op2->Next->Pt.X >= Pt.X &&
op2->Next->Pt.X <= op2->Pt.X && op2->Next->Pt.Y == Pt.Y)
op2 = op2->Next;
if (!DiscardLeft && (op2->Pt.X != Pt.X)) op2 = op2->Next;
op2b = DupOutPt(op2, DiscardLeft);
if (op2b->Pt != Pt)
{
op2 = op2b;
op2->Pt = Pt;
op2b = DupOutPt(op2, DiscardLeft);
};
};
if ((Dir1 == dLeftToRight) == DiscardLeft)
{
op1->Prev = op2;
op2->Next = op1;
op1b->Next = op2b;
op2b->Prev = op1b;
}
else
{
op1->Next = op2;
op2->Prev = op1;
op1b->Prev = op2b;
op2b->Next = op1b;
}
return true;
}
//------------------------------------------------------------------------------
bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2)
{
OutPt *op1 = j->OutPt1, *op1b;
OutPt *op2 = j->OutPt2, *op2b;
//There are 3 kinds of joins for output polygons ...
//1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are vertices anywhere
//along (horizontal) collinear edges (& Join.OffPt is on the same horizontal).
//2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same
//location at the Bottom of the overlapping segment (& Join.OffPt is above).
//3. StrictSimple joins where edges touch but are not collinear and where
//Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point.
bool isHorizontal = (j->OutPt1->Pt.Y == j->OffPt.Y);
if (isHorizontal && (j->OffPt == j->OutPt1->Pt) &&
(j->OffPt == j->OutPt2->Pt))
{
//Strictly Simple join ...
if (outRec1 != outRec2) return false;
op1b = j->OutPt1->Next;
while (op1b != op1 && (op1b->Pt == j->OffPt))
op1b = op1b->Next;
bool reverse1 = (op1b->Pt.Y > j->OffPt.Y);
op2b = j->OutPt2->Next;
while (op2b != op2 && (op2b->Pt == j->OffPt))
op2b = op2b->Next;
bool reverse2 = (op2b->Pt.Y > j->OffPt.Y);
if (reverse1 == reverse2) return false;
if (reverse1)
{
op1b = DupOutPt(op1, false);
op2b = DupOutPt(op2, true);
op1->Prev = op2;
op2->Next = op1;
op1b->Next = op2b;
op2b->Prev = op1b;
j->OutPt1 = op1;
j->OutPt2 = op1b;
return true;
} else
{
op1b = DupOutPt(op1, true);
op2b = DupOutPt(op2, false);
op1->Next = op2;
op2->Prev = op1;
op1b->Prev = op2b;
op2b->Next = op1b;
j->OutPt1 = op1;
j->OutPt2 = op1b;
return true;
}
}
else if (isHorizontal)
{
//treat horizontal joins differently to non-horizontal joins since with
//them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt
//may be anywhere along the horizontal edge.
op1b = op1;
while (op1->Prev->Pt.Y == op1->Pt.Y && op1->Prev != op1b && op1->Prev != op2)
op1 = op1->Prev;
while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->Next != op2)
op1b = op1b->Next;
if (op1b->Next == op1 || op1b->Next == op2) return false; //a flat 'polygon'
op2b = op2;
while (op2->Prev->Pt.Y == op2->Pt.Y && op2->Prev != op2b && op2->Prev != op1b)
op2 = op2->Prev;
while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->Next != op1)
op2b = op2b->Next;
if (op2b->Next == op2 || op2b->Next == op1) return false; //a flat 'polygon'
cInt Left, Right;
//Op1 --> Op1b & Op2 --> Op2b are the extremites of the horizontal edges
if (!GetOverlap(op1->Pt.X, op1b->Pt.X, op2->Pt.X, op2b->Pt.X, Left, Right))
return false;
//DiscardLeftSide: when overlapping edges are joined, a spike will created
//which needs to be cleaned up. However, we don't want Op1 or Op2 caught up
//on the discard Side as either may still be needed for other joins ...
IntPoint Pt;
bool DiscardLeftSide;
if (op1->Pt.X >= Left && op1->Pt.X <= Right)
{
Pt = op1->Pt; DiscardLeftSide = (op1->Pt.X > op1b->Pt.X);
}
else if (op2->Pt.X >= Left&& op2->Pt.X <= Right)
{
Pt = op2->Pt; DiscardLeftSide = (op2->Pt.X > op2b->Pt.X);
}
else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right)
{
Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->Pt.X;
}
else
{
Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->Pt.X);
}
j->OutPt1 = op1; j->OutPt2 = op2;
return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide);
} else
{
//nb: For non-horizontal joins ...
// 1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y
// 2. Jr.OutPt1.Pt > Jr.OffPt.Y
//make sure the polygons are correctly oriented ...
op1b = op1->Next;
while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Next;
bool Reverse1 = ((op1b->Pt.Y > op1->Pt.Y) ||
!SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange));
if (Reverse1)
{
op1b = op1->Prev;
while ((op1b->Pt == op1->Pt) && (op1b != op1)) op1b = op1b->Prev;
if ((op1b->Pt.Y > op1->Pt.Y) ||
!SlopesEqual(op1->Pt, op1b->Pt, j->OffPt, m_UseFullRange)) return false;
};
op2b = op2->Next;
while ((op2b->Pt == op2->Pt) && (op2b != op2))op2b = op2b->Next;
bool Reverse2 = ((op2b->Pt.Y > op2->Pt.Y) ||
!SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange));
if (Reverse2)
{
op2b = op2->Prev;
while ((op2b->Pt == op2->Pt) && (op2b != op2)) op2b = op2b->Prev;
if ((op2b->Pt.Y > op2->Pt.Y) ||
!SlopesEqual(op2->Pt, op2b->Pt, j->OffPt, m_UseFullRange)) return false;
}
if ((op1b == op1) || (op2b == op2) || (op1b == op2b) ||
((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false;
if (Reverse1)
{
op1b = DupOutPt(op1, false);
op2b = DupOutPt(op2, true);
op1->Prev = op2;
op2->Next = op1;
op1b->Next = op2b;
op2b->Prev = op1b;
j->OutPt1 = op1;
j->OutPt2 = op1b;
return true;
} else
{
op1b = DupOutPt(op1, true);
op2b = DupOutPt(op2, false);
op1->Next = op2;
op2->Prev = op1;
op1b->Prev = op2b;
op2b->Next = op1b;
j->OutPt1 = op1;
j->OutPt2 = op1b;
return true;
}
}
}
//----------------------------------------------------------------------
static OutRec* ParseFirstLeft(OutRec* FirstLeft)
{
while (FirstLeft && !FirstLeft->Pts)
FirstLeft = FirstLeft->FirstLeft;
return FirstLeft;
}
//------------------------------------------------------------------------------
void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
{
//tests if NewOutRec contains the polygon before reassigning FirstLeft
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec* outRec = m_PolyOuts[i];
OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
if (outRec->Pts && firstLeft == OldOutRec)
{
if (Poly2ContainsPoly1(outRec->Pts, NewOutRec->Pts))
outRec->FirstLeft = NewOutRec;
}
}
}
//----------------------------------------------------------------------
void Clipper::FixupFirstLefts2(OutRec* InnerOutRec, OutRec* OuterOutRec)
{
//A polygon has split into two such that one is now the inner of the other.
//It's possible that these polygons now wrap around other polygons, so check
//every polygon that's also contained by OuterOutRec's FirstLeft container
//(including 0) to see if they've become inner to the new inner polygon ...
OutRec* orfl = OuterOutRec->FirstLeft;
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec* outRec = m_PolyOuts[i];
if (!outRec->Pts || outRec == OuterOutRec || outRec == InnerOutRec)
continue;
OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec)
continue;
if (Poly2ContainsPoly1(outRec->Pts, InnerOutRec->Pts))
outRec->FirstLeft = InnerOutRec;
else if (Poly2ContainsPoly1(outRec->Pts, OuterOutRec->Pts))
outRec->FirstLeft = OuterOutRec;
else if (outRec->FirstLeft == InnerOutRec || outRec->FirstLeft == OuterOutRec)
outRec->FirstLeft = orfl;
}
}
//----------------------------------------------------------------------
void Clipper::FixupFirstLefts3(OutRec* OldOutRec, OutRec* NewOutRec)
{
//reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec* outRec = m_PolyOuts[i];
OutRec* firstLeft = ParseFirstLeft(outRec->FirstLeft);
if (outRec->Pts && outRec->FirstLeft == OldOutRec)
outRec->FirstLeft = NewOutRec;
}
}
//----------------------------------------------------------------------
void Clipper::JoinCommonEdges()
{
for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
{
Join* join = m_Joins[i];
OutRec *outRec1 = GetOutRec(join->OutPt1->Idx);
OutRec *outRec2 = GetOutRec(join->OutPt2->Idx);
if (!outRec1->Pts || !outRec2->Pts) continue;
if (outRec1->IsOpen || outRec2->IsOpen) continue;
//get the polygon fragment with the correct hole state (FirstLeft)
//before calling JoinPoints() ...
OutRec *holeStateRec;
if (outRec1 == outRec2) holeStateRec = outRec1;
else if (OutRec1RightOfOutRec2(outRec1, outRec2)) holeStateRec = outRec2;
else if (OutRec1RightOfOutRec2(outRec2, outRec1)) holeStateRec = outRec1;
else holeStateRec = GetLowermostRec(outRec1, outRec2);
if (!JoinPoints(join, outRec1, outRec2)) continue;
if (outRec1 == outRec2)
{
//instead of joining two polygons, we've just created a new one by
//splitting one polygon into two.
outRec1->Pts = join->OutPt1;
- outRec1->BottomPt = 0;
+ outRec1->BottomPt = nullptr;
outRec2 = CreateOutRec();
outRec2->Pts = join->OutPt2;
//update all OutRec2.Pts Idx's ...
UpdateOutPtIdxs(*outRec2);
if (Poly2ContainsPoly1(outRec2->Pts, outRec1->Pts))
{
//outRec1 contains outRec2 ...
outRec2->IsHole = !outRec1->IsHole;
outRec2->FirstLeft = outRec1;
if (m_UsingPolyTree) FixupFirstLefts2(outRec2, outRec1);
if ((outRec2->IsHole ^ m_ReverseOutput) == (Area(*outRec2) > 0))
ReversePolyPtLinks(outRec2->Pts);
} else if (Poly2ContainsPoly1(outRec1->Pts, outRec2->Pts))
{
//outRec2 contains outRec1 ...
outRec2->IsHole = outRec1->IsHole;
outRec1->IsHole = !outRec2->IsHole;
outRec2->FirstLeft = outRec1->FirstLeft;
outRec1->FirstLeft = outRec2;
if (m_UsingPolyTree) FixupFirstLefts2(outRec1, outRec2);
if ((outRec1->IsHole ^ m_ReverseOutput) == (Area(*outRec1) > 0))
ReversePolyPtLinks(outRec1->Pts);
}
else
{
//the 2 polygons are completely separate ...
outRec2->IsHole = outRec1->IsHole;
outRec2->FirstLeft = outRec1->FirstLeft;
//fixup FirstLeft pointers that may need reassigning to OutRec2
if (m_UsingPolyTree) FixupFirstLefts1(outRec1, outRec2);
}
} else
{
//joined 2 polygons together ...
- outRec2->Pts = 0;
- outRec2->BottomPt = 0;
+ outRec2->Pts = nullptr;
+ outRec2->BottomPt = nullptr;
outRec2->Idx = outRec1->Idx;
outRec1->IsHole = holeStateRec->IsHole;
if (holeStateRec == outRec2)
outRec1->FirstLeft = outRec2->FirstLeft;
outRec2->FirstLeft = outRec1;
if (m_UsingPolyTree) FixupFirstLefts3(outRec2, outRec1);
}
}
}
//------------------------------------------------------------------------------
// ClipperOffset support functions ...
//------------------------------------------------------------------------------
DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
{
if(pt2.X == pt1.X && pt2.Y == pt1.Y)
return DoublePoint(0, 0);
double Dx = (double)(pt2.X - pt1.X);
double dy = (double)(pt2.Y - pt1.Y);
double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy );
Dx *= f;
dy *= f;
return DoublePoint(dy, -Dx);
}
//------------------------------------------------------------------------------
// ClipperOffset class
//------------------------------------------------------------------------------
ClipperOffset::ClipperOffset(double miterLimit, double arcTolerance)
{
this->MiterLimit = miterLimit;
this->ArcTolerance = arcTolerance;
m_lowest.X = -1;
}
//------------------------------------------------------------------------------
ClipperOffset::~ClipperOffset()
{
Clear();
}
//------------------------------------------------------------------------------
void ClipperOffset::Clear()
{
for (int i = 0; i < m_polyNodes.ChildCount(); ++i)
delete m_polyNodes.Childs[i];
m_polyNodes.Childs.clear();
m_lowest.X = -1;
}
//------------------------------------------------------------------------------
void ClipperOffset::AddPath(const Path& path, JoinType joinType, EndType endType)
{
int highI = (int)path.size() - 1;
if (highI < 0) return;
PolyNode* newNode = new PolyNode();
newNode->m_jointype = joinType;
newNode->m_endtype = endType;
//strip duplicate points from path and also get index to the lowest point ...
if (endType == etClosedLine || endType == etClosedPolygon)
while (highI > 0 && path[0] == path[highI]) highI--;
newNode->Contour.reserve(highI + 1);
newNode->Contour.push_back(path[0]);
int j = 0, k = 0;
for (int i = 1; i <= highI; i++)
if (newNode->Contour[j] != path[i])
{
j++;
newNode->Contour.push_back(path[i]);
if (path[i].Y > newNode->Contour[k].Y ||
(path[i].Y == newNode->Contour[k].Y &&
path[i].X < newNode->Contour[k].X)) k = j;
}
if (endType == etClosedPolygon && j < 2)
{
delete newNode;
return;
}
m_polyNodes.AddChild(*newNode);
//if this path's lowest pt is lower than all the others then update m_lowest
if (endType != etClosedPolygon) return;
if (m_lowest.X < 0)
m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k);
else
{
IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X]->Contour[(int)m_lowest.Y];
if (newNode->Contour[k].Y > ip.Y ||
(newNode->Contour[k].Y == ip.Y &&
newNode->Contour[k].X < ip.X))
m_lowest = IntPoint(m_polyNodes.ChildCount() - 1, k);
}
}
//------------------------------------------------------------------------------
void ClipperOffset::AddPaths(const Paths& paths, JoinType joinType, EndType endType)
{
for (Paths::size_type i = 0; i < paths.size(); ++i)
AddPath(paths[i], joinType, endType);
}
//------------------------------------------------------------------------------
void ClipperOffset::FixOrientations()
{
//fixup orientations of all closed paths if the orientation of the
//closed path with the lowermost vertex is wrong ...
if (m_lowest.X >= 0 &&
!Orientation(m_polyNodes.Childs[(int)m_lowest.X]->Contour))
{
for (int i = 0; i < m_polyNodes.ChildCount(); ++i)
{
PolyNode& node = *m_polyNodes.Childs[i];
if (node.m_endtype == etClosedPolygon ||
(node.m_endtype == etClosedLine && Orientation(node.Contour)))
ReversePath(node.Contour);
}
} else
{
for (int i = 0; i < m_polyNodes.ChildCount(); ++i)
{
PolyNode& node = *m_polyNodes.Childs[i];
if (node.m_endtype == etClosedLine && !Orientation(node.Contour))
ReversePath(node.Contour);
}
}
}
//------------------------------------------------------------------------------
void ClipperOffset::Execute(Paths& solution, double delta)
{
solution.clear();
FixOrientations();
DoOffset(delta);
//now clean up 'corners' ...
Clipper clpr;
clpr.AddPaths(m_destPolys, ptSubject, true);
if (delta > 0)
{
clpr.Execute(ctUnion, solution, pftPositive, pftPositive);
}
else
{
IntRect r = clpr.GetBounds();
Path outer(4);
outer[0] = IntPoint(r.left - 10, r.bottom + 10);
outer[1] = IntPoint(r.right + 10, r.bottom + 10);
outer[2] = IntPoint(r.right + 10, r.top - 10);
outer[3] = IntPoint(r.left - 10, r.top - 10);
clpr.AddPath(outer, ptSubject, true);
clpr.ReverseSolution(true);
clpr.Execute(ctUnion, solution, pftNegative, pftNegative);
if (solution.size() > 0) solution.erase(solution.begin());
}
}
//------------------------------------------------------------------------------
void ClipperOffset::Execute(PolyTree& solution, double delta)
{
solution.Clear();
FixOrientations();
DoOffset(delta);
//now clean up 'corners' ...
Clipper clpr;
clpr.AddPaths(m_destPolys, ptSubject, true);
if (delta > 0)
{
clpr.Execute(ctUnion, solution, pftPositive, pftPositive);
}
else
{
IntRect r = clpr.GetBounds();
Path outer(4);
outer[0] = IntPoint(r.left - 10, r.bottom + 10);
outer[1] = IntPoint(r.right + 10, r.bottom + 10);
outer[2] = IntPoint(r.right + 10, r.top - 10);
outer[3] = IntPoint(r.left - 10, r.top - 10);
clpr.AddPath(outer, ptSubject, true);
clpr.ReverseSolution(true);
clpr.Execute(ctUnion, solution, pftNegative, pftNegative);
//remove the outer PolyNode rectangle ...
if (solution.ChildCount() == 1 && solution.Childs[0]->ChildCount() > 0)
{
PolyNode* outerNode = solution.Childs[0];
solution.Childs.reserve(outerNode->ChildCount());
solution.Childs[0] = outerNode->Childs[0];
solution.Childs[0]->Parent = outerNode->Parent;
for (int i = 1; i < outerNode->ChildCount(); ++i)
solution.AddChild(*outerNode->Childs[i]);
}
else
solution.Clear();
}
}
//------------------------------------------------------------------------------
void ClipperOffset::DoOffset(double delta)
{
m_destPolys.clear();
m_delta = delta;
//if Zero offset, just copy any CLOSED polygons to m_p and return ...
if (NEAR_ZERO(delta))
{
m_destPolys.reserve(m_polyNodes.ChildCount());
for (int i = 0; i < m_polyNodes.ChildCount(); i++)
{
PolyNode& node = *m_polyNodes.Childs[i];
if (node.m_endtype == etClosedPolygon)
m_destPolys.push_back(node.Contour);
}
return;
}
//see offset_triginometry3.svg in the documentation folder ...
if (MiterLimit > 2) m_miterLim = 2/(MiterLimit * MiterLimit);
else m_miterLim = 0.5;
double y;
if (ArcTolerance <= 0.0) y = def_arc_tolerance;
else if (ArcTolerance > std::fabs(delta) * def_arc_tolerance)
y = std::fabs(delta) * def_arc_tolerance;
else y = ArcTolerance;
//see offset_triginometry2.svg in the documentation folder ...
double steps = pi / std::acos(1 - y / std::fabs(delta));
if (steps > std::fabs(delta) * pi)
steps = std::fabs(delta) * pi; //ie excessive precision check
m_sin = std::sin(two_pi / steps);
m_cos = std::cos(two_pi / steps);
m_StepsPerRad = steps / two_pi;
if (delta < 0.0) m_sin = -m_sin;
m_destPolys.reserve(m_polyNodes.ChildCount() * 2);
for (int i = 0; i < m_polyNodes.ChildCount(); i++)
{
PolyNode& node = *m_polyNodes.Childs[i];
m_srcPoly = node.Contour;
int len = (int)m_srcPoly.size();
if (len == 0 || (delta <= 0 && (len < 3 || node.m_endtype != etClosedPolygon)))
continue;
m_destPoly.clear();
if (len == 1)
{
if (node.m_jointype == jtRound)
{
double X = 1.0, Y = 0.0;
for (cInt j = 1; j <= steps; j++)
{
m_destPoly.push_back(IntPoint(
Round(m_srcPoly[0].X + X * delta),
Round(m_srcPoly[0].Y + Y * delta)));
double X2 = X;
X = X * m_cos - m_sin * Y;
Y = X2 * m_sin + Y * m_cos;
}
}
else
{
double X = -1.0, Y = -1.0;
for (int j = 0; j < 4; ++j)
{
m_destPoly.push_back(IntPoint(
Round(m_srcPoly[0].X + X * delta),
Round(m_srcPoly[0].Y + Y * delta)));
if (X < 0) X = 1;
else if (Y < 0) Y = 1;
else X = -1;
}
}
m_destPolys.push_back(m_destPoly);
continue;
}
//build m_normals ...
m_normals.clear();
m_normals.reserve(len);
for (int j = 0; j < len - 1; ++j)
m_normals.push_back(GetUnitNormal(m_srcPoly[j], m_srcPoly[j + 1]));
if (node.m_endtype == etClosedLine || node.m_endtype == etClosedPolygon)
m_normals.push_back(GetUnitNormal(m_srcPoly[len - 1], m_srcPoly[0]));
else
m_normals.push_back(DoublePoint(m_normals[len - 2]));
if (node.m_endtype == etClosedPolygon)
{
int k = len - 1;
for (int j = 0; j < len; ++j)
OffsetPoint(j, k, node.m_jointype);
m_destPolys.push_back(m_destPoly);
}
else if (node.m_endtype == etClosedLine)
{
int k = len - 1;
for (int j = 0; j < len; ++j)
OffsetPoint(j, k, node.m_jointype);
m_destPolys.push_back(m_destPoly);
m_destPoly.clear();
//re-build m_normals ...
DoublePoint n = m_normals[len -1];
for (int j = len - 1; j > 0; j--)
m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y);
m_normals[0] = DoublePoint(-n.X, -n.Y);
k = 0;
for (int j = len - 1; j >= 0; j--)
OffsetPoint(j, k, node.m_jointype);
m_destPolys.push_back(m_destPoly);
}
else
{
int k = 0;
for (int j = 1; j < len - 1; ++j)
OffsetPoint(j, k, node.m_jointype);
IntPoint pt1;
if (node.m_endtype == etOpenButt)
{
int j = len - 1;
pt1 = IntPoint((cInt)Round(m_srcPoly[j].X + m_normals[j].X *
delta), (cInt)Round(m_srcPoly[j].Y + m_normals[j].Y * delta));
m_destPoly.push_back(pt1);
pt1 = IntPoint((cInt)Round(m_srcPoly[j].X - m_normals[j].X *
delta), (cInt)Round(m_srcPoly[j].Y - m_normals[j].Y * delta));
m_destPoly.push_back(pt1);
}
else
{
int j = len - 1;
k = len - 2;
m_sinA = 0;
m_normals[j] = DoublePoint(-m_normals[j].X, -m_normals[j].Y);
if (node.m_endtype == etOpenSquare)
DoSquare(j, k);
else
DoRound(j, k);
}
//re-build m_normals ...
for (int j = len - 1; j > 0; j--)
m_normals[j] = DoublePoint(-m_normals[j - 1].X, -m_normals[j - 1].Y);
m_normals[0] = DoublePoint(-m_normals[1].X, -m_normals[1].Y);
k = len - 1;
for (int j = k - 1; j > 0; --j) OffsetPoint(j, k, node.m_jointype);
if (node.m_endtype == etOpenButt)
{
pt1 = IntPoint((cInt)Round(m_srcPoly[0].X - m_normals[0].X * delta),
(cInt)Round(m_srcPoly[0].Y - m_normals[0].Y * delta));
m_destPoly.push_back(pt1);
pt1 = IntPoint((cInt)Round(m_srcPoly[0].X + m_normals[0].X * delta),
(cInt)Round(m_srcPoly[0].Y + m_normals[0].Y * delta));
m_destPoly.push_back(pt1);
}
else
{
k = 1;
m_sinA = 0;
if (node.m_endtype == etOpenSquare)
DoSquare(0, 1);
else
DoRound(0, 1);
}
m_destPolys.push_back(m_destPoly);
}
}
}
//------------------------------------------------------------------------------
void ClipperOffset::OffsetPoint(int j, int& k, JoinType jointype)
{
//cross product ...
m_sinA = (m_normals[k].X * m_normals[j].Y - m_normals[j].X * m_normals[k].Y);
if (std::fabs(m_sinA * m_delta) < 1.0)
{
//dot product ...
double cosA = (m_normals[k].X * m_normals[j].X + m_normals[j].Y * m_normals[k].Y );
if (cosA > 0) // angle => 0 degrees
{
m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta)));
return;
}
//else angle => 180 degrees
}
else if (m_sinA > 1.0) m_sinA = 1.0;
else if (m_sinA < -1.0) m_sinA = -1.0;
if (m_sinA * m_delta < 0)
{
m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[k].X * m_delta),
Round(m_srcPoly[j].Y + m_normals[k].Y * m_delta)));
m_destPoly.push_back(m_srcPoly[j]);
m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta)));
}
else
switch (jointype)
{
case jtMiter:
{
double r = 1 + (m_normals[j].X * m_normals[k].X +
m_normals[j].Y * m_normals[k].Y);
if (r >= m_miterLim) DoMiter(j, k, r); else DoSquare(j, k);
break;
}
case jtSquare: DoSquare(j, k); break;
case jtRound: DoRound(j, k); break;
}
k = j;
}
//------------------------------------------------------------------------------
void ClipperOffset::DoSquare(int j, int k)
{
double dx = std::tan(std::atan2(m_sinA,
m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y) / 4);
m_destPoly.push_back(IntPoint(
Round(m_srcPoly[j].X + m_delta * (m_normals[k].X - m_normals[k].Y * dx)),
Round(m_srcPoly[j].Y + m_delta * (m_normals[k].Y + m_normals[k].X * dx))));
m_destPoly.push_back(IntPoint(
Round(m_srcPoly[j].X + m_delta * (m_normals[j].X + m_normals[j].Y * dx)),
Round(m_srcPoly[j].Y + m_delta * (m_normals[j].Y - m_normals[j].X * dx))));
}
//------------------------------------------------------------------------------
void ClipperOffset::DoMiter(int j, int k, double r)
{
double q = m_delta / r;
m_destPoly.push_back(IntPoint(Round(m_srcPoly[j].X + (m_normals[k].X + m_normals[j].X) * q),
Round(m_srcPoly[j].Y + (m_normals[k].Y + m_normals[j].Y) * q)));
}
//------------------------------------------------------------------------------
void ClipperOffset::DoRound(int j, int k)
{
double a = std::atan2(m_sinA,
m_normals[k].X * m_normals[j].X + m_normals[k].Y * m_normals[j].Y);
int steps = std::max((int)Round(m_StepsPerRad * std::fabs(a)), 1);
double X = m_normals[k].X, Y = m_normals[k].Y, X2;
for (int i = 0; i < steps; ++i)
{
m_destPoly.push_back(IntPoint(
Round(m_srcPoly[j].X + X * m_delta),
Round(m_srcPoly[j].Y + Y * m_delta)));
X2 = X;
X = X * m_cos - m_sin * Y;
Y = X2 * m_sin + Y * m_cos;
}
m_destPoly.push_back(IntPoint(
Round(m_srcPoly[j].X + m_normals[j].X * m_delta),
Round(m_srcPoly[j].Y + m_normals[j].Y * m_delta)));
}
//------------------------------------------------------------------------------
// Miscellaneous public functions
//------------------------------------------------------------------------------
void Clipper::DoSimplePolygons()
{
PolyOutList::size_type i = 0;
while (i < m_PolyOuts.size())
{
OutRec* outrec = m_PolyOuts[i++];
OutPt* op = outrec->Pts;
if (!op || outrec->IsOpen) continue;
do //for each Pt in Polygon until duplicate found do ...
{
OutPt* op2 = op->Next;
while (op2 != outrec->Pts)
{
if ((op->Pt == op2->Pt) && op2->Next != op && op2->Prev != op)
{
//split the polygon into two ...
OutPt* op3 = op->Prev;
OutPt* op4 = op2->Prev;
op->Prev = op4;
op4->Next = op;
op2->Prev = op3;
op3->Next = op2;
outrec->Pts = op;
OutRec* outrec2 = CreateOutRec();
outrec2->Pts = op2;
UpdateOutPtIdxs(*outrec2);
if (Poly2ContainsPoly1(outrec2->Pts, outrec->Pts))
{
//OutRec2 is contained by OutRec1 ...
outrec2->IsHole = !outrec->IsHole;
outrec2->FirstLeft = outrec;
if (m_UsingPolyTree) FixupFirstLefts2(outrec2, outrec);
}
else
if (Poly2ContainsPoly1(outrec->Pts, outrec2->Pts))
{
//OutRec1 is contained by OutRec2 ...
outrec2->IsHole = outrec->IsHole;
outrec->IsHole = !outrec2->IsHole;
outrec2->FirstLeft = outrec->FirstLeft;
outrec->FirstLeft = outrec2;
if (m_UsingPolyTree) FixupFirstLefts2(outrec, outrec2);
}
else
{
//the 2 polygons are separate ...
outrec2->IsHole = outrec->IsHole;
outrec2->FirstLeft = outrec->FirstLeft;
if (m_UsingPolyTree) FixupFirstLefts1(outrec, outrec2);
}
op2 = op; //ie get ready for the Next iteration
}
op2 = op2->Next;
}
op = op->Next;
}
while (op != outrec->Pts);
}
}
//------------------------------------------------------------------------------
void ReversePath(Path& p)
{
std::reverse(p.begin(), p.end());
}
//------------------------------------------------------------------------------
void ReversePaths(Paths& p)
{
for (Paths::size_type i = 0; i < p.size(); ++i)
ReversePath(p[i]);
}
//------------------------------------------------------------------------------
void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillType fillType)
{
Clipper c;
c.StrictlySimple(true);
c.AddPath(in_poly, ptSubject, true);
c.Execute(ctUnion, out_polys, fillType, fillType);
}
//------------------------------------------------------------------------------
void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFillType fillType)
{
Clipper c;
c.StrictlySimple(true);
c.AddPaths(in_polys, ptSubject, true);
c.Execute(ctUnion, out_polys, fillType, fillType);
}
//------------------------------------------------------------------------------
void SimplifyPolygons(Paths &polys, PolyFillType fillType)
{
SimplifyPolygons(polys, polys, fillType);
}
//------------------------------------------------------------------------------
inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2)
{
double Dx = ((double)pt1.X - pt2.X);
double dy = ((double)pt1.Y - pt2.Y);
return (Dx*Dx + dy*dy);
}
//------------------------------------------------------------------------------
double DistanceFromLineSqrd(
const IntPoint& pt, const IntPoint& ln1, const IntPoint& ln2)
{
//The equation of a line in general form (Ax + By + C = 0)
//given 2 points (x¹,y¹) & (x²,y²) is ...
//(y¹ - y²)x + (x² - x¹)y + (y² - y¹)x¹ - (x² - x¹)y¹ = 0
//A = (y¹ - y²); B = (x² - x¹); C = (y² - y¹)x¹ - (x² - x¹)y¹
//perpendicular distance of point (x³,y³) = (Ax³ + By³ + C)/Sqrt(A² + B²)
//see http://en.wikipedia.org/wiki/Perpendicular_distance
double A = double(ln1.Y - ln2.Y);
double B = double(ln2.X - ln1.X);
double C = A * ln1.X + B * ln1.Y;
C = A * pt.X + B * pt.Y - C;
return (C * C) / (A * A + B * B);
}
//---------------------------------------------------------------------------
bool SlopesNearCollinear(const IntPoint& pt1,
const IntPoint& pt2, const IntPoint& pt3, double distSqrd)
{
//this function is more accurate when the point that's geometrically
//between the other 2 points is the one that's tested for distance.
//ie makes it more likely to pick up 'spikes' ...
if (Abs(pt1.X - pt2.X) > Abs(pt1.Y - pt2.Y))
{
if ((pt1.X > pt2.X) == (pt1.X < pt3.X))
return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd;
else if ((pt2.X > pt1.X) == (pt2.X < pt3.X))
return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
else
return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd;
}
else
{
if ((pt1.Y > pt2.Y) == (pt1.Y < pt3.Y))
return DistanceFromLineSqrd(pt1, pt2, pt3) < distSqrd;
else if ((pt2.Y > pt1.Y) == (pt2.Y < pt3.Y))
return DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
else
return DistanceFromLineSqrd(pt3, pt1, pt2) < distSqrd;
}
}
//------------------------------------------------------------------------------
bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd)
{
double Dx = (double)pt1.X - pt2.X;
double dy = (double)pt1.Y - pt2.Y;
return ((Dx * Dx) + (dy * dy) <= distSqrd);
}
//------------------------------------------------------------------------------
OutPt* ExcludeOp(OutPt* op)
{
OutPt* result = op->Prev;
result->Next = op->Next;
op->Next->Prev = result;
result->Idx = 0;
return result;
}
//------------------------------------------------------------------------------
void CleanPolygon(const Path& in_poly, Path& out_poly, double distance)
{
//distance = proximity in units/pixels below which vertices
//will be stripped. Default ~= sqrt(2).
size_t size = in_poly.size();
if (size == 0)
{
out_poly.clear();
return;
}
OutPt* outPts = new OutPt[size];
for (size_t i = 0; i < size; ++i)
{
outPts[i].Pt = in_poly[i];
outPts[i].Next = &outPts[(i + 1) % size];
outPts[i].Next->Prev = &outPts[i];
outPts[i].Idx = 0;
}
double distSqrd = distance * distance;
OutPt* op = &outPts[0];
while (op->Idx == 0 && op->Next != op->Prev)
{
if (PointsAreClose(op->Pt, op->Prev->Pt, distSqrd))
{
op = ExcludeOp(op);
size--;
}
else if (PointsAreClose(op->Prev->Pt, op->Next->Pt, distSqrd))
{
ExcludeOp(op->Next);
op = ExcludeOp(op);
size -= 2;
}
else if (SlopesNearCollinear(op->Prev->Pt, op->Pt, op->Next->Pt, distSqrd))
{
op = ExcludeOp(op);
size--;
}
else
{
op->Idx = 1;
op = op->Next;
}
}
if (size < 3) size = 0;
out_poly.resize(size);
for (size_t i = 0; i < size; ++i)
{
out_poly[i] = op->Pt;
op = op->Next;
}
delete [] outPts;
}
//------------------------------------------------------------------------------
void CleanPolygon(Path& poly, double distance)
{
CleanPolygon(poly, poly, distance);
}
//------------------------------------------------------------------------------
void CleanPolygons(const Paths& in_polys, Paths& out_polys, double distance)
{
out_polys.resize(in_polys.size());
for (Paths::size_type i = 0; i < in_polys.size(); ++i)
CleanPolygon(in_polys[i], out_polys[i], distance);
}
//------------------------------------------------------------------------------
void CleanPolygons(Paths& polys, double distance)
{
CleanPolygons(polys, polys, distance);
}
//------------------------------------------------------------------------------
void Minkowski(const Path& poly, const Path& path,
Paths& solution, bool isSum, bool isClosed)
{
int delta = (isClosed ? 1 : 0);
size_t polyCnt = poly.size();
size_t pathCnt = path.size();
Paths pp;
pp.reserve(pathCnt);
if (isSum)
for (size_t i = 0; i < pathCnt; ++i)
{
Path p;
p.reserve(polyCnt);
for (size_t j = 0; j < poly.size(); ++j)
p.push_back(IntPoint(path[i].X + poly[j].X, path[i].Y + poly[j].Y));
pp.push_back(p);
}
else
for (size_t i = 0; i < pathCnt; ++i)
{
Path p;
p.reserve(polyCnt);
for (size_t j = 0; j < poly.size(); ++j)
p.push_back(IntPoint(path[i].X - poly[j].X, path[i].Y - poly[j].Y));
pp.push_back(p);
}
solution.clear();
solution.reserve((pathCnt + delta) * (polyCnt + 1));
for (size_t i = 0; i < pathCnt - 1 + delta; ++i)
for (size_t j = 0; j < polyCnt; ++j)
{
Path quad;
quad.reserve(4);
quad.push_back(pp[i % pathCnt][j % polyCnt]);
quad.push_back(pp[(i + 1) % pathCnt][j % polyCnt]);
quad.push_back(pp[(i + 1) % pathCnt][(j + 1) % polyCnt]);
quad.push_back(pp[i % pathCnt][(j + 1) % polyCnt]);
if (!Orientation(quad)) ReversePath(quad);
solution.push_back(quad);
}
}
//------------------------------------------------------------------------------
void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool pathIsClosed)
{
Minkowski(pattern, path, solution, true, pathIsClosed);
Clipper c;
c.AddPaths(solution, ptSubject, true);
c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
}
//------------------------------------------------------------------------------
void TranslatePath(const Path& input, Path& output, const IntPoint &delta)
{
//precondition: input != output
output.resize(input.size());
for (size_t i = 0; i < input.size(); ++i)
output[i] = IntPoint(input[i].X + delta.X, input[i].Y + delta.Y);
}
//------------------------------------------------------------------------------
void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solution, bool pathIsClosed)
{
Clipper c;
for (size_t i = 0; i < paths.size(); ++i)
{
Paths tmp;
Minkowski(pattern, paths[i], tmp, true, pathIsClosed);
c.AddPaths(tmp, ptSubject, true);
if (pathIsClosed)
{
Path tmp2;
TranslatePath(paths[i], tmp2, pattern[0]);
c.AddPath(tmp2, ptClip, true);
}
}
c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
}
//------------------------------------------------------------------------------
void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution)
{
Minkowski(poly1, poly2, solution, false, true);
Clipper c;
c.AddPaths(solution, ptSubject, true);
c.Execute(ctUnion, solution, pftNonZero, pftNonZero);
}
//------------------------------------------------------------------------------
enum NodeType {ntAny, ntOpen, ntClosed};
void AddPolyNodeToPaths(const PolyNode& polynode, NodeType nodetype, Paths& paths)
{
bool match = true;
if (nodetype == ntClosed) match = !polynode.IsOpen();
else if (nodetype == ntOpen) return;
if (!polynode.Contour.empty() && match)
paths.push_back(polynode.Contour);
for (int i = 0; i < polynode.ChildCount(); ++i)
AddPolyNodeToPaths(*polynode.Childs[i], nodetype, paths);
}
//------------------------------------------------------------------------------
void PolyTreeToPaths(const PolyTree& polytree, Paths& paths)
{
paths.resize(0);
paths.reserve(polytree.Total());
AddPolyNodeToPaths(polytree, ntAny, paths);
}
//------------------------------------------------------------------------------
void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths)
{
paths.resize(0);
paths.reserve(polytree.Total());
AddPolyNodeToPaths(polytree, ntClosed, paths);
}
//------------------------------------------------------------------------------
void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths)
{
paths.resize(0);
paths.reserve(polytree.Total());
//Open paths are top level only, so ...
for (int i = 0; i < polytree.ChildCount(); ++i)
if (polytree.Childs[i]->IsOpen())
paths.push_back(polytree.Childs[i]->Contour);
}
//------------------------------------------------------------------------------
std::ostream& operator <<(std::ostream &s, const IntPoint &p)
{
s << "(" << p.X << "," << p.Y << ")";
return s;
}
//------------------------------------------------------------------------------
std::ostream& operator <<(std::ostream &s, const Path &p)
{
if (p.empty()) return s;
Path::size_type last = p.size() -1;
for (Path::size_type i = 0; i < last; i++)
s << "(" << p[i].X << "," << p[i].Y << "), ";
s << "(" << p[last].X << "," << p[last].Y << ")\n";
return s;
}
//------------------------------------------------------------------------------
std::ostream& operator <<(std::ostream &s, const Paths &p)
{
for (Paths::size_type i = 0; i < p.size(); i++)
s << p[i];
s << "\n";
return s;
}
IntPoint::IntPoint(const Marble::GeoDataCoordinates *coordinates) :
X(qRound64(coordinates->longitude() * scale)),
Y(qRound64(coordinates->latitude() * scale)),
m_coordinates(coordinates)
{
// nothing to do
}
Marble::GeoDataCoordinates IntPoint::coordinates() const
{
using namespace Marble;
GeoDataCoordinates const coords = GeoDataCoordinates(double(X) / scale, double(Y) / scale);
if (m_coordinates) {
bool const clipperKeptTheNode = qRound64(m_coordinates->longitude() * scale) == X &&
qRound64(m_coordinates->latitude() * scale) == Y;
if (clipperKeptTheNode) {
return *m_coordinates;
}
}
return coords;
}
bool IntPoint::isInside(const cInt &minX, const cInt &maxX, const cInt &minY, const cInt &maxY) const
{
return X > minX && X < maxX && Y > minY && Y < maxY;
}
//------------------------------------------------------------------------------
} //ClipperLib namespace