mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-30 08:34:16 +01:00
opening saved games and saving of changes now work.
This commit is contained in:
parent
a8014a855b
commit
b61ed7b631
6 changed files with 111 additions and 24 deletions
|
@ -55,29 +55,37 @@ writeToDB( XWStreamCtxt* stream, void* closure )
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
CommonGlobals* cGlobals = (CommonGlobals*)closure;
|
CommonGlobals* cGlobals = (CommonGlobals*)closure;
|
||||||
sqlite3_int64 rowid = cGlobals->rowid;
|
sqlite3_int64 selRow = cGlobals->selRow;
|
||||||
sqlite3* pDb = cGlobals->pDb;
|
sqlite3* pDb = cGlobals->pDb;
|
||||||
XP_U16 len = stream_getSize( stream );
|
XP_U16 len = stream_getSize( stream );
|
||||||
|
char buf[256];
|
||||||
|
char* query;
|
||||||
|
|
||||||
sqlite3_stmt* stmt = NULL;
|
sqlite3_stmt* stmt = NULL;
|
||||||
if ( 0 == rowid ) { /* new row; need to insert blob first */
|
if ( -1 == selRow ) { /* new row; need to insert blob first */
|
||||||
const char* txt = "INSERT INTO games (game) VALUES (?)";
|
query = "INSERT INTO games (game) VALUES (?)";
|
||||||
result = sqlite3_prepare_v2( pDb, txt, -1, &stmt, NULL );
|
} else {
|
||||||
XP_ASSERT( SQLITE_OK == result );
|
const char* fmt = "UPDATE games SET game=? where rowid=%lld";
|
||||||
result = sqlite3_bind_zeroblob( stmt, 1 /*col 0 ??*/, len );
|
snprintf( buf, sizeof(buf), fmt, selRow );
|
||||||
XP_ASSERT( SQLITE_OK == result );
|
query = buf;
|
||||||
result = sqlite3_step( stmt );
|
}
|
||||||
XP_ASSERT( SQLITE_DONE == result );
|
|
||||||
|
|
||||||
rowid = sqlite3_last_insert_rowid( pDb );
|
result = sqlite3_prepare_v2( pDb, query, -1, &stmt, NULL );
|
||||||
XP_LOGF( "%s: new rowid: %lld", __func__, rowid );
|
XP_ASSERT( SQLITE_OK == result );
|
||||||
cGlobals->rowid = rowid;
|
result = sqlite3_bind_zeroblob( stmt, 1 /*col 0 ??*/, len );
|
||||||
sqlite3_finalize( stmt );
|
XP_ASSERT( SQLITE_OK == result );
|
||||||
|
result = sqlite3_step( stmt );
|
||||||
|
XP_ASSERT( SQLITE_DONE == result );
|
||||||
|
|
||||||
|
if ( -1 == selRow ) { /* new row; need to insert blob first */
|
||||||
|
selRow = sqlite3_last_insert_rowid( pDb );
|
||||||
|
XP_LOGF( "%s: new rowid: %lld", __func__, selRow );
|
||||||
|
cGlobals->selRow = selRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_blob* blob;
|
sqlite3_blob* blob;
|
||||||
result = sqlite3_blob_open( pDb, "main", "games", "game",
|
result = sqlite3_blob_open( pDb, "main", "games", "game",
|
||||||
rowid, 1 /*flags: writeable*/, &blob );
|
selRow, 1 /*flags: writeable*/, &blob );
|
||||||
XP_ASSERT( SQLITE_OK == result );
|
XP_ASSERT( SQLITE_OK == result );
|
||||||
const XP_U8* ptr = stream_getPtr( stream );
|
const XP_U8* ptr = stream_getPtr( stream );
|
||||||
result = sqlite3_blob_write( blob, ptr, len, 0 );
|
result = sqlite3_blob_write( blob, ptr, len, 0 );
|
||||||
|
@ -128,3 +136,21 @@ getGameName( GTKGamesGlobals* XP_UNUSED(gg), const sqlite3_int64* rowid,
|
||||||
snprintf( buf, len, "Game %lld", *rowid );
|
snprintf( buf, len, "Game %lld", *rowid );
|
||||||
LOG_RETURNF( "%s", buf );
|
LOG_RETURNF( "%s", buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XP_Bool
|
||||||
|
loadGame( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid )
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
snprintf( buf, sizeof(buf), "SELECT game from games WHERE rowid = %lld", rowid );
|
||||||
|
|
||||||
|
sqlite3_stmt *ppStmt;
|
||||||
|
int result = sqlite3_prepare_v2( pDb, buf, -1, &ppStmt, NULL );
|
||||||
|
XP_ASSERT( SQLITE_OK == result );
|
||||||
|
result = sqlite3_step( ppStmt );
|
||||||
|
XP_ASSERT( SQLITE_ROW == result );
|
||||||
|
const void* ptr = sqlite3_column_blob( ppStmt, 0 );
|
||||||
|
int size = sqlite3_column_bytes( ppStmt, 0 );
|
||||||
|
stream_putBytes( stream, ptr, size );
|
||||||
|
sqlite3_finalize( ppStmt );
|
||||||
|
return XP_TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,6 @@ void writeToDB( XWStreamCtxt* stream, void* closure );
|
||||||
GSList* listGames( GTKGamesGlobals* gg );
|
GSList* listGames( GTKGamesGlobals* gg );
|
||||||
void getGameName( GTKGamesGlobals* gg, const sqlite3_int64* rowid,
|
void getGameName( GTKGamesGlobals* gg, const sqlite3_int64* rowid,
|
||||||
XP_UCHAR* buf, XP_U16 len );
|
XP_UCHAR* buf, XP_U16 len );
|
||||||
|
XP_Bool loadGame( XWStreamCtxt* stream, sqlite3* pDb, sqlite3_int64 rowid );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include "gtkdraw.h"
|
#include "gtkdraw.h"
|
||||||
#include "memstream.h"
|
#include "memstream.h"
|
||||||
#include "filestream.h"
|
#include "filestream.h"
|
||||||
|
#include "gamesdb.h"
|
||||||
|
|
||||||
/* static guint gtkSetupClientSocket( GtkAppGlobals* globals, int sock ); */
|
/* static guint gtkSetupClientSocket( GtkAppGlobals* globals, int sock ); */
|
||||||
static void setCtrlsForTray( GtkAppGlobals* globals );
|
static void setCtrlsForTray( GtkAppGlobals* globals );
|
||||||
|
@ -396,7 +397,8 @@ createOrLoadObjects( GtkAppGlobals* globals )
|
||||||
|
|
||||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||||
#endif
|
#endif
|
||||||
LaunchParams* params = globals->cGlobals.params;
|
CommonGlobals* cGlobals = &globals->cGlobals;
|
||||||
|
LaunchParams* params = cGlobals->params;
|
||||||
|
|
||||||
globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area,
|
globals->draw = (GtkDrawCtx*)gtkDrawCtxtMake( globals->drawing_area,
|
||||||
globals );
|
globals );
|
||||||
|
@ -415,11 +417,19 @@ createOrLoadObjects( GtkAppGlobals* globals )
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( !!params->fileName && file_exists( params->fileName ) ) {
|
if ( !!params->fileName && file_exists( params->fileName ) ) {
|
||||||
stream = streamFromFile( &globals->cGlobals, params->fileName, globals );
|
stream = streamFromFile( cGlobals, params->fileName, globals );
|
||||||
#ifdef USE_SQLITE
|
#ifdef USE_SQLITE
|
||||||
} else if ( !!params->dbFileName && file_exists( params->dbFileName ) ) {
|
} else if ( !!params->dbFileName && file_exists( params->dbFileName ) ) {
|
||||||
stream = streamFromDB( &globals->cGlobals, globals );
|
stream = streamFromDB( cGlobals, globals );
|
||||||
#endif
|
#endif
|
||||||
|
} else if ( !!cGlobals->pDb && 0 <= cGlobals->selRow ) {
|
||||||
|
stream = mem_stream_make( MPPARM(params->util->mpool)
|
||||||
|
params->vtMgr,
|
||||||
|
cGlobals, CHANNEL_NONE, NULL );
|
||||||
|
if ( !loadGame( stream, cGlobals->pDb, cGlobals->selRow ) ) {
|
||||||
|
stream_destroy( stream );
|
||||||
|
stream = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !!stream ) {
|
if ( !!stream ) {
|
||||||
|
@ -2501,6 +2511,8 @@ makeNewGame( GtkAppGlobals* globals )
|
||||||
globals->cGlobals.params->dict =
|
globals->cGlobals.params->dict =
|
||||||
linux_dictionary_make( MEMPOOL globals->cGlobals.params,
|
linux_dictionary_make( MEMPOOL globals->cGlobals.params,
|
||||||
gi->dictName, XP_TRUE );
|
gi->dictName, XP_TRUE );
|
||||||
|
} else {
|
||||||
|
success = XP_FALSE;
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,29 @@
|
||||||
|
|
||||||
enum { ROW_ITEM, NAME_ITEM, N_ITEMS };
|
enum { ROW_ITEM, NAME_ITEM, N_ITEMS };
|
||||||
|
|
||||||
static void
|
/* Prototype for selection handler callback */
|
||||||
init_games_list( GtkWidget* list )
|
static void
|
||||||
|
tree_selection_changed_cb( GtkTreeSelection* selection, gpointer data )
|
||||||
{
|
{
|
||||||
|
LOG_FUNC();
|
||||||
|
GTKGamesGlobals* gg = (GTKGamesGlobals*)data;
|
||||||
|
|
||||||
|
GtkTreeIter iter;
|
||||||
|
GtkTreeModel *model;
|
||||||
|
gchar *row;
|
||||||
|
|
||||||
|
if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) {
|
||||||
|
gtk_tree_model_get( model, &iter, ROW_ITEM, &row, -1 );
|
||||||
|
sscanf( row, "%lld", &gg->selRow );
|
||||||
|
g_print ("You selected row %s (parsed: %lld)\n", row, gg->selRow );
|
||||||
|
g_free( row );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget*
|
||||||
|
init_games_list( GTKGamesGlobals* gg )
|
||||||
|
{
|
||||||
|
GtkWidget* list = gtk_tree_view_new();
|
||||||
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
|
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
|
||||||
GtkTreeViewColumn* column =
|
GtkTreeViewColumn* column =
|
||||||
gtk_tree_view_column_new_with_attributes( "Row", renderer, "text",
|
gtk_tree_view_column_new_with_attributes( "Row", renderer, "text",
|
||||||
|
@ -45,6 +65,13 @@ init_games_list( GtkWidget* list )
|
||||||
G_TYPE_STRING, G_TYPE_STRING );
|
G_TYPE_STRING, G_TYPE_STRING );
|
||||||
gtk_tree_view_set_model( GTK_TREE_VIEW(list), GTK_TREE_MODEL(store) );
|
gtk_tree_view_set_model( GTK_TREE_VIEW(list), GTK_TREE_MODEL(store) );
|
||||||
g_object_unref( store );
|
g_object_unref( store );
|
||||||
|
|
||||||
|
GtkTreeSelection* select =
|
||||||
|
gtk_tree_view_get_selection( GTK_TREE_VIEW (list) );
|
||||||
|
gtk_tree_selection_set_mode( select, GTK_SELECTION_SINGLE );
|
||||||
|
g_signal_connect( G_OBJECT(select), "changed",
|
||||||
|
G_CALLBACK (tree_selection_changed_cb), gg );
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -77,10 +104,25 @@ handle_newgame_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
||||||
} else {
|
} else {
|
||||||
GtkWidget* gameWindow = globals->window;
|
GtkWidget* gameWindow = globals->window;
|
||||||
globals->cGlobals.pDb = gg->pDb;
|
globals->cGlobals.pDb = gg->pDb;
|
||||||
|
globals->cGlobals.selRow = -1;
|
||||||
gtk_widget_show( gameWindow );
|
gtk_widget_show( gameWindow );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_open_button( GtkWidget* XP_UNUSED(widget), void* closure )
|
||||||
|
{
|
||||||
|
GTKGamesGlobals* gg = (GTKGamesGlobals*)closure;
|
||||||
|
if ( -1 != gg->selRow ) {
|
||||||
|
gg->params->needsNewGame = XP_FALSE;
|
||||||
|
GtkAppGlobals* globals = malloc( sizeof(*globals) );
|
||||||
|
initGlobals( globals, gg->params );
|
||||||
|
globals->cGlobals.pDb = gg->pDb;
|
||||||
|
globals->cGlobals.selRow = gg->selRow;
|
||||||
|
gtk_widget_show( globals->window );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_quit_button( GtkWidget* XP_UNUSED(widget), gpointer data )
|
handle_quit_button( GtkWidget* XP_UNUSED(widget), gpointer data )
|
||||||
{
|
{
|
||||||
|
@ -111,9 +153,9 @@ makeGamesWindow( GTKGamesGlobals* gg )
|
||||||
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
|
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
|
||||||
gtk_container_add( GTK_CONTAINER(window), vbox );
|
gtk_container_add( GTK_CONTAINER(window), vbox );
|
||||||
gtk_widget_show( vbox );
|
gtk_widget_show( vbox );
|
||||||
GtkWidget* list = gtk_tree_view_new();
|
GtkWidget* list = init_games_list( gg );
|
||||||
gtk_container_add( GTK_CONTAINER(vbox), list );
|
gtk_container_add( GTK_CONTAINER(vbox), list );
|
||||||
init_games_list( list );
|
|
||||||
gtk_widget_show( list );
|
gtk_widget_show( list );
|
||||||
|
|
||||||
GSList* games = listGames( gg );
|
GSList* games = listGames( gg );
|
||||||
|
@ -134,6 +176,11 @@ makeGamesWindow( GTKGamesGlobals* gg )
|
||||||
G_CALLBACK(handle_newgame_button), gg );
|
G_CALLBACK(handle_newgame_button), gg );
|
||||||
gtk_widget_show( button );
|
gtk_widget_show( button );
|
||||||
|
|
||||||
|
button = gtk_button_new_with_label( "Open" );
|
||||||
|
gtk_container_add( GTK_CONTAINER(hbox), button );
|
||||||
|
g_signal_connect( GTK_OBJECT(button), "clicked",
|
||||||
|
G_CALLBACK(handle_open_button), gg );
|
||||||
|
gtk_widget_show( button );
|
||||||
button = gtk_button_new_with_label( "Quit" );
|
button = gtk_button_new_with_label( "Quit" );
|
||||||
gtk_container_add( GTK_CONTAINER(hbox), button );
|
gtk_container_add( GTK_CONTAINER(hbox), button );
|
||||||
g_signal_connect( GTK_OBJECT(button), "clicked",
|
g_signal_connect( GTK_OBJECT(button), "clicked",
|
||||||
|
@ -148,6 +195,7 @@ int
|
||||||
gtkmain( LaunchParams* params )
|
gtkmain( LaunchParams* params )
|
||||||
{
|
{
|
||||||
GTKGamesGlobals gg = {0};
|
GTKGamesGlobals gg = {0};
|
||||||
|
gg.selRow = -1;
|
||||||
gg.params = params;
|
gg.params = params;
|
||||||
XP_LOGF( "%s: I'M HERE!!! (calling makeGamesDB())", __func__ );
|
XP_LOGF( "%s: I'M HERE!!! (calling makeGamesDB())", __func__ );
|
||||||
gg.pDb = openGamesDB();
|
gg.pDb = openGamesDB();
|
||||||
|
|
|
@ -261,7 +261,7 @@ saveGame( CommonGlobals* cGlobals )
|
||||||
if ( !!cGlobals->params->fileName || !!cGlobals->pDb ) {
|
if ( !!cGlobals->params->fileName || !!cGlobals->pDb ) {
|
||||||
XP_Bool doSave = XP_TRUE;
|
XP_Bool doSave = XP_TRUE;
|
||||||
XP_Bool newGame = !file_exists( cGlobals->params->fileName )
|
XP_Bool newGame = !file_exists( cGlobals->params->fileName )
|
||||||
|| 0 == cGlobals->rowid;
|
|| -1 == cGlobals->selRow;
|
||||||
/* don't fail to save first time! */
|
/* don't fail to save first time! */
|
||||||
if ( 0 < cGlobals->params->saveFailPct && !newGame ) {
|
if ( 0 < cGlobals->params->saveFailPct && !newGame ) {
|
||||||
XP_U16 pct = XP_RANDOM() % 100;
|
XP_U16 pct = XP_RANDOM() % 100;
|
||||||
|
|
|
@ -169,11 +169,11 @@ struct CommonGlobals {
|
||||||
CommonPrefs cp;
|
CommonPrefs cp;
|
||||||
|
|
||||||
XWGame game;
|
XWGame game;
|
||||||
sqlite3_int64 rowid;
|
|
||||||
XP_U16 lastNTilesToUse;
|
XP_U16 lastNTilesToUse;
|
||||||
XP_U16 lastStreamSize;
|
XP_U16 lastStreamSize;
|
||||||
XP_Bool manualFinal; /* use asked for final scores */
|
XP_Bool manualFinal; /* use asked for final scores */
|
||||||
sqlite3* pDb;
|
sqlite3* pDb;
|
||||||
|
sqlite3_int64 selRow;
|
||||||
|
|
||||||
SocketChangedFunc socketChanged;
|
SocketChangedFunc socketChanged;
|
||||||
void* socketChangedClosure;
|
void* socketChangedClosure;
|
||||||
|
@ -211,6 +211,7 @@ struct CommonGlobals {
|
||||||
|
|
||||||
typedef struct _GTKGamesGlobals {
|
typedef struct _GTKGamesGlobals {
|
||||||
sqlite3* pDb;
|
sqlite3* pDb;
|
||||||
|
sqlite3_int64 selRow;
|
||||||
LaunchParams* params;
|
LaunchParams* params;
|
||||||
} GTKGamesGlobals;
|
} GTKGamesGlobals;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue