ENH: create a "Virtual Folder" in CodeBlocks, which contains all the cmake

files of the project, i.e. there is now a "CMake Files" folder additionally
to the "Sources", "Headers" and "Others" folders which already existed.
Patch by Daniel Teske.

Alex
This commit is contained in:
Alexander Neundorf 2009-06-28 04:58:27 -04:00
parent 42270c86b0
commit 45652bc20b
1 changed files with 192 additions and 0 deletions

View File

@ -110,6 +110,146 @@ void cmExtraCodeBlocksGenerator::CreateProjectFile(
}
/* Tree is used to create a "Virtual Folder" in CodeBlocks, in which all
CMake files this project depends on will be put. This means additionally
to the "Sources" and "Headers" virtual folders of CodeBlocks, there will
now also be a "CMake Files" virtual folder.
Patch by Daniel Teske <daniel.teske AT nokia.com> (which use C::B project
files in QtCreator).*/
struct Tree
{
std::string path; //only one component of the path
std::vector<Tree> folders;
std::vector<std::string> files;
void InsertPath(const std::vector<std::string>& splitted,
std::vector<std::string>::size_type start,
const std::string& fileName);
void BuildVirtualFolder(std::string& virtualFolders) const;
void BuildVirtualFolderImpl(std::string& virtualFolders,
const std::string& prefix) const;
void BuildUnit(std::string& unitString, const std::string& fsPath) const;
void BuildUnitImpl(std::string& unitString,
const std::string& virtualFolderPath,
const std::string& fsPath) const;
};
void Tree::InsertPath(const std::vector<std::string>& splitted,
std::vector<std::string>::size_type start,
const std::string& fileName)
{
if (start == splitted.size())
{
files.push_back(fileName);
return;
}
for (std::vector<Tree>::iterator
it = folders.begin();
it != folders.end();
++it)
{
if ((*it).path == splitted.at(start))
{
if (start + 1 < splitted.size())
{
it->InsertPath(splitted, start + 1, fileName);
return;
}
else
{
// last part of splitted
it->files.push_back(fileName);
return;
}
}
}
// Not found in folders, thus insert
Tree newFolder;
newFolder.path = splitted.at(start);
if (start + 1 < splitted.size())
{
newFolder.InsertPath(splitted, start + 1, fileName);
folders.push_back(newFolder);
return;
}
else
{
// last part of splitted
newFolder.files.push_back(fileName);
folders.push_back(newFolder);
return;
}
}
void Tree::BuildVirtualFolder(std::string& virtualFolders) const
{
virtualFolders += "<Option virtualFolders=\"CMake Files\\;";
for (std::vector<Tree>::const_iterator it = folders.begin();
it != folders.end();
++it)
{
it->BuildVirtualFolderImpl(virtualFolders, "");
}
virtualFolders += "\" />";
}
void Tree::BuildVirtualFolderImpl(std::string& virtualFolders,
const std::string& prefix) const
{
virtualFolders += "CMake Files\\" + prefix + path + "\\;";
for (std::vector<Tree>::const_iterator it = folders.begin();
it != folders.end();
++it)
{
it->BuildVirtualFolderImpl(virtualFolders, prefix + path + "\\");
}
}
void Tree::BuildUnit(std::string& unitString, const std::string& fsPath) const
{
for (std::vector<std::string>::const_iterator it = files.begin();
it != files.end();
++it)
{
unitString += " <Unit filename=\"" + fsPath + *it + "\">\n";
unitString += " <Option virtualFolder=\"CMake Files\\\" />\n";
unitString += " </Unit>\n";
}
for (std::vector<Tree>::const_iterator it = folders.begin();
it != folders.end();
++it)
{
it->BuildUnitImpl(unitString, "", fsPath);
}
}
void Tree::BuildUnitImpl(std::string& unitString,
const std::string& virtualFolderPath,
const std::string& fsPath) const
{
for (std::vector<std::string>::const_iterator it = files.begin();
it != files.end();
++it)
{
unitString += " <Unit filename=\"" +fsPath+path+ "/" + *it + "\">\n";
unitString += " <Option virtualFolder=\"CMake Files\\"
+ virtualFolderPath + path + "\\\" />\n";
unitString += " </Unit>\n";
}
for (std::vector<Tree>::const_iterator it = folders.begin();
it != folders.end();
++it)
{
it->BuildUnitImpl(unitString,
virtualFolderPath + path + "\\", fsPath + path + "/");
}
}
void cmExtraCodeBlocksGenerator
::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
const std::string& filename)
@ -121,6 +261,54 @@ void cmExtraCodeBlocksGenerator
return;
}
Tree tree;
// build tree of virtual folders
for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
it = this->GlobalGenerator->GetProjectMap().begin();
it != this->GlobalGenerator->GetProjectMap().end();
++it)
{
// Convert
std::vector<std::string> listFiles =
it->second[0]->GetMakefile()->GetListFiles();
for (std::vector<std::string>::const_iterator jt = listFiles.begin();
jt != listFiles.end();
++jt)
{
const std::string &relative =
cmSystemTools::RelativePath(
it->second[0]->GetMakefile()->GetHomeDirectory(),
jt->c_str());
std::vector<std::string> splitted;
cmSystemTools::SplitPath(relative.c_str(), splitted, false);
// Split filename from path
std::string fileName = *(splitted.end()-1);
splitted.erase(splitted.end() - 1, splitted.end());
// We don't want paths with ".." in them
// reasons are that we don't want files outside the project
// TODO: the path should be normalized first though
// We don't want paths with CMakeFiles in them
// or do we?
// In speedcrunch those where purely internal
if (splitted.size() >= 1
&& relative.find("..") == std::string::npos
&& relative.find("CMakeFiles") == std::string::npos)
{
tree.InsertPath(splitted, 1, fileName);
}
}
}
// Now build a virtual tree string
std::string virtualFolders;
tree.BuildVirtualFolder(virtualFolders);
// And one for <Unit>
std::string unitFiles;
tree.BuildUnit(unitFiles, std::string(mf->GetHomeDirectory()) + "/");
// figure out the compiler
std::string compiler = this->GetCBCompilerId(mf);
std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
@ -132,6 +320,7 @@ void cmExtraCodeBlocksGenerator
" <Option title=\"" << mf->GetProjectName()<<"\" />\n"
" <Option makefile_is_custom=\"1\" />\n"
" <Option compiler=\"" << compiler << "\" />\n"
" "<<virtualFolders<<"\n"
" <Build>\n";
bool installTargetCreated = false;
@ -345,6 +534,9 @@ void cmExtraCodeBlocksGenerator
" </Unit>\n";
}
// Add CMakeLists.txt
fout<<unitFiles;
fout<<" </Project>\n"
"</CodeBlocks_project_file>\n";
}