diff options
Diffstat (limited to 'kttsd/kttsmgr/kttsmgr.cpp')
-rw-r--r-- | kttsd/kttsmgr/kttsmgr.cpp | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/kttsd/kttsmgr/kttsmgr.cpp b/kttsd/kttsmgr/kttsmgr.cpp new file mode 100644 index 0000000..80b66b9 --- /dev/null +++ b/kttsd/kttsmgr/kttsmgr.cpp @@ -0,0 +1,334 @@ +/***************************************************** vim:set ts=4 sw=4 sts=4: + KTTS Manager Program + -------------------- + Copyright: + (C) 2004 by Gary Cramblitt <garycramblitt@comcast.net> + ------------------- + Original author: Gary Cramblitt <garycramblitt@comcast.net> + Current Maintainer: Gary Cramblitt <garycramblitt@comcast.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + ******************************************************************************/ + +// Qt includes. +#include <qimage.h> + +// KDE includes. +#include <kconfig.h> +#include <kuniqueapplication.h> +#include <kcmultidialog.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <kdebug.h> +#include <ksystemtray.h> +#include <kiconloader.h> +#include <kpopupmenu.h> +#include <kaboutapplication.h> +#include <dcopclient.h> +#include <kdeversion.h> + +// KTTSMgr includes. +#include "kspeech.h" +#include "kttsmgr.h" + +static const KCmdLineOptions options[] = +{ + { "s", 0, 0 }, + { "systray", I18N_NOOP("Start minimized in system tray"), 0 }, + { "a", 0, 0 }, + { "autoexit", I18N_NOOP("Exit when speaking is finished and minimized in system tray"), 0 }, + KCmdLineLastOption +}; + +int main (int argc, char *argv[]) +{ + KGlobal::locale()->setMainCatalogue("kttsd"); + + KAboutData aboutdata("kttsmgr", I18N_NOOP("KTTSMgr"), + "0.3.5.2", I18N_NOOP("Text-to-Speech Manager"), + KAboutData::License_GPL, "(C) 2002, José Pablo Ezequiel Fernández"); + aboutdata.addAuthor("José Pablo Ezequiel Fernández",I18N_NOOP("Original Author"),"pupeno@pupeno.com"); + aboutdata.addAuthor("Gary Cramblitt", I18N_NOOP("Maintainer"),"garycramblitt@comcast.net"); + aboutdata.addAuthor("Gunnar Schmi Dt", I18N_NOOP("Contributor"),"gunnar@schmi-dt.de"); + aboutdata.addAuthor("Olaf Schmidt", I18N_NOOP("Contributor"),"ojschmidt@kde.org"); + aboutdata.addAuthor("Paul Giannaros", I18N_NOOP("Contributor"), "ceruleanblaze@gmail.com"); + aboutdata.addCredit("Jorge Luis Arzola", I18N_NOOP("Testing"), "arzolacub@hotmail.com"); + aboutdata.addCredit("David Powell", I18N_NOOP("Testing"), "achiestdragon@gmail.com"); + KCmdLineArgs::init( argc, argv, &aboutdata ); + + KCmdLineArgs::addCmdLineOptions( options ); + + KUniqueApplication::addCmdLineOptions(); + + if(!KUniqueApplication::start()) + { + kdDebug() << "kttsmgr is already running" << endl; + return (0); + } + + KUniqueApplication app; + +#if KDE_VERSION >= KDE_MAKE_VERSION (3,3,90) + QPixmap icon = KGlobal::iconLoader()->loadIcon("kttsd", KIcon::Panel); + aboutdata.setProgramLogo(icon.convertToImage()); +#endif + + // The real work of KTTS Manager is done in the KControl Module kcmkttsd. + KCMultiDialog dlg(KCMultiDialog::Plain, i18n("KDE Text-to-Speech Manager"), 0, "kttsmgrdlg", false); + dlg.addModule("kcmkttsd"); + + dlg.setIcon(KGlobal::iconLoader()->loadIcon("kttsd", KIcon::Small)); + + // Get SysTray and ShowMainWindow options. + KConfig* config = new KConfig("kttsdrc"); + config->setGroup("General"); + bool embedInSysTray = config->readBoolEntry("EmbedInSysTray", true); + // Can only hide main window if we are in the system tray, otherwise, no way + // for user to do anything. + bool showMainWindowOnStartup = true; + if (embedInSysTray) + showMainWindowOnStartup = config->readBoolEntry("ShowMainWindowOnStartup", true); + + // If --systray option specified, start minimized in system tray. + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->isSet("systray")) + { + embedInSysTray = true; + showMainWindowOnStartup = false; + } + + KttsMgrTray* tray = 0; + if (embedInSysTray) + { + tray = new KttsMgrTray(&dlg); + tray->show(); + } + else app.setMainWidget(&dlg); + + if (showMainWindowOnStartup) +#if KDE_VERSION < KDE_MAKE_VERSION (3,3,0) + dlg.show(); +#else + { + if (embedInSysTray) + tray->setActive(); + else + dlg.show(); + } +#endif + int result = app.exec(); + delete tray; + return result; +} + +/* KttsToolTip class */ + +KttsToolTip::KttsToolTip ( QWidget* parent ) : QToolTip(parent) +{ +} + +/*virtual*/ void KttsToolTip::maybeTip ( const QPoint & p ) +{ + Q_UNUSED(p); + + if (!parentWidget()->inherits("KttsMgrTray")) + return; + + KttsMgrTray* kttsMgrTray = dynamic_cast<KttsMgrTray*>(parentWidget()); + + QRect r(kttsMgrTray->geometry()); + if ( !r.isValid() ) + return; + + QString status = "<qt><b>KTTSMgr</b> - "; + status += i18n("<qt>Text-to-Speech Manager"); + status += "<br/><br/>"; + status += kttsMgrTray->getStatus(); + status += "</qt>"; + + tip(r, status); +} + +/* KttsMgrTray class */ + +KttsMgrTray::KttsMgrTray(QWidget *parent): + DCOPStub("kttsd", "KSpeech"), + DCOPObject("kkttsmgr_kspeechsink"), + KSystemTray(parent, "kttsmgrsystemtray") +{ + QPixmap icon = KGlobal::iconLoader()->loadIcon("kttsd", KIcon::Small); + setPixmap (icon); + + // QToolTip::add(this, i18n("Text-to-speech manager")); + m_toolTip = new KttsToolTip(this); + + int id; + id = contextMenu()->idAt(0); + if (id != -1) contextMenu()->changeTitle(id, icon, "KTTSMgr"); + + id = contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("klipper", KIcon::Small), + i18n("&Speak Clipboard Contents"), this, SLOT(speakClipboardSelected())); + id = contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("stop", KIcon::Small), + i18n("&Hold"), this, SLOT(holdSelected())); + id = contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("exec", KIcon::Small), + i18n("Resume"), this, SLOT(resumeSelected())); + id = contextMenu()->insertSeparator(); + id = contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("contents", KIcon::Small), + i18n("KTTS &Handbook"), this, SLOT(helpSelected())); + id = contextMenu()->insertItem (KGlobal::iconLoader()->loadIcon("kttsd", KIcon::Small), + i18n("&About KTTSMgr"), this, SLOT(aboutSelected())); + + connect(this, SIGNAL(quitSelected()), this, SLOT(quitSelected())); + // If --autoexit option given, exit when speaking stops. + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->isSet("autoexit")) + { + connectDCOPSignal("kttsd", "KSpeech", + "textFinished(QCString,uint)", + "textFinished(QCString,uint)", + false); + // Install an event filter so we can check when KTTSMgr becomes inconified to the systray. + parent->installEventFilter(this); + } +} + +KttsMgrTray::~KttsMgrTray() +{ + delete m_toolTip; +} + +void KttsMgrTray::textFinished(const QCString& /*appId*/, uint /*jobNum*/) +{ + // kdDebug() << "KttsMgrTray::textFinished: running" << endl; + exitWhenFinishedSpeaking(); +} + +/*virtual*/ bool KttsMgrTray::eventFilter( QObject* /*o*/, QEvent* e ) +{ + if ( e->type() == QEvent::Hide ) exitWhenFinishedSpeaking(); + return false; +} + +void KttsMgrTray::exitWhenFinishedSpeaking() +{ + // kdDebug() << "KttsMgrTray::exitWhenFinishedSpeaking: running" << endl; + if ( parentWidget()->isShown() ) return; + QString jobNums = getTextJobNumbers(); + QStringList jobNumsList = QStringList::split(jobNums, ","); + uint jobNumsListCount = jobNumsList.count(); + // Since there can only be 2 Finished jobs at a time, more than 2 jobs means at least + // one job is not Finished. + if (jobNumsListCount > 2) return; + // Exit if all jobs are Finished or there are no jobs. + for (uint ndx=0; ndx < jobNumsListCount; ++ndx) + { + if (getTextJobState(jobNumsList[ndx].toInt()) != KSpeech::jsFinished) return; + } + kapp->quit(); +} + +/** +* Convert a KTTSD job state integer into a display string. +* @param state KTTSD job state +* @return Display string for the state. +*/ +QString KttsMgrTray::stateToStr(int state) +{ + switch( state ) + { + case KSpeech::jsQueued: return i18n("Queued"); + case KSpeech::jsSpeakable: return i18n("Waiting"); + case KSpeech::jsSpeaking: return i18n("Speaking"); + case KSpeech::jsPaused: return i18n("Paused"); + case KSpeech::jsFinished: return i18n("Finished"); + default: return i18n("Unknown"); + } +} + +QString KttsMgrTray::getStatus() +{ + if (!isKttsdRunning()) return i18n("Text-to-Speech System is not running"); + uint jobCount = getTextJobCount(); + QString status = i18n("1 job", "%n jobs", jobCount); + if (jobCount > 0) + { + uint job = getCurrentTextJob(); + int jobState = 0; + if (job != 0) + { + // kdDebug() << "KttsMgrTray::getStatus: job = " << job << endl; + jobState = getTextJobState(job); + int sentenceCount = getTextCount(job); + uint seq = moveRelTextSentence(0, job); + status += i18n(", current job %1 at sentence %2 of %3 sentences" + ).arg(stateToStr(jobState)).arg(seq).arg(sentenceCount); + } + } + return status; +} + +void KttsMgrTray::speakClipboardSelected() +{ + if (!isKttsdRunning()) + { + QString error; + if (KApplication::startServiceByDesktopName("kttsd", QStringList(), &error) != 0) + kdError() << "Starting KTTSD failed with message " << error << endl; + } + speakClipboard(); +} + +void KttsMgrTray::aboutSelected() +{ + KAboutApplication aboutDlg(kapp->aboutData(), 0, "kttsmgraboutdlg", true); + aboutDlg.exec(); +} + +void KttsMgrTray::helpSelected() +{ + kapp->invokeHelp(QString::null,"kttsd"); +} + +void KttsMgrTray::quitSelected() +{ + // kdDebug() << "Running KttsMgrTray::quitSelected" << endl; + kapp->quit(); +} + +void KttsMgrTray::holdSelected() +{ + if (isKttsdRunning()) + { + uint jobNum = getCurrentTextJob(); + pauseText(jobNum); + } +} + +void KttsMgrTray::resumeSelected() +{ + if (isKttsdRunning()) + { + uint jobNum = getCurrentTextJob(); + resumeText(jobNum); + } +} + +bool KttsMgrTray::isKttsdRunning() +{ + DCOPClient *client = kapp->dcopClient(); + return (client->isApplicationRegistered("kttsd")); +} + +#include "kttsmgr.moc" |