/* 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 #include #include #include "fielddlg.h" #include "setdlg.h" static void field_dlg_done( GtkWidget *widget, gpointer data ); static void field_dlg_cancel( GtkWidget *widget, gpointer data ); static void field_dlg_destroyed( GtkWidget *widget, gpointer data ); static gint field_dlg_key_pressed( GtkWidget *widget, GdkEventKey *event ); static void type_selected( GtkWidget *widget, gpointer data ); static void member_selected( GtkWidget *widget, gint row, gint col, GdkEventButton bevent ); static void set_member_add( GtkWidget *widget, gpointer data ); static void set_member_remove( GtkWidget *widget, gpointer data ); enum FieldClass { FT_INTEGER, FT_FLOAT, FT_STRING }; struct FieldInfo { const char *pretty_name; const char *name; int has_displaylen; int has_unsigned; int has_zerofill; int has_decimals; int is_set; int has_binary; guint32 max_size; enum FieldClass type; }; static const struct FieldInfo field_types[] = { { "Tiny Int", "TINYINT", TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 0, FT_INTEGER }, { "Small Int", "SMALLINT", TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 0, FT_INTEGER }, { "Medium Int", "MEDIUMINT", TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 0, FT_INTEGER }, { "Integer", "INT", TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 0, FT_INTEGER }, { "Big Int", "BIGINT", TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, 0, FT_INTEGER }, { "Float", "FLOAT", TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, 0, FT_FLOAT }, { "Double", "DOUBLE", TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, 0, FT_FLOAT }, { "Decimal", "DECIMAL", TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, 0, FT_STRING }, { "Timestamp", "TIMESTAMP", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, FT_STRING }, { "Time", "TIME", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, FT_STRING }, { "Date", "DATE", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, FT_STRING }, { "Year", "YEAR", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, FT_INTEGER }, { "Char", "CHAR", TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, 255, FT_STRING }, { "Var Char", "VARCHAR", TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, 255, FT_STRING }, { "Tiny Text", "TINYTEXT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xff, FT_STRING }, { "Text", "TEXT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xffff, FT_STRING }, { "Medium Text", "MEDIUMTEXT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xffffff, FT_STRING }, { "Long Text", "LONGTEXT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xffffffff, FT_STRING }, { "Tiny BLOB", "TINYBLOB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xff, FT_STRING }, { "BLOB", "BLOB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xffff, FT_STRING }, { "Medium BLOB", "MEDIUMBLOB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xffffff, FT_STRING }, { "Long BLOB", "LONGBLOB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0xffffffff, FT_STRING }, { "Enumeration", "ENUM", FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0xffff, FT_STRING }, { "Set", "SET", FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 64, FT_STRING } }; #define NUM_TYPES ( sizeof( field_types ) / sizeof( struct FieldInfo ) ) static GSList *group; static FieldDlg *field_dlg_active; static struct FieldInfo *selected_type; static gint selected_member; FieldDlg *field_dlg_new( CreateTableDlg *owner ) { FieldDlg *field_dlg; GtkWidget *table, *label, *entry, *button, *dialog, *menu, *item, *hbox, *vbox, *scrolled; static char *titles[] = { "Member" }; int i; field_dlg_active = field_dlg = g_new( FieldDlg, 1 ); field_dlg->old_name = NULL; field_dlg->owner = owner; dialog = field_dlg->dialog = gtk_dialog_new(); gtk_signal_connect( GTK_OBJECT( dialog ), "destroy", GTK_SIGNAL_FUNC( field_dlg_destroyed ), field_dlg ); gtk_signal_connect( GTK_OBJECT( dialog ), "key_press_event", GTK_SIGNAL_FUNC( field_dlg_key_pressed ), NULL ); field_dlg->table = table = gtk_table_new( 9, 2, FALSE ); label = gtk_label_new( "Name" ); gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT ); gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); entry = field_dlg->field = gtk_entry_new(); 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 ); label = gtk_label_new( "Type" ); gtk_label_set_justify( GTK_LABEL( label ), GTK_JUSTIFY_RIGHT ); gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); entry = field_dlg->ftype = gtk_option_menu_new(); menu = gtk_menu_new(); group = NULL; for( i = 0; i < NUM_TYPES; i++ ) { item = gtk_radio_menu_item_new_with_label( group, field_types[i].pretty_name ); group = gtk_radio_menu_item_group( GTK_RADIO_MENU_ITEM( item ) ); gtk_signal_connect( GTK_OBJECT( item ), "activate", GTK_SIGNAL_FUNC( type_selected ), (gpointer)&field_types[i] ); gtk_menu_append( GTK_MENU( menu ), item ); gtk_widget_show( item ); } gtk_option_menu_set_menu( GTK_OPTION_MENU( entry ), menu ); 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 ); field_dlg->displaylen = entry = gtk_entry_new(); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->decimal = entry = gtk_entry_new(); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->is_unsigned = entry = gtk_check_button_new_with_label( "Unsigned" ); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->is_zerofilled = entry = gtk_check_button_new_with_label( "Zero filled" ); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->is_binary = entry = gtk_check_button_new_with_label( "Binary" ); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->is_null = entry = gtk_check_button_new_with_label( "Can be null" ); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->auto_inc = entry = gtk_check_button_new_with_label( "Auto increment" ); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->pri_key = entry = gtk_check_button_new_with_label( "Primary key" ); gtk_widget_show( entry ); gtk_widget_ref( entry ); field_dlg->def = entry = gtk_entry_new(); gtk_widget_show( entry ); gtk_widget_ref( entry ); hbox = field_dlg->set_hbox = gtk_hbox_new( FALSE, 5 ); gtk_widget_show( hbox ); /* create set list */ field_dlg->set_list = entry = gtk_clist_new_with_titles( 1, titles ); gtk_clist_column_titles_passive( GTK_CLIST( entry ) ); gtk_widget_show( entry ); gtk_signal_connect( GTK_OBJECT( entry ), "select_row", GTK_SIGNAL_FUNC( member_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 ), field_dlg->set_list, TRUE, TRUE, 5 ); #else /* GTK 1.0 */ /* create a scrolled window for the set 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 ), field_dlg->set_list ); gtk_widget_show( scrolled ); gtk_box_pack_start( GTK_BOX( hbox ), scrolled, TRUE, TRUE, 5 ); #endif /* GTK 1.0 */ /* create add and remove buttons */ field_dlg->set_add = entry = gtk_button_new_with_label( "Add" ); gtk_signal_connect( GTK_OBJECT( entry ), "clicked", GTK_SIGNAL_FUNC( set_member_add ), field_dlg ); gtk_widget_show( entry ); field_dlg->set_remove = entry = gtk_button_new_with_label( "Remove" ); gtk_signal_connect( GTK_OBJECT( entry ), "clicked", GTK_SIGNAL_FUNC( set_member_remove ), field_dlg ); gtk_widget_show( entry ); vbox = gtk_vbox_new( FALSE, 5 ); gtk_widget_show( vbox ); gtk_box_pack_end( GTK_BOX( hbox ), vbox, FALSE, FALSE, 5 ); gtk_box_pack_start( GTK_BOX( vbox ), field_dlg->set_add, FALSE, FALSE, 5 ); gtk_box_pack_start( GTK_BOX( vbox ), field_dlg->set_remove, FALSE, FALSE, 5 ); gtk_widget_ref( hbox ); type_selected( NULL, (gpointer)field_types ); gtk_box_pack_start( GTK_BOX( GTK_DIALOG( dialog )->vbox ), table, TRUE, TRUE, 0 ); gtk_widget_show( table ); gtk_widget_grab_focus( field_dlg->field ); /* 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( field_dlg_cancel ), field_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( "Commit" ); gtk_signal_connect( GTK_OBJECT( button ), "clicked", GTK_SIGNAL_FUNC( field_dlg_done ), field_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 ); return field_dlg; } void field_dlg_show( FieldDlg *field_dlg ) { gtk_widget_show( field_dlg->dialog ); } void field_dlg_done( GtkWidget *widget, gpointer data ) { FieldDlg *field_dlg; struct FieldInfo *finfo = selected_type; gchar *name, *displaylen, *decimals, *set_member; GString *fragment; gint i; fragment = g_string_new( NULL ); field_dlg = FIELD_DLG(data); g_assert( field_dlg ); gtk_widget_hide( field_dlg->dialog ); while( gtk_events_pending()) gtk_main_iteration(); name = gtk_entry_get_text( GTK_ENTRY( field_dlg->field ) ); g_string_sprintf( fragment, "%s", finfo->name ); if( finfo->is_set ) { g_string_sprintfa( fragment, "(" ); for( i = 0; i < GTK_CLIST( field_dlg->set_list )->rows; i++ ) { gtk_clist_get_text( GTK_CLIST( field_dlg->set_list ), i, 0, &set_member ); g_string_sprintfa( fragment, "%s'%s'", i ? ", " : "", set_member ); } g_string_sprintfa( fragment, ")" ); } if( finfo->has_displaylen ) { displaylen = gtk_entry_get_text( GTK_ENTRY( field_dlg->displaylen ) ); if( *displaylen ) { g_string_sprintfa( fragment, "(%s", displaylen ); if( finfo->has_decimals ) { decimals = gtk_entry_get_text( GTK_ENTRY( field_dlg->decimal ) ); g_string_sprintfa( fragment, ",%s)", decimals ); } else { g_string_sprintfa( fragment, ")" ); } } } if( finfo->has_zerofill && GTK_TOGGLE_BUTTON( field_dlg->is_zerofilled )->active ) { g_string_sprintfa( fragment, " ZEROFILL" ); } if( finfo->has_unsigned && GTK_TOGGLE_BUTTON( field_dlg->is_unsigned )->active ) { g_string_sprintfa( fragment, " UNSIGNED" ); } if( finfo->has_binary && GTK_TOGGLE_BUTTON( field_dlg->is_binary )->active ) { g_string_sprintfa( fragment, " BINARY" ); } g_string_sprintfa( fragment, " %sNULL", GTK_TOGGLE_BUTTON( field_dlg->is_null )->active ? "" : "NOT " ); if( GTK_ENTRY( field_dlg->def )->text_length ) { if( finfo->type == FT_INTEGER || finfo->type == FT_FLOAT ) g_string_sprintfa( fragment, " DEFAULT %s", gtk_entry_get_text( GTK_ENTRY( field_dlg->def )) ); else g_string_sprintfa( fragment, " DEFAULT '%s'", gtk_entry_get_text( GTK_ENTRY( field_dlg->def )) ); } if( GTK_TOGGLE_BUTTON( field_dlg->auto_inc )->active ) { g_string_sprintfa( fragment, " AUTO_INCREMENT" ); } if( GTK_TOGGLE_BUTTON( field_dlg->pri_key )->active ) { g_string_sprintfa( fragment, " PRIMARY KEY" ); } if( field_dlg->old_name ) create_table_dlg_change_field( field_dlg->owner, field_dlg->old_name, name, fragment->str, TRUE ); else create_table_dlg_add_field( field_dlg->owner, name, fragment->str, TRUE ); g_string_free( fragment, TRUE ); gtk_widget_destroy( field_dlg->dialog ); } void field_dlg_cancel( GtkWidget *widget, gpointer data ) { FieldDlg *field_dlg; field_dlg = FIELD_DLG(data); gtk_widget_destroy( field_dlg->dialog ); } gint field_dlg_key_pressed( GtkWidget *widget, GdkEventKey *event ) { if( event->keyval == GDK_Escape ) gtk_widget_destroy( widget ); return FALSE; } void field_dlg_destroyed( GtkWidget *widget, gpointer data ) { FieldDlg *field_dlg; field_dlg = FIELD_DLG( data ); gtk_widget_unref( field_dlg->displaylen ); gtk_widget_unref( field_dlg->is_zerofilled ); gtk_widget_unref( field_dlg->is_unsigned ); gtk_widget_unref( field_dlg->decimal ); gtk_widget_unref( field_dlg->is_binary ); gtk_widget_unref( field_dlg->set_hbox ); g_free( data ); } void field_dlg_add_member( FieldDlg *field_dlg, gchar *member ) { gtk_clist_append( GTK_CLIST( field_dlg->set_list ), &member ); } void set_member_add( GtkWidget *widget, gpointer data ) { FieldDlg *field_dlg; SetDlg *set_dlg; field_dlg = FIELD_DLG( data ); set_dlg = set_dlg_new( field_dlg ); set_dlg_show( set_dlg ); } void set_member_remove( GtkWidget *widget, gpointer data ) { FieldDlg *field_dlg; field_dlg = FIELD_DLG( data ); gtk_clist_remove( GTK_CLIST( field_dlg->set_list ), selected_member ); } void field_dlg_set( FieldDlg *field_dlg, gchar *name, gchar *def ) { gint type, length = 0, decimals = 0; gchar *mods, *end_type, *decs_start, *def_val; gchar len[10], decs[10]; field_dlg->old_name = g_strdup( name ); gtk_entry_set_text( GTK_ENTRY( field_dlg->field ), name ); def = g_strdup( def ); mods = strchr( def, ' ' )+1; if( (end_type = strchr( def, '(' )) ) { *end_type = '\0'; length = atoi( end_type + 1 ); if( ( decs_start = strchr( end_type + 1, ',' ) ) ) decimals = atoi( decs_start + 1 ); if( strchr( end_type+1, ')' ) ) g_strup( strchr( end_type+1, ')' ) ); } else { g_strup( mods ); end_type = strchr( def, ' ' ); *end_type = '\0'; } for( type = 0; type < NUM_TYPES; type++ ) { if( strcasecmp( field_types[type].name, def ) == 0 ) { gtk_option_menu_set_history( GTK_OPTION_MENU( field_dlg->ftype ), type ); type_selected( NULL, (gpointer)&field_types[type] ); break; } } sprintf( len, "%d", length ); gtk_entry_set_text( GTK_ENTRY( field_dlg->displaylen ), len ); if( !strstr( mods, "NOT NULL" ) ) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( field_dlg->is_null ), TRUE ); if( strstr( mods, "UNSIGNED" ) ) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( field_dlg->is_unsigned ), TRUE ); if( strstr( mods, "ZEROFILL" ) ) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( field_dlg->is_zerofilled ), TRUE ); if( strstr( mods, "AUTO_INCREMENT" ) ) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( field_dlg->auto_inc ), TRUE ); if( strstr( mods, "PRIMARY KEY" ) ) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( field_dlg->pri_key ), TRUE ); if( strstr( mods, "BINARY" ) ) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON( field_dlg->is_binary ), TRUE ); if( decimals ) { sprintf( decs, "%d", decimals ); gtk_entry_set_text( GTK_ENTRY( field_dlg->decimal ), decs ); } if( ( def_val = strstr( mods, "DEFAULT " ) ) ) { def_val += 8; if( *def_val == '\'' ) { def_val++; if( strchr( def_val, '\'' ) ) *strchr( def_val, '\'' ) = '\0'; } else if( strchr( def_val, ' ' ) ) *strchr( def_val, ' ' ) = '\0'; gtk_entry_set_text( GTK_ENTRY( field_dlg->def ), def_val ); } if( field_types[type].is_set ) { char *c, *mem_start = NULL; int in_quote = 0; for( c = end_type+1; c && *c; c++ ) { switch( *c ) { case '\'': in_quote = !in_quote; if( in_quote ) { mem_start = c+1; break; } /* else FALL THROUGH */ case ' ': if( in_quote ) break; case ',': if( mem_start ) { *c = '\0'; field_dlg_add_member( field_dlg, mem_start ); mem_start = NULL; } break; case ')': if( mem_start ) { *c = '\0'; field_dlg_add_member( field_dlg, mem_start ); mem_start = NULL; } c = NULL; break; default: break; } if( !c ) break; } } } void member_selected( GtkWidget *widget, gint row, gint col, GdkEventButton bevent ) { selected_member = row; } void type_selected( GtkWidget *dummy, gpointer data ) { struct FieldInfo *finfo; int row = 2; GtkWidget *label, *table, *widget; GList *node; GtkTableChild *child; finfo = (struct FieldInfo *)data; selected_type = finfo; table = field_dlg_active->table; /* empty the optional fields */ do { node = GTK_TABLE( table )->children; do { child = (GtkTableChild *)node->data; if( child->top_attach >= 2 ) { widget = child->widget; gtk_container_remove( GTK_CONTAINER( table ), widget ); break; } } while( (node = g_list_next( node )) ); } while( node ); if( !finfo->is_set ) { if( finfo->has_displaylen ) { label = gtk_label_new( "Display length" ); gtk_widget_show( label ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row+1, GTK_FILL, 0, 5, 5 ); gtk_table_attach( GTK_TABLE( table ), field_dlg_active->displaylen, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; } if( finfo->has_unsigned ) { gtk_table_attach( GTK_TABLE( table ), field_dlg_active->is_unsigned, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; } if( finfo->has_zerofill ) { gtk_table_attach( GTK_TABLE( table ), field_dlg_active->is_zerofilled, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; } if( finfo->has_decimals ) { label = gtk_label_new( "Decimals" ); gtk_widget_show( label ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row+1, GTK_FILL, 0, 5, 5 ); gtk_table_attach( GTK_TABLE( table ), field_dlg_active->decimal, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; } if( finfo->has_binary ) { gtk_table_attach( GTK_TABLE( table ), field_dlg_active->is_binary, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; } } else { gtk_table_attach( GTK_TABLE( table ), field_dlg_active->set_hbox, 0, 2, row, row+4, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 5, 5 ); row+=4; } gtk_table_attach( GTK_TABLE( table ), field_dlg_active->is_null, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; gtk_table_attach( GTK_TABLE( table ), field_dlg_active->auto_inc, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; gtk_table_attach( GTK_TABLE( table ), field_dlg_active->pri_key, 0, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); row++; label = gtk_label_new( "Default value" ); gtk_widget_show( label ); gtk_table_attach( GTK_TABLE( table ), label, 0, 1, row, row+1, GTK_FILL, 0, 5, 5 ); gtk_table_attach( GTK_TABLE( table ), field_dlg_active->def, 1, 2, row, row+1, GTK_FILL|GTK_EXPAND, 0, 5, 5 ); }