Bug is present in recent svn version 10373 :
Code::Blocks svn build rev 10373 Jul 29 2015, 18:44:13 - wx2.8.12 (Linux, unicode) - 64 bit
OK, got it ( using compiled version described above )
When I load a sample project I made for this post's purpose, I get :
http://www.mediafire.com/view/s565sfhf03nql72/08.png (http://www.mediafire.com/view/s565sfhf03nql72/08.png)
Here are the steps :
I) Project gets loaded ; files are inserted in the cbProject.m_Files member :
ProjectFile* cbProject::AddFile(int targetIndex, const wxString& filename, bool compile, bool link, cb_unused unsigned short int weight)
{
...
m_Files.insert(pf);
...
}
with m_Files beeing a wxHashSet :
This is a simple, type-safe, and reasonably efficient hash set class, whose interface is a subset of the interface of STL containers.
Insert_Result wxHashSet::insert(const value_type &v)
, as declared in "projectfile.h".
WX_DECLARE_HASH_SET ( ProjectFile*, wxPointerHash, wxPointerEqual, FilesList );
Lets dump m_Files as projectfile objects are inserted inside it :
ProjectFile* cbProject::AddFile(int targetIndex, const wxString& filename, bool compile, bool link, cb_unused unsigned short int weight)
{ ...
m_Files.insert(pf);
for (FilesList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
{
ProjectFile* gpf = *it;
LOG("cbProject::AddFile():%s\n", gpf->relativeFilename.mb_str(wxConvUTF8).data());
}
...
}
which gives :
INF:[a1473a00]:cbProject::AddFile():../src/a.txt
INF:[a1473a00]:cbProject::AddFile():../src/a.txt
INF:[a1473a00]:cbProject::AddFile():../src/b.txt
INF:[a1473a00]:cbProject::AddFile():../src/c.txt
INF:[a1473a00]:cbProject::AddFile():../src/a.txt
INF:[a1473a00]:cbProject::AddFile():../src/b.txt
INF:[a1473a00]:cbProject::AddFile():../src/c.txt
INF:[a1473a00]:cbProject::AddFile():../src/d.txt
INF:[a1473a00]:cbProject::AddFile():../src/a.txt
INF:[a1473a00]:cbProject::AddFile():../src/b.txt
...
INF:[a1473a00]:cbProject::AddFile():../src/c.txt
INF:[a1473a00]:cbProject::AddFile():../src/d.txt
INF:[a1473a00]:cbProject::AddFile():../src/g.txt
INF:[a1473a00]:cbProject::AddFile():../src/i.txt
INF:[a1473a00]:cbProject::AddFile():../src/a.txt
INF:[a1473a00]:cbProject::AddFile():../src/f.txt
INF:[a1473a00]:cbProject::AddFile():../src/h.txt
INF:[a1473a00]:cbProject::AddFile():../src/b.txt
INF:[a1473a00]:cbProject::AddFile():../src/e.txt
II) Then ProjectManagerUI::BuildProjectTree() is called,
void ProjectManagerUI::BuildProjectTree(cbProject* project, cbTreeCtrl* tree, const wxTreeItemId& root, int ptvs, FilesGroupsAndMasks* fgam)
{
...
// iterate all project files and add them to the tree
...
// add file in the tree
pf->SetTreeItemId(ProjectAddTreeNode(project, tree, nodetext, parentNode, useFolders, folders_kind,
pf->compile, (int)pf->GetFileState(), ftd));
which iterates as I did for dumping m_Files
III) At each iteration, ProjectAddTreeNode()@projectmanagerui.cpp is called :
wxTreeItemId
ProjectAddTreeNode(cbProject* project, wxTreeCtrl* tree, const wxString& text, const wxTreeItemId& parent,
bool useFolders, FileTreeData::FileTreeDataKind folders_kind, bool compiles, int image,
FileTreeData* data)
{
...
int pos = path.Find(_T('/'));
if (pos == -1)
pos = path.Find(_T('\\'));
if (useFolders && pos >= 0)
{
....
}
else
{
ret = tree->AppendItem(parent, text, image, image, data); // (L1)
...
}
which always ends up, for simple filenames, ( that does not contain any path separator ) at the line (L1) by appending an item - so adding it at the end of "tree".
So no sorting is apparently performed anywhere.
I suppose it is the same bug when moving files across ( virtual or not ) folders.
Please consider, in projectmanagerui.cpp :
wxTreeItemId
ProjectAddTreeNode(cbProject* project, wxTreeCtrl* tree, const wxString& text, const wxTreeItemId& parent,
bool useFolders, FileTreeData::FileTreeDataKind folders_kind, bool compiles, int image,
FileTreeData* data)
{
...
int pos = path.Find(_T('/'));
if (pos == -1)
pos = path.Find(_T('\\'));
if (useFolders && pos >= 0)
{
....
}
else
{
ret = tree->AppendItem(parent, text, image, image, data); // (L1)
...
}
at line (L1), replacing AppendItem(...) by InsertItem(...) ( call to ProjectFindNodeToInsertAfter(...) needed )
That resolves the bug, but I cant figure out what it can breaks elsewhere.
trunk@svn10640 - ProjectTreeSortChildrenRecursive()@ProjectManagerUI.cpp : remove the red part and it is ok
static void ProjectTreeSortChildrenRecursive(cbTreeCtrl* tree, const wxTreeItemId& parent)
{
wxTreeItemIdValue cookie = nullptr;
tree->SortChildren(parent);
wxTreeItemId current = tree->GetFirstChild(parent, cookie);
while (current && tree->ItemHasChildren(current))
{
ProjectTreeSortChildrenRecursive(tree, current);
current = tree->GetNextChild(parent, cookie);
}
}
It breaks the recursion traveling ; current may not have children, but may have brothers :
while (...) loop :
current ( = first child )
|
+------------------------------------+
| |
has children dont have children
| |
v v
- recursion on current's children - missing loop on current's brothers
- loop on current's brothers
You may put the optimization test on 'sterile' nodes inside the while (...) loop. Or code a recurse process differently.
Here it is, I did
diff -au projectmanagerui.cpp@10648 projectmanagerui.cpp@earlgrey > projectmanagerui.cpp.patch
so you patch with
patch projectmanagerui.cpp projectmanagerui.cpp.patch
I :
* added an optimization at method begin
* moved the misplaced original one.
-> bye bye, bug :)
Here it is
$ cd codeblocks-code
$ svn diff > projectmanagerui.cpp@10668.svn-diff.patch