/* * glade-gtk-dialog.c - GladeWidgetAdaptor for GtkDialog * * Copyright (C) 2013 Tristan Van Berkom * * Authors: * Tristan Van Berkom * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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. */ #include #include #include #include "glade-gtk-action-widgets.h" #include "glade-gtk-dialog.h" #include "glade-gtk.h" G_GNUC_BEGIN_IGNORE_DEPRECATIONS GObject * glade_gtk_dialog_construct_object (GladeWidgetAdaptor *adaptor, guint n_parameters, GParameter *parameters) { g_autofree GParameter *params = glade_gtk_get_params_without_use_header_bar (&n_parameters, parameters); return GLADE_WIDGET_ADAPTOR_GET_ADAPTOR_CLASS (GTK_TYPE_WINDOW)->construct_object (adaptor, n_parameters, params); } G_GNUC_END_IGNORE_DEPRECATIONS static void glade_gtk_stop_emission_POINTER (gpointer instance, gpointer dummy, gpointer data) { g_signal_stop_emission (instance, GPOINTER_TO_UINT (data), 0); } static void glade_gtk_dialog_stop_offending_signals (GtkWidget * widget) { static gpointer hierarchy = NULL, screen; if (hierarchy == NULL) { hierarchy = GUINT_TO_POINTER (g_signal_lookup ("hierarchy-changed", GTK_TYPE_WIDGET)); screen = GUINT_TO_POINTER (g_signal_lookup ("screen-changed", GTK_TYPE_WIDGET)); } g_signal_connect (widget, "hierarchy-changed", G_CALLBACK (glade_gtk_stop_emission_POINTER), hierarchy); g_signal_connect (widget, "screen-changed", G_CALLBACK (glade_gtk_stop_emission_POINTER), screen); } static void glade_gtk_file_chooser_forall (GtkWidget * widget, gpointer data) { /* GtkFileChooserWidget packs a GtkFileChooserDefault */ if (GTK_IS_FILE_CHOOSER_WIDGET (widget)) gtk_container_forall (GTK_CONTAINER (widget), glade_gtk_file_chooser_default_forall, NULL); } void glade_gtk_dialog_post_create (GladeWidgetAdaptor *adaptor, GObject *object, GladeCreateReason reason) { GladeWidget *widget, *vbox_widget, *actionarea_widget; GtkDialog *dialog; /* Chain Up first */ GLADE_WIDGET_ADAPTOR_GET_ADAPTOR_CLASS (GTK_TYPE_WINDOW)->post_create (adaptor, object, reason); g_return_if_fail (GTK_IS_DIALOG (object)); widget = glade_widget_get_from_gobject (GTK_WIDGET (object)); if (!widget) return; dialog = GTK_DIALOG (object); if (reason == GLADE_CREATE_USER) { /* HIG compliant border-width defaults on dialogs */ glade_widget_property_set (widget, "border-width", 5); } vbox_widget = glade_widget_get_from_gobject (gtk_dialog_get_content_area (dialog)); G_GNUC_BEGIN_IGNORE_DEPRECATIONS actionarea_widget = glade_widget_get_from_gobject (gtk_dialog_get_action_area (dialog)); G_GNUC_END_IGNORE_DEPRECATIONS /* We need to stop default emissions of "hierarchy-changed" and * "screen-changed" of GtkFileChooserDefault to avoid an abort() * when doing a reparent. * GtkFileChooserDialog packs a GtkFileChooserWidget in * his internal vbox. */ if (GTK_IS_FILE_CHOOSER_DIALOG (object)) gtk_container_forall (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), glade_gtk_file_chooser_forall, NULL); /* These properties are controlled by the GtkDialog style properties: * "content-area-border", "button-spacing" and "action-area-border", * so we must disable their use. */ glade_widget_remove_property (vbox_widget, "border-width"); glade_widget_remove_property (actionarea_widget, "border-width"); glade_widget_remove_property (actionarea_widget, "spacing"); if (reason == GLADE_CREATE_LOAD || reason == GLADE_CREATE_USER) { GObject *child; gint size; G_GNUC_BEGIN_IGNORE_DEPRECATIONS; if (GTK_IS_COLOR_SELECTION_DIALOG (object)) { child = glade_widget_adaptor_get_internal_child (adaptor, object, "color_selection"); size = 1; } else if (GTK_IS_FONT_SELECTION_DIALOG (object)) { child = glade_widget_adaptor_get_internal_child (adaptor, object, "font_selection"); size = 2; } else size = -1; G_GNUC_END_IGNORE_DEPRECATIONS; /* Set this to a sane value. At load time, if there are any children then * size will adjust appropriately (otherwise the default "3" gets * set and we end up with extra placeholders). */ if (size > -1) glade_widget_property_set (glade_widget_get_from_gobject (child), "size", size); } /* Only set these on the original create. */ if (reason == GLADE_CREATE_USER) { /* HIG compliant spacing defaults on dialogs */ glade_widget_property_set (vbox_widget, "spacing", 2); if (GTK_IS_ABOUT_DIALOG (object) || GTK_IS_FILE_CHOOSER_DIALOG (object)) glade_widget_property_set (vbox_widget, "size", 3); else glade_widget_property_set (vbox_widget, "size", 2); glade_widget_property_set (actionarea_widget, "size", 2); glade_widget_property_set (actionarea_widget, "layout-style", GTK_BUTTONBOX_END); } } void glade_gtk_dialog_read_child (GladeWidgetAdaptor * adaptor, GladeWidget * widget, GladeXmlNode * node) { GLADE_WIDGET_ADAPTOR_GET_ADAPTOR_CLASS (GTK_TYPE_CONTAINER)->read_child (adaptor, widget, node); node = glade_xml_node_get_parent (node); glade_gtk_action_widgets_read_child (widget, node, "action_area"); } void glade_gtk_dialog_write_child (GladeWidgetAdaptor * adaptor, GladeWidget * widget, GladeXmlContext * context, GladeXmlNode * node) { GladeWidget *parent = glade_widget_get_parent (widget); /* Before writing out the children, force any response id carrying buttons * to have a name. * * This is NOT correct, but is an exception, we force the buttons to have * names in a non-undoable way at save time for the purpose of action widgets * only. */ glade_gtk_action_widgets_ensure_names (parent, "action_area"); GLADE_WIDGET_ADAPTOR_GET_ADAPTOR_CLASS (GTK_TYPE_CONTAINER)->write_child (adaptor, widget, context, node); if (parent && GTK_IS_DIALOG (glade_widget_get_object (parent))) glade_gtk_action_widgets_write_child (parent, context, node, "action_area"); } /* Shared with file chooser widget */ void glade_gtk_file_chooser_default_forall (GtkWidget * widget, gpointer data) { /* Since GtkFileChooserDefault is not exposed we check if its a * GtkFileChooser */ if (GTK_IS_FILE_CHOOSER (widget)) { /* Finally we can connect to the signals we want to stop its * default handler. Since both signals has the same signature * we use one callback for both :) */ glade_gtk_dialog_stop_offending_signals (widget); } }