From 46caa2663b4dd909530732a3f1ae3f293755f667 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 9 Mar 2019 14:24:34 +0100 Subject: [PATCH] LibGUI: Use a separate data role for the table model sorting order. This allows data to be displayed nicely while sorting happens based on some underlying raw data. :^) --- AK/String.cpp | 2 +- .../FileManager/DirectoryTableModel.cpp | 3 +- .../FileManager/DirectoryTableModel.h | 2 +- Applications/Launcher/main.cpp | 3 +- .../ProcessManager/ProcessTableModel.cpp | 28 ++++++++++++++++++- .../ProcessManager/ProcessTableModel.h | 2 +- Kernel/makeall.sh | 2 +- LibGUI/GSortingProxyTableModel.cpp | 8 +++--- LibGUI/GSortingProxyTableModel.h | 2 +- LibGUI/GTableModel.h | 4 ++- LibGUI/GTableView.cpp | 2 +- 11 files changed, 43 insertions(+), 15 deletions(-) diff --git a/AK/String.cpp b/AK/String.cpp index fe48dc004c..e6195700d8 100644 --- a/AK/String.cpp +++ b/AK/String.cpp @@ -27,7 +27,7 @@ bool String::operator<(const String& other) const if (!other.m_impl) return false; - return strcmp(characters(), other.characters()); + return strcmp(characters(), other.characters()) < 0; } String String::empty() diff --git a/Applications/FileManager/DirectoryTableModel.cpp b/Applications/FileManager/DirectoryTableModel.cpp index c8166ac256..c21a8a98d7 100644 --- a/Applications/FileManager/DirectoryTableModel.cpp +++ b/Applications/FileManager/DirectoryTableModel.cpp @@ -135,8 +135,9 @@ String DirectoryTableModel::name_for_gid(uid_t gid) const return (*it).value; } -GVariant DirectoryTableModel::data(const GModelIndex& index) const +GVariant DirectoryTableModel::data(const GModelIndex& index, Role role) const { + ASSERT(role == Role::Display); auto& entry = this->entry(index.row()); switch (index.column()) { case Column::Icon: return icon_for(entry); diff --git a/Applications/FileManager/DirectoryTableModel.h b/Applications/FileManager/DirectoryTableModel.h index 3926341600..a275a12c7b 100644 --- a/Applications/FileManager/DirectoryTableModel.h +++ b/Applications/FileManager/DirectoryTableModel.h @@ -24,7 +24,7 @@ public: virtual int column_count() const override; virtual String column_name(int column) const override; virtual ColumnMetadata column_metadata(int column) const override; - virtual GVariant data(const GModelIndex&) const override; + virtual GVariant data(const GModelIndex&, Role = Role::Display) const override; virtual void update() override; virtual void activate(const GModelIndex&) override; diff --git a/Applications/Launcher/main.cpp b/Applications/Launcher/main.cpp index 7710056fc6..f95b73a3a6 100644 --- a/Applications/Launcher/main.cpp +++ b/Applications/Launcher/main.cpp @@ -51,8 +51,7 @@ public: perror("execl"); } }; - } - virtual ~LauncherButton() { } + } virtual ~LauncherButton() { } private: String m_executable_path; diff --git a/Applications/ProcessManager/ProcessTableModel.cpp b/Applications/ProcessManager/ProcessTableModel.cpp index fbf530d737..ab736006c4 100644 --- a/Applications/ProcessManager/ProcessTableModel.cpp +++ b/Applications/ProcessManager/ProcessTableModel.cpp @@ -67,11 +67,37 @@ static String pretty_byte_size(size_t size) return String::format("%uK", size / 1024); } -GVariant ProcessTableModel::data(const GModelIndex& index) const +GVariant ProcessTableModel::data(const GModelIndex& index, Role role) const { ASSERT(is_valid(index)); + auto it = m_processes.find(m_pids[index.row()]); auto& process = *(*it).value; + + if (role == Role::Sort) { + switch (index.column()) { + case Column::Icon: return 0; + case Column::PID: return process.current_state.pid; + case Column::State: return process.current_state.state; + case Column::User: return process.current_state.user; + case Column::Priority: + if (process.current_state.priority == "Low") + return 0; + if (process.current_state.priority == "Normal") + return 1; + if (process.current_state.priority == "High") + return 2; + ASSERT_NOT_REACHED(); + return 3; + case Column::Linear: return (int)process.current_state.linear; + case Column::Physical: return (int)process.current_state.physical; + case Column::CPU: return process.current_state.cpu_percent; + case Column::Name: return process.current_state.name; + } + ASSERT_NOT_REACHED(); + return { }; + } + switch (index.column()) { case Column::Icon: return *m_generic_process_icon; case Column::PID: return process.current_state.pid; diff --git a/Applications/ProcessManager/ProcessTableModel.h b/Applications/ProcessManager/ProcessTableModel.h index 6b5d9af65b..ced17f0b7f 100644 --- a/Applications/ProcessManager/ProcessTableModel.h +++ b/Applications/ProcessManager/ProcessTableModel.h @@ -28,7 +28,7 @@ public: virtual int column_count() const override; virtual String column_name(int column) const override; virtual ColumnMetadata column_metadata(int column) const override; - virtual GVariant data(const GModelIndex&) const override; + virtual GVariant data(const GModelIndex&, Role = Role::Display) const override; virtual void update() override; pid_t selected_pid() const; diff --git a/Kernel/makeall.sh b/Kernel/makeall.sh index 2448f50a1e..5dd7f8c756 100755 --- a/Kernel/makeall.sh +++ b/Kernel/makeall.sh @@ -2,7 +2,7 @@ sudo id -make_cmd="make -j2" +make_cmd="make -j3" $make_cmd -C ../LibC clean && \ $make_cmd -C ../LibC && \ diff --git a/LibGUI/GSortingProxyTableModel.cpp b/LibGUI/GSortingProxyTableModel.cpp index 2c02e123e2..8eb9846b3f 100644 --- a/LibGUI/GSortingProxyTableModel.cpp +++ b/LibGUI/GSortingProxyTableModel.cpp @@ -54,9 +54,9 @@ GTableModel::ColumnMetadata GSortingProxyTableModel::column_metadata(int index) return target().column_metadata(index); } -GVariant GSortingProxyTableModel::data(const GModelIndex& index) const +GVariant GSortingProxyTableModel::data(const GModelIndex& index, Role role) const { - return target().data(map_to_target(index)); + return target().data(map_to_target(index), role); } void GSortingProxyTableModel::activate(const GModelIndex& index) @@ -102,8 +102,8 @@ void GSortingProxyTableModel::resort() auto& context = *(Context*)(ctx); GModelIndex index1 { row1, context.key_column }; GModelIndex index2 { row2, context.key_column }; - auto data1 = context.target->data(index1); - auto data2 = context.target->data(index2); + auto data1 = context.target->data(index1, GTableModel::Role::Sort); + auto data2 = context.target->data(index2, GTableModel::Role::Sort); if (data1 == data2) return 0; bool is_less_than = data1 < data2; diff --git a/LibGUI/GSortingProxyTableModel.h b/LibGUI/GSortingProxyTableModel.h index a920edddde..429ca91e62 100644 --- a/LibGUI/GSortingProxyTableModel.h +++ b/LibGUI/GSortingProxyTableModel.h @@ -12,7 +12,7 @@ public: virtual String row_name(int) const override; virtual String column_name(int) const override; virtual ColumnMetadata column_metadata(int) const override; - virtual GVariant data(const GModelIndex&) const override; + virtual GVariant data(const GModelIndex&, Role = Role::Display) const override; virtual void update() override; virtual void activate(const GModelIndex&) override; diff --git a/LibGUI/GTableModel.h b/LibGUI/GTableModel.h index 517e682b11..baae6c4eff 100644 --- a/LibGUI/GTableModel.h +++ b/LibGUI/GTableModel.h @@ -40,6 +40,8 @@ public: TextAlignment text_alignment { TextAlignment::CenterLeft }; }; + enum class Role { Display, Sort, Custom }; + virtual ~GTableModel(); virtual int row_count() const = 0; @@ -47,7 +49,7 @@ public: virtual String row_name(int) const { return { }; } virtual String column_name(int) const { return { }; } virtual ColumnMetadata column_metadata(int) const { return { }; } - virtual GVariant data(const GModelIndex&) const = 0; + virtual GVariant data(const GModelIndex&, Role = Role::Display) const = 0; virtual void update() = 0; virtual void activate(const GModelIndex&) { } diff --git a/LibGUI/GTableView.cpp b/LibGUI/GTableView.cpp index f9363b720e..7d37718327 100644 --- a/LibGUI/GTableView.cpp +++ b/LibGUI/GTableView.cpp @@ -108,7 +108,7 @@ void GTableView::mousedown_event(GMouseEvent& event) for (int i = 0; i < m_model->column_count(); ++i) { auto header_rect = this->header_rect(i); if (header_rect.contains(adjusted_position)) { - auto new_sort_order = GSortOrder::Descending; + auto new_sort_order = GSortOrder::Ascending; if (m_model->key_column() == i) new_sort_order = m_model->sort_order() == GSortOrder::Ascending ? GSortOrder::Descending : GSortOrder::Ascending; m_model->set_key_column_and_sort_order(i, new_sort_order);