qt3support--
[kdeaccessibility.git] / kttsd / kttsd / speechdata.h
blobfcd69c4ca8daf4f5610d685ca3497d7b6119c6a7
1 /*************************************************** vim:set ts=4 sw=4 sts=4:
2 This contains the SpeechData class which is in charge of maintaining
3 all the data on the memory.
4 It maintains queues manages the text.
5 We could say that this is the common repository between the KTTSD class
6 (dcop service) and the Speaker class (speaker, loads plug ins, call plug in
7 functions)
8 -------------------
9 Copyright:
10 (C) 2002-2003 by José Pablo Ezequiel "Pupeno" Fernández <pupeno@kde.org>
11 (C) 2003-2004 by Olaf Schmidt <ojschmidt@kde.org>
12 (C) 2004-2005 by Gary Cramblitt <garycramblitt@comcast.net>
13 -------------------
14 Original author: José Pablo Ezequiel "Pupeno" Fernández
15 ******************************************************************************/
17 /******************************************************************************
18 * *
19 * This program is free software; you can redistribute it and/or modify *
20 * it under the terms of the GNU General Public License as published by *
21 * the Free Software Foundation; either version 2 of the License. *
22 * *
23 ******************************************************************************/
25 #ifndef _SPEECHDATA_H_
26 #define _SPEECHDATA_H_
28 // Qt includes.
29 #include <QQueue>
30 #include <QList>
31 #include <QByteArray>
32 #include <QHash>
33 #include <QString>
34 #include <QStringList>
35 #include <QMap>
37 // KDE includes.
38 #include <kconfig.h>
40 // KTTS includes.
41 #include <kspeech.h>
42 #include <talkercode.h>
43 #include <filtermgr.h>
45 class TalkerMgr;
47 /**
48 * Struct containing a text cell, for messages, warnings, and texts.
49 * Contains the text itself, the associated talker,
50 * the ID of the application that requested it be spoken, and a sequence number.
52 struct mlText{
53 QString talker; /* Requested Talker code for the sentence. */
54 QString text; /* Text of sentence. */
55 QByteArray appId; /* DCOP senderId of the application that requested the speech. */
56 uint jobNum; /* Text jobNum. Only applies to text messages; not warning and messages. */
57 uint seq; /* Sequence number. */
60 /**
61 * Struct containing a text job.
63 struct mlJob {
64 uint jobNum; /* Job number. */
65 KSpeech::kttsdJobState state; /* Job state. */
66 QByteArray appId; /* DCOP senderId of the application that requested the speech job. */
67 QString talker; /* Requested Talker code in which to speak the text. */
68 int seq; /* Current sentence being spoken. */
69 QList<int> partSeqNums; /* List containing last sequence number for each part of a job. */
70 QStringList sentences; /* List of sentences in the job. */
73 /**
74 * Struct used to keep a pool of FilterMgr objects.
76 struct PooledFilterMgr {
77 FilterMgr* filterMgr; /* The FilterMgr object. */
78 bool busy; /* True if the FilterMgr is busy. */
79 mlJob* job; /* The job the FilterMgr is filtering. */
80 TalkerCode* talkerCode; /* TalkerCode object passed to FilterMgr. */
83 /**
84 * Struct used to keep notification options.
86 struct NotifyOptions {
87 QString eventName;
88 int action;
89 QString talker;
90 QString customMsg;
93 /**
94 * A list of notification options for a single app, indexed by event.
96 typedef QMap<QString, NotifyOptions> NotifyEventMap;
98 /**
99 * A list of notification event maps for all apps, indexed by app.
101 typedef QMap<QString, NotifyEventMap> NotifyAppMap;
104 * SpeechData class which is in charge of maintaining all the data on the memory.
105 * It maintains queues and has methods to enque
106 * messages and warnings and manage the text queues.
107 * We could say that this is the common repository between the KTTSD class
108 * (dcop service) and the Speaker class (speaker, loads plug ins, call plug in
109 * functions)
111 class SpeechData : public QObject {
112 Q_OBJECT
114 public:
116 * Constructor
117 * Sets text to be stopped and warnings and messages queues to be autodelete (thread safe)
119 SpeechData();
122 * Destructor
124 ~SpeechData();
127 * Read the configuration
129 bool readConfig();
132 * Say a message as soon as possible, interrupting any other speech in progress.
133 * IMPORTANT: This method is reserved for use by Screen Readers and should not be used
134 * by any other applications.
135 * @param msg The message to be spoken.
136 * @param talker Code for the talker to speak the message. Example "en".
137 * If NULL, defaults to the user's default talker.
138 * If no plugin has been configured for the specified Talker code,
139 * defaults to the closest matching talker.
140 * @param appId The DCOP senderId of the application.
142 * If an existing Screen Reader output is in progress, it is stopped and discarded and
143 * replaced with this new message.
145 void setScreenReaderOutput(const QString &msg, const QString &talker,
146 const QByteArray& appId);
149 * Given an appId, returns the last (most recently queued) Job Number with that appId,
150 * or if no such job, the Job Number of the last (most recent) job in the queue.
151 * @param appId The DCOP senderId of the application.
152 * @return Job Number of the text job.
153 * If no such job, returns 0.
154 * If appId is NULL, returns the Job Number of the last job in the queue.
155 * Does not change textJobs.current().
157 uint findAJobNumByAppId(const QByteArray& appId);
160 * Retrieves the Screen Reader Output.
162 mlText* getScreenReaderOutput();
165 * Returns true if Screen Reader Output is ready to be spoken.
167 bool screenReaderOutputReady();
170 * Add a new warning to the queue.
172 void enqueueWarning( const QString &, const QString &talker,
173 const QByteArray& appId);
176 * Pop (get and erase) a warning from the queue.
177 * @return Pointer to mlText structure containing the warning.
179 * Caller is responsible for deleting the structure.
181 mlText* dequeueWarning();
184 * Are there any Warnings?
186 bool warningInQueue();
189 * Add a new message to the queue.
191 void enqueueMessage( const QString &, const QString &talker,
192 const QByteArray&);
195 * Pop (get and erase) a message from the queue.
196 * @return Pointer to mlText structure containing the message.
198 * Caller is responsible for deleting the structure.
200 mlText* dequeueMessage();
203 * Are there any Messages?
205 bool messageInQueue();
208 * Sets the GREP pattern that will be used as the sentence delimiter.
209 * @param delimiter A valid GREP pattern.
210 * @param appId The DCOP senderId of the application.
212 * The default delimiter is
213 @verbatim
214 ([\\.\\?\\!\\:\\;])\\s
215 @endverbatim
217 * Note that backward slashes must be escaped.
219 * Changing the sentence delimiter does not affect other applications.
220 * @see sentenceparsing
222 void setSentenceDelimiter(const QString &delimiter, const QByteArray appId);
224 /* The following methods correspond to the methods in KSpeech interface. */
227 * Queue a text job. Does not start speaking the text.
228 * (thread safe)
229 * @param text The message to be spoken.
230 * @param talker Code for the talker to speak the text. Example "en".
231 * If NULL, defaults to the user's default talker.
232 * If no plugin has been configured for the specified Talker code,
233 * defaults to the closest matching talker.
234 * @param appId The DCOP senderId of the application.
235 * @return Job number.
237 * The text is parsed into individual sentences. Call getTextCount to retrieve
238 * the sentence count. Call startText to mark the job as speakable and if the
239 * job is the first speakable job in the queue, speaking will begin.
240 * @see startText.
242 uint setText(const QString &text, const QString &talker, const QByteArray& appId);
245 * Adds another part to a text job. Does not start speaking the text.
246 * (thread safe)
247 * @param jobNum Job number of the text job.
248 * @param text The message to be spoken.
249 * @param appId The DCOP senderId of the application.
250 * @return Part number for the added part. Parts are numbered starting at 1.
252 * The text is parsed into individual sentences. Call getTextCount to retrieve
253 * the sentence count. Call startText to mark the job as speakable and if the
254 * job is the first speakable job in the queue, speaking will begin.
255 * @see setText.
256 * @see startText.
258 int appendText(const QString &text, const uint jobNum, const QByteArray& appId);
261 * Get the number of sentences in a text job.
262 * (thread safe)
263 * @param jobNum Job number of the text job.
264 * @return The number of sentences in the job. -1 if no such job.
266 * The sentences of a job are given sequence numbers from 1 to the number returned by this
267 * method. The sequence numbers are emitted in the sentenceStarted and sentenceFinished signals.
269 int getTextCount(const uint jobNum);
272 * Get the number of jobs in the text job queue.
273 * (thread safe)
274 * @return Number of text jobs in the queue. 0 if none.
276 uint getTextJobCount();
279 * Get a comma-separated list of text job numbers in the queue.
280 * @return Comma-separated list of text job numbers in the queue.
282 QString getTextJobNumbers();
285 * Get the state of a text job.
286 * (thread safe)
287 * @param jobNum Job number of the text job.
288 * @return State of the job. -1 if invalid job number.
290 int getTextJobState(const uint jobNum);
293 * Set the state of a text job.
294 * @param jobNum Job Number of the job.
295 * @param state New state for the job.
298 void setTextJobState(const uint jobNum, const KSpeech::kttsdJobState state);
301 * Get information about a text job.
302 * @param jobNum Job number of the text job.
303 * @return A QDataStream containing information about the job.
304 * Blank if no such job.
306 * The stream contains the following elements:
307 * - int state Job state.
308 * - QByteArray appId DCOP senderId of the application that requested the speech job.
309 * - QString talker Talker code as requested by application.
310 * - int seq Current sentence being spoken. Sentences are numbered starting at 1.
311 * - int sentenceCount Total number of sentences in the job.
312 * - int partNum Current part of the job begin spoken. Parts are numbered starting at 1.
313 * - int partCount Total number of parts in the job.
315 * Note that sequence numbers apply to the entire job.
316 * They do not start from 1 at the beginning of each part.
318 * The following sample code will decode the stream:
319 @verbatim
320 QByteArray jobInfo = getTextJobInfo(jobNum);
321 QDataStream stream(jobInfo, QIODevice::ReadOnly);
322 int state;
323 QByteArray appId;
324 QString talker;
325 int seq;
326 int sentenceCount;
327 int partNum;
328 int partCount;
329 stream >> state;
330 stream >> appId;
331 stream >> talker;
332 stream >> seq;
333 stream >> sentenceCount;
334 stream >> partNum;
335 stream >> partCount;
336 @endverbatim
338 QByteArray getTextJobInfo(const uint jobNum);
341 * Return a sentence of a job.
342 * @param jobNum Job number of the text job.
343 * @param seq Sequence number of the sentence.
344 * @return The specified sentence in the specified job. If no such
345 * job or sentence, returns "".
347 QString getTextJobSentence(const uint jobNum, const uint seq=1);
350 * Remove a text job from the queue.
351 * (thread safe)
352 * @param jobNum Job number of the text job.
354 * The job is deleted from the queue and the textRemoved signal is emitted.
356 void removeText(const uint jobNum);
359 * Change the talker for a text job.
360 * @param jobNum Job number of the text job.
361 * @param talker New code for the talker to do speaking. Example "en".
362 * If NULL, defaults to the user's default talker.
363 * If no plugin has been configured for the specified Talker code,
364 * defaults to the closest matching talker.
366 void changeTextTalker(const QString &talker, uint jobNum);
369 * Move a text job down in the queue so that it is spoken later.
370 * @param jobNum Job number of the text job.
372 void moveTextLater(const uint jobNum);
375 * Jump to the first sentence of a specified part of a text job.
376 * @param partNum Part number of the part to jump to. Parts are numbered starting at 1.
377 * @param jobNum Job number of the text job.
378 * @return Part number of the part actually jumped to.
380 * If partNum is greater than the number of parts in the job, jumps to last part.
381 * If partNum is 0, does nothing and returns the current part number.
382 * If no such job, does nothing and returns 0.
383 * Does not affect the current speaking/not-speaking state of the job.
385 int jumpToTextPart(const int partNum, const uint jobNum);
388 * Advance or rewind N sentences in a text job.
389 * @param n Number of sentences to advance (positive) or rewind (negative)
390 * in the job.
391 * @param jobNum Job number of the text job.
392 * @return Sequence number of the sentence actually moved to. Sequence numbers
393 * are numbered starting at 1.
395 * If no such job, does nothing and returns 0.
396 * If n is zero, returns the current sequence number of the job.
397 * Does not affect the current speaking/not-speaking state of the job.
399 uint moveRelTextSentence(const int n, const uint jobNum);
402 * Given a jobNum, returns the first job with that jobNum.
403 * @return Pointer to the text job.
404 * If no such job, returns 0.
405 * Does not change textJobs.current().
407 mlJob* findJobByJobNum(const uint jobNum);
410 * Given a Job Number, returns the next speakable text job on the queue.
411 * @param prevJobNum Current job number (which should not be returned).
412 * @return Pointer to mlJob structure of the first speakable job
413 * not equal prevJobNum. If no such job, returns null.
415 * Caller must not delete the job.
417 mlJob* getNextSpeakableJob(const uint prevJobNum);
420 * Given previous job number and sequence number, returns the next sentence from the
421 * text queue. If no such sentence is available, either because we've run out of
422 * jobs, or because all jobs are paused, returns null.
423 * @param prevJobNum Previous Job Number.
424 * @param prevSeq Previous sequency number.
425 * @return Pointer to n mlText structure containing the next sentence. If no
426 * sentence, returns null.
428 * Caller is responsible for deleting the returned mlText structure (if not null).
430 mlText* getNextSentenceText(const uint prevJobNum, const uint prevSeq);
433 * Given a Job Number, sets the current sequence number of the job.
434 * @param jobNum Job Number.
435 * @param seq Sequence number.
436 * If for some reason, the job does not exist, nothing happens.
438 void setJobSequenceNum(const uint jobNum, const uint seq);
441 * Given a Job Number, returns the current sequence number of the job.
442 * @param jobNum Job Number.
443 * @return Sequence number of the job. If no such job, returns 0.
445 uint getJobSequenceNum(const uint jobNum);
448 * Given a jobNum, returns the appId of the application that owns the job.
449 * @param jobNum Job number of the text job.
450 * @return appId of the job.
451 * If no such job, returns "".
452 * Does not change textJobs.current().
454 QByteArray getAppIdByJobNum(const uint jobNum);
457 * Sets pointer to the TalkerMgr object.
459 void setTalkerMgr(TalkerMgr* talkerMgr);
461 /* The following properties come from the configuration. */
464 * Text pre message
466 QString textPreMsg;
469 * Text pre message enabled ?
471 bool textPreMsgEnabled;
474 * Text pre sound
476 QString textPreSnd;
479 * Text pre sound enabled ?
481 bool textPreSndEnabled;
484 * Text post message
486 QString textPostMsg;
489 * Text post message enabled ?
491 bool textPostMsgEnabled;
494 * Text post sound
496 QString textPostSnd;
499 * Text post sound enabled ?
501 bool textPostSndEnabled;
504 * Paragraph pre message
506 QString parPreMsg;
509 * Paragraph pre message enabled ?
511 bool parPreMsgEnabled;
514 * Paragraph pre sound
516 QString parPreSnd;
519 * Paragraph pre sound enabled ?
521 bool parPreSndEnabled;
524 * Paragraph post message
526 QString parPostMsg;
529 * Paragraph post message enabled ?
531 bool parPostMsgEnabled;
534 * Paragraph post sound
536 QString parPostSnd;
539 * Paragraph post sound enabled ?
541 bool parPostSndEnabled;
544 * Keep audio files. Do not delete generated tmp wav files.
546 bool keepAudio;
547 QString keepAudioPath;
550 * Notification settings.
552 bool notify;
553 bool notifyExcludeEventsWithSound;
554 NotifyAppMap notifyAppMap;
555 int notifyDefaultPresent;
556 NotifyOptions notifyDefaultOptions;
559 * Automatically start KTTSMgr whenever speaking.
561 bool autoStartManager;
564 * Automatically exit auto-started KTTSMgr when speaking finishes.
566 bool autoExitManager;
569 * Configuration
571 KConfig *config;
574 * True if at least one XML Transformer plugin for html is enabled.
576 bool supportsHTML;
578 signals:
580 * This signal is emitted whenever a new text job is added to the queue.
581 * @param appId The DCOP senderId of the application that created the job.
582 * @param jobNum Job number of the text job.
584 void textSet(const QByteArray& appId, const uint jobNum);
587 * This signal is emitted whenever a new part is appended to a text job.
588 * @param appId The DCOP senderId of the application that created the job.
589 * @param jobNum Job number of the text job.
590 * @param partNum Part number of the new part. Parts are numbered starting
591 * at 1.
593 void textAppended(const QByteArray& appId, const uint jobNum, const int partNum);
596 * This signal is emitted whenever a text job is deleted from the queue.
597 * The job is no longer in the queue when this signal is emitted.
598 * @param appId The DCOP senderId of the application that created the job.
599 * @param jobNum Job number of the text job.
601 void textRemoved(const QByteArray& appId, const uint jobNum);
603 private:
605 * Screen Reader Output.
607 mlText screenReaderOutput;
610 * Queue of warnings
612 QQueue<mlJob*> warnings;
615 * Queue of messages
617 QQueue<mlJob*> messages;
620 * Queue of text jobs.
622 QList<mlJob*> textJobs;
625 * TalkerMgr object local pointer.
627 TalkerMgr* m_talkerMgr;
630 * Pool of FilterMgrs.
632 QHash<int, PooledFilterMgr*> m_pooledFilterMgrs;
635 * Job counter. Each new job increments this counter.
637 uint jobCounter;
640 * Talker of the text
642 QString textTalker;
645 * Map of sentence delimiters. One per app. If none specified for an app, uses default.
647 QMap<QByteArray, QString> sentenceDelimiters;
650 * Determines whether the given text is SSML markup.
652 bool isSsml(const QString &text);
655 * Given an appId, returns the last (most recently queued) job with that appId.
656 * @param appId The DCOP senderId of the application.
657 * @return Pointer to the text job.
658 * If no such job, returns 0.
659 * If appId is NULL, returns the last job in the queue.
660 * Does not change textJobs.current().
662 mlJob* findLastJobByAppId(const QByteArray& appId);
665 * Given an appId, returns the last (most recently queued) job with that appId,
666 * or if no such job, the last (most recent) job in the queue.
667 * @param appId The DCOP senderId of the application.
668 * @return Pointer to the text job.
669 * If no such job, returns 0.
670 * If appId is NULL, returns the last job in the queue.
671 * Does not change textJobs.current().
673 mlJob* SpeechData::findAJobByAppId(const QByteArray& appId);
676 * Given a job and a sequence number, returns the part that sentence is in.
677 * If no such job or sequence number, returns 0.
678 * @param job The text job.
679 * @param seq Sequence number of the sentence. Sequence numbers begin with 1.
680 * @return Part number of the part the sentence is in. Parts are numbered
681 * beginning with 1. If no such job or sentence, returns 0.
683 int getJobPartNumFromSeq(const mlJob& job, const int seq);
686 * Parses a block of text into sentences using the application-specified regular expression
687 * or (if not specified), the default regular expression.
688 * @param text The message to be spoken.
689 * @param appId The DCOP senderId of the application.
690 * @return List of parsed sentences.
693 QStringList SpeechData::parseText(const QString &text, const QByteArray &appId);
696 * Delete expired jobs. At most, one finished job is kept on the queue.
697 * @param finishedJobNum Job number of a job that just finished
698 * The just finished job is not deleted, but any other finished jobs are.
699 * Does not change the textJobs.current() pointer.
701 void deleteExpiredJobs(const uint finishedJobNum);
704 * Assigns a FilterMgr to a job and starts filtering on it.
706 void startJobFiltering(mlJob* job, const QString& text, bool noSBD);
709 * Waits for filtering to be completed on a job.
710 * This is typically called because an app has requested job info that requires
711 * filtering to be completed, such as getJobInfo.
713 void waitJobFiltering(const mlJob* job);
716 * Processes filters by looping across the pool of FilterMgrs.
717 * As each FilterMgr finishes, emits appropriate signals and flags it as no longer busy.
719 void doFiltering();
722 * Loads notify events from a file. Clearing data if clear is True.
724 void loadNotifyEventsFromFile( const QString& filename, bool clear);
726 private slots:
727 void slotFilterMgrFinished();
728 void slotFilterMgrStopped();
731 #endif // _SPEECHDATA_H_