diff options
Diffstat (limited to 'src/prefsdialog.cpp')
-rw-r--r-- | src/prefsdialog.cpp | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/src/prefsdialog.cpp b/src/prefsdialog.cpp new file mode 100644 index 0000000..39ca384 --- /dev/null +++ b/src/prefsdialog.cpp @@ -0,0 +1,361 @@ +/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include <config.h> + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include "prefsdialog.h" + +#include "cgroups.h" +#include "proctable.h" +#include "selinux.h" +#include "settings-keys.h" +#include "systemd.h" +#include "util.h" + +static HdyPreferencesWindow *prefs_dialog = NULL; + +static gboolean +prefs_dialog_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data) +{ + prefs_dialog = NULL; + return FALSE; +} + +class SpinButtonUpdater +{ +public: + SpinButtonUpdater(const string& key) + : key(key) + { } + + static gboolean callback(GtkWidget *widget, GdkEventFocus *event, gpointer data) + { + SpinButtonUpdater* updater = static_cast<SpinButtonUpdater*>(data); + gtk_spin_button_update(GTK_SPIN_BUTTON(widget)); + updater->update(GTK_SPIN_BUTTON(widget)); + return FALSE; + } + +private: + + void update(GtkSpinButton* spin) + { + int new_value = 1000 * gtk_spin_button_get_value(spin); + + GsmApplication::get()->settings->set_int(this->key, new_value); + + procman_debug("set %s to %d", this->key.c_str(), new_value); + } + + const string key; +}; + +class ScaleUpdater +{ +public: + ScaleUpdater(const string& key) + : key(key) + { } + + static gboolean callback(GtkRange *range, gpointer data) + { + ScaleUpdater* updater = static_cast<ScaleUpdater*>(data); + updater->update(range); + return FALSE; + } + +private: + + void update(GtkRange* range) + { + int new_value = gtk_range_get_value(range); + + GsmApplication::get()->settings->set_int(this->key, new_value); + + procman_debug("set %s to %d", this->key.c_str(), new_value); + } + + const string key; +}; + +static void +field_toggled (const gchar *gsettings_parent, gchar *path_str, gpointer data) +{ + GtkTreeModel *model = static_cast<GtkTreeModel*>(data); + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + GtkTreeIter iter; + GtkTreeViewColumn *column; + gboolean toggled; + auto settings = GsmApplication::get()->settings->get_child (gsettings_parent); + int id; + + if (!path) + return; + + gtk_tree_model_get_iter (model, &iter, path); + + gtk_tree_model_get (model, &iter, 2, &column, -1); + + gtk_tree_model_get (model, &iter, 0, &toggled, -1); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !toggled, -1); + gtk_tree_view_column_set_visible (column, !toggled); + + id = gtk_tree_view_column_get_sort_column_id (column); + + auto key = Glib::ustring::compose ("col-%1-visible", id); + settings->set_boolean (key, !toggled); + + gtk_tree_path_free (path); + +} + +static void +field_row_activated ( GtkTreeView *tree, GtkTreePath *path, + GtkTreeViewColumn *column, gpointer data) +{ + GtkTreeModel * model = gtk_tree_view_get_model (tree); + gchar * path_str = gtk_tree_path_to_string (path); + field_toggled((gchar*)data, path_str, model ); + g_free (path_str); +} + +static void +proc_field_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data) +{ + field_toggled("proctree", path_str, data); +} + +static void +disk_field_toggled (GtkCellRendererToggle *cell, gchar *path_str, gpointer data) +{ + field_toggled("disktreenew", path_str, data); +} + +static void +create_field_page(GtkBuilder* builder, GtkTreeView *tree, const gchar *widgetname) +{ + GtkTreeView *treeview; + GList *it, *columns; + GtkListStore *model; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; + gchar *full_widgetname; + + full_widgetname = g_strdup_printf ("%s_columns", widgetname); + treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, full_widgetname)); + g_free (full_widgetname); + + model = gtk_list_store_new (3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER); + + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL(model)); + g_object_unref (G_OBJECT (model)); + + column = gtk_tree_view_column_new (); + + cell = gtk_cell_renderer_toggle_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_attributes (column, cell, + "active", 0, + NULL); + if(!g_strcmp0(widgetname, "proctree")) + g_signal_connect (G_OBJECT (cell), "toggled", G_CALLBACK (proc_field_toggled), model); + else if(!g_strcmp0(widgetname, "disktreenew")) + g_signal_connect (G_OBJECT (cell), "toggled", G_CALLBACK (disk_field_toggled), model); + + g_signal_connect (G_OBJECT (GTK_TREE_VIEW (treeview)), "row-activated", G_CALLBACK (field_row_activated), (gpointer)widgetname); + + gtk_tree_view_column_set_clickable (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + column = gtk_tree_view_column_new (); + + cell = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_attributes (column, cell, + "text", 1, + NULL); + + gtk_tree_view_column_set_title (column, "Not Shown"); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree)); + + for(it = columns; it; it = it->next) + { + GtkTreeViewColumn *column = static_cast<GtkTreeViewColumn*>(it->data); + GtkTreeIter iter; + const gchar *title; + gboolean visible; + gint column_id; + + title = gtk_tree_view_column_get_title (column); + if (!title) + title = _("Icon"); + + column_id = gtk_tree_view_column_get_sort_column_id(column); + if ((column_id == COL_CGROUP) && (!cgroups_enabled())) + continue; + if ((column_id == COL_SECURITYCONTEXT) && (!can_show_security_context_column ())) + continue; + + if ((column_id == COL_UNIT || + column_id == COL_SESSION || + column_id == COL_SEAT || + column_id == COL_OWNER) + && !procman::systemd_logind_running() + ) + continue; + + visible = gtk_tree_view_column_get_visible (column); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, 0, visible, 1, title, 2, column,-1); + } + + g_list_free(columns); + +} + +void +create_preferences_dialog (GsmApplication *app) +{ + typedef SpinButtonUpdater SBU; + + static SBU interval_updater("update-interval"); + static SBU graph_interval_updater("graph-update-interval"); + static SBU disks_interval_updater("disks-interval"); + static ScaleUpdater graph_points_updater("graph-data-points"); + + GtkAdjustment *adjustment; + GtkSpinButton *spin_button; + GtkSwitch *check_switch; + GtkSwitch *smooth_switch; + GtkBuilder *builder; + gfloat update; + + if (prefs_dialog) + return; + + builder = gtk_builder_new(); + gtk_builder_add_from_resource (builder, "/org/gnome/gnome-system-monitor/data/preferences.ui", NULL); + + prefs_dialog = HDY_PREFERENCES_WINDOW (gtk_builder_get_object (builder, "preferences_dialog")); + + spin_button = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "processes_interval_spinner")); + + update = (gfloat) app->config.update_interval; + adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(spin_button)); + gtk_adjustment_configure (adjustment, + update / 1000.0, + MIN_UPDATE_INTERVAL / 1000, + MAX_UPDATE_INTERVAL / 1000, + 0.25, + 1.0, + 0); + g_signal_connect (G_OBJECT (spin_button), "focus_out_event", + G_CALLBACK (SBU::callback), &interval_updater); + + smooth_switch = GTK_SWITCH (gtk_builder_get_object (builder, "smooth_switch")); + g_settings_bind(app->settings->gobj (), SmoothRefresh::KEY.c_str(), smooth_switch, "active", G_SETTINGS_BIND_DEFAULT); + + check_switch = GTK_SWITCH (gtk_builder_get_object (builder, "check_switch")); + g_settings_bind (app->settings->gobj (), GSM_SETTING_SHOW_KILL_DIALOG, + check_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *solaris_switch = GTK_SWITCH (gtk_builder_get_object (builder, "solaris_switch")); + g_settings_bind (app->settings->gobj (), GSM_SETTING_SOLARIS_MODE, + solaris_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *proc_mem_in_iec_switch = GTK_SWITCH (gtk_builder_get_object (builder, "proc_mem_in_iec_switch")); + g_settings_bind(app->settings->gobj (), GSM_SETTING_PROCESS_MEMORY_IN_IEC, + proc_mem_in_iec_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *logarithmic_scale_switch = GTK_SWITCH (gtk_builder_get_object (builder, "logarithmic_scale_switch")); + g_settings_bind (app->settings->gobj (), GSM_SETTING_LOGARITHMIC_SCALE, + logarithmic_scale_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *draw_stacked_switch = GTK_SWITCH (gtk_builder_get_object (builder, "draw_stacked_switch")); + g_settings_bind (app->settings->gobj (), GSM_SETTING_DRAW_STACKED, + draw_stacked_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *draw_smooth_switch = GTK_SWITCH (gtk_builder_get_object (builder, "draw_smooth_switch")); + g_settings_bind (app->settings->gobj (), GSM_SETTING_DRAW_SMOOTH, + draw_smooth_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *res_mem_in_iec_switch = GTK_SWITCH (gtk_builder_get_object (builder, "res_mem_in_iec_switch")); + g_settings_bind(app->settings->gobj (), GSM_SETTING_RESOURCES_MEMORY_IN_IEC, + res_mem_in_iec_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + create_field_page (builder, GTK_TREE_VIEW (app->tree), "proctree"); + + update = (gfloat) app->config.graph_update_interval; + spin_button = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "resources_interval_spinner")); + adjustment = gtk_spin_button_get_adjustment (spin_button); + gtk_adjustment_configure (adjustment, update / 1000.0, 0.05, + 10.0, 0.05, 0.5, 0); + g_signal_connect (G_OBJECT (spin_button), "focus_out_event", + G_CALLBACK(SBU::callback), + &graph_interval_updater); + + update = (gfloat) app->config.graph_data_points; + GtkRange* range = GTK_RANGE (gtk_builder_get_object (builder, "graph_data_points_scale")); + adjustment = gtk_range_get_adjustment (range); + gtk_adjustment_configure (adjustment, update, 30, + 600, 10, 60, 0); + g_signal_connect (G_OBJECT (range), "value-changed", + G_CALLBACK(ScaleUpdater::callback), + &graph_points_updater); + + GtkSwitch *bits_switch = GTK_SWITCH (gtk_builder_get_object (builder, "bits_switch")); + g_settings_bind(app->settings->gobj (), GSM_SETTING_NETWORK_IN_BITS, + bits_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *bits_unit_switch = GTK_SWITCH (gtk_builder_get_object (builder, "bits_unit_switch")); + g_settings_bind(app->settings->gobj (), GSM_SETTING_NETWORK_TOTAL_UNIT, + bits_unit_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + GtkSwitch *bits_total_switch = GTK_SWITCH (gtk_builder_get_object (builder, "bits_total_switch")); + g_settings_bind(app->settings->gobj (), GSM_SETTING_NETWORK_TOTAL_IN_BITS, + bits_total_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + update = (gfloat) app->config.disks_update_interval; + spin_button = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "devices_interval_spinner")); + adjustment = gtk_spin_button_get_adjustment (spin_button); + gtk_adjustment_configure (adjustment, update / 1000.0, 1.0, + 100.0, 1.0, 1.0, 0); + g_signal_connect (G_OBJECT (spin_button), "focus_out_event", + G_CALLBACK(SBU::callback), + &disks_interval_updater); + + + check_switch = GTK_SWITCH (gtk_builder_get_object (builder, "all_devices_check")); + g_settings_bind (app->settings->gobj (), GSM_SETTING_SHOW_ALL_FS, + check_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + create_field_page (builder, GTK_TREE_VIEW (app->disk_list), "disktreenew"); + + gtk_window_set_transient_for (GTK_WINDOW (prefs_dialog), GTK_WINDOW (GsmApplication::get()->main_window)); + gtk_window_set_modal (GTK_WINDOW (prefs_dialog), TRUE); + + gtk_widget_show_all (GTK_WIDGET (prefs_dialog)); + g_signal_connect (G_OBJECT (prefs_dialog), "delete-event", + G_CALLBACK (prefs_dialog_delete_event), NULL); + + gtk_window_present (GTK_WINDOW (prefs_dialog)); + + gtk_builder_connect_signals (builder, NULL); + g_object_unref (G_OBJECT (builder)); +} |