implement dependent (nested) files in VS project format and in UE UI

This commit is contained in:
Michael Becker 2019-10-26 00:32:55 -04:00
parent 334eabdaaf
commit 25f9f3ef4f
7 changed files with 149 additions and 17 deletions

View File

@ -6,12 +6,12 @@ using UniversalEditor.ObjectModels.PropertyList;
namespace UniversalEditor.ObjectModels.Project
{
public class ProjectFile : ICloneable
public class ProjectFile : IProjectFileContainer, ICloneable
{
public class ProjectFileCollection
: System.Collections.ObjectModel.Collection<ProjectFile>
{
private ProjectFolder _parent = null;
private IProjectFileContainer _parent = null;
public ProjectFileCollection(ProjectFolder parent = null)
{
_parent = parent;
@ -30,24 +30,53 @@ namespace UniversalEditor.ObjectModels.Project
return file;
}
private Dictionary<string, ProjectFile> _itemsByName = new Dictionary<string, ProjectFile>();
public ProjectFile this[string name]
{
get
{
if (_itemsByName.ContainsKey(name))
return _itemsByName[name];
return null;
}
}
protected override void InsertItem(int index, ProjectFile item)
{
base.InsertItem(index, item);
item.Parent = _parent;
if (_parent != null)
item.Parent = _parent;
_itemsByName[item.DestinationFileName] = item;
}
protected override void RemoveItem(int index)
{
this[index].Parent = null;
if (_itemsByName.ContainsKey(this[index].DestinationFileName))
_itemsByName.Remove(this[index].DestinationFileName);
if (_parent != null)
this[index].Parent = null;
base.RemoveItem(index);
}
protected override void ClearItems()
{
foreach (ProjectFile file in this)
if (_parent != null)
{
file.Parent = null;
foreach (ProjectFile file in this)
{
file.Parent = null;
}
}
base.ClearItems();
}
protected override void SetItem(int index, ProjectFile item)
{
if (_itemsByName.ContainsKey(this[index].DestinationFileName))
_itemsByName.Remove(this[index].DestinationFileName);
base.SetItem(index, item);
_itemsByName[item.DestinationFileName] = item;
}
}
private string mvarSourceFileName = String.Empty;
@ -68,8 +97,8 @@ namespace UniversalEditor.ObjectModels.Project
/// </summary>
public PropertyListObjectModel Configuration { get { return mvarConfiguration; } set { mvarConfiguration = value; } }
private ProjectFolder mvarParent = null;
public ProjectFolder Parent { get { return mvarParent; } private set { mvarParent = value; } }
private IProjectFileContainer mvarParent = null;
public IProjectFileContainer Parent { get { return mvarParent; } private set { mvarParent = value; } }
public object Clone()
{
@ -82,5 +111,8 @@ namespace UniversalEditor.ObjectModels.Project
private byte[] mvarContent = new byte[0];
public byte[] Content { get { return mvarContent; } set { mvarContent = value; } }
public ProjectFileCollection Dependents { get; } = new ProjectFileCollection();
public ProjectFileCollection Files { get; } = new ProjectFileCollection();
}
}

View File

@ -79,5 +79,30 @@ namespace UniversalEditor.ObjectModels.Project
parentFolder.Files.Add(pf);
}
}
public ProjectFile FindFile(string filePath)
{
string[] pathParts = filePath.Split(new char[] { '\\', '/' });
ProjectFolder pfParent = null;
for (int i = 0; i < pathParts.Length - 1; i++)
{
if (pfParent == null)
{
pfParent = Folders[pathParts[i]];
}
else
{
pfParent = pfParent.Folders[pathParts[i]];
}
}
if (pfParent == null)
{
return Files[pathParts[pathParts.Length - 1]];
}
else
{
return pfParent.Files[pathParts[pathParts.Length - 1]];
}
}
}
}

View File

