1
/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
3
This file is part of Déjà Dup.
4
For copyright information, see AUTHORS.
6
Déjà Dup is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
11
Déjà Dup is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
24
internal abstract class RecursiveOp : Object
26
public signal void done();
27
public signal void raise_error(File src, File dst, string errstr);
29
public File src {get; construct;}
30
public File dst {get; construct;}
32
protected FileType src_type;
33
protected FileType dst_type;
34
protected virtual void handle_file() {} // src is file
35
protected virtual void handle_dir() {} // src is dir
36
protected virtual void finish_dir() {} // src is dir we are done with
37
protected abstract RecursiveOp clone_for_info(FileInfo info);
49
Idle.add(idle_action);
50
var loop = new MainLoop(null, false);
51
done.connect((m) => {loop.quit();});
55
public void start_async()
58
src_type = src.query_file_type(FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
60
dst_type = dst.query_file_type(FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
63
case FileType.DIRECTORY:
74
void recurse_on_info(FileInfo info)
77
var op = clone_for_info(info);
79
op.done.connect((m) => {remove_ref(); m.unref();});
80
op.raise_error.connect((m, s, d, e) => {raise_error(s, d, e);}); // percolate up
84
static const int NUM_ENUMERATED = 16;
92
var enumerator = yield src.enumerate_children_async(
93
FILE_ATTRIBUTE_STANDARD_NAME,
94
FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
95
Priority.DEFAULT, null);
98
var infos = yield enumerator.next_files_async(NUM_ENUMERATED,
99
Priority.DEFAULT, null);
101
foreach (FileInfo info in infos)
102
recurse_on_info(info);
104
if (infos.length() != NUM_ENUMERATED) {
105
remove_ref(); // parent dir itself
111
raise_error(src, dst, e.message);
112
remove_ref(); // parent dir itself
127
if (src_type == FileType.DIRECTORY)