manager: Bring back multiple graph as an option.

Essentially a revert of the changes in 09189003ddf9
This commit is contained in:
Jon Nordby 2009-11-11 11:02:57 -05:00
parent 7aad3e86da
commit fa8dccf0aa
4 changed files with 147 additions and 96 deletions

View File

@ -1,15 +1,41 @@
<gconfschemafile> <gconfschemafile>
<schemalist> <schemalist>
<schema> <schema>
<key>/schemas/apps/::PACKAGE::/vmlist-fields/stats-type</key> <key>/schemas/apps/::PACKAGE::/vmlist-fields/disk_usage</key>
<applyto>/apps/::PACKAGE::/vmlist-fields/stats-type</applyto> <applyto>/apps/::PACKAGE::/vmlist-fields/disk_usage</applyto>
<owner>::PACKAGE::</owner> <owner>::PACKAGE::</owner>
<type>int</type> <type>bool</type>
<default>0</default> <default>0</default>
<locale name="C"> <locale name="C">
<short>Stats type in manager view</short> <short>Show disk I/O in summary</short>
<long>Type of stats to graph (cpu, disk, net) in manager view</long> <long>Show the disk I/O field in the domain list summary view</long>
</locale>
</schema>
<schema>
<key>/schemas/apps/::PACKAGE::/vmlist-fields/network_traffic</key>
<applyto>/apps/::PACKAGE::/vmlist-fields/network_traffic</applyto>
<owner>::PACKAGE::</owner>
<type>bool</type>
<default>0</default>
<locale name="C">
<short>Show network I/O in summary</short>
<long>Show the network I/O field in the domain list summary view</long>
</locale>
</schema>
<schema>
<key>/schemas/apps/::PACKAGE::/vmlist-fields/cpu_usage</key>
<applyto>/apps/::PACKAGE::/vmlist-fields/cpu_usage</applyto>
<owner>::PACKAGE::</owner>
<type>bool</type>
<default>1</default>
<locale name="C">
<short>Show cpu usage in summary</short>
<long>Show the cpu usage field in the domain list summary view</long>
</locale> </locale>
</schema> </schema>

View File

@ -256,12 +256,23 @@ class vmmConfig:
# Suggest gconf syncs, so that the unset dirs are fully removed # Suggest gconf syncs, so that the unset dirs are fully removed
self.conf.suggest_sync() self.conf.suggest_sync()
def get_vmlist_stats_type(self): def is_vmlist_cpu_usage_visible(self):
return self.conf.get_int(self.conf_dir + "/vmlist-fields/stats_type") return self.conf.get_bool(self.conf_dir + "/vmlist-fields/cpu_usage")
def set_vmlist_stats_type(self, val): def is_vmlist_disk_io_visible(self):
self.conf.set_int(self.conf_dir + "/vmlist-fields/stats_type", val) return self.conf.get_bool(self.conf_dir + "/vmlist-fields/disk_usage")
def is_vmlist_network_traffic_visible(self):
return self.conf.get_bool(self.conf_dir + "/vmlist-fields/network_traffic")
def set_vmlist_cpu_usage_visible(self, state):
self.conf.set_bool(self.conf_dir + "/vmlist-fields/cpu_usage", state)
def set_vmlist_disk_io_visible(self, state):
self.conf.set_bool(self.conf_dir + "/vmlist-fields/disk_usage", state)
def set_vmlist_network_traffic_visible(self, state):
self.conf.set_bool(self.conf_dir + "/vmlist-fields/network_traffic", state)
def get_default_directory(self, conn, _type): def get_default_directory(self, conn, _type):
if not _type: if not _type:
@ -301,9 +312,14 @@ class vmmConfig:
def set_view_system_tray(self, val): def set_view_system_tray(self, val):
self.conf.set_bool(self.conf_dir + "/system-tray", val) self.conf.set_bool(self.conf_dir + "/system-tray", val)
def on_vmlist_stats_type_changed(self, callback): def on_vmlist_cpu_usage_visible_changed(self, callback):
self.conf.notify_add(self.conf_dir + "/vmlist-fields/stats_type", self.conf.notify_add(self.conf_dir + "/vmlist-fields/cpu_usage", callback)
callback)
def on_vmlist_disk_io_visible_changed(self, callback):
self.conf.notify_add(self.conf_dir + "/vmlist-fields/disk_usage", callback)
def on_vmlist_network_traffic_visible_changed(self, callback):
self.conf.notify_add(self.conf_dir + "/vmlist-fields/network_traffic", callback)
def get_stats_update_interval(self): def get_stats_update_interval(self):
interval = self.conf.get_int(self.conf_dir + "/stats/update-interval") interval = self.conf.get_int(self.conf_dir + "/stats/update-interval")

