#ifndef CARDPACK_H #define CARDPACK_H #include #include #include "ICardPack.h" #include "../study/StudyRecord.h" #include "IDictionary.h" #include "Field.h" #include "TreeItem.h" class DicRecord; class Card; /** @brief Pack of cards A card pack consists of cards of certain card pattern. A card pattern is a combination of fields: question field and answer fields. */ class CardPack: public TreeItem, public ICardPack { Q_OBJECT public: static const QString SynonymDelimiter; static const QString HomonymDelimiter; public: CardPack(IDictionary* dict); CardPack(IDictionary* dict, const CardPack* otherPack); ~CardPack(); // Getters QString id() const; QString name() const { return m_name; } // See also id() QString curCardName() const { return m_curCardName; } IDictionary* dictionary() const { return m_dictionary; } QList getRecords() const; // Tree view const TreeItem* parent() const; const TreeItem* child( int /*aRow*/ ) const { return NULL; } int childCount() const { return 0; } int columnCount() const { return 3; } QVariant data( int aColumn ) const; int row() const; int topParentRow() const; // Fields QList getFields() const { return fields; } const Field* getQuestionField() const; QList getAnswerFields() const; bool getUsesExactAnswer() const { return usesExactAnswer; } // Cards QStringList getCardQuestions() const { return cardQuestions; } bool containsQuestion(const QString& question) const { return cardQuestions.contains(question); } int cardsNum() const { return cardQuestions.size(); } Card* getCard(const QString& cardName); // Study records QList getStudyRecords() const { return studyRecords.values(); } QList getScheduledDates() const; QList getStudyRecords(QString cardId) const { return studyRecords.values(cardId); } int studyRecordsNum() const { return studyRecords.uniqueKeys().size(); } bool containsReviewedCards() const; StudyRecord getStudyRecord(QString cardId) const; QString findLastReviewedCard() const; // Study statistics QStringList getNewCards() const; QStringList getActiveCards() const; int getActiveRepeatingCardsNum() const; int countScheduledForTodayCards() const; QStringList getPriorityActiveCards() const; QStringList getLearningCards() const; int getLearningReviewsNum() const; int getTimeToNextLearning() const; int getInactiveLearningReviewsNum() const; QStringList getSmallestIntervalCards(const QStringList& priorityCards); int getTodayReviewedCardsNum() const; int getTodayNewCardsNum() const; public: // Setters void setName( QString aName ) { m_name = aName; } void setCurCard( const QString aCardId ); // Fields void setFields( QList aFields ) { fields = aFields; } void setField( int aPos, const Field* aField ); void addField( const Field* aField ) { fields << aField; } void removeField( int aPos ) { fields.removeAt(aPos); } void removeField( const Field* aField ) { fields.removeAll( aField ); } void insertField( int aPos, const Field* aField ) { fields.insert( aPos, aField ); } void setQstField( const Field* aField ); void setAnsFields( QList aFields ); void setUsesExactAnswer(bool uses) { usesExactAnswer = uses; } void setReadingStudyFile(bool reading) { isReadingStudyFile = reading; } void addStudyRecord( const QString aCardId, const StudyRecord& aStudyRecord ); public: void generateQuestions(); void disableDictRecordUpdates(); void enableDictRecordUpdates(); private: void destroyCards(); void addQuestionElementsForRecord(const DicRecord* record); void removeAbsentCards(QStringList& cardQuestions); void removeDelayedCard(const QString& cardName); signals: void studyRecordAdded(); void cardsGenerated(); private slots: void processEntryChangedEvent( int aEntryIx, int aFieldIx = IDictionary::AllFields ); private: static const int MinRequiredFieldsNum = 2; private: QString m_name; // Not used IDictionary* m_dictionary; // The first field is the question, others are answers. QList fields; QStringList cardQuestions; ///< Original order of questions QHash cards; ///< Card name -> card (own) QString m_curCardName; QMultiHash studyRecords; // Card ID -> Study record bool isReadingStudyFile; bool usesExactAnswer; }; #endif