Commit ac2a7714 authored by Dennis Nienhüser's avatar Dennis Nienhüser

Refactoring of the DBus Interface

Our current DBus interface exposes all signals, slots and properties of
both MarbleWidget and MarbleMap to the DBus session bus. There are a
couple of problems:
- 3rd party developers who include MarbleWidget have their application
  exposed to DBus and the Marble part of it can be controlled from
  there.
- not all method signatures are compatible with DBus. In particular
  QRegion and Marble specific types cannot be send over DBus (without
  us implementing support for it). In Qt5 there seems to be a change
  that warns against that in the shell. This means that in Qt5 you get
  lots of debug spam all the time in the shell, e.g. a simple map drag
  results in hundreds of warnings a la
    QDBusAbstractAdaptor: Cannot relay signal
Marble::MarbleMap::renderStateChanged(RenderState): Unregistered input
type in parameter list: RenderState
    QDBusAbstractAdaptor: Cannot relay signal
Marble::MarbleWidget::mouseClickGeoPosition(double,double,GeoDataCoordin
ates::Unit): Unregistered input type in parameter list:
GeoDataCoordinates::Unit
    QDBusAbstractAdaptor: Cannot relay signal
Marble::MarbleMap::repaintNeeded(QRegion): Type not registered with
QtDBus in parameter list: QRegion
- it's an utter mess. Currently we expose more than 120 (!) Marble
  specific things to DBus

The patch tries to improve that by
- Not exposing anything to DBus in the library, but only from the Qt
  and KDE applications (i.e. move session bus registration to
  ControlView.cpp)
- Expose only a limited subset of methods and properties (implemented
  in the new class MarbleDBusInterface)

The drawbacks are that we're changing the interface (hence break any
external scripts etc. that rely on it), and limit it at the same time
-- some information that people might be using is not available
anymore. I'm not aware of anyone really using the DBus interface
though, so I'd risk changing it. For limited functionality I'm happy to
bring in more things if there's a sane use case behind it.

