8b910ce242a093d74fa4451c4f50c372b1688ce7
[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 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 void
53 message_dialog_init (struct source_stream *ss) 
54 {
55   message_queue = g_queue_new();
56   msg_init (ss, enqueue_msg);
57 }
58
59 void
60 message_dialog_done (void)
61 {
62   msg_done();
63   g_queue_free(message_queue);
64 }
65
66 static gboolean 
67 dequeue_message(gpointer data)
68 {
69   struct msg * m ;
70
71   /* If a pointer grab is in effect, then the combination of that, and
72      a modal dialog box, will cause an impossible situation. 
73      So don't pop it up just yet.
74   */ 
75   if ( gdk_pointer_is_grabbed())
76     return TRUE;
77
78   m = g_queue_pop_tail(message_queue);
79
80   if ( m ) 
81     {
82       popup_message(m);
83       msg_destroy(m);
84       return TRUE;
85     }
86   
87   return FALSE;
88 }
89
90 static void
91 enqueue_msg(const struct msg *msg)
92 {
93   struct msg *m = msg_dup(msg);
94
95   g_queue_push_head(message_queue, m);
96
97   g_idle_add(dequeue_message, 0);
98 }
99
100
101 void 
102 popup_message(const struct msg *m)
103 {
104   GtkWindow *parent;
105   GtkWidget *dialog;
106
107   gint message_type;
108   const char *msg;
109
110   switch (m->severity)
111     {
112     case MSG_ERROR:
113       message_type = GTK_MESSAGE_ERROR;
114       break;
115     case MSG_WARNING:
116       message_type = GTK_MESSAGE_WARNING;
117       break;
118     case MSG_NOTE:
119     default:
120       message_type = GTK_MESSAGE_INFO;
121       break;
122     };
123   
124   switch (m->category) 
125     {
126     case MSG_SYNTAX:
127       msg = _("Script Error");
128       break;
129
130     case MSG_DATA:
131       msg = _("Data File Error");
132       break;
133
134     case MSG_GENERAL:
135     default:
136       msg = _("PSPP Error");
137       break;
138     };
139
140   parent = GTK_WINDOW(get_widget_assert(xml, "data_editor"));
141
142   dialog = gtk_message_dialog_new(parent,
143                                   GTK_DIALOG_MODAL,
144                                   message_type,
145                                   GTK_BUTTONS_CLOSE,
146                                   msg);
147
148   gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
149                                            _("%s (line %d) %s"),
150                                            m->where.file_name,
151                                            m->where.line_number,
152                                            m->text);
153
154   gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
155
156   gtk_dialog_run(GTK_DIALOG(dialog));
157
158   gtk_widget_destroy (dialog);
159 }
160