3
* Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
4
* Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by the Free
8
* Software Foundation; either version 2 of the License, or (at your option)
11
* This program is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16
* You should have received a copy of the GNU General Public License along with
17
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18
* Place, Suite 330, Boston, MA 02111-1307 USA
20
* Based on code written by Jonathan Blandford <jrb@gnome.org> for
28
#include <thunar/thunar-application.h>
29
#include <thunar/thunar-clipboard-manager.h>
30
#include <thunar/thunar-create-dialog.h>
31
#include <thunar/thunar-gio-extensions.h>
32
#include <thunar/thunar-gobject-extensions.h>
33
#include <thunar/thunar-gtk-extensions.h>
34
#include <thunar/thunar-location-button.h>
35
#include <thunar/thunar-location-buttons.h>
36
#include <thunar/thunar-location-buttons-ui.h>
37
#include <thunar/thunar-private.h>
38
#include <thunar/thunar-properties-dialog.h>
42
#define THUNAR_LOCATION_BUTTONS_SCROLL_TIMEOUT (200)
46
/* Property identifiers */
50
PROP_CURRENT_DIRECTORY,
57
static void thunar_location_buttons_component_init (ThunarComponentIface *iface);
58
static void thunar_location_buttons_navigator_init (ThunarNavigatorIface *iface);
59
static void thunar_location_buttons_location_bar_init (ThunarLocationBarIface *iface);
60
static void thunar_location_buttons_finalize (GObject *object);
61
static void thunar_location_buttons_get_property (GObject *object,
65
static void thunar_location_buttons_set_property (GObject *object,
69
static GtkUIManager *thunar_location_buttons_get_ui_manager (ThunarComponent *component);
70
static void thunar_location_buttons_set_ui_manager (ThunarComponent *component,
71
GtkUIManager *ui_manager);
72
static ThunarFile *thunar_location_buttons_get_current_directory (ThunarNavigator *navigator);
73
static void thunar_location_buttons_set_current_directory (ThunarNavigator *navigator,
74
ThunarFile *current_directory);
75
static void thunar_location_buttons_unmap (GtkWidget *widget);
76
static void thunar_location_buttons_size_request (GtkWidget *widget,
77
GtkRequisition *requisition);
78
static void thunar_location_buttons_size_allocate (GtkWidget *widget,
79
GtkAllocation *allocation);
80
static void thunar_location_buttons_state_changed (GtkWidget *widget,
81
GtkStateType previous_state);
82
static void thunar_location_buttons_grab_notify (GtkWidget *widget,
83
gboolean was_grabbed);
84
static void thunar_location_buttons_add (GtkContainer *container,
86
static void thunar_location_buttons_remove (GtkContainer *container,
88
static void thunar_location_buttons_forall (GtkContainer *container,
89
gboolean include_internals,
91
gpointer callback_data);
92
static GtkWidget *thunar_location_buttons_make_button (ThunarLocationButtons *buttons,
94
static void thunar_location_buttons_remove_1 (GtkContainer *container,
96
static gboolean thunar_location_buttons_scroll_timeout (gpointer user_data);
97
static void thunar_location_buttons_scroll_timeout_destroy (gpointer user_data);
98
static void thunar_location_buttons_stop_scrolling (ThunarLocationButtons *buttons);
99
static void thunar_location_buttons_update_sliders (ThunarLocationButtons *buttons);
100
static gboolean thunar_location_buttons_slider_button_press (GtkWidget *button,
101
GdkEventButton *event,
102
ThunarLocationButtons *buttons);
103
static gboolean thunar_location_buttons_slider_button_release (GtkWidget *button,
104
GdkEventButton *event,
105
ThunarLocationButtons *buttons);
106
static void thunar_location_buttons_scroll_left (GtkWidget *button,
107
ThunarLocationButtons *buttons);
108
static void thunar_location_buttons_scroll_right (GtkWidget *button,
109
ThunarLocationButtons *buttons);
110
static void thunar_location_buttons_clicked (ThunarLocationButton *button,
111
gboolean open_in_tab,
112
ThunarLocationButtons *buttons);
113
static void thunar_location_buttons_context_menu (ThunarLocationButton *button,
114
GdkEventButton *event,
115
ThunarLocationButtons *buttons);
116
static void thunar_location_buttons_gone (ThunarLocationButton *button,
117
ThunarLocationButtons *buttons);
118
static void thunar_location_buttons_action_create_folder (GtkAction *action,
119
ThunarLocationButtons *buttons);
120
static void thunar_location_buttons_action_down_folder (GtkAction *action,
121
ThunarLocationButtons *buttons);
122
static void thunar_location_buttons_action_empty_trash (GtkAction *action,
123
ThunarLocationButtons *buttons);
124
static void thunar_location_buttons_action_open (GtkAction *action,
125
ThunarLocationButtons *buttons);
126
static void thunar_location_buttons_action_open_in_new_tab (GtkAction *action,
127
ThunarLocationButtons *buttons);
128
static void thunar_location_buttons_action_open_in_new_window (GtkAction *action,
129
ThunarLocationButtons *buttons);
130
static void thunar_location_buttons_action_paste_into_folder (GtkAction *action,
131
ThunarLocationButtons *buttons);
132
static void thunar_location_buttons_action_properties (GtkAction *action,
133
ThunarLocationButtons *buttons);
137
struct _ThunarLocationButtonsClass
139
GtkContainerClass __parent__;
142
struct _ThunarLocationButtons
144
GtkContainer __parent__;
146
GtkActionGroup *action_group;
147
GtkUIManager *ui_manager;
150
GtkWidget *left_slider;
151
GtkWidget *right_slider;
153
ThunarFile *current_directory;
156
gboolean ignore_click : 1;
159
GList *fake_root_button;
160
GList *first_scrolled_button;
162
guint scroll_timeout_id;
167
static GQuark thunar_file_quark = 0;
171
static const GtkActionEntry action_entries[] =
173
{ "location-buttons-down-folder", NULL, "Down Folder", "<alt>Down", NULL, G_CALLBACK (thunar_location_buttons_action_down_folder), },
174
{ "location-buttons-context-menu", NULL, "Context Menu", NULL, "", NULL, },
175
{ "location-buttons-open", GTK_STOCK_OPEN, N_("_Open"), "", NULL, G_CALLBACK (thunar_location_buttons_action_open), },
176
{ "location-buttons-open-in-new-tab", NULL, N_("Open in New Tab"), "", NULL, G_CALLBACK (thunar_location_buttons_action_open_in_new_tab), },
177
{ "location-buttons-open-in-new-window", NULL, N_("Open in New Window"), "", NULL, G_CALLBACK (thunar_location_buttons_action_open_in_new_window), },
178
{ "location-buttons-create-folder", NULL, N_("Create _Folder..."), "", NULL, G_CALLBACK (thunar_location_buttons_action_create_folder), },
179
{ "location-buttons-empty-trash", NULL, N_("_Empty Trash"), "", N_("Delete all files and folders in the Trash"), G_CALLBACK (thunar_location_buttons_action_empty_trash), },
180
{ "location-buttons-paste-into-folder", GTK_STOCK_PASTE, N_("Paste Into Folder"), "", NULL, G_CALLBACK (thunar_location_buttons_action_paste_into_folder), },
181
{ "location-buttons-properties", GTK_STOCK_PROPERTIES, N_("_Properties..."), "", NULL, G_CALLBACK (thunar_location_buttons_action_properties), },
186
G_DEFINE_TYPE_WITH_CODE (ThunarLocationButtons, thunar_location_buttons, GTK_TYPE_CONTAINER,
187
G_IMPLEMENT_INTERFACE (THUNAR_TYPE_NAVIGATOR, thunar_location_buttons_navigator_init)
188
G_IMPLEMENT_INTERFACE (THUNAR_TYPE_COMPONENT, thunar_location_buttons_component_init)
189
G_IMPLEMENT_INTERFACE (THUNAR_TYPE_LOCATION_BAR, thunar_location_buttons_location_bar_init))
194
thunar_location_buttons_class_init (ThunarLocationButtonsClass *klass)
196
GtkContainerClass *gtkcontainer_class;
197
GtkWidgetClass *gtkwidget_class;
198
GObjectClass *gobject_class;
200
gobject_class = G_OBJECT_CLASS (klass);
201
gobject_class->finalize = thunar_location_buttons_finalize;
202
gobject_class->get_property = thunar_location_buttons_get_property;
203
gobject_class->set_property = thunar_location_buttons_set_property;
205
gtkwidget_class = GTK_WIDGET_CLASS (klass);
206
gtkwidget_class->unmap = thunar_location_buttons_unmap;
207
gtkwidget_class->size_request = thunar_location_buttons_size_request;
208
gtkwidget_class->size_allocate = thunar_location_buttons_size_allocate;
209
gtkwidget_class->state_changed = thunar_location_buttons_state_changed;
210
gtkwidget_class->grab_notify = thunar_location_buttons_grab_notify;
212
gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
213
gtkcontainer_class->add = thunar_location_buttons_add;
214
gtkcontainer_class->remove = thunar_location_buttons_remove;
215
gtkcontainer_class->forall = thunar_location_buttons_forall;
217
/* Override ThunarNavigator's properties */
218
g_object_class_override_property (gobject_class, PROP_CURRENT_DIRECTORY, "current-directory");
220
/* Override ThunarComponent's properties */
221
g_object_class_override_property (gobject_class, PROP_SELECTED_FILES, "selected-files");
222
g_object_class_override_property (gobject_class, PROP_UI_MANAGER, "ui-manager");
225
* ThunarLocationButtons:spacing:
227
* The amount of space between the path buttons.
229
gtk_widget_class_install_style_property (gtkwidget_class,
230
g_param_spec_int ("spacing",
232
_("The amount of space between the path buttons"),
236
thunar_file_quark = g_quark_from_static_string ("button-thunar-file");
242
thunar_location_buttons_component_init (ThunarComponentIface *iface)
244
iface->get_selected_files = (gpointer) exo_noop_null;
245
iface->set_selected_files = (gpointer) exo_noop;
246
iface->get_ui_manager = thunar_location_buttons_get_ui_manager;
247
iface->set_ui_manager = thunar_location_buttons_set_ui_manager;
253
thunar_location_buttons_navigator_init (ThunarNavigatorIface *iface)
255
iface->get_current_directory = thunar_location_buttons_get_current_directory;
256
iface->set_current_directory = thunar_location_buttons_set_current_directory;
262
thunar_location_buttons_location_bar_init (ThunarLocationBarIface *iface)
264
iface->accept_focus = (gpointer) exo_noop_false;
265
iface->is_standalone = (gpointer) exo_noop_true;
271
thunar_location_buttons_init (ThunarLocationButtons *buttons)
275
/* setup the action group for the location buttons */
276
buttons->action_group = gtk_action_group_new ("ThunarLocationButtons");
277
gtk_action_group_set_translation_domain (buttons->action_group, GETTEXT_PACKAGE);
278
gtk_action_group_add_actions (buttons->action_group, action_entries, G_N_ELEMENTS (action_entries), buttons);
280
gtk_widget_set_has_window (GTK_WIDGET (buttons), FALSE);
281
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (buttons), FALSE);
283
buttons->left_slider = gtk_button_new ();
284
g_signal_connect (G_OBJECT (buttons->left_slider), "button-press-event", G_CALLBACK (thunar_location_buttons_slider_button_press), buttons);
285
g_signal_connect (G_OBJECT (buttons->left_slider), "button-release-event", G_CALLBACK (thunar_location_buttons_slider_button_release), buttons);
286
g_signal_connect (G_OBJECT (buttons->left_slider), "clicked", G_CALLBACK (thunar_location_buttons_scroll_left), buttons);
287
gtk_container_add (GTK_CONTAINER (buttons), buttons->left_slider);
288
gtk_widget_show (buttons->left_slider);
290
arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_OUT);
291
gtk_container_add (GTK_CONTAINER (buttons->left_slider), arrow);
292
gtk_widget_show (arrow);
294
buttons->right_slider = gtk_button_new ();
295
g_signal_connect (G_OBJECT (buttons->right_slider), "button-press-event", G_CALLBACK (thunar_location_buttons_slider_button_press), buttons);
296
g_signal_connect (G_OBJECT (buttons->right_slider), "button-release-event", G_CALLBACK (thunar_location_buttons_slider_button_release), buttons);
297
g_signal_connect (G_OBJECT (buttons->right_slider), "clicked", G_CALLBACK (thunar_location_buttons_scroll_right), buttons);
298
gtk_container_add (GTK_CONTAINER (buttons), buttons->right_slider);
299
gtk_widget_show (buttons->right_slider);
301
arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
302
gtk_container_add (GTK_CONTAINER (buttons->right_slider), arrow);
303
gtk_widget_show (arrow);
309
thunar_location_buttons_finalize (GObject *object)
311
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (object);
313
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
315
/* disconnect from the selected files and the UI manager */
316
thunar_component_set_selected_files (THUNAR_COMPONENT (buttons), NULL);
317
thunar_component_set_ui_manager (THUNAR_COMPONENT (buttons), NULL);
319
/* be sure to cancel the scrolling */
320
thunar_location_buttons_stop_scrolling (buttons);
322
/* release from the current_directory */
323
thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (buttons), NULL);
325
/* release our action group */
326
g_object_unref (G_OBJECT (buttons->action_group));
328
(*G_OBJECT_CLASS (thunar_location_buttons_parent_class)->finalize) (object);
334
thunar_location_buttons_get_property (GObject *object,
341
case PROP_CURRENT_DIRECTORY:
342
g_value_set_object (value, thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (object)));
345
case PROP_SELECTED_FILES:
346
g_value_set_boxed (value, thunar_component_get_selected_files (THUNAR_COMPONENT (object)));
349
case PROP_UI_MANAGER:
350
g_value_set_object (value, thunar_component_get_ui_manager (THUNAR_COMPONENT (object)));
354
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
362
thunar_location_buttons_set_property (GObject *object,
369
case PROP_CURRENT_DIRECTORY:
370
thunar_navigator_set_current_directory (THUNAR_NAVIGATOR (object), g_value_get_object (value));
373
case PROP_SELECTED_FILES:
374
thunar_component_set_selected_files (THUNAR_COMPONENT (object), g_value_get_boxed (value));
377
case PROP_UI_MANAGER:
378
thunar_component_set_ui_manager (THUNAR_COMPONENT (object), g_value_get_object (value));
382
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
390
thunar_location_buttons_get_ui_manager (ThunarComponent *component)
392
return THUNAR_LOCATION_BUTTONS (component)->ui_manager;
398
thunar_location_buttons_set_ui_manager (ThunarComponent *component,
399
GtkUIManager *ui_manager)
401
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (component);
402
GError *error = NULL;
404
/* disconnect from the previous ui manager */
405
if (G_UNLIKELY (buttons->ui_manager != NULL))
407
/* drop our action group from the previous UI manager */
408
gtk_ui_manager_remove_action_group (buttons->ui_manager, buttons->action_group);
410
/* unmerge our ui controls from the previous UI manager */
411
gtk_ui_manager_remove_ui (buttons->ui_manager, buttons->ui_merge_id);
413
/* drop our reference on the previous UI manager */
414
g_object_unref (G_OBJECT (buttons->ui_manager));
417
/* activate the new UI manager */
418
buttons->ui_manager = ui_manager;
420
/* connect to the new UI manager */
421
if (G_LIKELY (ui_manager != NULL))
423
/* we keep a reference on the new manager */
424
g_object_ref (G_OBJECT (ui_manager));
426
/* add our action group to the new manager */
427
gtk_ui_manager_insert_action_group (ui_manager, buttons->action_group, -1);
429
/* merge our UI control items with the new manager */
430
buttons->ui_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, thunar_location_buttons_ui, thunar_location_buttons_ui_length, &error);
431
if (G_UNLIKELY (buttons->ui_merge_id == 0))
433
g_error ("Failed to merge ThunarLocationButtons menus: %s", error->message);
434
g_error_free (error);
438
/* notify listeners */
439
g_object_notify (G_OBJECT (buttons), "ui-manager");
445
thunar_location_buttons_get_current_directory (ThunarNavigator *navigator)
447
return THUNAR_LOCATION_BUTTONS (navigator)->current_directory;
453
thunar_location_buttons_set_current_directory (ThunarNavigator *navigator,
454
ThunarFile *current_directory)
456
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (navigator);
457
ThunarFile *file_parent;
462
_thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory));
464
/* verify that we're not already using the new directory */
465
if (G_UNLIKELY (buttons->current_directory == current_directory))
468
/* check if we already have a button for that directory */
469
for (lp = buttons->list; lp != NULL; lp = lp->next)
470
if (thunar_location_button_get_file (lp->data) == current_directory)
473
/* if we already have a button for that directory, just activate it */
474
if (G_UNLIKELY (lp != NULL))
476
/* fake a "clicked" event for that button */
477
thunar_location_button_clicked (THUNAR_LOCATION_BUTTON (lp->data));
481
/* regenerate the button list */
482
if (G_LIKELY (buttons->current_directory != NULL))
484
g_object_unref (G_OBJECT (buttons->current_directory));
486
/* remove all buttons */
487
while (buttons->list != NULL)
488
gtk_container_remove (GTK_CONTAINER (buttons), buttons->list->data);
490
/* clear the first scrolled and fake root buttons */
491
buttons->first_scrolled_button = NULL;
492
buttons->fake_root_button = NULL;
495
buttons->current_directory = current_directory;
497
if (G_LIKELY (current_directory != NULL))
499
g_object_ref (G_OBJECT (current_directory));
501
gtk_widget_push_composite_child ();
503
/* add the new buttons */
504
for (file = current_directory; file != NULL; file = file_parent)
506
button = thunar_location_buttons_make_button (buttons, file);
507
buttons->list = g_list_append (buttons->list, button);
508
gtk_container_add (GTK_CONTAINER (buttons), button);
509
gtk_widget_show (button);
511
/* use 'Home' as fake root button */
512
if (thunar_file_is_home (file))
513
buttons->fake_root_button = g_list_last (buttons->list);
515
/* continue with the parent (if any) */
516
file_parent = thunar_file_get_parent (file, NULL);
518
if (G_LIKELY (file != current_directory))
519
g_object_unref (G_OBJECT (file));
522
gtk_widget_pop_composite_child ();
526
g_object_notify (G_OBJECT (buttons), "current-directory");
532
thunar_location_buttons_unmap (GtkWidget *widget)
534
/* be sure to stop the scroll timer before the buttons are unmapped */
535
thunar_location_buttons_stop_scrolling (THUNAR_LOCATION_BUTTONS (widget));
537
/* do the real unmap */
538
(*GTK_WIDGET_CLASS (thunar_location_buttons_parent_class)->unmap) (widget);
544
thunar_location_buttons_size_request (GtkWidget *widget,
545
GtkRequisition *requisition)
547
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (widget);
548
GtkRequisition child_requisition;
552
gtk_widget_style_get (GTK_WIDGET (buttons),
556
requisition->width = 0;
557
requisition->height = 0;
559
/* calculate the size of the biggest button */
560
for (lp = buttons->list; lp != NULL; lp = lp->next)
562
gtk_widget_size_request (GTK_WIDGET (lp->data), &child_requisition);
563
requisition->width = MAX (child_requisition.width, requisition->width);
564
requisition->height = MAX (child_requisition.height, requisition->height);
567
/* add space for the sliders if we have more than one path */
568
buttons->slider_width = MIN (requisition->height * 2 / 3 + 5, requisition->height);
569
if (buttons->list != NULL && buttons->list->next != NULL)
570
requisition->width += (spacing + buttons->slider_width) * 2;
572
gtk_widget_size_request (buttons->left_slider, &child_requisition);
573
gtk_widget_size_request (buttons->right_slider, &child_requisition);
575
requisition->width += GTK_CONTAINER (widget)->border_width * 2;
576
requisition->height += GTK_CONTAINER (widget)->border_width * 2;
578
widget->requisition = *requisition;
584
thunar_location_buttons_size_allocate (GtkWidget *widget,
585
GtkAllocation *allocation)
587
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (widget);
588
GtkTextDirection direction;
589
GtkAllocation child_allocation;
591
gboolean need_sliders = FALSE;
592
gboolean reached_end;
595
gint left_slider_offset = 0;
596
gint right_slider_offset = 0;
597
gint allocation_width;
603
widget->allocation = *allocation;
605
/* if no path is set, we don't have to allocate anything */
606
if (G_UNLIKELY (buttons->list == NULL))
609
gtk_widget_style_get (GTK_WIDGET (buttons), "spacing", &spacing, NULL);
611
direction = gtk_widget_get_direction (widget);
612
border_width = GTK_CONTAINER (buttons)->border_width;
613
allocation_width = allocation->width - 2 * border_width;
615
/* check if we need to display the sliders */
616
if (G_LIKELY (buttons->fake_root_button != NULL))
617
width = buttons->slider_width + spacing;
621
for (lp = buttons->list; lp != NULL; lp = lp->next)
623
width += GTK_WIDGET (lp->data)->requisition.width + spacing;
624
if (lp == buttons->fake_root_button)
628
if (width <= allocation_width)
630
if (G_LIKELY (buttons->fake_root_button != NULL))
631
first_button = buttons->fake_root_button;
633
first_button = g_list_last (buttons->list);
637
slider_space = 2 * (spacing + buttons->slider_width);
639
if (buttons->first_scrolled_button != NULL)
640
first_button = buttons->first_scrolled_button;
642
first_button = buttons->list;
645
/* To see how much space we have, and how many buttons we can display.
646
* We start at the first button, count forward until hit the new
647
* button, then count backwards.
649
width = GTK_WIDGET (first_button->data)->requisition.width;
650
for (lp = first_button->prev, reached_end = FALSE; lp != NULL && !reached_end; lp = lp->prev)
653
if (width + child->requisition.width + spacing + slider_space > allocation_width)
655
else if (lp == buttons->fake_root_button)
658
width += child->requisition.width + spacing;
661
while (first_button->next != NULL && !reached_end)
663
child = first_button->data;
664
if (width + child->requisition.width + spacing + slider_space > allocation_width)
670
width += child->requisition.width + spacing;
671
if (first_button == buttons->fake_root_button)
673
first_button = first_button->next;
678
/* Now we allocate space to the buttons */
679
child_allocation.y = allocation->y + border_width;
680
child_allocation.height = MAX (1, allocation->height - border_width * 2);
682
if (G_UNLIKELY (direction == GTK_TEXT_DIR_RTL))
684
child_allocation.x = allocation->x + allocation->width - border_width;
685
if (need_sliders || buttons->fake_root_button != NULL)
687
child_allocation.x -= spacing + buttons->slider_width;
688
left_slider_offset = allocation->width - border_width - buttons->slider_width;
693
child_allocation.x = allocation->x + border_width;
694
if (need_sliders || buttons->fake_root_button != NULL)
696
left_slider_offset = border_width;
697
child_allocation.x += spacing + buttons->slider_width;
701
for (lp = first_button; lp != NULL; lp = lp->prev)
705
child_allocation.width = child->requisition.width;
706
if (G_UNLIKELY (direction == GTK_TEXT_DIR_RTL))
707
child_allocation.x -= child_allocation.width;
709
/* check to see if we don't have any more space to allocate buttons */
710
if (need_sliders && direction == GTK_TEXT_DIR_RTL)
712
if (child_allocation.x - spacing - buttons->slider_width < widget->allocation.x + border_width)
715
else if (need_sliders && direction == GTK_TEXT_DIR_LTR)
717
if (child_allocation.x + child_allocation.width + spacing + buttons->slider_width > widget->allocation.x + border_width + allocation_width)
721
gtk_widget_set_child_visible (GTK_WIDGET (lp->data), TRUE);
722
gtk_widget_size_allocate (child, &child_allocation);
724
if (direction == GTK_TEXT_DIR_RTL)
726
child_allocation.x -= spacing;
727
right_slider_offset = border_width;
731
child_allocation.x += child_allocation.width + spacing;
732
right_slider_offset = allocation->width - border_width - buttons->slider_width;
736
/* now we go hide all the buttons that don't fit */
737
for (; lp != NULL; lp = lp->prev)
738
gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE);
739
for (lp = first_button->next; lp != NULL; lp = lp->next)
740
gtk_widget_set_child_visible (GTK_WIDGET (lp->data), FALSE);
742
if (need_sliders || buttons->fake_root_button != NULL)
744
child_allocation.width = buttons->slider_width;
745
child_allocation.x = left_slider_offset + allocation->x;
746
gtk_widget_size_allocate (buttons->left_slider, &child_allocation);
747
gtk_widget_set_child_visible (buttons->left_slider, TRUE);
748
gtk_widget_show_all (buttons->left_slider);
750
thunar_location_buttons_update_sliders (buttons);
754
gtk_widget_set_child_visible (buttons->left_slider, FALSE);
759
child_allocation.width = buttons->slider_width;
760
child_allocation.x = right_slider_offset + allocation->x;
761
gtk_widget_size_allocate (buttons->right_slider, &child_allocation);
762
gtk_widget_set_child_visible (buttons->right_slider, TRUE);
763
gtk_widget_show_all (buttons->right_slider);
765
thunar_location_buttons_update_sliders (buttons);
769
gtk_widget_set_child_visible (buttons->right_slider, FALSE);
776
thunar_location_buttons_state_changed (GtkWidget *widget,
777
GtkStateType previous_state)
779
if (!gtk_widget_is_sensitive (widget))
780
thunar_location_buttons_stop_scrolling (THUNAR_LOCATION_BUTTONS (widget));
786
thunar_location_buttons_grab_notify (GtkWidget *widget,
787
gboolean was_grabbed)
789
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (widget);
792
thunar_location_buttons_stop_scrolling (buttons);
798
thunar_location_buttons_add (GtkContainer *container,
801
gtk_widget_set_parent (widget, GTK_WIDGET (container));
807
thunar_location_buttons_remove (GtkContainer *container,
810
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (container);
813
if (widget == buttons->left_slider)
815
thunar_location_buttons_remove_1 (container, widget);
816
buttons->left_slider = NULL;
819
else if (widget == buttons->right_slider)
821
thunar_location_buttons_remove_1 (container, widget);
822
buttons->right_slider = NULL;
826
for (lp = buttons->list; lp != NULL; lp = lp->next)
827
if (widget == GTK_WIDGET (lp->data))
829
thunar_location_buttons_remove_1 (container, widget);
830
buttons->list = g_list_remove_link (buttons->list, lp);
839
thunar_location_buttons_forall (GtkContainer *container,
840
gboolean include_internals,
841
GtkCallback callback,
842
gpointer callback_data)
844
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (container);
848
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
849
_thunar_return_if_fail (callback != NULL);
851
for (lp = buttons->list; lp != NULL; )
853
child = GTK_WIDGET (lp->data);
856
(*callback) (child, callback_data);
859
if (buttons->left_slider != NULL && include_internals)
860
(*callback) (buttons->left_slider, callback_data);
862
if (buttons->right_slider != NULL && include_internals)
863
(*callback) (buttons->right_slider, callback_data);
869
thunar_location_buttons_make_button (ThunarLocationButtons *buttons,
874
/* allocate the button */
875
button = thunar_location_button_new ();
877
/* connect to the file */
878
thunar_location_button_set_file (THUNAR_LOCATION_BUTTON (button), file);
880
/* the current directory is active */
881
thunar_location_button_set_active (THUNAR_LOCATION_BUTTON (button), (file == buttons->current_directory));
883
/* connect signal handlers */
884
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (thunar_location_buttons_clicked), buttons);
885
g_signal_connect (G_OBJECT (button), "gone", G_CALLBACK (thunar_location_buttons_gone), buttons);
886
g_signal_connect (G_OBJECT (button), "context-menu", G_CALLBACK (thunar_location_buttons_context_menu), buttons);
894
thunar_location_buttons_remove_1 (GtkContainer *container,
897
gboolean need_resize = gtk_widget_get_visible (widget);
898
gtk_widget_unparent (widget);
899
if (G_LIKELY (need_resize))
900
gtk_widget_queue_resize (GTK_WIDGET (container));
906
thunar_location_buttons_scroll_timeout (gpointer user_data)
908
ThunarLocationButtons *buttons = THUNAR_LOCATION_BUTTONS (user_data);
910
GDK_THREADS_ENTER ();
912
if (gtk_widget_has_focus (buttons->left_slider))
913
thunar_location_buttons_scroll_left (buttons->left_slider, buttons);
914
else if (gtk_widget_has_focus (buttons->right_slider))
915
thunar_location_buttons_scroll_right (buttons->right_slider, buttons);
917
GDK_THREADS_LEAVE ();
925
thunar_location_buttons_scroll_timeout_destroy (gpointer user_data)
927
THUNAR_LOCATION_BUTTONS (user_data)->scroll_timeout_id = 0;
933
thunar_location_buttons_stop_scrolling (ThunarLocationButtons *buttons)
935
if (buttons->scroll_timeout_id != 0)
936
g_source_remove (buttons->scroll_timeout_id);
942
thunar_location_buttons_update_sliders (ThunarLocationButtons *buttons)
946
if (G_LIKELY (buttons->list != NULL))
948
button = GTK_WIDGET (buttons->list->data);
949
if (gtk_widget_get_child_visible (button))
951
gtk_widget_set_sensitive (buttons->right_slider, FALSE);
952
thunar_location_buttons_stop_scrolling (buttons);
956
gtk_widget_set_sensitive (buttons->right_slider, TRUE);
959
button = GTK_WIDGET (g_list_last (buttons->list)->data);
960
if (gtk_widget_get_child_visible (button) && buttons->fake_root_button == NULL)
962
gtk_widget_set_sensitive (buttons->left_slider, FALSE);
963
thunar_location_buttons_stop_scrolling (buttons);
967
gtk_widget_set_sensitive (buttons->left_slider, TRUE);
975
thunar_location_buttons_slider_button_press (GtkWidget *button,
976
GdkEventButton *event,
977
ThunarLocationButtons *buttons)
979
if (!gtk_widget_has_focus (button))
980
gtk_widget_grab_focus (button);
982
if (event->type != GDK_BUTTON_PRESS || event->button != 1)
985
buttons->ignore_click = FALSE;
987
if (button == buttons->left_slider)
988
thunar_location_buttons_scroll_left (button, buttons);
989
else if (button == buttons->right_slider)
990
thunar_location_buttons_scroll_right (button, buttons);
992
if (G_LIKELY (buttons->scroll_timeout_id == 0))
994
buttons->scroll_timeout_id = g_timeout_add_full (G_PRIORITY_LOW, THUNAR_LOCATION_BUTTONS_SCROLL_TIMEOUT,
995
thunar_location_buttons_scroll_timeout, buttons,
996
thunar_location_buttons_scroll_timeout_destroy);
1005
thunar_location_buttons_slider_button_release (GtkWidget *button,
1006
GdkEventButton *event,
1007
ThunarLocationButtons *buttons)
1009
if (event->type == GDK_BUTTON_RELEASE)
1011
thunar_location_buttons_stop_scrolling (buttons);
1012
buttons->ignore_click = TRUE;
1021
thunar_location_buttons_scroll_left (GtkWidget *button,
1022
ThunarLocationButtons *buttons)
1026
if (G_UNLIKELY (buttons->ignore_click))
1028
buttons->ignore_click = FALSE;
1032
gtk_widget_queue_resize (GTK_WIDGET (buttons));
1034
for (lp = g_list_last (buttons->list); lp != NULL; lp = lp->prev)
1035
if (lp->prev != NULL && gtk_widget_get_child_visible (GTK_WIDGET (lp->prev->data)))
1037
if (lp->prev == buttons->fake_root_button)
1038
buttons->fake_root_button = NULL;
1039
buttons->first_scrolled_button = lp;
1047
thunar_location_buttons_scroll_right (GtkWidget *button,
1048
ThunarLocationButtons *buttons)
1050
GtkTextDirection direction;
1051
GList *right_button = NULL;
1052
GList *left_button = NULL;
1054
gint space_available;
1059
if (G_UNLIKELY (buttons->ignore_click))
1061
buttons->ignore_click = FALSE;
1065
gtk_widget_style_get (GTK_WIDGET (buttons),
1066
"spacing", &spacing,
1069
gtk_widget_queue_resize (GTK_WIDGET (buttons));
1071
border_width = GTK_CONTAINER (buttons)->border_width;
1072
direction = gtk_widget_get_direction (GTK_WIDGET (buttons));
1074
/* find the button at the 'right' end that we have to make visible */
1075
for (lp = buttons->list; lp != NULL; lp = lp->next)
1076
if (lp->next != NULL && gtk_widget_get_child_visible (GTK_WIDGET (lp->next->data)))
1082
/* find the last visible button on the 'left' end */
1083
for (lp = g_list_last (buttons->list); lp != NULL; lp = lp->prev)
1084
if (gtk_widget_get_child_visible (GTK_WIDGET (lp->data)))
1090
space_needed = GTK_WIDGET (right_button->data)->allocation.width + spacing;
1091
if (direction == GTK_TEXT_DIR_RTL)
1093
space_available = buttons->right_slider->allocation.x - GTK_WIDGET (buttons)->allocation.x;
1097
space_available = (GTK_WIDGET (buttons)->allocation.x + GTK_WIDGET (buttons)->allocation.width - border_width)
1098
- (buttons->right_slider->allocation.x + buttons->right_slider->allocation.width);
1101
/* We have space_available extra space that's not being used. We
1102
* need space_needed space to make the button fit. So we walk down
1103
* from the end, removing buttons until we get all the space we
1106
while (space_available < space_needed)
1108
space_available += GTK_WIDGET (left_button->data)->allocation.width + spacing;
1109
left_button = left_button->prev;
1110
buttons->first_scrolled_button = left_button;
1117
thunar_location_buttons_clicked (ThunarLocationButton *button,
1118
gboolean open_in_tab,
1119
ThunarLocationButtons *buttons)
1121
ThunarFile *directory;
1124
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button));
1125
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1127
/* determine the directory associated with the clicked button */
1128
directory = thunar_location_button_get_file (button);
1133
thunar_navigator_open_new_tab (THUNAR_NAVIGATOR (buttons), directory);
1137
/* disconnect from previous current directory (if any) */
1138
if (G_LIKELY (buttons->current_directory != NULL))
1139
g_object_unref (G_OBJECT (buttons->current_directory));
1141
/* setup the new current directory */
1142
buttons->current_directory = directory;
1144
/* take a reference on the new directory (if any) */
1145
if (G_LIKELY (directory != NULL))
1146
g_object_ref (G_OBJECT (directory));
1148
/* check if the button is visible on the button bar */
1149
if (!gtk_widget_get_child_visible (GTK_WIDGET (button)))
1151
/* scroll to the button */
1152
buttons->first_scrolled_button = g_list_find (buttons->list, button);
1153
gtk_widget_queue_resize (GTK_WIDGET (buttons));
1155
/* we may need to reset the fake_root_button */
1156
if (G_LIKELY (buttons->fake_root_button != NULL))
1158
/* check if the fake_root_button is before the first_scrolled_button (from right to left) */
1159
for (lp = buttons->list; lp != NULL && lp != buttons->first_scrolled_button; lp = lp->next)
1160
if (lp == buttons->fake_root_button)
1162
/* reset the fake_root_button */
1163
buttons->fake_root_button = NULL;
1169
/* update all buttons */
1170
for (lp = buttons->list; lp != NULL; lp = lp->next)
1172
/* determine the directory for this button */
1173
button = THUNAR_LOCATION_BUTTON (lp->data);
1174
directory = thunar_location_button_get_file (button);
1176
/* update the location button state (making sure to not recurse with the "clicked" handler) */
1177
g_signal_handlers_block_by_func (G_OBJECT (button), thunar_location_buttons_clicked, buttons);
1178
thunar_location_button_set_active (button, directory == buttons->current_directory);
1179
g_signal_handlers_unblock_by_func (G_OBJECT (button), thunar_location_buttons_clicked, buttons);
1182
/* notify the surrounding module that we want to change to a different directory. */
1183
thunar_navigator_change_directory (THUNAR_NAVIGATOR (buttons), buttons->current_directory);
1189
thunar_location_buttons_gone (ThunarLocationButton *button,
1190
ThunarLocationButtons *buttons)
1192
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button));
1193
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1194
_thunar_return_if_fail (g_list_find (buttons->list, button) != NULL);
1196
/* drop all buttons up to the button that emitted the "gone" signal */
1197
while (buttons->list->data != button)
1198
gtk_widget_destroy (buttons->list->data);
1200
/* drop the button itself */
1201
gtk_widget_destroy (GTK_WIDGET (button));
1207
thunar_location_buttons_context_menu (ThunarLocationButton *button,
1208
GdkEventButton *event,
1209
ThunarLocationButtons *buttons)
1211
ThunarClipboardManager *clipboard;
1212
const gchar *display_name;
1217
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1218
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTON (button));
1220
/* determine the file for the button */
1221
file = thunar_location_button_get_file (button);
1222
if (G_LIKELY (file != NULL))
1224
/* we cannot popup the context menu without an ui manager */
1225
if (G_LIKELY (buttons->ui_manager != NULL))
1227
/* determine the display name of the file */
1228
display_name = thunar_file_get_display_name (file);
1230
/* be sure to keep a reference on the navigation bar */
1231
g_object_ref (G_OBJECT (buttons));
1233
/* grab a reference on the clipboard manager for this display */
1234
clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons)));
1236
/* setup the "Open" action */
1237
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open");
1238
thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in this window"), display_name);
1239
g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
1240
gtk_action_set_sensitive (action, (file != buttons->current_directory));
1242
/* setup the "Open in New Window" action */
1243
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open-in-new-window");
1244
thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in a new window"), display_name);
1245
g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
1247
/* setup the "Open in New Tab" action */
1248
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-open-in-new-tab");
1249
thunar_gtk_action_set_tooltip (action, _("Open \"%s\" in a new tab"), display_name);
1250
g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
1252
/* setup the "Create Folder..." action */
1253
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-create-folder");
1254
thunar_gtk_action_set_tooltip (action, _("Create a new folder in \"%s\""), display_name);
1255
g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
1256
gtk_action_set_sensitive (action, thunar_file_is_writable (file));
1257
gtk_action_set_visible (action, !thunar_file_is_trashed (file));
1259
/* setup the "Empty Trash" action */
1260
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-empty-trash");
1261
gtk_action_set_visible (action, (thunar_file_is_root (file) && thunar_file_is_trashed (file)));
1262
gtk_action_set_sensitive (action, (thunar_file_get_size (file) > 0));
1264
/* setup the "Paste Into Folder" action */
1265
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-paste-into-folder");
1266
thunar_gtk_action_set_tooltip (action, _("Move or copy files previously selected by a Cut or Copy command into \"%s\""), display_name);
1267
g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
1268
gtk_action_set_sensitive (action, thunar_clipboard_manager_get_can_paste (clipboard));
1270
/* setup the "Properties..." action */
1271
action = gtk_action_group_get_action (buttons->action_group, "location-buttons-properties");
1272
thunar_gtk_action_set_tooltip (action, _("View the properties of the folder \"%s\""), display_name);
1273
g_object_set_qdata_full (G_OBJECT (action), thunar_file_quark, g_object_ref (G_OBJECT (file)), (GDestroyNotify) g_object_unref);
1275
/* run the menu on the screen on the buttons' screen */
1276
menu = gtk_ui_manager_get_widget (buttons->ui_manager, "/location-buttons-context-menu");
1277
thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (buttons), NULL, NULL, event->button, event->time);
1280
g_object_unref (G_OBJECT (buttons));
1281
g_object_unref (G_OBJECT (clipboard));
1289
thunar_location_buttons_action_create_folder (GtkAction *action,
1290
ThunarLocationButtons *buttons)
1292
ThunarApplication *application;
1293
ThunarFile *directory;
1297
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1298
_thunar_return_if_fail (GTK_IS_ACTION (action));
1300
/* determine the directory for the action */
1301
directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark);
1302
if (G_UNLIKELY (directory == NULL))
1305
/* ask the user to enter a name for the new folder */
1306
name = thunar_show_create_dialog (GTK_WIDGET (buttons),
1309
_("Create New Folder"));
1310
if (G_LIKELY (name != NULL))
1312
/* fake the path list */
1313
path_list.data = g_file_resolve_relative_path (thunar_file_get_file (directory), name);
1314
path_list.next = path_list.prev = NULL;
1316
/* launch the operation */
1317
application = thunar_application_get ();
1318
thunar_application_mkdir (application, GTK_WIDGET (buttons), &path_list, NULL);
1319
g_object_unref (G_OBJECT (application));
1321
/* release the path */
1322
g_object_unref (path_list.data);
1324
/* release the file name */
1332
thunar_location_buttons_action_down_folder (GtkAction *action,
1333
ThunarLocationButtons *buttons)
1337
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1338
_thunar_return_if_fail (GTK_IS_ACTION (action));
1340
/* lookup the active button */
1341
for (lp = buttons->list; lp != NULL; lp = lp->next)
1342
if (thunar_location_button_get_active (lp->data))
1344
/* check if we have a folder below that one */
1345
if (G_LIKELY (lp->prev != NULL))
1347
/* enter that folder */
1348
thunar_location_button_clicked (lp->prev->data);
1358
thunar_location_buttons_action_empty_trash (GtkAction *action,
1359
ThunarLocationButtons *buttons)
1361
ThunarApplication *application;
1363
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1364
_thunar_return_if_fail (GTK_IS_ACTION (action));
1366
/* launch the operation */
1367
application = thunar_application_get ();
1368
thunar_application_empty_trash (application, GTK_WIDGET (buttons), NULL);
1369
g_object_unref (G_OBJECT (application));
1375
thunar_location_buttons_action_open (GtkAction *action,
1376
ThunarLocationButtons *buttons)
1378
ThunarFile *directory;
1380
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1381
_thunar_return_if_fail (GTK_IS_ACTION (action));
1383
/* determine the directory for the action */
1384
directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark);
1385
if (G_LIKELY (directory != NULL && thunar_file_is_directory (directory)))
1387
/* open the folder in this window */
1388
thunar_navigator_change_directory (THUNAR_NAVIGATOR (buttons), directory);
1395
thunar_location_buttons_action_open_in_new_tab (GtkAction *action,
1396
ThunarLocationButtons *buttons)
1398
ThunarFile *directory;
1400
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1401
_thunar_return_if_fail (GTK_IS_ACTION (action));
1403
/* determine the directory for the action */
1404
directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark);
1405
if (G_LIKELY (directory != NULL))
1407
/* open tab in thsi window */
1408
thunar_navigator_open_new_tab (THUNAR_NAVIGATOR (buttons), directory);
1415
thunar_location_buttons_action_open_in_new_window (GtkAction *action,
1416
ThunarLocationButtons *buttons)
1418
ThunarApplication *application;
1419
ThunarFile *directory;
1421
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1422
_thunar_return_if_fail (GTK_IS_ACTION (action));
1424
/* determine the directory for the action */
1425
directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark);
1426
if (G_LIKELY (directory != NULL))
1428
/* open a new window for the directory */
1429
application = thunar_application_get ();
1430
thunar_application_open_window (application, directory, gtk_widget_get_screen (GTK_WIDGET (buttons)), NULL);
1431
g_object_unref (G_OBJECT (application));
1438
thunar_location_buttons_action_paste_into_folder (GtkAction *action,
1439
ThunarLocationButtons *buttons)
1441
ThunarClipboardManager *clipboard;
1442
ThunarFile *directory;
1444
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1445
_thunar_return_if_fail (GTK_IS_ACTION (action));
1447
/* determine the directory for the action */
1448
directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark);
1449
if (G_LIKELY (directory != NULL))
1451
/* paste files from the clipboard to the folder represented by this button */
1452
clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (GTK_WIDGET (buttons)));
1453
thunar_clipboard_manager_paste_files (clipboard, thunar_file_get_file (directory), GTK_WIDGET (buttons), NULL);
1454
g_object_unref (G_OBJECT (clipboard));
1461
thunar_location_buttons_action_properties (GtkAction *action,
1462
ThunarLocationButtons *buttons)
1464
ThunarFile *directory;
1465
GtkWidget *toplevel;
1468
_thunar_return_if_fail (THUNAR_IS_LOCATION_BUTTONS (buttons));
1469
_thunar_return_if_fail (GTK_IS_ACTION (action));
1471
/* determine the directory for the action */
1472
directory = g_object_get_qdata (G_OBJECT (action), thunar_file_quark);
1473
if (G_LIKELY (directory != NULL))
1475
/* determine the toplevel window */
1476
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (buttons));
1477
if (G_LIKELY (toplevel != NULL && gtk_widget_get_toplevel (toplevel)))
1479
/* popup the properties dialog */
1480
dialog = thunar_properties_dialog_new (GTK_WINDOW (toplevel));
1481
thunar_properties_dialog_set_file (THUNAR_PROPERTIES_DIALOG (dialog), directory);
1482
gtk_widget_show (dialog);