/* Glimmer - gdsmanpage.c * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This library 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 Library General Public License for more details. * * You should have received a copy of the GNU Library 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 "gdsmanpage.h" #include "../gtkextext/gtkextext.h" /* function declarations */ static void gds_manpage_class_init (GdsManpageClass * klass); static void gds_manpage_init (GdsManpage * gds_manpage); GtkWidget *gds_manpage_new (void); static void gds_manpage_destroy (GtkObject * object); static void set_search_button_sensitive (GtkWidget * widget, GdsManpage * gmp); static void set_page_from_entry_text (GtkWidget * widget, GdsManpage * gds_manpage); void error_dialog (GtkWidget * parent, gchar * search); static gboolean check_glist_for_multiple_entries (GList * list, gchar * new_entry); static void kill_combo_history (GList * list); /* end function declarations */ static GtkWindowClass *parent_class = NULL; GtkType gds_manpage_get_type (void) { static GtkType manpage_type = 0; if (!manpage_type) { static const GtkTypeInfo manpage_info = { "GdsManpage", sizeof (GdsManpage), sizeof (GdsManpageClass), (GtkClassInitFunc) gds_manpage_class_init, (GtkObjectInitFunc) gds_manpage_init, NULL, NULL, (GtkClassInitFunc) NULL, }; manpage_type = gtk_type_unique (GTK_TYPE_WINDOW, &manpage_info); } return (manpage_type); } static void gds_manpage_class_init (GdsManpageClass * klass) { GtkObjectClass *object_class; object_class = (GtkObjectClass *) klass; parent_class = gtk_type_class (GTK_TYPE_WINDOW); object_class->destroy = gds_manpage_destroy; } static void gds_manpage_init (GdsManpage * gds_manpage) { gds_manpage->history = NULL; } GtkWidget * gds_manpage_new () { GdsManpage *gds_manpage; GtkWidget *main_box; GtkWidget *util_box; GtkWidget *label = NULL; GtkWidget *vscrollbar; GtkWidget *hsep; gds_manpage = gtk_type_new (GDS_TYPE_MANPAGE); gtk_container_set_border_width (GTK_CONTAINER (gds_manpage), 5); gtk_window_set_title (GTK_WINDOW (gds_manpage), "GDS Manpage Viewer"); main_box = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (gds_manpage), main_box); gtk_widget_show (main_box); util_box = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (main_box), util_box, TRUE, TRUE, 0); gtk_widget_show (util_box); gds_manpage->extext = gtk_extext_new (); gtk_widget_set_usize (gds_manpage->extext, 500, 500); gtk_box_pack_start (GTK_BOX (util_box), gds_manpage->extext, TRUE, TRUE, 0); gtk_extext_set_draw_pixmaps (GTK_EXTEXT (gds_manpage->extext), FALSE); gtk_extext_set_draw_numbers (GTK_EXTEXT (gds_manpage->extext), FALSE); gtk_extext_set_draw_cursor (GTK_EXTEXT (gds_manpage->extext), FALSE); gtk_widget_show (gds_manpage->extext); vscrollbar = gtk_vscrollbar_new (GTK_EXTEXT (gds_manpage->extext)->vadj); gtk_box_pack_start (GTK_BOX (util_box), vscrollbar, FALSE, FALSE, 0); gtk_widget_show (vscrollbar); hsep = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (main_box), hsep, TRUE, TRUE, 5); gtk_widget_show (hsep); util_box = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (main_box), util_box, TRUE, TRUE, 0); gtk_widget_show (util_box); label = gtk_label_new ("Manpage: "); gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 0); gtk_widget_show (label); gds_manpage->search_combo = gtk_combo_new (); gtk_combo_disable_activate (GTK_COMBO (gds_manpage->search_combo)); gtk_box_pack_start (GTK_BOX (util_box), gds_manpage->search_combo, FALSE, TRUE, 0); gtk_signal_connect (GTK_OBJECT (GTK_COMBO (gds_manpage->search_combo)->entry), "changed", GTK_SIGNAL_FUNC (set_search_button_sensitive), gds_manpage); gtk_signal_connect (GTK_OBJECT (GTK_COMBO (gds_manpage->search_combo)->entry), "activate", GTK_SIGNAL_FUNC (set_page_from_entry_text), gds_manpage); gtk_widget_show (gds_manpage->search_combo); gds_manpage->close_button = gnome_stock_button (GNOME_STOCK_BUTTON_CLOSE); gtk_box_pack_end (GTK_BOX (util_box), gds_manpage->close_button, FALSE, FALSE, 5); gtk_signal_connect_object (GTK_OBJECT (gds_manpage->close_button), "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy), (GtkObject *) gds_manpage); GTK_WIDGET_SET_FLAGS (gds_manpage->close_button, GTK_CAN_DEFAULT); gtk_widget_show (gds_manpage->close_button); gds_manpage->search_button = gnome_pixmap_button (gnome_stock_pixmap_widget_at_size (GTK_WIDGET (gds_manpage), GNOME_STOCK_PIXMAP_SEARCH, 20, 20), "Search"); gtk_signal_connect (GTK_OBJECT (gds_manpage->search_button), "clicked", GTK_SIGNAL_FUNC (set_page_from_entry_text), gds_manpage); gtk_box_pack_end (GTK_BOX (util_box), gds_manpage->search_button, FALSE, FALSE, 5); GTK_WIDGET_SET_FLAGS (gds_manpage->search_button, GTK_CAN_DEFAULT); gtk_widget_grab_default (gds_manpage->search_button); gtk_widget_show (gds_manpage->search_button); gtk_widget_set_sensitive (gds_manpage->search_button, FALSE); gtk_extext_set_editable (GTK_EXTEXT (gds_manpage->extext), FALSE); return GTK_WIDGET (gds_manpage); } static void gds_manpage_destroy (GtkObject * object) { GtkWidget *gds_manpage; g_return_if_fail (object != NULL); g_return_if_fail (GDS_IS_MANPAGE (object)); gds_manpage = GTK_WIDGET (object); kill_combo_history (GDS_MANPAGE (gds_manpage)->history); gtk_widget_destroy (gds_manpage); } static void set_search_button_sensitive (GtkWidget * widget, GdsManpage * gmp) { if (strlen (gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (gmp->search_combo)->entry))) > 0) { gtk_widget_set_sensitive (gmp->search_button, TRUE); } else { gtk_widget_set_sensitive (gmp->search_button, FALSE); } } static void set_page_from_entry_text (GtkWidget * widget, GdsManpage * gds_manpage) { FILE *fp; gchar line[128]; GtkEntry *entry = (GtkEntry *) GTK_COMBO (gds_manpage->search_combo)->entry; gchar *man_text; gchar man_command[128] = "man "; gint n = 0; gchar text[128]; gchar cur; gint lines = 0; man_text = gtk_entry_get_text (entry); if (strlen (man_text) < 1) { return; } strcat (man_command, man_text); if (!(fp = popen (man_command, "r"))) { perror ("Error opening man process!"); return; } if (GTK_WIDGET (gds_manpage)->window != NULL) gdk_window_set_cursor (GTK_WIDGET (gds_manpage)->window, gdk_cursor_new (GDK_WATCH)); while (gtk_events_pending ()) gtk_main_iteration (); if (feof (fp)) { error_dialog (GTK_WIDGET (gds_manpage), man_text); return; } gtk_extext_freeze (GTK_EXTEXT (gds_manpage->extext)); gtk_extext_set_editable (GTK_EXTEXT (gds_manpage->extext), TRUE); gtk_extext_delete_text (GTK_EXTEXT (gds_manpage->extext), 0, GTK_EXTEXT (gds_manpage->extext)->length); while (fgets (line, sizeof (line), fp)) { gint i = 0, j = 0; lines++; n = strlen (line); for (i = 0; i < n; i++) { cur = line[i]; if (line[i + 1] == 8) i++; else if (line[i] != 8) { text[j] = cur; j++; text[j] = '\0'; } } if (j > 0) gtk_extext_insert (GTK_EXTEXT (gds_manpage->extext), text, strlen (text)); while (gtk_events_pending ()) gtk_main_iteration (); } pclose (fp); gtk_extext_thaw (GTK_EXTEXT (gds_manpage->extext)); gtk_extext_set_position (GTK_EXTEXT (gds_manpage->extext), 0); gtk_extext_set_editable (GTK_EXTEXT (gds_manpage->extext), FALSE); g_print ("%d lines were printed.\n", lines); if (lines < 1) { error_dialog (GTK_WIDGET (gds_manpage), man_text); } if (GTK_WIDGET (gds_manpage)->window != NULL) gdk_window_set_cursor (GTK_WIDGET (gds_manpage)->window, gdk_cursor_new (GDK_LEFT_PTR)); } gboolean gds_manpage_change_page (GdsManpage * gds_manpage, gchar * manpage) { gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gds_manpage->search_combo)->entry), manpage); set_page_from_entry_text (NULL, gds_manpage); return (TRUE); } void gds_manpage_set_history (GdsManpage * gmp, GList * history) { g_return_if_fail (gmp != NULL); g_return_if_fail (GDS_IS_MANPAGE (gmp)); if (history == NULL) { return; } gmp->history = history; gtk_combo_set_popdown_strings (GTK_COMBO (gmp->search_combo), gmp->history); } gboolean gds_manpage_add_search_string (GdsManpage * gmp, gchar * string) { gpointer temp; g_return_val_if_fail (gmp != NULL, FALSE); g_return_val_if_fail (GDS_IS_MANPAGE (gmp), FALSE); if (check_glist_for_multiple_entries (gmp->history, string)) return (FALSE); temp = g_new (char, strlen (string) + 1); strcpy ((gchar *) temp, string); gmp->history = g_list_prepend (gmp->history, temp); gtk_combo_set_popdown_strings (GTK_COMBO (gmp->search_combo), gmp->history); return (TRUE); } void gds_manpage_set_search_string (GdsManpage * gmp, gchar * string) { g_return_if_fail (gmp != NULL); g_return_if_fail (GDS_IS_MANPAGE (gmp)); if (string) gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (gmp->search_combo)->entry), string); } void error_dialog (GtkWidget * parent, gchar * search) { GtkWidget *error_window; GnomeDialog *dialog; GtkWidget *pixmap; GtkWidget *box; gchar *name; GtkWidget *label; gchar *line; error_window = gnome_dialog_new (_("Error!"), GNOME_STOCK_BUTTON_OK, NULL); dialog = GNOME_DIALOG (error_window); box = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (dialog->vbox), box, FALSE, FALSE, 0); gtk_widget_show (box); name = gnome_pixmap_file ("gnome-error.png"); if (name) { pixmap = gnome_pixmap_new_from_file (name); gtk_box_pack_start (GTK_BOX (box), pixmap, FALSE, FALSE, 10); gtk_widget_show (pixmap); } line = g_strconcat ("No manual entry for ", search, " !", NULL); label = gtk_label_new (line); gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 5); gtk_widget_show (label); g_free (line); gnome_dialog_set_parent (dialog, GTK_WINDOW (parent)); gnome_dialog_run_and_close (dialog); } static gboolean check_glist_for_multiple_entries (GList * list, gchar * new_entry) { GList *temp; gchar *cmp_text; if (list == NULL) { return (FALSE); } temp = list; while (temp != NULL) { cmp_text = temp->data; if (!strcmp (cmp_text, new_entry)) { return (TRUE); } temp = g_list_next (temp); } return (FALSE); } static void kill_combo_history (GList * list) { GList *temp; if (list == NULL) return; temp = list; while (temp != NULL) { g_free (temp->data); temp = g_list_next (temp); } g_list_free (list); }