[gnome-system-monitor] Added support for actions on multiple processes (bgo #681405)



commit 5cf1225d86929114d6f0424112fd2abc8880dc26
Author: Robert Roth <robert roth off gmail com>
Date:   Fri Aug 2 01:33:50 2013 +0300

    Added support for actions on multiple processes (bgo #681405)

 src/interface.cpp      |    2 +-
 src/procdialogs.cpp    |   71 +++++++++++++++++++++++++++++++++---------------
 src/procman-app.h      |    1 -
 src/procproperties.cpp |    6 ++--
 src/proctable.cpp      |   22 ++++++---------
 src/proctable.h        |    2 +
 6 files changed, 64 insertions(+), 40 deletions(-)
---
diff --git a/src/interface.cpp b/src/interface.cpp
index cce62fa..6f375e9 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -724,7 +724,7 @@ update_sensitivity(ProcmanApp *app)
     GAction *action;
 
     processes_sensitivity = (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (app->stack)), "processes") 
== 0);
-    selected_sensitivity = (processes_sensitivity && app->selected_process != NULL);
+    selected_sensitivity = (processes_sensitivity && gtk_tree_selection_count_selected_rows (app->selection) 
0);
 
     for (i = 0; i != G_N_ELEMENTS(processes_actions); ++i) {
         action = g_action_map_lookup_action (G_ACTION_MAP (app->main_window),
diff --git a/src/procdialogs.cpp b/src/procdialogs.cpp
index 6a8b661..2a1654e 100644
--- a/src/procdialogs.cpp
+++ b/src/procdialogs.cpp
@@ -67,31 +67,50 @@ procdialog_create_kill_dialog (ProcmanApp *app, int signal)
     kargs = g_new(KillArgs, 1);
     kargs->app = app;
     kargs->signal = signal;
-
-
-    if (signal == SIGKILL) {
-        /*xgettext: primary alert message*/
-        primary = g_strdup_printf (_("Kill the selected process “%s” (PID: %u)?"),
-                                   app->selected_process->name,
-                                   app->selected_process->pid);
+    gint selected_count = gtk_tree_selection_count_selected_rows (app->selection);
+
+    if ( selected_count == 1 ) {
+        ProcInfo *selected_process = NULL;
+        // get the last selected row
+        gtk_tree_selection_selected_foreach (app->selection, get_last_selected,
+                                         &selected_process);
+        if (signal == SIGKILL) {
+            /*xgettext: primary alert message for killing single process*/
+            primary = g_strdup_printf (_("Are you sure you want to kill the selected process “%s” (PID: 
%u)?"),
+                                       selected_process->name,
+                                       selected_process->pid);
+        } else {
+            /*xgettext: primary alert message for ending single process*/
+            primary = g_strdup_printf (_("Are you sure you want to end the selected process “%s” (PID: 
%u)?"),
+                                       selected_process->name,
+                                       selected_process->pid);
+        }
+    } else {
+        if (signal == SIGKILL) {
+            /*xgettext: primary alert message for killing multiple processes*/
+            primary = g_strdup_printf (_("Are you sure you want to kill the %d selected processes?"),
+                                       selected_count);
+        } else {
+            /*xgettext: primary alert message for ending multiple processes*/
+            primary = g_strdup_printf (_("Are you sure you want to end the %d selected processes?"),
+                                       selected_count);
+        }
+    }
+    
+    if ( signal == SIGKILL ) {
         /*xgettext: secondary alert message*/
         secondary = _("Killing a process may destroy data, break the "
                       "session or introduce a security risk. "
                       "Only unresponsive processes should be killed.");
-        button_text = _("_Kill Process");
-    }
-    else {
-        /*xgettext: primary alert message*/
-        primary = g_strdup_printf (_("End the selected process “%s” (PID: %u)?"),
-                                   app->selected_process->name,
-                                   app->selected_process->pid);
+        button_text = ngettext("_Kill Process", "_Kill Processes", selected_count);
+    } else {
         /*xgettext: secondary alert message*/
-        secondary = _("Ending a process may destroy data, break the "
+        secondary = _("Killing a process may destroy data, break the "
                       "session or introduce a security risk. "
-                      "Only unresponsive processes should be ended.");
-        button_text = _("_End Process");
+                      "Only unresponsive processes should be killed.");
+        button_text = ngettext("_End Process", "_End Processes", selected_count);
     }
-
+    
     kill_alert_dialog = gtk_message_dialog_new (GTK_WINDOW (app->main_window),
                                                 static_cast<GtkDialogFlags>(GTK_DIALOG_MODAL | 
GTK_DIALOG_DESTROY_WITH_PARENT),
                                                 GTK_MESSAGE_WARNING,
@@ -147,7 +166,8 @@ renice_dialog_button_pressed (GtkDialog *dialog, gint id, gpointer data)
 void
 procdialog_create_renice_dialog (ProcmanApp *app)
 {
-    ProcInfo *info = app->selected_process;
+    ProcInfo *info;
+    
     GtkWidget *label;
     GtkWidget *priority_label;
     GtkAdjustment *renice_adj;
@@ -158,6 +178,9 @@ procdialog_create_renice_dialog (ProcmanApp *app)
     if (renice_dialog)
         return;
 
+    gtk_tree_selection_selected_foreach (app->selection, get_last_selected,
+                                         &info);
+    gint selected_count = gtk_tree_selection_count_selected_rows (app->selection);
     if (!info)
         return;
 
@@ -165,9 +188,13 @@ procdialog_create_renice_dialog (ProcmanApp *app)
     gtk_builder_add_from_resource (builder, "/org/gnome/gnome-system-monitor/data/renice.ui", NULL);
 
     renice_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "renice_dialog"));
-
-    dialog_title = g_strdup_printf (_("Change Priority of Process “%s” (PID: %u)"),
-                                    info->name, info->pid);
+    if ( selected_count == 1 ) {
+        dialog_title = g_strdup_printf (_("Change Priority of Process “%s” (PID: %u)"),
+                                        info->name, info->pid);
+    } else {
+        dialog_title = g_strdup_printf (_("Change Priority of %d selected processes"),
+                                        selected_count);
+    }
 
     gtk_window_set_title (GTK_WINDOW(renice_dialog), dialog_title);
     
diff --git a/src/procman-app.h b/src/procman-app.h
index 5f4ffd9..951dc02 100644
--- a/src/procman-app.h
+++ b/src/procman-app.h
@@ -175,7 +175,6 @@ public:
     LoadGraph        *net_graph;
     gint              cpu_label_fixed_width;
     gint              net_label_fixed_width;
-    ProcInfo         *selected_process;
     GtkTreeSelection *selection;
     guint             timeout;
     guint             disk_timeout;
diff --git a/src/procproperties.cpp b/src/procproperties.cpp
index 238b922..e9b8ca0 100644
--- a/src/procproperties.cpp
+++ b/src/procproperties.cpp
@@ -143,7 +143,7 @@ close_procprop_dialog (GtkDialog *dialog, gint id, gpointer data)
 }
 
 static GtkWidget *
-create_procproperties_tree (ProcmanApp *app)
+create_procproperties_tree (ProcmanApp *app, ProcInfo *info)
 {
     GtkWidget *tree;
     GtkListStore *model;
@@ -172,7 +172,7 @@ create_procproperties_tree (ProcmanApp *app)
     }
 
     gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(tree), FALSE);
-    fill_proc_properties(tree, app->selected_process);
+    fill_proc_properties(tree, info);
 
     return tree;
 }
@@ -244,7 +244,7 @@ create_single_procproperties_dialog (GtkTreeModel *model, GtkTreePath *path,
     gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
                                          GTK_SHADOW_IN);
 
-    tree = create_procproperties_tree (app);
+    tree = create_procproperties_tree (app, info);
     gtk_container_add (GTK_CONTAINER (scrolled), tree);
     g_object_set_data (G_OBJECT (tree), "selected_info", GUINT_TO_POINTER (info->pid));
 
diff --git a/src/proctable.cpp b/src/proctable.cpp
index 09eacf7..22d53aa 100644
--- a/src/proctable.cpp
+++ b/src/proctable.cpp
@@ -227,7 +227,7 @@ cb_tree_popup_menu (GtkWidget *widget, gpointer data)
     return TRUE;
 }
 
-static void
+void
 get_last_selected (GtkTreeModel *model, GtkTreePath *path,
                    GtkTreeIter *iter, gpointer data)
 {
@@ -243,16 +243,16 @@ cb_row_selected (GtkTreeSelection *selection, gpointer data)
 
     app->selection = selection;
 
-    app->selected_process = NULL;
+    ProcInfo *selected_process = NULL;
 
     /* get the most recent selected process and determine if there are
     ** no selected processes
     */
     gtk_tree_selection_selected_foreach (app->selection, get_last_selected,
-                                         &app->selected_process);
-    if (app->selected_process) {
+                                         &selected_process);
+    if (selected_process) {
         GVariant *priority;
-        gint nice = app->selected_process->nice;
+        gint nice = selected_process->nice;
         if (nice < -7)
             priority = g_variant_new_int32 (-20);
         else if (nice < -2)
@@ -345,7 +345,6 @@ proctable_new (ProcmanApp * const app)
     GtkTreeModelFilter *model_filter;
     GtkTreeModelSort *model_sort;
     
-    GtkTreeSelection *selection;
     GtkTreeViewColumn *column;
     GtkCellRenderer *cell_renderer;
     const gchar *titles[] = {
@@ -424,9 +423,6 @@ proctable_new (ProcmanApp * const app)
     gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (proctree), TRUE);
     g_object_unref (G_OBJECT (model));
 
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (proctree));
-    gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
-
     column = gtk_tree_view_column_new ();
 
     cell_renderer = gtk_cell_renderer_pixbuf_new ();
@@ -613,7 +609,10 @@ proctable_new (ProcmanApp * const app)
         }
     }
 
-    g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (proctree))),
+    app->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (proctree));
+    gtk_tree_selection_set_mode (app->selection, GTK_SELECTION_MULTIPLE);
+    
+    g_signal_connect (G_OBJECT (app->selection),
                       "changed",
                       G_CALLBACK (cb_row_selected), app);
     g_signal_connect (G_OBJECT (proctree), "popup_menu",
@@ -887,9 +886,6 @@ remove_info_from_tree (ProcmanApp *app, GtkTreeModel *model,
 
     g_assert(not gtk_tree_model_iter_has_child(model, &current->node));
 
-    if (app->selected_process == current)
-        app->selected_process = NULL;
-
     orphans.push_back(current);
     gtk_tree_store_remove(GTK_TREE_STORE(model), &current->node);
     procman::poison(current->node, 0x69);
diff --git a/src/proctable.h b/src/proctable.h
index f7cb46a..ea01b71 100644
--- a/src/proctable.h
+++ b/src/proctable.h
@@ -73,5 +73,7 @@ void            proctable_set_columns_order(GtkTreeView *treeview, GSList *order
 char*           make_loadavg_string(void);
 
 void            get_process_memory_writable (ProcInfo *info);
+void            get_last_selected (GtkTreeModel *model, GtkTreePath *path,
+                                   GtkTreeIter *iter, gpointer data);
 
 #endif /* _PROCMAN_PROCTABLE_H_ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]