summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2020-12-02 20:15:28 +0100
committerBenjamin Otte <otte@redhat.com>2020-12-03 02:02:27 +0100
commiteb9c204535962fd2918d1338a292a42b32c3ae10 (patch)
tree07dc41846236d40de9a232678b9a0f627abe5f6c
parenta51f11999a13998c190856951c9a0ae98b824954 (diff)
downloadgtk+-eb9c204535962fd2918d1338a292a42b32c3ae10.tar.gz
gtk: Remove GtkFileChooserButton
... as discussed in the meeting.
-rw-r--r--demos/gtk-demo/listview_words.c36
-rw-r--r--demos/gtk-demo/paintable_svg.c57
-rw-r--r--demos/gtk-demo/pickers.c38
-rw-r--r--demos/widget-factory/widget-factory.ui3
-rw-r--r--docs/reference/gtk/gtk4-docs.xml1
-rw-r--r--docs/reference/gtk/gtk4-sections.txt25
-rw-r--r--docs/reference/gtk/gtk4.types.in1
-rw-r--r--docs/tools/widgets.c46
-rw-r--r--gtk/gtk-autocleanups.h1
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtkfilechooser.c11
-rw-r--r--gtk/gtkfilechooserbutton.c2930
-rw-r--r--gtk/gtkfilechooserbutton.h62
-rw-r--r--gtk/meson.build2
-rw-r--r--tests/meson.build1
-rw-r--r--tests/testfilechooserbutton.c283
-rw-r--r--testsuite/gtk/defaultvalue.c3
-rw-r--r--testsuite/gtk/focus-chain/widget-factory.tab1
-rw-r--r--testsuite/gtk/focus-chain/widget-factory.tab-backward1
-rw-r--r--testsuite/gtk/focus-chain/widget-factory.ui3
-rw-r--r--testsuite/gtk/focus-chain/widget-factory2.ui3
-rw-r--r--testsuite/gtk/focus-chain/widget-factory3.ui3
-rw-r--r--testsuite/gtk/notify.c3
-rw-r--r--testsuite/gtk/object.c2
-rw-r--r--testsuite/gtk/templates.c18
25 files changed, 80 insertions, 3455 deletions
diff --git a/demos/gtk-demo/listview_words.c b/demos/gtk-demo/listview_words.c
index 867f74e652..e2a5a1e2fa 100644
--- a/demos/gtk-demo/listview_words.c
+++ b/demos/gtk-demo/listview_words.c
@@ -142,16 +142,42 @@ load_file (GtkStringList *list,
}
static void
-file_selected_cb (GtkWidget *button,
+open_response_cb (GtkWidget *dialog,
+ int response,
GtkStringList *stringlist)
{
- GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
+ gtk_widget_hide (dialog);
- if (file)
+ if (response == GTK_RESPONSE_ACCEPT)
{
+ GFile *file;
+
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
load_file (stringlist, file);
g_object_unref (file);
}
+
+ gtk_window_destroy (GTK_WINDOW (dialog));
+}
+
+static void
+file_open_cb (GtkWidget *button,
+ GtkStringList *stringlist)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new ("Open file",
+ GTK_WINDOW (gtk_widget_get_root (button)),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Load", GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), stringlist);
+ gtk_widget_show (dialog);
}
GtkWidget *
@@ -189,8 +215,8 @@ do_listview_words (GtkWidget *do_widget)
header = gtk_header_bar_new ();
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
- open_button = gtk_file_chooser_button_new ("_Open", GTK_FILE_CHOOSER_ACTION_OPEN);
- g_signal_connect (open_button, "file-set", G_CALLBACK (file_selected_cb), stringlist);
+ open_button = gtk_button_new_with_mnemonic ("_Open");
+ g_signal_connect (open_button, "clicked", G_CALLBACK (file_open_cb), stringlist);
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), open_button);
gtk_window_set_titlebar (GTK_WINDOW (window), header);
diff --git a/demos/gtk-demo/paintable_svg.c b/demos/gtk-demo/paintable_svg.c
index eab506f4ed..9d87f121ac 100644
--- a/demos/gtk-demo/paintable_svg.c
+++ b/demos/gtk-demo/paintable_svg.c
@@ -13,19 +13,50 @@
static void
-file_set (GtkFileChooserButton *button,
- GtkWidget *picture)
+open_response_cb (GtkWidget *dialog,
+ int response,
+ GtkPicture *picture)
{
- GFile *file;
- GdkPaintable *paintable;
+ gtk_widget_hide (dialog);
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ GFile *file;
+ GdkPaintable *paintable;
+
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+ paintable = svg_paintable_new (file);
+ gtk_picture_set_paintable (GTK_PICTURE (picture), paintable);
+ g_object_unref (paintable);
+ g_object_unref (file);
+ }
- file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
+ gtk_window_destroy (GTK_WINDOW (dialog));
+}
- paintable = svg_paintable_new (file);
- gtk_picture_set_paintable (GTK_PICTURE (picture), paintable);
+static void
+show_file_open (GtkWidget *button,
+ GtkPicture *picture)
+{
+ GtkFileFilter *filter;
+ GtkWidget *dialog;
- g_object_unref (paintable);
- g_object_unref (file);
+ dialog = gtk_file_chooser_dialog_new ("Open node file",
+ GTK_WINDOW (gtk_widget_get_root (button)),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Load", GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_mime_type (filter, "image/svg+xml");
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), picture);
+ gtk_widget_show (dialog);
}
static GtkWidget *window;
@@ -35,7 +66,6 @@ do_paintable_svg (GtkWidget *do_widget)
{
GtkWidget *header;
GtkWidget *picture;
- GtkFileFilter *filter;
GtkWidget *button;
GFile *file;
GdkPaintable *paintable;
@@ -49,17 +79,14 @@ do_paintable_svg (GtkWidget *do_widget)
gtk_window_set_title (GTK_WINDOW (window), "Paintable — SVG");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
- button = gtk_file_chooser_button_new ("Select an SVG file", GTK_FILE_CHOOSER_ACTION_OPEN);
- filter = gtk_file_filter_new ();
- gtk_file_filter_add_mime_type (filter, "image/svg+xml");
- gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (button), filter);
+ button = gtk_button_new_with_mnemonic ("_Open");
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
picture = gtk_picture_new ();
gtk_picture_set_can_shrink (GTK_PICTURE (picture), TRUE);
gtk_widget_set_size_request (picture, 16, 16);
- g_signal_connect (button, "file-set", G_CALLBACK (file_set), picture);
+ g_signal_connect (button, "clicked", G_CALLBACK (show_file_open), picture);
gtk_window_set_child (GTK_WINDOW (window), picture);
diff --git a/demos/gtk-demo/pickers.c b/demos/gtk-demo/pickers.c
index 0b42034030..e5f6ef99d4 100644
--- a/demos/gtk-demo/pickers.c
+++ b/demos/gtk-demo/pickers.c
@@ -63,9 +63,6 @@ do_pickers (GtkWidget *do_widget)
if (!window)
{
- char *dir;
- GFile *file;
-
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
@@ -129,41 +126,6 @@ do_pickers (GtkWidget *do_widget)
gtk_widget_set_hexpand (label, TRUE);
gtk_grid_attach (GTK_GRID (table), label, 0, 2, 1, 1);
- picker = gtk_file_chooser_button_new ("Pick a File",
- GTK_FILE_CHOOSER_ACTION_OPEN);
- gtk_grid_attach (GTK_GRID (table), picker, 1, 2, 1, 1);
-
- picker = gtk_file_chooser_button_new ("Pick a File",
- GTK_FILE_CHOOSER_ACTION_OPEN);
-
- dir = g_get_current_dir ();
- file = g_file_new_for_path (dir);
- gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (picker), file, NULL);
- g_object_unref (file);
- g_free (dir);
-
- gtk_file_chooser_add_choice (GTK_FILE_CHOOSER (picker),
- "choice",
- "Encoding",
- (const char *[]) { "option1", "option2", NULL },
- (const char *[]) { "UTF-8", "Other Encoding", NULL });
- gtk_file_chooser_set_choice (GTK_FILE_CHOOSER (picker), "choice", "option1");
- gtk_file_chooser_add_choice (GTK_FILE_CHOOSER (picker),
- "check",
- "Read backwards",
- NULL, NULL);
- gtk_file_chooser_set_choice (GTK_FILE_CHOOSER (picker), "check", "false");
-
- gtk_grid_attach (GTK_GRID (table), picker, 2, 2, 1, 1);
-
- label = gtk_label_new ("Folder:");
- gtk_widget_set_halign (label, GTK_ALIGN_START);
- gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
- picker = gtk_file_chooser_button_new ("Pick a Folder",
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
- gtk_grid_attach (GTK_GRID (table), label, 0, 3, 1, 1);
- gtk_grid_attach (GTK_GRID (table), picker, 1, 3, 1, 1);
-
label = gtk_label_new ("Mail:");
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui
index ba2378ba34..6d6f539140 100644
--- a/demos/widget-factory/widget-factory.ui
+++ b/demos/widget-factory/widget-factory.ui
@@ -879,9 +879,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</object>
</child>
<child>
- <object class="GtkFileChooserButton" id="filechooserbutton1"/>
- </child>
- <child>
<object class="GtkLinkButton" id="linkbutton1">
<property name="label" translatable="yes">link button</property>
<property name="receives-default">1</property>
diff --git a/docs/reference/gtk/gtk4-docs.xml b/docs/reference/gtk/gtk4-docs.xml
index 25ed9eebd7..faae8a2de6 100644
--- a/docs/reference/gtk/gtk4-docs.xml
+++ b/docs/reference/gtk/gtk4-docs.xml
@@ -283,7 +283,6 @@
<xi:include href="xml/gtkcolorchooserwidget.xml" />
<xi:include href="xml/gtkcolorchooserdialog.xml" />
<xi:include href="xml/gtkfilechooser.xml" />
- <xi:include href="xml/gtkfilechooserbutton.xml" />
<xi:include href="xml/gtkfilechoosernative.xml" />
<xi:include href="xml/gtkfilechooserdialog.xml" />
<xi:include href="xml/gtkfilechooserwidget.xml" />
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index c6e8f87a58..faad758464 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -1340,31 +1340,6 @@ GtkFileChooserWidgetPrivate
</SECTION>
<SECTION>
-<FILE>gtkfilechooserbutton</FILE>
-<TITLE>GtkFileChooserButton</TITLE>
-GtkFileChooserButton
-gtk_file_chooser_button_new
-gtk_file_chooser_button_new_with_dialog
-gtk_file_chooser_button_get_title
-gtk_file_chooser_button_set_title
-gtk_file_chooser_button_get_width_chars
-gtk_file_chooser_button_set_width_chars
-gtk_file_chooser_button_get_modal
-gtk_file_chooser_button_set_modal
-
-<SUBSECTION Standard>
-GTK_FILE_CHOOSER_BUTTON
-GTK_IS_FILE_CHOOSER_BUTTON
-GTK_TYPE_FILE_CHOOSER_BUTTON
-GTK_FILE_CHOOSER_BUTTON_CLASS
-GTK_IS_FILE_CHOOSER_BUTTON_CLASS
-GTK_FILE_CHOOSER_BUTTON_GET_CLASS
-<SUBSECTION Private>
-gtk_file_chooser_button_get_type
-GtkFileChooserButtonPrivate
-</SECTION>
-
-<SECTION>
<FILE>gtkfilefilter</FILE>
GtkFileFilter
gtk_file_filter_new
diff --git a/docs/reference/gtk/gtk4.types.in b/docs/reference/gtk/gtk4.types.in
index 5981ffb897..9bc79517f7 100644
--- a/docs/reference/gtk/gtk4.types.in
+++ b/docs/reference/gtk/gtk4.types.in
@@ -87,7 +87,6 @@ gtk_event_controller_motion_get_type
gtk_event_controller_scroll_get_type
gtk_every_filter_get_type
gtk_expander_get_type
-gtk_file_chooser_button_get_type
gtk_file_chooser_dialog_get_type
gtk_file_chooser_get_type
gtk_file_chooser_native_get_type
diff --git a/docs/tools/widgets.c b/docs/tools/widgets.c
index 51889d8e96..884939adb5 100644
--- a/docs/tools/widgets.c
+++ b/docs/tools/widgets.c
@@ -616,51 +616,6 @@ create_font_button (void)
}
static WidgetInfo *
-create_file_button (void)
-{
- GtkWidget *vbox;
- GtkWidget *vbox2;
- GtkWidget *picker;
- char *path;
- GFile *file;
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
- picker = gtk_file_chooser_button_new ("File Chooser Button",
- GTK_FILE_CHOOSER_ACTION_OPEN);
- gtk_widget_set_size_request (picker, 150, -1);
- gtk_widget_set_halign (picker, GTK_ALIGN_CENTER);
- gtk_widget_set_valign (picker, GTK_ALIGN_CENTER);
- gtk_box_append (GTK_BOX (vbox2), picker);
- gtk_box_append (GTK_BOX (vbox2),
- gtk_label_new ("File Button (Files)"));
-
- gtk_box_append (GTK_BOX (vbox),
- vbox2);
- gtk_box_append (GTK_BOX (vbox),
- gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
-
- vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
- picker = gtk_file_chooser_button_new ("File Chooser Button",
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
- gtk_widget_set_size_request (picker, 150, -1);
- path = g_build_filename (g_get_home_dir (), "Documents", NULL);
- file = g_file_new_for_path (path);
- gtk_file_chooser_set_file (GTK_FILE_CHOOSER (picker), file, NULL);
- g_free (path);
- g_object_unref (file);
- gtk_widget_set_halign (picker, GTK_ALIGN_CENTER);
- gtk_widget_set_valign (picker, GTK_ALIGN_CENTER);
- gtk_box_append (GTK_BOX (vbox2), picker);
- gtk_box_append (GTK_BOX (vbox2), gtk_label_new ("File Button (Select Folder)"));
- gtk_box_append (GTK_BOX (vbox), vbox2);
-
- add_margin (vbox);
-
- return new_widget_info ("file-button", vbox, MEDIUM);
-}
-
-static WidgetInfo *
create_editable_label (void)
{
GtkWidget *vbox;
@@ -2144,7 +2099,6 @@ get_all_widgets (void)
retval = g_list_prepend (retval, create_combo_box_entry ());
retval = g_list_prepend (retval, create_combo_box_text ());
retval = g_list_prepend (retval, create_entry ());
- retval = g_list_prepend (retval, create_file_button ());
retval = g_list_prepend (retval, create_font_button ());
retval = g_list_prepend (retval, create_frame ());
retval = g_list_prepend (retval, create_icon_view ());
diff --git a/gtk/gtk-autocleanups.h b/gtk/gtk-autocleanups.h
index 127a63c4a8..561e8dbb84 100644
--- a/gtk/gtk-autocleanups.h
+++ b/gtk/gtk-autocleanups.h
@@ -66,7 +66,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEntry, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEntryCompletion, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEventController, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkExpander, g_object_unref)
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkFileChooserButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkFileChooserDialog, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkFileChooserWidget, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkFileFilter, g_object_unref)
diff --git a/gtk/gtk.h b/gtk/gtk.h
index be942b218b..d5f50a86b3 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -119,7 +119,6 @@
#include <gtk/gtkfixed.h>
#include <gtk/gtkfixedlayout.h>
#include <gtk/gtkfilechooser.h>
-#include <gtk/gtkfilechooserbutton.h>
#include <gtk/gtkfilechooserdialog.h>
#include <gtk/gtkfilechoosernative.h>
#include <gtk/gtkfilechooserwidget.h>
diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c
index fd7162a539..decad3fcc8 100644
--- a/gtk/gtkfilechooser.c
+++ b/gtk/gtkfilechooser.c
@@ -29,15 +29,14 @@
* SECTION:gtkfilechooser
* @Short_description: File chooser interface used by GtkFileChooserWidget and GtkFileChooserDialog
* @Title: GtkFileChooser
- * @See_also: #GtkFileChooserDialog, #GtkFileChooserWidget, #GtkFileChooserButton
+ * @See_also: #GtkFileChooserDialog, #GtkFileChooserWidget
*
* #GtkFileChooser is an interface that can be implemented by file
* selection widgets. In GTK, the main objects that implement this
- * interface are #GtkFileChooserWidget, #GtkFileChooserDialog, and
- * #GtkFileChooserButton. You do not need to write an object that
- * implements the #GtkFileChooser interface unless you are trying to
- * adapt an existing file selector to expose a standard programming
- * interface.
+ * interface are #GtkFileChooserWidget and #GtkFileChooserDialog. You do not
+ * need to write an object that implements the #GtkFileChooser interface
+ * unless you are trying to adapt an existing file selector to expose a
+ * standard programming interface.
*
* #GtkFileChooser allows for shortcuts to various places in the filesystem.
* In the default implementation these are displayed in the left pane. It
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
deleted file mode 100644
index 3830d69ef9..0000000000
--- a/gtk/gtkfilechooserbutton.c
+++ /dev/null
@@ -1,2930 +0,0 @@
-/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
-
-/* gtkfilechooserbutton.c
- *
- * Copyright (c) 2004 James M. Cape <jcape@ignore-your.tv>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <string.h>
-#include <cairo-gobject.h>
-
-#include "gtkintl.h"
-#include "gtkbookmarksmanagerprivate.h"
-#include "gtkbutton.h"
-#include "gtkcelllayout.h"
-#include "gtkcellrenderertext.h"
-#include "gtkcellrendererpixbuf.h"
-#include "gtkcombobox.h"
-#include "gtkdroptarget.h"
-#include "gtkicontheme.h"
-#include "gtkimage.h"
-#include "gtklabel.h"
-#include "gtkliststore.h"
-#include "gtktreemodelfilter.h"
-#include "gtkseparator.h"
-#include "gtkfilechooserdialog.h"
-#include "gtkfilechoosernative.h"
-#include "gtkfilechooserprivate.h"
-#include "gtkfilechooserutils.h"
-#include "gtkmarshalers.h"
-#include "gtkbinlayout.h"
-
-#include "gtkfilechooserbutton.h"
-
-#include "gtkorientable.h"
-
-#include "gtktypebuiltins.h"
-#include "gtkprivate.h"
-#include "gtksettings.h"
-#include "gtkstylecontextprivate.h"
-#include "gtkbitmaskprivate.h"
-#include "gtkeventcontroller.h"
-#include "gtkwidgetprivate.h"
-
-/**
- * SECTION:gtkfilechooserbutton
- * @Short_description: A button to launch a file chooser dialog
- * @Title: GtkFileChooserButton
- * @See_also:#GtkFileChooserDialog
- *
- * The #GtkFileChooserButton is a widget that lets the user select a
- * file. It implements the #GtkFileChooser interface. Visually, it is a
- * file name with a button to bring up a #GtkFileChooserDialog.
- * The user can then use that dialog to change the file associated with
- * that button. This widget does not support setting the
- * #GtkFileChooser:select-multiple property to %TRUE.
- *
- * ## Create a button to let the user select a file in /etc
- *
- * |[<!-- language="C" -->
- * {
- * GtkWidget *button;
- * GFile *cwd = g_file_new_for_path ("/etc");
- *
- * button = gtk_file_chooser_button_new (_("Select a file"),
- * GTK_FILE_CHOOSER_ACTION_OPEN);
- * gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (button), cwd, NULL);
- * g_object_unref (cwd);
- * }
- * ]|
- *
- * The #GtkFileChooserButton supports the #GtkFileChooserActions
- * %GTK_FILE_CHOOSER_ACTION_OPEN and %GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER.
- *
- * > The #GtkFileChooserButton will ellipsize the label, and will thus
- * > request little horizontal space. To give the button more space,
- * > you should call gtk_widget_get_preferred_size(),
- * > gtk_file_chooser_button_set_width_chars(), or pack the button in
- * > such a way that other interface elements give space to the
- * > widget.
- *
- * # CSS nodes
- *
- * GtkFileChooserButton has a single CSS node with the name “filechooserbutton”.
- */
-
-
-/* **************** *
- * Private Macros *
- * **************** */
-
-#define ICON_SIZE 16
-#define DEFAULT_TITLE N_("Select a File")
-#define DESKTOP_DISPLAY_NAME N_("Desktop")
-#define FALLBACK_DISPLAY_NAME N_("(None)")
-
-
-/* ********************** *
- * Private Enumerations *
- * ********************** */
-
-/* Property IDs */
-enum
-{
- PROP_0,
-
- PROP_DIALOG,
- PROP_TITLE,
- PROP_WIDTH_CHARS,
- PROP_MODAL
-};
-
-/* Signals */
-enum
-{
- FILE_SET,
- LAST_SIGNAL
-};
-
-/* TreeModel Columns
- */
-enum
-{
- ICON_COLUMN,
- DISPLAY_NAME_COLUMN,
- TYPE_COLUMN,
- DATA_COLUMN,
- IS_FOLDER_COLUMN,
- CANCELLABLE_COLUMN,
- NUM_COLUMNS
-};
-
-/* TreeModel Row Types */
-typedef enum
-{
- ROW_TYPE_SPECIAL,
- ROW_TYPE_VOLUME,
- ROW_TYPE_SHORTCUT,
- ROW_TYPE_BOOKMARK_SEPARATOR,
- ROW_TYPE_BOOKMARK,
- ROW_TYPE_CURRENT_FOLDER_SEPARATOR,
- ROW_TYPE_CURRENT_FOLDER,
- ROW_TYPE_OTHER_SEPARATOR,
- ROW_TYPE_OTHER,
-
- ROW_TYPE_INVALID = -1
-}
-RowType;
-
-
-/* ******************** *
- * Private Structures *
- * ******************** */
-
-typedef struct _GtkFileChooserButtonClass GtkFileChooserButtonClass;
-
-struct _GtkFileChooserButton
-{
- GtkWidget parent_instance;
-
- GtkFileChooser *chooser; /* Points to either dialog or native, depending on which is set */
- GtkWidget *dialog; /* Set if you explicitly enable */
- GtkFileChooserNative *native; /* Otherwise this is set */
- GtkWidget *box;
- GtkWidget *button;
- GtkWidget *image;
- GtkWidget *label;
- GtkWidget *combo_box;
- GtkCellRenderer *icon_cell;
- GtkCellRenderer *name_cell;
-
- GtkTreeModel *model;
- GtkTreeModel *filter_model;
-
- GFile *selection_while_inactive;
- GFile *current_folder_while_inactive;
-
- GVolumeMonitor *volume_monitor;
-
- GCancellable *dnd_select_folder_cancellable;
- GCancellable *update_button_cancellable;
- GSList *change_icon_theme_cancellables;
-
- GtkBookmarksManager *bookmarks_manager;
-
- guint8 n_special;
- guint8 n_volumes;
- guint8 n_shortcuts;
- guint8 n_bookmarks;
- guint has_bookmark_separator : 1;
- guint has_current_folder_separator : 1;
- guint has_current_folder : 1;
- guint has_other_separator : 1;
-
- /* Used for hiding/showing the dialog when the button is hidden */
- guint active : 1;
-
- /* Whether the next async callback from GIO should emit the "selection-changed" signal */
- guint is_changing_selection : 1;
-};
-
-struct _GtkFileChooserButtonClass
-{
- GtkWidgetClass parent_class;
-
- void (* file_set) (GtkFileChooserButton *fc);
-};
-
-
-/* ********************* *
- * Function Prototypes *
- * ********************* */
-
-/* GtkFileChooserIface Functions */
-static void gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface);
-static gboolean gtk_file_chooser_button_set_current_folder (GtkFileChooser *chooser,
- GFile *file,
- GError **error);
-static GFile *gtk_file_chooser_button_get_current_folder (GtkFileChooser *chooser);
-static gboolean gtk_file_chooser_button_select_file (GtkFileChooser *chooser,
- GFile *file,
- GError **error);
-static void gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser,
- GFile *file);
-static void gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser);
-static GListModel *gtk_file_chooser_button_get_files (GtkFileChooser *chooser);
-static gboolean gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
- GFile *file,
- GError **error);
-static gboolean gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser,
- GFile *file,
- GError **error);
-
-/* GObject Functions */
-static void gtk_file_chooser_button_constructed (GObject *object);
-static void gtk_file_chooser_button_dispose (GObject *object);
-static void gtk_file_chooser_button_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_file_chooser_button_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
-static void gtk_file_chooser_button_finalize (GObject *object);
-
-/* GtkWidget Functions */
-static void gtk_file_chooser_button_show (GtkWidget *widget);
-static void gtk_file_chooser_button_hide (GtkWidget *widget);
-static void gtk_file_chooser_button_root (GtkWidget *widget);
-static void gtk_file_chooser_button_map (GtkWidget *widget);
-static gboolean gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget,
- gboolean group_cycling);
-static void gtk_file_chooser_button_state_flags_changed (GtkWidget *widget,
- GtkStateFlags previous_state);
-
-/* Utility Functions */
-static void set_info_for_file_at_iter (GtkFileChooserButton *button,
- GFile *file,
- GtkTreeIter *iter);
-
-static int model_get_type_position (GtkFileChooserButton *button,
- RowType row_type);
-static void model_free_row_data (GtkFileChooserButton *button,
- GtkTreeIter *iter);
-static void model_add_special (GtkFileChooserButton *button);
-static void model_add_other (GtkFileChooserButton *button);
-static void model_add_volumes (GtkFileChooserButton *button,
- GSList *volumes);
-static void model_add_bookmarks (GtkFileChooserButton *button,
- GSList *bookmarks);
-static void model_update_current_folder (GtkFileChooserButton *button,
- GFile *file);
-static void model_remove_rows (GtkFileChooserButton *button,
- int pos,
- int n_rows);
-
-static gboolean filter_model_visible_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data);
-
-static gboolean combo_box_row_separator_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data);
-static void name_cell_data_func (GtkCellLayout *layout,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data);
-static void open_dialog (GtkFileChooserButton *button);
-static void update_combo_box (GtkFileChooserButton *button);
-static void update_label_and_image (GtkFileChooserButton *button);
-
-/* Child Object Callbacks */
-static void bookmarks_changed_cb (gpointer user_data);
-
-static void combo_box_changed_cb (GtkComboBox *combo_box,
- gpointer user_data);
-
-static void button_clicked_cb (GtkButton *real_button,
- gpointer user_data);
-
-static void dialog_response_cb (GtkDialog *dialog,
- int response,
- gpointer user_data);
-static void native_response_cb (GtkFileChooserNative *native,
- int response,
- gpointer user_data);
-static void volumes_changed (GVolumeMonitor *volume_monitor,
- gpointer volume,
- gpointer user_data);
-static GSList * get_volumes_list (GVolumeMonitor *volume_monitor);
-
-static guint file_chooser_button_signals[LAST_SIGNAL] = { 0 };
-
-/* ******************* *
- * GType Declaration *
- * ******************* */
-
-G_DEFINE_TYPE_WITH_CODE (GtkFileChooserButton, gtk_file_chooser_button, GTK_TYPE_WIDGET,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
- gtk_file_chooser_button_file_chooser_iface_init))
-
-struct DndSelectFolderData
-{
- GtkFileChooserButton *button;
- GtkFileChooserAction action;
- GCancellable *cancellable;
- GFile *file;
- char **uris;
- guint i;
- gboolean selected;
-};
-
-static void
-dnd_select_folder_get_info_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GFile *file = G_FILE (object);
- struct DndSelectFolderData *data = user_data;
- GFileInfo *info;
- GtkFileChooserButton *button = data->button;
-
- if (g_cancellable_is_cancelled (data->cancellable))
- {
- g_object_unref (data->button);
- g_object_unref (data->file);
- g_object_unref (data->cancellable);
- g_strfreev (data->uris);
- g_free (data);
- return;
- }
-
- button->dnd_select_folder_cancellable = NULL;
-
- info = g_file_query_info_finish (file, result, NULL);
- if (info)
- {
- gboolean is_folder;
-
- is_folder = _gtk_file_info_consider_as_directory (info);
-
- data->selected =
- (((data->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && is_folder) ||
- (data->action == GTK_FILE_CHOOSER_ACTION_OPEN && !is_folder)) &&
- gtk_file_chooser_select_file (GTK_FILE_CHOOSER (data->button), data->file, NULL));
- }
- else
- data->selected = FALSE;
-
- g_clear_object (&info);
-
- if (data->selected || data->uris[++data->i] == NULL)
- {
- g_signal_emit (data->button, file_chooser_button_signals[FILE_SET], 0);
-
- g_object_unref (data->button);
- g_object_unref (data->file);
- g_object_unref (data->cancellable);
- g_strfreev (data->uris);
- g_free (data);
-
- return;
- }
-
- if (data->file)
- g_object_unref (data->file);
-
- data->file = g_file_new_for_uri (data->uris[data->i]);
-
- g_clear_object (&data->cancellable);
- data->cancellable = g_cancellable_new ();
- button->dnd_select_folder_cancellable = data->cancellable;
-
- g_file_query_info_async (data->file,
- "standard::type",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- data->cancellable,
- dnd_select_folder_get_info_cb,
- user_data);
-}
-
-static gboolean
-gtk_file_chooser_button_drop (GtkDropTarget *target,
- const GValue *value,
- double x,
- double y,
- GtkFileChooserButton *button)
-{
- struct DndSelectFolderData *info;
- GFile *file;
-
- file = g_value_get_object (value);
-
- info = g_new0 (struct DndSelectFolderData, 1);
- info->button = g_object_ref (button);
- info->i = 0;
- info->uris = g_new0 (char *, 2);
- info->selected = FALSE;
- g_object_get (button->chooser, "action", &info->action, NULL);
-
- info->file = g_object_ref (file);
-
- g_clear_pointer (&button->dnd_select_folder_cancellable, g_cancellable_cancel);
-
- info->cancellable = g_cancellable_new ();
- button->dnd_select_folder_cancellable = info->cancellable;
- g_file_query_info_async (info->file,
- "standard::type",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- info->cancellable,
- dnd_select_folder_get_info_cb,
- info);
-
- return TRUE;
-}
-
-static void
-gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
-{
- GObjectClass *gobject_class;
- GtkWidgetClass *widget_class;
-
- gobject_class = G_OBJECT_CLASS (class);
- widget_class = GTK_WIDGET_CLASS (class);
-
- gobject_class->constructed = gtk_file_chooser_button_constructed;
- gobject_class->set_property = gtk_file_chooser_button_set_property;
- gobject_class->get_property = gtk_file_chooser_button_get_property;
- gobject_class->finalize = gtk_file_chooser_button_finalize;
- gobject_class->dispose = gtk_file_chooser_button_dispose;
-
- widget_class->show = gtk_file_chooser_button_show;
- widget_class->hide = gtk_file_chooser_button_hide;
- widget_class->map = gtk_file_chooser_button_map;
- widget_class->root = gtk_file_chooser_button_root;
- widget_class->mnemonic_activate = gtk_file_chooser_button_mnemonic_activate;
- widget_class->state_flags_changed = gtk_file_chooser_button_state_flags_changed;
- widget_class->grab_focus = gtk_widget_grab_focus_child;
- widget_class->focus = gtk_widget_focus_child;
-
- /**
- * GtkFileChooserButton::file-set:
- * @widget: the object which received the signal.
- *
- * The ::file-set signal is emitted when the user selects a file.
- *
- * Note that this signal is only emitted when the user
- * changes the file.
- */
- file_chooser_button_signals[FILE_SET] =
- g_signal_new (I_("file-set"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkFileChooserButtonClass, file_set),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
-
- /**
- * GtkFileChooserButton:dialog:
- *
- * Instance of the #GtkFileChooserDialog associated with the button.
- */
- g_object_class_install_property (gobject_class, PROP_DIALOG,
- g_param_spec_object ("dialog",
- P_("Dialog"),
- P_("The file chooser dialog to use."),
- GTK_TYPE_FILE_CHOOSER,
- (GTK_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY)));
-
- /**
- * GtkFileChooserButton:title:
- *
- * Title to put on the #GtkFileChooserDialog associated with the button.
- */
- g_object_class_install_property (gobject_class, PROP_TITLE,
- g_param_spec_string ("title",
- P_("Title"),
- P_("The title of the file chooser dialog."),
- _(DEFAULT_TITLE),
- GTK_PARAM_READWRITE));
-
- /**
- * GtkFileChooserButton:width-chars:
- *
- * The width of the entry and label inside the button, in characters.
- */
- g_object_class_install_property (gobject_class, PROP_WIDTH_CHARS,
- g_param_spec_int ("width-chars",
- P_("Width In Characters"),
- P_("The desired width of the button widget, in characters."),
- -1, G_MAXINT, -1,
- GTK_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class, PROP_MODAL,
- g_param_spec_boolean ("modal",
- P_("Modal"),
- P_("Whether to make the dialog modal"),
- TRUE,
- GTK_PARAM_READWRITE));
-
- _gtk_file_chooser_install_properties (gobject_class);
-
- gtk_widget_class_set_css_name (widget_class, I_("filechooserbutton"));
-
- gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
-}
-
-static void
-gtk_file_chooser_button_init (GtkFileChooserButton *button)
-{
- GtkWidget *box;
- GtkWidget *icon;
- GtkDropTarget *target;
-
- button->button = gtk_button_new ();
- g_signal_connect (button->button, "clicked", G_CALLBACK (button_clicked_cb), button);
- button->image = gtk_image_new ();
- button->label = gtk_label_new (_(FALLBACK_DISPLAY_NAME));
- gtk_label_set_xalign (GTK_LABEL (button->label), 0.0f);
- gtk_widget_set_hexpand (button->label, TRUE);
- icon = gtk_image_new_from_icon_name ("document-open-symbolic");
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_widget_set_valign (button->image, GTK_ALIGN_BASELINE);
- gtk_box_append (GTK_BOX (box), button->image);
- gtk_widget_set_valign (button->label, GTK_ALIGN_BASELINE);
- gtk_box_append (GTK_BOX (box), button->label);
- gtk_widget_set_valign (icon, GTK_ALIGN_BASELINE);
- gtk_box_append (GTK_BOX (box), icon);
- gtk_button_set_child (GTK_BUTTON (button->button), box);
-
- gtk_widget_set_parent (button->button, GTK_WIDGET (button));
-
- button->model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLUMNS,
- G_TYPE_ICON,
- G_TYPE_STRING,
- G_TYPE_CHAR,
- G_TYPE_POINTER,
- G_TYPE_BOOLEAN,
- G_TYPE_POINTER));
-
- button->combo_box = gtk_combo_box_new ();
- g_signal_connect (button->combo_box, "changed", G_CALLBACK (combo_box_changed_cb), button);
- button->icon_cell = gtk_cell_renderer_pixbuf_new ();
- button->name_cell = gtk_cell_renderer_text_new ();
- g_object_set (button->name_cell, "xpad", 6, NULL);
-
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (button->combo_box), button->icon_cell, FALSE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (button->combo_box),
- button->icon_cell, "gicon", ICON_COLUMN, NULL);
-
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (button->combo_box), button->name_cell, FALSE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (button->combo_box),
- button->name_cell, "text", DISPLAY_NAME_COLUMN, NULL);
-
- gtk_widget_hide (button->combo_box);
- gtk_widget_set_parent (button->combo_box, GTK_WIDGET (button));
-
- /* Bookmarks manager */
- button->bookmarks_manager = _gtk_bookmarks_manager_new (bookmarks_changed_cb, button);
- gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (button->combo_box),
- button->name_cell, name_cell_data_func,
- NULL, NULL);
-
- /* DnD */
- target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
- g_signal_connect (target, "drop", G_CALLBACK (gtk_file_chooser_button_drop), button);
- gtk_widget_add_controller (GTK_WIDGET (button), GTK_EVENT_CONTROLLER (target));
-}
-
-
-/* ******************************* *
- * GtkFileChooserIface Functions *
- * ******************************* */
-static void
-gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface)
-{
- _gtk_file_chooser_delegate_iface_init (iface);
-
- iface->set_current_folder = gtk_file_chooser_button_set_current_folder;
- iface->get_current_folder = gtk_file_chooser_button_get_current_folder;
- iface->select_file = gtk_file_chooser_button_select_file;
- iface->unselect_file = gtk_file_chooser_button_unselect_file;
- iface->unselect_all = gtk_file_chooser_button_unselect_all;
- iface->get_files = gtk_file_chooser_button_get_files;
- iface->add_shortcut_folder = gtk_file_chooser_button_add_shortcut_folder;
- iface->remove_shortcut_folder = gtk_file_chooser_button_remove_shortcut_folder;
-}
-
-static void
-emit_selection_changed_if_changing_selection (GtkFileChooserButton *button)
-{
- if (button->is_changing_selection)
- {
- button->is_changing_selection = FALSE;
- }
-}
-
-static gboolean
-gtk_file_chooser_button_set_current_folder (GtkFileChooser *chooser,
- GFile *file,
- GError **error)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
-
- if (button->current_folder_while_inactive)
- g_object_unref (button->current_folder_while_inactive);
-
- button->current_folder_while_inactive = g_object_ref (file);
-
- update_combo_box (button);
-
- if (button->active)
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (button->chooser), file, NULL);
-
- return TRUE;
-}
-
-static GFile *
-gtk_file_chooser_button_get_current_folder (GtkFileChooser *chooser)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
-
- if (button->current_folder_while_inactive)
- return g_object_ref (button->current_folder_while_inactive);
- else
- return NULL;
-}
-
-static gboolean
-gtk_file_chooser_button_select_file (GtkFileChooser *chooser,
- GFile *file,
- GError **error)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
-
- if (button->selection_while_inactive)
- g_object_unref (button->selection_while_inactive);
-
- button->selection_while_inactive = g_object_ref (file);
-
- button->is_changing_selection = TRUE;
-
- update_label_and_image (button);
- update_combo_box (button);
-
- if (button->active)
- gtk_file_chooser_select_file (GTK_FILE_CHOOSER (button->chooser), file, NULL);
-
- return TRUE;
-}
-
-static void
-unselect_current_file (GtkFileChooserButton *button)
-{
- if (button->selection_while_inactive)
- {
- g_object_unref (button->selection_while_inactive);
- button->selection_while_inactive = NULL;
- }
-
- button->is_changing_selection = TRUE;
-
- update_label_and_image (button);
- update_combo_box (button);
-}
-
-static void
-gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser,
- GFile *file)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
-
- if (g_file_equal (button->selection_while_inactive, file))
- unselect_current_file (button);
-
- if (button->active)
- gtk_file_chooser_unselect_file (GTK_FILE_CHOOSER (button->chooser), file);
-}
-
-static void
-gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
-
- unselect_current_file (button);
-
- if (button->active)
- gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (button->chooser));
-}
-
-static GFile *
-get_selected_file (GtkFileChooserButton *button)
-{
- GFile *retval;
-
- retval = NULL;
-
- if (button->selection_while_inactive)
- retval = button->selection_while_inactive;
- else if (button->chooser && gtk_file_chooser_get_action (button->chooser) == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
- {
- /* If there is no "real" selection in SELECT_FOLDER mode, then we'll just return
- * the current folder, since that is what GtkFileChooserWidget would do.
- */
- if (button->current_folder_while_inactive)
- retval = button->current_folder_while_inactive;
- }
-
- if (retval)
- return g_object_ref (retval);
- else
- return NULL;
-}
-
-static GListModel *
-gtk_file_chooser_button_get_files (GtkFileChooser *chooser)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
- GFile *file;
- GListStore *store;
-
- store = g_list_store_new (G_TYPE_FILE);
-
- file = get_selected_file (button);
- if (file)
- {
- g_list_store_append (store, file);
- g_object_unref (file);
- }
-
- return G_LIST_MODEL (store);
-}
-
-static gboolean
-gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser,
- GFile *file,
- GError **error)
-{
- GtkFileChooser *delegate;
- gboolean retval;
-
- delegate = g_object_get_qdata (G_OBJECT (chooser),
- GTK_FILE_CHOOSER_DELEGATE_QUARK);
- retval = gtk_file_chooser_add_shortcut_folder (delegate, file, error);
-
- if (retval)
- {
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
- GtkTreeIter iter;
- int pos;
-
- pos = model_get_type_position (button, ROW_TYPE_SHORTCUT);
- pos += button->n_shortcuts;
-
- gtk_list_store_insert (GTK_LIST_STORE (button->model), &iter, pos);
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
- TYPE_COLUMN, ROW_TYPE_SHORTCUT,
- DATA_COLUMN, g_object_ref (file),
- IS_FOLDER_COLUMN, FALSE,
- -1);
- set_info_for_file_at_iter (button, file, &iter);
- button->n_shortcuts++;
-
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model));
- }
-
- return retval;
-}
-
-static gboolean
-gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser,
- GFile *file,
- GError **error)
-{
- GtkFileChooser *delegate;
- gboolean retval;
-
- delegate = g_object_get_qdata (G_OBJECT (chooser),
- GTK_FILE_CHOOSER_DELEGATE_QUARK);
-
- retval = gtk_file_chooser_remove_shortcut_folder (delegate, file, error);
-
- if (retval)
- {
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
- GtkTreeIter iter;
- int pos;
- char type;
-
- pos = model_get_type_position (button, ROW_TYPE_SHORTCUT);
- gtk_tree_model_iter_nth_child (button->model, &iter, NULL, pos);
-
- do
- {
- gpointer data;
-
- gtk_tree_model_get (button->model, &iter,
- TYPE_COLUMN, &type,
- DATA_COLUMN, &data,
- -1);
-
- if (type == ROW_TYPE_SHORTCUT &&
- data && g_file_equal (data, file))
- {
- model_free_row_data (GTK_FILE_CHOOSER_BUTTON (chooser), &iter);
- gtk_list_store_remove (GTK_LIST_STORE (button->model), &iter);
- button->n_shortcuts--;
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model));
- update_combo_box (GTK_FILE_CHOOSER_BUTTON (chooser));
- break;
- }
- }
- while (type == ROW_TYPE_SHORTCUT &&
- gtk_tree_model_iter_next (button->model, &iter));
- }
-
- return retval;
-}
-
-
-/* ******************* *
- * GObject Functions *
- * ******************* */
-
-static void
-gtk_file_chooser_button_constructed (GObject *object)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
- GSList *list;
-
- G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->constructed (object);
-
- if (!button->dialog)
- {
- button->native = gtk_file_chooser_native_new (NULL,
- NULL,
- GTK_FILE_CHOOSER_ACTION_OPEN,
- NULL,
- NULL);
- button->chooser = GTK_FILE_CHOOSER (button->native);
- gtk_file_chooser_button_set_title (button, _(DEFAULT_TITLE));
- gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (button->native), TRUE);
-
- g_signal_connect (button->native, "response",
- G_CALLBACK (native_response_cb), object);
- }
- else /* dialog set */
- {
- button->chooser = GTK_FILE_CHOOSER (button->dialog);
- gtk_window_set_hide_on_close (GTK_WINDOW (button->chooser), TRUE);
-
- if (!gtk_window_get_title (GTK_WINDOW (button->dialog)))
- gtk_file_chooser_button_set_title (button, _(DEFAULT_TITLE));
-
- g_signal_connect (button->dialog, "response",
- G_CALLBACK (dialog_response_cb), object);
-
- g_object_add_weak_pointer (G_OBJECT (button->dialog),
- (gpointer) (&button->dialog));
- }
-
- /* This is used, instead of the standard delegate, to ensure that signals are only
- * delegated when the OK button is pressed. */
- g_object_set_qdata (object, GTK_FILE_CHOOSER_DELEGATE_QUARK, button->chooser);
-
- model_add_special (button);
-
- button->volume_monitor = g_volume_monitor_get ();
- g_signal_connect (button->volume_monitor, "mount-added",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "mount-removed",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "mount-changed",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "volume-added",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "volume-removed",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "volume-changed",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "drive-connected",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "drive-disconnected",
- G_CALLBACK (volumes_changed), button);
- g_signal_connect (button->volume_monitor, "drive-changed",
- G_CALLBACK (volumes_changed), button);
-
- list = get_volumes_list (button->volume_monitor);
- model_add_volumes (button, list);
- g_slist_free_full (list, g_object_unref);
-
- list = _gtk_bookmarks_manager_list_bookmarks (button->bookmarks_manager);
- model_add_bookmarks (button, list);
- g_slist_free_full (list, g_object_unref);
-
- model_add_other (button);
-
- button->filter_model = gtk_tree_model_filter_new (button->model, NULL);
- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (button->filter_model),
- filter_model_visible_func,
- object, NULL);
-
- gtk_combo_box_set_model (GTK_COMBO_BOX (button->combo_box), button->filter_model);
- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (button->combo_box),
- combo_box_row_separator_func,
- NULL, NULL);
-
- /* set up the action for a user-provided dialog, this also updates
- * the label, image and combobox
- */
- g_object_set (object,
- "action", gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button->chooser)),
- NULL);
-
- update_label_and_image (button);
- update_combo_box (button);
-}
-
-static void
-gtk_file_chooser_button_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
-
- switch (param_id)
- {
- case PROP_DIALOG:
- /* Construct-only */
- button->dialog = g_value_get_object (value);
- break;
- case PROP_WIDTH_CHARS:
- gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (object),
- g_value_get_int (value));
- break;
- case GTK_FILE_CHOOSER_PROP_ACTION:
- switch (g_value_get_enum (value))
- {
- case GTK_FILE_CHOOSER_ACTION_SAVE:
- {
- GEnumClass *eclass;
- GEnumValue *eval;
-
- eclass = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION);
- eval = g_enum_get_value (eclass, g_value_get_enum (value));
- g_warning ("%s: Choosers of type '%s' do not support '%s'.",
- G_STRFUNC, G_OBJECT_TYPE_NAME (object), eval->value_name);
-
- g_value_set_enum ((GValue *) value, GTK_FILE_CHOOSER_ACTION_OPEN);
- }
- break;
- default:
- break;
- }
-
- g_object_set_property (G_OBJECT (button->chooser), pspec->name, value);
- update_label_and_image (GTK_FILE_CHOOSER_BUTTON (object));
- update_combo_box (GTK_FILE_CHOOSER_BUTTON (object));
-
- switch (g_value_get_enum (value))
- {
- case GTK_FILE_CHOOSER_ACTION_OPEN:
- gtk_widget_hide (button->combo_box);
- gtk_widget_show (button->button);
- gtk_widget_queue_resize (GTK_WIDGET (button));
- break;
- case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
- gtk_widget_show (button->combo_box);
- gtk_widget_hide (button->button);
- gtk_widget_queue_resize (GTK_WIDGET (button));
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- break;
-
- case PROP_TITLE:
- case PROP_MODAL:
- case GTK_FILE_CHOOSER_PROP_FILTER:
- case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
- g_object_set_property (G_OBJECT (button->chooser), pspec->name, value);
- break;
-
- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
- g_warning ("%s: Choosers of type '%s' do not support selecting multiple files.",
- G_STRFUNC, G_OBJECT_TYPE_NAME (object));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-gtk_file_chooser_button_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
-
- switch (param_id)
- {
- case PROP_WIDTH_CHARS:
- g_value_set_int (value,
- gtk_label_get_width_chars (GTK_LABEL (button->label)));
- break;
-
- case PROP_TITLE:
- case PROP_MODAL:
- case GTK_FILE_CHOOSER_PROP_ACTION:
- case GTK_FILE_CHOOSER_PROP_FILTER:
- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
- case GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS:
- case GTK_FILE_CHOOSER_PROP_FILTERS:
- case GTK_FILE_CHOOSER_PROP_SHORTCUT_FOLDERS:
- g_object_get_property (G_OBJECT (button->chooser), pspec->name, value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-gtk_file_chooser_button_finalize (GObject *object)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
-
- g_clear_object (&button->selection_while_inactive);
- g_clear_object (&button->current_folder_while_inactive);
-
- gtk_widget_unparent (button->button);
- gtk_widget_unparent (button->combo_box);
-
- G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize (object);
-}
-
-/* ********************* *
- * GtkWidget Functions *
- * ********************* */
-
-static void
-gtk_file_chooser_button_state_flags_changed (GtkWidget *widget,
- GtkStateFlags previous_state)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
-
- if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_DROP_ACTIVE)
- {
- gtk_widget_set_state_flags (button->button, GTK_STATE_FLAG_DROP_ACTIVE, FALSE);
- gtk_widget_set_state_flags (button->combo_box, GTK_STATE_FLAG_DROP_ACTIVE, FALSE);
- }
- else
- {
- gtk_widget_unset_state_flags (button->button, GTK_STATE_FLAG_DROP_ACTIVE);
- gtk_widget_unset_state_flags (button->combo_box, GTK_STATE_FLAG_DROP_ACTIVE);
- }
-
- GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->state_flags_changed (widget, previous_state);
-}
-
-static void
-gtk_file_chooser_button_dispose (GObject *object)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
-
- if (button->model)
- {
- model_remove_rows (button, 0, gtk_tree_model_iter_n_children (button->model, NULL));
- g_clear_object (&button->model);
- }
-
- g_clear_pointer ((GtkWindow **)&button->dialog, gtk_window_destroy);
-
- if (button->native)
- gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (button->native));
-
- g_clear_object (&button->native);
- button->chooser = NULL; /* Was either button->dialog or button->native! */
-
- g_clear_pointer (&button->dnd_select_folder_cancellable, g_cancellable_cancel);
- g_clear_pointer (&button->update_button_cancellable, g_cancellable_cancel);
-
- g_slist_free_full (button->change_icon_theme_cancellables, (GDestroyNotify)g_cancellable_cancel);
- button->change_icon_theme_cancellables = NULL;
-
- g_clear_object (&button->filter_model);
-
- if (button->volume_monitor)
- g_signal_handlers_disconnect_by_func (button->volume_monitor, volumes_changed, button);
- g_clear_object (&button->volume_monitor);
-
- g_clear_pointer (&button->bookmarks_manager, _gtk_bookmarks_manager_free);
-
- G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->dispose (object);
-}
-
-static void
-gtk_file_chooser_button_show (GtkWidget *widget)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
-
- if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->show)
- GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->show (widget);
-
- if (button->active)
- open_dialog (GTK_FILE_CHOOSER_BUTTON (widget));
-}
-
-static void
-gtk_file_chooser_button_hide (GtkWidget *widget)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
-
- if (button->dialog)
- gtk_widget_hide (button->dialog);
- else if (button->native)
- gtk_native_dialog_hide (GTK_NATIVE_DIALOG (button->native));
-
- if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->hide)
- GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->hide (widget);
-}
-
-static void
-gtk_file_chooser_button_map (GtkWidget *widget)
-{
- GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->map (widget);
-}
-
-static gboolean
-gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget,
- gboolean group_cycling)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget);
-
- switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button->chooser)))
- {
- case GTK_FILE_CHOOSER_ACTION_OPEN:
- gtk_widget_grab_focus (button->button);
- break;
- case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
- return gtk_widget_mnemonic_activate (button->combo_box, group_cycling);
- break;
- case GTK_FILE_CHOOSER_ACTION_SAVE:
- default:
- g_assert_not_reached ();
- break;
- }
-
- return TRUE;
-}
-
-/* Changes the icons wherever it is needed */
-struct ChangeIconThemeData
-{
- GtkFileChooserButton *button;
- GtkTreeRowReference *row_ref;
- GCancellable *cancellable;
-};
-
-static void
-change_icon_theme_get_info_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GFile *file = G_FILE (source);
- struct ChangeIconThemeData *data = user_data;
- GFileInfo *info;
- GIcon *icon;
- GtkFileChooserButton *button = data->button;
-
- if (g_cancellable_is_cancelled (data->cancellable))
- {
- g_object_unref (data->button);
- g_object_unref (data->cancellable);
- gtk_tree_row_reference_free (data->row_ref);
- g_free (data);
- return;
- }
-
- button->change_icon_theme_cancellables =
- g_slist_remove (button->change_icon_theme_cancellables, data->cancellable);
-
- info = g_file_query_info_finish (file, result, NULL);
- if (!info)
- goto out;
-
- icon = _gtk_file_info_get_icon (info, ICON_SIZE, gtk_widget_get_scale_factor (GTK_WIDGET (data->button)));
- if (icon)
- {
- int width = 0;
- GtkTreeIter iter;
- GtkTreePath *path;
-
- width = MAX (width, ICON_SIZE);
-
- path = gtk_tree_row_reference_get_path (data->row_ref);
- if (path)
- {
- gtk_tree_model_get_iter (button->model, &iter, path);
- gtk_tree_path_free (path);
-
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- ICON_COLUMN, icon,
- -1);
-
- g_object_set (button->icon_cell,
- "width", width,
- NULL);
- }
- g_object_unref (icon);
- }
-
-out:
- g_object_unref (data->button);
- g_object_unref (data->cancellable);
- gtk_tree_row_reference_free (data->row_ref);
- g_free (data);
-
- g_clear_object (&info);
-}
-
-static void
-change_icon_theme (GtkFileChooserButton *button)
-{
- GtkTreeIter iter;
- int width = 0;
-
- g_slist_free_full (button->change_icon_theme_cancellables, (GDestroyNotify)g_cancellable_cancel);
- button->change_icon_theme_cancellables = NULL;
-
- update_label_and_image (button);
-
- gtk_tree_model_get_iter_first (button->model, &iter);
-
- do
- {
- GIcon *icon = NULL;
- char type;
- gpointer data;
-
- type = ROW_TYPE_INVALID;
- gtk_tree_model_get (button->model, &iter,
- TYPE_COLUMN, &type,
- DATA_COLUMN, &data,
- -1);
-
- switch (type)
- {
- case ROW_TYPE_SPECIAL:
- case ROW_TYPE_SHORTCUT:
- case ROW_TYPE_BOOKMARK:
- case ROW_TYPE_CURRENT_FOLDER:
- if (data)
- {
- if (g_file_is_native (G_FILE (data)))
- {
- GtkTreePath *path;
- struct ChangeIconThemeData *info;
-
- info = g_new0 (struct ChangeIconThemeData, 1);
- info->button = g_object_ref (button);
- path = gtk_tree_model_get_path (button->model, &iter);
- info->row_ref = gtk_tree_row_reference_new (button->model, path);
- gtk_tree_path_free (path);
-
- info->cancellable = g_cancellable_new ();
- g_file_query_info_async (data,
- "standard::icon",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- info->cancellable,
- change_icon_theme_get_info_cb,
- info);
-
- button->change_icon_theme_cancellables =
- g_slist_append (button->change_icon_theme_cancellables, info->cancellable);
- icon = NULL;
- }
- else
- {
- /* Don't call get_info for remote paths to avoid latency and
- * auth dialogs.
- * If we switch to a better bookmarks file format (XBEL), we
- * should use mime info to get a better icon.
- */
- icon = g_themed_icon_new ("folder-remote");
- }
- }
- break;
- case ROW_TYPE_VOLUME:
- if (G_IS_DRIVE (data))
- icon = g_drive_get_icon (G_DRIVE (data));
- else if (G_IS_VOLUME (data))
- icon = g_volume_get_icon (G_VOLUME (data));
- else if (G_IS_MOUNT (data))
- icon = g_mount_get_icon (G_MOUNT (data));
- else
- icon = NULL;
- break;
- default:
- continue;
- break;
- }
-
- if (icon)
- width = MAX (width, ICON_SIZE);
-
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- ICON_COLUMN, icon,
- -1);
-
- if (icon)
- g_object_unref (icon);
- }
- while (gtk_tree_model_iter_next (button->model, &iter));
-
- g_object_set (button->icon_cell,
- "width", width,
- NULL);
-}
-
-static void
-gtk_file_chooser_button_root (GtkWidget *widget)
-{
- GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->root (widget);
-
- change_icon_theme (GTK_FILE_CHOOSER_BUTTON (widget));
-}
-
-/* ******************* *
- * Utility Functions *
- * ******************* */
-
-/* General */
-
-struct SetDisplayNameData
-{
- GtkFileChooserButton *button;
- char *label;
- GtkTreeRowReference *row_ref;
-};
-
-static void
-set_info_get_info_cb (GObject *source,
- GAsyncResult *result,
- gpointer callback_data)
-{
- GFile *file = G_FILE (source);
- struct SetDisplayNameData *data = callback_data;
- GFileInfo *info = NULL;
- GIcon *icon;
- GtkTreePath *path;
- GtkTreeIter iter;
- GCancellable *model_cancellable = NULL;
- GtkFileChooserButton *button = data->button;
- gboolean is_folder;
-
- if (!button->model)
- /* button got destroyed */
- goto out;
-
- path = gtk_tree_row_reference_get_path (data->row_ref);
- if (!path)
- /* Cancellable doesn't exist anymore in the model */
- goto out;
-
- gtk_tree_model_get_iter (button->model, &iter, path);
- gtk_tree_path_free (path);
-
- /* Validate the cancellable */
- gtk_tree_model_get (button->model, &iter,
- CANCELLABLE_COLUMN, &model_cancellable,
- -1);
-
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- CANCELLABLE_COLUMN, NULL,
- -1);
-
- info = g_file_query_info_finish (file, result, NULL);
- if (!info)
- goto out;
-
- icon = _gtk_file_info_get_icon (info, ICON_SIZE, gtk_widget_get_scale_factor (GTK_WIDGET (data->button)));
-
- if (!data->label)
- data->label = g_strdup (g_file_info_get_display_name (info));
-
- is_folder = _gtk_file_info_consider_as_directory (info);
-
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- ICON_COLUMN, icon,
- DISPLAY_NAME_COLUMN, data->label,
- IS_FOLDER_COLUMN, is_folder,
- -1);
-
- if (icon)
- g_object_unref (icon);
-
-out:
- g_object_unref (data->button);
- g_free (data->label);
- gtk_tree_row_reference_free (data->row_ref);
- g_free (data);
-
- g_clear_object (&info);
-}
-
-static void
-set_info_for_file_at_iter (GtkFileChooserButton *button,
- GFile *file,
- GtkTreeIter *iter)
-{
- struct SetDisplayNameData *data;
- GtkTreePath *tree_path;
- GCancellable *cancellable;
-
- data = g_new0 (struct SetDisplayNameData, 1);
- data->button = g_object_ref (button);
- data->label = _gtk_bookmarks_manager_get_bookmark_label (button->bookmarks_manager, file);
-
- tree_path = gtk_tree_model_get_path (button->model, iter);
- data->row_ref = gtk_tree_row_reference_new (button->model, tree_path);
- gtk_tree_path_free (tree_path);
-
- cancellable = g_cancellable_new ();
- g_file_query_info_async (file,
- "standard::type,standard::icon,standard::display-name",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- cancellable,
- set_info_get_info_cb,
- data);
-
- gtk_list_store_set (GTK_LIST_STORE (button->model), iter,
- CANCELLABLE_COLUMN, cancellable,
- -1);
-}
-
-/* Shortcuts Model */
-static int
-model_get_type_position (GtkFileChooserButton *button,
- RowType row_type)
-{
- int retval = 0;
-
- if (row_type == ROW_TYPE_SPECIAL)
- return retval;
-
- retval += button->n_special;
-
- if (row_type == ROW_TYPE_VOLUME)
- return retval;
-
- retval += button->n_volumes;
-
- if (row_type == ROW_TYPE_SHORTCUT)
- return retval;
-
- retval += button->n_shortcuts;
-
- if (row_type == ROW_TYPE_BOOKMARK_SEPARATOR)
- return retval;
-
- retval += button->has_bookmark_separator;
-
- if (row_type == ROW_TYPE_BOOKMARK)
- return retval;
-
- retval += button->n_bookmarks;
-
- if (row_type == ROW_TYPE_CURRENT_FOLDER_SEPARATOR)
- return retval;
-
- retval += button->has_current_folder_separator;
-
- if (row_type == ROW_TYPE_CURRENT_FOLDER)
- return retval;
-
- retval += button->has_current_folder;
-
- if (row_type == ROW_TYPE_OTHER_SEPARATOR)
- return retval;
-
- retval += button->has_other_separator;
-
- if (row_type == ROW_TYPE_OTHER)
- return retval;
-
- retval++;
-
- g_assert_not_reached ();
- return -1;
-}
-
-static void
-model_free_row_data (GtkFileChooserButton *button,
- GtkTreeIter *iter)
-{
- char type;
- gpointer data;
- GCancellable *cancellable;
-
- gtk_tree_model_get (button->model, iter,
- TYPE_COLUMN, &type,
- DATA_COLUMN, &data,
- CANCELLABLE_COLUMN, &cancellable,
- -1);
-
- if (cancellable)
- g_cancellable_cancel (cancellable);
-
- switch (type)
- {
- case ROW_TYPE_SPECIAL:
- case ROW_TYPE_SHORTCUT:
- case ROW_TYPE_BOOKMARK:
- case ROW_TYPE_CURRENT_FOLDER:
- case ROW_TYPE_VOLUME:
- g_object_unref (data);
- break;
- default:
- break;
- }
-}
-
-static void
-model_add_special_get_info_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GFile *file = G_FILE (source);
- struct ChangeIconThemeData *data = user_data;
- GtkTreeIter iter;
- GtkTreePath *path;
- GIcon *icon;
- GCancellable *model_cancellable = NULL;
- GtkFileChooserButton *button = data->button;
- GFileInfo *info = NULL;
- char *name;
-
- if (!button->model)
- /* button got destroyed */
- goto out;
-
- path = gtk_tree_row_reference_get_path (data->row_ref);
- if (!path)
- /* Cancellable doesn't exist anymore in the model */
- goto out;
-
- gtk_tree_model_get_iter (button->model, &iter, path);
- gtk_tree_path_free (path);
-
- gtk_tree_model_get (button->model, &iter,
- CANCELLABLE_COLUMN, &model_cancellable,
- -1);
-
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- CANCELLABLE_COLUMN, NULL,
- -1);
-
- info = g_file_query_info_finish (file, result, NULL);
- if (!info)
- goto out;
-
- icon = _gtk_file_info_get_icon (info, ICON_SIZE, gtk_widget_get_scale_factor (GTK_WIDGET (data->button)));
- if (icon)
- {
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- ICON_COLUMN, icon,
- -1);
- g_object_unref (icon);
- }
-
- gtk_tree_model_get (button->model, &iter,
- DISPLAY_NAME_COLUMN, &name,
- -1);
- if (!name)
- gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
- DISPLAY_NAME_COLUMN, g_file_info_get_display_name (info),
- -1);
- g_free (name);
-
-out:
- g_object_unref (data->button);
- gtk_tree_row_reference_free (data->row_ref);
- g_free (data);
-
- g_clear_object (&info);
-}
-
-static void
-model_add_special (GtkFileChooserButton *button)
-{
- const char *homedir;
- const char *desktopdir;
- GtkListStore *store;
- GtkTreeIter iter;
- GFile *file;
- int pos;
-
- store = GTK_LIST_STORE (button->model);
- pos = model_get_type_position (button, ROW_TYPE_SPECIAL);
-
- homedir = g_get_home_dir ();
-
- if (homedir)
- {
- GtkTreePath *tree_path;
- GCancellable *cancellable;
- struct ChangeIconThemeData *info;
-
- file = g_file_new_for_path (homedir);
- gtk_list_store_insert (store, &iter, pos);
- pos++;
-
- info = g_new0 (struct ChangeIconThemeData, 1);
- info->button = g_object_ref (button);
- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
- info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
- tree_path);
- gtk_tree_path_free (tree_path);
-
- cancellable = g_cancellable_new ();
- g_file_query_info_async (file,
- "standard::icon,standard::display-name",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- cancellable,
- model_add_special_get_info_cb,
- info);
-
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, NULL,
- TYPE_COLUMN, ROW_TYPE_SPECIAL,
- DATA_COLUMN, file,
- IS_FOLDER_COLUMN, TRUE,
- CANCELLABLE_COLUMN, cancellable,
- -1);
-
- button->n_special++;
- }
-
- desktopdir = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
-
- /* "To disable a directory, point it to the homedir."
- * See http://freedesktop.org/wiki/Software/xdg-user-dirs
- */
- if (g_strcmp0 (desktopdir, g_get_home_dir ()) != 0)
- {
- GtkTreePath *tree_path;
- GCancellable *cancellable;
- struct ChangeIconThemeData *info;
-
- file = g_file_new_for_path (desktopdir);
- gtk_list_store_insert (store, &iter, pos);
- pos++;
-
- info = g_new0 (struct ChangeIconThemeData, 1);
- info->button = g_object_ref (button);
- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
- info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store),
- tree_path);
- gtk_tree_path_free (tree_path);
-
- cancellable = g_cancellable_new ();
- g_file_query_info_async (file,
- "standard::icon,standard::display-name",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- cancellable,
- model_add_special_get_info_cb,
- info);
-
- gtk_list_store_set (store, &iter,
- TYPE_COLUMN, ROW_TYPE_SPECIAL,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, _(DESKTOP_DISPLAY_NAME),
- DATA_COLUMN, file,
- IS_FOLDER_COLUMN, TRUE,
- CANCELLABLE_COLUMN, cancellable,
- -1);
-
- button->n_special++;
- }
-}
-
-static void
-model_add_volumes (GtkFileChooserButton *button,
- GSList *volumes)
-{
- GtkListStore *store;
- int pos;
- GSList *l;
-
- if (!volumes)
- return;
-
- store = GTK_LIST_STORE (button->model);
- pos = model_get_type_position (button, ROW_TYPE_VOLUME);
-
- for (l = volumes; l; l = l->next)
- {
- gpointer *volume;
- GtkTreeIter iter;
- GIcon *icon;
- char *display_name;
-
- volume = l->data;
- if (G_IS_DRIVE (volume))
- {
- icon = g_drive_get_icon (G_DRIVE (volume));
- display_name = g_drive_get_name (G_DRIVE (volume));
- }
- else if (G_IS_VOLUME (volume))
- {
- icon = g_volume_get_icon (G_VOLUME (volume));
- display_name = g_volume_get_name (G_VOLUME (volume));
- }
- else if (G_IS_MOUNT (volume))
- {
- icon = g_mount_get_icon (G_MOUNT (volume));
- display_name = g_mount_get_name (G_MOUNT (volume));
- }
- else
- {
- icon = NULL;
- display_name = NULL;
- }
-
- gtk_list_store_insert (store, &iter, pos);
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, icon,
- DISPLAY_NAME_COLUMN, display_name,
- TYPE_COLUMN, ROW_TYPE_VOLUME,
- DATA_COLUMN, g_object_ref (volume),
- IS_FOLDER_COLUMN, TRUE,
- -1);
-
- g_clear_object (&icon);
- g_free (display_name);
-
- button->n_volumes++;
- pos++;
- }
-}
-
-static void
-model_add_bookmarks (GtkFileChooserButton *button,
- GSList *bookmarks)
-{
- GtkListStore *store;
- GtkTreeIter iter;
- int pos;
- GSList *l;
-
- if (!bookmarks)
- return;
-
- store = GTK_LIST_STORE (button->model);
- pos = model_get_type_position (button, ROW_TYPE_BOOKMARK);
-
- for (l = bookmarks; l; l = l->next)
- {
- GFile *file;
-
- file = l->data;
-
- if (_gtk_file_has_native_path (file))
- {
- gtk_list_store_insert (store, &iter, pos);
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
- TYPE_COLUMN, ROW_TYPE_BOOKMARK,
- DATA_COLUMN, g_object_ref (file),
- IS_FOLDER_COLUMN, FALSE,
- -1);
- set_info_for_file_at_iter (button, file, &iter);
- }
- else
- {
- char *label;
- GIcon *icon;
-
- /* Don't call get_info for remote paths to avoid latency and
- * auth dialogs.
- * If we switch to a better bookmarks file format (XBEL), we
- * should use mime info to get a better icon.
- */
- label = _gtk_bookmarks_manager_get_bookmark_label (button->bookmarks_manager, file);
- if (!label)
- label = _gtk_file_chooser_label_for_file (file);
-
- icon = g_themed_icon_new ("folder-remote");
-
- gtk_list_store_insert (store, &iter, pos);
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, icon,
- DISPLAY_NAME_COLUMN, label,
- TYPE_COLUMN, ROW_TYPE_BOOKMARK,
- DATA_COLUMN, g_object_ref (file),
- IS_FOLDER_COLUMN, TRUE,
- -1);
-
- g_free (label);
- if (icon)
- g_object_unref (icon);
- }
-
- button->n_bookmarks++;
- pos++;
- }
-
- if (button->n_bookmarks > 0 &&
- !button->has_bookmark_separator)
- {
- pos = model_get_type_position (button, ROW_TYPE_BOOKMARK_SEPARATOR);
-
- gtk_list_store_insert (store, &iter, pos);
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, NULL,
- TYPE_COLUMN, ROW_TYPE_BOOKMARK_SEPARATOR,
- DATA_COLUMN, NULL,
- IS_FOLDER_COLUMN, FALSE,
- -1);
- button->has_bookmark_separator = TRUE;
- }
-}
-
-static void
-model_update_current_folder (GtkFileChooserButton *button,
- GFile *file)
-{
- GtkListStore *store;
- GtkTreeIter iter;
- int pos;
-
- if (!file)
- return;
-
- store = GTK_LIST_STORE (button->model);
-
- if (!button->has_current_folder_separator)
- {
- pos = model_get_type_position (button, ROW_TYPE_CURRENT_FOLDER_SEPARATOR);
- gtk_list_store_insert (store, &iter, pos);
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, NULL,
- TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER_SEPARATOR,
- DATA_COLUMN, NULL,
- IS_FOLDER_COLUMN, FALSE,
- -1);
- button->has_current_folder_separator = TRUE;
- }
-
- pos = model_get_type_position (button, ROW_TYPE_CURRENT_FOLDER);
- if (!button->has_current_folder)
- {
- gtk_list_store_insert (store, &iter, pos);
- button->has_current_folder = TRUE;
- }
- else
- {
- gtk_tree_model_iter_nth_child (button->model, &iter, NULL, pos);
- model_free_row_data (button, &iter);
- }
-
- if (g_file_is_native (file))
- {
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
- TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER,
- DATA_COLUMN, g_object_ref (file),
- IS_FOLDER_COLUMN, FALSE,
- -1);
- set_info_for_file_at_iter (button, file, &iter);
- }
- else
- {
- char *label;
- GIcon *icon;
-
- /* Don't call get_info for remote paths to avoid latency and
- * auth dialogs.
- * If we switch to a better bookmarks file format (XBEL), we
- * should use mime info to get a better icon.
- */
- label = _gtk_bookmarks_manager_get_bookmark_label (button->bookmarks_manager, file);
- if (!label)
- label = _gtk_file_chooser_label_for_file (file);
-
- if (g_file_is_native (file))
- icon = g_themed_icon_new ("folder");
- else
- icon = g_themed_icon_new ("folder-remote");
-
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, icon,
- DISPLAY_NAME_COLUMN, label,
- TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER,
- DATA_COLUMN, g_object_ref (file),
- IS_FOLDER_COLUMN, TRUE,
- -1);
-
- g_free (label);
- if (icon)
- g_object_unref (icon);
- }
-}
-
-static void
-model_add_other (GtkFileChooserButton *button)
-{
- GtkListStore *store;
- GtkTreeIter iter;
- int pos;
- GIcon *icon;
-
- store = GTK_LIST_STORE (button->model);
- pos = model_get_type_position (button, ROW_TYPE_OTHER_SEPARATOR);
- icon = g_themed_icon_new ("document-open-symbolic");
-
- gtk_list_store_insert (store, &iter, pos);
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, icon,
- DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME),
- TYPE_COLUMN, ROW_TYPE_OTHER_SEPARATOR,
- DATA_COLUMN, NULL,
- IS_FOLDER_COLUMN, FALSE,
- -1);
- button->has_other_separator = TRUE;
- pos++;
-
- gtk_list_store_insert (store, &iter, pos);
- gtk_list_store_set (store, &iter,
- ICON_COLUMN, NULL,
- DISPLAY_NAME_COLUMN, _("Other…"),
- TYPE_COLUMN, ROW_TYPE_OTHER,
- DATA_COLUMN, NULL,
- IS_FOLDER_COLUMN, FALSE,
- -1);
-
- g_object_unref (icon);
-}
-
-static void
-model_remove_rows (GtkFileChooserButton *button,
- int pos,
- int n_rows)
-{
- GtkListStore *store;
-
- if (!n_rows)
- return;
-
- store = GTK_LIST_STORE (button->model);
-
- do
- {
- GtkTreeIter iter;
-
- if (!gtk_tree_model_iter_nth_child (button->model, &iter, NULL, pos))
- g_assert_not_reached ();
-
- model_free_row_data (button, &iter);
- gtk_list_store_remove (store, &iter);
- n_rows--;
- }
- while (n_rows);
-}
-
-/* Filter Model */
-static gboolean
-test_if_file_is_visible (GFile *file,
- gboolean is_folder)
-{
- if (!file)
- return FALSE;
-
- if (!is_folder)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-filter_model_visible_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- char type;
- gpointer data;
- gboolean retval, is_folder;
-
- type = ROW_TYPE_INVALID;
- data = NULL;
-
- gtk_tree_model_get (model, iter,
- TYPE_COLUMN, &type,
- DATA_COLUMN, &data,
- IS_FOLDER_COLUMN, &is_folder,
- -1);
-
- switch (type)
- {
- case ROW_TYPE_CURRENT_FOLDER:
- retval = TRUE;
- break;
- case ROW_TYPE_SPECIAL:
- case ROW_TYPE_SHORTCUT:
- case ROW_TYPE_BOOKMARK:
- retval = test_if_file_is_visible (data, is_folder);
- break;
- case ROW_TYPE_VOLUME:
- retval = TRUE;
- break;
- default:
- retval = TRUE;
- break;
- }
-
- return retval;
-}
-
-/* Combo Box */
-static void
-name_cell_data_func (GtkCellLayout *layout,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- char type;
-
- type = 0;
- gtk_tree_model_get (model, iter,
- TYPE_COLUMN, &type,
- -1);
-
- if (type == ROW_TYPE_CURRENT_FOLDER)
- g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- else if (type == ROW_TYPE_BOOKMARK || type == ROW_TYPE_SHORTCUT)
- g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
- else
- g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_NONE, NULL);
-}
-
-static gboolean
-combo_box_row_separator_func (GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- char type = ROW_TYPE_INVALID;
-
- gtk_tree_model_get (model, iter, TYPE_COLUMN, &type, -1);
-
- return (type == ROW_TYPE_BOOKMARK_SEPARATOR ||
- type == ROW_TYPE_CURRENT_FOLDER_SEPARATOR ||
- type == ROW_TYPE_OTHER_SEPARATOR);
-}
-
-static void
-select_combo_box_row_no_notify (GtkFileChooserButton *button, int pos)
-{
- GtkTreeIter iter, filter_iter;
-
- gtk_tree_model_iter_nth_child (button->model, &iter, NULL, pos);
- gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (button->filter_model),
- &filter_iter, &iter);
-
- g_signal_handlers_block_by_func (button->combo_box, combo_box_changed_cb, button);
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (button->combo_box), &filter_iter);
- g_signal_handlers_unblock_by_func (button->combo_box, combo_box_changed_cb, button);
-}
-
-static void
-update_combo_box (GtkFileChooserButton *button)
-{
- GFile *file;
- GtkTreeIter iter;
- gboolean row_found;
-
- file = get_selected_file (button);
-
- row_found = FALSE;
-
- gtk_tree_model_get_iter_first (button->filter_model, &iter);
-
- do
- {
- char type;
- gpointer data;
-
- type = ROW_TYPE_INVALID;
- data = NULL;
-
- gtk_tree_model_get (button->filter_model, &iter,
- TYPE_COLUMN, &type,
- DATA_COLUMN, &data,
- -1);
-
- switch (type)
- {
- case ROW_TYPE_SPECIAL:
- case ROW_TYPE_SHORTCUT:
- case ROW_TYPE_BOOKMARK:
- case ROW_TYPE_CURRENT_FOLDER:
- row_found = (file && g_file_equal (data, file));
- break;
- case ROW_TYPE_VOLUME:
- {
- GFile *base_file = g_file_new_for_uri ("file:///");
- row_found = (file && g_file_equal (base_file, file));
- g_object_unref (base_file);
- }
- break;
- default:
- row_found = FALSE;
- break;
- }
-
- if (row_found)
- {
- g_signal_handlers_block_by_func (button->combo_box, combo_box_changed_cb, button);
- gtk_combo_box_set_active_iter (GTK_COMBO_BOX (button->combo_box),
- &iter);
- g_signal_handlers_unblock_by_func (button->combo_box, combo_box_changed_cb, button);
- }
- }
- while (!row_found && gtk_tree_model_iter_next (button->filter_model, &iter));
-
- if (!row_found)
- {
- int pos;
-
- /* If it hasn't been found already, update & select the current-folder row. */
- if (file)
- {
- model_update_current_folder (button, file);
- pos = model_get_type_position (button, ROW_TYPE_CURRENT_FOLDER);
- }
- else
- {
- /* No selection; switch to that row */
-
- pos = model_get_type_position (button, ROW_TYPE_OTHER_SEPARATOR);
- }
-
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model));
-
- select_combo_box_row_no_notify (button, pos);
- }
-
- if (file)
- g_object_unref (file);
-}
-
-/* Button */
-static void
-update_label_get_info_cb (GObject *source,
- GAsyncResult *result,
- gpointer data)
-{
- GFile *file = G_FILE (source);
- GtkFileChooserButton *button = data;
- GIcon *icon;
- GFileInfo *info;
-
- g_clear_object (&button->update_button_cancellable);
-
- info = g_file_query_info_finish (file, result, NULL);
- if (!info)
- goto out;
-
- gtk_label_set_text (GTK_LABEL (button->label), g_file_info_get_display_name (info));
-
- icon = _gtk_file_info_get_icon (info, ICON_SIZE, gtk_widget_get_scale_factor (GTK_WIDGET (button)));
- gtk_image_set_from_gicon (GTK_IMAGE (button->image), icon);
- gtk_image_set_pixel_size (GTK_IMAGE (button->image), ICON_SIZE);
- if (icon)
- g_object_unref (icon);
-
-out:
- emit_selection_changed_if_changing_selection (button);
-
- g_clear_object (&info);
- g_object_unref (button);
-}
-
-static void
-update_label_and_image (GtkFileChooserButton *button)
-{
- char *label_text;
- GFile *file;
- gboolean done_changing_selection;
-
- file = get_selected_file (button);
-
- label_text = NULL;
- done_changing_selection = FALSE;
-
- if (button->update_button_cancellable)
- {
- g_cancellable_cancel (button->update_button_cancellable);
- button->update_button_cancellable = NULL;
- }
-
- if (file)
- {
- GMount *mount;
- GFile *base_file;
-
- mount = g_file_find_enclosing_mount (file, NULL, NULL);
- if (!mount && g_file_is_native (file))
- base_file = g_file_new_for_uri ("file:///");
- else if (mount)
- base_file = g_mount_get_root (mount);
- else
- base_file = NULL;
-
- if (base_file && g_file_equal (base_file, file))
- {
- GIcon *icon;
-
- label_text = g_mount_get_name (mount);
- icon = g_mount_get_icon (mount);
- gtk_image_set_from_gicon (GTK_IMAGE (button->image), icon);
- gtk_image_set_pixel_size (GTK_IMAGE (button->image), ICON_SIZE);
- g_clear_object (&icon);
- }
-
- g_clear_object (&base_file);
- g_clear_object (&mount);
-
- if (label_text)
- {
- done_changing_selection = TRUE;
- goto out;
- }
-
- if (g_file_is_native (file) ||
- !_gtk_bookmarks_manager_has_bookmark (button->bookmarks_manager, file))
- {
- button->update_button_cancellable = g_cancellable_new ();
- g_file_query_info_async (file,
- "standard::icon,standard::display-name",
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- button->update_button_cancellable,
- update_label_get_info_cb,
- g_object_ref (button));
- }
- else
- {
- GIcon *icon;
-
- label_text = _gtk_bookmarks_manager_get_bookmark_label (button->bookmarks_manager, file);
- icon = g_themed_icon_new ("text-x-generic");
- gtk_image_set_from_gicon (GTK_IMAGE (button->image), icon);
- gtk_image_set_pixel_size (GTK_IMAGE (button->image), ICON_SIZE);
- if (icon)
- g_object_unref (icon);
-
- done_changing_selection = TRUE;
- }
- }
- else
- {
- /* We know the selection is empty */
- done_changing_selection = TRUE;
- }
-
-out:
-
- g_clear_object (&file);
-
- if (label_text)
- {
- gtk_label_set_text (GTK_LABEL (button->label), label_text);
- g_free (label_text);
- }
- else
- {
- gtk_label_set_text (GTK_LABEL (button->label), _(FALLBACK_DISPLAY_NAME));
- gtk_image_set_from_gicon (GTK_IMAGE (button->image), NULL);
- }
-
- if (done_changing_selection)
- emit_selection_changed_if_changing_selection (button);
-}
-
-
-/* ************************ *
- * Child Object Callbacks *
- * ************************ */
-
-static gboolean
-mount_referenced_by_volume_activation_root (GList *volumes, GMount *mount)
-{
- GList *l;
- GFile *mount_root;
- gboolean ret;
-
- ret = FALSE;
-
- mount_root = g_mount_get_root (mount);
-
- for (l = volumes; l != NULL; l = l->next)
- {
- GVolume *volume = G_VOLUME (l->data);
- GFile *volume_activation_root;
-
- volume_activation_root = g_volume_get_activation_root (volume);
- if (volume_activation_root != NULL)
- {
- if (g_file_has_prefix (volume_activation_root, mount_root))
- {
- ret = TRUE;
- g_object_unref (volume_activation_root);
- break;
- }
- g_object_unref (volume_activation_root);
- }
- }
-
- g_object_unref (mount_root);
- return ret;
-}
-
-static GSList *
-get_volumes_list (GVolumeMonitor *volume_monitor)
-{
- GSList *result;
- GList *l, *ll;
- GList *drives;
- GList *volumes;
- GList *mounts;
- GDrive *drive;
- GVolume *volume;
- GMount *mount;
-
- result = NULL;
-
- /* first go through all connected drives */
- drives = g_volume_monitor_get_connected_drives (volume_monitor);
-
- for (l = drives; l != NULL; l = l->next)
- {
- drive = l->data;
- volumes = g_drive_get_volumes (drive);
-
- if (volumes)
- {
- for (ll = volumes; ll != NULL; ll = ll->next)
- {
- volume = ll->data;
- mount = g_volume_get_mount (volume);
-
- if (mount)
- {
- /* Show mounted volume */
- result = g_slist_prepend (result, g_object_ref (mount));
- g_object_unref (mount);
- }
- else
- {
- /* Do show the unmounted volumes in the sidebar;
- * this is so the user can mount it (in case automounting
- * is off).
- *
- * Also, even if automounting is enabled, this gives a visual
- * cue that the user should remember to yank out the media if
- * he just unmounted it.
- */
- result = g_slist_prepend (result, g_object_ref (volume));
- }
-
- g_object_unref (volume);
- }
-
- g_list_free (volumes);
- }
- else if (g_drive_is_media_removable (drive) && !g_drive_is_media_check_automatic (drive))
- {
- /* If the drive has no mountable volumes and we cannot detect media change.. we
- * display the drive in the sidebar so the user can manually poll the drive by
- * right clicking and selecting "Rescan..."
- *
- * This is mainly for drives like floppies where media detection doesn't
- * work.. but it's also for human beings who like to turn off media detection
- * in the OS to save battery juice.
- */
-
- result = g_slist_prepend (result, g_object_ref (drive));
- }
-
- g_object_unref (drive);
- }
-
- g_list_free (drives);
-
- /* add all volumes that is not associated with a drive */
- volumes = g_volume_monitor_get_volumes (volume_monitor);
-
- for (l = volumes; l != NULL; l = l->next)
- {
- volume = l->data;
- drive = g_volume_get_drive (volume);
-
- if (drive)
- {
- g_object_unref (drive);
- continue;
- }
-
- mount = g_volume_get_mount (volume);
-
- if (mount)
- {
- /* show this mount */
- result = g_slist_prepend (result, g_object_ref (mount));
- g_object_unref (mount);
- }
- else
- {
- /* see comment above in why we add an icon for a volume */
- result = g_slist_prepend (result, g_object_ref (volume));
- }
-
- g_object_unref (volume);
- }
-
- /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
- mounts = g_volume_monitor_get_mounts (volume_monitor);
-
- for (l = mounts; l != NULL; l = l->next)
- {
- mount = l->data;
- volume = g_mount_get_volume (mount);
-
- if (volume)
- {
- g_object_unref (volume);
- continue;
- }
-
- /* if there's exists one or more volumes with an activation root
- * inside the mount, don't display the mount
- */
- if (mount_referenced_by_volume_activation_root (volumes, mount))
- {
- g_object_unref (mount);
- continue;
- }
-
- /* show this mount */
- result = g_slist_prepend (result, g_object_ref (mount));
- g_object_unref (mount);
- }
-
- g_list_free (volumes);
- g_list_free (mounts);
-
- return result;
-}
-
-static void
-volumes_changed (GVolumeMonitor *volume_monitor,
- gpointer volume,
- gpointer user_data)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
- GSList *volumes;
-
- model_remove_rows (user_data,
- model_get_type_position (user_data, ROW_TYPE_VOLUME),
- button->n_volumes);
-
- button->n_volumes = 0;
-
- volumes = get_volumes_list (volume_monitor);
- model_add_volumes (user_data, volumes);
- g_slist_free_full (volumes, g_object_unref);
-
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model));
-
- update_label_and_image (user_data);
- update_combo_box (user_data);
-}
-
-static void
-bookmarks_changed_cb (gpointer user_data)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
- GSList *bookmarks;
-
- bookmarks = _gtk_bookmarks_manager_list_bookmarks (button->bookmarks_manager);
- model_remove_rows (user_data,
- model_get_type_position (user_data, ROW_TYPE_BOOKMARK_SEPARATOR),
- button->n_bookmarks + button->has_bookmark_separator);
- button->has_bookmark_separator = FALSE;
- button->n_bookmarks = 0;
- model_add_bookmarks (user_data, bookmarks);
- g_slist_free_full (bookmarks, g_object_unref);
-
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model));
-
- update_label_and_image (user_data);
- update_combo_box (user_data);
-}
-
-static void
-save_inactive_state (GtkFileChooserButton *button)
-{
- if (button->current_folder_while_inactive)
- g_object_unref (button->current_folder_while_inactive);
-
- if (button->selection_while_inactive)
- g_object_unref (button->selection_while_inactive);
-
- button->current_folder_while_inactive = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button->chooser));
- button->selection_while_inactive = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button->chooser));
-}
-
-static void
-restore_inactive_state (GtkFileChooserButton *button)
-{
- if (button->current_folder_while_inactive)
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (button->chooser), button->current_folder_while_inactive, NULL);
-
- if (button->selection_while_inactive)
- gtk_file_chooser_select_file (GTK_FILE_CHOOSER (button->chooser), button->selection_while_inactive, NULL);
- else
- gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (button->chooser));
-}
-
-/* Dialog */
-static void
-open_dialog (GtkFileChooserButton *button)
-{
- GtkWidget *toplevel;
-
- toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (button)));
-
- /* Setup the dialog parent to be chooser button's toplevel, and be modal
- as needed. */
- if (button->dialog != NULL)
- {
- if (!gtk_widget_get_visible (button->dialog))
- {
- if (GTK_IS_WINDOW (toplevel))
- {
- if (GTK_WINDOW (toplevel) != gtk_window_get_transient_for (GTK_WINDOW (button->dialog)))
- gtk_window_set_transient_for (GTK_WINDOW (button->dialog),
- GTK_WINDOW (toplevel));
- if (gtk_window_get_modal (GTK_WINDOW (toplevel)))
- gtk_window_set_modal (GTK_WINDOW (button->dialog), TRUE);
- }
- }
- }
- else
- {
- if (!gtk_native_dialog_get_visible (GTK_NATIVE_DIALOG (button->native)))
- {
- if (GTK_IS_WINDOW (toplevel))
- {
- if (GTK_WINDOW (toplevel) != gtk_native_dialog_get_transient_for (GTK_NATIVE_DIALOG (button->native)))
- gtk_native_dialog_set_transient_for (GTK_NATIVE_DIALOG (button->native),
- GTK_WINDOW (toplevel));
-
- if (gtk_window_get_modal (GTK_WINDOW (toplevel)))
- gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (button->native), TRUE);
- }
- }
- }
-
- if (!button->active)
- {
- restore_inactive_state (button);
- button->active = TRUE;
- }
-
- gtk_widget_set_sensitive (button->combo_box, FALSE);
- if (button->dialog)
- gtk_window_present (GTK_WINDOW (button->dialog));
- else
- gtk_native_dialog_show (GTK_NATIVE_DIALOG (button->native));
-}
-
-/* Combo Box */
-static void
-combo_box_changed_cb (GtkComboBox *combo_box,
- gpointer user_data)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
- GtkTreeIter iter;
- gboolean file_was_set;
-
- file_was_set = FALSE;
-
- if (gtk_combo_box_get_active_iter (combo_box, &iter))
- {
- char type;
- gpointer data;
-
- type = ROW_TYPE_INVALID;
- data = NULL;
-
- gtk_tree_model_get (button->filter_model, &iter,
- TYPE_COLUMN, &type,
- DATA_COLUMN, &data,
- -1);
-
- switch (type)
- {
- case ROW_TYPE_SPECIAL:
- case ROW_TYPE_SHORTCUT:
- case ROW_TYPE_BOOKMARK:
- case ROW_TYPE_CURRENT_FOLDER:
- if (data)
- {
- gtk_file_chooser_button_select_file (GTK_FILE_CHOOSER (button), data, NULL);
- file_was_set = TRUE;
- }
- break;
- case ROW_TYPE_VOLUME:
- {
- GFile *base_file = g_file_new_for_uri ("file:///");
- gtk_file_chooser_button_select_file (GTK_FILE_CHOOSER (button), base_file, NULL);
- file_was_set = TRUE;
- g_object_unref (base_file);
- }
- break;
- case ROW_TYPE_OTHER:
- open_dialog (user_data);
- break;
- default:
- break;
- }
- }
-
- if (file_was_set)
- g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
-}
-
-/* Button */
-static void
-button_clicked_cb (GtkButton *real_button,
- gpointer user_data)
-{
- open_dialog (user_data);
-}
-
-/* Dialog */
-
-static void
-common_response_cb (GtkFileChooserButton *button,
- int response)
-{
- if (response == GTK_RESPONSE_ACCEPT ||
- response == GTK_RESPONSE_OK)
- {
- save_inactive_state (button);
- }
- else
- {
- restore_inactive_state (button);
- }
-
- if (button->active)
- button->active = FALSE;
-
- update_label_and_image (button);
- update_combo_box (button);
-
- gtk_widget_set_sensitive (button->combo_box, TRUE);
-}
-
-
-static void
-dialog_response_cb (GtkDialog *dialog,
- int response,
- gpointer user_data)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
-
- common_response_cb (button, response);
-
- gtk_widget_hide (button->dialog);
-
- if (response == GTK_RESPONSE_ACCEPT ||
- response == GTK_RESPONSE_OK)
- g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
-}
-
-static void
-native_response_cb (GtkFileChooserNative *native,
- int response,
- gpointer user_data)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
-
- common_response_cb (button, response);
-
- /* dialog already hidden */
-
- if (response == GTK_RESPONSE_ACCEPT ||
- response == GTK_RESPONSE_OK)
- g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
-}
-
-
-/* ************************************************************************** *
- * Public API *
- * ************************************************************************** */
-
-/**
- * gtk_file_chooser_button_new:
- * @title: the title of the browse dialog.
- * @action: the open mode for the widget.
- *
- * Creates a new file-selecting button widget.
- *
- * Returns: a new button widget.
- */
-GtkWidget *
-gtk_file_chooser_button_new (const char *title,
- GtkFileChooserAction action)
-{
- g_return_val_if_fail (action == GTK_FILE_CHOOSER_ACTION_OPEN ||
- action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL);
-
- return g_object_new (GTK_TYPE_FILE_CHOOSER_BUTTON,
- "action", action,
- "title", (title ? title : _(DEFAULT_TITLE)),
- NULL);
-}
-
-/**
- * gtk_file_chooser_button_new_with_dialog:
- * @dialog: (type Gtk.Dialog): the widget to use as dialog
- *
- * Creates a #GtkFileChooserButton widget which uses @dialog as its
- * file-picking window.
- *
- * Note that @dialog must be a #GtkDialog (or subclass) which
- * implements the #GtkFileChooser interface and must not have
- * %GTK_DIALOG_DESTROY_WITH_PARENT set.
- *
- * Also note that the dialog needs to have its confirmative button
- * added with response %GTK_RESPONSE_ACCEPT or %GTK_RESPONSE_OK in
- * order for the button to take over the file selected in the dialog.
- *
- * Returns: a new button widget.
- */
-GtkWidget *
-gtk_file_chooser_button_new_with_dialog (GtkWidget *dialog)
-{
- g_return_val_if_fail (GTK_IS_FILE_CHOOSER (dialog) && GTK_IS_DIALOG (dialog), NULL);
-
- return g_object_new (GTK_TYPE_FILE_CHOOSER_BUTTON,
- "dialog", dialog,
- NULL);
-}
-
-/**
- * gtk_file_chooser_button_set_title:
- * @button: the button widget to modify.
- * @title: the new browse dialog title.
- *
- * Modifies the @title of the browse dialog used by @button.
- */
-void
-gtk_file_chooser_button_set_title (GtkFileChooserButton *button,
- const char *title)
-{
- g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
-
- if (button->dialog)
- gtk_window_set_title (GTK_WINDOW (button->dialog), title);
- else
- gtk_native_dialog_set_title (GTK_NATIVE_DIALOG (button->native), title);
- g_object_notify (G_OBJECT (button), "title");
-}
-
-/**
- * gtk_file_chooser_button_get_title:
- * @button: the button widget to examine.
- *
- * Retrieves the title of the browse dialog used by @button. The returned value
- * should not be modified or freed.
- *
- * Returns: a pointer to the browse dialog’s title.
- */
-const char *
-gtk_file_chooser_button_get_title (GtkFileChooserButton *button)
-{
- g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), NULL);
-
- if (button->dialog)
- return gtk_window_get_title (GTK_WINDOW (button->dialog));
- else
- return gtk_native_dialog_get_title (GTK_NATIVE_DIALOG (button->native));
-}
-
-/**
- * gtk_file_chooser_button_get_width_chars:
- * @button: the button widget to examine.
- *
- * Retrieves the width in characters of the @button widget’s entry and/or label.
- *
- * Returns: an integer width (in characters) that the button will use to size itself.
- */
-int
-gtk_file_chooser_button_get_width_chars (GtkFileChooserButton *button)
-{
- g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), -1);
-
- return gtk_label_get_width_chars (GTK_LABEL (button->label));
-}
-
-/**
- * gtk_file_chooser_button_set_width_chars:
- * @button: the button widget to examine.
- * @n_chars: the new width, in characters.
- *
- * Sets the width (in characters) that @button will use to @n_chars.
- */
-void
-gtk_file_chooser_button_set_width_chars (GtkFileChooserButton *button,
- int n_chars)
-{
- g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
-
- gtk_label_set_width_chars (GTK_LABEL (button->label), n_chars);
- g_object_notify (G_OBJECT (button), "width-chars");
-}
-
-/**
- * gtk_file_chooser_button_set_modal:
- * @button: a #GtkFileChooserButton
- * @modal: %TRUE to make the dialog modal
- *
- * Sets whether the dialog should be modal.
- */
-void
-gtk_file_chooser_button_set_modal (GtkFileChooserButton *button,
- gboolean modal)
-{
- g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
-
- g_object_set (button, "modal", modal, NULL);
-}
-
-/**
- * gtk_file_chooser_button_get_modal:
- * @button: a #GtkFileChooserButton
- *
- * Gets whether the dialog is modal.
- *
- * Returns: %TRUE if the dialog is modal
- */
-gboolean
-gtk_file_chooser_button_get_modal (GtkFileChooserButton *button)
-{
- gboolean modal;
-
- g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), FALSE);
-
- g_object_get (button, "modal", &modal, NULL);
-
- return modal;
-}
diff --git a/gtk/gtkfilechooserbutton.h b/gtk/gtkfilechooserbutton.h
deleted file mode 100644
index cf4b1aaea5..0000000000
--- a/gtk/gtkfilechooserbutton.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* gtkfilechooserbutton.h
- *
- * Copyright (c) 2004 James M. Cape <jcape@ignore-your.tv>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GTK_FILE_CHOOSER_BUTTON_H__
-#define __GTK_FILE_CHOOSER_BUTTON_H__
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#include <gtk/gtkbox.h>
-#include <gtk/gtkfilechooser.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_FILE_CHOOSER_BUTTON (gtk_file_chooser_button_get_type ())
-#define GTK_FILE_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER_BUTTON, GtkFileChooserButton))
-#define GTK_IS_FILE_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILE_CHOOSER_BUTTON))
-
-typedef struct _GtkFileChooserButton GtkFileChooserButton;
-
-GDK_AVAILABLE_IN_ALL
-GType gtk_file_chooser_button_get_type (void) G_GNUC_CONST;
-GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_file_chooser_button_new (const char *title,
- GtkFileChooserAction action);
-GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_file_chooser_button_new_with_dialog (GtkWidget *dialog);
-GDK_AVAILABLE_IN_ALL
-const char * gtk_file_chooser_button_get_title (GtkFileChooserButton *button);
-GDK_AVAILABLE_IN_ALL
-void gtk_file_chooser_button_set_title (GtkFileChooserButton *button,
- const char *title);
-GDK_AVAILABLE_IN_ALL
-int gtk_file_chooser_button_get_width_chars (GtkFileChooserButton *button);
-GDK_AVAILABLE_IN_ALL
-void gtk_file_chooser_button_set_width_chars (GtkFileChooserButton *button,
- int n_chars);
-GDK_AVAILABLE_IN_ALL
-gboolean gtk_file_chooser_button_get_modal (GtkFileChooserButton *button);
-GDK_AVAILABLE_IN_ALL
-void gtk_file_chooser_button_set_modal (GtkFileChooserButton *button,
- gboolean modal);
-
-G_END_DECLS
-
-#endif /* !__GTK_FILE_CHOOSER_BUTTON_H__ */
diff --git a/gtk/meson.build b/gtk/meson.build
index d7f206c231..0e0239a8a6 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -241,7 +241,6 @@ gtk_public_sources = files([
'gtkexpander.c',
'gtkexpression.c',
'gtkfilechooser.c',
- 'gtkfilechooserbutton.c',
'gtkfilechooserdialog.c',
'gtkfilechoosernative.c',
'gtkfilechooserwidget.c',
@@ -529,7 +528,6 @@ gtk_public_headers = files([
'gtkexpander.h',
'gtkexpression.h',
'gtkfilechooser.h',
- 'gtkfilechooserbutton.h',
'gtkfilechooserdialog.h',
'gtkfilechoosernative.h',
'gtkfilechooserwidget.h',
diff --git a/tests/meson.build b/tests/meson.build
index 4acdc7dcaf..51b2311a80 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -33,7 +33,6 @@ gtk_tests = [
['testentrycompletion'],
['testentryicons'],
['testfilechooser'],
- ['testfilechooserbutton'],
['testflowbox'],
['testfontoptions'],
['testframe'],
diff --git a/tests/testfilechooserbutton.c b/tests/testfilechooserbutton.c
deleted file mode 100644
index 239790c8af..0000000000
--- a/tests/testfilechooserbutton.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
-
-/* GTK+: gtkfilechooserbutton.c
- *
- * Copyright (c) 2004 James M. Cape <jcape@ignore-your.tv>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-static const char *backend = "gtk+";
-static gboolean rtl = FALSE;
-static GOptionEntry entries[] = {
- { "backend", 'b', 0, G_OPTION_ARG_STRING, &backend, "The filesystem backend to use.", "gtk+" },
- { "right-to-left", 'r', 0, G_OPTION_ARG_NONE, &rtl, "Force right-to-left layout.", NULL },
- { NULL }
-};
-
-static char *gtk_src_dir = NULL;
-
-static void
-print_selected_path_clicked_cb (GtkWidget *button,
- gpointer user_data)
-{
- GFile *folder, *filename;
- char *folder_uri, *filename_uri;
-
- folder = gtk_file_chooser_get_current_folder (user_data);
- filename = gtk_file_chooser_get_file (user_data);
-
- folder_uri = g_file_get_uri (folder);
- filename_uri = g_file_get_uri (filename);
- g_message ("Currently Selected:\n\tFolder: `%s'\n\tFilename: `%s'\nDone.\n",
- folder_uri, filename_uri);
- g_free (folder_uri);
- g_free (filename_uri);
-
- g_object_unref (folder);
- g_object_unref (filename);
-}
-
-static void
-add_pwds_parent_as_shortcut_clicked_cb (GtkWidget *button,
- gpointer user_data)
-{
- GFile *path = g_file_new_for_path (gtk_src_dir);
- GError *err = NULL;
-
- if (!gtk_file_chooser_add_shortcut_folder (user_data, path, &err))
- {
- g_message ("Couldn't add `%s' as shortcut folder: %s", gtk_src_dir,
- err->message);
- g_error_free (err);
- }
- else
- {
- g_message ("Added `%s' as shortcut folder.", gtk_src_dir);
- }
-
- g_object_unref (path);
-}
-
-static void
-del_pwds_parent_as_shortcut_clicked_cb (GtkWidget *button,
- gpointer user_data)
-{
- GFile *path = g_file_new_for_path (gtk_src_dir);
- GError *err = NULL;
-
- if (!gtk_file_chooser_remove_shortcut_folder (user_data, path, &err))
- {
- g_message ("Couldn't remove `%s' as shortcut folder: %s", gtk_src_dir,
- err->message);
- g_error_free (err);
- }
- else
- {
- g_message ("Removed `%s' as shortcut folder.", gtk_src_dir);
- }
-
- g_object_unref (path);
-}
-
-static void
-tests_button_clicked_cb (GtkButton *real_button,
- gpointer user_data)
-{
- GtkWidget *tests;
-
- tests = g_object_get_data (user_data, "tests-dialog");
-
- if (tests == NULL)
- {
- GtkWidget *box, *button;
-
- tests = gtk_window_new ();
- gtk_window_set_hide_on_close (GTK_WINDOW (tests), TRUE);
- gtk_window_set_title (GTK_WINDOW (tests),
- "Tests - TestFileChooserButton");
- gtk_window_set_transient_for (GTK_WINDOW (tests),
- GTK_WINDOW (gtk_widget_get_root (user_data)));
-
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_append (GTK_BOX (tests), box);
-
- button = gtk_button_new_with_label ("Print Selected Path");
- g_signal_connect (button, "clicked",
- G_CALLBACK (print_selected_path_clicked_cb), user_data);
- gtk_box_append (GTK_BOX (box), button);
-
- button = gtk_button_new_with_label ("Add $PWD's Parent as Shortcut");
- g_signal_connect (button, "clicked",
- G_CALLBACK (add_pwds_parent_as_shortcut_clicked_cb), user_data);
- gtk_box_append (GTK_BOX (box), button);
-
- button = gtk_button_new_with_label ("Remove $PWD's Parent as Shortcut");
- g_signal_connect (button, "clicked",
- G_CALLBACK (del_pwds_parent_as_shortcut_clicked_cb), user_data);
- gtk_box_append (GTK_BOX (box), button);
-
- g_object_set_data (user_data, "tests-dialog", tests);
- }
-
- gtk_window_present (GTK_WINDOW (tests));
-}
-
-static void
-chooser_selection_changed_cb (GtkFileChooser *chooser,
- gpointer user_data)
-{
- GFile *filename;
- char *uri;
-
- filename = gtk_file_chooser_get_file (chooser);
-
- uri = g_file_get_uri (filename);
- g_message ("%s::selection-changed\n\tSelection:`%s'\nDone.\n",
- G_OBJECT_TYPE_NAME (chooser), uri);
- g_free (uri);
-
- g_object_unref (filename);
-}
-
-static void
-add_new_filechooser_button (const char *mnemonic,
- const char *chooser_title,
- GtkFileChooserAction action,
- GtkWidget *group_box,
- GtkSizeGroup *label_group)
-{
- GtkWidget *hbox, *label, *chooser, *button;
- GFile *path;
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
- gtk_box_append (GTK_BOX (group_box), hbox);
-
- label = gtk_label_new_with_mnemonic (mnemonic);
- gtk_size_group_add_widget (GTK_SIZE_GROUP (label_group), label);
- gtk_label_set_xalign (GTK_LABEL (label), 0.0);
- gtk_box_append (GTK_BOX (hbox), label);
-
- chooser = gtk_file_chooser_button_new (g_strconcat(chooser_title,
- " - testfilechooserbutton", NULL),
- action);
- gtk_widget_set_hexpand (chooser, TRUE);
-
- path = g_file_new_for_path (gtk_src_dir);
- gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (chooser), path, NULL);
- gtk_file_chooser_remove_shortcut_folder (GTK_FILE_CHOOSER (chooser), path, NULL);
- g_object_unref (path);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), chooser);
- g_signal_connect (chooser, "selection-changed", G_CALLBACK (chooser_selection_changed_cb), NULL);
- gtk_box_append (GTK_BOX (hbox), chooser);
-
- button = gtk_button_new_with_label ("Tests");
- g_signal_connect (button, "clicked", G_CALLBACK (tests_button_clicked_cb), chooser);
- gtk_box_append (GTK_BOX (hbox), button);
-}
-
-static void
-quit_cb (GtkWidget *widget,
- gpointer data)
-{
- gboolean *done = data;
-
- *done = TRUE;
-
- g_main_context_wakeup (NULL);
-}
-
-int
-main (int argc,
- char *argv[])
-{
- GtkWidget *win, *vbox, *frame, *group_box;
- GtkSizeGroup *label_group;
- GOptionContext *context;
- char *cwd;
- gboolean done = FALSE;
-
- context = g_option_context_new ("- test GtkFileChooserButton widget");
- g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
- g_option_context_parse (context, &argc, &argv, NULL);
- g_option_context_free (context);
-
- gtk_init ();
-
- /* to test rtl layout, use "--right-to-left" */
- if (rtl)
- gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
-
- cwd = g_get_current_dir();
- gtk_src_dir = g_path_get_dirname (cwd);
- g_free (cwd);
-
- win = gtk_dialog_new_with_buttons ("TestFileChooserButton", NULL, 0,
- "_Quit", GTK_RESPONSE_CLOSE, NULL);
- g_signal_connect (win, "response", G_CALLBACK (quit_cb), &done);
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 18);
- gtk_widget_set_margin_start (vbox, 6);
- gtk_widget_set_margin_end (vbox, 6);
- gtk_widget_set_margin_top (vbox, 6);
- gtk_widget_set_margin_bottom (vbox, 6);
- gtk_box_append (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (win))), vbox);
-
- frame = gtk_frame_new ("<b>GtkFileChooserButton</b>");
- gtk_label_set_use_markup (GTK_LABEL (gtk_frame_get_label_widget (GTK_FRAME (frame))), TRUE);
- gtk_box_append (GTK_BOX (vbox), frame);
-
- gtk_widget_set_halign (frame, GTK_ALIGN_FILL);
- gtk_widget_set_valign (frame, GTK_ALIGN_FILL);
- g_object_set (frame, "margin-top", 6, "margin-start", 12, NULL);
-
- label_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-
- group_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_frame_set_child (GTK_FRAME (frame), group_box);
-
- /* OPEN */
- add_new_filechooser_button ("_Open:", "Select A File",
- GTK_FILE_CHOOSER_ACTION_OPEN,
- group_box, label_group);
-
- /* SELECT_FOLDER */
- add_new_filechooser_button ("Select _Folder:", "Select A Folder",
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- group_box, label_group);
-
- g_object_unref (label_group);
-
- gtk_widget_show (win);
- gtk_window_present (GTK_WINDOW (win));
-
- while (!done)
- g_main_context_iteration (NULL, TRUE);
-
- return 0;
-}
diff --git a/testsuite/gtk/defaultvalue.c b/testsuite/gtk/defaultvalue.c
index 22146a5c90..d55e6d5381 100644
--- a/testsuite/gtk/defaultvalue.c
+++ b/testsuite/gtk/defaultvalue.c
@@ -94,8 +94,7 @@ test_type (gconstpointer data)
return;
/* These leak their GDBusConnections */
- if (g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_BUTTON) ||
- g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_DIALOG) ||
+ if (g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_DIALOG) ||
g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_WIDGET) ||
g_str_equal (g_type_name (type), "GtkPlacesSidebar"))
return;
diff --git a/testsuite/gtk/focus-chain/widget-factory.tab b/testsuite/gtk/focus-chain/widget-factory.tab
index 468e4560fd..b10898543d 100644
--- a/testsuite/gtk/focus-chain/widget-factory.tab
+++ b/testsuite/gtk/focus-chain/widget-factory.tab
@@ -16,7 +16,6 @@ GtkToggleButton
GtkToggleButton
GtkButton
GtkButton
-GtkButton
GtkLinkButton
GtkSwitch
GtkScale
diff --git a/testsuite/gtk/focus-chain/widget-factory.tab-backward b/testsuite/gtk/focus-chain/widget-factory.tab-backward
index dd7582889a..4025f6adf6 100644
--- a/testsuite/gtk/focus-chain/widget-factory.tab-backward
+++ b/testsuite/gtk/focus-chain/widget-factory.tab-backward
@@ -12,7 +12,6 @@ GtkSwitch
GtkLinkButton
GtkButton
GtkButton
-GtkButton
GtkToggleButton
GtkToggleButton
GtkToggleButton
diff --git a/testsuite/gtk/focus-chain/widget-factory.ui b/testsuite/gtk/focus-chain/widget-factory.ui
index 654671b4fd..cfa86b68fe 100644
--- a/testsuite/gtk/focus-chain/widget-factory.ui
+++ b/testsuite/gtk/focus-chain/widget-factory.ui
@@ -855,9 +855,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</object>
</child>
<child>
- <object class="GtkFileChooserButton" id="filechooserbutton1"/>
- </child>
- <child>
<object class="GtkLinkButton" id="linkbutton1">
<property name="label" translatable="yes">link button</property>
<property name="receives-default">1</property>
diff --git a/testsuite/gtk/focus-chain/widget-factory2.ui b/testsuite/gtk/focus-chain/widget-factory2.ui
index 5dd9037329..748c98ffde 100644
--- a/testsuite/gtk/focus-chain/widget-factory2.ui
+++ b/testsuite/gtk/focus-chain/widget-factory2.ui
@@ -856,9 +856,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</object>
</child>
<child>
- <object class="GtkFileChooserButton" id="filechooserbutton1"/>
- </child>
- <child>
<object class="GtkLinkButton" id="linkbutton1">
<property name="label" translatable="yes">link button</property>
<property name="receives-default">1</property>
diff --git a/testsuite/gtk/focus-chain/widget-factory3.ui b/testsuite/gtk/focus-chain/widget-factory3.ui
index b6d52bea51..d7a2643843 100644
--- a/testsuite/gtk/focus-chain/widget-factory3.ui
+++ b/testsuite/gtk/focus-chain/widget-factory3.ui
@@ -856,9 +856,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</object>
</child>
<child>
- <object class="GtkFileChooserButton" id="filechooserbutton1"/>
- </child>
- <child>
<object class="GtkLinkButton" id="linkbutton1">
<property name="label" translatable="yes">link button</property>
<property name="receives-default">1</property>
diff --git a/testsuite/gtk/notify.c b/testsuite/gtk/notify.c
index f90fb66be2..12ae9edb89 100644
--- a/testsuite/gtk/notify.c
+++ b/testsuite/gtk/notify.c
@@ -401,8 +401,7 @@ test_type (gconstpointer data)
return;
/* These leak their GDBusConnections */
- if (g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_BUTTON) ||
- g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_DIALOG) ||
+ if (g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_DIALOG) ||
g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_WIDGET) ||
g_type_is_a (type, GTK_TYPE_FILE_CHOOSER_NATIVE))
return;
diff --git a/testsuite/gtk/object.c b/testsuite/gtk/object.c
index d4c13339c8..2efe3cdb65 100644
--- a/testsuite/gtk/object.c
+++ b/testsuite/gtk/object.c
@@ -57,8 +57,6 @@ list_ignore_properties (gboolean buglist)
{ "GtkWidget", "has-default", (void*) TRUE, }, /* conflicts with toplevel-less widgets */
{ "GtkWidget", "display", (void*) MATCH_ANY_VALUE },
{ "GtkCellView", "background", (void*) "", }, /* "" is not a valid background color */
- { "GtkFileChooserButton", "select-multiple", (void*) MATCH_ANY_VALUE }, /* property disabled */
- { "GtkFileChooserButton", "action", (void*) GTK_FILE_CHOOSER_ACTION_SAVE },
{ "GtkFileChooserWidget", "select-multiple", (void*) 0x1 }, /* property conflicts */
{ "GtkFileChooserDialog", "select-multiple", (void*) MATCH_ANY_VALUE }, /* property disabled */
{ "GtkTextView", "overwrite", (void*) MATCH_ANY_VALUE }, /* needs text buffer */
diff --git a/testsuite/gtk/templates.c b/testsuite/gtk/templates.c
index 9eb1974213..843fd500d9 100644
--- a/testsuite/gtk/templates.c
+++ b/testsuite/gtk/templates.c
@@ -331,23 +331,6 @@ test_file_chooser_dialog_show (void)
}
static void
-test_file_chooser_button_basic (void)
-{
- GtkWidget *widget;
- gboolean done = FALSE;
-
- g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
-
- widget = gtk_file_chooser_button_new ("Choose a file !", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
- g_assert (GTK_IS_FILE_CHOOSER_BUTTON (widget));
- g_timeout_add (100, main_loop_quit_cb, &done);
- while (!done)
- g_main_context_iteration (NULL, TRUE);
-
- g_object_unref (g_object_ref_sink (widget));
-}
-
-static void
test_font_button_basic (void)
{
GtkWidget *widget;
@@ -469,7 +452,6 @@ main (int argc, char **argv)
g_test_add_func ("/template/GtkFileChooserWidget/basic", test_file_chooser_widget_basic);
g_test_add_func ("/template/GtkFileChooserDialog/basic", test_file_chooser_dialog_basic);
g_test_add_func ("/template/GtkFileChooserDialog/show", test_file_chooser_dialog_show);
- g_test_add_func ("/template/GtkFileChooserButton/basic", test_file_chooser_button_basic);
g_test_add_func ("/template/GtkFontButton/basic", test_font_button_basic);
g_test_add_func ("/template/GtkFontChooserWidget/basic", test_font_chooser_widget_basic);
g_test_add_func ("/template/GtkFontChooserDialog/basic", test_font_chooser_dialog_basic);