View File

@ -32,8 +32,6 @@ from virtManager.delete import vmmDeleteDialog
from virtManager.graphwidgets import CellRendererSparkline from virtManager.graphwidgets import CellRendererSparkline
from virtManager import util as util from virtManager import util as util
VMLIST_SORT_NAME = 1
VMLIST_SORT_STATS = 2
# fields in the tree model data set # fields in the tree model data set
ROW_HANDLE = 0 ROW_HANDLE = 0
@ -51,8 +49,9 @@ ROW_COLOR = 11
# Columns in the tree view # Columns in the tree view
COL_NAME = 0 COL_NAME = 0
COL_STATUS = 1 COL_CPU = 1
COL_STATS = 2 COL_DISK = 2
COL_NETWORK = 3
rcstring = """ rcstring = """
style "toolbar-style" { style "toolbar-style" {
@ -158,12 +157,11 @@ class vmmManager(gobject.GObject):
self.startup_error = None self.startup_error = None
self.ignore_pause = False self.ignore_pause = False
self.stats_column = None
self.stats_sparkline = None
self.prepare_vmlist() self.prepare_vmlist()
self.config.on_vmlist_stats_type_changed(self.stats_toggled_config) self.config.on_vmlist_cpu_usage_visible_changed(self.toggle_cpu_usage_visible_widget)
self.config.on_vmlist_disk_io_visible_changed(self.toggle_disk_io_visible_widget)
self.config.on_vmlist_network_traffic_visible_changed(self.toggle_network_traffic_visible_widget)
# Register callbacks with the global stats enable/disable values # Register callbacks with the global stats enable/disable values
# that disable the associated vmlist widgets if reporting is disabled # that disable the associated vmlist widgets if reporting is disabled
@ -172,6 +170,11 @@ class vmmManager(gobject.GObject):
self.config.on_stats_enable_net_poll_changed(self.enable_polling, self.config.on_stats_enable_net_poll_changed(self.enable_polling,
cfg.STATS_NETWORK) cfg.STATS_NETWORK)
self.window.get_widget("menu_view_stats_cpu").set_active(self.config.is_vmlist_cpu_usage_visible())
self.window.get_widget("menu_view_stats_disk").set_active(self.config.is_vmlist_disk_io_visible())
self.window.get_widget("menu_view_stats_network").set_active(self.config.is_vmlist_network_traffic_visible())
self.vmmenu_icons = {} self.vmmenu_icons = {}
self.vmmenu_icons["run"] = gtk.Image() self.vmmenu_icons["run"] = gtk.Image()
self.vmmenu_icons["run"].set_from_stock(gtk.STOCK_MEDIA_PLAY, self.vmmenu_icons["run"].set_from_stock(gtk.STOCK_MEDIA_PLAY,
@ -333,12 +336,12 @@ class vmmManager(gobject.GObject):
self.connmenu.show() self.connmenu.show()
self.window.signal_autoconnect({ self.window.signal_autoconnect({
"on_menu_view_stats_disk_toggled" : (self.stats_toggled, "on_menu_view_cpu_usage_activate": (self.toggle_stats_visible,
cfg.STATS_DISK), cfg.STATS_CPU),
"on_menu_view_stats_network_toggled" : (self.stats_toggled, "on_menu_view_disk_io_activate" : (self.toggle_stats_visible,
cfg.STATS_NETWORK), cfg.STATS_DISK),
"on_menu_view_stats_cpu_toggled" : (self.stats_toggled, "on_menu_view_network_traffic_activate": (self.toggle_stats_visible,
cfg.STATS_CPU), cfg.STATS_NETWORK),
"on_vm_manager_delete_event": self.close, "on_vm_manager_delete_event": self.close,
"on_menu_file_add_connection_activate": self.new_connection, "on_menu_file_add_connection_activate": self.new_connection,
@ -876,11 +879,18 @@ class vmmManager(gobject.GObject):
nameCol.set_expand(True) nameCol.set_expand(True)
nameCol.set_spacing(6) nameCol.set_spacing(6)
cpuUsageCol = gtk.TreeViewColumn(_("CPU usage")) cpuUsageCol = gtk.TreeViewColumn(_("CPU usage"))
cpuUsageCol.set_min_width(150) diskIOCol = gtk.TreeViewColumn(_("Disk I/O"))
networkTrafficCol = gtk.TreeViewColumn(_("Network I/O"))
cpuUsageCol.set_min_width(140)
diskIOCol.set_min_width(140)
networkTrafficCol.set_min_width(140)
statusCol = nameCol statusCol = nameCol
vmlist.append_column(nameCol) vmlist.append_column(nameCol)
vmlist.append_column(cpuUsageCol) vmlist.append_column(cpuUsageCol)
vmlist.append_column(diskIOCol)
vmlist.append_column(networkTrafficCol)
# For the columns which follow, we deliberately bind columns # For the columns which follow, we deliberately bind columns
# to fields in the list store & on each update copy the info # to fields in the list store & on each update copy the info
@ -900,7 +910,7 @@ class vmmManager(gobject.GObject):
nameCol.pack_start(name_txt, True) nameCol.pack_start(name_txt, True)
nameCol.add_attribute(name_txt, 'markup', ROW_MARKUP) nameCol.add_attribute(name_txt, 'markup', ROW_MARKUP)
nameCol.add_attribute(name_txt, 'foreground-gdk', ROW_COLOR) nameCol.add_attribute(name_txt, 'foreground-gdk', ROW_COLOR)
nameCol.set_sort_column_id(VMLIST_SORT_NAME) nameCol.set_sort_column_id(COL_NAME)
cpuUsage_txt = gtk.CellRendererText() cpuUsage_txt = gtk.CellRendererText()
cpuUsage_img = CellRendererSparkline() cpuUsage_img = CellRendererSparkline()
@ -911,14 +921,37 @@ class vmmManager(gobject.GObject):
cpuUsageCol.pack_start(cpuUsage_txt, False) cpuUsageCol.pack_start(cpuUsage_txt, False)
cpuUsageCol.add_attribute(cpuUsage_img, 'visible', ROW_IS_VM) cpuUsageCol.add_attribute(cpuUsage_img, 'visible', ROW_IS_VM)
cpuUsageCol.add_attribute(cpuUsage_txt, 'visible', ROW_IS_CONN) cpuUsageCol.add_attribute(cpuUsage_txt, 'visible', ROW_IS_CONN)
cpuUsageCol.set_sort_column_id(VMLIST_SORT_STATS) cpuUsageCol.set_cell_data_func(cpuUsage_img, self.cpu_usage_img, None)
self.stats_sparkline = cpuUsage_img cpuUsageCol.set_visible(self.config.is_vmlist_cpu_usage_visible())
self.stats_column = cpuUsageCol cpuUsageCol.set_sort_column_id(COL_CPU)
self.stats_toggled(None, self.get_stats_type())
model.set_sort_func(VMLIST_SORT_NAME, self.vmlist_name_sorter) diskIO_img = CellRendererSparkline()
diskIO_img.set_property("xpad", 6)
diskIO_img.set_property("ypad", 12)
diskIO_img.set_property("reversed", True)
diskIOCol.pack_start(diskIO_img, True)
diskIOCol.add_attribute(diskIO_img, 'visible', ROW_IS_VM)
diskIOCol.set_cell_data_func(diskIO_img, self.disk_io_img, None)
diskIOCol.set_visible(self.config.is_vmlist_disk_io_visible())
diskIOCol.set_sort_column_id(COL_DISK)
model.set_sort_column_id(VMLIST_SORT_NAME, gtk.SORT_ASCENDING) networkTraffic_img = CellRendererSparkline()
networkTraffic_img.set_property("xpad", 6)
networkTraffic_img.set_property("ypad", 12)
networkTraffic_img.set_property("reversed", True)
networkTrafficCol.pack_start(networkTraffic_img, True)
networkTrafficCol.add_attribute(networkTraffic_img, 'visible', ROW_IS_VM)
networkTrafficCol.set_cell_data_func(networkTraffic_img,
self.network_traffic_img, None)
networkTrafficCol.set_visible(self.config.is_vmlist_network_traffic_visible())
networkTrafficCol.set_sort_column_id(COL_NETWORK)
model.set_sort_func(COL_NAME, self.vmlist_name_sorter)
model.set_sort_func(COL_CPU, self.vmlist_cpu_usage_sorter)
model.set_sort_func(COL_DISK, self.vmlist_disk_io_sorter)
model.set_sort_func(COL_NETWORK, self.vmlist_network_usage_sorter)
model.set_sort_column_id(COL_NAME, gtk.SORT_ASCENDING)
def vmlist_name_sorter(self, model, iter1, iter2): def vmlist_name_sorter(self, model, iter1, iter2):
return cmp(model.get_value(iter1, ROW_NAME), return cmp(model.get_value(iter1, ROW_NAME),
@ -950,53 +983,31 @@ class vmmManager(gobject.GObject):
widget.set_sensitive(False) widget.set_sensitive(False)
tool_text = _("Disabled in preferences dialog.") tool_text = _("Disabled in preferences dialog.")
if self.get_stats_type() == userdata:
# Switch graphs over to guaranteed safe value
self.stats_toggled(None, cfg.STATS_CPU)
util.tooltip_wrapper(widget, tool_text) util.tooltip_wrapper(widget, tool_text)
def stats_toggled_config(self, ignore1, ignore2, conf_entry, ignore4): def toggle_network_traffic_visible_widget(self, *ignore):
self.stats_toggled(None, conf_entry.get_value().get_int()) vmlist = self.window.get_widget("vm-list")
col = vmlist.get_column(COL_NETWORK)
col.set_visible(self.config.is_vmlist_network_traffic_visible())
def get_stats_type(self): def toggle_disk_io_visible_widget(self, *ignore):
return self.config.get_vmlist_stats_type() vmlist = self.window.get_widget("vm-list")
col = vmlist.get_column(COL_DISK)
col.set_visible(self.config.is_vmlist_disk_io_visible())
def stats_toggled(self, src, stats_id): def toggle_cpu_usage_visible_widget(self, *ignore):
if src and not src.get_active(): vmlist = self.window.get_widget("vm-list")
return col = vmlist.get_column(COL_CPU)
col.set_visible(self.config.is_vmlist_cpu_usage_visible())
if stats_id == cfg.STATS_NETWORK: def toggle_stats_visible(self, src, stats_id):
column_name = _("Network I/O") visible = src.get_active()
stats_func = self.network_traffic_img set_stats = {
sort_func = self.vmlist_network_usage_sorter cfg.STATS_CPU: self.config.set_vmlist_cpu_usage_visible,
widg = "menu_view_stats_network" cfg.STATS_DISK: self.config.set_vmlist_disk_io_visible,
elif stats_id == cfg.STATS_DISK: cfg.STATS_NETWORK: self.config.set_vmlist_network_traffic_visible,
column_name = _("Disk I/O") }
stats_func = self.disk_io_img set_stats[stats_id](visible)
sort_func = self.vmlist_disk_io_sorter
widg = "menu_view_stats_disk"
elif stats_id == cfg.STATS_CPU:
column_name = _("CPU Usage")
stats_func = self.cpu_usage_img
sort_func = self.vmlist_cpu_usage_sorter
widg = "menu_view_stats_cpu"
else:
return
if not src:
self.window.get_widget(widg).set_active(True)
if self.stats_column:
vmlist = self.window.get_widget("vm-list")
model = vmlist.get_model()
self.stats_column.set_title(column_name)
self.stats_column.set_cell_data_func(self.stats_sparkline,
stats_func, None)
model.set_sort_func(VMLIST_SORT_STATS, sort_func)
if stats_id != self.get_stats_type():
self.config.set_vmlist_stats_type(stats_id)
def cpu_usage_img(self, column, cell, model, _iter, data): def cpu_usage_img(self, column, cell, model, _iter, data):
if model.get_value(_iter, ROW_HANDLE) is None: if model.get_value(_iter, ROW_HANDLE) is None:

View File

@ -158,33 +158,31 @@
<child> <child>
<widget class="GtkMenu" id="menu1"> <widget class="GtkMenu" id="menu1">
<property name="visible">True</property> <property name="visible">True</property>
<child> <child>
<widget class="GtkRadioMenuItem" id="menu_view_stats_cpu"> <widget class="GtkCheckMenuItem" id="menu_view_stats_cpu">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">CPU</property> <property name="label" translatable="yes">CPU Usage</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="draw_as_radio">True</property> <property name="active">True</property>
<signal name="toggled" handler="on_menu_view_stats_cpu_toggled"/> <signal name="activate" handler="on_menu_view_cpu_usage_activate"/>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menu_view_stats_disk">
<property name="visible">True</property>
<property name="label" translatable="yes">Disk I/O</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="activate" handler="on_menu_view_disk_io_activate"/>
</widget> </widget>
</child> </child>
<child> <child>
<widget class="GtkRadioMenuItem" id="menu_view_stats_disk"> <widget class="GtkCheckMenuItem" id="menu_view_stats_network">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">Disk</property> <property name="label" translatable="yes">Network I/O</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="draw_as_radio">True</property> <property name="active">True</property>
<property name="group">menu_view_stats_cpu</property> <signal name="activate" handler="on_menu_view_network_traffic_activate"/>
<signal name="toggled" handler="on_menu_view_stats_disk_toggled"/>
</widget>
</child>
<child>
<widget class="GtkRadioMenuItem" id="menu_view_stats_network">
<property name="visible">True</property>
<property name="label" translatable="yes">Network</property>
<property name="use_underline">True</property>
<property name="draw_as_radio">True</property>
<property name="group">menu_view_stats_cpu</property>
<signal name="toggled" handler="on_menu_view_stats_network_toggled"/>
</widget> </widget>
</child> </child>
</widget> </widget>