3
* Copyright (C) 2015 Christian Hergert <christian@hergert.me>
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#include "ide-context.h"
20
#include "ide-project-file.h"
21
#include "ide-project-files.h"
26
GHashTable *files_by_path;
27
} IdeProjectFilesPrivate;
29
G_DEFINE_TYPE_WITH_PRIVATE (IdeProjectFiles, ide_project_files,
30
IDE_TYPE_PROJECT_ITEM)
33
ide_project_files_dispose (GObject *object)
35
IdeProjectFiles *self = (IdeProjectFiles *)object;
36
IdeProjectFilesPrivate *priv = ide_project_files_get_instance_private (self);
38
g_clear_pointer (&priv->files_by_path, g_hash_table_unref);
40
G_OBJECT_CLASS (ide_project_files_parent_class)->dispose (object);
44
ide_project_files_class_init (IdeProjectFilesClass *klass)
46
GObjectClass *object_class = G_OBJECT_CLASS (klass);
48
object_class->dispose = ide_project_files_dispose;
52
ide_project_files_init (IdeProjectFiles *self)
54
IdeProjectFilesPrivate *priv = ide_project_files_get_instance_private (self);
56
priv->files_by_path = g_hash_table_new_full (g_str_hash, g_str_equal,
57
g_free, g_object_unref);
60
static IdeProjectItem *
61
ide_project_files_find_child (IdeProjectItem *item,
67
g_assert (IDE_IS_PROJECT_ITEM (item));
70
children = ide_project_item_get_children (item);
74
for (iter = g_sequence_get_begin_iter (children);
75
!g_sequence_iter_is_end (iter);
76
iter = g_sequence_iter_next (iter))
78
IdeProjectItem *current_item = g_sequence_get (iter);
80
if (IDE_IS_PROJECT_FILE (current_item))
85
file = IDE_PROJECT_FILE (current_item);
86
name = ide_project_file_get_name (file);
88
if (g_strcmp0 (name, child) == 0)
97
* ide_project_files_find_file:
98
* @self: (in): A #IdeProjectFiles.
101
* Tries to locate an #IdeProjectFile matching the given file.
102
* If @file is the working directory, @self is returned.
104
* Returns: (transfer none) (nullable): An #IdeProjectItem or %NULL.
107
ide_project_files_find_file (IdeProjectFiles *self,
110
IdeProjectItem *item;
118
g_return_val_if_fail (IDE_IS_PROJECT_FILES (self), NULL);
119
g_return_val_if_fail (G_IS_FILE (file), NULL);
121
item = IDE_PROJECT_ITEM (self);
122
context = ide_object_get_context (IDE_OBJECT (self));
123
vcs = ide_context_get_vcs (context);
124
workdir = ide_vcs_get_working_directory (vcs);
126
if (g_file_equal (workdir, file))
127
return IDE_PROJECT_ITEM (self);
129
path = g_file_get_relative_path (workdir, file);
133
parts = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
135
for (i = 0; parts [i]; i++)
137
if (!(item = ide_project_files_find_child (item, parts [i])))
148
* ide_project_files_get_file_for_path:
150
* Retrieves an #IdeFile for the path. If no such path exists within the
151
* project, %NULL is returned.
153
* Returns: (transfer full) (nullable): An #IdeFile or %NULL.
156
ide_project_files_get_file_for_path (IdeProjectFiles *self,
159
IdeProjectFilesPrivate *priv = ide_project_files_get_instance_private (self);
160
IdeProjectItem *item = (IdeProjectItem *)self;
161
IdeFile *file = NULL;
165
g_return_val_if_fail (IDE_IS_PROJECT_FILES (self), NULL);
167
if ((file = g_hash_table_lookup (priv->files_by_path, path)))
168
return g_object_ref (file);
170
parts = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
172
for (i = 0; item && parts [i]; i++)
173
item = ide_project_files_find_child (item, parts [i]);
178
const gchar *file_path;
181
context = ide_object_get_context (IDE_OBJECT (self));
182
gfile = ide_project_file_get_file (IDE_PROJECT_FILE (item));
183
file_path = ide_project_file_get_path (IDE_PROJECT_FILE (item));
184
file = g_object_new (IDE_TYPE_FILE,
190
g_hash_table_insert (priv->files_by_path, g_strdup (file_path), g_object_ref (file));
197
ide_project_files_add_file (IdeProjectFiles *self,
198
IdeProjectFile *file)
200
IdeProjectItem *item = (IdeProjectItem *)self;
201
g_autoptr(GFile) parent = NULL;
202
g_autofree gchar *path = NULL;
210
g_return_if_fail (IDE_IS_PROJECT_FILES (self));
211
g_return_if_fail (IDE_IS_PROJECT_FILE (file));
213
context = ide_object_get_context (IDE_OBJECT (self));
214
vcs = ide_context_get_vcs (context);
215
workdir = ide_vcs_get_working_directory (vcs);
217
gfile = ide_project_file_get_file (file);
218
parent = g_file_get_parent (gfile);
219
path = g_file_get_relative_path (workdir, parent);
223
ide_project_item_append (IDE_PROJECT_ITEM (self), IDE_PROJECT_ITEM (file));
227
parts = g_strsplit (path, G_DIR_SEPARATOR_S, 0);
229
for (i = 0; parts [i]; i++)
231
IdeProjectItem *found;
233
found = ide_project_files_find_child (item, parts [i]);
237
g_autoptr(GFileInfo) file_info = NULL;
238
g_autofree gchar *child_path = NULL;
239
IdeProjectItem *child;
240
const gchar *item_path;
241
g_autoptr(GFile) item_file = NULL;
243
file_info = g_file_info_new ();
244
g_file_info_set_file_type (file_info, G_FILE_TYPE_DIRECTORY);
245
g_file_info_set_display_name (file_info, parts [i]);
246
g_file_info_set_name (file_info, parts [i]);
248
item_path = ide_project_file_get_path (IDE_PROJECT_FILE (item));
249
child_path = g_strjoin (G_DIR_SEPARATOR_S, item_path, parts [i], NULL);
250
item_file = g_file_get_child (workdir, child_path);
252
child = g_object_new (IDE_TYPE_PROJECT_FILE,
257
"file-info", file_info,
259
ide_project_item_append (item, child);
269
ide_project_item_append (item, IDE_PROJECT_ITEM (file));