@ -5,7 +5,7 @@ using System.Text;
namespace UniversalEditor.ObjectModels.Project
{
public class ProjectFolder : ICloneable
public class ProjectFolder : IProjectFileContainer, ICloneable
{
public class ProjectFolderCollection
: System.Collections.ObjectModel.Collection<ProjectFolder>

View File

@ -0,0 +1,28 @@
//
// ProjectItem.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace UniversalEditor.ObjectModels.Project
{
public interface IProjectFileContainer
{
ProjectFile.ProjectFileCollection Files { get; }
}
}

View File

@ -16,7 +16,6 @@
<AssemblyOriginatorKeyFile>..\..\..\..\MichaelBecker.snk</AssemblyOriginatorKeyFile>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ReleaseVersion>1.0.*</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -181,6 +180,7 @@
<Compile Include="ObjectModels\JSON\Fields\JSONStringField.cs" />
<Compile Include="DataFormats\Text\Plain\PlainTextDataFormat.cs" />
<Compile Include="DataFormats\Shortcut\Linux\LinuxShortcutDataFormat.cs" />
<Compile Include="ObjectModels\Project\ProjectItem.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UniversalEditor.Core\UniversalEditor.Core.csproj">

View File

@ -24,6 +24,7 @@ using MBS.Framework.UserInterface;
using MBS.Framework.UserInterface.Controls;
using MBS.Framework.UserInterface.Dialogs;
using MBS.Framework.UserInterface.Layouts;
using UniversalEditor.ObjectModels.Project;
using UniversalEditor.ObjectModels.Solution;
namespace UniversalEditor.UserInterface.Panels
@ -59,16 +60,31 @@ namespace UniversalEditor.UserInterface.Panels
}
foreach (ObjectModels.Project.ProjectFile file in fold.Files)
{
TreeModelRow rowFile = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmSolutionExplorer.Columns[0], file.DestinationFileName)
});
rowFile.SetExtraData<ObjectModels.Project.ProjectFile>("file", file);
if (file.Dependents.Count > 0)
continue;
TreeModelRow rowFile = LoadSolutionExplorerFile(file);
rowFolder.Rows.Add(rowFile);
}
return rowFolder;
}
private TreeModelRow LoadSolutionExplorerFile(ProjectFile file)
{
TreeModelRow rowFile = new TreeModelRow(new TreeModelRowColumn[]
{
new TreeModelRowColumn(tmSolutionExplorer.Columns[0], file.DestinationFileName)
});
rowFile.SetExtraData<ObjectModels.Project.ProjectFile>("file", file);
foreach (ProjectFile file2 in file.Files)
{
TreeModelRow rowFile2 = LoadSolutionExplorerFile(file2);
rowFile2.SetExtraData<ObjectModels.Project.ProjectFile>("file", file2);
rowFile.Rows.Add(rowFile2);
}
return rowFile;
}
private void UpdateSolutionExplorer()
{
tmSolutionExplorer.Rows.Clear();

View File

@ -44,6 +44,7 @@ namespace UniversalEditor.DataFormats.Project.Microsoft.VisualStudio
MarkupTagElement tagProject = (mom.Elements["Project"] as MarkupTagElement);
if (tagProject == null) throw new InvalidDataFormatException();
Dictionary<string, List<string>> dependents = new Dictionary<string, List<string>>();
for (int i = 0; i < tagProject.Elements.Count; i++)
{
MarkupTagElement tag = (tagProject.Elements[i] as MarkupTagElement);
@ -54,10 +55,24 @@ namespace UniversalEditor.DataFormats.Project.Microsoft.VisualStudio
for (int j = 0; j < tag.Elements.Count; j++)
{
MarkupTagElement tag1 = (tag.Elements[j] as MarkupTagElement);
if (tag1.FullName.Equals("Compile") || tag1.FullName.Equals("Content") || tag1.FullName.Equals("None"))
if (tag1.FullName.Equals("Compile") || tag1.FullName.Equals("Content") || tag1.FullName.Equals("EmbeddedResource") || tag1.FullName.Equals("None"))
{
MarkupAttribute attInclude = tag1.Attributes["Include"];
proj.FileSystem.AddFile(basePath + System.IO.Path.DirectorySeparatorChar.ToString() + attInclude.Value.Replace('\\', System.IO.Path.DirectorySeparatorChar), attInclude.Value, '\\');
string relativePath = attInclude.Value.Replace('\\', System.IO.Path.DirectorySeparatorChar);
proj.FileSystem.AddFile(basePath + System.IO.Path.DirectorySeparatorChar.ToString() + relativePath, attInclude.Value, '\\');
MarkupTagElement tagDependentUpon = (tag1.Elements["DependentUpon"] as MarkupTagElement);
if (tagDependentUpon != null)
{
string[] pathParts = attInclude.Value.Split(new char[] { '\\' });
string dependentParentPath = String.Join("\\", pathParts, 0, pathParts.Length - 1);
string dependentFullPath = String.Format("{0}\\{1}", dependentParentPath, tagDependentUpon.Value);
if (!dependents.ContainsKey(dependentFullPath))
{
dependents[dependentFullPath] = new List<string>();
}
dependents[dependentFullPath].Add(relativePath);
}
}
else if (tag1.FullName.Equals("Reference"))
{
@ -69,6 +84,22 @@ namespace UniversalEditor.DataFormats.Project.Microsoft.VisualStudio
}
}
}
foreach (KeyValuePair<string, List<string>> kvp in dependents)
{
ProjectFile pfDependent = proj.FileSystem.FindFile(kvp.Key);
foreach (string val in kvp.Value)
{
ProjectFile pf2 = proj.FileSystem.FindFile(val);
if (pf2 == null)
{
Console.WriteLine("prj::fs file {0} not found", val);
continue;
}
pfDependent.Files.Add(pf2);
pf2.Dependents.Add(pfDependent);
}
}
}
protected override void BeforeSaveInternal(Stack<ObjectModel> objectModels)
{