#ifdef HAVE_CONFIG_H # include #endif #include #include #include /* columns */ enum { POSITION_COLUMN = 0, OFFSET_COLUMN, END_COLUMN, VALUE_COLUMN, PARENT_COLUMN, NUM_COLUMNS }; gint lastSelected = -1; /* Result structure */ typedef struct _ResultItem ResultItem; struct _ResultItem { gint position; gint parent; gint offset; gint end; gint sample_offset; gint sample_end; gchar * value; ResultItem *children; }; GtkWidget * regexpEntry; GtkWidget * dataEntry; GtkWidget * resultEntry; GtkWidget * optMultiline; GtkWidget * optCaseless; GtkWidget * optDotAll; GtkWidget * regexpEscaped; GtkWidget * escapeLevel; GtkWidget * resultTree; GtkWidget * aboutDialog = NULL; ResultItem * lastResult = NULL; void clear_model ( GtkWidget * tree ); void update_model ( ResultItem * result, GtkWidget * tree ); void apply_tag ( gint start_pos, gint end_pos, const gchar * tag ); void remove_tag ( gint start_pos, gint end_pos, const gchar * tag ); void select_match ( gint match ); void set_escaped ( gchar * expression, unsigned int levels ); gboolean opt_multiline () { return gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( optMultiline ) ); } gboolean opt_caseless () { return gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( optCaseless ) ); } gboolean opt_dotall () { return gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( optDotAll ) ); } unsigned int escape_level () { return gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(escapeLevel) ); } gchar * get_regexp () { return gtk_editable_get_chars ( GTK_EDITABLE(regexpEntry), 0, -1 ); } gchar * get_sampledata () { GtkTextIter start_iter, end_iter; GtkTextBuffer * buffer; buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW(dataEntry) ); gtk_text_buffer_get_start_iter ( buffer, &start_iter ); gtk_text_buffer_get_end_iter ( buffer, &end_iter ); return gtk_text_buffer_get_text ( buffer, &start_iter, &end_iter, FALSE ); } gchar * from_locale ( const char * str ) { gsize read, written; return g_locale_to_utf8 ( str, -1, &read, &written, NULL ); } void set_escaped ( gchar * expression, unsigned int levels ) { unsigned int num; gchar * escaped; unsigned int x; // temp var unsigned int i, j; if ( !expression ) return; num = (1<position >= 0 ) { if ( result->value ) g_free ( result->value ); result++; } lastResult = NULL; } void about_dialog ( GtkWidget *widget, gpointer user_data ) { const gchar * authors [] = { "Jens Reimann ", NULL }; const gchar * documenters [] = { NULL }; if ( !aboutDialog ) { aboutDialog = (GtkWidget*)gnome_about_new ( "GRegExp Explorer", VERSION, "(c) by Jens Reimann 2004", "", authors, documenters, NULL, NULL ); g_object_add_weak_pointer ( G_OBJECT(aboutDialog), (void**)&aboutDialog ); } gtk_widget_show ( aboutDialog ); gtk_window_present ( GTK_WINDOW(aboutDialog ) ); } char * to_locale ( const gchar * str ) { gsize read, written; return g_locale_from_utf8 ( str, -1, &read, &written, NULL ); } static ResultItem r_test [] = { { 0, -1, 0, 10, 0, 10, "X0" }, { 1, 0, 0, 10, 0, 10, "X0" }, { 2, 1, 0, 10, 0, 10, "X0" }, { 3, 1, 0, 10, 0, 10, "X0" }, { -1 } }; ResultItem * transform ( int * ovector, unsigned int matches, const gchar * data ) { ResultItem * resultItems; int parent; GTrashStack * stack; unsigned int o; resultItems = g_malloc ( sizeof(ResultItem)*(matches+1) ); parent = 0; stack = NULL; for ( o = 0; o0 ) { buffer = g_malloc ( end-offset + 1 ); g_strlcpy ( buffer, data+offset, end-offset+1 ); } else { buffer = g_strdup ( "" ); } resultItems[o].position = o; resultItems[o].offset = offset; resultItems[o].end = end; resultItems[o].value = buffer; if ( (resultItems[o].offset >= resultItems[parent].offset) && (resultItems[o].end <= resultItems[parent].end) ) { resultItems[o].parent = (o?parent:-1); parent = o; } else { while ( !( (resultItems[o].offset >= resultItems[parent].offset) && (resultItems[o].end <= resultItems[parent].end) ) && !(parent<0) ) { parent = resultItems[parent].parent; } resultItems[o].parent = (o?parent:-1); parent = o; } } // Mark end resultItems[o].position = -1; return resultItems; } void set_result_error ( gchar * text ) { gtk_text_buffer_set_text ( gtk_text_view_get_buffer(GTK_TEXT_VIEW(resultEntry) ), text, -1 ); g_free ( text ); } void parse_result ( gchar * data, ResultItem * resultItems, unsigned int matches ) { GtkTextIter iter; GtkTextBuffer * buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(resultEntry) ); gchar * result; int o, j, i, x; gtk_text_buffer_set_text ( buffer, "", -1 ); gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0); result = g_malloc ( (strlen ( data ) + 128 ) * 2 ); j = 0; i = 0; x = 0; while ( data[i] ) { for ( o = 0; o" ); return; } } // Fill result tree resultItems = transform ( ovector, rc, data ); update_model ( resultItems, resultTree ); parse_result ( data, resultItems, rc ); // Reset last selected lastSelected = -1; clear_result (); // Set new lastResult = resultItems; return; } void data_changed ( GtkWidget *widget, gpointer user_data ) { gchar * regexpStr; gchar * dataStr; dataStr = get_sampledata (); regexpStr = get_regexp (); process ( regexpStr, dataStr ); set_escaped ( regexpStr, escape_level() ); g_free ( dataStr ); g_free ( regexpStr ); } void selected ( GtkWidget *widget, gpointer ptr ) { GtkTreeSelection * sel; GtkTreeModel * model; GtkTreeIter iter; gint position; sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW(resultTree) ); if ( !gtk_tree_selection_get_selected ( sel, &model, &iter ) ) { return; } gtk_tree_model_get ( model, &iter, POSITION_COLUMN, &position, -1 ); select_match ( position ); } void select_match ( gint match ) { if ( lastSelected >= 0 ) { remove_tag ( lastResult[lastSelected].sample_offset, lastResult[lastSelected].sample_end, "match" ); } lastSelected = match; apply_tag ( lastResult[lastSelected].sample_offset, lastResult[lastSelected].sample_end, "match" ); } void remove_tag ( gint start_pos, gint end_pos, const gchar * tag ) { GtkTextIter start_iter, end_iter; GtkTextBuffer * buffer; buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW(resultEntry) ); gtk_text_buffer_get_iter_at_offset ( buffer, &start_iter, start_pos ); gtk_text_buffer_get_iter_at_offset ( buffer, &end_iter, end_pos ); gtk_text_buffer_remove_tag_by_name ( buffer, tag, &start_iter, &end_iter ); } void apply_tag ( gint start_pos, gint end_pos, const gchar * tag ) { GtkTextIter start_iter, end_iter; GtkTextBuffer * buffer; buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW(resultEntry) ); gtk_text_buffer_get_iter_at_offset ( buffer, &start_iter, start_pos ); gtk_text_buffer_get_iter_at_offset ( buffer, &end_iter, end_pos ); gtk_text_buffer_apply_tag_by_name ( buffer, tag, &start_iter, &end_iter ); } void append_result ( GtkTreeStore * model, ResultItem * head, gint parent, GtkTreeIter * rootIter ) { GtkTreeIter iter; ResultItem * result = head; while ( result->position >= 0 ) { if ( result->parent == parent ) { gtk_tree_store_append ( model, &iter, rootIter ); gtk_tree_store_set ( model, &iter, POSITION_COLUMN, result->position, OFFSET_COLUMN, result->offset, END_COLUMN, result->end, VALUE_COLUMN, result->value, PARENT_COLUMN, result->parent, -1 ); append_result ( model, result, result->position, &iter ); } result++; } /* while ( result->position >= 0 ) { if ( result->children ) { append_result ( model, result->children, &iter ); } result++; } */ } void clear_model ( GtkWidget * tree ) { GtkTreeStore * model; /* create tree store */ model = gtk_tree_store_new ( NUM_COLUMNS, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT ); gtk_tree_view_set_model ( GTK_TREE_VIEW(tree), GTK_TREE_MODEL(model) ); g_object_unref ( model ); } void update_model ( ResultItem * result, GtkWidget * tree ) { GtkTreeStore * model; /* create tree store */ model = gtk_tree_store_new ( NUM_COLUMNS, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INT ); append_result ( model, result, -1, NULL ); gtk_tree_view_set_model ( GTK_TREE_VIEW(tree), GTK_TREE_MODEL(model) ); g_object_unref ( model ); gtk_tree_view_expand_all ( GTK_TREE_VIEW(tree) ); } void init_result_entry ( GtkTextView * text ) { GtkTextBuffer * buffer; buffer = gtk_text_view_get_buffer ( GTK_TEXT_VIEW(resultEntry) ); gtk_text_buffer_create_tag (buffer, "match", "foreground", "red", "weight", PANGO_WEIGHT_BOLD, NULL); } void init_tree ( GtkTreeView * tree ) { gint col_offset; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeModel *model = gtk_tree_view_get_model (tree); /* column for position */ renderer = gtk_cell_renderer_text_new (); col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, "Position", renderer, "text", POSITION_COLUMN, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), col_offset - 1); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE); /* column for offset */ renderer = gtk_cell_renderer_text_new (); col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, "Offset", renderer, "text", OFFSET_COLUMN, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), col_offset - 1); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE); /* column for length */ renderer = gtk_cell_renderer_text_new (); col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, "End", renderer, "text", END_COLUMN, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), col_offset - 1); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE); /* column for value */ renderer = gtk_cell_renderer_text_new (); col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, "Value", renderer, "text", VALUE_COLUMN, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), col_offset - 1); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE); /* column for parent */ renderer = gtk_cell_renderer_text_new (); col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, "Parent", renderer, "text", PARENT_COLUMN, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree), col_offset - 1); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE); // Set some tree options gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree), TRUE); gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree)), GTK_SELECTION_SINGLE); } int main (int argc, char *argv[]) { GtkWidget *app1; GladeXML *xml; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #endif gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR, NULL); /* * The following code was added by Glade to create one of each component * (except popup menus), just so that you see something after building * the project. Delete any components that you don't want shown initially. */ /* load the interface */ xml = glade_xml_new(DATADIR"gregexp/glade/gregexp.glade", NULL, NULL); /* connect the signals in the interface */ glade_xml_signal_autoconnect(xml); regexpEntry = glade_xml_get_widget ( xml, "regexp_entry" ); regexpEscaped = glade_xml_get_widget ( xml, "regexp_escaped" ); dataEntry = glade_xml_get_widget ( xml, "data_entry" ); resultEntry = glade_xml_get_widget ( xml, "result_entry" ); optMultiline = glade_xml_get_widget ( xml, "opt_multiline" ); optCaseless = glade_xml_get_widget ( xml, "opt_caseless" ); optDotAll = glade_xml_get_widget ( xml, "opt_dotall" ); escapeLevel = glade_xml_get_widget ( xml, "escape_level" ); resultTree = glade_xml_get_widget ( xml, "result_tree" ); init_result_entry ( GTK_TEXT_VIEW(resultEntry ) ); init_tree ( GTK_TREE_VIEW(resultTree) ); g_signal_connect_after ( G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(dataEntry))), "changed", GTK_SIGNAL_FUNC(data_changed), NULL ); // g_signal_connect_after ( G_OBJECT(resultTree), "cursor-changed", GTK_SIGNAL_FUNC(selected), NULL ); data_changed ( NULL, NULL ); /* start the event loop */ gtk_main(); return 0; }