/* gmysql -- a graphical frontend to MySQL databases Copyright (C) 1998, 1999 Stephen R. Dodd This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "createtabledlg.h" #include "fielddlg.h" #include "indexdlg.h" #include "msgbox.h" #include "qbox.h" static CreateTableDlg *create_table_dlg_construct( TableList *owner, gchar *ok_label ); static void create_table_dlg_done( GtkWidget *widget, gpointer data ); static void create_table_dlg_cancel( GtkWidget *widget, gpointer data ); static void create_table_dlg_destroyed( GtkWidget *widget, gpointer data ); static gint create_table_dlg_key_pressed( GtkWidget *widget, GdkEventKey *event ); static void populate_host_list( gpointer key, gpointer value, gpointer user_data ); static void host_selected( GtkWidget *widget, gpointer data ); static void db_selected( GtkWidget *widget, gpointer data ); static void field_add( GtkWidget *widget, gpointer data ); static void field_edit( GtkWidget *widget, gpointer data ); static void field_remove( GtkWidget *widget, gpointer data ); static void field_selected( GtkWidget *widget, gint row, gint col, GdkEventButton bevent ); static void index_selected( GtkWidget *widget, gint row, gint col, GdkEventButton bevent ); static void index_add( GtkWidget *widget, gpointer data ); static void index_remove( GtkWidget *widget, gpointer data ); static void process_mod( gpointer key, gpointer data, gpointer user_data ); static void process_idx_mod( gpointer key, gpointer data, gpointer user_data ); static void free_mod( gpointer key, gpointer data, gpointer user_data ); typedef struct _ModInfo ModInfo; /*typedef struct _IdxModInfo IdxModInfo; struct _IdxModInfo { gchar *index_name; gint add; gint delete; gchar *def; };*/ struct _ModInfo { gchar *name; gchar *new_name; gint add; gint delete; gchar *def; }; static GSList *group; static gchar *selected_host; static gchar *selected_db; static GtkWidget *db_option_menu; static GtkWidget *host_option_menu; static GHashTable *conns; static gint selected_index; static gint selected_field; static gint host_pos; static gint set_host_pos; CreateTableDlg *create_table_dlg_new_modified( TableList *owner, gchar *host, gchar *db, gchar *table ) { CreateTableDlg *create_table_dlg; selected_host = host; selected_db = db; create_table_dlg = create_table_dlg_construct( owner, "Commit" ); gtk_entry_set_text( GTK_ENTRY( create_table_dlg->table ), table ); gtk_widget_set_sensitive( create_table_dlg->table, FALSE ); gtk_widget_set_sensitive( create_table_dlg->host, FALSE ); gtk_widget_set_sensitive( create_table_dlg->db, FALSE ); create_table_dlg->new_table = FALSE; create_table_dlg->mods = g_hash_table_new( g_str_hash, g_str_equal ); create_table_dlg->idx_mods = g_hash_table_new( g_str_hash, g_str_equal ); return create_table_dlg; } CreateTableDlg *create_table_dlg_new( TableList *owner, gchar *host, gchar *db ) { selected_host = host; selected_db = db; return create_table_dlg_construct( owner, "Create" ); } CreateTableDlg *create_table_dlg_construct( TableList *owner, gchar *ok_label ) { CreateTableDlg *create_table_dlg; GtkWidget *table, *label, *entry, *button, *dialog, *menu; GtkWidget *hbox, *vbox, *scrolled; static char *titles[] = { "Field", "Type" }; static char *titles2[] = { "Index", "Field", "Unique" }; create_table_dlg = g_new( CreateTableDlg, 1 ); create_table_dlg->new_table = TRUE; create_table_dlg->owner = owner; /* create dialog */ dialog = create_table_dlg->dialog = gtk_dialog_new(); gtk_signal_connect( GTK_OBJECT( dialog ), "destroy", GTK_SIGNAL_FUNC( create_table_dlg_destroyed ), create_table_dlg ); gtk_signal_connect( GTK_OBJECT( dialog ), "key_press_event", GTK_SIGNAL_FUNC( create_table_dlg_key_pressed ), NULL ); gtk_widget_set_usize( dialog, 450, 400 ); table = gtk_table_new( 5, 2, FALSE ); /* create host list box and label */ label = gtk_label_new( "Host" ); gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT ); gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); host_option_menu = entry = create_table_dlg->host = gtk_option_menu_new(); menu = gtk_menu_new(); group = NULL; /*selected_host = NULL;*/ host_pos = 0; g_hash_table_foreach( owner->conns, populate_host_list, menu ); gtk_option_menu_set_menu( GTK_OPTION_MENU( entry ), menu ); gtk_option_menu_set_history( GTK_OPTION_MENU( entry ), set_host_pos ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_FILL, 0, 5, 5 ); gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 0, 1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); gtk_widget_show( label ); gtk_widget_show( entry ); /* create database list box and label */ label = gtk_label_new( "Database" ); gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT ); gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); db_option_menu = entry = create_table_dlg->db = gtk_option_menu_new(); conns = owner->conns; host_selected( NULL, selected_host ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_FILL, 0, 5, 5 ); gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 1, 2, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); gtk_widget_show( label ); gtk_widget_show( entry ); /* create table text box and label */ label = gtk_label_new( "Table" ); gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT ); gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); entry = create_table_dlg->table = gtk_entry_new(); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, GTK_FILL, 0, 5, 5 ); gtk_table_attach( GTK_TABLE( table ), entry, 1, 2, 2, 3, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); gtk_widget_show( label ); gtk_widget_show( entry ); /* create the field list */ entry = create_table_dlg->field_list = gtk_clist_new_with_titles( 2, titles ); gtk_clist_column_titles_passive( GTK_CLIST( entry ) ); gtk_clist_set_column_width( GTK_CLIST( entry ), 0, 80 ); gtk_signal_connect( GTK_OBJECT( entry ), "select_row", GTK_SIGNAL_FUNC( field_selected ), NULL ); hbox = gtk_hbox_new( FALSE, 5 ); gtk_widget_show( hbox ); gtk_table_attach( GTK_TABLE( table ), hbox, 0, 2, 3, 4, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 5, 5 ); vbox = gtk_vbox_new( FALSE, 5 ); gtk_widget_show( vbox ); gtk_widget_show( entry ); #if CONFIG_GTK_MAJOR==1 && CONFIG_GTK_MINOR==0 gtk_clist_set_policy( GTK_CLIST( entry ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); gtk_box_pack_start( GTK_BOX( hbox ), entry, TRUE, TRUE, 5 ); #else /* not GTK 1.0 */ /* create a scrolled window */ scrolled = gtk_scrolled_window_new( NULL, NULL ); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); gtk_container_add( GTK_CONTAINER( scrolled ), create_table_dlg->field_list ); gtk_widget_show( scrolled ); gtk_box_pack_start( GTK_BOX( hbox ), scrolled, TRUE, TRUE, 5 ); #endif /* GTK 1.0 */ gtk_box_pack_end( GTK_BOX( hbox ), vbox, FALSE, FALSE, 5 ); button = gtk_button_new_with_label( "Add" ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( field_add ), create_table_dlg ); gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 5 ); gtk_widget_show( button ); button = gtk_button_new_with_label( "Edit" ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( field_edit ), create_table_dlg ); gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 5 ); gtk_widget_show( button ); button = gtk_button_new_with_label( "Remove" ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( field_remove ), create_table_dlg ); gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 5 ); gtk_widget_show( button ); /* create an hbox containing the index list */ hbox = gtk_hbox_new( FALSE, 5 ); gtk_widget_show( hbox ); entry = create_table_dlg->index_list = gtk_clist_new_with_titles( 3, titles2 ); gtk_clist_column_titles_passive( GTK_CLIST( entry ) ); gtk_clist_set_column_width( GTK_CLIST( entry ), 0, 80 ); gtk_clist_set_column_width( GTK_CLIST( entry ), 1, 100 ); gtk_signal_connect( GTK_OBJECT( entry ), "select_row", GTK_SIGNAL_FUNC( index_selected ), NULL ); #if CONFIG_GTK_MAJOR==1 && CONFIG_GTK_MINOR==0 gtk_clist_set_policy( GTK_CLIST( entry ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); gtk_box_pack_start( GTK_BOX( hbox ), entry, TRUE, TRUE, 5 ); #else /* not GTK 1.0 */ /* create a scrolled window for index list */ scrolled = gtk_scrolled_window_new( NULL, NULL ); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( scrolled ), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); gtk_container_add( GTK_CONTAINER( scrolled ), create_table_dlg->index_list ); gtk_widget_show( scrolled ); gtk_box_pack_start( GTK_BOX( hbox ), scrolled, TRUE, TRUE, 5 ); #endif /* GTK 1.0 */ gtk_table_attach( GTK_TABLE( table ), hbox, 0, 2, 4, 5, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 5, 5 ); vbox = gtk_vbox_new( FALSE, 5 ); gtk_widget_show( vbox ); gtk_box_pack_end( GTK_BOX( hbox ), vbox, FALSE, FALSE, 5 ); gtk_widget_show( entry ); button = gtk_button_new_with_label( "Add" ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( index_add ), create_table_dlg ); gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 5 ); gtk_widget_show( button ); /*FIXME: button = gtk_button_new_with_label( "Edit" ); gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 5 ); gtk_widget_show( button ); */ button = gtk_button_new_with_label( "Remove" ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( index_remove ), create_table_dlg ); gtk_box_pack_start( GTK_BOX( vbox ), button, FALSE, FALSE, 5 ); gtk_widget_show( button ); gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->vbox ), table, TRUE, TRUE, 0 ); gtk_widget_show( table ); gtk_widget_grab_focus( create_table_dlg->db ); /* must come after table is shown? */ gtk_box_set_homogeneous( GTK_BOX( GTK_DIALOG( dialog )->action_area ), FALSE ); button = gtk_button_new_with_label( "Cancel" ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( create_table_dlg_cancel ), create_table_dlg ); GTK_WIDGET_SET_FLAGS( button, GTK_CAN_DEFAULT ); gtk_box_pack_end( GTK_BOX( GTK_DIALOG( dialog )->action_area ), button, FALSE, FALSE, 0 ); gtk_widget_show( button ); button = gtk_button_new_with_label( ok_label ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( create_table_dlg_done ), create_table_dlg ); GTK_WIDGET_SET_FLAGS( button, GTK_CAN_DEFAULT ); gtk_box_pack_end( GTK_BOX( GTK_DIALOG( dialog )->action_area ), button, FALSE, FALSE, 0 ); gtk_widget_grab_default( button ); /* must do after packing but before showing */ #if !(CONFIG_GTK_MAJOR==1 && CONFIG_GTK_MINOR==0) gtk_window_set_modal( GTK_WINDOW( dialog ), TRUE ); #endif /* not GTK 1.0 */ gtk_widget_show( button ); create_table_dlg->mods = NULL; create_table_dlg->idx_mods = NULL; return create_table_dlg; } void create_table_dlg_add_index( CreateTableDlg *create_table_dlg, gchar *name, GSList *fields, gint unique, gint user ) { gchar *text[3]; gint row; ModInfo *mod_info; GString *def; def = g_string_new( "" ); name = g_strdup( name ); text[0] = name; if( strcmp( name, "PRIMARY" ) == 0 ) g_string_sprintf( def, "PRIMARY KEY (" ); else g_string_sprintf( def, "%s %s (", unique ? "UNIQUE" : "INDEX", name ); while( fields ) { text[1] = (gchar *)fields->data; g_string_sprintfa( def, "%s%s", text[0][0] ? "" : ", ", text[1] ); text[2] = unique ? "Y" : "N"; row = gtk_clist_append( GTK_CLIST( create_table_dlg->index_list ), text ); gtk_clist_set_row_data( GTK_CLIST( create_table_dlg->index_list ), row, name ); text[0] = ""; fields = g_slist_next( fields ); } g_string_sprintfa( def, ")" ); if( user && !create_table_dlg->new_table ) { mod_info = g_hash_table_lookup( create_table_dlg->idx_mods, name ); if( !mod_info ) { mod_info = g_new( ModInfo, 1 ); mod_info->name = g_strdup( name ); mod_info->def = g_strdup( def->str ); mod_info->add = TRUE; mod_info->delete = FALSE; g_hash_table_insert( create_table_dlg->idx_mods, mod_info->name, mod_info ); } else { /* must be a delete??, so this is a change */ mod_info->add = FALSE; mod_info->delete = FALSE; mod_info->def = g_strdup( def->str ); } } } /* * WARNING: Black Magic beyond this point */ void create_table_dlg_change_field( CreateTableDlg *create_table_dlg, gchar *old_name, gchar *name, gchar *type, gint user ) { ModInfo *mod_info; gtk_clist_set_text( GTK_CLIST( create_table_dlg->field_list ), selected_field, 0, name ); gtk_clist_set_text( GTK_CLIST( create_table_dlg->field_list ), selected_field, 1, type ); if( user && !create_table_dlg->new_table ) { mod_info = g_hash_table_lookup( create_table_dlg->mods, old_name ); if( !mod_info ) { /* it's not be touched yet this table editing sesh, easyish */ mod_info = g_new( ModInfo, 1 ); mod_info->name = g_strdup( old_name ); mod_info->def = g_strdup( type ); mod_info->new_name = g_strdup( name ); mod_info->add = FALSE; mod_info->delete = FALSE; g_hash_table_insert( create_table_dlg->mods, mod_info->name, mod_info ); } else if( mod_info->add ) { /* it's a pending add, also easy... */ g_free( mod_info->name ); g_free( mod_info->def ); mod_info->name = g_strdup( name ); mod_info->def = g_strdup( type ); /* rethingumy it in the hash table */ g_hash_table_remove( create_table_dlg->mods, mod_info ); g_hash_table_insert( create_table_dlg->mods, mod_info->name, mod_info ); } else { /* it can't be a delete, right??, so this is a change */ /*mod_info->add = FALSE; mod_info->delete = FALSE;*/ g_free( mod_info->def ); mod_info->def = g_strdup( type ); if( mod_info->new_name ) g_free( mod_info->new_name ); mod_info->new_name = g_strdup( name ); /* let's hope to hell it works... */ } } } void create_table_dlg_add_field( CreateTableDlg *create_table_dlg, gchar *name, gchar *type, gint user ) { gchar *text[2]; ModInfo *mod_info; text[0] = name; text[1] = type; gtk_clist_append( GTK_CLIST( create_table_dlg->field_list ), text ); if( user && !create_table_dlg->new_table ) { mod_info = g_hash_table_lookup( create_table_dlg->mods, name ); if( !mod_info ) { mod_info = g_new( ModInfo, 1 ); mod_info->name = g_strdup( name ); mod_info->def = g_strdup( type ); mod_info->new_name = NULL; mod_info->add = TRUE; mod_info->delete = FALSE; g_hash_table_insert( create_table_dlg->mods, mod_info->name, mod_info ); } else { /* must be a delete??, so this is a change */ if( mod_info->new_name ) g_warning( "Erk, user is adding a new field " "with the same name is a previous field which has a pending rename," " I'm all confused *****\n" ); mod_info->add = FALSE; mod_info->delete = FALSE; mod_info->def = g_strdup( type ); } } } void create_table_dlg_show( CreateTableDlg *create_table_dlg ) { gtk_widget_show( create_table_dlg->dialog ); } void create_table_dlg_done( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; gchar *db, *table, *field, *type, *index; DBConn *db_conn; MsgBox *msg_box; GString *ddl; gint i; create_table_dlg = CREATE_TABLE_DLG(data); g_assert( create_table_dlg ); db = selected_db; table = gtk_entry_get_text( GTK_ENTRY( create_table_dlg->table ) ); gtk_widget_hide( create_table_dlg->dialog ); while( gtk_events_pending()) gtk_main_iteration(); db_conn = g_hash_table_lookup( create_table_dlg->owner->conns, selected_host ); if( db_conn ) { if( mysql_select_db( &db_conn->mysql, db ) ) { msg_box = msg_box_new( mysql_error( &db_conn->mysql ) ); msg_box_show( msg_box ); } else if( create_table_dlg->new_table ) { ddl = g_string_new( "CREATE TABLE " ); g_string_sprintfa( ddl, "%s (", table ); for( i = 0; i < GTK_CLIST( create_table_dlg->field_list )->rows; i++ ) { gtk_clist_get_text( GTK_CLIST( create_table_dlg->field_list ), i, 0, &field ); gtk_clist_get_text( GTK_CLIST( create_table_dlg->field_list ), i, 1, &type ); g_string_sprintfa( ddl, "%s%s %s", i ? ", " : "", field, type ); } for( i = 0; i < GTK_CLIST( create_table_dlg->index_list )->rows; i++ ) { gtk_clist_get_text( GTK_CLIST( create_table_dlg->index_list ), i, 0, &index ); gtk_clist_get_text( GTK_CLIST( create_table_dlg->index_list ), i, 1, &field ); if( *index ) g_string_sprintfa( ddl, "%s, UNIQUE %s (", i ? ")" : "", index ); g_string_sprintfa( ddl, "%s%s", *index ? "" : ", ", field ); } g_string_sprintfa( ddl, ")%s", i ? ")" : "" ); if( mysql_query( &db_conn->mysql, ddl->str ) ) { msg_box = msg_box_new( mysql_error( &db_conn->mysql ) ); msg_box_show( msg_box ); } else { table_list_refresh( create_table_dlg->owner ); } g_string_free( ddl, TRUE ); } else { /* eek, try and figure out alter table */ ddl = g_string_new( "ALTER TABLE " ); g_string_sprintfa( ddl, "%s ", table ); g_hash_table_foreach( create_table_dlg->mods, process_mod, ddl ); g_hash_table_foreach( create_table_dlg->idx_mods, process_idx_mod, ddl ); g_hash_table_freeze( create_table_dlg->mods ); g_hash_table_freeze( create_table_dlg->idx_mods ); g_hash_table_foreach( create_table_dlg->mods, free_mod, create_table_dlg->mods ); g_hash_table_foreach( create_table_dlg->idx_mods, free_mod, create_table_dlg->idx_mods ); g_hash_table_destroy( create_table_dlg->mods ); create_table_dlg->mods = NULL; g_hash_table_destroy( create_table_dlg->idx_mods ); create_table_dlg->idx_mods = NULL; if( mysql_query( &db_conn->mysql, ddl->str ) ) { msg_box = msg_box_new( mysql_error( &db_conn->mysql ) ); msg_box_show( msg_box ); } g_string_free( ddl, TRUE ); } } gtk_widget_destroy( create_table_dlg->dialog ); } void free_mod( gpointer key, gpointer data, gpointer user_data ) { ModInfo *mod_info; mod_info = (ModInfo *)data; g_free( mod_info->name ); g_free( mod_info ); } void process_mod( gpointer key, gpointer data, gpointer user_data ) { ModInfo *mod_info; GString *ddl; mod_info = (ModInfo *)data; ddl = (GString *)user_data; if( ddl->str[ddl->len-1] != ' ' ) g_string_append( ddl, ", " ); if( mod_info->add ) { g_string_sprintfa( ddl, "ADD COLUMN %s %s", mod_info->name, mod_info->def ); g_free( mod_info->def ); } else if( mod_info->delete ) { g_string_sprintfa( ddl, "DROP COLUMN %s", mod_info->name ); } else { /* change */ g_string_sprintfa( ddl, "CHANGE COLUMN %s %s %s", mod_info->name, mod_info->new_name ? mod_info->new_name : mod_info->name, mod_info->def ); g_free( mod_info->def ); } } void process_idx_mod( gpointer key, gpointer data, gpointer user_data ) { ModInfo *mod_info; GString *ddl; mod_info = (ModInfo *)data; ddl = (GString *)user_data; if( ddl->str[ddl->len-1] != ' ' ) g_string_append( ddl, ", " ); if( mod_info->add ) { g_string_sprintfa( ddl, "ADD %s", mod_info->def ); g_free( mod_info->def ); } else if( mod_info->delete ) { if( strcmp( mod_info->name, "PRIMARY" ) == 0 ) g_string_sprintfa( ddl, "DROP PRIMARY KEY" ); else g_string_sprintfa( ddl, "DROP INDEX %s", mod_info->name ); } else { /* change */ if( strcmp( mod_info->name, "PRIMARY" ) == 0 ) g_string_sprintfa( ddl, "DROP PRIMARY KEY, ADD %s", mod_info->def ); else g_string_sprintfa( ddl, "DROP INDEX %s, ADD %s", mod_info->name, mod_info->def ); g_free( mod_info->def ); } } void create_table_dlg_cancel( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; create_table_dlg = CREATE_TABLE_DLG(data); gtk_widget_destroy( create_table_dlg->dialog ); } gint create_table_dlg_key_pressed( GtkWidget *widget, GdkEventKey *event ) { if( event->keyval == GDK_Escape ) gtk_widget_destroy( widget ); return FALSE; } void create_table_dlg_destroyed( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; create_table_dlg = CREATE_TABLE_DLG( data ); if( create_table_dlg->mods ) g_hash_table_destroy( create_table_dlg->mods ); if( create_table_dlg->idx_mods ) g_hash_table_destroy( create_table_dlg->idx_mods ); g_free( data ); } void populate_host_list( gpointer key, gpointer value, gpointer user_data ) { DBConn *db_conn; GtkWidget *menu, *item; db_conn = (DBConn *)value; menu = GTK_WIDGET( user_data ); item = gtk_radio_menu_item_new_with_label( group, db_conn->host ); group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( item ) ); gtk_signal_connect( GTK_OBJECT( item ), "activate", GTK_SIGNAL_FUNC( host_selected ), db_conn->host ); if( !selected_host ) selected_host = db_conn->host; else if( strcmp( selected_host, db_conn->host ) == 0 ) set_host_pos = host_pos; host_pos++; gtk_widget_show( item ); gtk_menu_append( GTK_MENU( menu ), item ); } void db_selected( GtkWidget *widget, gpointer data ) { selected_db = data; } void host_selected( GtkWidget *widget, gpointer data ) { DBConn *db_conn; MYSQL_RES *res; MYSQL_ROW row; GtkWidget *menu, *item; GSList *group = NULL; gint db_pos = 0, set_db_pos = 0; selected_host = data; menu = gtk_menu_new(); db_conn = (DBConn *)g_hash_table_lookup( conns, selected_host ); if( !db_conn ) return; res = mysql_list_dbs( &db_conn->mysql, NULL ); if( res == NULL ) { g_print("EEK: %s\n", mysql_error( &db_conn->mysql ) ); return; } while( ( row = mysql_fetch_row( res ) ) ) { item = gtk_radio_menu_item_new_with_label( group, row[0] ); group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( item ) ); gtk_signal_connect( GTK_OBJECT( item ), "activate", GTK_SIGNAL_FUNC( db_selected ), row[0] ); gtk_menu_append( GTK_MENU( menu ), item ); gtk_widget_show( item ); if( !selected_db ) selected_db = row[0]; else if( strcmp( selected_db, row[0] ) == 0 ) set_db_pos = db_pos; db_pos++; } gtk_option_menu_set_menu( GTK_OPTION_MENU( db_option_menu ), menu ); gtk_option_menu_set_history( GTK_OPTION_MENU( db_option_menu ), set_db_pos ); } void index_selected( GtkWidget *widget, gint row, gint col, GdkEventButton bevent ) { selected_index = row; } void field_selected( GtkWidget *widget, gint row, gint col, GdkEventButton bevent ) { selected_field = row; } void field_remove( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; gchar *field_name; ModInfo *mod_info; gint i; gchar *field, *del_field = NULL; QBox *q_box; gint ask = 1; gchar *index, *last_index = NULL; create_table_dlg = CREATE_TABLE_DLG( data ); gtk_clist_get_text( GTK_CLIST( create_table_dlg->field_list ), selected_field, 0, &del_field ); if( !del_field ) return; if( !create_table_dlg->new_table ) { gtk_clist_get_text( GTK_CLIST( create_table_dlg->field_list ), selected_field, 0, &field_name ); mod_info = g_hash_table_lookup( create_table_dlg->mods, field_name ); if( !mod_info ) { mod_info = g_new( ModInfo, 1 ); mod_info->name = g_strdup( field_name ); mod_info->add = FALSE; mod_info->delete = TRUE; mod_info->new_name = NULL; g_hash_table_insert( create_table_dlg->mods, mod_info->name, mod_info ); } else { /* must be add or change?? */ g_free( mod_info->def ); mod_info->add = FALSE; mod_info->delete = TRUE; if( mod_info->new_name ) g_free( mod_info->new_name ); } } for( i = 0; i < GTK_CLIST( create_table_dlg->index_list )->rows; i++ ) { gtk_clist_get_text( GTK_CLIST( create_table_dlg->index_list ), i, 1, &field ); gtk_clist_get_text( GTK_CLIST( create_table_dlg->index_list ), i, 0, &index ); if( strcmp( field, del_field ) == 0 ) { if( ask ) { q_box = q_box_new( "One or more indices exist on this field.\n" "Do you want to remove the field from them?", "Yes", "No" ); if( q_box_do_modal( q_box ) == 1 ) break; ask = 0; } if( strlen( index ) ) last_index = g_strdup( index ); gtk_clist_remove( GTK_CLIST( create_table_dlg->index_list ), i-- ); } else { if( last_index ) if( !strlen( index ) ) gtk_clist_set_text( GTK_CLIST( create_table_dlg->index_list ), i, 0, last_index ); g_free( last_index ); last_index = NULL; } } gtk_clist_remove( GTK_CLIST( create_table_dlg->field_list ), selected_field ); } void field_edit( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; FieldDlg *field_dlg; gchar *name = NULL, *def = NULL; create_table_dlg = CREATE_TABLE_DLG( data ); gtk_clist_get_text( GTK_CLIST( create_table_dlg->field_list ), selected_field, 0, &name ); gtk_clist_get_text( GTK_CLIST( create_table_dlg->field_list ), selected_field, 1, &def ); if( !name ) return; field_dlg = field_dlg_new( create_table_dlg ); field_dlg_set( field_dlg, name, def ); field_dlg_show( field_dlg ); } void field_add( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; FieldDlg *field_dlg; create_table_dlg = CREATE_TABLE_DLG( data ); field_dlg = field_dlg_new( create_table_dlg ); field_dlg_show( field_dlg ); } void index_add( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; IndexDlg *index_dlg; int i; gchar *field; create_table_dlg = CREATE_TABLE_DLG( data ); index_dlg = index_dlg_new( create_table_dlg ); for( i = 0; i < GTK_CLIST( create_table_dlg->field_list )->rows; i++ ) { gtk_clist_get_text( GTK_CLIST( create_table_dlg->field_list ), i, 0, &field ); index_dlg_add_avail_field( index_dlg, field ); } index_dlg_show( index_dlg ); } void index_remove( GtkWidget *widget, gpointer data ) { CreateTableDlg *create_table_dlg; gchar *index_name; ModInfo *mod_info; QBox *q_box; gint row; GString *msg; create_table_dlg = CREATE_TABLE_DLG( data ); index_name = gtk_clist_get_row_data( GTK_CLIST( create_table_dlg->index_list ), selected_index ); if( !index_name ) return; msg = g_string_new( NULL ); g_string_sprintf( msg, "Are you sure you want to delete index '%s'?", index_name ); q_box = q_box_new( msg->str, "Yes", "No" ); g_string_free( msg, TRUE ); if( q_box_do_modal( q_box ) == 1 ) return; do { row = gtk_clist_find_row_from_data( GTK_CLIST( create_table_dlg->index_list ), index_name ); if( row >= 0 ) gtk_clist_remove( GTK_CLIST( create_table_dlg->index_list ), row ); } while( row >= 0 ); if( !create_table_dlg->new_table ) { mod_info = g_hash_table_lookup( create_table_dlg->idx_mods, index_name ); if( !mod_info ) { mod_info = g_new( ModInfo, 1 ); mod_info->name = g_strdup( index_name ); mod_info->add = FALSE; mod_info->delete = TRUE; g_hash_table_insert( create_table_dlg->idx_mods, mod_info->name, mod_info ); } else { /* must be add or change?? */ g_free( mod_info->def ); mod_info->add = FALSE; mod_info->delete = TRUE; } } g_free( index_name ); }