How to iterate over wxDataViewTreeCtrl items and serialize them to a file?
by apoorv569 from LinuxQuestions.org on (#5E67A)
I have a application that I'm making with wxWidgets which plays audio samples and helps organize them. I have a wxDataViewListCtrl which has several column which holds information about the audio file like filename, path, length, sample rate and all, it also has a toggle column, that when clicked, should add that item to wxDataViewTreeCtrl, and remove when toggled off. I have the wxDataViewTreeCtrl setup as,
Code: CollectionView = new wxDataViewTreeCtrl(ViewChoice, BCID_CollectionView, wxDefaultPosition, wxDefaultSize, wxDV_NO_HEADER);And I added a root node to begin with,
Code: wxDataViewItem RootNode = CollectionView->AppendContainer(wxDataViewItem(0), "ROOT", 0);And this function should add that item to wxDataViewTreeCtrl, SampleListView is wxDataViewListCtrl here,
Code:void Browser::OnCheckFavorite(wxDataViewEvent& event)
{
// int selectedRow = SampleListView->GetSelectedRow();
int selectedRow = SampleListView->ItemToRow(event.GetItem());
if (selectedRow < 0) return;
wxString Selection = SampleListView->GetTextValue(selectedRow, 1);
std::deque<wxDataViewItem> nodes;
nodes.push_back(RootNode);
wxDataViewItem foundItem;
if (SampleListView->GetToggleValue(selectedRow, 0))
{
wxLogDebug("Toggle on");
while(!nodes.empty())
{
wxDataViewItem currentItem = nodes.front();
nodes.pop_front();
if ( CollectionView->GetItemText(currentItem) == Selection )
{
foundItem = currentItem;
wxLogDebug(CollectionView->GetItemText(currentItem));
wxLogDebug("Toggle selection: %s", CollectionView->GetItemText(CollectionView->GetSelection()));
break;
}
int row = 0;
wxDataViewItem child = CollectionView->GetNthChild(currentItem, row);
while ( child.IsOk() )
{
nodes.push_back(child);
child = CollectionView->GetNthChild(currentItem, row + 1);
row ++;
}
}
nodes.clear();
if (foundItem.IsOk())
{
const wxString& msg = wxString::Format("%s already added as favorite. Skipping..", Selection);
wxMessageDialog *msgDialog = new wxMessageDialog(NULL, msg, "Info", wxOK | wxICON_INFORMATION);
msgDialog->ShowModal();
}
else
{
wxLogDebug("Sample not found adding as fav.");
wxDataViewItem selected = CollectionView->GetSelection();
wxString folder = CollectionView->GetItemText(selected);
wxLogDebug("Selected: %s", folder);
CollectionView->AppendItem(RootNode, Selection);
std::string path = "/home/apoorv/repos/cpp-projects/wxWidgets/SampleBrowser/tree.yaml";
serialize.SerializeDataViewTreeCtrlItems(path, *CollectionView, RootNode);
db.UpdateFavoriteColumn(Selection.ToStdString(), 1);
// db.UpdateFavoriteFolderDatabase(Selection.ToStdString(), folder.ToStdString());
}
}And this code is responsible for serializing the tree items to a yaml file, so I save and load the data back to the application,
Code:void Serializer::SerializeDataViewTreeCtrlItems(std::string filepath, wxDataViewTreeCtrl& tree, wxDataViewItem& item)
{
std::ifstream ifin(filepath);
YAML::Emitter out;
out << YAML::BeginMap; // Container
out << YAML::Key << "Container" << YAML::Value << "";
if (!tree.IsContainer(item))
{
out << YAML::Key << "Child";
out << YAML::BeginMap; // Child
for ( int i = 0; i < tree.GetChildCount(item); i++ )
{
wxString child = tree.GetItemText(tree.GetNthChild(item, i));
out << YAML::Key << "Item" << YAML::Value << child.ToStdString();
}
out << YAML::EndMap; // Child
}
out << YAML::EndMap; // Container
std::ofstream ofout(filepath);
ofout << out.c_str();
}But running this code keeps giving me error about invalid index and nothing gets output to the yaml file,
Code:./src/common/list.cpp(317): assert "Assert failure" failed in Item(): invalid index in wxListBase::ItemWhat am I doing wrong here?


Code: CollectionView = new wxDataViewTreeCtrl(ViewChoice, BCID_CollectionView, wxDefaultPosition, wxDefaultSize, wxDV_NO_HEADER);And I added a root node to begin with,
Code: wxDataViewItem RootNode = CollectionView->AppendContainer(wxDataViewItem(0), "ROOT", 0);And this function should add that item to wxDataViewTreeCtrl, SampleListView is wxDataViewListCtrl here,
Code:void Browser::OnCheckFavorite(wxDataViewEvent& event)
{
// int selectedRow = SampleListView->GetSelectedRow();
int selectedRow = SampleListView->ItemToRow(event.GetItem());
if (selectedRow < 0) return;
wxString Selection = SampleListView->GetTextValue(selectedRow, 1);
std::deque<wxDataViewItem> nodes;
nodes.push_back(RootNode);
wxDataViewItem foundItem;
if (SampleListView->GetToggleValue(selectedRow, 0))
{
wxLogDebug("Toggle on");
while(!nodes.empty())
{
wxDataViewItem currentItem = nodes.front();
nodes.pop_front();
if ( CollectionView->GetItemText(currentItem) == Selection )
{
foundItem = currentItem;
wxLogDebug(CollectionView->GetItemText(currentItem));
wxLogDebug("Toggle selection: %s", CollectionView->GetItemText(CollectionView->GetSelection()));
break;
}
int row = 0;
wxDataViewItem child = CollectionView->GetNthChild(currentItem, row);
while ( child.IsOk() )
{
nodes.push_back(child);
child = CollectionView->GetNthChild(currentItem, row + 1);
row ++;
}
}
nodes.clear();
if (foundItem.IsOk())
{
const wxString& msg = wxString::Format("%s already added as favorite. Skipping..", Selection);
wxMessageDialog *msgDialog = new wxMessageDialog(NULL, msg, "Info", wxOK | wxICON_INFORMATION);
msgDialog->ShowModal();
}
else
{
wxLogDebug("Sample not found adding as fav.");
wxDataViewItem selected = CollectionView->GetSelection();
wxString folder = CollectionView->GetItemText(selected);
wxLogDebug("Selected: %s", folder);
CollectionView->AppendItem(RootNode, Selection);
std::string path = "/home/apoorv/repos/cpp-projects/wxWidgets/SampleBrowser/tree.yaml";
serialize.SerializeDataViewTreeCtrlItems(path, *CollectionView, RootNode);
db.UpdateFavoriteColumn(Selection.ToStdString(), 1);
// db.UpdateFavoriteFolderDatabase(Selection.ToStdString(), folder.ToStdString());
}
}And this code is responsible for serializing the tree items to a yaml file, so I save and load the data back to the application,
Code:void Serializer::SerializeDataViewTreeCtrlItems(std::string filepath, wxDataViewTreeCtrl& tree, wxDataViewItem& item)
{
std::ifstream ifin(filepath);
YAML::Emitter out;
out << YAML::BeginMap; // Container
out << YAML::Key << "Container" << YAML::Value << "";
if (!tree.IsContainer(item))
{
out << YAML::Key << "Child";
out << YAML::BeginMap; // Child
for ( int i = 0; i < tree.GetChildCount(item); i++ )
{
wxString child = tree.GetItemText(tree.GetNthChild(item, i));
out << YAML::Key << "Item" << YAML::Value << child.ToStdString();
}
out << YAML::EndMap; // Child
}
out << YAML::EndMap; // Container
std::ofstream ofout(filepath);
ofout << out.c_str();
}But running this code keeps giving me error about invalid index and nothing gets output to the yaml file,
Code:./src/common/list.cpp(317): assert "Assert failure" failed in Item(): invalid index in wxListBase::ItemWhat am I doing wrong here?