Easier adjusting of layouts
[dia.git] / lib / message.c
blob50c7e3d56c181c3e31bed6bba39960bc8283ab12
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
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 2 of the License, or
7 * (at your option) any later version.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #include <config.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdarg.h>
24 #undef GTK_DISABLE_DEPRECATED /* for gtk_object_get_user_data */
25 #include <gtk/gtk.h>
26 #include <glib.h>
28 #include "intl.h"
29 #include "utils.h"
30 #include "message.h"
32 static GHashTable *message_hash_table;
34 typedef struct {
35 GtkWidget *dialog;
36 GtkWidget *repeat_label;
37 GList *repeats;
38 GtkWidget *repeat_view;
39 GtkWidget *show_repeats;
40 } DiaMessageInfo;
42 static void
43 gtk_message_toggle_repeats(GtkWidget *button, gpointer *userdata) {
44 DiaMessageInfo *msginfo = (DiaMessageInfo*)userdata;
45 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
46 gtk_widget_show(msginfo->repeat_view);
47 else {
48 gtk_widget_hide(msginfo->repeat_view);
49 gtk_container_check_resize(GTK_CONTAINER(msginfo->dialog));
53 static void
54 message_dialog_destroyed(GtkWidget *widget, gpointer userdata)
56 DiaMessageInfo *msginfo = (DiaMessageInfo *)userdata;
58 msginfo->dialog = NULL;
59 msginfo->repeat_label = NULL;
60 msginfo->repeat_view = NULL;
61 msginfo->show_repeats = NULL;
65 /** Set up a dialog for these messages.
66 * Msginfo may contain repeats, and should be filled out
68 static void
69 message_create_dialog(const gchar *title, DiaMessageInfo *msginfo, gchar *buf)
71 GtkWidget *dialog = NULL;
72 GtkTextBuffer *textbuffer;
73 GtkMessageType type = GTK_MESSAGE_INFO;
74 GList *repeats;
76 /* quite dirty in order to not change Dia's message api */
77 if (title) {
78 if (0 == strcmp (title, _("Error")))
79 type = GTK_MESSAGE_ERROR;
80 else if (0 == strcmp (title, _("Warning")))
81 type = GTK_MESSAGE_WARNING;
83 if (msginfo->repeats != NULL)
84 buf = (gchar *)msginfo->repeats->data;
85 dialog = gtk_message_dialog_new (NULL, /* no parent window */
86 0, /* GtkDialogFlags */
87 type,
88 GTK_BUTTONS_CLOSE,
89 "%s", buf);
90 if (title) {
91 gchar *real_title;
93 real_title = g_strdup_printf ("Dia: %s", title);
94 gtk_window_set_title (GTK_WINDOW(dialog), real_title);
95 g_free (real_title);
97 gtk_widget_show (dialog);
98 g_signal_connect (G_OBJECT (dialog), "response",
99 G_CALLBACK (gtk_widget_hide),
100 NULL);
101 msginfo->dialog = dialog;
102 g_signal_connect (G_OBJECT (dialog), "destroy",
103 G_CALLBACK (message_dialog_destroyed),
104 msginfo);
106 msginfo->repeat_label = gtk_label_new(_("There is one similar message."));
107 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(msginfo->dialog)->vbox),
108 msginfo->repeat_label);
110 msginfo->show_repeats =
111 gtk_check_button_new_with_label(_("Show repeated messages"));
112 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(msginfo->dialog)->vbox),
113 msginfo->show_repeats);
114 g_signal_connect(G_OBJECT(msginfo->show_repeats), "toggled",
115 G_CALLBACK(gtk_message_toggle_repeats), msginfo);
117 msginfo->repeat_view = gtk_text_view_new();
118 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(msginfo->dialog)->vbox),
119 msginfo->repeat_view);
120 gtk_text_view_set_editable(GTK_TEXT_VIEW(msginfo->repeat_view), FALSE);
122 textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(msginfo->repeat_view));
123 if (msginfo->repeats != NULL) {
124 repeats = msginfo->repeats;
125 repeats = repeats->next;
126 for (; repeats != NULL; repeats = repeats->next) {
127 gtk_text_buffer_insert_at_cursor(textbuffer, (gchar*)repeats->data, -1);
132 static void
133 gtk_message_internal(const char* title, const char *fmt,
134 va_list *args, va_list *args2)
136 static gchar *buf = NULL;
137 static gint alloc = 0;
138 gint len;
139 DiaMessageInfo *msginfo;
140 GtkTextBuffer *textbuffer;
142 if (message_hash_table == NULL) {
143 message_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
146 len = format_string_length_upper_bound (fmt, args);
148 if (len >= alloc) {
149 if (buf)
150 g_free (buf);
152 alloc = nearest_pow (MAX(len + 1, 1024));
154 buf = g_new (char, alloc);
157 vsprintf (buf, fmt, *args2);
159 msginfo = (DiaMessageInfo*)g_hash_table_lookup(message_hash_table, fmt);
160 if (msginfo == NULL) {
161 msginfo = g_new0(DiaMessageInfo, 1);
162 g_hash_table_insert(message_hash_table, (char *)fmt, msginfo);
164 if (msginfo->dialog == NULL)
165 message_create_dialog(title, msginfo, buf);
167 if (msginfo->repeats != NULL) {
168 if (g_list_length(msginfo->repeats) > 1) {
169 char *newlabel;
170 newlabel = g_strdup_printf(_("There are %d similar messages."),
171 g_list_length(msginfo->repeats));
172 gtk_label_set_text(GTK_LABEL(msginfo->repeat_label), newlabel);
174 gtk_widget_show(msginfo->repeat_label);
175 gtk_widget_show(msginfo->show_repeats);
178 /* Insert in scrollable view, but only the repeated ones */
179 if (msginfo->repeats != NULL) {
180 textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(msginfo->repeat_view));
181 gtk_text_buffer_insert_at_cursor(textbuffer, buf, -1);
183 msginfo->repeats = g_list_append(msginfo->repeats, g_strdup(buf));
184 gtk_widget_show (msginfo->dialog);
187 static MessageInternal message_internal = gtk_message_internal;
189 void
190 set_message_func(MessageInternal func)
192 g_assert(func);
193 message_internal = func;
196 void
197 message(const char *title, const char *format, ...)
199 va_list args, args2;
201 va_start (args, format);
202 va_start (args2, format);
203 message_internal(title, format, &args, &args2);
204 va_end (args);
205 va_end (args2);
208 void
209 message_notice(const char *format, ...)
211 va_list args, args2;
213 va_start (args, format);
214 va_start (args2, format);
215 message_internal(_("Notice"), format, &args, &args2);
216 va_end (args);
217 va_end (args2);
219 void
220 message_warning(const char *format, ...)
222 va_list args, args2;
224 va_start (args, format);
225 va_start (args2, format);
226 message_internal(_("Warning"), format, &args, &args2);
227 va_end (args);
228 va_end (args2);
231 void
232 message_error(const char *format, ...)
234 va_list args, args2;
236 va_start (args, format);
237 va_start (args2, format);
238 message_internal(_("Error"), format, &args, &args2);
239 va_end (args);
240 va_end (args2);