~noskcaj/ubuntu/vivid/thunar/1.6.4

« back to all changes in this revision

Viewing changes to thunar/thunar-shortcuts-view.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc
  • Date: 2010-12-04 16:46:20 UTC
  • mto: (2.1.3 experimental) (1.3.1)
  • mto: This revision was merged to the branch mainline in revision 69.
  • Revision ID: james.westby@ubuntu.com-20101204164620-h7p4t2e9z6hfhz6l
Tags: upstream-1.1.4
ImportĀ upstreamĀ versionĀ 1.1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id$ */
 
1
/* vi:set et ai sw=2 sts=2 ts=2: */
2
2
/*-
3
3
 * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org>
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify it
6
 
 * under the terms of the GNU General Public License as published by the Free
7
 
 * Software Foundation; either version 2 of the License, or (at your option)
8
 
 * any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful, but WITHOUT
11
 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
 
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13
 
 * more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License along with
16
 
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17
 
 * Place, Suite 330, Boston, MA  02111-1307  USA
18
 
 *
19
 
 * Inspired by the shortcuts list as found in the GtkFileChooser, which was
20
 
 * developed for Gtk+ by Red Hat, Inc.
 
4
 * Copyright (c) 2009-2010 Jannis Pohlmann <jannis@xfce.org>
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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.
21
20
 */
22
21
 
23
22
#ifdef HAVE_CONFIG_H
31
30
#include <string.h>
32
31
#endif
33
32
 
 
33
#ifdef HAVE_LIBNOTIFY
 
34
#include <thunar/thunar-notify.h>
 
35
#endif
34
36
#include <thunar/thunar-application.h>
 
37
#include <thunar/thunar-browser.h>
35
38
#include <thunar/thunar-dialogs.h>
36
39
#include <thunar/thunar-dnd.h>
 
40
#include <thunar/thunar-gio-extensions.h>
37
41
#include <thunar/thunar-gtk-extensions.h>
38
42
#include <thunar/thunar-preferences.h>
39
43
#include <thunar/thunar-private.h>
59
63
 
60
64
 
61
65
 
62
 
static void           thunar_shortcuts_view_class_init            (ThunarShortcutsViewClass *klass);
63
 
static void           thunar_shortcuts_view_init                  (ThunarShortcutsView      *view);
64
 
static void           thunar_shortcuts_view_finalize              (GObject                  *object);
65
 
static gboolean       thunar_shortcuts_view_button_press_event    (GtkWidget                *widget,
66
 
                                                                   GdkEventButton           *event);
67
 
static gboolean       thunar_shortcuts_view_button_release_event  (GtkWidget                *widget,
68
 
                                                                   GdkEventButton           *event);
69
 
static void           thunar_shortcuts_view_drag_begin            (GtkWidget                *widget,
70
 
                                                                   GdkDragContext           *context);
71
 
static void           thunar_shortcuts_view_drag_data_received    (GtkWidget                *widget,
72
 
                                                                   GdkDragContext           *context,
73
 
                                                                   gint                      x,
74
 
                                                                   gint                      y,
75
 
                                                                   GtkSelectionData         *selection_data,
76
 
                                                                   guint                     info,
77
 
                                                                   guint                     time);
78
 
static gboolean       thunar_shortcuts_view_drag_drop             (GtkWidget                *widget,
79
 
                                                                   GdkDragContext           *context,
80
 
                                                                   gint                      x,
81
 
                                                                   gint                      y,
82
 
                                                                   guint                     time);
83
 
static gboolean       thunar_shortcuts_view_drag_motion           (GtkWidget                *widget,
84
 
                                                                   GdkDragContext           *context,
85
 
                                                                   gint                      x,
86
 
                                                                   gint                      y,
87
 
                                                                   guint                     time);
88
 
static void           thunar_shortcuts_view_drag_leave            (GtkWidget                *widget,
89
 
                                                                   GdkDragContext           *context,
90
 
                                                                   guint                     time);
91
 
static gboolean       thunar_shortcuts_view_popup_menu            (GtkWidget                *widget);
92
 
static void           thunar_shortcuts_view_row_activated         (GtkTreeView              *tree_view,
93
 
                                                                   GtkTreePath              *path,
94
 
                                                                   GtkTreeViewColumn        *column);
95
 
static void           thunar_shortcuts_view_context_menu          (ThunarShortcutsView      *view,
96
 
                                                                   GdkEventButton           *event,
97
 
                                                                   GtkTreeModel             *model,
98
 
                                                                   GtkTreeIter              *iter);
99
 
static void           thunar_shortcuts_view_remove_activated      (GtkWidget                *item,
100
 
                                                                   ThunarShortcutsView      *view);
101
 
static void           thunar_shortcuts_view_rename_activated      (GtkWidget                *item,
102
 
                                                                   ThunarShortcutsView      *view);
103
 
static void           thunar_shortcuts_view_renamed               (GtkCellRenderer          *renderer,
104
 
                                                                   const gchar              *path_string,
105
 
                                                                   const gchar              *text,
106
 
                                                                   ThunarShortcutsView      *view);
107
 
static GdkDragAction  thunar_shortcuts_view_compute_drop_actions  (ThunarShortcutsView      *view,
108
 
                                                                   GdkDragContext           *context,
109
 
                                                                   gint                      x,
110
 
                                                                   gint                      y,
111
 
                                                                   GtkTreePath             **path_return,
112
 
                                                                   GdkDragAction            *action_return,
113
 
                                                                   GtkTreeViewDropPosition  *position_return);
114
 
static GtkTreePath   *thunar_shortcuts_view_compute_drop_position (ThunarShortcutsView      *view,
115
 
                                                                   gint                      x,
116
 
                                                                   gint                      y);
117
 
static void           thunar_shortcuts_view_drop_uri_list         (ThunarShortcutsView      *view,
118
 
                                                                   GList                    *path_list,
119
 
                                                                   GtkTreePath              *dst_path);
120
 
static void           thunar_shortcuts_view_open                  (ThunarShortcutsView      *view);
121
 
static void           thunar_shortcuts_view_open_in_new_window    (ThunarShortcutsView      *view);
122
 
static void           thunar_shortcuts_view_empty_trash           (ThunarShortcutsView      *view);
123
 
static gboolean       thunar_shortcuts_view_eject                 (ThunarShortcutsView      *view);
124
 
static gboolean       thunar_shortcuts_view_mount                 (ThunarShortcutsView      *view);
125
 
static gboolean       thunar_shortcuts_view_unmount               (ThunarShortcutsView      *view);
126
 
