John's original code for patch #6210.
[pspp-builds.git] / src / ui / gui / message-dialog.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
16
17
18 #include <stdio.h>
19 #include <stdarg.h>
20
21 #include <config.h>
22 #include <gettext.h>
23 #define _(msgid) gettext (msgid)
24 #define N_(msgid) msgid
25
26 #include <libpspp/message.h>
27 #include <libpspp/msg-locator.h>
28 #include "message-dialog.h"
29 #include "progname.h"
30
31
32 #include <gtk/gtk.h>
33 #include <glade/glade.h>
34 #include <glib.h>
35
36 #include "helper.h"
37
38 static void enqueue_msg (const struct msg *m);
39
40
41 static GQueue *message_queue;
42
43
44 void
45 message_dialog_init (struct source_stream *ss)
46 {
47   message_queue = g_queue_new ();
48   msg_init (ss, enqueue_msg);
49 }
50
51 void
52 message_dialog_done (void)
53 {
54   msg_done ();
55   g_queue_free (message_queue);
56 }
57
58 static gboolean
59 dequeue_message (gpointer data)
60 {
61   struct msg * m ;
62
63   /* If a pointer grab is in effect, then the combination of that, and
64      a modal dialog box, will cause an impossible situation.
65      So don't pop it up just yet.
66   */
67   if ( gdk_pointer_is_grabbed ())
68     return TRUE;
69
70   m = g_queue_pop_tail (message_queue);
71
72   if ( m )
73     {
74       popup_message (m);
75       msg_destroy (m);
76       return TRUE;
77     }
78
79   return FALSE;
80 }
81
82 static void
83 enqueue_msg (const struct msg *msg)
84 {
85   struct msg *m = msg_dup (msg);
86
87   g_queue_push_head (message_queue, m);
88
89   g_idle_add (dequeue_message, 0);
90 }
91
92
93 void
94 popup_message (const struct msg *m)
95 {
96   GtkWidget *dialog;
97   gchar *location = NULL;
98
99   gint message_type;
100   const char *msg;
101
102   switch (m->severity)
103     {
104     case MSG_ERROR:
105       message_type = GTK_MESSAGE_ERROR;
106       switch (m->category)
107         {
108         case MSG_SYNTAX:
109           msg = _("Script Error");
110           break;
111
112         case MSG_DATA:
113           msg = _("Data File Error");
114           break;
115
116         case MSG_GENERAL:
117         default:
118           msg = _("PSPP Error");
119           break;
120         };
121       break;
122     case MSG_WARNING:
123       message_type = GTK_MESSAGE_WARNING;
124       switch (m->category)
125         {
126         case MSG_SYNTAX:
127           msg = _("Script Warning");
128       break;
129
130         case MSG_DATA:
131           msg = _("Data File Warning");
132           break;
133
134         case MSG_GENERAL:
135     default:
136           msg = _("PSPP Warning");
137       break;
138     };
139       break;
140     case MSG_NOTE:
141     default:
142       message_type = GTK_MESSAGE_INFO;
143   switch (m->category)
144     {
145     case MSG_SYNTAX:
146           msg = _("Script Information");
147       break;
148
149     case MSG_DATA:
150           msg = _("Data File Information");
151       break;
152
153     case MSG_GENERAL:
154     default:
155           msg = _("PSPP Information");
156           break;
157         };
158       break;
159     };
160
161   dialog = gtk_message_dialog_new ( NULL,
162                                   GTK_DIALOG_MODAL,
163                                   message_type,
164                                   GTK_BUTTONS_CLOSE,
165                                   msg);
166   if ( m->where.line_number != -1)
167     {
168       location = g_strdup_printf (_("%s (line %d)"),
169                                   m->where.file_name ? m->where.file_name : "",
170                                   m->where.line_number);
171     }
172   else
173     {
174       location = g_strdup_printf (_("%s"),
175                                   m->where.file_name ? m->where.file_name : "");    }
176
177   gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
178                                             _("%s %s"),
179                                             location,
180                                             m->text);
181   g_free (location);
182
183   gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
184
185   gtk_dialog_run (GTK_DIALOG (dialog));
186
187   gtk_widget_destroy (dialog);
188 }
189