r288: Removed the borders from the toolbar buttons and put the new help icon
[rox-filer.git] / ROX-Filer / src / gui_support.c
blobf0d3ff5503505bd53487a04bb4889af834bb9be1
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2000, Thomas Leonard, <tal197@ecs.soton.ac.uk>.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* gui_support.c - general (GUI) support routines */
24 #include "config.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/param.h>
30 #include <stdarg.h>
31 #include <errno.h>
33 #include <glib.h>
34 #include <X11/Xlib.h>
35 #include <X11/Xatom.h>
36 #include <gdk/gdk.h>
38 #include "main.h"
39 #include "gui_support.h"
40 #include "pixmaps.h"
42 GdkFont *item_font = NULL;
43 GdkFont *fixed_font = NULL;
44 GtkStyle *fixed_style = NULL;
45 gint fixed_width;
46 GdkColor red = {0, 0xffff, 0, 0};
47 GdkGC *red_gc = NULL; /* Not automatically initialised */
50 static GdkAtom xa_cardinal;
52 void gui_support_init()
54 fixed_font = gdk_font_load("fixed");
55 item_font = gtk_widget_get_default_style()->font;
57 fixed_style = gtk_style_copy(gtk_widget_get_default_style());
58 fixed_style->font = fixed_font;
60 fixed_width = gdk_string_width(fixed_font, "m");
62 xa_cardinal = gdk_atom_intern("CARDINAL", FALSE);
64 gdk_color_alloc(gtk_widget_get_default_colormap(), &red);
67 static void choice_clicked(GtkWidget *widget, gpointer number)
69 int *choice_return;
71 choice_return = gtk_object_get_data(GTK_OBJECT(widget),
72 "choice_return");
74 if (choice_return)
75 *choice_return = (int) number;
78 /* Open a modal dialog box showing a message.
79 * The user can choose from a selection of buttons at the bottom.
80 * Returns -1 if the window is destroyed, or the number of the button
81 * if one is clicked (starting from zero).
83 int get_choice(char *title,
84 char *message,
85 int number_of_buttons, ...)
87 GtkWidget *dialog;
88 GtkWidget *vbox, *action_area, *separator;
89 GtkWidget *text, *text_container;
90 GtkWidget *button = NULL;
91 int i, retval;
92 va_list ap;
93 int choice_return;
95 dialog = gtk_window_new(GTK_WINDOW_DIALOG);
96 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
97 gtk_window_set_title(GTK_WINDOW(dialog), title);
98 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
100 vbox = gtk_vbox_new(FALSE, 0);
101 gtk_container_add(GTK_CONTAINER(dialog), vbox);
103 action_area = gtk_hbox_new(TRUE, 5);
104 gtk_container_set_border_width(GTK_CONTAINER(action_area), 10);
105 gtk_box_pack_end(GTK_BOX(vbox), action_area, FALSE, TRUE, 0);
107 separator = gtk_hseparator_new ();
108 gtk_box_pack_end(GTK_BOX(vbox), separator, FALSE, TRUE, 0);
110 text = gtk_label_new(message);
111 gtk_label_set_line_wrap(GTK_LABEL(text), TRUE);
112 text_container = gtk_event_box_new();
113 gtk_container_set_border_width(GTK_CONTAINER(text_container), 32);
114 gtk_container_add(GTK_CONTAINER(text_container), text);
116 gtk_box_pack_start(GTK_BOX(vbox),
117 text_container,
118 TRUE, TRUE, 0);
120 va_start(ap, number_of_buttons);
122 for (i = 0; i < number_of_buttons; i++)
124 button = gtk_button_new_with_label(va_arg(ap, char *));
125 gtk_object_set_data(GTK_OBJECT(button), "choice_return",
126 &choice_return);
127 gtk_box_pack_start(GTK_BOX(action_area),
128 button,
129 TRUE, TRUE, 16);
130 gtk_signal_connect(GTK_OBJECT(button), "clicked",
131 choice_clicked, (gpointer) i);
132 if (i == 0)
133 gtk_window_set_focus(GTK_WINDOW(dialog), button);
135 if (!i)
136 gtk_widget_grab_focus(button);
138 va_end(ap);
140 gtk_object_set_data(GTK_OBJECT(dialog), "choice_return",
141 &choice_return);
142 gtk_signal_connect(GTK_OBJECT(dialog), "destroy", choice_clicked,
143 (gpointer) -1);
145 choice_return = -2;
147 gtk_widget_show_all(dialog);
149 while (choice_return == -2)
150 g_main_iteration(TRUE);
152 retval = choice_return;
154 if (retval != -1)
155 gtk_widget_destroy(dialog);
157 return retval;
160 /* Display a message in a window */
161 void report_error(char *title, char *message)
163 g_return_if_fail(message != NULL);
165 if (!title)
166 title = _("Error");
168 get_choice(title, message, 1, "OK");
171 void set_cardinal_property(GdkWindow *window, GdkAtom prop, guint32 value)
173 gdk_property_change(window, prop, xa_cardinal, 32,
174 GDK_PROP_MODE_REPLACE, (gchar *) &value, 1);
177 void make_panel_window(GdkWindow *window)
179 static gboolean need_init = TRUE;
180 static GdkAtom xa_state;
182 if (need_init)
184 xa_state = gdk_atom_intern("_WIN_STATE", FALSE);
185 need_init = FALSE;
188 gdk_window_set_decorations(window, 0);
189 gdk_window_set_functions(window, 0);
191 set_cardinal_property(window, xa_state,
192 WIN_STATE_STICKY | WIN_STATE_HIDDEN |
193 WIN_STATE_FIXED_POSITION | WIN_STATE_ARRANGE_IGNORE);
196 gint hide_dialog_event(GtkWidget *widget, GdkEvent *event, gpointer window)
198 gtk_widget_hide((GtkWidget *) window);
200 return TRUE;
203 static gboolean error_idle_cb(gpointer data)
205 char **error = (char **) data;
207 report_error(error[0], error[1]);
208 g_free(error[0]);
209 g_free(error[1]);
210 error[0] = error[1] = NULL;
212 if (--number_of_windows == 0)
213 gtk_main_quit();
215 return FALSE;
218 /* Display an error next time we are idle */
219 void delayed_error(char *title, char *error)
221 static char *delayed_error_data[2] = {NULL, NULL};
222 gboolean already_open;
224 g_return_if_fail(error != NULL);
226 already_open = delayed_error_data[1] != NULL;
228 g_free(delayed_error_data[0]);
229 g_free(delayed_error_data[1]);
231 delayed_error_data[0] = g_strdup(title);
232 delayed_error_data[1] = g_strdup(error);
234 if (already_open)
235 return;
237 gtk_idle_add(error_idle_cb, delayed_error_data);
239 number_of_windows++;
242 /* Load the file into memory. Return TRUE on success.
243 * Block is zero terminated (but this is not included in the length).
245 gboolean load_file(char *pathname, char **data_out, long *length_out)
247 FILE *file;
248 long length;
249 char *buffer;
250 gboolean retval = FALSE;
252 file = fopen(pathname, "r");
254 if (!file)
256 guchar *message;
258 message = g_strdup_printf("open(%s): %s",
259 pathname, g_strerror(errno));
260 delayed_error(PROJECT, message);
261 g_free(message);
262 return FALSE;
265 fseek(file, 0, SEEK_END);
266 length = ftell(file);
268 buffer = malloc(length + 1);
269 if (buffer)
271 fseek(file, 0, SEEK_SET);
272 fread(buffer, 1, length, file);
274 if (ferror(file))
276 delayed_error(_("Error reading file"),
277 g_strerror(errno));
278 g_free(buffer);
280 else
282 *data_out = buffer;
283 *length_out = length;
284 buffer[length] = '\0';
285 retval = TRUE;
288 else
289 delayed_error(PROJECT,
290 _("Can't allocate memory for buffer to "
291 "load this file"));
293 fclose(file);
295 return retval;
298 GtkWidget *new_help_button(HelpFunc show_help, gpointer data)
300 GtkWidget *b, *icon;
302 b = gtk_button_new();
303 gtk_button_set_relief(GTK_BUTTON(b), GTK_RELIEF_NONE);
304 icon = gtk_pixmap_new(im_help->pixmap, im_help->mask);
305 gtk_container_add(GTK_CONTAINER(b), icon);
306 gtk_signal_connect_object(GTK_OBJECT(b), "clicked", show_help, data);
308 GTK_WIDGET_UNSET_FLAGS(b, GTK_CAN_FOCUS);
310 return b;