diff options
Diffstat (limited to 'src/study/CardSideView.cpp')
-rw-r--r-- | src/study/CardSideView.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/study/CardSideView.cpp b/src/study/CardSideView.cpp new file mode 100644 index 0000000..8956210 --- /dev/null +++ b/src/study/CardSideView.cpp @@ -0,0 +1,205 @@ +#include "CardSideView.h" +#include "../field-styles/FieldStyleFactory.h" +#include "../dictionary/CardPack.h" +#include "../dictionary/IDictionary.h" + +#include <QtCore> + +CardSideView::CardSideView( bool aMode ): + m_showMode(aMode), cardPack(NULL) +{ + setFrameStyle( QFrame::Plain | QFrame::Box ); + setAlignment( Qt::AlignCenter ); + setTextFormat( Qt::RichText ); + setWordWrap( true ); + setAutoFillBackground( true ); + setPalette( FieldStyleFactory::inst()->cardBgColor ); + newIcon = new QLabel(this); + newIcon->setPixmap(QPixmap(":/images/new-topright.png")); + updateNewIconPos(); + newIcon->hide(); +} + +void CardSideView::setEnabled( bool aEnabled ) + { + QLabel::setEnabled( aEnabled ); + setBackgroundVisible( aEnabled ); + } + +/** Cleans background and text */ +void CardSideView::setBackgroundVisible( bool aVisible ) + { + if( aVisible ) + QLabel::setEnabled( true ); + setAutoFillBackground( aVisible ); + setLineWidth( aVisible? 1 : 0 ); + if( !aVisible ) + setText(""); + } + +void CardSideView::setPack(const CardPack* pack) + { + cardPack = pack; + } + +void CardSideView::setQstAnsr( const QString aQuestion, const QStringList aAnswers ) + { + m_question = aQuestion; + m_answers = aAnswers; + updateText(); + } + +void CardSideView::setQuestion( const QString aQuestion ) + { + m_question = aQuestion; + updateText(); + } + +void CardSideView::setShowMode( bool aMode ) + { + m_showMode = aMode; + updateText(); + } + +void CardSideView::updateText() +{ + setText(getFormattedText()); +} + +QString CardSideView::getFormattedText() const +{ + if(!cardPack) + return QString(); + if(m_showMode == QstMode) + return getFormattedQuestion(); + else + return getFormattedAnswer(); +} + +QString CardSideView::getFormattedQuestion() const +{ + const Field* qstField = cardPack->getQuestionField(); + if(!qstField) + return QString(); + return formattedField(m_question, qstField->style()); +} + +QString CardSideView::getFormattedAnswer() const +{ + QStringList formattedAnswers; + int i = 0; + foreach(const Field* field, cardPack->getAnswerFields()) + { + QString text = getFormattedAnswerField(field, i); + if(i == 0) + text += "<br/>"; + if(!text.isEmpty()) + formattedAnswers << text; + i++; + } + return formattedAnswers.join("<br/>"); +} + +QString CardSideView::getFormattedAnswerField(const Field* field, int index) const +{ + if(!field) + return QString(); + if(index >= m_answers.size()) + return QString(); + if(m_answers[index].isEmpty()) + return QString(); + return formattedField(m_answers[index], field->style() ); +} + +QString CardSideView::formattedField( const QString aField, const QString aStyle ) const + { + Q_ASSERT( cardPack ); + QString text = static_cast<IDictionary*>(cardPack->dictionary())-> + extendImagePaths( aField ); + + FieldStyle fieldStyle = FieldStyleFactory::inst()->getStyle( aStyle ); + QString beginning("<span style=\""); + beginning += QString("font-family:'%1'").arg( fieldStyle.font.family() ); + beginning += QString("; font-size:%1pt").arg( fieldStyle.font.pointSize() ); + beginning += getHighlighting(fieldStyle); + beginning += "\">" + fieldStyle.prefix; + QString ending( fieldStyle.suffix + "</span>"); + + // Highlight keywords inside plain text. Ignore tags. + if(m_showMode == AnsMode && fieldStyle.hasKeyword) + { + QString highlightedText; + int curPos = 0; + while( curPos < text.length() ) + { + QString curText; + int beginTagPos = text.indexOf( "<", curPos ); + if( beginTagPos > -1 ) + curText = text.mid( curPos, beginTagPos - curPos ); // copy plain text + else + curText = text.mid( curPos, -1 ); // copy until end of string + curText = highlightKeyword(curText, fieldStyle); + highlightedText += curText; + if( beginTagPos == -1 ) + break; + int endTagPos = text.indexOf( ">", beginTagPos ); + if( endTagPos > -1 ) + highlightedText += text.mid( beginTagPos, endTagPos - beginTagPos + 1 ); // copy tag + else + { + highlightedText += text.mid( curPos, -1 ); // copy until end of string + break; + } + curPos = endTagPos + 1; + } + text = highlightedText; + } + + return beginning + text + ending; + } + +QString CardSideView::highlightKeyword( const QString aText, const FieldStyle& fieldStyle ) const + { + QString resText = aText; + if( !m_question.isEmpty() ) + resText.replace(QRegExp( "\\b(\\w*" + QRegExp::escape( m_question ) + "\\w*)\\b", + Qt::CaseInsensitive ), "[\\1]"); + QString spanBegin("<span style=\""); + spanBegin += getHighlighting(fieldStyle.getKeywordStyle()) + "\">"; + resText.replace('[', spanBegin); + resText.replace( ']', "</span>" ); + return resText; + } + +QString CardSideView::getHighlighting(const FieldStyle& fieldStyle) const +{ + QString res; + if(fieldStyle.color != Qt::black) + res += QString("; color:%1").arg(fieldStyle.color.name()); + if(fieldStyle.font.bold()) + res += "; font-weight:bold"; + if(fieldStyle.font.italic()) + res += "; font-style:italic"; + return res; +} + +QSize CardSideView::sizeHint() const +{ + return QSize(300, 200); +} + +void CardSideView::updateNewIconPos() +{ + newIcon->move(rect().topRight() - QPoint(newIcon->width(), 0)); +} + +void CardSideView::showNewIcon(bool visible) +{ + newIcon->setVisible(visible); + updateNewIconPos(); +} + +void CardSideView::resizeEvent(QResizeEvent* /*event*/) +{ + updateNewIconPos(); +} |