[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Eliot-dev] eliot game/coord.cpp game/coord.h game/Makefile...
From: |
Olivier Teulière |
Subject: |
[Eliot-dev] eliot game/coord.cpp game/coord.h game/Makefile... |
Date: |
Thu, 19 Feb 2009 18:25:21 +0000 |
CVSROOT: /cvsroot/eliot
Module name: eliot
Changes by: Olivier Teulière <ipkiss> 09/02/19 18:25:21
Modified files:
game : coord.cpp coord.h Makefile.am training.cpp
qt : Makefile.am board_widget.cpp board_widget.h
main_window.cpp main_window.h player_widget.cpp
player_widget.h training_widget.cpp
training_widget.h
qt/ui : player_widget.ui training_widget.ui
Added files:
qt : coord_model.cpp coord_model.h
play_word_mediator.cpp play_word_mediator.h
Log message:
- Allow setting the coordinates of the played word by clicking on the
board
- New PlayWordMediator class, to encapsulate the behaviour of the
controls
used to play a word
- The Training mode now has input fields to play words directly,
without
choosing them in the search results
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/game/coord.cpp?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/game/coord.h?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/game/Makefile.am?cvsroot=eliot&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/eliot/game/training.cpp?cvsroot=eliot&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/Makefile.am?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/board_widget.cpp?cvsroot=eliot&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/board_widget.h?cvsroot=eliot&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/main_window.cpp?cvsroot=eliot&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/main_window.h?cvsroot=eliot&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/player_widget.cpp?cvsroot=eliot&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/player_widget.h?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/training_widget.cpp?cvsroot=eliot&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/training_widget.h?cvsroot=eliot&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/coord_model.cpp?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/coord_model.h?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/play_word_mediator.cpp?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/play_word_mediator.h?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/ui/player_widget.ui?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/ui/training_widget.ui?cvsroot=eliot&r1=1.3&r2=1.4
Patches:
Index: game/coord.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/coord.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- game/coord.cpp 22 Nov 2008 13:09:30 -0000 1.11
+++ game/coord.cpp 19 Feb 2009 18:25:17 -0000 1.12
@@ -45,12 +45,23 @@
m_col >= BOARD_MIN && m_col <= BOARD_MAX);
}
+/*
void Coord::operator=(const Coord &iOther)
{
m_dir = iOther.m_dir;
m_row = iOther.m_row;
m_col = iOther.m_col;
}
+*/
+
+bool Coord::operator==(const Coord &iOther) const
+{
+ if (!isValid() && !iOther.isValid())
+ return true;
+ return m_row == iOther.m_row
+ && m_col == iOther.m_col
+ && m_dir == iOther.m_dir;
+}
void Coord::swap()
{
Index: game/coord.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/coord.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- game/coord.h 22 Nov 2008 13:09:30 -0000 1.9
+++ game/coord.h 19 Feb 2009 18:25:17 -0000 1.10
@@ -50,7 +50,7 @@
Direction getDir() const { return m_dir; }
bool isValid() const;
- void operator=(const Coord &iOther);
+ bool operator==(const Coord &iOther) const;
// Swap the coordinates (without changing the direction)
void swap();
Index: game/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/game/Makefile.am,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- game/Makefile.am 24 Jan 2009 23:02:42 -0000 1.24
+++ game/Makefile.am 19 Feb 2009 18:25:17 -0000 1.25
@@ -24,6 +24,8 @@
libgame_a_SOURCES= \
game_exception.cpp game_exception.h \
command.h command.cpp \
+ coord.cpp coord.h \
+ cross.cpp cross.h \
rack.cpp rack.h \
pldrack.cpp pldrack.h \
round.cpp round.h \
@@ -38,8 +40,6 @@
player_rack_cmd.cpp player_rack_cmd.h \
ai_player.h \
ai_percent.cpp ai_percent.h \
- coord.cpp coord.h \
- cross.cpp cross.h \
board.cpp board.h \
board_cross.cpp \
matrix.h \
Index: game/training.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/training.cpp,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- game/training.cpp 24 Jan 2009 17:44:57 -0000 1.33
+++ game/training.cpp 19 Feb 2009 18:25:17 -0000 1.34
@@ -88,6 +88,8 @@
// Perform all the validity checks, and fill a round
Round round;
+ removeTestPlay();
+
int res = checkPlayedWord(iCoord, iWord, round);
if (res != 0)
{
Index: qt/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- qt/Makefile.am 30 Nov 2008 20:53:45 -0000 1.9
+++ qt/Makefile.am 19 Feb 2009 18:25:17 -0000 1.10
@@ -47,12 +47,14 @@
ui/training_widget.ui.h \
ui/prefs_dialog.ui.h \
ui/dic_tools_widget.ui.h \
+ coord_model.moc.cpp \
new_game.moc.cpp \
dic_tools_widget.moc.cpp \
bag_widget.moc.cpp \
score_widget.moc.cpp \
board_widget.moc.cpp \
history_widget.moc.cpp \
+ play_word_mediator.moc.cpp \
player_widget.moc.cpp \
training_widget.moc.cpp \
prefs_dialog.moc.cpp \
@@ -62,12 +64,14 @@
eliot_SOURCES = \
qtcommon.h \
+ coord_model.h coord_model.cpp \
bag_widget.cpp bag_widget.h \
dic_tools_widget.cpp dic_tools_widget.h \
new_game.cpp new_game.h \
score_widget.cpp score_widget.h \
board_widget.cpp board_widget.h \
history_widget.cpp history_widget.h \
+ play_word_mediator.cpp play_word_mediator.h \
training_widget.cpp training_widget.h \
player_widget.cpp player_widget.h \
prefs_dialog.cpp prefs_dialog.h \
Index: qt/board_widget.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/board_widget.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- qt/board_widget.cpp 26 Jan 2009 20:30:41 -0000 1.11
+++ qt/board_widget.cpp 19 Feb 2009 18:25:17 -0000 1.12
@@ -21,6 +21,7 @@
#include <math.h>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
+#include <QtGui/QMouseEvent>
#include <QtCore/QSettings>
#include "board_widget.h"
@@ -29,6 +30,7 @@
#include "public_game.h"
#include "tile.h"
#include "board.h"
+#include "coord_model.h"
using namespace std;
@@ -42,16 +44,21 @@
const QColor BoardWidget::PreviewColour(183, 183, 123);
const QColor BoardWidget::NormalColour(0, 0, 0);
const QColor BoardWidget::JokerColour(255, 0, 0);
+const QColor BoardWidget::ArrowColour(10, 10, 10);
-BoardWidget::BoardWidget(QWidget *parent)
- : QFrame(parent), m_game(NULL)
+BoardWidget::BoardWidget(CoordModel &iCoordModel, QWidget *parent)
+ : QFrame(parent), m_game(NULL), m_coordModel(iCoordModel)
{
setFrameStyle(QFrame::Panel);
// Use as much space as possible
QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setSizePolicy(policy);
setMinimumSize(200, 200);
+
+ // Listen to changes in the coordinates
+ QObject::connect(&m_coordModel, SIGNAL(coordChanged(const Coord&)),
+ this, SLOT(updateArrow(const Coord&)));
}
@@ -62,6 +69,14 @@
}
+void BoardWidget::updateArrow(const Coord &)
+{
+ // Refresh everything
+ // We could actually refresh only the 2 involved squares...
+ refresh();
+}
+
+
void BoardWidget::refresh()
{
update();
@@ -158,5 +173,64 @@
Qt::AlignCenter,
QString(1, 'A' + x - 1));
}
+ // Draw the arrow
+ const Coord &markCoord = m_coordModel.getCoord();
+ if (m_game != NULL && markCoord.isValid())
+ {
+ const unsigned int xPos = (markCoord.getCol() - BOARD_MIN + 1) *
squareSize + 1;
+ const unsigned int yPos = (markCoord.getRow() - BOARD_MIN + 1) *
squareSize + 1;
+ painter.setPen(QPen(ArrowColour, 0));
+ painter.setBrush(ArrowColour);
+ const int mid = squareSize / 2;
+ const int fifth = squareSize / 5;
+ const int width = squareSize / 16;
+ painter.translate(xPos + mid, yPos + mid);
+ if (markCoord.getDir() == Coord::VERTICAL)
+ painter.rotate(90);
+ const QPoint points[] =
+ {
+ QPoint(-mid + fifth, -width),
+ QPoint(-mid + 3*fifth, -width),
+ QPoint(-mid + 3*fifth, -fifth),
+ QPoint(-mid + 4*fifth, 0),
+ QPoint(-mid + 3*fifth, fifth),
+ QPoint(-mid + 3*fifth, width),
+ QPoint(-mid + fifth, width)
+ };
+ painter.drawPolygon(points, 7);
+
+ painter.setPen(QPen());
+ painter.setBrush(NormalColour);
+ }
+}
+
+
+void BoardWidget::mousePressEvent(QMouseEvent *iEvent)
+{
+ if (m_game == NULL)
+ {
+ m_coordModel.clear();
+ return;
+ }
+
+ if (iEvent->button() == Qt::LeftButton)
+ {
+ // Find the coordinates
+ const int size = std::min(width(), height());
+ const int squareSize = (int)floor((size - 1) / (BOARD_MAX - BOARD_MIN
+ 2));
+ int row = iEvent->y() / squareSize;
+ int col = iEvent->x() / squareSize;
+ // Change the direction if this is exactly the same as the current one
+ Coord coord(row, col, Coord::HORIZONTAL);
+ if (m_coordModel.getCoord() == coord)
+ coord.setDir(Coord::VERTICAL);
+ // Take into acount the new coordinates
+ m_coordModel.setCoord(coord);
+ }
+ else if (iEvent->button() == Qt::RightButton)
+ {
+ // On a right click anywhere on the board, remove the arrow
+ m_coordModel.clear();
+ }
}
Index: qt/board_widget.h
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/board_widget.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- qt/board_widget.h 30 Nov 2008 20:53:45 -0000 1.5
+++ qt/board_widget.h 19 Feb 2009 18:25:18 -0000 1.6
@@ -24,15 +24,17 @@
#include <QtGui/QFrame>
-class PublicGame;
class QTreeView;
+class PublicGame;
+class CoordModel;
+class Coord;
class BoardWidget: public QFrame
{
Q_OBJECT;
public:
- explicit BoardWidget(QWidget *parent = 0);
+ explicit BoardWidget(CoordModel &iCoordModel, QWidget *parent = 0);
public slots:
void setGame(const PublicGame *iGame);
@@ -43,11 +45,19 @@
virtual QSize sizeHint() const;
/// Paint the board
virtual void paintEvent(QPaintEvent *iEvent);
+ /// Catch mouse clicks on the board
+ virtual void mousePressEvent(QMouseEvent *iEvent);
+
+private slots:
+ void updateArrow(const Coord &iCoord);
private:
/// Encapsulated game, can be NULL
const PublicGame *m_game;
+ /// Coordinates of the next word to play
+ CoordModel &m_coordModel;
+
/// Define a few background colours
//@{
static const QColor EmptyColour;
@@ -59,6 +69,7 @@
static const QColor PreviewColour;
static const QColor NormalColour;
static const QColor JokerColour;
+ static const QColor ArrowColour;
//@}
};
Index: qt/main_window.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/main_window.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- qt/main_window.cpp 24 Jan 2009 17:44:57 -0000 1.29
+++ qt/main_window.cpp 19 Feb 2009 18:25:18 -0000 1.30
@@ -99,7 +99,7 @@
this, SLOT(updateStatusBar(const Dictionary*)));
// Board
- BoardWidget *boardWidget = new BoardWidget;
+ BoardWidget *boardWidget = new BoardWidget(m_coordModel);
QObject::connect(this, SIGNAL(gameChanged(const PublicGame*)),
boardWidget, SLOT(setGame(const PublicGame*)));
QObject::connect(this, SIGNAL(gameUpdated()),
@@ -134,7 +134,7 @@
// Players racks
m_ui.groupBoxPlayers->hide();
- m_playersWidget = new PlayerTabWidget(NULL);
+ m_playersWidget = new PlayerTabWidget(m_coordModel, NULL);
m_ui.groupBoxPlayers->layout()->addWidget(m_playersWidget);
QObject::connect(this, SIGNAL(gameChangedNonConst(PublicGame*)),
m_playersWidget, SLOT(setGame(PublicGame*)));
@@ -765,7 +765,7 @@
if (m_boardWindow == NULL)
{
// Create the window
- BoardWidget *board = new BoardWidget(NULL);
+ BoardWidget *board = new BoardWidget(m_coordModel, NULL);
board->setGame(m_game);
m_boardWindow = new AuxWindow(*board, _q("Board"), "BoardWindow",
m_actionWindowsBoard);
Index: qt/main_window.h
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/main_window.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- qt/main_window.h 14 Dec 2008 13:20:46 -0000 1.15
+++ qt/main_window.h 19 Feb 2009 18:25:19 -0000 1.16
@@ -24,6 +24,7 @@
#include <QMainWindow>
#include <ui/main_window.ui.h>
+#include "coord_model.h"
class Dictionary;
@@ -139,9 +140,12 @@
AuxWindow *m_dicToolsWindow;
//@}
- /// Label indicationg the name of the current dictionary
+ /// Label indicating the name of the current dictionary
QLabel *m_dicNameLabel;
+ /// Model for the coordinates of the word to play
+ CoordModel m_coordModel;
+
/// Save window state
void writeSettings() const;
/// Restore window state
Index: qt/player_widget.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/player_widget.cpp,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- qt/player_widget.cpp 14 Dec 2008 13:20:46 -0000 1.14
+++ qt/player_widget.cpp 19 Feb 2009 18:25:19 -0000 1.15
@@ -25,11 +25,13 @@
#include "player_widget.h"
#include "training_widget.h"
+#include "play_word_mediator.h"
#include "qtcommon.h"
#include "public_game.h"
#include "player.h"
#include "pldrack.h"
#include "coord.h"
+#include "coord_model.h"
#include "dic.h"
#include "debug.h"
@@ -49,47 +51,22 @@
};
-/// Validator used for the "play word" line edit
-class PlayWordValidator: public QValidator
-{
-public:
- explicit PlayWordValidator(QObject *parent,
- const Dictionary &iDic);
- virtual State validate(QString &input, int &pos) const;
-
-private:
- const Dictionary &m_dic;
-};
-
-
-/// Validator used for the "coords" line edit
-class CoordsValidator: public QValidator
-{
-public:
- explicit CoordsValidator(QObject *parent);
- virtual State validate(QString &input, int &pos) const;
-};
-
-
-PlayerWidget::PlayerWidget(QWidget *parent, unsigned int iPlayerNb, PublicGame
*iGame)
+PlayerWidget::PlayerWidget(QWidget *parent, CoordModel &iCoordModel,
+ unsigned int iPlayerNb, PublicGame *iGame)
: QWidget(parent), m_game(iGame), m_player(iPlayerNb)
{
setupUi(this);
- lineEditPlay->setFocus();
- // These strings cannot be in the .ui file, because of the newlines
- lineEditPlay->setToolTip(_q("Enter the word to play (case-insensitive).\n"
- "A joker from the rack must be written in parentheses.\n"
- "E.g.: w(o)rd or W(O)RD"));
- lineEditCoords->setToolTip(_q("Enter the coordinates of the word.\n"
- "Specify the row before the column for horizontal words,\n"
- "and the column before the row for vertical words.\n"
- "E.g.: H4 or 4H"));
+
+ // Use the mediator
+ m_mediator = new PlayWordMediator(this, *lineEditPlay, *lineEditCoords,
+ *pushButtonPlay, iCoordModel, iGame);
+ QObject::connect(m_mediator, SIGNAL(gameUpdated()),
+ this, SIGNAL(gameUpdated()));
+ QObject::connect(m_mediator, SIGNAL(notifyProblem(QString)),
+ this, SIGNAL(notifyProblem(QString)));
if (m_game)
{
- lineEditPlay->setValidator(new PlayWordValidator(this,
m_game->getDic()));
- lineEditCoords->setValidator(new CoordsValidator(this));
-
// Do not allow messing with AI players
if (!m_game->getPlayer(m_player).isHuman())
setEnabled(false);
@@ -156,13 +133,6 @@
}
-void PlayerWidget::on_lineEditPlay_textChanged()
-{
- pushButtonPlay->setEnabled(lineEditPlay->hasAcceptableInput() &&
- lineEditCoords->hasAcceptableInput());
-}
-
-
void PlayerWidget::on_lineEditChange_textChanged()
{
pushButtonChange->setEnabled(lineEditChange->hasAcceptableInput() &&
@@ -171,93 +141,6 @@
}
-void PlayerWidget::on_lineEditPlay_returnPressed()
-{
- if (!lineEditPlay->hasAcceptableInput() ||
- !lineEditCoords->hasAcceptableInput())
- return;
-
- // Convert the jokers to lowercase
- QString word = lineEditPlay->text().toUpper();
- int pos;
- while ((pos = word.indexOf('(')) != -1)
- {
- if (word.size() < pos + 3 || word[pos + 2] != ')' ||
- !m_game->getDic().validateLetters(qtw(QString(word[pos + 1]))))
- {
- // Bug in validate()!
- // This should never happen
- QString msg = _q("Cannot play word: misplaced parentheses");
- emit notifyProblem(msg);
- break;
- }
- else
- {
- QChar chr = word[pos + 1].toLower();
- word.remove(pos, 3);
- word.insert(pos, chr);
- }
- }
-
- QString coords = lineEditCoords->text();
- int res = m_game->play(qtw(word), qtw(coords));
- if (res == 0)
- {
- emit gameUpdated();
- lineEditPlay->setFocus();
- }
- else
- {
- // Try to be as explicit as possible concerning the error
- QString msg = _q("Cannot play '%1' at position '%2':\n")
- .arg(lineEditPlay->text()).arg(coords);
- switch (res)
- {
- case 1:
- msg += _q("Some letters are not valid for the current
dictionary");
- break;
- case 2:
- msg += _q("Invalid coordinates");
- break;
- case 3:
- msg += _q("The word does not exist");
- break;
- case 4:
- msg += _q("The rack doesn't contain the letters needed to play
this word");
- break;
- case 5:
- msg += _q("The word is part of a longer one");
- break;
- case 6:
- msg += _q("The word tries to replace an existing letter");
- break;
- case 7:
- msg += _q("An orthogonal word is not valid");
- break;
- case 8:
- msg += _q("The word is already present on the board at these
coordinates");
- break;
- case 9:
- msg += _q("A word cannot be isolated (not connected to the
placed words)");
- break;
- case 10:
- msg += _q("The first word of the game must be horizontal");
- break;
- case 11:
- msg += _q("The first word of the game must cover the H8
square");
- break;
- case 12:
- msg += _q("The word is going out of the board");
- break;
- default:
- msg += _q("Incorrect or misplaced word (%1)").arg(1);
- }
- // FIXME: the error is too generic
- emit notifyProblem(msg);
- }
-}
-
-
void PlayerWidget::on_lineEditChange_returnPressed()
{
ASSERT(m_game->getMode() == PublicGame::kFREEGAME,
@@ -308,76 +191,8 @@
-PlayWordValidator::PlayWordValidator(QObject *parent,
- const Dictionary &iDic)
- : QValidator(parent), m_dic(iDic)
-{
-}
-
-
-QValidator::State PlayWordValidator::validate(QString &input, int &) const
-{
- if (input == "")
- return Intermediate;
-
- QString copy(input);
- // Strip parentheses
- copy.remove('(');
- copy.remove(')');
- // The string is invalid if it contains characters not present
- // in the dictionary
- if (!m_dic.validateLetters(qtw(copy)) || copy.contains('?'))
- return Invalid;
-
- // Check the parentheses pairs
- copy = input;
- int pos;
- while ((pos = copy.indexOf('(')) != -1)
- {
- if (copy.size() < pos + 3 || copy[pos + 2] != ')' ||
- !m_dic.validateLetters(qtw(QString(copy[pos + 1]))))
- {
- return Intermediate;
- }
- else
- {
- copy.remove(pos, 3);
- }
- }
- if (copy.indexOf(')') != -1)
- return Intermediate;
-
- return Acceptable;
-}
-
-
-
-CoordsValidator::CoordsValidator(QObject *parent)
- : QValidator(parent)
-{
-}
-
-
-QValidator::State CoordsValidator::validate(QString &input, int &) const
-{
- // Only authorize characters part of a valid coordinate
- wstring copy = qtw(input.toUpper());
- wstring authorized = L"ABCDEFGHIJKLMNO1234567890";
- if (copy.find_first_not_of(authorized) != wstring::npos)
- return Invalid;
-
- // Check coordinates
- Coord c(qtw(input));
- if (!c.isValid())
- return Intermediate;
-
- return Acceptable;
-}
-
-
-
-PlayerTabWidget::PlayerTabWidget(QWidget *parent)
- : QTabWidget(parent)
+PlayerTabWidget::PlayerTabWidget(CoordModel &iCoordModel, QWidget *parent)
+ : QTabWidget(parent), m_coordModel(iCoordModel)
{
QObject::connect(this, SIGNAL(currentChanged(int)),
this, SLOT(changeCurrentPlayer(int)));
@@ -405,8 +220,7 @@
if (iGame->getMode() == PublicGame::kTRAINING)
{
const Player &player = iGame->getPlayer(0);
- TrainingWidget *trWidget = new TrainingWidget;
- trWidget->setGame(iGame);
+ TrainingWidget *trWidget = new TrainingWidget(NULL, m_coordModel,
iGame);
QObject::connect(this, SIGNAL(refreshSignal()),
trWidget, SLOT(refresh()));
// Forward signals to the outside
@@ -426,7 +240,7 @@
for (unsigned int i = 0; i < iGame->getNbPlayers(); ++i)
{
const Player &player = iGame->getPlayer(i);
- PlayerWidget *p = new PlayerWidget(NULL, i, iGame);
+ PlayerWidget *p = new PlayerWidget(NULL, m_coordModel, i,
iGame);
QObject::connect(this, SIGNAL(refreshSignal()), p,
SLOT(refresh()));
// Forward signals to the outside
QObject::connect(p, SIGNAL(notifyProblem(QString)),
@@ -460,6 +274,8 @@
if (m_game == NULL)
return;
+ m_coordModel.clear();
+
// Change the active player when the active tab changes
// (only in duplicate mode)
if (m_game->getMode() == PublicGame::kDUPLICATE &&
Index: qt/player_widget.h
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/player_widget.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- qt/player_widget.h 14 Dec 2008 13:20:47 -0000 1.9
+++ qt/player_widget.h 19 Feb 2009 18:25:19 -0000 1.10
@@ -18,8 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
-#ifndef RACK_WIDGET_H_
-#define RACK_WIDGET_H_
+#ifndef PLAYER_WIDGET_H_
+#define PLAYER_WIDGET_H_
#include <QtGui/QWidget>
#include <QtGui/QTabWidget>
@@ -28,13 +28,17 @@
class QLineEdit;
class PublicGame;
+class PlayWordMediator;
+class CoordModel;
+class Coord;
class PlayerWidget: public QWidget, private Ui::PlayerWidget
{
Q_OBJECT;
public:
- explicit PlayerWidget(QWidget *parent = 0,
+ explicit PlayerWidget(QWidget *parent,
+ CoordModel &iCoordModel,
unsigned int iPlayerNb = 0,
PublicGame *iGame = NULL);
@@ -51,20 +55,18 @@
private slots:
void on_pushButtonShuffle_clicked();
- void on_pushButtonPlay_clicked() { on_lineEditPlay_returnPressed(); }
void on_pushButtonChange_clicked() { on_lineEditChange_returnPressed(); }
void on_pushButtonPass_clicked() { on_lineEditChange_returnPressed(); }
- void on_lineEditPlay_textChanged();
- void on_lineEditCoords_textChanged() { on_lineEditPlay_textChanged(); }
void on_lineEditChange_textChanged();
- void on_lineEditPlay_returnPressed();
- void on_lineEditCoords_returnPressed() { on_lineEditPlay_returnPressed(); }
void on_lineEditChange_returnPressed();
private:
/// Encapsulated game, can be NULL
PublicGame *m_game;
+ /// Mediator for the "play word" controls
+ PlayWordMediator *m_mediator;
+
/// Encapsulated player, valid iff m_game is not NULL
unsigned int m_player;
@@ -76,7 +78,7 @@
Q_OBJECT;
public:
- explicit PlayerTabWidget(QWidget *parent = 0);
+ explicit PlayerTabWidget(CoordModel &iCoordModel, QWidget *parent = 0);
public slots:
void setGame(PublicGame *iGame);
@@ -95,6 +97,9 @@
private:
/// Encapsulated game, can be NULL
PublicGame *m_game;
+
+ /// Model for the word coordinates
+ CoordModel &m_coordModel;
};
#endif
Index: qt/training_widget.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/training_widget.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- qt/training_widget.cpp 24 Jan 2009 10:28:21 -0000 1.9
+++ qt/training_widget.cpp 19 Feb 2009 18:25:20 -0000 1.10
@@ -23,6 +23,8 @@
#include "training_widget.h"
#include "qtcommon.h"
+#include "play_word_mediator.h"
+
#include "dic.h"
#include "bag.h"
#include "public_game.h"
@@ -37,21 +39,27 @@
class RackValidator: public QValidator
{
public:
- explicit RackValidator(QObject *parent);
+ explicit RackValidator(QObject *parent, const Bag *iBag);
virtual State validate(QString &input, int &pos) const;
- void setBag(const Bag *iBag) { m_bag = iBag; }
-
private:
const Bag *m_bag;
};
-TrainingWidget::TrainingWidget(QWidget *parent)
- : QWidget(parent), m_game(NULL)
+TrainingWidget::TrainingWidget(QWidget *parent, CoordModel &iCoordModel,
PublicGame *iGame)
+ : QWidget(parent), m_game(iGame)
{
setupUi(this);
+ // Use the mediator
+ m_mediator = new PlayWordMediator(this, *lineEditPlay, *lineEditCoords,
+ *pushButtonPlay, iCoordModel, m_game);
+ QObject::connect(m_mediator, SIGNAL(gameUpdated()),
+ this, SIGNAL(gameUpdated()));
+ QObject::connect(m_mediator, SIGNAL(notifyProblem(QString)),
+ this, SIGNAL(notifyProblem(QString)));
+
// Associate the model to the view
m_model = new QStandardItemModel(this);
treeViewResults->setModel(m_model);
@@ -76,8 +84,9 @@
this,
SLOT(showPreview(const QItemSelection&, const
QItemSelection&)));
- m_validator = new RackValidator(this);
- lineEditRack->setValidator(m_validator);
+ if (m_game)
+ lineEditRack->setValidator(new RackValidator(this, &m_game->getBag()));
+
// Notify that the rack changed
QObject::connect(lineEditRack, SIGNAL(textChanged(const QString&)),
this, SIGNAL(rackUpdated(const QString&)));
@@ -86,17 +95,6 @@
}
-void TrainingWidget::setGame(PublicGame *iGame)
-{
- m_game = iGame;
- if (m_game != NULL)
- m_validator->setBag(&m_game->getBag());
- else
- m_validator->setBag(NULL);
- refresh();
-}
-
-
void TrainingWidget::refresh()
{
updateModel();
@@ -115,6 +113,8 @@
// Update the rack only if it is needed, to avoid losing cursor
position
if (qfw(rack) != lineEditRack->text())
lineEditRack->setText(qfw(rack));
+ lineEditPlay->clear();
+ lineEditCoords->clear();
lineEditRack->setEnabled(true);
pushButtonRack->setEnabled(true);
pushButtonComplement->setEnabled(true);
@@ -171,9 +171,9 @@
void TrainingWidget::enablePlayButton(const QItemSelection &iSelected,
const QItemSelection &)
{
- // Enable the "Play" button iff at least one line in the tree view
- // is selected
- pushButtonPlay->setEnabled(!iSelected.indexes().empty());
+ // Enable the "Play selected" button iff at least one line
+ // in the tree view is selected
+ pushButtonPlaySelected->setEnabled(!iSelected.indexes().empty());
}
@@ -252,7 +252,7 @@
}
-void TrainingWidget::on_pushButtonPlay_clicked()
+void TrainingWidget::on_pushButtonPlaySelected_clicked()
{
QModelIndexList indexList =
treeViewResults->selectionModel()->selectedIndexes();
if (indexList.empty())
@@ -281,8 +281,8 @@
-RackValidator::RackValidator(QObject *parent)
- : QValidator(parent)
+RackValidator::RackValidator(QObject *parent, const Bag *iBag)
+ : QValidator(parent), m_bag(iBag)
{
}
Index: qt/training_widget.h
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/training_widget.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- qt/training_widget.h 14 Dec 2008 13:20:49 -0000 1.5
+++ qt/training_widget.h 19 Feb 2009 18:25:20 -0000 1.6
@@ -25,20 +25,20 @@
#include "ui/training_widget.ui.h"
-class PublicGame;
-class RackValidator;
class QStandardItemModel;
class QString;
+class CoordModel;
+class PlayWordMediator;
+class PublicGame;
class TrainingWidget: public QWidget, private Ui::TrainingWidget
{
Q_OBJECT;
public:
- explicit TrainingWidget(QWidget *parent = 0);
+ explicit TrainingWidget(QWidget *parent, CoordModel &iCoordModel,
PublicGame *iGame);
public slots:
- void setGame(PublicGame *iGame);
void refresh();
signals:
@@ -60,7 +60,7 @@
void on_pushButtonRack_clicked();
void on_pushButtonComplement_clicked();
void on_pushButtonSearch_clicked();
- void on_pushButtonPlay_clicked();
+ void on_pushButtonPlaySelected_clicked();
void on_treeViewResults_doubleClicked(const QModelIndex &iIndex);
private:
@@ -70,8 +70,8 @@
/// Model of the search results
QStandardItemModel *m_model;
- /// Validator for the rack edition
- RackValidator *m_validator;
+ /// Mediator for the "play word" controls
+ PlayWordMediator *m_mediator;
/// Force synchronizing the model with the contents of the search results
void updateModel();
Index: qt/ui/player_widget.ui
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/ui/player_widget.ui,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- qt/ui/player_widget.ui 14 Sep 2008 17:56:19 -0000 1.4
+++ qt/ui/player_widget.ui 19 Feb 2009 18:25:20 -0000 1.5
@@ -6,7 +6,7 @@
<x>0</x>
<y>0</y>
<width>460</width>
- <height>148</height>
+ <height>117</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout" >
@@ -31,6 +31,44 @@
</property>
</widget>
</item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="labelChange" >
+ <property name="text" >
+ <string>_("Change letters:")</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="lineEditChange" >
+ <property name="toolTip" >
+ <string>_("Enter the letters you want to change")</string>
+ </property>
+ <property name="text" >
+ <string>dummy</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2" colspan="2" >
+ <widget class="QPushButton" name="pushButtonChange" >
+ <property name="text" >
+ <string>_("Change")</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="4" >
+ <widget class="QPushButton" name="pushButtonPass" >
+ <property name="text" >
+ <string>_("Pass")</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>_("Ref.:")</string>
+ </property>
+ </widget>
+ </item>
<item row="1" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
@@ -53,6 +91,13 @@
</property>
</widget>
</item>
+ <item row="1" column="4" >
+ <widget class="QPushButton" name="pushButtonPlay" >
+ <property name="text" >
+ <string>_("Play")</string>
+ </property>
+ </widget>
+ </item>
<item row="1" column="3" >
<widget class="QLineEdit" name="lineEditCoords" >
<property name="sizePolicy" >
@@ -78,51 +123,6 @@
</property>
</widget>
</item>
- <item row="1" column="4" >
- <widget class="QPushButton" name="pushButtonPlay" >
- <property name="text" >
- <string>_("Play")</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" >
- <widget class="QLabel" name="labelChange" >
- <property name="text" >
- <string>_("Change letters:")</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <widget class="QLineEdit" name="lineEditChange" >
- <property name="toolTip" >
- <string>_("Enter the letters you want to change")</string>
- </property>
- <property name="text" >
- <string>dummy</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2" colspan="2" >
- <widget class="QPushButton" name="pushButtonChange" >
- <property name="text" >
- <string>_("Change")</string>
- </property>
- </widget>
- </item>
- <item row="2" column="4" >
- <widget class="QPushButton" name="pushButtonPass" >
- <property name="text" >
- <string>_("Pass")</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2" >
- <widget class="QLabel" name="label_3" >
- <property name="text" >
- <string>_("Ref.:")</string>
- </property>
- </widget>
- </item>
</layout>
</widget>
<resources/>
Index: qt/ui/training_widget.ui
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/ui/training_widget.ui,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- qt/ui/training_widget.ui 31 Aug 2008 11:48:22 -0000 1.3
+++ qt/ui/training_widget.ui 19 Feb 2009 18:25:20 -0000 1.4
@@ -5,14 +5,14 @@
<rect>
<x>0</x>
<y>0</y>
- <width>415</width>
- <height>371</height>
+ <width>511</width>
+ <height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
- <layout class="QVBoxLayout" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
<item>
<layout class="QHBoxLayout" >
<item>
@@ -23,7 +23,81 @@
</widget>
</item>
<item>
- <widget class="QLineEdit" name="lineEditRack" />
+ <widget class="QLineEdit" name="lineEditRack" >
+ <property name="minimumSize" >
+ <size>
+ <width>60</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>_("Play a word:")</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditPlay" >
+ <property name="minimumSize" >
+ <size>
+ <width>60</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>_("Enter the word to play (case-insensitive).
+A joker from the rack must be written in parentheses.
+E.g.: w(o)rd or W(O)RD")</string>
+ </property>
+ <property name="statusTip" >
+ <string>_("Enter the word to play (case-insensitive). A joker from the
rack must be written in parentheses. E.g.: w(o)rd or W(O)RD")</string>
+ </property>
+ <property name="text" >
+ <string>dummy</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>_("Ref.:")</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEditCoords" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>45</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip" >
+ <string>_("Enter the coordinates of the word.
+Specify the row before the column for horizontal words,
+ and the column before the row for vertical words.
+E.g.: H4 or 4H")</string>
+ </property>
+ <property name="statusTip" >
+ <string>_("Enter the coordinates of the word. Specify the row before
the column for horizontal words, and the column before the row for vertical
words. E.g.: H4 or 4H")</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonPlay" >
+ <property name="text" >
+ <string>_("Play")</string>
+ </property>
+ </widget>
</item>
</layout>
</item>
@@ -54,12 +128,12 @@
</widget>
</item>
<item>
- <widget class="QPushButton" name="pushButtonPlay" >
+ <widget class="QPushButton" name="pushButtonPlaySelected" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
- <string>_("Play")</string>
+ <string>_("Play selected")</string>
</property>
</widget>
</item>
@@ -82,6 +156,7 @@
</widget>
</item>
</layout>
+ <zorder>treeViewResults</zorder>
</widget>
</item>
</layout>
Index: qt/coord_model.cpp
===================================================================
RCS file: qt/coord_model.cpp
diff -N qt/coord_model.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ qt/coord_model.cpp 19 Feb 2009 18:25:18 -0000 1.1
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2009 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *****************************************************************************/
+
+#include "coord_model.h"
+
+
+void CoordModel::setCoord(const Coord &iCoord)
+{
+ m_prevCoord = m_currCoord;
+ m_currCoord = iCoord;
+ emit coordChanged(iCoord);
+}
+
+
+void CoordModel::clear()
+{
+ setCoord(Coord());
+}
+
Index: qt/coord_model.h
===================================================================
RCS file: qt/coord_model.h
diff -N qt/coord_model.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ qt/coord_model.h 19 Feb 2009 18:25:18 -0000 1.1
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2009 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *****************************************************************************/
+
+#ifndef COORD_MODEL_H_
+#define COORD_MODEL_H_
+
+#include <QObject>
+#include "coord.h"
+
+
+class CoordModel: public QObject
+{
+ Q_OBJECT;
+
+public:
+ void setCoord(const Coord &iCoord);
+ void clear();
+
+ const Coord &getCoord() const { return m_currCoord; }
+ const Coord &getPrevCoord() const { return m_prevCoord; }
+
+signals:
+ void coordChanged(const Coord &iNewCoord);
+
+private:
+ Coord m_currCoord;
+ Coord m_prevCoord;
+};
+
+#endif
+
Index: qt/play_word_mediator.cpp
===================================================================
RCS file: qt/play_word_mediator.cpp
diff -N qt/play_word_mediator.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ qt/play_word_mediator.cpp 19 Feb 2009 18:25:19 -0000 1.1
@@ -0,0 +1,278 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2009 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *****************************************************************************/
+
+#include <QtGui/QLineEdit>
+#include <QtGui/QPushButton>
+
+#include "play_word_mediator.h"
+#include "coord_model.h"
+#include "qtcommon.h"
+
+#include "public_game.h"
+#include "coord.h"
+#include "dic.h"
+#include "debug.h"
+
+
+/// Validator used for the "play word" line edit
+class PlayWordValidator: public QValidator
+{
+public:
+ explicit PlayWordValidator(QObject *parent,
+ const Dictionary &iDic);
+ virtual State validate(QString &input, int &pos) const;
+
+private:
+ const Dictionary &m_dic;
+};
+
+
+/// Validator used for the "coords" line edit
+class CoordsValidator: public QValidator
+{
+public:
+ explicit CoordsValidator(QObject *parent);
+ virtual State validate(QString &input, int &pos) const;
+};
+
+
+
+PlayWordMediator::PlayWordMediator(QObject *parent, QLineEdit &iEditPlay,
+ QLineEdit &iEditCoord, QPushButton
&iButtonPlay,
+ CoordModel &iCoordModel, PublicGame *iGame)
+ : QObject(parent), m_game(iGame), m_lineEditPlay(iEditPlay),
+ m_lineEditCoord(iEditCoord), m_pushButtonPlay(iButtonPlay),
+ m_coordModel(iCoordModel)
+{
+ m_lineEditPlay.setFocus();
+ // These strings cannot be in the .ui file, because of the newlines
+ m_lineEditPlay.setToolTip(_q("Enter the word to play (case-insensitive).\n"
+ "A joker from the rack must be written in parentheses.\n"
+ "E.g.: w(o)rd or W(O)RD"));
+ m_lineEditCoord.setToolTip(_q("Enter the coordinates of the word.\n"
+ "Specify the row before the column for horizontal words,\n"
+ "and the column before the row for vertical words.\n"
+ "E.g.: H4 or 4H"));
+
+ /// Set validators;
+ if (m_game)
+ {
+ m_lineEditPlay.setValidator(new PlayWordValidator(this,
m_game->getDic()));
+ m_lineEditCoord.setValidator(new CoordsValidator(this));
+ }
+
+ // Set all the connections
+ QObject::connect(&m_lineEditPlay, SIGNAL(textChanged(const QString&)),
+ this, SLOT(lineEditPlay_textChanged()));
+ QObject::connect(&m_lineEditPlay, SIGNAL(returnPressed()),
+ this, SLOT(lineEditPlay_returnPressed()));
+ QObject::connect(&m_lineEditCoord, SIGNAL(textChanged(const QString&)),
+ this, SLOT(lineEditCoord_textChanged(const QString&)));
+ QObject::connect(&m_lineEditCoord, SIGNAL(returnPressed()),
+ this, SLOT(lineEditCoord_returnPressed()));
+ QObject::connect(&m_pushButtonPlay, SIGNAL(clicked()),
+ this, SLOT(pushButtonPlay_clicked()));
+ QObject::connect(&m_coordModel, SIGNAL(coordChanged(const Coord&)),
+ this, SLOT(updateCoord(const Coord&)));
+}
+
+
+void PlayWordMediator::lineEditPlay_textChanged()
+{
+ m_pushButtonPlay.setEnabled(m_lineEditPlay.hasAcceptableInput() &&
+ m_lineEditCoord.hasAcceptableInput());
+}
+
+
+void PlayWordMediator::lineEditPlay_returnPressed()
+{
+ if (!m_lineEditPlay.hasAcceptableInput() ||
+ !m_lineEditCoord.hasAcceptableInput())
+ return;
+
+ // Convert the jokers to lowercase
+ QString word = m_lineEditPlay.text().toUpper();
+ int pos;
+ while ((pos = word.indexOf('(')) != -1)
+ {
+ if (word.size() < pos + 3 || word[pos + 2] != ')' ||
+ !m_game->getDic().validateLetters(qtw(QString(word[pos + 1]))))
+ {
+ // Bug in validate()!
+ // This should never happen
+ QString msg = _q("Cannot play word: misplaced parentheses");
+ emit notifyProblem(msg);
+ break;
+ }
+ else
+ {
+ QChar chr = word[pos + 1].toLower();
+ word.remove(pos, 3);
+ word.insert(pos, chr);
+ }
+ }
+
+ QString coords = m_lineEditCoord.text();
+ int res = m_game->play(qtw(word), qtw(coords));
+ if (res == 0)
+ {
+ emit gameUpdated();
+ m_lineEditPlay.setFocus();
+ }
+ else
+ {
+ // Try to be as explicit as possible concerning the error
+ QString msg = _q("Cannot play '%1' at position '%2':\n")
+ .arg(m_lineEditPlay.text()).arg(coords);
+ switch (res)
+ {
+ case 1:
+ msg += _q("Some letters are not valid for the current
dictionary");
+ break;
+ case 2:
+ msg += _q("Invalid coordinates");
+ break;
+ case 3:
+ msg += _q("The word does not exist");
+ break;
+ case 4:
+ msg += _q("The rack doesn't contain the letters needed to play
this word");
+ break;
+ case 5:
+ msg += _q("The word is part of a longer one");
+ break;
+ case 6:
+ msg += _q("The word tries to replace an existing letter");
+ break;
+ case 7:
+ msg += _q("An orthogonal word is not valid");
+ break;
+ case 8:
+ msg += _q("The word is already present on the board at these
coordinates");
+ break;
+ case 9:
+ msg += _q("A word cannot be isolated (not connected to the
placed words)");
+ break;
+ case 10:
+ msg += _q("The first word of the game must be horizontal");
+ break;
+ case 11:
+ msg += _q("The first word of the game must cover the H8
square");
+ break;
+ case 12:
+ msg += _q("The word is going out of the board");
+ break;
+ default:
+ msg += _q("Incorrect or misplaced word (%1)").arg(1);
+ }
+ // FIXME: the error is too generic
+ emit notifyProblem(msg);
+ }
+}
+
+
+void PlayWordMediator::lineEditCoord_textChanged(const QString &iText)
+{
+ Coord c(qtw(iText));
+ if (!(m_coordModel.getCoord() == c))
+ m_coordModel.setCoord(Coord(qtw(iText)));
+ lineEditPlay_textChanged();
+}
+
+
+void PlayWordMediator::updateCoord(const Coord &iCoord)
+{
+ if (iCoord.isValid() && m_lineEditCoord.text() != qfw(iCoord.toString()))
+ m_lineEditCoord.setText(qfw(iCoord.toString()));
+ else if (!iCoord.isValid() && m_lineEditCoord.hasAcceptableInput())
+ m_lineEditCoord.setText("");
+ lineEditPlay_textChanged();
+}
+
+
+// ------ Validators ------
+
+PlayWordValidator::PlayWordValidator(QObject *parent,
+ const Dictionary &iDic)
+ : QValidator(parent), m_dic(iDic)
+{
+}
+
+
+QValidator::State PlayWordValidator::validate(QString &input, int &) const
+{
+ if (input == "")
+ return Intermediate;
+
+ QString copy(input);
+ // Strip parentheses
+ copy.remove('(');
+ copy.remove(')');
+ // The string is invalid if it contains characters not present
+ // in the dictionary
+ if (!m_dic.validateLetters(qtw(copy)) || copy.contains('?'))
+ return Invalid;
+
+ // Check the parentheses pairs
+ copy = input;
+ int pos;
+ while ((pos = copy.indexOf('(')) != -1)
+ {
+ if (copy.size() < pos + 3 || copy[pos + 2] != ')' ||
+ !m_dic.validateLetters(qtw(QString(copy[pos + 1]))))
+ {
+ return Intermediate;
+ }
+ else
+ {
+ copy.remove(pos, 3);
+ }
+ }
+ if (copy.indexOf(')') != -1)
+ return Intermediate;
+
+ return Acceptable;
+}
+
+
+
+CoordsValidator::CoordsValidator(QObject *parent)
+ : QValidator(parent)
+{
+}
+
+
+QValidator::State CoordsValidator::validate(QString &input, int &) const
+{
+ // Only authorize characters part of a valid coordinate
+ wstring copy = qtw(input.toUpper());
+ wstring authorized = L"ABCDEFGHIJKLMNO1234567890";
+ if (copy.find_first_not_of(authorized) != wstring::npos)
+ return Invalid;
+
+ // Check coordinates
+ Coord c(qtw(input));
+ if (!c.isValid())
+ return Intermediate;
+
+ return Acceptable;
+}
+
+
Index: qt/play_word_mediator.h
===================================================================
RCS file: qt/play_word_mediator.h
diff -N qt/play_word_mediator.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ qt/play_word_mediator.h 19 Feb 2009 18:25:19 -0000 1.1
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2008 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ *****************************************************************************/
+
+#ifndef VALIDATORS_H_
+#define VALIDATORS_H_
+
+#include <QtGui/QValidator>
+
+
+class QLineEdit;
+class QPushButton;
+class PublicGame;
+class Coord;
+class CoordModel;
+class Dictionary;
+
+/**
+ * Mediator handling the connections between the controls used to play a word.
+ * The controls are:
+ * - a QLineEdit for the played word
+ * - a QLineEdit for the coordinates
+ * - a Play button to really play the word
+ *
+ * All the logic between these controls is handled by the mediator, as long as
+ * it is alive (same lifetime as the controls themselves).
+ * Note: this class is not a graphical widget, because it would cause problems
+ * to place the controls exactly where wanted in the QGridLayout of the
+ * PlayerWidget class...
+ */
+class PlayWordMediator: public QObject
+{
+ Q_OBJECT;
+
+public:
+ PlayWordMediator(QObject *parent, QLineEdit &iEditWord,
+ QLineEdit &iEditCoord, QPushButton &iButtonPlay,
+ CoordModel &iCoordModel, PublicGame *iGame);
+
+signals:
+ void gameUpdated();
+ void notifyProblem(QString iMsg);
+
+private slots:
+ void lineEditPlay_textChanged();
+ void lineEditPlay_returnPressed();
+ void lineEditCoord_textChanged(const QString &iText);
+ void lineEditCoord_returnPressed() { lineEditPlay_returnPressed(); }
+ void pushButtonPlay_clicked() { lineEditPlay_returnPressed(); }
+ void updateCoord(const Coord &iNewCoord);
+
+private:
+ PublicGame *m_game;
+ QLineEdit &m_lineEditPlay;
+ QLineEdit &m_lineEditCoord;
+ QPushButton &m_pushButtonPlay;
+ CoordModel &m_coordModel;
+};
+
+#endif
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Eliot-dev] eliot game/coord.cpp game/coord.h game/Makefile...,
Olivier Teulière <=