/*************************************************************************** * Copyright 2001-2008 by Anne-Marie Mahfouf * * annma@kde.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "klettresview.h" #include #include #include #include #include #include #include #include //Project headers #include "klettres.h" #include "prefs.h" #include "kltheme.h" #include "langutils.h" KLettresView::KLettresView(KLettres *parent) : QWidget(parent) { m_klettres = parent; //lineEdit for user input m_letterEdit = new KLineEdit( this ); m_letterEdit->setToolTip(i18n("Type the letter or syllable that you just heard" ) ); m_letterEdit->setFont(Prefs::font()); m_letterEdit->setContextMenuPolicy(Qt::NoContextMenu); m_letterEdit->setAutoFillBackground(true); randomInt = 0; m_theme = 0; // essential m_renderer = new QSvgRenderer(); setTheme(KLThemeFactory::instance()->buildTheme(0)); } KLettresView::~KLettresView() { delete m_renderer; delete m_theme; } void KLettresView::chooseSound() { //get the next random sound m_random=m_klettres->soundFactory->randomList[randomInt%m_klettres->soundFactory->sounds]; //The sound is played kDebug() << "m_random " << m_random; m_klettres->soundFactory->playSound(m_random); //store letter or syllable in m_currentLetter m_currentLetter = m_klettres->soundFactory->namesList[m_random]; //Find the length of the syllable m_length=m_klettres->soundFactory->namesList[m_random].length(); kDebug() << "syllable length " << m_length; int width; if (m_length<3) width = 200; else width = 200+(20*(m_length-2)); m_letterEdit->setMinimumSize( QSize( width, 100 ) ); m_letterEdit->setMaximumSize( QSize( width, 100 ) ); update(); } void KLettresView::setTheme(KLTheme *theme) { // we don't allow null themes if (!theme) return; QString svgpath = KStandardDirs::locate("data", QString("klettres/pics/%1/%2").arg(theme->name(), theme->svgFileName())); // we don't allow themes with no svg installed if (!QFile::exists(svgpath)) return; delete m_theme; m_theme = theme; // stylesheet int r1, g1, b1; m_theme->backgroundInputColor().getRgb(&r1, &g1, &b1); int r2, g2, b2; m_theme->letterInputColor().getRgb(&r2, &g2, &b2); m_letterEdit->setStyleSheet(QString("border-style: solid; background-color: rgb(%1, %2, %3); color: rgb(%4, %5, %6) ; border-color: rgb(%4, %5, %6); border-bottom-right-radius:10; border-radius: 15px; border-width: 3px").arg(r1).arg(g1).arg(b1).arg(r2).arg(g2).arg(b2)); m_renderer->load(svgpath); m_backgroundCache = QPixmap(); update(); } void KLettresView::paintEvent( QPaintEvent * e ) { QPainter p(this); paintBackground(p, e->rect()); paintLetter(p, e->rect()); m_letterEdit->setFont(Prefs::font()); } void KLettresView::paintBackground(QPainter &p, const QRect& rect) { // Draw the background if (m_backgroundCache.size() != size()) { m_backgroundCache = QPixmap(size()); QPainter aux(&m_backgroundCache); m_renderer->render(&aux); } p.drawPixmap(rect.topLeft(), m_backgroundCache, rect); } void KLettresView::paintLetter(QPainter &p, const QRect& rect) { if (Prefs::level()%2==1) { QRect myRect = m_theme->wordRect(size()); if (!myRect.intersects(rect)) return; p.setPen( m_theme->letterColor()); p.setFont(Prefs::font()); p.drawText(myRect, m_currentLetter); } m_letterEdit->setGeometry( m_theme->inputRect(size())); m_letterEdit->setFocus(); } void KLettresView::game() { m_cursorPos = 1; //reset everything so when you change language or levels //it all restarts nicely QObject::disconnect(m_letterEdit, SIGNAL(textChanged(const QString&)),this,SLOT(slotProcess(const QString&)) ); m_letterEdit->clear(); m_letterEdit->setCursorPosition(0); m_letterEdit->setMaxLength( 1 ); m_letterEdit->setFocus(); m_upperLetter.clear(); chooseSound(); randomInt++; QObject::connect(m_letterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotProcess(const QString&)) ); } void KLettresView::slotProcess(const QString &inputLetter) { QString lang = Prefs::language(); QObject::disconnect(m_letterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotProcess(const QString&)) ); //check if backspace if(inputLetter.length() != m_cursorPos) { m_cursorPos--; m_letterEdit->setMaxLength( m_cursorPos ); QObject::connect(m_letterEdit, SIGNAL(textChanged(const QString&)),this,SLOT(slotProcess(const QString&)) ); return; } QChar input_character = inputLetter.at(inputLetter.length()-1); QChar input_character_u; kDebug() << "input_character " << input_character << endl; if ((!LangUtils::isIndian(lang) && (input_character.isLetter())) || (LangUtils::isIndian(lang))) { if (input_character.unicode() == 0x00DF) { //everything in upper except the ß input_character_u = input_character.toLower(); } else { input_character_u = input_character.toUpper(); } m_upperLetter.append(input_character_u); m_letterEdit->selectAll(); m_letterEdit->cut(); m_letterEdit->setText(m_upperLetter); QTimer::singleShot(m_timer*100, this, SLOT(slotTimerDone())); } else { kDebug() << "cursor " << m_cursorPos << endl; m_letterEdit->backspace(); QObject::connect(m_letterEdit, SIGNAL(textChanged(const QString&)),this,SLOT(slotProcess(const QString&)) ); } } void KLettresView::slotTimerDone() { QString match = m_currentLetter.left(m_cursorPos ); kDebug() << "match " << match.toUpper() << endl; kDebug() << "m_upperLetter " << m_upperLetter << endl; if (match == m_upperLetter) { if (m_cursorPos!=m_length) {//if text in lineEdit not equal to text on button //i.e if you still have to allow input m_letterEdit->setMaxLength( m_cursorPos +1 ); m_letterEdit->setCursorPosition( m_cursorPos ); m_letterEdit->setFocus(); m_cursorPos ++; QObject::connect(m_letterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotProcess(const QString&)) ); } else { game(); //another syllable } } else { //if not, cut it kDebug() << "wrong letter "<< endl; m_letterEdit->backspace(); //delete the char to the left and position curseur accordingly m_upperLetter.remove(m_upperLetter.size()-1, 1); m_letterEdit->setFocus(); //play sound again m_klettres->soundFactory->playSound(m_random); QObject::connect(m_letterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotProcess(const QString&)) ); } } void KLettresView::slotPlayAgain() { //TODO wait for the previous sound to be payed before playing again as it won't play if the previous one was not finished m_klettres->soundFactory->playSound(m_random); } void KLettresView::keyReleaseEvent(QKeyEvent * e) { if (e->key() == Qt::Key_Backspace) { m_upperLetter.remove(m_cursorPos-1, 1); } } #include "klettresview.moc"