static gboolean       thunar_shortcuts_view_separator_func        (GtkTreeModel             *model,
127
 
                                                                   GtkTreeIter              *iter,
128
 
                                                                   gpointer                  user_data);
 
66
static void           thunar_shortcuts_view_finalize                     (GObject                  *object);
 
67
static gboolean       thunar_shortcuts_view_button_press_event           (GtkWidget                *widget,
 
68
                                                                          GdkEventButton           *event);
 
69
static gboolean       thunar_shortcuts_view_button_release_event         (GtkWidget                *widget,
 
70
                                                                          GdkEventButton           *event);
 
71
static void           thunar_shortcuts_view_drag_begin                   (GtkWidget                *widget,
 
72
                                                                          GdkDragContext           *context);
 
73
static void           thunar_shortcuts_view_drag_data_received           (GtkWidget                *widget,
 
74
                                                                          GdkDragContext           *context,
 
75
                                                                          gint                      x,
 
76
                                                                          gint                      y,
 
77
                                                                          GtkSelectionData         *selection_data,
 
78
                                                                          guint                     info,
 
79
                                                                          guint                     timestamp);
 
80
static gboolean       thunar_shortcuts_view_drag_drop                    (GtkWidget                *widget,
 
81
                                                                          GdkDragContext           *context,
 
82
                                                                          gint                      x,
 
83
                                                                          gint                      y,
 
84
                                                                          guint                     timestamp);
 
85
static gboolean       thunar_shortcuts_view_drag_motion                  (GtkWidget                *widget,
 
86
                                                                          GdkDragContext           *context,
 
87
                                                                          gint                      x,
 
88
                                                                          gint                      y,
 
89
                                                                          guint                     timestamp);
 
90
static void           thunar_shortcuts_view_drag_leave                   (GtkWidget                *widget,
 
91
                                                                          GdkDragContext           *context,
 
92
                                                                          guint                     timestamp);
 
93
static gboolean       thunar_shortcuts_view_popup_menu                   (GtkWidget                *widget);
 
94
static void           thunar_shortcuts_view_row_activated                (GtkTreeView              *tree_view,
 
95
                                                                          GtkTreePath              *path,
 
96
                                                                          GtkTreeViewColumn        *column);
 
97
static void           thunar_shortcuts_view_context_menu                 (ThunarShortcutsView      *view,
 
98
                                                                          GdkEventButton           *event,
 
99
                                                                          GtkTreeModel             *model,
 
100
                                                                          GtkTreeIter              *iter);
 
101
static void           thunar_shortcuts_view_remove_activated             (GtkWidget                *item,
 
102
                                                                          ThunarShortcutsView      *view);
 
103
static void           thunar_shortcuts_view_rename_activated             (GtkWidget                *item,
 
104
                                                                          ThunarShortcutsView      *view);
 
105
static void           thunar_shortcuts_view_renamed                      (GtkCellRenderer          *renderer,
 
106
                                                                          const gchar              *path_string,
 
107
                                                                          const gchar              *text,
 
108
                                                                          ThunarShortcutsView      *view);
 
109
static GdkDragAction  thunar_shortcuts_view_compute_drop_actions         (ThunarShortcutsView      *view,
 
110
                                                                          GdkDragContext           *context,
 
111
                                                                          gint                      x,
 
112
                                                                          gint                      y,
 
113
                                                                          GtkTreePath             **path_return,
 
114
                                                                          GdkDragAction            *action_return,
 
115
                                                                          GtkTreeViewDropPosition  *position_return);
 
116
static GtkTreePath   *thunar_shortcuts_view_compute_drop_position        (ThunarShortcutsView      *view,
 
117
                                                                          gint                      x,
 
118
                                                                          gint                      y);
 
119
static void           thunar_shortcuts_view_drop_uri_list                (ThunarShortcutsView      *view,
 
120
                                                                          GList                    *path_list,
 
121
                                                                          GtkTreePath              *dst_path);
 
122
static void           thunar_shortcuts_view_open_clicked                 (ThunarShortcutsView      *view);
 
123
static void           thunar_shortcuts_view_open                         (ThunarShortcutsView      *view,
 
124
                                                                          gboolean                  new_window);
 
125
static void           thunar_shortcuts_view_open_in_new_window_clicked   (ThunarShortcutsView      *view);
 
126
static void           thunar_shortcuts_view_empty_trash                  (ThunarShortcutsView      *view);
 
127
static void           thunar_shortcuts_view_eject                        (ThunarShortcutsView      *view);
 
128
static void           thunar_shortcuts_view_mount                        (ThunarShortcutsView      *view);
 
129
static gboolean       thunar_shortcuts_view_separator_func               (GtkTreeModel             *model,
 
130
                                                                          GtkTreeIter              *iter,
 
131
                                                                          gpointer                  user_data);
129
132
 
130
133
 
131
134
 
147
150
   * button-release-event should activate.
148
151
   */
149
152
  gint pressed_button;
 
153
  guint pressed_eject_button : 1;
150
154
 
151
155
  /* drop site support */
152
156
  guint  drop_data_ready : 1; /* whether the drop data was received already */
153
157
  guint  drop_occurred : 1;
154
 
  GList *drop_path_list;      /* the list of URIs that are contained in the drop data */
 
158
  GList *drop_file_list;      /* the list of URIs that are contained in the drop data */
155
159
 
156
 
#if GTK_CHECK_VERSION(2,8,0)
157
160
  /* id of the signal used to queue a resize on the
158
161
   * column whenever the shortcuts icon size is changed.
159
162
   */
160
163
  gint queue_resize_signal_id;
161
 
#endif
162
164
};
163
165
 
164
166
 
176
178
 
177
179
 
178
180
 
179
 
static GObjectClass *thunar_shortcuts_view_parent_class;
180
 
static guint         view_signals[LAST_SIGNAL];
181
 
 
182
 
 
183
 
 
184
 
GType
185
 
thunar_shortcuts_view_get_type (void)
186
 
{
187
 
  static GType type = G_TYPE_INVALID;
188
 
 
189
 
  if (G_UNLIKELY (type == G_TYPE_INVALID))
190
 
    {
191
 
      static const GTypeInfo info =
192
 
      {
193
 
        sizeof (ThunarShortcutsViewClass),
194
 
        NULL,
195
 
        NULL,
196
 
        (GClassInitFunc) thunar_shortcuts_view_class_init,
197
 
        NULL,
198
 
        NULL,
199
 
        sizeof (ThunarShortcutsView),
200
 
        0,
201
 
        (GInstanceInitFunc) thunar_shortcuts_view_init,
202
 
        NULL,
203
 
      };
204
 
 
205
 
      type = g_type_register_static (GTK_TYPE_TREE_VIEW, I_("ThunarShortcutsView"), &info, 0);
206
 
    }
207
 
 
208
 
  return type;
209
 
}
 
