1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "window-manager.h"
20 #include "output-viewer.h"
24 #include <sys/types.h>
28 #include <glade/glade.h>
35 struct editor_window parent;
36 GtkTextBuffer *buffer; /* The buffer which contains the text */
38 FILE *fp; /* The file it's viewing */
43 cancel_urgency (GtkWindow *window, gpointer data)
45 gtk_window_set_urgency_hint (window, FALSE);
49 static struct output_viewer *the_output_viewer = NULL;
51 int viewer_length = 16;
52 int viewer_width = 59;
54 /* Callback for the "delete" action (clicking the x on the top right
55 hand corner of the window) */
57 on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
59 struct output_viewer *ov = user_data;
63 the_output_viewer = NULL;
65 unlink (OUTPUT_FILE_NAME);
71 /* Sets width and length according to the new size
72 of the output window */
74 on_textview_resize (GtkWidget *widget,
75 GtkAllocation *allocation,
78 PangoContext * context ;
80 PangoRectangle logical;
82 gint right_margin, left_margin;
83 GtkTextView *text_view = GTK_TEXT_VIEW (widget);
85 context = gtk_widget_create_pango_context (widget);
86 layout = pango_layout_new (context);
88 style = gtk_widget_get_style (widget);
90 pango_layout_set_font_description (layout, style->font_desc);
92 /* Find the width of one character. We can use any character, because
93 the textview has a monospaced font */
94 pango_layout_set_text (layout, "M", 1);
96 pango_layout_get_extents (layout, NULL, &logical);
98 left_margin = gtk_text_view_get_left_margin (text_view);
99 right_margin = gtk_text_view_get_right_margin (text_view);
101 viewer_length = allocation->height / PANGO_PIXELS (logical.height);
102 viewer_width = (allocation->width - right_margin - left_margin)
103 / PANGO_PIXELS (logical.width);
105 g_object_unref (G_OBJECT (layout));
106 g_object_unref (G_OBJECT (context));
112 Create a new output viewer
114 struct output_viewer *
115 new_output_viewer (void)
117 GladeXML *xml = XML_NEW ("output-viewer.glade");
119 struct output_viewer *ov ;
120 struct editor_window *e;
124 ov = g_malloc (sizeof (*ov));
126 e = (struct editor_window *)ov;
129 e->window = GTK_WINDOW (get_widget_assert (xml, "output-viewer-window"));
130 ov->textview = get_widget_assert (xml, "output-viewer-textview");
131 ov->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (ov->textview));
133 g_signal_connect (e->window,
135 G_CALLBACK (cancel_urgency),
139 /* Output uses ascii characters for tabular material.
140 So we need a monospaced font otherwise it'll look silly */
141 PangoFontDescription *font_desc =
142 pango_font_description_from_string ("monospace");
144 gtk_widget_modify_font (ov->textview, font_desc);
145 pango_font_description_free (font_desc);
148 g_signal_connect (ov->textview, "size-allocate",
149 G_CALLBACK (on_textview_resize), NULL);
153 g_signal_connect (get_widget_assert (xml,"help_about"),
155 G_CALLBACK (about_new),
158 g_signal_connect (get_widget_assert (xml,"help_reference"),
160 G_CALLBACK (reference_manual),
163 g_signal_connect (get_widget_assert (xml,"windows_minimise-all"),
165 G_CALLBACK (minimise_all_windows),
168 g_object_unref (xml);
171 g_signal_connect (e->window, "delete-event",
172 G_CALLBACK (on_delete), ov);
179 reload_the_viewer (void)
183 /* If there is no output, then don't do anything */
184 if (0 != stat (OUTPUT_FILE_NAME, &buf))
187 if ( NULL == the_output_viewer )
190 (struct output_viewer *) window_create (WINDOW_OUTPUT, NULL);
193 reload_viewer (the_output_viewer);
198 reload_viewer (struct output_viewer *ov)
200 GtkTextIter end_iter;
203 static char *line = NULL;
205 gboolean chars_inserted = FALSE;
207 gtk_text_buffer_get_end_iter (ov->buffer, &end_iter);
209 line = xrealloc (line, sizeof (char) * (viewer_width + 1));
212 mark = gtk_text_buffer_create_mark (ov->buffer, NULL, &end_iter, TRUE);
216 Apparently Windoze is not capabale of writing to a file whilst
217 another (or the same) process is reading from it. Therefore, we
218 must close the file after reading it, and clear the entire buffer
219 before writing to it.
220 This will be slower for large buffers, but should work
221 (in so far as anything ever works on windows).
224 GtkTextIter start_iter;
225 FILE *fp = fopen (OUTPUT_FILE_NAME, "r");
228 g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
232 /* Delete all the entire buffer */
233 gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
234 gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter);
237 gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
238 /* Read in the next lot of text */
239 while (fgets (line, viewer_width + 1, fp) != NULL)
241 chars_inserted = TRUE;
242 gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1);
251 ov->fp = fopen (OUTPUT_FILE_NAME, "r");
254 g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
259 /* Read in the next lot of text */
260 while (fgets (line, viewer_width + 1, ov->fp) != NULL)
262 chars_inserted = TRUE;
263 gtk_text_buffer_insert (ov->buffer, &end_iter, line, -1);
268 /* Scroll to where the start of this lot of text begins */
269 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ov->textview),
271 0.1, TRUE, 0.0, 0.0);
274 if ( chars_inserted )
275 gtk_window_set_urgency_hint ( ((struct editor_window *)ov)->window, TRUE);