Skip to content

Commit 99dd301

Browse files
committed
Feature: Sketch initial support for files adding into project.
1 parent 4829697 commit 99dd301

8 files changed

Lines changed: 215 additions & 23 deletions

File tree

SolutionProjectModel/Project.cpp

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -303,22 +303,63 @@ std::string Project::GetToolset()
303303
//
304304
// Adds files to the project.
305305
//
306-
void Project::AddFiles(std::initializer_list<std::string> fileList)
306+
void Project::AddFiles(std::initializer_list<std::wstring> fileList)
307307
{
308-
wstring projDir = GetSaveDirectory();
309-
path pprojDir(projDir);
310-
error_code ec;
308+
for (wstring f : fileList)
309+
AddFile(f.c_str());
310+
}
311+
312+
void Project::AddFile(const wchar_t* file)
313+
{
314+
wstring projectDir = GetSaveDirectory();
315+
path pathFile(file);
316+
if( !pathFile.is_absolute() )
317+
pathFile = path(projectDir).append(file);
318+
319+
pathFile = weakly_canonical(pathFile);
320+
wstring relativePath = relative(pathFile, projectDir);
321+
322+
auto it = find_if(files.begin(), files.end(), [relativePath](ProjectFile& f) { return f.relativePath == relativePath; } );
323+
if( it != files.end() )
324+
return;
325+
326+
xml_node proj = project();
327+
xml_node markInsert = markForPropertyGroup;
328+
wstring name;
329+
330+
while( (name = markInsert.next_sibling().name()) == L"Import" || name == L"PropertyGroup" || name == L"PropertyGroup" || name == L"ItemDefinitionGroup")
331+
markInsert = markInsert.next_sibling();
332+
333+
ItemType newType = ProjectFile::GetFromPath(relativePath.c_str());
334+
xml_node itemGroup;
311335

312-
for (auto f : fileList)
336+
for(xml_node next = markInsert.next_sibling() ; (name = next.name() ) == L"ItemGroup"; )
313337
{
314-
path fp(f);
315-
if (!fp.is_absolute())
316-
fp = path(projDir).append(f);
338+
ItemType type;
317339

318-
fp = canonical(fp);
340+
if( StringToEnum( as_utf8(next.first_child().name()).c_str() , type))
341+
{
342+
if(newType > type)
343+
{
344+
markInsert = next; next = next.next_sibling();
345+
continue;
346+
}
319347

320-
wstring relativePath = relative(fp, pprojDir);
348+
if(type == newType)
349+
itemGroup = next;
350+
}
351+
352+
break;
321353
}
354+
355+
if(itemGroup.empty())
356+
itemGroup = proj.insert_child_after(L"ItemGroup", markInsert);
357+
358+
ProjectFile p;
359+
p.relativePath = relativePath;
360+
p.node = itemGroup.append_child(as_wide(EnumToString(newType)).c_str());
361+
p.node.append_attribute(L"Include").set_value(relativePath.c_str());
362+
files.push_back(p);
322363
}
323364

324365

@@ -398,9 +439,9 @@ pugi::xml_node Project::project()
398439
// Specify utf-8 encoding.
399440
pugi::xml_node decl;
400441

401-
for (auto n : children())
402-
if (n.type() == pugi::node_declaration)
403-
decl = n;
442+
for (auto markInsert : children())
443+
if (markInsert.type() == pugi::node_declaration)
444+
decl = markInsert;
404445

405446
// Xml declaration
406447
if (decl.empty())

SolutionProjectModel/Project.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@
22
#include "ProjectFile.h"
33
#include <string>
44
#include <vector>
5+
#include <list>
56
#include <initializer_list>
67
#include <guiddef.h> //GUID
78

8-
// warning C4251: ... needs to have dll-interface to be used by clients of class ...
9-
#pragma warning( disable: 4251 )
10-
// warning C4275: non dll-interface class 'pugi::xml_document' used as base for dll-interface class 'Solution'
11-
#pragma warning( disable: 4275 )
12-
139
//---------------------------------------------------------
1410
// Project
1511
//---------------------------------------------------------
@@ -76,7 +72,8 @@ class SPM_DLLEXPORT Project : pugi::xml_document
7672
//
7773
// Adds files to the project.
7874
//
79-
void AddFiles(std::initializer_list<std::string> fileList);
75+
void AddFiles(std::initializer_list<std::wstring> fileList);
76+
void AddFile(const wchar_t* file);
8077

8178

8279
protected:
@@ -92,6 +89,9 @@ class SPM_DLLEXPORT Project : pugi::xml_document
9289
// "Debug", "Release", user defined
9390
std::vector<std::string> configurations;
9491

92+
// List of files within a project.
93+
std::list<ProjectFile> files;
94+
9595
// Project guid
9696
GUID guid;
9797

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,43 @@
11
#pragma once
2+
#include "ProjectFile.h"
3+
#include <filesystem>
4+
#include <algorithm>
5+
6+
using namespace std;
7+
using namespace std::filesystem;
8+
9+
string lowercased( string s )
10+
{
11+
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
12+
return s;
13+
}
14+
15+
//
16+
// Generic autoprobe - file extension to guessed type.
17+
//
18+
ItemType ProjectFile::GetFromPath(const wchar_t* file)
19+
{
20+
string ext = lowercased(path(file).extension().string().substr(1));
21+
22+
struct TypeInfoStr
23+
{
24+
const char* ext;
25+
ItemType type;
26+
} types [] =
27+
{
28+
{"properties", AntProjectPropertiesFile},
29+
{"h", ClInclude},
30+
{"c", ClCompile},
31+
{"cxx", ClCompile},
32+
{"cpp", ClCompile},
33+
{"java", JavaCompile},
34+
{"template", GradleTemplate},
35+
{"rc", ResourceCompile},
36+
{"ico", Image},
37+
{"txt", Text},
38+
{"?", None}
39+
};
40+
41+
TypeInfoStr* end = types + _countof(types) - 1;
42+
return find_if(types, end, [ext](TypeInfoStr& ti) { return ti.ext == ext; } )->type;
43+
}

