mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 02:39:28 +00:00
C++: Fix and test the reset
function on model adapter
They were causing infinite recursion because they were calling themselves. Also add the missing MapModel::reset Yet another motivation for https://github.com/slint-ui/slint/issues/3888 as the code was mixing the `reset` function on the adapter meaning "please re-apply the adapter filter/map/sort function" with the `reset` function on Model which means "the subclass has changed and we should notify listeners". Fixes #4968
This commit is contained in:
parent
dc5004f9c4
commit
fe38a1e97d
2 changed files with 100 additions and 5 deletions
|
@ -632,7 +632,7 @@ struct FilterModelInner : private_api::ModelChangeListener
|
|||
void reset() override
|
||||
{
|
||||
update_mapping();
|
||||
target_model.reset();
|
||||
target_model.Model<ModelData>::reset();
|
||||
}
|
||||
|
||||
void update_mapping()
|
||||
|
@ -721,7 +721,7 @@ struct MapModelInner : private_api::ModelChangeListener
|
|||
{
|
||||
target_model.row_removed(index, count);
|
||||
}
|
||||
void reset() override { target_model.reset(); }
|
||||
void reset() override { target_model.Model<SourceModelData>::reset(); }
|
||||
|
||||
slint::MapModel<SourceModelData, MappedModelData> &target_model;
|
||||
};
|
||||
|
@ -767,6 +767,10 @@ public:
|
|||
/// Returns the source model of this filter model.
|
||||
std::shared_ptr<Model<SourceModelData>> source_model() const { return model; }
|
||||
|
||||
/// Re-applies the model's mapping function on each row of the source model. Use this if state
|
||||
/// external to the mapping function has changed.
|
||||
void reset() { inner->reset(); }
|
||||
|
||||
private:
|
||||
std::shared_ptr<private_api::MapModelInner<SourceModelData, MappedModelData>> inner;
|
||||
std::shared_ptr<slint::Model<SourceModelData>> model;
|
||||
|
@ -874,7 +878,7 @@ struct SortModelInner : private_api::ModelChangeListener
|
|||
void reset() override
|
||||
{
|
||||
sorted_rows_dirty = true;
|
||||
target_model.reset();
|
||||
target_model.Model<ModelData>::reset();
|
||||
}
|
||||
|
||||
void ensure_sorted()
|
||||
|
@ -987,7 +991,7 @@ struct ReverseModelInner : private_api::ModelChangeListener
|
|||
target_model.row_removed(source_model->row_count() - first_removed_row, count);
|
||||
}
|
||||
|
||||
void reset() override { source_model.reset(); }
|
||||
void reset() override { target_model.reset(); }
|
||||
|
||||
std::shared_ptr<slint::Model<ModelData>> source_model;
|
||||
slint::ReverseModel<ModelData> &target_model;
|
||||
|
|
|
@ -221,12 +221,47 @@ SCENARIO("Filtering Model Remove")
|
|||
REQUIRE(even_rows->row_data(1) == 4);
|
||||
}
|
||||
|
||||
SCENARIO("Filtering Model Reset")
|
||||
{
|
||||
auto vec_model =
|
||||
std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4, 5, 6 });
|
||||
|
||||
bool even = true;
|
||||
|
||||
auto even_rows = std::make_shared<slint::FilterModel<int>>(
|
||||
vec_model, [&even](auto value) { return value % 2 == !even; });
|
||||
|
||||
auto observer = std::make_shared<ModelObserver>();
|
||||
even_rows->attach_peer(observer);
|
||||
|
||||
REQUIRE(even_rows->row_count() == 3);
|
||||
REQUIRE(even_rows->row_data(0) == 2);
|
||||
REQUIRE(even_rows->row_data(1) == 4);
|
||||
REQUIRE(even_rows->row_data(2) == 6);
|
||||
|
||||
even = false;
|
||||
even_rows->reset();
|
||||
|
||||
REQUIRE(observer->added_rows.empty());
|
||||
REQUIRE(observer->changed_rows.empty());
|
||||
REQUIRE(observer->removed_rows.empty());
|
||||
REQUIRE(observer->model_reset);
|
||||
observer->clear();
|
||||
|
||||
REQUIRE(even_rows->row_count() == 3);
|
||||
REQUIRE(even_rows->row_data(0) == 1);
|
||||
REQUIRE(even_rows->row_data(1) == 3);
|
||||
REQUIRE(even_rows->row_data(2) == 5);
|
||||
}
|
||||
|
||||
SCENARIO("Mapped Model")
|
||||
{
|
||||
auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4 });
|
||||
|
||||
int to_add = 1;
|
||||
|
||||
auto plus_one_model = std::make_shared<slint::MapModel<int, int>>(
|
||||
vec_model, [](auto value) { return value + 1; });
|
||||
vec_model, [&to_add](auto value) { return value + to_add; });
|
||||
|
||||
auto observer = std::make_shared<ModelObserver>();
|
||||
plus_one_model->attach_peer(observer);
|
||||
|
@ -283,6 +318,21 @@ SCENARIO("Mapped Model")
|
|||
REQUIRE(plus_one_model->row_data(1) == 4);
|
||||
REQUIRE(plus_one_model->row_data(2) == 3);
|
||||
REQUIRE(plus_one_model->row_data(3) == 5);
|
||||
|
||||
to_add = 51;
|
||||
plus_one_model->reset();
|
||||
|
||||
REQUIRE(observer->added_rows.empty());
|
||||
REQUIRE(observer->changed_rows.empty());
|
||||
REQUIRE(observer->removed_rows.empty());
|
||||
REQUIRE(observer->model_reset);
|
||||
observer->clear();
|
||||
|
||||
REQUIRE(plus_one_model->row_count() == 4);
|
||||
REQUIRE(plus_one_model->row_data(0) == 151);
|
||||
REQUIRE(plus_one_model->row_data(1) == 54);
|
||||
REQUIRE(plus_one_model->row_data(2) == 53);
|
||||
REQUIRE(plus_one_model->row_data(3) == 55);
|
||||
}
|
||||
|
||||
SCENARIO("Sorted Model Insert")
|
||||
|
@ -400,6 +450,38 @@ SCENARIO("Sorted Model Change")
|
|||
REQUIRE(sorted_model->row_data(3) == 3);
|
||||
}
|
||||
|
||||
SCENARIO("Sorted Model Reset")
|
||||
{
|
||||
auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
|
||||
|
||||
bool ascending = true;
|
||||
|
||||
auto sorted_model =
|
||||
std::make_shared<slint::SortModel<int>>(vec_model, [&ascending](auto lhs, auto rhs) {
|
||||
return ascending ? lhs < rhs : rhs < lhs;
|
||||
});
|
||||
|
||||
auto observer = std::make_shared<ModelObserver>();
|
||||
sorted_model->attach_peer(observer);
|
||||
|
||||
REQUIRE(sorted_model->row_count() == 4);
|
||||
REQUIRE(sorted_model->row_data(0) == 1);
|
||||
REQUIRE(sorted_model->row_data(1) == 2);
|
||||
REQUIRE(sorted_model->row_data(2) == 3);
|
||||
REQUIRE(sorted_model->row_data(3) == 4);
|
||||
|
||||
ascending = false;
|
||||
sorted_model->reset();
|
||||
|
||||
REQUIRE(sorted_model->row_count() == 4);
|
||||
REQUIRE(sorted_model->row_data(0) == 4);
|
||||
REQUIRE(sorted_model->row_data(1) == 3);
|
||||
REQUIRE(sorted_model->row_data(2) == 2);
|
||||
REQUIRE(sorted_model->row_data(3) == 1);
|
||||
|
||||
REQUIRE(observer->model_reset);
|
||||
}
|
||||
|
||||
SCENARIO("Reverse Model Insert")
|
||||
{
|
||||
auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
|
||||
|
@ -493,6 +575,15 @@ SCENARIO("Reverse Model Change")
|
|||
REQUIRE(reverse_model->row_data(1) == 1);
|
||||
REQUIRE(reverse_model->row_data(2) == 10);
|
||||
REQUIRE(reverse_model->row_data(3) == 3);
|
||||
|
||||
vec_model->clear();
|
||||
REQUIRE(observer->added_rows.empty());
|
||||
REQUIRE(observer->changed_rows.empty());
|
||||
REQUIRE(observer->removed_rows.empty());
|
||||
REQUIRE(observer->model_reset);
|
||||
observer->clear();
|
||||
|
||||
REQUIRE(reverse_model->row_count() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("VectorModel clear and replace")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue