Generate the dictionary from the wizard, and (optinally) load it.

The wizard is now fully usable.
This commit is contained in:
Olivier Teulière 2010-05-15 12:20:19 +00:00
parent 9d5c9fe1d0
commit 80ca8844d9
9 changed files with 236 additions and 112 deletions

View file

@ -43,6 +43,7 @@ EXTRA_DIST = \
ui/dic_tools_widget.ui \ ui/dic_tools_widget.ui \
ui/dic_wizard_info_page.ui \ ui/dic_wizard_info_page.ui \
ui/dic_wizard_letters_def_page.ui \ ui/dic_wizard_letters_def_page.ui \
ui/dic_wizard_conclusion_page.ui \
ui/main_window.ui \ ui/main_window.ui \
ui/new_game.ui \ ui/new_game.ui \
ui/player_widget.ui \ ui/player_widget.ui \
@ -79,6 +80,7 @@ nodist_eliot_SOURCES = \
ui/dic_tools_widget.ui.h \ ui/dic_tools_widget.ui.h \
ui/dic_wizard_info_page.ui.h \ ui/dic_wizard_info_page.ui.h \
ui/dic_wizard_letters_def_page.ui.h \ ui/dic_wizard_letters_def_page.ui.h \
ui/dic_wizard_conclusion_page.ui.h \
coord_model.moc.cpp \ coord_model.moc.cpp \
new_game.moc.cpp \ new_game.moc.cpp \
dic_tools_widget.moc.cpp \ dic_tools_widget.moc.cpp \

View file

@ -328,6 +328,12 @@ void DicToolsWidget::refreshDicInfo()
tmp += inputVect[i] + L" "; tmp += inputVect[i] + L" ";
} }
model->setData(model->index(rowNum, 5), qfw(tmp)); model->setData(model->index(rowNum, 5), qfw(tmp));
// Center the text in the column
for (int col = 0; col < 5; ++col)
{
model->item(rowNum, col)->setTextAlignment(Qt::AlignCenter);
}
++rowNum; ++rowNum;
} }
treeViewDicLetters->resizeColumnToContents(0); treeViewDicLetters->resizeColumnToContents(0);

View file

