GSortingProxyModel.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include <AK/QuickSort.h>
  2. #include <LibGUI/GAbstractView.h>
  3. #include <LibGUI/GSortingProxyModel.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. GSortingProxyModel::GSortingProxyModel(NonnullRefPtr<GModel>&& target)
  7. : m_target(move(target))
  8. , m_key_column(-1)
  9. {
  10. m_target->on_update = [this] {
  11. resort();
  12. };
  13. }
  14. GSortingProxyModel::~GSortingProxyModel()
  15. {
  16. }
  17. int GSortingProxyModel::row_count(const GModelIndex& index) const
  18. {
  19. return target().row_count(index);
  20. }
  21. int GSortingProxyModel::column_count(const GModelIndex& index) const
  22. {
  23. return target().column_count(index);
  24. }
  25. GModelIndex GSortingProxyModel::map_to_target(const GModelIndex& index) const
  26. {
  27. if (!index.is_valid())
  28. return {};
  29. if (index.row() >= m_row_mappings.size() || index.column() >= column_count())
  30. return {};
  31. return target().index(m_row_mappings[index.row()], index.column());
  32. }
  33. String GSortingProxyModel::row_name(int index) const
  34. {
  35. return target().row_name(index);
  36. }
  37. String GSortingProxyModel::column_name(int index) const
  38. {
  39. return target().column_name(index);
  40. }
  41. GModel::ColumnMetadata GSortingProxyModel::column_metadata(int index) const
  42. {
  43. return target().column_metadata(index);
  44. }
  45. GVariant GSortingProxyModel::data(const GModelIndex& index, Role role) const
  46. {
  47. return target().data(map_to_target(index), role);
  48. }
  49. void GSortingProxyModel::update()
  50. {
  51. target().update();
  52. }
  53. void GSortingProxyModel::set_key_column_and_sort_order(int column, GSortOrder sort_order)
  54. {
  55. if (column == m_key_column && sort_order == m_sort_order)
  56. return;
  57. ASSERT(column >= 0 && column < column_count());
  58. m_key_column = column;
  59. m_sort_order = sort_order;
  60. resort();
  61. }
  62. void GSortingProxyModel::resort()
  63. {
  64. auto old_row_mappings = m_row_mappings;
  65. int row_count = target().row_count();
  66. m_row_mappings.resize(row_count);
  67. for (int i = 0; i < row_count; ++i)
  68. m_row_mappings[i] = i;
  69. if (m_key_column == -1) {
  70. did_update();
  71. return;
  72. }
  73. quick_sort(m_row_mappings.begin(), m_row_mappings.end(), [&](auto row1, auto row2) -> bool {
  74. auto data1 = target().data(target().index(row1, m_key_column), GModel::Role::Sort);
  75. auto data2 = target().data(target().index(row2, m_key_column), GModel::Role::Sort);
  76. if (data1 == data2)
  77. return 0;
  78. bool is_less_than;
  79. if (data1.is_string() && data2.is_string() && !m_sorting_case_sensitive)
  80. is_less_than = data1.as_string().to_lowercase() < data2.as_string().to_lowercase();
  81. else
  82. is_less_than = data1 < data2;
  83. return m_sort_order == GSortOrder::Ascending ? is_less_than : !is_less_than;
  84. });
  85. did_update();
  86. for_each_view([&](GAbstractView& view) {
  87. auto& selection = view.selection();
  88. Vector<GModelIndex> selected_indexes_in_target;
  89. selection.for_each_index([&](const GModelIndex& index) {
  90. selected_indexes_in_target.append(target().index(old_row_mappings[index.row()], index.column()));
  91. });
  92. selection.clear();
  93. for (auto& index : selected_indexes_in_target) {
  94. for (int i = 0; i < m_row_mappings.size(); ++i) {
  95. if (m_row_mappings[i] == index.row()) {
  96. selection.add(this->index(i, index.column()));
  97. continue;
  98. }
  99. }
  100. }
  101. });
  102. }