akregator/src

speechclient.cpp

00001 /*
00002     This file is part of Akregator.
00003 
00004     Copyright (C) 2005 Frank Osterfeld <frank.osterfeld at kdemail.net>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include "article.h"
00026 #include "speechclient.h"
00027 #include "utils.h"
00028 
00029 #include <dcopclient.h>
00030 #include <kapplication.h>
00031 #include <kcharsets.h>
00032 #include <klocale.h>
00033 #include <kdebug.h>
00034 #include <kstaticdeleter.h>
00035 #include <ktrader.h>
00036 
00037 #include <qstring.h>
00038 #include <qvaluelist.h>
00039 
00040 namespace Akregator 
00041 {
00042 
00043 class SpeechClient::SpeechClientPrivate
00044 {
00045     public:
00046 
00047     bool isTextSpeechInstalled;
00048     QValueList<uint> pendingJobs;
00049 };
00050 
00051 SpeechClient* SpeechClient::m_self = 0;
00052 
00053 static KStaticDeleter<SpeechClient> speechclsd;
00054 
00055 SpeechClient* SpeechClient::self()
00056 {
00057     if (!m_self)
00058         m_self = speechclsd.setObject(m_self, new SpeechClient);
00059     return m_self;
00060 }
00061 
00062 
00063 SpeechClient::SpeechClient() : DCOPStub("kttsd", "KSpeech"), DCOPObject("akregatorpart_kspeechsink"), QObject(), d(new SpeechClientPrivate)
00064 {
00065     d->isTextSpeechInstalled = false;
00066     setupSpeechSystem();
00067 }
00068 
00069 SpeechClient::~SpeechClient()
00070 {
00071     delete d;
00072     d = 0;
00073 }
00074 
00075 void SpeechClient::slotSpeak(const QString& text, const QString& language)
00076 {
00077     if (!isTextToSpeechInstalled() || text.isEmpty())
00078         return;
00079     uint jobNum = setText(text, language);
00080     startText(jobNum);
00081     d->pendingJobs.append(jobNum);
00082     if (d->pendingJobs.count() == 1)
00083     {
00084         emit signalJobsStarted();
00085         emit signalActivated(true);
00086     }
00087 }
00088 
00089 void SpeechClient::slotSpeak(const Article& article)
00090 {
00091     if (!isTextToSpeechInstalled() || article.isNull())
00092         return;
00093     
00094     QString speakMe;
00095     speakMe += KCharsets::resolveEntities(Utils::stripTags((article).title())) 
00096     + ". . . . " 
00097     + KCharsets::resolveEntities(Utils::stripTags((article).description()));
00098     slotSpeak(speakMe, "en");
00099 }
00100 
00101 void SpeechClient::slotSpeak(const QValueList<Article>& articles)
00102 {
00103     if (!isTextToSpeechInstalled() || articles.isEmpty())
00104         return;
00105 
00106     QString speakMe;
00107 
00108     for (QValueList<Article>::ConstIterator it = articles.begin(); it != articles.end(); ++it)
00109     {
00110         if (!speakMe.isEmpty())
00111             speakMe += ". . . . . . " + i18n("Next Article: ");
00112         speakMe += KCharsets::resolveEntities(Utils::stripTags((*it).title())) 
00113         + ". . . . " 
00114         + KCharsets::resolveEntities(Utils::stripTags((*it).description()));
00115     }
00116 
00117     SpeechClient::self()->slotSpeak(speakMe, "en");
00118 }
00119 
00120 void SpeechClient::slotAbortJobs()
00121 {
00122     if (!d->pendingJobs.isEmpty())
00123     {
00124         for (QValueList<uint>::ConstIterator it = d->pendingJobs.begin(); it != d->pendingJobs.end(); ++it)
00125         {
00126             removeText(*it);
00127         }
00128 
00129         d->pendingJobs.clear();
00130         emit signalJobsDone();
00131         emit signalActivated(false);
00132     }
00133 }
00134 
00135 ASYNC SpeechClient::textRemoved(const QCString& /*appId*/, uint jobNum)
00136 {
00137     kdDebug() << "SpeechClient::textRemoved() called" << endl;
00138     if (d->pendingJobs.contains(jobNum))
00139     {
00140         d->pendingJobs.remove(jobNum);
00141         if (d->pendingJobs.isEmpty())
00142         {
00143             emit signalJobsDone();
00144             emit signalActivated(false);
00145         }
00146     }
00147 }
00148 
00149 bool SpeechClient::isTextToSpeechInstalled() const
00150 {
00151     return d->isTextSpeechInstalled;
00152 }
00153 
00154 void SpeechClient::setupSpeechSystem()
00155 {
00156     KTrader::OfferList offers = KTrader::self()->query("DCOP/Text-to-Speech", "Name == 'KTTSD'");
00157     if (offers.count() == 0)
00158     {
00159         kdDebug() << "KTTSD not installed, disable support" << endl;
00160         d->isTextSpeechInstalled = false;
00161     }
00162     else
00163     {
00164         DCOPClient* client = dcopClient();
00165         //client->attach();
00166         if (client->isApplicationRegistered("kttsd")) 
00167         {
00168             d->isTextSpeechInstalled = true;
00169         }
00170         else
00171         {
00172             QString error;
00173             if (KApplication::startServiceByDesktopName("kttsd", QStringList(), &error))
00174             {
00175                 kdDebug() << "Starting KTTSD failed with message " << error << endl;
00176                 d->isTextSpeechInstalled = false;
00177             }
00178             else
00179             {
00180                 d->isTextSpeechInstalled = true;
00181             }
00182         }
00183     }
00184     if (d->isTextSpeechInstalled)
00185     {
00186 
00187         bool c = connectDCOPSignal("kttsd", "KSpeech",
00188                 "textRemoved(QCString, uint)",
00189                 "textRemoved(QCString, uint)",
00190                 false);
00191         if (!c)
00192             kdDebug() << "SpeechClient::setupSpeechSystem(): connecting signals failed" << endl;
00193         c = connectDCOPSignal("kttsd", "KSpeech",
00194                 "textFinished(QCString, uint)",
00195                 "textRemoved(QCString, uint)",
00196                 false);
00197     }
00198 }
00199 
00200 
00201 } // namespace Akregator
00202 
00203 #include "speechclient.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys