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);
199 reload_viewer (struct output_viewer *ov)
201 GtkTextIter end_iter;
204 static char *line = NULL;
206 gboolean chars_inserted = FALSE;
208 gtk_text_buffer_get_end_iter (ov->buffer, &end_iter);
210 line = xrealloc (line, sizeof (char) * (viewer_width + 1));
213 mark = gtk_text_buffer_create_mark (ov->buffer, NULL, &end_iter, TRUE);
217 Apparently Windoze is not capabale of writing to a file whilst
218 another (or the same) process is reading from it. Therefore, we
219 must close the file after reading it, and clear the entire buffer
220 before writing to it.
221 This will be slower for large buffers, but should work
222 (in so far as anything ever works on windows).
225 GtkTextIter start_iter;
226 FILE *fp = fopen (OUTPUT_FILE_NAME, "r");
229 g_print ("Cannot open %s\n", OUTPUT_FILE_NAME);
233 /* Delete all the entire buffer */
234 gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
235 gtk_text_buffer_delete (ov->buffer, &start_iter, &end_iter);
238 gtk_text_buffer_get_start_iter (ov->buffer, &start_iter);
239 /* Read in the next lot of text */
240 while (fgets (line, viewer_width + 1, fp) != NULL)
242 chars_inserted = TRUE;
243 gtk_text_buffer_insert (ov->buffer, &start_iter, line, -1);
252 ov->fp = fopen (output_file_name (), "r");
255 g_print ("Cannot open %s\n", output_file_name ());
260 /* Read in the next lot of text */
261 while (fgets (line, viewer_width + 1, ov->fp) != NULL)
263 chars_inserted = TRUE;
264 gtk_text_buffer_insert (ov->buffer, &end_iter, line, -1);
269 /* Scroll to where the start of this lot of text begins */
270 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (ov->textview),
272 0.1, TRUE, 0.0, 0.0);
275 if ( chars_inserted )
276 gtk_window_set_urgency_hint ( ((struct editor_window *)ov)->window, TRUE);
280 #define OUTPUT_FILE_NAME "psppire.txt"
283 output_file_name (void)
285 const char *dir = default_output_path ();
286 static char *filename = NULL;
288 if ( NULL == filename )
289 filename = xasprintf ("%s%s", dir, OUTPUT_FILE_NAME);