/* This is -*- C -*- */ /* $Id: guppi-stream-preview.c,v 1.13 2001/10/10 06:48:10 trow Exp $ */ /* * guppi-stream-preview.c * * Copyright (C) 1999, 2000 EMC Capital Management, Inc. * * Developed by Jon Trowbridge and * Havoc Pennington . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * 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 "guppi-stream-preview.h" /* #include */ #include #include #include #include #include #include #include #include #include #include "guppi-convenient.h" /* First, some style info */ GdkColor * style_active_line_color (void) { static GdkColor *c = NULL; if (c == NULL) { c = guppi_new (GdkColor, 1); guppi_permanent_alloc (c); c->red = 0; c->green = 0; c->blue = 0; gdk_color_alloc (gdk_colormap_get_system (), c); } return c; } GdkColor * style_inactive_line_color (void) { static GdkColor *c = NULL; if (c == NULL) { c = guppi_new (GdkColor, 1); guppi_permanent_alloc (c); c->red = 0x8000; c->green = 0x8000; c->blue = 0x8000; gdk_color_alloc (gdk_colormap_get_system (), c); } return c; } GdkColor * style_active_line_number_color (void) { static GdkColor *c = NULL; if (c == NULL) { c = guppi_new (GdkColor, 1); guppi_permanent_alloc (c); c->red = 0; c->green = 0; c->blue = 0xffff; gdk_color_alloc (gdk_colormap_get_system (), c); } return c; } GdkColor * style_inactive_line_number_color (void) { static GdkColor *c = NULL; if (c == NULL) { c = guppi_new (GdkColor, 1); guppi_permanent_alloc (c); c->red = 0x8000; c->green = 0x8000; c->blue = 0x6fff; gdk_color_alloc (gdk_colormap_get_system (), c); } return c; } GdkColor * style_title_line_color (void) { static GdkColor *c = NULL; if (c == NULL) { c = guppi_new (GdkColor, 1); guppi_permanent_alloc (c); c->red = 0xc000; c->green = 0; c->blue = 0; gdk_color_alloc (gdk_colormap_get_system (), c); } return c; } GdkColor * style_invalid_line_color (void) { static GdkColor *c = NULL; if (c == NULL) { c = guppi_new (GdkColor, 1); guppi_permanent_alloc (c); c->red = 0xffff; c->green = 0; c->blue = 0; gdk_color_alloc (gdk_colormap_get_system (), c); } return c; } GdkFont * style_line_font (void) { static GdkFont *f = NULL; if (f == NULL) { const gchar *s = "-misc-fixed-medium-r-*-*-*-120-*-*-*-*-iso8859-1"; f = gdk_font_load (s); if (!f) { g_warning ("Can't find font %s", s); f = gdk_font_load ("fixed"); g_assert (f); } } return f; } GdkFont * style_line_number_font (void) { static GdkFont *f = NULL; if (f == NULL) { const gchar *s = "-misc-fixed-medium-r-*-*-*-50-*-*-*-*-iso8859-1"; f = gdk_font_load (s); if (!f) { g_warning ("Can't find font %s", s); f = gdk_font_load ("fixed"); g_assert (f); } } return f; } /********************************************************************/ static GtkObjectClass *parent_class = NULL; static void guppi_stream_preview_destroy (GtkObject * obj) { GuppiStreamPreview *gsp = GUPPI_STREAM_PREVIEW (obj); gtk_signal_disconnect_by_data (GTK_OBJECT (gsp->stream), gsp); guppi_unref0 (gsp->stream); if (parent_class->destroy) parent_class->destroy (obj); } static void guppi_stream_preview_finalize (GtkObject * obj) { guppi_finalized (obj); if (parent_class->finalize) parent_class->finalize (obj); } static void guppi_stream_preview_class_init (GuppiStreamPreviewClass * klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; parent_class = gtk_type_class (GTK_TYPE_FRAME); object_class->destroy = guppi_stream_preview_destroy; object_class->finalize = guppi_stream_preview_finalize; } static void guppi_stream_preview_init (GuppiStreamPreview * obj) { obj->line_skip = NULL; obj->line_skip_user_data = NULL; obj->extra_info = NULL; obj->extra_info_user_data = NULL; obj->line_color = NULL; obj->line_color_user_data = NULL; } GtkType guppi_stream_preview_get_type (void) { static GtkType guppi_stream_preview_type = 0; if (!guppi_stream_preview_type) { static const GtkTypeInfo guppi_stream_preview_info = { "GuppiStreamPreview", sizeof (GuppiStreamPreview), sizeof (GuppiStreamPreviewClass), (GtkClassInitFunc) guppi_stream_preview_class_init, (GtkObjectInitFunc) guppi_stream_preview_init, NULL, NULL, (GtkClassInitFunc) NULL }; guppi_stream_preview_type = gtk_type_unique (GTK_TYPE_FRAME, &guppi_stream_preview_info); } return guppi_stream_preview_type; } static void guppi_stream_preview_set_info (GuppiStreamPreview * gsp) { GuppiStream *gs; gchar total_bytes[128]; gchar total_lines[128]; gint lines, lines_est; gchar all[256]; g_return_if_fail (gsp != NULL); gs = gsp->stream; if (gs->total_size >= 0) g_snprintf (total_bytes, 128, "%d", gs->total_size); else g_snprintf (total_bytes, 128, _("?")); lines = guppi_stream_number_of_lines (gs); lines_est = guppi_stream_estimated_number_of_lines (gs); if (lines >= 0) g_snprintf (total_lines, 128, "%d", lines); else if (lines_est >= 0) g_snprintf (total_lines, 128, _("approx %d"), lines_est); else g_snprintf (total_lines, 128, _("?")); g_snprintf (all, 256, _("Size: %s bytes / Length: %s lines"), total_bytes, total_lines); gtk_label_set (gsp->info_label, all); } static void render_marked_line (GtkText * text, const gchar * line, gchar escape, gboolean skip, GdkFont * font, GdkColor * active_color, GdkColor * inactive_color) { const gchar *prev; const gchar *p; gboolean pending, in_comment; g_return_if_fail (text != NULL); g_return_if_fail (line != NULL); p = line; prev = p; pending = FALSE; in_comment = FALSE; while (p && *p) { if (pending) { if (*p == 'L') { gtk_text_insert (text, font, inactive_color, NULL, p + 1, -1); p = NULL; } else if (*p == 'C') { in_comment = TRUE; prev = p + 1; } else if (*p == 'c') { in_comment = FALSE; prev = p + 1; } else if (*p != escape) { g_message ("Unknown line marking: -%c", *p); } pending = FALSE; } else { if (*p == escape) { pending = TRUE; if (p > prev) gtk_text_insert (text, font, in_comment || skip ? inactive_color : active_color, NULL, prev, p - prev); prev = p; } } if (p) ++p; } if (p > prev) gtk_text_insert (text, font, in_comment || skip ? inactive_color : active_color, NULL, prev, p - prev); } static void guppi_stream_preview_render_into_text (GuppiStreamPreview * gsp) { gint i; const gchar *line; const gchar *sani; const gint buffer_len = 32; gchar buffer[32]; gboolean skip_line; GdkFont *l_f; GdkFont *ln_f; GdkColor *ln_c; GdkColor *info_c; GdkColor *this_c; gchar escape; g_return_if_fail (gsp != NULL); l_f = style_line_font (); ln_f = style_line_number_font (); escape = guppi_stream_escape (gsp->stream); gtk_text_freeze (gsp->text); gtk_text_set_point (gsp->text, 0); gtk_text_forward_delete (gsp->text, gtk_text_get_length (gsp->text)); gtk_text_thaw (gsp->text); /* If I don't thaw and re-freeze here (i.e. if I try to make all of my changes between one freeze/thaw pair) I get a segfault if the scrolling window my GtkText is sitting inside of isn't up at the very top. I don't know if this is a gtk bug or if I'm doing something wrong somewhere. This workaround makes things flicker a bit more, but otherwise seems pretty painless. */ gtk_text_freeze (gsp->text); for (i = 0; i <= gsp->stream->current_line_no; ++i) { if (i != 0) gtk_text_insert (gsp->text, NULL, NULL, NULL, "\n", 1); line = guppi_stream_get_marked_line (gsp->stream, i); sani = guppi_stream_get_sanitized_line (gsp->stream, i); skip_line = FALSE; if (gsp->line_skip) skip_line = (gsp->line_skip) (gsp, sani, i + 1, gsp->line_skip_user_data); if (skip_line) { ln_c = style_inactive_line_number_color (); } else { ln_c = style_active_line_number_color (); } g_snprintf (buffer, buffer_len, "%4d", i + 1); gtk_text_insert (gsp->text, ln_f, ln_c, NULL, buffer, -1); gtk_text_insert (gsp->text, l_f, NULL, NULL, " ", 1); if (gsp->extra_info) { info_c = (gsp->extra_info) (gsp, sani, i + 1, buffer, buffer_len, gsp->extra_info_user_data); if (info_c == NULL) info_c = ln_c; gtk_text_insert (gsp->text, ln_f, info_c, NULL, buffer, -1); gtk_text_insert (gsp->text, l_f, NULL, NULL, " ", 1); } this_c = style_active_line_color (); if (gsp->line_color) { GdkColor *alt_c = (gsp->line_color) (gsp, sani, i + 1, gsp->line_color_user_data); if (alt_c != NULL) this_c = alt_c; } render_marked_line (gsp->text, line, escape, skip_line, l_f, this_c, style_inactive_line_color ()); } gtk_text_thaw (gsp->text); } #ifdef EXTRA_CONTROLS static void guppi_stream_preview_reset_codes (GuppiStreamPreview * gsp) { gchar *p; g_return_if_fail (gsp != NULL); p = gtk_entry_get_text (gsp->eol_combo_entry); guppi_stream_set_eol_comment (gsp->stream, strcmp (p, _("")) == 0 ? NULL : p); p = gtk_entry_get_text (gsp->begin_ml_combo_entry); guppi_stream_set_ml_comment_start (gsp->stream, strcmp (p, _("")) == 0 ? NULL : p); p = gtk_entry_get_text (gsp->end_ml_combo_entry); guppi_stream_set_ml_comment_end (gsp->stream, strcmp (p, _("")) == 0 ? NULL : p); } #endif #ifdef EXTRA_CONTROLS static void guppi_stream_preview_sync_codes (GuppiStreamPreview * gsp) { const gchar *p; g_return_if_fail (gsp != NULL); g_return_if_fail (gsp->stream != NULL); p = guppi_stream_eol_comment (gsp->stream); gtk_entry_set_text (gsp->eol_combo_entry, p ? p : ""); p = guppi_stream_ml_comment_start (gsp->stream); gtk_entry_set_text (gsp->begin_ml_combo_entry, p ? p : ""); p = guppi_stream_ml_comment_end (gsp->stream); gtk_entry_set_text (gsp->end_ml_combo_entry, p ? p : ""); } #endif /**********************************************************************/ static void on_stream_preload (GuppiStream * gs, gpointer user_data) { GuppiStreamPreview *gsp = GUPPI_STREAM_PREVIEW (user_data); g_return_if_fail (gsp != NULL); g_message ("preloading"); guppi_stream_preview_render_into_text (gsp); guppi_stream_preview_set_info (gsp); } #ifdef EXTRA_CONTROLS static void on_stream_fully_preloaded (GuppiStream * gs, gpointer user_data) { GuppiStreamPreview *gsp = GUPPI_STREAM_PREVIEW (user_data); g_return_if_fail (gsp != NULL); gtk_widget_set_sensitive (GTK_WIDGET (gsp->preload_button), FALSE); } #endif static void on_stream_changed_codes (GuppiStream * gs, gpointer user_data) { GuppiStreamPreview *gsp = GUPPI_STREAM_PREVIEW (user_data); g_return_if_fail (gsp != NULL); // guppi_stream_preview_render_into_text(gsp); guppi_stream_preview_refresh (gsp); #ifdef EXTRA_CONTROLS guppi_stream_preview_sync_codes (gsp); #endif } #ifdef EXTRA_CONTROLS static void on_preload_button_clicked (GtkButton * button, gpointer user_data) { GuppiStreamPreview *gsp = GUPPI_STREAM_PREVIEW (user_data); g_return_if_fail (gsp != NULL); guppi_stream_load_more_lines (gsp->stream); } static void on_combo_entry_focus_out (GtkWidget * w, GdkEventFocus * foo, gpointer user_data) { GuppiStreamPreview *gsp = GUPPI_STREAM_PREVIEW (user_data); g_return_if_fail (gsp != NULL); guppi_stream_preview_reset_codes (gsp); } #endif void guppi_stream_preview_construct (GuppiStreamPreview * gsp) { GtkWidget *preview_frame; GtkWidget *vbox1; GtkWidget *scrolledwindow1; GtkWidget *text; GtkWidget *info_label; #ifdef EXTRA_CONTROLS GtkWidget *hseparator1; GtkWidget *table1; GtkWidget *label4; GtkWidget *label5; GtkWidget *label6; GtkWidget *eol_combo; GList *eol_combo_items = NULL; GtkWidget *combo_entry6; GtkWidget *begin_ml_combo; GList *begin_ml_combo_items = NULL; GtkWidget *combo_entry7; GtkWidget *end_ml_combo; GList *end_ml_combo_items = NULL; GtkWidget *combo_entry8; GtkWidget *preload_button; #endif g_return_if_fail (gsp != NULL); preview_frame = GTK_WIDGET (gsp); gsp->preview_frame = GTK_FRAME (preview_frame); gtk_frame_set_label (gsp->preview_frame, _("No stream selected.")); gtk_container_set_border_width (GTK_CONTAINER (preview_frame), 3); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); gtk_container_add (GTK_CONTAINER (preview_frame), vbox1); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2); scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow1); gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gsp->vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolledwindow1)); text = gtk_text_new (NULL, gsp->vadj); gtk_text_set_line_wrap (GTK_TEXT (text), FALSE); gtk_widget_show (text); gtk_container_add (GTK_CONTAINER (scrolledwindow1), text); gsp->text = GTK_TEXT (text); info_label = gtk_label_new (_("No stream selected.")); gtk_widget_show (info_label); gtk_box_pack_start (GTK_BOX (vbox1), info_label, FALSE, FALSE, 1); gsp->info_label = GTK_LABEL (info_label); #ifdef EXTRA_CONTROLS hseparator1 = gtk_hseparator_new (); gtk_widget_show (hseparator1); gtk_box_pack_start (GTK_BOX (vbox1), hseparator1, FALSE, TRUE, 2); table1 = gtk_table_new (2, 4, FALSE); gtk_widget_show (table1); gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 2); label4 = gtk_label_new (_("Ignore To\nEnd of Line")); gtk_widget_show (label4); gtk_table_attach (GTK_TABLE (table1), label4, 1, 2, 0, 1, (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0); label5 = gtk_label_new (_("Begin Multiline\nComment")); gtk_widget_show (label5); gtk_table_attach (GTK_TABLE (table1), label5, 2, 3, 0, 1, (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0); label6 = gtk_label_new (_("End Multiline\nComment")); gtk_widget_show (label6); gtk_table_attach (GTK_TABLE (table1), label6, 3, 4, 0, 1, (GtkAttachOptions) (0), (GtkAttachOptions) (0), 0, 0); eol_combo = gtk_combo_new (); gtk_widget_show (eol_combo); gtk_table_attach (GTK_TABLE (table1), eol_combo, 1, 2, 1, 2, (GtkAttachOptions) (GTK_EXPAND), (GtkAttachOptions) (0), 0, 0); gtk_widget_set_usize (eol_combo, 75, -2); eol_combo_items = g_list_append (eol_combo_items, "#"); eol_combo_items = g_list_append (eol_combo_items, "//"); eol_combo_items = g_list_append (eol_combo_items, ";"); eol_combo_items = g_list_append (eol_combo_items, _("")); gtk_combo_set_popdown_strings (GTK_COMBO (eol_combo), eol_combo_items); g_list_free (eol_combo_items); gtk_combo_disable_activate (GTK_COMBO (eol_combo)); gsp->eol_combo_entry = GTK_ENTRY (GTK_COMBO (eol_combo)->entry); combo_entry6 = GTK_COMBO (eol_combo)->entry; gtk_widget_show (combo_entry6); gtk_entry_set_text (GTK_ENTRY (combo_entry6), "#"); begin_ml_combo = gtk_combo_new (); gtk_widget_show (begin_ml_combo); gtk_table_attach (GTK_TABLE (table1), begin_ml_combo, 2, 3, 1, 2, (GtkAttachOptions) (GTK_EXPAND), (GtkAttachOptions) (0), 0, 0); gtk_widget_set_usize (begin_ml_combo, 75, -2); begin_ml_combo_items = g_list_append (begin_ml_combo_items, _("")); begin_ml_combo_items = g_list_append (begin_ml_combo_items, "/*"); begin_ml_combo_items = g_list_append (begin_ml_combo_items, "<"); begin_ml_combo_items = g_list_append (begin_ml_combo_items, "(*"); gtk_combo_set_popdown_strings (GTK_COMBO (begin_ml_combo), begin_ml_combo_items); g_list_free (begin_ml_combo_items); gtk_combo_disable_activate (GTK_COMBO (begin_ml_combo)); gsp->begin_ml_combo_entry = GTK_ENTRY (GTK_COMBO (begin_ml_combo)->entry); combo_entry7 = GTK_COMBO (begin_ml_combo)->entry; gtk_widget_show (combo_entry7); gtk_entry_set_text (GTK_ENTRY (combo_entry7), _("")); end_ml_combo = gtk_combo_new (); gtk_widget_show (end_ml_combo); gtk_table_attach (GTK_TABLE (table1), end_ml_combo, 3, 4, 1, 2, (GtkAttachOptions) (GTK_EXPAND), (GtkAttachOptions) (0), 0, 0); gtk_widget_set_usize (end_ml_combo, 75, -2); end_ml_combo_items = g_list_append (end_ml_combo_items, _("")); end_ml_combo_items = g_list_append (end_ml_combo_items, "*/"); end_ml_combo_items = g_list_append (end_ml_combo_items, ">"); end_ml_combo_items = g_list_append (end_ml_combo_items, "*)"); gtk_combo_set_popdown_strings (GTK_COMBO (end_ml_combo), end_ml_combo_items); g_list_free (end_ml_combo_items); gtk_combo_disable_activate (GTK_COMBO (end_ml_combo)); gsp->end_ml_combo_entry = GTK_ENTRY (GTK_COMBO (end_ml_combo)->entry); combo_entry8 = GTK_COMBO (end_ml_combo)->entry; gtk_widget_show (combo_entry8); gtk_entry_set_text (GTK_ENTRY (combo_entry8), _("")); preload_button = gtk_button_new_with_label (_("Preload")); gtk_widget_show (preload_button); gtk_table_attach (GTK_TABLE (table1), preload_button, 0, 1, 0, 2, (GtkAttachOptions) (GTK_EXPAND), (GtkAttachOptions) (0), 0, 0); gsp->preload_button = GTK_BUTTON (preload_button); #endif #ifdef EXTRA_CONTROLS /* This means we are fully preloaded. */ if (guppi_stream_number_of_lines (gsp->stream) >= 0) gtk_widget_set_sensitive (GTK_WIDGET (gsp->preload_button), FALSE); /* Get the comment codes in the GuppiStream to match up with the ones in our combo boxes. */ guppi_stream_preview_sync_codes (gsp); #endif #ifdef EXTRA_CONTROLS s = gtk_signal_connect (GTK_OBJECT (gsp->stream), "fully_preloaded", GTK_SIGNAL_FUNC (on_stream_fully_preloaded), gsp); gtk_signal_connect (GTK_OBJECT (gsp->preload_button), "clicked", GTK_SIGNAL_FUNC (on_preload_button_clicked), gsp); gtk_signal_connect_object (GTK_OBJECT (gsp->eol_combo_entry), "activate", GTK_SIGNAL_FUNC (guppi_stream_preview_reset_codes), GTK_OBJECT (gsp)); gtk_signal_connect_object (GTK_OBJECT (gsp->begin_ml_combo_entry), "activate", GTK_SIGNAL_FUNC (guppi_stream_preview_reset_codes), GTK_OBJECT (gsp)); gtk_signal_connect_object (GTK_OBJECT (gsp->end_ml_combo_entry), "activate", GTK_SIGNAL_FUNC (guppi_stream_preview_reset_codes), GTK_OBJECT (gsp)); gtk_signal_connect (GTK_OBJECT (gsp->eol_combo_entry), "focus_out_event", GTK_SIGNAL_FUNC (on_combo_entry_focus_out), GTK_OBJECT (gsp)); gtk_signal_connect (GTK_OBJECT (gsp->begin_ml_combo_entry), "focus_out_event", GTK_SIGNAL_FUNC (on_combo_entry_focus_out), GTK_OBJECT (gsp)); gtk_signal_connect (GTK_OBJECT (gsp->end_ml_combo_entry), "focus_out_event", GTK_SIGNAL_FUNC (on_combo_entry_focus_out), GTK_OBJECT (gsp)); #endif } GtkWidget * guppi_stream_preview_new (GuppiStream * stream) { GuppiStreamPreview *gsp; g_return_val_if_fail (stream != NULL, NULL); gsp = GUPPI_STREAM_PREVIEW (guppi_type_new (guppi_stream_preview_get_type ())); guppi_stream_preview_construct (gsp); guppi_stream_preview_set_stream (gsp, stream); return GTK_WIDGET (gsp); } void guppi_stream_preview_set_stream (GuppiStreamPreview * gsp, GuppiStream * gs) { g_return_if_fail (gsp != NULL); g_return_if_fail (gs != NULL); g_return_if_fail (gsp->stream == NULL); /* can't set stream twice */ gsp->stream = gs; guppi_ref (gs); gtk_frame_set_label (gsp->preview_frame, guppi_stream_source (gsp->stream)); /* We touch the stream to force the initial preloading, if necessary. */ guppi_stream_load_some_lines (gsp->stream); guppi_stream_preview_render_into_text (gsp); guppi_stream_preview_set_info (gsp); gtk_signal_connect (GTK_OBJECT (gsp->stream), "preload", GTK_SIGNAL_FUNC (on_stream_preload), gsp); gtk_signal_connect (GTK_OBJECT (gsp->stream), "changed_codes", GTK_SIGNAL_FUNC (on_stream_changed_codes), gsp); } void guppi_stream_preview_refresh (GuppiStreamPreview * gsp) { gfloat x; x = gsp->vadj->value; guppi_stream_preview_render_into_text (gsp); gtk_adjustment_set_value (gsp->vadj, x); } void guppi_stream_preview_set_line_skip_cb (GuppiStreamPreview * gsp, gboolean (*cb) (GuppiStreamPreview *, const gchar *, gint, gpointer), gpointer user_data) { g_return_if_fail (gsp != NULL); g_return_if_fail (cb != NULL); gsp->line_skip = cb; gsp->line_skip_user_data = user_data; guppi_stream_preview_render_into_text (gsp); } void guppi_stream_preview_set_extra_info_cb (GuppiStreamPreview * gsp, GdkColor * (*cb) (GuppiStreamPreview *, const gchar *, gint, gchar *, gint, gpointer), gpointer user_data) { g_return_if_fail (gsp != NULL); g_return_if_fail (cb != NULL); gsp->extra_info = cb; gsp->extra_info_user_data = user_data; guppi_stream_preview_render_into_text (gsp); } void guppi_stream_preview_set_line_color_cb (GuppiStreamPreview * gsp, GdkColor * (*cb) (GuppiStreamPreview *, const gchar *, gint, gpointer), gpointer user_data) { g_return_if_fail (gsp != NULL); g_return_if_fail (cb != NULL); gsp->line_color = cb; gsp->line_color_user_data = user_data; guppi_stream_preview_render_into_text (gsp); } GtkWidget * guppi_stream_preview_glade_custom_func (gchar * name, gchar * dum1, gchar * dum2, gint dum3, gint dum4) { GtkWidget *w; w = GTK_WIDGET (guppi_type_new (GUPPI_TYPE_STREAM_PREVIEW)); guppi_stream_preview_construct (GUPPI_STREAM_PREVIEW (w)); return w; } /* $Id: guppi-stream-preview.c,v 1.13 2001/10/10 06:48:10 trow Exp $ */