~elementary-apps/pantheon-files/trunk

« back to all changes in this revision

Viewing changes to gtk-module/LocationBar.vala

  • Committer: donadigo
  • Date: 2015-04-30 22:07:48 UTC
  • mto: This revision was merged to the branch mainline in revision 1842.
  • Revision ID: donadigos159@gmail.com-20150430220748-kay2fc7qf1sn30bf
Initial commit; filechooser gtk module

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
2
 
/*-
3
 
 * Copyright (c) 2015 Pantheon Developers (http://launchpad.net/elementary)
4
 
 *
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.
9
 
 *
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.
14
 
 *
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.
19
 
 *
20
 
 * Authored by: Corentin Noël <tintou@mailoo.org>
21
 
 */
22
 
 
23
 
namespace Marlin {
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";
43
 
 
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";
52
 
}
53
 
 
54
 
namespace Marlin.View.Chrome
55
 
{
56
 
    public class LocationBar : Gtk.Box {
57
 
        public Breadcrumbs bread;
58
 
 
59
 
        private string _path;
60
 
        public new string path {
61
 
            set {
62
 
                var new_path = GLib.Uri.unescape_string (value);
63
 
                if (new_path != null) {
64
 
                    _path = new_path;
65
 
 
66
 
                    if (!bread.is_focus) {
67
 
                        bread.text = "";
68
 
                        bread.change_breadcrumbs (new_path);
69
 
                    }
70
 
                } else {
71
 
                    critical ("Tried to set null path");
72
 
                }
73
 
            }
74
 
 
75
 
            get {
76
 
                return _path;
77
 
            }
78
 
        }
79
 
 
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);
84
 
 
85
 
        public override void get_preferred_width (out int minimum_width, out int natural_width) {
86
 
            minimum_width = -1;
87
 
            natural_width = 3000;
88
 
        }
89
 
 
90
 
        public LocationBar () {
91
 
            bread = new Breadcrumbs ();
92
 
            bread.escape.connect (() => { escape(); });
93
 
            bread.path_changed.connect (on_path_changed);
94
 
 
95
 
            bread.reload.connect (() => {
96
 
            });
97
 
 
98
 
            bread.activate_alternate.connect ((file) => {
99
 
                path = "file://" + file.get_path ();
100
 
                change_to_file (file.get_path ());              
101
 
            });
102
 
            
103
 
            margin_top = 4;
104
 
            margin_bottom = 4;
105
 
            margin_left = 3;
106
 
            pack_start (bread, true, true, 0);
107
 
        }
108
 
 
109
 
        private void on_path_changed (File? file) {
110
 
            if (file == null)
111
 
                return;
112
 
 
113
 
            activate (file);
114
 
        }
115
 
    }
116
 
 
117
 
    public class Breadcrumbs : BasePathBar {
118
 
        Gtk.Menu menu;
119
 
 
120
 
        double menu_x_root;
121
 
        double menu_y_root;
122
 
 
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 */
126
 
 
127
 
        Gdk.DragAction current_suggested_action = 0; /* No action */
128
 
        Gdk.DragAction current_actions = 0; /* No action */
129
 
 
130
 
        public Breadcrumbs ()
131
 
        {
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});
141
 
 
142
 
            string dir;
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] = "/";
147
 
                add_icon (icon);
148
 
            }
149
 
 
150
 
 
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] = "/";
155
 
                add_icon (icon);
156
 
            }
157
 
 
158
 
 
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] = "/";
163
 
                add_icon (icon);
164
 
            }
165
 
 
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] = "/";
170
 
                add_icon (icon);
171
 
            }
172
 
 
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] = "/";
177
 
                add_icon (icon);
178
 
            }
179
 
 
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] = "/";
184
 
                add_icon (icon);
185
 
            }
186
 
 
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] = "/";
191
 
                add_icon (icon);
192
 
            }
193
 
 
194
 
 
195
 
            dir = "/media";
