eliot/qt/new_game.cpp
Olivier Teulière 52b7363888 Players are not created by the Game object anymore but by the user of the class.
This allows more flexibility, in particular to choose the type of player or its name.
2008-01-28 19:17:33 +00:00

255 lines
8.1 KiB
C++

/*****************************************************************************
* 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
*****************************************************************************/
#include <QtGui/QStandardItemModel>
#include <QtGui/QKeyEvent>
#include <QtGui/QMessageBox>
#include "new_game.h"
#include "qtcommon.h"
#include "game_factory.h"
#include "game.h"
#include "training.h"
#include "freegame.h"
#include "duplicate.h"
#include "player.h"
#include "ai_percent.h"
const QString NewGame::kHUMAN = _q("Human");
const QString NewGame::kAI = _q("AI");
NewGame::NewGame(QWidget *iParent)
: QDialog(iParent)
{
setupUi(this);
// Initialize the model of the default players
m_model = new QStandardItemModel(2, 2, this);
m_model->setHeaderData(0, Qt::Horizontal, _q("Name"), Qt::DisplayRole);
m_model->setHeaderData(1, Qt::Horizontal, _q("Type"), Qt::DisplayRole);
m_model->setData(m_model->index(0, 0), _q("HumanPlayer"));
m_model->setData(m_model->index(0, 1), kHUMAN);
m_model->setData(m_model->index(1, 0), _q("Eliot"));
m_model->setData(m_model->index(1, 1), kAI);
// Initialize the QTreeView with the model we just created
treeViewPlayers->setModel(m_model);
PlayersDelegate *delegate = new PlayersDelegate(this);
treeViewPlayers->setItemDelegateForColumn(1, delegate);
// Enable the Remove button only when there is a selection in the tree
QObject::connect(treeViewPlayers->selectionModel(),
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
this,
SLOT(enableRemoveButton(const QItemSelection&, const QItemSelection&)));
// Enable the Ok button only when if there are enough players for the
// current mode
QObject::connect(m_model, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
this, SLOT(enableOkButton()));
QObject::connect(m_model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
this, SLOT(enableOkButton()));
QObject::connect(comboBoxMode, SIGNAL(currentIndexChanged(int)),
this, SLOT(enableOkButton()));
// Install a custom event filter, to remove the selection when the
// "Delete" key is pressed
PlayersEventFilter *filter = new PlayersEventFilter(this);
treeViewPlayers->installEventFilter(filter);
QObject::connect(filter, SIGNAL(deletePressed()),
this, SLOT(on_pushButtonRemove_clicked()));
}
Game * NewGame::createGame(const Dictionary &iDic) const
{
// Create the game
Game *game = NULL;
if (comboBoxMode->currentText() == _q("Training"))
game = GameFactory::Instance()->createTraining(iDic);
else if (comboBoxMode->currentText() == _q("Free game"))
game = GameFactory::Instance()->createFreeGame(iDic);
else
game = GameFactory::Instance()->createDuplicate(iDic);
// Add the players
if (comboBoxMode->currentText() != _q("Training"))
{
set<QString> allNames;
for (int num = 0; num < m_model->rowCount(); ++num)
{
QString name = m_model->data(m_model->index(num, 0)).toString();
if (name == "")
name = _q("Player %1").arg(num + 1);
// Ensure unicity of the players names
if (allNames.find(name) != allNames.end())
{
int n = 2;
while (allNames.find(name + QString(" (%1)").arg(n)) != allNames.end())
{
++n;
}
name += QString(" (%1)").arg(n);
}
allNames.insert(name);
QString type = m_model->data(m_model->index(num, 1)).toString();
Player *player;
if (type == kHUMAN)
player = new HumanPlayer;
else
player = new AIPercent(1);
player->setName(qtw(name));
game->addPlayer(player);
}
}
else
{
const_cast<Player *>(&game->getPlayer(0))->setName(qtw(_q("Training")));
}
// Joker game?
if (checkBoxJoker->isChecked())
game->setVariant(Game::kJOKER);
return game;
}
void NewGame::enableOkButton()
{
// Enable the "Ok" button:
// - always in training mode
// - if there is at least one player in duplicate mode
// - if there are at least 2 players in free game mode
bool disable =
(comboBoxMode->currentText() == _q("Duplicate") && m_model->rowCount() < 1) ||
(comboBoxMode->currentText() == _q("Free game") && m_model->rowCount() < 2);
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!disable);
}
void NewGame::enableRemoveButton(const QItemSelection &iSelected,
const QItemSelection &)
{
// Enable the "Remove" button iff at least one line in the tree view
// is selected
pushButtonRemove->setEnabled(!iSelected.indexes().empty());
}
void NewGame::on_comboBoxMode_activated(int iIndex)
{
groupBoxPlayers->setEnabled(iIndex != 2);
}
void NewGame::on_pushButtonAdd_clicked()
{
// Add a new row
int rowNum = m_model->rowCount();
bool res = m_model->insertRow(rowNum);
if (!res)
return;
// Change the contents of the row
m_model->setData(m_model->index(rowNum, 0), lineEditName->displayText());
m_model->setData(m_model->index(rowNum, 1), comboBoxType->currentText());
}
void NewGame::on_pushButtonRemove_clicked()
{
QModelIndexList indexList = treeViewPlayers->selectionModel()->selectedIndexes();
if (indexList.empty())
return;
m_model->removeRow(indexList.front().row());
}
PlayersDelegate::PlayersDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
QWidget *PlayersDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex &) const
{
QComboBox *editor = new QComboBox(parent);
editor->addItem(NewGame::kHUMAN);
editor->addItem(NewGame::kAI);
return editor;
}
void PlayersDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QComboBox *combo = static_cast<QComboBox*>(editor);
QString text = index.model()->data(index, Qt::DisplayRole).toString();
combo->setCurrentIndex(combo->findText(text));
}
void PlayersDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox *combo = static_cast<QComboBox*>(editor);
model->setData(index, combo->currentText());
}
void PlayersDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &) const
{
editor->setGeometry(option.rect);
}
PlayersEventFilter::PlayersEventFilter(QObject *parent)
: QObject(parent)
{
}
bool PlayersEventFilter::eventFilter(QObject *obj, QEvent *event)
{
// If the Delete key is pressed, remove the selected line, if any
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Delete)
{
emit deletePressed();
return true;
}
}
// Standard event processing
return QObject::eventFilter(obj, event);
}