From 0c1634d5307f6f1e2709774903b2b6fedf97ae3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Teuli=C3=A8re?= Date: Wed, 16 May 2012 22:05:52 +0200 Subject: [PATCH] Arbitration: do not accept blindly any rack in Intermediate state. This fixes a bug with languages using multichar tiles. --- qt/arbitration_widget.cpp | 18 ++++++++++-- qt/arbitration_widget.h | 7 +++++ qt/validator_factory.cpp | 58 ++++++++++++++++++++------------------- qt/validator_factory.h | 2 +- 4 files changed, 53 insertions(+), 32 deletions(-) diff --git a/qt/arbitration_widget.cpp b/qt/arbitration_widget.cpp index 2ec92b4..76f3f73 100644 --- a/qt/arbitration_widget.cpp +++ b/qt/arbitration_widget.cpp @@ -83,6 +83,8 @@ ArbitrationWidget::ArbitrationWidget(QWidget *parent, redPalette.setColor(QPalette::Text, Qt::red); // Define validators + m_unstrictRackValidator = + ValidatorFactory::newRackValidator(this, m_game->getBag()); QValidator * val = ValidatorFactory::newRackValidator(this, m_game->getBag(), true, &m_game->getHistory(), @@ -407,9 +409,19 @@ void ArbitrationWidget::rackEdited(const QString &iText) try { - const wstring &input = m_game->getDic().convertFromInput(wfq(iText)); - m_game->arbitrationSetRackManual(input); - emit gameUpdated(); + // Update the game rack if it is valid, or if it is "almost valid", + // i.e. in Intermediate state due to the duplicate constraints only. + // This is practical to have the rack updated letter by letter on the + // external board. + QString copy = iText; + int unused = 0; + if (lineEditRack->hasAcceptableInput() || + m_unstrictRackValidator->validate(copy, unused) == QValidator::Acceptable) + { + const wstring &input = m_game->getDic().convertFromInput(wfq(iText)); + m_game->arbitrationSetRackManual(input); + emit gameUpdated(); + } } catch (std::exception &e) { diff --git a/qt/arbitration_widget.h b/qt/arbitration_widget.h index 99a131d..ba467eb 100644 --- a/qt/arbitration_widget.h +++ b/qt/arbitration_widget.h @@ -37,6 +37,7 @@ class QStandardItemModel; class QSortFilterProxyModel; class QMenu; class QPoint; +class QValidator; class ArbitrationWidget: public QWidget, private Ui::ArbitrationWidget { @@ -102,6 +103,12 @@ private: /// Accumulator used to build the table number KeyAccumulator *m_keyAccum; + /** + * Validator less strict than the default one + * (it doesn't check duplicate constraints) + */ + QValidator *m_unstrictRackValidator; + /// Palette to write text in black QPalette blackPalette; diff --git a/qt/validator_factory.cpp b/qt/validator_factory.cpp index a2489ab..ad87f0b 100644 --- a/qt/validator_factory.cpp +++ b/qt/validator_factory.cpp @@ -106,23 +106,23 @@ class RackValidator: public QValidator { public: RackValidator(QObject *parent, const Bag &iBag, - const History *iHistory, bool checkDuplicate, + const History *iHistory, bool iStrict, int iMaxLetters); virtual State validate(QString &input, int &pos) const; private: const Bag &m_bag; const History *m_history; - bool m_checkDuplicate; + bool m_strict; int m_maxLetters; }; RackValidator::RackValidator(QObject *parent, const Bag &iBag, - const History *iHistory, bool checkDuplicate, + const History *iHistory, bool iStrict, int iMaxLetters) : QValidator(parent), m_bag(iBag), - m_history(iHistory), m_checkDuplicate(checkDuplicate), + m_history(iHistory), m_strict(iStrict), m_maxLetters(iMaxLetters) { } @@ -160,30 +160,32 @@ QValidator::State RackValidator::validate(QString &input, int &) const } } - // Make sure we don't have too many letters... - if (m_maxLetters > 0 && intInput.size() > (unsigned)m_maxLetters) - return Intermediate; - // ... or too few - if (m_maxLetters > 0 && intInput.size() < (unsigned)m_maxLetters && - m_bag.getNbTiles() >= (unsigned)m_maxLetters) + if (m_strict) { - return Intermediate; - } - - // Check that the rack has 2 consonants and 2 vocals - if (m_checkDuplicate) - { - PlayedRack pld; - pld.setManual(intInput); - - int min; - if (m_bag.getNbVowels() > 1 && m_bag.getNbConsonants() > 1 - && m_history->getSize() < 15) - min = 2; - else - min = 1; - if (!pld.checkRack(min, min)) + // Make sure we don't have too many letters... + if (m_maxLetters > 0 && intInput.size() > (unsigned)m_maxLetters) return Intermediate; + // ... or too few + if (m_maxLetters > 0 && intInput.size() < (unsigned)m_maxLetters && + m_bag.getNbTiles() >= (unsigned)m_maxLetters) + { + return Intermediate; + } + + // Check that the rack has 2 consonants and 2 vocals + if (m_history != 0) + { + PlayedRack pld; + pld.setManual(intInput); + int min; + if (m_bag.getNbVowels() > 1 && m_bag.getNbConsonants() > 1 + && m_history->getSize() < 15) + min = 2; + else + min = 1; + if (!pld.checkRack(min, min)) + return Intermediate; + } } return Acceptable; @@ -192,11 +194,11 @@ QValidator::State RackValidator::validate(QString &input, int &) const QValidator *ValidatorFactory::newRackValidator(QObject *parent, const Bag &iBag, - bool checkDuplicate, + bool iStrict, const History *iHistory, int iMaxLetters) { - return new RackValidator(parent, iBag, iHistory, checkDuplicate, iMaxLetters); + return new RackValidator(parent, iBag, iHistory, iStrict, iMaxLetters); } // }}} diff --git a/qt/validator_factory.h b/qt/validator_factory.h index bef9b8a..83d96b0 100644 --- a/qt/validator_factory.h +++ b/qt/validator_factory.h @@ -50,7 +50,7 @@ public: */ static QValidator *newRackValidator(QObject *parent, const Bag &iBag, - bool checkDuplicate = false, + bool iStrict = false, const History *iHistory = 0, int iMaxLetters = 0);