File indexing completed on 2024-04-21 03:42:04

0001 /*
0002     SPDX-FileCopyrightText: KDE Tuberling <e.bischoff@noos.fr>
0003     SPDX-FileCopyrightText: 2001 Eric Bischoff
0004     SPDX-FileCopyrightText: 2004-2007 Anne-Marie Mahfouf <annma@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "soundfactory.h"
0010 
0011 #include <KRandom>
0012 #include <QStandardPaths>
0013 
0014 #include <KLocalizedString>
0015 #include <KMessageBox>
0016 #include <phonon/MediaObject>
0017 
0018 #include "klettres_debug.h"
0019 #include "klettres.h"
0020 #include "prefs.h"
0021 
0022 SoundFactory::SoundFactory(KLettres *parent, const QString &name)
0023         : QObject(parent), m_player(nullptr)
0024 {
0025     setObjectName(name);
0026     klettres = parent;
0027 
0028     namesList.clear();
0029     filesList.clear();
0030     sounds = 0;
0031 
0032     bool ok = klettres->loadLayout(m_layoutsDocument);
0033     if (ok)  {
0034         change(Prefs::language());
0035     }
0036     if (!ok)  {
0037         loadFailure();
0038     }  else  {
0039         setSoundSequence();
0040     }
0041 }
0042 
0043 SoundFactory::~SoundFactory()
0044 {
0045 }
0046 
0047 void SoundFactory::change(const QString &currentLanguage)
0048 {
0049     //go load the sounds for the current language
0050     bool ok = loadLanguage(m_layoutsDocument, currentLanguage);
0051     //tell the user if there are no sounds or get the random sounds
0052     if (!ok)  {
0053         loadFailure();
0054     }  else  {
0055         setSoundSequence();
0056     }
0057 }
0058 
0059 void SoundFactory::playSound(int mySound)
0060 {
0061     QString soundFile;
0062 
0063     if ((uint) mySound >= sounds) {
0064         return;
0065     }
0066 
0067     soundFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
0068                        QStringLiteral("klettres/") + filesList[mySound]);
0069     qCDebug(KLETTRES_LOG) << "soundFile " << soundFile;
0070 
0071     if (soundFile.isEmpty()) {
0072         return;
0073     }
0074 
0075     if (!m_player)  {
0076         m_player = Phonon::createPlayer(Phonon::GameCategory, QUrl::fromLocalFile(soundFile));
0077         m_player->setParent(this);
0078     }  else  {
0079         m_player->setCurrentSource(QUrl::fromLocalFile(soundFile));
0080     }
0081     m_player->play();
0082 }
0083 
0084 void SoundFactory::loadFailure()
0085 {
0086     KMessageBox::error(klettres, i18n("Error while loading the sound names."));
0087     klettres->slotChangeLevel(Prefs::level()-1);
0088     bool ok = loadLanguage(m_layoutsDocument, Prefs::language());
0089     if (ok)  {
0090         change(Prefs::language());
0091     }
0092 }
0093 
0094 bool SoundFactory::loadLanguage(QDomDocument &layoutDocument, const QString &currentLanguage)
0095 {
0096     QDomNodeList languagesList,
0097     alphabetList,
0098     syllablesList,
0099     soundNamesList;
0100     QDomElement languageElement,
0101     alphabetElement,
0102     syllableElement,
0103     soundNameElement;
0104     QDomAttr nameAttribute, fileAttribute;
0105 
0106     languagesList = layoutDocument.elementsByTagName(QStringLiteral("language"));
0107     QDomAttr codeAttribute;
0108     //check if the sound files match current language
0109     languageElement = (const QDomElement &) languagesList.item(0).toElement();
0110     codeAttribute = languageElement.attributeNode(QStringLiteral("code"));
0111 
0112     if (currentLanguage != codeAttribute.value()) {
0113         qCDebug(KLETTRES_LOG) << "Fail reading language !!! ";
0114         return false;
0115     } else {
0116         qCDebug(KLETTRES_LOG) << "current language " << currentLanguage;
0117     }
0118     //check here if alphabet and syllables both exist
0119     alphabetList = languageElement.elementsByTagName(QStringLiteral("alphabet"));
0120     syllablesList = languageElement.elementsByTagName(QStringLiteral("syllables"));
0121 
0122     //load the sounds for level 1 and 2 (alphabet)
0123     if ((Prefs::level() == 1) || (Prefs::level() == 2))  {
0124         if (alphabetList.count() != 1) {
0125             return false;
0126         }
0127         alphabetElement = (const QDomElement &) alphabetList.item(0).toElement();
0128         soundNamesList = alphabetElement.elementsByTagName(QStringLiteral("sound"));
0129     }
0130 
0131     //load the sounds for level 3 and 4 (syllables)
0132     if ((Prefs::level() == 3) || (Prefs::level() == 4))  {
0133         if (syllablesList.count() != 1) {
0134             Prefs::setLevel(1);
0135             Prefs::self()->save();
0136             return false;
0137         }
0138 
0139         syllableElement = (const QDomElement &) syllablesList.item(0).toElement();
0140 
0141         soundNamesList = syllableElement.elementsByTagName(QStringLiteral("sound"));
0142     }
0143     //Counts the number of sounds
0144     sounds = soundNamesList.count();
0145     qCDebug(KLETTRES_LOG) << "number of sounds" << sounds;
0146     if (sounds < 1)  {
0147         return false;
0148     }
0149     namesList.clear();
0150     filesList.clear();
0151 
0152     for (uint sound = 0; sound < sounds; sound++)  {
0153         soundNameElement = (const QDomElement &) soundNamesList.item(sound).toElement();
0154         nameAttribute = soundNameElement.attributeNode(QStringLiteral("name"));
0155         //namesList helds the names of the letter or syllable to display
0156         namesList.append(nameAttribute.value());
0157         fileAttribute = soundNameElement.attributeNode(QStringLiteral("file"));
0158         //filesList helds the names of the sound files (i.e the location of the sounds like fr/alpha/a-0.mp3)
0159         filesList.append(fileAttribute.value());
0160     }
0161     if (namesList.isEmpty()) {
0162         return false;
0163     }
0164     if (filesList.isEmpty())  {
0165         return false;
0166     }
0167     return true;
0168 }
0169 
0170 void SoundFactory::setSoundSequence()
0171 {
0172     // Seed the random number generator
0173     randomList.clear();
0174     //get the number of sounds then shuffle it: each number will be taken once then the sequence will come back
0175     for (uint j = 0; j < sounds; j++) 
0176         randomList.append(j);
0177 
0178     KRandom::shuffle(randomList);
0179 }
0180 
0181 #include "moc_soundfactory.cpp"