mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-25 14:05:15 +00:00
This breaks GSortingProxyModel selection preservation across resorts. I'm not yet sure how we're going to solve that, but it's going to have to work a bit differently than before, since the model itself no longer knows what's selected. Selection is now managed by GModelSelection which allows us to select any arbitrary number of items, and to have different selections in different views onto the same model. Pretty sweet. :^)
97 lines
2.6 KiB
C++
97 lines
2.6 KiB
C++
#include <AK/QuickSort.h>
|
|
#include <LibGUI/GSortingProxyModel.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
GSortingProxyModel::GSortingProxyModel(NonnullRefPtr<GModel>&& target)
|
|
: m_target(move(target))
|
|
, m_key_column(-1)
|
|
{
|
|
m_target->on_update = [this] {
|
|
resort();
|
|
};
|
|
}
|
|
|
|
GSortingProxyModel::~GSortingProxyModel()
|
|
{
|
|
}
|
|
|
|
int GSortingProxyModel::row_count(const GModelIndex& index) const
|
|
{
|
|
return target().row_count(index);
|
|
}
|
|
|
|
int GSortingProxyModel::column_count(const GModelIndex& index) const
|
|
{
|
|
return target().column_count(index);
|
|
}
|
|
|
|
GModelIndex GSortingProxyModel::map_to_target(const GModelIndex& index) const
|
|
{
|
|
if (!index.is_valid())
|
|
return {};
|
|
if (index.row() >= m_row_mappings.size() || index.column() >= column_count())
|
|
return {};
|
|
return target().index(m_row_mappings[index.row()], index.column());
|
|
}
|
|
|
|
String GSortingProxyModel::row_name(int index) const
|
|
{
|
|
return target().row_name(index);
|
|
}
|
|
|
|
String GSortingProxyModel::column_name(int index) const
|
|
{
|
|
return target().column_name(index);
|
|
}
|
|
|
|
GModel::ColumnMetadata GSortingProxyModel::column_metadata(int index) const
|
|
{
|
|
return target().column_metadata(index);
|
|
}
|
|
|
|
GVariant GSortingProxyModel::data(const GModelIndex& index, Role role) const
|
|
{
|
|
return target().data(map_to_target(index), role);
|
|
}
|
|
|
|
void GSortingProxyModel::update()
|
|
{
|
|
target().update();
|
|
}
|
|
|
|
void GSortingProxyModel::set_key_column_and_sort_order(int column, GSortOrder sort_order)
|
|
{
|
|
if (column == m_key_column && sort_order == m_sort_order)
|
|
return;
|
|
|
|
ASSERT(column >= 0 && column < column_count());
|
|
m_key_column = column;
|
|
m_sort_order = sort_order;
|
|
resort();
|
|
}
|
|
|
|
void GSortingProxyModel::resort()
|
|
{
|
|
int row_count = target().row_count();
|
|
m_row_mappings.resize(row_count);
|
|
for (int i = 0; i < row_count; ++i)
|
|
m_row_mappings[i] = i;
|
|
if (m_key_column == -1) {
|
|
did_update();
|
|
return;
|
|
}
|
|
quick_sort(m_row_mappings.begin(), m_row_mappings.end(), [&](auto row1, auto row2) -> bool {
|
|
auto data1 = target().data(target().index(row1, m_key_column), GModel::Role::Sort);
|
|
auto data2 = target().data(target().index(row2, m_key_column), GModel::Role::Sort);
|
|
if (data1 == data2)
|
|
return 0;
|
|
bool is_less_than;
|
|
if (data1.is_string() && data2.is_string() && !m_sorting_case_sensitive)
|
|
is_less_than = data1.as_string().to_lowercase() < data2.as_string().to_lowercase();
|
|
else
|
|
is_less_than = data1 < data2;
|
|
return m_sort_order == GSortOrder::Ascending ? is_less_than : !is_less_than;
|
|
});
|
|
did_update();
|
|
}
|