summaryrefslogtreecommitdiff
path: root/src/dictionary/Card.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dictionary/Card.cpp')
-rw-r--r--src/dictionary/Card.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/dictionary/Card.cpp b/src/dictionary/Card.cpp
new file mode 100644
index 0000000..6464941
--- /dev/null
+++ b/src/dictionary/Card.cpp
@@ -0,0 +1,125 @@
+#include <QtDebug>
+
+#include "Card.h"
+#include "ICardPack.h"
+#include "DicRecord.h"
+#include "Field.h"
+
+bool Card::operator==( const Card& another ) const
+ {
+ return question == another.getQuestion();
+ }
+
+/** Card name is its question.
+ Image tags are replaced with image names.
+ */
+QString Card::getName() const
+ {
+ QString nameStr = question;
+ QRegExp imageNameRx("<img\\s*src=\"(.+[/\\\\])?(.+)\".*>");
+ nameStr.replace( imageNameRx, "\\2");
+ return nameStr;
+ }
+
+QStringList Card::getAnswers()
+ {
+ generateAnswers();
+ return answers;
+ }
+
+QList<const DicRecord*> Card::getSourceRecords()
+ {
+ if( sourceRecords.isEmpty() )
+ generateAnswers();
+ return sourceRecords;
+ }
+
+QMultiHash<QString, QString> Card::getAnswerElements()
+{
+ QMultiHash<QString, QString> answerElements; // Key: field name
+ QString qstFieldName = cardPack->getQuestionFieldName();
+ foreach(DicRecord* record, cardPack->getRecords())
+ if(record->getFieldElements(qstFieldName).contains(question) &&
+ record->isValid(qstFieldName))
+ {
+ sourceRecords << record;
+ connect(record, SIGNAL(valueChanged(QString)), SLOT(dropAnswers()));
+ foreach(QString ansFieldName, cardPack->getAnswerFieldNames())
+ {
+ if(record->getFieldValue(ansFieldName).isEmpty())
+ continue;
+ foreach(QString ansElement, record->getFieldElements(ansFieldName))
+ if(!answerElements.contains(ansFieldName, ansElement))
+ answerElements.insert(ansFieldName, ansElement);
+ }
+ }
+ return answerElements;
+}
+
+void Card::generateAnswersFromElements(
+ const QMultiHash<QString, QString>& answerElements)
+{
+ foreach(const Field* ansField, cardPack->getAnswerFields())
+ {
+ if(!ansField)
+ {
+ answers << "";
+ continue;
+ }
+ QStringList elements = getAnswerElementsForField(answerElements, ansField->name());
+ if(elements.isEmpty())
+ {
+ answers << "";
+ continue;
+ }
+ answers << elements.join(ICardPack::HomonymDelimiter);
+ }
+}
+
+QStringList Card::getAnswerElementsForField(const QMultiHash<QString, QString>& answerElements,
+ const QString& fieldName) const
+{
+ QStringList elements = answerElements.values(fieldName); // reversed order
+ QStringList elementsInOrder;
+ elementsInOrder.reserve(elements.size());
+ std::reverse_copy( elements.begin(), elements.end(),
+ std::back_inserter(elementsInOrder) );
+ return elementsInOrder;
+}
+
+// Fills also list of source entries
+void Card::generateAnswers()
+ {
+ if(!cardPack)
+ return;
+ clearAnswers();
+ generateAnswersFromElements(getAnswerElements());
+ }
+
+void Card::clearAnswers()
+{
+ answers.clear();
+ foreach(const DicRecord* record, sourceRecords)
+ disconnect( record, 0, this, SLOT(dropAnswers()) );
+ sourceRecords.clear();
+}
+
+void Card::dropAnswers()
+ {
+ clearAnswers();
+ emit answersChanged();
+ }
+
+StudyRecord Card::getStudyRecord() const
+ {
+ return cardPack->getStudyRecord(getQuestion());
+ }
+
+///< Reviewed at least twice
+bool Card::isScheduledAndReviewed() const
+ {
+ if(!cardPack)
+ return false;
+ int reviews = cardPack->getStudyRecords(getQuestion()).size();
+ return reviews >= 2;
+ }