summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2009-06-17 12:56:05 +0200
committerAlexander Larsson <alexl@redhat.com>2009-06-17 12:56:05 +0200
commit7303f3c9fdc2fcb75907a3fd81cc4a44446931a7 (patch)
tree7607ea832b4c8ddb1f61240b7ca43299f9f67e6e /gtk
parentc08bf93fe5fd0f7192aec9ad0358da246c211e0f (diff)
parent1a385c50f041cdcc8ee88b27af85094901c2b05d (diff)
downloadgtk+-7303f3c9fdc2fcb75907a3fd81cc4a44446931a7.tar.gz
Merge branch 'master' into client-side-windows
This updates client-side-windows to the the latest soname change for easier testing. Conflicts: gdk/x11/gdkwindow-x11.c tests/Makefile.am
Diffstat (limited to 'gtk')
-rw-r--r--gtk/Makefile.am2
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtk.symbols31
-rw-r--r--gtk/gtkaboutdialog.c2
-rw-r--r--gtk/gtkactivatable.c4
-rw-r--r--gtk/gtkassistant.c34
-rw-r--r--gtk/gtkbbox.c349
-rw-r--r--gtk/gtkbuilderparser.c36
-rw-r--r--gtk/gtkcellrendererpixbuf.c155
-rw-r--r--gtk/gtkcellview.c4
-rw-r--r--gtk/gtkcellview.h2
-rw-r--r--gtk/gtkcombobox.c6
-rw-r--r--gtk/gtkdnd.c146
-rw-r--r--gtk/gtkentry.c5
-rw-r--r--gtk/gtkentrycompletion.c10
-rw-r--r--gtk/gtkenums.h12
-rw-r--r--gtk/gtkfilechooserdefault.c304
-rw-r--r--gtk/gtkfilechooserprivate.h6
-rw-r--r--gtk/gtkfilechoosersettings.c125
-rw-r--r--gtk/gtkfilechoosersettings.h19
-rw-r--r--gtk/gtkfilesystemmodel.c3
-rw-r--r--gtk/gtkfontsel.c2
-rw-r--r--gtk/gtkhandlebox.c3
-rw-r--r--gtk/gtkhbbox.c196
-rw-r--r--gtk/gtkiconview.c6
-rw-r--r--gtk/gtkinfobar.c1263
-rw-r--r--gtk/gtkinfobar.h116
-rw-r--r--gtk/gtkmessagedialog.h10
-rw-r--r--gtk/gtkpathbar.c106
-rw-r--r--gtk/gtkprintoperation-private.h2
-rw-r--r--gtk/gtkprintoperation-unix.c6
-rw-r--r--gtk/gtkprintoperation.c132
-rw-r--r--gtk/gtkprintoperation.h6
-rw-r--r--gtk/gtkprintsettings.c6
-rw-r--r--gtk/gtkprintunixdialog.c241
-rw-r--r--gtk/gtkprintunixdialog.h7
-rw-r--r--gtk/gtkrecentmanager.c7
-rw-r--r--gtk/gtkrecentmanager.h2
-rw-r--r--gtk/gtkstatusicon.c3
-rw-r--r--gtk/gtkstock.c2
-rw-r--r--gtk/gtktreeprivate.h2
-rw-r--r--gtk/gtktreeview.c45
-rw-r--r--gtk/gtktreeviewcolumn.c2
-rw-r--r--gtk/gtktreeviewcolumn.h2
-rw-r--r--gtk/gtkvbbox.c195
-rw-r--r--gtk/tests/builder.c55
-rw-r--r--gtk/tests/treeview-scrolling.c2
-rw-r--r--gtk/updateiconcache.c2
48 files changed, 2980 insertions, 697 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index d80dc7f56a..6d7a03865d 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -230,6 +230,7 @@ gtk_public_h_sources = \
gtkimcontextsimple.h \
gtkimmodule.h \
gtkimmulticontext.h \
+ gtkinfobar.h \
gtkinputdialog.h \
gtkinvisible.h \
gtkitem.h \
@@ -486,6 +487,7 @@ gtk_base_c_sources = \
gtkimcontextsimple.c \
gtkimmodule.c \
gtkimmulticontext.c \
+ gtkinfobar.c \
gtkinputdialog.c \
gtkinvisible.c \
gtkitem.c \
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 7b9b765e08..b91a6badf5 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -110,6 +110,7 @@
#include <gtk/gtkimcontext.h>
#include <gtk/gtkimcontextsimple.h>
#include <gtk/gtkimmulticontext.h>
+#include <gtk/gtkinfobar.h>
#include <gtk/gtkinputdialog.h>
#include <gtk/gtkinvisible.h>
#include <gtk/gtkitem.h>
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index d9ddbf8691..ac4fa2cf72 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -690,7 +690,9 @@ gtk_cell_renderer_toggle_set_radio
#if IN_HEADER(__GTK_CELL_VIEW_H__)
#if IN_FILE(__GTK_CELL_VIEW_C__)
+#ifndef GTK_DISABLE_DEPRECATED
gtk_cell_view_get_cell_renderers
+#endif
gtk_cell_view_get_displayed_row
gtk_cell_view_get_model
gtk_cell_view_get_size_of_row
@@ -2986,6 +2988,10 @@ gtk_print_operation_is_finished
gtk_print_operation_cancel
gtk_print_operation_draw_page_finish
gtk_print_operation_set_defer_drawing
+gtk_print_operation_set_support_selection
+gtk_print_operation_get_support_selection
+gtk_print_operation_set_has_selection
+gtk_print_operation_get_has_selection
#endif
#endif
@@ -3110,6 +3116,11 @@ gtk_print_unix_dialog_get_settings
gtk_print_unix_dialog_get_selected_printer
gtk_print_unix_dialog_add_custom_tab
gtk_print_unix_dialog_set_manual_capabilities
+gtk_print_unix_dialog_get_manual_capabilities
+gtk_print_unix_dialog_set_support_selection
+gtk_print_unix_dialog_get_support_selection
+gtk_print_unix_dialog_set_has_selection
+gtk_print_unix_dialog_get_has_selection
#endif
#endif
#endif
@@ -4593,7 +4604,9 @@ gtk_tree_view_column_clear_attributes
gtk_tree_view_column_clicked
gtk_tree_view_column_focus_cell
gtk_tree_view_column_get_alignment
+#ifndef GTK_DISABLE_DEPRECATED
gtk_tree_view_column_get_cell_renderers
+#endif
gtk_tree_view_column_get_clickable
gtk_tree_view_column_get_expand
gtk_tree_view_column_get_fixed_width
@@ -5155,6 +5168,24 @@ gtk_win32_embed_widget_get_type G_GNUC_CONST
#endif
#endif
+#if IN_HEADER(__GTK_INFO_BAR_H__)
+#if IN_FILE(__GTK_INFO_BAR_C__)
+gtk_info_bar_get_type G_GNUC_CONST
+gtk_info_bar_new
+gtk_info_bar_new_with_buttons
+gtk_info_bar_get_action_area
+gtk_info_bar_get_content_area
+gtk_info_bar_add_action_widget
+gtk_info_bar_add_button
+gtk_info_bar_add_buttons
+gtk_info_bar_set_response_sensitive
+gtk_info_bar_set_default_response
+gtk_info_bar_response
+gtk_info_bar_set_message_type
+gtk_info_bar_get_message_type
+#endif
+#endif
+
#ifdef INCLUDE_VARIABLES
gtk_binary_age
gtk_interface_age
diff --git a/gtk/gtkaboutdialog.c b/gtk/gtkaboutdialog.c
index b073c98228..91d30fe344 100644
--- a/gtk/gtkaboutdialog.c
+++ b/gtk/gtkaboutdialog.c
@@ -2303,7 +2303,7 @@ gtk_about_dialog_set_email_hook (GtkAboutDialogActivateLinkFunc func,
* Installs a global function to be called whenever the user activates a
* URL link in an about dialog.
*
- * Since 2.18 here exists a default function which uses gtk_show_uri(). To
+ * Since 2.18 there exists a default function which uses gtk_show_uri(). To
* deactivate it, you can pass %NULL for @func.
*
* Return value: the previous URL hook.
diff --git a/gtk/gtkactivatable.c b/gtk/gtkactivatable.c
index 8e1483726c..65c166b87e 100644
--- a/gtk/gtkactivatable.c
+++ b/gtk/gtkactivatable.c
@@ -449,7 +449,7 @@ gtk_activatable_do_set_related_action (GtkActivatable *activatable,
/* Some apps are using the object data directly...
* so continue to set it for a bit longer
*/
- g_object_set_data (activatable, "gtk-action", NULL);
+ g_object_set_data (G_OBJECT (activatable), "gtk-action", NULL);
/*
* We don't want prev_action to be activated
@@ -478,7 +478,7 @@ gtk_activatable_do_set_related_action (GtkActivatable *activatable,
_gtk_action_add_to_proxy_list (action, GTK_WIDGET (activatable));
- g_object_set_data (activatable, "gtk-action", action);
+ g_object_set_data (G_OBJECT (activatable), "gtk-action", action);
}
}
}
diff --git a/gtk/gtkassistant.c b/gtk/gtkassistant.c
index 4e8f155aea..b7ed75641d 100644
--- a/gtk/gtkassistant.c
+++ b/gtk/gtkassistant.c
@@ -217,7 +217,7 @@ gtk_assistant_class_init (GtkAssistantClass *class)
* @assistant: the #GtkAssistant
* @page: the current page
*
- * The ::prepared signal is emitted when a new page is set as the assistant's
+ * The ::prepare signal is emitted when a new page is set as the assistant's
* current page, before making the new page visible. A handler for this signal
* can do any preparation which are necessary before showing @page.
*
@@ -237,14 +237,14 @@ gtk_assistant_class_init (GtkAssistantClass *class)
* @assistant: the @GtkAssistant
*
* The ::apply signal is emitted when the apply button is clicked. The default
- * behavior of the #GtkAssistant is to switch to the page after the current page,
- * unless the current page is the last one.
+ * behavior of the #GtkAssistant is to switch to the page after the current
+ * page, unless the current page is the last one.
*
- * A handler for the ::apply signal should carry out the actions for which the
- * wizard has collected data. If the action takes a long time to complete, you
- * might consider to put a page of type GTK_ASSISTANT_PAGE_PROGRESS after the
- * confirmation page and handle this operation within the ::prepare signal of
- * the progress page.
+ * A handler for the ::apply signal should carry out the actions for which
+ * the wizard has collected data. If the action takes a long time to complete,
+ * you might consider to put a page of type %GTK_ASSISTANT_PAGE_PROGRESS
+ * after the confirmation page and handle this operation within the
+ * #GtkAssistant::prepare signal of the progress page.
*
* Since: 2.10
*/
@@ -263,7 +263,7 @@ gtk_assistant_class_init (GtkAssistantClass *class)
*
* The ::close signal is emitted either when the close button of
* a summary page is clicked, or when the apply button in the last
- * page in the flow (of type GTK_ASSISTANT_PAGE_CONFIRM) is clicked.
+ * page in the flow (of type %GTK_ASSISTANT_PAGE_CONFIRM) is clicked.
*
* Since: 2.10
*/
@@ -296,7 +296,7 @@ gtk_assistant_class_init (GtkAssistantClass *class)
/**
* GtkAssistant:page-type:
*
- * The type of the assistant page.
+ * The type of the assistant page.
*
* Since: 2.10
*/
@@ -312,7 +312,7 @@ gtk_assistant_class_init (GtkAssistantClass *class)
/**
* GtkAssistant:title:
*
- * The title that is displayed in the page header.
+ * The title that is displayed in the page header.
*
* If title and header-image are both %NULL, no header is displayed.
*
@@ -346,7 +346,7 @@ gtk_assistant_class_init (GtkAssistantClass *class)
/**
* GtkAssistant:header-image:
*
- * The image that is displayed next to the page.
+ * The image that is displayed next to the page.
*
* Set this to %NULL to make the sidebar disappear.
*
@@ -430,14 +430,12 @@ compute_last_button_state (GtkAssistant *assistant)
page_info = g_list_nth_data (priv->pages, page_num);
count++;
-
- g_assert (page_info);
}
/* make the last button visible if we can skip multiple
- * pages and end on a confirmation or summary page
+ * pages and end on a confirmation or summary page
*/
- if (count > 1 &&
+ if (count > 1 && page_info &&
(page_info->type == GTK_ASSISTANT_PAGE_CONFIRM ||
page_info->type == GTK_ASSISTANT_PAGE_SUMMARY))
{
@@ -2174,7 +2172,7 @@ gtk_assistant_set_page_complete (GtkAssistant *assistant,
* @assistant: a #GtkAssistant
* @page: a page of @assistant
*
- * Gets whether @page is complete..
+ * Gets whether @page is complete.
*
* Return value: %TRUE if @page is complete.
*
@@ -2267,7 +2265,7 @@ gtk_assistant_accessible_ref_child (AtkObject *accessible,
return NULL;
else if (index < n_pages)
{
- GtkAssistantPage *page = g_list_nth_data (priv->pages, index / 2);
+ GtkAssistantPage *page = g_list_nth_data (priv->pages, index);
child = page->page;
title = gtk_assistant_get_page_title (assistant, child);
diff --git a/gtk/gtkbbox.c b/gtk/gtkbbox.c
index 609e45dc33..b2a0acf922 100644
--- a/gtk/gtkbbox.c
+++ b/gtk/gtkbbox.c
@@ -26,6 +26,7 @@
#include "config.h"
#include "gtkbbox.h"
+#include "gtkorientable.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "gtkalias.h"
@@ -48,6 +49,10 @@ static void gtk_button_box_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
+static void gtk_button_box_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void gtk_button_box_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
static void gtk_button_box_set_child_property (GtkContainer *container,
GtkWidget *child,
guint property_id,
@@ -80,6 +85,9 @@ gtk_button_box_class_init (GtkButtonBoxClass *class)
gobject_class->set_property = gtk_button_box_set_property;
gobject_class->get_property = gtk_button_box_get_property;
+ widget_class->size_request = gtk_button_box_size_request;
+ widget_class->size_allocate = gtk_button_box_size_allocate;
+
container_class->set_child_property = gtk_button_box_set_child_property;
container_class->get_child_property = gtk_button_box_get_child_property;
@@ -471,5 +479,346 @@ _gtk_button_box_child_requisition (GtkWidget *widget,
*height = needed_height;
}
+/* this is a kludge function to support the deprecated
+ * gtk_[vh]button_box_set_layout_default() just in case anyone is still
+ * using it (why?)
+ */
+static GtkButtonBoxStyle
+gtk_button_box_kludge_get_layout_default (GtkButtonBox *widget)
+{
+ GtkOrientation orientation;
+
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ return gtk_hbutton_box_get_layout_default ();
+ else
+ return gtk_vbutton_box_get_layout_default ();
+}
+
+static void
+gtk_button_box_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GtkBox *box;
+ GtkButtonBox *bbox;
+ gint nvis_children;
+ gint child_width;
+ gint child_height;
+ gint spacing;
+ GtkButtonBoxStyle layout;
+ GtkOrientation orientation;
+
+ box = GTK_BOX (widget);
+ bbox = GTK_BUTTON_BOX (widget);
+
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
+ spacing = box->spacing;
+ layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
+ ? bbox->layout_style : gtk_button_box_kludge_get_layout_default (GTK_BUTTON_BOX (widget));
+
+ _gtk_button_box_child_requisition (widget,
+ &nvis_children,
+ NULL,
+ &child_width,
+ &child_height);
+
+ if (nvis_children == 0)
+ {
+ requisition->width = 0;
+ requisition->height = 0;
+ }
+ else
+ {
+ switch (layout)
+ {
+ case GTK_BUTTONBOX_SPREAD:
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ requisition->width =
+ nvis_children*child_width + ((nvis_children+1)*spacing);
+ else
+ requisition->height =
+ nvis_children*child_height + ((nvis_children+1)*spacing);
+
+ break;
+ case GTK_BUTTONBOX_EDGE:
+ case GTK_BUTTONBOX_START:
+ case GTK_BUTTONBOX_END:
+ case GTK_BUTTONBOX_CENTER:
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ requisition->width =
+ nvis_children*child_width + ((nvis_children-1)*spacing);
+ else
+ requisition->height =
+ nvis_children*child_height + ((nvis_children-1)*spacing);
+
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ requisition->height = child_height;
+ }
+ else
+ {
+ requisition->width = child_width;
+ }
+ }
+
+ requisition->width += GTK_CONTAINER (box)->border_width * 2;
+ requisition->height += GTK_CONTAINER (box)->border_width * 2;
+}
+
+static void
+gtk_button_box_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkBox *base_box;
+ GtkButtonBox *box;
+ GtkBoxChild *child;
+ GList *children;
+ GtkAllocation child_allocation;
+ gint nvis_children;
+ gint n_secondaries;
+ gint child_width;
+ gint child_height;
+ gint x = 0;
+ gint y = 0;
+ gint secondary_x = 0;
+ gint secondary_y = 0;
+ gint width;
+ gint height;
+ gint childspace;
+ gint childspacing = 0;
+ GtkButtonBoxStyle layout;
+ gint spacing;
+ GtkOrientation orientation;
+
+ orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
+ base_box = GTK_BOX (widget);
+ box = GTK_BUTTON_BOX (widget);
+ spacing = base_box->spacing;
+ layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
+ ? box->layout_style : gtk_button_box_kludge_get_layout_default (GTK_BUTTON_BOX (widget));
+ _gtk_button_box_child_requisition (widget,
+ &nvis_children,
+ &n_secondaries,
+ &child_width,
+ &child_height);
+ widget->allocation = *allocation;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ width = allocation->width - GTK_CONTAINER (box)->border_width*2;
+ else
+ height = allocation->height - GTK_CONTAINER (box)->border_width*2;
+
+ switch (layout)
+ {
+ case GTK_BUTTONBOX_SPREAD:
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ childspacing = (width - (nvis_children * child_width))
+ / (nvis_children + 1);
+ x = allocation->x + GTK_CONTAINER (box)->border_width
+ + childspacing;
+ secondary_x = x + ((nvis_children - n_secondaries)
+ * (child_width + childspacing));
+ }
+ else
+ {
+ childspacing = (height - (nvis_children * child_height))
+ / (nvis_children + 1);
+ y = allocation->y + GTK_CONTAINER (box)->border_width
+ + childspacing;
+ secondary_y = y + ((nvis_children - n_secondaries)
+ * (child_height + childspacing));
+ }
+
+ break;
+
+ case GTK_BUTTONBOX_EDGE:
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (nvis_children >= 2)
+ {
+ childspacing = (width - (nvis_children * child_width))
+ / (nvis_children - 1);
+ x = allocation->x + GTK_CONTAINER (box)->border_width;
+ secondary_x = x + ((nvis_children - n_secondaries)
+ * (child_width + childspacing));
+ }
+ else
+ {
+ /* one or zero children, just center */
+ childspacing = width;
+ x = secondary_x = allocation->x
+ + (allocation->width - child_width) / 2;
+ }
+ }
+ else
+ {
+ if (nvis_children >= 2)
+ {
+ childspacing = (height - (nvis_children*child_height))
+ / (nvis_children-1);
+ y = allocation->y + GTK_CONTAINER (box)->border_width;
+ secondary_y = y + ((nvis_children - n_secondaries)
+ * (child_height + childspacing));
+ }
+ else
+ {
+ /* one or zero children, just center */
+ childspacing = height;
+ y = secondary_y = allocation->y
+ + (allocation->height - child_height) / 2;
+ }
+ }
+
+ break;
+
+ case GTK_BUTTONBOX_START:
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ childspacing = spacing;
+ x = allocation->x + GTK_CONTAINER (box)->border_width;
+ secondary_x = allocation->x + allocation->width
+ - child_width * n_secondaries
+ - spacing * (n_secondaries - 1)
+ - GTK_CONTAINER (box)->border_width;
+ }
+ else
+ {
+ childspacing = spacing;
+ y = allocation->y + GTK_CONTAINER (box)->border_width;
+ secondary_y = allocation->y + allocation->height
+ - child_height * n_secondaries
+ - spacing * (n_secondaries - 1)
+ - GTK_CONTAINER (box)->border_width;
+ }
+
+ break;
+
+ case GTK_BUTTONBOX_END:
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ childspacing = spacing;
+ x = allocation->x + allocation->width
+ - child_width * (nvis_children - n_secondaries)
+ - spacing * (nvis_children - n_secondaries - 1)
+ - GTK_CONTAINER (box)->border_width;
+ secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
+ }
+ else
+ {
+ childspacing = spacing;
+ y = allocation->y + allocation->height
+ - child_height * (nvis_children - n_secondaries)
+ - spacing * (nvis_children - n_secondaries - 1)
+ - GTK_CONTAINER (box)->border_width;
+ secondary_y = allocation->y + GTK_CONTAINER (box)->border_width;
+ }
+
+ break;
+
+ case GTK_BUTTONBOX_CENTER:
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ childspacing = spacing;
+ x = allocation->x +
+ (allocation->width
+ - (child_width * (nvis_children - n_secondaries)
+ + spacing * (nvis_children - n_secondaries - 1)))/2
+ + (n_secondaries * child_width + n_secondaries * spacing)/2;
+ secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
+ }
+ else
+ {
+ childspacing = spacing;
+ y = allocation->y +
+ (allocation->height
+ - (child_height * (nvis_children - n_secondaries)
+ + spacing * (nvis_children - n_secondaries - 1)))/2
+ + (n_secondaries * child_height + n_secondaries * spacing)/2;
+ secondary_y = allocation->y + GTK_CONTAINER (box)->border_width;
+ }
+
+ break;
+
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ y = allocation->y + (allocation->height - child_height) / 2;
+ childspace = child_width + childspacing;
+ }
+ else
+ {
+ x = allocation->x + (allocation->width - child_width) / 2;
+ childspace = child_height + childspacing;
+ }
+
+ children = GTK_BOX (box)->children;
+
+ while (children)
+ {
+ child = children->data;
+ children = children->next;
+
+ if (GTK_WIDGET_VISIBLE (child->widget))
+ {
+ child_allocation.width = child_width;
+ child_allocation.height = child_height;
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ child_allocation.y = y;
+
+ if (child->is_secondary)
+ {
+ child_allocation.x = secondary_x;
+ secondary_x += childspace;
+ }
+ else
+ {
+ child_allocation.x = x;
+ x += childspace;
+ }
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ child_allocation.x = (allocation->x + allocation->width)
+ - (child_allocation.x + child_width - allocation->x);
+ }
+ else
+ {
+ child_allocation.x = x;
+
+ if (child->is_secondary)
+ {
+ child_allocation.y = secondary_y;
+ secondary_y += childspace;
+ }
+ else
+ {
+ child_allocation.y = y;
+ y += childspace;
+ }
+ }
+
+ gtk_widget_size_allocate (child->widget, &child_allocation);
+ }
+ }
+}
+
#define __GTK_BUTTON_BOX_C__
#include "gtkaliasdef.c"
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index c5cb2d8938..f6f12a5bf6 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -893,40 +893,6 @@ start_element (GMarkupParseContext *context,
element_name);
}
-/* This function is taken from gettext.h
- * GNU gettext uses '\004' to separate context and msgid in .mo files.
- */
-static const char *
-_dpgettext (const char *domain,
- const char *msgctxt,
- const char *msgid)
-{
- size_t msgctxt_len = strlen (msgctxt) + 1;
- size_t msgid_len = strlen (msgid) + 1;
- const char *translation;
- char* msg_ctxt_id;
-
- msg_ctxt_id = g_alloca (msgctxt_len + msgid_len);
-
- memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
- msg_ctxt_id[msgctxt_len - 1] = '\004';
- memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
-
- translation = g_dgettext (domain, msg_ctxt_id);
-
- if (translation == msg_ctxt_id)
- {
- /* try the old way of doing message contexts, too */
- msg_ctxt_id[msgctxt_len - 1] = '|';
- translation = g_dgettext (domain, msg_ctxt_id);
-
- if (translation == msg_ctxt_id)
- return msgid;
- }
-
- return translation;
-}
-
gchar *
_gtk_builder_parser_translate (const gchar *domain,
const gchar *context,
@@ -935,7 +901,7 @@ _gtk_builder_parser_translate (const gchar *domain,
const char *s;
if (context)
- s = _dpgettext (domain, context, text);
+ s = g_dpgettext2 (domain, context, text);
else
s = g_dgettext (domain, text);
diff --git a/gtk/gtkcellrendererpixbuf.c b/gtk/gtkcellrendererpixbuf.c
index 0431295e41..c0ec609688 100644
--- a/gtk/gtkcellrendererpixbuf.c
+++ b/gtk/gtkcellrendererpixbuf.c
@@ -284,39 +284,6 @@ gtk_cell_renderer_pixbuf_get_property (GObject *object,
}
static void
-unset_image_properties (GtkCellRendererPixbuf *cell)
-{
- GtkCellRendererPixbufPrivate *priv;
-
- priv = GTK_CELL_RENDERER_PIXBUF_GET_PRIVATE (cell);
-
- if (priv->stock_id)
- {
- g_free (priv->stock_id);
- priv->stock_id = NULL;
- g_object_notify (G_OBJECT (cell), "stock-id");
- }
- if (priv->icon_name)
- {
- g_free (priv->icon_name);
- priv->icon_name = NULL;
- g_object_notify (G_OBJECT (cell), "icon-name");
- }
- if (cell->pixbuf)
- {
- g_object_unref (cell->pixbuf);
- cell->pixbuf = NULL;
- g_object_notify (G_OBJECT (cell), "pixbuf");
- }
- if (priv->gicon)
- {
- g_object_unref (priv->gicon);
- priv->gicon = NULL;
- g_object_notify (G_OBJECT (cell), "gicon");
- }
-}
-
-static void
gtk_cell_renderer_pixbuf_set_property (GObject *object,
guint param_id,
const GValue *value,
@@ -330,8 +297,30 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object,
switch (param_id)
{
case PROP_PIXBUF:
- unset_image_properties (cellpixbuf);
- cellpixbuf->pixbuf = (GdkPixbuf *) g_value_dup_object (value);
+ if (cellpixbuf->pixbuf)
+ g_object_unref (cellpixbuf->pixbuf);
+ cellpixbuf->pixbuf = (GdkPixbuf*) g_value_dup_object (value);
+ if (cellpixbuf->pixbuf)
+ {
+ if (priv->stock_id)
+ {
+ g_free (priv->stock_id);
+ priv->stock_id = NULL;
+ g_object_notify (object, "stock-id");
+ }
+ if (priv->icon_name)
+ {
+ g_free (priv->icon_name);
+ priv->icon_name = NULL;
+ g_object_notify (object, "icon-name");
+ }
+ if (priv->gicon)
+ {
+ g_object_unref (priv->gicon);
+ priv->gicon = NULL;
+ g_object_notify (object, "gicon");
+ }
+ }
break;
case PROP_PIXBUF_EXPANDER_OPEN:
if (cellpixbuf->pixbuf_expander_open)
@@ -344,8 +333,38 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object,
cellpixbuf->pixbuf_expander_closed = (GdkPixbuf*) g_value_dup_object (value);
break;
case PROP_STOCK_ID:
- unset_image_properties (cellpixbuf);
+ if (priv->stock_id)
+ {
+ if (cellpixbuf->pixbuf)
+ {
+ g_object_unref (cellpixbuf->pixbuf);
+ cellpixbuf->pixbuf = NULL;
+ g_object_notify (object, "pixbuf");
+ }
+ g_free (priv->stock_id);
+ }
priv->stock_id = g_value_dup_string (value);
+ if (priv->stock_id)
+ {
+ if (cellpixbuf->pixbuf)
+ {
+ g_object_unref (cellpixbuf->pixbuf);
+ cellpixbuf->pixbuf = NULL;
+ g_object_notify (object, "pixbuf");
+ }
+ if (priv->icon_name)
+ {
+ g_free (priv->icon_name);
+ priv->icon_name = NULL;
+ g_object_notify (object, "icon-name");
+ }
+ if (priv->gicon)
+ {
+ g_object_unref (priv->gicon);
+ priv->gicon = NULL;
+ g_object_notify (object, "gicon");
+ }
+ }
break;
case PROP_STOCK_SIZE:
priv->stock_size = g_value_get_uint (value);
@@ -355,15 +374,75 @@ gtk_cell_renderer_pixbuf_set_property (GObject *object,
priv->stock_detail = g_value_dup_string (value);
break;
case PROP_ICON_NAME:
- unset_image_properties (cellpixbuf);
+ if (priv->icon_name)
+ {
+ if (cellpixbuf->pixbuf)
+ {
+ g_object_unref (cellpixbuf->pixbuf);
+ cellpixbuf->pixbuf = NULL;
+ g_object_notify (object, "pixbuf");
+ }
+ g_free (priv->icon_name);
+ }
priv->icon_name = g_value_dup_string (value);
+ if (priv->icon_name)
+ {
+ if (cellpixbuf->pixbuf)
+ {
+ g_object_unref (cellpixbuf->pixbuf);
+ cellpixbuf->pixbuf = NULL;
+ g_object_notify (object, "pixbuf");
+ }
+ if (priv->stock_id)
+ {
+ g_free (priv->stock_id);
+ priv->stock_id = NULL;
+ g_object_notify (object, "stock-id");
+ }
+ if (priv->gicon)
+ {
+ g_object_unref (priv->gicon);
+ priv->gicon = NULL;
+ g_object_notify (object, "gicon");
+ }
+ }
break;
case PROP_FOLLOW_STATE:
priv->follow_state = g_value_get_boolean (value);
break;
case PROP_GICON:
- unset_image_properties (cellpixbuf);
+ if (priv->gicon)
+ {
+ if (cellpixbuf->pixbuf)
+ {
+ g_object_unref (cellpixbuf->pixbuf);
+ cellpixbuf->pixbuf = NULL;
+ g_object_notify (object, "pixbuf");
+ }
+ g_object_unref (priv->gicon);
+ }
priv->gicon = (GIcon *) g_value_dup_object (value);
+ if (priv->gicon)
+ {
+ if (cellpixbuf->pixbuf)
+ {
+ g_object_unref (cellpixbuf->pixbuf);
+ cellpixbuf->pixbuf = NULL;
+ g_object_notify (object, "pixbuf");
+ }
+ if (priv->stock_id)
+ {
+ g_free (priv->stock_id);
+ priv->stock_id = NULL;
+ g_object_notify (object, "stock-id");
+ }
+ if (priv->icon_name)
+ {
+ g_free (priv->icon_name);
+ priv->icon_name = NULL;
+ g_object_notify (object, "icon-name");
+ }
+ }
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c
index 43cdce1cc1..6add539de8 100644
--- a/gtk/gtkcellview.c
+++ b/gtk/gtkcellview.c
@@ -1053,7 +1053,9 @@ gtk_cell_view_set_background_color (GtkCellView *cell_view,
* g_list_free() when no longer needed.
*
* Since: 2.6
- */
+ *
+ * Deprecated: 2.18: use gtk_cell_layout_get_cells() instead.
+ **/
GList *
gtk_cell_view_get_cell_renderers (GtkCellView *cell_view)
{
diff --git a/gtk/gtkcellview.h b/gtk/gtkcellview.h
index c07f24960c..73de84e191 100644
--- a/gtk/gtkcellview.h
+++ b/gtk/gtkcellview.h
@@ -72,7 +72,9 @@ gboolean gtk_cell_view_get_size_of_row (GtkCellView *cell_v
void gtk_cell_view_set_background_color (GtkCellView *cell_view,
const GdkColor *color);
+#ifndef GTK_DISABLE_DEPRECATED
GList *gtk_cell_view_get_cell_renderers (GtkCellView *cell_view);
+#endif
G_END_DECLS
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index 1628789a55..3e6fbefc18 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -1701,7 +1701,7 @@ cell_view_is_sensitive (GtkCellView *cell_view)
GList *cells, *list;
gboolean sensitive;
- cells = gtk_cell_view_get_cell_renderers (cell_view);
+ cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cell_view));
sensitive = FALSE;
for (list = cells; list; list = list->next)
@@ -1738,7 +1738,7 @@ tree_column_row_is_sensitive (GtkComboBox *combo_box,
priv->model,
iter, FALSE, FALSE);
- cells = gtk_tree_view_column_get_cell_renderers (priv->column);
+ cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->column));
sensitive = FALSE;
for (list = cells; list; list = list->next)
@@ -4103,7 +4103,7 @@ gtk_combo_box_list_select_func (GtkTreeSelection *selection,
gtk_tree_view_column_cell_set_cell_data (column, model, &iter,
FALSE, FALSE);
- cell = cells = gtk_tree_view_column_get_cell_renderers (column);
+ cell = cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
while (cell)
{
g_object_get (cell->data,
diff --git a/gtk/gtkdnd.c b/gtk/gtkdnd.c
index b8e5fbc09f..8bbb4d24da 100644
--- a/gtk/gtkdnd.c
+++ b/gtk/gtkdnd.c
@@ -33,6 +33,12 @@
#include "gdk/gdkkeysyms.h"
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include "gdk/x11/gdkx.h"
+#endif
+
#include "gtkdnd.h"
#include "gtkiconfactory.h"
#include "gtkicontheme.h"
@@ -393,6 +399,139 @@ gtk_drag_get_ipc_widget (GtkWidget *widget)
}
+#ifdef GDK_WINDOWING_X11
+
+/*
+ * We want to handle a handful of keys during DND, e.g. Escape to abort.
+ * Grabbing the keyboard has the unfortunate side-effect of preventing
+ * useful things such as using Alt-Tab to cycle between windows or
+ * switching workspaces. Therefore, we just grab the few keys we are
+ * interested in. Note that we need to put the grabs on the root window
+ * in order for them to still work when the focus is moved to another
+ * app/workspace.
+ *
+ * GDK needs a little help to successfully deliver root key events...
+ */
+
+static GdkFilterReturn
+root_key_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *ev = (XEvent *)xevent;
+
+ if ((ev->type == KeyPress || ev->type == KeyRelease) &&
+ ev->xkey.root == ev->xkey.window)
+ ev->xkey.window = (Window)data;
+
+ return GDK_FILTER_CONTINUE;
+}
+
+typedef struct {
+ gint keysym;
+ gint modifiers;
+} GrabKey;
+
+static GrabKey grab_keys[] = {
+ { XK_Escape, 0 },
+ { XK_space, 0 },
+ { XK_KP_Space, 0 },
+ { XK_Return, 0 },
+ { XK_KP_Enter, 0 },
+ { XK_Up, 0 },
+ { XK_Up, Mod1Mask },
+ { XK_Down, 0 },
+ { XK_Down, Mod1Mask },
+ { XK_Left, 0 },
+ { XK_Left, Mod1Mask },
+ { XK_Right, 0 },
+ { XK_Right, Mod1Mask },
+ { XK_KP_Up, 0 },
+ { XK_KP_Up, Mod1Mask },
+ { XK_KP_Down, 0 },
+ { XK_KP_Down, Mod1Mask },
+ { XK_KP_Left, 0 },
+ { XK_KP_Left, Mod1Mask },
+ { XK_KP_Right, 0 },
+ { XK_KP_Right, Mod1Mask }
+};
+
+static void
+grab_dnd_keys (GtkWidget *widget,
+ guint32 time)
+{
+ guint i;
+ GdkWindow *window, *root;
+ gint keycode;
+
+ window = widget->window;
+ root = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
+
+ gdk_error_trap_push ();
+
+ for (i = 0; i < G_N_ELEMENTS (grab_keys); ++i)
+ {
+ keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (window), grab_keys[i].keysym);
+ XGrabKey (GDK_WINDOW_XDISPLAY (window),
+ keycode, grab_keys[i].modifiers,
+ GDK_WINDOW_XID (root),
+ FALSE,
+ GrabModeAsync,
+ GrabModeAsync);
+ }
+
+ gdk_flush ();
+ gdk_error_trap_pop ();
+
+ gdk_window_add_filter (NULL, root_key_filter, (gpointer) GDK_WINDOW_XID (window));
+}
+
+static void
+ungrab_dnd_keys (GtkWidget *widget,
+ guint32 time)
+{
+ guint i;
+ GdkWindow *window, *root;
+ gint keycode;
+
+ window = widget->window;
+ root = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
+
+ gdk_window_remove_filter (NULL, root_key_filter, (gpointer) GDK_WINDOW_XID (window));
+
+ gdk_error_trap_push ();
+
+ for (i = 0; i < G_N_ELEMENTS (grab_keys); ++i)
+ {
+ keycode = XKeysymToKeycode (GDK_WINDOW_XDISPLAY (window), grab_keys[i].keysym);
+ XUngrabKey (GDK_WINDOW_XDISPLAY (window),
+ keycode, grab_keys[i].modifiers,
+ GDK_WINDOW_XID (root));
+ }
+
+ gdk_flush ();
+ gdk_error_trap_pop ();
+}
+
+#else
+
+static void
+grab_dnd_keys (GtkWidget *widget,
+ guint32 time)
+{
+ gdk_keyboard_grab (widget->window, FALSE, time);
+}
+
+static void
+ungrab_dnd_keys (GtkWidget *widget,
+ guint32 time)
+{
+ gdk_display_keyboard_ungrab (gtk_widget_get_display (widget), time);
+}
+
+#endif
+
+
/***************************************************************
* gtk_drag_release_ipc_widget:
* Releases widget retrieved with gtk_drag_get_ipc_widget ()
@@ -408,6 +547,7 @@ gtk_drag_release_ipc_widget (GtkWidget *widget)
GdkScreen *screen = gtk_widget_get_screen (widget);
GSList *drag_widgets = g_object_get_data (G_OBJECT (screen),
"gtk-dnd-ipc-widgets");
+ ungrab_dnd_keys (widget, GDK_CURRENT_TIME);
if (window->group)
gtk_window_group_remove_window (window->group, window);
drag_widgets = g_slist_prepend (drag_widgets, widget);
@@ -2224,8 +2364,8 @@ gtk_drag_begin_internal (GtkWidget *widget,
return NULL;
}
- gdk_keyboard_grab (ipc_widget->window, FALSE, time);
-
+ grab_dnd_keys (ipc_widget, time);
+
/* We use a GTK grab here to override any grabs that the widget
* we are dragging from might have held
*/
@@ -3965,7 +4105,7 @@ gtk_drag_end (GtkDragSourceInfo *info, guint32 time)
info);
gdk_display_pointer_ungrab (display, time);
- gdk_display_keyboard_ungrab (display, time);
+ ungrab_dnd_keys (info->ipc_widget, time);
gtk_grab_remove (info->ipc_widget);
/* Send on a release pair to the original
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index a21e94f57f..5473143f72 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -6448,6 +6448,11 @@ gtk_entry_ensure_pixbuf (GtkEntry *entry,
icon_info->stock_id,
GTK_ICON_SIZE_MENU,
NULL);
+ if (!icon_info->pixbuf)
+ icon_info->pixbuf = gtk_widget_render_icon (GTK_WIDGET (entry),
+ GTK_STOCK_MISSING_IMAGE,
+ GTK_ICON_SIZE_MENU,
+ NULL);
GTK_WIDGET_STATE (entry) = state;
break;
diff --git a/gtk/gtkentrycompletion.c b/gtk/gtkentrycompletion.c
index 820449dc1a..a3a01be9ff 100644
--- a/gtk/gtkentrycompletion.c
+++ b/gtk/gtkentrycompletion.c
@@ -758,7 +758,7 @@ gtk_entry_completion_get_cells (GtkCellLayout *cell_layout)
priv = GTK_ENTRY_COMPLETION_GET_PRIVATE (cell_layout);
- return gtk_tree_view_column_get_cell_renderers (priv->column);
+ return gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->column));
}
/* all those callbacks */
@@ -1426,9 +1426,6 @@ _gtk_entry_completion_resize_popup (GtkEntryCompletion *completion)
gtk_tree_view_columns_autosize (GTK_TREE_VIEW (completion->priv->tree_view));
gtk_widget_set_size_request (completion->priv->tree_view, width, items * height);
- /* default on no match */
- completion->priv->current_selected = -1;
-
if (actions)
{
gtk_widget_show (completion->priv->action_view);
@@ -1489,7 +1486,7 @@ _gtk_entry_completion_popup (GtkEntryCompletion *completion)
completion->priv->ignore_enter = TRUE;
column = gtk_tree_view_get_column (GTK_TREE_VIEW (completion->priv->action_view), 0);
- renderers = gtk_tree_view_column_get_cell_renderers (column);
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
gtk_widget_ensure_style (completion->priv->tree_view);
g_object_set (GTK_CELL_RENDERER (renderers->data), "cell-background-gdk",
&completion->priv->tree_view->style->bg[GTK_STATE_NORMAL],
@@ -1498,6 +1495,9 @@ _gtk_entry_completion_popup (GtkEntryCompletion *completion)
gtk_widget_show_all (completion->priv->vbox);
+ /* default on no match */
+ completion->priv->current_selected = -1;
+
_gtk_entry_completion_resize_popup (completion);
toplevel = gtk_widget_get_toplevel (completion->priv->entry);
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h
index 9262aeaf78..2dc9f8fcdc 100644
--- a/gtk/gtkenums.h
+++ b/gtk/gtkenums.h
@@ -208,6 +208,15 @@ typedef enum
typedef enum
{
+ GTK_MESSAGE_INFO,
+ GTK_MESSAGE_WARNING,
+ GTK_MESSAGE_QUESTION,
+ GTK_MESSAGE_ERROR,
+ GTK_MESSAGE_OTHER
+} GtkMessageType;
+
+typedef enum
+{
GTK_PIXELS,
GTK_INCHES,
GTK_CENTIMETERS
@@ -485,7 +494,8 @@ typedef enum
{
GTK_PRINT_PAGES_ALL,
GTK_PRINT_PAGES_CURRENT,
- GTK_PRINT_PAGES_RANGES
+ GTK_PRINT_PAGES_RANGES,
+ GTK_PRINT_PAGES_SELECTION
} GtkPrintPages;
typedef enum
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 5f40411551..7dc98676e4 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -145,6 +145,8 @@ typedef struct _GtkFileChooserDefaultClass GtkFileChooserDefaultClass;
#define MAX_LOADING_TIME 500
+#define DEFAULT_NEW_FOLDER_NAME _("Type name of new folder")
+
struct _GtkFileChooserDefaultClass
{
GtkVBoxClass parent_class;
@@ -189,14 +191,6 @@ typedef enum {
SHORTCUT_TYPE_RECENT
} ShortcutType;
-/* Column numbers for the file list */
-enum {
- FILE_LIST_COL_NAME,
- FILE_LIST_COL_SIZE,
- FILE_LIST_COL_MTIME,
- FILE_LIST_COL_NUM_COLUMNS
-};
-
/* Column numbers for the search model.
* Keep this in sync with search_setup_model()
*/
@@ -804,6 +798,8 @@ _gtk_file_chooser_default_init (GtkFileChooserDefault *impl)
impl->pending_select_files = NULL;
impl->location_mode = LOCATION_MODE_PATH_BAR;
impl->operation_mode = OPERATION_MODE_BROWSE;
+ impl->sort_column = FILE_LIST_COL_NAME;
+ impl->sort_order = GTK_SORT_ASCENDING;
impl->recent_manager = gtk_recent_manager_get_default ();
gtk_box_set_spacing (GTK_BOX (impl), 12);
@@ -960,6 +956,9 @@ gtk_file_chooser_default_finalize (GObject *object)
if (impl->preview_file)
g_object_unref (impl->preview_file);
+ if (impl->browse_path_bar_size_group)
+ g_object_unref (impl->browse_path_bar_size_group);
+
load_remove_timer (impl);
/* Free all the Models we have */
@@ -1743,7 +1742,7 @@ shortcuts_insert_file (GtkFileChooserDefault *impl,
gtk_tree_path_free (p);
cancellable = _gtk_file_system_get_info (request->impl->file_system, request->file,
- "standard::is-hidden,standard::display-name,standard::icon",
+ "standard::is-hidden,standard::is-backup,standard::display-name,standard::icon",
get_file_info_finished, request);
gtk_list_store_set (impl->shortcuts_model, &iter,
@@ -2418,7 +2417,9 @@ edited_idle_cb (GtkFileChooserDefault *impl)
gtk_widget_set_sensitive (impl->browse_new_folder_button, TRUE);
- if (impl->edited_new_text) /* not cancelled? */
+ if (impl->edited_new_text /* not cancelled? */
+ && (strlen (impl->edited_new_text) != 0)
+ && (strcmp (impl->edited_new_text, DEFAULT_NEW_FOLDER_NAME) != 0)) /* Don't create folder if name is empty or has not been edited */
{
GError *error = NULL;
GFile *file;
@@ -3706,7 +3707,7 @@ rename_selected_bookmark (GtkFileChooserDefault *impl)
{
path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
column = gtk_tree_view_get_column (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), 0);
- renderers = gtk_tree_view_column_get_cell_renderers (column);
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
cell = g_list_nth_data (renderers, 1);
g_list_free (renderers);
g_object_set (cell, "editable", TRUE, NULL);
@@ -4453,35 +4454,70 @@ list_button_press_event_cb (GtkWidget *widget,
return TRUE;
}
+typedef struct {
+ OperationMode operation_mode;
+ gint general_column;
+ gint model_column;
+} ColumnMap;
+
+/* Sigh. Each operation mode has different sort column IDs. This table
+ * translates between them.
+ */
+static const ColumnMap column_map[] = {
+ { OPERATION_MODE_BROWSE, FILE_LIST_COL_NAME, FILE_LIST_COL_NAME },
+ { OPERATION_MODE_BROWSE, FILE_LIST_COL_SIZE, FILE_LIST_COL_SIZE },
+ { OPERATION_MODE_BROWSE, FILE_LIST_COL_MTIME, FILE_LIST_COL_MTIME },
+
+ { OPERATION_MODE_SEARCH, FILE_LIST_COL_NAME, SEARCH_MODEL_COL_FILE },
+ { OPERATION_MODE_SEARCH, FILE_LIST_COL_SIZE, SEARCH_MODEL_COL_SIZE },
+ { OPERATION_MODE_SEARCH, FILE_LIST_COL_MTIME, SEARCH_MODEL_COL_MTIME },
+
+ { OPERATION_MODE_RECENT, FILE_LIST_COL_NAME, RECENT_MODEL_COL_FILE },
+ { OPERATION_MODE_RECENT, FILE_LIST_COL_SIZE, 0 },
+ { OPERATION_MODE_RECENT, FILE_LIST_COL_MTIME, RECENT_MODEL_COL_INFO }
+};
+
+static gint
+general_column_to_model_column (GtkFileChooserDefault *impl, gint general_column)
+{
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (column_map); i++)
+ if (column_map[i].operation_mode == impl->operation_mode
+ && column_map[i].general_column == general_column)
+ return column_map[i].model_column;
+
+ g_assert_not_reached ();
+ return 0;
+}
+
+static gint
+model_column_to_general_column (GtkFileChooserDefault *impl, gint model_column)
+{
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (column_map); i++)
+ if (column_map[i].operation_mode == impl->operation_mode
+ && column_map[i].model_column == model_column)
+ return column_map[i].general_column;
+
+ g_assert_not_reached ();
+ return 0;
+}
+
/* Sets the sort column IDs for the file list based on the operation mode */
static void
file_list_set_sort_column_ids (GtkFileChooserDefault *impl)
{
int name_id, mtime_id, size_id;
- name_id = mtime_id = size_id = 0;
-
- switch (impl->operation_mode)
- {
- case OPERATION_MODE_BROWSE:
- name_id = FILE_LIST_COL_NAME;
- mtime_id = FILE_LIST_COL_MTIME;
- size_id = FILE_LIST_COL_SIZE;
- break;
- case OPERATION_MODE_SEARCH:
- name_id = SEARCH_MODEL_COL_FILE;
- mtime_id = SEARCH_MODEL_COL_MTIME;
- size_id = SEARCH_MODEL_COL_SIZE;
- break;
- case OPERATION_MODE_RECENT:
- name_id = RECENT_MODEL_COL_FILE;
- mtime_id = RECENT_MODEL_COL_INFO;
- break;
- }
+ name_id = general_column_to_model_column (impl, FILE_LIST_COL_NAME);
+ mtime_id = general_column_to_model_column (impl, FILE_LIST_COL_MTIME);
+ size_id = general_column_to_model_column (impl, FILE_LIST_COL_SIZE);
- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id);
+ gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id);
gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id);
- gtk_tree_view_column_set_sort_column_id (impl->list_size_column, size_id);
+ gtk_tree_view_column_set_sort_column_id (impl->list_size_column, size_id);
}
static gboolean
@@ -4634,7 +4670,6 @@ create_file_list (GtkFileChooserDefault *impl)
gtk_tree_view_column_set_expand (impl->list_name_column, TRUE);
gtk_tree_view_column_set_resizable (impl->list_name_column, TRUE);
gtk_tree_view_column_set_title (impl->list_name_column, _("Name"));
- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, FILE_LIST_COL_NAME);
renderer = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (impl->list_name_column, renderer, FALSE);
@@ -4664,7 +4699,6 @@ create_file_list (GtkFileChooserDefault *impl)
gtk_tree_view_column_pack_start (column, renderer, TRUE); /* bug: it doesn't expand */
gtk_tree_view_column_set_cell_data_func (column, renderer,
list_size_data_func, impl, NULL);
- gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
impl->list_size_column = column;
@@ -4852,6 +4886,7 @@ save_folder_combo_create (GtkFileChooserDefault *impl)
NULL);
cell = gtk_cell_renderer_text_new ();
+ g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
"text", SHORTCUTS_COL_NAME,
@@ -5201,6 +5236,8 @@ location_button_create (GtkFileChooserDefault *impl)
impl->location_button = g_object_new (GTK_TYPE_TOGGLE_BUTTON,
"image", image,
NULL);
+
+ gtk_size_group_add_widget (impl->browse_path_bar_size_group, impl->location_button);
g_signal_connect (impl->location_button, "toggled",
G_CALLBACK (location_button_toggled_cb), impl);
@@ -5216,7 +5253,6 @@ static GtkWidget *
browse_widgets_create (GtkFileChooserDefault *impl)
{
GtkWidget *vbox;
- GtkWidget *hbox;
GtkWidget *hpaned;
GtkWidget *widget;
GtkSizeGroup *size_group;
@@ -5226,26 +5262,31 @@ browse_widgets_create (GtkFileChooserDefault *impl)
vbox = gtk_vbox_new (FALSE, 12);
/* Location widgets */
- hbox = gtk_hbox_new (FALSE, 12);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
- impl->browse_path_bar_hbox = hbox;
+ impl->browse_path_bar_hbox = gtk_hbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), impl->browse_path_bar_hbox, FALSE, FALSE, 0);
+ gtk_widget_show (impl->browse_path_bar_hbox);
+
+ /* Size group that allows the path bar to be the same size between modes */
+ impl->browse_path_bar_size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
+ gtk_size_group_set_ignore_hidden (impl->browse_path_bar_size_group, FALSE);
+
+ /* Location button */
location_button_create (impl);
- gtk_box_pack_start (GTK_BOX (hbox), impl->location_button, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->location_button, FALSE, FALSE, 0);
/* Path bar */
impl->browse_path_bar = create_path_bar (impl);
g_signal_connect (impl->browse_path_bar, "path-clicked", G_CALLBACK (path_bar_clicked), impl);
gtk_widget_show_all (impl->browse_path_bar);
- gtk_box_pack_start (GTK_BOX (hbox), impl->browse_path_bar, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->browse_path_bar, TRUE, TRUE, 0);
/* Create Folder */
impl->browse_new_folder_button = gtk_button_new_with_mnemonic (_("Create Fo_lder"));
g_signal_connect (impl->browse_new_folder_button, "clicked",
G_CALLBACK (new_folder_button_clicked), impl);
- gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
+ gtk_box_pack_end (GTK_BOX (impl->browse_path_bar_hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
/* Box for the location label and entry */
@@ -6009,6 +6050,35 @@ get_is_file_filtered (GtkFileChooserDefault *impl,
}
static void
+set_sort_column (GtkFileChooserDefault *impl)
+{
+ GtkTreeSortable *sortable;
+
+ switch (impl->operation_mode)
+ {
+ case OPERATION_MODE_BROWSE:
+ sortable = GTK_TREE_SORTABLE (impl->sort_model);
+ break;
+
+ case OPERATION_MODE_SEARCH:
+ sortable = GTK_TREE_SORTABLE (impl->search_model_sort);
+ break;
+
+ case OPERATION_MODE_RECENT:
+ sortable = GTK_TREE_SORTABLE (impl->recent_model_sort);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ return;
+ }
+
+ gtk_tree_sortable_set_sort_column_id (sortable,
+ general_column_to_model_column (impl, impl->sort_column),
+ impl->sort_order);
+}
+
+static void
settings_load (GtkFileChooserDefault *impl)
{
GtkFileChooserSettings *settings;
@@ -6016,6 +6086,8 @@ settings_load (GtkFileChooserDefault *impl)
gboolean show_hidden;
gboolean expand_folders;
gboolean show_size_column;
+ gint sort_column;
+ GtkSortType sort_order;
settings = _gtk_file_chooser_settings_new ();
@@ -6023,6 +6095,8 @@ settings_load (GtkFileChooserDefault *impl)
show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings);
expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings);
show_size_column = _gtk_file_chooser_settings_get_show_size_column (settings);
+ sort_column = _gtk_file_chooser_settings_get_sort_column (settings);
+ sort_order = _gtk_file_chooser_settings_get_sort_order (settings);
g_object_unref (settings);
@@ -6037,6 +6111,10 @@ settings_load (GtkFileChooserDefault *impl)
impl->show_size_column = show_size_column;
if (impl->list_size_column)
gtk_tree_view_column_set_visible (impl->list_size_column, show_size_column);
+
+ impl->sort_column = sort_column;
+ impl->sort_order = sort_order;
+ set_sort_column (impl);
}
static void
@@ -6075,6 +6153,8 @@ settings_save (GtkFileChooserDefault *impl)
_gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl)));
_gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders);
_gtk_file_chooser_settings_set_show_size_column (settings, impl->show_size_column);
+ _gtk_file_chooser_settings_set_sort_column (settings, impl->sort_column);
+ _gtk_file_chooser_settings_set_sort_order (settings, impl->sort_order);
save_dialog_geometry (impl, settings);
@@ -6089,7 +6169,6 @@ static void
gtk_file_chooser_default_realize (GtkWidget *widget)
{
GtkFileChooserDefault *impl;
- char *current_working_dir;
impl = GTK_FILE_CHOOSER_DEFAULT (widget);
@@ -6296,10 +6375,15 @@ static void
list_sort_column_changed_cb (GtkTreeSortable *sortable,
GtkFileChooserDefault *impl)
{
+ gint sort_column_id;
GtkSortType sort_type;
- if (gtk_tree_sortable_get_sort_column_id (sortable, NULL, &sort_type))
- impl->list_sort_ascending = (sort_type == GTK_SORT_ASCENDING);
+ if (gtk_tree_sortable_get_sort_column_id (sortable, &sort_column_id, &sort_type))
+ {
+ impl->list_sort_ascending = (sort_type == GTK_SORT_ASCENDING);
+ impl->sort_column = model_column_to_general_column (impl, sort_column_id);
+ impl->sort_order = sort_type;
+ }
}
static void
@@ -6343,7 +6427,7 @@ load_set_model (GtkFileChooserDefault *impl)
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_SIZE, size_sort_func, impl, NULL);
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_MTIME, mtime_sort_func, impl, NULL);
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (impl->sort_model), NULL, NULL, NULL);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, GTK_SORT_ASCENDING);
+ set_sort_column (impl);
impl->list_sort_ascending = TRUE;
profile_msg (" gtk_tree_model_sort_new_with_model end", NULL);
@@ -6501,7 +6585,8 @@ show_and_select_files_finished_loading (GtkFolder *folder,
if (info)
{
if (!have_hidden)
- have_hidden = g_file_info_get_is_hidden (info);
+ have_hidden = g_file_info_get_is_hidden (info)
+ || g_file_info_get_is_backup (info);
if (!have_filtered)
have_filtered = (! _gtk_file_info_consider_as_directory (info)) &&
@@ -6604,7 +6689,7 @@ show_and_select_files (GtkFileChooserDefault *impl,
impl->show_and_select_files_cancellable =
_gtk_file_system_get_folder (impl->file_system, parent_file,
- "standard::is-hidden,standard::type,standard::name,standard::content-type",
+ "standard::is-hidden,standard::is-backup,standard::type,standard::name,standard::content-type",
show_and_select_files_get_folder_cb, info);
profile_end ("end", NULL);
@@ -7035,13 +7120,14 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
}
else
{
- /* Error and bail out, ignoring "not found" errors since they're useless:
+ /* Error and bail out, ignoring "not found" errors since they're useless:
* they only happen when a program defaults to a folder that has been (re)moved.
*/
if (!g_error_matches (data->original_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- error_changing_folder_dialog (impl, data->original_file, data->original_error);
+ error_changing_folder_dialog (impl, data->original_file, data->original_error);
else
g_error_free (data->original_error);
+
g_object_unref (data->original_file);
goto out;
@@ -7050,7 +7136,13 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
if (data->original_file)
{
- error_changing_folder_dialog (impl, data->original_file, data->original_error);
+ /* Error and bail out, ignoring "not found" errors since they're useless:
+ * they only happen when a program defaults to a folder that has been (re)moved.
+ */
+ if (!g_error_matches (data->original_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ error_changing_folder_dialog (impl, data->original_file, data->original_error);
+ else
+ g_error_free (data->original_error);
g_object_unref (data->original_file);
}
@@ -9290,9 +9382,7 @@ search_setup_model (GtkFileChooserDefault *impl)
SEARCH_MODEL_COL_SIZE,
search_column_size_sort_func,
impl, NULL);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->search_model_sort),
- SEARCH_MODEL_COL_MTIME,
- GTK_SORT_DESCENDING);
+ set_sort_column (impl);
/* EB: setting the model here will make the hits list update feel
* more "alive" than setting the model at the end of the search
@@ -9393,12 +9483,20 @@ static void
search_setup_widgets (GtkFileChooserDefault *impl)
{
GtkWidget *label;
+ GtkWidget *image;
impl->search_hbox = gtk_hbox_new (FALSE, 12);
+
+ /* Image */
+
+ image = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_BUTTON);
+ gtk_size_group_add_widget (GTK_SIZE_GROUP (impl->browse_path_bar_size_group), image);
+ gtk_box_pack_start (GTK_BOX (impl->search_hbox), image, FALSE, FALSE, 5);
/* Label */
- label = gtk_label_new_with_mnemonic (_("_Search:"));
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("<b>_Search:</b>"));
gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0);
/* Entry */
@@ -9450,6 +9548,35 @@ search_setup_widgets (GtkFileChooserDefault *impl)
/* FMQ: hide the filter combo? */
}
+/* Stops running operations like populating the browse model, searches, and the recent-files model */
+static void
+stop_operation (GtkFileChooserDefault *impl, OperationMode mode)
+{
+ switch (mode)
+ {
+ case OPERATION_MODE_BROWSE:
+ stop_loading_and_clear_list_model (impl);
+ break;
+
+ case OPERATION_MODE_SEARCH:
+ search_stop_searching (impl, FALSE);
+ search_clear_model (impl, TRUE);
+
+ gtk_widget_destroy (impl->search_hbox);
+ impl->search_hbox = NULL;
+ impl->search_entry = NULL;
+ break;
+
+ case OPERATION_MODE_RECENT:
+ recent_stop_loading (impl);
+ recent_clear_model (impl, TRUE);
+
+ gtk_widget_destroy (impl->recent_hbox);
+ impl->recent_hbox = NULL;
+ break;
+ }
+}
+
/* Main entry point to the searching functions; this gets called when the user
* activates the Search shortcut.
*/
@@ -9467,21 +9594,7 @@ search_activate (GtkFileChooserDefault *impl)
previous_mode = impl->operation_mode;
impl->operation_mode = OPERATION_MODE_SEARCH;
- switch (previous_mode)
- {
- case OPERATION_MODE_RECENT:
- recent_stop_loading (impl);
- recent_clear_model (impl, TRUE);
- break;
-
- case OPERATION_MODE_BROWSE:
- stop_loading_and_clear_list_model (impl);
- break;
-
- case OPERATION_MODE_SEARCH:
- g_assert_not_reached ();
- break;
- }
+ stop_operation (impl, previous_mode);
g_assert (impl->search_hbox == NULL);
g_assert (impl->search_entry == NULL);
@@ -9572,6 +9685,9 @@ recent_switch_to_browse_mode (GtkFileChooserDefault *impl)
recent_stop_loading (impl);
recent_clear_model (impl, TRUE);
+ gtk_widget_destroy (impl->recent_hbox);
+ impl->recent_hbox = NULL;
+
gtk_widget_show (impl->browse_path_bar);
gtk_widget_show (impl->browse_new_folder_button);
@@ -9797,9 +9913,7 @@ recent_setup_model (GtkFileChooserDefault *impl)
RECENT_MODEL_COL_INFO,
recent_column_mtime_sort_func,
impl, NULL);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model_sort),
- RECENT_MODEL_COL_INFO,
- GTK_SORT_DESCENDING);
+ set_sort_column (impl);
}
typedef struct
@@ -10103,9 +10217,29 @@ recent_should_respond (GtkFileChooserDefault *impl)
static void
recent_hide_entry (GtkFileChooserDefault *impl)
{
+ GtkWidget *label;
+ GtkWidget *image;
+
+ impl->recent_hbox = gtk_hbox_new (FALSE, 12);
+
+ /* Image */
+ image = gtk_image_new_from_icon_name ("document-open-recent", GTK_ICON_SIZE_BUTTON);
+ gtk_size_group_add_widget (impl->browse_path_bar_size_group, image);
+ gtk_box_pack_start (GTK_BOX (impl->recent_hbox), image, FALSE, FALSE, 5);
+
+ /* Label */
+ label = gtk_label_new (NULL);
+ gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), _("<b>Recently Used</b>"));
+ gtk_box_pack_start (GTK_BOX (impl->recent_hbox), label, FALSE, FALSE, 0);
+
gtk_widget_hide (impl->browse_path_bar);
gtk_widget_hide (impl->browse_new_folder_button);
+ /* Box for recent widgets */
+ gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->recent_hbox, TRUE, TRUE, 0);
+ gtk_widget_show_all (impl->recent_hbox);
+
+ /* Hide the location widgets temporarily */
if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
{
@@ -10128,25 +10262,7 @@ recent_activate (GtkFileChooserDefault *impl)
previous_mode = impl->operation_mode;
impl->operation_mode = OPERATION_MODE_RECENT;
- switch (previous_mode)
- {
- case OPERATION_MODE_SEARCH:
- search_stop_searching (impl, FALSE);
- search_clear_model (impl, TRUE);
-
- gtk_widget_destroy (impl->search_hbox);
- impl->search_hbox = NULL;
- impl->search_entry = NULL;
- break;
-
- case OPERATION_MODE_BROWSE:
- stop_loading_and_clear_list_model (impl);
- break;
-
- case OPERATION_MODE_RECENT:
- g_assert_not_reached ();
- break;
- }
+ stop_operation (impl, previous_mode);
recent_hide_entry (impl);
@@ -10403,7 +10519,7 @@ shortcuts_activate_volume (GtkFileChooserDefault *impl,
if (!_gtk_file_system_volume_is_mounted (volume))
{
- GtkMountOperation *mount_op;
+ GMountOperation *mount_op;
set_busy_cursor (impl, TRUE);
@@ -11026,7 +11142,7 @@ list_name_data_func (GtkTreeViewColumn *tree_column,
if (!info)
{
g_object_set (cell,
- "text", _("Type name of new folder"),
+ "text", DEFAULT_NEW_FOLDER_NAME,
"sensitive", TRUE,
"ellipsize", PANGO_ELLIPSIZE_NONE,
NULL);
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index ee561a1569..400a211270 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -28,6 +28,7 @@
#include "gtkrecentmanager.h"
#include "gtksearchengine.h"
#include "gtkquery.h"
+#include "gtksizegroup.h"
#include "gtktreemodelsort.h"
#include "gtktreestore.h"
#include "gtktreeview.h"
@@ -181,6 +182,7 @@ struct _GtkFileChooserDefault
GtkWidget *browse_files_popup_menu_size_column_item;
GtkWidget *browse_new_folder_button;
GtkWidget *browse_path_bar_hbox;
+ GtkSizeGroup *browse_path_bar_size_group;
GtkWidget *browse_path_bar;
GtkFileSystemModel *browse_files_model;
@@ -196,6 +198,7 @@ struct _GtkFileChooserDefault
GtkTreeModelSort *search_model_sort;
/* OPERATION_MODE_RECENT */
+ GtkWidget *recent_hbox;
GtkRecentManager *recent_manager;
GtkListStore *recent_model;
guint load_recent_id;
@@ -279,6 +282,9 @@ struct _GtkFileChooserDefault
gulong toplevel_set_focus_id;
GtkWidget *toplevel_last_focus_widget;
+ gint sort_column;
+ GtkSortType sort_order;
+
#if 0
GdkDragContext *shortcuts_drag_context;
GSource *shortcuts_drag_outside_idle;
diff --git a/gtk/gtkfilechoosersettings.c b/gtk/gtkfilechoosersettings.c
index fe3543d2c4..1553c36fd4 100644
--- a/gtk/gtkfilechoosersettings.c
+++ b/gtk/gtkfilechoosersettings.c
@@ -46,6 +46,14 @@
#define GEOMETRY_Y_KEY "GeometryY"
#define GEOMETRY_WIDTH_KEY "GeometryWidth"
#define GEOMETRY_HEIGHT_KEY "GeometryHeight"
+#define SORT_COLUMN_KEY "SortColumn"
+#define SORT_ORDER_KEY "SortOrder"
+
+#define COLUMN_NAME_STRING "name"
+#define COLUMN_MTIME_STRING "modified"
+#define COLUMN_SIZE_STRING "size"
+#define SORT_ASCENDING_STRING "ascending"
+#define SORT_DESCENDING_STRING "descending"
#define MODE_PATH_BAR "path-bar"
#define MODE_FILENAME_ENTRY "filename-entry"
@@ -104,6 +112,7 @@ ensure_settings_read (GtkFileChooserSettings *settings)
GError *error;
GKeyFile *key_file;
gchar *location_mode_str, *filename;
+ gchar *sort_column, *sort_order;
gboolean value;
if (settings->settings_read)
@@ -129,6 +138,8 @@ ensure_settings_read (GtkFileChooserSettings *settings)
if (!g_key_file_has_group (key_file, SETTINGS_GROUP))
goto out;
+ /* Location mode */
+
location_mode_str = g_key_file_get_string (key_file, SETTINGS_GROUP,
LOCATION_MODE_KEY, NULL);
if (location_mode_str)
@@ -144,6 +155,8 @@ ensure_settings_read (GtkFileChooserSettings *settings)
g_free (location_mode_str);
}
+ /* Show hidden */
+
value = g_key_file_get_boolean (key_file, SETTINGS_GROUP,
SHOW_HIDDEN_KEY, &error);
if (error)
@@ -151,6 +164,8 @@ ensure_settings_read (GtkFileChooserSettings *settings)
else
settings->show_hidden = value != FALSE;
+ /* Expand folders */
+
value = g_key_file_get_boolean (key_file, SETTINGS_GROUP,
EXPAND_FOLDERS_KEY, &error);
if (error)
@@ -158,6 +173,8 @@ ensure_settings_read (GtkFileChooserSettings *settings)
else
settings->expand_folders = value != FALSE;
+ /* Show size column */
+
value = g_key_file_get_boolean (key_file, SETTINGS_GROUP,
SHOW_SIZE_COLUMN_KEY, &error);
if (error)
@@ -165,11 +182,49 @@ ensure_settings_read (GtkFileChooserSettings *settings)
else
settings->show_size_column = value != FALSE;
+ /* Geometry */
+
get_int_key (key_file, SETTINGS_GROUP, GEOMETRY_X_KEY, &settings->geometry_x);
get_int_key (key_file, SETTINGS_GROUP, GEOMETRY_Y_KEY, &settings->geometry_y);
get_int_key (key_file, SETTINGS_GROUP, GEOMETRY_WIDTH_KEY, &settings->geometry_width);
get_int_key (key_file, SETTINGS_GROUP, GEOMETRY_HEIGHT_KEY, &settings->geometry_height);
+ /* Sort column */
+
+ sort_column = g_key_file_get_string (key_file, SETTINGS_GROUP,
+ SORT_COLUMN_KEY, NULL);
+ if (sort_column)
+ {
+ if (EQ (COLUMN_NAME_STRING, sort_column))
+ settings->sort_column = FILE_LIST_COL_NAME;
+ else if (EQ (COLUMN_MTIME_STRING, sort_column))
+ settings->sort_column = FILE_LIST_COL_MTIME;
+ else if (EQ (COLUMN_SIZE_STRING, sort_column))
+ settings->sort_column = FILE_LIST_COL_SIZE;
+ else
+ g_warning ("Unknown sort column name '%s' encountered in filechooser settings",
+ sort_column);
+
+ g_free (sort_column);
+ }
+
+ /* Sort order */
+
+ sort_order = g_key_file_get_string (key_file, SETTINGS_GROUP,
+ SORT_ORDER_KEY, NULL);
+ if (sort_order)
+ {
+ if (EQ (SORT_ASCENDING_STRING, sort_order))
+ settings->sort_order = GTK_SORT_ASCENDING;
+ else if (EQ (SORT_DESCENDING_STRING, sort_order))
+ settings->sort_order = GTK_SORT_DESCENDING;
+ else
+ g_warning ("Unknown sort column order '%s' encountered in filechooser settings",
+ sort_order);
+
+ g_free (sort_order);
+ }
+
out:
g_key_file_free (key_file);
@@ -189,6 +244,8 @@ static void
_gtk_file_chooser_settings_init (GtkFileChooserSettings *settings)
{
settings->location_mode = LOCATION_MODE_PATH_BAR;
+ settings->sort_order = GTK_SORT_ASCENDING;
+ settings->sort_column = FILE_LIST_COL_NAME;
settings->show_hidden = FALSE;
settings->expand_folders = FALSE;
settings->show_size_column = FALSE;
@@ -288,6 +345,34 @@ _gtk_file_chooser_settings_set_geometry (GtkFileChooserSettings *settings,
settings->geometry_height = height;
}
+gint
+_gtk_file_chooser_settings_get_sort_column (GtkFileChooserSettings *settings)
+{
+ ensure_settings_read (settings);
+ return settings->sort_column;
+}
+
+void
+_gtk_file_chooser_settings_set_sort_column (GtkFileChooserSettings *settings,
+ gint sort_column)
+{
+ settings->sort_column = sort_column;
+}
+
+GtkSortType
+_gtk_file_chooser_settings_get_sort_order (GtkFileChooserSettings *settings)
+{
+ ensure_settings_read (settings);
+ return settings->sort_order;
+}
+
+void
+_gtk_file_chooser_settings_set_sort_order (GtkFileChooserSettings *settings,
+ GtkSortType sort_order)
+{
+ settings->sort_order = sort_order;
+}
+
gboolean
_gtk_file_chooser_settings_save (GtkFileChooserSettings *settings,
GError **error)
@@ -296,6 +381,8 @@ _gtk_file_chooser_settings_save (GtkFileChooserSettings *settings,
gchar *filename;
gchar *dirname;
gchar *contents;
+ gchar *sort_column;
+ gchar *sort_order;
gsize len;
gboolean retval;
GKeyFile *key_file;
@@ -317,6 +404,40 @@ _gtk_file_chooser_settings_save (GtkFileChooserSettings *settings,
return FALSE;
}
+ switch (settings->sort_column)
+ {
+ case FILE_LIST_COL_NAME:
+ sort_column = COLUMN_NAME_STRING;
+ break;
+
+ case FILE_LIST_COL_MTIME:
+ sort_column = COLUMN_MTIME_STRING;
+ break;
+
+ case FILE_LIST_COL_SIZE:
+ sort_column = COLUMN_SIZE_STRING;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ sort_column = NULL;
+ }
+
+ switch (settings->sort_order)
+ {
+ case GTK_SORT_ASCENDING:
+ sort_order = SORT_ASCENDING_STRING;
+ break;
+
+ case GTK_SORT_DESCENDING:
+ sort_order = SORT_DESCENDING_STRING;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ sort_order = NULL;
+ }
+
key_file = g_key_file_new ();
/* Initialise with the on-disk keyfile, so we keep unknown options */
@@ -338,6 +459,10 @@ _gtk_file_chooser_settings_save (GtkFileChooserSettings *settings,
GEOMETRY_WIDTH_KEY, settings->geometry_width);
g_key_file_set_integer (key_file, SETTINGS_GROUP,
GEOMETRY_HEIGHT_KEY, settings->geometry_height);
+ g_key_file_set_string (key_file, SETTINGS_GROUP,
+ SORT_COLUMN_KEY, sort_column);
+ g_key_file_set_string (key_file, SETTINGS_GROUP,
+ SORT_ORDER_KEY, sort_order);
contents = g_key_file_to_data (key_file, &len, error);
g_key_file_free (key_file);
diff --git a/gtk/gtkfilechoosersettings.h b/gtk/gtkfilechoosersettings.h
index 1bc45aa253..5fd7ad2e5a 100644
--- a/gtk/gtkfilechoosersettings.h
+++ b/gtk/gtkfilechoosersettings.h
@@ -29,6 +29,14 @@ G_BEGIN_DECLS
#define GTK_FILE_CHOOSER_SETTINGS_TYPE (_gtk_file_chooser_settings_get_type ())
+/* Column numbers for the file list */
+enum {
+ FILE_LIST_COL_NAME,
+ FILE_LIST_COL_SIZE,
+ FILE_LIST_COL_MTIME,
+ FILE_LIST_COL_NUM_COLUMNS
+};
+
typedef struct _GtkFileChooserSettings GtkFileChooserSettings;
typedef struct _GtkFileChooserSettingsClass GtkFileChooserSettingsClass;
@@ -38,6 +46,9 @@ struct _GtkFileChooserSettings
LocationMode location_mode;
+ GtkSortType sort_order;
+ gint sort_column;
+
int geometry_x;
int geometry_y;
int geometry_width;
@@ -74,6 +85,14 @@ gboolean _gtk_file_chooser_settings_get_show_size_column (GtkFileChooserSettings
void _gtk_file_chooser_settings_set_show_size_column (GtkFileChooserSettings *settings,
gboolean show_column);
+gint _gtk_file_chooser_settings_get_sort_column (GtkFileChooserSettings *settings);
+void _gtk_file_chooser_settings_set_sort_column (GtkFileChooserSettings *settings,
+ gint sort_column);
+
+GtkSortType _gtk_file_chooser_settings_get_sort_order (GtkFileChooserSettings *settings);
+void _gtk_file_chooser_settings_set_sort_order (GtkFileChooserSettings *settings,
+ GtkSortType sort_order);
+
void _gtk_file_chooser_settings_get_geometry (GtkFileChooserSettings *settings,
int *out_x,
int *out_y,
diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c
index 79eb10c25b..1d0b736d07 100644
--- a/gtk/gtkfilesystemmodel.c
+++ b/gtk/gtkfilesystemmodel.c
@@ -1336,7 +1336,8 @@ file_model_node_is_visible (GtkFileSystemModel *model,
model->show_folders != is_folder)
return FALSE;
- if (!model->show_hidden && g_file_info_get_is_hidden (info))
+ if (!model->show_hidden &&
+ (g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info)))
return FALSE;
if (model->filter_func &&
diff --git a/gtk/gtkfontsel.c b/gtk/gtkfontsel.c
index 84ee9dc85a..c3593c88b8 100644
--- a/gtk/gtkfontsel.c
+++ b/gtk/gtkfontsel.c
@@ -90,7 +90,7 @@
/* These are what we use as the standard font sizes, for the size list.
*/
static const guint16 font_sizes[] = {
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 26, 28,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
32, 36, 40, 48, 56, 64, 72
};
diff --git a/gtk/gtkhandlebox.c b/gtk/gtkhandlebox.c
index 2215689567..46e9592bf2 100644
--- a/gtk/gtkhandlebox.c
+++ b/gtk/gtkhandlebox.c
@@ -1079,7 +1079,8 @@ gtk_handle_box_button_press (GtkWidget *widget,
gint root_x, root_y;
gint width, height;
- gtk_invisible_set_screen (GTK_INVISIBLE (invisible), gtk_widget_get_screen (hb));
+ gtk_invisible_set_screen (GTK_INVISIBLE (invisible),
+ gtk_widget_get_screen (GTK_WIDGET (hb)));
gdk_window_get_deskrelative_origin (hb->bin_window, &desk_x, &desk_y);
gdk_window_get_origin (hb->bin_window, &root_x, &root_y);
gdk_drawable_get_size (hb->bin_window, &width, &height);
diff --git a/gtk/gtkhbbox.c b/gtk/gtkhbbox.c
index d7835faaa9..d852daf0a2 100644
--- a/gtk/gtkhbbox.c
+++ b/gtk/gtkhbbox.c
@@ -26,15 +26,11 @@
#include "config.h"
#include "gtkhbbox.h"
+#include "gtkorientable.h"
#include "gtkintl.h"
#include "gtkalias.h"
-static void gtk_hbutton_box_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void gtk_hbutton_box_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-
static gint default_spacing = 30;
static gint default_layout_style = GTK_BUTTONBOX_EDGE;
@@ -43,18 +39,13 @@ G_DEFINE_TYPE (GtkHButtonBox, gtk_hbutton_box, GTK_TYPE_BUTTON_BOX)
static void
gtk_hbutton_box_class_init (GtkHButtonBoxClass *class)
{
- GtkWidgetClass *widget_class;
-
- widget_class = (GtkWidgetClass*) class;
-
- widget_class->size_request = gtk_hbutton_box_size_request;
- widget_class->size_allocate = gtk_hbutton_box_size_allocate;
}
static void
gtk_hbutton_box_init (GtkHButtonBox *hbutton_box)
{
- /* button_box_init has done everything already */
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (hbutton_box),
+ GTK_ORIENTATION_HORIZONTAL);
}
GtkWidget*
@@ -105,186 +96,5 @@ gtk_hbutton_box_get_layout_default (void)
return default_layout_style;
}
-
-
-static void
-gtk_hbutton_box_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- GtkBox *box;
- GtkButtonBox *bbox;
- gint nvis_children;
- gint child_width;
- gint child_height;
- gint spacing;
- GtkButtonBoxStyle layout;
-
- box = GTK_BOX (widget);
- bbox = GTK_BUTTON_BOX (widget);
-
- spacing = box->spacing;
- layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
- ? bbox->layout_style : default_layout_style;
-
- _gtk_button_box_child_requisition (widget,
- &nvis_children,
- NULL,
- &child_width,
- &child_height);
-
- if (nvis_children == 0)
- {
- requisition->width = 0;
- requisition->height = 0;
- }
- else
- {
- switch (layout)
- {
- case GTK_BUTTONBOX_SPREAD:
- requisition->width =
- nvis_children*child_width + ((nvis_children+1)*spacing);
- break;
- case GTK_BUTTONBOX_EDGE:
- case GTK_BUTTONBOX_START:
- case GTK_BUTTONBOX_END:
- case GTK_BUTTONBOX_CENTER:
- requisition->width = nvis_children*child_width + ((nvis_children-1)*spacing);
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- requisition->height = child_height;
- }
-
- requisition->width += GTK_CONTAINER (box)->border_width * 2;
- requisition->height += GTK_CONTAINER (box)->border_width * 2;
-}
-
-
-
-static void
-gtk_hbutton_box_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- GtkBox *base_box;
- GtkButtonBox *box;
- GtkBoxChild *child;
- GList *children;
- GtkAllocation child_allocation;
- gint nvis_children;
- gint n_secondaries;
- gint child_width;
- gint child_height;
- gint x = 0;
- gint secondary_x = 0;
- gint y = 0;
- gint width;
- gint childspace;
- gint childspacing = 0;
- GtkButtonBoxStyle layout;
- gint spacing;
-
- base_box = GTK_BOX (widget);
- box = GTK_BUTTON_BOX (widget);
- spacing = base_box->spacing;
- layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
- ? box->layout_style : default_layout_style;
- _gtk_button_box_child_requisition (widget,
- &nvis_children,
- &n_secondaries,
- &child_width,
- &child_height);
- widget->allocation = *allocation;
- width = allocation->width - GTK_CONTAINER (box)->border_width*2;
- switch (layout)
- {
- case GTK_BUTTONBOX_SPREAD:
- childspacing = (width - (nvis_children * child_width)) / (nvis_children + 1);
- x = allocation->x + GTK_CONTAINER (box)->border_width + childspacing;
- secondary_x = x + ((nvis_children - n_secondaries) * (child_width + childspacing));
- break;
- case GTK_BUTTONBOX_EDGE:
- if (nvis_children >= 2)
- {
- childspacing = (width - (nvis_children * child_width)) / (nvis_children - 1);
- x = allocation->x + GTK_CONTAINER (box)->border_width;
- secondary_x = x + ((nvis_children - n_secondaries) * (child_width + childspacing));
- }
- else
- {
- /* one or zero children, just center */
- childspacing = width;
- x = secondary_x = allocation->x + (allocation->width - child_width) / 2;
- }
- break;
- case GTK_BUTTONBOX_START:
- childspacing = spacing;
- x = allocation->x + GTK_CONTAINER (box)->border_width;
- secondary_x = allocation->x + allocation->width
- - child_width * n_secondaries
- - spacing * (n_secondaries - 1)
- - GTK_CONTAINER (box)->border_width;
- break;
- case GTK_BUTTONBOX_END:
- childspacing = spacing;
- x = allocation->x + allocation->width
- - child_width * (nvis_children - n_secondaries)
- - spacing * (nvis_children - n_secondaries - 1)
- - GTK_CONTAINER (box)->border_width;
- secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
- break;
- case GTK_BUTTONBOX_CENTER:
- childspacing = spacing;
- x = allocation->x +
- (allocation->width
- - (child_width * (nvis_children - n_secondaries)
- + spacing * (nvis_children - n_secondaries - 1)))/2
- + (n_secondaries * child_width + n_secondaries * spacing)/2;
- secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
-
- y = allocation->y + (allocation->height - child_height) / 2;
- childspace = child_width + childspacing;
-
- children = GTK_BOX (box)->children;
-
- while (children)
- {
- child = children->data;
- children = children->next;
-
- if (GTK_WIDGET_VISIBLE (child->widget))
- {
- child_allocation.width = child_width;
- child_allocation.height = child_height;
- child_allocation.y = y;
-
- if (child->is_secondary)
- {
- child_allocation.x = secondary_x;
- secondary_x += childspace;
- }
- else
- {
- child_allocation.x = x;
- x += childspace;
- }
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- child_allocation.x = (allocation->x + allocation->width) - (child_allocation.x + child_width - allocation->x);
-
- gtk_widget_size_allocate (child->widget, &child_allocation);
- }
- }
-}
-
#define __GTK_HBUTTON_BOX_C__
#include "gtkaliasdef.c"
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index 3a413f0ed2..afbc229222 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -9014,12 +9014,14 @@ gtk_icon_view_accessible_model_row_changed (GtkTreeModel *tree_model,
GtkIconViewItem *item;
GtkIconViewAccessible *a11y_view;
GtkIconViewItemAccessible *a11y_item;
- gchar *name, *text;
+ const gchar *name;
+ gchar *text;
atk_obj = gtk_widget_get_accessible (GTK_WIDGET (user_data));
a11y_view = GTK_ICON_VIEW_ACCESSIBLE (atk_obj);
index = gtk_tree_path_get_indices(path)[0];
- a11y_item = gtk_icon_view_accessible_find_child (atk_obj, index);
+ a11y_item = GTK_ICON_VIEW_ITEM_ACCESSIBLE (
+ gtk_icon_view_accessible_find_child (atk_obj, index));
if (a11y_item)
{
diff --git a/gtk/gtkinfobar.c b/gtk/gtkinfobar.c
new file mode 100644
index 0000000000..c96bd84b52
--- /dev/null
+++ b/gtk/gtkinfobar.c
@@ -0,0 +1,1263 @@
+/*
+ * gtkinfobar.c
+ * This file is part of GTK+
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ *
+ * 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 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gedit Team, 2005. See the AUTHORS file for a
+ * list of people on the gtk Team.
+ * See the gedit ChangeLog files for a list of changes.
+ *
+ * Modified by the GTK+ team, 2008-2009.
+ */
+
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "gtkinfobar.h"
+#include "gtkaccessible.h"
+#include "gtkbuildable.h"
+#include "gtkbox.h"
+#include "gtkvbbox.h"
+#include "gtklabel.h"
+#include "gtkbutton.h"
+#include "gtkenums.h"
+#include "gtkbindings.h"
+#include "gtkdialog.h"
+#include "gtkintl.h"
+#include "gtkprivate.h"
+#include "gtkstock.h"
+#include "gdkkeysyms.h"
+#include "gtkalias.h"
+
+
+/**
+ * SECTION:gtkinfobar
+ * @short_description: Report important messages to the user
+ * @include: gtk/gtk.h
+ * @see_also: #GtkStatusbar, #GtkMessageDialog
+ *
+ * #GtkInfoBar is a widget that can be used to show messages to
+ * the user without showing a dialog. It is often temporarily shown
+ * at the top or bottom of a document. In contrast to #GtkDialog, which
+ * has a horizontal action area at the bottom, #GtkInfoBar has a
+ * vertical action area at the side.
+ *
+ * The API of #GtkInfoBar is very similar to #GtkDialog, allowing you
+ * to add buttons to the action area with gtk_info_bar_add_button() or
+ * gtk_info_bar_new_with_buttons(). The sensitivity of action widgets
+ * can be controlled with gtk_info_bar_set_response_sensitive().
+ * To add widgets to the main content area of a #GtkInfoBar, use
+ * gtk_info_bar_get_content_area() and add your widgets to the container.
+ *
+ * Similar to #GtkMessageDialog, the contents of a #GtkInfoBar can by
+ * classified as error message, warning, informational message, etc,
+ * by using gtk_info_bar_set_message_type(). GTK+ uses the message type
+ * to determine the background color of the message area.
+ *
+ * <example>
+ * <title>Simple GtkInfoBar usage.</title>
+ * <programlisting>
+ * /&ast; set up info bar &ast;/
+ * info_bar = gtk_info_bar_new ();
+ * gtk_widget_set_no_show_all (info_bar, TRUE);
+ * message_label = gtk_label_new ("");
+ * gtk_widget_show (message_label);
+ * content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
+ * gtk_container_add (GTK_CONTAINER (content_area), message_label);
+ * gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ * GTK_STOCK_OK, GTK_RESPONSE_OK);
+ * g_signal_connect (info_bar, "response",
+ * G_CALLBACK (gtk_widget_hide), NULL);
+ * gtk_table_attach (GTK_TABLE (table),
+ * info_bar,
+ * 0, 1, 2, 3,
+ * GTK_EXPAND | GTK_FILL, 0,
+ * 0, 0);
+ *
+ * /&ast; ... &ast;/
+ *
+ * /&ast; show an error message &ast;/
+ * gtk_label_set_text (GTK_LABEL (message_label), error_message);
+ * gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
+ * GTK_MESSAGE_ERROR);
+ * gtk_widget_show (info_bar);
+ * </programlisting>
+ * </example>
+ *
+ * <refsect2 id="GtkInfoBar-BUILDER-UI">
+ * <title>GtkInfoBar as GtkBuildable</title>
+ * <para>
+ * The GtkInfoBar implementation of the GtkBuildable interface exposes
+ * the content area and action area as internal children with the names
+ * "content_area" and "action_area".
+ * </para>
+ * <para>
+ * GtkInfoBar supports a custom &lt;action-widgets&gt; element, which
+ * can contain multiple &lt;action-widget&gt; elements. The "response"
+ * attribute specifies a numeric response, and the content of the element
+ * is the id of widget (which should be a child of the dialogs @action_area).
+ * </para>
+ * </refsect2>
+ */
+
+#define GTK_INFO_BAR_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+ GTK_TYPE_INFO_BAR, \
+ GtkInfoBarPrivate))
+
+enum
+{
+ PROP_0,
+ PROP_MESSAGE_TYPE
+};
+
+struct _GtkInfoBarPrivate
+{
+ GtkWidget *content_area;
+ GtkWidget *action_area;
+
+ GtkMessageType message_type;
+};
+
+typedef struct _ResponseData ResponseData;
+
+struct _ResponseData
+{
+ gint response_id;
+};
+
+enum
+{
+ RESPONSE,
+ CLOSE,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+
+static void gtk_info_bar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_info_bar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gtk_info_bar_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+static gboolean gtk_info_bar_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gtk_info_bar_buildable_interface_init (GtkBuildableIface *iface);
+static GObject *gtk_info_bar_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname);
+static gboolean gtk_info_bar_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data);
+static void gtk_info_bar_buildable_custom_finished (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer user_data);
+
+
+G_DEFINE_TYPE_WITH_CODE (GtkInfoBar, gtk_info_bar, GTK_TYPE_HBOX,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+ gtk_info_bar_buildable_interface_init))
+
+static void
+gtk_info_bar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkInfoBar *info_bar;
+ GtkInfoBarPrivate *priv;
+
+ info_bar = GTK_INFO_BAR (object);
+ priv = GTK_INFO_BAR_GET_PRIVATE (info_bar);
+
+ switch (prop_id)
+ {
+ case PROP_MESSAGE_TYPE:
+ gtk_info_bar_set_message_type (info_bar, g_value_get_enum (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_info_bar_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkInfoBar *info_bar;
+ GtkInfoBarPrivate *priv;
+
+ info_bar = GTK_INFO_BAR (object);
+ priv = GTK_INFO_BAR_GET_PRIVATE (info_bar);
+
+ switch (prop_id)
+ {
+ case PROP_MESSAGE_TYPE:
+ g_value_set_enum (value, gtk_info_bar_get_message_type (info_bar));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_info_bar_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gtk_info_bar_parent_class)->finalize (object);
+}
+
+static void
+response_data_free (gpointer data)
+{
+ g_slice_free (ResponseData, data);
+}
+
+static ResponseData *
+get_response_data (GtkWidget *widget,
+ gboolean create)
+{
+ ResponseData *ad = g_object_get_data (G_OBJECT (widget),
+ "gtk-info-bar-response-data");
+
+ if (ad == NULL && create)
+ {
+ ad = g_slice_new (ResponseData);
+
+ g_object_set_data_full (G_OBJECT (widget),
+ I_("gtk-info-bar-response-data"),
+ ad,
+ response_data_free);
+ }
+
+ return ad;
+}
+
+static GtkWidget *
+find_button (GtkInfoBar *info_bar,
+ gint response_id)
+{
+ GList *children, *list;
+ GtkWidget *child = NULL;
+
+ children = gtk_container_get_children (GTK_CONTAINER (info_bar->priv->action_area));
+
+ for (list = children; list; list = list->next)
+ {
+ ResponseData *rd = get_response_data (list->data, FALSE);
+
+ if (rd && rd->response_id == response_id)
+ {
+ child = list->data;
+ break;
+ }
+ }
+
+ g_list_free (children);
+
+ return child;
+}
+
+static void
+gtk_info_bar_close (GtkInfoBar *info_bar)
+{
+ if (!find_button (info_bar, GTK_RESPONSE_CANCEL))
+ return;
+
+ gtk_info_bar_response (GTK_INFO_BAR (info_bar),
+ GTK_RESPONSE_CANCEL);
+}
+
+static gboolean
+gtk_info_bar_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GtkInfoBarPrivate *priv = GTK_INFO_BAR_GET_PRIVATE (widget);
+ gboolean use_tooltip_style;
+ const char* type_detail[] = {
+ "infobar-info",
+ "infobar-warning",
+ "infobar-question",
+ "infobar-error",
+ "infobar"
+ };
+ const char *detail;
+
+ gtk_widget_style_get (widget,
+ "use-tooltip-style", &use_tooltip_style,
+ NULL);
+
+ if (use_tooltip_style)
+ detail = "toolbar";
+ else
+ detail = type_detail[priv->message_type];
+
+ gtk_paint_flat_box (widget->style,
+ widget->window,
+ GTK_STATE_NORMAL,
+ GTK_SHADOW_OUT,
+ NULL,
+ widget,
+ detail,
+ widget->allocation.x,
+ widget->allocation.y,
+ widget->allocation.width + 1,
+ widget->allocation.height + 1);
+
+ if (GTK_WIDGET_CLASS (gtk_info_bar_parent_class)->expose_event)
+ GTK_WIDGET_CLASS (gtk_info_bar_parent_class)->expose_event (widget, event);
+
+ return FALSE;
+}
+
+static void
+gtk_info_bar_class_init (GtkInfoBarClass *klass)
+{
+ GtkWidgetClass *widget_class;
+ GObjectClass *object_class;
+ GtkBindingSet *binding_set;
+
+ widget_class = GTK_WIDGET_CLASS (klass);
+ object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = gtk_info_bar_get_property;
+ object_class->set_property = gtk_info_bar_set_property;
+ object_class->finalize = gtk_info_bar_finalize;
+
+ widget_class->style_set = gtk_info_bar_style_set;
+ widget_class->expose_event = gtk_info_bar_expose;
+
+ klass->close = gtk_info_bar_close;
+
+ /**
+ * GtkInfoBar:message-type:
+ *
+ * The type of the message.
+ *
+ * The type is used to determine the colors to use in the info bar.
+ * The following symbolic color names can by used to customize
+ * these colors:
+ * "info_fg_color", "info_bg_color",
+ * "warning_fg_color", "warning_bg_color",
+ * "question_fg_color", "question_bg_color",
+ * "error_fg_color", "error_bg_color",
+ * "other_fg_color", "other_bg_color".
+ *
+ * Since: 2.18
+ */
+ g_object_class_install_property (object_class,
+ PROP_MESSAGE_TYPE,
+ g_param_spec_enum ("message-type",
+ P_("Message Type"),
+ P_("The type of message"),
+ GTK_TYPE_MESSAGE_TYPE,
+ GTK_MESSAGE_OTHER,
+ GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ /**
+ * GtkInfoBar::response:
+ * @info_bar: the object on which the signal is emitted
+ * @response_id: the response ID
+ *
+ * Emitted when an action widget is clicked or the application programmer
+ * calls gtk_dialog_response(). The @response_id depends on which action
+ * widget was clicked.
+ *
+ * Since: 2.18
+ */
+ signals[RESPONSE] = g_signal_new (I_("response"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkInfoBarClass, response),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ /**
+ * GtkInfoBar::close:
+ *
+ * The ::close signal is a
+ * <link linkend="keybinding-signals">keybinding signal</link>
+ * which gets emitted when the user uses a keybinding to dismiss
+ * the info bar.
+ *
+ * The default binding for this signal is the Escape key.
+ *
+ * Since: 2.18
+ */
+ signals[CLOSE] = g_signal_new (I_("close"),
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkInfoBarClass, close),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * GtkInfoBar:content-area-border:
+ *
+ * The width of the border around the content
+ * content area of the info bar.
+ *
+ * Since: 2.18
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("content-area-border",
+ P_("Content area border"),
+ P_("Width of border around the content area"),
+ 0,
+ G_MAXINT,
+ 8,
+ GTK_PARAM_READABLE));
+
+ /**
+ * GtkInfoBar:content-area-spacing:
+ *
+ * The default spacing used between elements of the
+ * content area of the info bar.
+ *
+ * Since: 2.18
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("content-area-spacing",
+ P_("Content area spacing"),
+ P_("Spacing between elements of the area"),
+ 0,
+ G_MAXINT,
+ 16,
+ GTK_PARAM_READABLE));
+
+ /**
+ * GtkInfoBar:button-spacing:
+ *
+ * Spacing between buttons in the action area of the info bar.
+ *
+ * Since: 2.18
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("button-spacing",
+ P_("Button spacing"),
+ P_("Spacing between buttons"),
+ 0,
+ G_MAXINT,
+ 6,
+ GTK_PARAM_READABLE));
+
+ /**
+ * GtkInfoBar:action-area-border:
+ *
+ * Width of the border around the action area of the info bar.
+ *
+ * Since: 2.18
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("action-area-border",
+ P_("Action area border"),
+ P_("Width of border around the action area"),
+ 0,
+ G_MAXINT,
+ 5,
+ GTK_PARAM_READABLE));
+
+ /**
+ * GtkInfoBar:use-tooltip-style:
+ *
+ * When %TRUE, use the same background/foreground color as #GtkTooltip.
+ * Otherwise, GTK+ uses #GtkInfoBar::message-type to determine which
+ * symbolic colors to use.
+ *
+ * Since: 2.18
+ */
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_boolean ("use-tooltip-style",
+ P_("Use tooltip style"),
+ P_("Wether to use the same style as GtkTooltip for drawing"),
+ TRUE,
+ GTK_PARAM_READABLE));
+
+ binding_set = gtk_binding_set_by_class (klass);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "close", 0);
+
+ g_type_class_add_private (object_class, sizeof (GtkInfoBarPrivate));
+}
+
+static void
+gtk_info_bar_update_colors (GtkInfoBar *info_bar)
+{
+ GtkWidget *widget = (GtkWidget*)info_bar;
+ GtkInfoBarPrivate *priv;
+ GdkColor default_border_color = { 0, 0xb800, 0xad00, 0x9d00 };
+ GdkColor default_fill_color = { 0, 0xff00, 0xff00, 0xbf00 };
+ GdkColor *fg, *bg;
+ GdkColor sym_fg, sym_bg;
+ gboolean use_tooltip_style;
+ GtkStyle *style;
+ const char* fg_color_name[] = {
+ "info_fg_color",
+ "warning_fg_color",
+ "question_fg_color",
+ "error_fg_color",
+ "other_fg_color"
+ };
+ const char* bg_color_name[] = {
+ "info_bg_color",
+ "warning_bg_color",
+ "question_bg_color",
+ "error_bg_color",
+ "other_bg_color"
+ };
+ gboolean has_color;
+
+ priv = GTK_INFO_BAR_GET_PRIVATE (info_bar);
+ style = gtk_widget_get_style (widget);
+
+ gtk_widget_style_get (widget,
+ "use-tooltip-style", &use_tooltip_style, NULL);
+
+ has_color = FALSE;
+
+ if (gtk_style_lookup_color (style, fg_color_name[priv->message_type], &sym_fg) &&
+ gtk_style_lookup_color (style, bg_color_name[priv->message_type], &sym_bg))
+ {
+ fg = &sym_fg;
+ bg = &sym_bg;
+ has_color = TRUE;
+ }
+ else if (use_tooltip_style)
+ {
+ style = gtk_rc_get_style_by_paths (gtk_widget_get_settings (widget),
+ "gtk-tooltip", "GtkTooltip", G_TYPE_NONE);
+ if (style)
+ {
+ fg = &style->fg[GTK_STATE_NORMAL];
+ bg = &style->bg[GTK_STATE_NORMAL];
+ }
+ else
+ {
+ fg = &default_border_color;
+ bg = &default_fill_color;
+ }
+
+ has_color = TRUE;
+ }
+
+ if (has_color)
+ {
+ if (!gdk_color_equal (bg, &widget->style->bg[GTK_STATE_NORMAL]))
+ gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, bg);
+ if (!gdk_color_equal (fg, &widget->style->fg[GTK_STATE_NORMAL]))
+ gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, fg);
+ }
+}
+
+static void
+gtk_info_bar_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ GtkInfoBar *info_bar = GTK_INFO_BAR (widget);
+ gint button_spacing;
+ gint action_area_border;
+ gint content_area_spacing;
+ gint content_area_border;
+
+ gtk_widget_style_get (widget,
+ "button-spacing", &button_spacing,
+ "action-area-border", &action_area_border,
+ "content-area-spacing", &content_area_spacing,
+ "content-area-border", &content_area_border,
+ NULL);
+
+ gtk_box_set_spacing (GTK_BOX (info_bar->priv->action_area), button_spacing);
+ gtk_container_set_border_width (GTK_CONTAINER (info_bar->priv->action_area),
+ action_area_border);
+ gtk_box_set_spacing (GTK_BOX (info_bar->priv->content_area), content_area_spacing);
+ gtk_container_set_border_width (GTK_CONTAINER (info_bar->priv->content_area),
+ content_area_border);
+
+ gtk_info_bar_update_colors (info_bar);
+}
+
+static void
+gtk_info_bar_init (GtkInfoBar *info_bar)
+{
+ GtkWidget *content_area;
+ GtkWidget *action_area;
+
+ gtk_widget_push_composite_child ();
+
+ info_bar->priv = GTK_INFO_BAR_GET_PRIVATE (info_bar);
+
+ content_area = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (content_area);
+ gtk_box_pack_start (GTK_BOX (info_bar), content_area, TRUE, TRUE, 0);
+
+ action_area = gtk_vbutton_box_new ();
+ gtk_widget_show (action_area);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area), GTK_BUTTONBOX_END);
+ gtk_box_pack_start (GTK_BOX (info_bar), action_area, FALSE, TRUE, 0);
+
+ gtk_widget_set_app_paintable (GTK_WIDGET (info_bar), TRUE);
+
+ info_bar->priv->content_area = content_area;
+ info_bar->priv->action_area = action_area;
+
+ gtk_widget_pop_composite_child ();
+}
+
+static GtkBuildableIface *parent_buildable_iface;
+
+static void
+gtk_info_bar_buildable_interface_init (GtkBuildableIface *iface)
+{
+ parent_buildable_iface = g_type_interface_peek_parent (iface);
+ iface->get_internal_child = gtk_info_bar_buildable_get_internal_child;
+ iface->custom_tag_start = gtk_info_bar_buildable_custom_tag_start;
+ iface->custom_finished = gtk_info_bar_buildable_custom_finished;
+}
+
+static GObject *
+gtk_info_bar_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname)
+{
+ if (strcmp (childname, "content_area") == 0)
+ return G_OBJECT (GTK_INFO_BAR (buildable)->priv->content_area);
+ else if (strcmp (childname, "action_area") == 0)
+ return G_OBJECT (GTK_INFO_BAR (buildable)->priv->action_area);
+
+ return parent_buildable_iface->get_internal_child (buildable,
+ builder,
+ childname);
+}
+
+static gint
+get_response_for_widget (GtkInfoBar *info_bar,
+ GtkWidget *widget)
+{
+ ResponseData *rd;
+
+ rd = get_response_data (widget, FALSE);
+ if (!rd)
+ return GTK_RESPONSE_NONE;
+ else
+ return rd->response_id;
+}
+
+static void
+action_widget_activated (GtkWidget *widget,
+ GtkInfoBar *info_bar)
+{
+ gint response_id;
+
+ response_id = get_response_for_widget (info_bar, widget);
+ gtk_info_bar_response (info_bar, response_id);
+}
+
+/**
+ * gtk_info_bar_add_action_widget:
+ * @info_bar: a #GtkInfoBar
+ * @child: an activatable widget
+ * @response_id: response ID for @child
+ *
+ * Add an activatable widget to the action area of a #GtkInfoBar,
+ * connecting a signal handler that will emit the #GtkInfoBar::response
+ * signal on the message area when the widget is activated. The widget
+ * is appended to the end of the message areas action area.
+ *
+ * Since: 2.18
+ */
+void
+gtk_info_bar_add_action_widget (GtkInfoBar *info_bar,
+ GtkWidget *child,
+ gint response_id)
+{
+ ResponseData *ad;
+ guint signal_id;
+
+ g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ ad = get_response_data (child, TRUE);
+
+ ad->response_id = response_id;
+
+ if (GTK_IS_BUTTON (child))
+ signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
+ else
+ signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal;
+
+ if (signal_id)
+ {
+ GClosure *closure;
+
+ closure = g_cclosure_new_object (G_CALLBACK (action_widget_activated),
+ G_OBJECT (info_bar));
+ g_signal_connect_closure_by_id (child, signal_id, 0, closure, FALSE);
+ }
+ else
+ g_warning ("Only 'activatable' widgets can be packed into the action area of a GtkInfoBar");
+
+ gtk_box_pack_end (GTK_BOX (info_bar->priv->action_area),
+ child, FALSE, FALSE, 0);
+ if (response_id == GTK_RESPONSE_HELP)
+ gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (info_bar->priv->action_area),
+ child, TRUE);
+}
+
+/**
+ * gtk_info_bar_get_action_area:
+ * @info_bar: a #GtkInfoBar
+ *
+ * Returns the action area of @info_bar.
+ *
+ * Returns: the action area.
+ *
+ * Since: 2.18
+ */
+GtkWidget*
+gtk_info_bar_get_action_area (GtkInfoBar *info_bar)
+{
+ g_return_val_if_fail (GTK_IS_INFO_BAR (info_bar), NULL);
+
+ return info_bar->priv->action_area;
+}
+
+/**
+ * gtk_info_bar_get_content_area:
+ * @info_bar: a #GtkInfoBar
+ *
+ * Returns the content area of @info_bar.
+ *
+ * Returns: the content area.
+ *
+ * Since: 2.18
+ */
+GtkWidget*
+gtk_info_bar_get_content_area (GtkInfoBar *info_bar)
+{
+ g_return_val_if_fail (GTK_IS_INFO_BAR (info_bar), NULL);
+
+ return info_bar->priv->content_area;
+}
+
+/**
+ * gtk_info_bar_add_button:
+ * @info_bar: a #GtkInfoBar
+ * @button_text: text of button, or stock ID
+ * @response_id: response ID for the button
+ *
+ * Adds a button with the given text (or a stock button, if button_text
+ * is a stock ID) and sets things up so that clicking the button will emit
+ * the "response" signal with the given response_id. The button is appended
+ * to the end of the info bars's action area. The button widget is
+ * returned, but usually you don't need it.
+ *
+ * Returns: the button widget that was added
+ *
+ * Since: 2.18
+ */
+GtkWidget*
+gtk_info_bar_add_button (GtkInfoBar *info_bar,
+ const gchar *button_text,
+ gint response_id)
+{
+ GtkWidget *button;
+
+ g_return_val_if_fail (GTK_IS_INFO_BAR (info_bar), NULL);
+ g_return_val_if_fail (button_text != NULL, NULL);
+
+ button = gtk_button_new_from_stock (button_text);
+
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+
+ gtk_widget_show (button);
+
+ gtk_info_bar_add_action_widget (info_bar, button, response_id);
+
+ return button;
+}
+
+static void
+add_buttons_valist (GtkInfoBar *info_bar,
+ const gchar *first_button_text,
+ va_list args)
+{
+ const gchar* text;
+ gint response_id;
+
+ g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
+
+ if (first_button_text == NULL)
+ return;
+
+ text = first_button_text;
+ response_id = va_arg (args, gint);
+
+ while (text != NULL)
+ {
+ gtk_info_bar_add_button (info_bar, text, response_id);
+
+ text = va_arg (args, gchar*);
+ if (text == NULL)
+ break;
+
+ response_id = va_arg (args, int);
+ }
+}
+
+/**
+ * gtk_info_bar_add_buttons:
+ * @info_bar: a #GtkInfoBar
+ * @first_button_text: button text or stock ID
+ * @...: response ID for first button, then more text-response_id pairs,
+ * ending with %NULL
+ *
+ * Adds more buttons, same as calling gtk_info_bar_add_button()
+ * repeatedly. The variable argument list should be %NULL-terminated
+ * as with gtk_info_bar_new_with_buttons(). Each button must have both
+ * text and response ID.
+ *
+ * Since: 2.18
+ */
+void
+gtk_info_bar_add_buttons (GtkInfoBar *info_bar,
+ const gchar *first_button_text,
+ ...)
+{
+ va_list args;
+
+ va_start (args, first_button_text);
+ add_buttons_valist (info_bar, first_button_text, args);
+ va_end (args);
+}
+
+/**
+ * gtk_info_bar_new:
+ *
+ * Creates a new #GtkInfoBar object.
+ *
+ * Returns: a new #GtkInfoBar object
+ *
+ * Since: 2.18
+ */
+GtkWidget *
+gtk_info_bar_new (void)
+{
+ return g_object_new (GTK_TYPE_INFO_BAR, NULL);
+}
+
+/**
+ * gtk_info_bar_new_with_buttons:
+ * @first_button_text: stock ID or text to go in first button, or %NULL
+ * @...: response ID for first button, then additional buttons, ending
+ * with %NULL
+ *
+ * Creates a new #GtkInfoBar with buttons. Button text/response ID
+ * pairs should be listed, with a %NULL pointer ending the list.
+ * Button text can be either a stock ID such as %GTK_STOCK_OK, or
+ * some arbitrary text. A response ID can be any positive number,
+ * or one of the values in the #GtkResponseType enumeration. If the
+ * user clicks one of these dialog buttons, GtkInfoBar will emit
+ * the "response" signal with the corresponding response ID.
+ *
+ * Returns: a new #GtkInfoBar
+ */
+GtkWidget*
+gtk_info_bar_new_with_buttons (const gchar *first_button_text,
+ ...)
+{
+ GtkInfoBar *info_bar;
+ va_list args;
+
+ info_bar = GTK_INFO_BAR (gtk_info_bar_new ());
+
+ va_start (args, first_button_text);
+ add_buttons_valist (info_bar, first_button_text, args);
+ va_end (args);
+
+ return GTK_WIDGET (info_bar);
+}
+
+/**
+ * gtk_info_bar_set_response_sensitive:
+ * @info_bar: a #GtkInfoBar
+ * @response_id: a response ID
+ * @setting: TRUE for sensitive
+ *
+ * Calls gtk_widget_set_sensitive (widget, setting) for each
+ * widget in the info bars's action area with the given response_id.
+ * A convenient way to sensitize/desensitize dialog buttons.
+ *
+ * Since: 2.18
+ */
+void
+gtk_info_bar_set_response_sensitive (GtkInfoBar *info_bar,
+ gint response_id,
+ gboolean setting)
+{
+ GList *children, *list;
+
+ g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
+
+ children = gtk_container_get_children (GTK_CONTAINER (info_bar->priv->action_area));
+
+ for (list = children; list; list = list->next)
+ {
+ GtkWidget *widget = list->data;
+ ResponseData *rd = get_response_data (widget, FALSE);
+
+ if (rd && rd->response_id == response_id)
+ gtk_widget_set_sensitive (widget, setting);
+ }
+
+ g_list_free (children);
+}
+
+/**
+ * gtk_info_bar_set_default_response:
+ * @info_bar: a #GtkInfoBar
+ * @response_id: a response ID
+ *
+ * Sets the last widget in the info bar's action area with
+ * the given response_id as the default widget for the dialog.
+ * Pressing "Enter" normally activates the default widget.
+ *
+ * Since: 2.18
+ */
+void
+gtk_info_bar_set_default_response (GtkInfoBar *info_bar,
+ gint response_id)
+{
+ GList *children, *list;
+
+ g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
+
+ children = gtk_container_get_children (GTK_CONTAINER (info_bar->priv->action_area));
+
+ for (list = children; list; list = list->next)
+ {
+ GtkWidget *widget = list->data;
+ ResponseData *rd = get_response_data (widget, FALSE);
+
+ if (rd && rd->response_id == response_id)
+ gtk_widget_grab_default (widget);
+ }
+
+ g_list_free (children);
+}
+
+/**
+ * gtk_info_bar_response:
+ * @info_bar: a #GtkInfoBar
+ * @response_id: a response ID
+ *
+ * Emits the 'response' signal with the given @response_id.
+ *
+ * Since: 2.18
+ */
+void
+gtk_info_bar_response (GtkInfoBar *info_bar,
+ gint response_id)
+{
+ g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
+
+ g_signal_emit (info_bar, signals[RESPONSE], 0, response_id);
+}
+
+typedef struct
+{
+ gchar *widget_name;
+ gchar *response_id;
+} ActionWidgetInfo;
+
+typedef struct
+{
+ GtkInfoBar *info_bar;
+ GtkBuilder *builder;
+ GSList *items;
+ gchar *response;
+} ActionWidgetsSubParserData;
+
+static void
+attributes_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ ActionWidgetsSubParserData *parser_data = (ActionWidgetsSubParserData*)user_data;
+ guint i;
+
+ if (strcmp (element_name, "action-widget") == 0)
+ {
+ for (i = 0; names[i]; i++)
+ if (strcmp (names[i], "response") == 0)
+ parser_data->response = g_strdup (values[i]);
+ }
+ else if (strcmp (element_name, "action-widgets") == 0)
+ return;
+ else
+ g_warning ("Unsupported tag for GtkInfoBar: %s\n", element_name);
+}
+
+static void
+attributes_text_element (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ ActionWidgetsSubParserData *parser_data = (ActionWidgetsSubParserData*)user_data;
+ ActionWidgetInfo *item;
+
+ if (!parser_data->response)
+ return;
+
+ item = g_new (ActionWidgetInfo, 1);
+ item->widget_name = g_strndup (text, text_len);
+ item->response_id = parser_data->response;
+ parser_data->items = g_slist_prepend (parser_data->items, item);
+ parser_data->response = NULL;
+}
+
+static const GMarkupParser attributes_parser =
+{
+ attributes_start_element,
+ NULL,
+ attributes_text_element,
+};
+
+gboolean
+gtk_info_bar_buildable_custom_tag_start (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ GMarkupParser *parser,
+ gpointer *data)
+{
+ ActionWidgetsSubParserData *parser_data;
+
+ if (child)
+ return FALSE;
+
+ if (strcmp (tagname, "action-widgets") == 0)
+ {
+ parser_data = g_slice_new0 (ActionWidgetsSubParserData);
+ parser_data->info_bar = GTK_INFO_BAR (buildable);
+ parser_data->items = NULL;
+
+ *parser = attributes_parser;
+ *data = parser_data;
+ return TRUE;
+ }
+
+ return parent_buildable_iface->custom_tag_start (buildable, builder, child,
+ tagname, parser, data);
+}
+
+static void
+gtk_info_bar_buildable_custom_finished (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ GObject *child,
+ const gchar *tagname,
+ gpointer user_data)
+{
+ GSList *l;
+ ActionWidgetsSubParserData *parser_data;
+ GObject *object;
+ GtkInfoBar *info_bar;
+ ResponseData *ad;
+ guint signal_id;
+
+ if (strcmp (tagname, "action-widgets"))
+ {
+ parent_buildable_iface->custom_finished (buildable, builder, child,
+ tagname, user_data);
+ return;
+ }
+
+ info_bar = GTK_INFO_BAR (buildable);
+ parser_data = (ActionWidgetsSubParserData*)user_data;
+ parser_data->items = g_slist_reverse (parser_data->items);
+
+ for (l = parser_data->items; l; l = l->next)
+ {
+ ActionWidgetInfo *item = l->data;
+
+ object = gtk_builder_get_object (builder, item->widget_name);
+ if (!object)
+ {
+ g_warning ("Unknown object %s specified in action-widgets of %s",
+ item->widget_name,
+ gtk_buildable_get_name (GTK_BUILDABLE (buildable)));
+ continue;
+ }
+
+ ad = get_response_data (GTK_WIDGET (object), TRUE);
+ ad->response_id = atoi (item->response_id);
+
+ if (GTK_IS_BUTTON (object))
+ signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
+ else
+ signal_id = GTK_WIDGET_GET_CLASS (object)->activate_signal;
+
+ if (signal_id)
+ {
+ GClosure *closure;
+
+ closure = g_cclosure_new_object (G_CALLBACK (action_widget_activated),
+ G_OBJECT (info_bar));
+ g_signal_connect_closure_by_id (object,
+ signal_id,
+ 0,
+ closure,
+ FALSE);
+ }
+
+ if (ad->response_id == GTK_RESPONSE_HELP)
+ gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (info_bar->priv->action_area),
+ GTK_WIDGET (object), TRUE);
+
+ g_free (item->widget_name);
+ g_free (item->response_id);
+ g_free (item);
+ }
+ g_slist_free (parser_data->items);
+ g_slice_free (ActionWidgetsSubParserData, parser_data);
+}
+
+/**
+ * gtk_info_bar_set_message_type:
+ * @info_bar: a #GtkInfoBar
+ * @message_type: a #GtkMessageType
+ *
+ * Sets the message type of the message area.
+ * GTK+ uses this type to determine what color to use
+ * when drawing the message area.
+ *
+ * Since: 2.18
+ */
+void
+gtk_info_bar_set_message_type (GtkInfoBar *info_bar,
+ GtkMessageType message_type)
+{
+ GtkInfoBarPrivate *priv;
+ AtkObject *atk_obj;
+
+ g_return_if_fail (GTK_IS_INFO_BAR (info_bar));
+
+ priv = GTK_INFO_BAR_GET_PRIVATE (info_bar);
+
+ if (priv->message_type != message_type)
+ {
+ priv->message_type = message_type;
+
+ gtk_info_bar_update_colors (info_bar);
+ gtk_widget_queue_draw (GTK_WIDGET (info_bar));
+
+ atk_obj = gtk_widget_get_accessible (GTK_WIDGET (info_bar));
+ if (GTK_IS_ACCESSIBLE (atk_obj))
+ {
+ GtkStockItem item;
+ const char *stock_id = NULL;
+
+ atk_object_set_role (atk_obj, ATK_ROLE_ALERT);
+
+ switch (message_type)
+ {
+ case GTK_MESSAGE_INFO:
+ stock_id = GTK_STOCK_DIALOG_INFO;
+ break;
+
+ case GTK_MESSAGE_QUESTION:
+ stock_id = GTK_STOCK_DIALOG_QUESTION;
+ break;
+
+ case GTK_MESSAGE_WARNING:
+ stock_id = GTK_STOCK_DIALOG_WARNING;
+ break;
+
+ case GTK_MESSAGE_ERROR:
+ stock_id = GTK_STOCK_DIALOG_ERROR;
+ break;
+
+ case GTK_MESSAGE_OTHER:
+ break;
+
+ default:
+ g_warning ("Unknown GtkMessageType %u", message_type);
+ break;
+ }
+
+ if (stock_id)
+ {
+ gtk_stock_lookup (stock_id, &item);
+ atk_object_set_name (atk_obj, item.label);
+ }
+ }
+
+ g_object_notify (G_OBJECT (info_bar), "message-type");
+ }
+}
+
+/**
+ * gtk_info_bar_get_message_type:
+ * @info_bar: a #GtkInfoBar
+ *
+ * Returns the message type of the message area.
+ *
+ * Returns: the message type of the message area.
+ *
+ * Since: 2.18
+ */
+GtkMessageType
+gtk_info_bar_get_message_type (GtkInfoBar *info_bar)
+{
+ GtkInfoBarPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_INFO_BAR (info_bar), GTK_MESSAGE_OTHER);
+
+ priv = GTK_INFO_BAR_GET_PRIVATE (info_bar);
+
+ return priv->message_type;
+}
+
+
+#define __GTK_INFO_BAR_C__
+#include "gtkaliasdef.c"
diff --git a/gtk/gtkinfobar.h b/gtk/gtkinfobar.h
new file mode 100644
index 0000000000..cbc206a120
--- /dev/null
+++ b/gtk/gtkinfobar.h
@@ -0,0 +1,116 @@
+/*
+ * gtkinfobar.h
+ * This file is part of GTK+
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ *
+ * 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 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the gedit Team, 2005. See the gedit AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the gedit ChangeLog files for a list of changes.
+ *
+ * Modified by the GTK+ Team, 2008-2009.
+ */
+
+#ifndef __GTK_INFO_BAR_H__
+#define __GTK_INFO_BAR_H__
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkenums.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define GTK_TYPE_INFO_BAR (gtk_info_bar_get_type())
+#define GTK_INFO_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INFO_BAR, GtkInfoBar))
+#define GTK_INFO_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INFO_BAR, GtkInfoBarClass))
+#define GTK_IS_INFO_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INFO_BAR))
+#define GTK_IS_INFO_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_INFO_BAR))
+#define GTK_INFO_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INFO_BAR, GtkInfoBarClass))
+
+
+typedef struct _GtkInfoBarPrivate GtkInfoBarPrivate;
+typedef struct _GtkInfoBarClass GtkInfoBarClass;
+typedef struct _GtkInfoBar GtkInfoBar;
+
+
+struct _GtkInfoBar
+{
+ GtkHBox parent;
+
+ /*< private > */
+ GtkInfoBarPrivate *priv;
+};
+
+
+struct _GtkInfoBarClass
+{
+ GtkHBoxClass parent_class;
+
+ /* Signals */
+ void (* response) (GtkInfoBar *info_bar, gint response_id);
+
+ /* Keybinding signals */
+ void (* close) (GtkInfoBar *info_bar);
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+ void (*_gtk_reserved5) (void);
+ void (*_gtk_reserved6) (void);
+};
+
+GType gtk_info_bar_get_type (void) G_GNUC_CONST;
+GtkWidget *gtk_info_bar_new (void);
+
+GtkWidget *gtk_info_bar_new_with_buttons (const gchar *first_button_text,
+ ...);
+
+GtkWidget *gtk_info_bar_get_action_area (GtkInfoBar *info_bar);
+GtkWidget *gtk_info_bar_get_content_area (GtkInfoBar *info_bar);
+void gtk_info_bar_add_action_widget (GtkInfoBar *info_bar,
+ GtkWidget *child,
+ gint response_id);
+GtkWidget *gtk_info_bar_add_button (GtkInfoBar *info_bar,
+ const gchar *button_text,
+ gint response_id);
+void gtk_info_bar_add_buttons (GtkInfoBar *info_bar,
+ const gchar *first_button_text,
+ ...);
+void gtk_info_bar_set_response_sensitive (GtkInfoBar *info_bar,
+ gint response_id,
+ gboolean setting);
+void gtk_info_bar_set_default_response (GtkInfoBar *info_bar,
+ gint response_id);
+
+/* Emit response signal */
+void gtk_info_bar_response (GtkInfoBar *info_bar,
+ gint response_id);
+
+void gtk_info_bar_set_message_type (GtkInfoBar *info_bar,
+ GtkMessageType message_type);
+GtkMessageType gtk_info_bar_get_message_type (GtkInfoBar *info_bar);
+
+G_END_DECLS
+
+#endif /* __GTK_INFO_BAR_H__ */
diff --git a/gtk/gtkmessagedialog.h b/gtk/gtkmessagedialog.h
index 947773c76d..1bb1ec5fc2 100644
--- a/gtk/gtkmessagedialog.h
+++ b/gtk/gtkmessagedialog.h
@@ -32,20 +32,12 @@
#define __GTK_MESSAGE_DIALOG_H__
#include <gtk/gtkdialog.h>
+#include <gtk/gtkenums.h>
G_BEGIN_DECLS
typedef enum
{
- GTK_MESSAGE_INFO,
- GTK_MESSAGE_WARNING,
- GTK_MESSAGE_QUESTION,
- GTK_MESSAGE_ERROR,
- GTK_MESSAGE_OTHER
-} GtkMessageType;
-
-typedef enum
-{
GTK_BUTTONS_NONE,
GTK_BUTTONS_OK,
GTK_BUTTONS_CLOSE,
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index a1a5093bd2..a9d2da3900 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -330,7 +330,13 @@ gtk_path_bar_size_request (GtkWidget *widget,
{
button_data = BUTTON_DATA (list->data);
gtk_widget_size_request (button_data->button, &child_requisition);
- requisition->width = MAX (child_requisition.width, requisition->width);
+
+ if (button_data->type == NORMAL_BUTTON)
+ /* Use 2*Height as button width because of ellipsized label. */
+ requisition->width = MAX (child_requisition.height * 2, requisition->width);
+ else
+ requisition->width = MAX (child_requisition.width, requisition->width);
+
requisition->height = MAX (child_requisition.height, requisition->height);
}
@@ -455,7 +461,6 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
gint border_width;
gboolean need_sliders = FALSE;
gint up_slider_offset = 0;
- gint down_slider_offset = 0;
widget->allocation = *allocation;
@@ -572,9 +577,14 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
for (list = first_button; list; list = list->prev)
{
- child = BUTTON_DATA (list->data)->button;
+ ButtonData *button_data;
+
+ button_data = BUTTON_DATA (list->data);
+ child = button_data->button;
+
+ child_allocation.width = MIN (child->requisition.width,
+ allocation_width - (path_bar->spacing + path_bar->slider_width) * 2);
- child_allocation.width = child->requisition.width;
if (direction == GTK_TEXT_DIR_RTL)
child_allocation.x -= child_allocation.width;
@@ -591,21 +601,21 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
break;
}
- gtk_widget_set_child_visible (BUTTON_DATA (list->data)->button, TRUE);
+ if (child_allocation.width < child->requisition.width)
+ {
+ if (!gtk_widget_get_has_tooltip (child))
+ gtk_widget_set_tooltip_text (child, button_data->dir_name);
+ }
+ else if (gtk_widget_get_has_tooltip (child))
+ gtk_widget_set_tooltip_text (child, NULL);
+
+ gtk_widget_set_child_visible (child, TRUE);
gtk_widget_size_allocate (child, &child_allocation);
if (direction == GTK_TEXT_DIR_RTL)
- {
- child_allocation.x -= path_bar->spacing;
- down_slider_offset = child_allocation.x - widget->allocation.x - path_bar->slider_width;
- down_slider_offset = border_width;
- }
+ child_allocation.x -= path_bar->spacing;
else
- {
- down_slider_offset = child_allocation.x - widget->allocation.x;
- down_slider_offset = allocation->width - border_width - path_bar->slider_width;
- child_allocation.x += child_allocation.width + path_bar->spacing;
- }
+ child_allocation.x += child_allocation.width + path_bar->spacing;
}
/* Now we go hide all the widgets that don't fit */
while (list)
@@ -633,7 +643,14 @@ gtk_path_bar_size_allocate (GtkWidget *widget,
if (need_sliders)
{
child_allocation.width = path_bar->slider_width;
- child_allocation.x = down_slider_offset + allocation->x;
+
+ if (direction == GTK_TEXT_DIR_RTL)
+ child_allocation.x = border_width;
+ else
+ child_allocation.x = allocation->width - border_width - path_bar->slider_width;
+
+ child_allocation.x += allocation->x;
+
gtk_widget_size_allocate (path_bar->down_slider_button, &child_allocation);
gtk_widget_set_child_visible (path_bar->down_slider_button, TRUE);
@@ -775,11 +792,7 @@ gtk_path_bar_scroll_down (GtkPathBar *path_bar)
{
GList *list;
GList *down_button = NULL;
- GList *up_button = NULL;
gint space_available;
- gint space_needed;
- gint border_width;
- GtkTextDirection direction;
if (path_bar->ignore_click)
{
@@ -795,9 +808,6 @@ gtk_path_bar_scroll_down (GtkPathBar *path_bar)
gtk_widget_queue_resize (GTK_WIDGET (path_bar));
- border_width = GTK_CONTAINER (path_bar)->border_width;
- direction = gtk_widget_get_direction (GTK_WIDGET (path_bar));
-
/* We find the button at the 'down' end that we have to make
* visible */
for (list = path_bar->button_list; list; list = list->next)
@@ -808,37 +818,24 @@ gtk_path_bar_scroll_down (GtkPathBar *path_bar)
break;
}
}
-
- /* Find the last visible button on the 'up' end
- */
- for (list = g_list_last (path_bar->button_list); list; list = list->prev)
- {
- if (gtk_widget_get_child_visible (BUTTON_DATA (list->data)->button))
- {
- up_button = list;
- break;
- }
- }
- /* We check if down_button might be NULL in cases where the pathbar's horizontal size is smaller
- * than the button and it doesn't get displayed. e.g., on Windows it might be "My Documents and Settings"
+ space_available = (GTK_WIDGET (path_bar)->allocation.width
+ - 2 * GTK_CONTAINER (path_bar)->border_width
+ - 2 * path_bar->spacing - 2 * path_bar->slider_width
+ - BUTTON_DATA (down_button->data)->button->allocation.width);
+ path_bar->first_scrolled_button = down_button;
+
+ /* We have space_available free space that's not being used.
+ * So we walk down from the end, adding buttons until we use all free space.
*/
- space_needed = down_button ? BUTTON_DATA (down_button->data)->button->allocation.width : 0 + path_bar->spacing;
- if (direction == GTK_TEXT_DIR_RTL)
- space_available = path_bar->down_slider_button->allocation.x - GTK_WIDGET (path_bar)->allocation.x;
- else
- space_available = (GTK_WIDGET (path_bar)->allocation.x + GTK_WIDGET (path_bar)->allocation.width - border_width) -
- (path_bar->down_slider_button->allocation.x + path_bar->down_slider_button->allocation.width);
-
- /* We have space_available extra space that's not being used. We
- * need space_needed space to make the button fit. So we walk down
- * from the end, removing buttons until we get all the space we
- * need. */
- while (space_available < space_needed)
+ while (space_available > 0)
{
- space_available += BUTTON_DATA (up_button->data)->button->allocation.width + path_bar->spacing;
- up_button = up_button->prev;
- path_bar->first_scrolled_button = up_button;
+ path_bar->first_scrolled_button = down_button;
+ down_button = down_button->next;
+ if (!down_button)
+ break;
+ space_available -= (BUTTON_DATA (down_button->data)->button->allocation.width
+ + path_bar->spacing);
}
}
@@ -1484,6 +1481,7 @@ make_directory_button (GtkPathBar *path_bar,
case NORMAL_BUTTON:
default:
button_data->label = gtk_label_new (NULL);
+ gtk_label_set_ellipsize (GTK_LABEL (button_data->label), PANGO_ELLIPSIZE_END);
label_alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
gtk_container_add (GTK_CONTAINER (label_alignment), button_data->label);
child = label_alignment;
@@ -1663,7 +1661,7 @@ gtk_path_bar_get_info_callback (GCancellable *cancellable,
}
display_name = g_file_info_get_display_name (info);
- is_hidden = g_file_info_get_is_hidden (info);
+ is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
gtk_widget_push_composite_child ();
button_data = make_directory_button (file_info->path_bar, display_name,
@@ -1691,7 +1689,7 @@ gtk_path_bar_get_info_callback (GCancellable *cancellable,
file_info->path_bar->get_info_cancellable =
_gtk_file_system_get_info (file_info->path_bar->file_system,
file_info->file,
- "standard::display-name,standard::is-hidden",
+ "standard::display-name,standard::is-hidden,standard::is-backup",
gtk_path_bar_get_info_callback,
file_info);
}
@@ -1729,7 +1727,7 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar,
path_bar->get_info_cancellable =
_gtk_file_system_get_info (path_bar->file_system,
info->file,
- "standard::display-name,standard::is-hidden",
+ "standard::display-name,standard::is-hidden,standard::is-backup",
gtk_path_bar_get_info_callback,
info);
diff --git a/gtk/gtkprintoperation-private.h b/gtk/gtkprintoperation-private.h
index 718f16df6f..8c800eaea5 100644
--- a/gtk/gtkprintoperation-private.h
+++ b/gtk/gtkprintoperation-private.h
@@ -54,6 +54,8 @@ struct _GtkPrintOperationPrivate
guint cancelled : 1;
guint allow_async : 1;
guint is_sync : 1;
+ guint support_selection : 1;
+ guint has_selection : 1;
GtkPageDrawingState page_drawing_state;
diff --git a/gtk/gtkprintoperation-unix.c b/gtk/gtkprintoperation-unix.c
index ad8bc126f8..765752b158 100644
--- a/gtk/gtkprintoperation-unix.c
+++ b/gtk/gtkprintoperation-unix.c
@@ -421,6 +421,12 @@ get_print_dialog (GtkPrintOperation *op,
gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (pd),
priv->current_page);
+ gtk_print_unix_dialog_set_support_selection (GTK_PRINT_UNIX_DIALOG (pd),
+ priv->support_selection);
+
+ gtk_print_unix_dialog_set_has_selection (GTK_PRINT_UNIX_DIALOG (pd),
+ priv->has_selection);
+
g_signal_emit_by_name (op, "create-custom-widget",
&priv->custom_widget);
diff --git a/gtk/gtkprintoperation.c b/gtk/gtkprintoperation.c
index d0e6fb9aae..966417b22f 100644
--- a/gtk/gtkprintoperation.c
+++ b/gtk/gtkprintoperation.c
@@ -163,6 +163,8 @@ gtk_print_operation_init (GtkPrintOperation *operation)
priv->export_filename = NULL;
priv->track_print_status = FALSE;
priv->is_sync = FALSE;
+ priv->support_selection = FALSE;
+ priv->has_selection = FALSE;
priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY;
@@ -223,6 +225,7 @@ preview_iface_is_selected (GtkPrintOperationPreview *preview,
switch (priv->print_pages)
{
+ case GTK_PRINT_PAGES_SELECTION:
case GTK_PRINT_PAGES_ALL:
return (page_nr >= 0) && (page_nr < priv->nr_of_pages);
case GTK_PRINT_PAGES_CURRENT:
@@ -830,9 +833,9 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class)
* @setup: actual page setup
* @settings: actual print settings
*
- * Emmited after change of selected printer. The actual page setup and
+ * Emitted after change of selected printer. The actual page setup and
* print settings are passed to the custom widget, which can actualize
- * itself according to this change.
+ * itself according to this change.
*
* Since: 2.18
*/
@@ -1193,6 +1196,39 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class)
NULL,
GTK_PARAM_READWRITE));
+ /**
+ * GtkPrintOperation:support-selection:
+ *
+ * If %TRUE, the print operation will support print of selection.
+ * This allows the print dialog to show a "Selection" button.
+ *
+ * Since: 2.18
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TRACK_PRINT_STATUS,
+ g_param_spec_boolean ("support-selection",
+ P_("Support Selection"),
+ P_("TRUE if the print operation will support print of selection."),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkPrintOperation:has-selection:
+ *
+ * Determines whether there is a selection in your application.
+ * This can allow your application to print the selection.
+ * This is typically used to make a "Selection" button sensitive.
+ *
+ * Since: 2.18
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TRACK_PRINT_STATUS,
+ g_param_spec_boolean ("has-selection",
+ P_("Has Selection"),
+ P_("TRUE if a selecion exists."),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
}
/**
@@ -2976,7 +3012,99 @@ gtk_print_operation_cancel (GtkPrintOperation *op)
op->priv->cancelled = TRUE;
}
+/**
+ * gtk_print_operation_set_support_selection:
+ * @op: a #GtkPrintOperation
+ * @support_selection: %TRUE to support selection
+ *
+ * Sets whether selection is supported by #GtkPrintOperation.
+ *
+ * Since: 2.18
+ */
+void
+gtk_print_operation_set_support_selection (GtkPrintOperation *op,
+ gboolean support_selection)
+{
+ GtkPrintOperationPrivate *priv;
+ g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
+
+ priv = op->priv;
+
+ support_selection = support_selection != FALSE;
+ if (priv->support_selection != support_selection)
+ {
+ priv->support_selection = support_selection;
+ g_object_notify (G_OBJECT (op), "support-selection");
+ }
+}
+
+/**
+ * gtk_print_operation_get_support_selection:
+ * @op: a #GtkPrintOperation
+ *
+ * Gets the value of #GtkPrintOperation::support-selection property.
+ *
+ * Returns: whether the application supports print of selection
+ *
+ * Since: 2.18
+ */
+gboolean
+gtk_print_operation_get_support_selection (GtkPrintOperation *op)
+{
+ g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
+
+ return op->priv->support_selection;
+}
+
+/**
+ * gtk_print_operation_set_has_selection:
+ * @op: a #GtkPrintOperation
+ * @has_selection: %TRUE indicates that a selection exists
+ *
+ * Sets whether there is a selection to print.
+ *
+ * Application has to set number of pages to which the selection
+ * will draw by gtk_print_operation_set_n_pages() in a callback of
+ * #GtkPrintOperation::begin-print.
+ *
+ * Since: 2.18
+ */
+void
+gtk_print_operation_set_has_selection (GtkPrintOperation *op,
+ gboolean has_selection)
+{
+ GtkPrintOperationPrivate *priv;
+
+ g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
+
+ priv = op->priv;
+
+ has_selection = has_selection != FALSE;
+ if (priv->has_selection != has_selection)
+ {
+ priv->has_selection = has_selection;
+ g_object_notify (G_OBJECT (op), "has-selection");
+ }
+}
+
+/**
+ * gtk_print_operation_get_has_selection:
+ * @op: a #GtkPrintOperation
+ *
+ * Gets the value of #GtkPrintOperation::has-selection property.
+ *
+ * Returns: whether there is a selection
+ *
+ * Since: 2.18
+ */
+gboolean
+gtk_print_operation_get_has_selection (GtkPrintOperation *op)
+{
+ g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE);
+
+ return op->priv->has_selection;
+}
#define __GTK_PRINT_OPERATION_C__
#include "gtkaliasdef.c"
diff --git a/gtk/gtkprintoperation.h b/gtk/gtkprintoperation.h
index af46332fcf..aee3d95ec6 100644
--- a/gtk/gtkprintoperation.h
+++ b/gtk/gtkprintoperation.h
@@ -178,6 +178,12 @@ gboolean gtk_print_operation_is_finished (GtkPrintOper
void gtk_print_operation_cancel (GtkPrintOperation *op);
void gtk_print_operation_draw_page_finish (GtkPrintOperation *op);
void gtk_print_operation_set_defer_drawing (GtkPrintOperation *op);
+void gtk_print_operation_set_support_selection (GtkPrintOperation *op,
+ gboolean support_selection);
+gboolean gtk_print_operation_get_support_selection (GtkPrintOperation *op);
+void gtk_print_operation_set_has_selection (GtkPrintOperation *op,
+ gboolean has_selection);
+gboolean gtk_print_operation_get_has_selection (GtkPrintOperation *op);
GtkPageSetup *gtk_print_run_page_setup_dialog (GtkWindow *parent,
GtkPageSetup *page_setup,
diff --git a/gtk/gtkprintsettings.c b/gtk/gtkprintsettings.c
index 4328960f9e..e50208017b 100644
--- a/gtk/gtkprintsettings.c
+++ b/gtk/gtkprintsettings.c
@@ -1356,6 +1356,9 @@ gtk_print_settings_get_print_pages (GtkPrintSettings *settings)
if (val == NULL || (strcmp (val, "all") == 0))
return GTK_PRINT_PAGES_ALL;
+ if (strcmp (val, "selection") == 0)
+ return GTK_PRINT_PAGES_SELECTION;
+
if (strcmp (val, "current") == 0)
return GTK_PRINT_PAGES_CURRENT;
@@ -1389,6 +1392,9 @@ gtk_print_settings_set_print_pages (GtkPrintSettings *settings,
case GTK_PRINT_PAGES_CURRENT:
str = "current";
break;
+ case GTK_PRINT_PAGES_SELECTION:
+ str = "selection";
+ break;
case GTK_PRINT_PAGES_RANGES:
str = "ranges";
break;
diff --git a/gtk/gtkprintunixdialog.c b/gtk/gtkprintunixdialog.c
index 92c93e9300..85fa6eaa78 100644
--- a/gtk/gtkprintunixdialog.c
+++ b/gtk/gtkprintunixdialog.c
@@ -115,7 +115,10 @@ enum {
PROP_PAGE_SETUP,
PROP_CURRENT_PAGE,
PROP_PRINT_SETTINGS,
- PROP_SELECTED_PRINTER
+ PROP_SELECTED_PRINTER,
+ PROP_MANUAL_CAPABILITIES,
+ PROP_SUPPORT_SELECTION,
+ PROP_HAS_SELECTION
};
enum {
@@ -143,8 +146,13 @@ struct GtkPrintUnixDialogPrivate
GtkPageSetup *page_setup;
gboolean page_setup_set;
+ gboolean support_selection;
+ gboolean has_selection;
+
GtkWidget *all_pages_radio;
GtkWidget *current_page_radio;
+ GtkWidget *selection_radio;
+ GtkWidget *range_table;
GtkWidget *page_range_radio;
GtkWidget *page_range_entry;
@@ -286,6 +294,31 @@ gtk_print_unix_dialog_class_init (GtkPrintUnixDialogClass *class)
GTK_TYPE_PRINTER,
GTK_PARAM_READABLE));
+ g_object_class_install_property (object_class,
+ PROP_MANUAL_CAPABILITIES,
+ g_param_spec_flags ("manual-capabilities",
+ P_("Manual Capabilites"),
+ P_("Capabilities the application can handle"),
+ GTK_TYPE_PRINT_CAPABILITIES,
+ 0,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SUPPORT_SELECTION,
+ g_param_spec_boolean ("support-selection",
+ P_("Support Selection"),
+ P_("Whether the dialog supports selection"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_HAS_SELECTION,
+ g_param_spec_boolean ("has-selection",
+ P_("Has Selection"),
+ P_("Whether the application has a selection"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
g_type_class_add_private (class, sizeof (GtkPrintUnixDialogPrivate));
}
@@ -428,6 +461,9 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog)
priv->page_setup = gtk_page_setup_new ();
priv->page_setup_set = FALSE;
+ priv->support_selection = FALSE;
+ priv->has_selection = FALSE;
+
g_signal_connect (dialog,
"destroy",
(GCallback) gtk_print_unix_dialog_destroy,
@@ -783,6 +819,15 @@ gtk_print_unix_dialog_set_property (GObject *object,
case PROP_PRINT_SETTINGS:
gtk_print_unix_dialog_set_settings (dialog, g_value_get_object (value));
break;
+ case PROP_MANUAL_CAPABILITIES:
+ gtk_print_unix_dialog_set_manual_capabilities (dialog, g_value_get_flags (value));
+ break;
+ case PROP_SUPPORT_SELECTION:
+ gtk_print_unix_dialog_set_support_selection (dialog, g_value_get_boolean (value));
+ break;
+ case PROP_HAS_SELECTION:
+ gtk_print_unix_dialog_set_has_selection (dialog, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -812,6 +857,15 @@ gtk_print_unix_dialog_get_property (GObject *object,
case PROP_SELECTED_PRINTER:
g_value_set_object (value, priv->current_printer);
break;
+ case PROP_MANUAL_CAPABILITIES:
+ g_value_set_flags (value, priv->manual_capabilities);
+ break;
+ case PROP_SUPPORT_SELECTION:
+ g_value_set_boolean (value, priv->support_selection);
+ break;
+ case PROP_HAS_SELECTION:
+ g_value_set_boolean (value, priv->has_selection);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1803,7 +1857,8 @@ create_main_page (GtkPrintUnixDialog *dialog)
gtk_widget_show (hbox);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
- table = gtk_table_new (3, 2, FALSE);
+ table = gtk_table_new (4, 2, FALSE);
+ priv->range_table = table;
gtk_table_set_row_spacings (GTK_TABLE (table), 6);
gtk_table_set_col_spacings (GTK_TABLE (table), 12);
frame = wrap_in_frame (_("Range"), table);
@@ -1826,6 +1881,17 @@ create_main_page (GtkPrintUnixDialog *dialog)
0, 2, 1, 2, GTK_FILL, 0,
0, 0);
+
+ radio = gtk_radio_button_new_with_mnemonic (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)),
+ _("Se_lection"));
+
+ gtk_widget_set_sensitive (radio, priv->has_selection);
+ priv->selection_radio = radio;
+ gtk_table_attach (GTK_TABLE (table), radio,
+ 0, 2, 2, 3, GTK_FILL, 0,
+ 0, 0);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 2, 0);
+
radio = gtk_radio_button_new_with_mnemonic (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("Pag_es:"));
range_tooltip = _("Specify one or more page ranges,\n e.g. 1-3,7,11");
gtk_widget_set_tooltip_text (radio, range_tooltip);
@@ -1833,7 +1899,7 @@ create_main_page (GtkPrintUnixDialog *dialog)
priv->page_range_radio = radio;
gtk_widget_show (radio);
gtk_table_attach (GTK_TABLE (table), radio,
- 0, 1, 2, 3, GTK_FILL, 0,
+ 0, 1, 3, 4, GTK_FILL, 0,
0, 0);
entry = gtk_entry_new ();
gtk_widget_set_tooltip_text (entry, range_tooltip);
@@ -1842,7 +1908,7 @@ create_main_page (GtkPrintUnixDialog *dialog)
priv->page_range_entry = entry;
gtk_widget_show (entry);
gtk_table_attach (GTK_TABLE (table), entry,
- 1, 2, 2, 3, GTK_FILL, 0,
+ 1, 2, 3, 4, GTK_FILL, 0,
0, 0);
g_signal_connect (radio, "toggled", G_CALLBACK (update_entry_sensitivity), entry);
update_entry_sensitivity (radio, entry);
@@ -2030,6 +2096,8 @@ dialog_get_print_pages (GtkPrintUnixDialog *dialog)
return GTK_PRINT_PAGES_ALL;
else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->current_page_radio)))
return GTK_PRINT_PAGES_CURRENT;
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->selection_radio)))
+ return GTK_PRINT_PAGES_SELECTION;
else
return GTK_PRINT_PAGES_RANGES;
}
@@ -2044,6 +2112,8 @@ dialog_set_print_pages (GtkPrintUnixDialog *dialog,
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->page_range_radio), TRUE);
else if (pages == GTK_PRINT_PAGES_CURRENT)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->current_page_radio), TRUE);
+ else if (pages == GTK_PRINT_PAGES_SELECTION)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->selection_radio), TRUE);
else
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->all_pages_radio), TRUE);
}
@@ -3410,21 +3480,162 @@ gtk_print_unix_dialog_set_manual_capabilities (GtkPrintUnixDialog *dialog,
{
GtkPrintUnixDialogPrivate *priv = dialog->priv;
- priv->manual_capabilities = capabilities;
- update_dialog_from_capabilities (dialog);
+ if (priv->manual_capabilities != capabilities)
+ {
+ priv->manual_capabilities = capabilities;
+ update_dialog_from_capabilities (dialog);
- if (priv->current_printer)
+ if (priv->current_printer)
+ {
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->printer_treeview));
+
+ g_object_unref (priv->current_printer);
+ priv->current_printer = NULL;
+ priv->internal_printer_change = TRUE;
+ selected_printer_changed (selection, dialog);
+ priv->internal_printer_change = FALSE;
+ }
+
+ g_object_notify (G_OBJECT (dialog), "manual-capabilities");
+ }
+}
+
+/**
+ * gtk_print_unix_dialog_get_manual_capabilities:
+ * @dialog: a #GtkPrintUnixDialog
+ *
+ * Gets the value of #GtkPrintUnixDialog::manual-capabilities property.
+ *
+ * Returns: the printing capabilities
+ *
+ * Since: 2.18
+ */
+GtkPrintCapabilities
+gtk_print_unix_dialog_get_manual_capabilities (GtkPrintUnixDialog *dialog)
+{
+ g_return_val_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog), FALSE);
+
+ return dialog->priv->manual_capabilities;
+}
+
+/**
+ * gtk_print_unix_dialog_set_support_selection:
+ * @dialog: a #GtkPrintUnixDialog
+ * @support_selection: %TRUE to allow print selection
+ *
+ * Sets whether the print dialog allows user to print a selection.
+ *
+ * Since: 2.18
+ */
+void
+gtk_print_unix_dialog_set_support_selection (GtkPrintUnixDialog *dialog,
+ gboolean support_selection)
+{
+ GtkPrintUnixDialogPrivate *priv;
+
+ g_return_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog));
+
+ priv = dialog->priv;
+
+ support_selection = support_selection != FALSE;
+ if (priv->support_selection != support_selection)
{
- GtkTreeSelection *selection;
+ priv->support_selection = support_selection;
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->printer_treeview));
+ if (priv->selection_radio)
+ {
+ if (support_selection)
+ {
+ gtk_widget_set_sensitive (priv->selection_radio, priv->has_selection);
+ gtk_table_set_row_spacing (GTK_TABLE (priv->range_table),
+ 2,
+ gtk_table_get_default_row_spacing (GTK_TABLE (priv->range_table)));
+ gtk_widget_show (priv->selection_radio);
+ }
+ else
+ {
+ gtk_widget_set_sensitive (priv->selection_radio, FALSE);
+ gtk_table_set_row_spacing (GTK_TABLE (priv->range_table), 2, 0);
+ gtk_widget_hide (priv->selection_radio);
+ }
+ }
- g_object_unref (priv->current_printer);
- priv->current_printer = NULL;
- priv->internal_printer_change = TRUE;
- selected_printer_changed (selection, dialog);
- priv->internal_printer_change = FALSE;
- }
+ g_object_notify (G_OBJECT (dialog), "support-selection");
+ }
+}
+
+/**
+ * gtk_print_unix_dialog_get_support_selection:
+ * @dialog: a #GtkPrintUnixDialog
+ *
+ * Gets the value of #GtkPrintUnixDialog::support-selection property.
+ *
+ * Returns: whether the application supports print of selection
+ *
+ * Since: 2.18
+ */
+gboolean
+gtk_print_unix_dialog_get_support_selection (GtkPrintUnixDialog *dialog)
+{
+ g_return_val_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog), FALSE);
+
+ return dialog->priv->support_selection;
+}
+
+/**
+ * gtk_print_unix_dialog_set_has_selection:
+ * @dialog: a #GtkPrintUnixDialog
+ * @has_selection: %TRUE indicates that a selection exists
+ *
+ * Sets whether a selection exists.
+ *
+ * Since: 2.18
+ */
+void
+gtk_print_unix_dialog_set_has_selection (GtkPrintUnixDialog *dialog,
+ gboolean has_selection)
+{
+ GtkPrintUnixDialogPrivate *priv;
+
+ g_return_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog));
+
+ priv = dialog->priv;
+
+ has_selection = has_selection != FALSE;
+ if (priv->has_selection != has_selection)
+ {
+ priv->has_selection = has_selection;
+
+ if (priv->selection_radio)
+ {
+ if (priv->support_selection)
+ gtk_widget_set_sensitive (priv->selection_radio, has_selection);
+ else
+ gtk_widget_set_sensitive (priv->selection_radio, FALSE);
+ }
+
+ g_object_notify (G_OBJECT (dialog), "has-selection");
+ }
+}
+
+/**
+ * gtk_print_unix_dialog_get_has_selection:
+ * @dialog: a #GtkPrintUnixDialog
+ *
+ * Gets the value of #GtkPrintUnixDialog::has-selection property.
+ *
+ * Returns: whether there is a selection
+ *
+ * Since: 2.18
+ */
+gboolean
+gtk_print_unix_dialog_get_has_selection (GtkPrintUnixDialog *dialog)
+{
+ g_return_val_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog), FALSE);
+
+ return dialog->priv->has_selection;
}
#define __GTK_PRINT_UNIX_DIALOG_C__
diff --git a/gtk/gtkprintunixdialog.h b/gtk/gtkprintunixdialog.h
index c7a919f9dc..0d7efccfc3 100644
--- a/gtk/gtkprintunixdialog.h
+++ b/gtk/gtkprintunixdialog.h
@@ -83,6 +83,13 @@ void gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog
GtkWidget *tab_label);
void gtk_print_unix_dialog_set_manual_capabilities (GtkPrintUnixDialog *dialog,
GtkPrintCapabilities capabilities);
+GtkPrintCapabilities gtk_print_unix_dialog_get_manual_capabilities (GtkPrintUnixDialog *dialog);
+void gtk_print_unix_dialog_set_support_selection (GtkPrintUnixDialog *dialog,
+ gboolean support_selection);
+gboolean gtk_print_unix_dialog_get_support_selection (GtkPrintUnixDialog *dialog);
+void gtk_print_unix_dialog_set_has_selection (GtkPrintUnixDialog *dialog,
+ gboolean has_selection);
+gboolean gtk_print_unix_dialog_get_has_selection (GtkPrintUnixDialog *dialog);
G_END_DECLS
diff --git a/gtk/gtkrecentmanager.c b/gtk/gtkrecentmanager.c
index 317b3d5f5e..5cedaa0e54 100644
--- a/gtk/gtkrecentmanager.c
+++ b/gtk/gtkrecentmanager.c
@@ -1735,15 +1735,16 @@ recent_app_info_free (RecentAppInfo *app_info)
* storage specification, they will be expanded.
*
* Return value: %TRUE if an application with @app_name has registered this
- * resource inside the recently used list, or %FALSE otherwise. You should
- * free the returned command line using g_free().
+ * resource inside the recently used list, or %FALSE otherwise. The
+ * @app_exec string is owned by the #GtkRecentInfo and should not be
+ * modified or freed
*
* Since: 2.10
*/
gboolean
gtk_recent_info_get_application_info (GtkRecentInfo *info,
const gchar *app_name,
- gchar **app_exec,
+ const gchar **app_exec,
guint *count,
time_t *time_)
{
diff --git a/gtk/gtkrecentmanager.h b/gtk/gtkrecentmanager.h
index 4127e67b21..ccc6581594 100644
--- a/gtk/gtkrecentmanager.h
+++ b/gtk/gtkrecentmanager.h
@@ -186,7 +186,7 @@ time_t gtk_recent_info_get_visited (GtkRecentInfo *info
gboolean gtk_recent_info_get_private_hint (GtkRecentInfo *info);
gboolean gtk_recent_info_get_application_info (GtkRecentInfo *info,
const gchar *app_name,
- gchar **app_exec,
+ const gchar **app_exec,
guint *count,
time_t *time_);
gchar ** gtk_recent_info_get_applications (GtkRecentInfo *info,
diff --git a/gtk/gtkstatusicon.c b/gtk/gtkstatusicon.c
index f2ed5012a1..3e89f5362c 100644
--- a/gtk/gtkstatusicon.c
+++ b/gtk/gtkstatusicon.c
@@ -1022,10 +1022,13 @@ gtk_status_icon_set_property (GObject *object,
break;
case PROP_HAS_TOOLTIP:
gtk_status_icon_set_has_tooltip (status_icon, g_value_get_boolean (value));
+ break;
case PROP_TOOLTIP_TEXT:
gtk_status_icon_set_tooltip_text (status_icon, g_value_get_string (value));
+ break;
case PROP_TOOLTIP_MARKUP:
gtk_status_icon_set_tooltip_markup (status_icon, g_value_get_string (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/gtk/gtkstock.c b/gtk/gtkstock.c
index 5dd0cea713..153ef0877c 100644
--- a/gtk/gtkstock.c
+++ b/gtk/gtkstock.c
@@ -451,7 +451,7 @@ static const GtkStockItem builtin_items [] =
* return (gchar*)g_dpgettext2 (GETTEXT_PACKAGE, msgctxt, msgid);
* }
*
- * /&ast; ... &ast/
+ * /&ast; ... &ast;/
*
* gtk_stock_add (items, G_N_ELEMENTS (items));
* gtk_stock_set_translate_func ("odd-item-domain", my_translate_func, "odd items");
diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h
index 384c176982..44259abe35 100644
--- a/gtk/gtktreeprivate.h
+++ b/gtk/gtktreeprivate.h
@@ -238,6 +238,8 @@ struct _GtkTreeViewPrivate
guint post_validation_flag : 1;
+ /* Whether our key press handler is to avoid sending an unhandled binding to the search entry */
+ guint search_entry_avoid_unhandled_binding : 1;
/* Auto expand/collapse timeout in hover mode */
guint auto_expand_timeout;
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index caa517c07a..068b2369a4 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -5377,6 +5377,12 @@ gtk_tree_view_key_press (GtkWidget *widget,
if (GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->key_press_event (widget, event))
return TRUE;
+ if (tree_view->priv->search_entry_avoid_unhandled_binding)
+ {
+ tree_view->priv->search_entry_avoid_unhandled_binding = FALSE;
+ return FALSE;
+ }
+
/* We pass the event to the search_entry. If its text changes, then we start
* the typeahead find capabilities. */
if (GTK_WIDGET_HAS_FOCUS (tree_view)
@@ -10231,27 +10237,21 @@ gtk_tree_view_real_select_cursor_parent (GtkTreeView *tree_view)
GdkModifierType state;
if (! GTK_WIDGET_HAS_FOCUS (tree_view))
- return FALSE;
+ goto out;
cursor_path = NULL;
if (tree_view->priv->cursor)
cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
if (cursor_path == NULL)
- return FALSE;
+ goto out;
_gtk_tree_view_find_node (tree_view, cursor_path,
&cursor_tree, &cursor_node);
if (cursor_tree == NULL)
{
gtk_tree_path_free (cursor_path);
- return FALSE;
- }
-
- if (gtk_get_current_event_state (&state))
- {
- if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
- tree_view->priv->ctrl_pressed = TRUE;
+ goto out;
}
if (cursor_tree->parent_node)
@@ -10262,19 +10262,30 @@ gtk_tree_view_real_select_cursor_parent (GtkTreeView *tree_view)
gtk_tree_path_up (cursor_path);
+ if (gtk_get_current_event_state (&state))
+ {
+ if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+ tree_view->priv->ctrl_pressed = TRUE;
+ }
+
gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, FALSE);
- }
+ gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
- gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+ gtk_tree_view_queue_draw_path (tree_view, cursor_path, NULL);
+ gtk_tree_path_free (cursor_path);
- gtk_widget_grab_focus (GTK_WIDGET (tree_view));
- gtk_tree_view_queue_draw_path (tree_view, cursor_path, NULL);
- gtk_tree_path_free (cursor_path);
+ tree_view->priv->ctrl_pressed = FALSE;
- tree_view->priv->ctrl_pressed = FALSE;
+ return TRUE;
+ }
- return TRUE;
+ out:
+
+ tree_view->priv->search_entry_avoid_unhandled_binding = TRUE;
+ return FALSE;
}
+
static gboolean
gtk_tree_view_search_entry_flush_timeout (GtkTreeView *tree_view)
{
@@ -10320,7 +10331,7 @@ gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view)
return;
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (tree_view));
- screen = gtk_widget_get_screen (tree_view);
+ screen = gtk_widget_get_screen (GTK_WIDGET (tree_view));
if (tree_view->priv->search_window != NULL)
{
diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c
index 24f99e4c15..bf98fdf1ad 100644
--- a/gtk/gtktreeviewcolumn.c
+++ b/gtk/gtktreeviewcolumn.c
@@ -1548,6 +1548,8 @@ gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column)
* in no particular order. The list must be freed with g_list_free().
*
* Return value: A list of #GtkCellRenderers
+ *
+ * Deprecated: 2.18: use gtk_cell_layout_get_cells() instead.
**/
GList *
gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column)
diff --git a/gtk/gtktreeviewcolumn.h b/gtk/gtktreeviewcolumn.h
index 9238a623ce..b06e845d9f 100644
--- a/gtk/gtktreeviewcolumn.h
+++ b/gtk/gtktreeviewcolumn.h
@@ -135,7 +135,9 @@ void gtk_tree_view_column_pack_end (GtkTreeViewCol
GtkCellRenderer *cell,
gboolean expand);
void gtk_tree_view_column_clear (GtkTreeViewColumn *tree_column);
+#ifndef GTK_DISABLE_DEPRECATED
GList *gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column);
+#endif
void gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell_renderer,
const gchar *attribute,
diff --git a/gtk/gtkvbbox.c b/gtk/gtkvbbox.c
index e42db03b36..5198e46a30 100644
--- a/gtk/gtkvbbox.c
+++ b/gtk/gtkvbbox.c
@@ -26,15 +26,11 @@
#include "config.h"
#include "gtkvbbox.h"
+#include "gtkorientable.h"
#include "gtkintl.h"
#include "gtkalias.h"
-static void gtk_vbutton_box_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void gtk_vbutton_box_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-
static gint default_spacing = 10;
static GtkButtonBoxStyle default_layout_style = GTK_BUTTONBOX_EDGE;
@@ -43,18 +39,13 @@ G_DEFINE_TYPE (GtkVButtonBox, gtk_vbutton_box, GTK_TYPE_BUTTON_BOX)
static void
gtk_vbutton_box_class_init (GtkVButtonBoxClass *class)
{
- GtkWidgetClass *widget_class;
-
- widget_class = (GtkWidgetClass*) class;
-
- widget_class->size_request = gtk_vbutton_box_size_request;
- widget_class->size_allocate = gtk_vbutton_box_size_allocate;
}
static void
gtk_vbutton_box_init (GtkVButtonBox *vbutton_box)
{
- /* button_box_init has done everything allready */
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (vbutton_box),
+ GTK_ORIENTATION_VERTICAL);
}
GtkWidget*
@@ -107,185 +98,5 @@ gtk_vbutton_box_get_layout_default (void)
return default_layout_style;
}
-
-
-
-static void
-gtk_vbutton_box_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- GtkBox *box;
- GtkButtonBox *bbox;
- gint nvis_children;
- gint child_width;
- gint child_height;
- gint spacing;
- GtkButtonBoxStyle layout;
-
- box = GTK_BOX (widget);
- bbox = GTK_BUTTON_BOX (widget);
-
- spacing = box->spacing;
- layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
- ? bbox->layout_style : default_layout_style;
-
- _gtk_button_box_child_requisition (widget,
- &nvis_children,
- NULL,
- &child_width,
- &child_height);
-
- if (nvis_children == 0)
- {
- requisition->width = 0;
- requisition->height = 0;
- }
- else
- {
- switch (layout)
- {
- case GTK_BUTTONBOX_SPREAD:
- requisition->height =
- nvis_children*child_height + ((nvis_children+1)*spacing);
- break;
- case GTK_BUTTONBOX_EDGE:
- case GTK_BUTTONBOX_START:
- case GTK_BUTTONBOX_END:
- case GTK_BUTTONBOX_CENTER:
- requisition->height =
- nvis_children*child_height + ((nvis_children-1)*spacing);
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- requisition->width = child_width;
- }
-
- requisition->width += GTK_CONTAINER (box)->border_width * 2;
- requisition->height += GTK_CONTAINER (box)->border_width * 2;
-}
-
-
-
-static void
-gtk_vbutton_box_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- GtkBox *base_box;
- GtkButtonBox *box;
- GtkBoxChild *child;
- GList *children;
- GtkAllocation child_allocation;
- gint nvis_children;
- gint n_secondaries;
- gint child_width;
- gint child_height;
- gint x = 0;
- gint y = 0;
- gint secondary_y = 0;
- gint height;
- gint childspace;
- gint childspacing = 0;
- GtkButtonBoxStyle layout;
- gint spacing;
-
- base_box = GTK_BOX (widget);
- box = GTK_BUTTON_BOX (widget);
- spacing = base_box->spacing;
- layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
- ? box->layout_style : default_layout_style;
- _gtk_button_box_child_requisition (widget,
- &nvis_children,
- &n_secondaries,
- &child_width,
- &child_height);
- widget->allocation = *allocation;
- height = allocation->height - GTK_CONTAINER (box)->border_width*2;
- switch (layout)
- {
- case GTK_BUTTONBOX_SPREAD:
- childspacing = (height - (nvis_children * child_height)) / (nvis_children + 1);
- y = allocation->y + GTK_CONTAINER (box)->border_width + childspacing;
- secondary_y = y + ((nvis_children - n_secondaries) * (child_height + childspacing));
- break;
- case GTK_BUTTONBOX_EDGE:
- if (nvis_children >= 2)
- {
- childspacing = (height - (nvis_children*child_height)) / (nvis_children-1);
- y = allocation->y + GTK_CONTAINER (box)->border_width;
- secondary_y = y + ((nvis_children - n_secondaries) * (child_height + childspacing));
- }
- else
- {
- /* one or zero children, just center */
- childspacing = height;
- y = secondary_y = allocation->y + (allocation->height - child_height) / 2;
- }
- break;
- case GTK_BUTTONBOX_START:
- childspacing = spacing;
- y = allocation->y + GTK_CONTAINER (box)->border_width;
- secondary_y = allocation->y + allocation->height
- - child_height * n_secondaries
- - spacing * (n_secondaries - 1)
- - GTK_CONTAINER (box)->border_width;
- break;
- case GTK_BUTTONBOX_END:
- childspacing = spacing;
- y = allocation->y + allocation->height
- - child_height * (nvis_children - n_secondaries)
- - spacing * (nvis_children - n_secondaries - 1)
- - GTK_CONTAINER (box)->border_width;
- secondary_y = allocation->y + GTK_CONTAINER (box)->border_width;
- break;
- case GTK_BUTTONBOX_CENTER:
- childspacing = spacing;
- y = allocation->y +
- (allocation->height
- - (child_height * (nvis_children - n_secondaries)
- + spacing * (nvis_children - n_secondaries - 1)))/2
- + (n_secondaries * child_height + n_secondaries * spacing)/2;
- secondary_y = allocation->y + GTK_CONTAINER (box)->border_width;
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
-
- x = allocation->x + (allocation->width - child_width) / 2;
- childspace = child_height + childspacing;
-
- children = GTK_BOX (box)->children;
-
- while (children)
- {
- child = children->data;
- children = children->next;
-
- if (GTK_WIDGET_VISIBLE (child->widget))
- {
- child_allocation.width = child_width;
- child_allocation.height = child_height;
- child_allocation.x = x;
-
- if (child->is_secondary)
- {
- child_allocation.y = secondary_y;
- secondary_y += childspace;
- }
- else
- {
- child_allocation.y = y;
- y += childspace;
- }
-
- gtk_widget_size_allocate (child->widget, &child_allocation);
- }
- }
-}
-
#define __GTK_VBBOX_C__
#include "gtkaliasdef.c"
diff --git a/gtk/tests/builder.c b/gtk/tests/builder.c
index 7b2cc19b60..f5a85ac4fa 100644
--- a/gtk/tests/builder.c
+++ b/gtk/tests/builder.c
@@ -1147,7 +1147,7 @@ test_treeview_column (void)
g_assert (GTK_IS_TREE_VIEW_COLUMN (column));
g_assert (strcmp (gtk_tree_view_column_get_title (column), "Test") == 0);
- renderers = gtk_tree_view_column_get_cell_renderers (column);
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
g_assert (g_list_length (renderers) == 1);
renderer = g_list_nth_data (renderers, 0);
g_assert (renderer);
@@ -1423,7 +1423,7 @@ test_cell_view (void)
path = gtk_tree_path_new_first ();
gtk_cell_view_set_displayed_row (GTK_CELL_VIEW (cellview), path);
- renderers = gtk_cell_view_get_cell_renderers (GTK_CELL_VIEW (cellview));
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (cellview));
g_assert (renderers);
g_assert (g_list_length (renderers) == 1);
@@ -2483,6 +2483,56 @@ test_file (const gchar *filename)
builder = NULL;
}
+static void
+test_message_area (void)
+{
+ GtkBuilder *builder;
+ GError *error;
+ GObject *obj, *obj1;
+ const gchar buffer[] =
+ "<interface>"
+ " <object class=\"GtkInfoBar\" id=\"infobar1\">"
+ " <child internal-child=\"content_area\">"
+ " <object class=\"GtkHBox\" id=\"contentarea1\">"
+ " <child>"
+ " <object class=\"GtkLabel\" id=\"content\">"
+ " <property name=\"label\" translatable=\"yes\">Message</property>"
+ " </object>"
+ " </child>"
+ " </object>"
+ " </child>"
+ " <child internal-child=\"action_area\">"
+ " <object class=\"GtkVButtonBox\" id=\"actionarea1\">"
+ " <child>"
+ " <object class=\"GtkButton\" id=\"button_ok\">"
+ " <property name=\"label\">gtk-ok</property>"
+ " <property name=\"use-stock\">yes</property>"
+ " </object>"
+ " </child>"
+ " </object>"
+ " </child>"
+ " <action-widgets>"
+ " <action-widget response=\"1\">button_ok</action-widget>"
+ " </action-widgets>"
+ " </object>"
+ "</interface>";
+
+ error = NULL;
+ builder = builder_new_from_string (buffer, -1, NULL);
+ g_assert (error == NULL);
+ obj = gtk_builder_get_object (builder, "infobar1");
+ g_assert (GTK_IS_INFO_BAR (obj));
+ obj1 = gtk_builder_get_object (builder, "content");
+ g_assert (GTK_IS_LABEL (obj1));
+ g_assert (gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (obj1))) == GTK_WIDGET (obj));
+
+ obj1 = gtk_builder_get_object (builder, "button_ok");
+ g_assert (GTK_IS_BUTTON (obj1));
+ g_assert (gtk_widget_get_parent (gtk_widget_get_parent (GTK_WIDGET (obj1))) == GTK_WIDGET (obj));
+
+ g_object_unref (builder);
+}
+
int
main (int argc, char **argv)
{
@@ -2525,6 +2575,7 @@ main (int argc, char **argv)
g_test_add_func ("/Builder/Requires", test_requires);
g_test_add_func ("/Builder/AddObjects", test_add_objects);
g_test_add_func ("/Builder/Menus", test_menus);
+ g_test_add_func ("/Builder/MessageArea", test_message_area);
return g_test_run();
}
diff --git a/gtk/tests/treeview-scrolling.c b/gtk/tests/treeview-scrolling.c
index 5ee24c123b..0207dbcff2 100644
--- a/gtk/tests/treeview-scrolling.c
+++ b/gtk/tests/treeview-scrolling.c
@@ -728,7 +728,7 @@ scroll_new_row (ScrollFixture *fixture,
/* Set up a signal handler to acquire the editable widget */
column = gtk_tree_view_get_column (GTK_TREE_VIEW (fixture->tree_view), 0);
- renderers = gtk_tree_view_column_get_cell_renderers (column);
+ renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
g_signal_connect (G_OBJECT (renderers->data), "editing-started",
G_CALLBACK (scroll_new_row_editing_started),
diff --git a/gtk/updateiconcache.c b/gtk/updateiconcache.c
index f6a5cfff20..edd68c03cf 100644
--- a/gtk/updateiconcache.c
+++ b/gtk/updateiconcache.c
@@ -1687,7 +1687,7 @@ main (int argc, char **argv)
{
if (path)
{
- g_printerr (_("No theme index file."));
+ g_printerr (_("No theme index file.\n"));
}
else
{