Qt interface:

- Initialize the random numbers generator, and print the seed value
 - Handle properly Qt builds without STL support
 - Save the position of the main window
 - Got rid of the useless toolbar
 - Better size of the preferences dialog
 - Hopefully fixed translation issues on Windows
 - The Settings class throws an exception when asked for a non-existing setting
This commit is contained in:
Olivier Teulière 2008-09-05 21:31:30 +00:00
parent f5bde7fb4e
commit 990f4c5212
16 changed files with 304 additions and 106 deletions

View file

@ -45,7 +45,7 @@
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
// For ntohl & Co. // For htonl & Co.
#ifdef WIN32 #ifdef WIN32
# include <winsock2.h> # include <winsock2.h>
#else #else
@ -63,6 +63,9 @@
#else #else
# define _(String) String # define _(String) String
#endif #endif
#ifdef WIN32
# include <windows.h>
#endif
#include "hashtable.h" #include "hashtable.h"
#include "encoding.h" #include "encoding.h"
@ -438,7 +441,17 @@ int main(int argc, char* argv[])
#if ENABLE_NLS #if ENABLE_NLS
// Set the message domain // Set the message domain
bindtextdomain(PACKAGE, LOCALEDIR); #ifdef WIN32
// Get the absolute path, as returned by GetFullPathName()
char localeDir[MAX_PATH];
GetFullPathName(argv[0], MAX_PATH, localeDir, NULL);
char *pos = strrchr(localeDir, L'\\');
if (pos)
*pos = '\0';
#else
static const char *localeDir = LOCALEDIR;
#endif
bindtextdomain(PACKAGE, localeDir);
textdomain(PACKAGE); textdomain(PACKAGE);
#endif #endif

View file

@ -41,6 +41,9 @@
#else #else
# define _(String) String # define _(String) String
#endif #endif
#ifdef WIN32
# include <windows.h>
#endif
#include "header.h" #include "header.h"
#include "encoding.h" #include "encoding.h"
@ -125,7 +128,17 @@ int main(int argc, char *argv[])
#if ENABLE_NLS #if ENABLE_NLS
// Set the message domain // Set the message domain
bindtextdomain(PACKAGE, LOCALEDIR); #ifdef WIN32
// Get the absolute path, as returned by GetFullPathName()
char localeDir[MAX_PATH];
GetFullPathName(argv[0], MAX_PATH, localeDir, NULL);
char *pos = strrchr(localeDir, L'\\');
if (pos)
*pos = '\0';
#else
static const char *localeDir = LOCALEDIR;
#endif
bindtextdomain(PACKAGE, localeDir);
textdomain(PACKAGE); textdomain(PACKAGE);
#endif #endif

View file

@ -38,6 +38,9 @@
#else #else
# define _(String) String # define _(String) String
#endif #endif
#ifdef WIN32
# include <windows.h>
#endif
#include "dic.h" #include "dic.h"
#include "dic_exception.h" #include "dic_exception.h"
@ -61,7 +64,17 @@ int main(int argc, char* argv[])
#if ENABLE_NLS #if ENABLE_NLS
// Set the message domain // Set the message domain
bindtextdomain(PACKAGE, LOCALEDIR); #ifdef WIN32
// Get the absolute path, as returned by GetFullPathName()
char localeDir[MAX_PATH];
GetFullPathName(argv[0], MAX_PATH, localeDir, NULL);
char *pos = strrchr(localeDir, L'\\');
if (pos)
*pos = '\0';
#else
static const char *localeDir = LOCALEDIR;
#endif
bindtextdomain(PACKAGE, localeDir);
textdomain(PACKAGE); textdomain(PACKAGE);
#endif #endif

View file

