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

Added Storage Analyzer.

Added ListBox in storage.
Enhancements of HeaderBar.
parent a9483458
......@@ -13,7 +13,7 @@ New GNOME Usage!
- [x] Support other architectures than x86_64 (netinfo precompiled library)
- [ ] Fix bug with refreshing ProcessListBox 50% (focus, and click when refresh)
- [ ] Search in processes
- [ ] Storage view - 1%
- [ ] Storage view - 75%
- [ ] Power view (Design?)
- [ ] Disk usage (What library we can use?)
- [ ] Data view - 0%
......
......@@ -112,45 +112,17 @@ PieChart.available, ColorRectangle.available {
}
ColorRectangle.system {
color: #2e3436;
color: #3c4447;
}
ColorRectangle.applications {
color: #4e9a06;
}
ColorRectangle.documents {
color: #99b9dc;
}
ColorRectangle.downloads {
color: #9bb8db;
}
ColorRectangle.music {
color: #457fd3;
}
ColorRectangle.pictures {
color: #3466a5;
}
ColorRectangle.videos {
color: #204a87;
}
ColorRectangle.others-storage {
color: #16325c;
}
ColorRectangle.trash {
color: #ef2929;
}
ColorRectangle.cache {
color: #fce94f;
}
ColorRectangle.user {
color: #ad7fa8;
}
......@@ -158,3 +130,11 @@ ColorRectangle.user {
ColorRectangle.available-storage {
color: #d3d7cf;
}
row.folders {
color: #457fd3;
}
list.folders {
color: #457fd3;
}
\ No newline at end of file
......@@ -125,38 +125,10 @@ ColorRectangle.applications {
color: #4e9a06;
}
ColorRectangle.documents {
color: #99b9dc;
}
ColorRectangle.downloads {
color: #9bb8db;
}
ColorRectangle.music {
color: #457fd3;
}
ColorRectangle.pictures {
color: #3466a5;
}
ColorRectangle.videos {
color: #204a87;
}
ColorRectangle.others_storage {
color: #16325c;
}
ColorRectangle.trash {
color: #ef2929;
}
ColorRectangle.cache {
color: #fce94f;
}
ColorRectangle.user {
color: #ad7fa8;
}
......@@ -164,3 +136,11 @@ ColorRectangle.user {
ColorRectangle.available_storage {
color: #d3d7cf;
}
row.folders {
color: #457fd3;
}
list.folders {
color: #457fd3;
}
......@@ -58,8 +58,13 @@ c_library: rg egg gmodule-2.0 m rt gtop-2.0 pthread dl netinfo
*vala_source: process-row.vala
*vala_source: process.vala
*vala_source: settings.vala
*vala_source: storage-analyzer.vala
*vala_source: storage-graph.vala
*vala_source: storage-item.vala
*vala_source: storage-list-box.vala
*vala_source: storage-row.vala
*vala_source: storage-view.vala
*vala_source: storage-worker.vala
*vala_source: sub-process-list-box.vala
*vala_source: sub-process-sub-row.vala
*vala_source: system-monitor.vala
......@@ -108,8 +113,13 @@ h_folder: /usr/include/libgtop-2.0
*translate: vala src/process-row.vala
*translate: vala src/process.vala
*translate: vala src/settings.vala
*translate: vala src/storage-analyzer.vala
*translate: vala src/storage-graph.vala
*translate: vala src/storage-item.vala
*translate: vala src/storage-list-box.vala
*translate: vala src/storage-row.vala
*translate: vala src/storage-view.vala
*translate: vala src/storage-worker.vala
*translate: vala src/sub-process-list-box.vala
*translate: vala src/sub-process-sub-row.vala
*translate: vala src/system-monitor.vala
......
......@@ -2,17 +2,18 @@
# Please keep this file sorted alphabetically.
data/org.gnome.Usage.desktop
data/org.gnome.Usage.gschema.xml
external/egg/egg-date-time.c
external/egg/egg-file-chooser-entry.c
external/egg/egg-search-bar.c
src/application.vala
src/cpu-sub-view.vala
src/data-view.vala
src/graph-block.vala
src/graph-stack-switcher.vala
src/memory-sub-view.vala
src/network-sub-view.vala
src/performance-view.vala
src/power-view.vala
src/process-dialog.vala
src/storage-analyzer.vala
src/storage-item.vala
src/storage-view.vala
src/utils.vala
src/window.vala
......@@ -7,6 +7,7 @@ namespace Usage
public Settings settings;
private Window window;
private SystemMonitor monitor;
private StorageAnalyzer storage_analyzer;
private const GLib.ActionEntry app_entries[] =
{
......@@ -19,6 +20,7 @@ namespace Usage
application_id = "org.gnome.Usage";
settings = new Settings();
monitor = new SystemMonitor();
storage_analyzer = new StorageAnalyzer();
}
public SystemMonitor get_system_monitor()
......@@ -26,6 +28,11 @@ namespace Usage
return monitor;
}
public StorageAnalyzer get_storage_analyzer()
{
return storage_analyzer;
}
public Window? get_window()
{
return window;
......
......@@ -10,11 +10,26 @@ namespace Usage {
set_css_name("ColorRectangle");
}
public ColorRectangle(string css_class)
public Gdk.RGBA get_color()
{
return color;
}
public ColorRectangle.new_from_rgba(Gdk.RGBA color)
{
this.color = color;
init();
}
public ColorRectangle.new_from_css(string css_class)
{
get_style_context().add_class(css_class);
color = get_style_context().get_color(get_style_context().get_state());
init();
}
private void init()
{
this.height_request = 17;
this.width_request = 17;
this.valign = Gtk.Align.CENTER;
......
......@@ -10,7 +10,7 @@ namespace Usage {
public GraphBlockRow(GraphBlockType type, string label_text, string css_class)
{
Object(orientation: Gtk.Orientation.HORIZONTAL);
var color_rectangle = new ColorRectangle(css_class);
var color_rectangle = new ColorRectangle.new_from_css(css_class);
var label = new Gtk.Label(label_text);
label.margin = 5;
label.ellipsize = Pango.EllipsizeMode.END;
......
......@@ -22,10 +22,10 @@ namespace Usage
this.sub_views = sub_views;
buttons = {
new GraphSwitcherButton.processor("Processor"),
new GraphSwitcherButton.memory("Memory"),
new GraphSwitcherButton.disk("Disk I/O"),
new GraphSwitcherButton.network("Network"),
new GraphSwitcherButton.processor(_("Processor")),
new GraphSwitcherButton.memory(_("Memory")),
new GraphSwitcherButton.disk(_("Disk I/O")),
new GraphSwitcherButton.network(_("Network")),
};
foreach(Gtk.ToggleButton button in buttons)
......
namespace Usage
{
public enum HeaderBarMode
{
PERFORMANCE,
DATA,
STORAGE,
POWER
}
public class HeaderBar : Gtk.HeaderBar
{
private Gtk.StackSwitcher stack_switcher;
private Gtk.MenuButton menu_button;
private Gtk.Button? storage_back_button;
private bool show_storage_back_btn = false;
private Gtk.Button? storage_rescan_button;
private HeaderBarMode mode;
public HeaderBar(Gtk.Stack stack)
{
mode = HeaderBarMode.PERFORMANCE;
show_close_button = true;
stack_switcher = new Gtk.StackSwitcher();
stack_switcher.halign = Gtk.Align.CENTER;
stack_switcher.set_stack(stack);
set_custom_title(stack_switcher);
menu_button = new Gtk.MenuButton();
menu_button.add(new Gtk.Image.from_icon_name("open-menu-symbolic", Gtk.IconSize.BUTTON));
set_mode(HeaderBarMode.PERFORMANCE);
show_all();
}
public void set_mode(HeaderBarMode mode)
{
switch(this.mode)
{
case HeaderBarMode.PERFORMANCE:
break;
case HeaderBarMode.DATA:
break;
case HeaderBarMode.STORAGE:
remove(storage_back_button);
remove(storage_rescan_button);
storage_rescan_button = null;
storage_back_button = null;
break;
case HeaderBarMode.POWER:
break;
}
switch(mode)
{
case HeaderBarMode.PERFORMANCE:
show_stack_switcher();
break;
case HeaderBarMode.DATA:
show_stack_switcher();
break;
case HeaderBarMode.STORAGE:
show_stack_switcher();
storage_back_button = new Gtk.Button.from_icon_name("go-previous-symbolic");
storage_back_button.clicked.connect(() => {
((StorageView) (GLib.Application.get_default() as Application).get_window().get_views()[2]).get_storage_list_box().on_back_button_clicked();
});
show_storage_back_button(show_storage_back_btn);
storage_rescan_button = new Gtk.Button.from_icon_name("view-refresh-symbolic");
storage_rescan_button.clicked.connect(() => {
(GLib.Application.get_default() as Application).get_storage_analyzer().create_cache.begin(true);
((StorageView) (GLib.Application.get_default() as Application).get_window().get_views()[2]).get_storage_list_box().reload();
});
storage_rescan_button.show();
pack_start(storage_back_button);
pack_end(storage_rescan_button);
break;
case HeaderBarMode.POWER:
show_stack_switcher();
break;
}
this.mode = mode;
}
public void show_title_text(string title)
{
set_custom_title(null);
set_title(title);
}
public void show_stack_switcher()
{
set_custom_title(stack_switcher);
}
public void show_storage_back_button(bool show)
{
if(storage_back_button != null)
{
if(show)
{
storage_back_button.show();
show_storage_back_btn = true;
}
else
{
storage_back_button.hide();
show_storage_back_btn = false;
}
}
}
}
}
\ No newline at end of file
This diff is collapsed.
using Gee;
namespace Usage
{
public enum StorageItemPosition
{
FIRST,
SECOND,
ANYWHERE,
PENULTIMATE,
LAST
}
public enum StorageItemType
{
STORAGE,
SYSTEM,
DOCUMENTS,
DOWNLOADS,
DESKTOP,
MUSIC,
PICTURES,
VIDEOS,
TRASH,
USER,
AVAILABLE,
FILE,
DIRECTORY
}
public class StorageItem : Object
{
private string name;
private string path;
private StorageItemType type;
private uint64 size;
private double percentage;
private StorageItemPosition prefered_position = StorageItemPosition.ANYWHERE;
private int section;
private Gdk.RGBA color;
public StorageItem.item(StorageItemType type, string name, string path, uint64 size, double percentage, int section = 0, StorageItemPosition prefered_position = StorageItemPosition.ANYWHERE)
{
this.type = type;
this.name = name;
this.path = path;
this.size = size;
this.percentage = percentage;
this.section = section;
this.prefered_position = prefered_position;
}
public StorageItem.directory(string name, string path, uint64 size, double percentage)
{
StorageItem.item(StorageItemType.DIRECTORY, name, path, size, percentage);
}
public StorageItem.file(string name, string path, uint64 size, double percentage)
{
StorageItem.item(StorageItemType.FILE, name, path, size, percentage);
}
public StorageItem.trash(string path, uint64 size, double percentage, int section = 0)
{
StorageItem.item(StorageItemType.TRASH, _("Trash"), path, size, percentage, section, StorageItemPosition.PENULTIMATE);
}
public StorageItem.storage(string name, string path, uint64 size, int section = 0)
{
StorageItem.item(StorageItemType.STORAGE, name, path, size, 0, section, StorageItemPosition.FIRST);
}
public StorageItem.system(string name, uint64 size, double percentage, int section = 0)
{
StorageItem.item(StorageItemType.SYSTEM, name, "", size, percentage, section);
}
public StorageItem.available(uint64 size, double percentage, int section = 0)
{
StorageItem.item(StorageItemType.AVAILABLE, _("Available"), "", size, percentage, section, StorageItemPosition.LAST);
}
public StorageItemPosition get_prefered_position()
{
return prefered_position;
}
public void set_color(Gdk.RGBA color)
{
this.color = color;
}
public Gdk.RGBA get_color()
{
return color;
}
public int get_section()
{
return section;
}
public uint64 get_size()
{
return size;
}
public double get_percentage()
{
return percentage;
}
public string get_name()
{
return name;
}
public StorageItemType get_item_type()
{
return type;
}
public string get_path()
{
return path;
}
}
}
\ No newline at end of file
namespace Usage
{
public class StorageListBox : Gtk.ListBox
{
public signal void loading();
public signal void loaded();
private List<string?> path_history;
private List<string?> name_history;
private string? actual_path;
private string? actual_name;
private ListStore model;
private bool root = true;
private StorageAnalyzer storage_analyzer;
private Gdk.RGBA color;
public StorageListBox()
{
set_selection_mode (Gtk.SelectionMode.NONE);
set_header_func (update_header);
model = new ListStore(typeof(StorageItem));
bind_model(model, on_row_created);
row_activated.connect(on_row_activated);
path_history = new List<string>();
name_history = new List<string>();
actual_path = null;
actual_name = null;
storage_analyzer = (GLib.Application.get_default() as Application).get_storage_analyzer();
reload();
}
public void on_back_button_clicked()
{
unowned List<string>? path = path_history.last();
unowned List<string>? name = name_history.last();
actual_path = path.data;
actual_name = name.data;
load(path.data);
path_history.delete_link(path);
name_history.delete_link(name);
if(root)
{
(GLib.Application.get_default() as Application).get_window().get_header_bar().show_storage_back_button(false);
(GLib.Application.get_default() as Application).get_window().get_header_bar().show_stack_switcher();
}
else
(GLib.Application.get_default() as Application).get_window().get_header_bar().show_title_text(actual_name);
}
public void reload()
{
get_style_context().add_class("folders");
color = get_style_context().get_color(get_style_context().get_state());
get_style_context().remove_class("folders");
this.hide();
loading();
root = true;
storage_analyzer.cache_complete.connect(() => {
storage_analyzer.prepare_items.begin(actual_path, color, (obj, res) => {
loaded();
this.show();
model.remove_all();
foreach(unowned StorageItem item in storage_analyzer.prepare_items.end(res))
model.append(item);
});
});
}
private void load(string? path)
{
if(path == null)
{
root = true;
get_style_context().add_class("folders");
color = get_style_context().get_color(get_style_context().get_state());
get_style_context().remove_class("folders");
}
else
root = false;
this.hide();
loading();
storage_analyzer.prepare_items.begin(path, color, (obj, res) => {
loaded();
this.show();
model.remove_all();
foreach(unowned StorageItem item in storage_analyzer.prepare_items.end(res))
model.append(item);
});
}
private void on_row_activated (Gtk.ListBoxRow row)
{
StorageRow storage_row = (StorageRow) row;
if(storage_row.get_item_type() == StorageItemType.FILE)
;//TODO: action on click
else if(storage_row.get_item_type() != StorageItemType.STORAGE && storage_row.get_item_type() != StorageItemType.SYSTEM
&& storage_row.get_item_type() != StorageItemType.AVAILABLE)
{
path_history.append(actual_path);
name_history.append(actual_name);
actual_path = storage_row.get_item_path();
actual_name = storage_row.get_item_name();
(GLib.Application.get_default() as Application).get_window().get_header_bar().show_storage_back_button(true);
(GLib.Application.get_default() as Application).get_window().get_header_bar().show_title_text(actual_name);
if(root)
color = storage_row.get_color();
load(actual_path);
}
}
private Gtk.Widget on_row_created (Object item)
{
unowned StorageItem storage_item = (StorageItem) item;