ladybird/Userland/Libraries/LibGUI/ProcessChooser.cpp
sin-ack 9c9a5c55cb Userland+LibGUI: Make Margins arguments match CSS ordering
Previously the argument order for Margins was (left, top, right,
bottom). To make it more familiar and closer to how CSS does it, the
argument order is now (top, right, bottom, left).
2021-08-18 10:30:50 +02:00

112 lines
3.9 KiB
C++

/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Button.h>
#include <LibGUI/MessageBox.h>
#include <LibGUI/ProcessChooser.h>
#include <LibGUI/RunningProcessesModel.h>
#include <LibGUI/SortingProxyModel.h>
#include <LibGUI/TableView.h>
namespace GUI {
ProcessChooser::ProcessChooser(const StringView& window_title, const StringView& button_label, const Gfx::Bitmap* window_icon, GUI::Window* parent_window)
: Dialog(parent_window)
, m_window_title(window_title)
, m_button_label(button_label)
, m_window_icon(window_icon)
{
set_title(m_window_title);
if (m_window_icon)
set_icon(m_window_icon);
else if (parent_window)
set_icon(parent_window->icon());
resize(300, 340);
center_on_screen();
auto& widget = set_main_widget<GUI::Widget>();
widget.set_fill_with_background_color(true);
widget.set_layout<GUI::VerticalBoxLayout>();
m_table_view = widget.add<GUI::TableView>();
auto process_model = RunningProcessesModel::create();
auto sorting_model = GUI::SortingProxyModel::create(process_model);
sorting_model->set_sort_role(GUI::ModelRole::Display);
m_table_view->set_model(sorting_model);
m_table_view->set_key_column_and_sort_order(RunningProcessesModel::Column::PID, GUI::SortOrder::Descending);
m_process_model = process_model;
m_table_view->on_activation = [this](const ModelIndex& index) { set_pid_from_index_and_close(index); };
auto& button_container = widget.add<GUI::Widget>();
button_container.set_fixed_height(30);
button_container.set_layout<GUI::HorizontalBoxLayout>();
button_container.set_content_margins({ 4, 0, 4, 0 });
button_container.layout()->set_margins({ 0, 4, 0, 0 });
button_container.layout()->add_spacer();
auto& select_button = button_container.add<GUI::Button>(m_button_label);
select_button.set_fixed_width(80);
select_button.on_click = [this](auto) {
if (m_table_view->selection().is_empty()) {
GUI::MessageBox::show(this, "No process selected!", m_window_title, GUI::MessageBox::Type::Error);
return;
}
auto index = m_table_view->selection().first();
set_pid_from_index_and_close(index);
};
auto& cancel_button = button_container.add<GUI::Button>("Cancel");
cancel_button.set_fixed_width(80);
cancel_button.on_click = [this](auto) {
done(ExecCancel);
};
m_process_model->update();
m_refresh_timer = add<Core::Timer>();
m_refresh_timer->start(m_refresh_interval); // Start the timer to update the processes
m_refresh_timer->on_timeout = [this] {
auto previous_selected_pid = -1; // Store the selection index to not to clear the selection upon update.
if (!m_table_view->selection().is_empty()) {
auto pid_as_variant = m_table_view->selection().first().data(GUI::ModelRole::Custom);
previous_selected_pid = pid_as_variant.as_i32();
}
m_process_model->update();
if (previous_selected_pid == -1) {
return;
}
auto model = m_table_view->model();
auto row_count = model->row_count();
auto column_index = 1; // Corresponds to PID column in the m_table_view.
for (int row_index = 0; row_index < row_count; ++row_index) {
auto cell_index = model->index(row_index, column_index);
auto pid_as_variant = cell_index.data(GUI::ModelRole::Custom);
if (previous_selected_pid == pid_as_variant.as_i32()) {
m_table_view->selection().set(cell_index); // Set only if PIDs are matched.
}
}
};
}
void ProcessChooser::set_pid_from_index_and_close(const ModelIndex& index)
{
m_pid = index.data(GUI::ModelRole::Custom).as_i32();
done(ExecOK);
}
ProcessChooser::~ProcessChooser()
{
}
}