@ -1,7 +1,7 @@
ICONV_VERSION = 1.12 ICONV_VERSION = 1.12
WX_VERSION = 2.6.4 WX_VERSION = 2.6.4
BOOST_VERSION = 1_34_1 BOOST_VERSION = 1_34_1
QT_VERSION = 4.3.3 QT_VERSION = 4.4.1
PREFIX = $(shell pwd)/inst PREFIX = $(shell pwd)/inst
WGET = wget -c WGET = wget -c
@ -72,14 +72,14 @@ $(BOOST_DIR):
### Qt ### ### Qt ###
# FIXME: No automated way at the moment :-( # FIXME: No automated way at the moment :-(
QT_ARCHIVE = qt-win-opensource-$(QT_VERSION)-mingw.exe QT_ARCHIVE = qt4-$(QT_VERSION)-win32-bin.tar.bz2
QT_DIR = qt4-$(QT_VERSION)-win32-bin
$(QT_ARCHIVE): $(QT_DIR):
$(WGET) ftp://ftp.trolltech.com/qt/source/qt-win-opensource-4.3.3-mingw.exe $(WGET) http://download.videolan.org/pub/videolan/testing/contrib/$(QT_ARCHIVE)
tar xjf $(QT_ARCHIVE)
.qt: $(QT_ARCHIVE) .qt: $(QT_DIR)
@echo "=============== Important note ===============" (cd $<; mkdir -p $(PREFIX)/bin; mkdir -p $(PREFIX)/include; mkdir -p $(PREFIX)/lib/pkgconfig; rm -f $(PREFIX)/lib/pkgconfig/Qt*; sed 's,@@PREFIX@@,$(PREFIX),' lib/pkgconfig/QtCore.pc.in > $(PREFIX)/lib/pkgconfig/QtCore.pc; sed 's,@@PREFIX@@,$(PREFIX),' lib/pkgconfig/QtGui.pc.in > $(PREFIX)/lib/pkgconfig/QtGui.pc; cp -r include/* $(PREFIX)/include; cp lib/*a $(PREFIX)/lib; mkdir -p $(PREFIX)/share/qt4/translations; cp -r share/translations/* $(PREFIX)/share/qt4/translations)
@echo "You need to install $(QT_ARCHIVE) yourself using wine!"
@echo "=============================================="
touch $@ touch $@

View file

@ -33,6 +33,7 @@ libgame_a_SOURCES= \
duplicate.cpp duplicate.h \ duplicate.cpp duplicate.h \
freegame.cpp freegame.h \ freegame.cpp freegame.h \
game.cpp game.h \ game.cpp game.h \
game_exception.cpp game_exception.h \
game_factory.cpp game_factory.h \ game_factory.cpp game_factory.h \
game_io.cpp \ game_io.cpp \
move.cpp move.h \ move.cpp move.h \

36
game/game_exception.cpp Normal file
View file

@ -0,0 +1,36 @@
/*****************************************************************************
* Eliot
* Copyright (C) 2007 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 "game_exception.h"
using namespace std;
GameException::GameException(const string &iMessage)
: m_message(iMessage)
{
}
const char *GameException::what() const throw()
{
return m_message.c_str();
}

45
game/game_exception.h Normal file
View file

@ -0,0 +1,45 @@
/*****************************************************************************
* Eliot
* Copyright (C) 2007 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 _GAME_EXCEPTION_H_
#define _GAME_EXCEPTION_H_
#include <exception>
#include <string>
/**
* Exception class for the Game library.
* It simply inherits from the standard exception and overrides
* its what() method.
*/
class GameException: public std::exception
{
public:
GameException(const std::string &iMessage);
~GameException() throw() {}
virtual const char *what() const throw();
private:
std::string m_message;
};
#endif

View file

@ -21,6 +21,7 @@
#include <cstdlib> #include <cstdlib>
#include "settings.h" #include "settings.h"
#include "game_exception.h"
Settings *Settings::m_instance = NULL; Settings *Settings::m_instance = NULL;
@ -113,8 +114,7 @@ void Settings::OptionsHandler<T>::setOption(const string &iName, const T &iValue
typename map<string, T>::iterator it = m_options.find(iName); typename map<string, T>::iterator it = m_options.find(iName);
if (it == m_options.end()) if (it == m_options.end())
{ {
// FIXME: throw an exception object instead throw GameException("No such option: " + iName);
throw 1;
} }
it->second = iValue; it->second = iValue;
} }
@ -126,8 +126,7 @@ const T& Settings::OptionsHandler<T>::getOption(const string &iName) const
typename map<string, T>::const_iterator it = m_options.find(iName); typename map<string, T>::const_iterator it = m_options.find(iName);
if (it == m_options.end()) if (it == m_options.end())
{ {
// FIXME: throw an exception object instead throw GameException("No such option: " + iName);
throw 1;
} }
return it->second; return it->second;
} }

