Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / konqueror / kttsplugin / khtmlkttsd.cpp
blob1f3bd663817961a7967fec2fb05136c7bf2fb1f8
1 /***************************************************************************
2 Copyright (C) 2002 by George Russell <george.russell@clara.net>
3 Copyright (C) 2003-2004 by Olaf Schmidt <ojschmidt@kde.org>
4 ***************************************************************************/
6 /***************************************************************************
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 ***************************************************************************/
15 // Own
16 #include "khtmlkttsd.h"
18 // KDE
19 #include <dom/dom_string.h>
20 #include <dom/html_document.h>
21 #include <dom/html_element.h>
22 #include <kaction.h>
23 #include <kactioncollection.h>
24 #include <kdebug.h>
25 #include <khtml_part.h> // this plugin applies to a khtml part
26 #include <config-kttsplugin.h>
27 #ifdef HAVE_WEBKITKDE
28 #include <webkitpart.h>
29 #ifdef HAVE_WEBVIEW
30 #include <webview.h>
31 #else
32 #include <webkitview.h>
33 #endif
34 #include <QWebFrame>
35 #endif
36 #include <kicon.h>
37 #include <klocale.h>
38 #include <kmessagebox.h>
39 #include <kpluginfactory.h>
40 #include <kservicetypetrader.h>
41 #include <kspeech.h>
42 #include <ktoolinvocation.h>
45 #include "kspeechinterface.h"
47 KHTMLPluginKTTSD::KHTMLPluginKTTSD( QObject* parent, const QVariantList& )
48 : Plugin( parent )
50 if (qobject_cast<KHTMLPart*>(parent)) { // should always be true, but let's make sure
51 QAction *action = actionCollection()->addAction( "tools_kttsd" );
52 action->setIcon( KIcon("text-speak") );
53 action->setText( i18n("&Speak Text") );
54 connect(action, SIGNAL(triggered(bool) ), SLOT(slotReadOut()));
58 KHTMLPluginKTTSD::~KHTMLPluginKTTSD()
62 void KHTMLPluginKTTSD::slotReadOut()
64 // The parent is assumed to be a KHTMLPart (checked in constructor)
65 KParts::ReadOnlyPart* part = static_cast<KParts::ReadOnlyPart *>(parent());
67 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kttsd"))
69 QString error;
70 if (KToolInvocation::startServiceByDesktopName("kttsd", QStringList(), &error)) {
71 KMessageBox::error(part->widget(), error, i18n("Starting KTTSD Failed") );
74 // Find out if KTTSD supports xhtml (rich speak).
75 bool supportsXhtml = false;
76 org::kde::KSpeech kttsd( "org.kde.kttsd", "/KSpeech", QDBusConnection::sessionBus() );
77 QString talker = kttsd.defaultTalker();
78 QDBusReply<int> reply = kttsd.getTalkerCapabilities2(talker);
79 if ( !reply.isValid())
80 kDebug() << "D-Bus call getTalkerCapabilities2() failed, assuming non-XHTML support.";
81 else
83 supportsXhtml = reply.value() & KSpeech::tcCanParseHtml;
86 QString query;
87 bool hasSelection = false;
88 KHTMLPart *compPart = dynamic_cast<KHTMLPart *>(part);
89 if ( compPart )
91 if (supportsXhtml)
93 kDebug() << "KTTS claims to support rich speak (XHTML to SSML).";
94 if (hasSelection)
95 query = compPart->selectedTextAsHTML();
96 else
98 // TODO: Fooling around with the selection probably has unwanted
99 // side effects, but until a method is supplied to get valid xhtml
100 // from entire document..
101 // query = part->document().toString().string();
102 compPart->selectAll();
103 query = compPart->selectedTextAsHTML();
104 // Restore no selection.
105 compPart->setSelection(compPart->document().createRange());
107 } else {
108 if (hasSelection)
109 query = compPart->selectedText();
110 else
111 query = compPart->htmlDocument().body().innerText().string();
114 #ifdef HAVE_WEBKITKDE
115 else
117 WebKitPart *webkitPart = dynamic_cast<WebKitPart *>(part);
118 if ( webkitPart )
120 if (supportsXhtml)
122 kDebug() << "KTTS claims to support rich speak (XHTML to SSML).";
123 if (hasSelection)
124 query = webkitPart->view()->page()->currentFrame()->toHtml();
125 else
127 // TODO: Fooling around with the selection probably has unwanted
128 // side effects, but until a method is supplied to get valid xhtml
129 // from entire document..
130 // query = part->document().toString().string();
131 #if 0
132 webkitPart->selectAll();
133 query = webkitPart->view()->page()->currentFrame()->toHtml();
134 // Restore no selection.
135 webkitPart->setSelection(webkitPart->document().createRange());
136 #endif
138 } else {
139 if (hasSelection)
140 query = webkitPart->view()->selectedText();
141 else
142 query = webkitPart->view()->page()->currentFrame()->toHtml();
147 #endif
148 // kDebug() << "query =" << query;
150 reply = kttsd.say(query, KSpeech::soNone);
151 if ( !reply.isValid()) {
152 KMessageBox::sorry(part->widget(), i18n("The D-Bus call say() failed."),
153 i18n("D-Bus Call Failed"));
157 K_PLUGIN_FACTORY(KHTMLPluginKTTSDFactory,
158 const KService::List offers = KServiceTypeTrader::self()->query("DBUS/Text-to-Speech", "Name == 'KTTSD'");
159 // If KTTSD is not installed, don't create the plugin at all.
160 if (!offers.isEmpty()) {
161 registerPlugin<KHTMLPluginKTTSD>();
164 K_EXPORT_PLUGIN( KHTMLPluginKTTSDFactory( "khtmlkttsd" ) )
166 #include "khtmlkttsd.moc"