2006-11-08 19:46:56 +00:00
|
|
|
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
|
2004-09-26 05:47:11 +00:00
|
|
|
/* gtkpathbar.c
|
2004-02-20 01:10:28 +00:00
|
|
|
* Copyright (C) 2004 Red Hat, Inc., Jonathan Blandford <jrb@gnome.org>
|
|
|
|
*
|
|
|
|
* 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
|
2012-02-27 13:01:10 +00:00
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
2004-02-20 01:10:28 +00:00
|
|
|
*/
|
|
|
|
|
2008-06-22 14:28:52 +00:00
|
|
|
#include "config.h"
|
2010-09-09 13:35:58 +00:00
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
#include "gtkpathbar.h"
|
2010-09-09 13:35:58 +00:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
#include "gtkarrow.h"
|
2012-03-03 18:22:22 +00:00
|
|
|
#include "gtkbox.h"
|
2004-11-20 04:52:57 +00:00
|
|
|
#include "gtkdnd.h"
|
2012-03-03 18:22:22 +00:00
|
|
|
#include "gtkiconfactory.h"
|
|
|
|
#include "gtkicontheme.h"
|
2004-03-08 09:56:34 +00:00
|
|
|
#include "gtkimage.h"
|
|
|
|
#include "gtkintl.h"
|
2004-02-20 01:10:28 +00:00
|
|
|
#include "gtklabel.h"
|
2004-02-23 07:11:31 +00:00
|
|
|
#include "gtkmain.h"
|
|
|
|
#include "gtkmarshalers.h"
|
2012-03-03 18:22:22 +00:00
|
|
|
#include "gtksettings.h"
|
|
|
|
#include "gtktogglebutton.h"
|
2012-03-16 19:01:50 +00:00
|
|
|
#include "gtkwidgetpath.h"
|
2010-07-09 17:22:23 +00:00
|
|
|
|
2004-02-23 07:11:31 +00:00
|
|
|
|
|
|
|
enum {
|
|
|
|
PATH_CLICKED,
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
2004-03-08 09:56:34 +00:00
|
|
|
typedef enum {
|
|
|
|
NORMAL_BUTTON,
|
|
|
|
ROOT_BUTTON,
|
|
|
|
HOME_BUTTON,
|
2004-03-10 06:20:48 +00:00
|
|
|
DESKTOP_BUTTON
|
2004-03-08 09:56:34 +00:00
|
|
|
} ButtonType;
|
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
#define BUTTON_DATA(x) ((ButtonData *)(x))
|
|
|
|
|
2005-11-22 12:40:15 +00:00
|
|
|
#define SCROLL_DELAY_FACTOR 5
|
2004-09-26 05:47:11 +00:00
|
|
|
|
2004-02-23 07:11:31 +00:00
|
|
|
static guint path_bar_signals [LAST_SIGNAL] = { 0 };
|
|
|
|
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
/* Icon size for if we can't get it from the theme */
|
2005-02-11 17:30:33 +00:00
|
|
|
#define FALLBACK_ICON_SIZE 16
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
typedef struct _ButtonData ButtonData;
|
|
|
|
|
|
|
|
struct _ButtonData
|
|
|
|
{
|
|
|
|
GtkWidget *button;
|
|
|
|
ButtonType type;
|
|
|
|
char *dir_name;
|
2008-06-10 00:39:35 +00:00
|
|
|
GFile *file;
|
2004-03-09 21:29:59 +00:00
|
|
|
GtkWidget *image;
|
|
|
|
GtkWidget *label;
|
2008-06-10 00:39:35 +00:00
|
|
|
GCancellable *cancellable;
|
2004-10-28 15:00:05 +00:00
|
|
|
guint ignore_changes : 1;
|
|
|
|
guint file_is_hidden : 1;
|
2004-03-09 21:29:59 +00:00
|
|
|
};
|
2005-06-13 19:18:54 +00:00
|
|
|
/* This macro is used to check if a button can be used as a fake root.
|
|
|
|
* All buttons in front of a fake root are automatically hidden when in a
|
|
|
|
* directory below a fake root and replaced with the "<" arrow button.
|
|
|
|
*/
|
|
|
|
#define BUTTON_IS_FAKE_ROOT(button) ((button)->type == HOME_BUTTON)
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2006-05-14 04:25:34 +00:00
|
|
|
G_DEFINE_TYPE (GtkPathBar, gtk_path_bar, GTK_TYPE_CONTAINER)
|
2004-02-20 01:10:28 +00:00
|
|
|
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
static void gtk_path_bar_finalize (GObject *object);
|
|
|
|
static void gtk_path_bar_dispose (GObject *object);
|
2008-03-03 21:15:21 +00:00
|
|
|
static void gtk_path_bar_realize (GtkWidget *widget);
|
|
|
|
static void gtk_path_bar_unrealize (GtkWidget *widget);
|
2010-10-27 13:13:26 +00:00
|
|
|
static void gtk_path_bar_get_preferred_width (GtkWidget *widget,
|
|
|
|
gint *minimum,
|
|
|
|
gint *natural);
|
|
|
|
static void gtk_path_bar_get_preferred_height (GtkWidget *widget,
|
|
|
|
gint *minimum,
|
|
|
|
gint *natural);
|
2008-03-03 21:15:21 +00:00
|
|
|
static void gtk_path_bar_map (GtkWidget *widget);
|
|
|
|
static void gtk_path_bar_unmap (GtkWidget *widget);
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
static void gtk_path_bar_size_allocate (GtkWidget *widget,
|
|
|
|
GtkAllocation *allocation);
|
|
|
|
static void gtk_path_bar_add (GtkContainer *container,
|
|
|
|
GtkWidget *widget);
|
|
|
|
static void gtk_path_bar_remove (GtkContainer *container,
|
|
|
|
GtkWidget *widget);
|
|
|
|
static void gtk_path_bar_forall (GtkContainer *container,
|
|
|
|
gboolean include_internals,
|
|
|
|
GtkCallback callback,
|
|
|
|
gpointer callback_data);
|
2011-09-05 16:12:13 +00:00
|
|
|
static GtkWidgetPath *gtk_path_bar_get_path_for_child (GtkContainer *container,
|
|
|
|
GtkWidget *child);
|
2008-03-03 21:15:21 +00:00
|
|
|
static gboolean gtk_path_bar_scroll (GtkWidget *widget,
|
|
|
|
GdkEventScroll *event);
|
|
|
|
static void gtk_path_bar_scroll_up (GtkPathBar *path_bar);
|
|
|
|
static void gtk_path_bar_scroll_down (GtkPathBar *path_bar);
|
2005-02-11 17:30:33 +00:00
|
|
|
static void gtk_path_bar_stop_scrolling (GtkPathBar *path_bar);
|
2007-05-16 17:42:53 +00:00
|
|
|
static gboolean gtk_path_bar_slider_up_defocus (GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar);
|
|
|
|
static gboolean gtk_path_bar_slider_down_defocus (GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar);
|
2004-09-26 05:47:11 +00:00
|
|
|
static gboolean gtk_path_bar_slider_button_press (GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar);
|
|
|
|
static gboolean gtk_path_bar_slider_button_release(GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar);
|
|
|
|
static void gtk_path_bar_grab_notify (GtkWidget *widget,
|
|
|
|
gboolean was_grabbed);
|
|
|
|
static void gtk_path_bar_state_changed (GtkWidget *widget,
|
|
|
|
GtkStateType previous_state);
|
2011-01-04 01:41:49 +00:00
|
|
|
static void gtk_path_bar_style_updated (GtkWidget *widget);
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
static void gtk_path_bar_screen_changed (GtkWidget *widget,
|
|
|
|
GdkScreen *previous_screen);
|
|
|
|
static void gtk_path_bar_check_icon_theme (GtkPathBar *path_bar);
|
|
|
|
static void gtk_path_bar_update_button_appearance (GtkPathBar *path_bar,
|
|
|
|
ButtonData *button_data,
|
|
|
|
gboolean current_dir);
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2006-11-08 19:46:56 +00:00
|
|
|
static void
|
|
|
|
on_slider_unmap (GtkWidget *widget,
|
|
|
|
GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
if (path_bar->timer &&
|
2006-11-09 16:51:05 +00:00
|
|
|
((widget == path_bar->up_slider_button && path_bar->scrolling_up) ||
|
|
|
|
(widget == path_bar->down_slider_button && path_bar->scrolling_down)))
|
|
|
|
gtk_path_bar_stop_scrolling (path_bar);
|
2006-11-08 19:46:56 +00:00
|
|
|
}
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
static GtkWidget *
|
2004-03-12 22:51:13 +00:00
|
|
|
get_slider_button (GtkPathBar *path_bar,
|
|
|
|
GtkArrowType arrow_type)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
|
|
|
GtkWidget *button;
|
2007-05-16 17:42:53 +00:00
|
|
|
AtkObject *atk_obj;
|
2004-02-25 08:55:48 +00:00
|
|
|
|
|
|
|
gtk_widget_push_composite_child ();
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
button = gtk_button_new ();
|
2007-05-16 17:42:53 +00:00
|
|
|
atk_obj = gtk_widget_get_accessible (button);
|
|
|
|
if (arrow_type == GTK_ARROW_LEFT)
|
|
|
|
atk_object_set_name (atk_obj, _("Up Path"));
|
|
|
|
else
|
|
|
|
atk_object_set_name (atk_obj, _("Down Path"));
|
|
|
|
|
2005-11-21 15:00:57 +00:00
|
|
|
gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
|
2012-03-03 03:53:22 +00:00
|
|
|
gtk_widget_add_events (button, GDK_SCROLL_MASK);
|
2008-08-11 09:17:49 +00:00
|
|
|
gtk_container_add (GTK_CONTAINER (button),
|
|
|
|
gtk_arrow_new (arrow_type, GTK_SHADOW_OUT));
|
2004-02-20 01:10:28 +00:00
|
|
|
gtk_container_add (GTK_CONTAINER (path_bar), button);
|
|
|
|
gtk_widget_show_all (button);
|
|
|
|
|
2006-11-08 19:46:56 +00:00
|
|
|
g_signal_connect (G_OBJECT (button), "unmap",
|
|
|
|
G_CALLBACK (on_slider_unmap), path_bar);
|
|
|
|
|
2004-02-25 08:55:48 +00:00
|
|
|
gtk_widget_pop_composite_child ();
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
return button;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_init (GtkPathBar *path_bar)
|
|
|
|
{
|
2011-11-28 19:41:02 +00:00
|
|
|
GtkStyleContext *context;
|
|
|
|
|
2010-03-06 10:29:31 +00:00
|
|
|
gtk_widget_set_has_window (GTK_WIDGET (path_bar), FALSE);
|
2004-02-20 01:10:28 +00:00
|
|
|
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (path_bar), FALSE);
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
path_bar->get_info_cancellable = NULL;
|
2006-05-01 21:41:12 +00:00
|
|
|
|
Merged the federico-filename-entry branch, to fix bug #136541. Combined
2006-05-03 Federico Mena Quintero <federico@novell.com>
Merged the federico-filename-entry branch, to fix bug #136541.
Combined ChangeLogs:
2006-04-17 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechooserdefault.c (pending_select_paths_process):
Oops, we *do* need to check that we are in OPEN mode before
selecting the first row in the file list. See
https://bugzilla.novell.com/show_bug.cgi?id=166906
(gtk_file_chooser_default_get_paths): If we are in the case for
the file list, and the list has no selected rows, jump to the case
for the filename entry. This is so that
1. The user types a filename in the SAVE filename entry
("foo.txt").
2. He then double-clicks on a folder ("bar") in the file
list.
will yield the expected "bar/foo.txt" selection.
2006-03-29 Federico Mena Quintero <federico@novell.com>
* gtk/gtkpathbar.c (gtk_path_bar_init): Reduce the inter-button
spacing to 0.
* gtk/gtkfilechooserdefault.c (browse_widgets_create): Make the
location label bold.
2006-03-29 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechooserdefault.c (location_mode_set): Just change the
location_mode field if we are in SAVE/CREATE_FOLDER modes.
(gtk_file_chooser_default_get_paths): Get the path based on the
currently focused widget, or the last-focused widget. This is
what we should have been doing in the beginning, but it worked out
fine because we didn't have the possibility of a filename entry in
OPEN mode.
(gtk_file_chooser_default_should_respond): Handle the case where
the last focused widget is the location_entry.
2006-03-28 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechoosersettings.[ch]: New files with a simple
framework for saving/loading settings from the file chooser in
$XDG_CONFIG_HOME/gtk-2.0/gtkfilechooser.
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_unmap):
Save the current settings.
(settings_save): New helper function. We save the location_mode
and show_hidden flags.
(gtk_file_chooser_default_map): Load the settings.
(settings_load): New helper function.
* gtk/gtkfilechooserentry.c
(_gtk_file_chooser_entry_set_file_part): Oops, don't modify
in_change. Our handlers are what set the file_part, so they
*must* be run when we modify the text.
2006-03-27 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechooserprivate.h (struct _GtkFileChooserDefault):
Removed the save_file_name_entry. We'll make this be the same as
the location_entry widget.
(struct _GtkFileChooserDefault): Leave only location_button,
location_entry_box, location_label, location_entry. We'll use a
single toggle button for the location entry, which will appear
below the path bar.
(struct _GtkFileChooserDefault): Added a
processing_pending_selections flag.
* gtk/gtkfilechooserdefault.c (save_widgets_create): Destroy the
old location_entry if necessary, and hide the location toggle
widgets.
(update_chooser_entry): In multiple selection mode, just clear the
location_entry.
(check_save_entry): Allow running in OPEN or SELECT_FOLDER modes
if we are in LOCATION_MODE_FILENAME_ENTRY.
(gtk_file_chooser_default_should_respond): Switch to a folder if
the location_entry contains a folder name in OPEN and SAVE mode,
not just SAVE mode. If the entry doesn't contain a folder name,
but is otherwise well-formed, and we are in OPEN mode, return that
we should respond with that filename.
(gtk_file_chooser_default_initial_focus): Focus the location_entry
if appropriate.
(browse_widgets_create): Create the location_entry_box and the
location_label here.
(update_appearance): Call location_mode_set() when switching back
to OPEN/SELECT_FOLDER mode. Hide the location_button when
switching to SAVE/CREATE_FOLDER mode.
(pending_select_paths_process): Turn the
processing_pending_selections flag on and off around changes to
the current selection. Don't special-case OPEN mode anymore,
since the new flag will take care of things in
update_chooser_entry().
(update_chooser_entry): Don't do anything if
processing_pending_selections is TRUE. This keeps the entry from
being polluted when changing folders.
(location_popup_handler): In OPEN/SELECT_FOLDER modes, toggle
between the path bar and the entry. In SAVE/CREATE_FOLDER modes, simply focus the
location_entry.
(update_from_entry): Removed.
(location_entry_create): Removed.
(open_location_cb): Removed.
(file_list_build_popup_menu): Don't add an "Open _Location" menu item.
(location_entry_set_initial_text): Don't do anything if
current_folder is NULL.
* gtk/gtkfilechooserentry.c
(_gtk_file_chooser_entry_set_file_part): Turn in_change on and off
around the call to gtk_entry_set_text(). This makes completion
not happen when the caller has explicitly set a name.
2006-03-24 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechooserprivate.h (struct _GtkFileChooserDefault):
Added fields location_mode_box, location_pathbar_radio,
location_filename_radio, location_widget_box, location_label,
location_entry. The radio buttons will switch between the pathbar
and the location entry; the other boxes are for layout purposes.
(enum LocationMode): New enum.
(struct _GtkFileChooserDefault): Added a location_mode field.
* gtk/gtkfilechooserdefault.c (browse_widgets_create): Create the
location radio buttons to switch between the pathbar and the
location entry. Pack the browse_path_bar in the new
location_widget_box instead of a generic hbox.
(location_buttons_create): New function.
(gtk_file_chooser_default_init): Initialize impl->location_mode.
(location_switch_to_path_bar): New function.
(location_switch_to_filename_entry): New function.
* gtk/gtkfilechooserbutton.c (model_add_special): The display_name
should not be const.
2006-05-03 22:30:52 +00:00
|
|
|
path_bar->spacing = 0;
|
2004-03-12 22:51:13 +00:00
|
|
|
path_bar->up_slider_button = get_slider_button (path_bar, GTK_ARROW_LEFT);
|
|
|
|
path_bar->down_slider_button = get_slider_button (path_bar, GTK_ARROW_RIGHT);
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
path_bar->icon_size = FALLBACK_ICON_SIZE;
|
2004-09-26 05:47:11 +00:00
|
|
|
|
2008-08-11 09:17:49 +00:00
|
|
|
g_signal_connect_swapped (path_bar->up_slider_button, "clicked",
|
|
|
|
G_CALLBACK (gtk_path_bar_scroll_up), path_bar);
|
|
|
|
g_signal_connect_swapped (path_bar->down_slider_button, "clicked",
|
|
|
|
G_CALLBACK (gtk_path_bar_scroll_down), path_bar);
|
|
|
|
|
|
|
|
g_signal_connect (path_bar->up_slider_button, "focus-out-event",
|
|
|
|
G_CALLBACK (gtk_path_bar_slider_up_defocus), path_bar);
|
|
|
|
g_signal_connect (path_bar->down_slider_button, "focus-out-event",
|
|
|
|
G_CALLBACK (gtk_path_bar_slider_down_defocus), path_bar);
|
|
|
|
|
|
|
|
g_signal_connect (path_bar->up_slider_button, "button-press-event",
|
|
|
|
G_CALLBACK (gtk_path_bar_slider_button_press), path_bar);
|
|
|
|
g_signal_connect (path_bar->up_slider_button, "button-release-event",
|
|
|
|
G_CALLBACK (gtk_path_bar_slider_button_release), path_bar);
|
|
|
|
g_signal_connect (path_bar->down_slider_button, "button-press-event",
|
|
|
|
G_CALLBACK (gtk_path_bar_slider_button_press), path_bar);
|
|
|
|
g_signal_connect (path_bar->down_slider_button, "button-release-event",
|
|
|
|
G_CALLBACK (gtk_path_bar_slider_button_release), path_bar);
|
2011-11-28 19:41:02 +00:00
|
|
|
|
|
|
|
context = gtk_widget_get_style_context (GTK_WIDGET (path_bar));
|
|
|
|
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LINKED);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_class_init (GtkPathBarClass *path_bar_class)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class;
|
|
|
|
GtkWidgetClass *widget_class;
|
|
|
|
GtkContainerClass *container_class;
|
|
|
|
|
|
|
|
gobject_class = (GObjectClass *) path_bar_class;
|
|
|
|
widget_class = (GtkWidgetClass *) path_bar_class;
|
|
|
|
container_class = (GtkContainerClass *) path_bar_class;
|
|
|
|
|
2004-02-23 07:11:31 +00:00
|
|
|
gobject_class->finalize = gtk_path_bar_finalize;
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
gobject_class->dispose = gtk_path_bar_dispose;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-10-27 13:13:26 +00:00
|
|
|
widget_class->get_preferred_width = gtk_path_bar_get_preferred_width;
|
|
|
|
widget_class->get_preferred_height = gtk_path_bar_get_preferred_height;
|
2008-03-03 21:15:21 +00:00
|
|
|
widget_class->realize = gtk_path_bar_realize;
|
|
|
|
widget_class->unrealize = gtk_path_bar_unrealize;
|
|
|
|
widget_class->map = gtk_path_bar_map;
|
2005-03-22 17:36:41 +00:00
|
|
|
widget_class->unmap = gtk_path_bar_unmap;
|
2004-02-20 01:10:28 +00:00
|
|
|
widget_class->size_allocate = gtk_path_bar_size_allocate;
|
2011-01-04 01:41:49 +00:00
|
|
|
widget_class->style_updated = gtk_path_bar_style_updated;
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
widget_class->screen_changed = gtk_path_bar_screen_changed;
|
2004-09-26 05:47:11 +00:00
|
|
|
widget_class->grab_notify = gtk_path_bar_grab_notify;
|
|
|
|
widget_class->state_changed = gtk_path_bar_state_changed;
|
2008-03-03 21:15:21 +00:00
|
|
|
widget_class->scroll_event = gtk_path_bar_scroll;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
|
|
|
container_class->add = gtk_path_bar_add;
|
|
|
|
container_class->forall = gtk_path_bar_forall;
|
|
|
|
container_class->remove = gtk_path_bar_remove;
|
2011-09-05 16:12:13 +00:00
|
|
|
container_class->get_path_for_child = gtk_path_bar_get_path_for_child;
|
2010-10-08 14:25:27 +00:00
|
|
|
gtk_container_class_handle_border_width (container_class);
|
2004-02-20 23:21:01 +00:00
|
|
|
/* FIXME: */
|
|
|
|
/* container_class->child_type = gtk_path_bar_child_type;*/
|
2004-02-23 07:11:31 +00:00
|
|
|
|
|
|
|
path_bar_signals [PATH_CLICKED] =
|
2005-09-01 05:11:46 +00:00
|
|
|
g_signal_new (I_("path-clicked"),
|
2010-09-18 23:55:42 +00:00
|
|
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
2004-02-23 07:11:31 +00:00
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GtkPathBarClass, path_clicked),
|
|
|
|
NULL, NULL,
|
2005-11-10 15:17:40 +00:00
|
|
|
_gtk_marshal_VOID__POINTER_POINTER_BOOLEAN,
|
|
|
|
G_TYPE_NONE, 3,
|
|
|
|
G_TYPE_POINTER,
|
2004-04-02 00:35:07 +00:00
|
|
|
G_TYPE_POINTER,
|
|
|
|
G_TYPE_BOOLEAN);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2004-02-23 07:11:31 +00:00
|
|
|
gtk_path_bar_finalize (GObject *object)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
|
|
|
GtkPathBar *path_bar;
|
|
|
|
|
|
|
|
path_bar = GTK_PATH_BAR (object);
|
2005-02-11 17:30:33 +00:00
|
|
|
|
|
|
|
gtk_path_bar_stop_scrolling (path_bar);
|
|
|
|
|
2004-02-23 07:11:31 +00:00
|
|
|
g_list_free (path_bar->button_list);
|
2008-06-10 00:39:35 +00:00
|
|
|
if (path_bar->root_file)
|
|
|
|
g_object_unref (path_bar->root_file);
|
|
|
|
if (path_bar->home_file)
|
|
|
|
g_object_unref (path_bar->home_file);
|
|
|
|
if (path_bar->desktop_file)
|
|
|
|
g_object_unref (path_bar->desktop_file);
|
2004-03-10 06:20:48 +00:00
|
|
|
|
2004-03-04 06:47:54 +00:00
|
|
|
if (path_bar->root_icon)
|
2004-03-09 16:08:49 +00:00
|
|
|
g_object_unref (path_bar->root_icon);
|
2004-03-10 06:20:48 +00:00
|
|
|
if (path_bar->home_icon)
|
|
|
|
g_object_unref (path_bar->home_icon);
|
|
|
|
if (path_bar->desktop_icon)
|
|
|
|
g_object_unref (path_bar->desktop_icon);
|
|
|
|
|
2004-03-08 09:56:34 +00:00
|
|
|
if (path_bar->file_system)
|
|
|
|
g_object_unref (path_bar->file_system);
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2004-02-23 07:31:44 +00:00
|
|
|
G_OBJECT_CLASS (gtk_path_bar_parent_class)->finalize (object);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
/* Removes the settings signal handler. It's safe to call multiple times */
|
|
|
|
static void
|
|
|
|
remove_settings_signal (GtkPathBar *path_bar,
|
|
|
|
GdkScreen *screen)
|
|
|
|
{
|
|
|
|
if (path_bar->settings_signal_id)
|
|
|
|
{
|
|
|
|
GtkSettings *settings;
|
|
|
|
|
|
|
|
settings = gtk_settings_get_for_screen (screen);
|
|
|
|
g_signal_handler_disconnect (settings,
|
|
|
|
path_bar->settings_signal_id);
|
|
|
|
path_bar->settings_signal_id = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_dispose (GObject *object)
|
|
|
|
{
|
2006-05-01 21:41:12 +00:00
|
|
|
GtkPathBar *path_bar = GTK_PATH_BAR (object);
|
|
|
|
|
|
|
|
remove_settings_signal (path_bar, gtk_widget_get_screen (GTK_WIDGET (object)));
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (path_bar->get_info_cancellable)
|
|
|
|
g_cancellable_cancel (path_bar->get_info_cancellable);
|
|
|
|
path_bar->get_info_cancellable = NULL;
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (gtk_path_bar_parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
/* Size requisition:
|
|
|
|
*
|
|
|
|
* Ideally, our size is determined by another widget, and we are just filling
|
|
|
|
* available space.
|
|
|
|
*/
|
|
|
|
static void
|
2010-10-27 13:13:26 +00:00
|
|
|
gtk_path_bar_get_preferred_width (GtkWidget *widget,
|
|
|
|
gint *minimum,
|
|
|
|
gint *natural)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
ButtonData *button_data;
|
2004-02-20 01:10:28 +00:00
|
|
|
GtkPathBar *path_bar;
|
|
|
|
GList *list;
|
2010-10-27 13:13:26 +00:00
|
|
|
gint child_height;
|
|
|
|
gint height;
|
|
|
|
gint child_min, child_nat;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
|
|
|
path_bar = GTK_PATH_BAR (widget);
|
|
|
|
|
2010-10-27 13:13:26 +00:00
|
|
|
*minimum = *natural = 0;
|
|
|
|
height = 0;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data = BUTTON_DATA (list->data);
|
2010-10-27 13:13:26 +00:00
|
|
|
gtk_widget_get_preferred_width (button_data->button, &child_min, &child_nat);
|
|
|
|
gtk_widget_get_preferred_height (button_data->button, &child_height, NULL);
|
|
|
|
height = MAX (height, child_height);
|
2010-09-14 01:33:06 +00:00
|
|
|
|
2009-06-05 19:07:10 +00:00
|
|
|
if (button_data->type == NORMAL_BUTTON)
|
2010-10-27 13:13:26 +00:00
|
|
|
{
|
|
|
|
/* Use 2*Height as button width because of ellipsized label. */
|
|
|
|
child_min = MAX (child_min, child_height * 2);
|
|
|
|
child_nat = MAX (child_min, child_height * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
*minimum = MAX (*minimum, child_min);
|
|
|
|
*natural = MAX (*natural, child_nat);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add space for slider, if we have more than one path */
|
|
|
|
/* Theoretically, the slider could be bigger than the other button. But we're
|
|
|
|
* not going to worry about that now.
|
|
|
|
*/
|
2010-10-27 13:13:26 +00:00
|
|
|
path_bar->slider_width = MIN (height * 2 / 3 + 5, height);
|
2004-02-20 01:10:28 +00:00
|
|
|
if (path_bar->button_list && path_bar->button_list->next != NULL)
|
2010-10-27 13:13:26 +00:00
|
|
|
{
|
|
|
|
*minimum += (path_bar->spacing + path_bar->slider_width) * 2;
|
|
|
|
*natural += (path_bar->spacing + path_bar->slider_width) * 2;
|
|
|
|
}
|
|
|
|
}
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-10-27 13:13:26 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_get_preferred_height (GtkWidget *widget,
|
|
|
|
gint *minimum,
|
|
|
|
gint *natural)
|
|
|
|
{
|
|
|
|
ButtonData *button_data;
|
|
|
|
GtkPathBar *path_bar;
|
|
|
|
GList *list;
|
|
|
|
gint child_min, child_nat;
|
|
|
|
|
|
|
|
path_bar = GTK_PATH_BAR (widget);
|
|
|
|
|
|
|
|
*minimum = *natural = 0;
|
|
|
|
|
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
|
|
|
{
|
|
|
|
button_data = BUTTON_DATA (list->data);
|
|
|
|
gtk_widget_get_preferred_height (button_data->button, &child_min, &child_nat);
|
|
|
|
|
|
|
|
*minimum = MAX (*minimum, child_min);
|
|
|
|
*natural = MAX (*natural, child_nat);
|
|
|
|
}
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_update_slider_buttons (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
if (path_bar->button_list)
|
|
|
|
{
|
|
|
|
GtkWidget *button;
|
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
button = BUTTON_DATA (path_bar->button_list->data)->button;
|
2004-02-20 01:10:28 +00:00
|
|
|
if (gtk_widget_get_child_visible (button))
|
2005-11-21 15:00:57 +00:00
|
|
|
{
|
|
|
|
gtk_path_bar_stop_scrolling (path_bar);
|
|
|
|
gtk_widget_set_sensitive (path_bar->down_slider_button, FALSE);
|
|
|
|
}
|
2004-02-20 01:10:28 +00:00
|
|
|
else
|
|
|
|
gtk_widget_set_sensitive (path_bar->down_slider_button, TRUE);
|
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
button = BUTTON_DATA (g_list_last (path_bar->button_list)->data)->button;
|
2004-02-20 01:10:28 +00:00
|
|
|
if (gtk_widget_get_child_visible (button))
|
2005-11-21 15:00:57 +00:00
|
|
|
{
|
|
|
|
gtk_path_bar_stop_scrolling (path_bar);
|
|
|
|
gtk_widget_set_sensitive (path_bar->up_slider_button, FALSE);
|
|
|
|
}
|
2004-02-20 01:10:28 +00:00
|
|
|
else
|
|
|
|
gtk_widget_set_sensitive (path_bar->up_slider_button, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-03 21:15:21 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_map (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
gdk_window_show (GTK_PATH_BAR (widget)->event_window);
|
|
|
|
|
|
|
|
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->map (widget);
|
|
|
|
}
|
|
|
|
|
2005-03-22 17:36:41 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_unmap (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
gtk_path_bar_stop_scrolling (GTK_PATH_BAR (widget));
|
2008-03-03 21:15:21 +00:00
|
|
|
gdk_window_hide (GTK_PATH_BAR (widget)->event_window);
|
2005-03-22 17:36:41 +00:00
|
|
|
|
|
|
|
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->unmap (widget);
|
|
|
|
}
|
|
|
|
|
2008-03-03 21:15:21 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_realize (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkPathBar *path_bar;
|
2010-08-11 21:05:51 +00:00
|
|
|
GtkAllocation allocation;
|
|
|
|
GdkWindow *window;
|
2008-03-03 21:15:21 +00:00
|
|
|
GdkWindowAttr attributes;
|
|
|
|
gint attributes_mask;
|
|
|
|
|
2010-03-06 10:51:33 +00:00
|
|
|
gtk_widget_set_realized (widget, TRUE);
|
2008-03-03 21:15:21 +00:00
|
|
|
|
|
|
|
path_bar = GTK_PATH_BAR (widget);
|
2010-08-11 21:05:51 +00:00
|
|
|
window = gtk_widget_get_parent_window (widget);
|
|
|
|
gtk_widget_set_window (widget, window);
|
|
|
|
g_object_ref (window);
|
|
|
|
|
|
|
|
gtk_widget_get_allocation (widget, &allocation);
|
2008-03-03 21:15:21 +00:00
|
|
|
|
|
|
|
attributes.window_type = GDK_WINDOW_CHILD;
|
2010-08-11 21:05:51 +00:00
|
|
|
attributes.x = allocation.x;
|
|
|
|
attributes.y = allocation.y;
|
|
|
|
attributes.width = allocation.width;
|
|
|
|
attributes.height = allocation.height;
|
2008-03-03 21:15:21 +00:00
|
|
|
attributes.wclass = GDK_INPUT_ONLY;
|
|
|
|
attributes.event_mask = gtk_widget_get_events (widget);
|
|
|
|
attributes.event_mask |= GDK_SCROLL_MASK;
|
|
|
|
attributes_mask = GDK_WA_X | GDK_WA_Y;
|
|
|
|
|
|
|
|
path_bar->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
|
2010-08-11 21:05:51 +00:00
|
|
|
&attributes, attributes_mask);
|
2008-03-03 21:15:21 +00:00
|
|
|
gdk_window_set_user_data (path_bar->event_window, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_unrealize (GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkPathBar *path_bar;
|
|
|
|
|
|
|
|
path_bar = GTK_PATH_BAR (widget);
|
|
|
|
|
|
|
|
gdk_window_set_user_data (path_bar->event_window, NULL);
|
|
|
|
gdk_window_destroy (path_bar->event_window);
|
|
|
|
path_bar->event_window = NULL;
|
|
|
|
|
2008-08-12 09:06:34 +00:00
|
|
|
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->unrealize (widget);
|
2008-03-03 21:15:21 +00:00
|
|
|
}
|
|
|
|
|
2011-09-05 16:12:13 +00:00
|
|
|
static void
|
|
|
|
child_ordering_changed (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
|
|
|
if (path_bar->up_slider_button)
|
|
|
|
gtk_widget_reset_style (path_bar->up_slider_button);
|
|
|
|
if (path_bar->down_slider_button)
|
|
|
|
gtk_widget_reset_style (path_bar->down_slider_button);
|
|
|
|
|
|
|
|
for (l = path_bar->button_list; l; l = l->next)
|
|
|
|
{
|
|
|
|
ButtonData *data = l->data;
|
|
|
|
|
|
|
|
gtk_widget_reset_style (data->button);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
/* This is a tad complicated
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
gtk_path_bar_size_allocate (GtkWidget *widget,
|
|
|
|
GtkAllocation *allocation)
|
|
|
|
{
|
|
|
|
GtkWidget *child;
|
|
|
|
GtkPathBar *path_bar = GTK_PATH_BAR (widget);
|
|
|
|
GtkTextDirection direction;
|
|
|
|
GtkAllocation child_allocation;
|
|
|
|
GList *list, *first_button;
|
|
|
|
gint width;
|
|
|
|
gint allocation_width;
|
|
|
|
gboolean need_sliders = FALSE;
|
|
|
|
gint up_slider_offset = 0;
|
2010-04-20 04:33:20 +00:00
|
|
|
GtkRequisition child_requisition;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-08-11 21:05:51 +00:00
|
|
|
gtk_widget_set_allocation (widget, allocation);
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-03-02 06:16:02 +00:00
|
|
|
if (gtk_widget_get_realized (widget))
|
2008-03-03 21:15:21 +00:00
|
|
|
gdk_window_move_resize (path_bar->event_window,
|
|
|
|
allocation->x, allocation->y,
|
|
|
|
allocation->width, allocation->height);
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
/* No path is set; we don't have to allocate anything. */
|
|
|
|
if (path_bar->button_list == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
direction = gtk_widget_get_direction (widget);
|
2010-10-08 14:25:27 +00:00
|
|
|
allocation_width = allocation->width;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
|
|
|
/* First, we check to see if we need the scrollbars. */
|
2005-06-13 19:18:54 +00:00
|
|
|
if (path_bar->fake_root)
|
|
|
|
width = path_bar->spacing + path_bar->slider_width;
|
|
|
|
else
|
2010-04-20 04:33:20 +00:00
|
|
|
width = 0;
|
2005-06-13 19:18:54 +00:00
|
|
|
|
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
child = BUTTON_DATA (list->data)->button;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-09-21 14:35:17 +00:00
|
|
|
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
|
2010-04-20 04:33:20 +00:00
|
|
|
|
|
|
|
width += child_requisition.width + path_bar->spacing;
|
2005-06-13 19:18:54 +00:00
|
|
|
if (list == path_bar->fake_root)
|
|
|
|
break;
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (width <= allocation_width)
|
|
|
|
{
|
2005-06-13 19:18:54 +00:00
|
|
|
if (path_bar->fake_root)
|
|
|
|
first_button = path_bar->fake_root;
|
|
|
|
else
|
|
|
|
first_button = g_list_last (path_bar->button_list);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gboolean reached_end = FALSE;
|
|
|
|
gint slider_space = 2 * (path_bar->spacing + path_bar->slider_width);
|
|
|
|
|
2004-02-20 23:21:01 +00:00
|
|
|
if (path_bar->first_scrolled_button)
|
|
|
|
first_button = path_bar->first_scrolled_button;
|
|
|
|
else
|
|
|
|
first_button = path_bar->button_list;
|
2004-02-20 01:10:28 +00:00
|
|
|
need_sliders = TRUE;
|
|
|
|
|
|
|
|
/* To see how much space we have, and how many buttons we can display.
|
|
|
|
* We start at the first button, count forward until hit the new
|
|
|
|
* button, then count backwards.
|
|
|
|
*/
|
|
|
|
/* Count down the path chain towards the end. */
|
2010-09-21 14:35:17 +00:00
|
|
|
gtk_widget_get_preferred_size (BUTTON_DATA (first_button->data)->button,
|
|
|
|
&child_requisition, NULL);
|
2010-04-20 04:33:20 +00:00
|
|
|
|
|
|
|
width = child_requisition.width;
|
2004-02-20 01:10:28 +00:00
|
|
|
list = first_button->prev;
|
|
|
|
while (list && !reached_end)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
child = BUTTON_DATA (list->data)->button;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-09-21 14:35:17 +00:00
|
|
|
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
|
2010-04-20 04:33:20 +00:00
|
|
|
|
|
|
|
if (width + child_requisition.width +
|
2004-02-23 07:11:31 +00:00
|
|
|
path_bar->spacing + slider_space > allocation_width)
|
2004-02-20 01:10:28 +00:00
|
|
|
reached_end = TRUE;
|
2005-06-13 19:18:54 +00:00
|
|
|
else if (list == path_bar->fake_root)
|
|
|
|
break;
|
2004-02-20 01:10:28 +00:00
|
|
|
else
|
2010-04-20 04:33:20 +00:00
|
|
|
width += child_requisition.width + path_bar->spacing;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
|
|
|
list = list->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Finally, we walk up, seeing how many of the previous buttons we can
|
|
|
|
* add */
|
2005-06-13 19:18:54 +00:00
|
|
|
while (first_button->next && !reached_end)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
child = BUTTON_DATA (first_button->next->data)->button;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-09-21 14:35:17 +00:00
|
|
|
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
|
2010-04-20 04:33:20 +00:00
|
|
|
|
|
|
|
if (width + child_requisition.width + path_bar->spacing + slider_space > allocation_width)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
|
|
|
reached_end = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-04-20 04:33:20 +00:00
|
|
|
width += child_requisition.width + path_bar->spacing;
|
2005-06-13 19:18:54 +00:00
|
|
|
if (first_button == path_bar->fake_root)
|
|
|
|
break;
|
2004-02-20 01:10:28 +00:00
|
|
|
first_button = first_button->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now, we allocate space to the buttons */
|
2010-10-08 14:25:27 +00:00
|
|
|
child_allocation.y = allocation->y;
|
|
|
|
child_allocation.height = allocation->height;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL)
|
|
|
|
{
|
2010-10-08 14:25:27 +00:00
|
|
|
child_allocation.x = allocation->x + allocation->width;
|
2005-06-13 19:18:54 +00:00
|
|
|
if (need_sliders || path_bar->fake_root)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
|
|
|
child_allocation.x -= (path_bar->spacing + path_bar->slider_width);
|
2010-10-08 14:25:27 +00:00
|
|
|
up_slider_offset = allocation->width - path_bar->slider_width;
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-08 14:25:27 +00:00
|
|
|
child_allocation.x = allocation->x;
|
2005-06-13 19:18:54 +00:00
|
|
|
if (need_sliders || path_bar->fake_root)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2010-10-08 14:25:27 +00:00
|
|
|
up_slider_offset = 0;
|
2004-02-20 01:10:28 +00:00
|
|
|
child_allocation.x += (path_bar->spacing + path_bar->slider_width);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (list = first_button; list; list = list->prev)
|
|
|
|
{
|
2010-08-11 21:05:51 +00:00
|
|
|
GtkAllocation widget_allocation;
|
2009-06-05 19:07:10 +00:00
|
|
|
ButtonData *button_data;
|
|
|
|
|
|
|
|
button_data = BUTTON_DATA (list->data);
|
|
|
|
child = button_data->button;
|
|
|
|
|
2010-09-21 14:35:17 +00:00
|
|
|
gtk_widget_get_preferred_size (child, &child_requisition, NULL);
|
2010-04-20 04:33:20 +00:00
|
|
|
|
|
|
|
child_allocation.width = MIN (child_requisition.width,
|
2009-06-05 19:07:10 +00:00
|
|
|
allocation_width - (path_bar->spacing + path_bar->slider_width) * 2);
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2004-02-20 23:21:01 +00:00
|
|
|
if (direction == GTK_TEXT_DIR_RTL)
|
|
|
|
child_allocation.x -= child_allocation.width;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
|
|
|
/* Check to see if we've don't have any more space to allocate buttons */
|
|
|
|
if (need_sliders && direction == GTK_TEXT_DIR_RTL)
|
|
|
|
{
|
2010-08-11 21:05:51 +00:00
|
|
|
gtk_widget_get_allocation (widget, &widget_allocation);
|
2010-10-08 14:25:27 +00:00
|
|
|
if (child_allocation.x - path_bar->spacing - path_bar->slider_width < widget_allocation.x)
|
2004-02-20 01:10:28 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (need_sliders && direction == GTK_TEXT_DIR_LTR)
|
|
|
|
{
|
2010-08-11 21:05:51 +00:00
|
|
|
gtk_widget_get_allocation (widget, &widget_allocation);
|
2004-02-20 23:21:01 +00:00
|
|
|
if (child_allocation.x + child_allocation.width + path_bar->spacing + path_bar->slider_width >
|
2010-10-08 14:25:27 +00:00
|
|
|
widget_allocation.x + allocation_width)
|
2004-02-20 01:10:28 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-04-20 04:33:20 +00:00
|
|
|
if (child_allocation.width < child_requisition.width)
|
2009-06-05 19:07:10 +00:00
|
|
|
{
|
|
|
|
if (!gtk_widget_get_has_tooltip (child))
|
|
|
|
gtk_widget_set_tooltip_text (child, button_data->dir_name);
|
|
|
|
}
|
|
|
|
else if (gtk_widget_get_has_tooltip (child))
|
|
|
|
gtk_widget_set_tooltip_text (child, NULL);
|
|
|
|
|
|
|
|
gtk_widget_set_child_visible (child, TRUE);
|
2004-02-20 01:10:28 +00:00
|
|
|
gtk_widget_size_allocate (child, &child_allocation);
|
|
|
|
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL)
|
2009-06-05 19:07:10 +00:00
|
|
|
child_allocation.x -= path_bar->spacing;
|
2004-02-20 01:10:28 +00:00
|
|
|
else
|
2009-06-05 19:07:10 +00:00
|
|
|
child_allocation.x += child_allocation.width + path_bar->spacing;
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
/* Now we go hide all the widgets that don't fit */
|
|
|
|
while (list)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
gtk_widget_set_child_visible (BUTTON_DATA (list->data)->button, FALSE);
|
2004-02-20 01:10:28 +00:00
|
|
|
list = list->prev;
|
|
|
|
}
|
|
|
|
for (list = first_button->next; list; list = list->next)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
gtk_widget_set_child_visible (BUTTON_DATA (list->data)->button, FALSE);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
2005-06-13 19:18:54 +00:00
|
|
|
if (need_sliders || path_bar->fake_root)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
|
|
|
child_allocation.width = path_bar->slider_width;
|
|
|
|
child_allocation.x = up_slider_offset + allocation->x;
|
|
|
|
gtk_widget_size_allocate (path_bar->up_slider_button, &child_allocation);
|
|
|
|
|
2005-06-13 19:18:54 +00:00
|
|
|
gtk_widget_set_child_visible (path_bar->up_slider_button, TRUE);
|
|
|
|
gtk_widget_show_all (path_bar->up_slider_button);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gtk_widget_set_child_visible (path_bar->up_slider_button, FALSE);
|
|
|
|
|
|
|
|
if (need_sliders)
|
|
|
|
{
|
|
|
|
child_allocation.width = path_bar->slider_width;
|
2009-06-05 19:07:10 +00:00
|
|
|
|
|
|
|
if (direction == GTK_TEXT_DIR_RTL)
|
2010-10-08 14:25:27 +00:00
|
|
|
child_allocation.x = 0;
|
2009-06-05 19:07:10 +00:00
|
|
|
else
|
2010-10-08 14:25:27 +00:00
|
|
|
child_allocation.x = allocation->width - path_bar->slider_width;
|
2009-06-05 19:07:10 +00:00
|
|
|
|
|
|
|
child_allocation.x += allocation->x;
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
gtk_widget_size_allocate (path_bar->down_slider_button, &child_allocation);
|
|
|
|
|
|
|
|
gtk_widget_set_child_visible (path_bar->down_slider_button, TRUE);
|
|
|
|
gtk_widget_show_all (path_bar->down_slider_button);
|
|
|
|
gtk_path_bar_update_slider_buttons (path_bar);
|
|
|
|
}
|
|
|
|
else
|
2005-06-13 19:18:54 +00:00
|
|
|
gtk_widget_set_child_visible (path_bar->down_slider_button, FALSE);
|
2011-09-05 16:12:13 +00:00
|
|
|
|
|
|
|
child_ordering_changed (path_bar);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
static void
|
2011-01-04 01:41:49 +00:00
|
|
|
gtk_path_bar_style_updated (GtkWidget *widget)
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
{
|
2011-01-04 01:41:49 +00:00
|
|
|
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->style_updated (widget);
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
|
|
|
|
gtk_path_bar_check_icon_theme (GTK_PATH_BAR (widget));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_screen_changed (GtkWidget *widget,
|
|
|
|
GdkScreen *previous_screen)
|
|
|
|
{
|
|
|
|
if (GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->screen_changed)
|
|
|
|
GTK_WIDGET_CLASS (gtk_path_bar_parent_class)->screen_changed (widget, previous_screen);
|
|
|
|
|
|
|
|
/* We might nave a new settings, so we remove the old one */
|
|
|
|
if (previous_screen)
|
|
|
|
remove_settings_signal (GTK_PATH_BAR (widget), previous_screen);
|
|
|
|
|
|
|
|
gtk_path_bar_check_icon_theme (GTK_PATH_BAR (widget));
|
|
|
|
}
|
|
|
|
|
2008-03-03 21:15:21 +00:00
|
|
|
static gboolean
|
|
|
|
gtk_path_bar_scroll (GtkWidget *widget,
|
|
|
|
GdkEventScroll *event)
|
|
|
|
{
|
|
|
|
switch (event->direction)
|
|
|
|
{
|
|
|
|
case GDK_SCROLL_RIGHT:
|
|
|
|
case GDK_SCROLL_DOWN:
|
|
|
|
gtk_path_bar_scroll_down (GTK_PATH_BAR (widget));
|
|
|
|
break;
|
|
|
|
case GDK_SCROLL_LEFT:
|
|
|
|
case GDK_SCROLL_UP:
|
|
|
|
gtk_path_bar_scroll_up (GTK_PATH_BAR (widget));
|
|
|
|
break;
|
2012-03-03 03:09:28 +00:00
|
|
|
case GDK_SCROLL_SMOOTH:
|
|
|
|
break;
|
2008-03-03 21:15:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_add (GtkContainer *container,
|
|
|
|
GtkWidget *widget)
|
2011-09-05 16:12:13 +00:00
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
|
|
|
gtk_widget_set_parent (widget, GTK_WIDGET (container));
|
|
|
|
}
|
|
|
|
|
2004-03-17 15:29:06 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_remove_1 (GtkContainer *container,
|
|
|
|
GtkWidget *widget)
|
|
|
|
{
|
2010-03-01 06:47:38 +00:00
|
|
|
gboolean was_visible = gtk_widget_get_visible (widget);
|
2004-03-17 15:29:06 +00:00
|
|
|
gtk_widget_unparent (widget);
|
|
|
|
if (was_visible)
|
|
|
|
gtk_widget_queue_resize (GTK_WIDGET (container));
|
|
|
|
}
|
|
|
|
|
2004-02-20 01:10:28 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_remove (GtkContainer *container,
|
|
|
|
GtkWidget *widget)
|
|
|
|
{
|
|
|
|
GtkPathBar *path_bar;
|
|
|
|
GList *children;
|
|
|
|
|
|
|
|
path_bar = GTK_PATH_BAR (container);
|
|
|
|
|
2004-03-17 15:29:06 +00:00
|
|
|
if (widget == path_bar->up_slider_button)
|
|
|
|
{
|
|
|
|
gtk_path_bar_remove_1 (container, widget);
|
|
|
|
path_bar->up_slider_button = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (widget == path_bar->down_slider_button)
|
|
|
|
{
|
|
|
|
gtk_path_bar_remove_1 (container, widget);
|
|
|
|
path_bar->down_slider_button = NULL;
|
|
|
|
return;
|
|
|
|
}
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2004-03-17 15:29:06 +00:00
|
|
|
children = path_bar->button_list;
|
2004-02-20 01:10:28 +00:00
|
|
|
while (children)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
if (widget == BUTTON_DATA (children->data)->button)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2004-03-17 15:29:06 +00:00
|
|
|
gtk_path_bar_remove_1 (container, widget);
|
2004-02-20 01:10:28 +00:00
|
|
|
path_bar->button_list = g_list_remove_link (path_bar->button_list, children);
|
|
|
|
g_list_free (children);
|
2004-03-17 15:29:06 +00:00
|
|
|
return;
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
children = children->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_forall (GtkContainer *container,
|
|
|
|
gboolean include_internals,
|
|
|
|
GtkCallback callback,
|
|
|
|
gpointer callback_data)
|
|
|
|
{
|
|
|
|
GtkPathBar *path_bar;
|
|
|
|
GList *children;
|
|
|
|
|
|
|
|
g_return_if_fail (callback != NULL);
|
|
|
|
path_bar = GTK_PATH_BAR (container);
|
|
|
|
|
|
|
|
children = path_bar->button_list;
|
|
|
|
while (children)
|
|
|
|
{
|
|
|
|
GtkWidget *child;
|
2004-03-09 21:29:59 +00:00
|
|
|
child = BUTTON_DATA (children->data)->button;
|
2004-02-20 01:10:28 +00:00
|
|
|
children = children->next;
|
|
|
|
|
|
|
|
(* callback) (child, callback_data);
|
|
|
|
}
|
|
|
|
|
2004-03-17 15:29:06 +00:00
|
|
|
if (path_bar->up_slider_button)
|
|
|
|
(* callback) (path_bar->up_slider_button, callback_data);
|
|
|
|
|
|
|
|
if (path_bar->down_slider_button)
|
|
|
|
(* callback) (path_bar->down_slider_button, callback_data);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
2011-09-05 16:12:13 +00:00
|
|
|
static GtkWidgetPath *
|
|
|
|
gtk_path_bar_get_path_for_child (GtkContainer *container,
|
|
|
|
GtkWidget *child)
|
|
|
|
{
|
|
|
|
GtkPathBar *path_bar = GTK_PATH_BAR (container);
|
|
|
|
GtkWidgetPath *path;
|
|
|
|
|
|
|
|
path = gtk_widget_path_copy (gtk_widget_get_path (GTK_WIDGET (path_bar)));
|
|
|
|
|
|
|
|
if (gtk_widget_get_visible (child) &&
|
|
|
|
gtk_widget_get_child_visible (child))
|
|
|
|
{
|
|
|
|
GtkWidgetPath *sibling_path;
|
|
|
|
GList *visible_children;
|
|
|
|
GList *l;
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
/* 1. Build the list of visible children, in visually left-to-right order
|
|
|
|
* (i.e. independently of the widget's direction). Note that our
|
|
|
|
* button_list is stored in innermost-to-outermost path order!
|
|
|
|
*/
|
|
|
|
|
|
|
|
visible_children = NULL;
|
|
|
|
|
|
|
|
if (gtk_widget_get_visible (path_bar->down_slider_button) &&
|
|
|
|
gtk_widget_get_child_visible (path_bar->down_slider_button))
|
|
|
|
visible_children = g_list_prepend (visible_children, path_bar->down_slider_button);
|
|
|
|
|
|
|
|
for (l = path_bar->button_list; l; l = l->next)
|
|
|
|
{
|
|
|
|
ButtonData *data = l->data;
|
|
|
|
|
|
|
|
if (gtk_widget_get_visible (data->button) &&
|
|
|
|
gtk_widget_get_child_visible (data->button))
|
|
|
|
visible_children = g_list_prepend (visible_children, data->button);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gtk_widget_get_visible (path_bar->up_slider_button) &&
|
|
|
|
gtk_widget_get_child_visible (path_bar->up_slider_button))
|
|
|
|
visible_children = g_list_prepend (visible_children, path_bar->up_slider_button);
|
|
|
|
|
|
|
|
if (gtk_widget_get_direction (GTK_WIDGET (path_bar)) == GTK_TEXT_DIR_RTL)
|
|
|
|
visible_children = g_list_reverse (visible_children);
|
|
|
|
|
|
|
|
/* 2. Find the index of the child within that list */
|
|
|
|
|
|
|
|
pos = 0;
|
|
|
|
|
|
|
|
for (l = visible_children; l; l = l->next)
|
|
|
|
{
|
|
|
|
GtkWidget *button = l->data;
|
|
|
|
|
|
|
|
if (button == child)
|
|
|
|
break;
|
|
|
|
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 3. Build the path */
|
|
|
|
|
|
|
|
sibling_path = gtk_widget_path_new ();
|
|
|
|
|
|
|
|
for (l = visible_children; l; l = l->next)
|
|
|
|
gtk_widget_path_append_for_widget (sibling_path, l->data);
|
|
|
|
|
|
|
|
gtk_widget_path_append_with_siblings (path, sibling_path, pos);
|
|
|
|
|
|
|
|
g_list_free (visible_children);
|
|
|
|
gtk_widget_path_unref (sibling_path);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
gtk_widget_path_append_for_widget (path, child);
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2004-02-20 23:21:01 +00:00
|
|
|
static void
|
2008-03-03 21:15:21 +00:00
|
|
|
gtk_path_bar_scroll_down (GtkPathBar *path_bar)
|
2004-02-20 23:21:01 +00:00
|
|
|
{
|
2010-08-11 21:05:51 +00:00
|
|
|
GtkAllocation allocation, button_allocation;
|
2004-02-20 23:21:01 +00:00
|
|
|
GList *list;
|
2004-02-23 07:11:31 +00:00
|
|
|
GList *down_button = NULL;
|
2004-02-20 23:21:01 +00:00
|
|
|
gint space_available;
|
2004-09-26 05:47:11 +00:00
|
|
|
|
|
|
|
if (path_bar->ignore_click)
|
|
|
|
{
|
|
|
|
path_bar->ignore_click = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-03-03 21:15:21 +00:00
|
|
|
if (gtk_widget_get_child_visible (BUTTON_DATA (path_bar->button_list->data)->button))
|
|
|
|
{
|
|
|
|
/* Return if the last button is already visible */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-03-15 18:12:51 +00:00
|
|
|
gtk_widget_queue_resize (GTK_WIDGET (path_bar));
|
|
|
|
|
2004-02-20 23:21:01 +00:00
|
|
|
/* We find the button at the 'down' end that we have to make
|
|
|
|
* visible */
|
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
if (list->next && gtk_widget_get_child_visible (BUTTON_DATA (list->next->data)->button))
|
2004-02-20 23:21:01 +00:00
|
|
|
{
|
|
|
|
down_button = list;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-11 21:05:51 +00:00
|
|
|
gtk_widget_get_allocation (GTK_WIDGET (path_bar), &allocation);
|
|
|
|
gtk_widget_get_allocation (BUTTON_DATA (down_button->data)->button, &button_allocation);
|
|
|
|
|
|
|
|
space_available = (allocation.width
|
2009-06-05 19:07:10 +00:00
|
|
|
- 2 * path_bar->spacing - 2 * path_bar->slider_width
|
2010-08-11 21:05:51 +00:00
|
|
|
- button_allocation.width);
|
2009-06-05 19:07:10 +00:00
|
|
|
path_bar->first_scrolled_button = down_button;
|
|
|
|
|
|
|
|
/* We have space_available free space that's not being used.
|
|
|
|
* So we walk down from the end, adding buttons until we use all free space.
|
2007-06-04 18:17:14 +00:00
|
|
|
*/
|
2009-06-05 19:07:10 +00:00
|
|
|
while (space_available > 0)
|
2004-02-20 23:21:01 +00:00
|
|
|
{
|
2009-06-05 19:07:10 +00:00
|
|
|
path_bar->first_scrolled_button = down_button;
|
|
|
|
down_button = down_button->next;
|
|
|
|
if (!down_button)
|
|
|
|
break;
|
2010-08-11 21:05:51 +00:00
|
|
|
space_available -= (button_allocation.width
|
2009-06-05 19:07:10 +00:00
|
|
|
+ path_bar->spacing);
|
2004-02-20 23:21:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-03-03 21:15:21 +00:00
|
|
|
gtk_path_bar_scroll_up (GtkPathBar *path_bar)
|
2004-02-20 23:21:01 +00:00
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
|
2004-09-26 05:47:11 +00:00
|
|
|
if (path_bar->ignore_click)
|
|
|
|
{
|
|
|
|
path_bar->ignore_click = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-03-03 21:15:21 +00:00
|
|
|
list = g_list_last (path_bar->button_list);
|
|
|
|
|
|
|
|
if (gtk_widget_get_child_visible (BUTTON_DATA (list->data)->button))
|
|
|
|
{
|
|
|
|
/* Return if the first button is already visible */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-03-15 18:12:51 +00:00
|
|
|
gtk_widget_queue_resize (GTK_WIDGET (path_bar));
|
|
|
|
|
2008-03-03 21:15:21 +00:00
|
|
|
for ( ; list; list = list->prev)
|
2004-02-20 23:21:01 +00:00
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
if (list->prev && gtk_widget_get_child_visible (BUTTON_DATA (list->prev->data)->button))
|
2004-02-20 23:21:01 +00:00
|
|
|
{
|
2005-06-13 19:18:54 +00:00
|
|
|
if (list->prev == path_bar->fake_root)
|
|
|
|
path_bar->fake_root = NULL;
|
2004-02-20 23:21:01 +00:00
|
|
|
path_bar->first_scrolled_button = list;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-26 05:47:11 +00:00
|
|
|
static gboolean
|
|
|
|
gtk_path_bar_scroll_timeout (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
if (path_bar->timer)
|
|
|
|
{
|
2005-11-07 20:10:04 +00:00
|
|
|
if (path_bar->scrolling_up)
|
2008-03-03 21:15:21 +00:00
|
|
|
gtk_path_bar_scroll_up (path_bar);
|
2005-11-19 03:46:04 +00:00
|
|
|
else if (path_bar->scrolling_down)
|
2008-03-03 21:15:21 +00:00
|
|
|
gtk_path_bar_scroll_down (path_bar);
|
2004-09-26 05:47:11 +00:00
|
|
|
|
|
|
|
if (path_bar->need_timer)
|
|
|
|
{
|
2005-11-22 12:40:15 +00:00
|
|
|
GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (path_bar));
|
|
|
|
guint timeout;
|
|
|
|
|
|
|
|
g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
|
|
|
|
|
2004-09-26 05:47:11 +00:00
|
|
|
path_bar->need_timer = FALSE;
|
|
|
|
|
2006-12-22 19:10:43 +00:00
|
|
|
path_bar->timer = gdk_threads_add_timeout (timeout * SCROLL_DELAY_FACTOR,
|
2004-09-26 05:47:11 +00:00
|
|
|
(GSourceFunc)gtk_path_bar_scroll_timeout,
|
|
|
|
path_bar);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
retval = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_stop_scrolling (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
if (path_bar->timer)
|
|
|
|
{
|
|
|
|
g_source_remove (path_bar->timer);
|
|
|
|
path_bar->timer = 0;
|
|
|
|
path_bar->need_timer = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-16 17:42:53 +00:00
|
|
|
static gboolean
|
|
|
|
gtk_path_bar_slider_up_defocus (GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
GList *up_button = NULL;
|
|
|
|
|
|
|
|
if (event->type != GDK_FOCUS_CHANGE)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (list = g_list_last (path_bar->button_list); list; list = list->prev)
|
|
|
|
{
|
|
|
|
if (gtk_widget_get_child_visible (BUTTON_DATA (list->data)->button))
|
|
|
|
{
|
|
|
|
up_button = list;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* don't let the focus vanish */
|
2010-02-27 04:24:24 +00:00
|
|
|
if ((!gtk_widget_is_sensitive (path_bar->up_slider_button)) ||
|
2007-05-16 17:42:53 +00:00
|
|
|
(!gtk_widget_get_child_visible (path_bar->up_slider_button)))
|
|
|
|
gtk_widget_grab_focus (BUTTON_DATA (up_button->data)->button);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gtk_path_bar_slider_down_defocus (GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
GList *down_button = NULL;
|
|
|
|
|
|
|
|
if (event->type != GDK_FOCUS_CHANGE)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
|
|
|
{
|
|
|
|
if (gtk_widget_get_child_visible (BUTTON_DATA (list->data)->button))
|
|
|
|
{
|
|
|
|
down_button = list;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* don't let the focus vanish */
|
2010-02-27 04:24:24 +00:00
|
|
|
if ((!gtk_widget_is_sensitive (path_bar->down_slider_button)) ||
|
2007-05-16 17:42:53 +00:00
|
|
|
(!gtk_widget_get_child_visible (path_bar->down_slider_button)))
|
|
|
|
gtk_widget_grab_focus (BUTTON_DATA (down_button->data)->button);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-09-26 05:47:11 +00:00
|
|
|
static gboolean
|
|
|
|
gtk_path_bar_slider_button_press (GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar)
|
|
|
|
{
|
2012-01-25 17:44:55 +00:00
|
|
|
if (event->type != GDK_BUTTON_PRESS || event->button != GDK_BUTTON_PRIMARY)
|
2004-09-26 05:47:11 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
path_bar->ignore_click = FALSE;
|
|
|
|
|
|
|
|
if (widget == path_bar->up_slider_button)
|
2005-11-07 20:10:04 +00:00
|
|
|
{
|
2005-11-19 03:46:04 +00:00
|
|
|
path_bar->scrolling_down = FALSE;
|
2005-11-07 20:10:04 +00:00
|
|
|
path_bar->scrolling_up = TRUE;
|
2008-03-03 21:15:21 +00:00
|
|
|
gtk_path_bar_scroll_up (path_bar);
|
2005-11-07 20:10:04 +00:00
|
|
|
}
|
2004-09-26 05:47:11 +00:00
|
|
|
else if (widget == path_bar->down_slider_button)
|
2005-11-07 20:10:04 +00:00
|
|
|
{
|
|
|
|
path_bar->scrolling_up = FALSE;
|
2005-11-19 03:46:04 +00:00
|
|
|
path_bar->scrolling_down = TRUE;
|
2008-03-03 21:15:21 +00:00
|
|
|
gtk_path_bar_scroll_down (path_bar);
|
2005-11-07 20:10:04 +00:00
|
|
|
}
|
2004-09-26 05:47:11 +00:00
|
|
|
|
|
|
|
if (!path_bar->timer)
|
|
|
|
{
|
2005-11-22 12:40:15 +00:00
|
|
|
GtkSettings *settings = gtk_widget_get_settings (widget);
|
|
|
|
guint timeout;
|
|
|
|
|
|
|
|
g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
|
|
|
|
|
2004-09-26 05:47:11 +00:00
|
|
|
path_bar->need_timer = TRUE;
|
2006-12-22 19:10:43 +00:00
|
|
|
path_bar->timer = gdk_threads_add_timeout (timeout,
|
2004-09-26 05:47:11 +00:00
|
|
|
(GSourceFunc)gtk_path_bar_scroll_timeout,
|
|
|
|
path_bar);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gtk_path_bar_slider_button_release (GtkWidget *widget,
|
|
|
|
GdkEventButton *event,
|
|
|
|
GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
if (event->type != GDK_BUTTON_RELEASE)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
path_bar->ignore_click = TRUE;
|
|
|
|
gtk_path_bar_stop_scrolling (path_bar);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_grab_notify (GtkWidget *widget,
|
|
|
|
gboolean was_grabbed)
|
|
|
|
{
|
|
|
|
if (!was_grabbed)
|
|
|
|
gtk_path_bar_stop_scrolling (GTK_PATH_BAR (widget));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_state_changed (GtkWidget *widget,
|
|
|
|
GtkStateType previous_state)
|
|
|
|
{
|
2010-02-27 04:24:24 +00:00
|
|
|
if (!gtk_widget_is_sensitive (widget))
|
2004-09-26 05:47:11 +00:00
|
|
|
gtk_path_bar_stop_scrolling (GTK_PATH_BAR (widget));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
/* Changes the icons wherever it is needed */
|
|
|
|
static void
|
|
|
|
reload_icons (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
|
|
|
|
if (path_bar->root_icon)
|
|
|
|
{
|
|
|
|
g_object_unref (path_bar->root_icon);
|
|
|
|
path_bar->root_icon = NULL;
|
|
|
|
}
|
|
|
|
if (path_bar->home_icon)
|
|
|
|
{
|
|
|
|
g_object_unref (path_bar->home_icon);
|
|
|
|
path_bar->home_icon = NULL;
|
|
|
|
}
|
|
|
|
if (path_bar->desktop_icon)
|
|
|
|
{
|
|
|
|
g_object_unref (path_bar->desktop_icon);
|
|
|
|
path_bar->desktop_icon = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
|
|
|
{
|
|
|
|
ButtonData *button_data;
|
|
|
|
gboolean current_dir;
|
|
|
|
|
|
|
|
button_data = BUTTON_DATA (list->data);
|
|
|
|
if (button_data->type != NORMAL_BUTTON)
|
|
|
|
{
|
|
|
|
current_dir = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_data->button));
|
|
|
|
gtk_path_bar_update_button_appearance (path_bar, button_data, current_dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
change_icon_theme (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GtkSettings *settings;
|
|
|
|
gint width, height;
|
|
|
|
|
|
|
|
settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (path_bar)));
|
|
|
|
|
2005-02-11 17:30:33 +00:00
|
|
|
if (gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &width, &height))
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
path_bar->icon_size = MAX (width, height);
|
|
|
|
else
|
|
|
|
path_bar->icon_size = FALLBACK_ICON_SIZE;
|
|
|
|
|
|
|
|
reload_icons (path_bar);
|
|
|
|
}
|
|
|
|
/* Callback used when a GtkSettings value changes */
|
|
|
|
static void
|
|
|
|
settings_notify_cb (GObject *object,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
name = g_param_spec_get_name (pspec);
|
|
|
|
|
|
|
|
if (! strcmp (name, "gtk-icon-theme-name") ||
|
|
|
|
! strcmp (name, "gtk-icon-sizes"))
|
|
|
|
change_icon_theme (path_bar);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gtk_path_bar_check_icon_theme (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GtkSettings *settings;
|
|
|
|
|
|
|
|
if (path_bar->settings_signal_id)
|
|
|
|
return;
|
|
|
|
|
|
|
|
settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (path_bar)));
|
|
|
|
path_bar->settings_signal_id = g_signal_connect (settings, "notify", G_CALLBACK (settings_notify_cb), path_bar);
|
|
|
|
|
|
|
|
change_icon_theme (path_bar);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Public functions and their helpers */
|
2004-02-20 01:10:28 +00:00
|
|
|
static void
|
|
|
|
gtk_path_bar_clear_buttons (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
while (path_bar->button_list != NULL)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
gtk_container_remove (GTK_CONTAINER (path_bar), BUTTON_DATA (path_bar->button_list->data)->button);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
2004-02-23 07:11:31 +00:00
|
|
|
path_bar->first_scrolled_button = NULL;
|
2005-06-13 19:18:54 +00:00
|
|
|
path_bar->fake_root = NULL;
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
2004-02-23 07:11:31 +00:00
|
|
|
static void
|
|
|
|
button_clicked_cb (GtkWidget *button,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
ButtonData *button_data;
|
2004-04-02 00:35:07 +00:00
|
|
|
GtkPathBar *path_bar;
|
|
|
|
GList *button_list;
|
|
|
|
gboolean child_is_hidden;
|
2008-06-10 00:39:35 +00:00
|
|
|
GFile *child_file;
|
2004-03-09 21:29:59 +00:00
|
|
|
|
|
|
|
button_data = BUTTON_DATA (data);
|
|
|
|
if (button_data->ignore_changes)
|
|
|
|
return;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2010-08-11 21:05:51 +00:00
|
|
|
path_bar = GTK_PATH_BAR (gtk_widget_get_parent (button));
|
2004-04-02 00:35:07 +00:00
|
|
|
|
|
|
|
button_list = g_list_find (path_bar->button_list, button_data);
|
|
|
|
g_assert (button_list != NULL);
|
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
g_signal_handlers_block_by_func (button,
|
|
|
|
G_CALLBACK (button_clicked_cb), data);
|
2004-03-04 06:47:54 +00:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
|
2006-05-01 21:41:12 +00:00
|
|
|
g_signal_handlers_unblock_by_func (button,
|
|
|
|
G_CALLBACK (button_clicked_cb), data);
|
2004-03-04 06:47:54 +00:00
|
|
|
|
2004-04-02 00:35:07 +00:00
|
|
|
if (button_list->prev)
|
|
|
|
{
|
|
|
|
ButtonData *child_data;
|
|
|
|
|
|
|
|
child_data = BUTTON_DATA (button_list->prev->data);
|
2008-06-10 00:39:35 +00:00
|
|
|
child_file = child_data->file;
|
2004-04-02 00:35:07 +00:00
|
|
|
child_is_hidden = child_data->file_is_hidden;
|
|
|
|
}
|
|
|
|
else
|
2005-11-10 15:17:40 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
child_file = NULL;
|
2005-11-10 15:17:40 +00:00
|
|
|
child_is_hidden = FALSE;
|
|
|
|
}
|
2004-04-02 00:35:07 +00:00
|
|
|
|
2005-11-10 15:17:40 +00:00
|
|
|
g_signal_emit (path_bar, path_bar_signals [PATH_CLICKED], 0,
|
2008-06-10 00:39:35 +00:00
|
|
|
button_data->file, child_file, child_is_hidden);
|
2004-02-23 07:11:31 +00:00
|
|
|
}
|
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
struct SetButtonImageData
|
|
|
|
{
|
|
|
|
GtkPathBar *path_bar;
|
|
|
|
ButtonData *button_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2008-06-10 00:39:35 +00:00
|
|
|
set_button_image_get_info_cb (GCancellable *cancellable,
|
|
|
|
GFileInfo *info,
|
|
|
|
const GError *error,
|
|
|
|
gpointer user_data)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
2006-05-01 21:41:12 +00:00
|
|
|
GdkPixbuf *pixbuf;
|
|
|
|
struct SetButtonImageData *data = user_data;
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (cancellable != data->button_data->cancellable)
|
2006-05-01 21:41:12 +00:00
|
|
|
goto out;
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
data->button_data->cancellable = NULL;
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2006-09-04 19:32:13 +00:00
|
|
|
if (!data->button_data->button)
|
|
|
|
{
|
|
|
|
g_free (data->button_data);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
if (cancelled || error)
|
|
|
|
goto out;
|
|
|
|
|
2008-06-13 16:47:41 +00:00
|
|
|
pixbuf = _gtk_file_info_render_icon (info, GTK_WIDGET (data->path_bar),
|
|
|
|
data->path_bar->icon_size);
|
2006-05-01 21:41:12 +00:00
|
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (data->button_data->image), pixbuf);
|
|
|
|
|
|
|
|
switch (data->button_data->type)
|
|
|
|
{
|
|
|
|
case HOME_BUTTON:
|
|
|
|
if (data->path_bar->home_icon)
|
|
|
|
g_object_unref (pixbuf);
|
|
|
|
else
|
|
|
|
data->path_bar->home_icon = pixbuf;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DESKTOP_BUTTON:
|
|
|
|
if (data->path_bar->desktop_icon)
|
|
|
|
g_object_unref (pixbuf);
|
|
|
|
else
|
|
|
|
data->path_bar->desktop_icon = pixbuf;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
out:
|
|
|
|
g_free (data);
|
2008-06-10 00:39:35 +00:00
|
|
|
g_object_unref (cancellable);
|
2006-05-01 21:41:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_button_image (GtkPathBar *path_bar,
|
|
|
|
ButtonData *button_data)
|
2004-03-08 09:56:34 +00:00
|
|
|
{
|
2004-03-10 06:20:48 +00:00
|
|
|
GtkFileSystemVolume *volume;
|
2006-05-01 21:41:12 +00:00
|
|
|
struct SetButtonImageData *data;
|
2004-03-10 06:20:48 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
switch (button_data->type)
|
2004-03-08 09:56:34 +00:00
|
|
|
{
|
2004-03-10 06:20:48 +00:00
|
|
|
case ROOT_BUTTON:
|
2004-03-08 09:56:34 +00:00
|
|
|
|
|
|
|
if (path_bar->root_icon != NULL)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
|
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
|
|
|
break;
|
|
|
|
}
|
2008-06-10 00:39:35 +00:00
|
|
|
|
2008-06-13 16:47:41 +00:00
|
|
|
volume = _gtk_file_system_get_volume_for_file (path_bar->file_system, path_bar->root_file);
|
2004-03-08 09:56:34 +00:00
|
|
|
if (volume == NULL)
|
2006-05-01 21:41:12 +00:00
|
|
|
return;
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2008-06-13 16:47:41 +00:00
|
|
|
path_bar->root_icon = _gtk_file_system_volume_render_icon (volume,
|
|
|
|
GTK_WIDGET (path_bar),
|
|
|
|
path_bar->icon_size,
|
|
|
|
NULL);
|
2010-03-09 04:56:43 +00:00
|
|
|
_gtk_file_system_volume_unref (volume);
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
|
|
|
break;
|
|
|
|
|
2004-03-10 06:20:48 +00:00
|
|
|
case HOME_BUTTON:
|
2004-03-08 09:56:34 +00:00
|
|
|
if (path_bar->home_icon != NULL)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
|
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->home_icon);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = g_new0 (struct SetButtonImageData, 1);
|
|
|
|
data->path_bar = path_bar;
|
|
|
|
data->button_data = button_data;
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (button_data->cancellable)
|
|
|
|
g_cancellable_cancel (button_data->cancellable);
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
button_data->cancellable =
|
2008-06-13 16:47:41 +00:00
|
|
|
_gtk_file_system_get_info (path_bar->file_system,
|
|
|
|
path_bar->home_file,
|
|
|
|
"standard::icon",
|
|
|
|
set_button_image_get_info_cb,
|
|
|
|
data);
|
2006-05-01 21:41:12 +00:00
|
|
|
break;
|
|
|
|
|
2004-03-10 06:20:48 +00:00
|
|
|
case DESKTOP_BUTTON:
|
|
|
|
if (path_bar->desktop_icon != NULL)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
|
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), path_bar->desktop_icon);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
data = g_new0 (struct SetButtonImageData, 1);
|
|
|
|
data->path_bar = path_bar;
|
|
|
|
data->button_data = button_data;
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (button_data->cancellable)
|
|
|
|
g_cancellable_cancel (button_data->cancellable);
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
button_data->cancellable =
|
2008-06-13 16:47:41 +00:00
|
|
|
_gtk_file_system_get_info (path_bar->file_system,
|
|
|
|
path_bar->desktop_file,
|
|
|
|
"standard::icon",
|
|
|
|
set_button_image_get_info_cb,
|
|
|
|
data);
|
2006-05-01 21:41:12 +00:00
|
|
|
break;
|
2004-03-10 06:20:48 +00:00
|
|
|
default:
|
2006-05-01 21:41:12 +00:00
|
|
|
break;
|
2004-03-08 09:56:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
static void
|
|
|
|
button_data_free (ButtonData *button_data)
|
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
if (button_data->file)
|
|
|
|
g_object_unref (button_data->file);
|
|
|
|
button_data->file = NULL;
|
2006-09-04 19:32:13 +00:00
|
|
|
|
2007-03-09 21:57:37 +00:00
|
|
|
g_free (button_data->dir_name);
|
2006-09-04 19:32:13 +00:00
|
|
|
button_data->dir_name = NULL;
|
|
|
|
|
|
|
|
button_data->button = NULL;
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (button_data->cancellable)
|
|
|
|
g_cancellable_cancel (button_data->cancellable);
|
2006-09-04 19:32:13 +00:00
|
|
|
else
|
|
|
|
g_free (button_data);
|
2004-03-09 21:29:59 +00:00
|
|
|
}
|
|
|
|
|
2004-04-13 20:56:50 +00:00
|
|
|
static const char *
|
|
|
|
get_dir_name (ButtonData *button_data)
|
|
|
|
{
|
2005-10-04 20:08:32 +00:00
|
|
|
return button_data->dir_name;
|
2004-04-13 20:56:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* We always want to request the same size for the label, whether
|
|
|
|
* or not the contents are bold
|
|
|
|
*/
|
|
|
|
static void
|
2011-06-07 16:59:11 +00:00
|
|
|
set_label_size_request (GtkWidget *widget,
|
2010-10-28 06:17:06 +00:00
|
|
|
ButtonData *button_data)
|
2004-04-13 20:56:50 +00:00
|
|
|
{
|
|
|
|
const gchar *dir_name = get_dir_name (button_data);
|
|
|
|
PangoLayout *layout = gtk_widget_create_pango_layout (button_data->label, dir_name);
|
2010-10-28 06:17:06 +00:00
|
|
|
gint width, height, bold_width, bold_height;
|
2004-04-13 20:56:50 +00:00
|
|
|
gchar *markup;
|
2010-10-28 06:17:06 +00:00
|
|
|
|
|
|
|
pango_layout_get_pixel_size (layout, &width, &height);
|
2004-04-13 20:56:50 +00:00
|
|
|
|
|
|
|
markup = g_markup_printf_escaped ("<b>%s</b>", dir_name);
|
|
|
|
pango_layout_set_markup (layout, markup, -1);
|
|
|
|
g_free (markup);
|
|
|
|
|
|
|
|
pango_layout_get_pixel_size (layout, &bold_width, &bold_height);
|
2010-10-28 06:17:06 +00:00
|
|
|
|
2011-06-07 16:59:11 +00:00
|
|
|
gtk_widget_set_size_request (widget,
|
2010-10-28 06:17:06 +00:00
|
|
|
MAX (width, bold_width),
|
|
|
|
MAX (height, bold_height));
|
2004-04-13 20:56:50 +00:00
|
|
|
g_object_unref (layout);
|
|
|
|
}
|
|
|
|
|
2004-03-04 06:47:54 +00:00
|
|
|
static void
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
gtk_path_bar_update_button_appearance (GtkPathBar *path_bar,
|
|
|
|
ButtonData *button_data,
|
|
|
|
gboolean current_dir)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2004-04-13 20:56:50 +00:00
|
|
|
const gchar *dir_name = get_dir_name (button_data);
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
if (button_data->label != NULL)
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2004-03-08 09:56:34 +00:00
|
|
|
if (current_dir)
|
|
|
|
{
|
|
|
|
char *markup;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2004-03-08 09:56:34 +00:00
|
|
|
markup = g_markup_printf_escaped ("<b>%s</b>", dir_name);
|
2004-03-09 21:29:59 +00:00
|
|
|
gtk_label_set_markup (GTK_LABEL (button_data->label), markup);
|
2004-03-08 09:56:34 +00:00
|
|
|
g_free (markup);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
gtk_label_set_text (GTK_LABEL (button_data->label), dir_name);
|
2004-03-08 09:56:34 +00:00
|
|
|
}
|
2004-02-23 07:11:31 +00:00
|
|
|
}
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
if (button_data->image != NULL)
|
2004-02-23 07:11:31 +00:00
|
|
|
{
|
2006-05-01 21:41:12 +00:00
|
|
|
set_button_image (path_bar, button_data);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_data->button)) != current_dir)
|
2004-03-04 06:47:54 +00:00
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data->ignore_changes = TRUE;
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_data->button), current_dir);
|
|
|
|
button_data->ignore_changes = FALSE;
|
2004-03-04 06:47:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-10 06:20:48 +00:00
|
|
|
static ButtonType
|
|
|
|
find_button_type (GtkPathBar *path_bar,
|
2008-06-10 00:39:35 +00:00
|
|
|
GFile *file)
|
2004-03-10 06:20:48 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
if (path_bar->root_file != NULL &&
|
|
|
|
g_file_equal (file, path_bar->root_file))
|
2004-03-10 06:20:48 +00:00
|
|
|
return ROOT_BUTTON;
|
2008-06-10 00:39:35 +00:00
|
|
|
if (path_bar->home_file != NULL &&
|
|
|
|
g_file_equal (file, path_bar->home_file))
|
2004-03-10 06:20:48 +00:00
|
|
|
return HOME_BUTTON;
|
2008-06-10 00:39:35 +00:00
|
|
|
if (path_bar->desktop_file != NULL &&
|
|
|
|
g_file_equal (file, path_bar->desktop_file))
|
2004-03-10 06:20:48 +00:00
|
|
|
return DESKTOP_BUTTON;
|
|
|
|
|
|
|
|
return NORMAL_BUTTON;
|
|
|
|
}
|
|
|
|
|
2004-11-20 04:52:57 +00:00
|
|
|
static void
|
2011-01-24 02:50:39 +00:00
|
|
|
button_drag_data_get_cb (GtkWidget *widget,
|
|
|
|
GdkDragContext *context,
|
|
|
|
GtkSelectionData *selection_data,
|
|
|
|
guint info,
|
|
|
|
guint time_,
|
|
|
|
gpointer data)
|
2004-11-20 04:52:57 +00:00
|
|
|
{
|
|
|
|
ButtonData *button_data;
|
2008-02-12 15:07:38 +00:00
|
|
|
char *uris[2];
|
2004-11-20 04:52:57 +00:00
|
|
|
|
|
|
|
button_data = data;
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
uris[0] = g_file_get_uri (button_data->file);
|
2008-02-12 15:07:38 +00:00
|
|
|
uris[1] = NULL;
|
2004-11-20 04:52:57 +00:00
|
|
|
|
2008-02-12 15:07:38 +00:00
|
|
|
gtk_selection_data_set_uris (selection_data, uris);
|
2011-01-24 02:50:39 +00:00
|
|
|
|
2008-02-12 15:07:38 +00:00
|
|
|
g_free (uris[0]);
|
2004-11-20 04:52:57 +00:00
|
|
|
}
|
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
static ButtonData *
|
2004-03-08 09:56:34 +00:00
|
|
|
make_directory_button (GtkPathBar *path_bar,
|
|
|
|
const char *dir_name,
|
2008-06-10 00:39:35 +00:00
|
|
|
GFile *file,
|
2004-04-02 00:35:07 +00:00
|
|
|
gboolean current_dir,
|
|
|
|
gboolean file_is_hidden)
|
2004-03-04 06:47:54 +00:00
|
|
|
{
|
2007-05-16 17:42:53 +00:00
|
|
|
AtkObject *atk_obj;
|
2004-03-08 09:56:34 +00:00
|
|
|
GtkWidget *child = NULL;
|
2004-03-09 21:29:59 +00:00
|
|
|
ButtonData *button_data;
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2004-08-25 19:19:43 +00:00
|
|
|
file_is_hidden = !! file_is_hidden;
|
2004-03-08 09:56:34 +00:00
|
|
|
/* Is it a special button? */
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data = g_new0 (ButtonData, 1);
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
button_data->type = find_button_type (path_bar, file);
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data->button = gtk_toggle_button_new ();
|
2007-05-16 17:42:53 +00:00
|
|
|
atk_obj = gtk_widget_get_accessible (button_data->button);
|
2005-11-21 15:00:57 +00:00
|
|
|
gtk_button_set_focus_on_click (GTK_BUTTON (button_data->button), FALSE);
|
2012-03-03 03:53:22 +00:00
|
|
|
gtk_widget_add_events (button_data->button, GDK_SCROLL_MASK);
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
switch (button_data->type)
|
2004-03-08 09:56:34 +00:00
|
|
|
{
|
|
|
|
case ROOT_BUTTON:
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data->image = gtk_image_new ();
|
|
|
|
child = button_data->image;
|
2007-07-20 11:10:07 +00:00
|
|
|
button_data->label = NULL;
|
2007-05-16 17:42:53 +00:00
|
|
|
atk_object_set_name (atk_obj, _("File System Root"));
|
2004-03-08 09:56:34 +00:00
|
|
|
break;
|
|
|
|
case HOME_BUTTON:
|
2004-03-10 06:20:48 +00:00
|
|
|
case DESKTOP_BUTTON:
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data->image = gtk_image_new ();
|
|
|
|
button_data->label = gtk_label_new (NULL);
|
2010-10-31 17:07:20 +00:00
|
|
|
child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
|
2004-03-09 21:29:59 +00:00
|
|
|
gtk_box_pack_start (GTK_BOX (child), button_data->image, FALSE, FALSE, 0);
|
2011-06-07 16:59:11 +00:00
|
|
|
gtk_box_pack_start (GTK_BOX (child), button_data->label, FALSE, FALSE, 0);
|
2004-03-08 09:56:34 +00:00
|
|
|
break;
|
|
|
|
case NORMAL_BUTTON:
|
2004-03-10 06:20:48 +00:00
|
|
|
default:
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data->label = gtk_label_new (NULL);
|
2009-06-05 19:07:10 +00:00
|
|
|
gtk_label_set_ellipsize (GTK_LABEL (button_data->label), PANGO_ELLIPSIZE_END);
|
2011-06-07 16:59:11 +00:00
|
|
|
child = button_data->label;
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data->image = NULL;
|
2004-03-08 09:56:34 +00:00
|
|
|
}
|
2004-03-04 06:47:54 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data->dir_name = g_strdup (dir_name);
|
2008-06-10 00:39:35 +00:00
|
|
|
button_data->file = g_object_ref (file);
|
2004-04-02 00:35:07 +00:00
|
|
|
button_data->file_is_hidden = file_is_hidden;
|
2008-06-10 00:39:35 +00:00
|
|
|
|
2011-06-07 16:59:11 +00:00
|
|
|
/*
|
2010-10-28 06:17:06 +00:00
|
|
|
* The following function ensures that the alignment will always
|
|
|
|
* request the same size whether the button's text is bold or not.
|
|
|
|
*/
|
2011-06-07 16:59:11 +00:00
|
|
|
if (button_data->label)
|
|
|
|
set_label_size_request (button_data->label, button_data);
|
2010-10-28 06:17:06 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
gtk_container_add (GTK_CONTAINER (button_data->button), child);
|
|
|
|
gtk_widget_show_all (button_data->button);
|
2004-02-20 01:10:28 +00:00
|
|
|
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
gtk_path_bar_update_button_appearance (path_bar, button_data, current_dir);
|
2004-03-04 06:47:54 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
g_signal_connect (button_data->button, "clicked",
|
|
|
|
G_CALLBACK (button_clicked_cb),
|
|
|
|
button_data);
|
2004-03-10 06:20:48 +00:00
|
|
|
g_object_weak_ref (G_OBJECT (button_data->button),
|
|
|
|
(GWeakNotify) button_data_free, button_data);
|
2004-03-09 21:29:59 +00:00
|
|
|
|
2004-11-20 04:52:57 +00:00
|
|
|
gtk_drag_source_set (button_data->button,
|
|
|
|
GDK_BUTTON1_MASK,
|
2008-02-16 02:31:33 +00:00
|
|
|
NULL, 0,
|
2004-11-20 04:52:57 +00:00
|
|
|
GDK_ACTION_COPY);
|
2008-02-16 02:31:33 +00:00
|
|
|
gtk_drag_source_add_uri_targets (button_data->button);
|
2008-08-11 09:17:49 +00:00
|
|
|
g_signal_connect (button_data->button, "drag-data-get",
|
2004-11-20 04:52:57 +00:00
|
|
|
G_CALLBACK (button_drag_data_get_cb), button_data);
|
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
return button_data;
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
2004-03-04 06:47:54 +00:00
|
|
|
static gboolean
|
|
|
|
gtk_path_bar_check_parent_path (GtkPathBar *path_bar,
|
2011-11-28 17:34:37 +00:00
|
|
|
GFile *file)
|
2004-03-04 06:47:54 +00:00
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
GList *current_path = NULL;
|
2005-06-13 19:18:54 +00:00
|
|
|
gboolean need_new_fake_root = FALSE;
|
2004-03-04 06:47:54 +00:00
|
|
|
|
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
|
|
|
{
|
2004-03-09 21:29:59 +00:00
|
|
|
ButtonData *button_data;
|
2004-03-04 06:47:54 +00:00
|
|
|
|
2004-03-09 21:29:59 +00:00
|
|
|
button_data = list->data;
|
2008-06-10 00:39:35 +00:00
|
|
|
if (g_file_equal (file, button_data->file))
|
2004-03-04 06:47:54 +00:00
|
|
|
{
|
|
|
|
current_path = list;
|
|
|
|
break;
|
|
|
|
}
|
2005-06-13 19:18:54 +00:00
|
|
|
if (list == path_bar->fake_root)
|
|
|
|
need_new_fake_root = TRUE;
|
2004-03-04 06:47:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (current_path)
|
|
|
|
{
|
2005-06-13 19:18:54 +00:00
|
|
|
if (need_new_fake_root)
|
|
|
|
{
|
|
|
|
path_bar->fake_root = NULL;
|
|
|
|
for (list = current_path; list; list = list->next)
|
|
|
|
{
|
|
|
|
ButtonData *button_data;
|
|
|
|
|
|
|
|
button_data = list->data;
|
|
|
|
if (BUTTON_IS_FAKE_ROOT (button_data))
|
|
|
|
{
|
|
|
|
path_bar->fake_root = list;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-03-04 06:47:54 +00:00
|
|
|
for (list = path_bar->button_list; list; list = list->next)
|
|
|
|
{
|
Support changes in icon themes.
Wed Mar 10 02:41:05 2004 Jonathan Blandford <jrb@gnome.org>
* gtk/gtkpathbar.c: (gtk_path_bar_init), (gtk_path_bar_class_init),
(remove_settings_signal), (gtk_path_bar_dispose),
(gtk_path_bar_style_set), (gtk_path_bar_screen_changed),
(gtk_path_bar_scroll_up), (reload_icons), (change_icon_theme),
(settings_notify_cb), (gtk_path_bar_check_icon_theme),
(get_button_image), (gtk_path_bar_update_button_appearance),
(make_directory_button), (gtk_path_bar_check_parent_path): Support
changes in icon themes.
* gtk/gtkpathbar.h: add two elements
* tests/testfilechooser.c: (main): use gnome-vfs method again to
get more testing.
2004-03-10 07:42:20 +00:00
|
|
|
gtk_path_bar_update_button_appearance (path_bar,
|
|
|
|
BUTTON_DATA (list->data),
|
|
|
|
(list == current_path) ? TRUE : FALSE);
|
2004-03-04 06:47:54 +00:00
|
|
|
}
|
2004-09-26 05:54:59 +00:00
|
|
|
|
2004-09-26 05:47:11 +00:00
|
|
|
if (!gtk_widget_get_child_visible (BUTTON_DATA (current_path->data)->button))
|
|
|
|
{
|
|
|
|
path_bar->first_scrolled_button = current_path;
|
|
|
|
gtk_widget_queue_resize (GTK_WIDGET (path_bar));
|
|
|
|
}
|
2004-09-26 05:54:59 +00:00
|
|
|
|
2004-03-04 06:47:54 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-02-23 07:11:31 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
struct SetFileInfo
|
2004-02-20 01:10:28 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
GFile *file;
|
|
|
|
GFile *parent_file;
|
2006-05-01 21:41:12 +00:00
|
|
|
GtkPathBar *path_bar;
|
|
|
|
GList *new_buttons;
|
|
|
|
GList *fake_root;
|
|
|
|
gboolean first_directory;
|
|
|
|
};
|
2004-03-08 22:53:35 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
static void
|
2008-06-10 00:39:35 +00:00
|
|
|
gtk_path_bar_set_file_finish (struct SetFileInfo *info,
|
|
|
|
gboolean result)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
GList *l;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
gtk_path_bar_clear_buttons (info->path_bar);
|
|
|
|
info->path_bar->button_list = g_list_reverse (info->new_buttons);
|
|
|
|
info->path_bar->fake_root = info->fake_root;
|
2004-02-25 08:55:48 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
for (l = info->path_bar->button_list; l; l = l->next)
|
2004-02-23 07:11:31 +00:00
|
|
|
{
|
2006-05-01 21:41:12 +00:00
|
|
|
GtkWidget *button = BUTTON_DATA (l->data)->button;
|
|
|
|
gtk_container_add (GTK_CONTAINER (info->path_bar), button);
|
2004-02-23 07:11:31 +00:00
|
|
|
}
|
2011-11-28 17:49:35 +00:00
|
|
|
|
|
|
|
child_ordering_changed (info->path_bar);
|
2006-05-01 21:41:12 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GList *l;
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
for (l = info->new_buttons; l; l = l->next)
|
2004-03-15 05:42:51 +00:00
|
|
|
{
|
2006-05-01 21:41:12 +00:00
|
|
|
ButtonData *button_data;
|
2004-02-23 20:24:01 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
button_data = BUTTON_DATA (l->data);
|
|
|
|
gtk_widget_destroy (button_data->button);
|
2004-03-01 19:48:28 +00:00
|
|
|
}
|
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
g_list_free (info->new_buttons);
|
|
|
|
}
|
2004-02-20 01:10:28 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (info->file)
|
|
|
|
g_object_unref (info->file);
|
|
|
|
if (info->parent_file)
|
|
|
|
g_object_unref (info->parent_file);
|
2011-09-05 16:12:13 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
g_free (info);
|
|
|
|
}
|
2004-02-23 07:11:31 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
static void
|
2008-06-10 00:39:35 +00:00
|
|
|
gtk_path_bar_get_info_callback (GCancellable *cancellable,
|
|
|
|
GFileInfo *info,
|
|
|
|
const GError *error,
|
|
|
|
gpointer data)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
|
|
|
struct SetFileInfo *file_info = data;
|
2006-05-01 21:41:12 +00:00
|
|
|
ButtonData *button_data;
|
|
|
|
const gchar *display_name;
|
|
|
|
gboolean is_hidden;
|
2004-03-08 09:56:34 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (cancellable != file_info->path_bar->get_info_cancellable)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
gtk_path_bar_set_file_finish (file_info, FALSE);
|
|
|
|
g_object_unref (cancellable);
|
2006-05-01 21:41:12 +00:00
|
|
|
return;
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
g_object_unref (cancellable);
|
|
|
|
file_info->path_bar->get_info_cancellable = NULL;
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (cancelled || !info)
|
2004-03-08 16:16:26 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
gtk_path_bar_set_file_finish (file_info, FALSE);
|
2006-05-01 21:41:12 +00:00
|
|
|
return;
|
|
|
|
}
|
2004-03-08 16:16:26 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
display_name = g_file_info_get_display_name (info);
|
2009-06-12 00:58:51 +00:00
|
|
|
is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
|
2004-03-08 16:16:26 +00:00
|
|
|
|
2006-05-01 21:41:12 +00:00
|
|
|
gtk_widget_push_composite_child ();
|
2008-06-10 00:39:35 +00:00
|
|
|
button_data = make_directory_button (file_info->path_bar, display_name,
|
|
|
|
file_info->file,
|
|
|
|
file_info->first_directory, is_hidden);
|
2006-05-01 21:41:12 +00:00
|
|
|
gtk_widget_pop_composite_child ();
|
2008-06-10 00:39:35 +00:00
|
|
|
g_object_unref (file_info->file);
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
file_info->new_buttons = g_list_prepend (file_info->new_buttons, button_data);
|
2006-05-01 21:41:12 +00:00
|
|
|
|
|
|
|
if (BUTTON_IS_FAKE_ROOT (button_data))
|
2008-06-10 00:39:35 +00:00
|
|
|
file_info->fake_root = file_info->new_buttons;
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2011-11-28 18:03:02 +00:00
|
|
|
/* We have assigned the info for the innermost button, i.e. the deepest directory.
|
|
|
|
* Now, go on to fetch the info for this directory's parent.
|
|
|
|
*/
|
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
file_info->file = file_info->parent_file;
|
|
|
|
file_info->first_directory = FALSE;
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (!file_info->file)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
2011-11-28 18:03:02 +00:00
|
|
|
/* No parent? Okay, we are done. */
|
2008-06-10 00:39:35 +00:00
|
|
|
gtk_path_bar_set_file_finish (file_info, TRUE);
|
2006-05-01 21:41:12 +00:00
|
|
|
return;
|
2004-03-08 16:16:26 +00:00
|
|
|
}
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
file_info->parent_file = g_file_get_parent (file_info->file);
|
2004-02-25 08:55:48 +00:00
|
|
|
|
2011-11-28 18:03:02 +00:00
|
|
|
/* Recurse asynchronously */
|
2008-06-10 00:39:35 +00:00
|
|
|
file_info->path_bar->get_info_cancellable =
|
2008-06-13 16:47:41 +00:00
|
|
|
_gtk_file_system_get_info (file_info->path_bar->file_system,
|
|
|
|
file_info->file,
|
2009-06-12 00:58:51 +00:00
|
|
|
"standard::display-name,standard::is-hidden,standard::is-backup",
|
2008-06-13 16:47:41 +00:00
|
|
|
gtk_path_bar_get_info_callback,
|
|
|
|
file_info);
|
2006-05-01 21:41:12 +00:00
|
|
|
}
|
2004-04-06 01:23:26 +00:00
|
|
|
|
2011-11-29 21:07:01 +00:00
|
|
|
void
|
2011-01-24 02:50:39 +00:00
|
|
|
_gtk_path_bar_set_file (GtkPathBar *path_bar,
|
|
|
|
GFile *file,
|
2011-11-29 21:07:01 +00:00
|
|
|
const gboolean keep_trail)
|
2006-05-01 21:41:12 +00:00
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
struct SetFileInfo *info;
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2011-11-29 21:07:01 +00:00
|
|
|
g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
|
|
|
|
g_return_if_fail (G_IS_FILE (file));
|
2006-05-01 21:41:12 +00:00
|
|
|
|
|
|
|
/* Check whether the new path is already present in the pathbar as buttons.
|
|
|
|
* This could be a parent directory or a previous selected subdirectory.
|
|
|
|
*/
|
2011-11-28 17:34:37 +00:00
|
|
|
if (keep_trail && gtk_path_bar_check_parent_path (path_bar, file))
|
2011-11-29 21:07:01 +00:00
|
|
|
return;
|
2004-03-08 16:16:26 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
info = g_new0 (struct SetFileInfo, 1);
|
|
|
|
info->file = g_object_ref (file);
|
2006-05-01 21:41:12 +00:00
|
|
|
info->path_bar = path_bar;
|
|
|
|
info->first_directory = TRUE;
|
2008-06-10 00:39:35 +00:00
|
|
|
info->parent_file = g_file_get_parent (info->file);
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
if (path_bar->get_info_cancellable)
|
|
|
|
g_cancellable_cancel (path_bar->get_info_cancellable);
|
2006-05-01 21:41:12 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
path_bar->get_info_cancellable =
|
2008-06-13 16:47:41 +00:00
|
|
|
_gtk_file_system_get_info (path_bar->file_system,
|
2011-01-24 02:50:39 +00:00
|
|
|
info->file,
|
|
|
|
"standard::display-name,standard::is-hidden,standard::is-backup",
|
|
|
|
gtk_path_bar_get_info_callback,
|
|
|
|
info);
|
2004-02-20 01:10:28 +00:00
|
|
|
}
|
2004-03-04 06:47:54 +00:00
|
|
|
|
2004-03-08 09:56:34 +00:00
|
|
|
/* FIXME: This should be a construct-only property */
|
2004-03-04 06:47:54 +00:00
|
|
|
void
|
2004-03-08 09:56:34 +00:00
|
|
|
_gtk_path_bar_set_file_system (GtkPathBar *path_bar,
|
|
|
|
GtkFileSystem *file_system)
|
2004-03-04 06:47:54 +00:00
|
|
|
{
|
2004-03-08 09:56:34 +00:00
|
|
|
const char *home;
|
2004-03-10 06:20:48 +00:00
|
|
|
|
2004-03-04 06:47:54 +00:00
|
|
|
g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
|
|
|
|
|
2004-03-08 09:56:34 +00:00
|
|
|
g_assert (path_bar->file_system == NULL);
|
2004-03-04 06:47:54 +00:00
|
|
|
|
2004-03-08 09:56:34 +00:00
|
|
|
path_bar->file_system = g_object_ref (file_system);
|
|
|
|
|
|
|
|
home = g_get_home_dir ();
|
2004-08-14 16:47:48 +00:00
|
|
|
if (home != NULL)
|
|
|
|
{
|
2008-01-09 17:02:50 +00:00
|
|
|
const gchar *desktop;
|
2007-06-07 04:23:10 +00:00
|
|
|
|
2008-06-10 00:39:35 +00:00
|
|
|
path_bar->home_file = g_file_new_for_path (home);
|
2004-08-14 16:47:48 +00:00
|
|
|
/* FIXME: Need file system backend specific way of getting the
|
|
|
|
* Desktop path.
|
|
|
|
*/
|
2007-06-07 04:23:10 +00:00
|
|
|
desktop = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
|
|
|
|
if (desktop != NULL)
|
2008-06-10 00:39:35 +00:00
|
|
|
path_bar->desktop_file = g_file_new_for_path (desktop);
|
2007-06-07 04:23:10 +00:00
|
|
|
else
|
2008-06-10 00:39:35 +00:00
|
|
|
path_bar->desktop_file = NULL;
|
2004-08-14 16:47:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-06-10 00:39:35 +00:00
|
|
|
path_bar->home_file = NULL;
|
|
|
|
path_bar->desktop_file = NULL;
|
2004-08-14 16:47:48 +00:00
|
|
|
}
|
2008-06-10 00:39:35 +00:00
|
|
|
path_bar->root_file = g_file_new_for_path ("/");
|
2004-03-04 06:47:54 +00:00
|
|
|
}
|
2004-03-15 02:12:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* _gtk_path_bar_up:
|
|
|
|
* @path_bar: a #GtkPathBar
|
|
|
|
*
|
|
|
|
* If the selected button in the pathbar is not the furthest button "up" (in the
|
|
|
|
* root direction), act as if the user clicked on the next button up.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
_gtk_path_bar_up (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
|
|
|
for (l = path_bar->button_list; l; l = l->next)
|
|
|
|
{
|
|
|
|
GtkWidget *button = BUTTON_DATA (l->data)->button;
|
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
|
|
|
|
{
|
|
|
|
if (l->next)
|
|
|
|
{
|
|
|
|
GtkWidget *next_button = BUTTON_DATA (l->next->data)->button;
|
|
|
|
button_clicked_cb (next_button, l->next->data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* _gtk_path_bar_down:
|
|
|
|
* @path_bar: a #GtkPathBar
|
|
|
|
*
|
|
|
|
* If the selected button in the pathbar is not the furthest button "down" (in the
|
|
|
|
* leaf direction), act as if the user clicked on the next button down.
|
|
|
|
**/
|
|
|
|
void
|
|
|
|
_gtk_path_bar_down (GtkPathBar *path_bar)
|
|
|
|
{
|
|
|
|
GList *l;
|
|
|
|
|
|
|
|
for (l = path_bar->button_list; l; l = l->next)
|
|
|
|
{
|
|
|
|
GtkWidget *button = BUTTON_DATA (l->data)->button;
|
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
|
|
|
|
{
|
|
|
|
if (l->prev)
|
|
|
|
{
|
|
|
|
GtkWidget *prev_button = BUTTON_DATA (l->prev->data)->button;
|
|
|
|
button_clicked_cb (prev_button, l->prev->data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|