summaryrefslogtreecommitdiff
path: root/gtk/gtkfilechooserbutton.c
diff options
context:
space:
mode:
authorJames M. Cape <jcape@ignore-your.tv>2004-11-30 21:06:48 +0000
committerJames M. Cape <jcape@src.gnome.org>2004-11-30 21:06:48 +0000
commit1b45c64014d37e89fcaa2600cbda266f4d8cb5ca (patch)
tree1e35049232753fdf973b32ab91a9bfb1f681985d /gtk/gtkfilechooserbutton.c
parentf79a113bedb8217c418afbf0c293098d46f492a7 (diff)
downloadgtk+-1b45c64014d37e89fcaa2600cbda266f4d8cb5ca.tar.gz
removed "GtkFileChooserButton:active" property and getter/setter.
2004-11-30 James M. Cape <jcape@ignore-your.tv> * gtk/gtkfilechooserbutton.h (gtk_file_chooser_button_get_active) (gtk_file_chooser_button_set_active): * gtk/gtkfilechooserbutton.c (gtk_file_chooser_button_class_init) (gtk_file_chooser_button_get_active) (gtk_file_chooser_button_set_active): * docs/reference/gtk/gtk-sections.txt: * docs/reference/gtk/tmpl/gtkfilechooserbutton.sgml: * gtk/gtk.symbols: removed "GtkFileChooserButton:active" property and getter/setter. * gtk/gtkfilechooserbutton.c (struct _GtkFileChooserButtonPrivate) (button_toggled_cb) (dialog_response_cb) (button_notify_active_cb) (gtk_file_chooser_button_init) (button_clicked_cb) (gtk_file_chooser_button_show): Use a GtkButton instead of a GtkToggleButton. (struct _GtkFileChooserButtonPrivate) (gtk_file_chooser_button_destroy) (gtk_file_chooser_button_style_set) (gtk_file_chooser_button_screen_changed): Don't bother with the (remove_settings_signal) (settings_notify_cb) (check_icon_theme): Don't use GtkSettings at all, just call change_icon_theme() directly. (struct _GtkFileChooserButtonPrivate) (gtk_file_chooser_button_init) (gtk_file_chooser_button_drag_data_received) (gtk_file_chooser_button_mnemonic_activate) (gtk_file_chooser_button_set_width_chars) (gtk_file_chooser_button_get_width_chars) (entry_changed_cb) (update_idler) (update_entry) (update_dialog) (dialog_selection_changed_cb) (dialog_response_cb) (entry_size_allocate_cb): Remove all references to the now-defunct entry, store the old path (to support "Cancel") in an instance member. (update_label_and_image) (update_label) (update_image) (gtk_file_chooser_button_init) (dialog_response_cb) (dialog_selection_changed_cb): Merge label/image updates, only display the filename (not the whole path, fixes #157725). (struct _GtkFileChooserButtonPrivate) (dialog_selection_changed_cb) (dialog_selection_changed_proxy_cb): Merge "selection-changed" handlers, block while dialog is visible (fixes #158482). * tests/testfilechooserbutton.c (delete_event_cb) (properties_button_clicked_cb) (print_selected_path_clicked_cb) (tests_button_clicked_cb) (main): Add per-chooser "tests" window, don't delete on WM close, update properties_button_clicked_cb() "delete-event" callback.
Diffstat (limited to 'gtk/gtkfilechooserbutton.c')
-rw-r--r--gtk/gtkfilechooserbutton.c878
1 files changed, 144 insertions, 734 deletions
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index 014d53f6fe..98ba56ef87 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -32,18 +32,15 @@
#include "gtkalias.h"
#include "gtkintl.h"
+#include "gtkbutton.h"
#include "gtkdnd.h"
-#include "gtkentry.h"
-#include "gtkhbox.h"
#include "gtkicontheme.h"
#include "gtkiconfactory.h"
#include "gtkimage.h"
#include "gtklabel.h"
#include "gtkstock.h"
-#include "gtktogglebutton.h"
#include "gtkvseparator.h"
#include "gtkfilechooserdialog.h"
-#include "gtkfilechooserentry.h"
#include "gtkfilechooserprivate.h"
#include "gtkfilechooserutils.h"
@@ -61,8 +58,6 @@
#define ENTRY_BUTTON_SPACING 0
#define FALLBACK_ICON_SIZE 20
#define FALLBACK_ICON_NAME "stock_unknown"
-#define NEW_FILE_ICON_NAME "stock_new"
-#define NEW_DIR_ICON_NAME "stock_new-dir"
/* ********************** *
* Private Enumerations *
@@ -75,7 +70,6 @@ enum
PROP_DIALOG,
PROP_TITLE,
- PROP_ACTIVE,
PROP_WIDTH_CHARS
};
@@ -87,24 +81,19 @@ enum
struct _GtkFileChooserButtonPrivate
{
GtkWidget *dialog;
- GtkWidget *accept_button;
- GtkWidget *entry_box;
- GtkWidget *entry_image;
- GtkWidget *entry;
- GtkWidget *label_box;
- GtkWidget *label_image;
- GtkWidget *label;
GtkWidget *button;
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkFilePath *old_path;
gchar *backend;
- gulong entry_changed_id;
gulong dialog_file_activated_id;
gulong dialog_folder_changed_id;
gulong dialog_selection_changed_id;
- gulong dialog_selection_changed_proxy_id;
- gulong settings_signal_id;
- guint update_id;
gint icon_size;
+
+ /* Used for hiding/showing the dialog when the button is hidden */
+ guint8 active : 1;
};
@@ -162,8 +151,6 @@ static void dialog_update_preview_cb (GtkFileChooser *di
gpointer user_data);
static void dialog_selection_changed_cb (GtkFileChooser *dialog,
gpointer user_data);
-static void dialog_selection_changed_proxy_cb (GtkFileChooser *dialog,
- gpointer user_data);
static void dialog_file_activated_cb (GtkFileChooser *dialog,
gpointer user_data);
static void dialog_current_folder_changed_cb (GtkFileChooser *dialog,
@@ -174,30 +161,15 @@ static void dialog_notify_cb (GObject *di
static gboolean dialog_delete_event_cb (GtkWidget *dialog,
GdkEvent *event,
gpointer user_data);
-static void dialog_response_cb (GtkFileChooser *dialog,
+static void dialog_response_cb (GtkDialog *dialog,
gint response,
gpointer user_data);
-static void button_toggled_cb (GtkToggleButton *real_button,
- gpointer user_data);
-static void button_notify_active_cb (GObject *real_button,
- GParamSpec *pspec,
- gpointer user_data);
-
-static void entry_size_allocate_cb (GtkWidget *entry,
- GtkAllocation *allocation,
- gpointer user_data);
-static void entry_changed_cb (GtkEditable *editable,
+static void button_clicked_cb (GtkButton *real_button,
gpointer user_data);
/* Utility Functions */
-static void remove_settings_signal (GtkFileChooserButton *button,
- GdkScreen *screen);
-
-static void update_dialog (GtkFileChooserButton *button);
-static void update_entry (GtkFileChooserButton *button);
-static void update_label (GtkFileChooserButton *button);
-static void update_icons (GtkFileChooserButton *button);
+static void update_label_and_image (GtkFileChooserButton *button);
/* ******************* *
@@ -269,21 +241,6 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
G_PARAM_READWRITE));
/**
- * GtkFileChooserButton:active:
- *
- * %TRUE, if the #GtkFileChooserDialog associated with the button has been
- * made visible. This can also be set by the application, though it is
- * rarely useful to do so.
- *
- * Since: 2.6
- */
- g_object_class_install_property (gobject_class, PROP_ACTIVE,
- g_param_spec_boolean ("active",
- P_("Active"),
- P_("Whether the browse dialog is visible or not."),
- FALSE, G_PARAM_READWRITE));
-
- /**
* GtkFileChooserButton:width-chars:
*
* The width of the entry and label inside the button, in characters.
@@ -310,8 +267,6 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
GtkWidget *box, *image, *sep;
GtkTargetList *target_list;
- gtk_box_set_spacing (GTK_BOX (button), ENTRY_BUTTON_SPACING);
-
priv = G_TYPE_INSTANCE_GET_PRIVATE (button, GTK_TYPE_FILE_CHOOSER_BUTTON,
GtkFileChooserButtonPrivate);
button->priv = priv;
@@ -320,60 +275,38 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
gtk_widget_push_composite_child ();
- priv->entry_box = gtk_hbox_new (FALSE, 4);
- gtk_container_add (GTK_CONTAINER (button), priv->entry_box);
-
- priv->entry_image = gtk_image_new ();
- gtk_box_pack_start (GTK_BOX (priv->entry_box), priv->entry_image,
- FALSE, FALSE, 0);
- gtk_widget_show (priv->entry_image);
-
- priv->entry = _gtk_file_chooser_entry_new (FALSE);
- gtk_container_add (GTK_CONTAINER (priv->entry_box), priv->entry);
- gtk_widget_show (priv->entry);
-
- priv->button = gtk_toggle_button_new ();
- g_signal_connect (priv->button, "toggled",
- G_CALLBACK (button_toggled_cb), button);
- g_signal_connect (priv->button, "notify::active",
- G_CALLBACK (button_notify_active_cb), button);
- g_signal_connect (priv->entry, "size-allocate",
- G_CALLBACK (entry_size_allocate_cb), priv->button);
- gtk_box_pack_start (GTK_BOX (button), priv->button, TRUE, TRUE, 0);
+ priv->button = gtk_button_new ();
+ g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked_cb),
+ button);
+ gtk_container_add (GTK_CONTAINER (button), priv->button);
gtk_widget_show (priv->button);
box = gtk_hbox_new (FALSE, 4);
gtk_container_add (GTK_CONTAINER (priv->button), box);
gtk_widget_show (box);
-
- priv->label_box = gtk_hbox_new (FALSE, 6);
- gtk_container_add (GTK_CONTAINER (box), priv->label_box);
- gtk_widget_show (priv->label_box);
- priv->label_image = gtk_image_new ();
- gtk_box_pack_start (GTK_BOX (priv->label_box), priv->label_image,
- FALSE, FALSE, 0);
- gtk_widget_show (priv->label_image);
+ priv->image = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (box), priv->image, FALSE, FALSE, 0);
+ gtk_widget_show (priv->image);
priv->label = gtk_label_new (_(DEFAULT_FILENAME));
gtk_label_set_ellipsize (GTK_LABEL (priv->label), PANGO_ELLIPSIZE_START);
gtk_misc_set_alignment (GTK_MISC (priv->label), 0.0, 0.5);
- gtk_container_add (GTK_CONTAINER (priv->label_box), priv->label);
+ gtk_container_add (GTK_CONTAINER (box), priv->label);
gtk_widget_show (priv->label);
sep = gtk_vseparator_new ();
- gtk_box_pack_end (GTK_BOX (priv->label_box), sep, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), sep, FALSE, FALSE, 0);
gtk_widget_show (sep);
image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_box_pack_end (GTK_BOX (box), image, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 0);
gtk_widget_show (image);
gtk_widget_pop_composite_child ();
/* DnD */
- gtk_drag_dest_unset (priv->entry);
gtk_drag_dest_set (GTK_WIDGET (button),
(GTK_DEST_DEFAULT_ALL),
NULL, 0,
@@ -397,7 +330,6 @@ gtk_file_chooser_button_constructor (GType type,
{
GObject *object;
GtkFileChooserButtonPrivate *priv;
- GtkFilePath *path;
object = (*G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->constructor) (type,
n_params,
@@ -409,20 +341,23 @@ gtk_file_chooser_button_constructor (GType type,
if (priv->backend)
priv->dialog = gtk_file_chooser_dialog_new_with_backend (NULL, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
- priv->backend, NULL);
+ priv->backend,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN,
+ GTK_RESPONSE_ACCEPT,
+ NULL);
else
priv->dialog = gtk_file_chooser_dialog_new (NULL, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN,
+ GTK_RESPONSE_ACCEPT,
NULL);
- gtk_dialog_add_button (GTK_DIALOG (priv->dialog),
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
- priv->accept_button = gtk_dialog_add_button (GTK_DIALOG (priv->dialog),
- GTK_STOCK_OPEN,
- GTK_RESPONSE_ACCEPT);
gtk_dialog_set_default_response (GTK_DIALOG (priv->dialog),
GTK_RESPONSE_ACCEPT);
-
gtk_dialog_set_alternative_button_order (GTK_DIALOG (priv->dialog),
GTK_RESPONSE_ACCEPT,
GTK_RESPONSE_CANCEL,
@@ -449,9 +384,6 @@ gtk_file_chooser_button_constructor (GType type,
priv->dialog_selection_changed_id =
g_signal_connect (priv->dialog, "selection-changed",
G_CALLBACK (dialog_selection_changed_cb), object);
- priv->dialog_selection_changed_proxy_id =
- g_signal_connect (priv->dialog, "selection-changed",
- G_CALLBACK (dialog_selection_changed_proxy_cb), object);
g_signal_connect (priv->dialog, "update-preview",
G_CALLBACK (dialog_update_preview_cb), object);
g_signal_connect (priv->dialog, "notify",
@@ -459,17 +391,6 @@ gtk_file_chooser_button_constructor (GType type,
g_object_add_weak_pointer (G_OBJECT (priv->dialog),
(gpointer *) (&priv->dialog));
- _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (priv->entry),
- _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog)));
- path = gtk_file_path_new_steal ("/");
- _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (priv->entry),
- path);
- priv->entry_changed_id = g_signal_connect (priv->entry, "changed",
- G_CALLBACK (entry_changed_cb),
- object);
-
- update_label (GTK_FILE_CHOOSER_BUTTON (object));
-
return object;
}
@@ -489,10 +410,6 @@ gtk_file_chooser_button_set_property (GObject *object,
/* Construct-only */
priv->dialog = g_value_get_object (value);
break;
- case PROP_ACTIVE:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button),
- g_value_get_boolean (value));
- break;
case PROP_WIDTH_CHARS:
gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (object),
g_value_get_int (value));
@@ -509,45 +426,16 @@ gtk_file_chooser_button_set_property (GObject *object,
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_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;
}
-
- g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
- _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (priv->entry),
- g_value_get_enum (value));
- update_icons (GTK_FILE_CHOOSER_BUTTON (object));
- switch (g_value_get_enum (value))
- {
- case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
- gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
- /* Fall through to set the widget states */
- case GTK_FILE_CHOOSER_ACTION_OPEN:
- gtk_widget_hide (priv->entry_box);
- gtk_widget_show (priv->label_box);
- gtk_box_set_child_packing (GTK_BOX (object), priv->button,
- TRUE, TRUE, 0, GTK_PACK_START);
- gtk_button_set_label (GTK_BUTTON (priv->accept_button),
- GTK_STOCK_OPEN);
- break;
-
- case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
- gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
- /* Fall through to set the widget states */
- case GTK_FILE_CHOOSER_ACTION_SAVE:
- gtk_widget_show (priv->entry_box);
- gtk_widget_hide (priv->label_box);
- gtk_box_set_child_packing (GTK_BOX (object), priv->button,
- FALSE, FALSE, 0, GTK_PACK_START);
- gtk_button_set_label (GTK_BUTTON (priv->accept_button),
- GTK_STOCK_SAVE);
- break;
- }
+ g_object_set_property (G_OBJECT (priv->dialog), pspec->name, value);
+ update_label_and_image (GTK_FILE_CHOOSER_BUTTON (object));
break;
case PROP_TITLE:
@@ -588,13 +476,9 @@ gtk_file_chooser_button_get_property (GObject *object,
switch (param_id)
{
- case PROP_ACTIVE:
- g_value_set_boolean (value,
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button)));
- break;
case PROP_WIDTH_CHARS:
g_value_set_int (value,
- gtk_entry_get_width_chars (GTK_ENTRY (priv->entry)));
+ gtk_label_get_width_chars (GTK_LABEL (priv->label)));
break;
case PROP_TITLE:
@@ -629,14 +513,11 @@ gtk_file_chooser_button_destroy (GtkObject * object)
priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (object);
- if (priv->update_id)
- g_source_remove (priv->update_id);
-
if (priv->dialog != NULL)
gtk_widget_destroy (priv->dialog);
-
- remove_settings_signal (GTK_FILE_CHOOSER_BUTTON (object),
- gtk_widget_get_screen (GTK_WIDGET (object)));
+
+ if (priv->old_path)
+ gtk_file_path_free (priv->old_path);
if (GTK_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->destroy != NULL)
(*GTK_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->destroy) (object);
@@ -657,6 +538,8 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
guint drag_time)
{
GtkFileChooserButtonPrivate *priv;
+ GtkFileSystem *fs;
+ GtkFilePath *path;
gchar *text;
if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->drag_data_received != NULL)
@@ -671,11 +554,14 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (widget);
+ fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog));
+
switch (info)
{
case TEXT_URI_LIST:
{
gchar **uris;
+ GtkFilePath *base_path;
guint i;
gboolean selected;
@@ -687,10 +573,6 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
selected = FALSE;
for (i = 0; !selected && uris[i] != NULL; i++)
{
- GtkFileSystem *fs;
- GtkFilePath *path, *base_path;
-
- fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog));
path = gtk_file_system_uri_to_path (fs, uris[i]);
base_path = NULL;
@@ -713,11 +595,9 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
g_object_get (priv->dialog, "action", &action, NULL);
selected =
- ((((action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ||
- action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) &&
+ (((action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
gtk_file_info_get_is_folder (info)) ||
- ((action == GTK_FILE_CHOOSER_ACTION_OPEN ||
- action == GTK_FILE_CHOOSER_ACTION_SAVE) &&
+ (action == GTK_FILE_CHOOSER_ACTION_OPEN &&
!gtk_file_info_get_is_folder (info))) &&
_gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog),
path, NULL));
@@ -739,8 +619,13 @@ gtk_file_chooser_button_drag_data_received (GtkWidget *widget,
case TEXT_PLAIN:
text = gtk_selection_data_get_text (data);
- gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
- g_free (text);
+ path = gtk_file_path_new_steal (text);
+ _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog), path,
+ NULL);
+ gtk_file_path_free (path);
+ break;
+
+ default:
break;
}
@@ -769,7 +654,7 @@ gtk_file_chooser_button_show (GtkWidget *widget)
if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->show)
(*GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->show) (widget);
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button)))
+ if (priv->active)
gtk_widget_show (priv->dialog);
}
@@ -793,18 +678,7 @@ gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget,
GtkFileChooserButtonPrivate *priv;
priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (widget);
-
- switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog)))
- {
- case GTK_FILE_CHOOSER_ACTION_OPEN:
- case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
- gtk_widget_grab_focus (priv->button);
- break;
- case GTK_FILE_CHOOSER_ACTION_SAVE:
- case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
- gtk_widget_grab_focus (priv->entry);
- break;
- }
+ gtk_widget_grab_focus (priv->button);
return TRUE;
}
@@ -824,44 +698,7 @@ change_icon_theme (GtkFileChooserButton *button)
else
button->priv->icon_size = FALLBACK_ICON_SIZE;
- update_icons (button);
-}
-
-/* Callback used when a GtkSettings value changes */
-static void
-settings_notify_cb (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- const char *name;
-
- name = g_param_spec_get_name (pspec);
-
- if (strcmp (name, "gtk-icon-theme-name") == 0
- || strcmp (name, "gtk-icon-sizes") == 0)
- change_icon_theme (user_data);
-}
-
-/* Installs a signal handler for GtkSettings so that we can monitor changes in
- * the icon theme.
- */
-static void
-check_icon_theme (GtkFileChooserButton *button)
-{
- GtkSettings *settings;
-
- if (button->priv->settings_signal_id)
- return;
-
- if (gtk_widget_has_screen (GTK_WIDGET (button)))
- {
- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (button)));
- button->priv->settings_signal_id = g_signal_connect (settings, "notify",
- G_CALLBACK (settings_notify_cb),
- button);
-
- change_icon_theme (button);
- }
+ update_label_and_image (button);
}
static void
@@ -888,8 +725,7 @@ gtk_file_chooser_button_screen_changed (GtkWidget *widget,
(*GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->screen_changed) (widget,
old_screen);
- remove_settings_signal (button, old_screen);
- check_icon_theme (button);
+ change_icon_theme (button);
}
@@ -997,42 +833,6 @@ gtk_file_chooser_button_get_title (GtkFileChooserButton *button)
}
/**
- * gtk_file_chooser_button_set_active:
- * @button: the button widget to modify.
- * @is_active: whether or not the dialog is visible.
- *
- * Modifies whether or not the dialog attached to @button is visible or not.
- *
- * Since: 2.6
- **/
-void
-gtk_file_chooser_button_set_active (GtkFileChooserButton *button,
- gboolean is_active)
-{
- g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button->priv->button), is_active);
-}
-
-/**
- * gtk_file_chooser_button_get_active:
- * @button: the button widget to examine.
- *
- * Retrieves whether or not the dialog attached to @button is visible.
- *
- * Returns: a boolean whether the dialog is visible or not.
- *
- * Since: 2.6
- **/
-gboolean
-gtk_file_chooser_button_get_active (GtkFileChooserButton *button)
-{
- g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), FALSE);
-
- return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button->priv->button));
-}
-
-/**
* gtk_file_chooser_button_get_width_chars:
* @button: the button widget to examine.
*
@@ -1047,7 +847,7 @@ gtk_file_chooser_button_get_width_chars (GtkFileChooserButton *button)
{
g_return_val_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button), -1);
- return gtk_entry_get_width_chars (GTK_ENTRY (button->priv->entry));
+ return gtk_label_get_width_chars (GTK_LABEL (button->priv->label));
}
/**
@@ -1065,7 +865,6 @@ gtk_file_chooser_button_set_width_chars (GtkFileChooserButton *button,
{
g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
- gtk_entry_set_width_chars (GTK_ENTRY (button->priv->entry), n_chars);
gtk_label_set_width_chars (GTK_LABEL (button->priv->label), n_chars);
g_object_notify (G_OBJECT (button), "width-chars");
}
@@ -1075,23 +874,7 @@ gtk_file_chooser_button_set_width_chars (GtkFileChooserButton *button,
* Utility Functions *
* ******************* */
-/* Removes the settings signal handler. It's safe to call multiple times */
-static void
-remove_settings_signal (GtkFileChooserButton *button,
- GdkScreen *screen)
-{
- if (button->priv->settings_signal_id)
- {
- GtkSettings *settings;
-
- settings = gtk_settings_get_for_screen (screen);
- g_signal_handler_disconnect (settings,
- button->priv->settings_signal_id);
- button->priv->settings_signal_id = 0;
- }
-}
-
-static GtkIconTheme *
+static inline GtkIconTheme *
get_icon_theme (GtkWidget *widget)
{
if (gtk_widget_has_screen (widget))
@@ -1100,146 +883,25 @@ get_icon_theme (GtkWidget *widget)
return gtk_icon_theme_get_default ();
}
-static gboolean
-check_if_path_exists (GtkFileSystem *fs,
- const GtkFilePath *path)
-{
- gboolean path_exists;
- GtkFilePath *parent_path;
-
- path_exists = FALSE;
- parent_path = NULL;
-
- if (gtk_file_system_get_parent (fs, path, &parent_path, NULL))
- {
- GtkFileFolder *folder;
-
- folder = gtk_file_system_get_folder (fs, parent_path, 0, NULL);
- if (folder)
- {
- GtkFileInfo *info;
-
- info = gtk_file_folder_get_info (folder, path, NULL);
- if (info)
- {
- path_exists = TRUE;
- gtk_file_info_free (info);
- }
-
- g_object_unref (folder);
- }
-
- gtk_file_path_free (parent_path);
- }
-
- return path_exists;
-}
-
static void
-update_icons (GtkFileChooserButton *button)
+update_label_and_image (GtkFileChooserButton *button)
{
GtkFileChooserButtonPrivate *priv;
GdkPixbuf *pixbuf;
- GSList *paths;
-
- priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button);
- pixbuf = NULL;
- paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (priv->dialog));
-
- if (paths)
- {
- GtkFilePath *path;
- GtkFileSystem *fs;
-
- path = paths->data;
- fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog));
-
- switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog)))
- {
- case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
- {
- GtkFileSystemVolume *volume;
-
- volume = gtk_file_system_get_volume_for_path (fs, path);
- if (volume)
- {
- GtkFilePath *base_path;
-
- base_path = gtk_file_system_volume_get_base_path (fs, volume);
-
- if (base_path && gtk_file_path_compare (base_path, path) == 0)
- pixbuf = gtk_file_system_volume_render_icon (fs, volume,
- GTK_WIDGET (button),
- priv->icon_size,
- NULL);
-
- if (base_path)
- gtk_file_path_free (base_path);
-
- gtk_file_system_volume_free (fs, volume);
- }
- }
-
- case GTK_FILE_CHOOSER_ACTION_OPEN:
- if (!pixbuf)
- pixbuf = gtk_file_system_render_icon (fs, path, GTK_WIDGET (button),
- priv->icon_size, NULL);
- break;
-
- case GTK_FILE_CHOOSER_ACTION_SAVE:
- if (check_if_path_exists (fs, path))
- pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)),
- GTK_STOCK_DIALOG_WARNING,
- priv->icon_size, 0, NULL);
- else
- pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)),
- NEW_FILE_ICON_NAME,
- priv->icon_size, 0, NULL);
- break;
- case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
- if (check_if_path_exists (fs, path))
- pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)),
- GTK_STOCK_DIALOG_WARNING,
- priv->icon_size, 0, NULL);
- else
- pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)),
- NEW_DIR_ICON_NAME,
- priv->icon_size, 0, NULL);
- break;
- }
-
- gtk_file_paths_free (paths);
- }
-
- if (!pixbuf)
- pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)),
- FALLBACK_ICON_NAME,
- priv->icon_size, 0, NULL);
-
- gtk_image_set_from_pixbuf (GTK_IMAGE (priv->entry_image), pixbuf);
- gtk_image_set_from_pixbuf (GTK_IMAGE (priv->label_image), pixbuf);
-
- if (pixbuf)
- g_object_unref (pixbuf);
-}
-
-
-static void
-update_label (GtkFileChooserButton *button)
-{
- GtkFileChooserButtonPrivate *priv;
gchar *label_text;
GSList *paths;
priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button);
paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (button->priv->dialog));
label_text = NULL;
+ pixbuf = NULL;
if (paths)
{
GtkFileSystem *fs;
- GtkFilePath *path;
+ GtkFilePath *path, *parent_path;
GtkFileSystemVolume *volume;
+ GtkFileFolder *folder;
path = paths->data;
@@ -1252,7 +914,13 @@ update_label (GtkFileChooserButton *button)
base_path = gtk_file_system_volume_get_base_path (fs, volume);
if (base_path && gtk_file_path_compare (base_path, path) == 0)
- label_text = gtk_file_system_volume_get_display_name (fs, volume);
+ {
+ label_text = gtk_file_system_volume_get_display_name (fs, volume);
+ pixbuf = gtk_file_system_volume_render_icon (fs, volume,
+ GTK_WIDGET (button),
+ priv->icon_size,
+ NULL);
+ }
if (base_path)
gtk_file_path_free (base_path);
@@ -1262,60 +930,28 @@ update_label (GtkFileChooserButton *button)
if (label_text)
goto out;
}
-
- if (gtk_file_system_path_is_local (fs, path))
- {
- const gchar *home;
- gchar *tmp;
- gchar *filename;
-
- filename = gtk_file_system_path_to_filename (fs, path);
-
- if (!filename)
- goto out;
-
- home = g_get_home_dir ();
-
- /* Munging for psuedo-volumes and files in the user's home tree */
- if (home)
- {
- if (strcmp (filename, home) == 0)
- {
- label_text = g_strdup (_("Home"));
- goto localout;
- }
-
- tmp = g_build_filename (home, "Desktop", NULL);
-
- if (strcmp (filename, tmp) == 0)
- label_text = g_strdup (_("Desktop"));
- g_free (tmp);
+ if (!pixbuf)
+ pixbuf = gtk_file_system_render_icon (fs, path, GTK_WIDGET (button),
+ priv->icon_size, NULL);
- if (label_text)
- goto out;
+ parent_path = NULL;
+ gtk_file_system_get_parent (fs, path, &parent_path, NULL);
- if (g_str_has_prefix (filename, home))
- {
- label_text = g_strconcat ("~", filename + strlen (home), NULL);
- goto localout;
- }
- }
-
- if (!label_text)
- label_text = g_strdup (filename);
-
- localout:
- g_free (filename);
- }
- else
+ folder = gtk_file_system_get_folder (fs, parent_path ? parent_path : path,
+ GTK_FILE_INFO_DISPLAY_NAME, NULL);
+ if (folder)
{
- gchar *uri;
+ GtkFileInfo *info;
- uri = gtk_file_system_path_to_uri (fs, path);
+ info = gtk_file_folder_get_info (folder, path, NULL);
+ g_object_unref (folder);
- if (uri)
- label_text = uri;
+ if (info)
+ {
+ label_text = g_strdup (gtk_file_info_get_display_name (info));
+ gtk_file_info_free (info);
+ }
}
out:
@@ -1329,180 +965,15 @@ update_label (GtkFileChooserButton *button)
}
else
gtk_label_set_text (GTK_LABEL (priv->label), _(DEFAULT_FILENAME));
-}
-
-static void
-update_entry (GtkFileChooserButton *button)
-{
- GtkFileChooserButtonPrivate *priv;
- GSList *paths;
- gchar *filename;
-
- priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button);
-
- paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (priv->dialog));
-
- if (paths)
- {
- GtkFileSystem *fs;
- GtkFilePath *path;
-
- path = paths->data;
- fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog));
-
- if (gtk_file_system_path_is_local (fs, path))
- {
- filename = gtk_file_system_path_to_filename (fs, path);
-
- if (filename)
- {
- const gchar *home;
- gchar *tmp;
-
- if (g_file_test (filename, G_FILE_TEST_IS_DIR))
- {
- tmp = g_strconcat (filename, "/", NULL);
- g_free (filename);
- filename = tmp;
- }
-
- home = g_get_home_dir ();
-
- if (home && g_str_has_prefix (filename, home))
- {
- tmp = g_strconcat ("~", filename + strlen (home), NULL);
- g_free (filename);
- filename = tmp;
- }
- }
- }
- else
- filename = gtk_file_system_path_to_uri (fs, path);
- }
- else
- filename = NULL;
-
- if (filename)
- {
- gchar *entry_text;
-
- entry_text = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
- g_free (filename);
-
- gtk_entry_set_text (GTK_ENTRY (priv->entry), entry_text);
- g_free (entry_text);
- }
- else
- gtk_entry_set_text (GTK_ENTRY (priv->entry), "");
-}
-
-static void
-update_dialog (GtkFileChooserButton *button)
-{
- GtkFileChooserButtonPrivate *priv;
- GtkFilePath *current_folder;
- GtkFileSystem *fs;
- GtkFilePath *folder_part, *full_path;
- gchar *file_part;
- const gchar *text;
- GtkFilePath *base_path;
-
- priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button);
- file_part = NULL;
- folder_part = NULL;
- fs = _gtk_file_chooser_get_file_system (GTK_FILE_CHOOSER (priv->dialog));
-
- text = gtk_entry_get_text (GTK_ENTRY (priv->entry));
-
- base_path = gtk_file_path_new_dup ("/");
- gtk_file_system_parse (fs, base_path, text, &folder_part, &file_part, NULL);
- gtk_file_path_free (base_path);
-
- switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog)))
- {
- case GTK_FILE_CHOOSER_ACTION_OPEN:
- gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
- if (folder_part)
- {
- GtkFileFolder *folder;
- GtkFileInfo *info;
-
- folder = gtk_file_system_get_folder (fs, folder_part,
- GTK_FILE_INFO_IS_FOLDER, NULL);
-
- full_path = gtk_file_system_make_path (fs, folder_part, file_part, NULL);
- info = gtk_file_folder_get_info (folder, full_path, NULL);
-
- /* Entry contents don't exist. */
- if (info == NULL)
- _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog),
- folder_part, NULL);
- /* Entry contents are a folder */
- else if (gtk_file_info_get_is_folder (info))
- _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog),
- full_path, NULL);
- /* Entry contents must be a file. */
- else
- _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog),
- full_path, NULL);
-
- if (info)
- gtk_file_info_free (info);
-
- gtk_file_path_free (full_path);
- }
- break;
- case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
- gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
- if (folder_part)
- {
- /* Entry contents don't exist. */
- if (file_part && file_part[0] != '\0')
- {
- full_path = gtk_file_system_make_path (fs, folder_part, file_part,
- NULL);
- if (full_path)
- {
- _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (priv->dialog),
- full_path, NULL);
- gtk_file_path_free (full_path);
- }
- else
- _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog),
- folder_part, NULL);
- }
- else
- {
- _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog),
- folder_part, NULL);
- }
- }
- break;
-
- case GTK_FILE_CHOOSER_ACTION_SAVE:
- case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
- gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
- if (folder_part)
- {
- current_folder = _gtk_file_chooser_get_current_folder_path (GTK_FILE_CHOOSER (priv->dialog));
-
- if (!current_folder ||
- gtk_file_path_compare (current_folder, folder_part) != 0)
- {
- _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (priv->dialog),
- folder_part, NULL);
- g_signal_emit_by_name (button, "current-folder-changed");
- }
-
- if (current_folder)
- gtk_file_path_free (current_folder);
- }
+
+ if (!pixbuf)
+ pixbuf = gtk_icon_theme_load_icon (get_icon_theme (GTK_WIDGET (button)),
+ FALLBACK_ICON_NAME,
+ priv->icon_size, 0, NULL);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (priv->dialog),
- file_part);
- g_signal_emit_by_name (button, "selection-changed");
- break;
- }
+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
+ if (pixbuf)
+ g_object_unref (pixbuf);
}
/* ************************ *
@@ -1527,25 +998,7 @@ static void
dialog_selection_changed_cb (GtkFileChooser *dialog,
gpointer user_data)
{
- GtkFileChooserButtonPrivate *priv;
-
- priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data);
-
- g_signal_handler_block (priv->entry, priv->entry_changed_id);
- update_entry (user_data);
- g_signal_handler_unblock (priv->entry, priv->entry_changed_id);
- update_icons (user_data);
- update_label (user_data);
-}
-
-static void
-dialog_selection_changed_proxy_cb (GtkFileChooser *dialog,
- gpointer user_data)
-{
- GtkFileChooserButtonPrivate *priv;
-
- priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data);
-
+ update_label_and_image (user_data);
g_signal_emit_by_name (user_data, "selection-changed");
}
@@ -1580,9 +1033,9 @@ dialog_delete_event_cb (GtkWidget *dialog,
}
static void
-dialog_response_cb (GtkFileChooser *dialog,
- gint response,
- gpointer user_data)
+dialog_response_cb (GtkDialog *dialog,
+ gint response,
+ gpointer user_data)
{
GtkFileChooserButtonPrivate *priv;
@@ -1590,36 +1043,58 @@ dialog_response_cb (GtkFileChooser *dialog,
if (response == GTK_RESPONSE_ACCEPT)
{
- g_signal_handler_block (priv->entry, priv->entry_changed_id);
- update_entry (user_data);
- g_signal_handler_unblock (priv->entry, priv->entry_changed_id);
- update_label (user_data);
- update_icons (user_data);
-
g_signal_emit_by_name (user_data, "current-folder-changed");
g_signal_emit_by_name (user_data, "selection-changed");
}
- else
+ else if (priv->old_path)
{
- g_signal_handler_block (priv->dialog, priv->dialog_selection_changed_id);
- update_dialog (user_data);
- g_signal_handler_unblock (priv->dialog, priv->dialog_selection_changed_id);
+ switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)))
+ {
+ case GTK_FILE_CHOOSER_ACTION_OPEN:
+ _gtk_file_chooser_select_path (GTK_FILE_CHOOSER (dialog), priv->old_path,
+ NULL);
+ break;
+ case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
+ _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (dialog),
+ priv->old_path, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
}
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE);
+ if (priv->old_path)
+ {
+ gtk_file_path_free (priv->old_path);
+ priv->old_path = NULL;
+ }
+
+ update_label_and_image (user_data);
+
+ g_signal_handler_unblock (priv->dialog,
+ priv->dialog_folder_changed_id);
+ g_signal_handler_unblock (priv->dialog,
+ priv->dialog_file_activated_id);
+ g_signal_handler_unblock (priv->dialog,
+ priv->dialog_selection_changed_id);
+ priv->active = FALSE;
+ gtk_widget_hide (priv->dialog);
}
static void
-button_toggled_cb (GtkToggleButton *real_button,
- gpointer user_data)
+button_clicked_cb (GtkButton *real_button,
+ gpointer user_data)
{
GtkFileChooserButtonPrivate *priv;
priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data);
- if (gtk_toggle_button_get_active (real_button))
+ if (!priv->active)
{
+ GSList *paths;
+
/* Setup the dialog parent to be chooser button's toplevel, and be modal
as needed. */
if (!GTK_WIDGET_VISIBLE (priv->dialog))
@@ -1631,7 +1106,8 @@ button_toggled_cb (GtkToggleButton *real_button,
if (GTK_WIDGET_TOPLEVEL (toplevel) && GTK_IS_WINDOW (toplevel))
{
if (GTK_WINDOW (toplevel) != gtk_window_get_transient_for (GTK_WINDOW (priv->dialog)))
- gtk_window_set_transient_for (GTK_WINDOW (priv->dialog), GTK_WINDOW (toplevel));
+ gtk_window_set_transient_for (GTK_WINDOW (priv->dialog),
+ GTK_WINDOW (toplevel));
gtk_window_set_modal (GTK_WINDOW (priv->dialog),
gtk_window_get_modal (GTK_WINDOW (toplevel)));
@@ -1643,84 +1119,18 @@ button_toggled_cb (GtkToggleButton *real_button,
g_signal_handler_block (priv->dialog,
priv->dialog_file_activated_id);
g_signal_handler_block (priv->dialog,
- priv->dialog_selection_changed_proxy_id);
- gtk_widget_set_sensitive (priv->entry, FALSE);
- gtk_window_present (GTK_WINDOW (priv->dialog));
- }
- else
- {
- g_signal_handler_unblock (priv->dialog,
- priv->dialog_folder_changed_id);
- g_signal_handler_unblock (priv->dialog,
- priv->dialog_file_activated_id);
- g_signal_handler_unblock (priv->dialog,
- priv->dialog_selection_changed_proxy_id);
- gtk_widget_set_sensitive (priv->entry, TRUE);
- gtk_widget_hide (priv->dialog);
- }
-}
-
-static void
-button_notify_active_cb (GObject *real_button,
- GParamSpec *pspec,
- gpointer user_data)
-{
- g_object_notify (user_data, "active");
-}
-
-
-static gboolean
-update_idler (gpointer user_data)
-{
- GtkFileChooserButtonPrivate *priv;
- gboolean retval;
- gint start, end;
-
- GDK_THREADS_ENTER ();
-
- priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data);
-
- if (!gtk_editable_get_selection_bounds (GTK_EDITABLE (priv->entry),
- &start, &end))
- {
- g_signal_handler_block (priv->dialog,
priv->dialog_selection_changed_id);
- update_dialog (user_data);
- g_signal_handler_unblock (priv->dialog,
- priv->dialog_selection_changed_id);
- update_icons (user_data);
- update_label (user_data);
- priv->update_id = 0;
- retval = FALSE;
- }
- else
- retval = FALSE;
-
- GDK_THREADS_LEAVE ();
-
- return retval;
-}
-
-static void
-entry_changed_cb (GtkEditable *editable,
- gpointer user_data)
-{
- GtkFileChooserButtonPrivate *priv;
-
- priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (user_data);
+ paths = _gtk_file_chooser_get_paths (GTK_FILE_CHOOSER (priv->dialog));
+ if (paths)
+ {
+ if (paths->data)
+ priv->old_path = gtk_file_path_copy (paths->data);
- if (priv->update_id)
- g_source_remove (priv->update_id);
+ gtk_file_paths_free (paths);
+ }
- priv->update_id = g_idle_add_full (G_PRIORITY_LOW, update_idler,
- user_data, NULL);
-}
+ priv->active = TRUE;
+ }
-/* Ensure the button height == entry height */
-static void
-entry_size_allocate_cb (GtkWidget *entry,
- GtkAllocation *allocation,
- gpointer user_data)
-{
- gtk_widget_set_size_request (user_data, -1, allocation->height);
+ gtk_window_present (GTK_WINDOW (priv->dialog));
}