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
learnspellingseditor.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/learnspellingseditor.h"
32 
33 #include "miscellaneous/iconfactory.h"
34 #include "miscellaneous/application.h"
35 #include "core/templatefactory.h"
36 #include "core/templatecore.h"
37 #include "core/templateentrypoint.h"
38 
39 #include <QTimer>
40 
41 
42 LearnSpellingsEditor::LearnSpellingsEditor(TemplateCore *core, QWidget *parent)
43  : TemplateEditor(core, parent), m_ui(new Ui::LearnSpellingsEditor) {
44  m_ui->setupUi(this);
45 
46  // Set validators.
47  QRegExpValidator *author_validator = new QRegExpValidator(this);
48  QRegExpValidator *title_validator = new QRegExpValidator(this);
49 
50  author_validator->setRegExp(QRegExp(".{,50}"));
51  title_validator->setRegExp(QRegExp(".{,100}"));
52 
53  m_ui->m_txtAuthor->lineEdit()->setValidator(author_validator);
54  m_ui->m_txtName->lineEdit()->setValidator(title_validator);
55 
56  // Set tab order.
57  QList<QWidget*> tab_order_widgets;
58  tab_order_widgets << m_ui->m_txtTitle->lineEdit() << m_ui->m_txtDescription->lineEdit() <<
59  m_ui->m_txtAuthor->lineEdit() << m_ui->m_txtName->lineEdit() <<
60  m_ui->m_listItems << m_ui->m_btnItemAdd << m_ui->m_btnItemRemove <<
61  m_ui->m_btnItemUp << m_ui->m_btnItemDown;
62 
63  for (int i = 1; i < tab_order_widgets.size(); i++) {
64  setTabOrder(tab_order_widgets.at(i - 1), tab_order_widgets.at(i));
65  }
66 
67  m_ui->m_txtTitle->lineEdit()->setPlaceholderText(tr("Word to spell"));
68  m_ui->m_txtDescription->lineEdit()->setPlaceholderText(tr("Meaning of the word"));
69  m_ui->m_txtNumberOfItems->lineEdit()->setEnabled(false);
70  m_ui->m_txtAuthor->lineEdit()->setPlaceholderText(tr("Author of this collection"));
71  m_ui->m_txtName->lineEdit()->setPlaceholderText(tr("Name of this collection"));
72 
74 
75  m_ui->m_btnItemAdd->setIcon(factory->fromTheme("item-add"));
76  m_ui->m_btnItemRemove->setIcon(factory->fromTheme("item-remove"));
77  m_ui->m_btnItemUp->setIcon(factory->fromTheme("move-up"));
78  m_ui->m_btnItemDown->setIcon(factory->fromTheme("move-down"));
79 
80  connect(m_ui->m_txtDescription->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(checkDescription(QString)));
81  connect(m_ui->m_txtTitle->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(checkTitle(QString)));
82  connect(m_ui->m_btnItemAdd, SIGNAL(clicked()), this, SLOT(addSampleWord()));
83  connect(m_ui->m_btnItemRemove, SIGNAL(clicked()), this, SLOT(removeSelectedWord()));
84  connect(m_ui->m_txtDescription->lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(saveWord()));
85  connect(m_ui->m_txtTitle->lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(saveWord()));
86  connect(m_ui->m_listItems, SIGNAL(currentRowChanged(int)), this, SLOT(displayWord(int)));
87  connect(m_ui->m_btnItemUp, SIGNAL(clicked()), this, SLOT(moveWordUp()));
88  connect(m_ui->m_btnItemDown, SIGNAL(clicked()), this, SLOT(moveWordDown()));
89  connect(m_ui->m_txtAuthor->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onAuthorChanged(QString)));
90  connect(m_ui->m_txtName->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onNameChanged(QString)));
91 
92  checkDescription(m_ui->m_txtDescription->lineEdit()->text());
93  checkTitle(m_ui->m_txtTitle->lineEdit()->text());
94  checkAuthor();
95  checkName();
96  setEditorsEnabled(false);
97  updateItemCount();
98 }
99 
100 LearnSpellingsEditor::~LearnSpellingsEditor() {
101  delete m_ui;
102 }
103 
105  /*if (!canGenerateApplications()) {
106  return QString();
107  }*/
108 
109  QDomDocument source_document = qApp->templateManager()->generateBundleHeader(core()->entryPoint()->typeIndentifier(),
110  m_ui->m_txtAuthor->lineEdit()->text(),
111  QString(),
112  m_ui->m_txtName->lineEdit()->text(),
113  QString(),
114  "1");
115  FIND_DATA_ELEMENT(data_element, source_document);
116 
117  foreach (const LearnSpellingsItem &item, activeWords()) {
118  QDomElement item_element = source_document.createElement("item");
119 
120  // Fill in details about question.
121  QDomElement word_element = source_document.createElement("word");
122  QDomElement meaning_element = source_document.createElement("meaning");
123 
124  word_element.appendChild(source_document.createTextNode(item.word()));
125  meaning_element.appendChild(source_document.createTextNode(item.meaning()));
126 
127  item_element.appendChild(word_element);
128  item_element.appendChild(meaning_element);
129 
130  data_element.appendChild(item_element);
131  }
132 
133  return source_document.toString(XML_BUNDLE_INDENTATION);
134 }
135 
136 bool LearnSpellingsEditor::loadBundleData(const QString &bundle_data) {
137  QDomDocument bundle_document;
138  bundle_document.setContent(bundle_data);
139 
140  QDomNodeList items = bundle_document.documentElement().elementsByTagName("item");
141 
142  for (int i = 0; i < items.size(); i++) {
143  QDomNode item = items.at(i);
144 
145  if (item.isElement()) {
146  QString word = item.namedItem("word").toElement().text();
147  QString meaning = item.namedItem("meaning").toElement().text();
148 
149  if (word.isEmpty()) {
150  // TODO: error
151  continue;
152  }
153  else {
154  addSampleWord(word, meaning);
155  }
156  }
157  else {
158  continue;
159  }
160  }
161 
162  // Load author & name.
163  m_ui->m_txtAuthor->lineEdit()->setText(bundle_document.documentElement().namedItem("author").namedItem("name").toElement().text());
164  m_ui->m_txtName->lineEdit()->setText(bundle_document.documentElement().namedItem("title").toElement().text());
165 
166  return true;
167 }
168 
169 void LearnSpellingsEditor::addSampleWord(const QString &title, const QString &description) {
170  int marked_item = m_ui->m_listItems->currentRow();
171  LearnSpellingsItem new_item;
172  QListWidgetItem *new_item_view = new QListWidgetItem();
173 
174  new_item.setWord(title);
175  new_item.setMeaning(description);
176 
177  new_item_view->setText(new_item.word());
178  new_item_view->setData(Qt::UserRole, QVariant::fromValue(new_item));
179 
180  if (m_ui->m_listItems->count() == 0) {
181  // We are adding first item.
182  setEditorsEnabled(true);
183 
184  m_ui->m_btnItemRemove->setEnabled(true);
185 
186  m_ui->m_listItems->insertItem(0, new_item_view);
187  m_ui->m_listItems->setCurrentRow(0);
188  }
189  else {
190  m_ui->m_listItems->insertItem(marked_item + 1, new_item_view);
191  m_ui->m_listItems->setCurrentRow(marked_item + 1);
192  }
193 
194  updateItemCount();
195 }
196 
197 void LearnSpellingsEditor::addSampleWord() {
198  addSampleWord(tr("cat"), tr("Cats are animals which are hated by dogs."));
199  launch();
200  emit changed();
201 }
202 
203 void LearnSpellingsEditor::checkAuthor() {
204  if (m_ui->m_txtAuthor->lineEdit()->text().isEmpty()) {
205  m_ui->m_txtAuthor->setStatus(WidgetWithStatus::Error,
206  tr("No author is specified."));
207  }
208  else {
209  m_ui->m_txtAuthor->setStatus(WidgetWithStatus::Ok,
210  tr("Author is specified."));
211  }
212 }
213 
214 void LearnSpellingsEditor::checkName() {
215  if (m_ui->m_txtName->lineEdit()->text().isEmpty()) {
216  m_ui->m_txtName->setStatus(WidgetWithStatus::Error,
217  tr("No collection title is specified."));
218  }
219  else {
220  m_ui->m_txtName->setStatus(WidgetWithStatus::Ok,
221  tr("Collection title is specified."));
222  }
223 }
224 
225 void LearnSpellingsEditor::onAuthorChanged(const QString& new_author) {
226  Q_UNUSED(new_author)
227 
228  checkAuthor();
229 
230  launch();
231  emit changed();
232 }
233 
234 void LearnSpellingsEditor::onNameChanged(const QString& new_name) {
235  Q_UNUSED(new_name)
236 
237  checkName();
238 
239  launch();
240  emit changed();
241 }
242 
243 void LearnSpellingsEditor::configureUpDown() {
244  if (m_ui->m_listItems->count() > 1) {
245  int index = m_ui->m_listItems->currentRow();
246 
247  if (index == 0) {
248  m_ui->m_btnItemUp->setEnabled(false);
249  m_ui->m_btnItemDown->setEnabled(true);
250  }
251  else if (index == m_ui->m_listItems->count() - 1) {
252  m_ui->m_btnItemUp->setEnabled(true);
253  m_ui->m_btnItemDown->setEnabled(false);
254  }
255  else {
256  m_ui->m_btnItemUp->setEnabled(true);
257  m_ui->m_btnItemDown->setEnabled(true);
258  }
259  }
260  else {
261  m_ui->m_btnItemUp->setEnabled(false);
262  m_ui->m_btnItemDown->setEnabled(false);
263  }
264 }
265 
266 QList<LearnSpellingsItem> LearnSpellingsEditor::activeWords() const {
267  QList<LearnSpellingsItem> questions;
268 
269  for (int i = 0; i < m_ui->m_listItems->count(); i++) {
270  questions.append(m_ui->m_listItems->item(i)->data(Qt::UserRole).value<LearnSpellingsItem>());
271  }
272 
273  return questions;
274 }
275 
277  return
278  !activeWords().isEmpty() &&
279  !m_ui->m_txtAuthor->lineEdit()->text().simplified().isEmpty() &&
280  !m_ui->m_txtName->lineEdit()->text().simplified().isEmpty();
281 }
282 
284  return m_ui->m_txtName->lineEdit()->text();
285 }
286 
288  return m_ui->m_txtAuthor->lineEdit()->text();
289 }
290 
291 void LearnSpellingsEditor::updateItemCount() {
292  m_ui->m_txtNumberOfItems->lineEdit()->setText(QString::number(m_ui->m_listItems->count()));
293 
294  if (m_ui->m_listItems->count() > 0) {
295  m_ui->m_txtNumberOfItems->setStatus(WidgetWithStatus::Ok, tr("Collection contains at least one word."));
296  }
297  else {
298  m_ui->m_txtNumberOfItems->setStatus(WidgetWithStatus::Error, tr("Collection does not contain any words."));
299  }
300 }
301 
302 void LearnSpellingsEditor::removeSelectedWord() {
303  int current_row = m_ui->m_listItems->currentRow();
304 
305  if (current_row >= 0) {
306  if (m_ui->m_listItems->count() == 1) {
307  // We are removing last visible question.
308  setEditorsEnabled(false);
309 
310  m_ui->m_btnItemRemove->setEnabled(false);
311  }
312 
313  delete m_ui->m_listItems->takeItem(current_row);
314  }
315 
316  updateItemCount();
317  launch();
318  emit changed();
319 }
320 
321 void LearnSpellingsEditor::saveWord() {
322  m_activeItem.setWord(m_ui->m_txtTitle->lineEdit()->text());
323  m_activeItem.setMeaning(m_ui->m_txtDescription->lineEdit()->text());
324 
325  m_ui->m_listItems->currentItem()->setData(Qt::UserRole, QVariant::fromValue(m_activeItem));
326  m_ui->m_listItems->currentItem()->setText(m_activeItem.word());
327 
328  emit changed();
329 }
330 
331 void LearnSpellingsEditor::displayWord(int index) {
332  if (index >= 0) {
333  LearnSpellingsItem item = m_ui->m_listItems->item(index)->data(Qt::UserRole).value<LearnSpellingsItem>();
334 
335  m_ui->m_txtTitle->lineEdit()->setText(item.word());
336  m_ui->m_txtDescription->lineEdit()->setText(item.meaning());
337  m_activeItem = item;
338  }
339  else {
340  m_ui->m_txtTitle->lineEdit()->clear();
341  m_ui->m_txtDescription->lineEdit()->clear();
342  }
343 
344  QTimer::singleShot(0, this, SLOT(configureUpDown()));
345 }
346 
347 void LearnSpellingsEditor::checkTitle(const QString &title) {
348  if (title.simplified().isEmpty()) {
349  m_ui->m_txtTitle->setStatus(WidgetWithStatus::Error, tr("Please, enter some word."));
350  }
351  else {
352  m_ui->m_txtTitle->setStatus(WidgetWithStatus::Ok, tr("Word seems to be okay."));
353  }
354 }
355 
356 void LearnSpellingsEditor::moveWordUp() {
357  int index = m_ui->m_listItems->currentRow();
358 
359  m_ui->m_listItems->insertItem(index - 1, m_ui->m_listItems->takeItem(index));
360  m_ui->m_listItems->setCurrentRow(index - 1);
361 
362  emit changed();
363 }
364 
365 void LearnSpellingsEditor::moveWordDown() {
366  int index = m_ui->m_listItems->currentRow();
367 
368  m_ui->m_listItems->insertItem(index + 1, m_ui->m_listItems->takeItem(index));
369  m_ui->m_listItems->setCurrentRow(index + 1);
370 
371  emit changed();
372 }
373 
374 void LearnSpellingsEditor::checkDescription(const QString &description) {
375  if (description.simplified().isEmpty()) {
376  m_ui->m_txtDescription->setStatus(WidgetWithStatus::Error, tr("Please, enter some meaning."));
377  }
378  else {
379  m_ui->m_txtDescription->setStatus(WidgetWithStatus::Ok, tr("Meaning seems to be okay."));
380  }
381 }
382 
383 void LearnSpellingsEditor::setEditorsEnabled(bool enabled) {
384  m_ui->m_groupItemEditor->setEnabled(enabled);
385 }
Editor widget of Learn Spellings template.
QString generateBundleData()
Generates RAW data which represent data of this template.
TemplateCore * core() const
Access to associated template core.
void changed()
Emitted everytime any child widget of editor changes its contents.
bool canGenerateApplications()
Specifies if template can generate applications or not.
Represents the editor of the template.
Icon theme manipulator and provider.
Definition: iconfactory.h:47
bool loadBundleData(const QString &bundle_data)
Loads editor state from XML bundle.
QString projectName()
Access to project name of current editor.
The core class container for single template.
Definition: templatecore.h:43
QIcon fromTheme(const QString &name)
Returns icon from active theme.
Definition: iconfactory.h:58
Class which represents single word for Learn Spellings template.
virtual void launch()
Executed when given template with this editor is launched.
static IconFactory * instance()
Singleton getter.
Definition: iconfactory.cpp:48
QString authorName()
Access to author name of current editor.