akregator/src

speechclient.cpp
1 /*
2  This file is part of Akregator.
3 
4  Copyright (C) 2005 Frank Osterfeld <frank.osterfeld at kdemail.net>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of TQt, and distribute the resulting executable,
22  without including the source code for TQt in the source distribution.
23 */
24 
25 #include "article.h"
26 #include "speechclient.h"
27 #include "utils.h"
28 
29 #include <dcopclient.h>
30 #include <tdeapplication.h>
31 #include <kcharsets.h>
32 #include <tdelocale.h>
33 #include <kdebug.h>
34 #include <kstaticdeleter.h>
35 #include <ktrader.h>
36 
37 #include <tqstring.h>
38 #include <tqvaluelist.h>
39 
40 namespace Akregator
41 {
42 
43 class SpeechClient::SpeechClientPrivate
44 {
45  public:
46 
47  bool isTextSpeechInstalled;
48  TQValueList<uint> pendingJobs;
49 };
50 
51 SpeechClient* SpeechClient::m_self = 0;
52 
53 static KStaticDeleter<SpeechClient> speechclsd;
54 
55 SpeechClient* SpeechClient::self()
56 {
57  if (!m_self)
58  m_self = speechclsd.setObject(m_self, new SpeechClient);
59  return m_self;
60 }
61 
62 
63 SpeechClient::SpeechClient() : DCOPStub("kttsd", "KSpeech"), DCOPObject("akregatorpart_kspeechsink"), TQObject(), d(new SpeechClientPrivate)
64 {
65  d->isTextSpeechInstalled = false;
66  setupSpeechSystem();
67 }
68 
69 SpeechClient::~SpeechClient()
70 {
71  delete d;
72  d = 0;
73 }
74 
75 void SpeechClient::slotSpeak(const TQString& text, const TQString& language)
76 {
77  if (!isTextToSpeechInstalled() || text.isEmpty())
78  return;
79  uint jobNum = setText(text, language);
80  startText(jobNum);
81  d->pendingJobs.append(jobNum);
82  if (d->pendingJobs.count() == 1)
83  {
84  emit signalJobsStarted();
85  emit signalActivated(true);
86  }
87 }
88 
89 void SpeechClient::slotSpeak(const Article& article)
90 {
91  if (!isTextToSpeechInstalled() || article.isNull())
92  return;
93 
94  TQString speakMe;
95  speakMe += KCharsets::resolveEntities(Utils::stripTags((article).title()))
96  + ". . . . "
97  + KCharsets::resolveEntities(Utils::stripTags((article).description()));
98  slotSpeak(speakMe, "en");
99 }
100 
101 void SpeechClient::slotSpeak(const TQValueList<Article>& articles)
102 {
103  if (!isTextToSpeechInstalled() || articles.isEmpty())
104  return;
105 
106  TQString speakMe;
107 
108  for (TQValueList<Article>::ConstIterator it = articles.begin(); it != articles.end(); ++it)
109  {
110  if (!speakMe.isEmpty())
111  speakMe += ". . . . . . " + i18n("Next Article: ");
112  speakMe += KCharsets::resolveEntities(Utils::stripTags((*it).title()))
113  + ". . . . "
114  + KCharsets::resolveEntities(Utils::stripTags((*it).description()));
115  }
116 
117  SpeechClient::self()->slotSpeak(speakMe, "en");
118 }
119 
120 void SpeechClient::slotAbortJobs()
121 {
122  if (!d->pendingJobs.isEmpty())
123  {
124  for (TQValueList<uint>::ConstIterator it = d->pendingJobs.begin(); it != d->pendingJobs.end(); ++it)
125  {
126  removeText(*it);
127  }
128 
129  d->pendingJobs.clear();
130  emit signalJobsDone();
131  emit signalActivated(false);
132  }
133 }
134 
135 ASYNC SpeechClient::textRemoved(const TQCString& /*appId*/, uint jobNum)
136 {
137  kdDebug() << "SpeechClient::textRemoved() called" << endl;
138  if (d->pendingJobs.contains(jobNum))
139  {
140  d->pendingJobs.remove(jobNum);
141  if (d->pendingJobs.isEmpty())
142  {
143  emit signalJobsDone();
144  emit signalActivated(false);
145  }
146  }
147 }
148 
149 bool SpeechClient::isTextToSpeechInstalled() const
150 {
151  return d->isTextSpeechInstalled;
152 }
153 
154 void SpeechClient::setupSpeechSystem()
155 {
156  TDETrader::OfferList offers = TDETrader::self()->query("DCOP/Text-to-Speech", "Name == 'KTTSD'");
157  if (offers.count() == 0)
158  {
159  kdDebug() << "KTTSD not installed, disable support" << endl;
160  d->isTextSpeechInstalled = false;
161  }
162  else
163  {
164  DCOPClient* client = dcopClient();
165  //client->attach();
166  if (client->isApplicationRegistered("kttsd"))
167  {
168  d->isTextSpeechInstalled = true;
169  }
170  else
171  {
172  TQString error;
173  if (TDEApplication::startServiceByDesktopName("kttsd", TQStringList(), &error))
174  {
175  kdDebug() << "Starting KTTSD failed with message " << error << endl;
176  d->isTextSpeechInstalled = false;
177  }
178  else
179  {
180  d->isTextSpeechInstalled = true;
181  }
182  }
183  }
184  if (d->isTextSpeechInstalled)
185  {
186 
187  bool c = connectDCOPSignal("kttsd", "KSpeech",
188  "textRemoved(TQCString, uint)",
189  "textRemoved(TQCString, uint)",
190  false);
191  if (!c)
192  kdDebug() << "SpeechClient::setupSpeechSystem(): connecting signals failed" << endl;
193  c = connectDCOPSignal("kttsd", "KSpeech",
194  "textFinished(TQCString, uint)",
195  "textRemoved(TQCString, uint)",
196  false);
197  }
198 }
199 
200 
201 } // namespace Akregator
202 
203 #include "speechclient.moc"