196
 
            if (dir.contains ("/")) {
197
 
                IconDirectory icon = {dir, Marlin.ICON_FILESYSTEM_SYMBOLIC, false, null, null, dir.split ("/"), true, null};
198
 
                icon.exploded[0] = "/";
199
 
                add_icon (icon);
200
 
            }
201
 
 
202
 
            IconDirectory icon = {"/", Marlin.ICON_FILESYSTEM_SYMBOLIC, false, null, null, null, false, null};
203
 
            icon.exploded = {"/"};
204
 
            add_icon (icon);
205
 
            
206
 
            up.connect (() => {
207
 
                File file = get_file_for_path (text);
208
 
                File parent = file.get_parent ();
209
 
                
210
 
                if (parent != null && file.get_uri () != parent.get_uri ())
211
 
                    change_breadcrumbs (parent.get_uri ());
212
 
                    
213
 
                //win.go_up ();
214
 
                grab_focus ();
215
 
            });
216
 
 
217
 
            menu = new Gtk.Menu ();
218
 
            menu.show_all ();
219
 
        }
220
 
 
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;
224
 
            push_in = true;
225
 
        }
226
 
 
227
 
        protected override void load_right_click_menu (double x, double y) {
228
 
            if (current_right_click_root == null)
229
 
                return;
230
 
 
231
 
            menu_x_root = x;
232
 
            menu_y_root = y;
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. */
237
 
            
238
 
            menu.popup (null,
239
 
                        null,
240
 
                        get_menu_position,
241
 
                        0,
242
 
                        Gtk.get_current_event_time ());
243
 
        }
244
 
 
245
 
        protected override bool on_drag_motion (Gdk.DragContext context, int x, int y, uint time) {
246
 
            Gtk.drag_unhighlight (this);
247
 
 
248
 
            foreach (BreadcrumbsElement element in elements)
249
 
                element.pressed = false;
250
 
 
251
 
            var el = get_element_from_coordinates (x, y);
252
 
 
253
 
            if (el != null)
254
 
                el.pressed = true;
255
 
            else
256
 
                /* No action taken on drop */
257
 
                Gdk.drag_status (context, 0, time);
258
 
 
259
 
            queue_draw ();
260
 
 
261
 
            return false;
262
 
        }
263
 
 
264
 
        protected override bool on_drag_drop (Gdk.DragContext context,
265
 
                                   int x,
266
 
                                   int y,
267
 
                                   uint timestamp) {
268
 
            Gtk.TargetList list = null;
269
 
            bool ok_to_drop = false;
270
 
 
271
 
            Gdk.Atom target = Gtk.drag_dest_find_target  (this, context, list);
272
 
 
273
 
            ok_to_drop = (target != Gdk.Atom.NONE);
274
 
 
275
 
            if (ok_to_drop) {
276
 
                drop_occurred = true;
277
 
                Gtk.drag_get_data (this, context, target, timestamp);
278
 
            }
279
 
 
280
 
            return ok_to_drop;
281
 
        }
282
 
 
283
 
        protected override void on_drag_data_received (Gdk.DragContext context,
284
 
                                            int x,
285
 
                                            int y,
286
 
                                            Gtk.SelectionData selection_data,
287
 
                                            uint info,
288
 
                                            uint timestamp
289
 
                                            ) {
290
 
            bool success = false;
291
 
 
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;
298
 
                }
299
 
            }
300
 
 
301
 
            if (drop_data_ready && drop_occurred && info == TargetType.TEXT_URI_LIST) {
302
 
                drop_occurred = false;
303
 
                current_actions = 0;
304
 
                current_suggested_action = 0;
305
 
 
306
 
                Gtk.drag_finish (context, success, false, timestamp);
307
 
                on_drag_leave (context, timestamp);
308
 
            }
309
 
        }
310
 
 
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;
315
 
                    break;
316
 
                }
317
 
            }
318
 
 
319
 
            drop_occurred = false;
320
 
            drop_data_ready = false;
321
 
            drop_file_list = null;
322
 
 
323
 
            queue_draw ();
324
 
        }
325
 
    }
326
 
}