181
static guint view_signals[LAST_SIGNAL];
 
182
 
 
183
 
 
184
 
 
185
G_DEFINE_TYPE_WITH_CODE (ThunarShortcutsView, thunar_shortcuts_view, GTK_TYPE_TREE_VIEW,
 
186
                         G_IMPLEMENT_INTERFACE (THUNAR_TYPE_BROWSER, NULL))
210
187
 
211
188
 
212
189
 
217
194
  GtkWidgetClass   *gtkwidget_class;
218
195
  GObjectClass     *gobject_class;
219
196
 
220
 
  /* determine the parent type class */
221
 
  thunar_shortcuts_view_parent_class = g_type_class_peek_parent (klass);
222
 
 
223
197
  gobject_class = G_OBJECT_CLASS (klass);
224
198
  gobject_class->finalize = thunar_shortcuts_view_finalize;
225
199
 
281
255
  gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
282
256
 
283
257
  /* queue a resize on the column whenever the icon size is changed */
284
 
#if GTK_CHECK_VERSION(2,8,0)
285
258
  view->queue_resize_signal_id = g_signal_connect_swapped (G_OBJECT (view->preferences), "notify::shortcuts-icon-size",
286
259
                                                           G_CALLBACK (gtk_tree_view_column_queue_resize), column);
287
 
#endif
288
260
 
289
261
  /* allocate the special icon renderer */
290
262
  view->icon_renderer = thunar_shortcuts_icon_renderer_new ();
304
276
  renderer = g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
305
277
                           "ellipsize-set", TRUE,
306
278
                           "ellipsize", PANGO_ELLIPSIZE_END,
307
 
                           "width-chars", strlen (_("File System")),
 
279
                           "width-chars", g_utf8_strlen (_("File System"), -1),
308
280
                           NULL);
309
281
  g_signal_connect (G_OBJECT (renderer), "edited", G_CALLBACK (thunar_shortcuts_view_renamed), view);
310
282
  gtk_tree_view_column_pack_start (column, renderer, TRUE);
312
284
                                       "text", THUNAR_SHORTCUTS_MODEL_COLUMN_NAME,
313
285
                                       NULL);
314
286
 
 
287
  /* allocate icon renderer for the eject symbol */
 
288
  renderer = gtk_cell_renderer_pixbuf_new ();
 
289
  g_object_set (renderer, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
 
290
  gtk_tree_view_column_pack_start (column, renderer, FALSE);
 
291
  gtk_tree_view_column_set_attributes (column, renderer,
 
292
                                       "icon-name", THUNAR_SHORTCUTS_MODEL_COLUMN_EJECT,
 
293
                                       NULL);
 
294
 
 
295
 
315
296
  /* enable drag support for the shortcuts view (actually used to support reordering) */
316
297
  gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (view), GDK_BUTTON1_MASK, drag_targets,
317
298
                                          G_N_ELEMENTS (drag_targets), GDK_ACTION_MOVE);
334
315
  ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (object);
335
316
 
336
317
  /* release drop path list (if drag_leave wasn't called) */
337
 
  thunar_vfs_path_list_free (view->drop_path_list);
 
318
  thunar_g_file_list_free (view->drop_file_list);
338
319
 
339
320
  /* release the provider factory */
340
321
  g_object_unref (G_OBJECT (view->provider_factory));
341
322
 
342
323
  /* disconnect the queue resize signal handler */
343
 
#if GTK_CHECK_VERSION(2,8,0)
344
324
  g_signal_handler_disconnect (G_OBJECT (view->preferences), view->queue_resize_signal_id);
345
 
#endif
346
325
 
347
326
  /* disconnect from the preferences object */
348
327
  g_signal_handlers_disconnect_matched (G_OBJECT (view->preferences), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, view);
362
341
  GtkTreePath         *path;
363
342
  GtkTreeIter          iter;
364
343
  gboolean             result;
 
344
  gchar               *eject_icon;
365
345
 
366
346
  /* reset the pressed button state */
367
347
  view->pressed_button = -1;
 
348
  view->pressed_eject_button = 0;
368
349
 
369
350
  /* completely ignore double click events */
370
351
  if (event->type == GDK_2BUTTON_PRESS)
393
374
      else if ((event->button == 1 || event->button == 2) && event->type == GDK_BUTTON_PRESS
394
375
            && (event->state & gtk_accelerator_get_default_mod_mask ()) == 0)
395
376
        {
 
377
          /* check if we clicked the eject button area */
 
378
          gint icon_width, icon_height, column_width;
 
379
          column_width = gtk_tree_view_column_get_width (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0));
 
380
          gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
 
381
          if (event->x >= column_width - icon_width - 3)
 
382
            {
 
383
              /* check if that shortcut actually has an eject button */
 
384
              model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
 
385
              if (gtk_tree_model_get_iter (model, &iter, path))
 
386
                {
 
387
                  gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_EJECT, &eject_icon, -1);
 
388
                  if (strlen (eject_icon) > 0)
 
389
                    view->pressed_eject_button = 1;
 
390
                  g_free (eject_icon);
 
391
                }
 
392
            }
 
393
 
 
394
          /*
 
395
          g_debug("thunar_shortcuts_view_button_press_event(): x: %f, y: %f; my width: %i, eject width: %i, eject: %i", 
 
396
                  event->x, event->y, column_width, icon_width, view->pressed_eject_button);
 
397
          */
 
398
 
396
399
          /* remember the button as pressed and handle it in the release handler */
397
400
          view->pressed_button = event->button;
 
401
 
 
402
 
398
403
        }
399
404
 
400
405
      /* release the path */
415
420
  /* check if we have an event matching the pressed button state */
416
421
  if (G_LIKELY (view->pressed_button == (gint) event->button))
417
422
    {
 
423
      if (view->pressed_eject_button)
 
424
        thunar_shortcuts_view_eject (view);
 
425
 
418
426
      /* check if we should simply open or open in new window */
419
427
      if (G_LIKELY (event->button == 1))
420
 
        thunar_shortcuts_view_open (view);
 
428
        thunar_shortcuts_view_open (view, FALSE);
421
429
      else if (G_UNLIKELY (event->button == 2))
422
 
        thunar_shortcuts_view_open_in_new_window (view);
 
430
        thunar_shortcuts_view_open (view, TRUE);
423
431
    }