View file

@ -24,6 +24,9 @@
#include <QLocale> #include <QLocale>
#include <QTranslator> #include <QTranslator>
#include "main_window.h" #include "main_window.h"
#ifdef WIN32
# include <windows.h>
#endif
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
@ -37,24 +40,33 @@ int main(int argc, char **argv)
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
// Set the message domain // Set the message domain
bindtextdomain(PACKAGE, LOCALEDIR); #ifdef WIN32
// Get the absolute path, as returned by GetFullPathName()
char localeDir[MAX_PATH];
GetFullPathName(argv[0], MAX_PATH, localeDir, NULL);
char *pos = strrchr(localeDir, L'\\');
if (pos)
*pos = '\0';
#else
static const char *localeDir = LOCALEDIR;
#endif
bindtextdomain(PACKAGE, localeDir);
textdomain(PACKAGE); textdomain(PACKAGE);
// Translations for Qt's own strings // Translations for Qt's own strings
QTranslator translator; QTranslator translator;
// Set the path for the translation file // Set the path for the translation file
#if !defined( WIN32 ) #ifdef WIN32
QString path = QString(QT4LOCALEDIR); QString path = localeDir;
#else #else
QString path = QString(LOCALEDIR) + "/qt4/"; QString path = QString(QT4LOCALEDIR);
#endif #endif
QString lang = QLocale::system().name(); QString lang = QLocale::system().name();
translator.load(path + "qt_" + lang); translator.load(path + "/qt_" + lang);
app.installTranslator(&translator); app.installTranslator(&translator);
#endif #endif
MainWindow qmain; MainWindow qmain;
qmain.move(200, 200);
qmain.show(); qmain.show();
return app.exec(); return app.exec();
} }

View file

