(Maybe the first) correction of the order the album art images are searched. Also...
[maemo-rb.git] / rbutil / rbutilqt / talkfile.cpp
blob815c2824fbc5df0f5bf7a478ddaae493b432ce3e
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"
21 #include "rbsettings.h"
23 TalkFileCreator::TalkFileCreator(QObject* parent): QObject(parent)
28 //! \brief Creates Talkfiles.
29 //!
30 //! \param logger A pointer to a Loggerobject
31 bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger)
33 m_abort = false;
34 m_logger = logger;
36 QMultiMap<QString,QString> fileList;
37 QMultiMap<QString,QString> dirList;
38 QStringList toSpeakList, voicedEntries, encodedEntries;
39 QString errStr;
41 m_logger->addItem(tr("Starting Talk file generation"),LOGINFO);
43 //tts
44 m_tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString());
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->setFinished();
51 return false;
54 // Encoder
55 m_enc = EncBase::getEncoder(this,RbSettings::value(RbSettings::CurEncoder).toString());
57 if(!m_enc->start())
59 m_logger->addItem(tr("Init of Encoder engine failed"),LOGERROR);
60 m_logger->setFinished();
61 m_tts->stop();
62 return false;
65 QCoreApplication::processEvents();
67 connect(logger,SIGNAL(aborted()),this,SLOT(abort()));
68 m_logger->setProgressMax(0);
70 // read in Maps of paths - file/dirnames
71 m_logger->addItem(tr("Reading Filelist..."),LOGINFO);
72 if(createDirAndFileMaps(m_dir,&dirList,&fileList) == false)
74 m_logger->addItem(tr("Talk file creation aborted"),LOGERROR);
75 doAbort(toSpeakList);
76 return false;
79 // create List of all Files/Dirs to speak
80 QMapIterator<QString, QString> dirIt(dirList);
81 while (dirIt.hasNext())
83 dirIt.next();
84 // insert only non dublicate dir entries into list
85 if(!toSpeakList.contains(dirIt.value()))
87 qDebug() << "toSpeaklist dir:" << dirIt.value();
88 toSpeakList.append(dirIt.value());
91 QMapIterator<QString, QString> fileIt(fileList);
92 while (fileIt.hasNext())
94 fileIt.next();
95 // insert only non- dublictae file entries into list
96 if(!toSpeakList.contains(fileIt.value()))
98 if(m_stripExtensions)
99 toSpeakList.append(stripExtension(fileIt.value()));
100 else
101 toSpeakList.append(fileIt.value());
105 // Voice entries
106 m_logger->addItem(tr("Voicing entries..."),LOGINFO);
107 TTSStatus voiceStatus= voiceList(toSpeakList,voicedEntries);
108 if(voiceStatus == FatalError)
110 doAbort(toSpeakList);
111 return false;
114 // Encoding Entries
115 m_logger->addItem(tr("Encoding files..."),LOGINFO);
116 if(encodeList(voicedEntries,encodedEntries) == false)
118 doAbort(toSpeakList);
119 return false;
122 // Copying talk files
123 m_logger->addItem(tr("Copying Talkfile for Dirs..."),LOGINFO);
124 if(copyTalkDirFiles(dirList,&errStr) == false)
126 m_logger->addItem(errStr,LOGERROR);
127 doAbort(toSpeakList);
128 return false;
131 //Copying file talk files
132 m_logger->addItem(tr("Copying Talkfile for Files..."),LOGINFO);
133 if(copyTalkFileFiles(fileList,&errStr) == false)
135 m_logger->addItem(errStr,LOGERROR);
136 doAbort(toSpeakList);
137 return false;
140 // Deleting left overs
141 if( !cleanup(toSpeakList))
142 return false;
144 m_tts->stop();
145 m_enc->stop();
146 m_logger->addItem(tr("Finished creating Talk files"),LOGOK);
147 m_logger->setProgressMax(1);
148 m_logger->setProgressValue(1);
149 m_logger->setFinished();
151 return true;
154 //! \brief resets the internal progress counter, and sets the Progressbar in the Logger
156 //! \param max The maximum to shich the Progressbar is set.
157 void TalkFileCreator::resetProgress(int max)
159 m_progress = 0;
160 m_logger->setProgressMax(max);
161 m_logger->setProgressValue(m_progress);
164 //! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed
166 //! \param filename The filename from which to strip the Extension
167 //! \returns the modified string
168 QString TalkFileCreator::stripExtension(QString filename)
170 if(filename.lastIndexOf(".") != -1)
171 return filename.left(filename.lastIndexOf("."));
172 else
173 return filename;
176 //! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder
178 //! \param cleanupList List of filenames to give to cleanup()
179 void TalkFileCreator::doAbort(QStringList cleanupList)
181 cleanup(cleanupList);
182 m_logger->setProgressMax(1);
183 m_logger->setProgressValue(0);
184 m_logger->setFinished();
185 m_tts->stop();
186 m_enc->stop();
189 //! \brief Creates MultiMaps (paths -> File/dir names) of all Dirs and Files in a Folder.
190 //! Depending on settings, either Dirs or Files can be ignored.
191 //! Also recursion is controlled by settings
193 //! \param startDir The dir where it beginns scanning
194 //! \param dirMap The MulitMap where the dirs are stored
195 //! \param filMap The MultiMap where Files are stored
196 //! \returns true on Success, false if User aborted.
197 bool TalkFileCreator::createDirAndFileMaps(QDir startDir,QMultiMap<QString,QString> *dirMap,QMultiMap<QString,QString> *fileMap)
199 // create Iterator
200 QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags;
201 if(m_recursive)
202 flags = QDirIterator::Subdirectories;
204 QDirIterator it(startDir,flags);
206 // read in Maps of paths - file/dirnames
207 while (it.hasNext())
209 it.next();
210 if(m_abort)
212 return false;
215 QFileInfo fileInf = it.fileInfo();
217 // its a dir
218 if(fileInf.isDir())
220 QDir dir = fileInf.dir();
222 // insert into List
223 if(!dir.dirName().isEmpty() && m_talkFolders)
225 qDebug() << "Dir: " << dir.dirName() << " - " << dir.path();
226 dirMap->insert(dir.path(),dir.dirName());
229 else // its a File
231 // insert into List
232 if( !fileInf.fileName().isEmpty() && !fileInf.fileName().endsWith(".talk") && m_talkFiles)
234 qDebug() << "File: " << fileInf.fileName() << " - " << fileInf.path();
235 fileMap->insert(fileInf.path(),fileInf.fileName());
238 QCoreApplication::processEvents();
240 return true;
243 //! \brief Voices a List of string to the temp dir. Progress is handled inside.
245 //! \param toSpeak QStringList with the Entries to voice.
246 //! \param errString pointer to where the Error cause is written
247 //! \returns true on success, false on error or user abort
248 TTSStatus TalkFileCreator::voiceList(QStringList toSpeak,QStringList& voicedEntries)
250 resetProgress(toSpeak.size());
251 QStringList errors;
253 bool warnings = false;
254 for(int i=0; i < toSpeak.size(); i++)
256 if(m_abort)
258 m_logger->addItem(tr("Talk file creation aborted"), LOGERROR);
259 return FatalError;
262 QString filename = QDir::tempPath()+ "/"+ toSpeak[i] + ".wav";
264 QString error;
265 TTSStatus status = m_tts->voice(toSpeak[i],filename, &error);
266 if(status == Warning)
268 warnings = true;
269 m_logger->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak[i]).arg(error),
270 LOGWARNING);
272 else if (status == FatalError)
274 m_logger->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak[i]).arg(error),
275 LOGERROR);
276 return FatalError;
278 else
279 voicedEntries.append(toSpeak[i]);
280 m_logger->setProgressValue(++m_progress);
281 QCoreApplication::processEvents();
283 if(warnings)
284 return Warning;
285 else
286 return NoError;
290 //! \brief Encodes a List of strings from/to the temp dir. Progress is handled inside.
291 //! It expects the inputfile in the temp dir with the name in the List appended with ".wav"
293 //! \param toSpeak QStringList with the Entries to encode.
294 //! \param errString pointer to where the Error cause is written
295 //! \returns true on success, false on error or user abort
296 bool TalkFileCreator::encodeList(QStringList toEncode,QStringList& encodedEntries)
298 resetProgress(toEncode.size());
299 for(int i=0; i < toEncode.size(); i++)
301 if(m_abort)
303 m_logger->addItem(tr("Talk file creation aborted"), LOGERROR);
304 return false;
307 QString wavfilename = QDir::tempPath()+ "/"+ toEncode[i] + ".wav";
308 QString filename = QDir::tempPath()+ "/"+ toEncode[i] + ".talk";
310 if(!m_enc->encode(wavfilename,filename))
312 m_logger->addItem(tr("Encoding of %1 failed").arg(filename), LOGERROR);
313 return false;
315 encodedEntries.append(toEncode[i]);
316 m_logger->setProgressValue(++m_progress);
317 QCoreApplication::processEvents();
319 return true;
322 //! \brief copys Talkfile for Dirs from the temp dir to the target. Progress and installlog is handled inside
324 //! \param dirMap a MultiMap of Paths -> Dirnames
325 //! \param errString Pointer to a QString where the error cause is written.
326 //! \returns true on success, false on error or user abort
327 bool TalkFileCreator::copyTalkDirFiles(QMultiMap<QString,QString> dirMap,QString* errString)
329 resetProgress(dirMap.size());
331 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
332 installlog.beginGroup("talkfiles");
334 QMapIterator<QString, QString> it(dirMap);
335 while (it.hasNext())
337 it.next();
338 if(m_abort)
340 *errString = tr("Talk file creation aborted");
341 return false;
344 QString source = QDir::tempPath()+ "/"+ it.value() + ".talk";
346 if(!QFileInfo(source).exists())
347 continue; // this file was skipped in one of the previous steps
349 QString target = it.key() + "/" + "_dirname.talk";
351 // remove target if it exists, and if we should overwrite it
352 if(m_overwriteTalk && QFile::exists(target))
353 QFile::remove(target);
355 // copying
356 if(!QFile::copy(source,target))
358 *errString = tr("Copying of %1 to %2 failed").arg(source).arg(target);
359 return false;
362 // add to installlog
363 QString now = QDate::currentDate().toString("yyyyMMdd");
364 installlog.setValue(target.remove(0,m_mountpoint.length()),now);
366 m_logger->setProgressValue(++m_progress);
367 QCoreApplication::processEvents();
369 installlog.endGroup();
370 installlog.sync();
371 return true;
374 //! \brief copys Talkfile for Files from the temp dir to the target. Progress and installlog is handled inside
376 //! \param fileMap a MultiMap of Paths -> Filenames
377 //! \param errString Pointer to a QString where the error cause is written.
378 //! \returns true on success, false on error or user abort
379 bool TalkFileCreator::copyTalkFileFiles(QMultiMap<QString,QString> fileMap,QString* errString)
381 resetProgress(fileMap.size());
383 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
384 installlog.beginGroup("talkfiles");
386 QMapIterator<QString, QString> it(fileMap);
387 while (it.hasNext())
389 it.next();
390 if(m_abort)
392 *errString = tr("Talk file creation aborted");
393 return false;
396 QString source;
397 QString target = it.key() + "/" + it.value() + ".talk";
399 // correct source if we hav stripExtension enabled
400 if(m_stripExtensions)
401 source = QDir::tempPath()+ "/"+ stripExtension(it.value()) + ".talk";
402 else
403 source = QDir::tempPath()+ "/"+ it.value() + ".talk";
405 if(!QFileInfo(source).exists())
406 continue; // this file was skipped in one of the previous steps
408 // remove target if it exists, and if we should overwrite it
409 if(m_overwriteTalk && QFile::exists(target))
410 QFile::remove(target);
412 // copy file
413 qDebug() << "copying: " << source << " to " << target;
414 if(!QFile::copy(source,target))
416 *errString = tr("Copying of %1 to %2 failed").arg(source).arg(target);
417 return false;
420 // add to Install log
421 QString now = QDate::currentDate().toString("yyyyMMdd");
422 installlog.setValue(target.remove(0,m_mountpoint.length()),now);
424 m_logger->setProgressValue(++m_progress);
425 QCoreApplication::processEvents();
427 installlog.endGroup();
428 installlog.sync();
429 return true;
433 //! \brief Cleans up Files potentially left in the temp dir
435 //! \param list List of file to try to delete in the temp dir. Function appends ".wav" and ".talk" to the filenames
436 bool TalkFileCreator::cleanup(QStringList list)
438 m_logger->addItem(tr("Cleaning up.."),LOGINFO);
440 for(int i=0; i < list.size(); i++)
442 if(QFile::exists(QDir::tempPath()+ "/"+ list[i] + ".wav"))
443 QFile::remove(QDir::tempPath()+ "/"+ list[i] + ".wav");
444 if(QFile::exists(QDir::tempPath()+ "/"+ list[i] + ".talk"))
445 QFile::remove(QDir::tempPath()+ "/"+ list[i] + ".talk");
447 QCoreApplication::processEvents();
449 return true;
452 //! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position
454 void TalkFileCreator::abort()
456 m_abort = true;