BuildmLearn Toolkit  2.0.4
BuildmLearn Toolkit is an easy-to-use program that helps users make mobile apps without any knowledge of application development.
 All Classes Functions Enumerations Groups Pages
learnspellingssimulator.cpp
1 /*
2  Copyright (c) 2012, BuildmLearn Contributors listed at http://buildmlearn.org/people/
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are met:
7 
8  * Redistributions of source code must retain the above copyright notice, this
9  list of conditions and the following disclaimer.
10 
11  * Redistributions in binary form must reproduce the above copyright notice,
12  this list of conditions and the following disclaimer in the documentation
13  and/or other materials provided with the distribution.
14 
15  * Neither the name of the BuildmLearn nor the names of its
16  contributors may be used to endorse or promote products derived from
17  this software without specific prior written permission.
18 
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 
31 #include "templates/learnspellings/learnspellingssimulator.h"
32 
33 #include "definitions/definitions.h"
34 #include "core/templatecore.h"
35 #include "core/templatefactory.h"
36 #include "gui/custommessagebox.h"
37 #include "network-web/networkfactory.h"
38 #include "miscellaneous/iofactory.h"
39 #include "miscellaneous/application.h"
40 #include "templates/learnspellings/learnspellingseditor.h"
41 
42 #include <QInputDialog>
43 #include <QFile>
44 #include <QTextStream>
45 #include <QDataStream>
46 #include <QDir>
47 #include <QDateTime>
48 
49 
50 LearnSpellingsSimulator::LearnSpellingsSimulator(TemplateCore *core, QWidget *parent)
51  : TemplateSimulator(core, parent), m_ui(new Ui::LearnSpellingsSimulator), m_words(QList<LearnSpellingsItem>()), m_activeWord(-1) {
52  m_ui->setupUi(this);
53 
54  QFont caption_font = m_ui->m_lblQuestionNumber->font();
55  caption_font.setPointSize(caption_font.pointSize() + SIMULATOR_HEADER_SIZE_INCREASE);
56  m_ui->m_lblQuestionNumber->setFont(caption_font);
57 
58  caption_font = m_ui->m_lblHeading->font();
59  caption_font.setPointSize(caption_font.pointSize() + SIMULATOR_HEADING_SIZE_INCREASE);
60  m_ui->m_lblHeading->setFont(caption_font);
61 
62  connect(m_ui->m_btnPlayWord, SIGNAL(clicked()), this, SLOT(playWord()));
63  connect(m_ui->m_btnStart, SIGNAL(clicked()), this, SLOT(start()));
64  connect(m_ui->m_btnRestart, SIGNAL(clicked()), this, SLOT(restart()));
65  connect(m_ui->m_btnExit, SIGNAL(clicked()), this, SLOT(exit()));
66  connect(m_ui->m_btnSkip, SIGNAL(clicked()), this, SLOT(skipThisWord()));
67  connect(m_ui->m_btnSpellIt, SIGNAL(clicked()), this, SLOT(spellThisWord()));
68  connect(m_ui->m_btnGoToNextWord, SIGNAL(clicked()), this, SLOT(loadNextWord()));
69 }
70 
71 LearnSpellingsSimulator::~LearnSpellingsSimulator() {
72  delete m_ui;
73 }
74 
75 bool LearnSpellingsSimulator::startSimulation() {
76  LearnSpellingsEditor *editor = static_cast<LearnSpellingsEditor*>(core()->editor());
77 
78  if (!editor->canGenerateApplications()) {
79  // There are no active questions or quiz does not
80  // containt its name or author name.
81  return false;
82  }
83 
84  // Load the questions, setup the quiz and start it.
85  m_words = editor->activeWords();
86 
87  if (m_words.isEmpty()) {
88  return false;
89  }
90 
91  m_ui->m_btnStart->setEnabled(true);
92  m_ui->m_lblAuthor->setText(editor->m_ui->m_txtAuthor->lineEdit()->text());
93  m_ui->m_lblHeading->setText(editor->m_ui->m_txtName->lineEdit()->text());
94  m_ui->m_phoneWidget->setCurrentIndex(1);
95 
96  return true;
97 }
98 
99 bool LearnSpellingsSimulator::stopSimulation() {
100  m_ui->m_phoneWidget->setCurrentIndex(0);
101 
102  emit canGoBackChanged(false);
103 
104  return true;
105 }
106 
107 bool LearnSpellingsSimulator::goBack() {
108  return false;
109 }
110 
111 void LearnSpellingsSimulator::start() {
112  m_activeWord = -1;
113  m_resultCorrect = m_resultIncorrect = m_resultSkipped = 0;
114  loadNextWord();
115 }
116 
117 void LearnSpellingsSimulator::restart() {
118  m_ui->m_phoneWidget->setCurrentIndex(1);
119 }
120 
121 void LearnSpellingsSimulator::exit() {
122  stopSimulation();
124 }
125 
126 void LearnSpellingsSimulator::playWord() {
127 #if defined(Q_OS_OS2)
129  qApp->trayIcon()->showMessage(tr("Cannot play sound"), tr("Sound cannot play on this platform."),
130  QSystemTrayIcon::Warning);
131  }
132  else {
133  CustomMessageBox::show(this, QMessageBox::Warning, tr("Cannot play sound"), tr("Sound cannot play on this platform."));
134  }
135 #else
136  // Play sound.
137  QByteArray output;
138 
139  LearnSpellingsItem current_item = m_words.at(m_activeWord);
140 
141  if (current_item.audioFilePath().isEmpty() || !QFile::exists(current_item.audioFilePath())) {
142  // Current word does not contain downloaded audio file.
143  QString word = m_words.at(m_activeWord).word().replace(' ', '+');
144  //QString word = QUrl::toPercentEncoding(m_words.at(m_activeWord).word());
145  QString url = QString(TTS_SERVICE_URL).arg(word);
146  QNetworkReply::NetworkError result_of_download = NetworkFactory::downloadFile(url, 10000, output);
147 
148  if (result_of_download != QNetworkReply::NoError) {
149  // There was apparently some error.
151  qApp->trayIcon()->showMessage(tr("Cannot play sound"), tr("Sound cannot play on this platform because sound file was not downloaded."),
152  QSystemTrayIcon::Warning);
153  }
154  else {
155  CustomMessageBox::show(this, QMessageBox::Warning, tr("Cannot play sound"), tr("Sound cannot play on this platform because sound file was not downloaded."));
156  }
157 
158  return;
159  }
160 
161  // Store downloaded sound file.
162  QString sound_file_name = qApp->templateManager()->tempDirectory() + QDir::separator() +
163  "sound_" + QDateTime::currentDateTime().toString("yyyy-MM-dd-hhmmss") + ".wav";
164  QFile sound_file(sound_file_name);
165  sound_file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Unbuffered);
166  sound_file.write(output);
167  sound_file.close();
168 
169  // We obtained new sound file for this particular word.
170  // So, store the path.
171  // NOTE: Note that this is forgotten when new simulation is started.
172  m_words[m_activeWord].setAudioFilePath(sound_file_name);
173  }
174 
175  IOFactory::playWaveFile(m_words.at(m_activeWord).audioFilePath());
176 #endif
177 
178  m_ui->m_btnSkip->setEnabled(true);
179  m_ui->m_btnSpellIt->setEnabled(true);
180 }
181 
182 void LearnSpellingsSimulator::skipThisWord() {
183  m_resultSkipped++;
184  loadNextWord();
185 }
186 
187 void LearnSpellingsSimulator::spellThisWord() {
188  // TODO: display input box for spell word, if answer is correct
189  // then increment.
190  // then display "word result page"
191  QString guessed_word = QInputDialog::getText(this, tr("Enter spelling"), tr("Enter spelling")).simplified();
192  LearnSpellingsItem current_word = m_words.at(m_activeWord);
193 
194  if (!guessed_word.isEmpty()) {
195  if (QString::compare(guessed_word, current_word.word(), Qt::CaseInsensitive) == 0) {
196  // User guessed the word!!!
197  m_resultCorrect++;
198  m_ui->m_lblResultCaption->setText(tr("This is correct spelling"));
199  }
200  else {
201  // User made a mistake.
202  m_resultIncorrect++;
203  m_ui->m_lblResultCaption->setText(tr("This is not the correct spelling"));
204  }
205 
206  // Display page with overview of current word status.
207  m_ui->m_lblEnteredWord->setText(tr("You entered %1").arg(guessed_word));
208  m_ui->m_lblCorrectWordDescription->setText(tr("<p style=\" font-size: 18pt;\">%1</p><p>%2</p>").arg(current_word.word(), current_word.meaning()));
209  m_ui->m_listener->setCurrentIndex(1);
210  }
211  else {
212  CustomMessageBox::show(this, QMessageBox::Warning, tr("Enter some word"), tr("You must enter some word"));
213  }
214 }
215 
216 void LearnSpellingsSimulator::loadNextWord() {
217  m_activeWord++;
218  m_ui->m_lblQuestionNumber->setText(tr("Word #%1 of %2").arg(QString::number(m_activeWord + 1),
219  QString::number(m_words.size())));
220 
221  if (m_activeWord < m_words.size()) {
222  // We are not viewing last word, display the "listening" page.
223  m_ui->m_btnSkip->setEnabled(false);
224  m_ui->m_btnSpellIt->setEnabled(false);
225  m_ui->m_listener->setCurrentIndex(0);
226  m_ui->m_phoneWidget->setCurrentIndex(2);
227  }
228  else {
229  // We are already viewing last word, we need to go to "summary" page and display results.
230  m_ui->m_lblTotalCorrect->setText(tr("Correct spelled %1").arg(QString::number(m_resultCorrect)));
231  m_ui->m_lblTotalUnanswered->setText(tr("Unanswered %1").arg(QString::number(m_resultSkipped)));
232  m_ui->m_lblTotalWrong->setText(tr("Wrond spelled %1").arg(QString::number(m_resultIncorrect)));
233  m_ui->m_phoneWidget->setCurrentIndex(3);
234  }
235 }
virtual TemplateEditor * editor() const
Access to editor widget of the template.
Definition: templatecore.h:84
Editor widget of Learn Spellings template.
void canGoBackChanged(bool can_go_back)
Emitted if "can go back" status of simulator changes.
bool canGenerateApplications()
Specifies if template can generate applications or not.
Simulator widget for Learn Spellings template.
static void playWaveFile(const QString &file_path)
Plays selected file with default audio output.
Definition: iofactory.cpp:52
TemplateCore * core() const
Access to associated template core.
static bool isSystemTrayAvailable()
Indicates whether tray icon is supported.
static QMessageBox::StandardButton show(QWidget *parent, QMessageBox::Icon icon, const QString &title, const QString &text, const QString &informative_text=QString(), const QString &detailed_text=QString(), QMessageBox::StandardButtons buttons=QMessageBox::Ok, QMessageBox::StandardButton default_button=QMessageBox::Ok)
Displays custom message box.
static QNetworkReply::NetworkError downloadFile(const QString &url, int timeout, QByteArray &output, bool protected_contents=false, const QString &username=QString(), const QString &password=QString())
Performs SYNCHRONOUS download of file with given URL and given timeout.
void simulationStopRequested()
Emitted if simulation is stopped from template itself.
The core class container for single template.
Definition: templatecore.h:43
Class which represents single word for Learn Spellings template.
Base widget which represents simulator of the template.