SolutionProjectModel/ProjectFile.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
11
#pragma once
22
#include "../pugixml/pugixml.hpp"
3+
#include <string>
4+
#include "ProjectFileTypes.h"
35

46
#ifdef SPM_EXPORT
57
#define SPM_DLLEXPORT __declspec(dllexport)
68
#else
79
#define SPM_DLLEXPORT __declspec(dllimport)
810
#endif
911

10-
12+
// warning C4251: ... needs to have dll-interface to be used by clients of class ...
13+
#pragma warning( disable: 4251 )
14+
// warning C4275: non dll-interface class 'pugi::xml_document' used as base for dll-interface class 'Solution'
15+
#pragma warning( disable: 4275 )
16+
17+
18+
//
19+
// Information about that particular file.
20+
//
1121
class SPM_DLLEXPORT ProjectFile
1222
{
1323
public:
24+
//
25+
// Generic autoprobe - file extension to guessed type.
26+
//
27+
static ItemType GetFromPath(const wchar_t* file);
1428

29+
//
30+
// Relative path to file (from project path perspective)
31+
//
32+
std::wstring relativePath;
1533

16-
protected:
34+
//
35+
// Xml node containing child xml data.
36+
//
37+
pugi::xml_node node;
1738
};
1839

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#pragma once
2+
#include "EnumReflect.h"
3+
4+
/// <summary>
5+
/// Defines what needs to be done with given item. Not all project types support all enumerations - for example
6+
/// packaging projects / C# projects does not support CustomBuild.
7+
///
8+
/// Order of ItemType must be the same as appear in .vcxproj (first comes first)
9+
/// </summary>
10+
DECLARE_ENUM(ItemType,
11+
12+
/// <summary>
13+
/// C# references to .net assemblies
14+
/// </summary>
15+
Reference,
16+
17+
/// <summary>
18+
/// Header file (.h)
19+
/// </summary>
20+
ClInclude,
21+
22+
/// <summary>
23+
/// Source codes (.cpp) files
24+
/// </summary>
25+
ClCompile,
26+
27+
/// <summary>
28+
/// .rc / resource files.
29+
/// </summary>
30+
ResourceCompile,
31+
32+
/// <summary>
33+
/// Any custom file with custom build step
34+
/// </summary>
35+
CustomBuild,
36+
37+
/// <summary>
38+
/// .def / .bat
39+
/// </summary>
40+
None,
41+
42+
/// <summary>
43+
/// .ico files.
44+
/// </summary>
45+
Image,
46+
47+
/// <summary>
48+
/// .txt files.
49+
/// </summary>
50+
Text,
51+
52+
// Following enumerations are used in android packaging project (.androidproj)
53+
Content,
54+
AntBuildXml,
55+
AndroidManifest,
56+
AntProjectPropertiesFile,
57+
58+
/// <summary>
59+
/// For Android package project: Reference to another project, which needs to be included into package.
60+
/// </summary>
61+
ProjectReference,
62+
63+
/// <summary>
64+
/// Intentionally not valid value, so can be replaced with correct one. (Visual studio does not supports one)
65+
/// </summary>
66+
Invalid,
67+
68+
/// <summary>
69+
/// C# - source codes to compile
70+
/// </summary>
71+
Compile,
72+
73+
/// <summary>
74+
/// Android / Gradle project, *.template files.
75+
/// </summary>
76+
GradleTemplate,
77+
78+
/// <summary>
79+
/// .java - source codes to compile
80+
/// </summary>
81+
JavaCompile
82+
);
83+
84+

SolutionProjectModel/SolutionProjectModel.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,11 @@
172172
<ItemGroup>
173173
<ClInclude Include="..\pugixml\pugiconfig.hpp" />
174174
<ClInclude Include="..\pugixml\pugixml.hpp" />
175+
<ClInclude Include="EnumReflect.h" />
175176
<ClInclude Include="Project.h" />
176177
<ClInclude Include="ProjectFile.h" />
177178
<ClInclude Include="Solution.h" />
179+
<ClInclude Include="ProjectFileTypes.h" />
178180
</ItemGroup>
179181
<ItemGroup>
180182
<Natvis Include="..\pugixml\pugixml.natvis" />

SolutionProjectModel/SolutionProjectModel.vcxproj.filters

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
<Filter>pugixml</Filter>
2020
</ClInclude>
2121
<ClInclude Include="ProjectFile.h" />
22+
<ClInclude Include="EnumReflect.h" />
23+
<ClInclude Include="ProjectFileTypes.h" />
2224
</ItemGroup>
2325
<ItemGroup>
2426
<Filter Include="pugixml">

SolutionProjectModel/testCppApp.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ void main(void)
1414
//printf("%s", p.configurations[0].c_str());
1515

1616
p.AddPlatforms( { "Win32" } );
17-
p.AddFiles({ "Solution.h" });
18-
p.AddFiles({ path(p.GetSaveDirectory()).append("Solution.cpp").string() });
17+
p.AddFiles({ L"Solution.h" });
18+
p.AddFiles({ path(p.GetSaveDirectory()).append(L"Solution.cpp").wstring() });
1919
p.Save();
2020

2121
p.AddPlatforms({ "x64" });

0 commit comments

Comments
 (0)