424
432
 
425
433
  /* reset the pressed button state */
426
434
  view->pressed_button = -1;
 
435
  view->pressed_eject_button = 0;
427
436
 
428
437
  /* call the parent's release event handler */
429
438
  return (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->button_release_event) (widget, event);
454
463
                                          gint              y,
455
464
                                          GtkSelectionData *selection_data,
456
465
                                          guint             info,
457
 
                                          guint             time)
 
466
                                          guint             timestamp)
458
467
{
459
468
  GtkTreeViewDropPosition position = GTK_TREE_VIEW_DROP_BEFORE;
460
469
  ThunarShortcutsView    *view = THUNAR_SHORTCUTS_VIEW (widget);
473
482
    {
474
483
      /* extract the URI list from the selection data (if valid) */
475
484
      if (info == TEXT_URI_LIST && selection_data->format == 8 && selection_data->length > 0)
476
 
        view->drop_path_list = thunar_vfs_path_list_from_string ((const gchar *) selection_data->data, NULL);
 
485
        view->drop_file_list = thunar_g_file_list_new_from_string ((const gchar *) selection_data->data);
477
486
 
478
487
      /* reset the state */
479
488
      view->drop_data_ready = TRUE;
502
511
                    gtk_tree_path_next (path);
503
512
 
504
513
                  /* just add the required shortcuts then */
505
 
                  thunar_shortcuts_view_drop_uri_list (view, view->drop_path_list, path);
 
514
                  thunar_shortcuts_view_drop_uri_list (view, view->drop_file_list, path);
506
515
                }
507
516
              else if (G_LIKELY ((actions & (GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)) != 0))
508
517
                {
518
527
                        {
519
528
                          /* ask the user what to do with the drop data */
520
529
                          if (G_UNLIKELY (action == GDK_ACTION_ASK))
521
 
                            action = thunar_dnd_ask (widget, file, view->drop_path_list, time, actions);
 
530
                            action = thunar_dnd_ask (widget, file, view->drop_file_list, timestamp, actions);
522
531
 
523
532
                          /* perform the requested action */
524
533
                          if (G_LIKELY (action != 0))
525
534
                            {
526
535
                              /* really perform the drop :-) */
527
 
                              succeed = thunar_dnd_perform (widget, file, view->drop_path_list, action, NULL);
 
536
                              succeed = thunar_dnd_perform (widget, file, view->drop_file_list, action, NULL);
528
537
                            }
529
538
 
530
539
                          /* release the file */
539
548
        }
540
549
 
541
550
      /* disable the drop highlighting */
542
 
      thunar_shortcuts_view_drag_leave (widget, context, time);
 
551
      thunar_shortcuts_view_drag_leave (widget, context, timestamp);
543
552
 
544
553
      /* tell the peer that we handled the drop */
545
 
      gtk_drag_finish (context, succeed, FALSE, time);
 
554
      gtk_drag_finish (context, succeed, FALSE, timestamp);
546
555
    }
547
556
  else
548
557
    {
549
 
      gdk_drag_status (context, 0, time);
 
558
      gdk_drag_status (context, 0, timestamp);
550
559
    }
551
560
}
552
561
 
557
566
                                 GdkDragContext *context,
558
567
                                 gint            x,
559
568
                                 gint            y,
560
 
                                 guint           time)
 
569
                                 guint           timestamp)
561
570
{
562
571
  ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
563
572
  GtkTreeSelection    *selection;
579
588
      view->drop_occurred = TRUE;
580
589
 
581
590
      /* request the drag data from the source. */
582
 
      gtk_drag_get_data (widget, context, target, time);
 
591
      gtk_drag_get_data (widget, context, target, timestamp);
583
592
    }
584
593
  else if (target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW"))
585
594
    {
608
617
      gtk_tree_path_free (dst_path);
609
618
 
610
619
      /* finish the dnd operation */
611
 
      gtk_drag_finish (context, TRUE, FALSE, time);
 
620
      gtk_drag_finish (context, TRUE, FALSE, timestamp);
612
621
    }
613
622
  else
614
623
    {
626
635
                                   GdkDragContext *context,
627
636
                                   gint            x,
628
637
                                   gint            y,
629
 
                                   guint           time)
 
638
                                   guint           timestamp)
630
639
{
631
640
  GtkTreeViewDropPosition position = GTK_TREE_VIEW_DROP_BEFORE;
632
641
  ThunarShortcutsView    *view = THUNAR_SHORTCUTS_VIEW (widget);
646
655
      if (G_UNLIKELY (!view->drop_data_ready))
647
656
        {
648
657
          /* request the drag data from the source */
649
 
          gtk_drag_get_data (widget, context, target, time);
 
658
          gtk_drag_get_data (widget, context, target, timestamp);
650
659
 
651
660
          /* gdk_drag_status() will be called by drag_data_received */
652
661
          return TRUE;
699
708
    }
700
709
 
701
710
  /* tell Gdk whether we can drop here */
702
 
  gdk_drag_status (context, action, time);
 
711
  gdk_drag_status (context, action, timestamp);
703
712
 
704
713
  return TRUE;
705
714
}
709
718
static void
710
719
thunar_shortcuts_view_drag_leave (GtkWidget      *widget,
711
720
                                  GdkDragContext *context,
712
 
                                  guint           time)
 
721
                                  guint           timestamp)
713
722
{
714
723
  ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (widget);
715
724
 
719
728
  /* reset the "drop data ready" status and free the URI list */
720
729
  if (G_LIKELY (view->drop_data_ready))
721
730
    {
722
 
      thunar_vfs_path_list_free (view->drop_path_list);
 
731
      thunar_g_file_list_free (view->drop_file_list);
723
732
      view->drop_data_ready = FALSE;
724
 
      view->drop_path_list = NULL;
 
733
      view->drop_file_list = NULL;
725
734
    }
726
735
 
727
736
  /* schedule a repaint to make sure the special drop icon for the target row
730
739
  gtk_widget_queue_draw (widget);
731
740
 
732
741
  /* call the parent's handler */
733
 
  (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->drag_leave) (widget, context, time);
 
742
  (*GTK_WIDGET_CLASS (thunar_shortcuts_view_parent_class)->drag_leave) (widget, context, timestamp);
734
743
}
735
744
 
736
745
 
776
785
    (*GTK_TREE_VIEW_CLASS (thunar_shortcuts_view_parent_class)->row_activated) (tree_view, path, column);
777
786
 
778
787
  /* open the selected shortcut */
779
 
  thunar_shortcuts_view_open (view);
 
788
  thunar_shortcuts_view_open (view, FALSE);
780
789
}
781
790
 
782
791
 
787
796
                                    GtkTreeModel        *model,
788
797
                                    GtkTreeIter         *iter)
789
798
{
790
 
  ThunarVfsVolume *volume;
791
 
  GtkTreePath     *path;
792
 
  ThunarFile      *file;
793
 
  GtkWidget       *image;
794
 
  GtkWidget       *menu;
795
 
  GtkWidget       *item;
796
 
  gboolean         mutable;
797
 
  GtkWidget       *window;
798
 
  GList           *providers, *lp;
799
 
  GList           *actions = NULL, *tmp;
 
799
  GtkTreePath *path;
 
800
  ThunarFile  *file;
 
801
  GtkWidget   *image;
 
802
  GtkWidget   *menu;
 
803
  GtkWidget   *item;
 
804
  GtkWidget   *window;
 
805
  gboolean     mutable;
 
806
  GVolume     *volume;
 
807
  GList       *providers, *lp;
 
808
  GList       *actions = NULL, *tmp;
800
809
 
801
810
  /* determine the tree path for the given iter */
802
811
  path = gtk_tree_model_get_path (model, iter);
815
824
 
816
825
  /* append the "Open" menu action */
817
826
  item = gtk_image_menu_item_new_with_mnemonic (_("_Open"));
818
 
  g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open), view);
 
827
  g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_clicked), view);
819
828
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
820
829
  gtk_widget_show (item);
821
830
 
826
835
 
827
836
  /* append the "Open in New Window" menu action */
828
837
  item = gtk_image_menu_item_new_with_mnemonic (_("Open in New Window"));
829
 
  g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_in_new_window), view);
 
838
  g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_open_in_new_window_clicked), view);
830
839
  gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
831
840
  gtk_widget_show (item);
832
841
 
840
849
    {
841
850
      /* append the "Mount Volume" menu action */
842
851
      item = gtk_image_menu_item_new_with_mnemonic (_("_Mount Volume"));
843
 
      gtk_widget_set_sensitive (item, !thunar_vfs_volume_is_mounted (volume));
 
852
      gtk_widget_set_sensitive (item, !thunar_g_volume_is_mounted (volume));
844
853
      g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_mount), view);
845
854
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
846
855
      gtk_widget_show (item);
847
856
 
848
857
      /* check if the volume is ejectable */
849
 
      if (thunar_vfs_volume_is_ejectable (volume))
 
858
      if (thunar_g_volume_is_removable (volume))
850
859
        {
851
860
          /* append the "Eject Volume" menu action */
852
861
          item = gtk_image_menu_item_new_with_mnemonic (_("E_ject Volume"));
854
863
          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
855
864
          gtk_widget_show (item);
856
865
        }
857
 
      else
858
 
        {
859
 
          /* append the "Unmount Volume" menu item */
860
 
          item = gtk_image_menu_item_new_with_mnemonic (_("_Unmount Volume"));
861
 
          gtk_widget_set_sensitive (item, thunar_vfs_volume_is_mounted (volume));
862
 
          g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_unmount), view);
863
 
          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
864
 
          gtk_widget_show (item);
865
 
        }
866
866
 
867
867
      /* append a menu separator */
868
868
      item = gtk_separator_menu_item_new ();
873
873
    {
874
874
      /* append the "Empty Trash" menu action */
875
875
      item = gtk_image_menu_item_new_with_mnemonic (_("_Empty Trash"));
876
 
      gtk_widget_set_sensitive (item, (thunar_file_get_size (file) > 0));
 
876
      gtk_widget_set_sensitive (item, (thunar_file_get_item_count (file) > 0));
877
877
      g_signal_connect_swapped (G_OBJECT (item), "activate", G_CALLBACK (thunar_shortcuts_view_empty_trash), view);
878
878
      gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
879
879
      gtk_widget_show (item);
1003
1003
    {
1004
1004
      /* determine the text renderer */
1005
1005
      column = gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0);
1006
 
      renderers = gtk_tree_view_column_get_cell_renderers (column);
 
1006
      renderers = gtk_cell_layout_get_cells  (GTK_CELL_LAYOUT (column));
1007
1007
      renderer = g_list_nth_data (renderers, 1);
1008
1008
 
1009
1009
      /* make sure the text renderer is editable */
1076
1076
          if (G_LIKELY (file != NULL))
1077
1077
            {
1078
1078
              /* check if the file accepts the drop */
1079
 
              actions = thunar_file_accepts_drop (file, view->drop_path_list, context, action_return);
 
1079
              actions = thunar_file_accepts_drop (file, view->drop_file_list, context, action_return);
1080
1080
              if (G_LIKELY (actions != 0))
1081
1081
                {
1082
1082
                  /* we can drop into this location */
1191
1191
  GtkTreePath  *path;
1192
1192
  ThunarFile   *file;
1193
1193
  GError       *error = NULL;
1194
 
  gchar        *display_string;
1195
 
  gchar        *uri_string;
1196
1194
  GList        *lp;
1197
1195
 
1198
1196
  /* take a copy of the destination path */
1202
1200
  model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
1203
1201
  for (lp = path_list; lp != NULL; lp = lp->next)
1204
1202
    {
1205
 
      file = thunar_file_get_for_path (lp->data, &error);
 
1203
      file = thunar_file_get (lp->data, &error);
1206
1204
      if (G_UNLIKELY (file == NULL))
1207
1205
        break;
1208
1206
 
1209
1207
      /* make sure, that only directories gets added to the shortcuts list */
1210
1208
      if (G_UNLIKELY (!thunar_file_is_directory (file)))
1211
1209
        {
1212
 
          uri_string = thunar_vfs_path_dup_string (lp->data);
1213
 
          display_string = g_filename_display_name (uri_string);
1214
1210
          g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR,
1215
1211
                       _("The path \"%s\" does not refer to a directory"),
1216
 
                       display_string);
1217
 
          g_object_unref (G_OBJECT (file));
1218
 
          g_free (display_string);
1219
 
          g_free (uri_string);
 
1212
                       thunar_file_get_display_name (file));
 
1213
          g_object_unref (file);
1220
1214
          break;
1221
1215
        }
1222
1216
 
1223
1217
      thunar_shortcuts_model_add (THUNAR_SHORTCUTS_MODEL (model), path, file);
1224
 
      g_object_unref (G_OBJECT (file));
 
1218
      g_object_unref (file);
1225
1219
      gtk_tree_path_next (path);
1226
1220
    }
1227
1221
 
1241
1235
 
1242
1236
 
1243
1237
static void
1244
 
thunar_shortcuts_view_open (ThunarShortcutsView *view)
 
1238
thunar_shortcuts_view_open_clicked (ThunarShortcutsView *view)
 
1239
{
 
1240
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
 
1241
  thunar_shortcuts_view_open (view, FALSE);
 
1242
}
 
1243
 
 
1244
 
 
1245
 
 
1246
static void
 
1247
thunar_shortcuts_view_poke_file_finish (ThunarBrowser *browser,
 
1248
                                        ThunarFile    *file,
 
1249
                                        ThunarFile    *target_file,
 
1250
                                        GError        *error,
 
1251
                                        gpointer       user_data)
 
1252
{
 
1253
  ThunarApplication *application;
 
1254
  gboolean           new_window = GPOINTER_TO_UINT (user_data);
 
1255
 
 
1256
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser));
 
