ffdd491ee2d780bdb8ebdbe3e9edc4fa48e44816
[pspp-builds.git] / src / ui / gui / message-dialog.c
1 /*
2    PSPPIRE --- A Graphical User Interface for PSPP
3    Copyright (C) 2004,2005  Free Software Foundation
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA.
19 */
20
21
22 #include <stdio.h>
23 #include <stdarg.h>
24
25 #include <config.h>
26 #include <gettext.h>
27 #define _(msgid) gettext (msgid)
28 #define N_(msgid) msgid
29
30 #include <libpspp/message.h>
31 #include <libpspp/msg-locator.h>
32 #include "message-dialog.h"
33 #include "progname.h"
34
35
36 #include <gtk/gtk.h>
37 #include <glade/glade.h>
38 #include <glib.h>
39
40 #include "helper.h"
41
42 static void enqueue_msg (const struct msg *m);
43
44
45 static GQueue *message_queue;
46
47
48 void
49 message_dialog_init (struct source_stream *ss)
50 {
51   message_queue = g_queue_new ();
52   msg_init (ss, enqueue_msg);
53 }
54
55 void
56 message_dialog_done (void)
57 {
58   msg_done ();
59   g_queue_free (message_queue);
60 }
61
62 static gboolean
63 dequeue_message (gpointer data)
64 {
65   struct msg * m ;
66
67   /* If a pointer grab is in effect, then the combination of that, and
68      a modal dialog box, will cause an impossible situation.
69      So don't pop it up just yet.
70   */
71   if ( gdk_pointer_is_grabbed ())
72     return TRUE;
73
74   m = g_queue_pop_tail (message_queue);
75
76   if ( m )
77     {
78       popup_message (m);
79       msg_destroy (m);
80       return TRUE;
81     }
82
83   return FALSE;
84 }
85
86 static void
87 enqueue_msg (const struct msg *msg)
88 {
89   struct msg *m = msg_dup (msg);
90
91   g_queue_push_head (message_queue, m);
92
93   g_idle_add (dequeue_message, 0);
94 }
95
96
97 void
98 popup_message (const struct msg *m)
99 {
100   GtkWidget *dialog;
101   gchar *location = NULL;
102
103   gint message_type;
104   const char *msg;
105
106   switch (m->severity)
107     {
108     case MSG_ERROR:
109       message_type = GTK_MESSAGE_ERROR;
110       break;
111     case MSG_WARNING:
112       message_type = GTK_MESSAGE_WARNING;
113       break;
114     case MSG_NOTE:
115     default:
116       message_type = GTK_MESSAGE_INFO;
117       break;
118     };
119
120   switch (m->category)
121     {
122     case MSG_SYNTAX:
123       msg = _("Script Error");
124       break;
125
126     case MSG_DATA:
127       msg = _("Data File Error");
128       break;
129
130     case MSG_GENERAL:
131     default:
132       msg = _("PSPP Error");
133       break;
134     };
135
136   dialog = gtk_message_dialog_new ( NULL,
137                                   GTK_DIALOG_MODAL,
138                                   message_type,
139                                   GTK_BUTTONS_CLOSE,
140                                   msg);
141   if ( m->where.line_number != -1)
142     {
143       location = g_strdup_printf (_("%s (line %d)"),
144                                   m->where.file_name ? m->where.file_name : "",
145                                   m->where.line_number);
146     }
147   else
148     {
149       location = g_strdup_printf (_("%s"),
150                                   m->where.file_name ? m->where.file_name : "");    }
151
152   gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
153                                             _("%s %s"),
154                                             location,
155                                             m->text);
156   g_free (location);
157
158   gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
159
160   gtk_dialog_run (GTK_DIALOG (dialog));
161
162   gtk_widget_destroy (dialog);
163 }
164