REVIEW: 123896
parent 0fb8375b
......@@ -37,6 +37,11 @@
#include <QMenu>
#include <QToolBar>
#ifdef MARBLE_DBUS
#include <QDBusConnection>
#include "MarbleDBusInterface.h"
#endif
#include "GeoSceneDocument.h"
#include "GeoSceneHead.h"
#include "GeoUriParser.h"
......@@ -91,6 +96,17 @@ ControlView::ControlView( QWidget *parent )
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 );
......
......@@ -69,6 +69,7 @@ set(marblewidget_SRCS
MarbleMap.cpp
MarbleControlBox.cpp
MarbleColors.cpp
MarbleDBusInterface.cpp
NavigationWidget.cpp
MapViewWidget.cpp
FileViewWidget.cpp
......
#include "MarbleDBusInterface.h"
#include "MarbleWidget.h"
#include "MarbleModel.h"
#include "MapThemeManager.h"
#include <GeoSceneDocument.h>
#include <GeoSceneSettings.h>
#include <GeoSceneProperty.h>
namespace Marble
{
class MarbleDBusInterface::Private
{
public:
Private( MarbleWidget* widget );
MarbleWidget* m_marbleWidget;
QPointF m_currentCenter;
};
MarbleDBusInterface::Private::Private( MarbleWidget *widget ) :
m_marbleWidget( widget )
{
// nothing to do
}
MarbleDBusInterface::MarbleDBusInterface( MarbleWidget* widget ) :
QDBusAbstractAdaptor( widget ),
d( new Private( widget ) )
{
connect( widget, SIGNAL(themeChanged(QString)), this, SIGNAL(mapThemeChanged(QString)) );
connect( widget, SIGNAL(tileLevelChanged(int)), this, SIGNAL(tileLevelChanged(int)) );
connect( widget, SIGNAL(zoomChanged(int)), this, SIGNAL(zoomChanged(int)) );
connect( widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
this, SLOT(handleVisibleLatLonAltBoxChange()) );
}
MarbleDBusInterface::~MarbleDBusInterface()
{
// nothing to do
// (an explicit destructor is required by QScopePointer)
}
QString MarbleDBusInterface::mapTheme() const
{
return d->m_marbleWidget->mapThemeId();
}
QStringList MarbleDBusInterface::mapThemes() const
{
MapThemeManager mapThemeManager;
return mapThemeManager.mapThemeIds();
}
int MarbleDBusInterface::tileLevel() const
{
return d->m_marbleWidget->tileZoomLevel();
}
int MarbleDBusInterface::zoom() const
{
return d->m_marbleWidget->zoom();
}
QPointF MarbleDBusInterface::center() const
{
return d->m_currentCenter;
}
void MarbleDBusInterface::setMapTheme( const QString &mapTheme )
{
d->m_marbleWidget->setMapThemeId( mapTheme );
}
void MarbleDBusInterface::setZoom(int zoom)
{
d->m_marbleWidget->setZoom(zoom);
}
void MarbleDBusInterface::setPropertyEnabled(const QString &key, bool enabled )
{
d->m_marbleWidget->setPropertyValue( key, enabled );
}
bool MarbleDBusInterface::isPropertyEnabled( const QString &key ) const
{
bool value = false;
GeoSceneDocument const * const mapTheme = d->m_marbleWidget->model()->mapTheme();
if ( mapTheme ) {
mapTheme->settings()->propertyValue( key, value );
}
return value;
}
QStringList MarbleDBusInterface::properties() const
{
QStringList properties;
GeoSceneDocument const * const mapTheme = d->m_marbleWidget->model()->mapTheme();
if ( mapTheme ) {
foreach( const GeoSceneProperty* property, mapTheme->settings()->allProperties() ) {
properties << property->name();
}
}
return properties;
}
void MarbleDBusInterface::setCenter( const QPointF &center ) const
{
d->m_marbleWidget->centerOn( center.x(), center.y() );
}
void MarbleDBusInterface::handleVisibleLatLonAltBoxChange()
{
QPointF const newCenter = QPointF( d->m_marbleWidget->centerLongitude(),
d->m_marbleWidget->centerLatitude() );
if ( newCenter != d->m_currentCenter ) {
d->m_currentCenter = newCenter;
emit centerChanged( d->m_currentCenter );
}
}
}
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed 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 <earthwings@gentoo.org>
//
namespace Marble
{
class MarbleWidget;
}
#include <QDBusAbstractAdaptor>
#include <QScopedPointer>
#include <QStringList>
#include <QPointF>
namespace Marble {
class MarbleDBusInterface : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.marble")
Q_PROPERTY(QString mapTheme READ mapTheme WRITE setMapTheme NOTIFY mapThemeChanged)
Q_PROPERTY(QStringList mapThemes READ mapThemes)
Q_PROPERTY(int tileLevel READ tileLevel NOTIFY tileLevelChanged)
Q_PROPERTY(int zoom READ zoom WRITE setZoom NOTIFY zoomChanged)
Q_PROPERTY(QStringList properties READ properties)
Q_PROPERTY(QPointF center READ center WRITE setCenter NOTIFY centerChanged)
public:
explicit MarbleDBusInterface(MarbleWidget* widget);
~MarbleDBusInterface();
QString mapTheme() const;
QStringList mapThemes() const;
int tileLevel() const;
int zoom() const;
QPointF center() const;
public Q_SLOTS:
void setMapTheme( const QString & mapTheme );
void setZoom( int zoom );
QStringList properties() const;
void setCenter( const QPointF &center ) const;
public Q_SLOTS:
Q_INVOKABLE void setPropertyEnabled( const QString &key, bool enabled );
Q_INVOKABLE bool isPropertyEnabled( const QString &key ) const;
Q_SIGNALS:
void mapThemeChanged( const QString &mapTheme );
void tileLevelChanged( int tileLevel );
void zoomChanged( int zoom );
void centerChanged( const QPointF &center );
private Q_SLOTS:
void handleVisibleLatLonAltBoxChange();
private:
Q_DISABLE_COPY(MarbleDBusInterface)
class Private;
friend class Private;
QScopedPointer<Private> const d;
};
}
......@@ -27,10 +27,6 @@
#include <QSizePolicy>
#include <QRegion>
#ifdef MARBLE_DBUS
#include <QDBusConnection>
#endif
// Marble
#include "layers/FogLayer.h"
#include "layers/FpsLayer.h"
......@@ -260,24 +256,12 @@ void MarbleMapPrivate::updateProperty( const QString &name, bool show )
MarbleMap::MarbleMap()
: d( new MarbleMapPrivate( this, new MarbleModel( this ) ) )
{
#ifdef MARBLE_DBUS
QDBusConnection::sessionBus().registerObject( "/MarbleMap", this,
QDBusConnection::ExportAllSlots
| QDBusConnection::ExportAllSignals
| QDBusConnection::ExportAllProperties );
#endif
// nothing to do
}
MarbleMap::MarbleMap(MarbleModel *model)
: d( new MarbleMapPrivate( this, model ) )
{
#ifdef MARBLE_DBUS
QDBusConnection::sessionBus().registerObject( "/MarbleMap", this,
QDBusConnection::ExportAllSlots
| QDBusConnection::ExportAllSignals
| QDBusConnection::ExportAllProperties );
#endif
d->m_modelIsOwned = false;
}
......
......@@ -24,11 +24,6 @@
#include <QSizePolicy>
#include <QNetworkProxy>
#include <QMetaMethod>
#ifdef MARBLE_DBUS
#include <QDBusConnection>
#endif
#include "DataMigration.h"
#include "FpsLayer.h"
#include "FileManager.h"
......@@ -167,13 +162,6 @@ void MarbleWidgetPrivate::construct()
dataMigration->exec();
delete dataMigration;
#ifdef MARBLE_DBUS
QDBusConnection::sessionBus().registerObject( "/MarbleWidget", m_widget,
QDBusConnection::ExportAllSlots
| QDBusConnection::ExportAllSignals
| QDBusConnection::ExportAllProperties );
#endif
// Widget settings
m_widget->setMinimumSize( 200, 300 );
m_widget->setFocusPolicy( Qt::WheelFocus );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment