summaryrefslogtreecommitdiffstats
path: root/meta/recipes-gnome/gtk+
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-gnome/gtk+
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-gnome/gtk+')
-rw-r--r--meta/recipes-gnome/gtk+/gdk-pixbuf-csource-native_2.12.7.bb37
-rw-r--r--meta/recipes-gnome/gtk+/gdk-pixbuf-csource/reduce-dependencies.patch221
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/cellrenderer-cairo.patch32
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/combo-arrow-size.patch67
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/disable-print.patch26
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/entry-cairo.patch103
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch9521
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-props.patch57
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-sizefix.patch35
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/filesystem-volumes.patch198
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/gtklabel-resize-patch10
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/hardcoded_libtool.patch29
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/menu-deactivate.patch51
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/no-demos.patch10
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/pangoxft2.10.6.diff2456
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/range-no-redraw.patch127
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/run-iconcache.patch19
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/scrolled-placement.patch22
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/toggle-font.diff100
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/xsettings.patch16
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch31
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/cellrenderer-cairo.patch32
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/disable-gio-png-sniff-test.diff97
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/entry-cairo.patch103
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/hardcoded_libtool.patch31
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/no-demos.patch10
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/run-iconcache.patch19
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/toggle-font.diff100
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.16.6/xsettings.patch16
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch28
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/cellrenderer-cairo.patch29
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/configurefix.patch85
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/disable-gio-png-sniff-test.diff97
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/entry-cairo.patch103
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/hardcoded_libtool.patch31
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/no-demos.patch10
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/run-iconcache.patch21
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/toggle-font.diff100
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.20.1/xsettings.patch18
-rw-r--r--meta/recipes-gnome/gtk+/gtk+.inc85
-rw-r--r--meta/recipes-gnome/gtk+/gtk+_2.12.7.bb50
-rw-r--r--meta/recipes-gnome/gtk+/gtk+_2.16.6.bb49
-rw-r--r--meta/recipes-gnome/gtk+/gtk+_2.20.1.bb54
43 files changed, 14336 insertions, 0 deletions
diff --git a/meta/recipes-gnome/gtk+/gdk-pixbuf-csource-native_2.12.7.bb b/meta/recipes-gnome/gtk+/gdk-pixbuf-csource-native_2.12.7.bb
new file mode 100644
index 0000000000..c88a79570a
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gdk-pixbuf-csource-native_2.12.7.bb
@@ -0,0 +1,37 @@
1require gtk+_${PV}.bb
2inherit native
3DEPENDS = "jpeg-native libpng-native gettext-native glib-2.0-native libx11-native"
4S = "${WORKDIR}/gtk+-${PV}"
5FILESPATH = "${FILE_DIRNAME}/gdk-pixbuf-csource:${FILE_DIRNAME}/gtk+-${PV}:${FILE_DIRNAME}/files"
6SRC_URI += "file://reduce-dependencies.patch;patch=1"
7PR = "r11"
8
9#clear recommends for uclibc builds
10RRECOMMENDS = " "
11RRECOMMENDS_${PN}_linux = " "
12RRECOMMENDS_${PN}_linux-gnueabi = " "
13
14EXTRA_OECONF = "\
15 --with-gdktarget=x11 \
16 --without-libtiff \
17 --with-libjpeg \
18 --with-libpng \
19 --x-includes=${STAGING_INCDIR} \
20 --x-libraries=${STAGING_LIBDIR} \
21"
22
23PACKAGES_DYNAMIC = ""
24
25do_compile() {
26 cd gdk-pixbuf && oe_runmake
27}
28
29do_install() {
30 cd gdk-pixbuf
31 oe_runmake 'DESTDIR=${D}' install
32 install -d ${D}${sysconfdir}/gtk-2.0
33 GDK_PIXBUF_MODULEDIR=${D}${libdir}/gtk-2.0/2.10.0/loaders ${D}${bindir}/gdk-pixbuf-query-loaders > ${D}${sysconfdir}/gtk-2.0/gdk-pixbuf.loaders
34 sed -i -e 's#${D}##g' ${D}${sysconfdir}/gtk-2.0/gdk-pixbuf.loaders
35 find ${D}${libdir} -name "libpixbufloader-*.la" -exec rm \{\} \;
36}
37
diff --git a/meta/recipes-gnome/gtk+/gdk-pixbuf-csource/reduce-dependencies.patch b/meta/recipes-gnome/gtk+/gdk-pixbuf-csource/reduce-dependencies.patch
new file mode 100644
index 0000000000..6b030e8f16
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gdk-pixbuf-csource/reduce-dependencies.patch
@@ -0,0 +1,221 @@
1#
2# strip unnecessary stuff out of configure, we just want
3# to build gdk-pixbuf-csource.
4# -- Michael 'Mickey' Lauer <mlauer@vanille-media.de>
5#
6---
7# configure.in | 116 ++---------------------------------------------------------
8# 1 file changed, 5 insertions(+), 111 deletions(-)
9#
10--- gtk+-2.12.7.orig/configure.in
11+++ gtk+-2.12.7/configure.in
12@@ -30,13 +30,10 @@ m4_define([gtk_api_version], [2.0])
13 #GTK_BINARY_VERSION=$GTK_MAJOR_VERSION.$GTK_MINOR_VERSION.$LT_CURRENT
14 m4_define([gtk_binary_version], [2.10.0])
15
16 # required versions of other packages
17 m4_define([glib_required_version], [2.13.5])
18-m4_define([pango_required_version], [1.17.3])
19-m4_define([atk_required_version], [1.9.0])
20-m4_define([cairo_required_version], [1.2.0])
21
22
23 AC_INIT([gtk+], [gtk_version],
24 [http://bugzilla.gnome.org/enter_bug.cgi?product=gtk%2B],
25 [gtk+])
26@@ -347,14 +344,11 @@ ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
27 ## Later on we actually use the cflags/libs from separate pkg-config
28 ## calls. Oh, also the later pkg-config calls don't include
29 ## the version requirements since those make the module lists
30 ## annoying to construct
31 PKG_CHECK_MODULES(BASE_DEPENDENCIES,
32- [glib-2.0 >= glib_required_version dnl
33- atk >= atk_required_version dnl
34- pango >= pango_required_version dnl
35- cairo >= cairo_required_version])
36+ [glib-2.0 >= glib_required_version])
37
38 if test "$os_win32" != yes; then
39 # libtool option to control which symbols are exported
40 # right now, symbols starting with _ are not exported
41 LIBTOOL_EXPORT_OPTIONS='-export-symbols-regex "^[[^_]].*"'
42@@ -1059,27 +1053,19 @@ GDK_PIXBUF_DEP_CFLAGS="`$PKG_CONFIG --cf
43
44 GDK_PIXBUF_XLIB_PACKAGES=
45 GDK_PIXBUF_XLIB_EXTRA_CFLAGS=
46 GDK_PIXBUF_XLIB_EXTRA_LIBS=
47
48-X_PACKAGES=fontconfig
49+X_PACKAGES=
50 GDK_EXTRA_LIBS="$GDK_WLIBS"
51 GDK_EXTRA_CFLAGS=
52
53 # GTK+ uses some X calls, so needs to link against X directly
54 GTK_DEP_PACKAGES_FOR_X=
55 GTK_DEP_LIBS_FOR_X=
56
57 if test "x$gdktarget" = "xx11"; then
58- #
59- # We use fontconfig very peripherally when decoding the default
60- # settings.
61- #
62- if $PKG_CONFIG --exists fontconfig; then : ; else
63- AC_MSG_ERROR([
64-*** fontconfig (http://www.fontconfig.org) is required by the X11 backend.])
65- fi
66
67 #
68 # Check for basic X packages; we use pkg-config if available
69 #
70 if $PKG_CONFIG --exists x11 xext xrender; then
71@@ -1122,20 +1108,10 @@ if test "x$gdktarget" = "xx11"; then
72 CPPFLAGS="$CPPFLAGS $X_CFLAGS"
73
74 gtk_save_LIBS=$LIBS
75 LIBS="$x_libs_for_checks $LIBS"
76
77- # Sanity check for the X11 and Xext libraries. While everything we need from
78- # Xext is optional, the chances a system has *none* of these things is so
79- # small that we just unconditionally require it.
80- AC_CHECK_FUNC(XOpenDisplay, :,
81- AC_MSG_ERROR([*** libX11 not found. Check 'config.log' for more details.]))
82- AC_CHECK_FUNC(XextFindDisplay, :,
83- AC_MSG_ERROR([*** libXext not found. Check 'config.log' for more details.]))
84- AC_CHECK_FUNC(XRenderQueryExtension, :,
85- AC_MSG_ERROR([*** libXrender not found. Check 'config.log' for more details.]))
86-
87 # Check for xReply
88
89 AC_MSG_CHECKING([if <X11/extensions/XIproto.h> is needed for xReply])
90 AC_TRY_COMPILE([#include <X11/Xlibint.h>],
91 [xReply *rep;],
92@@ -1416,104 +1392,33 @@ if test "x$gdktarget" = "xdirectfb"; the
93 AM_CONDITIONAL(USE_DIRECTFB, true)
94 else
95 AM_CONDITIONAL(USE_DIRECTFB, false)
96 fi
97
98-
99-# Check for Pango flags
100-
101-if test "x$gdktarget" = "xwin32"; then
102- PANGO_PACKAGES="pangowin32 pangocairo"
103-else
104- PANGO_PACKAGES="pango pangocairo"
105-fi
106-
107-AC_MSG_CHECKING(Pango flags)
108-if $PKG_CONFIG --exists $PANGO_PACKAGES ; then
109- PANGO_CFLAGS=`$PKG_CONFIG --cflags $PANGO_PACKAGES`
110- PANGO_LIBS=`$PKG_CONFIG --libs $PANGO_PACKAGES`
111-
112- AC_MSG_RESULT($PANGO_CFLAGS $PANGO_LIBS)
113-else
114- AC_MSG_ERROR([
115-*** Pango not found. Pango built with Cairo support is required
116-*** to build GTK+. See http://www.pango.org for Pango information.
117-])
118-fi
119-
120-CFLAGS="$CFLAGS $PANGO_CFLAGS"
121-
122-if $PKG_CONFIG --uninstalled $PANGO_PACKAGES; then
123- :
124-else
125- gtk_save_LIBS="$LIBS"
126- LIBS="$PANGO_LIBS $LIBS"
127- AC_TRY_LINK_FUNC(pango_context_new, :, AC_MSG_ERROR([
128-*** Can't link to Pango. Pango is required to build
129-*** GTK+. For more information see http://www.pango.org]))
130- LIBS="$gtk_save_LIBS"
131-fi
132-
133-CFLAGS="$saved_cflags"
134-LDFLAGS="$saved_ldflags"
135-
136-GDK_PACKAGES="$PANGO_PACKAGES"
137-if test "x$gdktarget" = "xx11"; then
138- GDK_PACKAGES="$GDK_PACKAGES $X_PACKAGES"
139-fi
140 GDK_DEP_LIBS="$GDK_EXTRA_LIBS `$PKG_CONFIG --libs $GDK_PIXBUF_PACKAGES $GDK_PACKAGES` $GDK_PIXBUF_EXTRA_LIBS"
141 GDK_DEP_CFLAGS="`$PKG_CONFIG --cflags gthread-2.0 $GDK_PIXBUF_PACKAGES $GDK_PACKAGES` $GDK_PIXBUF_EXTRA_CFLAGS $GDK_EXTRA_CFLAGS"
142
143 #
144 # If we aren't writing explicit dependencies, then don't put the extra libraries we need
145 # into the pkg-config files
146 #
147 if test $enable_explicit_deps != yes ; then
148- GDK_PACKAGES="$PANGO_PACKAGES"
149+ GDK_PACKAGES=
150 GDK_EXTRA_LIBS=
151 fi
152
153 AC_SUBST(GDK_PACKAGES)
154 AC_SUBST(GDK_EXTRA_LIBS)
155 AC_SUBST(GDK_EXTRA_CFLAGS)
156 AC_SUBST(GDK_DEP_LIBS)
157 AC_SUBST(GDK_DEP_CFLAGS)
158
159
160-########################################
161-# Check for Accessibility Toolkit flags
162-########################################
163-
164-ATK_PACKAGES=atk
165-AC_MSG_CHECKING(ATK flags)
166-if $PKG_CONFIG --exists $ATK_PACKAGES ; then
167- ATK_CFLAGS=`$PKG_CONFIG --cflags $ATK_PACKAGES`
168- ATK_LIBS=`$PKG_CONFIG --libs $ATK_PACKAGES`
169-
170- AC_MSG_RESULT($ATK_CFLAGS $ATK_LIBS)
171-else
172- AC_MSG_ERROR([
173-*** Accessibility Toolkit not found. Accessibility Toolkit is required
174-*** to build GTK+.
175-])
176-fi
177-
178-if $PKG_CONFIG --uninstalled $ATK_PACKAGES; then
179- :
180-else
181- gtk_save_LIBS="$LIBS"
182- LIBS="$ATK_LIBS $LIBS"
183- AC_TRY_LINK_FUNC(atk_object_get_type, : , AC_MSG_ERROR([
184- *** Cannot link to Accessibility Toolkit. Accessibility Toolkit is required
185- *** to build GTK+]))
186- LIBS="$gtk_save_LIBS"
187-fi
188-
189-GTK_PACKAGES="atk cairo"
190+GTK_PACKAGES=
191 GTK_EXTRA_LIBS=
192 GTK_EXTRA_CFLAGS=
193-GTK_DEP_LIBS="$GDK_EXTRA_LIBS $GTK_DEP_LIBS_FOR_X `$PKG_CONFIG --libs $GDK_PIXBUF_PACKAGES $PANGO_PACKAGES $GTK_PACKAGES_FOR_X $GTK_PACKAGES` $GTK_EXTRA_LIBS $GDK_PIXBUF_EXTRA_LIBS"
194+GTK_DEP_LIBS="$GDK_EXTRA_LIBS $GTK_DEP_LIBS_FOR_X `$PKG_CONFIG --libs $GDK_PIXBUF_PACKAGES $GTK_PACKAGES_FOR_X $GTK_PACKAGES` $GTK_EXTRA_LIBS $GDK_PIXBUF_EXTRA_LIBS"
195 GTK_DEP_CFLAGS="`$PKG_CONFIG --cflags gthread-2.0 $GDK_PIXBUF_PACKAGES $GDK_PACKAGES $GTK_PACKAGES` $GDK_PIXBUF_EXTRA_CFLAGS $GDK_EXTRA_CFLAGS $GTK_EXTRA_CFLAGS"
196
197 if test x"$os_win32" = xyes; then
198 GTK_EXTRA_CFLAGS="$msnative_struct"
199 fi
200@@ -1567,21 +1472,10 @@ LIBS="$CUPS_LIBS"
201 AC_CHECK_FUNCS(httpGetAuthString)
202 LIBS="$gtk_save_libs"
203
204 gtk_save_cppflags="$CPPFLAGS"
205 CPPFLAGS="$CPPFLAGS $GTK_DEP_CFLAGS"
206-
207-AC_CHECK_HEADER(cairo-pdf.h,,AC_MSG_ERROR([
208-*** Can't find cairo-pdf.h. You must build Cairo with the pdf
209-*** backend enabled.]))
210-
211-if test "$os_win32" != "yes"; then
212- AC_CHECK_HEADER(cairo-ps.h,,AC_MSG_ERROR([
213-*** Can't find cairo-ps.h. You must build Cairo with the
214-*** postscript backend enabled.]))
215-fi
216-
217 CPPFLAGS="$gtk_save_cppflags"
218
219
220 AC_ARG_ENABLE(test-print-backend,
221 [AC_HELP_STRING([--enable-test-print-backend],
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/cellrenderer-cairo.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/cellrenderer-cairo.patch
new file mode 100644
index 0000000000..4439e69fb6
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/cellrenderer-cairo.patch
@@ -0,0 +1,32 @@
1Index: gtk/gtkcellrenderer.c
2===================================================================
3RCS file: /cvs/gnome/gtk+/gtk/gtkcellrenderer.c,v
4retrieving revision 1.55
5diff -u -r1.55 gtkcellrenderer.c
6--- gtk/gtkcellrenderer.c 14 May 2006 04:25:28 -0000 1.55
7+++ gtk/gtkcellrenderer.c 30 Jun 2006 10:57:43 -0000
8@@ -551,6 +551,7 @@
9
10 if (cell->cell_background_set && !selected)
11 {
12+#ifdef USE_CAIRO_INTERNALLY
13 cairo_t *cr = gdk_cairo_create (window);
14
15 gdk_cairo_rectangle (cr, background_area);
16@@ -558,6 +559,16 @@
17 cairo_fill (cr);
18
19 cairo_destroy (cr);
20+#else
21+ GdkGC *gc;
22+
23+ gc = gdk_gc_new (window);
24+ gdk_gc_set_rgb_fg_color (gc, &priv->cell_background);
25+ gdk_draw_rectangle (window, gc, TRUE,
26+ background_area->x, background_area->y,
27+ background_area->width, background_area->height);
28+ g_object_unref (gc);
29+#endif
30 }
31
32 GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/combo-arrow-size.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/combo-arrow-size.patch
new file mode 100644
index 0000000000..d44c454ce3
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/combo-arrow-size.patch
@@ -0,0 +1,67 @@
1Index: gtk/gtkcombobox.c
2===================================================================
3RCS file: /cvs/gnome/gtk+/gtk/gtkcombobox.c,v
4retrieving revision 1.185
5diff -u -p -r1.185 gtkcombobox.c
6--- gtk/gtkcombobox.c 12 Oct 2006 13:48:07 -0000 1.185
7+++ gtk/gtkcombobox.c 1 Nov 2006 19:01:09 -0000
8@@ -756,6 +756,25 @@ gtk_combo_box_class_init (GtkComboBoxCla
9 FALSE,
10 GTK_PARAM_READABLE));
11
12+ /**
13+ * GtkComboBox:arrow-size:
14+ *
15+ * Sets the minimum size of the arrow in the combo box. Note
16+ * that the arrow size is coupled to the font size, so in case
17+ * a larger font is used, the arrow will be larger than set
18+ * by arrow size.
19+ *
20+ * Since: 2.12
21+ */
22+ gtk_widget_class_install_style_property (widget_class,
23+ g_param_spec_int ("arrow-size",
24+ P_("Arrow Size"),
25+ P_("The minimum size of the arrow in the combo box"),
26+ 0,
27+ G_MAXINT,
28+ 15,
29+ GTK_PARAM_READABLE));
30+
31 g_type_class_add_private (object_class, sizeof (GtkComboBoxPrivate));
32 }
33
34@@ -1897,7 +1916,12 @@ gtk_combo_box_size_request (GtkWidget
35 {
36 gint width, height;
37 gint focus_width, focus_pad;
38+ gint font_size;
39+ gint arrow_size;
40 GtkRequisition bin_req;
41+ PangoContext *context;
42+ PangoFontMetrics *metrics;
43+ PangoFontDescription *font_desc;
44
45 GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
46
47@@ -1910,7 +1934,20 @@ gtk_combo_box_size_request (GtkWidget
48 gtk_widget_style_get (GTK_WIDGET (widget),
49 "focus-line-width", &focus_width,
50 "focus-padding", &focus_pad,
51+ "arrow-size", &arrow_size,
52 NULL);
53+
54+ font_desc = GTK_BIN (widget)->child->style->font_desc;
55+ context = gtk_widget_get_pango_context (widget);
56+ metrics = pango_context_get_metrics (context, font_desc,
57+ pango_context_get_language (context));
58+ font_size = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
59+ pango_font_metrics_get_descent (metrics));
60+ pango_font_metrics_unref (metrics);
61+
62+ arrow_size = MAX (arrow_size, font_size);
63+
64+ gtk_widget_set_size_request (combo_box->priv->arrow, arrow_size, arrow_size);
65
66 if (!combo_box->priv->tree_view)
67 {
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/disable-print.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/disable-print.patch
new file mode 100644
index 0000000000..13cbd91d77
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/disable-print.patch
@@ -0,0 +1,26 @@
1--- gtk+-2.12.0/configure.in~ 2006-07-05 18:11:44.000000000 +0200
2+++ gtk+-2.12.0/configure.in 2006-07-05 18:11:44.000000000 +0200
3@@ -1554,22 +1554 @@
4-AC_PATH_PROG(CUPS_CONFIG, cups-config, no)
5-if test "x$CUPS_CONFIG" != "xno"; then
6- CUPS_CFLAGS=`$CUPS_CONFIG --cflags | sed 's/-O[0-9]*//' | sed 's/-m[^\t]*//g'`
7- CUPS_LIBS=`$CUPS_CONFIG --libs`
8-
9- CUPS_API_VERSION=`$CUPS_CONFIG --api-version`
10- CUPS_API_MAJOR=`echo $ECHO_N $CUPS_API_VERSION | awk -F. '{print $1}'`
11- CUPS_API_MINOR=`echo $ECHO_N $CUPS_API_VERSION | awk -F. '{print $2}'`
12-
13- if test $CUPS_API_MAJOR -gt 1 -o \
14- $CUPS_API_MAJOR -eq 1 -a $CUPS_API_MINOR -ge 2; then
15- AC_DEFINE(HAVE_CUPS_API_1_2)
16- fi
17-
18- AC_SUBST(CUPS_API_MAJOR)
19- AC_SUBST(CUPS_API_MINOR)
20- AC_SUBST(CUPS_CFLAGS)
21- AC_SUBST(CUPS_LIBS)
22-
23- AC_CHECK_HEADER(cups/cups.h,,AC_MSG_ERROR([[*** Sorry, cups-config present but cups/cups.h missing.]]))
24-fi
25-AM_CONDITIONAL(HAVE_CUPS, test "x$CUPS_CONFIG" != "xno")
26+AM_CONDITIONAL(HAVE_CUPS, false)
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/entry-cairo.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/entry-cairo.patch
new file mode 100644
index 0000000000..3313e7f132
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/entry-cairo.patch
@@ -0,0 +1,103 @@
1Index: gtk/gtkentry.c
2===================================================================
3RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
4retrieving revision 1.317
5diff -u -r1.317 gtkentry.c
6--- gtk/gtkentry.c 29 Jun 2006 09:18:05 -0000 1.317
7+++ gtk/gtkentry.c 2 Jul 2006 14:14:24 -0000
8@@ -3337,7 +3337,9 @@
9 if (GTK_WIDGET_DRAWABLE (entry))
10 {
11 PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
12+#ifdef USE_CAIRO_INTERNALLY
13 cairo_t *cr;
14+#endif
15 gint x, y;
16 gint start_pos, end_pos;
17
18@@ -3345,23 +3347,35 @@
19
20 get_layout_position (entry, &x, &y);
21
22+#ifdef USE_CAIRO_INTERNALLY
23 cr = gdk_cairo_create (entry->text_area);
24
25 cairo_move_to (cr, x, y);
26 gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
27 pango_cairo_show_layout (cr, layout);
28+#else
29+ gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
30+ x, y,
31+ layout);
32+#endif
33
34 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
35 {
36 gint *ranges;
37 gint n_ranges, i;
38 PangoRectangle logical_rect;
39- GdkColor *selection_color, *text_color;
40 GtkBorder inner_border;
41+#ifdef USE_CAIRO_INTERNALLY
42+ GdkColor *selection_color, *text_color;
43+#else
44+ GdkGC *selection_gc, *text_gc;
45+ GdkRegion *clip_region;
46+#endif
47
48 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
49 gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
50
51+#ifdef USE_CAIRO_INTERNALLY
52 if (GTK_WIDGET_HAS_FOCUS (entry))
53 {
54 selection_color = &widget->style->base [GTK_STATE_SELECTED];
55@@ -3390,11 +3404,46 @@
56 cairo_move_to (cr, x, y);
57 gdk_cairo_set_source_color (cr, text_color);
58 pango_cairo_show_layout (cr, layout);
59-
60+#else
61+ if (GTK_WIDGET_HAS_FOCUS (entry))
62+ {
63+ selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
64+ text_gc = widget->style->text_gc [GTK_STATE_SELECTED];
65+ }
66+ else
67+ {
68+ selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE];
69+ text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
70+ }
71+
72+ clip_region = gdk_region_new ();
73+ for (i = 0; i < n_ranges; ++i)
74+ {
75+ GdkRectangle rect;
76+
77+ rect.x = inner_border.left - entry->scroll_offset + ranges[2 * i];
78+ rect.y = y;
79+ rect.width = ranges[2 * i + 1];
80+ rect.height = logical_rect.height;
81+
82+ gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
83+ rect.x, rect.y, rect.width, rect.height);
84+
85+ gdk_region_union_with_rect (clip_region, &rect);
86+ }
87+
88+ gdk_gc_set_clip_region (text_gc, clip_region);
89+ gdk_draw_layout (entry->text_area, text_gc,
90+ x, y,
91+ layout);
92+ gdk_gc_set_clip_region (text_gc, NULL);
93+ gdk_region_destroy (clip_region);
94+#endif
95 g_free (ranges);
96 }
97-
98+#ifdef USE_CAIRO_INTERNALLY
99 cairo_destroy (cr);
100+#endif
101 }
102 }
103
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch
new file mode 100644
index 0000000000..146316c9c1
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch
@@ -0,0 +1,9521 @@
1Index: gtk+-2.12.5/gtk/gtkfilechooserdefault.c
2================ ===================================================
3--- gtk+-2.12.5/gtk/gtkfilechooserdefault.c (revision 19337)
4+++ gtk+-2.12.5/gtk/gtkfilechooserdefault.c (working copy)
5@@ -27,12 +27,12 @@
6 #include "gtkcelllayout.h"
7 #include "gtkcellrendererpixbuf.h"
8 #include "gtkcellrenderertext.h"
9+#include "gtkcellrenderertext.h"
10 #include "gtkcheckmenuitem.h"
11 #include "gtkclipboard.h"
12 #include "gtkcombobox.h"
13 #include "gtkentry.h"
14 #include "gtkeventbox.h"
15-#include "gtkexpander.h"
16 #include "gtkfilechooserprivate.h"
17 #include "gtkfilechooserdefault.h"
18 #include "gtkfilechooserembed.h"
19@@ -53,17 +53,13 @@
20 #include "gtkmarshalers.h"
21 #include "gtkmenuitem.h"
22 #include "gtkmessagedialog.h"
23-#include "gtkpathbar.h"
24 #include "gtkprivate.h"
25 #include "gtkradiobutton.h"
26-#include "gtkrecentfilter.h"
27-#include "gtkrecentmanager.h"
28 #include "gtkscrolledwindow.h"
29 #include "gtkseparatormenuitem.h"
30 #include "gtksizegroup.h"
31 #include "gtkstock.h"
32 #include "gtktable.h"
33-#include "gtktooltip.h"
34 #include "gtktreednd.h"
35 #include "gtktreeprivate.h"
36 #include "gtktreeselection.h"
37@@ -81,8 +77,6 @@
38 #include <errno.h>
39 #include <string.h>
40 #include <time.h>
41-#include <sys/stat.h>
42-#include <sys/types.h>
43
44
45 #ifdef HAVE_UNISTD_H
46@@ -92,6 +86,8 @@
47 #include <io.h>
48 #endif
49
50+#define DEFAULT_SPACING 5
51+
52 /* Profiling stuff */
53 #undef PROFILE_FILE_CHOOSER
54 #ifdef PROFILE_FILE_CHOOSER
55@@ -150,6 +145,7 @@
56 #define GTK_FILE_CHOOSER_DEFAULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass))
57
58 #define MAX_LOADING_TIME 500
59+#define LONG_CLICK_LENGTH 500
60
61 struct _GtkFileChooserDefaultClass
62 {
63@@ -163,38 +159,12 @@
64 UP_FOLDER,
65 DOWN_FOLDER,
66 HOME_FOLDER,
67- DESKTOP_FOLDER,
68- QUICK_BOOKMARK,
69- LOCATION_TOGGLE_POPUP,
70 SHOW_HIDDEN,
71- SEARCH_SHORTCUT,
72- RECENT_SHORTCUT,
73-
74 LAST_SIGNAL
75 };
76
77 static guint signals[LAST_SIGNAL] = { 0 };
78
79-/* Column numbers for the shortcuts tree. Keep these in sync with shortcuts_model_create() */
80-enum {
81- SHORTCUTS_COL_PIXBUF,
82- SHORTCUTS_COL_NAME,
83- SHORTCUTS_COL_DATA,
84- SHORTCUTS_COL_TYPE,
85- SHORTCUTS_COL_REMOVABLE,
86- SHORTCUTS_COL_PIXBUF_VISIBLE,
87- SHORTCUTS_COL_HANDLE,
88- SHORTCUTS_COL_NUM_COLUMNS
89-};
90-
91-typedef enum {
92- SHORTCUT_TYPE_PATH,
93- SHORTCUT_TYPE_VOLUME,
94- SHORTCUT_TYPE_SEPARATOR,
95- SHORTCUT_TYPE_SEARCH,
96- SHORTCUT_TYPE_RECENT
97-} ShortcutType;
98-
99 /* Column numbers for the file list */
100 enum {
101 FILE_LIST_COL_NAME,
102@@ -203,100 +173,10 @@
103 FILE_LIST_COL_NUM_COLUMNS
104 };
105
106-/* Column numbers for the search model.
107- * Keep this in sync with search_setup_model()
108- */
109-enum {
110- SEARCH_MODEL_COL_PATH,
111- SEARCH_MODEL_COL_DISPLAY_NAME,
112- SEARCH_MODEL_COL_COLLATION_KEY,
113- SEARCH_MODEL_COL_STAT,
114- SEARCH_MODEL_COL_HANDLE,
115- SEARCH_MODEL_COL_PIXBUF,
116- SEARCH_MODEL_COL_MIME_TYPE,
117- SEARCH_MODEL_COL_IS_FOLDER,
118- SEARCH_MODEL_COL_NUM_COLUMNS
119-};
120-
121-enum {
122- RECENT_MODEL_COL_PATH,
123- RECENT_MODEL_COL_DISPLAY_NAME,
124- RECENT_MODEL_COL_INFO,
125- RECENT_MODEL_COL_IS_FOLDER,
126- RECENT_MODEL_COL_HANDLE,
127- RECENT_MODEL_COL_NUM_COLUMNS
128-};
129-
130-/* Identifiers for target types */
131-enum {
132- GTK_TREE_MODEL_ROW,
133- TEXT_URI_LIST
134-};
135-
136-/* Target types for dragging from the shortcuts list */
137-static const GtkTargetEntry shortcuts_source_targets[] = {
138- { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW }
139-};
140-
141-static const int num_shortcuts_source_targets = G_N_ELEMENTS (shortcuts_source_targets);
142-
143-/* Target types for dropping into the shortcuts list */
144-static const GtkTargetEntry shortcuts_dest_targets[] = {
145- { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW },
146- { "text/uri-list", 0, TEXT_URI_LIST }
147-};
148-
149-static const int num_shortcuts_dest_targets = G_N_ELEMENTS (shortcuts_dest_targets);
150-
151-/* Target types for DnD from the file list */
152-static const GtkTargetEntry file_list_source_targets[] = {
153- { "text/uri-list", 0, TEXT_URI_LIST }
154-};
155-
156-static const int num_file_list_source_targets = G_N_ELEMENTS (file_list_source_targets);
157-
158-/* Target types for dropping into the file list */
159-static const GtkTargetEntry file_list_dest_targets[] = {
160- { "text/uri-list", 0, TEXT_URI_LIST }
161-};
162-
163-static const int num_file_list_dest_targets = G_N_ELEMENTS (file_list_dest_targets);
164-
165-/* Target types for dragging from the recent files list */
166-static const GtkTargetEntry recent_list_source_targets[] = {
167- { "text/uri-list", 0, TEXT_URI_LIST }
168-};
169-
170-static const int num_recent_list_source_targets = G_N_ELEMENTS (recent_list_source_targets);
171-
172-static gboolean
173-search_is_possible (GtkFileChooserDefault *impl)
174-{
175- if (impl->search_engine == NULL)
176- impl->search_engine = _gtk_search_engine_new ();
177-
178- return impl->search_engine != NULL;
179-}
180-
181-/* Interesting places in the shortcuts bar */
182-typedef enum {
183- SHORTCUTS_SEARCH,
184- SHORTCUTS_RECENT,
185- SHORTCUTS_RECENT_SEPARATOR,
186- SHORTCUTS_HOME,
187- SHORTCUTS_DESKTOP,
188- SHORTCUTS_VOLUMES,
189- SHORTCUTS_SHORTCUTS,
190- SHORTCUTS_BOOKMARKS_SEPARATOR,
191- SHORTCUTS_BOOKMARKS,
192- SHORTCUTS_CURRENT_FOLDER_SEPARATOR,
193- SHORTCUTS_CURRENT_FOLDER
194-} ShortcutsIndex;
195-
196 /* Icon size for if we can't get it from the theme */
197-#define FALLBACK_ICON_SIZE 16
198+#define FALLBACK_ICON_SIZE 24
199
200-#define PREVIEW_HBOX_SPACING 12
201+#define LIST_HBOX_SPACING DEFAULT_SPACING
202 #define NUM_LINES 45
203 #define NUM_CHARS 60
204
205@@ -369,52 +248,17 @@
206 static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed);
207 static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed);
208
209-static void location_popup_handler (GtkFileChooserDefault *impl,
210- const gchar *path);
211-static void location_popup_on_paste_handler (GtkFileChooserDefault *impl);
212-static void location_toggle_popup_handler (GtkFileChooserDefault *impl);
213-static void up_folder_handler (GtkFileChooserDefault *impl);
214-static void down_folder_handler (GtkFileChooserDefault *impl);
215-static void home_folder_handler (GtkFileChooserDefault *impl);
216-static void desktop_folder_handler (GtkFileChooserDefault *impl);
217-static void quick_bookmark_handler (GtkFileChooserDefault *impl,
218- gint bookmark_index);
219-static void show_hidden_handler (GtkFileChooserDefault *impl);
220-static void search_shortcut_handler (GtkFileChooserDefault *impl);
221-static void recent_shortcut_handler (GtkFileChooserDefault *impl);
222-static void update_appearance (GtkFileChooserDefault *impl);
223+static void up_folder_handler (GtkFileChooserDefault *impl);
224+static void down_folder_handler (GtkFileChooserDefault *impl);
225+static void home_folder_handler (GtkFileChooserDefault *impl);
226+static void show_hidden_handler (GtkFileChooserDefault *impl);
227+static void update_appearance (GtkFileChooserDefault *impl);
228
229-static void set_current_filter (GtkFileChooserDefault *impl,
230- GtkFileFilter *filter);
231-static void check_preview_change (GtkFileChooserDefault *impl);
232-
233 static void filter_combo_changed (GtkComboBox *combo_box,
234 GtkFileChooserDefault *impl);
235-static void shortcuts_row_activated_cb (GtkTreeView *tree_view,
236- GtkTreePath *path,
237- GtkTreeViewColumn *column,
238- GtkFileChooserDefault *impl);
239
240-static gboolean shortcuts_key_press_event_cb (GtkWidget *widget,
241- GdkEventKey *event,
242- GtkFileChooserDefault *impl);
243-
244-static gboolean shortcuts_select_func (GtkTreeSelection *selection,
245- GtkTreeModel *model,
246- GtkTreePath *path,
247- gboolean path_currently_selected,
248- gpointer data);
249-static gboolean shortcuts_get_selected (GtkFileChooserDefault *impl,
250- GtkTreeIter *iter);
251-static void shortcuts_activate_iter (GtkFileChooserDefault *impl,
252- GtkTreeIter *iter);
253-static int shortcuts_get_index (GtkFileChooserDefault *impl,
254- ShortcutsIndex where);
255-static int shortcut_find_position (GtkFileChooserDefault *impl,
256- const GtkFilePath *path);
257-
258-static void bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl);
259-
260+static void set_current_filter (GtkFileChooserDefault *impl,
261+ GtkFileFilter *filter);
262 static gboolean list_select_func (GtkTreeSelection *selection,
263 GtkTreeModel *model,
264 GtkTreePath *path,
265@@ -433,19 +277,6 @@
266 GtkTreeIter *iter,
267 gpointer user_data);
268
269-static void path_bar_clicked (GtkPathBar *path_bar,
270- GtkFilePath *file_path,
271- GtkFilePath *child_path,
272- gboolean child_is_hidden,
273- GtkFileChooserDefault *impl);
274-
275-static void add_bookmark_button_clicked_cb (GtkButton *button,
276- GtkFileChooserDefault *impl);
277-static void remove_bookmark_button_clicked_cb (GtkButton *button,
278- GtkFileChooserDefault *impl);
279-static void save_folder_combo_changed_cb (GtkComboBox *combo,
280- GtkFileChooserDefault *impl);
281-
282 static void list_icon_data_func (GtkTreeViewColumn *tree_column,
283 GtkCellRenderer *cell,
284 GtkTreeModel *tree_model,
285@@ -477,115 +308,8 @@
286
287 static void location_button_toggled_cb (GtkToggleButton *toggle,
288 GtkFileChooserDefault *impl);
289-static void location_switch_to_path_bar (GtkFileChooserDefault *impl);
290+static void settings_load (GtkFileChooserDefault *impl);
291
292-static void search_stop_searching (GtkFileChooserDefault *impl,
293- gboolean remove_query);
294-static void search_clear_model (GtkFileChooserDefault *impl,
295- gboolean remove_from_treeview);
296-static gboolean search_should_respond (GtkFileChooserDefault *impl);
297-static void search_switch_to_browse_mode (GtkFileChooserDefault *impl);
298-static GSList *search_get_selected_paths (GtkFileChooserDefault *impl);
299-static void search_entry_activate_cb (GtkEntry *entry,
300- gpointer data);
301-static void settings_load (GtkFileChooserDefault *impl);
302-static void search_get_valid_child_iter (GtkFileChooserDefault *impl,
303- GtkTreeIter *child_iter,
304- GtkTreeIter *iter);
305-
306-static void recent_manager_update (GtkFileChooserDefault *impl);
307-static void recent_stop_loading (GtkFileChooserDefault *impl);
308-static void recent_clear_model (GtkFileChooserDefault *impl,
309- gboolean remove_from_treeview);
310-static gboolean recent_should_respond (GtkFileChooserDefault *impl);
311-static void recent_switch_to_browse_mode (GtkFileChooserDefault *impl);
312-static GSList * recent_get_selected_paths (GtkFileChooserDefault *impl);
313-static void recent_get_valid_child_iter (GtkFileChooserDefault *impl,
314- GtkTreeIter *child_iter,
315- GtkTreeIter *iter);
316-
317-
318-
319-
320-/* Drag and drop interface declarations */
321-
322-typedef struct {
323- GtkTreeModelFilter parent;
324-
325- GtkFileChooserDefault *impl;
326-} ShortcutsPaneModelFilter;
327-
328-typedef struct {
329- GtkTreeModelFilterClass parent_class;
330-} ShortcutsPaneModelFilterClass;
331-
332-#define SHORTCUTS_PANE_MODEL_FILTER_TYPE (_shortcuts_pane_model_filter_get_type ())
333-#define SHORTCUTS_PANE_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHORTCUTS_PANE_MODEL_FILTER_TYPE, ShortcutsPaneModelFilter))
334-
335-static void shortcuts_pane_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface);
336-
337-G_DEFINE_TYPE_WITH_CODE (ShortcutsPaneModelFilter,
338- _shortcuts_pane_model_filter,
339- GTK_TYPE_TREE_MODEL_FILTER,
340- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
341- shortcuts_pane_model_filter_drag_source_iface_init))
342-
343-static GtkTreeModel *shortcuts_pane_model_filter_new (GtkFileChooserDefault *impl,
344- GtkTreeModel *child_model,
345- GtkTreePath *root);
346-
347-
348-typedef struct {
349- GtkTreeModelSort parent;
350-
351- GtkFileChooserDefault *impl;
352-} RecentModelSort;
353-
354-typedef struct {
355- GtkTreeModelSortClass parent_class;
356-} RecentModelSortClass;
357-
358-#define RECENT_MODEL_SORT_TYPE (_recent_model_sort_get_type ())
359-#define RECENT_MODEL_SORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RECENT_MODEL_SORT_TYPE, RecentModelSort))
360-
361-static void recent_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface);
362-
363-G_DEFINE_TYPE_WITH_CODE (RecentModelSort,
364- _recent_model_sort,
365- GTK_TYPE_TREE_MODEL_SORT,
366- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
367- recent_model_sort_drag_source_iface_init));
368-
369-static GtkTreeModel *recent_model_sort_new (GtkFileChooserDefault *impl,
370- GtkTreeModel *child_model);
371-
372-
373-typedef struct {
374- GtkTreeModelSort parent;
375-
376- GtkFileChooserDefault *impl;
377-} SearchModelSort;
378-
379-typedef struct {
380- GtkTreeModelSortClass parent_class;
381-} SearchModelSortClass;
382-
383-#define SEARCH_MODEL_SORT_TYPE (_search_model_sort_get_type ())
384-#define SEARCH_MODEL_SORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEARCH_MODEL_SORT_TYPE, SearchModelSort))
385-
386-static void search_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface);
387-
388-G_DEFINE_TYPE_WITH_CODE (SearchModelSort,
389- _search_model_sort,
390- GTK_TYPE_TREE_MODEL_SORT,
391- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
392- search_model_sort_drag_source_iface_init));
393-
394-static GtkTreeModel *search_model_sort_new (GtkFileChooserDefault *impl,
395- GtkTreeModel *child_model);
396-
397-
398-
399 G_DEFINE_TYPE_WITH_CODE (GtkFileChooserDefault, _gtk_file_chooser_default, GTK_TYPE_VBOX,
400 G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
401 gtk_file_chooser_default_iface_init)
402@@ -595,13 +319,9 @@
403 static void
404 _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
405 {
406- static const guint quick_bookmark_keyvals[10] = {
407- GDK_1, GDK_2, GDK_3, GDK_4, GDK_5, GDK_6, GDK_7, GDK_8, GDK_9, GDK_0
408- };
409 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
410 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
411 GtkBindingSet *binding_set;
412- int i;
413
414 gobject_class->finalize = gtk_file_chooser_default_finalize;
415 gobject_class->constructor = gtk_file_chooser_default_constructor;
416@@ -621,7 +341,7 @@
417 _gtk_binding_signal_new (I_("location-popup"),
418 G_OBJECT_CLASS_TYPE (class),
419 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
420- G_CALLBACK (location_popup_handler),
421+ NULL,
422 NULL, NULL,
423 _gtk_marshal_VOID__STRING,
424 G_TYPE_NONE, 1, G_TYPE_STRING);
425@@ -629,18 +349,10 @@
426 _gtk_binding_signal_new ("location-popup-on-paste",
427 G_OBJECT_CLASS_TYPE (class),
428 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
429- G_CALLBACK (location_popup_on_paste_handler),
430+ NULL,
431 NULL, NULL,
432 _gtk_marshal_VOID__VOID,
433 G_TYPE_NONE, 0);
434- signals[LOCATION_TOGGLE_POPUP] =
435- _gtk_binding_signal_new (I_("location-toggle-popup"),
436- G_OBJECT_CLASS_TYPE (class),
437- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
438- G_CALLBACK (location_toggle_popup_handler),
439- NULL, NULL,
440- _gtk_marshal_VOID__VOID,
441- G_TYPE_NONE, 0);
442 signals[UP_FOLDER] =
443 _gtk_binding_signal_new (I_("up-folder"),
444 G_OBJECT_CLASS_TYPE (class),
445@@ -665,22 +377,6 @@
446 NULL, NULL,
447 _gtk_marshal_VOID__VOID,
448 G_TYPE_NONE, 0);
449- signals[DESKTOP_FOLDER] =
450- _gtk_binding_signal_new (I_("desktop-folder"),
451- G_OBJECT_CLASS_TYPE (class),
452- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
453- G_CALLBACK (desktop_folder_handler),
454- NULL, NULL,
455- _gtk_marshal_VOID__VOID,
456- G_TYPE_NONE, 0);
457- signals[QUICK_BOOKMARK] =
458- _gtk_binding_signal_new (I_("quick-bookmark"),
459- G_OBJECT_CLASS_TYPE (class),
460- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
461- G_CALLBACK (quick_bookmark_handler),
462- NULL, NULL,
463- _gtk_marshal_VOID__INT,
464- G_TYPE_NONE, 1, G_TYPE_INT);
465 signals[SHOW_HIDDEN] =
466 _gtk_binding_signal_new ("show-hidden",
467 G_OBJECT_CLASS_TYPE (class),
468@@ -689,22 +385,6 @@
469 NULL, NULL,
470 _gtk_marshal_VOID__VOID,
471 G_TYPE_NONE, 0);
472- signals[SEARCH_SHORTCUT] =
473- _gtk_binding_signal_new ("search-shortcut",
474- G_OBJECT_CLASS_TYPE (class),
475- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
476- G_CALLBACK (search_shortcut_handler),
477- NULL, NULL,
478- _gtk_marshal_VOID__VOID,
479- G_TYPE_NONE, 0);
480- signals[RECENT_SHORTCUT] =
481- _gtk_binding_signal_new ("recent-shortcut",
482- G_OBJECT_CLASS_TYPE (class),
483- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
484- G_CALLBACK (recent_shortcut_handler),
485- NULL, NULL,
486- _gtk_marshal_VOID__VOID,
487- G_TYPE_NONE, 0);
488
489 binding_set = gtk_binding_set_by_class (class);
490
491@@ -764,29 +444,11 @@
492 "home-folder",
493 0);
494 gtk_binding_entry_add_signal (binding_set,
495- GDK_d, GDK_MOD1_MASK,
496- "desktop-folder",
497- 0);
498- gtk_binding_entry_add_signal (binding_set,
499 GDK_h, GDK_CONTROL_MASK,
500 "show-hidden",
501 0);
502- gtk_binding_entry_add_signal (binding_set,
503- GDK_s, GDK_MOD1_MASK,
504- "search-shortcut",
505- 0);
506- gtk_binding_entry_add_signal (binding_set,
507- GDK_r, GDK_MOD1_MASK,
508- "recent-shortcut",
509- 0);
510
511- for (i = 0; i < 10; i++)
512- gtk_binding_entry_add_signal (binding_set,
513- quick_bookmark_keyvals[i], GDK_MOD1_MASK,
514- "quick-bookmark",
515- 1, G_TYPE_INT, i);
516-
517 _gtk_file_chooser_install_properties (gobject_class);
518 }
519
520 static void
521@@ -797,7 +465,6 @@
522 iface->select_all = gtk_file_chooser_default_select_all;
523 iface->unselect_all = gtk_file_chooser_default_unselect_all;
524 iface->get_paths = gtk_file_chooser_default_get_paths;
525- iface->get_preview_path = gtk_file_chooser_default_get_preview_path;
526 iface->get_file_system = gtk_file_chooser_default_get_file_system;
527 iface->set_current_folder = gtk_file_chooser_default_set_current_folder;
528 iface->get_current_folder = gtk_file_chooser_default_get_current_folder;
529@@ -805,9 +472,12 @@
530 iface->add_filter = gtk_file_chooser_default_add_filter;
531 iface->remove_filter = gtk_file_chooser_default_remove_filter;
532 iface->list_filters = gtk_file_chooser_default_list_filters;
533+
534+ /* these are only stubs */
535+ iface->get_preview_path = gtk_file_chooser_default_get_preview_path;
536 iface->add_shortcut_folder = gtk_file_chooser_default_add_shortcut_folder;
537 iface->remove_shortcut_folder = gtk_file_chooser_default_remove_shortcut_folder;
538- iface->list_shortcut_folders = gtk_file_chooser_default_list_shortcut_folders;
539+
540 }
541
542 static void
543@@ -827,87 +497,29 @@
544 access ("MARK: *** CREATE FILE CHOOSER", F_OK);
545 #endif
546 impl->local_only = TRUE;
547- impl->preview_widget_active = TRUE;
548- impl->use_preview_label = TRUE;
549 impl->select_multiple = FALSE;
550 impl->show_hidden = FALSE;
551+ impl->show_create_folder = TRUE;
552 impl->icon_size = FALLBACK_ICON_SIZE;
553 impl->load_state = LOAD_EMPTY;
554 impl->reload_state = RELOAD_EMPTY;
555 impl->pending_select_paths = NULL;
556- impl->location_mode = LOCATION_MODE_PATH_BAR;
557- impl->operation_mode = OPERATION_MODE_BROWSE;
558+ impl->location_mode = LOCATION_MODE_FILENAME_ENTRY;
559+ impl->path_history = NULL;
560
561- gtk_box_set_spacing (GTK_BOX (impl), 12);
562+ gtk_box_set_spacing (GTK_BOX (impl), DEFAULT_SPACING);
563
564 impl->tooltips = gtk_tooltips_new ();
565 g_object_ref_sink (impl->tooltips);
566
567+ if (!impl->root_folder)
568+ impl->root_folder = g_strdup ("/");
569+
570 profile_end ("end", NULL);
571 }
572
573-/* Frees the data columns for the specified iter in the shortcuts model*/
574-static void
575-shortcuts_free_row_data (GtkFileChooserDefault *impl,
576- GtkTreeIter *iter)
577-{
578- gpointer col_data;
579- ShortcutType shortcut_type;
580- GtkFileSystemHandle *handle;
581
582- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter,
583- SHORTCUTS_COL_DATA, &col_data,
584- SHORTCUTS_COL_TYPE, &shortcut_type,
585- SHORTCUTS_COL_HANDLE, &handle,
586- -1);
587-
588- if (handle)
589- gtk_file_system_cancel_operation (handle);
590-
591- if (!(shortcut_type == SHORTCUT_TYPE_PATH ||
592- shortcut_type == SHORTCUT_TYPE_VOLUME) ||
593- !col_data)
594- return;
595-
596- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
597- {
598- GtkFileSystemVolume *volume;
599-
600- volume = col_data;
601- gtk_file_system_volume_free (impl->file_system, volume);
602- }
603- else
604- {
605- GtkFilePath *path;
606-
607- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
608-
609- path = col_data;
610- gtk_file_path_free (path);
611- }
612-}
613-
614-/* Frees all the data columns in the shortcuts model */
615 static void
616-shortcuts_free (GtkFileChooserDefault *impl)
617-{
618- GtkTreeIter iter;
619-
620- if (!impl->shortcuts_model)
621- return;
622-
623- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
624- do
625- {
626- shortcuts_free_row_data (impl, &iter);
627- }
628- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter));
629-
630- g_object_unref (impl->shortcuts_model);
631- impl->shortcuts_model = NULL;
632-}
633-
634-static void
635 pending_select_paths_free (GtkFileChooserDefault *impl)
636 {
637 GSList *l;
638@@ -964,19 +576,28 @@
639 }
640
641 static void
642-gtk_file_chooser_default_finalize (GObject *object)
643+path_history_free (GtkFileChooserDefault *impl)
644 {
645- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
646 GSList *l;
647
648- if (impl->shortcuts_pane_filter_model)
649- g_object_unref (impl->shortcuts_pane_filter_model);
650+ for (l = impl->path_history; l; l = l->next)
651+ {
652+ GtkFilePath *path;
653
654- if (impl->shortcuts_combo_filter_model)
655- g_object_unref (impl->shortcuts_combo_filter_model);
656+ path = l->data;
657+ gtk_file_path_free (path);
658+ }
659
660- shortcuts_free (impl);
661+ g_slist_free (impl->path_history);
662+ impl->path_history = NULL;
663+}
664
665+static void
666+gtk_file_chooser_default_finalize (GObject *object)
667+{
668+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
669+ GSList *l;
670+
671 g_object_unref (impl->file_system);
672
673 g_free (impl->browse_files_last_selected_name);
674@@ -999,8 +620,7 @@
675 if (impl->current_folder)
676 gtk_file_path_free (impl->current_folder);
677
678- if (impl->preview_path)
679- gtk_file_path_free (impl->preview_path);
680+ path_history_free (impl);
681
682 load_remove_timer (impl);
683
684@@ -1011,15 +631,18 @@
685 if (impl->sort_model)
686 g_object_unref (impl->sort_model);
687
688- search_clear_model (impl, FALSE);
689- recent_clear_model (impl, FALSE);
690+ if (impl->list_press_path)
691+ {
692+ gtk_tree_path_free (impl->list_press_path);
693+ impl->list_press_path = NULL;
694+ }
695
696- g_free (impl->preview_display_name);
697-
698 g_free (impl->edited_new_text);
699
700 g_object_unref (impl->tooltips);
701
702+ g_free (impl->root_folder);
703+
704 G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->finalize (object);
705 }
706
707@@ -1104,28 +727,6 @@
708 path, error);
709 }
710
711-/* Shows an error dialog about not being able to add a bookmark */
712-static void
713-error_adding_bookmark_dialog (GtkFileChooserDefault *impl,
714- const GtkFilePath *path,
715- GError *error)
716-{
717- error_dialog (impl,
718- _("Could not add a bookmark"),
719- path, error);
720-}
721-
722-/* Shows an error dialog about not being able to remove a bookmark */
723-static void
724-error_removing_bookmark_dialog (GtkFileChooserDefault *impl,
725- const GtkFilePath *path,
726- GError *error)
727-{
728- error_dialog (impl,
729- _("Could not remove bookmark"),
730- path, error);
731-}
732-
733 /* Shows an error dialog about not being able to create a folder */
734 static void
735 error_creating_folder_dialog (GtkFileChooserDefault *impl,
736@@ -1146,9 +747,9 @@
737 GError *error)
738 {
739 error_dialog (impl,
740- _("The folder could not be created, as a file with the same "
741- "name already exists. Try using a different name for the "
742- "folder, or rename the file first."),
743+ _("The folder could not be created, as a file with the same name "
744+ "already exists. Try using a different name for the folder, "
745+ "or rename the file first."),
746 path, error);
747 }
748
749@@ -1175,514 +776,108 @@
750
751 /* Changes folders, displaying an error dialog if this fails */
752 static gboolean
753-change_folder_and_display_error (GtkFileChooserDefault *impl,
754- const GtkFilePath *path,
755- gboolean clear_entry)
756+change_folder (GtkFileChooserDefault *impl, const GtkFilePath *path,
757+ gboolean errormsg)
758 {
759 GError *error;
760 gboolean result;
761 GtkFilePath *path_copy;
762+ gchar * file_name;
763
764 g_return_val_if_fail (path != NULL, FALSE);
765
766- profile_start ("start", (char *) path);
767-
768- /* We copy the path because of this case:
769- *
770- * list_row_activated()
771- * fetches path from model; path belongs to the model (*)
772- * calls change_folder_and_display_error()
773- * calls _gtk_file_chooser_set_current_folder_path()
774- * changing folders fails, sets model to NULL, thus freeing the path in (*)
775- */
776-
777 path_copy = gtk_file_path_copy (path);
778+ file_name = gtk_file_system_path_to_filename (impl->file_system, path_copy);
779
780- error = NULL;
781- result = gtk_file_chooser_default_update_current_folder (GTK_FILE_CHOOSER (impl), path_copy, TRUE, clear_entry, &error);
782+ if (!file_name)
783+ {
784+ gtk_file_path_free (path_copy);
785+ return 0;
786+ }
787
788- if (!result)
789- error_changing_folder_dialog (impl, path_copy, error);
790+ if (impl->root_folder && file_name[0] == '/' && file_name[1] == 0)
791+ {
792+ /* If changing to / and we have root_folder, change into it instead */
793+ gtk_file_path_free (path_copy);
794+ path_copy = gtk_file_system_filename_to_path (impl->file_system,
795+ impl->root_folder);
796
797- gtk_file_path_free (path_copy);
798+ gtk_widget_set_sensitive (impl->up_button, FALSE);
799+ }
800+ else if (impl->root_folder &&
801+ strcmp (file_name, impl->root_folder) &&
802+ !strncmp (file_name, impl->root_folder, strlen (file_name)))
803+ {
804+ /* refuse to change below the root */
805+ gtk_file_path_free (path_copy);
806+ g_free (file_name);
807+ return 0;
808+ }
809+ else if (!strcmp (file_name, impl->root_folder))
810+ {
811+ gtk_widget_set_sensitive (impl->up_button, FALSE);
812+ }
813+ else if (impl->current_folder && !strcmp (file_name, "/media"))
814+ {
815+ /* Asked to changed into /media -- if we are already in a media
816+ * child folder, we refuse, but if we are in the root, we permit this
817+ */
818+ gchar *name =
819+ gtk_file_system_path_to_filename (impl->file_system,
820+ impl->current_folder);
821
822- profile_end ("end", (char *) path);
823+ if (name && !strncmp (name, "/media", 6))
824+ {
825+ g_free (name);
826+ gtk_file_path_free (path_copy);
827+ g_free (file_name);
828+ return 0;
829+ }
830
831- return result;
832-}
833-
834-static void
835-update_preview_widget_visibility (GtkFileChooserDefault *impl)
836-{
837- if (impl->use_preview_label)
838- {
839- if (!impl->preview_label)
840- {
841- impl->preview_label = gtk_label_new (impl->preview_display_name);
842- gtk_box_pack_start (GTK_BOX (impl->preview_box), impl->preview_label, FALSE, FALSE, 0);
843- gtk_box_reorder_child (GTK_BOX (impl->preview_box), impl->preview_label, 0);
844- gtk_label_set_ellipsize (GTK_LABEL (impl->preview_label), PANGO_ELLIPSIZE_MIDDLE);
845- gtk_widget_show (impl->preview_label);
846- }
847- }
848+ gtk_widget_set_sensitive (impl->up_button, TRUE);
849+ }
850+ else if (!strncmp (file_name, "/media/", 7))
851+ {
852+ /* Changing into a media child -- if it is an immediate child, disable
853+ * the Up button
854+ */
855+ gchar * p = file_name + 7;
856+ gchar * q = strchr (p, '/');
857+ if (!q)
858+ gtk_widget_set_sensitive (impl->up_button, FALSE);
859+ else
860+ gtk_widget_set_sensitive (impl->up_button, TRUE);
861+ }
862 else
863- {
864- if (impl->preview_label)
865- {
866- gtk_widget_destroy (impl->preview_label);
867- impl->preview_label = NULL;
868- }
869- }
870+ {
871+ gtk_widget_set_sensitive (impl->up_button, TRUE);
872+ }
873
874- if (impl->preview_widget_active && impl->preview_widget)
875- gtk_widget_show (impl->preview_box);
876- else
877- gtk_widget_hide (impl->preview_box);
878
879- g_signal_emit_by_name (impl, "default-size-changed");
880-}
881+ error = NULL;
882+ result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path_copy, &error);
883
884-static void
885-set_preview_widget (GtkFileChooserDefault *impl,
886- GtkWidget *preview_widget)
887-{
888- if (preview_widget == impl->preview_widget)
889- return;
890+ if (errormsg && !result)
891+ error_changing_folder_dialog (impl, path_copy, error);
892
893- if (impl->preview_widget)
894- gtk_container_remove (GTK_CONTAINER (impl->preview_box),
895- impl->preview_widget);
896+ gtk_label_set_text (GTK_LABEL (impl->location_label), file_name);
897
898- impl->preview_widget = preview_widget;
899- if (impl->preview_widget)
900- {
901- gtk_widget_show (impl->preview_widget);
902- gtk_box_pack_start (GTK_BOX (impl->preview_box), impl->preview_widget, TRUE, TRUE, 0);
903- gtk_box_reorder_child (GTK_BOX (impl->preview_box),
904- impl->preview_widget,
905- (impl->use_preview_label && impl->preview_label) ? 1 : 0);
906- }
907+ gtk_file_path_free (path_copy);
908+ g_free (file_name);
909
910- update_preview_widget_visibility (impl);
911+ return result;
912 }
913
914-/* Renders a "Search" icon at an appropriate size for a tree view */
915-static GdkPixbuf *
916-render_search_icon (GtkFileChooserDefault *impl)
917+static gboolean
918+change_folder_and_display_error (GtkFileChooserDefault *impl,
919+ const GtkFilePath *path)
920 {
921- return gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FIND, GTK_ICON_SIZE_MENU, NULL);
922+ return change_folder (impl, path, TRUE);
923 }
924
925-static GdkPixbuf *
926-render_recent_icon (GtkFileChooserDefault *impl)
927-{
928- GtkIconTheme *theme;
929- GdkPixbuf *retval;
930
931- if (gtk_widget_has_screen (GTK_WIDGET (impl)))
932- theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
933- else
934- theme = gtk_icon_theme_get_default ();
935-
936- retval = gtk_icon_theme_load_icon (theme, "document-open-recent",
937- impl->icon_size, 0,
938- NULL);
939-
940- /* fallback */
941- if (!retval)
942- retval = gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
943-
944- return retval;
945-}
946-
947-
948-/* Re-reads all the icons for the shortcuts, used when the theme changes */
949-struct ReloadIconsData
950-{
951- GtkFileChooserDefault *impl;
952- GtkTreeRowReference *row_ref;
953-};
954-
955-static void
956-shortcuts_reload_icons_get_info_cb (GtkFileSystemHandle *handle,
957- const GtkFileInfo *info,
958- const GError *error,
959- gpointer user_data)
960-{
961- GdkPixbuf *pixbuf;
962- GtkTreeIter iter;
963- GtkTreePath *path;
964- gboolean cancelled = handle->cancelled;
965- struct ReloadIconsData *data = user_data;
966-
967- if (!g_slist_find (data->impl->reload_icon_handles, handle))
968- goto out;
969-
970- data->impl->reload_icon_handles = g_slist_remove (data->impl->reload_icon_handles, handle);
971-
972- if (cancelled || error)
973- goto out;
974-
975- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->impl),
976- data->impl->icon_size, NULL);
977-
978- path = gtk_tree_row_reference_get_path (data->row_ref);
979- gtk_tree_model_get_iter (GTK_TREE_MODEL (data->impl->shortcuts_model), &iter, path);
980- gtk_list_store_set (data->impl->shortcuts_model, &iter,
981- SHORTCUTS_COL_PIXBUF, pixbuf,
982- -1);
983- gtk_tree_path_free (path);
984-
985- if (pixbuf)
986- g_object_unref (pixbuf);
987-
988-out:
989- gtk_tree_row_reference_free (data->row_ref);
990- g_object_unref (data->impl);
991- g_free (data);
992-
993- g_object_unref (handle);
994-}
995-
996-static void
997-shortcuts_reload_icons (GtkFileChooserDefault *impl)
998-{
999- GSList *l;
1000- GtkTreeIter iter;
1001-
1002- profile_start ("start", NULL);
1003-
1004- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
1005- goto out;
1006-
1007- for (l = impl->reload_icon_handles; l; l = l->next)
1008- {
1009- GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (l->data);
1010- gtk_file_system_cancel_operation (handle);
1011- }
1012- g_slist_free (impl->reload_icon_handles);
1013- impl->reload_icon_handles = NULL;
1014-
1015- do
1016- {
1017- gpointer data;
1018- ShortcutType shortcut_type;
1019- gboolean pixbuf_visible;
1020- GdkPixbuf *pixbuf;
1021-
1022- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
1023- SHORTCUTS_COL_DATA, &data,
1024- SHORTCUTS_COL_TYPE, &shortcut_type,
1025- SHORTCUTS_COL_PIXBUF_VISIBLE, &pixbuf_visible,
1026- -1);
1027-
1028- pixbuf = NULL;
1029- if (pixbuf_visible)
1030- {
1031- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
1032- {
1033- GtkFileSystemVolume *volume;
1034-
1035- volume = data;
1036- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl),
1037- impl->icon_size, NULL);
1038- }
1039- else if (shortcut_type == SHORTCUT_TYPE_PATH)
1040- {
1041- if (gtk_file_system_path_is_local (impl->file_system, (GtkFilePath *)data))
1042- {
1043- const GtkFilePath *path;
1044- struct ReloadIconsData *info;
1045- GtkTreePath *tree_path;
1046- GtkFileSystemHandle *handle;
1047-
1048- path = data;
1049-
1050- info = g_new0 (struct ReloadIconsData, 1);
1051- info->impl = g_object_ref (impl);
1052- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
1053- info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), tree_path);
1054- gtk_tree_path_free (tree_path);
1055-
1056- handle = gtk_file_system_get_info (impl->file_system, path,
1057- GTK_FILE_INFO_ICON,
1058- shortcuts_reload_icons_get_info_cb,
1059- info);
1060- impl->reload_icon_handles = g_slist_append (impl->reload_icon_handles, handle);
1061- }
1062- else
1063- {
1064- GtkIconTheme *icon_theme;
1065-
1066- /* Don't call get_info for remote paths to avoid latency and
1067- * auth dialogs.
1068- * If we switch to a better bookmarks file format (XBEL), we
1069- * should use mime info to get a better icon.
1070- */
1071- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
1072- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-share",
1073- impl->icon_size, 0, NULL);
1074- }
1075- }
1076- else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
1077- {
1078- pixbuf = render_search_icon (impl);
1079- }
1080- else if (shortcut_type == SHORTCUT_TYPE_RECENT)
1081- {
1082- pixbuf = render_recent_icon (impl);
1083- }
1084-
1085- gtk_list_store_set (impl->shortcuts_model, &iter,
1086- SHORTCUTS_COL_PIXBUF, pixbuf,
1087- -1);
1088-
1089- if (pixbuf)
1090- g_object_unref (pixbuf);
1091-
1092- }
1093- }
1094- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model),&iter));
1095-
1096- out:
1097-
1098- profile_end ("end", NULL);
1099-}
1100-
1101-static void
1102-shortcuts_find_folder (GtkFileChooserDefault *impl,
1103- GtkFilePath *folder)
1104-{
1105- GtkTreeSelection *selection;
1106- int pos;
1107- GtkTreePath *path;
1108-
1109- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
1110-
1111- g_assert (folder != NULL);
1112- pos = shortcut_find_position (impl, folder);
1113- if (pos == -1)
1114- {
1115- gtk_tree_selection_unselect_all (selection);
1116- return;
1117- }
1118-
1119- path = gtk_tree_path_new_from_indices (pos, -1);
1120- gtk_tree_selection_select_path (selection, path);
1121- gtk_tree_path_free (path);
1122-}
1123-
1124-/* If a shortcut corresponds to the current folder, selects it */
1125-static void
1126-shortcuts_find_current_folder (GtkFileChooserDefault *impl)
1127-{
1128- shortcuts_find_folder (impl, impl->current_folder);
1129-}
1130-
1131-/* Removes the specified number of rows from the shortcuts list */
1132-static void
1133-shortcuts_remove_rows (GtkFileChooserDefault *impl,
1134- int start_row,
1135- int n_rows)
1136-{
1137- GtkTreePath *path;
1138-
1139- path = gtk_tree_path_new_from_indices (start_row, -1);
1140-
1141- for (; n_rows; n_rows--)
1142- {
1143- GtkTreeIter iter;
1144-
1145- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
1146- g_assert_not_reached ();
1147-
1148- shortcuts_free_row_data (impl, &iter);
1149- gtk_list_store_remove (impl->shortcuts_model, &iter);
1150- }
1151-
1152- gtk_tree_path_free (path);
1153-}
1154-
1155-static void
1156-shortcuts_update_count (GtkFileChooserDefault *impl,
1157- ShortcutsIndex type,
1158- gint value)
1159-{
1160- switch (type)
1161- {
1162- case SHORTCUTS_HOME:
1163- if (value < 0)
1164- impl->has_home = FALSE;
1165- else
1166- impl->has_home = TRUE;
1167- break;
1168-
1169- case SHORTCUTS_DESKTOP:
1170- if (value < 0)
1171- impl->has_desktop = FALSE;
1172- else
1173- impl->has_desktop = TRUE;
1174- break;
1175-
1176- case SHORTCUTS_VOLUMES:
1177- impl->num_volumes += value;
1178- break;
1179-
1180- case SHORTCUTS_SHORTCUTS:
1181- impl->num_shortcuts += value;
1182- break;
1183-
1184- case SHORTCUTS_BOOKMARKS:
1185- impl->num_bookmarks += value;
1186- break;
1187-
1188- case SHORTCUTS_CURRENT_FOLDER:
1189- if (value < 0)
1190- impl->shortcuts_current_folder_active = FALSE;
1191- else
1192- impl->shortcuts_current_folder_active = TRUE;
1193- break;
1194-
1195- default:
1196- /* nothing */
1197- break;
1198- }
1199-}
1200-
1201-struct ShortcutsInsertRequest
1202-{
1203- GtkFileChooserDefault *impl;
1204- GtkFilePath *parent_path;
1205- GtkFilePath *path;
1206- int pos;
1207- char *label_copy;
1208- GtkTreeRowReference *row_ref;
1209- ShortcutsIndex type;
1210- gboolean name_only;
1211- gboolean removable;
1212-};
1213-
1214-static void
1215-get_file_info_finished (GtkFileSystemHandle *handle,
1216- const GtkFileInfo *info,
1217- const GError *error,
1218- gpointer data)
1219-{
1220- gint pos = -1;
1221- gboolean cancelled = handle->cancelled;
1222- GdkPixbuf *pixbuf;
1223- GtkTreePath *path;
1224- GtkTreeIter iter;
1225- GtkFileSystemHandle *model_handle;
1226- struct ShortcutsInsertRequest *request = data;
1227-
1228- path = gtk_tree_row_reference_get_path (request->row_ref);
1229- if (!path)
1230- /* Handle doesn't exist anymore in the model */
1231- goto out;
1232-
1233- pos = gtk_tree_path_get_indices (path)[0];
1234- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->shortcuts_model),
1235- &iter, path);
1236- gtk_tree_path_free (path);
1237-
1238- /* validate handle, else goto out */
1239- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->shortcuts_model), &iter,
1240- SHORTCUTS_COL_HANDLE, &model_handle,
1241- -1);
1242- if (handle != model_handle)
1243- goto out;
1244-
1245- /* set the handle to NULL in the model (we unref later on) */
1246- gtk_list_store_set (request->impl->shortcuts_model, &iter,
1247- SHORTCUTS_COL_HANDLE, NULL,
1248- -1);
1249-
1250- if (cancelled)
1251- goto out;
1252-
1253- if (!info)
1254- {
1255- gtk_list_store_remove (request->impl->shortcuts_model, &iter);
1256- shortcuts_update_count (request->impl, request->type, -1);
1257-
1258- if (request->type == SHORTCUTS_HOME)
1259- {
1260- const char *home = g_get_home_dir ();
1261- GtkFilePath *home_path;
1262-
1263- home_path = gtk_file_system_filename_to_path (request->impl->file_system, home);
1264- error_getting_info_dialog (request->impl, home_path, g_error_copy (error));
1265- gtk_file_path_free (home_path);
1266- }
1267- else if (request->type == SHORTCUTS_CURRENT_FOLDER)
1268- {
1269- /* Remove the current folder separator */
1270- gint separator_pos = shortcuts_get_index (request->impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
1271- shortcuts_remove_rows (request->impl, separator_pos, 1);
1272- }
1273-
1274- goto out;
1275- }
1276-
1277- if (!request->label_copy)
1278- request->label_copy = g_strdup (gtk_file_info_get_display_name (info));
1279- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (request->impl),
1280- request->impl->icon_size, NULL);
1281-
1282- gtk_list_store_set (request->impl->shortcuts_model, &iter,
1283- SHORTCUTS_COL_PIXBUF, pixbuf,
1284- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1285- SHORTCUTS_COL_NAME, request->label_copy,
1286- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH,
1287- SHORTCUTS_COL_REMOVABLE, request->removable,
1288- -1);
1289-
1290- if (request->impl->shortcuts_pane_filter_model)
1291- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (request->impl->shortcuts_pane_filter_model));
1292-
1293- if (request->impl->shortcuts_combo_filter_model)
1294- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (request->impl->shortcuts_combo_filter_model));
1295-
1296- if (request->type == SHORTCUTS_CURRENT_FOLDER &&
1297- request->impl->save_folder_combo != NULL)
1298- {
1299- /* The current folder is updated via _activate_iter(), don't
1300- * have save_folder_combo_changed_cb() call _activate_iter()
1301- * again.
1302- */
1303- g_signal_handlers_block_by_func (request->impl->save_folder_combo,
1304- G_CALLBACK (save_folder_combo_changed_cb),
1305- request->impl);
1306-
1307- if (request->impl->has_search)
1308- pos -= 1;
1309-
1310- if (request->impl->has_recent)
1311- pos -= 2;
1312-
1313- gtk_combo_box_set_active (GTK_COMBO_BOX (request->impl->save_folder_combo), pos);
1314- g_signal_handlers_unblock_by_func (request->impl->save_folder_combo,
1315- G_CALLBACK (save_folder_combo_changed_cb),
1316- request->impl);
1317- }
1318-
1319- if (pixbuf)
1320- g_object_unref (pixbuf);
1321-
1322-out:
1323- g_object_unref (request->impl);
1324- gtk_file_path_free (request->parent_path);
1325- gtk_file_path_free (request->path);
1326- gtk_tree_row_reference_free (request->row_ref);
1327- g_free (request->label_copy);
1328- g_free (request);
1329-
1330- g_object_unref (handle);
1331-}
1332-
1333 /* FIXME: GtkFileSystem needs a function to split a remote path
1334- * into hostname and path components, or maybe just have a
1335+ * into hostname and path components, or maybe just have a
1336 * gtk_file_system_path_get_display_name().
1337 *
1338 * This function is also used in gtkfilechooserbutton.c
1339@@ -1692,11 +887,11 @@
1340 {
1341 const gchar *path, *start, *end, *p;
1342 gchar *host, *label;
1343-
1344+
1345 start = strstr (uri, "://");
1346 start += 3;
1347 path = strchr (start, '/');
1348-
1349+
1350 if (path)
1351 end = path;
1352 else
1353@@ -1711,719 +906,25 @@
1354 {
1355 start = p + 1;
1356 }
1357-
1358+
1359 p = strchr (start, ':');
1360 if (p && p < end)
1361 end = p;
1362-
1363+
1364 host = g_strndup (start, end - start);
1365
1366- /* Translators: the first string is a path and the second string
1367- * is a hostname. Nautilus and the panel contain the same string
1368- * to translate.
1369+ /* Translators: the first string is a path and the second string
1370+ * is a hostname. Nautilus and the panel contain the same string
1371+ * to translate.
1372 */
1373 label = g_strdup_printf (_("%1$s on %2$s"), path, host);
1374-
1375+
1376 g_free (host);
1377
1378 return label;
1379 }
1380
1381-/* Inserts a path in the shortcuts tree, making a copy of it; alternatively,
1382- * inserts a volume. A position of -1 indicates the end of the tree.
1383- */
1384-static void
1385-shortcuts_insert_path (GtkFileChooserDefault *impl,
1386- int pos,
1387- ShortcutType shortcut_type,
1388- GtkFileSystemVolume *volume,
1389- const GtkFilePath *path,
1390- const char *label,
1391- gboolean removable,
1392- ShortcutsIndex type)
1393-{
1394- char *label_copy;
1395- GdkPixbuf *pixbuf = NULL;
1396- gpointer data = NULL;
1397- GtkTreeIter iter;
1398- GtkIconTheme *icon_theme;
1399
1400- profile_start ("start", (shortcut_type == SHORTCUT_TYPE_VOLUME) ? "volume"
1401- : ((shortcut_type == SHORTCUT_TYPE_PATH) ? (char *) path : NULL));
1402-
1403- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
1404- {
1405- data = volume;
1406- label_copy = gtk_file_system_volume_get_display_name (impl->file_system, volume);
1407- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl),
1408- impl->icon_size, NULL);
1409- }
1410- else if (shortcut_type == SHORTCUT_TYPE_PATH)
1411- {
1412- if (gtk_file_system_path_is_local (impl->file_system, path))
1413- {
1414- struct ShortcutsInsertRequest *request;
1415- GtkFileSystemHandle *handle;
1416- GtkTreePath *p;
1417-
1418- request = g_new0 (struct ShortcutsInsertRequest, 1);
1419- request->impl = g_object_ref (impl);
1420- request->path = gtk_file_path_copy (path);
1421- request->name_only = TRUE;
1422- request->removable = removable;
1423- request->pos = pos;
1424- request->type = type;
1425- if (label)
1426- request->label_copy = g_strdup (label);
1427-
1428- if (pos == -1)
1429- gtk_list_store_append (impl->shortcuts_model, &iter);
1430- else
1431- gtk_list_store_insert (impl->shortcuts_model, &iter, pos);
1432-
1433- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
1434- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), p);
1435- gtk_tree_path_free (p);
1436-
1437- handle = gtk_file_system_get_info (request->impl->file_system, request->path,
1438- GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_HIDDEN | GTK_FILE_INFO_ICON,
1439- get_file_info_finished, request);
1440-
1441- gtk_list_store_set (impl->shortcuts_model, &iter,
1442- SHORTCUTS_COL_DATA, gtk_file_path_copy (path),
1443- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH,
1444- SHORTCUTS_COL_HANDLE, handle,
1445- -1);
1446-
1447- shortcuts_update_count (impl, type, 1);
1448-
1449- return;
1450- }
1451- else
1452- {
1453- /* Don't call get_info for remote paths to avoid latency and
1454- * auth dialogs.
1455- */
1456- data = gtk_file_path_copy (path);
1457- if (label)
1458- label_copy = g_strdup (label);
1459- else
1460- {
1461- gchar *uri;
1462-
1463- uri = gtk_file_system_path_to_uri (impl->file_system, path);
1464-
1465- label_copy = _gtk_file_chooser_label_for_uri (uri);
1466-
1467- g_free (uri);
1468- }
1469-
1470- /* If we switch to a better bookmarks file format (XBEL), we
1471- * should use mime info to get a better icon.
1472- */
1473- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
1474- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-share",
1475- impl->icon_size, 0, NULL);
1476- }
1477- }
1478- else
1479- {
1480- g_assert_not_reached ();
1481-
1482- return;
1483- }
1484-
1485- if (pos == -1)
1486- gtk_list_store_append (impl->shortcuts_model, &iter);
1487- else
1488- gtk_list_store_insert (impl->shortcuts_model, &iter, pos);
1489-
1490- shortcuts_update_count (impl, type, 1);
1491-
1492- gtk_list_store_set (impl->shortcuts_model, &iter,
1493- SHORTCUTS_COL_PIXBUF, pixbuf,
1494- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1495- SHORTCUTS_COL_NAME, label_copy,
1496- SHORTCUTS_COL_DATA, data,
1497- SHORTCUTS_COL_TYPE, shortcut_type,
1498- SHORTCUTS_COL_REMOVABLE, removable,
1499- SHORTCUTS_COL_HANDLE, NULL,
1500- -1);
1501-
1502- if (impl->shortcuts_pane_filter_model)
1503- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
1504-
1505- if (impl->shortcuts_combo_filter_model)
1506- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
1507-
1508- if (type == SHORTCUTS_CURRENT_FOLDER && impl->save_folder_combo != NULL)
1509- {
1510- /* The current folder is updated via _activate_iter(), don't
1511- * have save_folder_combo_changed_cb() call _activate_iter()
1512- * again.
1513- */
1514- gint combo_pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER);
1515-
1516- if (impl->has_search)
1517- combo_pos -= 1;
1518-
1519- if (impl->has_recent)
1520- combo_pos -= 2;
1521-
1522- g_signal_handlers_block_by_func (impl->save_folder_combo,
1523- G_CALLBACK (save_folder_combo_changed_cb),
1524- impl);
1525-
1526- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), combo_pos);
1527- g_signal_handlers_unblock_by_func (impl->save_folder_combo,
1528- G_CALLBACK (save_folder_combo_changed_cb),
1529- impl);
1530- }
1531-
1532- g_free (label_copy);
1533-
1534- if (pixbuf)
1535- g_object_unref (pixbuf);
1536-
1537- profile_end ("end", NULL);
1538-}
1539-
1540-static void
1541-shortcuts_append_search (GtkFileChooserDefault *impl)
1542-{
1543- GdkPixbuf *pixbuf;
1544- GtkTreeIter iter;
1545-
1546- pixbuf = render_search_icon (impl);
1547-
1548- gtk_list_store_append (impl->shortcuts_model, &iter);
1549- gtk_list_store_set (impl->shortcuts_model, &iter,
1550- SHORTCUTS_COL_PIXBUF, pixbuf,
1551- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1552- SHORTCUTS_COL_NAME, _("Search"),
1553- SHORTCUTS_COL_DATA, NULL,
1554- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEARCH,
1555- SHORTCUTS_COL_REMOVABLE, FALSE,
1556- -1);
1557-
1558- if (pixbuf)
1559- g_object_unref (pixbuf);
1560-
1561- impl->has_search = TRUE;
1562-}
1563-
1564-static void
1565-shortcuts_append_recent (GtkFileChooserDefault *impl)
1566-{
1567- GdkPixbuf *pixbuf;
1568- GtkTreeIter iter;
1569-
1570- pixbuf = render_recent_icon (impl);
1571-
1572- gtk_list_store_append (impl->shortcuts_model, &iter);
1573- gtk_list_store_set (impl->shortcuts_model, &iter,
1574- SHORTCUTS_COL_PIXBUF, pixbuf,
1575- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1576- SHORTCUTS_COL_NAME, _("Recently Used"),
1577- SHORTCUTS_COL_DATA, NULL,
1578- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_RECENT,
1579- SHORTCUTS_COL_REMOVABLE, FALSE,
1580- -1);
1581-
1582- if (pixbuf)
1583- g_object_unref (pixbuf);
1584-
1585- impl->has_recent = TRUE;
1586-}
1587-
1588-/* Appends an item for the user's home directory to the shortcuts model */
1589-static void
1590-shortcuts_append_home (GtkFileChooserDefault *impl)
1591-{
1592- const char *home;
1593- GtkFilePath *home_path;
1594-
1595- profile_start ("start", NULL);
1596-
1597- home = g_get_home_dir ();
1598- if (home == NULL)
1599- {
1600- profile_end ("end - no home directory!?", NULL);
1601- return;
1602- }
1603-
1604- home_path = gtk_file_system_filename_to_path (impl->file_system, home);
1605-
1606- shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, home_path, NULL, FALSE, SHORTCUTS_HOME);
1607- impl->has_home = TRUE;
1608-
1609- gtk_file_path_free (home_path);
1610-
1611- profile_end ("end", NULL);
1612-}
1613-
1614-/* Appends the ~/Desktop directory to the shortcuts model */
1615-static void
1616-shortcuts_append_desktop (GtkFileChooserDefault *impl)
1617-{
1618- const char *name;
1619- GtkFilePath *path;
1620-
1621- profile_start ("start", NULL);
1622-
1623- name = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
1624- path = gtk_file_system_filename_to_path (impl->file_system, name);
1625- shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, path, _("Desktop"), FALSE, SHORTCUTS_DESKTOP);
1626- impl->has_desktop = TRUE;
1627-
1628- /* We do not actually pop up an error dialog if there is no desktop directory
1629- * because some people may really not want to have one.
1630- */
1631-
1632- gtk_file_path_free (path);
1633-
1634- profile_end ("end", NULL);
1635-}
1636-
1637-/* Appends a list of GtkFilePath to the shortcuts model; returns how many were inserted */
1638-static int
1639-shortcuts_append_paths (GtkFileChooserDefault *impl,
1640- GSList *paths)
1641-{
1642- int start_row;
1643- int num_inserted;
1644- gchar *label;
1645-
1646- profile_start ("start", NULL);
1647-
1648- /* As there is no separator now, we want to start there.
1649- */
1650- start_row = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR);
1651- num_inserted = 0;
1652-
1653- for (; paths; paths = paths->next)
1654- {
1655- GtkFilePath *path;
1656-
1657- path = paths->data;
1658-
1659- if (impl->local_only &&
1660- !gtk_file_system_path_is_local (impl->file_system, path))
1661- continue;
1662-
1663- label = gtk_file_system_get_bookmark_label (impl->file_system, path);
1664-
1665- /* NULL GError, but we don't really want to show error boxes here */
1666- shortcuts_insert_path (impl, start_row + num_inserted, SHORTCUT_TYPE_PATH, NULL, path, label, TRUE, SHORTCUTS_BOOKMARKS);
1667- num_inserted++;
1668-
1669- g_free (label);
1670- }
1671-
1672- profile_end ("end", NULL);
1673-
1674- return num_inserted;
1675-}
1676-
1677-/* Returns the index for the corresponding item in the shortcuts bar */
1678-static int
1679-shortcuts_get_index (GtkFileChooserDefault *impl,
1680- ShortcutsIndex where)
1681-{
1682- int n;
1683-
1684- n = 0;
1685-
1686- if (where == SHORTCUTS_SEARCH)
1687- goto out;
1688-
1689- n += impl->has_search ? 1 : 0;
1690-
1691- if (where == SHORTCUTS_RECENT)
1692- goto out;
1693-
1694- n += impl->has_recent ? 1 : 0;
1695-
1696- if (where == SHORTCUTS_RECENT_SEPARATOR)
1697- goto out;
1698-
1699- n += impl->has_recent ? 1 : 0;
1700-
1701- if (where == SHORTCUTS_HOME)
1702- goto out;
1703-
1704- n += impl->has_home ? 1 : 0;
1705-
1706- if (where == SHORTCUTS_DESKTOP)
1707- goto out;
1708-
1709- n += impl->has_desktop ? 1 : 0;
1710-
1711- if (where == SHORTCUTS_VOLUMES)
1712- goto out;
1713-
1714- n += impl->num_volumes;
1715-
1716- if (where == SHORTCUTS_SHORTCUTS)
1717- goto out;
1718-
1719- n += impl->num_shortcuts;
1720-
1721- if (where == SHORTCUTS_BOOKMARKS_SEPARATOR)
1722- goto out;
1723-
1724- /* If there are no bookmarks there won't be a separator */
1725- n += (impl->num_bookmarks > 0) ? 1 : 0;
1726-
1727- if (where == SHORTCUTS_BOOKMARKS)
1728- goto out;
1729-
1730- n += impl->num_bookmarks;
1731-
1732- if (where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR)
1733- goto out;
1734-
1735- n += 1;
1736-
1737- if (where == SHORTCUTS_CURRENT_FOLDER)
1738- goto out;
1739-
1740- g_assert_not_reached ();
1741-
1742- out:
1743-
1744- return n;
1745-}
1746-
1747-/* Adds all the file system volumes to the shortcuts model */
1748-static void
1749-shortcuts_add_volumes (GtkFileChooserDefault *impl)
1750-{
1751- int start_row;
1752- GSList *list, *l;
1753- int n;
1754- gboolean old_changing_folders;
1755-
1756- profile_start ("start", NULL);
1757-
1758-
1759- old_changing_folders = impl->changing_folder;
1760- impl->changing_folder = TRUE;
1761-
1762- start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
1763- shortcuts_remove_rows (impl, start_row, impl->num_volumes);
1764- impl->num_volumes = 0;
1765-
1766- list = gtk_file_system_list_volumes (impl->file_system);
1767-
1768- n = 0;
1769-
1770- for (l = list; l; l = l->next)
1771- {
1772- GtkFileSystemVolume *volume;
1773-
1774- volume = l->data;
1775-
1776- if (impl->local_only)
1777- {
1778- if (gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
1779- {
1780- GtkFilePath *base_path;
1781-
1782- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
1783- if (base_path != NULL)
1784- {
1785- gboolean is_local = gtk_file_system_path_is_local (impl->file_system, base_path);
1786- gtk_file_path_free (base_path);
1787-
1788- if (!is_local)
1789- {
1790- gtk_file_system_volume_free (impl->file_system, volume);
1791- continue;
1792- }
1793- }
1794- }
1795- }
1796-
1797- shortcuts_insert_path (impl, start_row + n, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES);
1798- n++;
1799- }
1800-
1801- impl->num_volumes = n;
1802- g_slist_free (list);
1803-
1804- if (impl->shortcuts_pane_filter_model)
1805- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
1806-
1807- if (impl->shortcuts_combo_filter_model)
1808- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
1809-
1810- impl->changing_folder = old_changing_folders;
1811-
1812- profile_end ("end", NULL);
1813-}
1814-
1815-/* Inserts a separator node in the shortcuts list */
1816-static void
1817-shortcuts_insert_separator (GtkFileChooserDefault *impl,
1818- ShortcutsIndex where)
1819-{
1820- GtkTreeIter iter;
1821-
1822- g_assert (where == SHORTCUTS_RECENT_SEPARATOR ||
1823- where == SHORTCUTS_BOOKMARKS_SEPARATOR ||
1824- where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
1825-
1826- gtk_list_store_insert (impl->shortcuts_model, &iter,
1827- shortcuts_get_index (impl, where));
1828- gtk_list_store_set (impl->shortcuts_model, &iter,
1829- SHORTCUTS_COL_PIXBUF, NULL,
1830- SHORTCUTS_COL_PIXBUF_VISIBLE, FALSE,
1831- SHORTCUTS_COL_NAME, NULL,
1832- SHORTCUTS_COL_DATA, NULL,
1833- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEPARATOR,
1834- -1);
1835-}
1836-
1837-/* Updates the list of bookmarks */
1838-static void
1839-shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
1840-{
1841- GSList *bookmarks;
1842- gboolean old_changing_folders;
1843- GtkTreeIter iter;
1844- GtkFilePath *list_selected = NULL;
1845- GtkFilePath *combo_selected = NULL;
1846- ShortcutType shortcut_type;
1847- gpointer col_data;
1848-
1849- profile_start ("start", NULL);
1850-
1851- old_changing_folders = impl->changing_folder;
1852- impl->changing_folder = TRUE;
1853-
1854- if (shortcuts_get_selected (impl, &iter))
1855- {
1856- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
1857- &iter,
1858- SHORTCUTS_COL_DATA, &col_data,
1859- SHORTCUTS_COL_TYPE, &shortcut_type,
1860- -1);
1861-
1862- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
1863- list_selected = gtk_file_path_copy (col_data);
1864- }
1865-
1866- if (impl->save_folder_combo &&
1867- gtk_combo_box_get_active_iter (GTK_COMBO_BOX (impl->save_folder_combo),
1868- &iter))
1869- {
1870- GtkTreeIter child_iter;
1871-
1872- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
1873- &child_iter,
1874- &iter);
1875- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
1876- &child_iter,
1877- SHORTCUTS_COL_DATA, &col_data,
1878- SHORTCUTS_COL_TYPE, &shortcut_type,
1879- -1);
1880-
1881- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
1882- combo_selected = gtk_file_path_copy (col_data);
1883- }
1884-
1885- if (impl->num_bookmarks > 0)
1886- shortcuts_remove_rows (impl,
1887- shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR),
1888- impl->num_bookmarks + 1);
1889-
1890- impl->num_bookmarks = 0;
1891-
1892- bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
1893- shortcuts_append_paths (impl, bookmarks);
1894- gtk_file_paths_free (bookmarks);
1895-
1896- if (impl->num_bookmarks > 0)
1897- shortcuts_insert_separator (impl, SHORTCUTS_BOOKMARKS_SEPARATOR);
1898-
1899- if (impl->shortcuts_pane_filter_model)
1900- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
1901-
1902- if (impl->shortcuts_combo_filter_model)
1903- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
1904-
1905- if (list_selected)
1906- {
1907- shortcuts_find_folder (impl, list_selected);
1908- gtk_file_path_free (list_selected);
1909- }
1910-
1911- if (combo_selected)
1912- {
1913- gint pos;
1914-
1915- pos = shortcut_find_position (impl, combo_selected);
1916- if (pos != -1)
1917- {
1918- if (impl->has_search)
1919- pos -= 1;
1920-
1921- if (impl->has_recent)
1922- pos -= 2;
1923-
1924- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos);
1925- }
1926-
1927- gtk_file_path_free (combo_selected);
1928- }
1929-
1930- impl->changing_folder = old_changing_folders;
1931-
1932- profile_end ("end", NULL);
1933-}
1934-
1935-/* Appends a separator and a row to the shortcuts list for the current folder */
1936-static void
1937-shortcuts_add_current_folder (GtkFileChooserDefault *impl)
1938-{
1939- int pos;
1940- gboolean success;
1941-
1942- g_assert (!impl->shortcuts_current_folder_active);
1943-
1944- success = TRUE;
1945-
1946- g_assert (impl->current_folder != NULL);
1947-
1948- pos = shortcut_find_position (impl, impl->current_folder);
1949- if (pos == -1)
1950- {
1951- GtkFileSystemVolume *volume;
1952- GtkFilePath *base_path;
1953-
1954- /* Separator */
1955-
1956- shortcuts_insert_separator (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
1957-
1958- /* Item */
1959-
1960- pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER);
1961-
1962- volume = gtk_file_system_get_volume_for_path (impl->file_system, impl->current_folder);
1963- if (volume)
1964- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
1965- else
1966- base_path = NULL;
1967-
1968- if (base_path &&
1969- strcmp (gtk_file_path_get_string (base_path), gtk_file_path_get_string (impl->current_folder)) == 0)
1970- {
1971- shortcuts_insert_path (impl, pos, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
1972- }
1973- else
1974- {
1975- shortcuts_insert_path (impl, pos, SHORTCUT_TYPE_PATH, NULL, impl->current_folder, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
1976- if (volume)
1977- gtk_file_system_volume_free (impl->file_system, volume);
1978- }
1979-
1980- if (base_path)
1981- gtk_file_path_free (base_path);
1982- }
1983- else if (impl->save_folder_combo != NULL)
1984- {
1985- if (impl->has_search)
1986- pos -= 1;
1987-
1988- if (impl->has_recent)
1989- pos -= 2; /* + separator */
1990-
1991- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos);
1992- }
1993-}
1994-
1995-/* Updates the current folder row in the shortcuts model */
1996-static void
1997-shortcuts_update_current_folder (GtkFileChooserDefault *impl)
1998-{
1999- int pos;
2000-
2001- pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
2002-
2003- if (impl->shortcuts_current_folder_active)
2004- {
2005- shortcuts_remove_rows (impl, pos, 2);
2006- impl->shortcuts_current_folder_active = FALSE;
2007- }
2008-
2009- shortcuts_add_current_folder (impl);
2010-}
2011-
2012-/* Filter function used for the shortcuts filter model */
2013-static gboolean
2014-shortcuts_pane_filter_cb (GtkTreeModel *model,
2015- GtkTreeIter *iter,
2016- gpointer data)
2017-{
2018- GtkFileChooserDefault *impl;
2019- GtkTreePath *path;
2020- int pos;
2021-
2022- impl = GTK_FILE_CHOOSER_DEFAULT (data);
2023-
2024- path = gtk_tree_model_get_path (model, iter);
2025- if (!path)
2026- return FALSE;
2027-
2028- pos = *gtk_tree_path_get_indices (path);
2029- gtk_tree_path_free (path);
2030-
2031- return (pos < shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR));
2032-}
2033-
2034-/* Creates the list model for shortcuts */
2035-static void
2036-shortcuts_model_create (GtkFileChooserDefault *impl)
2037-{
2038- /* Keep this order in sync with the SHORCUTS_COL_* enum values */
2039- impl->shortcuts_model = gtk_list_store_new (SHORTCUTS_COL_NUM_COLUMNS,
2040- GDK_TYPE_PIXBUF, /* pixbuf */
2041- G_TYPE_STRING, /* name */
2042- G_TYPE_POINTER, /* path or volume */
2043- G_TYPE_INT, /* ShortcutType */
2044- G_TYPE_BOOLEAN, /* removable */
2045- G_TYPE_BOOLEAN, /* pixbuf cell visibility */
2046- G_TYPE_POINTER); /* GtkFileSystemHandle */
2047-
2048- if (search_is_possible (impl))
2049- {
2050- shortcuts_append_search (impl);
2051- }
2052-
2053- if (impl->recent_manager)
2054- {
2055- shortcuts_append_recent (impl);
2056- shortcuts_insert_separator (impl, SHORTCUTS_RECENT_SEPARATOR);
2057- }
2058-
2059- if (impl->file_system)
2060- {
2061- shortcuts_append_home (impl);
2062- shortcuts_append_desktop (impl);
2063- shortcuts_add_volumes (impl);
2064- }
2065-
2066- impl->shortcuts_pane_filter_model = shortcuts_pane_model_filter_new (impl,
2067- GTK_TREE_MODEL (impl->shortcuts_model),
2068- NULL);
2069-
2070- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
2071- shortcuts_pane_filter_cb,
2072- impl,
2073- NULL);
2074-}
2075-
2076 /* Callback used when the "New Folder" button is clicked */
2077 static void
2078 new_folder_button_clicked (GtkButton *button,
2079@@ -2472,7 +973,7 @@
2080 goto out;
2081
2082 if (!error)
2083- change_folder_and_display_error (impl, path, FALSE);
2084+ change_folder_and_display_error (impl, path);
2085 else
2086 error_creating_folder_dialog (impl, path, g_error_copy (error));
2087
2088@@ -2488,7 +989,7 @@
2089 edited_idle_cb (GtkFileChooserDefault *impl)
2090 {
2091 GDK_THREADS_ENTER ();
2092-
2093+
2094 g_source_destroy (impl->edited_idle);
2095 impl->edited_idle = NULL;
2096
2097@@ -2558,10 +1059,10 @@
2098 const gchar *new_text,
2099 GtkFileChooserDefault *impl)
2100 {
2101- /* work around bug #154921 */
2102- g_object_set (cell_renderer_text,
2103+ /* work around bug #154921 */
2104+ g_object_set (cell_renderer_text,
2105 "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
2106- queue_edited_idle (impl, new_text);
2107+ queue_edited_idle (impl, new_text);
2108 }
2109
2110 /* Callback used from the text cell renderer when the new folder edition gets
2111@@ -2571,10 +1072,10 @@
2112 renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text,
2113 GtkFileChooserDefault *impl)
2114 {
2115- /* work around bug #154921 */
2116- g_object_set (cell_renderer_text,
2117+ /* work around bug #154921 */
2118+ g_object_set (cell_renderer_text,
2119 "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
2120- queue_edited_idle (impl, NULL);
2121+ queue_edited_idle (impl, NULL);
2122 }
2123
2124 /* Creates the widgets for the filter combo box */
2125@@ -2587,253 +1088,9 @@
2126 g_signal_connect (impl->filter_combo, "changed",
2127 G_CALLBACK (filter_combo_changed), impl);
2128
2129- gtk_widget_set_tooltip_text (impl->filter_combo,
2130- _("Select which types of files are shown"));
2131-
2132 return impl->filter_combo;
2133 }
2134
2135-static GtkWidget *
2136-button_new (GtkFileChooserDefault *impl,
2137- const char *text,
2138- const char *stock_id,
2139- gboolean sensitive,
2140- gboolean show,
2141- GCallback callback)
2142-{
2143- GtkWidget *button;
2144- GtkWidget *image;
2145-
2146- button = gtk_button_new_with_mnemonic (text);
2147- image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
2148- gtk_button_set_image (GTK_BUTTON (button), image);
2149-
2150- gtk_widget_set_sensitive (button, sensitive);
2151- g_signal_connect (button, "clicked", callback, impl);
2152-
2153- if (show)
2154- gtk_widget_show (button);
2155-
2156- return button;
2157-}
2158-
2159-/* Looks for a path among the shortcuts; returns its index or -1 if it doesn't exist */
2160-static int
2161-shortcut_find_position (GtkFileChooserDefault *impl,
2162- const GtkFilePath *path)
2163-{
2164- GtkTreeIter iter;
2165- int i;
2166- int current_folder_separator_idx;
2167-
2168- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
2169- return -1;
2170-
2171- current_folder_separator_idx = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
2172-
2173-#if 0
2174- /* FIXME: is this still needed? */
2175- if (current_folder_separator_idx >= impl->shortcuts_model->length)
2176- return -1;
2177-#endif
2178-
2179- for (i = 0; i < current_folder_separator_idx; i++)
2180- {
2181- gpointer col_data;
2182- ShortcutType shortcut_type;
2183-
2184- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2185- SHORTCUTS_COL_DATA, &col_data,
2186- SHORTCUTS_COL_TYPE, &shortcut_type,
2187- -1);
2188-
2189- if (col_data)
2190- {
2191- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
2192- {
2193- GtkFileSystemVolume *volume;
2194- GtkFilePath *base_path;
2195- gboolean exists;
2196-
2197- volume = col_data;
2198- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
2199-
2200- exists = base_path && strcmp (gtk_file_path_get_string (path),
2201- gtk_file_path_get_string (base_path)) == 0;
2202- g_free (base_path);
2203-
2204- if (exists)
2205- return i;
2206- }
2207- else if (shortcut_type == SHORTCUT_TYPE_PATH)
2208- {
2209- GtkFilePath *model_path;
2210-
2211- model_path = col_data;
2212-
2213- if (model_path && gtk_file_path_compare (model_path, path) == 0)
2214- return i;
2215- }
2216- }
2217-
2218- if (i < current_folder_separator_idx - 1)
2219- {
2220- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
2221- g_assert_not_reached ();
2222- }
2223- }
2224-
2225- return -1;
2226-}
2227-
2228-/* Tries to add a bookmark from a path name */
2229-static gboolean
2230-shortcuts_add_bookmark_from_path (GtkFileChooserDefault *impl,
2231- const GtkFilePath *path,
2232- int pos)
2233-{
2234- GError *error;
2235-
2236- g_return_val_if_fail (path != NULL, FALSE);
2237-
2238- if (shortcut_find_position (impl, path) != -1)
2239- return FALSE;
2240-
2241- error = NULL;
2242- if (!gtk_file_system_insert_bookmark (impl->file_system, path, pos, &error))
2243- {
2244- error_adding_bookmark_dialog (impl, path, error);
2245- return FALSE;
2246- }
2247-
2248- return TRUE;
2249-}
2250-
2251-static void
2252-add_bookmark_foreach_cb (GtkTreeModel *model,
2253- GtkTreePath *path,
2254- GtkTreeIter *iter,
2255- gpointer data)
2256-{
2257- GtkFileChooserDefault *impl;
2258- GtkFileSystemModel *fs_model;
2259- GtkTreeIter child_iter;
2260- const GtkFilePath *file_path;
2261-
2262- impl = (GtkFileChooserDefault *) data;
2263-
2264- switch (impl->operation_mode)
2265- {
2266- case OPERATION_MODE_BROWSE:
2267- fs_model = impl->browse_files_model;
2268- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, iter);
2269- file_path = _gtk_file_system_model_get_path (fs_model, &child_iter);
2270- break;
2271-
2272- case OPERATION_MODE_SEARCH:
2273- search_get_valid_child_iter (impl, &child_iter, iter);
2274- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
2275- SEARCH_MODEL_COL_PATH, &file_path,
2276- -1);
2277- break;
2278-
2279- case OPERATION_MODE_RECENT:
2280- recent_get_valid_child_iter (impl, &child_iter, iter);
2281- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
2282- RECENT_MODEL_COL_PATH, &file_path,
2283- -1);
2284- break;
2285- }
2286-
2287- shortcuts_add_bookmark_from_path (impl, file_path, -1);
2288-}
2289-
2290-/* Adds a bookmark from the currently selected item in the file list */
2291-static void
2292-bookmarks_add_selected_folder (GtkFileChooserDefault *impl)
2293-{
2294- GtkTreeSelection *selection;
2295-
2296- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
2297-
2298- if (gtk_tree_selection_count_selected_rows (selection) == 0)
2299- shortcuts_add_bookmark_from_path (impl, impl->current_folder, -1);
2300- else
2301- gtk_tree_selection_selected_foreach (selection,
2302- add_bookmark_foreach_cb,
2303- impl);
2304-}
2305-
2306-/* Callback used when the "Add bookmark" button is clicked */
2307-static void
2308-add_bookmark_button_clicked_cb (GtkButton *button,
2309- GtkFileChooserDefault *impl)
2310-{
2311- bookmarks_add_selected_folder (impl);
2312-}
2313-
2314-/* Returns TRUE plus an iter in the shortcuts_model if a row is selected;
2315- * returns FALSE if no shortcut is selected.
2316- */
2317-static gboolean
2318-shortcuts_get_selected (GtkFileChooserDefault *impl,
2319- GtkTreeIter *iter)
2320-{
2321- GtkTreeSelection *selection;
2322- GtkTreeIter parent_iter;
2323-
2324- if (!impl->browse_shortcuts_tree_view)
2325- return FALSE;
2326-
2327- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
2328-
2329- if (!gtk_tree_selection_get_selected (selection, NULL, &parent_iter))
2330- return FALSE;
2331-
2332- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
2333- iter,
2334- &parent_iter);
2335- return TRUE;
2336-}
2337-
2338-/* Removes the selected bookmarks */
2339-static void
2340-remove_selected_bookmarks (GtkFileChooserDefault *impl)
2341-{
2342- GtkTreeIter iter;
2343- gpointer col_data;
2344- GtkFilePath *path;
2345- gboolean removable;
2346- GError *error;
2347-
2348- if (!shortcuts_get_selected (impl, &iter))
2349- return;
2350-
2351- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2352- SHORTCUTS_COL_DATA, &col_data,
2353- SHORTCUTS_COL_REMOVABLE, &removable,
2354- -1);
2355-
2356- if (!removable)
2357- return;
2358-
2359- g_assert (col_data != NULL);
2360-
2361- path = col_data;
2362-
2363- error = NULL;
2364- if (!gtk_file_system_remove_bookmark (impl->file_system, path, &error))
2365- error_removing_bookmark_dialog (impl, path, error);
2366-}
2367-
2368-/* Callback used when the "Remove bookmark" button is clicked */
2369-static void
2370-remove_bookmark_button_clicked_cb (GtkButton *button,
2371- GtkFileChooserDefault *impl)
2372-{
2373- remove_selected_bookmarks (impl);
2374-}
2375-
2376 struct selection_check_closure {
2377 GtkFileChooserDefault *impl;
2378 int num_selected;
2379@@ -2856,29 +1113,11 @@
2380 closure = data;
2381 closure->num_selected++;
2382
2383- switch (closure->impl->operation_mode)
2384- {
2385- case OPERATION_MODE_BROWSE:
2386- gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
2387- info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
2388- is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE;
2389- break;
2390+ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
2391
2392- case OPERATION_MODE_SEARCH:
2393- search_get_valid_child_iter (closure->impl, &child_iter, iter);
2394- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter,
2395- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
2396- -1);
2397- break;
2398+ info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
2399+ is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE;
2400
2401- case OPERATION_MODE_RECENT:
2402- recent_get_valid_child_iter (closure->impl, &child_iter, iter);
2403- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter,
2404- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
2405- -1);
2406- break;
2407- }
2408-
2409 closure->all_folders = closure->all_folders && is_folder;
2410 closure->all_files = closure->all_files && !is_folder;
2411 }
2412@@ -2920,1126 +1159,6 @@
2413 const GtkFilePath *path;
2414 };
2415
2416-static void
2417-get_selected_path_foreach_cb (GtkTreeModel *model,
2418- GtkTreePath *path,
2419- GtkTreeIter *iter,
2420- gpointer data)
2421-{
2422- struct get_selected_path_closure *closure;
2423- GtkTreeIter child_iter;
2424-
2425- closure = data;
2426-
2427- switch (closure->impl->operation_mode)
2428- {
2429- case OPERATION_MODE_BROWSE:
2430- gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
2431- closure->path = _gtk_file_system_model_get_path (closure->impl->browse_files_model, &child_iter);
2432- break;
2433-
2434- case OPERATION_MODE_SEARCH:
2435- search_get_valid_child_iter (closure->impl, &child_iter, iter);
2436- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter,
2437- SEARCH_MODEL_COL_PATH, &closure->path,
2438- -1);
2439- break;
2440-
2441- case OPERATION_MODE_RECENT:
2442- recent_get_valid_child_iter (closure->impl, &child_iter, iter);
2443- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter,
2444- RECENT_MODEL_COL_PATH, &closure->path,
2445- -1);
2446- break;
2447- }
2448-}
2449-
2450-/* Returns a selected path from the file list */
2451-static const GtkFilePath *
2452-get_selected_path (GtkFileChooserDefault *impl)
2453-{
2454- struct get_selected_path_closure closure;
2455- GtkTreeSelection *selection;
2456-
2457- closure.impl = impl;
2458- closure.path = NULL;
2459-
2460- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
2461- gtk_tree_selection_selected_foreach (selection,
2462- get_selected_path_foreach_cb,
2463- &closure);
2464-
2465- return closure.path;
2466-}
2467-
2468-typedef struct {
2469- GtkFileChooserDefault *impl;
2470- gchar *tip;
2471-} UpdateTooltipData;
2472-
2473-static void
2474-update_tooltip (GtkTreeModel *model,
2475- GtkTreePath *path,
2476- GtkTreeIter *iter,
2477- gpointer data)
2478-{
2479- UpdateTooltipData *udata = data;
2480- GtkTreeIter child_iter;
2481- const GtkFileInfo *info;
2482-
2483- if (udata->tip == NULL)
2484- {
2485- const gchar *display_name;
2486-
2487- switch (udata->impl->operation_mode)
2488- {
2489- case OPERATION_MODE_BROWSE:
2490- gtk_tree_model_sort_convert_iter_to_child_iter (udata->impl->sort_model,
2491- &child_iter,
2492- iter);
2493- info = _gtk_file_system_model_get_info (udata->impl->browse_files_model, &child_iter);
2494- display_name = gtk_file_info_get_display_name (info);
2495- break;
2496-
2497- case OPERATION_MODE_SEARCH:
2498- search_get_valid_child_iter (udata->impl, &child_iter, iter);
2499- gtk_tree_model_get (GTK_TREE_MODEL (udata->impl->search_model), &child_iter,
2500- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
2501- -1);
2502- break;
2503-
2504- case OPERATION_MODE_RECENT:
2505- recent_get_valid_child_iter (udata->impl, &child_iter, iter);
2506- gtk_tree_model_get (GTK_TREE_MODEL (udata->impl->recent_model), &child_iter,
2507- RECENT_MODEL_COL_DISPLAY_NAME, &display_name,
2508- -1);
2509- break;
2510- }
2511-
2512- udata->tip = g_strdup_printf (_("Add the folder '%s' to the bookmarks"),
2513- display_name);
2514- }
2515-}
2516-
2517-
2518-/* Sensitize the "add bookmark" button if all the selected items are folders, or
2519- * if there are no selected items *and* the current folder is not in the
2520- * bookmarks list. De-sensitize the button otherwise.
2521- */
2522-static void
2523-bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl)
2524-{
2525- gint num_selected;
2526- gboolean all_folders;
2527- gboolean active;
2528- gchar *tip;
2529-
2530- selection_check (impl, &num_selected, NULL, &all_folders);
2531-
2532- if (num_selected == 0)
2533- active = (impl->current_folder != NULL) && (shortcut_find_position (impl, impl->current_folder) == -1);
2534- else if (num_selected == 1)
2535- {
2536- const GtkFilePath *path;
2537-
2538- path = get_selected_path (impl);
2539- active = all_folders && (shortcut_find_position (impl, path) == -1);
2540- }
2541- else
2542- active = all_folders;
2543-
2544- gtk_widget_set_sensitive (impl->browse_shortcuts_add_button, active);
2545-
2546- if (impl->browse_files_popup_menu_add_shortcut_item)
2547- gtk_widget_set_sensitive (impl->browse_files_popup_menu_add_shortcut_item,
2548- (num_selected == 0) ? FALSE : active);
2549-
2550- if (active)
2551- {
2552- if (num_selected == 0)
2553- tip = g_strdup_printf (_("Add the current folder to the bookmarks"));
2554- else if (num_selected > 1)
2555- tip = g_strdup_printf (_("Add the selected folders to the bookmarks"));
2556- else
2557- {
2558- GtkTreeSelection *selection;
2559- UpdateTooltipData data;
2560-
2561- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
2562- data.impl = impl;
2563- data.tip = NULL;
2564- gtk_tree_selection_selected_foreach (selection, update_tooltip, &data);
2565- tip = data.tip;
2566- }
2567-
2568- gtk_widget_set_tooltip_text (impl->browse_shortcuts_add_button, tip);
2569- g_free (tip);
2570- }
2571-}
2572-
2573-/* Sets the sensitivity of the "remove bookmark" button depending on whether a
2574- * bookmark row is selected in the shortcuts tree.
2575- */
2576-static void
2577-bookmarks_check_remove_sensitivity (GtkFileChooserDefault *impl)
2578-{
2579- GtkTreeIter iter;
2580- gboolean removable = FALSE;
2581- gchar *name = NULL;
2582-
2583- if (shortcuts_get_selected (impl, &iter))
2584- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2585- SHORTCUTS_COL_REMOVABLE, &removable,
2586- SHORTCUTS_COL_NAME, &name,
2587- -1);
2588-
2589- gtk_widget_set_sensitive (impl->browse_shortcuts_remove_button, removable);
2590-
2591- if (removable)
2592- {
2593- gchar *tip;
2594-
2595- tip = g_strdup_printf (_("Remove the bookmark '%s'"), name);
2596- gtk_widget_set_tooltip_text (impl->browse_shortcuts_remove_button, tip);
2597- g_free (tip);
2598- }
2599-
2600- g_free (name);
2601-}
2602-
2603-static void
2604-shortcuts_check_popup_sensitivity (GtkFileChooserDefault *impl)
2605-{
2606- GtkTreeIter iter;
2607- gboolean removable = FALSE;
2608-
2609- if (impl->browse_shortcuts_popup_menu == NULL)
2610- return;
2611-
2612- if (shortcuts_get_selected (impl, &iter))
2613- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2614- SHORTCUTS_COL_REMOVABLE, &removable,
2615- -1);
2616-
2617- gtk_widget_set_sensitive (impl->browse_shortcuts_popup_menu_remove_item, removable);
2618- gtk_widget_set_sensitive (impl->browse_shortcuts_popup_menu_rename_item, removable);
2619-}
2620-
2621-/* GtkWidget::drag-begin handler for the shortcuts list. */
2622-static void
2623-shortcuts_drag_begin_cb (GtkWidget *widget,
2624- GdkDragContext *context,
2625- GtkFileChooserDefault *impl)
2626-{
2627-#if 0
2628- impl->shortcuts_drag_context = g_object_ref (context);
2629-#endif
2630-}
2631-
2632-#if 0
2633-/* Removes the idle handler for outside drags */
2634-static void
2635-shortcuts_cancel_drag_outside_idle (GtkFileChooserDefault *impl)
2636-{
2637- if (!impl->shortcuts_drag_outside_idle)
2638- return;
2639-
2640- g_source_destroy (impl->shortcuts_drag_outside_idle);
2641- impl->shortcuts_drag_outside_idle = NULL;
2642-}
2643-#endif
2644-
2645-/* GtkWidget::drag-end handler for the shortcuts list. */
2646-static void
2647-shortcuts_drag_end_cb (GtkWidget *widget,
2648- GdkDragContext *context,
2649- GtkFileChooserDefault *impl)
2650-{
2651-#if 0
2652- g_object_unref (impl->shortcuts_drag_context);
2653-
2654- shortcuts_cancel_drag_outside_idle (impl);
2655-
2656- if (!impl->shortcuts_drag_outside)
2657- return;
2658-
2659- gtk_button_clicked (GTK_BUTTON (impl->browse_shortcuts_remove_button));
2660-
2661- impl->shortcuts_drag_outside = FALSE;
2662-#endif
2663-}
2664-
2665-/* GtkWidget::drag-data-delete handler for the shortcuts list. */
2666-static void
2667-shortcuts_drag_data_delete_cb (GtkWidget *widget,
2668- GdkDragContext *context,
2669- GtkFileChooserDefault *impl)
2670-{
2671- g_signal_stop_emission_by_name (widget, "drag_data_delete");
2672-}
2673-
2674-#if 0
2675-/* Creates a suitable drag cursor to indicate that the selected bookmark will be
2676- * deleted or not.
2677- */
2678-static void
2679-shortcuts_drag_set_delete_cursor (GtkFileChooserDefault *impl,
2680- gboolean delete)
2681-{
2682- GtkTreeView *tree_view;
2683- GtkTreeIter iter;
2684- GtkTreePath *path;
2685- GdkPixmap *row_pixmap;
2686- GdkBitmap *mask;
2687- int row_pixmap_y;
2688- int cell_y;
2689-
2690- tree_view = GTK_TREE_VIEW (impl->browse_shortcuts_tree_view);
2691-
2692- /* Find the selected path and get its drag pixmap */
2693-
2694- if (!shortcuts_get_selected (impl, &iter))
2695- g_assert_not_reached ();
2696-
2697- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
2698-
2699- row_pixmap = gtk_tree_view_create_row_drag_icon (tree_view, path);
2700- gtk_tree_path_free (path);
2701-
2702- mask = NULL;
2703- row_pixmap_y = 0;
2704-
2705- if (delete)
2706- {
2707- GdkPixbuf *pixbuf;
2708-
2709- pixbuf = gtk_widget_render_icon (impl->browse_shortcuts_tree_view,
2710- GTK_STOCK_DELETE,
2711- GTK_ICON_SIZE_DND,
2712- NULL);
2713- if (pixbuf)
2714- {
2715- GdkPixmap *composite;
2716- int row_pixmap_width, row_pixmap_height;
2717- int pixbuf_width, pixbuf_height;
2718- int composite_width, composite_height;
2719- int pixbuf_x, pixbuf_y;
2720- GdkGC *gc, *mask_gc;
2721- GdkColor color;
2722- GdkBitmap *pixbuf_mask;
2723-
2724- /* Create pixmap and mask for composite image */
2725-
2726- gdk_drawable_get_size (row_pixmap, &row_pixmap_width, &row_pixmap_height);
2727- pixbuf_width = gdk_pixbuf_get_width (pixbuf);
2728- pixbuf_height = gdk_pixbuf_get_height (pixbuf);
2729-
2730- composite_width = MAX (row_pixmap_width, pixbuf_width);
2731- composite_height = MAX (row_pixmap_height, pixbuf_height);
2732-
2733- row_pixmap_y = (composite_height - row_pixmap_height) / 2;
2734-
2735- if (gtk_widget_get_direction (impl->browse_shortcuts_tree_view) == GTK_TEXT_DIR_RTL)
2736- pixbuf_x = 0;
2737- else
2738- pixbuf_x = composite_width - pixbuf_width;
2739-
2740- pixbuf_y = (composite_height - pixbuf_height) / 2;
2741-
2742- composite = gdk_pixmap_new (row_pixmap, composite_width, composite_height, -1);
2743- gc = gdk_gc_new (composite);
2744-
2745- mask = gdk_pixmap_new (row_pixmap, composite_width, composite_height, 1);
2746- mask_gc = gdk_gc_new (mask);
2747- color.pixel = 0;
2748- gdk_gc_set_foreground (mask_gc, &color);
2749- gdk_draw_rectangle (mask, mask_gc, TRUE, 0, 0, composite_width, composite_height);
2750-
2751- color.red = 0xffff;
2752- color.green = 0xffff;
2753- color.blue = 0xffff;
2754- gdk_gc_set_rgb_fg_color (gc, &color);
2755- gdk_draw_rectangle (composite, gc, TRUE, 0, 0, composite_width, composite_height);
2756-
2757- /* Composite the row pixmap and the pixbuf */
2758-
2759- gdk_pixbuf_render_pixmap_and_mask_for_colormap
2760- (pixbuf,
2761- gtk_widget_get_colormap (impl->browse_shortcuts_tree_view),
2762- NULL, &pixbuf_mask, 128);
2763- gdk_draw_drawable (mask, mask_gc, pixbuf_mask,
2764- 0, 0,
2765- pixbuf_x, pixbuf_y,
2766- pixbuf_width, pixbuf_height);
2767- g_object_unref (pixbuf_mask);
2768-
2769- gdk_draw_drawable (composite, gc, row_pixmap,
2770- 0, 0,
2771- 0, row_pixmap_y,
2772- row_pixmap_width, row_pixmap_height);
2773- color.pixel = 1;
2774- gdk_gc_set_foreground (mask_gc, &color);
2775- gdk_draw_rectangle (mask, mask_gc, TRUE, 0, row_pixmap_y, row_pixmap_width, row_pixmap_height);
2776-
2777- gdk_draw_pixbuf (composite, gc, pixbuf,
2778- 0, 0,
2779- pixbuf_x, pixbuf_y,
2780- pixbuf_width, pixbuf_height,
2781- GDK_RGB_DITHER_MAX,
2782- 0, 0);
2783-
2784- g_object_unref (pixbuf);
2785- g_object_unref (row_pixmap);
2786-
2787- row_pixmap = composite;
2788- }
2789- }
2790-
2791- /* The hotspot offsets here are copied from gtk_tree_view_drag_begin(), ugh */
2792-
2793- gtk_tree_view_get_path_at_pos (tree_view,
2794- tree_view->priv->press_start_x,
2795- tree_view->priv->press_start_y,
2796- NULL,
2797- NULL,
2798- NULL,
2799- &cell_y);
2800-
2801- gtk_drag_set_icon_pixmap (impl->shortcuts_drag_context,
2802- gdk_drawable_get_colormap (row_pixmap),
2803- row_pixmap,
2804- mask,
2805- tree_view->priv->press_start_x + 1,
2806- row_pixmap_y + cell_y + 1);
2807-
2808- g_object_unref (row_pixmap);
2809- if (mask)
2810- g_object_unref (mask);
2811-}
2812-
2813-/* We set the delete cursor and the shortcuts_drag_outside flag in an idle
2814- * handler so that we can tell apart the drag_leave event that comes right
2815- * before a drag_drop, from a normal drag_leave. We don't want to set the
2816- * cursor nor the flag in the latter case.
2817- */
2818-static gboolean
2819-shortcuts_drag_outside_idle_cb (GtkFileChooserDefault *impl)
2820-{
2821- GDK_THREADS_ENTER ();
2822-
2823- shortcuts_drag_set_delete_cursor (impl, TRUE);
2824- impl->shortcuts_drag_outside = TRUE;
2825-
2826- shortcuts_cancel_drag_outside_idle (impl);
2827-
2828- GDK_THREADS_LEAVE ();
2829-
2830- return FALSE;
2831-}
2832-#endif
2833-
2834-/* GtkWidget::drag-leave handler for the shortcuts list. We unhighlight the
2835- * drop position.
2836- */
2837-static void
2838-shortcuts_drag_leave_cb (GtkWidget *widget,
2839- GdkDragContext *context,
2840- guint time_,
2841- GtkFileChooserDefault *impl)
2842-{
2843-#if 0
2844- if (gtk_drag_get_source_widget (context) == widget && !impl->shortcuts_drag_outside_idle)
2845- {
2846- impl->shortcuts_drag_outside_idle = g_idle_source_new ();
2847- g_source_set_closure (impl->shortcuts_drag_outside_idle,
2848- g_cclosure_new_object (G_CALLBACK (shortcuts_drag_outside_idle_cb),
2849- G_OBJECT (impl)));
2850- g_source_attach (impl->shortcuts_drag_outside_idle, NULL);
2851- }
2852-#endif
2853-
2854- gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
2855- NULL,
2856- GTK_TREE_VIEW_DROP_BEFORE);
2857-
2858- g_signal_stop_emission_by_name (widget, "drag_leave");
2859-}
2860-
2861-/* Computes the appropriate row and position for dropping */
2862-static void
2863-shortcuts_compute_drop_position (GtkFileChooserDefault *impl,
2864- int x,
2865- int y,
2866- GtkTreePath **path,
2867- GtkTreeViewDropPosition *pos)
2868-{
2869- GtkTreeView *tree_view;
2870- GtkTreeViewColumn *column;
2871- int cell_y;
2872- GdkRectangle cell;
2873- int row;
2874- int bookmarks_index;
2875-
2876- tree_view = GTK_TREE_VIEW (impl->browse_shortcuts_tree_view);
2877-
2878- bookmarks_index = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
2879-
2880- if (!gtk_tree_view_get_path_at_pos (tree_view,
2881- x,
2882- y - TREE_VIEW_HEADER_HEIGHT (tree_view),
2883- path,
2884- &column,
2885- NULL,
2886- &cell_y))
2887- {
2888- row = bookmarks_index + impl->num_bookmarks - 1;
2889- *path = gtk_tree_path_new_from_indices (row, -1);
2890- *pos = GTK_TREE_VIEW_DROP_AFTER;
2891- return;
2892- }
2893-
2894- row = *gtk_tree_path_get_indices (*path);
2895- gtk_tree_view_get_background_area (tree_view, *path, column, &cell);
2896- gtk_tree_path_free (*path);
2897-
2898- if (row < bookmarks_index)
2899- {
2900- row = bookmarks_index;
2901- *pos = GTK_TREE_VIEW_DROP_BEFORE;
2902- }
2903- else if (row > bookmarks_index + impl->num_bookmarks - 1)
2904- {
2905- row = bookmarks_index + impl->num_bookmarks - 1;
2906- *pos = GTK_TREE_VIEW_DROP_AFTER;
2907- }
2908- else
2909- {
2910- if (cell_y < cell.height / 2)
2911- *pos = GTK_TREE_VIEW_DROP_BEFORE;
2912- else
2913- *pos = GTK_TREE_VIEW_DROP_AFTER;
2914- }
2915-
2916- *path = gtk_tree_path_new_from_indices (row, -1);
2917-}
2918-
2919-/* GtkWidget::drag-motion handler for the shortcuts list. We basically
2920- * implement the destination side of DnD by hand, due to limitations in
2921- * GtkTreeView's DnD API.
2922- */
2923-static gboolean
2924-shortcuts_drag_motion_cb (GtkWidget *widget,
2925- GdkDragContext *context,
2926- gint x,
2927- gint y,
2928- guint time_,
2929- GtkFileChooserDefault *impl)
2930-{
2931- GtkTreePath *path;
2932- GtkTreeViewDropPosition pos;
2933- GdkDragAction action;
2934-
2935-#if 0
2936- if (gtk_drag_get_source_widget (context) == widget)
2937- {
2938- shortcuts_cancel_drag_outside_idle (impl);
2939-
2940- if (impl->shortcuts_drag_outside)
2941- {
2942- shortcuts_drag_set_delete_cursor (impl, FALSE);
2943- impl->shortcuts_drag_outside = FALSE;
2944- }
2945- }
2946-#endif
2947-
2948- if (context->suggested_action == GDK_ACTION_COPY ||
2949- (context->actions & GDK_ACTION_COPY) != 0)
2950- action = GDK_ACTION_COPY;
2951- else if (context->suggested_action == GDK_ACTION_MOVE ||
2952- (context->actions & GDK_ACTION_MOVE) != 0)
2953- action = GDK_ACTION_MOVE;
2954- else
2955- {
2956- action = 0;
2957- goto out;
2958- }
2959-
2960- shortcuts_compute_drop_position (impl, x, y, &path, &pos);
2961- gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), path, pos);
2962- gtk_tree_path_free (path);
2963-
2964- out:
2965-
2966- g_signal_stop_emission_by_name (widget, "drag_motion");
2967-
2968- if (action != 0)
2969- {
2970- gdk_drag_status (context, action, time_);
2971- return TRUE;
2972- }
2973- else
2974- return FALSE;
2975-}
2976-
2977-/* GtkWidget::drag-drop handler for the shortcuts list. */
2978-static gboolean
2979-shortcuts_drag_drop_cb (GtkWidget *widget,
2980- GdkDragContext *context,
2981- gint x,
2982- gint y,
2983- guint time_,
2984- GtkFileChooserDefault *impl)
2985-{
2986-#if 0
2987- shortcuts_cancel_drag_outside_idle (impl);
2988-#endif
2989-
2990- g_signal_stop_emission_by_name (widget, "drag_drop");
2991- return TRUE;
2992-}
2993-
2994-/* Parses a "text/uri-list" string and inserts its URIs as bookmarks */
2995-static void
2996-shortcuts_drop_uris (GtkFileChooserDefault *impl,
2997- const char *data,
2998- int position)
2999-{
3000- gchar **uris;
3001- gint i;
3002-
3003- uris = g_uri_list_extract_uris (data);
3004-
3005- for (i = 0; uris[i]; i++)
3006- {
3007- char *uri;
3008- GtkFilePath *path;
3009-
3010- uri = uris[i];
3011- path = gtk_file_system_uri_to_path (impl->file_system, uri);
3012-
3013- if (path)
3014- {
3015- if (shortcuts_add_bookmark_from_path (impl, path, position))
3016- position++;
3017-
3018- gtk_file_path_free (path);
3019- }
3020- else
3021- {
3022- GError *error = NULL;
3023-
3024- g_set_error (&error,
3025- GTK_FILE_CHOOSER_ERROR,
3026- GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
3027- _("Could not add a bookmark for '%s' "
3028- "because it is an invalid path name."),
3029- uri);
3030- error_adding_bookmark_dialog (impl, path, error);
3031- }
3032- }
3033-
3034- g_strfreev (uris);
3035-}
3036-
3037-/* Reorders the selected bookmark to the specified position */
3038-static void
3039-shortcuts_reorder (GtkFileChooserDefault *impl,
3040- int new_position)
3041-{
3042- GtkTreeIter iter;
3043- gpointer col_data;
3044- ShortcutType shortcut_type;
3045- GtkTreePath *path;
3046- int old_position;
3047- int bookmarks_index;
3048- const GtkFilePath *file_path;
3049- GtkFilePath *file_path_copy;
3050- GError *error;
3051- gchar *name;
3052-
3053- /* Get the selected path */
3054-
3055- if (!shortcuts_get_selected (impl, &iter))
3056- g_assert_not_reached ();
3057-
3058- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
3059- old_position = *gtk_tree_path_get_indices (path);
3060- gtk_tree_path_free (path);
3061-
3062- bookmarks_index = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
3063- old_position -= bookmarks_index;
3064- g_assert (old_position >= 0 && old_position < impl->num_bookmarks);
3065-
3066- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
3067- SHORTCUTS_COL_NAME, &name,
3068- SHORTCUTS_COL_DATA, &col_data,
3069- SHORTCUTS_COL_TYPE, &shortcut_type,
3070- -1);
3071- g_assert (col_data != NULL);
3072- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
3073-
3074- file_path = col_data;
3075- file_path_copy = gtk_file_path_copy (file_path); /* removal below will free file_path, so we need a copy */
3076-
3077- /* Remove the path from the old position and insert it in the new one */
3078-
3079- if (new_position > old_position)
3080- new_position--;
3081-
3082- if (old_position == new_position)
3083- goto out;
3084-
3085- error = NULL;
3086- if (gtk_file_system_remove_bookmark (impl->file_system, file_path_copy, &error))
3087- {
3088- shortcuts_add_bookmark_from_path (impl, file_path_copy, new_position);
3089- gtk_file_system_set_bookmark_label (impl->file_system, file_path_copy, name);
3090- }
3091- else
3092- error_adding_bookmark_dialog (impl, file_path_copy, error);
3093-
3094- out:
3095-
3096- gtk_file_path_free (file_path_copy);
3097-}
3098-
3099-/* Callback used when we get the drag data for the bookmarks list. We add the
3100- * received URIs as bookmarks if they are folders.
3101- */
3102-static void
3103-shortcuts_drag_data_received_cb (GtkWidget *widget,
3104- GdkDragContext *context,
3105- gint x,
3106- gint y,
3107- GtkSelectionData *selection_data,
3108- guint info,
3109- guint time_,
3110- gpointer data)
3111-{
3112- GtkFileChooserDefault *impl;
3113- GtkTreePath *tree_path;
3114- GtkTreeViewDropPosition tree_pos;
3115- int position;
3116- int bookmarks_index;
3117-
3118- impl = GTK_FILE_CHOOSER_DEFAULT (data);
3119-
3120- /* Compute position */
3121-
3122- bookmarks_index = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
3123-
3124- shortcuts_compute_drop_position (impl, x, y, &tree_path, &tree_pos);
3125- position = *gtk_tree_path_get_indices (tree_path);
3126- gtk_tree_path_free (tree_path);
3127-
3128- if (tree_pos == GTK_TREE_VIEW_DROP_AFTER)
3129- position++;
3130-
3131- g_assert (position >= bookmarks_index);
3132- position -= bookmarks_index;
3133-
3134- if (selection_data->target == gdk_atom_intern_static_string ("text/uri-list"))
3135- shortcuts_drop_uris (impl, (const char *) selection_data->data, position);
3136- else if (selection_data->target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW"))
3137- shortcuts_reorder (impl, position);
3138-
3139- g_signal_stop_emission_by_name (widget, "drag_data_received");
3140-}
3141-
3142-/* Callback used when the selection in the shortcuts tree changes */
3143-static void
3144-shortcuts_selection_changed_cb (GtkTreeSelection *selection,
3145- GtkFileChooserDefault *impl)
3146-{
3147- bookmarks_check_remove_sensitivity (impl);
3148- shortcuts_check_popup_sensitivity (impl);
3149-}
3150-
3151-static gboolean
3152-shortcuts_row_separator_func (GtkTreeModel *model,
3153- GtkTreeIter *iter,
3154- gpointer data)
3155-{
3156- ShortcutType shortcut_type;
3157-
3158- gtk_tree_model_get (model, iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1);
3159-
3160- return shortcut_type == SHORTCUT_TYPE_SEPARATOR;
3161-}
3162-
3163-/* Since GtkTreeView has a keybinding attached to '/', we need to catch
3164- * keypresses before the TreeView gets them.
3165- */
3166-static gboolean
3167-tree_view_keybinding_cb (GtkWidget *tree_view,
3168- GdkEventKey *event,
3169- GtkFileChooserDefault *impl)
3170-{
3171- if ((event->keyval == GDK_slash
3172- || event->keyval == GDK_KP_Divide
3173-#ifdef G_OS_UNIX
3174- || event->keyval == GDK_asciitilde
3175-#endif
3176- ) && ! (event->state & (~GDK_SHIFT_MASK & gtk_accelerator_get_default_mod_mask ())))
3177- {
3178- location_popup_handler (impl, event->string);
3179- return TRUE;
3180- }
3181-
3182- return FALSE;
3183-}
3184-
3185-/* Callback used when the file list's popup menu is detached */
3186-static void
3187-shortcuts_popup_menu_detach_cb (GtkWidget *attach_widget,
3188- GtkMenu *menu)
3189-{
3190- GtkFileChooserDefault *impl;
3191-
3192- impl = g_object_get_data (G_OBJECT (attach_widget), "GtkFileChooserDefault");
3193- g_assert (GTK_IS_FILE_CHOOSER_DEFAULT (impl));
3194-
3195- impl->browse_shortcuts_popup_menu = NULL;
3196- impl->browse_shortcuts_popup_menu_remove_item = NULL;
3197- impl->browse_shortcuts_popup_menu_rename_item = NULL;
3198-}
3199-
3200-static void
3201-remove_shortcut_cb (GtkMenuItem *item,
3202- GtkFileChooserDefault *impl)
3203-{
3204- remove_selected_bookmarks (impl);
3205-}
3206-
3207-/* Rename the selected bookmark */
3208-static void
3209-rename_selected_bookmark (GtkFileChooserDefault *impl)
3210-{
3211- GtkTreeIter iter;
3212- GtkTreePath *path;
3213- GtkTreeViewColumn *column;
3214- GtkCellRenderer *cell;
3215- GList *renderers;
3216-
3217- if (shortcuts_get_selected (impl, &iter))
3218- {
3219- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
3220- column = gtk_tree_view_get_column (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), 0);
3221- renderers = gtk_tree_view_column_get_cell_renderers (column);
3222- cell = g_list_nth_data (renderers, 1);
3223- g_list_free (renderers);
3224- g_object_set (cell, "editable", TRUE, NULL);
3225- gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
3226- path, column, cell, TRUE);
3227- gtk_tree_path_free (path);
3228- }
3229-}
3230-
3231-static void
3232-rename_shortcut_cb (GtkMenuItem *item,
3233- GtkFileChooserDefault *impl)
3234-{
3235- rename_selected_bookmark (impl);
3236-}
3237-
3238-/* Constructs the popup menu for the file list if needed */
3239-static void
3240-shortcuts_build_popup_menu (GtkFileChooserDefault *impl)
3241-{
3242- GtkWidget *item;
3243-
3244- if (impl->browse_shortcuts_popup_menu)
3245- return;
3246-
3247- impl->browse_shortcuts_popup_menu = gtk_menu_new ();
3248- gtk_menu_attach_to_widget (GTK_MENU (impl->browse_shortcuts_popup_menu),
3249- impl->browse_shortcuts_tree_view,
3250- shortcuts_popup_menu_detach_cb);
3251-
3252- item = gtk_image_menu_item_new_with_label (_("Remove"));
3253- impl->browse_shortcuts_popup_menu_remove_item = item;
3254- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
3255- gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU));
3256- g_signal_connect (item, "activate",
3257- G_CALLBACK (remove_shortcut_cb), impl);
3258- gtk_widget_show (item);
3259- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_shortcuts_popup_menu), item);
3260-
3261- item = gtk_menu_item_new_with_label (_("Rename..."));
3262- impl->browse_shortcuts_popup_menu_rename_item = item;
3263- g_signal_connect (item, "activate",
3264- G_CALLBACK (rename_shortcut_cb), impl);
3265- gtk_widget_show (item);
3266- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_shortcuts_popup_menu), item);
3267-
3268- shortcuts_check_popup_sensitivity (impl);
3269-}
3270-
3271-static void
3272-shortcuts_update_popup_menu (GtkFileChooserDefault *impl)
3273-{
3274- shortcuts_build_popup_menu (impl);
3275-}
3276-
3277-static void
3278-popup_position_func (GtkMenu *menu,
3279- gint *x,
3280- gint *y,
3281- gboolean *push_in,
3282- gpointer user_data);
3283-
3284-static void
3285-shortcuts_popup_menu (GtkFileChooserDefault *impl,
3286- GdkEventButton *event)
3287-{
3288- shortcuts_update_popup_menu (impl);
3289- if (event)
3290- gtk_menu_popup (GTK_MENU (impl->browse_shortcuts_popup_menu),
3291- NULL, NULL, NULL, NULL,
3292- event->button, event->time);
3293- else
3294- {
3295- gtk_menu_popup (GTK_MENU (impl->browse_shortcuts_popup_menu),
3296- NULL, NULL,
3297- popup_position_func, impl->browse_shortcuts_tree_view,
3298- 0, GDK_CURRENT_TIME);
3299- gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_shortcuts_popup_menu),
3300- FALSE);
3301- }
3302-}
3303-
3304-/* Callback used for the GtkWidget::popup-menu signal of the shortcuts list */
3305-static gboolean
3306-shortcuts_popup_menu_cb (GtkWidget *widget,
3307- GtkFileChooserDefault *impl)
3308-{
3309- shortcuts_popup_menu (impl, NULL);
3310- return TRUE;
3311-}
3312-
3313-/* Callback used when a button is pressed on the shortcuts list.
3314- * We trap button 3 to bring up a popup menu.
3315- */
3316-static gboolean
3317-shortcuts_button_press_event_cb (GtkWidget *widget,
3318- GdkEventButton *event,
3319- GtkFileChooserDefault *impl)
3320-{
3321- static gboolean in_press = FALSE;
3322- gboolean handled;
3323-
3324- if (in_press)
3325- return FALSE;
3326-
3327- if (event->button != 3)
3328- return FALSE;
3329-
3330- in_press = TRUE;
3331- handled = gtk_widget_event (impl->browse_shortcuts_tree_view, (GdkEvent *) event);
3332- in_press = FALSE;
3333-
3334- if (!handled)
3335- return FALSE;
3336-
3337- shortcuts_popup_menu (impl, event);
3338- return TRUE;
3339-}
3340-
3341-static void
3342-shortcuts_edited (GtkCellRenderer *cell,
3343- gchar *path_string,
3344- gchar *new_text,
3345- GtkFileChooserDefault *impl)
3346-{
3347- GtkTreePath *path;
3348- GtkTreeIter iter;
3349- GtkFilePath *shortcut;
3350-
3351- g_object_set (cell, "editable", FALSE, NULL);
3352-
3353- path = gtk_tree_path_new_from_string (path_string);
3354- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
3355- g_assert_not_reached ();
3356-
3357- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
3358- SHORTCUTS_COL_DATA, &shortcut,
3359- -1);
3360- gtk_tree_path_free (path);
3361-
3362- gtk_file_system_set_bookmark_label (impl->file_system, shortcut, new_text);
3363-}
3364-
3365-static void
3366-shortcuts_editing_canceled (GtkCellRenderer *cell,
3367- GtkFileChooserDefault *impl)
3368-{
3369- g_object_set (cell, "editable", FALSE, NULL);
3370-}
3371-
3372-/* Creates the widgets for the shortcuts and bookmarks tree */
3373-static GtkWidget *
3374-shortcuts_list_create (GtkFileChooserDefault *impl)
3375-{
3376- GtkWidget *swin;
3377- GtkTreeSelection *selection;
3378- GtkTreeViewColumn *column;
3379- GtkCellRenderer *renderer;
3380-
3381- /* Scrolled window */
3382-
3383- swin = gtk_scrolled_window_new (NULL, NULL);
3384- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
3385- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3386- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
3387- GTK_SHADOW_IN);
3388- gtk_widget_show (swin);
3389-
3390- /* Tree */
3391-
3392- impl->browse_shortcuts_tree_view = gtk_tree_view_new ();
3393-#ifdef PROFILE_FILE_CHOOSER
3394- g_object_set_data (G_OBJECT (impl->browse_shortcuts_tree_view), "fmq-name", "shortcuts");
3395-#endif
3396- g_signal_connect (impl->browse_shortcuts_tree_view, "key_press_event",
3397- G_CALLBACK (tree_view_keybinding_cb), impl);
3398- g_signal_connect (impl->browse_shortcuts_tree_view, "popup_menu",
3399- G_CALLBACK (shortcuts_popup_menu_cb), impl);
3400- g_signal_connect (impl->browse_shortcuts_tree_view, "button_press_event",
3401- G_CALLBACK (shortcuts_button_press_event_cb), impl);
3402- /* Accessible object name for the file chooser's shortcuts pane */
3403- atk_object_set_name (gtk_widget_get_accessible (impl->browse_shortcuts_tree_view), _("Places"));
3404-
3405- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), impl->shortcuts_pane_filter_model);
3406-
3407- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
3408- GDK_BUTTON1_MASK,
3409- shortcuts_source_targets,
3410- num_shortcuts_source_targets,
3411- GDK_ACTION_MOVE);
3412-
3413- gtk_drag_dest_set (impl->browse_shortcuts_tree_view,
3414- GTK_DEST_DEFAULT_ALL,
3415- shortcuts_dest_targets,
3416- num_shortcuts_dest_targets,
3417- GDK_ACTION_COPY | GDK_ACTION_MOVE);
3418-
3419- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
3420- gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
3421- gtk_tree_selection_set_select_function (selection,
3422- shortcuts_select_func,
3423- impl, NULL);
3424-
3425- g_signal_connect (selection, "changed",
3426- G_CALLBACK (shortcuts_selection_changed_cb), impl);
3427-
3428- g_signal_connect (impl->browse_shortcuts_tree_view, "row_activated",
3429- G_CALLBACK (shortcuts_row_activated_cb), impl);
3430-
3431- g_signal_connect (impl->browse_shortcuts_tree_view, "key_press_event",
3432- G_CALLBACK (shortcuts_key_press_event_cb), impl);
3433-
3434- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_begin",
3435- G_CALLBACK (shortcuts_drag_begin_cb), impl);
3436- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_end",
3437- G_CALLBACK (shortcuts_drag_end_cb), impl);
3438- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_data_delete",
3439- G_CALLBACK (shortcuts_drag_data_delete_cb), impl);
3440-
3441- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_leave",
3442- G_CALLBACK (shortcuts_drag_leave_cb), impl);
3443- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_motion",
3444- G_CALLBACK (shortcuts_drag_motion_cb), impl);
3445- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_drop",
3446- G_CALLBACK (shortcuts_drag_drop_cb), impl);
3447- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_data_received",
3448- G_CALLBACK (shortcuts_drag_data_received_cb), impl);
3449-
3450- gtk_container_add (GTK_CONTAINER (swin), impl->browse_shortcuts_tree_view);
3451- gtk_widget_show (impl->browse_shortcuts_tree_view);
3452-
3453- /* Column */
3454-
3455- column = gtk_tree_view_column_new ();
3456- /* Column header for the file chooser's shortcuts pane */
3457- gtk_tree_view_column_set_title (column, _("_Places"));
3458-
3459- renderer = gtk_cell_renderer_pixbuf_new ();
3460- gtk_tree_view_column_pack_start (column, renderer, FALSE);
3461- gtk_tree_view_column_set_attributes (column, renderer,
3462- "pixbuf", SHORTCUTS_COL_PIXBUF,
3463- "visible", SHORTCUTS_COL_PIXBUF_VISIBLE,
3464- NULL);
3465-
3466- renderer = gtk_cell_renderer_text_new ();
3467- g_signal_connect (renderer, "edited",
3468- G_CALLBACK (shortcuts_edited), impl);
3469- g_signal_connect (renderer, "editing-canceled",
3470- G_CALLBACK (shortcuts_editing_canceled), impl);
3471- gtk_tree_view_column_pack_start (column, renderer, TRUE);
3472- gtk_tree_view_column_set_attributes (column, renderer,
3473- "text", SHORTCUTS_COL_NAME,
3474- NULL);
3475-
3476- gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
3477- shortcuts_row_separator_func,
3478- NULL, NULL);
3479-
3480- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), column);
3481-
3482- return swin;
3483-}
3484-
3485-/* Creates the widgets for the shortcuts/bookmarks pane */
3486-static GtkWidget *
3487-shortcuts_pane_create (GtkFileChooserDefault *impl,
3488- GtkSizeGroup *size_group)
3489-{
3490- GtkWidget *vbox;
3491- GtkWidget *hbox;
3492- GtkWidget *widget;
3493-
3494- vbox = gtk_vbox_new (FALSE, 6);
3495- gtk_widget_show (vbox);
3496-
3497- /* Shortcuts tree */
3498-
3499- widget = shortcuts_list_create (impl);
3500- gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
3501-
3502- /* Box for buttons */
3503-
3504- hbox = gtk_hbox_new (TRUE, 6);
3505- gtk_size_group_add_widget (size_group, hbox);
3506- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
3507- gtk_widget_show (hbox);
3508-
3509- /* Add bookmark button */
3510-
3511- impl->browse_shortcuts_add_button = button_new (impl,
3512- _("_Add"),
3513- GTK_STOCK_ADD,
3514- FALSE,
3515- TRUE,
3516- G_CALLBACK (add_bookmark_button_clicked_cb));
3517- gtk_box_pack_start (GTK_BOX (hbox), impl->browse_shortcuts_add_button, TRUE, TRUE, 0);
3518- gtk_widget_set_tooltip_text (impl->browse_shortcuts_add_button,
3519- _("Add the selected folder to the Bookmarks"));
3520-
3521- /* Remove bookmark button */
3522-
3523- impl->browse_shortcuts_remove_button = button_new (impl,
3524- _("_Remove"),
3525- GTK_STOCK_REMOVE,
3526- FALSE,
3527- TRUE,
3528- G_CALLBACK (remove_bookmark_button_clicked_cb));
3529- gtk_box_pack_start (GTK_BOX (hbox), impl->browse_shortcuts_remove_button, TRUE, TRUE, 0);
3530- gtk_widget_set_tooltip_text (impl->browse_shortcuts_remove_button,
3531- _("Remove the selected bookmark"));
3532-
3533- return vbox;
3534-}
3535-
3536 /* Handles key press events on the file list, so that we can trap Enter to
3537 * activate the default button on our own. Also, checks to see if '/' has been
3538 * pressed. See comment by tree_view_keybinding_cb() for more details.
3539@@ -4056,17 +1175,6 @@
3540
3541 modifiers = gtk_accelerator_get_default_mod_mask ();
3542
3543- if ((event->keyval == GDK_slash
3544- || event->keyval == GDK_KP_Divide
3545-#ifdef G_OS_UNIX
3546- || event->keyval == GDK_asciitilde
3547-#endif
3548- ) && ! (event->state & (~GDK_SHIFT_MASK & modifiers)))
3549- {
3550- location_popup_handler (impl, event->string);
3551- return TRUE;
3552- }
3553-
3554 if ((event->keyval == GDK_Return
3555 || event->keyval == GDK_ISO_Enter
3556 || event->keyval == GDK_KP_Enter
3557@@ -4091,474 +1199,66 @@
3558 return FALSE;
3559 }
3560
3561-/* Callback used when the file list's popup menu is detached */
3562-static void
3563-popup_menu_detach_cb (GtkWidget *attach_widget,
3564- GtkMenu *menu)
3565+static gboolean
3566+list_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
3567 {
3568- GtkFileChooserDefault *impl;
3569+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
3570+ GtkFileChooserDefault *impl = data;
3571+ GtkTreePath *path;
3572
3573- impl = g_object_get_data (G_OBJECT (attach_widget), "GtkFileChooserDefault");
3574- g_assert (GTK_IS_FILE_CHOOSER_DEFAULT (impl));
3575-
3576- impl->browse_files_popup_menu = NULL;
3577- impl->browse_files_popup_menu_add_shortcut_item = NULL;
3578- impl->browse_files_popup_menu_hidden_files_item = NULL;
3579-}
3580-
3581-/* Callback used when the "Add to Bookmarks" menu item is activated */
3582-static void
3583-add_to_shortcuts_cb (GtkMenuItem *item,
3584- GtkFileChooserDefault *impl)
3585-{
3586- bookmarks_add_selected_folder (impl);
3587-}
3588-
3589-/* Callback used when the "Show Hidden Files" menu item is toggled */
3590-static void
3591-show_hidden_toggled_cb (GtkCheckMenuItem *item,
3592- GtkFileChooserDefault *impl)
3593-{
3594- g_object_set (impl,
3595- "show-hidden", gtk_check_menu_item_get_active (item),
3596- NULL);
3597-}
3598-
3599-/* Shows an error dialog about not being able to select a dragged file */
3600-static void
3601-error_selecting_dragged_file_dialog (GtkFileChooserDefault *impl,
3602- const GtkFilePath *path,
3603- GError *error)
3604-{
3605- error_dialog (impl,
3606- _("Could not select file"),
3607- path, error);
3608-}
3609-
3610-static void
3611-file_list_drag_data_select_uris (GtkFileChooserDefault *impl,
3612- gchar **uris)
3613-{
3614- int i;
3615- char *uri;
3616- GtkFileChooser *chooser = GTK_FILE_CHOOSER (impl);
3617-
3618- for (i = 1; uris[i]; i++)
3619+ if (event->type != GDK_BUTTON_PRESS ||
3620+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
3621+ &path, NULL, NULL, NULL))
3622 {
3623- GtkFilePath *path;
3624-
3625- uri = uris[i];
3626- path = gtk_file_system_uri_to_path (impl->file_system, uri);
3627-
3628- if (path)
3629- {
3630- GError *error = NULL;
3631-
3632- gtk_file_chooser_default_select_path (chooser, path, &error);
3633- if (error)
3634- error_selecting_dragged_file_dialog (impl, path, error);
3635-
3636- gtk_file_path_free (path);
3637- }
3638+ return FALSE;
3639 }
3640-}
3641
3642-struct FileListDragData
3643-{
3644- GtkFileChooserDefault *impl;
3645- gchar **uris;
3646- GtkFilePath *path;
3647-};
3648+ impl->list_press_time = event->time;
3649+ impl->list_press_path = path;
3650
3651-static void
3652-file_list_drag_data_received_get_info_cb (GtkFileSystemHandle *handle,
3653- const GtkFileInfo *info,
3654- const GError *error,
3655- gpointer user_data)
3656-{
3657- gboolean cancelled = handle->cancelled;
3658- struct FileListDragData *data = user_data;
3659- GtkFileChooser *chooser = GTK_FILE_CHOOSER (data->impl);
3660-
3661- if (handle != data->impl->file_list_drag_data_received_handle)
3662- goto out;
3663-
3664- data->impl->file_list_drag_data_received_handle = NULL;
3665-
3666- if (cancelled || error)
3667- goto out;
3668-
3669- if ((data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
3670- data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) &&
3671- data->uris[1] == 0 && !error &&
3672- gtk_file_info_get_is_folder (info))
3673- change_folder_and_display_error (data->impl, data->path, FALSE);
3674- else
3675- {
3676- GError *error = NULL;
3677-
3678- gtk_file_chooser_default_unselect_all (chooser);
3679- gtk_file_chooser_default_select_path (chooser, data->path, &error);
3680- if (error)
3681- error_selecting_dragged_file_dialog (data->impl, data->path, error);
3682- else
3683- browse_files_center_selected_row (data->impl);
3684- }
3685-
3686- if (data->impl->select_multiple)
3687- file_list_drag_data_select_uris (data->impl, data->uris);
3688-
3689-out:
3690- g_object_unref (data->impl);
3691- g_strfreev (data->uris);
3692- gtk_file_path_free (data->path);
3693- g_free (data);
3694-
3695- g_object_unref (handle);
3696+ return FALSE;
3697 }
3698
3699-static void
3700-file_list_drag_data_received_cb (GtkWidget *widget,
3701- GdkDragContext *context,
3702- gint x,
3703- gint y,
3704- GtkSelectionData *selection_data,
3705- guint info,
3706- guint time_,
3707- gpointer data)
3708-{
3709- GtkFileChooserDefault *impl;
3710- GtkFileChooser *chooser;
3711- gchar **uris;
3712- char *uri;
3713- GtkFilePath *path;
3714- GError *error = NULL;
3715-
3716- impl = GTK_FILE_CHOOSER_DEFAULT (data);
3717- chooser = GTK_FILE_CHOOSER (data);
3718-
3719- /* Parse the text/uri-list string, navigate to the first one */
3720- uris = g_uri_list_extract_uris ((const char *) selection_data->data);
3721- if (uris[0])
3722- {
3723- uri = uris[0];
3724- path = gtk_file_system_uri_to_path (impl->file_system, uri);
3725-
3726- if (path)
3727- {
3728- struct FileListDragData *data;
3729-
3730- data = g_new0 (struct FileListDragData, 1);
3731- data->impl = g_object_ref (impl);
3732- data->uris = uris;
3733- data->path = path;
3734-
3735- if (impl->file_list_drag_data_received_handle)
3736- gtk_file_system_cancel_operation (impl->file_list_drag_data_received_handle);
3737-
3738- impl->file_list_drag_data_received_handle =
3739- gtk_file_system_get_info (impl->file_system, path,
3740- GTK_FILE_INFO_IS_FOLDER,
3741- file_list_drag_data_received_get_info_cb,
3742- data);
3743- goto out;
3744- }
3745- else
3746- {
3747- g_set_error (&error,
3748- GTK_FILE_CHOOSER_ERROR,
3749- GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
3750- _("Could not select file '%s' "
3751- "because it is an invalid path name."),
3752- uri);
3753- error_selecting_dragged_file_dialog (impl, NULL, error);
3754- }
3755-
3756- if (impl->select_multiple)
3757- file_list_drag_data_select_uris (impl, uris);
3758- }
3759-
3760- g_strfreev (uris);
3761-
3762-out:
3763- g_signal_stop_emission_by_name (widget, "drag_data_received");
3764-}
3765-
3766-/* Don't do anything with the drag_drop signal */
3767 static gboolean
3768-file_list_drag_drop_cb (GtkWidget *widget,
3769- GdkDragContext *context,
3770- gint x,
3771- gint y,
3772- guint time_,
3773- GtkFileChooserDefault *impl)
3774+list_button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
3775 {
3776- g_signal_stop_emission_by_name (widget, "drag_drop");
3777- return TRUE;
3778-}
3779+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
3780+ GtkFileChooserDefault *impl = data;
3781+ GtkTreePath *path = NULL;
3782+ gboolean retval = FALSE;
3783
3784-/* Disable the normal tree drag motion handler, it makes it look like you're
3785- dropping the dragged item onto a tree item */
3786-static gboolean
3787-file_list_drag_motion_cb (GtkWidget *widget,
3788- GdkDragContext *context,
3789- gint x,
3790- gint y,
3791- guint time_,
3792- GtkFileChooserDefault *impl)
3793-{
3794- g_signal_stop_emission_by_name (widget, "drag_motion");
3795- return TRUE;
3796-}
3797-
3798-/* Constructs the popup menu for the file list if needed */
3799-static void
3800-file_list_build_popup_menu (GtkFileChooserDefault *impl)
3801-{
3802- GtkWidget *item;
3803-
3804- if (impl->browse_files_popup_menu)
3805- return;
3806-
3807- impl->browse_files_popup_menu = gtk_menu_new ();
3808- gtk_menu_attach_to_widget (GTK_MENU (impl->browse_files_popup_menu),
3809- impl->browse_files_tree_view,
3810- popup_menu_detach_cb);
3811-
3812- item = gtk_image_menu_item_new_with_mnemonic (_("_Add to Bookmarks"));
3813- impl->browse_files_popup_menu_add_shortcut_item = item;
3814- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
3815- gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU));
3816- gtk_widget_set_sensitive (item, FALSE);
3817- g_signal_connect (item, "activate",
3818- G_CALLBACK (add_to_shortcuts_cb), impl);
3819- gtk_widget_show (item);
3820- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
3821-
3822- item = gtk_separator_menu_item_new ();
3823- gtk_widget_show (item);
3824- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
3825-
3826- item = gtk_check_menu_item_new_with_mnemonic (_("Show _Hidden Files"));
3827- impl->browse_files_popup_menu_hidden_files_item = item;
3828- g_signal_connect (item, "toggled",
3829- G_CALLBACK (show_hidden_toggled_cb), impl);
3830- gtk_widget_show (item);
3831- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
3832-}
3833-
3834-/* Updates the popup menu for the file list, creating it if necessary */
3835-static void
3836-file_list_update_popup_menu (GtkFileChooserDefault *impl)
3837-{
3838- file_list_build_popup_menu (impl);
3839-
3840- /* FIXME - handle OPERATION_MODE_SEARCH and OPERATION_MODE_RECENT */
3841-
3842- /* The sensitivity of the Add to Bookmarks item is set in
3843- * bookmarks_check_add_sensitivity()
3844- */
3845-
3846- g_signal_handlers_block_by_func (impl->browse_files_popup_menu_hidden_files_item,
3847- G_CALLBACK (show_hidden_toggled_cb), impl);
3848- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (impl->browse_files_popup_menu_hidden_files_item),
3849- impl->show_hidden);
3850- g_signal_handlers_unblock_by_func (impl->browse_files_popup_menu_hidden_files_item,
3851- G_CALLBACK (show_hidden_toggled_cb), impl);
3852-}
3853-
3854-static void
3855-popup_position_func (GtkMenu *menu,
3856- gint *x,
3857- gint *y,
3858- gboolean *push_in,
3859- gpointer user_data)
3860-{
3861- GtkWidget *widget = GTK_WIDGET (user_data);
3862- GdkScreen *screen = gtk_widget_get_screen (widget);
3863- GtkRequisition req;
3864- gint monitor_num;
3865- GdkRectangle monitor;
3866-
3867- g_return_if_fail (GTK_WIDGET_REALIZED (widget));
3868-
3869- gdk_window_get_origin (widget->window, x, y);
3870-
3871- gtk_widget_size_request (GTK_WIDGET (menu), &req);
3872-
3873- *x += (widget->allocation.width - req.width) / 2;
3874- *y += (widget->allocation.height - req.height) / 2;
3875-
3876- monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
3877- gtk_menu_set_monitor (menu, monitor_num);
3878- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
3879-
3880- *x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
3881- *y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
3882-
3883- *push_in = FALSE;
3884-}
3885-
3886-static void
3887-file_list_popup_menu (GtkFileChooserDefault *impl,
3888- GdkEventButton *event)
3889-{
3890- file_list_update_popup_menu (impl);
3891- if (event)
3892- gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
3893- NULL, NULL, NULL, NULL,
3894- event->button, event->time);
3895- else
3896+ if (!impl->list_press_time ||
3897+ !impl->list_press_path ||
3898+ event->type != GDK_BUTTON_RELEASE ||
3899+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
3900+ &path, NULL, NULL, NULL))
3901 {
3902- gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
3903- NULL, NULL,
3904- popup_position_func, impl->browse_files_tree_view,
3905- 0, GDK_CURRENT_TIME);
3906- gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_files_popup_menu),
3907- FALSE);
3908+ goto done;
3909 }
3910
3911-}
3912-
3913-/* Callback used for the GtkWidget::popup-menu signal of the file list */
3914-static gboolean
3915-list_popup_menu_cb (GtkWidget *widget,
3916- GtkFileChooserDefault *impl)
3917-{
3918- file_list_popup_menu (impl, NULL);
3919- return TRUE;
3920-}
3921-
3922-/* Callback used when a button is pressed on the file list. We trap button 3 to
3923- * bring up a popup menu.
3924- */
3925-static gboolean
3926-list_button_press_event_cb (GtkWidget *widget,
3927- GdkEventButton *event,
3928- GtkFileChooserDefault *impl)
3929-{
3930- static gboolean in_press = FALSE;
3931- gboolean handled;
3932-
3933- if (in_press)
3934- return FALSE;
3935-
3936- if (event->button != 3)
3937- return FALSE;
3938-
3939- in_press = TRUE;
3940- handled = gtk_widget_event (impl->browse_files_tree_view, (GdkEvent *) event);
3941- in_press = FALSE;
3942-
3943- file_list_popup_menu (impl, event);
3944- return TRUE;
3945-}
3946-
3947-/* Sets the sort column IDs for the file list based on the operation mode */
3948-static void
3949-file_list_set_sort_column_ids (GtkFileChooserDefault *impl)
3950-{
3951- int name_id, mtime_id;
3952-
3953- name_id = mtime_id = 0;
3954-
3955- switch (impl->operation_mode)
3956+ if (event->time - impl->list_press_time > LONG_CLICK_LENGTH &&
3957+ !gtk_tree_path_compare (impl->list_press_path, path))
3958 {
3959- case OPERATION_MODE_BROWSE:
3960- name_id = FILE_LIST_COL_NAME;
3961- mtime_id = FILE_LIST_COL_MTIME;
3962- break;
3963- case OPERATION_MODE_SEARCH:
3964- name_id = SEARCH_MODEL_COL_PATH;
3965- mtime_id = SEARCH_MODEL_COL_STAT;
3966- break;
3967- case OPERATION_MODE_RECENT:
3968- name_id = RECENT_MODEL_COL_PATH;
3969- mtime_id = RECENT_MODEL_COL_INFO;
3970- break;
3971+ retval = TRUE;
3972+ list_row_activated (tree, path, NULL, impl);
3973 }
3974
3975- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id);
3976- gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id);
3977-}
3978+ done:
3979+ if (path)
3980+ gtk_tree_path_free (path);
3981
3982-static gboolean
3983-file_list_query_tooltip_cb (GtkWidget *widget,
3984- gint x,
3985- gint y,
3986- gboolean keyboard_tip,
3987- GtkTooltip *tooltip,
3988- gpointer user_data)
3989-{
3990- GtkFileChooserDefault *impl = user_data;
3991- GtkTreeIter iter, child_iter;
3992- GtkTreePath *path = NULL;
3993- GtkFilePath *file_path = NULL;
3994- gchar *filename;
3995+ impl->list_press_time = 0;
3996
3997- if (impl->operation_mode == OPERATION_MODE_BROWSE)
3998- return FALSE;
3999-
4000-
4001- gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (impl->browse_files_tree_view),
4002- &x, &y,
4003- keyboard_tip,
4004- NULL, &path, NULL);
4005-
4006- if (!path)
4007- return FALSE;
4008-
4009- switch (impl->operation_mode)
4010+ if (impl->list_press_path)
4011 {
4012- case OPERATION_MODE_SEARCH:
4013- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
4014- {
4015- gtk_tree_path_free (path);
4016- return FALSE;
4017- }
4018-
4019- search_get_valid_child_iter (impl, &child_iter, &iter);
4020- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
4021- SEARCH_MODEL_COL_PATH, &file_path,
4022- -1);
4023- break;
4024-
4025- case OPERATION_MODE_RECENT:
4026- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), &iter, path))
4027- {
4028- gtk_tree_path_free (path);
4029- return FALSE;
4030- }
4031-
4032- recent_get_valid_child_iter (impl, &child_iter, &iter);
4033- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
4034- RECENT_MODEL_COL_PATH, &file_path,
4035- -1);
4036- break;
4037-
4038- case OPERATION_MODE_BROWSE:
4039- g_assert_not_reached ();
4040- return FALSE;
4041+ gtk_tree_path_free (impl->list_press_path);
4042+ impl->list_press_path = NULL;
4043 }
4044
4045- if (!file_path)
4046- {
4047- gtk_tree_path_free (path);
4048- return FALSE;
4049- }
4050-
4051- filename = gtk_file_system_path_to_filename (impl->file_system, file_path);
4052- gtk_tooltip_set_text (tooltip, filename);
4053- gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (impl->browse_files_tree_view),
4054- tooltip,
4055- path);
4056-
4057- g_free (filename);
4058- gtk_tree_path_free (path);
4059-
4060- return TRUE;
4061+ return FALSE;
4062 }
4063
4064+
4065 /* Creates the widgets for the file list */
4066 static GtkWidget *
4067 create_file_list (GtkFileChooserDefault *impl)
4068@@ -4572,7 +1272,7 @@
4069
4070 swin = gtk_scrolled_window_new (NULL, NULL);
4071 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
4072- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
4073+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4074 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
4075 GTK_SHADOW_IN);
4076
4077@@ -4588,41 +1288,19 @@
4078 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE);
4079 gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view);
4080
4081- gtk_drag_dest_set (impl->browse_files_tree_view,
4082- GTK_DEST_DEFAULT_ALL,
4083- file_list_dest_targets,
4084- num_file_list_dest_targets,
4085- GDK_ACTION_COPY | GDK_ACTION_MOVE);
4086-
4087 g_signal_connect (impl->browse_files_tree_view, "row_activated",
4088 G_CALLBACK (list_row_activated), impl);
4089 g_signal_connect (impl->browse_files_tree_view, "key_press_event",
4090 G_CALLBACK (trap_activate_cb), impl);
4091- g_signal_connect (impl->browse_files_tree_view, "popup_menu",
4092- G_CALLBACK (list_popup_menu_cb), impl);
4093 g_signal_connect (impl->browse_files_tree_view, "button_press_event",
4094- G_CALLBACK (list_button_press_event_cb), impl);
4095+ G_CALLBACK (list_button_press), impl);
4096+ g_signal_connect (impl->browse_files_tree_view, "button_release_event",
4097+ G_CALLBACK (list_button_release), impl);
4098
4099- g_signal_connect (impl->browse_files_tree_view, "drag_data_received",
4100- G_CALLBACK (file_list_drag_data_received_cb), impl);
4101- g_signal_connect (impl->browse_files_tree_view, "drag_drop",
4102- G_CALLBACK (file_list_drag_drop_cb), impl);
4103- g_signal_connect (impl->browse_files_tree_view, "drag_motion",
4104- G_CALLBACK (file_list_drag_motion_cb), impl);
4105-
4106- g_object_set (impl->browse_files_tree_view, "has-tooltip", TRUE, NULL);
4107- g_signal_connect (impl->browse_files_tree_view, "query-tooltip",
4108- G_CALLBACK (file_list_query_tooltip_cb), impl);
4109-
4110 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
4111 gtk_tree_selection_set_select_function (selection,
4112 list_select_func,
4113 impl, NULL);
4114- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_files_tree_view),
4115- GDK_BUTTON1_MASK,
4116- file_list_source_targets,
4117- num_file_list_source_targets,
4118- GDK_ACTION_COPY);
4119
4120 g_signal_connect (selection, "changed",
4121 G_CALLBACK (list_selection_changed), impl);
4122@@ -4666,7 +1344,6 @@
4123 gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
4124 gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
4125 #endif
4126-
4127 /* Modification time column */
4128
4129 column = gtk_tree_view_column_new ();
4130@@ -4677,276 +1354,221 @@
4131 gtk_tree_view_column_pack_start (column, renderer, TRUE);
4132 gtk_tree_view_column_set_cell_data_func (column, renderer,
4133 list_mtime_data_func, impl, NULL);
4134+ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_MTIME);
4135 gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
4136- impl->list_mtime_column = column;
4137-
4138- file_list_set_sort_column_ids (impl);
4139-
4140 gtk_widget_show_all (swin);
4141
4142 return swin;
4143 }
4144
4145-static GtkWidget *
4146-create_path_bar (GtkFileChooserDefault *impl)
4147+static void
4148+up_button_clicked_cb (GtkButton *button, gpointer data)
4149 {
4150- GtkWidget *path_bar;
4151+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
4152+ up_folder_handler (impl);
4153+}
4154
4155- path_bar = g_object_new (GTK_TYPE_PATH_BAR, NULL);
4156- _gtk_path_bar_set_file_system (GTK_PATH_BAR (path_bar), impl->file_system);
4157+static void
4158+volume_button_clicked_cb (GtkButton *button, gpointer data)
4159+{
4160+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
4161+ GtkFilePath * path = g_object_get_data (G_OBJECT (button), "file-path");
4162
4163- return path_bar;
4164+ change_folder_and_display_error (impl, path);
4165 }
4166
4167-/* Creates the widgets for the files/folders pane */
4168 static GtkWidget *
4169-file_pane_create (GtkFileChooserDefault *impl,
4170- GtkSizeGroup *size_group)
4171+create_bar (GtkFileChooserDefault *impl)
4172 {
4173- GtkWidget *vbox;
4174- GtkWidget *hbox;
4175- GtkWidget *widget;
4176+ GSList *list, *l;
4177+ int n;
4178+ GtkWidget *bar = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4179+ GtkWidget *img;
4180+ GtkWidget *label;
4181
4182- vbox = gtk_vbox_new (FALSE, 6);
4183- gtk_widget_show (vbox);
4184+ /* first the Up button */
4185+ img = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
4186+ gtk_widget_show (img);
4187
4188- /* Box for lists and preview */
4189+ impl->up_button = gtk_button_new ();
4190+ gtk_container_add (GTK_CONTAINER (impl->up_button), img);
4191+ gtk_widget_show (impl->up_button);
4192+ gtk_widget_set_sensitive (impl->up_button, FALSE);
4193+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->up_button), FALSE);
4194
4195- hbox = gtk_hbox_new (FALSE, PREVIEW_HBOX_SPACING);
4196- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
4197- gtk_widget_show (hbox);
4198+ g_signal_connect (impl->up_button, "clicked",
4199+ G_CALLBACK (up_button_clicked_cb), impl);
4200+ gtk_box_pack_start (GTK_BOX(bar), impl->up_button, FALSE, FALSE, 0);
4201
4202- /* File list */
4203+ impl->num_volumes = 0;
4204+ list = gtk_file_system_list_volumes (impl->file_system);
4205
4206- widget = create_file_list (impl);
4207- gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
4208+ n = 0;
4209
4210- /* Preview */
4211+ for (l = list; l; l = l->next, n++)
4212+ {
4213+ GtkFileSystemVolume *volume;
4214+ GdkPixbuf *pixbuf;
4215+ GtkWidget *button;
4216+ GtkWidget *image;
4217+ GtkFilePath *base_path;
4218+ gchar * file_name = NULL;
4219
4220- impl->preview_box = gtk_vbox_new (FALSE, 12);
4221- gtk_box_pack_start (GTK_BOX (hbox), impl->preview_box, FALSE, FALSE, 0);
4222- /* Don't show preview box initially */
4223+ volume = l->data;
4224+ base_path =
4225+ gtk_file_system_volume_get_base_path (impl->file_system, volume);
4226
4227- /* Filter combo */
4228+ if (impl->local_only)
4229+ {
4230+ gboolean is_local =
4231+ gtk_file_system_path_is_local (impl->file_system, base_path);
4232
4233- impl->filter_combo_hbox = gtk_hbox_new (FALSE, 12);
4234+ if (!is_local)
4235+ {
4236+ gtk_file_path_free (base_path);
4237+ gtk_file_system_volume_free (impl->file_system, volume);
4238+ continue;
4239+ }
4240+ }
4241
4242- widget = filter_create (impl);
4243+#if 0
4244+ label_copy =
4245+ gtk_file_system_volume_get_display_name (impl->file_system, volume);
4246+#endif
4247+ pixbuf =
4248+ gtk_file_system_volume_render_icon (impl->file_system, volume,
4249+ GTK_WIDGET (impl),
4250+ impl->icon_size, NULL);
4251
4252- gtk_widget_show (widget);
4253- gtk_box_pack_end (GTK_BOX (impl->filter_combo_hbox), widget, FALSE, FALSE, 0);
4254+ button = gtk_button_new ();
4255+ image = gtk_image_new_from_pixbuf (pixbuf);
4256+ g_object_unref (G_OBJECT (pixbuf));
4257+ gtk_container_add (GTK_CONTAINER (button), image);
4258+ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
4259
4260- gtk_size_group_add_widget (size_group, impl->filter_combo_hbox);
4261- gtk_box_pack_end (GTK_BOX (vbox), impl->filter_combo_hbox, FALSE, FALSE, 0);
4262+ file_name =
4263+ gtk_file_system_path_to_filename (impl->file_system, base_path);
4264
4265- return vbox;
4266-}
4267+ if (file_name && impl->root_folder &&
4268+ strcmp (file_name, impl->root_folder) &&
4269+ !strncmp (file_name, impl->root_folder, strlen (file_name)))
4270+ {
4271+ /* The base path is below the root folder; we replace it with
4272+ * the root folder
4273+ */
4274+ gtk_file_path_free (base_path);
4275+ base_path = gtk_file_system_filename_to_path (impl->file_system,
4276+ impl->root_folder);
4277+ }
4278
4279-/* Callback used when the "Browse for more folders" expander is toggled */
4280-static void
4281-expander_changed_cb (GtkExpander *expander,
4282- GParamSpec *pspec,
4283- GtkFileChooserDefault *impl)
4284-{
4285- impl->expand_folders = gtk_expander_get_expanded(GTK_EXPANDER (impl->save_expander));
4286- update_appearance (impl);
4287-}
4288+ g_free (file_name);
4289+ gtk_widget_show_all (button);
4290
4291-/* Callback used when the selection changes in the save folder combo box */
4292-static void
4293-save_folder_combo_changed_cb (GtkComboBox *combo,
4294- GtkFileChooserDefault *impl)
4295-{
4296- GtkTreeIter iter;
4297+ g_object_set_data (G_OBJECT (button), "file-path", base_path);
4298
4299- if (impl->changing_folder)
4300- return;
4301+ g_signal_connect (button, "clicked",
4302+ G_CALLBACK (volume_button_clicked_cb), impl);
4303
4304- if (gtk_combo_box_get_active_iter (combo, &iter))
4305- {
4306- GtkTreeIter child_iter;
4307-
4308- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
4309- &child_iter,
4310- &iter);
4311- shortcuts_activate_iter (impl, &child_iter);
4312- }
4313-}
4314+ gtk_box_pack_start (GTK_BOX(bar), button, FALSE, FALSE, 0);
4315+ }
4316
4317-/* Filter function used to filter out the Search item and its separator.
4318- * Used for the "Save in folder" combo box, so that these items do not appear in it.
4319- */
4320-static gboolean
4321-shortcuts_combo_filter_func (GtkTreeModel *model,
4322- GtkTreeIter *iter,
4323- gpointer data)
4324-{
4325- GtkFileChooserDefault *impl;
4326- GtkTreePath *tree_path;
4327- gint *indices;
4328- int idx;
4329- gboolean retval;
4330+ impl->num_volumes = n;
4331+ g_slist_free (list);
4332
4333- impl = GTK_FILE_CHOOSER_DEFAULT (data);
4334+ label = impl->location_label = gtk_label_new (NULL);
4335+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
4336+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
4337+ gtk_label_set_text (GTK_LABEL (label), impl->root_folder);
4338+ gtk_widget_show (label);
4339+ gtk_box_pack_start (GTK_BOX(bar), label, TRUE, TRUE, 0);
4340
4341- g_assert (model == GTK_TREE_MODEL (impl->shortcuts_model));
4342+ gtk_widget_show (bar);
4343
4344- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), iter);
4345- g_assert (tree_path != NULL);
4346+ return bar;
4347+}
4348
4349- indices = gtk_tree_path_get_indices (tree_path);
4350-
4351- retval = TRUE;
4352-
4353- if (impl->has_search)
4354- {
4355- idx = shortcuts_get_index (impl, SHORTCUTS_SEARCH);
4356- if (idx == indices[0])
4357- retval = FALSE;
4358- }
4359-
4360- if (impl->has_recent)
4361- {
4362- idx = shortcuts_get_index (impl, SHORTCUTS_RECENT);
4363- if (idx == indices[0])
4364- retval = FALSE;
4365- else
4366- {
4367- idx = shortcuts_get_index (impl, SHORTCUTS_RECENT_SEPARATOR);
4368- if (idx == indices[0])
4369- retval = FALSE;
4370- }
4371- }
4372-
4373- gtk_tree_path_free (tree_path);
4374-
4375- return retval;
4376- }
4377-
4378-/* Creates the combo box with the save folders */
4379+/* Creates the widgets for the files/folders pane */
4380 static GtkWidget *
4381-save_folder_combo_create (GtkFileChooserDefault *impl)
4382+file_pane_create (GtkFileChooserDefault *impl)
4383 {
4384- GtkWidget *combo;
4385- GtkCellRenderer *cell;
4386+ GtkWidget *vbox;
4387+ GtkWidget *hbox;
4388+ GtkWidget *widget;
4389+ vbox = gtk_vbox_new (FALSE, DEFAULT_SPACING);
4390+ gtk_widget_show (vbox);
4391
4392- impl->shortcuts_combo_filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->shortcuts_model), NULL);
4393- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
4394- shortcuts_combo_filter_func,
4395- impl,
4396- NULL);
4397+ /* The volume bar and 'Create Folder' button */
4398+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4399+ gtk_widget_show (hbox);
4400+ impl->bar = create_bar (impl);
4401+ gtk_widget_show_all (impl->bar);
4402+ gtk_box_pack_start (GTK_BOX (hbox), impl->bar, TRUE, TRUE, 0);
4403
4404- combo = g_object_new (GTK_TYPE_COMBO_BOX,
4405- "model", impl->shortcuts_combo_filter_model,
4406- "focus-on-click", FALSE,
4407- NULL);
4408- gtk_widget_show (combo);
4409+ /* Create Folder */
4410+ widget = gtk_image_new_from_icon_name ("folder-new", GTK_ICON_SIZE_BUTTON);
4411+ gtk_widget_show (widget);
4412+ impl->browse_new_folder_button = gtk_button_new ();
4413+ gtk_container_add (GTK_CONTAINER (impl->browse_new_folder_button), widget);
4414+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->browse_new_folder_button),
4415+ FALSE);
4416
4417- cell = gtk_cell_renderer_pixbuf_new ();
4418- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, FALSE);
4419- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
4420- "pixbuf", SHORTCUTS_COL_PIXBUF,
4421- "visible", SHORTCUTS_COL_PIXBUF_VISIBLE,
4422- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE,
4423- NULL);
4424+ g_signal_connect (impl->browse_new_folder_button, "clicked",
4425+ G_CALLBACK (new_folder_button_clicked), impl);
4426+ gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
4427
4428- cell = gtk_cell_renderer_text_new ();
4429- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
4430- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
4431- "text", SHORTCUTS_COL_NAME,
4432- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE,
4433- NULL);
4434+ widget = filter_create (impl);
4435+ gtk_widget_hide (widget);
4436+ gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
4437
4438- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
4439- shortcuts_row_separator_func,
4440- NULL, NULL);
4441+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4442
4443- g_signal_connect (combo, "changed",
4444- G_CALLBACK (save_folder_combo_changed_cb), impl);
4445+ /* Box for lists */
4446+ hbox = gtk_hbox_new (FALSE, LIST_HBOX_SPACING);
4447+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
4448+ gtk_widget_show (hbox);
4449
4450- return combo;
4451+ /* File list */
4452+
4453+ widget = create_file_list (impl);
4454+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
4455+
4456+ return vbox;
4457 }
4458
4459 /* Creates the widgets specific to Save mode */
4460-static void
4461+static GtkWidget *
4462 save_widgets_create (GtkFileChooserDefault *impl)
4463 {
4464 GtkWidget *vbox;
4465- GtkWidget *table;
4466+ GtkWidget *hbox;
4467 GtkWidget *widget;
4468- GtkWidget *alignment;
4469
4470- if (impl->save_widgets != NULL)
4471- return;
4472+ vbox = gtk_vbox_new (FALSE, 0);
4473+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4474
4475- location_switch_to_path_bar (impl);
4476-
4477- vbox = gtk_vbox_new (FALSE, 12);
4478-
4479- table = gtk_table_new (2, 2, FALSE);
4480- gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
4481- gtk_widget_show (table);
4482- gtk_table_set_row_spacings (GTK_TABLE (table), 12);
4483- gtk_table_set_col_spacings (GTK_TABLE (table), 12);
4484-
4485- /* Label */
4486-
4487- widget = gtk_label_new_with_mnemonic (_("_Name:"));
4488+ widget = gtk_label_new (_("Name:"));
4489 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
4490- gtk_table_attach (GTK_TABLE (table), widget,
4491- 0, 1, 0, 1,
4492- GTK_FILL, GTK_FILL,
4493- 0, 0);
4494+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
4495 gtk_widget_show (widget);
4496
4497- /* Location entry */
4498-
4499 impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
4500 _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
4501 impl->file_system);
4502- gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
4503+/* gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); */
4504 gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
4505- gtk_table_attach (GTK_TABLE (table), impl->location_entry,
4506- 1, 2, 0, 1,
4507- GTK_EXPAND | GTK_FILL, 0,
4508- 0, 0);
4509+ gtk_box_pack_start (GTK_BOX (hbox), impl->location_entry,
4510+ TRUE, TRUE, 0);
4511+
4512 gtk_widget_show (impl->location_entry);
4513- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), impl->location_entry);
4514
4515- /* Folder combo */
4516- impl->save_folder_label = gtk_label_new (NULL);
4517- gtk_misc_set_alignment (GTK_MISC (impl->save_folder_label), 0.0, 0.5);
4518- gtk_table_attach (GTK_TABLE (table), impl->save_folder_label,
4519- 0, 1, 1, 2,
4520- GTK_FILL, GTK_FILL,
4521- 0, 0);
4522- gtk_widget_show (impl->save_folder_label);
4523+ gtk_widget_show (hbox);
4524+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4525
4526- impl->save_folder_combo = save_folder_combo_create (impl);
4527- gtk_table_attach (GTK_TABLE (table), impl->save_folder_combo,
4528- 1, 2, 1, 2,
4529- GTK_EXPAND | GTK_FILL, GTK_FILL,
4530- 0, 0);
4531- gtk_label_set_mnemonic_widget (GTK_LABEL (impl->save_folder_label), impl->save_folder_combo);
4532-
4533- /* Expander */
4534- alignment = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
4535- gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
4536-
4537- impl->save_expander = gtk_expander_new_with_mnemonic (_("_Browse for other folders"));
4538- gtk_container_add (GTK_CONTAINER (alignment), impl->save_expander);
4539- g_signal_connect (impl->save_expander, "notify::expanded",
4540- G_CALLBACK (expander_changed_cb),
4541- impl);
4542- gtk_widget_show_all (alignment);
4543-
4544- impl->save_widgets = vbox;
4545- gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0);
4546- gtk_box_reorder_child (GTK_BOX (impl), impl->save_widgets, 0);
4547- gtk_widget_show (impl->save_widgets);
4548+ return vbox;
4549 }
4550
4551 /* Destroys the widgets specific to Save mode */
4552+/* ??? */
4553 static void
4554 save_widgets_destroy (GtkFileChooserDefault *impl)
4555 {
4556@@ -4956,313 +1578,17 @@
4557 gtk_widget_destroy (impl->save_widgets);
4558 impl->save_widgets = NULL;
4559 impl->location_entry = NULL;
4560- impl->save_folder_label = NULL;
4561- impl->save_folder_combo = NULL;
4562- impl->save_expander = NULL;
4563 }
4564
4565-/* Turns on the path bar widget. Can be called even if we are already in that
4566- * mode.
4567- */
4568-static void
4569-location_switch_to_path_bar (GtkFileChooserDefault *impl)
4570-{
4571- if (impl->location_entry)
4572- {
4573- gtk_widget_destroy (impl->location_entry);
4574- impl->location_entry = NULL;
4575- }
4576-
4577- gtk_widget_hide (impl->location_entry_box);
4578-}
4579-
4580-/* Sets the full path of the current folder as the text in the location entry. */
4581-static void
4582-location_entry_set_initial_text (GtkFileChooserDefault *impl)
4583-{
4584- char *text;
4585-
4586- if (!impl->current_folder)
4587- return;
4588-
4589- if (gtk_file_system_path_is_local (impl->file_system, impl->current_folder))
4590- {
4591- char *filename;
4592-
4593- filename = gtk_file_system_path_to_filename (impl->file_system, impl->current_folder);
4594- if (filename)
4595- {
4596- text = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
4597- g_free (filename);
4598- }
4599- else
4600- text = NULL;
4601- }
4602- else
4603- text = gtk_file_system_path_to_uri (impl->file_system, impl->current_folder);
4604-
4605- if (text)
4606- {
4607- gboolean need_slash;
4608- int len;
4609-
4610- len = strlen (text);
4611- need_slash = (text[len - 1] != G_DIR_SEPARATOR);
4612-
4613- if (need_slash)
4614- {
4615- char *slash_text;
4616-
4617- slash_text = g_new (char, len + 2);
4618- strcpy (slash_text, text);
4619- slash_text[len] = G_DIR_SEPARATOR;
4620- slash_text[len + 1] = 0;
4621-
4622- g_free (text);
4623- text = slash_text;
4624- }
4625-
4626- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), text);
4627- g_free (text);
4628- }
4629-}
4630-
4631-/* Turns on the location entry. Can be called even if we are already in that
4632- * mode.
4633- */
4634-static void
4635-location_switch_to_filename_entry (GtkFileChooserDefault *impl)
4636-{
4637- /* when in search or recent files mode, we are not showing the
4638- * location_entry_box container, so there's no point in switching
4639- * to it.
4640- */
4641- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
4642- impl->operation_mode == OPERATION_MODE_RECENT)
4643- return;
4644-
4645- if (impl->location_entry)
4646- gtk_widget_destroy (impl->location_entry);
4647-
4648- /* Box */
4649-
4650- gtk_widget_show (impl->location_entry_box);
4651-
4652- /* Entry */
4653-
4654- impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
4655- _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
4656- impl->file_system);
4657- gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
4658- _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
4659-
4660- gtk_box_pack_start (GTK_BOX (impl->location_entry_box), impl->location_entry, TRUE, TRUE, 0);
4661- gtk_label_set_mnemonic_widget (GTK_LABEL (impl->location_label), impl->location_entry);
4662-
4663- /* Configure the entry */
4664-
4665- _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->current_folder);
4666-
4667- /* Done */
4668-
4669- gtk_widget_show (impl->location_entry);
4670- gtk_widget_grab_focus (impl->location_entry);
4671-}
4672-
4673-/* Sets a new location mode. set_buttons determines whether the toggle button
4674- * for the mode will also be changed.
4675- */
4676-static void
4677-location_mode_set (GtkFileChooserDefault *impl,
4678- LocationMode new_mode,
4679- gboolean set_button)
4680-{
4681- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
4682- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
4683- {
4684- GtkWindow *toplevel;
4685- GtkWidget *current_focus;
4686- gboolean button_active;
4687- gboolean switch_to_file_list;
4688-
4689- switch (new_mode)
4690- {
4691- case LOCATION_MODE_PATH_BAR:
4692- button_active = FALSE;
4693-
4694- /* The location_entry will disappear when we switch to path bar mode. So,
4695- * we'll focus the file list in that case, to avoid having a window with
4696- * no focused widget.
4697- */
4698- toplevel = get_toplevel (GTK_WIDGET (impl));
4699- switch_to_file_list = FALSE;
4700- if (toplevel)
4701- {
4702- current_focus = gtk_window_get_focus (toplevel);
4703- if (!current_focus || current_focus == impl->location_entry)
4704- switch_to_file_list = TRUE;
4705- }
4706-
4707- location_switch_to_path_bar (impl);
4708-
4709- if (switch_to_file_list)
4710- gtk_widget_grab_focus (impl->browse_files_tree_view);
4711-
4712- break;
4713-
4714- case LOCATION_MODE_FILENAME_ENTRY:
4715- button_active = TRUE;
4716- location_switch_to_filename_entry (impl);
4717- break;
4718-
4719- default:
4720- g_assert_not_reached ();
4721- return;
4722- }
4723-
4724- if (set_button)
4725- {
4726- g_signal_handlers_block_by_func (impl->location_button,
4727- G_CALLBACK (location_button_toggled_cb), impl);
4728-
4729- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (impl->location_button), button_active);
4730-
4731- g_signal_handlers_unblock_by_func (impl->location_button,
4732- G_CALLBACK (location_button_toggled_cb), impl);
4733- }
4734- }
4735-
4736- impl->location_mode = new_mode;
4737-}
4738-
4739-static void
4740-location_toggle_popup_handler (GtkFileChooserDefault *impl)
4741-{
4742- /* If the file entry is not visible, show it.
4743- * If it is visible, turn it off only if it is focused. Otherwise, switch to the entry.
4744- */
4745- if (impl->location_mode == LOCATION_MODE_PATH_BAR)
4746- {
4747- location_mode_set (impl, LOCATION_MODE_FILENAME_ENTRY, TRUE);
4748- }
4749- else if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
4750- {
4751- if (GTK_WIDGET_HAS_FOCUS (impl->location_entry))
4752- {
4753- location_mode_set (impl, LOCATION_MODE_PATH_BAR, TRUE);
4754- }
4755- else
4756- {
4757- gtk_widget_grab_focus (impl->location_entry);
4758- }
4759- }
4760-}
4761-
4762-/* Callback used when one of the location mode buttons is toggled */
4763-static void
4764-location_button_toggled_cb (GtkToggleButton *toggle,
4765- GtkFileChooserDefault *impl)
4766-{
4767- gboolean is_active;
4768- LocationMode new_mode;
4769-
4770- is_active = gtk_toggle_button_get_active (toggle);
4771-
4772- if (is_active)
4773- {
4774- g_assert (impl->location_mode == LOCATION_MODE_PATH_BAR);
4775- new_mode = LOCATION_MODE_FILENAME_ENTRY;
4776- }
4777- else
4778- {
4779- g_assert (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY);
4780- new_mode = LOCATION_MODE_PATH_BAR;
4781- }
4782-
4783- location_mode_set (impl, new_mode, FALSE);
4784-}
4785-
4786-/* Creates a toggle button for the location entry. */
4787-static void
4788-location_button_create (GtkFileChooserDefault *impl)
4789-{
4790- GtkWidget *image;
4791- const char *str;
4792-
4793- image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON);
4794- gtk_widget_show (image);
4795-
4796- impl->location_button = g_object_new (GTK_TYPE_TOGGLE_BUTTON,
4797- "image", image,
4798- NULL);
4799-
4800- g_signal_connect (impl->location_button, "toggled",
4801- G_CALLBACK (location_button_toggled_cb), impl);
4802-
4803- str = _("Type a file name");
4804-
4805- gtk_widget_set_tooltip_text (impl->location_button, str);
4806- atk_object_set_name (gtk_widget_get_accessible (impl->location_button), str);
4807-}
4808-
4809 /* Creates the main hpaned with the widgets shared by Open and Save mode */
4810 static GtkWidget *
4811 browse_widgets_create (GtkFileChooserDefault *impl)
4812 {
4813- GtkWidget *vbox;
4814- GtkWidget *hbox;
4815- GtkWidget *hpaned;
4816 GtkWidget *widget;
4817- GtkSizeGroup *size_group;
4818
4819- /* size group is used by the [+][-] buttons and the filter combo */
4820- size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4821- vbox = gtk_vbox_new (FALSE, 12);
4822+ widget = file_pane_create (impl);
4823
4824- /* Location widgets */
4825- hbox = gtk_hbox_new (FALSE, 12);
4826- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4827- gtk_widget_show (hbox);
4828- impl->browse_path_bar_hbox = hbox;
4829-
4830- location_button_create (impl);
4831- gtk_box_pack_start (GTK_BOX (hbox), impl->location_button, FALSE, FALSE, 0);
4832-
4833- /* Path bar */
4834-
4835- impl->browse_path_bar = create_path_bar (impl);
4836- g_signal_connect (impl->browse_path_bar, "path-clicked", G_CALLBACK (path_bar_clicked), impl);
4837- gtk_widget_show_all (impl->browse_path_bar);
4838- gtk_box_pack_start (GTK_BOX (hbox), impl->browse_path_bar, TRUE, TRUE, 0);
4839-
4840- /* Create Folder */
4841- impl->browse_new_folder_button = gtk_button_new_with_mnemonic (_("Create Fo_lder"));
4842- g_signal_connect (impl->browse_new_folder_button, "clicked",
4843- G_CALLBACK (new_folder_button_clicked), impl);
4844- gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
4845-
4846- /* Box for the location label and entry */
4847-
4848- impl->location_entry_box = gtk_hbox_new (FALSE, 12);
4849- gtk_box_pack_start (GTK_BOX (vbox), impl->location_entry_box, FALSE, FALSE, 0);
4850-
4851- impl->location_label = gtk_label_new_with_mnemonic (_("_Location:"));
4852- gtk_widget_show (impl->location_label);
4853- gtk_box_pack_start (GTK_BOX (impl->location_entry_box), impl->location_label, FALSE, FALSE, 0);
4854-
4855- /* Paned widget */
4856- hpaned = gtk_hpaned_new ();
4857- gtk_widget_show (hpaned);
4858- gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
4859-
4860- widget = shortcuts_pane_create (impl, size_group);
4861- gtk_paned_pack1 (GTK_PANED (hpaned), widget, FALSE, FALSE);
4862- widget = file_pane_create (impl, size_group);
4863- gtk_paned_pack2 (GTK_PANED (hpaned), widget, TRUE, FALSE);
4864-
4865- g_object_unref (size_group);
4866-
4867- return vbox;
4868+ return widget;
4869 }
4870
4871 static GObject*
4872@@ -5284,20 +1610,14 @@
4873
4874 gtk_widget_push_composite_child ();
4875
4876- /* Recent files manager */
4877- recent_manager_update (impl);
4878+ /* Widgets for Save mode */
4879+ impl->save_widgets = save_widgets_create (impl);
4880+ gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0);
4881
4882- /* Shortcuts model */
4883- shortcuts_model_create (impl);
4884-
4885 /* The browse widgets */
4886 impl->browse_widgets = browse_widgets_create (impl);
4887 gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0);
4888
4889- /* Alignment to hold extra widget */
4890- impl->extra_align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
4891- gtk_box_pack_start (GTK_BOX (impl), impl->extra_align, FALSE, FALSE, 0);
4892-
4893 gtk_widget_pop_composite_child ();
4894 update_appearance (impl);
4895
4896@@ -5306,35 +1626,7 @@
4897 return object;
4898 }
4899
4900-/* Sets the extra_widget by packing it in the appropriate place */
4901 static void
4902-set_extra_widget (GtkFileChooserDefault *impl,
4903- GtkWidget *extra_widget)
4904-{
4905- if (extra_widget)
4906- {
4907- g_object_ref (extra_widget);
4908- /* FIXME: is this right ? */
4909- gtk_widget_show (extra_widget);
4910- }
4911-
4912- if (impl->extra_widget)
4913- {
4914- gtk_container_remove (GTK_CONTAINER (impl->extra_align), impl->extra_widget);
4915- g_object_unref (impl->extra_widget);
4916- }
4917-
4918- impl->extra_widget = extra_widget;
4919- if (impl->extra_widget)
4920- {
4921- gtk_container_add (GTK_CONTAINER (impl->extra_align), impl->extra_widget);
4922- gtk_widget_show (impl->extra_align);
4923- }
4924- else
4925- gtk_widget_hide (impl->extra_align);
4926-}
4927-
4928-static void
4929 set_local_only (GtkFileChooserDefault *impl,
4930 gboolean local_only)
4931 {
4932@@ -5342,12 +1634,6 @@
4933 {
4934 impl->local_only = local_only;
4935
4936- if (impl->shortcuts_model && impl->file_system)
4937- {
4938- shortcuts_add_volumes (impl);
4939- shortcuts_add_bookmarks (impl);
4940- }
4941-
4942 if (local_only &&
4943 !gtk_file_system_path_is_local (impl->file_system, impl->current_folder))
4944 {
4945@@ -5374,21 +1660,9 @@
4946 volumes_changed_cb (GtkFileSystem *file_system,
4947 GtkFileChooserDefault *impl)
4948 {
4949- shortcuts_add_volumes (impl);
4950+ /* FIXME -- update the bar */
4951 }
4952
4953-/* Callback used when the set of bookmarks changes in the file system */
4954-static void
4955-bookmarks_changed_cb (GtkFileSystem *file_system,
4956- GtkFileChooserDefault *impl)
4957-{
4958- shortcuts_add_bookmarks (impl);
4959-
4960- bookmarks_check_add_sensitivity (impl);
4961- bookmarks_check_remove_sensitivity (impl);
4962- shortcuts_check_popup_sensitivity (impl);
4963-}
4964-
4965 /* Sets the file chooser to multiple selection mode */
4966 static void
4967 set_select_multiple (GtkFileChooserDefault *impl,
4968@@ -5408,8 +1682,6 @@
4969
4970 impl->select_multiple = select_multiple;
4971 g_object_notify (G_OBJECT (impl), "select-multiple");
4972-
4973- check_preview_change (impl);
4974 }
4975
4976 static void
4977@@ -5422,8 +1694,6 @@
4978 {
4979 g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
4980 impl->volumes_changed_id = 0;
4981- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
4982- impl->bookmarks_changed_id = 0;
4983 g_object_unref (impl->file_system);
4984 }
4985
4986@@ -5459,14 +1729,28 @@
4987 impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
4988 G_CALLBACK (volumes_changed_cb),
4989 impl);
4990- impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed",
4991- G_CALLBACK (bookmarks_changed_cb),
4992- impl);
4993 }
4994
4995 profile_end ("end", NULL);
4996 }
4997
4998+static void
4999+show_new_folder_button (GtkFileChooserDefault *impl)
5000+{
5001+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5002+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) &&
5003+ impl->show_create_folder)
5004+ {
5005+ gtk_widget_show (impl->browse_new_folder_button);
5006+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 0.5, 0.5);
5007+ }
5008+ else
5009+ {
5010+ gtk_widget_hide (impl->browse_new_folder_button);
5011+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 1.0, 0.5);
5012+ }
5013+}
5014+
5015 /* This function is basically a do_all function.
5016 *
5017 * It sets the visibility on all the widgets based on the current state, and
5018@@ -5478,33 +1762,9 @@
5019 if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5020 impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5021 {
5022- const char *text;
5023+ gtk_widget_show (impl->save_widgets);
5024+ gtk_widget_show (impl->browse_widgets);
5025
5026- gtk_widget_hide (impl->location_button);
5027- save_widgets_create (impl);
5028-
5029- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
5030- text = _("Save in _folder:");
5031- else
5032- text = _("Create in _folder:");
5033-
5034- gtk_label_set_text_with_mnemonic (GTK_LABEL (impl->save_folder_label), text);
5035-
5036- if (gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)))
5037- {
5038- gtk_widget_set_sensitive (impl->save_folder_label, FALSE);
5039- gtk_widget_set_sensitive (impl->save_folder_combo, FALSE);
5040- gtk_widget_show (impl->browse_widgets);
5041- }
5042- else
5043- {
5044- gtk_widget_set_sensitive (impl->save_folder_label, TRUE);
5045- gtk_widget_set_sensitive (impl->save_folder_combo, TRUE);
5046- gtk_widget_hide (impl->browse_widgets);
5047- }
5048-
5049- gtk_widget_show (impl->browse_new_folder_button);
5050-
5051 if (impl->select_multiple)
5052 {
5053 g_warning ("Save mode cannot be set in conjunction with multiple selection mode. "
5054@@ -5515,23 +1775,12 @@
5055 else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
5056 impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
5057 {
5058- gtk_widget_show (impl->location_button);
5059- save_widgets_destroy (impl);
5060+ gtk_widget_hide (impl->save_widgets);
5061 gtk_widget_show (impl->browse_widgets);
5062- location_mode_set (impl, impl->location_mode, TRUE);
5063 }
5064
5065- if (impl->location_entry)
5066- _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
5067+ show_new_folder_button (impl);
5068
5069- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
5070- gtk_widget_hide (impl->browse_new_folder_button);
5071- else
5072- gtk_widget_show (impl->browse_new_folder_button);
5073-
5074- /* This *is* needed; we need to redraw the file list because the "sensitivity"
5075- * of files may change depending whether we are in a file or folder-only mode.
5076- */
5077 gtk_widget_queue_draw (impl->browse_files_tree_view);
5078
5079 g_signal_emit_by_name (impl, "default-size-changed");
5080@@ -5556,8 +1805,7 @@
5081 {
5082 gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl));
5083
5084- if ((action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5085- action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5086+ if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5087 && impl->select_multiple)
5088 {
5089 g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but "
5090@@ -5584,29 +1832,10 @@
5091 set_local_only (impl, g_value_get_boolean (value));
5092 break;
5093
5094- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5095- set_preview_widget (impl, g_value_get_object (value));
5096- break;
5097-
5098- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5099- impl->preview_widget_active = g_value_get_boolean (value);
5100- update_preview_widget_visibility (impl);
5101- break;
5102-
5103- case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5104- impl->use_preview_label = g_value_get_boolean (value);
5105- update_preview_widget_visibility (impl);
5106- break;
5107-
5108- case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
5109- set_extra_widget (impl, g_value_get_object (value));
5110- break;
5111-
5112 case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
5113 {
5114 gboolean select_multiple = g_value_get_boolean (value);
5115- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5116- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5117+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5118 && select_multiple)
5119 {
5120 g_warning ("Tried to set the file chooser to multiple selection mode, but this is "
5121@@ -5639,6 +1868,51 @@
5122 }
5123 break;
5124
5125+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER:
5126+ {
5127+ GtkFilePath * path;
5128+ gchar * new_root = g_strdup (g_value_get_string (value));
5129+
5130+ if (!new_root)
5131+ {
5132+ new_root = g_strdup ("/");
5133+ }
5134+
5135+ path = gtk_file_system_filename_to_path (impl->file_system,
5136+ new_root);
5137+ if (change_folder (impl, path, FALSE))
5138+ {
5139+ g_free (impl->root_folder);
5140+ impl->root_folder = new_root;
5141+ }
5142+ else
5143+ {
5144+ g_warning ("Unable to set [%s] as root folder", new_root);
5145+ g_free (new_root);
5146+ }
5147+
5148+ gtk_file_path_free (path);
5149+ }
5150+ break;
5151+
5152+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
5153+ {
5154+ gboolean show = g_value_get_boolean (value);
5155+ if (show != impl->show_create_folder)
5156+ {
5157+ impl->show_create_folder = show;
5158+ show_new_folder_button (impl);
5159+ }
5160+ }
5161+ break;
5162+
5163+ /* These are not supported */
5164+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5165+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5166+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5167+ case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
5168+ break;
5169+
5170 default:
5171 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5172 break;
5173@@ -5667,30 +1941,34 @@
5174 g_value_set_boolean (value, impl->local_only);
5175 break;
5176
5177- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5178- g_value_set_object (value, impl->preview_widget);
5179+ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
5180+ g_value_set_boolean (value, impl->select_multiple);
5181 break;
5182
5183- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5184- g_value_set_boolean (value, impl->preview_widget_active);
5185+ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
5186+ g_value_set_boolean (value, impl->show_hidden);
5187 break;
5188
5189- case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5190- g_value_set_boolean (value, impl->use_preview_label);
5191+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER:
5192+ g_value_set_string (value, impl->root_folder);
5193 break;
5194
5195- case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
5196- g_value_set_object (value, impl->extra_widget);
5197+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
5198+ g_value_set_boolean (value, impl->show_create_folder);
5199 break;
5200
5201- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
5202- g_value_set_boolean (value, impl->select_multiple);
5203+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5204+ g_value_set_object (value, NULL);
5205 break;
5206
5207- case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
5208- g_value_set_boolean (value, impl->show_hidden);
5209+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5210+ g_value_set_boolean (value, FALSE);
5211 break;
5212
5213+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5214+ g_value_set_boolean (value, FALSE);
5215+ break;
5216+
5217 case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
5218 g_value_set_boolean (value, impl->do_overwrite_confirmation);
5219 break;
5220@@ -5723,24 +2001,12 @@
5221 GSList *l;
5222 GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object;
5223
5224- if (impl->extra_widget)
5225- {
5226- g_object_unref (impl->extra_widget);
5227- impl->extra_widget = NULL;
5228- }
5229-
5230 if (impl->volumes_changed_id > 0)
5231 {
5232 g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
5233 impl->volumes_changed_id = 0;
5234 }
5235
5236- if (impl->bookmarks_changed_id > 0)
5237- {
5238- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
5239- impl->bookmarks_changed_id = 0;
5240- }
5241-
5242 pending_select_paths_free (impl);
5243
5244 /* cancel all pending operations */
5245@@ -5766,23 +2032,6 @@
5246 impl->reload_icon_handles = NULL;
5247 }
5248
5249- if (impl->loading_shortcuts)
5250- {
5251- for (l = impl->loading_shortcuts; l; l = l->next)
5252- {
5253- GtkFileSystemHandle *handle =l->data;
5254- gtk_file_system_cancel_operation (handle);
5255- }
5256- g_slist_free (impl->loading_shortcuts);
5257- impl->loading_shortcuts = NULL;
5258- }
5259-
5260- if (impl->file_list_drag_data_received_handle)
5261- {
5262- gtk_file_system_cancel_operation (impl->file_list_drag_data_received_handle);
5263- impl->file_list_drag_data_received_handle = NULL;
5264- }
5265-
5266 if (impl->update_current_folder_handle)
5267 {
5268 gtk_file_system_cancel_operation (impl->update_current_folder_handle);
5269@@ -5807,15 +2056,6 @@
5270 impl->update_from_entry_handle = NULL;
5271 }
5272
5273- if (impl->shortcuts_activate_iter_handle)
5274- {
5275- gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle);
5276- impl->shortcuts_activate_iter_handle = NULL;
5277- }
5278-
5279- search_stop_searching (impl, TRUE);
5280- recent_stop_loading (impl);
5281-
5282 remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl)));
5283
5284 G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object);
5285@@ -5828,12 +2068,7 @@
5286 static void
5287 gtk_file_chooser_default_show_all (GtkWidget *widget)
5288 {
5289- GtkFileChooserDefault *impl = (GtkFileChooserDefault *) widget;
5290-
5291 gtk_widget_show (widget);
5292-
5293- if (impl->extra_widget)
5294- gtk_widget_show_all (impl->extra_widget);
5295 }
5296
5297 /* Handler for GtkWindow::set-focus; this is where we save the last-focused
5298@@ -5894,7 +2129,6 @@
5299 else
5300 impl->icon_size = FALLBACK_ICON_SIZE;
5301
5302- shortcuts_reload_icons (impl);
5303 gtk_widget_queue_resize (impl->browse_files_tree_view);
5304
5305 profile_end ("end", NULL);
5306@@ -5912,8 +2146,8 @@
5307
5308 name = g_param_spec_get_name (pspec);
5309
5310- if (strcmp (name, "gtk-icon-theme-name") == 0 ||
5311- strcmp (name, "gtk-icon-sizes") == 0)
5312+ if (strcmp (name, "gtk-icon-theme-name") == 0
5313+ || strcmp (name, "gtk-icon-sizes") == 0)
5314 change_icon_theme (impl);
5315
5316 profile_end ("end", NULL);
5317@@ -5948,24 +2182,6 @@
5318 }
5319
5320 static void
5321-recent_manager_update (GtkFileChooserDefault *impl)
5322-{
5323- GtkRecentManager *manager;
5324-
5325- profile_start ("start", NULL);
5326-
5327- if (gtk_widget_has_screen (GTK_WIDGET (impl)))
5328- manager = gtk_recent_manager_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
5329- else
5330- manager = gtk_recent_manager_get_default ();
5331-
5332- if (impl->recent_manager != manager)
5333- impl->recent_manager = manager;
5334-
5335- profile_end ("end", NULL);
5336-}
5337-
5338-static void
5339 gtk_file_chooser_default_style_set (GtkWidget *widget,
5340 GtkStyle *previous_style)
5341 {
5342@@ -6005,7 +2221,6 @@
5343
5344 remove_settings_signal (impl, previous_screen);
5345 check_icon_theme (impl);
5346- recent_manager_update (impl);
5347
5348 g_signal_emit_by_name (widget, "default-size-changed");
5349
5350@@ -6032,15 +2247,6 @@
5351
5352 impl->default_width = allocation->width;
5353 impl->default_height = allocation->height;
5354-
5355- if (impl->preview_widget_active &&
5356- impl->preview_widget &&
5357- GTK_WIDGET_DRAWABLE (impl->preview_widget))
5358- impl->default_width -= impl->preview_widget->allocation.width + PREVIEW_HBOX_SPACING;
5359-
5360- if (impl->extra_widget &&
5361- GTK_WIDGET_DRAWABLE (impl->extra_widget))
5362- impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height;
5363 }
5364
5365 static gboolean
5366@@ -6094,23 +2300,18 @@
5367 settings_load (GtkFileChooserDefault *impl)
5368 {
5369 GtkFileChooserSettings *settings;
5370- LocationMode location_mode;
5371 gboolean show_hidden;
5372 gboolean expand_folders;
5373
5374 settings = _gtk_file_chooser_settings_new ();
5375
5376- location_mode = _gtk_file_chooser_settings_get_location_mode (settings);
5377 show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings);
5378 expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings);
5379
5380 g_object_unref (settings);
5381
5382- location_mode_set (impl, location_mode, TRUE);
5383 gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden);
5384 impl->expand_folders = expand_folders;
5385- if (impl->save_expander)
5386- gtk_expander_set_expanded (GTK_EXPANDER (impl->save_expander), expand_folders);
5387 }
5388
5389 static void
5390@@ -6120,7 +2321,6 @@
5391
5392 settings = _gtk_file_chooser_settings_new ();
5393
5394- _gtk_file_chooser_settings_set_location_mode (settings, impl->location_mode);
5395 _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl)));
5396 _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders);
5397
5398@@ -6143,44 +2343,32 @@
5399
5400 GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget);
5401
5402- if (impl->operation_mode == OPERATION_MODE_BROWSE)
5403+ switch (impl->reload_state)
5404 {
5405- switch (impl->reload_state)
5406- {
5407- case RELOAD_EMPTY:
5408- /* The user didn't explicitly give us a folder to
5409- * display, so we'll use the cwd
5410- */
5411- current_working_dir = g_get_current_dir ();
5412- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl),
5413- current_working_dir);
5414- g_free (current_working_dir);
5415- break;
5416-
5417- case RELOAD_HAS_FOLDER:
5418- /* Nothing; we are already loading or loaded, so we
5419- * don't need to reload
5420- */
5421- break;
5422+ case RELOAD_EMPTY:
5423+ /* The user didn't explicitly give us a folder to display, so we'll use the cwd */
5424+ current_working_dir = g_get_current_dir ();
5425+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl), current_working_dir);
5426+ g_free (current_working_dir);
5427+ break;
5428
5429- case RELOAD_WAS_UNMAPPED:
5430- /* Just reload the current folder; else continue
5431- * the pending load.
5432- */
5433- if (impl->current_folder)
5434- {
5435- pending_select_paths_store_selection (impl);
5436- change_folder_and_display_error (impl, impl->current_folder, FALSE);
5437- }
5438- break;
5439+ case RELOAD_HAS_FOLDER:
5440+ /* Nothing; we are already loading or loaded, so we don't need to reload */
5441+ break;
5442
5443- default:
5444- g_assert_not_reached ();
5445- }
5446+ case RELOAD_WAS_UNMAPPED:
5447+ /* Just reload the current folder; else continue the pending load. */
5448+ if (impl->current_folder)
5449+ {
5450+ pending_select_paths_store_selection (impl);
5451+ change_folder_and_display_error (impl, impl->current_folder);
5452+ }
5453+ break;
5454+
5455+ default:
5456+ g_assert_not_reached ();
5457 }
5458
5459- bookmarks_changed_cb (impl->file_system, impl);
5460-
5461 settings_load (impl);
5462
5463 profile_end ("end", NULL);
5464@@ -6244,8 +2432,8 @@
5465
5466 #define COMPARE_DIRECTORIES \
5467 GtkFileChooserDefault *impl = user_data; \
5468- const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \
5469- const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \
5470+ const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \
5471+ const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \
5472 gboolean dir_a, dir_b; \
5473 \
5474 if (info_a) \
5475@@ -6387,6 +2575,8 @@
5476
5477 profile_start ("start", NULL);
5478
5479+ GDK_THREADS_ENTER ();
5480+
5481 impl = GTK_FILE_CHOOSER_DEFAULT (data);
5482 g_assert (impl->load_state == LOAD_PRELOAD);
5483 g_assert (impl->load_timeout_id != 0);
5484@@ -6397,6 +2587,8 @@
5485
5486 load_set_model (impl);
5487
5488+ GDK_THREADS_LEAVE ();
5489+
5490 profile_end ("end", NULL);
5491
5492 return FALSE;
5493@@ -6409,7 +2601,7 @@
5494 g_assert (impl->load_timeout_id == 0);
5495 g_assert (impl->load_state != LOAD_PRELOAD);
5496
5497- impl->load_timeout_id = gdk_threads_add_timeout (MAX_LOADING_TIME, load_timeout_cb, impl);
5498+ impl->load_timeout_id = g_timeout_add (MAX_LOADING_TIME, load_timeout_cb, impl);
5499 impl->load_state = LOAD_PRELOAD;
5500 }
5501
5502@@ -6494,12 +2686,10 @@
5503 gpointer user_data)
5504 {
5505 gboolean have_hidden;
5506- gboolean have_filtered;
5507 GSList *l;
5508 struct ShowAndSelectPathsData *data = user_data;
5509
5510 have_hidden = FALSE;
5511- have_filtered = FALSE;
5512
5513 for (l = data->paths; l; l = l->next)
5514 {
5515@@ -6515,12 +2705,9 @@
5516 if (!have_hidden)
5517 have_hidden = gtk_file_info_get_is_hidden (info);
5518
5519- if (!have_filtered)
5520- have_filtered = !gtk_file_info_get_is_folder (info) && get_is_file_filtered (data->impl, path, info);
5521-
5522 gtk_file_info_free (info);
5523
5524- if (have_hidden && have_filtered)
5525+ if (have_hidden)
5526 break; /* we now have all the information we need */
5527 }
5528 }
5529@@ -6534,9 +2721,6 @@
5530 if (have_hidden)
5531 g_object_set (data->impl, "show-hidden", TRUE, NULL);
5532
5533- if (have_filtered)
5534- set_current_filter (data->impl, NULL);
5535-
5536 for (l = data->paths; l; l = l->next)
5537 {
5538 const GtkFilePath *path;
5539@@ -6644,6 +2828,12 @@
5540 * but rather on behalf of something else like GtkFileChooserButton. In
5541 * that case, the chooser's selection should be what the caller expects,
5542 * as the user can't see that something else got selected. See bug #165264.
5543+ *
5544+ * Also, we don't select the first file if we are not in OPEN mode. Doing
5545+ * so would change the contents of the filename entry for SAVE or
5546+ * CREATE_FOLDER, which is undesired; in SELECT_FOLDER, we don't want to
5547+ * select a *different* folder from the one into which the user just
5548+ * navigated.
5549 */
5550 if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
5551 browse_files_select_first_row (impl);
5552@@ -6690,11 +2880,17 @@
5553 profile_end ("end", NULL);
5554 }
5555
5556-static void
5557-stop_loading_and_clear_list_model (GtkFileChooserDefault *impl)
5558+/* Gets rid of the old list model and creates a new one for the current folder */
5559+static gboolean
5560+set_list_model (GtkFileChooserDefault *impl,
5561+ GError **error)
5562 {
5563+ g_assert (impl->current_folder != NULL);
5564+
5565+ profile_start ("start", NULL);
5566+
5567 load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */
5568-
5569+
5570 if (impl->browse_files_model)
5571 {
5572 g_object_unref (impl->browse_files_model);
5573@@ -6706,21 +2902,7 @@
5574 g_object_unref (impl->sort_model);
5575 impl->sort_model = NULL;
5576 }
5577-
5578- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
5579-}
5580
5581-/* Gets rid of the old list model and creates a new one for the current folder */
5582-static gboolean
5583-set_list_model (GtkFileChooserDefault *impl,
5584- GError **error)
5585-{
5586- g_assert (impl->current_folder != NULL);
5587-
5588- profile_start ("start", NULL);
5589-
5590- stop_loading_and_clear_list_model (impl);
5591-
5592 set_busy_cursor (impl, TRUE);
5593 gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
5594
5595@@ -6794,17 +2976,10 @@
5596 struct update_chooser_entry_selected_foreach_closure closure;
5597 const char *file_part;
5598
5599- /* no need to update the file chooser's entry if there's no entry */
5600- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5601- impl->operation_mode == OPERATION_MODE_RECENT ||
5602- !impl->location_entry)
5603- return;
5604-
5605 if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5606 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
5607- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5608- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
5609- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)))
5610+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5611+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER))
5612 return;
5613
5614 g_assert (impl->location_entry != NULL);
5615@@ -6822,45 +2997,39 @@
5616 else if (closure.num_selected == 1)
5617 {
5618 GtkTreeIter child_iter;
5619-
5620- if (impl->operation_mode == OPERATION_MODE_BROWSE)
5621- {
5622- const GtkFileInfo *info;
5623- gboolean change_entry;
5624+ const GtkFileInfo *info;
5625+ gboolean change_entry;
5626
5627- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
5628- &child_iter,
5629- &closure.first_selected_iter);
5630+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
5631+ &child_iter,
5632+ &closure.first_selected_iter);
5633
5634- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
5635+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
5636
5637- /* If the cursor moved to the row of the newly created folder,
5638- * retrieving info will return NULL.
5639- */
5640- if (!info)
5641- return;
5642+ /* If the cursor moved to the row of the newly created folder,
5643+ * retrieving info will return NULL.
5644+ */
5645+ if (!info)
5646+ return;
5647
5648- g_free (impl->browse_files_last_selected_name);
5649- impl->browse_files_last_selected_name =
5650- g_strdup (gtk_file_info_get_display_name (info));
5651+ g_free (impl->browse_files_last_selected_name);
5652+ impl->browse_files_last_selected_name = g_strdup (gtk_file_info_get_display_name (info));
5653
5654- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
5655- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
5656- change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
5657- else
5658- change_entry = TRUE; /* ... unless we are in one of the folder modes */
5659+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5660+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
5661+ change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
5662+ else
5663+ change_entry = TRUE; /* ... unless we are in one of the folder modes */
5664
5665- if (change_entry)
5666- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
5667- impl->browse_files_last_selected_name);
5668+ if (change_entry)
5669+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->browse_files_last_selected_name);
5670
5671- return;
5672- }
5673+ return;
5674 }
5675 else
5676 {
5677- g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5678- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER));
5679+ g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5680+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER));
5681
5682 /* Multiple selection, so just clear the entry. */
5683
5684@@ -6957,7 +3126,7 @@
5685
5686 /* get parent path and try to change the folder to that */
5687 if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) &&
5688- parent_path != NULL)
5689+ parent_path)
5690 {
5691 gtk_file_path_free (data->path);
5692 data->path = parent_path;
5693@@ -6998,9 +3167,6 @@
5694 if (!gtk_file_info_get_is_folder (info))
5695 goto out;
5696
5697- if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), data->path, data->keep_trail, NULL))
5698- goto out;
5699-
5700 if (impl->current_folder != data->path)
5701 {
5702 if (impl->current_folder)
5703@@ -7011,17 +3177,6 @@
5704 impl->reload_state = RELOAD_HAS_FOLDER;
5705 }
5706
5707- /* Update the widgets that may trigger a folder change themselves. */
5708-
5709- if (!impl->changing_folder)
5710- {
5711- impl->changing_folder = TRUE;
5712-
5713- shortcuts_update_current_folder (impl);
5714-
5715- impl->changing_folder = FALSE;
5716- }
5717-
5718 /* Set the folder on the save entry */
5719
5720 if (impl->location_entry)
5721@@ -7041,13 +3196,7 @@
5722
5723 /* Refresh controls */
5724
5725- shortcuts_find_current_folder (impl);
5726-
5727 g_signal_emit_by_name (impl, "current-folder-changed", 0);
5728-
5729- check_preview_change (impl);
5730- bookmarks_check_add_sensitivity (impl);
5731-
5732 g_signal_emit_by_name (impl, "selection-changed", 0);
5733
5734 out:
5735@@ -7069,18 +3218,6 @@
5736
5737 profile_start ("start", (char *) path);
5738
5739- switch (impl->operation_mode)
5740- {
5741- case OPERATION_MODE_SEARCH:
5742- search_switch_to_browse_mode (impl);
5743- break;
5744- case OPERATION_MODE_RECENT:
5745- recent_switch_to_browse_mode (impl);
5746- break;
5747- case OPERATION_MODE_BROWSE:
5748- break;
5749- }
5750-
5751 g_assert (path != NULL);
5752
5753 if (impl->local_only &&
5754@@ -7123,10 +3260,6 @@
5755 {
5756 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5757
5758- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5759- impl->operation_mode == OPERATION_MODE_RECENT)
5760- return NULL;
5761-
5762 if (impl->reload_state == RELOAD_EMPTY)
5763 {
5764 char *current_working_dir;
5765@@ -7151,8 +3284,8 @@
5766 {
5767 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5768
5769- g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5770- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
5771+ g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5772+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
5773
5774 pending_select_paths_free (impl);
5775 _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name);
5776@@ -7187,14 +3320,10 @@
5777 return FALSE;
5778
5779 if (!parent_path)
5780- return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
5781+ return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
5782
5783- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5784- impl->operation_mode == OPERATION_MODE_RECENT ||
5785- impl->load_state == LOAD_EMPTY)
5786- {
5787- same_path = FALSE;
5788- }
5789+ if (impl->load_state == LOAD_EMPTY)
5790+ same_path = FALSE;
5791 else
5792 {
5793 g_assert (impl->current_folder != NULL);
5794@@ -7289,17 +3418,6 @@
5795 gtk_file_chooser_default_select_all (GtkFileChooser *chooser)
5796 {
5797 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5798-
5799- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5800- impl->operation_mode == OPERATION_MODE_RECENT)
5801- {
5802- GtkTreeSelection *selection;
5803-
5804- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
5805- gtk_tree_selection_select_all (selection);
5806- return;
5807- }
5808-
5809 if (impl->select_multiple)
5810 gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model),
5811 maybe_select, impl);
5812@@ -7340,9 +3458,8 @@
5813
5814 g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5815 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
5816- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5817- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
5818- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY));
5819+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5820+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
5821
5822 chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
5823
5824@@ -7439,14 +3556,7 @@
5825 struct get_paths_closure info;
5826 GtkWindow *toplevel;
5827 GtkWidget *current_focus;
5828- gboolean file_list_seen;
5829
5830- if (impl->operation_mode == OPERATION_MODE_SEARCH)
5831- return search_get_selected_paths (impl);
5832-
5833- if (impl->operation_mode == OPERATION_MODE_RECENT)
5834- return recent_get_selected_paths (impl);
5835-
5836 info.impl = impl;
5837 info.result = NULL;
5838 info.path_from_entry = NULL;
5839@@ -7457,14 +3567,12 @@
5840 else
5841 current_focus = NULL;
5842
5843- file_list_seen = FALSE;
5844 if (current_focus == impl->browse_files_tree_view)
5845 {
5846 GtkTreeSelection *selection;
5847
5848 file_list:
5849
5850- file_list_seen = TRUE;
5851 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
5852 gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info);
5853
5854@@ -7499,12 +3607,8 @@
5855 return NULL;
5856 }
5857
5858- if (info.path_from_entry)
5859- info.result = g_slist_prepend (info.result, info.path_from_entry);
5860- else if (!file_list_seen)
5861- goto file_list;
5862- else
5863- return NULL;
5864+ g_assert (info.path_from_entry != NULL);
5865+ info.result = g_slist_prepend (info.result, info.path_from_entry);
5866 }
5867 else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
5868 goto file_list;
5869@@ -7512,9 +3616,9 @@
5870 goto file_entry;
5871 else
5872 {
5873- /* The focus is on a dialog's action area button or something else */
5874- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5875- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5876+ /* The focus is on a dialog's action area button or something else */
5877+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5878+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5879 goto file_entry;
5880 else
5881 goto file_list;
5882@@ -7533,17 +3637,6 @@
5883 return g_slist_reverse (info.result);
5884 }
5885
5886-static GtkFilePath *
5887-gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser)
5888-{
5889- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5890-
5891- if (impl->preview_path)
5892- return gtk_file_path_copy (impl->preview_path);
5893- else
5894- return NULL;
5895-}
5896-
5897 static GtkFileSystem *
5898 gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser)
5899 {
5900@@ -7558,9 +3651,9 @@
5901 gboolean show)
5902 {
5903 if (show)
5904- gtk_widget_show (impl->filter_combo_hbox);
5905+ gtk_widget_show (impl->filter_combo);
5906 else
5907- gtk_widget_hide (impl->filter_combo_hbox);
5908+ gtk_widget_hide (impl->filter_combo);
5909 }
5910
5911 static void
5912@@ -7588,7 +3683,7 @@
5913 if (!g_slist_find (impl->filters, impl->current_filter))
5914 set_current_filter (impl, filter);
5915
5916- show_filters (impl, TRUE);
5917+ show_filters (impl, g_slist_length (impl->filters) > 1);
5918 }
5919
5920 static void
5921@@ -7627,8 +3722,7 @@
5922
5923 g_object_unref (filter);
5924
5925- if (!impl->filters)
5926- show_filters (impl, FALSE);
5927+ show_filters (impl, g_slist_length (impl->filters) > 1);
5928 }
5929
5930 static GSList *
5931@@ -7639,234 +3733,6 @@
5932 return g_slist_copy (impl->filters);
5933 }
5934
5935-/* Returns the position in the shortcuts tree where the nth specified shortcut would appear */
5936-static int
5937-shortcuts_get_pos_for_shortcut_folder (GtkFileChooserDefault *impl,
5938- int pos)
5939-{
5940- return pos + shortcuts_get_index (impl, SHORTCUTS_SHORTCUTS);
5941-}
5942-
5943-struct AddShortcutData
5944-{
5945- GtkFileChooserDefault *impl;
5946- GtkFilePath *path;
5947-};
5948-
5949-static void
5950-add_shortcut_get_info_cb (GtkFileSystemHandle *handle,
5951- const GtkFileInfo *info,
5952- const GError *error,
5953- gpointer user_data)
5954-{
5955- int pos;
5956- gboolean cancelled = handle->cancelled;
5957- struct AddShortcutData *data = user_data;
5958-
5959- if (!g_slist_find (data->impl->loading_shortcuts, handle))
5960- goto out;
5961-
5962- data->impl->loading_shortcuts = g_slist_remove (data->impl->loading_shortcuts, handle);
5963-
5964- if (cancelled || error || !gtk_file_info_get_is_folder (info))
5965- goto out;
5966-
5967- pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts);
5968-
5969- shortcuts_insert_path (data->impl, pos, SHORTCUT_TYPE_PATH, NULL, data->path, NULL, FALSE, SHORTCUTS_SHORTCUTS);
5970-
5971-out:
5972- g_object_unref (data->impl);
5973- gtk_file_path_free (data->path);
5974- g_free (data);
5975-
5976- g_object_unref (handle);
5977-}
5978-
5979-static gboolean
5980-gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser,
5981- const GtkFilePath *path,
5982- GError **error)
5983-{
5984- GtkFileSystemHandle *handle;
5985- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5986- struct AddShortcutData *data;
5987- GSList *l;
5988- int pos;
5989-
5990- /* Avoid adding duplicates */
5991- pos = shortcut_find_position (impl, path);
5992- if (pos >= 0 && pos < shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR))
5993- {
5994- gchar *uri;
5995-
5996- uri = gtk_file_system_path_to_uri (impl->file_system, path);
5997- /* translators, "Shortcut" means "Bookmark" here */
5998- g_set_error (error,
5999- GTK_FILE_CHOOSER_ERROR,
6000- GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
6001- _("Shortcut %s already exists"),
6002- uri);
6003- g_free (uri);
6004-
6005- return FALSE;
6006- }
6007-
6008- for (l = impl->loading_shortcuts; l; l = l->next)
6009- {
6010- GtkFileSystemHandle *h = l->data;
6011- GtkFilePath *p;
6012-
6013- p = g_object_get_data (G_OBJECT (h), "add-shortcut-path-key");
6014- if (p && !gtk_file_path_compare (path, p))
6015- {
6016- gchar *uri;
6017-
6018- uri = gtk_file_system_path_to_uri (impl->file_system, path);
6019- g_set_error (error,
6020- GTK_FILE_CHOOSER_ERROR,
6021- GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
6022- _("Shortcut %s already exists"),
6023- uri);
6024- g_free (uri);
6025-
6026- return FALSE;
6027- }
6028- }
6029-
6030- data = g_new0 (struct AddShortcutData, 1);
6031- data->impl = g_object_ref (impl);
6032- data->path = gtk_file_path_copy (path);
6033-
6034- handle = gtk_file_system_get_info (impl->file_system, path,
6035- GTK_FILE_INFO_IS_FOLDER,
6036- add_shortcut_get_info_cb, data);
6037-
6038- if (!handle)
6039- return FALSE;
6040-
6041- impl->loading_shortcuts = g_slist_append (impl->loading_shortcuts, handle);
6042- g_object_set_data (G_OBJECT (handle), "add-shortcut-path-key", data->path);
6043-
6044- return TRUE;
6045-}
6046-
6047-static gboolean
6048-gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser,
6049- const GtkFilePath *path,
6050- GError **error)
6051-{
6052- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
6053- int pos;
6054- GtkTreeIter iter;
6055- GSList *l;
6056- char *uri;
6057- int i;
6058-
6059- for (l = impl->loading_shortcuts; l; l = l->next)
6060- {
6061- GtkFileSystemHandle *h = l->data;
6062- GtkFilePath *p;
6063-
6064- p = g_object_get_data (G_OBJECT (h), "add-shortcut-path-key");
6065- if (p && !gtk_file_path_compare (path, p))
6066- {
6067- impl->loading_shortcuts = g_slist_remove (impl->loading_shortcuts, h);
6068- gtk_file_system_cancel_operation (h);
6069- return TRUE;
6070- }
6071- }
6072-
6073- if (impl->num_shortcuts == 0)
6074- goto out;
6075-
6076- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
6077- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
6078- g_assert_not_reached ();
6079-
6080- for (i = 0; i < impl->num_shortcuts; i++)
6081- {
6082- gpointer col_data;
6083- ShortcutType shortcut_type;
6084- GtkFilePath *shortcut;
6085-
6086- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
6087- SHORTCUTS_COL_DATA, &col_data,
6088- SHORTCUTS_COL_TYPE, &shortcut_type,
6089- -1);
6090- g_assert (col_data != NULL);
6091- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
6092-
6093- shortcut = col_data;
6094- if (gtk_file_path_compare (shortcut, path) == 0)
6095- {
6096- shortcuts_remove_rows (impl, pos + i, 1);
6097- impl->num_shortcuts--;
6098- return TRUE;
6099- }
6100-
6101- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
6102- g_assert_not_reached ();
6103- }
6104-
6105- out:
6106-
6107- uri = gtk_file_system_path_to_uri (impl->file_system, path);
6108- /* translators, "Shortcut" means "Bookmark" here */
6109- g_set_error (error,
6110- GTK_FILE_CHOOSER_ERROR,
6111- GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
6112- _("Shortcut %s does not exist"),
6113- uri);
6114- g_free (uri);
6115-
6116- return FALSE;
6117-}
6118-
6119-static GSList *
6120-gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
6121-{
6122- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
6123- int pos;
6124- GtkTreeIter iter;
6125- int i;
6126- GSList *list;
6127-
6128- if (impl->num_shortcuts == 0)
6129- return NULL;
6130-
6131- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
6132- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
6133- g_assert_not_reached ();
6134-
6135- list = NULL;
6136-
6137- for (i = 0; i < impl->num_shortcuts; i++)
6138- {
6139- gpointer col_data;
6140- ShortcutType shortcut_type;
6141- GtkFilePath *shortcut;
6142-
6143- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
6144- SHORTCUTS_COL_DATA, &col_data,
6145- SHORTCUTS_COL_TYPE, &shortcut_type,
6146- -1);
6147- g_assert (col_data != NULL);
6148- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
6149-
6150- shortcut = col_data;
6151- list = g_slist_prepend (list, gtk_file_path_copy (shortcut));
6152-
6153- if (i != impl->num_shortcuts - 1)
6154- {
6155- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
6156- g_assert_not_reached ();
6157- }
6158- }
6159-
6160- return g_slist_reverse (list);
6161-}
6162-
6163 /* Guesses a size based upon font sizes */
6164 static void
6165 find_good_size_from_style (GtkWidget *widget,
6166@@ -7911,25 +3777,9 @@
6167 gint *default_height)
6168 {
6169 GtkFileChooserDefault *impl;
6170- GtkRequisition req;
6171
6172 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
6173 find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height);
6174-
6175- if (impl->preview_widget_active &&
6176- impl->preview_widget &&
6177- GTK_WIDGET_VISIBLE (impl->preview_widget))
6178- {
6179- gtk_widget_size_request (impl->preview_box, &req);
6180- *default_width += PREVIEW_HBOX_SPACING + req.width;
6181- }
6182-
6183- if (impl->extra_widget &&
6184- GTK_WIDGET_VISIBLE (impl->extra_widget))
6185- {
6186- gtk_widget_size_request (impl->extra_align, &req);
6187- *default_height += GTK_BOX (chooser_embed)->spacing + req.height;
6188- }
6189 }
6190
6191 static gboolean
6192@@ -7940,8 +3790,7 @@
6193 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
6194
6195 return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6196- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
6197- gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)));
6198+ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
6199 }
6200
6201 struct switch_folder_closure {
6202@@ -7988,7 +3837,7 @@
6203
6204 g_assert (closure.path && closure.num_selected == 1);
6205
6206- change_folder_and_display_error (impl, closure.path, FALSE);
6207+ change_folder_and_display_error (impl, closure.path);
6208 }
6209
6210 /* Gets the GtkFileInfo for the selected row in the file list; assumes single
6211@@ -8187,24 +4036,7 @@
6212 }
6213 }
6214
6215-/* Gives the focus to the browse tree view only if it is visible */
6216 static void
6217-focus_browse_tree_view_if_possible (GtkFileChooserDefault *impl)
6218-{
6219- gboolean do_focus;
6220-
6221- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
6222- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6223- && !gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)))
6224- do_focus = FALSE;
6225- else
6226- do_focus = TRUE;
6227-
6228- if (do_focus)
6229- gtk_widget_grab_focus (impl->browse_files_tree_view);
6230-}
6231-
6232-static void
6233 action_create_folder_cb (GtkFileSystemHandle *handle,
6234 const GtkFilePath *path,
6235 const GError *error,
6236@@ -8300,7 +4132,7 @@
6237 else
6238 {
6239 /* This will display an error, which is what we want */
6240- change_folder_and_display_error (data->impl, data->parent_path, FALSE);
6241+ change_folder_and_display_error (data->impl, data->parent_path);
6242 }
6243
6244 out:
6245@@ -8378,51 +4210,7 @@
6246 g_object_unref (handle);
6247 }
6248
6249-static void
6250-paste_text_received (GtkClipboard *clipboard,
6251- const gchar *text,
6252- GtkFileChooserDefault *impl)
6253-{
6254- GtkFilePath *path;
6255
6256- if (!text)
6257- return;
6258-
6259- path = gtk_file_system_uri_to_path (impl->file_system, text);
6260- if (!path)
6261- {
6262- if (!g_path_is_absolute (text))
6263- {
6264- location_popup_handler (impl, text);
6265- return;
6266- }
6267-
6268- path = gtk_file_system_filename_to_path (impl->file_system, text);
6269- if (!path)
6270- {
6271- location_popup_handler (impl, text);
6272- return;
6273- }
6274- }
6275-
6276- if (!gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (impl), path, NULL))
6277- location_popup_handler (impl, text);
6278-
6279- gtk_file_path_free (path);
6280-}
6281-
6282-/* Handler for the "location-popup-on-paste" keybinding signal */
6283-static void
6284-location_popup_on_paste_handler (GtkFileChooserDefault *impl)
6285-{
6286- GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (impl),
6287- GDK_SELECTION_CLIPBOARD);
6288- gtk_clipboard_request_text (clipboard,
6289- (GtkClipboardTextReceivedFunc) paste_text_received,
6290- impl);
6291-}
6292-
6293-
6294 /* Implementation for GtkFileChooserEmbed::should_respond() */
6295 static gboolean
6296 gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
6297@@ -8469,12 +4257,6 @@
6298
6299 g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
6300
6301- if (impl->operation_mode == OPERATION_MODE_SEARCH)
6302- return search_should_respond (impl);
6303-
6304- if (impl->operation_mode == OPERATION_MODE_RECENT)
6305- return recent_should_respond (impl);
6306-
6307 selection_check (impl, &num_selected, &all_files, &all_folders);
6308
6309 if (num_selected > 2)
6310@@ -8533,9 +4315,8 @@
6311
6312 g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
6313 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
6314- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6315- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6316- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY));
6317+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6318+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
6319
6320 entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
6321 check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
6322@@ -8548,14 +4329,14 @@
6323 error = NULL;
6324 if (is_folder)
6325 {
6326- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6327- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
6328+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6329+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
6330 {
6331- change_folder_and_display_error (impl, path, TRUE);
6332+ change_folder_and_display_error (impl, path);
6333 retval = FALSE;
6334 }
6335- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
6336- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6337+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
6338+ || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6339 {
6340 /* The folder already exists, so we do not need to create it.
6341 * Just respond to terminate the dialog.
6342@@ -8598,37 +4379,13 @@
6343 gtk_file_path_free (path);
6344 return retval;
6345 }
6346- else if (impl->toplevel_last_focus_widget == impl->browse_shortcuts_tree_view)
6347- {
6348- /* The focus is on a dialog's action area button, *and* the widget that
6349- * was focused immediately before it is the shortcuts list. Switch to the
6350- * selected shortcut and tell the caller not to respond.
6351- */
6352- GtkTreeIter iter;
6353-
6354- if (shortcuts_get_selected (impl, &iter))
6355- {
6356- shortcuts_activate_iter (impl, &iter);
6357-
6358- focus_browse_tree_view_if_possible (impl);
6359- }
6360- else
6361- goto file_list;
6362-
6363- return FALSE;
6364- }
6365 else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
6366 {
6367 /* The focus is on a dialog's action area button, *and* the widget that
6368- * was focused immediately before it is the file list.
6369+ * was focused immediately before it is the file list.
6370 */
6371 goto file_list;
6372 }
6373- else if (impl->operation_mode == OPERATION_MODE_SEARCH && impl->toplevel_last_focus_widget == impl->search_entry)
6374- {
6375- search_entry_activate_cb (GTK_ENTRY (impl->search_entry), impl);
6376- return FALSE;
6377- }
6378 else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry)
6379 {
6380 /* The focus is on a dialog's action area button, *and* the widget that
6381@@ -8657,17 +4414,16 @@
6382
6383 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
6384
6385- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6386- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6387+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6388+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6389 {
6390- if (impl->location_mode == LOCATION_MODE_PATH_BAR)
6391 widget = impl->browse_files_tree_view;
6392- else
6393- widget = impl->location_entry;
6394 }
6395- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
6396- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6397- widget = impl->location_entry;
6398+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
6399+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6400+ {
6401+ widget = impl->location_entry;
6402+ }
6403 else
6404 {
6405 g_assert_not_reached ();
6406@@ -8678,1475 +4434,7 @@
6407 gtk_widget_grab_focus (widget);
6408 }
6409
6410-/* Callback used from gtk_tree_selection_selected_foreach(); gets the selected GtkFilePaths */
6411 static void
6412-search_selected_foreach_get_path_cb (GtkTreeModel *model,
6413- GtkTreePath *path,
6414- GtkTreeIter *iter,
6415- gpointer data)
6416-{
6417- GSList **list;
6418- const GtkFilePath *file_path;
6419- GtkFilePath *file_path_copy;
6420-
6421- list = data;
6422-
6423- gtk_tree_model_get (model, iter, SEARCH_MODEL_COL_PATH, &file_path, -1);
6424- file_path_copy = gtk_file_path_copy (file_path);
6425- *list = g_slist_prepend (*list, file_path_copy);
6426-}
6427-
6428-/* Constructs a list of the selected paths in search mode */
6429-static GSList *
6430-search_get_selected_paths (GtkFileChooserDefault *impl)
6431-{
6432- GSList *result;
6433- GtkTreeSelection *selection;
6434-
6435- result = NULL;
6436-
6437- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
6438- gtk_tree_selection_selected_foreach (selection, search_selected_foreach_get_path_cb, &result);
6439- result = g_slist_reverse (result);
6440-
6441- return result;
6442-}
6443-
6444-/* Called from ::should_respond(). We return whether there are selected files
6445- * in the search list.
6446- */
6447-static gboolean
6448-search_should_respond (GtkFileChooserDefault *impl)
6449-{
6450- GtkTreeSelection *selection;
6451-
6452- g_assert (impl->operation_mode == OPERATION_MODE_SEARCH);
6453-
6454- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
6455- return (gtk_tree_selection_count_selected_rows (selection) != 0);
6456-}
6457-
6458-struct SearchHitInsertRequest
6459-{
6460- GtkFileChooserDefault *impl;
6461- GtkFilePath *path;
6462- GtkTreeRowReference *row_ref;
6463-};
6464-
6465-static void
6466-search_hit_get_info_cb (GtkFileSystemHandle *handle,
6467- const GtkFileInfo *info,
6468- const GError *error,
6469- gpointer data)
6470-{
6471- gboolean cancelled = handle->cancelled;
6472- GdkPixbuf *pixbuf = NULL;
6473- GtkTreePath *path;
6474- GtkTreeIter iter;
6475- GtkFileSystemHandle *model_handle;
6476- gboolean is_folder = FALSE;
6477- char *mime_type;
6478- char *display_name;
6479- struct SearchHitInsertRequest *request = data;
6480-
6481- if (!request->impl->search_model)
6482- goto out;
6483-
6484- path = gtk_tree_row_reference_get_path (request->row_ref);
6485- if (!path)
6486- goto out;
6487-
6488- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->search_model),
6489- &iter, path);
6490- gtk_tree_path_free (path);
6491-
6492- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->search_model), &iter,
6493- SEARCH_MODEL_COL_HANDLE, &model_handle,
6494- -1);
6495- if (handle != model_handle)
6496- goto out;
6497-
6498- /* set the handle to NULL in the model */
6499- gtk_list_store_set (request->impl->search_model, &iter,
6500- SEARCH_MODEL_COL_HANDLE, NULL,
6501- -1);
6502-
6503- if (cancelled)
6504- goto out;
6505-
6506- if (!info)
6507- {
6508- gtk_list_store_remove (request->impl->search_model, &iter);
6509- goto out;
6510- }
6511-
6512- display_name = g_strdup (gtk_file_info_get_display_name (info));
6513- mime_type = g_strdup (gtk_file_info_get_mime_type (info));
6514- is_folder = gtk_file_info_get_is_folder (info);
6515- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (request->impl),
6516- request->impl->icon_size, NULL);
6517-
6518- gtk_list_store_set (request->impl->search_model, &iter,
6519- SEARCH_MODEL_COL_PIXBUF, pixbuf,
6520- SEARCH_MODEL_COL_DISPLAY_NAME, display_name,
6521- SEARCH_MODEL_COL_MIME_TYPE, mime_type,
6522- SEARCH_MODEL_COL_IS_FOLDER, is_folder,
6523- -1);
6524-
6525- if (pixbuf)
6526- g_object_unref (pixbuf);
6527-
6528-out:
6529- g_object_unref (request->impl);
6530- gtk_file_path_free (request->path);
6531- gtk_tree_row_reference_free (request->row_ref);
6532- g_free (request);
6533-
6534- g_object_unref (handle);
6535-}
6536-
6537-/* Adds one hit from the search engine to the search_model */
6538-static void
6539-search_add_hit (GtkFileChooserDefault *impl,
6540- gchar *uri)
6541-{
6542- GtkFilePath *path;
6543- char *filename;
6544- char *tmp;
6545- char *collation_key;
6546- struct stat statbuf;
6547- struct stat *statbuf_copy;
6548- GtkTreeIter iter;
6549- GtkTreePath *p;
6550- GtkFileSystemHandle *handle;
6551- struct SearchHitInsertRequest *request;
6552-
6553- path = gtk_file_system_uri_to_path (impl->file_system, uri);
6554- if (!path)
6555- return;
6556-
6557- filename = gtk_file_system_path_to_filename (impl->file_system, path);
6558- if (!filename)
6559- {
6560- gtk_file_path_free (path);
6561- return;
6562- }
6563-
6564- if (stat (filename, &statbuf) != 0)
6565- {
6566- gtk_file_path_free (path);
6567- g_free (filename);
6568- return;
6569- }
6570-
6571- statbuf_copy = g_new (struct stat, 1);
6572- *statbuf_copy = statbuf;
6573-
6574- tmp = g_filename_display_name (filename);
6575- collation_key = g_utf8_collate_key_for_filename (tmp, -1);
6576- g_free (tmp);
6577-
6578- request = g_new0 (struct SearchHitInsertRequest, 1);
6579- request->impl = g_object_ref (impl);
6580- request->path = gtk_file_path_copy (path);
6581-
6582- gtk_list_store_append (impl->search_model, &iter);
6583- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->search_model), &iter);
6584-
6585- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->search_model), p);
6586- gtk_tree_path_free (p);
6587-
6588- handle = gtk_file_system_get_info (impl->file_system, path,
6589- GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_ICON | GTK_FILE_INFO_MIME_TYPE | GTK_FILE_INFO_DISPLAY_NAME,
6590- search_hit_get_info_cb,
6591- request);
6592-
6593- gtk_list_store_set (impl->search_model, &iter,
6594- SEARCH_MODEL_COL_PATH, path,
6595- SEARCH_MODEL_COL_COLLATION_KEY, collation_key,
6596- SEARCH_MODEL_COL_STAT, statbuf_copy,
6597- SEARCH_MODEL_COL_HANDLE, handle,
6598- -1);
6599-}
6600-
6601-/* Callback used from GtkSearchEngine when we get new hits */
6602-static void
6603-search_engine_hits_added_cb (GtkSearchEngine *engine,
6604- GList *hits,
6605- gpointer data)
6606-{
6607- GtkFileChooserDefault *impl;
6608- GList *l;
6609-
6610- impl = GTK_FILE_CHOOSER_DEFAULT (data);
6611-
6612- for (l = hits; l; l = l->next)
6613- search_add_hit (impl, (gchar*)l->data);
6614-}
6615-
6616-/* Callback used from GtkSearchEngine when the query is done running */
6617-static void
6618-search_engine_finished_cb (GtkSearchEngine *engine,
6619- gpointer data)
6620-{
6621- GtkFileChooserDefault *impl;
6622-
6623- impl = GTK_FILE_CHOOSER_DEFAULT (data);
6624-
6625-#if 0
6626- /* EB: setting the model here will avoid loads of row events,
6627- * but it'll make the search look like blocked.
6628- */
6629- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
6630- GTK_TREE_MODEL (impl->search_model_filter));
6631-#endif
6632-
6633- /* FMQ: if search was empty, say that we got no hits */
6634- set_busy_cursor (impl, FALSE);
6635-}
6636-
6637-/* Displays a generic error when we cannot create a GtkSearchEngine.
6638- * It would be better if _gtk_search_engine_new() gave us a GError
6639- * with a better message, but it doesn't do that right now.
6640- */
6641-static void
6642-search_error_could_not_create_client (GtkFileChooserDefault *impl)
6643-{
6644- error_message (impl,
6645- _("Could not start the search process"),
6646- _("The program was not able to create a connection to the indexer "
6647- "daemon. Please make sure it is running."));
6648-}
6649-
6650-static void
6651-search_engine_error_cb (GtkSearchEngine *engine,
6652- const gchar *message,
6653- gpointer data)
6654-{
6655- GtkFileChooserDefault *impl;
6656-
6657- impl = GTK_FILE_CHOOSER_DEFAULT (data);
6658-
6659- search_stop_searching (impl, TRUE);
6660- error_message (impl, _("Could not send the search request"), message);
6661-
6662- set_busy_cursor (impl, FALSE);
6663-}
6664-
6665-/* Frees the data in the search_model */
6666-static void
6667-search_clear_model (GtkFileChooserDefault *impl,
6668- gboolean remove_from_treeview)
6669-{
6670- GtkTreeModel *model;
6671- GtkTreeIter iter;
6672-
6673- if (!impl->search_model)
6674- return;
6675-
6676- model = GTK_TREE_MODEL (impl->search_model);
6677-
6678- if (gtk_tree_model_get_iter_first (model, &iter))
6679- do
6680- {
6681- GtkFilePath *path;
6682- gchar *display_name;
6683- gchar *collation_key;
6684- struct stat *statbuf;
6685- GtkFileSystemHandle *handle;
6686-
6687- gtk_tree_model_get (model, &iter,
6688- SEARCH_MODEL_COL_PATH, &path,
6689- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
6690- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key,
6691- SEARCH_MODEL_COL_STAT, &statbuf,
6692- SEARCH_MODEL_COL_HANDLE, &handle,
6693- -1);
6694-
6695- if (handle)
6696- gtk_file_system_cancel_operation (handle);
6697-
6698- gtk_file_path_free (path);
6699- g_free (display_name);
6700- g_free (collation_key);
6701- g_free (statbuf);
6702- }
6703- while (gtk_tree_model_iter_next (model, &iter));
6704-
6705- g_object_unref (impl->search_model);
6706- impl->search_model = NULL;
6707-
6708- g_object_unref (impl->search_model_filter);
6709- impl->search_model_filter = NULL;
6710-
6711- g_object_unref (impl->search_model_sort);
6712- impl->search_model_sort = NULL;
6713-
6714- if (remove_from_treeview)
6715- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
6716-}
6717-
6718-/* Stops any ongoing searches; does not touch the search_model */
6719-static void
6720-search_stop_searching (GtkFileChooserDefault *impl,
6721- gboolean remove_query)
6722-{
6723- if (remove_query && impl->search_query)
6724- {
6725- g_object_unref (impl->search_query);
6726- impl->search_query = NULL;
6727- }
6728-
6729- if (impl->search_engine)
6730- {
6731- _gtk_search_engine_stop (impl->search_engine);
6732-
6733- g_object_unref (impl->search_engine);
6734- impl->search_engine = NULL;
6735- }
6736-}
6737-
6738-/* Stops any pending searches, clears the file list, and switches back to OPERATION_MODE_BROWSE */
6739-static void
6740-search_switch_to_browse_mode (GtkFileChooserDefault *impl)
6741-{
6742- g_assert (impl->operation_mode != OPERATION_MODE_BROWSE);
6743-
6744- search_stop_searching (impl, FALSE);
6745- search_clear_model (impl, TRUE);
6746-
6747- gtk_widget_destroy (impl->search_hbox);
6748- impl->search_hbox = NULL;
6749- impl->search_entry = NULL;
6750-
6751- gtk_widget_show (impl->browse_path_bar);
6752- gtk_widget_show (impl->browse_new_folder_button);
6753-
6754- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6755- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6756- {
6757- gtk_widget_show (impl->location_button);
6758-
6759- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
6760- gtk_widget_show (impl->location_entry_box);
6761- }
6762-
6763- impl->operation_mode = OPERATION_MODE_BROWSE;
6764-
6765- file_list_set_sort_column_ids (impl);
6766-}
6767-
6768-/* Sort callback from the path column */
6769-static gint
6770-search_column_path_sort_func (GtkTreeModel *model,
6771- GtkTreeIter *a,
6772- GtkTreeIter *b,
6773- gpointer user_data)
6774-{
6775- GtkFileChooserDefault *impl = user_data;
6776- GtkTreeIter child_a, child_b;
6777- const char *collation_key_a, *collation_key_b;
6778- gboolean is_folder_a, is_folder_b;
6779-
6780- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
6781- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
6782-
6783- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a,
6784- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a,
6785- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_a,
6786- -1);
6787- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_b,
6788- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b,
6789- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_b,
6790- -1);
6791-
6792- if (!collation_key_a)
6793- return 1;
6794-
6795- if (!collation_key_b)
6796- return -1;
6797-
6798- /* always show folders first */
6799- if (is_folder_a != is_folder_b)
6800- return is_folder_a ? 1 : -1;
6801-
6802- return strcmp (collation_key_a, collation_key_b);
6803-}
6804-
6805-/* Sort callback from the modification time column */
6806-static gint
6807-search_column_mtime_sort_func (GtkTreeModel *model,
6808- GtkTreeIter *a,
6809- GtkTreeIter *b,
6810- gpointer user_data)
6811-{
6812- GtkFileChooserDefault *impl = user_data;
6813- GtkTreeIter child_a, child_b;
6814- const struct stat *statbuf_a, *statbuf_b;
6815- gboolean is_folder_a, is_folder_b;
6816-
6817- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
6818- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
6819-
6820- /* Note that although we store a whole struct stat in the model, we only
6821- * compare the mtime here. If we add another column relative to a struct stat
6822- * (e.g. a file size column), we'll want another sort callback similar to this
6823- * one as well.
6824- */
6825- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a,
6826- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a,
6827- SEARCH_MODEL_COL_STAT, &statbuf_a,
6828- -1);
6829- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_b,
6830- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b,
6831- SEARCH_MODEL_COL_STAT, &statbuf_b,
6832- -1);
6833-
6834- if (!statbuf_a)
6835- return 1;
6836-
6837- if (!statbuf_b)
6838- return -1;
6839-
6840- if (is_folder_a != is_folder_b)
6841- return is_folder_a ? 1 : -1;
6842-
6843- if (statbuf_a->st_mtime < statbuf_b->st_mtime)
6844- return -1;
6845- else if (statbuf_a->st_mtime > statbuf_b->st_mtime)
6846- return 1;
6847- else
6848- return 0;
6849-}
6850-
6851-static gboolean
6852-search_get_is_filtered (GtkFileChooserDefault *impl,
6853- const GtkFilePath *path,
6854- const gchar *display_name,
6855- const gchar *mime_type)
6856-{
6857- GtkFileFilterInfo filter_info;
6858- GtkFileFilterFlags needed;
6859- gboolean result;
6860-
6861- if (!impl->current_filter)
6862- return FALSE;
6863-
6864- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
6865- needed = gtk_file_filter_get_needed (impl->current_filter);
6866-
6867- filter_info.display_name = display_name;
6868- filter_info.mime_type = mime_type;
6869-
6870- if (needed & GTK_FILE_FILTER_FILENAME)
6871- {
6872- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
6873- if (filter_info.filename)
6874- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
6875- }
6876- else
6877- filter_info.filename = NULL;
6878-
6879- if (needed & GTK_FILE_FILTER_URI)
6880- {
6881- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
6882- if (filter_info.uri)
6883- filter_info.contains |= GTK_FILE_FILTER_URI;
6884- }
6885- else
6886- filter_info.uri = NULL;
6887-
6888- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
6889-
6890- if (filter_info.filename)
6891- g_free ((gchar *) filter_info.filename);
6892- if (filter_info.uri)
6893- g_free ((gchar *) filter_info.uri);
6894-
6895- return !result;
6896-
6897-}
6898-
6899-/* Visibility function for the recent filter model */
6900-static gboolean
6901-search_model_visible_func (GtkTreeModel *model,
6902- GtkTreeIter *iter,
6903- gpointer user_data)
6904-{
6905- GtkFileChooserDefault *impl = user_data;
6906- GtkFilePath *file_path;
6907- gchar *display_name, *mime_type;
6908- gboolean is_folder;
6909-
6910- if (!impl->current_filter)
6911- return TRUE;
6912-
6913- gtk_tree_model_get (model, iter,
6914- SEARCH_MODEL_COL_PATH, &file_path,
6915- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
6916- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
6917- SEARCH_MODEL_COL_MIME_TYPE, &mime_type,
6918- -1);
6919-
6920- if (!display_name)
6921- return TRUE;
6922-
6923- if (is_folder)
6924- return TRUE;
6925-
6926- return !search_get_is_filtered (impl, file_path, display_name, mime_type);
6927-}
6928-
6929-/* Creates the search_model and puts it in the tree view */
6930-static void
6931-search_setup_model (GtkFileChooserDefault *impl)
6932-{
6933- g_assert (impl->search_model == NULL);
6934- g_assert (impl->search_model_filter == NULL);
6935- g_assert (impl->search_model_sort == NULL);
6936-
6937- /* We store these columns in the search model:
6938- *
6939- * SEARCH_MODEL_COL_PATH - a GtkFilePath for the hit's URI, stored as a
6940- * pointer not as a GTK_TYPE_FILE_PATH
6941- * SEARCH_MODEL_COL_DISPLAY_NAME - a string with the display name, stored
6942- * as a pointer not as a G_TYPE_STRING
6943- * SEARCH_MODEL_COL_COLLATION_KEY - collation key for the filename, stored
6944- * as a pointer not as a G_TYPE_STRING
6945- * SEARCH_MODEL_COL_STAT - pointer to a struct stat
6946- * SEARCH_MODEL_COL_HANDLE - handle used when getting the hit's info
6947- * SEARCH_MODEL_COL_PIXBUF - GdkPixbuf for the hit's icon
6948- * SEARCH_MODEL_COL_MIME_TYPE - a string with the hit's MIME type
6949- * SEARCH_MODEL_COL_IS_FOLDER - a boolean flag for folders
6950- *
6951- * Keep this in sync with the enumeration defined near the beginning
6952- * of this file.
6953- */
6954- impl->search_model = gtk_list_store_new (SEARCH_MODEL_COL_NUM_COLUMNS,
6955- G_TYPE_POINTER,
6956- G_TYPE_POINTER,
6957- G_TYPE_POINTER,
6958- G_TYPE_POINTER,
6959- G_TYPE_POINTER,
6960- GDK_TYPE_PIXBUF,
6961- G_TYPE_POINTER,
6962- G_TYPE_BOOLEAN);
6963-
6964- impl->search_model_filter =
6965- GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL));
6966- gtk_tree_model_filter_set_visible_func (impl->search_model_filter,
6967- search_model_visible_func,
6968- impl, NULL);
6969-
6970- impl->search_model_sort =
6971- GTK_TREE_MODEL_SORT (search_model_sort_new (impl, GTK_TREE_MODEL (impl->search_model_filter)));
6972- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort),
6973- SEARCH_MODEL_COL_PATH,
6974- search_column_path_sort_func,
6975- impl, NULL);
6976- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort),
6977- SEARCH_MODEL_COL_STAT,
6978- search_column_mtime_sort_func,
6979- impl, NULL);
6980- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->search_model_sort),
6981- SEARCH_MODEL_COL_STAT,
6982- GTK_SORT_DESCENDING);
6983-
6984- /* EB: setting the model here will make the hits list update feel
6985- * more "alive" than setting the model at the end of the search
6986- * run
6987- */
6988- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
6989- GTK_TREE_MODEL (impl->search_model_sort));
6990-}
6991-
6992-static void
6993-search_get_valid_child_iter (GtkFileChooserDefault *impl,
6994- GtkTreeIter *child_iter,
6995- GtkTreeIter *iter)
6996-{
6997- GtkTreeIter middle;
6998-
6999- if (!impl->search_model)
7000- return;
7001-
7002- if (!impl->search_model_filter || !impl->search_model_sort)
7003- return;
7004-
7005- /* pass 1: get the iterator in the filter model */
7006- gtk_tree_model_sort_convert_iter_to_child_iter (impl->search_model_sort,
7007- &middle, iter);
7008-
7009- /* pass 2: get the iterator in the real model */
7010- gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter,
7011- child_iter, &middle);
7012-}
7013-
7014-/* Creates a new query with the specified text and launches it */
7015-static void
7016-search_start_query (GtkFileChooserDefault *impl,
7017- const gchar *query_text)
7018-{
7019- search_stop_searching (impl, FALSE);
7020- search_clear_model (impl, TRUE);
7021- search_setup_model (impl);
7022- set_busy_cursor (impl, TRUE);
7023-
7024- if (impl->search_engine == NULL)
7025- impl->search_engine = _gtk_search_engine_new ();
7026-
7027- if (!impl->search_engine)
7028- {
7029- set_busy_cursor (impl, FALSE);
7030- search_error_could_not_create_client (impl); /* lame; we don't get an error code or anything */
7031- return;
7032- }
7033-
7034- if (!impl->search_query)
7035- {
7036- impl->search_query = _gtk_query_new ();
7037- _gtk_query_set_text (impl->search_query, query_text);
7038- }
7039-
7040- _gtk_search_engine_set_query (impl->search_engine, impl->search_query);
7041-
7042- g_signal_connect (impl->search_engine, "hits-added",
7043- G_CALLBACK (search_engine_hits_added_cb), impl);
7044- g_signal_connect (impl->search_engine, "finished",
7045- G_CALLBACK (search_engine_finished_cb), impl);
7046- g_signal_connect (impl->search_engine, "error",
7047- G_CALLBACK (search_engine_error_cb), impl);
7048-
7049- _gtk_search_engine_start (impl->search_engine);
7050-}
7051-
7052-/* Callback used when the user presses Enter while typing on the search
7053- * entry; starts the query
7054- */
7055-static void
7056-search_entry_activate_cb (GtkEntry *entry,
7057- gpointer data)
7058-{
7059- GtkFileChooserDefault *impl;
7060- const char *text;
7061-
7062- impl = GTK_FILE_CHOOSER_DEFAULT (data);
7063-
7064- text = gtk_entry_get_text (GTK_ENTRY (impl->search_entry));
7065- if (strlen (text) == 0)
7066- return;
7067-
7068- /* reset any existing query object */
7069- if (impl->search_query)
7070- {
7071- g_object_unref (impl->search_query);
7072- impl->search_query = NULL;
7073- }
7074-
7075- search_start_query (impl, text);
7076-}
7077-
7078-/* Hides the path bar and creates the search entry */
7079-static void
7080-search_setup_widgets (GtkFileChooserDefault *impl)
7081-{
7082- GtkWidget *label;
7083-
7084- impl->search_hbox = gtk_hbox_new (FALSE, 12);
7085-
7086- /* Label */
7087-
7088- label = gtk_label_new_with_mnemonic (_("_Search:"));
7089- gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0);
7090-
7091- /* Entry */
7092-
7093- impl->search_entry = gtk_entry_new ();
7094- gtk_label_set_mnemonic_widget (GTK_LABEL (label), impl->search_entry);
7095- g_signal_connect (impl->search_entry, "activate",
7096- G_CALLBACK (search_entry_activate_cb),
7097- impl);
7098- gtk_box_pack_start (GTK_BOX (impl->search_hbox), impl->search_entry, TRUE, TRUE, 0);
7099-
7100- /* if there already is a query, restart it */
7101- if (impl->search_query)
7102- {
7103- gchar *query = _gtk_query_get_text (impl->search_query);
7104-
7105- if (query)
7106- {
7107- gtk_entry_set_text (GTK_ENTRY (impl->search_entry), query);
7108- search_start_query (impl, query);
7109-
7110- g_free (query);
7111- }
7112- else
7113- {
7114- g_object_unref (impl->search_query);
7115- impl->search_query = NULL;
7116- }
7117- }
7118-
7119- gtk_widget_hide (impl->browse_path_bar);
7120- gtk_widget_hide (impl->browse_new_folder_button);
7121-
7122- /* Box for search widgets */
7123- gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->search_hbox, TRUE, TRUE, 0);
7124- gtk_widget_show_all (impl->search_hbox);
7125-
7126- /* Hide the location widgets temporarily */
7127-
7128- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
7129- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7130- {
7131- gtk_widget_hide (impl->location_button);
7132- gtk_widget_hide (impl->location_entry_box);
7133- }
7134-
7135- gtk_widget_grab_focus (impl->search_entry);
7136-
7137- /* FMQ: hide the filter combo? */
7138-}
7139-
7140-/* Main entry point to the searching functions; this gets called when the user
7141- * activates the Search shortcut.
7142- */
7143-static void
7144-search_activate (GtkFileChooserDefault *impl)
7145-{
7146- OperationMode previous_mode;
7147-
7148- if (impl->operation_mode == OPERATION_MODE_SEARCH)
7149- {
7150- gtk_widget_grab_focus (impl->search_entry);
7151- return;
7152- }
7153-
7154- previous_mode = impl->operation_mode;
7155- impl->operation_mode = OPERATION_MODE_SEARCH;
7156-
7157- switch (previous_mode)
7158- {
7159- case OPERATION_MODE_RECENT:
7160- recent_stop_loading (impl);
7161- recent_clear_model (impl, TRUE);
7162- break;
7163-
7164- case OPERATION_MODE_BROWSE:
7165- stop_loading_and_clear_list_model (impl);
7166- break;
7167-
7168- case OPERATION_MODE_SEARCH:
7169- g_assert_not_reached ();
7170- break;
7171- }
7172-
7173- g_assert (impl->search_hbox == NULL);
7174- g_assert (impl->search_entry == NULL);
7175- g_assert (impl->search_model == NULL);
7176- g_assert (impl->search_model_filter == NULL);
7177-
7178- search_setup_widgets (impl);
7179- file_list_set_sort_column_ids (impl);
7180-}
7181-
7182-/*
7183- * Recent files support
7184- */
7185-
7186-/* Frees the data in the recent_model */
7187-static void
7188-recent_clear_model (GtkFileChooserDefault *impl,
7189- gboolean remove_from_treeview)
7190-{
7191- GtkTreeModel *model;
7192- GtkTreeIter iter;
7193-
7194- if (!impl->recent_model)
7195- return;
7196-
7197- model = GTK_TREE_MODEL (impl->recent_model);
7198-
7199- if (remove_from_treeview)
7200- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
7201-
7202- if (gtk_tree_model_get_iter_first (model, &iter))
7203- {
7204- do
7205- {
7206- GtkFilePath *file_path;
7207- GtkFileSystemHandle *handle;
7208- GtkRecentInfo *recent_info;
7209- gchar *display_name;
7210-
7211- gtk_tree_model_get (model, &iter,
7212- RECENT_MODEL_COL_DISPLAY_NAME, &display_name,
7213- RECENT_MODEL_COL_PATH, &file_path,
7214- RECENT_MODEL_COL_HANDLE, &handle,
7215- RECENT_MODEL_COL_INFO, &recent_info,
7216- -1);
7217-
7218- if (handle)
7219- gtk_file_system_cancel_operation (handle);
7220-
7221- gtk_file_path_free (file_path);
7222- gtk_recent_info_unref (recent_info);
7223- g_free (display_name);
7224- }
7225- while (gtk_tree_model_iter_next (model, &iter));
7226- }
7227-
7228- g_object_unref (impl->recent_model);
7229- impl->recent_model = NULL;
7230-
7231- g_object_unref (impl->recent_model_filter);
7232- impl->recent_model_filter = NULL;
7233-
7234- g_object_unref (impl->recent_model_sort);
7235- impl->recent_model_sort = NULL;
7236-}
7237-
7238-/* Stops any ongoing loading of the recent files list; does
7239- * not touch the recent_model
7240- */
7241-static void
7242-recent_stop_loading (GtkFileChooserDefault *impl)
7243-{
7244- if (impl->load_recent_id)
7245- {
7246- g_source_remove (impl->load_recent_id);
7247- impl->load_recent_id = 0;
7248- }
7249-}
7250-
7251-/* Stops any pending load, clears the file list, and switches
7252- * back to OPERATION_MODE_BROWSE
7253- */
7254-static void
7255-recent_switch_to_browse_mode (GtkFileChooserDefault *impl)
7256-{
7257- g_assert (impl->operation_mode != OPERATION_MODE_BROWSE);
7258-
7259- recent_stop_loading (impl);
7260- recent_clear_model (impl, TRUE);
7261-
7262- gtk_widget_show (impl->browse_path_bar);
7263- gtk_widget_show (impl->browse_new_folder_button);
7264-
7265- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
7266- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7267- {
7268- gtk_widget_show (impl->location_button);
7269-
7270- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
7271- gtk_widget_show (impl->location_entry_box);
7272- }
7273-
7274- impl->operation_mode = OPERATION_MODE_BROWSE;
7275-
7276- file_list_set_sort_column_ids (impl);
7277-}
7278-
7279-/* Sort callback from the modification time column */
7280-static gint
7281-recent_column_mtime_sort_func (GtkTreeModel *model,
7282- GtkTreeIter *a,
7283- GtkTreeIter *b,
7284- gpointer user_data)
7285-{
7286- GtkFileChooserDefault *impl = user_data;
7287- GtkTreeIter child_a, child_b;
7288- GtkRecentInfo *info_a, *info_b;
7289- gboolean is_folder_a, is_folder_b;
7290-
7291- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
7292- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
7293-
7294- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_a,
7295- RECENT_MODEL_COL_IS_FOLDER, &is_folder_a,
7296- RECENT_MODEL_COL_INFO, &info_a,
7297- -1);
7298- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_b,
7299- RECENT_MODEL_COL_IS_FOLDER, &is_folder_b,
7300- RECENT_MODEL_COL_INFO, &info_b,
7301- -1);
7302-
7303- if (!info_a)
7304- return 1;
7305-
7306- if (!info_b)
7307- return -1;
7308-
7309- /* folders always go first */
7310- if (is_folder_a != is_folder_b)
7311- return is_folder_a ? 1 : -1;
7312-
7313- if (gtk_recent_info_get_modified (info_a) < gtk_recent_info_get_modified (info_b))
7314- return -1;
7315- else if (gtk_recent_info_get_modified (info_a) > gtk_recent_info_get_modified (info_b))
7316- return 1;
7317- else
7318- return 0;
7319-}
7320-
7321-static gint
7322-recent_column_path_sort_func (GtkTreeModel *model,
7323- GtkTreeIter *a,
7324- GtkTreeIter *b,
7325- gpointer user_data)
7326-{
7327- GtkFileChooserDefault *impl = user_data;
7328- GtkTreeIter child_a, child_b;
7329- gboolean is_folder_a, is_folder_b;
7330- gchar *name_a, *name_b;
7331-
7332- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
7333- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
7334-
7335- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_a,
7336- RECENT_MODEL_COL_IS_FOLDER, &is_folder_a,
7337- RECENT_MODEL_COL_DISPLAY_NAME, &name_a,
7338- -1);
7339- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_b,
7340- RECENT_MODEL_COL_IS_FOLDER, &is_folder_b,
7341- RECENT_MODEL_COL_DISPLAY_NAME, &name_b,
7342- -1);
7343-
7344- if (!name_a)
7345- return 1;
7346-
7347- if (!name_b)
7348- return -1;
7349-
7350- if (is_folder_a != is_folder_b)
7351- return is_folder_a ? 1 : -1;
7352-
7353- return strcmp (name_a, name_b);
7354-}
7355-
7356-static gboolean
7357-recent_get_is_filtered (GtkFileChooserDefault *impl,
7358- const GtkFilePath *path,
7359- GtkRecentInfo *recent_info)
7360-{
7361- GtkFileFilterInfo filter_info;
7362- GtkFileFilterFlags needed;
7363- gboolean result;
7364-
7365- if (!impl->current_filter)
7366- return FALSE;
7367-
7368- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
7369- needed = gtk_file_filter_get_needed (impl->current_filter);
7370-
7371- filter_info.display_name = gtk_recent_info_get_display_name (recent_info);
7372- filter_info.mime_type = gtk_recent_info_get_mime_type (recent_info);
7373-
7374- if (needed & GTK_FILE_FILTER_FILENAME)
7375- {
7376- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
7377- if (filter_info.filename)
7378- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
7379- }
7380- else
7381- filter_info.filename = NULL;
7382-
7383- if (needed & GTK_FILE_FILTER_URI)
7384- {
7385- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
7386- if (filter_info.uri)
7387- filter_info.contains |= GTK_FILE_FILTER_URI;
7388- }
7389- else
7390- filter_info.uri = NULL;
7391-
7392- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
7393-
7394- if (filter_info.filename)
7395- g_free ((gchar *) filter_info.filename);
7396- if (filter_info.uri)
7397- g_free ((gchar *) filter_info.uri);
7398-
7399- return !result;
7400-}
7401-
7402-/* Visibility function for the recent filter model */
7403-static gboolean
7404-recent_model_visible_func (GtkTreeModel *model,
7405- GtkTreeIter *iter,
7406- gpointer user_data)
7407-{
7408- GtkFileChooserDefault *impl = user_data;
7409- GtkFilePath *file_path;
7410- GtkRecentInfo *recent_info;
7411- gboolean is_folder;
7412-
7413- if (!impl->current_filter)
7414- return TRUE;
7415-
7416- gtk_tree_model_get (model, iter,
7417- RECENT_MODEL_COL_INFO, &recent_info,
7418- RECENT_MODEL_COL_PATH, &file_path,
7419- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
7420- -1);
7421-
7422- if (!recent_info)
7423- return TRUE;
7424-
7425- if (is_folder)
7426- return TRUE;
7427-
7428- return !recent_get_is_filtered (impl, file_path, recent_info);
7429-}
7430-
7431-static void
7432-recent_setup_model (GtkFileChooserDefault *impl)
7433-{
7434- g_assert (impl->recent_model == NULL);
7435- g_assert (impl->recent_model_filter == NULL);
7436- g_assert (impl->recent_model_sort == NULL);
7437-
7438- /* We store these columns in the search model:
7439- *
7440- * RECENT_MODEL_COL_PATH - a pointer to GtkFilePath for the hit's URI,
7441- * stored as a pointer and not as a GTK_TYPE_FILE_PATH;
7442- * RECENT_MODEL_COL_DISPLAY_NAME - a string with the display name,
7443- * stored as a pointer and not as a G_TYPE_STRING;
7444- * RECENT_MODEL_COL_INFO - GtkRecentInfo, stored as a pointer and not
7445- * as a GTK_TYPE_RECENT_INFO;
7446- * RECENT_MODEL_COL_IS_FOLDER - boolean flag;
7447- * RECENT_MODEL_COL_HANDLE - GtkFileSystemHandle, stored as a pointer
7448- * and not as a GTK_TYPE_FILE_SYSTEM_HANDLE;
7449- *
7450- * Keep this in sync with the enumeration defined near the beginning of
7451- * this file.
7452- */
7453- impl->recent_model = gtk_list_store_new (RECENT_MODEL_COL_NUM_COLUMNS,
7454- G_TYPE_POINTER,
7455- G_TYPE_POINTER,
7456- G_TYPE_POINTER,
7457- G_TYPE_BOOLEAN,
7458- G_TYPE_POINTER);
7459-
7460- impl->recent_model_filter =
7461- GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->recent_model), NULL));
7462- gtk_tree_model_filter_set_visible_func (impl->recent_model_filter,
7463- recent_model_visible_func,
7464- impl,
7465- NULL);
7466-
7467- /* this is the model that will actually be added to
7468- * the browse_files_tree_view widget; remember: we are
7469- * stuffing the real model into a filter model and then
7470- * into a sort model; this means we'll have to translate
7471- * the child iterator *twice* to get from a path or an
7472- * iterator coming from the tree view widget to the
7473- * real data inside the model.
7474- */
7475- impl->recent_model_sort =
7476- GTK_TREE_MODEL_SORT (recent_model_sort_new (impl, GTK_TREE_MODEL (impl->recent_model_filter)));
7477- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->recent_model_sort),
7478- RECENT_MODEL_COL_PATH,
7479- recent_column_path_sort_func,
7480- impl, NULL);
7481- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->recent_model_sort),
7482- RECENT_MODEL_COL_INFO,
7483- recent_column_mtime_sort_func,
7484- impl, NULL);
7485- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model_sort),
7486- RECENT_MODEL_COL_INFO,
7487- GTK_SORT_DESCENDING);
7488-}
7489-
7490-typedef struct
7491-{
7492- GtkFileChooserDefault *impl;
7493- GList *items;
7494- gint n_items;
7495- gint n_loaded_items;
7496- guint needs_sorting : 1;
7497-} RecentLoadData;
7498-
7499-static void
7500-recent_idle_cleanup (gpointer data)
7501-{
7502- RecentLoadData *load_data = data;
7503- GtkFileChooserDefault *impl = load_data->impl;
7504-
7505- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
7506- GTK_TREE_MODEL (impl->recent_model_sort));
7507-
7508- set_busy_cursor (impl, FALSE);
7509-
7510- impl->load_recent_id = 0;
7511-
7512- if (load_data->items)
7513- {
7514- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
7515- g_list_free (load_data->items);
7516- }
7517-
7518- g_free (load_data);
7519-}
7520-
7521-struct RecentItemInsertRequest
7522-{
7523- GtkFileChooserDefault *impl;
7524- GtkFilePath *path;
7525- GtkTreeRowReference *row_ref;
7526-};
7527-
7528-static void
7529-recent_item_get_info_cb (GtkFileSystemHandle *handle,
7530- const GtkFileInfo *info,
7531- const GError *error,
7532- gpointer data)
7533-{
7534- gboolean cancelled = handle->cancelled;
7535- GtkTreePath *path;
7536- GtkTreeIter iter;
7537- GtkFileSystemHandle *model_handle;
7538- gboolean is_folder = FALSE;
7539- struct RecentItemInsertRequest *request = data;
7540-
7541- if (!request->impl->recent_model)
7542- goto out;
7543-
7544- path = gtk_tree_row_reference_get_path (request->row_ref);
7545- if (!path)
7546- goto out;
7547-
7548- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->recent_model),
7549- &iter, path);
7550- gtk_tree_path_free (path);
7551-
7552- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->recent_model), &iter,
7553- RECENT_MODEL_COL_HANDLE, &model_handle,
7554- -1);
7555- if (handle != model_handle)
7556- goto out;
7557-
7558- gtk_list_store_set (request->impl->recent_model, &iter,
7559- RECENT_MODEL_COL_HANDLE, NULL,
7560- -1);
7561-
7562- if (cancelled)
7563- goto out;
7564-
7565- if (!info)
7566- {
7567- gtk_list_store_remove (request->impl->recent_model, &iter);
7568- goto out;
7569- }
7570-
7571- is_folder = gtk_file_info_get_is_folder (info);
7572-
7573- gtk_list_store_set (request->impl->recent_model, &iter,
7574- RECENT_MODEL_COL_IS_FOLDER, is_folder,
7575- -1);
7576-
7577-out:
7578- g_object_unref (request->impl);
7579- gtk_file_path_free (request->path);
7580- gtk_tree_row_reference_free (request->row_ref);
7581- g_free (request);
7582-
7583- g_object_unref (handle);
7584-}
7585-
7586-static gint
7587-recent_sort_mru (gconstpointer a,
7588- gconstpointer b)
7589-{
7590- GtkRecentInfo *info_a = (GtkRecentInfo *) a;
7591- GtkRecentInfo *info_b = (GtkRecentInfo *) b;
7592-
7593- return (gtk_recent_info_get_modified (info_b) - gtk_recent_info_get_modified (info_a));
7594-}
7595-
7596-static gint
7597-get_recent_files_limit (GtkWidget *widget)
7598-{
7599- GtkSettings *settings;
7600- gint limit;
7601-
7602- if (gtk_widget_has_screen (widget))
7603- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
7604- else
7605- settings = gtk_settings_get_default ();
7606-
7607- g_object_get (G_OBJECT (settings), "gtk-recent-files-limit", &limit, NULL);
7608-
7609- return limit;
7610-}
7611-
7612-static gboolean
7613-recent_idle_load (gpointer data)
7614-{
7615- RecentLoadData *load_data = data;
7616- GtkFileChooserDefault *impl = load_data->impl;
7617- GtkTreeIter iter;
7618- GtkTreePath *p;
7619- GtkRecentInfo *info;
7620- const gchar *uri, *display_name;
7621- GtkFilePath *path;
7622- GtkFileSystemHandle *handle;
7623- struct RecentItemInsertRequest *request;
7624-
7625- if (!impl->recent_manager)
7626- return FALSE;
7627-
7628- /* first iteration: load all the items */
7629- if (!load_data->items)
7630- {
7631- load_data->items = gtk_recent_manager_get_items (impl->recent_manager);
7632- if (!load_data->items)
7633- return FALSE;
7634-
7635- load_data->needs_sorting = TRUE;
7636-
7637- return TRUE;
7638- }
7639-
7640- /* second iteration: preliminary MRU sorting and clamping */
7641- if (load_data->needs_sorting)
7642- {
7643- gint limit;
7644-
7645- load_data->items = g_list_sort (load_data->items, recent_sort_mru);
7646- load_data->n_items = g_list_length (load_data->items);
7647-
7648- limit = get_recent_files_limit (GTK_WIDGET (impl));
7649-
7650- if (limit != -1 && (load_data->n_items > limit))
7651- {
7652- GList *clamp, *l;
7653-
7654- clamp = g_list_nth (load_data->items, limit - 1);
7655- if (G_LIKELY (clamp))
7656- {
7657- l = clamp->next;
7658- clamp->next = NULL;
7659-
7660- g_list_foreach (l, (GFunc) gtk_recent_info_unref, NULL);
7661- g_list_free (l);
7662-
7663- load_data->n_items = limit;
7664- }
7665- }
7666-
7667- load_data->n_loaded_items = 0;
7668- load_data->needs_sorting = FALSE;
7669-
7670- return TRUE;
7671- }
7672-
7673- info = g_list_nth_data (load_data->items, load_data->n_loaded_items);
7674- g_assert (info != NULL);
7675-
7676- uri = gtk_recent_info_get_uri (info);
7677- display_name = gtk_recent_info_get_display_name (info);
7678- path = gtk_file_system_uri_to_path (impl->file_system, uri);
7679- if (!path)
7680- goto load_next;
7681-
7682- gtk_list_store_append (impl->recent_model, &iter);
7683- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->recent_model), &iter);
7684-
7685- request = g_new0 (struct RecentItemInsertRequest, 1);
7686- request->impl = g_object_ref (impl);
7687- request->path = gtk_file_path_copy (path);
7688- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->recent_model), p);
7689- gtk_tree_path_free (p);
7690-
7691- handle = gtk_file_system_get_info (impl->file_system, path,
7692- GTK_FILE_INFO_IS_FOLDER,
7693- recent_item_get_info_cb,
7694- request);
7695-
7696- gtk_list_store_set (impl->recent_model, &iter,
7697- RECENT_MODEL_COL_PATH, path,
7698- RECENT_MODEL_COL_DISPLAY_NAME, g_strdup (display_name),
7699- RECENT_MODEL_COL_INFO, gtk_recent_info_ref (info),
7700- RECENT_MODEL_COL_HANDLE, handle,
7701- -1);
7702-
7703-load_next:
7704-
7705- load_data->n_loaded_items += 1;
7706-
7707- /* finished loading items */
7708- if (load_data->n_loaded_items == load_data->n_items)
7709- {
7710- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
7711- g_list_free (load_data->items);
7712- load_data->items = NULL;
7713-
7714- return FALSE;
7715- }
7716-
7717- return TRUE;
7718-}
7719-
7720-static void
7721-recent_start_loading (GtkFileChooserDefault *impl)
7722-{
7723- RecentLoadData *load_data;
7724-
7725- recent_stop_loading (impl);
7726- recent_clear_model (impl, TRUE);
7727- recent_setup_model (impl);
7728- set_busy_cursor (impl, TRUE);
7729-
7730- if (!impl->recent_manager)
7731- recent_manager_update (impl);
7732-
7733- g_assert (impl->load_recent_id == 0);
7734-
7735- load_data = g_new (RecentLoadData, 1);
7736- load_data->impl = impl;
7737- load_data->items = NULL;
7738- load_data->n_items = 0;
7739- load_data->n_loaded_items = 0;
7740- load_data->needs_sorting = TRUE;
7741-
7742- /* begin lazy loading the recent files into the model */
7743- impl->load_recent_id = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30,
7744- recent_idle_load,
7745- load_data,
7746- recent_idle_cleanup);
7747-}
7748-
7749-static void
7750-recent_selected_foreach_get_path_cb (GtkTreeModel *model,
7751- GtkTreePath *path,
7752- GtkTreeIter *iter,
7753- gpointer data)
7754-{
7755- GSList **list;
7756- const GtkFilePath *file_path;
7757- GtkFilePath *file_path_copy;
7758-
7759- list = data;
7760-
7761- gtk_tree_model_get (model, iter, RECENT_MODEL_COL_PATH, &file_path, -1);
7762- file_path_copy = gtk_file_path_copy (file_path);
7763- *list = g_slist_prepend (*list, file_path_copy);
7764-}
7765-
7766-/* Constructs a list of the selected paths in recent files mode */
7767-static GSList *
7768-recent_get_selected_paths (GtkFileChooserDefault *impl)
7769-{
7770- GSList *result;
7771- GtkTreeSelection *selection;
7772-
7773- result = NULL;
7774-
7775- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7776- gtk_tree_selection_selected_foreach (selection, recent_selected_foreach_get_path_cb, &result);
7777- result = g_slist_reverse (result);
7778-
7779- return result;
7780-}
7781-
7782-/* Called from ::should_respond(). We return whether there are selected
7783- * files in the recent files list.
7784- */
7785-static gboolean
7786-recent_should_respond (GtkFileChooserDefault *impl)
7787-{
7788- GtkTreeSelection *selection;
7789-
7790- g_assert (impl->operation_mode == OPERATION_MODE_RECENT);
7791-
7792- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7793- return (gtk_tree_selection_count_selected_rows (selection) != 0);
7794-}
7795-
7796-/* Hide the location widgets temporarily */
7797-static void
7798-recent_hide_entry (GtkFileChooserDefault *impl)
7799-{
7800- gtk_widget_hide (impl->browse_path_bar);
7801- gtk_widget_hide (impl->browse_new_folder_button);
7802-
7803- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
7804- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7805- {
7806- gtk_widget_hide (impl->location_button);
7807- gtk_widget_hide (impl->location_entry_box);
7808- }
7809-}
7810-
7811-/* Main entry point to the recent files functions; this gets called when
7812- * the user activates the Recently Used shortcut.
7813- */
7814-static void
7815-recent_activate (GtkFileChooserDefault *impl)
7816-{
7817- OperationMode previous_mode;
7818-
7819- if (impl->operation_mode == OPERATION_MODE_RECENT)
7820- return;
7821-
7822- previous_mode = impl->operation_mode;
7823- impl->operation_mode = OPERATION_MODE_RECENT;
7824-
7825- switch (previous_mode)
7826- {
7827- case OPERATION_MODE_SEARCH:
7828- search_stop_searching (impl, FALSE);
7829- search_clear_model (impl, TRUE);
7830-
7831- gtk_widget_destroy (impl->search_hbox);
7832- impl->search_hbox = NULL;
7833- impl->search_entry = NULL;
7834- break;
7835-
7836- case OPERATION_MODE_BROWSE:
7837- stop_loading_and_clear_list_model (impl);
7838- break;
7839-
7840- case OPERATION_MODE_RECENT:
7841- g_assert_not_reached ();
7842- break;
7843- }
7844-
7845- recent_hide_entry (impl);
7846- file_list_set_sort_column_ids (impl);
7847- recent_start_loading (impl);
7848-}
7849-
7850-/* convert an iterator coming from the model bound to
7851- * browse_files_tree_view to an interator inside the
7852- * real recent_model
7853- */
7854-static void
7855-recent_get_valid_child_iter (GtkFileChooserDefault *impl,
7856- GtkTreeIter *child_iter,
7857- GtkTreeIter *iter)
7858-{
7859- GtkTreeIter middle;
7860-
7861- if (!impl->recent_model)
7862- return;
7863-
7864- if (!impl->recent_model_filter || !impl->recent_model_sort)
7865- return;
7866-
7867- /* pass 1: get the iterator in the filter model */
7868- gtk_tree_model_sort_convert_iter_to_child_iter (impl->recent_model_sort,
7869- &middle, iter);
7870-
7871- /* pass 2: get the iterator in the real model */
7872- gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter,
7873- child_iter,
7874- &middle);
7875-}
7876-
7877-
7878-static void
7879 set_current_filter (GtkFileChooserDefault *impl,
7880 GtkFileFilter *filter)
7881 {
7882@@ -10175,12 +4463,6 @@
7883 if (impl->browse_files_model)
7884 install_list_model_filter (impl);
7885
7886- if (impl->search_model_filter)
7887- gtk_tree_model_filter_refilter (impl->search_model_filter);
7888-
7889- if (impl->recent_model_filter)
7890- gtk_tree_model_filter_refilter (impl->recent_model_filter);
7891-
7892 g_object_notify (G_OBJECT (impl), "filter");
7893 }
7894 }
7895@@ -10195,355 +4477,7 @@
7896 set_current_filter (impl, new_filter);
7897 }
7898
7899-static void
7900-check_preview_change (GtkFileChooserDefault *impl)
7901-{
7902- GtkTreePath *cursor_path;
7903- const GtkFilePath *new_path;
7904- const char *new_display_name;
7905-
7906- gtk_tree_view_get_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), &cursor_path, NULL);
7907- new_path = NULL;
7908- new_display_name = NULL;
7909- if (cursor_path)
7910- {
7911- GtkTreeIter child_iter;
7912-
7913- if (impl->operation_mode == OPERATION_MODE_BROWSE)
7914- {
7915- if (impl->sort_model)
7916- {
7917- GtkTreeIter iter;
7918- const GtkFileInfo *new_info;
7919-
7920- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, cursor_path);
7921- gtk_tree_path_free (cursor_path);
7922-
7923- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
7924-
7925- new_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
7926- new_info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
7927- if (new_info)
7928- new_display_name = gtk_file_info_get_display_name (new_info);
7929- }
7930- }
7931- else if (impl->operation_mode == OPERATION_MODE_SEARCH)
7932- {
7933- GtkTreeIter iter;
7934-
7935- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort),
7936- &iter, cursor_path);
7937- gtk_tree_path_free (cursor_path);
7938-
7939- search_get_valid_child_iter (impl, &child_iter, &iter);
7940- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
7941- SEARCH_MODEL_COL_PATH, &new_path,
7942- SEARCH_MODEL_COL_DISPLAY_NAME, &new_display_name,
7943- -1);
7944- }
7945- else if (impl->operation_mode == OPERATION_MODE_RECENT)
7946- {
7947- GtkTreeIter iter;
7948-
7949- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort),
7950- &iter, cursor_path);
7951- gtk_tree_path_free (cursor_path);
7952-
7953- recent_get_valid_child_iter (impl, &child_iter, &iter);
7954- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
7955- RECENT_MODEL_COL_PATH, &new_path,
7956- RECENT_MODEL_COL_DISPLAY_NAME, &new_display_name,
7957- -1);
7958- }
7959- }
7960-
7961- if (new_path != impl->preview_path &&
7962- !(new_path && impl->preview_path &&
7963- gtk_file_path_compare (new_path, impl->preview_path) == 0))
7964- {
7965- if (impl->preview_path)
7966- {
7967- gtk_file_path_free (impl->preview_path);
7968- g_free (impl->preview_display_name);
7969- }
7970-
7971- if (new_path)
7972- {
7973- impl->preview_path = gtk_file_path_copy (new_path);
7974- impl->preview_display_name = g_strdup (new_display_name);
7975- }
7976- else
7977- {
7978- impl->preview_path = NULL;
7979- impl->preview_display_name = NULL;
7980- }
7981-
7982- if (impl->use_preview_label && impl->preview_label)
7983- gtk_label_set_text (GTK_LABEL (impl->preview_label), impl->preview_display_name);
7984-
7985- g_signal_emit_by_name (impl, "update-preview");
7986- }
7987-}
7988-
7989-static void
7990-shortcuts_activate_volume_mount_cb (GtkFileSystemHandle *handle,
7991- GtkFileSystemVolume *volume,
7992- const GError *error,
7993- gpointer data)
7994-{
7995- GtkFilePath *path;
7996- gboolean cancelled = handle->cancelled;
7997- GtkFileChooserDefault *impl = data;
7998-
7999- if (handle != impl->shortcuts_activate_iter_handle)
8000- goto out;
8001-
8002- impl->shortcuts_activate_iter_handle = NULL;
8003-
8004- set_busy_cursor (impl, FALSE);
8005-
8006- if (cancelled)
8007- goto out;
8008-
8009- if (error)
8010- {
8011- char *msg;
8012-
8013- msg = g_strdup_printf (_("Could not mount %s"),
8014- gtk_file_system_volume_get_display_name (impl->file_system, volume));
8015- error_message (impl, msg, error->message);
8016- g_free (msg);
8017-
8018- goto out;
8019- }
8020-
8021- path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
8022- if (path != NULL)
8023- {
8024- change_folder_and_display_error (impl, path, FALSE);
8025- focus_browse_tree_view_if_possible (impl);
8026-
8027- gtk_file_path_free (path);
8028- }
8029-
8030-out:
8031- g_object_unref (impl);
8032- g_object_unref (handle);
8033-}
8034-
8035-
8036-/* Activates a volume by mounting it if necessary and then switching to its
8037- * base path.
8038- */
8039-static void
8040-shortcuts_activate_volume (GtkFileChooserDefault *impl,
8041- GtkFileSystemVolume *volume)
8042-{
8043- GtkFilePath *path;
8044-
8045- switch (impl->operation_mode)
8046- {
8047- case OPERATION_MODE_BROWSE:
8048- break;
8049- case OPERATION_MODE_SEARCH:
8050- search_switch_to_browse_mode (impl);
8051- break;
8052- case OPERATION_MODE_RECENT:
8053- recent_switch_to_browse_mode (impl);
8054- break;
8055- }
8056-
8057- /* We ref the file chooser since volume_mount() may run a main loop, and the
8058- * user could close the file chooser window in the meantime.
8059- */
8060- g_object_ref (impl);
8061-
8062- if (!gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
8063- {
8064- set_busy_cursor (impl, TRUE);
8065-
8066- impl->shortcuts_activate_iter_handle =
8067- gtk_file_system_volume_mount (impl->file_system, volume,
8068- shortcuts_activate_volume_mount_cb,
8069- g_object_ref (impl));
8070- }
8071- else
8072- {
8073- path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
8074- if (path != NULL)
8075- {
8076- change_folder_and_display_error (impl, path, FALSE);
8077- gtk_file_path_free (path);
8078- }
8079- }
8080-
8081- g_object_unref (impl);
8082-}
8083-
8084-/* Opens the folder or volume at the specified iter in the shortcuts model */
8085-struct ShortcutsActivateData
8086-{
8087- GtkFileChooserDefault *impl;
8088- GtkFilePath *path;
8089-};
8090-
8091-static void
8092-shortcuts_activate_get_info_cb (GtkFileSystemHandle *handle,
8093- const GtkFileInfo *info,
8094- const GError *error,
8095- gpointer user_data)
8096-{
8097- gboolean cancelled = handle->cancelled;
8098- struct ShortcutsActivateData *data = user_data;
8099-
8100- if (handle != data->impl->shortcuts_activate_iter_handle)
8101- goto out;
8102-
8103- data->impl->shortcuts_activate_iter_handle = NULL;
8104-
8105- if (cancelled)
8106- goto out;
8107-
8108- if (!error && gtk_file_info_get_is_folder (info))
8109- {
8110- change_folder_and_display_error (data->impl, data->path, FALSE);
8111- focus_browse_tree_view_if_possible (data->impl);
8112- }
8113- else
8114- gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (data->impl),
8115- data->path,
8116- NULL);
8117-
8118-out:
8119- g_object_unref (data->impl);
8120- gtk_file_path_free (data->path);
8121- g_free (data);
8122-
8123- g_object_unref (handle);
8124-}
8125-
8126-static void
8127-shortcuts_activate_iter (GtkFileChooserDefault *impl,
8128- GtkTreeIter *iter)
8129-{
8130- gpointer col_data;
8131- ShortcutType shortcut_type;
8132-
8133- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY && impl->action != GTK_FILE_CHOOSER_ACTION_SAVE)
8134- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), "");
8135-
8136- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter,
8137- SHORTCUTS_COL_DATA, &col_data,
8138- SHORTCUTS_COL_TYPE, &shortcut_type,
8139- -1);
8140-
8141- if (impl->shortcuts_activate_iter_handle)
8142- {
8143- gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle);
8144- impl->shortcuts_activate_iter_handle = NULL;
8145- }
8146-
8147- if (shortcut_type == SHORTCUT_TYPE_SEPARATOR)
8148- return;
8149- else if (shortcut_type == SHORTCUT_TYPE_VOLUME)
8150- {
8151- GtkFileSystemVolume *volume;
8152-
8153- volume = col_data;
8154-
8155- shortcuts_activate_volume (impl, volume);
8156- }
8157- else if (shortcut_type == SHORTCUT_TYPE_PATH)
8158- {
8159- struct ShortcutsActivateData *data;
8160-
8161- data = g_new0 (struct ShortcutsActivateData, 1);
8162- data->impl = g_object_ref (impl);
8163- data->path = gtk_file_path_copy (col_data);
8164-
8165- impl->shortcuts_activate_iter_handle =
8166- gtk_file_system_get_info (impl->file_system, data->path,
8167- GTK_FILE_INFO_IS_FOLDER,
8168- shortcuts_activate_get_info_cb, data);
8169- }
8170- else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
8171- {
8172- search_activate (impl);
8173- }
8174- else if (shortcut_type == SHORTCUT_TYPE_RECENT)
8175- {
8176- recent_activate (impl);
8177- }
8178-}
8179-
8180-/* Callback used when a row in the shortcuts list is activated */
8181-static void
8182-shortcuts_row_activated_cb (GtkTreeView *tree_view,
8183- GtkTreePath *path,
8184- GtkTreeViewColumn *column,
8185- GtkFileChooserDefault *impl)
8186-{
8187- GtkTreeIter iter;
8188- GtkTreeIter child_iter;
8189-
8190- if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &iter, path))
8191- return;
8192-
8193- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
8194- &child_iter,
8195- &iter);
8196- shortcuts_activate_iter (impl, &child_iter);
8197-}
8198-
8199-/* Handler for GtkWidget::key-press-event on the shortcuts list */
8200 static gboolean
8201-shortcuts_key_press_event_cb (GtkWidget *widget,
8202- GdkEventKey *event,
8203- GtkFileChooserDefault *impl)
8204-{
8205- guint modifiers;
8206-
8207- modifiers = gtk_accelerator_get_default_mod_mask ();
8208-
8209- if ((event->keyval == GDK_BackSpace
8210- || event->keyval == GDK_Delete
8211- || event->keyval == GDK_KP_Delete)
8212- && (event->state & modifiers) == 0)
8213- {
8214- remove_selected_bookmarks (impl);
8215- return TRUE;
8216- }
8217-
8218- if ((event->keyval == GDK_F2)
8219- && (event->state & modifiers) == 0)
8220- {
8221- rename_selected_bookmark (impl);
8222- return TRUE;
8223- }
8224-
8225- return FALSE;
8226-}
8227-
8228-static gboolean
8229-shortcuts_select_func (GtkTreeSelection *selection,
8230- GtkTreeModel *model,
8231- GtkTreePath *path,
8232- gboolean path_currently_selected,
8233- gpointer data)
8234-{
8235- GtkFileChooserDefault *impl = data;
8236- GtkTreeIter filter_iter;
8237- ShortcutType shortcut_type;
8238-
8239- if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &filter_iter, path))
8240- g_assert_not_reached ();
8241-
8242- gtk_tree_model_get (impl->shortcuts_pane_filter_model, &filter_iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1);
8243-
8244- return shortcut_type != SHORTCUT_TYPE_SEPARATOR;
8245-}
8246-
8247-static gboolean
8248 list_select_func (GtkTreeSelection *selection,
8249 GtkTreeModel *model,
8250 GtkTreePath *path,
8251@@ -10556,55 +4490,17 @@
8252 impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8253 {
8254 GtkTreeIter iter, child_iter;
8255+ const GtkFileInfo *info;
8256
8257- switch (impl->operation_mode)
8258- {
8259- case OPERATION_MODE_SEARCH:
8260- {
8261- gboolean is_folder;
8262+ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8263+ return FALSE;
8264+
8265+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
8266
8267- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
8268- return FALSE;
8269+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8270
8271- search_get_valid_child_iter (impl, &child_iter, &iter);
8272- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8273- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8274- -1);
8275- if (!is_folder)
8276- return FALSE;
8277- }
8278- break;
8279-
8280- case OPERATION_MODE_RECENT:
8281- {
8282- gboolean is_folder;
8283-
8284- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), &iter, path))
8285- return FALSE;
8286-
8287- recent_get_valid_child_iter (impl, &child_iter, &iter);
8288- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8289- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8290- -1);
8291- if (!is_folder)
8292- return FALSE;
8293- }
8294- break;
8295-
8296- case OPERATION_MODE_BROWSE:
8297- {
8298- const GtkFileInfo *info;
8299-
8300- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8301- return FALSE;
8302-
8303- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
8304- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8305- if (info && !gtk_file_info_get_is_folder (info))
8306- return FALSE;
8307- }
8308- break;
8309- }
8310+ if (info && !gtk_file_info_get_is_folder (info))
8311+ return FALSE;
8312 }
8313
8314 return TRUE;
8315@@ -10615,8 +4511,7 @@
8316 GtkFileChooserDefault *impl)
8317 {
8318 /* See if we are in the new folder editable row for Save mode */
8319- if (impl->operation_mode == OPERATION_MODE_BROWSE &&
8320- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8321+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8322 {
8323 const GtkFileInfo *info;
8324 gboolean had_selection;
8325@@ -10634,9 +4529,6 @@
8326 if (impl->location_entry)
8327 update_chooser_entry (impl);
8328
8329- check_preview_change (impl);
8330- bookmarks_check_add_sensitivity (impl);
8331-
8332 g_signal_emit_by_name (impl, "selection-changed", 0);
8333 }
8334
8335@@ -10647,107 +4539,30 @@
8336 GtkTreeViewColumn *column,
8337 GtkFileChooserDefault *impl)
8338 {
8339- GtkTreeIter iter;
8340- GtkTreeIter child_iter;
8341+ GtkTreeIter iter, child_iter;
8342+ const GtkFileInfo *info;
8343
8344- switch (impl->operation_mode)
8345- {
8346- case OPERATION_MODE_SEARCH:
8347- {
8348- GtkFilePath *file_path;
8349- gboolean is_folder;
8350+ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8351+ return;
8352
8353- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
8354- return;
8355+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
8356
8357- search_get_valid_child_iter (impl, &child_iter, &iter);
8358- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8359- SEARCH_MODEL_COL_PATH, &file_path,
8360- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8361- -1);
8362-
8363- if (is_folder)
8364- {
8365- change_folder_and_display_error (impl, file_path, FALSE);
8366- return;
8367- }
8368+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8369
8370- g_signal_emit_by_name (impl, "file-activated");
8371- }
8372- break;
8373+ if (gtk_file_info_get_is_folder (info))
8374+ {
8375+ const GtkFilePath *file_path;
8376
8377- case OPERATION_MODE_RECENT:
8378- {
8379- GtkFilePath *file_path;
8380- gboolean is_folder;
8381+ file_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8382
8383- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), &iter, path))
8384- return;
8385-
8386- recent_get_valid_child_iter (impl, &child_iter, &iter);
8387- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8388- RECENT_MODEL_COL_PATH, &file_path,
8389- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8390- -1);
8391+ change_folder_and_display_error (impl, file_path);
8392
8393- if (is_folder)
8394- {
8395- change_folder_and_display_error (impl, file_path, FALSE);
8396- return;
8397- }
8398-
8399- g_signal_emit_by_name (impl, "file-activated");
8400- }
8401- break;
8402-
8403- case OPERATION_MODE_BROWSE:
8404- {
8405- const GtkFileInfo *info;
8406-
8407- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8408- return;
8409-
8410- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8411- &child_iter, &iter);
8412- info = _gtk_file_system_model_get_info (impl->browse_files_model,
8413- &child_iter);
8414-
8415- if (gtk_file_info_get_is_folder (info))
8416- {
8417- const GtkFilePath *file_path;
8418-
8419- file_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8420- change_folder_and_display_error (impl, file_path, FALSE);
8421- return;
8422- }
8423-
8424- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8425- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8426- g_signal_emit_by_name (impl, "file-activated");
8427- }
8428- break;
8429+ return;
8430 }
8431-}
8432
8433-static void
8434-path_bar_clicked (GtkPathBar *path_bar,
8435- GtkFilePath *file_path,
8436- GtkFilePath *child_path,
8437- gboolean child_is_hidden,
8438- GtkFileChooserDefault *impl)
8439-{
8440- if (child_path)
8441- pending_select_paths_add (impl, child_path);
8442-
8443- if (!change_folder_and_display_error (impl, file_path, FALSE))
8444- return;
8445-
8446- /* Say we have "/foo/bar/[.baz]" and the user clicks on "bar". We should then
8447- * show hidden files so that ".baz" appears in the file list, as it will still
8448- * be shown in the path bar: "/foo/[bar]/.baz"
8449- */
8450- if (child_is_hidden)
8451- g_object_set (impl, "show-hidden", TRUE, NULL);
8452+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8453+ impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8454+ g_signal_emit_by_name (impl, "file-activated");
8455 }
8456
8457 static const GtkFileInfo *
8458@@ -10772,83 +4587,40 @@
8459 {
8460 GtkFileChooserDefault *impl = data;
8461 GtkTreeIter child_iter;
8462- GdkPixbuf *pixbuf = NULL;
8463+ const GtkFilePath *path;
8464+ GdkPixbuf *pixbuf;
8465+ const GtkFileInfo *info;
8466 gboolean sensitive = TRUE;
8467
8468 profile_start ("start", NULL);
8469
8470- switch (impl->operation_mode)
8471- {
8472- case OPERATION_MODE_SEARCH:
8473- {
8474- GtkTreeIter child_iter;
8475- gboolean is_folder;
8476+ info = get_list_file_info (impl, iter);
8477
8478- search_get_valid_child_iter (impl, &child_iter, iter);
8479- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8480- SEARCH_MODEL_COL_PIXBUF, &pixbuf,
8481- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8482- -1);
8483-
8484- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8485- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8486- sensitive = is_folder;
8487- }
8488- break;
8489+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8490+ &child_iter,
8491+ iter);
8492+ path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8493
8494- case OPERATION_MODE_RECENT:
8495- {
8496- GtkTreeIter child_iter;
8497- GtkRecentInfo *info;
8498- gboolean is_folder;
8499+ if (path)
8500+ {
8501+ pixbuf = NULL;
8502
8503- recent_get_valid_child_iter (impl, &child_iter, iter);
8504- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8505- RECENT_MODEL_COL_INFO, &info,
8506- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8507- -1);
8508-
8509- pixbuf = gtk_recent_info_get_icon (info, impl->icon_size);
8510-
8511- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8512- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8513- sensitive = is_folder;
8514- }
8515- break;
8516-
8517- case OPERATION_MODE_BROWSE:
8518- {
8519- const GtkFileInfo *info;
8520- const GtkFilePath *path;
8521-
8522- info = get_list_file_info (impl, iter);
8523-
8524- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8525- &child_iter,
8526- iter);
8527- path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8528- if (path)
8529- {
8530- if (info)
8531- {
8532- /* FIXME: NULL GError */
8533- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (impl),
8534- impl->icon_size, NULL);
8535- }
8536- }
8537- else
8538- {
8539- /* We are on the editable row */
8540- pixbuf = NULL;
8541- }
8542-
8543- if (info &&
8544- (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8545- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
8546- sensitive = gtk_file_info_get_is_folder (info);
8547- }
8548- break;
8549+ if (info)
8550+ {
8551+ /* FIXME: NULL GError */
8552+ pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (impl),
8553+ impl->icon_size, NULL);
8554+ }
8555 }
8556+ else
8557+ {
8558+ /* We are on the editable row */
8559+ pixbuf = NULL;
8560+ }
8561+
8562+ if (info && (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8563+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
8564+ sensitive = gtk_file_info_get_is_folder (info);
8565
8566 g_object_set (cell,
8567 "pixbuf", pixbuf,
8568@@ -10869,85 +4641,21 @@
8569 gpointer data)
8570 {
8571 GtkFileChooserDefault *impl = data;
8572- const GtkFileInfo *info;
8573+ const GtkFileInfo *info = get_list_file_info (impl, iter);
8574 gboolean sensitive = TRUE;
8575
8576- if (impl->operation_mode == OPERATION_MODE_SEARCH)
8577- {
8578- GtkTreeIter child_iter;
8579- gchar *display_name;
8580- gboolean is_folder;
8581-
8582- search_get_valid_child_iter (impl, &child_iter, iter);
8583- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8584- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
8585- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8586- -1);
8587-
8588- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8589- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8590- {
8591- sensitive = is_folder;
8592- }
8593-
8594- g_object_set (cell,
8595- "text", display_name,
8596- "sensitive", sensitive,
8597- "ellipsize", PANGO_ELLIPSIZE_END,
8598- NULL);
8599-
8600- return;
8601- }
8602-
8603- if (impl->operation_mode == OPERATION_MODE_RECENT)
8604- {
8605- GtkTreeIter child_iter;
8606- GtkRecentInfo *recent_info;
8607- gchar *display_name;
8608- gboolean is_folder;
8609-
8610- recent_get_valid_child_iter (impl, &child_iter, iter);
8611- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8612- RECENT_MODEL_COL_INFO, &recent_info,
8613- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8614- -1);
8615-
8616- display_name = gtk_recent_info_get_short_name (recent_info);
8617-
8618- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8619- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8620- {
8621- sensitive = is_folder;
8622- }
8623-
8624- g_object_set (cell,
8625- "text", display_name,
8626- "sensitive", sensitive,
8627- "ellipsize", PANGO_ELLIPSIZE_END,
8628- NULL);
8629-
8630- g_free (display_name);
8631-
8632- return;
8633- }
8634-
8635- info = get_list_file_info (impl, iter);
8636- sensitive = TRUE;
8637-
8638 if (!info)
8639 {
8640 g_object_set (cell,
8641 "text", _("Type name of new folder"),
8642- "sensitive", TRUE,
8643- "ellipsize", PANGO_ELLIPSIZE_NONE,
8644 NULL);
8645
8646 return;
8647 }
8648
8649
8650- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8651- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8652+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
8653+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8654 {
8655 sensitive = gtk_file_info_get_is_folder (info);
8656 }
8657@@ -10955,7 +4663,6 @@
8658 g_object_set (cell,
8659 "text", gtk_file_info_get_display_name (info),
8660 "sensitive", sensitive,
8661- "ellipsize", PANGO_ELLIPSIZE_END,
8662 NULL);
8663 }
8664
8665@@ -11017,142 +4724,64 @@
8666 gpointer data)
8667 {
8668 GtkFileChooserDefault *impl;
8669- time_t time_mtime;
8670- gchar *date_str = NULL;
8671+ const GtkFileInfo *info;
8672+ GtkFileTime time_mtime;
8673+ GDate mtime, now;
8674+ int days_diff;
8675+ char buf[256];
8676 gboolean sensitive = TRUE;
8677
8678 impl = data;
8679
8680- if (impl->operation_mode == OPERATION_MODE_SEARCH)
8681+ info = get_list_file_info (impl, iter);
8682+ if (!info)
8683 {
8684- GtkTreeIter child_iter;
8685- struct stat *statbuf;
8686- gboolean is_folder;
8687-
8688- search_get_valid_child_iter (impl, &child_iter, iter);
8689- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8690- SEARCH_MODEL_COL_STAT, &statbuf,
8691- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8692- -1);
8693- if (statbuf)
8694- time_mtime = statbuf->st_mtime;
8695- else
8696- time_mtime = 0;
8697-
8698-
8699- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8700- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8701- sensitive = is_folder;
8702+ g_object_set (cell,
8703+ "text", "",
8704+ "sensitive", TRUE,
8705+ NULL);
8706+ return;
8707 }
8708- else if (impl->operation_mode == OPERATION_MODE_RECENT)
8709- {
8710- GtkTreeIter child_iter;
8711- GtkRecentInfo *info;
8712- gboolean is_folder;
8713
8714- recent_get_valid_child_iter (impl, &child_iter, iter);
8715- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8716- RECENT_MODEL_COL_INFO, &info,
8717- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8718- -1);
8719+ time_mtime = gtk_file_info_get_modification_time (info);
8720
8721- if (info)
8722- time_mtime = gtk_recent_info_get_modified (info);
8723- else
8724- time_mtime = 0;
8725-
8726- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8727- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8728- sensitive = is_folder;
8729- }
8730+ if (time_mtime == 0)
8731+ strcpy (buf, _("Unknown"));
8732 else
8733 {
8734- const GtkFileInfo *info;
8735-
8736- info = get_list_file_info (impl, iter);
8737- if (!info)
8738- {
8739- g_object_set (cell,
8740- "text", "",
8741- "sensitive", TRUE,
8742- NULL);
8743- return;
8744- }
8745-
8746- time_mtime = (time_t) gtk_file_info_get_modification_time (info);
8747-
8748- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8749- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8750- sensitive = gtk_file_info_get_is_folder (info);
8751- }
8752-
8753- if (G_UNLIKELY (time_mtime == 0))
8754- date_str = g_strdup (_("Unknown"));
8755- else
8756- {
8757- GDate mtime, now;
8758- gint days_diff;
8759- struct tm tm_mtime;
8760 time_t time_now;
8761- const gchar *format;
8762- gchar *locale_format = NULL;
8763- gchar buf[256];
8764-
8765-#ifdef HAVE_LOCALTIME_R
8766- localtime_r ((time_t *) &time_mtime, &tm_mtime);
8767-#else
8768- {
8769- struct tm *ptm = localtime ((time_t *) &time_mtime);
8770-
8771- if (!ptm)
8772- {
8773- g_warning ("ptm != NULL failed");
8774-
8775- g_object_set (cell,
8776- "text", _("Unknown"),
8777- "sensitive", sensitive,
8778- NULL);
8779- return;
8780- }
8781- else
8782- memcpy ((void *) &tm_mtime, (void *) ptm, sizeof (struct tm));
8783- }
8784-#endif /* HAVE_LOCALTIME_R */
8785-
8786 g_date_set_time_t (&mtime, time_mtime);
8787 time_now = time (NULL);
8788 g_date_set_time_t (&now, time_now);
8789
8790 days_diff = g_date_get_julian (&now) - g_date_get_julian (&mtime);
8791
8792- /* Translators: %H means "hours" and %M means "minutes" */
8793 if (days_diff == 0)
8794- format = _("Today at %H:%M");
8795+ strcpy (buf, _("Today"));
8796 else if (days_diff == 1)
8797- format = _("Yesterday at %H:%M");
8798+ strcpy (buf, _("Yesterday"));
8799 else
8800 {
8801+ char *format;
8802+
8803 if (days_diff > 1 && days_diff < 7)
8804 format = "%A"; /* Days from last week */
8805 else
8806 format = "%x"; /* Any other date */
8807- }
8808
8809- locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL);
8810-
8811- if (strftime (buf, sizeof (buf), locale_format, &tm_mtime) != 0)
8812- date_str = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
8813- else
8814- date_str = g_strdup (_("Unknown"));
8815-
8816- g_free (locale_format);
8817+ if (g_date_strftime (buf, sizeof (buf), format, &mtime) == 0)
8818+ strcpy (buf, _("Unknown"));
8819+ }
8820 }
8821
8822+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8823+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8824+ sensitive = gtk_file_info_get_is_folder (info);
8825+
8826 g_object_set (cell,
8827- "text", date_str,
8828+ "text", buf,
8829 "sensitive", sensitive,
8830 NULL);
8831- g_free (date_str);
8832 }
8833
8834 GtkWidget *
8835@@ -11163,437 +4792,73 @@
8836 NULL);
8837 }
8838
8839+/* Handler for the "up-folder" keybinding signal */
8840 static void
8841-location_set_user_text (GtkFileChooserDefault *impl,
8842- const gchar *path)
8843+up_folder_handler (GtkFileChooserDefault *impl)
8844 {
8845- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), path);
8846- gtk_editable_set_position (GTK_EDITABLE (impl->location_entry), -1);
8847-}
8848+ GtkFilePath * parent;
8849+ pending_select_paths_add (impl, impl->current_folder);
8850
8851-static void
8852-location_popup_handler (GtkFileChooserDefault *impl,
8853- const gchar *path)
8854-{
8855- if (impl->operation_mode != OPERATION_MODE_BROWSE)
8856- {
8857- GtkWidget *widget_to_focus;
8858-
8859- /* This will give us the location widgets back */
8860- switch (impl->operation_mode)
8861- {
8862- case OPERATION_MODE_SEARCH:
8863- search_switch_to_browse_mode (impl);
8864- break;
8865- case OPERATION_MODE_RECENT:
8866- recent_switch_to_browse_mode (impl);
8867- break;
8868- case OPERATION_MODE_BROWSE:
8869- g_assert_not_reached ();
8870- break;
8871- }
8872+ if (gtk_file_system_get_parent (impl->file_system, impl->current_folder,
8873+ &parent, NULL) && parent)
8874+ {
8875+ impl->path_history = g_slist_prepend (impl->path_history,
8876+ gtk_file_path_copy (impl->current_folder));
8877
8878- if (impl->current_folder)
8879- change_folder_and_display_error (impl, impl->current_folder, FALSE);
8880-
8881- if (impl->location_mode == LOCATION_MODE_PATH_BAR)
8882- widget_to_focus = impl->browse_files_tree_view;
8883- else
8884- widget_to_focus = impl->location_entry;
8885-
8886- gtk_widget_grab_focus (widget_to_focus);
8887- return;
8888- }
8889-
8890- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8891- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
8892- {
8893- LocationMode new_mode;
8894-
8895- if (path != NULL)
8896- {
8897- /* since the user typed something, we unconditionally want to turn on the entry */
8898- new_mode = LOCATION_MODE_FILENAME_ENTRY;
8899- }
8900- else if (impl->location_mode == LOCATION_MODE_PATH_BAR)
8901- new_mode = LOCATION_MODE_FILENAME_ENTRY;
8902- else if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
8903- new_mode = LOCATION_MODE_PATH_BAR;
8904- else
8905- {
8906- g_assert_not_reached ();
8907- return;
8908- }
8909-
8910- location_mode_set (impl, new_mode, TRUE);
8911- if (new_mode == LOCATION_MODE_FILENAME_ENTRY)
8912- {
8913- if (path != NULL)
8914- location_set_user_text (impl, path);
8915- else
8916- {
8917- location_entry_set_initial_text (impl);
8918- gtk_editable_select_region (GTK_EDITABLE (impl->location_entry), 0, -1);
8919- }
8920- }
8921- }
8922- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
8923- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8924- {
8925- gtk_widget_grab_focus (impl->location_entry);
8926- if (path != NULL)
8927- location_set_user_text (impl, path);
8928- }
8929- else
8930- g_assert_not_reached ();
8931+ change_folder_and_display_error (impl, parent);
8932+ gtk_file_path_free (parent);
8933+ }
8934 }
8935
8936-/* Handler for the "up-folder" keybinding signal */
8937-static void
8938-up_folder_handler (GtkFileChooserDefault *impl)
8939-{
8940- _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar));
8941-}
8942-
8943 /* Handler for the "down-folder" keybinding signal */
8944 static void
8945 down_folder_handler (GtkFileChooserDefault *impl)
8946 {
8947- _gtk_path_bar_down (GTK_PATH_BAR (impl->browse_path_bar));
8948-}
8949+ if (impl->path_history)
8950+ {
8951+ GtkFilePath * path = impl->path_history->data;
8952
8953-/* Switches to the shortcut in the specified index */
8954-static void
8955-switch_to_shortcut (GtkFileChooserDefault *impl,
8956- int pos)
8957-{
8958- GtkTreeIter iter;
8959-
8960- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
8961- g_assert_not_reached ();
8962-
8963- shortcuts_activate_iter (impl, &iter);
8964- focus_browse_tree_view_if_possible (impl);
8965+ change_folder_and_display_error (impl, path);
8966+ impl->path_history = g_slist_remove (impl->path_history, path);
8967+ gtk_file_path_free (path);
8968+ }
8969 }
8970
8971 /* Handler for the "home-folder" keybinding signal */
8972 static void
8973 home_folder_handler (GtkFileChooserDefault *impl)
8974 {
8975- if (impl->has_home)
8976- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_HOME));
8977 }
8978
8979-/* Handler for the "desktop-folder" keybinding signal */
8980 static void
8981-desktop_folder_handler (GtkFileChooserDefault *impl)
8982-{
8983- if (impl->has_desktop)
8984- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_DESKTOP));
8985-}
8986-
8987-/* Handler for the "search-shortcut" keybinding signal */
8988-static void
8989-search_shortcut_handler (GtkFileChooserDefault *impl)
8990-{
8991- if (impl->has_search)
8992- {
8993- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_SEARCH));
8994-
8995- /* we want the entry widget to grab the focus the first
8996- * time, not the browse_files_tree_view widget.
8997- */
8998- if (impl->search_entry)
8999- gtk_widget_grab_focus (impl->search_entry);
9000- }
9001-}
9002-
9003-/* Handler for the "recent-shortcut" keybinding signal */
9004-static void
9005-recent_shortcut_handler (GtkFileChooserDefault *impl)
9006-{
9007- if (impl->has_recent)
9008- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_RECENT));
9009-}
9010-
9011-static void
9012-quick_bookmark_handler (GtkFileChooserDefault *impl,
9013- gint bookmark_index)
9014-{
9015- int bookmark_pos;
9016- GtkTreePath *path;
9017-
9018- if (bookmark_index < 0 || bookmark_index >= impl->num_bookmarks)
9019- return;
9020-
9021- bookmark_pos = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS) + bookmark_index;
9022-
9023- path = gtk_tree_path_new_from_indices (bookmark_pos, -1);
9024- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
9025- path, NULL,
9026- FALSE, 0.0, 0.0);
9027- gtk_tree_path_free (path);
9028-
9029- switch_to_shortcut (impl, bookmark_pos);
9030-}
9031-
9032-static void
9033 show_hidden_handler (GtkFileChooserDefault *impl)
9034 {
9035- g_object_set (impl,
9036- "show-hidden", !impl->show_hidden,
9037- NULL);
9038 }
9039
9040-
9041-/* Drag and drop interfaces */
9042-
9043-static void
9044-_shortcuts_pane_model_filter_class_init (ShortcutsPaneModelFilterClass *class)
9045+static GtkFilePath *
9046+gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser)
9047 {
9048+ return NULL;
9049 }
9050
9051-static void
9052-_shortcuts_pane_model_filter_init (ShortcutsPaneModelFilter *model)
9053-{
9054- model->impl = NULL;
9055-}
9056-
9057-/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */
9058 static gboolean
9059-shortcuts_pane_model_filter_row_draggable (GtkTreeDragSource *drag_source,
9060- GtkTreePath *path)
9061+gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser,
9062+ const GtkFilePath *path,
9063+ GError **error)
9064 {
9065- ShortcutsPaneModelFilter *model;
9066- int pos;
9067- int bookmarks_pos;
9068-
9069- model = SHORTCUTS_PANE_MODEL_FILTER (drag_source);
9070-
9071- pos = *gtk_tree_path_get_indices (path);
9072- bookmarks_pos = shortcuts_get_index (model->impl, SHORTCUTS_BOOKMARKS);
9073-
9074- return (pos >= bookmarks_pos && pos < bookmarks_pos + model->impl->num_bookmarks);
9075-}
9076-
9077-/* GtkTreeDragSource::drag_data_get implementation for the shortcuts filter model */
9078-static gboolean
9079-shortcuts_pane_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
9080- GtkTreePath *path,
9081- GtkSelectionData *selection_data)
9082-{
9083- ShortcutsPaneModelFilter *model;
9084-
9085- model = SHORTCUTS_PANE_MODEL_FILTER (drag_source);
9086-
9087- /* FIXME */
9088-
9089- return FALSE;
9090-}
9091-
9092-/* Fill the GtkTreeDragSourceIface vtable */
9093-static void
9094-shortcuts_pane_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface)
9095-{
9096- iface->row_draggable = shortcuts_pane_model_filter_row_draggable;
9097- iface->drag_data_get = shortcuts_pane_model_filter_drag_data_get;
9098-}
9099-
9100-#if 0
9101-/* Fill the GtkTreeDragDestIface vtable */
9102-static void
9103-shortcuts_pane_model_filter_drag_dest_iface_init (GtkTreeDragDestIface *iface)
9104-{
9105- iface->drag_data_received = shortcuts_pane_model_filter_drag_data_received;
9106- iface->row_drop_possible = shortcuts_pane_model_filter_row_drop_possible;
9107-}
9108-#endif
9109-
9110-static GtkTreeModel *
9111-shortcuts_pane_model_filter_new (GtkFileChooserDefault *impl,
9112- GtkTreeModel *child_model,
9113- GtkTreePath *root)
9114-{
9115- ShortcutsPaneModelFilter *model;
9116-
9117- model = g_object_new (SHORTCUTS_PANE_MODEL_FILTER_TYPE,
9118- "child-model", child_model,
9119- "virtual-root", root,
9120- NULL);
9121-
9122- model->impl = impl;
9123-
9124- return GTK_TREE_MODEL (model);
9125-}
9126-
9127-
9128-
9129-static gboolean
9130-recent_model_sort_row_draggable (GtkTreeDragSource *drag_source,
9131- GtkTreePath *path)
9132-{
9133- RecentModelSort *model;
9134- GtkTreeIter iter, child_iter;
9135- gboolean is_folder;
9136-
9137- model = RECENT_MODEL_SORT (drag_source);
9138- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9139 return FALSE;
9140-
9141- recent_get_valid_child_iter (model->impl, &child_iter, &iter);
9142- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->recent_model), &child_iter,
9143- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
9144- -1);
9145-
9146- return is_folder;
9147 }
9148
9149 static gboolean
9150-recent_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
9151- GtkTreePath *path,
9152- GtkSelectionData *selection_data)
9153+gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser,
9154+ const GtkFilePath *path,
9155+ GError **error)
9156 {
9157- RecentModelSort *model;
9158- GtkTreeIter iter, child_iter;
9159- GtkFilePath *file_path;
9160- gchar **uris;
9161-
9162- model = RECENT_MODEL_SORT (drag_source);
9163- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9164- return FALSE;
9165-
9166- recent_get_valid_child_iter (model->impl, &child_iter, &iter);
9167- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->recent_model), &child_iter,
9168- RECENT_MODEL_COL_PATH, &file_path,
9169- -1);
9170- g_assert (file_path != NULL);
9171-
9172- uris = g_new (gchar *, 2);
9173- uris[0] = gtk_file_system_path_to_uri (model->impl->file_system, file_path);
9174- uris[1] = NULL;
9175-
9176- gtk_selection_data_set_uris (selection_data, uris);
9177-
9178- g_strfreev (uris);
9179-
9180- return TRUE;
9181+ return TRUE;
9182 }
9183
9184-static void
9185-recent_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface)
9186+static GSList *
9187+gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
9188 {
9189- iface->row_draggable = recent_model_sort_row_draggable;
9190- iface->drag_data_get = recent_model_sort_drag_data_get;
9191+ return NULL;
9192 }
9193-
9194-static void
9195-_recent_model_sort_class_init (RecentModelSortClass *klass)
9196-{
9197-
9198-}
9199-
9200-static void
9201-_recent_model_sort_init (RecentModelSort *model)
9202-{
9203- model->impl = NULL;
9204-}
9205-
9206-static GtkTreeModel *
9207-recent_model_sort_new (GtkFileChooserDefault *impl,
9208- GtkTreeModel *child_model)
9209-{
9210- RecentModelSort *model;
9211-
9212- model = g_object_new (RECENT_MODEL_SORT_TYPE,
9213- "model", child_model,
9214- NULL);
9215- model->impl = impl;
9216-
9217- return GTK_TREE_MODEL (model);
9218-}
9219-
9220-
9221-
9222-static gboolean
9223-search_model_sort_row_draggable (GtkTreeDragSource *drag_source,
9224- GtkTreePath *path)
9225-{
9226- SearchModelSort *model;
9227- GtkTreeIter iter, child_iter;
9228- gboolean is_folder;
9229-
9230- model = SEARCH_MODEL_SORT (drag_source);
9231- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9232- return FALSE;
9233-
9234- search_get_valid_child_iter (model->impl, &child_iter, &iter);
9235- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->search_model), &child_iter,
9236- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
9237- -1);
9238-
9239- return is_folder;
9240-}
9241-
9242-static gboolean
9243-search_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
9244- GtkTreePath *path,
9245- GtkSelectionData *selection_data)
9246-{
9247- SearchModelSort *model;
9248- GtkTreeIter iter, child_iter;
9249- GtkFilePath *file_path;
9250- gchar **uris;
9251-
9252- model = SEARCH_MODEL_SORT (drag_source);
9253- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9254- return FALSE;
9255-
9256- search_get_valid_child_iter (model->impl, &child_iter, &iter);
9257- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->search_model), &child_iter,
9258- RECENT_MODEL_COL_PATH, &file_path,
9259- -1);
9260- g_assert (file_path != NULL);
9261-
9262- uris = g_new (gchar *, 2);
9263- uris[0] = gtk_file_system_path_to_uri (model->impl->file_system, file_path);
9264- uris[1] = NULL;
9265-
9266- gtk_selection_data_set_uris (selection_data, uris);
9267-
9268- g_strfreev (uris);
9269-
9270- return TRUE;
9271-}
9272-
9273-static void
9274-search_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface)
9275-{
9276- iface->row_draggable = search_model_sort_row_draggable;
9277- iface->drag_data_get = search_model_sort_drag_data_get;
9278-}
9279-
9280-static void
9281-_search_model_sort_class_init (SearchModelSortClass *klass)
9282-{
9283-
9284-}
9285-
9286-static void
9287-_search_model_sort_init (SearchModelSort *model)
9288-{
9289- model->impl = NULL;
9290-}
9291-
9292-static GtkTreeModel *
9293-search_model_sort_new (GtkFileChooserDefault *impl,
9294- GtkTreeModel *child_model)
9295-{
9296- SearchModelSort *model;
9297-
9298- model = g_object_new (SEARCH_MODEL_SORT_TYPE,
9299- "model", child_model,
9300- NULL);
9301- model->impl = impl;
9302-
9303- return GTK_TREE_MODEL (model);
9304-}
9305Index: gtk+-2.12.5/gtk/gtkfilechooserprivate.h
9306===================================================================
9307--- gtk+-2.12.5/gtk/gtkfilechooserprivate.h (revision 19337)
9308+++ gtk+-2.12.5/gtk/gtkfilechooserprivate.h (working copy)
9309@@ -25,9 +25,6 @@
9310 #include "gtkfilesystem.h"
9311 #include "gtkfilesystemmodel.h"
9312 #include "gtkliststore.h"
9313-#include "gtkrecentmanager.h"
9314-#include "gtksearchengine.h"
9315-#include "gtkquery.h"
9316 #include "gtktooltips.h"
9317 #include "gtktreemodelsort.h"
9318 #include "gtktreestore.h"
9319@@ -146,12 +143,6 @@
9320 LOCATION_MODE_FILENAME_ENTRY
9321 } LocationMode;
9322
9323-typedef enum {
9324- OPERATION_MODE_BROWSE,
9325- OPERATION_MODE_SEARCH,
9326- OPERATION_MODE_RECENT
9327-} OperationMode;
9328-
9329 struct _GtkFileChooserDefault
9330 {
9331 GtkVBox parent_instance;
9332@@ -162,53 +153,19 @@
9333
9334 /* Save mode widgets */
9335 GtkWidget *save_widgets;
9336+ GtkWidget *save_file_name_entry;
9337
9338- GtkWidget *save_folder_label;
9339- GtkWidget *save_folder_combo;
9340- GtkWidget *save_expander;
9341-
9342 /* The file browsing widgets */
9343 GtkWidget *browse_widgets;
9344- GtkWidget *browse_shortcuts_tree_view;
9345- GtkWidget *browse_shortcuts_add_button;
9346- GtkWidget *browse_shortcuts_remove_button;
9347- GtkWidget *browse_shortcuts_popup_menu;
9348- GtkWidget *browse_shortcuts_popup_menu_remove_item;
9349- GtkWidget *browse_shortcuts_popup_menu_rename_item;
9350 GtkWidget *browse_files_tree_view;
9351- GtkWidget *browse_files_popup_menu;
9352- GtkWidget *browse_files_popup_menu_add_shortcut_item;
9353- GtkWidget *browse_files_popup_menu_hidden_files_item;
9354 GtkWidget *browse_new_folder_button;
9355- GtkWidget *browse_path_bar_hbox;
9356- GtkWidget *browse_path_bar;
9357+ GtkWidget *bar;
9358+ GtkWidget *up_button;
9359
9360 GtkFileSystemModel *browse_files_model;
9361- char *browse_files_last_selected_name;
9362+ char *browse_files_last_selected_name; /* ??? */
9363
9364- /* OPERATION_MODE_SEARCH */
9365- GtkWidget *search_hbox;
9366- GtkWidget *search_entry;
9367- GtkSearchEngine *search_engine;
9368- GtkQuery *search_query;
9369- GtkListStore *search_model;
9370- GtkTreeModelFilter *search_model_filter;
9371- GtkTreeModelSort *search_model_sort;
9372-
9373- /* OPERATION_MODE_RECENT */
9374- GtkRecentManager *recent_manager;
9375- GtkListStore *recent_model;
9376- guint load_recent_id;
9377- GtkTreeModelFilter *recent_model_filter;
9378- GtkTreeModelSort *recent_model_sort;
9379-
9380- GtkWidget *filter_combo_hbox;
9381 GtkWidget *filter_combo;
9382- GtkWidget *preview_box;
9383- GtkWidget *preview_label;
9384- GtkWidget *preview_widget;
9385- GtkWidget *extra_align;
9386- GtkWidget *extra_widget;
9387
9388 GtkWidget *location_button;
9389 GtkWidget *location_entry_box;
9390@@ -217,23 +174,13 @@
9391 LocationMode location_mode;
9392
9393 GtkListStore *shortcuts_model;
9394+ GtkTreeModel *shortcuts_filter_model;
9395
9396- /* Filter for the shortcuts pane. We filter out the "current folder" row and
9397- * the separator that we use for the "Save in folder" combo.
9398- */
9399- GtkTreeModel *shortcuts_pane_filter_model;
9400-
9401- /* Filter for the "Save in folder" combo. We filter out the Search row and
9402- * its separator.
9403- */
9404- GtkTreeModel *shortcuts_combo_filter_model;
9405-
9406 GtkTreeModelSort *sort_model;
9407
9408 /* Handles */
9409 GSList *loading_shortcuts;
9410 GSList *reload_icon_handles;
9411- GtkFileSystemHandle *file_list_drag_data_received_handle;
9412 GtkFileSystemHandle *update_current_folder_handle;
9413 GtkFileSystemHandle *show_and_select_paths_handle;
9414 GtkFileSystemHandle *should_respond_get_info_handle;
9415@@ -246,9 +193,8 @@
9416 ReloadState reload_state;
9417 guint load_timeout_id;
9418
9419- OperationMode operation_mode;
9420-
9421 GSList *pending_select_paths;
9422+ GSList *path_history;
9423
9424 GtkFileFilter *current_filter;
9425 GSList *filters;
9426@@ -256,20 +202,16 @@
9427 GtkTooltips *tooltips;
9428
9429 int num_volumes;
9430- int num_shortcuts;
9431- int num_bookmarks;
9432
9433 gulong volumes_changed_id;
9434- gulong bookmarks_changed_id;
9435
9436 GtkFilePath *current_volume_path;
9437 GtkFilePath *current_folder;
9438- GtkFilePath *preview_path;
9439- char *preview_display_name;
9440
9441 GtkTreeViewColumn *list_name_column;
9442 GtkCellRenderer *list_name_renderer;
9443- GtkTreeViewColumn *list_mtime_column;
9444+ guint32 list_press_time;
9445+ GtkTreePath *list_press_path;
9446
9447 GSource *edited_idle;
9448 char *edited_new_text;
9449@@ -280,10 +222,7 @@
9450 gulong toplevel_set_focus_id;
9451 GtkWidget *toplevel_last_focus_widget;
9452
9453-#if 0
9454- GdkDragContext *shortcuts_drag_context;
9455- GSource *shortcuts_drag_outside_idle;
9456-#endif
9457+ gchar * root_folder;
9458
9459 gint default_width;
9460 gint default_height;
9461@@ -291,23 +230,13 @@
9462 /* Flags */
9463
9464 guint local_only : 1;
9465- guint preview_widget_active : 1;
9466- guint use_preview_label : 1;
9467 guint select_multiple : 1;
9468 guint show_hidden : 1;
9469+ guint show_create_folder : 1;
9470 guint do_overwrite_confirmation : 1;
9471 guint list_sort_ascending : 1;
9472 guint changing_folder : 1;
9473- guint shortcuts_current_folder_active : 1;
9474 guint expand_folders : 1;
9475- guint has_home : 1;
9476- guint has_desktop : 1;
9477- guint has_search : 1;
9478- guint has_recent : 1;
9479-
9480-#if 0
9481- guint shortcuts_drag_outside : 1;
9482-#endif
9483 };
9484
9485
9486Index: gtk+-2.12.5/tests/autotestfilechooser.c
9487===================================================================
9488--- gtk+-2.12.5/tests/autotestfilechooser.c (revision 19337)
9489+++ gtk+-2.12.5/tests/autotestfilechooser.c (working copy)
9490@@ -510,9 +510,6 @@
9491 && (impl->location_mode == LOCATION_MODE_PATH_BAR
9492 ? impl->location_entry == NULL
9493 : impl->location_entry != NULL)
9494- && impl->save_folder_label == NULL
9495- && impl->save_folder_combo == NULL
9496- && impl->save_expander == NULL
9497 && GTK_IS_CONTAINER (impl->browse_widgets) && GTK_WIDGET_DRAWABLE (impl->browse_widgets));
9498 }
9499 else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action))
9500@@ -523,9 +520,6 @@
9501 */
9502 passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && GTK_WIDGET_DRAWABLE (impl->save_widgets)
9503 && impl->location_entry != NULL && GTK_WIDGET_DRAWABLE (impl->location_entry)
9504- && GTK_IS_LABEL (impl->save_folder_label) && GTK_WIDGET_DRAWABLE (impl->save_folder_label)
9505- && GTK_IS_COMBO_BOX (impl->save_folder_combo) && GTK_WIDGET_DRAWABLE (impl->save_folder_combo)
9506- && GTK_IS_EXPANDER (impl->save_expander) && GTK_WIDGET_DRAWABLE (impl->save_expander)
9507 && GTK_IS_CONTAINER (impl->browse_widgets));
9508
9509 /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of
9510@@ -1026,11 +1020,6 @@
9511 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
9512 sleep_in_main_loop (500);
9513
9514- g_signal_emit_by_name (impl->browse_path_bar, "path-clicked",
9515- (GtkFilePath *) cwd_path,
9516- (GtkFilePath *) base_dir_path,
9517- FALSE);
9518- sleep_in_main_loop (500);
9519 passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
9520
9521 log_test (passed, "test_folder_switch_and_filters(): filter after changing folder");
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-props.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-props.patch
new file mode 100644
index 0000000000..7d55f3cbb9
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-props.patch
@@ -0,0 +1,57 @@
1Index: gtk+-2.12.3/gtk/gtkfilechooser.c
2===================================================================
3--- gtk+-2.12.3.orig/gtk/gtkfilechooser.c 2007-12-04 16:52:08.000000000 +0000
4+++ gtk+-2.12.3/gtk/gtkfilechooser.c 2008-01-02 13:15:38.000000000 +0000
5@@ -272,6 +272,20 @@
6 "if necessary."),
7 FALSE,
8 GTK_PARAM_READWRITE));
9+
10+ g_object_interface_install_property (g_iface,
11+ g_param_spec_string ("root-folder",
12+ P_("File System Root"),
13+ P_("Root folder for the file system below which the user should not be able to switch"),
14+ NULL,
15+ G_PARAM_WRITABLE));
16+
17+ g_object_interface_install_property (g_iface,
18+ g_param_spec_boolean ("show-create-folder",
19+ P_("Show Create Folder button"),
20+ P_("Whether the Create Folder button should be visible on the bar"),
21+ TRUE,
22+ G_PARAM_READWRITE));
23 }
24
25 /**
26Index: gtk+-2.12.3/gtk/gtkfilechooserutils.h
27===================================================================
28--- gtk+-2.12.3.orig/gtk/gtkfilechooserutils.h 2007-12-04 16:52:08.000000000 +0000
29+++ gtk+-2.12.3/gtk/gtkfilechooserutils.h 2008-01-02 13:15:17.000000000 +0000
30@@ -41,7 +41,9 @@
31 GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
32 GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN,
33 GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION,
34- GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION
35+ GTK_FILE_CHOOSER_PROP_ROOT_FOLDER,
36+ GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER,
37+ GTK_FILE_CHOOSER_PROP_LAST = GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER
38 } GtkFileChooserProp;
39
40 void _gtk_file_chooser_install_properties (GObjectClass *klass);
41Index: gtk+-2.12.3/gtk/gtkfilechooserutils.c
42===================================================================
43--- gtk+-2.12.3.orig/gtk/gtkfilechooserutils.c 2007-12-04 16:52:08.000000000 +0000
44+++ gtk+-2.12.3/gtk/gtkfilechooserutils.c 2008-01-02 13:15:17.000000000 +0000
45@@ -117,6 +117,12 @@
46 g_object_class_override_property (klass,
47 GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION,
48 "do-overwrite-confirmation");
49+ g_object_class_override_property (klass,
50+ GTK_FILE_CHOOSER_PROP_ROOT_FOLDER,
51+ "root-folder");
52+ g_object_class_override_property (klass,
53+ GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER,
54+ "show-create-folder");
55 }
56
57 /**
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-sizefix.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-sizefix.patch
new file mode 100644
index 0000000000..694b059b9a
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-sizefix.patch
@@ -0,0 +1,35 @@
1--- gtk+-2.12.7.orig/gtk/gtkfilechooserdialog.c
2+++ gtk+-2.12.7/gtk/gtkfilechooserdialog.c
3@@ -165,10 +165,10 @@
4 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5
6 if (width)
7- *width = MIN (*width, (monitor.width * 3) / 4);
8+ *width = MIN (*width, monitor.width);
9
10 if (height)
11- *height = MIN (*height, (monitor.height * 3) / 4);
12+ *height = MIN (*height, monitor.height);
13 }
14
15 static void
16@@ -183,6 +183,7 @@
17
18 priv = GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE (dialog);
19
20+#if 0
21 /* Unset any previously set size */
22 gtk_widget_set_size_request (GTK_WIDGET (dialog), -1, -1);
23
24@@ -209,6 +210,11 @@
25 /* Ideal target size plus any extra size */
26 width = default_width + width + (2 * GTK_CONTAINER (dialog)->border_width);
27 height = default_height + height + (2 * GTK_CONTAINER (dialog)->border_width);
28+#endif
29+
30+ /* for small screens we just hard code a sensible value */
31+ width = 350;
32+ height = 350;
33
34 if (GTK_WIDGET_REALIZED (dialog))
35 clamp_to_screen (GTK_WIDGET (dialog), &width, &height);
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/filesystem-volumes.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filesystem-volumes.patch
new file mode 100644
index 0000000000..826fd6bee0
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filesystem-volumes.patch
@@ -0,0 +1,198 @@
1Index: gtk+-2.12.3/gtk/gtkfilesystemunix.c
2===================================================================
3--- gtk+-2.12.3.orig/gtk/gtkfilesystemunix.c 2007-12-04 16:52:08.000000000 +0000
4+++ gtk+-2.12.3/gtk/gtkfilesystemunix.c 2008-01-02 13:15:02.000000000 +0000
5@@ -38,6 +38,7 @@
6 #include <errno.h>
7 #include <string.h>
8 #include <sys/stat.h>
9+#include <sys/statvfs.h>
10 #include <sys/types.h>
11 #include <pwd.h>
12 #ifdef HAVE_UNISTD_H
13@@ -474,7 +475,55 @@
14 static GSList *
15 gtk_file_system_unix_list_volumes (GtkFileSystem *file_system)
16 {
17- return g_slist_append (NULL, get_root_volume ());
18+ struct statvfs stv;
19+ struct stat st;
20+ GSList * l = g_slist_append (NULL, get_root_volume ());
21+
22+ if (!statvfs ("/.", &stv))
23+ {
24+ fsblkcnt_t root_blocks = stv.f_blocks;
25+ fsfilcnt_t root_files = stv.f_files;
26+
27+ GDir * dir;
28+ if ((dir = g_dir_open ("/media", 0, NULL)) != NULL)
29+ {
30+ const gchar * name;
31+ while ((name = g_dir_read_name (dir)) != NULL)
32+ {
33+ gchar * abs_name;
34+
35+ /* Skip ram disks */
36+ if (!strcmp (name, "ram"))
37+ continue;
38+
39+ abs_name = g_strconcat ("/media/", name, NULL);
40+
41+ if (!stat (abs_name, &st) && S_ISDIR (st.st_mode))
42+ {
43+ gchar * dot = g_strconcat (abs_name, "/.", NULL);
44+ if (!statvfs (dot, &stv) &&
45+ (stv.f_blocks != root_blocks ||
46+ stv.f_files != root_files))
47+ {
48+ GtkFilePath * path =
49+ gtk_file_system_filename_to_path (file_system,
50+ abs_name);
51+
52+ if (path)
53+ l = g_slist_append (l, path);
54+ }
55+
56+ g_free (dot);
57+ }
58+
59+ g_free (abs_name);
60+ }
61+
62+ g_dir_close (dir);
63+ }
64+ }
65+
66+ return l;
67 }
68
69 static GtkFileSystemVolume *
70@@ -488,13 +537,18 @@
71 remove_trailing_slash (const char *filename)
72 {
73 int len;
74-
75+
76 len = strlen (filename);
77
78- if (len > 1 && filename[len - 1] == '/')
79- return g_strndup (filename, len - 1);
80- else
81- return g_memdup (filename, len + 1);
82+ if (len > 1)
83+ {
84+ gchar *c = g_utf8_prev_char (filename + len);
85+
86+ if (c && *c == '/')
87+ return g_strndup (filename, len - 1);
88+ }
89+
90+ return g_memdup (filename, len + 1);
91 }
92
93 /* Delay callback dispatching
94@@ -1128,7 +1182,7 @@
95 gtk_file_system_unix_volume_get_base_path (GtkFileSystem *file_system,
96 GtkFileSystemVolume *volume)
97 {
98- return gtk_file_path_new_dup ("/");
99+ return gtk_file_path_copy ((GtkFilePath*)volume);
100 }
101
102 static gboolean
103@@ -1162,7 +1216,32 @@
104 gtk_file_system_unix_volume_get_display_name (GtkFileSystem *file_system,
105 GtkFileSystemVolume *volume)
106 {
107- return g_strdup (_("File System")); /* Same as Nautilus */
108+ gchar * slash;
109+ gchar * path;
110+ gchar * c;
111+
112+ g_return_val_if_fail (file_system && volume, NULL);
113+
114+ path = gtk_file_system_path_to_filename (file_system, (GtkFilePath*) volume);
115+
116+ g_return_val_if_fail (path && *path, NULL);
117+
118+ if (path[0] == '/' && !path[1])
119+ return g_strdup (_("Filesystem")); /* Same as Nautilus */
120+
121+ /* Now the media volumes */
122+ /* strip trailing / if any */
123+ c = g_utf8_prev_char (path + strlen(path));
124+
125+ if (*c == '/')
126+ *c = 0;
127+
128+ slash = g_utf8_strrchr (path, -1, '/');
129+
130+ if (!slash)
131+ return g_strdup (path);
132+
133+ return g_strdup (slash + 1);
134 }
135
136 static IconType
137@@ -1250,10 +1329,57 @@
138 GtkFileSystemVolume *volume,
139 GError **error)
140 {
141- /* FIXME: maybe we just always want to return GTK_STOCK_HARDDISK here?
142- * or the new tango icon name?
143- */
144- return g_strdup ("gnome-dev-harddisk");
145+ gchar * c;
146+ gchar * slash;
147+ gchar * path = NULL;
148+ GtkFilePath * fpath;
149+ const gchar * id = NULL;
150+
151+ g_return_val_if_fail (file_system && volume, NULL);
152+
153+ fpath = gtk_file_system_volume_get_base_path (file_system, volume);
154+
155+ if (!fpath)
156+ goto out;
157+
158+ path = gtk_file_system_path_to_filename (file_system, fpath);
159+ gtk_file_path_free (fpath);
160+
161+ if (!path || !*path || (*path == '/' && !path[1]))
162+ goto out;
163+
164+ /* Now the media volumes */
165+ /* strip trailing / if any */
166+ c = g_utf8_prev_char (path + strlen(path));
167+
168+ if (*c == '/')
169+ *c = 0;
170+
171+ slash = g_utf8_strrchr (path, -1, '/');
172+
173+ if (slash)
174+ {
175+ slash++;
176+
177+ if (!strcmp (slash, "card"))
178+ id = "gnome-dev-media-sdmmc";
179+ else if (!strcmp (slash, "cf"))
180+ id = "gnome-dev-media-cf";
181+ else if (!strncmp (slash, "mmc", 3))
182+ id = "gnome-dev-media-sdmmc";
183+ else if (!strcmp (slash, "usbhdd"))
184+ id = "gnome-dev-removable-usb";
185+ else
186+ id = "gnome-dev-removable";
187+ }
188+
189+ out:
190+ g_free (path);
191+
192+ if (!id)
193+ id = "gnome-fs-blockdev";
194+
195+ return g_strdup (id);
196 }
197
198 static char *
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/gtklabel-resize-patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/gtklabel-resize-patch
new file mode 100644
index 0000000000..df29656343
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/gtklabel-resize-patch
@@ -0,0 +1,10 @@
1--- gtk+-2.4.3/gtk/gtklabel.c~ 2004-06-11 13:50:34.000000000 +0100
2+++ gtk+-2.4.3/gtk/gtklabel.c 2004-07-05 13:33:57.000000000 +0100
3@@ -1623,6 +1623,7 @@
4
5 /* We have to clear the layout, fonts etc. may have changed */
6 gtk_label_clear_layout (label);
7+ gtk_widget_queue_resize (GTK_WIDGET (label));
8 }
9
10 static void
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/hardcoded_libtool.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/hardcoded_libtool.patch
new file mode 100644
index 0000000000..1c2cd0576d
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/hardcoded_libtool.patch
@@ -0,0 +1,29 @@
1--- /tmp/configure.in 2007-01-08 17:50:49.000000000 +0100
2+++ gtk+-2.10.7/configure.in 2007-01-08 17:52:33.495251000 +0100
3@@ -371,7 +371,7 @@
4 case $enable_explicit_deps in
5 auto)
6 export SED
7- deplibs_check_method=`(./libtool --config; echo 'eval echo $deplibs_check_method') | sh`
8+ deplibs_check_method=`($host_alias-libtool --config; echo 'eval echo $deplibs_check_method') | sh`
9 if test "x$deplibs_check_method" '!=' xpass_all || test "x$enable_static" = xyes ; then
10 enable_explicit_deps=yes
11 else
12@@ -773,7 +773,7 @@
13 dnl Now we check to see if our libtool supports shared lib deps
14 dnl (in a rather ugly way even)
15 if $dynworks; then
16- pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} ./libtool --config"
17+ pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} $host_alias-libtool --config"
18 pixbuf_deplibs_check=`$pixbuf_libtool_config | \
19 grep '^[[a-z_]]*check[[a-z_]]*_method=[['\''"]]' | \
20 sed 's/.*[['\''"]]\(.*\)[['\''"]]$/\1/'`
21@@ -1611,7 +1611,7 @@
22 # We are using gmodule-no-export now, but I'm leaving the stripping
23 # code in place for now, since pango and atk still require gmodule.
24 export SED
25-export_dynamic=`(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`
26+export_dynamic=`($host_alias-libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`
27 if test -n "$export_dynamic"; then
28 GDK_PIXBUF_DEP_LIBS=`echo $GDK_PIXBUF_DEP_LIBS | sed -e "s/$export_dynamic//"`
29 GDK_PIXBUF_XLIB_DEP_LIBS=`echo $GDK_PIXBUF_XLIB_DEP_LIBS | sed -e "s/$export_dynamic//"`
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/menu-deactivate.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/menu-deactivate.patch
new file mode 100644
index 0000000000..cfb8849e9f
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/menu-deactivate.patch
@@ -0,0 +1,51 @@
1--- gtk+-2.10.0/gtk/gtkmenushell.c.orig 2006-07-05 17:17:34.000000000 +0200
2+++ gtk+-2.10.0/gtk/gtkmenushell.c 2006-07-05 17:19:01.000000000 +0200
3@@ -42,7 +42,7 @@
4 #include "gtkintl.h"
5 #include "gtkalias.h"
6
7-#define MENU_SHELL_TIMEOUT 500
8+#define MENU_SHELL_TIMEOUT 2000
9
10 #define PACK_DIRECTION(m) \
11 (GTK_IS_MENU_BAR (m) \
12@@ -203,6 +203,8 @@
13
14 G_DEFINE_TYPE (GtkMenuShell, gtk_menu_shell, GTK_TYPE_CONTAINER)
15
16+static int last_crossing_time;
17+
18 static void
19 gtk_menu_shell_class_init (GtkMenuShellClass *klass)
20 {
21@@ -517,6 +519,7 @@
22 gtk_grab_add (GTK_WIDGET (menu_shell));
23 menu_shell->have_grab = TRUE;
24 menu_shell->active = TRUE;
25+ last_crossing_time = 0;
26 }
27 }
28
29@@ -669,6 +672,13 @@
30 menu_shell->activate_time = 0;
31 deactivate = FALSE;
32 }
33+
34+ if (last_crossing_time != 0
35+ && ((event->time - last_crossing_time) < 500))
36+ {
37+ last_crossing_time = 0;
38+ deactivate = FALSE;
39+ }
40
41 if (deactivate)
42 {
43@@ -716,6 +726,8 @@
44 {
45 menu_item = gtk_get_event_widget ((GdkEvent*) event);
46
47+ last_crossing_time = event->time;
48+
49 if (!menu_item ||
50 (GTK_IS_MENU_ITEM (menu_item) &&
51 !_gtk_menu_item_is_selectable (menu_item)))
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/no-demos.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/no-demos.patch
new file mode 100644
index 0000000000..0fc4c48d1a
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/no-demos.patch
@@ -0,0 +1,10 @@
1--- gtk+-2.10.1/Makefile.am.orig 2006-08-08 12:37:30.000000000 +0100
2+++ gtk+-2.10.1/Makefile.am 2006-08-08 12:37:48.000000000 +0100
3@@ -1,6 +1,6 @@
4 ## Makefile.am for GTK+
5
6-SRC_SUBDIRS = gdk-pixbuf gdk gtk modules demos tests perf contrib
7+SRC_SUBDIRS = gdk-pixbuf gdk gtk modules tests perf contrib
8 SUBDIRS = po po-properties $(SRC_SUBDIRS) docs m4macros
9
10 # require automake 1.4
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/pangoxft2.10.6.diff b/meta/recipes-gnome/gtk+/gtk+-2.12.7/pangoxft2.10.6.diff
new file mode 100644
index 0000000000..63828cec63
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/pangoxft2.10.6.diff
@@ -0,0 +1,2456 @@
1http://mail.gnome.org/archives/performance-list/2006-October/msg00063.html
2
3From: Xan Lópe
4To: ext Matt Hoosier
5Cc: performance-list gnome org
6Subject: Re: [patch] Remove pangocairo from Gtk+ 2.8.20
7Date: Mon, 30 Oct 2006 14:31:56 +0200
8Hi,
9
10I've upgraded your patch against GTK+ 2.10.6, and we are getting great
11performance figures compared to GTK+ 2.10.6 with pangocairo too
12(basically at the level of GTK+ 2.6.10 again). Right now I'm working on
13a python/cairo script to get some nice graphics from a torture test
14session with several GTK+s, hope to get it ready soon.
15
16Index: gtk+-2.10.6/configure.in
17===================================================================
18--- gtk+-2.10.6.orig/configure.in 2006-10-30 12:59:28.000000000 +0000
19+++ gtk+-2.10.6/configure.in 2006-10-30 12:59:30.000000000 +0000
20@@ -1435,7 +1435,7 @@
21 if test "x$gdktarget" = "xwin32"; then
22 PANGO_PACKAGES="pangowin32 pangocairo"
23 else
24- PANGO_PACKAGES="pango pangocairo"
25+ PANGO_PACKAGES="pango pangocairo pangoxft"
26 fi
27
28 AC_MSG_CHECKING(Pango flags)
29Index: gtk+-2.10.6/gdk/gdkaliasdef.c
30===================================================================
31--- gtk+-2.10.6.orig/gdk/gdkaliasdef.c 2006-10-30 12:58:29.000000000 +0000
32+++ gtk+-2.10.6/gdk/gdkaliasdef.c 2006-10-30 12:59:30.000000000 +0000
33@@ -1799,9 +1799,6 @@
34 #undef gdk_pango_context_get
35 extern __typeof (gdk_pango_context_get) gdk_pango_context_get __attribute((alias("IA__gdk_pango_context_get"), visibility("default")));
36
37-#undef gdk_pango_context_get_for_screen
38-extern __typeof (gdk_pango_context_get_for_screen) gdk_pango_context_get_for_screen __attribute((alias("IA__gdk_pango_context_get_for_screen"), visibility("default")));
39-
40 #ifndef GDK_DISABLE_DEPRECATED
41 #undef gdk_pango_context_set_colormap
42 extern __typeof (gdk_pango_context_set_colormap) gdk_pango_context_set_colormap __attribute((alias("IA__gdk_pango_context_set_colormap"), visibility("default")));
43@@ -1836,6 +1833,13 @@
44
45 #endif
46 #endif
47+#if IN_HEADER(__GDK_PANGO_H__)
48+#if IN_FILE(__GDK_PANGO_X11_C__)
49+#undef gdk_pango_context_get_for_screen
50+extern __typeof (gdk_pango_context_get_for_screen) gdk_pango_context_get_for_screen __attribute((alias("IA__gdk_pango_context_get_for_screen"), visibility("default")));
51+
52+#endif
53+#endif
54 #if IN_HEADER(__GDK_PIXBUF_H__)
55 #if IN_FILE(__GDK_PIXBUF_DRAWABLE_C__)
56 #undef gdk_pixbuf_get_from_drawable
57Index: gtk+-2.10.6/gdk/gdkalias.h
58===================================================================
59--- gtk+-2.10.6.orig/gdk/gdkalias.h 2006-10-30 12:58:29.000000000 +0000
60+++ gtk+-2.10.6/gdk/gdkalias.h 2006-10-30 12:59:30.000000000 +0000
61@@ -1796,9 +1796,6 @@
62 extern __typeof (gdk_pango_context_get) IA__gdk_pango_context_get __attribute((visibility("hidden")));
63 #define gdk_pango_context_get IA__gdk_pango_context_get
64
65-extern __typeof (gdk_pango_context_get_for_screen) IA__gdk_pango_context_get_for_screen __attribute((visibility("hidden")));
66-#define gdk_pango_context_get_for_screen IA__gdk_pango_context_get_for_screen
67-
68 #ifndef GDK_DISABLE_DEPRECATED
69 extern __typeof (gdk_pango_context_set_colormap) IA__gdk_pango_context_set_colormap __attribute((visibility("hidden")));
70 #define gdk_pango_context_set_colormap IA__gdk_pango_context_set_colormap
71@@ -1833,6 +1830,13 @@
72
73 #endif
74 #endif
75+#if IN_HEADER(__GDK_PANGO_H__)
76+#if IN_FILE(__GDK_PANGO_X11_C__)
77+extern __typeof (gdk_pango_context_get_for_screen) IA__gdk_pango_context_get_for_screen __attribute((visibility("hidden")));
78+#define gdk_pango_context_get_for_screen IA__gdk_pango_context_get_for_screen
79+
80+#endif
81+#endif
82 #if IN_HEADER(__GDK_PIXBUF_H__)
83 #if IN_FILE(__GDK_PIXBUF_DRAWABLE_C__)
84 extern __typeof (gdk_pixbuf_get_from_drawable) IA__gdk_pixbuf_get_from_drawable __attribute((visibility("hidden")));
85Index: gtk+-2.10.6/gdk/gdkdraw.c
86===================================================================
87--- gtk+-2.10.6.orig/gdk/gdkdraw.c 2006-10-30 12:58:29.000000000 +0000
88+++ gtk+-2.10.6/gdk/gdkdraw.c 2006-10-30 12:59:30.000000000 +0000
89@@ -909,9 +909,9 @@
90 {
91 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
92 g_return_if_fail (GDK_IS_GC (gc));
93-
94- real_draw_glyphs (drawable, gc, NULL, font,
95- x, y, glyphs);
96+
97+
98+ GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs (drawable, gc, font, x, y, glyphs);
99 }
100
101 /**
102@@ -949,8 +949,9 @@
103 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
104 g_return_if_fail (GDK_IS_GC (gc));
105
106- real_draw_glyphs (drawable, gc, matrix, font,
107- x / PANGO_SCALE, y / PANGO_SCALE, glyphs);
108+ if (GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs_transformed)
109+ GDK_DRAWABLE_GET_CLASS (drawable)->draw_glyphs_transformed (drawable, gc, matrix,
110+ font, x, y, glyphs);
111 }
112
113 /**
114@@ -974,28 +975,12 @@
115 GdkTrapezoid *trapezoids,
116 gint n_trapezoids)
117 {
118- cairo_t *cr;
119- int i;
120-
121 g_return_if_fail (GDK_IS_DRAWABLE (drawable));
122 g_return_if_fail (GDK_IS_GC (gc));
123 g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL);
124
125- cr = gdk_cairo_create (drawable);
126- _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE);
127-
128- for (i = 0; i < n_trapezoids; i++)
129- {
130- cairo_move_to (cr, trapezoids[i].x11, trapezoids[i].y1);
131- cairo_line_to (cr, trapezoids[i].x21, trapezoids[i].y1);
132- cairo_line_to (cr, trapezoids[i].x22, trapezoids[i].y2);
133- cairo_line_to (cr, trapezoids[i].x21, trapezoids[i].y2);
134- cairo_close_path (cr);
135- }
136-
137- cairo_fill (cr);
138-
139- cairo_destroy (cr);
140+ GDK_DRAWABLE_GET_CLASS (drawable)->draw_trapezoids (drawable, gc,
141+ trapezoids, n_trapezoids);
142 }
143
144 /**
145Index: gtk+-2.10.6/gdk/gdkpango.c
146===================================================================
147--- gtk+-2.10.6.orig/gdk/gdkpango.c 2006-10-30 12:58:29.000000000 +0000
148+++ gtk+-2.10.6/gdk/gdkpango.c 2006-10-30 12:59:30.000000000 +0000
149@@ -50,19 +50,34 @@
150 GdkBitmap *stipple[MAX_RENDER_PART + 1];
151 gboolean embossed;
152
153- cairo_t *cr;
154- PangoRenderPart last_part;
155+ /* When switching between the normal and shadow copies when
156+ * drawing shadows we can get unexpected recursion into the
157+ * drawing functions; the 'in_emboss' flag guards against that.
158+ */
159+ gboolean in_emboss;
160
161 /* Current target */
162 GdkDrawable *drawable;
163 GdkGC *base_gc;
164
165 gboolean gc_changed;
166+
167+ /* Cached GC, derived from base_gc */
168+ GdkGC *gc;
169+ PangoColor gc_color;
170+ gboolean gc_color_set;
171+ GdkBitmap *gc_stipple;
172+
173+ /* we accumulate trapezoids for the same PangoRenderPart */
174+ GArray *trapezoids;
175+ PangoRenderPart trapezoid_part;
176 };
177
178 static PangoAttrType gdk_pango_attr_stipple_type;
179 static PangoAttrType gdk_pango_attr_embossed_type;
180
181+static void flush_trapezoids (GdkPangoRenderer *gdk_renderer);
182+
183 enum {
184 PROP_0,
185 PROP_SCREEN
186@@ -77,6 +92,10 @@
187 GdkPangoRendererPrivate *priv = gdk_renderer->priv;
188 int i;
189
190+ if (priv->gc)
191+ g_object_unref (priv->gc);
192+ if (priv->gc_stipple)
193+ g_object_unref (priv->gc_stipple);
194 if (priv->base_gc)
195 g_object_unref (priv->base_gc);
196 if (priv->drawable)
197@@ -86,6 +105,8 @@
198 if (priv->stipple[i])
199 g_object_unref (priv->stipple[i]);
200
201+ g_array_free (priv->trapezoids, TRUE);
202+
203 G_OBJECT_CLASS (gdk_pango_renderer_parent_class)->finalize (object);
204 }
205
206@@ -112,25 +133,6 @@
207 return object;
208 }
209
210-/* Adjusts matrix and color for the renderer to draw the secondary
211- * "shadow" copy for embossed text */
212-static void
213-emboss_context (cairo_t *cr)
214-{
215- cairo_matrix_t tmp_matrix;
216-
217- /* The gymnastics here to adjust the matrix are because we want
218- * to offset by +1,+1 in device-space, not in user-space,
219- * so we can't just draw the layout at x + 1, y + 1
220- */
221- cairo_get_matrix (cr, &tmp_matrix);
222- tmp_matrix.x0 += 1.0;
223- tmp_matrix.y0 += 1.0;
224- cairo_set_matrix (cr, &tmp_matrix);
225-
226- cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
227-}
228-
229 static inline gboolean
230 color_equal (PangoColor *c1, PangoColor *c2)
231 {
232@@ -146,74 +148,154 @@
233 return FALSE;
234 }
235
236-static cairo_t *
237-get_cairo_context (GdkPangoRenderer *gdk_renderer,
238- PangoRenderPart part)
239+/* Adjusts matrix and color for the renderer to draw the secondar
240+ * "shadow" copy for embossed text */
241+static void
242+emboss_renderer (PangoRenderer *renderer,
243+ PangoRenderPart part,
244+ PangoMatrix **save_matrix,
245+ PangoColor **save_color)
246+{
247+ GdkPangoRendererPrivate *priv = GDK_PANGO_RENDERER(renderer)->priv;
248+ static const PangoColor white = { 0xffff, 0xffff, 0xffff };
249+ PangoMatrix tmp_matrix = PANGO_MATRIX_INIT;
250+
251+ priv->in_emboss = TRUE;
252+
253+ *save_color = pango_renderer_get_color (renderer, part);
254+ if (*save_color)
255+ *save_color = pango_color_copy (*save_color);
256+
257+ *save_matrix = renderer->matrix;
258+ if (*save_matrix)
259+ {
260+ *save_matrix = pango_matrix_copy (*save_matrix);
261+ tmp_matrix = **save_matrix;
262+ }
263+
264+ /* The gymnastics here to adjust the matrix are because we want
265+ * to offset by +1,+1 in device-space, not in user-space,
266+ * so we can't just draw the layout at x + 1, y + 1
267+ */
268+ tmp_matrix.x0 += 1;
269+ tmp_matrix.y0 += 1;
270+
271+ pango_renderer_set_matrix (renderer, &tmp_matrix);
272+ pango_renderer_set_color (renderer, part, &white);
273+}
274+
275+/* Restores from emboss_renderer() */
276+static void
277+unemboss_renderer (PangoRenderer *renderer,
278+ PangoRenderPart part,
279+ PangoMatrix **save_matrix,
280+ PangoColor **save_color)
281+{
282+ GdkPangoRendererPrivate *priv = GDK_PANGO_RENDERER(renderer)->priv;
283+ pango_renderer_set_matrix (renderer, *save_matrix);
284+ pango_renderer_set_color (renderer, part, *save_color);
285+
286+ if (*save_matrix)
287+ pango_matrix_free (*save_matrix);
288+ if (*save_color)
289+ pango_color_free (*save_color);
290+
291+ priv->in_emboss = FALSE;
292+}
293+
294+/* Gets the GC for drawing @part. This make involve copying the base GC
295+ * for the renderer, in which case we keep a one-GC cache. */
296+static GdkGC *
297+get_gc (GdkPangoRenderer *gdk_renderer,
298+ PangoRenderPart part)
299 {
300 PangoRenderer *renderer = PANGO_RENDERER (gdk_renderer);
301+ PangoColor *color;
302+ GdkBitmap *stipple;
303 GdkPangoRendererPrivate *priv = gdk_renderer->priv;
304
305- if (!priv->cr)
306+ color = pango_renderer_get_color (renderer, part);
307+
308+ if (part <= MAX_RENDER_PART)
309+ stipple = priv->stipple[part];
310+ else
311+ stipple = NULL;
312+
313+ if (!color && !stipple) /* nothing override, use base_gc */
314+ return priv->base_gc;
315+ else
316 {
317- const PangoMatrix *matrix;
318+ gboolean new_stipple = FALSE;
319+ gboolean new_color = FALSE;
320
321- priv->cr = gdk_cairo_create (priv->drawable);
322+ if (stipple != priv->gc_stipple)
323+ new_stipple = TRUE;
324
325- matrix = pango_renderer_get_matrix (renderer);
326- if (matrix)
327+ if ((priv->gc_color_set && !color) ||
328+ (!priv->gc_color_set && color) ||
329+ priv->gc_color.red != color->red ||
330+ priv->gc_color.green != color->green ||
331+ priv->gc_color.blue != color->blue)
332+ new_color = TRUE;
333+
334+ if (!priv->gc)
335 {
336- cairo_matrix_t cairo_matrix;
337-
338- cairo_matrix_init (&cairo_matrix,
339- matrix->xx, matrix->yx,
340- matrix->xy, matrix->yy,
341- matrix->x0, matrix->y0);
342- cairo_set_matrix (priv->cr, &cairo_matrix);
343+ priv->gc = gdk_gc_new (priv->drawable);
344+ gdk_gc_copy (priv->gc, priv->base_gc);
345+ }
346+ else if (new_color && priv->gc_color_set && !color)
347+ {
348+ /* We have to recopy the original GC onto the cached GC
349+ * to get the default color */
350+ new_stipple = TRUE;
351+ gdk_gc_copy (priv->gc, priv->base_gc);
352+ }
353+ else if (new_stipple && priv->gc_stipple && !stipple)
354+ {
355+ /* Similarly, we need to make a new copy to restore to the
356+ * default stipple state (the caller may have set a stipple
357+ * on the GC, and even if not, gdk_gc_set_stipple (gc, NULL)
358+ * doesn't work currently to restore to the default X stipple) */
359+ new_color = TRUE;
360+ gdk_gc_copy (priv->gc, priv->base_gc);
361 }
362- }
363-
364- if (part != priv->last_part)
365- {
366- PangoColor *pango_color;
367- GdkColor *color;
368- GdkColor tmp_color;
369- gboolean changed;
370
371- pango_color = pango_renderer_get_color (renderer, part);
372-
373- if (priv->last_part != -1)
374- changed = priv->gc_changed ||
375- priv->stipple[priv->last_part] != priv->stipple[part] ||
376- !color_equal (pango_color,
377- pango_renderer_get_color (renderer, priv->last_part));
378- else
379- changed = TRUE;
380-
381- if (changed)
382+ if (new_color)
383 {
384- if (pango_color)
385+ if (color)
386 {
387- tmp_color.red = pango_color->red;
388- tmp_color.green = pango_color->green;
389- tmp_color.blue = pango_color->blue;
390+ GdkColor gdk_color;
391+
392+ gdk_color.red = color->red;
393+ gdk_color.green = color->green;
394+ gdk_color.blue = color->blue;
395
396- color = &tmp_color;
397+ gdk_gc_set_rgb_fg_color (priv->gc, &gdk_color);
398+
399+ priv->gc_color = *color;
400+ priv->gc_color_set = TRUE;
401 }
402 else
403- color = NULL;
404+ priv->gc_color_set = FALSE;
405+ }
406
407- _gdk_gc_update_context (priv->base_gc,
408- priv->cr,
409- color,
410- priv->stipple[part],
411- priv->gc_changed);
412+ if (new_stipple)
413+ {
414+ if (priv->gc_stipple)
415+ g_object_unref (priv->gc_stipple);
416+
417+ if (stipple)
418+ {
419+ gdk_gc_set_stipple (priv->gc, stipple);
420+ gdk_gc_set_fill (priv->gc, GDK_STIPPLED);
421+ priv->gc_stipple = g_object_ref (stipple);
422+ }
423+ else
424+ priv->gc_stipple = NULL;
425 }
426
427- priv->last_part = part;
428- priv->gc_changed = FALSE;
429+ return priv->gc;
430 }
431-
432- return priv->cr;
433 }
434
435 static void
436@@ -225,133 +307,78 @@
437 {
438 GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
439 GdkPangoRendererPrivate *priv = gdk_renderer->priv;
440- cairo_t *cr;
441
442- cr = get_cairo_context (gdk_renderer,
443- PANGO_RENDER_PART_FOREGROUND);
444+ flush_trapezoids (gdk_renderer);
445
446- if (priv->embossed)
447+ if (!priv->in_emboss && priv->embossed)
448 {
449- cairo_save (cr);
450- emboss_context (cr);
451- cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
452- pango_cairo_show_glyph_string (cr, font, glyphs);
453- cairo_restore (cr);
454- }
455-
456- cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
457- pango_cairo_show_glyph_string (cr, font, glyphs);
458-}
459-
460-/* Draws an error underline that looks like one of:
461- * H E H
462- * /\ /\ /\ /\ /\ -
463- * A/ \ / \ / \ A/ \ / \ |
464- * \ \ / \ / /D \ \ / \ |
465- * \ \/ C \/ / \ \/ C \ | height = HEIGHT_SQUARES * square
466- * \ /\ F / \ F /\ \ |
467- * \ / \ / \ / \ \G |
468- * \ / \ / \ / \ / |
469- * \/ \/ \/ \/ -
470- * B B
471- * |----|
472- * unit_width = (HEIGHT_SQUARES - 1) * square
473- *
474- * The x, y, width, height passed in give the desired bounding box;
475- * x/width are adjusted to make the underline a integer number of units
476- * wide.
477- */
478-#define HEIGHT_SQUARES 2.5
479+ PangoMatrix *save_matrix;
480+ PangoColor *save_color;
481
482-/* Cut-and-pasted between here and pango/pango/pangocairo-render.c */
483+ emboss_renderer (renderer, PANGO_RENDER_PART_FOREGROUND, &save_matrix, &save_color);
484+ gdk_draw_glyphs_transformed (priv->drawable,
485+ get_gc (gdk_renderer, PANGO_RENDER_PART_FOREGROUND),
486+ renderer->matrix, font, x, y, glyphs);
487+ unemboss_renderer (renderer, PANGO_RENDER_PART_FOREGROUND, &save_matrix, &save_color);
488+ }
489+
490+ gdk_draw_glyphs_transformed (priv->drawable,
491+ get_gc (gdk_renderer, PANGO_RENDER_PART_FOREGROUND),
492+ renderer->matrix, font, x, y, glyphs);
493+}
494+
495+/* Outputs any pending trapezoids, we do this when the part or
496+ * part color changes, when we are about to draw text, etc. */
497 static void
498-draw_error_underline (cairo_t *cr,
499- double x,
500- double y,
501- double width,
502- double height)
503-{
504- double square = height / HEIGHT_SQUARES;
505- double unit_width = (HEIGHT_SQUARES - 1) * square;
506- int width_units = (width + unit_width / 2) / unit_width;
507- double y_top, y_bottom;
508- int i;
509+flush_trapezoids (GdkPangoRenderer *gdk_renderer)
510+{
511+ GdkPangoRendererPrivate *priv = gdk_renderer->priv;
512
513- x += (width - width_units * unit_width) / 2;
514- width = width_units * unit_width;
515+ if (!priv->trapezoids || priv->trapezoids->len == 0)
516+ return;
517
518- y_top = y;
519- y_bottom = y + height;
520-
521- /* Bottom of squiggle */
522- cairo_move_to (cr, x - square / 2, y_top + square / 2); /* A */
523- for (i = 0; i < width_units; i += 2)
524- {
525- double x_middle = x + (i + 1) * unit_width;
526- double x_right = x + (i + 2) * unit_width;
527-
528- cairo_line_to (cr, x_middle, y_bottom); /* B */
529-
530- if (i + 1 == width_units)
531- /* Nothing */;
532- else if (i + 2 == width_units)
533- cairo_line_to (cr, x_right + square / 2, y_top + square / 2); /* D */
534- else
535- cairo_line_to (cr, x_right, y_top + square); /* C */
536- }
537-
538- /* Top of squiggle */
539- for (i -= 2; i >= 0; i -= 2)
540- {
541- double x_left = x + i * unit_width;
542- double x_middle = x + (i + 1) * unit_width;
543- double x_right = x + (i + 2) * unit_width;
544-
545- if (i + 1 == width_units)
546- cairo_line_to (cr, x_middle + square / 2, y_bottom - square / 2); /* G */
547- else {
548- if (i + 2 == width_units)
549- cairo_line_to (cr, x_right, y_top); /* E */
550- cairo_line_to (cr, x_middle, y_bottom - square); /* F */
551- }
552-
553- cairo_line_to (cr, x_left, y_top); /* H */
554- }
555+ gdk_draw_trapezoids (priv->drawable,
556+ get_gc (gdk_renderer, priv->trapezoid_part),
557+ (GdkTrapezoid *)priv->trapezoids->data,
558+ priv->trapezoids->len);
559
560- cairo_close_path (cr);
561- cairo_fill (cr);
562+ g_array_set_size (priv->trapezoids, 0);
563 }
564
565+/* Draws a single trapezoid ... we don't draw it immediately, but rather
566+ * cache it to join together with other trapezoids that form part of the
567+ * same logical shape */
568 static void
569-gdk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
570- PangoRenderPart part,
571- int x,
572- int y,
573- int width,
574- int height)
575+gdk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
576+ PangoRenderPart part,
577+ double y1,
578+ double x11,
579+ double x21,
580+ double y2,
581+ double x12,
582+ double x22)
583 {
584 GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
585- GdkPangoRendererPrivate *priv = gdk_renderer->priv;
586- cairo_t *cr;
587-
588- cr = get_cairo_context (gdk_renderer, part);
589-
590- if (priv->embossed && part != PANGO_RENDER_PART_BACKGROUND)
591- {
592- cairo_save (cr);
593- emboss_context (cr);
594- cairo_rectangle (cr,
595- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
596- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
597+ GdkTrapezoid trap;
598
599- cairo_fill (cr);
600- cairo_restore (cr);
601- }
602+ if (!gdk_renderer->priv->trapezoids)
603+ gdk_renderer->priv->trapezoids = g_array_new (FALSE, FALSE,
604+ sizeof (GdkTrapezoid));
605+
606+ if (gdk_renderer->priv->trapezoids->len > 0 &&
607+ gdk_renderer->priv->trapezoid_part != part)
608+ flush_trapezoids (gdk_renderer);
609+
610+ gdk_renderer->priv->trapezoid_part = part;
611+
612+ trap.y1 = y1;
613+ trap.x11 = x11 / 2;
614+ trap.x21 = x21;
615+ trap.y2 = y2;
616+ trap.x12 = x12;
617+ trap.x22 = x22;
618
619- cairo_rectangle (cr,
620- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
621- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
622- cairo_fill (cr);
623+ g_array_append_val (gdk_renderer->priv->trapezoids, trap);
624 }
625
626 static void
627@@ -363,23 +390,51 @@
628 {
629 GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
630 GdkPangoRendererPrivate *priv = gdk_renderer->priv;
631- cairo_t *cr;
632-
633- cr = get_cairo_context (gdk_renderer, PANGO_RENDER_PART_UNDERLINE);
634-
635- if (priv->embossed)
636+
637+ if (!priv->in_emboss && priv->embossed)
638 {
639- cairo_save (cr);
640- emboss_context (cr);
641- draw_error_underline (cr,
642- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
643- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
644- cairo_restore (cr);
645+ PangoMatrix *save_matrix;
646+ PangoColor *save_color;
647+
648+ emboss_renderer (renderer, PANGO_RENDER_PART_UNDERLINE, &save_matrix, &save_color);
649+ PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_error_underline (renderer,
650+ x, y, width, height);
651+ unemboss_renderer (renderer, PANGO_RENDER_PART_UNDERLINE, &save_matrix, &save_color);
652 }
653
654- draw_error_underline (cr,
655- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
656- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
657+ PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_error_underline (renderer,
658+ x, y, width, height);
659+}
660+
661+/* We can't handle embossing at the level of trapezoids, because when an
662+ * underline is split into multiple trapezoids, the normal and shadow
663+ * trapezoids will be drawn mixed together. Instead, we have to emboss
664+ * and entire rectangle or error underline
665+ */
666+static void
667+gdk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
668+ PangoRenderPart part,
669+ int x,
670+ int y,
671+ int width,
672+ int height)
673+{
674+ GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
675+ GdkPangoRendererPrivate *priv = gdk_renderer->priv;
676+
677+ if (!priv->in_emboss && priv->embossed && part != PANGO_RENDER_PART_BACKGROUND)
678+ {
679+ PangoMatrix *save_matrix;
680+ PangoColor *save_color;
681+
682+ emboss_renderer (renderer, part, &save_matrix, &save_color);
683+ PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_rectangle (renderer, part,
684+ x, y, width, height);
685+ unemboss_renderer (renderer, part, &save_matrix, &save_color);
686+ }
687+
688+ PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->draw_rectangle (renderer, part,
689+ x, y, width, height);
690 }
691
692 static void
693@@ -388,8 +443,8 @@
694 {
695 GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
696
697- if (gdk_renderer->priv->last_part == part)
698- gdk_renderer->priv->last_part = (PangoRenderPart)-1;
699+ if (part == gdk_renderer->priv->trapezoid_part)
700+ flush_trapezoids (gdk_renderer);
701 }
702
703 static void
704@@ -410,13 +465,8 @@
705 {
706 GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer);
707 GdkPangoRendererPrivate *priv = gdk_renderer->priv;
708-
709- if (priv->cr)
710- {
711- cairo_destroy (priv->cr);
712- priv->cr = NULL;
713- }
714- priv->last_part = (PangoRenderPart)-1;
715+
716+ flush_trapezoids (gdk_renderer);
717 }
718
719 static void
720@@ -515,7 +565,6 @@
721 GDK_TYPE_PANGO_RENDERER,
722 GdkPangoRendererPrivate);
723
724- renderer->priv->last_part = (PangoRenderPart)-1;
725 renderer->priv->gc_changed = TRUE;
726 }
727
728@@ -527,6 +576,7 @@
729 PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
730
731 renderer_class->draw_glyphs = gdk_pango_renderer_draw_glyphs;
732+ renderer_class->draw_trapezoid = gdk_pango_renderer_draw_trapezoid;
733 renderer_class->draw_rectangle = gdk_pango_renderer_draw_rectangle;
734 renderer_class->draw_error_underline = gdk_pango_renderer_draw_error_underline;
735 renderer_class->part_changed = gdk_pango_renderer_part_changed;
736@@ -647,6 +697,8 @@
737
738 priv = gdk_renderer->priv;
739
740+ flush_trapezoids (gdk_renderer);
741+
742 if (priv->drawable != drawable)
743 {
744 if (priv->drawable)
745@@ -681,6 +733,8 @@
746
747 priv = gdk_renderer->priv;
748
749+ flush_trapezoids (gdk_renderer);
750+
751 if (priv->base_gc != gc)
752 {
753 if (priv->base_gc)
754@@ -689,6 +743,20 @@
755 if (priv->base_gc)
756 g_object_ref (priv->base_gc);
757
758+ if (priv->gc)
759+ {
760+ g_object_unref (priv->gc);
761+ priv->gc = NULL;
762+ }
763+
764+ priv->gc_color_set = FALSE;
765+
766+ if (priv->gc_stipple)
767+ {
768+ g_object_unref (priv->gc_stipple);
769+ priv->gc_stipple = NULL;
770+ }
771+
772 priv->gc_changed = TRUE;
773 }
774 }
775@@ -1414,50 +1482,5 @@
776 return gdk_pango_context_get_for_screen (gdk_screen_get_default ());
777 }
778
779-/**
780- * gdk_pango_context_get_for_screen:
781- * @screen: the #GdkScreen for which the context is to be created.
782- *
783- * Creates a #PangoContext for @screen.
784- *
785- * The context must be freed when you're finished with it.
786- *
787- * When using GTK+, normally you should use gtk_widget_get_pango_context()
788- * instead of this function, to get the appropriate context for
789- * the widget you intend to render text onto.
790- *
791- * The newly created context will have the default font options
792- * (see #cairo_font_options_t) for the screen; if these options
793- * change it will not be updated. Using gtk_widget_get_pango_context()
794- * is more convenient if you want to keep a context around and track
795- * changes to the screen's font rendering settings.
796- *
797- * Return value: a new #PangoContext for @screen
798- *
799- * Since: 2.2
800- **/
801-PangoContext *
802-gdk_pango_context_get_for_screen (GdkScreen *screen)
803-{
804- PangoFontMap *fontmap;
805- PangoContext *context;
806- const cairo_font_options_t *options;
807- double dpi;
808-
809- g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
810-
811- fontmap = pango_cairo_font_map_get_default ();
812-
813- context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
814-
815- options = gdk_screen_get_font_options (screen);
816- pango_cairo_context_set_font_options (context, options);
817-
818- dpi = gdk_screen_get_resolution (screen);
819- pango_cairo_context_set_resolution (context, dpi);
820-
821- return context;
822-}
823-
824 #define __GDK_PANGO_C__
825 #include "gdkaliasdef.c"
826Index: gtk+-2.10.6/gdk/gdk.symbols
827===================================================================
828--- gtk+-2.10.6.orig/gdk/gdk.symbols 2006-10-30 12:58:29.000000000 +0000
829+++ gtk+-2.10.6/gdk/gdk.symbols 2006-10-30 12:59:30.000000000 +0000
830@@ -861,7 +861,6 @@
831 gdk_pango_attr_embossed_new
832 gdk_pango_attr_stipple_new
833 gdk_pango_context_get
834-gdk_pango_context_get_for_screen
835 #ifndef GDK_DISABLE_DEPRECATED
836 gdk_pango_context_set_colormap
837 #endif
838@@ -877,6 +876,12 @@
839 #endif
840 #endif
841
842+#if IN_HEADER(__GDK_PANGO_H__)
843+#if IN_FILE(__GDK_PANGO_X11_C__)
844+gdk_pango_context_get_for_screen
845+#endif
846+#endif
847+
848 #if IN_HEADER(__GDK_PIXBUF_H__)
849 #if IN_FILE(__GDK_PIXBUF_DRAWABLE_C__)
850 gdk_pixbuf_get_from_drawable
851Index: gtk+-2.10.6/gdk/gdkwindow.c
852===================================================================
853--- gtk+-2.10.6.orig/gdk/gdkwindow.c 2006-10-30 12:58:29.000000000 +0000
854+++ gtk+-2.10.6/gdk/gdkwindow.c 2006-10-30 12:59:30.000000000 +0000
855@@ -1834,9 +1834,14 @@
856 }
857 else
858 {
859- method->cr = cairo_create (paint->surface);
860+ /*method->cr = cairo_create (paint->surface);
861
862- gdk_cairo_set_source_color (method->cr, &private->bg_color);
863+ gdk_cairo_set_source_color (method->cr, &private->bg_color);*/
864+ GdkGC *gc = _gdk_drawable_get_scratch_gc (paint->pixmap, FALSE);
865+
866+ gdk_gc_set_foreground (gc, &(private->bg_color));
867+
868+ method->gc = g_object_ref (gc);
869 }
870 }
871
872Index: gtk+-2.10.6/gdk/x11/gdkdisplay-x11.c
873===================================================================
874--- gtk+-2.10.6.orig/gdk/x11/gdkdisplay-x11.c 2006-10-30 12:58:29.000000000 +0000
875+++ gtk+-2.10.6/gdk/x11/gdkdisplay-x11.c 2006-10-30 12:59:30.000000000 +0000
876@@ -190,7 +190,8 @@
877 display_x11->leader_window_title_set = FALSE;
878
879 display_x11->have_render = GDK_UNKNOWN;
880-
881+ display_x11->have_render_with_trapezoids = GDK_UNKNOWN;
882+
883 #ifdef HAVE_XFIXES
884 if (XFixesQueryExtension (display_x11->xdisplay,
885 &display_x11->xfixes_event_base,
886Index: gtk+-2.10.6/gdk/x11/gdkdisplay-x11.h
887===================================================================
888--- gtk+-2.10.6.orig/gdk/x11/gdkdisplay-x11.h 2006-10-30 12:58:29.000000000 +0000
889+++ gtk+-2.10.6/gdk/x11/gdkdisplay-x11.h 2006-10-30 12:59:30.000000000 +0000
890@@ -78,6 +78,7 @@
891 gboolean use_xshm;
892 gboolean have_shm_pixmaps;
893 GdkTristate have_render;
894+ GdkTristate have_render_with_trapezoids;
895 gboolean have_xfixes;
896 gint xfixes_event_base;
897
898Index: gtk+-2.10.6/gdk/x11/gdkdrawable-x11.c
899===================================================================
900--- gtk+-2.10.6.orig/gdk/x11/gdkdrawable-x11.c 2006-10-30 12:58:30.000000000 +0000
901+++ gtk+-2.10.6/gdk/x11/gdkdrawable-x11.c 2006-10-30 12:59:30.000000000 +0000
902@@ -26,6 +26,8 @@
903
904 #include <config.h>
905
906+#include <pango/pangoxft.h>
907+
908 #include "gdkx.h"
909 #include "gdkregion-generic.h"
910
911@@ -106,7 +108,21 @@
912 GdkGC *gc,
913 GdkPoint *points,
914 gint npoints);
915-
916+
917+static void gdk_x11_draw_glyphs (GdkDrawable *drawable,
918+ GdkGC *gc,
919+ PangoFont *font,
920+ gint x,
921+ gint y,
922+ PangoGlyphString *glyphs);
923+static void gdk_x11_draw_glyphs_transformed (GdkDrawable *drawable,
924+ GdkGC *gc,
925+ PangoMatrix *matrix,
926+ PangoFont *font,
927+ gint x,
928+ gint y,
929+ PangoGlyphString *glyphs);
930+
931 static void gdk_x11_draw_image (GdkDrawable *drawable,
932 GdkGC *gc,
933 GdkImage *image,
934@@ -129,6 +145,11 @@
935 gint x_dither,
936 gint y_dither);
937
938+static void gdk_x11_draw_trapezoids (GdkDrawable *drawable,
939+ GdkGC *gc,
940+ GdkTrapezoid *trapezoids,
941+ gint n_trapezoids);
942+
943 static cairo_surface_t *gdk_x11_ref_cairo_surface (GdkDrawable *drawable);
944
945 static void gdk_x11_set_colormap (GdkDrawable *drawable,
946@@ -163,8 +184,11 @@
947 drawable_class->draw_points = gdk_x11_draw_points;
948 drawable_class->draw_segments = gdk_x11_draw_segments;
949 drawable_class->draw_lines = gdk_x11_draw_lines;
950+ drawable_class->draw_glyphs = gdk_x11_draw_glyphs;
951+ drawable_class->draw_glyphs_transformed = gdk_x11_draw_glyphs_transformed;
952 drawable_class->draw_image = gdk_x11_draw_image;
953 drawable_class->draw_pixbuf = gdk_x11_draw_pixbuf;
954+ drawable_class->draw_trapezoids = gdk_x11_draw_trapezoids;
955
956 drawable_class->ref_cairo_surface = gdk_x11_ref_cairo_surface;
957
958@@ -327,6 +351,72 @@
959 return x11display->have_render == GDK_YES;
960 }
961
962+gboolean
963+_gdk_x11_have_render_with_trapezoids (GdkDisplay *display)
964+{
965+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
966+ GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display);
967+
968+ if (x11display->have_render_with_trapezoids == GDK_UNKNOWN)
969+ {
970+ x11display->have_render_with_trapezoids = GDK_NO;
971+ if (_gdk_x11_have_render (display))
972+ {
973+ /*
974+ * Require protocol >= 0.4 for CompositeTrapezoids support.
975+ */
976+ int major_version, minor_version;
977+
978+#define XRENDER_TETRAPEZOIDS_MAJOR 0
979+#define XRENDER_TETRAPEZOIDS_MINOR 4
980+
981+ if (XRenderQueryVersion (xdisplay, &major_version,
982+ &minor_version))
983+ if ((major_version == XRENDER_TETRAPEZOIDS_MAJOR) &&
984+ (minor_version >= XRENDER_TETRAPEZOIDS_MINOR))
985+ x11display->have_render_with_trapezoids = GDK_YES;
986+ }
987+ }
988+
989+ return x11display->have_render_with_trapezoids == GDK_YES;
990+}
991+
992+static XftDraw *
993+gdk_x11_drawable_get_xft_draw (GdkDrawable *drawable)
994+{
995+ GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
996+
997+ if (impl->xft_draw == NULL)
998+ {
999+ GdkColormap *colormap = gdk_drawable_get_colormap (drawable);
1000+
1001+ if (colormap)
1002+ {
1003+ GdkVisual *visual;
1004+
1005+ visual = gdk_colormap_get_visual (colormap);
1006+
1007+ impl->xft_draw = XftDrawCreate (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid,
1008+ GDK_VISUAL_XVISUAL (visual), GDK_COLORMAP_XCOLORMAP (colormap));
1009+ }
1010+ else if (gdk_drawable_get_depth (drawable) == 1)
1011+ {
1012+ impl->xft_draw = XftDrawCreateBitmap (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid);
1013+ }
1014+ else
1015+ {
1016+ g_warning ("Using Xft rendering requires the drawable argument to\n"
1017+ "have a specified colormap. All windows have a colormap,\n"
1018+ "however, pixmaps only have colormap by default if they\n"
1019+ "were created with a non-NULL window argument. Otherwise\n"
1020+ "a colormap must be set on them with gdk_drawable_set_colormap");
1021+ return NULL;
1022+ }
1023+ }
1024+
1025+ return impl->xft_draw;
1026+}
1027+
1028 static Picture
1029 gdk_x11_drawable_get_picture (GdkDrawable *drawable)
1030 {
1031@@ -393,6 +483,57 @@
1032 }
1033 }
1034
1035+static void
1036+gdk_x11_drawable_update_xft_clip (GdkDrawable *drawable,
1037+ GdkGC *gc)
1038+{
1039+ XftDraw *xft_draw = gdk_x11_drawable_get_xft_draw (drawable);
1040+ GdkRegion *clip_region = _gdk_gc_get_clip_region (gc);
1041+
1042+ if (gc && clip_region)
1043+ {
1044+ GdkRegionBox *boxes = clip_region->rects;
1045+ gint n_boxes = clip_region->numRects;
1046+#if 0 /* Until XftDrawSetClipRectangles is there */
1047+ XRectangle *rects = g_new (XRectangle, n_boxes);
1048+ int i;
1049+
1050+ for (i=0; i < n_boxes; i++)
1051+ {
1052+ rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
1053+ rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
1054+ rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x;
1055+ rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y;
1056+ }
1057+ XftDrawSetClipRectangles (xft_draw, 0, 0, rects, n_boxes);
1058+
1059+ g_free (rects);
1060+#else
1061+ Region xregion = XCreateRegion ();
1062+ int i;
1063+
1064+ for (i=0; i < n_boxes; i++)
1065+ {
1066+ XRectangle rect;
1067+
1068+ rect.x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
1069+ rect.y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
1070+ rect.width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rect.x;
1071+ rect.height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rect.y;
1072+
1073+ XUnionRectWithRegion (&rect, xregion, xregion);
1074+ }
1075+
1076+ XftDrawSetClip (xft_draw, xregion);
1077+ XDestroyRegion (xregion);
1078+#endif
1079+ }
1080+ else
1081+ {
1082+ XftDrawSetClip (xft_draw, NULL);
1083+ }
1084+}
1085+
1086 /*****************************************************
1087 * X11 specific implementations of generic functions *
1088 *****************************************************/
1089@@ -780,6 +921,45 @@
1090 }
1091
1092 static void
1093+gdk_x11_draw_glyphs (GdkDrawable *drawable,
1094+ GdkGC *gc,
1095+ PangoFont *font,
1096+ gint x,
1097+ gint y,
1098+ PangoGlyphString *glyphs)
1099+{
1100+ gdk_x11_draw_glyphs_transformed (drawable, gc, NULL,
1101+ font,
1102+ x * PANGO_SCALE,
1103+ y * PANGO_SCALE,
1104+ glyphs);
1105+}
1106+
1107+static void
1108+gdk_x11_draw_glyphs_transformed (GdkDrawable *drawable,
1109+ GdkGC *gc,
1110+ PangoMatrix *matrix,
1111+ PangoFont *font,
1112+ gint x,
1113+ gint y,
1114+ PangoGlyphString *glyphs)
1115+{
1116+ GdkDrawableImplX11 *impl;
1117+ PangoRenderer *renderer;
1118+
1119+ impl = GDK_DRAWABLE_IMPL_X11 (drawable);
1120+
1121+ g_return_if_fail (PANGO_XFT_IS_FONT (font));
1122+
1123+ renderer = _gdk_x11_renderer_get (drawable, gc);
1124+ if (matrix)
1125+ pango_renderer_set_matrix (renderer, matrix);
1126+ pango_renderer_draw_glyphs (renderer, font, glyphs, x, y);
1127+ if (matrix)
1128+ pango_renderer_set_matrix (renderer, NULL);
1129+}
1130+
1131+static void
1132 gdk_x11_draw_image (GdkDrawable *drawable,
1133 GdkGC *gc,
1134 GdkImage *image,
1135@@ -1444,6 +1624,47 @@
1136 }
1137
1138 static void
1139+gdk_x11_draw_trapezoids (GdkDrawable *drawable,
1140+ GdkGC *gc,
1141+ GdkTrapezoid *trapezoids,
1142+ gint n_trapezoids)
1143+{
1144+ GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
1145+ GdkDisplay *display = gdk_screen_get_display (screen);
1146+ XTrapezoid *xtrapezoids;
1147+ gint i;
1148+
1149+ if (!_gdk_x11_have_render_with_trapezoids (display))
1150+ {
1151+ GdkDrawable *wrapper = GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper;
1152+ GDK_DRAWABLE_CLASS (_gdk_drawable_impl_x11_parent_class)->draw_trapezoids (wrapper, gc,
1153+ trapezoids, n_trapezoids);
1154+ return;
1155+ }
1156+
1157+ xtrapezoids = g_new (XTrapezoid, n_trapezoids);
1158+
1159+ for (i = 0; i < n_trapezoids; i++)
1160+ {
1161+ xtrapezoids[i].top = XDoubleToFixed (trapezoids[i].y1);
1162+ xtrapezoids[i].bottom = XDoubleToFixed (trapezoids[i].y2);
1163+ xtrapezoids[i].left.p1.x = XDoubleToFixed (trapezoids[i].x11);
1164+ xtrapezoids[i].left.p1.y = XDoubleToFixed (trapezoids[i].y1);
1165+ xtrapezoids[i].left.p2.x = XDoubleToFixed (trapezoids[i].x12);
1166+ xtrapezoids[i].left.p2.y = XDoubleToFixed (trapezoids[i].y2);
1167+ xtrapezoids[i].right.p1.x = XDoubleToFixed (trapezoids[i].x21);
1168+ xtrapezoids[i].right.p1.y = XDoubleToFixed (trapezoids[i].y1);
1169+ xtrapezoids[i].right.p2.x = XDoubleToFixed (trapezoids[i].x22);
1170+ xtrapezoids[i].right.p2.y = XDoubleToFixed (trapezoids[i].y2);
1171+ }
1172+
1173+ _gdk_x11_drawable_draw_xtrapezoids (drawable, gc,
1174+ xtrapezoids, n_trapezoids);
1175+
1176+ g_free (xtrapezoids);
1177+}
1178+
1179+static void
1180 gdk_x11_cairo_surface_destroy (void *data)
1181 {
1182 GdkDrawableImplX11 *impl = data;
1183@@ -1498,5 +1719,89 @@
1184 return impl->cairo_surface;
1185 }
1186
1187+void
1188+_gdk_x11_drawable_draw_xtrapezoids (GdkDrawable *drawable,
1189+ GdkGC *gc,
1190+ XTrapezoid *xtrapezoids,
1191+ int n_trapezoids)
1192+{
1193+ GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
1194+ GdkDisplay *display = gdk_screen_get_display (screen);
1195+ GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display);
1196+
1197+ XftDraw *draw;
1198+
1199+ if (!_gdk_x11_have_render_with_trapezoids (display))
1200+ {
1201+ /* This is the case of drawing the borders of the unknown glyph box
1202+ * without render on the display, we need to feed it back to
1203+ * fallback code. Not efficient, but doesn't matter.
1204+ */
1205+ GdkTrapezoid *trapezoids = g_new (GdkTrapezoid, n_trapezoids);
1206+ int i;
1207+
1208+ for (i = 0; i < n_trapezoids; i++)
1209+ {
1210+ trapezoids[i].y1 = XFixedToDouble (xtrapezoids[i].top);
1211+ trapezoids[i].y2 = XFixedToDouble (xtrapezoids[i].bottom);
1212+ trapezoids[i].x11 = XFixedToDouble (xtrapezoids[i].left.p1.x);
1213+ trapezoids[i].x12 = XFixedToDouble (xtrapezoids[i].left.p2.x);
1214+ trapezoids[i].x21 = XFixedToDouble (xtrapezoids[i].right.p1.x);
1215+ trapezoids[i].x22 = XFixedToDouble (xtrapezoids[i].right.p2.x);
1216+ }
1217+
1218+ gdk_x11_draw_trapezoids (drawable, gc, trapezoids, n_trapezoids);
1219+ g_free (trapezoids);
1220+
1221+ return;
1222+ }
1223+
1224+ gdk_x11_drawable_update_xft_clip (drawable, gc);
1225+ draw = gdk_x11_drawable_get_xft_draw (drawable);
1226+
1227+ if (!x11display->mask_format)
1228+ x11display->mask_format = XRenderFindStandardFormat (x11display->xdisplay,
1229+ PictStandardA8);
1230+
1231+ XRenderCompositeTrapezoids (x11display->xdisplay, PictOpOver,
1232+ _gdk_x11_gc_get_fg_picture (gc),
1233+ XftDrawPicture (draw),
1234+ x11display->mask_format,
1235+ - gc->ts_x_origin, - gc->ts_y_origin,
1236+ xtrapezoids, n_trapezoids);
1237+}
1238+
1239+void
1240+_gdk_x11_drawable_draw_xft_glyphs (GdkDrawable *drawable,
1241+ GdkGC *gc,
1242+ XftFont *xft_font,
1243+ XftGlyphSpec *glyphs,
1244+ gint n_glyphs)
1245+{
1246+ GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
1247+ GdkDisplay *display = gdk_screen_get_display (screen);
1248+ GdkDisplayX11 *x11display = GDK_DISPLAY_X11 (display);
1249+ XftDraw *draw;
1250+
1251+ gdk_x11_drawable_update_xft_clip (drawable, gc);
1252+ draw = gdk_x11_drawable_get_xft_draw (drawable);
1253+
1254+ if (_gdk_x11_have_render (display))
1255+ {
1256+ XftGlyphSpecRender (x11display->xdisplay, PictOpOver,
1257+ _gdk_x11_gc_get_fg_picture (gc),
1258+ xft_font,
1259+ XftDrawPicture (draw),
1260+ - gc->ts_x_origin, - gc->ts_y_origin,
1261+ glyphs, n_glyphs);
1262+ }
1263+ else
1264+ {
1265+ XftColor color;
1266+
1267+ _gdk_gc_x11_get_fg_xft_color (gc, &color);
1268+ XftDrawGlyphSpec (draw, &color, xft_font, glyphs, n_glyphs);
1269+ }
1270+}
1271 #define __GDK_DRAWABLE_X11_C__
1272 #include "gdkaliasdef.c"
1273Index: gtk+-2.10.6/gdk/x11/gdkdrawable-x11.h
1274===================================================================
1275--- gtk+-2.10.6.orig/gdk/x11/gdkdrawable-x11.h 2006-10-30 12:58:30.000000000 +0000
1276+++ gtk+-2.10.6/gdk/x11/gdkdrawable-x11.h 2006-10-30 12:59:30.000000000 +0000
1277@@ -33,6 +33,7 @@
1278
1279 #include <X11/Xlib.h>
1280 #include <X11/extensions/Xrender.h>
1281+#include <X11/Xft/Xft.h>
1282
1283 G_BEGIN_DECLS
1284
1285@@ -68,6 +69,8 @@
1286 Window xid;
1287 GdkScreen *screen;
1288
1289+ XftDraw *xft_draw;
1290+
1291 Picture picture;
1292 cairo_surface_t *cairo_surface;
1293 };
1294@@ -92,7 +95,15 @@
1295 /* Note that the following take GdkDrawableImplX11, not the wrapper drawable */
1296 void _gdk_x11_drawable_finish (GdkDrawable *drawable);
1297 void _gdk_x11_drawable_update_size (GdkDrawable *drawable);
1298-
1299+void _gdk_x11_drawable_draw_xtrapezoids (GdkDrawable *drawable,
1300+ GdkGC *gc,
1301+ XTrapezoid *xtrapezoids,
1302+ int n_trapezoids);
1303+void _gdk_x11_drawable_draw_xft_glyphs (GdkDrawable *drawable,
1304+ GdkGC *gc,
1305+ XftFont *xft_font,
1306+ XftGlyphSpec *glyphs,
1307+ gint n_glyphs);
1308 G_END_DECLS
1309
1310 #endif /* __GDK_DRAWABLE_X11_H__ */
1311Index: gtk+-2.10.6/gdk/x11/gdkgc-x11.c
1312===================================================================
1313--- gtk+-2.10.6.orig/gdk/x11/gdkgc-x11.c 2006-10-30 12:58:30.000000000 +0000
1314+++ gtk+-2.10.6/gdk/x11/gdkgc-x11.c 2006-10-30 12:59:30.000000000 +0000
1315@@ -80,7 +80,10 @@
1316 gdk_gc_x11_finalize (GObject *object)
1317 {
1318 GdkGCX11 *x11_gc = GDK_GC_X11 (object);
1319-
1320+
1321+ if (x11_gc->fg_picture != None)
1322+ XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture);
1323+
1324 XFreeGC (GDK_GC_XDISPLAY (x11_gc), GDK_GC_XGC (x11_gc));
1325
1326 G_OBJECT_CLASS (_gdk_gc_x11_parent_class)->finalize (object);
1327@@ -110,7 +113,7 @@
1328
1329 private->dirty_mask = 0;
1330 private->have_clip_mask = FALSE;
1331-
1332+
1333 private->screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
1334
1335 private->depth = gdk_drawable_get_depth (drawable);
1336@@ -339,6 +342,18 @@
1337 }
1338
1339 static void
1340+clear_fg_picture (GdkGC *gc)
1341+{
1342+ GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
1343+
1344+ if (x11_gc->fg_picture != None)
1345+ {
1346+ XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), x11_gc->fg_picture);
1347+ x11_gc->fg_picture = None;
1348+ }
1349+}
1350+
1351+static void
1352 gdk_x11_gc_set_values (GdkGC *gc,
1353 GdkGCValues *values,
1354 GdkGCValuesMask values_mask)
1355@@ -367,6 +382,29 @@
1356 x11_gc->have_clip_mask = values->clip_mask != NULL;
1357 }
1358
1359+ if (values_mask & GDK_GC_BACKGROUND)
1360+ {
1361+ if (_gdk_gc_get_fill (gc) == GDK_OPAQUE_STIPPLED)
1362+ clear_fg_picture (gc);
1363+ }
1364+
1365+ if (values_mask & GDK_GC_FILL)
1366+ {
1367+ clear_fg_picture (gc);
1368+ }
1369+
1370+ if (values_mask & GDK_GC_STIPPLE)
1371+ {
1372+ if (_gdk_gc_get_fill (gc) == GDK_STIPPLED || _gdk_gc_get_fill (gc) == GDK_OPAQUE_STIPPLED)
1373+ clear_fg_picture (gc);
1374+ }
1375+
1376+ if (values_mask & GDK_GC_TILE)
1377+ {
1378+ if (_gdk_gc_get_fill (gc) == GDK_TILED)
1379+ clear_fg_picture (gc);
1380+ }
1381+
1382 gdk_x11_gc_values_to_xvalues (values, values_mask, &xvalues, &xvalues_mask);
1383
1384 XChangeGC (GDK_GC_XDISPLAY (gc),
1385@@ -642,6 +680,8 @@
1386 x11_dst_gc->dirty_mask = x11_src_gc->dirty_mask;
1387 x11_dst_gc->have_clip_region = x11_src_gc->have_clip_region;
1388 x11_dst_gc->have_clip_mask = x11_src_gc->have_clip_mask;
1389+
1390+ clear_fg_picture (dst_gc);
1391 }
1392
1393 /**
1394@@ -701,5 +741,359 @@
1395 return gc_x11->xgc;
1396 }
1397
1398+/* Various bits of the below are roughly cribbed from XFree86
1399+ * lib/Xft/xftdraw.c, Copyright 2000, Keith Packard
1400+ */
1401+
1402+static XRenderPictFormat *
1403+foreground_format (GdkGC *gc)
1404+{
1405+ XRenderPictFormat pf;
1406+
1407+ pf.type = PictTypeDirect;
1408+ pf.depth = 32;
1409+ pf.direct.redMask = 0xff;
1410+ pf.direct.greenMask = 0xff;
1411+ pf.direct.blueMask = 0xff;
1412+ pf.direct.alphaMask = 0xff;
1413+
1414+ return XRenderFindFormat (GDK_GC_XDISPLAY (gc),
1415+ (PictFormatType |
1416+ PictFormatDepth |
1417+ PictFormatRedMask |
1418+ PictFormatGreenMask |
1419+ PictFormatBlueMask |
1420+ PictFormatAlphaMask),
1421+ &pf,
1422+ 0);
1423+}
1424+
1425+static Picture
1426+make_fg_tile_picture (GdkGC *gc)
1427+{
1428+ GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
1429+ GdkVisual *visual = gdk_drawable_get_visual (_gdk_gc_get_tile (gc));
1430+ XRenderPictFormat *format = NULL;
1431+
1432+ if (visual)
1433+ {
1434+ format = XRenderFindVisualFormat (GDK_GC_XDISPLAY (gc),
1435+ GDK_VISUAL_XVISUAL (visual));
1436+ }
1437+ else if (x11_gc->depth == 1)
1438+ {
1439+ format = XRenderFindStandardFormat (GDK_GC_XDISPLAY (gc),
1440+ PictStandardA1);
1441+ }
1442+
1443+ if (format)
1444+ {
1445+ XRenderPictureAttributes pa;
1446+ pa.repeat = True;
1447+
1448+ return XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
1449+ GDK_PIXMAP_XID (_gdk_gc_get_tile (gc)),
1450+ format,
1451+ CPRepeat, &pa);
1452+ }
1453+
1454+ return None;
1455+}
1456+
1457+static Picture
1458+make_stipple_picture (GdkGC *gc)
1459+{
1460+ XRenderPictFormat *format = NULL;
1461+ XRenderPictureAttributes pa;
1462+
1463+ format = XRenderFindStandardFormat (GDK_GC_XDISPLAY (gc),
1464+ PictStandardA1);
1465+
1466+ pa.repeat = True;
1467+ return XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
1468+ GDK_PIXMAP_XID (_gdk_gc_get_stipple (gc)),
1469+ format,
1470+ CPRepeat, &pa);
1471+}
1472+
1473+static Picture
1474+make_color_picture (GdkGC *gc,
1475+ XRenderColor *color)
1476+{
1477+ GdkGCX11 *x11_gc = GDK_GC_X11 (gc);
1478+ XRenderPictureAttributes pa;
1479+ XRenderPictFormat *pix_format = foreground_format (gc);
1480+ Pixmap pix;
1481+ Picture picture;
1482+
1483+ if (!pix_format)
1484+ return None;
1485+
1486+ pix = XCreatePixmap (GDK_GC_XDISPLAY (gc),
1487+ GDK_SCREEN_XROOTWIN (x11_gc->screen),
1488+ 1, 1, pix_format->depth);
1489+ pa.repeat = True;
1490+ picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
1491+ pix,
1492+ pix_format,
1493+ CPRepeat, &pa);
1494+ XFreePixmap (GDK_GC_XDISPLAY (gc), pix);
1495+
1496+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
1497+ picture, color,
1498+ 0, 0, 1, 1);
1499+
1500+ return picture;
1501+}
1502+
1503+static void
1504+get_bg_color (GdkGC *gc,
1505+ XRenderColor *render_color)
1506+{
1507+ GdkColormap *cmap;
1508+
1509+ cmap = gdk_gc_get_colormap (gc);
1510+
1511+ if (cmap)
1512+ {
1513+ GdkColor color;
1514+
1515+ gdk_colormap_query_color (cmap, _gdk_gc_get_bg_pixel (gc), &color);
1516+
1517+ render_color->alpha = 0xffff;
1518+ render_color->red = color.red;
1519+ render_color->green = color.green;
1520+ render_color->blue = color.blue;
1521+ }
1522+ else /* Not worth warning, just use black */
1523+ {
1524+ render_color->alpha = 0xffff;
1525+ render_color->red = 0;
1526+ render_color->green = 0;
1527+ render_color->blue = 0;
1528+ }
1529+}
1530+
1531+/**
1532+ * _gdk_x11_gc_get_fg_picture:
1533+ * @gc: a #GdkGC
1534+ *
1535+ * Gets a Xrender Picture object suitable for being the source
1536+ * drawable for drawing with the foreground the graphics context.
1537+ *
1538+ * Return value: a Picture, owned by the GC; this cannot be
1539+ * used over subsequent modification of the GC.
1540+ **/
1541+Picture
1542+_gdk_x11_gc_get_fg_picture (GdkGC *gc)
1543+{
1544+ GdkGCX11 *x11_gc;
1545+ gboolean new = FALSE;
1546+ XftColor xftcolor;
1547+ GdkFill fill;
1548+ int width, height;
1549+
1550+ g_return_val_if_fail (GDK_IS_GC_X11 (gc), None);
1551+
1552+ if (!_gdk_x11_have_render (GDK_GC_DISPLAY (gc)))
1553+ return None;
1554+
1555+ x11_gc = GDK_GC_X11 (gc);
1556+
1557+ fill = GDK_SOLID;
1558+ width = 1;
1559+ height = 1;
1560+
1561+ switch (_gdk_gc_get_fill (gc))
1562+ {
1563+ case GDK_SOLID:
1564+ break;
1565+ case GDK_TILED:
1566+ if (_gdk_gc_get_tile (gc))
1567+ {
1568+ if (!x11_gc->fg_picture)
1569+ x11_gc->fg_picture = make_fg_tile_picture (gc);
1570+
1571+ if (x11_gc->fg_picture != None)
1572+ return x11_gc->fg_picture;
1573+ }
1574+ break;
1575+ case GDK_STIPPLED:
1576+ case GDK_OPAQUE_STIPPLED:
1577+ if (_gdk_gc_get_stipple (gc))
1578+ {
1579+ gdk_drawable_get_size (_gdk_gc_get_stipple (gc), &width, &height);
1580+ fill = _gdk_gc_get_fill (gc);
1581+ }
1582+ break;
1583+ }
1584+
1585+ if (x11_gc->fg_picture == None)
1586+ {
1587+ XRenderPictureAttributes pa;
1588+ XRenderPictFormat *pix_format = foreground_format (gc);
1589+ Pixmap pix;
1590+
1591+ if (!pix_format)
1592+ return None;
1593+
1594+ pix = XCreatePixmap (GDK_GC_XDISPLAY (gc),
1595+ GDK_SCREEN_XROOTWIN (x11_gc->screen),
1596+ width, height, pix_format->depth);
1597+ pa.repeat = True;
1598+ x11_gc->fg_picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
1599+ pix,
1600+ pix_format,
1601+ CPRepeat, &pa);
1602+ XFreePixmap (GDK_GC_XDISPLAY (gc), pix);
1603+
1604+ new = TRUE;
1605+ }
1606+
1607+ _gdk_gc_x11_get_fg_xft_color (gc, &xftcolor);
1608+
1609+ if (x11_gc->fg_picture_color.alpha != 0xffff ||
1610+ x11_gc->fg_picture_color.red != xftcolor.color.red ||
1611+ x11_gc->fg_picture_color.green != xftcolor.color.green ||
1612+ x11_gc->fg_picture_color.blue != xftcolor.color.blue)
1613+ {
1614+ x11_gc->fg_picture_color.alpha = 0xffff;
1615+ x11_gc->fg_picture_color.red = xftcolor.color.red;
1616+ x11_gc->fg_picture_color.green = xftcolor.color.green;
1617+ x11_gc->fg_picture_color.blue = xftcolor.color.blue;
1618+
1619+ new = TRUE;
1620+ }
1621+
1622+ switch (fill)
1623+ {
1624+ case GDK_SOLID:
1625+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
1626+ x11_gc->fg_picture, &x11_gc->fg_picture_color,
1627+ 0, 0, width, height);
1628+ break;
1629+ case GDK_STIPPLED:
1630+ {
1631+ Picture stipple_picture = make_stipple_picture (gc);
1632+
1633+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
1634+ x11_gc->fg_picture, &x11_gc->fg_picture_color,
1635+ 0, 0, width, height);
1636+ XRenderComposite (GDK_GC_XDISPLAY (gc),
1637+ PictOpInReverse,
1638+ stipple_picture, None, x11_gc->fg_picture,
1639+ 0, 0, 0, 0, 0, 0, width, height);
1640+
1641+ XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), stipple_picture);
1642+ }
1643+ break;
1644+ case GDK_OPAQUE_STIPPLED:
1645+ {
1646+ XRenderColor bg_color;
1647+
1648+ Picture stipple_picture = make_stipple_picture (gc);
1649+ Picture fg_picture = make_color_picture (gc, &x11_gc->fg_picture_color);
1650+
1651+ get_bg_color (gc, &bg_color);
1652+
1653+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
1654+ x11_gc->fg_picture, &bg_color,
1655+ 0, 0, width, height);
1656+ XRenderComposite (GDK_GC_XDISPLAY (gc),
1657+ PictOpOver,
1658+ fg_picture, stipple_picture, x11_gc->fg_picture,
1659+ 0, 0, 0, 0, 0, 0, width, height);
1660+
1661+ XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), stipple_picture);
1662+ XRenderFreePicture (GDK_GC_XDISPLAY (x11_gc), fg_picture);
1663+ }
1664+ break;
1665+ case GDK_TILED:
1666+ g_assert_not_reached (); /* handled above */
1667+ break;
1668+ }
1669+
1670+ return x11_gc->fg_picture;
1671+}
1672+
1673+/**
1674+ * _gdk_gc_x11_get_fg_xft_color:
1675+ * @gc: a #GdkGC
1676+ * @xftcolor: location to store the color
1677+ *
1678+ * Gets the foreground color of the GC as a XftColor.
1679+ **/
1680+void
1681+_gdk_gc_x11_get_fg_xft_color (GdkGC *gc,
1682+ XftColor *xftcolor)
1683+{
1684+ GdkGCX11 *x11_gc;
1685+ GdkColormap *cmap;
1686+ GdkColor color;
1687+
1688+ g_return_if_fail (GDK_IS_GC_X11 (gc));
1689+
1690+ x11_gc = GDK_GC_X11 (gc);
1691+
1692+ cmap = gdk_gc_get_colormap (gc);
1693+
1694+ xftcolor->pixel = _gdk_gc_get_fg_pixel (gc);
1695+
1696+ if (cmap)
1697+ {
1698+ gdk_colormap_query_color (cmap, xftcolor->pixel, &color);
1699+ xftcolor->color.alpha = 0xffff;
1700+ xftcolor->color.red = color.red;
1701+ xftcolor->color.green = color.green;
1702+ xftcolor->color.blue = color.blue;
1703+ }
1704+ else if (x11_gc->depth == 1)
1705+ {
1706+ /* Drawing with Xft on a bitmap is a bit bizzare; it
1707+ * takes alpha >= 0x8000 to mean 'set to 1' and
1708+ * alpha < 0x8000 to mean 'set to 0'.
1709+ */
1710+ if (xftcolor->pixel)
1711+ {
1712+ xftcolor->color.red = 0xffff;
1713+ xftcolor->color.green = 0xffff;
1714+ xftcolor->color.blue = 0xffff;
1715+ xftcolor->color.alpha = 0xffff;
1716+ }
1717+ else
1718+ {
1719+ xftcolor->color.red = 0;
1720+ xftcolor->color.green = 0;
1721+ xftcolor->color.blue = 0;
1722+ xftcolor->color.alpha = 0;
1723+ }
1724+ }
1725+ else
1726+ {
1727+ g_warning ("Using Xft rendering requires the GC argument to have a\n"
1728+ "specified colormap. If the GC was created for a drawable\n"
1729+ "with a colormap, the colormap will be set on the GC\n"
1730+ "automatically. Otherwise, a colormap must be set on it with"
1731+ "gdk_gc_set_colormap");
1732+ }
1733+}
1734+
1735+void
1736+_gdk_windowing_gc_get_foreground (GdkGC *gc,
1737+ GdkColor *color)
1738+{
1739+ GdkColormap *cmap;
1740+
1741+ g_return_if_fail (GDK_IS_GC_X11 (gc));
1742+
1743+ color->pixel = _gdk_gc_get_fg_pixel (gc);
1744+
1745+ cmap = gdk_gc_get_colormap (gc);
1746+
1747+ if (cmap)
1748+ gdk_colormap_query_color (cmap, _gdk_gc_get_fg_pixel (gc), color);
1749+ else
1750+ g_warning ("No colormap in _gdk_windowing_gc_get_foreground");
1751+}
1752 #define __GDK_GC_X11_C__
1753 #include "gdkaliasdef.c"
1754Index: gtk+-2.10.6/gdk/x11/gdkprivate-x11.h
1755===================================================================
1756--- gtk+-2.10.6.orig/gdk/x11/gdkprivate-x11.h 2006-10-30 12:58:30.000000000 +0000
1757+++ gtk+-2.10.6/gdk/x11/gdkprivate-x11.h 2006-10-30 12:59:30.000000000 +0000
1758@@ -63,6 +63,9 @@
1759 guint have_clip_region : 1;
1760 guint have_clip_mask : 1;
1761 guint depth : 8;
1762+
1763+ Picture fg_picture;
1764+ XRenderColor fg_picture_color;
1765 };
1766
1767 struct _GdkGCX11Class
1768@@ -102,6 +105,11 @@
1769 GType _gdk_gc_x11_get_type (void);
1770
1771 gboolean _gdk_x11_have_render (GdkDisplay *display);
1772+gboolean _gdk_x11_have_render_with_trapezoids (GdkDisplay *display);
1773+
1774+Picture _gdk_x11_gc_get_fg_picture (GdkGC *gc);
1775+void _gdk_gc_x11_get_fg_xft_color (GdkGC *gc,
1776+ XftColor *xftcolor);
1777
1778 GdkGC *_gdk_x11_gc_new (GdkDrawable *drawable,
1779 GdkGCValues *values,
1780Index: gtk+-2.10.6/gdk/x11/gdkwindow-x11.c
1781===================================================================
1782--- gtk+-2.10.6.orig/gdk/x11/gdkwindow-x11.c 2006-10-30 12:58:30.000000000 +0000
1783+++ gtk+-2.10.6/gdk/x11/gdkwindow-x11.c 2006-10-30 12:59:30.000000000 +0000
1784@@ -1114,7 +1114,8 @@
1785 {
1786 GdkWindowObject *private = (GdkWindowObject *)window;
1787 GdkToplevelX11 *toplevel;
1788-
1789+ GdkDrawableImplX11 *draw_impl;
1790+
1791 g_return_if_fail (GDK_IS_WINDOW (window));
1792
1793 _gdk_selection_window_destroyed (window);
1794@@ -1126,6 +1127,11 @@
1795 if (toplevel)
1796 gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
1797
1798+ draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
1799+
1800+ if (draw_impl->xft_draw)
1801+ XftDrawDestroy (draw_impl->xft_draw);
1802+
1803 _gdk_x11_drawable_finish (private->impl);
1804
1805 if (!recursing && !foreign_destroy)
1806Index: gtk+-2.10.6/gdk/x11/Makefile.am
1807===================================================================
1808--- gtk+-2.10.6.orig/gdk/x11/Makefile.am 2006-10-30 12:58:30.000000000 +0000
1809+++ gtk+-2.10.6/gdk/x11/Makefile.am 2006-10-30 12:59:30.000000000 +0000
1810@@ -37,6 +37,7 @@
1811 gdkinput.c \
1812 gdkkeys-x11.c \
1813 gdkmain-x11.c \
1814+ gdkpango-x11.c \
1815 gdkpixmap-x11.c \
1816 gdkpixmap-x11.h \
1817 gdkproperty-x11.c \
1818Index: gtk+-2.10.6/gtk/gtkcalendar.c
1819===================================================================
1820--- gtk+-2.10.6.orig/gtk/gtkcalendar.c 2006-10-30 12:58:30.000000000 +0000
1821+++ gtk+-2.10.6/gtk/gtkcalendar.c 2006-10-30 12:59:30.000000000 +0000
1822@@ -1821,7 +1821,7 @@
1823 }
1824 }
1825
1826-
1827+
1828 /****************************************
1829 * Repainting *
1830 ****************************************/
1831@@ -1831,7 +1831,7 @@
1832 {
1833 GtkWidget *widget = GTK_WIDGET (calendar);
1834 GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
1835- cairo_t *cr;
1836+ GdkGC *gc;
1837 char buffer[255];
1838 int x, y;
1839 gint header_width;
1840@@ -1849,7 +1849,7 @@
1841 else
1842 year_left = !priv->year_before;
1843
1844- cr = gdk_cairo_create (priv->header_win);
1845+ gc = calendar->gc;
1846
1847 header_width = widget->allocation.width - 2 * widget->style->xthickness;
1848
1849@@ -1902,9 +1902,9 @@
1850 - (max_year_width - logical_rect.width)/2);
1851
1852
1853- gdk_cairo_set_source_color (cr, HEADER_FG_COLOR (GTK_WIDGET (calendar)));
1854- cairo_move_to (cr, x, y);
1855- pango_cairo_show_layout (cr, layout);
1856+ gdk_gc_set_foreground (gc, HEADER_FG_COLOR (GTK_WIDGET (calendar)));
1857+ gdk_draw_layout (priv->header_win, gc, x, y, layout);
1858+
1859
1860 /* Draw month */
1861 g_snprintf (buffer, sizeof (buffer), "%s", default_monthname[calendar->month]);
1862@@ -1924,19 +1924,19 @@
1863 else
1864 x = 3 + priv->arrow_width + (max_month_width - logical_rect.width)/2;
1865
1866- cairo_move_to (cr, x, y);
1867- pango_cairo_show_layout (cr, layout);
1868-
1869+ gdk_draw_layout (priv->header_win, gc, x, y, layout);
1870+
1871+ gdk_gc_set_foreground (gc, BACKGROUND_COLOR (GTK_WIDGET (calendar)));
1872+
1873 g_object_unref (layout);
1874- cairo_destroy (cr);
1875 }
1876
1877 static void
1878 calendar_paint_day_names (GtkCalendar *calendar)
1879 {
1880 GtkWidget *widget = GTK_WIDGET (calendar);
1881+ GdkGC *gc;
1882 GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
1883- cairo_t *cr;
1884 char buffer[255];
1885 int day,i;
1886 int day_width, cal_width;
1887@@ -1946,8 +1946,7 @@
1888 gint focus_padding;
1889 gint focus_width;
1890
1891- cr = gdk_cairo_create (priv->day_name_win);
1892-
1893+ gc = calendar->gc;
1894 gtk_widget_style_get (GTK_WIDGET (widget),
1895 "focus-line-width", &focus_width,
1896 "focus-padding", &focus_padding,
1897@@ -1961,22 +1960,19 @@
1898 * Draw rectangles as inverted background for the labels.
1899 */
1900
1901- gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget));
1902- cairo_rectangle (cr,
1903- CALENDAR_MARGIN, CALENDAR_MARGIN,
1904- cal_width-CALENDAR_MARGIN * 2,
1905- priv->day_name_h - CALENDAR_MARGIN);
1906- cairo_fill (cr);
1907-
1908+ gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (widget));
1909+ gdk_draw_rectangle (priv->day_name_win, gc, TRUE,
1910+ CALENDAR_MARGIN, CALENDAR_MARGIN,
1911+ cal_width-CALENDAR_MARGIN * 2,
1912+ priv->day_name_h - CALENDAR_MARGIN);
1913+
1914 if (calendar->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
1915- {
1916- cairo_rectangle (cr,
1917- CALENDAR_MARGIN,
1918- priv->day_name_h - CALENDAR_YSEP,
1919- priv->week_width - CALENDAR_YSEP - CALENDAR_MARGIN,
1920- CALENDAR_YSEP);
1921- cairo_fill (cr);
1922- }
1923+ gdk_draw_rectangle (priv->day_name_win, gc, TRUE,
1924+ CALENDAR_MARGIN,
1925+ priv->day_name_h - CALENDAR_YSEP,
1926+ priv->week_width - CALENDAR_YSEP - CALENDAR_MARGIN,
1927+ CALENDAR_YSEP);
1928+
1929
1930 /*
1931 * Write the labels
1932@@ -1984,7 +1980,7 @@
1933
1934 layout = gtk_widget_create_pango_layout (widget, NULL);
1935
1936- gdk_cairo_set_source_color (cr, SELECTED_FG_COLOR (widget));
1937+ gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (widget));
1938 for (i = 0; i < 7; i++)
1939 {
1940 if (gtk_widget_get_direction (GTK_WIDGET (calendar)) == GTK_TEXT_DIR_RTL)
1941@@ -1997,19 +1993,18 @@
1942 pango_layout_set_text (layout, buffer, -1);
1943 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
1944
1945- cairo_move_to (cr,
1946- (CALENDAR_MARGIN +
1947- + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
1948- (priv->week_width + (priv->week_width ? CALENDAR_XSEP : 0))
1949- : 0)
1950- + day_wid_sep * i
1951- + (day_width - logical_rect.width)/2),
1952- CALENDAR_MARGIN + focus_width + focus_padding + logical_rect.y);
1953- pango_cairo_show_layout (cr, layout);
1954+ gdk_draw_layout (priv->day_name_win, gc,
1955+ (CALENDAR_MARGIN +
1956+ + (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?
1957+ (priv->week_width + (priv->week_width ? CALENDAR_XSEP : 0))
1958+ : 0)
1959+ + day_wid_sep * i
1960+ + (day_width - logical_rect.width)/2),
1961+ CALENDAR_MARGIN + focus_width + focus_padding + logical_rect.y,
1962+ layout);
1963 }
1964
1965 g_object_unref (layout);
1966- cairo_destroy (cr);
1967 }
1968
1969 static void
1970@@ -2017,7 +2012,7 @@
1971 {
1972 GtkWidget *widget = GTK_WIDGET (calendar);
1973 GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
1974- cairo_t *cr;
1975+ GdkGC *gc;
1976 gint row, week = 0, year;
1977 gint x_loc;
1978 char buffer[32];
1979@@ -2027,7 +2022,7 @@
1980 gint focus_padding;
1981 gint focus_width;
1982
1983- cr = gdk_cairo_create (priv->week_win);
1984+ gc = calendar->gc;
1985
1986 gtk_widget_style_get (GTK_WIDGET (widget),
1987 "focus-line-width", &focus_width,
1988@@ -2038,20 +2033,20 @@
1989 * Draw a rectangle as inverted background for the labels.
1990 */
1991
1992- gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget));
1993+ gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (widget));
1994 if (priv->day_name_win)
1995- cairo_rectangle (cr,
1996- CALENDAR_MARGIN,
1997- 0,
1998- priv->week_width - CALENDAR_MARGIN,
1999- priv->main_h - CALENDAR_MARGIN);
2000+ gdk_draw_rectangle (priv->week_win, gc, TRUE,
2001+ CALENDAR_MARGIN,
2002+ 0,
2003+ priv->week_width - CALENDAR_MARGIN,
2004+ priv->main_h - CALENDAR_MARGIN);
2005 else
2006- cairo_rectangle (cr,
2007- CALENDAR_MARGIN,
2008- CALENDAR_MARGIN,
2009- priv->week_width - CALENDAR_MARGIN,
2010- priv->main_h - 2 * CALENDAR_MARGIN);
2011- cairo_fill (cr);
2012+ gdk_draw_rectangle (priv->week_win, gc, TRUE,
2013+ CALENDAR_MARGIN,
2014+ CALENDAR_MARGIN,
2015+ priv->week_width - CALENDAR_MARGIN,
2016+ priv->main_h - 2 * CALENDAR_MARGIN);
2017+
2018
2019 /*
2020 * Write the labels
2021@@ -2059,7 +2054,7 @@
2022
2023 layout = gtk_widget_create_pango_layout (widget, NULL);
2024
2025- gdk_cairo_set_source_color (cr, SELECTED_FG_COLOR (widget));
2026+ gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (widget));
2027 day_height = calendar_row_height (calendar);
2028 for (row = 0; row < 6; row++)
2029 {
2030@@ -2095,12 +2090,10 @@
2031 - logical_rect.width
2032 - CALENDAR_XSEP - focus_padding - focus_width);
2033
2034- cairo_move_to (cr, x_loc, y_loc);
2035- pango_cairo_show_layout (cr, layout);
2036+ gdk_draw_layout (priv->week_win, gc, x_loc, y_loc, layout);
2037 }
2038
2039 g_object_unref (layout);
2040- cairo_destroy (cr);
2041 }
2042
2043 static void
2044@@ -2149,7 +2142,7 @@
2045 {
2046 GtkWidget *widget = GTK_WIDGET (calendar);
2047 GtkCalendarPrivate *priv = GTK_CALENDAR_GET_PRIVATE (calendar);
2048- cairo_t *cr;
2049+ GdkGC *gc;
2050 GdkColor *text_color;
2051 gchar buffer[32];
2052 gint day;
2053@@ -2162,7 +2155,7 @@
2054 g_return_if_fail (row < 6);
2055 g_return_if_fail (col < 7);
2056
2057- cr = gdk_cairo_create (priv->main_win);
2058+ gc = calendar->gc;
2059
2060 day = calendar->day[row][col];
2061
2062@@ -2170,11 +2163,11 @@
2063
2064 if (calendar->day_month[row][col] == MONTH_PREV)
2065 {
2066- text_color = PREV_MONTH_COLOR (widget);
2067+ gdk_gc_set_foreground (gc, PREV_MONTH_COLOR (GTK_WIDGET (calendar)));
2068 }
2069 else if (calendar->day_month[row][col] == MONTH_NEXT)
2070 {
2071- text_color = NEXT_MONTH_COLOR (widget);
2072+ gdk_gc_set_foreground (gc, NEXT_MONTH_COLOR (GTK_WIDGET (calendar)));
2073 }
2074 else
2075 {
2076@@ -2188,16 +2181,16 @@
2077 #endif
2078 if (calendar->selected_day == day)
2079 {
2080- gdk_cairo_set_source_color (cr, SELECTED_BG_COLOR (widget));
2081- gdk_cairo_rectangle (cr, &day_rect);
2082- cairo_fill (cr);
2083+ gdk_gc_set_foreground (gc, SELECTED_BG_COLOR (GTK_WIDGET (calendar)));
2084+ gdk_draw_rectangle (priv->main_win, gc, TRUE, day_rect.x, day_rect.y,
2085+ day_rect.width, day_rect.height);
2086 }
2087 if (calendar->selected_day == day)
2088- text_color = SELECTED_FG_COLOR (widget);
2089+ gdk_gc_set_foreground (gc, SELECTED_FG_COLOR (GTK_WIDGET (calendar)));
2090 else if (calendar->marked_date[day-1])
2091- text_color = MARKED_COLOR (widget);
2092+ gdk_gc_set_foreground (gc, MARKED_COLOR (GTK_WIDGET (calendar)));
2093 else
2094- text_color = NORMAL_DAY_COLOR (widget);
2095+ gdk_gc_set_foreground (gc, NORMAL_DAY_COLOR (GTK_WIDGET (calendar)));
2096 }
2097
2098 /* Translators: this defines whether the day numbers should use
2099@@ -2219,16 +2212,13 @@
2100 x_loc -= logical_rect.width;
2101 y_loc = day_rect.y + (day_rect.height - logical_rect.height) / 2;
2102
2103- gdk_cairo_set_source_color (cr, text_color);
2104- cairo_move_to (cr, x_loc, y_loc);
2105- pango_cairo_show_layout (cr, layout);
2106+ gdk_draw_layout (priv->main_win, gc,
2107+ x_loc, y_loc, layout);
2108
2109 if (calendar->marked_date[day-1]
2110 && calendar->day_month[row][col] == MONTH_CURRENT)
2111- {
2112- cairo_move_to (cr, x_loc - 1, y_loc);
2113- pango_cairo_show_layout (cr, layout);
2114- }
2115+ gdk_draw_layout (priv->main_win, gc,
2116+ x_loc-1, y_loc, layout);
2117
2118 if (GTK_WIDGET_HAS_FOCUS (calendar)
2119 && calendar->focus_row == row && calendar->focus_col == col)
2120@@ -2253,7 +2243,6 @@
2121 }
2122
2123 g_object_unref (layout);
2124- cairo_destroy (cr);
2125 }
2126
2127 static void
2128Index: gtk+-2.10.6/gtk/gtkentry.c
2129===================================================================
2130--- gtk+-2.10.6.orig/gtk/gtkentry.c 2006-10-30 12:58:30.000000000 +0000
2131+++ gtk+-2.10.6/gtk/gtkentry.c 2006-10-30 12:59:30.000000000 +0000
2132@@ -3333,7 +3333,6 @@
2133 if (GTK_WIDGET_DRAWABLE (entry))
2134 {
2135 PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
2136- cairo_t *cr;
2137 gint x, y;
2138 gint start_pos, end_pos;
2139
2140@@ -3341,56 +3340,60 @@
2141
2142 get_layout_position (entry, &x, &y);
2143
2144- cr = gdk_cairo_create (entry->text_area);
2145-
2146- cairo_move_to (cr, x, y);
2147- gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
2148- pango_cairo_show_layout (cr, layout);
2149-
2150+ gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
2151+ x, y,
2152+ layout);
2153+
2154 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
2155 {
2156 gint *ranges;
2157 gint n_ranges, i;
2158 PangoRectangle logical_rect;
2159- GdkColor *selection_color, *text_color;
2160+ GdkGC *selection_gc, *text_gc;
2161 GtkBorder inner_border;
2162-
2163+ GdkRegion *clip_region;
2164+
2165 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
2166 gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
2167
2168 if (GTK_WIDGET_HAS_FOCUS (entry))
2169 {
2170- selection_color = &widget->style->base [GTK_STATE_SELECTED];
2171- text_color = &widget->style->text [GTK_STATE_SELECTED];
2172+ selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
2173+ text_gc = widget->style->text_gc [GTK_STATE_SELECTED];
2174 }
2175 else
2176 {
2177- selection_color = &widget->style->base [GTK_STATE_ACTIVE];
2178- text_color = &widget->style->text [GTK_STATE_ACTIVE];
2179+ selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE];
2180+ text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
2181 }
2182-
2183+
2184+ clip_region = gdk_region_new ();
2185 _gtk_entry_effective_inner_border (entry, &inner_border);
2186
2187 for (i = 0; i < n_ranges; ++i)
2188- cairo_rectangle (cr,
2189- inner_border.left - entry->scroll_offset + ranges[2 * i],
2190- y,
2191- ranges[2 * i + 1],
2192- logical_rect.height);
2193+ {
2194+ GdkRectangle rect;
2195
2196- cairo_clip (cr);
2197-
2198- gdk_cairo_set_source_color (cr, selection_color);
2199- cairo_paint (cr);
2200+ rect.x = inner_border.left - entry->scroll_offset + ranges[2 * i];
2201+ rect.y = y;
2202+ rect.width = ranges[2 * i + 1];
2203+ rect.height = logical_rect.height;
2204+
2205+ gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
2206+ rect.x, rect.y, rect.width, rect.height);
2207
2208- cairo_move_to (cr, x, y);
2209- gdk_cairo_set_source_color (cr, text_color);
2210- pango_cairo_show_layout (cr, layout);
2211+ gdk_region_union_with_rect (clip_region, &rect);
2212+ }
2213
2214+ gdk_gc_set_clip_region (text_gc, clip_region);
2215+ gdk_draw_layout (entry->text_area, text_gc,
2216+ x, y,
2217+ layout);
2218+ gdk_gc_set_clip_region (text_gc, NULL);
2219+
2220+ gdk_region_destroy (clip_region);
2221 g_free (ranges);
2222 }
2223-
2224- cairo_destroy (cr);
2225 }
2226 }
2227
2228Index: gtk+-2.10.6/gtk/gtkwidget.c
2229===================================================================
2230--- gtk+-2.10.6.orig/gtk/gtkwidget.c 2006-10-30 12:58:30.000000000 +0000
2231+++ gtk+-2.10.6/gtk/gtkwidget.c 2006-10-30 12:59:30.000000000 +0000
2232@@ -5445,7 +5445,8 @@
2233 GdkScreen *screen;
2234
2235 update_pango_context (widget, context);
2236-
2237+/* TODO: Figure out the proper way to handle this in a pangoxft setting
2238+
2239 screen = gtk_widget_get_screen_unchecked (widget);
2240 if (screen)
2241 {
2242@@ -5453,7 +5454,7 @@
2243 gdk_screen_get_resolution (screen));
2244 pango_cairo_context_set_font_options (context,
2245 gdk_screen_get_font_options (screen));
2246- }
2247+ }*/
2248 }
2249 }
2250
2251Index: gtk+-2.10.6/gdk/x11/gdkpango-x11.c
2252===================================================================
2253--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2254+++ gtk+-2.10.6/gdk/x11/gdkpango-x11.c 2006-10-30 12:59:30.000000000 +0000
2255@@ -0,0 +1,174 @@
2256+/* GDK - The GIMP Drawing Kit
2257+ * Copyright (C) 2000 Red Hat, Inc.
2258+ *
2259+ * This library is free software; you can redistribute it and/or
2260+ * modify it under the terms of the GNU Lesser General Public
2261+ * License as published by the Free Software Foundation; either
2262+ * version 2 of the License, or (at your option) any later version.
2263+ *
2264+ * This library is distributed in the hope that it will be useful,
2265+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2266+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2267+ * Lesser General Public License for more details.
2268+ *
2269+ * You should have received a copy of the GNU Lesser General Public
2270+ * License along with this library; if not, write to the
2271+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
2272+ * Boston, MA 02111-1307, USA.
2273+ */
2274+
2275+#include <config.h>
2276+#include <stdlib.h>
2277+
2278+#include "gdkx.h"
2279+#include "gdkdisplay-x11.h"
2280+#include "gdkpango.h"
2281+#include <pango/pangoxft.h>
2282+#include <pango/pangoxft-render.h>
2283+#include "gdkalias.h"
2284+
2285+#include <math.h>
2286+
2287+typedef struct _GdkX11Renderer GdkX11Renderer;
2288+typedef struct _GdkX11RendererClass GdkX11RendererClass;
2289+
2290+#define GDK_TYPE_X11_RENDERER (_gdk_x11_renderer_get_type())
2291+#define GDK_X11_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_X11_RENDERER, GdkX11Renderer))
2292+#define GDK_IS_X11_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_X11_RENDERER))
2293+#define GDK_X11_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_X11_RENDERER, GdkX11RendererClass))
2294+#define GDK_IS_X11_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_X11_RENDERER))
2295+#define GDK_X11_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_X11_RENDERER, GdkX11RendererClass))
2296+
2297+#define MAX_RENDER_PART PANGO_RENDER_PART_STRIKETHROUGH
2298+
2299+struct _GdkX11Renderer
2300+{
2301+ PangoXftRenderer parent_instance;
2302+
2303+ XRenderPictFormat *mask_format;
2304+
2305+ GdkDrawable *drawable;
2306+ GdkGC *gc;
2307+};
2308+
2309+struct _GdkX11RendererClass
2310+{
2311+ PangoXftRendererClass parent_class;
2312+};
2313+
2314+G_DEFINE_TYPE (GdkX11Renderer, _gdk_x11_renderer, PANGO_TYPE_XFT_RENDERER)
2315+
2316+static void
2317+gdk_x11_renderer_finalize (GObject *object)
2318+{
2319+ G_OBJECT_CLASS (_gdk_x11_renderer_parent_class)->finalize (object);
2320+}
2321+
2322+static void
2323+gdk_x11_renderer_composite_trapezoids (PangoXftRenderer *xftrenderer,
2324+ PangoRenderPart part,
2325+ XTrapezoid *trapezoids,
2326+ int n_trapezoids)
2327+{
2328+ /* Because we only use this renderer for "draw_glyphs()" calls, we
2329+ * won't hit this code path much. However, it is hit for drawing
2330+ * the "unknown glyph" hex squares. We can safely ignore the part,
2331+ */
2332+ GdkX11Renderer *x11_renderer = GDK_X11_RENDERER (xftrenderer);
2333+
2334+ _gdk_x11_drawable_draw_xtrapezoids (x11_renderer->drawable,
2335+ x11_renderer->gc,
2336+ trapezoids, n_trapezoids);
2337+
2338+}
2339+
2340+static void
2341+gdk_x11_renderer_composite_glyphs (PangoXftRenderer *xftrenderer,
2342+ XftFont *xft_font,
2343+ XftGlyphSpec *glyphs,
2344+ gint n_glyphs)
2345+{
2346+ GdkX11Renderer *x11_renderer = GDK_X11_RENDERER (xftrenderer);
2347+
2348+ _gdk_x11_drawable_draw_xft_glyphs (x11_renderer->drawable,
2349+ x11_renderer->gc,
2350+ xft_font, glyphs, n_glyphs);
2351+}
2352+
2353+static void
2354+_gdk_x11_renderer_init (GdkX11Renderer *renderer)
2355+{
2356+}
2357+
2358+static void
2359+_gdk_x11_renderer_class_init (GdkX11RendererClass *klass)
2360+{
2361+ PangoXftRendererClass *xftrenderer_class = PANGO_XFT_RENDERER_CLASS (klass);
2362+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
2363+
2364+ xftrenderer_class->composite_glyphs = gdk_x11_renderer_composite_glyphs;
2365+ xftrenderer_class->composite_trapezoids = gdk_x11_renderer_composite_trapezoids;
2366+
2367+ object_class->finalize = gdk_x11_renderer_finalize;
2368+}
2369+
2370+PangoRenderer *
2371+_gdk_x11_renderer_get (GdkDrawable *drawable,
2372+ GdkGC *gc)
2373+{
2374+ GdkScreen *screen = GDK_DRAWABLE_IMPL_X11 (drawable)->screen;
2375+ GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
2376+ GdkX11Renderer *x11_renderer;
2377+
2378+ if (!screen_x11->renderer)
2379+ {
2380+ screen_x11->renderer = g_object_new (GDK_TYPE_X11_RENDERER,
2381+ "display", GDK_SCREEN_XDISPLAY (screen),
2382+ "screen", GDK_SCREEN_XNUMBER (screen),
2383+ NULL);
2384+ }
2385+
2386+ x11_renderer = GDK_X11_RENDERER (screen_x11->renderer);
2387+
2388+ x11_renderer->drawable = drawable;
2389+ x11_renderer->gc = gc;
2390+
2391+ return screen_x11->renderer;
2392+}
2393+
2394+/**
2395+ * gdk_pango_context_get_for_screen:
2396+ * @screen: the #GdkScreen for which the context is to be created.
2397+ *
2398+ * Creates a #PangoContext for @screen.
2399+ *
2400+ * The context must be freed when you're finished with it.
2401+ *
2402+ * When using GTK+, normally you should use gtk_widget_get_pango_context()
2403+ * instead of this function, to get the appropriate context for
2404+ * the widget you intend to render text onto.
2405+ *
2406+ * Return value: a new #PangoContext for @screen
2407+ *
2408+ * Since: 2.2
2409+ **/
2410+PangoContext *
2411+gdk_pango_context_get_for_screen (GdkScreen *screen)
2412+{
2413+ PangoContext *context;
2414+
2415+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2416+
2417+ if (screen->closed)
2418+ return NULL;
2419+
2420+ context = pango_xft_get_context (GDK_SCREEN_XDISPLAY (screen),
2421+ GDK_SCREEN_X11 (screen)->screen_num);
2422+
2423+ g_object_set_data (G_OBJECT (context), "gdk-pango-screen", screen);
2424+
2425+ return context;
2426+}
2427+
2428+#define __GDK_PANGO_X11_C__
2429+#include "gdkaliasdef.c"
2430Index: gtk+-2.10.6/gdk/x11/gdkpixmap-x11.c
2431===================================================================
2432--- gtk+-2.10.6.orig/gdk/x11/gdkpixmap-x11.c 2006-10-30 12:58:30.000000000 +0000
2433+++ gtk+-2.10.6/gdk/x11/gdkpixmap-x11.c 2006-10-30 12:59:30.000000000 +0000
2434@@ -119,6 +119,9 @@
2435 {
2436 GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (impl);
2437
2438+ if (draw_impl->xft_draw)
2439+ XftDrawDestroy (draw_impl->xft_draw);
2440+
2441 _gdk_x11_drawable_finish (GDK_DRAWABLE (draw_impl));
2442 }
2443
2444--- gtk+-2.10.6.orig/gtk/gtkcalendar.c.orig 2006-11-14 14:39:34.000000000 -0800
2445+++ gtk+-2.10.6/gtk/gtkcalendar.c 2006-11-14 14:37:34.000000000 -0800
2446@@ -1495,6 +1495,10 @@ gtk_calendar_realize (GtkWidget *widget)
2447 BACKGROUND_COLOR ( GTK_WIDGET ( calendar)));
2448 gdk_window_show (priv->main_win);
2449 gdk_window_set_user_data (priv->main_win, widget);
2450+
2451+ /* Set widgets gc */
2452+ calendar->gc = gdk_gc_new (widget->window);
2453+
2454 gdk_window_set_background (widget->window, BACKGROUND_COLOR (widget));
2455 gdk_window_show (widget->window);
2456 gdk_window_set_user_data (widget->window, widget);
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/range-no-redraw.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/range-no-redraw.patch
new file mode 100644
index 0000000000..14387b8a2e
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/range-no-redraw.patch
@@ -0,0 +1,127 @@
15f084ea0849d5967a3c22821542ecaaa8accb398
2diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
3index bd95351..64e0e59 100644
4--- gtk/gtkrange.c
5+++ gtk/gtkrange.c
6@@ -109,6 +109,8 @@ struct _GtkRangeLayout
7 GtkSensitivityType upper_sensitivity;
8
9 gdouble fill_level;
10+
11+ guint motion_idle_id;
12 };
13
14
15@@ -205,6 +207,8 @@ static gboolean gtk_range_real_change_value (GtkRange *range,
16 static void gtk_range_update_value (GtkRange *range);
17 static gboolean gtk_range_key_press (GtkWidget *range,
18 GdkEventKey *event);
19+static void gtk_range_add_motion_idle (GtkRange *range);
20+static void gtk_range_remove_motion_idle (GtkRange *range);
21
22
23 static guint signals[LAST_SIGNAL];
24@@ -1167,6 +1171,7 @@ gtk_range_destroy (GtkObject *object)
25
26 gtk_range_remove_step_timer (range);
27 gtk_range_remove_update_timer (range);
28+ gtk_range_remove_motion_idle (range);
29
30 if (range->adjustment)
31 {
32@@ -1276,6 +1281,7 @@ gtk_range_unrealize (GtkWidget *widget)
33
34 gtk_range_remove_step_timer (range);
35 gtk_range_remove_update_timer (range);
36+ gtk_range_remove_motion_idle (range);
37
38 gdk_window_set_user_data (range->event_window, NULL);
39 gdk_window_destroy (range->event_window);
40@@ -2165,7 +2171,7 @@ gtk_range_motion_notify (GtkWidget *widget,
41 gtk_widget_queue_draw (widget);
42
43 if (range->layout->grab_location == MOUSE_SLIDER)
44- update_slider_position (range, x, y);
45+ gtk_range_add_motion_idle (range);
46
47 /* We handled the event if the mouse was in the range_rect */
48 return range->layout->mouse_location != MOUSE_OUTSIDE;
49@@ -3335,9 +3341,10 @@ initial_timeout (gpointer data)
50 g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
51
52 range = GTK_RANGE (data);
53- range->timer->timeout_id = gdk_threads_add_timeout (timeout * SCROLL_DELAY_FACTOR,
54- second_timeout,
55- range);
56+ range->timer->timeout_id =
57+ gdk_threads_add_timeout (timeout * SCROLL_DELAY_FACTOR,
58+ second_timeout,
59+ range);
60 /* remove self */
61 return FALSE;
62 }
63@@ -3357,9 +3364,8 @@ gtk_range_add_step_timer (GtkRange *range,
64
65 range->timer = g_new (GtkRangeStepTimer, 1);
66
67- range->timer->timeout_id = gdk_threads_add_timeout (timeout,
68- initial_timeout,
69- range);
70+ range->timer->timeout_id =
71+ gdk_threads_add_timeout (timeout, initial_timeout, range);
72 range->timer->step = step;
73
74 gtk_range_scroll (range, range->timer->step);
75@@ -3397,9 +3403,8 @@ gtk_range_reset_update_timer (GtkRange *range)
76 {
77 gtk_range_remove_update_timer (range);
78
79- range->update_timeout_id = gdk_threads_add_timeout (UPDATE_DELAY,
80- update_timeout,
81- range);
82+ range->update_timeout_id =
83+ gdk_threads_add_timeout (UPDATE_DELAY, update_timeout, range);
84 }
85
86 static void
87@@ -3412,5 +3417,40 @@ gtk_range_remove_update_timer (GtkRange *range)
88 }
89 }
90
91+static gboolean
92+motion_idle (gpointer data)
93+{
94+ GtkRange *range = data;
95+ GtkRangeLayout *layout = range->layout;
96+
97+ update_slider_position (range, layout->mouse_x, layout->mouse_y);
98+
99+ layout->motion_idle_id = 0;
100+
101+ return FALSE;
102+}
103+
104+static void
105+gtk_range_add_motion_idle (GtkRange *range)
106+{
107+ if (!range->layout->motion_idle_id)
108+ {
109+ range->layout->motion_idle_id =
110+ gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
111+ motion_idle, range,
112+ NULL);
113+ }
114+}
115+
116+static void
117+gtk_range_remove_motion_idle (GtkRange *range)
118+{
119+ if (range->layout->motion_idle_id != 0)
120+ {
121+ g_source_remove (range->layout->motion_idle_id);
122+ range->layout->motion_idle_id = 0;
123+ }
124+}
125+
126 #define __GTK_RANGE_C__
127 #include "gtkaliasdef.c"
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/run-iconcache.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/run-iconcache.patch
new file mode 100644
index 0000000000..ac15e9ab24
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/run-iconcache.patch
@@ -0,0 +1,19 @@
1--- /tmp/Makefile.am 2007-01-08 17:44:47.000000000 +0100
2+++ gtk+-2.10.7/gtk/Makefile.am 2007-01-08 17:45:17.025251000 +0100
3@@ -1128,11 +1128,11 @@
4 ./gtk-update-icon-cache
5 endif
6
7-gtkbuiltincache.h: @REBUILD@ stamp-icons
8- $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT)
9- $(gtk_update_icon_cache_program) --force --ignore-theme-index \
10- --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \
11- mv gtkbuiltincache.h.tmp gtkbuiltincache.h
12+#gtkbuiltincache.h: @REBUILD@ stamp-icons
13+# $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT)
14+# $(gtk_update_icon_cache_program) --force --ignore-theme-index \
15+# --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \
16+# mv gtkbuiltincache.h.tmp gtkbuiltincache.h
17
18 EXTRA_DIST += \
19 $(STOCK_ICONS) \
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/scrolled-placement.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/scrolled-placement.patch
new file mode 100644
index 0000000000..a0b50c8cac
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/scrolled-placement.patch
@@ -0,0 +1,22 @@
1Index: gdk/x11/gdksettings.c
2===================================================================
3--- gdk/x11/gdksettings.c (revision 18493)
4+++ gdk/x11/gdksettings.c (working copy)
5@@ -65,7 +65,8 @@
6 "Xft/RGBA\0" "gtk-xft-rgba\0"
7 "Xft/DPI\0" "gtk-xft-dpi\0"
8 "Net/FallbackIconTheme\0" "gtk-fallback-icon-theme\0"
9- "Gtk/TouchscreenMode\0" "gtk-touchscreen-mode\0";
10+ "Gtk/TouchscreenMode\0" "gtk-touchscreen-mode\0"
11+ "Gtk/ScrolledWindowPlacement\0" "gtk-scrolled-window-placement\0";
12
13 static const struct
14 {
15@@ -107,5 +108,6 @@
16 { 1197, 1206 },
17 { 1219, 1227 },
18 { 1239, 1261 },
19- { 1285, 1305 }
20+ { 1285, 1305 },
21+ { 1326, 1354 }
22 };
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/toggle-font.diff b/meta/recipes-gnome/gtk+/gtk+-2.12.7/toggle-font.diff
new file mode 100644
index 0000000000..59ad150b2f
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/toggle-font.diff
@@ -0,0 +1,100 @@
1Index: gtk/gtkcellrenderertoggle.c
2===================================================================
3--- gtk/gtkcellrenderertoggle.c (revision 18523)
4+++ gtk/gtkcellrenderertoggle.c (working copy)
5@@ -71,6 +71,8 @@
6 PROP_INDICATOR_SIZE
7 };
8
9+/* This is a hard-coded default which promptly gets overridden by a size
10+ calculated from the font size. */
11 #define TOGGLE_WIDTH 13
12
13 static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };
14@@ -80,8 +82,9 @@
15 typedef struct _GtkCellRendererTogglePrivate GtkCellRendererTogglePrivate;
16 struct _GtkCellRendererTogglePrivate
17 {
18- gint indicator_size;
19-
20+ gint indicator_size; /* This is the real size */
21+ gint override_size; /* This is the size set from the indicator-size property */
22+ GtkWidget *cached_widget;
23 guint inconsistent : 1;
24 };
25
26@@ -104,6 +107,7 @@
27 GTK_CELL_RENDERER (celltoggle)->ypad = 2;
28
29 priv->indicator_size = TOGGLE_WIDTH;
30+ priv->override_size = 0;
31 priv->inconsistent = FALSE;
32 }
33
34@@ -210,7 +214,7 @@
35 g_value_set_boolean (value, celltoggle->radio);
36 break;
37 case PROP_INDICATOR_SIZE:
38- g_value_set_int (value, priv->indicator_size);
39+ g_value_set_int (value, priv->override_size ? priv->override_size : priv->indicator_size);
40 break;
41 default:
42 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
43@@ -245,7 +249,7 @@
44 celltoggle->radio = g_value_get_boolean (value);
45 break;
46 case PROP_INDICATOR_SIZE:
47- priv->indicator_size = g_value_get_int (value);
48+ priv->override_size = g_value_get_int (value);
49 break;
50 default:
51 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
52@@ -273,6 +277,27 @@
53 }
54
55 static void
56+on_widget_style_set (GtkWidget *widget, GtkStyle *previous, gpointer user_data)
57+{
58+ GtkCellRendererTogglePrivate *priv = user_data;
59+ PangoContext *context;
60+ PangoFontMetrics *metrics;
61+ int height;
62+
63+ context = gtk_widget_get_pango_context (widget);
64+ metrics = pango_context_get_metrics (context,
65+ widget->style->font_desc,
66+ pango_context_get_language (context));
67+
68+ height = pango_font_metrics_get_ascent (metrics) +
69+ pango_font_metrics_get_descent (metrics);
70+
71+ pango_font_metrics_unref (metrics);
72+
73+ priv->indicator_size = PANGO_PIXELS (height * 0.85);
74+}
75+
76+static void
77 gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
78 GtkWidget *widget,
79 GdkRectangle *cell_area,
80@@ -287,6 +312,20 @@
81
82 priv = GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE (cell);
83
84+ if (priv->override_size) {
85+ priv->indicator_size = priv->override_size;
86+ } else if (priv->cached_widget != widget) {
87+ if (priv->cached_widget) {
88+ g_object_remove_weak_pointer (widget, &priv->cached_widget);
89+ g_signal_handlers_disconnect_by_func (priv->cached_widget, on_widget_style_set, priv);
90+ }
91+ priv->cached_widget = widget;
92+ g_object_add_weak_pointer (widget, &priv->cached_widget);
93+ g_signal_connect (widget, "style-set", on_widget_style_set, priv);
94+
95+ on_widget_style_set (widget, NULL, priv);
96+ }
97+
98 calc_width = (gint) cell->xpad * 2 + priv->indicator_size;
99 calc_height = (gint) cell->ypad * 2 + priv->indicator_size;
100
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/xsettings.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/xsettings.patch
new file mode 100644
index 0000000000..b63e262d34
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/xsettings.patch
@@ -0,0 +1,16 @@
1--- gtk+-2.4.4/gdk/x11/gdkevents-x11.c.old Sun Aug 22 17:14:00 2004
2+++ gtk+-2.4.4/gdk/x11/gdkevents-x11.c Sun Aug 22 17:14:00 2004
3@@ -2827,10 +2827,9 @@
4 {
5 GdkScreenX11 *screen = data;
6
7- if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent))
8- return GDK_FILTER_REMOVE;
9- else
10- return GDK_FILTER_CONTINUE;
11+ xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent);
12+
13+ return GDK_FILTER_CONTINUE;
14 }
15
16 static void
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch b/meta/recipes-gnome/gtk+/gtk+-2.16.6/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch
new file mode 100644
index 0000000000..e0d6ab9522
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch
@@ -0,0 +1,31 @@
1From 69b9441eab2a7215509687dc22b48b6f212d22aa Mon Sep 17 00:00:00 2001
2From: Rob Bradford <rob@linux.intel.com>
3Date: Thu, 4 Jun 2009 15:43:20 +0100
4Subject: [PATCH] =?utf-8?q?bgo#584832=20=E2=80=93=20Duplicate=20the=20exec=20string=20returned=20by=20gtk=5Frecent=5Finfo=5Fget=5Fapplication=5Finfo?=
5MIME-Version: 1.0
6Content-Type: text/plain; charset=utf-8
7Content-Transfer-Encoding: 8bit
8
9This function states that the caller is responsible for freeing the string
10passed returned by reference. Unfortunately if you do this you get a crash
11since the internal value is returned without being duplicated.
12---
13 gtk/gtkrecentmanager.c | 2 +-
14 1 files changed, 1 insertions(+), 1 deletions(-)
15
16diff --git a/gtk/gtkrecentmanager.c b/gtk/gtkrecentmanager.c
17index 317b3d5..d062572 100644
18--- a/gtk/gtkrecentmanager.c
19+++ b/gtk/gtkrecentmanager.c
20@@ -1764,7 +1764,7 @@ gtk_recent_info_get_application_info (GtkRecentInfo *info,
21 }
22
23 if (app_exec)
24- *app_exec = ai->exec;
25+ *app_exec = g_strdup (ai->exec);
26
27 if (count)
28 *count = ai->count;
29--
301.6.3.1
31
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/cellrenderer-cairo.patch b/meta/recipes-gnome/gtk+/gtk+-2.16.6/cellrenderer-cairo.patch
new file mode 100644
index 0000000000..4439e69fb6
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/cellrenderer-cairo.patch
@@ -0,0 +1,32 @@
1Index: gtk/gtkcellrenderer.c
2===================================================================
3RCS file: /cvs/gnome/gtk+/gtk/gtkcellrenderer.c,v
4retrieving revision 1.55
5diff -u -r1.55 gtkcellrenderer.c
6--- gtk/gtkcellrenderer.c 14 May 2006 04:25:28 -0000 1.55
7+++ gtk/gtkcellrenderer.c 30 Jun 2006 10:57:43 -0000
8@@ -551,6 +551,7 @@
9
10 if (cell->cell_background_set && !selected)
11 {
12+#ifdef USE_CAIRO_INTERNALLY
13 cairo_t *cr = gdk_cairo_create (window);
14
15 gdk_cairo_rectangle (cr, background_area);
16@@ -558,6 +559,16 @@
17 cairo_fill (cr);
18
19 cairo_destroy (cr);
20+#else
21+ GdkGC *gc;
22+
23+ gc = gdk_gc_new (window);
24+ gdk_gc_set_rgb_fg_color (gc, &priv->cell_background);
25+ gdk_draw_rectangle (window, gc, TRUE,
26+ background_area->x, background_area->y,
27+ background_area->width, background_area->height);
28+ g_object_unref (gc);
29+#endif
30 }
31
32 GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/disable-gio-png-sniff-test.diff b/meta/recipes-gnome/gtk+/gtk+-2.16.6/disable-gio-png-sniff-test.diff
new file mode 100644
index 0000000000..5c64ac04de
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/disable-gio-png-sniff-test.diff
@@ -0,0 +1,97 @@
1Index: gtk+-2.14.2/configure.in
2===================================================================
3--- gtk+-2.14.2.orig/configure.in 2008-09-23 16:32:42.000000000 +0100
4+++ gtk+-2.14.2/configure.in 2008-09-23 16:37:13.000000000 +0100
5@@ -1025,48 +1025,50 @@
6 # check one of the variables here
7 AM_CONDITIONAL(INCLUDE_GDIPLUS, [test x"$INCLUDE_gdip_ico" = xyes])
8
9-if test x$gio_can_sniff = x; then
10- AC_MSG_CHECKING([if gio can sniff png])
11- gtk_save_LIBS="$LIBS"
12- gtk_save_CFLAGS="$CFLAGS"
13- LIBS="`$PKG_CONFIG --libs gio-2.0`"
14- CFLAGS="`$PKG_CONFIG --cflags gio-2.0`"
15- AC_RUN_IFELSE([AC_LANG_SOURCE([[
16- #include <gio/gio.h>
17- static const gsize data_size = 159;
18- static const guint8 data[] =
19- {
20- 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
21- 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
22- 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xde, 0x00, 0x00, 0x00,
23- 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
24- 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00,
25- 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74,
26- 0x49, 0x4d, 0x45, 0x07, 0xd8, 0x07, 0x0f, 0x10, 0x08, 0x15, 0x61, 0xd8,
27- 0x35, 0x37, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f,
28- 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
29- 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57,
30- 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08,
31- 0xd7, 0x63, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x05, 0xfe, 0x02, 0xfe, 0xdc,
32- 0xcc, 0x59, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
33- 0x42, 0x60, 0x82
34- };
35- int
36- main (int argc, char **argv)
37- {
38- char *content_type;
39- char *image_png;
40- content_type = g_content_type_guess (NULL, data, data_size, NULL);
41- image_png = g_content_type_from_mime_type ("image/png");
42- return !!strcmp (content_type, image_png);
43- }]])],
44- [gio_can_sniff=yes
45- AC_DEFINE(GDK_PIXBUF_USE_GIO_MIME, 1, [Define if gio can sniff image data])],
46- [gio_can_sniff=no])
47- AC_MSG_RESULT($gio_can_sniff)
48- LIBS="$gtk_save_LIBS"
49- CFLAGS="$gtk_save_CFLAGS"
50-fi
51+# Disabled due to cross-compile
52+#if test x$gio_can_sniff = x; then
53+# AC_MSG_CHECKING([if gio can sniff png])
54+# gtk_save_LIBS="$LIBS"
55+# gtk_save_CFLAGS="$CFLAGS"
56+# LIBS="`$PKG_CONFIG --libs gio-2.0`"
57+# CFLAGS="`$PKG_CONFIG --cflags gio-2.0`"
58+# AC_RUN_IFELSE([AC_LANG_SOURCE([[
59+# #include <gio/gio.h>
60+# static const gsize data_size = 159;
61+# static const guint8 data[] =
62+# {
63+# 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
64+# 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
65+# 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xde, 0x00, 0x00, 0x00,
66+# 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
67+# 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00,
68+# 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74,
69+# 0x49, 0x4d, 0x45, 0x07, 0xd8, 0x07, 0x0f, 0x10, 0x08, 0x15, 0x61, 0xd8,
70+# 0x35, 0x37, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f,
71+# 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
72+# 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57,
73+# 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08,
74+# 0xd7, 0x63, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x05, 0xfe, 0x02, 0xfe, 0xdc,
75+# 0xcc, 0x59, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
76+# 0x42, 0x60, 0x82
77+# };
78+# int
79+# main (int argc, char **argv)
80+# {
81+# char *content_type;
82+# char *image_png;
83+# content_type = g_content_type_guess (NULL, data, data_size, NULL);
84+# image_png = g_content_type_from_mime_type ("image/png");
85+# return !!strcmp (content_type, image_png);
86+# }]])],
87+# [gio_can_sniff=yes
88+# [gio_can_sniff=no])
89+# AC_MSG_RESULT($gio_can_sniff)
90+# LIBS="$gtk_save_LIBS"
91+# CFLAGS="$gtk_save_CFLAGS"
92+#fi
93+
94+AC_DEFINE(GDK_PIXBUF_USE_GIO_MIME, 1, [Define if gio can sniff image data])],
95
96 #
97 # Allow building some or all immodules included
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/entry-cairo.patch b/meta/recipes-gnome/gtk+/gtk+-2.16.6/entry-cairo.patch
new file mode 100644
index 0000000000..3313e7f132
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/entry-cairo.patch
@@ -0,0 +1,103 @@
1Index: gtk/gtkentry.c
2===================================================================
3RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
4retrieving revision 1.317
5diff -u -r1.317 gtkentry.c
6--- gtk/gtkentry.c 29 Jun 2006 09:18:05 -0000 1.317
7+++ gtk/gtkentry.c 2 Jul 2006 14:14:24 -0000
8@@ -3337,7 +3337,9 @@
9 if (GTK_WIDGET_DRAWABLE (entry))
10 {
11 PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
12+#ifdef USE_CAIRO_INTERNALLY
13 cairo_t *cr;
14+#endif
15 gint x, y;
16 gint start_pos, end_pos;
17
18@@ -3345,23 +3347,35 @@
19
20 get_layout_position (entry, &x, &y);
21
22+#ifdef USE_CAIRO_INTERNALLY
23 cr = gdk_cairo_create (entry->text_area);
24
25 cairo_move_to (cr, x, y);
26 gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
27 pango_cairo_show_layout (cr, layout);
28+#else
29+ gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
30+ x, y,
31+ layout);
32+#endif
33
34 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
35 {
36 gint *ranges;
37 gint n_ranges, i;
38 PangoRectangle logical_rect;
39- GdkColor *selection_color, *text_color;
40 GtkBorder inner_border;
41+#ifdef USE_CAIRO_INTERNALLY
42+ GdkColor *selection_color, *text_color;
43+#else
44+ GdkGC *selection_gc, *text_gc;
45+ GdkRegion *clip_region;
46+#endif
47
48 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
49 gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
50
51+#ifdef USE_CAIRO_INTERNALLY
52 if (GTK_WIDGET_HAS_FOCUS (entry))
53 {
54 selection_color = &widget->style->base [GTK_STATE_SELECTED];
55@@ -3390,11 +3404,46 @@
56 cairo_move_to (cr, x, y);
57 gdk_cairo_set_source_color (cr, text_color);
58 pango_cairo_show_layout (cr, layout);
59-
60+#else
61+ if (GTK_WIDGET_HAS_FOCUS (entry))
62+ {
63+ selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
64+ text_gc = widget->style->text_gc [GTK_STATE_SELECTED];
65+ }
66+ else
67+ {
68+ selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE];
69+ text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
70+ }
71+
72+ clip_region = gdk_region_new ();
73+ for (i = 0; i < n_ranges; ++i)
74+ {
75+ GdkRectangle rect;
76+
77+ rect.x = inner_border.left - entry->scroll_offset + ranges[2 * i];
78+ rect.y = y;
79+ rect.width = ranges[2 * i + 1];
80+ rect.height = logical_rect.height;
81+
82+ gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
83+ rect.x, rect.y, rect.width, rect.height);
84+
85+ gdk_region_union_with_rect (clip_region, &rect);
86+ }
87+
88+ gdk_gc_set_clip_region (text_gc, clip_region);
89+ gdk_draw_layout (entry->text_area, text_gc,
90+ x, y,
91+ layout);
92+ gdk_gc_set_clip_region (text_gc, NULL);
93+ gdk_region_destroy (clip_region);
94+#endif
95 g_free (ranges);
96 }
97-
98+#ifdef USE_CAIRO_INTERNALLY
99 cairo_destroy (cr);
100+#endif
101 }
102 }
103
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/hardcoded_libtool.patch b/meta/recipes-gnome/gtk+/gtk+-2.16.6/hardcoded_libtool.patch
new file mode 100644
index 0000000000..82fbbac8d7
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/hardcoded_libtool.patch
@@ -0,0 +1,31 @@
1Index: gtk+-2.14.2/configure.in
2===================================================================
3--- gtk+-2.14.2.orig/configure.in 2008-09-23 15:52:44.000000000 +0100
4+++ gtk+-2.14.2/configure.in 2008-09-23 15:53:51.000000000 +0100
5@@ -401,7 +401,7 @@
6 case $enable_explicit_deps in
7 auto)
8 export SED
9- deplibs_check_method=`(./libtool --config; echo 'eval echo \"$deplibs_check_method\"') | sh`
10+ deplibs_check_method=`(./$host_alias-libtool --config; echo 'eval echo \"$deplibs_check_method\"') | sh`
11 if test "x$deplibs_check_method" '!=' xpass_all || test "x$enable_static" = xyes ; then
12 enable_explicit_deps=yes
13 else
14@@ -759,7 +759,7 @@
15 dnl Now we check to see if our libtool supports shared lib deps
16 dnl (in a rather ugly way even)
17 if $dynworks; then
18- pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} ./libtool --config"
19+ pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} $host_alias-libtool --config"
20 pixbuf_deplibs_check=`$pixbuf_libtool_config | \
21 grep '^[[a-z_]]*check[[a-z_]]*_method=[['\''"]]' | \
22 sed 's/.*[['\''"]]\(.*\)[['\''"]]$/\1/'`
23@@ -1893,7 +1893,7 @@
24 # We are using gmodule-no-export now, but I'm leaving the stripping
25 # code in place for now, since pango and atk still require gmodule.
26 export SED
27-export_dynamic=`(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`
28+export_dynamic=`($host_alias-libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`
29 if test -n "$export_dynamic"; then
30 GDK_PIXBUF_DEP_LIBS=`echo $GDK_PIXBUF_DEP_LIBS | sed -e "s/$export_dynamic//"`
31 GDK_PIXBUF_XLIB_DEP_LIBS=`echo $GDK_PIXBUF_XLIB_DEP_LIBS | sed -e "s/$export_dynamic//"`
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/no-demos.patch b/meta/recipes-gnome/gtk+/gtk+-2.16.6/no-demos.patch
new file mode 100644
index 0000000000..0fc4c48d1a
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/no-demos.patch
@@ -0,0 +1,10 @@
1--- gtk+-2.10.1/Makefile.am.orig 2006-08-08 12:37:30.000000000 +0100
2+++ gtk+-2.10.1/Makefile.am 2006-08-08 12:37:48.000000000 +0100
3@@ -1,6 +1,6 @@
4 ## Makefile.am for GTK+
5
6-SRC_SUBDIRS = gdk-pixbuf gdk gtk modules demos tests perf contrib
7+SRC_SUBDIRS = gdk-pixbuf gdk gtk modules tests perf contrib
8 SUBDIRS = po po-properties $(SRC_SUBDIRS) docs m4macros
9
10 # require automake 1.4
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/run-iconcache.patch b/meta/recipes-gnome/gtk+/gtk+-2.16.6/run-iconcache.patch
new file mode 100644
index 0000000000..ac15e9ab24
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/run-iconcache.patch
@@ -0,0 +1,19 @@
1--- /tmp/Makefile.am 2007-01-08 17:44:47.000000000 +0100
2+++ gtk+-2.10.7/gtk/Makefile.am 2007-01-08 17:45:17.025251000 +0100
3@@ -1128,11 +1128,11 @@
4 ./gtk-update-icon-cache
5 endif
6
7-gtkbuiltincache.h: @REBUILD@ stamp-icons
8- $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT)
9- $(gtk_update_icon_cache_program) --force --ignore-theme-index \
10- --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \
11- mv gtkbuiltincache.h.tmp gtkbuiltincache.h
12+#gtkbuiltincache.h: @REBUILD@ stamp-icons
13+# $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT)
14+# $(gtk_update_icon_cache_program) --force --ignore-theme-index \
15+# --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \
16+# mv gtkbuiltincache.h.tmp gtkbuiltincache.h
17
18 EXTRA_DIST += \
19 $(STOCK_ICONS) \
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/toggle-font.diff b/meta/recipes-gnome/gtk+/gtk+-2.16.6/toggle-font.diff
new file mode 100644
index 0000000000..59ad150b2f
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/toggle-font.diff
@@ -0,0 +1,100 @@
1Index: gtk/gtkcellrenderertoggle.c
2===================================================================
3--- gtk/gtkcellrenderertoggle.c (revision 18523)
4+++ gtk/gtkcellrenderertoggle.c (working copy)
5@@ -71,6 +71,8 @@
6 PROP_INDICATOR_SIZE
7 };
8
9+/* This is a hard-coded default which promptly gets overridden by a size
10+ calculated from the font size. */
11 #define TOGGLE_WIDTH 13
12
13 static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };
14@@ -80,8 +82,9 @@
15 typedef struct _GtkCellRendererTogglePrivate GtkCellRendererTogglePrivate;
16 struct _GtkCellRendererTogglePrivate
17 {
18- gint indicator_size;
19-
20+ gint indicator_size; /* This is the real size */
21+ gint override_size; /* This is the size set from the indicator-size property */
22+ GtkWidget *cached_widget;
23 guint inconsistent : 1;
24 };
25
26@@ -104,6 +107,7 @@
27 GTK_CELL_RENDERER (celltoggle)->ypad = 2;
28
29 priv->indicator_size = TOGGLE_WIDTH;
30+ priv->override_size = 0;
31 priv->inconsistent = FALSE;
32 }
33
34@@ -210,7 +214,7 @@
35 g_value_set_boolean (value, celltoggle->radio);
36 break;
37 case PROP_INDICATOR_SIZE:
38- g_value_set_int (value, priv->indicator_size);
39+ g_value_set_int (value, priv->override_size ? priv->override_size : priv->indicator_size);
40 break;
41 default:
42 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
43@@ -245,7 +249,7 @@
44 celltoggle->radio = g_value_get_boolean (value);
45 break;
46 case PROP_INDICATOR_SIZE:
47- priv->indicator_size = g_value_get_int (value);
48+ priv->override_size = g_value_get_int (value);
49 break;
50 default:
51 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
52@@ -273,6 +277,27 @@
53 }
54
55 static void
56+on_widget_style_set (GtkWidget *widget, GtkStyle *previous, gpointer user_data)
57+{
58+ GtkCellRendererTogglePrivate *priv = user_data;
59+ PangoContext *context;
60+ PangoFontMetrics *metrics;
61+ int height;
62+
63+ context = gtk_widget_get_pango_context (widget);
64+ metrics = pango_context_get_metrics (context,
65+ widget->style->font_desc,
66+ pango_context_get_language (context));
67+
68+ height = pango_font_metrics_get_ascent (metrics) +
69+ pango_font_metrics_get_descent (metrics);
70+
71+ pango_font_metrics_unref (metrics);
72+
73+ priv->indicator_size = PANGO_PIXELS (height * 0.85);
74+}
75+
76+static void
77 gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
78 GtkWidget *widget,
79 GdkRectangle *cell_area,
80@@ -287,6 +312,20 @@
81
82 priv = GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE (cell);
83
84+ if (priv->override_size) {
85+ priv->indicator_size = priv->override_size;
86+ } else if (priv->cached_widget != widget) {
87+ if (priv->cached_widget) {
88+ g_object_remove_weak_pointer (widget, &priv->cached_widget);
89+ g_signal_handlers_disconnect_by_func (priv->cached_widget, on_widget_style_set, priv);
90+ }
91+ priv->cached_widget = widget;
92+ g_object_add_weak_pointer (widget, &priv->cached_widget);
93+ g_signal_connect (widget, "style-set", on_widget_style_set, priv);
94+
95+ on_widget_style_set (widget, NULL, priv);
96+ }
97+
98 calc_width = (gint) cell->xpad * 2 + priv->indicator_size;
99 calc_height = (gint) cell->ypad * 2 + priv->indicator_size;
100
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.16.6/xsettings.patch b/meta/recipes-gnome/gtk+/gtk+-2.16.6/xsettings.patch
new file mode 100644
index 0000000000..b63e262d34
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.16.6/xsettings.patch
@@ -0,0 +1,16 @@
1--- gtk+-2.4.4/gdk/x11/gdkevents-x11.c.old Sun Aug 22 17:14:00 2004
2+++ gtk+-2.4.4/gdk/x11/gdkevents-x11.c Sun Aug 22 17:14:00 2004
3@@ -2827,10 +2827,9 @@
4 {
5 GdkScreenX11 *screen = data;
6
7- if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent))
8- return GDK_FILTER_REMOVE;
9- else
10- return GDK_FILTER_CONTINUE;
11+ xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent);
12+
13+ return GDK_FILTER_CONTINUE;
14 }
15
16 static void
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch
new file mode 100644
index 0000000000..ee55f9cc3b
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch
@@ -0,0 +1,28 @@
1From 69b9441eab2a7215509687dc22b48b6f212d22aa Mon Sep 17 00:00:00 2001
2From: Rob Bradford <rob@linux.intel.com>
3Date: Thu, 4 Jun 2009 15:43:20 +0100
4Subject: [PATCH] =?utf-8?q?bgo#584832=20=E2=80=93=20Duplicate=20the=20exec=20string=20returned=20by=20gtk=5Frecent=5Finfo=5Fget=5Fapplication=5Finfo?=
5MIME-Version: 1.0
6Content-Type: text/plain; charset=utf-8
7Content-Transfer-Encoding: 8bit
8
9This function states that the caller is responsible for freeing the string
10passed returned by reference. Unfortunately if you do this you get a crash
11since the internal value is returned without being duplicated.
12---
13 gtk/gtkrecentmanager.c | 2 +-
14 1 files changed, 1 insertions(+), 1 deletions(-)
15
16Index: gtk+-2.21.2/gtk/gtkrecentmanager.c
17===================================================================
18--- gtk+-2.21.2.orig/gtk/gtkrecentmanager.c 2010-06-22 18:11:30.000000000 +0800
19+++ gtk+-2.21.2/gtk/gtkrecentmanager.c 2010-06-22 18:11:53.000000000 +0800
20@@ -1766,7 +1766,7 @@
21 }
22
23 if (app_exec)
24- *app_exec = ai->exec;
25+ *app_exec = g_strdup (ai->exec);
26
27 if (count)
28 *count = ai->count;
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/cellrenderer-cairo.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/cellrenderer-cairo.patch
new file mode 100644
index 0000000000..92ce643125
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/cellrenderer-cairo.patch
@@ -0,0 +1,29 @@
1Index: gtk/gtkcellrenderer.c
2===================================================================
3--- gtk/gtkcellrenderer.c.orig 2010-06-22 17:21:22.000000000 +0800
4+++ gtk/gtkcellrenderer.c 2010-06-22 17:21:25.000000000 +0800
5@@ -566,6 +566,7 @@
6
7 if (cell->cell_background_set && !selected)
8 {
9+#ifdef USE_CAIRO_INTERNALLY
10 cairo_t *cr = gdk_cairo_create (window);
11
12 gdk_cairo_rectangle (cr, background_area);
13@@ -573,6 +574,16 @@
14 cairo_fill (cr);
15
16 cairo_destroy (cr);
17+#else
18+ GdkGC *gc;
19+
20+ gc = gdk_gc_new (window);
21+ gdk_gc_set_rgb_fg_color (gc, &priv->cell_background);
22+ gdk_draw_rectangle (window, gc, TRUE,
23+ background_area->x, background_area->y,
24+ background_area->width, background_area->height);
25+ g_object_unref (gc);
26+#endif
27 }
28
29 GTK_CELL_RENDERER_GET_CLASS (cell)->render (cell,
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/configurefix.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/configurefix.patch
new file mode 100644
index 0000000000..7f6c73be49
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/configurefix.patch
@@ -0,0 +1,85 @@
1Index: gtk+-2.21.2/docs/faq/Makefile.am
2===================================================================
3--- gtk+-2.21.2.orig/docs/faq/Makefile.am 2010-04-09 10:29:53.000000000 +0800
4+++ gtk+-2.21.2/docs/faq/Makefile.am 2010-06-22 17:39:24.000000000 +0800
5@@ -3,34 +3,36 @@
6 EXTRA_DIST += \
7 gtk-faq.sgml
8
9-if HAVE_DOCBOOK
10+
11 html:
12+if HAVE_DOCBOOK
13 if test -w $(srcdir); then \
14 (cd $(srcdir); \
15 db2html gtk-faq.sgml; \
16 test -d html && rm -r html; \
17 mv gtk-faq html); \
18 fi
19-
20-pdf:
21- if test -w $(srcdir); then \
22- (cd $(srcdir); db2pdf gtk-faq.sgml); \
23- fi
24-
25-dist-hook: html
26- cp -Rp $(srcdir)/html $(distdir)
27 else
28-html:
29 echo "***"
30 echo "*** Warning: FAQ not built"
31 echo "***"
32+endif
33
34 pdf:
35+if HAVE_DOCBOOK
36+ if test -w $(srcdir); then \
37+ (cd $(srcdir); db2pdf gtk-faq.sgml); \
38+ fi
39+else
40 echo "***"
41 echo "*** Warning: FAQ not built"
42 echo "***"
43+endif
44
45-dist-hook:
46+dist-hook: html
47+if HAVE_DOCBOOK
48+ cp -Rp $(srcdir)/html $(distdir)
49+else
50 echo "***"
51 echo "*** Warning: FAQ not built"
52 echo "*** DISTRIBUTION IS INCOMPLETE"
53Index: gtk+-2.21.2/gtk-doc.make
54===================================================================
55--- gtk+-2.21.2.orig/gtk-doc.make 2010-05-28 00:01:48.000000000 +0800
56+++ gtk+-2.21.2/gtk-doc.make 2010-06-22 17:39:24.000000000 +0800
57@@ -23,7 +23,7 @@
58
59 TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
60
61-EXTRA_DIST = \
62+EXTRA_DIST += \
63 $(content_files) \
64 $(HTML_IMAGES) \
65 $(DOC_MAIN_SGML_FILE) \
66Index: gtk+-2.21.2/gtk/tests/Makefile.am
67===================================================================
68--- gtk+-2.21.2.orig/gtk/tests/Makefile.am 2010-06-10 20:53:46.000000000 +0800
69+++ gtk+-2.21.2/gtk/tests/Makefile.am 2010-06-22 17:39:24.000000000 +0800
70@@ -58,13 +58,13 @@
71 # this doesn't work in make distcheck, since running
72 # on a naked X server creates slightly different event
73 # sequences than running on a normal desktop
74-# TEST_PROGS += crossingevents
75+#TEST_PROGS += crossingevents
76 crossingevents_SOURCES = crossingevents.c
77 crossingevents_LDADD = $(progs_ldadd)
78
79 # this doesn't work in make distcheck, since it doesn't
80 # find file-chooser-test-dir
81-# TEST_PROGS += filechooser
82+#TEST_PROGS += filechooser
83 filechooser_SOURCES = filechooser.c pixbuf-init.c
84 filechooser_LDADD = $(progs_ldadd)
85
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/disable-gio-png-sniff-test.diff b/meta/recipes-gnome/gtk+/gtk+-2.20.1/disable-gio-png-sniff-test.diff
new file mode 100644
index 0000000000..13ae61ef88
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/disable-gio-png-sniff-test.diff
@@ -0,0 +1,97 @@
1Index: gtk+-2.21.2/configure.in
2===================================================================
3--- gtk+-2.21.2.orig/configure.in 2010-06-22 18:14:40.000000000 +0800
4+++ gtk+-2.21.2/configure.in 2010-06-22 18:14:58.000000000 +0800
5@@ -1072,48 +1072,50 @@
6 # check one of the variables here
7 AM_CONDITIONAL(INCLUDE_GDIPLUS, [test x"$INCLUDE_gdip_ico" = xyes])
8
9-if test x$gio_can_sniff = x; then
10- AC_MSG_CHECKING([if gio can sniff png])
11- gtk_save_LIBS="$LIBS"
12- gtk_save_CFLAGS="$CFLAGS"
13- LIBS="`$PKG_CONFIG --libs gio-2.0`"
14- CFLAGS="`$PKG_CONFIG --cflags gio-2.0`"
15- AC_RUN_IFELSE([AC_LANG_SOURCE([[
16- #include <gio/gio.h>
17- static const gsize data_size = 159;
18- static const guint8 data[] =
19- {
20- 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
21- 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
22- 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xde, 0x00, 0x00, 0x00,
23- 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
24- 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00,
25- 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74,
26- 0x49, 0x4d, 0x45, 0x07, 0xd8, 0x07, 0x0f, 0x10, 0x08, 0x15, 0x61, 0xd8,
27- 0x35, 0x37, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f,
28- 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
29- 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57,
30- 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08,
31- 0xd7, 0x63, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x05, 0xfe, 0x02, 0xfe, 0xdc,
32- 0xcc, 0x59, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
33- 0x42, 0x60, 0x82
34- };
35- int
36- main (int argc, char **argv)
37- {
38- char *content_type;
39- char *image_png;
40- content_type = g_content_type_guess (NULL, data, data_size, NULL);
41- image_png = g_content_type_from_mime_type ("image/png");
42- return !!strcmp (content_type, image_png);
43- }]])],
44- [gio_can_sniff=yes
45- AC_DEFINE(GDK_PIXBUF_USE_GIO_MIME, 1, [Define if gio can sniff image data])],
46- [gio_can_sniff=no])
47- AC_MSG_RESULT($gio_can_sniff)
48- LIBS="$gtk_save_LIBS"
49- CFLAGS="$gtk_save_CFLAGS"
50-fi
51+# Disabled due to cross-compile
52+#if test x$gio_can_sniff = x; then
53+# AC_MSG_CHECKING([if gio can sniff png])
54+# gtk_save_LIBS="$LIBS"
55+# gtk_save_CFLAGS="$CFLAGS"
56+# LIBS="`$PKG_CONFIG --libs gio-2.0`"
57+# CFLAGS="`$PKG_CONFIG --cflags gio-2.0`"
58+# AC_RUN_IFELSE([AC_LANG_SOURCE([[
59+# #include <gio/gio.h>
60+# static const gsize data_size = 159;
61+# static const guint8 data[] =
62+# {
63+# 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
64+# 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
65+# 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xde, 0x00, 0x00, 0x00,
66+# 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
67+# 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00,
68+# 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74,
69+# 0x49, 0x4d, 0x45, 0x07, 0xd8, 0x07, 0x0f, 0x10, 0x08, 0x15, 0x61, 0xd8,
70+# 0x35, 0x37, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f,
71+# 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
72+# 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57,
73+# 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08,
74+# 0xd7, 0x63, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x05, 0xfe, 0x02, 0xfe, 0xdc,
75+# 0xcc, 0x59, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
76+# 0x42, 0x60, 0x82
77+# };
78+# int
79+# main (int argc, char **argv)
80+# {
81+# char *content_type;
82+# char *image_png;
83+# content_type = g_content_type_guess (NULL, data, data_size, NULL);
84+# image_png = g_content_type_from_mime_type ("image/png");
85+# return !!strcmp (content_type, image_png);
86+# }]])],
87+# [gio_can_sniff=yes
88+# [gio_can_sniff=no])
89+# AC_MSG_RESULT($gio_can_sniff)
90+# LIBS="$gtk_save_LIBS"
91+# CFLAGS="$gtk_save_CFLAGS"
92+#fi
93+
94+AC_DEFINE(GDK_PIXBUF_USE_GIO_MIME, 1, [Define if gio can sniff image data])],
95
96 #
97 # Allow building some or all immodules included
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/entry-cairo.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/entry-cairo.patch
new file mode 100644
index 0000000000..3313e7f132
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/entry-cairo.patch
@@ -0,0 +1,103 @@
1Index: gtk/gtkentry.c
2===================================================================
3RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
4retrieving revision 1.317
5diff -u -r1.317 gtkentry.c
6--- gtk/gtkentry.c 29 Jun 2006 09:18:05 -0000 1.317
7+++ gtk/gtkentry.c 2 Jul 2006 14:14:24 -0000
8@@ -3337,7 +3337,9 @@
9 if (GTK_WIDGET_DRAWABLE (entry))
10 {
11 PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
12+#ifdef USE_CAIRO_INTERNALLY
13 cairo_t *cr;
14+#endif
15 gint x, y;
16 gint start_pos, end_pos;
17
18@@ -3345,23 +3347,35 @@
19
20 get_layout_position (entry, &x, &y);
21
22+#ifdef USE_CAIRO_INTERNALLY
23 cr = gdk_cairo_create (entry->text_area);
24
25 cairo_move_to (cr, x, y);
26 gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
27 pango_cairo_show_layout (cr, layout);
28+#else
29+ gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
30+ x, y,
31+ layout);
32+#endif
33
34 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
35 {
36 gint *ranges;
37 gint n_ranges, i;
38 PangoRectangle logical_rect;
39- GdkColor *selection_color, *text_color;
40 GtkBorder inner_border;
41+#ifdef USE_CAIRO_INTERNALLY
42+ GdkColor *selection_color, *text_color;
43+#else
44+ GdkGC *selection_gc, *text_gc;
45+ GdkRegion *clip_region;
46+#endif
47
48 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
49 gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
50
51+#ifdef USE_CAIRO_INTERNALLY
52 if (GTK_WIDGET_HAS_FOCUS (entry))
53 {
54 selection_color = &widget->style->base [GTK_STATE_SELECTED];
55@@ -3390,11 +3404,46 @@
56 cairo_move_to (cr, x, y);
57 gdk_cairo_set_source_color (cr, text_color);
58 pango_cairo_show_layout (cr, layout);
59-
60+#else
61+ if (GTK_WIDGET_HAS_FOCUS (entry))
62+ {
63+ selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
64+ text_gc = widget->style->text_gc [GTK_STATE_SELECTED];
65+ }
66+ else
67+ {
68+ selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE];
69+ text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
70+ }
71+
72+ clip_region = gdk_region_new ();
73+ for (i = 0; i < n_ranges; ++i)
74+ {
75+ GdkRectangle rect;
76+
77+ rect.x = inner_border.left - entry->scroll_offset + ranges[2 * i];
78+ rect.y = y;
79+ rect.width = ranges[2 * i + 1];
80+ rect.height = logical_rect.height;
81+
82+ gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
83+ rect.x, rect.y, rect.width, rect.height);
84+
85+ gdk_region_union_with_rect (clip_region, &rect);
86+ }
87+
88+ gdk_gc_set_clip_region (text_gc, clip_region);
89+ gdk_draw_layout (entry->text_area, text_gc,
90+ x, y,
91+ layout);
92+ gdk_gc_set_clip_region (text_gc, NULL);
93+ gdk_region_destroy (clip_region);
94+#endif
95 g_free (ranges);
96 }
97-
98+#ifdef USE_CAIRO_INTERNALLY
99 cairo_destroy (cr);
100+#endif
101 }
102 }
103
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/hardcoded_libtool.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/hardcoded_libtool.patch
new file mode 100644
index 0000000000..66be74475b
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/hardcoded_libtool.patch
@@ -0,0 +1,31 @@
1Index: gtk+-2.21.2/configure.in
2===================================================================
3--- gtk+-2.21.2.orig/configure.in 2010-06-22 17:21:41.000000000 +0800
4+++ gtk+-2.21.2/configure.in 2010-06-22 17:28:59.000000000 +0800
5@@ -425,7 +425,7 @@
6 case $enable_explicit_deps in
7 auto)
8 export SED
9- deplibs_check_method=`(./libtool --config; echo 'eval echo \"$deplibs_check_method\"') | sh`
10+ deplibs_check_method=`(./$host_alias-libtool --config; echo 'eval echo \"$deplibs_check_method\"') | sh`
11 if test "x$deplibs_check_method" '!=' xpass_all || test "x$enable_static" = xyes ; then
12 enable_explicit_deps=yes
13 else
14@@ -804,7 +804,7 @@
15 dnl Now we check to see if our libtool supports shared lib deps
16 dnl (in a rather ugly way even)
17 if $dynworks; then
18- pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} ./libtool --config"
19+ pixbuf_libtool_config="${CONFIG_SHELL-/bin/sh} $host_alias-libtool --config"
20 pixbuf_deplibs_check=`$pixbuf_libtool_config | \
21 grep '^[[a-z_]]*check[[a-z_]]*_method=[['\''"]]' | \
22 sed 's/.*[['\''"]]\(.*\)[['\''"]]$/\1/'`
23@@ -1974,7 +1974,7 @@
24 # We are using gmodule-no-export now, but I'm leaving the stripping
25 # code in place for now, since pango and atk still require gmodule.
26 export SED
27-export_dynamic=`(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`
28+export_dynamic=`($host_alias-libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh`
29 if test -n "$export_dynamic"; then
30 GDK_PIXBUF_DEP_LIBS=`echo $GDK_PIXBUF_DEP_LIBS | sed -e "s/$export_dynamic//"`
31 GDK_PIXBUF_XLIB_DEP_LIBS=`echo $GDK_PIXBUF_XLIB_DEP_LIBS | sed -e "s/$export_dynamic//"`
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/no-demos.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/no-demos.patch
new file mode 100644
index 0000000000..0fc4c48d1a
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/no-demos.patch
@@ -0,0 +1,10 @@
1--- gtk+-2.10.1/Makefile.am.orig 2006-08-08 12:37:30.000000000 +0100
2+++ gtk+-2.10.1/Makefile.am 2006-08-08 12:37:48.000000000 +0100
3@@ -1,6 +1,6 @@
4 ## Makefile.am for GTK+
5
6-SRC_SUBDIRS = gdk-pixbuf gdk gtk modules demos tests perf contrib
7+SRC_SUBDIRS = gdk-pixbuf gdk gtk modules tests perf contrib
8 SUBDIRS = po po-properties $(SRC_SUBDIRS) docs m4macros
9
10 # require automake 1.4
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/run-iconcache.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/run-iconcache.patch
new file mode 100644
index 0000000000..518875e6fd
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/run-iconcache.patch
@@ -0,0 +1,21 @@
1Index: gtk+-2.21.2/gtk/Makefile.am
2===================================================================
3--- gtk+-2.21.2.orig/gtk/Makefile.am 2010-06-22 17:21:41.000000000 +0800
4+++ gtk+-2.21.2/gtk/Makefile.am 2010-06-22 17:28:12.000000000 +0800
5@@ -1376,11 +1376,11 @@
6 ./gtk-update-icon-cache
7 endif
8
9-gtkbuiltincache.h: @REBUILD@ stamp-icons
10- $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT) $(GTK_UPDATE_ICON_CACHE_MANIFEST)
11- $(gtk_update_icon_cache_program) --force --ignore-theme-index \
12- --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \
13- mv gtkbuiltincache.h.tmp gtkbuiltincache.h
14+#gtkbuiltincache.h: @REBUILD@ stamp-icons
15+# $(MAKE) $(AM_MAKEFLAGS) gtk-update-icon-cache$(EXEEXT) $(GTK_UPDATE_ICON_CACHE_MANIFEST)
16+# $(gtk_update_icon_cache_program) --force --ignore-theme-index \
17+# --source builtin_icons stock-icons > gtkbuiltincache.h.tmp && \
18+# mv gtkbuiltincache.h.tmp gtkbuiltincache.h
19
20 EXTRA_DIST += \
21 $(STOCK_ICONS) \
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/toggle-font.diff b/meta/recipes-gnome/gtk+/gtk+-2.20.1/toggle-font.diff
new file mode 100644
index 0000000000..4853628c82
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/toggle-font.diff
@@ -0,0 +1,100 @@
1Index: gtk/gtkcellrenderertoggle.c
2===================================================================
3--- gtk/gtkcellrenderertoggle.c.orig 2010-06-22 18:11:33.000000000 +0800
4+++ gtk/gtkcellrenderertoggle.c 2010-06-22 18:11:43.000000000 +0800
5@@ -71,6 +71,8 @@
6 PROP_INDICATOR_SIZE
7 };
8
9+/* This is a hard-coded default which promptly gets overridden by a size
10+ calculated from the font size. */
11 #define TOGGLE_WIDTH 13
12
13 static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };
14@@ -80,8 +82,9 @@
15 typedef struct _GtkCellRendererTogglePrivate GtkCellRendererTogglePrivate;
16 struct _GtkCellRendererTogglePrivate
17 {
18- gint indicator_size;
19-
20+ gint indicator_size; /* This is the real size */
21+ gint override_size; /* This is the size set from the indicator-size property */
22+ GtkWidget *cached_widget;
23 guint inconsistent : 1;
24 };
25
26@@ -104,6 +107,7 @@
27 GTK_CELL_RENDERER (celltoggle)->ypad = 2;
28
29 priv->indicator_size = TOGGLE_WIDTH;
30+ priv->override_size = 0;
31 priv->inconsistent = FALSE;
32 }
33
34@@ -210,7 +214,7 @@
35 g_value_set_boolean (value, celltoggle->radio);
36 break;
37 case PROP_INDICATOR_SIZE:
38- g_value_set_int (value, priv->indicator_size);
39+ g_value_set_int (value, priv->override_size ? priv->override_size : priv->indicator_size);
40 break;
41 default:
42 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
43@@ -245,7 +249,7 @@
44 celltoggle->radio = g_value_get_boolean (value);
45 break;
46 case PROP_INDICATOR_SIZE:
47- priv->indicator_size = g_value_get_int (value);
48+ priv->override_size = g_value_get_int (value);
49 break;
50 default:
51 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
52@@ -273,6 +277,27 @@
53 }
54
55 static void
56+on_widget_style_set (GtkWidget *widget, GtkStyle *previous, gpointer user_data)
57+{
58+ GtkCellRendererTogglePrivate *priv = user_data;
59+ PangoContext *context;
60+ PangoFontMetrics *metrics;
61+ int height;
62+
63+ context = gtk_widget_get_pango_context (widget);
64+ metrics = pango_context_get_metrics (context,
65+ widget->style->font_desc,
66+ pango_context_get_language (context));
67+
68+ height = pango_font_metrics_get_ascent (metrics) +
69+ pango_font_metrics_get_descent (metrics);
70+
71+ pango_font_metrics_unref (metrics);
72+
73+ priv->indicator_size = PANGO_PIXELS (height * 0.85);
74+}
75+
76+static void
77 gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
78 GtkWidget *widget,
79 GdkRectangle *cell_area,
80@@ -287,6 +312,20 @@
81
82 priv = GTK_CELL_RENDERER_TOGGLE_GET_PRIVATE (cell);
83
84+ if (priv->override_size) {
85+ priv->indicator_size = priv->override_size;
86+ } else if (priv->cached_widget != widget) {
87+ if (priv->cached_widget) {
88+ g_object_remove_weak_pointer (widget, &priv->cached_widget);
89+ g_signal_handlers_disconnect_by_func (priv->cached_widget, on_widget_style_set, priv);
90+ }
91+ priv->cached_widget = widget;
92+ g_object_add_weak_pointer (widget, &priv->cached_widget);
93+ g_signal_connect (widget, "style-set", on_widget_style_set, priv);
94+
95+ on_widget_style_set (widget, NULL, priv);
96+ }
97+
98 calc_width = (gint) cell->xpad * 2 + priv->indicator_size;
99 calc_height = (gint) cell->ypad * 2 + priv->indicator_size;
100
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.20.1/xsettings.patch b/meta/recipes-gnome/gtk+/gtk+-2.20.1/xsettings.patch
new file mode 100644
index 0000000000..84231e9b91
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.20.1/xsettings.patch
@@ -0,0 +1,18 @@
1Index: gtk+-2.21.2/gdk/x11/gdkevents-x11.c
2===================================================================
3--- gtk+-2.21.2.orig/gdk/x11/gdkevents-x11.c 2010-06-22 17:28:04.000000000 +0800
4+++ gtk+-2.21.2/gdk/x11/gdkevents-x11.c 2010-06-22 17:28:06.000000000 +0800
5@@ -3062,10 +3062,9 @@
6 {
7 GdkScreenX11 *screen = data;
8
9- if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent))
10- return GDK_FILTER_REMOVE;
11- else
12- return GDK_FILTER_CONTINUE;
13+ xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent);
14+
15+ return GDK_FILTER_CONTINUE;
16 }
17
18 static Bool
diff --git a/meta/recipes-gnome/gtk+/gtk+.inc b/meta/recipes-gnome/gtk+/gtk+.inc
new file mode 100644
index 0000000000..f7fa00d5c4
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+.inc
@@ -0,0 +1,85 @@
1DESCRIPTION = "GTK+ is a multi-platform toolkit for creating graphical user interfaces. Offering a complete \
2set of widgets, GTK+ is suitable for projects ranging from small one-off projects to complete application suites."
3HOMEPAGE = "http://www.gtk.org"
4BUGTRACKER = "https://bugzilla.gnome.org/"
5
6LICENSE = "LGPLv2 & LGPLv2+ & LGPLv2.1+"
7
8SECTION = "libs"
9PRIORITY = "optional"
10DEPENDS = "glib-2.0 pango atk jpeg libpng libxext libxcursor gtk-doc-native libxrandr \
11 libgcrypt libxdamage libxrender libxcomposite cairo"
12
13inherit autotools pkgconfig
14
15FILES_${PN} = "${bindir}/gdk-pixbuf-query-loaders \
16 ${bindir}/gtk-update-icon-cache \
17 ${bindir}/gtk-query-immodules-2.0 \
18 ${libdir}/lib*${SOLIBS} \
19 ${datadir}/themes ${sysconfdir} \
20 ${libdir}/gtk-2.0/${LIBV}/engines/libpixmap.so"
21
22FILES_${PN}-dev += " \
23 ${datadir}/gtk-2.0/include \
24 ${libdir}/gtk-2.0/include \
25 ${libdir}/gtk-2.0/${LIBV}/loaders/*.la \
26 ${libdir}/gtk-2.0/${LIBV}/immodules/*.la \
27 ${libdir}/gtk-2.0/${LIBV}/engines/*.la \
28 ${bindir}/gdk-pixbuf-csource \
29 ${bindir}/gtk-builder-convert"
30
31FILES_${PN}-dbg += " \
32 ${libdir}/gtk-2.0/${LIBV}/loaders/.debug/* \
33 ${libdir}/gtk-2.0/${LIBV}/immodules/.debug/* \
34 ${libdir}/gtk-2.0/${LIBV}/engines/.debug/* \
35 ${libdir}/gtk-2.0/${LIBV}/printbackends/.debug/*"
36
37BASE_RRECOMMENDS = "ttf-dejavu-sans"
38BASE_RRECOMMENDS_angstrom = "ttf-dejavu-sans gdk-pixbuf-loader-png gdk-pixbuf-loader-jpeg gdk-pixbuf-loader-gif gdk-pixbuf-loader-xpm"
39BASE_RRECOMMENDS_poky = "gdk-pixbuf-loader-png gdk-pixbuf-loader-jpeg gdk-pixbuf-loader-gif gdk-pixbuf-loader-xpm shared-mime-info"
40BASE_RRECOMMENDS_moblin = "gdk-pixbuf-loader-png gdk-pixbuf-loader-jpeg gdk-pixbuf-loader-gif gdk-pixbuf-loader-xpm shared-mime-info"
41
42GLIBC_RRECOMMENDS= "${BASE_RRECOMMENDS} glibc-gconv-iso8859-1"
43
44RRECOMMENDS_${PN} = "${BASE_RRECOMMENDS}"
45RRECOMMENDS_${PN}_linux = "${GLIBC_RRECOMMENDS}"
46RRECOMMENDS_${PN}_linux-gnueabi = "${GLIBC_RRECOMMENDS}"
47
48do_install () {
49 autotools_do_install
50
51 install -d ${D}${sysconfdir}/gtk-2.0
52
53 mkdir -p ${D}${libdir}/gtk-2.0/include
54 install -m 0644 gdk/gdkconfig.h ${D}${libdir}/gtk-2.0/include/gdkconfig.h
55
56 install -m 0644 gtk/gtkfilechooserprivate.h ${D}${includedir}/gtk-2.0/gtk/
57 install -m 0644 gtk/gtkfilechooserutils.h ${D}${includedir}/gtk-2.0/gtk/
58 install -m 0644 gtk/gtkfilesystemmodel.h ${D}${includedir}/gtk-2.0/gtk/
59}
60
61SYSROOT_PREPROCESS_FUNCS += "gtk_sysroot_preprocess"
62
63gtk_sysroot_preprocess () {
64 if [ -e ${D}${bindir}/gtk-builder-convert ]; then
65 install -d ${SYSROOT_DESTDIR}${STAGING_BINDIR_CROSS}/
66 install -m 755 ${D}${bindir}/gtk-builder-convert ${SYSROOT_DESTDIR}${STAGING_BINDIR_CROSS}/
67 fi
68}
69
70postinst_prologue() {
71if [ "x$D" != "x" ]; then
72 exit 1
73fi
74
75}
76
77postinst_pixbufloader() {
78if [ "x$D" != "x" ]; then
79 exit 1
80fi
81
82gdk-pixbuf-query-loaders > ${sysconfdir}/gtk-2.0/gdk-pixbuf.loaders
83
84test -x ${bindir}/gtk-update-icon-cache && gtk-update-icon-cache -q ${datadir}/icons/hicolor
85}
diff --git a/meta/recipes-gnome/gtk+/gtk+_2.12.7.bb b/meta/recipes-gnome/gtk+/gtk+_2.12.7.bb
new file mode 100644
index 0000000000..d829308513
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+_2.12.7.bb
@@ -0,0 +1,50 @@
1require gtk+.inc
2
3PR = "r9"
4
5SRC_URI = "http://download.gnome.org/sources/gtk+/2.12/gtk+-${PV}.tar.bz2 \
6 file://xsettings.patch;patch=1 \
7 file://run-iconcache.patch;patch=1 \
8 file://disable-print.patch;patch=1 \
9 file://hardcoded_libtool.patch;patch=1 \
10 file://no-demos.patch;patch=1 \
11 file://cellrenderer-cairo.patch;patch=1;pnum=0 \
12 file://entry-cairo.patch;patch=1;pnum=0 \
13 file://toggle-font.diff;patch=1;pnum=0 \
14 file://scrolled-placement.patch;patch=1;pnum=0 \
15 file://filesystem-volumes.patch;patch=1 \
16 file://filechooser-props.patch;patch=1 \
17 file://filechooser-default.patch;patch=1 \
18 file://filechooser-sizefix.patch;patch=1 \
19# temporary
20# file://gtklabel-resize-patch;patch=1 \
21# file://menu-deactivate.patch;patch=1 \
22# file://combo-arrow-size.patch;patch=1;pnum=0 \
23# die die die
24# file://pangoxft2.10.6.diff;patch=1 \
25 "
26
27EXTRA_OECONF = "--without-libtiff --disable-xkb --disable-glibtest --enable-display-migration"
28
29LIBV = "2.10.0"
30
31PACKAGES_DYNAMIC += "gdk-pixbuf-loader-* gtk-immodule-* gtk-printbackend-*"
32
33python populate_packages_prepend () {
34 import os.path
35
36 prologue = bb.data.getVar("postinst_prologue", d, 1)
37 postinst_pixbufloader = bb.data.getVar("postinst_pixbufloader", d, 1)
38
39 gtk_libdir = bb.data.expand('${libdir}/gtk-2.0/${LIBV}', d)
40 loaders_root = os.path.join(gtk_libdir, 'loaders')
41 immodules_root = os.path.join(gtk_libdir, 'immodules')
42 printmodules_root = os.path.join(gtk_libdir, 'printbackends');
43
44 do_split_packages(d, loaders_root, '^libpixbufloader-(.*)\.so$', 'gdk-pixbuf-loader-%s', 'GDK pixbuf loader for %s', postinst_pixbufloader)
45 do_split_packages(d, immodules_root, '^im-(.*)\.so$', 'gtk-immodule-%s', 'GTK input module for %s', prologue + 'gtk-query-immodules-2.0 > /etc/gtk-2.0/gtk.immodules')
46 do_split_packages(d, printmodules_root, '^libprintbackend-(.*)\.so$', 'gtk-printbackend-%s', 'GTK printbackend module for %s')
47
48 if (bb.data.getVar('DEBIAN_NAMES', d, 1)):
49 bb.data.setVar('PKG_${PN}', 'libgtk-2.0', d)
50}
diff --git a/meta/recipes-gnome/gtk+/gtk+_2.16.6.bb b/meta/recipes-gnome/gtk+/gtk+_2.16.6.bb
new file mode 100644
index 0000000000..becd2bc29c
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+_2.16.6.bb
@@ -0,0 +1,49 @@
1require gtk+.inc
2
3PR = "r5"
4
5SRC_URI = "http://download.gnome.org/sources/gtk+/2.16/gtk+-${PV}.tar.bz2 \
6 file://xsettings.patch;patch=1 \
7 file://run-iconcache.patch;patch=1 \
8 file://hardcoded_libtool.patch;patch=1 \
9 file://no-demos.patch;patch=1 \
10 file://cellrenderer-cairo.patch;patch=1;pnum=0 \
11 file://toggle-font.diff;patch=1;pnum=0 \
12 file://0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch;patch=1 \
13# TO MERGE
14# file://entry-cairo.patch;patch=1;pnum=0 \
15# file://filesystem-volumes.patch;patch=1 \
16# file://filechooser-props.patch;patch=1 \
17# file://filechooser-default.patch;patch=1 \
18# file://filechooser-sizefix.patch;patch=1 \
19# temporary
20# file://gtklabel-resize-patch;patch=1 \
21# file://menu-deactivate.patch;patch=1 \
22# file://combo-arrow-size.patch;patch=1;pnum=0 \
23 file://disable-gio-png-sniff-test.diff;patch=1 \
24 "
25
26EXTRA_OECONF = "--without-libtiff --without-libjasper --disable-xkb --disable-glibtest --disable-cups"
27
28LIBV = "2.10.0"
29
30PACKAGES_DYNAMIC += "gdk-pixbuf-loader-* gtk-immodule-* gtk-printbackend-*"
31
32python populate_packages_prepend () {
33 import os.path
34
35 prologue = bb.data.getVar("postinst_prologue", d, 1)
36 postinst_pixbufloader = bb.data.getVar("postinst_pixbufloader", d, 1)
37
38 gtk_libdir = bb.data.expand('${libdir}/gtk-2.0/${LIBV}', d)
39 loaders_root = os.path.join(gtk_libdir, 'loaders')
40 immodules_root = os.path.join(gtk_libdir, 'immodules')
41 printmodules_root = os.path.join(gtk_libdir, 'printbackends');
42
43 do_split_packages(d, loaders_root, '^libpixbufloader-(.*)\.so$', 'gdk-pixbuf-loader-%s', 'GDK pixbuf loader for %s', postinst_pixbufloader)
44 do_split_packages(d, immodules_root, '^im-(.*)\.so$', 'gtk-immodule-%s', 'GTK input module for %s', prologue + 'gtk-query-immodules-2.0 > /etc/gtk-2.0/gtk.immodules')
45 do_split_packages(d, printmodules_root, '^libprintbackend-(.*)\.so$', 'gtk-printbackend-%s', 'GTK printbackend module for %s')
46
47 if (bb.data.getVar('DEBIAN_NAMES', d, 1)):
48 bb.data.setVar('PKG_${PN}', 'libgtk-2.0', d)
49}
diff --git a/meta/recipes-gnome/gtk+/gtk+_2.20.1.bb b/meta/recipes-gnome/gtk+/gtk+_2.20.1.bb
new file mode 100644
index 0000000000..00de6950a3
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+_2.20.1.bb
@@ -0,0 +1,54 @@
1require gtk+.inc
2
3LIC_FILES_CHKSUM = "file://COPYING;md5=3bf50002aefd002f49e7bb854063f7e7 \
4 file://gtk/gtk.h;endline=27;md5=c59e0b4490dd135a5726ebf851f9b17f \
5 file://gdk/gdk.h;endline=27;md5=07db285ec208fb3e0bf7d861b0614202 \
6 file://tests/testgtk.c;endline=27;md5=262db5db5f776f9863e56df31423e24c"
7PR = "r0"
8
9SRC_URI = "http://download.gnome.org/sources/gtk+/2.20/gtk+-${PV}.tar.bz2 \
10 file://xsettings.patch;patch=1 \
11 file://run-iconcache.patch;patch=1 \
12 file://hardcoded_libtool.patch;patch=1 \
13 file://no-demos.patch;patch=1 \
14 file://cellrenderer-cairo.patch;patch=1;pnum=0 \
15 file://toggle-font.diff;patch=1;pnum=0 \
16 file://0001-bgo-584832-Duplicate-the-exec-string-returned-by-gtk.patch;patch=1 \
17# TO MERGE
18# file://entry-cairo.patch;patch=1;pnum=0 \
19# file://filesystem-volumes.patch;patch=1 \
20# file://filechooser-props.patch;patch=1 \
21# file://filechooser-default.patch;patch=1 \
22# file://filechooser-sizefix.patch;patch=1 \
23# temporary
24# file://gtklabel-resize-patch;patch=1 \
25# file://menu-deactivate.patch;patch=1 \
26# file://combo-arrow-size.patch;patch=1;pnum=0 \
27 file://disable-gio-png-sniff-test.diff;patch=1 \
28 file://configurefix.patch;patch=1 \
29 "
30
31EXTRA_OECONF = "--without-libtiff --without-libjasper --disable-xkb --disable-glibtest --disable-cups"
32
33LIBV = "2.10.0"
34
35PACKAGES_DYNAMIC += "gdk-pixbuf-loader-* gtk-immodule-* gtk-printbackend-*"
36
37python populate_packages_prepend () {
38 import os.path
39
40 prologue = bb.data.getVar("postinst_prologue", d, 1)
41 postinst_pixbufloader = bb.data.getVar("postinst_pixbufloader", d, 1)
42
43 gtk_libdir = bb.data.expand('${libdir}/gtk-2.0/${LIBV}', d)
44 loaders_root = os.path.join(gtk_libdir, 'loaders')
45 immodules_root = os.path.join(gtk_libdir, 'immodules')
46 printmodules_root = os.path.join(gtk_libdir, 'printbackends');
47
48 do_split_packages(d, loaders_root, '^libpixbufloader-(.*)\.so$', 'gdk-pixbuf-loader-%s', 'GDK pixbuf loader for %s', postinst_pixbufloader)
49 do_split_packages(d, immodules_root, '^im-(.*)\.so$', 'gtk-immodule-%s', 'GTK input module for %s', prologue + 'gtk-query-immodules-2.0 > /etc/gtk-2.0/gtk.immodules')
50 do_split_packages(d, printmodules_root, '^libprintbackend-(.*)\.so$', 'gtk-printbackend-%s', 'GTK printbackend module for %s')
51
52 if (bb.data.getVar('DEBIAN_NAMES', d, 1)):
53 bb.data.setVar('PKG_${PN}', 'libgtk-2.0', d)
54}