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