1257
  _thunar_return_if_fail (THUNAR_IS_FILE (file));
 
1258
 
 
1259
  if (error == NULL)
 
1260
    {
 
1261
      if (new_window)
 
1262
        {
 
1263
          /* open a new window for the target folder */
 
1264
          application = thunar_application_get ();
 
1265
          thunar_application_open_window (application, target_file, 
 
1266
                                          gtk_widget_get_screen (GTK_WIDGET (browser)), NULL);
 
1267
          g_object_unref (application);
 
1268
        }
 
1269
      else
 
1270
        {
 
1271
          /* invoke the signal to change to that folder */
 
1272
          g_signal_emit (browser, view_signals[SHORTCUT_ACTIVATED], 0, target_file);
 
1273
        }
 
1274
    }
 
1275
  else
 
1276
    {
 
1277
      thunar_dialogs_show_error (GTK_WIDGET (browser), error, _("Failed to open \"%s\""),
 
1278
                                 thunar_file_get_display_name (file));
 
1279
    }
 
1280
}
 
1281
 
 
1282
 
 
1283
 
 
1284
static void
 
1285
thunar_shortcuts_view_poke_volume_finish (ThunarBrowser *browser,
 
1286
                                          GVolume       *volume,
 
1287
                                          ThunarFile    *mount_point,
 
1288
                                          GError        *error,
 
1289
                                          gpointer       user_data)
 
1290
{
 
1291
  gboolean new_window = GPOINTER_TO_UINT (user_data);
 
1292
  gchar   *volume_name;
 
1293
 
 
1294
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser));
 
1295
  _thunar_return_if_fail (G_IS_VOLUME (volume));
 
1296
 
 
1297
  if (error == NULL)
 
1298
    {
 
1299
      thunar_browser_poke_file (browser, mount_point, GTK_WIDGET (browser),
 
1300
                                thunar_shortcuts_view_poke_file_finish,
 
1301
                                GUINT_TO_POINTER (new_window));
 
1302
    }
 
1303
  else
 
1304
    {
 
1305
      volume_name = g_volume_get_name (volume);
 
1306
      thunar_dialogs_show_error (GTK_WIDGET (browser), error, 
 
1307
                                 _("Failed to mount \"%s\""), volume_name);
 
1308
      g_free (volume_name);
 
1309
    }
 
1310
}
 
1311
 
 
1312
 
 
1313
 
 
1314
static void
 
1315
thunar_shortcuts_view_open (ThunarShortcutsView *view,
 
1316
                            gboolean             new_window)
1245
1317
{
1246
1318
  GtkTreeSelection *selection;
1247
1319
  GtkTreeModel     *model;
1248
1320
  GtkTreeIter       iter;
1249
1321
  ThunarFile       *file;
 
1322
  GVolume          *volume;
1250
1323
 
1251
1324
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
1252
1325
 
1253
 
  /* make sure to mount the volume first (if it's a volume) */
1254
 
  if (!thunar_shortcuts_view_mount (view))
1255
 
    return;
1256
 
 
1257
1326
  /* determine the selected item */
1258
1327
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
 
1328
 
 
1329
  /* avoid dealing with invalid selections */
 
1330
  if (!GTK_IS_TREE_SELECTION (selection))
 
1331
    return;
 
1332
 
1259
1333
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
1260
1334
    {
1261
1335
      /* determine the file for the shortcut at the given tree iterator */
1262
 
      gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file, -1);
1263
 
      if (G_LIKELY (file != NULL))
1264
 
        {
1265
 
          /* invoke the signal to change to that folder */
1266
 
          g_signal_emit (G_OBJECT (view), view_signals[SHORTCUT_ACTIVATED], 0, file);
1267
 
          g_object_unref (G_OBJECT (file));
1268
 
        }
 
1336
      gtk_tree_model_get (model, &iter, 
 
1337
                          THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file,
 
1338
                          THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, 
 
1339
                          -1);
 
1340
 
 
1341
      if (G_LIKELY (volume != NULL))
 
1342
        {
 
1343
          thunar_browser_poke_volume (THUNAR_BROWSER (view), volume, view,
 
1344
                                      thunar_shortcuts_view_poke_volume_finish,
 
1345
                                      GUINT_TO_POINTER (new_window));
 
1346
        }
 
1347
      else if (file != NULL) 
 
1348
        {
 
1349
          thunar_browser_poke_file (THUNAR_BROWSER (view), file, view,
 
1350
                                    thunar_shortcuts_view_poke_file_finish,
 
1351
                                    GUINT_TO_POINTER (new_window));
 
1352
        }
 
1353
 
 
1354
      if (file != NULL)
 
1355
        g_object_unref (file);
 
1356
 
 
1357
      if (volume != NULL)
 
1358
        g_object_unref (volume);
1269
1359
    }
1270
1360
}
1271
1361
 
1272
1362
 
1273
1363
 
1274
1364
static void
1275
 
thunar_shortcuts_view_open_in_new_window (ThunarShortcutsView *view)
 
1365
thunar_shortcuts_view_open_in_new_window_clicked (ThunarShortcutsView *view)
1276
1366
{
1277
 
  ThunarApplication *application;
1278
 
  GtkTreeSelection  *selection;
1279
 
  GtkTreeModel      *model;
1280
 
  GtkTreeIter        iter;
1281
 
  ThunarFile        *file;
1282
 
 
1283
1367
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
1284
 
 
1285
 
  /* make sure to mount the volume first (if it's a volume) */
1286
 
  if (!thunar_shortcuts_view_mount (view))
1287
 
    return;
1288
 
 
1289
 
  /* determine the selected item */
1290
 
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
1291
 
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
1292
 
    {
1293
 
      /* determine the file for the shortcut at the given tree iterator */
1294
 
      gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file, -1);
1295
 
      if (G_LIKELY (file != NULL))
1296
 
        {
1297
 
          /* open a new window for the shortcut target folder */
1298
 
          application = thunar_application_get ();
1299
 
          thunar_application_open_window (application, file, gtk_widget_get_screen (GTK_WIDGET (view)));
1300
 
          g_object_unref (G_OBJECT (application));
1301
 
          g_object_unref (G_OBJECT (file));
1302
 
        }
1303
 
    }
 
