94
93
file = GOF.File.get (location);
95
94
cancellable = new Cancellable ();
96
95
state = State.NOT_LOADED;
100
98
scheme = location.get_uri_scheme ();
101
99
is_trash = (scheme == "trash");
102
100
is_recent = (scheme == "recent");
103
101
is_local = is_trash || is_recent || (scheme == "file");
105
if (!prepare_directory ())
109
connect_volume_monitor_signals ();
111
assert (directory_cache != null);
112
directory_cache.insert (location, this);
114
this.add_toggle_ref ((ToggleNotify) toggle_ref_notify);
117
debug ("created dir %s ref_count %u", this.file.uri, this.ref_count);
118
file_hash = new HashTable<GLib.File,GOF.File> (GLib.File.hash, GLib.File.equal);
119
uri_contain_keypath_icons = "/icons" in file.uri || "/.icons" in file.uri;
102
is_network = !is_local && ("ftp ftps afp dav davs".contains (scheme));
125
108
disconnect_volume_monitor_signals ();
111
public void init (GOFFileLoadedFunc? file_loaded_func = null) {
112
if (state == State.LOADING) { /* Could happen reloading multiple windows */
115
state = State.LOADING;
116
cancellable.cancel ();
117
cancellable.reset ();
118
if (file_hash != null && file_hash.size () > 0) { /* false on first visit or when reloading */
119
list_cached_files (file_loaded_func); /* will call make ready when done */
120
} else if (!prepare_directory (file_loaded_func)) { /* Returns true if has already called make_ready () or will do so in a callback */
123
/* Otherwise the directory will be prepared and the done_loaded signal emitted when ready */
128
126
/* This is also called when reloading the directory so that another attempt to connect to
129
127
* the network is made
131
private bool prepare_directory () {
132
if (!get_file_info ()) {
134
/* local uris are deemed loadable even if they do not exist
135
* If they do not exist an opportunity will be given to create them
141
if (!file.is_folder () && !file.is_root_network_folder () && !try_parent ()) {
129
private bool prepare_directory (GOFFileLoadedFunc? file_loaded_func) {
130
if (!get_file_info (file_loaded_func)) {
132
} else if (is_local && !file.is_folder ()) {
133
if (!can_try_parent ()) {
136
return get_file_info (file_loaded_func);
149
private bool try_parent () {
142
private bool can_try_parent () {
150
143
if (file.is_connected) {
151
144
GLib.File? parent = location.get_parent ();
152
145
if (parent != null) {
153
146
file = GOF.File.get (parent);
154
147
selected_file = location.dup ();
155
148
location = parent;
156
if (get_file_info ())
163
private bool get_file_info () {
155
private bool get_file_info (GOFFileLoadedFunc? file_loaded_func) {
164
156
if (!is_local && !check_network ()) {
168
160
* that did not ensure the correct info Aync purposes, and retrieved from cache (bug 1511307).
170
162
file.info = null;
171
if (!file.ensure_query_info()) {
172
if (is_local || !file.is_connected)
163
if (!file.ensure_query_info()) { /* should set file.exists and file.connected appropriately */
164
if (is_local || !file.is_connected || !file.exists) {
178
170
mount_mountable.begin ((obj,res) => {
171
bool success = false;
181
173
mount_mountable.end (res);
183
175
} catch (Error e) {
184
debug ("mount_mountable failed: %s", e.message);
186
176
if (e is IOError.ALREADY_MOUNTED) {
188
} else if (e is IOError.PERMISSION_DENIED ||
189
e is IOError.FAILED_HANDLED) {
179
warning ("mount_mountable failed: %s", e.message);
180
if (e is IOError.PERMISSION_DENIED ||
181
e is IOError.FAILED_HANDLED) {
191
permission_denied = true;
183
permission_denied = true;
187
make_ready (success, file_loaded_func);
190
make_ready (true, file_loaded_func);
241
234
if (connectable != null) {
243
if (net_mon.can_reach (connectable))
246
catch (GLib.Error e) {}
236
net_mon.can_reach (connectable);
238
catch (GLib.Error e) {
239
warning ("Error connecting to connectable %s - %s", file.uri, e.message);
255
private void make_ready () {
257
unowned GLib.List? trash_dirs = null;
258
file.mount = GOF.File.get_mount_at (location);
260
if (file.mount != null) {
261
file.is_mounted = true;
262
trash_dirs = Marlin.FileOperations.get_trash_dirs_for_mount (file.mount);
263
has_trash_dirs = (trash_dirs != null);
265
has_trash_dirs = is_local;
249
private void make_ready (bool ready, GOFFileLoadedFunc? file_loaded_func = null) {
254
} else if (!is_cached) {
255
assert (directory_cache != null);
256
directory_cache.insert (location, this);
258
this.add_toggle_ref ((ToggleNotify) toggle_ref_notify);
261
debug ("created dir %s ref_count %u", this.file.uri, this.ref_count);
262
file_hash = new HashTable<GLib.File,GOF.File> (GLib.File.hash, GLib.File.equal);
263
uri_contain_keypath_icons = "/icons" in file.uri || "/.icons" in file.uri;
266
monitor = location.monitor_directory (0);
267
monitor.rate_limit = 100;
268
monitor.changed.connect (directory_changed);
269
} catch (IOError e) {
270
if (!(e is IOError.NOT_MOUNTED)) {
271
/* Will fail for remote filesystems - not an error */
272
debug ("directory monitor failed: %s %s", e.message, file.uri);
276
set_confirm_trash ();
277
file.mount = GOF.File.get_mount_at (location);
278
if (file.mount != null) {
279
file.is_mounted = true;
280
unowned GLib.List? trash_dirs = null;
281
trash_dirs = Marlin.FileOperations.get_trash_dirs_for_mount (file.mount);
282
has_trash_dirs = (trash_dirs != null);
284
has_trash_dirs = is_local;
288
connect_volume_monitor_signals ();
293
/* May be loading for the first time or reloading after clearing directory info */
294
load (file_loaded_func);
268
297
private static void toggle_ref_notify (void* data, Object object, bool is_last) {
314
348
* to perform filename completion.- Emitting a done_loaded signal in that case would cause
315
349
* the premature ending of text entry.
317
public void load (GOFFileLoadedFunc? file_loaded_func = null) {
318
cancellable.reset ();
351
private void load (GOFFileLoadedFunc? file_loaded_func = null) {
352
/* Should only be called after creation and if reloaded */
353
if (!is_cached || file_hash != null && file_hash.size () > 0) {
354
critical ("(Re)load directory called when not cleared");
358
warning ("load called when cannot load - not expected to happen");
359
after_loading (file_loaded_func);
363
if (state != State.LOADING) {
364
warning ("load called in loaded or loading state - not expected to happen");
319
368
longest_file_name = "";
320
369
permission_denied = false;
321
if (state == State.LOADING)
371
list_directory.begin (file_loaded_func);
374
private void list_cached_files (GOFFileLoadedFunc? file_loaded_func = null) {
375
if (state == State.NOT_LOADED) {
376
warning ("list cached files called in unloaded state - not expected to happen");
324
if (state != State.LOADED) {
325
set_confirm_trash ();
326
list_directory.begin (file_loaded_func);
379
bool show_hidden = is_trash || Preferences.get_default ().pref_show_hidden_files;
380
foreach (GOF.File gof in file_hash.get_values ()) {
382
after_load_file (gof, show_hidden, file_loaded_func);
385
after_loading (file_loaded_func);
388
private async void list_directory (GOFFileLoadedFunc? file_loaded_func) {
390
bool show_hidden = is_trash || Preferences.get_default ().pref_show_hidden_files;
391
var e = yield this.location.enumerate_children_async (gio_attrs, 0, 0, cancellable);
392
while (state == State.LOADING) {
393
var files = yield e.next_files_async (200, 0, cancellable);
395
state = State.LOADED;
397
foreach (var file_info in files) {
398
GLib.File loc = location.get_child (file_info.get_name ());
399
GOF.File? gof = GOF.File.cache_lookup (loc);
402
gof = new GOF.File (loc, location);
404
gof.info = file_info;
407
file_hash.insert (gof.location, gof);
409
after_load_file (gof, show_hidden, file_loaded_func);
415
} catch (Error err) {
416
warning ("Listing directory error: %s %s", err.message, file.uri);
418
if (err is IOError.NOT_FOUND || err is IOError.NOT_DIRECTORY) {
420
} else if (err is IOError.PERMISSION_DENIED)
421
permission_denied = true;
422
else if (err is IOError.NOT_MOUNTED)
423
file.is_mounted = false;
425
after_loading (file_loaded_func);
428
private void after_load_file (GOF.File gof, bool show_hidden, GOFFileLoadedFunc? file_loaded_func) {
429
if (!gof.is_hidden || show_hidden) {
430
if (track_longest_name)
431
update_longest_file_name (gof);
328
433
if (file_loaded_func == null) {
330
monitor = location.monitor_directory (0);
331
monitor.rate_limit = 100;
332
monitor.changed.connect (directory_changed);
333
} catch (IOError e) {
334
if (!(e is IOError.NOT_MOUNTED)) {
335
/* Will fail for remote filesystems - not an error */
336
debug ("directory monitor failed: %s %s", e.message, file.uri);
341
/* even if the directory is currently loading model_add_file manage duplicates */
342
debug ("directory %s load cached files", file.uri);
344
bool show_hidden = is_trash || Preferences.get_default ().pref_show_hidden_files;
346
foreach (GOF.File gof in file_hash.get_values ()) {
348
if (gof.info != null && (!gof.is_hidden || show_hidden)) {
349
if (track_longest_name)
350
update_longest_file_name (gof);
352
if (file_loaded_func == null)
355
file_loaded_func (gof);
360
if (file_loaded_func == null && !cancellable.is_cancelled ())
436
file_loaded_func (gof);
440
private void after_loading (GOFFileLoadedFunc? file_loaded_func) {
441
if (file_loaded_func == null && !cancellable.is_cancelled ()) {
444
state = State.LOADED;
365
447
public void block_monitor () {
427
501
yield location.mount_enclosing_volume (0, mount_op, cancellable);
430
private async void list_directory (GOFFileLoadedFunc? file_loaded_func = null) {
432
state = State.NOT_LOADED;
438
state = State.LOADING;
440
var e = yield this.location.enumerate_children_async (gio_attrs, 0, 0, cancellable);
441
while (state == State.LOADING) {
442
var files = yield e.next_files_async (200, 0, cancellable);
446
bool show_hidden = is_trash || Preferences.get_default ().pref_show_hidden_files;
448
foreach (var file_info in files) {
449
GLib.File loc = location.get_child (file_info.get_name ());
450
GOF.File? gof = GOF.File.cache_lookup (loc);
453
gof = new GOF.File (loc, location);
455
gof.info = file_info;
458
file_hash.insert (gof.location, gof);
460
if (!gof.is_hidden || show_hidden) {
461
if (track_longest_name)
462
update_longest_file_name (gof);
464
if (file_loaded_func == null)
467
file_loaded_func (gof);
474
if (state == State.LOADING) {
476
state = State.LOADED;
478
warning ("WARNING load() has been called again before LOADING finished");
481
} catch (Error err) {
482
warning ("Listing directory error: %s %s", err.message, file.uri);
483
state = State.NOT_LOADED;
485
if (err is IOError.NOT_FOUND || err is IOError.NOT_DIRECTORY)
487
else if (err is IOError.PERMISSION_DENIED)
488
permission_denied = true;
489
else if (err is IOError.NOT_MOUNTED)
490
file.is_mounted = false;
493
if (file_loaded_func == null && !cancellable.is_cancelled ())
497
504
public GOF.File? file_hash_lookup_location (GLib.File? location) {
498
505
if (location != null && location is GLib.File) {
499
506
GOF.File? result = file_hash.lookup (location);