/* $Id: thunar-location-buttons.c 23626 2006-11-04 00:29:23Z benny $ */
/*-
* Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*
* Based on code written by Jonathan Blandford <jrb@gnome.org> for
* Red Hat, Inc.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <thunar/thunar-application.h>
#include <thunar/thunar-clipboard-manager.h>
#include <thunar/thunar-create-dialog.h>
#include <thunar/thunar-gobject-extensions.h>
#include <thunar/thunar-gtk-extensions.h>
#include <thunar/thunar-location-button.h>
#include <thunar/thunar-location-buttons.h>
#include <thunar/thunar-location-buttons-ui.h>
#include <thunar/thunar-private.h>
#include <thunar/thunar-properties-dialog.h>
#define THUNAR_LOCATION_BUTTONS_SCROLL_TIMEOUT (200)
/* Property identifiers */
enum
{
PROP_0,
PROP_CURRENT_DIRECTORY,
PROP_SELECTED_FILES,
PROP_UI_MANAGER,
};
static void thunar_location_buttons_class_init (ThunarLocationButtonsClass *klass);
static void thunar_location_buttons_component_init (ThunarComponentIface *iface);
static void thunar_location_buttons_navigator_init (ThunarNavigatorIface *iface);
static void thunar_location_buttons_location_bar_init (ThunarLocationBarIface *iface);
static void thunar_location_buttons_init (ThunarLocationButtons *buttons);
static void thunar_location_buttons_finalize (GObject *object);
static void thunar_location_buttons_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void thunar_location_buttons_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static GtkUIManager *thunar_location_buttons_get_ui_manager (ThunarComponent *component);
static void thunar_location_buttons_set_ui_manager (ThunarComponent *component,
GtkUIManager *ui_manager);
static ThunarFile *thunar_location_buttons_get_current_directory (ThunarNavigator *navigator);
static void thunar_location_buttons_set_current_directory (ThunarNavigator *navigator,
ThunarFile *current_directory);
static void thunar_location_buttons_unmap (GtkWidget *widget);
static void thunar_location_buttons_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void thunar_location_buttons_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void thunar_location_buttons_state_changed (GtkWidget *widget,
GtkStateType previous_state);
static void thunar_location_buttons_grab_notify (GtkWidget *widget,
gboolean was_grabbed);
static void thunar_location_buttons_add (GtkContainer *container,
GtkWidget *widget);
static void thunar_location_buttons_remove (GtkContainer *container,
GtkWidget *widget);
static void thunar_location_buttons_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static GtkWidget *thunar_location_buttons_make_button (ThunarLocationButtons *buttons,
ThunarFile *file);
static void thunar_location_buttons_remove_1 (GtkContainer *container,
GtkWidget *widget);
static gboolean thunar_location_buttons_scroll_timeout (gpointer user_data);
static void thunar_location_buttons_scroll_timeout_destroy (gpointer user_data);
static void thunar_location_buttons_stop_scrolling (ThunarLocationButtons *buttons);
static void thunar_location_buttons_update_sliders (ThunarLocationButtons *buttons);
static gboolean thunar_location_buttons_slider_button_press (GtkWidget *button,
GdkEventButton *event,
ThunarLocationButtons *buttons);
static gboolean thunar_location_buttons_slider_button_release (GtkWidget *button,
GdkEventButton *event,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_scroll_left (GtkWidget *button,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_scroll_right (GtkWidget *button,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_clicked (ThunarLocationButton *button,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_context_menu (ThunarLocationButton *button,
GdkEventButton *event,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_gone (ThunarLocationButton *button,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_action_create_folder (GtkAction *action,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_action_down_folder (GtkAction *action,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_action_empty_trash (GtkAction *action,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_action_open (GtkAction *action,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_action_open_in_new_window (GtkAction *action,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_action_paste_into_folder (GtkAction *action,
ThunarLocationButtons *buttons);
static void thunar_location_buttons_action_properties (GtkAction *action,
ThunarLocationButtons *buttons);
struct _ThunarLocationButtonsClass
{
GtkContainerClass __parent__;
};
struct _ThunarLocationButtons
{
GtkContainer __parent__;
GtkActionGroup *action_group;
GtkUIManager *ui_manager;
guint ui_merge_id;
GtkWidget *left_slider;
GtkWidget *right_slider;
ThunarFile *current_directory;
gint slider_width;
gboolean ignore_click : 1;
GList *list;
GList *fake_root_button;
GList *first_scrolled_button;
guint scroll_timeout_id;
};
static const GtkActionEntry action_entries[] =
{
{ "location-buttons-down-folder", NULL, "Down Folder", "<alt>Down", NULL, G_CALLBACK (thunar_location_buttons_action_down_folder), },
{ "location-buttons-context-menu", NULL, "Context Menu", NULL, NULL, NULL, },
{ "location-buttons-open", GTK_STOCK_OPEN, N_("_Open"), NULL, NULL, G_CALLBACK (thunar_location_buttons_action_open), },
{ "location-buttons-open-in-new-window", NULL, N_("Open in New Window"), NULL, NULL, G_CALLBACK (thunar_location_buttons_action_open_in_new_window), },
{ "location-buttons-create-folder", NULL, N_("Create _Folder..."), NULL, NULL, G_CALLBACK (thunar_location_buttons_action_create_folder), },
{ "location-buttons-empty-trash", NULL, N_("_Empty Trash"), NULL, N_("Delete all files and folders in the Trash"), G_CALLBACK (thunar_location_buttons_action_empty_trash), },
{ "location-buttons-paste-into-folder", GTK_STOCK_PASTE, N_("Paste Into Folder"), NULL, NULL, G_CALLBACK (thunar_location_buttons_action_paste_into_folder), },
{ "location-buttons-properties", GTK_STOCK_PROPERTIES, N_("_Properties..."), NULL, NULL, G_CALLBACK (thunar_location_buttons_action_properties), },
};
static GObjectClass *thunar_location_buttons_parent_class;
GType
thunar_location_buttons_get_type (void)
{
static GType type = G_TYPE_INVALID;
if (G_UNLIKELY (type == G_TYPE_INVALID))
{
static const GTypeInfo info =
{
sizeof (ThunarLocationButtonsClass),
NULL,
NULL,
(GClassInitFunc) thunar_location_buttons_class_init,
NULL,
NULL,
sizeof (ThunarLocationButtons),
0,
(GInstanceInitFunc) thunar_location_buttons_init,
NULL,
};
static const GInterfaceInfo component_info =
{
(GInterfaceInitFunc) thunar_location_buttons_component_init,
NULL,
NULL,
};
static const GInterfaceInfo navigator_info =
{
(GInterfaceInitFunc) thunar_location_buttons_navigator_init,
NULL,
NULL,
};
static const GInterfaceInfo location_bar_info =
{
(GInterfaceInitFunc) thunar_location_buttons_location_bar_init,
NULL,
NULL,
};
type = g_type_register_static (GTK_TYPE_CONTAINER, I_("ThunarLocationButtons"), &info, 0);
g_type_add_interface_static (type, THUNAR_TYPE_NAVIGATOR, &navigator_info);
g_type_add_interface_static (type, THUNAR_TYPE_COMPONENT, &component_info);
g_type_add_interface_static (type, THUNAR_TYPE_LOCATION_BAR, &location_bar_info);
}
return type;
}
static void
thunar_location_buttons_class_init (ThunarLocationButtonsClass *klass)
{
GtkContainerClass *gtkcontainer_class;
GtkWidgetClass *gtkwidget_class;
GObjectClass *gobject_class;
/* determine the parent type class */
thunar_location_buttons_parent_class = g_type_class_peek_parent (klass);
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = thunar_location_buttons_finalize;
gobject_class->get_property = thunar_location_buttons_get_property;
gobject_class->set_property = thunar_location_buttons_set_property;
gtkwidget_class = GTK_WIDGET_CLASS (klass);
gtkwidget_class->unmap = thunar_location_buttons_unmap;
gtkwidget_class->size_request = thunar_location_buttons_size_request;
gtkwidget_class->size_allocate = thunar_location_buttons_size_allocate;
gtkwidget_class->state_changed = thunar_location_buttons_state_changed;
gtkwidget_class->grab_notify = thunar_location_buttons_grab_notify;
gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
gtkcontainer_class->add = thunar_location_buttons_add;
gtkcontainer_class->remove = thunar_location_buttons_remove;
gtkcontainer_class->forall = thunar_location_buttons_forall;
/* Override ThunarNavigator's properties */
g_object_class_override_property (gobject_class, PROP_CURRENT_DIRECTORY, "current-directory");
/* Override ThunarComponent's properties */
g_object_class_override_property (gobject_class, PROP_SELECTED_FILES, "selected-files");
g_object_class_override_property (gobject_class, PROP_UI_MANAGER, "ui-manager");
/**
* ThunarLocationButtons:spacing:
*
* The amount of space between the path buttons.
**/
gtk_widget_class_install_style_property (gtkwidget_class,
g_param_spec_int ("spacing",
_("Spacing"),
_("The amount of space between the path buttons"),
0, G_MAXINT, 3,
G_PARAM_READABLE));
}
static void
thunar_location_buttons_component_init (ThunarComponentIface *iface)
{
iface->get_selected_files = (gpointer) exo_noop_null;
iface->set_selected_files = (gpointer) exo_noop;
iface->get_ui_manager = thunar_location_buttons_get_ui_manager;
iface->set_ui_manager = thunar_location_buttons_set_ui_manager;
}
static void
thunar_location_buttons_navigator_init (ThunarNavigatorIface *iface)
{
iface->get_current_directory = thunar_location_buttons_get_current_directory;
iface->set_current_directory = thunar_location_buttons_set_current_directory;
}
static void
thunar_location_buttons_location_bar_init (ThunarLocationBarIface *iface)
{
iface->accept_focus = (gpointer) exo_noop_false;
iface->is_standalone = (gpointer) exo_noop_true;
}
static void
thunar_location_buttons_init (ThunarLocationButtons *buttons)
{
GtkWidget *arrow;
/* setup the action group for the location buttons */
buttons->action_group = gtk_action_group_new ("ThunarLocationButtons");
gtk_action_group_set_translation_domain (buttons->action_group, GETTEXT_PACKAGE);
gtk_action_group_add_actions (buttons->action_group, action_entries, G_N_ELEMENTS (action_entries), buttons);
GTK_WIDGET_SET_FLAGS (buttons, GTK_NO_WINDOW);
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (buttons), FALSE);
buttons->left_slider = gtk_button_new ();
g_signal_connect (G_OBJECT (buttons->left_slider), "button-press-event", G_CALLBACK (thunar_location_buttons_slider_button_press), buttons);
g_signal_connect (G_OBJECT (buttons->left_slider), "button-release-event", G_CALLBACK (thunar_location_buttons_slider_button_release), buttons);
g_signal_connect (G_OBJECT (buttons->left_slider), "clicked", G_CALLBACK (thunar_location_buttons_scroll_left), buttons);
gtk_container_add (GTK_CONTAINER (buttons), buttons->left_slider);
gtk_widget_show (buttons->left_slider);
arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (buttons->left_slider), arrow);
gtk_widget_show (arrow);
buttons->right_slider = gtk_button_new ();
g_signal_connect (G_OBJECT (buttons->right_slider), "button-press-event", G_CALLBACK (thunar_location_buttons_slider_button_press), buttons);
g_signal_connect (G_OBJECT (buttons->right_slider), "button-release-event", G_CALLBACK (thunar_location_buttons_slider_button_release), buttons);
g_signal_connect (G_OBJECT (buttons->right_slider), "clicked", G_CALLBACK (thunar_location_buttons_scroll_right), buttons);
gtk_container_add (GTK_CONTAINER (buttons), buttons->right_slider);
gtk_widget_show (buttons->right_slider);
arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (buttons->right_slider), arrow);
gtk_widget_show (arrow);
}
static void
thunar_location_buttons_finalize (GObject *object)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (object);
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
/* disconnect from the selected files and the UI manager */
thunar_component_set_selected_files (THUNAR_COMPONENT (buttons), NULL);
thunar_component_set_ui_manager (THUNAR_COMPONENT (buttons), NULL);
/* be sure to cancel the scrolling */
thunar_location_buttons_stop_scrolling (buttons);
/* release from the current_directory */
thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (buttons), NULL);
/* release our action group */
g_object_unref (G_OBJECT (buttons->action_group));
(*G_OBJECT_CLASS (thunar_location_buttons_parent_class)->finalize) (object);
}
static void
thunar_location_buttons_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
case PROP_CURRENT_DIRECTORY:
g_value_set_object (value, thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (object)));
break;
case PROP_SELECTED_FILES:
g_value_set_boxed (value, thunar_component_get_selected_files (THUNAR_COMPONENT (object)));
break;
case PROP_UI_MANAGER:
g_value_set_object (value, thunar_component_get_ui_manager (THUNAR_COMPONENT (object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
thunar_location_buttons_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
switch (prop_id)
{
case PROP_CURRENT_DIRECTORY:
thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (object), g_value_get_object (value));
break;
case PROP_SELECTED_FILES:
thunar_component_set_selected_files (THUNAR_COMPONENT (object), g_value_get_boxed (value));
break;
case PROP_UI_MANAGER:
thunar_component_set_ui_manager (THUNAR_COMPONENT (object), g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GtkUIManager*
thunar_location_buttons_get_ui_manager (ThunarComponent *component)
{
return THUNAR_LOCATION_BUTTONS (component)->ui_manager;
}
static void
thunar_location_buttons_set_ui_manager (ThunarComponent *component,
GtkUIManager *ui_manager)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (component);
GError *error = NULL;
/* disconnect from the previous ui manager */
if (G_UNLIKELY (buttons->ui_manager != NULL))
{
/* drop our action group from the previous UI manager */
gtk_ui_manager_remove_action_group (buttons->ui_manager, buttons->action_group);
/* unmerge our ui controls from the previous UI manager */
gtk_ui_manager_remove_ui (buttons->ui_manager, buttons->ui_merge_id);
/* drop our reference on the previous UI manager */
g_object_unref (G_OBJECT (buttons->ui_manager));
}
/* activate the new UI manager */
buttons->ui_manager = ui_manager;
/* connect to the new UI manager */
if (G_LIKELY (ui_manager != NULL))
{
/* we keep a reference on the new manager */
g_object_ref (G_OBJECT (ui_manager));
/* add our action group to the new manager */
gtk_ui_manager_insert_action_group (ui_manager, buttons->action_group, -1);
/* merge our UI control items with the new manager */
buttons->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_location_buttons_ui, thunar_location_buttons_ui_length, &error);
if (G_UNLIKELY (buttons->ui_merge_id == 0))
{
g_error ("Failed to merge ThunarLocationButtons menus: %s", error->message);
g_error_free (error);
}
}
/* notify listeners */
g_object_notify (G_OBJECT (buttons), "ui-manager");
}
static ThunarFile*
thunar_location_buttons_get_current_directory (ThunarNavigator *navigator)
{
return THUNAR_LOCATION_BUTTONS (navigator)->current_directory;
}
static void
thunar_location_buttons_set_current_directory (ThunarNavigator *navigator,
ThunarFile *current_directory)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (navigator);
ThunarFile *file_parent;
ThunarFile *file;
GtkWidget *button;
GList *lp;
_thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory));
/* verify that we're not already using the new directory */
if (G_UNLIKELY (buttons->current_directory == current_directory))
return;
/* check if we already have a button for that directory */
for (lp = buttons->list; lp != NULL; lp = lp->next)
if (thunar_location_button_get_file (lp->data) == current_directory)
break;
/* if we already have a button for that directory, just activate it */
if (G_UNLIKELY (lp != NULL))
{
/* fake a "clicked" event for that button */
thunar_location_button_clicked (THUNAR_LOCATION_BUTTON (lp->data));
}
else
{
/* regenerate the button list */
if (G_LIKELY (buttons->current_directory != NULL))
{
g_object_unref (G_OBJECT (buttons->current_directory));
/* remove all buttons */
while (buttons->list != NULL)
gtk_container_remove (GTK_CONTAINER (buttons), buttons->list->data);
/* clear the first scrolled and fake root buttons */
buttons->first_scrolled_button = NULL;
buttons->fake_root_button = NULL;
}
buttons->current_directory = current_directory;
if (G_LIKELY (current_directory != NULL))
{
g_object_ref (G_OBJECT (current_directory));
gtk_widget_push_composite_child ();
/* add the new buttons */
for (file = current_directory; file != NULL; file = file_parent)
{
button = thunar_location_buttons_make_button (buttons, file);
buttons->list = g_list_append (buttons->list, button);
gtk_container_add (GTK_CONTAINER (buttons), button);
gtk_widget_show (button);
/* use 'Home' as fake root button */
if (thunar_file_is_home (file))
buttons->fake_root_button = g_list_last (buttons->list);
/* continue with the parent (if any) */
file_parent = thunar_file_get_parent (file, NULL);
if (G_LIKELY (file != current_directory))
g_object_unref (G_OBJECT (file));
}
gtk_widget_pop_composite_child ();
}
}
g_object_notify (G_OBJECT (buttons), "current-directory");
}
static void
thunar_location_buttons_unmap (GtkWidget *widget)
{
/* be sure to stop the scroll timer before the buttons are unmapped */
thunar_location_buttons_stop_scrolling (THUNAR_LOCATION_BUTTONS (widget));
/* do the real unmap */
(*GTK_WIDGET_CLASS (thunar_location_buttons_parent_class)->unmap) (widget);
}
static void
thunar_location_buttons_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (widget);
GtkRequisition child_requisition;
GList *lp;
gint spacing;
gtk_widget_style_get (GTK_WIDGET (buttons),
"spacing", &spacing,
NULL);
requisition->width = 0;
requisition->height = 0;
/* calculate the size of the biggest button */
for (lp = buttons->list; lp != NULL; lp = lp->next)
{
gtk_widget_size_request (GTK_WIDGET (lp->data), &child_requisition);
requisition->width = MAX (child_requisition.width, requisition->width);
requisition->height = MAX (child_requisition.height, requisition->height);
}
/* add space for the sliders if we have more than one path */
buttons->slider_width = MIN (requisition->height * 2 / 3 + 5, requisition->height);
if (buttons->list != NULL && buttons->list->next != NULL)
requisition->width += (spacing + buttons->slider_width) * 2;
gtk_widget_size_request (buttons->left_slider, &child_requisition);
gtk_widget_size_request (buttons->right_slider, &child_requisition);
requisition->width += GTK_CONTAINER (widget)->border_width * 2;
requisition->height += GTK_CONTAINER (widget)->border_width * 2;
widget->requisition = *requisition;
}
static void
thunar_location_buttons_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (widget);
GtkTextDirection direction;
GtkAllocation child_allocation;
GtkWidget *child;
gboolean need_sliders = FALSE;
gboolean reached_end;
GList *first_button;
GList *lp;
gint left_slider_offset = 0;
gint right_slider_offset = 0;
gint allocation_width;
gint border_width;
gint slider_space;
gint spacing;
gint width;
widget->allocation = *allocation;
/* if no path is set, we don't have to allocate anything */
if (G_UNLIKELY (buttons->list == NULL))
return;
gtk_widget_style_get (GTK_WIDGET (buttons), "spacing", &spacing, NULL);
direction = gtk_widget_get_direction (widget);
border_width = GTK_CONTAINER (buttons)->border_width;
allocation_width = allocation->width - 2 * border_width;
/* check if we need to display the sliders */
if (G_LIKELY (buttons->fake_root_button != NULL))
width = buttons->slider_width + spacing;
else
width = 0;
for (lp = buttons->list; lp != NULL; lp = lp->next)
{
width += GTK_WIDGET (lp->data)->requisition.width + spacing;
if (lp == buttons->fake_root_button)
break;
}
if (width <= allocation_width)
{
if (G_LIKELY (buttons->fake_root_button != NULL))
first_button = buttons->fake_root_button;
else
first_button = g_list_last (buttons->list);
}
else
{
slider_space = 2 * (spacing + buttons->slider_width);
if (buttons->first_scrolled_button != NULL)
first_button = buttons->first_scrolled_button;
else
first_button = buttons->list;
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.
*/
width = GTK_WIDGET (first_button->data)->requisition.width;
for (lp = first_button->prev, reached_end = FALSE; lp != NULL && !reached_end; lp = lp->prev)
{
child = lp->data;
if (width + child->requisition.width + spacing + slider_space > allocation_width)
reached_end = TRUE;
else if (lp == buttons->fake_root_button)
break;
else
width += child->requisition.width + spacing;
}
while (first_button->next != NULL && !reached_end)
{
child = first_button->data;
if (width + child->requisition.width + spacing + slider_space > allocation_width)
{
reached_end = TRUE;
}
else
{
width += child->requisition.width + spacing;
if (first_button == buttons->fake_root_button)
break;
first_button = first_button->next;
}
}
}
/* Now we allocate space to the buttons */
child_allocation.y = allocation->y + border_width;
child_allocation.height = MAX (1, allocation->height - border_width * 2);
if (G_UNLIKELY (direction == GTK_TEXT_DIR_RTL))
{
child_allocation.x = allocation->x + allocation->width - border_width;
if (need_sliders || buttons->fake_root_button != NULL)
{
child_allocation.x -= spacing + buttons->slider_width;
left_slider_offset = allocation->width - border_width - buttons->slider_width;
}
}
else
{
child_allocation.x = allocation->x + border_width;
if (need_sliders || buttons->fake_root_button != NULL)
{
left_slider_offset = border_width;
child_allocation.x += spacing + buttons->slider_width;
}
}
for (lp = first_button; lp != NULL; lp = lp->prev)
{
child = lp->data;
child_allocation.width = child->requisition.width;
if (G_UNLIKELY (direction == GTK_TEXT_DIR_RTL))
child_allocation.x -= child_allocation.width;
/* check to see if we don't have any more space to allocate buttons */
if (need_sliders && direction == GTK_TEXT_DIR_RTL)
{
if (child_allocation.x - spacing - buttons->slider_width < widget->allocation.x + border_width)
break;
}
else if (need_sliders && direction == GTK_TEXT_DIR_LTR)
{
if (child_allocation.x + child_allocation.width + spacing + buttons->slider_width > widget->allocation.x + border_width + allocation_width)
break;
}
gtk_widget_set_child_visible (GTK_WIDGET (lp->data), TRUE);
gtk_widget_size_allocate (child, &child_allocation);
if (direction == GTK_TEXT_DIR_RTL)
{
child_allocation.x -= spacing;
right_slider_offset = border_width;
}
else
{
child_allocation.x += child_allocation.width + spacing;
right_slider_offset = allocation->width - border_width - buttons->slider_width;
}
}
/* now we go hide all the buttons that don't fit */
for (; lp != NULL; lp = lp->prev)
gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE);
for (lp = first_button->next; lp != NULL; lp = lp->next)
gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE);
if (need_sliders || buttons->fake_root_button != NULL)
{
child_allocation.width = buttons->slider_width;
child_allocation.x = left_slider_offset + allocation->x;
gtk_widget_size_allocate (buttons->left_slider, &child_allocation);
gtk_widget_set_child_visible (buttons->left_slider, TRUE);
gtk_widget_show_all (buttons->left_slider);
thunar_location_buttons_update_sliders (buttons);
}
else
{
gtk_widget_set_child_visible (buttons->left_slider, FALSE);
}
if (need_sliders)
{
child_allocation.width = buttons->slider_width;
child_allocation.x = right_slider_offset + allocation->x;
gtk_widget_size_allocate (buttons->right_slider, &child_allocation);
gtk_widget_set_child_visible (buttons->right_slider, TRUE);
gtk_widget_show_all (buttons->right_slider);
thunar_location_buttons_update_sliders (buttons);
}
else
{
gtk_widget_set_child_visible (buttons->right_slider, FALSE);
}
}
static void
thunar_location_buttons_state_changed (GtkWidget *widget,
GtkStateType previous_state)
{
if (!GTK_WIDGET_IS_SENSITIVE (widget))
thunar_location_buttons_stop_scrolling (THUNAR_LOCATION_BUTTONS (widget));
}
static void
thunar_location_buttons_grab_notify (GtkWidget *widget,
gboolean was_grabbed)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (widget);
if (!was_grabbed)
thunar_location_buttons_stop_scrolling (buttons);
}
static void
thunar_location_buttons_add (GtkContainer *container,
GtkWidget *widget)
{
gtk_widget_set_parent (widget, GTK_WIDGET (container));
}
static void
thunar_location_buttons_remove (GtkContainer *container,
GtkWidget *widget)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (container);
GList *lp;
if (widget == buttons->left_slider)
{
thunar_location_buttons_remove_1 (container, widget);
buttons->left_slider = NULL;
return;
}
else if (widget == buttons->right_slider)
{
thunar_location_buttons_remove_1 (container, widget);
buttons->right_slider = NULL;
return;
}
for (lp = buttons->list; lp != NULL; lp = lp->next)
if (widget == GTK_WIDGET (lp->data))
{
thunar_location_buttons_remove_1 (container, widget);
buttons->list = g_list_remove_link (buttons->list, lp);
g_list_free (lp);
return;
}
}
static void
thunar_location_buttons_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (container);
GtkWidget *child;
GList *lp;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (callback != NULL);
for (lp = buttons->list; lp != NULL; )
{
child = GTK_WIDGET (lp->data);
lp = lp->next;
(*callback) (child, callback_data);
}
if (buttons->left_slider != NULL && include_internals)
(*callback) (buttons->left_slider, callback_data);
if (buttons->right_slider != NULL && include_internals)
(*callback) (buttons->right_slider, callback_data);
}
static GtkWidget*
thunar_location_buttons_make_button (ThunarLocationButtons *buttons,
ThunarFile *file)
{
GtkWidget *button;
/* allocate the button */
button = thunar_location_button_new ();
/* connect to the file */
thunar_location_button_set_file (THUNAR_LOCATION_BUTTON (button), file);
/* the current directory is active */
thunar_location_button_set_active (THUNAR_LOCATION_BUTTON (button), (file == buttons->current_directory));
/* connect signal handlers */
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (thunar_location_buttons_clicked), buttons);
g_signal_connect (G_OBJECT (button), "gone", G_CALLBACK (thunar_location_buttons_gone), buttons);
g_signal_connect (G_OBJECT (button), "context-menu", G_CALLBACK (thunar_location_buttons_context_menu), buttons);
return button;
}
static void
thunar_location_buttons_remove_1 (GtkContainer *container,
GtkWidget *widget)
{
gboolean need_resize = GTK_WIDGET_VISIBLE (widget);
gtk_widget_unparent (widget);
if (G_LIKELY (need_resize))
gtk_widget_queue_resize (GTK_WIDGET (container));
}
static gboolean
thunar_location_buttons_scroll_timeout (gpointer user_data)
{
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (user_data);
GDK_THREADS_ENTER ();
if (GTK_WIDGET_HAS_FOCUS (buttons->left_slider))
thunar_location_buttons_scroll_left (buttons->left_slider, buttons);
else if (GTK_WIDGET_HAS_FOCUS (buttons->right_slider))
thunar_location_buttons_scroll_right (buttons->right_slider, buttons);
GDK_THREADS_LEAVE ();
return TRUE;
}
static void
thunar_location_buttons_scroll_timeout_destroy (gpointer user_data)
{
THUNAR_LOCATION_BUTTONS (user_data)->scroll_timeout_id = 0;
}
static void
thunar_location_buttons_stop_scrolling (ThunarLocationButtons *buttons)
{
if (buttons->scroll_timeout_id != 0)
g_source_remove (buttons->scroll_timeout_id);
}
static void
thunar_location_buttons_update_sliders (ThunarLocationButtons *buttons)
{
GtkWidget *button;
if (G_LIKELY (buttons->list != NULL))
{
button = GTK_WIDGET (buttons->list->data);
if (gtk_widget_get_child_visible (button))
{
gtk_widget_set_sensitive (buttons->right_slider, FALSE);
thunar_location_buttons_stop_scrolling (buttons);
}
else
{
gtk_widget_set_sensitive (buttons->right_slider, TRUE);
}
button = GTK_WIDGET (g_list_last (buttons->list)->data);
if (gtk_widget_get_child_visible (button) && buttons->fake_root_button == NULL)
{
gtk_widget_set_sensitive (buttons->left_slider, FALSE);
thunar_location_buttons_stop_scrolling (buttons);
}
else
{
gtk_widget_set_sensitive (buttons->left_slider, TRUE);
}
}
}
static gboolean
thunar_location_buttons_slider_button_press (GtkWidget *button,
GdkEventButton *event,
ThunarLocationButtons *buttons)
{
if (!GTK_WIDGET_HAS_FOCUS (button))
gtk_widget_grab_focus (button);
if (event->type != GDK_BUTTON_PRESS || event->button != 1)
return FALSE;
buttons->ignore_click = FALSE;
if (button == buttons->left_slider)
thunar_location_buttons_scroll_left (button, buttons);
else if (button == buttons->right_slider)
thunar_location_buttons_scroll_right (button, buttons);
if (G_LIKELY (buttons->scroll_timeout_id == 0))
{
buttons->scroll_timeout_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_LOCATION_BUTTONS_SCROLL_TIMEOUT,
thunar_location_buttons_scroll_timeout, buttons,
thunar_location_buttons_scroll_timeout_destroy);
}
return FALSE;
}
static gboolean
thunar_location_buttons_slider_button_release (GtkWidget *button,
GdkEventButton *event,
ThunarLocationButtons *buttons)
{
if (event->type == GDK_BUTTON_RELEASE)
{
thunar_location_buttons_stop_scrolling (buttons);
buttons->ignore_click = TRUE;
}
return FALSE;
}
static void
thunar_location_buttons_scroll_left (GtkWidget *button,
ThunarLocationButtons *buttons)
{
GList *lp;
if (G_UNLIKELY (buttons->ignore_click))
{
buttons->ignore_click = FALSE;
return;
}
gtk_widget_queue_resize (GTK_WIDGET (buttons));
for (lp = g_list_last (buttons->list); lp != NULL; lp = lp->prev)
if (lp->prev != NULL && gtk_widget_get_child_visible (GTK_WIDGET (lp->prev->data)))
{
if (lp->prev == buttons->fake_root_button)
buttons->fake_root_button = NULL;
buttons->first_scrolled_button = lp;
break;
}
}
static void
thunar_location_buttons_scroll_right (GtkWidget *button,
ThunarLocationButtons *buttons)
{
GtkTextDirection direction;
GList *right_button = NULL;
GList *left_button = NULL;
GList *lp;
gint space_available;
gint space_needed;
gint border_width;
gint spacing;
if (G_UNLIKELY (buttons->ignore_click))
{
buttons->ignore_click = FALSE;
return;
}
gtk_widget_style_get (GTK_WIDGET (buttons),
"spacing", &spacing,
NULL);
gtk_widget_queue_resize (GTK_WIDGET (buttons));
border_width = GTK_CONTAINER (buttons)->border_width;
direction = gtk_widget_get_direction (GTK_WIDGET (buttons));
/* find the button at the 'right' end that we have to make visible */
for (lp = buttons->list; lp != NULL; lp = lp->next)
if (lp->next != NULL && gtk_widget_get_child_visible (GTK_WIDGET (lp->next->data)))
{
right_button = lp;
break;
}
/* find the last visible button on the 'left' end */
for (lp = g_list_last (buttons->list); lp != NULL; lp = lp->prev)
if (gtk_widget_get_child_visible (GTK_WIDGET (lp->data)))
{
left_button = lp;
break;
}
space_needed = GTK_WIDGET (right_button->data)->allocation.width + spacing;
if (direction == GTK_TEXT_DIR_RTL)
{
space_available = buttons->right_slider->allocation.x - GTK_WIDGET (buttons)->allocation.x;
}
else
{
space_available = (GTK_WIDGET (buttons)->allocation.x + GTK_WIDGET (buttons)->allocation.width - border_width)
- (buttons->right_slider->allocation.x + buttons->right_slider->allocation.width);
}
/* We have space_available extra space that's not being used. We
* need space_needed space to make the button fit. So we walk down
* from the end, removing buttons until we get all the space we
* need.
*/
while (space_available < space_needed)
{
space_available += GTK_WIDGET (left_button->data)->allocation.width + spacing;
left_button = left_button->prev;
buttons->first_scrolled_button = left_button;
}
}
static void
thunar_location_buttons_clicked (ThunarLocationButton *button,
ThunarLocationButtons *buttons)
{
ThunarFile *directory;
GList *lp;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button));
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
/* determine the directory associated with the clicked button */
directory = thunar_location_button_get_file (button);
/* disconnect from previous current directory (if any) */
if (G_LIKELY (buttons->current_directory != NULL))
g_object_unref (G_OBJECT (buttons->current_directory));
/* setup the new current directory */
buttons->current_directory = directory;
/* take a reference on the new directory (if any) */
if (G_LIKELY (directory != NULL))
g_object_ref (G_OBJECT (directory));
/* check if the button is visible on the button bar */
if (!gtk_widget_get_child_visible (GTK_WIDGET (button)))
{
/* scroll to the button */
buttons->first_scrolled_button = g_list_find (buttons->list, button);
gtk_widget_queue_resize (GTK_WIDGET (buttons));
/* we may need to reset the fake_root_button */
if (G_LIKELY (buttons->fake_root_button != NULL))
{
/* check if the fake_root_button is before the first_scrolled_button (from right to left) */
for (lp = buttons->list; lp != NULL && lp != buttons->first_scrolled_button; lp = lp->next)
if (lp == buttons->fake_root_button)
{
/* reset the fake_root_button */
buttons->fake_root_button = NULL;
break;
}
}
}
/* update all buttons */
for (lp = buttons->list; lp != NULL; lp = lp->next)
{
/* determine the directory for this button */
button = THUNAR_LOCATION_BUTTON (lp->data);
directory = thunar_location_button_get_file (button);
/* update the location button state (making sure to not recurse with the "clicked" handler) */
g_signal_handlers_block_by_func (G_OBJECT (button), thunar_location_buttons_clicked, buttons);
thunar_location_button_set_active (button, directory == buttons->current_directory);
g_signal_handlers_unblock_by_func (G_OBJECT (button), thunar_location_buttons_clicked, buttons);
}
/* notify the surrounding module that we want to change to a different directory. */
thunar_navigator_change_directory (THUNAR_NAVIGATOR (buttons), buttons->current_directory);
}
static void
thunar_location_buttons_gone (ThunarLocationButton *button,
ThunarLocationButtons *buttons)
{
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button));
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (g_list_find (buttons->list, button) != NULL);
/* drop all buttons up to the button that emitted the "gone" signal */
while (buttons->list->data != button)
gtk_widget_destroy (buttons->list->data);
/* drop the button itself */
gtk_widget_destroy (GTK_WIDGET (button));
}
static void
thunar_location_buttons_context_menu (ThunarLocationButton *button,
GdkEventButton *event,
ThunarLocationButtons *buttons)
{
ThunarClipboardManager *clipboard;
const gchar *display_name;
ThunarFile *file;
GtkAction *action;
GtkWidget *menu;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button));
/* determine the file for the button */
file = thunar_location_button_get_file (button);
if (G_LIKELY (file != NULL))
{
/* we cannot popup the context menu without an ui manager */
if (G_LIKELY (buttons->ui_manager != NULL))
{
/* determine the display name of the file */
display_name = thunar_file_get_display_name (file);
/* be sure to keep a reference on the navigation bar */
g_object_ref (G_OBJECT (buttons));
/* grab a reference on the clipboard manager for this display */
clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons)));
/* setup the "Open" action */
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open");
thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in this window"), display_name);
g_object_set_data_full (G_OBJECT (action), I_("thunar-file"), g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
gtk_action_set_sensitive (action, (file != buttons->current_directory));
/* setup the "Open in New Window" action */
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open-in-new-window");
thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in a new window"), display_name);
g_object_set_data_full (G_OBJECT (action), I_("thunar-file"), g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
/* setup the "Create Folder..." action */
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-create-folder");
thunar_gtk_action_set_tooltip (action, _("Create a new folder in \"%s\""), display_name);
g_object_set_data_full (G_OBJECT (action), I_("thunar-file"), g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
gtk_action_set_sensitive (action, thunar_file_is_writable (file));
gtk_action_set_visible (action, !thunar_file_is_trashed (file));
/* setup the "Empty Trash" action */
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-empty-trash");
gtk_action_set_visible (action, (thunar_file_is_root (file) && thunar_file_is_trashed (file)));
gtk_action_set_sensitive (action, (thunar_file_get_size (file) > 0));
/* setup the "Paste Into Folder" action */
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-paste-into-folder");
thunar_gtk_action_set_tooltip (action, _("Move or copy files previously selected by a Cut or Copy command into \"%s\""), display_name);
g_object_set_data_full (G_OBJECT (action), I_("thunar-file"), g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
gtk_action_set_sensitive (action, thunar_clipboard_manager_get_can_paste (clipboard));
/* setup the "Properties..." action */
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-properties");
thunar_gtk_action_set_tooltip (action, _("View the properties of the folder \"%s\""), display_name);
g_object_set_data_full (G_OBJECT (action), I_("thunar-file"), g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
/* run the menu on the screen on the buttons' screen */
menu = gtk_ui_manager_get_widget (buttons->ui_manager, "/location-buttons-context-menu");
thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (buttons), NULL, NULL, event->button, event->time);
/* cleanup */
g_object_unref (G_OBJECT (buttons));
g_object_unref (G_OBJECT (clipboard));
}
}
}
static void
thunar_location_buttons_action_create_folder (GtkAction *action,
ThunarLocationButtons *buttons)
{
ThunarVfsMimeDatabase *mime_database;
ThunarVfsMimeInfo *mime_info;
ThunarApplication *application;
ThunarFile *directory;
GList path_list;
gchar *name;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (GTK_IS_ACTION (action));
/* determine the directory for the action */
directory = g_object_get_data (G_OBJECT (action), "thunar-file");
if (G_UNLIKELY (directory == NULL))
return;
/* lookup "inode/directory" mime info */
mime_database = thunar_vfs_mime_database_get_default ();
mime_info = thunar_vfs_mime_database_get_info (mime_database, "inode/directory");
/* ask the user to enter a name for the new folder */
name = thunar_show_create_dialog (GTK_WIDGET (buttons), mime_info, _("New Folder"), _("Create New Folder"));
if (G_LIKELY (name != NULL))
{
/* fake the path list */
path_list.data = thunar_vfs_path_relative (thunar_file_get_path (directory), name);
path_list.next = path_list.prev = NULL;
/* launch the operation */
application = thunar_application_get ();
thunar_application_mkdir (application, GTK_WIDGET (buttons), &path_list, NULL);
g_object_unref (G_OBJECT (application));
/* release the path */
thunar_vfs_path_unref (path_list.data);
/* release the file name */
g_free (name);
}
/* cleanup */
g_object_unref (G_OBJECT (mime_database));
thunar_vfs_mime_info_unref (mime_info);
}
static void
thunar_location_buttons_action_down_folder (GtkAction *action,
ThunarLocationButtons *buttons)
{
GList *lp;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (GTK_IS_ACTION (action));
/* lookup the active button */
for (lp = buttons->list; lp != NULL; lp = lp->next)
if (thunar_location_button_get_active (lp->data))
{
/* check if we have a folder below that one */
if (G_LIKELY (lp->prev != NULL))
{
/* enter that folder */
thunar_location_button_clicked (lp->prev->data);
}
break;
}
}
static void
thunar_location_buttons_action_empty_trash (GtkAction *action,
ThunarLocationButtons *buttons)
{
ThunarApplication *application;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (GTK_IS_ACTION (action));
/* launch the operation */
application = thunar_application_get ();
thunar_application_empty_trash (application, GTK_WIDGET (buttons));
g_object_unref (G_OBJECT (application));
}
static void
thunar_location_buttons_action_open (GtkAction *action,
ThunarLocationButtons *buttons)
{
ThunarFile *directory;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (GTK_IS_ACTION (action));
/* determine the directory for the action */
directory = g_object_get_data (G_OBJECT (action), "thunar-file");
if (G_LIKELY (directory != NULL && thunar_file_is_directory (directory)))
{
/* open the folder in this window */
thunar_navigator_change_directory (THUNAR_NAVIGATOR (buttons), directory);
}
}
static void
thunar_location_buttons_action_open_in_new_window (GtkAction *action,
ThunarLocationButtons *buttons)
{
ThunarApplication *application;
ThunarFile *directory;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (GTK_IS_ACTION (action));
/* determine the directory for the action */
directory = g_object_get_data (G_OBJECT (action), "thunar-file");
if (G_LIKELY (directory != NULL))
{
/* open a new window for the directory */
application = thunar_application_get ();
thunar_application_open_window (application, directory, gtk_widget_get_screen (GTK_WIDGET (buttons)));
g_object_unref (G_OBJECT (application));
}
}
static void
thunar_location_buttons_action_paste_into_folder (GtkAction *action,
ThunarLocationButtons *buttons)
{
ThunarClipboardManager *clipboard;
ThunarFile *directory;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (GTK_IS_ACTION (action));
/* determine the directory for the action */
directory = g_object_get_data (G_OBJECT (action), "thunar-file");
if (G_LIKELY (directory != NULL))
{
/* paste files from the clipboard to the folder represented by this button */
clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons)));
thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_path (directory), GTK_WIDGET (buttons), NULL);
g_object_unref (G_OBJECT (clipboard));
}
}
static void
thunar_location_buttons_action_properties (GtkAction *action,
ThunarLocationButtons *buttons)
{
ThunarFile *directory;
GtkWidget *toplevel;
GtkWidget *dialog;
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
_thunar_return_if_fail (GTK_IS_ACTION (action));
/* determine the directory for the action */
directory = g_object_get_data (G_OBJECT (action), "thunar-file");
if (G_LIKELY (directory != NULL))
{
/* determine the toplevel window */
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (buttons));
if (G_LIKELY (toplevel != NULL && GTK_WIDGET_TOPLEVEL (toplevel)))
{
/* popup the properties dialog */
dialog = thunar_properties_dialog_new ();
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
thunar_properties_dialog_set_file (THUNAR_PROPERTIES_DIALOG (dialog), directory);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
gtk_widget_show (dialog);
}
}
}
/**
* thunar_location_buttons_new:
*
* Creates a new #ThunarLocationButtons object, that does
* not display any path by default.
*
* Return value: the newly allocated #ThunarLocationButtons object.
**/
GtkWidget*
thunar_location_buttons_new (void)
{
return g_object_new (THUNAR_TYPE_LOCATION_BUTTONS, NULL);
}