Hello! I'm sending in attachement my patch for Measure Tool plugin. Quick summary of changes: 1. Add load/save measure points. It's under View menu (where plugin actions go). It simply saves measure points to KML file as GeoDataLineString. 2. Ability to add measure points quicker using Ctrl + mouse left click. It works when there is at least one measure point on map. 3. As side effect I added "Center on Measure Points" option under "Right click menu". I needed it to Load Measure Points to work properly. 4. Right click stops kineticSpinning - without that Center on Measure Points doesn't work properly when spinning. I don't know if it's good place for patch like this so if it's not could you send me to a proper place? I'm looking forward to your review. Tomasz Meresiński
>From 907d6aab6e96c53149cff7887619f7c608b7f424 Mon Sep 17 00:00:00 2001 From: Tomasz Meresinski <[email protected]> Date: Sat, 27 Jun 2015 11:42:00 +0200 Subject: [PATCH] Measure tool plugin improvements --- src/lib/marble/MarbleInputHandler.cpp | 4 + src/plugins/render/measure/MeasureToolPlugin.cpp | 170 ++++++++++++++++++++++- src/plugins/render/measure/MeasureToolPlugin.h | 22 ++- 3 files changed, 193 insertions(+), 3 deletions(-) diff --git a/src/lib/marble/MarbleInputHandler.cpp b/src/lib/marble/MarbleInputHandler.cpp index 517d117..63e79b3 100644 --- a/src/lib/marble/MarbleInputHandler.cpp +++ b/src/lib/marble/MarbleInputHandler.cpp @@ -492,6 +492,10 @@ void MarbleDefaultInputHandler::handleMiddleMouseButtonPress(QMouseEvent *event) void MarbleDefaultInputHandler::handleRightMouseButtonPress(QMouseEvent *event) { + if (MarbleInputHandler::d->m_inertialEarthRotation) + { + d->m_kineticSpinning.stop(); + } emit rmbRequest(event->x(), event->y()); } diff --git a/src/plugins/render/measure/MeasureToolPlugin.cpp b/src/plugins/render/measure/MeasureToolPlugin.cpp index 3f07ed0..27ebd37 100644 --- a/src/plugins/render/measure/MeasureToolPlugin.cpp +++ b/src/plugins/render/measure/MeasureToolPlugin.cpp @@ -18,12 +18,18 @@ #include "GeoPainter.h" #include "GeoDataLinearRing.h" +#include <GeoDataDocument.h> +#include <GeoDataPlacemark.h> #include "MarbleDebug.h" #include "MarbleMath.h" #include "MarbleModel.h" #include "MarbleLocale.h" #include "ViewportParams.h" #include "Planet.h" +#include "GeoWriter.h" +#include "handlers/kml/KmlElementDictionary.h" +#include "GeoDataParser.h" +#include <GeoDataTypes.h> #include <QDialog> #include <QColor> @@ -32,7 +38,10 @@ #include <QPushButton> #include <QCheckBox> #include <QTextDocument> +#include <QFileDialog> #include <qmath.h> +#include <QFile> +#include <QMessageBox> namespace Marble { @@ -51,7 +60,12 @@ MeasureToolPlugin::MeasureToolPlugin( const MarbleModel *marbleModel ) m_addMeasurePointAction( 0 ), m_removeLastMeasurePointAction( 0 ), m_removeMeasurePointsAction( 0 ), + m_saveMeasurePointsAction( 0 ), + m_loadMeasurePointsAction( 0 ), + m_centerOnMeasurePointsAction( 0 ), m_separator( 0 ), + m_isMouseAddActionEnabled( false ), + m_lastSavePath( QDir::homePath() ), m_marbleWidget( 0 ), m_configDialog( 0 ), m_showDistanceLabel( true ), @@ -593,11 +607,22 @@ void MeasureToolPlugin::drawInfobox( GeoPainter *painter ) const painter->setTransform(QTransform()); } +void MeasureToolPlugin::addMeasurePointMouseEvent(qreal lon, qreal lat) +{ + if ( QApplication::keyboardModifiers().testFlag( Qt::ControlModifier ) ) { + addMeasurePoint( lon, lat ); + emit repaintNeeded(); + } +} + void MeasureToolPlugin::addMeasurePoint( qreal lon, qreal lat ) { + if (m_paintMode == Circular && m_measureLineString.size() >= 2) { + return; + } m_measureLineString << GeoDataCoordinates( lon, lat ); - + emit numberOfMeasurePointsChanged( m_measureLineString.size() ); } @@ -616,6 +641,110 @@ void MeasureToolPlugin::removeMeasurePoints() emit numberOfMeasurePointsChanged( m_measureLineString.size() ); } +void MeasureToolPlugin::saveMeasurePoints() +{ + QString fileName = QFileDialog::getSaveFileName( m_marbleWidget, QObject::tr( "Save Measure Points" ), + m_lastSavePath, QObject::tr( "KML File (*.kml)" ), 0, QFileDialog::DontResolveSymlinks ); + //Qt5 does not append fileName with extension, ehh.. + if (!fileName.midRef( 1 ).contains( '.' )) { //I want to add extension only if fileName does not contain one + fileName.append( QStringLiteral(".kml") ); + } + + if ( !fileName.isEmpty() ) { + if ( saveToKml( fileName )) { + m_lastSavePath = QFileInfo( fileName ).absolutePath(); + } + } +} + +void MeasureToolPlugin::loadMeasurePoints() +{ + QString fileName = QFileDialog::getOpenFileName( m_marbleWidget, QObject::tr("Load Measure Points"), + m_lastSavePath, QObject::tr( "KML File (*.kml);;All Files (*)" ), 0, QFileDialog::DontResolveSymlinks ); + + if ( !fileName.isEmpty() ) { + if ( loadFromKml( fileName ) ) { + if ( m_paintMode == Circular && m_measureLineString.size() > 2 ) { + m_measureLineString.erase(m_measureLineString.begin() + 2, m_measureLineString.end()); + } + m_lastSavePath = QFileInfo( fileName ).absolutePath(); + centerOnTrack(); + emit numberOfMeasurePointsChanged( m_measureLineString.size() ); + } + } +} + +bool MeasureToolPlugin::saveToKml(QString fileName) +{ + if ( fileName.isEmpty() ) { + return false; + } + + GeoDataDocument document; + GeoDataPlacemark *placemark = new GeoDataPlacemark; + placemark->setGeometry( new GeoDataLineString(m_measureLineString) ); + document.append( placemark ); + GeoWriter writer; + QFile outFile( fileName ); + if ( !outFile.open( QIODevice::WriteOnly ) ) { + QMessageBox::warning( m_marbleWidget, QObject::tr("Cannot open file"), outFile.errorString() ); + return false; + } + if ( !writer.write( &outFile, &document ) ) { + QMessageBox::warning( m_marbleWidget, QObject::tr("Cannot save measure points"), QObject::tr("Cannot write to file")); + return false; + } + return true; +} + +bool MeasureToolPlugin::loadFromKml(QString fileName) +{ + GeoDataParser parser( GeoData_KML ); + QFile inFile( fileName ); + if ( !inFile.open( QIODevice::ReadOnly ) ) { + return false; + } + if ( !parser.read( &inFile ) ) { + return false; + } + GeoDocument *document = parser.releaseDocument(); + if ( document->isGeoDataDocument() ) { + GeoDataDocument *dataDocument = (GeoDataDocument *)document; + if ( dataDocument->size() == 1) { + GeoDataFeature &feature = dataDocument->first(); + if ( feature.nodeType() == GeoDataTypes::GeoDataPlacemarkType ) { + GeoDataGeometry *geometry = static_cast<GeoDataPlacemark &>(feature).geometry(); + if ( geometry->nodeType() == GeoDataTypes::GeoDataLineStringType ) { + m_measureLineString = *(GeoDataLineString *)geometry; + return true; + } + } + } + } + return false; +} + +void MeasureToolPlugin::centerOnTrack() +{ + GeoDataLineString fullPath = m_measureLineString; + if ( m_paintMode == Circular && m_measureLineString.size() == 2 ) { + fullPath.append( m_measureLineString.at(1).rotateAround( m_measureLineString.at(0), 180, GeoDataCoordinates::Degree ) ); + } + m_marbleWidget->centerOn( fullPath.latLonAltBox() ); +} + +const QList< QActionGroup* >* MeasureToolPlugin::actionGroups() const +{ + return &m_actionGroups; +} + +const QList< QActionGroup* >* MeasureToolPlugin::toolbarActionGroups() const +{ + return &m_actionGroups; +} + + + void MeasureToolPlugin::addContextItems() { MarbleWidgetPopupMenu *menu = m_marbleWidget->popupMenu(); @@ -628,20 +757,37 @@ void MeasureToolPlugin::addContextItems() m_removeMeasurePointsAction->setEnabled( false ); m_separator = new QAction( this ); m_separator->setSeparator( true ); + m_centerOnMeasurePointsAction = new QAction( tr( "&Center On Measure Points" ), this ); + m_centerOnMeasurePointsAction->setEnabled( false ); 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_centerOnMeasurePointsAction ); + menu->addAction( Qt::RightButton, m_saveMeasurePointsAction ); + menu->addAction( Qt::RightButton, m_loadMeasurePointsAction ); 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( m_centerOnMeasurePointsAction, SIGNAL(triggered()), SLOT(centerOnTrack()) ); connect( this, SIGNAL(numberOfMeasurePointsChanged(int)), SLOT(setNumberOfMeasurePoints(int)) ); + + cleanActionGroups(); + QActionGroup *group = new QActionGroup(this); + m_saveMeasurePointsAction = new QAction( tr( "&Save Measure Points"), this ); + m_saveMeasurePointsAction->setEnabled( false ); + group->addAction(m_saveMeasurePointsAction); + m_loadMeasurePointsAction = new QAction( tr( "&Load Measure Points"), this); + group->addAction(m_loadMeasurePointsAction); + m_actionGroups.append(group); + connect( m_saveMeasurePointsAction, SIGNAL(triggered()), SLOT(saveMeasurePoints())); + connect( m_loadMeasurePointsAction, SIGNAL(triggered()), SLOT(loadMeasurePoints())); } void MeasureToolPlugin::removeContextItems() @@ -649,9 +795,18 @@ void MeasureToolPlugin::removeContextItems() delete m_addMeasurePointAction; delete m_removeLastMeasurePointAction; delete m_removeMeasurePointsAction; + delete m_centerOnMeasurePointsAction; delete m_separator; + cleanActionGroups(); } +void MeasureToolPlugin::cleanActionGroups() +{ + qDeleteAll(m_actionGroups); + emit actionGroupsChanged(); +} + + void MeasureToolPlugin::addMeasurePointEvent() { QPoint p = m_marbleWidget->popupMenu()->mousePosition(); @@ -668,7 +823,18 @@ void MeasureToolPlugin::setNumberOfMeasurePoints( int newNumber ) const bool enableMeasureActions = ( newNumber > 0 ); m_removeMeasurePointsAction->setEnabled(enableMeasureActions); m_removeLastMeasurePointAction->setEnabled(enableMeasureActions); + m_centerOnMeasurePointsAction->setEnabled(enableMeasureActions); + m_saveMeasurePointsAction->setEnabled(enableMeasureActions); + if ( enableMeasureActions && !m_isMouseAddActionEnabled ) { + connect( m_marbleWidget, SIGNAL(mouseClickGeoPosition(qreal, qreal, GeoDataCoordinates::Unit)), SLOT(addMeasurePointMouseEvent(qreal,qreal))); + m_isMouseAddActionEnabled = true; + } + else if ( !enableMeasureActions && m_isMouseAddActionEnabled ) { + disconnect( m_marbleWidget, SIGNAL(mouseClickGeoPosition(qreal, qreal, GeoDataCoordinates::Unit)), this, SLOT(addMeasurePointMouseEvent(qreal,qreal))); + m_isMouseAddActionEnabled = false; + } + if (m_paintMode == Circular) { if (newNumber >= 2) { m_addMeasurePointAction->setEnabled(false); diff --git a/src/plugins/render/measure/MeasureToolPlugin.h b/src/plugins/render/measure/MeasureToolPlugin.h index e78d381..3833eab 100644 --- a/src/plugins/render/measure/MeasureToolPlugin.h +++ b/src/plugins/render/measure/MeasureToolPlugin.h @@ -27,6 +27,7 @@ #include <QFont> #include <QPen> #include <QAction> +#include <QMetaObject> namespace Marble { @@ -74,6 +75,9 @@ class MeasureToolPlugin : public RenderPlugin, public DialogConfigurationInterfa QDialog *configDialog(); QHash<QString,QVariant> settings() const; void setSettings( const QHash<QString,QVariant> &settings ); + + const QList<QActionGroup *> *actionGroups() const; + const QList<QActionGroup *> *toolbarActionGroups() const; Q_SIGNALS: void numberOfMeasurePointsChanged( int newNumber ); @@ -87,14 +91,20 @@ class MeasureToolPlugin : public RenderPlugin, public DialogConfigurationInterfa void drawSegments( GeoPainter *painter ); void addContextItems(); void removeContextItems(); + bool saveToKml( QString fileName ); + bool loadFromKml( QString fileName ); private Q_SLOTS: void setNumberOfMeasurePoints( int number ); void addMeasurePointEvent(); - + void addMeasurePointMouseEvent( qreal lon, qreal lat ); + void addMeasurePoint( qreal lon, qreal lat ); void removeLastMeasurePoint(); void removeMeasurePoints(); + void saveMeasurePoints(); + void loadMeasurePoints(); + void centerOnTrack(); void writeSettings(); @@ -102,6 +112,7 @@ class MeasureToolPlugin : public RenderPlugin, public DialogConfigurationInterfa Q_DISABLE_COPY( MeasureToolPlugin ) QString meterToPreferredUnit(qreal meters, bool isSquare = false) const; + void cleanActionGroups(); // The line strings in the distance path. GeoDataLineString m_measureLineString; @@ -116,7 +127,16 @@ class MeasureToolPlugin : public RenderPlugin, public DialogConfigurationInterfa QAction *m_addMeasurePointAction; QAction *m_removeLastMeasurePointAction; QAction *m_removeMeasurePointsAction; + QAction *m_saveMeasurePointsAction; + QAction *m_loadMeasurePointsAction; + QAction *m_centerOnMeasurePointsAction; QAction *m_separator; + + QList<QActionGroup *> m_actionGroups; + + bool m_isMouseAddActionEnabled; + + QString m_lastSavePath; MarbleWidget* m_marbleWidget; -- 2.4.4
_______________________________________________ Marble-devel mailing list [email protected] https://mail.kde.org/mailman/listinfo/marble-devel
