X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Fui%2Fgui%2Fmessage-dialog.c;h=d0f02dfaddef54f32b3c3fd9088fd8e7a7738fc0;hb=e51aad5ecebae7e6cdd4acc38be1a738e5c0e6c4;hp=01eb8ce509409219622a8039b9b90d596c7cb1e9;hpb=52b9fca3a729eaef7d13469029e4391aa033a659;p=pspp
diff --git a/src/ui/gui/message-dialog.c b/src/ui/gui/message-dialog.c
index 01eb8ce509..d0f02dfadd 100644
--- a/src/ui/gui/message-dialog.c
+++ b/src/ui/gui/message-dialog.c
@@ -1,11 +1,9 @@
-/*
- PSPPIRE --- A Graphical User Interface for PSPP
- Copyright (C) 2004,2005 Free Software Foundation
- Written by John Darrington
+/* PSPPIRE - a graphical user interface for PSPP.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
+ This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -14,149 +12,269 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
+ along with this program. If not, see . */
#include
#include
#include
+#include
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
#include
+#include
+#include
#include "message-dialog.h"
+#include "progname.h"
#include
#include
+#include
#include "helper.h"
-extern GladeXML *xml;
-
-#define _(A) A
+static void enqueue_msg (const struct msg *m);
+static gboolean popup_messages (gpointer);
+#define MAX_EARLY_MESSAGES 100
+static GQueue *early_queue;
-void
-vmsg(int klass, const char *fmt, va_list args)
-{
- gchar *msg = 0;
- gchar *text = g_strdup_vprintf (fmt, args);
+static unsigned long dropped_messages;
- GtkWindow *parent ;
- GtkWidget *dialog ;
-
- gint message_type;
+#define MAX_LATE_MESSAGES 10
+static GQueue *late_queue;
- switch (klass)
- {
- case SE:
- case DE:
- case ME:
- message_type = GTK_MESSAGE_ERROR;
- break;
- case SW:
- case DW:
- case MW:
- message_type = GTK_MESSAGE_WARNING;
- break;
- case SM:
- case MM:
- default:
- message_type = GTK_MESSAGE_INFO;
- break;
- };
-
- switch (klass)
- {
- case SE:
- case SW:
- case SM:
- msg = g_strdup(_("Script Error"));
- break;
+static int error_cnt, warning_cnt, note_cnt;
- case DE:
- case DW:
- msg = g_strdup(_("Data File Error"));
- break;
+static GladeXML *message_xml;
+static GtkWidget *message_dialog;
- case ME:
- case MW:
- case MM:
- default:
- msg = g_strdup(_("PSPP Error"));
- break;
- };
-
- parent = GTK_WINDOW(get_widget_assert(xml, "data_editor"));
-
- dialog = gtk_message_dialog_new(parent,
- GTK_DIALOG_MODAL,
- message_type,
- GTK_BUTTONS_CLOSE,
- msg);
-
- gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), text);
-
- g_free(text);
- g_free(msg);
-
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-
- gtk_dialog_run(GTK_DIALOG(dialog));
-
- gtk_widget_destroy (dialog);
-
-}
-
-
-void
-msg(int klass, const char *fmt, ...)
+void
+message_dialog_init (struct source_stream *ss)
{
- va_list ap;
- va_start(ap, fmt);
- vmsg(klass, fmt, ap);
- va_end(ap);
+ early_queue = g_queue_new ();
+ dropped_messages = 0;
+ late_queue = g_queue_new ();
+ error_cnt = warning_cnt = note_cnt = 0;
+ msg_init (ss, enqueue_msg);
+ message_xml = XML_NEW ("message-dialog.glade");
+ message_dialog = get_widget_assert (message_xml, "message-dialog");
}
-
void
-err_vmsg (const struct error *e, const char *format, va_list args)
+message_dialog_done (void)
{
- vmsg(e->class, format, args);
+ msg_done ();
+ g_queue_free (early_queue);
+ dropped_messages = 0;
+ g_queue_free (late_queue);
+ gtk_widget_destroy (message_dialog);
+ g_object_unref (message_xml);
}
-
-void
-err_assert_fail(const char *expr, const char *file, int line)
+static void
+format_message (struct msg *m, struct string *msg)
{
- msg(ME, "Assertion failed: %s:%d; (%s)\n",file,line,expr);
+ const char *label;
+
+ if (m->where.file_name)
+ ds_put_format (msg, "%s:", m->where.file_name);
+ if (m->where.line_number != -1)
+ ds_put_format (msg, "%d:", m->where.line_number);
+ if (m->where.file_name || m->where.line_number != -1)
+ ds_put_char (msg, ' ');
+
+ switch (m->severity)
+ {
+ case MSG_ERROR:
+ switch (m->category)
+ {
+ case MSG_SYNTAX:
+ label = _("syntax error");
+ break;
+
+ case MSG_DATA:
+ label = _("data file error");
+ break;
+
+ case MSG_GENERAL:
+ default:
+ label = _("PSPP error");
+ break;
+ }
+ break;
+ case MSG_WARNING:
+ switch (m->category)
+ {
+ case MSG_SYNTAX:
+ label = _("syntax warning");
+ break;
+
+ case MSG_DATA:
+ label = _("data file warning");
+ break;
+
+ case MSG_GENERAL:
+ default:
+ label = _("PSPP warning");
+ break;
+ }
+ break;
+ case MSG_NOTE:
+ default:
+ switch (m->category)
+ {
+ case MSG_SYNTAX:
+ label = _("syntax information");
+ break;
+
+ case MSG_DATA:
+ label = _("data file information");
+ break;
+
+ case MSG_GENERAL:
+ default:
+ label = _("PSPP information");
+ break;
+ }
+ break;
+ }
+ ds_put_format (msg, "%s: %s\n", label, m->text);
+ msg_destroy (m);
}
-/* The GUI is always interactive.
- So this function does nothing */
-void
-err_cond_fail(void)
+static void
+enqueue_msg (const struct msg *msg)
{
-}
+ struct msg *m = msg_dup (msg);
+ switch (m->severity)
+ {
+ case MSG_ERROR:
+ error_cnt++;
+ break;
+ case MSG_WARNING:
+ warning_cnt++;
+ break;
+ case MSG_NOTE:
+ note_cnt++;
+ break;
+ }
-void
-err_failure(void)
-{
- msg(ME, _("Terminating NOW due to fatal error"));
- gtk_main_quit();
+ if (g_queue_get_length (early_queue) < MAX_EARLY_MESSAGES)
+ {
+ if (g_queue_is_empty (early_queue))
+ g_idle_add (popup_messages, NULL);
+ g_queue_push_tail (early_queue, m);
+ }
+ else
+ {
+ if (g_queue_get_length (late_queue) >= MAX_LATE_MESSAGES)
+ {
+ struct msg *m = g_queue_pop_head (late_queue);
+ msg_destroy (m);
+ dropped_messages++;
+ }
+ g_queue_push_tail (late_queue, m);
+ }
}
-
-/* FIXME: This is a stub .
- * A temporary workaround until getl.c is rearranged
- */
-void
-err_location (struct file_locator *f)
+static gboolean
+popup_messages (gpointer unused UNUSED)
{
- f->filename = 0;
- f->line_number = -1;
+ GtkTextBuffer *text_buffer;
+ GtkTextIter end;
+ GtkTextView *text_view;
+ GtkLabel *label;
+ struct string lead = DS_EMPTY_INITIALIZER;
+ struct string msg = DS_EMPTY_INITIALIZER;
+ int message_cnt;
+
+ /* Set up the dialog. */
+ if (message_xml == NULL || message_dialog == NULL)
+ goto use_fallback;
+
+ /* If a pointer grab is in effect, then the combination of that, and
+ a modal dialog box, will cause an impossible situation.
+ So don't pop it up just yet.
+ */
+ if ( gdk_display_pointer_is_grabbed (gtk_widget_get_display (message_dialog)))
+ {
+ ds_destroy (&lead);
+ ds_destroy (&msg);
+ return TRUE;
+ }
+
+ /* Compose the lead-in. */
+ message_cnt = error_cnt + warning_cnt + note_cnt;
+ if (dropped_messages == 0)
+ ds_put_format (
+ &lead,
+ ngettext ("The PSPP processing engine reported the following message:",
+ "The PSPP processing engine reported the following messages:",
+ message_cnt));
+ else
+ {
+ ds_put_format (
+ &lead,
+ ngettext ("The PSPP processing engine reported %d message.",
+ "The PSPP processing engine reported %d messages.",
+ message_cnt),
+ message_cnt);
+ ds_put_cstr (&lead, " ");
+ ds_put_format (
+ &lead,
+ ngettext ("%d of these messages are displayed below.",
+ "%d of these messages are displayed below.",
+ MAX_EARLY_MESSAGES + MAX_LATE_MESSAGES),
+ MAX_EARLY_MESSAGES + MAX_LATE_MESSAGES);
+ }
+
+
+ /* Compose the messages. */
+ while (!g_queue_is_empty (early_queue))
+ format_message (g_queue_pop_head (early_queue), &msg);
+ if (dropped_messages)
+ {
+ ds_put_format (&msg, "...\nOmitting %lu messages\n...\n",
+ dropped_messages);
+ dropped_messages = 0;
+ }
+ while (!g_queue_is_empty (late_queue))
+ format_message (g_queue_pop_head (late_queue), &msg);
+
+ text_buffer = gtk_text_buffer_new (NULL);
+ gtk_text_buffer_get_end_iter (text_buffer, &end);
+ gtk_text_buffer_insert (text_buffer, &end, ds_data (&msg), ds_length (&msg));
+
+ label = GTK_LABEL (get_widget_assert (message_xml, "lead-in"));
+ if (label == NULL)
+ goto use_fallback;
+ gtk_label_set_text (label, ds_cstr (&lead));
+
+ text_view = GTK_TEXT_VIEW (get_widget_assert (message_xml, "message"));
+ if (text_view == NULL)
+ goto use_fallback;
+ gtk_text_view_set_buffer (text_view, text_buffer);
+
+ gtk_widget_grab_focus (get_widget_assert (message_xml, "close-button"));
+ gtk_dialog_run ( GTK_DIALOG (message_dialog));
+ gtk_widget_hide (message_dialog);
+
+ ds_destroy (&lead);
+ ds_destroy (&msg);
+
+ return FALSE;
+
+use_fallback:
+ g_warning ("Could not create message dialog. "
+ "Is PSPPIRE properly installed?");
+ fputs (ds_cstr (&msg), stderr);
+ ds_destroy (&lead);
+ ds_destroy (&msg);
+ return FALSE;
}