On 16.04.2012 14:27, Koen Deforche wrote:
> Hey Stefan,
>
> Op 10 april 2012 16:47 heeft Stefan Ruppert<[email protected]> het
> volgende geschreven:
>> Hi all,
>>
>> I managed to use the WTreeView to load thousands and more tree items
>> from our database. It works fine, but sometimes when I select a new tree
>> which will remove the complete old large tree within the WTreeView it
>> crashes or asserts.
>>
>> Currently I got the following assert(). I'm using the latest Wt 3.2.1
>> release.
>>
>> myarmbrowser.wt: /home/ruppert/work/wt/wt-3.2.1/src/Wt/WTreeView.C:1899:
>> void Wt::WTreeView::modelRowsInserted(const Wt::WModelIndex&, int, int):
>> Assertion `n' failed.
>> Abgebrochen (Speicherabzug geschrieben)
>>
>> I have a complete call stack, it seems to crash within endInsertRows()
>> signal processing. For small trees (less than 1000 items) I never
>> noticed a crash.
>>
>> Maybe I'll try to limit the tree, but whats the number of items which
>> can be handled correctly?
>
> Obviously, any number should be handled correctly (limited by a CSS
> limitation w.r.t. maximum height of a widget, actually).
>
> The assertion suggests a genuine bug -- could you suggest how we can
> reproduce it here, preferably with a test case ?
>
> Regards,
> koen
Hi Koen,
today I had some time to debug the crashes with large tree views. In
fact I think I have found a serious bug within WStandardItem class.
Currently I'm using a WStandardItemModel which is populated with a huge
tree. The I use a WSortFilterProxyModel model to support filtering and
sorting on that tree. Now whenever a new tree is loaded the old tree is
removed be calling removeRows() on the source model. This will result in
calling WStandardItem::removeRows() method. And here is a bug during
removing rows in conjunction with a WSortFilterProxyModel:
void WStandardItem::removeRows(int row, int count)
{
if (model_)
model_->beginRemoveRows(index(), row, row + count - 1);
for (int i = 0; i < columnCount(); ++i) {
Column& c = (*columns_)[i];
for (int j = 0; j < count; ++j)
delete c[row + j];
c.erase(c.begin() + row, c.begin() + row + count);
}
renumberRows(row);
if (model_)
model_->endRemoveRows();
}
Here all removed items are deleted before the endRemoveRows() signal is
emitted. But within the endRemoveRows() signal the WSortFilterProxyModel
removes its source WModelIndex instance which in turn will use the
deleted WStandardItem instances!!!
Here is a change which works for me:
void WStandardItem::removeRows(int row, int count)
{
if (model_)
model_->beginRemoveRows(index(), row, row + count - 1);
Column eraseColumns;
for (int i = 0; i < columnCount(); ++i) {
Column& c = (*columns_)[i];
for (int j = 0; j < count; ++j)
eraseColumns.push_back(c[row + j]);
c.erase(c.begin() + row, c.begin() + row + count);
}
renumberRows(row);
if (model_)
model_->endRemoveRows();
for (int i = 0; i < eraseColumns.size(); ++i)
delete eraseColumns[i];
}
Regards,
Stefan
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
witty-interest mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/witty-interest