1368
  thunar_shortcuts_view_open (view, TRUE);
1304
1369
}
1305
1370
 
1306
1371
 
1314
1379
 
1315
1380
  /* empty the trash bin (asking the user first) */
1316
1381
  application = thunar_application_get ();
1317
 
  thunar_application_empty_trash (application, GTK_WIDGET (view));
 
1382
  thunar_application_empty_trash (application, GTK_WIDGET (view), NULL);
1318
1383
  g_object_unref (G_OBJECT (application));
1319
1384
}
1320
1385
 
1321
1386
 
1322
1387
 
1323
 
static gboolean
 
1388
static void
 
1389
thunar_shortcuts_view_eject_finish (GObject      *object,
 
1390
                                    GAsyncResult *result,
 
1391
                                    gpointer      user_data)
 
1392
{
 
1393
  ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (user_data);
 
1394
  GtkWidget           *window;
 
1395
  GVolume             *volume = G_VOLUME (object);
 
1396
  GError              *error = NULL;
 
1397
  gchar               *volume_name;
 
1398
 
 
1399
  _thunar_return_if_fail (G_IS_VOLUME (object));
 
1400
  _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
 
1401
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
 
1402
 
 
1403
  /* check if there was an error */
 
1404
  if (!g_volume_eject_finish (volume, result, &error))
 
1405
    {
 
1406
      /* ignore GIO errors already handled */
 
1407
      if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED)
 
1408
        {
 
1409
          window = gtk_widget_get_toplevel (GTK_WIDGET (view));
 
1410
 
 
1411
          /* display an error dialog to inform the user */
 
1412
          volume_name = g_volume_get_name (volume);
 
1413
          thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), volume_name);
 
1414
          g_free (volume_name);
 
1415
 
 
1416
          g_error_free (error);
 
1417
        }
 
1418
    }
 
1419
 
 
1420
#ifdef HAVE_LIBNOTIFY
 
1421
  thunar_notify_eject_finish (volume);
 
1422
#endif
 
1423
 
 
1424
  g_object_unref (view);
 
1425
}
 
1426
 
 
1427
 
 
1428
 
 
1429
static void
 
1430
thunar_shortcuts_view_unmount_finish (GObject      *object,
 
1431
                                      GAsyncResult *result,
 
1432
                                      gpointer      user_data)
 
1433
{
 
1434
  ThunarShortcutsView *view = THUNAR_SHORTCUTS_VIEW (user_data);
 
1435
  GtkWidget           *window;
 
1436
  GMount              *mount = G_MOUNT (object);
 
1437
  GError              *error = NULL;
 
1438
  gchar               *mount_name;
 
1439
 
 
1440
  _thunar_return_if_fail (G_IS_MOUNT (object));
 
1441
  _thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
 
1442
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
 
1443
 
 
1444
  /* check if there was an error */
 
1445
  if (!g_mount_unmount_finish (mount, result, &error))
 
1446
    {
 
1447
      /* ignore GIO errors already handled */
 
1448
      if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED)
 
1449
        {
 
1450
          window = gtk_widget_get_toplevel (GTK_WIDGET (view));
 
1451
 
 
1452
          /* display an error dialog to inform the user */
 
1453
          mount_name = g_mount_get_name (mount);
 
1454
          thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), mount_name);
 
1455
          g_free (mount_name);
 
1456
 
 
1457
          g_error_free (error);
 
1458
        }
 
1459
    }
 
1460
 
 
1461
#ifdef HAVE_LIBNOTIFY
 
1462
  thunar_notify_unmount_finish (mount);
 
1463
#endif
 
1464
 
 
1465
  g_object_unref (view);
 
1466
}
 
1467
 
 
1468
 
 
1469
 
 
1470
static void
1324
1471
thunar_shortcuts_view_eject (ThunarShortcutsView *view)
1325
1472
{
1326
1473
  GtkTreeSelection *selection;
1327
 
  ThunarVfsVolume  *volume;
1328
1474
  GtkTreeModel     *model;
1329
1475
  GtkTreeIter       iter;
1330
 
  GtkWidget        *window;
1331
 
  gboolean          result = TRUE;
1332
 
  GError           *error = NULL;
 
1476
  GVolume          *volume;
 
1477
  GMount           *mount;
1333
1478
 
1334
 
  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE);
 
1479
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
1335
1480
 
1336
1481
  /* determine the selected item */
1337
1482
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
1341
1486
      gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, -1);
1342
1487
      if (G_UNLIKELY (volume != NULL))
1343
1488
        {
1344
 
          /* determine the toplevel window */
1345
 
          window = gtk_widget_get_toplevel (GTK_WIDGET (view));
1346
 
 
1347
 
          /* try to eject the volume */
1348
 
          result = thunar_vfs_volume_eject (volume, window, &error);
1349
 
          if (G_UNLIKELY (!result))
1350
 
            {
1351
 
              /* display an error dialog to inform the user */
1352
 
              thunar_dialogs_show_error (window, error, _("Failed to eject \"%s\""), thunar_vfs_volume_get_name (volume));
1353
 
              g_error_free (error);
 
1489
          /* determine what the appropriate method is: eject or unmount */
 
1490
          if (g_volume_can_eject (volume))
 
1491
            {
 
1492
#ifdef HAVE_LIBNOTIFY
 
1493
              thunar_notify_eject (volume);
 
1494
#endif
 
1495
 
 
1496
              /* try to to eject the volume asynchronously */
 
1497
              g_volume_eject (volume, G_MOUNT_UNMOUNT_NONE, NULL, 
 
1498
                              thunar_shortcuts_view_eject_finish, 
 
1499
                              g_object_ref (view));
 
1500
            }
 
1501
          else
 
1502
            {
 
1503
              /* determine the mount of the volume */
 
1504
              mount = g_volume_get_mount (volume);
 
1505
              if (G_LIKELY (mount != NULL))
 
1506
                {
 
1507
#ifdef HAVE_LIBNOTIFY
 
1508
                  thunar_notify_unmount (mount);
 
1509
#endif
 
1510
 
 
1511
                  /* the volume is mounted, try to unmount the mount */
 
1512
                  g_mount_unmount (mount, G_MOUNT_UNMOUNT_NONE, NULL,
 
1513
                                   thunar_shortcuts_view_unmount_finish, 
 
1514
                                   g_object_ref (view));
 
1515
 
 
1516
                  /* release the mount */
 
1517
                  g_object_unref (mount);
 
1518
                }
1354
1519
            }
1355
1520
 
1356
1521
          /* cleanup */
1357
 
          g_object_unref (G_OBJECT (volume));
 
1522
          g_object_unref (volume);
1358
1523
        }
1359
1524
    }
1360
 
 
1361
 
  return result;
1362
 
}
1363
 
 
1364
 
 
1365
 
 
1366
 
static gboolean
 
1525
}
 
1526
 
 
1527
 
 
1528
 
 
1529
static void
 
1530
thunar_shortcuts_view_poke_volume_mount_finish (ThunarBrowser *browser,
 
1531
                                                GVolume       *volume,
 
1532
                                                ThunarFile    *mount_point,
 
1533
                                                GError        *error,
 
1534
                                                gpointer       ignored)
 
1535
{
 
1536
  gchar *volume_name;
 
1537
 
 
1538
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (browser));
 
1539
  _thunar_return_if_fail (G_IS_VOLUME (volume));
 
1540
 
 
1541
  if (error != NULL)
 
1542
    {
 
1543
      volume_name = g_volume_get_name (volume);
 
1544
      thunar_dialogs_show_error (GTK_WIDGET (browser), error, 
 
1545
                                 _("Failed to mount \"%s\""), volume_name);
 
1546
      g_free (volume_name);
 
1547
    }
 
1548
}
 
1549
 
 
1550
 
 
1551
 
 
1552
 
 
1553
static void
1367
1554
thunar_shortcuts_view_mount (ThunarShortcutsView *view)
1368
1555
{
1369
1556
  GtkTreeSelection *selection;
1370
 
  ThunarVfsVolume  *volume;
1371
 
  GtkTreeModel     *model;
1372
 
  GtkTreeIter       iter;
1373
 
  GtkWidget        *window;
1374
 
  gboolean          result = TRUE;
1375
 
  GError           *error = NULL;
1376
 
 
1377
 
  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE);
1378
 
 
1379
 
  /* determine the selected item */
1380
 
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
1381
 
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
1382
 
    {
1383
 
      /* determine the volume for the shortcut at the given tree iterator */
1384
 
      gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, -1);
1385
 
      if (G_UNLIKELY (volume != NULL))
1386
 
        {
1387
 
          /* check if the volume isn't already mounted */
1388
 
          if (G_LIKELY (!thunar_vfs_volume_is_mounted (volume)))
1389
 
            {
1390
 
              /* determine the toplevel window */
1391
 
              window = gtk_widget_get_toplevel (GTK_WIDGET (view));
1392
 
 
1393
 
              /* try to mount the volume */
1394
 
              result = thunar_vfs_volume_mount (volume, window, &error);
1395
 
              if (G_UNLIKELY (!result))
1396
 
                {
1397
 
                  /* display an error dialog to inform the user */
1398
 
                  thunar_dialogs_show_error (window, error, _("Failed to mount \"%s\""), thunar_vfs_volume_get_name (volume));
1399
 
                  g_error_free (error);
1400
 
                }
1401
 
            }
1402
 
 
1403
 
          /* cleanup */
1404
 
          g_object_unref (G_OBJECT (volume));
1405
 
        }
1406
 
    }
1407
 
 
1408
 
  return result;
1409
 
}
1410
 
 
1411
 
 
1412
 
 
1413
 
static gboolean
1414
 
thunar_shortcuts_view_unmount (ThunarShortcutsView *view)
1415
 
{
1416
 
  GtkTreeSelection *selection;
1417
 
  ThunarVfsVolume  *volume;
1418
 
  GtkTreeModel     *model;
1419
 
  GtkTreeIter       iter;
1420
 
  GtkWidget        *window;
1421
 
  gboolean          result = TRUE;
1422
 
  GError           *error = NULL;
1423
 
 
1424
 
  _thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view), FALSE);
1425
 
 
1426
 
  /* determine the selected item */
1427
 
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
1428
 
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
1429
 
    {
1430
 
      /* determine the volume for the shortcut at the given tree iterator */
1431
 
      gtk_tree_model_get (model, &iter, THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, -1);
1432
 
      if (G_UNLIKELY (volume != NULL))
1433
 
        {
1434
 
          /* determine the toplevel window */
1435
 
          window = gtk_widget_get_toplevel (GTK_WIDGET (view));
1436
 
 
1437
 
          /* try to unmount the volume */
1438
 
          result = thunar_vfs_volume_unmount (volume, window, &error);
1439
 
          if (G_UNLIKELY (!result))
1440
 
            {
1441
 
              /* display an error dialog to inform the user */
1442
 
              thunar_dialogs_show_error (window, error, _("Failed to unmount \"%s\""), thunar_vfs_volume_get_name (volume));
1443
 
              g_error_free (error);
1444
 
            }
1445
 
 
1446
 
          /* cleanup */
1447
 
          g_object_unref (G_OBJECT (volume));
1448
 
        }
1449
 
    }
1450
 
 
1451
 
  return result;
 
1557
  GtkTreeModel     *model;
 
1558
  GtkTreeIter       iter;
 
1559
  GVolume          *volume;
 
1560
 
 
1561
  _thunar_return_if_fail (THUNAR_IS_SHORTCUTS_VIEW (view));
 
1562
 
 
1563
  /* determine the selected item */
 
1564
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
 
1565
 
 
1566
  /* avoid dealing with invalid selections */
 
1567
  if (!GTK_IS_TREE_SELECTION (selection))
 
1568
    return;
 
1569
 
 
1570
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
 
1571
    {
 
1572
      /* determine the file for the shortcut at the given tree iterator */
 
1573
      gtk_tree_model_get (model, &iter, 
 
1574
                          THUNAR_SHORTCUTS_MODEL_COLUMN_VOLUME, &volume, 
 
1575
                          -1);
 
1576
 
 
1577
      if (G_LIKELY (volume != NULL))
 
1578
        {
 
1579
          thunar_browser_poke_volume (THUNAR_BROWSER (view), volume, view,
 
1580
                                      thunar_shortcuts_view_poke_volume_mount_finish,
 
1581
                                      NULL);
 
1582
          g_object_unref (volume);
 
1583
        }
 
1584
    }
1452
1585
}
1453
1586
 
1454
1587