1
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
3
* Copyright (c) 2015 Pantheon Developers (http://launchpad.net/elementary)
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
20
* Authored by: Corentin Noël <tintou@mailoo.org>
24
public const string ICON_ABOUT_LOGO = "system-file-manager";
25
public const string ICON_FILESYSTEM = "drive-harddisk-system";
26
public const string ICON_FILESYSTEM_SYMBOLIC = "drive-harddisk-symbolic";
27
public const string ICON_FOLDER = "folder";
28
public const string ICON_FOLDER_DOCUMENTS_SYMBOLIC = "folder-documents-symbolic";
29
public const string ICON_FOLDER_DOWNLOADS_SYMBOLIC = "folder-download-symbolic";
30
public const string ICON_FOLDER_MUSIC_SYMBOLIC = "folder-music-symbolic";
31
public const string ICON_FOLDER_PICTURES_SYMBOLIC = "folder-pictures-symbolic";
32
public const string ICON_FOLDER_REMOTE = "folder-remote";
33
public const string ICON_FOLDER_REMOTE_SYMBOLIC = "folder-remote-symbolic";
34
public const string ICON_FOLDER_TEMPLATES_SYMBOLIC = "folder-templates-symbolic";
35
public const string ICON_FOLDER_VIDEOS_SYMBOLIC = "folder-videos-symbolic";
36
public const string ICON_GO_HOME_SYMBOLIC = "go-home-symbolic";
37
public const string ICON_HOME = "user-home";
38
public const string ICON_NETWORK = "network-workgroup";
39
public const string ICON_NETWORK_SERVER = "network-server";
40
public const string ICON_TRASH = "user-trash";
41
public const string ICON_TRASH_FULL = "user-trash-full";
42
public const string ICON_TRASH_SYMBOLIC = "user-trash-symbolic";
44
public const string PROTOCOL_NAME_AFP = "AFP";
45
public const string PROTOCOL_NAME_DAV = "DAV";
46
public const string PROTOCOL_NAME_DAVS = "DAVS";
47
public const string PROTOCOL_NAME_FTP = "FTP";
48
public const string PROTOCOL_NAME_NETWORK = "Network";
49
public const string PROTOCOL_NAME_SFTP = "SFTP";
50
public const string PROTOCOL_NAME_SMB = "SMB";
51
public const string PROTOCOL_NAME_TRASH = "Trash";
54
namespace Marlin.View.Chrome
56
public class LocationBar : Gtk.Box {
57
public Breadcrumbs bread;
60
public new string path {
62
var new_path = GLib.Uri.unescape_string (value);
63
if (new_path != null) {
66
if (!bread.is_focus) {
68
bread.change_breadcrumbs (new_path);
71
critical ("Tried to set null path");
80
public new signal void activate (GLib.File file);
81
public signal void activate_alternate (GLib.File file);
82
public signal void escape ();
83
public signal void change_to_file (string filename);
85
public override void get_preferred_width (out int minimum_width, out int natural_width) {
90
public LocationBar () {
91
bread = new Breadcrumbs ();
92
bread.escape.connect (() => { escape(); });
93
bread.path_changed.connect (on_path_changed);
95
bread.reload.connect (() => {
98
bread.activate_alternate.connect ((file) => {
99
path = "file://" + file.get_path ();
100
change_to_file (file.get_path ());
106
pack_start (bread, true, true, 0);
109
private void on_path_changed (File? file) {
117
public class Breadcrumbs : BasePathBar {
123
private bool drop_data_ready = false; /* whether the drop data was received already */
124
private bool drop_occurred = false; /* whether the data was dropped */
125
private GLib.List<GLib.File> drop_file_list = null; /* the list of URIs in the drop data */
127
Gdk.DragAction current_suggested_action = 0; /* No action */
128
Gdk.DragAction current_actions = 0; /* No action */
130
public Breadcrumbs ()
132
/* the string split of the path url is kinda too basic, we should use the Gile to split our uris and determine the protocol (if any) with g_uri_parse_scheme or g_file_get_uri_scheme */
133
add_icon ({ "afp://", Marlin.ICON_FOLDER_REMOTE_SYMBOLIC, true, null, null, null, true, Marlin.PROTOCOL_NAME_AFP});
134
add_icon ({ "dav://", Marlin.ICON_FOLDER_REMOTE_SYMBOLIC, true, null, null, null, true, Marlin.PROTOCOL_NAME_DAV});
135
add_icon ({ "davs://", Marlin.ICON_FOLDER_REMOTE_SYMBOLIC, true, null, null, null, true,Marlin.PROTOCOL_NAME_DAVS});
136
add_icon ({ "ftp://", Marlin.ICON_FOLDER_REMOTE_SYMBOLIC, true, null, null, null, true, Marlin.PROTOCOL_NAME_FTP});
137
add_icon ({ "network://", Marlin.ICON_FOLDER_REMOTE_SYMBOLIC, true, null, null, null, true, Marlin.PROTOCOL_NAME_NETWORK});
138
add_icon ({ "sftp://", Marlin.ICON_FOLDER_REMOTE_SYMBOLIC, true, null, null, null, true, Marlin.PROTOCOL_NAME_SFTP});
139
add_icon ({ "smb://", Marlin.ICON_FOLDER_REMOTE_SYMBOLIC, true, null, null, null, true,Marlin.PROTOCOL_NAME_SMB});
140
add_icon ({ "trash://", Marlin.ICON_TRASH_SYMBOLIC, true, null, null, null, true, Marlin.PROTOCOL_NAME_TRASH});
143
dir = Environment.get_user_special_dir (UserDirectory.MUSIC);
144
if (dir.contains ("/")) {
145
IconDirectory icon = {dir, Marlin.ICON_FOLDER_MUSIC_SYMBOLIC, false, null, null, dir.split ("/"), false, null};
146
icon.exploded[0] = "/";
151
dir = Environment.get_user_special_dir (UserDirectory.PICTURES);
152
if (dir.contains ("/")) {
153
IconDirectory icon = {dir, Marlin.ICON_FOLDER_PICTURES_SYMBOLIC, false, null, null, dir.split ("/"), false, null};
154
icon.exploded[0] = "/";
159
dir = Environment.get_user_special_dir (UserDirectory.VIDEOS);
160
if (dir.contains ("/")) {
161
IconDirectory icon = {dir, Marlin.ICON_FOLDER_VIDEOS_SYMBOLIC, false, null, null, dir.split ("/"), false, null};
162
icon.exploded[0] = "/";
166
dir = Environment.get_user_special_dir (UserDirectory.DOWNLOAD);
167
if (dir.contains ("/")) {
168
IconDirectory icon = {dir, Marlin.ICON_FOLDER_DOWNLOADS_SYMBOLIC, false, null, null, dir.split ("/"), false, null};
169
icon.exploded[0] = "/";
173
dir = Environment.get_user_special_dir (UserDirectory.DOCUMENTS);
174
if (dir.contains ("/")) {
175
IconDirectory icon = {dir, Marlin.ICON_FOLDER_DOCUMENTS_SYMBOLIC, false, null, null, dir.split ("/"), false, null};
176
icon.exploded[0] = "/";
180
dir = Environment.get_user_special_dir (UserDirectory.TEMPLATES);
181
if (dir.contains ("/")) {
182
IconDirectory icon = {dir, Marlin.ICON_FOLDER_TEMPLATES_SYMBOLIC, false, null, null, dir.split ("/"), false, null};
183
icon.exploded[0] = "/";
187
dir = Environment.get_home_dir ();
188
if (dir.contains ("/")) {
189
IconDirectory icon = {dir, Marlin.ICON_GO_HOME_SYMBOLIC, false, null, null, dir.split ("/"), true, null};
190
icon.exploded[0] = "/";
196
if (dir.contains ("/")) {
197
IconDirectory icon = {dir, Marlin.ICON_FILESYSTEM_SYMBOLIC, false, null, null, dir.split ("/"), true, null};
198
icon.exploded[0] = "/";
202
IconDirectory icon = {"/", Marlin.ICON_FILESYSTEM_SYMBOLIC, false, null, null, null, false, null};
203
icon.exploded = {"/"};
207
File file = get_file_for_path (text);
208
File parent = file.get_parent ();
210
if (parent != null && file.get_uri () != parent.get_uri ())
211
change_breadcrumbs (parent.get_uri ());
217
menu = new Gtk.Menu ();
221
private void get_menu_position (Gtk.Menu menu, out int x, out int y, out bool push_in) {
222
x = (int) menu_x_root;
223
y = (int) menu_y_root;
227
protected override void load_right_click_menu (double x, double y) {
228
if (current_right_click_root == null)
233
menu = new Gtk.Menu ();
234
menu.cancel.connect (() => { reset_elements_states (); });
235
menu.deactivate.connect (() => { reset_elements_states (); });
236
/* current_right_click_root is parent of the directory named on the breadcrumb. */
242
Gtk.get_current_event_time ());
245
protected override bool on_drag_motion (Gdk.DragContext context, int x, int y, uint time) {
246
Gtk.drag_unhighlight (this);
248
foreach (BreadcrumbsElement element in elements)
249
element.pressed = false;
251
var el = get_element_from_coordinates (x, y);
256
/* No action taken on drop */
257
Gdk.drag_status (context, 0, time);
264
protected override bool on_drag_drop (Gdk.DragContext context,
268
Gtk.TargetList list = null;
269
bool ok_to_drop = false;
271
Gdk.Atom target = Gtk.drag_dest_find_target (this, context, list);
273
ok_to_drop = (target != Gdk.Atom.NONE);
276
drop_occurred = true;
277
Gtk.drag_get_data (this, context, target, timestamp);
283
protected override void on_drag_data_received (Gdk.DragContext context,
286
Gtk.SelectionData selection_data,
290
bool success = false;
292
if (!drop_data_ready) {
293
drop_file_list = null;
294
foreach (var uri in selection_data.get_uris ()) {
295
debug ("Path to move: %s\n", uri);
296
drop_file_list.append (File.new_for_uri (uri));
297
drop_data_ready = true;
301
if (drop_data_ready && drop_occurred && info == TargetType.TEXT_URI_LIST) {
302
drop_occurred = false;
304
current_suggested_action = 0;
306
Gtk.drag_finish (context, success, false, timestamp);
307
on_drag_leave (context, timestamp);
311
protected override void on_drag_leave (Gdk.DragContext drag_context, uint time) {
312
foreach (BreadcrumbsElement element in elements) {
313
if (element.pressed) {
314
element.pressed = false;
319
drop_occurred = false;
320
drop_data_ready = false;
321
drop_file_list = null;