1
/* vi:set et ai sw=2 sts=2 ts=2: */
3
* Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org>
4
* Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org>
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License as
8
* published by the Free Software Foundation; either version 2 of
9
* the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public
17
* License along with this program; if not, write to the Free
18
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
* Boston, MA 02110-1301, USA.
33
#include <gdk/gdkkeysyms.h>
34
#include <libxfce4ui/libxfce4ui.h>
36
#include <thunar/thunar-application.h>
37
#include <thunar/thunar-browser.h>
38
#include <thunar/thunar-clipboard-manager.h>
39
#include <thunar/thunar-compact-view.h>
40
#include <thunar/thunar-details-view.h>
41
#include <thunar/thunar-dialogs.h>
42
#include <thunar/thunar-shortcuts-pane.h>
43
#include <thunar/thunar-gio-extensions.h>
44
#include <thunar/thunar-gobject-extensions.h>
45
#include <thunar/thunar-gtk-extensions.h>
46
#include <thunar/thunar-icon-view.h>
47
#include <thunar/thunar-launcher.h>
48
#include <thunar/thunar-location-buttons.h>
49
#include <thunar/thunar-location-dialog.h>
50
#include <thunar/thunar-location-entry.h>
51
#include <thunar/thunar-marshal.h>
52
#include <thunar/thunar-pango-extensions.h>
53
#include <thunar/thunar-preferences-dialog.h>
54
#include <thunar/thunar-preferences.h>
55
#include <thunar/thunar-private.h>
56
#include <thunar/thunar-util.h>
57
#include <thunar/thunar-statusbar.h>
58
#include <thunar/thunar-stock.h>
59
#include <thunar/thunar-trash-action.h>
60
#include <thunar/thunar-tree-pane.h>
61
#include <thunar/thunar-window.h>
62
#include <thunar/thunar-window-ui.h>
63
#include <thunar/thunar-device-monitor.h>
69
/* Property identifiers */
73
PROP_CURRENT_DIRECTORY,
79
/* Signal identifiers */
95
static void thunar_window_dispose (GObject *object);
96
static void thunar_window_finalize (GObject *object);
97
static void thunar_window_get_property (GObject *object,
101
static void thunar_window_set_property (GObject *object,
105
static gboolean thunar_window_back (ThunarWindow *window);
106
static gboolean thunar_window_reload (ThunarWindow *window);
107
static gboolean thunar_window_toggle_sidepane (ThunarWindow *window);
108
static gboolean thunar_window_toggle_menubar (ThunarWindow *window);
109
static void thunar_window_toggle_menubar_deactivate (GtkWidget *menubar,
110
ThunarWindow *window);
111
static gboolean thunar_window_zoom_in (ThunarWindow *window);
112
static gboolean thunar_window_zoom_out (ThunarWindow *window);
113
static gboolean thunar_window_zoom_reset (ThunarWindow *window);
114
static gboolean thunar_window_tab_change (ThunarWindow *window,
116
static void thunar_window_realize (GtkWidget *widget);
117
static void thunar_window_unrealize (GtkWidget *widget);
118
static gboolean thunar_window_configure_event (GtkWidget *widget,
119
GdkEventConfigure *event);
120
static void thunar_window_notebook_switch_page (GtkWidget *notebook,
123
ThunarWindow *window);
124
static void thunar_window_notebook_page_added (GtkWidget *notebook,
127
ThunarWindow *window);
128
static void thunar_window_notebook_page_removed (GtkWidget *notebook,
131
ThunarWindow *window);
132
static gboolean thunar_window_notebook_button_press_event (GtkWidget *notebook,
133
GdkEventButton *event,
134
ThunarWindow *window);
135
static gboolean thunar_window_notebook_popup_menu (GtkWidget *notebook,
136
ThunarWindow *window);
137
static gpointer thunar_window_notebook_create_window (GtkWidget *notebook,
141
ThunarWindow *window);
142
static void thunar_window_notebook_insert (ThunarWindow *window,
143
ThunarFile *directory);
144
static void thunar_window_merge_custom_preferences (ThunarWindow *window);
145
static gboolean thunar_window_bookmark_merge (gpointer user_data);
146
static void thunar_window_merge_go_actions (ThunarWindow *window);
147
static void thunar_window_install_location_bar (ThunarWindow *window,
149
static void thunar_window_install_sidepane (ThunarWindow *window,
151
static void thunar_window_start_open_location (ThunarWindow *window,
152
const gchar *initial_text);
153
static void thunar_window_action_open_new_tab (GtkAction *action,
154
ThunarWindow *window);
155
static void thunar_window_action_open_new_window (GtkAction *action,
156
ThunarWindow *window);
157
static void thunar_window_action_empty_trash (GtkAction *action,
158
ThunarWindow *window);
159
static void thunar_window_action_detach_tab (GtkAction *action,
160
ThunarWindow *window);
161
static void thunar_window_action_close_all_windows (GtkAction *action,
162
ThunarWindow *window);
163
static void thunar_window_action_close_tab (GtkAction *action,
164
ThunarWindow *window);
165
static void thunar_window_action_close_window (GtkAction *action,
166
ThunarWindow *window);
167
static void thunar_window_action_preferences (GtkAction *action,
168
ThunarWindow *window);
169
static void thunar_window_action_reload (GtkAction *action,
170
ThunarWindow *window);
171
static void thunar_window_action_pathbar_changed (GtkToggleAction *action,
172
ThunarWindow *window);
173
static void thunar_window_action_toolbar_changed (GtkToggleAction *action,
174
ThunarWindow *window);
175
static void thunar_window_action_shortcuts_changed (GtkToggleAction *action,
176
ThunarWindow *window);
177
static void thunar_window_action_tree_changed (GtkToggleAction *action,
178
ThunarWindow *window);
179
static void thunar_window_action_statusbar_changed (GtkToggleAction *action,
180
ThunarWindow *window);
181
static void thunar_window_action_menubar_changed (GtkToggleAction *action,
182
ThunarWindow *window);
183
static void thunar_window_action_zoom_in (GtkAction *action,
184
ThunarWindow *window);
185
static void thunar_window_action_zoom_out (GtkAction *action,
186
ThunarWindow *window);
187
static void thunar_window_action_zoom_reset (GtkAction *action,
188
ThunarWindow *window);
189
static void thunar_window_action_view_changed (GtkRadioAction *action,
190
GtkRadioAction *current,
191
ThunarWindow *window);
192
static void thunar_window_action_go_up (GtkAction *action,
193
ThunarWindow *window);
194
static void thunar_window_action_open_home (GtkAction *action,
195
ThunarWindow *window);
196
static void thunar_window_action_open_desktop (GtkAction *action,
197
ThunarWindow *window);
198
static void thunar_window_action_open_templates (GtkAction *action,
199
ThunarWindow *window);
200
static void thunar_window_action_open_file_system (GtkAction *action,
201
ThunarWindow *window);
202
static void thunar_window_action_open_trash (GtkAction *action,
203
ThunarWindow *window);
204
static void thunar_window_action_open_network (GtkAction *action,
205
ThunarWindow *window);
206
static void thunar_window_action_open_bookmark (GtkAction *action,
207
ThunarWindow *window);
208
static void thunar_window_action_open_location (GtkAction *action,
209
ThunarWindow *window);
210
static void thunar_window_action_contents (GtkAction *action,
211
ThunarWindow *window);
212
static void thunar_window_action_about (GtkAction *action,
213
ThunarWindow *window);
214
static void thunar_window_action_show_hidden (GtkToggleAction *action,
215
ThunarWindow *window);
216
static void thunar_window_current_directory_changed (ThunarFile *current_directory,
217
ThunarWindow *window);
218
static void thunar_window_connect_proxy (GtkUIManager *manager,
221
ThunarWindow *window);
222
static void thunar_window_disconnect_proxy (GtkUIManager *manager,
225
ThunarWindow *window);
226
static void thunar_window_menu_item_selected (GtkWidget *menu_item,
227
ThunarWindow *window);
228
static void thunar_window_menu_item_deselected (GtkWidget *menu_item,
229
ThunarWindow *window);
230
static void thunar_window_update_custom_actions (ThunarView *view,
232
ThunarWindow *window);
233
static void thunar_window_notify_loading (ThunarView *view,
235
ThunarWindow *window);
236
static void thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor,
237
ThunarDevice *device,
239
ThunarWindow *window);
240
static void thunar_window_device_changed (ThunarDeviceMonitor *device_monitor,
241
ThunarDevice *device,
242
ThunarWindow *window);
243
static gboolean thunar_window_merge_idle (gpointer user_data);
244
static void thunar_window_merge_idle_destroy (gpointer user_data);
245
static gboolean thunar_window_save_paned (ThunarWindow *window);
246
static gboolean thunar_window_save_geometry_timer (gpointer user_data);
247
static void thunar_window_save_geometry_timer_destroy (gpointer user_data);
248
static void thunar_window_set_zoom_level (ThunarWindow *window,
249
ThunarZoomLevel zoom_level);
253
struct _ThunarWindowClass
255
GtkWindowClass __parent__;
257
/* internal action signals */
258
gboolean (*back) (ThunarWindow *window);
259
gboolean (*reload) (ThunarWindow *window);
260
gboolean (*toggle_sidepane) (ThunarWindow *window);
261
gboolean (*toggle_menubar) (ThunarWindow *window);
262
gboolean (*zoom_in) (ThunarWindow *window);
263
gboolean (*zoom_out) (ThunarWindow *window);
264
gboolean (*zoom_reset) (ThunarWindow *window);
265
gboolean (*tab_change) (ThunarWindow *window,
271
GtkWindow __parent__;
273
/* support for custom preferences actions */
274
ThunarxProviderFactory *provider_factory;
275
guint custom_preferences_merge_id;
277
/* UI manager merge ID for go menu actions */
278
guint go_items_actions_merge_id;
280
/* UI manager merge ID for the bookmark actions */
281
guint bookmark_items_actions_merge_id;
282
GtkActionGroup *bookmark_action_group;
283
GFile *bookmark_file;
284
GFileMonitor *bookmark_monitor;
285
guint bookmark_reload_idle_id;
287
ThunarClipboardManager *clipboard;
289
ThunarPreferences *preferences;
291
ThunarIconFactory *icon_factory;
293
GtkActionGroup *action_group;
294
GtkUIManager *ui_manager;
296
/* to be able to change folder on "device-pre-unmount" if required */
297
ThunarDeviceMonitor *device_monitor;
299
/* closures for the menu_item_selected()/menu_item_deselected() callbacks */
300
GClosure *menu_item_selected_closure;
301
GClosure *menu_item_deselected_closure;
303
/* custom menu actions for the file menu */
304
GtkActionGroup *custom_actions;
305
guint custom_merge_id;
315
GtkWidget *statusbar;
318
GSList *view_bindings;
320
/* support for two different styles of location bars */
321
GtkWidget *location_bar;
322
GtkWidget *location_toolbar;
324
ThunarLauncher *launcher;
326
ThunarFile *current_directory;
328
/* zoom-level support */
329
ThunarZoomLevel zoom_level;
331
/* menu merge idle source */
334
/* support to remember window geometry */
335
guint save_geometry_timer_id;
337
/* support to toggle side pane using F9,
338
* see the toggle_sidepane() function.
340
GType toggle_sidepane_type;
345
static GtkActionEntry action_entries[] =
347
{ "file-menu", NULL, N_ ("_File"), NULL, },
348
{ "new-tab", "tab-new", N_ ("New _Tab"), "<control>T", N_ ("Open a new tab for the displayed location"), G_CALLBACK (thunar_window_action_open_new_tab), },
349
{ "new-window", "window-new", N_ ("New _Window"), "<control>N", N_ ("Open a new Thunar window for the displayed location"), G_CALLBACK (thunar_window_action_open_new_window), },
350
{ "sendto-menu", NULL, N_ ("_Send To"), NULL, },
351
{ "empty-trash", NULL, N_ ("_Empty Trash"), NULL, N_ ("Delete all files and folders in the Trash"), G_CALLBACK (thunar_window_action_empty_trash), },
352
{ "detach-tab", NULL, N_ ("Detac_h Tab"), NULL, N_ ("Open current folder in a new window"), G_CALLBACK (thunar_window_action_detach_tab), },
353
{ "close-all-windows", NULL, N_ ("Close _All Windows"), "<control><shift>W", N_ ("Close all Thunar windows"), G_CALLBACK (thunar_window_action_close_all_windows), },
354
{ "close-tab", GTK_STOCK_CLOSE, N_ ("C_lose Tab"), "<control>W", N_ ("Close this folder"), G_CALLBACK (thunar_window_action_close_tab), },
355
{ "close-window", GTK_STOCK_QUIT, N_ ("_Close Window"), "<control>Q", N_ ("Close this window"), G_CALLBACK (thunar_window_action_close_window), },
356
{ "edit-menu", NULL, N_ ("_Edit"), NULL, },
357
{ "preferences", GTK_STOCK_PREFERENCES, N_ ("Pr_eferences..."), NULL, N_ ("Edit Thunars Preferences"), G_CALLBACK (thunar_window_action_preferences), },
358
{ "view-menu", NULL, N_ ("_View"), NULL, },
359
{ "reload", GTK_STOCK_REFRESH, N_ ("_Reload"), "<control>R", N_ ("Reload the current folder"), G_CALLBACK (thunar_window_action_reload), },
360
{ "view-location-selector-menu", NULL, N_ ("_Location Selector"), NULL, },
361
{ "view-side-pane-menu", NULL, N_ ("_Side Pane"), NULL, },
362
{ "zoom-in", GTK_STOCK_ZOOM_IN, N_ ("Zoom I_n"), "<control>plus", N_ ("Show the contents in more detail"), G_CALLBACK (thunar_window_action_zoom_in), },
363
{ "zoom-out", GTK_STOCK_ZOOM_OUT, N_ ("Zoom _Out"), "<control>minus", N_ ("Show the contents in less detail"), G_CALLBACK (thunar_window_action_zoom_out), },
364
{ "zoom-reset", GTK_STOCK_ZOOM_100, N_ ("Normal Si_ze"), "<control>0", N_ ("Show the contents at the normal size"), G_CALLBACK (thunar_window_action_zoom_reset), },
365
{ "go-menu", NULL, N_ ("_Go"), NULL, },
366
{ "open-parent", GTK_STOCK_GO_UP, N_ ("Open _Parent"), "<alt>Up", N_ ("Open the parent folder"), G_CALLBACK (thunar_window_action_go_up), },
367
{ "open-home", GTK_STOCK_HOME, N_ ("_Home"), "<alt>Home", N_ ("Go to the home folder"), G_CALLBACK (thunar_window_action_open_home), },
368
{ "open-desktop", THUNAR_STOCK_DESKTOP, N_ ("Desktop"), NULL, N_ ("Go to the desktop folder"), G_CALLBACK (thunar_window_action_open_desktop), },
369
{ "open-file-system", GTK_STOCK_HARDDISK, N_ ("File System"), NULL, N_ ("Browse the file system"), G_CALLBACK (thunar_window_action_open_file_system), },
370
{ "open-network", GTK_STOCK_NETWORK, N_("B_rowse Network"), NULL, N_ ("Browse local network connections"), G_CALLBACK (thunar_window_action_open_network), },
371
{ "open-templates", THUNAR_STOCK_TEMPLATES, N_("T_emplates"), NULL, N_ ("Go to the templates folder"), G_CALLBACK (thunar_window_action_open_templates), },
372
{ "open-location", NULL, N_ ("_Open Location..."), "<control>L", N_ ("Specify a location to open"), G_CALLBACK (thunar_window_action_open_location), },
373
{ "help-menu", NULL, N_ ("_Help"), NULL, },
374
{ "contents", GTK_STOCK_HELP, N_ ("_Contents"), "F1", N_ ("Display Thunar user manual"), G_CALLBACK (thunar_window_action_contents), },
375
{ "about", GTK_STOCK_ABOUT, N_ ("_About"), NULL, N_ ("Display information about Thunar"), G_CALLBACK (thunar_window_action_about), },
378
static const GtkToggleActionEntry toggle_action_entries[] =
380
{ "show-hidden", NULL, N_ ("Show _Hidden Files"), "<control>H", N_ ("Toggles the display of hidden files in the current window"), G_CALLBACK (thunar_window_action_show_hidden), FALSE, },
381
{ "view-location-selector-pathbar", NULL, N_ ("_Pathbar Style"), NULL, N_ ("Modern approach with buttons that correspond to folders"), G_CALLBACK (thunar_window_action_pathbar_changed), FALSE, },
382
{ "view-location-selector-toolbar", NULL, N_ ("_Toolbar Style"), NULL, N_ ("Traditional approach with location bar and navigation buttons"), G_CALLBACK (thunar_window_action_toolbar_changed), FALSE, },
383
{ "view-side-pane-shortcuts", NULL, N_ ("_Shortcuts"), "<control>B", N_ ("Toggles the visibility of the shortcuts pane"), G_CALLBACK (thunar_window_action_shortcuts_changed), FALSE, },
384
{ "view-side-pane-tree", NULL, N_ ("_Tree"), "<control>E", N_ ("Toggles the visibility of the tree pane"), G_CALLBACK (thunar_window_action_tree_changed), FALSE, },
385
{ "view-statusbar", NULL, N_ ("St_atusbar"), NULL, N_ ("Change the visibility of this window's statusbar"), G_CALLBACK (thunar_window_action_statusbar_changed), FALSE, },
386
{ "view-menubar", NULL, N_ ("_Menubar"), "<control>M", N_ ("Change the visibility of this window's menubar"), G_CALLBACK (thunar_window_action_menubar_changed), TRUE, },
391
static guint window_signals[LAST_SIGNAL];
395
G_DEFINE_TYPE_WITH_CODE (ThunarWindow, thunar_window, GTK_TYPE_WINDOW,
396
G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL))
401
thunar_window_class_init (ThunarWindowClass *klass)
403
GtkWidgetClass *gtkwidget_class;
404
GtkBindingSet *binding_set;
405
GObjectClass *gobject_class;
408
gobject_class = G_OBJECT_CLASS (klass);
409
gobject_class->dispose = thunar_window_dispose;
410
gobject_class->finalize = thunar_window_finalize;
411
gobject_class->get_property = thunar_window_get_property;
412
gobject_class->set_property = thunar_window_set_property;
414
gtkwidget_class = GTK_WIDGET_CLASS (klass);
415
gtkwidget_class->realize = thunar_window_realize;
416
gtkwidget_class->unrealize = thunar_window_unrealize;
417
gtkwidget_class->configure_event = thunar_window_configure_event;
419
klass->back = thunar_window_back;
420
klass->reload = thunar_window_reload;
421
klass->toggle_sidepane = thunar_window_toggle_sidepane;
422
klass->toggle_menubar = thunar_window_toggle_menubar;
423
klass->zoom_in = thunar_window_zoom_in;
424
klass->zoom_out = thunar_window_zoom_out;
425
klass->zoom_reset = thunar_window_zoom_reset;
426
klass->tab_change = thunar_window_tab_change;
429
* ThunarWindow:current-directory:
431
* The directory currently displayed within this #ThunarWindow
434
g_object_class_install_property (gobject_class,
435
PROP_CURRENT_DIRECTORY,
436
g_param_spec_object ("current-directory",
440
EXO_PARAM_READWRITE));
443
* ThunarWindow:show-hidden:
445
* Whether to show hidden files in the current window.
447
g_object_class_install_property (gobject_class,
449
g_param_spec_boolean ("show-hidden",
453
EXO_PARAM_READABLE));
456
* ThunarWindow:ui-manager:
458
* The #GtkUIManager used for this #ThunarWindow. This property
459
* can only be read and is garantied to always contain a valid
460
* #GtkUIManager instance (thus it's never %NULL).
462
g_object_class_install_property (gobject_class,
464
g_param_spec_object ("ui-manager",
468
EXO_PARAM_READABLE));
471
* ThunarWindow:zoom-level:
473
* The #ThunarZoomLevel applied to the #ThunarView currently
474
* shown within this window.
476
g_object_class_install_property (gobject_class,
478
g_param_spec_enum ("zoom-level",
481
THUNAR_TYPE_ZOOM_LEVEL,
482
THUNAR_ZOOM_LEVEL_NORMAL,
483
EXO_PARAM_READWRITE));
486
* ThunarWindow::back:
487
* @window : a #ThunarWindow instance.
489
* Emitted whenever the user requests to go to the
490
* previous visited folder. This is an internal
491
* signal used to bind the action to keys.
493
window_signals[BACK] =
494
g_signal_new (I_("back"),
495
G_TYPE_FROM_CLASS (klass),
496
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
497
G_STRUCT_OFFSET (ThunarWindowClass, back),
498
g_signal_accumulator_true_handled, NULL,
499
_thunar_marshal_BOOLEAN__VOID,
503
* ThunarWindow::reload:
504
* @window : a #ThunarWindow instance.
506
* Emitted whenever the user requests to reload the contents
507
* of the currently displayed folder. This is an internal
508
* signal used to bind the action to keys.
510
window_signals[RELOAD] =
511
g_signal_new (I_("reload"),
512
G_TYPE_FROM_CLASS (klass),
513
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
514
G_STRUCT_OFFSET (ThunarWindowClass, reload),
515
g_signal_accumulator_true_handled, NULL,
516
_thunar_marshal_BOOLEAN__VOID,
520
* ThunarWindow::toggle-sidepane:
521
* @window : a #ThunarWindow instance.
523
* Emitted whenever the user toggles the visibility of the
524
* sidepane. This is an internal signal used to bind the
527
window_signals[TOGGLE_SIDEPANE] =
528
g_signal_new (I_("toggle-sidepane"),
529
G_TYPE_FROM_CLASS (klass),
530
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
531
G_STRUCT_OFFSET (ThunarWindowClass, toggle_sidepane),
532
g_signal_accumulator_true_handled, NULL,
533
_thunar_marshal_BOOLEAN__VOID,
537
* ThunarWindow::toggle-sidepane:
538
* @window : a #ThunarWindow instance.
540
* Emitted whenever the user toggles the visibility of the
541
* sidepane. This is an internal signal used to bind the
544
window_signals[TOGGLE_MENUBAR] =
545
g_signal_new (I_("toggle-menubar"),
546
G_TYPE_FROM_CLASS (klass),
547
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
548
G_STRUCT_OFFSET (ThunarWindowClass, toggle_menubar),
549
g_signal_accumulator_true_handled, NULL,
550
_thunar_marshal_BOOLEAN__VOID,
554
* ThunarWindow::zoom-in:
555
* @window : a #ThunarWindow instance.
557
* Emitted whenever the user requests to zoom in. This
558
* is an internal signal used to bind the action to keys.
560
window_signals[ZOOM_IN] =
561
g_signal_new (I_("zoom-in"),
562
G_TYPE_FROM_CLASS (klass),
563
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
564
G_STRUCT_OFFSET (ThunarWindowClass, zoom_in),
565
g_signal_accumulator_true_handled, NULL,
566
_thunar_marshal_BOOLEAN__VOID,
570
* ThunarWindow::zoom-out:
571
* @window : a #ThunarWindow instance.
573
* Emitted whenever the user requests to zoom out. This
574
* is an internal signal used to bind the action to keys.
576
window_signals[ZOOM_OUT] =
577
g_signal_new (I_("zoom-out"),
578
G_TYPE_FROM_CLASS (klass),
579
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
580
G_STRUCT_OFFSET (ThunarWindowClass, zoom_out),
581
g_signal_accumulator_true_handled, NULL,
582
_thunar_marshal_BOOLEAN__VOID,
586
* ThunarWindow::zoom-reset:
587
* @window : a #ThunarWindow instance.
589
* Emitted whenever the user requests reset the zoom level.
590
* This is an internal signal used to bind the action to keys.
592
window_signals[ZOOM_RESET] =
593
g_signal_new (I_("zoom-reset"),
594
G_TYPE_FROM_CLASS (klass),
595
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
596
G_STRUCT_OFFSET (ThunarWindowClass, zoom_reset),
597
g_signal_accumulator_true_handled, NULL,
598
_thunar_marshal_BOOLEAN__VOID,
602
* ThunarWindow::tab-chage:
603
* @window : a #ThunarWindow instance.
606
* Emitted whenever the user uses a Alt+N combination to
609
window_signals[TAB_CHANGE] =
610
g_signal_new (I_("tab-change"),
611
G_TYPE_FROM_CLASS (klass),
612
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
613
G_STRUCT_OFFSET (ThunarWindowClass, tab_change),
614
g_signal_accumulator_true_handled, NULL,
615
_thunar_marshal_BOOLEAN__INT,
619
/* setup the key bindings for the windows */
620
binding_set = gtk_binding_set_by_class (klass);
621
gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0, "back", 0);
622
gtk_binding_entry_add_signal (binding_set, GDK_F5, 0, "reload", 0);
623
gtk_binding_entry_add_signal (binding_set, GDK_F9, 0, "toggle-sidepane", 0);
624
gtk_binding_entry_add_signal (binding_set, GDK_F10, 0, "toggle-menubar", 0);
625
gtk_binding_entry_add_signal (binding_set, GDK_KP_Add, GDK_CONTROL_MASK, "zoom-in", 0);
626
gtk_binding_entry_add_signal (binding_set, GDK_KP_Subtract, GDK_CONTROL_MASK, "zoom-out", 0);
627
gtk_binding_entry_add_signal (binding_set, GDK_KP_0, GDK_CONTROL_MASK, "zoom-reset", 0);
628
gtk_binding_entry_add_signal (binding_set, GDK_KP_Insert, GDK_CONTROL_MASK, "zoom-reset", 0);
630
/* setup the key bindings for Alt+N */
631
for (i = 0; i < 10; i++)
633
gtk_binding_entry_add_signal (binding_set, GDK_0 + i, GDK_MOD1_MASK,
634
"tab-change", 1, G_TYPE_UINT, i - 1);
641
view_type2index (GType type)
643
/* this necessary for platforms where sizeof(GType) != sizeof(gint),
644
* see http://bugzilla.xfce.org/show_bug.cgi?id=2726 for details.
646
if (sizeof (GType) == sizeof (gint))
648
/* no need to map anything */
653
/* map from types to unique indices */
654
if (G_LIKELY (type == THUNAR_TYPE_COMPACT_VIEW))
656
else if (type == THUNAR_TYPE_DETAILS_VIEW)
666
view_index2type (gint idx)
668
/* this necessary for platforms where sizeof(GType) != sizeof(gint),
669
* see http://bugzilla.xfce.org/show_bug.cgi?id=2726 for details.
671
if (sizeof (GType) == sizeof (gint))
673
/* no need to map anything */
678
/* map from indices to unique types */
681
case 0: return THUNAR_TYPE_COMPACT_VIEW;
682
case 1: return THUNAR_TYPE_DETAILS_VIEW;
683
default: return THUNAR_TYPE_ICON_VIEW;
691
thunar_window_init (ThunarWindow *window)
693
GtkRadioAction *radio_action;
694
GtkAccelGroup *accel_group;
699
gboolean last_show_hidden;
700
gboolean last_menubar_visible;
702
gchar *last_location_bar;
703
gchar *last_side_pane;
705
gint last_separator_position;
706
gint last_window_width;
707
gint last_window_height;
708
gboolean last_window_maximized;
709
gboolean last_statusbar_visible;
712
/* unset the view type */
713
window->view_type = G_TYPE_NONE;
715
/* grab a reference on the provider factory */
716
window->provider_factory = thunarx_provider_factory_get_default ();
718
/* grab a reference on the preferences */
719
window->preferences = thunar_preferences_get ();
721
/* get all properties for init */
722
g_object_get (G_OBJECT (window->preferences),
723
"last-show-hidden", &last_show_hidden,
724
"last-window-width", &last_window_width,
725
"last-window-height", &last_window_height,
726
"last-window-maximized", &last_window_maximized,
727
"last-menubar-visible", &last_menubar_visible,
728
"last-separator-position", &last_separator_position,
729
"last-location-bar", &last_location_bar,
730
"last-side-pane", &last_side_pane,
731
"last-statusbar-visible", &last_statusbar_visible,
734
/* connect to the volume monitor */
735
window->device_monitor = thunar_device_monitor_get ();
736
g_signal_connect (window->device_monitor, "device-pre-unmount", G_CALLBACK (thunar_window_device_pre_unmount), window);
737
g_signal_connect (window->device_monitor, "device-removed", G_CALLBACK (thunar_window_device_changed), window);
738
g_signal_connect (window->device_monitor, "device-changed", G_CALLBACK (thunar_window_device_changed), window);
740
/* allocate a closure for the menu_item_selected() callback */
741
window->menu_item_selected_closure = g_cclosure_new_object (G_CALLBACK (thunar_window_menu_item_selected), G_OBJECT (window));
742
g_closure_ref (window->menu_item_selected_closure);
743
g_closure_sink (window->menu_item_selected_closure);
745
/* allocate a closure for the menu_item_deselected() callback */
746
window->menu_item_deselected_closure = g_cclosure_new_object (G_CALLBACK (thunar_window_menu_item_deselected), G_OBJECT (window));
747
g_closure_ref (window->menu_item_deselected_closure);
748
g_closure_sink (window->menu_item_deselected_closure);
749
window->icon_factory = thunar_icon_factory_get_default ();
751
/* setup the action group for this window */
752
window->action_group = gtk_action_group_new ("ThunarWindow");
753
gtk_action_group_set_translation_domain (window->action_group, GETTEXT_PACKAGE);
754
gtk_action_group_add_actions (window->action_group, action_entries, G_N_ELEMENTS (action_entries), GTK_WIDGET (window));
755
gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries, G_N_ELEMENTS (toggle_action_entries), GTK_WIDGET (window));
757
/* initialize the "show-hidden" action using the last value from the preferences */
758
action = gtk_action_group_get_action (window->action_group, "show-hidden");
759
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), last_show_hidden);
764
radio_action = gtk_radio_action_new ("view-as-icons", _("View as _Icons"), _("Display folder content in an icon view"),
765
NULL, view_type2index (THUNAR_TYPE_ICON_VIEW));
766
gtk_action_group_add_action_with_accel (window->action_group, GTK_ACTION (radio_action), "<control>1");
767
gtk_radio_action_set_group (radio_action, NULL);
768
group = gtk_radio_action_get_group (radio_action);
769
g_object_unref (G_OBJECT (radio_action));
771
radio_action = gtk_radio_action_new ("view-as-detailed-list", _("View as _Detailed List"), _("Display folder content in a detailed list view"),
772
NULL, view_type2index (THUNAR_TYPE_DETAILS_VIEW));
773
gtk_action_group_add_action_with_accel (window->action_group, GTK_ACTION (radio_action), "<control>2");
774
gtk_radio_action_set_group (radio_action, group);
775
group = gtk_radio_action_get_group (radio_action);
776
g_object_unref (G_OBJECT (radio_action));
778
radio_action = gtk_radio_action_new ("view-as-compact-list", _("View as _Compact List"), _("Display folder content in a compact list view"),
779
NULL, view_type2index (THUNAR_TYPE_COMPACT_VIEW));
780
gtk_action_group_add_action_with_accel (window->action_group, GTK_ACTION (radio_action), "<control>3");
781
gtk_radio_action_set_group (radio_action, group);
782
group = gtk_radio_action_get_group (radio_action);
783
g_object_unref (G_OBJECT (radio_action));
785
window->ui_manager = gtk_ui_manager_new ();
786
g_signal_connect (G_OBJECT (window->ui_manager), "connect-proxy", G_CALLBACK (thunar_window_connect_proxy), window);
787
g_signal_connect (G_OBJECT (window->ui_manager), "disconnect-proxy", G_CALLBACK (thunar_window_disconnect_proxy), window);
788
gtk_ui_manager_insert_action_group (window->ui_manager, window->action_group, 0);
789
gtk_ui_manager_add_ui_from_string (window->ui_manager, thunar_window_ui, thunar_window_ui_length, NULL);
791
accel_group = gtk_ui_manager_get_accel_group (window->ui_manager);
792
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
794
/* setup the launcher support */
795
window->launcher = thunar_launcher_new ();
796
thunar_launcher_set_widget (window->launcher, GTK_WIDGET (window));
797
thunar_component_set_ui_manager (THUNAR_COMPONENT (window->launcher), window->ui_manager);
798
exo_binding_new (G_OBJECT (window), "current-directory", G_OBJECT (window->launcher), "current-directory");
799
g_signal_connect_swapped (G_OBJECT (window->launcher), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window);
800
g_signal_connect_swapped (G_OBJECT (window->launcher), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window);
802
/* determine the default window size from the preferences */
803
gtk_window_set_default_size (GTK_WINDOW (window), last_window_width, last_window_height);
805
/* restore the maxized state of the window */
806
if (G_UNLIKELY (last_window_maximized))
807
gtk_window_maximize (GTK_WINDOW (window));
809
window->table = gtk_table_new (6, 1, FALSE);
810
gtk_container_add (GTK_CONTAINER (window), window->table);
811
gtk_widget_show (window->table);
813
window->menubar = gtk_ui_manager_get_widget (window->ui_manager, "/main-menu");
814
gtk_table_attach (GTK_TABLE (window->table), window->menubar, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
816
/* update menubar visibiliy */
817
action = gtk_action_group_get_action (window->action_group, "view-menubar");
818
g_signal_connect (G_OBJECT (window->menubar), "deactivate", G_CALLBACK (thunar_window_toggle_menubar_deactivate), window);
819
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), last_menubar_visible);
821
/* append the menu item for the spinner */
822
item = gtk_menu_item_new ();
823
gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
824
gtk_menu_item_set_right_justified (GTK_MENU_ITEM (item), TRUE);
825
gtk_menu_shell_append (GTK_MENU_SHELL (window->menubar), item);
826
gtk_widget_show (item);
828
/* place the spinner into the menu item */
829
window->spinner = gtk_spinner_new ();
830
gtk_container_add (GTK_CONTAINER (item), window->spinner);
831
exo_binding_new (G_OBJECT (window->spinner), "active",
832
G_OBJECT (window->spinner), "visible");
834
/* check if we need to add the root warning */
835
if (G_UNLIKELY (geteuid () == 0))
837
/* add the bar for the root warning */
838
infobar = gtk_info_bar_new ();
839
gtk_info_bar_set_message_type (GTK_INFO_BAR (infobar), GTK_MESSAGE_WARNING);
840
gtk_table_attach (GTK_TABLE (window->table), infobar, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
841
gtk_widget_show (infobar);
843
/* add the label with the root warning */
844
label = gtk_label_new (_("Warning, you are using the root account, you may harm your system."));
845
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (infobar))), label);
846
gtk_widget_show (label);
849
window->paned = gtk_hpaned_new ();
850
gtk_container_set_border_width (GTK_CONTAINER (window->paned), 0);
851
gtk_table_attach (GTK_TABLE (window->table), window->paned, 0, 1, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
852
gtk_widget_show (window->paned);
854
/* determine the last separator position and apply it to the paned view */
855
gtk_paned_set_position (GTK_PANED (window->paned), last_separator_position);
856
g_signal_connect_swapped (window->paned, "accept-position", G_CALLBACK (thunar_window_save_paned), window);
857
g_signal_connect_swapped (window->paned, "button-release-event", G_CALLBACK (thunar_window_save_paned), window);
859
window->view_box = gtk_table_new (3, 1, FALSE);
860
gtk_paned_pack2 (GTK_PANED (window->paned), window->view_box, TRUE, FALSE);
861
gtk_widget_show (window->view_box);
864
window->notebook = gtk_notebook_new ();
865
gtk_table_attach (GTK_TABLE (window->view_box), window->notebook, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
866
g_signal_connect (G_OBJECT (window->notebook), "switch-page", G_CALLBACK (thunar_window_notebook_switch_page), window);
867
g_signal_connect (G_OBJECT (window->notebook), "page-added", G_CALLBACK (thunar_window_notebook_page_added), window);
868
g_signal_connect (G_OBJECT (window->notebook), "page-removed", G_CALLBACK (thunar_window_notebook_page_removed), window);
869
g_signal_connect_after (G_OBJECT (window->notebook), "button-press-event", G_CALLBACK (thunar_window_notebook_button_press_event), window);
870
g_signal_connect (G_OBJECT (window->notebook), "popup-menu", G_CALLBACK (thunar_window_notebook_popup_menu), window);
871
g_signal_connect (G_OBJECT (window->notebook), "create-window", G_CALLBACK (thunar_window_notebook_create_window), window);
872
gtk_notebook_set_show_border (GTK_NOTEBOOK (window->notebook), FALSE);
873
gtk_notebook_set_homogeneous_tabs (GTK_NOTEBOOK (window->notebook), TRUE);
874
gtk_notebook_set_scrollable (GTK_NOTEBOOK (window->notebook), TRUE);
875
gtk_container_set_border_width (GTK_CONTAINER (window->notebook), 0);
876
gtk_notebook_set_group_name (GTK_NOTEBOOK (window->notebook), "thunar-tabs");
877
gtk_widget_show (window->notebook);
879
/* drop the notebook borders */
880
style = gtk_rc_style_new ();
881
style->xthickness = style->ythickness = 0;
882
gtk_widget_modify_style (window->notebook, style);
883
g_object_unref (G_OBJECT (style));
885
/* determine the selected location selector */
886
if (exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_BUTTONS)))
887
type = THUNAR_TYPE_LOCATION_BUTTONS;
888
else if (exo_str_is_equal (last_location_bar, g_type_name (THUNAR_TYPE_LOCATION_ENTRY)))
889
type = THUNAR_TYPE_LOCATION_ENTRY;
892
g_free (last_location_bar);
894
/* activate the selected location selector */
895
action = gtk_action_group_get_action (window->action_group, "view-location-selector-pathbar");
896
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (type == THUNAR_TYPE_LOCATION_BUTTONS));
897
action = gtk_action_group_get_action (window->action_group, "view-location-selector-toolbar");
898
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (type == THUNAR_TYPE_LOCATION_ENTRY));
900
/* determine the selected side pane (FIXME: Should probably be last-shortcuts-visible and last-tree-visible preferences) */
901
if (exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_SHORTCUTS_PANE)))
902
type = THUNAR_TYPE_SHORTCUTS_PANE;
903
else if (exo_str_is_equal (last_side_pane, g_type_name (THUNAR_TYPE_TREE_PANE)))
904
type = THUNAR_TYPE_TREE_PANE;
907
g_free (last_side_pane);
909
/* activate the selected side pane */
910
action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts");
911
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (type == THUNAR_TYPE_SHORTCUTS_PANE));
912
action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree");
913
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (type == THUNAR_TYPE_TREE_PANE));
915
/* check if we should display the statusbar by default */
916
action = gtk_action_group_get_action (window->action_group, "view-statusbar");
917
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), last_statusbar_visible);
920
action = gtk_action_group_get_action (window->action_group, "view-as-icons");
921
g_signal_connect (G_OBJECT (action), "changed", G_CALLBACK (thunar_window_action_view_changed), window);
923
/* schedule asynchronous menu action merging */
924
window->merge_idle_id = g_idle_add_full (G_PRIORITY_LOW + 20, thunar_window_merge_idle, window, thunar_window_merge_idle_destroy);
930
thunar_window_dispose (GObject *object)
932
ThunarWindow *window = THUNAR_WINDOW (object);
934
/* destroy the save geometry timer source */
935
if (G_UNLIKELY (window->save_geometry_timer_id != 0))
936
g_source_remove (window->save_geometry_timer_id);
938
/* destroy the merge idle source */
939
if (G_UNLIKELY (window->merge_idle_id != 0))
940
g_source_remove (window->merge_idle_id);
942
/* un-merge the custom preferences */
943
if (G_LIKELY (window->custom_preferences_merge_id != 0))
945
gtk_ui_manager_remove_ui (window->ui_manager, window->custom_preferences_merge_id);
946
window->custom_preferences_merge_id = 0;
949
/* un-merge the go menu actions */
950
if (G_LIKELY (window->go_items_actions_merge_id != 0))
952
gtk_ui_manager_remove_ui (window->ui_manager, window->go_items_actions_merge_id);
953
window->go_items_actions_merge_id = 0;
956
/* un-merge the bookmark actions */
957
if (G_LIKELY (window->bookmark_items_actions_merge_id != 0))
959
gtk_ui_manager_remove_ui (window->ui_manager, window->bookmark_items_actions_merge_id);
960
window->bookmark_items_actions_merge_id = 0;
963
if (window->bookmark_reload_idle_id != 0)
965
g_source_remove (window->bookmark_reload_idle_id);
966
window->bookmark_reload_idle_id = 0;
969
/* disconnect from the current-directory */
970
thunar_window_set_current_directory (window, NULL);
972
(*G_OBJECT_CLASS (thunar_window_parent_class)->dispose) (object);
978
thunar_window_finalize (GObject *object)
980
ThunarWindow *window = THUNAR_WINDOW (object);
982
/* drop our references on the menu_item_selected()/menu_item_deselected() closures */
983
g_closure_unref (window->menu_item_deselected_closure);
984
g_closure_unref (window->menu_item_selected_closure);
986
/* disconnect from the volume monitor */
987
g_signal_handlers_disconnect_matched (window->device_monitor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window);
988
g_object_unref (window->device_monitor);
990
/* disconnect from the ui manager */
991
g_signal_handlers_disconnect_matched (window->ui_manager, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window);
992
g_object_unref (window->ui_manager);
994
/* release the custom actions */
995
if (window->custom_actions != NULL)
996
g_object_unref (window->custom_actions);
998
g_object_unref (window->action_group);
999
g_object_unref (window->icon_factory);
1000
g_object_unref (window->launcher);
1002
if (window->bookmark_action_group != NULL)
1003
g_object_unref (window->bookmark_action_group);
1005
if (window->bookmark_file != NULL)
1006
g_object_unref (window->bookmark_file);
1008
if (window->bookmark_monitor != NULL)
1010
g_file_monitor_cancel (window->bookmark_monitor);
1011
g_object_unref (window->bookmark_monitor);
1014
/* release our reference on the provider factory */
1015
g_object_unref (window->provider_factory);
1017
/* release the preferences reference */
1018
g_object_unref (window->preferences);
1020
(*G_OBJECT_CLASS (thunar_window_parent_class)->finalize) (object);
1026
thunar_window_get_property (GObject *object,
1031
ThunarWindow *window = THUNAR_WINDOW (object);
1036
case PROP_CURRENT_DIRECTORY:
1037
g_value_set_object (value, thunar_window_get_current_directory (window));
1040
case PROP_SHOW_HIDDEN:
1041
action = gtk_action_group_get_action (window->action_group, "show-hidden");
1042
g_value_set_boolean (value, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
1045
case PROP_UI_MANAGER:
1046
g_value_set_object (value, window->ui_manager);
1049
case PROP_ZOOM_LEVEL:
1050
g_value_set_enum (value, window->zoom_level);
1054
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1062
thunar_window_set_property (GObject *object,
1064
const GValue *value,
1067
ThunarWindow *window = THUNAR_WINDOW (object);
1071
case PROP_CURRENT_DIRECTORY:
1072
thunar_window_set_current_directory (window, g_value_get_object (value));
1075
case PROP_ZOOM_LEVEL:
1076
thunar_window_set_zoom_level (window, g_value_get_enum (value));
1080
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1088
thunar_window_back (ThunarWindow *window)
1092
const gchar *accel_path;
1095
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1097
/* check source event */
1098
event = gtk_get_current_event ();
1100
&& event->type == GDK_KEY_PRESS)
1102
action = thunar_gtk_ui_manager_get_action_by_name (window->ui_manager, "open-parent");
1103
if (G_LIKELY (action != NULL))
1105
/* check if the current event (back) is different then the open-parent
1106
* accelerator. this way a user can override the default backspace action
1107
* of back in open-parent, without backspace resulting in a back action
1108
* if open-parent is insensitive in the menu */
1109
accel_path = gtk_action_get_accel_path (action);
1110
if (accel_path != NULL
1111
&& gtk_accel_map_lookup_entry (accel_path, &key)
1112
&& key.accel_key == ((GdkEventKey *) event)->keyval
1113
&& key.accel_mods == 0)
1118
/* activate the "back" action */
1119
action = thunar_gtk_ui_manager_get_action_by_name (window->ui_manager, "back");
1120
if (G_LIKELY (action != NULL))
1122
gtk_action_activate (action);
1132
thunar_window_reload (ThunarWindow *window)
1134
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1136
/* force the view to reload */
1137
if (G_LIKELY (window->view != NULL))
1139
thunar_view_reload (THUNAR_VIEW (window->view));
1149
thunar_window_toggle_sidepane (ThunarWindow *window)
1154
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1156
/* check if a side pane is currently active */
1157
if (G_LIKELY (window->sidepane != NULL))
1159
/* determine the currently active side pane type */
1160
window->toggle_sidepane_type = G_OBJECT_TYPE (window->sidepane);
1162
/* just reset both side pane actions */
1163
action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts");
1164
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
1165
action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree");
1166
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
1170
/* check if we have a previously remembered toggle type */
1171
if (G_UNLIKELY (window->toggle_sidepane_type == G_TYPE_INVALID))
1173
/* guess type based on the last-side-pane preference, default to shortcuts */
1174
g_object_get (G_OBJECT (window->preferences), "last-side-pane", &type_name, NULL);
1175
if (exo_str_is_equal (type_name, g_type_name (THUNAR_TYPE_TREE_PANE)))
1176
window->toggle_sidepane_type = THUNAR_TYPE_TREE_PANE;
1178
window->toggle_sidepane_type = THUNAR_TYPE_SHORTCUTS_PANE;
1182
/* activate the given side pane */
1183
action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts");
1184
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (window->toggle_sidepane_type == THUNAR_TYPE_SHORTCUTS_PANE));
1185
action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree");
1186
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), (window->toggle_sidepane_type == THUNAR_TYPE_TREE_PANE));
1195
thunar_window_toggle_menubar (ThunarWindow *window)
1197
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1199
if (!gtk_widget_get_visible (window->menubar))
1201
/* temporarily show menu bar */
1202
gtk_widget_show (window->menubar);
1212
thunar_window_toggle_menubar_deactivate (GtkWidget *menubar,
1213
ThunarWindow *window)
1217
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1218
_thunar_return_if_fail (window->menubar == menubar);
1220
/* this was a temporarily show, hide the bar */
1221
action = gtk_action_group_get_action (window->action_group, "view-menubar");
1222
if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1223
gtk_widget_hide (menubar);
1229
thunar_window_zoom_in (ThunarWindow *window)
1231
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1233
/* check if we can still zoom in */
1234
if (G_LIKELY (window->zoom_level < THUNAR_ZOOM_N_LEVELS - 1))
1236
thunar_window_set_zoom_level (window, window->zoom_level + 1);
1246
thunar_window_zoom_out (ThunarWindow *window)
1248
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1250
/* check if we can still zoom out */
1251
if (G_LIKELY (window->zoom_level > 0))
1253
thunar_window_set_zoom_level (window, window->zoom_level - 1);
1263
thunar_window_zoom_reset (ThunarWindow *window)
1265
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1267
/* tell the view to reset it's zoom level */
1268
if (G_LIKELY (window->view != NULL))
1270
thunar_view_reset_zoom_level (THUNAR_VIEW (window->view));
1280
thunar_window_tab_change (ThunarWindow *window,
1283
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
1285
/* Alt+0 is 10th tab */
1286
gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook),
1287
nth == -1 ? 8 : nth);
1295
thunar_window_realize (GtkWidget *widget)
1297
ThunarWindow *window = THUNAR_WINDOW (widget);
1299
/* let the GtkWidget class perform the realize operation */
1300
(*GTK_WIDGET_CLASS (thunar_window_parent_class)->realize) (widget);
1302
/* connect to the clipboard manager of the new display and be sure to redraw the window
1303
* whenever the clipboard contents change to make sure we always display up2date state.
1305
window->clipboard = thunar_clipboard_manager_get_for_display (gtk_widget_get_display (widget));
1306
g_signal_connect_swapped (G_OBJECT (window->clipboard), "changed",
1307
G_CALLBACK (gtk_widget_queue_draw), widget);
1313
thunar_window_unrealize (GtkWidget *widget)
1315
ThunarWindow *window = THUNAR_WINDOW (widget);
1317
/* disconnect from the clipboard manager */
1318
g_signal_handlers_disconnect_by_func (G_OBJECT (window->clipboard), gtk_widget_queue_draw, widget);
1319
g_object_unref (G_OBJECT (window->clipboard));
1321
/* let the GtkWidget class unrealize the window */
1322
(*GTK_WIDGET_CLASS (thunar_window_parent_class)->unrealize) (widget);
1328
thunar_window_configure_event (GtkWidget *widget,
1329
GdkEventConfigure *event)
1331
ThunarWindow *window = THUNAR_WINDOW (widget);
1333
/* check if we have a new dimension here */
1334
if (widget->allocation.width != event->width || widget->allocation.height != event->height)
1336
/* drop any previous timer source */
1337
if (window->save_geometry_timer_id != 0)
1338
g_source_remove (window->save_geometry_timer_id);
1340
/* check if we should schedule another save timer */
1341
if (gtk_widget_get_visible (widget))
1343
/* save the geometry one second after the last configure event */
1344
window->save_geometry_timer_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, 1, thunar_window_save_geometry_timer,
1345
window, thunar_window_save_geometry_timer_destroy);
1349
/* let Gtk+ handle the configure event */
1350
return (*GTK_WIDGET_CLASS (thunar_window_parent_class)->configure_event) (widget, event);
1356
thunar_window_binding_destroyed (gpointer data,
1359
ThunarWindow *window = THUNAR_WINDOW (data);
1361
if (window->view_bindings != NULL)
1362
window->view_bindings = g_slist_remove (window->view_bindings, binding);
1368
thunar_window_binding_create (ThunarWindow *window,
1369
gpointer src_object,
1370
const gchar *src_prop,
1371
gpointer dst_object,
1372
const gchar *dst_prop,
1373
GBindingFlags flags)
1377
_thunar_return_if_fail (G_IS_OBJECT (src_object));
1378
_thunar_return_if_fail (G_IS_OBJECT (dst_object));
1380
binding = g_object_bind_property (G_OBJECT (src_object), src_prop,
1381
G_OBJECT (dst_object), dst_prop,
1384
g_object_weak_ref (G_OBJECT (binding), thunar_window_binding_destroyed, window);
1385
window->view_bindings = g_slist_prepend (window->view_bindings, binding);
1391
thunar_window_notebook_switch_page (GtkWidget *notebook,
1394
ThunarWindow *window)
1397
GSList *view_bindings;
1398
ThunarFile *current_directory;
1400
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1401
_thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1402
_thunar_return_if_fail (THUNAR_IS_VIEW (page));
1403
_thunar_return_if_fail (window->notebook == notebook);
1405
/* leave if nothing changed */
1406
if (window->view == page)
1409
if (G_LIKELY (window->view != NULL))
1411
/* unregisters the actions from the ui */
1412
thunar_component_set_ui_manager (THUNAR_COMPONENT (window->view), NULL);
1414
/* unset view during switch */
1415
window->view = NULL;
1418
/* disconnect existing bindings */
1419
view_bindings = window->view_bindings;
1420
window->view_bindings = NULL;
1421
g_slist_free_full (view_bindings, g_object_unref);
1423
/* update the directory of the current window */
1424
current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (page));
1425
thunar_window_set_current_directory (window, current_directory);
1427
/* activate the selected view */
1428
action = gtk_action_group_get_action (window->action_group, "view-as-icons");
1429
g_signal_handlers_block_by_func (action, thunar_window_action_view_changed, window);
1430
gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), view_type2index (G_OBJECT_TYPE (page)));
1431
g_signal_handlers_unblock_by_func (action, thunar_window_action_view_changed, window);
1433
/* add stock bindings */
1434
thunar_window_binding_create (window, window, "current-directory", page, "current-directory", G_BINDING_DEFAULT);
1435
thunar_window_binding_create (window, window, "show-hidden", page, "show-hidden", G_BINDING_SYNC_CREATE);
1436
thunar_window_binding_create (window, page, "loading", window->spinner, "active", G_BINDING_SYNC_CREATE);
1437
thunar_window_binding_create (window, page, "selected-files", window->launcher, "selected-files", G_BINDING_SYNC_CREATE);
1438
thunar_window_binding_create (window, page, "zoom-level", window, "zoom-level", G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
1440
/* connect to the location bar (if any) */
1441
if (G_LIKELY (window->location_bar != NULL))
1443
thunar_window_binding_create (window, page, "selected-files",
1444
window->location_bar, "selected-files",
1445
G_BINDING_SYNC_CREATE);
1448
/* connect to the sidepane (if any) */
1449
if (G_LIKELY (window->sidepane != NULL))
1451
thunar_window_binding_create (window, page, "selected-files",
1452
window->sidepane, "selected-files",
1453
G_BINDING_SYNC_CREATE);
1456
/* connect to the statusbar (if any) */
1457
if (G_LIKELY (window->statusbar != NULL))
1459
thunar_window_binding_create (window, page, "statusbar-text",
1460
window->statusbar, "text",
1461
G_BINDING_SYNC_CREATE);
1464
/* activate new view */
1465
window->view = page;
1467
/* integrate the standard view action in the ui */
1468
thunar_component_set_ui_manager (THUNAR_COMPONENT (page), window->ui_manager);
1470
/* update the actions */
1471
thunar_standard_view_selection_changed (THUNAR_STANDARD_VIEW (page));
1473
gtk_widget_grab_focus (page);
1479
thunar_window_notebook_show_tabs (ThunarWindow *window)
1482
gboolean show_tabs = TRUE;
1485
/* check if tabs should be visible */
1486
n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
1489
g_object_get (G_OBJECT (window->preferences),
1490
"misc-always-show-tabs", &show_tabs, NULL);
1493
/* update visibility */
1494
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), show_tabs);
1496
/* visibility of the detach action */
1497
action = gtk_action_group_get_action (window->action_group, "detach-tab");
1498
gtk_action_set_visible (action, n_pages > 1);
1504
thunar_window_notebook_page_added (GtkWidget *notebook,
1507
ThunarWindow *window)
1509
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1510
_thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1511
_thunar_return_if_fail (THUNAR_IS_VIEW (page));
1512
_thunar_return_if_fail (window->notebook == notebook);
1514
/* connect signals */
1515
g_signal_connect (G_OBJECT (page), "notify::loading", G_CALLBACK (thunar_window_notify_loading), window);
1516
g_signal_connect (G_OBJECT (page), "notify::selected-files", G_CALLBACK (thunar_window_update_custom_actions), window);
1517
g_signal_connect_swapped (G_OBJECT (page), "start-open-location", G_CALLBACK (thunar_window_start_open_location), window);
1518
g_signal_connect_swapped (G_OBJECT (page), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window);
1519
g_signal_connect_swapped (G_OBJECT (page), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window);
1521
/* update tab visibility */
1522
thunar_window_notebook_show_tabs (window);
1524
/* set default type if not set yet */
1525
if (window->view_type == G_TYPE_NONE)
1526
window->view_type = G_OBJECT_TYPE (page);
1532
thunar_window_notebook_page_removed (GtkWidget *notebook,
1535
ThunarWindow *window)
1539
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1540
_thunar_return_if_fail (GTK_IS_NOTEBOOK (notebook));
1541
_thunar_return_if_fail (THUNAR_IS_VIEW (page));
1542
_thunar_return_if_fail (window->notebook == notebook);
1544
/* drop connected signals */
1545
g_signal_handlers_disconnect_matched (page, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, window);
1547
/* remove from the ui */
1548
thunar_component_set_ui_manager (THUNAR_COMPONENT (page), NULL);
1550
n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
1553
/* destroy the window */
1554
gtk_widget_destroy (GTK_WIDGET (window));
1558
/* update tab visibility */
1559
thunar_window_notebook_show_tabs (window);
1566
thunar_window_notebook_popup_menu_real (ThunarWindow *window,
1572
/* run the menu on the view's screen (figuring out whether to use the file or the folder context menu) */
1573
menu = gtk_ui_manager_get_widget (window->ui_manager, "/tab-context-menu");
1574
thunar_gtk_menu_run (GTK_MENU (menu), GTK_WIDGET (window),
1575
NULL, NULL, button, timestamp);
1581
thunar_window_notebook_button_press_event (GtkWidget *notebook,
1582
GdkEventButton *event,
1583
ThunarWindow *window)
1587
GtkWidget *label_box;
1588
GtkAllocation alloc;
1592
if ((event->button == 2 || event->button == 3)
1593
&& event->type == GDK_BUTTON_PRESS)
1595
/* get real window coordinates */
1596
gdk_window_get_position (event->window, &x, &y);
1600
/* lookup the clicked tab */
1601
while ((page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), page_num)) != NULL)
1603
label_box = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), page);
1604
gtk_widget_get_allocation (label_box, &alloc);
1606
if (x >= alloc.x && x < alloc.x + alloc.width
1607
&& y >= alloc.y && y < alloc.y + alloc.height)
1613
/* leave if no tab could be found */
1617
if (event->button == 2)
1619
/* check if we should close the tab */
1620
g_object_get (window->preferences, "misc-tab-close-middle-click", &close_tab, NULL);
1622
gtk_widget_destroy (page);
1624
else if (event->button == 3)
1626
/* update the current tab before we show the menu */
1627
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page_num);
1629
/* show the tab menu */
1630
thunar_window_notebook_popup_menu_real (window, event->time, event->button);
1642
thunar_window_notebook_popup_menu (GtkWidget *notebook,
1643
ThunarWindow *window)
1645
thunar_window_notebook_popup_menu_real (window, gtk_get_current_event_time (), 0);
1652
thunar_window_notebook_create_window (GtkWidget *notebook,
1656
ThunarWindow *window)
1658
GtkWidget *new_window;
1659
ThunarApplication *application;
1665
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL);
1666
_thunar_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
1667
_thunar_return_val_if_fail (window->notebook == notebook, NULL);
1668
_thunar_return_val_if_fail (THUNAR_IS_VIEW (page), NULL);
1670
/* do nothing if this window has only 1 tab */
1671
if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) < 2)
1674
/* create new window */
1675
application = thunar_application_get ();
1676
screen = gtk_window_get_screen (GTK_WINDOW (window));
1677
new_window = thunar_application_open_window (application, NULL, screen, NULL);
1678
g_object_unref (application);
1680
/* make sure the new window has the same size */
1681
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
1682
gtk_window_resize (GTK_WINDOW (new_window), width, height);
1684
/* move the window to the drop position */
1685
if (x >= 0 && y >= 0)
1687
/* get the monitor geometry */
1688
monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
1689
gdk_screen_get_monitor_geometry (screen, monitor_num, &geo);
1691
/* calculate window position, but keep it on the current monitor */
1692
x = CLAMP (x - width / 2, geo.x, geo.x + geo.width - width);
1693
y = CLAMP (y - height / 2, geo.y, geo.y + geo.height - height);
1695
/* move the window */
1696
gtk_window_move (GTK_WINDOW (new_window), MAX (0, x), MAX (0, y));
1699
/* insert page in new notebook */
1700
return THUNAR_WINDOW (new_window)->notebook;
1706
thunar_window_notebook_insert (ThunarWindow *window,
1707
ThunarFile *directory)
1712
GtkWidget *label_box;
1717
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1718
_thunar_return_if_fail (THUNAR_IS_FILE (directory));
1719
_thunar_return_if_fail (window->view_type != G_TYPE_NONE);
1721
/* leave if no directory is set */
1722
if (directory == NULL)
1725
/* allocate and setup a new view */
1726
view = g_object_new (window->view_type, "current-directory", directory, NULL);
1727
gtk_widget_show (view);
1729
label_box = gtk_hbox_new (FALSE, 0);
1731
label = gtk_label_new (NULL);
1732
exo_binding_new (G_OBJECT (view), "display-name", G_OBJECT (label), "label");
1733
exo_binding_new (G_OBJECT (view), "tooltip-text", G_OBJECT (label), "tooltip-text");
1734
gtk_widget_set_has_tooltip (label, TRUE);
1735
gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
1736
gtk_misc_set_padding (GTK_MISC (label), 3, 3);
1737
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
1738
gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
1739
gtk_box_pack_start (GTK_BOX (label_box), label, TRUE, TRUE, 0);
1740
gtk_widget_show (label);
1742
button = gtk_button_new ();
1743
gtk_box_pack_start (GTK_BOX (label_box), button, FALSE, FALSE, 0);
1744
gtk_widget_set_can_default (button, FALSE);
1745
gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
1746
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
1747
gtk_widget_set_tooltip_text (button, _("Close tab"));
1748
g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), view);
1749
gtk_widget_show (button);
1751
/* make button a bit smaller */
1752
style = gtk_rc_style_new ();
1753
style->xthickness = style->ythickness = 0;
1754
gtk_widget_modify_style (button, style);
1755
g_object_unref (G_OBJECT (style));
1757
icon = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
1758
gtk_container_add (GTK_CONTAINER (button), icon);
1759
gtk_widget_show (icon);
1761
/* insert the new page */
1762
page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook));
1763
page_num = gtk_notebook_insert_page (GTK_NOTEBOOK (window->notebook), view, label_box, page_num + 1);
1765
/* switch to the new tab*/
1766
gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), page_num);
1768
/* set tab child properties */
1769
gtk_container_child_set (GTK_CONTAINER (window->notebook), view, "tab-expand", TRUE, NULL);
1770
gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook), view, TRUE);
1771
gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (window->notebook), view, TRUE);
1773
/* take focus on the view */
1774
gtk_widget_grab_focus (view);
1780
thunar_window_install_location_bar (ThunarWindow *window,
1784
gboolean small_icons;
1786
_thunar_return_if_fail (type == G_TYPE_NONE || g_type_is_a (type, THUNAR_TYPE_LOCATION_BAR));
1787
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1789
/* drop the previous location bar (if any) */
1790
if (G_UNLIKELY (window->location_bar != NULL))
1792
/* check if it was toolbar'ed (and thereby need to be disconnected from the toolbar) */
1793
if (!thunar_location_bar_is_standalone (THUNAR_LOCATION_BAR (window->location_bar)))
1795
/* disconnect the toolbar from the window */
1796
gtk_container_remove (GTK_CONTAINER (window->table), window->location_toolbar);
1797
window->location_toolbar = NULL;
1800
/* destroy the location bar */
1801
gtk_widget_destroy (window->location_bar);
1802
window->location_bar = NULL;
1805
/* check if we have a new location bar */
1806
if (G_LIKELY (type != G_TYPE_NONE))
1808
/* allocate the new location bar widget */
1809
window->location_bar = g_object_new (type, "ui-manager", window->ui_manager, NULL);
1810
exo_binding_new (G_OBJECT (window), "current-directory", G_OBJECT (window->location_bar), "current-directory");
1811
g_signal_connect_swapped (G_OBJECT (window->location_bar), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window);
1812
g_signal_connect_swapped (G_OBJECT (window->location_bar), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window);
1814
/* connect the location widget to the view (if any) */
1815
if (G_LIKELY (window->view != NULL))
1816
thunar_window_binding_create (window, window->view, "selected-files", window->location_bar, "selected-files", G_BINDING_SYNC_CREATE);
1818
/* check if the location bar should be placed into a toolbar */
1819
if (!thunar_location_bar_is_standalone (THUNAR_LOCATION_BAR (window->location_bar)))
1821
/* setup the toolbar for the location bar */
1822
window->location_toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/location-toolbar");
1823
g_object_get (G_OBJECT (window->preferences), "misc-small-toolbar-icons", &small_icons, NULL);
1824
gtk_toolbar_set_icon_size (GTK_TOOLBAR (window->location_toolbar),
1825
small_icons ? GTK_ICON_SIZE_SMALL_TOOLBAR : GTK_ICON_SIZE_LARGE_TOOLBAR);
1826
gtk_table_attach (GTK_TABLE (window->table), window->location_toolbar, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
1827
gtk_widget_show (window->location_toolbar);
1829
/* add the location bar tool item (destroyed with the location bar) */
1830
item = gtk_tool_item_new ();
1831
gtk_tool_item_set_expand (item, TRUE);
1832
g_signal_connect_object (G_OBJECT (window->location_bar), "destroy", G_CALLBACK (gtk_widget_destroy), item, G_CONNECT_SWAPPED);
1833
gtk_toolbar_insert (GTK_TOOLBAR (window->location_toolbar), item, -1);
1834
gtk_widget_show (GTK_WIDGET (item));
1836
/* add the location bar itself */
1837
gtk_container_add (GTK_CONTAINER (item), window->location_bar);
1841
/* it's a standalone location bar, just place it above the view */
1842
gtk_table_attach (GTK_TABLE (window->view_box), window->location_bar, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 6);
1845
/* display the new location bar widget */
1846
gtk_widget_show (window->location_bar);
1849
/* remember the setting */
1850
if (gtk_widget_get_visible (GTK_WIDGET (window)))
1851
g_object_set (G_OBJECT (window->preferences), "last-location-bar", g_type_name (type), NULL);
1857
thunar_window_install_sidepane (ThunarWindow *window,
1860
_thunar_return_if_fail (type == G_TYPE_NONE || g_type_is_a (type, THUNAR_TYPE_SIDE_PANE));
1861
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1863
/* drop the previous side pane (if any) */
1864
if (G_UNLIKELY (window->sidepane != NULL))
1866
gtk_widget_destroy (window->sidepane);
1867
window->sidepane = NULL;
1870
/* check if we have a new sidepane widget */
1871
if (G_LIKELY (type != G_TYPE_NONE))
1873
/* allocate the new side pane widget */
1874
window->sidepane = g_object_new (type, NULL);
1875
gtk_widget_set_size_request (window->sidepane, 0, -1);
1876
thunar_component_set_ui_manager (THUNAR_COMPONENT (window->sidepane), window->ui_manager);
1877
exo_binding_new (G_OBJECT (window), "show-hidden", G_OBJECT (window->sidepane), "show-hidden");
1878
exo_binding_new (G_OBJECT (window), "current-directory", G_OBJECT (window->sidepane), "current-directory");
1879
g_signal_connect_swapped (G_OBJECT (window->sidepane), "change-directory", G_CALLBACK (thunar_window_set_current_directory), window);
1880
g_signal_connect_swapped (G_OBJECT (window->sidepane), "open-new-tab", G_CALLBACK (thunar_window_notebook_insert), window);
1881
gtk_paned_pack1 (GTK_PANED (window->paned), window->sidepane, FALSE, FALSE);
1882
gtk_widget_show (window->sidepane);
1884
/* connect the side pane widget to the view (if any) */
1885
if (G_LIKELY (window->view != NULL))
1886
thunar_window_binding_create (window, window->view, "selected-files", window->sidepane, "selected-files", G_BINDING_SYNC_CREATE);
1889
/* remember the setting */
1890
if (gtk_widget_get_visible (GTK_WIDGET (window)))
1891
g_object_set (G_OBJECT (window->preferences), "last-side-pane", g_type_name (type), NULL);
1897
thunar_window_merge_custom_preferences (ThunarWindow *window)
1903
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1904
_thunar_return_if_fail (window->custom_preferences_merge_id == 0);
1906
/* determine the available preferences providers */
1907
providers = thunarx_provider_factory_list_providers (window->provider_factory, THUNARX_TYPE_PREFERENCES_PROVIDER);
1908
if (G_LIKELY (providers != NULL))
1910
/* allocate a new merge id from the UI manager */
1911
window->custom_preferences_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager);
1913
/* add actions from all providers */
1914
for (pp = providers; pp != NULL; pp = pp->next)
1916
/* determine the available actions for the provider */
1917
actions = thunarx_preferences_provider_get_actions (THUNARX_PREFERENCES_PROVIDER (pp->data), GTK_WIDGET (window));
1918
for (ap = actions; ap != NULL; ap = ap->next)
1920
/* add the action to the action group */
1921
gtk_action_group_add_action (window->action_group, GTK_ACTION (ap->data));
1923
/* add the action to the UI manager */
1924
gtk_ui_manager_add_ui (window->ui_manager,
1925
window->custom_preferences_merge_id,
1926
"/main-menu/edit-menu/placeholder-custom-preferences",
1927
gtk_action_get_name (GTK_ACTION (ap->data)),
1928
gtk_action_get_name (GTK_ACTION (ap->data)),
1929
GTK_UI_MANAGER_MENUITEM, FALSE);
1931
/* release the reference on the action */
1932
g_object_unref (G_OBJECT (ap->data));
1935
/* release the reference on the provider */
1936
g_object_unref (G_OBJECT (pp->data));
1938
/* release the action list */
1939
g_list_free (actions);
1942
/* release the provider list */
1943
g_list_free (providers);
1950
thunar_window_bookmark_changed (ThunarWindow *window)
1952
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
1954
if (window->bookmark_reload_idle_id == 0)
1955
window->bookmark_reload_idle_id = g_idle_add (thunar_window_bookmark_merge, window);
1961
thunar_window_bookmark_release_file (gpointer data)
1963
ThunarFile *file = THUNAR_FILE (data);
1966
thunar_file_unwatch (file);
1968
/* disconnect changed and destroy signals */
1969
g_signal_handlers_disconnect_matched (file,
1970
G_SIGNAL_MATCH_FUNC, 0,
1972
G_CALLBACK (thunar_window_bookmark_changed),
1975
g_object_unref (file);
1981
thunar_window_bookmark_merge_line (GFile *file_path,
1986
ThunarWindow *window = THUNAR_WINDOW (user_data);
1987
GtkAction *action = NULL;
1988
GChecksum *checksum;
1993
gchar *remote_name = NULL;
1994
const gchar *unique_name;
1996
GtkIconTheme *icon_theme;
1997
const gchar *icon_name;
1999
_thunar_return_if_fail (G_IS_FILE (file_path));
2000
_thunar_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
2001
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2003
/* create unique id based on the uri */
2004
uri = g_file_get_uri (file_path);
2005
checksum = g_checksum_new (G_CHECKSUM_MD5);
2006
g_checksum_update (checksum, (const guchar *) uri, strlen (uri));
2007
unique_name = g_checksum_get_string (checksum);
2010
parse_name = g_file_get_parse_name (file_path);
2011
tooltip = g_strdup_printf (_("Open the location \"%s\""), parse_name);
2012
g_free (parse_name);
2014
icon_theme = gtk_icon_theme_get_for_screen (gtk_window_get_screen (GTK_WINDOW (window)));
2016
if (g_file_has_uri_scheme (file_path, "file"))
2018
/* try to open the file corresponding to the uri */
2019
file = thunar_file_get (file_path, NULL);
2020
if (G_UNLIKELY (file == NULL))
2023
/* make sure the file refers to a directory */
2024
if (G_UNLIKELY (thunar_file_is_directory (file)))
2027
name = thunar_file_get_display_name (file);
2029
action = gtk_action_new (unique_name, name, tooltip, NULL);
2030
icon_name = thunar_file_get_icon_name (file, THUNAR_FILE_ICON_STATE_DEFAULT, icon_theme);
2031
gtk_action_set_icon_name (action, icon_name);
2032
g_object_set_data_full (G_OBJECT (action), I_("thunar-file"), file,
2033
thunar_window_bookmark_release_file);
2035
/* watch the file */
2036
thunar_file_watch (file);
2038
g_signal_connect_swapped (G_OBJECT (file), "destroy",
2039
G_CALLBACK (thunar_window_bookmark_changed), window);
2040
g_signal_connect_swapped (G_OBJECT (file), "changed",
2041
G_CALLBACK (thunar_window_bookmark_changed), window);
2045
g_object_unref (file);
2048
/* add to the local bookmarks */
2049
path = "/main-menu/go-menu/placeholder-go-local-actions";
2055
remote_name = thunar_g_file_get_display_name_remote (file_path);
2059
action = gtk_action_new (unique_name, name, tooltip, NULL);
2060
gtk_action_set_icon_name (action, "folder-remote");
2061
g_object_set_data_full (G_OBJECT (action), I_("location-file"),
2062
g_object_ref (file_path), g_object_unref);
2064
g_free (remote_name);
2066
/* add to the remote bookmarks */
2067
path = "/main-menu/go-menu/placeholder-go-remote-actions";
2070
if (G_LIKELY (action != NULL))
2072
if (gtk_action_group_get_action (window->bookmark_action_group, unique_name) == NULL)
2074
/* connect action */
2075
g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_window_action_open_bookmark), window);
2077
/* insert the bookmark in the group */
2078
gtk_action_group_add_action_with_accel (window->bookmark_action_group, action, NULL);
2080
/* add the action to the UI manager */
2081
gtk_ui_manager_add_ui (window->ui_manager,
2082
window->bookmark_items_actions_merge_id,
2084
unique_name, unique_name,
2085
GTK_UI_MANAGER_MENUITEM, FALSE);
2088
g_object_unref (action);
2091
g_checksum_free (checksum);
2098
thunar_window_bookmark_merge (gpointer user_data)
2100
ThunarWindow *window = THUNAR_WINDOW (user_data);
2102
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
2104
GDK_THREADS_ENTER ();
2106
/* remove old actions */
2107
if (window->bookmark_items_actions_merge_id != 0)
2109
gtk_ui_manager_remove_ui (window->ui_manager, window->bookmark_items_actions_merge_id);
2110
gtk_ui_manager_ensure_update (window->ui_manager);
2113
/* drop old bookmarks action group */
2114
if (window->bookmark_action_group != NULL)
2116
gtk_ui_manager_remove_action_group (window->ui_manager, window->bookmark_action_group);
2117
g_object_unref (window->bookmark_action_group);
2120
/* lazy initialize the bookmarks */
2121
if (window->bookmark_file == NULL)
2123
window->bookmark_file = thunar_g_file_new_for_bookmarks ();
2124
window->bookmark_monitor = g_file_monitor_file (window->bookmark_file, G_FILE_MONITOR_NONE, NULL, NULL);
2125
if (G_LIKELY (window->bookmark_monitor != NULL))
2127
g_signal_connect_swapped (window->bookmark_monitor, "changed",
2128
G_CALLBACK (thunar_window_bookmark_changed), window);
2132
/* generate a new merge id */
2133
window->bookmark_items_actions_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager);
2135
/* create a new action group */
2136
window->bookmark_action_group = gtk_action_group_new ("ThunarBookmarks");
2137
gtk_ui_manager_insert_action_group (window->ui_manager, window->bookmark_action_group, -1);
2139
/* collect bookmarks */
2140
thunar_util_load_bookmarks (window->bookmark_file,
2141
thunar_window_bookmark_merge_line,
2144
window->bookmark_reload_idle_id = 0;
2146
GDK_THREADS_LEAVE ();
2154
thunar_window_merge_go_actions (ThunarWindow *window)
2158
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2159
_thunar_return_if_fail (window->go_items_actions_merge_id == 0);
2161
/* setup the "open-trash" action */
2162
if (thunar_g_vfs_is_uri_scheme_supported ("trash"))
2164
/* allocate a new merge id from the UI manager */
2165
window->go_items_actions_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager);
2167
/* add the trash action to the action group */
2168
action = thunar_trash_action_new ();
2169
g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (thunar_window_action_open_trash), window);
2170
gtk_action_group_add_action_with_accel (window->action_group, action, NULL);
2172
/* add the action to the UI manager */
2173
gtk_ui_manager_add_ui (window->ui_manager,
2174
window->go_items_actions_merge_id,
2175
"/main-menu/go-menu/placeholder-go-items-actions",
2176
gtk_action_get_name (GTK_ACTION (action)),
2177
gtk_action_get_name (GTK_ACTION (action)),
2178
GTK_UI_MANAGER_MENUITEM, FALSE);
2180
g_object_unref (action);
2183
/* setup visibility of the "open-network" action */
2184
action = gtk_action_group_get_action (window->action_group, "open-network");
2185
gtk_action_set_visible (action, thunar_g_vfs_is_uri_scheme_supported ("network"));
2191
thunar_window_open_or_launch (ThunarWindow *window,
2194
GError *error = NULL;
2196
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2197
_thunar_return_if_fail (THUNAR_IS_FILE (file));
2199
if (thunar_file_is_directory (file))
2201
/* open the new directory */
2202
thunar_window_set_current_directory (window, file);
2206
/* try to launch the selected file */
2207
if (!thunar_file_launch (file, window, NULL, &error))
2209
thunar_dialogs_show_error (window, error, _("Failed to launch \"%s\""),
2210
thunar_file_get_display_name (file));
2211
g_error_free (error);
2219
thunar_window_poke_file_finish (ThunarBrowser *browser,
2221
ThunarFile *target_file,
2225
_thunar_return_if_fail (THUNAR_IS_WINDOW (browser));
2226
_thunar_return_if_fail (THUNAR_IS_FILE (file));
2230
thunar_window_open_or_launch (THUNAR_WINDOW (browser), target_file);
2234
thunar_dialogs_show_error (GTK_WIDGET (browser), error,
2235
_("Failed to open \"%s\""),
2236
thunar_file_get_display_name (file));
2243
thunar_window_start_open_location (ThunarWindow *window,
2244
const gchar *initial_text)
2246
ThunarFile *selected_file;
2249
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2251
/* bring up the "Open Location"-dialog if the window has no location bar or the location bar
2252
* in the window does not support text entry by the user.
2254
if (window->location_bar == NULL || !thunar_location_bar_accept_focus (THUNAR_LOCATION_BAR (window->location_bar), initial_text))
2256
/* allocate the "Open Location" dialog */
2257
dialog = thunar_location_dialog_new ();
2258
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
2259
gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
2260
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
2261
thunar_location_dialog_set_working_directory (THUNAR_LOCATION_DIALOG (dialog),
2262
thunar_window_get_current_directory (window));
2263
thunar_location_dialog_set_selected_file (THUNAR_LOCATION_DIALOG (dialog),
2264
thunar_window_get_current_directory (window));
2266
/* setup the initial text (if any) */
2267
if (G_UNLIKELY (initial_text != NULL))
2269
/* show, grab focus, set text and move cursor to the end */
2270
gtk_widget_show_now (dialog);
2271
gtk_widget_grab_focus (THUNAR_LOCATION_DIALOG (dialog)->entry);
2272
gtk_entry_set_text (GTK_ENTRY (THUNAR_LOCATION_DIALOG (dialog)->entry), initial_text);
2273
gtk_editable_set_position (GTK_EDITABLE (THUNAR_LOCATION_DIALOG (dialog)->entry), -1);
2276
/* run the dialog */
2277
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
2279
/* be sure to hide the location dialog first */
2280
gtk_widget_hide (dialog);
2282
/* check if we have a new directory or a file to launch */
2283
selected_file = thunar_location_dialog_get_selected_file (THUNAR_LOCATION_DIALOG (dialog));
2284
if (selected_file != NULL)
2286
thunar_browser_poke_file (THUNAR_BROWSER (window), selected_file, window,
2287
thunar_window_poke_file_finish, NULL);
2291
/* destroy the dialog */
2292
gtk_widget_destroy (dialog);
2299
thunar_window_action_open_new_tab (GtkAction *action,
2300
ThunarWindow *window)
2302
/* insert new tab with current directory as default */
2303
thunar_window_notebook_insert (window, thunar_window_get_current_directory (window));
2309
thunar_window_action_open_new_window (GtkAction *action,
2310
ThunarWindow *window)
2312
ThunarApplication *application;
2313
ThunarFile *start_file;
2314
GtkWidget *new_window;
2316
/* popup a new window */
2317
application = thunar_application_get ();
2318
new_window = thunar_application_open_window (application, window->current_directory,
2319
gtk_widget_get_screen (GTK_WIDGET (window)), NULL);
2320
g_object_unref (G_OBJECT (application));
2322
/* determine the first visible file in the current window */
2323
if (window->view != NULL && thunar_view_get_visible_range (THUNAR_VIEW (window->view), &start_file, NULL))
2325
/* scroll the new window to the same file */
2326
thunar_window_scroll_to_file (THUNAR_WINDOW (new_window), start_file, FALSE, TRUE, 0.1f, 0.1f);
2328
/* release the file reference */
2329
g_object_unref (G_OBJECT (start_file));
2336
thunar_window_action_empty_trash (GtkAction *action,
2337
ThunarWindow *window)
2339
ThunarApplication *application;
2341
/* launch the operation */
2342
application = thunar_application_get ();
2343
thunar_application_empty_trash (application, GTK_WIDGET (window), NULL);
2344
g_object_unref (G_OBJECT (application));
2350
thunar_window_action_detach_tab (GtkAction *action,
2351
ThunarWindow *window)
2353
GtkWidget *notebook;
2355
GtkWidget *view = window->view;
2357
_thunar_return_if_fail (THUNAR_IS_VIEW (view));
2358
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2360
/* create a new window */
2361
notebook = thunar_window_notebook_create_window (window->notebook, view, -1, -1, window);
2362
if (notebook == NULL)
2365
/* get the current label */
2366
label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (window->notebook), view);
2367
_thunar_return_if_fail (GTK_IS_WIDGET (label));
2369
/* ref object so they don't destroy when removed from the container */
2370
g_object_ref (label);
2371
g_object_ref (view);
2373
/* remove view from the current notebook */
2374
gtk_container_remove (GTK_CONTAINER (window->notebook), view);
2376
/* insert in the new notebook */
2377
gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), view, label, 0);
2379
/* set tab child properties */
2380
gtk_container_child_set (GTK_CONTAINER (notebook), view, "tab-expand", TRUE, NULL);
2381
gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (notebook), view, TRUE);
2382
gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (notebook), view, TRUE);
2385
g_object_unref (label);
2386
g_object_unref (view);
2392
thunar_window_action_close_all_windows (GtkAction *action,
2393
ThunarWindow *window)
2395
ThunarApplication *application;
2398
/* query the list of currently open windows */
2399
application = thunar_application_get ();
2400
windows = thunar_application_get_windows (application);
2401
g_object_unref (G_OBJECT (application));
2403
/* destroy all open windows */
2404
g_list_free_full (windows, (GDestroyNotify) gtk_widget_destroy);
2410
thunar_window_action_close_tab (GtkAction *action,
2411
ThunarWindow *window)
2413
if (window->view != NULL)
2414
gtk_widget_destroy (window->view);
2420
thunar_window_action_close_window (GtkAction *action,
2421
ThunarWindow *window)
2423
gtk_widget_destroy (GTK_WIDGET (window));
2429
thunar_window_action_preferences (GtkAction *action,
2430
ThunarWindow *window)
2433
ThunarApplication *application;
2435
_thunar_return_if_fail (GTK_IS_ACTION (action));
2436
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2438
/* allocate and display a preferences dialog */;
2439
dialog = thunar_preferences_dialog_new (GTK_WINDOW (window));
2440
gtk_widget_show (dialog);
2442
/* ...and let the application take care of it */
2443
application = thunar_application_get ();
2444
thunar_application_take_window (application, GTK_WINDOW (dialog));
2445
g_object_unref (G_OBJECT (application));
2451
thunar_window_action_reload (GtkAction *action,
2452
ThunarWindow *window)
2456
_thunar_return_if_fail (GTK_IS_ACTION (action));
2457
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2459
/* force the view to reload */
2460
g_signal_emit (G_OBJECT (window), window_signals[RELOAD], 0, &result);
2466
thunar_window_action_pathbar_changed (GtkToggleAction *action,
2467
ThunarWindow *window)
2469
GtkAction *other_action;
2472
_thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2473
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2475
/* determine the new type of location bar */
2476
type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_LOCATION_BUTTONS : G_TYPE_NONE;
2478
/* install the new location bar */
2479
thunar_window_install_location_bar (window, type);
2481
/* check if we actually installed anything */
2482
if (G_LIKELY (type != G_TYPE_NONE))
2484
/* reset the state of the toolbar action (without firing the handler) */
2485
other_action = gtk_action_group_get_action (window->action_group, "view-location-selector-toolbar");
2486
g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_toolbar_changed, window);
2487
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE);
2488
g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_toolbar_changed, window);
2495
thunar_window_action_toolbar_changed (GtkToggleAction *action,
2496
ThunarWindow *window)
2498
GtkAction *other_action;
2501
_thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2502
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2504
/* determine the new type of location bar */
2505
type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_LOCATION_ENTRY : G_TYPE_NONE;
2507
/* install the new location bar */
2508
thunar_window_install_location_bar (window, type);
2510
/* check if we actually installed anything */
2511
if (G_LIKELY (type != G_TYPE_NONE))
2513
/* reset the state of the pathbar action (without firing the handler) */
2514
other_action = gtk_action_group_get_action (window->action_group, "view-location-selector-pathbar");
2515
g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_pathbar_changed, window);
2516
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE);
2517
g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_pathbar_changed, window);
2524
thunar_window_action_shortcuts_changed (GtkToggleAction *action,
2525
ThunarWindow *window)
2527
GtkAction *other_action;
2530
/* determine the new type of side pane */
2531
type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_SHORTCUTS_PANE : G_TYPE_NONE;
2533
/* install the new sidepane */
2534
thunar_window_install_sidepane (window, type);
2536
/* check if we actually installed anything */
2537
if (G_LIKELY (type != G_TYPE_NONE))
2539
/* reset the state of the tree pane action (without firing the handler) */
2540
other_action = gtk_action_group_get_action (window->action_group, "view-side-pane-tree");
2541
g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_tree_changed, window);
2542
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE);
2543
g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_tree_changed, window);
2550
thunar_window_action_tree_changed (GtkToggleAction *action,
2551
ThunarWindow *window)
2553
GtkAction *other_action;
2556
/* determine the new type of side pane */
2557
type = gtk_toggle_action_get_active (action) ? THUNAR_TYPE_TREE_PANE : G_TYPE_NONE;
2559
/* install the new sidepane */
2560
thunar_window_install_sidepane (window, type);
2562
/* check if we actually installed anything */
2563
if (G_LIKELY (type != G_TYPE_NONE))
2565
/* reset the state of the shortcuts pane action (without firing the handler) */
2566
other_action = gtk_action_group_get_action (window->action_group, "view-side-pane-shortcuts");
2567
g_signal_handlers_block_by_func (G_OBJECT (other_action), thunar_window_action_shortcuts_changed, window);
2568
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (other_action), FALSE);
2569
g_signal_handlers_unblock_by_func (G_OBJECT (other_action), thunar_window_action_shortcuts_changed, window);
2576
thunar_window_action_statusbar_changed (GtkToggleAction *action,
2577
ThunarWindow *window)
2581
_thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2582
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2584
/* determine the new state of the action */
2585
active = gtk_toggle_action_get_active (action);
2587
/* check if we should drop the statusbar */
2588
if (!active && window->statusbar != NULL)
2590
/* just get rid of the statusbar */
2591
gtk_widget_destroy (window->statusbar);
2592
window->statusbar = NULL;
2594
else if (active && window->statusbar == NULL)
2596
/* setup a new statusbar */
2597
window->statusbar = thunar_statusbar_new ();
2598
gtk_table_attach (GTK_TABLE (window->view_box), window->statusbar, 0, 1, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
2599
gtk_widget_show (window->statusbar);
2601
/* connect to the view (if any) */
2602
if (G_LIKELY (window->view != NULL))
2603
thunar_window_binding_create (window, window->view, "statusbar-text", window->statusbar, "text", G_BINDING_SYNC_CREATE);
2606
/* remember the setting */
2607
if (gtk_widget_get_visible (GTK_WIDGET (window)))
2608
g_object_set (G_OBJECT (window->preferences), "last-statusbar-visible", active, NULL);
2614
thunar_window_action_menubar_changed (GtkToggleAction *action,
2615
ThunarWindow *window)
2619
_thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2620
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2622
/* determine the new state of the action */
2623
active = gtk_toggle_action_get_active (action);
2625
/* show or hide the bar */
2626
gtk_widget_set_visible (window->menubar, active);
2628
/* remember the setting */
2629
if (gtk_widget_get_visible (GTK_WIDGET (window)))
2630
g_object_set (G_OBJECT (window->preferences), "last-menubar-visible", active, NULL);
2636
thunar_window_action_zoom_in (GtkAction *action,
2637
ThunarWindow *window)
2641
_thunar_return_if_fail (GTK_IS_ACTION (action));
2642
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2644
/* increase the zoom level */
2645
g_signal_emit (G_OBJECT (window), window_signals[ZOOM_IN], 0, &result);
2651
thunar_window_action_zoom_out (GtkAction *action,
2652
ThunarWindow *window)
2656
_thunar_return_if_fail (GTK_IS_ACTION (action));
2657
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2659
/* decrease the zoom level */
2660
g_signal_emit (G_OBJECT (window), window_signals[ZOOM_OUT], 0, &result);
2666
thunar_window_action_zoom_reset (GtkAction *action,
2667
ThunarWindow *window)
2671
_thunar_return_if_fail (GTK_IS_ACTION (action));
2672
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2674
/* reset zoom level */
2675
g_signal_emit (G_OBJECT (window), window_signals[ZOOM_RESET], 0, &result);
2681
thunar_window_action_view_changed (GtkRadioAction *action,
2682
GtkRadioAction *current,
2683
ThunarWindow *window)
2685
ThunarFile *file = NULL;
2686
ThunarFile *current_directory = NULL;
2687
GtkWidget *old_view;
2689
/* drop the previous view (if any) */
2690
old_view = window->view;
2691
if (G_LIKELY (window->view != NULL))
2693
/* get first visible file in the previous view */
2694
if (!thunar_view_get_visible_range (THUNAR_VIEW (window->view), &file, NULL))
2697
/* store the active directory */
2698
current_directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (window->view));
2699
if (current_directory != NULL)
2700
g_object_ref (current_directory);
2702
/* update the UI (else GtkUIManager will crash on merging) */
2703
gtk_ui_manager_ensure_update (window->ui_manager);
2706
/* determine the new type of view */
2707
window->view_type = view_index2type (gtk_radio_action_get_current_value (action));
2709
/* always open a new directory */
2710
if (current_directory == NULL && window->current_directory != NULL)
2711
current_directory = g_object_ref (window->current_directory);
2713
/* allocate a new view of the requested type */
2714
if (G_LIKELY (window->view_type != G_TYPE_NONE))
2716
/* create new page */
2717
if (current_directory != NULL)
2718
thunar_window_notebook_insert (window, current_directory);
2720
/* scroll to the previously visible file in the old view */
2721
if (G_UNLIKELY (file != NULL))
2722
thunar_view_scroll_to_file (THUNAR_VIEW (window->view), file, FALSE, TRUE, 0.0f, 0.0f);
2726
/* this should not happen under normal conditions */
2727
window->view = NULL;
2730
/* destroy the old view */
2731
if (old_view != NULL)
2732
gtk_widget_destroy (old_view);
2734
/* remember the setting */
2735
if (gtk_widget_get_visible (GTK_WIDGET (window)))
2736
g_object_set (G_OBJECT (window->preferences), "last-view", g_type_name (window->view_type), NULL);
2738
/* release the file references */
2739
if (G_UNLIKELY (file != NULL))
2740
g_object_unref (G_OBJECT (file));
2741
if (G_UNLIKELY (current_directory != NULL))
2742
g_object_unref (G_OBJECT (current_directory));
2748
thunar_window_action_go_up (GtkAction *action,
2749
ThunarWindow *window)
2752
GError *error = NULL;
2754
parent = thunar_file_get_parent (window->current_directory, &error);
2755
if (G_LIKELY (parent != NULL))
2757
thunar_window_set_current_directory (window, parent);
2758
g_object_unref (G_OBJECT (parent));
2762
thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open parent folder"));
2763
g_error_free (error);
2770
thunar_window_action_open_home (GtkAction *action,
2771
ThunarWindow *window)
2774
ThunarFile *home_file;
2775
GError *error = NULL;
2777
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2779
/* determine the path to the home directory */
2780
home = thunar_g_file_new_for_home ();
2782
/* determine the file for the home directory */
2783
home_file = thunar_file_get (home, &error);
2784
if (G_UNLIKELY (home_file == NULL))
2786
/* display an error to the user */
2787
thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open the home folder"));
2788
g_error_free (error);
2792
/* open the home folder */
2793
thunar_window_set_current_directory (window, home_file);
2794
g_object_unref (G_OBJECT (home_file));
2797
/* release our reference on the home path */
2798
g_object_unref (home);
2804
thunar_window_open_user_folder (GtkAction *action,
2805
ThunarWindow *window,
2806
GUserDirectory thunar_user_dir,
2807
const gchar *default_name)
2809
ThunarFile *user_file = NULL;
2810
gboolean result = FALSE;
2811
GError *error = NULL;
2819
path = g_get_user_special_dir (thunar_user_dir);
2820
home_dir = thunar_g_file_new_for_home ();
2822
/* check if there is an entry in user-dirs.dirs */
2823
path = g_get_user_special_dir (thunar_user_dir);
2824
if (G_LIKELY (path != NULL))
2826
user_dir = g_file_new_for_path (path);
2828
/* if equal to home, leave */
2829
if (g_file_equal (user_dir, home_dir))
2835
user_dir = g_file_resolve_relative_path (home_dir, default_name);
2838
/* try to load the user dir */
2839
user_file = thunar_file_get (user_dir, NULL);
2841
/* check if the directory exists */
2842
if (G_UNLIKELY (user_file == NULL || !thunar_file_exists (user_file)))
2844
/* release the instance if it does not exist */
2845
if (user_file != NULL)
2847
g_object_unref (user_file);
2851
/* ask the user to create the directory */
2852
parse_name = g_file_get_parse_name (user_dir);
2853
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
2854
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
2855
GTK_MESSAGE_QUESTION,
2857
_("The directory \"%s\" does not exist. Do you want to create it?"),
2859
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
2860
response = gtk_dialog_run (GTK_DIALOG (dialog));
2861
gtk_widget_destroy (dialog);
2862
g_free (parse_name);
2864
if (response == GTK_RESPONSE_YES
2865
&& g_file_make_directory_with_parents (user_dir, NULL, &error))
2868
user_file = thunar_file_get (user_dir, &error);
2872
if (G_LIKELY (user_file != NULL))
2874
/* open the folder */
2875
thunar_window_set_current_directory (window, user_file);
2876
g_object_unref (G_OBJECT (user_file));
2879
else if (error != NULL)
2881
parse_name = g_file_get_parse_name (user_dir);
2882
thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open directory \"%s\""), parse_name);
2883
g_free (parse_name);
2884
g_error_free (error);
2889
g_object_unref (user_dir);
2890
g_object_unref (home_dir);
2898
thunar_window_action_open_desktop (GtkAction *action,
2899
ThunarWindow *window)
2901
_thunar_return_if_fail (GTK_IS_ACTION (action));
2902
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2904
thunar_window_open_user_folder (action, window,
2905
G_USER_DIRECTORY_DESKTOP,
2912
thunar_window_action_open_templates (GtkAction *action,
2913
ThunarWindow *window)
2921
gboolean show_about_templates;
2924
_thunar_return_if_fail (GTK_IS_ACTION (action));
2925
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
2927
success = thunar_window_open_user_folder (action,window,
2928
G_USER_DIRECTORY_TEMPLATES,
2931
/* check whether we should display the "About Templates" dialog */
2932
g_object_get (G_OBJECT (window->preferences),
2933
"misc-show-about-templates", &show_about_templates,
2936
if (G_UNLIKELY(show_about_templates && success))
2938
/* display the "About Templates" dialog */
2939
dialog = gtk_dialog_new_with_buttons (_("About Templates"), GTK_WINDOW (window),
2940
GTK_DIALOG_DESTROY_WITH_PARENT
2941
| GTK_DIALOG_NO_SEPARATOR,
2942
GTK_STOCK_OK, GTK_RESPONSE_OK,
2945
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
2947
hbox = gtk_hbox_new (FALSE, 6);
2948
gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
2949
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0);
2950
gtk_widget_show (hbox);
2952
image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
2953
gtk_misc_set_alignment (GTK_MISC (image), 0.5f, 0.0f);
2954
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
2955
gtk_widget_show (image);
2957
vbox = gtk_vbox_new (FALSE, 18);
2958
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
2959
gtk_widget_show (vbox);
2961
label = gtk_label_new (_("All files in this folder will appear in the \"Create Document\" menu."));
2962
gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
2963
gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_big_bold ());
2964
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
2965
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
2966
gtk_widget_show (label);
2968
label = gtk_label_new (_("If you frequently create certain kinds "
2969
" of documents, make a copy of one and put it in this "
2970
"folder. Thunar will add an entry for this document in the"
2971
" \"Create Document\" menu.\n\n"
2972
"You can then select the entry from the \"Create Document\" "
2973
"menu and a copy of the document will be created in the "
2974
"directory you are viewing."));
2975
gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
2976
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
2977
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
2978
gtk_widget_show (label);
2980
button = gtk_check_button_new_with_mnemonic (_("Do _not display this message again"));
2981
exo_mutual_binding_new_with_negation (G_OBJECT (window->preferences), "misc-show-about-templates", G_OBJECT (button), "active");
2982
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2983
gtk_widget_show (button);
2985
gtk_dialog_run (GTK_DIALOG (dialog));
2986
gtk_widget_destroy (dialog);
2993
thunar_window_action_open_file_system (GtkAction *action,
2994
ThunarWindow *window)
2997
ThunarFile *root_file;
2998
GError *error = NULL;
3000
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3002
/* determine the path to the root directory */
3003
root = thunar_g_file_new_for_root ();
3005
/* determine the file for the root directory */
3006
root_file = thunar_file_get (root, &error);
3007
if (G_UNLIKELY (root_file == NULL))
3009
/* display an error to the user */
3010
thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to open the file system root folder"));
3011
g_error_free (error);
3015
/* open the root folder */
3016
thunar_window_set_current_directory (window, root_file);
3017
g_object_unref (G_OBJECT (root_file));
3020
/* release our reference on the home path */
3021
g_object_unref (root);
3027
thunar_window_action_open_trash (GtkAction *action,
3028
ThunarWindow *window)
3031
ThunarFile *trash_bin_file;
3032
GError *error = NULL;
3034
_thunar_return_if_fail (GTK_IS_ACTION (action));
3035
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3037
/* determine the path to the trash bin */
3038
trash_bin = thunar_g_file_new_for_trash ();
3040
/* determine the file for the trash bin */
3041
trash_bin_file = thunar_file_get (trash_bin, &error);
3042
if (G_UNLIKELY (trash_bin_file == NULL))
3044
/* display an error to the user */
3045
thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to display the contents of the trash can"));
3046
g_error_free (error);
3050
/* open the trash folder */
3051
thunar_window_set_current_directory (window, trash_bin_file);
3052
g_object_unref (G_OBJECT (trash_bin_file));
3055
/* release our reference on the trash bin path */
3056
g_object_unref (trash_bin);
3062
thunar_window_action_open_network (GtkAction *action,
3063
ThunarWindow *window)
3065
ThunarFile *network_file;
3066
GError *error = NULL;
3069
_thunar_return_if_fail (GTK_IS_ACTION (action));
3070
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3072
/* determine the network root location */
3073
network = g_file_new_for_uri ("network://");
3075
/* determine the file for this location */
3076
network_file = thunar_file_get (network, &error);
3077
if (G_UNLIKELY (network_file == NULL))
3079
/* display an error to the user */
3080
thunar_dialogs_show_error (GTK_WIDGET (window), error, _("Failed to browse the network"));
3081
g_error_free (error);
3085
/* open the network root location */
3086
thunar_window_set_current_directory (window, network_file);
3087
g_object_unref (G_OBJECT (network_file));
3090
/* release our reference on the location itself */
3091
g_object_unref (network);
3097
thunar_window_poke_location_finish (ThunarBrowser *browser,
3100
ThunarFile *target_file,
3104
_thunar_return_if_fail (THUNAR_IS_WINDOW (browser));
3105
_thunar_return_if_fail (THUNAR_IS_FILE (file));
3107
thunar_window_poke_file_finish (browser, file, target_file, error, ignored);
3113
thunar_window_action_open_bookmark (GtkAction *action,
3114
ThunarWindow *window)
3116
ThunarFile *local_file;
3119
/* try to open the local file */
3120
local_file = g_object_get_data (G_OBJECT (action), I_("thunar-file"));
3121
if (local_file != NULL)
3123
thunar_window_set_current_directory (window, local_file);
3127
/* try to the remote file */
3128
remote_file = g_object_get_data (G_OBJECT (action), I_("location-file"));
3129
if (remote_file != NULL)
3131
thunar_browser_poke_location (THUNAR_BROWSER (window), remote_file, window,
3132
thunar_window_poke_location_finish, NULL);
3139
thunar_window_action_open_location (GtkAction *action,
3140
ThunarWindow *window)
3142
/* just use the "start-open-location" callback */
3143
thunar_window_start_open_location (window, NULL);
3149
thunar_window_action_contents (GtkAction *action,
3150
ThunarWindow *window)
3152
/* display the documentation index */
3153
xfce_dialog_show_help (GTK_WINDOW (window), "thunar", NULL, NULL);
3159
thunar_window_action_about (GtkAction *action,
3160
ThunarWindow *window)
3162
/* just popup the about dialog */
3163
thunar_dialogs_show_about (GTK_WINDOW (window), PACKAGE_NAME,
3164
_("Thunar is a fast and easy to use file manager\n"
3165
"for the Xfce Desktop Environment."));
3171
thunar_window_action_show_hidden (GtkToggleAction *action,
3172
ThunarWindow *window)
3174
_thunar_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3175
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3177
/* just emit the "notify" signal for the "show-hidden"
3178
* signal and the view will automatically sync its state.
3180
g_object_notify (G_OBJECT (window), "show-hidden");
3182
if (gtk_widget_get_visible (GTK_WIDGET (window)))
3183
g_object_set (G_OBJECT (window->preferences), "last-show-hidden",
3184
gtk_toggle_action_get_active (action), NULL);
3190
thunar_window_current_directory_changed (ThunarFile *current_directory,
3191
ThunarWindow *window)
3193
GtkIconTheme *icon_theme;
3195
const gchar *icon_name;
3197
gboolean show_full_path;
3198
gchar *parse_name = NULL;
3201
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3202
_thunar_return_if_fail (THUNAR_IS_FILE (current_directory));
3203
_thunar_return_if_fail (window->current_directory == current_directory);
3205
/* update the "Empty Trash" action */
3206
action = gtk_action_group_get_action (window->action_group, "empty-trash");
3207
gtk_action_set_sensitive (action, (thunar_file_get_item_count (current_directory) > 0));
3208
gtk_action_set_visible (action, (thunar_file_is_root (current_directory) && thunar_file_is_trashed (current_directory)));
3210
/* get name of directory or full path */
3211
g_object_get (G_OBJECT (window->preferences), "misc-full-path-in-title", &show_full_path, NULL);
3212
if (G_UNLIKELY (show_full_path))
3213
name = parse_name = g_file_get_parse_name (thunar_file_get_file (current_directory));
3215
name = thunar_file_get_display_name (current_directory);
3217
/* set window title */
3218
title = g_strdup_printf ("%s - %s", name, _("File Manager"));
3219
gtk_window_set_title (GTK_WINDOW (window), title);
3221
g_free (parse_name);
3223
/* set window icon */
3224
icon_theme = gtk_icon_theme_get_for_screen (gtk_window_get_screen (GTK_WINDOW (window)));
3225
icon_name = thunar_file_get_icon_name (current_directory,
3226
THUNAR_FILE_ICON_STATE_DEFAULT,
3228
gtk_window_set_icon_name (GTK_WINDOW (window), icon_name);
3234
thunar_window_connect_proxy (GtkUIManager *manager,
3237
ThunarWindow *window)
3239
/* we want to get informed when the user hovers a menu item */
3240
if (GTK_IS_MENU_ITEM (proxy))
3242
g_signal_connect_closure (G_OBJECT (proxy), "select", window->menu_item_selected_closure, FALSE);
3243
g_signal_connect_closure (G_OBJECT (proxy), "deselect", window->menu_item_deselected_closure, FALSE);
3250
thunar_window_disconnect_proxy (GtkUIManager *manager,
3253
ThunarWindow *window)
3255
/* undo what we did in connect_proxy() */
3256
if (GTK_IS_MENU_ITEM (proxy))
3258
g_signal_handlers_disconnect_matched (G_OBJECT (proxy), G_SIGNAL_MATCH_CLOSURE, 0, 0, window->menu_item_selected_closure, NULL, NULL);
3259
g_signal_handlers_disconnect_matched (G_OBJECT (proxy), G_SIGNAL_MATCH_CLOSURE, 0, 0, window->menu_item_deselected_closure, NULL, NULL);
3266
thunar_window_menu_item_selected (GtkWidget *menu_item,
3267
ThunarWindow *window)
3270
const gchar *tooltip;
3272
gchar *short_tip = NULL;
3275
/* we can only display tooltips if we have a statusbar */
3276
if (G_LIKELY (window->statusbar != NULL))
3278
/* determine the action for the menu item */
3279
action = gtk_widget_get_action (menu_item);
3280
if (G_UNLIKELY (action == NULL))
3283
/* determine the tooltip from the action */
3284
tooltip = gtk_action_get_tooltip (action);
3285
if (G_LIKELY (tooltip != NULL))
3287
/* check if there is a new line in the tooltip */
3288
p = strchr (tooltip, '\n');
3291
short_tip = g_strndup (tooltip, p - tooltip);
3292
tooltip = short_tip;
3295
/* push to the statusbar */
3296
id = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->statusbar), "Menu tooltip");
3297
gtk_statusbar_push (GTK_STATUSBAR (window->statusbar), id, tooltip);
3306
thunar_window_menu_item_deselected (GtkWidget *menu_item,
3307
ThunarWindow *window)
3311
/* we can only undisplay tooltips if we have a statusbar */
3312
if (G_LIKELY (window->statusbar != NULL))
3314
/* drop the last tooltip from the statusbar */
3315
id = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->statusbar), "Menu tooltip");
3316
gtk_statusbar_pop (GTK_STATUSBAR (window->statusbar), id);
3323
thunar_window_update_custom_actions (ThunarView *view,
3325
ThunarWindow *window)
3328
GList *selected_files;
3329
GList *actions = NULL;
3334
_thunar_return_if_fail (THUNAR_IS_VIEW (view));
3335
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3337
/* leave if the signal is emitted from a non-active tab */
3338
if (!gtk_widget_get_realized (GTK_WIDGET (window))
3339
|| window->view != GTK_WIDGET (view))
3342
/* load the menu provides from the provider factory */
3343
providers = thunarx_provider_factory_list_providers (window->provider_factory,
3344
THUNARX_TYPE_MENU_PROVIDER);
3345
if (G_LIKELY (providers != NULL))
3347
/* grab a reference to the current directory of the window */
3348
folder = thunar_window_get_current_directory (window);
3350
/* get a list of selected files */
3351
selected_files = thunar_component_get_selected_files (THUNAR_COMPONENT (view));
3353
/* load the actions offered by the menu providers */
3354
for (lp = providers; lp != NULL; lp = lp->next)
3356
if (G_LIKELY (selected_files != NULL))
3358
tmp = thunarx_menu_provider_get_file_actions (lp->data,
3359
GTK_WIDGET (window),
3362
else if (G_LIKELY (folder != NULL))
3364
tmp = thunarx_menu_provider_get_folder_actions (lp->data,
3365
GTK_WIDGET (window),
3366
THUNARX_FILE_INFO (folder));
3373
actions = g_list_concat (actions, tmp);
3374
g_object_unref (G_OBJECT (lp->data));
3376
g_list_free (providers);
3379
/* remove previously inserted menu actions from the UI manager */
3380
if (window->custom_merge_id != 0)
3382
gtk_ui_manager_remove_ui (window->ui_manager, window->custom_merge_id);
3383
gtk_ui_manager_ensure_update (window->ui_manager);
3384
window->custom_merge_id = 0;
3387
/* drop any previous custom action group */
3388
if (window->custom_actions != NULL)
3390
gtk_ui_manager_remove_action_group (window->ui_manager, window->custom_actions);
3391
g_object_unref (window->custom_actions);
3392
window->custom_actions = NULL;
3395
/* add the actions specified by the menu providers */
3396
if (G_LIKELY (actions != NULL))
3398
/* allocate the action group and the merge id for the custom actions */
3399
window->custom_actions = gtk_action_group_new ("ThunarActions");
3400
window->custom_merge_id = gtk_ui_manager_new_merge_id (window->ui_manager);
3401
gtk_ui_manager_insert_action_group (window->ui_manager, window->custom_actions, -1);
3403
/* add the actions to the UI manager */
3404
for (lp = actions; lp != NULL; lp = lp->next)
3406
/* add the action to the action group */
3407
gtk_action_group_add_action_with_accel (window->custom_actions,
3408
GTK_ACTION (lp->data),
3411
/* add to the file context menu */
3412
gtk_ui_manager_add_ui (window->ui_manager,
3413
window->custom_merge_id,
3414
"/main-menu/file-menu/placeholder-custom-actions",
3415
gtk_action_get_name (GTK_ACTION (lp->data)),
3416
gtk_action_get_name (GTK_ACTION (lp->data)),
3417
GTK_UI_MANAGER_MENUITEM, FALSE);
3419
/* release the reference on the action */
3420
g_object_unref (G_OBJECT (lp->data));
3424
g_list_free (actions);
3431
thunar_window_notify_loading (ThunarView *view,
3433
ThunarWindow *window)
3437
_thunar_return_if_fail (THUNAR_IS_VIEW (view));
3438
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3440
if (gtk_widget_get_realized (GTK_WIDGET (window))
3441
&& window->view == GTK_WIDGET (view))
3443
/* setup the proper cursor */
3444
if (thunar_view_get_loading (view))
3446
cursor = gdk_cursor_new (GDK_WATCH);
3447
gdk_window_set_cursor (GTK_WIDGET (window)->window, cursor);
3448
gdk_cursor_unref (cursor);
3452
gdk_window_set_cursor (GTK_WIDGET (window)->window, NULL);
3460
thunar_window_device_pre_unmount (ThunarDeviceMonitor *device_monitor,
3461
ThunarDevice *device,
3463
ThunarWindow *window)
3467
_thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (device_monitor));
3468
_thunar_return_if_fail (window->device_monitor == device_monitor);
3469
_thunar_return_if_fail (THUNAR_IS_DEVICE (device));
3470
_thunar_return_if_fail (G_IS_FILE (root_file));
3471
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3473
/* nothing to do if we don't have a current directory */
3474
if (G_UNLIKELY (window->current_directory == NULL))
3477
/* check if the file is the current directory or an ancestor of the current directory */
3478
if (thunar_file_is_gfile_ancestor (window->current_directory, root_file))
3480
/* change to the home folder */
3481
action = gtk_action_group_get_action (window->action_group, "open-home");
3482
if (G_LIKELY (action != NULL))
3483
gtk_action_activate (action);
3490
thunar_window_device_changed (ThunarDeviceMonitor *device_monitor,
3491
ThunarDevice *device,
3492
ThunarWindow *window)
3496
_thunar_return_if_fail (THUNAR_IS_DEVICE_MONITOR (device_monitor));
3497
_thunar_return_if_fail (window->device_monitor == device_monitor);
3498
_thunar_return_if_fail (THUNAR_IS_DEVICE (device));
3499
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3501
if (thunar_device_is_mounted (device))
3504
root_file = thunar_device_get_root (device);
3505
if (root_file != NULL)
3507
thunar_window_device_pre_unmount (device_monitor, device, root_file, window);
3508
g_object_unref (root_file);
3515
thunar_window_merge_idle (gpointer user_data)
3517
ThunarWindow *window = THUNAR_WINDOW (user_data);
3519
/* merge custom preferences from the providers */
3520
GDK_THREADS_ENTER ();
3521
thunar_window_merge_custom_preferences (window);
3522
thunar_window_merge_go_actions (window);
3523
GDK_THREADS_LEAVE ();
3525
thunar_window_bookmark_merge (window);
3533
thunar_window_merge_idle_destroy (gpointer user_data)
3535
THUNAR_WINDOW (user_data)->merge_idle_id = 0;
3541
thunar_window_save_paned (ThunarWindow *window)
3543
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
3545
g_object_set (G_OBJECT (window->preferences), "last-separator-position",
3546
gtk_paned_get_position (GTK_PANED (window->paned)), NULL);
3548
/* for button release event */
3555
thunar_window_save_geometry_timer (gpointer user_data)
3557
GdkWindowState state;
3558
ThunarWindow *window = THUNAR_WINDOW (user_data);
3559
gboolean remember_geometry;
3563
GDK_THREADS_ENTER ();
3565
/* check if we should remember the window geometry */
3566
g_object_get (G_OBJECT (window->preferences), "misc-remember-geometry", &remember_geometry, NULL);
3567
if (G_LIKELY (remember_geometry))
3569
/* check if the window is still visible */
3570
if (gtk_widget_get_visible (GTK_WIDGET (window)))
3572
/* determine the current state of the window */
3573
state = gdk_window_get_state (GTK_WIDGET (window)->window);
3575
/* don't save geometry for maximized or fullscreen windows */
3576
if ((state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
3578
/* determine the current width/height of the window... */
3579
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
3581
/* ...and remember them as default for new windows */
3582
g_object_set (G_OBJECT (window->preferences), "last-window-width", width, "last-window-height", height,
3583
"last-window-maximized", FALSE, NULL);
3587
/* only store that the window is full screen */
3588
g_object_set (G_OBJECT (window->preferences), "last-window-maximized", TRUE, NULL);
3593
GDK_THREADS_LEAVE ();
3601
thunar_window_save_geometry_timer_destroy (gpointer user_data)
3603
THUNAR_WINDOW (user_data)->save_geometry_timer_id = 0;
3609
* thunar_window_set_zoom_level:
3610
* @window : a #ThunarWindow instance.
3611
* @zoom_level : the new zoom level for @window.
3613
* Sets the zoom level for @window to @zoom_level.
3616
thunar_window_set_zoom_level (ThunarWindow *window,
3617
ThunarZoomLevel zoom_level)
3619
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3620
_thunar_return_if_fail (zoom_level < THUNAR_ZOOM_N_LEVELS);
3622
/* check if we have a new zoom level */
3623
if (G_LIKELY (window->zoom_level != zoom_level))
3625
/* remember the new zoom level */
3626
window->zoom_level = zoom_level;
3628
/* notify listeners */
3629
g_object_notify (G_OBJECT (window), "zoom-level");
3632
/* update the "Zoom In" and "Zoom Out" actions */
3633
thunar_gtk_action_group_set_action_sensitive (window->action_group, "zoom-in", (zoom_level < THUNAR_ZOOM_N_LEVELS - 1));
3634
thunar_gtk_action_group_set_action_sensitive (window->action_group, "zoom-out", (zoom_level > 0));
3640
* thunar_window_get_current_directory:
3641
* @window : a #ThunarWindow instance.
3643
* Queries the #ThunarFile instance, which represents the directory
3644
* currently displayed within @window. %NULL is returned if @window
3645
* is not currently associated with any directory.
3647
* Return value: the directory currently displayed within @window or %NULL.
3650
thunar_window_get_current_directory (ThunarWindow *window)
3652
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL);
3653
return window->current_directory;
3659
* thunar_window_set_current_directory:
3660
* @window : a #ThunarWindow instance.
3661
* @current_directory : the new directory or %NULL.
3664
thunar_window_set_current_directory (ThunarWindow *window,
3665
ThunarFile *current_directory)
3671
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3672
_thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory));
3674
/* check if we already display the requested directory */
3675
if (G_UNLIKELY (window->current_directory == current_directory))
3678
/* disconnect from the previously active directory */
3679
if (G_LIKELY (window->current_directory != NULL))
3681
/* disconnect signals and release reference */
3682
g_signal_handlers_disconnect_by_func (G_OBJECT (window->current_directory), thunar_window_current_directory_changed, window);
3683
g_object_unref (G_OBJECT (window->current_directory));
3686
/* activate the new directory */
3687
window->current_directory = current_directory;
3689
/* connect to the new directory */
3690
if (G_LIKELY (current_directory != NULL))
3692
/* take a reference on the file and connect the "changed"/"destroy" signals */
3693
g_signal_connect (G_OBJECT (current_directory), "changed", G_CALLBACK (thunar_window_current_directory_changed), window);
3694
g_object_ref (G_OBJECT (current_directory));
3696
/* create a new view if the window is new */
3697
if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) == 0)
3699
/* determine the last selected view if we don't have a valid default */
3700
g_object_get (G_OBJECT (window->preferences), "last-view", &type_name, NULL);
3701
type = g_type_from_name (type_name);
3703
/* activate the selected view */
3704
action = gtk_action_group_get_action (window->action_group, "view-as-icons");
3705
g_signal_handlers_block_by_func (action, thunar_window_action_view_changed, window);
3706
gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), view_type2index (g_type_is_a (type, THUNAR_TYPE_VIEW) ? type : THUNAR_TYPE_ICON_VIEW));
3707
thunar_window_action_view_changed (GTK_RADIO_ACTION (action), GTK_RADIO_ACTION (action), window);
3708
g_signal_handlers_unblock_by_func (action, thunar_window_action_view_changed, window);
3711
/* update window icon and title */
3712
thunar_window_current_directory_changed (current_directory, window);
3714
/* grab the focus to the main view */
3715
if (G_LIKELY (window->view != NULL))
3716
gtk_widget_grab_focus (window->view);
3719
/* enable the 'Open new window' action if we have a valid directory */
3720
thunar_gtk_action_group_set_action_sensitive (window->action_group, "new-window", (current_directory != NULL));
3721
thunar_gtk_action_group_set_action_sensitive (window->action_group, "new-tab", (current_directory != NULL));
3723
/* enable the 'Up' action if possible for the new directory */
3724
thunar_gtk_action_group_set_action_sensitive (window->action_group, "open-parent", (current_directory != NULL
3725
&& thunar_file_has_parent (current_directory)));
3727
/* tell everybody that we have a new "current-directory",
3728
* we do this first so other widgets display the new
3729
* state already while the folder view is loading.
3731
g_object_notify (G_OBJECT (window), "current-directory");
3737
* thunar_window_scroll_to_file:
3738
* @window : a #ThunarWindow instance.
3739
* @file : a #ThunarFile.
3740
* @select_file : if %TRUE the @file will also be selected.
3741
* @use_align : %TRUE to use the alignment arguments.
3742
* @row_align : the vertical alignment.
3743
* @col_align : the horizontal alignment.
3745
* Tells the @window to scroll to the @file
3746
* in the current view.
3749
thunar_window_scroll_to_file (ThunarWindow *window,
3751
gboolean select_file,
3756
_thunar_return_if_fail (THUNAR_IS_WINDOW (window));
3757
_thunar_return_if_fail (THUNAR_IS_FILE (file));
3759
/* verify that we have a valid view */
3760
if (G_LIKELY (window->view != NULL))
3761
thunar_view_scroll_to_file (THUNAR_VIEW (window->view), file, select_file, use_align, row_align, col_align);
3767
thunar_window_get_directories (ThunarWindow *window,
3774
ThunarFile *directory;
3776
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), NULL);
3778
n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
3779
if (G_UNLIKELY (n_pages == 0))
3782
/* create array of uris */
3783
uris = g_new0 (gchar *, n_pages + 1);
3784
for (n = 0; n < n_pages; n++)
3787
view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), n);
3788
_thunar_return_val_if_fail (THUNAR_IS_NAVIGATOR (view), FALSE);
3790
/* get the directory of the view */
3791
directory = thunar_navigator_get_current_directory (THUNAR_NAVIGATOR (view));
3792
_thunar_return_val_if_fail (THUNAR_IS_FILE (directory), FALSE);
3795
uris[n] = thunar_file_dup_uri (directory);
3799
if (active_page != NULL)
3800
*active_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook));
3808
thunar_window_set_directories (ThunarWindow *window,
3812
ThunarFile *directory;
3815
_thunar_return_val_if_fail (THUNAR_IS_WINDOW (window), FALSE);
3816
_thunar_return_val_if_fail (uris != NULL, FALSE);
3818
for (n = 0; uris[n] != NULL; n++)
3820
/* check if the string looks like an uri */
3821
if (!exo_str_looks_like_an_uri (uris[n]))
3824
/* get the file for the uri */
3825
directory = thunar_file_get_for_uri (uris[n], NULL);
3826
if (G_UNLIKELY (directory == NULL))
3829
/* open the directory in a new notebook */
3830
if (thunar_file_is_directory (directory))
3832
if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) == 0)
3833
thunar_window_set_current_directory (window, directory);
3835
thunar_window_notebook_insert (window, directory);
3838
g_object_unref (G_OBJECT (directory));
3841
/* select the page */
3842
gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), active_page);
3844
/* we succeeded if new pages have been opened */
3845
return gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) > 0;