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 <data/file-name.h>
20 #include "window-manager.h"
21 #include "output-viewer.h"
25 #include <sys/types.h>
29 #include <glade/glade.h>
36 struct editor_window parent;
37 GtkTextBuffer *buffer; /* The buffer which contains the text */
39 FILE *fp; /* The file it's viewing */
44 cancel_urgency (GtkWindow *window, gpointer data)
46 gtk_window_set_urgency_hint (window, FALSE);
50 static struct output_viewer *the_output_viewer = NULL;
52 int viewer_length = 16;
53 int viewer_width = 59;
55 /* Callback for the "delete" action (clicking the x on the top right
56 hand corner of the window) */
58 on_delete (GtkWidget *w, GdkEvent *event, gpointer user_data)
60 struct output_viewer *ov = user_data;
64 the_output_viewer = NULL;
66 unlink (output_file_name ());
72 /* Sets width and length according to the new size
73 of the output window */
75 on_textview_resize (GtkWidget *widget,
76 GtkAllocation *allocation,
79 PangoContext * context ;
81 PangoRectangle logical;
83 gint right_margin, left_margin;
84 GtkTextView *text_view = GTK_TEXT_VIEW (widget);
86 context = gtk_widget_create_pango_context (widget);
87 layout = pango_layout_new (context);
89 style = gtk_widget_get_style (widget);
91 pango_layout_set_font_description (layout, style->font_desc);
93 /* Find the width of one character. We can use any character, because
94 the textview has a monospaced font */
95 pango_layout_set_text (layout, "M", 1);
97 pango_layout_get_extents (layout, NULL, &logical);
99 left_margin = gtk_text_view_get_left_margin (text_view);
100 right_margin = gtk_text_view_get_right_margin (text_view);
102 viewer_length = allocation->height / PANGO_PIXELS (logical.height);
103 viewer_width = (allocation->width - right_margin - left_margin)
104 / PANGO_PIXELS (logical.width);
106 g_object_unref (G_OBJECT (layout));
107 g_object_unref (G_OBJECT (context));
113 Create a new output viewer
115 struct output_viewer *
116 new_output_viewer (void)
118 GladeXML *xml = XML_NEW ("output-viewer.glade");
120 struct output_viewer *ov ;
121 struct editor_window *e;
125 ov = g_malloc (sizeof (*ov));
127 e = (struct editor_window *)ov;
130 e->window = GTK_WINDOW (get_widget_assert (xml, "output-viewer-window"));
131 ov->textview = get_widget_assert (xml, "output-viewer-textview");
132 ov->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (ov->textview));
134 g_signal_connect (e->window,
136 G_CALLBACK (cancel_urgency),
140 /* Output uses ascii characters for tabular material.
141 So we need a monospaced font otherwise it'll look silly */
142 PangoFontDescription *font_desc =
143 pango_font_description_from_string ("monospace");
145 gtk_widget_modify_font (ov->textview, font_desc);
146 pango_font_description_free (font_desc);
149 g_signal_connect (ov->textview, "size-allocate",
150 G_CALLBACK (on_textview_resize), NULL);
154 g_signal_connect (get_widget_assert (xml,"help_about"),
156 G_CALLBACK (about_new),
159 g_signal_connect (get_widget_assert (xml,"help_reference"),
161 G_CALLBACK (reference_manual),
164 g_signal_connect (get_widget_assert (xml,"windows_minimise-all"),
166 G_CALLBACK (minimise_all_windows),
169 g_object_unref (xml);
172 g_signal_connect (e->window, "delete-event",
173 G_CALLBACK (on_delete), ov);
180 reload_the_viewer (void)
184 /* If there is no output, then don't do anything */
185 if (0 != stat (output_file_name (), &buf))
188 if ( NULL == the_output_viewer )
191 (struct output_viewer *) window_create (WINDOW_OUTPUT, NULL);
194 reload_viewer (the_output_viewer);
197 #define OUTPUT_FILE_NAME "psppire.txt"
200 reload_viewer (struct output_viewer *ov)
202 GtkTextIter end_iter;
205 static char *line = NULL;
207 gboolean chars_inserted = FALSE;
209 gtk_text_buffer_get_end_iter (ov->buffer, &end_iter);
211 line = xrealloc (line, sizeof (char) * (viewer_width + 1));
214 mark = gtk_text_buffer_create_mark (ov->buffer, NULL, &end_iter, TRUE);
218 Apparently Windoze is not capabale of writing to a file whilst
219 another (or the same) process is reading from it. Therefore, we
220 must close the file after reading it, and clear the entire buffer
221 before writing to it.
222 This will be slower for large buffers, but should work
223 (in so far as anything ever works on windows).
226 GtkTextIter start_iter;
227 FILE *fp = fopen (OUTPUT_FILE_NAME, "r");
230 g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
234 /* Delete all the entire buffer */
235 gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
236 gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter);
239 gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
240 /* Read in the next lot of text */
241 while (fgets (line, viewer_width + 1, fp) != NULL)
243 chars_inserted = TRUE;
244 gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1);
253 ov->fp = fopen (output_file_name (), "r");
256 g_print ("Cannot open %s\n", output_file_name ());
261 /* Read in the next lot of text */
262 while (fgets (line, viewer_width + 1, ov->fp) != NULL)
264 chars_inserted = TRUE;
265 gtk_text_buffer_insert (ov->buffer, &end_iter, line, -1);
270 /* Scroll to where the start of this lot of text begins */
271 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ov->textview),
273 0.1, TRUE, 0.0, 0.0);
276 if ( chars_inserted )
277 gtk_window_set_urgency_hint ( ((struct editor_window *)ov)->window, TRUE);
284 output_file_name (void)
286 const char *dir = default_output_path ();
287 static char *filename = NULL;
289 if ( NULL == filename )
290 filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME);