in EnvDTE.Client/Impl/ProjectModelImpl/ProjectItemsImplementation.cs [14:96]
public class ProjectItemsImplementation(
[NotNull] DteImplementation dte,
[NotNull] ProjectImplementation containingProject,
[NotNull] object parent,
[NotNull] ProjectItemModel parentItemModel)
: ProjectItems
{
private IEnumerable<ProjectItemModel> ProjectItemModels =>
dte.DteProtocolModel.ProjectItem_get_ProjectItems.Sync(new(parentItemModel));
protected DteImplementation DteImplementation => dte;
protected ProjectImplementation ContainingProjectImplementation => containingProject;
public DTE DTE => dte;
public object Parent => parent;
public Project ContainingProject => containingProject;
public int Count => dte.DteProtocolModel.ProjectItem_get_ProjectItemCount.Sync(new(parentItemModel));
public virtual string Kind => Constants.vsProjectItemKindPhysicalFolder;
[CanBeNull]
public ProjectItem Item(object index)
{
int? intIndex;
if (index is string name)
intIndex = dte.DteProtocolModel.ProjectItem_get_SubItemIndex.Sync(
new(name, parentItemModel));
else
intIndex = ImplementationUtil.GetValidIndexOrThrow(index, Count);
if (intIndex is null) return null;
var itemModel = ProjectItemModels.ElementAtOrDefault(intIndex.Value);
return itemModel is null ? null : CreateProjectItem(itemModel);
}
public IEnumerator GetEnumerator() => ProjectItemModels.Select(CreateProjectItem).GetEnumerator();
[CanBeNull] public ProjectItem AddFromFile([NotNull] string fileName) =>
AddExistingItem(fileName, dte.DteProtocolModel.ProjectItems_addFromFile);
[CanBeNull] public ProjectItem AddFromFileCopy([NotNull] string filePath) =>
AddExistingItem(filePath, dte.DteProtocolModel.ProjectItems_addFromFileCopy);
[CanBeNull] public ProjectItem AddFromDirectory([NotNull] string directory) =>
AddExistingItem(directory, dte.DteProtocolModel.ProjectItems_addFromDirectory, isDirectory: true);
[CanBeNull]
public ProjectItem AddFolder([NotNull] string name, [NotNull] string kind = Constants.vsProjectItemKindPhysicalFolder)
{
var kindModel = kind.ToRdItemKindModel();
// Only works with PhysicalFolder project item kind in VS (this also means that we don't have to pass the kind to the host)
if (kindModel != ProjectItemKindModel.PhysicalFolder) throw new ArgumentException(nameof(kind));
var id = dte.DteProtocolModel.ProjectItems_addFolder.Sync(
new(name, parentItemModel));
return id is null ? null : CreateProjectItem(id);
}
protected virtual ProjectItemImplementation CreateProjectItem([NotNull] ProjectItemModel projectItemModel) =>
new(dte, projectItemModel, containingProject);
internal ProjectItemImplementation Item(ProjectItemModel projectItemModel) => CreateProjectItem(projectItemModel);
[CanBeNull]
private ProjectItem AddExistingItem(
[NotNull] string path,
[NotNull] IRdCall<AddExistingItemRequest, ProjectItemModel> addCall,
bool isDirectory = false)
{
var fullPath = Path.GetFullPath(path);
// This operation could take a long time, so call it asynchronously to avoid the timeout
// TODO: Figure out if its possible to enable cancellation
var id = addCall.Start(dte.DteLifetime,
new(fullPath, isDirectory, parentItemModel)).GetAwaiter().GetResult();
return id is null ? null : CreateProjectItem(id);
}
#region NotImplemented
public ProjectItem AddFromTemplate(string FileName, string Name) => throw new NotImplementedException();
#endregion
}