rbutil: add the forgotten ui file from festival support.
[kugel-rb.git] / rbutil / rbutilqt / talkfile.cpp
blob43993be4363fd12b8f4f06ed6c1e505f1818b0e2
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "talkfile.h"
22 TalkFileCreator::TalkFileCreator(QObject* parent): QObject(parent)
27 //! \brief Creates Talkfiles.
28 //!
29 //! \param logger A pointer to a Loggerobject
30 bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger)
32 m_abort = false;
33 m_logger = logger;
35 QMultiMap<QString,QString> fileList;
36 QMultiMap<QString,QString> dirList;
37 QStringList toSpeakList, voicedEntries, encodedEntries;
38 QString errStr;
40 m_logger->addItem(tr("Starting Talk file generation"),LOGINFO);
42 //tts
43 m_tts = TTSBase::getTTS(settings->curTTS());
44 m_tts->setCfg(settings);
46 if(!m_tts->start(&errStr))
48 m_logger->addItem(errStr.trimmed(),LOGERROR);
49 m_logger->addItem(tr("Init of TTS engine failed"),LOGERROR);
50 m_logger->abort();
51 return false;
54 // Encoder
55 m_enc = EncBase::getEncoder(settings->curEncoder());
56 m_enc->setCfg(settings);
58 if(!m_enc->start())
60 m_logger->addItem(tr("Init of Encoder engine failed"),LOGERROR);
61 m_logger->abort();
62 m_tts->stop();
63 return false;
66 QCoreApplication::processEvents();
68 connect(logger,SIGNAL(aborted()),this,SLOT(abort()));
69 m_logger->setProgressMax(0);
71 // read in Maps of paths - file/dirnames
72 m_logger->addItem(tr("Reading Filelist..."),LOGINFO);
73 if(createDirAndFileMaps(m_dir,&dirList,&fileList) == false)
75 m_logger->addItem(tr("Talk file creation aborted"),LOGERROR);
76 doAbort(toSpeakList);
77 return false;
80 // create List of all Files/Dirs to speak
81 QMapIterator<QString, QString> dirIt(dirList);
82 while (dirIt.hasNext())
84 dirIt.next();
85 // insert only non dublicate dir entries into list
86 if(!toSpeakList.contains(dirIt.value()))
88 qDebug() << "toSpeaklist dir:" << dirIt.value();
89 toSpeakList.append(dirIt.value());
92 QMapIterator<QString, QString> fileIt(fileList);
93 while (fileIt.hasNext())
95 fileIt.next();
96 // insert only non- dublictae file entries into list
97 if(!toSpeakList.contains(fileIt.value()))
99 if(m_stripExtensions)
100 toSpeakList.append(stripExtension(fileIt.value()));
101 else
102 toSpeakList.append(fileIt.value());
106 // Voice entries
107 m_logger->addItem(tr("Voicing entries..."),LOGINFO);
108 TTSStatus voiceStatus= voiceList(toSpeakList,voicedEntries);
109 if(voiceStatus == FatalError)
111 doAbort(toSpeakList);
112 return false;
115 // Encoding Entries
116 m_logger->addItem(tr("Encoding files..."),LOGINFO);
117 if(encodeList(voicedEntries,encodedEntries) == false)
119 doAbort(toSpeakList);
120 return false;
123 // Copying talk files
124 m_logger->addItem(tr("Copying Talkfile for Dirs..."),LOGINFO);
125 if(copyTalkDirFiles(dirList,&errStr) == false)
127 m_logger->addItem(errStr,LOGERROR);
128 doAbort(toSpeakList);
129 return false;
132 //Copying file talk files
133 m_logger->addItem(tr("Copying Talkfile for Files..."),LOGINFO);
134 if(copyTalkFileFiles(fileList,&errStr) == false)
136 m_logger->addItem(errStr,LOGERROR);
137 doAbort(toSpeakList);
138 return false;
141 // Deleting left overs
142 if( !cleanup(toSpeakList))
143 return false;
145 m_tts->stop();
146 m_enc->stop();
147 m_logger->addItem(tr("Finished creating Talk files"),LOGOK);
148 m_logger->setProgressMax(1);
149 m_logger->setProgressValue(1);
150 m_logger->abort();
152 return true;
155 //! \brief resets the internal progress counter, and sets the Progressbar in the Logger
157 //! \param max The maximum to shich the Progressbar is set.
158 void TalkFileCreator::resetProgress(int max)
160 m_progress = 0;
161 m_logger->setProgressMax(max);
162 m_logger->setProgressValue(m_progress);
165 //! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed
167 //! \param filename The filename from which to strip the Extension
168 //! \returns the modified string
169 QString TalkFileCreator::stripExtension(QString filename)
171 if(filename.lastIndexOf(".") != -1)
172 return filename.left(filename.lastIndexOf("."));
173 else
174 return filename;
177 //! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder
179 //! \param cleanupList List of filenames to give to cleanup()
180 void TalkFileCreator::doAbort(QStringList cleanupList)
182 cleanup(cleanupList);
183 m_logger->setProgressMax(1);
184 m_logger->setProgressValue(0);
185 m_logger->abort();
186 m_tts->stop();
187 m_enc->stop();
190 //! \brief Creates MultiMaps (paths -> File/dir names) of all Dirs and Files in a Folder.
191 //! Depending on settings, either Dirs or Files can be ignored.
192 //! Also recursion is controlled by settings
194 //! \param startDir The dir where it beginns scanning
195 //! \param dirMap The MulitMap where the dirs are stored
196 //! \param filMap The MultiMap where Files are stored
197 //! \returns true on Success, false if User aborted.
198 bool TalkFileCreator::createDirAndFileMaps(QDir startDir,QMultiMap<QString,QString> *dirMap,QMultiMap<QString,QString> *fileMap)
200 // create Iterator
201 QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags;
202 if(m_recursive)
203 flags = QDirIterator::Subdirectories;
205 QDirIterator it(startDir,flags);
207 // read in Maps of paths - file/dirnames
208 while (it.hasNext())
210 it.next();
211 if(m_abort)
213 return false;
216 QFileInfo fileInf = it.fileInfo();
218 // its a dir
219 if(fileInf.isDir())
221 QDir dir = fileInf.dir();
223 // insert into List
224 if(!dir.dirName().isEmpty() && m_talkFolders)
226 qDebug() << "Dir: " << dir.dirName() << " - " << dir.path();
227 dirMap->insert(dir.path(),dir.dirName());
230 else // its a File
232 // insert into List
233 if( !fileInf.fileName().isEmpty() && !fileInf.fileName().endsWith(".talk") && m_talkFiles)
235 qDebug() << "File: " << fileInf.fileName() << " - " << fileInf.path();
236 fileMap->insert(fileInf.path(),fileInf.fileName());
239 QCoreApplication::processEvents();
241 return true;
244 //! \brief Voices a List of string to the temp dir. Progress is handled inside.
246 //! \param toSpeak QStringList with the Entries to voice.
247 //! \param errString pointer to where the Error cause is written
248 //! \returns true on success, false on error or user abort
249 TTSStatus TalkFileCreator::voiceList(QStringList toSpeak,QStringList& voicedEntries)
251 resetProgress(toSpeak.size());
252 QStringList errors;
254 bool warnings = false;
255 for(int i=0; i < toSpeak.size(); i++)
257 if(m_abort)
259 m_logger->addItem(tr("Talk file creation aborted"), LOGERROR);
260 return FatalError;
263 QString filename = QDir::tempPath()+ "/"+ toSpeak[i] + ".wav";
265 QString error;
266 TTSStatus status = m_tts->voice(toSpeak[i],filename, &error);
267 if(status == Warning)
269 warnings = true;
270 m_logger->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak[i]).arg(error),
271 LOGWARNING);
273 else if (status == FatalError)
275 m_logger->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak[i]).arg(error),
276 LOGERROR);
277 return FatalError;
279 else
280 voicedEntries.append(toSpeak[i]);
281 m_logger->setProgressValue(++m_progress);
282 QCoreApplication::processEvents();
284 if(warnings)
285 return Warning;
286 else
287 return NoError;
291 //! \brief Encodes a List of strings from/to the temp dir. Progress is handled inside.
292 //! It expects the inputfile in the temp dir with the name in the List appended with ".wav"
294 //! \param toSpeak QStringList with the Entries to encode.
295 //! \param errString pointer to where the Error cause is written
296 //! \returns true on success, false on error or user abort
297 bool TalkFileCreator::encodeList(QStringList toEncode,QStringList& encodedEntries)
299 resetProgress(toEncode.size());
300 for(int i=0; i < toEncode.size(); i++)
302 if(m_abort)
304 m_logger->addItem(tr("Talk file creation aborted"), LOGERROR);
305 return false;
308 QString wavfilename = QDir::tempPath()+ "/"+ toEncode[i] + ".wav";
309 QString filename = QDir::tempPath()+ "/"+ toEncode[i] + ".talk";
311 if(!m_enc->encode(wavfilename,filename))
313 m_logger->addItem(tr("Encoding of %1 failed").arg(filename), LOGERROR);
314 return false;
316 encodedEntries.append(toEncode[i]);
317 m_logger->setProgressValue(++m_progress);
318 QCoreApplication::processEvents();
320 return true;
323 //! \brief copys Talkfile for Dirs from the temp dir to the target. Progress and installlog is handled inside
325 //! \param dirMap a MultiMap of Paths -> Dirnames
326 //! \param errString Pointer to a QString where the error cause is written.
327 //! \returns true on success, false on error or user abort
328 bool TalkFileCreator::copyTalkDirFiles(QMultiMap<QString,QString> dirMap,QString* errString)
330 resetProgress(dirMap.size());
332 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
333 installlog.beginGroup("talkfiles");
335 QMapIterator<QString, QString> it(dirMap);
336 while (it.hasNext())
338 it.next();
339 if(m_abort)
341 *errString = tr("Talk file creation aborted");
342 return false;
345 QString source = QDir::tempPath()+ "/"+ it.value() + ".talk";
347 if(!QFileInfo(source).exists())
348 continue; // this file was skipped in one of the previous steps
350 QString target = it.key() + "/" + "_dirname.talk";
352 // remove target if it exists, and if we should overwrite it
353 if(m_overwriteTalk && QFile::exists(target))
354 QFile::remove(target);
356 // copying
357 if(!QFile::copy(source,target))
359 *errString = tr("Copying of %1 to %2 failed").arg(source).arg(target);
360 return false;
363 // add to installlog
364 QString now = QDate::currentDate().toString("yyyyMMdd");
365 installlog.setValue(target.remove(0,m_mountpoint.length()),now);
367 m_logger->setProgressValue(++m_progress);
368 QCoreApplication::processEvents();
370 installlog.endGroup();
371 installlog.sync();
372 return true;
375 //! \brief copys Talkfile for Files from the temp dir to the target. Progress and installlog is handled inside
377 //! \param fileMap a MultiMap of Paths -> Filenames
378 //! \param errString Pointer to a QString where the error cause is written.
379 //! \returns true on success, false on error or user abort
380 bool TalkFileCreator::copyTalkFileFiles(QMultiMap<QString,QString> fileMap,QString* errString)
382 resetProgress(fileMap.size());
384 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
385 installlog.beginGroup("talkfiles");
387 QMapIterator<QString, QString> it(fileMap);
388 while (it.hasNext())
390 it.next();
391 if(m_abort)
393 *errString = tr("Talk file creation aborted");
394 return false;
397 QString source;
398 QString target = it.key() + "/" + it.value() + ".talk";
400 // correct source if we hav stripExtension enabled
401 if(m_stripExtensions)
402 source = QDir::tempPath()+ "/"+ stripExtension(it.value()) + ".talk";
403 else
404 source = QDir::tempPath()+ "/"+ it.value() + ".talk";
406 if(!QFileInfo(source).exists())
407 continue; // this file was skipped in one of the previous steps
409 // remove target if it exists, and if we should overwrite it
410 if(m_overwriteTalk && QFile::exists(target))
411 QFile::remove(target);
413 // copy file
414 qDebug() << "copying: " << source << " to " << target;
415 if(!QFile::copy(source,target))
417 *errString = tr("Copying of %1 to %2 failed").arg(source).arg(target);
418 return false;
421 // add to Install log
422 QString now = QDate::currentDate().toString("yyyyMMdd");
423 installlog.setValue(target.remove(0,m_mountpoint.length()),now);
425 m_logger->setProgressValue(++m_progress);
426 QCoreApplication::processEvents();
428 installlog.endGroup();
429 installlog.sync();
430 return true;
434 //! \brief Cleans up Files potentially left in the temp dir
435 //!
436 //! \param list List of file to try to delete in the temp dir. Function appends ".wav" and ".talk" to the filenames
437 bool TalkFileCreator::cleanup(QStringList list)
439 m_logger->addItem(tr("Cleaning up.."),LOGINFO);
441 for(int i=0; i < list.size(); i++)
443 if(QFile::exists(QDir::tempPath()+ "/"+ list[i] + ".wav"))
444 QFile::remove(QDir::tempPath()+ "/"+ list[i] + ".wav");
445 if(QFile::exists(QDir::tempPath()+ "/"+ list[i] + ".talk"))
446 QFile::remove(QDir::tempPath()+ "/"+ list[i] + ".talk");
448 QCoreApplication::processEvents();
450 return true;
453 //! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position
455 void TalkFileCreator::abort()
457 m_abort = true;