/* Functions for creating and updating GTK widgets.
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
}
else
{
- wv = (widget_value *) malloc (sizeof (widget_value));
+ wv = (widget_value *) xmalloc (sizeof (widget_value));
malloc_cpt++;
}
memset (wv, 0, sizeof (widget_value));
look good in all cases. */
Lisp_Object specified_file = Qnil;
Lisp_Object tail;
+ Lisp_Object file;
extern Lisp_Object QCfile;
for (tail = XCDR (img->spec);
if (EQ (XCAR (tail), QCfile))
specified_file = XCAR (XCDR (tail));
- if (STRINGP (specified_file))
- {
- Lisp_Object file = Qnil;
- struct gcpro gcpro1;
- GCPRO1 (file);
-
- file = x_find_image_file (specified_file);
- /* We already loaded the image once before calling this
- function, so this should not fail. */
- xassert (STRINGP (file) != 0);
+ /* We already loaded the image once before calling this
+ function, so this only fails if the image file has been removed.
+ In that case, use the pixmap already loaded. */
+ if (STRINGP (specified_file)
+ && STRINGP (file = x_find_image_file (specified_file)))
+ {
if (! old_widget)
old_widget = GTK_IMAGE (gtk_image_new_from_file (SSDATA (file)));
else
gtk_image_set_from_file (old_widget, SSDATA (file));
- UNGCPRO;
return GTK_WIDGET (old_widget);
}
return gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (w));
}
+/* Callback called when the "Show hidden files" toggle is pressed.
+ WIDGET is the toggle widget, DATA is the file chooser dialog. */
+
static void
xg_toggle_visibility_cb (widget, data)
GtkWidget *widget;
{
GtkFileChooser *dialog = GTK_FILE_CHOOSER (data);
gboolean visible;
- extern int x_gtk_show_hidden_files;
g_object_get (G_OBJECT (dialog), "show-hidden", &visible, NULL);
g_object_set (G_OBJECT (dialog), "show-hidden", !visible, NULL);
- x_gtk_show_hidden_files = !visible;
+}
+
+
+/* Callback called when a property changes in a file chooser.
+ GOBJECT is the file chooser dialog, ARG1 describes the property.
+ USER_DATA is the toggle widget in the file chooser dialog.
+ We use this to update the "Show hidden files" toggle when the user
+ changes that property by right clicking in the file list. */
+
+static void
+xg_toggle_notify_cb (gobject, arg1, user_data)
+ GObject *gobject;
+ GParamSpec *arg1;
+ gpointer user_data;
+{
+ extern int x_gtk_show_hidden_files;
+
+ if (strcmp (arg1->name, "show-hidden") == 0)
+ {
+ GtkFileChooser *dialog = GTK_FILE_CHOOSER (gobject);
+ GtkWidget *wtoggle = GTK_WIDGET (user_data);
+ gboolean visible, toggle_on;
+
+ g_object_get (G_OBJECT (gobject), "show-hidden", &visible, NULL);
+ toggle_on = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wtoggle));
+
+ if (!!visible != !!toggle_on)
+ {
+ g_signal_handlers_block_by_func (G_OBJECT (wtoggle),
+ G_CALLBACK (xg_toggle_visibility_cb),
+ gobject);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wtoggle), visible);
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT (wtoggle),
+ G_CALLBACK (xg_toggle_visibility_cb),
+ gobject);
+ }
+ x_gtk_show_hidden_files = visible;
+ }
}
/* Read a file name from the user using a file chooser dialog.
}
gtk_widget_show (wtoggle);
g_signal_connect (G_OBJECT (wtoggle), "clicked",
- G_CALLBACK (xg_toggle_visibility_cb), G_OBJECT(filewin));
+ G_CALLBACK (xg_toggle_visibility_cb), filewin);
+ g_signal_connect (G_OBJECT (filewin), "notify",
+ G_CALLBACK (xg_toggle_notify_cb), wtoggle);
message[0] = '\0';
if (action != GTK_FILE_CHOOSER_ACTION_SAVE)
the GtkImage with a new image. */
#define XG_TOOL_BAR_IMAGE_DATA "emacs-tool-bar-image"
+/* The key for storing the latest modifiers so the activate callback can
+ get them. */
+#define XG_TOOL_BAR_LAST_MODIFIER "emacs-tool-bar-modifier"
+
+
/* Callback function invoked when a tool bar item is pressed.
W is the button widget in the tool bar that got pressed,
CLIENT_DATA is an integer that is the index of the button in the
tool bar. 0 is the first button. */
+static gboolean
+xg_tool_bar_button_cb (widget, event, user_data)
+ GtkWidget *widget;
+ GdkEventButton *event;
+ gpointer user_data;
+{
+ g_object_set_data (G_OBJECT (user_data), XG_TOOL_BAR_LAST_MODIFIER,
+ (gpointer) event->state);
+ return FALSE;
+}
+
+
static void
xg_tool_bar_callback (w, client_data)
GtkWidget *w;
{
/* The EMACS_INT cast avoids a warning. */
int idx = (int) (EMACS_INT) client_data;
+ int mod = (int) g_object_get_data (G_OBJECT (w), XG_TOOL_BAR_LAST_MODIFIER);
+
FRAME_PTR f = (FRAME_PTR) g_object_get_data (G_OBJECT (w), XG_FRAME_DATA);
Lisp_Object key, frame;
struct input_event event;
event.kind = TOOL_BAR_EVENT;
event.frame_or_window = frame;
event.arg = key;
- event.modifiers = 0; /* These are not available. */
+ /* Convert between the modifier bits GDK uses and the modifier bits
+ Emacs uses. This assumes GDK an X masks are the same, which they are when
+ this is written. */
+ event.modifiers = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), mod);
kbd_buffer_store_event (&event);
}
gpointer client_data;
{
FRAME_PTR f = (FRAME_PTR) client_data;
+ extern int x_gtk_whole_detached_tool_bar;
+
+ g_object_set (G_OBJECT (w), "show-arrow", !x_gtk_whole_detached_tool_bar,
+ NULL);
if (f)
{
gpointer client_data;
{
FRAME_PTR f = (FRAME_PTR) client_data;
+ g_object_set (G_OBJECT (w), "show-arrow", TRUE, NULL);
if (f)
{
Lisp_Object help, frame;
if (! GTK_IS_BUTTON (w))
- {
- return FALSE;
- }
+ return FALSE;
if (! f || ! f->n_tool_bar_items || NILP (f->tool_bar_items))
return FALSE;
if (! wicon)
{
GtkWidget *w = xg_get_image_for_pixmap (f, img, x->widget, NULL);
+ GtkToolItem *ti = gtk_tool_button_new (w, "");
gtk_misc_set_padding (GTK_MISC (w), hmargin, vmargin);
+ gtk_toolbar_insert (GTK_TOOLBAR (x->toolbar_widget),
+ ti,
+ i);
/* The EMACS_INT cast avoids a warning. */
- gtk_toolbar_append_item (GTK_TOOLBAR (x->toolbar_widget),
- 0, 0, 0,
- w,
- GTK_SIGNAL_FUNC (xg_tool_bar_callback),
- (gpointer) (EMACS_INT) i);
+ g_signal_connect (GTK_WIDGET (ti), "clicked",
+ GTK_SIGNAL_FUNC (xg_tool_bar_callback),
+ (gpointer) (EMACS_INT) i);
+
+ gtk_widget_show (GTK_WIDGET (ti));
+ gtk_widget_show (GTK_WIDGET (w));
/* Save the image so we can see if an update is needed when
this function is called again. */
g_object_set_data (G_OBJECT (w), XG_TOOL_BAR_IMAGE_DATA,
(gpointer)img->pixmap);
+ g_object_set_data (G_OBJECT (ti), XG_FRAME_DATA, (gpointer)f);
+
/* Catch expose events to overcome an annoying redraw bug, see
comment for xg_tool_bar_item_expose_callback. */
- g_signal_connect (G_OBJECT (w),
+ g_signal_connect (G_OBJECT (ti),
"expose-event",
G_CALLBACK (xg_tool_bar_item_expose_callback),
0);
- /* We must set sensitive on the button that is the parent
- of the GtkImage parent. Go upwards until we find the button. */
+ gtk_widget_set_sensitive (GTK_WIDGET (ti), enabled_p);
+ gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (ti), FALSE);
+
while (! GTK_IS_BUTTON (w))
w = gtk_widget_get_parent (w);
- if (w)
- {
- /* Save the frame in the button so the xg_tool_bar_callback
- can get at it. */
- g_object_set_data (G_OBJECT (w), XG_FRAME_DATA, (gpointer)f);
- gtk_widget_set_sensitive (w, enabled_p);
-
- /* Use enter/leave notify to show help. We use the events
- rather than the GtkButton specific signals "enter" and
- "leave", so we can have only one callback. The event
- will tell us what kind of event it is. */
- /* The EMACS_INT cast avoids a warning. */
- g_signal_connect (G_OBJECT (w),
- "enter-notify-event",
- G_CALLBACK (xg_tool_bar_help_callback),
- (gpointer) (EMACS_INT) i);
- g_signal_connect (G_OBJECT (w),
- "leave-notify-event",
- G_CALLBACK (xg_tool_bar_help_callback),
- (gpointer) (EMACS_INT) i);
- }
+ /* Callback to save modifyer mask (Shift/Control, etc). GTK makes
+ no distinction based on modifiers in the activate callback,
+ so we have to do it ourselves. */
+ g_signal_connect (w, "button-release-event",
+ GTK_SIGNAL_FUNC (xg_tool_bar_button_cb),
+ ti);
+
+ g_object_set_data (G_OBJECT (w), XG_FRAME_DATA, (gpointer)f);
+
+ /* Use enter/leave notify to show help. We use the events
+ rather than the GtkButton specific signals "enter" and
+ "leave", so we can have only one callback. The event
+ will tell us what kind of event it is. */
+ /* The EMACS_INT cast avoids a warning. */
+ g_signal_connect (G_OBJECT (w),
+ "enter-notify-event",
+ G_CALLBACK (xg_tool_bar_help_callback),
+ (gpointer) (EMACS_INT) i);
+ g_signal_connect (G_OBJECT (w),
+ "leave-notify-event",
+ G_CALLBACK (xg_tool_bar_help_callback),
+ (gpointer) (EMACS_INT) i);
}
else
{