Commit c33ecafa authored by Petr Štětka's avatar Petr Štětka
Browse files

version 0.0.7

Implemented subprocess
parent 1d3180ee
......@@ -18,7 +18,7 @@ sudo make install
In terminal run ```gnome-usage``` command or run GNOME Usage application from app launcher.
##Version
Actual version is 0.0.6
Actual version is 0.0.7
##License
Code is under GNU GPLv3 license.
......
No preview for this file type
......@@ -5,7 +5,7 @@ project_name: gnome-usage
vala_binary: src/gnome-usage
*version: 0.0.6
*version: 0.0.7
*vala_vapi: vapis/better.vapi
*vala_vapi: vapis/egg-private.vapi
*vala_vapi: vapis/glibtop.vapi
......@@ -39,10 +39,12 @@ c_library: gtop-2.0 ${CMAKE_SOURCE_DIR}/external/rg/librg.a ${CMAKE_SOURCE_DIR}/
*vala_source: network-sub-view.vala
*vala_source: performance-view.vala
*vala_source: power-view.vala
*vala_source: process-list.vala
*vala_source: process-list-box.vala
*vala_source: process-row.vala
*vala_source: settings.vala
*vala_source: storage-view.vala
*vala_source: sub-process-list-box.vala
*vala_source: sub-process-sub-row.vala
*vala_source: system-monitor.vala
*vala_source: view.vala
*vala_source: window.vala
......@@ -57,26 +59,28 @@ h_folder: /usr/include/libgtop-2.0
translate: c src/better-box.c
*translate: vala src/cpu-graph-table.vala
*translate: vala src/cpu-sub-view.vala
*translate: vala src/gnome-usage.vala
*translate: vala src/sub-process-list-box.vala
*translate: vala src/application.vala
*translate: vala src/header-bar.vala
*translate: vala src/network-sub-view.vala
*translate: vala src/cpu-graph.vala
*translate: vala src/performance-view.vala
*translate: vala src/memory-graph-table.vala
*translate: vala src/process-row.vala
*translate: vala src/window.vala
*translate: vala src/sub-process-sub-row.vala
*translate: vala src/view.vala
*translate: vala src/graph-switcher-button.vala
*translate: vala src/disk-sub-view.vala
*translate: vala src/memory-sub-view.vala
*translate: vala src/graph-stack-switcher.vala
*translate: vala src/system-monitor.vala
*translate: vala src/application.vala
*translate: vala src/window.vala
*translate: vala src/process-row.vala
*translate: vala src/memory-graph.vala
*translate: vala src/process-list.vala
*translate: vala src/cpu-sub-view.vala
*translate: vala src/process-list-box.vala
*translate: vala src/settings.vala
*translate: vala src/storage-view.vala
*translate: vala src/gnome-usage.vala
*translate: vala src/power-view.vala
*translate: vala src/data-view.vala
......
......@@ -14,10 +14,12 @@ src/memory-sub-view.vala
src/network-sub-view.vala
src/performance-view.vala
src/power-view.vala
src/process-list.vala
src/process-list-box.vala
src/process-row.vala
src/settings.vala
src/storage-view.vala
src/sub-process-list-box.vala
src/sub-process-sub-row.vala
src/system-monitor.vala
src/view.vala
src/window.vala
......
......@@ -7,13 +7,13 @@ set (GETTEXT_PACKAGE "gnome-usage")
set (RELEASE_NAME "gnome-usage")
set (CMAKE_C_FLAGS "")
set (PREFIX ${CMAKE_INSTALL_PREFIX})
set (VERSION "0.0.6")
set (VERSION "0.0.7")
set (TESTSRCDIR "${CMAKE_SOURCE_DIR}")
set (DOLLAR "$")
configure_file (${CMAKE_SOURCE_DIR}/src/Config.vala.cmake ${CMAKE_BINARY_DIR}/src/Config.vala)
add_definitions(-DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\")
set (VERSION "0.0.6")
set (VERSION "0.0.7")
add_definitions (${DEPS_CFLAGS})
link_libraries ( ${DEPS_LIBRARIES} )
link_directories ( ${DEPS_LIBRARY_DIRS} )
......@@ -52,10 +52,12 @@ set (APP_SOURCES ${APP_SOURCES} memory-sub-view.vala)
set (APP_SOURCES ${APP_SOURCES} network-sub-view.vala)
set (APP_SOURCES ${APP_SOURCES} performance-view.vala)
set (APP_SOURCES ${APP_SOURCES} power-view.vala)
set (APP_SOURCES ${APP_SOURCES} process-list.vala)
set (APP_SOURCES ${APP_SOURCES} process-list-box.vala)
set (APP_SOURCES ${APP_SOURCES} process-row.vala)
set (APP_SOURCES ${APP_SOURCES} settings.vala)
set (APP_SOURCES ${APP_SOURCES} storage-view.vala)
set (APP_SOURCES ${APP_SOURCES} sub-process-list-box.vala)
set (APP_SOURCES ${APP_SOURCES} sub-process-sub-row.vala)
set (APP_SOURCES ${APP_SOURCES} system-monitor.vala)
set (APP_SOURCES ${APP_SOURCES} view.vala)
set (APP_SOURCES ${APP_SOURCES} window.vala)
......
......@@ -23,7 +23,7 @@ namespace Usage
var process_list_box_frame = new Gtk.Frame(null);
process_list_box_frame.margin_top = 30;
process_list_box_frame.margin_bottom = 20;
process_list_box_frame.add(new ListBox());
process_list_box_frame.add(new ProcessListBox());
var cpu_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
cpu_box.pack_start(label, false, false, 0);
......
// project version=0.0.6
// project version=0.0.7
public static int main (string[] args)
{
......
using Gee;
namespace Usage
{
public class ProcessListBox : Gtk.Box
{
private Gee.ArrayList<ProcessRow> rows;
HashTable<string, ProcessRow> process_rows_table;
public ProcessListBox()
{
orientation = Gtk.Orientation.VERTICAL;
rows = new Gee.ArrayList<ProcessRow>();
process_rows_table = new HashTable<string, ProcessRow>(str_hash, str_equal);
Timeout.add((GLib.Application.get_default() as Application).settings.list_update_interval, () =>
{
update();
return true;
});
}
public void update()
{
foreach(ProcessRow row in rows)
row.pre_update();
var duplicates = new HashSet<string>();
int stress = 0;
foreach(unowned Process process in (GLib.Application.get_default() as Application).monitor.get_processes())
{
if(duplicates.contains(process.cmdline))
{
unowned ProcessRow row = process_rows_table[process.cmdline];
if(!row.is_in_subrows(process.pid))
{
if((int) process.cpu_load > 0)
row.add_sub_row(process.pid, (int) process.cpu_load, process.cmdline);
}
else
{
if((int) process.cpu_load > 0)
row.update_sub_row(process.pid, (int) process.cpu_load);
}
}
else
{
if(!(process.cmdline in process_rows_table))
{
if((int) process.cpu_load > 0)
{
ProcessRow row = new ProcessRow(process.pid, (int) process.cpu_load, process.cmdline);
rows.add(row);
process_rows_table.insert (process.cmdline, row);
duplicates.add(process.cmdline);
}
}
else
{
if((int) process.cpu_load > 0)
{
unowned ProcessRow row = process_rows_table[process.cmdline];
row.update_row(process.pid, (int) process.cpu_load);
duplicates.add(process.cmdline);
}
}
}
}
sort();
this.forall ((element) => this.remove (element)); //clear box
foreach(unowned ProcessRow row in process_rows_table.get_values())
{
row.post_update();
if(row.alive == false)
{
process_rows_table.remove(row.get_name());
rows.remove(row);
}
}
for(int i = 0; i < rows.size; i++)
if(rows[i].alive)
this.add(rows[i]);
}
public void sort()
{
rows.sort((a, b) => {
return(b as ProcessRow).get_value() - ( a as ProcessRow).get_value();
});
}
}
}
using Gee;
namespace Usage
{
public class ProcessListBox : Gtk.ListBox
{
public ProcessListBox()
{
set_selection_mode (Gtk.SelectionMode.NONE);
set_header_func (update_header);
}
private void update_header(Gtk.ListBoxRow row, Gtk.ListBoxRow? before_row)
{
if(before_row == null)
row.set_header(null);
else
{
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
separator.show();
row.set_header(separator);
}
}
}
public class ListBox : Gtk.Box
{
private Gee.ArrayList<Row> rows;
HashTable<uint, Row> process_rows_table;
public ListBox()
{
orientation = Gtk.Orientation.VERTICAL;
rows = new Gee.ArrayList<Row>();
process_rows_table = new HashTable<uint, Row>(direct_hash, direct_equal);
Timeout.add((GLib.Application.get_default() as Application).settings.list_update_interval, () =>
{
update();
return true;
});
}
public void update()
{
foreach(Row row in rows)
row.alive = false;
/*GLib.List<unowned Process> processes = (GLib.Application.get_default() as Application).monitor.get_processes();
for(int i = 0; i < processes.length(); i++)
{
for(int j = i + 1; j < processes.length(); j++)
{
if(processes.nth_data(i).cmdline == processes.nth_data(j).cmdline)
stdout.printf(processes.nth_data(i).pid.to_string() + " " + processes.nth_data(j).pid.to_string() + " " + processes.nth_data(i).cmdline + " " + processes.nth_data(j).cmdline + "\n");
}
}
stdout.printf("\n\n\n");*/
foreach(unowned Process process in (GLib.Application.get_default() as Application).monitor.get_processes())
{
if(!(process.pid in process_rows_table))
{
if((int) process.cpu_load > 0)
{
Row row = new Row(process.pid, (int) process.cpu_load, process.cmdline);
rows.add(row);
process_rows_table.insert (process.pid, row);
}
}
else
{
if((int) process.cpu_load > 0)
{
unowned Row row = process_rows_table[process.pid];
row.alive = true;
row.set_value((int) process.cpu_load);
}
else
{
unowned Row row = process_rows_table[process.pid];
rows.remove(row);
process_rows_table.remove(process.pid);
}
}
}
sort();
this.forall ((element) => this.remove (element)); //clear box
for(int i = 0; i < rows.size; i++)
{
if(rows[i].alive)
{
this.add(rows[i]);
}
else
{
process_rows_table.remove(rows[i].get_pid());
rows.remove(rows[i]);
}
}
}
public void sort()
{
rows.sort((a, b) => {
return(b as Row).get_value() - ( a as Row).get_value();
});
}
}
public class ProcessDetailListBoxRow : Gtk.ListBoxRow
{
private Gtk.Image icon;
private Gtk.Label title_label;
private Gtk.Label load_label;
public int sort_id;
public bool is_headline { get; private set; }
public ProcessDetailListBoxRow(string title, int load)
{
set_can_focus(true);
this.get_style_context().add_class("processDetailListBoxRow");
var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
box.margin = 12;
title_label = new Gtk.Label(title);
load_label = new Gtk.Label(load.to_string() + " %");
icon = new Gtk.Image.from_icon_name("system-run-symbolic", Gtk.IconSize.BUTTON);
box.pack_start(icon, false, false, 10);
box.pack_start(title_label, false, true, 5);
box.pack_end(load_label, false, true, 10);
add(box);
show_all();
}
}
}
namespace Usage
{
public class Row : Gtk.Box
public class ProcessRow : Gtk.Box
{
Gtk.Image icon;
Gtk.Label title_label;
Gtk.Label load_label;
Gtk.Revealer revealer;
Gtk.EventBox event_box;
ProcessListBox sub_process_list_box; //TODO subprocess
SubProcessListBox sub_process_list_box;
bool in_box = false;
/*private Gee.ArrayList<String> names;
private Gee.ArrayList<int> values;
public Gee.ArrayList<uint> pids;*/
private uint pid;
private int value;
string name;
public bool alive = true;
public bool group = false;
//public bool is_headline { get; private set; }
public bool showing_details { get; private set; }
public bool max_usage { get; private set; }
public Row(/*Gee.ArrayList<uint> pids, Gee.ArrayList<int> values, Gee.ArrayList<int> values*/uint pid, int value, string name)
public ProcessRow(uint pid, int value, string name)
{
/*this.pids = pids;
this.names = names;
this.values = values;*/
this.pid = pid;
this.name = name;
......@@ -36,18 +31,15 @@ namespace Usage
main_box.margin = 12;
title_label = new Gtk.Label(name); //TODO implement give name
load_label = new Gtk.Label(null);
load_label.ellipsize = Pango.EllipsizeMode.END;
load_label.max_width_chars = 30;
icon = new Gtk.Image.from_icon_name("dialog-error", Gtk.IconSize.BUTTON); //TODO implement give icon
main_box.pack_start(icon, false, false, 10);
main_box.pack_start(title_label, false, true, 5);
main_box.pack_end(load_label, false, true, 10);
sub_process_list_box = new ProcessListBox();
for(int i = 4; i > 0; i--)
{
var row = new ProcessDetailListBoxRow("Title " + i.to_string(), 50); //TODO realy values
sub_process_list_box.insert(row, 0);
}
sub_process_list_box = new SubProcessListBox();
revealer = new Gtk.Revealer();
revealer.add(sub_process_list_box);
......@@ -56,7 +48,8 @@ namespace Usage
event_box.add(main_box);
event_box.button_press_event.connect ((event) => {
switch_details();
if(group)
switch_details();
return false;
});
......@@ -76,12 +69,65 @@ namespace Usage
this.pack_start(event_box, false, true, 0);
this.pack_end(revealer, false, true, 0);
this.pack_end(separator, false, true, 0);// TODO Fix for last element
this.pack_end(separator, false, true, 0); //TODO Fix for last element
update_row(pid, value);
set_value(value);
show_all();
}
public void pre_update()
{
alive = false;
sub_process_list_box.pre_update();
}
public void post_update()
{
sub_process_list_box.post_update();
if(sub_process_list_box.get_sub_rows_count() == 1)
{
group = false;
name = sub_process_list_box.get_first_name();
pid = sub_process_list_box.get_first_pid();
update_row(pid, sub_process_list_box.get_first_value());
sub_process_list_box.remove_all();
if(showing_details)
hide_details();
}
update();
}
public bool is_in_subrows(uint pid)
{
return sub_process_list_box.is_in_table(pid);
}
public void add_sub_row(uint pid, int value, string name)
{
alive = true;
if(sub_process_list_box.get_sub_rows_count() == 0)
{
sub_process_list_box.add_sub_row(this.pid, this.value, this.name);
group = true;
}
sub_process_list_box.add_sub_row(pid, value, name);
}
public void update_sub_row(uint pid, int value)
{
alive = true;
sub_process_list_box.update_sub_row(pid, value);
}
public string get_name()
{
return name;
}
public uint get_pid()
{
return pid;
......@@ -92,20 +138,46 @@ namespace Usage
return value;
}
public void set_value(int value)
public void update_row(uint pid, int value)
{
this.value = int.min(value, 100);
update();
alive = true;
if(!group)
{
this.value = int.min(value, 100);
}
else
{
if(sub_process_list_box.is_in_table(pid))
sub_process_list_box.update_sub_row(pid, value);
else
sub_process_list_box.add_sub_row(pid, value, this.name);
}
}
private void update()
{
if(value >= 90)
max_usage = true;
if(group)
{
int max_value = 0;
string values = "";
foreach(int sub_value in sub_process_list_box.get_values())
{
values += " " + sub_value.to_string() + "%";
if(sub_value > max_value)
max_value = sub_value;
}
this.value = max_value;
load_label.set_label(values);
}
else
max_usage = false;
load_label.set_label(value.to_string() + "%");
load_label.set_label(value.to_string() + "%");
if(value >= 90)
max_usage = true;
else
max_usage = false;
style();
}
......
using Gee;
namespace Usage
{
public class SubProcessListBox : Gtk.Box
{
private Gee.ArrayList<SubProcessSubRow> sub_rows;
HashTable<uint, SubProcessSubRow> process_sub_rows_table;
public SubProcessListBox()
{
orientation = Gtk.Orientation.VERTICAL;
sub_rows = new Gee.ArrayList<SubProcessSubRow>();
process_sub_rows_table = new HashTable<uint, SubProcessSubRow>(direct_hash, direct_equal);
}
public string get_first_name()
{
return sub_rows[0].get_name();
}
public uint get_first_pid()
{
return sub_rows[0].get_pid();
}
public int get_first_value()
{
return sub_rows[0].get_value();
}
public uint get_sub_rows_count()
{
return sub_rows.size;
}
public bool is_in_table(uint pid)
{
return (pid in process_sub_rows_table);
}
public void pre_update()
{
foreach(SubProcessSubRow sub_row in sub_rows)
sub_row.set_alive(false);
}
public void post_update()
{
sort();
this.forall ((element) => this.remove (element)); //clear box
foreach(