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

Reply via email to