diff --git a/CMakeLists.txt b/CMakeLists.txt index e2b113819..8f9a4c737 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -151,6 +151,7 @@ kde4_add_ui_files(okularpart_SRCS conf/dlgpresentationbase.ui ) +qt4_add_dbus_interfaces(okularpart_SRCS ${DBUS_INTERFACES_INSTALL_DIR}/org.kde.KSpeech.xml) kde4_add_plugin(okularpart ${okularpart_SRCS}) diff --git a/ui/tts.cpp b/ui/tts.cpp index 76e155796..42f630323 100644 --- a/ui/tts.cpp +++ b/ui/tts.cpp @@ -9,46 +9,34 @@ #include "tts.h" -#include -#include -#include -#include - #include #include #include "pageviewutils.h" +#include "kspeechinterface.h" /* Private storage. */ class OkularTTS::Private { public: - Private() + Private( OkularTTS *qq ) + : q( qq ), kspeech( 0 ) { } + void setupIface(); + void teardownIface(); + + OkularTTS *q; PageViewMessage *messageWindow; + org::kde::KSpeech* kspeech; }; - -OkularTTS::OkularTTS( PageViewMessage *messageWindow, QObject *parent ) - : QObject( parent ), d( new Private ) +void OkularTTS::Private::setupIface() { - d->messageWindow = messageWindow; -} - -OkularTTS::~OkularTTS() -{ - delete d; -} - -void OkularTTS::say( const QString &text ) -{ - if ( text.isEmpty() ) + if ( kspeech ) return; - // Albert says is this ever necessary? - // we already attached on Part constructor // If KTTSD not running, start it. QDBusReply reply = QDBusConnection::sessionBus().interface()->isServiceRegistered( "org.kde.kttsd" ); bool kttsdactive = false; @@ -59,7 +47,7 @@ void OkularTTS::say( const QString &text ) QString error; if ( KToolInvocation::startServiceByDesktopName( "kttsd", QStringList(), &error ) ) { - d->messageWindow->display( i18n( "Starting KTTSD Failed: %1", error ) ); + messageWindow->display( i18n( "Starting KTTSD Failed: %1", error ) ); } else { @@ -69,9 +57,60 @@ void OkularTTS::say( const QString &text ) if ( kttsdactive ) { // creating the connection to the kspeech interface - QDBusInterface kspeech( "org.kde.kttsd", "/KSpeech", "org.kde.KSpeech" ); - kspeech.call( "setApplicationName", "Okular" ); - kspeech.call( "say", text, 0 ); + kspeech = new org::kde::KSpeech( "org.kde.kttsd", "/KSpeech", QDBusConnection::sessionBus() ); + kspeech->setApplicationName( "Okular" ); + connect( QDBusConnection::sessionBus().interface(), SIGNAL( serviceUnregistered( const QString & ) ), + q, SLOT( slotServiceUnregistered( const QString & ) ) ); + connect( QDBusConnection::sessionBus().interface(), SIGNAL( serviceOwnerChanged( const QString &, const QString &, const QString & ) ), + q, SLOT( slotServiceOwnerChanged( const QString &, const QString &, const QString & ) ) ); + } +} + +void OkularTTS::Private::teardownIface() +{ + disconnect( QDBusConnection::sessionBus().interface(), 0, q, 0 ); + + delete kspeech; + kspeech = 0; +} + + +OkularTTS::OkularTTS( PageViewMessage *messageWindow, QObject *parent ) + : QObject( parent ), d( new Private( this ) ) +{ + d->messageWindow = messageWindow; +} + +OkularTTS::~OkularTTS() +{ + delete d; +} + +void OkularTTS::say( const QString &text ) +{ + if ( text.isEmpty() ) + return; + + d->setupIface(); + if ( d->kspeech ) + { + d->kspeech->say( text, 0 ); + } +} + +void OkularTTS::slotServiceUnregistered( const QString &service ) +{ + if ( service == QLatin1String( "org.kde.kttsd" ) ) + { + d->teardownIface(); + } +} + +void OkularTTS::slotServiceOwnerChanged( const QString &service, const QString &, const QString &newOwner ) +{ + if ( service == QLatin1String( "org.kde.kttsd" ) && newOwner.isEmpty() ) + { + d->teardownIface(); } } diff --git a/ui/tts.h b/ui/tts.h index 52e3060e1..2e1bb1107 100644 --- a/ui/tts.h +++ b/ui/tts.h @@ -23,6 +23,10 @@ class OkularTTS : public QObject void say( const QString &text ); + private slots: + void slotServiceUnregistered( const QString& ); + void slotServiceOwnerChanged( const QString&, const QString&, const QString& ); + private: // private storage class Private;