@ -21,6 +21,7 @@
#include <iostream> #include <iostream>
#include <QtGui/QLabel> #include <QtGui/QLabel>
#include <QtGui/QSpinBox>
#include <QtGui/QVBoxLayout> #include <QtGui/QVBoxLayout>
#include <QtGui/QFileDialog> #include <QtGui/QFileDialog>
#include <QtGui/QStandardItemModel> #include <QtGui/QStandardItemModel>
@ -32,6 +33,8 @@
#include "dic_wizard.h" #include "dic_wizard.h"
#include "qtcommon.h" #include "qtcommon.h"
#include "compdic.h"
#include "dic_exception.h"
using namespace std; using namespace std;
@ -170,7 +173,7 @@ WizardLettersDefPage::WizardLettersDefPage(QWidget *parent) : QWizardPage(parent
setupUi(this); setupUi(this);
setTitle(_q("Letters characteristics")); setTitle(_q("Letters characteristics"));
labelTableDesc->setText(_q("The table below lists all the letters found in the word list (plus the joker). " labelDesc->setText(_q("The table below lists all the letters found in the word list (plus the joker). "
"For each letter, you need to define:\n" "For each letter, you need to define:\n"
" - its number of points;\n" " - its number of points;\n"
" - its frequency (number of occurrences in the game);\n" " - its frequency (number of occurrences in the game);\n"
@ -187,19 +190,12 @@ WizardLettersDefPage::WizardLettersDefPage(QWidget *parent) : QWizardPage(parent
m_model->setHeaderData(2, Qt::Horizontal, _q("Frequency"), Qt::DisplayRole); m_model->setHeaderData(2, Qt::Horizontal, _q("Frequency"), Qt::DisplayRole);
m_model->setHeaderData(3, Qt::Horizontal, _q("Vowel?"), Qt::DisplayRole); m_model->setHeaderData(3, Qt::Horizontal, _q("Vowel?"), Qt::DisplayRole);
m_model->setHeaderData(4, Qt::Horizontal, _q("Consonant?"), Qt::DisplayRole); m_model->setHeaderData(4, Qt::Horizontal, _q("Consonant?"), Qt::DisplayRole);
tableLetters->setModel(m_model);
treeLetters->setModel(m_model); treeLetters->setModel(m_model);
treeLetters->header()->setDefaultAlignment(Qt::AlignCenter); treeLetters->header()->setDefaultAlignment(Qt::AlignCenter);
treeLetters->setItemDelegate(new LettersDelegate);
connect(buttonLoadLetters, SIGNAL(clicked(bool)), connect(buttonLoadLetters, SIGNAL(clicked(bool)),
this, SLOT(loadLettersFromWordList())); this, SLOT(loadLettersFromWordList()));
connect(buttonRemoveLetter, SIGNAL(clicked(bool)),
this, SLOT(removeLetter()));
// Enable the Remove button only when there is a selection in the tree
connect(treeLetters->selectionModel(),
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
this,
SLOT(enableRemoveButton(const QItemSelection&)));
} }
@ -233,8 +229,8 @@ void WizardLettersDefPage::loadLettersFromWordList()
if (!res) if (!res)
return; return;
m_model->setData(m_model->index(rowNum, 0), ch); m_model->setData(m_model->index(rowNum, 0), ch);
m_model->setData(m_model->index(rowNum, 1), 0); m_model->setData(m_model->index(rowNum, 1), 1);
m_model->setData(m_model->index(rowNum, 2), 0); m_model->setData(m_model->index(rowNum, 2), 1);
m_model->setData(m_model->index(rowNum, 3), m_model->setData(m_model->index(rowNum, 3),
(bool)QString("AEIOUY").contains(ch)); (bool)QString("AEIOUY").contains(ch));
m_model->setData(m_model->index(rowNum, 4), m_model->setData(m_model->index(rowNum, 4),
@ -246,7 +242,7 @@ void WizardLettersDefPage::loadLettersFromWordList()
bool res = m_model->insertRow(rowNum); bool res = m_model->insertRow(rowNum);
if (!res) if (!res)
return; return;
m_model->setData(m_model->index(rowNum, 0), QString(_q("? (joker)"))); m_model->setData(m_model->index(rowNum, 0), QChar('?'));
m_model->setData(m_model->index(rowNum, 1), 0); m_model->setData(m_model->index(rowNum, 1), 0);
m_model->setData(m_model->index(rowNum, 2), 2); m_model->setData(m_model->index(rowNum, 2), 2);
m_model->setData(m_model->index(rowNum, 3), true); m_model->setData(m_model->index(rowNum, 3), true);
@ -264,46 +260,29 @@ void WizardLettersDefPage::loadLettersFromWordList()
} }
void WizardLettersDefPage::enableRemoveButton(const QItemSelection &iSelected) // ---------- WizardConclusionPage ----------
WizardConclusionPage::WizardConclusionPage(QWidget *parent) : QWizardPage(parent)
{ {
// Enable the "Remove" button iff at least one line in the tree view setupUi(this);
// is selected
buttonRemoveLetter->setEnabled(!iSelected.indexes().empty());
} }
void WizardLettersDefPage::removeLetter() void WizardConclusionPage::initializePage()
{ {
QModelIndexList indexList = treeLetters->selectionModel()->selectedIndexes(); setTitle(_q("Conclusion"));
if (indexList.empty())
return;
// Warn the user of the consequences // This code must not be in the constructor, because the call to wizard()
QString msg = _q("If you remove this letter, the only way to play words " // supposes that the page is already associated with the wizard
"containing this letter will be to use the joker tile(s). " // (and thus already constructed)
"This might be wanted in some rare cases, but it is " QString finishText = wizard()->buttonText(QWizard::FinishButton);
"usually better to remove the words containing the " finishText.remove('&');
"unwanted letter from the word list."); labelDesc->setText(_q("Click %1 to generate the dictionary.\n\n").arg(finishText) +
QMessageBox confoBox(QMessageBox::Warning, _q("Eliot"), msg, QString("You may now load it in Eliot using the checkbox below.\n"
QMessageBox::Yes | QMessageBox::No, this); "You can also load it later manually, using the "
confoBox.setInformativeText(_q("Do you really want to continue?")); "'Settings -> Change dictionary...' menu option."));
confoBox.setDefaultButton(QMessageBox::Yes);
confoBox.setEscapeButton(QMessageBox::No);
int ret = confoBox.exec();
if (ret != QMessageBox::Yes)
return;
m_model->removeRow(indexList.front().row()); registerField("loadDic", checkBoxLoadDic);
}
bool WizardLettersDefPage::isComplete() const
{
if (!QWizardPage::isComplete())
return false;
// TODO
return true;
} }
@ -314,7 +293,73 @@ DicWizard::DicWizard(QWidget *parent)
{ {
setOption(QWizard::IndependentPages); setOption(QWizard::IndependentPages);
addPage(new WizardInfoPage); addPage(new WizardInfoPage);
addPage(new WizardLettersDefPage()); m_lettersPageId = addPage(new WizardLettersDefPage());
// TODO addPage(new WizardConclusionPage());
setWindowTitle(_q("Dictionary creation"));
}
void DicWizard::accept()
{
CompDic builder;
try {
// Retrieve the letters model
const QStandardItemModel *model =
static_cast<WizardLettersDefPage*>(page(m_lettersPageId))->getModel();
// Define the letters
for (int i = 0; i < model->rowCount(); ++i)
{
QString letter = model->data(model->index(i, 0)).toString();
int points = model->data(model->index(i, 1)).toInt();
int frequency = model->data(model->index(i, 2)).toInt();
bool isVowel = model->data(model->index(i, 3)).toBool();
bool isConsonant = model->data(model->index(i, 4)).toBool();
wstring wstr = qtw(letter);
if (wstr.size() != 1)
throw DicException("Invalid letter '" + qtl(letter) + "'");
builder.addLetter(wstr[0], points, frequency,
isVowel, isConsonant, vector<wstring>());
}
// Build the dictionary
builder.generateDawg(qtl(field("wordList").toString()),
qtl(field("genDic").toString()),
qtl(field("dicName").toString()));
}
catch (std::exception &e)
{
QMessageBox::warning(this, _q("Eliot - Error"), e.what());
return;
}
emit infoMsg(_q("Dictionary successfully created"));
bool shouldLoad = field("loadDic").toBool();
if (shouldLoad)
{
emit loadDictionary(field("genDic").toString());
}
QDialog::accept();
}
// ---------- LettersDelegate ----------
QWidget * LettersDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
// For integer columns, bound the values in the [0, 20] range
QWidget * editor = QStyledItemDelegate::createEditor(parent, option, index);
if (editor->inherits("QSpinBox"))
{
static_cast<QSpinBox*>(editor)->setMinimum(0);
static_cast<QSpinBox*>(editor)->setMaximum(20);
}
return editor;
} }

View file

@ -23,12 +23,16 @@
#include <QtGui/QWizard> #include <QtGui/QWizard>
#include <QtGui/QWizardPage> #include <QtGui/QWizardPage>
#include <QtGui/QStyledItemDelegate>
#include "ui/dic_wizard_info_page.ui.h" #include "ui/dic_wizard_info_page.ui.h"
#include "ui/dic_wizard_letters_def_page.ui.h" #include "ui/dic_wizard_letters_def_page.ui.h"
#include "ui/dic_wizard_conclusion_page.ui.h"
class QStandardItemModel; class QStandardItemModel;
class QItemSelection; class QItemSelection;
class QStyleOptionViewItem;
class QModelIndex;
class DicWizard: public QWizard class DicWizard: public QWizard
{ {
@ -36,9 +40,14 @@ class DicWizard: public QWizard
public: public:
DicWizard(QWidget *parent); DicWizard(QWidget *parent);
virtual void accept();
private: private:
QWizardPage *createLettersDefPage() const; int m_lettersPageId;
signals:
void loadDictionary(QString dawgFile);
void infoMsg(QString message);
}; };
@ -61,17 +70,37 @@ class WizardLettersDefPage: public QWizardPage, private Ui::WizardLettersDefPage
Q_OBJECT Q_OBJECT
public: public:
explicit WizardLettersDefPage(QWidget *parent = 0); explicit WizardLettersDefPage(QWidget *parent = 0);
virtual bool isComplete() const; const QStandardItemModel * getModel() const { return m_model; }
private: private:
QStandardItemModel *m_model; QStandardItemModel *m_model;
private slots: private slots:
void loadLettersFromWordList(); void loadLettersFromWordList();
void enableRemoveButton(const QItemSelection &);
void removeLetter();
}; };
class WizardConclusionPage: public QWizardPage, private Ui::WizardConclusionPage
{
Q_OBJECT
public:
explicit WizardConclusionPage(QWidget *parent = 0);
virtual void initializePage();
};
class LettersDelegate: public QStyledItemDelegate
{
Q_OBJECT;
public:
explicit LettersDelegate(QWidget *parent = 0)
: QStyledItemDelegate(parent) {}
virtual QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
};
#endif #endif

View file

@ -170,6 +170,7 @@ MainWindow::MainWindow(QWidget *iParent)
{ {
displayErrorMsg(_q("Cannot load dictionary '%1' indicated in the " displayErrorMsg(_q("Cannot load dictionary '%1' indicated in the "
"preferences.\nReason: %2").arg(dicPath).arg(e.what())); "preferences.\nReason: %2").arg(dicPath).arg(e.what()));
return;
} }
} }
emit dicChanged(m_dic); emit dicChanged(m_dic);
@ -352,6 +353,45 @@ void MainWindow::readSettings()
} }
void MainWindow::changeDictionary(QString iFileName)
{
if (!iFileName.isEmpty())
{
if (m_game)
{
QString msg = _q("Loading a dictionary will stop the current game.");
QMessageBox confirmationBox(QMessageBox::Question, _q("Eliot"), msg,
QMessageBox::Yes | QMessageBox::No, this);
confirmationBox.setInformativeText(_q("Do you want to continue?"));
confirmationBox.setDefaultButton(QMessageBox::Yes);
confirmationBox.setEscapeButton(QMessageBox::No);
int res = confirmationBox.exec();
if (res == QMessageBox::No)
return;
}
destroyCurrentGame();
try
{
Dictionary *dic = new Dictionary(qtl(iFileName));
delete m_dic;
m_dic = dic;
emit dicChanged(m_dic);
displayInfoMsg(_q("Loaded dictionary '%1'").arg(iFileName));
// Save the location of the dictionary in the preferences
QSettings qs(ORGANIZATION, PACKAGE_NAME);
qs.setValue(PrefsDialog::kINTF_DIC_PATH, iFileName);
}
catch (std::exception &e)
{
displayErrorMsg(e.what());
}
}
}
QAction * MainWindow::addMenuAction(QMenu *menu, QString iText, QAction * MainWindow::addMenuAction(QMenu *menu, QString iText,
const QKeySequence &iShortcut, const QKeySequence &iShortcut,
QString iStatusTip, const char *iMember, QString iStatusTip, const char *iMember,
@ -705,42 +745,9 @@ void MainWindow::onSettingsPreferences()
void MainWindow::onSettingsChooseDic() void MainWindow::onSettingsChooseDic()
{ {
if (m_game)
{
QString msg = _q("Loading a dictionary will stop the current game.");
QMessageBox confirmationBox(QMessageBox::Question, _q("Eliot"), msg,
QMessageBox::Yes | QMessageBox::No, this);
confirmationBox.setInformativeText(_q("Do you want to continue?"));
confirmationBox.setDefaultButton(QMessageBox::Yes);
confirmationBox.setEscapeButton(QMessageBox::No);
int res = confirmationBox.exec();
if (res == QMessageBox::No)
return;
}
QString fileName = QString fileName =
QFileDialog::getOpenFileName(this, _q("Choose a dictionary"), "", "*.dawg"); QFileDialog::getOpenFileName(this, _q("Choose a dictionary"), "", "*.dawg");
if (!fileName.isEmpty()) changeDictionary(fileName);
{
destroyCurrentGame();
try
{
Dictionary *dic = new Dictionary(qtl(fileName));
delete m_dic;
m_dic = dic;
emit dicChanged(m_dic);
displayInfoMsg(_q("Loaded dictionary '%1'").arg(fileName));
// Save the location of the dictionary in the preferences
QSettings qs(ORGANIZATION, PACKAGE_NAME);
qs.setValue(PrefsDialog::kINTF_DIC_PATH, fileName);
}
catch (std::exception &e)
{
displayErrorMsg(e.what());
}
}
} }
@ -749,6 +756,10 @@ void MainWindow::onSettingsCreateDic()
DicWizard *wizard = new DicWizard(this); DicWizard *wizard = new DicWizard(this);
wizard->setWindowTitle(_("Dictionary creation wizard")); wizard->setWindowTitle(_("Dictionary creation wizard"));
wizard->setModal(true); wizard->setModal(true);
connect(wizard, SIGNAL(infoMsg(QString)),
this, SLOT(displayInfoMsg(QString)));
connect(wizard, SIGNAL(loadDictionary(QString)),
this, SLOT(changeDictionary(QString)));
wizard->show(); wizard->show();
} }

View file

@ -83,6 +83,9 @@ private slots:
void onHistoryLastTurn(); void onHistoryLastTurn();
void onHistoryReplayTurn(); void onHistoryReplayTurn();
/** Load a new dictionary */
void changeDictionary(QString);
/** Perform some updates when the game is updated */ /** Perform some updates when the game is updated */
void refresh(); void refresh();

View file

@ -207,6 +207,9 @@
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated"> <property name="rootIsDecorated">
<bool>false</bool> <bool>false</bool>
</property> </property>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WizardConclusionPage</class>
<widget class="QWizardPage" name="WizardConclusionPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="labelDesc">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxLoadDic">
<property name="text">
<string>_(&quot;Load this dictionary in Eliot&quot;)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>231</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -15,7 +15,7 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QLabel" name="labelTableDesc"> <widget class="QLabel" name="labelDesc">
<property name="text"> <property name="text">
<string>Description</string> <string>Description</string>
</property> </property>
@ -46,16 +46,6 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QPushButton" name="buttonRemoveLetter">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>_(&quot;Remove Letter&quot;)</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -71,22 +61,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QTableView" name="tableLetters">
<property name="editTriggers">
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>