#include #include #include #include #include #include #include #include #include #include #include "g2c_helpers.h" #include "g2c_doc.h" #include "g2c_project.h" #include "g2c_widget.h" #include #ifdef USE_GNOME #include #endif #define RECURSE_ALL G_MAXINT #define RECURSE_NONE 0 /* Uncomment this line to aid in debugging. */ /****************************************************************** ** Function Prototypes ** ******************************************************************/ static void output_main_file( g2cDoc *doc ); static void parse_project_properties( g2cDoc *doc ); static void parse_top_level_widgets( g2cDoc *doc ); static g2cWidget *parse_widget( g2cDoc *doc, g2cWidget *parent ); static g2cSignal *parse_signal( g2cDoc *doc ); static g2cAccel *parse_accel( g2cDoc *doc ); static void parse_child( g2cDoc *doc, g2cWidget *widget ); static gchar *get_dir_prefix( g2cDoc *doc ); static const xmlChar *get_node_name( xmlNodePtr node ); static const xmlChar *get_node_text( xmlNodePtr node ); static void init_types( g2cDoc *doc ); static void output_widget_create( g2cWidget *widget, FILE *file, gint recurse_levels, gboolean properties_only ); static void output_signal_connect( g2cWidget *widget, FILE *file ); static void output_signal_prototype( g2cWidget *widget, FILE *file ); static void output_signal_handler( g2cWidget *widget, FILE *file ); static void output_widget_struct( g2cWidget *widget, FILE *file ); static void output_temp_declarations( g2cWidget *widget, FILE *file ); static void output_accelerator_declarations( g2cWidget *widget, FILE *file ); static void output_focus_accelerator_declarations( g2cWidget *widget, FILE *file ); static void output_accelerators( g2cWidget *widget, FILE *file ); static void output_toolbar_widget( g2cWidget *widget, FILE *file ); static void output_clist_column( g2cWidget *widget, FILE *file ); static void output_menu_item( g2cWidget *widget, FILE* file ); static void output_menu( g2cWidget *widget, FILE* file ); static void handle_file_compare( gchar *temp_file_name, gchar *file_name ); static void output_gnome_dialog( g2cWidget *widget, FILE *file ); static void output_gnome_uiinfo( g2cWidget *widget, FILE *file ); static void output_gnome_uiinfo_struct( g2cWidget *widget, FILE *file ); static void output_gnome_uiinfo_empty( g2cWidget *widget, FILE *file ); /* Helpers */ gchar *spaces_to_ulines( gchar *input ); static void create_if_not_exist( gchar *filename ); /* Callbacks */ static void output_widget_files( gpointer data, gpointer user_data ); static void output_radio_group ( gpointer data, gpointer user_data ); /****************************************************************** ** Class Functions ** ******************************************************************/ g2cDoc * g2c_doc_new( char *xml_file_name ) { g2cDoc *doc = g_new0( g2cDoc, 1 ); /* Every document gets a project. One per customer please. */ doc->project = g2c_project_new(); CURRENT_PROJECT = doc->project; /* Open the XML document and save a pointer to it in the struct */ doc->xmldoc = xmlParseFile( xml_file_name ); doc->current = NULL; return doc; } void g2c_doc_destroy( g2cDoc *doc ) { /* Where is the call to release the xmlDoc pointer? */ if( doc->xmldoc ) xmlFreeDoc( doc->xmldoc ); if( doc->project ) g2c_project_destroy( doc->project ); doc->current = NULL; g_free( doc ); } void g2c_doc_parse( g2cDoc *doc ) { xmlNodePtr project_node = NULL; /* First line should be */ g_message( "XML Version: %s\n", doc->xmldoc->version ); doc->current = xmlDocGetRootElement( doc->xmldoc ); g_assert( NULL != doc->current ); /* Root node should be */ if( strcmp( get_node_name( doc->current ), "GTK-Interface" ) != 0 ) { g_error( "This is not a glade file!" ); } /* Move to the node */ doc->current = doc->current->childs; if( strcmp( doc->current->name, "project" ) != 0 ) { g_error( "Could not find project section!" ); } /* Save our place so that we can go to the first widget * after parsing the project properties */ project_node = doc->current; parse_project_properties( doc ); /* Get all of the widget types. Note that we have to wait * until we know if gnome support is enabled! */ init_types( doc ); /* Now parse any top-level widgets */ doc->current = project_node->next; if( NULL != doc->current ) parse_top_level_widgets( doc ); } void g2c_doc_output( g2cDoc *doc ) { gchar *filename = NULL; /* Write out the main.c file, if necessary */ if( doc->project->output_main_file ) output_main_file( doc ); /* Parse po/POTFILES.in */ CURRENT_PO_PARSER = g2c_file_parser_new ("po/POTFILES.in", doc->project, FT_PO); /* Parse $src/Makefile.am */ filename = g_strdup_printf ("%s/Makefile.am", doc->project->source_directory); CURRENT_MAKE_PARSER = g2c_file_parser_new (filename, doc->project, FT_MAKE); g_free (filename); /* Parse $src/main.c */ filename = g_strdup_printf ("%s/%s_main.c", doc->project->source_directory, doc->project->program_name); CURRENT_MAIN_PARSER = g2c_file_parser_new (filename, doc->project, FT_MAIN); g_free (filename); /* Make sure that the main file is in po/POTFILES.in and $src/Makefile.am */ filename = g_strdup_printf ("%s/%s_main.c", doc->project->source_directory, doc->project->program_name); if (!g2c_file_parser_item_exists (CURRENT_PO_PARSER, filename)) { g2c_file_parser_add_item (CURRENT_PO_PARSER, filename); } g_free (filename); filename = g_strdup_printf ("%s_main.c", doc->project->program_name); if (!g2c_file_parser_item_exists (CURRENT_MAKE_PARSER, filename)) { g2c_file_parser_add_item (CURRENT_MAKE_PARSER, filename); } g_free (filename); /* For each top level widget, write a separate source file. * Use the directory specified in using the "directory" and * "source_directory" in the project properties. If the * "directory" is NULL, use the current directory. */ g_list_foreach( doc->project->top_level_widgets, output_widget_files, doc ); if (CURRENT_PO_PARSER != NULL) g2c_file_parser_destroy (CURRENT_PO_PARSER); if (CURRENT_MAKE_PARSER != NULL) g2c_file_parser_destroy (CURRENT_MAKE_PARSER); if (CURRENT_MAIN_PARSER != NULL) g2c_file_parser_destroy (CURRENT_MAIN_PARSER); CURRENT_PO_PARSER = NULL; CURRENT_MAKE_PARSER = NULL; CURRENT_MAIN_PARSER = NULL; } /******************************************************************* ** Helper functions ** *******************************************************************/ gchar * spaces_to_ulines( gchar *input ) { int i = 0; for( i = 0; i < strlen( input ); i++ ) { if( input[i] == ' ' ) input[i] = '_'; } return input; } static const xmlChar * get_node_name( xmlNodePtr node ) { if( xmlIsBlankNode( node ) ) return NULL; else return node->name; } static const xmlChar * get_node_text( xmlNodePtr node ) { if ( xmlIsBlankNode( node ) ) return NULL; else if( !xmlNodeIsText( node->childs ) ) return NULL; else return node->childs->content; } static gchar* get_dir_prefix( g2cDoc *doc ) { gchar *directory = NULL; gchar *dir_prefix = NULL; if( NULL != doc->project->directory ) directory = g_strdup( doc->project->directory ); else directory = g_get_current_dir(); dir_prefix = g_strjoin( "/", directory, doc->project->source_directory, NULL ); if (NULL != directory) g_free( directory ); return dir_prefix; /* Freed by caller */ } static void parse_project_properties( g2cDoc *doc ) { /* Get the first top-level widget */ doc->current = doc->current->childs; while( NULL != doc->current ) { /* Skip blank nodes */ if( xmlIsBlankNode( doc->current ) ) { doc->current = doc->current->next; continue; } /* Set the project property */ { g2c_project_set_property( doc->project, get_node_name( doc->current ), get_node_text( doc->current ) ); } doc->current = doc->current->next; } } static void parse_top_level_widgets( g2cDoc *doc ) { xmlNodePtr top = NULL; g2cWidget *widget = NULL; top = doc->current; /* doc->current should be set to the first widget */ while( NULL != top ) { if( xmlIsBlankNode( doc->current ) ) { doc->current = doc->current->next; continue; } widget = parse_widget( doc, NULL ); g2c_project_add_top_level_widget( doc->project, widget ); top = top->next; doc->current = top; } } static g2cWidget * parse_widget( g2cDoc *doc, g2cWidget *parent ) { xmlNodePtr node = NULL; g2cWidget *widget = NULL; g2cWidget *subwidget = NULL; g2cSignal *signal = NULL; g2cAccel *accel = NULL; int order = 0; /* Get the first child node */ doc->current = doc->current->childs; /* Parse the class */ g_assert( strcmp( get_node_name( doc->current ), "class" ) == 0 ); widget = g2c_widget_new( get_node_text( doc->current ) ); widget->parent = parent; if( NULL == widget->klass_name ) { g_print( "%s\n", get_node_name( doc->current ) ); g_print( "%s\n", get_node_text( doc->current ) ); } g_assert( NULL != widget->klass_name ); if( 0 == widget->klass ) g_print( "*** No class found in gtk for %s\n", widget->klass_name ); doc->current = doc->current->next; /* This can either be "name" (gtk) or "child_name" (gnome) if( ( strcmp( get_node_name( doc->current ), "name" ) == 0 ) || ( strcmp( get_node_name( doc->current ), "child_name" ) == 0 ) ) else g_assert_not_reached(); g2c_widget_set_property( widget, get_node_name( doc->current ), get_node_text( doc->current ) ); g_assert( NULL != widget->name ); doc->current = doc->current->next; */ /* Mark the current position in the document */ node = doc->current; /* Get the rest of the properties */ while( NULL != node ) { if( xmlIsBlankNode( node ) ) { node = node->next; doc->current = node; } else if( strcmp( get_node_name( node ), "widget" ) == 0 ) { subwidget = parse_widget( doc, widget ); g2c_widget_add_subwidget( widget, subwidget ); g2c_widget_set_order( subwidget, order++ ); } else if( strcmp( get_node_name( node ), "child" ) == 0 ) { parse_child( doc, widget ); } else if( strcmp( get_node_name( node ), "signal" ) == 0 ) { signal = parse_signal( doc ); g2c_widget_add_signal( widget, signal ); } else if( strcmp( get_node_name( node ), "accelerator" ) == 0 ) { accel = parse_accel( doc ); g2c_widget_add_accel( widget, accel ); } else if( strcmp( get_node_name( node ), "focus_target" ) == 0 ) { g2c_widget_add_focus_target( widget, get_node_text( node ) ); g2c_widget_set_property( widget, get_node_name( node ), get_node_text( node ) ); } else { g2c_widget_set_property( widget, get_node_name( node ), get_node_text( node ) ); } node = node->next; doc->current = node; } /* Post-processing */ /* If this was a GtkRadioMenuItem, look for groups */ if( gtk_type_is_a( widget->klass, GTK_TYPE_RADIO_MENU_ITEM ) || gtk_type_is_a( widget->klass, GTK_TYPE_RADIO_BUTTON ) ) { if( NULL != g2c_widget_get_property( widget, "group" ) ) { g2c_widget_add_radio_group( parent, spaces_to_ulines( g2c_widget_get_property( widget, "group" ) ) ); } else { g_print( "No radio group found for %s\n", widget->name ); } } else if( gtk_type_is_a( widget->klass, GTK_TYPE_OPTION_MENU ) ) { /* Handle option menu: this is tricky! */ g2c_widget_add_option_menu( widget ); } return widget; } static void parse_child( g2cDoc *doc, g2cWidget *widget ) { gboolean flag = FALSE; /* The good stuff starts with this node's children */ doc->current = doc->current->childs; if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_PACKER ) ) { widget->packing_type = PACKER_PACKING; /* Parse the side, anchor, expand, xfill, yfill, use_default, * border_width, xpad, ypad, xipad and yipad */ g_assert( strcmp( get_node_name( doc->current ), "side" ) == 0 ); widget->packing.packer.side = g_strdup( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "anchor" ) == 0 ); widget->packing.packer.anchor = g_strdup( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "expand" ) == 0 ); widget->packing.packer.expand = g2c_get_bool( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "xfill" ) == 0 ); widget->packing.packer.xfill = g2c_get_bool( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "yfill" ) == 0 ); widget->packing.packer.yfill = g2c_get_bool( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "use_default" ) == 0 ); widget->packing.packer.use_default = g2c_get_bool( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "border_width" ) == 0 ); widget->packing.packer.border_width = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "xpad" ) == 0 ); widget->packing.packer.xpad = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "ypad" ) == 0 ); widget->packing.packer.ypad = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "xipad" ) == 0 ); widget->packing.packer.xipad = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "yipad" ) == 0 ); widget->packing.packer.yipad = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_BOX ) ) { widget->packing_type = BOX_PACKING; /* Parse the padding, expand and fill */ g_assert( strcmp( get_node_name( doc->current ), "padding" ) == 0 ); widget->packing.box.padding = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "expand" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.box.expand = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "fill" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.box.fill = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_TABLE ) ) { widget->packing_type = TABLE_PACKING; /* Parse the packing info */ g_assert( strcmp( get_node_name( doc->current ), "left_attach" ) == 0 ); widget->packing.table.left_attach = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "right_attach" ) == 0 ); widget->packing.table.right_attach = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "top_attach" ) == 0 ); widget->packing.table.top_attach = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "bottom_attach" ) == 0 ); widget->packing.table.bottom_attach = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "xpad" ) == 0 ); widget->packing.table.xpad = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "ypad" ) == 0 ); widget->packing.table.ypad = atoi( get_node_text( doc->current ) ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "xexpand" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.table.xexpand = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "yexpand" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.table.yexpand = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "xshrink" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.table.xshrink = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "yshrink" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.table.yshrink = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "xfill" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.table.xfill = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "yfill" ) == 0 ); flag = ( strcmp( get_node_text( doc->current ), "True" ) == 0 ); widget->packing.table.yfill = ( flag ) ? TRUE : FALSE; doc->current = doc->current->next; } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_TOOLBAR ) ) { /* Usually a toolbar widget with a property , * which is boolean */ /* Parse the packing info */ g_assert( strcmp( get_node_name( doc->current ), "new_group" ) == 0 ); g2c_widget_set_property( widget, "new_group", get_node_text( doc->current ) ); doc->current = doc->current->next; } } static g2cAccel * parse_accel( g2cDoc *doc ) { g2cAccel *accel = g2c_accel_new(); /* The good stuff starts with this node's children */ doc->current = doc->current->childs; /* Parse the name and class */ g_assert( strcmp( get_node_name( doc->current ), "modifiers" ) == 0 ); g2c_accel_set_modifiers( accel, get_node_text( doc->current ) ); g_assert( NULL != accel->modifiers ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "key" ) == 0 ); g2c_accel_set_key( accel, get_node_text( doc->current ) ); g_assert( NULL != accel->key ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "signal" ) == 0 ); g2c_accel_set_signal( accel, get_node_text( doc->current ) ); g_assert( NULL != accel->signal ); doc->current = doc->current->next; return accel; } static g2cSignal * parse_signal( g2cDoc *doc ) { g2cSignal *signal = g2c_signal_new(); /* The good stuff starts with this node's children */ doc->current = doc->current->childs; /* Parse the name and class */ g_assert( strcmp( get_node_name( doc->current ), "name" ) == 0 ); g2c_signal_set_name( signal, get_node_text( doc->current ) ); g_assert( NULL != signal->name ); doc->current = doc->current->next; g_assert( strcmp( get_node_name( doc->current ), "handler" ) == 0 ); g2c_signal_set_handler( signal, get_node_text( doc->current ) ); g_assert( NULL != signal->handler ); doc->current = doc->current->next; if( strcmp( get_node_name( doc->current ), "object" ) == 0 ) { g2c_signal_set_object( signal, get_node_text( doc->current ) ); g_assert( NULL != signal->object ); doc->current = doc->current->next; } if( strcmp( get_node_name( doc->current ), "after" ) == 0 ) { g2c_signal_set_after( signal, get_node_text( doc->current ) ); doc->current = doc->current->next; } if( strcmp( get_node_name( doc->current ), "data" ) == 0 ) { g2c_signal_set_data( signal, get_node_text( doc->current ) ); g_assert( NULL != signal->data ); doc->current = doc->current->next; } g_assert( strcmp( get_node_name( doc->current ), "last_modification_time" ) == 0 ); g2c_signal_set_timestamp( signal, get_node_text( doc->current ) ); g_assert( NULL != signal->timestamp ); return signal; } static void output_widget_files( gpointer data, gpointer user_data ) { FILE *file = 0; gchar *dir_prefix = NULL; gchar *file_name = NULL; gchar *temp_file_name = NULL; gchar *gui_name = NULL; gchar *std_name = NULL; gchar *type_name = NULL; gchar *po_name = NULL; gchar *make_name = NULL; g2cWidget *widget = (g2cWidget*) data; g2cDoc *doc = (g2cDoc*) user_data; struct stat s_stat; g_assert( NULL != widget ); g_assert( NULL != doc ); /* Need to create the files in the source directory */ dir_prefix = get_dir_prefix( doc ); /* Does the directory exist? */ if( -1 == stat( dir_prefix, &s_stat ) ) { if( ENOENT == errno ) { /* Directory does not exist. Try to create it. */ mkdir( dir_prefix, 0775 ); } else { g_error( "Could not create or access source directory: %s\n", dir_prefix ); } } /* There are two sets of files created for each widget: * * widget_gui.h struct containing gui; gui create/destroy prototypes * widget_gui.c implementation of the gui constructor/destructor * widget.h struct containing pointer to gui struct; create/destroy prototypes * widget.c implementation of constructor/destructor: calls widget_gui_create() * * Nifty feature: the .h files are written as temporary files, then compared to the original * file to see if any changes occurred (using diff). If no changes were made, then * the file is left untouched (so it doesn't need to be recompiled). Otherwise, the * temp file is renamed to be the old file. */ /* Get the transformed names for the widget */ gui_name = g2c_transform_name( widget->name, NT_GUI ); std_name = g2c_transform_name( widget->name, NT_STANDARD ); type_name = g2c_transform_name( widget->name, NT_TYPENAME ); /* Write widget_gui.h * * #ifndef WIDGET_NAME_GUI_H * #define WIDGET_NAME_GUI_H * * #include * #include // if Gnome enabled * * typedef struct tag_WidgetNameGui * { * * } WidgetNameGui; * * WidgetNameGui* widget_name_gui_create( WidgetName *owner ); * void widget_name_gui_destroy( WidgetNameGui *widget_name_gui ); * * ***Signal handlers *** * * void signal_handler_a( ... ); * void signal_handler_b( ... ); * * #endif * */ /* This file is always blown away then written, so now existence checks are necessary */ file_name = g_strconcat( dir_prefix, "/", widget->name, "_gui.h", NULL ); temp_file_name = g_strconcat( g_get_tmp_dir(), "/", widget->name, "_gui.h", NULL ); make_name = g_strconcat (widget->name, "_gui.h", NULL); /* Make sure this is in $src/Makefile.am */ if (!g2c_file_parser_item_exists (CURRENT_MAKE_PARSER, make_name)) { /* Add to the end of $src/Makefile.am */ g2c_file_parser_add_item (CURRENT_MAKE_PARSER, make_name); } create_if_not_exist( file_name ); file = fopen( temp_file_name, "w" ); if (file == NULL) { printf ("File %s could not be opened. %s\n", temp_file_name, strerror(errno)); g_assert(file != NULL); } CURRENT_FILE = file; /* #ifndef WIDGET_NAME_GUI_H * #define WIDGET_NAME_GUI_H */ fprintf( file, "#ifndef %s\n", gui_name ); fprintf( file, "#define %s\n", gui_name ); fprintf( file, "\n" ); /* #include */ fprintf( file, "#include \n" ); #ifdef USE_GNOME if( doc->project->gnome_support ) fprintf( file, "#include \n" ); #endif fprintf( file, "\n" ); /* typedef struct tag_WindgetNameGui { */ fprintf( file, "typedef struct tag_%sGui\n", type_name ); fprintf( file, "{\n" ); /* GtkTooltips *tooltips; */ fprintf( file, "\t%-20s *%s;\n", "GtkTooltips", "tooltips" ); /* GtkAccelGroup *accelerators */ fprintf( file, "\t%-20s *%s;\n", "GtkAccelGroup", "accel_group" ); /* Groups */ if( NULL != widget->radio_groups ) { g_list_foreach( widget->radio_groups, output_radio_group, NULL ); } /* - all of the subwidgets */ output_widget_struct( widget, file ); /* } WidgetNameGui; */ fprintf( file, "} %sGui;\n", type_name ); fprintf( file, "\n" ); /* WidgetNameGui *widget_name_gui_create( void ); */ fprintf( file, "%sGui *%s_gui_create (gpointer owner);\n", type_name, widget->name ); fprintf( file, "\n" ); /* void widget_name_gui_destroy( WidgetNameGui *gui ); */ fprintf( file, "void %s_gui_destroy (%sGui *%s);\n", widget->name, type_name, widget->name ); fprintf( file, "\n" ); /* Signals prototypes */ /* void signal_handler_a( ... ); */ clear_signal_list (); output_signal_prototype( widget, file ); clear_signal_list (); /* #endif */ fprintf( file, "#endif" ); fprintf( file, "\n" ); fclose( file ); CURRENT_FILE = NULL; /* Compare the temp file with the original file using diff */ handle_file_compare( temp_file_name, file_name ); g_free( file_name ); g_free( temp_file_name ); /* Write widget_gui.c * * #ifdef HAVE_CONFIG_H * # include * #endif * * #include * #include * #include * #include * #include * * #include * #include * #include // if gnome enabled * * #include "widget_gui.h" * * // If this is a gnome app, define UIINFO structs * static GnomeUIInfo file1_menu_uiinfo[] = * { * GNOMEUIINFO_MENU_NEW_ITEM( N_("_New File"), NULL, on_new_file1_activate, NULL ), * ... * } * * WidgetNameGui *widget_name_gui_create( void ) * { * WidgetNameGui *gui = g_new0( WidgetNameGui, 1 ); * * WIDET CREATION CODE * * ACCELERATOR CODE * * SIGNAL CONNECTION CODE * * return gui; * } * * void widget_name_gui_destroy( WidgetNameGui *widget_name ) * { * WIDGET DESTRUCTION CODE * } * * #endif * */ /* This file is always blown away then written, so now existence checks are necessary */ file_name = g_strconcat( dir_prefix, "/", widget->name, "_gui.c", NULL ); temp_file_name = g_strconcat( g_get_tmp_dir(), "/", widget->name, "_gui.c", NULL ); po_name = g_strconcat (doc->project->source_directory, "/", widget->name, "_gui.c", NULL); make_name = g_strconcat (widget->name, "_gui.c", NULL); create_if_not_exist( file_name ); /* Make sure this is in po/POTFILES.in */ if (!g2c_file_parser_item_exists (CURRENT_PO_PARSER, po_name)) { /* Add to the end of po/POTFILES.in */ g2c_file_parser_add_item (CURRENT_PO_PARSER, po_name); } /* Make sure this is in $src/Makefile.am */ if (!g2c_file_parser_item_exists (CURRENT_MAKE_PARSER, make_name)) { /* Add to the end of $src/Makefile.am */ g2c_file_parser_add_item (CURRENT_MAKE_PARSER, make_name); } file = fopen( temp_file_name, "w" ); CURRENT_FILE = file; /* #include */ fprintf( file, "#ifdef HAVE_CONFIG_H\n" "# include \n" "#endif\n" "\n" "#include \n" "#include \n" "#include \n" "#include \n" "#include \n" "\n" "#include \n" "#include \n" "\n" ); #ifdef USE_GNOME if( doc->project->gnome_support ) fprintf( file, "#include \n" ); #endif /* #include widget_name_gui.h */ fprintf( file, "#include \"%s_gui.h\"\n", widget->name ); fprintf( file, "\n" ); /* If this is a gnome app, output widget structs here */ #ifdef USE_GNOME if( doc->project->gnome_support ) { output_gnome_uiinfo( widget, file ); } #endif /* WidgetNameGui *widget_name_gui_create( void ) */ fprintf( file, "%sGui *%s_gui_create (gpointer owner)\n", type_name, widget->name ); fprintf( file, "{\n" ); /* Output temporary declarations */ output_temp_declarations( widget, file ); /* Accelerator Declarations */ output_accelerator_declarations( widget, file ); /* FocusTarget Accelerator Declarations */ output_focus_accelerator_declarations( widget, file ); /* WidgetNameGui *gui = g_new0( WidgetNameGui, 1 ); */ fprintf( file, "\t%sGui *gui = g_new0 (%sGui, 1);\n", type_name, type_name ); fprintf( file, "\n" ); /* Tooltips */ fprintf( file, "\tgui->tooltips = gtk_tooltips_new ();\n" ); /* Accelerators */ fprintf( file, "\tgui->accel_group = gtk_accel_group_new ();\n" ); /* WIDGET CREATION CODE */ fprintf( file, "\n\t/* Widget construction */\n" ); output_widget_create( widget, file, RECURSE_ALL, FALSE ); /* ACCELERATOR CODE */ fprintf( file, "\n\t/* Accelerators */\n" ); output_accelerators( widget, file ); fprintf( file, "\tgtk_window_add_accel_group (GTK_WINDOW (gui->%s), gui->accel_group);\n", widget->name ); /* SIGNAL CONNECTION CODE */ fprintf( file, "\n\t/* Signal connections */\n" ); output_signal_connect( widget, file ); /* return gui; */ fprintf( file, "\treturn gui;\n" ); fprintf( file, "}\n" ); fprintf( file, "\n" ); /* void widget_name_gui_destroy( WidgetNameGui *gui ) */ fprintf( file, "void %s_gui_destroy (%sGui *gui)\n", widget->name, type_name ); fprintf( file, "{\n" ); /* gtk_widget_destroy( gui->widget_name ); */ fprintf( file, "\tgtk_widget_destroy (GTK_WIDGET (gui->%s));\n", widget->name ); /* g_free( gui ); */ fprintf( file, "\tg_free (gui);\n" ); fprintf( file, "}\n" ); fprintf( file, "\n" ); fclose( file ); CURRENT_FILE = NULL; /* Compare the temp file with the original file using diff */ handle_file_compare( temp_file_name, file_name ); g_free( file_name ); g_free( temp_file_name ); g_free( make_name ); /* Write widget.h * * #ifndef WIDGET_NAME_H * #define WIDGET_NAME_H * * #include * #include "widget_gui.h" * * typedef struct tag_WidgetName * { * WidgetNameGui *gui; * \* Put all your stuff here! *\ * } WidgetName; * * WidgetName* widget_name_create( void ); * void widget_name_destroy( WidgetName *widget_name ); * * #endif * */ file_name = g_strconcat( dir_prefix, "/", widget->name, ".h", NULL ); make_name = g_strconcat( widget->name, ".h", NULL); /* Make sure this is in $src/Makefile.am */ if (!g2c_file_parser_item_exists (CURRENT_MAKE_PARSER, make_name)) { /* Add to the end of $src/Makefile.am */ g2c_file_parser_add_item (CURRENT_MAKE_PARSER, make_name); } /* Make sure this widget is createdis in $src/main.c */ g2c_file_parser_update_main_file (CURRENT_MAIN_PARSER, widget); /* Before we blast away this file, check to see if it already exists. * If it does, then we can leave it alone. Otherwise we need to write * some boilerplate code. */ if( g2c_check_file_exists( file_name ) ) { /* The file exists, and we don't update this file after creation */ } else { /* The file does not yet exist, so we're going to create it * and add the boilerplate stuff. */ file = fopen( file_name, "w" ); CURRENT_FILE = file; g_print( "Creating %s\n", file_name ); fprintf( file, "/* Note: this file is only created once! You can modify it all you want.\n" ); fprintf( file, " * If you change the name of the widget, a new file will be created based\n" ); fprintf( file, " * on the new widget name! This file will still exist, however.\n" ); fprintf( file, " */\n" ); fprintf( file, "#ifndef %s\n", std_name ); fprintf( file, "#define %s\n", std_name ); fprintf( file, "\n" ); fprintf( file, "#include \n" ); fprintf( file, "#include \"%s_gui.h\"\n", widget->name ); fprintf( file, "\n" ); fprintf( file, "typedef struct tag_%s\n", type_name ); fprintf( file, "{\n" ); fprintf( file, "\t%sGui *gui;\n", type_name ); fprintf( file, "\t/* Put all your stuff here! */\n" ); fprintf( file, "} %s;\n", type_name ); fprintf( file, "\n" ); fprintf( file, "%s *%s_create (void);\n", type_name, widget->name ); fprintf( file, "\n" ); fprintf( file, "void %s_destroy (%s *%s);\n", widget->name, type_name, widget->name ); fprintf( file, "\n" ); fprintf( file, "#endif" ); fprintf( file, "\n" ); fclose( file ); CURRENT_FILE = NULL; } g_free( file_name ); /* Write widget.c * * #include * #include "widgetname_gui.h" * #include "widgetname.h" * * WidgetNameGui *widgetname_create( void ) * { * WidgetName *widgetname = g_new0 (WidgetName, 1); * widgetname->gui = widgetname_gui_create ((gpointer) widgetname) * * return widgetname; * } * * void widget_name_destroy( WidgetName *widget_name ) * { * gtk_widget_destroy (GTK_WIDGET(widgetname->gui->widgetname)); * g_free (widgetname); * } * * ***Signal handlers *** * * void signal_handler_a( ... ); * void signal_handler_b( ... ); * * #endif * */ file_name = g_strconcat( dir_prefix, "/", widget->name, ".c", NULL ); po_name = g_strconcat (doc->project->source_directory, "/", widget->name, ".c", NULL); make_name = g_strconcat (widget->name, ".c", NULL); CURRENT_FILE_NAME = file_name; CURRENT_FILE = NULL; /* Make sure this is in po/POTFILES.in */ if (!g2c_file_parser_item_exists (CURRENT_PO_PARSER, po_name)) { /* Add to the end of po/POTFILES.in */ g2c_file_parser_add_item (CURRENT_PO_PARSER, po_name); } /* Make sure this is in $src/Makefile.am */ if (!g2c_file_parser_item_exists (CURRENT_MAKE_PARSER, make_name)) { /* Add to the end of $src/Makefile.am */ g2c_file_parser_add_item (CURRENT_MAKE_PARSER, make_name); } if( g2c_check_file_exists( file_name ) ) { /* The file exists, so we are only going to append to it when necessary. * This will happen in output_signal_handler */ CURRENT_SOURCE_PARSER = g2c_file_parser_new( file_name, doc->project, FT_SOURCE ); } else { /* The file does not yet exist, so we're going to create it * and add the boilerplate stuff. */ file = fopen( file_name, "w" ); CURRENT_FILE = file; g_print( "Creating %s\n", file_name ); fprintf( file, "#include \n" ); fprintf( file, "#include \"%s_gui.h\"\n", widget->name ); fprintf( file, "#include \"%s.h\"\n", widget->name ); fprintf( file, "\n" ); fprintf( file, "%s *%s_create (void)\n", type_name, widget->name ); fprintf( file, "{\n" ); fprintf( file, "\t%s *%s = g_new0 (%s, 1);\n", type_name, widget->name, type_name ); fprintf( file, "\t%s->gui = %s_gui_create ((gpointer) %s);\n", widget->name, widget->name, widget->name ); fprintf( file, "\n" ); fprintf( file, "\treturn %s;\n", widget->name ); fprintf( file, "}\n" ); fprintf( file, "\n" ); fprintf( file, "void %s_destroy (%s *%s)\n", widget->name, type_name, widget->name ); fprintf( file, "{\n" ); fprintf( file, "\tgtk_widget_destroy (GTK_WIDGET(%s->gui->%s));\n", widget->name, widget->name ); fprintf( file, "\tg_free (%s);\n", widget->name ); fprintf( file, "}\n" ); } output_signal_handler( widget, file ); /* Make sure there is a newline at the end of the file (gcc needs it) */ g_free( file_name ); if( NULL != CURRENT_FILE ) { fclose( CURRENT_FILE ); } /* Clean up */ g_free( dir_prefix ); g_free( gui_name ); g_free( std_name ); g_free( type_name ); g_free( make_name ); if( NULL != CURRENT_SOURCE_PARSER ) g2c_file_parser_destroy( CURRENT_SOURCE_PARSER ); CURRENT_FILE = NULL; CURRENT_FILE_NAME = NULL; CURRENT_SOURCE_PARSER = NULL; } static void output_widget_create( g2cWidget *widget, FILE *file, gint recurse_levels, gboolean properties_only ) { gchar *func_name = NULL; gchar *x_attach_options = NULL; gchar *y_attach_options = NULL; gboolean expand, shrink, fill; gboolean output_create = TRUE; gchar *create_string = NULL; GList *children = NULL; g_assert( NULL != widget ); g_assert( NULL != file ); func_name = g2c_transform_name( widget->klass_name, NT_FUNCTION ); /* Output the create string for the widget. * Some really strange constructors, namely ones with dependencies, * are in the else clauses. * * Also, for certain widgets the widget has been pre-created by the framework. * Examples are dialog action areas and GnomeApp widgets. The constructors for * these functions are handled elsewhere. In all cases, the properties_only * flag will be set to TRUE, and the constructor logic will be bypassed. * * Since the Gnome code is so different from the GTK code, we will use separate * handlers for them. */ /* In some cases, we don't want to make a create string. Usually this is because * the widget is created indirectly, such as when a button is added to a toolbar */ #ifdef SOURCE_DEBUG fprintf( file, "\tg_print(\"Handling %s\\n\");\n", widget->name ); #endif if( NULL != widget->parent ) { if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_TOOLBAR ) ) if( strcmp( widget->klass_name, "GtkRadioButton" ) == 0 || strcmp( widget->klass_name, "GtkToggleButton" ) == 0 || strcmp( widget->klass_name, "GtkButton" ) == 0 ) output_create = FALSE; } if( !properties_only ) { #ifdef USE_GNOME if( gtk_type_is_a( widget->klass, GNOME_TYPE_DIALOG ) ) { recurse_levels = RECURSE_NONE; output_gnome_dialog( widget, file ); } else #endif /* USE_GNOME */ { /* Gtk widget */ if( gtk_type_is_a( widget->klass, GTK_TYPE_MENU_ITEM ) && ( NULL == g2c_widget_get_property( widget, "label" ) ) ) { if( CURRENT_PROJECT->gnome_support ) { /* Refer to the element in the uiinfo menu structures */ fprintf( file, "\tgui->%s = (%s*) %s_uiinfo[%d].widget;\n", widget->name, widget->klass_name, widget->parent->name, widget->order ); } else { /* Just create the item */ fprintf( file, "\tgui->%s = (GtkMenuItem*) gtk_menu_item_new ();\n", widget->name ); } } else if( gtk_type_is_a( widget->klass, GTK_TYPE_MENU_SHELL ) && !gtk_type_is_a( widget->parent->klass, GTK_TYPE_OPTION_MENU ) && CURRENT_PROJECT->gnome_support ) { create_string = g2c_widget_create_string( widget ); if( NULL != create_string ) { fprintf( file, create_string ); g_free( create_string ); } fprintf( file, "\tgnome_app_fill_menu (GTK_MENU_SHELL (gui->%s),\n" "\t %s_uiinfo,\n" "\t gui->accel_group,\n" "\t TRUE,\n" "\t 0);\n", widget->name, widget->name ); } else { /* gui->widget_name = widget_type_new(); */ create_string = g2c_widget_create_string( widget ); if( NULL != create_string ) { fprintf( file, create_string ); g_free( create_string ); } } if( gtk_type_is_a( widget->klass, GTK_TYPE_RADIO_BUTTON ) && ( FALSE == CURRENT_PROJECT->gnome_support ) ) { fprintf( file, "\tgui->%s = gtk_radio_button_group (GTK_RADIO_BUTTON (gui->%s));\n", spaces_to_ulines( g2c_widget_get_property( widget, "group" ) ), widget->name ); } if( NULL != widget->parent ) { if( gtk_type_is_a( widget->klass, GTK_TYPE_MENU ) ) { /* Handle a menu */ output_menu( widget, file ); } else if( gtk_type_is_a( widget->klass, GTK_TYPE_MENU_ITEM ) ) { /* Handle a menu item */ output_menu_item( widget, file ); if( gtk_type_is_a( widget->klass, GTK_TYPE_RADIO_MENU_ITEM ) && ( FALSE == CURRENT_PROJECT->gnome_support ) ) { fprintf( file, "\tgui->%s = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM(gui->%s));\n", g2c_widget_get_property( widget, "group" ), widget->name ); } } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_TOOLBAR ) ) { /* This is a child widget of a GtkToolbar */ output_toolbar_widget( widget, file ); } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_CLIST ) ) { /* This is a column in a CList (or derivative) */ output_clist_column( widget, file ); } /* Pack the widget, if necessary */ if( !widget->klass || !widget->parent->klass ) g_print( "%s:%d, %s:%d\n", widget->klass_name, widget->klass, widget->parent->klass_name, widget->parent->klass ); if( ( gtk_type_is_a( widget->parent->klass, GTK_TYPE_CONTAINER ) ) && ( !gtk_type_is_a( widget->klass, GTK_TYPE_MENU_ITEM ) ) && ( !gtk_type_is_a( widget->klass, GTK_TYPE_MENU ) ) && ( !gtk_type_is_a( widget->parent->klass, GTK_TYPE_TOOLBAR ) ) && ( !gtk_type_is_a( widget->parent->klass, GTK_TYPE_CLIST ) ) && ( strcmp( widget->parent->klass_name, "GtkCombo" ) != 0 ) ) { if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_BOX ) && ( widget->child_name == NULL ) ) { /* gtk_box_pack_end (GTK_BOX (the_parent), widget_name, expand, fill, padding); */ fprintf( file, "\tgtk_box_pack_start (GTK_BOX (gui->%s), \n" "\t GTK_WIDGET (gui->%s), %s, %s, %d);\n", widget->parent->name, widget->name, widget->packing.box.expand ? "TRUE" : "FALSE", widget->packing.box.fill ? "TRUE" : "FALSE", widget->packing.box.padding ); } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_LAYOUT ) ) { fprintf( file, "\tgtk_layout_put (GTK_LAYOUT (gui->%s), GTK_WIDGET (gui->%s), %s, %s);\n", widget->parent->name, widget->name, g2c_widget_get_property( widget, "x" ), g2c_widget_get_property( widget, "y" ) ); } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_PACKER ) ) { gchar *option_names[3] = { "GTK_PACK_EXPAND", "GTK_FILL_X", "GTK_FILL_Y" }; gchar *options[4] = { NULL, NULL, NULL, NULL }; gchar *option_string = NULL; guint i = 0; if( widget->packing.packer.expand ) options[i++] = g_strdup( option_names[0] ); if( widget->packing.packer.xfill ) options[i++] = g_strdup( option_names[1] ); if( widget->packing.packer.yfill ) options[i++] = g_strdup( option_names[2] ); option_string = g_strjoinv( " | ", (gchar**) options ); if( g2c_get_bool( g2c_widget_get_property( widget, "use_default" ) ) ) { fprintf( file, "\tgtk_packer_add_defaults (GTK_PACKER (gui->%s), GTK_WIDGET (gui->%s), \n" "\t %s, %s, (GtkPackerOptions) (%s));\n", widget->parent->name, widget->name, widget->packing.packer.side, widget->packing.packer.anchor, option_string ); } else { fprintf( file, "\tgtk_packer_add (GTK_PACKER (gui->%s), GTK_WIDGET (gui->%s), \n" "\t %s, %s, (GtkPackerOptions) (%s), \n" "\t %d, %d, %d, %d, %d);\n", widget->parent->name, widget->name, widget->packing.packer.side, widget->packing.packer.anchor, option_string, widget->packing.packer.border_width, widget->packing.packer.xpad, widget->packing.packer.ypad, widget->packing.packer.xipad, widget->packing.packer.yipad ); } g_free( option_string ); for( i = 0; i < 4; i++ ) if( NULL != options[i] ) g_free( options[i] ); } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_TABLE ) ) { expand = widget->packing.table.xexpand; shrink = widget->packing.table.xshrink; fill = widget->packing.table.xfill; x_attach_options = g_strdup_printf( "%s%s%s%s%s", expand ? "GTK_EXPAND" : "", ( expand && shrink ) ? " | " : "", shrink ? "GTK_SHRINK" : "", ( ( expand || shrink ) && fill ) ? " | " : "", fill ? "GTK_FILL" : "" ); if( strcmp( x_attach_options, "" ) == 0 ) { g_free( x_attach_options ); x_attach_options = g_strdup( "0" ); } expand = widget->packing.table.yexpand; shrink = widget->packing.table.yshrink; fill = widget->packing.table.yfill; y_attach_options = g_strdup_printf( "%s%s%s%s%s", expand ? "GTK_EXPAND" : "", ( expand && shrink ) ? " | " : "", shrink ? "GTK_SHRINK" : "", ( ( expand || shrink ) && fill ) ? " | " : "", fill ? "GTK_FILL" : "" ); if( strcmp( y_attach_options, "" ) == 0 ) { g_free( y_attach_options ); y_attach_options = g_strdup( "0" ); } fprintf( file, "\tgtk_table_attach (GTK_TABLE (gui->%s ), \n" "\t GTK_WIDGET(gui->%s ),\n" "\t %d, %d, %d, %d,\n" "\t %s, %s,\n" "\t %d, %d);\n", widget->parent->name, widget->name, widget->packing.table.left_attach, widget->packing.table.right_attach, widget->packing.table.top_attach, widget->packing.table.bottom_attach, x_attach_options, y_attach_options, widget->packing.table.xpad, widget->packing.table.ypad ); g_free( x_attach_options ); g_free( y_attach_options ); } #ifdef USE_GNOME else if( gtk_type_is_a( widget->parent->klass, GNOME_TYPE_DRUID ) ) { /* Handle Gnome Druids */ if( gtk_type_is_a( widget->klass, GNOME_TYPE_DRUID_PAGE ) ) { fprintf( file, "\tgnome_druid_append_page (GNOME_DRUID (gui->%s),\n" "\t GNOME_DRUID_PAGE (gui->%s));\n", widget->parent->name, widget->name ); } } #endif else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_NOTEBOOK ) ) { /* Labels are added in this statement, so don't add them again */ if( !gtk_type_is_a( widget->klass, GTK_TYPE_LABEL ) ) { fprintf( file, "\tgtk_notebook_append_page (GTK_NOTEBOOK (gui->%s),\n" "\t GTK_WIDGET (gui->%s),\n" "\t GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->name, g2c_widget_get_property( widget, "_tab_label" ) ); } } #ifdef USE_GNOME else if( gtk_type_is_a( widget->parent->klass, GNOME_TYPE_APP ) ) { /* This is either a GnomeDock or a GnomeAppBar. * GnomeDock is never added (it already was created/added). * GnomeAppBar is added using the gnome_app_set_statusbar call. */ if( gtk_type_is_a( widget->klass, GNOME_TYPE_APPBAR ) ) { fprintf( file, "\tgnome_app_set_statusbar (GNOME_APP (gui->%s),\n" "\t GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->name ); } } else if( gtk_type_is_a( widget->parent->klass, GNOME_TYPE_DOCK ) ) { /* This is either a GnomeDockItem or the center widget. * If this is a GnomeDockItem, and the child widget is a menubar, * then we use a special call for it. */ if( gtk_type_is_a( widget->klass, GNOME_TYPE_DOCK_ITEM ) ) { /* GnomeDockItem */ fprintf( file, "\tgnome_app_add_dock_item (GNOME_APP (gui->%s),\n" "\t gui->%s,\n" "\t %s, %s, %s, %s);\n\n", g2c_widget_get_top_parent( widget )->name, widget->name, g2c_widget_get_property( widget, "placement" ), g2c_widget_get_property( widget, "band" ), g2c_widget_get_property( widget, "position" ), g2c_widget_get_property( widget, "offset" ) ); } else { /* Center widget */ fprintf( file, "\tgnome_app_set_contents( GNOME_APP (gui->%s),\n" "\t GTK_WIDGET (gui->%s));\n", g2c_widget_get_top_parent( widget )->name, widget->name ); } } #endif /* USE_GNOME */ else if( widget->child_name == NULL ) { fprintf( file, "\tgtk_container_add (GTK_CONTAINER (gui->%s),\n" "\t GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->name ); } } } } } /* Write out the properties */ g_hash_table_foreach( widget->properties, g2c_widget_create_arg_cb, widget ); if( !properties_only ) /* Need a way to get the owning class from this widget */ { fprintf( file, "\tgtk_object_set_data (GTK_OBJECT (gui->%s), \"owner\", owner);\n", widget->name ); fprintf( file, "\n" ); if( strcmp( widget->klass_name, "GtkMenu" ) != 0 ) { if( CURRENT_PROJECT->gnome_support && gtk_type_is_a( widget->klass , GTK_TYPE_MENU_ITEM ) && !gtk_type_is_a( widget->parent->parent->klass, GTK_TYPE_OPTION_MENU ) ) {} else if( NULL == g2c_widget_get_property( widget, "visible" ) ) { fprintf( file, "\tgtk_widget_show (GTK_WIDGET (gui->%s));\n\n", widget->name ); } } /* Recursively handle the children of this widget */ children = g_list_first( widget->children ); while( ( NULL != children ) && ( recurse_levels > 0 ) ) { /* Call this function recursively. */ output_widget_create( children->data, file, recurse_levels, properties_only ); children = g_list_next( children ); } recurse_levels--; /* Handle options that are only usuable AFTER the children have been output */ g_hash_table_foreach( widget->properties, g2c_widget_output_after_children_cb, widget ); } /* Menus attached to option menus must be added AFTER the menus have been created! */ if( gtk_type_is_a( widget->klass, GTK_TYPE_MENU ) && gtk_type_is_a( widget->parent->klass, GTK_TYPE_OPTION_MENU ) ) { fprintf( file, "\tgtk_option_menu_set_menu (GTK_OPTION_MENU (gui->%s), GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->name ); } if( NULL != func_name ) g_free( func_name ); } static void output_temp_declarations( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); g_list_foreach( (gpointer) widget->children, (GFunc ) g2c_widget_create_temp_declaration_cb, (gpointer) NULL ); /* These only appear in top-level widgets, so no recursion is necessary */ g_list_foreach( (gpointer) widget->children, (GFunc) output_temp_declarations, (gpointer) file ); } static void output_accelerator_declarations( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); g_list_foreach( (gpointer) widget->children, (GFunc ) g2c_widget_create_accel_declaration_cb, (gpointer) NULL ); /* These only appear in top-level widgets, so no recursion is necessary */ g_list_foreach( (gpointer) widget->children, (GFunc) output_accelerator_declarations, (gpointer) file ); } static void output_focus_accelerator_declarations( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); g_list_foreach( widget->accelerators, g2c_widget_create_focus_accel_declaration_cb, widget ); /* These only appear in top-level widgets, so no recursion is necessary */ } static void output_accelerators( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); g_list_foreach( widget->accelerators, g2c_widget_create_accel_cb, widget ); /* Recursively handle the children of this widget */ g_list_foreach( (gpointer) widget->children, (GFunc) output_accelerators, (gpointer) file ); } static void output_signal_handler( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); g_list_foreach( widget->signals, g2c_widget_create_signal_handler_cb, widget ); /* Recursively handle the children of this widget */ g_list_foreach( (gpointer) widget->children, (GFunc) output_signal_handler, (gpointer) file ); } static void output_signal_connect( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); g_list_foreach( widget->signals, g2c_widget_create_signal_connect_cb, widget ); /* Recursively handle the children of this widget */ g_list_foreach( (gpointer) widget->children, (GFunc) output_signal_connect, (gpointer) file ); } static void output_signal_prototype( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); g_list_foreach( widget->signals, g2c_widget_create_signal_prototype_cb, widget ); /* Recursively handle the children of this widget */ g_list_foreach( (gpointer) widget->children, (GFunc) output_signal_prototype, (gpointer) file ); } static void output_widget_struct( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); fprintf( CURRENT_FILE, "\t%-20s *%s;\n", widget->klass_name, widget->name ); if( gtk_type_is_a( widget->klass, GTK_TYPE_MENU ) ) { /* Create an accelerator group */ fprintf( CURRENT_FILE, "\t%-20s *%s_accel_group;\n", "GtkAccelGroup", widget->name ); } /* Recursively handle the children of this widget */ g_list_foreach( (gpointer) widget->children, (GFunc) output_widget_struct, (gpointer) file ); } static void output_toolbar_widget( g2cWidget *widget, FILE* file ) { gchar *label = NULL; gchar *tooltip = NULL; gchar *widget_type = NULL; gchar *pixmap_widget = NULL; g_assert( NULL != widget ); g_assert( NULL != file ); /* Label */ if( NULL != g2c_widget_get_property( widget, "label" ) ) label = g_strdup_printf( "_(\"%s\")", g2c_widget_get_property( widget, "label" ) ); /* Tooltip */ if( NULL != g2c_widget_get_property( widget, "tooltip" ) ) tooltip = g_strdup_printf( "_(\"%s\")", g2c_widget_get_property( widget, "tooltip" ) ); /* What type of widget are we appending? */ if( strcmp( widget->klass_name, "GtkRadioButton" ) == 0 ) widget_type = g_strdup( "GTK_TOOLBAR_CHILD_RADIOBUTTON" ); else if( strcmp( widget->klass_name, "GtkToggleButton" ) == 0 ) widget_type = g_strdup( "GTK_TOOLBAR_CHILD_TOGGLEBUTTON" ); else if( CURRENT_PROJECT->gnome_support && ( strcmp( widget->klass_name, "GtkButton" ) == 0 ) ) widget_type = g_strdup( "GTK_TOOLBAR_CHILD_BUTTON" ); /* How shall the pixmap be created? */ if( NULL != g2c_widget_get_property( widget, "stock_pixmap" ) ) { /* This only happens under gnome */ pixmap_widget = g_strdup_printf( "gnome_stock_pixmap_widget (GTK_WIDGET (gui->%s), %s)", widget->name, g2c_widget_get_property( widget, "stock_pixmap" ) ); } else if( NULL != g2c_widget_get_property( widget, "icon" ) ) { if( CURRENT_PROJECT->gnome_support ) { pixmap_widget = g_strdup_printf( "gnome_pixmap_new_from_file (\"%s/%s\")", CURRENT_PROJECT->pixmaps_directory, g2c_widget_get_property( widget, "icon" ) ); } else { pixmap_widget = g_strdup_printf( "create_pixmap (GTK_WIDGET (gui->%s), \"%s/%s\")", widget->name, CURRENT_PROJECT->pixmaps_directory, g2c_widget_get_property( widget, "icon" ) ); } } /* If this widget starts a new group, then add a spacer */ if( NULL != g2c_widget_get_property( widget, "new_group" ) ) { /* Output a spacer */ fprintf( file, "\tgtk_toolbar_append_space (GTK_TOOLBAR (gui->%s));\n", widget->parent->name ); } /* If this is a plain widget */ if( NULL == widget_type ) { fprintf( file, "\tgtk_toolbar_append_widget (GTK_TOOLBAR (gui->%s),\n" "\t GTK_WIDGET (gui->%s),\n" "\t %s, NULL);\n", widget->parent->name, widget->name, ( NULL == tooltip ) ? "NULL" : tooltip ); } /* If this is not a plain widget */ else { fprintf( file, "\tgui->%s = (%s*) gtk_toolbar_append_element (\n" "\t GTK_TOOLBAR (gui->%s),\n" "\t %s,\n" "\t NULL,\n" "\t %s,\n" "\t %s,\n" "\t NULL,\n" "\t %s,\n" "\t NULL, NULL);\n", widget->name, widget->klass_name, widget->parent->name, widget_type, ( NULL == label ) ? "NULL" : label, ( NULL == tooltip ) ? "NULL" : tooltip, ( NULL == pixmap_widget ) ? "NULL" : pixmap_widget ); } if( NULL != label ) g_free( label ); if( NULL != tooltip ) g_free( tooltip ); if( NULL != widget_type ) g_free( widget_type ); if( NULL != pixmap_widget ) g_free( pixmap_widget ); } static void output_clist_column( g2cWidget *widget, FILE *file ) { g_assert( NULL != widget ); g_assert( NULL != file ); fprintf( file, "\tgtk_clist_set_column_widget (GTK_CLIST (gui->%s), %d, GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->order, widget->name ); } static void output_menu( g2cWidget *widget, FILE* file ) { if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_MENU_ITEM ) ) { if( CURRENT_PROJECT->gnome_support ) return; fprintf( file, "\tgtk_menu_item_set_submenu (GTK_MENU_ITEM (gui->%s), GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->name ); fprintf( file, "\tgui->%s_accel_group = gtk_menu_ensure_uline_accel_group (GTK_MENU (gui->%s));\n", widget->name, widget->name ); } } static void output_menu_item( g2cWidget *widget, FILE* file ) { /* Note: the following line is a hack for now, since GTK_TYPE_MENU_BAR is not * defined withing gtkmenubar.h */ if( CURRENT_PROJECT->gnome_support && !gtk_type_is_a( widget->parent->parent->klass, GTK_TYPE_OPTION_MENU ) ) return; if( strcmp( widget->parent->klass_name, "GtkMenuBar" ) == 0 ) { /* Append to the menubar */ fprintf( file, "\tgtk_menu_bar_append (GTK_MENU_BAR (gui->%s), GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->name ); } else if( gtk_type_is_a( widget->parent->klass, GTK_TYPE_MENU ) ) { fprintf( file, "\tgtk_menu_append (GTK_MENU (gui->%s), GTK_WIDGET (gui->%s));\n", widget->parent->name, widget->name ); if( NULL == g2c_widget_get_property( widget, "label" ) ) { fprintf( file, "\tgtk_widget_set_sensitive (GTK_WIDGET (gui->%s), FALSE);\n", widget->name ); } } else { g_print( "Shouldn't be here! %s %s %d\n", widget->name, widget->parent->klass_name, widget->parent->klass ); g_assert_not_reached(); } } static void output_radio_group( gpointer data, gpointer user_data ) { gchar *radio_group = (gchar *) data; fprintf( CURRENT_FILE, "\t%-20s *%s;\n", "GSList", radio_group ); } static void init_types( g2cDoc *doc ) { GTK_TYPE_WIDGET; GTK_TYPE_CONTAINER; GTK_TYPE_BIN; GTK_TYPE_BUTTON; GTK_TYPE_ACCEL_LABEL; GTK_TYPE_ADJUSTMENT; GTK_TYPE_ALIGNMENT; GTK_TYPE_ARROW; GTK_TYPE_ASPECT_FRAME; GTK_TYPE_BOX; GTK_TYPE_CALENDAR; GTK_TYPE_CHECK_BUTTON; GTK_TYPE_CHECK_MENU_ITEM; GTK_TYPE_CLIST; GTK_TYPE_COLOR_SELECTION; GTK_TYPE_COLOR_SELECTION_DIALOG; GTK_TYPE_CTREE; GTK_TYPE_CURVE; GTK_TYPE_DATA; GTK_TYPE_DIALOG; GTK_TYPE_DRAWING_AREA; GTK_TYPE_EDITABLE; GTK_TYPE_ENTRY; GTK_TYPE_EVENT_BOX; GTK_TYPE_FILE_SELECTION; GTK_TYPE_FIXED; GTK_TYPE_FONT_SELECTION; GTK_TYPE_FONT_SELECTION_DIALOG; GTK_TYPE_FRAME; GTK_TYPE_HANDLE_BOX; GTK_TYPE_HBOX; GTK_TYPE_HSCALE; GTK_TYPE_HSCROLLBAR; GTK_TYPE_HSEPARATOR; GTK_TYPE_IMAGE; GTK_TYPE_INPUT_DIALOG; /* GTK_TYPE_INVISIBLE; */ GTK_TYPE_ITEM; GTK_TYPE_LABEL; GTK_TYPE_LAYOUT; GTK_TYPE_LIST; GTK_TYPE_LIST_ITEM; GTK_TYPE_MENU; GTK_TYPE_MISC; GTK_TYPE_NOTEBOOK; GTK_TYPE_OPTION_MENU; GTK_TYPE_PACKER; GTK_TYPE_PANED; GTK_TYPE_PIXMAP; GTK_TYPE_PREVIEW; GTK_TYPE_PROGRESS; GTK_TYPE_PROGRESS_BAR; GTK_TYPE_RADIO_BUTTON; GTK_TYPE_RADIO_MENU_ITEM; GTK_TYPE_RANGE; GTK_TYPE_RULER; GTK_TYPE_SCALE; GTK_TYPE_SCROLLBAR; GTK_TYPE_SCROLLED_WINDOW; GTK_TYPE_SEPARATOR; GTK_TYPE_SPIN_BUTTON; GTK_TYPE_TABLE; GTK_TYPE_TEAROFF_MENU_ITEM; GTK_TYPE_TEXT; GTK_TYPE_TOGGLE_BUTTON; GTK_TYPE_TOOLBAR; GTK_TYPE_TOOLTIPS; GTK_TYPE_TREE; GTK_TYPE_TREE_ITEM; /* GTK_TYPE_MAKE; */ /* GTK_TYPE_SEQNO; */ GTK_TYPE_VBOX; GTK_TYPE_VIEWPORT; GTK_TYPE_VSCALE; GTK_TYPE_VSCROLLBAR; GTK_TYPE_VSEPARATOR; GTK_TYPE_WINDOW; #ifdef USE_GNOME if( doc->project->gnome_support ) { gnomelib_init( "G2C", "1.0" ); GTK_TYPE_DIAL; GTK_TYPE_CLOCK; GNOME_TYPE_CANVAS_IMAGE; GNOME_TYPE_CANVAS_LINE; GNOME_TYPE_CANVAS_POLYGON; GNOME_TYPE_CANVAS_RE; GNOME_TYPE_CANVAS_RECT; GNOME_TYPE_CANVAS_ELLIPSE; GNOME_TYPE_CANVAS_TEXT; GNOME_TYPE_CANVAS_WIDGET; GNOME_TYPE_CANVAS_ITEM; GNOME_TYPE_CANVAS_GROUP; GNOME_TYPE_CANVAS; GNOME_TYPE_COLOR_PICKER; GNOME_TYPE_FONT_PICKER; GNOME_TYPE_DRUID_PAGE_FINISH; GNOME_TYPE_DRUID_PAGE_STANDARD; GNOME_TYPE_DRUID_PAGE_START; GNOME_TYPE_DRUID_PAGE; GNOME_TYPE_DRUID; GNOME_TYPE_ABOUT; GNOME_TYPE_ANIMATOR; GNOME_TYPE_APP; GNOME_TYPE_APPBAR; GNOME_TYPE_CALCULATOR; GNOME_TYPE_CANVAS_ITEM; GNOME_TYPE_CANVAS_GROUP; GNOME_TYPE_CANVAS; GNOME_TYPE_CANVAS_IMAGE; GNOME_TYPE_CANVAS_LINE; GNOME_TYPE_CANVAS_RE; GNOME_TYPE_CANVAS_RECT; GNOME_TYPE_CANVAS_ELLIPSE; GNOME_TYPE_CANVAS_POLYGON; GNOME_TYPE_CANVAS_TEXT; GNOME_TYPE_CANVAS_WIDGET; GNOME_TYPE_CLIENT; GNOME_TYPE_COLOR_PICKER; GNOME_TYPE_DATE_EDIT; GNOME_TYPE_DENTRY_EDIT; GNOME_TYPE_DIALOG; GNOME_TYPE_DOCK; GNOME_TYPE_DOCK_BAND; GNOME_TYPE_DOCK_ITEM; GNOME_TYPE_DOCK_LAYOUT; GNOME_TYPE_DRUID; GNOME_TYPE_DRUID_PAGE; GNOME_TYPE_DRUID_PAGE_START; GNOME_TYPE_DRUID_PAGE_STANDARD; GNOME_TYPE_DRUID_PAGE_FINISH; GNOME_TYPE_ENTRY; GNOME_TYPE_FILE_ENTRY; GNOME_TYPE_FONT_PICKER; GNOME_TYPE_FONT_SELECTOR; GNOME_TYPE_GURU; GNOME_TYPE_HREF; GNOME_TYPE_ICON_LIST; GNOME_TYPE_ICON_TEXT_ITEM; GNOME_TYPE_ICON_SELECTION; GNOME_TYPE_ICON_ENTRY; GNOME_TYPE_LESS; GNOME_TYPE_MESSAGE_BOX; GNOME_TYPE_MDI; GNOME_TYPE_MDI_CHILD; GNOME_TYPE_MDI_GENERIC_CHILD; GNOME_TYPE_NUMBER_ENTRY; GNOME_TYPE_PROPERTY_BOX; GNOME_TYPE_PIXMAP; GNOME_TYPE_PIXMAP_ENTRY; GNOME_TYPE_SCORES; GNOME_TYPE_SPELL; GNOME_TYPE_STOCK; GNOME_TYPE_PAPER_SELECTOR; GNOME_TYPE_PROC_BAR; } #endif } static void output_gnome_dialog( g2cWidget *widget, FILE *file ) { g2cWidget *vbox = NULL; g2cWidget *action_area = NULL; g2cWidget *button = NULL; GList *buttons = NULL; GList *user_widgets = NULL; gchar *title = NULL; g_assert( NULL != widget ); g_assert( NULL != file ); /* The structure of a Gnome Dialog: * * GtkWindow * | * |--GtkVBox ( child_name=GnomeDialog:vbox ) * | * |--GtkHButtonBox ( action area, pack=GTK_PACK_END, child_name=GnomeDialog:action_area ) * | | * | |-- GtkButton(s) ( stock_button = stockbutton type ) * | * |--User Widget(s) (handle as usual) * * Just to make things more interesting, the buttons in the action area are not created * separately. Instead, they are passed along with the title to the constructor of * the GnomeDialog. */ /* The first child is the GtkVBox */ vbox = (g2cWidget*) g_list_first( widget->children )->data; action_area = (g2cWidget*) g_list_first( vbox->children )->data; buttons = g_list_first( action_area->children ); g_assert( vbox ); g_assert( action_area ); g_assert( buttons ); if( NULL == title ) title = g_strdup( "\"\"" ); else title = g_strdup_printf( "_(\"%s\")", g2c_widget_get_property( widget, "title" ) ); /* Write the constructor */ fprintf( file, "\tgui->%s = (GnomeDialog*) gnome_dialog_new (%s, NULL);\n", widget->name, title ); /* Need the names of each of the buttons */ while( NULL != buttons ) { button = (g2cWidget*) buttons->data; /* Add this button to the action area */ fprintf( file, "\tgnome_dialog_append_button (GNOME_DIALOG(gui->%s), %s);\n", widget->name, g2c_widget_get_property( button, "stock_button" ) ); fprintf( file, "\tgui->%s = (GtkButton*) g_list_last (GNOME_DIALOG (gui->%s)->buttons)->data;\n", button->name, widget->name ); output_widget_create( button, file, RECURSE_NONE, TRUE ); buttons = g_list_next( buttons ); } fprintf( file, "\tgui->%s = GTK_VBOX (gui->%s->vbox);\n", vbox->name, widget->name ); output_widget_create( vbox, file, RECURSE_NONE, TRUE ); /* Now handle the user widgets */ user_widgets = g_list_next( vbox->children ); while( NULL != user_widgets ) { output_widget_create( user_widgets->data, file, RECURSE_ALL, FALSE ); user_widgets = g_list_next( user_widgets ); } if( NULL != title ) g_free( title ); } static void output_gnome_uiinfo( g2cWidget *widget, FILE *file ) { g2cWidget *menubar = NULL; g_assert( NULL != widget ); g_assert( NULL != file ); /* Output structs for menus and toolbars * static GnomeUIInfo file1_menu_uiinfo[] = * { * GNOMEUIINFO_MENU_NEW_ITEM (N_("_New File"), NULL, on_new_file1_activate, NULL), * GNOMEUIINFO_MENU_OPEN_ITEM (on_open1_activate, NULL), * GNOMEUIINFO_MENU_SAVE_ITEM (on_save1_activate, NULL), * GNOMEUIINFO_MENU_SAVE_AS_ITEM (on_save_as1_activate, NULL), * GNOMEUIINFO_SEPARATOR, * GNOMEUIINFO_MENU_EXIT_ITEM (on_exit1_activate, NULL), * GNOMEUIINFO_END * }; */ /* First we need to find the menubar in the widget list. */ menubar = g2c_widget_find_by_type_name( widget, "GtkMenuBar" ); /* Parse the menus. * * If the widget has a member, then we will use a stock gnome UIInfo struct. * Otherwise we will create a special struct for it (see GnomeUIInfoStruct for details). * * STRUCTURE * * GtkMenuBar * |--GtkMenuItem * | |--GtkMenu * | | |--GtkPixmapMenuItem/GtkMenuItem/etc. * | | | |--GtkMenu * | | | | |--GtkMenuItem (recursive) * | | |--GtkPixmapMenuItem/GtkMenuItem/etc. * | |--GtkMenu... * |--GtkMenuItem... * * Structs are created for each menubar/menuitem/subtree, but the only one that * is referenced in the widget_create function is the menubar (menubar1_uiinfo). * In the call to create the menubar (if a gnome app), we just use the menubar entry, * and do no recursion (see output_menu_bar); * * To make things more interesting, these structures refer to their child structures, * so we need to write out the structures for child menus before we output the * structures for the menu itself. Consider the file structure below: * * File Edit View * Open Cut Side * ---- Copy Front * Exit Paste Back * * We need to output the structures in this order: * * File { Open, Separator, Exit } * Edit { Cut, Copy, Paste } * Side { Front, Back } <-- Note that this comes before View! * View { Side } * Menubar { File, Edit, View } * */ if( menubar ) output_gnome_uiinfo_struct( menubar, file ); } void output_gnome_uiinfo_empty( g2cWidget *widget, FILE *file ) { fprintf( file, "static GnomeUIInfo %s_menu_uiinfo[] = \n" "{ \n" "\tGNOMEUIINFO_END \n" "};\n", widget->name ); } void output_gnome_uiinfo_struct( g2cWidget *widget, FILE *file ) { GList *children = NULL; GList *subchildren = NULL; GList *submenu = NULL; GList *signals = NULL; GList *accels = NULL; g2cSignal *signal = NULL; g2cAccel *accel = NULL; g2cWidget *child = NULL; g2cWidget *subchild = NULL; gchar *stock_item = NULL; gchar *stock_icon = NULL; gchar *icon = NULL; gchar *label = NULL; gchar *tooltip = NULL; gchar *pixmap_type = NULL; gchar *pixmap = NULL; gchar *uiinfo_type = NULL; gboolean has_radioitems = FALSE; gboolean is_radioitem = FALSE; g_assert( NULL != widget ); /* We are being passed something of type GtkMenu, not GtkMenuItem! * As such, we need to first determine if there are any submenus * of this menu, and if so, call this function on that menu recursively. * * Then we print out the actual struct for this menu's GtkMenuItems. */ /* The children will all be GtkMenuItems */ children = g_list_first( widget->children ); /* We process items bottom up, so start with the children */ while( NULL != children ) { child = (g2cWidget*) children->data; submenu = g_list_first( child->children ); if( NULL != submenu ) { output_gnome_uiinfo_struct( submenu->data, file ); } else if( strcmp( widget->klass_name, "GtkMenuBar" ) == 0 ) { /* Handle the case of an empty top-level menu (no menu items) */ output_gnome_uiinfo_empty( child, file ); } children = g_list_next( children ); } /* Output the actual struct. * * 1. Ouput the struct header. * 2. For each child of this widget, create a line in the struct. * If this menu item has a stock item, use it. Otherwise, * use the more elaborate struct format. */ /* No radio items is the default */ is_radioitem = FALSE; if( gtk_type_is_a( widget->klass, GTK_TYPE_MENU_SHELL ) ) { fprintf( file, "static GnomeUIInfo %s_uiinfo[] =\n" "{\n", widget->name ); /* For each of the children, add the appropriate GNOMEUI_INFO call */ children = g_list_first( widget->children ); while( NULL != children ) { child = (g2cWidget*) children->data; /* Determine if there is a pixmap associated with this item, and if so, * is it a stock pixmap or a pixmap in a file */ stock_item = g2c_widget_get_property( child, "stock_item" ); stock_icon = g2c_widget_get_property( child, "stock_icon" ); icon = g2c_widget_get_property( child, "icon" ); label = g2c_widget_get_property( child, "label" ); if( NULL != label ) label = g_strdup_printf( "N_(\"%s\")", label ); else label = g_strdup( "NULL" ); tooltip = g2c_widget_get_property( child, "tooltip" ); if( NULL != tooltip ) tooltip = g_strdup_printf( "N_(\"%s\")", tooltip ); else tooltip = g_strdup( "NULL" ); signals = g_list_first( child->signals ); if( NULL != signals ) signal = signals->data; accels = g_list_first( child->accelerators ); if( NULL != accels ) accel = accels->data; if( NULL != stock_item ) { /* Each call is a little different, so we'll handle * this with an if-else statement */ if( strcmp( stock_item, "GNOMEUIINFO_MENU_CLEAR_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_CLOSE_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_COPY_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_CUT_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_END_GAME_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_EXIT_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_FIND_AGAIN_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_FIND_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_HINT_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_NEW_GAME_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_NEW_WINDOW_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_OPEN_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_PASTE_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_PAUSE_GAME_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_PREFERENCES_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_PRINT_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_PRINT_SETUP_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_PROPERTIES_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_REDO_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_REDO_MOVE_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_REPLACE_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_RESTART_GAME_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_REVERT_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_SAVE_AS_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_SAVE_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_SCORES_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_SELECT_ALL_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_UNDO_ITEM" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_UNDO_MOVE_ITEM" ) == 0 ) { fprintf( file, "\t%s (%s, NULL)", stock_item, signal->handler ); } else if( strcmp( stock_item, "GNOMEUIINFO_MENU_EDIT_TREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_FILES_TREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_FILE_TREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_GAME_TREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_HELP_TREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_NEW_SUBTREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_SETTINGS_TREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_VIEW_TREE" ) == 0 || strcmp( stock_item, "GNOMEUIINFO_MENU_WINDOWS_TREE" ) == 0 ) { submenu = g_list_first( child->children ); if( submenu ) { subchild = (g2cWidget*) g_list_first( submenu )->data; fprintf( file, "\t%s (%s_uiinfo)", stock_item, subchild->name ); } else fprintf( file, "\t%s (%s_menu_uiinfo)", stock_item, child->name ); } else if( strcmp( stock_item, "GNOMEUIINFO_MENU_ABOUT_ITEM" ) == 0 ) { if( CURRENT_PROJECT->gnome_help_support ) { fprintf( file, "\tGNOMEUIINFO_HELP (\"%s\"),\n", CURRENT_PROJECT->program_name ); } fprintf( file, "\t%s (%s, NULL)", stock_item, signal->handler ); } else if( strcmp( stock_item, "GNOMEUIINFO_MENU_NEW_ITEM" ) == 0 ) { fprintf( file, "\t%s (%s, %s, %s, NULL)", stock_item, label, tooltip, ( NULL != signal ) ? signal->handler : "NULL" ); } else { /* No such stock item */ fprintf( file, "\t*** Unknown Stock Item" ); } } /* End stock_item */ /* This is not a stock item. Is it a radio, check, or regular item? */ else if( gtk_type_is_a( child->klass, GTK_TYPE_RADIO_MENU_ITEM ) ) { /* This is a radio item */ is_radioitem = TRUE; fprintf( file, "\tGNOMEUIINFO_ITEM (%s, %s,\n" "\t %s, NULL)", label, tooltip, ( NULL != signal ) ? signal->handler : "NULL" ); } else if( gtk_type_is_a( child->klass, GTK_TYPE_CHECK_MENU_ITEM ) ) { /* This is a toggle item */ fprintf( file, "\tGNOMEUIINFO_TOGGLEITEM (%s, %s,\n" "\t %s, NULL)", label, tooltip, ( NULL != signal ) ? signal->handler : "NULL" ); } else if( strcmp( label, "NULL" ) != 0 ) { subchildren = NULL; subchild = NULL; /* What type of item is this? */ if( NULL != child->children ) { /* Search for GtkRadioMenuItems */ /* Get GtkMenu child */ subchildren = g_list_first( child->children ); subchild = (g2cWidget*) subchildren->data; /* Get GtkMenuItem child */ subchildren = g_list_first( subchild->children ); subchild = (g2cWidget*) subchildren->data; /* Is this a container item for radioitems? */ if( gtk_type_is_a( subchild->klass, GTK_TYPE_RADIO_MENU_ITEM ) ) has_radioitems = TRUE; else has_radioitems = FALSE; } else uiinfo_type = g_strdup( "GNOME_APP_UI_ITEM" ); if( NULL != stock_icon ) { pixmap_type = g_strdup( "GNOME_APP_PIXMAP_STOCK" ); pixmap = g_strdup( stock_icon ); } else if( NULL != icon ) { pixmap_type = g_strdup( "GNOME_APP_PIXMAP_FILENAME" ); pixmap = g_strdup_printf( "\"%s/%s\"", CURRENT_PROJECT->pixmaps_directory, icon ); } else { pixmap_type = g_strdup( "GNOME_APP_PIXMAP_NONE" ); pixmap = g_strdup( "NULL" ); } if( has_radioitems ) { fprintf( file, "\t{\n" "\t\tGNOME_APP_UI_SUBTREE, %s,\n" "\t\t%s,\n" "\t\t(gpointer) %s_menu_radio_items_uiinfo, NULL, NULL,\n" "\t\t%s, %s,\n" "\t\t%s, (GdkModifierType) %s, NULL\n" "\t}", label, tooltip, child->name, pixmap_type, pixmap, ( NULL != accel ) ? accel->key : "0", ( NULL != accel ) ? accel->modifiers : "0" ); } else if( NULL == uiinfo_type ) { fprintf( file, "\t{\n" "\t\tGNOME_APP_UI_SUBTREE, %s,\n" "\t\t%s,\n" "\t\t(gpointer) %s_menu_uiinfo, NULL, NULL,\n" "\t\t%s, %s,\n" "\t\t%s, (GdkModifierType) %s, NULL\n" "\t}", label, tooltip, child->name, pixmap_type, pixmap, ( NULL != accel ) ? accel->key : "0", ( NULL != accel ) ? accel->modifiers : "0" ); } else { fprintf( file, "\t{\n" "\t\t%s, %s,\n" "\t\t%s,\n" "\t\t(gpointer) %s, NULL, NULL,\n" "\t\t%s, %s,\n" "\t\t%s, (GdkModifierType) %s, NULL\n" "\t}", uiinfo_type, label, tooltip, ( NULL != signal ) ? signal->handler : "NULL", pixmap_type, pixmap, ( NULL != accel ) ? accel->key : "0", ( NULL != accel ) ? accel->modifiers : "0" ); } } else { fprintf( file, "\tGNOMEUIINFO_SEPARATOR" ); } fprintf( file, ",\n" ); if( NULL != pixmap_type ) g_free( pixmap_type ); if( NULL != pixmap ) g_free( pixmap ); if( NULL != label ) g_free( label ); if( NULL != tooltip ) g_free( tooltip ); if( NULL != uiinfo_type ) g_free( uiinfo_type ); pixmap_type = NULL; pixmap = NULL; stock_icon = NULL; stock_item = NULL; icon = NULL; label = NULL; tooltip = NULL; signal = NULL; signals = NULL; accel = NULL; accels = NULL; uiinfo_type = NULL; children = g_list_next( children ); } fprintf( file, "\tGNOMEUIINFO_END" "\n};\n\n" ); /* If this was a group of radio items, we need a special struct to * hold them. */ if( is_radioitem ) { fprintf( file, "static GnomeUIInfo %s_radio_items_uiinfo[] =\n" "{\n" "\tGNOMEUIINFO_RADIOLIST (%s_uiinfo),\n" "\tGNOMEUIINFO_END\n" "};\n\n", child->parent->name, child->parent->name ); } } } static void handle_file_compare( gchar *temp_file_name, gchar *file_name ) { /* Run ctags on the file in question, then take each line * in the returned tags file and put it the function * list of the parser */ FILE *file = NULL; gchar *cmd = NULL; gchar *cmd_res = g_malloc0( 1024 ); /* Create the command */ cmd = g_strdup_printf( "diff --ignore-all-space --ignore-blank-lines --brief %s %s", temp_file_name, file_name ); file = popen( cmd, "r" ); g_free( cmd ); cmd = NULL; /* If there was any resulting text, then the files were different */ fgets( cmd_res, 1024, file ); cmd_res = g_strchomp( cmd_res ); if( strlen( cmd_res ) > 0 ) { /* Copy the temp file to the old file */ g_print( "Writing %s\n", file_name ); cmd = g_strdup_printf( "mv -f %s %s", temp_file_name, file_name ); system( cmd ); } pclose( file ); if( NULL != cmd ) g_free( cmd ); if( NULL != cmd_res ) g_free( cmd_res ); } static void create_if_not_exist( gchar *filename ) { struct stat s_stat; /* Does the directory exist? */ if( -1 == stat( filename, &s_stat ) ) { if( ENOENT == errno ) { /* Directory does not exist. Try to create it. */ creat( filename, 0664 ); } else { g_error( "Could not create or acces file: %s\n", filename ); } } } void output_main_file ( g2cDoc *doc ) { return; }