@ -60,12 +60,29 @@
#include "coord.h" #include "coord.h"
const char *MainWindow::m_windowName = "MainWindow";
MainWindow::MainWindow(QWidget *iParent) MainWindow::MainWindow(QWidget *iParent)
: QMainWindow(iParent), m_dic(NULL), m_game(NULL), m_newGameDialog(NULL), : QMainWindow(iParent), m_dic(NULL), m_game(NULL), m_newGameDialog(NULL),
m_prefsDialog(NULL), m_bagWindow(NULL), m_boardWindow(NULL), m_prefsDialog(NULL), m_bagWindow(NULL), m_boardWindow(NULL),
m_historyWindow(NULL), m_dicToolsWindow(NULL), m_dicNameLabel(NULL) m_historyWindow(NULL), m_dicToolsWindow(NULL), m_dicNameLabel(NULL)
{ {
m_ui.setupUi(this); m_ui.setupUi(this);
readSettings();
// Initialize the random numbers generator
// Note: This must be done _after_ creating the QMenuBar object,
// because on Gnome QMenuBar calls gconftool2, which for some reason
// calls srand() internally...
// This could be disabled using QApplication::setDesktopSettingsAware(),
// but we would lose the desktop integration...
unsigned int val = time(NULL);
srand(val);
#ifdef DEBUG
// Make it easier to reproduce bugs
cout << "Rand seed: " << val << endl;
#endif
QObject::connect(this, SIGNAL(gameChanged(const Game*)), QObject::connect(this, SIGNAL(gameChanged(const Game*)),
this, SLOT(updateForGame(const Game*))); this, SLOT(updateForGame(const Game*)));
@ -216,7 +233,7 @@ void MainWindow::updateStatusBar(const Dictionary *iDic)
void MainWindow::displayErrorMsg(QString iMsg, QString iContext) void MainWindow::displayErrorMsg(QString iMsg, QString iContext)
{ {
if (iContext == "") if (iContext == "")
iContext = PACKAGE_NAME; iContext = _q("%1 error").arg(PACKAGE_NAME);
QMessageBox::warning(this, iContext, iMsg); QMessageBox::warning(this, iContext, iMsg);
} }
@ -239,10 +256,33 @@ void MainWindow::closeEvent(QCloseEvent *event)
m_historyWindow->close(); m_historyWindow->close();
if (m_dicToolsWindow) if (m_dicToolsWindow)
m_dicToolsWindow->close(); m_dicToolsWindow->close();
writeSettings();
event->accept(); event->accept();
} }
void MainWindow::writeSettings() const
{
QSettings settings(ORGANIZATION, PACKAGE_NAME);
settings.beginGroup(m_windowName);
settings.setValue("size", size());
settings.setValue("pos", pos());
settings.endGroup();
}
void MainWindow::readSettings()
{
QSettings settings(ORGANIZATION, PACKAGE_NAME);
settings.beginGroup(m_windowName);
QSize size = settings.value("size").toSize();
if (size.isValid())
resize(size);
move(settings.value("pos", QPoint(200, 200)).toPoint());
settings.endGroup();
}
void MainWindow::on_action_GameNew_triggered() void MainWindow::on_action_GameNew_triggered()
{ {
if (m_dic == NULL) if (m_dic == NULL)

View file

@ -97,6 +97,8 @@ private:
/// Dialog for the preferences /// Dialog for the preferences
PrefsDialog *m_prefsDialog; PrefsDialog *m_prefsDialog;
static const char * m_windowName;
/// Auxiliary windows /// Auxiliary windows
//@{ //@{
AuxWindow *m_bagWindow; AuxWindow *m_bagWindow;
@ -108,6 +110,11 @@ private:
/// Label indicationg the name of the current dictionary /// Label indicationg the name of the current dictionary
QLabel *m_dicNameLabel; QLabel *m_dicNameLabel;
/// Save window state
void writeSettings() const;
/// Restore window state
void readSettings();
/// Destroy the current game (if any) and the associated widgets /// Destroy the current game (if any) and the associated widgets
void destroyCurrentGame(); void destroyCurrentGame();

View file

@ -22,8 +22,10 @@
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtGui/QFileDialog> #include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>
#include "prefs_dialog.h" #include "prefs_dialog.h"
#include "game_exception.h"
#include "settings.h" #include "settings.h"
@ -36,6 +38,8 @@ PrefsDialog::PrefsDialog(QWidget *iParent)
{ {
setupUi(this); setupUi(this);
try
{
// Interface settings // Interface settings
QSettings qs(ORGANIZATION, PACKAGE_NAME); QSettings qs(ORGANIZATION, PACKAGE_NAME);
checkBoxIntfAlignHistory->setChecked(qs.value(kINTF_ALIGN_HISTORY).toBool()); checkBoxIntfAlignHistory->setChecked(qs.value(kINTF_ALIGN_HISTORY).toBool());
@ -45,6 +49,12 @@ PrefsDialog::PrefsDialog(QWidget *iParent)
checkBoxDuplRefuseInvalid->setChecked(Settings::Instance().getBool("duplicate-reject-invalid")); checkBoxDuplRefuseInvalid->setChecked(Settings::Instance().getBool("duplicate-reject-invalid"));
spinBoxDuplSoloPlayers->setValue(Settings::Instance().getInt("duplicate-solo-players")); spinBoxDuplSoloPlayers->setValue(Settings::Instance().getInt("duplicate-solo-players"));
spinBoxDuplSoloValue->setValue(Settings::Instance().getInt("duplicate-solo-value")); spinBoxDuplSoloValue->setValue(Settings::Instance().getInt("duplicate-solo-value"));
}
catch (GameException &e)
{
QMessageBox::warning(this, _q("%1 error").arg(PACKAGE_NAME),
_q("Cannot load preferences: %1").arg(e.what()));
}
// Freegame settings // Freegame settings
checkBoxFreeRefuseInvalid->setChecked(Settings::Instance().getBool("freegame-reject-invalid")); checkBoxFreeRefuseInvalid->setChecked(Settings::Instance().getBool("freegame-reject-invalid"));
@ -69,6 +79,8 @@ void PrefsDialog::updateSettings()
{ {
bool shouldEmitUpdate = false; bool shouldEmitUpdate = false;
try
{
// Interface settings // Interface settings
QSettings qs(ORGANIZATION, PACKAGE_NAME); QSettings qs(ORGANIZATION, PACKAGE_NAME);
if (qs.value(kINTF_ALIGN_HISTORY).toBool() != checkBoxIntfAlignHistory->isChecked()) if (qs.value(kINTF_ALIGN_HISTORY).toBool() != checkBoxIntfAlignHistory->isChecked())
@ -93,6 +105,12 @@ void PrefsDialog::updateSettings()
// Training settings // Training settings
}
catch (GameException &e)
{
QMessageBox::warning(this, _q("%1 error").arg(PACKAGE_NAME),
_q("Cannot save preferences: %1").arg(e.what()));
}
if (shouldEmitUpdate) if (shouldEmitUpdate)
emit gameUpdated(); emit gameUpdated();

View file

@ -22,6 +22,7 @@
#define QT_COMMON_H_ #define QT_COMMON_H_
#include "config.h" #include "config.h"
#include <QtCore/QString>
#if ENABLE_NLS #if ENABLE_NLS
# include <libintl.h> # include <libintl.h>
@ -40,7 +41,7 @@
#define qfl(s) QString::fromLocal8Bit(s) #define qfl(s) QString::fromLocal8Bit(s)
#define qtl(s) (s).toLocal8Bit().data() #define qtl(s) (s).toLocal8Bit().data()
// Convert to/from std::wstring // Convert to/from std::wstring
#ifdef WIN32 #ifdef QT_NO_STL
# include "encoding.h" # include "encoding.h"
# define qfw(s) qfl(convertToMb(s).c_str()) # define qfw(s) qfl(convertToMb(s).c_str())
# define qtw(s) convertToWc(qtl(s)) # define qtw(s) convertToWc(qtl(s))

View file

@ -20,9 +20,9 @@
<property name="geometry" > <property name="geometry" >
<rect> <rect>
<x>0</x> <x>0</x>
<y>37</y> <y>26</y>
<width>747</width> <width>747</width>
<height>557</height> <height>568</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" > <layout class="QVBoxLayout" >
@ -126,25 +126,6 @@
</rect> </rect>
</property> </property>
</widget> </widget>
<widget class="QToolBar" name="toolBar" >
<property name="geometry" >
<rect>
<x>0</x>
<y>26</y>
<width>747</width>
<height>11</height>
</rect>
</property>
<property name="windowTitle" >
<string>toolBar</string>
</property>
<attribute name="toolBarArea" >
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak" >
<bool>false</bool>
</attribute>
</widget>
<action name="action_SettingsChooseDic" > <action name="action_SettingsChooseDic" >
<property name="text" > <property name="text" >
<string>_("Choose dictionary...")</string> <string>_("Choose dictionary...")</string>

View file

@ -5,7 +5,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>343</width> <width>401</width>
<height>432</height> <height>432</height>
</rect> </rect>
</property> </property>
@ -30,6 +30,12 @@
</item> </item>
<item> <item>
<widget class="QLineEdit" name="lineEditIntfDicPath" > <widget class="QLineEdit" name="lineEditIntfDicPath" >
<property name="minimumSize" >
<size>
<width>130</width>
<height>0</height>
</size>
</property>
<property name="toolTip" > <property name="toolTip" >
<string>_("Enter the dictionary path (mandatory to start a game)")</string> <string>_("Enter the dictionary path (mandatory to start a game)")</string>
</property> </property>

View file

@ -24,6 +24,9 @@
#else #else
# define _(String) String # define _(String) String
#endif #endif
#ifdef WIN32
# include <windows.h>
#endif
#include <ctype.h> #include <ctype.h>
#include <cstring> // For strlen #include <cstring> // For strlen
@ -1118,7 +1121,17 @@ int main(int argc, char ** argv)
#if ENABLE_NLS #if ENABLE_NLS
// Set the message domain // Set the message domain
bindtextdomain(PACKAGE, LOCALEDIR); #ifdef WIN32
// Get the absolute path, as returned by GetFullPathName()
char localeDir[MAX_PATH];
GetFullPathName(argv[0], MAX_PATH, localeDir, NULL);
char *pos = strrchr(localeDir, L'\\');
if (pos)
*pos = '\0';
#else
static const char *localeDir = LOCALEDIR;
#endif
bindtextdomain(PACKAGE, localeDir);
textdomain(PACKAGE); textdomain(PACKAGE);
#endif #endif