summaryrefslogtreecommitdiffstats
path: root/kttsd/kttsjobmgr
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit00bb99ac80741fc50ef8a289719373032f2391eb (patch)
tree3a5a9bf72f942784b38bf77dd66c534662fab5f2 /kttsd/kttsjobmgr
downloadtdeaccessibility-00bb99ac80741fc50ef8a289719373032f2391eb.tar.gz
tdeaccessibility-00bb99ac80741fc50ef8a289719373032f2391eb.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeaccessibility@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kttsd/kttsjobmgr')
-rw-r--r--kttsd/kttsjobmgr/Makefile.am40
-rw-r--r--kttsd/kttsjobmgr/kttsjobmgr.cpp1023
-rw-r--r--kttsd/kttsjobmgr/kttsjobmgr.desktop49
-rw-r--r--kttsd/kttsjobmgr/kttsjobmgr.h298
4 files changed, 1410 insertions, 0 deletions
diff --git a/kttsd/kttsjobmgr/Makefile.am b/kttsd/kttsjobmgr/Makefile.am
new file mode 100644
index 0000000..98727e0
--- /dev/null
+++ b/kttsd/kttsjobmgr/Makefile.am
@@ -0,0 +1,40 @@
+# Include paths. INCLUDES is maintained by KDevelop, AM_CPPFLAGS is the preferred variable,
+# so keep them synchronized.
+INCLUDES = \
+ -I$(top_srcdir)/kttsd/libkttsd -I$(top_builddir)/kttsd/libkttsd \
+ $(KTTS_KSPEECH_INCLUDE) \
+ $(all_includes)
+
+# Let automoc handle all of the metsource files (moc).
+METASOURCES = AUTO
+
+#########################################################################
+# KPART SECTION
+#########################################################################
+# This is the kpart that gets installed. It's name is used for all
+# of the other Makefile.am variables.
+kde_module_LTLIBRARIES = libkttsjobmgrpart.la
+
+kspeech_DIR = $(KTTS_KSPEECH_DIR)
+kspeechsink_DIR = $(KTTS_KSPEECH_DIR)
+
+# The source, library search path, and link libraries.
+libkttsjobmgrpart_la_SOURCES = \
+ kspeech.stub kspeechsink.skel \
+ kttsjobmgr.cpp
+
+libkttsjobmgrpart_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) $(KDE_PLUGIN)
+libkttsjobmgrpart_la_LIBADD = \
+ $(top_builddir)/kttsd/libkttsd/libkttsd.la \
+ $(LIB_KFILE) $(LIBVM) $(LIB_KPARTS)
+
+# Header files not to be installed.
+noinst_HEADERS =
+
+# Install desktop file to standard services directory.
+kde_services_DATA = kttsjobmgr.desktop
+
+# This rc file should never have been installed.
+# createGUI not supported within a KCModule.
+install-data-local:
+ rm -f $(DESTDIR)$(kde_datadir)/kttsjobmgr/kttsjobmgrui.rc
diff --git a/kttsd/kttsjobmgr/kttsjobmgr.cpp b/kttsd/kttsjobmgr/kttsjobmgr.cpp
new file mode 100644
index 0000000..2b2e1c5
--- /dev/null
+++ b/kttsd/kttsjobmgr/kttsjobmgr.cpp
@@ -0,0 +1,1023 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ A KPart to display running jobs in KTTSD and permit user to stop, rewind,
+ advance, change Talker, etc.
+ -------------------
+ Copyright : (C) 2004,2005 by 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; version 2 of the License. *
+ * *
+ ***************************************************************************/
+
+// QT includes.
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qsplitter.h>
+#include <qclipboard.h>
+#include <qpushbutton.h>
+#include <qobjectlist.h>
+#include <qwhatsthis.h>
+
+#include <qmime.h>
+
+// KDE includes.
+#include <kinstance.h>
+#include <klocale.h>
+#include <kaboutdata.h>
+#include <klistview.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kencodingfiledialog.h>
+#include <kapplication.h>
+#include <kinputdialog.h>
+#include <ktextedit.h>
+
+// KTTS includes.
+#include "kspeech.h"
+#include "talkercode.h"
+#include "selecttalkerdlg.h"
+#include "kttsjobmgr.h"
+#include "kttsjobmgr.moc"
+
+K_EXPORT_COMPONENT_FACTORY( libkttsjobmgrpart, KttsJobMgrFactory )
+
+/**
+* We need one static instance of the factory for our C 'main'
+* function
+*/
+KInstance *KttsJobMgrFactory::s_instance = 0L;
+
+KttsJobMgrFactory::~KttsJobMgrFactory()
+{
+ if (s_instance)
+ {
+ delete s_instance->aboutData();
+ delete s_instance;
+ }
+
+ s_instance = 0;
+}
+
+QObject *KttsJobMgrFactory::createObject(QObject *parent, const char *name, const char*,
+ const QStringList& )
+{
+ QObject *obj = new KttsJobMgrPart((QWidget*)parent, name);
+ emit objectCreated(obj);
+ return obj;
+}
+
+KInstance *KttsJobMgrFactory::instance()
+{
+ if ( !s_instance )
+ s_instance = new KInstance( aboutData() );
+ return s_instance;
+}
+
+KAboutData *KttsJobMgrFactory::aboutData()
+{
+ KAboutData *about = new KAboutData("kttsjobmgr", I18N_NOOP("KttsJobMgr"), "1.99");
+ return about;
+}
+
+KttsJobMgrPart::KttsJobMgrPart(QWidget *parent, const char *name) :
+ DCOPStub("kttsd", "KSpeech"),
+ DCOPObject("kttsjobmgr_kspeechsink"),
+ KParts::ReadOnlyPart(parent, name)
+{
+ // Initialize some variables.
+ m_selectOnTextSet = false;
+ m_buttonBox = 0;
+
+ setInstance(KttsJobMgrFactory::instance());
+
+ // All the ktts components use the same catalogue.
+ KGlobal::locale()->insertCatalogue("kttsd");
+
+ // Create a QVBox to host everything.
+ QVBox* vBox = new QVBox(parent);
+ vBox->setMargin(6);
+
+ // Create a splitter to contain the Job List View and the current sentence.
+ QSplitter* splitter = new QSplitter(vBox);
+ splitter->setOrientation(QSplitter::Vertical);
+
+ // Create Job List View widget.
+ m_jobListView = new KListView(splitter, "joblistview");
+ m_jobListView->setSelectionModeExt(KListView::Single);
+ m_jobListView->addColumn(i18n("Job Num"));
+ m_jobListView->addColumn(i18n("Owner"));
+ m_jobListView->addColumn(i18n("Talker ID"));
+ m_jobListView->addColumn(i18n("State"));
+ m_jobListView->addColumn(i18n("Position"));
+ m_jobListView->addColumn(i18n("Sentences"));
+ m_jobListView->addColumn(i18n("Part Num"));
+ m_jobListView->addColumn(i18n("Parts"));
+
+ // Do not sort the list.
+ m_jobListView->setSorting(-1);
+
+ QString jobListViewWT = i18n(
+ "<p>These are all the text jobs. The <b>State</b> column "
+ "may be:"
+ "<ul>"
+ "<li><b>Queued</b> - the job is waiting and will not be spoken until its state "
+ "is changed to <b>Waiting</b> by clicking the <b>Resume</b> or <b>Restart</b> buttons.</li>"
+ "<li><b>Waiting</b> - the job is ready to be spoken. It will be spoken when the jobs "
+ "preceding it in the list have finished.</li>"
+ "<li><b>Speaking</b> - the job is speaking. The <b>Position</b> column shows the current "
+ "sentence of the job being spoken. You may pause a speaking job by clicking the "
+ "<b>Hold</b> button.</li>"
+ "<li><b>Paused</b> - the job is currently paused. Paused jobs prevent jobs below them "
+ "from speaking. Use the <b>Resume</b> or <b>Restart</b> buttons to resume speaking the "
+ "job, or click <b>Later</b> to move the job down in the list.</li>"
+ "<li><b>Finished</b> - the job has finished speaking. When a second job finishes, "
+ "this one will be deleted. You may click <b>Restart</b> to repeat the job.</li>"
+ "</ul>"
+ "<em>Note</em>: Messages, Warnings, and Screen Reader Output do not appear in this list. "
+ "See the Handbook for more information."
+ "</p>");
+ QWhatsThis::add(m_jobListView, jobListViewWT);
+
+ // splitter->setResizeMode(m_jobListView, QSplitter::Stretch);
+
+ // Create a VBox to hold buttons and current sentence.
+ QVBox* bottomBox = new QVBox(splitter);
+
+ // Create a box to hold buttons.
+ m_buttonBox = new QVBox(bottomBox);
+ m_buttonBox->setSpacing(6);
+
+ // Create 3 HBoxes to host buttons.
+ QHBox* hbox1 = new QHBox(m_buttonBox);
+ hbox1->setSpacing(6);
+ QHBox* hbox2 = new QHBox(m_buttonBox);
+ hbox2->setSpacing(6);
+ QHBox* hbox3 = new QHBox(m_buttonBox);
+ hbox3->setSpacing(6);
+
+ // Do not let button box stretch vertically.
+ m_buttonBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+ // All the buttons with "job_" at start of their names will be enabled/disabled when a job is
+ // selected in the Job List View.
+ // All the buttons with "part_" at the start of their names will be enabled/disabled when a
+ // job is selected in the Job List View that has multiple parts.
+
+ QPushButton* btn;
+ QString wt;
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("stop", KIcon::Small, 0, true),
+ i18n("Hold"), hbox1, "job_hold");
+ wt = i18n(
+ "<p>Changes a job to Paused state. If currently speaking, the job stops speaking. "
+ "Paused jobs prevent jobs that follow them from speaking, so either click "
+ "<b>Resume</b> to make the job speakable, or click <b>Later</b> to move it "
+ "down in the list.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_hold()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("exec", KIcon::Small, 0, true),
+ i18n("Resume"), hbox1, "job_resume");
+ wt = i18n(
+ "<p>Resumes a paused job or changes a Queued job to Waiting. If the job is the "
+ "top speakable job in the list, it begins speaking.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_resume()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("redo", KIcon::Small, 0, true),
+ i18n("R&estart"), hbox1, "job_restart");
+ wt = i18n(
+ "<p>Rewinds a job to the beginning and changes its state to Waiting. If the job "
+ "is the top speakable job in the list, it begins speaking.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_restart()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("edittrash", KIcon::Small, 0, true),
+ i18n("Re&move"), hbox1, "job_remove");
+ wt = i18n(
+ "<p>Deletes the job. If it is currently speaking, it stops speaking. The next "
+ "speakable job in the list begins speaking.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_remove()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("down", KIcon::Small, 0, true),
+ i18n("&Later"), hbox1, "job_later");
+ wt = i18n(
+ "<p>Moves a job downward in the list so that it will be spoken later. If the job "
+ "is currently speaking, its state changes to Paused.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_move()));
+
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("2leftarrow", KIcon::Small, 0, true),
+ i18n("Pre&vious Part"), hbox2, "part_prevpart");
+ wt = i18n(
+ "<p>Rewinds a multi-part job to the previous part.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_prev_par()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("1leftarrow", KIcon::Small, 0, true),
+ i18n("&Previous Sentence"), hbox2, "job_prevsentence");
+ wt = i18n(
+ "<p>Rewinds a job to the previous sentence.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_prev_sen()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("1rightarrow", KIcon::Small, 0, true),
+ i18n("&Next Sentence"), hbox2, "job_nextsentence");
+ wt = i18n(
+ "<p>Advances a job to the next sentence.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_next_sen()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("2rightarrow", KIcon::Small, 0, true),
+ i18n("Ne&xt Part"), hbox2, "part_nextpart");
+ wt = i18n(
+ "<p>Advances a multi-part job to the next part.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_next_par()));
+
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("klipper", KIcon::Small, 0, true),
+ i18n("&Speak Clipboard"), hbox3, "speak_clipboard");
+ wt = i18n(
+ "<p>Queues the current contents of the clipboard for speaking and sets its state "
+ "to Waiting. If the job is the topmost in the list, it begins speaking. "
+ "The job will be spoken by the topmost Talker in the <b>Talkers</b> tab.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_speak_clipboard()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("fileopen", KIcon::Small, 0, true),
+ i18n("Spea&k File"), hbox3, "speak_file");
+ wt = i18n(
+ "<p>Prompts you for a file name and queues the contents of the file for speaking. "
+ "You must click the <b>Resume</b> button before the job will be speakable. "
+ "The job will be spoken by the topmost Talker in the <b>Talkers</b> tab.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_speak_file()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("translate", KIcon::Small, 0, true),
+ i18n("Change Talker"), hbox3, "job_changetalker");
+ wt = i18n(
+ "<p>Prompts you with a list of your configured Talkers from the <b>Talkers</b> tab. "
+ "The job will be spoken using the selected Talker.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_job_change_talker()));
+ btn = new QPushButton(KGlobal::iconLoader()->loadIconSet("reload_page", KIcon::Small, 0, true),
+ i18n("&Refresh"), hbox3, "refresh");
+ wt = i18n(
+ "<p>Refresh the list of jobs.</p>");
+ QWhatsThis::add(btn, wt);
+ connect (btn, SIGNAL(clicked()), this, SLOT(slot_refresh()));
+
+ // Disable job buttons until a job is selected.
+ enableJobActions(false);
+ enableJobPartActions(false);
+
+ // Create a VBox for the current sentence and sentence label.
+ QVBox* sentenceVBox = new QVBox(bottomBox);
+
+ // Create a label for current sentence.
+ QLabel* currentSentenceLabel = new QLabel(sentenceVBox);
+ currentSentenceLabel->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+ currentSentenceLabel->setText(i18n("Current Sentence"));
+
+ // Create a box to contain the current sentence.
+ m_currentSentence = new KTextEdit(sentenceVBox);
+ m_currentSentence->setReadOnly(true);
+ m_currentSentence->setWordWrap(QTextEdit::WidgetWidth);
+ m_currentSentence->setWrapPolicy(QTextEdit::AtWordOrDocumentBoundary);
+ m_currentSentence->setHScrollBarMode(QScrollView::AlwaysOff);
+ m_currentSentence->setVScrollBarMode(QScrollView::Auto);
+ wt = i18n(
+ "<p>The text of the sentence currently speaking.</p>");
+ QWhatsThis::add(m_currentSentence, wt);
+
+ // Set the main widget for the part.
+ setWidget(vBox);
+
+ connect(m_jobListView, SIGNAL(selectionChanged(QListViewItem* )),
+ this, SLOT(slot_selectionChanged(QListViewItem* )));
+
+ // Fill the Job List View.
+ refreshJobListView();
+ // Select first item (if any).
+ autoSelectInJobListView();
+
+ // Connect DCOP Signals emitted by KTTSD to our own DCOP methods.
+ connectDCOPSignal("kttsd", "KSpeech",
+ "kttsdStarted()",
+ "kttsdStarted()",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "markerSeen(QCString,QString)",
+ "markerSeen(QCString,QString)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "sentenceStarted(QCString,uint,uint)",
+ "sentenceStarted(QCString,uint,uint)",
+ false);
+ connectDCOPSignal(0, 0,
+ "sentenceFinished(QCString,uint,uint)",
+ "sentenceFinished(QCString,uint,uint)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "textSet(QCString,uint)",
+ "textSet(QCString,uint)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "textStarted(QCString,uint)",
+ "textStarted(QCString,uint)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "textFinished(QCString,uint)",
+ "textFinished(QCString,uint)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "textStopped(QCString,uint)",
+ "textStopped(QCString,uint)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "textPaused(QCString,uint)",
+ "textPaused(QCString,uint)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "textResumed(QCString,uint)",
+ "textResumed(QCString,uint)",
+ false);
+ connectDCOPSignal("kttsd", "KSpeech",
+ "textRemoved(QCString,uint)",
+ "textRemoved(QCString,uint)",
+ false);
+
+ m_extension = new KttsJobMgrBrowserExtension(this);
+
+ m_jobListView->show();
+
+ // Divide splitter in half. ListView gets half. Buttons and Current Sentence get half.
+ int halfSplitterSize = splitter->height()/2;
+ QValueList<int> splitterSizes;
+ splitterSizes.append(halfSplitterSize);
+ splitterSizes.append(halfSplitterSize);
+ splitter->setSizes(splitterSizes);
+}
+
+KttsJobMgrPart::~KttsJobMgrPart()
+{
+ closeURL();
+}
+
+bool KttsJobMgrPart::openFile()
+{
+ return true;
+}
+
+bool KttsJobMgrPart::closeURL()
+{
+ return true;
+}
+
+/**
+* This slot is connected to the Job List View selectionChanged signal.
+*/
+void KttsJobMgrPart::slot_selectionChanged(QListViewItem*)
+{
+ // Enable job buttons.
+ enableJobActions(true);
+ enableJobPartActions((getCurrentJobPartCount() > 1));
+}
+
+/**
+* Slots connected to buttons.
+*/
+void KttsJobMgrPart::slot_job_hold()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ pauseText(jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_job_resume()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ resumeText(jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_job_restart()
+{
+ uint jobNum = getCurrentJobNum();
+ // kdDebug() << "KttsJobMgrPart::slot_job_restart: jobNum = " << jobNum << endl;
+ if (jobNum)
+ {
+ startText(jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_job_prev_par()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ // Get current part number.
+ uint partNum = jumpToTextPart(0, jobNum);
+ if (partNum > 1) jumpToTextPart(--partNum, jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_job_prev_sen()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ moveRelTextSentence(-1, jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_job_next_sen()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ moveRelTextSentence(1, jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_job_next_par()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ // Get current part number.
+ uint partNum = jumpToTextPart(0, jobNum);
+ jumpToTextPart(++partNum, jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_job_remove()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ removeText(jobNum);
+ m_currentSentence->clear();
+ }
+}
+
+void KttsJobMgrPart::slot_job_move()
+{
+ uint jobNum = getCurrentJobNum();
+ if (jobNum)
+ {
+ moveTextLater(jobNum);
+ refreshJobListView();
+ // Select the job we just moved.
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item) m_jobListView->setSelected(item, true);
+ }
+}
+
+void KttsJobMgrPart::slot_job_change_talker()
+{
+ QListViewItem* item = m_jobListView->selectedItem();
+ if (item)
+ {
+ QString talkerID = item->text(jlvcTalkerID);
+ QStringList talkerIDs = m_talkerCodesToTalkerIDs.values();
+ int ndx = talkerIDs.findIndex(talkerID);
+ QString talkerCode;
+ if (ndx >= 0) talkerCode = m_talkerCodesToTalkerIDs.keys()[ndx];
+ SelectTalkerDlg dlg(widget(), "selecttalkerdialog", i18n("Select Talker"), talkerCode, true);
+ int dlgResult = dlg.exec();
+ if (dlgResult != KDialogBase::Accepted) return;
+ talkerCode = dlg.getSelectedTalkerCode();
+ int jobNum = item->text(jlvcJobNum).toInt();
+ changeTextTalker(talkerCode, jobNum);
+ refreshJob(jobNum);
+ }
+}
+
+void KttsJobMgrPart::slot_speak_clipboard()
+{
+ // Get the clipboard object.
+ QClipboard *cb = kapp->clipboard();
+
+
+ // Copy text from the clipboard.
+ QString text;
+ QMimeSource* data = cb->data();
+ if (data)
+ {
+ if (data->provides("text/html"))
+ {
+ if (supportsMarkup(NULL, KSpeech::mtHtml))
+ {
+ QByteArray d = data->encodedData("text/html");
+ text = QString(d);
+ }
+ }
+ if (data->provides("text/ssml"))
+ {
+ if (supportsMarkup(NULL, KSpeech::mtSsml))
+ {
+ QByteArray d = data->encodedData("text/ssml");
+ text = QString(d);
+ }
+ }
+ }
+ if (text.isEmpty())
+ text = cb->text();
+
+ // Speak it.
+ if ( !text.isEmpty() )
+ {
+ uint jobNum = setText(text, NULL);
+ // kdDebug() << "KttsJobMgrPart::slot_speak_clipboard: started jobNum " << jobNum << endl;
+ startText(jobNum);
+ // Set flag so that the job we just created will be selected when textSet signal is received.
+ m_selectOnTextSet = true;
+ }
+}
+
+void KttsJobMgrPart::slot_speak_file()
+{
+ KEncodingFileDialog dlg;
+ KEncodingFileDialog::Result result = dlg.getOpenFileNameAndEncoding();
+ if (result.fileNames.count() == 1)
+ {
+ // kdDebug() << "KttsJobMgr::slot_speak_file: calling setFile with filename " <<
+ // result.fileNames[0] << " and encoding " << result.encoding << endl;
+ setFile(result.fileNames[0], NULL, result.encoding);
+ }
+}
+
+void KttsJobMgrPart::slot_refresh()
+{
+ // Clear TalkerID cache.
+ m_talkerCodesToTalkerIDs.clear();
+ // Get current job number.
+ uint jobNum = getCurrentJobNum();
+ refreshJobListView();
+ // Select the previously-selected job.
+ if (jobNum)
+ {
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item) m_jobListView->setSelected(item, true);
+ }
+}
+
+
+/**
+* Convert a KTTSD job state integer into a display string.
+* @param state KTTSD job state
+* @return Display string for the state.
+*/
+QString KttsJobMgrPart::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");
+ }
+}
+
+/**
+* Get the Job Number of the currently-selected job in the Job List View.
+* @return Job Number of currently-selected job.
+* 0 if no currently-selected job.
+*/
+uint KttsJobMgrPart::getCurrentJobNum()
+{
+ uint jobNum = 0;
+ QListViewItem* item = m_jobListView->selectedItem();
+ if (item)
+ {
+ QString jobNumStr = item->text(jlvcJobNum);
+ jobNum = jobNumStr.toUInt(0, 10);
+ }
+ return jobNum;
+}
+
+/**
+* Get the number of parts in the currently-selected job in the Job List View.
+* @return Number of parts in currently-selected job.
+* 0 if no currently-selected job.
+*/
+int KttsJobMgrPart::getCurrentJobPartCount()
+{
+ int partCount = 0;
+ QListViewItem* item = m_jobListView->selectedItem();
+ if (item)
+ {
+ QString partCountStr = item->text(jlvcPartCount);
+ partCount = partCountStr.toUInt(0, 10);
+ }
+ return partCount;
+}
+
+/**
+* Given a Job Number, returns the Job List View item containing the job.
+* @param jobNum Job Number.
+* @return QListViewItem containing the job or 0 if not found.
+*/
+QListViewItem* KttsJobMgrPart::findItemByJobNum(const uint jobNum)
+{
+ return m_jobListView->findItem(QString::number(jobNum), jlvcJobNum);
+}
+
+/**
+* Refresh display of a single job in the JobListView.
+* @param jobNum Job Number.
+*/
+void KttsJobMgrPart::refreshJob(uint jobNum)
+{
+ QByteArray jobInfo = getTextJobInfo(jobNum);
+ QDataStream stream(jobInfo, IO_ReadOnly);
+ int state;
+ QCString appId;
+ QString talker;
+ int seq;
+ int sentenceCount;
+ int partNum;
+ int partCount;
+ stream >> state;
+ stream >> appId;
+ stream >> talker;
+ stream >> seq;
+ stream >> sentenceCount;
+ stream >> partNum;
+ stream >> partCount;
+ QString talkerID = cachedTalkerCodeToTalkerID(talker);
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcTalkerID, talkerID);
+ item->setText(jlvcState, stateToStr(state));
+ item->setText(jlvcPosition, QString::number(seq));
+ item->setText(jlvcSentences, QString::number(sentenceCount));
+ item->setText(jlvcPartNum, QString::number(partNum));
+ item->setText(jlvcPartCount, QString::number(partCount));
+ }
+}
+
+/**
+* Fill the Job List View.
+*/
+void KttsJobMgrPart::refreshJobListView()
+{
+ // kdDebug() << "KttsJobMgrPart::refreshJobListView: Running" << endl;
+ m_jobListView->clear();
+ enableJobActions(false);
+ enableJobPartActions(false);
+ QString jobNumbers = getTextJobNumbers();
+ // kdDebug() << "jobNumbers: " << jobNumbers << endl;
+ QStringList jobNums = QStringList::split(",", jobNumbers);
+ QListViewItem* lastItem = 0;
+ QStringList::ConstIterator endJobNums(jobNums.constEnd());
+ for( QStringList::ConstIterator it = jobNums.constBegin(); it != endJobNums; ++it)
+ {
+ QString jobNumStr = *it;
+ // kdDebug() << "jobNumStr: " << jobNumStr << endl;
+ uint jobNum = jobNumStr.toUInt(0, 10);
+ QByteArray jobInfo = getTextJobInfo(jobNum);
+ QDataStream stream(jobInfo, IO_ReadOnly);
+ int state;
+ QCString appId;
+ QString talkerCode;
+ int seq;
+ int sentenceCount;
+ int partNum;
+ int partCount;
+ stream >> state;
+ stream >> appId;
+ stream >> talkerCode;
+ stream >> seq;
+ stream >> sentenceCount;
+ stream >> partNum;
+ stream >> partCount;
+ QString talkerID = cachedTalkerCodeToTalkerID(talkerCode);
+ // Append to list.
+ if (lastItem)
+ lastItem = new QListViewItem(m_jobListView, lastItem, jobNumStr, appId, talkerID,
+ stateToStr(state), QString::number(seq), QString::number(sentenceCount),
+ QString::number(partNum), QString::number(partCount));
+ else
+ lastItem = new QListViewItem(m_jobListView, jobNumStr, appId, talkerID,
+ stateToStr(state), QString::number(seq), QString::number(sentenceCount),
+ QString::number(partNum), QString::number(partCount));
+ }
+}
+
+/**
+* If nothing selected in Job List View and list not empty, select top item.
+* If nothing selected and list is empty, disable job buttons.
+*/
+void KttsJobMgrPart::autoSelectInJobListView()
+{
+ // If something selected, nothing to do.
+ if (m_jobListView->selectedItem()) return;
+ // If empty, disable job buttons.
+ QListViewItem* item = m_jobListView->firstChild();
+ if (!item)
+ {
+ enableJobActions(false);
+ enableJobPartActions(false);
+ }
+ else
+ // Select first item. Should fire itemSelected event which will enable job buttons.
+ m_jobListView->setSelected(item, true);
+}
+
+/**
+* Return the Talker ID corresponding to a Talker Code, retrieving from cached list if present.
+* @param talkerCode Talker Code.
+* @return Talker ID.
+*/
+QString KttsJobMgrPart::cachedTalkerCodeToTalkerID(const QString& talkerCode)
+{
+ // If in the cache, return that.
+ if (m_talkerCodesToTalkerIDs.contains(talkerCode))
+ return m_talkerCodesToTalkerIDs[talkerCode];
+ else
+ {
+ // Otherwise, retrieve Talker ID from KTTSD and cache it.
+ QString talkerID = talkerCodeToTalkerId(talkerCode);
+ m_talkerCodesToTalkerIDs[talkerCode] = talkerID;
+ return talkerID;
+ }
+}
+
+/**
+* Enables or disables all the job-related buttons.
+* @param enable True to enable the job-related butons. False to disable.
+*/
+void KttsJobMgrPart::enableJobActions(bool enable)
+{
+ if (!m_buttonBox) return;
+ QObjectList *l = m_buttonBox->queryList( "QPushButton", "job_*", true, true );
+ QObjectListIt it( *l ); // iterate over the buttons
+ QObject *obj;
+
+ while ( (obj = it.current()) != 0 ) {
+ // for each found object...
+ ++it;
+ ((QPushButton*)obj)->setEnabled( enable );
+ }
+ delete l; // delete the list, not the objects
+
+ if (enable)
+ {
+ // Later button only enables if currently selected list item is not bottom of list.
+ QListViewItem* item = m_jobListView->selectedItem();
+ if (item)
+ {
+ bool enableLater = item->nextSibling();
+
+ l = m_buttonBox->queryList( "QPushButton", "job_later", false, true );
+ it = QObjectListIt( *l ); // iterate over the buttons
+ if ( (obj = it.current()) != 0 ) {
+ // for each found object...
+ ((QPushButton*)obj)->setEnabled( enableLater );
+ }
+ delete l; // delete the list, not the objects
+ }
+ }
+}
+
+/**
+* Enables or disables all the job part-related buttons.
+* @param enable True to enable the job par-related butons. False to disable.
+*/
+void KttsJobMgrPart::enableJobPartActions(bool enable)
+{
+ if (!m_buttonBox) return;
+ QObjectList *l = m_buttonBox->queryList( "QPushButton", "part_*", true, true );
+ QObjectListIt it( *l ); // iterate over the buttons
+ QObject *obj;
+
+ while ( (obj = it.current()) != 0 ) {
+ // for each found object...
+ ++it;
+ ((QPushButton*)obj)->setEnabled( enable );
+ }
+ delete l; // delete the list, not the objects
+}
+
+/** DCOP Methods connected to DCOP Signals emitted by KTTSD. */
+
+/**
+* This signal is emitted when KTTSD starts or restarts after a call to reinit.
+*/
+ASYNC KttsJobMgrPart::kttsdStarted() { slot_refresh(); }
+
+/**
+* This signal is emitted when the speech engine/plugin encounters a marker in the text.
+* @param appId DCOP application ID of the application that queued the text.
+* @param markerName The name of the marker seen.
+* @see markers
+*/
+ASYNC KttsJobMgrPart::markerSeen(const QCString&, const QString&)
+{
+}
+
+/**
+ * This signal is emitted whenever a sentence begins speaking.
+ * @param appId DCOP application ID of the application that queued the text.
+ * @param jobNum Job number of the text job.
+ * @param seq Sequence number of the text.
+ * @see getTextCount
+ */
+ASYNC KttsJobMgrPart::sentenceStarted(const QCString&, const uint jobNum, const uint seq)
+{
+ // kdDebug() << "KttsJobMgrPart::sentencedStarted: jobNum = " << jobNum << " seq = " << seq << endl;
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcState, stateToStr(KSpeech::jsSpeaking));
+ item->setText(jlvcPosition, QString::number(seq));
+ m_currentSentence->setText(getTextJobSentence(jobNum, seq));
+ }
+}
+
+/**
+* This signal is emitted when a sentence has finished speaking.
+* @param appId DCOP application ID of the application that queued the text.
+* @param jobNum Job number of the text job.
+* @param seq Sequence number of the text.
+* @see getTextCount
+*/
+ASYNC KttsJobMgrPart::sentenceFinished(const QCString& /*appId*/, const uint /*jobNum*/, const uint /*seq*/)
+{
+ // kdDebug() << "KttsJobMgrPart::sentencedFinished: jobNum = " << jobNum << endl;
+/*
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcState, stateToStr(KSpeech::jsSpeaking));
+ }
+*/
+}
+
+/**
+* This signal is emitted whenever a new text job is added to the queue.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+*/
+ASYNC KttsJobMgrPart::textSet(const QCString&, const uint jobNum)
+{
+ QByteArray jobInfo = getTextJobInfo(jobNum);
+ QDataStream stream(jobInfo, IO_ReadOnly);
+ int state;
+ QCString appId;
+ QString talkerCode;
+ int seq;
+ int sentenceCount;
+ int partNum;
+ int partCount;
+ stream >> state;
+ stream >> appId;
+ stream >> talkerCode;
+ stream >> seq;
+ stream >> sentenceCount;
+ stream >> partNum;
+ stream >> partCount;
+ QString talkerID = cachedTalkerCodeToTalkerID(talkerCode);
+ QListViewItem* item = new QListViewItem(m_jobListView, m_jobListView->lastItem(),
+ QString::number(jobNum), appId, talkerID,
+ stateToStr(state), QString::number(seq), QString::number(sentenceCount),
+ QString::number(partNum), QString::number(partCount));
+ // Should we select this job?
+ if (m_selectOnTextSet)
+ {
+ m_jobListView->setSelected(item, true);
+ m_selectOnTextSet = false;
+ }
+ // If a job not already selected, select this one.
+ autoSelectInJobListView();
+}
+
+/**
+* This signal is emitted whenever a new part is appended to a text job.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+* @param partNum Part number of the new part. Parts are numbered starting
+* at 1.
+*/
+ASYNC KttsJobMgrPart::textAppended(const QCString& appId, const uint jobNum, const int /*partNum*/)
+{
+ textSet(appId, jobNum);
+}
+
+/**
+* This signal is emitted whenever speaking of a text job begins.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+*/
+ASYNC KttsJobMgrPart::textStarted(const QCString&, const uint jobNum)
+{
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcState, stateToStr(KSpeech::jsSpeaking));
+ item->setText(jlvcPosition, "1");
+ }
+}
+
+/**
+* This signal is emitted whenever a text job is finished. The job has
+* been marked for deletion from the queue and will be deleted when another
+* job reaches the Finished state. (Only one job in the text queue may be
+* in state Finished at one time.) If @ref startText or @ref resumeText is
+* called before the job is deleted, it will remain in the queue for speaking.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+*/
+ASYNC KttsJobMgrPart::textFinished(const QCString&, const uint jobNum)
+{
+ // kdDebug() << "KttsJobMgrPart::textFinished: jobNum = " << jobNum << endl;
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcState, stateToStr(KSpeech::jsFinished));
+ // Update sentence pointer, since signal may not be emitted for final CR.
+ refreshJob(jobNum);
+ }
+ m_currentSentence->setText(QString::null);
+}
+
+/**
+* This signal is emitted whenever a speaking text job stops speaking.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+*/
+ASYNC KttsJobMgrPart::textStopped(const QCString&, const uint jobNum)
+{
+ // kdDebug() << "KttsJobMgrPart::textStopped: jobNum = " << jobNum << endl;
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcState, stateToStr(KSpeech::jsQueued));
+ item->setText(jlvcPosition, "1");
+ }
+}
+
+/**
+* This signal is emitted whenever a speaking text job is paused.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+*/
+ASYNC KttsJobMgrPart::textPaused(const QCString&, const uint jobNum)
+{
+ // kdDebug() << "KttsJobMgrPart::textPaused: jobNum = " << jobNum << endl;
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcState, stateToStr(KSpeech::jsPaused));
+ }
+}
+
+/**
+* This signal is emitted when a text job, that was previously paused, resumes speaking.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+*/
+ASYNC KttsJobMgrPart::textResumed(const QCString&, const uint jobNum)
+{
+ QListViewItem* item = findItemByJobNum(jobNum);
+ if (item)
+ {
+ item->setText(jlvcState, stateToStr(KSpeech::jsSpeaking));
+ }
+}
+
+/**
+* This signal is emitted whenever a text job is deleted from the queue.
+* The job is no longer in the queue when this signal is emitted.
+* @param appId The DCOP senderId of the application that created the job.
+* @param jobNum Job number of the text job.
+*/
+ASYNC KttsJobMgrPart::textRemoved(const QCString&, const uint jobNum)
+{
+ QListViewItem* item = findItemByJobNum(jobNum);
+ delete item;
+ autoSelectInJobListView();
+}
+
+KttsJobMgrBrowserExtension::KttsJobMgrBrowserExtension(KttsJobMgrPart *parent)
+ : KParts::BrowserExtension(parent, "KttsJobMgrBrowserExtension")
+{
+}
+
+KttsJobMgrBrowserExtension::~KttsJobMgrBrowserExtension()
+{
+}
diff --git a/kttsd/kttsjobmgr/kttsjobmgr.desktop b/kttsd/kttsjobmgr/kttsjobmgr.desktop
new file mode 100644
index 0000000..f20da0c
--- /dev/null
+++ b/kttsd/kttsjobmgr/kttsjobmgr.desktop
@@ -0,0 +1,49 @@
+[Desktop Entry]
+Type=Service
+Name=kttsjobmgrpart
+Name[pt_BR]=Componente Ger. de Jobs do Ktts
+Name[tr]=Kttsjobmgrpart
+Comment=KDE Text-to-speech Job Manager
+Comment[bg]=Мениджър на задачите за синтез на глас
+Comment[ca]=Gestor de treballs de text a veu de KDE
+Comment[cs]=Správce úloh zvukové syntézy KDE
+Comment[da]=KDE's Tekst-til-tale Job-håndtering
+Comment[de]=KDE-Auftragsverwaltung für Sprachausgabe
+Comment[el]=KDE διαχειριστής εργασιών κειμένου-σε-ομιλία
+Comment[es]=Administrador de trabajos del sintetizador de texto a voz de KDE
+Comment[et]=KDE teksti kõneks muutmise tööde haldur
+Comment[eu]=KDE-ren testutik-hizketarako lan-kudeatzailea
+Comment[fa]=مدیر کار متن به گفتار KDE
+Comment[fi]=KDE Teksti puheeksi -töidenhallintaohjelma
+Comment[fr]=Gestionnaire de tâches de synthèse vocale pour KDE
+Comment[ga]=Bainisteoir Jabanna Téacs-go-Caint KDE
+Comment[gl]=Xestor de Traballos de Texto-para-Fala de KDE
+Comment[hu]=KDE-s kezelőprogram szövegfelolvasáshoz
+Comment[is]=KDE texti-í-tal verkstjóri
+Comment[it]=Gestore dei processi di pronuncia di KDE
+Comment[ja]=KDE テキスト読み上げジョブマネージャ
+Comment[ka]=KDE ტექსტი-გახმოვანების ამოცანათა მმართველი
+Comment[km]=ឧបករណ៍​គ្រប់គ្រង​ការងារ​អត្ថបទ​ដែលត្រូវ​និយាយ​របស់ KDE
+Comment[mk]=Менаџер на задачи во KDE за текст-во-говор
+Comment[ms]=Pengurus Kerja Teks-ke-tutur KDE
+Comment[nb]=Jobbkontroll for KDE tekst-til-tale
+Comment[nds]=KDE-Pleger för Vörleesopgaven
+Comment[ne]=केडीई पाठ वाचक काम प्रबन्धक
+Comment[nl]=KDE Tekst-tot-spraak-taakbeheer
+Comment[pa]=KDE ਪਾਠ ਤੋਂ ਬੋਲੀ ਕੰਮ ਮੈਨੇਜਰ
+Comment[pl]=Menedżer zadań odczytywania tekstu
+Comment[pt]=Gestor de Trabalhos do Texto para Fala do KDE
+Comment[pt_BR]=Gerenciador de Trabalhos de Texto para Fala do KDE
+Comment[ru]=Управление заданиями по синтезу речи
+Comment[sk]=Správca úloh KDE text-na-reč
+Comment[sl]=Upravitelj opravil besedila v govor za KDE
+Comment[sr]=KDE-ов менаџер послова за текст-у-говор
+Comment[sr@Latn]=KDE-ov menadžer poslova za tekst-u-govor
+Comment[sv]=KDE:s text-till-tal jobbhantering
+Comment[ta]=கேடியி உரையில் இருந்து பேச்சு பணி மேலாளர்
+Comment[tg]=Идоракунии фармоишҳо бо воситаи таҳлили овоз
+Comment[tr]=KDE Metinden Konuşmaya Görev Yöneticisi
+Comment[uk]=Менеджер завдань KDE для синтезу мовлення з тексту
+Comment[vi]=Trình quản lý Tác vụ Văn bản sang Tiếng nói KDE
+Comment[zh_TW]=KDE 文字轉語音工作管理員
+ServiceTypes=KParts/ReadOnlyPart
diff --git a/kttsd/kttsjobmgr/kttsjobmgr.h b/kttsd/kttsjobmgr/kttsjobmgr.h
new file mode 100644
index 0000000..6bb4898
--- /dev/null
+++ b/kttsd/kttsjobmgr/kttsjobmgr.h
@@ -0,0 +1,298 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ A KPart to display running jobs in KTTSD and permit user to stop, rewind,
+ advance, change Talker, etc.
+ -------------------
+ Copyright : (C) 2004 by 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; version 2 of the License. *
+ * *
+ ***************************************************************************/
+
+#ifndef _KTTSJOBMGRPART_H_
+#define _KTTSJOBMGRPART_H_
+
+// KDE includes.
+#include <kparts/browserextension.h>
+#include <klibloader.h>
+
+// KTTS includes.
+#include "kspeech_stub.h"
+#include "kspeechsink.h"
+
+class KAboutData;
+class KInstance;
+class KttsJobMgrBrowserExtension;
+class KListView;
+class QListViewItem;
+class QVBox;
+class KTextEdit;
+
+class KttsJobMgrFactory : public KLibFactory
+{
+ Q_OBJECT
+public:
+ KttsJobMgrFactory() {};
+ virtual ~KttsJobMgrFactory();
+
+ virtual QObject* createObject(QObject* parent = 0, const char* name = 0,
+ const char* classname = "QObject",
+ const QStringList &args = QStringList());
+
+ static KInstance *instance();
+ static KAboutData *aboutData();
+
+private:
+ static KInstance *s_instance;
+};
+
+class KttsJobMgrPart:
+ public KParts::ReadOnlyPart,
+ public KSpeech_stub,
+ virtual public KSpeechSink
+{
+ Q_OBJECT
+public:
+ KttsJobMgrPart(QWidget *parent, const char *name);
+ virtual ~KttsJobMgrPart();
+
+protected:
+ virtual bool openFile();
+ virtual bool closeURL();
+
+ /** DCOP Methods connected to DCOP Signals emitted by KTTSD. */
+
+ /**
+ * This signal is emitted when KTTSD starts or restarts after a call to reinit.
+ */
+ ASYNC kttsdStarted();
+ /**
+ * This signal is emitted when the speech engine/plugin encounters a marker in the text.
+ * @param appId DCOP application ID of the application that queued the text.
+ * @param markerName The name of the marker seen.
+ * @see markers
+ */
+ ASYNC markerSeen(const QCString& appId, const QString& markerName);
+ /**
+ * This signal is emitted whenever a sentence begins speaking.
+ * @param appId DCOP application ID of the application that queued the text.
+ * @param jobNum Job number of the text job.
+ * @param seq Sequence number of the text.
+ * @see getTextCount
+ */
+ ASYNC sentenceStarted(const QCString& appId, const uint jobNum, const uint seq);
+ /**
+ * This signal is emitted when a sentence has finished speaking.
+ * @param appId DCOP application ID of the application that queued the text.
+ * @param jobNum Job number of the text job.
+ * @param seq Sequence number of the text.
+ * @see getTextCount
+ */
+ ASYNC sentenceFinished(const QCString& appId, const uint jobNum, const uint seq);
+
+ /**
+ * This signal is emitted whenever a new text job is added to the queue.
+ * @param appId The DCOP senderId of the application that created the job. NULL if kttsd.
+ * @param jobNum Job number of the text job.
+ */
+ ASYNC textSet(const QCString& appId, const uint jobNum);
+
+ /**
+ * This signal is emitted whenever a new part is appended to a text job.
+ * @param appId The DCOP senderId of the application that created the job.
+ * @param jobNum Job number of the text job.
+ * @param partNum Part number of the new part. Parts are numbered starting
+ * at 1.
+ */
+ ASYNC textAppended(const QCString& appId, const uint jobNum, const int partNum);
+
+ /**
+ * This signal is emitted whenever speaking of a text job begins.
+ * @param appId The DCOP senderId of the application that created the job. NULL if kttsd.
+ * @param jobNum Job number of the text job.
+ */
+ ASYNC textStarted(const QCString& appId, const uint jobNum);
+ /**
+ * This signal is emitted whenever a text job is finished. The job has
+ * been marked for deletion from the queue and will be deleted when another
+ * job reaches the Finished state. (Only one job in the text queue may be
+ * in state Finished at one time.) If @ref startText or @ref resumeText is
+ * called before the job is deleted, it will remain in the queue for speaking.
+ * @param appId The DCOP senderId of the application that created the job. NULL if kttsd.
+ * @param jobNum Job number of the text job.
+ */
+ ASYNC textFinished(const QCString& appId, const uint jobNum);
+ /**
+ * This signal is emitted whenever a speaking text job stops speaking.
+ * @param appId The DCOP senderId of the application that created the job. NULL if kttsd.
+ * @param jobNum Job number of the text job.
+ */
+ ASYNC textStopped(const QCString& appId, const uint jobNum);
+ /**
+ * This signal is emitted whenever a speaking text job is paused.
+ * @param appId The DCOP senderId of the application that created the job. NULL if kttsd.
+ * @param jobNum Job number of the text job.
+ */
+ ASYNC textPaused(const QCString& appId, const uint jobNum);
+ /**
+ * This signal is emitted when a text job, that was previously paused, resumes speaking.
+ * @param appId The DCOP senderId of the application that created the job. NULL if kttsd.
+ * @param jobNum Job number of the text job.
+ */
+ ASYNC textResumed(const QCString& appId, const uint jobNum);
+ /**
+ * This signal is emitted whenever a text job is deleted from the queue.
+ * The job is no longer in the queue when this signal is emitted.
+ * @param appId The DCOP senderId of the application that created the job. NULL if kttsd.
+ * @param jobNum Job number of the text job.
+ */
+ ASYNC textRemoved(const QCString& appId, const uint jobNum);
+
+private slots:
+ /**
+ * This slot is connected to the Job List View selectionChanged signal.
+ */
+ void slot_selectionChanged(QListViewItem* item);
+ /**
+ * Slots connected to buttons.
+ */
+ void slot_job_hold();
+ void slot_job_resume();
+ void slot_job_restart();
+ void slot_job_remove();
+ void slot_job_move();
+ void slot_job_change_talker();
+ void slot_speak_clipboard();
+ void slot_speak_file();
+ void slot_refresh();
+ void slot_job_prev_par();
+ void slot_job_prev_sen();
+ void slot_job_next_sen();
+ void slot_job_next_par();
+
+private:
+ /**
+ * @enum JobListViewColumn
+ * Columns in the Job List View.
+ */
+ enum JobListViewColumn
+ {
+ jlvcJobNum = 0, /**< Job Number. */
+ jlvcOwner = 1, /**< AppId of job owner */
+ jlvcTalkerID = 2, /**< Job Talker ID */
+ jlvcState = 3, /**< Job State */
+ jlvcPosition = 4, /**< Current sentence of job. */
+ jlvcSentences = 5, /**< Number of sentences in job. */
+ jlvcPartNum = 6, /**< Current part of the job. */
+ jlvcPartCount = 7 /**< Number of parts in job. */
+ };
+
+ /**
+ * Convert a KTTSD job state integer into a display string.
+ * @param state KTTSD job state
+ * @return Display string for the state.
+ */
+ QString stateToStr(int state);
+
+ /**
+ * Get the Job Number of the currently-selected job in the Job List View.
+ * @return Job Number of currently-selected job.
+ * 0 if no currently-selected job.
+ */
+ uint getCurrentJobNum();
+
+ /**
+ * Get the number of parts in the currently-selected job in the Job List View.
+ * @return Number of parts in currently-selected job.
+ * 0 if no currently-selected job.
+ */
+ int getCurrentJobPartCount();
+
+ /**
+ * Given a Job Number, returns the Job List View item containing the job.
+ * @param jobNum Job Number.
+ * @return QListViewItem containing the job or 0 if not found.
+ */
+ QListViewItem* findItemByJobNum(const uint jobNum);
+
+ /**
+ * Enables or disables all the job-related buttons.
+ * @param enable True to enable the job-related butons. False to disable.
+ */
+ void enableJobActions(bool enable);
+
+ /**
+ * Enables or disables all the job part-related buttons.
+ * @param enable True to enable the job par-related butons. False to disable.
+ */
+ void enableJobPartActions(bool enable);
+
+ /**
+ * Refresh display of a single job in the JobListView.
+ * @param jobNum Job Number.
+ */
+ void refreshJob(uint jobNum);
+
+ /**
+ * Fill the Job List View.
+ */
+ void refreshJobListView();
+
+ /**
+ * If nothing selected in Job List View and list not empty, select top item.
+ * If nothing selected and list is empty, disable job buttons.
+ */
+ void autoSelectInJobListView();
+
+ /**
+ * Return the Talker ID corresponding to a Talker Code, retrieving from cached list if present.
+ * @param talkerCode Talker Code.
+ * @return Talker ID.
+ */
+ QString cachedTalkerCodeToTalkerID(const QString& talkerCode);
+
+ /**
+ * Job ListView.
+ */
+ KListView* m_jobListView;
+ KttsJobMgrBrowserExtension *m_extension;
+
+ /**
+ * Current sentence box.
+ */
+ KTextEdit* m_currentSentence;
+
+ /**
+ * Box containing buttons.
+ */
+ QVBox* m_buttonBox;
+
+ /**
+ * This flag is set to True whenever we want to select the next job that
+ * is announced in a textSet signal.
+ */
+ bool m_selectOnTextSet;
+
+ /**
+ * Cache mapping Talker Codes to Talker IDs.
+ */
+ QMap<QString,QString> m_talkerCodesToTalkerIDs;
+};
+
+class KttsJobMgrBrowserExtension : public KParts::BrowserExtension
+{
+ Q_OBJECT
+ friend class KttsJobMgrPart;
+public:
+ KttsJobMgrBrowserExtension(KttsJobMgrPart *parent);
+ virtual ~KttsJobMgrBrowserExtension();
+};
+
+#endif // _KTTSJOBMGRPART_H_
+